diff --git a/.mailmap b/.mailmap index 5273cfd70ad6..c021f29779a7 100644 --- a/.mailmap +++ b/.mailmap @@ -15,6 +15,7 @@ Adriana Reus Alan Cox Alan Cox Aleksey Gorelov +Aleksandar Markovic Al Viro Al Viro Andreas Herrmann @@ -43,6 +44,7 @@ Corey Minyard Damian Hobson-Garcia David Brownell David Woodhouse +Deng-Cheng Zhu Dmitry Eremin-Solenikov Domen Puncer Douglas Gilbert @@ -68,6 +70,8 @@ Jacob Shin James Bottomley James Bottomley James E Wilson +James Hogan +James Hogan James Ketrenos Javi Merino @@ -98,6 +102,8 @@ Leonid I Ananiev Linas Vepstas Linus Lüssing Linus Lüssing +Maciej W. Rozycki +Marcin Nowakowski Mark Brown Martin Kepplinger Martin Kepplinger @@ -112,9 +118,11 @@ Mauro Carvalho Chehab Matt Ranostay Matthew Ranostay Matt Ranostay Matt Ranostay +Matt Redfearn Mayuresh Janorkar Michael Buesch Michel Dänzer +Miodrag Dinic Mitesh shah Mohit Kumar Morten Welinder @@ -125,6 +133,7 @@ Mythri P K Nguyen Anh Quynh Paolo 'Blaisorblade' Giarrusso Patrick Mochel +Paul Burton Peter A Jonsson Peter Oruba Peter Oruba diff --git a/CREDITS b/CREDITS index 5d09c26d69cd..a3ec0c744172 100644 --- a/CREDITS +++ b/CREDITS @@ -2090,7 +2090,7 @@ S: Kuala Lumpur, Malaysia N: Mohit Kumar D: ST Microelectronics SPEAr13xx PCI host bridge driver -D: Synopsys Designware PCI host bridge driver +D: Synopsys DesignWare PCI host bridge driver N: Gabor Kuti E: seasons@falcon.sch.bme.hu @@ -2113,6 +2113,10 @@ S: J. Obrechtstr 23 S: NL-5216 GP 's-Hertogenbosch S: The Netherlands +N: Ashley Lai +E: ashleydlai@gmail.com +D: IBM VTPM driver + N: Savio Lam E: lam836@cs.cuhk.hk D: Author of the dialog utility, foundation @@ -2606,11 +2610,9 @@ E: tmolina@cablespeed.com D: bug fixes, documentation, minor hackery N: Paul Moore -E: paul.moore@hp.com -D: NetLabel author -S: Hewlett-Packard -S: 110 Spit Brook Road -S: Nashua, NH 03062 +E: paul@paul-moore.com +W: http://www.paul-moore.com +D: NetLabel, SELinux, audit N: James Morris E: jmorris@namei.org @@ -3335,6 +3337,10 @@ S: Braunschweiger Strasse 79 S: 31134 Hildesheim S: Germany +N: Marcel Selhorst +E: tpmdd@selhorst.net +D: TPM driver + N: Darren Senn E: sinster@darkwater.com D: Whatever I notice needs doing (so far: itimers, /proc) @@ -4130,7 +4136,6 @@ D: MD driver D: EISA/sysfs subsystem S: France - # Don't add your name here, unless you really _are_ after Marc # alphabetically. Leonard used to be very proud of being the # last entry, and he'll get positively pissed if he can't even diff --git a/Documentation/ABI/stable/sysfs-bus-nvmem b/Documentation/ABI/stable/sysfs-bus-nvmem new file mode 100644 index 000000000000..5923ab4620c5 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-bus-nvmem @@ -0,0 +1,19 @@ +What: /sys/bus/nvmem/devices/.../nvmem +Date: July 2015 +KernelVersion: 4.2 +Contact: Srinivas Kandagatla +Description: + This file allows user to read/write the raw NVMEM contents. + Permissions for write to this file depends on the nvmem + provider configuration. + + ex: + hexdump /sys/bus/nvmem/devices/qfprom0/nvmem + + 0000000 0000 0000 0000 0000 0000 0000 0000 0000 + * + 00000a0 db10 2240 0000 e000 0c00 0c00 0000 0c00 + 0000000 0000 0000 0000 0000 0000 0000 0000 0000 + ... + * + 0001000 diff --git a/Documentation/ABI/stable/sysfs-driver-dma-ioatdma b/Documentation/ABI/stable/sysfs-driver-dma-ioatdma new file mode 100644 index 000000000000..420c1d09e42f --- /dev/null +++ b/Documentation/ABI/stable/sysfs-driver-dma-ioatdma @@ -0,0 +1,30 @@ +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/cap +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: Capabilities the DMA supports.Currently there are DMA_PQ, DMA_PQ_VAL, + DMA_XOR,DMA_XOR_VAL,DMA_INTERRUPT. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/ring_active +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: The number of descriptors active in the ring. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/ring_size +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: Descriptor ring size, total number of descriptors available. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/version +Date: December 3, 2009 +KernelVersion: 2.6.32 +Contact: dmaengine@vger.kernel.org +Description: Version of ioatdma device. + +What: sys/devices/pciXXXX:XX/0000:XX:XX.X/dma/dmachan/quickdata/intr_coalesce +Date: August 8, 2017 +KernelVersion: 4.14 +Contact: dmaengine@vger.kernel.org +Description: Tune-able interrupt delay value per channel basis. diff --git a/Documentation/ABI/testing/configfs-usb-gadget-rndis b/Documentation/ABI/testing/configfs-usb-gadget-rndis index e32879b84b4d..137399095d74 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-rndis +++ b/Documentation/ABI/testing/configfs-usb-gadget-rndis @@ -12,3 +12,6 @@ Description: Ethernet over USB link dev_addr - MAC address of device's end of this Ethernet over USB link + class - USB interface class, default is 02 (hex) + subclass - USB interface subclass, default is 06 (hex) + protocol - USB interface protocol, default is 00 (hex) diff --git a/Documentation/ABI/testing/ppc-memtrace b/Documentation/ABI/testing/ppc-memtrace new file mode 100644 index 000000000000..2e8b93741270 --- /dev/null +++ b/Documentation/ABI/testing/ppc-memtrace @@ -0,0 +1,45 @@ +What: /sys/kernel/debug/powerpc/memtrace +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This folder contains the relevant debugfs files for the + hardware trace macro to use. CONFIG_PPC64_HARDWARE_TRACING + must be set. + +What: /sys/kernel/debug/powerpc/memtrace/enable +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: Write an integer containing the size in bytes of the memory + you want removed from each NUMA node to this file - it must be + aligned to the memblock size. This amount of RAM will be removed + from the kernel mappings and the following debugfs files will be + created. This can only be successfully done once per boot. Once + memory is successfully removed from each node, the following + files are created. + +What: /sys/kernel/debug/powerpc/memtrace/ +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This directory contains information about the removed memory + from the specific NUMA node. + +What: /sys/kernel/debug/powerpc/memtrace//size +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This contains the size of the memory removed from the node. + +What: /sys/kernel/debug/powerpc/memtrace//start +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This contains the start address of the removed memory. + +What: /sys/kernel/debug/powerpc/memtrace//trace +Date: Aug 2017 +KernelVersion: 4.14 +Contact: linuxppc-dev@lists.ozlabs.org +Description: This is where the hardware trace macro will output the trace + it generates. diff --git a/Documentation/ABI/testing/procfs-smaps_rollup b/Documentation/ABI/testing/procfs-smaps_rollup new file mode 100644 index 000000000000..0a54ed0d63c9 --- /dev/null +++ b/Documentation/ABI/testing/procfs-smaps_rollup @@ -0,0 +1,31 @@ +What: /proc/pid/smaps_rollup +Date: August 2017 +Contact: Daniel Colascione +Description: + This file provides pre-summed memory information for a + process. The format is identical to /proc/pid/smaps, + except instead of an entry for each VMA in a process, + smaps_rollup has a single entry (tagged "[rollup]") + for which each field is the sum of the corresponding + fields from all the maps in /proc/pid/smaps. + For more details, see the procfs man page. + + Typical output looks like this: + + 00100000-ff709000 ---p 00000000 00:00 0 [rollup] + Rss: 884 kB + Pss: 385 kB + Shared_Clean: 696 kB + Shared_Dirty: 0 kB + Private_Clean: 120 kB + Private_Dirty: 68 kB + Referenced: 884 kB + Anonymous: 68 kB + LazyFree: 0 kB + AnonHugePages: 0 kB + ShmemPmdMapped: 0 kB + Shared_Hugetlb: 0 kB + Private_Hugetlb: 0 kB + Swap: 0 kB + SwapPss: 0 kB + Locked: 385 kB diff --git a/Documentation/ABI/testing/sysfs-block-zram b/Documentation/ABI/testing/sysfs-block-zram index 451b6d882b2c..c1513c756af1 100644 --- a/Documentation/ABI/testing/sysfs-block-zram +++ b/Documentation/ABI/testing/sysfs-block-zram @@ -90,3 +90,11 @@ Description: device's debugging info useful for kernel developers. Its format is not documented intentionally and may change anytime without any notice. + +What: /sys/block/zram/backing_dev +Date: June 2017 +Contact: Minchan Kim +Description: + The backing_dev file is read-write and set up backing + device for zram to write incompressible pages. + For using, user should enable CONFIG_ZRAM_WRITEBACK. diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 2db2cdf42d54..7eead5f97e02 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -119,6 +119,15 @@ Description: unique to allow association with event codes. Units after application of scale and offset are milliamps. +What: /sys/bus/iio/devices/iio:deviceX/in_powerY_raw +KernelVersion: 4.5 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no bias removal etc.) power measurement from + channel Y. The number must always be specified and + unique to allow association with event codes. Units after + application of scale and offset are milliwatts. + What: /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw KernelVersion: 3.2 Contact: linux-iio@vger.kernel.org diff --git a/Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32 new file mode 100644 index 000000000000..ad2cc63e4bf8 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32 @@ -0,0 +1,57 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_count0_preset +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Reading returns the current preset value. Writing sets the + preset value. Encoder counts continuously from 0 to preset + value, depending on direction (up/down). + +What: /sys/bus/iio/devices/iio:deviceX/in_count_quadrature_mode_available +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Reading returns the list possible quadrature modes. + +What: /sys/bus/iio/devices/iio:deviceX/in_count0_quadrature_mode +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Configure the device counter quadrature modes: + - non-quadrature: + Encoder IN1 input servers as the count input (up + direction). + - quadrature: + Encoder IN1 and IN2 inputs are mixed to get direction + and count. + +What: /sys/bus/iio/devices/iio:deviceX/in_count_polarity_available +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Reading returns the list possible active edges. + +What: /sys/bus/iio/devices/iio:deviceX/in_count0_polarity +KernelVersion: 4.13 +Contact: fabrice.gasnier@st.com +Description: + Configure the device encoder/counter active edge: + - rising-edge + - falling-edge + - both-edges + + In non-quadrature mode, device counts up on active edge. + In quadrature mode, encoder counting scenarios are as follows: + ---------------------------------------------------------------- + | Active | Level on | IN1 signal | IN2 signal | + | edge | opposite |------------------------------------------ + | | signal | Rising | Falling | Rising | Falling | + ---------------------------------------------------------------- + | Rising | High -> | Down | - | Up | - | + | edge | Low -> | Up | - | Down | - | + ---------------------------------------------------------------- + | Falling | High -> | - | Up | - | Down | + | edge | Low -> | - | Down | - | Up | + ---------------------------------------------------------------- + | Both | High -> | Down | Up | Up | Down | + | edges | Low -> | Up | Down | Down | Up | + ---------------------------------------------------------------- diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 index 33e96f740639..147d4e8a1403 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 +++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 @@ -14,3 +14,11 @@ Description: Show or set the gain boost of the amp, from 0-31 range. 18 = indoors (default) 14 = outdoors + +What /sys/bus/iio/devices/iio:deviceX/noise_level_tripped +Date: May 2017 +KernelVersion: 4.13 +Contact: Matt Ranostay +Description: + When 1 the noise level is over the trip level and not reporting + valid data diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index 2a98149943ea..392bef5bd399 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -45,6 +45,8 @@ Contact: thunderbolt-software@lists.01.org Description: When a devices supports Thunderbolt secure connect it will have this attribute. Writing 32 byte hex string changes authorization to use the secure connection method instead. + Writing an empty string clears the key and regular connection + method can be used again. What: /sys/bus/thunderbolt/devices/.../device Date: Sep 2017 diff --git a/Documentation/ABI/testing/sysfs-bus-usb-lvstest b/Documentation/ABI/testing/sysfs-bus-usb-lvstest index 5151290cf8e7..ee0046dc4192 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb-lvstest +++ b/Documentation/ABI/testing/sysfs-bus-usb-lvstest @@ -45,3 +45,16 @@ Contact: Pratyush Anand Description: Write to this node to issue "U3 exit" for Link Layer Validation device. It is needed for TD.7.36. + +What: /sys/bus/usb/devices/.../enable_compliance +Date: July 2017 +Description: + Write to this node to set the port to compliance mode to test + with Link Layer Validation device. It is needed for TD.7.34. + +What: /sys/bus/usb/devices/.../warm_reset +Date: July 2017 +Description: + Write to this node to issue "Warm Reset" for Link Layer Validation + device. It may be needed to properly reset an xHCI 1.1 host port if + compliance mode needed to be explicitly enabled. diff --git a/Documentation/ABI/testing/sysfs-class-remoteproc b/Documentation/ABI/testing/sysfs-class-remoteproc index d188afebc8ba..c3afe9fab646 100644 --- a/Documentation/ABI/testing/sysfs-class-remoteproc +++ b/Documentation/ABI/testing/sysfs-class-remoteproc @@ -1,6 +1,6 @@ What: /sys/class/remoteproc/.../firmware Date: October 2016 -Contact: Matt Redfearn +Contact: Matt Redfearn Description: Remote processor firmware Reports the name of the firmware currently loaded to the @@ -11,7 +11,7 @@ Description: Remote processor firmware What: /sys/class/remoteproc/.../state Date: October 2016 -Contact: Matt Redfearn +Contact: Matt Redfearn Description: Remote processor state Reports the state of the remote processor, which will be one of: diff --git a/Documentation/ABI/testing/sysfs-driver-altera-cvp b/Documentation/ABI/testing/sysfs-driver-altera-cvp new file mode 100644 index 000000000000..8cde64a71edb --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-altera-cvp @@ -0,0 +1,8 @@ +What: /sys/bus/pci/drivers/altera-cvp/chkcfg +Date: May 2017 +Kernel Version: 4.13 +Contact: Anatolij Gustschin +Description: + Contains either 1 or 0 and controls if configuration + error checking in altera-cvp driver is turned on or + off. diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-powercap b/Documentation/ABI/testing/sysfs-firmware-opal-powercap new file mode 100644 index 000000000000..c9b66ec4f165 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-opal-powercap @@ -0,0 +1,31 @@ +What: /sys/firmware/opal/powercap +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: Powercap directory for Powernv (P8, P9) servers + + Each folder in this directory contains a + power-cappable component. + +What: /sys/firmware/opal/powercap/system-powercap + /sys/firmware/opal/powercap/system-powercap/powercap-min + /sys/firmware/opal/powercap/system-powercap/powercap-max + /sys/firmware/opal/powercap/system-powercap/powercap-current +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: System powercap directory and attributes applicable for + Powernv (P8, P9) servers + + This directory provides powercap information. It + contains below sysfs attributes: + + - powercap-min : This file provides the minimum + possible powercap in Watt units + + - powercap-max : This file provides the maximum + possible powercap in Watt units + + - powercap-current : This file provides the current + powercap set on the system. Writing to this file + creates a request for setting a new-powercap. The + powercap requested must be between powercap-min + and powercap-max. diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-psr b/Documentation/ABI/testing/sysfs-firmware-opal-psr new file mode 100644 index 000000000000..cc2ece70e365 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-opal-psr @@ -0,0 +1,18 @@ +What: /sys/firmware/opal/psr +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: Power-Shift-Ratio directory for Powernv P9 servers + + Power-Shift-Ratio allows to provide hints the firmware + to shift/throttle power between different entities in + the system. Each attribute in this directory indicates + a settable PSR. + +What: /sys/firmware/opal/psr/cpu_to_gpu_X +Date: August 2017 +Contact: Linux for PowerPC mailing list +Description: PSR sysfs attributes for Powernv P9 servers + + Power-Shift-Ratio between CPU and GPU for a given chip + with chip-id X. This file gives the ratio (0-100) + which is used by OCC for power-capping. diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 84c606fb3ca4..11b7f4ebea7c 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -57,6 +57,15 @@ Contact: "Jaegeuk Kim" Description: Controls the issue rate of small discard commands. +What: /sys/fs/f2fs//discard_granularity +Date: July 2017 +Contact: "Chao Yu" +Description: + Controls discard granularity of inner discard thread, inner thread + will not issue discards with size that is smaller than granularity. + The unit size is one block, now only support configuring in range + of [1, 512]. + What: /sys/fs/f2fs//max_victim_search Date: January 2014 Contact: "Jaegeuk Kim" @@ -130,3 +139,15 @@ Date: June 2017 Contact: "Chao Yu" Description: Controls current reserved blocks in system. + +What: /sys/fs/f2fs//gc_urgent +Date: August 2017 +Contact: "Jaegeuk Kim" +Description: + Do background GC agressively + +What: /sys/fs/f2fs//gc_urgent_sleep_time +Date: August 2017 +Contact: "Jaegeuk Kim" +Description: + Controls sleep time of GC urgent mode diff --git a/Documentation/ABI/testing/sysfs-kernel-mm-swap b/Documentation/ABI/testing/sysfs-kernel-mm-swap new file mode 100644 index 000000000000..94672016c268 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-kernel-mm-swap @@ -0,0 +1,16 @@ +What: /sys/kernel/mm/swap/ +Date: August 2017 +Contact: Linux memory management mailing list +Description: Interface for swapping + +What: /sys/kernel/mm/swap/vma_ra_enabled +Date: August 2017 +Contact: Linux memory management mailing list +Description: Enable/disable VMA based swap readahead. + + If set to true, the VMA based swap readahead algorithm + will be used for swappable anonymous pages mapped in a + VMA, and the global swap readahead algorithm will be + still used for tmpfs etc. other users. If set to + false, the global swap readahead algorithm will be + used for all swappable pages. diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power index f523e5a3ac33..a1d1612f3651 100644 --- a/Documentation/ABI/testing/sysfs-power +++ b/Documentation/ABI/testing/sysfs-power @@ -127,7 +127,7 @@ Description: What; /sys/power/pm_trace_dev_match Date: October 2010 -Contact: James Hogan +Contact: James Hogan Description: The /sys/power/pm_trace_dev_match file contains the name of the device associated with the last PM event point saved in the RTC @@ -273,3 +273,15 @@ Description: This output is useful for system wakeup diagnostics of spurious wakeup interrupts. + +What: /sys/power/pm_debug_messages +Date: July 2017 +Contact: Rafael J. Wysocki +Description: + The /sys/power/pm_debug_messages file controls the printing + of debug messages from the system suspend/hiberbation + infrastructure to the kernel log. + + Writing a "1" to this file enables the debug messages and + writing a "0" (default) to it disables them. Reads from + this file return the current value. diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 45b29326d719..ac66ae2509a9 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -515,14 +515,15 @@ API at all. :: void * - dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) + dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, + gfp_t flag, unsigned long attrs) -Identical to dma_alloc_coherent() except that the platform will -choose to return either consistent or non-consistent memory as it sees -fit. By using this API, you are guaranteeing to the platform that you -have all the correct and necessary sync points for this memory in the -driver should it choose to return non-consistent memory. +Identical to dma_alloc_coherent() except that when the +DMA_ATTR_NON_CONSISTENT flags is passed in the attrs argument, the +platform will choose to return either consistent or non-consistent memory +as it sees fit. By using this API, you are guaranteeing to the platform +that you have all the correct and necessary sync points for this memory +in the driver should it choose to return non-consistent memory. Note: where the platform can return consistent memory, it will guarantee that the sync points become nops. @@ -535,12 +536,13 @@ that simply cannot make consistent memory. :: void - dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) + dma_free_attrs(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t dma_handle, unsigned long attrs) -Free memory allocated by the nonconsistent API. All parameters must -be identical to those passed in (and returned by -dma_alloc_noncoherent()). +Free memory allocated by the dma_alloc_attrs(). All parameters common +parameters must identical to those otherwise passed to dma_fre_coherent, +and the attrs argument must be identical to the attrs passed to +dma_alloc_attrs(). :: @@ -564,8 +566,8 @@ memory or doing partial flushes. dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) -Do a partial sync of memory that was allocated by -dma_alloc_noncoherent(), starting at virtual address vaddr and +Do a partial sync of memory that was allocated by dma_alloc_attrs() with +the DMA_ATTR_NON_CONSISTENT flag starting at virtual address vaddr and continuing on for size. Again, you *must* observe the cache line boundaries when doing this. @@ -590,34 +592,11 @@ size is the size of the area (must be multiples of PAGE_SIZE). flags can be ORed together and are: -- DMA_MEMORY_MAP - request that the memory returned from - dma_alloc_coherent() be directly writable. - -- DMA_MEMORY_IO - request that the memory returned from - dma_alloc_coherent() be addressable using read()/write()/memcpy_toio() etc. - -One or both of these flags must be present. - -- DMA_MEMORY_INCLUDES_CHILDREN - make the declared memory be allocated by - dma_alloc_coherent of any child devices of this one (for memory residing - on a bridge). - - DMA_MEMORY_EXCLUSIVE - only allocate memory from the declared regions. Do not allow dma_alloc_coherent() to fall back to system memory when it's out of memory in the declared region. -The return value will be either DMA_MEMORY_MAP or DMA_MEMORY_IO and -must correspond to a passed in flag (i.e. no returning DMA_MEMORY_IO -if only DMA_MEMORY_MAP were passed in) for success or zero for -failure. - -Note, for DMA_MEMORY_IO returns, all subsequent memory returned by -dma_alloc_coherent() may no longer be accessed directly, but instead -must be accessed using the correct bus functions. If your driver -isn't prepared to handle this contingency, it should not specify -DMA_MEMORY_IO in the input flags. - -As a simplification for the platforms, only **one** such region of +As a simplification for the platforms, only *one* such region of memory may be declared per device. For reasons of efficiency, most platforms choose to track the declared diff --git a/Documentation/Makefile b/Documentation/Makefile index a42320385df3..85f7856f0092 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -22,6 +22,8 @@ ifeq ($(HAVE_SPHINX),0) .DEFAULT: $(warning The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed and in PATH, or set the SPHINXBUILD make variable to point to the full path of the '$(SPHINXBUILD)' executable.) + @echo + @./scripts/sphinx-pre-install @echo " SKIP Sphinx $@ target." else # HAVE_SPHINX @@ -95,16 +97,6 @@ endif # HAVE_SPHINX # The following targets are independent of HAVE_SPHINX, and the rules should # work or silently pass without Sphinx. -# no-ops for the Sphinx toolchain -sgmldocs: - @: -psdocs: - @: -mandocs: - @: -installmandocs: - @: - cleandocs: $(Q)rm -rf $(BUILDDIR) $(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/media clean diff --git a/Documentation/RCU/Design/Requirements/Requirements.html b/Documentation/RCU/Design/Requirements/Requirements.html index 95b30fa25d56..62e847bcdcdd 100644 --- a/Documentation/RCU/Design/Requirements/Requirements.html +++ b/Documentation/RCU/Design/Requirements/Requirements.html @@ -2080,6 +2080,8 @@ Some of the relevant points of interest are as follows:
  • Scheduler and RCU.
  • Tracing and RCU.
  • Energy Efficiency. +
  • + Scheduling-Clock Interrupts and RCU.
  • Memory Efficiency.
  • Performance, Scalability, Response Time, and Reliability. @@ -2532,6 +2534,134 @@ I learned of many of these requirements via angry phone calls: Flaming me on the Linux-kernel mailing list was apparently not sufficient to fully vent their ire at RCU's energy-efficiency bugs! +

    +Scheduling-Clock Interrupts and RCU

    + +

    +The kernel transitions between in-kernel non-idle execution, userspace +execution, and the idle loop. +Depending on kernel configuration, RCU handles these states differently: + + + + + + + + + + + + + + + + + + +
    HZ KconfigIn-KernelUsermodeIdle
    HZ_PERIODICCan rely on scheduling-clock interrupt.Can rely on scheduling-clock interrupt and its + detection of interrupt from usermode.Can rely on RCU's dyntick-idle detection.
    NO_HZ_IDLECan rely on scheduling-clock interrupt.Can rely on scheduling-clock interrupt and its + detection of interrupt from usermode.Can rely on RCU's dyntick-idle detection.
    NO_HZ_FULLCan only sometimes rely on scheduling-clock interrupt. + In other cases, it is necessary to bound kernel execution + times and/or use IPIs.Can rely on RCU's dyntick-idle detection.Can rely on RCU's dyntick-idle detection.
    + + + + + + + + +
     
    Quick Quiz:
    + Why can't NO_HZ_FULL in-kernel execution rely on the + scheduling-clock interrupt, just like HZ_PERIODIC + and NO_HZ_IDLE do? +
    Answer:
    + Because, as a performance optimization, NO_HZ_FULL + does not necessarily re-enable the scheduling-clock interrupt + on entry to each and every system call. +
     
    + +

    +However, RCU must be reliably informed as to whether any given +CPU is currently in the idle loop, and, for NO_HZ_FULL, +also whether that CPU is executing in usermode, as discussed +earlier. +It also requires that the scheduling-clock interrupt be enabled when +RCU needs it to be: + +

      +
    1. If a CPU is either idle or executing in usermode, and RCU believes + it is non-idle, the scheduling-clock tick had better be running. + Otherwise, you will get RCU CPU stall warnings. Or at best, + very long (11-second) grace periods, with a pointless IPI waking + the CPU from time to time. +
    2. If a CPU is in a portion of the kernel that executes RCU read-side + critical sections, and RCU believes this CPU to be idle, you will get + random memory corruption. DON'T DO THIS!!! + +
      This is one reason to test with lockdep, which will complain + about this sort of thing. +
    3. If a CPU is in a portion of the kernel that is absolutely + positively no-joking guaranteed to never execute any RCU read-side + critical sections, and RCU believes this CPU to to be idle, + no problem. This sort of thing is used by some architectures + for light-weight exception handlers, which can then avoid the + overhead of rcu_irq_enter() and rcu_irq_exit() + at exception entry and exit, respectively. + Some go further and avoid the entireties of irq_enter() + and irq_exit(). + +
      Just make very sure you are running some of your tests with + CONFIG_PROVE_RCU=y, just in case one of your code paths + was in fact joking about not doing RCU read-side critical sections. +
    4. If a CPU is executing in the kernel with the scheduling-clock + interrupt disabled and RCU believes this CPU to be non-idle, + and if the CPU goes idle (from an RCU perspective) every few + jiffies, no problem. It is usually OK for there to be the + occasional gap between idle periods of up to a second or so. + +
      If the gap grows too long, you get RCU CPU stall warnings. +
    5. If a CPU is either idle or executing in usermode, and RCU believes + it to be idle, of course no problem. +
    6. If a CPU is executing in the kernel, the kernel code + path is passing through quiescent states at a reasonable + frequency (preferably about once per few jiffies, but the + occasional excursion to a second or so is usually OK) and the + scheduling-clock interrupt is enabled, of course no problem. + +
      If the gap between a successive pair of quiescent states grows + too long, you get RCU CPU stall warnings. +
    + + + + + + + + +
     
    Quick Quiz:
    + But what if my driver has a hardware interrupt handler + that can run for many seconds? + I cannot invoke schedule() from an hardware + interrupt handler, after all! +
    Answer:
    + One approach is to do rcu_irq_exit();rcu_irq_enter(); + every so often. + But given that long-running interrupt handlers can cause + other problems, not least for response time, shouldn't you + work to keep your interrupt handler's runtime within reasonable + bounds? +
     
    + +

    +But as long as RCU is properly informed of kernel state transitions between +in-kernel execution, usermode execution, and idle, and as long as the +scheduling-clock interrupt is enabled when RCU needs it to be, you +can rest assured that the bugs you encounter will be in some other +part of RCU or some other part of the kernel! +

    Memory Efficiency

    diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index 6beda556faf3..49747717d905 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt @@ -23,6 +23,14 @@ over a rather long period of time, but improvements are always welcome! Yet another exception is where the low real-time latency of RCU's read-side primitives is critically important. + One final exception is where RCU readers are used to prevent + the ABA problem (https://en.wikipedia.org/wiki/ABA_problem) + for lockless updates. This does result in the mildly + counter-intuitive situation where rcu_read_lock() and + rcu_read_unlock() are used to protect updates, however, this + approach provides the same potential simplifications that garbage + collectors do. + 1. Does the update code have proper mutual exclusion? RCU does allow -readers- to run (almost) naked, but -writers- must @@ -40,7 +48,9 @@ over a rather long period of time, but improvements are always welcome! explain how this single task does not become a major bottleneck on big multiprocessor machines (for example, if the task is updating information relating to itself that other tasks can read, there - by definition can be no bottleneck). + by definition can be no bottleneck). Note that the definition + of "large" has changed significantly: Eight CPUs was "large" + in the year 2000, but a hundred CPUs was unremarkable in 2017. 2. Do the RCU read-side critical sections make proper use of rcu_read_lock() and friends? These primitives are needed @@ -55,6 +65,12 @@ over a rather long period of time, but improvements are always welcome! Disabling of preemption can serve as rcu_read_lock_sched(), but is less readable. + Letting RCU-protected pointers "leak" out of an RCU read-side + critical section is every bid as bad as letting them leak out + from under a lock. Unless, of course, you have arranged some + other means of protection, such as a lock or a reference count + -before- letting them out of the RCU read-side critical section. + 3. Does the update code tolerate concurrent accesses? The whole point of RCU is to permit readers to run without @@ -78,10 +94,10 @@ over a rather long period of time, but improvements are always welcome! This works quite well, also. - c. Make updates appear atomic to readers. For example, + c. Make updates appear atomic to readers. For example, pointer updates to properly aligned fields will appear atomic, as will individual atomic primitives. - Sequences of perations performed under a lock will -not- + Sequences of operations performed under a lock will -not- appear to be atomic to RCU readers, nor will sequences of multiple atomic primitives. @@ -168,8 +184,8 @@ over a rather long period of time, but improvements are always welcome! 5. If call_rcu(), or a related primitive such as call_rcu_bh(), call_rcu_sched(), or call_srcu() is used, the callback function - must be written to be called from softirq context. In particular, - it cannot block. + will be called from softirq context. In particular, it cannot + block. 6. Since synchronize_rcu() can block, it cannot be called from any sort of irq context. The same rule applies for @@ -178,11 +194,14 @@ over a rather long period of time, but improvements are always welcome! synchronize_sched_expedite(), and synchronize_srcu_expedited(). The expedited forms of these primitives have the same semantics - as the non-expedited forms, but expediting is both expensive - and unfriendly to real-time workloads. Use of the expedited - primitives should be restricted to rare configuration-change - operations that would not normally be undertaken while a real-time - workload is running. + as the non-expedited forms, but expediting is both expensive and + (with the exception of synchronize_srcu_expedited()) unfriendly + to real-time workloads. Use of the expedited primitives should + be restricted to rare configuration-change operations that would + not normally be undertaken while a real-time workload is running. + However, real-time workloads can use rcupdate.rcu_normal kernel + boot parameter to completely disable expedited grace periods, + though this might have performance implications. In particular, if you find yourself invoking one of the expedited primitives repeatedly in a loop, please do everyone a favor: @@ -193,11 +212,6 @@ over a rather long period of time, but improvements are always welcome! of the system, especially to real-time workloads running on the rest of the system. - In addition, it is illegal to call the expedited forms from - a CPU-hotplug notifier, or while holding a lock that is acquired - by a CPU-hotplug notifier. Failing to observe this restriction - will result in deadlock. - 7. If the updater uses call_rcu() or synchronize_rcu(), then the corresponding readers must use rcu_read_lock() and rcu_read_unlock(). If the updater uses call_rcu_bh() or @@ -321,7 +335,7 @@ over a rather long period of time, but improvements are always welcome! Similarly, disabling preemption is not an acceptable substitute for rcu_read_lock(). Code that attempts to use preemption disabling where it should be using rcu_read_lock() will break - in real-time kernel builds. + in CONFIG_PREEMPT=y kernel builds. If you want to wait for interrupt handlers, NMI handlers, and code under the influence of preempt_disable(), you instead @@ -356,23 +370,22 @@ over a rather long period of time, but improvements are always welcome! not the case, a self-spawning RCU callback would prevent the victim CPU from ever going offline.) -14. SRCU (srcu_read_lock(), srcu_read_unlock(), srcu_dereference(), - synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu()) - may only be invoked from process context. Unlike other forms of - RCU, it -is- permissible to block in an SRCU read-side critical - section (demarked by srcu_read_lock() and srcu_read_unlock()), - hence the "SRCU": "sleepable RCU". Please note that if you - don't need to sleep in read-side critical sections, you should be - using RCU rather than SRCU, because RCU is almost always faster - and easier to use than is SRCU. +14. Unlike other forms of RCU, it -is- permissible to block in an + SRCU read-side critical section (demarked by srcu_read_lock() + and srcu_read_unlock()), hence the "SRCU": "sleepable RCU". + Please note that if you don't need to sleep in read-side critical + sections, you should be using RCU rather than SRCU, because RCU + is almost always faster and easier to use than is SRCU. - Also unlike other forms of RCU, explicit initialization - and cleanup is required via init_srcu_struct() and - cleanup_srcu_struct(). These are passed a "struct srcu_struct" - that defines the scope of a given SRCU domain. Once initialized, - the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock() - synchronize_srcu(), synchronize_srcu_expedited(), and call_srcu(). - A given synchronize_srcu() waits only for SRCU read-side critical + Also unlike other forms of RCU, explicit initialization and + cleanup is required either at build time via DEFINE_SRCU() + or DEFINE_STATIC_SRCU() or at runtime via init_srcu_struct() + and cleanup_srcu_struct(). These last two are passed a + "struct srcu_struct" that defines the scope of a given + SRCU domain. Once initialized, the srcu_struct is passed + to srcu_read_lock(), srcu_read_unlock() synchronize_srcu(), + synchronize_srcu_expedited(), and call_srcu(). A given + synchronize_srcu() waits only for SRCU read-side critical sections governed by srcu_read_lock() and srcu_read_unlock() calls that have been passed the same srcu_struct. This property is what makes sleeping read-side critical sections tolerable -- @@ -390,10 +403,16 @@ over a rather long period of time, but improvements are always welcome! Therefore, SRCU should be used in preference to rw_semaphore only in extremely read-intensive situations, or in situations requiring SRCU's read-side deadlock immunity or low read-side - realtime latency. + realtime latency. You should also consider percpu_rw_semaphore + when you need lightweight readers. - Note that, rcu_assign_pointer() relates to SRCU just as it does - to other forms of RCU. + SRCU's expedited primitive (synchronize_srcu_expedited()) + never sends IPIs to other CPUs, so it is easier on + real-time workloads than is synchronize_rcu_expedited(), + synchronize_rcu_bh_expedited() or synchronize_sched_expedited(). + + Note that rcu_dereference() and rcu_assign_pointer() relate to + SRCU just as they do to other forms of RCU. 15. The whole point of call_rcu(), synchronize_rcu(), and friends is to wait until all pre-existing readers have finished before @@ -435,3 +454,33 @@ over a rather long period of time, but improvements are always welcome! These debugging aids can help you find problems that are otherwise extremely difficult to spot. + +18. If you register a callback using call_rcu(), call_rcu_bh(), + call_rcu_sched(), or call_srcu(), and pass in a function defined + within a loadable module, then it in necessary to wait for + all pending callbacks to be invoked after the last invocation + and before unloading that module. Note that it is absolutely + -not- sufficient to wait for a grace period! The current (say) + synchronize_rcu() implementation waits only for all previous + callbacks registered on the CPU that synchronize_rcu() is running + on, but it is -not- guaranteed to wait for callbacks registered + on other CPUs. + + You instead need to use one of the barrier functions: + + o call_rcu() -> rcu_barrier() + o call_rcu_bh() -> rcu_barrier_bh() + o call_rcu_sched() -> rcu_barrier_sched() + o call_srcu() -> srcu_barrier() + + However, these barrier functions are absolutely -not- guaranteed + to wait for a grace period. In fact, if there are no call_rcu() + callbacks waiting anywhere in the system, rcu_barrier() is within + its rights to return immediately. + + So if you need to wait for both an RCU grace period and for + all pre-existing call_rcu() callbacks, you will need to execute + both rcu_barrier() and synchronize_rcu(), if necessary, using + something like workqueues to to execute them concurrently. + + See rcubarrier.txt for more information. diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt index 745f429fda79..7d4ae110c2c9 100644 --- a/Documentation/RCU/rcu.txt +++ b/Documentation/RCU/rcu.txt @@ -76,15 +76,12 @@ o I hear that RCU is patented? What is with that? Of these, one was allowed to lapse by the assignee, and the others have been contributed to the Linux kernel under GPL. There are now also LGPL implementations of user-level RCU - available (http://lttng.org/?q=node/18). + available (http://liburcu.org/). o I hear that RCU needs work in order to support realtime kernels? - This work is largely completed. Realtime-friendly RCU can be - enabled via the CONFIG_PREEMPT_RCU kernel configuration - parameter. However, work is in progress for enabling priority - boosting of preempted RCU read-side critical sections. This is - needed if you have CPU-bound realtime threads. + Realtime-friendly RCU can be enabled via the CONFIG_PREEMPT_RCU + kernel configuration parameter. o Where can I find more information on RCU? diff --git a/Documentation/RCU/rcu_dereference.txt b/Documentation/RCU/rcu_dereference.txt index b2a613f16d74..1acb26b09b48 100644 --- a/Documentation/RCU/rcu_dereference.txt +++ b/Documentation/RCU/rcu_dereference.txt @@ -25,35 +25,35 @@ o You must use one of the rcu_dereference() family of primitives for an example where the compiler can in fact deduce the exact value of the pointer, and thus cause misordering. +o You are only permitted to use rcu_dereference on pointer values. + The compiler simply knows too much about integral values to + trust it to carry dependencies through integer operations. + There are a very few exceptions, namely that you can temporarily + cast the pointer to uintptr_t in order to: + + o Set bits and clear bits down in the must-be-zero low-order + bits of that pointer. This clearly means that the pointer + must have alignment constraints, for example, this does + -not- work in general for char* pointers. + + o XOR bits to translate pointers, as is done in some + classic buddy-allocator algorithms. + + It is important to cast the value back to pointer before + doing much of anything else with it. + o Avoid cancellation when using the "+" and "-" infix arithmetic operators. For example, for a given variable "x", avoid - "(x-x)". There are similar arithmetic pitfalls from other - arithmetic operators, such as "(x*0)", "(x/(x+1))" or "(x%1)". - The compiler is within its rights to substitute zero for all of - these expressions, so that subsequent accesses no longer depend - on the rcu_dereference(), again possibly resulting in bugs due - to misordering. + "(x-(uintptr_t)x)" for char* pointers. The compiler is within its + rights to substitute zero for this sort of expression, so that + subsequent accesses no longer depend on the rcu_dereference(), + again possibly resulting in bugs due to misordering. Of course, if "p" is a pointer from rcu_dereference(), and "a" and "b" are integers that happen to be equal, the expression "p+a-b" is safe because its value still necessarily depends on the rcu_dereference(), thus maintaining proper ordering. -o Avoid all-zero operands to the bitwise "&" operator, and - similarly avoid all-ones operands to the bitwise "|" operator. - If the compiler is able to deduce the value of such operands, - it is within its rights to substitute the corresponding constant - for the bitwise operation. Once again, this causes subsequent - accesses to no longer depend on the rcu_dereference(), causing - bugs due to misordering. - - Please note that single-bit operands to bitwise "&" can also - be dangerous. At this point, the compiler knows that the - resulting value can only take on one of two possible values. - Therefore, a very small amount of additional information will - allow the compiler to deduce the exact value, which again can - result in misordering. - o If you are using RCU to protect JITed functions, so that the "()" function-invocation operator is applied to a value obtained (directly or indirectly) from rcu_dereference(), you may need to @@ -61,25 +61,6 @@ o If you are using RCU to protect JITed functions, so that the This issue arises on some systems when a newly JITed function is using the same memory that was used by an earlier JITed function. -o Do not use the results from the boolean "&&" and "||" when - dereferencing. For example, the following (rather improbable) - code is buggy: - - int *p; - int *q; - - ... - - p = rcu_dereference(gp) - q = &global_q; - q += p != &oom_p1 && p != &oom_p2; - r1 = *q; /* BUGGY!!! */ - - The reason this is buggy is that "&&" and "||" are often compiled - using branches. While weak-memory machines such as ARM or PowerPC - do order stores after such branches, they can speculate loads, - which can result in misordering bugs. - o Do not use the results from relational operators ("==", "!=", ">", ">=", "<", or "<=") when dereferencing. For example, the following (quite strange) code is buggy: diff --git a/Documentation/RCU/rcubarrier.txt b/Documentation/RCU/rcubarrier.txt index b10cfe711e68..5d7759071a3e 100644 --- a/Documentation/RCU/rcubarrier.txt +++ b/Documentation/RCU/rcubarrier.txt @@ -263,6 +263,11 @@ Quick Quiz #2: What happens if CPU 0's rcu_barrier_func() executes are delayed for a full grace period? Couldn't this result in rcu_barrier() returning prematurely? +The current rcu_barrier() implementation is more complex, due to the need +to avoid disturbing idle CPUs (especially on battery-powered systems) +and the need to minimally disturb non-idle CPUs in real-time systems. +However, the code above illustrates the concepts. + rcu_barrier() Summary diff --git a/Documentation/RCU/torture.txt b/Documentation/RCU/torture.txt index 278f6a9383b6..55918b54808b 100644 --- a/Documentation/RCU/torture.txt +++ b/Documentation/RCU/torture.txt @@ -276,15 +276,17 @@ o "Free-Block Circulation": Shows the number of torture structures somehow gets incremented farther than it should. Different implementations of RCU can provide implementation-specific -additional information. For example, SRCU provides the following +additional information. For example, Tree SRCU provides the following additional line: - srcu-torture: per-CPU(idx=1): 0(0,1) 1(0,1) 2(0,0) 3(0,1) + srcud-torture: Tree SRCU per-CPU(idx=0): 0(35,-21) 1(-4,24) 2(1,1) 3(-26,20) 4(28,-47) 5(-9,4) 6(-10,14) 7(-14,11) T(1,6) -This line shows the per-CPU counter state. The numbers in parentheses are -the values of the "old" and "current" counters for the corresponding CPU. -The "idx" value maps the "old" and "current" values to the underlying -array, and is useful for debugging. +This line shows the per-CPU counter state, in this case for Tree SRCU +using a dynamically allocated srcu_struct (hence "srcud-" rather than +"srcu-"). The numbers in parentheses are the values of the "old" and +"current" counters for the corresponding CPU. The "idx" value maps the +"old" and "current" values to the underlying array, and is useful for +debugging. The final "T" entry contains the totals of the counters. USAGE @@ -304,3 +306,9 @@ checked for such errors. The "rmmod" command forces a "SUCCESS", "FAILURE", or "RCU_HOTPLUG" indication to be printk()ed. The first two are self-explanatory, while the last indicates that while there were no RCU failures, CPU-hotplug problems were detected. + +However, the tools/testing/selftests/rcutorture/bin/kvm.sh script +provides better automation, including automatic failure analysis. +It assumes a qemu/kvm-enabled platform, and runs guest OSes out of initrd. +See tools/testing/selftests/rcutorture/doc/initrd.txt for instructions +on setting up such an initrd. diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index 8ed6c9f6133c..df62466da4e0 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -890,6 +890,8 @@ SRCU: Critical sections Grace period Barrier srcu_read_lock_held SRCU: Initialization/cleanup + DEFINE_SRCU + DEFINE_STATIC_SRCU init_srcu_struct cleanup_srcu_struct @@ -913,7 +915,8 @@ a. Will readers need to block? If so, you need SRCU. b. What about the -rt patchset? If readers would need to block in an non-rt kernel, you need SRCU. If readers would block in a -rt kernel, but not in a non-rt kernel, SRCU is not - necessary. + necessary. (The -rt patchset turns spinlocks into sleeplocks, + hence this distinction.) c. Do you need to treat NMI handlers, hardirq handlers, and code segments with preemption disabled (whether diff --git a/Documentation/admin-guide/LSM/tomoyo.rst b/Documentation/admin-guide/LSM/tomoyo.rst index a5947218fa64..e2d6b6e15082 100644 --- a/Documentation/admin-guide/LSM/tomoyo.rst +++ b/Documentation/admin-guide/LSM/tomoyo.rst @@ -9,8 +9,8 @@ TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel. LiveCD-based tutorials are available at -http://tomoyo.sourceforge.jp/1.7/1st-step/ubuntu10.04-live/ -http://tomoyo.sourceforge.jp/1.7/1st-step/centos5-live/ +http://tomoyo.sourceforge.jp/1.8/ubuntu12.04-live.html +http://tomoyo.sourceforge.jp/1.8/centos6-live.html Though these tutorials use non-LSM version of TOMOYO, they are useful for you to know what TOMOYO is. @@ -21,35 +21,35 @@ How to enable TOMOYO? Build the kernel with ``CONFIG_SECURITY_TOMOYO=y`` and pass ``security=tomoyo`` on kernel's command line. -Please see http://tomoyo.sourceforge.jp/2.3/ for details. +Please see http://tomoyo.osdn.jp/2.5/ for details. Where is documentation? ======================= User <-> Kernel interface documentation is available at -http://tomoyo.sourceforge.jp/2.3/policy-reference.html . +http://tomoyo.osdn.jp/2.5/policy-specification/index.html . Materials we prepared for seminars and symposiums are available at -http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 . +http://osdn.jp/projects/tomoyo/docs/?category_id=532&language_id=1 . Below lists are chosen from three aspects. What is TOMOYO? TOMOYO Linux Overview - http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf + http://osdn.jp/projects/tomoyo/docs/lca2009-takeda.pdf TOMOYO Linux: pragmatic and manageable security for Linux - http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf + http://osdn.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box - http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf + http://osdn.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf What can TOMOYO do? Deep inside TOMOYO Linux - http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf + http://osdn.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf The role of "pathname based access control" in security. - http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf + http://osdn.jp/projects/tomoyo/docs/lfj2008-bof.pdf History of TOMOYO? Realities of Mainlining - http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf + http://osdn.jp/projects/tomoyo/docs/lfj2008.pdf What is future plan? ==================== @@ -60,6 +60,6 @@ multiple LSM modules at the same time. We feel sorry that you have to give up SELinux/SMACK/AppArmor etc. when you want to use TOMOYO. We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM -version of TOMOYO, available at http://tomoyo.sourceforge.jp/1.7/ . +version of TOMOYO, available at http://tomoyo.osdn.jp/1.8/ . LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning to port non-LSM version's functionalities to LSM versions. diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index 6b71852dadc2..4ec843123cc3 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -3081,3 +3081,8 @@ 1 = /dev/osd1 Second OSD Device ... 255 = /dev/osd255 256th OSD Device + + 384-511 char RESERVED FOR DYNAMIC ASSIGNMENT + Character devices that request a dynamic allocation of major + number will take numbers starting from 511 and downward, + once the 234-254 range is full. diff --git a/Documentation/admin-guide/kernel-parameters.rst b/Documentation/admin-guide/kernel-parameters.rst index d76ab3907e2b..b2598cc9834c 100644 --- a/Documentation/admin-guide/kernel-parameters.rst +++ b/Documentation/admin-guide/kernel-parameters.rst @@ -138,6 +138,7 @@ parameter is applicable:: PPT Parallel port support is enabled. PS2 Appropriate PS/2 support is enabled. RAM RAM disk support is enabled. + RDT Intel Resource Director Technology. S390 S390 architecture is enabled. SCSI Appropriate SCSI support is enabled. A lot of drivers have their options described inside diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index d9c171ce4190..05496622b4ef 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2233,6 +2233,17 @@ memory contents and reserves bad memory regions that are detected. + mem_encrypt= [X86-64] AMD Secure Memory Encryption (SME) control + Valid arguments: on, off + Default (depends on kernel configuration option): + on (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) + off (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=n) + mem_encrypt=on: Activate SME + mem_encrypt=off: Do not activate SME + + Refer to Documentation/x86/amd-memory-encryption.txt + for details on when memory encryption can be activated. + mem_sleep_default= [SUSPEND] Default system suspend mode: s2idle - Suspend-To-Idle shallow - Power-On Suspend or equivalent (if supported) @@ -2633,9 +2644,10 @@ In kernels built with CONFIG_NO_HZ_FULL=y, set the specified list of CPUs whose tick will be stopped whenever possible. The boot CPU will be forced outside - the range to maintain the timekeeping. - The CPUs in this range must also be included in the - rcu_nocbs= set. + the range to maintain the timekeeping. Any CPUs + in this list will have their RCU callbacks offloaded, + just as if they had also been called out in the + rcu_nocbs= boot parameter. noiotrap [SH] Disables trapped I/O port accesses. @@ -2696,6 +2708,8 @@ nopat [X86] Disable PAT (page attribute table extension of pagetables) support. + nopcid [X86-64] Disable the PCID cpu feature. + norandmaps Don't use address space randomization. Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space @@ -2750,6 +2764,15 @@ If the dependencies are under your control, you can turn on cpu0_hotplug. + nps_mtm_hs_ctr= [KNL,ARC] + This parameter sets the maximum duration, in + cycles, each HW thread of the CTOP can run + without interruptions, before HW switches it. + The actual maximum duration is 16 times this + parameter's value. + Format: integer between 1 and 255 + Default: 255 + nptcg= [IA-64] Override max number of concurrent global TLB purges which is reported from either PAL_VM_SUMMARY or SAL PALO. @@ -2769,7 +2792,7 @@ Allowed values are enable and disable numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA. - one of ['zone', 'node', 'default'] can be specified + 'node', 'default' can be specified This can be set from sysctl after boot. See Documentation/sysctl/vm.txt for details. @@ -3598,6 +3621,12 @@ Run specified binary instead of /init from the ramdisk, used for early userspace startup. See initrd. + rdt= [HW,X86,RDT] + Turn on/off individual RDT features. List is: + cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, mba. + E.g. to turn on cmt and turn off mba use: + rdt=cmt,!mba + reboot= [KNL] Format (x86 or x86_64): [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \ @@ -4375,6 +4404,10 @@ decrease the size and leave more room for directly mapped kernel RAM. + vmcp_cma=nn[MG] [KNL,S390] + Sets the memory size reserved for contiguous memory + allocations for the vmcp device driver. + vmhalt= [KNL,S390] Perform z/VM CP command after system halt. Format: diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst index 7af83a92d2d6..47153e64dfb5 100644 --- a/Documentation/admin-guide/pm/cpufreq.rst +++ b/Documentation/admin-guide/pm/cpufreq.rst @@ -479,14 +479,6 @@ This governor exposes the following tunables: # echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) > ondemand/sampling_rate - -``min_sampling_rate`` - The minimum value of ``sampling_rate``. - - Equal to 10000 (10 ms) if :c:macro:`CONFIG_NO_HZ_COMMON` and - :c:data:`tick_nohz_active` are both set or to 20 times the value of - :c:data:`jiffies` in microseconds otherwise. - ``up_threshold`` If the estimated CPU load is above this value (in percent), the governor will set the frequency to the maximum value allowed for the policy. diff --git a/Documentation/admin-guide/pm/index.rst b/Documentation/admin-guide/pm/index.rst index 7f148f76f432..49237ac73442 100644 --- a/Documentation/admin-guide/pm/index.rst +++ b/Documentation/admin-guide/pm/index.rst @@ -5,12 +5,6 @@ Power Management .. toctree:: :maxdepth: 2 - cpufreq - intel_pstate - -.. only:: subproject and html - - Indices - ======= - - * :ref:`genindex` + strategies + system-wide + working-state diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst index 1d6249825efc..d2b6fda3d67b 100644 --- a/Documentation/admin-guide/pm/intel_pstate.rst +++ b/Documentation/admin-guide/pm/intel_pstate.rst @@ -167,35 +167,17 @@ is set. ``powersave`` ............. -Without HWP, this P-state selection algorithm generally depends on the -processor model and/or the system profile setting in the ACPI tables and there -are two variants of it. - -One of them is used with processors from the Atom line and (regardless of the -processor model) on platforms with the system profile in the ACPI tables set to -"mobile" (laptops mostly), "tablet", "appliance PC", "desktop", or -"workstation". It is also used with processors supporting the HWP feature if -that feature has not been enabled (that is, with the ``intel_pstate=no_hwp`` -argument in the kernel command line). It is similar to the algorithm +Without HWP, this P-state selection algorithm is similar to the algorithm implemented by the generic ``schedutil`` scaling governor except that the utilization metric used by it is based on numbers coming from feedback registers of the CPU. It generally selects P-states proportional to the -current CPU utilization, so it is referred to as the "proportional" algorithm. +current CPU utilization. -The second variant of the ``powersave`` P-state selection algorithm, used in all -of the other cases (generally, on processors from the Core line, so it is -referred to as the "Core" algorithm), is based on the values read from the APERF -and MPERF feedback registers and the previously requested target P-state. -It does not really take CPU utilization into account explicitly, but as a rule -it causes the CPU P-state to ramp up very quickly in response to increased -utilization which is generally desirable in server environments. - -Regardless of the variant, this algorithm is run by the driver's utilization -update callback for the given CPU when it is invoked by the CPU scheduler, but -not more often than every 10 ms (that can be tweaked via ``debugfs`` in `this -particular case `_). Like in the ``performance`` -case, the hardware configuration is not touched if the new P-state turns out to -be the same as the current one. +This algorithm is run by the driver's utilization update callback for the +given CPU when it is invoked by the CPU scheduler, but not more often than +every 10 ms. Like in the ``performance`` case, the hardware configuration +is not touched if the new P-state turns out to be the same as the current +one. This is the default P-state selection algorithm if the :c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option @@ -720,34 +702,7 @@ P-state is called, the ``ftrace`` filter can be set to to gnome-shell-3409 [001] ..s. 2537.650850: intel_pstate_set_pstate <-intel_pstate_timer_func -0 [000] ..s. 2537.654843: intel_pstate_set_pstate <-intel_pstate_timer_func -Tuning Interface in ``debugfs`` -------------------------------- - -The ``powersave`` algorithm provided by ``intel_pstate`` for `the Core line of -processors in the active mode `_ is based on a `PID controller`_ -whose parameters were chosen to address a number of different use cases at the -same time. However, it still is possible to fine-tune it to a specific workload -and the ``debugfs`` interface under ``/sys/kernel/debug/pstate_snb/`` is -provided for this purpose. [Note that the ``pstate_snb`` directory will be -present only if the specific P-state selection algorithm matching the interface -in it actually is in use.] - -The following files present in that directory can be used to modify the PID -controller parameters at run time: - -| ``deadband`` -| ``d_gain_pct`` -| ``i_gain_pct`` -| ``p_gain_pct`` -| ``sample_rate_ms`` -| ``setpoint`` - -Note, however, that achieving desirable results this way generally requires -expert-level understanding of the power vs performance tradeoff, so extra care -is recommended when attempting to do that. - .. _LCEU2015: http://events.linuxfoundation.org/sites/events/files/slides/LinuxConEurope_2015.pdf .. _SDM: http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-system-programming-manual-325384.html .. _ACPI specification: http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf -.. _PID controller: https://en.wikipedia.org/wiki/PID_controller diff --git a/Documentation/admin-guide/pm/sleep-states.rst b/Documentation/admin-guide/pm/sleep-states.rst new file mode 100644 index 000000000000..1e5c0f00cb2f --- /dev/null +++ b/Documentation/admin-guide/pm/sleep-states.rst @@ -0,0 +1,245 @@ +=================== +System Sleep States +=================== + +:: + + Copyright (c) 2017 Intel Corp., Rafael J. Wysocki + +Sleep states are global low-power states of the entire system in which user +space code cannot be executed and the overall system activity is significantly +reduced. + + +Sleep States That Can Be Supported +================================== + +Depending on its configuration and the capabilities of the platform it runs on, +the Linux kernel can support up to four system sleep states, includig +hibernation and up to three variants of system suspend. The sleep states that +can be supported by the kernel are listed below. + +.. _s2idle: + +Suspend-to-Idle +--------------- + +This is a generic, pure software, light-weight variant of system suspend (also +referred to as S2I or S2Idle). It allows more energy to be saved relative to +runtime idle by freezing user space, suspending the timekeeping and putting all +I/O devices into low-power states (possibly lower-power than available in the +working state), such that the processors can spend time in their deepest idle +states while the system is suspended. + +The system is woken up from this state by in-band interrupts, so theoretically +any devices that can cause interrupts to be generated in the working state can +also be set up as wakeup devices for S2Idle. + +This state can be used on platforms without support for :ref:`standby ` +or :ref:`suspend-to-RAM `, or it can be used in addition to any of the +deeper system suspend variants to provide reduced resume latency. It is always +supported if the :c:macro:`CONFIG_SUSPEND` kernel configuration option is set. + +.. _standby: + +Standby +------- + +This state, if supported, offers moderate, but real, energy savings, while +providing a relatively straightforward transition back to the working state. No +operating state is lost (the system core logic retains power), so the system can +go back to where it left off easily enough. + +In addition to freezing user space, suspending the timekeeping and putting all +I/O devices into low-power states, which is done for :ref:`suspend-to-idle +` too, nonboot CPUs are taken offline and all low-level system functions +are suspended during transitions into this state. For this reason, it should +allow more energy to be saved relative to :ref:`suspend-to-idle `, but +the resume latency will generally be greater than for that state. + +The set of devices that can wake up the system from this state usually is +reduced relative to :ref:`suspend-to-idle ` and it may be necessary to +rely on the platform for setting up the wakeup functionality as appropriate. + +This state is supported if the :c:macro:`CONFIG_SUSPEND` kernel configuration +option is set and the support for it is registered by the platform with the +core system suspend subsystem. On ACPI-based systems this state is mapped to +the S1 system state defined by ACPI. + +.. _s2ram: + +Suspend-to-RAM +-------------- + +This state (also referred to as STR or S2RAM), if supported, offers significant +energy savings as everything in the system is put into a low-power state, except +for memory, which should be placed into the self-refresh mode to retain its +contents. All of the steps carried out when entering :ref:`standby ` +are also carried out during transitions to S2RAM. Additional operations may +take place depending on the platform capabilities. In particular, on ACPI-based +systems the kernel passes control to the platform firmware (BIOS) as the last +step during S2RAM transitions and that usually results in powering down some +more low-level components that are not directly controlled by the kernel. + +The state of devices and CPUs is saved and held in memory. All devices are +suspended and put into low-power states. In many cases, all peripheral buses +lose power when entering S2RAM, so devices must be able to handle the transition +back to the "on" state. + +On ACPI-based systems S2RAM requires some minimal boot-strapping code in the +platform firmware to resume the system from it. This may be the case on other +platforms too. + +The set of devices that can wake up the system from S2RAM usually is reduced +relative to :ref:`suspend-to-idle ` and :ref:`standby ` and it +may be necessary to rely on the platform for setting up the wakeup functionality +as appropriate. + +S2RAM is supported if the :c:macro:`CONFIG_SUSPEND` kernel configuration option +is set and the support for it is registered by the platform with the core system +suspend subsystem. On ACPI-based systems it is mapped to the S3 system state +defined by ACPI. + +.. _hibernation: + +Hibernation +----------- + +This state (also referred to as Suspend-to-Disk or STD) offers the greatest +energy savings and can be used even in the absence of low-level platform support +for system suspend. However, it requires some low-level code for resuming the +system to be present for the underlying CPU architecture. + +Hibernation is significantly different from any of the system suspend variants. +It takes three system state changes to put it into hibernation and two system +state changes to resume it. + +First, when hibernation is triggered, the kernel stops all system activity and +creates a snapshot image of memory to be written into persistent storage. Next, +the system goes into a state in which the snapshot image can be saved, the image +is written out and finally the system goes into the target low-power state in +which power is cut from almost all of its hardware components, including memory, +except for a limited set of wakeup devices. + +Once the snapshot image has been written out, the system may either enter a +special low-power state (like ACPI S4), or it may simply power down itself. +Powering down means minimum power draw and it allows this mechanism to work on +any system. However, entering a special low-power state may allow additional +means of system wakeup to be used (e.g. pressing a key on the keyboard or +opening a laptop lid). + +After wakeup, control goes to the platform firmware that runs a boot loader +which boots a fresh instance of the kernel (control may also go directly to +the boot loader, depending on the system configuration, but anyway it causes +a fresh instance of the kernel to be booted). That new instance of the kernel +(referred to as the ``restore kernel``) looks for a hibernation image in +persistent storage and if one is found, it is loaded into memory. Next, all +activity in the system is stopped and the restore kernel overwrites itself with +the image contents and jumps into a special trampoline area in the original +kernel stored in the image (referred to as the ``image kernel``), which is where +the special architecture-specific low-level code is needed. Finally, the +image kernel restores the system to the pre-hibernation state and allows user +space to run again. + +Hibernation is supported if the :c:macro:`CONFIG_HIBERNATION` kernel +configuration option is set. However, this option can only be set if support +for the given CPU architecture includes the low-level code for system resume. + + +Basic ``sysfs`` Interfaces for System Suspend and Hibernation +============================================================= + +The following files located in the :file:`/sys/power/` directory can be used by +user space for sleep states control. + +``state`` + This file contains a list of strings representing sleep states supported + by the kernel. Writing one of these strings into it causes the kernel + to start a transition of the system into the sleep state represented by + that string. + + In particular, the strings "disk", "freeze" and "standby" represent the + :ref:`hibernation `, :ref:`suspend-to-idle ` and + :ref:`standby ` sleep states, respectively. The string "mem" + is interpreted in accordance with the contents of the ``mem_sleep`` file + described below. + + If the kernel does not support any system sleep states, this file is + not present. + +``mem_sleep`` + This file contains a list of strings representing supported system + suspend variants and allows user space to select the variant to be + associated with the "mem" string in the ``state`` file described above. + + The strings that may be present in this file are "s2idle", "shallow" + and "deep". The string "s2idle" always represents :ref:`suspend-to-idle + ` and, by convention, "shallow" and "deep" represent + :ref:`standby ` and :ref:`suspend-to-RAM `, + respectively. + + Writing one of the listed strings into this file causes the system + suspend variant represented by it to be associated with the "mem" string + in the ``state`` file. The string representing the suspend variant + currently associated with the "mem" string in the ``state`` file + is listed in square brackets. + + If the kernel does not support system suspend, this file is not present. + +``disk`` + This file contains a list of strings representing different operations + that can be carried out after the hibernation image has been saved. The + possible options are as follows: + + ``platform`` + Put the system into a special low-power state (e.g. ACPI S4) to + make additional wakeup options available and possibly allow the + platform firmware to take a simplified initialization path after + wakeup. + + ``shutdown`` + Power off the system. + + ``reboot`` + Reboot the system (useful for diagnostics mostly). + + ``suspend`` + Hybrid system suspend. Put the system into the suspend sleep + state selected through the ``mem_sleep`` file described above. + If the system is successfully woken up from that state, discard + the hibernation image and continue. Otherwise, use the image + to restore the previous state of the system. + + ``test_resume`` + Diagnostic operation. Load the image as though the system had + just woken up from hibernation and the currently running kernel + instance was a restore kernel and follow up with full system + resume. + + Writing one of the listed strings into this file causes the option + represented by it to be selected. + + The currently selected option is shown in square brackets which means + that the operation represented by it will be carried out after creating + and saving the image next time hibernation is triggered by writing + ``disk`` to :file:`/sys/power/state`. + + If the kernel does not support hibernation, this file is not present. + +According to the above, there are two ways to make the system go into the +:ref:`suspend-to-idle ` state. The first one is to write "freeze" +directly to :file:`/sys/power/state`. The second one is to write "s2idle" to +:file:`/sys/power/mem_sleep` and then to write "mem" to +:file:`/sys/power/state`. Likewise, there are two ways to make the system go +into the :ref:`standby ` state (the strings to write to the control +files in that case are "standby" or "shallow" and "mem", respectively) if that +state is supported by the platform. However, there is only one way to make the +system go into the :ref:`suspend-to-RAM ` state (write "deep" into +:file:`/sys/power/mem_sleep` and "mem" into :file:`/sys/power/state`). + +The default suspend variant (ie. the one to be used without writing anything +into :file:`/sys/power/mem_sleep`) is either "deep" (on the majority of systems +supporting :ref:`suspend-to-RAM `) or "s2idle", but it can be overridden +by the value of the "mem_sleep_default" parameter in the kernel command line. +On some ACPI-based systems, depending on the information in the ACPI tables, the +default may be "s2idle" even if :ref:`suspend-to-RAM ` is supported. diff --git a/Documentation/admin-guide/pm/strategies.rst b/Documentation/admin-guide/pm/strategies.rst new file mode 100644 index 000000000000..afe4d3f831fe --- /dev/null +++ b/Documentation/admin-guide/pm/strategies.rst @@ -0,0 +1,52 @@ +=========================== +Power Management Strategies +=========================== + +:: + + Copyright (c) 2017 Intel Corp., Rafael J. Wysocki + +The Linux kernel supports two major high-level power management strategies. + +One of them is based on using global low-power states of the whole system in +which user space code cannot be executed and the overall system activity is +significantly reduced, referred to as :doc:`sleep states `. The +kernel puts the system into one of these states when requested by user space +and the system stays in it until a special signal is received from one of +designated devices, triggering a transition to the ``working state`` in which +user space code can run. Because sleep states are global and the whole system +is affected by the state changes, this strategy is referred to as the +:doc:`system-wide power management `. + +The other strategy, referred to as the :doc:`working-state power management +`, is based on adjusting the power states of individual hardware +components of the system, as needed, in the working state. In consequence, if +this strategy is in use, the working state of the system usually does not +correspond to any particular physical configuration of it, but can be treated as +a metastate covering a range of different power states of the system in which +the individual components of it can be either ``active`` (in use) or +``inactive`` (idle). If they are active, they have to be in power states +allowing them to process data and to be accessed by software. In turn, if they +are inactive, ideally, they should be in low-power states in which they may not +be accessible. + +If all of the system components are active, the system as a whole is regarded as +"runtime active" and that situation typically corresponds to the maximum power +draw (or maximum energy usage) of it. If all of them are inactive, the system +as a whole is regarded as "runtime idle" which may be very close to a sleep +state from the physical system configuration and power draw perspective, but +then it takes much less time and effort to start executing user space code than +for the same system in a sleep state. However, transitions from sleep states +back to the working state can only be started by a limited set of devices, so +typically the system can spend much more time in a sleep state than it can be +runtime idle in one go. For this reason, systems usually use less energy in +sleep states than when they are runtime idle most of the time. + +Moreover, the two power management strategies address different usage scenarios. +Namely, if the user indicates that the system will not be in use going forward, +for example by closing its lid (if the system is a laptop), it probably should +go into a sleep state at that point. On the other hand, if the user simply goes +away from the laptop keyboard, it probably should stay in the working state and +use the working-state power management in case it becomes idle, because the user +may come back to it at any time and then may want the system to be immediately +accessible. diff --git a/Documentation/admin-guide/pm/system-wide.rst b/Documentation/admin-guide/pm/system-wide.rst new file mode 100644 index 000000000000..0c81e4c5de39 --- /dev/null +++ b/Documentation/admin-guide/pm/system-wide.rst @@ -0,0 +1,8 @@ +============================ +System-Wide Power Management +============================ + +.. toctree:: + :maxdepth: 2 + + sleep-states diff --git a/Documentation/admin-guide/pm/working-state.rst b/Documentation/admin-guide/pm/working-state.rst new file mode 100644 index 000000000000..fa01bf083dfe --- /dev/null +++ b/Documentation/admin-guide/pm/working-state.rst @@ -0,0 +1,9 @@ +============================== +Working-State Power Management +============================== + +.. toctree:: + :maxdepth: 2 + + cpufreq + intel_pstate diff --git a/Documentation/arm/firmware.txt b/Documentation/arm/firmware.txt index da6713adac8a..7f175dbb427e 100644 --- a/Documentation/arm/firmware.txt +++ b/Documentation/arm/firmware.txt @@ -60,7 +60,7 @@ Example of using a firmware operation: /* some platform code, e.g. SMP initialization */ - __raw_writel(virt_to_phys(exynos4_secondary_startup), + __raw_writel(__pa_symbol(exynos4_secondary_startup), CPU1_BOOT_REG); /* Call Exynos specific smc call */ diff --git a/Documentation/arm64/cpu-feature-registers.txt b/Documentation/arm64/cpu-feature-registers.txt index d1c97f9f51cc..dad411d635d8 100644 --- a/Documentation/arm64/cpu-feature-registers.txt +++ b/Documentation/arm64/cpu-feature-registers.txt @@ -179,6 +179,8 @@ infrastructure: | FCMA | [19-16] | y | |--------------------------------------------------| | JSCVT | [15-12] | y | + |--------------------------------------------------| + | DPB | [3-0] | y | x--------------------------------------------------x Appendix I: Example diff --git a/Documentation/atomic_bitops.txt b/Documentation/atomic_bitops.txt new file mode 100644 index 000000000000..5550bfdcce5f --- /dev/null +++ b/Documentation/atomic_bitops.txt @@ -0,0 +1,66 @@ + +On atomic bitops. + + +While our bitmap_{}() functions are non-atomic, we have a number of operations +operating on single bits in a bitmap that are atomic. + + +API +--- + +The single bit operations are: + +Non-RMW ops: + + test_bit() + +RMW atomic operations without return value: + + {set,clear,change}_bit() + clear_bit_unlock() + +RMW atomic operations with return value: + + test_and_{set,clear,change}_bit() + test_and_set_bit_lock() + +Barriers: + + smp_mb__{before,after}_atomic() + + +All RMW atomic operations have a '__' prefixed variant which is non-atomic. + + +SEMANTICS +--------- + +Non-atomic ops: + +In particular __clear_bit_unlock() suffers the same issue as atomic_set(), +which is why the generic version maps to clear_bit_unlock(), see atomic_t.txt. + + +RMW ops: + +The test_and_{}_bit() operations return the original value of the bit. + + +ORDERING +-------- + +Like with atomic_t, the rule of thumb is: + + - non-RMW operations are unordered; + + - RMW operations that have no return value are unordered; + + - RMW operations that have a return value are fully ordered. + +Except for test_and_set_bit_lock() which has ACQUIRE semantics and +clear_bit_unlock() which has RELEASE semantics. + +Since a platform only has a single means of achieving atomic operations +the same barriers as for atomic_t are used, see atomic_t.txt. + diff --git a/Documentation/atomic_t.txt b/Documentation/atomic_t.txt new file mode 100644 index 000000000000..913396ac5824 --- /dev/null +++ b/Documentation/atomic_t.txt @@ -0,0 +1,242 @@ + +On atomic types (atomic_t atomic64_t and atomic_long_t). + +The atomic type provides an interface to the architecture's means of atomic +RMW operations between CPUs (atomic operations on MMIO are not supported and +can lead to fatal traps on some platforms). + +API +--- + +The 'full' API consists of (atomic64_ and atomic_long_ prefixes omitted for +brevity): + +Non-RMW ops: + + atomic_read(), atomic_set() + atomic_read_acquire(), atomic_set_release() + + +RMW atomic operations: + +Arithmetic: + + atomic_{add,sub,inc,dec}() + atomic_{add,sub,inc,dec}_return{,_relaxed,_acquire,_release}() + atomic_fetch_{add,sub,inc,dec}{,_relaxed,_acquire,_release}() + + +Bitwise: + + atomic_{and,or,xor,andnot}() + atomic_fetch_{and,or,xor,andnot}{,_relaxed,_acquire,_release}() + + +Swap: + + atomic_xchg{,_relaxed,_acquire,_release}() + atomic_cmpxchg{,_relaxed,_acquire,_release}() + atomic_try_cmpxchg{,_relaxed,_acquire,_release}() + + +Reference count (but please see refcount_t): + + atomic_add_unless(), atomic_inc_not_zero() + atomic_sub_and_test(), atomic_dec_and_test() + + +Misc: + + atomic_inc_and_test(), atomic_add_negative() + atomic_dec_unless_positive(), atomic_inc_unless_negative() + + +Barriers: + + smp_mb__{before,after}_atomic() + + + +SEMANTICS +--------- + +Non-RMW ops: + +The non-RMW ops are (typically) regular LOADs and STOREs and are canonically +implemented using READ_ONCE(), WRITE_ONCE(), smp_load_acquire() and +smp_store_release() respectively. + +The one detail to this is that atomic_set{}() should be observable to the RMW +ops. That is: + + C atomic-set + + { + atomic_set(v, 1); + } + + P1(atomic_t *v) + { + atomic_add_unless(v, 1, 0); + } + + P2(atomic_t *v) + { + atomic_set(v, 0); + } + + exists + (v=2) + +In this case we would expect the atomic_set() from CPU1 to either happen +before the atomic_add_unless(), in which case that latter one would no-op, or +_after_ in which case we'd overwrite its result. In no case is "2" a valid +outcome. + +This is typically true on 'normal' platforms, where a regular competing STORE +will invalidate a LL/SC or fail a CMPXCHG. + +The obvious case where this is not so is when we need to implement atomic ops +with a lock: + + CPU0 CPU1 + + atomic_add_unless(v, 1, 0); + lock(); + ret = READ_ONCE(v->counter); // == 1 + atomic_set(v, 0); + if (ret != u) WRITE_ONCE(v->counter, 0); + WRITE_ONCE(v->counter, ret + 1); + unlock(); + +the typical solution is to then implement atomic_set{}() with atomic_xchg(). + + +RMW ops: + +These come in various forms: + + - plain operations without return value: atomic_{}() + + - operations which return the modified value: atomic_{}_return() + + these are limited to the arithmetic operations because those are + reversible. Bitops are irreversible and therefore the modified value + is of dubious utility. + + - operations which return the original value: atomic_fetch_{}() + + - swap operations: xchg(), cmpxchg() and try_cmpxchg() + + - misc; the special purpose operations that are commonly used and would, + given the interface, normally be implemented using (try_)cmpxchg loops but + are time critical and can, (typically) on LL/SC architectures, be more + efficiently implemented. + +All these operations are SMP atomic; that is, the operations (for a single +atomic variable) can be fully ordered and no intermediate state is lost or +visible. + + +ORDERING (go read memory-barriers.txt first) +-------- + +The rule of thumb: + + - non-RMW operations are unordered; + + - RMW operations that have no return value are unordered; + + - RMW operations that have a return value are fully ordered; + + - RMW operations that are conditional are unordered on FAILURE, + otherwise the above rules apply. + +Except of course when an operation has an explicit ordering like: + + {}_relaxed: unordered + {}_acquire: the R of the RMW (or atomic_read) is an ACQUIRE + {}_release: the W of the RMW (or atomic_set) is a RELEASE + +Where 'unordered' is against other memory locations. Address dependencies are +not defeated. + +Fully ordered primitives are ordered against everything prior and everything +subsequent. Therefore a fully ordered primitive is like having an smp_mb() +before and an smp_mb() after the primitive. + + +The barriers: + + smp_mb__{before,after}_atomic() + +only apply to the RMW ops and can be used to augment/upgrade the ordering +inherent to the used atomic op. These barriers provide a full smp_mb(). + +These helper barriers exist because architectures have varying implicit +ordering on their SMP atomic primitives. For example our TSO architectures +provide full ordered atomics and these barriers are no-ops. + +Thus: + + atomic_fetch_add(); + +is equivalent to: + + smp_mb__before_atomic(); + atomic_fetch_add_relaxed(); + smp_mb__after_atomic(); + +However the atomic_fetch_add() might be implemented more efficiently. + +Further, while something like: + + smp_mb__before_atomic(); + atomic_dec(&X); + +is a 'typical' RELEASE pattern, the barrier is strictly stronger than +a RELEASE. Similarly for something like: + + atomic_inc(&X); + smp_mb__after_atomic(); + +is an ACQUIRE pattern (though very much not typical), but again the barrier is +strictly stronger than ACQUIRE. As illustrated: + + C strong-acquire + + { + } + + P1(int *x, atomic_t *y) + { + r0 = READ_ONCE(*x); + smp_rmb(); + r1 = atomic_read(y); + } + + P2(int *x, atomic_t *y) + { + atomic_inc(y); + smp_mb__after_atomic(); + WRITE_ONCE(*x, 1); + } + + exists + (r0=1 /\ r1=0) + +This should not happen; but a hypothetical atomic_inc_acquire() -- +(void)atomic_fetch_inc_acquire() for instance -- would allow the outcome, +since then: + + P1 P2 + + t = LL.acq *y (0) + t++; + *x = 1; + r0 = *x (1) + RMB + r1 = *y (0) + SC *y, t; + +is allowed. diff --git a/Documentation/block/bfq-iosched.txt b/Documentation/block/bfq-iosched.txt index 05e2822a80b3..3d6951d63489 100644 --- a/Documentation/block/bfq-iosched.txt +++ b/Documentation/block/bfq-iosched.txt @@ -16,14 +16,16 @@ throughput. So, when needed for achieving a lower latency, BFQ builds schedules that may lead to a lower throughput. If your main or only goal, for a given device, is to achieve the maximum-possible throughput at all times, then do switch off all low-latency heuristics -for that device, by setting low_latency to 0. Full details in Section 3. +for that device, by setting low_latency to 0. See Section 3 for +details on how to configure BFQ for the desired tradeoff between +latency and throughput, or on how to maximize throughput. On average CPUs, the current version of BFQ can handle devices performing at most ~30K IOPS; at most ~50 KIOPS on faster CPUs. As a reference, 30-50 KIOPS correspond to very high bandwidths with sequential I/O (e.g., 8-12 GB/s if I/O requests are 256 KB large), and -to 120-200 MB/s with 4KB random I/O. BFQ has not yet been tested on -multi-queue devices. +to 120-200 MB/s with 4KB random I/O. BFQ is currently being tested on +multi-queue devices too. The table of contents follow. Impatients can just jump to Section 3. @@ -33,7 +35,7 @@ CONTENTS 1-1 Personal systems 1-2 Server systems 2. How does BFQ work? -3. What are BFQ's tunable? +3. What are BFQ's tunables and how to properly configure BFQ? 4. BFQ group scheduling 4-1 Service guarantees provided 4-2 Interface @@ -145,19 +147,28 @@ plus a lot of code, are borrowed from CFQ. contrast, BFQ may idle the device for a short time interval, giving the process the chance to go on being served if it issues a new request in time. Device idling typically boosts the - throughput on rotational devices, if processes do synchronous - and sequential I/O. In addition, under BFQ, device idling is - also instrumental in guaranteeing the desired throughput - fraction to processes issuing sync requests (see the description - of the slice_idle tunable in this document, or [1, 2], for more - details). + throughput on rotational devices and on non-queueing flash-based + devices, if processes do synchronous and sequential I/O. In + addition, under BFQ, device idling is also instrumental in + guaranteeing the desired throughput fraction to processes + issuing sync requests (see the description of the slice_idle + tunable in this document, or [1, 2], for more details). - With respect to idling for service guarantees, if several processes are competing for the device at the same time, but - all processes (and groups, after the following commit) have - the same weight, then BFQ guarantees the expected throughput - distribution without ever idling the device. Throughput is - thus as high as possible in this common scenario. + all processes and groups have the same weight, then BFQ + guarantees the expected throughput distribution without ever + idling the device. Throughput is thus as high as possible in + this common scenario. + + - On flash-based storage with internal queueing of commands + (typically NCQ), device idling happens to be always detrimental + for throughput. So, with these devices, BFQ performs idling + only when strictly needed for service guarantees, i.e., for + guaranteeing low latency or fairness. In these cases, overall + throughput may be sub-optimal. No solution currently exists to + provide both strong service guarantees and optimal throughput + on devices with internal queueing. - If low-latency mode is enabled (default configuration), BFQ executes some special heuristics to detect interactive and soft @@ -191,10 +202,7 @@ plus a lot of code, are borrowed from CFQ. - Queues are scheduled according to a variant of WF2Q+, named B-WF2Q+, and implemented using an augmented rb-tree to preserve an O(log N) overall complexity. See [2] for more details. B-WF2Q+ is - also ready for hierarchical scheduling. However, for a cleaner - logical breakdown, the code that enables and completes - hierarchical support is provided in the next commit, which focuses - exactly on this feature. + also ready for hierarchical scheduling, details in Section 4. - B-WF2Q+ guarantees a tight deviation with respect to an ideal, perfectly fair, and smooth service. In particular, B-WF2Q+ @@ -249,13 +257,24 @@ plus a lot of code, are borrowed from CFQ. the Idle class, to prevent it from starving. -3. What are BFQ's tunable? -========================== +3. What are BFQ's tunables and how to properly configure BFQ? +============================================================= -The tunables back_seek-max, back_seek_penalty, fifo_expire_async and -fifo_expire_sync below are the same as in CFQ. Their description is -just copied from that for CFQ. Some considerations in the description -of slice_idle are copied from CFQ too. +Most BFQ tunables affect service guarantees (basically latency and +fairness) and throughput. For full details on how to choose the +desired tradeoff between service guarantees and throughput, see the +parameters slice_idle, strict_guarantees and low_latency. For details +on how to maximise throughput, see slice_idle, timeout_sync and +max_budget. The other performance-related parameters have been +inherited from, and have been preserved mostly for compatibility with +CFQ. So far, no performance improvement has been reported after +changing the latter parameters in BFQ. + +In particular, the tunables back_seek-max, back_seek_penalty, +fifo_expire_async and fifo_expire_sync below are the same as in +CFQ. Their description is just copied from that for CFQ. Some +considerations in the description of slice_idle are copied from CFQ +too. per-process ioprio and weight ----------------------------- @@ -285,15 +304,17 @@ number of seeks and see improved throughput. Setting slice_idle to 0 will remove all the idling on queues and one should see an overall improved throughput on faster storage devices -like multiple SATA/SAS disks in hardware RAID configuration. +like multiple SATA/SAS disks in hardware RAID configuration, as well +as flash-based storage with internal command queueing (and +parallelism). So depending on storage and workload, it might be useful to set slice_idle=0. In general for SATA/SAS disks and software RAID of SATA/SAS disks keeping slice_idle enabled should be useful. For any configurations where there are multiple spindles behind single LUN -(Host based hardware RAID controller or for storage arrays), setting -slice_idle=0 might end up in better throughput and acceptable -latencies. +(Host based hardware RAID controller or for storage arrays), or with +flash-based fast storage, setting slice_idle=0 might end up in better +throughput and acceptable latencies. Idling is however necessary to have service guarantees enforced in case of differentiated weights or differentiated I/O-request lengths. @@ -312,13 +333,14 @@ There is an important flipside for idling: apart from the above cases where it is beneficial also for throughput, idling can severely impact throughput. One important case is random workload. Because of this issue, BFQ tends to avoid idling as much as possible, when it is not -beneficial also for throughput. As a consequence of this behavior, and -of further issues described for the strict_guarantees tunable, -short-term service guarantees may be occasionally violated. And, in -some cases, these guarantees may be more important than guaranteeing -maximum throughput. For example, in video playing/streaming, a very -low drop rate may be more important than maximum throughput. In these -cases, consider setting the strict_guarantees parameter. +beneficial also for throughput (as detailed in Section 2). As a +consequence of this behavior, and of further issues described for the +strict_guarantees tunable, short-term service guarantees may be +occasionally violated. And, in some cases, these guarantees may be +more important than guaranteeing maximum throughput. For example, in +video playing/streaming, a very low drop rate may be more important +than maximum throughput. In these cases, consider setting the +strict_guarantees parameter. strict_guarantees ----------------- @@ -420,6 +442,13 @@ The default value is 0, which enables auto-tuning: BFQ sets max_budget to the maximum number of sectors that can be served during timeout_sync, according to the estimated peak rate. +For specific devices, some users have occasionally reported to have +reached a higher throughput by setting max_budget explicitly, i.e., by +setting max_budget to a higher value than 0. In particular, they have +set max_budget to higher values than those to which BFQ would have set +it with auto-tuning. An alternative way to achieve this goal is to +just increase the value of timeout_sync, leaving max_budget equal to 0. + weights ------- @@ -427,51 +456,6 @@ Read-only parameter, used to show the weights of the currently active BFQ queues. -wr_ tunables ------------- - -BFQ exports a few parameters to control/tune the behavior of -low-latency heuristics. - -wr_coeff - -Factor by which the weight of a weight-raised queue is multiplied. If -the queue is deemed soft real-time, then the weight is further -multiplied by an additional, constant factor. - -wr_max_time - -Maximum duration of a weight-raising period for an interactive task -(ms). If set to zero (default value), then this value is computed -automatically, as a function of the peak rate of the device. In any -case, when the value of this parameter is read, it always reports the -current duration, regardless of whether it has been set manually or -computed automatically. - -wr_max_softrt_rate - -Maximum service rate below which a queue is deemed to be associated -with a soft real-time application, and is then weight-raised -accordingly (sectors/sec). - -wr_min_idle_time - -Minimum idle period after which interactive weight-raising may be -reactivated for a queue (in ms). - -wr_rt_max_time - -Maximum weight-raising duration for soft real-time queues (in ms). The -start time from which this duration is considered is automatically -moved forward if the queue is detected to be still soft real-time -before the current soft real-time weight-raising period finishes. - -wr_min_inter_arr_async - -Minimum period between I/O request arrivals after which weight-raising -may be reactivated for an already busy async queue (in ms). - - 4. Group scheduling with BFQ ============================ diff --git a/Documentation/blockdev/cciss.txt b/Documentation/blockdev/cciss.txt deleted file mode 100644 index 3a5477cc456e..000000000000 --- a/Documentation/blockdev/cciss.txt +++ /dev/null @@ -1,194 +0,0 @@ -This driver is for Compaq's SMART Array Controllers. - -Supported Cards: ----------------- - -This driver is known to work with the following cards: - - * SA 5300 - * SA 5i - * SA 532 - * SA 5312 - * SA 641 - * SA 642 - * SA 6400 - * SA 6400 U320 Expansion Module - * SA 6i - * SA P600 - * SA P800 - * SA E400 - * SA P400i - * SA E200 - * SA E200i - * SA E500 - * SA P700m - * SA P212 - * SA P410 - * SA P410i - * SA P411 - * SA P812 - * SA P712m - * SA P711m - -Detecting drive failures: -------------------------- - -To get the status of logical volumes and to detect physical drive -failures, you can use the cciss_vol_status program found here: -http://cciss.sourceforge.net/#cciss_utils - -Device Naming: --------------- - -If nodes are not already created in the /dev/cciss directory, run as root: - -# cd /dev -# ./MAKEDEV cciss - -You need some entries in /dev for the cciss device. The MAKEDEV script -can make device nodes for you automatically. Currently the device setup -is as follows: - -Major numbers: - 104 cciss0 - 105 cciss1 - 106 cciss2 - 105 cciss3 - 108 cciss4 - 109 cciss5 - 110 cciss6 - 111 cciss7 - -Minor numbers: - b7 b6 b5 b4 b3 b2 b1 b0 - |----+----| |----+----| - | | - | +-------- Partition ID (0=wholedev, 1-15 partition) - | - +-------------------- Logical Volume number - -The device naming scheme is: -/dev/cciss/c0d0 Controller 0, disk 0, whole device -/dev/cciss/c0d0p1 Controller 0, disk 0, partition 1 -/dev/cciss/c0d0p2 Controller 0, disk 0, partition 2 -/dev/cciss/c0d0p3 Controller 0, disk 0, partition 3 - -/dev/cciss/c1d1 Controller 1, disk 1, whole device -/dev/cciss/c1d1p1 Controller 1, disk 1, partition 1 -/dev/cciss/c1d1p2 Controller 1, disk 1, partition 2 -/dev/cciss/c1d1p3 Controller 1, disk 1, partition 3 - -CCISS simple mode support -------------------------- - -The "cciss_simple_mode=1" boot parameter may be used to prevent the driver -from putting the controller into "performant" mode. The difference is that -with simple mode, each command completion requires an interrupt, while with -"performant mode" (the default, and ordinarily better performing) it is -possible to have multiple command completions indicated by a single -interrupt. - -SCSI tape drive and medium changer support ------------------------------------------- - -SCSI sequential access devices and medium changer devices are supported and -appropriate device nodes are automatically created. (e.g. -/dev/st0, /dev/st1, etc. See the "st" man page for more details.) -You must enable "SCSI tape drive support for Smart Array 5xxx" and -"SCSI support" in your kernel configuration to be able to use SCSI -tape drives with your Smart Array 5xxx controller. - -Additionally, note that the driver will engage the SCSI core at init -time if any tape drives or medium changers are detected. The driver may -also be directed to dynamically engage the SCSI core via the /proc filesystem -entry which the "block" side of the driver creates as -/proc/driver/cciss/cciss* at runtime. This is best done via a script. - -For example: - - for x in /proc/driver/cciss/cciss[0-9]* - do - echo "engage scsi" > $x - done - -Once the SCSI core is engaged by the driver, it cannot be disengaged -(except by unloading the driver, if it happens to be linked as a module.) - -Note also that if no sequential access devices or medium changers are -detected, the SCSI core will not be engaged by the action of the above -script. - -Hot plug support for SCSI tape drives -------------------------------------- - -Hot plugging of SCSI tape drives is supported, with some caveats. -The cciss driver must be informed that changes to the SCSI bus -have been made. This may be done via the /proc filesystem. -For example: - - echo "rescan" > /proc/scsi/cciss0/1 - -This causes the driver to query the adapter about changes to the -physical SCSI buses and/or fibre channel arbitrated loop and the -driver to make note of any new or removed sequential access devices -or medium changers. The driver will output messages indicating what -devices have been added or removed and the controller, bus, target and -lun used to address the device. It then notifies the SCSI mid layer -of these changes. - -Note that the naming convention of the /proc filesystem entries -contains a number in addition to the driver name. (E.g. "cciss0" -instead of just "cciss" which you might expect.) - -Note: ONLY sequential access devices and medium changers are presented -as SCSI devices to the SCSI mid layer by the cciss driver. Specifically, -physical SCSI disk drives are NOT presented to the SCSI mid layer. The -physical SCSI disk drives are controlled directly by the array controller -hardware and it is important to prevent the kernel from attempting to directly -access these devices too, as if the array controller were merely a SCSI -controller in the same way that we are allowing it to access SCSI tape drives. - -SCSI error handling for tape drives and medium changers -------------------------------------------------------- - -The linux SCSI mid layer provides an error handling protocol which -kicks into gear whenever a SCSI command fails to complete within a -certain amount of time (which can vary depending on the command). -The cciss driver participates in this protocol to some extent. The -normal protocol is a four step process. First the device is told -to abort the command. If that doesn't work, the device is reset. -If that doesn't work, the SCSI bus is reset. If that doesn't work -the host bus adapter is reset. Because the cciss driver is a block -driver as well as a SCSI driver and only the tape drives and medium -changers are presented to the SCSI mid layer, and unlike more -straightforward SCSI drivers, disk i/o continues through the block -side during the SCSI error recovery process, the cciss driver only -implements the first two of these actions, aborting the command, and -resetting the device. Additionally, most tape drives will not oblige -in aborting commands, and sometimes it appears they will not even -obey a reset command, though in most circumstances they will. In -the case that the command cannot be aborted and the device cannot be -reset, the device will be set offline. - -In the event the error handling code is triggered and a tape drive is -successfully reset or the tardy command is successfully aborted, the -tape drive may still not allow i/o to continue until some command -is issued which positions the tape to a known position. Typically you -must rewind the tape (by issuing "mt -f /dev/st0 rewind" for example) -before i/o can proceed again to a tape drive which was reset. - -There is a cciss_tape_cmds module parameter which can be used to make cciss -allocate more commands for use by tape drives. Ordinarily only a few commands -(6) are allocated for tape drives because tape drives are slow and -infrequently used and the primary purpose of Smart Array controllers is to -act as a RAID controller for disk drives, so the vast majority of commands -are allocated for disk devices. However, if you have more than a few tape -drives attached to a smart array, the default number of commands may not be -enough (for example, if you have 8 tape drives, you could only rewind 6 -at one time with the default number of commands.) The cciss_tape_cmds module -parameter allows more commands (up to 16 more) to be allocated for use by -tape drives. For example: - - insmod cciss.ko cciss_tape_cmds=16 - -Or, as a kernel boot parameter passed in via grub: cciss.cciss_tape_cmds=8 diff --git a/Documentation/blockdev/zram.txt b/Documentation/blockdev/zram.txt index 4fced8a21307..257e65714c6a 100644 --- a/Documentation/blockdev/zram.txt +++ b/Documentation/blockdev/zram.txt @@ -168,6 +168,7 @@ max_comp_streams RW the number of possible concurrent compress operations comp_algorithm RW show and change the compression algorithm compact WO trigger memory compaction debug_stat RO this file is used for zram debugging purposes +backing_dev RW set up backend storage for zram to write out User space is advised to use the following files to read the device statistics. @@ -231,5 +232,15 @@ line of text and contains the following stats separated by whitespace: resets the disksize to zero. You must set the disksize again before reusing the device. +* Optional Feature + += writeback + +With incompressible pages, there is no memory saving with zram. +Instead, with CONFIG_ZRAM_WRITEBACK, zram can write incompressible page +to backing storage rather than keeping it in memory. +User should set up backing device via /sys/block/zramX/backing_dev +before disksize setting. + Nitin Gupta ngupta@vflare.org diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index bde177103567..dc44785dc0fa 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt @@ -18,7 +18,9 @@ v1 is available under Documentation/cgroup-v1/. 1-2. What is cgroup? 2. Basic Operations 2-1. Mounting - 2-2. Organizing Processes + 2-2. Organizing Processes and Threads + 2-2-1. Processes + 2-2-2. Threads 2-3. [Un]populated Notification 2-4. Controlling Controllers 2-4-1. Enabling and Disabling @@ -167,8 +169,11 @@ cgroup v2 currently supports the following mount options. Delegation section for details. -Organizing Processes --------------------- +Organizing Processes and Threads +-------------------------------- + +Processes +~~~~~~~~~ Initially, only the root cgroup exists to which all processes belong. A child cgroup can be created by creating a sub-directory:: @@ -219,6 +224,105 @@ is removed subsequently, " (deleted)" is appended to the path:: 0::/test-cgroup/test-cgroup-nested (deleted) +Threads +~~~~~~~ + +cgroup v2 supports thread granularity for a subset of controllers to +support use cases requiring hierarchical resource distribution across +the threads of a group of processes. By default, all threads of a +process belong to the same cgroup, which also serves as the resource +domain to host resource consumptions which are not specific to a +process or thread. The thread mode allows threads to be spread across +a subtree while still maintaining the common resource domain for them. + +Controllers which support thread mode are called threaded controllers. +The ones which don't are called domain controllers. + +Marking a cgroup threaded makes it join the resource domain of its +parent as a threaded cgroup. The parent may be another threaded +cgroup whose resource domain is further up in the hierarchy. The root +of a threaded subtree, that is, the nearest ancestor which is not +threaded, is called threaded domain or thread root interchangeably and +serves as the resource domain for the entire subtree. + +Inside a threaded subtree, threads of a process can be put in +different cgroups and are not subject to the no internal process +constraint - threaded controllers can be enabled on non-leaf cgroups +whether they have threads in them or not. + +As the threaded domain cgroup hosts all the domain resource +consumptions of the subtree, it is considered to have internal +resource consumptions whether there are processes in it or not and +can't have populated child cgroups which aren't threaded. Because the +root cgroup is not subject to no internal process constraint, it can +serve both as a threaded domain and a parent to domain cgroups. + +The current operation mode or type of the cgroup is shown in the +"cgroup.type" file which indicates whether the cgroup is a normal +domain, a domain which is serving as the domain of a threaded subtree, +or a threaded cgroup. + +On creation, a cgroup is always a domain cgroup and can be made +threaded by writing "threaded" to the "cgroup.type" file. The +operation is single direction:: + + # echo threaded > cgroup.type + +Once threaded, the cgroup can't be made a domain again. To enable the +thread mode, the following conditions must be met. + +- As the cgroup will join the parent's resource domain. The parent + must either be a valid (threaded) domain or a threaded cgroup. + +- When the parent is an unthreaded domain, it must not have any domain + controllers enabled or populated domain children. The root is + exempt from this requirement. + +Topology-wise, a cgroup can be in an invalid state. Please consider +the following toplogy:: + + A (threaded domain) - B (threaded) - C (domain, just created) + +C is created as a domain but isn't connected to a parent which can +host child domains. C can't be used until it is turned into a +threaded cgroup. "cgroup.type" file will report "domain (invalid)" in +these cases. Operations which fail due to invalid topology use +EOPNOTSUPP as the errno. + +A domain cgroup is turned into a threaded domain when one of its child +cgroup becomes threaded or threaded controllers are enabled in the +"cgroup.subtree_control" file while there are processes in the cgroup. +A threaded domain reverts to a normal domain when the conditions +clear. + +When read, "cgroup.threads" contains the list of the thread IDs of all +threads in the cgroup. Except that the operations are per-thread +instead of per-process, "cgroup.threads" has the same format and +behaves the same way as "cgroup.procs". While "cgroup.threads" can be +written to in any cgroup, as it can only move threads inside the same +threaded domain, its operations are confined inside each threaded +subtree. + +The threaded domain cgroup serves as the resource domain for the whole +subtree, and, while the threads can be scattered across the subtree, +all the processes are considered to be in the threaded domain cgroup. +"cgroup.procs" in a threaded domain cgroup contains the PIDs of all +processes in the subtree and is not readable in the subtree proper. +However, "cgroup.procs" can be written to from anywhere in the subtree +to migrate all threads of the matching process to the cgroup. + +Only threaded controllers can be enabled in a threaded subtree. When +a threaded controller is enabled inside a threaded subtree, it only +accounts for and controls resource consumptions associated with the +threads in the cgroup and its descendants. All consumptions which +aren't tied to a specific thread belong to the threaded domain cgroup. + +Because a threaded subtree is exempt from no internal process +constraint, a threaded controller must be able to handle competition +between threads in a non-leaf cgroup and its child cgroups. Each +threaded controller defines how such competitions are handled. + + [Un]populated Notification -------------------------- @@ -302,15 +406,15 @@ disabled if one or more children have it enabled. No Internal Process Constraint ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Non-root cgroups can only distribute resources to their children when -they don't have any processes of their own. In other words, only -cgroups which don't contain any processes can have controllers enabled -in their "cgroup.subtree_control" files. +Non-root cgroups can distribute domain resources to their children +only when they don't have any processes of their own. In other words, +only domain cgroups which don't contain any processes can have domain +controllers enabled in their "cgroup.subtree_control" files. -This guarantees that, when a controller is looking at the part of the -hierarchy which has it enabled, processes are always only on the -leaves. This rules out situations where child cgroups compete against -internal processes of the parent. +This guarantees that, when a domain controller is looking at the part +of the hierarchy which has it enabled, processes are always only on +the leaves. This rules out situations where child cgroups compete +against internal processes of the parent. The root cgroup is exempt from this restriction. Root contains processes and anonymous resource consumption which can't be associated @@ -334,10 +438,10 @@ Model of Delegation ~~~~~~~~~~~~~~~~~~~ A cgroup can be delegated in two ways. First, to a less privileged -user by granting write access of the directory and its "cgroup.procs" -and "cgroup.subtree_control" files to the user. Second, if the -"nsdelegate" mount option is set, automatically to a cgroup namespace -on namespace creation. +user by granting write access of the directory and its "cgroup.procs", +"cgroup.threads" and "cgroup.subtree_control" files to the user. +Second, if the "nsdelegate" mount option is set, automatically to a +cgroup namespace on namespace creation. Because the resource control interface files in a given directory control the distribution of the parent's resources, the delegatee @@ -644,6 +748,29 @@ Core Interface Files All cgroup core files are prefixed with "cgroup." + cgroup.type + + A read-write single value file which exists on non-root + cgroups. + + When read, it indicates the current type of the cgroup, which + can be one of the following values. + + - "domain" : A normal valid domain cgroup. + + - "domain threaded" : A threaded domain cgroup which is + serving as the root of a threaded subtree. + + - "domain invalid" : A cgroup which is in an invalid state. + It can't be populated or have controllers enabled. It may + be allowed to become a threaded cgroup. + + - "threaded" : A threaded cgroup which is a member of a + threaded subtree. + + A cgroup can be turned into a threaded cgroup by writing + "threaded" to this file. + cgroup.procs A read-write new-line separated values file which exists on all cgroups. @@ -658,9 +785,6 @@ All cgroup core files are prefixed with "cgroup." the PID to the cgroup. The writer should match all of the following conditions. - - Its euid is either root or must match either uid or suid of - the target process. - - It must have write access to the "cgroup.procs" file. - It must have write access to the "cgroup.procs" file of the @@ -669,6 +793,35 @@ All cgroup core files are prefixed with "cgroup." When delegating a sub-hierarchy, write access to this file should be granted along with the containing directory. + In a threaded cgroup, reading this file fails with EOPNOTSUPP + as all the processes belong to the thread root. Writing is + supported and moves every thread of the process to the cgroup. + + cgroup.threads + A read-write new-line separated values file which exists on + all cgroups. + + When read, it lists the TIDs of all threads which belong to + the cgroup one-per-line. The TIDs are not ordered and the + same TID may show up more than once if the thread got moved to + another cgroup and then back or the TID got recycled while + reading. + + A TID can be written to migrate the thread associated with the + TID to the cgroup. The writer should match all of the + following conditions. + + - It must have write access to the "cgroup.threads" file. + + - The cgroup that the thread is currently in must be in the + same resource domain as the destination cgroup. + + - It must have write access to the "cgroup.procs" file of the + common ancestor of the source and destination cgroups. + + When delegating a sub-hierarchy, write access to this file + should be granted along with the containing directory. + cgroup.controllers A read-only space separated values file which exists on all cgroups. @@ -701,6 +854,38 @@ All cgroup core files are prefixed with "cgroup." 1 if the cgroup or its descendants contains any live processes; otherwise, 0. + cgroup.max.descendants + A read-write single value files. The default is "max". + + Maximum allowed number of descent cgroups. + If the actual number of descendants is equal or larger, + an attempt to create a new cgroup in the hierarchy will fail. + + cgroup.max.depth + A read-write single value files. The default is "max". + + Maximum allowed descent depth below the current cgroup. + If the actual descent depth is equal or larger, + an attempt to create a new child cgroup will fail. + + cgroup.stat + A read-only flat-keyed file with the following entries: + + nr_descendants + Total number of visible descendant cgroups. + + nr_dying_descendants + Total number of dying descendant cgroups. A cgroup becomes + dying after being deleted by a user. The cgroup will remain + in dying state for some time undefined time (which can depend + on system load) before being completely destroyed. + + A process can't enter a dying cgroup under any circumstances, + a dying cgroup can't revive. + + A dying cgroup can consume system resources not exceeding + limits, which were active at the moment of cgroup deletion. + Controllers =========== diff --git a/Documentation/conf.py b/Documentation/conf.py index 71b032bb44fd..63857d33778c 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -29,7 +29,7 @@ from load_config import loadConfig # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.2' +needs_sphinx = '1.3' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -271,10 +271,29 @@ latex_elements = { # Additional stuff for the LaTeX preamble. 'preamble': ''' - \\usepackage{ifthen} + % Use some font with UTF-8 support with XeLaTeX + \\usepackage{fontspec} + \\setsansfont{DejaVu Serif} + \\setromanfont{DejaVu Sans} + \\setmonofont{DejaVu Sans Mono} - % Allow generate some pages in landscape - \\usepackage{lscape} + ''' +} + +# Fix reference escape troubles with Sphinx 1.4.x +if major == 1 and minor > 3: + latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n' + +if major == 1 and minor <= 4: + latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}' +elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)): + latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=1in' + latex_elements['preamble'] += '\\fvset{fontsize=auto}\n' + +# Customize notice background colors on Sphinx < 1.6: +if major == 1 and minor < 6: + latex_elements['preamble'] += ''' + \\usepackage{ifthen} % Put notes in color and let them be inside a table \\definecolor{NoteColor}{RGB}{204,255,255} @@ -325,27 +344,26 @@ latex_elements = { } \\makeatother - % Use some font with UTF-8 support with XeLaTeX - \\usepackage{fontspec} - \\setsansfont{DejaVu Serif} - \\setromanfont{DejaVu Sans} - \\setmonofont{DejaVu Sans Mono} - - % To allow adjusting table sizes - \\usepackage{adjustbox} - ''' -} - -# Fix reference escape troubles with Sphinx 1.4.x -if major == 1 and minor > 3: - latex_elements['preamble'] += '\\renewcommand*{\\DUrole}[2]{ #2 }\n' - -if major == 1 and minor <= 4: - latex_elements['preamble'] += '\\usepackage[margin=0.5in, top=1in, bottom=1in]{geometry}' -elif major == 1 and (minor > 5 or (minor == 5 and patch >= 3)): - latex_elements['sphinxsetup'] = 'hmargin=0.5in, vmargin=0.5in' +# With Sphinx 1.6, it is possible to change the Bg color directly +# by using: +# \definecolor{sphinxnoteBgColor}{RGB}{204,255,255} +# \definecolor{sphinxwarningBgColor}{RGB}{255,204,204} +# \definecolor{sphinxattentionBgColor}{RGB}{255,255,204} +# \definecolor{sphinximportantBgColor}{RGB}{192,255,204} +# +# However, it require to use sphinx heavy box with: +# +# \renewenvironment{sphinxlightbox} {% +# \\begin{sphinxheavybox} +# } +# \\end{sphinxheavybox} +# } +# +# Unfortunately, the implementation is buggy: if a note is inside a +# table, it isn't displayed well. So, for now, let's use boring +# black and white notes. # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, diff --git a/Documentation/core-api/genalloc.rst b/Documentation/core-api/genalloc.rst new file mode 100644 index 000000000000..6b38a39fab24 --- /dev/null +++ b/Documentation/core-api/genalloc.rst @@ -0,0 +1,144 @@ +The genalloc/genpool subsystem +============================== + +There are a number of memory-allocation subsystems in the kernel, each +aimed at a specific need. Sometimes, however, a kernel developer needs to +implement a new allocator for a specific range of special-purpose memory; +often that memory is located on a device somewhere. The author of the +driver for that device can certainly write a little allocator to get the +job done, but that is the way to fill the kernel with dozens of poorly +tested allocators. Back in 2005, Jes Sorensen lifted one of those +allocators from the sym53c8xx_2 driver and posted_ it as a generic module +for the creation of ad hoc memory allocators. This code was merged +for the 2.6.13 release; it has been modified considerably since then. + +.. _posted: https://lwn.net/Articles/125842/ + +Code using this allocator should include . The action +begins with the creation of a pool using one of: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_create + +.. kernel-doc:: lib/genalloc.c + :functions: devm_gen_pool_create + +A call to :c:func:`gen_pool_create` will create a pool. The granularity of +allocations is set with min_alloc_order; it is a log-base-2 number like +those used by the page allocator, but it refers to bytes rather than pages. +So, if min_alloc_order is passed as 3, then all allocations will be a +multiple of eight bytes. Increasing min_alloc_order decreases the memory +required to track the memory in the pool. The nid parameter specifies +which NUMA node should be used for the allocation of the housekeeping +structures; it can be -1 if the caller doesn't care. + +The "managed" interface :c:func:`devm_gen_pool_create` ties the pool to a +specific device. Among other things, it will automatically clean up the +pool when the given device is destroyed. + +A pool is shut down with: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_destroy + +It's worth noting that, if there are still allocations outstanding from the +given pool, this function will take the rather extreme step of invoking +BUG(), crashing the entire system. You have been warned. + +A freshly created pool has no memory to allocate. It is fairly useless in +that state, so one of the first orders of business is usually to add memory +to the pool. That can be done with one of: + +.. kernel-doc:: include/linux/genalloc.h + :functions: gen_pool_add + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_add_virt + +A call to :c:func:`gen_pool_add` will place the size bytes of memory +starting at addr (in the kernel's virtual address space) into the given +pool, once again using nid as the node ID for ancillary memory allocations. +The :c:func:`gen_pool_add_virt` variant associates an explicit physical +address with the memory; this is only necessary if the pool will be used +for DMA allocations. + +The functions for allocating memory from the pool (and putting it back) +are: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_alloc + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_dma_alloc + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_free + +As one would expect, :c:func:`gen_pool_alloc` will allocate size< bytes +from the given pool. The :c:func:`gen_pool_dma_alloc` variant allocates +memory for use with DMA operations, returning the associated physical +address in the space pointed to by dma. This will only work if the memory +was added with :c:func:`gen_pool_add_virt`. Note that this function +departs from the usual genpool pattern of using unsigned long values to +represent kernel addresses; it returns a void * instead. + +That all seems relatively simple; indeed, some developers clearly found it +to be too simple. After all, the interface above provides no control over +how the allocation functions choose which specific piece of memory to +return. If that sort of control is needed, the following functions will be +of interest: + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_alloc_algo + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_set_algo + +Allocations with :c:func:`gen_pool_alloc_algo` specify an algorithm to be +used to choose the memory to be allocated; the default algorithm can be set +with :c:func:`gen_pool_set_algo`. The data value is passed to the +algorithm; most ignore it, but it is occasionally needed. One can, +naturally, write a special-purpose algorithm, but there is a fair set +already available: + +- gen_pool_first_fit is a simple first-fit allocator; this is the default + algorithm if none other has been specified. + +- gen_pool_first_fit_align forces the allocation to have a specific + alignment (passed via data in a genpool_data_align structure). + +- gen_pool_first_fit_order_align aligns the allocation to the order of the + size. A 60-byte allocation will thus be 64-byte aligned, for example. + +- gen_pool_best_fit, as one would expect, is a simple best-fit allocator. + +- gen_pool_fixed_alloc allocates at a specific offset (passed in a + genpool_data_fixed structure via the data parameter) within the pool. + If the indicated memory is not available the allocation fails. + +There is a handful of other functions, mostly for purposes like querying +the space available in the pool or iterating through chunks of memory. +Most users, however, should not need much beyond what has been described +above. With luck, wider awareness of this module will help to prevent the +writing of special-purpose memory allocators in the future. + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_virt_to_phys + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_for_each_chunk + +.. kernel-doc:: lib/genalloc.c + :functions: addr_in_gen_pool + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_avail + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_size + +.. kernel-doc:: lib/genalloc.c + :functions: gen_pool_get + +.. kernel-doc:: lib/genalloc.c + :functions: of_gen_pool_get diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index 0606be3a3111..d5bbe035316d 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -20,6 +20,7 @@ Core utilities genericirq flexible-arrays librs + genalloc Interfaces for kernel debugging =============================== diff --git a/Documentation/core-api/kernel-api.rst b/Documentation/core-api/kernel-api.rst index 17b00914c6ab..5da10184d908 100644 --- a/Documentation/core-api/kernel-api.rst +++ b/Documentation/core-api/kernel-api.rst @@ -344,3 +344,38 @@ codecs, and devices with strict requirements for interface clocking. .. kernel-doc:: include/linux/clk.h :internal: + +Synchronization Primitives +========================== + +Read-Copy Update (RCU) +---------------------- + +.. kernel-doc:: include/linux/rcupdate.h + +.. kernel-doc:: include/linux/rcupdate_wait.h + +.. kernel-doc:: include/linux/rcutree.h + +.. kernel-doc:: kernel/rcu/tree.c + +.. kernel-doc:: kernel/rcu/tree_plugin.h + +.. kernel-doc:: kernel/rcu/tree_exp.h + +.. kernel-doc:: kernel/rcu/update.c + +.. kernel-doc:: include/linux/srcu.h + +.. kernel-doc:: kernel/rcu/srcutree.c + +.. kernel-doc:: include/linux/rculist_bl.h + +.. kernel-doc:: include/linux/rculist.h + +.. kernel-doc:: include/linux/rculist_nulls.h + +.. kernel-doc:: include/linux/rcu_sync.h + +.. kernel-doc:: kernel/rcu/sync.c + diff --git a/Documentation/core-api/workqueue.rst b/Documentation/core-api/workqueue.rst index ffdec94fbca1..00a5ba51e63f 100644 --- a/Documentation/core-api/workqueue.rst +++ b/Documentation/core-api/workqueue.rst @@ -39,8 +39,8 @@ up. Although MT wq wasted a lot of resource, the level of concurrency provided was unsatisfactory. The limitation was common to both ST and MT wq albeit less severe on MT. Each wq maintained its own separate -worker pool. A MT wq could provide only one execution context per CPU -while a ST wq one for the whole system. Work items had to compete for +worker pool. An MT wq could provide only one execution context per CPU +while an ST wq one for the whole system. Work items had to compete for those very limited execution contexts leading to various problems including proneness to deadlocks around the single execution context. @@ -151,7 +151,7 @@ Application Programming Interface (API) ``alloc_workqueue()`` allocates a wq. The original ``create_*workqueue()`` functions are deprecated and scheduled for -removal. ``alloc_workqueue()`` takes three arguments - @``name``, +removal. ``alloc_workqueue()`` takes three arguments - ``@name``, ``@flags`` and ``@max_active``. ``@name`` is the name of the wq and also used as the name of the rescuer thread if there is one. @@ -197,7 +197,7 @@ resources, scheduled and executed. served by worker threads with elevated nice level. Note that normal and highpri worker-pools don't interact with - each other. Each maintain its separate pool of workers and + each other. Each maintains its separate pool of workers and implements concurrency management among its workers. ``WQ_CPU_INTENSIVE`` @@ -243,11 +243,15 @@ throttling the number of active work items, specifying '0' is recommended. Some users depend on the strict execution ordering of ST wq. The -combination of ``@max_active`` of 1 and ``WQ_UNBOUND`` is used to -achieve this behavior. Work items on such wq are always queued to the -unbound worker-pools and only one work item can be active at any given +combination of ``@max_active`` of 1 and ``WQ_UNBOUND`` used to +achieve this behavior. Work items on such wq were always queued to the +unbound worker-pools and only one work item could be active at any given time thus achieving the same ordering property as ST wq. +In the current implementation the above configuration only guarantees +ST behavior within a given NUMA node. Instead ``alloc_ordered_queue()`` should +be used to achieve system-wide ST behavior. + Example Execution Scenarios =========================== diff --git a/Documentation/cpu-freq/index.txt b/Documentation/cpu-freq/index.txt index 03a7cee6ac73..c15e75386a05 100644 --- a/Documentation/cpu-freq/index.txt +++ b/Documentation/cpu-freq/index.txt @@ -32,8 +32,6 @@ cpufreq-stats.txt - General description of sysfs cpufreq stats. index.txt - File index, Mailing list and Links (this document) -intel-pstate.txt - Intel pstate cpufreq driver specific file. - pcc-cpufreq.txt - PCC cpufreq driver specific file. diff --git a/Documentation/dev-tools/gdb-kernel-debugging.rst b/Documentation/dev-tools/gdb-kernel-debugging.rst index 5e93c9bc6619..19df79286f00 100644 --- a/Documentation/dev-tools/gdb-kernel-debugging.rst +++ b/Documentation/dev-tools/gdb-kernel-debugging.rst @@ -31,11 +31,13 @@ Setup CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports CONFIG_FRAME_POINTER, keep it enabled. -- Install that kernel on the guest. +- Install that kernel on the guest, turn off KASLR if necessary by adding + "nokaslr" to the kernel command line. Alternatively, QEMU allows to boot the kernel directly using -kernel, -append, -initrd command line switches. This is generally only useful if you do not depend on modules. See QEMU documentation for more details on - this mode. + this mode. In this case, you should build the kernel with + CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR. - Enable the gdb stub of QEMU/KVM, either diff --git a/Documentation/dev-tools/kgdb.rst b/Documentation/dev-tools/kgdb.rst index 75273203a35a..d38be58f872a 100644 --- a/Documentation/dev-tools/kgdb.rst +++ b/Documentation/dev-tools/kgdb.rst @@ -348,6 +348,15 @@ default behavior is always set to 0. - ``echo 1 > /sys/module/debug_core/parameters/kgdbreboot`` - Enter the debugger on reboot notify. +Kernel parameter: ``nokaslr`` +----------------------------- + +If the architecture that you are using enable KASLR by default, +you should consider turning it off. KASLR randomizes the +virtual address where the kernel image is mapped and confuse +gdb which resolve kernel symbol address from symbol table +of vmlinux. + Using kdb ========= @@ -358,7 +367,7 @@ This is a quick example of how to use kdb. 1. Configure kgdboc at boot using kernel parameters:: - console=ttyS0,115200 kgdboc=ttyS0,115200 + console=ttyS0,115200 kgdboc=ttyS0,115200 nokaslr OR diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt index 4a0a7469fdd7..32df07e29f68 100644 --- a/Documentation/device-mapper/dm-raid.txt +++ b/Documentation/device-mapper/dm-raid.txt @@ -344,3 +344,4 @@ Version History (wrong raid10_copies/raid10_format sequence) 1.11.1 Add raid4/5/6 journal write-back support via journal_mode option 1.12.1 fix for MD deadlock between mddev_suspend() and md_write_start() available +1.13.0 Fix dev_health status at end of "recover" (was 'a', now 'A') diff --git a/Documentation/devicetree/bindings/arc/hsdk.txt b/Documentation/devicetree/bindings/arc/hsdk.txt new file mode 100644 index 000000000000..be50654bbf61 --- /dev/null +++ b/Documentation/devicetree/bindings/arc/hsdk.txt @@ -0,0 +1,7 @@ +Synopsys DesignWare ARC HS Development Kit Device Tree Bindings +--------------------------------------------------------------------------- + +ARC HSDK Board with quad-core ARC HS38x4 in silicon. + +Required root node properties: + - compatible = "snps,hsdk"; diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index 0fff40a6330d..4e4bc0bae597 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.txt +++ b/Documentation/devicetree/bindings/arm/amlogic.txt @@ -1,6 +1,18 @@ Amlogic MesonX device tree bindings ------------------------------------------- +Work in progress statement: + +Device tree files and bindings applying to Amlogic SoCs and boards are +considered "unstable". Any Amlogic device tree binding may change at +any time. Be sure to use a device tree binary and a kernel image +generated from the same source tree. + +Please refer to Documentation/devicetree/bindings/ABI.txt for a definition of a +stable binding/ABI. + +--------------------------------------------------------------- + Boards with the Amlogic Meson6 SoC shall have the following properties: Required root node property: compatible: "amlogic,meson6" @@ -61,3 +73,32 @@ Board compatible values (alphabetically, grouped by SoC): - "amlogic,q201" (Meson gxm s912) - "kingnovel,r-box-pro" (Meson gxm S912) - "nexbox,a1" (Meson gxm s912) + +Amlogic Meson Firmware registers Interface +------------------------------------------ + +The Meson SoCs have a register bank with status and data shared with the +secure firmware. + +Required properties: + - compatible: For Meson GX SoCs, must be "amlogic,meson-gx-ao-secure", "syscon" + +Properties should indentify components of this register interface : + +Meson GX SoC Information +------------------------ +A firmware register encodes the SoC type, package and revision information on +the Meson GX SoCs. +If present, the following property should be added : + +Optional properties: + - amlogic,has-chip-id: If present, the interface gives the current SoC version. + +Example +------- + +ao-secure@140 { + compatible = "amlogic,meson-gx-ao-secure", "syscon"; + reg = <0x0 0x140 0x0 0x140>; + amlogic,has-chip-id; +}; diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt index e926aea1147d..68301b77e854 100644 --- a/Documentation/devicetree/bindings/arm/arch_timer.txt +++ b/Documentation/devicetree/bindings/arm/arch_timer.txt @@ -108,6 +108,5 @@ Example: frame-number = <1> interrupts = <0 15 0x8>; reg = <0xf0003000 0x1000>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt index 9c97de23919a..3e3efa046ac5 100644 --- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt @@ -42,6 +42,10 @@ Raspberry Pi Zero Required root node properties: compatible = "raspberrypi,model-zero", "brcm,bcm2835"; +Raspberry Pi Zero W +Required root node properties: +compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; + Generic BCM2835 board Required root node properties: compatible = "brcm,bcm2835"; diff --git a/Documentation/devicetree/bindings/arm/bhf.txt b/Documentation/devicetree/bindings/arm/bhf.txt new file mode 100644 index 000000000000..886b503caf9c --- /dev/null +++ b/Documentation/devicetree/bindings/arm/bhf.txt @@ -0,0 +1,6 @@ +Beckhoff Automation Platforms Device Tree Bindings +-------------------------------------------------- + +CX9020 Embedded PC +Required root node properties: + - compatible = "bhf,cx9020", "fsl,imx53"; diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt index fcbae6a5e6c1..15ac8e8dcfdf 100644 --- a/Documentation/devicetree/bindings/arm/coresight.txt +++ b/Documentation/devicetree/bindings/arm/coresight.txt @@ -34,8 +34,8 @@ its hardware characteristcs. - Embedded Trace Macrocell (version 4.x): "arm,coresight-etm4x", "arm,primecell"; - - Qualcomm Configurable Replicator (version 1.x): - "qcom,coresight-replicator1x", "arm,primecell"; + - Coresight programmable Replicator : + "arm,coresight-dynamic-replicator", "arm,primecell"; - System Trace Macrocell: "arm,coresight-stm", "arm,primecell"; [1] diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index a44253cad269..b92f12bd5244 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -200,6 +200,7 @@ described below. "arm,realview-smp" "brcm,bcm11351-cpu-method" "brcm,bcm23550" + "brcm,bcm2836-smp" "brcm,bcm-nsp-smp" "brcm,brahma-b15" "marvell,armada-375-smp" diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-8kp.txt b/Documentation/devicetree/bindings/arm/marvell/armada-8kp.txt new file mode 100644 index 000000000000..f3e9624534c6 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/armada-8kp.txt @@ -0,0 +1,15 @@ +Marvell Armada 8KPlus Platforms Device Tree Bindings +---------------------------------------------------- + +Boards using a SoC of the Marvell Armada 8KP families must carry +the following root node property: + + - compatible, with one of the following values: + + - "marvell,armada-8080", "marvell,armada-ap810-octa", "marvell,armada-ap810" + when the SoC being used is the Armada 8080 + +Example: + +compatible = "marvell,armada-8080-db", "marvell,armada-8080", + "marvell,armada-ap810-octa", "marvell,armada-ap810" diff --git a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt index 171d02cadea4..29cdbae6c5ac 100644 --- a/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt +++ b/Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt @@ -183,7 +183,6 @@ cpm_syscon0: system-controller@440000 { gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cpm_pinctrl 0 0 32>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt index da7bd138e6f2..91d517849483 100644 --- a/Documentation/devicetree/bindings/arm/mediatek.txt +++ b/Documentation/devicetree/bindings/arm/mediatek.txt @@ -1,12 +1,12 @@ -MediaTek mt65xx, mt67xx & mt81xx Platforms Device Tree Bindings +MediaTek SoC based Platforms Device Tree Bindings -Boards with a MediaTek mt65xx/mt67xx/mt81xx SoC shall have the -following property: +Boards with a MediaTek SoC shall have the following property: Required root node property: compatible: Must contain one of "mediatek,mt2701" + "mediatek,mt2712" "mediatek,mt6580" "mediatek,mt6589" "mediatek,mt6592" @@ -14,7 +14,8 @@ compatible: Must contain one of "mediatek,mt6795" "mediatek,mt6797" "mediatek,mt7622" - "mediatek,mt7623" + "mediatek,mt7623" which is referred to MT7623N SoC + "mediatek,mt7623a" "mediatek,mt8127" "mediatek,mt8135" "mediatek,mt8173" @@ -25,6 +26,9 @@ Supported boards: - Evaluation board for MT2701: Required root node properties: - compatible = "mediatek,mt2701-evb", "mediatek,mt2701"; +- Evaluation board for MT2712: + Required root node properties: + - compatible = "mediatek,mt2712-evb", "mediatek,mt2712"; - Evaluation board for MT6580: Required root node properties: - compatible = "mediatek,mt6580-evbp1", "mediatek,mt6580"; @@ -46,9 +50,11 @@ Supported boards: - Reference board variant 1 for MT7622: Required root node properties: - compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622"; -- Evaluation board for MT7623: +- Reference board for MT7623n with NAND: Required root node properties: - - compatible = "mediatek,mt7623-evb", "mediatek,mt7623"; + - compatible = "mediatek,mt7623n-rfb-nand", "mediatek,mt7623"; +- Bananapi BPI-R2 board: + - compatible = "bananapi,bpi-r2", "mediatek,mt7623"; - MTK mt8127 tablet moose EVB: Required root node properties: - compatible = "mediatek,mt8127-moose", "mediatek,mt8127"; diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt index 8219b2c6bb29..2ecc712bf707 100644 --- a/Documentation/devicetree/bindings/arm/omap/omap.txt +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt @@ -80,6 +80,9 @@ SoCs: - OMAP5432 compatible = "ti,omap5432", "ti,omap5" +- DRA762 + compatible = "ti,dra762", "ti,dra7" + - DRA742 compatible = "ti,dra742", "ti,dra74", "ti,dra7" @@ -154,6 +157,9 @@ Boards: - AM335X phyCORE-AM335x: Development kit compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx" +- AM335X UC-8100-ME-T: Communication-centric industrial computing platform + compatible = "moxa,uc-8100-me-t", "ti,am33xx"; + - OMAP5 EVM : Evaluation Module compatible = "ti,omap5-evm", "ti,omap5" @@ -184,6 +190,9 @@ Boards: - AM5718 IDK compatible = "ti,am5718-idk", "ti,am5718", "ti,dra7" +- DRA762 EVM: Software Development Board for DRA762 + compatible = "ti,dra76-evm", "ti,dra762", "ti,dra7" + - DRA742 EVM: Software Development Board for DRA742 compatible = "ti,dra7-evm", "ti,dra742", "ti,dra74", "ti,dra7" diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index 61c8b4620415..13611a8199bb 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt @@ -9,9 +9,11 @@ Required properties: - compatible : should be one of "apm,potenza-pmu" "arm,armv8-pmuv3" + "arm,cortex-a73-pmu" "arm,cortex-a72-pmu" "arm,cortex-a57-pmu" "arm,cortex-a53-pmu" + "arm,cortex-a35-pmu" "arm,cortex-a17-pmu" "arm,cortex-a15-pmu" "arm,cortex-a12-pmu" diff --git a/Documentation/devicetree/bindings/arm/qcom.txt b/Documentation/devicetree/bindings/arm/qcom.txt index 028d16e72186..0ed4d39d7fe1 100644 --- a/Documentation/devicetree/bindings/arm/qcom.txt +++ b/Documentation/devicetree/bindings/arm/qcom.txt @@ -25,6 +25,7 @@ The 'SoC' element must be one of the following strings: msm8994 msm8996 mdm9615 + ipq8074 The 'board' element must be one of the following strings: @@ -33,6 +34,7 @@ The 'board' element must be one of the following strings: dragonboard mtp sbc + hk01 The 'soc_version' and 'board_version' elements take the form of v. where the minor number may be omitted when it's zero, i.e. v1.0 is the same diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index 11c0ac4a2d56..b003148e2945 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -134,6 +134,10 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "phytec,rk3288-pcm-947", "phytec,rk3288-phycore-som", "rockchip,rk3288"; +- Pine64 Rock64 board: + Required root node properties: + - compatible = "pine64,rock64", "rockchip,rk3328"; + - Rockchip PX3 Evaluation board: Required root node properties: - compatible = "rockchip,px3-evb", "rockchip,px3", "rockchip,rk3188"; @@ -173,6 +177,14 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "rockchip,rk3399-evb", "rockchip,rk3399"; +- Rockchip RK3399 Sapphire Excavator board: + Required root node properties: + - compatible = "rockchip,rk3399-sapphire-excavator", "rockchip,rk3399"; + +- Theobroma Systems RK3399-Q7 Haikou Baseboard: + Required root node properties: + - compatible = "tsd,rk3399-q7-haikou", "rockchip,rk3399"; + - Tronsmart Orion R68 Meta Required root node properties: - compatible = "tronsmart,orion-r68-meta", "rockchip,rk3368"; diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt index 1a671e329864..ae75cb3b1331 100644 --- a/Documentation/devicetree/bindings/arm/shmobile.txt +++ b/Documentation/devicetree/bindings/arm/shmobile.txt @@ -39,6 +39,8 @@ SoCs: compatible = "renesas,r8a7795" - R-Car M3-W (R8A77960) compatible = "renesas,r8a7796" + - R-Car D3 (R8A77995) + compatible = "renesas,r8a77995" Boards: @@ -53,6 +55,8 @@ Boards: compatible = "renesas,blanche", "renesas,r8a7792" - BOCK-W compatible = "renesas,bockw", "renesas,r8a7778" + - Draak (RTP0RC77995SEB0010S) + compatible = "renesas,draak", "renesas,r8a77995" - Genmai (RTK772100BC00000BR) compatible = "renesas,genmai", "renesas,r7s72100" - GR-Peach (X28A-M01-E/F) @@ -64,6 +68,10 @@ Boards: compatible = "renesas,h3ulcb", "renesas,r8a7795"; - Henninger compatible = "renesas,henninger", "renesas,r8a7791" + - iWave Systems RZ/G1E SODIMM SOM Development Platform (iW-RainboW-G22D) + compatible = "iwave,g22d", "iwave,g22m", "renesas,r8a7745" + - iWave Systems RZ/G1E SODIMM System On Module (iW-RainboW-G22M-SM) + compatible = "iwave,g22m", "renesas,r8a7745" - iWave Systems RZ/G1M Qseven Development Platform (iW-RainboW-G20D-Qseven) compatible = "iwave,g20d", "iwave,g20m", "renesas,r8a7743" - iWave Systems RZ/G1M Qseven System On Module (iW-RainboW-G20M-Qseven) diff --git a/Documentation/devicetree/bindings/ata/ahci-mtk.txt b/Documentation/devicetree/bindings/ata/ahci-mtk.txt new file mode 100644 index 000000000000..d2aa696b161b --- /dev/null +++ b/Documentation/devicetree/bindings/ata/ahci-mtk.txt @@ -0,0 +1,51 @@ +MediaTek Serial ATA controller + +Required properties: + - compatible : Must be "mediatek,-ahci", "mediatek,mtk-ahci". + When using "mediatek,mtk-ahci" compatible strings, you + need SoC specific ones in addition, one of: + - "mediatek,mt7622-ahci" + - reg : Physical base addresses and length of register sets. + - interrupts : Interrupt associated with the SATA device. + - interrupt-names : Associated name must be: "hostc". + - clocks : A list of phandle and clock specifier pairs, one for each + entry in clock-names. + - clock-names : Associated names must be: "ahb", "axi", "asic", "rbc", "pm". + - phys : A phandle and PHY specifier pair for the PHY port. + - phy-names : Associated name must be: "sata-phy". + - ports-implemented : See ./ahci-platform.txt for details. + +Optional properties: + - power-domains : A phandle and power domain specifier pair to the power + domain which is responsible for collapsing and restoring + power to the peripheral. + - resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. + - reset-names : Associated names must be: "axi", "sw", "reg". + - mediatek,phy-mode : A phandle to the system controller, used to enable + SATA function. + +Example: + + sata: sata@1a200000 { + compatible = "mediatek,mt7622-ahci", + "mediatek,mtk-ahci"; + reg = <0 0x1a200000 0 0x1100>; + interrupts = ; + interrupt-names = "hostc"; + clocks = <&pciesys CLK_SATA_AHB_EN>, + <&pciesys CLK_SATA_AXI_EN>, + <&pciesys CLK_SATA_ASIC_EN>, + <&pciesys CLK_SATA_RBC_EN>, + <&pciesys CLK_SATA_PM_EN>; + clock-names = "ahb", "axi", "asic", "rbc", "pm"; + phys = <&u3port1 PHY_TYPE_SATA>; + phy-names = "sata-phy"; + ports-implemented = <0x1>; + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + resets = <&pciesys MT7622_SATA_AXI_BUS_RST>, + <&pciesys MT7622_SATA_PHY_SW_RST>, + <&pciesys MT7622_SATA_PHY_REG_RST>; + reset-names = "axi", "sw", "reg"; + mediatek,phy-mode = <&pciesys>; + }; diff --git a/Documentation/devicetree/bindings/ata/apm-xgene.txt b/Documentation/devicetree/bindings/ata/apm-xgene.txt index a668f0e7d001..02e690a675db 100644 --- a/Documentation/devicetree/bindings/ata/apm-xgene.txt +++ b/Documentation/devicetree/bindings/ata/apm-xgene.txt @@ -57,7 +57,6 @@ Example: <0x0 0x1f227000 0x0 0x1000>; interrupts = <0x0 0x87 0x4>; dma-coherent; - status = "ok"; clocks = <&sataclk 0>; phys = <&phy2 0>; phy-names = "sata-phy"; @@ -72,7 +71,6 @@ Example: <0x0 0x1f237000 0x0 0x1000>; interrupts = <0x0 0x88 0x4>; dma-coherent; - status = "ok"; clocks = <&sataclk 0>; phys = <&phy3 0>; phy-names = "sata-phy"; diff --git a/Documentation/devicetree/bindings/ata/imx-pata.txt b/Documentation/devicetree/bindings/ata/imx-pata.txt index e38d73414b0d..f1172f00188a 100644 --- a/Documentation/devicetree/bindings/ata/imx-pata.txt +++ b/Documentation/devicetree/bindings/ata/imx-pata.txt @@ -13,5 +13,4 @@ Example: reg = <0x83fe0000 0x4000>; interrupts = <70>; clocks = <&clks 161>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt index fa6cde41b460..f2ab7fd013bd 100644 --- a/Documentation/devicetree/bindings/bus/mvebu-mbus.txt +++ b/Documentation/devicetree/bindings/bus/mvebu-mbus.txt @@ -227,7 +227,6 @@ See the example below, where a more complete device tree is shown: }; devbus-bootcs { - status = "okay"; ranges = <0 MBUS_ID(0x01, 0x2f) 0 0x8000000>; /* NOR */ @@ -240,7 +239,6 @@ See the example below, where a more complete device tree is shown: pcie-controller { compatible = "marvell,armada-xp-pcie"; - status = "okay"; device_type = "pci"; #address-cells = <3>; @@ -258,7 +256,6 @@ See the example below, where a more complete device tree is shown: pcie@1,0 { /* Port 0, Lane 0 */ - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt index 83b0e54f727c..3e21eb822811 100644 --- a/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt +++ b/Documentation/devicetree/bindings/bus/nvidia,tegra20-gmi.txt @@ -84,7 +84,6 @@ gmi@70090000 { reset-names = "gmi"; ranges = <4 0 0xd0000000 0xfffffff>; - status = "okay"; bus@4,0 { compatible = "simple-bus"; @@ -121,7 +120,6 @@ gmi@70090000 { reset-names = "gmi"; ranges = <4 0 0xd0000000 0xfffffff>; - status = "okay"; can@4,0 { reg = <4 0 0x100>; diff --git a/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt index 7ff13be1750b..3108d03802ee 100644 --- a/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt +++ b/Documentation/devicetree/bindings/bus/nvidia,tegra210-aconnect.txt @@ -33,7 +33,6 @@ Example: #size-cells = <1>; ranges = <0x702c0000 0x0 0x702c0000 0x00040000>; - status = "disabled"; child1 { ... diff --git a/Documentation/devicetree/bindings/chosen.txt b/Documentation/devicetree/bindings/chosen.txt index dee3f5d9df26..e3b13ea7d2ae 100644 --- a/Documentation/devicetree/bindings/chosen.txt +++ b/Documentation/devicetree/bindings/chosen.txt @@ -5,9 +5,31 @@ The chosen node does not represent a real device, but serves as a place for passing data between firmware and the operating system, like boot arguments. Data in the chosen node does not represent the hardware. +The following properties are recognized: -stdout-path property --------------------- + +kaslr-seed +----------- + +This property is used when booting with CONFIG_RANDOMIZE_BASE as the +entropy used to randomize the kernel image base address location. Since +it is used directly, this value is intended only for KASLR, and should +not be used for other purposes (as it may leak information about KASLR +offsets). It is parsed as a u64 value, e.g. + +/ { + chosen { + kaslr-seed = <0xfeedbeef 0xc0def00d>; + }; +}; + +Note that if this property is set from UEFI (or a bootloader in EFI +mode) when EFI_RNG_PROTOCOL is supported, it will be overwritten by +the Linux EFI stub (which will populate the property itself, using +EFI_RNG_PROTOCOL). + +stdout-path +----------- Device trees may specify the device to be used for boot console output with a stdout-path property under /chosen, as described in the Devicetree diff --git a/Documentation/devicetree/bindings/clock/alphascale,acc.txt b/Documentation/devicetree/bindings/clock/alphascale,acc.txt index 62e67e883e76..b3205b21c9d0 100644 --- a/Documentation/devicetree/bindings/clock/alphascale,acc.txt +++ b/Documentation/devicetree/bindings/clock/alphascale,acc.txt @@ -102,7 +102,6 @@ uart4: serial@80010000 { reg = <0x80010000 0x4000>; clocks = <&acc CLKID_SYS_UART4>, <&acc CLKID_AHB_UART4>; interrupts = <19>; - status = "disabled"; }; Clock consumer with only one, _AHB_ sink. diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt index a55d31b48d6e..786dc39ca904 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt @@ -5,9 +5,11 @@ controllers within the Always-On part of the SoC. Required Properties: -- compatible: should be "amlogic,gxbb-aoclkc" -- reg: physical base address of the clock controller and length of memory - mapped region. +- compatible: value should be different for each SoC family as : + - GXBB (S905) : "amlogic,meson-gxbb-aoclkc" + - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc" + - GXM (S912) : "amlogic,meson-gxm-aoclkc" + followed by the common "amlogic,meson-gx-aoclkc" - #clock-cells: should be 1. @@ -23,14 +25,22 @@ to specify the reset which they consume. All available resets are defined as preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be used in device tree sources. +Parent node should have the following properties : +- compatible: "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd" +- reg: base address and size of the AO system control register space. + Example: AO Clock controller node: - clkc_AO: clock-controller@040 { - compatible = "amlogic,gxbb-aoclkc"; - reg = <0x0 0x040 0x0 0x4>; +ao_sysctrl: sys-ctrl@0 { + compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"; + reg = <0x0 0x0 0x0 0x100>; + + clkc_AO: clock-controller { + compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc"; #clock-cells = <1>; #reset-cells = <1>; }; +}; Example: UART controller node that consumes the clock and reset generated by the clock controller: @@ -41,5 +51,4 @@ Example: UART controller node that consumes the clock and reset generated interrupts = <0 90 1>; clocks = <&clkc_AO CLKID_AO_UART1>; resets = <&clkc_AO RESET_AO_UART1>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt index a09d627b5508..924040769186 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt @@ -33,5 +33,4 @@ Example: UART controller node that consumes the clock generated by the clock reg = <0xc81004c0 0x14>; interrupts = <0 90 1>; clocks = <&clkc CLKID_CLK81>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt index 606da38c0959..b455c5aa9139 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt @@ -16,18 +16,25 @@ Required Properties: mapped region. - #clock-cells: should be 1. +- #reset-cells: should be 1. Each clock is assigned an identifier and client nodes can use this identifier to specify the clock which they consume. All available clocks are defined as preprocessor macros in the dt-bindings/clock/meson8b-clkc.h header and can be used in device tree sources. +Similarly a preprocessor macro for each reset line is defined in +dt-bindings/reset/amlogic,meson8b-clkc-reset.h (which can be used from the +device tree sources). + + Example: Clock controller node: clkc: clock-controller@c1104000 { - #clock-cells = <1>; compatible = "amlogic,meson8b-clkc"; reg = <0xc1108000 0x4>, <0xc1104000 0x460>; + #clock-cells = <1>; + #reset-cells = <1>; }; @@ -39,5 +46,4 @@ Example: UART controller node that consumes the clock generated by the clock reg = <0xc81004c0 0x14>; interrupts = <0 90 1>; clocks = <&clkc CLKID_CLK81>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index 5f3ad65daf69..51c259a92d02 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt @@ -81,6 +81,16 @@ Required properties: "atmel,sama5d2-clk-generated": at91 generated clock + "atmel,sama5d2-clk-audio-pll-frac": + at91 audio fractional pll + + "atmel,sama5d2-clk-audio-pll-pad": + at91 audio pll CLK_AUDIO output pin + + "atmel,sama5d2-clk-audio-pll-pmc" + at91 audio pll output on AUDIOPLLCLK that feeds the PMC + and can be used by peripheral clock or generic clock + Required properties for SCKC node: - reg : defines the IO memory reserved for the SCKC. - #size-cells : shall be 0 (reg is used to encode clk id). diff --git a/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt b/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt index 5286e260fcae..8e5a7d868557 100644 --- a/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt +++ b/Documentation/devicetree/bindings/clock/brcm,kona-ccu.txt @@ -46,7 +46,6 @@ Device tree example: uart@3e002000 { compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart"; - status = "disabled"; reg = <0x3e002000 0x1000>; clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>; interrupts = ; diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt index 1dc80f8811fe..fe885abc9cb4 100644 --- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt +++ b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt @@ -465,5 +465,4 @@ Example 3: UART controller node that consumes the clock generated by the clock clock-names = "uart", "clk_uart_baud0"; pinctrl-names = "default"; pinctrl-0 = <&uart0_bus>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/hi3660-clock.txt b/Documentation/devicetree/bindings/clock/hi3660-clock.txt index cc9b86c35758..0035a7ecaf20 100644 --- a/Documentation/devicetree/bindings/clock/hi3660-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3660-clock.txt @@ -38,5 +38,4 @@ Examples: clocks = <&crg_ctrl HI3660_CLK_MUX_UART0>, <&crg_ctrl HI3660_PCLK>; clock-names = "uartclk", "apb_pclk"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt b/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt index 7894a64887cb..4733e58e491b 100644 --- a/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt +++ b/Documentation/devicetree/bindings/clock/hix5hd2-clock.txt @@ -27,5 +27,4 @@ Examples: interrupts = <0 49 4>; clocks = <&clock HIX5HD2_FIXED_83M>; clock-names = "apb_pclk"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt index 53d7e50ed875..05a245c9df08 100644 --- a/Documentation/devicetree/bindings/clock/idt,versaclock5.txt +++ b/Documentation/devicetree/bindings/clock/idt,versaclock5.txt @@ -1,24 +1,32 @@ -Binding for IDT VersaClock5 programmable i2c clock generator. +Binding for IDT VersaClock 5,6 programmable i2c clock generators. -The IDT VersaClock5 are programmable i2c clock generators providing -from 3 to 12 output clocks. +The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock +generators providing from 3 to 12 output clocks. ==I2C device node== Required properties: -- compatible: shall be one of "idt,5p49v5923" , "idt,5p49v5933" , - "idt,5p49v5935". +- compatible: shall be one of + "idt,5p49v5923" + "idt,5p49v5925" + "idt,5p49v5933" + "idt,5p49v5935" + "idt,5p49v6901" - reg: i2c device address, shall be 0x68 or 0x6a. - #clock-cells: from common clock binding; shall be set to 1. - clocks: from common clock binding; list of parent clock handles, - - 5p49v5923: (required) either or both of XTAL or CLKIN + - 5p49v5923 and + 5p49v5925 and + 5p49v6901: (required) either or both of XTAL or CLKIN reference clock. - 5p49v5933 and - 5p49v5935: (optional) property not present (internal Xtal used) or CLKIN reference clock. - clock-names: from common clock binding; clock input names, can be - - 5p49v5923: (required) either or both of "xin", "clkin". + - 5p49v5923 and + 5p49v5925 and + 5p49v6901: (required) either or both of "xin", "clkin". - 5p49v5933 and - 5p49v5935: (optional) property not present or "clkin". @@ -37,6 +45,7 @@ clock specifier, the following mapping applies: 1 -- OUT1 2 -- OUT4 +5P49V5925 and 5P49V5935: 0 -- OUT0_SEL_I2CB 1 -- OUT1 @@ -44,6 +53,13 @@ clock specifier, the following mapping applies: 3 -- OUT3 4 -- OUT4 +5P49V6901: + 0 -- OUT0_SEL_I2CB + 1 -- OUT1 + 2 -- OUT2 + 3 -- OUT3 + 4 -- OUT4 + ==Example== /* 25MHz reference crystal */ diff --git a/Documentation/devicetree/bindings/clock/imx21-clock.txt b/Documentation/devicetree/bindings/clock/imx21-clock.txt index c3b0db437c48..806f63d628bd 100644 --- a/Documentation/devicetree/bindings/clock/imx21-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx21-clock.txt @@ -24,5 +24,4 @@ Examples: clocks = <&clks IMX21_CLK_UART1_IPG_GATE>, <&clks IMX21_CLK_PER1>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx23-clock.txt b/Documentation/devicetree/bindings/clock/imx23-clock.txt index 5083c0b834b2..8385348d3bd9 100644 --- a/Documentation/devicetree/bindings/clock/imx23-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx23-clock.txt @@ -67,5 +67,4 @@ auart0: serial@8006c000 { reg = <0x8006c000 0x2000>; interrupts = <24 25 23>; clocks = <&clks 32>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx25-clock.txt b/Documentation/devicetree/bindings/clock/imx25-clock.txt index ba6b312ff8a5..f8135ea9ca4e 100644 --- a/Documentation/devicetree/bindings/clock/imx25-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx25-clock.txt @@ -157,5 +157,4 @@ uart1: serial@43f90000 { interrupts = <45>; clocks = <&clks 79>, <&clks 50>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx27-clock.txt b/Documentation/devicetree/bindings/clock/imx27-clock.txt index cc05de9ec393..4c95c048d3b2 100644 --- a/Documentation/devicetree/bindings/clock/imx27-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx27-clock.txt @@ -24,5 +24,4 @@ Examples: clocks = <&clks IMX27_CLK_UART1_IPG_GATE>, <&clks IMX27_CLK_PER1_GATE>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx28-clock.txt b/Documentation/devicetree/bindings/clock/imx28-clock.txt index e6587af62ff0..d84a37d2885f 100644 --- a/Documentation/devicetree/bindings/clock/imx28-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx28-clock.txt @@ -90,5 +90,4 @@ auart0: serial@8006a000 { reg = <0x8006a000 0x2000>; interrupts = <112 70 71>; clocks = <&clks 45>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx31-clock.txt b/Documentation/devicetree/bindings/clock/imx31-clock.txt index 8163d565f697..0a291090e562 100644 --- a/Documentation/devicetree/bindings/clock/imx31-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx31-clock.txt @@ -87,5 +87,4 @@ uart1: serial@43f90000 { interrupts = <45>; clocks = <&clks 10>, <&clks 30>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt index cadc4d29ada6..a24ca9e582d2 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -25,5 +25,4 @@ can1: can@53fc8000 { interrupts = <82>; clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, <&clks IMX5_CLK_CAN1_SERIAL_GATE>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index 9252912a5b0e..aa0a4d423ef5 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -27,5 +27,4 @@ uart1: serial@02020000 { interrupts = <0 26 0x04>; clocks = <&clks IMX6QDL_CLK_UART_IPG>, <&clks IMX6QDL_CLK_UART_SERIAL>; clock-names = "ipg", "per"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt b/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt deleted file mode 100644 index 52b457c23eed..000000000000 --- a/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt +++ /dev/null @@ -1,83 +0,0 @@ -Device Tree Clock bindins for CPU DVFS of Mediatek MT8173 SoC - -Required properties: -- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names. -- clock-names: Should contain the following: - "cpu" - The multiplexer for clock input of CPU cluster. - "intermediate" - A parent of "cpu" clock which is used as "intermediate" clock - source (usually MAINPLL) when the original CPU PLL is under - transition and not stable yet. - Please refer to Documentation/devicetree/bindings/clk/clock-bindings.txt for - generic clock consumer properties. -- proc-supply: Regulator for Vproc of CPU cluster. - -Optional properties: -- sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver - needs to do "voltage tracking" to step by step scale up/down Vproc and - Vsram to fit SoC specific needs. When absent, the voltage scaling - flow is handled by hardware, hence no software "voltage tracking" is - needed. - -Example: --------- - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x000>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA53SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x001>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA53SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - cpu2: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x100>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA57SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - cpu3: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x101>; - enable-method = "psci"; - cpu-idle-states = <&CPU_SLEEP_0>; - clocks = <&infracfg CLK_INFRA_CA57SEL>, - <&apmixedsys CLK_APMIXED_MAINPLL>; - clock-names = "cpu", "intermediate"; - }; - - &cpu0 { - proc-supply = <&mt6397_vpca15_reg>; - }; - - &cpu1 { - proc-supply = <&mt6397_vpca15_reg>; - }; - - &cpu2 { - proc-supply = <&da9211_vcpu_reg>; - sram-supply = <&mt6397_vsramca7_reg>; - }; - - &cpu3 { - proc-supply = <&da9211_vcpu_reg>; - sram-supply = <&mt6397_vsramca7_reg>; - }; diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt index 63f9d8277d48..dff236f524a7 100644 --- a/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt +++ b/Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt @@ -66,7 +66,6 @@ clock@70110000 { #clock-cells = <0>; clock-output-names = "dfllCPU_out"; vdd-cpu-supply = <&vdd_cpu>; - status = "okay"; nvidia,sample-rate = <12500>; nvidia,droop-ctrl = <0x00000f00>; diff --git a/Documentation/devicetree/bindings/clock/pxa-clock.txt b/Documentation/devicetree/bindings/clock/pxa-clock.txt index 4b4a9024bd99..8f67239411fe 100644 --- a/Documentation/devicetree/bindings/clock/pxa-clock.txt +++ b/Documentation/devicetree/bindings/clock/pxa-clock.txt @@ -12,5 +12,4 @@ Examples: pxa2xx_clks: pxa2xx_clks@41300004 { compatible = "marvell,pxa-clocks"; #clock-cells = <1>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 0cd894f987a3..316e13686568 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -22,6 +22,7 @@ Required Properties: - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) + - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3) - reg: Base address and length of the memory resource used by the CPG/MSSR block @@ -30,7 +31,7 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, - r8a7795, r8a7796) + r8a7795, r8a7796, r8a77995) - "extalr" (r8a7795, r8a7796) - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) @@ -81,5 +82,4 @@ Examples dma-names = "tx", "rx"; power-domains = <&cpg>; resets = <&cpg 310>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt index e4cdaf1cb333..7cc4c0330b53 100644 --- a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt @@ -44,5 +44,4 @@ Examples interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7778_CLK_SDHI0>; power-domains = <&cpg_clocks>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt new file mode 100644 index 000000000000..e96e085271c1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt @@ -0,0 +1,55 @@ +* Renesas R-Car USB 2.0 clock selector + +This file provides information on what the device node for the R-Car USB 2.0 +clock selector. + +If you connect an external clock to the USB_EXTAL pin only, you should set +the clock rate to "usb_extal" node only. +If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module +is not needed because this is default setting. (Of course, you can set the +clock rates to both "usb_extal" and "usb_xtal" nodes. + +Case 1: An external clock connects to R-Car SoC + +----------+ +--- R-Car ---------------------+ + |External |---|USB_EXTAL ---> all usb channels| + |clock | |USB_XTAL | + +----------+ +-------------------------------+ +In this case, we need this driver with "usb_extal" clock. + +Case 2: An oscillator connects to R-Car SoC + +----------+ +--- R-Car ---------------------+ + |Oscillator|---|USB_EXTAL -+-> all usb channels| + | |---|USB_XTAL --+ | + +----------+ +-------------------------------+ +In this case, we don't need this selector. + +Required properties: +- compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of + an R8A7795 SoC. + "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of + an R8A7796 SoC. + "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3 + compatible device. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + +- reg: offset and length of the USB 2.0 clock selector register block. +- clocks: A list of phandles and specifier pairs. +- clock-names: Name of the clocks. + - The functional clock must be "ehci_ohci" + - The USB_EXTAL clock pin must be "usb_extal" + - The USB_XTAL clock pin must be "usb_xtal" +- #clock-cells: Must be 0 + +Example (R-Car H3): + + usb2_clksel: clock-controller@e6590630 { + compatible = "renesas,r8a77950-rcar-usb2-clock-sel", + "renesas,rcar-gen3-usb2-clock-sel"; + reg = <0 0xe6590630 0 0x02>; + clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>; + clock-names = "ehci_ohci", "usb_extal", "usb_xtal"; + #clock-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt index bb51a33a1fbf..bb5d942075fb 100644 --- a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt +++ b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt @@ -50,5 +50,4 @@ Examples clocks = <&mstp3_clks R7S72100_CLK_MTU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt index 455a9a00a623..6f8744fd301b 100644 --- a/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt +++ b/Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt @@ -1,12 +1,14 @@ -* Rockchip RK3128 Clock and Reset Unit +* Rockchip RK3126/RK3128 Clock and Reset Unit -The RK3128 clock controller generates and supplies clock to various +The RK3126/RK3128 clock controller generates and supplies clock to various controllers within the SoC and also implements a reset controller for SoC peripherals. Required Properties: -- compatible: should be "rockchip,rk3128-cru" +- compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru" + "rockchip,rk3126-cru" - controller compatible with RK3126 SoC. + "rockchip,rk3128-cru" - controller compatible with RK3128 SoC. - reg: physical base address of the controller and length of memory mapped region. - #clock-cells: should be 1. diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt index 822505e715ae..2632d3f13004 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt @@ -46,5 +46,4 @@ Example: UART controller node that consumes the clock generated by the clock interrupts = <1 23 3 4>, <1 23 4 4>; clock-names = "uart", "clk_uart_baud2"; clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt index 2b430960ba47..21a8c23e658f 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt @@ -46,5 +46,4 @@ Example: UART controller node that consumes the clock generated by the clock clock-names = "uart", "clk_uart_baud2", "clk_uart_baud3"; clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>, <&clocks SCLK_UART>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt index e67bb05478af..985c0f574e9a 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt @@ -52,5 +52,4 @@ Example: UART controller node that consumes the clock generated by the clock "clk_uart_baud3"; clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>, <&clocks SCLK_UART>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt index fa171dc4bd3c..872ee8e0f041 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s3c64xx-clock.txt @@ -73,5 +73,4 @@ Example: UART controller node that consumes the clock generated by the clock "clk_uart_baud3"; clocks = <&clock PCLK_UART0>, <&clocks PCLK_UART0>, <&clock SCLK_UART>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt index effd9401c133..15b48e20a061 100644 --- a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt +++ b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt @@ -74,5 +74,4 @@ Example: UART controller node that consumes the clock generated by the clock "clk_uart_baud1"; clocks = <&clocks UART0>, <&clocks UART0>, <&clocks SCLK_UART0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt b/Documentation/devicetree/bindings/clock/silabs,si5351.txt index 28b28309f535..a6c4ef343b44 100644 --- a/Documentation/devicetree/bindings/clock/silabs,si5351.txt +++ b/Documentation/devicetree/bindings/clock/silabs,si5351.txt @@ -12,7 +12,11 @@ generators can be found in [1]. ==I2C device node== Required properties: -- compatible: shall be one of "silabs,si5351{a,a-msop,b,c}". +- compatible: shall be one of the following: + "silabs,si5351a" - Si5351a, QFN20 package + "silabs,si5351a-msop" - Si5351a, MSOP10 package + "silabs,si5351b" - Si5351b, QFN20 package + "silabs,si5351c" - Si5351c, QFN20 package - reg: i2c device address, shall be 0x60 or 0x61. - #clock-cells: from common clock binding; shall be set to 1. - clocks: from common clock binding; list of parent clock diff --git a/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt new file mode 100644 index 000000000000..c56c7553c730 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt @@ -0,0 +1,28 @@ +Binding for the HSDK Generic PLL clock + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible: should be "snps,hsdk--pll-clock" + "snps,hsdk-core-pll-clock" + "snps,hsdk-gp-pll-clock" + "snps,hsdk-hdmi-pll-clock" +- reg : should contain base register location and length. +- clocks: shall be the input parent clock phandle for the PLL. +- #clock-cells: from common clock binding; Should always be set to 0. + +Example: + input_clk: input-clk { + clock-frequency = <33333333>; + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + cpu_clk: cpu-clk@0 { + compatible = "snps,hsdk-core-pll-clock"; + reg = <0x00 0x10>; + #clock-cells = <0>; + clocks = <&input_clk>; + }; diff --git a/Documentation/devicetree/bindings/clock/snps,pll-clock.txt b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt new file mode 100644 index 000000000000..11fe4876612c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/snps,pll-clock.txt @@ -0,0 +1,28 @@ +Binding for the AXS10X Generic PLL clock + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible: should be "snps,axs10x--pll-clock" + "snps,axs10x-arc-pll-clock" + "snps,axs10x-pgu-pll-clock" +- reg: should always contain 2 pairs address - length: first for PLL config +registers and second for corresponding LOCK CGU register. +- clocks: shall be the input parent clock phandle for the PLL. +- #clock-cells: from common clock binding; Should always be set to 0. + +Example: + input-clk: input-clk { + clock-frequency = <33333333>; + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + core-clk: core-clk@80 { + compatible = "snps,axs10x-arc-pll-clock"; + reg = <0x80 0x10>, <0x100 0x10>; + #clock-cells = <0>; + clocks = <&input-clk>; + }; diff --git a/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt new file mode 100644 index 000000000000..cac24ee10b72 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt @@ -0,0 +1,71 @@ +STMicroelectronics STM32H7 Reset and Clock Controller +===================================================== + +The RCC IP is both a reset and a clock controller. + +Please refer to clock-bindings.txt for common clock controller binding usage. +Please also refer to reset.txt for common reset controller binding usage. + +Required properties: +- compatible: Should be: + "st,stm32h743-rcc" + +- reg: should be register base and length as documented in the + datasheet + +- #reset-cells: 1, see below + +- #clock-cells : from common clock binding; shall be set to 1 + +- clocks: External oscillator clock phandle + - high speed external clock signal (HSE) + - low speed external clock signal (LSE) + - external I2S clock (I2S_CKIN) + +Optional properties: +- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain + write protection (RTC clock). + +Example: + + rcc: reset-clock-controller@58024400 { + compatible = "st,stm32h743-rcc", "st,stm32-rcc"; + reg = <0x58024400 0x400>; + #reset-cells = <1>; + #clock-cells = <1>; + clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>; + + st,syscfg = <&pwrcfg>; +}; + +The peripheral clock consumer should specify the desired clock by +having the clock ID in its "clocks" phandle cell. + +Example: + + timer5: timer@40000c00 { + compatible = "st,stm32-timer"; + reg = <0x40000c00 0x400>; + interrupts = <50>; + clocks = <&rcc TIM5_CK>; + }; + +Specifying softreset control of devices +======================================= + +Device nodes should specify the reset channel required in their "resets" +property, containing a phandle to the reset device node and an index specifying +which channel to use. +The index is the bit number within the RCC registers bank, starting from RCC +base address. +It is calculated as: index = register_offset / 4 * 32 + bit_offset. +Where bit_offset is the bit offset within the register. + +For example, for CRC reset: + crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107 + +Example: + + timer2 { + resets = <&rcc STM32H7_APB1L_RESET(TIM2)>; + }; diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt index df9fad58facd..7eda08eb8a1e 100644 --- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt +++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt @@ -3,18 +3,24 @@ Allwinner Clock Control Unit Binding Required properties : - compatible: must contain one of the following compatibles: + - "allwinner,sun4i-a10-ccu" + - "allwinner,sun5i-a10s-ccu" + - "allwinner,sun5i-a13-ccu" - "allwinner,sun6i-a31-ccu" + - "allwinner,sun7i-a20-ccu" - "allwinner,sun8i-a23-ccu" - "allwinner,sun8i-a33-ccu" - "allwinner,sun8i-a83t-ccu" - "allwinner,sun8i-a83t-r-ccu" - "allwinner,sun8i-h3-ccu" - "allwinner,sun8i-h3-r-ccu" ++ - "allwinner,sun8i-r40-ccu" - "allwinner,sun8i-v3s-ccu" - "allwinner,sun9i-a80-ccu" - "allwinner,sun50i-a64-ccu" - "allwinner,sun50i-a64-r-ccu" - "allwinner,sun50i-h5-ccu" + - "nextthing,gr8-ccu" - reg: Must contain the registers base address and length - clocks: phandle to the oscillators feeding the CCU. Two are needed: diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt index 1e884c40ab50..4e59dc6b1778 100644 --- a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt @@ -14,10 +14,9 @@ Required properties: - compatible: Must be "ti,k2g-sci-clk" - #clock-cells: Shall be 2. In clock consumers, this cell represents the device ID and clock ID - exposed by the PM firmware. The assignments can be found in the header - files .h> (which covers the device IDs) and - .h> (which covers the clock IDs), where - is the SoC involved, for example 'k2g'. + exposed by the PM firmware. The list of valid values for the device IDs + and clocks IDs for 66AK2G SoC are documented at + http://processors.wiki.ti.com/index.php/TISCI#66AK2G02_Data Examples: -------- diff --git a/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt b/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt index 585e8c191f50..10f7047755f3 100644 --- a/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt +++ b/Documentation/devicetree/bindings/clock/ti/dra7-atl.txt @@ -81,13 +81,11 @@ atl: atl@4843c000 { <&atl_clkin2_ck>, <&atl_clkin3_ck>; clocks = <&atl_gfclk_mux>; clock-names = "fck"; - status = "disabled"; }; #include &atl { - status = "okay"; atl2 { bws = ; diff --git a/Documentation/devicetree/bindings/clock/uniphier-clock.txt b/Documentation/devicetree/bindings/clock/uniphier-clock.txt index 812163060fa3..7b5f602765fe 100644 --- a/Documentation/devicetree/bindings/clock/uniphier-clock.txt +++ b/Documentation/devicetree/bindings/clock/uniphier-clock.txt @@ -6,7 +6,6 @@ System clock Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-clock" - for sLD3 SoC. "socionext,uniphier-ld4-clock" - for LD4 SoC. "socionext,uniphier-pro4-clock" - for Pro4 SoC. "socionext,uniphier-sld8-clock" - for sLD8 SoC. @@ -14,6 +13,7 @@ Required properties: "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC. "socionext,uniphier-ld11-clock" - for LD11 SoC. "socionext,uniphier-ld20-clock" - for LD20 SoC. + "socionext,uniphier-pxs3-clock" - for PXs3 SoC - #clock-cells: should be 1. Example: @@ -48,7 +48,6 @@ Media I/O (MIO) clock, SD clock Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-mio-clock" - for sLD3 SoC. "socionext,uniphier-ld4-mio-clock" - for LD4 SoC. "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC. "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC. @@ -56,6 +55,7 @@ Required properties: "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC. "socionext,uniphier-ld11-mio-clock" - for LD11 SoC. "socionext,uniphier-ld20-sd-clock" - for LD20 SoC. + "socionext,uniphier-pxs3-sd-clock" - for PXs3 SoC - #clock-cells: should be 1. Example: @@ -82,11 +82,9 @@ Provided clocks: 8: USB2 ch0 host 9: USB2 ch1 host 10: USB2 ch2 host -11: USB2 ch3 host 12: USB2 ch0 PHY 13: USB2 ch1 PHY 14: USB2 ch2 PHY -15: USB2 ch3 PHY Peripheral clock @@ -94,7 +92,6 @@ Peripheral clock Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-peri-clock" - for sLD3 SoC. "socionext,uniphier-ld4-peri-clock" - for LD4 SoC. "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC. "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC. @@ -102,6 +99,7 @@ Required properties: "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC. "socionext,uniphier-ld11-peri-clock" - for LD11 SoC. "socionext,uniphier-ld20-peri-clock" - for LD20 SoC. + "socionext,uniphier-pxs3-peri-clock" - for PXs3 SoC - #clock-cells: should be 1. Example: diff --git a/Documentation/devicetree/bindings/clock/zx296702-clk.txt b/Documentation/devicetree/bindings/clock/zx296702-clk.txt index 750442b65505..e85ecb510d56 100644 --- a/Documentation/devicetree/bindings/clock/zx296702-clk.txt +++ b/Documentation/devicetree/bindings/clock/zx296702-clk.txt @@ -31,5 +31,4 @@ uart0: serial@0x09405000 { reg = <0x09405000 0x1000>; interrupts = ; clocks = <&lsp1clk ZX296702_UART0_PCLK>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/clock/zx296718-clk.txt b/Documentation/devicetree/bindings/clock/zx296718-clk.txt index 4ad703808407..3a46bf0b2540 100644 --- a/Documentation/devicetree/bindings/clock/zx296718-clk.txt +++ b/Documentation/devicetree/bindings/clock/zx296718-clk.txt @@ -34,5 +34,4 @@ usbphy0:usb-phy0 { #phy-cells = <0>; clocks = <&topclk USB20_PHY_CLK>; clock-names = "phyclk"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt new file mode 100644 index 000000000000..f6403089edcf --- /dev/null +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek.txt @@ -0,0 +1,247 @@ +Binding for MediaTek's CPUFreq driver +===================================== + +Required properties: +- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names. +- clock-names: Should contain the following: + "cpu" - The multiplexer for clock input of CPU cluster. + "intermediate" - A parent of "cpu" clock which is used as "intermediate" clock + source (usually MAINPLL) when the original CPU PLL is under + transition and not stable yet. + Please refer to Documentation/devicetree/bindings/clk/clock-bindings.txt for + generic clock consumer properties. +- operating-points-v2: Please refer to Documentation/devicetree/bindings/opp/opp.txt + for detail. +- proc-supply: Regulator for Vproc of CPU cluster. + +Optional properties: +- sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver + needs to do "voltage tracking" to step by step scale up/down Vproc and + Vsram to fit SoC specific needs. When absent, the voltage scaling + flow is handled by hardware, hence no software "voltage tracking" is + needed. +- #cooling-cells: +- cooling-min-level: +- cooling-max-level: + Please refer to Documentation/devicetree/bindings/thermal/thermal.txt + for detail. + +Example 1 (MT7623 SoC): + + cpu_opp_table: opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp-598000000 { + opp-hz = /bits/ 64 <598000000>; + opp-microvolt = <1050000>; + }; + + opp-747500000 { + opp-hz = /bits/ 64 <747500000>; + opp-microvolt = <1050000>; + }; + + opp-1040000000 { + opp-hz = /bits/ 64 <1040000000>; + opp-microvolt = <1150000>; + }; + + opp-1196000000 { + opp-hz = /bits/ 64 <1196000000>; + opp-microvolt = <1200000>; + }; + + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1300000>; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x0>; + clocks = <&infracfg CLK_INFRA_CPUSEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; + cooling-min-level = <0>; + cooling-max-level = <7>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x1>; + operating-points-v2 = <&cpu_opp_table>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x2>; + operating-points-v2 = <&cpu_opp_table>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x3>; + operating-points-v2 = <&cpu_opp_table>; + }; + +Example 2 (MT8173 SoC): + cpu_opp_table_a: opp_table_a { + compatible = "operating-points-v2"; + opp-shared; + + opp-507000000 { + opp-hz = /bits/ 64 <507000000>; + opp-microvolt = <859000>; + }; + + opp-702000000 { + opp-hz = /bits/ 64 <702000000>; + opp-microvolt = <908000>; + }; + + opp-1001000000 { + opp-hz = /bits/ 64 <1001000000>; + opp-microvolt = <983000>; + }; + + opp-1105000000 { + opp-hz = /bits/ 64 <1105000000>; + opp-microvolt = <1009000>; + }; + + opp-1183000000 { + opp-hz = /bits/ 64 <1183000000>; + opp-microvolt = <1028000>; + }; + + opp-1404000000 { + opp-hz = /bits/ 64 <1404000000>; + opp-microvolt = <1083000>; + }; + + opp-1508000000 { + opp-hz = /bits/ 64 <1508000000>; + opp-microvolt = <1109000>; + }; + + opp-1573000000 { + opp-hz = /bits/ 64 <1573000000>; + opp-microvolt = <1125000>; + }; + }; + + cpu_opp_table_b: opp_table_b { + compatible = "operating-points-v2"; + opp-shared; + + opp-507000000 { + opp-hz = /bits/ 64 <507000000>; + opp-microvolt = <828000>; + }; + + opp-702000000 { + opp-hz = /bits/ 64 <702000000>; + opp-microvolt = <867000>; + }; + + opp-1001000000 { + opp-hz = /bits/ 64 <1001000000>; + opp-microvolt = <927000>; + }; + + opp-1209000000 { + opp-hz = /bits/ 64 <1209000000>; + opp-microvolt = <968000>; + }; + + opp-1404000000 { + opp-hz = /bits/ 64 <1007000000>; + opp-microvolt = <1028000>; + }; + + opp-1612000000 { + opp-hz = /bits/ 64 <1612000000>; + opp-microvolt = <1049000>; + }; + + opp-1807000000 { + opp-hz = /bits/ 64 <1807000000>; + opp-microvolt = <1089000>; + }; + + opp-1989000000 { + opp-hz = /bits/ 64 <1989000000>; + opp-microvolt = <1125000>; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x000>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA53SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_a>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x001>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA53SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_a>; + }; + + cpu2: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x100>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA57SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_b>; + }; + + cpu3: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a57"; + reg = <0x101>; + enable-method = "psci"; + cpu-idle-states = <&CPU_SLEEP_0>; + clocks = <&infracfg CLK_INFRA_CA57SEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table_b>; + }; + + &cpu0 { + proc-supply = <&mt6397_vpca15_reg>; + }; + + &cpu1 { + proc-supply = <&mt6397_vpca15_reg>; + }; + + &cpu2 { + proc-supply = <&da9211_vcpu_reg>; + sram-supply = <&mt6397_vsramca7_reg>; + }; + + &cpu3 { + proc-supply = <&da9211_vcpu_reg>; + sram-supply = <&mt6397_vsramca7_reg>; + }; diff --git a/Documentation/devicetree/bindings/crypto/artpec6-crypto.txt b/Documentation/devicetree/bindings/crypto/artpec6-crypto.txt new file mode 100644 index 000000000000..d9cca4875bd6 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/artpec6-crypto.txt @@ -0,0 +1,16 @@ +Axis crypto engine with PDMA interface. + +Required properties: +- compatible : Should be one of the following strings: + "axis,artpec6-crypto" for the version in the Axis ARTPEC-6 SoC + "axis,artpec7-crypto" for the version in the Axis ARTPEC-7 SoC. +- reg: Base address and size for the PDMA register area. +- interrupts: Interrupt handle for the PDMA interrupt line. + +Example: + +crypto@f4264000 { + compatible = "axis,artpec6-crypto"; + reg = <0xf4264000 0x1000>; + interrupts = ; +}; diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt index f2aab3dc2b52..7de1a9674c70 100644 --- a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt +++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt @@ -66,3 +66,16 @@ sha@f8034000 { dmas = <&dma1 2 17>; dma-names = "tx"; }; + +* Eliptic Curve Cryptography (I2C) + +Required properties: +- compatible : must be "atmel,atecc508a". +- reg: I2C bus address of the device. +- clock-frequency: must be present in the i2c controller node. + +Example: +atecc508a@C0 { + compatible = "atmel,atecc508a"; + reg = <0xC0>; +}; diff --git a/Documentation/devicetree/bindings/crypto/fsl-dcp.txt b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt index 6949e50f1f16..76a0b4e80e83 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-dcp.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-dcp.txt @@ -13,5 +13,4 @@ dcp@80028000 { compatible = "fsl,imx28-dcp", "fsl,imx23-dcp"; reg = <0x80028000 0x2000>; interrupts = <52 53>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt index 941bb6a6fb13..fbc07d12322f 100644 --- a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt +++ b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt @@ -23,5 +23,4 @@ Example: interrupt-names = "mem", "ring0", "ring1", "ring2", "ring3", "eip"; clocks = <&cpm_syscon0 1 26>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/crypto/marvell-cesa.txt b/Documentation/devicetree/bindings/crypto/marvell-cesa.txt index c6c6a4a045bd..28d3f2496b89 100644 --- a/Documentation/devicetree/bindings/crypto/marvell-cesa.txt +++ b/Documentation/devicetree/bindings/crypto/marvell-cesa.txt @@ -41,5 +41,4 @@ Examples: clock-names = "cesa0", "cesa1"; marvell,crypto-srams = <&crypto_sram0>, <&crypto_sram1>; marvell,crypto-sram-size = <0x600>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/mv_cesa.txt b/Documentation/devicetree/bindings/crypto/mv_cesa.txt index c0c35f00335b..d9b92e2f3138 100644 --- a/Documentation/devicetree/bindings/crypto/mv_cesa.txt +++ b/Documentation/devicetree/bindings/crypto/mv_cesa.txt @@ -29,5 +29,4 @@ Examples: interrupts = <22>; marvell,crypto-srams = <&crypto_sram>; marvell,crypto-sram-size = <0x600>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt index 096df34b11c1..5e2ba385b8c9 100644 --- a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -25,5 +25,4 @@ Examples: clock-names = "aclk", "hclk", "sclk", "apb_pclk"; resets = <&cru SRST_CRYPTO>; reset-names = "crypto-rst"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/crypto/st,stm32-hash.txt b/Documentation/devicetree/bindings/crypto/st,stm32-hash.txt new file mode 100644 index 000000000000..04fc246f02f7 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/st,stm32-hash.txt @@ -0,0 +1,30 @@ +* STMicroelectronics STM32 HASH + +Required properties: +- compatible: Should contain entries for this and backward compatible + HASH versions: + - "st,stm32f456-hash" for stm32 F456. + - "st,stm32f756-hash" for stm32 F756. +- reg: The address and length of the peripheral registers space +- interrupts: the interrupt specifier for the HASH +- clocks: The input clock of the HASH instance + +Optional properties: +- resets: The input reset of the HASH instance +- dmas: DMA specifiers for the HASH. See the DMA client binding, + Documentation/devicetree/bindings/dma/dma.txt +- dma-names: DMA request name. Should be "in" if a dma is present. +- dma-maxburst: Set number of maximum dma burst supported + +Example: + +hash1: hash@50060400 { + compatible = "st,stm32f756-hash"; + reg = <0x50060400 0x400>; + interrupts = <80>; + clocks = <&rcc 0 STM32F7_AHB2_CLOCK(HASH)>; + resets = <&rcc STM32F7_AHB2_RESET(HASH)>; + dmas = <&dma2 7 2 0x400 0x0>; + dma-names = "in"; + dma-maxburst = <0>; +}; diff --git a/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt b/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt index f2233138eba9..001dd63979a9 100644 --- a/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt +++ b/Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt @@ -15,5 +15,4 @@ Example: rockchip,pmu = <&pmugrf>; clocks = <&cru PCLK_DDR_MON>; clock-names = "pclk_ddr_mon"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt index 7a9e8603c150..d6d2833482c9 100644 --- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt +++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt @@ -205,5 +205,4 @@ Example: rockchip,phy_lpddr4_ck_cs_drv = ; rockchip,phy_lpddr4_dq_drv = ; rockchip,phy_lpddr4_odt = ; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/display/atmel,lcdc.txt b/Documentation/devicetree/bindings/display/atmel,lcdc.txt index ecb8da063d07..1a21202778ee 100644 --- a/Documentation/devicetree/bindings/display/atmel,lcdc.txt +++ b/Documentation/devicetree/bindings/display/atmel,lcdc.txt @@ -34,7 +34,6 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fb>; display = <&display0>; - status = "okay"; #address-cells = <1>; #size-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt index ec94468b35be..82f2acb3d374 100644 --- a/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt +++ b/Documentation/devicetree/bindings/display/atmel/hlcdc-dc.txt @@ -23,7 +23,6 @@ Example: interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; clock-names = "periph_clk","sys_clk", "slow_clk"; - status = "disabled"; hlcdc-display-controller { compatible = "atmel,hlcdc-display-controller"; diff --git a/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt b/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt new file mode 100644 index 000000000000..b13adf30b8d3 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt @@ -0,0 +1,32 @@ +Synopsys DesignWare MIPI DSI host controller +============================================ + +This document defines device tree properties for the Synopsys DesignWare MIPI +DSI host controller. It doesn't constitue a device tree binding specification +by itself but is meant to be referenced by platform-specific device tree +bindings. + +When referenced from platform device tree bindings the properties defined in +this document are defined as follows. The platform device tree bindings are +responsible for defining whether each optional property is used or not. + +- reg: Memory mapped base address and length of the DesignWare MIPI DSI + host controller registers. (mandatory) + +- clocks: References to all the clocks specified in the clock-names property + as specified in [1]. (mandatory) + +- clock-names: + - "pclk" is the peripheral clock for either AHB and APB. (mandatory) + - "px_clk" is the pixel clock for the DPI/RGB input. (optional) + +- resets: References to all the resets specified in the reset-names property + as specified in [2]. (optional) + +- reset-names: string reset name, must be "apb" if used. (optional) + +- panel or bridge node: see [3]. (mandatory) + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/reset/reset.txt +[3] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt diff --git a/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt b/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt index 7baa6582517e..aacc8b92968c 100644 --- a/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt +++ b/Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt @@ -33,7 +33,6 @@ stdp2690-ge-b850v3-fw required properties: Example: &mux2_i2c2 { - status = "okay"; clock-frequency = <100000>; stdp4028@73 { diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt index 81b68580e199..b1a8929c2536 100644 --- a/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt +++ b/Documentation/devicetree/bindings/display/bridge/renesas,dw-hdmi.txt @@ -13,6 +13,7 @@ Required properties: - compatible : Shall contain one or more of - "renesas,r8a7795-hdmi" for R8A7795 (R-Car H3) compatible HDMI TX + - "renesas,r8a7796-hdmi" for R8A7796 (R-Car M3-W) compatible HDMI TX - "renesas,rcar-gen3-hdmi" for the generic R-Car Gen3 compatible HDMI TX When compatible with generic versions, nodes must list the SoC-specific @@ -43,7 +44,6 @@ Example: clocks = <&cpg CPG_CORE R8A7795_CLK_S0D4>, <&cpg CPG_MOD 729>; clock-names = "iahb", "isfr"; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; - status = "disabled"; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt index 549c538b38a5..fc2588292a68 100644 --- a/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt +++ b/Documentation/devicetree/bindings/display/exynos/exynos5433-decon.txt @@ -25,12 +25,6 @@ Required properties: size-cells must 1 and 0, respectively. - port: contains an endpoint node which is connected to the endpoint in the mic node. The reg value muset be 0. -- i80-if-timings: specify whether the panel which is connected to decon uses - i80 lcd interface or mipi video interface. This node contains - no timing information as that of fimd does. Because there is - no register in decon to specify i80 interface timing value, - it is not needed, but make it remain to use same kind of node - in fimd and exynos7 decon. Example: SoC specific DT entry: @@ -59,9 +53,3 @@ decon: decon@13800000 { }; }; }; - -Board specific DT entry: -&decon { - i80-if-timings { - }; -}; diff --git a/Documentation/devicetree/bindings/display/fsl,tcon.txt b/Documentation/devicetree/bindings/display/fsl,tcon.txt index 6fa4ab668db5..475008747801 100644 --- a/Documentation/devicetree/bindings/display/fsl,tcon.txt +++ b/Documentation/devicetree/bindings/display/fsl,tcon.txt @@ -14,5 +14,4 @@ timing-controller@4003d000 { reg = <0x4003d000 0x1000>; clocks = <&clks VF610_CLK_TCON0>; clock-names = "ipg"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt index fa01db7eb66c..f79854783c2c 100644 --- a/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt +++ b/Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt @@ -116,7 +116,7 @@ Parallel display support Required properties: - compatible: Should be "fsl,imx-parallel-display" Optional properties: -- interface_pix_fmt: How this display is connected to the +- interface-pix-fmt: How this display is connected to the display interface. Currently supported types: "rgb24", "rgb565", "bgr666" and "lvds666". - edid: verbatim EDID data block describing attached display. diff --git a/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt b/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt index 309c47f25b87..f79641bd5f18 100644 --- a/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt +++ b/Documentation/devicetree/bindings/display/marvell,pxa2xx-lcdc.txt @@ -23,7 +23,6 @@ Example: reg = <0x44000000 0x10000>; interrupts = <17>; clocks = <&clks CLK_LCD>; - status = "okay"; port { lcdc_out: endpoint { diff --git a/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt b/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt index 5c70a8380e58..d0f55161579a 100644 --- a/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt +++ b/Documentation/devicetree/bindings/display/panel/innolux,p079zca.txt @@ -18,6 +18,5 @@ Example: power-supply = <...>; backlight = <&backlight>; enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt index c6cb96a4fa93..4bbd1e9bf3be 100644 --- a/Documentation/devicetree/bindings/display/renesas,du.txt +++ b/Documentation/devicetree/bindings/display/renesas,du.txt @@ -36,8 +36,10 @@ Required Properties: When supplied they must be named "dclkin.x" with "x" being the input clock numerical index. - - vsps: A list of phandles to the VSP nodes that handle the memory - interfaces for the DU channels. + - vsps: A list of phandle and channel index tuples to the VSPs that handle + the memory interfaces for the DU channels. The phandle identifies the VSP + instance that serves the DU channel, and the channel index identifies the + LIF instance in that VSP. Required nodes: @@ -59,24 +61,24 @@ corresponding to each DU output. R8A7796 (M3-W) DPAD HDMI LVDS - -Example: R8A7790 (R-Car H2) DU +Example: R8A7795 (R-Car H3) ES2.0 DU - du: du@feb00000 { - compatible = "renesas,du-r8a7790"; - reg = <0 0xfeb00000 0 0x70000>, - <0 0xfeb90000 0 0x1c>, - <0 0xfeb94000 0 0x1c>; - reg-names = "du", "lvds.0", "lvds.1"; - interrupt-parent = <&gic>; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>, - <0 269 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_DU0>, - <&mstp7_clks R8A7790_CLK_DU1>, - <&mstp7_clks R8A7790_CLK_DU2>, - <&mstp7_clks R8A7790_CLK_LVDS0>, - <&mstp7_clks R8A7790_CLK_LVDS1>; - clock-names = "du.0", "du.1", "du.2", "lvds.0", "lvds.1"; + du: display@feb00000 { + compatible = "renesas,du-r8a7795"; + reg = <0 0xfeb00000 0 0x80000>, + <0 0xfeb90000 0 0x14>; + reg-names = "du", "lvds.0"; + interrupts = , + , + , + ; + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 721>, + <&cpg CPG_MOD 727>; + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; + vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>; ports { #address-cells = <1>; @@ -89,12 +91,19 @@ Example: R8A7790 (R-Car H2) DU }; port@1 { reg = <1>; - du_out_lvds0: endpoint { + du_out_hdmi0: endpoint { + remote-endpoint = <&dw_hdmi0_in>; }; }; port@2 { reg = <2>; - du_out_lvds1: endpoint { + du_out_hdmi1: endpoint { + remote-endpoint = <&dw_hdmi1_in>; + }; + }; + port@3 { + reg = <3>; + du_out_lvds0: endpoint { }; }; }; diff --git a/Documentation/devicetree/bindings/display/repaper.txt b/Documentation/devicetree/bindings/display/repaper.txt new file mode 100644 index 000000000000..f5f9f9cf6a25 --- /dev/null +++ b/Documentation/devicetree/bindings/display/repaper.txt @@ -0,0 +1,52 @@ +Pervasive Displays RePaper branded e-ink displays + +Required properties: +- compatible: "pervasive,e1144cs021" for 1.44" display + "pervasive,e1190cs021" for 1.9" display + "pervasive,e2200cs021" for 2.0" display + "pervasive,e2271cs021" for 2.7" display + +- panel-on-gpios: Timing controller power control +- discharge-gpios: Discharge control +- reset-gpios: RESET pin +- busy-gpios: BUSY pin + +Required property for e2271cs021: +- border-gpios: Border control + +The node for this driver must be a child node of a SPI controller, hence +all mandatory properties described in ../spi/spi-bus.txt must be specified. + +Optional property: +- pervasive,thermal-zone: name of thermometer's thermal zone + +Example: + + display_temp: lm75@48 { + compatible = "lm75b"; + reg = <0x48>; + #thermal-sensor-cells = <0>; + }; + + thermal-zones { + display { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&display_temp>; + }; + }; + + papirus27@0{ + compatible = "pervasive,e2271cs021"; + reg = <0>; + + spi-max-frequency = <8000000>; + + panel-on-gpios = <&gpio 23 0>; + border-gpios = <&gpio 14 0>; + discharge-gpios = <&gpio 15 0>; + reset-gpios = <&gpio 24 0>; + busy-gpios = <&gpio 25 0>; + + pervasive,thermal-zone = "display"; + }; diff --git a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt index 47665a12786f..43561584c13a 100644 --- a/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt @@ -59,7 +59,6 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&edp_hpd>; - status = "disabled"; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt index 046076c6b277..adc94fc3c9f8 100644 --- a/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/dw_hdmi-rockchip.txt @@ -11,7 +11,9 @@ following device-specific properties. Required properties: -- compatible: Shall contain "rockchip,rk3288-dw-hdmi". +- compatible: should be one of the following: + "rockchip,rk3288-dw-hdmi" + "rockchip,rk3399-dw-hdmi" - reg: See dw_hdmi.txt. - reg-io-width: See dw_hdmi.txt. Shall be 4. - interrupts: HDMI interrupt number @@ -30,7 +32,8 @@ Optional properties I2C master controller. - clock-names: See dw_hdmi.txt. The "cec" clock is optional. - clock-names: May contain "cec" as defined in dw_hdmi.txt. - +- clock-names: May contain "grf", power for grf io. +- clock-names: May contain "vpll", external clock for some hdmi phy. Example: @@ -43,7 +46,6 @@ hdmi: hdmi@ff980000 { interrupts = ; clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>; clock-names = "iahb", "isfr"; - status = "disabled"; ports { hdmi_in: port { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt index 543b07435f4f..6bb59ab39f2f 100644 --- a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt @@ -36,7 +36,6 @@ Example: resets = <&cru SRST_MIPIDSI0>; reset-names = "apb"; rockchip,grf = <&grf>; - status = "okay"; ports { #address-cells = <1>; @@ -65,6 +64,5 @@ Example: pinctrl-names = "default"; pinctrl-0 = <&lcd_en>; backlight = <&backlight>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt index 8096a29f9776..cec21714f0e0 100644 --- a/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt +++ b/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt @@ -25,7 +25,6 @@ hdmi: hdmi@20034000 { clock-names = "pclk"; pinctrl-names = "default"; pinctrl-0 = <&hdmi_ctl>; - status = "disabled"; hdmi_in: port { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt index 9eb3f0a2a078..5d835d9c1ba8 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop.txt @@ -8,8 +8,12 @@ Required properties: - compatible: value should be one of the following "rockchip,rk3036-vop"; "rockchip,rk3288-vop"; + "rockchip,rk3368-vop"; + "rockchip,rk3366-vop"; "rockchip,rk3399-vop-big"; "rockchip,rk3399-vop-lit"; + "rockchip,rk3228-vop"; + "rockchip,rk3328-vop"; - interrupts: should contain a list of all VOP IP block interrupts in the order: VSYNC, LCD_SYSTEM. The interrupt specifier diff --git a/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt b/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt index c46ba641a1df..a9168ae6946c 100644 --- a/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt +++ b/Documentation/devicetree/bindings/display/simple-framebuffer-sunxi.txt @@ -28,6 +28,5 @@ chosen { allwinner,pipeline = "de_be0-lcd0-hdmi"; clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>, <&ahb_gates 44>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/display/sitronix,st7586.txt b/Documentation/devicetree/bindings/display/sitronix,st7586.txt new file mode 100644 index 000000000000..1d0dad1210d3 --- /dev/null +++ b/Documentation/devicetree/bindings/display/sitronix,st7586.txt @@ -0,0 +1,22 @@ +Sitronix ST7586 display panel + +Required properties: +- compatible: "lego,ev3-lcd". +- a0-gpios: The A0 signal (since this binding is for serial mode, this is + the pin labeled D1 on the controller, not the pin labeled A0) +- reset-gpios: Reset pin + +The node for this driver must be a child node of a SPI controller, hence +all mandatory properties described in ../spi/spi-bus.txt must be specified. + +Optional properties: +- rotation: panel rotation in degrees counter clockwise (0,90,180,270) + +Example: + display@0{ + compatible = "lego,ev3-lcd"; + reg = <0>; + spi-max-frequency = <10000000>; + a0-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt index 8e1476941c0f..74b5ac7b26d6 100644 --- a/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt +++ b/Documentation/devicetree/bindings/display/st,stm32-ltdc.txt @@ -1,7 +1,6 @@ * STMicroelectronics STM32 lcd-tft display controller - ltdc: lcd-tft display controller host - must be a sub-node of st-display-subsystem Required properties: - compatible: "st,stm32-ltdc" - reg: Physical base address of the IP registers and length of memory mapped region. @@ -13,8 +12,40 @@ Required nodes: - Video port for RGB output. -Example: +* STMicroelectronics STM32 DSI controller specific extensions to Synopsys + DesignWare MIPI DSI host controller +The STMicroelectronics STM32 DSI controller uses the Synopsys DesignWare MIPI +DSI host controller. For all mandatory properties & nodes, please refer +to the related documentation in [5]. + +Mandatory properties specific to STM32 DSI: +- #address-cells: Should be <1>. +- #size-cells: Should be <0>. +- compatible: "st,stm32-dsi". +- clock-names: + - phy pll reference clock string name, must be "ref". +- resets: see [5]. +- reset-names: see [5]. + +Mandatory nodes specific to STM32 DSI: +- ports: A node containing DSI input & output port nodes with endpoint + definitions as documented in [3] & [4]. + - port@0: DSI input port node, connected to the ltdc rgb output port. + - port@1: DSI output port node, connected to a panel or a bridge input port. +- panel or bridge node: A node containing the panel or bridge description as + documented in [6]. + - port: panel or bridge port node, connected to the DSI output port (port@1). + +Note: You can find more documentation in the following references +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/reset/reset.txt +[3] Documentation/devicetree/bindings/media/video-interfaces.txt +[4] Documentation/devicetree/bindings/graph.txt +[5] Documentation/devicetree/bindings/display/bridge/dw_mipi_dsi.txt +[6] Documentation/devicetree/bindings/display/mipi-dsi-bus.txt + +Example 1: RGB panel / { ... soc { @@ -34,3 +65,73 @@ Example: }; }; }; + +Example 2: DSI panel + +/ { + ... + soc { + ... + ltdc: display-controller@40016800 { + compatible = "st,stm32-ltdc"; + reg = <0x40016800 0x200>; + interrupts = <88>, <89>; + resets = <&rcc STM32F4_APB2_RESET(LTDC)>; + clocks = <&rcc 1 CLK_LCD>; + clock-names = "lcd"; + + port { + ltdc_out_dsi: endpoint { + remote-endpoint = <&dsi_in>; + }; + }; + }; + + + dsi: dsi@40016c00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "st,stm32-dsi"; + reg = <0x40016c00 0x800>; + clocks = <&rcc 1 CLK_F469_DSI>, <&clk_hse>; + clock-names = "ref", "pclk"; + resets = <&rcc STM32F4_APB2_RESET(DSI)>; + reset-names = "apb"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi_in: endpoint { + remote-endpoint = <<dc_out_dsi>; + }; + }; + + port@1 { + reg = <1>; + dsi_out: endpoint { + remote-endpoint = <&dsi_in_panel>; + }; + }; + + }; + + panel-dsi@0 { + reg = <0>; /* dsi virtual channel (0..3) */ + compatible = ...; + enable-gpios = ...; + + port { + dsi_in_panel: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + + }; + + }; + + }; +}; diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt index b83e6018041d..92441086caba 100644 --- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt @@ -4,15 +4,33 @@ Allwinner A10 Display Pipeline The Allwinner A10 Display pipeline is composed of several components that are going to be documented below: -For the input port of all components up to the TCON in the display -pipeline, if there are multiple components, the local endpoint IDs -must correspond to the index of the upstream block. For example, if -the remote endpoint is Frontend 1, then the local endpoint ID must -be 1. +For all connections between components up to the TCONs in the display +pipeline, when there are multiple components of the same type at the +same depth, the local endpoint ID must be the same as the remote +component's index. For example, if the remote endpoint is Frontend 1, +then the local endpoint ID must be 1. -Conversely, for the output ports of the same group, the remote endpoint -ID must be the index of the local hardware block. If the local backend -is backend 1, then the remote endpoint ID must be 1. + Frontend 0 [0] ------- [0] Backend 0 [0] ------- [0] TCON 0 + [1] -- -- [1] [1] -- -- [1] + \ / \ / + X X + / \ / \ + [0] -- -- [0] [0] -- -- [0] + Frontend 1 [1] ------- [1] Backend 1 [1] ------- [1] TCON 1 + +For a two pipeline system such as the one depicted above, the lines +represent the connections between the components, while the numbers +within the square brackets corresponds to the ID of the local endpoint. + +The same rule also applies to DE 2.0 mixer-TCON connections: + + Mixer 0 [0] ----------- [0] TCON 0 + [1] ---- ---- [1] + \ / + X + / \ + [0] ---- ---- [0] + Mixer 1 [1] ----------- [1] TCON 1 HDMI Encoder ------------ @@ -260,7 +278,6 @@ hdmi: hdmi@01c16000 { <&dma SUN4I_DMA_NORMAL 16>, <&dma SUN4I_DMA_DEDICATED 24>; dma-names = "ddc-tx", "ddc-rx", "audio-tx"; - status = "disabled"; ports { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/dma/fsl-edma.txt b/Documentation/devicetree/bindings/dma/fsl-edma.txt index 191d7bd8a6fe..97e213e07660 100644 --- a/Documentation/devicetree/bindings/dma/fsl-edma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-edma.txt @@ -72,5 +72,4 @@ sai2: sai@40031000 { dma-names = "tx", "rx"; dmas = <&edma0 0 21>, <&edma0 0 20>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/dma/mv-xor.txt b/Documentation/devicetree/bindings/dma/mv-xor.txt index c075f5988135..0ffb4d8766a8 100644 --- a/Documentation/devicetree/bindings/dma/mv-xor.txt +++ b/Documentation/devicetree/bindings/dma/mv-xor.txt @@ -30,7 +30,6 @@ xor@d0060900 { reg = <0xd0060900 0x100 0xd0060b00 0x100>; clocks = <&coreclk 0>; - status = "okay"; xor00 { interrupts = <51>; diff --git a/Documentation/devicetree/bindings/dma/qcom_adm.txt b/Documentation/devicetree/bindings/dma/qcom_adm.txt index 9bcab9115982..9d3b2f917b7b 100644 --- a/Documentation/devicetree/bindings/dma/qcom_adm.txt +++ b/Documentation/devicetree/bindings/dma/qcom_adm.txt @@ -48,7 +48,6 @@ Each dmas request consists of 3 cells: Example: spi4: spi@1a280000 { - status = "ok"; spi-max-frequency = <50000000>; pinctrl-0 = <&spi_pins>; diff --git a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt index 79a204d50234..891db41e9420 100644 --- a/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt +++ b/Documentation/devicetree/bindings/dma/renesas,rcar-dmac.txt @@ -25,6 +25,7 @@ Required Properties: - "renesas,dmac-r8a7794" (R-Car E2) - "renesas,dmac-r8a7795" (R-Car H3) - "renesas,dmac-r8a7796" (R-Car M3-W) + - "renesas,dmac-r8a77970" (R-Car V3M) - reg: base address and length of the registers block for the DMAC diff --git a/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt b/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt index e7780a186a36..1be6941ac1e5 100644 --- a/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt +++ b/Documentation/devicetree/bindings/dma/renesas,usb-dmac.txt @@ -8,6 +8,7 @@ Required Properties: - "renesas,r8a7793-usb-dmac" (R-Car M2-N) - "renesas,r8a7794-usb-dmac" (R-Car E2) - "renesas,r8a7795-usb-dmac" (R-Car H3) + - "renesas,r8a7796-usb-dmac" (R-Car M3-W) - reg: base address and length of the registers block for the DMAC - interrupts: interrupt specifiers for the DMAC, one for each entry in interrupt-names. diff --git a/Documentation/devicetree/bindings/dma/snps-dma.txt b/Documentation/devicetree/bindings/dma/snps-dma.txt index 4775c66f4508..a122723907ac 100644 --- a/Documentation/devicetree/bindings/dma/snps-dma.txt +++ b/Documentation/devicetree/bindings/dma/snps-dma.txt @@ -63,7 +63,6 @@ Example: compatible = "arm,pl011", "arm,primecell"; reg = <0xe0000000 0x1000>; interrupts = <0 35 0x4>; - status = "disabled"; dmas = <&dmahost 12 0 1>, <&dmahost 13 0 1 0>; dma-names = "rx", "rx"; diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt index 495d853c569b..52cfec9e77ad 100644 --- a/Documentation/devicetree/bindings/dma/st_fdma.txt +++ b/Documentation/devicetree/bindings/dma/st_fdma.txt @@ -69,7 +69,6 @@ Example: sti_uni_player2: sti-uni-player@2 { compatible = "st,sti-uni-player"; - status = "disabled"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_PCM_2>; diff --git a/Documentation/devicetree/bindings/dma/ste-dma40.txt b/Documentation/devicetree/bindings/dma/ste-dma40.txt index 95800ab37bb0..aa7dbd565ad0 100644 --- a/Documentation/devicetree/bindings/dma/ste-dma40.txt +++ b/Documentation/devicetree/bindings/dma/ste-dma40.txt @@ -135,5 +135,4 @@ Example: <&dma 13 0 0x0>; /* Logical - MemToDev */ dma-names = "rx", "rx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/dma/sun4i-dma.txt b/Documentation/devicetree/bindings/dma/sun4i-dma.txt index f1634a27a830..3b484380c56a 100644 --- a/Documentation/devicetree/bindings/dma/sun4i-dma.txt +++ b/Documentation/devicetree/bindings/dma/sun4i-dma.txt @@ -40,7 +40,6 @@ Example: clock-names = "ahb", "mod"; dmas = <&dma 1 29>, <&dma 1 28>; dma-names = "rx", "tx"; - status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/dma/sun6i-dma.txt b/Documentation/devicetree/bindings/dma/sun6i-dma.txt index 6b267045f522..98fbe1a5c6dd 100644 --- a/Documentation/devicetree/bindings/dma/sun6i-dma.txt +++ b/Documentation/devicetree/bindings/dma/sun6i-dma.txt @@ -9,6 +9,7 @@ Required properties: "allwinner,sun8i-a23-dma" "allwinner,sun8i-a83t-dma" "allwinner,sun8i-h3-dma" + "allwinner,sun8i-v3s-dma" - reg: Should contain the registers base address and length - interrupts: Should contain a reference to the interrupt used by this device - clocks: Should contain a reference to the parent AHB clock diff --git a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt index aead5869a28d..b849a1ed389d 100644 --- a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt +++ b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt @@ -62,7 +62,6 @@ uart1: serial@4806a000 { interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; ti,hwmods = "uart1"; clock-frequency = <48000000>; - status = "disabled"; /* Requesting crossbar input 49 and 50 */ dmas = <&sdma_xbar 49>, <&sdma_xbar 50>; dma-names = "tx", "rx"; diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt index 18090e7226b4..41f0c1a07c56 100644 --- a/Documentation/devicetree/bindings/dma/ti-edma.txt +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -9,7 +9,12 @@ execute the actual DMA tansfer. eDMA3 Channel Controller Required properties: -- compatible: "ti,edma3-tpcc" for the channel controller(s) +-------------------- +- compatible: Should be: + - "ti,edma3-tpcc" for the channel controller(s) on OMAP, + AM33xx and AM43xx SoCs. + - "ti,k2g-edma3-tpcc", "ti,edma3-tpcc" for the + channel controller(s) on 66AK2G. - #dma-cells: Should be set to <2>. The first number is the DMA request number and the second is the TC the channel is serviced on. - reg: Memory map of eDMA CC @@ -19,8 +24,19 @@ Required properties: - ti,tptcs: List of TPTCs associated with the eDMA in the following form: <&tptc_phandle TC_priority_number>. The highest priority is 0. +SoC-specific Required properties: +-------------------------------- +The following are mandatory properties for OMAP, AM33xx and AM43xx SoCs only: +- ti,hwmods: Name of the hwmods associated to the eDMA CC. + +The following are mandatory properties for 66AK2G SoCs only: +- power-domains:Should contain a phandle to a PM domain provider node + and an args specifier containing the device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt + Optional properties: -- ti,hwmods: Name of the hwmods associated to the eDMA CC +------------------- - ti,edma-memcpy-channels: List of channels allocated to be used for memcpy, iow these channels will be SW triggered channels. See example. - ti,edma-reserved-slot-ranges: PaRAM slot ranges which should not be used by @@ -31,17 +47,34 @@ Optional properties: eDMA3 Transfer Controller Required properties: -- compatible: "ti,edma3-tptc" for the transfer controller(s) +-------------------- +- compatible: Should be: + - "ti,edma3-tptc" for the transfer controller(s) on OMAP, + AM33xx and AM43xx SoCs. + - "ti,k2g-edma3-tptc", "ti,edma3-tptc" for the + transfer controller(s) on 66AK2G. - reg: Memory map of eDMA TC - interrupts: Interrupt number for TCerrint. +SoC-specific Required properties: +-------------------------------- +The following are mandatory properties for OMAP, AM33xx and AM43xx SoCs only: +- ti,hwmods: Name of the hwmods associated to the eDMA TC. + +The following are mandatory properties for 66AK2G SoCs only: +- power-domains:Should contain a phandle to a PM domain provider node + and an args specifier containing the device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt + Optional properties: -- ti,hwmods: Name of the hwmods associated to the given eDMA TC +------------------- - interrupt-names: "edma3_tcerrint" ------------------------------------------------------------------------------ -Example: +Examples: +1. edma: edma@49000000 { compatible = "ti,edma3-tpcc"; ti,hwmods = "tpcc"; @@ -102,13 +135,64 @@ mcasp0: mcasp@48038000 { reg-names = "mpu", "dat"; interrupts = <80>, <81>; interrupt-names = "tx", "rx"; - status = "disabled"; /* DMA channels 8 and 9 executed on eDMA TC2 - high priority queue */ dmas = <&edma 8 2>, <&edma 9 2>; dma-names = "tx", "rx"; }; +2. +edma1: edma@02728000 { + compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc"; + reg = <0x02728000 0x8000>; + reg-names = "edma3_cc"; + interrupts = , + , + ; + interrupt-names = "edma3_ccint", "emda3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma1_tptc0 7>, <&edma1_tptc1 0>; + + /* + * memcpy is disabled, can be enabled with: + * ti,edma-memcpy-channels = <12 13 14 15>; + * for example. + */ + + power-domains = <&k2g_pds 0x4f>; +}; + +edma1_tptc0: tptc@027b0000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b0000 0x400>; + power-domains = <&k2g_pds 0x4f>; +}; + +edma1_tptc1: tptc@027b8000 { + compatible = "ti, k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b8000 0x400>; + power-domains = <&k2g_pds 0x4f>; +}; + +mmc0: mmc@23000000 { + compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc"; + reg = <0x23000000 0x400>; + interrupts = ; + dmas = <&edma1 24 0>, <&edma1 25 0>; + dma-names = "tx", "rx"; + bus-width = <4>; + ti,needs-special-reset; + no-1-8-v; + max-frequency = <96000000>; + power-domains = <&k2g_pds 0xb>; + clocks = <&k2g_clks 0xb 1>, <&k2g_clks 0xb 2>; + clock-names = "fck", "mmchsdb_fck"; + status = "disabled"; +}; + ------------------------------------------------------------------------------ DEPRECATED binding, new DTS files must use the ti,edma3-tpcc/ti,edma3-tptc binding. diff --git a/Documentation/devicetree/bindings/eeprom/eeprom.txt b/Documentation/devicetree/bindings/eeprom/eeprom.txt index 5696eb508e95..afc04589eadf 100644 --- a/Documentation/devicetree/bindings/eeprom/eeprom.txt +++ b/Documentation/devicetree/bindings/eeprom/eeprom.txt @@ -16,8 +16,12 @@ Required properties: "renesas,r1ex24002" + The following manufacturers values have been deprecated: + "at", "at24" + If there is no specific driver for , a generic - driver based on is selected. Possible types are: + device with and manufacturer "atmel" should be used. + Possible types are: "24c00", "24c01", "24c02", "24c04", "24c08", "24c16", "24c32", "24c64", "24c128", "24c256", "24c512", "24c1024", "spd" diff --git a/Documentation/devicetree/bindings/extcon/extcon-usbc-cros-ec.txt b/Documentation/devicetree/bindings/extcon/extcon-usbc-cros-ec.txt new file mode 100644 index 000000000000..8e8625c00dfa --- /dev/null +++ b/Documentation/devicetree/bindings/extcon/extcon-usbc-cros-ec.txt @@ -0,0 +1,24 @@ +ChromeOS EC USB Type-C cable and accessories detection + +On ChromeOS systems with USB Type C ports, the ChromeOS Embedded Controller is +able to detect the state of external accessories such as display adapters +or USB devices when said accessories are attached or detached. + +The node for this device must be under a cros-ec node like google,cros-ec-spi +or google,cros-ec-i2c. + +Required properties: +- compatible: Should be "google,extcon-usbc-cros-ec". +- google,usb-port-id: Specifies the USB port ID to use. + +Example: + cros-ec@0 { + compatible = "google,cros-ec-i2c"; + + ... + + extcon { + compatible = "google,extcon-usbc-cros-ec"; + google,usb-port-id = <0>; + }; + } diff --git a/Documentation/devicetree/bindings/fpga/altera-passive-serial.txt b/Documentation/devicetree/bindings/fpga/altera-passive-serial.txt new file mode 100644 index 000000000000..48478bc07e29 --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/altera-passive-serial.txt @@ -0,0 +1,29 @@ +Altera Passive Serial SPI FPGA Manager + +Altera FPGAs support a method of loading the bitstream over what is +referred to as "passive serial". +The passive serial link is not technically SPI, and might require extra +circuits in order to play nicely with other SPI slaves on the same bus. + +See https://www.altera.com/literature/hb/cyc/cyc_c51013.pdf + +Required properties: +- compatible: Must be one of the following: + "altr,fpga-passive-serial", + "altr,fpga-arria10-passive-serial" +- reg: SPI chip select of the FPGA +- nconfig-gpios: config pin (referred to as nCONFIG in the manual) +- nstat-gpios: status pin (referred to as nSTATUS in the manual) + +Optional properties: +- confd-gpios: confd pin (referred to as CONF_DONE in the manual) + +Example: + fpga: fpga@0 { + compatible = "altr,fpga-passive-serial"; + spi-max-frequency = <20000000>; + reg = <0>; + nconfig-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; + nstat-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; + confd-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; + }; diff --git a/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt new file mode 100644 index 000000000000..8dcfba926bc7 --- /dev/null +++ b/Documentation/devicetree/bindings/fpga/xilinx-pr-decoupler.txt @@ -0,0 +1,36 @@ +Xilinx LogiCORE Partial Reconfig Decoupler Softcore + +The Xilinx LogiCORE Partial Reconfig Decoupler manages one or more +decouplers / fpga bridges. +The controller can decouple/disable the bridges which prevents signal +changes from passing through the bridge. The controller can also +couple / enable the bridges which allows traffic to pass through the +bridge normally. + +The Driver supports only MMIO handling. A PR region can have multiple +PR Decouplers which can be handled independently or chained via decouple/ +decouple_status signals. + +Required properties: +- compatible : Should contain "xlnx,pr-decoupler-1.00" followed by + "xlnx,pr-decoupler" +- regs : base address and size for decoupler module +- clocks : input clock to IP +- clock-names : should contain "aclk" + +Optional properties: +- bridge-enable : 0 if driver should disable bridge at startup + 1 if driver should enable bridge at startup + Default is to leave bridge in current state. + +See Documentation/devicetree/bindings/fpga/fpga-region.txt for generic bindings. + +Example: + fpga-bridge@100000450 { + compatible = "xlnx,pr-decoupler-1.00", + "xlnx-pr-decoupler"; + regs = <0x10000045 0x10>; + clocks = <&clkc 15>; + clock-names = "aclk"; + bridge-enable = <0>; + }; diff --git a/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt b/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt index 9766f7472f51..cfa4ed42b62f 100644 --- a/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt +++ b/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt @@ -31,7 +31,6 @@ Example for full FPGA configuration: cell-index = <1>; interrupts = <92>; clocks = <&coreclk 0>; - status = "okay"; fpga_mgr_spi: fpga-mgr@0 { compatible = "xlnx,fpga-slave-serial"; diff --git a/Documentation/devicetree/bindings/gpio/gpio-74x164.txt b/Documentation/devicetree/bindings/gpio/gpio-74x164.txt index ce1b2231bf5d..2a97553d8d76 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-74x164.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-74x164.txt @@ -12,6 +12,9 @@ Required properties: 1 = active low - registers-number: Number of daisy-chained shift registers +Optional properties: +- enable-gpios: GPIO connected to the OE (Output Enable) pin. + Example: gpio5: gpio5@0 { diff --git a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt index c756afa88cc6..fc6378c778c5 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-aspeed.txt @@ -18,7 +18,7 @@ Required properties: Optional properties: - interrupt-parent : The parent interrupt controller, optional if inherited -- clocks : A phandle to the HPLL clock node for debounce timings +- clocks : A phandle to the clock to use for debounce timings The gpio and interrupt properties are further described in their respective bindings documentation: diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt index 5079ba7d6568..8beb0539b6d8 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt @@ -1,7 +1,10 @@ Davinci/Keystone GPIO controller bindings Required Properties: -- compatible: should be "ti,dm6441-gpio", "ti,keystone-gpio" +- compatible: should be "ti,dm6441-gpio": for Davinci da850 SoCs + "ti,keystone-gpio": for Keystone 2 66AK2H/K, 66AK2L, + 66AK2E SoCs + "ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G - reg: Physical base address of the controller and the size of memory mapped registers. @@ -20,7 +23,21 @@ Required Properties: - ti,ngpio: The number of GPIO pins supported. - ti,davinci-gpio-unbanked: The number of GPIOs that have an individual interrupt - line to processor. + line to processor. + +- clocks: Should contain the device's input clock, and should be defined as per + the appropriate clock bindings consumer usage in, + + Documentation/devicetree/bindings/clock/keystone-gate.txt + for 66AK2HK/66AK2L/66AK2E SoCs or, + + Documentation/devicetree/bindings/clock/ti,sci-clk.txt + for 66AK2G SoCs + +- clock-names: Name should be "gpio"; + +Currently clock-names and clocks are needed for all keystone 2 platforms +Davinci platforms do not have DT clocks as of now. The GPIO controller also acts as an interrupt controller. It uses the default two cells specifier as described in Documentation/devicetree/bindings/ @@ -60,3 +77,73 @@ leds { ... }; }; + +Example for 66AK2G: + +gpio0: gpio@2603000 { + compatible = "ti,k2g-gpio", "ti,keystone-gpio"; + reg = <0x02603000 0x100>; + gpio-controller; + #gpio-cells = <2>; + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + ti,ngpio = <144>; + ti,davinci-gpio-unbanked = <0>; + clocks = <&k2g_clks 0x001b 0x0>; + clock-names = "gpio"; +}; + +Example for 66AK2HK/66AK2L/66AK2E: + +gpio0: gpio@260bf00 { + compatible = "ti,keystone-gpio"; + reg = <0x0260bf00 0x100>; + gpio-controller; + #gpio-cells = <2>; + /* HW Interrupts mapped to GPIO pins */ + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + clocks = <&clkgpio>; + clock-names = "gpio"; + ti,ngpio = <32>; + ti,davinci-gpio-unbanked = <32>; +}; diff --git a/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt b/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt index 4b6cc632ca5c..69d46162d0f5 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt @@ -23,7 +23,6 @@ gpio0: gpio@1100 { #gpio-cells = <2>; reg = <0x1100 0x080>; interrupts = <78 0x8>; - status = "okay"; }; Example of gpio-controller node for a ls2080a SoC: diff --git a/Documentation/devicetree/bindings/gpio/gpio-vf610.txt b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt index 436cc99c6598..0ccbae44019c 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-vf610.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-vf610.txt @@ -5,7 +5,9 @@ functionality. Each pair serves 32 GPIOs. The VF610 has 5 instances of each, and each PORT module has its own interrupt. Required properties for GPIO node: -- compatible : Should be "fsl,-gpio", currently "fsl,vf610-gpio" +- compatible : Should be "fsl,-gpio", below is supported list: + "fsl,vf610-gpio" + "fsl,imx7ulp-gpio" - reg : The first reg tuple represents the PORT module, the second tuple the GPIO module. - interrupts : Should be the port interrupt shared by all 32 pins. diff --git a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt index 6826a371fb69..51c86f69995e 100644 --- a/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt +++ b/Documentation/devicetree/bindings/gpio/renesas,gpio-rcar.txt @@ -2,8 +2,9 @@ Required Properties: - - compatible: should contain one of the following. + - compatible: should contain one or more of the following: - "renesas,gpio-r8a7743": for R8A7743 (RZ/G1M) compatible GPIO controller. + - "renesas,gpio-r8a7745": for R8A7745 (RZ/G1E) compatible GPIO controller. - "renesas,gpio-r8a7778": for R8A7778 (R-Mobile M1) compatible GPIO controller. - "renesas,gpio-r8a7779": for R8A7779 (R-Car H1) compatible GPIO controller. - "renesas,gpio-r8a7790": for R8A7790 (R-Car H2) compatible GPIO controller. @@ -13,7 +14,14 @@ Required Properties: - "renesas,gpio-r8a7794": for R8A7794 (R-Car E2) compatible GPIO controller. - "renesas,gpio-r8a7795": for R8A7795 (R-Car H3) compatible GPIO controller. - "renesas,gpio-r8a7796": for R8A7796 (R-Car M3-W) compatible GPIO controller. - - "renesas,gpio-rcar": for generic R-Car GPIO controller. + - "renesas,rcar-gen1-gpio": for a generic R-Car Gen1 GPIO controller. + - "renesas,rcar-gen2-gpio": for a generic R-Car Gen2 or RZ/G1 GPIO controller. + - "renesas,rcar-gen3-gpio": for a generic R-Car Gen3 GPIO controller. + - "renesas,gpio-rcar": deprecated. + + When compatible with the generic version nodes must list the + SoC-specific version corresponding to the platform first followed by + the generic version. - reg: Base address and length of each memory resource used by the GPIO controller hardware module. @@ -43,7 +51,7 @@ interrupt-controller/interrupts.txt. Example: R8A7779 (R-Car H1) GPIO controller nodes gpio0: gpio@ffc40000 { - compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; + compatible = "renesas,gpio-r8a7779", "renesas,rcar-gen1-gpio"; reg = <0xffc40000 0x2c>; interrupt-parent = <&gic>; interrupts = <0 141 0x4>; @@ -55,7 +63,7 @@ Example: R8A7779 (R-Car H1) GPIO controller nodes }; ... gpio6: gpio@ffc46000 { - compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; + compatible = "renesas,gpio-r8a7779", "renesas,rcar-gen1-gpio"; reg = <0xffc46000 0x2c>; interrupt-parent = <&gic>; interrupts = <0 147 0x4>; diff --git a/Documentation/devicetree/bindings/gpio/spear_spics.txt b/Documentation/devicetree/bindings/gpio/spear_spics.txt index 96c37eb15075..dd04d96e6ff1 100644 --- a/Documentation/devicetree/bindings/gpio/spear_spics.txt +++ b/Documentation/devicetree/bindings/gpio/spear_spics.txt @@ -42,7 +42,6 @@ spics: spics@e0700000{ spi0: spi@e0100000 { - status = "okay"; num-cs = <3>; cs-gpios = <&gpio1 7 0>, <&spics 0>, <&spics 1>; diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt index 5aa5926029ee..039219df05c5 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt @@ -17,6 +17,7 @@ Required properties: * which must be preceded by one of the following vendor specifics: + "amlogic,meson-gxm-mali" + "rockchip,rk3288-mali" + + "rockchip,rk3399-mali" - reg : Physical base address of the device and length of the register area. diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt index 2b6243e730f6..b4ebd56d03f3 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt +++ b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt @@ -10,6 +10,7 @@ Required properties: * And, optionally, one of the vendor specific compatible: + allwinner,sun4i-a10-mali + allwinner,sun7i-a20-mali + + allwinner,sun50i-h5-mali + amlogic,meson-gxbb-mali + amlogic,meson-gxl-mali + stericsson,db8500-mali @@ -58,6 +59,10 @@ to specify one more vendor-specific compatible, among: Required properties: * resets: phandle to the reset line for the GPU + - allwinner,sun50i-h5-mali + Required properties: + * resets: phandle to the reset line for the GPU + - stericsson,db8500-mali Required properties: * interrupt-names and interrupts: diff --git a/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt b/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt index b7e4c7444510..f32bbba4d3bc 100644 --- a/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt +++ b/Documentation/devicetree/bindings/gpu/nvidia,gk20a.txt @@ -51,7 +51,6 @@ Example for GK20A: resets = <&tegra_car 184>; reset-names = "gpu"; iommus = <&mc TEGRA_SWGROUP_GPU>; - status = "disabled"; }; Example for GM20B: @@ -70,7 +69,6 @@ Example for GM20B: resets = <&tegra_car 184>; reset-names = "gpu"; iommus = <&mc TEGRA_SWGROUP_GPU>; - status = "disabled"; }; Example for GP10B: @@ -89,5 +87,4 @@ Example for GP10B: reset-names = "gpu"; power-domains = <&bpmp TEGRA186_POWER_DOMAIN_GPU>; iommus = <&smmu TEGRA186_SID_GPU>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/gpu/samsung-g2d.txt b/Documentation/devicetree/bindings/gpu/samsung-g2d.txt index c4f358dafdaa..1e7959332dbc 100644 --- a/Documentation/devicetree/bindings/gpu/samsung-g2d.txt +++ b/Documentation/devicetree/bindings/gpu/samsung-g2d.txt @@ -24,5 +24,4 @@ Example: interrupts = <0 89 0>; clocks = <&clock 177>, <&clock 277>; clock-names = "sclk_fimg2d", "fimg2d"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/hsi/omap-ssi.txt b/Documentation/devicetree/bindings/hsi/omap-ssi.txt index f26625e42693..b8eca3c7810d 100644 --- a/Documentation/devicetree/bindings/hsi/omap-ssi.txt +++ b/Documentation/devicetree/bindings/hsi/omap-ssi.txt @@ -92,6 +92,5 @@ ssi-controller@48058000 { interrupts = <69>, <70>; - status = "disabled"; /* second port is not used on N900 */ } } diff --git a/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt index cf4460564adb..367c8203213b 100644 --- a/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt +++ b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt @@ -11,6 +11,8 @@ Required properties for pwm-tacho node: - #size-cells : should be 1. +- #cooling-cells: should be 2. + - reg : address and length of the register set for the device. - pinctrl-names : a pinctrl state named "default" must be defined. @@ -28,12 +30,17 @@ fan subnode format: Under fan subnode there can upto 8 child nodes, with each child node representing a fan. If there are 8 fans each fan can have one PWM port and one/two Fan tach inputs. +For PWM port can be configured cooling-levels to create cooling device. +Cooling device could be bound to a thermal zone for the thermal control. Required properties for each child node: - reg : should specify PWM source port. integer value in the range 0 to 7 with 0 indicating PWM port A and 7 indicating PWM port H. +- cooling-levels: PWM duty cycle values in a range from 0 to 255 + which correspond to thermal cooling states. + - aspeed,fan-tach-ch : should specify the Fan tach input channel. integer value in the range 0 through 15, with 0 indicating Fan tach channel 0 and 15 indicating Fan tach channel 15. @@ -50,6 +57,7 @@ pwm_tacho_fixed_clk: fixedclk { pwm_tacho: pwmtachocontroller@1e786000 { #address-cells = <1>; #size-cells = <1>; + #cooling-cells = <2>; reg = <0x1E786000 0x1000>; compatible = "aspeed,ast2500-pwm-tacho"; clocks = <&pwm_tacho_fixed_clk>; @@ -58,6 +66,7 @@ pwm_tacho: pwmtachocontroller@1e786000 { fan@0 { reg = <0x00>; + cooling-levels = /bits/ 8 <125 151 177 203 229 255>; aspeed,fan-tach-ch = /bits/ 8 <0x00>; }; diff --git a/Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt b/Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt new file mode 100644 index 000000000000..f68a0a68fc52 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt @@ -0,0 +1,21 @@ +Device-tree bindings for IBM Common Form Factor Power Supply Version 1 +---------------------------------------------------------------------- + +Required properties: + - compatible = "ibm,cffps1"; + - reg = < I2C bus address >; : Address of the power supply on the + I2C bus. + +Example: + + i2c-bus@100 { + #address-cells = <1>; + #size-cells = <0>; + #interrupt-cells = <1>; + < more properties > + + power-supply@68 { + compatible = "ibm,cffps1"; + reg = <0x68>; + }; + }; diff --git a/Documentation/devicetree/bindings/hwmon/ltq-cputemp.txt b/Documentation/devicetree/bindings/hwmon/ltq-cputemp.txt new file mode 100644 index 000000000000..33fd00a987c7 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/ltq-cputemp.txt @@ -0,0 +1,10 @@ +Lantiq cpu temperatur sensor + +Requires node properties: +- compatible value : + "lantiq,cputemp" + +Example: + cputemp@0 { + compatible = "lantiq,cputemp"; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-altera.txt b/Documentation/devicetree/bindings/i2c/i2c-altera.txt new file mode 100644 index 000000000000..767664f448ec --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-altera.txt @@ -0,0 +1,39 @@ +* Altera I2C Controller +* This is Altera's synthesizable logic block I2C Controller for use +* in Altera's FPGAs. + +Required properties : + - compatible : should be "altr,softip-i2c-v1.0" + - reg : Offset and length of the register set for the device + - interrupts : where IRQ is the interrupt number. + - clocks : phandle to input clock. + - #address-cells = <1>; + - #size-cells = <0>; + +Recommended properties : + - clock-frequency : desired I2C bus clock frequency in Hz. + +Optional properties : + - fifo-size : Size of the RX and TX FIFOs in bytes. + - Child nodes conforming to i2c bus binding + +Example : + + i2c@100080000 { + compatible = "altr,softip-i2c-v1.0"; + reg = <0x00000001 0x00080000 0x00000040>; + interrupt-parent = <&intc>; + interrupts = <0 43 4>; + clocks = <&clk_0>; + clock-frequency = <100000>; + #address-cells = <1>; + #size-cells = <0>; + fifo-size = <4>; + + eeprom@51 { + compatible = "atmel,24c32"; + reg = <0x51>; + pagesize = <32>; + }; + }; + diff --git a/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt index 8ce9cd2855b5..c143948b2a37 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt @@ -20,8 +20,8 @@ i2c@0 { #address-cells = <1>; #size-cells = <0>; - retu-mfd: retu@1 { - compatible = "retu-mfd"; + retu: retu@1 { + compatible = "nokia,retu"; reg = <0x1>; }; }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt index 7ce23ac61308..81b5d55086fa 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt @@ -102,7 +102,6 @@ And for clarification, here are the snipplets for the i2c-parents: #address-cells = <1>; #size-cells = <0>; compatible = "i2c-gpio"; - status = "disabled"; gpios = <&gpio5 6 GPIO_ACTIVE_HIGH /* sda */ &gpio5 5 GPIO_ACTIVE_HIGH /* scl */ >; diff --git a/Documentation/devicetree/bindings/i2c/i2c-efm32.txt b/Documentation/devicetree/bindings/i2c/i2c-efm32.txt index 50b25c3da186..3b30e54ae3c7 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-efm32.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-efm32.txt @@ -22,7 +22,6 @@ Example: interrupts = <9>; clocks = <&cmu clk_HFPERCLKI2C0>; clock-frequency = <100000>; - status = "ok"; energymicro,location = <3>; eeprom@50 { diff --git a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt index bd5a7befd951..ff7bf37deb43 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mtk.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-mtk.txt @@ -1,14 +1,15 @@ -* Mediatek's I2C controller +* MediaTek's I2C controller -The Mediatek's I2C controller is used to interface with I2C devices. +The MediaTek's I2C controller is used to interface with I2C devices. Required properties: - compatible: value should be either of the following. - "mediatek,mt2701-i2c", "mediatek,mt6577-i2c": for Mediatek mt2701 - "mediatek,mt6577-i2c": for i2c compatible with mt6577. - "mediatek,mt6589-i2c": for i2c compatible with mt6589. - "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for i2c compatible with mt7623. - "mediatek,mt8173-i2c": for i2c compatible with mt8173. + "mediatek,mt2701-i2c", "mediatek,mt6577-i2c": for MediaTek MT2701 + "mediatek,mt6577-i2c": for MediaTek MT6577 + "mediatek,mt6589-i2c": for MediaTek MT6589 + "mediatek,mt7622-i2c": for MediaTek MT7622 + "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for MediaTek MT7623 + "mediatek,mt8173-i2c": for MediaTek MT8173 - reg: physical base address of the controller and dma base, length of memory mapped region. - interrupts: interrupt number to the cpu. diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index 2b8bd33dbf8d..cad39aee9f73 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -2,6 +2,8 @@ I2C for R-Car platforms Required properties: - compatible: + "renesas,i2c-r8a7743" if the device is a part of a R8A7743 SoC. + "renesas,i2c-r8a7745" if the device is a part of a R8A7745 SoC. "renesas,i2c-r8a7778" if the device is a part of a R8A7778 SoC. "renesas,i2c-r8a7779" if the device is a part of a R8A7779 SoC. "renesas,i2c-r8a7790" if the device is a part of a R8A7790 SoC. @@ -12,7 +14,8 @@ Required properties: "renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC. "renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC. "renesas,rcar-gen1-i2c" for a generic R-Car Gen1 compatible device. - "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 compatible device. + "renesas,rcar-gen2-i2c" for a generic R-Car Gen2 or RZ/G1 compatible + device. "renesas,rcar-gen3-i2c" for a generic R-Car Gen3 compatible device. "renesas,i2c-rcar" (deprecated) diff --git a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt index e18445d0980c..22f2eeb2c4c9 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rk3x.txt @@ -7,6 +7,7 @@ Required properties : - reg : Offset and length of the register set for the device - compatible: should be one of the following: + - "rockchip,rv1108-i2c": for rv1108 - "rockchip,rk3066-i2c": for rk3066 - "rockchip,rk3188-i2c": for rk3188 - "rockchip,rk3228-i2c": for rk3228 diff --git a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt index ae9c2a735f39..224390999e81 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-sh_mobile.txt @@ -4,6 +4,8 @@ Required properties: - compatible : - "renesas,iic-r8a73a4" (R-Mobile APE6) - "renesas,iic-r8a7740" (R-Mobile A1) + - "renesas,iic-r8a7743" (RZ/G1M) + - "renesas,iic-r8a7745" (RZ/G1E) - "renesas,iic-r8a7790" (R-Car H2) - "renesas,iic-r8a7791" (R-Car M2-W) - "renesas,iic-r8a7792" (R-Car V2H) @@ -12,7 +14,8 @@ Required properties: - "renesas,iic-r8a7795" (R-Car H3) - "renesas,iic-r8a7796" (R-Car M3-W) - "renesas,iic-sh73a0" (SH-Mobile AG5) - - "renesas,rcar-gen2-iic" (generic R-Car Gen2 compatible device) + - "renesas,rcar-gen2-iic" (generic R-Car Gen2 or RZ/G1 + compatible device) - "renesas,rcar-gen3-iic" (generic R-Car Gen3 compatible device) - "renesas,rmobile-iic" (generic device) diff --git a/Documentation/devicetree/bindings/i2c/i2c-sprd.txt b/Documentation/devicetree/bindings/i2c/i2c-sprd.txt new file mode 100644 index 000000000000..60b7cda15dd2 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-sprd.txt @@ -0,0 +1,31 @@ +I2C for Spreadtrum platforms + +Required properties: +- compatible: Should be "sprd,sc9860-i2c". +- reg: Specify the physical base address of the controller and length + of memory mapped region. +- interrupts: Should contain I2C interrupt. +- clock-names: Should contain following entries: + "i2c" for I2C clock, + "source" for I2C source (parent) clock, + "enable" for I2C module enable clock. +- clocks: Should contain a clock specifier for each entry in clock-names. +- clock-frequency: Constains desired I2C bus clock frequency in Hz. +- #address-cells: Should be 1 to describe address cells for I2C device address. +- #size-cells: Should be 0 means no size cell for I2C device address. + +Optional properties: +- Child nodes conforming to I2C bus binding + +Examples: +i2c0: i2c@70500000 { + compatible = "sprd,sc9860-i2c"; + reg = <0 0x70500000 0 0x1000>; + interrupts = ; + clock-names = "i2c", "source", "enable"; + clocks = <&clk_i2c3>, <&ext_26m>, <&clk_ap_apb_gates 11>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; +}; + diff --git a/Documentation/devicetree/bindings/i2c/i2c-stm32.txt b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt index 78eaf7b718ed..3b5489966634 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-stm32.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt @@ -1,7 +1,9 @@ * I2C controller embedded in STMicroelectronics STM32 I2C platform Required properties : -- compatible : Must be "st,stm32f4-i2c" +- compatible : Must be one of the following + - "st,stm32f4-i2c" + - "st,stm32f7-i2c" - reg : Offset and length of the register set for the device - interrupts : Must contain the interrupt id for I2C event and then the interrupt id for I2C error. @@ -14,8 +16,16 @@ Required properties : Optional properties : - clock-frequency : Desired I2C bus clock frequency in Hz. If not specified, - the default 100 kHz frequency will be used. As only Normal and Fast modes - are supported, possible values are 100000 and 400000. + the default 100 kHz frequency will be used. + For STM32F4 SoC Standard-mode and Fast-mode are supported, possible values are + 100000 and 400000. + For STM32F7 SoC, Standard-mode, Fast-mode and Fast-mode Plus are supported, + possible values are 100000, 400000 and 1000000. +- i2c-scl-rising-time-ns : Only for STM32F7, I2C SCL Rising time for the board + (default: 25) +- i2c-scl-falling-time-ns : Only for STM32F7, I2C SCL Falling time for the board + (default: 10) + I2C Timings are derived from these 2 values Example : @@ -31,3 +41,16 @@ Example : pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; pinctrl-names = "default"; }; + + i2c@40005400 { + compatible = "st,stm32f7-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40005400 0x400>; + interrupts = <31>, + <32>; + resets = <&rcc STM32F7_APB1_RESET(I2C1)>; + clocks = <&rcc 1 CLK_I2C1>; + pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>; + pinctrl-names = "default"; + }; diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt index 656716b72cc4..f64064f8bdc2 100644 --- a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt +++ b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt @@ -71,5 +71,4 @@ Example: reset-names = "i2c"; dmas = <&apbdma 16>, <&apbdma 16>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt index 3223684a643b..552e7a83951d 100644 --- a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt @@ -11,6 +11,11 @@ Required properties: - atmel,min-sample-rate-hz: Minimum sampling rate, it depends on SoC. - atmel,max-sample-rate-hz: Maximum sampling rate, it depends on SoC. - atmel,startup-time-ms: Startup time expressed in ms, it depends on SoC. + - atmel,trigger-edge-type: One of possible edge types for the ADTRG hardware + trigger pin. When the specific edge type is detected, the conversion will + start. Possible values are rising, falling, or both. + This property uses the IRQ edge types values: IRQ_TYPE_EDGE_RISING , + IRQ_TYPE_EDGE_FALLING or IRQ_TYPE_EDGE_BOTH Example: @@ -25,4 +30,5 @@ adc: adc@fc030000 { atmel,startup-time-ms = <4>; vddana-supply = <&vdd_3v3_lp_reg>; vref-supply = <&vdd_3v3_lp_reg>; + atmel,trigger-edge-type = ; } diff --git a/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt b/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt index caaaed765ce4..7b1b1e4086d4 100644 --- a/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/brcm,iproc-static-adc.txt @@ -37,5 +37,4 @@ For example: clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>; clock-names = "tsc_clk"; interrupts = ; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt b/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt index 0bcae5140bc5..9ada5abd45fa 100644 --- a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt @@ -17,5 +17,4 @@ adc0: adc@400e3000 { clocks = <&ccu1 CLK_APB3_ADC0>; vref-supply = <®_vdda>; resets = <&rgu 40>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt b/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt index 68c45cbbe3d9..64dc4843c180 100644 --- a/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt +++ b/Documentation/devicetree/bindings/iio/adc/mt6577_auxadc.txt @@ -12,6 +12,7 @@ for the Thermal Controller which holds a phandle to the AUXADC. Required properties: - compatible: Should be one of: - "mediatek,mt2701-auxadc": For MT2701 family of SoCs + - "mediatek,mt7622-auxadc": For MT7622 family of SoCs - "mediatek,mt8173-auxadc": For MT8173 family of SoCs - reg: Address range of the AUXADC unit. - clocks: Should contain a clock specifier for each entry in clock-names diff --git a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt index e0a9b9d6d6fd..c2c50b59873d 100644 --- a/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/rockchip-saradc.txt @@ -6,6 +6,7 @@ Required properties: - "rockchip,rk3066-tsadc": for rk3036 - "rockchip,rk3328-saradc", "rockchip,rk3399-saradc": for rk3328 - "rockchip,rk3399-saradc": for rk3399 + - "rockchip,rv1108-saradc", "rockchip,rk3399-saradc": for rv1108 - reg: physical base address of the controller and length of memory mapped region. diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt index 8310073f14e1..48bfcaa3ffcd 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt @@ -74,6 +74,11 @@ Optional properties: * can be 6, 8, 10 or 12 on stm32f4 * can be 8, 10, 12, 14 or 16 on stm32h7 Default is maximum resolution if unset. +- st,min-sample-time-nsecs: Minimum sampling time in nanoseconds. + Depending on hardware (board) e.g. high/low analog input source impedance, + fine tune of ADC sampling time may be recommended. + This can be either one value or an array that matches 'st,adc-channels' list, + to set sample time resp. for all channels, or independently for each channel. Example: adc: adc@40012000 { diff --git a/Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt b/Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt new file mode 100644 index 000000000000..a04aa5c04103 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/counter/stm32-lptimer-cnt.txt @@ -0,0 +1,27 @@ +STMicroelectronics STM32 Low-Power Timer quadrature encoder and counter + +STM32 Low-Power Timer provides several counter modes. It can be used as: +- quadrature encoder to detect angular position and direction of rotary + elements, from IN1 and IN2 input signals. +- simple counter from IN1 input signal. + +Must be a sub-node of an STM32 Low-Power Timer device tree node. +See ../mfd/stm32-lptimer.txt for details about the parent node. + +Required properties: +- compatible: Must be "st,stm32-lptimer-counter". +- pinctrl-names: Set to "default". +- pinctrl-0: List of phandles pointing to pin configuration nodes, + to set IN1/IN2 pins in mode of operation for Low-Power + Timer input on external pin. + +Example: + timer@40002400 { + compatible = "st,stm32-lptimer"; + ... + counter { + compatible = "st,stm32-lptimer-counter"; + pinctrl-names = "default"; + pinctrl-0 = <&lptim1_in_pins>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt b/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt index 7d6647d4af5e..42db783c4e75 100644 --- a/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt +++ b/Documentation/devicetree/bindings/iio/dac/lpc1850-dac.txt @@ -16,5 +16,4 @@ dac: dac@400e1000 { clocks = <&ccu1 CLK_APB3_DAC>; vref-supply = <®_vdda>; resets = <&rgu 42>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt b/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt index bcee71f808d0..bf2925c671c6 100644 --- a/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt +++ b/Documentation/devicetree/bindings/iio/dac/st,stm32-dac.txt @@ -10,7 +10,9 @@ current. Contents of a stm32 dac root node: ----------------------------------- Required properties: -- compatible: Must be "st,stm32h7-dac-core". +- compatible: Should be one of: + "st,stm32f4-dac-core" + "st,stm32h7-dac-core" - reg: Offset and length of the device's register set. - clocks: Must contain an entry for pclk (which feeds the peripheral bus interface) diff --git a/Documentation/devicetree/bindings/iio/humidity/hdc100x.txt b/Documentation/devicetree/bindings/iio/humidity/hdc100x.txt new file mode 100644 index 000000000000..c52333bdfd19 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/humidity/hdc100x.txt @@ -0,0 +1,17 @@ +* HDC100x temperature + humidity sensors + +Required properties: + - compatible: Should contain one of the following: + ti,hdc1000 + ti,hdc1008 + ti,hdc1010 + ti,hdc1050 + ti,hdc1080 + - reg: i2c address of the sensor + +Example: + +hdc100x@40 { + compatible = "ti,hdc1000"; + reg = <0x40>; +}; diff --git a/Documentation/devicetree/bindings/iio/humidity/hts221.txt b/Documentation/devicetree/bindings/iio/humidity/hts221.txt index b20ab9c12080..10adeb0d703d 100644 --- a/Documentation/devicetree/bindings/iio/humidity/hts221.txt +++ b/Documentation/devicetree/bindings/iio/humidity/hts221.txt @@ -5,9 +5,18 @@ Required properties: - reg: i2c address of the sensor / spi cs line Optional properties: +- drive-open-drain: the interrupt/data ready line will be configured + as open drain, which is useful if several sensors share the same + interrupt line. This is a boolean property. + If the requested interrupt is configured as IRQ_TYPE_LEVEL_HIGH or + IRQ_TYPE_EDGE_RISING a pull-down resistor is needed to drive the line + when it is not active, whereas a pull-up one is needed when interrupt + line is configured as IRQ_TYPE_LEVEL_LOW or IRQ_TYPE_EDGE_FALLING. + Refer to pinctrl/pinctrl-bindings.txt for the property description. - interrupt-parent: should be the phandle for the interrupt controller - interrupts: interrupt mapping for IRQ. It should be configured with - flags IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING. + flags IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_RISING, IRQ_TYPE_LEVEL_LOW or + IRQ_TYPE_EDGE_FALLING. Refer to interrupt-controller/interrupts.txt for generic interrupt client node bindings. diff --git a/Documentation/devicetree/bindings/iio/humidity/htu21.txt b/Documentation/devicetree/bindings/iio/humidity/htu21.txt new file mode 100644 index 000000000000..97d79636f7ae --- /dev/null +++ b/Documentation/devicetree/bindings/iio/humidity/htu21.txt @@ -0,0 +1,13 @@ +*HTU21 - Measurement-Specialties htu21 temperature & humidity sensor and humidity part of MS8607 sensor + +Required properties: + + - compatible: should be "meas,htu21" or "meas,ms8607-humidity" + - reg: I2C address of the sensor + +Example: + +htu21@40 { + compatible = "meas,htu21"; + reg = <0x40>; +}; diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt index 6f28ff55f3ec..1ff1af799c76 100644 --- a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt @@ -11,6 +11,14 @@ Required properties: Optional properties: - st,drdy-int-pin: the pin on the package that will be used to signal "data ready" (valid values: 1 or 2). +- drive-open-drain: the interrupt/data ready line will be configured + as open drain, which is useful if several sensors share the same + interrupt line. This is a boolean property. + (This binding is taken from pinctrl/pinctrl-bindings.txt) + If the requested interrupt is configured as IRQ_TYPE_LEVEL_HIGH or + IRQ_TYPE_EDGE_RISING a pull-down resistor is needed to drive the line + when it is not active, whereas a pull-up one is needed when interrupt + line is configured as IRQ_TYPE_LEVEL_LOW or IRQ_TYPE_EDGE_FALLING. - interrupt-parent: should be the phandle for the interrupt controller - interrupts: interrupt mapping for IRQ. It should be configured with flags IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_RISING, IRQ_TYPE_LEVEL_LOW or diff --git a/Documentation/devicetree/bindings/iio/pressure/ms5637.txt b/Documentation/devicetree/bindings/iio/pressure/ms5637.txt new file mode 100644 index 000000000000..1f43ffa068ac --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/ms5637.txt @@ -0,0 +1,17 @@ +* MS5637 - Measurement-Specialties MS5637, MS5805, MS5837 and MS8607 pressure & temperature sensor + +Required properties: + + -compatible: should be one of the following + meas,ms5637 + meas,ms5805 + meas,ms5837 + meas,ms8607-temppressure + -reg: I2C address of the sensor + +Example: + +ms5637@76 { + compatible = "meas,ms5637"; + reg = <0x76>; +}; diff --git a/Documentation/devicetree/bindings/iio/proximity/as3935.txt b/Documentation/devicetree/bindings/iio/proximity/as3935.txt index 38d74314b7ab..b6c1afa6f02d 100644 --- a/Documentation/devicetree/bindings/iio/proximity/as3935.txt +++ b/Documentation/devicetree/bindings/iio/proximity/as3935.txt @@ -16,6 +16,10 @@ Optional properties: - ams,tuning-capacitor-pf: Calibration tuning capacitor stepping value 0 - 120pF. This will require using the calibration data from the manufacturer. + - ams,nflwdth: Set the noise and watchdog threshold register on + startup. This will need to set according to the noise from the + MCU board, and possibly the local environment. Refer to the + datasheet for the threshold settings. Example: @@ -27,4 +31,5 @@ as3935@0 { interrupt-parent = <&gpio1>; interrupts = <16 1>; ams,tuning-capacitor-pf = <80>; + ams,nflwdth = <0x44>; }; diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index eaa8fbba34e2..9ec6f5ce54fc 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt @@ -45,6 +45,7 @@ Accelerometers: - st,lis2dh12-accel - st,h3lis331dl-accel - st,lng2dm-accel +- st,lis3l02dq Gyroscopes: - st,l3g4200d-gyro @@ -52,6 +53,7 @@ Gyroscopes: - st,lsm330dl-gyro - st,lsm330dlc-gyro - st,l3gd20-gyro +- st,l3gd20h-gyro - st,l3g4is-gyro - st,lsm330-gyro - st,lsm9ds0-gyro @@ -62,6 +64,7 @@ Magnetometers: - st,lsm303dlhc-magn - st,lsm303dlm-magn - st,lis3mdl-magn +- st,lis2mdl Pressure sensors: - st,lps001wp-press diff --git a/Documentation/devicetree/bindings/iio/temperature/tsys01.txt b/Documentation/devicetree/bindings/iio/temperature/tsys01.txt new file mode 100644 index 000000000000..0d5cc5595d0c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/temperature/tsys01.txt @@ -0,0 +1,19 @@ +* TSYS01 - Measurement Specialties temperature sensor + +Required properties: + + - compatible: should be "meas,tsys01" + - reg: I2C address of the sensor (changeable via CSB pin) + + ------------------------ + | CSB | Device Address | + ------------------------ + 1 0x76 + 0 0x77 + +Example: + +tsys01@76 { + compatible = "meas,tsys01"; + reg = <0x76>; +}; diff --git a/Documentation/devicetree/bindings/iio/timer/stm32-lptimer-trigger.txt b/Documentation/devicetree/bindings/iio/timer/stm32-lptimer-trigger.txt new file mode 100644 index 000000000000..85e6806b17d7 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/timer/stm32-lptimer-trigger.txt @@ -0,0 +1,23 @@ +STMicroelectronics STM32 Low-Power Timer Trigger + +STM32 Low-Power Timer provides trigger source (LPTIM output) that can be used +by STM32 internal ADC and/or DAC. + +Must be a sub-node of an STM32 Low-Power Timer device tree node. +See ../mfd/stm32-lptimer.txt for details about the parent node. + +Required properties: +- compatible: Must be "st,stm32-lptimer-trigger". +- reg: Identify trigger hardware block. Must be 0, 1 or 2 + respectively for lptimer1, lptimer2 or lptimer3 + trigger output. + +Example: + timer@40002400 { + compatible = "st,stm32-lptimer"; + ... + trigger@0 { + compatible = "st,stm32-lptimer-trigger"; + reg = <0>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt index 55a653d15303..b8e8c769d434 100644 --- a/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt +++ b/Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt @@ -4,7 +4,9 @@ Must be a sub-node of an STM32 Timers device tree node. See ../mfd/stm32-timers.txt for details about the parent node. Required parameters: -- compatible: Must be "st,stm32-timer-trigger". +- compatible: Must be one of: + "st,stm32-timer-trigger" + "st,stm32h7-timer-trigger" - reg: Identify trigger hardware block. Example: @@ -14,7 +16,7 @@ Example: compatible = "st,stm32-timers"; reg = <0x40010000 0x400>; clocks = <&rcc 0 160>; - clock-names = "clk_int"; + clock-names = "int"; timer@0 { compatible = "st,stm32-timer-trigger"; diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index 1852906517ab..23e3abc3fdef 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt @@ -22,6 +22,8 @@ Optional properties for main touchpad device: experiment to determine which bit corresponds to which input. Use KEY_RESERVED for unused padding values. +- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low) + Example: touch@4b { diff --git a/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt b/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt index b77f50bd6403..262deab73588 100644 --- a/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt +++ b/Documentation/devicetree/bindings/input/brcm,bcm-keypad.txt @@ -72,7 +72,6 @@ Example: /* Required Board specific properties */ keypad,num-rows = <5>; keypad,num-columns = <5>; - status = "okay"; linux,keymap = ; + }; + + vibrator_enable_pin: pinmux_vibrator_enable_pin { + pinctrl-single,pins = < + OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1) /* dmtimer9_pwm_evt (gpio_28) */ + >; + }; +}; + +/ { + pwm8: dmtimer-pwm { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_direction_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer8>; + ti,clock-source = <0x01>; + }; + + pwm9: dmtimer-pwm { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_enable_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer9>; + ti,clock-source = <0x01>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm8 0 1000000000 0>, + <&pwm9 0 1000000000 0>; + pwm-names = "enable", "direction"; + direction-duty-cycle-ns = <1000000000>; + }; +}; diff --git a/Documentation/devicetree/bindings/input/ti,drv260x.txt b/Documentation/devicetree/bindings/input/ti,drv260x.txt index ee09c8f4474a..4c5312eaaa85 100644 --- a/Documentation/devicetree/bindings/input/ti,drv260x.txt +++ b/Documentation/devicetree/bindings/input/ti,drv260x.txt @@ -43,7 +43,7 @@ haptics: haptics@5a { mode = ; library-sel = ; vib-rated-mv = <3200>; - vib-overdriver-mv = <3200>; + vib-overdrive-mv = <3200>; } For more product information please see the link below: diff --git a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt index 9d9e930f3251..df531b5b6a0d 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt @@ -32,5 +32,4 @@ Example: pinctrl-1 = <&pinctrl_touchctrl_default>; pinctrl-2 = <&pinctrl_touchctrl_gpios>; vf50-ts-min-pressure = <200>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt index d4927c202aef..e67e58b61706 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt @@ -35,5 +35,4 @@ Example: measure-delay-time = <0xfff>; pre-charge-time = <0xffff>; touchscreen-average-samples = <32>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt index 4c29cdab0ea5..5eb108e180fa 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt @@ -99,7 +99,7 @@ Examples: compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c200000 0 0x200000>; + reg = <0x0 0x2c200000 0 0x20000>; }; }; @@ -124,14 +124,14 @@ Examples: compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c200000 0 0x200000>; + reg = <0x0 0x2c200000 0 0x20000>; }; gic-its@2c400000 { compatible = "arm,gic-v3-its"; msi-controller; #msi-cells = <1>; - reg = <0x0 0x2c400000 0 0x200000>; + reg = <0x0 0x2c400000 0 0x20000>; }; ppi-partitions { diff --git a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt index 9e389493203f..49ccabbfa6f3 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt @@ -4,8 +4,10 @@ Required properties: - compatible: should be "fsl,-msi" to identify Layerscape PCIe MSI controller block such as: - "fsl,1s1021a-msi" - "fsl,1s1043a-msi" + "fsl,ls1021a-msi" + "fsl,ls1043a-msi" + "fsl,ls1046a-msi" + "fsl,ls1043a-v1.1-msi" - msi-controller: indicates that this is a PCIe MSI controller node - reg: physical base address of the controller and length of memory mapped. - interrupts: an interrupt to the parent interrupt controller. @@ -23,7 +25,7 @@ MSI controller node Examples: msi1: msi-controller@1571000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1571000 0x0 0x8>, msi-controller; interrupts = <0 116 0x4>; diff --git a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt index 11cc87aeb276..07bf0b9a5139 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt @@ -17,6 +17,7 @@ Required properties: "mediatek,mt6582-sysirq", "mediatek,mt6577-sysirq": for MT6582 "mediatek,mt6580-sysirq", "mediatek,mt6577-sysirq": for MT6580 "mediatek,mt6577-sysirq": for MT6577 + "mediatek,mt2712-sysirq", "mediatek,mt6577-sysirq": for MT2712 "mediatek,mt2701-sysirq", "mediatek,mt6577-sysirq": for MT2701 - interrupt-controller : Identifies the node as an interrupt controller - #interrupt-cells : Use the same format as specified by GIC in arm,gic.txt. diff --git a/Documentation/devicetree/bindings/interrupt-controller/socionext,uniphier-aidet.txt b/Documentation/devicetree/bindings/interrupt-controller/socionext,uniphier-aidet.txt new file mode 100644 index 000000000000..48e71d3ac2ad --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/socionext,uniphier-aidet.txt @@ -0,0 +1,32 @@ +UniPhier AIDET + +UniPhier AIDET (ARM Interrupt Detector) is an add-on block for ARM GIC (Generic +Interrupt Controller). GIC itself can handle only high level and rising edge +interrupts. The AIDET provides logic inverter to support low level and falling +edge interrupts. + +Required properties: +- compatible: Should be one of the following: + "socionext,uniphier-ld4-aidet" - for LD4 SoC + "socionext,uniphier-pro4-aidet" - for Pro4 SoC + "socionext,uniphier-sld8-aidet" - for sLD8 SoC + "socionext,uniphier-pro5-aidet" - for Pro5 SoC + "socionext,uniphier-pxs2-aidet" - for PXs2/LD6b SoC + "socionext,uniphier-ld11-aidet" - for LD11 SoC + "socionext,uniphier-ld20-aidet" - for LD20 SoC + "socionext,uniphier-pxs3-aidet" - for PXs3 SoC +- reg: Specifies offset and length of the register set for the device. +- interrupt-controller: Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode an interrupt + source. The value should be 2. The first cell defines the interrupt number + (corresponds to the SPI interrupt number of GIC). The second cell specifies + the trigger type as defined in interrupts.txt in this directory. + +Example: + + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pro4-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; diff --git a/Documentation/devicetree/bindings/iommu/qcom,iommu.txt b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt new file mode 100644 index 000000000000..b2641ceb2b40 --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/qcom,iommu.txt @@ -0,0 +1,121 @@ +* QCOM IOMMU v1 Implementation + +Qualcomm "B" family devices which are not compatible with arm-smmu have +a similar looking IOMMU but without access to the global register space, +and optionally requiring additional configuration to route context irqs +to non-secure vs secure interrupt line. + +** Required properties: + +- compatible : Should be one of: + + "qcom,msm8916-iommu" + + Followed by "qcom,msm-iommu-v1". + +- clock-names : Should be a pair of "iface" (required for IOMMUs + register group access) and "bus" (required for + the IOMMUs underlying bus access). + +- clocks : Phandles for respective clocks described by + clock-names. + +- #address-cells : must be 1. + +- #size-cells : must be 1. + +- #iommu-cells : Must be 1. Index identifies the context-bank #. + +- ranges : Base address and size of the iommu context banks. + +- qcom,iommu-secure-id : secure-id. + +- List of sub-nodes, one per translation context bank. Each sub-node + has the following required properties: + + - compatible : Should be one of: + - "qcom,msm-iommu-v1-ns" : non-secure context bank + - "qcom,msm-iommu-v1-sec" : secure context bank + - reg : Base address and size of context bank within the iommu + - interrupts : The context fault irq. + +** Optional properties: + +- reg : Base address and size of the SMMU local base, should + be only specified if the iommu requires configuration + for routing of context bank irq's to secure vs non- + secure lines. (Ie. if the iommu contains secure + context banks) + + +** Examples: + + apps_iommu: iommu@1e20000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1e20000 0x40000>; + reg = <0x1ef0000 0x3000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <17>; + + // mdp_0: + iommu-ctx@4000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x4000 0x1000>; + interrupts = ; + }; + + // venus_ns: + iommu-ctx@5000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x5000 0x1000>; + interrupts = ; + }; + }; + + gpu_iommu: iommu@1f08000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1f08000 0x10000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_GFX_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <18>; + + // gfx3d_user: + iommu-ctx@1000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x1000 0x1000>; + interrupts = ; + }; + + // gfx3d_priv: + iommu-ctx@2000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x2000 0x1000>; + interrupts = ; + }; + }; + + ... + + venus: video-codec@1d00000 { + ... + iommus = <&apps_iommu 5>; + }; + + mdp: mdp@1a01000 { + ... + iommus = <&apps_iommu 4>; + }; + + gpu@01c00000 { + ... + iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; + }; diff --git a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt index 9a55ac3735e5..2098f7732264 100644 --- a/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt +++ b/Documentation/devicetree/bindings/iommu/rockchip,iommu.txt @@ -15,6 +15,11 @@ Required properties: to associate with its master device. See: Documentation/devicetree/bindings/iommu/iommu.txt +Optional properties: +- rockchip,disable-mmu-reset : Don't use the mmu reset operation. + Some mmu instances may produce unexpected results + when the reset operation is used. + Example: vopl_mmu: iommu@ff940300 { diff --git a/Documentation/devicetree/bindings/leds/ams,as3645a.txt b/Documentation/devicetree/bindings/leds/ams,as3645a.txt new file mode 100644 index 000000000000..fdc40e354a64 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ams,as3645a.txt @@ -0,0 +1,79 @@ +Analog devices AS3645A device tree bindings + +The AS3645A flash LED controller can drive two LEDs, one high current +flash LED and one indicator LED. The high current flash LED can be +used in torch mode as well. + +Ranges below noted as [a, b] are closed ranges between a and b, i.e. a +and b are included in the range. + +Please also see common.txt in the same directory. + + +Required properties +=================== + +compatible : Must be "ams,as3645a". +reg : The I2C address of the device. Typically 0x30. +#address-cells : 1 +#size-cells : 0 + + +Required properties of the flash child node (0) +=============================================== + +reg: 0 +flash-timeout-us: Flash timeout in microseconds. The value must be in + the range [100000, 850000] and divisible by 50000. +flash-max-microamp: Maximum flash current in microamperes. Has to be + in the range between [200000, 500000] and + divisible by 20000. +led-max-microamp: Maximum torch (assist) current in microamperes. The + value must be in the range between [20000, 160000] and + divisible by 20000. +ams,input-max-microamp: Maximum flash controller input current. The + value must be in the range [1250000, 2000000] + and divisible by 50000. + + +Optional properties of the flash child node +=========================================== + +label : The label of the flash LED. + + +Required properties of the indicator child node (1) +=================================================== + +reg: 1 +led-max-microamp: Maximum indicator current. The allowed values are + 2500, 5000, 7500 and 10000. + +Optional properties of the indicator child node +=============================================== + +label : The label of the indicator LED. + + +Example +======= + + as3645a@30 { + #address-cells: 1 + #size-cells: 0 + reg = <0x30>; + compatible = "ams,as3645a"; + flash@0 { + reg = <0x0>; + flash-timeout-us = <150000>; + flash-max-microamp = <320000>; + led-max-microamp = <60000>; + ams,input-max-microamp = <1750000>; + label = "as3645a:flash"; + }; + indicator@1 { + reg = <0x1>; + led-max-microamp = <10000>; + label = "as3645a:indicator"; + }; + }; diff --git a/Documentation/devicetree/bindings/leds/irled/gpio-ir-tx.txt b/Documentation/devicetree/bindings/leds/irled/gpio-ir-tx.txt new file mode 100644 index 000000000000..cbe8dfd29715 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/irled/gpio-ir-tx.txt @@ -0,0 +1,14 @@ +Device tree bindings for IR LED connected through gpio pin which is used as +remote controller transmitter. + +Required properties: + - compatible: should be "gpio-ir-tx". + - gpios : Should specify the IR LED GPIO, see "gpios property" in + Documentation/devicetree/bindings/gpio/gpio.txt. Active low LEDs + should be indicated using flags in the GPIO specifier. + +Example: + irled@0 { + compatible = "gpio-ir-tx"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.txt b/Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.txt new file mode 100644 index 000000000000..66e5672c2e3d --- /dev/null +++ b/Documentation/devicetree/bindings/leds/irled/pwm-ir-tx.txt @@ -0,0 +1,13 @@ +Device tree bindings for IR LED connected through pwm pin which is used as +remote controller transmitter. + +Required properties: + - compatible: should be "pwm-ir-tx". + - pwms : PWM property to point to the PWM device (phandle)/port (id) + and to specify the period time to be used: <&phandle id period_ns>; + +Example: + irled { + compatible = "pwm-ir-tx"; + pwms = <&pwm0 0 10000000>; + }; diff --git a/Documentation/devicetree/bindings/leds/leds-gpio.txt b/Documentation/devicetree/bindings/leds/leds-gpio.txt index 76535ca37120..a48dda268f81 100644 --- a/Documentation/devicetree/bindings/leds/leds-gpio.txt +++ b/Documentation/devicetree/bindings/leds/leds-gpio.txt @@ -18,6 +18,9 @@ LED sub-node properties: see Documentation/devicetree/bindings/leds/common.txt - retain-state-suspended: (optional) The suspend state can be retained.Such as charge-led gpio. +- retain-state-shutdown: (optional) Retain the state of the LED on shutdown. + Useful in BMC systems, for example when the BMC is rebooted while the host + remains up. - panic-indicator : (optional) see Documentation/devicetree/bindings/leds/common.txt diff --git a/Documentation/devicetree/bindings/leds/leds-pca955x.txt b/Documentation/devicetree/bindings/leds/leds-pca955x.txt new file mode 100644 index 000000000000..7984efb767b4 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-pca955x.txt @@ -0,0 +1,88 @@ +* NXP - pca955x LED driver + +The PCA955x family of chips are I2C LED blinkers whose pins not used +to control LEDs can be used as general purpose I/Os. The GPIO pins can +be input or output, and output pins can also be pulse-width controlled. + +Required properties: +- compatible : should be one of : + "nxp,pca9550" + "nxp,pca9551" + "nxp,pca9552" + "nxp,pca9553" +- #address-cells: must be 1 +- #size-cells: must be 0 +- reg: I2C slave address. depends on the model. + +Optional properties: +- gpio-controller: allows pins to be used as GPIOs. +- #gpio-cells: must be 2. +- gpio-line-names: define the names of the GPIO lines + +LED sub-node properties: +- reg : number of LED line. + from 0 to 1 for the pca9550 + from 0 to 7 for the pca9551 + from 0 to 15 for the pca9552 + from 0 to 3 for the pca9553 +- type: (optional) either + PCA9532_TYPE_NONE + PCA9532_TYPE_LED + PCA9532_TYPE_GPIO + see dt-bindings/leds/leds-pca955x.h (default to LED) +- label : (optional) + see Documentation/devicetree/bindings/leds/common.txt +- linux,default-trigger : (optional) + see Documentation/devicetree/bindings/leds/common.txt + +Examples: + +pca9552: pca9552@60 { + compatible = "nxp,pca9552"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60>; + + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "GPIO12", "GPIO13", "GPIO14", "GPIO15"; + + gpio@12 { + reg = <12>; + type = ; + }; + gpio@13 { + reg = <13>; + type = ; + }; + gpio@14 { + reg = <14>; + type = ; + }; + gpio@15 { + reg = <15>; + type = ; + }; + + led@0 { + label = "red:power"; + linux,default-trigger = "default-on"; + reg = <0>; + type = ; + }; + led@1 { + label = "green:power"; + reg = <1>; + type = ; + }; + led@2 { + label = "pca9552:yellow"; + reg = <2>; + type = ; + }; + led@3 { + label = "pca9552:white"; + reg = <3>; + type = ; + }; +}; diff --git a/Documentation/devicetree/bindings/media/i2c/adv748x.txt b/Documentation/devicetree/bindings/media/i2c/adv748x.txt new file mode 100644 index 000000000000..21ffb5ed8183 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/adv748x.txt @@ -0,0 +1,95 @@ +* Analog Devices ADV748X video decoder with HDMI receiver + +The ADV7481 and ADV7482 are multi format video decoders with an integrated +HDMI receiver. They can output CSI-2 on two independent outputs TXA and TXB +from three input sources HDMI, analog and TTL. + +Required Properties: + + - compatible: Must contain one of the following + - "adi,adv7481" for the ADV7481 + - "adi,adv7482" for the ADV7482 + + - reg: I2C slave address + +Optional Properties: + + - interrupt-names: Should specify the interrupts as "intrq1", "intrq2" and/or + "intrq3". All interrupts are optional. The "intrq3" interrupt + is only available on the adv7481 + - interrupts: Specify the interrupt lines for the ADV748x + +The device node must contain one 'port' child node per device input and output +port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. The port nodes +are numbered as follows. + + Name Type Port + --------------------------------------- + AIN0 sink 0 + AIN1 sink 1 + AIN2 sink 2 + AIN3 sink 3 + AIN4 sink 4 + AIN5 sink 5 + AIN6 sink 6 + AIN7 sink 7 + HDMI sink 8 + TTL sink 9 + TXA source 10 + TXB source 11 + +The digital output port nodes must contain at least one endpoint. + +Ports are optional if they are not connected to anything at the hardware level. + +Example: + + video-receiver@70 { + compatible = "adi,adv7482"; + reg = <0x70>; + + #address-cells = <1>; + #size-cells = <0>; + + interrupt-parent = <&gpio6>; + interrupt-names = "intrq1", "intrq2"; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>, + <31 IRQ_TYPE_LEVEL_LOW>; + + port@7 { + reg = <7>; + + adv7482_ain7: endpoint { + remote-endpoint = <&cvbs_in>; + }; + }; + + port@8 { + reg = <8>; + + adv7482_hdmi: endpoint { + remote-endpoint = <&hdmi_in>; + }; + }; + + port@10 { + reg = <10>; + + adv7482_txa: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&csi40_in>; + }; + }; + + port@11 { + reg = <11>; + + adv7482_txb: endpoint { + clock-lanes = <0>; + data-lanes = <1>; + remote-endpoint = <&csi20_in>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt new file mode 100644 index 000000000000..b88dcdd41def --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/dongwoon,dw9714.txt @@ -0,0 +1,9 @@ +Dongwoon Anatech DW9714 camera voice coil lens driver + +DW9174 is a 10-bit DAC with current sink capability. It is intended +for driving voice coil lenses in camera modules. + +Mandatory properties: + +- compatible: "dongwoon,dw9714" +- reg: I²C slave address diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt b/Documentation/devicetree/bindings/media/meson-ao-cec.txt new file mode 100644 index 000000000000..8671bdb08080 --- /dev/null +++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt @@ -0,0 +1,28 @@ +* Amlogic Meson AO-CEC driver + +The Amlogic Meson AO-CEC module is present is Amlogic SoCs and its purpose is +to handle communication between HDMI connected devices over the CEC bus. + +Required properties: + - compatible : value should be following + "amlogic,meson-gx-ao-cec" + + - reg : Physical base address of the IP registers and length of memory + mapped region. + + - interrupts : AO-CEC interrupt number to the CPU. + - clocks : from common clock binding: handle to AO-CEC clock. + - clock-names : from common clock binding: must contain "core", + corresponding to entry in the clocks property. + - hdmi-phandle: phandle to the HDMI controller + +Example: + +cec_AO: cec@100 { + compatible = "amlogic,meson-gx-ao-cec"; + reg = <0x0 0x00100 0x0 0x14>; + interrupts = ; + clocks = <&clkc_AO CLKID_AO_CEC_32K>; + clock-names = "core"; + hdmi-phandle = <&hdmi_tx>; +}; diff --git a/Documentation/devicetree/bindings/media/mtk-cir.txt b/Documentation/devicetree/bindings/media/mtk-cir.txt index 2be2005577d6..5e18087ce11f 100644 --- a/Documentation/devicetree/bindings/media/mtk-cir.txt +++ b/Documentation/devicetree/bindings/media/mtk-cir.txt @@ -2,10 +2,14 @@ Device-Tree bindings for Mediatek consumer IR controller found in Mediatek SoC family Required properties: -- compatible : "mediatek,mt7623-cir" +- compatible : Should be + "mediatek,mt7623-cir": for MT7623 SoC + "mediatek,mt7622-cir": for MT7622 SoC - clocks : list of clock specifiers, corresponding to entries in clock-names property; -- clock-names : should contain "clk" entries; +- clock-names : should contain + - "clk" entries: for MT7623 SoC + - "clk", "bus" entries: for MT7622 SoC - interrupts : should contain IR IRQ number; - reg : should contain IO map address for IR. diff --git a/Documentation/devicetree/bindings/media/pxa-camera.txt b/Documentation/devicetree/bindings/media/pxa-camera.txt index 11f5b5d51af8..bc03ec096269 100644 --- a/Documentation/devicetree/bindings/media/pxa-camera.txt +++ b/Documentation/devicetree/bindings/media/pxa-camera.txt @@ -24,7 +24,6 @@ Example: clock-frequency = <50000000>; clock-output-names = "qci_mclk"; - status = "okay"; port { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/media/qcom,camss.txt b/Documentation/devicetree/bindings/media/qcom,camss.txt new file mode 100644 index 000000000000..cadecebc73f7 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,camss.txt @@ -0,0 +1,197 @@ +Qualcomm Camera Subsystem + +* Properties + +- compatible: + Usage: required + Value type: + Definition: Should contain: + - "qcom,msm8916-camss" +- reg: + Usage: required + Value type: + Definition: Register ranges as listed in the reg-names property. +- reg-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "csiphy0" + - "csiphy0_clk_mux" + - "csiphy1" + - "csiphy1_clk_mux" + - "csid0" + - "csid1" + - "ispif" + - "csi_clk_mux" + - "vfe0" +- interrupts: + Usage: required + Value type: + Definition: Interrupts as listed in the interrupt-names property. +- interrupt-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "csiphy0" + - "csiphy1" + - "csid0" + - "csid1" + - "ispif" + - "vfe0" +- power-domains: + Usage: required + Value type: + Definition: A phandle and power domain specifier pairs to the + power domain which is responsible for collapsing + and restoring power to the peripheral. +- clocks: + Usage: required + Value type: + Definition: A list of phandle and clock specifier pairs as listed + in clock-names property. +- clock-names: + Usage: required + Value type: + Definition: Should contain the following entries: + - "camss_top_ahb" + - "ispif_ahb" + - "csiphy0_timer" + - "csiphy1_timer" + - "csi0_ahb" + - "csi0" + - "csi0_phy" + - "csi0_pix" + - "csi0_rdi" + - "csi1_ahb" + - "csi1" + - "csi1_phy" + - "csi1_pix" + - "csi1_rdi" + - "camss_ahb" + - "camss_vfe_vfe" + - "camss_csi_vfe" + - "iface" + - "bus" +- vdda-supply: + Usage: required + Value type: + Definition: A phandle to voltage supply for CSI2. +- iommus: + Usage: required + Value type: + Definition: A list of phandle and IOMMU specifier pairs. + +* Nodes + +- ports: + Usage: required + Definition: As described in video-interfaces.txt in same directory. + Properties: + - reg: + Usage: required + Value type: + Definition: Selects CSI2 PHY interface - PHY0 or PHY1. + Endpoint node properties: + - clock-lanes: + Usage: required + Value type: + Definition: The physical clock lane index. The value + must always be <1> as the physical clock + lane is lane 1. + - data-lanes: + Usage: required + Value type: + Definition: An array of physical data lanes indexes. + Position of an entry determines the logical + lane number, while the value of an entry + indicates physical lane index. Lane swapping + is supported. + +* An Example + + camss: camss@1b00000 { + compatible = "qcom,msm8916-camss"; + reg = <0x1b0ac00 0x200>, + <0x1b00030 0x4>, + <0x1b0b000 0x200>, + <0x1b00038 0x4>, + <0x1b08000 0x100>, + <0x1b08400 0x100>, + <0x1b0a000 0x500>, + <0x1b00020 0x10>, + <0x1b10000 0x1000>; + reg-names = "csiphy0", + "csiphy0_clk_mux", + "csiphy1", + "csiphy1_clk_mux", + "csid0", + "csid1", + "ispif", + "csi_clk_mux", + "vfe0"; + interrupts = , + , + , + , + , + ; + interrupt-names = "csiphy0", + "csiphy1", + "csid0", + "csid1", + "ispif", + "vfe0"; + power-domains = <&gcc VFE_GDSC>; + clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, + <&gcc GCC_CAMSS_ISPIF_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CSI0_AHB_CLK>, + <&gcc GCC_CAMSS_CSI0_CLK>, + <&gcc GCC_CAMSS_CSI0PHY_CLK>, + <&gcc GCC_CAMSS_CSI0PIX_CLK>, + <&gcc GCC_CAMSS_CSI0RDI_CLK>, + <&gcc GCC_CAMSS_CSI1_AHB_CLK>, + <&gcc GCC_CAMSS_CSI1_CLK>, + <&gcc GCC_CAMSS_CSI1PHY_CLK>, + <&gcc GCC_CAMSS_CSI1PIX_CLK>, + <&gcc GCC_CAMSS_CSI1RDI_CLK>, + <&gcc GCC_CAMSS_AHB_CLK>, + <&gcc GCC_CAMSS_VFE0_CLK>, + <&gcc GCC_CAMSS_CSI_VFE0_CLK>, + <&gcc GCC_CAMSS_VFE_AHB_CLK>, + <&gcc GCC_CAMSS_VFE_AXI_CLK>; + clock-names = "camss_top_ahb", + "ispif_ahb", + "csiphy0_timer", + "csiphy1_timer", + "csi0_ahb", + "csi0", + "csi0_phy", + "csi0_pix", + "csi0_rdi", + "csi1_ahb", + "csi1", + "csi1_phy", + "csi1_pix", + "csi1_rdi", + "camss_ahb", + "camss_vfe_vfe", + "camss_csi_vfe", + "iface", + "bus"; + vdda-supply = <&pm8916_l2>; + iommus = <&apps_iommu 3>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + csiphy0_ep: endpoint { + clock-lanes = <1>; + data-lanes = <0 2>; + remote-endpoint = <&ov5645_ep>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/media/renesas,drif.txt b/Documentation/devicetree/bindings/media/renesas,drif.txt index 39516b94c28f..0d8974aa8b38 100644 --- a/Documentation/devicetree/bindings/media/renesas,drif.txt +++ b/Documentation/devicetree/bindings/media/renesas,drif.txt @@ -40,6 +40,7 @@ To summarize, Required properties of an internal channel: ------------------------------------------- - compatible: "renesas,r8a7795-drif" if DRIF controller is a part of R8A7795 SoC. + "renesas,r8a7796-drif" if DRIF controller is a part of R8A7796 SoC. "renesas,rcar-gen3-drif" for a generic R-Car Gen3 compatible device. When compatible with the generic version, nodes must list the diff --git a/Documentation/devicetree/bindings/media/s5p-cec.txt b/Documentation/devicetree/bindings/media/s5p-cec.txt index 1b1a10ba48ce..6f3756da900f 100644 --- a/Documentation/devicetree/bindings/media/s5p-cec.txt +++ b/Documentation/devicetree/bindings/media/s5p-cec.txt @@ -33,5 +33,4 @@ hdmicec: cec@100B0000 { hdmi-phandle = <&hdmi>; pinctrl-names = "default"; pinctrl-0 = <&hdmi_cec>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt index 922d6f8e74be..e4e15d8d7521 100644 --- a/Documentation/devicetree/bindings/media/samsung-fimc.txt +++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt @@ -166,7 +166,6 @@ Example: clock-output-names = "cam_a_clkout", "cam_b_clkout"; pinctrl-names = "default"; pinctrl-0 = <&cam_port_a_clk_active>; - status = "okay"; #address-cells = <1>; #size-cells = <1>; @@ -189,7 +188,6 @@ Example: compatible = "samsung,exynos4210-fimc"; reg = <0x11800000 0x1000>; interrupts = <0 85 0>; - status = "okay"; }; csis_0: csis@11880000 { diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt index cc51b1fd6e0c..6af3fc210ecc 100644 --- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt +++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt @@ -52,7 +52,6 @@ Example: c8sectpfe@08a20000 { compatible = "st,stih407-c8sectpfe"; - status = "okay"; reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>; reg-names = "stfe", "stfe-ram"; interrupts = , ; diff --git a/Documentation/devicetree/bindings/media/ti,da850-vpif.txt b/Documentation/devicetree/bindings/media/ti,da850-vpif.txt index df7182a63e59..e47c7ccc57f1 100644 --- a/Documentation/devicetree/bindings/media/ti,da850-vpif.txt +++ b/Documentation/devicetree/bindings/media/ti,da850-vpif.txt @@ -59,7 +59,6 @@ I2C-connected TVP5147 decoder: tvp5147@5d { compatible = "ti,tvp5147"; reg = <0x5d>; - status = "okay"; port { composite_in: endpoint { diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt index 9cd2a369125d..852041a7480c 100644 --- a/Documentation/devicetree/bindings/media/video-interfaces.txt +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt @@ -76,6 +76,11 @@ Optional endpoint properties mode horizontal and vertical synchronization signals are provided to the slave device (data source) by the master device (data sink). In the master mode the data source device is also the source of the synchronization signals. +- bus-type: data bus type. Possible values are: + 0 - autodetect based on other properties (MIPI CSI-2 D-PHY, parallel or Bt656) + 1 - MIPI CSI-2 C-PHY + 2 - MIPI CSI1 + 3 - CCP2 - bus-width: number of data lines actively used, valid for the parallel busses. - data-shift: on the parallel data busses, if bus-width is used to specify the number of data lines, data-shift can be used to specify which data lines are @@ -112,7 +117,8 @@ Optional endpoint properties should be the combined length of data-lanes and clock-lanes properties. If the lane-polarities property is omitted, the value must be interpreted as 0 (normal). This property is valid for serial busses only. - +- strobe: Whether the clock signal is used as clock (0) or strobe (1). Used + with CCP2, for instance. Example ------- diff --git a/Documentation/devicetree/bindings/media/zx-irdec.txt b/Documentation/devicetree/bindings/media/zx-irdec.txt new file mode 100644 index 000000000000..295b9fab593e --- /dev/null +++ b/Documentation/devicetree/bindings/media/zx-irdec.txt @@ -0,0 +1,14 @@ +IR Decoder (IRDEC) on ZTE ZX family SoCs + +Required properties: + - compatible: Should be "zte,zx296718-irdec". + - reg: Physical base address and length of IRDEC registers. + - interrupts: Interrupt number of IRDEC. + +Exmaples: + + irdec: ir-decoder@111000 { + compatible = "zte,zx296718-irdec"; + reg = <0x111000 0x1000>; + interrupts = ; + }; diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt index 21277a56e94c..ddf46b8856a5 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt @@ -15,6 +15,9 @@ Required properties: the register. - "smi" : It's the clock for transfer data and command. +Required property for mt2701: +- mediatek,larb-id :the hardware id of this larb. + Example: larb1: larb@16010000 { compatible = "mediatek,mt8173-smi-larb"; @@ -25,3 +28,15 @@ Example: <&vdecsys CLK_VDEC_LARB_CKEN>; clock-names = "apb", "smi"; }; + +Example for mt2701: + larb0: larb@14010000 { + compatible = "mediatek,mt2701-smi-larb"; + reg = <0 0x14010000 0 0x1000>; + mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB0>; + clock-names = "apb", "smi"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_DISP>; + }; diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt index 1ee3bc09f319..8b9388cc1ccc 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt @@ -130,7 +130,6 @@ The reg property implicitly specifies the chip select as this: Example: devbus-bootcs@d0010400 { - status = "okay"; ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf0000000, size 0x1000000 */ #address-cells = <1>; #size-cells = <1>; diff --git a/Documentation/devicetree/bindings/mfd/act8945a.txt b/Documentation/devicetree/bindings/mfd/act8945a.txt index 462819ac3da8..e6f168db6c72 100644 --- a/Documentation/devicetree/bindings/mfd/act8945a.txt +++ b/Documentation/devicetree/bindings/mfd/act8945a.txt @@ -12,7 +12,6 @@ Example: pmic@5b { compatible = "active-semi,act8945a"; reg = <0x5b>; - status = "okay"; active-semi,vsel-high; @@ -79,6 +78,5 @@ Example: active-semi,input-voltage-threshold-microvolt = <6600>; active-semi,precondition-timeout = <40>; active-semi,total-timeout = <3>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt index eec40be7f79a..3f643ef121ff 100644 --- a/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt +++ b/Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt @@ -25,7 +25,6 @@ Example: clocks = <&lcdc_clk>, <&lcdck>, <&clk32k>; clock-names = "periph_clk","sys_clk", "slow_clk"; interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; - status = "disabled"; hlcdc-display-controller { compatible = "atmel,hlcdc-display-controller"; diff --git a/Documentation/devicetree/bindings/mfd/atmel-smc.txt b/Documentation/devicetree/bindings/mfd/atmel-smc.txt index 26eeed373934..1103ce2030fb 100644 --- a/Documentation/devicetree/bindings/mfd/atmel-smc.txt +++ b/Documentation/devicetree/bindings/mfd/atmel-smc.txt @@ -8,6 +8,7 @@ Required properties: - compatible: Should be one of the following "atmel,at91sam9260-smc", "syscon" "atmel,sama5d3-smc", "syscon" + "atmel,sama5d2-smc", "syscon" - reg: Contains offset/length value of the SMC memory region. diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt index aca09af66514..9455503b0299 100644 --- a/Documentation/devicetree/bindings/mfd/axp20x.txt +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt @@ -7,7 +7,14 @@ axp209 (X-Powers) axp221 (X-Powers) axp223 (X-Powers) axp803 (X-Powers) +axp806 (X-Powers) axp809 (X-Powers) +axp813 (X-Powers) + +The AXP813 is 2 chips packaged into 1. The 2 chips do not share anything +other than the packaging. Pins are routed separately. As such they should +be treated as separate entities. The other half is an AC100 RTC/codec +combo chip. Please see ./ac100.txt for its bindings. Required properties: - compatible: should be one of: @@ -19,6 +26,7 @@ Required properties: * "x-powers,axp803" * "x-powers,axp806" * "x-powers,axp809" + * "x-powers,axp813" - reg: The I2C slave address or RSB hardware address for the AXP chip - interrupt-parent: The parent interrupt controller - interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin @@ -28,12 +36,14 @@ Required properties: Optional properties: - x-powers,dcdc-freq: defines the work frequency of DC-DC in KHz AXP152/20X: range: 750-1875, Default: 1.5 MHz - AXP22X/80X: range: 1800-4050, Default: 3 MHz + AXP22X/8XX: range: 1800-4050, Default: 3 MHz -- x-powers,drive-vbus-en: axp221 / axp223 only boolean, set this when the - N_VBUSEN pin is used as an output pin to control an external - regulator to drive the OTG VBus, rather then as an input pin - which signals whether the board is driving OTG VBus or not. +- x-powers,drive-vbus-en: boolean, set this when the N_VBUSEN pin is + used as an output pin to control an external + regulator to drive the OTG VBus, rather then + as an input pin which signals whether the + board is driving OTG VBus or not. + (axp221 / axp223 / axp813 only) - x-powers,master-mode: Boolean (axp806 only). Set this when the PMIC is wired for master mode. The default is slave mode. @@ -171,6 +181,36 @@ LDO_IO1 : LDO : ips-supply : GPIO 1 RTC_LDO : LDO : ips-supply : always on SW : On/Off Switch : swin-supply +AXP813 regulators, type, and corresponding input supply names: + +Regulator Type Supply Name Notes +--------- ---- ----------- ----- +DCDC1 : DC-DC buck : vin1-supply +DCDC2 : DC-DC buck : vin2-supply : poly-phase capable +DCDC3 : DC-DC buck : vin3-supply : poly-phase capable +DCDC4 : DC-DC buck : vin4-supply +DCDC5 : DC-DC buck : vin5-supply : poly-phase capable +DCDC6 : DC-DC buck : vin6-supply : poly-phase capable +DCDC7 : DC-DC buck : vin7-supply +ALDO1 : LDO : aldoin-supply : shared supply +ALDO2 : LDO : aldoin-supply : shared supply +ALDO3 : LDO : aldoin-supply : shared supply +DLDO1 : LDO : dldoin-supply : shared supply +DLDO2 : LDO : dldoin-supply : shared supply +DLDO3 : LDO : dldoin-supply : shared supply +DLDO4 : LDO : dldoin-supply : shared supply +ELDO1 : LDO : eldoin-supply : shared supply +ELDO2 : LDO : eldoin-supply : shared supply +ELDO3 : LDO : eldoin-supply : shared supply +FLDO1 : LDO : fldoin-supply : shared supply +FLDO2 : LDO : fldoin-supply : shared supply +FLDO3 : LDO : fldoin-supply : shared supply +LDO_IO0 : LDO : ips-supply : GPIO 0 +LDO_IO1 : LDO : ips-supply : GPIO 1 +RTC_LDO : LDO : ips-supply : always on +SW : On/Off Switch : swin-supply +DRIVEVBUS : Enable output : drivevbus-supply : external regulator + Example: axp209: pmic@34 { diff --git a/Documentation/devicetree/bindings/mfd/bd9571mwv.txt b/Documentation/devicetree/bindings/mfd/bd9571mwv.txt new file mode 100644 index 000000000000..9ab216a851d5 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/bd9571mwv.txt @@ -0,0 +1,49 @@ +* ROHM BD9571MWV Power Management Integrated Circuit (PMIC) bindings + +Required properties: + - compatible : Should be "rohm,bd9571mwv". + - reg : I2C slave address. + - interrupt-parent : Phandle to the parent interrupt controller. + - interrupts : The interrupt line the device is connected to. + - interrupt-controller : Marks the device node as an interrupt controller. + - #interrupt-cells : The number of cells to describe an IRQ, should be 2. + The first cell is the IRQ number. + The second cell is the flags, encoded as trigger + masks from ../interrupt-controller/interrupts.txt. + - gpio-controller : Marks the device node as a GPIO Controller. + - #gpio-cells : Should be two. The first cell is the pin number and + the second cell is used to specify flags. + See ../gpio/gpio.txt for more information. + - regulators: : List of child nodes that specify the regulator + initialization data. Child nodes must be named + after their hardware counterparts: + - vd09 + - vd18 + - vd25 + - vd33 + - dvfs + Each child node is defined using the standard + binding for regulators. + +Example: + + pmic: pmic@30 { + compatible = "rohm,bd9571mwv"; + reg = <0x30>; + interrupt-parent = <&gpio2>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + + regulators { + dvfs: dvfs { + regulator-name = "dvfs"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1030000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/da9052-i2c.txt b/Documentation/devicetree/bindings/mfd/da9052-i2c.txt index 9554292dc6cb..07c69c0c6624 100644 --- a/Documentation/devicetree/bindings/mfd/da9052-i2c.txt +++ b/Documentation/devicetree/bindings/mfd/da9052-i2c.txt @@ -4,6 +4,14 @@ Required properties: - compatible : Should be "dlg,da9052", "dlg,da9053-aa", "dlg,da9053-ab", or "dlg,da9053-bb" +Optional properties: +- dlg,tsi-as-adc : Boolean, if set the X+, X-, Y+, Y- touchscreen + input lines are used as general purpose analogue + input. +- tsiref-supply: Phandle to the regulator, which provides the reference + voltage for the TSIREF pin. Must be provided when the + touchscreen pins are used for ADC purposes. + Sub-nodes: - regulators : Contain the regulator nodes. The DA9052/53 regulators are bound using their names as listed below: @@ -29,7 +37,6 @@ Sub-nodes: Examples: i2c@63fc8000 { /* I2C1 */ - status = "okay"; pmic: dialog@48 { compatible = "dlg,da9053-aa"; diff --git a/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/Documentation/devicetree/bindings/mfd/mc13xxx.txt index 8aba48821a85..39ba4146769d 100644 --- a/Documentation/devicetree/bindings/mfd/mc13xxx.txt +++ b/Documentation/devicetree/bindings/mfd/mc13xxx.txt @@ -116,7 +116,6 @@ ecspi@70010000 { /* ECSPI1 */ fsl,spi-num-chipselects = <2>; cs-gpios = <&gpio4 24 0>, /* GPIO4_24 */ <&gpio4 25 0>; /* GPIO4_25 */ - status = "okay"; pmic: mc13892@0 { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/mfd/mxs-lradc.txt b/Documentation/devicetree/bindings/mfd/mxs-lradc.txt index 555fb117d4fa..755cbef0647d 100644 --- a/Documentation/devicetree/bindings/mfd/mxs-lradc.txt +++ b/Documentation/devicetree/bindings/mfd/mxs-lradc.txt @@ -26,7 +26,6 @@ Example for i.MX23 SoC: compatible = "fsl,imx23-lradc"; reg = <0x80050000 0x2000>; interrupts = <36 37 38 39 40 41 42 43 44>; - status = "okay"; fsl,lradc-touchscreen-wires = <4>; fsl,ave-ctrl = <4>; fsl,ave-delay = <2>; @@ -39,7 +38,6 @@ Example for i.MX28 SoC: compatible = "fsl,imx28-lradc"; reg = <0x80050000 0x2000>; interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>; - status = "okay"; fsl,lradc-touchscreen-wires = <5>; fsl,ave-ctrl = <4>; fsl,ave-delay = <2>; diff --git a/Documentation/devicetree/bindings/mfd/retu.txt b/Documentation/devicetree/bindings/mfd/retu.txt new file mode 100644 index 000000000000..876242394a16 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/retu.txt @@ -0,0 +1,25 @@ +* Device tree bindings for Nokia Retu and Tahvo multi-function device + +Retu and Tahvo are a multi-function devices found on Nokia Internet +Tablets (770, N800 and N810). The Retu chip provides watchdog timer +and power button control functionalities while Tahvo chip provides +USB transceiver functionality. + +Required properties: +- compatible: "nokia,retu" or "nokia,tahvo" +- reg: Specifies the CBUS slave address of the ASIC chip +- interrupts: The interrupt line the device is connected to +- interrupt-parent: The parent interrupt controller + +Example: + +cbus0 { + compatible = "i2c-cbus-gpio"; + ... + retu: retu@1 { + compatible = "nokia,retu"; + interrupt-parent = <&gpio4>; + interrupts = <12 IRQ_TYPE_EDGE_RISING>; + reg = <0x1>; + }; +}; diff --git a/Documentation/devicetree/bindings/mfd/rk808.txt b/Documentation/devicetree/bindings/mfd/rk808.txt index 9636ae8d8d41..91b65227afeb 100644 --- a/Documentation/devicetree/bindings/mfd/rk808.txt +++ b/Documentation/devicetree/bindings/mfd/rk808.txt @@ -1,11 +1,14 @@ RK8XX Power Management Integrated Circuit The rk8xx family current members: +rk805 rk808 rk818 Required properties: -- compatible: "rockchip,rk808", "rockchip,rk818" +- compatible: "rockchip,rk805" +- compatible: "rockchip,rk808" +- compatible: "rockchip,rk818" - reg: I2C slave address - interrupt-parent: The parent interrupt controller. - interrupts: the interrupt outputs of the controller. @@ -18,6 +21,14 @@ Optional properties: - rockchip,system-power-controller: Telling whether or not this pmic is controlling the system power. +Optional RK805 properties: +- vcc1-supply: The input supply for DCDC_REG1 +- vcc2-supply: The input supply for DCDC_REG2 +- vcc3-supply: The input supply for DCDC_REG3 +- vcc4-supply: The input supply for DCDC_REG4 +- vcc5-supply: The input supply for LDO_REG1 and LDO_REG2 +- vcc6-supply: The input supply for LDO_REG3 + Optional RK808 properties: - vcc1-supply: The input supply for DCDC_REG1 - vcc2-supply: The input supply for DCDC_REG2 @@ -56,6 +67,15 @@ by a child node of the 'regulators' node. /* standard regulator bindings here */ }; +Following regulators of the RK805 PMIC regulators are supported. Note that +the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO +number as described in RK805 datasheet. + + - DCDC_REGn + - valid values for n are 1 to 4. + - LDO_REGn + - valid values for n are 1 to 3 + Following regulators of the RK808 PMIC block are supported. Note that the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO number as described in RK808 datasheet. diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt index df664018c148..d759da606f75 100644 --- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt +++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt @@ -57,7 +57,6 @@ audio-subsystem { clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; pinctrl-names = "default"; pinctrl-0 = <&i2s0_bus>; - status = "disabled"; }; serial_3: serial@11460000 { @@ -69,6 +68,5 @@ audio-subsystem { clock-names = "uart", "clk_uart_baud0"; pinctrl-names = "default"; pinctrl-0 = <&uart_aud_bus>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt b/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt new file mode 100644 index 000000000000..2a9ff29db9c9 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/stm32-lptimer.txt @@ -0,0 +1,48 @@ +STMicroelectronics STM32 Low-Power Timer + +The STM32 Low-Power Timer (LPTIM) is a 16-bit timer that provides several +functions: +- PWM output (with programmable prescaler, configurable polarity) +- Quadrature encoder, counter +- Trigger source for STM32 ADC/DAC (LPTIM_OUT) + +Required properties: +- compatible: Must be "st,stm32-lptimer". +- reg: Offset and length of the device's register set. +- clocks: Phandle to the clock used by the LP Timer module. +- clock-names: Must be "mux". +- #address-cells: Should be '<1>'. +- #size-cells: Should be '<0>'. + +Optional subnodes: +- pwm: See ../pwm/pwm-stm32-lp.txt +- counter: See ../iio/timer/stm32-lptimer-cnt.txt +- trigger: See ../iio/timer/stm32-lptimer-trigger.txt + +Example: + + timer@40002400 { + compatible = "st,stm32-lptimer"; + reg = <0x40002400 0x400>; + clocks = <&timer_clk>; + clock-names = "mux"; + #address-cells = <1>; + #size-cells = <0>; + + pwm { + compatible = "st,stm32-pwm-lp"; + pinctrl-names = "default"; + pinctrl-0 = <&lppwm1_pins>; + }; + + trigger@0 { + compatible = "st,stm32-lptimer-trigger"; + reg = <0>; + }; + + counter { + compatible = "st,stm32-lptimer-counter"; + pinctrl-names = "default"; + pinctrl-0 = <&lptim1_in_pins>; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/tps6105x.txt b/Documentation/devicetree/bindings/mfd/tps6105x.txt new file mode 100644 index 000000000000..93602c7a19c8 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/tps6105x.txt @@ -0,0 +1,17 @@ +* Device tree bindings for TI TPS61050/61052 Boost Converters + +The TP61050/TPS61052 is a high-power "white LED driver". The +device provides LED, GPIO and regulator functionalities. + +Required properties: +- compatible: "ti,tps61050" or "ti,tps61052" +- reg: Specifies the I2C slave address + +Example: + +i2c0 { + tps61052@33 { + compatible = "ti,tps61052"; + reg = <0x33>; + }; +}; diff --git a/Documentation/devicetree/bindings/mfd/wm831x.txt b/Documentation/devicetree/bindings/mfd/wm831x.txt index 9f8b7430673c..505709403d3f 100644 --- a/Documentation/devicetree/bindings/mfd/wm831x.txt +++ b/Documentation/devicetree/bindings/mfd/wm831x.txt @@ -31,6 +31,7 @@ Required properties: ../interrupt-controller/interrupts.txt Optional sub-nodes: + - phys : Contains a phandle to the USB PHY. - regulators : Contains sub-nodes for each of the regulators supplied by the device. The regulators are bound using their names listed below: diff --git a/Documentation/devicetree/bindings/mfd/zii,rave-sp.txt b/Documentation/devicetree/bindings/mfd/zii,rave-sp.txt new file mode 100644 index 000000000000..088eff9ddb78 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/zii,rave-sp.txt @@ -0,0 +1,39 @@ +Zodiac Inflight Innovations RAVE Supervisory Processor + +RAVE Supervisory Processor communicates with SoC over UART. It is +expected that its Device Tree node is specified as a child of a node +corresponding to UART controller used for communication. + +Required parent device properties: + + - compatible: Should be one of: + - "zii,rave-sp-niu" + - "zii,rave-sp-mezz" + - "zii,rave-sp-esb" + - "zii,rave-sp-rdu1" + - "zii,rave-sp-rdu2" + + - current-speed: Should be set to baud rate SP device is using + +RAVE SP consists of the following sub-devices: + +Device Description +------ ----------- +rave-sp-wdt : Watchdog +rave-sp-nvmem : Interface to onborad EEPROM +rave-sp-backlight : Display backlight +rave-sp-hwmon : Interface to onboard hardware sensors +rave-sp-leds : Interface to onboard LEDs +rave-sp-input : Interface to onboard power button + +Example of usage: + + rdu { + compatible = "zii,rave-sp-rdu2"; + current-speed = <1000000>; + + watchdog { + compatible = "zii,rave-sp-watchdog"; + }; + }; + diff --git a/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt b/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt new file mode 100644 index 000000000000..0a2df4338332 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/fpi-bus.txt @@ -0,0 +1,31 @@ +Lantiq XWAY SoC FPI BUS binding +============================ + + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,xrx200-fpi" +- reg : The address and length of the XBAR + configuration register. + Address and length of the FPI bus itself. +- lantiq,rcu : A phandle to the RCU syscon +- lantiq,offset-endianness : Offset of the endianness configuration + register + +------------------------------------------------------------------------------- +Example for the FPI on the xrx200 SoCs: + fpi@10000000 { + compatible = "lantiq,xrx200-fpi"; + ranges = <0x0 0x10000000 0xf000000>; + reg = <0x1f400000 0x1000>, + <0x10000000 0xf000000>; + lantiq,rcu = <&rcu0>; + lantiq,offset-endianness = <0x4c>; + #address-cells = <1>; + #size-cells = <1>; + + gptu@e100a00 { + ...... + }; + }; diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt new file mode 100644 index 000000000000..a0c19bd1ce66 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt @@ -0,0 +1,36 @@ +Lantiq XWAY SoC GPHY binding +============================ + +This binding describes a software-defined ethernet PHY, provided by the RCU +module on newer Lantiq XWAY SoCs (xRX200 and newer). + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,xrx200a1x-gphy" + "lantiq,xrx200a2x-gphy" + "lantiq,xrx300-gphy" + "lantiq,xrx330-gphy" +- reg : Addrress of the GPHY FW load address register +- resets : Must reference the RCU GPHY reset bit +- reset-names : One entry, value must be "gphy" or optional "gphy2" +- clocks : A reference to the (PMU) GPHY clock gate + +Optional properties: +- lantiq,gphy-mode : GPHY_MODE_GE (default) or GPHY_MODE_FE as defined in + + + +------------------------------------------------------------------------------- +Example for the GPHys on the xRX200 SoCs: + +#include + gphy0: gphy@20 { + compatible = "lantiq,xrx200a2x-gphy"; + reg = <0x20 0x4>; + + resets = <&reset0 31 30>, <&reset1 7 7>; + reset-names = "gphy", "gphy2"; + clocks = <&pmu0 XRX200_PMU_GATE_GPHY>; + lantiq,gphy-mode = ; + }; diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt new file mode 100644 index 000000000000..a086f1e1cdd7 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt @@ -0,0 +1,89 @@ +Lantiq XWAY SoC RCU binding +=========================== + +This binding describes the RCU (reset controller unit) multifunction device, +where each sub-device has it's own set of registers. + +The RCU register range is used for multiple purposes. Mostly one device +uses one or multiple register exclusively, but for some registers some +bits are for one driver and some other bits are for a different driver. +With this patch all accesses to the RCU registers will go through +syscon. + + +------------------------------------------------------------------------------- +Required properties: +- compatible : The first and second values must be: + "lantiq,xrx200-rcu", "simple-mfd", "syscon" +- reg : The address and length of the system control registers + + +------------------------------------------------------------------------------- +Example of the RCU bindings on a xRX200 SoC: + rcu0: rcu@203000 { + compatible = "lantiq,xrx200-rcu", "simple-mfd", "syscon"; + reg = <0x203000 0x100>; + ranges = <0x0 0x203000 0x100>; + big-endian; + + gphy0: gphy@20 { + compatible = "lantiq,xrx200a2x-gphy"; + reg = <0x20 0x4>; + + resets = <&reset0 31 30>, <&reset1 7 7>; + reset-names = "gphy", "gphy2"; + lantiq,gphy-mode = ; + }; + + gphy1: gphy@68 { + compatible = "lantiq,xrx200a2x-gphy"; + reg = <0x68 0x4>; + + resets = <&reset0 29 28>, <&reset1 6 6>; + reset-names = "gphy", "gphy2"; + lantiq,gphy-mode = ; + }; + + reset0: reset-controller@10 { + compatible = "lantiq,xrx200-reset"; + reg = <0x10 4>, <0x14 4>; + + #reset-cells = <2>; + }; + + reset1: reset-controller@48 { + compatible = "lantiq,xrx200-reset"; + reg = <0x48 4>, <0x24 4>; + + #reset-cells = <2>; + }; + + usb_phy0: usb2-phy@18 { + compatible = "lantiq,xrx200-usb2-phy"; + reg = <0x18 4>, <0x38 4>; + status = "disabled"; + + resets = <&reset1 4 4>, <&reset0 4 4>; + reset-names = "phy", "ctrl"; + #phy-cells = <0>; + }; + + usb_phy1: usb2-phy@34 { + compatible = "lantiq,xrx200-usb2-phy"; + reg = <0x34 4>, <0x3C 4>; + status = "disabled"; + + resets = <&reset1 5 4>, <&reset0 4 4>; + reset-names = "phy", "ctrl"; + #phy-cells = <0>; + }; + + reboot@10 { + compatible = "syscon-reboot"; + reg = <0x10 4>; + + regmap = <&rcu0>; + offset = <0x10>; + mask = <0x40000000>; + }; + }; diff --git a/Documentation/devicetree/bindings/mips/ni.txt b/Documentation/devicetree/bindings/mips/ni.txt new file mode 100644 index 000000000000..722bf2d62da9 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/ni.txt @@ -0,0 +1,7 @@ +National Instruments MIPS platforms + +required root node properties: + - compatible: must be "ni,169445" + +CPU Nodes + - compatible: must be "mti,mips14KEc" diff --git a/Documentation/devicetree/bindings/mips/ralink.txt b/Documentation/devicetree/bindings/mips/ralink.txt index b35a8d04f8b6..a16e8d7fe56c 100644 --- a/Documentation/devicetree/bindings/mips/ralink.txt +++ b/Documentation/devicetree/bindings/mips/ralink.txt @@ -15,3 +15,4 @@ value must be one of the following values: ralink,rt5350-soc ralink,mt7620a-soc ralink,mt7620n-soc + ralink,mt7628a-soc diff --git a/Documentation/devicetree/bindings/misc/atmel-ssc.txt b/Documentation/devicetree/bindings/misc/atmel-ssc.txt index f8629bb73945..f9fb412642fe 100644 --- a/Documentation/devicetree/bindings/misc/atmel-ssc.txt +++ b/Documentation/devicetree/bindings/misc/atmel-ssc.txt @@ -47,5 +47,4 @@ ssc0: ssc@f0010000 { dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ssc0_tx &pinctrl_ssc0_rx>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index 49df630bd44f..60481bfc3d31 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -74,5 +74,4 @@ Example: phys = <&emmc_phy>; phy-names = "phy_arasan"; #clock-cells = <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt index e5a0140b2381..516fb0143d4c 100644 --- a/Documentation/devicetree/bindings/mmc/davinci_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/davinci_mmc.txt @@ -24,7 +24,6 @@ mmc0: mmc@1c40000 { compatible = "ti,da830-mmc", reg = <0x40000 0x1000>; interrupts = <16>; - status = "okay"; bus-width = <4>; max-frequency = <50000000>; dmas = <&edma 16 diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt index db442355cd24..184ccffe2739 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-mmc.txt @@ -20,5 +20,4 @@ sdhci1: sdhci@10014000 { dma-names = "rx-tx"; bus-width = <4>; cd-gpios = <&gpio3 29>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt index b878a1e305af..ed1456f5c94d 100644 --- a/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.txt @@ -16,11 +16,13 @@ Required Properties: - clocks: Array of clocks required for SDHC. - Require at least input clock for Xenon IP core. + Require at least input clock for Xenon IP core. For Armada AP806 and + CP110, the AXI clock is also mandatory. - clock-names: Array of names corresponding to clocks property. The input clock for Xenon IP core should be named as "core". + The input clock for the AXI bus must be named as "axi". - reg: * For "marvell,armada-3700-sdhci", two register areas. @@ -106,8 +108,8 @@ Example: compatible = "marvell,armada-ap806-sdhci"; reg = <0xaa0000 0x1000>; interrupts = - clocks = <&emmc_clk>; - clock-names = "core"; + clocks = <&emmc_clk>,<&axi_clk>; + clock-names = "core", "axi"; bus-width = <4>; marvell,xenon-phy-slow-mode; marvell,xenon-tun-count = <11>; @@ -126,8 +128,8 @@ Example: interrupts = vqmmc-supply = <&sd_vqmmc_regulator>; vmmc-supply = <&sd_vmmc_regulator>; - clocks = <&sdclk>; - clock-names = "core"; + clocks = <&sdclk>, <&axi_clk>; + clock-names = "core", "axi"; bus-width = <4>; marvell,xenon-tun-count = <9>; }; diff --git a/Documentation/devicetree/bindings/mmc/mmc-card.txt b/Documentation/devicetree/bindings/mmc/mmc-card.txt index a70fcd65b9ea..8d2d71758907 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-card.txt +++ b/Documentation/devicetree/bindings/mmc/mmc-card.txt @@ -21,7 +21,6 @@ Example: vmmc-supply = <®_vcc3v3>; bus-width = <8>; non-removable; - status = "okay"; mmccard: mmccard@0 { reg = <0>; diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt index c7f4a0ec48ed..b32ade645ad9 100644 --- a/Documentation/devicetree/bindings/mmc/mmc.txt +++ b/Documentation/devicetree/bindings/mmc/mmc.txt @@ -153,7 +153,6 @@ mmc3: mmc@01c12000 { bus-width = <4>; non-removable; mmc-pwrseq = <&sdhci0_pwrseq> - status = "okay"; brcmf: bcrmf@1 { reg = <1>; diff --git a/Documentation/devicetree/bindings/mmc/orion-sdio.txt b/Documentation/devicetree/bindings/mmc/orion-sdio.txt index 84f0ebd67a13..10f0818a34c5 100644 --- a/Documentation/devicetree/bindings/mmc/orion-sdio.txt +++ b/Documentation/devicetree/bindings/mmc/orion-sdio.txt @@ -13,5 +13,4 @@ Example: reg = <0xd00d4000 0x200>; interrupts = <54>; clocks = <&gateclk 17>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt b/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt index c32dc5a9dbe6..5ff1e12c655a 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt +++ b/Documentation/devicetree/bindings/mmc/renesas,mmcif.txt @@ -11,6 +11,8 @@ Required properties: - "renesas,mmcif-r7s72100" for the MMCIF found in r7s72100 SoCs - "renesas,mmcif-r8a73a4" for the MMCIF found in r8a73a4 SoCs - "renesas,mmcif-r8a7740" for the MMCIF found in r8a7740 SoCs + - "renesas,mmcif-r8a7743" for the MMCIF found in r8a7743 SoCs + - "renesas,mmcif-r8a7745" for the MMCIF found in r8a7745 SoCs - "renesas,mmcif-r8a7778" for the MMCIF found in r8a7778 SoCs - "renesas,mmcif-r8a7790" for the MMCIF found in r8a7790 SoCs - "renesas,mmcif-r8a7791" for the MMCIF found in r8a7791 SoCs @@ -21,7 +23,7 @@ Required properties: - interrupts: Some SoCs have only 1 shared interrupt, while others have either 2 or 3 individual interrupts (error, int, card detect). Below is the number of interrupts for each SoC: - 1: r8a73a4, r8a7778, r8a7790, r8a7791, r8a7793, r8a7794 + 1: r8a73a4, r8a7743, r8a7745, r8a7778, r8a7790, r8a7791, r8a7793, r8a7794 2: r8a7740, sh73a0 3: r7s72100 diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt index 49ed3ad2524a..c6558785e61b 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt @@ -15,6 +15,7 @@ Required Properties: - "rockchip,rk3288-dw-mshc": for Rockchip RK3288 - "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RV1108 - "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036 + - "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK322x - "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3328 - "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368 - "rockchip,rk3399-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3399 diff --git a/Documentation/devicetree/bindings/mmc/sdhci-st.txt b/Documentation/devicetree/bindings/mmc/sdhci-st.txt index 230fd696eb92..e35645598315 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-st.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-st.txt @@ -63,7 +63,6 @@ Example: mmc0: sdhci@fe81e000 { compatible = "st,sdhci"; - status = "disabled"; reg = <0xfe81e000 0x1000>; interrupts = ; interrupt-names = "mmcirq"; @@ -77,7 +76,6 @@ mmc0: sdhci@fe81e000 { mmc1: sdhci@09080000 { compatible = "st,sdhci-stih407", "st,sdhci"; - status = "disabled"; reg = <0x09080000 0x7ff>; reg-names = "mmc"; interrupts = ; @@ -94,7 +92,6 @@ mmc1: sdhci@09080000 { mmc0: sdhci@09060000 { compatible = "st,sdhci-stih407", "st,sdhci"; - status = "disabled"; reg = <0x09060000 0x7ff>, <0x9061008 0x20>; reg-names = "mmc", "top-mmc-delay"; interrupts = ; diff --git a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt index 7d53a799f140..63b57e2a10fb 100644 --- a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt +++ b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt @@ -12,6 +12,7 @@ Required properties: * "allwinner,sun4i-a10-mmc" * "allwinner,sun5i-a13-mmc" * "allwinner,sun7i-a20-mmc" + * "allwinner,sun8i-a83t-emmc" * "allwinner,sun9i-a80-mmc" * "allwinner,sun50i-a64-emmc" * "allwinner,sun50i-a64-mmc" diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index 0e026c151c1c..3a4ac401e6f9 100644 --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt @@ -1,33 +1,55 @@ -* TI Highspeed MMC host controller for OMAP +* TI Highspeed MMC host controller for OMAP and 66AK2G family. -The Highspeed MMC Host Controller on TI OMAP family +The Highspeed MMC Host Controller on TI OMAP and 66AK2G family provides an interface for MMC, SD, and SDIO types of memory cards. This file documents differences between the core properties described by mmc.txt and the properties used by the omap_hsmmc driver. Required properties: +-------------------- - compatible: Should be "ti,omap2-hsmmc", for OMAP2 controllers Should be "ti,omap3-hsmmc", for OMAP3 controllers Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0 Should be "ti,omap4-hsmmc", for OMAP4 controllers Should be "ti,am33xx-hsmmc", for AM335x controllers -- ti,hwmods: Must be "mmc", n is controller instance starting 1 + Should be "ti,k2g-hsmmc", "ti,omap4-hsmmc" for 66AK2G controllers. + +SoC specific required properties: +--------------------------------- +The following are mandatory properties for OMAPs, AM33xx and AM43xx SoCs only: +- ti,hwmods: Must be "mmc", n is controller instance starting 1. + +The following are mandatory properties for 66AK2G SoCs only: +- power-domains:Should contain a phandle to a PM domain provider node + and an args specifier containing the MMC device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt +- clocks: Must contain an entry for each entry in clock-names. Should + be defined as per the he appropriate clock bindings consumer + usage in Documentation/devicetree/bindings/clock/ti,sci-clk.txt +- clock-names: Shall be "fck" for the functional clock, + and "mmchsdb_fck" for the debounce clock. + Optional properties: -ti,dual-volt: boolean, supports dual voltage cards --supply: phandle to the regulator device tree node -"supply-name" examples are "vmmc", "vmmc_aux"(deprecated)/"vqmmc" etc -ti,non-removable: non-removable slot (like eMMC) -ti,needs-special-reset: Requires a special softreset sequence -ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed -dmas: List of DMA specifiers with the controller specific format -as described in the generic DMA client binding. A tx and rx -specifier is required. -dma-names: List of DMA request names. These strings correspond -1:1 with the DMA specifiers listed in dmas. The string naming is -to be "rx" and "tx" for RX and TX DMA requests, respectively. +-------------------- +- ti,dual-volt: boolean, supports dual voltage cards +- -supply: phandle to the regulator device tree node + "supply-name" examples are "vmmc", + "vmmc_aux"(deprecated)/"vqmmc" etc +- ti,non-removable: non-removable slot (like eMMC) +- ti,needs-special-reset: Requires a special softreset sequence +- ti,needs-special-hs-handling: HSMMC IP needs special setting + for handling High Speed +- dmas: List of DMA specifiers with the controller specific + format as described in the generic DMA client + binding. A tx and rx specifier is required. +- dma-names: List of DMA request names. These strings correspond + 1:1 with the DMA specifiers listed in dmas. + The string naming is to be "rx" and "tx" for + RX and TX DMA requests, respectively. Examples: diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index 4fd8b7acc510..54ef642f23a0 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt @@ -15,6 +15,8 @@ Required properties: "renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC "renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC "renesas,sdhi-r8a7740" - SDHI IP on R8A7740 SoC + "renesas,sdhi-r8a7743" - SDHI IP on R8A7743 SoC + "renesas,sdhi-r8a7745" - SDHI IP on R8A7745 SoC "renesas,sdhi-r8a7778" - SDHI IP on R8A7778 SoC "renesas,sdhi-r8a7779" - SDHI IP on R8A7779 SoC "renesas,sdhi-r8a7790" - SDHI IP on R8A7790 SoC @@ -33,10 +35,8 @@ Required properties: If 2 clocks are specified by the hardware, you must name them as "core" and "cd". If the controller only has 1 clock, naming is not required. - Below is the number clocks for each supported SoC: - 1: SH73A0, R8A73A4, R8A7740, R8A7778, R8A7779, R8A7790 - R8A7791, R8A7792, R8A7793, R8A7794, R8A7795, R8A7796 - 2: R7S72100 + Devices which have more than 1 clock are listed below: + 2: R7S72100 Optional properties: - toshiba,mmc-wrprotect-disable: write-protect detection is unavailable diff --git a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt index 906819a90c2b..0f59bd5361f5 100644 --- a/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt @@ -28,5 +28,4 @@ Example: max-frequency = <50000000>; cap-sdio-irq; cap-sd-highspeed; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt index 489807005eda..b93c1e2f25dd 100644 --- a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt +++ b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt @@ -24,7 +24,6 @@ spi@f0020000 { #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi0_default>; - status = "okay"; m25p80@0 { ... diff --git a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt index 5ded66ad7aef..840f9405dcf0 100644 --- a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt +++ b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt @@ -37,7 +37,6 @@ nor_flash: spi@1100d000 { clock-names = "spi", "sf"; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; flash@0 { compatible = "jedec,spi-nor"; diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt index 70dd5118a324..73d336befa08 100644 --- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt @@ -1,11 +1,20 @@ * Qualcomm NAND controller Required properties: -- compatible: should be "qcom,ipq806x-nand" +- compatible: must be one of the following: + * "qcom,ipq806x-nand" - for EBI2 NAND controller being used in IPQ806x + SoC and it uses ADM DMA + * "qcom,ipq4019-nand" - for QPIC NAND controller v1.4.0 being used in + IPQ4019 SoC and it uses BAM DMA + * "qcom,ipq8074-nand" - for QPIC NAND controller v1.5.0 being used in + IPQ8074 SoC and it uses BAM DMA + - reg: MMIO address range - clocks: must contain core clock and always on clock - clock-names: must contain "core" for the core clock and "aon" for the always on clock + +EBI2 specific properties: - dmas: DMA specifier, consisting of a phandle to the ADM DMA controller node and the channel number to be used for NAND. Refer to dma.txt and qcom_adm.txt for more details @@ -16,6 +25,12 @@ Required properties: - qcom,data-crci: must contain the ADM data type CRCI block instance number specified for the NAND controller on the given platform + +QPIC specific properties: +- dmas: DMA specifier, consisting of a phandle to the BAM DMA + and the channel number to be used for NAND. Refer to + dma.txt, qcom_bam_dma.txt for more details +- dma-names: must contain all 3 channel names : "tx", "rx", "cmd" - #address-cells: <1> - subnodes give the chip-select number - #size-cells: <0> @@ -26,7 +41,6 @@ chip-selects which (may) contain NAND flash chips. Their properties are as follows. Required properties: -- compatible: should contain "qcom,nandcs" - reg: a single integer representing the chip-select number (e.g., 0, 1, 2, etc.) - #address-cells: see partition.txt @@ -43,8 +57,8 @@ partition.txt for more detail. Example: -nand@1ac00000 { - compatible = "qcom,ebi2-nandc"; +nand-controller@1ac00000 { + compatible = "qcom,ipq806x-nand"; reg = <0x1ac00000 0x800>; clocks = <&gcc EBI2_CLK>, @@ -59,8 +73,7 @@ nand@1ac00000 { #address-cells = <1>; #size-cells = <0>; - nandcs@0 { - compatible = "qcom,nandcs"; + nand@0 { reg = <0>; nand-ecc-strength = <4>; @@ -84,3 +97,43 @@ nand@1ac00000 { }; }; }; + +nand-controller@79b0000 { + compatible = "qcom,ipq4019-nand"; + reg = <0x79b0000 0x1000>; + + clocks = <&gcc GCC_QPIC_CLK>, + <&gcc GCC_QPIC_AHB_CLK>; + clock-names = "core", "aon"; + + dmas = <&qpicbam 0>, + <&qpicbam 1>, + <&qpicbam 2>; + dma-names = "tx", "rx", "cmd"; + + #address-cells = <1>; + #size-cells = <0>; + + nand@0 { + reg = <0>; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot-nand"; + reg = <0 0x58a0000>; + }; + + partition@58a0000 { + label = "fs-nand"; + reg = <0x58a0000 0x4000000>; + }; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/mtd/st-fsm.txt b/Documentation/devicetree/bindings/mtd/st-fsm.txt index c2489391c437..54cef9ef3083 100644 --- a/Documentation/devicetree/bindings/mtd/st-fsm.txt +++ b/Documentation/devicetree/bindings/mtd/st-fsm.txt @@ -21,6 +21,5 @@ Example: st,syscfg = <&syscfg_rear>; st,boot-device-reg = <0x958>; st,boot-device-spi = <0x1a>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt index f322f56aef74..a37c67bcb43b 100644 --- a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt @@ -41,7 +41,6 @@ nfc: nand@01c03000 { #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>; - status = "okay"; nand@0 { reg = <0>; diff --git a/Documentation/devicetree/bindings/net/anarion-gmac.txt b/Documentation/devicetree/bindings/net/anarion-gmac.txt new file mode 100644 index 000000000000..fe678965ae69 --- /dev/null +++ b/Documentation/devicetree/bindings/net/anarion-gmac.txt @@ -0,0 +1,25 @@ +* Adaptrum Anarion ethernet controller + +This device is a platform glue layer for stmmac. +Please see stmmac.txt for the other unchanged properties. + +Required properties: + - compatible: Should be "adaptrum,anarion-gmac", "snps,dwmac" + - phy-mode: Should be "rgmii". Other modes are not currently supported. + + +Examples: + + gmac1: ethernet@f2014000 { + compatible = "adaptrum,anarion-gmac", "snps,dwmac"; + reg = <0xf2014000 0x4000>, <0xf2018100 8>; + + interrupt-parent = <&core_intc>; + interrupts = <21>; + interrupt-names = "macirq"; + + clocks = <&core_clk>; + clock-names = "stmmaceth"; + + phy-mode = "rgmii"; + }; diff --git a/Documentation/devicetree/bindings/net/brcm,amac.txt b/Documentation/devicetree/bindings/net/brcm,amac.txt index ad16c1f481f7..0bfad656a9ff 100644 --- a/Documentation/devicetree/bindings/net/brcm,amac.txt +++ b/Documentation/devicetree/bindings/net/brcm,amac.txt @@ -27,5 +27,4 @@ amac0: ethernet@18022000 { <0x18110000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt new file mode 100644 index 000000000000..4194ff7e6ee6 --- /dev/null +++ b/Documentation/devicetree/bindings/net/broadcom-bluetooth.txt @@ -0,0 +1,35 @@ +Broadcom Bluetooth Chips +--------------------- + +This documents the binding structure and common properties for serial +attached Broadcom devices. + +Serial attached Broadcom devices shall be a child node of the host UART +device the slave device is attached to. + +Required properties: + + - compatible: should contain one of the following: + * "brcm,bcm43438-bt" + +Optional properties: + + - max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt + - shutdown-gpios: GPIO specifier, used to enable the BT module + - device-wakeup-gpios: GPIO specifier, used to wakeup the controller + - host-wakeup-gpios: GPIO specifier, used to wakeup the host processor + - clocks: clock specifier if external clock provided to the controller + - clock-names: should be "extclk" + + +Example: + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + + bluetooth { + compatible = "brcm,bcm43438-bt"; + max-speed = <921600>; + }; +}; diff --git a/Documentation/devicetree/bindings/net/btusb.txt b/Documentation/devicetree/bindings/net/btusb.txt index 01fa2d4188d4..9c5e663fa1af 100644 --- a/Documentation/devicetree/bindings/net/btusb.txt +++ b/Documentation/devicetree/bindings/net/btusb.txt @@ -29,7 +29,6 @@ Example: Following example uses irq pin number 3 of gpio0 for out of band wake-on-bt: &usb_host1_ehci { - status = "okay"; #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt index 5a1d8b0c39e9..2d504256b0d8 100644 --- a/Documentation/devicetree/bindings/net/can/c_can.txt +++ b/Documentation/devicetree/bindings/net/can/c_can.txt @@ -11,9 +11,20 @@ Required properties: - interrupts : property with a value describing the interrupt number -Optional properties: +The following are mandatory properties for DRA7x, AM33xx and AM43xx SoCs only: - ti,hwmods : Must be "d_can" or "c_can", n being the instance number + +The following are mandatory properties for Keystone 2 66AK2G SoCs only: +- power-domains : Should contain a phandle to a PM domain provider node + and an args specifier containing the DCAN device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt +- clocks : CAN functional clock phandle. This property is as per the + binding, + Documentation/devicetree/bindings/clock/ti,sci-clk.txt + +Optional properties: - syscon-raminit : Handle to system control region that contains the RAMINIT register, register offset to the RAMINIT register and the CAN instance number (0 offset). diff --git a/Documentation/devicetree/bindings/net/can/m_can.txt b/Documentation/devicetree/bindings/net/can/m_can.txt index 9e331777c203..78138333ff7a 100644 --- a/Documentation/devicetree/bindings/net/can/m_can.txt +++ b/Documentation/devicetree/bindings/net/can/m_can.txt @@ -56,7 +56,6 @@ m_can1: can@020e8000 { <&clks IMX6SX_CLK_CANFD>; clock-names = "hclk", "cclk"; bosch,mram-cfg = <0x0 0 0 32 0 0 0 1>; - status = "disabled"; }; Board dts: diff --git a/Documentation/devicetree/bindings/net/dsa/ksz.txt b/Documentation/devicetree/bindings/net/dsa/ksz.txt index 0ab8b39d0b30..fd23904ac68e 100644 --- a/Documentation/devicetree/bindings/net/dsa/ksz.txt +++ b/Documentation/devicetree/bindings/net/dsa/ksz.txt @@ -24,7 +24,6 @@ Ethernet switch connected via SPI to the host, CPU port wired to eth0: pinctrl-0 = <&pinctrl_spi_ksz>; cs-gpios = <&pioC 25 0>; id = <1>; - status = "okay"; ksz9477: ksz9477@0 { compatible = "microchip,ksz9477"; @@ -34,7 +33,6 @@ Ethernet switch connected via SPI to the host, CPU port wired to eth0: spi-cpha; spi-cpol; - status = "okay"; ports { #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/net/dsa/lan9303.txt b/Documentation/devicetree/bindings/net/dsa/lan9303.txt index 04f2965a4467..4448d063ddf6 100644 --- a/Documentation/devicetree/bindings/net/dsa/lan9303.txt +++ b/Documentation/devicetree/bindings/net/dsa/lan9303.txt @@ -27,7 +27,6 @@ Example: I2C managed mode: master: masterdevice@X { - status = "okay"; fixed-link { /* RMII fixed link to LAN9303 */ speed = <100>; @@ -38,7 +37,6 @@ I2C managed mode: switch: switch@a { compatible = "smsc,lan9303-i2c"; reg = <0xa>; - status = "okay"; reset-gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; reset-duration = <200>; @@ -67,7 +65,6 @@ I2C managed mode: MDIO managed mode: master: masterdevice@X { - status = "okay"; phy-handle = <&switch>; mdio { diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt index 7da86f22a13b..2974e63ba311 100644 --- a/Documentation/devicetree/bindings/net/ethernet.txt +++ b/Documentation/devicetree/bindings/net/ethernet.txt @@ -1,5 +1,9 @@ The following properties are common to the Ethernet controllers: +NOTE: All 'phy*' properties documented below are Ethernet specific. For the +generic PHY 'phys' property, see +Documentation/devicetree/bindings/phy/phy-bindings.txt. + - local-mac-address: array of 6 bytes, specifies the MAC address that was assigned to the network device; - mac-address: array of 6 bytes, specifies the MAC address that was last used by diff --git a/Documentation/devicetree/bindings/net/ftgmac100.txt b/Documentation/devicetree/bindings/net/ftgmac100.txt index c1ce1680246f..72e7aaf7242e 100644 --- a/Documentation/devicetree/bindings/net/ftgmac100.txt +++ b/Documentation/devicetree/bindings/net/ftgmac100.txt @@ -30,6 +30,5 @@ Example: compatible = "aspeed,ast2500-mac", "faraday,ftgmac100"; reg = <0x1e660000 0x180>; interrupts = <2>; - status = "okay"; use-ncsi; }; diff --git a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt index ae4234ca4ee4..bedcfd5a52cd 100644 --- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt +++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt @@ -41,7 +41,6 @@ ethernet@70000 { interrupts = <8>; clocks = <&gate_clk 4>; tx-csum-limit = <9800> - status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; buffer-manager = <&bm>; diff --git a/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt index 9be1059ff03f..3d27c68613a6 100644 --- a/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt +++ b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt @@ -44,7 +44,6 @@ Example for SDIO device follows (calibration data is also available in below example). &mmc3 { - status = "okay"; vmmc-supply = <&wlan_en_reg>; bus-width = <4>; cap-power-off-card; @@ -70,7 +69,6 @@ below example). Example for USB device: &usb_host1_ohci { - status = "okay"; #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/net/marvell-neta-bm.txt b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt index c1b1d7c3bde1..07b31050dbe5 100644 --- a/Documentation/devicetree/bindings/net/marvell-neta-bm.txt +++ b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt @@ -31,7 +31,6 @@ bm: bm@c8000 { reg = <0xc8000 0xac>; clocks = <&gateclk 13>; internal-mem = <&bm_bppi>; - status = "okay"; pool2,capacity = <4096>; pool1,pkt-size = <512>; }; @@ -45,5 +44,4 @@ bm_bppi: bm-bppi { #address-cells = <1>; #size-cells = <1>; clocks = <&gateclk 13>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/net/marvell-pp2.txt b/Documentation/devicetree/bindings/net/marvell-pp2.txt index 6b4956beff8c..1814fa13f6ab 100644 --- a/Documentation/devicetree/bindings/net/marvell-pp2.txt +++ b/Documentation/devicetree/bindings/net/marvell-pp2.txt @@ -21,8 +21,9 @@ Required properties: - main controller clock (for both armada-375-pp2 and armada-7k-pp2) - GOP clock (for both armada-375-pp2 and armada-7k-pp2) - MG clock (only for armada-7k-pp2) -- clock-names: names of used clocks, must be "pp_clk", "gop_clk" and - "mg_clk" (the latter only for armada-7k-pp2). + - AXI clock (only for armada-7k-pp2) +- clock-names: names of used clocks, must be "pp_clk", "gop_clk", "mg_clk" + and "axi_clk" (the 2 latter only for armada-7k-pp2). The ethernet ports are represented by subnodes. At least one port is required. @@ -41,6 +42,11 @@ Optional properties (port): - marvell,loopback: port is loopback mode - phy: a phandle to a phy node defining the PHY address (as the reg property, a single integer). +- interrupt-names: if more than a single interrupt for rx is given, must + be the name associated to the interrupts listed. Valid + names are: "tx-cpu0", "tx-cpu1", "tx-cpu2", "tx-cpu3", + "rx-shared", "link". +- marvell,system-controller: a phandle to the system controller. Example for marvell,armada-375-pp2: @@ -52,12 +58,10 @@ ethernet@f0000 { <0xc5000 0x100>; clocks = <&gateclk 3>, <&gateclk 19>; clock-names = "pp_clk", "gop_clk"; - status = "okay"; eth0: eth0@c4000 { interrupts = ; port-id = <0>; - status = "okay"; phy = <&phy0>; phy-mode = "gmii"; }; @@ -65,7 +69,6 @@ ethernet@f0000 { eth1: eth1@c5000 { interrupts = ; port-id = <1>; - status = "okay"; phy = <&phy3>; phy-mode = "gmii"; }; @@ -76,23 +79,42 @@ Example for marvell,armada-7k-pp2: cpm_ethernet: ethernet@0 { compatible = "marvell,armada-7k-pp22"; reg = <0x0 0x100000>, <0x129000 0xb000>; - clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, <&cpm_syscon0 1 5>; - clock-names = "pp_clk", "gop_clk", "gp_clk"; + clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, + <&cpm_syscon0 1 5>, <&cpm_syscon0 1 18>; + clock-names = "pp_clk", "gop_clk", "gp_clk", "axi_clk"; eth0: eth0 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <0>; gop-port-id = <0>; }; eth1: eth1 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <1>; gop-port-id = <2>; }; eth2: eth2 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <2>; gop-port-id = <3>; }; diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt index c7194e87d5f4..214eaa9a6683 100644 --- a/Documentation/devicetree/bindings/net/mediatek-net.txt +++ b/Documentation/devicetree/bindings/net/mediatek-net.txt @@ -7,24 +7,32 @@ have dual GMAC each represented by a child node.. * Ethernet controller node Required properties: -- compatible: Should be "mediatek,mt2701-eth" +- compatible: Should be + "mediatek,mt2701-eth": for MT2701 SoC + "mediatek,mt7623-eth", "mediatek,mt2701-eth": for MT7623 SoC + "mediatek,mt7622-eth": for MT7622 SoC - reg: Address and length of the register set for the device - interrupts: Should contain the three frame engines interrupts in numeric order. These are fe_int0, fe_int1 and fe_int2. - clocks: the clock used by the core - clock-names: the names of the clock listed in the clocks property. These are - "ethif", "esw", "gp2", "gp1" + "ethif", "esw", "gp2", "gp1" : For MT2701 and MT7623 SoC + "ethif", "esw", "gp0", "gp1", "gp2", "sgmii_tx250m", "sgmii_rx250m", + "sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck", "eth2pll" : For MT7622 SoC - power-domains: phandle to the power domain that the ethernet is part of -- resets: Should contain a phandle to the ethsys reset signal -- reset-names: Should contain the reset signal name "eth" +- resets: Should contain phandles to the ethsys reset signals +- reset-names: Should contain the names of reset signal listed in the resets + property + These are "fe", "gmac" and "ppe" - mediatek,ethsys: phandle to the syscon node that handles the port setup +- mediatek,sgmiisys: phandle to the syscon node that handles the SGMII setup + which is required for those SoCs equipped with SGMII such as MT7622 SoC. - mediatek,pctl: phandle to the syscon node that handles the ports slew rate and driver current Optional properties: - interrupt-parent: Should be the phandle for the interrupt controller that services interrupts for this device - * Ethernet MAC node Required properties: diff --git a/Documentation/devicetree/bindings/net/meson-dwmac.txt b/Documentation/devicetree/bindings/net/meson-dwmac.txt index 0703ad3f3c1e..354dd9896bb5 100644 --- a/Documentation/devicetree/bindings/net/meson-dwmac.txt +++ b/Documentation/devicetree/bindings/net/meson-dwmac.txt @@ -66,5 +66,4 @@ Example for GXBB: <&clkc CLKID_MPLL2>; clock-names = "stmmaceth", "clkin0", "clkin1"; phy-mode = "rgmii"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt index c35b5b428a7f..42a248301615 100644 --- a/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt +++ b/Documentation/devicetree/bindings/net/micrel-ksz90x1.txt @@ -69,7 +69,6 @@ Examples: }; }; ethernet@70000 { - status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; }; diff --git a/Documentation/devicetree/bindings/net/microchip,enc28j60.txt b/Documentation/devicetree/bindings/net/microchip,enc28j60.txt index 1dc3bc75539d..44dff53d4dda 100644 --- a/Documentation/devicetree/bindings/net/microchip,enc28j60.txt +++ b/Documentation/devicetree/bindings/net/microchip,enc28j60.txt @@ -33,7 +33,6 @@ Example (for NXP i.MX28 with pin control stuff for GPIO irq): compatible = "fsl,imx28-spi"; pinctrl-names = "default"; pinctrl-0 = <&spi2_pins_b &spi2_sck_cfg>; - status = "okay"; enc28j60: ethernet@0 { compatible = "microchip,enc28j60"; diff --git a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt index 76df9173825a..c9b35251bb20 100644 --- a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt +++ b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt @@ -25,7 +25,6 @@ Optional I2C-based chip specific properties: Example (for ARM-based BeagleBoard Black with 88W8887 on UART5): &uart5 { - status = "okay"; nfcmrvluart: nfcmrvluart@5 { compatible = "marvell,nfc-uart"; @@ -41,7 +40,6 @@ Example (for ARM-based BeagleBoard Black with 88W8887 on UART5): Example (for ARM-based BeagleBoard Black with 88W8887 on I2C1): &i2c1 { - status = "okay"; clock-frequency = <400000>; nfcmrvli2c0: i2c@1 { diff --git a/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt b/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt index 5b6cd9b3f628..92486733df71 100644 --- a/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt +++ b/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt @@ -17,7 +17,6 @@ Example (for ARM-based BeagleBone with NPC100 NFC controller on I2C2): &i2c2 { - status = "okay"; npc100: npc100@29 { diff --git a/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt index 1aea822d4530..122460e42e3c 100644 --- a/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt +++ b/Documentation/devicetree/bindings/net/nfc/pn533-i2c.txt @@ -15,7 +15,6 @@ Example (for ARM-based BeagleBone with PN532 on I2C2): &i2c2 { - status = "okay"; pn532: pn532@24 { diff --git a/Documentation/devicetree/bindings/net/nfc/pn544.txt b/Documentation/devicetree/bindings/net/nfc/pn544.txt index dab69f36167c..538a86f7b2b0 100644 --- a/Documentation/devicetree/bindings/net/nfc/pn544.txt +++ b/Documentation/devicetree/bindings/net/nfc/pn544.txt @@ -17,7 +17,6 @@ Example (for ARM-based BeagleBone with PN544 on I2C2): &i2c2 { - status = "okay"; pn544: pn544@28 { diff --git a/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt b/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt index fb1e75facf1b..ed5b3eaadb39 100644 --- a/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt +++ b/Documentation/devicetree/bindings/net/nfc/s3fwrn5.txt @@ -12,7 +12,6 @@ Required properties: Example: &hsi2c_4 { - status = "okay"; s3fwrn5@27 { compatible = "samsung,s3fwrn5-i2c"; diff --git a/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt b/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt index 263732e8879f..b46d473be425 100644 --- a/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt +++ b/Documentation/devicetree/bindings/net/nfc/st-nci-i2c.txt @@ -20,7 +20,6 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on I2C2): &i2c2 { - status = "okay"; st21nfcb: st21nfcb@8 { diff --git a/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt b/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt index 711ca85a363d..54ce8e7ac681 100644 --- a/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt +++ b/Documentation/devicetree/bindings/net/nfc/st-nci-spi.txt @@ -19,7 +19,6 @@ Example (for ARM-based BeagleBoard xM with ST21NFCB on SPI4): &mcspi4 { - status = "okay"; st21nfcb: st21nfcb@0 { diff --git a/Documentation/devicetree/bindings/net/nfc/st21nfca.txt b/Documentation/devicetree/bindings/net/nfc/st21nfca.txt index 7bb2e213d6f9..5ee9440fa9ad 100644 --- a/Documentation/devicetree/bindings/net/nfc/st21nfca.txt +++ b/Documentation/devicetree/bindings/net/nfc/st21nfca.txt @@ -20,7 +20,6 @@ Example (for ARM-based BeagleBoard xM with ST21NFCA on I2C2): &i2c2 { - status = "okay"; st21nfca: st21nfca@1 { diff --git a/Documentation/devicetree/bindings/net/nfc/st95hf.txt b/Documentation/devicetree/bindings/net/nfc/st95hf.txt index ea3178bc9ddd..08a202e00d47 100644 --- a/Documentation/devicetree/bindings/net/nfc/st95hf.txt +++ b/Documentation/devicetree/bindings/net/nfc/st95hf.txt @@ -35,12 +35,10 @@ spi@9840000 { #address-cells = <1>; #size-cells = <0>; cs-gpios = <&pio0 4>; - status = "okay"; st95hf@0{ reg = <0>; compatible = "st,st95hf"; - status = "okay"; spi-max-frequency = <1000000>; enable-gpio = <&pio4 0>; interrupt-parent = <&pio0>; diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt index 60c833d62181..5ca9362ef127 100644 --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt @@ -23,7 +23,6 @@ Optional SoC Specific Properties: Example (for ARM-based BeagleBone with TRF7970A on SPI1): &spi1 { - status = "okay"; nfc@0 { compatible = "ti,trf7970a"; @@ -41,6 +40,5 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1): irq-status-read-quirk; en2-rf-quirk; clock-frequency = <27120000>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt index df0534e2eda1..d7117a22fd87 100644 --- a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt +++ b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt @@ -35,5 +35,4 @@ etha: ethernet@40400000 { /* Regmap for sys registers */ oxsemi,sys-ctrl = <&sys>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt index b55857696fc3..77d0b2a61ffa 100644 --- a/Documentation/devicetree/bindings/net/phy.txt +++ b/Documentation/devicetree/bindings/net/phy.txt @@ -2,11 +2,7 @@ PHY nodes Required properties: - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. + - interrupts : interrupt specifier for the sole interrupt. - interrupt-parent : the phandle for the interrupt controller that services interrupts for this device. - reg : The ID number for the phy, usually a small integer @@ -52,11 +48,16 @@ Optional Properties: Mark the corresponding energy efficient ethernet mode as broken and request the ethernet to stop advertising it. +- phy-is-integrated: If set, indicates that the PHY is integrated into the same + physical package as the Ethernet MAC. If needed, muxers should be configured + to ensure the integrated PHY is used. The absence of this property indicates + the muxers should be configured so that the external PHY is used. + Example: ethernet-phy@0 { compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22"; - interrupt-parent = <40000>; - interrupts = <35 1>; + interrupt-parent = <&PIC>; + interrupts = <35 IRQ_TYPE_EDGE_RISING>; reg = <0>; }; diff --git a/Documentation/devicetree/bindings/net/qca,qca7000.txt b/Documentation/devicetree/bindings/net/qca,qca7000.txt index 6d9efb2eb9a5..3987846b3fd3 100644 --- a/Documentation/devicetree/bindings/net/qca,qca7000.txt +++ b/Documentation/devicetree/bindings/net/qca,qca7000.txt @@ -41,7 +41,6 @@ ssp2: spi@80014000 { compatible = "fsl,imx28-spi"; pinctrl-names = "default"; pinctrl-0 = <&spi2_pins_a>; - status = "okay"; qca7000: ethernet@0 { compatible = "qca,qca7000"; @@ -78,7 +77,6 @@ auart0: serial@8006a000 { reg = <0x8006a000 0x2000>; pinctrl-names = "default"; pinctrl-0 = <&auart0_2pins_a>; - status = "okay"; qca7000: ethernet { compatible = "qca,qca7000"; diff --git a/Documentation/devicetree/bindings/net/renesas,ravb.txt b/Documentation/devicetree/bindings/net/renesas,ravb.txt index b519503be51a..16723535e1aa 100644 --- a/Documentation/devicetree/bindings/net/renesas,ravb.txt +++ b/Documentation/devicetree/bindings/net/renesas,ravb.txt @@ -4,19 +4,25 @@ This file provides information on what the device node for the Ethernet AVB interface contains. Required properties: -- compatible: "renesas,etheravb-r8a7790" if the device is a part of R8A7790 SoC. - "renesas,etheravb-r8a7791" if the device is a part of R8A7791 SoC. - "renesas,etheravb-r8a7792" if the device is a part of R8A7792 SoC. - "renesas,etheravb-r8a7793" if the device is a part of R8A7793 SoC. - "renesas,etheravb-r8a7794" if the device is a part of R8A7794 SoC. - "renesas,etheravb-r8a7795" if the device is a part of R8A7795 SoC. - "renesas,etheravb-r8a7796" if the device is a part of R8A7796 SoC. - "renesas,etheravb-rcar-gen2" for generic R-Car Gen 2 compatible interface. - "renesas,etheravb-rcar-gen3" for generic R-Car Gen 3 compatible interface. +- compatible: Must contain one or more of the following: + - "renesas,etheravb-r8a7743" for the R8A7743 SoC. + - "renesas,etheravb-r8a7745" for the R8A7745 SoC. + - "renesas,etheravb-r8a7790" for the R8A7790 SoC. + - "renesas,etheravb-r8a7791" for the R8A7791 SoC. + - "renesas,etheravb-r8a7792" for the R8A7792 SoC. + - "renesas,etheravb-r8a7793" for the R8A7793 SoC. + - "renesas,etheravb-r8a7794" for the R8A7794 SoC. + - "renesas,etheravb-rcar-gen2" as a fallback for the above + R-Car Gen2 and RZ/G1 devices. - When compatible with the generic version, nodes must list the - SoC-specific version corresponding to the platform first - followed by the generic version. + - "renesas,etheravb-r8a7795" for the R8A7795 SoC. + - "renesas,etheravb-r8a7796" for the R8A7796 SoC. + - "renesas,etheravb-rcar-gen3" as a fallback for the above + R-Car Gen3 devices. + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first followed by + the generic version. - reg: offset and length of (1) the register block and (2) the stream buffer. - interrupts: A list of interrupt-specifiers, one for each entry in diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt index 8f427550720a..9c16ee2965a2 100644 --- a/Documentation/devicetree/bindings/net/rockchip-dwmac.txt +++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.txt @@ -4,12 +4,14 @@ The device node has following properties. Required properties: - compatible: should be "rockchip,-gamc" + "rockchip,rk3128-gmac": found on RK312x SoCs "rockchip,rk3228-gmac": found on RK322x SoCs "rockchip,rk3288-gmac": found on RK3288 SoCs "rockchip,rk3328-gmac": found on RK3328 SoCs "rockchip,rk3366-gmac": found on RK3366 SoCs "rockchip,rk3368-gmac": found on RK3368 SoCs "rockchip,rk3399-gmac": found on RK3399 SoCs + "rockchip,rv1108-gmac": found on RV1108 SoCs - reg: addresses and length of the register sets for the device. - interrupts: Should contain the GMAC interrupts. - interrupt-names: Should contain the interrupt names "macirq". @@ -70,5 +72,4 @@ gmac: ethernet@ff290000 { tx_delay = <0x30>; rx_delay = <0x10>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/net/sff,sfp.txt b/Documentation/devicetree/bindings/net/sff,sfp.txt new file mode 100644 index 000000000000..60e970ce10ee --- /dev/null +++ b/Documentation/devicetree/bindings/net/sff,sfp.txt @@ -0,0 +1,76 @@ +Small Form Factor (SFF) Committee Small Form-factor Pluggable (SFP) +Transceiver + +Required properties: + +- compatible : must be "sff,sfp" + +Optional Properties: + +- i2c-bus : phandle of an I2C bus controller for the SFP two wire serial + interface + +- mod-def0-gpios : GPIO phandle and a specifier of the MOD-DEF0 (AKA Mod_ABS) + module presence input gpio signal, active (module absent) high + +- los-gpios : GPIO phandle and a specifier of the Receiver Loss of Signal + Indication input gpio signal, active (signal lost) high + +- tx-fault-gpios : GPIO phandle and a specifier of the Module Transmitter + Fault input gpio signal, active (fault condition) high + +- tx-disable-gpios : GPIO phandle and a specifier of the Transmitter Disable + output gpio signal, active (Tx disable) high + +- rate-select0-gpios : GPIO phandle and a specifier of the Rx Signaling Rate + Select (AKA RS0) output gpio signal, low: low Rx rate, high: high Rx rate + +- rate-select1-gpios : GPIO phandle and a specifier of the Tx Signaling Rate + Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high: + high Tx rate + +Example #1: Direct serdes to SFP connection + +sfp_eth3: sfp-eth3 { + compatible = "sff,sfp"; + i2c-bus = <&sfp_1g_i2c>; + los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>; + tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&cpm_gpio2 19 GPIO_ACTIVE_HIGH>; +}; + +&cps_emac3 { + phy-names = "comphy"; + phys = <&cps_comphy5 0>; + sfp = <&sfp_eth3>; +}; + +Example #2: Serdes to PHY to SFP connection + +sfp_eth0: sfp-eth0 { + compatible = "sff,sfp"; + i2c-bus = <&sfpp0_i2c>; + los-gpios = <&cps_gpio1 28 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&cps_gpio1 27 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&cps_sfpp0_pins>; + tx-disable-gpios = <&cps_gpio1 29 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&cps_gpio1 26 GPIO_ACTIVE_HIGH>; +}; + +p0_phy: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_phy0_pins &cps_phy0_pins>; + reg = <0>; + interrupt = <&cpm_gpio2 18 IRQ_TYPE_EDGE_FALLING>; + sfp = <&sfp_eth0>; +}; + +&cpm_eth0 { + phy = <&p0_phy>; + phy-mode = "10gbase-kr"; +}; diff --git a/Documentation/devicetree/bindings/net/smsc-lan87xx.txt b/Documentation/devicetree/bindings/net/smsc-lan87xx.txt index 974edd5c85cc..8b7c719b0bb9 100644 --- a/Documentation/devicetree/bindings/net/smsc-lan87xx.txt +++ b/Documentation/devicetree/bindings/net/smsc-lan87xx.txt @@ -15,7 +15,6 @@ smsc phy with disabled energy detect mode on an am335x based board. pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; - status = "okay"; ethernetphy0: ethernet-phy@0 { reg = <0>; diff --git a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt index 2e68a3cd8513..b30d04b54ee9 100644 --- a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt +++ b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt @@ -40,7 +40,6 @@ gmii_to_sgmii_converter: phy@0x100000240 { gmac0: ethernet@ff700000 { compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; altr,sysmgr-syscon = <&sysmgr 0x60 0>; - status = "disabled"; reg = <0xff700000 0x2000>; interrupts = <0 115 4>; interrupt-names = "macirq"; diff --git a/Documentation/devicetree/bindings/net/sti-dwmac.txt b/Documentation/devicetree/bindings/net/sti-dwmac.txt index d05c1e1fd9b6..062c5174add3 100644 --- a/Documentation/devicetree/bindings/net/sti-dwmac.txt +++ b/Documentation/devicetree/bindings/net/sti-dwmac.txt @@ -34,7 +34,6 @@ Example: ethernet0: dwmac@9630000 { device_type = "network"; - status = "disabled"; compatible = "st,stih407-dwmac", "snps,dwmac", "snps,dwmac-3.710"; reg = <0x9630000 0x8000>; reg-names = "stmmaceth"; diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt b/Documentation/devicetree/bindings/net/stm32-dwmac.txt index c35afb7e956a..489dbcb66c5a 100644 --- a/Documentation/devicetree/bindings/net/stm32-dwmac.txt +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt @@ -18,7 +18,6 @@ Example: ethernet@40028000 { compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; - status = "disabled"; reg = <0x40028000 0x8000>; reg-names = "stmmaceth"; interrupts = <0 61 0>, <0 62 0>; diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt index 590f622188de..b2bd4704f859 100644 --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm43xx-fmac.txt @@ -29,7 +29,6 @@ mmc3: mmc@01c12000 { vmmc-supply = <®_vmmc3>; bus-width = <4>; non-removable; - status = "okay"; brcmf: wifi@1 { reg = <1>; diff --git a/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt b/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt index 19331bb4ff6e..6830c4786f8a 100644 --- a/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt +++ b/Documentation/devicetree/bindings/net/wireless/esp,esp8089.txt @@ -21,7 +21,6 @@ Example: mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>; non-removable; - status = "okay"; esp8089: sdio_wifi@1 { compatible = "esp,esp8089"; diff --git a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt index 0854451ff91d..59de8646862d 100644 --- a/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt +++ b/Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt @@ -48,7 +48,6 @@ IRQ pin 38 is used as system wakeup source interrupt. wakeup pin 3 is configured so that firmware can wakeup host using this device side pin. &mmc3 { - status = "okay"; vmmc-supply = <&wlan_en_reg>; mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>; diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt b/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt index 7b2cbb14113e..f42f6b0f1bc7 100644 --- a/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt +++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore.txt @@ -31,7 +31,6 @@ clock, new bindings (for parsing the clock nodes) have to be added. Example: &mmc3 { - status = "okay"; vmmc-supply = <&wlan_en_reg>; bus-width = <4>; cap-power-off-card; diff --git a/Documentation/devicetree/bindings/net/xilinx_axienet.txt b/Documentation/devicetree/bindings/net/xilinx_axienet.txt new file mode 100644 index 000000000000..38f9ec076743 --- /dev/null +++ b/Documentation/devicetree/bindings/net/xilinx_axienet.txt @@ -0,0 +1,55 @@ +XILINX AXI ETHERNET Device Tree Bindings +-------------------------------------------------------- + +Also called AXI 1G/2.5G Ethernet Subsystem, the xilinx axi ethernet IP core +provides connectivity to an external ethernet PHY supporting different +interfaces: MII, GMII, RGMII, SGMII, 1000BaseX. It also includes two +segments of memory for buffering TX and RX, as well as the capability of +offloading TX/RX checksum calculation off the processor. + +Management configuration is done through the AXI interface, while payload is +sent and received through means of an AXI DMA controller. This driver +includes the DMA driver code, so this driver is incompatible with AXI DMA +driver. + +For more details about mdio please refer phy.txt file in the same directory. + +Required properties: +- compatible : Must be one of "xlnx,axi-ethernet-1.00.a", + "xlnx,axi-ethernet-1.01.a", "xlnx,axi-ethernet-2.01.a" +- reg : Address and length of the IO space. +- interrupts : Should be a list of two interrupt, TX and RX. +- phy-handle : Should point to the external phy device. + See ethernet.txt file in the same directory. +- xlnx,rxmem : Set to allocated memory buffer for Rx/Tx in the hardware + +Optional properties: +- phy-mode : See ethernet.txt +- xlnx,phy-type : Deprecated, do not use, but still accepted in preference + to phy-mode. +- xlnx,txcsum : 0 or empty for disabling TX checksum offload, + 1 to enable partial TX checksum offload, + 2 to enable full TX checksum offload +- xlnx,rxcsum : Same values as xlnx,txcsum but for RX checksum offload + +Example: + axi_ethernet_eth: ethernet@40c00000 { + compatible = "xlnx,axi-ethernet-1.00.a"; + device_type = "network"; + interrupt-parent = <µblaze_0_axi_intc>; + interrupts = <2 0>; + phy-mode = "mii"; + reg = <0x40c00000 0x40000>; + xlnx,rxcsum = <0x2>; + xlnx,rxmem = <0x800>; + xlnx,txcsum = <0x2>; + phy-handle = <&phy0>; + axi_ethernetlite_0_mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: phy@0 { + device_type = "ethernet-phy"; + reg = <1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt b/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt index 74cf52908a6c..0668c45a156d 100644 --- a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt +++ b/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt @@ -3,7 +3,10 @@ This binding is intended to represent MTK-EFUSE which is found in most Mediatek SOCs. Required properties: -- compatible: should be "mediatek,mt8173-efuse" or "mediatek,efuse" +- compatible: should be + "mediatek,mt7622-efuse", "mediatek,efuse": for MT7622 + "mediatek,mt7623-efuse", "mediatek,efuse": for MT7623 + "mediatek,mt8173-efuse" or "mediatek,efuse": for MT8173 - reg: Should contain registers location and length = Data cells = diff --git a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt index daebce9e6b07..372c72fd64dc 100644 --- a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt +++ b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt @@ -21,5 +21,4 @@ Example for i.MX28: #size-cells = <1>; reg = <0x8002c000 0x2000>; clocks = <&clks 25>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt index e36d261b9ba6..9d733af26be7 100644 --- a/Documentation/devicetree/bindings/opp/opp.txt +++ b/Documentation/devicetree/bindings/opp/opp.txt @@ -464,7 +464,6 @@ Example 5: opp-supported-hw opp_table { compatible = "operating-points-v2"; - status = "okay"; opp-shared; opp-600000000 { diff --git a/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt index 35a465362408..b9165b72473c 100644 --- a/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt +++ b/Documentation/devicetree/bindings/pci/83xx-512x-pci.txt @@ -1,11 +1,11 @@ * Freescale 83xx and 512x PCI bridges -Freescale 83xx and 512x SOCs include the same pci bridge core. +Freescale 83xx and 512x SOCs include the same PCI bridge core. 83xx/512x specific notes: - reg: should contain two address length tuples - The first is for the internal pci bridge registers - The second is for the pci config space access registers + The first is for the internal PCI bridge registers + The second is for the PCI config space access registers Example (MPC8313ERDB) pci0: pci@e0008500 { diff --git a/Documentation/devicetree/bindings/pci/aardvark-pci.txt b/Documentation/devicetree/bindings/pci/aardvark-pci.txt index bbcd9f4c501f..310ef7145c47 100644 --- a/Documentation/devicetree/bindings/pci/aardvark-pci.txt +++ b/Documentation/devicetree/bindings/pci/aardvark-pci.txt @@ -33,7 +33,6 @@ Example: pcie0: pcie@d0070000 { compatible = "marvell,armada-3700-pcie"; device_type = "pci"; - status = "disabled"; reg = <0 0xd0070000 0 0x20000>; #address-cells = <3>; #size-cells = <2>; diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt index 2951a6a50704..495880193adc 100644 --- a/Documentation/devicetree/bindings/pci/altera-pcie.txt +++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt @@ -7,21 +7,21 @@ Required properties: "Txs": TX slave port region "Cra": Control register access region - interrupt-parent: interrupt source phandle. -- interrupts: specifies the interrupt source of the parent interrupt controller. - The format of the interrupt specifier depends on the parent interrupt - controller. +- interrupts: specifies the interrupt source of the parent interrupt + controller. The format of the interrupt specifier depends + on the parent interrupt controller. - device_type: must be "pci" - #address-cells: set to <3> -- #size-cells: set to <2> +- #size-cells: set to <2> - #interrupt-cells: set to <1> -- ranges: describes the translation of addresses for root ports and standard - PCI regions. +- ranges: describes the translation of addresses for root ports and + standard PCI regions. - interrupt-map-mask and interrupt-map: standard PCI properties to define the mapping of the PCIe interface to interrupt numbers. Optional properties: -- msi-parent: Link to the hardware entity that serves as the MSI controller for this PCIe - controller. +- msi-parent: Link to the hardware entity that serves as the MSI controller + for this PCIe controller. - bus-range: PCI bus numbers covered Example @@ -45,5 +45,5 @@ Example <0 0 0 3 &pcie_0 3>, <0 0 0 4 &pcie_0 4>; ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000 - 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>; + 0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>; }; diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt index 5ecaea1e6eee..4e4aee4439ea 100644 --- a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt +++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt @@ -6,7 +6,7 @@ and thus inherits all the common properties defined in designware-pcie.txt. Required properties: - compatible: "axis,artpec6-pcie", "snps,dw-pcie" - reg: base addresses and lengths of the PCIe controller (DBI), - the phy controller, and configuration address space. + the PHY controller, and configuration address space. - reg-names: Must include the following entries: - "dbi" - "phy" diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt index b2480dd38c11..1da7ade3183c 100644 --- a/Documentation/devicetree/bindings/pci/designware-pcie.txt +++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt @@ -1,4 +1,4 @@ -* Synopsys Designware PCIe interface +* Synopsys DesignWare PCIe interface Required properties: - compatible: should contain "snps,dw-pcie" to identify the core. @@ -17,29 +17,27 @@ RC mode: properties to define the mapping of the PCIe interface to interrupt numbers. EP mode: -- num-ib-windows: number of inbound address translation - windows -- num-ob-windows: number of outbound address translation - windows +- num-ib-windows: number of inbound address translation windows +- num-ob-windows: number of outbound address translation windows Optional properties: - num-lanes: number of lanes to use (this property should be specified unless the link is brought already up in BIOS) -- reset-gpio: gpio pin number of power good signal +- reset-gpio: GPIO pin number of power good signal - clocks: Must contain an entry for each entry in clock-names. See ../clocks/clock-bindings.txt for details. - clock-names: Must include the following entries: - "pcie" - "pcie_bus" RC mode: -- num-viewport: number of view ports configured in - hardware. If a platform does not specify it, the driver assumes 2. -- bus-range: PCI bus numbers covered (it is recommended - for new devicetrees to specify this property, to keep backwards - compatibility a range of 0x00-0xff is assumed if not present) +- num-viewport: number of view ports configured in hardware. If a platform + does not specify it, the driver assumes 2. +- bus-range: PCI bus numbers covered (it is recommended for new devicetrees + to specify this property, to keep backwards compatibility a range of + 0x00-0xff is assumed if not present) + EP mode: -- max-functions: maximum number of functions that can be - configured +- max-functions: maximum number of functions that can be configured Example configuration: diff --git a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt index cf92d3ba5a26..7b1e48bf172b 100644 --- a/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt +++ b/Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt @@ -1,6 +1,6 @@ * Freescale i.MX6 PCIe interface -This PCIe host controller is based on the Synopsis Designware PCIe IP +This PCIe host controller is based on the Synopsys DesignWare PCIe IP and thus inherits all the common properties defined in designware-pcie.txt. Required properties: diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt index a339dbb15493..bdb7ab39d2d7 100644 --- a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt +++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt @@ -1,7 +1,7 @@ HiSilicon Hip05 and Hip06 PCIe host bridge DT description -HiSilicon PCIe host controller is based on Designware PCI core. -It shares common functions with PCIe Designware core driver and inherits +HiSilicon PCIe host controller is based on the Synopsys DesignWare PCI core. +It shares common functions with the PCIe DesignWare core driver and inherits common properties defined in Documentation/devicetree/bindings/pci/designware-pci.txt. @@ -40,7 +40,6 @@ Hip05 Example (note that Hip06 is the same except compatible): 0x0 0 0 2 &mbigen_pcie 2 11 0x0 0 0 3 &mbigen_pcie 3 12 0x0 0 0 4 &mbigen_pcie 4 13>; - status = "ok"; }; HiSilicon Hip06/Hip07 PCIe host bridge DT (almost-ECAM) description. @@ -83,5 +82,4 @@ Example: 0x0 0 0 2 &mbigen_pcie0 650 4 0x0 0 0 3 &mbigen_pcie0 650 4 0x0 0 0 4 &mbigen_pcie0 650 4>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/pci/kirin-pcie.txt b/Documentation/devicetree/bindings/pci/kirin-pcie.txt index 68ffa0fbcd73..6e217c63123d 100644 --- a/Documentation/devicetree/bindings/pci/kirin-pcie.txt +++ b/Documentation/devicetree/bindings/pci/kirin-pcie.txt @@ -1,8 +1,8 @@ HiSilicon Kirin SoCs PCIe host DT description -Kirin PCIe host controller is based on Designware PCI core. -It shares common functions with PCIe Designware core driver -and inherits common properties defined in +Kirin PCIe host controller is based on the Synopsys DesignWare PCI core. +It shares common functions with the PCIe DesignWare core driver and +inherits common properties defined in Documentation/devicetree/bindings/pci/designware-pci.txt. Additional properties are described here: @@ -16,7 +16,7 @@ Required properties "apb": apb Ctrl register defined by Kirin; "phy": apb PHY register defined by Kirin; "config": PCIe configuration space registers. -- reset-gpios: The gpio to generate PCIe perst assert and deassert signal. +- reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal. Optional properties: diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index ee1c72d5162e..c0484da0f20d 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -15,8 +15,10 @@ Required properties: - compatible: should contain the platform identifier such as: "fsl,ls1021a-pcie", "snps,dw-pcie" "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie" + "fsl,ls2088a-pcie" + "fsl,ls1088a-pcie" "fsl,ls1046a-pcie" -- reg: base addresses and lengths of the PCIe controller +- reg: base addresses and lengths of the PCIe controller register blocks. - interrupts: A list of interrupt outputs of the controller. Must contain an entry for each entry in the interrupt-names property. - interrupt-names: Must include the following entries: diff --git a/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt deleted file mode 100644 index fe80dda9bf73..000000000000 --- a/Documentation/devicetree/bindings/pci/mediatek,mt7623-pcie.txt +++ /dev/null @@ -1,130 +0,0 @@ -MediaTek Gen2 PCIe controller which is available on MT7623 series SoCs - -PCIe subsys supports single root complex (RC) with 3 Root Ports. Each root -ports supports a Gen2 1-lane Link and has PIPE interface to PHY. - -Required properties: -- compatible: Should contain "mediatek,mt7623-pcie". -- device_type: Must be "pci" -- reg: Base addresses and lengths of the PCIe controller. -- #address-cells: Address representation for root ports (must be 3) -- #size-cells: Size representation for root ports (must be 2) -- #interrupt-cells: Size representation for interrupts (must be 1) -- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties - Please refer to the standard PCI bus binding document for a more detailed - explanation. -- clocks: Must contain an entry for each entry in clock-names. - See ../clocks/clock-bindings.txt for details. -- clock-names: Must include the following entries: - - free_ck :for reference clock of PCIe subsys - - sys_ck0 :for clock of Port0 - - sys_ck1 :for clock of Port1 - - sys_ck2 :for clock of Port2 -- resets: Must contain an entry for each entry in reset-names. - See ../reset/reset.txt for details. -- reset-names: Must include the following entries: - - pcie-rst0 :port0 reset - - pcie-rst1 :port1 reset - - pcie-rst2 :port2 reset -- phys: List of PHY specifiers (used by generic PHY framework). -- phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the - number of PHYs as specified in *phys* property. -- power-domains: A phandle and power domain specifier pair to the power domain - which is responsible for collapsing and restoring power to the peripheral. -- bus-range: Range of bus numbers associated with this controller. -- ranges: Ranges for the PCI memory and I/O regions. - -In addition, the device tree node must have sub-nodes describing each -PCIe port interface, having the following mandatory properties: - -Required properties: -- device_type: Must be "pci" -- reg: Only the first four bytes are used to refer to the correct bus number - and device number. -- #address-cells: Must be 3 -- #size-cells: Must be 2 -- #interrupt-cells: Must be 1 -- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties - Please refer to the standard PCI bus binding document for a more detailed - explanation. -- ranges: Sub-ranges distributed from the PCIe controller node. An empty - property is sufficient. -- num-lanes: Number of lanes to use for this port. - -Examples: - - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", - "syscon"; - reg = <0 0x1a000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - - pcie: pcie-controller@1a140000 { - compatible = "mediatek,mt7623-pcie"; - device_type = "pci"; - reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ - <0 0x1a142000 0 0x1000>, /* Port0 registers */ - <0 0x1a143000 0 0x1000>, /* Port1 registers */ - <0 0x1a144000 0 0x1000>; /* Port2 registers */ - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0xf800 0 0 0>; - interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, - <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, - <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; - clocks = <&topckgen CLK_TOP_ETHIF_SEL>, - <&hifsys CLK_HIFSYS_PCIE0>, - <&hifsys CLK_HIFSYS_PCIE1>, - <&hifsys CLK_HIFSYS_PCIE2>; - clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; - resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, - <&hifsys MT2701_HIFSYS_PCIE1_RST>, - <&hifsys MT2701_HIFSYS_PCIE2_RST>; - reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; - phys = <&pcie0_phy>, <&pcie1_phy>, <&pcie2_phy>; - phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; - power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; - bus-range = <0x00 0xff>; - ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ - 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ - - pcie@0,0 { - device_type = "pci"; - reg = <0x0000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; - ranges; - num-lanes = <1>; - }; - - pcie@1,0 { - device_type = "pci"; - reg = <0x0800 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; - ranges; - num-lanes = <1>; - }; - - pcie@2,0 { - device_type = "pci"; - reg = <0x1000 0 0 0 0>; - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; - ranges; - num-lanes = <1>; - }; - }; diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt new file mode 100644 index 000000000000..3a6ce55dd310 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt @@ -0,0 +1,284 @@ +MediaTek Gen2 PCIe controller + +Required properties: +- compatible: Should contain one of the following strings: + "mediatek,mt2701-pcie" + "mediatek,mt2712-pcie" + "mediatek,mt7622-pcie" + "mediatek,mt7623-pcie" +- device_type: Must be "pci" +- reg: Base addresses and lengths of the PCIe subsys and root ports. +- reg-names: Names of the above areas to use during resource lookup. +- #address-cells: Address representation for root ports (must be 3) +- #size-cells: Size representation for root ports (must be 2) +- clocks: Must contain an entry for each entry in clock-names. + See ../clocks/clock-bindings.txt for details. +- clock-names: + Mandatory entries: + - sys_ckN :transaction layer and data link layer clock + Required entries for MT2701/MT7623: + - free_ck :for reference clock of PCIe subsys + Required entries for MT2712/MT7622: + - ahb_ckN :AHB slave interface operating clock for CSR access and RC + initiated MMIO access + Required entries for MT7622: + - axi_ckN :application layer MMIO channel operating clock + - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when + pcie_mac_ck/pcie_pipe_ck is turned off + - obff_ckN :OBFF functional block operating clock + - pipe_ckN :LTSSM and PHY/MAC layer operating clock + where N starting from 0 to one less than the number of root ports. +- phys: List of PHY specifiers (used by generic PHY framework). +- phy-names : Must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the + number of PHYs as specified in *phys* property. +- power-domains: A phandle and power domain specifier pair to the power domain + which is responsible for collapsing and restoring power to the peripheral. +- bus-range: Range of bus numbers associated with this controller. +- ranges: Ranges for the PCI memory and I/O regions. + +Required properties for MT7623/MT2701: +- #interrupt-cells: Size representation for interrupts (must be 1) +- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties + Please refer to the standard PCI bus binding document for a more detailed + explanation. +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the + number of root ports. + +Required properties for MT2712/MT7622: +-interrupts: A list of interrupt outputs of the controller, must have one + entry for each PCIe port + +In addition, the device tree node must have sub-nodes describing each +PCIe port interface, having the following mandatory properties: + +Required properties: +- device_type: Must be "pci" +- reg: Only the first four bytes are used to refer to the correct bus number + and device number. +- #address-cells: Must be 3 +- #size-cells: Must be 2 +- #interrupt-cells: Must be 1 +- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties + Please refer to the standard PCI bus binding document for a more detailed + explanation. +- ranges: Sub-ranges distributed from the PCIe controller node. An empty + property is sufficient. +- num-lanes: Number of lanes to use for this port. + +Examples for MT7623: + + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", + "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + pcie: pcie-controller@1a140000 { + compatible = "mediatek,mt7623-pcie"; + device_type = "pci"; + reg = <0 0x1a140000 0 0x1000>, /* PCIe shared registers */ + <0 0x1a142000 0 0x1000>, /* Port0 registers */ + <0 0x1a143000 0 0x1000>, /* Port1 registers */ + <0 0x1a144000 0 0x1000>; /* Port2 registers */ + reg-names = "subsys", "port0", "port1", "port2"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 0>; + interrupt-map = <0x0000 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>, + <0x0800 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>, + <0x1000 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <&hifsys CLK_HIFSYS_PCIE0>, + <&hifsys CLK_HIFSYS_PCIE1>, + <&hifsys CLK_HIFSYS_PCIE2>; + clock-names = "free_ck", "sys_ck0", "sys_ck1", "sys_ck2"; + resets = <&hifsys MT2701_HIFSYS_PCIE0_RST>, + <&hifsys MT2701_HIFSYS_PCIE1_RST>, + <&hifsys MT2701_HIFSYS_PCIE2_RST>; + reset-names = "pcie-rst0", "pcie-rst1", "pcie-rst2"; + phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>, + <&pcie2_phy PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1", "pcie-phy2"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + bus-range = <0x00 0xff>; + ranges = <0x81000000 0 0x1a160000 0 0x1a160000 0 0x00010000 /* I/O space */ + 0x83000000 0 0x60000000 0 0x60000000 0 0x10000000>; /* memory space */ + + pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 193 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + + pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 194 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + + pcie@2,0 { + device_type = "pci"; + reg = <0x1000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &sysirq GIC_SPI 195 IRQ_TYPE_LEVEL_LOW>; + ranges; + num-lanes = <1>; + }; + }; + +Examples for MT2712: + pcie: pcie@11700000 { + compatible = "mediatek,mt2712-pcie"; + device_type = "pci"; + reg = <0 0x11700000 0 0x1000>, + <0 0x112ff000 0 0x1000>; + reg-names = "port0", "port1"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = , + ; + clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, + <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, + <&pericfg CLK_PERI_PCIE0>, + <&pericfg CLK_PERI_PCIE1>; + clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; + phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1"; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; + + pcie0: pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie1: pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; + +Examples for MT7622: + pcie: pcie@1a140000 { + compatible = "mediatek,mt7622-pcie"; + device_type = "pci"; + reg = <0 0x1a140000 0 0x1000>, + <0 0x1a143000 0 0x1000>, + <0 0x1a145000 0 0x1000>; + reg-names = "subsys", "port0", "port1"; + #address-cells = <3>; + #size-cells = <2>; + interrupts = , + ; + clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, + <&pciesys CLK_PCIE_P1_MAC_EN>, + <&pciesys CLK_PCIE_P0_AHB_EN>, + <&pciesys CLK_PCIE_P1_AHB_EN>, + <&pciesys CLK_PCIE_P0_AUX_EN>, + <&pciesys CLK_PCIE_P1_AUX_EN>, + <&pciesys CLK_PCIE_P0_AXI_EN>, + <&pciesys CLK_PCIE_P1_AXI_EN>, + <&pciesys CLK_PCIE_P0_OBFF_EN>, + <&pciesys CLK_PCIE_P1_OBFF_EN>, + <&pciesys CLK_PCIE_P0_PIPE_EN>, + <&pciesys CLK_PCIE_P1_PIPE_EN>; + clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", + "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", + "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; + phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; + phy-names = "pcie-phy0", "pcie-phy1"; + power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; + bus-range = <0x00 0xff>; + ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; + + pcie0: pcie@0,0 { + device_type = "pci"; + reg = <0x0000 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc0 0>, + <0 0 0 2 &pcie_intc0 1>, + <0 0 0 3 &pcie_intc0 2>, + <0 0 0 4 &pcie_intc0 3>; + pcie_intc0: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + + pcie1: pcie@1,0 { + device_type = "pci"; + reg = <0x0800 0 0 0 0>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + ranges; + num-lanes = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc1 0>, + <0 0 0 2 &pcie_intc1 1>, + <0 0 0 3 &pcie_intc1 2>, + <0 0 0 4 &pcie_intc1 3>; + pcie_intc1: interrupt-controller { + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt index 2de6f65ecfb1..6173af6885f8 100644 --- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt +++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt @@ -77,7 +77,7 @@ and the following optional properties: - marvell,pcie-lane: the physical PCIe lane number, for ports having multiple lanes. If this property is not found, we assume that the value is 0. -- reset-gpios: optional gpio to PERST# +- reset-gpios: optional GPIO to PERST# - reset-delay-us: delay in us to wait after reset de-assertion, if not specified will default to 100ms, as required by the PCIe specification. @@ -85,7 +85,6 @@ Example: pcie-controller { compatible = "marvell,armada-xp-pcie"; - status = "disabled"; device_type = "pci"; #address-cells = <3>; @@ -147,7 +146,6 @@ pcie-controller { /* wait 20ms for device settle after reset deassertion */ reset-delay-us = <20000>; clocks = <&gateclk 5>; - status = "disabled"; }; pcie@2,0 { @@ -164,7 +162,6 @@ pcie-controller { marvell,pcie-port = <0>; marvell,pcie-lane = <1>; clocks = <&gateclk 6>; - status = "disabled"; }; pcie@3,0 { @@ -181,7 +178,6 @@ pcie-controller { marvell,pcie-port = <0>; marvell,pcie-lane = <2>; clocks = <&gateclk 7>; - status = "disabled"; }; pcie@4,0 { @@ -198,7 +194,6 @@ pcie-controller { marvell,pcie-port = <0>; marvell,pcie-lane = <3>; clocks = <&gateclk 8>; - status = "disabled"; }; pcie@5,0 { @@ -215,7 +210,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <0>; clocks = <&gateclk 9>; - status = "disabled"; }; pcie@6,0 { @@ -232,7 +226,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <1>; clocks = <&gateclk 10>; - status = "disabled"; }; pcie@7,0 { @@ -249,7 +242,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <2>; clocks = <&gateclk 11>; - status = "disabled"; }; pcie@8,0 { @@ -266,7 +258,6 @@ pcie-controller { marvell,pcie-port = <1>; marvell,pcie-lane = <3>; clocks = <&gateclk 12>; - status = "disabled"; }; pcie@9,0 { @@ -283,10 +274,9 @@ pcie-controller { marvell,pcie-port = <2>; marvell,pcie-lane = <0>; clocks = <&gateclk 26>; - status = "disabled"; }; - pcie@10,0 { + pcie@a,0 { device_type = "pci"; assigned-addresses = <0x82005000 0 0x82000 0 0x2000>; reg = <0x5000 0 0 0 0>; @@ -300,6 +290,5 @@ pcie-controller { marvell,pcie-port = <3>; marvell,pcie-lane = <0>; clocks = <&gateclk 27>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/pci/pci-armada8k.txt b/Documentation/devicetree/bindings/pci/pci-armada8k.txt index 598533a57d79..c1e4c3d10a74 100644 --- a/Documentation/devicetree/bindings/pci/pci-armada8k.txt +++ b/Documentation/devicetree/bindings/pci/pci-armada8k.txt @@ -1,6 +1,6 @@ * Marvell Armada 7K/8K PCIe interface -This PCIe host controller is based on the Synopsis Designware PCIe IP +This PCIe host controller is based on the Synopsys DesignWare PCIe IP and thus inherits all the common properties defined in designware-pcie.txt. Required properties: @@ -34,5 +34,4 @@ Example: interrupts = ; num-lanes = <1>; clocks = <&cpm_syscon0 1 13>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pci/pci-keystone.txt b/Documentation/devicetree/bindings/pci/pci-keystone.txt index d08a4d51108f..7e05487544ed 100644 --- a/Documentation/devicetree/bindings/pci/pci-keystone.txt +++ b/Documentation/devicetree/bindings/pci/pci-keystone.txt @@ -1,12 +1,12 @@ TI Keystone PCIe interface -Keystone PCI host Controller is based on Designware PCI h/w version 3.65. -It shares common functions with PCIe Designware core driver and inherit -common properties defined in +Keystone PCI host Controller is based on the Synopsys DesignWare PCI +hardware version 3.65. It shares common functions with the PCIe DesignWare +core driver and inherits common properties defined in Documentation/devicetree/bindings/pci/designware-pci.txt Please refer to Documentation/devicetree/bindings/pci/designware-pci.txt -for the details of Designware DT bindings. Additional properties are +for the details of DesignWare DT bindings. Additional properties are described here as well as properties that are not applicable. Required Properties:- @@ -52,13 +52,12 @@ pcie_intc: Interrupt controller device node for Legacy IRQ chip }; Optional properties:- - phys: phandle to Generic Keystone SerDes phy for PCI - phy-names: name of the Generic Keystine SerDes phy for PCI + phys: phandle to generic Keystone SerDes PHY for PCI + phy-names: name of the generic Keystone SerDes PHY for PCI - If boot loader already does PCI link establishment, then phys and phy-names shouldn't be present. interrupts: platform interrupt for error interrupts. -Designware DT Properties not applicable for Keystone PCI +DesignWare DT Properties not applicable for Keystone PCI 1. pcie_bus clock-names not used. Instead, a phandle to phys is used. - diff --git a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt index 07a75094c5a8..3d038638612b 100644 --- a/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt +++ b/Documentation/devicetree/bindings/pci/pci-rcar-gen2.txt @@ -6,11 +6,14 @@ AHB. There is one bridge instance per USB port connected to the internal OHCI and EHCI controllers. Required properties: -- compatible: "renesas,pci-r8a7790" for the R8A7790 SoC; +- compatible: "renesas,pci-r8a7743" for the R8A7743 SoC; + "renesas,pci-r8a7745" for the R8A7745 SoC; + "renesas,pci-r8a7790" for the R8A7790 SoC; "renesas,pci-r8a7791" for the R8A7791 SoC; "renesas,pci-r8a7793" for the R8A7793 SoC; "renesas,pci-r8a7794" for the R8A7794 SoC; - "renesas,pci-rcar-gen2" for a generic R-Car Gen2 compatible device + "renesas,pci-rcar-gen2" for a generic R-Car Gen2 or + RZ/G1 compatible device. When compatible with the generic version, nodes must list the diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt index 50f9e2ca5b13..c77981c5dd18 100644 --- a/Documentation/devicetree/bindings/pci/pci.txt +++ b/Documentation/devicetree/bindings/pci/pci.txt @@ -1,12 +1,12 @@ PCI bus bridges have standardized Device Tree bindings: PCI Bus Binding to: IEEE Std 1275-1994 -http://www.firmware.org/1275/bindings/pci/pci2_1.pdf +http://www.devicetree.org/open-firmware/bindings/pci/pci2_1.pdf And for the interrupt mapping part: Open Firmware Recommended Practice: Interrupt Mapping -http://www.firmware.org/1275/practice/imap/imap0_9d.pdf +http://www.devicetree.org/open-firmware/practice/imap/imap0_9d.pdf Additionally to the properties specified in the above standards a host bridge driver implementation may support the following properties: diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt index 9d418b71774f..3c9d321b3d3b 100644 --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt @@ -9,6 +9,7 @@ - "qcom,pcie-apq8084" for apq8084 - "qcom,pcie-msm8996" for msm8996 or apq8096 - "qcom,pcie-ipq4019" for ipq4019 + - "qcom,pcie-ipq8074" for ipq8074 - reg: Usage: required @@ -20,7 +21,7 @@ Value type: Definition: Must include the following entries - "parf" Qualcomm specific registers - - "dbi" Designware PCIe registers + - "dbi" DesignWare PCIe registers - "elbi" External local bus interface registers - "config" PCIe configuration space @@ -105,6 +106,16 @@ - "bus_master" Master AXI clock - "bus_slave" Slave AXI clock +- clock-names: + Usage: required for ipq8074 + Value type: + Definition: Should contain the following entries + - "iface" PCIe to SysNOC BIU clock + - "axi_m" AXI Master clock + - "axi_s" AXI Slave clock + - "ahb" AHB clock + - "aux" Auxiliary clock + - resets: Usage: required Value type: @@ -144,6 +155,18 @@ - "ahb" AHB reset - "phy_ahb" PHY AHB reset +- reset-names: + Usage: required for ipq8074 + Value type: + Definition: Should contain the following entries + - "pipe" PIPE reset + - "sleep" Sleep reset + - "sticky" Core Sticky reset + - "axi_m" AXI Master reset + - "axi_s" AXI Slave reset + - "ahb" AHB Reset + - "axi_m_sticky" AXI Master Sticky reset + - power-domains: Usage: required for apq8084 and msm8996/apq8096 Value type: @@ -180,7 +203,7 @@ - -gpios: Usage: optional Value type: - Definition: List of phandle and gpio specifier pairs. Should contain + Definition: List of phandle and GPIO specifier pairs. Should contain - "perst-gpios" PCIe endpoint reset signal line - "wake-gpios" PCIe endpoint wake signal line diff --git a/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt b/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt index 8e0a1eb0acbb..a04ab1b76211 100644 --- a/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt +++ b/Documentation/devicetree/bindings/pci/ralink,rt3883-pci.txt @@ -71,7 +71,7 @@ - interrupt-map: standard PCI properties to define the mapping of the PCI interface to interrupt numbers. - The PCI host bridge node migh have additional sub-nodes representing + The PCI host bridge node might have additional sub-nodes representing the onboard PCI devices/PCI slots. Each such sub-node must have the following mandatory properties: diff --git a/Documentation/devicetree/bindings/pci/rcar-pci.txt b/Documentation/devicetree/bindings/pci/rcar-pci.txt index bd27428dda61..76ba3a61d1a3 100644 --- a/Documentation/devicetree/bindings/pci/rcar-pci.txt +++ b/Documentation/devicetree/bindings/pci/rcar-pci.txt @@ -14,7 +14,7 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; SoC-specific version corresponding to the platform first followed by the generic version. -- reg: base address and length of the pcie controller registers. +- reg: base address and length of the PCIe controller registers. - #address-cells: set to <3> - #size-cells: set to <2> - bus-range: PCI bus numbers covered @@ -25,15 +25,14 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; source for hardware related interrupts (e.g. link speed change). - #interrupt-cells: set to <1> - interrupt-map-mask and interrupt-map: standard PCI properties - to define the mapping of the PCIe interface to interrupt - numbers. + to define the mapping of the PCIe interface to interrupt numbers. - clocks: from common clock binding: clock specifiers for the PCIe controller and PCIe bus clocks. - clock-names: from common clock binding: should be "pcie" and "pcie_bus". Example: -SoC specific DT Entry: +SoC-specific DT Entry: pcie: pcie@fe000000 { compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2"; @@ -54,5 +53,4 @@ SoC specific DT Entry: interrupt-map = <0 0 0 0 &gic 0 116 4>; clocks = <&mstp3_clks R8A7791_CLK_PCIE>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt index 1453a734c2f5..af34c65773fd 100644 --- a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt +++ b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt @@ -19,8 +19,6 @@ Required properties: - "pm" - msi-map: Maps a Requester ID to an MSI controller and associated msi-specifier data. See ./pci-msi.txt -- phys: From PHY bindings: Phandle for the Generic PHY for PCIe. -- phy-names: MUST be "pcie-phy". - interrupts: Three interrupt entries must be specified. - interrupt-names: Must include the following names - "sys" @@ -42,11 +40,24 @@ Required properties: interrupt source. The value must be 1. - interrupt-map-mask and interrupt-map: standard PCI properties +Required properties for legacy PHY model (deprecated): +- phys: From PHY bindings: Phandle for the Generic PHY for PCIe. +- phy-names: MUST be "pcie-phy". + +Required properties for per-lane PHY model (preferred): +- phys: Must contain an phandle to a PHY for each entry in phy-names. +- phy-names: Must include 4 entries for all 4 lanes even if some of + them won't be used for your cases. Entries are of the form "pcie-phy-N": + where N ranges from 0 to 3. + (see example below and you MUST also refer to ../phy/rockchip-pcie-phy.txt + for changing the #phy-cells of phy node to support it) + Optional Property: - aspm-no-l0s: RC won't support ASPM L0s. This property is needed if using 24MHz OSC for RC's PHY. -- ep-gpios: contain the entry for pre-reset gpio +- ep-gpios: contain the entry for pre-reset GPIO - num-lanes: number of lanes to use +- vpcie12v-supply: The phandle to the 12v regulator to use for PCIe. - vpcie3v3-supply: The phandle to the 3.3v regulator to use for PCIe. - vpcie1v8-supply: The phandle to the 1.8v regulator to use for PCIe. - vpcie0v9-supply: The phandle to the 0.9v regulator to use for PCIe. @@ -95,6 +106,7 @@ pcie0: pcie@f8000000 { <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; reset-names = "core", "mgmt", "mgmt-sticky", "pipe", "pm", "pclk", "aclk"; + /* deprecated legacy PHY model */ phys = <&pcie_phy>; phy-names = "pcie-phy"; pinctrl-names = "default"; @@ -111,3 +123,13 @@ pcie0: pcie@f8000000 { #interrupt-cells = <1>; }; }; + +pcie0: pcie@f8000000 { + ... + + /* preferred per-lane PHY model */ + phys = <&pcie_phy 0>, <&pcie_phy 1>, <&pcie_phy 2>, <&pcie_phy 3>; + phy-names = "pcie-phy-0", "pcie-phy-1", "pcie-phy-2", "pcie-phy-3"; + + ... +}; diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt index 7d3b09474657..34a11bfbfb60 100644 --- a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt +++ b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt @@ -1,29 +1,29 @@ * Samsung Exynos 5440 PCIe interface -This PCIe host controller is based on the Synopsis Designware PCIe IP +This PCIe host controller is based on the Synopsys DesignWare PCIe IP and thus inherits all the common properties defined in designware-pcie.txt. Required properties: - compatible: "samsung,exynos5440-pcie" -- reg: base addresses and lengths of the pcie controller, - the phy controller, additional register for the phy controller. - (Registers for the phy controller are DEPRECATED. +- reg: base addresses and lengths of the PCIe controller, + the PHY controller, additional register for the PHY controller. + (Registers for the PHY controller are DEPRECATED. Use the PHY framework.) - reg-names : First name should be set to "elbi". - And use the "config" instead of getting the confgiruation address space + And use the "config" instead of getting the configuration address space from "ranges". - NOTE: When use the "config" property, reg-names must be set. + NOTE: When using the "config" property, reg-names must be set. - interrupts: A list of interrupt outputs for level interrupt, pulse interrupt, special interrupt. -- phys: From PHY binding. Phandle for the Generic PHY. +- phys: From PHY binding. Phandle for the generic PHY. Refer to Documentation/devicetree/bindings/phy/samsung-phy.txt -Other common properties refer to - Documentation/devicetree/binding/pci/designware-pcie.txt +For other common properties, refer to + Documentation/devicetree/bindings/pci/designware-pcie.txt Example: -SoC specific DT Entry: +SoC-specific DT Entry: pcie@290000 { compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; @@ -83,7 +83,7 @@ With using PHY framework: ... }; -Board specific DT Entry: +Board-specific DT Entry: pcie@290000 { reset-gpio = <&pin_ctrl 5 0>; diff --git a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt index 49ea76da7718..d5a14f5dad46 100644 --- a/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt +++ b/Documentation/devicetree/bindings/pci/spear13xx-pcie.txt @@ -1,12 +1,12 @@ SPEAr13XX PCIe DT detail: ================================ -SPEAr13XX uses synopsis designware PCIe controller and ST MiPHY as phy +SPEAr13XX uses the Synopsys DesignWare PCIe controller and ST MiPHY as PHY controller. Required properties: -- compatible : should be "st,spear1340-pcie", "snps,dw-pcie". -- phys : phandle to phy node associated with pcie controller +- compatible : should be "st,spear1340-pcie", "snps,dw-pcie". +- phys : phandle to PHY node associated with PCIe controller - phy-names : must be "pcie-phy" - All other definitions as per generic PCI bindings diff --git a/Documentation/devicetree/bindings/pci/ti-pci.txt b/Documentation/devicetree/bindings/pci/ti-pci.txt index 6a07c96227e0..7f7af3044016 100644 --- a/Documentation/devicetree/bindings/pci/ti-pci.txt +++ b/Documentation/devicetree/bindings/pci/ti-pci.txt @@ -1,6 +1,6 @@ TI PCI Controllers -PCIe Designware Controller +PCIe DesignWare Controller - compatible: Should be "ti,dra7-pcie" for RC Should be "ti,dra7-pcie-ep" for EP - phys : list of PHY specifiers (used by generic PHY framework) @@ -13,7 +13,7 @@ PCIe Designware Controller HOST MODE ========= - reg : Two register ranges as listed in the reg-names property - - reg-names : The first entry must be "ti-conf" for the TI specific registers + - reg-names : The first entry must be "ti-conf" for the TI-specific registers The second entry must be "rc-dbics" for the DesignWare PCIe registers The third entry must be "config" for the PCIe configuration space @@ -30,7 +30,7 @@ HOST MODE DEVICE MODE =========== - reg : Four register ranges as listed in the reg-names property - - reg-names : "ti-conf" for the TI specific registers + - reg-names : "ti-conf" for the TI-specific registers "ep_dbics" for the standard configuration registers as they are locally accessed within the DIF CS space "ep_dbics2" for the standard configuration registers as @@ -46,7 +46,7 @@ DEVICE MODE access. Optional Property: - - gpios : Should be added if a gpio line is required to drive PERST# line + - gpios : Should be added if a GPIO line is required to drive PERST# line NOTE: Two DT nodes may be added for each PCI controller; one for host mode and another for device mode. So in order for PCI to diff --git a/Documentation/devicetree/bindings/pci/versatile.txt b/Documentation/devicetree/bindings/pci/versatile.txt index ebd1e7d0403e..0a702b13d2ac 100644 --- a/Documentation/devicetree/bindings/pci/versatile.txt +++ b/Documentation/devicetree/bindings/pci/versatile.txt @@ -5,7 +5,7 @@ PCI host controller found on the ARM Versatile PB board's FPGA. Required properties: - compatible: should contain "arm,versatile-pci" to identify the Versatile PCI controller. -- reg: base addresses and lengths of the pci controller. There must be 3 +- reg: base addresses and lengths of the PCI controller. There must be 3 entries: - Versatile-specific registers - Self Config space diff --git a/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt b/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt index 36d881c8e6d4..85d9b95234f7 100644 --- a/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt +++ b/Documentation/devicetree/bindings/pci/xgene-pci-msi.txt @@ -4,7 +4,7 @@ Required properties: - compatible: should be "apm,xgene1-msi" to identify X-Gene v1 PCIe MSI controller block. -- msi-controller: indicates that this is X-Gene v1 PCIe MSI controller node +- msi-controller: indicates that this is an X-Gene v1 PCIe MSI controller node - reg: physical base address (0x79000000) and length (0x900000) for controller registers. These registers include the MSI termination address and data registers as well as the MSI interrupt status registers. @@ -13,7 +13,8 @@ Required properties: interrupt number 0x10 to 0x1f. - interrupt-names: not required -Each PCIe node needs to have property msi-parent that points to msi controller node +Each PCIe node needs to have property msi-parent that points to an MSI +controller node Examples: @@ -44,7 +45,6 @@ SoC DTSI: + PCIe controller node with msi-parent property pointing to MSI node: pcie0: pcie@1f2b0000 { - status = "disabled"; device_type = "pci"; compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; #interrupt-cells = <1>; diff --git a/Documentation/devicetree/bindings/pci/xgene-pci.txt b/Documentation/devicetree/bindings/pci/xgene-pci.txt index 1070b068c7c6..6fd2decfa66c 100644 --- a/Documentation/devicetree/bindings/pci/xgene-pci.txt +++ b/Documentation/devicetree/bindings/pci/xgene-pci.txt @@ -8,7 +8,7 @@ Required properties: property. - reg-names: Must include the following entries: "csr": controller configuration registers. - "cfg": pcie configuration space registers. + "cfg": PCIe configuration space registers. - #address-cells: set to <3> - #size-cells: set to <2> - ranges: ranges for the outbound memory, I/O regions. @@ -21,11 +21,11 @@ Required properties: Optional properties: - status: Either "ok" or "disabled". -- dma-coherent: Present if dma operations are coherent +- dma-coherent: Present if DMA operations are coherent Example: -SoC specific DT Entry: +SoC-specific DT Entry: pcie0: pcie@1f2b0000 { status = "disabled"; @@ -51,7 +51,7 @@ SoC specific DT Entry: }; -Board specific DT Entry: +Board-specific DT Entry: &pcie0 { status = "ok"; }; diff --git a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt index 3259798a1192..01bf7fdf4c19 100644 --- a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt +++ b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt @@ -15,9 +15,9 @@ Required properties: - device_type: must be "pci" - interrupts: Should contain NWL PCIe interrupt - interrupt-names: Must include the following entries: - "msi1, msi0": interrupt asserted when MSI is received + "msi1, msi0": interrupt asserted when an MSI is received "intx": interrupt asserted when a legacy interrupt is received - "misc": interrupt asserted when miscellaneous is received + "misc": interrupt asserted when miscellaneous interrupt is received - interrupt-map-mask and interrupt-map: standard PCI properties to define the mapping of the PCI interface to interrupt numbers. - ranges: ranges for the PCI memory regions (I/O space region is not @@ -26,7 +26,8 @@ Required properties: detailed explanation - msi-controller: indicates that this is MSI controller node - msi-parent: MSI parent of the root complex itself -- legacy-interrupt-controller: Interrupt controller device node for Legacy interrupts +- legacy-interrupt-controller: Interrupt controller device node for Legacy + interrupts - interrupt-controller: identifies the node as an interrupt controller - #interrupt-cells: should be set to 1 - #address-cells: specifies the number of cells needed to encode an diff --git a/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt b/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt index 5f3a65a9dd88..e1bb12711fbf 100644 --- a/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt +++ b/Documentation/devicetree/bindings/phy/apm-xgene-phy.txt @@ -61,19 +61,16 @@ Example: compatible = "apm,xgene-phy"; reg = <0x0 0x1f21a000 0x0 0x100>; #phy-cells = <1>; - status = "disabled"; }; phy2: phy@1f22a000 { compatible = "apm,xgene-phy"; reg = <0x0 0x1f22a000 0x0 0x100>; #phy-cells = <1>; - status = "ok"; }; phy3: phy@1f23a000 { compatible = "apm,xgene-phy"; reg = <0x0 0x1f23a000 0x0 0x100>; #phy-cells = <1>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt b/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt index f37b3a86341d..300830dda0bf 100644 --- a/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/keystone-usb-phy.txt @@ -16,5 +16,4 @@ usb_phy: usb_phy@2620738 { #address-cells = <1>; #size-cells = <1>; reg = <0x2620738 32>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/phy/phy-bindings.txt b/Documentation/devicetree/bindings/phy/phy-bindings.txt index 1293c321754c..a403b81d0679 100644 --- a/Documentation/devicetree/bindings/phy/phy-bindings.txt +++ b/Documentation/devicetree/bindings/phy/phy-bindings.txt @@ -34,7 +34,9 @@ PHY user node ============= Required Properties: -phys : the phandle for the PHY device (used by the PHY subsystem) +phys : the phandle for the PHY device (used by the PHY subsystem; not to be + confused with the Ethernet specific 'phy' and 'phy-handle' properties, + see Documentation/devicetree/bindings/net/ethernet.txt for these) phy-names : the names of the PHY corresponding to the PHYs present in the *phys* phandle diff --git a/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt new file mode 100644 index 000000000000..643948b6b576 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-lantiq-rcu-usb2.txt @@ -0,0 +1,40 @@ +Lantiq XWAY SoC RCU USB 1.1/2.0 PHY binding +=========================================== + +This binding describes the USB PHY hardware provided by the RCU module on the +Lantiq XWAY SoCs. + +This node has to be a sub node of the Lantiq RCU block. + +------------------------------------------------------------------------------- +Required properties (controller (parent) node): +- compatible : Should be one of + "lantiq,ase-usb2-phy" + "lantiq,danube-usb2-phy" + "lantiq,xrx100-usb2-phy" + "lantiq,xrx200-usb2-phy" + "lantiq,xrx300-usb2-phy" +- reg : Defines the following sets of registers in the parent + syscon device + - Offset of the USB PHY configuration register + - Offset of the USB Analog configuration + register (only for xrx200 and xrx200) +- clocks : References to the (PMU) "phy" clk gate. +- clock-names : Must be "phy" +- resets : References to the RCU USB configuration reset bits. +- reset-names : Must be one of the following: + "phy" (optional) + "ctrl" (shared) + +------------------------------------------------------------------------------- +Example for the USB PHYs on an xRX200 SoC: + usb_phy0: usb2-phy@18 { + compatible = "lantiq,xrx200-usb2-phy"; + reg = <0x18 4>, <0x38 4>; + + clocks = <&pmu PMU_GATE_USB0_PHY>; + clock-names = "phy"; + resets = <&reset1 4 4>, <&reset0 4 4>; + reset-names = "phy", "ctrl"; + #phy-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt similarity index 88% rename from Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt rename to Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt index 0acc5a99fb79..41e09ed2ca70 100644 --- a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt +++ b/Documentation/devicetree/bindings/phy/phy-mtk-tphy.txt @@ -1,13 +1,18 @@ -mt65xx USB3.0 PHY binding +MediaTek T-PHY binding -------------------------- -This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC. +T-phy controller supports physical layer functionality for a number of +controllers on MediaTek SoCs, such as, USB2.0, USB3.0, PCIe, and SATA. Required properties (controller (parent) node): - compatible : should be one of - "mediatek,mt2701-u3phy" - "mediatek,mt2712-u3phy" - "mediatek,mt8173-u3phy" + "mediatek,generic-tphy-v1" + "mediatek,generic-tphy-v2" + "mediatek,mt2701-u3phy" (deprecated) + "mediatek,mt2712-u3phy" (deprecated) + "mediatek,mt8173-u3phy"; + make use of "mediatek,generic-tphy-v1" on mt2701 instead and + "mediatek,generic-tphy-v2" on mt2712 instead. - clocks : (deprecated, use port's clocks instead) a list of phandle + clock-specifier pairs, one for each entry in clock-names - clock-names : (deprecated, use port's one instead) must contain @@ -35,6 +40,8 @@ Required properties (port (child) node): cell after port phandle is phy type from: - PHY_TYPE_USB2 - PHY_TYPE_USB3 + - PHY_TYPE_PCIE + - PHY_TYPE_SATA Example: @@ -44,14 +51,12 @@ u3phy: usb-phy@11290000 { #address-cells = <2>; #size-cells = <2>; ranges; - status = "okay"; u2port0: usb-phy@11290800 { reg = <0 0x11290800 0 0x100>; clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; clock-names = "ref"; #phy-cells = <1>; - status = "okay"; }; u3port0: usb-phy@11290900 { @@ -59,7 +64,6 @@ u3phy: usb-phy@11290000 { clocks = <&clk26m>; clock-names = "ref"; #phy-cells = <1>; - status = "okay"; }; u2port1: usb-phy@11291000 { @@ -67,7 +71,6 @@ u3phy: usb-phy@11290000 { clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>; clock-names = "ref"; #phy-cells = <1>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt b/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt new file mode 100644 index 000000000000..bfcf80341657 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt @@ -0,0 +1,43 @@ +mvebu comphy driver +------------------- + +A comphy controller can be found on Marvell Armada 7k/8k on the CP110. It +provides a number of shared PHYs used by various interfaces (network, sata, +usb, PCIe...). + +Required properties: + +- compatible: should be "marvell,comphy-cp110" +- reg: should contain the comphy register location and length. +- marvell,system-controller: should contain a phandle to the + system controller node. +- #address-cells: should be 1. +- #size-cells: should be 0. + +A sub-node is required for each comphy lane provided by the comphy. + +Required properties (child nodes): + +- reg: comphy lane number. +- #phy-cells : from the generic phy bindings, must be 1. Defines the + input port to use for a given comphy lane. + +Example: + + cpm_comphy: phy@120000 { + compatible = "marvell,comphy-cp110"; + reg = <0x120000 0x6000>; + marvell,system-controller = <&cpm_syscon0>; + #address-cells = <1>; + #size-cells = <0>; + + cpm_comphy0: phy@0 { + reg = <0>; + #phy-cells = <1>; + }; + + cpm_comphy1: phy@1 { + reg = <1>; + #phy-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu.txt b/Documentation/devicetree/bindings/phy/phy-mvebu.txt index f95b6260a3b3..64afdd13d91d 100644 --- a/Documentation/devicetree/bindings/phy/phy-mvebu.txt +++ b/Documentation/devicetree/bindings/phy/phy-mvebu.txt @@ -18,7 +18,6 @@ Example: clocks = <&gate_clk 15>; clock-names = "sata"; #phy-cells = <0>; - status = "ok"; }; Armada 375 USB cluster diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt index 84d59b0db8df..074a7b3b0425 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt @@ -6,6 +6,7 @@ Required properties (phy (parent) node): * "rockchip,rk3328-usb2phy" * "rockchip,rk3366-usb2phy" * "rockchip,rk3399-usb2phy" + * "rockchip,rv1108-usb2phy" - reg : the address offset of grf for usb-phy configuration. - #clock-cells : should be 0. - clock-output-names : specify the 480m output clock name. @@ -18,6 +19,10 @@ Optional properties: usb-phy output 480m and xin24m. Refer to clk/clock-bindings.txt for generic clock consumer properties. + - rockchip,usbgrf : phandle to the syscon managing the "usb general + register files". When set driver will request its + phandle as one companion-grf for some special SoCs + (e.g RV1108). Required nodes : a sub-node is required for each port the phy provides. The sub-node name is used to identify host or otg port, @@ -28,10 +33,14 @@ Required nodes : a sub-node is required for each port the phy provides. Required properties (port (child) node): - #phy-cells : must be 0. See ./phy-bindings.txt for details. - interrupts : specify an interrupt for each entry in interrupt-names. - - interrupt-names : a list which shall be the following entries: + - interrupt-names : a list which should be one of the following cases: + Regular case: * "otg-id" : for the otg id interrupt. * "otg-bvalid" : for the otg vbus interrupt. * "linestate" : for the host/otg linestate interrupt. + Some SoCs use one interrupt with the above muxed together, so for these + * "otg-mux" : otg-port interrupt, which mux otg-id/otg-bvalid/linestate + to one. Optional properties: - phy-supply : phandle to a regulator that provides power to VBUS. @@ -58,14 +67,12 @@ grf: syscon@ff770000 { , ; interrupt-names = "otg-id", "otg-bvalid", "linestate"; - status = "okay"; }; u2phy_host: host-port { #phy-cells = <0>; interrupts = ; interrupt-names = "linestate"; - status = "okay"; }; }; }; diff --git a/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt b/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt index 86f2dbe07ed4..a1697c27aecd 100644 --- a/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-dwc3-usb-phy.txt @@ -25,7 +25,6 @@ Example: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; phy@100f8830 { @@ -35,5 +34,4 @@ Example: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt index e11c563a65ec..b6a9f2b92bab 100644 --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt @@ -6,6 +6,7 @@ controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB. Required properties: - compatible: compatible list, contains: + "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074 "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996, "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996. @@ -38,6 +39,8 @@ Required properties: "phy", "common", "cfg". For "qcom,msm8996-qmp-usb3-phy" must contain "phy", "common". + For "qcom,ipq8074-qmp-pcie-phy" must contain: + "phy", "common". - vdda-phy-supply: Phandle to a regulator supply to PHY core block. - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block. @@ -60,6 +63,13 @@ Required properties for child node: one for each entry in clock-names. - clock-names: Must contain following for pcie and usb qmp phys: "pipe" for pipe clock specific to each lane. + - clock-output-names: Name of the PHY clock that will be the parent for + the above pipe clock. + + For "qcom,ipq8074-qmp-pcie-phy": + - "pcie20_phy0_pipe_clk" Pipe Clock parent + (or) + "pcie20_phy1_pipe_clk" - resets: a list of phandles and reset controller specifier pairs, one for each entry in reset-names. @@ -96,6 +106,7 @@ Example: clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; clock-names = "pipe0"; + clock-output-names = "pcie_0_pipe_clk_src"; resets = <&gcc GCC_PCIE_0_PHY_BCR>; reset-names = "lane0"; }; diff --git a/Documentation/devicetree/bindings/phy/ralink-usb-phy.txt b/Documentation/devicetree/bindings/phy/ralink-usb-phy.txt new file mode 100644 index 000000000000..9d2868a437ab --- /dev/null +++ b/Documentation/devicetree/bindings/phy/ralink-usb-phy.txt @@ -0,0 +1,23 @@ +Mediatek/Ralink USB PHY + +Required properties: + - compatible: "ralink,rt3352-usbphy" + "mediatek,mt7620-usbphy" + "mediatek,mt7628-usbphy" + - reg: required for "mediatek,mt7628-usbphy", unused otherwise + - #phy-cells: should be 0 + - ralink,sysctl: a phandle to a ralink syscon register region + - resets: the two reset controllers for host and device + - reset-names: the names of the 2 reset controllers + +Example: + +usbphy: phy { + compatible = "mediatek,mt7628-usbphy"; + reg = <0x10120000 0x1000>; + #phy-cells = <0>; + + ralink,sysctl = <&sysc>; + resets = <&rstctrl 22 &rstctrl 25>; + reset-names = "host", "device"; +}; diff --git a/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt index 0f6222a672ce..b496042f1f44 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt @@ -3,7 +3,6 @@ Rockchip PCIE PHY Required properties: - compatible: rockchip,rk3399-pcie-phy - - #phy-cells: must be 0 - clocks: Must contain an entry in clock-names. See ../clocks/clock-bindings.txt for details. - clock-names: Must be "refclk" @@ -11,6 +10,12 @@ Required properties: See ../reset/reset.txt for details. - reset-names: Must be "phy" +Required properties for legacy PHY mode (deprecated): + - #phy-cells: must be 0 + +Required properties for per-lane PHY mode (preferred): + - #phy-cells: must be 1 + Example: grf: syscon@ff770000 { diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index ab80bfe31cb3..1c40ccd40ce4 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -82,7 +82,6 @@ usbphy: phy@125b0000 { reg = <0x125b0000 0x100>; clocks = <&clock 305>, <&clock 2>; clock-names = "phy", "ref"; - status = "okay"; #phy-cells = <1>; samsung,sysreg-phandle = <&sys_reg>; samsung,pmureg-phandle = <&pmu_reg>; diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index 005bc22938ff..cbc7847dbf6c 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt @@ -9,6 +9,7 @@ Required properties: * allwinner,sun7i-a20-usb-phy * allwinner,sun8i-a23-usb-phy * allwinner,sun8i-a33-usb-phy + * allwinner,sun8i-a83t-usb-phy * allwinner,sun8i-h3-usb-phy * allwinner,sun8i-v3s-usb-phy * allwinner,sun50i-a64-usb-phy @@ -17,18 +18,22 @@ Required properties: * "phy_ctrl" * "pmu0" for H3, V3s and A64 * "pmu1" - * "pmu2" for sun4i, sun6i or sun7i + * "pmu2" for sun4i, sun6i, sun7i, sun8i-a83t or sun8i-h3 + * "pmu3" for sun8i-h3 - #phy-cells : from the generic phy bindings, must be 1 - clocks : phandle + clock specifier for the phy clocks - clock-names : * "usb_phy" for sun4i, sun5i or sun7i * "usb0_phy", "usb1_phy" and "usb2_phy" for sun6i * "usb0_phy", "usb1_phy" for sun8i + * "usb0_phy", "usb1_phy", "usb2_phy" and "usb2_hsic_12M" for sun8i-a83t + * "usb0_phy", "usb1_phy", "usb2_phy" and "usb3_phy" for sun8i-h3 - resets : a list of phandle + reset specifier pairs - reset-names : * "usb0_reset" * "usb1_reset" - * "usb2_reset" for sun4i, sun6i or sun7i + * "usb2_reset" for sun4i, sun6i, sun7i, sun8i-a83t or sun8i-h3 + * "usb3_reset" for sun8i-h3 Optional properties: - usb0_id_det-gpios : gpio phandle for reading the otg id pin value @@ -37,6 +42,7 @@ Optional properties: - usb0_vbus-supply : regulator phandle for controller usb0 vbus - usb1_vbus-supply : regulator phandle for controller usb1 vbus - usb2_vbus-supply : regulator phandle for controller usb2 vbus +- usb3_vbus-supply : regulator phandle for controller usb3 vbus Example: usbphy: phy@0x01c13400 { diff --git a/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt index 1cca85c709d1..f9853156e311 100644 --- a/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun9i-usb-phy.txt @@ -33,6 +33,5 @@ Example: clock-names = "hsic_480M", "hsic_12M", "phy"; resets = <&usb_phy_clk 18>, <&usb_phy_clk 19>; reset-names = "hsic", "phy"; - status = "disabled"; #phy-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt index 590e60378be3..3e23fece99da 100644 --- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt @@ -148,5 +148,4 @@ dbgu: serial@fffff200 { interrupts = <1 4 7>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dbgu>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt new file mode 100644 index 000000000000..61466c58faae --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt @@ -0,0 +1,59 @@ +Cortina Systems Gemini pin controller + +This pin controller is found in the Cortina Systems Gemini SoC family, +see further arm/gemini.txt. It is a purely group-based multiplexing pin +controller. + +The pin controller node must be a subnode of the system controller node. + +Required properties: +- compatible: "cortina,gemini-pinctrl" + +Subnodes of the pin controller contain pin control multiplexing set-up. +Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes. + +Example: + + +syscon { + compatible = "cortina,gemini-syscon"; + ... + pinctrl { + compatible = "cortina,gemini-pinctrl"; + pinctrl-names = "default"; + pinctrl-0 = <&dram_default_pins>, <&system_default_pins>, + <&vcontrol_default_pins>; + + dram_default_pins: pinctrl-dram { + mux { + function = "dram"; + groups = "dramgrp"; + }; + }; + rtc_default_pins: pinctrl-rtc { + mux { + function = "rtc"; + groups = "rtcgrp"; + }; + }; + power_default_pins: pinctrl-power { + mux { + function = "power"; + groups = "powergrp"; + }; + }; + system_default_pins: pinctrl-system { + mux { + function = "system"; + groups = "systemgrp"; + }; + }; + (...) + uart_default_pins: pinctrl-uart { + mux { + function = "uart"; + groups = "uartrxtxgrp"; + }; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt index 9fde25f1401a..42d74f8a1bcc 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt @@ -61,7 +61,6 @@ Examples: usdhc@0219c000 { /* uSDHC4 */ non-removable; vmmc-supply = <®_3p3v>; - status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc4_1>; }; diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt index 8c5d27c5b562..6666277c3acb 100644 --- a/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt @@ -61,7 +61,6 @@ iomuxc-lpsr controller and SDA pad from iomuxc controller as: i2c1: i2c@30a20000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1_1 &pinctrl_i2c1_2>; - status = "okay"; }; iomuxc-lpsr@302c0000 { diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx7ulp-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx7ulp-pinctrl.txt new file mode 100644 index 000000000000..44ad670ae11e --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx7ulp-pinctrl.txt @@ -0,0 +1,61 @@ +* Freescale i.MX7ULP IOMUX Controller + +i.MX 7ULP has three IOMUXC instances: IOMUXC0 for M4 ports, IOMUXC1 for A7 +ports and IOMUXC DDR for DDR interface. + +Note: +This binding doc is only for the IOMUXC1 support in A7 Domain and it only +supports generic pin config. + +Please also refer pinctrl-bindings.txt in this directory for generic pinctrl +binding. + +=== Pin Controller Node === + +Required properties: +- compatible: "fsl,imx7ulp-iomuxc1" +- reg: Should contain the base physical address and size of the iomuxc + registers. + +=== Pin Configuration Node === +- pinmux: One integers array, represents a group of pins mux setting. + The format is pinmux = , PIN_FUNC_ID is a pin working on + a specific function. + + NOTE: i.MX7ULP PIN_FUNC_ID consists of 4 integers as it shares one mux + and config register as follows: + + + Refer to imx7ulp-pinfunc.h in in device tree source folder for all + available imx7ulp PIN_FUNC_ID. + +Optional Properties: +- drive-strength Integer. Controls Drive Strength + 0: Standard + 1: Hi Driver +- drive-push-pull Bool. Enable Pin Push-pull +- drive-open-drain Bool. Enable Pin Open-drian +- slew-rate: Integer. Controls Slew Rate + 0: Standard + 1: Slow +- bias-disable: Bool. Pull disabled +- bias-pull-down: Bool. Pull down on pin +- bias-pull-up: Bool. Pull up on pin + +Examples: +#include "imx7ulp-pinfunc.h" + +/* Pin Controller Node */ +iomuxc1: iomuxc@40ac0000 { + compatible = "fsl,imx7ulp-iomuxc1"; + reg = <0x40ac0000 0x1000>; + + /* Pin Configuration Node */ + pinctrl_lpuart4: lpuart4grp { + pinmux = < + IMX7ULP_PAD_PTC3__LPUART4_RX + IMX7ULP_PAD_PTC2__LPUART4_TX + >; + bias-pull-up; + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt index f2abdaee9022..e0e886b73527 100644 --- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-dpaux-padctl.txt @@ -56,5 +56,4 @@ Example: pinctrl-0 = <&state_dpaux_i2c>; pinctrl-1 = <&state_dpaux_off>; pinctrl-names = "default", "idle"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt index 09e81a95bbfd..b1159434f593 100644 --- a/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/oxnas,pinctrl.txt @@ -50,7 +50,6 @@ uart2: serial@900000 { reg-io-width = <1>; current-speed = <115200>; no-loopback-test; - status = "disabled"; resets = <&reset 22>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart2>; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt index ca01710ee29a..3b7266c7c438 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt @@ -69,8 +69,9 @@ PWM1 PWM2 PWM3 PWM4 PWM5 PWM6 PWM7 RGMII1 RGMII2 RMII1 RMII2 ROM16 ROM8 ROMCS1 ROMCS2 ROMCS3 ROMCS4 RXD1 RXD2 RXD3 RXD4 SALT1 SALT2 SALT3 SALT4 SD1 SD2 SGPMCK SGPMI SGPMLD SGPMO SGPSCK SGPSI0 SGPSI1 SGPSLD SIOONCTRL SIOPBI SIOPBO SIOPWREQ SIOPWRGD SIOS3 SIOS5 SIOSCI SPI1 SPI1DEBUG SPI1PASSTHRU SPICS1 TIMER3 TIMER4 -TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD2 TXD3 TXD4 UART6 USBCKI VGABIOS_ROM VGAHS -VGAVS VPI18 VPI24 VPI30 VPO12 VPO24 WDTRST1 WDTRST2 +TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD2 TXD3 TXD4 UART6 USB11D1 USB11H2 USB2D1 +USB2H1 USBCKI VGABIOS_ROM VGAHS VGAVS VPI18 VPI24 VPI30 VPO12 VPO24 WDTRST1 +WDTRST2 aspeed,ast2500-pinctrl, aspeed,g5-pinctrl: @@ -86,7 +87,8 @@ SALT11 SALT12 SALT13 SALT14 SALT2 SALT3 SALT4 SALT5 SALT6 SALT7 SALT8 SALT9 SCL1 SCL2 SD1 SD2 SDA1 SDA2 SGPS1 SGPS2 SIOONCTRL SIOPBI SIOPBO SIOPWREQ SIOPWRGD SIOS3 SIOS5 SIOSCI SPI1 SPI1CS1 SPI1DEBUG SPI1PASSTHRU SPI2CK SPI2CS0 SPI2CS1 SPI2MISO SPI2MOSI TIMER3 TIMER4 TIMER5 TIMER6 TIMER7 TIMER8 TXD1 TXD2 -TXD3 TXD4 UART6 USBCKI VGABIOSROM VGAHS VGAVS VPI24 VPO WDTRST1 WDTRST2 +TXD3 TXD4 UART6 USB11BHID USB2AD USB2AH USB2BD USB2BH USBCKI VGABIOSROM VGAHS +VGAVS VPI24 VPO WDTRST1 WDTRST2 Examples ======== diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt index 62d0f33fa65e..4483cc31e531 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt @@ -268,6 +268,8 @@ output-enable - enable output on a pin without actively driving it (such as enabling an output buffer) output-low - set the pin to output mode with low level output-high - set the pin to output mode with high level +sleep-hardware-state - indicate this is sleep related state which will be programmed + into the registers for the sleep state. slew-rate - set the slew rate For example: diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt index 17631d0a9af7..37d744750579 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt @@ -5,6 +5,7 @@ The Mediatek's Pin controller is used to control SoC pins. Required properties: - compatible: value should be one of the following. "mediatek,mt2701-pinctrl", compatible with mt2701 pinctrl. + "mediatek,mt2712-pinctrl", compatible with mt2712 pinctrl. "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl. "mediatek,mt7623-pinctrl", compatible with mt7623 pinctrl. "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl. diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt new file mode 100644 index 000000000000..eee3dc260934 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt @@ -0,0 +1,63 @@ +Pincontrol driver for RK805 Power management IC. + +RK805 has 2 pins which can be configured as GPIO output only. + +Please refer file +for details of the common pinctrl bindings used by client devices, +including the meaning of the phrase "pin configuration node". + +Optional Pinmux properties: +-------------------------- +Following properties are required if default setting of pins are required +at boot. +- pinctrl-names: A pinctrl state named per . +- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per + . + +The pin configurations are defined as child of the pinctrl states node. Each +sub-node have following properties: + +Required properties: +------------------ +- #gpio-cells: Should be two. The first cell is the pin number and the + second is the GPIO flags. + +- gpio-controller: Marks the device node as a GPIO controller. + +- pins: List of pins. Valid values of pins properties are: gpio0, gpio1. + +First 2 properties must be added in the RK805 PMIC node, documented in +Documentation/devicetree/bindings/mfd/rk808.txt + +Optional properties: +------------------- +Following are optional properties defined as pinmux DT binding document +. Absence of properties will leave the configuration +on default. + function, + output-low, + output-high. + +Valid values for function properties are: gpio. + +Theres is also not customised properties for any GPIO. + +Example: +-------- +rk805: rk805@18 { + compatible = "rockchip,rk805"; + ... + gpio-controller; + #gpio-cells = <2>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>, <&rk805_default>; + + rk805_default: pinmux { + gpio01 { + pins = "gpio0", "gpio1"; + function = "gpio"; + output-high; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt index e219849b21ca..39170f372599 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt @@ -81,5 +81,4 @@ pmm: pin-controller@1462000 { &vga { pinctrl-names = "default"; pinctrl-0 = <&vga_pins>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt index a7bde64798c7..a752a4716486 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,apq8064-pinctrl.txt @@ -46,7 +46,8 @@ Valid values for pins are: gpio0-gpio89 Valid values for function are: - cam_mclk, codec_mic_i2s, codec_spkr_i2s, gpio, gsbi1, gsbi2, gsbi3, gsbi4, + cam_mclk, codec_mic_i2s, codec_spkr_i2s, gp_clk_0a, gp_clk_0b, gp_clk_1a, + gp_clk_1b, gp_clk_2a, gp_clk_2b, gpio, gsbi1, gsbi2, gsbi3, gsbi4, gsbi4_cam_i2c, gsbi5, gsbi5_spi_cs1, gsbi5_spi_cs2, gsbi5_spi_cs3, gsbi6, gsbi6_spi_cs1, gsbi6_spi_cs2, gsbi6_spi_cs3, gsbi7, gsbi7_spi_cs1, gsbi7_spi_cs2, gsbi7_spi_cs3, gsbi_cam_i2c, hdmi, mi2s, riva_bt, riva_fm, diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt index cfb8500dd56b..93374f478b9e 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq4019-pinctrl.txt @@ -50,7 +50,11 @@ Valid values for qcom,pins are: Supports mux, bias and drive-strength Valid values for qcom,function are: -gpio, blsp_uart1, blsp_i2c0, blsp_i2c1, blsp_uart0, blsp_spi1, blsp_spi0 +aud_pin, audio_pwm, blsp_i2c0, blsp_i2c1, blsp_spi0, blsp_spi1, blsp_uart0, +blsp_uart1, chip_rst, gpio, i2s_rx, i2s_spdif_in, i2s_spdif_out, i2s_td, i2s_tx, +jtag, led0, led1, led2, led3, led4, led5, led6, led7, led8, led9, led10, led11, +mdc, mdio, pcie, pmu, prng_rosc, qpic, rgmii, rmii, sdio, smart0, smart1, +smart2, smart3, tm, wifi0, wifi1 Example: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt index 8d893a874634..5b12c57e7f02 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt +++ b/Documentation/devicetree/bindings/pinctrl/qcom,pmic-gpio.txt @@ -16,6 +16,7 @@ PMIC's from Qualcomm. "qcom,pm8941-gpio" "qcom,pm8994-gpio" "qcom,pma8084-gpio" + "qcom,pmi8994-gpio" And must contain either "qcom,spmi-gpio" or "qcom,ssbi-gpio" if the device is on an spmi bus or an ssbi bus respectively @@ -85,6 +86,7 @@ to specify in a pin configuration subnode: gpio1-gpio36 for pm8941 gpio1-gpio22 for pm8994 gpio1-gpio22 for pma8084 + gpio1-gpio10 for pmi8994 - function: Usage: required @@ -98,7 +100,10 @@ to specify in a pin configuration subnode: "dtest1", "dtest2", "dtest3", - "dtest4" + "dtest4", + And following values are supported by LV/MV GPIO subtypes: + "func3", + "func4" - bias-disable: Usage: optional @@ -183,6 +188,25 @@ to specify in a pin configuration subnode: Value type: Definition: The specified pins are configured in open-source mode. +- qcom,analog-pass: + Usage: optional + Value type: + Definition: The specified pins are configured in analog-pass-through mode. + +- qcom,atest: + Usage: optional + Value type: + Definition: Selects ATEST rail to route to GPIO when it's configured + in analog-pass-through mode. + Valid values are 1-4 corresponding to ATEST1 to ATEST4. + +- qcom,dtest-buffer: + Usage: optional + Value type: + Definition: Selects DTEST rail to route to GPIO when it's configured + as digital input. + Valid values are 1-4 corresponding to DTEST1 to DTEST4. + Example: pm8921_gpio: gpio@150 { diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt index 645082f03259..9b4f8041c36a 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/renesas,pfc-pinctrl.txt @@ -24,6 +24,7 @@ Required Properties: - "renesas,pfc-r8a7794": for R8A7794 (R-Car E2) compatible pin-controller. - "renesas,pfc-r8a7795": for R8A7795 (R-Car H3) compatible pin-controller. - "renesas,pfc-r8a7796": for R8A7796 (R-Car M3-W) compatible pin-controller. + - "renesas,pfc-r8a77995": for R8A77995 (R-Car D3) compatible pin-controller. - "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller. - reg: Base address and length of each memory resource used by the pin @@ -111,7 +112,7 @@ Examples Example 1: SH73A0 (SH-Mobile AG5) pin controller node - pfc: pfc@e6050000 { + pfc: pin-controller@e6050000 { compatible = "renesas,pfc-sh73a0"; reg = <0xe6050000 0x8000>, <0xe605801c 0x1c>; @@ -172,5 +173,4 @@ Example 4: KZM-A9-GT (SH-Mobile AG5) default pin state for the MMCIF device bus-width = <8>; vmmc-supply = <®_1p8v>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt index ee01ab58224d..4864e3a74de3 100644 --- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt @@ -24,6 +24,7 @@ Required properties for iomux controller: "rockchip,rk2928-pinctrl": for Rockchip RK2928 "rockchip,rk3066a-pinctrl": for Rockchip RK3066a "rockchip,rk3066b-pinctrl": for Rockchip RK3066b + "rockchip,rk3128-pinctrl": for Rockchip RK3128 "rockchip,rk3188-pinctrl": for Rockchip RK3188 "rockchip,rk3228-pinctrl": for Rockchip RK3228 "rockchip,rk3288-pinctrl": for Rockchip RK3288 @@ -120,7 +121,6 @@ uart2: serial@20064000 { reg-shift = <2>; reg-io-width = <1>; clocks = <&mux_uart2>; - status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&uart2_xfer>; diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt new file mode 100644 index 000000000000..b1cea7a3a071 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/sprd,pinctrl.txt @@ -0,0 +1,83 @@ +* Spreadtrum Pin Controller + +The Spreadtrum pin controller are organized in 3 blocks (types). + +The first block comprises some global control registers, and each +register contains several bit fields with one bit or several bits +to configure for some global common configuration, such as domain +pad driving level, system control select and so on ("domain pad +driving level": One pin can output 3.0v or 1.8v, depending on the +related domain pad driving selection, if the related domain pad +slect 3.0v, then the pin can output 3.0v. "system control" is used +to choose one function (like: UART0) for which system, since we +have several systems (AP/CP/CM4) on one SoC.). + +There are too much various configuration that we can not list all +of them, so we can not make every Spreadtrum-special configuration +as one generic configuration, and maybe it will add more strange +global configuration in future. Then we add one "sprd,control" to +set these various global control configuration, and we need use +magic number for this property. + +Moreover we recognise every fields comprising one bit or several +bits in one global control register as one pin, thus we should +record every pin's bit offset, bit width and register offset to +configure this field (pin). + +The second block comprises some common registers which have unified +register definition, and each register described one pin is used +to configure the pin sleep mode, function select and sleep related +configuration. + +Now we have 4 systems for sleep mode on SC9860 SoC: AP system, +PUBCP system, TGLDSP system and AGDSP system. And the pin sleep +related configuration are: +- input-enable +- input-disable +- output-high +- output-low +- bias-pull-up +- bias-pull-down + +In some situation we need set the pin sleep mode and pin sleep related +configuration, to set the pin sleep related configuration automatically +by hardware when the system specified by sleep mode goes into deep +sleep mode. For example, if we set the pin sleep mode as PUBCP_SLEEP +and set the pin sleep related configuration as "input-enable", which +means when PUBCP system goes into deep sleep mode, this pin will be set +input enable automatically. + +Moreover we can not use the "sleep" state, since some systems (like: +PUBCP system) do not run linux kernel OS (only AP system run linux +kernel on SC9860 platform), then we can not select "sleep" state +when the PUBCP system goes into deep sleep mode. Thus we introduce +"sprd,sleep-mode" property to set pin sleep mode. + +The last block comprises some misc registers which also have unified +register definition, and each register described one pin is used to +configure drive strength, pull up/down and so on. Especially for pull +up, we have two kind pull up resistor: 20K and 4.7K. + +Required properties for Spreadtrum pin controller: +- compatible: "sprd,-pinctrl" + Please refer to each sprd,-pinctrl.txt binding doc for supported SoCs. +- reg: The register address of pin controller device. +- pins : An array of pin names. + +Optional properties: +- function: Specified the function name. +- drive-strength: Drive strength in mA. +- input-schmitt-disable: Enable schmitt-trigger mode. +- input-schmitt-enable: Disable schmitt-trigger mode. +- bias-disable: Disable pin bias. +- bias-pull-down: Pull down on pin. +- bias-pull-up: Pull up on pin. +- input-enable: Enable pin input. +- input-disable: Enable pin output. +- output-high: Set the pin as an output level high. +- output-low: Set the pin as an output level low. +- sleep-hardware-state: Indicate these configs in this state are sleep related. +- sprd,control: Control values referring to databook for global control pins. +- sprd,sleep-mode: Sleep mode selection. + +Please refer to each sprd,-pinctrl.txt binding doc for supported values. diff --git a/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt new file mode 100644 index 000000000000..5a628333d52f --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/sprd,sc9860-pinctrl.txt @@ -0,0 +1,70 @@ +* Spreadtrum SC9860 Pin Controller + +Please refer to sprd,pinctrl.txt in this directory for common binding part +and usage. + +Required properties: +- compatible: Must be "sprd,sc9860-pinctrl". +- reg: The register address of pin controller device. +- pins : An array of strings, each string containing the name of a pin. + +Optional properties: +- function: A string containing the name of the function, values must be + one of: "func1", "func2", "func3" and "func4". +- drive-strength: Drive strength in mA. Supported values: 2, 4, 6, 8, 10, + 12, 14, 16, 20, 21, 24, 25, 27, 29, 31 and 33. +- input-schmitt-disable: Enable schmitt-trigger mode. +- input-schmitt-enable: Disable schmitt-trigger mode. +- bias-disable: Disable pin bias. +- bias-pull-down: Pull down on pin. +- bias-pull-up: Pull up on pin. Supported values: 20000 for pull-up resistor + is 20K and 4700 for pull-up resistor is 4.7K. +- input-enable: Enable pin input. +- input-disable: Enable pin output. +- output-high: Set the pin as an output level high. +- output-low: Set the pin as an output level low. +- sleep-hardware-state: Indicate these configs in this state are sleep related. +- sprd,control: Control values referring to databook for global control pins. +- sprd,sleep-mode: Choose the pin sleep mode, and supported values are: + AP_SLEEP, PUBCP_SLEEP, TGLDSP_SLEEP and AGDSP_SLEEP. + +Pin sleep mode definition: +enum pin_sleep_mode { + AP_SLEEP = BIT(0), + PUBCP_SLEEP = BIT(1), + TGLDSP_SLEEP = BIT(2), + AGDSP_SLEEP = BIT(3), +}; + +Example: +pin_controller: pinctrl@402a0000 { + compatible = "sprd,sc9860-pinctrl"; + reg = <0x402a0000 0x10000>; + + grp1: sd0 { + pins = "SC9860_VIO_SD2_IRTE", "SC9860_VIO_SD0_IRTE"; + sprd,control = <0x1>; + }; + + grp2: rfctl_33 { + pins = "SC9860_RFCTL33"; + function = "func2"; + sprd,sleep-mode = ; + grp2_sleep_mode: rfctl_33_sleep { + pins = "SC9860_RFCTL33"; + sleep-hardware-state; + output-low; + } + }; + + grp3: rfctl_misc_20 { + pins = "SC9860_RFCTL20_MISC"; + drive-strength = <10>; + bias-pull-up = <4700>; + grp3_sleep_mode: rfctl_misc_sleep { + pins = "SC9860_RFCTL20_MISC"; + sleep-hardware-state; + bias-pull-up; + } + }; +}; diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt index d907a74f8dc0..33e3d3c47552 100644 --- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.txt @@ -180,5 +180,4 @@ pin-controller { &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/power/power-controller.txt b/Documentation/devicetree/bindings/power/power-controller.txt index 4f7a3bc9c407..e45affea8078 100644 --- a/Documentation/devicetree/bindings/power/power-controller.txt +++ b/Documentation/devicetree/bindings/power/power-controller.txt @@ -13,6 +13,5 @@ Example: act8846: act8846@5 { compatible = "active-semi,act8846"; - status = "okay"; system-power-controller; } diff --git a/Documentation/devicetree/bindings/power/renesas,apmu.txt b/Documentation/devicetree/bindings/power/renesas,apmu.txt index 84404c9edff7..af21502e939c 100644 --- a/Documentation/devicetree/bindings/power/renesas,apmu.txt +++ b/Documentation/devicetree/bindings/power/renesas,apmu.txt @@ -1,12 +1,13 @@ DT bindings for the Renesas Advanced Power Management Unit -Renesas R-Car line of SoCs utilize one or more APMU hardware units +Renesas R-Car and RZ/G1 SoCs utilize one or more APMU hardware units for CPU core power domain control including SMP boot and CPU Hotplug. Required properties: - compatible: Should be "renesas,-apmu", "renesas,apmu" as fallback. Examples with soctypes are: + - "renesas,r8a7743-apmu" (RZ/G1M) - "renesas,r8a7790-apmu" (R-Car H2) - "renesas,r8a7791-apmu" (R-Car M2-W) - "renesas,r8a7792-apmu" (R-Car V2H) diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index d91715bc8d52..98cc8c09d02d 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -17,6 +17,7 @@ Required properties: - "renesas,r8a7794-sysc" (R-Car E2) - "renesas,r8a7795-sysc" (R-Car H3) - "renesas,r8a7796-sysc" (R-Car M3-W) + - "renesas,r8a77995-sysc" (R-Car D3) - reg: Address start and address range for the device. - #power-domain-cells: Must be 1. diff --git a/Documentation/devicetree/bindings/power/reset/st-reset.txt b/Documentation/devicetree/bindings/power/reset/st-reset.txt index 83734dc3a389..b63948737d80 100644 --- a/Documentation/devicetree/bindings/power/reset/st-reset.txt +++ b/Documentation/devicetree/bindings/power/reset/st-reset.txt @@ -8,5 +8,4 @@ Example node: restart { compatible = "st,stih407-restart"; st,syscfg = <&syscfg_sbc_reg>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt index 43c21fb04564..4a4766e9c254 100644 --- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt +++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt @@ -39,6 +39,8 @@ Required properties: - "rockchip,rk3368-pmu-io-voltage-domain" for rk3368 pmu-domains - "rockchip,rk3399-io-voltage-domain" for rk3399 - "rockchip,rk3399-pmu-io-voltage-domain" for rk3399 pmu-domains + - "rockchip,rv1108-io-voltage-domain" for rv1108 + - "rockchip,rv1108-pmu-io-voltage-domain" for rv1108 pmu-domains Deprecated properties: - rockchip,grf: phandle to the syscon managing the "general register files" diff --git a/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt b/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt index de78d761ce44..b86ecada4f84 100644 --- a/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/act8945a-charger.txt @@ -29,7 +29,6 @@ Example: pmic@5b { compatible = "active-semi,act8945a"; reg = <0x5b>; - status = "okay"; charger { compatible = "active-semi,act8945a-charger"; @@ -43,6 +42,5 @@ Example: active-semi,input-voltage-threshold-microvolt = <6600>; active-semi,precondition-timeout = <40>; active-semi,total-timeout = <3>; - status = "okay"; }; }; diff --git a/Documentation/devicetree/bindings/power/supply/bq24190.txt b/Documentation/devicetree/bindings/power/supply/bq24190.txt new file mode 100644 index 000000000000..9e517d307070 --- /dev/null +++ b/Documentation/devicetree/bindings/power/supply/bq24190.txt @@ -0,0 +1,51 @@ +TI BQ24190 Li-Ion Battery Charger + +Required properties: +- compatible: contains one of the following: + * "ti,bq24190" + * "ti,bq24192i" +- reg: integer, I2C address of the charger. +- interrupts[-extended]: configuration for charger INT pin. + +Optional properties: +- monitored-battery: phandle of battery characteristics devicetree node + The charger uses the following battery properties: + + precharge-current-microamp: maximum charge current during precharge + phase (typically 20% of battery capacity). + + charge-term-current-microamp: a charge cycle terminates when the + battery voltage is above recharge threshold, and the current is below + this setting (typically 10% of battery capacity). + See also Documentation/devicetree/bindings/power/supply/battery.txt +- ti,system-minimum-microvolt: when power is connected and the battery is below + minimum system voltage, the system will be regulated above this setting. + +Notes: +- Some circuit boards wire the chip's "OTG" pin high (enabling 500mA default + charge current on USB SDP ports, among other features). To simulate this on + boards that wire the pin to a GPIO, set a gpio-hog. + +Example: + + bat: battery { + compatible = "simple-battery"; + precharge-current-microamp = <256000>; + charge-term-current-microamp = <128000>; + // etc. + }; + + bq24190: charger@6a { + compatible = "ti,bq24190"; + reg = <0x6a>; + interrupts-extended = <&gpiochip 10 IRQ_TYPE_EDGE_FALLING>; + monitored-battery = <&bat>; + ti,system-minimum-microvolt = <3200000>; + }; + + &twl_gpio { + otg { + gpio-hog; + gpios = <6 0>; + output-high; + line-name = "otg-gpio"; + }; + }; diff --git a/Documentation/devicetree/bindings/power/supply/ltc2941.txt b/Documentation/devicetree/bindings/power/supply/ltc2941.txt index a9d7aa60558b..3b9ba147b041 100644 --- a/Documentation/devicetree/bindings/power/supply/ltc2941.txt +++ b/Documentation/devicetree/bindings/power/supply/ltc2941.txt @@ -1,13 +1,14 @@ -binding for LTC2941 and LTC2943 battery gauges +binding for LTC2941, LTC2942, LTC2943 and LTC2944 battery gauges -Both the LTC2941 and LTC2943 measure battery capacity. -The LTC2943 is compatible with the LTC2941, it adds voltage and -temperature monitoring, and uses a slightly different conversion -formula for the charge counter. +All chips measure battery capacity. +The LTC2942 is pin compatible with the LTC2941, it adds voltage and +temperature monitoring, and is runtime detected. LTC2943 and LTC2944 +is software compatible, uses a slightly different conversion formula +for the charge counter and adds voltage, current and temperature monitoring. Required properties: -- compatible: Should contain "lltc,ltc2941" or "lltc,ltc2943" which also - indicates the type of I2C chip attached. +- compatible: Should contain "lltc,ltc2941", "lltc,ltc2942", "lltc,ltc2943" + or "lltc,ltc2944" which also indicates the type of I2C chip attached. - reg: The 7-bit I2C address. - lltc,resistor-sense: The sense resistor value in milli-ohms. Can be a 32-bit negative value when the battery has been connected to the wrong end of the diff --git a/Documentation/devicetree/bindings/power/supply/max8903-charger.txt b/Documentation/devicetree/bindings/power/supply/max8903-charger.txt index f0f4e12b076e..bab947fef025 100644 --- a/Documentation/devicetree/bindings/power/supply/max8903-charger.txt +++ b/Documentation/devicetree/bindings/power/supply/max8903-charger.txt @@ -21,5 +21,4 @@ Example: flt-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; chg-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>; cen-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt b/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt index e03e85ae6572..d6e8dfd0a581 100644 --- a/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt +++ b/Documentation/devicetree/bindings/power/supply/maxim,max14656.txt @@ -12,7 +12,6 @@ Example: clock-frequency = <50000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; - status = "okay"; max14656@35 { compatible = "maxim,max14656"; diff --git a/Documentation/devicetree/bindings/power/wakeup-source.txt b/Documentation/devicetree/bindings/power/wakeup-source.txt index 963c6dfd484d..3c81f78b5c27 100644 --- a/Documentation/devicetree/bindings/power/wakeup-source.txt +++ b/Documentation/devicetree/bindings/power/wakeup-source.txt @@ -20,13 +20,12 @@ List of legacy properties and respective binding document 1. "enable-sdio-wakeup" Documentation/devicetree/bindings/mmc/mmc.txt 2. "gpio-key,wakeup" Documentation/devicetree/bindings/input/gpio-keys{,-polled}.txt 3. "has-tpo" Documentation/devicetree/bindings/rtc/rtc-opal.txt -4. "isil,irq2-can-wakeup-machine" Documentation/devicetree/bindings/rtc/isil,isl12057.txt -5. "linux,wakeup" Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt +4. "linux,wakeup" Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt Documentation/devicetree/bindings/mfd/tc3589x.txt Documentation/devicetree/bindings/input/ads7846.txt -6. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt -7. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung-keypad.txt -8. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt +5. "linux,keypad-wakeup" Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt +6. "linux,input-wakeup" Documentation/devicetree/bindings/input/samsung-keypad.txt +7. "nvidia,wakeup-source" Documentation/devicetree/bindings/input/nvidia,tegra20-kbc.txt Examples -------- diff --git a/Documentation/devicetree/bindings/powerpc/ibm,vas.txt b/Documentation/devicetree/bindings/powerpc/ibm,vas.txt new file mode 100644 index 000000000000..bf11d2faf7b8 --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/ibm,vas.txt @@ -0,0 +1,22 @@ +* IBM Powerpc Virtual Accelerator Switchboard (VAS) + +VAS is a hardware mechanism that allows kernel subsystems and user processes +to directly submit compression and other requests to Nest accelerators (NX) +or other coprocessors functions. + +Required properties: +- compatible : should be "ibm,vas". +- ibm,vas-id : A unique identifier for each instance of VAS in the system +- reg : Should contain 4 pairs of 64-bit fields specifying the Hypervisor + window context start and length, OS/User window context start and length, + "Paste address" start and length, "Paste window id" start bit and number + of bits) + +Example: + + vas@6019100000000 { + compatible = "ibm,vas", "ibm,power9-vas"; + reg = <0x6019100000000 0x2000000 0x6019000000000 0x100000000 0x8000000000000 0x100000000 0x20 0x10>; + name = "vas"; + ibm,vas-id = <0x1>; + }; diff --git a/Documentation/devicetree/bindings/powerpc/opal/sensor-groups.txt b/Documentation/devicetree/bindings/powerpc/opal/sensor-groups.txt new file mode 100644 index 000000000000..6ad881cbffda --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/opal/sensor-groups.txt @@ -0,0 +1,27 @@ +IBM OPAL Sensor Groups Binding +------------------------------- + +Node: /ibm,opal/sensor-groups + +Description: Contains sensor groups available in the Powernv P9 +servers. Each child node indicates a sensor group. + +- compatible : Should be "ibm,opal-sensor-group" + +Each child node contains below properties: + +- type : String to indicate the type of sensor-group + +- sensor-group-id: Abstract unique identifier provided by firmware of + type which is used for sensor-group + operations like clearing the min/max history of all + sensors belonging to the group. + +- ibm,chip-id : Chip ID + +- sensors : Phandle array of child nodes of /ibm,opal/sensor/ + belonging to this group + +- ops : Array of opal-call numbers indicating available operations on + sensor groups like clearing min/max, enabling/disabling sensor + group. diff --git a/Documentation/devicetree/bindings/pps/pps-gpio.txt b/Documentation/devicetree/bindings/pps/pps-gpio.txt index 40bf9c3564a5..0de23b793657 100644 --- a/Documentation/devicetree/bindings/pps/pps-gpio.txt +++ b/Documentation/devicetree/bindings/pps/pps-gpio.txt @@ -13,8 +13,12 @@ Optional properties: Example: pps { - compatible = "pps-gpio"; - gpios = <&gpio2 6 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pps>; + gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; assert-falling-edge; + + compatible = "pps-gpio"; + status = "okay"; }; diff --git a/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt b/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt index 7c04e22a5d6a..6b1075ee8a30 100644 --- a/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt +++ b/Documentation/devicetree/bindings/ptp/brcm,ptp-dte.txt @@ -16,5 +16,4 @@ Example: ptp: ptp-dte@180af650 { compatible = "brcm,iproc-ptp-dte", "brcm,ptp-dte"; reg = <0x180af650 0x10>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt index cf573e85b11d..8cf87d1bfca5 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-bcm2835.txt @@ -6,7 +6,7 @@ Required properties: - clocks: This clock defines the base clock frequency of the PWM hardware system, the period and the duty_cycle of the PWM signal is a multiple of the base period. -- #pwm-cells: Should be 2. See pwm.txt in this directory for a description of +- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of the cells format. Examples: @@ -15,7 +15,7 @@ pwm@2020c000 { compatible = "brcm,bcm2835-pwm"; reg = <0x2020c000 0x28>; clocks = <&clk_pwm>; - #pwm-cells = <2>; + #pwm-cells = <3>; }; clocks { diff --git a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt index 54c59b0560ad..ef8bd3cb67ab 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-mediatek.txt @@ -2,6 +2,8 @@ MediaTek PWM controller Required properties: - compatible: should be "mediatek,-pwm": + - "mediatek,mt2712-pwm": found on mt2712 SoC. + - "mediatek,mt7622-pwm": found on mt7622 SoC. - "mediatek,mt7623-pwm": found on mt7623 SoC. - reg: physical base address and length of the controller's registers. - #pwm-cells: must be 2. See pwm.txt in this directory for a description of @@ -10,7 +12,9 @@ Required properties: - clock-names: must contain the following: - "top": the top clock generator - "main": clock used by the PWM core - - "pwm1-5": the five per PWM clocks + - "pwm1-8": the eight per PWM clocks for mt2712 + - "pwm1-6": the six per PWM clocks for mt7622 + - "pwm1-5": the five per PWM clocks for mt7623 - pinctrl-names: Must contain a "default" entry. - pinctrl-0: One property must exist for each entry in pinctrl-names. See pinctrl/pinctrl-bindings.txt for details of the property values. diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt index 5b07bebbf6f7..1ee81321c35e 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-meson.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-meson.txt @@ -19,7 +19,6 @@ Example: compatible = "amlogic,meson-gxbb-pwm"; reg = <0x0 0x08550 0x0 0x10>; #pwm-cells = <3>; - status = "disabled"; clocks = <&xtal>, <&xtal>; clock-names = "clkin0", "clkin1"; } diff --git a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt index b8be3d09ee26..2c5e52a5bede 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-rockchip.txt @@ -3,10 +3,17 @@ Rockchip PWM controller Required properties: - compatible: should be "rockchip,-pwm" "rockchip,rk2928-pwm": found on RK29XX,RK3066 and RK3188 SoCs - "rockchip,rk3288-pwm": found on RK3288 SoC + "rockchip,rk3288-pwm": found on RK3288 SOC + "rockchip,rv1108-pwm", "rockchip,rk3288-pwm": found on RV1108 SoC "rockchip,vop-pwm": found integrated in VOP on RK3288 SoC - reg: physical base address and length of the controller's registers - - clocks: phandle and clock specifier of the PWM reference clock + - clocks: See ../clock/clock-bindings.txt + - For older hardware (rk2928, rk3066, rk3188, rk3228, rk3288, rk3399): + - There is one clock that's used both to derive the functional clock + for the device and as the bus clock. + - For newer hardware (rk3328 and future socs): specified by name + - "pwm": This is used to derive the functional clock. + - "pclk": This is the APB bus clock. - #pwm-cells: must be 2 (rk2928) or 3 (rk3288). See pwm.txt in this directory for a description of the cell format. diff --git a/Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt b/Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt new file mode 100644 index 000000000000..f8338d11fd2b --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt @@ -0,0 +1,24 @@ +STMicroelectronics STM32 Low-Power Timer PWM + +STM32 Low-Power Timer provides single channel PWM. + +Must be a sub-node of an STM32 Low-Power Timer device tree node. +See ../mfd/stm32-lptimer.txt for details about the parent node. + +Required parameters: +- compatible: Must be "st,stm32-pwm-lp". + +Optional properties: +- pinctrl-names: Set to "default". +- pinctrl-0: Phandle pointing to pin configuration node for PWM. + +Example: + timer@40002400 { + compatible = "st,stm32-lptimer"; + ... + pwm { + compatible = "st,stm32-pwm-lp"; + pinctrl-names = "default"; + pinctrl-0 = <&lppwm1_pins>; + }; + }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt index f1cbeefb3087..c5171660eaf9 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-sun4i.txt @@ -19,5 +19,4 @@ Example: reg = <0x01c20e00 0xc>; clocks = <&osc24M>; #pwm-cells = <3>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt index 8007e839a716..06a363d9ccef 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt @@ -6,6 +6,7 @@ Required properties: for am4372 - compatible = "ti,am4372-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; for da850 - compatible = "ti,da850-ecap", "ti,am3352-ecap", "ti,am33xx-ecap"; for dra746 - compatible = "ti,dra746-ecap", "ti,am3352-ecap"; + for 66ak2g - compatible = "ti,k2g-ecap", "ti,am3352-ecap"; - #pwm-cells: should be 3. See pwm.txt in this directory for a description of the cells format. The PWM channel index ranges from 0 to 4. The only third cell flag supported by this binding is PWM_POLARITY_INVERTED. diff --git a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt index 1a5d7b71db89..4633697fbda1 100644 --- a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt +++ b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt @@ -26,7 +26,6 @@ epwmss0: epwmss@48300000 { /* PWMSS for am33xx */ ti,hwmods = "epwmss0"; #address-cells = <1>; #size-cells = <1>; - status = "disabled"; ranges = <0x48300100 0x48300100 0x80 /* ECAP */ 0x48300180 0x48300180 0x80 /* EQEP */ 0x48300200 0x48300200 0x80>; /* EHRPWM */ @@ -40,7 +39,6 @@ epwmss0: epwmss@48300000 { /* PWMSS for am4372 */ ti,hwmods = "epwmss0"; #address-cells = <1>; #size-cells = <1>; - status = "disabled"; ranges = <0x48300100 0x48300100 0x80 /* ECAP */ 0x48300180 0x48300180 0x80 /* EQEP */ 0x48300200 0x48300200 0x80>; /* EHRPWM */ diff --git a/Documentation/devicetree/bindings/pwm/pwm-zx.txt b/Documentation/devicetree/bindings/pwm/pwm-zx.txt new file mode 100644 index 000000000000..a6bcc75c9164 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/pwm-zx.txt @@ -0,0 +1,22 @@ +ZTE ZX PWM controller + +Required properties: + - compatible: Should be "zte,zx296718-pwm". + - reg: Physical base address and length of the controller's registers. + - clocks : The phandle and specifier referencing the controller's clocks. + - clock-names: "pclk" for PCLK, "wclk" for WCLK to the PWM controller. The + PCLK is for register access, while WCLK is the reference clock for + calculating period and duty cycles. + - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of + the cells format. + +Example: + + pwm: pwm@1439000 { + compatible = "zte,zx296718-pwm"; + reg = <0x1439000 0x1000>; + clocks = <&lsp1crm LSP1_PWM_PCLK>, + <&lsp1crm LSP1_PWM_WCLK>; + clock-names = "pclk", "wclk"; + #pwm-cells = <3>; + }; diff --git a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt index b067e84a94b5..1aadc804dae4 100644 --- a/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt +++ b/Documentation/devicetree/bindings/pwm/renesas,tpu-pwm.txt @@ -6,7 +6,6 @@ Required Properties: - "renesas,tpu-r8a73a4": for R8A77A4 (R-Mobile APE6) compatible PWM controller. - "renesas,tpu-r8a7740": for R8A7740 (R-Mobile A1) compatible PWM controller. - "renesas,tpu-r8a7790": for R8A7790 (R-Car H2) compatible PWM controller. - - "renesas,tpu-sh7372": for SH7372 (SH-Mobile AP4) compatible PWM controller. - "renesas,tpu": for generic R-Car TPU PWM controller. - reg: Base address and length of each memory resource used by the PWM diff --git a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt index 6067d9830d07..3ae9f1088845 100644 --- a/Documentation/devicetree/bindings/regulator/act8865-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8865-regulator.txt @@ -52,7 +52,6 @@ Example: compatible = "active-semi,act8865"; reg = <0x5b>; active-semi,vsel-high; - status = "disabled"; regulators { vcc_1v8_reg: DCDC_REG1 { diff --git a/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt b/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt index 5c80a7779552..ac955dea00d1 100644 --- a/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/act8945a-regulator.txt @@ -23,7 +23,6 @@ Example: pmic@5b { compatible = "active-semi,act8945a"; reg = <0x5b>; - status = "okay"; active-semi,vsel-high; diff --git a/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt index 02649d8b3f5a..84d544d8c1b1 100644 --- a/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mt6311-regulator.txt @@ -1,4 +1,4 @@ -Mediatek MT6311 Regulator Driver +Mediatek MT6311 Regulator Required properties: - compatible: "mediatek,mt6311-regulator" diff --git a/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt index c35d878b0960..a48749db4df3 100644 --- a/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mt6323-regulator.txt @@ -1,4 +1,4 @@ -Mediatek MT6323 Regulator Driver +Mediatek MT6323 Regulator All voltage regulators are defined as subnodes of the regulators node. A list of regulators provided by this controller are defined as subnodes of the diff --git a/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt new file mode 100644 index 000000000000..0058441f16d2 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt @@ -0,0 +1,89 @@ +MediaTek MT6380 Regulator + +All voltage regulators provided by the MT6380 PMIC are described as the +subnodes of the MT6380 regulators node. Each regulator is named according +to its regulator type, buck- and ldo-. The definition for each +of these nodes is defined using the standard binding for regulators at +Documentation/devicetree/bindings/regulator/regulator.txt. + +The valid names for regulators are: +BUCK: + buck-core1, buck-vcore, buck-vrf +LDO: + ldo-vm ,ldo-va , ldo-vphy, ldo-vddr, ldo-vt + +Example: + + regulators { + compatible = "mediatek,mt6380-regulator"; + + mt6380_vcpu_reg: buck-vcore1 { + regulator-name = "vcore1"; + regulator-min-microvolt = < 600000>; + regulator-max-microvolt = <1393750>; + regulator-ramp-delay = <6250>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vcore_reg: buck-vcore { + regulator-name = "vcore"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1393750>; + regulator-ramp-delay = <6250>; + }; + + mt6380_vrf_reg: buck-vrf { + regulator-name = "vrf"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1575000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vm_reg: ldo-vm { + regulator-name = "vm"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1400000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_va_reg: ldo-va { + regulator-name = "va"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vphy_reg: ldo-vphy { + regulator-name = "vphy"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vddr_reg: ldo-vddr { + regulator-name = "vddr"; + regulator-min-microvolt = <1240000>; + regulator-max-microvolt = <1840000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + mt6380_vt_reg: ldo-vt { + regulator-name = "vt"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt index a42b1d6e9863..01141fb00875 100644 --- a/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/mt6397-regulator.txt @@ -1,4 +1,4 @@ -Mediatek MT6397 Regulator Driver +Mediatek MT6397 Regulator Required properties: - compatible: "mediatek,mt6397-regulator" diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt index bf85aa9ad6a7..3d78d507e29f 100644 --- a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt @@ -71,7 +71,7 @@ Continuous Voltage With Enable GPIO Example: * Inverted PWM logic, and the duty cycle range is limited * to 30%-70%. */ - pwm-dutycycle-range <700 300>; /* */ + pwm-dutycycle-range = <700 300>; /* */ }; Voltage Table Example: diff --git a/Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.txt b/Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.txt new file mode 100644 index 000000000000..3944ee3e731e --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.txt @@ -0,0 +1,20 @@ +STM32 VREFBUF - Voltage reference buffer + +Some STM32 devices embed a voltage reference buffer which can be used as +voltage reference for ADCs, DACs and also as voltage reference for external +components through the dedicated VREF+ pin. + +Required properties: +- compatible: Must be "st,stm32-vrefbuf". +- reg: Offset and length of VREFBUF register set. +- clocks: Must contain an entry for peripheral clock. + +Example: + vrefbuf: regulator@58003C00 { + compatible = "st,stm32-vrefbuf"; + reg = <0x58003C00 0x8>; + clocks = <&rcc VREF_CK>; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2500000>; + vdda-supply = <&vdda>; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt new file mode 100644 index 000000000000..fbcefd965dc4 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/imx-rproc.txt @@ -0,0 +1,33 @@ +NXP iMX6SX/iMX7D Co-Processor Bindings +---------------------------------------- + +This binding provides support for ARM Cortex M4 Co-processor found on some +NXP iMX SoCs. + +Required properties: +- compatible Should be one of: + "fsl,imx7d-cm4" + "fsl,imx6sx-cm4" +- clocks Clock for co-processor (See: ../clock/clock-bindings.txt) +- syscon Phandle to syscon block which provide access to + System Reset Controller + +Optional properties: +- memory-region list of phandels to the reserved memory regions. + (See: ../reserved-memory/reserved-memory.txt) + +Example: + m4_reserved_sysmem1: cm4@80000000 { + reg = <0x80000000 0x80000>; + }; + + m4_reserved_sysmem2: cm4@81000000 { + reg = <0x81000000 0x80000>; + }; + + imx7d-cm4 { + compatible = "fsl,imx7d-cm4"; + memory-region = <&m4_reserved_sysmem1>, <&m4_reserved_sysmem2>; + syscon = <&src>; + clocks = <&clks IMX7D_ARM_M4_ROOT_CLK>; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt index 75ad7b8df0b1..728e4193f7a6 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt @@ -63,9 +63,10 @@ on the Qualcomm ADSP Hexagon core. = SUBNODES -The adsp node may have an subnode named "smd-edge" that describes the SMD edge, -channels and devices related to the ADSP. See ../soc/qcom/qcom,smd.txt for -details on how to describe the SMD edge. +The adsp node may have an subnode named either "smd-edge" or "glink-edge" that +describes the communication edge, channels and devices related to the ADSP. +See ../soc/qcom/qcom,smd.txt and ../soc/qcom/qcom,glink.txt for details on how +to describe these. = EXAMPLE diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt index 92347fe6890e..7ff3f7903f26 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt +++ b/Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt @@ -90,6 +90,11 @@ the memory regions used by the Hexagon firmware. Each sub-node must contain: Value type: Definition: reference to the reserved-memory for the region +The Hexagon node may also have an subnode named either "smd-edge" or +"glink-edge" that describes the communication edge, channels and devices +related to the Hexagon. See ../soc/qcom/qcom,smd.txt and +../soc/qcom/qcom,glink.txt for details on how to describe these. + = EXAMPLE The following example describes the resources needed to boot control the Hexagon, as it is found on MSM8974 boards. diff --git a/Documentation/devicetree/bindings/remoteproc/ti,davinci-rproc.txt b/Documentation/devicetree/bindings/remoteproc/ti,davinci-rproc.txt new file mode 100644 index 000000000000..e44a97e21164 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/ti,davinci-rproc.txt @@ -0,0 +1,86 @@ +TI Davinci DSP devices +======================= + +Binding status: Unstable - Subject to changes for DT representation of clocks + and resets + +The TI Davinci family of SoCs usually contains a TI DSP Core sub-system that +is used to offload some of the processor-intensive tasks or algorithms, for +achieving various system level goals. + +The processor cores in the sub-system usually contain additional sub-modules +like L1 and/or L2 caches/SRAMs, an Interrupt Controller, an external memory +controller, a dedicated local power/sleep controller etc. The DSP processor +core used in Davinci SoCs is usually a C674x DSP CPU. + +DSP Device Node: +================ +Each DSP Core sub-system is represented as a single DT node. + +Required properties: +-------------------- +The following are the mandatory properties: + +- compatible: Should be one of the following, + "ti,da850-dsp" for DSPs on OMAP-L138 SoCs + +- reg: Should contain an entry for each value in 'reg-names'. + Each entry should have the memory region's start address + and the size of the region, the representation matching + the parent node's '#address-cells' and '#size-cells' values. + +- reg-names: Should contain strings with the following names, each + representing a specific internal memory region or a + specific register space, + "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig_base" + +- interrupts: Should contain the interrupt number used to receive the + interrupts from the DSP. The value should follow the + interrupt-specifier format as dictated by the + 'interrupt-parent' node. + +- memory-region: phandle to the reserved memory node to be associated + with the remoteproc device. The reserved memory node + can be a CMA memory node, and should be defined as + per the bindings in + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt + +Optional properties: +-------------------- +- interrupt-parent: phandle to the interrupt controller node. This property + is needed if the device node hierarchy doesn't have an + interrupt controller. + + +Example: +-------- + + /* DSP Reserved Memory node */ + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + dsp_memory_region: dsp-memory@c3000000 { + compatible = "shared-dma-pool"; + reg = <0xc3000000 0x1000000>; + reusable; + }; + }; + + /* DSP node */ + { + dsp: dsp@11800000 { + compatible = "ti,da850-dsp"; + reg = <0x11800000 0x40000>, + <0x11e00000 0x8000>, + <0x11f00000 0x8000>, + <0x01c14044 0x4>, + <0x01c14174 0x8>; + reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", + "chipsig"; + interrupt-parent = <&intc>; + interrupts = <28>; + memory-region = <&dsp_memory_region>; + }; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt index 2aac1aa4123d..1eb72874130b 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt +++ b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt @@ -26,6 +26,7 @@ The following are the mandatory properties: "ti,k2hk-dsp" for DSPs on Keystone 2 66AK2H/K SoCs "ti,k2l-dsp" for DSPs on Keystone 2 66AK2L SoCs "ti,k2e-dsp" for DSPs on Keystone 2 66AK2E SoCs + "ti,k2g-dsp" for DSPs on Keystone 2 66AK2G SoCs - reg: Should contain an entry for each value in 'reg-names'. Each entry should have the memory region's start address @@ -37,20 +38,18 @@ The following are the mandatory properties: should be defined in this order, "l2sram", "l1pram", "l1dram" -- clocks: Should contain the device's input clock, and should be - defined as per the bindings in, - Documentation/devicetree/bindings/clock/keystone-gate.txt - - ti,syscon-dev: Should be a pair of the phandle to the Keystone Device State Control node, and the register offset of the DSP boot address register within that node's address space. - resets: Should contain the phandle to the reset controller node managing the resets for this device, and a reset - specifier. Please refer to the following reset bindings - for the reset argument specifier as per SoC, + specifier. Please refer to either of the following reset + bindings for the reset argument specifier as per SoC, Documentation/devicetree/bindings/reset/ti-syscon-reset.txt - for 66AK2HK/66AK2L/66AK2E SoCs + for 66AK2HK/66AK2L/66AK2E SoCs or, + Documentation/devicetree/bindings/reset/ti,sci-reset.txt + for 66AK2G SoCs - interrupt-parent: Should contain a phandle to the Keystone 2 IRQ controller IP node that is used by the ARM CorePac processor to @@ -75,6 +74,22 @@ The following are the mandatory properties: The gpio device to be used is as per the bindings in, Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt +SoC-specific Required properties: +--------------------------------- +The following are mandatory properties for Keystone 2 66AK2HK, 66AK2L and 66AK2E +SoCs only: + +- clocks: Should contain the device's input clock, and should be + defined as per the bindings in, + Documentation/devicetree/bindings/clock/keystone-gate.txt + +The following are mandatory properties for Keystone 2 66AK2G SoCs only: + +- power-domains: Should contain a phandle to a PM domain provider node + and an args specifier containing the DSP device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt + Optional properties: -------------------- @@ -85,8 +100,10 @@ Optional properties: Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt -Example: --------- +Examples: +--------- + +1. /* 66AK2H/K DSP aliases */ aliases { rproc0 = &dsp0; @@ -131,3 +148,41 @@ Example: }; }; + +2. + /* 66AK2G DSP alias */ + aliases { + rproc0 = &dsp0; + }; + + /* 66AK2G DSP memory node */ + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + }; + }; + + /* 66AK2G DSP node */ + soc { + dsp0: dsp@10800000 { + compatible = "ti,k2g-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + power-domains = <&k2g_pds 0x0046>; + ti,syscon-dev = <&devctrl 0x40>; + resets = <&k2g_reset 0x0046 0x1>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + memory-region = <&dsp_common_memory>; + }; + }; diff --git a/Documentation/devicetree/bindings/reset/lantiq,reset.txt b/Documentation/devicetree/bindings/reset/lantiq,reset.txt new file mode 100644 index 000000000000..c6aef36b7d15 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/lantiq,reset.txt @@ -0,0 +1,30 @@ +Lantiq XWAY SoC RCU reset controller binding +============================================ + +This binding describes a reset-controller found on the RCU module on Lantiq +XWAY SoCs. + +This node has to be a sub node of the Lantiq RCU block. + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,danube-reset" + "lantiq,xrx200-reset" +- reg : Defines the following sets of registers in the parent + syscon device + - Offset of the reset set register + - Offset of the reset status register +- #reset-cells : Specifies the number of cells needed to encode the + reset line, should be 2. + The first cell takes the reset set bit and the + second cell takes the status bit. + +------------------------------------------------------------------------------- +Example for the reset-controllers on the xRX200 SoCs: + reset0: reset-controller@10 { + compatible = "lantiq,xrx200-reset"; + reg <0x10 0x04>, <0x14 0x04>; + + #reset-cells = <2>; + }; diff --git a/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt b/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt index b4e96a278445..05d5be48dae4 100644 --- a/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt +++ b/Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt @@ -80,5 +80,4 @@ mac: ethernet@40010000 { clock-names = "stmmaceth"; resets = <&rgu 22>; reset-names = "stmmaceth"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index fe5e0f37b3c9..e5a03ffe04fb 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -26,6 +26,7 @@ Required properties: - "renesas,r8a7794-rst" (R-Car E2) - "renesas,r8a7795-rst" (R-Car H3) - "renesas,r8a7796-rst" (R-Car M3-W) + - "renesas,r8a77995-rst" (R-Car D3) - reg: Address start and address range for the device. diff --git a/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt b/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt new file mode 100644 index 000000000000..830069b1c37c --- /dev/null +++ b/Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt @@ -0,0 +1,28 @@ +Binding for the Synopsys HSDK reset controller + +This binding uses the common reset binding[1]. + +[1] Documentation/devicetree/bindings/reset/reset.txt + +Required properties: +- compatible: should be "snps,hsdk-reset". +- reg: should always contain 2 pairs address - length: first for reset + configuration register and second for corresponding SW reset and status bits + register. +- #reset-cells: from common reset binding; Should always be set to 1. + +Example: + reset: reset@880 { + compatible = "snps,hsdk-reset"; + #reset-cells = <1>; + reg = <0x8A0 0x4>, <0xFF0 0x4>; + }; + +Specifying reset lines connected to IP modules: + ethernet@.... { + .... + resets = <&reset HSDK_V1_ETH_RESET>; + .... + }; + +The index could be found in diff --git a/Documentation/devicetree/bindings/reset/uniphier-reset.txt b/Documentation/devicetree/bindings/reset/uniphier-reset.txt index 83ab0f599c40..68a6f487c409 100644 --- a/Documentation/devicetree/bindings/reset/uniphier-reset.txt +++ b/Documentation/devicetree/bindings/reset/uniphier-reset.txt @@ -6,7 +6,6 @@ System reset Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-reset" - for sLD3 SoC "socionext,uniphier-ld4-reset" - for LD4 SoC "socionext,uniphier-pro4-reset" - for Pro4 SoC "socionext,uniphier-sld8-reset" - for sLD8 SoC @@ -37,7 +36,6 @@ Media I/O (MIO) reset, SD reset Required properties: - compatible: should be one of the following: - "socionext,uniphier-sld3-mio-reset" - for sLD3 SoC "socionext,uniphier-ld4-mio-reset" - for LD4 SoC "socionext,uniphier-pro4-mio-reset" - for Pro4 SoC "socionext,uniphier-sld8-mio-reset" - for sLD8 SoC @@ -92,3 +90,28 @@ Example: other nodes ... }; + + +Analog signal amplifier reset +----------------------------- + +Required properties: +- compatible: should be one of the following: + "socionext,uniphier-ld11-adamv-reset" - for LD11 SoC + "socionext,uniphier-ld20-adamv-reset" - for LD20 SoC +- #reset-cells: should be 1. + +Example: + + adamv@57920000 { + compatible = "socionext,uniphier-ld11-adamv", + "simple-mfd", "syscon"; + reg = <0x57920000 0x1000>; + + adamv_rst: reset { + compatible = "socionext,uniphier-ld11-adamv-reset"; + #reset-cells = <1>; + }; + + other nodes ... + }; diff --git a/Documentation/devicetree/bindings/rng/imx-rngc.txt b/Documentation/devicetree/bindings/rng/imx-rngc.txt new file mode 100644 index 000000000000..93c7174a7bed --- /dev/null +++ b/Documentation/devicetree/bindings/rng/imx-rngc.txt @@ -0,0 +1,21 @@ +Freescale RNGC (Random Number Generator Version C) + +The driver also supports version B, which is mostly compatible +to version C. + +Required properties: +- compatible : should be one of + "fsl,imx25-rngb" + "fsl,imx35-rngc" +- reg : offset and length of the register set of this block +- interrupts : the interrupt number for the RNGC block +- clocks : the RNGC clk source + +Example: + +rng@53fb0000 { + compatible = "fsl,imx25-rngb"; + reg = <0x53fb0000 0x4000>; + interrupts = <22>; + clocks = <&trng_clk>; +}; diff --git a/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt b/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt new file mode 100644 index 000000000000..634312dd95ca --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt @@ -0,0 +1,17 @@ +Android Goldfish RTC + +Android Goldfish RTC device used by Android emulator. + +Required properties: + +- compatible : should contain "google,goldfish-rtc" +- reg : +- interrupts : + +Example: + + goldfish_timer@9020000 { + compatible = "google,goldfish-rtc"; + reg = <0x9020000 0x1000>; + interrupts = <0x3>; + }; diff --git a/Documentation/devicetree/bindings/rtc/isil,isl12057.txt b/Documentation/devicetree/bindings/rtc/isil,isl12057.txt index cf83e0940302..fbbdd92e5af9 100644 --- a/Documentation/devicetree/bindings/rtc/isil,isl12057.txt +++ b/Documentation/devicetree/bindings/rtc/isil,isl12057.txt @@ -24,7 +24,6 @@ Optional properties: - "wakeup-source": mark the chip as a wakeup source, independently of the availability of an IRQ line connected to the SoC. - (Legacy property supported: "isil,irq2-can-wakeup-machine") - "interrupt-parent", "interrupts": for passing the interrupt line of the SoC connected to IRQ#2 of the RTC chip. diff --git a/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt b/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt new file mode 100644 index 000000000000..bbf1ccb5df31 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/realtek,rtd119x.txt @@ -0,0 +1,16 @@ +Realtek RTD129x Real-Time Clock +=============================== + +Required properties: +- compatible : Should be "realtek,rtd1295-rtc" +- reg : Specifies the physical base address and size +- clocks : Specifies the clock gate + + +Example: + + rtc@9801b600 { + compatible = "realtek,rtd1295-clk"; + reg = <0x9801b600 0x100>; + clocks = <&clkc RTD1295_CLK_EN_MISC_RTC>; + }; diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt index 0a4c371a9b7a..a66692a08ace 100644 --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt @@ -45,5 +45,4 @@ Example: interrupts = <17 1>; interrupt-names = "alarm"; st,syscfg = <&pwrcfg>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt index 945934918b71..d5e26d313f62 100644 --- a/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt +++ b/Documentation/devicetree/bindings/rtc/sun6i-rtc.txt @@ -10,7 +10,7 @@ Required properties: Required properties for new device trees - clocks : phandle to the 32kHz external oscillator -- clock-output-names : name of the LOSC clock created +- clock-output-names : names of the LOSC and its external output clocks created - #clock-cells : must be equals to 1. The RTC provides two clocks: the LOSC and its external output, with index 0 and 1 respectively. @@ -21,7 +21,7 @@ rtc: rtc@01f00000 { compatible = "allwinner,sun6i-a31-rtc"; reg = <0x01f00000 0x54>; interrupts = <0 40 4>, <0 41 4>; - clock-output-names = "osc32k"; + clock-output-names = "osc32k", "osc32k-out"; clocks = <&ext_osc32k>; #clock-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt index 2a42a323fa1a..b6a869f97715 100644 --- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt @@ -85,5 +85,4 @@ Example: <366 1>,<367 1>/* cq30-31 */ <376 4>,/* fatal ecc */ <381 4>;/* fatal axi */ - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt b/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt index 3ad115efed1e..6a4e0d30d8c4 100644 --- a/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt +++ b/Documentation/devicetree/bindings/security/tpm/st33zp24-i2c.txt @@ -19,7 +19,6 @@ Example (for ARM-based BeagleBoard xM with ST33ZP24 on I2C2): &i2c2 { - status = "okay"; st33zp24: st33zp24@13 { diff --git a/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt b/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt index 158b0165e01c..604dce901b60 100644 --- a/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt +++ b/Documentation/devicetree/bindings/security/tpm/st33zp24-spi.txt @@ -18,7 +18,6 @@ Example (for ARM-based BeagleBoard xM with ST33ZP24 on SPI4): &mcspi4 { - status = "okay"; st33zp24@0 { diff --git a/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt b/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt index 8cb638b7e89c..a65d7b71e81a 100644 --- a/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt +++ b/Documentation/devicetree/bindings/security/tpm/tpm-i2c.txt @@ -8,6 +8,12 @@ Required properties: the firmware event log - linux,sml-size : size of the memory allocated for the firmware event log +Optional properties: + +- powered-while-suspended: present when the TPM is left powered on between + suspend and resume (makes the suspend/resume + callbacks do nothing). + Example (for OpenPower Systems with Nuvoton TPM 2.0 on I2C) ---------------------------------------------------------- @@ -17,5 +23,4 @@ tpm@57 { compatible = "nuvoton,npct650", "nuvoton,npct601"; linux,sml-base = <0x7f 0xfd450000>; linux,sml-size = <0x10000>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt b/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt index 85741cd468cc..b800667da92b 100644 --- a/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt +++ b/Documentation/devicetree/bindings/security/tpm/tpm_tis_spi.txt @@ -13,7 +13,6 @@ Example (for ARM-based BeagleBoard xM with TPM_TIS on SPI4): &mcspi4 { - status = "okay"; tpm_tis@0 { diff --git a/Documentation/devicetree/bindings/serial/8250.txt b/Documentation/devicetree/bindings/serial/8250.txt index 419ff6c0a47f..dad3b2ec66d4 100644 --- a/Documentation/devicetree/bindings/serial/8250.txt +++ b/Documentation/devicetree/bindings/serial/8250.txt @@ -14,6 +14,8 @@ Required properties: tegra132, or tegra210. - "nxp,lpc3220-uart" - "ralink,rt2880-uart" + - For MediaTek BTIF, must contain '"mediatek,-btif", + "mediatek,mtk-btif"' where is mt7622, mt7623. - "altr,16550-FIFO32" - "altr,16550-FIFO64" - "altr,16550-FIFO128" diff --git a/Documentation/devicetree/bindings/serial/arc-uart.txt b/Documentation/devicetree/bindings/serial/arc-uart.txt index 5cae2eb686f8..256cc150ca7e 100644 --- a/Documentation/devicetree/bindings/serial/arc-uart.txt +++ b/Documentation/devicetree/bindings/serial/arc-uart.txt @@ -15,7 +15,6 @@ arcuart0: serial@c0fc1000 { interrupts = <5>; clock-frequency = <80000000>; current-speed = <115200>; - status = "okay"; }; Note: Each port should have an alias correctly numbered in "aliases" node. diff --git a/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt b/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt index 51b3c9e80ad9..048c3818c826 100644 --- a/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt +++ b/Documentation/devicetree/bindings/serial/axis,etraxfs-uart.txt @@ -15,7 +15,6 @@ serial@b00260000 { compatible = "axis,etraxfs-uart"; reg = <0xb0026000 0x1000>; interrupts = <68>; - status = "disabled"; dtr-gpios = <&sysgpio 0 GPIO_ACTIVE_LOW>; dsr-gpios = <&sysgpio 1 GPIO_ACTIVE_LOW>; rng-gpios = <&sysgpio 2 GPIO_ACTIVE_LOW>; diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt index b6cf384597e1..f73abff3de43 100644 --- a/Documentation/devicetree/bindings/serial/mtk-uart.txt +++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt @@ -3,6 +3,7 @@ Required properties: - compatible should contain: * "mediatek,mt2701-uart" for MT2701 compatible UARTS + * "mediatek,mt2712-uart" for MT2712 compatible UARTS * "mediatek,mt6580-uart" for MT6580 compatible UARTS * "mediatek,mt6582-uart" for MT6582 compatible UARTS * "mediatek,mt6589-uart" for MT6589 compatible UARTS diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt index c93a2d1c1a65..d7edf732eb7f 100644 --- a/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra20-hsuart.txt @@ -33,5 +33,4 @@ serial@70006000 { reset-names = "serial"; dmas = <&apbdma 8>, <&apbdma 8>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt index d5f73b8f614f..9d098cf73b53 100644 --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt @@ -72,13 +72,10 @@ Examples: }; uarta: serial@12490000 { - status = "ok"; }; uartb: serial@16340000 { - status = "ok"; }; uartc: serial@1a240000 { - status = "ok"; }; diff --git a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt index 8d27d1a603e7..cf504d0380ae 100644 --- a/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt +++ b/Documentation/devicetree/bindings/serial/renesas,sci-serial.txt @@ -41,6 +41,10 @@ Required properties: - "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART. - "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART. - "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART. + - "renesas,scif-r8a77970" for R8A77970 (R-Car V3M) SCIF compatible UART. + - "renesas,hscif-r8a77970" for R8A77970 (R-Car V3M) HSCIF compatible UART. + - "renesas,scif-r8a77995" for R8A77995 (R-Car D3) SCIF compatible UART. + - "renesas,hscif-r8a77995" for R8A77995 (R-Car D3) HSCIF compatible UART. - "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART. - "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART. - "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART, diff --git a/Documentation/devicetree/bindings/serial/rs485.txt b/Documentation/devicetree/bindings/serial/rs485.txt index 32b1fa1f2a5b..b8415936dfdb 100644 --- a/Documentation/devicetree/bindings/serial/rs485.txt +++ b/Documentation/devicetree/bindings/serial/rs485.txt @@ -5,14 +5,13 @@ the built-in half-duplex mode. The properties described hereafter shall be given to a half-duplex capable UART node. -Required properties: +Optional properties: - rs485-rts-delay: prop-encoded-array where: * a is the delay between rts signal and beginning of data sent in milliseconds. it corresponds to the delay before sending data. * b is the 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. - -Optional properties: + If this property is not specified, <0 0> is assumed. - linux,rs485-enabled-at-boot-time: empty property telling to enable the rs485 feature at boot time. It can be disabled later with proper ioctl. - rs485-rx-during-tx: empty property that enables the receiving of data even diff --git a/Documentation/devicetree/bindings/serial/serial.txt b/Documentation/devicetree/bindings/serial/serial.txt index b542a0ecf06e..863c2893759e 100644 --- a/Documentation/devicetree/bindings/serial/serial.txt +++ b/Documentation/devicetree/bindings/serial/serial.txt @@ -43,7 +43,6 @@ Examples: rng-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; cts-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; rts-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; - status = "okay"; }; scifa4: serial@e6c80000 { @@ -54,5 +53,4 @@ Examples: clock-names = "fck"; power-domains = <&pd_a3sp>; uart-has-rtscts; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt index 85ec5f2b1996..3657f9f9d17a 100644 --- a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt +++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt @@ -1,12 +1,19 @@ * STMicroelectronics STM32 USART Required properties: -- compatible: Can be either "st,stm32-usart", "st,stm32-uart", -"st,stm32f7-usart" or "st,stm32f7-uart" depending on whether -the device supports synchronous mode and is compatible with -stm32(f4) or stm32f7. +- compatible: can be either: + - "st,stm32-usart", + - "st,stm32-uart", + - "st,stm32f7-usart", + - "st,stm32f7-uart", + - "st,stm32h7-usart" + - "st,stm32h7-uart". + depending on whether the device supports synchronous mode + and is compatible with stm32(f4), stm32f7 or stm32h7. - reg: The address and length of the peripheral registers space -- interrupts: The interrupt line of the USART instance +- interrupts: + - The interrupt line for the USART instance, + - An optional wake-up interrupt. - clocks: The input clock of the USART instance Optional properties: diff --git a/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt b/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt index 362a76925bcd..f311472990a7 100644 --- a/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt +++ b/Documentation/devicetree/bindings/serio/allwinner,sun4i-ps2.txt @@ -19,5 +19,4 @@ Example: reg = <0x01c2a000 0x400>; interrupts = <0 62 4>; clocks = <&apb1_gates 6>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/serio/ps2-gpio.txt b/Documentation/devicetree/bindings/serio/ps2-gpio.txt new file mode 100644 index 000000000000..7b7bc9cdf986 --- /dev/null +++ b/Documentation/devicetree/bindings/serio/ps2-gpio.txt @@ -0,0 +1,23 @@ +Device-Tree binding for ps/2 gpio device + +Required properties: + - compatible = "ps2-gpio" + - data-gpios: the data pin + - clk-gpios: the clock pin + - interrupts: Should trigger on the falling edge of the clock line. + +Optional properties: + - write-enable: Indicates whether write function is provided + to serio device. Possibly providing the write fn will not work, because + of the tough timing requirements. + +Example nodes: + +ps2@0 { + compatible = "ps2-gpio"; + interrupt-parent = <&gpio>; + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; + data-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + clk-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + write-enable; +}; diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt index b1d165b4d4b3..40056f7990f8 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt @@ -12,11 +12,13 @@ power/power_domain.txt. It provides the power domains defined in - include/dt-bindings/power/mt8173-power.h - include/dt-bindings/power/mt6797-power.h - include/dt-bindings/power/mt2701-power.h +- include/dt-bindings/power/mt7622-power.h Required properties: - compatible: Should be one of: - "mediatek,mt2701-scpsys" - "mediatek,mt6797-scpsys" + - "mediatek,mt7622-scpsys" - "mediatek,mt8173-scpsys" - #power-domain-cells: Must be 1 - reg: Address range of the SCPSYS unit @@ -26,6 +28,7 @@ Required properties: enabled before enabling certain power domains. Required clocks for MT2701: "mm", "mfg", "ethif" Required clocks for MT6797: "mm", "mfg", "vdec" + Required clocks for MT7622: "hif_sel" Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt" Optional properties: diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt index 50fc20c6ce91..b277eca861f7 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,glink.txt @@ -1,11 +1,12 @@ -Qualcomm RPM GLINK binding +Qualcomm GLINK edge binding -This binding describes the Qualcomm RPM GLINK, a fifo based mechanism for -communication with the Resource Power Management system on various Qualcomm -platforms. +This binding describes a Qualcomm GLINK edge, a fifo based mechanism for +communication between subsystem-pairs on various Qualcomm platforms. Two types +of edges can be described by the binding; the GLINK RPM edge and a SMEM based +edge. - compatible: - Usage: required + Usage: required for glink-rpm Value type: Definition: must be "qcom,glink-rpm" @@ -16,7 +17,7 @@ platforms. signal this processor about communication related events - qcom,rpm-msg-ram: - Usage: required + Usage: required for glink-rpm Value type: Definition: handle to RPM message memory resource diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt index 2f5ede39bea2..fe1855f09dcc 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,gsbi.txt @@ -78,7 +78,6 @@ Example for APQ8064: interrupts = <0 152 0x0>; clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>; clock-names = "core", "iface"; - status = "ok"; }; }; diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.txt b/Documentation/devicetree/bindings/soc/rockchip/grf.txt index cc9f05d3cbc1..7dc5ce858a0e 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/grf.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/grf.txt @@ -21,6 +21,7 @@ Required Properties: - "rockchip,rk3328-grf", "syscon": for rk3328 - "rockchip,rk3368-grf", "syscon": for rk3368 - "rockchip,rk3399-grf", "syscon": for rk3399 + - "rockchip,rv1108-grf", "syscon": for rv1108 - compatible: PMUGRF should be one of the following: - "rockchip,rk3368-pmugrf", "syscon": for rk3368 - "rockchip,rk3399-pmugrf", "syscon": for rk3399 @@ -28,6 +29,8 @@ Required Properties: - "rockchip,rk3288-sgrf", "syscon": for rk3288 - compatible: USB2PHYGRF should be one of the followings - "rockchip,rk3328-usb2phy-grf", "syscon": for rk3328 +- compatible: USBGRF should be one of the following + - "rockchip,rv1108-usbgrf", "syscon": for rv1108 - reg: physical base address of the controller and length of memory mapped region. diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt index 01bfb6745fbd..301d2a9bc1b8 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt @@ -7,6 +7,7 @@ Required properties for power domain controller: - compatible: Should be one of the following. "rockchip,rk3288-power-controller" - for RK3288 SoCs. "rockchip,rk3328-power-controller" - for RK3328 SoCs. + "rockchip,rk3366-power-controller" - for RK3366 SoCs. "rockchip,rk3368-power-controller" - for RK3368 SoCs. "rockchip,rk3399-power-controller" - for RK3399 SoCs. - #power-domain-cells: Number of cells in a power-domain specifier. @@ -18,6 +19,7 @@ Required properties for power domain sub nodes: - reg: index of the power domain, should use macros in: "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain. "include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain. + "include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain. "include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain. "include/dt-bindings/power/rk3399-power.h" - for RK3399 type power domain. - clocks (optional): phandles to clocks which need to be enabled while power domain @@ -93,6 +95,7 @@ power domain to use. The index should use macros in: "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain. "include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain. + "include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain. "include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain. "include/dt-bindings/power/rk3399-power.h" - for rk3399 type power domain. diff --git a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt index c705db07d820..66e6265fb0aa 100644 --- a/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt +++ b/Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt @@ -46,12 +46,13 @@ Required Properties: - power-domains: phandle pointing to the corresponding PM domain node and an ID representing the device. -See dt-bindings/genpd/k2g.h for the list of valid identifiers for k2g. +See http://processors.wiki.ti.com/index.php/TISCI#66AK2G02_Data for the list +of valid identifiers for k2g. Example (K2G): -------------------- uart0: serial@02530c00 { compatible = "ns16550a"; ... - power-domains = <&k2g_pds K2G_DEV_UART0>; + power-domains = <&k2g_pds 0x002c>; }; diff --git a/Documentation/devicetree/bindings/sound/armada-370db-audio.txt b/Documentation/devicetree/bindings/sound/armada-370db-audio.txt index bf984d238620..953c092db72f 100644 --- a/Documentation/devicetree/bindings/sound/armada-370db-audio.txt +++ b/Documentation/devicetree/bindings/sound/armada-370db-audio.txt @@ -23,5 +23,4 @@ Example: compatible = "marvell,a370db-audio"; marvell,audio-controller = <&audio_controller>; marvell,audio-codec = <&audio_codec &spdif_out &spdif_in>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/atmel-classd.txt b/Documentation/devicetree/bindings/sound/atmel-classd.txt index 549e701cb7a1..898551076382 100644 --- a/Documentation/devicetree/bindings/sound/atmel-classd.txt +++ b/Documentation/devicetree/bindings/sound/atmel-classd.txt @@ -13,13 +13,11 @@ Required properties: Must be "tx". - clock-names Tuple listing input clock names. - Required elements: "pclk", "gclk" and "aclk". + Required elements: "pclk" and "gclk". - clocks Please refer to clock-bindings.txt. - assigned-clocks Should be <&classd_gclk>. -- assigned-clock-parents - Should be <&audio_pll_pmc>. Optional properties: - pinctrl-names, pinctrl-0 @@ -45,10 +43,9 @@ classd: classd@fc048000 { (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(47))>; dma-names = "tx"; - clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; - clock-names = "pclk", "gclk", "aclk"; + clocks = <&classd_clk>, <&classd_gclk>; + clock-names = "pclk", "gclk"; assigned-clocks = <&classd_gclk>; - assigned-clock-parents = <&audio_pll_pmc>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_classd_default>; diff --git a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt index fdb25b492514..9d049d4bfd58 100644 --- a/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt +++ b/Documentation/devicetree/bindings/sound/axentia,tse850-pcm5142.txt @@ -45,7 +45,6 @@ Example: &ssc0 { #sound-dai-cells = <0>; - status = "okay"; }; &i2c { diff --git a/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt b/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt index b139e66d2a11..630bf7c0344d 100644 --- a/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt +++ b/Documentation/devicetree/bindings/sound/brcm,cygnus-audio.txt @@ -47,21 +47,17 @@ Example: ssp0: ssp_port@0 { reg = <0>; - status = "okay"; }; ssp1: ssp_port@1 { reg = <1>; - status = "disabled"; }; ssp2: ssp_port@2 { reg = <2>; - status = "disabled"; }; spdif: spdif_port@3 { reg = <3>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/sound/cs43130.txt b/Documentation/devicetree/bindings/sound/cs43130.txt new file mode 100644 index 000000000000..8b1dd5aeb004 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs43130.txt @@ -0,0 +1,67 @@ +CS43130 DAC + +Required properties: + + - compatible : "cirrus,cs43130", "cirrus,cs4399", "cirrus,cs43131", + "cirrus,cs43198" + + - reg : the I2C address of the device for I2C + + - VA-supply, VP-supply, VL-supply, VCP-supply, VD-supply: + power supplies for the device, as covered in + Documentation/devicetree/bindings/regulator/regulator.txt. + + +Optional properties: + + - reset-gpios : Active low GPIO used to reset the device + + - cirrus,xtal-ibias: + When external MCLK is generated by external crystal + oscillator, CS43130 can be used to provide bias current + for external crystal. Amount of bias current sent is + set as: + 1 = 7.5uA + 2 = 12.5uA + 3 = 15uA + + - cirrus,dc-measure: + Boolean, define to enable headphone DC impedance measurement. + + - cirrus,ac-measure: + Boolean, define to enable headphone AC impedance measurement. + DC impedance must also be enabled for AC impedance measurement. + + - cirrus,dc-threshold: + Define 2 DC impedance thresholds in ohms for HP output control. + Default values are 50 and 120 Ohms. + + - cirrus,ac-freq: + Define the frequencies at which to measure HP AC impedance. + Only used if "cirrus,dc-measure" is defined. + Exactly 10 frequencies must be defined. + If this properties is undefined, by default, + following frequencies are used: + <24 43 93 200 431 928 2000 4309 9283 20000> + The above frequencies are logarithmically equally spaced. + Log base is 10. + +Example: + +cs43130: audio-codec@30 { + compatible = "cirrus,cs43130"; + reg = <0x30>; + reset-gpios = <&axi_gpio 54 0>; + VA-supply = <&dummy_vreg>; + VP-supply = <&dummy_vreg>; + VL-supply = <&dummy_vreg>; + VCP-supply = <&dummy_vreg>; + VD-supply = <&dummy_vreg>; + cirrus,xtal-ibias = <2>; + interrupt-parent = <&gpio0>; + interrupts = <55 8>; + cirrus,dc-measure; + cirrus,ac-measure; + cirrus,dc-threshold = /bits/ 16 <20 100>; + cirrus,ac-freq = /bits/ 16 <24 43 93 200 431 928 2000 4309 9283 20000>; +}; diff --git a/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt b/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt index e0b6165c9cfc..3ffc2562fb31 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcbsp.txt @@ -47,5 +47,4 @@ mcbsp0: mcbsp@1d10000 { dmas = <&edma0 3 1 &edma0 2 1>; dma-names = "tx", "rx"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/dmic.txt b/Documentation/devicetree/bindings/sound/dmic.txt new file mode 100644 index 000000000000..54c8ef6498a8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/dmic.txt @@ -0,0 +1,16 @@ +Device-Tree bindings for Digital microphone (DMIC) codec + +This device support generic PDM digital microphone. + +Required properties: + - compatible: should be "dmic-codec". + +Optional properties: + - dmicen-gpios: GPIO specifier for dmic to control start and stop + +Example node: + + dmic_codec: dmic@0 { + compatible = "dmic-codec"; + dmicen-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/sound/fsl,asrc.txt b/Documentation/devicetree/bindings/sound/fsl,asrc.txt index 3e26a9478e57..65979b205893 100644 --- a/Documentation/devicetree/bindings/sound/fsl,asrc.txt +++ b/Documentation/devicetree/bindings/sound/fsl,asrc.txt @@ -61,5 +61,4 @@ asrc: asrc@02034000 { "txa", "txb", "txc"; fsl,asrc-rate = <48000>; fsl,asrc-width = <16>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt b/Documentation/devicetree/bindings/sound/fsl,esai.txt index cd3ee5d84f03..21c401e2ccda 100644 --- a/Documentation/devicetree/bindings/sound/fsl,esai.txt +++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt @@ -59,5 +59,4 @@ esai: esai@02024000 { fsl,fifo-depth = <128>; fsl,esai-synchronous; big-endian; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt index 4ca39ddc0417..0f97e54c3d43 100644 --- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt +++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt @@ -59,5 +59,4 @@ spdif: spdif@02004000 { "rxtx7"; big-endian; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/hdmi.txt b/Documentation/devicetree/bindings/sound/hdmi.txt index 31af7bca3099..56407c30e954 100644 --- a/Documentation/devicetree/bindings/sound/hdmi.txt +++ b/Documentation/devicetree/bindings/sound/hdmi.txt @@ -13,5 +13,4 @@ Example node: hdmi_audio: hdmi_audio@0 { compatible = "linux,hdmi-audio"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt index 9800a560e0c2..77a57f84bed4 100644 --- a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt +++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt @@ -3,7 +3,8 @@ Mediatek AFE PCM controller for mt2701 Required properties: - compatible = "mediatek,mt2701-audio"; - reg: register location and size -- interrupts: Should contain AFE interrupt +- interrupts: should contain AFE and ASYS interrupts +- interrupt-names: should be "afe" and "asys" - power-domains: should define the power domain - clock-names: should have these clock names: "infra_sys_audio_clk", @@ -59,6 +60,7 @@ Example: <0 0x112A0000 0 0x20000>; interrupts = , ; + interrupt-names = "afe", "asys"; power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; clocks = <&infracfg CLK_INFRA_AUDIO>, <&topckgen CLK_TOP_AUD_MUX1_SEL>, diff --git a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt b/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt index ccb401cfef9d..551ecab67efe 100644 --- a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt +++ b/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-analog.txt @@ -31,8 +31,22 @@ Required properties - vdd-cdc-io-supply: phandle to VDD_CDC_IO regulator DT node. - vdd-cdc-tx-rx-cx-supply: phandle to VDD_CDC_TX/RX/CX regulator DT node. - vdd-micbias-supply: phandle of VDD_MICBIAS supply's regulator DT node. - Optional Properties: + - qcom,mbhc-vthreshold-low: Array of 5 threshold voltages in mV for 5 buttons + detection on headset when the mbhc is powered up + by internal current source, this is a low power. + - qcom,mbhc-vthreshold-high: Array of 5 thresold voltages in mV for 5 buttons + detection on headset when mbhc is powered up + from micbias. +- qcom,micbias-lvl: Voltage (mV) for Mic Bias +- qcom,hphl-jack-type-normally-open: boolean, present if hphl pin on jack is a + NO (Normally Open). If not specified, then + its assumed that hphl pin on jack is NC + (Normally Closed). +- qcom,gnd-jack-type-normally-open: boolean, present if gnd pin on jack is + NO (Normally Open). If not specified, then + its assumed that gnd pin on jack is NC + (Normally Closed). - qcom,micbias1-ext-cap: boolean, present if micbias1 has external capacitor connected. - qcom,micbias2-ext-cap: boolean, present if micbias2 has external capacitor @@ -48,6 +62,8 @@ spmi_bus { reg-names = "pmic-codec-core"; clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; clock-names = "mclk"; + qcom,mbhc-vthreshold-low = <75 150 237 450 500>; + qcom,mbhc-vthreshold-high = <75 150 237 450 500>; interrupt-parent = <&spmi_bus>; interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>, <0x1 0xf0 0x1 IRQ_TYPE_NONE>, diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 7246bb268bf9..085bec364caf 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -199,10 +199,10 @@ Ex) sound { compatible = "simple-scu-audio-card"; ... - simple-audio-card,cpu@0 { + simple-audio-card,cpu-0 { sound-dai = <&rcar_sound 0>; }; - simple-audio-card,cpu@1 { + simple-audio-card,cpu-1 { sound-dai = <&rcar_sound 1>; }; simple-audio-card,codec { @@ -441,79 +441,79 @@ rcar_sound: sound@ec500000 { "clk_a", "clk_b", "clk_c", "clk_i"; rcar_sound,dvc { - dvc0: dvc@0 { + dvc0: dvc-0 { dmas = <&audma0 0xbc>; dma-names = "tx"; }; - dvc1: dvc@1 { + dvc1: dvc-1 { dmas = <&audma0 0xbe>; dma-names = "tx"; }; }; rcar_sound,mix { - mix0: mix@0 { }; - mix1: mix@1 { }; + mix0: mix-0 { }; + mix1: mix-1 { }; }; rcar_sound,ctu { - ctu00: ctu@0 { }; - ctu01: ctu@1 { }; - ctu02: ctu@2 { }; - ctu03: ctu@3 { }; - ctu10: ctu@4 { }; - ctu11: ctu@5 { }; - ctu12: ctu@6 { }; - ctu13: ctu@7 { }; + ctu00: ctu-0 { }; + ctu01: ctu-1 { }; + ctu02: ctu-2 { }; + ctu03: ctu-3 { }; + ctu10: ctu-4 { }; + ctu11: ctu-5 { }; + ctu12: ctu-6 { }; + ctu13: ctu-7 { }; }; rcar_sound,src { - src0: src@0 { + src0: src-0 { interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; - src1: src@1 { + src1: src-1 { interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; - src2: src@2 { + src2: src-2 { interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; - src3: src@3 { + src3: src-3 { interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; - src4: src@4 { + src4: src-4 { interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; - src5: src@5 { + src5: src-5 { interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; - src6: src@6 { + src6: src-6 { interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; - src7: src@7 { + src7: src-7 { interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; - src8: src@8 { + src8: src-8 { interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; - src9: src@9 { + src9: src-9 { interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; @@ -521,52 +521,52 @@ rcar_sound: sound@ec500000 { }; rcar_sound,ssi { - ssi0: ssi@0 { + ssi0: ssi-0 { interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi1: ssi@1 { + ssi1: ssi-1 { interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi2: ssi@2 { + ssi2: ssi-2 { interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi3: ssi@3 { + ssi3: ssi-3 { interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi4: ssi@4 { + ssi4: ssi-4 { interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi5: ssi@5 { + ssi5: ssi-5 { interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi6: ssi@6 { + ssi6: ssi-6 { interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi7: ssi@7 { + ssi7: ssi-7 { interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi8: ssi@8 { + ssi8: ssi-8 { interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; - ssi9: ssi@9 { + ssi9: ssi-9 { interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; @@ -621,7 +621,6 @@ Example: simple sound card /* Single DAI */ #sound-dai-cells = <0>; - status = "okay"; rcar_sound,dai { dai0 { @@ -667,7 +666,6 @@ Example: simple sound card for Multi channel /* Single DAI */ #sound-dai-cells = <0>; - status = "okay"; rcar_sound,dai { dai0 { diff --git a/Documentation/devicetree/bindings/sound/rockchip,pdm.txt b/Documentation/devicetree/bindings/sound/rockchip,pdm.txt index 921729de7346..47f164fbd1d7 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,pdm.txt +++ b/Documentation/devicetree/bindings/sound/rockchip,pdm.txt @@ -29,11 +29,13 @@ pdm: pdm@ff040000 { dma-names = "rx"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&pdmm0_clk - &pdmm0_fsync &pdmm0_sdi0 &pdmm0_sdi1 &pdmm0_sdi2 &pdmm0_sdi3>; - pinctrl-1 = <&pdmm0_sleep>; - status = "disabled"; + pinctrl-1 = <&pdmm0_clk_sleep + &pdmm0_sdi0_sleep + &pdmm0_sdi1_sleep + &pdmm0_sdi2_sleep + &pdmm0_sdi3_sleep>; }; diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt index eac91db07178..72d3cf4c2606 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt @@ -4,7 +4,7 @@ Required properties: - compatible: "rockchip,rk3399-gru-sound" - rockchip,cpu: The phandle of the Rockchip I2S controller that's connected to the codecs -- rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs +- rockchip,codec: The phandle of the audio codecs Optional properties: - dmic-wakeup-delay-ms : specify delay time (ms) for DMIC ready. diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt index 206aba1b34bb..b208a752576c 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt @@ -7,8 +7,12 @@ Required properties: - compatible: should be one of the following: - "rockchip,rk3066-i2s": for rk3066 + - "rockchip,rk3036-i2s", "rockchip,rk3066-i2s": for rk3036 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188 + - "rockchip,rk3228-i2s", "rockchip,rk3066-i2s": for rk3228 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288 + - "rockchip,rk3328-i2s", "rockchip,rk3066-i2s": for rk3328 + - "rockchip,rk3366-i2s", "rockchip,rk3066-i2s": for rk3366 - "rockchip,rk3368-i2s", "rockchip,rk3066-i2s": for rk3368 - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399 - reg: physical base address of the controller and length of memory mapped diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt index 4706b96d450b..0a1dc4e1815c 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt @@ -41,6 +41,5 @@ spdif: spdif@0x1011e000 { dma-names = "tx"; clock-names = "hclk", "mclk"; clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>; - status = "disabled"; #sound-dai-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/sound/rt274.txt b/Documentation/devicetree/bindings/sound/rt274.txt new file mode 100644 index 000000000000..e9a6178c78cf --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt274.txt @@ -0,0 +1,33 @@ +RT274 audio CODEC + +This device supports I2C only. + +Required properties: + +- compatible : "realtek,rt274". + +- reg : The I2C address of the device. + +Optional properties: + +- interrupts : The CODEC's interrupt output. + + +Pins on the device (for linking into audio routes) for RT274: + + * DMIC1 Pin + * DMIC2 Pin + * MIC + * LINE1 + * LINE2 + * HPO Pin + * SPDIF + * LINE3 + +Example: + +codec: rt274@1c { + compatible = "realtek,rt274"; + reg = <0x1c>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; +}; diff --git a/Documentation/devicetree/bindings/sound/rt5663.txt b/Documentation/devicetree/bindings/sound/rt5663.txt index 70eaeaed2b18..ff381718c517 100644 --- a/Documentation/devicetree/bindings/sound/rt5663.txt +++ b/Documentation/devicetree/bindings/sound/rt5663.txt @@ -12,6 +12,14 @@ Required properties: Optional properties: +- "realtek,dc_offset_l_manual" +- "realtek,dc_offset_r_manual" +- "realtek,dc_offset_l_manual_mic" +- "realtek,dc_offset_r_manual_mic" + Based on the different PCB layout, add the manual offset value to + compensate the DC offset for each L and R channel, and they are different + between headphone and headset. + Pins on the device (for linking into audio routes) for RT5663: * IN1P diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.txt b/Documentation/devicetree/bindings/sound/samsung,odroid.txt index c30934dd975b..625b1b18fd02 100644 --- a/Documentation/devicetree/bindings/sound/samsung,odroid.txt +++ b/Documentation/devicetree/bindings/sound/samsung,odroid.txt @@ -7,9 +7,6 @@ Required properties: - model - the user-visible name of this sound complex - clocks - should contain entries matching clock names in the clock-names property - - clock-names - should contain following entries: - - "epll" - indicating the EPLL output clock - - "i2s_rclk" - indicating the RCLK (root) clock of the I2S0 controller - samsung,audio-widgets - this property specifies off-codec audio elements like headphones or speakers, for details see widgets.txt - samsung,audio-routing - a list of the connections between audio @@ -46,9 +43,6 @@ sound { "IN1", "Mic Jack", "Mic Jack", "MICBIAS"; - clocks = <&clock CLK_FOUT_EPLL>, <&i2s0 CLK_I2S_RCLK_SRC>; - clock-names = "epll", "sclk_i2s"; - cpu { sound-dai = <&i2s0 0>; }; diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index c7a93931fad2..166f2290233b 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -86,6 +86,9 @@ Optional CPU/CODEC subnodes properties: in dai startup() and disabled with clk_disable_unprepare() in dai shutdown(). +- system-clock-direction-out : specifies clock direction as 'out' on + initialization. It is useful for some aCPUs with + fixed clocks. Example 1 - single DAI link: diff --git a/Documentation/devicetree/bindings/sound/simple-scu-card.txt b/Documentation/devicetree/bindings/sound/simple-scu-card.txt index 327d229a51b2..32f8dbce5241 100644 --- a/Documentation/devicetree/bindings/sound/simple-scu-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-scu-card.txt @@ -24,6 +24,7 @@ Optional subnode properties: - simple-audio-card,convert-rate : platform specified sampling rate convert - simple-audio-card,convert-channels : platform specified converted channel size (2 - 8 ch) - simple-audio-card,prefix : see routing +- simple-audio-card,widgets : Please refer to widgets.txt. - simple-audio-card,routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, the second being the connection's source. Valid names for sources. diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt index 745dc62f76ea..40068ec0e9a5 100644 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt @@ -53,7 +53,6 @@ Example: sti_uni_player1: sti-uni-player@0x8D81000 { compatible = "st,stih407-uni-player-hdmi"; - status = "okay"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_PCM_1>; @@ -66,7 +65,6 @@ Example: sti_uni_player2: sti-uni-player@0x8D82000 { compatible = "st,stih407-uni-player-pcm-out"; - status = "okay"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_PCM_2>; @@ -78,7 +76,6 @@ Example: sti_uni_player3: sti-uni-player@0x8D85000 { compatible = "st,stih407-uni-player-spdif"; - status = "okay"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; clocks = <&clk_s_d0_flexgen CLK_SPDIFF>; @@ -90,7 +87,6 @@ Example: sti_uni_reader1: sti-uni-reader@0x8D84000 { compatible = "st,stih407-uni-reader-hdmi"; - status = "disabled"; #sound-dai-cells = <0>; st,syscfg = <&syscfg_core>; reg = <0x8D84000 0x158>; @@ -125,7 +121,6 @@ Example of audio card declaration: sound { compatible = "simple-audio-card"; simple-audio-card,name = "sti audio card"; - status = "okay"; simple-audio-card,dai-link@0 { /* DAC */ diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt index ee21da865771..fc5da6080759 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt @@ -8,6 +8,7 @@ Required properties: - compatible: should be one of the following: - "allwinner,sun4i-a10-i2s" - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - reg: physical base address of the controller and length of memory mapped region. - interrupts: should contain the I2S interrupt. @@ -22,6 +23,7 @@ Required properties: Required properties for the following compatibles: - "allwinner,sun6i-a31-i2s" + - "allwinner,sun8i-h3-i2s" - resets: phandle to the reset line for this codec Example: diff --git a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt index fe0a65e6d629..70ee177901d3 100644 --- a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt +++ b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt @@ -39,5 +39,4 @@ spdif: spdif@01c21000 { clock-names = "apb", "spdif"; dmas = <&dma 0 2>, <&dma 0 2>; dma-names = "rx", "tx"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/tas5720.txt b/Documentation/devicetree/bindings/sound/tas5720.txt index 806ea7381483..40d94f82beb3 100644 --- a/Documentation/devicetree/bindings/sound/tas5720.txt +++ b/Documentation/devicetree/bindings/sound/tas5720.txt @@ -17,7 +17,6 @@ Required properties: Example: tas5720: tas5720@6c { - status = "okay"; compatible = "ti,tas5720"; reg = <0x6c>; dvdd-supply = <&vdd_3v3_reg>; diff --git a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt index 5e2741af27be..ca75890f0d07 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic32x4.txt @@ -3,7 +3,9 @@ Texas Instruments - tlv320aic32x4 Codec module The tlv320aic32x4 serial control bus communicates through I2C protocols Required properties: - - compatible: Should be "ti,tlv320aic32x4" + - compatible - "string" - One of: + "ti,tlv320aic32x4" TLV320AIC3204 + "ti,tlv320aic32x6" TLV320AIC3206, TLV320AIC3256 - reg: I2C slave address - supply-*: Required supply regulators are: "iov" - digital IO power supply @@ -18,6 +20,8 @@ Optional properties: - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt - clocks/clock-names: Clock named 'mclk' for the master clock of the codec. See clock/clock-bindings.txt for information about the detailed format. + - aic32x4-gpio-func - + - Types are defined in include/sound/tlv320aic32x4.h Example: @@ -27,4 +31,11 @@ codec: tlv320aic32x4@18 { reg = <0x18>; clocks = <&clks 201>; clock-names = "mclk"; + aic32x4-gpio-func= < + 0xff /* AIC32X4_MFPX_DEFAULT_VALUE */ + 0xff /* AIC32X4_MFPX_DEFAULT_VALUE */ + 0x04 /* MFP3 AIC32X4_MFP3_GPIO_ENABLED */ + 0xff /* AIC32X4_MFPX_DEFAULT_VALUE */ + 0x08 /* MFP5 AIC32X4_MFP5_GPIO_INPUT */ + >; }; diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt index 47a213c411ce..ba5b45c483f5 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt @@ -26,6 +26,11 @@ Optional properties: 3 - MICBIAS output is connected to AVDD, If this node is not mentioned or if the value is incorrect, then MicBias is powered down. +- ai3x-ocmv - Output Common-Mode Voltage selection: + 0 - 1.35V, + 1 - 1.5V, + 2 - 1.65V, + 3 - 1.8V - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the device as covered in Documentation/devicetree/bindings/regulator/regulator.txt diff --git a/Documentation/devicetree/bindings/sound/wm8524.txt b/Documentation/devicetree/bindings/sound/wm8524.txt new file mode 100644 index 000000000000..20c62002cbcd --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8524.txt @@ -0,0 +1,16 @@ +WM8524 audio CODEC + +This device does not use I2C or SPI but a simple Hardware Control Interface. + +Required properties: + + - compatible : "wlf,wm8524" + + - wlf,mute-gpios: a GPIO spec for the MUTE pin. + +Example: + +codec: wm8524@0 { + compatible = "wlf,wm8524"; + wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; +}; diff --git a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt index 292ad5083704..3927251464f0 100644 --- a/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt +++ b/Documentation/devicetree/bindings/sound/zte,zx-i2s.txt @@ -27,7 +27,6 @@ Example: interrupts = ; dmas = <&dma 5>, <&dma 6>; dma-names = "tx", "rx"; - status = "okay"; }; sound { diff --git a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt index 989544ea6eb5..b5a5ca4502f9 100644 --- a/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt +++ b/Documentation/devicetree/bindings/sound/zte,zx-spdif.txt @@ -24,5 +24,4 @@ Example: interrupts = ; dmas = <&dma 4>; dma-names = "tx"; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/spi/efm32-spi.txt b/Documentation/devicetree/bindings/spi/efm32-spi.txt index 750e29aff9bc..2c1e6a43930b 100644 --- a/Documentation/devicetree/bindings/spi/efm32-spi.txt +++ b/Documentation/devicetree/bindings/spi/efm32-spi.txt @@ -28,7 +28,6 @@ spi1: spi@0x4000c400 { /* USART1 */ clocks = <&cmu 20>; cs-gpios = <&gpio 51 1>; // D3 energymicro,location = <1>; - status = "ok"; ks8851@0 { compatible = "ks8851"; @@ -36,6 +35,5 @@ spi1: spi@0x4000c400 { /* USART1 */ reg = <0>; interrupt-parent = <&boardfpga>; interrupts = <4>; - status = "ok"; }; }; diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index 31b5b21598ff..5bf13960f7f4 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt @@ -9,6 +9,7 @@ Required properties: - "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31 - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35 - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51 + - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc - reg : Offset and length of the register set for the device - interrupts : Should contain CSPI/eCSPI interrupt - cs-gpios : Specifies the gpio pins to be used for chipselects. diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt index b785976fe98a..9ba7c5a273b4 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt @@ -38,5 +38,4 @@ spi@7000d600 { reset-names = "spi"; dmas = <&apbdma 16>, <&apbdma 16>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt index bdf08e6dec9b..c212491929b5 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-sflash.txt @@ -34,5 +34,4 @@ spi@7000c380 { reset-names = "spi"; dmas = <&apbdma 11>, <&apbdma 11>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt index 5db9144a33c8..40d80b93e327 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra20-slink.txt @@ -34,5 +34,4 @@ spi@7000d600 { reset-names = "spi"; dmas = <&apbdma 16>, <&apbdma 16>; dma-names = "rx", "tx"; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/sh-hspi.txt b/Documentation/devicetree/bindings/spi/sh-hspi.txt index 319bad4af875..585fed90376e 100644 --- a/Documentation/devicetree/bindings/spi/sh-hspi.txt +++ b/Documentation/devicetree/bindings/spi/sh-hspi.txt @@ -24,6 +24,5 @@ Example: interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index 64ee489571c4..e865855726a2 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -6,6 +6,7 @@ Required properties: "renesas,msiof-r8a7792" (R-Car V2H) "renesas,msiof-r8a7793" (R-Car M2-N) "renesas,msiof-r8a7794" (R-Car E2) + "renesas,msiof-r8a7795" (R-Car H3) "renesas,msiof-r8a7796" (R-Car M3-W) "renesas,msiof-sh73a0" (SH-Mobile AG5) "renesas,sh-mobile-msiof" (generic SH-Mobile compatibile device) @@ -78,5 +79,4 @@ Example: dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/spi-clps711x.txt b/Documentation/devicetree/bindings/spi/spi-clps711x.txt index 4c3ec13f423f..5122dc7860af 100644 --- a/Documentation/devicetree/bindings/spi/spi-clps711x.txt +++ b/Documentation/devicetree/bindings/spi/spi-clps711x.txt @@ -23,7 +23,6 @@ spi@80000500 { reg = <0x80000500 0x4>; interrupts = <15>; clocks = <&clks CLPS711X_CLK_SPI>; - status = "disabled"; }; syscon3: syscon@80002200 { diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt index ff5893d275a2..13b1fcc8469e 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt @@ -39,7 +39,6 @@ dspi0@4002c000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_dspi0_1>; big-endian; - status = "okay"; sflash: at26df081a@0 { #address-cells = <1>; diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt index e0318cf92d73..236dcb0faf37 100644 --- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt @@ -57,5 +57,4 @@ spi: spi@1100a000 { clock-names = "parent-clk", "sel-clk", "spi-clk"; cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>; mediatek,pad-select = <1>, <0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt index 4f629cc7634a..df8ec31f2f07 100644 --- a/Documentation/devicetree/bindings/spi/spi-orion.txt +++ b/Documentation/devicetree/bindings/spi/spi-orion.txt @@ -29,7 +29,6 @@ Example: cell-index = <0>; reg = <0x10600 0x28>; interrupts = <23>; - status = "disabled"; }; Example with SPI direct mode support (optionally): @@ -48,7 +47,6 @@ Example with SPI direct mode support (optionally): , /* CS6 */ ; /* CS7 */ interrupts = <23>; - status = "disabled"; }; To enable the direct mode, the board specific 'ranges' property in the diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt b/Documentation/devicetree/bindings/spi/spi-rockchip.txt index 83da4931d832..6e3ffacbba32 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt @@ -6,6 +6,7 @@ and display controllers using the SPI communication interface. Required Properties: - compatible: should be one of the following. + "rockchip,rv1108-spi" for rv1108 SoCs. "rockchip,rk3036-spi" for rk3036 SoCS. "rockchip,rk3066-spi" for rk3066 SoCs. "rockchip,rk3188-spi" for rk3188 SoCs. diff --git a/Documentation/devicetree/bindings/spi/spi-sun4i.txt b/Documentation/devicetree/bindings/spi/spi-sun4i.txt index de827f5a301e..484bbff5337e 100644 --- a/Documentation/devicetree/bindings/spi/spi-sun4i.txt +++ b/Documentation/devicetree/bindings/spi/spi-sun4i.txt @@ -18,7 +18,6 @@ spi1: spi@01c06000 { interrupts = <11>; clocks = <&ahb_gates 21>, <&spi1_clk>; clock-names = "ahb", "mod"; - status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/spi/spi-sun6i.txt b/Documentation/devicetree/bindings/spi/spi-sun6i.txt index 2ec99b86b622..ab1811354cce 100644 --- a/Documentation/devicetree/bindings/spi/spi-sun6i.txt +++ b/Documentation/devicetree/bindings/spi/spi-sun6i.txt @@ -39,7 +39,6 @@ spi0: spi@01c68000 { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>; resets = <&ccu RST_BUS_SPI0>; - status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/spi/spi_atmel.txt b/Documentation/devicetree/bindings/spi/spi_atmel.txt index fb588b3e6a9a..f99c733d75c1 100644 --- a/Documentation/devicetree/bindings/spi/spi_atmel.txt +++ b/Documentation/devicetree/bindings/spi/spi_atmel.txt @@ -26,7 +26,6 @@ spi1: spi@fffcc000 { clock-names = "spi_clk"; cs-gpios = <&pioB 3 0>; atmel,fifo-size = <32>; - status = "okay"; mmc-slot@0 { compatible = "mmc-spi-slot"; diff --git a/Documentation/devicetree/bindings/sram/renesas,smp-sram.txt b/Documentation/devicetree/bindings/sram/renesas,smp-sram.txt new file mode 100644 index 000000000000..712d05e3e15e --- /dev/null +++ b/Documentation/devicetree/bindings/sram/renesas,smp-sram.txt @@ -0,0 +1,27 @@ +* Renesas SMP SRAM + +Renesas R-Car Gen2 and RZ/G1 SoCs need a small piece of SRAM for the jump stub +for secondary CPU bringup and CPU hotplug. +This memory is reserved by adding a child node to a "mmio-sram" node, cfr. +Documentation/devicetree/bindings/sram/sram.txt. + +Required child node properties: + - compatible: Must be "renesas,smp-sram", + - reg: Address and length of the reserved SRAM. + The full physical (bus) address must be aligned to a 256 KiB boundary. + + +Example: + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; diff --git a/Documentation/devicetree/bindings/sram/sunxi-sram.txt b/Documentation/devicetree/bindings/sram/sunxi-sram.txt index 8d5665468fe7..6bb92a1df753 100644 --- a/Documentation/devicetree/bindings/sram/sunxi-sram.txt +++ b/Documentation/devicetree/bindings/sram/sunxi-sram.txt @@ -9,7 +9,9 @@ Controller Node --------------- Required properties: -- compatible : "allwinner,sun4i-a10-sram-controller" +- compatible : should be: + - "allwinner,sun4i-a10-sram-controller" + - "allwinner,sun50i-a64-sram-controller" - reg : sram controller register offset + length SRAM nodes @@ -22,10 +24,13 @@ Each SRAM will have SRAM sections that are going to be handled by the SRAM controller as subnodes. These sections are represented following once again the representation described in the mmio-sram binding. -The valid sections compatible are: +The valid sections compatible for A10 are: - allwinner,sun4i-a10-sram-a3-a4 - allwinner,sun4i-a10-sram-d +The valid sections compatible for A64 are: + - allwinner,sun50i-a64-sram-c + Devices using SRAM sections --------------------------- @@ -59,7 +64,6 @@ sram-controller@01c00000 { emac_sram: sram-section@8000 { compatible = "allwinner,sun4i-a10-sram-a3-a4"; reg = <0x8000 0x4000>; - status = "disabled"; }; }; }; diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt index 4698e0edc205..24aacf8948c5 100644 --- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt @@ -20,5 +20,4 @@ Example: compatible = "marvell,armada370-thermal"; reg = <0xd0018300 0x4 0xd0018304 0x4>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt index 70b4c16c7ed8..9b4c7b017495 100644 --- a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt @@ -77,7 +77,6 @@ Example 1): interrupts = <2 4>; clocks = <&clock 383>; clock-names = "tmu_apbif"; - status = "disabled"; vtmu-supply = <&tmu_regulator_node>; #include "exynos4412-tmu-sensor-conf.dtsi" }; diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt index e2f494d74d8a..0d73ea5e9c0c 100644 --- a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt @@ -11,6 +11,7 @@ Required properties: - compatible: - "mediatek,mt8173-thermal" : For MT8173 family of SoCs - "mediatek,mt2701-thermal" : For MT2701 family of SoCs + - "mediatek,mt2712-thermal" : For MT2712 family of SoCs - reg: Address range of the thermal controller - interrupts: IRQ for the thermal controller - clocks, clock-names: Clocks needed for the thermal controller. required diff --git a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt index 07a9713ae6a7..fdf5caa6229b 100644 --- a/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rcar-gen3-thermal.txt @@ -36,7 +36,6 @@ Example: clocks = <&cpg CPG_MOD 522>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; #thermal-sensor-cells = <1>; - status = "okay"; }; thermal-zones { diff --git a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt index 43003aec94bd..e3a6234fb1ac 100644 --- a/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/rockchip-thermal.txt @@ -4,6 +4,7 @@ Required properties: - compatible : should be "rockchip,-tsadc" "rockchip,rk3228-tsadc": found on RK3228 SoCs "rockchip,rk3288-tsadc": found on RK3288 SoCs + "rockchip,rk3328-tsadc": found on RK3328 SoCs "rockchip,rk3368-tsadc": found on RK3368 SoCs "rockchip,rk3399-tsadc": found on RK3399 SoCs - reg : physical base address of the controller and length of memory mapped diff --git a/Documentation/devicetree/bindings/thermal/uniphier-thermal.txt b/Documentation/devicetree/bindings/thermal/uniphier-thermal.txt new file mode 100644 index 000000000000..686c0b42ed3f --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/uniphier-thermal.txt @@ -0,0 +1,64 @@ +* UniPhier Thermal bindings + +This describes the devicetree bindings for thermal monitor supported by +PVT(Process, Voltage and Temperature) monitoring unit implemented on Socionext +UniPhier SoCs. + +Required properties: +- compatible : + - "socionext,uniphier-pxs2-thermal" : For UniPhier PXs2 SoC + - "socionext,uniphier-ld20-thermal" : For UniPhier LD20 SoC +- interrupts : IRQ for the temperature alarm +- #thermal-sensor-cells : Should be 0. See ./thermal.txt for details. + +Optional properties: +- socionext,tmod-calibration: A pair of calibrated values referred from PVT, + in case that the values aren't set on SoC, + like a reference board. + +Example: + + sysctrl@61840000 { + compatible = "socionext,uniphier-ld20-sysctrl", + "simple-mfd", "syscon"; + reg = <0x61840000 0x10000>; + ... + pvtctl: pvtctl { + compatible = "socionext,uniphier-ld20-thermal"; + interrupts = <0 3 1>; + #thermal-sensor-cells = <0>; + }; + ... + }; + + thermal-zones { + cpu_thermal { + polling-delay-passive = <250>; /* 250ms */ + polling-delay = <1000>; /* 1000ms */ + thermal-sensors = <&pvtctl>; + + trips { + cpu_crit: cpu_crit { + temperature = <110000>; /* 110C */ + hysteresis = <2000>; + type = "critical"; + }; + cpu_alert: cpu_alert { + temperature = <100000>; /* 100C */ + hysteresis = <2000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = <&cpu0 (-1) (-1)>; + }; + map1 { + trip = <&cpu_alert>; + cooling-device = <&cpu2 (-1) (-1)>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt b/Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt new file mode 100644 index 000000000000..b4aa7ddb5b13 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt @@ -0,0 +1,28 @@ +NXP Low Power Timer/Pulse Width Modulation Module (TPM) + +The Timer/PWM Module (TPM) supports input capture, output compare, +and the generation of PWM signals to control electric motor and power +management applications. The counter, compare and capture registers +are clocked by an asynchronous clock that can remain enabled in low +power modes. TPM can support global counter bus where one TPM drives +the counter bus for the others, provided bit width is the same. + +Required properties: + +- compatible : should be "fsl,imx7ulp-tpm" +- reg : Specifies base physical address and size of the register sets + for the clock event device and clock source device. +- interrupts : Should be the clock event device interrupt. +- clocks : The clocks provided by the SoC to drive the timer, must contain + an entry for each entry in clock-names. +- clock-names : Must include the following entries: "igp" and "per". + +Example: +tpm5: tpm@40260000 { + compatible = "fsl,imx7ulp-tpm"; + reg = <0x40260000 0x1000>; + interrupts = ; + clocks = <&clks IMX7ULP_CLK_NIC1_BUS_DIV>, + <&clks IMX7ULP_CLK_LPTPM5>; + clock-names = "ipg", "per"; +}; diff --git a/Documentation/devicetree/bindings/timer/renesas,cmt.txt b/Documentation/devicetree/bindings/timer/renesas,cmt.txt index 1a05c1b243c1..6ca6b9e582a0 100644 --- a/Documentation/devicetree/bindings/timer/renesas,cmt.txt +++ b/Documentation/devicetree/bindings/timer/renesas,cmt.txt @@ -12,46 +12,29 @@ datasheets. Required Properties: - compatible: must contain one or more of the following: - - "renesas,cmt-32-r8a7740" for the r8a7740 32-bit CMT - (CMT0) - - "renesas,cmt-32-sh7372" for the sh7372 32-bit CMT - (CMT0) - - "renesas,cmt-32-sh73a0" for the sh73a0 32-bit CMT - (CMT0) - - "renesas,cmt-32" for all 32-bit CMT without fast clock support - (CMT0 on sh7372, sh73a0 and r8a7740) - This is a fallback for the above renesas,cmt-32-* entries. - - - "renesas,cmt-32-fast-r8a7740" for the r8a7740 32-bit CMT with fast - clock support (CMT[234]) - - "renesas,cmt-32-fast-sh7372" for the sh7372 32-bit CMT with fast - clock support (CMT[234]) - - "renesas,cmt-32-fast-sh73a0" for the sh73A0 32-bit CMT with fast - clock support (CMT[234]) - - "renesas,cmt-32-fast" for all 32-bit CMT with fast clock support - (CMT[234] on sh7372, sh73a0 and r8a7740) - This is a fallback for the above renesas,cmt-32-fast-* entries. - - - "renesas,cmt-48-sh7372" for the sh7372 48-bit CMT - (CMT1) - "renesas,cmt-48-sh73a0" for the sh73A0 48-bit CMT (CMT1) - "renesas,cmt-48-r8a7740" for the r8a7740 48-bit CMT (CMT1) - "renesas,cmt-48" for all non-second generation 48-bit CMT - (CMT1 on sh7372, sh73a0 and r8a7740) + (CMT1 on sh73a0 and r8a7740) This is a fallback for the above renesas,cmt-48-* entries. - - "renesas,cmt-48-r8a73a4" for the r8a73a4 48-bit CMT - (CMT[01]) - - "renesas,cmt-48-r8a7790" for the r8a7790 48-bit CMT - (CMT[01]) - - "renesas,cmt-48-r8a7791" for the r8a7791 48-bit CMT - (CMT[01]) - - "renesas,cmt-48-gen2" for all second generation 48-bit CMT - (CMT[01] on r8a73a4, r8a7790 and r8a7791) - This is a fallback for the renesas,cmt-48-r8a73a4, - renesas,cmt-48-r8a7790 and renesas,cmt-48-r8a7791 entries. + - "renesas,cmt0-r8a73a4" for the 32-bit CMT0 device included in r8a73a4. + - "renesas,cmt1-r8a73a4" for the 48-bit CMT1 device included in r8a73a4. + - "renesas,cmt0-r8a7790" for the 32-bit CMT0 device included in r8a7790. + - "renesas,cmt1-r8a7790" for the 48-bit CMT1 device included in r8a7790. + - "renesas,cmt0-r8a7791" for the 32-bit CMT0 device included in r8a7791. + - "renesas,cmt1-r8a7791" for the 48-bit CMT1 device included in r8a7791. + - "renesas,cmt0-r8a7793" for the 32-bit CMT0 device included in r8a7793. + - "renesas,cmt1-r8a7793" for the 48-bit CMT1 device included in r8a7793. + - "renesas,cmt0-r8a7794" for the 32-bit CMT0 device included in r8a7794. + - "renesas,cmt1-r8a7794" for the 48-bit CMT1 device included in r8a7794. + + - "renesas,rcar-gen2-cmt0" for 32-bit CMT0 devices included in R-Car Gen2. + - "renesas,rcar-gen2-cmt1" for 48-bit CMT1 devices included in R-Car Gen2. + These are fallbacks for r8a73a4 and all the R-Car Gen2 + entries listed above. - reg: base address and length of the registers block for the timer module. - interrupts: interrupt-specifier for the timer, one per channel. @@ -59,21 +42,29 @@ Required Properties: in clock-names. - clock-names: must contain "fck" for the functional clock. - - renesas,channels-mask: bitmask of the available channels. - -Example: R8A7790 (R-Car H2) CMT0 node - - CMT0 on R8A7790 implements hardware channels 5 and 6 only and names - them channels 0 and 1 in the documentation. +Example: R8A7790 (R-Car H2) CMT0 and CMT1 nodes cmt0: timer@ffca0000 { - compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; + compatible = "renesas,cmt0-r8a7790", "renesas,rcar-gen2-cmt0"; reg = <0 0xffca0000 0 0x1004>; interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, <0 142 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp1_clks R8A7790_CLK_CMT0>; clock-names = "fck"; + }; - renesas,channels-mask = <0x60>; + cmt1: timer@e6130000 { + compatible = "renesas,cmt1-r8a7790", "renesas,rcar-gen2-cmt1"; + reg = <0 0xe6130000 0 0x1004>; + interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, + <0 121 IRQ_TYPE_LEVEL_HIGH>, + <0 122 IRQ_TYPE_LEVEL_HIGH>, + <0 123 IRQ_TYPE_LEVEL_HIGH>, + <0 124 IRQ_TYPE_LEVEL_HIGH>, + <0 125 IRQ_TYPE_LEVEL_HIGH>, + <0 126 IRQ_TYPE_LEVEL_HIGH>, + <0 127 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_CMT1>; + clock-names = "fck"; }; diff --git a/Documentation/devicetree/bindings/trivial-devices.txt b/Documentation/devicetree/bindings/trivial-devices.txt index 35f406dd86b6..af284fbd4d23 100644 --- a/Documentation/devicetree/bindings/trivial-devices.txt +++ b/Documentation/devicetree/bindings/trivial-devices.txt @@ -21,6 +21,16 @@ adi,adt7490 +/-1C TDM Extended Temp Range I.C adi,adxl345 Three-Axis Digital Accelerometer adi,adxl346 Three-Axis Digital Accelerometer (backward-compatibility value "adi,adxl345" must be listed too) ams,iaq-core AMS iAQ-Core VOC Sensor +amstaos,tsl2571 AMS/TAOS ALS and proximity sensor +amstaos,tsl2671 AMS/TAOS ALS and proximity sensor +amstaos,tmd2671 AMS/TAOS ALS and proximity sensor +amstaos,tsl2771 AMS/TAOS ALS and proximity sensor +amstaos,tmd2771 AMS/TAOS ALS and proximity sensor +amstaos,tsl2572 AMS/TAOS ALS and proximity sensor +amstaos,tsl2672 AMS/TAOS ALS and proximity sensor +amstaos,tmd2672 AMS/TAOS ALS and proximity sensor +amstaos,tsl2772 AMS/TAOS ALS and proximity sensor +amstaos,tmd2772 AMS/TAOS ALS and proximity sensor at,24c08 i2c serial eeprom (24cxx) atmel,at97sc3204t i2c trusted platform module (TPM) capella,cm32181 CM32181: Ambient Light Sensor @@ -36,7 +46,9 @@ dallas,ds1775 Tiny Digital Thermometer and Thermostat dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O dallas,ds75 Digital Thermometer and Thermostat +devantech,srf02 Devantech SRF02 ultrasonic ranger in I2C mode devantech,srf08 Devantech SRF08 ultrasonic ranger +devantech,srf10 Devantech SRF10 ultrasonic ranger dlg,da9053 DA9053: flexible system level PMIC with multicore support dlg,da9063 DA9063: system PMIC for quad-core application processors domintech,dmard09 DMARD09: 3-axis Accelerometer @@ -54,6 +66,7 @@ fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz) infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz) +isil,isl1208 Intersil ISL1208 Low Power RTC with Battery Backed SRAM isil,isl29028 Intersil ISL29028 Ambient Light and Proximity Sensor isil,isl29030 Intersil ISL29030 Ambient Light and Proximity Sensor maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator @@ -168,6 +181,7 @@ st,m41t80 M41T80 - SERIAL ACCESS RTC WITH ALARMS taos,tsl2550 Ambient Light Sensor with SMBUS/Two Wire Serial Interface ti,ads7828 8-Channels, 12-bit ADC ti,ads7830 8-Channels, 8-bit ADC +ti,amc6821 Temperature Monitoring and Fan Control ti,tsc2003 I2C Touch-Screen Controller ti,tmp102 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface ti,tmp103 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface diff --git a/Documentation/devicetree/bindings/unittest.txt b/Documentation/devicetree/bindings/unittest.txt index 3bf58c20fe94..9a5b311f4434 100644 --- a/Documentation/devicetree/bindings/unittest.txt +++ b/Documentation/devicetree/bindings/unittest.txt @@ -10,7 +10,6 @@ All other properties are optional. Example: unittest { compatible = "unittest"; - status = "okay"; }; 2) OF unittest i2c adapter platform device @@ -25,7 +24,6 @@ Children nodes contain unittest i2c devices. Example: unittest-i2c-bus { compatible = "unittest-i2c-bus"; - status = "okay"; }; 3) OF unittest i2c device @@ -40,7 +38,6 @@ All other properties are optional Example: unittest-i2c-dev { compatible = "unittest-i2c-dev"; - status = "okay"; }; 4) OF unittest i2c mux device @@ -55,7 +52,6 @@ Children nodes contain unittest i2c bus nodes per channel. Example: unittest-i2c-mux { compatible = "unittest-i2c-mux"; - status = "okay"; #address-cells = <1>; #size-cells = <0>; channel-0 { @@ -65,7 +61,6 @@ Example: i2c-dev { reg = <8>; compatible = "unittest-i2c-dev"; - status = "okay"; }; }; }; diff --git a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt index d9b42da016f3..cb2bd83fa89a 100644 --- a/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt +++ b/Documentation/devicetree/bindings/usb/allwinner,sun4i-a10-musb.txt @@ -25,5 +25,4 @@ Example: phys = <&usbphy 0>; phy-names = "usb"; extcon = <&usbphy 0>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/usb/am33xx-usb.txt b/Documentation/devicetree/bindings/usb/am33xx-usb.txt index 20c2ff2ba07e..16920d78e1b8 100644 --- a/Documentation/devicetree/bindings/usb/am33xx-usb.txt +++ b/Documentation/devicetree/bindings/usb/am33xx-usb.txt @@ -4,9 +4,9 @@ - reg: offset and length of the usbss register sets - ti,hwmods : must be "usb_otg_hs" -The glue layer contains multiple child nodes. It is required the have +The glue layer contains multiple child nodes. It is required to have at least a control module node, USB node and a PHY node. The second USB -node and its PHY node is optional. The DMA node is also optional. +node and its PHY node are optional. The DMA node is also optional. Reset module ~~~~~~~~~~~~ diff --git a/Documentation/devicetree/bindings/usb/brcm,bdc.txt b/Documentation/devicetree/bindings/usb/brcm,bdc.txt new file mode 100644 index 000000000000..63e63af3bf59 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/brcm,bdc.txt @@ -0,0 +1,29 @@ +Broadcom USB Device Controller (BDC) +==================================== + +Required properties: + +- compatible: must be one of: + "brcm,bdc-v0.16" + "brcm,bdc" +- reg: the base register address and length +- interrupts: the interrupt line for this controller + +Optional properties: + +On Broadcom STB platforms, these properties are required: + +- phys: phandle to one or two USB PHY blocks + NOTE: Some SoC's have a single phy and some have + USB 2.0 and USB 3.0 phys +- clocks: phandle to the functional clock of this block + +Example: + + bdc@f0b02000 { + compatible = "brcm,bdc-v0.16"; + reg = <0xf0b02000 0xfc4>; + interrupts = <0x0 0x60 0x0>; + phys = <&usbphy_0 0x0>; + clocks = <&sw_usbd>; + }; diff --git a/Documentation/devicetree/bindings/usb/da8xx-usb.txt b/Documentation/devicetree/bindings/usb/da8xx-usb.txt index 717c5f656237..9ce22551b2b3 100644 --- a/Documentation/devicetree/bindings/usb/da8xx-usb.txt +++ b/Documentation/devicetree/bindings/usb/da8xx-usb.txt @@ -42,7 +42,6 @@ Example: usb_phy: usb-phy { compatible = "ti,da830-usb-phy"; #phy-cells = <0>; - status = "okay"; }; usb0: usb@200000 { compatible = "ti,da830-musb"; @@ -66,7 +65,6 @@ Example: "rx1", "rx2", "rx3", "rx4", "tx1", "tx2", "tx3", "tx4"; - status = "okay"; cppi41dma: dma-controller@201000 { compatible = "ti,da830-cppi41"; diff --git a/Documentation/devicetree/bindings/usb/dwc3-st.txt b/Documentation/devicetree/bindings/usb/dwc3-st.txt index 50dee3b44665..df0e02e1ee43 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-st.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-st.txt @@ -42,7 +42,6 @@ or "device". Example: st_dwc3: dwc3@8f94000 { - status = "disabled"; compatible = "st,stih407-dwc3"; reg = <0x08f94000 0x1000>, <0x110 0x4>; reg-names = "reg-glue", "syscfg-reg"; diff --git a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt index 30361b32a460..4aae5b2cef56 100644 --- a/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt +++ b/Documentation/devicetree/bindings/usb/dwc3-xilinx.txt @@ -18,7 +18,6 @@ Example device node: usb@0 { #address-cells = <0x2>; #size-cells = <0x1>; - status = "okay"; compatible = "xlnx,zynqmp-dwc3"; clock-names = "bus_clk" "ref_clk"; clocks = <&clk125>, <&clk125>; diff --git a/Documentation/devicetree/bindings/usb/ehci-st.txt b/Documentation/devicetree/bindings/usb/ehci-st.txt index 410d922cfdd7..9feea6c3e4d9 100644 --- a/Documentation/devicetree/bindings/usb/ehci-st.txt +++ b/Documentation/devicetree/bindings/usb/ehci-st.txt @@ -31,7 +31,6 @@ Example: clocks = <&clk_s_a1_ls 0>; phys = <&usb2_phy>; phy-names = "usb"; - status = "okay"; resets = <&powerdown STIH416_USB1_POWERDOWN>, <&softreset STIH416_USB1_SOFTRESET>; diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt index 78ebebb66dad..c97374315049 100644 --- a/Documentation/devicetree/bindings/usb/exynos-usb.txt +++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt @@ -40,7 +40,6 @@ Example: port@0 { reg = <0>; phys = <&usb2phy 1>; - status = "disabled"; }; }; @@ -75,7 +74,6 @@ Example: port@0 { reg = <0>; phys = <&usb2phy 1>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/usb/fcs,fusb302.txt b/Documentation/devicetree/bindings/usb/fcs,fusb302.txt new file mode 100644 index 000000000000..472facfa5a71 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/fcs,fusb302.txt @@ -0,0 +1,29 @@ +Fairchild FUSB302 Type-C Port controllers + +Required properties : +- compatible : "fcs,fusb302" +- reg : I2C slave address +- interrupts : Interrupt specifier + +Optional properties : +- fcs,max-sink-microvolt : Maximum voltage to negotiate when configured as sink +- fcs,max-sink-microamp : Maximum current to negotiate when configured as sink +- fcs,max-sink-microwatt : Maximum power to negotiate when configured as sink + If this is less then max-sink-microvolt * + max-sink-microamp then the configured current will + be clamped. +- fcs,operating-sink-microwatt : + Minimum amount of power accepted from a sink + when negotiating + +Example: + +fusb302: typec-portc@54 { + compatible = "fcs,fusb302"; + reg = <0x54>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + fcs,max-sink-microvolt = <12000000>; + fcs,max-sink-microamp = <3000000>; + fcs,max-sink-microwatt = <36000000>; +}; diff --git a/Documentation/devicetree/bindings/usb/isp1301.txt b/Documentation/devicetree/bindings/usb/isp1301.txt index 5405d99d9aaa..ecd607dacba5 100644 --- a/Documentation/devicetree/bindings/usb/isp1301.txt +++ b/Documentation/devicetree/bindings/usb/isp1301.txt @@ -21,5 +21,4 @@ Example: interrupt-parent = <&mic>; interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>; transceiver = <&isp1301>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/usb/keystone-usb.txt b/Documentation/devicetree/bindings/usb/keystone-usb.txt index 60527d335b58..f96e09f784cc 100644 --- a/Documentation/devicetree/bindings/usb/keystone-usb.txt +++ b/Documentation/devicetree/bindings/usb/keystone-usb.txt @@ -12,8 +12,21 @@ Required properties: MPU. - ranges: allows valid 1:1 translation between child's address space and parent's address space. - - clocks: Clock IDs array as required by the controller. - - clock-names: names of clocks correseponding to IDs in the clock property. + +SoC-specific Required Properties: +The following are mandatory properties for Keystone 2 66AK2HK, 66AK2L and 66AK2E +SoCs only: + +- clocks: Clock ID for USB functional clock. +- clock-names: Must be "usb". + + +The following are mandatory properties for Keystone 2 66AK2G SoCs only: + +- power-domains: Should contain a phandle to a PM domain provider node + and an args specifier containing the USB device id + value. This property is as per the binding, + Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt Sub-nodes: The dwc3 core should be added as subnode to Keystone DWC3 glue. @@ -31,7 +44,6 @@ Example: clock-names = "usb"; interrupts = ; ranges; - status = "disabled"; dwc3@2690000 { compatible = "synopsys,dwc3"; diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt similarity index 85% rename from Documentation/devicetree/bindings/usb/mt8173-xhci.txt rename to Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt index 0acfc8acbea1..5611a2e4ddf0 100644 --- a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt @@ -11,7 +11,11 @@ into two parts. ------------------------------------------------------------------------ Required properties: - - compatible : should contain "mediatek,mt8173-xhci" + - compatible : should be "mediatek,-xhci", "mediatek,mtk-xhci", + soc-model is the name of SoC, such as mt8173, mt2712 etc, when using + "mediatek,mtk-xhci" compatible string, you need SoC specific ones in + addition, one of: + - "mediatek,mt8173-xhci" - reg : specifies physical base address and size of the registers - reg-names: should be "mac" for xHCI MAC and "ippc" for IP port control - interrupts : interrupt used by the controller @@ -68,10 +72,14 @@ usb30: usb@11270000 { In the case, xhci is added as subnode to mtu3. An example and the DT binding details of mtu3 can be found in: -Documentation/devicetree/bindings/usb/mt8173-mtu3.txt +Documentation/devicetree/bindings/usb/mediatek,mtu3.txt Required properties: - - compatible : should contain "mediatek,mt8173-xhci" + - compatible : should be "mediatek,-xhci", "mediatek,mtk-xhci", + soc-model is the name of SoC, such as mt8173, mt2712 etc, when using + "mediatek,mtk-xhci" compatible string, you need SoC specific ones in + addition, one of: + - "mediatek,mt8173-xhci" - reg : specifies physical base address and size of the registers - reg-names: should be "mac" for xHCI MAC - interrupts : interrupt used by the host controller diff --git a/Documentation/devicetree/bindings/usb/mt8173-mtu3.txt b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt similarity index 91% rename from Documentation/devicetree/bindings/usb/mt8173-mtu3.txt rename to Documentation/devicetree/bindings/usb/mediatek,mtu3.txt index 1d7c3bc677f7..49f54767cd21 100644 --- a/Documentation/devicetree/bindings/usb/mt8173-mtu3.txt +++ b/Documentation/devicetree/bindings/usb/mediatek,mtu3.txt @@ -1,7 +1,11 @@ The device node for Mediatek USB3.0 DRD controller Required properties: - - compatible : should be "mediatek,mt8173-mtu3" + - compatible : should be "mediatek,-mtu3", "mediatek,mtu3", + soc-model is the name of SoC, such as mt8173, mt2712 etc, + when using "mediatek,mtu3" compatible string, you need SoC specific + ones in addition, one of: + - "mediatek,mt8173-mtu3" - reg : specifies physical base address and size of the registers - reg-names: should be "mac" for device IP and "ippc" for IP port control - interrupts : interrupt used by the device IP @@ -44,7 +48,7 @@ Optional properties: Sub-nodes: The xhci should be added as subnode to mtu3 as shown in the following example if host mode is enabled. The DT binding details of xhci can be found in: -Documentation/devicetree/bindings/usb/mt8173-xhci.txt +Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.txt Example: ssusb: usb@11271000 { @@ -71,7 +75,6 @@ ssusb: usb@11271000 { #address-cells = <2>; #size-cells = <2>; ranges; - status = "disabled"; usb_host: xhci@11270000 { compatible = "mediatek,mt8173-xhci"; @@ -82,6 +85,5 @@ ssusb: usb@11271000 { clocks = <&topckgen CLK_TOP_USB30_SEL>, <&clk26m>; clock-names = "sys_ck", "ref_ck"; vusb33-supply = <&mt6397_vusb_reg>; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/usb/ohci-st.txt b/Documentation/devicetree/bindings/usb/ohci-st.txt index 6d8393748da2..d893ec9131c3 100644 --- a/Documentation/devicetree/bindings/usb/ohci-st.txt +++ b/Documentation/devicetree/bindings/usb/ohci-st.txt @@ -29,7 +29,6 @@ Example: clock-names = "ic", "clk48"; phys = <&usb2_phy>; phy-names = "usb"; - status = "okay"; resets = <&powerdown STIH416_USB0_POWERDOWN>, <&softreset STIH416_USB0_SOFTRESET>; diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt index 73cc0963e823..bc8a2fa5d2bf 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt @@ -29,7 +29,6 @@ Example device nodes: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; ss_phy: phy@100f8830 { @@ -39,7 +38,6 @@ Example device nodes: clock-names = "ref"; #phy-cells = <0>; - status = "ok"; }; usb3_0: usb30@0 { @@ -51,7 +49,6 @@ Example device nodes: ranges; - status = "ok"; dwc3@10000000 { compatible = "snps,dwc3"; diff --git a/Documentation/devicetree/bindings/usb/renesas_usb3.txt b/Documentation/devicetree/bindings/usb/renesas_usb3.txt index 8d52766f07b9..e28025883b79 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usb3.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usb3.txt @@ -3,20 +3,30 @@ Renesas Electronics USB3.0 Peripheral driver Required properties: - compatible: Must contain one of the following: - "renesas,r8a7795-usb3-peri" + - "renesas,r8a7796-usb3-peri" + - "renesas,rcar-gen3-usb3-peri" for a generic R-Car Gen3 compatible + device + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + - reg: Base address and length of the register for the USB3.0 Peripheral - interrupts: Interrupt specifier for the USB3.0 Peripheral - clocks: clock phandle and specifier pair -Example: +Example of R-Car H3 ES1.x: usb3_peri0: usb@ee020000 { - compatible = "renesas,r8a7795-usb3-peri"; + compatible = "renesas,r8a7795-usb3-peri", + "renesas,rcar-gen3-usb3-peri"; reg = <0 0xee020000 0 0x400>; interrupts = ; clocks = <&cpg CPG_MOD 328>; }; usb3_peri1: usb@ee060000 { - compatible = "renesas,r8a7795-usb3-peri"; + compatible = "renesas,r8a7795-usb3-peri", + "renesas,rcar-gen3-usb3-peri"; reg = <0 0xee060000 0 0x400>; interrupts = ; clocks = <&cpg CPG_MOD 327>; diff --git a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt index 0536a938e3ab..50a31536e975 100644 --- a/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt +++ b/Documentation/devicetree/bindings/usb/rockchip,dwc3.txt @@ -29,13 +29,11 @@ Example device nodes: #address-cells = <2>; #size-cells = <2>; ranges; - status = "disabled"; usbdrd_dwc3_0: dwc3@fe800000 { compatible = "snps,dwc3"; reg = <0x0 0xfe800000 0x0 0x100000>; interrupts = ; dr_mode = "otg"; - status = "disabled"; }; }; @@ -48,12 +46,10 @@ Example device nodes: #address-cells = <2>; #size-cells = <2>; ranges; - status = "disabled"; usbdrd_dwc3_1: dwc3@fe900000 { compatible = "snps,dwc3"; reg = <0x0 0xfe900000 0x0 0x100000>; interrupts = ; dr_mode = "otg"; - status = "disabled"; }; }; diff --git a/Documentation/devicetree/bindings/usb/usb-device.txt b/Documentation/devicetree/bindings/usb/usb-device.txt index 1c35e7b665e1..ce02cebac26a 100644 --- a/Documentation/devicetree/bindings/usb/usb-device.txt +++ b/Documentation/devicetree/bindings/usb/usb-device.txt @@ -2,7 +2,7 @@ Generic USB Device Properties Usually, we only use device tree for hard wired USB device. The reference binding doc is from: -http://www.firmware.org/1275/bindings/usb/usb-1_0.ps +http://www.devicetree.org/open-firmware/bindings/usb/usb-1_0.ps Required properties: - compatible: usbVID,PID. The textual representation of VID, PID shall @@ -16,7 +16,6 @@ Required properties: Example: &usb1 { - status = "okay"; #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index daf465bef758..1afd298eddd7 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -3,12 +3,13 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order. This isn't an exhaustive list, but you should add new prefixes to it before using them to avoid name-space collisions. -abcn Abracon Corporation abilis Abilis Systems +abracon Abracon Corporation actions Actions Semiconductor Co., Ltd. active-semi Active-Semi International Inc ad Avionic Design GmbH adapteva Adapteva, Inc. +adaptrum Adaptrum, Inc. adh AD Holdings Plc. adi Analog Devices, Inc. advantech Advantech Corporation @@ -47,6 +48,7 @@ avic Shanghai AVIC Optoelectronics Co., Ltd. axentia Axentia Technologies AB axis Axis Communications AB bananapi BIPAI KEJI LIMITED +bhf Beckhoff Automation GmbH & Co. KG boe BOE Technology Group Co., Ltd. bosch Bosch Sensortec GmbH boundary Boundary Devices Inc. @@ -88,6 +90,7 @@ dlg Dialog Semiconductor dlink D-Link Corporation dmo Data Modul AG domintech Domintech Co., Ltd. +dongwoon Dongwoon Anatech dptechnics DPTechnics dragino Dragino Technology Co., Limited ea Embedded Artists AB @@ -175,6 +178,7 @@ kosagi Sutajio Ko-Usagi PTE Ltd. kyo Kyocera Corporation lacie LaCie lantiq Lantiq Semiconductor +lattice Lattice Semiconductor lego LEGO Systems A/S lenovo Lenovo Group Ltd. lg LG Corporation @@ -195,6 +199,7 @@ mediatek MediaTek Inc. megachips MegaChips melexis Melexis N.V. melfas MELFAS Inc. +mellanox Mellanox Technologies memsic MEMSIC Inc. merrii Merrii Technology Co., Ltd. micrel Micrel Inc. @@ -206,7 +211,7 @@ miramems MiraMEMS Sensing Technology Co., Ltd. mitsubishi Mitsubishi Electric Corporation mosaixtech Mosaix Technologies, Inc. motorola Motorola, Inc. -moxa Moxa +moxa Moxa Inc. mpl MPL AG mqmaker mqmaker Inc. msi Micro-Star International Co. Ltd. @@ -249,6 +254,7 @@ oxsemi Oxford Semiconductor, Ltd. panasonic Panasonic Corporation parade Parade Technologies Inc. pericom Pericom Technology Inc. +pervasive Pervasive Displays, Inc. phytec PHYTEC Messtechnik GmbH picochip Picochip Ltd pine64 Pine64 @@ -287,6 +293,7 @@ schindler Schindler seagate Seagate Technology PLC semtech Semtech Corporation sensirion Sensirion AG +sff Small Form Factor Committee sgx SGX Sensortech sharp Sharp Corporation si-en Si-En Technology Ltd. @@ -341,6 +348,7 @@ tpo TPO tronfy Tronfy tronsmart Tronsmart truly Truly Semiconductors Limited +tsd Theobroma Systems Design und Consulting GmbH tyan Tyan Computer Corporation ucrobotics uCRobotics udoo Udoo @@ -353,6 +361,7 @@ variscite Variscite Ltd. via VIA Technologies, Inc. virtio Virtual I/O Device Specification, developed by the OASIS consortium vivante Vivante Corporation +vocore VoCore Studio voipac Voipac Technologies s.r.o. wd Western Digital Corp. wetek WeTek Electronics, limited. diff --git a/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt b/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt index ecf42c07684d..cbaa6467ab2c 100644 --- a/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt +++ b/Documentation/devicetree/bindings/w1/fsl-imx-owire.txt @@ -15,5 +15,4 @@ owire: owire@63fa4000 { compatible = "fsl,imx53-owire", "fsl,imx21-owire"; reg = <0x63fa4000 0x4000>; clocks = <&clks 159>; - status = "disabled"; }; diff --git a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt index c5e74d7b4406..c5077a1f5cb3 100644 --- a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt @@ -8,9 +8,49 @@ Required properties: - reg: physical base address of the controller and length of memory mapped region +Optional properties: + + - aspeed,reset-type = "cpu|soc|system|none" + + Reset behavior - Whenever a timeout occurs the watchdog can be programmed + to generate one of three different, mutually exclusive, types of resets. + + Type "none" can be specified to indicate that no resets are to be done. + This is useful in situations where another watchdog engine on chip is + to perform the reset. + + If 'aspeed,reset-type=' is not specfied the default is to enable system + reset. + + Reset types: + + - cpu: Reset CPU on watchdog timeout + + - soc: Reset 'System on Chip' on watchdog timeout + + - system: Reset system on watchdog timeout + + - none: No reset is performed on timeout. Assumes another watchdog + engine is responsible for this. + + - aspeed,alt-boot: If property is present then boot from alternate block. + - aspeed,external-signal: If property is present then signal is sent to + external reset counter (only WDT1 and WDT2). If not + specified no external signal is sent. + - aspeed,ext-pulse-duration: External signal pulse duration in microseconds + +Optional properties for AST2500-compatible watchdogs: + - aspeed,ext-push-pull: If aspeed,external-signal is present, set the pin's + drive type to push-pull. The default is open-drain. + - aspeed,ext-active-high: If aspeed,external-signal is present and and the pin + is configured as push-pull, then set the pulse + polarity to active-high. The default is active-low. + Example: wdt1: watchdog@1e785000 { compatible = "aspeed,ast2400-wdt"; reg = <0x1e785000 0x1c>; + aspeed,reset-type = "system"; + aspeed,external-signal; }; diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt index f7cc7c060910..4fec1e3725b4 100644 --- a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt @@ -31,5 +31,4 @@ Example: atmel,watchdog-type = "hardware"; atmel,dbg-halt; atmel,idle-halt; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt index 86fa6de1019b..711a880b3d3b 100644 --- a/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/atmel-wdt.txt @@ -48,5 +48,4 @@ Example: atmel,idle-halt; atmel,max-heartbeat-sec = <16>; atmel,min-heartbeat-sec = <0>; - status = "okay"; }; diff --git a/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt b/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt new file mode 100644 index 000000000000..18d4d8302702 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/lantiq-wdt.txt @@ -0,0 +1,24 @@ +Lantiq WTD watchdog binding +============================ + +This describes the binding of the Lantiq watchdog driver. + +------------------------------------------------------------------------------- +Required properties: +- compatible : Should be one of + "lantiq,wdt" + "lantiq,xrx100-wdt" + "lantiq,xrx200-wdt", "lantiq,xrx100-wdt" + "lantiq,falcon-wdt" +- reg : Address of the watchdog block +- lantiq,rcu : A phandle to the RCU syscon (required for + "lantiq,falcon-wdt" and "lantiq,xrx100-wdt") + +------------------------------------------------------------------------------- +Example for the watchdog on the xRX200 SoCs: + watchdog@803f0 { + compatible = "lantiq,xrx200-wdt", "lantiq,xrx100-wdt"; + reg = <0x803f0 0x10>; + + lantiq,rcu = <&rcu0>; + }; diff --git a/Documentation/devicetree/bindings/watchdog/marvel.txt b/Documentation/devicetree/bindings/watchdog/marvel.txt index 858ed9221ac4..c1b67a78f00c 100644 --- a/Documentation/devicetree/bindings/watchdog/marvel.txt +++ b/Documentation/devicetree/bindings/watchdog/marvel.txt @@ -41,6 +41,5 @@ Example: reg = <0x20300 0x28>, <0x20108 0x4>; interrupts = <3>; timeout-sec = <10>; - status = "okay"; clocks = <&gate_clk 7>; }; diff --git a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt index ae70185d96e6..8a6d84cb36c9 100644 --- a/Documentation/devicetree/bindings/watchdog/meson-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/meson-wdt.txt @@ -2,7 +2,11 @@ Meson SoCs Watchdog timer Required properties: -- compatible : should be "amlogic,meson6-wdt" or "amlogic,meson8b-wdt" +- compatible : depending on the SoC this should be one of: + "amlogic,meson6-wdt" on Meson6 SoCs + "amlogic,meson8-wdt" and "amlogic,meson6-wdt" on Meson8 SoCs + "amlogic,meson8b-wdt" on Meson8b SoCs + "amlogic,meson8m2-wdt" and "amlogic,meson8b-wdt" on Meson8m2 SoCs - reg : Specifies base physical address and size of the registers. Example: diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt index 6a00939a059a..235de0683bb6 100644 --- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt @@ -3,9 +3,11 @@ Mediatek SoCs Watchdog timer Required properties: - compatible should contain: - * "mediatek,mt2701-wdt" for MT2701 compatible watchdog timers - * "mediatek,mt6589-wdt" for all compatible watchdog timers (MT2701, - MT6589) + "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701 + "mediatek,mt6589-wdt": for MT6589 + "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797 + "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622 + "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623 - reg : Specifies base physical address and size of the registers. diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt index 9e306afbbd49..bf6d1ca58af7 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt +++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt @@ -6,6 +6,7 @@ Required properties: Examples with soctypes are: - "renesas,r8a7795-wdt" (R-Car H3) - "renesas,r8a7796-wdt" (R-Car M3-W) + - "renesas,r8a77995-wdt" (R-Car D3) - "renesas,r7s72100-wdt" (RZ/A1) When compatible with the generic version, nodes must list the SoC-specific diff --git a/Documentation/devicetree/bindings/xilinx.txt b/Documentation/devicetree/bindings/xilinx.txt index 299d0923537b..1d11b9002ef8 100644 --- a/Documentation/devicetree/bindings/xilinx.txt +++ b/Documentation/devicetree/bindings/xilinx.txt @@ -281,6 +281,8 @@ capabilities of the underlying ICAP hardware differ between different families. May be 'virtex2p', 'virtex4', or 'virtex5'. + - compatible : should contain "xlnx,xps-hwicap-1.00.a" or + "xlnx,opb-hwicap-1.00.b". vi) Xilinx Uart 16550 diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index fb740445199f..417f91110010 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt @@ -1282,7 +1282,7 @@ hierarchy and routing of interrupts in the hardware. The interrupt tree model is fully described in the document "Open Firmware Recommended Practice: Interrupt Mapping Version 0.9". The document is available at: - + 1) interrupts property ---------------------- diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt index e33bc1c8ed2c..5dbe054a40ad 100644 --- a/Documentation/dmaengine/provider.txt +++ b/Documentation/dmaengine/provider.txt @@ -181,13 +181,6 @@ Currently, the types available are: - Used by the client drivers to register a callback that will be called on a regular basis through the DMA controller interrupt - * DMA_SG - - The device supports memory to memory scatter-gather - transfers. - - Even though a plain memcpy can look like a particular case of a - scatter-gather transfer, with a single chunk to transfer, it's a - distinct transaction type in the mem2mem transfers case - * DMA_PRIVATE - The devices only supports slave transfers, and as such isn't available for async transfers. @@ -395,6 +388,13 @@ where to put them) when DMA_CTRL_REUSE is already set - Terminating the channel + * DMA_PREP_CMD + - If set, the client driver tells DMA controller that passed data in DMA + API is command data. + - Interpretation of command data is DMA controller specific. It can be + used for issuing commands to other peripherals/register reads/register + writes for which the descriptor should be in different format from + normal data descriptors. General Design Notes -------------------- diff --git a/Documentation/doc-guide/sphinx.rst b/Documentation/doc-guide/sphinx.rst index 84e8e8a9cbdb..a2417633fdd8 100644 --- a/Documentation/doc-guide/sphinx.rst +++ b/Documentation/doc-guide/sphinx.rst @@ -19,6 +19,110 @@ Finally, there are thousands of plain text documentation files scattered around ``Documentation``. Some of these will likely be converted to reStructuredText over time, but the bulk of them will remain in plain text. +.. _sphinx_install: + +Sphinx Install +============== + +The ReST markups currently used by the Documentation/ files are meant to be +built with ``Sphinx`` version 1.3 or upper. If you're desiring to build +PDF outputs, it is recommended to use version 1.4.6 or upper. + +There's a script that checks for the Spinx requirements. Please see +:ref:`sphinx-pre-install` for further details. + +Most distributions are shipped with Sphinx, but its toolchain is fragile, +and it is not uncommon that upgrading it or some other Python packages +on your machine would cause the documentation build to break. + +A way to get rid of that is to use a different version than the one shipped +on your distributions. In order to do that, it is recommended to install +Sphinx inside a virtual environment, using ``virtualenv-3`` +or ``virtualenv``, depending on how your distribution packaged Python 3. + +.. note:: + + #) Sphinx versions below 1.5 don't work properly with Python's + docutils version 0.13.1 or upper. So, if you're willing to use + those versions, you should run ``pip install 'docutils==0.12'``. + + #) It is recommended to use the RTD theme for html output. Depending + on the Sphinx version, it should be installed in separate, + with ``pip install sphinx_rtd_theme``. + + #) Some ReST pages contain math expressions. Due to the way Sphinx work, + those expressions are written using LaTeX notation. It needs texlive + installed with amdfonts and amsmath in order to evaluate them. + +In summary, if you want to install Sphinx version 1.4.9, you should do:: + + $ virtualenv sphinx_1.4 + $ . sphinx_1.4/bin/activate + (sphinx_1.4) $ pip install -r Documentation/sphinx/requirements.txt + +After running ``. sphinx_1.4/bin/activate``, the prompt will change, +in order to indicate that you're using the new environment. If you +open a new shell, you need to rerun this command to enter again at +the virtual environment before building the documentation. + +Image output +------------ + +The kernel documentation build system contains an extension that +handles images on both GraphViz and SVG formats (see +:ref:`sphinx_kfigure`). + +For it to work, you need to install both GraphViz and ImageMagick +packages. If those packages are not installed, the build system will +still build the documentation, but won't include any images at the +output. + +PDF and LaTeX builds +-------------------- + +Such builds are currently supported only with Sphinx versions 1.4 and upper. + +For PDF and LaTeX output, you'll also need ``XeLaTeX`` version 3.14159265. + +Depending on the distribution, you may also need to install a series of +``texlive`` packages that provide the minimal set of functionalities +required for ``XeLaTeX`` to work. + +.. _sphinx-pre-install: + +Checking for Sphinx dependencies +-------------------------------- + +There's a script that automatically check for Sphinx dependencies. If it can +recognize your distribution, it will also give a hint about the install +command line options for your distro:: + + $ ./scripts/sphinx-pre-install + Checking if the needed tools for Fedora release 26 (Twenty Six) are available + Warning: better to also install "texlive-luatex85". + You should run: + + sudo dnf install -y texlive-luatex85 + /usr/bin/virtualenv sphinx_1.4 + . sphinx_1.4/bin/activate + pip install -r Documentation/sphinx/requirements.txt + + Can't build as 1 mandatory dependency is missing at ./scripts/sphinx-pre-install line 468. + +By default, it checks all the requirements for both html and PDF, including +the requirements for images, math expressions and LaTeX build, and assumes +that a virtual Python environment will be used. The ones needed for html +builds are assumed to be mandatory; the others to be optional. + +It supports two optional parameters: + +``--no-pdf`` + Disable checks for PDF; + +``--no-virtualenv`` + Use OS packaging for Sphinx instead of Python virtual environment. + + Sphinx Build ============ @@ -118,7 +222,7 @@ Here are some specific guidelines for the kernel documentation: the C domain ------------ -The `Sphinx C Domain`_ (name c) is suited for documentation of C API. E.g. a +The **Sphinx C Domain** (name c) is suited for documentation of C API. E.g. a function prototype: .. code-block:: rst @@ -229,6 +333,7 @@ Rendered as: - column 3 +.. _sphinx_kfigure: Figures & Images ================ diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 358b47c06ad4..2228fcc8e29f 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -259,5 +259,4 @@ wakeup.bin wakeup.elf wakeup.lds zImage* -zconf.hash.c zoffset.h diff --git a/Documentation/driver-api/basics.rst b/Documentation/driver-api/basics.rst index ab82250c7727..73fa7d42bbba 100644 --- a/Documentation/driver-api/basics.rst +++ b/Documentation/driver-api/basics.rst @@ -4,7 +4,7 @@ Driver Basics Driver Entry and Exit points ---------------------------- -.. kernel-doc:: include/linux/init.h +.. kernel-doc:: include/linux/module.h :internal: Driver device table @@ -103,9 +103,6 @@ Kernel utility functions .. kernel-doc:: kernel/panic.c :export: -.. kernel-doc:: kernel/sys.c - :export: - .. kernel-doc:: kernel/rcu/tree.c :export: diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index 31671b469627..dc384f2f7f34 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -139,9 +139,6 @@ DMA Fences Seqno Hardware Fences ~~~~~~~~~~~~~~~~~~~~~ -.. kernel-doc:: drivers/dma-buf/seqno-fence.c - :export: - .. kernel-doc:: include/linux/seqno-fence.h :internal: diff --git a/Documentation/driver-api/firmware/request_firmware.rst b/Documentation/driver-api/firmware/request_firmware.rst index 1c2c4967cd43..cc0aea880824 100644 --- a/Documentation/driver-api/firmware/request_firmware.rst +++ b/Documentation/driver-api/firmware/request_firmware.rst @@ -44,17 +44,6 @@ request_firmware_nowait .. kernel-doc:: drivers/base/firmware_class.c :functions: request_firmware_nowait -Considerations for suspend and resume -===================================== - -During suspend and resume only the built-in firmware and the firmware cache -elements of the firmware API can be used. This is managed by fw_pm_notify(). - -fw_pm_notify ------------- -.. kernel-doc:: drivers/base/firmware_class.c - :functions: fw_pm_notify - request firmware API expected driver use ======================================== diff --git a/Documentation/driver-api/gpio.rst b/Documentation/driver-api/gpio.rst new file mode 100644 index 000000000000..6dd4aa647f27 --- /dev/null +++ b/Documentation/driver-api/gpio.rst @@ -0,0 +1,45 @@ +=================================== +General Purpose Input/Output (GPIO) +=================================== + +Core +==== + +.. kernel-doc:: include/linux/gpio/driver.h + :internal: + +.. kernel-doc:: drivers/gpio/gpiolib.c + :export: + +Legacy API +========== + +The functions listed in this section are deprecated. The GPIO descriptor based +API described above should be used in new code. + +.. kernel-doc:: drivers/gpio/gpiolib-legacy.c + :export: + +ACPI support +============ + +.. kernel-doc:: drivers/gpio/gpiolib-acpi.c + :export: + +Device tree support +=================== + +.. kernel-doc:: drivers/gpio/gpiolib-of.c + :export: + +Device-managed API +================== + +.. kernel-doc:: drivers/gpio/devres.c + :export: + +sysfs helpers +============= + +.. kernel-doc:: drivers/gpio/gpiolib-sysfs.c + :export: diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 7c94ab50afed..9c20624842b7 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -44,6 +44,7 @@ available subsections can be seen below. uio-howto firmware/index pinctl + gpio misc_devices .. only:: subproject and html diff --git a/Documentation/driver-api/miscellaneous.rst b/Documentation/driver-api/miscellaneous.rst index 8da7d115bafc..304ffb146cf9 100644 --- a/Documentation/driver-api/miscellaneous.rst +++ b/Documentation/driver-api/miscellaneous.rst @@ -47,4 +47,3 @@ used by one consumer at a time. .. kernel-doc:: drivers/pwm/core.c :export: - diff --git a/Documentation/driver-api/mtdnand.rst b/Documentation/driver-api/mtdnand.rst index e9afa586d15e..2a5191b6d445 100644 --- a/Documentation/driver-api/mtdnand.rst +++ b/Documentation/driver-api/mtdnand.rst @@ -516,7 +516,7 @@ mirrored table is performed. The most important field in the nand_bbt_descr structure is the options field. The options define most of the table properties. Use the -predefined constants from nand.h to define the options. +predefined constants from rawnand.h to define the options. - Number of bits per block @@ -843,7 +843,7 @@ Chip option constants Constants for chip id table ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These constants are defined in nand.h. They are OR-ed together to +These constants are defined in rawnand.h. They are OR-ed together to describe the chip functionality:: /* Buswitdh is 16 bit */ @@ -865,7 +865,7 @@ describe the chip functionality:: Constants for runtime options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These constants are defined in nand.h. They are OR-ed together to +These constants are defined in rawnand.h. They are OR-ed together to describe the functionality:: /* The hw ecc generator provides a syndrome instead a ecc value on read @@ -956,7 +956,7 @@ developer. Each struct member has a short description which is marked with an [XXX] identifier. See the chapter "Documentation hints" for an explanation. -.. kernel-doc:: include/linux/mtd/nand.h +.. kernel-doc:: include/linux/mtd/rawnand.h :internal: Public Functions Provided diff --git a/Documentation/driver-api/pm/devices.rst b/Documentation/driver-api/pm/devices.rst index bedd32388dac..a0dc2879a152 100644 --- a/Documentation/driver-api/pm/devices.rst +++ b/Documentation/driver-api/pm/devices.rst @@ -675,7 +675,7 @@ sub-domain of the parent domain. Support for power domains is provided through the :c:member:`pm_domain` field of |struct device|. This field is a pointer to an object of type -|struct dev_pm_domain|, defined in :file:`include/linux/pm.h``, providing a set +|struct dev_pm_domain|, defined in :file:`include/linux/pm.h`, providing a set of power management callbacks analogous to the subsystem-level and device driver callbacks that are executed for the given device during all power transitions, instead of the respective subsystem-level callbacks. Specifically, if a diff --git a/Documentation/driver-api/s390-drivers.rst b/Documentation/driver-api/s390-drivers.rst index 7060da136095..ecf8851d3565 100644 --- a/Documentation/driver-api/s390-drivers.rst +++ b/Documentation/driver-api/s390-drivers.rst @@ -75,7 +75,7 @@ The channel-measurement facility provides a means to collect measurement data which is made available by the channel subsystem for each channel attached device. -.. kernel-doc:: arch/s390/include/asm/cmb.h +.. kernel-doc:: arch/s390/include/uapi/asm/cmb.h :internal: .. kernel-doc:: drivers/s390/cio/cmf.c diff --git a/Documentation/driver-api/scsi.rst b/Documentation/driver-api/scsi.rst index 859fb672319f..5a2aa7a377d9 100644 --- a/Documentation/driver-api/scsi.rst +++ b/Documentation/driver-api/scsi.rst @@ -224,14 +224,6 @@ mid to lowlevel SCSI driver interface .. kernel-doc:: drivers/scsi/hosts.c :export: -drivers/scsi/constants.c -~~~~~~~~~~~~~~~~~~~~~~~~ - -mid to lowlevel SCSI driver interface - -.. kernel-doc:: drivers/scsi/constants.c - :export: - Transport classes ----------------- diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 30e04f7a690d..69f08c0f23a8 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -312,6 +312,7 @@ IRQ devm_irq_alloc_descs_from() devm_irq_alloc_generic_chip() devm_irq_setup_generic_chip() + devm_irq_sim_init() LED devm_led_classdev_register() diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index 4421135826a2..d661e6f7e6a0 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt @@ -196,12 +196,13 @@ struct driver_attribute { }; Device drivers can export attributes via their sysfs directories. -Drivers can declare attributes using a DRIVER_ATTR macro that works -identically to the DEVICE_ATTR macro. +Drivers can declare attributes using a DRIVER_ATTR_RW and DRIVER_ATTR_RO +macro that works identically to the DEVICE_ATTR_RW and DEVICE_ATTR_RO +macros. Example: -DRIVER_ATTR(debug,0644,show_debug,store_debug); +DRIVER_ATTR_RW(debug); This is equivalent to declaring: diff --git a/Documentation/errseq.rst b/Documentation/errseq.rst new file mode 100644 index 000000000000..4c29bd5afbc5 --- /dev/null +++ b/Documentation/errseq.rst @@ -0,0 +1,149 @@ +The errseq_t datatype +===================== +An errseq_t is a way of recording errors in one place, and allowing any +number of "subscribers" to tell whether it has changed since a previous +point where it was sampled. + +The initial use case for this is tracking errors for file +synchronization syscalls (fsync, fdatasync, msync and sync_file_range), +but it may be usable in other situations. + +It's implemented as an unsigned 32-bit value. The low order bits are +designated to hold an error code (between 1 and MAX_ERRNO). The upper bits +are used as a counter. This is done with atomics instead of locking so that +these functions can be called from any context. + +Note that there is a risk of collisions if new errors are being recorded +frequently, since we have so few bits to use as a counter. + +To mitigate this, the bit between the error value and counter is used as +a flag to tell whether the value has been sampled since a new value was +recorded. That allows us to avoid bumping the counter if no one has +sampled it since the last time an error was recorded. + +Thus we end up with a value that looks something like this:: + + bit: 31..13 12 11..0 + +-----------------+----+----------------+ + | counter | SF | errno | + +-----------------+----+----------------+ + +The general idea is for "watchers" to sample an errseq_t value and keep +it as a running cursor. That value can later be used to tell whether +any new errors have occurred since that sampling was done, and atomically +record the state at the time that it was checked. This allows us to +record errors in one place, and then have a number of "watchers" that +can tell whether the value has changed since they last checked it. + +A new errseq_t should always be zeroed out. An errseq_t value of all zeroes +is the special (but common) case where there has never been an error. An all +zero value thus serves as the "epoch" if one wishes to know whether there +has ever been an error set since it was first initialized. + +API usage +========= +Let me tell you a story about a worker drone. Now, he's a good worker +overall, but the company is a little...management heavy. He has to +report to 77 supervisors today, and tomorrow the "big boss" is coming in +from out of town and he's sure to test the poor fellow too. + +They're all handing him work to do -- so much he can't keep track of who +handed him what, but that's not really a big problem. The supervisors +just want to know when he's finished all of the work they've handed him so +far and whether he made any mistakes since they last asked. + +He might have made the mistake on work they didn't actually hand him, +but he can't keep track of things at that level of detail, all he can +remember is the most recent mistake that he made. + +Here's our worker_drone representation:: + + struct worker_drone { + errseq_t wd_err; /* for recording errors */ + }; + +Every day, the worker_drone starts out with a blank slate:: + + struct worker_drone wd; + + wd.wd_err = (errseq_t)0; + +The supervisors come in and get an initial read for the day. They +don't care about anything that happened before their watch begins:: + + struct supervisor { + errseq_t s_wd_err; /* private "cursor" for wd_err */ + spinlock_t s_wd_err_lock; /* protects s_wd_err */ + } + + struct supervisor su; + + su.s_wd_err = errseq_sample(&wd.wd_err); + spin_lock_init(&su.s_wd_err_lock); + +Now they start handing him tasks to do. Every few minutes they ask him to +finish up all of the work they've handed him so far. Then they ask him +whether he made any mistakes on any of it:: + + spin_lock(&su.su_wd_err_lock); + err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); + spin_unlock(&su.su_wd_err_lock); + +Up to this point, that just keeps returning 0. + +Now, the owners of this company are quite miserly and have given him +substandard equipment with which to do his job. Occasionally it +glitches and he makes a mistake. He sighs a heavy sigh, and marks it +down:: + + errseq_set(&wd.wd_err, -EIO); + +...and then gets back to work. The supervisors eventually poll again +and they each get the error when they next check. Subsequent calls will +return 0, until another error is recorded, at which point it's reported +to each of them once. + +Note that the supervisors can't tell how many mistakes he made, only +whether one was made since they last checked, and the latest value +recorded. + +Occasionally the big boss comes in for a spot check and asks the worker +to do a one-off job for him. He's not really watching the worker +full-time like the supervisors, but he does need to know whether a +mistake occurred while his job was processing. + +He can just sample the current errseq_t in the worker, and then use that +to tell whether an error has occurred later:: + + errseq_t since = errseq_sample(&wd.wd_err); + /* submit some work and wait for it to complete */ + err = errseq_check(&wd.wd_err, since); + +Since he's just going to discard "since" after that point, he doesn't +need to advance it here. He also doesn't need any locking since it's +not usable by anyone else. + +Serializing errseq_t cursor updates +=================================== +Note that the errseq_t API does not protect the errseq_t cursor during a +check_and_advance_operation. Only the canonical error code is handled +atomically. In a situation where more than one task might be using the +same errseq_t cursor at the same time, it's important to serialize +updates to that cursor. + +If that's not done, then it's possible for the cursor to go backward +in which case the same error could be reported more than once. + +Because of this, it's often advantageous to first do an errseq_check to +see if anything has changed, and only later do an +errseq_check_and_advance after taking the lock. e.g.:: + + if (errseq_check(&wd.wd_err, READ_ONCE(su.s_wd_err)) { + /* su.s_wd_err is protected by s_wd_err_lock */ + spin_lock(&su.s_wd_err_lock); + err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); + spin_unlock(&su.s_wd_err_lock); + } + +That avoids the spinlock in the common case where nothing has changed +since the last time it was checked. diff --git a/Documentation/fb/fbcon.txt b/Documentation/fb/fbcon.txt index 4a9739abc860..a38d3aa4d189 100644 --- a/Documentation/fb/fbcon.txt +++ b/Documentation/fb/fbcon.txt @@ -148,6 +148,13 @@ C. Boot options Actually, the underlying fb driver is totally ignorant of console rotation. +5. fbcon=margin: + + This option specifies the color of the margins. The margins are the + leftover area at the right and the bottom of the screen that are not + used by text. By default, this area will be black. The 'color' value + is an integer number that depends on the framebuffer driver being used. + C. Attaching, Detaching and Unloading Before going on how to attach, detach and unload the framebuffer console, an diff --git a/Documentation/features/core/tracehook/arch-support.txt b/Documentation/features/core/tracehook/arch-support.txt index 5e97a89420ef..dfb638c2f842 100644 --- a/Documentation/features/core/tracehook/arch-support.txt +++ b/Documentation/features/core/tracehook/arch-support.txt @@ -25,7 +25,7 @@ | mn10300: | ok | | nios2: | ok | | openrisc: | ok | - | parisc: | TODO | + | parisc: | ok | | powerpc: | ok | | s390: | ok | | score: | TODO | diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index fe25787ff6d4..75d2d57e2c44 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -22,7 +22,7 @@ prototypes: struct vfsmount *(*d_automount)(struct path *path); int (*d_manage)(const struct path *, bool); struct dentry *(*d_real)(struct dentry *, const struct inode *, - unsigned int); + unsigned int, unsigned int); locking rules: rename_lock ->d_lock may block rcu-walk diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt index aed6b94160b1..0eb31de3a2c1 100644 --- a/Documentation/filesystems/caching/netfs-api.txt +++ b/Documentation/filesystems/caching/netfs-api.txt @@ -151,8 +151,6 @@ To define an object, a structure of the following type should be filled out: void (*mark_pages_cached)(void *cookie_netfs_data, struct address_space *mapping, struct pagevec *cached_pvec); - - void (*now_uncached)(void *cookie_netfs_data); }; This has the following fields: diff --git a/Documentation/filesystems/cifs/AUTHORS b/Documentation/filesystems/cifs/AUTHORS index c98800df677f..9f4f87e16240 100644 --- a/Documentation/filesystems/cifs/AUTHORS +++ b/Documentation/filesystems/cifs/AUTHORS @@ -41,6 +41,11 @@ Igor Mammedov (DFS support) Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code) Scott Lovenberg Pavel Shilovsky (for great work adding SMB2 support, and various SMB3 features) +Aurelien Aptel (for DFS SMB3 work and some key bug fixes) +Ronnie Sahlberg (for SMB3 xattr work and bug fixes) +Shirish Pargaonkar (for many ACL patches over the years) +Sachin Prabhu (many bug fixes, including for reconnect, copy offload and security) + Test case and Bug Report contributors ------------------------------------- diff --git a/Documentation/filesystems/cifs/README b/Documentation/filesystems/cifs/README index a54788405429..a9da51553ba3 100644 --- a/Documentation/filesystems/cifs/README +++ b/Documentation/filesystems/cifs/README @@ -1,10 +1,14 @@ -The CIFS VFS support for Linux supports many advanced network filesystem -features such as hierarchical dfs like namespace, hardlinks, locking and more. +This module supports the SMB3 family of advanced network protocols (as well +as older dialects, originally called "CIFS" or SMB1). + +The CIFS VFS module for Linux supports many advanced network filesystem +features such as hierarchical DFS like namespace, hardlinks, locking and more. It was designed to comply with the SNIA CIFS Technical Reference (which supersedes the 1992 X/Open SMB Standard) as well as to perform best practice practical interoperability with Windows 2000, Windows XP, Samba and equivalent servers. This code was developed in participation with the Protocol Freedom -Information Foundation. +Information Foundation. CIFS and now SMB3 has now become a defacto +standard for interoperating between Macs and Windows and major NAS appliances. Please see http://protocolfreedom.org/ and @@ -15,30 +19,11 @@ for more details. For questions or bug reports please contact: sfrench@samba.org (sfrench@us.ibm.com) +See the project page at: https://wiki.samba.org/index.php/LinuxCIFS_utils + Build instructions: ================== -For Linux 2.4: -1) Get the kernel source (e.g.from http://www.kernel.org) -and download the cifs vfs source (see the project page -at http://us1.samba.org/samba/Linux_CIFS_client.html) -and change directory into the top of the kernel directory -then patch the kernel (e.g. "patch -p1 < cifs_24.patch") -to add the cifs vfs to your kernel configure options if -it has not already been added (e.g. current SuSE and UL -users do not need to apply the cifs_24.patch since the cifs vfs is -already in the kernel configure menu) and then -mkdir linux/fs/cifs and then copy the current cifs vfs files from -the cifs download to your kernel build directory e.g. - - cp /fs/cifs/* to /fs/cifs - -2) make menuconfig (or make xconfig) -3) select cifs from within the network filesystem choices -4) save and exit -5) make dep -6) make modules (or "make" if CIFS VFS not to be built as a module) - -For Linux 2.6: +For Linux: 1) Download the kernel (e.g. from http://www.kernel.org) and change directory into the top of the kernel directory tree (e.g. /usr/src/linux-2.5.73) @@ -61,16 +46,13 @@ would simply type "make install"). If you do not have the utility mount.cifs (in the Samba 3.0 source tree and on the CIFS VFS web site) copy it to the same directory in which mount.smbfs and similar files reside (usually /sbin). Although the helper software is not -required, mount.cifs is recommended. Eventually the Samba 3.0 utility program -"net" may also be helpful since it may someday provide easier mount syntax for -users who are used to Windows e.g. - net use +required, mount.cifs is recommended. Most distros include a "cifs-utils" +package that includes this utility so it is recommended to install this. + Note that running the Winbind pam/nss module (logon service) on all of your Linux clients is useful in mapping Uids and Gids consistently across the domain to the proper network user. The mount.cifs mount helper can be -trivially built from Samba 3.0 or later source e.g. by executing: - - gcc samba/source/client/mount.cifs.c -o mount.cifs +found at cifs-utils.git on git.samba.org If cifs is built as a module, then the size and number of network buffers and maximum number of simultaneous requests to one server can be configured. @@ -79,6 +61,18 @@ Changing these from their defaults is not recommended. By executing modinfo on kernel/fs/cifs/cifs.ko the list of configuration changes that can be made at module initialization time (by running insmod cifs.ko) can be seen. +Recommendations +=============== +To improve security the SMB2.1 dialect or later (usually will get SMB3) is now +the new default. To use old dialects (e.g. to mount Windows XP) use "vers=1.0" +on mount (or vers=2.0 for Windows Vista). Note that the CIFS (vers=1.0) is +much older and less secure than the default dialect SMB3 which includes +many advanced security features such as downgrade attack detection +and encrypted shares and stronger signing and authentication algorithms. +There are additional mount options that may be helpful for SMB3 to get +improved POSIX behavior (NB: can use vers=3.0 to force only SMB3, never 2.1): + "mfsymlinks" and "cifsacl" and "idsfromsid" + Allowing User Mounts ==================== To permit users to mount and unmount over directories they own is possible @@ -98,9 +92,7 @@ and execution of suid programs on the remote target would be enabled by default. This can be changed, as with nfs and other filesystems, by simply specifying "nosuid" among the mount options. For user mounts though to be able to pass the suid flag to mount requires rebuilding -mount.cifs with the following flag: - - gcc samba/source/client/mount.cifs.c -DCIFS_ALLOW_USR_SUID -o mount.cifs +mount.cifs with the following flag: CIFS_ALLOW_USR_SUID There is a corresponding manual page for cifs mounting in the Samba 3.0 and later source tree in docs/manpages/mount.cifs.8 @@ -189,18 +181,18 @@ applications running on the same server as Samba. Use instructions: ================ Once the CIFS VFS support is built into the kernel or installed as a module -(cifs.o), you can use mount syntax like the following to access Samba or Windows -servers: +(cifs.ko), you can use mount syntax like the following to access Samba or +Mac or Windows servers: - mount -t cifs //9.53.216.11/e$ /mnt -o user=myname,pass=mypassword + mount -t cifs //9.53.216.11/e$ /mnt -o username=myname,password=mypassword Before -o the option -v may be specified to make the mount.cifs mount helper display the mount steps more verbosely. After -o the following commonly used cifs vfs specific options are supported: - user= - pass= + username= + password= domain= Other cifs mount options are described below. Use of TCP names (in addition to @@ -246,13 +238,16 @@ the Server's registry. Samba starting with version 3.10 will allow such filenames (ie those which contain valid Linux characters, which normally would be forbidden for Windows/CIFS semantics) as long as the server is configured for Unix Extensions (and the client has not disabled -/proc/fs/cifs/LinuxExtensionsEnabled). - +/proc/fs/cifs/LinuxExtensionsEnabled). In addition the mount option +"mapposix" can be used on CIFS (vers=1.0) to force the mapping of +illegal Windows/NTFS/SMB characters to a remap range (this mount parm +is the default for SMB3). This remap ("mapposix") range is also +compatible with Mac (and "Services for Mac" on some older Windows). CIFS VFS Mount Options ====================== A partial list of the supported mount options follows: - user The user name to use when trying to establish + username The user name to use when trying to establish the CIFS session. password The user password. If the mount helper is installed, the user will be prompted for password diff --git a/Documentation/filesystems/cifs/TODO b/Documentation/filesystems/cifs/TODO index 066ffddc3964..396ecfd6ff4a 100644 --- a/Documentation/filesystems/cifs/TODO +++ b/Documentation/filesystems/cifs/TODO @@ -1,4 +1,4 @@ -Version 2.03 August 1, 2014 +Version 2.04 September 13, 2017 A Partial List of Missing Features ================================== @@ -8,73 +8,69 @@ for visible, important contributions to this module. Here is a partial list of the known problems and missing features: a) SMB3 (and SMB3.02) missing optional features: - - RDMA + - RDMA (started) - multichannel (started) - directory leases (improved metadata caching) - T10 copy offload (copy chunk is only mechanism supported) - - encrypted shares b) improved sparse file support c) Directory entry caching relies on a 1 second timer, rather than -using FindNotify or equivalent. - (started) +using Directory Leases d) quota support (needs minor kernel change since quota calls to make it to network filesystems or deviceless filesystems) -e) improve support for very old servers (OS/2 and Win9x for example) -Including support for changing the time remotely (utimes command). +e) Better optimize open to reduce redundant opens (using reference +counts more) and to improve use of compounding in SMB3 to reduce +number of roundtrips. -f) hook lower into the sockets api (as NFS/SunRPC does) to avoid the -extra copy in/out of the socket buffers in some cases. - -g) Better optimize open (and pathbased setfilesize) to reduce the -oplock breaks coming from windows srv. Piggyback identical file -opens on top of each other by incrementing reference count rather -than resending (helps reduce server resource utilization and avoid -spurious oplock breaks). - -h) Add support for storing symlink info to Windows servers -in the Extended Attribute format their SFU clients would recognize. - -i) Finish inotify support so kde and gnome file list windows +f) Finish inotify support so kde and gnome file list windows will autorefresh (partially complete by Asser). Needs minor kernel vfs change to support removing D_NOTIFY on a file. -j) Add GUI tool to configure /proc/fs/cifs settings and for display of +g) Add GUI tool to configure /proc/fs/cifs settings and for display of the CIFS statistics (started) -k) implement support for security and trusted categories of xattrs +h) implement support for security and trusted categories of xattrs (requires minor protocol extension) to enable better support for SELINUX -l) Implement O_DIRECT flag on open (already supported on mount) +i) Implement O_DIRECT flag on open (already supported on mount) -m) Create UID mapping facility so server UIDs can be mapped on a per +j) Create UID mapping facility so server UIDs can be mapped on a per mount or a per server basis to client UIDs or nobody if no mapping -exists. This is helpful when Unix extensions are negotiated to -allow better permission checking when UIDs differ on the server -and client. Add new protocol request to the CIFS protocol -standard for asking the server for the corresponding name of a -particular uid. +exists. Also better integration with winbind for resolving SID owners -n) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too) +k) Add tools to take advantage of more smb3 specific ioctls and features -o) mount check for unmatched uids +l) encrypted file support -p) Add support for new vfs entry point for fallocate +m) improved stats gathering, tools (perhaps integration with nfsometer?) -q) Add tools to take advantage of cifs/smb3 specific ioctls and features -such as "CopyChunk" (fast server side file copy) +n) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed +file attribute via chflags) and improve user space tools for managing and +viewing them. -r) encrypted file support +o) mount helper GUI (to simplify the various configuration options on mount) -s) improved stats gathering, tools (perhaps integration with nfsometer?) +p) autonegotiation of dialects (offering more than one dialect ie SMB3.02, +SMB3, SMB2.1 not just SMB3). -t) allow setting more NTFS/SMB3 file attributes remotely (currently limited to compressed -file attribute via chflags) +q) Allow mount.cifs to be more verbose in reporting errors with dialect +or unsupported feature errors. -u) mount helper GUI (to simplify the various configuration options on mount) +r) updating cifs documentation, and user guid. +s) Addressing bugs found by running a broader set of xfstests in standard +file system xfstest suite. + +t) split cifs and smb3 support into separate modules so legacy (and less +secure) CIFS dialect can be disabled in environments that don't need it +and simplify the code. + +u) Finish up SMB3.1.1 dialect support + +v) POSIX Extensions for SMB3.1.1 KNOWN BUGS ==================================== diff --git a/Documentation/filesystems/cifs/cifs.txt b/Documentation/filesystems/cifs/cifs.txt index 2fac91ac96cf..67756607246e 100644 --- a/Documentation/filesystems/cifs/cifs.txt +++ b/Documentation/filesystems/cifs/cifs.txt @@ -1,24 +1,28 @@ - This is the client VFS module for the Common Internet File System - (CIFS) protocol which is the successor to the Server Message Block + This is the client VFS module for the SMB3 NAS protocol as well + older dialects such as the Common Internet File System (CIFS) + protocol which was the successor to the Server Message Block (SMB) protocol, the native file sharing mechanism for most early PC operating systems. New and improved versions of CIFS are now called SMB2 and SMB3. These dialects are also supported by the CIFS VFS module. CIFS is fully supported by network - file servers such as Windows 2000, 2003, 2008 and 2012 + file servers such as Windows 2000, 2003, 2008, 2012 and 2016 as well by Samba (which provides excellent CIFS - server support for Linux and many other operating systems), so + server support for Linux and many other operating systems), Apple + systems, as well as most Network Attached Storage vendors, so this network filesystem client can mount to a wide variety of servers. The intent of this module is to provide the most advanced network - file system function for CIFS compliant servers, including better - POSIX compliance, secure per-user session establishment, high - performance safe distributed caching (oplock), optional packet + file system function for SMB3 compliant servers, including advanced + security features, excellent parallelized high performance i/o, better + POSIX compliance, secure per-user session establishment, encryption, + high performance safe distributed caching (leases/oplocks), optional packet signing, large files, Unicode support and other internationalization improvements. Since both Samba server and this filesystem client support - the CIFS Unix extensions, the combination can provide a reasonable - alternative to NFSv4 for fileserving in some Linux to Linux environments, - not just in Linux to Windows environments. + the CIFS Unix extensions (and in the future SMB3 POSIX extensions), + the combination can provide a reasonable alternative to other network and + cluster file systems for fileserving in some Linux to Linux environments, + not just in Linux to Windows (or Linux to Mac) environments. This filesystem has an mount utility (mount.cifs) that can be obtained from diff --git a/Documentation/filesystems/dax.txt b/Documentation/filesystems/dax.txt index a7e6e14aeb08..3be3b266be41 100644 --- a/Documentation/filesystems/dax.txt +++ b/Documentation/filesystems/dax.txt @@ -63,9 +63,8 @@ Filesystem support consists of - implementing an mmap file operation for DAX files which sets the VM_MIXEDMAP and VM_HUGEPAGE flags on the VMA, and setting the vm_ops to include handlers for fault, pmd_fault, page_mkwrite, pfn_mkwrite. These - handlers should probably call dax_iomap_fault() (for fault and page_mkwrite - handlers), dax_iomap_pmd_fault(), dax_pfn_mkwrite() passing the appropriate - iomap operations. + handlers should probably call dax_iomap_fault() passing the appropriate + fault size and iomap operations. - calling iomap_zero_range() passing appropriate iomap operations instead of block_truncate_page() for DAX files - ensuring that there is sufficient locking between reads, writes, diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index 273ccb26885e..13c2ff034348 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -164,6 +164,16 @@ io_bits=%u Set the bit size of write IO requests. It should be set with "mode=lfs". usrquota Enable plain user disk quota accounting. grpquota Enable plain group disk quota accounting. +prjquota Enable plain project quota accounting. +usrjquota= Appoint specified file and type during mount, so that quota +grpjquota= information can be properly updated during recovery flow, +prjjquota= : must be in root directory; +jqfmt= : [vfsold,vfsv0,vfsv1]. +offusrjquota Turn off user journelled quota. +offgrpjquota Turn off group journelled quota. +offprjjquota Turn off project journelled quota. +quota Enable plain user disk quota accounting. +noquota Disable all plain disk quota option. ================================================================================ DEBUGFS ENTRIES @@ -209,6 +219,15 @@ Files in /sys/fs/f2fs/ gc_idle = 1 will select the Cost Benefit approach & setting gc_idle = 2 will select the greedy approach. + gc_urgent This parameter controls triggering background GCs + urgently or not. Setting gc_urgent = 0 [default] + makes back to default behavior, while if it is set + to 1, background thread starts to do GC by given + gc_urgent_sleep_time interval. + + gc_urgent_sleep_time This parameter controls sleep time for gc_urgent. + 500 ms is set by default. See above gc_urgent. + reclaim_segments This parameter controls the number of prefree segments to be reclaimed. If the number of prefree segments is larger than the number of segments diff --git a/Documentation/filesystems/orangefs.txt b/Documentation/filesystems/orangefs.txt index 1dfdec790946..e2818b60a5c2 100644 --- a/Documentation/filesystems/orangefs.txt +++ b/Documentation/filesystems/orangefs.txt @@ -45,14 +45,11 @@ upstream version of the kernel client. BUILDING THE USERSPACE FILESYSTEM ON A SINGLE SERVER ==================================================== -When Orangefs is upstream, "--with-kernel" shouldn't be needed, but -until then the path to where the kernel with the Orangefs kernel client -patch was built is needed to ensure that pvfs2-client-core (the bridge -between kernel space and user space) will build properly. You can omit ---prefix if you don't care that things are sprinkled around in -/usr/local. +You can omit --prefix if you don't care that things are sprinkled around in +/usr/local. As of version 2.9.6, Orangefs uses Berkeley DB by default, we +will probably be changing the default to lmdb soon. -./configure --prefix=/opt/ofs --with-kernel=/path/to/orangefs/kernel +./configure --prefix=/opt/ofs --with-db-backend=lmdb make @@ -82,9 +79,6 @@ prove things are working with: /opt/osf/bin/pvfs2-ls /mymountpoint -You might not want to enforce selinux, it doesn't seem to matter by -linux 3.11... - If stuff seems to be working, turn on the client core: /opt/osf/sbin/pvfs2-client -p /opt/osf/sbin/pvfs2-client-core diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt index 36f528a7fdd6..8caa60734647 100644 --- a/Documentation/filesystems/overlayfs.txt +++ b/Documentation/filesystems/overlayfs.txt @@ -210,8 +210,11 @@ path as another overlay mount and it may use a lower layer path that is beneath or above the path of another overlay lower layer path. Using an upper layer path and/or a workdir path that are already used by -another overlay mount is not allowed and will fail with EBUSY. Using +another overlay mount is not allowed and may fail with EBUSY. Using partially overlapping paths is not allowed but will not fail with EBUSY. +If files are accessed from two overlayfs mounts which share or overlap the +upper layer and/or workdir path the behavior of the overlay is undefined, +though it will not result in a crash or deadlock. Mounting an overlay using an upper layer path, where the upper layer path was previously used by another mounted overlay in combination with a diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 5fb17f49f7a2..93e0a2404532 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting @@ -228,7 +228,7 @@ anything from oops to silent memory corruption. --- [mandatory] - FS_NOMOUNT is gone. If you use it - just set MS_NOUSER in flags + FS_NOMOUNT is gone. If you use it - just set SB_NOUSER in flags (see rootfs for one kind of solution and bdev/socket/pipe for another). --- diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index 24da7b32c489..9a3658cc399e 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt @@ -366,7 +366,8 @@ struct driver_attribute { Declaring: -DRIVER_ATTR(_name, _mode, _show, _store) +DRIVER_ATTR_RO(_name) +DRIVER_ATTR_RW(_name) Creation/Removal: diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 73e7d91f03dc..5fd325df59e2 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -829,9 +829,7 @@ struct address_space_operations { swap_activate: Called when swapon is used on a file to allocate space if necessary and pin the block lookup information in memory. A return value of zero indicates success, - in which case this file can be used to back swapspace. The - swapspace operations will be proxied to this address space's - ->swap_{out,in} methods. + in which case this file can be used to back swapspace. swap_deactivate: Called during swapoff on files where swap_activate was successful. @@ -990,7 +988,7 @@ struct dentry_operations { struct vfsmount *(*d_automount)(struct path *); int (*d_manage)(const struct path *, bool); struct dentry *(*d_real)(struct dentry *, const struct inode *, - unsigned int); + unsigned int, unsigned int); }; d_revalidate: called when the VFS needs to revalidate a dentry. This diff --git a/Documentation/gpio/drivers-on-gpio.txt b/Documentation/gpio/drivers-on-gpio.txt index 306513251713..9a78d385b92e 100644 --- a/Documentation/gpio/drivers-on-gpio.txt +++ b/Documentation/gpio/drivers-on-gpio.txt @@ -84,6 +84,11 @@ hardware descriptions such as device tree or ACPI: NAND flash MTD subsystem and provides chip access and partition parsing like any other NAND driving hardware. +- ps2-gpio: drivers/input/serio/ps2-gpio.c is used to drive a PS/2 (IBM) serio + bus, data and clock line, by bit banging two GPIO lines. It will appear as + any other serio bus to the system and makes it possible to connect drivers + for e.g. keyboards and other PS/2 protocol based devices. + Apart from this there are special GPIO drivers in subsystems like MMC/SD to read card detect and write protect GPIO lines, and in the TTY serial subsystem to emulate MCTRL (modem control) signals CTS/RTS by using two GPIO lines. The diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 0d936c67bf7d..5ee9674fb9e9 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -201,6 +201,8 @@ drivers. Open/Close, File Operations and IOCTLs ====================================== +.. _drm_driver_fops: + File Operations --------------- diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 7c5e2549a58a..13dd237418cc 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -296,3 +296,12 @@ Auxiliary Modeset Helpers .. kernel-doc:: drivers/gpu/drm/drm_modeset_helper.c :export: + +Framebuffer GEM Helper Reference +================================ + +.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/drm_gem_framebuffer_helper.c + :export: diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 2d77c9580164..307284125d7a 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -523,9 +523,6 @@ Color Management Properties .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c :doc: overview -.. kernel-doc:: include/drm/drm_color_mgmt.h - :internal: - .. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c :export: @@ -554,60 +551,8 @@ various modules/drivers. Vertical Blanking ================= -Vertical blanking plays a major role in graphics rendering. To achieve -tear-free display, users must synchronize page flips and/or rendering to -vertical blanking. The DRM API offers ioctls to perform page flips -synchronized to vertical blanking and wait for vertical blanking. - -The DRM core handles most of the vertical blanking management logic, -which involves filtering out spurious interrupts, keeping race-free -blanking counters, coping with counter wrap-around and resets and -keeping use counts. It relies on the driver to generate vertical -blanking interrupts and optionally provide a hardware vertical blanking -counter. Drivers must implement the following operations. - -- int (\*enable_vblank) (struct drm_device \*dev, int crtc); void - (\*disable_vblank) (struct drm_device \*dev, int crtc); - Enable or disable vertical blanking interrupts for the given CRTC. - -- u32 (\*get_vblank_counter) (struct drm_device \*dev, int crtc); - Retrieve the value of the vertical blanking counter for the given - CRTC. If the hardware maintains a vertical blanking counter its value - should be returned. Otherwise drivers can use the - :c:func:`drm_vblank_count()` helper function to handle this - operation. - -Drivers must initialize the vertical blanking handling core with a call -to :c:func:`drm_vblank_init()` in their load operation. - -Vertical blanking interrupts can be enabled by the DRM core or by -drivers themselves (for instance to handle page flipping operations). -The DRM core maintains a vertical blanking use count to ensure that the -interrupts are not disabled while a user still needs them. To increment -the use count, drivers call :c:func:`drm_vblank_get()`. Upon -return vertical blanking interrupts are guaranteed to be enabled. - -To decrement the use count drivers call -:c:func:`drm_vblank_put()`. Only when the use count drops to zero -will the DRM core disable the vertical blanking interrupts after a delay -by scheduling a timer. The delay is accessible through the -vblankoffdelay module parameter or the ``drm_vblank_offdelay`` global -variable and expressed in milliseconds. Its default value is 5000 ms. -Zero means never disable, and a negative value means disable -immediately. Drivers may override the behaviour by setting the -:c:type:`struct drm_device ` -vblank_disable_immediate flag, which when set causes vblank interrupts -to be disabled immediately regardless of the drm_vblank_offdelay -value. The flag should only be set if there's a properly working -hardware vblank counter present. - -When a vertical blanking interrupt occurs drivers only need to call the -:c:func:`drm_handle_vblank()` function to account for the -interrupt. - -Resources allocated by :c:func:`drm_vblank_init()` must be freed -with a call to :c:func:`drm_vblank_cleanup()` in the driver unload -operation handler. +.. kernel-doc:: drivers/gpu/drm/drm_vblank.c + :doc: vblank handling Vertical Blanking and Interrupt Handling Functions Reference ------------------------------------------------------------ diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index 9412798645c1..b08e9dcd9177 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -191,7 +191,7 @@ acquired and release by :c:func:`calling drm_gem_object_get()` and holding the lock. When the last reference to a GEM object is released the GEM core calls -the :c:type:`struct drm_driver ` gem_free_object +the :c:type:`struct drm_driver ` gem_free_object_unlocked operation. That operation is mandatory for GEM-enabled drivers and must free the GEM object and all associated resources. @@ -492,7 +492,7 @@ DRM Sync Objects :doc: Overview .. kernel-doc:: include/drm/drm_syncobj.h - :export: + :internal: .. kernel-doc:: drivers/gpu/drm/drm_syncobj.c :export: diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 858457567d3d..679373b4a03f 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -160,6 +160,8 @@ other hand, a driver requires shared state between clients which is visible to user-space and accessible beyond open-file boundaries, they cannot support render nodes. +.. _drm_driver_ioctl: + IOCTL Support on Device Nodes ============================= diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 9c7ed3e3f1e9..2e7ee0313c1c 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -417,6 +417,10 @@ integrate with drm/i915 and to handle the `DRM_I915_PERF_OPEN` ioctl. :functions: i915_perf_open_ioctl .. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c :functions: i915_perf_release +.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c + :functions: i915_perf_add_config_ioctl +.. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c + :functions: i915_perf_remove_config_ioctl i915 Perf Stream ---------------- @@ -477,4 +481,16 @@ specific details than found in the more high-level sections. .. kernel-doc:: drivers/gpu/drm/i915/i915_perf.c :internal: -.. WARNING: DOCPROC directive not supported: !Cdrivers/gpu/drm/i915/i915_irq.c +Style +===== + +The drm/i915 driver codebase has some style rules in addition to (and, in some +cases, deviating from) the kernel coding style. + +Register macro definition style +------------------------------- + +The style guide for ``i915_reg.h``. + +.. kernel-doc:: drivers/gpu/drm/i915/i915_reg.h + :doc: The i915 register macro definition style guide diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index 1ae42006deea..22af55d06ab8 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -108,8 +108,8 @@ This would be especially useful for tinydrm: crtc state, clear that to the max values, x/y = 0 and w/h = MAX_INT, in __drm_atomic_helper_crtc_duplicate_state(). -- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm_ - prefix ofc and using drm_fb_. drm_framebuffer.c makes sense since this +- Move tinydrm_merge_clips into drm_framebuffer.c, dropping the tinydrm\_ + prefix ofc and using drm_fb\_. drm_framebuffer.c makes sense since this is a function useful to implement the fb->dirty function. - Create a new drm_fb_dirty function which does essentially what e.g. diff --git a/Documentation/hwmon/ftsteutates b/Documentation/hwmon/ftsteutates index 8c10a916de20..af54db92391b 100644 --- a/Documentation/hwmon/ftsteutates +++ b/Documentation/hwmon/ftsteutates @@ -18,6 +18,10 @@ enhancements. It can monitor up to 4 voltages, 16 temperatures and 8 fans. It also contains an integrated watchdog which is currently implemented in this driver. +To clear a temperature or fan alarm, execute the following command with the +correct path to the alarm file: + echo 0 >XXXX_alarm + Specification of the chip can be found here: ftp://ftp.ts.fujitsu.com/pub/Mainboard-OEM-Sales/Services/Software&Tools/Linux_SystemMonitoring&Watchdog&GPIO/BMC-Teutates_Specification_V1.21.pdf ftp://ftp.ts.fujitsu.com/pub/Mainboard-OEM-Sales/Services/Software&Tools/Linux_SystemMonitoring&Watchdog&GPIO/Fujitsu_mainboards-1-Sensors_HowTo-en-US.pdf diff --git a/Documentation/hwmon/ibm-cffps b/Documentation/hwmon/ibm-cffps new file mode 100644 index 000000000000..e05ecd8ecfcf --- /dev/null +++ b/Documentation/hwmon/ibm-cffps @@ -0,0 +1,54 @@ +Kernel driver ibm-cffps +======================= + +Supported chips: + * IBM Common Form Factor power supply + +Author: Eddie James + +Description +----------- + +This driver supports IBM Common Form Factor (CFF) power supplies. This driver +is a client to the core PMBus driver. + +Usage Notes +----------- + +This driver does not auto-detect devices. You will have to instantiate the +devices explicitly. Please see Documentation/i2c/instantiating-devices for +details. + +Sysfs entries +------------- + +The following attributes are supported: + +curr1_alarm Output current over-current alarm. +curr1_input Measured output current in mA. +curr1_label "iout1" + +fan1_alarm Fan 1 warning. +fan1_fault Fan 1 fault. +fan1_input Fan 1 speed in RPM. +fan2_alarm Fan 2 warning. +fan2_fault Fan 2 fault. +fan2_input Fan 2 speed in RPM. + +in1_alarm Input voltage under-voltage alarm. +in1_input Measured input voltage in mV. +in1_label "vin" +in2_alarm Output voltage over-voltage alarm. +in2_input Measured output voltage in mV. +in2_label "vout1" + +power1_alarm Input fault or alarm. +power1_input Measured input power in uW. +power1_label "pin" + +temp1_alarm PSU inlet ambient temperature over-temperature alarm. +temp1_input Measured PSU inlet ambient temp in millidegrees C. +temp2_alarm Secondary rectifier temp over-temperature alarm. +temp2_input Measured secondary rectifier temp in millidegrees C. +temp3_alarm ORing FET temperature over-temperature alarm. +temp3_input Measured ORing FET temperature in millidegrees C. diff --git a/Documentation/hwmon/lm25066 b/Documentation/hwmon/lm25066 index 2cb20ebb234d..3fa6bf820c88 100644 --- a/Documentation/hwmon/lm25066 +++ b/Documentation/hwmon/lm25066 @@ -29,6 +29,11 @@ Supported chips: Addresses scanned: - Datasheet: http://www.national.com/pf/LM/LM5066.html + * Texas Instruments LM5066I + Prefix: 'lm5066i' + Addresses scanned: - + Datasheet: + http://www.ti.com/product/LM5066I Author: Guenter Roeck @@ -37,8 +42,8 @@ Description ----------- This driver supports hardware monitoring for National Semiconductor / TI LM25056, -LM25063, LM25066, LM5064, and LM5066 Power Management, Monitoring, Control, and -Protection ICs. +LM25063, LM25066, LM5064, and LM5066/LM5066I Power Management, Monitoring, +Control, and Protection ICs. The driver is a client driver to the core PMBus driver. Please see Documentation/hwmon/pmbus for details on PMBus client drivers. diff --git a/Documentation/i2c/busses/i2c-i801 b/Documentation/i2c/busses/i2c-i801 index 0500193434cb..d47702456926 100644 --- a/Documentation/i2c/busses/i2c-i801 +++ b/Documentation/i2c/busses/i2c-i801 @@ -36,6 +36,7 @@ Supported adapters: * Intel Gemini Lake (SOC) * Intel Cannon Lake-H (PCH) * Intel Cannon Lake-LP (PCH) + * Intel Cedar Fork (PCH) Datasheets: Publicly available at the Intel website On Intel Patsburg and later chipsets, both the normal host SMBus controller diff --git a/Documentation/i2c/i2c-topology b/Documentation/i2c/i2c-topology index 1a014fede0b7..f74d78b53d4d 100644 --- a/Documentation/i2c/i2c-topology +++ b/Documentation/i2c/i2c-topology @@ -42,6 +42,10 @@ i2c-arb-gpio-challenge Parent-locked i2c-mux-gpio Normally parent-locked, mux-locked iff all involved gpio pins are controlled by the same i2c root adapter that they mux. +i2c-mux-gpmux Normally parent-locked, mux-locked iff + specified in device-tree. +i2c-mux-ltc4306 Mux-locked +i2c-mux-mlxcpld Parent-locked i2c-mux-pca9541 Parent-locked i2c-mux-pca954x Parent-locked i2c-mux-pinctrl Normally parent-locked, mux-locked iff @@ -50,9 +54,11 @@ i2c-mux-pinctrl Normally parent-locked, mux-locked iff i2c-mux-reg Parent-locked In drivers/iio/ +gyro/mpu3050 Mux-locked imu/inv_mpu6050/ Mux-locked In drivers/media/ +dvb-frontends/lgdt3306a Mux-locked dvb-frontends/m88ds3103 Parent-locked dvb-frontends/rtl2830 Parent-locked dvb-frontends/rtl2832 Mux-locked diff --git a/Documentation/iio/ep93xx_adc.txt b/Documentation/iio/ep93xx_adc.txt new file mode 100644 index 000000000000..23053e7817bd --- /dev/null +++ b/Documentation/iio/ep93xx_adc.txt @@ -0,0 +1,29 @@ +Cirrus Logic EP93xx ADC driver. + +1. Overview + +The driver is intended to work on both low-end (EP9301, EP9302) devices with +5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel +touchscreen/ADC module. + +2. Channel numbering + +Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. +EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is +not defined. So the last three are numbered randomly, let's say. + +Assuming ep93xx_adc is IIO device0, you'd find the following entries under +/sys/bus/iio/devices/iio:device0/: + + +-----------------+---------------+ + | sysfs entry | ball/pin name | + +-----------------+---------------+ + | in_voltage0_raw | YM | + | in_voltage1_raw | SXP | + | in_voltage2_raw | SXM | + | in_voltage3_raw | SYP | + | in_voltage4_raw | SYM | + | in_voltage5_raw | XP | + | in_voltage6_raw | XM | + | in_voltage7_raw | YP | + +-----------------+---------------+ diff --git a/Documentation/infiniband/tag_matching.txt b/Documentation/infiniband/tag_matching.txt new file mode 100644 index 000000000000..d2a3bf819226 --- /dev/null +++ b/Documentation/infiniband/tag_matching.txt @@ -0,0 +1,64 @@ +Tag matching logic + +The MPI standard defines a set of rules, known as tag-matching, for matching +source send operations to destination receives. The following parameters must +match the following source and destination parameters: +* Communicator +* User tag - wild card may be specified by the receiver +* Source rank – wild car may be specified by the receiver +* Destination rank – wild +The ordering rules require that when more than one pair of send and receive +message envelopes may match, the pair that includes the earliest posted-send +and the earliest posted-receive is the pair that must be used to satisfy the +matching operation. However, this doesn’t imply that tags are consumed in +the order they are created, e.g., a later generated tag may be consumed, if +earlier tags can’t be used to satisfy the matching rules. + +When a message is sent from the sender to the receiver, the communication +library may attempt to process the operation either after or before the +corresponding matching receive is posted. If a matching receive is posted, +this is an expected message, otherwise it is called an unexpected message. +Implementations frequently use different matching schemes for these two +different matching instances. + +To keep MPI library memory footprint down, MPI implementations typically use +two different protocols for this purpose: + +1. The Eager protocol- the complete message is sent when the send is +processed by the sender. A completion send is received in the send_cq +notifying that the buffer can be reused. + +2. The Rendezvous Protocol - the sender sends the tag-matching header, +and perhaps a portion of data when first notifying the receiver. When the +corresponding buffer is posted, the responder will use the information from +the header to initiate an RDMA READ operation directly to the matching buffer. +A fin message needs to be received in order for the buffer to be reused. + +Tag matching implementation + +There are two types of matching objects used, the posted receive list and the +unexpected message list. The application posts receive buffers through calls +to the MPI receive routines in the posted receive list and posts send messages +using the MPI send routines. The head of the posted receive list may be +maintained by the hardware, with the software expected to shadow this list. + +When send is initiated and arrives at the receive side, if there is no +pre-posted receive for this arriving message, it is passed to the software and +placed in the unexpected message list. Otherwise the match is processed, +including rendezvous processing, if appropriate, delivering the data to the +specified receive buffer. This allows overlapping receive-side MPI tag +matching with computation. + +When a receive-message is posted, the communication library will first check +the software unexpected message list for a matching receive. If a match is +found, data is delivered to the user buffer, using a software controlled +protocol. The UCX implementation uses either an eager or rendezvous protocol, +depending on data size. If no match is found, the entire pre-posted receive +list is maintained by the hardware, and there is space to add one more +pre-posted receive to this list, this receive is passed to the hardware. +Software is expected to shadow this list, to help with processing MPI cancel +operations. In addition, because hardware and software are not expected to be +tightly synchronized with respect to the tag-matching operation, this shadow +list is used to detect the case that a pre-posted receive is passed to the +hardware, as the matching unexpected message is being passed from the hardware +to the software. diff --git a/Documentation/input/input.rst b/Documentation/input/input.rst index 3b3a22975106..47f86a4bf16c 100644 --- a/Documentation/input/input.rst +++ b/Documentation/input/input.rst @@ -109,7 +109,7 @@ evdev nodes are created with minors starting with 256. keyboard ~~~~~~~~ -``keyboard`` is in-kernel input handler ad is a part of VT code. It +``keyboard`` is in-kernel input handler and is a part of VT code. It consumes keyboard keystrokes and handles user input for VT consoles. mousedev diff --git a/Documentation/input/joydev/index.rst b/Documentation/input/joydev/index.rst index 8d9666c7561c..ebcff43056e2 100644 --- a/Documentation/input/joydev/index.rst +++ b/Documentation/input/joydev/index.rst @@ -12,7 +12,6 @@ Linux Joystick support .. toctree:: :maxdepth: 3 - :numbered: joystick joystick-api diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index 7003141a6d4f..f6f80380dff2 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -297,9 +297,9 @@ more details, with real examples. ccflags-y specifies options for compiling with $(CC). Example: - # drivers/acpi/Makefile - ccflags-y := -Os - ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT + # drivers/acpi/acpica/Makefile + ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA + ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT This variable is necessary because the top Makefile owns the variable $(KBUILD_CFLAGS) and uses it for compilation flags for the @@ -1108,14 +1108,6 @@ When kbuild executes, the following steps are followed (roughly): ld Link target. Often, LDFLAGS_$@ is used to set specific options to ld. - objcopy - Copy binary. Uses OBJCOPYFLAGS usually specified in - arch/$(ARCH)/Makefile. - OBJCOPYFLAGS_$@ may be used to set additional options. - - gzip - Compress target. Use maximum compression to compress target. - Example: #arch/x86/boot/Makefile LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary @@ -1139,6 +1131,19 @@ When kbuild executes, the following steps are followed (roughly): resulting in the target file being recompiled for no obvious reason. + objcopy + Copy binary. Uses OBJCOPYFLAGS usually specified in + arch/$(ARCH)/Makefile. + OBJCOPYFLAGS_$@ may be used to set additional options. + + gzip + Compress target. Use maximum compression to compress target. + + Example: + #arch/x86/boot/compressed/Makefile + $(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE + $(call if_changed,gzip) + dtc Create flattened device tree blob object suitable for linking into vmlinux. Device tree blobs linked into vmlinux are placed @@ -1219,7 +1224,7 @@ When kbuild executes, the following steps are followed (roughly): that may be shared between individual architectures. The recommended approach how to use a generic header file is to list the file in the Kbuild file. - See "7.3 generic-y" for further info on syntax etc. + See "7.2 generic-y" for further info on syntax etc. --- 6.11 Post-link pass @@ -1254,13 +1259,13 @@ A Kbuild file may be defined under arch//include/uapi/asm/ and arch//include/asm/ to list asm files coming from asm-generic. See subsequent chapter for the syntax of the Kbuild file. - --- 7.1 no-export-headers +--- 7.1 no-export-headers no-export-headers is essentially used by include/uapi/linux/Kbuild to avoid exporting specific headers (e.g. kvm.h) on architectures that do not support it. It should be avoided as much as possible. - --- 7.2 generic-y +--- 7.2 generic-y If an architecture uses a verbatim copy of a header from include/asm-generic then this is listed in the file @@ -1287,7 +1292,7 @@ See subsequent chapter for the syntax of the Kbuild file. Example: termios.h #include - --- 7.3 generated-y +--- 7.3 generated-y If an architecture generates other header files alongside generic-y wrappers, generated-y specifies them. @@ -1299,7 +1304,7 @@ See subsequent chapter for the syntax of the Kbuild file. #arch/x86/include/asm/Kbuild generated-y += syscalls_32.h - --- 7.5 mandatory-y +--- 7.4 mandatory-y mandatory-y is essentially used by include/uapi/asm-generic/Kbuild.asm to define the minimum set of headers that must be exported in diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index ba2e7d254842..00b6dfed573c 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt @@ -121,8 +121,9 @@ space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/. Sysfs device attributes for the sensors and fan are on the thinkpad_hwmon device's sysfs attribute space, but you should locate it looking for a hwmon device with the name attribute of "thinkpad", or -better yet, through libsensors. - +better yet, through libsensors. For 4.14+ sysfs attributes were moved to the +hwmon device (/sys/bus/platform/devices/thinkpad_hwmon/hwmon/hwmon? or +/sys/class/hwmon/hwmon?). Driver version -------------- @@ -1478,3 +1479,7 @@ Sysfs interface changelog: 0x020700: Support for mute-only mixers. Volume control in read-only mode by default. Marker for ALSA mixer support. + +0x030000: Thermal and fan sysfs attributes were moved to the hwmon + device instead of being attached to the backing platform + device. diff --git a/Documentation/locking/crossrelease.txt b/Documentation/locking/crossrelease.txt new file mode 100644 index 000000000000..bdf1423d5f99 --- /dev/null +++ b/Documentation/locking/crossrelease.txt @@ -0,0 +1,874 @@ +Crossrelease +============ + +Started by Byungchul Park + +Contents: + + (*) Background + + - What causes deadlock + - How lockdep works + + (*) Limitation + + - Limit lockdep + - Pros from the limitation + - Cons from the limitation + - Relax the limitation + + (*) Crossrelease + + - Introduce crossrelease + - Introduce commit + + (*) Implementation + + - Data structures + - How crossrelease works + + (*) Optimizations + + - Avoid duplication + - Lockless for hot paths + + (*) APPENDIX A: What lockdep does to work aggresively + + (*) APPENDIX B: How to avoid adding false dependencies + + +========== +Background +========== + +What causes deadlock +-------------------- + +A deadlock occurs when a context is waiting for an event to happen, +which is impossible because another (or the) context who can trigger the +event is also waiting for another (or the) event to happen, which is +also impossible due to the same reason. + +For example: + + A context going to trigger event C is waiting for event A to happen. + A context going to trigger event A is waiting for event B to happen. + A context going to trigger event B is waiting for event C to happen. + +A deadlock occurs when these three wait operations run at the same time, +because event C cannot be triggered if event A does not happen, which in +turn cannot be triggered if event B does not happen, which in turn +cannot be triggered if event C does not happen. After all, no event can +be triggered since any of them never meets its condition to wake up. + +A dependency might exist between two waiters and a deadlock might happen +due to an incorrect releationship between dependencies. Thus, we must +define what a dependency is first. A dependency exists between them if: + + 1. There are two waiters waiting for each event at a given time. + 2. The only way to wake up each waiter is to trigger its event. + 3. Whether one can be woken up depends on whether the other can. + +Each wait in the example creates its dependency like: + + Event C depends on event A. + Event A depends on event B. + Event B depends on event C. + + NOTE: Precisely speaking, a dependency is one between whether a + waiter for an event can be woken up and whether another waiter for + another event can be woken up. However from now on, we will describe + a dependency as if it's one between an event and another event for + simplicity. + +And they form circular dependencies like: + + -> C -> A -> B - + / \ + \ / + ---------------- + + where 'A -> B' means that event A depends on event B. + +Such circular dependencies lead to a deadlock since no waiter can meet +its condition to wake up as described. + +CONCLUSION + +Circular dependencies cause a deadlock. + + +How lockdep works +----------------- + +Lockdep tries to detect a deadlock by checking dependencies created by +lock operations, acquire and release. Waiting for a lock corresponds to +waiting for an event, and releasing a lock corresponds to triggering an +event in the previous section. + +In short, lockdep does: + + 1. Detect a new dependency. + 2. Add the dependency into a global graph. + 3. Check if that makes dependencies circular. + 4. Report a deadlock or its possibility if so. + +For example, consider a graph built by lockdep that looks like: + + A -> B - + \ + -> E + / + C -> D - + + where A, B,..., E are different lock classes. + +Lockdep will add a dependency into the graph on detection of a new +dependency. For example, it will add a dependency 'E -> C' when a new +dependency between lock E and lock C is detected. Then the graph will be: + + A -> B - + \ + -> E - + / \ + -> C -> D - \ + / / + \ / + ------------------ + + where A, B,..., E are different lock classes. + +This graph contains a subgraph which demonstrates circular dependencies: + + -> E - + / \ + -> C -> D - \ + / / + \ / + ------------------ + + where C, D and E are different lock classes. + +This is the condition under which a deadlock might occur. Lockdep +reports it on detection after adding a new dependency. This is the way +how lockdep works. + +CONCLUSION + +Lockdep detects a deadlock or its possibility by checking if circular +dependencies were created after adding each new dependency. + + +========== +Limitation +========== + +Limit lockdep +------------- + +Limiting lockdep to work on only typical locks e.g. spin locks and +mutexes, which are released within the acquire context, the +implementation becomes simple but its capacity for detection becomes +limited. Let's check pros and cons in next section. + + +Pros from the limitation +------------------------ + +Given the limitation, when acquiring a lock, locks in a held_locks +cannot be released if the context cannot acquire it so has to wait to +acquire it, which means all waiters for the locks in the held_locks are +stuck. It's an exact case to create dependencies between each lock in +the held_locks and the lock to acquire. + +For example: + + CONTEXT X + --------- + acquire A + acquire B /* Add a dependency 'A -> B' */ + release B + release A + + where A and B are different lock classes. + +When acquiring lock A, the held_locks of CONTEXT X is empty thus no +dependency is added. But when acquiring lock B, lockdep detects and adds +a new dependency 'A -> B' between lock A in the held_locks and lock B. +They can be simply added whenever acquiring each lock. + +And data required by lockdep exists in a local structure, held_locks +embedded in task_struct. Forcing to access the data within the context, +lockdep can avoid racy problems without explicit locks while handling +the local data. + +Lastly, lockdep only needs to keep locks currently being held, to build +a dependency graph. However, relaxing the limitation, it needs to keep +even locks already released, because a decision whether they created +dependencies might be long-deferred. + +To sum up, we can expect several advantages from the limitation: + + 1. Lockdep can easily identify a dependency when acquiring a lock. + 2. Races are avoidable while accessing local locks in a held_locks. + 3. Lockdep only needs to keep locks currently being held. + +CONCLUSION + +Given the limitation, the implementation becomes simple and efficient. + + +Cons from the limitation +------------------------ + +Given the limitation, lockdep is applicable only to typical locks. For +example, page locks for page access or completions for synchronization +cannot work with lockdep. + +Can we detect deadlocks below, under the limitation? + +Example 1: + + CONTEXT X CONTEXT Y CONTEXT Z + --------- --------- ---------- + mutex_lock A + lock_page B + lock_page B + mutex_lock A /* DEADLOCK */ + unlock_page B held by X + unlock_page B + mutex_unlock A + mutex_unlock A + + where A and B are different lock classes. + +No, we cannot. + +Example 2: + + CONTEXT X CONTEXT Y + --------- --------- + mutex_lock A + mutex_lock A + wait_for_complete B /* DEADLOCK */ + complete B + mutex_unlock A + mutex_unlock A + + where A is a lock class and B is a completion variable. + +No, we cannot. + +CONCLUSION + +Given the limitation, lockdep cannot detect a deadlock or its +possibility caused by page locks or completions. + + +Relax the limitation +-------------------- + +Under the limitation, things to create dependencies are limited to +typical locks. However, synchronization primitives like page locks and +completions, which are allowed to be released in any context, also +create dependencies and can cause a deadlock. So lockdep should track +these locks to do a better job. We have to relax the limitation for +these locks to work with lockdep. + +Detecting dependencies is very important for lockdep to work because +adding a dependency means adding an opportunity to check whether it +causes a deadlock. The more lockdep adds dependencies, the more it +thoroughly works. Thus Lockdep has to do its best to detect and add as +many true dependencies into a graph as possible. + +For example, considering only typical locks, lockdep builds a graph like: + + A -> B - + \ + -> E + / + C -> D - + + where A, B,..., E are different lock classes. + +On the other hand, under the relaxation, additional dependencies might +be created and added. Assuming additional 'FX -> C' and 'E -> GX' are +added thanks to the relaxation, the graph will be: + + A -> B - + \ + -> E -> GX + / + FX -> C -> D - + + where A, B,..., E, FX and GX are different lock classes, and a suffix + 'X' is added on non-typical locks. + +The latter graph gives us more chances to check circular dependencies +than the former. However, it might suffer performance degradation since +relaxing the limitation, with which design and implementation of lockdep +can be efficient, might introduce inefficiency inevitably. So lockdep +should provide two options, strong detection and efficient detection. + +Choosing efficient detection: + + Lockdep works with only locks restricted to be released within the + acquire context. However, lockdep works efficiently. + +Choosing strong detection: + + Lockdep works with all synchronization primitives. However, lockdep + suffers performance degradation. + +CONCLUSION + +Relaxing the limitation, lockdep can add additional dependencies giving +additional opportunities to check circular dependencies. + + +============ +Crossrelease +============ + +Introduce crossrelease +---------------------- + +In order to allow lockdep to handle additional dependencies by what +might be released in any context, namely 'crosslock', we have to be able +to identify those created by crosslocks. The proposed 'crossrelease' +feature provoides a way to do that. + +Crossrelease feature has to do: + + 1. Identify dependencies created by crosslocks. + 2. Add the dependencies into a dependency graph. + +That's all. Once a meaningful dependency is added into graph, then +lockdep would work with the graph as it did. The most important thing +crossrelease feature has to do is to correctly identify and add true +dependencies into the global graph. + +A dependency e.g. 'A -> B' can be identified only in the A's release +context because a decision required to identify the dependency can be +made only in the release context. That is to decide whether A can be +released so that a waiter for A can be woken up. It cannot be made in +other than the A's release context. + +It's no matter for typical locks because each acquire context is same as +its release context, thus lockdep can decide whether a lock can be +released in the acquire context. However for crosslocks, lockdep cannot +make the decision in the acquire context but has to wait until the +release context is identified. + +Therefore, deadlocks by crosslocks cannot be detected just when it +happens, because those cannot be identified until the crosslocks are +released. However, deadlock possibilities can be detected and it's very +worth. See 'APPENDIX A' section to check why. + +CONCLUSION + +Using crossrelease feature, lockdep can work with what might be released +in any context, namely crosslock. + + +Introduce commit +---------------- + +Since crossrelease defers the work adding true dependencies of +crosslocks until they are actually released, crossrelease has to queue +all acquisitions which might create dependencies with the crosslocks. +Then it identifies dependencies using the queued data in batches at a +proper time. We call it 'commit'. + +There are four types of dependencies: + +1. TT type: 'typical lock A -> typical lock B' + + Just when acquiring B, lockdep can see it's in the A's release + context. So the dependency between A and B can be identified + immediately. Commit is unnecessary. + +2. TC type: 'typical lock A -> crosslock BX' + + Just when acquiring BX, lockdep can see it's in the A's release + context. So the dependency between A and BX can be identified + immediately. Commit is unnecessary, too. + +3. CT type: 'crosslock AX -> typical lock B' + + When acquiring B, lockdep cannot identify the dependency because + there's no way to know if it's in the AX's release context. It has + to wait until the decision can be made. Commit is necessary. + +4. CC type: 'crosslock AX -> crosslock BX' + + When acquiring BX, lockdep cannot identify the dependency because + there's no way to know if it's in the AX's release context. It has + to wait until the decision can be made. Commit is necessary. + But, handling CC type is not implemented yet. It's a future work. + +Lockdep can work without commit for typical locks, but commit step is +necessary once crosslocks are involved. Introducing commit, lockdep +performs three steps. What lockdep does in each step is: + +1. Acquisition: For typical locks, lockdep does what it originally did + and queues the lock so that CT type dependencies can be checked using + it at the commit step. For crosslocks, it saves data which will be + used at the commit step and increases a reference count for it. + +2. Commit: No action is reauired for typical locks. For crosslocks, + lockdep adds CT type dependencies using the data saved at the + acquisition step. + +3. Release: No changes are required for typical locks. When a crosslock + is released, it decreases a reference count for it. + +CONCLUSION + +Crossrelease introduces commit step to handle dependencies of crosslocks +in batches at a proper time. + + +============== +Implementation +============== + +Data structures +--------------- + +Crossrelease introduces two main data structures. + +1. hist_lock + + This is an array embedded in task_struct, for keeping lock history so + that dependencies can be added using them at the commit step. Since + it's local data, it can be accessed locklessly in the owner context. + The array is filled at the acquisition step and consumed at the + commit step. And it's managed in circular manner. + +2. cross_lock + + One per lockdep_map exists. This is for keeping data of crosslocks + and used at the commit step. + + +How crossrelease works +---------------------- + +It's the key of how crossrelease works, to defer necessary works to an +appropriate point in time and perform in at once at the commit step. +Let's take a look with examples step by step, starting from how lockdep +works without crossrelease for typical locks. + + acquire A /* Push A onto held_locks */ + acquire B /* Push B onto held_locks and add 'A -> B' */ + acquire C /* Push C onto held_locks and add 'B -> C' */ + release C /* Pop C from held_locks */ + release B /* Pop B from held_locks */ + release A /* Pop A from held_locks */ + + where A, B and C are different lock classes. + + NOTE: This document assumes that readers already understand how + lockdep works without crossrelease thus omits details. But there's + one thing to note. Lockdep pretends to pop a lock from held_locks + when releasing it. But it's subtly different from the original pop + operation because lockdep allows other than the top to be poped. + +In this case, lockdep adds 'the top of held_locks -> the lock to acquire' +dependency every time acquiring a lock. + +After adding 'A -> B', a dependency graph will be: + + A -> B + + where A and B are different lock classes. + +And after adding 'B -> C', the graph will be: + + A -> B -> C + + where A, B and C are different lock classes. + +Let's performs commit step even for typical locks to add dependencies. +Of course, commit step is not necessary for them, however, it would work +well because this is a more general way. + + acquire A + /* + * Queue A into hist_locks + * + * In hist_locks: A + * In graph: Empty + */ + + acquire B + /* + * Queue B into hist_locks + * + * In hist_locks: A, B + * In graph: Empty + */ + + acquire C + /* + * Queue C into hist_locks + * + * In hist_locks: A, B, C + * In graph: Empty + */ + + commit C + /* + * Add 'C -> ?' + * Answer the following to decide '?' + * What has been queued since acquire C: Nothing + * + * In hist_locks: A, B, C + * In graph: Empty + */ + + release C + + commit B + /* + * Add 'B -> ?' + * Answer the following to decide '?' + * What has been queued since acquire B: C + * + * In hist_locks: A, B, C + * In graph: 'B -> C' + */ + + release B + + commit A + /* + * Add 'A -> ?' + * Answer the following to decide '?' + * What has been queued since acquire A: B, C + * + * In hist_locks: A, B, C + * In graph: 'B -> C', 'A -> B', 'A -> C' + */ + + release A + + where A, B and C are different lock classes. + +In this case, dependencies are added at the commit step as described. + +After commits for A, B and C, the graph will be: + + A -> B -> C + + where A, B and C are different lock classes. + + NOTE: A dependency 'A -> C' is optimized out. + +We can see the former graph built without commit step is same as the +latter graph built using commit steps. Of course the former way leads to +earlier finish for building the graph, which means we can detect a +deadlock or its possibility sooner. So the former way would be prefered +when possible. But we cannot avoid using the latter way for crosslocks. + +Let's look at how commit steps work for crosslocks. In this case, the +commit step is performed only on crosslock AX as real. And it assumes +that the AX release context is different from the AX acquire context. + + BX RELEASE CONTEXT BX ACQUIRE CONTEXT + ------------------ ------------------ + acquire A + /* + * Push A onto held_locks + * Queue A into hist_locks + * + * In held_locks: A + * In hist_locks: A + * In graph: Empty + */ + + acquire BX + /* + * Add 'the top of held_locks -> BX' + * + * In held_locks: A + * In hist_locks: A + * In graph: 'A -> BX' + */ + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + It must be guaranteed that the following operations are seen after + acquiring BX globally. It can be done by things like barrier. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + acquire C + /* + * Push C onto held_locks + * Queue C into hist_locks + * + * In held_locks: C + * In hist_locks: C + * In graph: 'A -> BX' + */ + + release C + /* + * Pop C from held_locks + * + * In held_locks: Empty + * In hist_locks: C + * In graph: 'A -> BX' + */ + acquire D + /* + * Push D onto held_locks + * Queue D into hist_locks + * Add 'the top of held_locks -> D' + * + * In held_locks: A, D + * In hist_locks: A, D + * In graph: 'A -> BX', 'A -> D' + */ + acquire E + /* + * Push E onto held_locks + * Queue E into hist_locks + * + * In held_locks: E + * In hist_locks: C, E + * In graph: 'A -> BX', 'A -> D' + */ + + release E + /* + * Pop E from held_locks + * + * In held_locks: Empty + * In hist_locks: D, E + * In graph: 'A -> BX', 'A -> D' + */ + release D + /* + * Pop D from held_locks + * + * In held_locks: A + * In hist_locks: A, D + * In graph: 'A -> BX', 'A -> D' + */ + commit BX + /* + * Add 'BX -> ?' + * What has been queued since acquire BX: C, E + * + * In held_locks: Empty + * In hist_locks: D, E + * In graph: 'A -> BX', 'A -> D', + * 'BX -> C', 'BX -> E' + */ + + release BX + /* + * In held_locks: Empty + * In hist_locks: D, E + * In graph: 'A -> BX', 'A -> D', + * 'BX -> C', 'BX -> E' + */ + release A + /* + * Pop A from held_locks + * + * In held_locks: Empty + * In hist_locks: A, D + * In graph: 'A -> BX', 'A -> D', + * 'BX -> C', 'BX -> E' + */ + + where A, BX, C,..., E are different lock classes, and a suffix 'X' is + added on crosslocks. + +Crossrelease considers all acquisitions after acqiuring BX are +candidates which might create dependencies with BX. True dependencies +will be determined when identifying the release context of BX. Meanwhile, +all typical locks are queued so that they can be used at the commit step. +And then two dependencies 'BX -> C' and 'BX -> E' are added at the +commit step when identifying the release context. + +The final graph will be, with crossrelease: + + -> C + / + -> BX - + / \ + A - -> E + \ + -> D + + where A, BX, C,..., E are different lock classes, and a suffix 'X' is + added on crosslocks. + +However, the final graph will be, without crossrelease: + + A -> D + + where A and D are different lock classes. + +The former graph has three more dependencies, 'A -> BX', 'BX -> C' and +'BX -> E' giving additional opportunities to check if they cause +deadlocks. This way lockdep can detect a deadlock or its possibility +caused by crosslocks. + +CONCLUSION + +We checked how crossrelease works with several examples. + + +============= +Optimizations +============= + +Avoid duplication +----------------- + +Crossrelease feature uses a cache like what lockdep already uses for +dependency chains, but this time it's for caching CT type dependencies. +Once that dependency is cached, the same will never be added again. + + +Lockless for hot paths +---------------------- + +To keep all locks for later use at the commit step, crossrelease adopts +a local array embedded in task_struct, which makes access to the data +lockless by forcing it to happen only within the owner context. It's +like how lockdep handles held_locks. Lockless implmentation is important +since typical locks are very frequently acquired and released. + + +================================================= +APPENDIX A: What lockdep does to work aggresively +================================================= + +A deadlock actually occurs when all wait operations creating circular +dependencies run at the same time. Even though they don't, a potential +deadlock exists if the problematic dependencies exist. Thus it's +meaningful to detect not only an actual deadlock but also its potential +possibility. The latter is rather valuable. When a deadlock occurs +actually, we can identify what happens in the system by some means or +other even without lockdep. However, there's no way to detect possiblity +without lockdep unless the whole code is parsed in head. It's terrible. +Lockdep does the both, and crossrelease only focuses on the latter. + +Whether or not a deadlock actually occurs depends on several factors. +For example, what order contexts are switched in is a factor. Assuming +circular dependencies exist, a deadlock would occur when contexts are +switched so that all wait operations creating the dependencies run +simultaneously. Thus to detect a deadlock possibility even in the case +that it has not occured yet, lockdep should consider all possible +combinations of dependencies, trying to: + +1. Use a global dependency graph. + + Lockdep combines all dependencies into one global graph and uses them, + regardless of which context generates them or what order contexts are + switched in. Aggregated dependencies are only considered so they are + prone to be circular if a problem exists. + +2. Check dependencies between classes instead of instances. + + What actually causes a deadlock are instances of lock. However, + lockdep checks dependencies between classes instead of instances. + This way lockdep can detect a deadlock which has not happened but + might happen in future by others but the same class. + +3. Assume all acquisitions lead to waiting. + + Although locks might be acquired without waiting which is essential + to create dependencies, lockdep assumes all acquisitions lead to + waiting since it might be true some time or another. + +CONCLUSION + +Lockdep detects not only an actual deadlock but also its possibility, +and the latter is more valuable. + + +================================================== +APPENDIX B: How to avoid adding false dependencies +================================================== + +Remind what a dependency is. A dependency exists if: + + 1. There are two waiters waiting for each event at a given time. + 2. The only way to wake up each waiter is to trigger its event. + 3. Whether one can be woken up depends on whether the other can. + +For example: + + acquire A + acquire B /* A dependency 'A -> B' exists */ + release B + release A + + where A and B are different lock classes. + +A depedency 'A -> B' exists since: + + 1. A waiter for A and a waiter for B might exist when acquiring B. + 2. Only way to wake up each is to release what it waits for. + 3. Whether the waiter for A can be woken up depends on whether the + other can. IOW, TASK X cannot release A if it fails to acquire B. + +For another example: + + TASK X TASK Y + ------ ------ + acquire AX + acquire B /* A dependency 'AX -> B' exists */ + release B + release AX held by Y + + where AX and B are different lock classes, and a suffix 'X' is added + on crosslocks. + +Even in this case involving crosslocks, the same rule can be applied. A +depedency 'AX -> B' exists since: + + 1. A waiter for AX and a waiter for B might exist when acquiring B. + 2. Only way to wake up each is to release what it waits for. + 3. Whether the waiter for AX can be woken up depends on whether the + other can. IOW, TASK X cannot release AX if it fails to acquire B. + +Let's take a look at more complicated example: + + TASK X TASK Y + ------ ------ + acquire B + release B + fork Y + acquire AX + acquire C /* A dependency 'AX -> C' exists */ + release C + release AX held by Y + + where AX, B and C are different lock classes, and a suffix 'X' is + added on crosslocks. + +Does a dependency 'AX -> B' exist? Nope. + +Two waiters are essential to create a dependency. However, waiters for +AX and B to create 'AX -> B' cannot exist at the same time in this +example. Thus the dependency 'AX -> B' cannot be created. + +It would be ideal if the full set of true ones can be considered. But +we can ensure nothing but what actually happened. Relying on what +actually happens at runtime, we can anyway add only true ones, though +they might be a subset of true ones. It's similar to how lockdep works +for typical locks. There might be more true dependencies than what +lockdep has detected in runtime. Lockdep has no choice but to rely on +what actually happens. Crossrelease also relies on it. + +CONCLUSION + +Relying on what actually happens, lockdep can avoid adding false +dependencies. diff --git a/Documentation/locking/rt-mutex-design.txt b/Documentation/locking/rt-mutex-design.txt index 8666070d3189..6c6e8c2410de 100644 --- a/Documentation/locking/rt-mutex-design.txt +++ b/Documentation/locking/rt-mutex-design.txt @@ -97,9 +97,9 @@ waiter - A waiter is a struct that is stored on the stack of a blocked a process being blocked on the mutex, it is fine to allocate the waiter on the process's stack (local variable). This structure holds a pointer to the task, as well as the mutex that - the task is blocked on. It also has the plist node structures to - place the task in the waiter_list of a mutex as well as the - pi_list of a mutex owner task (described below). + the task is blocked on. It also has rbtree node structures to + place the task in the waiters rbtree of a mutex as well as the + pi_waiters rbtree of a mutex owner task (described below). waiter is sometimes used in reference to the task that is waiting on a mutex. This is the same as waiter->task. @@ -179,53 +179,34 @@ again. | F->L5-+ +If process G has the highest priority in the chain, then all the tasks up +the chain (A and B in this example), must have their priorities increased +to that of G. -Plist ------ - -Before I go further and talk about how the PI chain is stored through lists -on both mutexes and processes, I'll explain the plist. This is similar to -the struct list_head functionality that is already in the kernel. -The implementation of plist is out of scope for this document, but it is -very important to understand what it does. - -There are a few differences between plist and list, the most important one -being that plist is a priority sorted linked list. This means that the -priorities of the plist are sorted, such that it takes O(1) to retrieve the -highest priority item in the list. Obviously this is useful to store processes -based on their priorities. - -Another difference, which is important for implementation, is that, unlike -list, the head of the list is a different element than the nodes of a list. -So the head of the list is declared as struct plist_head and nodes that will -be added to the list are declared as struct plist_node. - - -Mutex Waiter List +Mutex Waiters Tree ----------------- -Every mutex keeps track of all the waiters that are blocked on itself. The mutex -has a plist to store these waiters by priority. This list is protected by -a spin lock that is located in the struct of the mutex. This lock is called -wait_lock. Since the modification of the waiter list is never done in -interrupt context, the wait_lock can be taken without disabling interrupts. +Every mutex keeps track of all the waiters that are blocked on itself. The +mutex has a rbtree to store these waiters by priority. This tree is protected +by a spin lock that is located in the struct of the mutex. This lock is called +wait_lock. -Task PI List +Task PI Tree ------------ -To keep track of the PI chains, each process has its own PI list. This is -a list of all top waiters of the mutexes that are owned by the process. -Note that this list only holds the top waiters and not all waiters that are +To keep track of the PI chains, each process has its own PI rbtree. This is +a tree of all top waiters of the mutexes that are owned by the process. +Note that this tree only holds the top waiters and not all waiters that are blocked on mutexes owned by the process. -The top of the task's PI list is always the highest priority task that +The top of the task's PI tree is always the highest priority task that is waiting on a mutex that is owned by the task. So if the task has inherited a priority, it will always be the priority of the task that is -at the top of this list. +at the top of this tree. -This list is stored in the task structure of a process as a plist called -pi_list. This list is protected by a spin lock also in the task structure, +This tree is stored in the task structure of a process as a rbtree called +pi_waiters. It is protected by a spin lock also in the task structure, called pi_lock. This lock may also be taken in interrupt context, so when locking the pi_lock, interrupts must be disabled. @@ -312,15 +293,12 @@ Mutex owner and flags The mutex structure contains a pointer to the owner of the mutex. If the mutex is not owned, this owner is set to NULL. Since all architectures -have the task structure on at least a four byte alignment (and if this is -not true, the rtmutex.c code will be broken!), this allows for the two -least significant bits to be used as flags. This part is also described -in Documentation/rt-mutex.txt, but will also be briefly described here. - -Bit 0 is used as the "Pending Owner" flag. This is described later. -Bit 1 is used as the "Has Waiters" flags. This is also described later - in more detail, but is set whenever there are waiters on a mutex. +have the task structure on at least a two byte alignment (and if this is +not true, the rtmutex.c code will be broken!), this allows for the least +significant bit to be used as a flag. Bit 0 is used as the "Has Waiters" +flag. It's set whenever there are waiters on a mutex. +See Documentation/locking/rt-mutex.txt for further details. cmpxchg Tricks -------------- @@ -359,40 +337,31 @@ Priority adjustments -------------------- The implementation of the PI code in rtmutex.c has several places that a -process must adjust its priority. With the help of the pi_list of a +process must adjust its priority. With the help of the pi_waiters of a process this is rather easy to know what needs to be adjusted. -The functions implementing the task adjustments are rt_mutex_adjust_prio, -__rt_mutex_adjust_prio (same as the former, but expects the task pi_lock -to already be taken), rt_mutex_getprio, and rt_mutex_setprio. +The functions implementing the task adjustments are rt_mutex_adjust_prio +and rt_mutex_setprio. rt_mutex_setprio is only used in rt_mutex_adjust_prio. -rt_mutex_getprio and rt_mutex_setprio are only used in __rt_mutex_adjust_prio. +rt_mutex_adjust_prio examines the priority of the task, and the highest +priority process that is waiting any of mutexes owned by the task. Since +the pi_waiters of a task holds an order by priority of all the top waiters +of all the mutexes that the task owns, we simply need to compare the top +pi waiter to its own normal/deadline priority and take the higher one. +Then rt_mutex_setprio is called to adjust the priority of the task to the +new priority. Note that rt_mutex_setprio is defined in kernel/sched/core.c +to implement the actual change in priority. -rt_mutex_getprio returns the priority that the task should have. Either the -task's own normal priority, or if a process of a higher priority is waiting on -a mutex owned by the task, then that higher priority should be returned. -Since the pi_list of a task holds an order by priority list of all the top -waiters of all the mutexes that the task owns, rt_mutex_getprio simply needs -to compare the top pi waiter to its own normal priority, and return the higher -priority back. +(Note: For the "prio" field in task_struct, the lower the number, the + higher the priority. A "prio" of 5 is of higher priority than a + "prio" of 10.) -(Note: if looking at the code, you will notice that the lower number of - prio is returned. This is because the prio field in the task structure - is an inverse order of the actual priority. So a "prio" of 5 is - of higher priority than a "prio" of 10.) - -__rt_mutex_adjust_prio examines the result of rt_mutex_getprio, and if the -result does not equal the task's current priority, then rt_mutex_setprio -is called to adjust the priority of the task to the new priority. -Note that rt_mutex_setprio is defined in kernel/sched/core.c to implement the -actual change in priority. - -It is interesting to note that __rt_mutex_adjust_prio can either increase +It is interesting to note that rt_mutex_adjust_prio can either increase or decrease the priority of the task. In the case that a higher priority -process has just blocked on a mutex owned by the task, __rt_mutex_adjust_prio +process has just blocked on a mutex owned by the task, rt_mutex_adjust_prio would increase/boost the task's priority. But if a higher priority task were for some reason to leave the mutex (timeout or signal), this same function -would decrease/unboost the priority of the task. That is because the pi_list +would decrease/unboost the priority of the task. That is because the pi_waiters always contains the highest priority task that is waiting on a mutex owned by the task, so we only need to compare the priority of that top pi waiter to the normal priority of the given task. @@ -412,9 +381,10 @@ priorities. rt_mutex_adjust_prio_chain is called with a task to be checked for PI (de)boosting (the owner of a mutex that a process is blocking on), a flag to -check for deadlocking, the mutex that the task owns, and a pointer to a waiter +check for deadlocking, the mutex that the task owns, a pointer to a waiter that is the process's waiter struct that is blocked on the mutex (although this -parameter may be NULL for deboosting). +parameter may be NULL for deboosting), a pointer to the mutex on which the task +is blocked, and a top_task as the top waiter of the mutex. For this explanation, I will not mention deadlock detection. This explanation will try to stay at a high level. @@ -424,133 +394,14 @@ that the state of the owner and lock can change when entered into this function. Before this function is called, the task has already had rt_mutex_adjust_prio performed on it. This means that the task is set to the priority that it -should be at, but the plist nodes of the task's waiter have not been updated -with the new priorities, and that this task may not be in the proper locations -in the pi_lists and wait_lists that the task is blocked on. This function +should be at, but the rbtree nodes of the task's waiter have not been updated +with the new priorities, and this task may not be in the proper locations +in the pi_waiters and waiters trees that the task is blocked on. This function solves all that. -A loop is entered, where task is the owner to be checked for PI changes that -was passed by parameter (for the first iteration). The pi_lock of this task is -taken to prevent any more changes to the pi_list of the task. This also -prevents new tasks from completing the blocking on a mutex that is owned by this -task. - -If the task is not blocked on a mutex then the loop is exited. We are at -the top of the PI chain. - -A check is now done to see if the original waiter (the process that is blocked -on the current mutex) is the top pi waiter of the task. That is, is this -waiter on the top of the task's pi_list. If it is not, it either means that -there is another process higher in priority that is blocked on one of the -mutexes that the task owns, or that the waiter has just woken up via a signal -or timeout and has left the PI chain. In either case, the loop is exited, since -we don't need to do any more changes to the priority of the current task, or any -task that owns a mutex that this current task is waiting on. A priority chain -walk is only needed when a new top pi waiter is made to a task. - -The next check sees if the task's waiter plist node has the priority equal to -the priority the task is set at. If they are equal, then we are done with -the loop. Remember that the function started with the priority of the -task adjusted, but the plist nodes that hold the task in other processes -pi_lists have not been adjusted. - -Next, we look at the mutex that the task is blocked on. The mutex's wait_lock -is taken. This is done by a spin_trylock, because the locking order of the -pi_lock and wait_lock goes in the opposite direction. If we fail to grab the -lock, the pi_lock is released, and we restart the loop. - -Now that we have both the pi_lock of the task as well as the wait_lock of -the mutex the task is blocked on, we update the task's waiter's plist node -that is located on the mutex's wait_list. - -Now we release the pi_lock of the task. - -Next the owner of the mutex has its pi_lock taken, so we can update the -task's entry in the owner's pi_list. If the task is the highest priority -process on the mutex's wait_list, then we remove the previous top waiter -from the owner's pi_list, and replace it with the task. - -Note: It is possible that the task was the current top waiter on the mutex, - in which case the task is not yet on the pi_list of the waiter. This - is OK, since plist_del does nothing if the plist node is not on any - list. - -If the task was not the top waiter of the mutex, but it was before we -did the priority updates, that means we are deboosting/lowering the -task. In this case, the task is removed from the pi_list of the owner, -and the new top waiter is added. - -Lastly, we unlock both the pi_lock of the task, as well as the mutex's -wait_lock, and continue the loop again. On the next iteration of the -loop, the previous owner of the mutex will be the task that will be -processed. - -Note: One might think that the owner of this mutex might have changed - since we just grab the mutex's wait_lock. And one could be right. - The important thing to remember is that the owner could not have - become the task that is being processed in the PI chain, since - we have taken that task's pi_lock at the beginning of the loop. - So as long as there is an owner of this mutex that is not the same - process as the tasked being worked on, we are OK. - - Looking closely at the code, one might be confused. The check for the - end of the PI chain is when the task isn't blocked on anything or the - task's waiter structure "task" element is NULL. This check is - protected only by the task's pi_lock. But the code to unlock the mutex - sets the task's waiter structure "task" element to NULL with only - the protection of the mutex's wait_lock, which was not taken yet. - Isn't this a race condition if the task becomes the new owner? - - The answer is No! The trick is the spin_trylock of the mutex's - wait_lock. If we fail that lock, we release the pi_lock of the - task and continue the loop, doing the end of PI chain check again. - - In the code to release the lock, the wait_lock of the mutex is held - the entire time, and it is not let go when we grab the pi_lock of the - new owner of the mutex. So if the switch of a new owner were to happen - after the check for end of the PI chain and the grabbing of the - wait_lock, the unlocking code would spin on the new owner's pi_lock - but never give up the wait_lock. So the PI chain loop is guaranteed to - fail the spin_trylock on the wait_lock, release the pi_lock, and - try again. - - If you don't quite understand the above, that's OK. You don't have to, - unless you really want to make a proof out of it ;) - - -Pending Owners and Lock stealing --------------------------------- - -One of the flags in the owner field of the mutex structure is "Pending Owner". -What this means is that an owner was chosen by the process releasing the -mutex, but that owner has yet to wake up and actually take the mutex. - -Why is this important? Why can't we just give the mutex to another process -and be done with it? - -The PI code is to help with real-time processes, and to let the highest -priority process run as long as possible with little latencies and delays. -If a high priority process owns a mutex that a lower priority process is -blocked on, when the mutex is released it would be given to the lower priority -process. What if the higher priority process wants to take that mutex again. -The high priority process would fail to take that mutex that it just gave up -and it would need to boost the lower priority process to run with full -latency of that critical section (since the low priority process just entered -it). - -There's no reason a high priority process that gives up a mutex should be -penalized if it tries to take that mutex again. If the new owner of the -mutex has not woken up yet, there's no reason that the higher priority process -could not take that mutex away. - -To solve this, we introduced Pending Ownership and Lock Stealing. When a -new process is given a mutex that it was blocked on, it is only given -pending ownership. This means that it's the new owner, unless a higher -priority process comes in and tries to grab that mutex. If a higher priority -process does come along and wants that mutex, we let the higher priority -process "steal" the mutex from the pending owner (only if it is still pending) -and continue with the mutex. - +The main operation of this function is summarized by Thomas Gleixner in +rtmutex.c. See the 'Chain walk basics and protection scope' comment for further +details. Taking of a mutex (The walk through) ------------------------------------ @@ -563,14 +414,14 @@ done when we have CMPXCHG enabled (otherwise the fast taking automatically fails). Only when the owner field of the mutex is NULL can the lock be taken with the CMPXCHG and nothing else needs to be done. -If there is contention on the lock, whether it is owned or pending owner -we go about the slow path (rt_mutex_slowlock). +If there is contention on the lock, we go about the slow path +(rt_mutex_slowlock). The slow path function is where the task's waiter structure is created on the stack. This is because the waiter structure is only needed for the scope of this function. The waiter structure holds the nodes to store -the task on the wait_list of the mutex, and if need be, the pi_list of -the owner. +the task on the waiters tree of the mutex, and if need be, the pi_waiters +tree of the owner. The wait_lock of the mutex is taken since the slow path of unlocking the mutex also takes this lock. @@ -581,102 +432,45 @@ contention). try_to_take_rt_mutex is used every time the task tries to grab a mutex in the slow path. The first thing that is done here is an atomic setting of -the "Has Waiters" flag of the mutex's owner field. Yes, this could really -be false, because if the mutex has no owner, there are no waiters and -the current task also won't have any waiters. But we don't have the lock -yet, so we assume we are going to be a waiter. The reason for this is to -play nice for those architectures that do have CMPXCHG. By setting this flag -now, the owner of the mutex can't release the mutex without going into the -slow unlock path, and it would then need to grab the wait_lock, which this -code currently holds. So setting the "Has Waiters" flag forces the owner -to synchronize with this code. +the "Has Waiters" flag of the mutex's owner field. By setting this flag +now, the current owner of the mutex being contended for can't release the mutex +without going into the slow unlock path, and it would then need to grab the +wait_lock, which this code currently holds. So setting the "Has Waiters" flag +forces the current owner to synchronize with this code. -Now that we know that we can't have any races with the owner releasing the -mutex, we check to see if we can take the ownership. This is done if the -mutex doesn't have a owner, or if we can steal the mutex from a pending -owner. Let's look at the situations we have here. +The lock is taken if the following are true: + 1) The lock has no owner + 2) The current task is the highest priority against all other + waiters of the lock - 1) Has owner that is pending - ---------------------------- +If the task succeeds to acquire the lock, then the task is set as the +owner of the lock, and if the lock still has waiters, the top_waiter +(highest priority task waiting on the lock) is added to this task's +pi_waiters tree. - The mutex has a owner, but it hasn't woken up and the mutex flag - "Pending Owner" is set. The first check is to see if the owner isn't the - current task. This is because this function is also used for the pending - owner to grab the mutex. When a pending owner wakes up, it checks to see - if it can take the mutex, and this is done if the owner is already set to - itself. If so, we succeed and leave the function, clearing the "Pending - Owner" bit. - - If the pending owner is not current, we check to see if the current priority is - higher than the pending owner. If not, we fail the function and return. - - There's also something special about a pending owner. That is a pending owner - is never blocked on a mutex. So there is no PI chain to worry about. It also - means that if the mutex doesn't have any waiters, there's no accounting needed - to update the pending owner's pi_list, since we only worry about processes - blocked on the current mutex. - - If there are waiters on this mutex, and we just stole the ownership, we need - to take the top waiter, remove it from the pi_list of the pending owner, and - add it to the current pi_list. Note that at this moment, the pending owner - is no longer on the list of waiters. This is fine, since the pending owner - would add itself back when it realizes that it had the ownership stolen - from itself. When the pending owner tries to grab the mutex, it will fail - in try_to_take_rt_mutex if the owner field points to another process. - - 2) No owner - ----------- - - If there is no owner (or we successfully stole the lock), we set the owner - of the mutex to current, and set the flag of "Has Waiters" if the current - mutex actually has waiters, or we clear the flag if it doesn't. See, it was - OK that we set that flag early, since now it is cleared. - - 3) Failed to grab ownership - --------------------------- - - The most interesting case is when we fail to take ownership. This means that - there exists an owner, or there's a pending owner with equal or higher - priority than the current task. - -We'll continue on the failed case. - -If the mutex has a timeout, we set up a timer to go off to break us out -of this mutex if we failed to get it after a specified amount of time. - -Now we enter a loop that will continue to try to take ownership of the mutex, or -fail from a timeout or signal. - -Once again we try to take the mutex. This will usually fail the first time -in the loop, since it had just failed to get the mutex. But the second time -in the loop, this would likely succeed, since the task would likely be -the pending owner. - -If the mutex is TASK_INTERRUPTIBLE a check for signals and timeout is done -here. - -The waiter structure has a "task" field that points to the task that is blocked -on the mutex. This field can be NULL the first time it goes through the loop -or if the task is a pending owner and had its mutex stolen. If the "task" -field is NULL then we need to set up the accounting for it. +If the lock is not taken by try_to_take_rt_mutex(), then the +task_blocks_on_rt_mutex() function is called. This will add the task to +the lock's waiter tree and propagate the pi chain of the lock as well +as the lock's owner's pi_waiters tree. This is described in the next +section. Task blocks on mutex -------------------- The accounting of a mutex and process is done with the waiter structure of the process. The "task" field is set to the process, and the "lock" field -to the mutex. The plist nodes are initialized to the processes current -priority. +to the mutex. The rbtree node of waiter are initialized to the processes +current priority. Since the wait_lock was taken at the entry of the slow lock, we can safely -add the waiter to the wait_list. If the current process is the highest -priority process currently waiting on this mutex, then we remove the -previous top waiter process (if it exists) from the pi_list of the owner, -and add the current process to that list. Since the pi_list of the owner +add the waiter to the task waiter tree. If the current process is the +highest priority process currently waiting on this mutex, then we remove the +previous top waiter process (if it exists) from the pi_waiters of the owner, +and add the current process to that tree. Since the pi_waiter of the owner has changed, we call rt_mutex_adjust_prio on the owner to see if the owner should adjust its priority accordingly. -If the owner is also blocked on a lock, and had its pi_list changed +If the owner is also blocked on a lock, and had its pi_waiters changed (or deadlock checking is on), we unlock the wait_lock of the mutex and go ahead and run rt_mutex_adjust_prio_chain on the owner, as described earlier. @@ -686,30 +480,23 @@ mutex (waiter "task" field is not NULL), then we go to sleep (call schedule). Waking up in the loop --------------------- -The schedule can then wake up for a few reasons. - 1) we were given pending ownership of the mutex. - 2) we received a signal and was TASK_INTERRUPTIBLE - 3) we had a timeout and was TASK_INTERRUPTIBLE +The task can then wake up for a couple of reasons: + 1) The previous lock owner released the lock, and the task now is top_waiter + 2) we received a signal or timeout -In any of these cases, we continue the loop and once again try to grab the -ownership of the mutex. If we succeed, we exit the loop, otherwise we continue -and on signal and timeout, will exit the loop, or if we had the mutex stolen -we just simply add ourselves back on the lists and go back to sleep. +In both cases, the task will try again to acquire the lock. If it +does, then it will take itself off the waiters tree and set itself back +to the TASK_RUNNING state. -Note: For various reasons, because of timeout and signals, the steal mutex - algorithm needs to be careful. This is because the current process is - still on the wait_list. And because of dynamic changing of priorities, - especially on SCHED_OTHER tasks, the current process can be the - highest priority task on the wait_list. +In first case, if the lock was acquired by another task before this task +could get the lock, then it will go back to sleep and wait to be woken again. -Failed to get mutex on Timeout or Signal ----------------------------------------- - -If a timeout or signal occurred, the waiter's "task" field would not be -NULL and the task needs to be taken off the wait_list of the mutex and perhaps -pi_list of the owner. If this process was a high priority process, then -the rt_mutex_adjust_prio_chain needs to be executed again on the owner, -but this time it will be lowering the priorities. +The second case is only applicable for tasks that are grabbing a mutex +that can wake up before getting the lock, either due to a signal or +a timeout (i.e. rt_mutex_timed_futex_lock()). When woken, it will try to +take the lock again, if it succeeds, then the task will return with the +lock held, otherwise it will return with -EINTR if the task was woken +by a signal, or -ETIMEDOUT if it timed out. Unlocking the Mutex @@ -739,25 +526,12 @@ owner still needs to make this check. If there are no waiters then the mutex owner field is set to NULL, the wait_lock is released and nothing more is needed. -If there are waiters, then we need to wake one up and give that waiter -pending ownership. +If there are waiters, then we need to wake one up. On the wake up code, the pi_lock of the current owner is taken. The top -waiter of the lock is found and removed from the wait_list of the mutex -as well as the pi_list of the current owner. The task field of the new -pending owner's waiter structure is set to NULL, and the owner field of the -mutex is set to the new owner with the "Pending Owner" bit set, as well -as the "Has Waiters" bit if there still are other processes blocked on the -mutex. - -The pi_lock of the previous owner is released, and the new pending owner's -pi_lock is taken. Remember that this is the trick to prevent the race -condition in rt_mutex_adjust_prio_chain from adding itself as a waiter -on the mutex. - -We now clear the "pi_blocked_on" field of the new pending owner, and if -the mutex still has waiters pending, we add the new top waiter to the pi_list -of the pending owner. +waiter of the lock is found and removed from the waiters tree of the mutex +as well as the pi_waiters tree of the current owner. The "Has Waiters" bit is +marked to prevent lower priority tasks from stealing the lock. Finally we unlock the pi_lock of the pending owner and wake it up. @@ -772,10 +546,14 @@ Credits ------- Author: Steven Rostedt +Updated: Alex Shi - 7/6/2017 -Reviewers: Ingo Molnar, Thomas Gleixner, Thomas Duetsch, and Randy Dunlap +Original Reviewers: Ingo Molnar, Thomas Gleixner, Thomas Duetsch, and + Randy Dunlap +Update (7/6/2017) Reviewers: Steven Rostedt and Sebastian Siewior Updates ------- This document was originally written for 2.6.17-rc3-mm1 +was updated on 4.12 diff --git a/Documentation/locking/rt-mutex.txt b/Documentation/locking/rt-mutex.txt index 243393d882ee..35793e003041 100644 --- a/Documentation/locking/rt-mutex.txt +++ b/Documentation/locking/rt-mutex.txt @@ -28,14 +28,13 @@ magic bullet for poorly designed applications, but it allows well-designed applications to use userspace locks in critical parts of an high priority thread, without losing determinism. -The enqueueing of the waiters into the rtmutex waiter list is done in +The enqueueing of the waiters into the rtmutex waiter tree is done in priority order. For same priorities FIFO order is chosen. For each rtmutex, only the top priority waiter is enqueued into the owner's -priority waiters list. This list too queues in priority order. Whenever +priority waiters tree. This tree too queues in priority order. Whenever the top priority waiter of a task changes (for example it timed out or -got a signal), the priority of the owner task is readjusted. [The -priority enqueueing is handled by "plists", see include/linux/plist.h -for more details.] +got a signal), the priority of the owner task is readjusted. The +priority enqueueing is handled by "pi_waiters". RT-mutexes are optimized for fastpath operations and have no internal locking overhead when locking an uncontended mutex or unlocking a mutex @@ -46,34 +45,29 @@ is used] The state of the rt-mutex is tracked via the owner field of the rt-mutex structure: -rt_mutex->owner holds the task_struct pointer of the owner. Bit 0 and 1 -are used to keep track of the "owner is pending" and "rtmutex has -waiters" state. +lock->owner holds the task_struct pointer of the owner. Bit 0 is used to +keep track of the "lock has waiters" state. - owner bit1 bit0 - NULL 0 0 mutex is free (fast acquire possible) - NULL 0 1 invalid state - NULL 1 0 Transitional state* - NULL 1 1 invalid state - taskpointer 0 0 mutex is held (fast release possible) - taskpointer 0 1 task is pending owner - taskpointer 1 0 mutex is held and has waiters - taskpointer 1 1 task is pending owner and mutex has waiters + owner bit0 + NULL 0 lock is free (fast acquire possible) + NULL 1 lock is free and has waiters and the top waiter + is going to take the lock* + taskpointer 0 lock is held (fast release possible) + taskpointer 1 lock is held and has waiters** -Pending-ownership handling is a performance optimization: -pending-ownership is assigned to the first (highest priority) waiter of -the mutex, when the mutex is released. The thread is woken up and once -it starts executing it can acquire the mutex. Until the mutex is taken -by it (bit 0 is cleared) a competing higher priority thread can "steal" -the mutex which puts the woken up thread back on the waiters list. +The fast atomic compare exchange based acquire and release is only +possible when bit 0 of lock->owner is 0. -The pending-ownership optimization is especially important for the -uninterrupted workflow of high-prio tasks which repeatedly -takes/releases locks that have lower-prio waiters. Without this -optimization the higher-prio thread would ping-pong to the lower-prio -task [because at unlock time we always assign a new owner]. +(*) It also can be a transitional state when grabbing the lock +with ->wait_lock is held. To prevent any fast path cmpxchg to the lock, +we need to set the bit0 before looking at the lock, and the owner may be +NULL in this small time, hence this can be a transitional state. -(*) The "mutex has waiters" bit gets set to take the lock. If the lock -doesn't already have an owner, this bit is quickly cleared if there are -no waiters. So this is a transitional state to synchronize with looking -at the owner field of the mutex and the mutex owner releasing the lock. +(**) There is a small time when bit 0 is set but there are no +waiters. This can happen when grabbing the lock in the slow path. +To prevent a cmpxchg of the owner releasing the lock, we need to +set this bit before looking at the lock. + +BTW, there is still technically a "Pending Owner", it's just not called +that anymore. The pending owner happens to be the top_waiter of a lock +that has no owner and has been woken up to grab the lock. diff --git a/Documentation/media/ca.h.rst.exceptions b/Documentation/media/ca.h.rst.exceptions index d7c9fed8c004..553559cc6ad7 100644 --- a/Documentation/media/ca.h.rst.exceptions +++ b/Documentation/media/ca.h.rst.exceptions @@ -16,7 +16,6 @@ replace define CA_NDS :c:type:`ca_descr_info` replace define CA_DSS :c:type:`ca_descr_info` # some typedefs should point to struct/enums -replace typedef ca_pid_t :c:type:`ca_pid` replace typedef ca_slot_info_t :c:type:`ca_slot_info` replace typedef ca_descr_info_t :c:type:`ca_descr_info` replace typedef ca_caps_t :c:type:`ca_caps` diff --git a/Documentation/media/cec-drivers/index.rst b/Documentation/media/cec-drivers/index.rst new file mode 100644 index 000000000000..7ef204823422 --- /dev/null +++ b/Documentation/media/cec-drivers/index.rst @@ -0,0 +1,34 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. include:: + +.. _cec-drivers: + +################################# +CEC driver-specific documentation +################################# + +**Copyright** |copy| 2017 : LinuxTV Developers + +This documentation is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +For more details see the file COPYING in the source distribution of Linux. + +.. only:: html + + .. class:: toc-title + + Table of Contents + +.. toctree:: + :maxdepth: 5 + :numbered: + + pulse8-cec diff --git a/Documentation/media/cec-drivers/pulse8-cec.rst b/Documentation/media/cec-drivers/pulse8-cec.rst new file mode 100644 index 000000000000..99551c6a9bc5 --- /dev/null +++ b/Documentation/media/cec-drivers/pulse8-cec.rst @@ -0,0 +1,11 @@ +Pulse-Eight CEC Adapter driver +============================== + +The pulse8-cec driver implements the following module option: + +``persistent_config`` +--------------------- + +By default this is off, but when set to 1 the driver will store the current +settings to the device's internal eeprom and restore it the next time the +device is connected to the USB port. diff --git a/Documentation/media/dmx.h.rst.exceptions b/Documentation/media/dmx.h.rst.exceptions index 2fdb458564ba..629db384104a 100644 --- a/Documentation/media/dmx.h.rst.exceptions +++ b/Documentation/media/dmx.h.rst.exceptions @@ -40,27 +40,17 @@ replace enum dmx_input :c:type:`dmx_input` replace symbol DMX_IN_FRONTEND :c:type:`dmx_input` replace symbol DMX_IN_DVR :c:type:`dmx_input` -# dmx_source_t symbols -replace enum dmx_source :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT0 :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT1 :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT2 :c:type:`dmx_source` -replace symbol DMX_SOURCE_FRONT3 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR0 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR1 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR2 :c:type:`dmx_source` -replace symbol DMX_SOURCE_DVR3 :c:type:`dmx_source` - - # Flags for struct dmx_sct_filter_params replace define DMX_CHECK_CRC :c:type:`dmx_sct_filter_params` replace define DMX_ONESHOT :c:type:`dmx_sct_filter_params` replace define DMX_IMMEDIATE_START :c:type:`dmx_sct_filter_params` -replace define DMX_KERNEL_CLIENT :c:type:`dmx_sct_filter_params` # some typedefs should point to struct/enums -replace typedef dmx_caps_t :c:type:`dmx_caps` replace typedef dmx_filter_t :c:type:`dmx_filter` replace typedef dmx_pes_type_t :c:type:`dmx_pes_type` replace typedef dmx_input_t :c:type:`dmx_input` -replace typedef dmx_source_t :c:type:`dmx_source` + +ignore symbol DMX_OUT_DECODER +ignore symbol DMX_OUT_TAP +ignore symbol DMX_OUT_TS_TAP +ignore symbol DMX_OUT_TSDEMUX_TAP diff --git a/Documentation/media/dvb-drivers/ci.rst b/Documentation/media/dvb-drivers/ci.rst index 69b07e9d1816..87f3748c49b9 100644 --- a/Documentation/media/dvb-drivers/ci.rst +++ b/Documentation/media/dvb-drivers/ci.rst @@ -143,7 +143,6 @@ All these ioctls are also valid for the High level CI interface #define CA_GET_MSG _IOR('o', 132, ca_msg_t) #define CA_SEND_MSG _IOW('o', 133, ca_msg_t) #define CA_SET_DESCR _IOW('o', 134, ca_descr_t) -#define CA_SET_PID _IOW('o', 135, ca_pid_t) On querying the device, the device yields information thus: diff --git a/Documentation/media/dvb-drivers/index.rst b/Documentation/media/dvb-drivers/index.rst index ea0da6d63299..376141143ae9 100644 --- a/Documentation/media/dvb-drivers/index.rst +++ b/Documentation/media/dvb-drivers/index.rst @@ -19,7 +19,9 @@ more details. For more details see the file COPYING in the source distribution of Linux. -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/frontend.h.rst.exceptions b/Documentation/media/frontend.h.rst.exceptions index 7656770f1936..f7c4df620a52 100644 --- a/Documentation/media/frontend.h.rst.exceptions +++ b/Documentation/media/frontend.h.rst.exceptions @@ -25,19 +25,9 @@ ignore define DTV_MAX_COMMAND ignore define MAX_DTV_STATS ignore define DTV_IOCTL_MAX_MSGS -# Stats enum is documented altogether -replace enum fecap_scale_params :ref:`frontend-stat-properties` -replace symbol FE_SCALE_COUNTER frontend-stat-properties -replace symbol FE_SCALE_DECIBEL frontend-stat-properties -replace symbol FE_SCALE_NOT_AVAILABLE frontend-stat-properties -replace symbol FE_SCALE_RELATIVE frontend-stat-properties - # the same reference is used for both get and set ioctls replace ioctl FE_SET_PROPERTY :c:type:`FE_GET_PROPERTY` -# Ignore struct used only internally at Kernel -ignore struct dtv_cmds_h - # Typedefs that use the enum reference replace typedef fe_sec_voltage_t :c:type:`fe_sec_voltage` @@ -45,3 +35,178 @@ replace typedef fe_sec_voltage_t :c:type:`fe_sec_voltage` replace define FE_TUNE_MODE_ONESHOT :c:func:`FE_SET_FRONTEND_TUNE_MODE` replace define LNA_AUTO dtv-lna replace define NO_STREAM_ID_FILTER dtv-stream-id + +# Those enums are defined at the frontend.h header, and not externally + +ignore symbol FE_IS_STUPID +ignore symbol FE_CAN_INVERSION_AUTO +ignore symbol FE_CAN_FEC_1_2 +ignore symbol FE_CAN_FEC_2_3 +ignore symbol FE_CAN_FEC_3_4 +ignore symbol FE_CAN_FEC_4_5 +ignore symbol FE_CAN_FEC_5_6 +ignore symbol FE_CAN_FEC_6_7 +ignore symbol FE_CAN_FEC_7_8 +ignore symbol FE_CAN_FEC_8_9 +ignore symbol FE_CAN_FEC_AUTO +ignore symbol FE_CAN_QPSK +ignore symbol FE_CAN_QAM_16 +ignore symbol FE_CAN_QAM_32 +ignore symbol FE_CAN_QAM_64 +ignore symbol FE_CAN_QAM_128 +ignore symbol FE_CAN_QAM_256 +ignore symbol FE_CAN_QAM_AUTO +ignore symbol FE_CAN_TRANSMISSION_MODE_AUTO +ignore symbol FE_CAN_BANDWIDTH_AUTO +ignore symbol FE_CAN_GUARD_INTERVAL_AUTO +ignore symbol FE_CAN_HIERARCHY_AUTO +ignore symbol FE_CAN_8VSB +ignore symbol FE_CAN_16VSB +ignore symbol FE_HAS_EXTENDED_CAPS +ignore symbol FE_CAN_MULTISTREAM +ignore symbol FE_CAN_TURBO_FEC +ignore symbol FE_CAN_2G_MODULATION +ignore symbol FE_NEEDS_BENDING +ignore symbol FE_CAN_RECOVER +ignore symbol FE_CAN_MUTE_TS + +ignore symbol QPSK +ignore symbol QAM_16 +ignore symbol QAM_32 +ignore symbol QAM_64 +ignore symbol QAM_128 +ignore symbol QAM_256 +ignore symbol QAM_AUTO +ignore symbol VSB_8 +ignore symbol VSB_16 +ignore symbol PSK_8 +ignore symbol APSK_16 +ignore symbol APSK_32 +ignore symbol DQPSK +ignore symbol QAM_4_NR + +ignore symbol SEC_VOLTAGE_13 +ignore symbol SEC_VOLTAGE_18 +ignore symbol SEC_VOLTAGE_OFF + +ignore symbol SEC_TONE_ON +ignore symbol SEC_TONE_OFF + +ignore symbol SEC_MINI_A +ignore symbol SEC_MINI_B + +ignore symbol FE_NONE +ignore symbol FE_HAS_SIGNAL +ignore symbol FE_HAS_CARRIER +ignore symbol FE_HAS_VITERBI +ignore symbol FE_HAS_SYNC +ignore symbol FE_HAS_LOCK +ignore symbol FE_REINIT +ignore symbol FE_TIMEDOUT + +ignore symbol FEC_NONE +ignore symbol FEC_1_2 +ignore symbol FEC_2_3 +ignore symbol FEC_3_4 +ignore symbol FEC_4_5 +ignore symbol FEC_5_6 +ignore symbol FEC_6_7 +ignore symbol FEC_7_8 +ignore symbol FEC_8_9 +ignore symbol FEC_AUTO +ignore symbol FEC_3_5 +ignore symbol FEC_9_10 +ignore symbol FEC_2_5 + +ignore symbol TRANSMISSION_MODE_AUTO +ignore symbol TRANSMISSION_MODE_1K +ignore symbol TRANSMISSION_MODE_2K +ignore symbol TRANSMISSION_MODE_8K +ignore symbol TRANSMISSION_MODE_4K +ignore symbol TRANSMISSION_MODE_16K +ignore symbol TRANSMISSION_MODE_32K +ignore symbol TRANSMISSION_MODE_C1 +ignore symbol TRANSMISSION_MODE_C3780 +ignore symbol TRANSMISSION_MODE_2K +ignore symbol TRANSMISSION_MODE_8K + +ignore symbol GUARD_INTERVAL_AUTO +ignore symbol GUARD_INTERVAL_1_128 +ignore symbol GUARD_INTERVAL_1_32 +ignore symbol GUARD_INTERVAL_1_16 +ignore symbol GUARD_INTERVAL_1_8 +ignore symbol GUARD_INTERVAL_1_4 +ignore symbol GUARD_INTERVAL_19_128 +ignore symbol GUARD_INTERVAL_19_256 +ignore symbol GUARD_INTERVAL_PN420 +ignore symbol GUARD_INTERVAL_PN595 +ignore symbol GUARD_INTERVAL_PN945 + +ignore symbol HIERARCHY_NONE +ignore symbol HIERARCHY_AUTO +ignore symbol HIERARCHY_1 +ignore symbol HIERARCHY_2 +ignore symbol HIERARCHY_4 + +ignore symbol INTERLEAVING_NONE +ignore symbol INTERLEAVING_AUTO +ignore symbol INTERLEAVING_240 +ignore symbol INTERLEAVING_720 + +ignore symbol PILOT_ON +ignore symbol PILOT_OFF +ignore symbol PILOT_AUTO + +ignore symbol ROLLOFF_35 +ignore symbol ROLLOFF_20 +ignore symbol ROLLOFF_25 +ignore symbol ROLLOFF_AUTO + +ignore symbol INVERSION_ON +ignore symbol INVERSION_OFF +ignore symbol INVERSION_AUTO + +ignore symbol SYS_UNDEFINED +ignore symbol SYS_DVBC_ANNEX_A +ignore symbol SYS_DVBC_ANNEX_B +ignore symbol SYS_DVBC_ANNEX_C +ignore symbol SYS_ISDBC +ignore symbol SYS_DVBT +ignore symbol SYS_DVBT2 +ignore symbol SYS_ISDBT +ignore symbol SYS_ATSC +ignore symbol SYS_ATSCMH +ignore symbol SYS_DTMB +ignore symbol SYS_DVBS +ignore symbol SYS_DVBS2 +ignore symbol SYS_TURBO +ignore symbol SYS_ISDBS +ignore symbol SYS_DAB +ignore symbol SYS_DSS +ignore symbol SYS_CMMB +ignore symbol SYS_DVBH + +ignore symbol ATSCMH_SCCC_BLK_SEP +ignore symbol ATSCMH_SCCC_BLK_COMB +ignore symbol ATSCMH_SCCC_BLK_RES + +ignore symbol ATSCMH_SCCC_CODE_HLF +ignore symbol ATSCMH_SCCC_CODE_QTR +ignore symbol ATSCMH_SCCC_CODE_RES + +ignore symbol ATSCMH_RSFRAME_ENS_PRI +ignore symbol ATSCMH_RSFRAME_ENS_SEC + +ignore symbol ATSCMH_RSFRAME_PRI_ONLY +ignore symbol ATSCMH_RSFRAME_PRI_SEC +ignore symbol ATSCMH_RSFRAME_RES + +ignore symbol ATSCMH_RSCODE_211_187 +ignore symbol ATSCMH_RSCODE_223_187 +ignore symbol ATSCMH_RSCODE_235_187 +ignore symbol ATSCMH_RSCODE_RES + +ignore symbol FE_SCALE_NOT_AVAILABLE +ignore symbol FE_SCALE_DECIBEL +ignore symbol FE_SCALE_RELATIVE +ignore symbol FE_SCALE_COUNTER diff --git a/Documentation/media/index.rst b/Documentation/media/index.rst index 7f8f0af620ce..1cf5316c8ff8 100644 --- a/Documentation/media/index.rst +++ b/Documentation/media/index.rst @@ -1,7 +1,11 @@ Linux Media Subsystem Documentation =================================== -Contents: +.. only:: html + + .. class:: toc-title + + Table of Contents .. toctree:: :maxdepth: 2 @@ -10,6 +14,7 @@ Contents: media_kapi dvb-drivers/index v4l-drivers/index + cec-drivers/index .. only:: subproject diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst index 8a65c69ed071..28866259998c 100644 --- a/Documentation/media/kapi/cec-core.rst +++ b/Documentation/media/kapi/cec-core.rst @@ -107,6 +107,7 @@ your driver: int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); + void (*adap_free)(struct cec_adapter *adap); /* High-level callbacks */ ... @@ -184,6 +185,14 @@ To log the current CEC hardware status: This optional callback can be used to show the status of the CEC hardware. The status is available through debugfs: cat /sys/kernel/debug/cec/cecX/status +To free any resources when the adapter is deleted: + +.. c:function:: + void (*adap_free)(struct cec_adapter *adap); + +This optional callback can be used to free any resources that might have been +allocated by the driver. It's called from cec_delete_adapter. + Your adapter driver will also have to react to events (typically interrupt driven) by calling into the framework in the following situations: @@ -336,3 +345,34 @@ log_addrs->num_log_addrs set to 0. The block argument is ignored when unconfiguring. This function will just return if the physical address is invalid. Once the physical address becomes valid, then the framework will attempt to claim these logical addresses. + +CEC Pin framework +----------------- + +Most CEC hardware operates on full CEC messages where the software provides +the message and the hardware handles the low-level CEC protocol. But some +hardware only drives the CEC pin and software has to handle the low-level +CEC protocol. The CEC pin framework was created to handle such devices. + +Note that due to the close-to-realtime requirements it can never be guaranteed +to work 100%. This framework uses highres timers internally, but if a +timer goes off too late by more than 300 microseconds wrong results can +occur. In reality it appears to be fairly reliable. + +One advantage of this low-level implementation is that it can be used as +a cheap CEC analyser, especially if interrupts can be used to detect +CEC pin transitions from low to high or vice versa. + +.. kernel-doc:: include/media/cec-pin.h + +CEC Notifier framework +---------------------- + +Most drm HDMI implementations have an integrated CEC implementation and no +notifier support is needed. But some have independent CEC implementations +that have their own driver. This could be an IP block for an SoC or a +completely separate chip that deals with the CEC pin. For those cases a +drm driver can install a notifier and use the notifier to inform the +CEC driver about changes in the physical address. + +.. kernel-doc:: include/media/cec-notifier.h diff --git a/Documentation/media/kapi/csi2.rst b/Documentation/media/kapi/csi2.rst index e33fcb967922..0560100efca2 100644 --- a/Documentation/media/kapi/csi2.rst +++ b/Documentation/media/kapi/csi2.rst @@ -51,6 +51,16 @@ not active. Some transmitters do this automatically but some have to be explicitly programmed to do so, and some are unable to do so altogether due to hardware constraints. +Stopping the transmitter +^^^^^^^^^^^^^^^^^^^^^^^^ + +A transmitter stops sending the stream of images as a result of +calling the ``.s_stream()`` callback. Some transmitters may stop the +stream at a frame boundary whereas others stop immediately, +effectively leaving the current frame unfinished. The receiver driver +should not make assumptions either way, but function properly in both +cases. + Receiver drivers ---------------- diff --git a/Documentation/media/kapi/v4l2-event.rst b/Documentation/media/kapi/v4l2-event.rst index 9a5e31546ae3..9938d21ef4d1 100644 --- a/Documentation/media/kapi/v4l2-event.rst +++ b/Documentation/media/kapi/v4l2-event.rst @@ -67,6 +67,8 @@ type). The ops argument allows the driver to specify a number of callbacks: +.. tabularcolumns:: |p{1.5cm}|p{16.0cm}| + ======== ============================================================== Callback Description ======== ============================================================== diff --git a/Documentation/media/media_kapi.rst b/Documentation/media/media_kapi.rst index bc0638956a43..83da736fad72 100644 --- a/Documentation/media/media_kapi.rst +++ b/Documentation/media/media_kapi.rst @@ -20,7 +20,9 @@ more details. For more details see the file COPYING in the source distribution of Linux. -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/media_uapi.rst b/Documentation/media/media_uapi.rst index fd8ebe002cd2..28eb35a1f965 100644 --- a/Documentation/media/media_uapi.rst +++ b/Documentation/media/media_uapi.rst @@ -14,7 +14,9 @@ any later version published by the Free Software Foundation. A copy of the license is included in the chapter entitled "GNU Free Documentation License". -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/uapi/cec/cec-api.rst b/Documentation/media/uapi/cec/cec-api.rst index bb018709970c..b68ca9c1d2e0 100644 --- a/Documentation/media/uapi/cec/cec-api.rst +++ b/Documentation/media/uapi/cec/cec-api.rst @@ -10,7 +10,10 @@ Part V - Consumer Electronics Control API This part describes the CEC: Consumer Electronics Control -.. class:: toc-title + +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/uapi/cec/cec-func-close.rst b/Documentation/media/uapi/cec/cec-func-close.rst index 895d9c2d1c04..334358dfa72e 100644 --- a/Documentation/media/uapi/cec/cec-func-close.rst +++ b/Documentation/media/uapi/cec/cec-func-close.rst @@ -40,7 +40,7 @@ freed. The device configuration remain unchanged. Return Value ============ -:c:func:`close()` returns 0 on success. On error, -1 is returned, and +:c:func:`close() ` returns 0 on success. On error, -1 is returned, and ``errno`` is set appropriately. Possible error codes are: ``EBADF`` diff --git a/Documentation/media/uapi/cec/cec-func-ioctl.rst b/Documentation/media/uapi/cec/cec-func-ioctl.rst index 22fb6304a2df..e2b6260b0086 100644 --- a/Documentation/media/uapi/cec/cec-func-ioctl.rst +++ b/Documentation/media/uapi/cec/cec-func-ioctl.rst @@ -39,7 +39,7 @@ Arguments Description =========== -The :c:func:`ioctl()` function manipulates cec device parameters. The +The :c:func:`ioctl() ` function manipulates cec device parameters. The argument ``fd`` must be an open file descriptor. The ioctl ``request`` code specifies the cec function to be called. It diff --git a/Documentation/media/uapi/cec/cec-func-open.rst b/Documentation/media/uapi/cec/cec-func-open.rst index 18dfb62f2efe..5d6663a649bd 100644 --- a/Documentation/media/uapi/cec/cec-func-open.rst +++ b/Documentation/media/uapi/cec/cec-func-open.rst @@ -46,7 +46,7 @@ Arguments Description =========== -To open a cec device applications call :c:func:`open()` with the +To open a cec device applications call :c:func:`open() ` with the desired device name. The function has no side effects; the device configuration remain unchanged. @@ -58,7 +58,7 @@ EBADF. Return Value ============ -:c:func:`open()` returns the new file descriptor on success. On error, +:c:func:`open() ` returns the new file descriptor on success. On error, -1 is returned, and ``errno`` is set appropriately. Possible error codes include: diff --git a/Documentation/media/uapi/cec/cec-func-poll.rst b/Documentation/media/uapi/cec/cec-func-poll.rst index fa0abd8fb160..d49f1ee0742d 100644 --- a/Documentation/media/uapi/cec/cec-func-poll.rst +++ b/Documentation/media/uapi/cec/cec-func-poll.rst @@ -39,10 +39,10 @@ Arguments Description =========== -With the :c:func:`poll()` function applications can wait for CEC +With the :c:func:`poll() ` function applications can wait for CEC events. -On success :c:func:`poll()` returns the number of file descriptors +On success :c:func:`poll() ` returns the number of file descriptors that have been selected (that is, file descriptors for which the ``revents`` field of the respective struct :c:type:`pollfd` is non-zero). CEC devices set the ``POLLIN`` and ``POLLRDNORM`` flags in @@ -53,13 +53,13 @@ then the ``POLLPRI`` flag is set. When the function times out it returns a value of zero, on failure it returns -1 and the ``errno`` variable is set appropriately. -For more details see the :c:func:`poll()` manual page. +For more details see the :c:func:`poll() ` manual page. Return Value ============ -On success, :c:func:`poll()` returns the number structures which have +On success, :c:func:`poll() ` returns the number structures which have non-zero ``revents`` fields, or zero if the call timed out. On error -1 is returned, and the ``errno`` variable is set appropriately: diff --git a/Documentation/media/uapi/cec/cec-funcs.rst b/Documentation/media/uapi/cec/cec-funcs.rst index 5b7630f2e076..6d696cead5cb 100644 --- a/Documentation/media/uapi/cec/cec-funcs.rst +++ b/Documentation/media/uapi/cec/cec-funcs.rst @@ -7,7 +7,6 @@ Function Reference .. toctree:: :maxdepth: 1 - :numbered: cec-func-open cec-func-close diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst index 6d7bf7bef3eb..6c1f6efb822e 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-caps.rst @@ -21,7 +21,7 @@ Arguments ========= ``fd`` - File descriptor returned by :ref:`open() `. + File descriptor returned by :c:func:`open() `. ``argp`` @@ -121,6 +121,13 @@ returns the information to the application. The ioctl never fails. high. This makes it impossible to use CEC to wake up displays that set the HPD pin low when in standby mode, but keep the CEC bus alive. + * .. _`CEC-CAP-MONITOR-PIN`: + + - ``CEC_CAP_MONITOR_PIN`` + - 0x00000080 + - The CEC hardware can monitor CEC pin changes from low to high voltage + and vice versa. When in pin monitoring mode the application will + receive ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events. diff --git a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst index fcf863ab6f43..84f431a022ad 100644 --- a/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst +++ b/Documentation/media/uapi/cec/cec-ioc-adap-g-log-addrs.rst @@ -48,7 +48,9 @@ can only be called by a file descriptor in initiator mode (see :ref:`CEC_S_MODE` the ``EBUSY`` error code will be returned. To clear existing logical addresses set ``num_log_addrs`` to 0. All other fields -will be ignored in that case. The adapter will go to the unconfigured state. +will be ignored in that case. The adapter will go to the unconfigured state and the +``cec_version``, ``vendor_id`` and ``osd_name`` fields are all reset to their default +values (CEC version 2.0, no vendor ID and an empty OSD name). If the physical address is valid (see :ref:`ioctl CEC_ADAP_S_PHYS_ADDR `), then this ioctl will block until all requested logical @@ -63,7 +65,7 @@ logical address types are already defined will return with error ``EBUSY``. .. c:type:: cec_log_addrs -.. tabularcolumns:: |p{1.0cm}|p{7.5cm}|p{8.0cm}| +.. tabularcolumns:: |p{1.0cm}|p{8.0cm}|p{7.5cm}| .. cssclass:: longtable @@ -146,6 +148,9 @@ logical address types are already defined will return with error ``EBUSY``. give the CEC framework more information about the device type, even though the framework won't use it directly in the CEC message. + +.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}| + .. _cec-log-addrs-flags: .. flat-table:: Flags for struct cec_log_addrs @@ -173,7 +178,7 @@ logical address types are already defined will return with error ``EBUSY``. to avoid trivial snooping of the keystrokes. * .. _`CEC-LOG-ADDRS-FL-CDC-ONLY`: - - `CEC_LOG_ADDRS_FL_CDC_ONLY` + - ``CEC_LOG_ADDRS_FL_CDC_ONLY`` - 4 - If this flag is set, then the device is CDC-Only. CDC-Only CEC devices are CEC devices that can only handle CDC messages. @@ -181,7 +186,7 @@ logical address types are already defined will return with error ``EBUSY``. All other messages are ignored. -.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| +.. tabularcolumns:: |p{7.8cm}|p{1.0cm}|p{8.7cm}| .. _cec-versions: diff --git a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst index 4d3570c2e0b3..a5c821809cc6 100644 --- a/Documentation/media/uapi/cec/cec-ioc-dqevent.rst +++ b/Documentation/media/uapi/cec/cec-ioc-dqevent.rst @@ -22,7 +22,7 @@ Arguments ========= ``fd`` - File descriptor returned by :ref:`open() `. + File descriptor returned by :c:func:`open() `. ``argp`` @@ -87,7 +87,7 @@ it is guaranteed that the state did change in between the two events. this is more than enough. -.. tabularcolumns:: |p{1.0cm}|p{4.2cm}|p{2.5cm}|p{8.8cm}| +.. tabularcolumns:: |p{1.0cm}|p{4.4cm}|p{2.5cm}|p{9.6cm}| .. c:type:: cec_event @@ -98,10 +98,11 @@ it is guaranteed that the state did change in between the two events. * - __u64 - ``ts`` - - :cspan:`1` Timestamp of the event in ns. + - :cspan:`1`\ Timestamp of the event in ns. - The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. To access - the same clock from userspace use :c:func:`clock_gettime`. + The timestamp has been taken from the ``CLOCK_MONOTONIC`` clock. + + To access the same clock from userspace use :c:func:`clock_gettime`. * - __u32 - ``event`` - :cspan:`1` The CEC event type, see :ref:`cec-events`. @@ -146,6 +147,20 @@ it is guaranteed that the state did change in between the two events. - 2 - Generated if one or more CEC messages were lost because the application didn't dequeue CEC messages fast enough. + * .. _`CEC-EVENT-PIN-CEC-LOW`: + + - ``CEC_EVENT_PIN_CEC_LOW`` + - 3 + - Generated if the CEC pin goes from a high voltage to a low voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. + * .. _`CEC-EVENT-PIN-CEC-HIGH`: + + - ``CEC_EVENT_PIN_CEC_HIGH`` + - 4 + - Generated if the CEC pin goes from a low voltage to a high voltage. + Only applies to adapters that have the ``CEC_CAP_MONITOR_PIN`` + capability set. .. tabularcolumns:: |p{6.0cm}|p{0.6cm}|p{10.9cm}| @@ -165,6 +180,12 @@ it is guaranteed that the state did change in between the two events. opened. See the table above for which events do this. This allows applications to learn the initial state of the CEC adapter at open() time. + * .. _`CEC-EVENT-FL-DROPPED-EVENTS`: + + - ``CEC_EVENT_FL_DROPPED_EVENTS`` + - 2 + - Set if one or more events of the given event type have been dropped. + This is an indication that the application cannot keep up. diff --git a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst index 664f0d47bbcd..508e2e325683 100644 --- a/Documentation/media/uapi/cec/cec-ioc-g-mode.rst +++ b/Documentation/media/uapi/cec/cec-ioc-g-mode.rst @@ -108,6 +108,8 @@ Available follower modes are: .. _cec-mode-follower_e: +.. cssclass:: longtable + .. flat-table:: Follower Modes :header-rows: 0 :stub-columns: 0 @@ -149,13 +151,28 @@ Available follower modes are: code. You cannot become a follower if :ref:`CEC_CAP_TRANSMIT ` is not set or if :ref:`CEC_MODE_NO_INITIATOR ` was specified, the ``EINVAL`` error code is returned in that case. + * .. _`CEC-MODE-MONITOR-PIN`: + + - ``CEC_MODE_MONITOR_PIN`` + - 0xd0 + - Put the file descriptor into pin monitoring mode. Can only be used in + combination with :ref:`CEC_MODE_NO_INITIATOR `, + otherwise the ``EINVAL`` error code will be returned. + This mode requires that the :ref:`CEC_CAP_MONITOR_PIN ` + capability is set, otherwise the ``EINVAL`` error code is returned. + While in pin monitoring mode this file descriptor can receive the + ``CEC_EVENT_PIN_CEC_LOW`` and ``CEC_EVENT_PIN_CEC_HIGH`` events to see the + low-level CEC pin transitions. This is very useful for debugging. + This mode is only allowed if the process has the ``CAP_NET_ADMIN`` + capability. If that is not set, then the ``EPERM`` error code is returned. * .. _`CEC-MODE-MONITOR`: - ``CEC_MODE_MONITOR`` - 0xe0 - Put the file descriptor into monitor mode. Can only be used in - combination with :ref:`CEC_MODE_NO_INITIATOR `, otherwise EINVAL error - code will be returned. In monitor mode all messages this CEC + combination with :ref:`CEC_MODE_NO_INITIATOR `,i + otherwise the ``EINVAL`` error code will be returned. + In monitor mode all messages this CEC device transmits and all messages it receives (both broadcast messages and directed messages for one its logical addresses) will be reported. This is very useful for debugging. This is only @@ -191,55 +208,68 @@ Core message processing details: * .. _`CEC-MSG-GET-CEC-VERSION`: - ``CEC_MSG_GET_CEC_VERSION`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return the CEC version that was - set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + - The core will return the CEC version that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. * .. _`CEC-MSG-GIVE-DEVICE-VENDOR-ID`: - ``CEC_MSG_GIVE_DEVICE_VENDOR_ID`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return the vendor ID that was - set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + - The core will return the vendor ID that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. * .. _`CEC-MSG-ABORT`: - ``CEC_MSG_ABORT`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will return a feature refused - message as per the specification. + - The core will return a Feature Abort message with reason + 'Feature Refused' as per the specification, except when in + passthrough mode. In passthrough mode the core does nothing + and this message has to be handled by a follower instead. * .. _`CEC-MSG-GIVE-PHYSICAL-ADDR`: - ``CEC_MSG_GIVE_PHYSICAL_ADDR`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current physical - address. + - The core will report the current physical address, except when + in passthrough mode. In passthrough mode the core does nothing + and this message has to be handled by a follower instead. * .. _`CEC-MSG-GIVE-OSD-NAME`: - ``CEC_MSG_GIVE_OSD_NAME`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current OSD name as - was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `. + - The core will report the current OSD name that was set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing and this message has to be handled by a follower + instead. * .. _`CEC-MSG-GIVE-FEATURES`: - ``CEC_MSG_GIVE_FEATURES`` - - When in passthrough mode this message has to be handled by - userspace, otherwise the core will report the current features as - was set with :ref:`ioctl CEC_ADAP_S_LOG_ADDRS ` - or the message is ignored if the CEC version was older than 2.0. + - The core will do nothing if the CEC version is older than 2.0, + otherwise it will report the current features that were set with + :ref:`ioctl CEC_ADAP_S_LOG_ADDRS `, + except when in passthrough mode. In passthrough mode the core + does nothing (for any CEC version) and this message has to be handled + by a follower instead. * .. _`CEC-MSG-USER-CONTROL-PRESSED`: - ``CEC_MSG_USER_CONTROL_PRESSED`` - - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key - press. This message is always passed on to userspace. + - If :ref:`CEC_CAP_RC ` is set and if + :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU ` + is set, then generate a remote control key + press. This message is always passed on to the follower(s). * .. _`CEC-MSG-USER-CONTROL-RELEASED`: - ``CEC_MSG_USER_CONTROL_RELEASED`` - - If :ref:`CEC_CAP_RC ` is set, then generate a remote control key - release. This message is always passed on to userspace. + - If :ref:`CEC_CAP_RC ` is set and if + :ref:`CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU ` + is set, then generate a remote control key + release. This message is always passed on to the follower(s). * .. _`CEC-MSG-REPORT-PHYSICAL-ADDR`: - ``CEC_MSG_REPORT_PHYSICAL_ADDR`` - The CEC framework will make note of the reported physical address - and then just pass the message on to userspace. + and then just pass the message on to the follower(s). diff --git a/Documentation/media/uapi/cec/cec-ioc-receive.rst b/Documentation/media/uapi/cec/cec-ioc-receive.rst index 267044f7ac30..0f397c535a4c 100644 --- a/Documentation/media/uapi/cec/cec-ioc-receive.rst +++ b/Documentation/media/uapi/cec/cec-ioc-receive.rst @@ -195,6 +195,8 @@ View On' messages from initiator 0xf ('Unregistered') to destination 0 ('TV'). valid if the :ref:`CEC_TX_STATUS_ERROR ` status bit is set. +.. tabularcolumns:: |p{6.2cm}|p{1.0cm}|p{10.3cm}| + .. _cec-msg-flags: .. flat-table:: Flags for struct cec_msg diff --git a/Documentation/media/uapi/dvb/audio-channel-select.rst b/Documentation/media/uapi/dvb/audio-channel-select.rst index 2ceb4efebdf0..8cab3d7abff5 100644 --- a/Documentation/media/uapi/dvb/audio-channel-select.rst +++ b/Documentation/media/uapi/dvb/audio-channel-select.rst @@ -44,7 +44,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 ``V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK`` control instead. This ioctl call asks the Audio Device to select the requested channel if diff --git a/Documentation/media/uapi/dvb/audio-fclose.rst b/Documentation/media/uapi/dvb/audio-fclose.rst index 4df24c8d74ed..58d351a3af4b 100644 --- a/Documentation/media/uapi/dvb/audio-fclose.rst +++ b/Documentation/media/uapi/dvb/audio-fclose.rst @@ -2,14 +2,14 @@ .. _audio_fclose: -================= -DVB audio close() -================= +======================== +Digital TV audio close() +======================== Name ---- -DVB audio close() +Digital TV audio close() .. attention:: This ioctl is deprecated diff --git a/Documentation/media/uapi/dvb/audio-fopen.rst b/Documentation/media/uapi/dvb/audio-fopen.rst index a802c2e0dc6a..4a174640bf11 100644 --- a/Documentation/media/uapi/dvb/audio-fopen.rst +++ b/Documentation/media/uapi/dvb/audio-fopen.rst @@ -2,14 +2,14 @@ .. _audio_fopen: -================ -DVB audio open() -================ +======================= +Digital TV audio open() +======================= Name ---- -DVB audio open() +Digital TV audio open() .. attention:: This ioctl is deprecated diff --git a/Documentation/media/uapi/dvb/audio-fwrite.rst b/Documentation/media/uapi/dvb/audio-fwrite.rst index 8882cad7d165..4980ae7953ef 100644 --- a/Documentation/media/uapi/dvb/audio-fwrite.rst +++ b/Documentation/media/uapi/dvb/audio-fwrite.rst @@ -2,14 +2,14 @@ .. _audio_fwrite: -================= -DVB audio write() -================= +========================= +Digital TV audio write() +========================= Name ---- -DVB audio write() +Digital TV audio write() .. attention:: This ioctl is deprecated diff --git a/Documentation/media/uapi/dvb/audio-set-av-sync.rst b/Documentation/media/uapi/dvb/audio-set-av-sync.rst index 0cef4917d2cf..cf621f3a3037 100644 --- a/Documentation/media/uapi/dvb/audio-set-av-sync.rst +++ b/Documentation/media/uapi/dvb/audio-set-av-sync.rst @@ -38,7 +38,7 @@ Arguments - boolean state - - Tells the DVB subsystem if A/V synchronization shall be ON or OFF. + - Tells the Digital TV subsystem if A/V synchronization shall be ON or OFF. TRUE: AV-sync ON diff --git a/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst b/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst index b063c496c2eb..f0db1fbdb066 100644 --- a/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst +++ b/Documentation/media/uapi/dvb/audio-set-bypass-mode.rst @@ -38,7 +38,7 @@ Arguments - boolean mode - Enables or disables the decoding of the current Audio stream in - the DVB subsystem. + the Digital TV subsystem. TRUE: Bypass is disabled @@ -50,8 +50,8 @@ Description This ioctl call asks the Audio Device to bypass the Audio decoder and forward the stream without decoding. This mode shall be used if streams -that can’t be handled by the DVB system shall be decoded. Dolby -DigitalTM streams are automatically forwarded by the DVB subsystem if +that can’t be handled by the Digial TV system shall be decoded. Dolby +DigitalTM streams are automatically forwarded by the Digital TV subsystem if the hardware can handle it. diff --git a/Documentation/media/uapi/dvb/audio-set-mute.rst b/Documentation/media/uapi/dvb/audio-set-mute.rst index 897e7228f4d8..0af105a8ddcc 100644 --- a/Documentation/media/uapi/dvb/audio-set-mute.rst +++ b/Documentation/media/uapi/dvb/audio-set-mute.rst @@ -48,7 +48,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` with the ``V4L2_DEC_CMD_START_MUTE_AUDIO`` flag instead. diff --git a/Documentation/media/uapi/dvb/audio.rst b/Documentation/media/uapi/dvb/audio.rst index 155622185ea4..e9f9e589c486 100644 --- a/Documentation/media/uapi/dvb/audio.rst +++ b/Documentation/media/uapi/dvb/audio.rst @@ -2,15 +2,16 @@ .. _dvb_audio: -################ -DVB Audio Device -################ -The DVB audio device controls the MPEG2 audio decoder of the DVB -hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data +####################### +Digital TV Audio Device +####################### + +The Digital TV audio device controls the MPEG2 audio decoder of the Digital +TV hardware. It can be accessed through ``/dev/dvb/adapter?/audio?``. Data types and and ioctl definitions can be accessed by including ``linux/dvb/audio.h`` in your application. -Please note that some DVB cards don’t have their own MPEG decoder, which +Please note that some Digital TV cards don’t have their own MPEG decoder, which results in the omission of the audio and video device. These ioctls were also used by V4L2 to control MPEG decoders implemented diff --git a/Documentation/media/uapi/dvb/audio_h.rst b/Documentation/media/uapi/dvb/audio_h.rst deleted file mode 100644 index e00c3010fdf9..000000000000 --- a/Documentation/media/uapi/dvb/audio_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _audio_h: - -********************* -DVB Audio Header File -********************* - -.. kernel-include:: $BUILDDIR/audio.h.rst diff --git a/Documentation/media/uapi/dvb/ca-fclose.rst b/Documentation/media/uapi/dvb/ca-fclose.rst index 5ecefa4abc3d..e84bbfcfa184 100644 --- a/Documentation/media/uapi/dvb/ca-fclose.rst +++ b/Documentation/media/uapi/dvb/ca-fclose.rst @@ -2,14 +2,14 @@ .. _ca_fclose: -============== -DVB CA close() -============== +===================== +Digital TV CA close() +===================== Name ---- -DVB CA close() +Digital TV CA close() Synopsis @@ -34,13 +34,10 @@ This system call closes a previously opened CA device. Return Value ------------ -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 +On success 0 is returned. +On error -1 is returned, and the ``errno`` variable is set +appropriately. - - .. row 1 - - - ``EBADF`` - - - fd is not a valid open file descriptor. +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-fopen.rst b/Documentation/media/uapi/dvb/ca-fopen.rst index 3d2819751446..056c71b53a70 100644 --- a/Documentation/media/uapi/dvb/ca-fopen.rst +++ b/Documentation/media/uapi/dvb/ca-fopen.rst @@ -2,14 +2,14 @@ .. _ca_fopen: -============= -DVB CA open() -============= +==================== +Digital TV CA open() +==================== Name ---- -DVB CA open() +Digital TV CA open() Synopsis @@ -23,25 +23,25 @@ Arguments --------- ``name`` - Name of specific DVB CA device. + Name of specific Digital TV CA device. ``flags`` A bit-wise OR of the following flags: +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| + .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - - - O_RDONLY + - - ``O_RDONLY`` - read-only access - - - - O_RDWR + - - ``O_RDWR`` - read/write access - - - - O_NONBLOCK + - - ``O_NONBLOCK`` - open in non-blocking mode (blocking mode is the default) @@ -49,50 +49,29 @@ Arguments Description ----------- -This system call opens a named ca device (e.g. /dev/ost/ca) for -subsequent use. +This system call opens a named ca device (e.g. ``/dev/dvb/adapter?/ca?``) +for subsequent use. -When an open() call has succeeded, the device will be ready for use. The +When an ``open()`` call has succeeded, the device will be ready for use. The significance of blocking or non-blocking mode is described in the documentation for functions where there is a difference. It does not -affect the semantics of the open() call itself. A device opened in +affect the semantics of the ``open()`` call itself. A device opened in blocking mode can later be put into non-blocking mode (and vice versa) -using the F_SETFL command of the fcntl system call. This is a standard -system call, documented in the Linux manual page for fcntl. Only one -user can open the CA Device in O_RDWR mode. All other attempts to open -the device in this mode will fail, and an error code will be returned. +using the ``F_SETFL`` command of the ``fcntl`` system call. This is a +standard system call, documented in the Linux manual page for fcntl. +Only one user can open the CA Device in ``O_RDWR`` mode. All other +attempts to open the device in this mode will fail, and an error code +will be returned. Return Value ------------ -.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 +On success 0 is returned. +On error -1 is returned, and the ``errno`` variable is set +appropriately. - - .. row 1 - - - ``ENODEV`` - - - Device driver not loaded/available. - - - .. row 2 - - - ``EINTERNAL`` - - - Internal error. - - - .. row 3 - - - ``EBUSY`` - - - Device or resource busy. - - - .. row 4 - - - ``EINVAL`` - - - Invalid argument. +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-cap.rst b/Documentation/media/uapi/dvb/ca-get-cap.rst index fbf7e359cb8a..d2d5c1355396 100644 --- a/Documentation/media/uapi/dvb/ca-get-cap.rst +++ b/Documentation/media/uapi/dvb/ca-get-cap.rst @@ -28,43 +28,19 @@ Arguments ``caps`` Pointer to struct :c:type:`ca_caps`. -.. c:type:: struct ca_caps - -.. flat-table:: struct ca_caps - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - unsigned int - - slot_num - - total number of CA card and module slots - - - - unsigned int - - slot_type - - bitmask with all supported slot types - - - - unsigned int - - descr_num - - total number of descrambler slots (keys) - - - - unsigned int - - descr_type - - bit mask with all supported descr types - - Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. - +Queries the Kernel for information about the available CA and descrambler +slots, and their types. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned and :c:type:`ca_caps` is filled. + +On error, -1 is returned and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-descr-info.rst b/Documentation/media/uapi/dvb/ca-get-descr-info.rst index 7bf327a3d0e3..e564fbb8d524 100644 --- a/Documentation/media/uapi/dvb/ca-get-descr-info.rst +++ b/Documentation/media/uapi/dvb/ca-get-descr-info.rst @@ -27,37 +27,16 @@ Arguments ``desc`` Pointer to struct :c:type:`ca_descr_info`. -.. c:type:: struct ca_descr_info - -.. flat-table:: struct ca_descr_info - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - - unsigned int - - num - - number of available descramblers (keys) - - - - unsigned int - - type - - type of supported scrambling system. Valid values are: - ``CA_ECD``, ``CA_NDS`` and ``CA_DSS``. - - Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. - +Returns information about all descrambler slots. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set +On success 0 is returned, and :c:type:`ca_descr_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set appropriately. The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-msg.rst b/Documentation/media/uapi/dvb/ca-get-msg.rst index 121588da3ef1..ceeda623ce93 100644 --- a/Documentation/media/uapi/dvb/ca-get-msg.rst +++ b/Documentation/media/uapi/dvb/ca-get-msg.rst @@ -28,47 +28,25 @@ Arguments ``msg`` Pointer to struct :c:type:`ca_msg`. - -.. c:type:: struct ca_msg - -.. flat-table:: struct ca_msg - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - unsigned int - - index - - - - - - - unsigned int - - type - - - - - - - unsigned int - - length - - - - - - - unsigned char - - msg[256] - - - - Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +Receives a message via a CI CA module. + +.. note:: + + Please notice that, on most drivers, this is done by reading from + the /dev/adapter?/ca? device node. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the + +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-get-slot-info.rst b/Documentation/media/uapi/dvb/ca-get-slot-info.rst index 54e5dc78a2dc..1a1d6f0c71b9 100644 --- a/Documentation/media/uapi/dvb/ca-get-slot-info.rst +++ b/Documentation/media/uapi/dvb/ca-get-slot-info.rst @@ -26,100 +26,32 @@ Arguments File descriptor returned by a previous call to :c:func:`open() `. ``info`` - Pointer to struct c:type:`ca_slot_info`. - -.. _ca_slot_info_type: - -.. flat-table:: ca_slot_info types - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - CA_CI - - 1 - - CI high level interface - - - - - CA_CI_LINK - - 2 - - CI link layer level interface - - - - - CA_CI_PHYS - - 4 - - CI physical layer level interface - - - - - CA_DESCR - - 8 - - built-in descrambler - - - - - CA_SC - - 128 - - simple smart card interface - -.. _ca_slot_info_flag: - -.. flat-table:: ca_slot_info flags - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - - CA_CI_MODULE_PRESENT - - 1 - - module (or card) inserted - - - - - CA_CI_MODULE_READY - - 2 - - - -.. c:type:: ca_slot_info - -.. flat-table:: struct ca_slot_info - :header-rows: 1 - :stub-columns: 0 - - - - - type - - name - - description - - - - - int - - num - - slot number - - - - - int - - type - - CA interface this slot supports, as defined at :ref:`ca_slot_info_type`. - - - - - unsigned int - - flags - - flags as defined at :ref:`ca_slot_info_flag`. - + Pointer to struct :c:type:`ca_slot_info`. Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +Returns information about a CA slot identified by +:c:type:`ca_slot_info`.slot_num. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned, and :c:type:`ca_slot_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 16 + + - - ``ENODEV`` + - the slot is not available. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-reset.rst b/Documentation/media/uapi/dvb/ca-reset.rst index 477313121a65..29788325f90e 100644 --- a/Documentation/media/uapi/dvb/ca-reset.rst +++ b/Documentation/media/uapi/dvb/ca-reset.rst @@ -28,12 +28,17 @@ Arguments Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +Puts the Conditional Access hardware on its initial state. It should +be called before start using the CA hardware. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-send-msg.rst b/Documentation/media/uapi/dvb/ca-send-msg.rst index 532ef5f9d6ac..9e91287b7bbc 100644 --- a/Documentation/media/uapi/dvb/ca-send-msg.rst +++ b/Documentation/media/uapi/dvb/ca-send-msg.rst @@ -32,12 +32,20 @@ Arguments Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +Sends a message via a CI CA module. +.. note:: + + Please notice that, on most drivers, this is done by writing + to the /dev/adapter?/ca? device node. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-set-descr.rst b/Documentation/media/uapi/dvb/ca-set-descr.rst index 70f7b3cf12ad..a6c47205ffd8 100644 --- a/Documentation/media/uapi/dvb/ca-set-descr.rst +++ b/Documentation/media/uapi/dvb/ca-set-descr.rst @@ -28,16 +28,19 @@ Arguments ``msg`` Pointer to struct :c:type:`ca_descr`. - Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. - +CA_SET_DESCR is used for feeding descrambler CA slots with descrambling +keys (refered as control words). Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca-set-pid.rst b/Documentation/media/uapi/dvb/ca-set-pid.rst deleted file mode 100644 index 891c1c72ef24..000000000000 --- a/Documentation/media/uapi/dvb/ca-set-pid.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _CA_SET_PID: - -========== -CA_SET_PID -========== - -Name ----- - -CA_SET_PID - - -Synopsis --------- - -.. c:function:: int ioctl(fd, CA_SET_PID, struct ca_pid *pid) - :name: CA_SET_PID - - -Arguments ---------- - -``fd`` - File descriptor returned by a previous call to :c:func:`open() `. - -``pid`` - Pointer to struct :c:type:`ca_pid`. - -.. c:type:: ca_pid - -.. flat-table:: struct ca_pid - :header-rows: 1 - :stub-columns: 0 - - - - - unsigned int - - pid - - Program ID - - - - - int - - index - - PID index. Use -1 to disable. - - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/ca.rst b/Documentation/media/uapi/dvb/ca.rst index 14b14abda1ae..deac72d89e93 100644 --- a/Documentation/media/uapi/dvb/ca.rst +++ b/Documentation/media/uapi/dvb/ca.rst @@ -2,14 +2,20 @@ .. _dvb_ca: -############# -DVB CA Device -############# -The DVB CA device controls the conditional access hardware. It can be -accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl +#################### +Digital TV CA Device +#################### + +The Digital TV CA device controls the conditional access hardware. It +can be accessed through ``/dev/dvb/adapter?/ca?``. Data types and and ioctl definitions can be accessed by including ``linux/dvb/ca.h`` in your application. +.. note:: + + There are three ioctls at this API that aren't documented: + :ref:`CA_GET_MSG`, :ref:`CA_SEND_MSG` and :ref:`CA_SET_DESCR`. + Documentation for them are welcome. .. toctree:: :maxdepth: 1 diff --git a/Documentation/media/uapi/dvb/ca_data_types.rst b/Documentation/media/uapi/dvb/ca_data_types.rst index d9e27c77426c..ac7cbd76ddd5 100644 --- a/Documentation/media/uapi/dvb/ca_data_types.rst +++ b/Documentation/media/uapi/dvb/ca_data_types.rst @@ -6,105 +6,4 @@ CA Data Types ************* - -.. c:type:: ca_slot_info - -ca_slot_info_t -============== - - -.. code-block:: c - - typedef struct ca_slot_info { - int num; /* slot number */ - - int type; /* CA interface this slot supports */ - #define CA_CI 1 /* CI high level interface */ - #define CA_CI_LINK 2 /* CI link layer level interface */ - #define CA_CI_PHYS 4 /* CI physical layer level interface */ - #define CA_DESCR 8 /* built-in descrambler */ - #define CA_SC 128 /* simple smart card interface */ - - unsigned int flags; - #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ - #define CA_CI_MODULE_READY 2 - } ca_slot_info_t; - - -.. c:type:: ca_descr_info - -ca_descr_info_t -=============== - - -.. code-block:: c - - typedef struct ca_descr_info { - unsigned int num; /* number of available descramblers (keys) */ - unsigned int type; /* type of supported scrambling system */ - #define CA_ECD 1 - #define CA_NDS 2 - #define CA_DSS 4 - } ca_descr_info_t; - - -.. c:type:: ca_caps - -ca_caps_t -========= - - -.. code-block:: c - - typedef struct ca_caps { - unsigned int slot_num; /* total number of CA card and module slots */ - unsigned int slot_type; /* OR of all supported types */ - unsigned int descr_num; /* total number of descrambler slots (keys) */ - unsigned int descr_type;/* OR of all supported types */ - } ca_cap_t; - - -.. c:type:: ca_msg - -ca_msg_t -======== - - -.. code-block:: c - - /* a message to/from a CI-CAM */ - typedef struct ca_msg { - unsigned int index; - unsigned int type; - unsigned int length; - unsigned char msg[256]; - } ca_msg_t; - - -.. c:type:: ca_descr - -ca_descr_t -========== - - -.. code-block:: c - - typedef struct ca_descr { - unsigned int index; - unsigned int parity; - unsigned char cw[8]; - } ca_descr_t; - - -.. c:type:: ca_pid - -ca-pid -====== - - -.. code-block:: c - - typedef struct ca_pid { - unsigned int pid; - int index; /* -1 == disable*/ - } ca_pid_t; +.. kernel-doc:: include/uapi/linux/dvb/ca.h diff --git a/Documentation/media/uapi/dvb/ca_function_calls.rst b/Documentation/media/uapi/dvb/ca_function_calls.rst index c085a0ebbc05..87d697851e82 100644 --- a/Documentation/media/uapi/dvb/ca_function_calls.rst +++ b/Documentation/media/uapi/dvb/ca_function_calls.rst @@ -18,4 +18,3 @@ CA Function Calls ca-get-msg ca-send-msg ca-set-descr - ca-set-pid diff --git a/Documentation/media/uapi/dvb/ca_h.rst b/Documentation/media/uapi/dvb/ca_h.rst deleted file mode 100644 index f513592ef529..000000000000 --- a/Documentation/media/uapi/dvb/ca_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _ca_h: - -********************************** -DVB Conditional Access Header File -********************************** - -.. kernel-include:: $BUILDDIR/ca.h.rst diff --git a/Documentation/media/uapi/dvb/demux.rst b/Documentation/media/uapi/dvb/demux.rst index b12b5a2dac94..45c3d6405c46 100644 --- a/Documentation/media/uapi/dvb/demux.rst +++ b/Documentation/media/uapi/dvb/demux.rst @@ -2,10 +2,15 @@ .. _dvb_demux: -################ -DVB Demux Device -################ -The DVB demux device controls the filters of the DVB hardware/software. +####################### +Digital TV Demux Device +####################### + +The Digital TV demux device controls the MPEG-TS filters for the +digital TV. If the driver and hardware supports, those filters are +implemented at the hardware. Otherwise, the Kernel provides a software +emulation. + It can be accessed through ``/dev/adapter?/demux?``. Data types and and ioctl definitions can be accessed by including ``linux/dvb/dmx.h`` in your application. diff --git a/Documentation/media/uapi/dvb/dmx-add-pid.rst b/Documentation/media/uapi/dvb/dmx-add-pid.rst index 689cd1fc9142..4d5632dfb43e 100644 --- a/Documentation/media/uapi/dvb/dmx-add-pid.rst +++ b/Documentation/media/uapi/dvb/dmx-add-pid.rst @@ -33,13 +33,17 @@ Description ----------- This ioctl call allows to add multiple PIDs to a transport stream filter -previously set up with DMX_SET_PES_FILTER and output equal to -DMX_OUT_TSDEMUX_TAP. +previously set up with :ref:`DMX_SET_PES_FILTER` and output equal to +:c:type:`DMX_OUT_TSDEMUX_TAP `. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fclose.rst b/Documentation/media/uapi/dvb/dmx-fclose.rst index ca93c23cde6d..578e929f4bde 100644 --- a/Documentation/media/uapi/dvb/dmx-fclose.rst +++ b/Documentation/media/uapi/dvb/dmx-fclose.rst @@ -2,14 +2,14 @@ .. _dmx_fclose: -================= -DVB demux close() -================= +======================== +Digital TV demux close() +======================== Name ---- -DVB demux close() +Digital TV demux close() Synopsis @@ -23,25 +23,23 @@ Arguments --------- ``fd`` - File descriptor returned by a previous call to :c:func:`open() `. + File descriptor returned by a previous call to + :c:func:`open() `. Description ----------- This system call deactivates and deallocates a filter that was -previously allocated via the open() call. +previously allocated via the :c:func:`open() ` call. Return Value ------------ -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 +On success 0 is returned. +On error, -1 is returned and the ``errno`` variable is set +appropriately. - - .. row 1 - - - ``EBADF`` - - - fd is not a valid open file descriptor. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fopen.rst b/Documentation/media/uapi/dvb/dmx-fopen.rst index a697e33c32ea..55628a18ba67 100644 --- a/Documentation/media/uapi/dvb/dmx-fopen.rst +++ b/Documentation/media/uapi/dvb/dmx-fopen.rst @@ -2,14 +2,14 @@ .. _dmx_fopen: -================ -DVB demux open() -================ +======================= +Digital TV demux open() +======================= Name ---- -DVB demux open() +Digital TV demux open() Synopsis @@ -22,25 +22,28 @@ Arguments --------- ``name`` - Name of specific DVB demux device. + Name of specific Digital TV demux device. ``flags`` A bit-wise OR of the following flags: +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| + .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - - O_RDONLY + - ``O_RDONLY`` - read-only access - - - O_RDWR + - ``O_RDWR`` - read/write access - - - O_NONBLOCK + - ``O_NONBLOCK`` - open in non-blocking mode (blocking mode is the default) @@ -48,52 +51,41 @@ Arguments Description ----------- -This system call, used with a device name of /dev/dvb/adapter0/demux0, +This system call, used with a device name of ``/dev/dvb/adapter?/demux?``, allocates a new filter and returns a handle which can be used for subsequent control of that filter. This call has to be made for each filter to be used, i.e. every returned file descriptor is a reference to -a single filter. /dev/dvb/adapter0/dvr0 is a logical device to be used +a single filter. ``/dev/dvb/adapter?/dvr?`` is a logical device to be used for retrieving Transport Streams for digital video recording. When reading from this device a transport stream containing the packets from all PES filters set in the corresponding demux device -(/dev/dvb/adapter0/demux0) having the output set to DMX_OUT_TS_TAP. A -recorded Transport Stream is replayed by writing to this device. +(``/dev/dvb/adapter?/demux?``) having the output set to ``DMX_OUT_TS_TAP``. +A recorded Transport Stream is replayed by writing to this device. The significance of blocking or non-blocking mode is described in the documentation for functions where there is a difference. It does not -affect the semantics of the open() call itself. A device opened in -blocking mode can later be put into non-blocking mode (and vice versa) -using the F_SETFL command of the fcntl system call. +affect the semantics of the ``open()`` call itself. A device opened +in blocking mode can later be put into non-blocking mode (and vice versa) +using the ``F_SETFL`` command of the fcntl system call. Return Value ------------ +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| + .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - - .. row 1 - - - ``ENODEV`` - - - Device driver not loaded/available. - - - .. row 2 - - - ``EINVAL`` - - - Invalid argument. - - - .. row 3 - - - ``EMFILE`` - + - - ``EMFILE`` - “Too many open files”, i.e. no more filters available. - - .. row 4 - - - ``ENOMEM`` - - - The driver failed to allocate enough memory. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fread.rst b/Documentation/media/uapi/dvb/dmx-fread.rst index e8c7f4db353f..488bdc4ba178 100644 --- a/Documentation/media/uapi/dvb/dmx-fread.rst +++ b/Documentation/media/uapi/dvb/dmx-fread.rst @@ -2,14 +2,14 @@ .. _dmx_fread: -================ -DVB demux read() -================ +======================= +Digital TV demux read() +======================= Name ---- -DVB demux read() +Digital TV demux read() Synopsis @@ -33,62 +33,48 @@ Arguments Description ----------- -This system call returns filtered data, which might be section or PES -data. The filtered data is transferred from the driver’s internal -circular buffer to buf. The maximum amount of data to be transferred is -implied by count. +This system call returns filtered data, which might be section or Packetized +Elementary Stream (PES) data. The filtered data is transferred from +the driver’s internal circular buffer to ``buf``. The maximum amount of data +to be transferred is implied by count. + +.. note:: + + if a section filter created with + :c:type:`DMX_CHECK_CRC ` flag set, + data that fails on CRC check will be silently ignored. + Return Value ------------ +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 + - - ``EWOULDBLOCK`` + - No data to return and ``O_NONBLOCK`` was specified. - - .. row 1 - - - ``EWOULDBLOCK`` - - - No data to return and O_NONBLOCK was specified. - - - .. row 2 - - - ``EBADF`` - - - fd is not a valid open file descriptor. - - - .. row 3 - - - ``ECRC`` - - - Last section had a CRC error - no data returned. The buffer is - flushed. - - - .. row 4 - - - ``EOVERFLOW`` - - - - - - .. row 5 - - - + - - ``EOVERFLOW`` - The filtered data was not read from the buffer in due time, resulting in non-read data being lost. The buffer is flushed. - - .. row 6 + - - ``ETIMEDOUT`` + - The section was not loaded within the stated timeout period. + See ioctl :ref:`DMX_SET_FILTER` for how to set a timeout. - - ``ETIMEDOUT`` + - - ``EFAULT`` + - The driver failed to write to the callers buffer due to an + invalid \*buf pointer. - - The section was not loaded within the stated timeout period. See - ioctl DMX_SET_FILTER for how to set a timeout. - - .. row 7 - - - ``EFAULT`` - - - The driver failed to write to the callers buffer due to an invalid - \*buf pointer. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-fwrite.rst b/Documentation/media/uapi/dvb/dmx-fwrite.rst index 8a90dfe28307..519e5733e53b 100644 --- a/Documentation/media/uapi/dvb/dmx-fwrite.rst +++ b/Documentation/media/uapi/dvb/dmx-fwrite.rst @@ -2,14 +2,14 @@ .. _dmx_fwrite: -================= -DVB demux write() -================= +======================== +Digital TV demux write() +======================== Name ---- -DVB demux write() +Digital TV demux write() Synopsis @@ -34,42 +34,39 @@ Description ----------- This system call is only provided by the logical device -/dev/dvb/adapter0/dvr0, associated with the physical demux device that +``/dev/dvb/adapter?/dvr?``, associated with the physical demux device that provides the actual DVR functionality. It is used for replay of a digitally recorded Transport Stream. Matching filters have to be defined -in the corresponding physical demux device, /dev/dvb/adapter0/demux0. +in the corresponding physical demux device, ``/dev/dvb/adapter?/demux?``. The amount of data to be transferred is implied by count. Return Value ------------ +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - - .. row 1 - - - ``EWOULDBLOCK`` - - - No data was written. This might happen if O_NONBLOCK was + - - ``EWOULDBLOCK`` + - No data was written. This might happen if ``O_NONBLOCK`` was specified and there is no more buffer space available (if - O_NONBLOCK is not specified the function will block until buffer + ``O_NONBLOCK`` is not specified the function will block until buffer space is available). - - .. row 2 - - - ``EBUSY`` - + - - ``EBUSY`` - This error code indicates that there are conflicting requests. The corresponding demux device is setup to receive data from the front- end. Make sure that these filters are stopped and that the - filters with input set to DMX_IN_DVR are started. + filters with input set to ``DMX_IN_DVR`` are started. - - .. row 3 - - - ``EBADF`` - - - fd is not a valid open file descriptor. +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-get-caps.rst b/Documentation/media/uapi/dvb/dmx-get-caps.rst deleted file mode 100644 index 145fb520d779..000000000000 --- a/Documentation/media/uapi/dvb/dmx-get-caps.rst +++ /dev/null @@ -1,41 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _DMX_GET_CAPS: - -============ -DMX_GET_CAPS -============ - -Name ----- - -DMX_GET_CAPS - - -Synopsis --------- - -.. c:function:: int ioctl(fd, DMX_GET_CAPS, struct dmx_caps *caps) - :name: DMX_GET_CAPS - -Arguments ---------- - -``fd`` - File descriptor returned by :c:func:`open() `. - -``caps`` - Pointer to struct :c:type:`dmx_caps` - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-get-event.rst b/Documentation/media/uapi/dvb/dmx-get-event.rst deleted file mode 100644 index 8be626c29158..000000000000 --- a/Documentation/media/uapi/dvb/dmx-get-event.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _DMX_GET_EVENT: - -============= -DMX_GET_EVENT -============= - -Name ----- - -DMX_GET_EVENT - - -Synopsis --------- - -.. c:function:: int ioctl( int fd, DMX_GET_EVENT, struct dmx_event *ev) - :name: DMX_GET_EVENT - - -Arguments ---------- - -``fd`` - File descriptor returned by :c:func:`open() `. - -``ev`` - Pointer to the location where the event is to be stored. - - -Description ------------ - -This ioctl call returns an event if available. If an event is not -available, the behavior depends on whether the device is in blocking or -non-blocking mode. In the latter case, the call fails immediately with -errno set to ``EWOULDBLOCK``. In the former case, the call blocks until an -event becomes available. - - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. - - - -.. flat-table:: - :header-rows: 0 - :stub-columns: 0 - - - - .. row 1 - - - ``EWOULDBLOCK`` - - - There is no event pending, and the device is in non-blocking mode. diff --git a/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst b/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst index b31634a1cca4..fbdbc12869d1 100644 --- a/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst +++ b/Documentation/media/uapi/dvb/dmx-get-pes-pids.rst @@ -25,18 +25,40 @@ Arguments File descriptor returned by :c:func:`open() `. ``pids`` - Undocumented. + Array used to store 5 Program IDs. Description ----------- -.. note:: This ioctl is undocumented. Documentation is welcome. +This ioctl allows to query a DVB device to return the first PID used +by audio, video, textext, subtitle and PCR programs on a given service. +They're stored as: + +======================= ======== ======================================= +PID element position content +======================= ======== ======================================= +pids[DMX_PES_AUDIO] 0 first audio PID +pids[DMX_PES_VIDEO] 1 first video PID +pids[DMX_PES_TELETEXT] 2 first teletext PID +pids[DMX_PES_SUBTITLE] 3 first subtitle PID +pids[DMX_PES_PCR] 4 first Program Clock Reference PID +======================= ======== ======================================= + + +.. note:: + + A value equal to 0xffff means that the PID was not filled by the + Kernel. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-get-stc.rst b/Documentation/media/uapi/dvb/dmx-get-stc.rst index 9fc501e8128a..604031f7904b 100644 --- a/Documentation/media/uapi/dvb/dmx-get-stc.rst +++ b/Documentation/media/uapi/dvb/dmx-get-stc.rst @@ -25,34 +25,42 @@ Arguments File descriptor returned by :c:func:`open() `. ``stc`` - Pointer to the location where the stc is to be stored. + Pointer to :c:type:`dmx_stc` where the stc data is to be stored. Description ----------- This ioctl call returns the current value of the system time counter -(which is driven by a PES filter of type DMX_PES_PCR). Some hardware -supports more than one STC, so you must specify which one by setting the -num field of stc before the ioctl (range 0...n). The result is returned -in form of a ratio with a 64 bit numerator and a 32 bit denominator, so -the real 90kHz STC value is stc->stc / stc->base . +(which is driven by a PES filter of type :c:type:`DMX_PES_PCR `). +Some hardware supports more than one STC, so you must specify which one by +setting the :c:type:`num ` field of stc before the ioctl (range 0...n). +The result is returned in form of a ratio with a 64 bit numerator +and a 32 bit denominator, so the real 90kHz STC value is +``stc->stc / stc->base``. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 - + :widths: 1 16 - .. row 1 - ``EINVAL`` - Invalid stc number. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-remove-pid.rst b/Documentation/media/uapi/dvb/dmx-remove-pid.rst index e411495c619c..456cc2ded2c0 100644 --- a/Documentation/media/uapi/dvb/dmx-remove-pid.rst +++ b/Documentation/media/uapi/dvb/dmx-remove-pid.rst @@ -34,13 +34,17 @@ Description This ioctl call allows to remove a PID when multiple PIDs are set on a transport stream filter, e. g. a filter previously set up with output -equal to DMX_OUT_TSDEMUX_TAP, created via either -DMX_SET_PES_FILTER or DMX_ADD_PID. +equal to :c:type:`DMX_OUT_TSDEMUX_TAP `, created via either +:ref:`DMX_SET_PES_FILTER` or :ref:`DMX_ADD_PID`. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst b/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst index f2f7379f29ed..74fd076a9b90 100644 --- a/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst +++ b/Documentation/media/uapi/dvb/dmx-set-buffer-size.rst @@ -33,13 +33,18 @@ Description This ioctl call is used to set the size of the circular buffer used for filtered data. The default size is two maximum sized sections, i.e. if -this function is not called a buffer size of 2 \* 4096 bytes will be +this function is not called a buffer size of ``2 * 4096`` bytes will be used. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the + +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-filter.rst b/Documentation/media/uapi/dvb/dmx-set-filter.rst index 1d50c803d69a..88594b8d3846 100644 --- a/Documentation/media/uapi/dvb/dmx-set-filter.rst +++ b/Documentation/media/uapi/dvb/dmx-set-filter.rst @@ -40,13 +40,18 @@ state whether a section should be CRC-checked, whether the filter should be a ”one-shot” filter, i.e. if the filtering operation should be stopped after the first section is received, and whether the filtering operation should be started immediately (without waiting for a -DMX_START ioctl call). If a filter was previously set-up, this filter -will be canceled, and the receive buffer will be flushed. +:ref:`DMX_START` ioctl call). If a filter was previously set-up, this +filter will be canceled, and the receive buffer will be flushed. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the + +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst b/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst index 145451d04f7d..d70e7bf96a41 100644 --- a/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst +++ b/Documentation/media/uapi/dvb/dmx-set-pes-filter.rst @@ -42,15 +42,17 @@ capability is supported. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 + :widths: 1 16 - .. row 1 @@ -61,3 +63,7 @@ appropriately. The generic error codes are described at the There are active filters filtering data from another input source. Make sure that these filters are stopped before starting this filter. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-set-source.rst b/Documentation/media/uapi/dvb/dmx-set-source.rst deleted file mode 100644 index ac7f77b25e06..000000000000 --- a/Documentation/media/uapi/dvb/dmx-set-source.rst +++ /dev/null @@ -1,44 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _DMX_SET_SOURCE: - -============== -DMX_SET_SOURCE -============== - -Name ----- - -DMX_SET_SOURCE - - -Synopsis --------- - -.. c:function:: int ioctl(fd, DMX_SET_SOURCE, struct dmx_source *src) - :name: DMX_SET_SOURCE - - -Arguments ---------- - - -``fd`` - File descriptor returned by :c:func:`open() `. - -``src`` - Undocumented. - - -Description ------------ - -.. note:: This ioctl is undocumented. Documentation is welcome. - - -Return Value ------------- - -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-start.rst b/Documentation/media/uapi/dvb/dmx-start.rst index 641f3e017fb1..36700e775296 100644 --- a/Documentation/media/uapi/dvb/dmx-start.rst +++ b/Documentation/media/uapi/dvb/dmx-start.rst @@ -29,15 +29,16 @@ Description ----------- This ioctl call is used to start the actual filtering operation defined -via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER. +via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER`. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. tabularcolumns:: |p{2.5cm}|p{15.0cm}| @@ -51,7 +52,7 @@ appropriately. The generic error codes are described at the - ``EINVAL`` - Invalid argument, i.e. no filtering parameters provided via the - DMX_SET_FILTER or DMX_SET_PES_FILTER functions. + :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` ioctls. - .. row 2 @@ -61,3 +62,7 @@ appropriately. The generic error codes are described at the There are active filters filtering data from another input source. Make sure that these filters are stopped before starting this filter. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx-stop.rst b/Documentation/media/uapi/dvb/dmx-stop.rst index 569a3df44923..6d9c927bcd5f 100644 --- a/Documentation/media/uapi/dvb/dmx-stop.rst +++ b/Documentation/media/uapi/dvb/dmx-stop.rst @@ -29,13 +29,17 @@ Description ----------- This ioctl call is used to stop the actual filtering operation defined -via the ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and -started via the DMX_START command. +via the ioctl calls :ref:`DMX_SET_FILTER` or :ref:`DMX_SET_PES_FILTER` and +started via the :ref:`DMX_START` command. Return Value ------------ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/dmx_fcalls.rst b/Documentation/media/uapi/dvb/dmx_fcalls.rst index 77a1554d9834..a17289143220 100644 --- a/Documentation/media/uapi/dvb/dmx_fcalls.rst +++ b/Documentation/media/uapi/dvb/dmx_fcalls.rst @@ -18,10 +18,7 @@ Demux Function Calls dmx-set-filter dmx-set-pes-filter dmx-set-buffer-size - dmx-get-event dmx-get-stc dmx-get-pes-pids - dmx-get-caps - dmx-set-source dmx-add-pid dmx-remove-pid diff --git a/Documentation/media/uapi/dvb/dmx_h.rst b/Documentation/media/uapi/dvb/dmx_h.rst deleted file mode 100644 index 4fd1704a0833..000000000000 --- a/Documentation/media/uapi/dvb/dmx_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _dmx_h: - -********************* -DVB Demux Header File -********************* - -.. kernel-include:: $BUILDDIR/dmx.h.rst diff --git a/Documentation/media/uapi/dvb/dmx_types.rst b/Documentation/media/uapi/dvb/dmx_types.rst index 80dd659860d7..2a023a4f516c 100644 --- a/Documentation/media/uapi/dvb/dmx_types.rst +++ b/Documentation/media/uapi/dvb/dmx_types.rst @@ -6,227 +6,4 @@ Demux Data Types **************** -Output for the demux -==================== - -.. c:type:: dmx_output - -.. tabularcolumns:: |p{5.0cm}|p{12.5cm}| - -.. flat-table:: enum dmx_output - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _DMX-OUT-DECODER: - - DMX_OUT_DECODER - - - Streaming directly to decoder. - - - .. row 3 - - - .. _DMX-OUT-TAP: - - DMX_OUT_TAP - - - Output going to a memory buffer (to be retrieved via the read - command). Delivers the stream output to the demux device on which - the ioctl is called. - - - .. row 4 - - - .. _DMX-OUT-TS-TAP: - - DMX_OUT_TS_TAP - - - Output multiplexed into a new TS (to be retrieved by reading from - the logical DVR device). Routes output to the logical DVR device - ``/dev/dvb/adapter?/dvr?``, which delivers a TS multiplexed from - all filters for which ``DMX_OUT_TS_TAP`` was specified. - - - .. row 5 - - - .. _DMX-OUT-TSDEMUX-TAP: - - DMX_OUT_TSDEMUX_TAP - - - Like :ref:`DMX_OUT_TS_TAP ` but retrieved - from the DMX device. - - -dmx_input_t -=========== - -.. c:type:: dmx_input - -.. code-block:: c - - typedef enum - { - DMX_IN_FRONTEND, /* Input from a front-end device. */ - DMX_IN_DVR /* Input from the logical DVR device. */ - } dmx_input_t; - - -dmx_pes_type_t -============== - -.. c:type:: dmx_pes_type - - -.. code-block:: c - - typedef enum - { - DMX_PES_AUDIO0, - DMX_PES_VIDEO0, - DMX_PES_TELETEXT0, - DMX_PES_SUBTITLE0, - DMX_PES_PCR0, - - DMX_PES_AUDIO1, - DMX_PES_VIDEO1, - DMX_PES_TELETEXT1, - DMX_PES_SUBTITLE1, - DMX_PES_PCR1, - - DMX_PES_AUDIO2, - DMX_PES_VIDEO2, - DMX_PES_TELETEXT2, - DMX_PES_SUBTITLE2, - DMX_PES_PCR2, - - DMX_PES_AUDIO3, - DMX_PES_VIDEO3, - DMX_PES_TELETEXT3, - DMX_PES_SUBTITLE3, - DMX_PES_PCR3, - - DMX_PES_OTHER - } dmx_pes_type_t; - - -struct dmx_filter -================= - -.. c:type:: dmx_filter - -.. code-block:: c - - typedef struct dmx_filter - { - __u8 filter[DMX_FILTER_SIZE]; - __u8 mask[DMX_FILTER_SIZE]; - __u8 mode[DMX_FILTER_SIZE]; - } dmx_filter_t; - - -.. c:type:: dmx_sct_filter_params - -struct dmx_sct_filter_params -============================ - - -.. code-block:: c - - struct dmx_sct_filter_params - { - __u16 pid; - dmx_filter_t filter; - __u32 timeout; - __u32 flags; - #define DMX_CHECK_CRC 1 - #define DMX_ONESHOT 2 - #define DMX_IMMEDIATE_START 4 - #define DMX_KERNEL_CLIENT 0x8000 - }; - - -struct dmx_pes_filter_params -============================ - -.. c:type:: dmx_pes_filter_params - -.. code-block:: c - - struct dmx_pes_filter_params - { - __u16 pid; - dmx_input_t input; - dmx_output_t output; - dmx_pes_type_t pes_type; - __u32 flags; - }; - - -struct dmx_event -================ - -.. c:type:: dmx_event - -.. code-block:: c - - struct dmx_event - { - dmx_event_t event; - time_t timeStamp; - union - { - dmx_scrambling_status_t scrambling; - } u; - }; - - -struct dmx_stc -============== - -.. c:type:: dmx_stc - -.. code-block:: c - - struct dmx_stc { - unsigned int num; /* input : which STC? 0..N */ - unsigned int base; /* output: divisor for stc to get 90 kHz clock */ - __u64 stc; /* output: stc in 'base'*90 kHz units */ - }; - - -struct dmx_caps -=============== - -.. c:type:: dmx_caps - -.. code-block:: c - - typedef struct dmx_caps { - __u32 caps; - int num_decoders; - } dmx_caps_t; - - -enum dmx_source -=============== - -.. c:type:: dmx_source - -.. code-block:: c - - typedef enum dmx_source { - DMX_SOURCE_FRONT0 = 0, - DMX_SOURCE_FRONT1, - DMX_SOURCE_FRONT2, - DMX_SOURCE_FRONT3, - DMX_SOURCE_DVR0 = 16, - DMX_SOURCE_DVR1, - DMX_SOURCE_DVR2, - DMX_SOURCE_DVR3 - } dmx_source_t; +.. kernel-doc:: include/uapi/linux/dvb/dmx.h diff --git a/Documentation/media/uapi/dvb/dtv-fe-stats.rst b/Documentation/media/uapi/dvb/dtv-fe-stats.rst deleted file mode 100644 index e8a02a1f138d..000000000000 --- a/Documentation/media/uapi/dvb/dtv-fe-stats.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_fe_stats - -******************* -struct dtv_fe_stats -******************* - - -.. code-block:: c - - #define MAX_DTV_STATS 4 - - struct dtv_fe_stats { - __u8 len; - struct dtv_stats stat[MAX_DTV_STATS]; - } __packed; diff --git a/Documentation/media/uapi/dvb/dtv-properties.rst b/Documentation/media/uapi/dvb/dtv-properties.rst deleted file mode 100644 index 48c4e834ad11..000000000000 --- a/Documentation/media/uapi/dvb/dtv-properties.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_properties - -********************* -struct dtv_properties -********************* - - -.. code-block:: c - - struct dtv_properties { - __u32 num; - struct dtv_property *props; - }; diff --git a/Documentation/media/uapi/dvb/dtv-property.rst b/Documentation/media/uapi/dvb/dtv-property.rst deleted file mode 100644 index 3ddc3474b00e..000000000000 --- a/Documentation/media/uapi/dvb/dtv-property.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_property - -******************* -struct dtv_property -******************* - - -.. code-block:: c - - /* Reserved fields should be set to 0 */ - - struct dtv_property { - __u32 cmd; - __u32 reserved[3]; - union { - __u32 data; - struct dtv_fe_stats st; - struct { - __u8 data[32]; - __u32 len; - __u32 reserved1[3]; - void *reserved2; - } buffer; - } u; - int result; - } __attribute__ ((packed)); - - /* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */ - #define DTV_IOCTL_MAX_MSGS 64 diff --git a/Documentation/media/uapi/dvb/dtv-stats.rst b/Documentation/media/uapi/dvb/dtv-stats.rst deleted file mode 100644 index 35239e72bf74..000000000000 --- a/Documentation/media/uapi/dvb/dtv-stats.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. c:type:: dtv_stats - -**************** -struct dtv_stats -**************** - - -.. code-block:: c - - struct dtv_stats { - __u8 scale; /* enum fecap_scale_params type */ - union { - __u64 uvalue; /* for counters and relative scales */ - __s64 svalue; /* for 1/1000 dB measures */ - }; - } __packed; diff --git a/Documentation/media/uapi/dvb/dvb-fe-read-status.rst b/Documentation/media/uapi/dvb/dvb-fe-read-status.rst index 76c20612b274..212f032cad8b 100644 --- a/Documentation/media/uapi/dvb/dvb-fe-read-status.rst +++ b/Documentation/media/uapi/dvb/dvb-fe-read-status.rst @@ -20,6 +20,6 @@ Signal statistics are provided via .. note:: Most statistics require the demodulator to be fully locked - (e. g. with FE_HAS_LOCK bit set). See + (e. g. with :c:type:`FE_HAS_LOCK ` bit set). See :ref:`Frontend statistics indicators ` for more details. diff --git a/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst b/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst index 899fd5c3545e..b152166f8fa7 100644 --- a/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst +++ b/Documentation/media/uapi/dvb/dvb-frontend-parameters.rst @@ -24,7 +24,7 @@ instead, in order to be able to support the newer System Delivery like DVB-S2, DVB-T2, DVB-C2, ISDB, etc. All kinds of parameters are combined as a union in the -FrontendParameters structure: +``dvb_frontend_parameters`` structure: .. code-block:: c diff --git a/Documentation/media/uapi/dvb/dvbapi.rst b/Documentation/media/uapi/dvb/dvbapi.rst index 37680137e3f2..18c86b3a3af1 100644 --- a/Documentation/media/uapi/dvb/dvbapi.rst +++ b/Documentation/media/uapi/dvb/dvbapi.rst @@ -10,12 +10,27 @@ Part II - Digital TV API .. note:: - This API is also known as **DVB API**, although it is generic - enough to support all digital TV standards. + This API is also known as Linux **DVB API**. + + It it was originally written to support the European digital TV + standard (DVB), and later extended to support all digital TV standards. + + In order to avoid confusion, within this document, it was opted to refer to + it, and to associated hardware as **Digital TV**. + + The word **DVB** is reserved to be used for: + + - the Digital TV API version + (e. g. DVB API version 3 or DVB API version 5); + - digital TV data types (enums, structs, defines, etc); + - digital TV device nodes (``/dev/dvb/...``); + - the European DVB standard. **Version 5.10** -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents @@ -30,12 +45,7 @@ Part II - Digital TV API net legacy_dvb_apis examples - audio_h - ca_h - dmx_h - frontend_h - net_h - video_h + headers ********************** @@ -46,11 +56,11 @@ Authors: - J. K. Metzler, Ralph - - Original author of the DVB API documentation. + - Original author of the Digital TV API documentation. - O. C. Metzler, Marcus - - Original author of the DVB API documentation. + - Original author of the Digital TV API documentation. - Carvalho Chehab, Mauro @@ -58,21 +68,26 @@ Authors: **Copyright** |copy| 2002-2003 : Convergence GmbH -**Copyright** |copy| 2009-2016 : Mauro Carvalho Chehab +**Copyright** |copy| 2009-2017 : Mauro Carvalho Chehab **************** Revision History **************** +:revision: 2.2.0 / 2017-09-01 (*mcc*) + +Most gaps between the uAPI document and the Kernel implementation +got fixed for the non-legacy API. + :revision: 2.1.0 / 2015-05-29 (*mcc*) DocBook improvements and cleanups, in order to document the system calls on a more standard way and provide more description about the current -DVB API. +Digital TV API. :revision: 2.0.4 / 2011-05-06 (*mcc*) -Add more information about DVB APIv5, better describing the frontend +Add more information about DVBv5 API, better describing the frontend GET/SET props ioctl's. diff --git a/Documentation/media/uapi/dvb/dvbproperty-006.rst b/Documentation/media/uapi/dvb/dvbproperty-006.rst deleted file mode 100644 index 3343a0f306fe..000000000000 --- a/Documentation/media/uapi/dvb/dvbproperty-006.rst +++ /dev/null @@ -1,12 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -************** -Property types -************** - -On :ref:`FE_GET_PROPERTY and FE_SET_PROPERTY `, -the actual action is determined by the dtv_property cmd/data pairs. -With one single ioctl, is possible to get/set up to 64 properties. The -actual meaning of each property is described on the next sections. - -The available frontend property types are shown on the next section. diff --git a/Documentation/media/uapi/dvb/dvbproperty.rst b/Documentation/media/uapi/dvb/dvbproperty.rst index dd2d71ce43fa..1a56c1724e59 100644 --- a/Documentation/media/uapi/dvb/dvbproperty.rst +++ b/Documentation/media/uapi/dvb/dvbproperty.rst @@ -2,63 +2,76 @@ .. _frontend-properties: -DVB Frontend properties -======================= +************** +Property types +************** Tuning into a Digital TV physical channel and starting decoding it requires changing a set of parameters, in order to control the tuner, the demodulator, the Linear Low-noise Amplifier (LNA) and to set the -antenna subsystem via Satellite Equipment Control (SEC), on satellite -systems. The actual parameters are specific to each particular digital +antenna subsystem via Satellite Equipment Control - SEC (on satellite +systems). The actual parameters are specific to each particular digital TV standards, and may change as the digital TV specs evolves. -In the past, the strategy used was to have a union with the parameters -needed to tune for DVB-S, DVB-C, DVB-T and ATSC delivery systems grouped -there. The problem is that, as the second generation standards appeared, -those structs were not big enough to contain the additional parameters. -Also, the union didn't have any space left to be expanded without -breaking userspace. So, the decision was to deprecate the legacy -union/struct based approach, in favor of a properties set approach. +In the past (up to DVB API version 3 - DVBv3), the strategy used was to have a +union with the parameters needed to tune for DVB-S, DVB-C, DVB-T and +ATSC delivery systems grouped there. The problem is that, as the second +generation standards appeared, the size of such union was not big +enough to group the structs that would be required for those new +standards. Also, extending it would break userspace. + +So, the legacy union/struct based approach was deprecated, in favor +of a properties set approach. On such approach, +:ref:`FE_GET_PROPERTY and FE_SET_PROPERTY ` are used +to setup the frontend and read its status. + +The actual action is determined by a set of dtv_property cmd/data pairs. +With one single ioctl, is possible to get/set up to 64 properties. + +This section describes the new and recommended way to set the frontend, +with supports all digital TV delivery systems. .. note:: - On Linux DVB API version 3, setting a frontend were done via - struct :c:type:`dvb_frontend_parameters`. - This got replaced on version 5 (also called "S2API", as this API were - added originally_enabled to provide support for DVB-S2), because the - old API has a very limited support to new standards and new hardware. - This section describes the new and recommended way to set the frontend, - with suppports all digital TV delivery systems. + 1. On Linux DVB API version 3, setting a frontend was done via + struct :c:type:`dvb_frontend_parameters`. -Example: with the properties based approach, in order to set the tuner -to a DVB-C channel at 651 kHz, modulated with 256-QAM, FEC 3/4 and -symbol rate of 5.217 Mbauds, those properties should be sent to + 2. Don't use DVB API version 3 calls on hardware with supports + newer standards. Such API provides no suport or a very limited + support to new standards and/or new hardware. + + 3. Nowadays, most frontends support multiple delivery systems. + Only with DVB API version 5 calls it is possible to switch between + the multiple delivery systems supported by a frontend. + + 4. DVB API version 5 is also called *S2API*, as the first + new standard added to it was DVB-S2. + +**Example**: in order to set the hardware to tune into a DVB-C channel +at 651 kHz, modulated with 256-QAM, FEC 3/4 and symbol rate of 5.217 +Mbauds, those properties should be sent to :ref:`FE_SET_PROPERTY ` ioctl: -- :ref:`DTV_DELIVERY_SYSTEM ` = - SYS_DVBC_ANNEX_A + :ref:`DTV_DELIVERY_SYSTEM ` = SYS_DVBC_ANNEX_A -- :ref:`DTV_FREQUENCY ` = 651000000 + :ref:`DTV_FREQUENCY ` = 651000000 -- :ref:`DTV_MODULATION ` = QAM_256 + :ref:`DTV_MODULATION ` = QAM_256 -- :ref:`DTV_INVERSION ` = INVERSION_AUTO + :ref:`DTV_INVERSION ` = INVERSION_AUTO -- :ref:`DTV_SYMBOL_RATE ` = 5217000 + :ref:`DTV_SYMBOL_RATE ` = 5217000 -- :ref:`DTV_INNER_FEC ` = FEC_3_4 + :ref:`DTV_INNER_FEC ` = FEC_3_4 -- :ref:`DTV_TUNE ` + :ref:`DTV_TUNE ` The code that would that would do the above is show in :ref:`dtv-prop-example`. -.. _dtv-prop-example: - -Example: Setting digital TV frontend properties -=============================================== - .. code-block:: c + :caption: Example: Setting digital TV frontend properties + :name: dtv-prop-example #include #include @@ -102,17 +115,12 @@ Example: Setting digital TV frontend properties provides methods for usual operations like program scanning and to read/write channel descriptor files. - .. toctree:: :maxdepth: 1 - dtv-stats - dtv-fe-stats - dtv-property - dtv-properties - dvbproperty-006 fe_property_parameters frontend-stat-properties frontend-property-terrestrial-systems frontend-property-cable-systems frontend-property-satellite-systems + frontend-header diff --git a/Documentation/media/uapi/dvb/dvbstb.svg b/Documentation/media/uapi/dvb/dvbstb.svg index 4effe45b448d..f6fe2f837373 100644 --- a/Documentation/media/uapi/dvb/dvbstb.svg +++ b/Documentation/media/uapi/dvb/dvbstb.svg @@ -1,17 +1,16 @@ -image/svg+xmlAntena -Frontend -CA -Demux -SEC -Audio -Video -TV - +image/svg+xmlAntena +Frontend +CA +Demux +SEC +Audio +Video +TV +Decoder +Decoder + diff --git a/Documentation/media/uapi/dvb/examples.rst b/Documentation/media/uapi/dvb/examples.rst index 1a94966312c0..e0f627ca2e4d 100644 --- a/Documentation/media/uapi/dvb/examples.rst +++ b/Documentation/media/uapi/dvb/examples.rst @@ -6,8 +6,8 @@ Examples ******** -In this section we would like to present some examples for using the DVB -API. +In this section we would like to present some examples for using the Digital +TV API. .. note:: diff --git a/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst b/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst index 302db2857f90..f220ee351e15 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-recv-slave-reply.rst @@ -26,8 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - pointer to struct - :c:type:`dvb_diseqc_slave_reply` + pointer to struct :c:type:`dvb_diseqc_slave_reply`. Description @@ -35,46 +34,15 @@ Description Receives reply from a DiSEqC 2.0 command. -.. c:type:: dvb_diseqc_slave_reply - -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| - -.. flat-table:: struct dvb_diseqc_slave_reply - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - - - .. row 1 - - - uint8_t - - - msg[4] - - - DiSEqC message (framing, data[3]) - - - .. row 2 - - - uint8_t - - - msg_len - - - Length of the DiSEqC message. Valid values are 0 to 4, where 0 - means no msg - - - .. row 3 - - - int - - - timeout - - - Return from ioctl after timeout ms with errorcode when no message - was received - +The received message is stored at the buffer pointed by ``argp``. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst b/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst index 75116f283faf..78476c1c7bf5 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-reset-overload.rst @@ -31,12 +31,16 @@ Description If the bus has been automatically powered off due to power overload, this ioctl call restores the power to the bus. The call requires read/write access to the device. This call has no effect if the device -is manually powered off. Not all DVB adapters support this ioctl. +is manually powered off. Not all Digital TV adapters support this ioctl. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst b/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst index e962f6ec5aaf..a7e05914efae 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-send-burst.rst @@ -26,7 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``tone`` - an integer enumered value described at :c:type:`fe_sec_mini_cmd` + An integer enumered value described at :c:type:`fe_sec_mini_cmd`. Description @@ -39,39 +39,14 @@ read/write permissions. It provides support for what's specified at `Digital Satellite Equipment Control (DiSEqC) - Simple "ToneBurst" Detection Circuit specification. `__ -.. c:type:: fe_sec_mini_cmd - -.. flat-table:: enum fe_sec_mini_cmd - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _SEC-MINI-A: - - ``SEC_MINI_A`` - - - Sends a mini-DiSEqC 22kHz '0' Tone Burst to select satellite-A - - - .. row 3 - - - .. _SEC-MINI-B: - - ``SEC_MINI_B`` - - - Sends a mini-DiSEqC 22kHz '1' Data Burst to select satellite-B - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst b/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst index bbcab3df39b5..6bd3994edfc2 100644 --- a/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst +++ b/Documentation/media/uapi/dvb/fe-diseqc-send-master-cmd.rst @@ -33,39 +33,17 @@ Arguments Description =========== -Sends a DiSEqC command to the antenna subsystem. - - -.. c:type:: dvb_diseqc_master_cmd - -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| - -.. flat-table:: struct dvb_diseqc_master_cmd - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - - - .. row 1 - - - uint8_t - - - msg[6] - - - DiSEqC message (framing, address, command, data[3]) - - - .. row 2 - - - uint8_t - - - msg_len - - - Length of the DiSEqC message. Valid values are 3 to 6 +Sends the DiSEqC command pointed by :c:type:`dvb_diseqc_master_cmd` +to the antenna subsystem. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst b/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst index f41371f12456..dcf2d20d460f 100644 --- a/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst +++ b/Documentation/media/uapi/dvb/fe-dishnetwork-send-legacy-cmd.rst @@ -46,6 +46,10 @@ dishes were already legacy in 2004. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst b/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst index bacafbc462d2..b20cb360fe37 100644 --- a/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst +++ b/Documentation/media/uapi/dvb/fe-enable-high-lnb-voltage.rst @@ -45,6 +45,10 @@ voltages. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-event.rst b/Documentation/media/uapi/dvb/fe-get-event.rst index 8a719c33073d..505db94bf183 100644 --- a/Documentation/media/uapi/dvb/fe-get-event.rst +++ b/Documentation/media/uapi/dvb/fe-get-event.rst @@ -44,10 +44,10 @@ an event becomes available. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. flat-table:: @@ -66,3 +66,6 @@ appropriately. The generic error codes are described at the - ``EOVERFLOW`` - Overflow in event queue - one or more events were lost. + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-frontend.rst b/Documentation/media/uapi/dvb/fe-get-frontend.rst index d53a3f8237c3..5db552cedd70 100644 --- a/Documentation/media/uapi/dvb/fe-get-frontend.rst +++ b/Documentation/media/uapi/dvb/fe-get-frontend.rst @@ -42,11 +42,10 @@ this command, read-only access to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. - +On success 0 is returned. +On error -1 is returned, and the ``errno`` variable is set +appropriately. .. flat-table:: :header-rows: 0 @@ -58,3 +57,6 @@ appropriately. The generic error codes are described at the - ``EINVAL`` - Maximum supported symbol rate reached. + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-info.rst b/Documentation/media/uapi/dvb/fe-get-info.rst index e3d64b251f61..49307c0abfee 100644 --- a/Documentation/media/uapi/dvb/fe-get-info.rst +++ b/Documentation/media/uapi/dvb/fe-get-info.rst @@ -9,7 +9,8 @@ ioctl FE_GET_INFO Name ==== -FE_GET_INFO - Query DVB frontend capabilities and returns information about the - front-end. This call only requires read-only access to the device +FE_GET_INFO - Query Digital TV frontend capabilities and returns information +about the - front-end. This call only requires read-only access to the device. Synopsis @@ -33,119 +34,13 @@ Arguments Description =========== -All DVB frontend devices support the ``FE_GET_INFO`` ioctl. It is used -to identify kernel devices compatible with this specification and to +All Digital TV frontend devices support the :ref:`FE_GET_INFO` ioctl. It is +used to identify kernel devices compatible with this specification and to obtain information about driver and hardware capabilities. The ioctl takes a pointer to dvb_frontend_info which is filled by the driver. When the driver is not compatible with this specification the ioctl returns an error. -.. c:type:: dvb_frontend_info - -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| - -.. flat-table:: struct dvb_frontend_info - :header-rows: 0 - :stub-columns: 0 - :widths: 1 1 2 - - - - .. row 1 - - - char - - - name[128] - - - Name of the frontend - - - .. row 2 - - - fe_type_t - - - type - - - **DEPRECATED**. DVBv3 type. Should not be used on modern programs, - as a frontend may have more than one type. So, the DVBv5 API - should be used instead to enumerate and select the frontend type. - - - .. row 3 - - - uint32_t - - - frequency_min - - - Minimal frequency supported by the frontend - - - .. row 4 - - - uint32_t - - - frequency_max - - - Maximal frequency supported by the frontend - - - .. row 5 - - - uint32_t - - - frequency_stepsize - - - Frequency step - all frequencies are multiple of this value - - - .. row 6 - - - uint32_t - - - frequency_tolerance - - - Tolerance of the frequency - - - .. row 7 - - - uint32_t - - - symbol_rate_min - - - Minimal symbol rate (for Cable/Satellite systems), in bauds - - - .. row 8 - - - uint32_t - - - symbol_rate_max - - - Maximal symbol rate (for Cable/Satellite systems), in bauds - - - .. row 9 - - - uint32_t - - - symbol_rate_tolerance - - - Maximal symbol rate tolerance, in ppm - - - .. row 10 - - - uint32_t - - - notifier_delay - - - **DEPRECATED**. Not used by any driver. - - - .. row 11 - - - enum :c:type:`fe_caps` - - - caps - - - Capabilities supported by the frontend - - -.. note:: - - The frequencies are specified in Hz for Terrestrial and Cable - systems. They're specified in kHz for Satellite systems - frontend capabilities ===================== @@ -153,274 +48,16 @@ frontend capabilities Capabilities describe what a frontend can do. Some capabilities are supported only on some specific frontend types. -.. c:type:: fe_caps - -.. tabularcolumns:: |p{6.5cm}|p{11.0cm}| - -.. flat-table:: enum fe_caps - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _FE-IS-STUPID: - - ``FE_IS_STUPID`` - - - There's something wrong at the frontend, and it can't report its - capabilities - - - .. row 3 - - - .. _FE-CAN-INVERSION-AUTO: - - ``FE_CAN_INVERSION_AUTO`` - - - The frontend is capable of auto-detecting inversion - - - .. row 4 - - - .. _FE-CAN-FEC-1-2: - - ``FE_CAN_FEC_1_2`` - - - The frontend supports FEC 1/2 - - - .. row 5 - - - .. _FE-CAN-FEC-2-3: - - ``FE_CAN_FEC_2_3`` - - - The frontend supports FEC 2/3 - - - .. row 6 - - - .. _FE-CAN-FEC-3-4: - - ``FE_CAN_FEC_3_4`` - - - The frontend supports FEC 3/4 - - - .. row 7 - - - .. _FE-CAN-FEC-4-5: - - ``FE_CAN_FEC_4_5`` - - - The frontend supports FEC 4/5 - - - .. row 8 - - - .. _FE-CAN-FEC-5-6: - - ``FE_CAN_FEC_5_6`` - - - The frontend supports FEC 5/6 - - - .. row 9 - - - .. _FE-CAN-FEC-6-7: - - ``FE_CAN_FEC_6_7`` - - - The frontend supports FEC 6/7 - - - .. row 10 - - - .. _FE-CAN-FEC-7-8: - - ``FE_CAN_FEC_7_8`` - - - The frontend supports FEC 7/8 - - - .. row 11 - - - .. _FE-CAN-FEC-8-9: - - ``FE_CAN_FEC_8_9`` - - - The frontend supports FEC 8/9 - - - .. row 12 - - - .. _FE-CAN-FEC-AUTO: - - ``FE_CAN_FEC_AUTO`` - - - The frontend can autodetect FEC. - - - .. row 13 - - - .. _FE-CAN-QPSK: - - ``FE_CAN_QPSK`` - - - The frontend supports QPSK modulation - - - .. row 14 - - - .. _FE-CAN-QAM-16: - - ``FE_CAN_QAM_16`` - - - The frontend supports 16-QAM modulation - - - .. row 15 - - - .. _FE-CAN-QAM-32: - - ``FE_CAN_QAM_32`` - - - The frontend supports 32-QAM modulation - - - .. row 16 - - - .. _FE-CAN-QAM-64: - - ``FE_CAN_QAM_64`` - - - The frontend supports 64-QAM modulation - - - .. row 17 - - - .. _FE-CAN-QAM-128: - - ``FE_CAN_QAM_128`` - - - The frontend supports 128-QAM modulation - - - .. row 18 - - - .. _FE-CAN-QAM-256: - - ``FE_CAN_QAM_256`` - - - The frontend supports 256-QAM modulation - - - .. row 19 - - - .. _FE-CAN-QAM-AUTO: - - ``FE_CAN_QAM_AUTO`` - - - The frontend can autodetect modulation - - - .. row 20 - - - .. _FE-CAN-TRANSMISSION-MODE-AUTO: - - ``FE_CAN_TRANSMISSION_MODE_AUTO`` - - - The frontend can autodetect the transmission mode - - - .. row 21 - - - .. _FE-CAN-BANDWIDTH-AUTO: - - ``FE_CAN_BANDWIDTH_AUTO`` - - - The frontend can autodetect the bandwidth - - - .. row 22 - - - .. _FE-CAN-GUARD-INTERVAL-AUTO: - - ``FE_CAN_GUARD_INTERVAL_AUTO`` - - - The frontend can autodetect the guard interval - - - .. row 23 - - - .. _FE-CAN-HIERARCHY-AUTO: - - ``FE_CAN_HIERARCHY_AUTO`` - - - The frontend can autodetect hierarch - - - .. row 24 - - - .. _FE-CAN-8VSB: - - ``FE_CAN_8VSB`` - - - The frontend supports 8-VSB modulation - - - .. row 25 - - - .. _FE-CAN-16VSB: - - ``FE_CAN_16VSB`` - - - The frontend supports 16-VSB modulation - - - .. row 26 - - - .. _FE-HAS-EXTENDED-CAPS: - - ``FE_HAS_EXTENDED_CAPS`` - - - Currently, unused - - - .. row 27 - - - .. _FE-CAN-MULTISTREAM: - - ``FE_CAN_MULTISTREAM`` - - - The frontend supports multistream filtering - - - .. row 28 - - - .. _FE-CAN-TURBO-FEC: - - ``FE_CAN_TURBO_FEC`` - - - The frontend supports turbo FEC modulation - - - .. row 29 - - - .. _FE-CAN-2G-MODULATION: - - ``FE_CAN_2G_MODULATION`` - - - The frontend supports "2nd generation modulation" (DVB-S2/T2)> - - - .. row 30 - - - .. _FE-NEEDS-BENDING: - - ``FE_NEEDS_BENDING`` - - - Not supported anymore, don't use it - - - .. row 31 - - - .. _FE-CAN-RECOVER: - - ``FE_CAN_RECOVER`` - - - The frontend can recover from a cable unplug automatically - - - .. row 32 - - - .. _FE-CAN-MUTE-TS: - - ``FE_CAN_MUTE_TS`` - - - The frontend can stop spurious TS data output +The frontend capabilities are described at :c:type:`fe_caps`. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-get-property.rst b/Documentation/media/uapi/dvb/fe-get-property.rst index 015d4db597b5..948d2ba84f2c 100644 --- a/Documentation/media/uapi/dvb/fe-get-property.rst +++ b/Documentation/media/uapi/dvb/fe-get-property.rst @@ -29,13 +29,13 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - pointer to struct :c:type:`dtv_properties` + Pointer to struct :c:type:`dtv_properties`. Description =========== -All DVB frontend devices support the ``FE_SET_PROPERTY`` and +All Digital TV frontend devices support the ``FE_SET_PROPERTY`` and ``FE_GET_PROPERTY`` ioctls. The supported properties and statistics depends on the delivery system and on the device: @@ -64,6 +64,10 @@ depends on the delivery system and on the device: Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-ber.rst b/Documentation/media/uapi/dvb/fe-read-ber.rst index e54972ad5250..1e6a79567a4c 100644 --- a/Documentation/media/uapi/dvb/fe-read-ber.rst +++ b/Documentation/media/uapi/dvb/fe-read-ber.rst @@ -41,6 +41,10 @@ access to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-signal-strength.rst b/Documentation/media/uapi/dvb/fe-read-signal-strength.rst index 4b13c4757744..198f6dfb53a1 100644 --- a/Documentation/media/uapi/dvb/fe-read-signal-strength.rst +++ b/Documentation/media/uapi/dvb/fe-read-signal-strength.rst @@ -41,6 +41,10 @@ to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-snr.rst b/Documentation/media/uapi/dvb/fe-read-snr.rst index 2aed487f5c99..6db22c043512 100644 --- a/Documentation/media/uapi/dvb/fe-read-snr.rst +++ b/Documentation/media/uapi/dvb/fe-read-snr.rst @@ -41,6 +41,10 @@ to the device is sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-status.rst b/Documentation/media/uapi/dvb/fe-read-status.rst index 812f086c20f5..4adb52f084ff 100644 --- a/Documentation/media/uapi/dvb/fe-read-status.rst +++ b/Documentation/media/uapi/dvb/fe-read-status.rst @@ -33,7 +33,7 @@ Arguments Description =========== -All DVB frontend devices support the ``FE_READ_STATUS`` ioctl. It is +All Digital TV frontend devices support the ``FE_READ_STATUS`` ioctl. It is used to check about the locking status of the frontend after being tuned. The ioctl takes a pointer to an integer where the status will be written. @@ -52,85 +52,14 @@ The fe_status parameter is used to indicate the current state and/or state changes of the frontend hardware. It is produced using the enum :c:type:`fe_status` values on a bitmask -.. c:type:: fe_status - -.. tabularcolumns:: |p{3.5cm}|p{14.0cm}| - -.. _fe-status: - -.. flat-table:: enum fe_status - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _FE-HAS-SIGNAL: - - ``FE_HAS_SIGNAL`` - - - The frontend has found something above the noise level - - - .. row 3 - - - .. _FE-HAS-CARRIER: - - ``FE_HAS_CARRIER`` - - - The frontend has found a DVB signal - - - .. row 4 - - - .. _FE-HAS-VITERBI: - - ``FE_HAS_VITERBI`` - - - The frontend FEC inner coding (Viterbi, LDPC or other inner code) - is stable - - - .. row 5 - - - .. _FE-HAS-SYNC: - - ``FE_HAS_SYNC`` - - - Synchronization bytes was found - - - .. row 6 - - - .. _FE-HAS-LOCK: - - ``FE_HAS_LOCK`` - - - The DVB were locked and everything is working - - - .. row 7 - - - .. _FE-TIMEDOUT: - - ``FE_TIMEDOUT`` - - - no lock within the last about 2 seconds - - - .. row 8 - - - .. _FE-REINIT: - - ``FE_REINIT`` - - - The frontend was reinitialized, application is recommended to - reset DiSEqC, tone and parameters - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst b/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst index 46687c123402..f2c688bcacb3 100644 --- a/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst +++ b/Documentation/media/uapi/dvb/fe-read-uncorrected-blocks.rst @@ -43,6 +43,10 @@ sufficient. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst b/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst index 1d5878da2f41..3c4bc179b313 100644 --- a/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst +++ b/Documentation/media/uapi/dvb/fe-set-frontend-tune-mode.rst @@ -30,7 +30,7 @@ Arguments - 0 - normal tune mode - - FE_TUNE_MODE_ONESHOT - When set, this flag will disable any + - ``FE_TUNE_MODE_ONESHOT`` - When set, this flag will disable any zigzagging or other "normal" tuning behaviour. Additionally, there will be no automatic monitoring of the lock status, and hence no frontend events will be generated. If a frontend device @@ -42,12 +42,16 @@ Description =========== Allow setting tuner mode flags to the frontend, between 0 (normal) or -FE_TUNE_MODE_ONESHOT mode +``FE_TUNE_MODE_ONESHOT`` mode Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-frontend.rst b/Documentation/media/uapi/dvb/fe-set-frontend.rst index 7f97dce9aee6..4f3dcf338254 100644 --- a/Documentation/media/uapi/dvb/fe-set-frontend.rst +++ b/Documentation/media/uapi/dvb/fe-set-frontend.rst @@ -48,17 +48,24 @@ requires read/write access to the device. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the -:ref:`Generic Error Codes ` chapter. +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| .. flat-table:: :header-rows: 0 :stub-columns: 0 - + :widths: 1 16 - .. row 1 - ``EINVAL`` - Maximum supported symbol rate reached. + + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-tone.rst b/Documentation/media/uapi/dvb/fe-set-tone.rst index 84e4da3fd4c9..758efa11014c 100644 --- a/Documentation/media/uapi/dvb/fe-set-tone.rst +++ b/Documentation/media/uapi/dvb/fe-set-tone.rst @@ -45,40 +45,14 @@ this is done using the DiSEqC ioctls. capability of selecting the band. So, it is recommended that applications would change to SEC_TONE_OFF when the device is not used. -.. c:type:: fe_sec_tone_mode - -.. flat-table:: enum fe_sec_tone_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _SEC-TONE-ON: - - ``SEC_TONE_ON`` - - - Sends a 22kHz tone burst to the antenna - - - .. row 3 - - - .. _SEC-TONE-OFF: - - ``SEC_TONE_OFF`` - - - Don't send a 22kHz tone to the antenna (except if the - FE_DISEQC_* ioctls are called) - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-set-voltage.rst b/Documentation/media/uapi/dvb/fe-set-voltage.rst index 052f316bb4a3..38d4485290a0 100644 --- a/Documentation/media/uapi/dvb/fe-set-voltage.rst +++ b/Documentation/media/uapi/dvb/fe-set-voltage.rst @@ -53,6 +53,10 @@ power up the LNBf. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/fe-type-t.rst b/Documentation/media/uapi/dvb/fe-type-t.rst index 548b965188d0..dee32ae104d7 100644 --- a/Documentation/media/uapi/dvb/fe-type-t.rst +++ b/Documentation/media/uapi/dvb/fe-type-t.rst @@ -78,7 +78,7 @@ parameter. In the old days, struct :c:type:`dvb_frontend_info` used to contain ``fe_type_t`` field to indicate the delivery systems, -filled with either FE_QPSK, FE_QAM, FE_OFDM or FE_ATSC. While this +filled with either ``FE_QPSK, FE_QAM, FE_OFDM`` or ``FE_ATSC``. While this is still filled to keep backward compatibility, the usage of this field is deprecated, as it can report just one delivery system, but some devices support multiple delivery systems. Please use diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst b/Documentation/media/uapi/dvb/fe_property_parameters.rst index 7bb7559c4500..6eef507fea50 100644 --- a/Documentation/media/uapi/dvb/fe_property_parameters.rst +++ b/Documentation/media/uapi/dvb/fe_property_parameters.rst @@ -6,6 +6,11 @@ Digital TV property parameters ****************************** +There are several different Digital TV parameters that can be used by +:ref:`FE_SET_PROPERTY and FE_GET_PROPERTY ioctls`. +This section describes each of them. Please notice, however, that only +a subset of them are needed to setup a frontend. + .. _DTV-UNDEFINED: @@ -67,144 +72,36 @@ DTV_MODULATION ============== Specifies the frontend modulation type for delivery systems that -supports more than one modulation type. The modulation can be one of the -types defined by enum :c:type:`fe_modulation`. - - -.. c:type:: fe_modulation - -Modulation property -------------------- - -Most of the digital TV standards currently offers more than one possible -modulation (sometimes called as "constellation" on some standards). This -enum contains the values used by the Kernel. Please note that not all -modulations are supported by a given standard. - - -.. flat-table:: enum fe_modulation - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _QPSK: - - ``QPSK`` - - - QPSK modulation - - - .. row 3 - - - .. _QAM-16: - - ``QAM_16`` - - - 16-QAM modulation - - - .. row 4 - - - .. _QAM-32: - - ``QAM_32`` - - - 32-QAM modulation - - - .. row 5 - - - .. _QAM-64: - - ``QAM_64`` - - - 64-QAM modulation - - - .. row 6 - - - .. _QAM-128: - - ``QAM_128`` - - - 128-QAM modulation - - - .. row 7 - - - .. _QAM-256: - - ``QAM_256`` - - - 256-QAM modulation - - - .. row 8 - - - .. _QAM-AUTO: - - ``QAM_AUTO`` - - - Autodetect QAM modulation - - - .. row 9 - - - .. _VSB-8: - - ``VSB_8`` - - - 8-VSB modulation - - - .. row 10 - - - .. _VSB-16: - - ``VSB_16`` - - - 16-VSB modulation - - - .. row 11 - - - .. _PSK-8: - - ``PSK_8`` - - - 8-PSK modulation - - - .. row 12 - - - .. _APSK-16: - - ``APSK_16`` - - - 16-APSK modulation - - - .. row 13 - - - .. _APSK-32: - - ``APSK_32`` - - - 32-APSK modulation - - - .. row 14 - - - .. _DQPSK: - - ``DQPSK`` - - - DQPSK modulation - - - .. row 15 - - - .. _QAM-4-NR: - - ``QAM_4_NR`` - - - 4-QAM-NR modulation - +supports more multiple modulations. + +The modulation can be one of the types defined by enum :c:type:`fe_modulation`. + +Most of the digital TV standards offers more than one possible +modulation type. + +The table below presents a summary of the types of modulation types +supported by each delivery system, as currently defined by specs. + +======================= ======================================================= +Standard Modulation types +======================= ======================================================= +ATSC (version 1) 8-VSB and 16-VSB. +DMTB 4-QAM, 16-QAM, 32-QAM, 64-QAM and 4-QAM-NR. +DVB-C Annex A/C 16-QAM, 32-QAM, 64-QAM and 256-QAM. +DVB-C Annex B 64-QAM. +DVB-T QPSK, 16-QAM and 64-QAM. +DVB-T2 QPSK, 16-QAM, 64-QAM and 256-QAM. +DVB-S No need to set. It supports only QPSK. +DVB-S2 QPSK, 8-PSK, 16-APSK and 32-APSK. +ISDB-T QPSK, DQPSK, 16-QAM and 64-QAM. +ISDB-S 8-PSK, QPSK and BPSK. +======================= ======================================================= + +.. note:: + + Please notice that some of the above modulation types may not be + defined currently at the Kernel. The reason is simple: no driver + needed such definition yet. .. _DTV-BANDWIDTH-HZ: @@ -214,33 +111,43 @@ DTV_BANDWIDTH_HZ Bandwidth for the channel, in HZ. +Should be set only for terrestrial delivery systems. + Possible values: ``1712000``, ``5000000``, ``6000000``, ``7000000``, ``8000000``, ``10000000``. +======================= ======================================================= +Terrestrial Standard Possible values for bandwidth +======================= ======================================================= +ATSC (version 1) No need to set. It is always 6MHz. +DMTB No need to set. It is always 8MHz. +DVB-T 6MHz, 7MHz and 8MHz. +DVB-T2 1.172 MHz, 5MHz, 6MHz, 7MHz, 8MHz and 10MHz +ISDB-T 5MHz, 6MHz, 7MHz and 8MHz, although most places + use 6MHz. +======================= ======================================================= + + .. note:: - #. DVB-T supports 6, 7 and 8MHz. - #. DVB-T2 supports 1.172, 5, 6, 7, 8 and 10MHz. + #. For ISDB-Tsb, the bandwidth can vary depending on the number of + connected segments. - #. ISDB-T supports 5MHz, 6MHz, 7MHz and 8MHz, although most - places use 6MHz. - - #. On DVB-C and DVB-S/S2, the bandwidth depends on the symbol rate. - So, the Kernel will silently ignore setting :ref:`DTV-BANDWIDTH-HZ`. - - #. For DVB-C and DVB-S/S2, the Kernel will return an estimation of the - bandwidth, calculated from :ref:`DTV-SYMBOL-RATE` and from - the rolloff, with is fixed for DVB-C and DVB-S. - - #. For DVB-S2, the bandwidth estimation will use :ref:`DTV-ROLLOFF`. - - #. For ISDB-Tsb, it can vary depending on the number of connected - segments. - - #. Bandwidth in ISDB-Tsb can be easily derived from other parameters + It can be easily derived from other parameters (DTV_ISDBT_SB_SEGMENT_IDX, DTV_ISDBT_SB_SEGMENT_COUNT). + #. On Satellite and Cable delivery systems, the bandwidth depends on + the symbol rate. So, the Kernel will silently ignore any setting + :ref:`DTV-BANDWIDTH-HZ`. I will however fill it back with a + bandwidth estimation. + + Such bandwidth estimation takes into account the symbol rate set with + :ref:`DTV-SYMBOL-RATE`, and the rolloff factor, with is fixed for + DVB-C and DVB-S. + + For DVB-S2, the rolloff should also be set via :ref:`DTV-ROLLOFF`. + .. _DTV-INVERSION: @@ -249,53 +156,7 @@ DTV_INVERSION Specifies if the frontend should do spectral inversion or not. -.. c:type:: fe_spectral_inversion - -enum fe_modulation: Frontend spectral inversion ------------------------------------------------ - -This parameter indicates if spectral inversion should be presumed or -not. In the automatic setting (``INVERSION_AUTO``) the hardware will try -to figure out the correct setting by itself. If the hardware doesn't -support, the DVB core will try to lock at the carrier first with -inversion off. If it fails, it will try to enable inversion. - - -.. flat-table:: enum fe_modulation - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _INVERSION-OFF: - - ``INVERSION_OFF`` - - - Don't do spectral band inversion. - - - .. row 3 - - - .. _INVERSION-ON: - - ``INVERSION_ON`` - - - Do spectral band inversion. - - - .. row 4 - - - .. _INVERSION-AUTO: - - ``INVERSION_AUTO`` - - - Autodetect spectral band inversion. - +The acceptable values are defined by :c:type:`fe_spectral_inversion`. .. _DTV-DISEQC-MASTER: @@ -311,8 +172,9 @@ Currently not implemented. DTV_SYMBOL_RATE =============== -Digital TV symbol rate, in bauds (symbols/second). Used on cable -standards. +Used on cable and satellite delivery systems. + +Digital TV symbol rate, in bauds (symbols/second). .. _DTV-INNER-FEC: @@ -320,128 +182,9 @@ standards. DTV_INNER_FEC ============= -Used cable/satellite transmissions. The acceptable values are: - -.. c:type:: fe_code_rate - -enum fe_code_rate: type of the Forward Error Correction. --------------------------------------------------------- - -.. flat-table:: enum fe_code_rate - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _FEC-NONE: - - ``FEC_NONE`` - - - No Forward Error Correction Code - - - .. row 3 - - - .. _FEC-AUTO: - - ``FEC_AUTO`` - - - Autodetect Error Correction Code - - - .. row 4 - - - .. _FEC-1-2: - - ``FEC_1_2`` - - - Forward Error Correction Code 1/2 - - - .. row 5 - - - .. _FEC-2-3: - - ``FEC_2_3`` - - - Forward Error Correction Code 2/3 - - - .. row 6 - - - .. _FEC-3-4: - - ``FEC_3_4`` - - - Forward Error Correction Code 3/4 - - - .. row 7 - - - .. _FEC-4-5: - - ``FEC_4_5`` - - - Forward Error Correction Code 4/5 - - - .. row 8 - - - .. _FEC-5-6: - - ``FEC_5_6`` - - - Forward Error Correction Code 5/6 - - - .. row 9 - - - .. _FEC-6-7: - - ``FEC_6_7`` - - - Forward Error Correction Code 6/7 - - - .. row 10 - - - .. _FEC-7-8: - - ``FEC_7_8`` - - - Forward Error Correction Code 7/8 - - - .. row 11 - - - .. _FEC-8-9: - - ``FEC_8_9`` - - - Forward Error Correction Code 8/9 - - - .. row 12 - - - .. _FEC-9-10: - - ``FEC_9_10`` - - - Forward Error Correction Code 9/10 - - - .. row 13 - - - .. _FEC-2-5: - - ``FEC_2_5`` - - - Forward Error Correction Code 2/5 - - - .. row 14 - - - .. _FEC-3-5: - - ``FEC_3_5`` - - - Forward Error Correction Code 3/5 +Used on cable and satellite delivery systems. +The acceptable values are defined by :c:type:`fe_code_rate`. .. _DTV-VOLTAGE: @@ -449,49 +192,14 @@ enum fe_code_rate: type of the Forward Error Correction. DTV_VOLTAGE =========== +Used on satellite delivery systems. + The voltage is usually used with non-DiSEqC capable LNBs to switch the polarzation (horizontal/vertical). When using DiSEqC epuipment this voltage has to be switched consistently to the DiSEqC commands as described in the DiSEqC spec. - -.. c:type:: fe_sec_voltage - -.. flat-table:: enum fe_sec_voltage - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _SEC-VOLTAGE-13: - - ``SEC_VOLTAGE_13`` - - - Set DC voltage level to 13V - - - .. row 3 - - - .. _SEC-VOLTAGE-18: - - ``SEC_VOLTAGE_18`` - - - Set DC voltage level to 18V - - - .. row 4 - - - .. _SEC-VOLTAGE-OFF: - - ``SEC_VOLTAGE_OFF`` - - - Don't send any voltage to the antenna - +The acceptable values are defined by :c:type:`fe_sec_voltage`. .. _DTV-TONE: @@ -507,50 +215,11 @@ Currently not used. DTV_PILOT ========= -Sets DVB-S2 pilot +Used on DVB-S2. +Sets DVB-S2 pilot. -.. c:type:: fe_pilot - -fe_pilot type -------------- - - -.. flat-table:: enum fe_pilot - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _PILOT-ON: - - ``PILOT_ON`` - - - Pilot tones enabled - - - .. row 3 - - - .. _PILOT-OFF: - - ``PILOT_OFF`` - - - Pilot tones disabled - - - .. row 4 - - - .. _PILOT-AUTO: - - ``PILOT_AUTO`` - - - Autodetect pilot tones - +The acceptable values are defined by :c:type:`fe_pilot`. .. _DTV-ROLLOFF: @@ -558,58 +227,11 @@ fe_pilot type DTV_ROLLOFF =========== -Sets DVB-S2 rolloff +Used on DVB-S2. +Sets DVB-S2 rolloff. -.. c:type:: fe_rolloff - -fe_rolloff type ---------------- - - -.. flat-table:: enum fe_rolloff - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ROLLOFF-35: - - ``ROLLOFF_35`` - - - Roloff factor: α=35% - - - .. row 3 - - - .. _ROLLOFF-20: - - ``ROLLOFF_20`` - - - Roloff factor: α=20% - - - .. row 4 - - - .. _ROLLOFF-25: - - ``ROLLOFF_25`` - - - Roloff factor: α=25% - - - .. row 5 - - - .. _ROLLOFF-AUTO: - - ``ROLLOFF_AUTO`` - - - Auto-detect the roloff factor. - +The acceptable values are defined by :c:type:`fe_rolloff`. .. _DTV-DISEQC-SLAVE-REPLY: @@ -641,180 +263,9 @@ Currently not implemented. DTV_DELIVERY_SYSTEM =================== -Specifies the type of Delivery system - - -.. c:type:: fe_delivery_system - -fe_delivery_system type ------------------------ - -Possible values: - - -.. flat-table:: enum fe_delivery_system - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _SYS-UNDEFINED: - - ``SYS_UNDEFINED`` - - - Undefined standard. Generally, indicates an error - - - .. row 3 - - - .. _SYS-DVBC-ANNEX-A: - - ``SYS_DVBC_ANNEX_A`` - - - Cable TV: DVB-C following ITU-T J.83 Annex A spec - - - .. row 4 - - - .. _SYS-DVBC-ANNEX-B: - - ``SYS_DVBC_ANNEX_B`` - - - Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM) - - - .. row 5 - - - .. _SYS-DVBC-ANNEX-C: - - ``SYS_DVBC_ANNEX_C`` - - - Cable TV: DVB-C following ITU-T J.83 Annex C spec - - - .. row 6 - - - .. _SYS-ISDBC: - - ``SYS_ISDBC`` - - - Cable TV: ISDB-C (no drivers yet) - - - .. row 7 - - - .. _SYS-DVBT: - - ``SYS_DVBT`` - - - Terrestral TV: DVB-T - - - .. row 8 - - - .. _SYS-DVBT2: - - ``SYS_DVBT2`` - - - Terrestral TV: DVB-T2 - - - .. row 9 - - - .. _SYS-ISDBT: - - ``SYS_ISDBT`` - - - Terrestral TV: ISDB-T - - - .. row 10 - - - .. _SYS-ATSC: - - ``SYS_ATSC`` - - - Terrestral TV: ATSC - - - .. row 11 - - - .. _SYS-ATSCMH: - - ``SYS_ATSCMH`` - - - Terrestral TV (mobile): ATSC-M/H - - - .. row 12 - - - .. _SYS-DTMB: - - ``SYS_DTMB`` - - - Terrestrial TV: DTMB - - - .. row 13 - - - .. _SYS-DVBS: - - ``SYS_DVBS`` - - - Satellite TV: DVB-S - - - .. row 14 - - - .. _SYS-DVBS2: - - ``SYS_DVBS2`` - - - Satellite TV: DVB-S2 - - - .. row 15 - - - .. _SYS-TURBO: - - ``SYS_TURBO`` - - - Satellite TV: DVB-S Turbo - - - .. row 16 - - - .. _SYS-ISDBS: - - ``SYS_ISDBS`` - - - Satellite TV: ISDB-S - - - .. row 17 - - - .. _SYS-DAB: - - ``SYS_DAB`` - - - Digital audio: DAB (not fully supported) - - - .. row 18 - - - .. _SYS-DSS: - - ``SYS_DSS`` - - - Satellite TV:"DSS (not fully supported) - - - .. row 19 - - - .. _SYS-CMMB: - - ``SYS_CMMB`` - - - Terrestral TV (mobile):CMMB (not fully supported) - - - .. row 20 - - - .. _SYS-DVBH: - - ``SYS_DVBH`` - - - Terrestral TV (mobile): DVB-H (standard deprecated) +Specifies the type of the delivery system. +The acceptable values are defined by :c:type:`fe_delivery_system`. .. _DTV-ISDBT-PARTIAL-RECEPTION: @@ -822,6 +273,8 @@ Possible values: DTV_ISDBT_PARTIAL_RECEPTION =========================== +Used only on ISDB. + If ``DTV_ISDBT_SOUND_BROADCASTING`` is '0' this bit-field represents whether the channel is in partial reception mode or not. @@ -840,6 +293,8 @@ Possible values: 0, 1, -1 (AUTO) DTV_ISDBT_SOUND_BROADCASTING ============================ +Used only on ISDB. + This field represents whether the other DTV_ISDBT_*-parameters are referring to an ISDB-T and an ISDB-Tsb channel. (See also ``DTV_ISDBT_PARTIAL_RECEPTION``). @@ -852,6 +307,8 @@ Possible values: 0, 1, -1 (AUTO) DTV_ISDBT_SB_SUBCHANNEL_ID ========================== +Used only on ISDB. + This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. (Note of the author: This might not be the correct description of the @@ -887,6 +344,8 @@ Possible values: 0 .. 41, -1 (AUTO) DTV_ISDBT_SB_SEGMENT_IDX ======================== +Used only on ISDB. + This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. ``DTV_ISDBT_SB_SEGMENT_IDX`` gives the index of the segment to be @@ -903,6 +362,8 @@ Note: This value cannot be determined by an automatic channel search. DTV_ISDBT_SB_SEGMENT_COUNT ========================== +Used only on ISDB. + This field only applies if ``DTV_ISDBT_SOUND_BROADCASTING`` is '1'. ``DTV_ISDBT_SB_SEGMENT_COUNT`` gives the total count of connected @@ -918,6 +379,8 @@ Note: This value cannot be determined by an automatic channel search. DTV-ISDBT-LAYER[A-C] parameters =============================== +Used only on ISDB. + ISDB-T channels can be coded hierarchically. As opposed to DVB-T in ISDB-T hierarchical layers can be decoded simultaneously. For that reason a ISDB-T demodulator has 3 Viterbi and 3 Reed-Solomon decoders. @@ -934,6 +397,8 @@ There are 3 parameter sets, for Layers A, B and C. DTV_ISDBT_LAYER_ENABLED ----------------------- +Used only on ISDB. + Hierarchical reception in ISDB-T is achieved by enabling or disabling layers in the decoding process. Setting all bits of ``DTV_ISDBT_LAYER_ENABLED`` to '1' forces all layers (if applicable) to @@ -964,7 +429,13 @@ Only the values of the first 3 bits are used. Other bits will be silently ignore DTV_ISDBT_LAYER[A-C]_FEC ------------------------ -Possible values: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``, +Used only on ISDB. + +The Forward Error Correction mechanism used by a given ISDB Layer, as +defined by :c:type:`fe_code_rate`. + + +Possible values are: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``, ``FEC_5_6``, ``FEC_7_8`` @@ -973,11 +444,19 @@ Possible values: ``FEC_AUTO``, ``FEC_1_2``, ``FEC_2_3``, ``FEC_3_4``, DTV_ISDBT_LAYER[A-C]_MODULATION ------------------------------- -Possible values: ``QAM_AUTO``, QP\ ``SK, QAM_16``, ``QAM_64``, ``DQPSK`` +Used only on ISDB. -Note: If layer C is ``DQPSK`` layer B has to be ``DQPSK``. If layer B is -``DQPSK`` and ``DTV_ISDBT_PARTIAL_RECEPTION``\ =0 layer has to be -``DQPSK``. +The modulation used by a given ISDB Layer, as defined by +:c:type:`fe_modulation`. + +Possible values are: ``QAM_AUTO``, ``QPSK``, ``QAM_16``, ``QAM_64``, ``DQPSK`` + +.. note:: + + #. If layer C is ``DQPSK``, then layer B has to be ``DQPSK``. + + #. If layer B is ``DQPSK`` and ``DTV_ISDBT_PARTIAL_RECEPTION``\ = 0, + then layer has to be ``DQPSK``. .. _DTV-ISDBT-LAYER-SEGMENT-COUNT: @@ -985,6 +464,8 @@ Note: If layer C is ``DQPSK`` layer B has to be ``DQPSK``. If layer B is DTV_ISDBT_LAYER[A-C]_SEGMENT_COUNT ---------------------------------- +Used only on ISDB. + Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO) Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and @@ -993,15 +474,15 @@ Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and .. _isdbt-layer_seg-cnt-table: .. flat-table:: Truth table for ISDB-T Sound Broadcasting - :header-rows: 0 + :header-rows: 1 :stub-columns: 0 - .. row 1 - - PR + - Partial Reception - - SB + - Sound Broadcasting - Layer A width @@ -1074,6 +555,8 @@ Note: Truth table for ``DTV_ISDBT_SOUND_BROADCASTING`` and DTV_ISDBT_LAYER[A-C]_TIME_INTERLEAVING -------------------------------------- +Used only on ISDB. + Valid values: 0, 1, 2, 4, -1 (AUTO) when DTV_ISDBT_SOUND_BROADCASTING is active, value 8 is also valid. @@ -1086,7 +569,7 @@ TMCC-structure, as shown in the table below. .. c:type:: isdbt_layer_interleaving_table .. flat-table:: ISDB-T time interleaving modes - :header-rows: 0 + :header-rows: 1 :stub-columns: 0 @@ -1147,6 +630,8 @@ TMCC-structure, as shown in the table below. DTV_ATSCMH_FIC_VER ------------------ +Used only on ATSC-MH. + Version number of the FIC (Fast Information Channel) signaling data. FIC is used for relaying information to allow rapid service acquisition @@ -1160,6 +645,8 @@ Possible values: 0, 1, 2, 3, ..., 30, 31 DTV_ATSCMH_PARADE_ID -------------------- +Used only on ATSC-MH. + Parade identification number A parade is a collection of up to eight MH groups, conveying one or two @@ -1173,6 +660,8 @@ Possible values: 0, 1, 2, 3, ..., 126, 127 DTV_ATSCMH_NOG -------------- +Used only on ATSC-MH. + Number of MH groups per MH subframe for a designated parade. Possible values: 1, 2, 3, 4, 5, 6, 7, 8 @@ -1183,6 +672,8 @@ Possible values: 1, 2, 3, 4, 5, 6, 7, 8 DTV_ATSCMH_TNOG --------------- +Used only on ATSC-MH. + Total number of MH groups including all MH groups belonging to all MH parades in one MH subframe. @@ -1194,6 +685,8 @@ Possible values: 0, 1, 2, 3, ..., 30, 31 DTV_ATSCMH_SGN -------------- +Used only on ATSC-MH. + Start group number. Possible values: 0, 1, 2, 3, ..., 14, 15 @@ -1204,6 +697,8 @@ Possible values: 0, 1, 2, 3, ..., 14, 15 DTV_ATSCMH_PRC -------------- +Used only on ATSC-MH. + Parade repetition cycle. Possible values: 1, 2, 3, 4, 5, 6, 7, 8 @@ -1214,44 +709,11 @@ Possible values: 1, 2, 3, 4, 5, 6, 7, 8 DTV_ATSCMH_RS_FRAME_MODE ------------------------ +Used only on ATSC-MH. + Reed Solomon (RS) frame mode. -Possible values are: - -.. tabularcolumns:: |p{5.0cm}|p{12.5cm}| - -.. c:type:: atscmh_rs_frame_mode - -.. flat-table:: enum atscmh_rs_frame_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-RSFRAME-PRI-ONLY: - - ``ATSCMH_RSFRAME_PRI_ONLY`` - - - Single Frame: There is only a primary RS Frame for all Group - Regions. - - - .. row 3 - - - .. _ATSCMH-RSFRAME-PRI-SEC: - - ``ATSCMH_RSFRAME_PRI_SEC`` - - - Dual Frame: There are two separate RS Frames: Primary RS Frame for - Group Region A and B and Secondary RS Frame for Group Region C and - D. - +The acceptable values are defined by :c:type:`atscmh_rs_frame_mode`. .. _DTV-ATSCMH-RS-FRAME-ENSEMBLE: @@ -1259,48 +721,11 @@ Possible values are: DTV_ATSCMH_RS_FRAME_ENSEMBLE ---------------------------- +Used only on ATSC-MH. + Reed Solomon(RS) frame ensemble. -Possible values are: - - -.. c:type:: atscmh_rs_frame_ensemble - -.. flat-table:: enum atscmh_rs_frame_ensemble - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-RSFRAME-ENS-PRI: - - ``ATSCMH_RSFRAME_ENS_PRI`` - - - Primary Ensemble. - - - .. row 3 - - - .. _ATSCMH-RSFRAME-ENS-SEC: - - ``AATSCMH_RSFRAME_PRI_SEC`` - - - Secondary Ensemble. - - - .. row 4 - - - .. _ATSCMH-RSFRAME-RES: - - ``AATSCMH_RSFRAME_RES`` - - - Reserved. Shouldn't be used. - +The acceptable values are defined by :c:type:`atscmh_rs_frame_ensemble`. .. _DTV-ATSCMH-RS-CODE-MODE-PRI: @@ -1308,56 +733,11 @@ Possible values are: DTV_ATSCMH_RS_CODE_MODE_PRI --------------------------- +Used only on ATSC-MH. + Reed Solomon (RS) code mode (primary). -Possible values are: - - -.. c:type:: atscmh_rs_code_mode - -.. flat-table:: enum atscmh_rs_code_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-RSCODE-211-187: - - ``ATSCMH_RSCODE_211_187`` - - - Reed Solomon code (211,187). - - - .. row 3 - - - .. _ATSCMH-RSCODE-223-187: - - ``ATSCMH_RSCODE_223_187`` - - - Reed Solomon code (223,187). - - - .. row 4 - - - .. _ATSCMH-RSCODE-235-187: - - ``ATSCMH_RSCODE_235_187`` - - - Reed Solomon code (235,187). - - - .. row 5 - - - .. _ATSCMH-RSCODE-RES: - - ``ATSCMH_RSCODE_RES`` - - - Reserved. Shouldn't be used. - +The acceptable values are defined by :c:type:`atscmh_rs_code_mode`. .. _DTV-ATSCMH-RS-CODE-MODE-SEC: @@ -1365,10 +745,11 @@ Possible values are: DTV_ATSCMH_RS_CODE_MODE_SEC --------------------------- +Used only on ATSC-MH. + Reed Solomon (RS) code mode (secondary). -Possible values are the same as documented on enum -:c:type:`atscmh_rs_code_mode`: +The acceptable values are defined by :c:type:`atscmh_rs_code_mode`. .. _DTV-ATSCMH-SCCC-BLOCK-MODE: @@ -1376,51 +757,11 @@ Possible values are the same as documented on enum DTV_ATSCMH_SCCC_BLOCK_MODE -------------------------- +Used only on ATSC-MH. + Series Concatenated Convolutional Code Block Mode. -Possible values are: - -.. tabularcolumns:: |p{4.5cm}|p{13.0cm}| - -.. c:type:: atscmh_sccc_block_mode - -.. flat-table:: enum atscmh_scc_block_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-SCCC-BLK-SEP: - - ``ATSCMH_SCCC_BLK_SEP`` - - - Separate SCCC: the SCCC outer code mode shall be set independently - for each Group Region (A, B, C, D) - - - .. row 3 - - - .. _ATSCMH-SCCC-BLK-COMB: - - ``ATSCMH_SCCC_BLK_COMB`` - - - Combined SCCC: all four Regions shall have the same SCCC outer - code mode. - - - .. row 4 - - - .. _ATSCMH-SCCC-BLK-RES: - - ``ATSCMH_SCCC_BLK_RES`` - - - Reserved. Shouldn't be used. - +The acceptable values are defined by :c:type:`atscmh_sccc_block_mode`. .. _DTV-ATSCMH-SCCC-CODE-MODE-A: @@ -1428,55 +769,19 @@ Possible values are: DTV_ATSCMH_SCCC_CODE_MODE_A --------------------------- +Used only on ATSC-MH. + Series Concatenated Convolutional Code Rate. -Possible values are: - - -.. c:type:: atscmh_sccc_code_mode - -.. flat-table:: enum atscmh_sccc_code_mode - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _ATSCMH-SCCC-CODE-HLF: - - ``ATSCMH_SCCC_CODE_HLF`` - - - The outer code rate of a SCCC Block is 1/2 rate. - - - .. row 3 - - - .. _ATSCMH-SCCC-CODE-QTR: - - ``ATSCMH_SCCC_CODE_QTR`` - - - The outer code rate of a SCCC Block is 1/4 rate. - - - .. row 4 - - - .. _ATSCMH-SCCC-CODE-RES: - - ``ATSCMH_SCCC_CODE_RES`` - - - to be documented. - - +The acceptable values are defined by :c:type:`atscmh_sccc_code_mode`. .. _DTV-ATSCMH-SCCC-CODE-MODE-B: DTV_ATSCMH_SCCC_CODE_MODE_B --------------------------- +Used only on ATSC-MH. + Series Concatenated Convolutional Code Rate. Possible values are the same as documented on enum @@ -1488,6 +793,8 @@ Possible values are the same as documented on enum DTV_ATSCMH_SCCC_CODE_MODE_C --------------------------- +Used only on ATSC-MH. + Series Concatenated Convolutional Code Rate. Possible values are the same as documented on enum @@ -1499,6 +806,8 @@ Possible values are the same as documented on enum DTV_ATSCMH_SCCC_CODE_MODE_D --------------------------- +Used only on ATSC-MH. + Series Concatenated Convolutional Code Rate. Possible values are the same as documented on enum @@ -1510,7 +819,7 @@ Possible values are the same as documented on enum DTV_API_VERSION =============== -Returns the major/minor version of the DVB API +Returns the major/minor version of the Digital TV API .. _DTV-CODE-RATE-HP: @@ -1518,8 +827,9 @@ Returns the major/minor version of the DVB API DTV_CODE_RATE_HP ================ -Used on terrestrial transmissions. The acceptable values are the ones -described at :c:type:`fe_transmit_mode`. +Used on terrestrial transmissions. + +The acceptable values are defined by :c:type:`fe_transmit_mode`. .. _DTV-CODE-RATE-LP: @@ -1527,8 +837,9 @@ described at :c:type:`fe_transmit_mode`. DTV_CODE_RATE_LP ================ -Used on terrestrial transmissions. The acceptable values are the ones -described at :c:type:`fe_transmit_mode`. +Used on terrestrial transmissions. + +The acceptable values are defined by :c:type:`fe_transmit_mode`. .. _DTV-GUARD-INTERVAL: @@ -1536,242 +847,56 @@ described at :c:type:`fe_transmit_mode`. DTV_GUARD_INTERVAL ================== -Possible values are: +The acceptable values are defined by :c:type:`fe_guard_interval`. +.. note:: -.. c:type:: fe_guard_interval - -Modulation guard interval -------------------------- - - -.. flat-table:: enum fe_guard_interval - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _GUARD-INTERVAL-AUTO: - - ``GUARD_INTERVAL_AUTO`` - - - Autodetect the guard interval - - - .. row 3 - - - .. _GUARD-INTERVAL-1-128: - - ``GUARD_INTERVAL_1_128`` - - - Guard interval 1/128 - - - .. row 4 - - - .. _GUARD-INTERVAL-1-32: - - ``GUARD_INTERVAL_1_32`` - - - Guard interval 1/32 - - - .. row 5 - - - .. _GUARD-INTERVAL-1-16: - - ``GUARD_INTERVAL_1_16`` - - - Guard interval 1/16 - - - .. row 6 - - - .. _GUARD-INTERVAL-1-8: - - ``GUARD_INTERVAL_1_8`` - - - Guard interval 1/8 - - - .. row 7 - - - .. _GUARD-INTERVAL-1-4: - - ``GUARD_INTERVAL_1_4`` - - - Guard interval 1/4 - - - .. row 8 - - - .. _GUARD-INTERVAL-19-128: - - ``GUARD_INTERVAL_19_128`` - - - Guard interval 19/128 - - - .. row 9 - - - .. _GUARD-INTERVAL-19-256: - - ``GUARD_INTERVAL_19_256`` - - - Guard interval 19/256 - - - .. row 10 - - - .. _GUARD-INTERVAL-PN420: - - ``GUARD_INTERVAL_PN420`` - - - PN length 420 (1/4) - - - .. row 11 - - - .. _GUARD-INTERVAL-PN595: - - ``GUARD_INTERVAL_PN595`` - - - PN length 595 (1/6) - - - .. row 12 - - - .. _GUARD-INTERVAL-PN945: - - ``GUARD_INTERVAL_PN945`` - - - PN length 945 (1/9) - - -Notes: - -1) If ``DTV_GUARD_INTERVAL`` is set the ``GUARD_INTERVAL_AUTO`` the -hardware will try to find the correct guard interval (if capable) and -will use TMCC to fill in the missing parameters. - -2) Intervals 1/128, 19/128 and 19/256 are used only for DVB-T2 at -present - -3) DTMB specifies PN420, PN595 and PN945. - + #. If ``DTV_GUARD_INTERVAL`` is set the ``GUARD_INTERVAL_AUTO`` the + hardware will try to find the correct guard interval (if capable) and + will use TMCC to fill in the missing parameters. + #. Intervals ``GUARD_INTERVAL_1_128``, ``GUARD_INTERVAL_19_128`` + and ``GUARD_INTERVAL_19_256`` are used only for DVB-T2 at + present. + #. Intervals ``GUARD_INTERVAL_PN420``, ``GUARD_INTERVAL_PN595`` and + ``GUARD_INTERVAL_PN945`` are used only for DMTB at the present. + On such standard, only those intervals and ``GUARD_INTERVAL_AUTO`` + are valid. .. _DTV-TRANSMISSION-MODE: DTV_TRANSMISSION_MODE ===================== -Specifies the number of carriers used by the standard. This is used only -on OFTM-based standards, e. g. DVB-T/T2, ISDB-T, DTMB +Used only on OFTM-based standards, e. g. DVB-T/T2, ISDB-T, DTMB. -.. c:type:: fe_transmit_mode +Specifies the FFT size (with corresponds to the approximate number of +carriers) used by the standard. -enum fe_transmit_mode: Number of carriers per channel ------------------------------------------------------ +The acceptable values are defined by :c:type:`fe_transmit_mode`. -.. tabularcolumns:: |p{5.0cm}|p{12.5cm}| +.. note:: -.. flat-table:: enum fe_transmit_mode - :header-rows: 1 - :stub-columns: 0 + #. ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called + **mode** on such standard, and are numbered from 1 to 3: + ==== ======== ======================== + Mode FFT size Transmission mode + ==== ======== ======================== + 1 2K ``TRANSMISSION_MODE_2K`` + 2 4K ``TRANSMISSION_MODE_4K`` + 3 8K ``TRANSMISSION_MODE_8K`` + ==== ======== ======================== - - .. row 1 + #. If ``DTV_TRANSMISSION_MODE`` is set the ``TRANSMISSION_MODE_AUTO`` + the hardware will try to find the correct FFT-size (if capable) and + will use TMCC to fill in the missing parameters. - - ID + #. DVB-T specifies 2K and 8K as valid sizes. - - Description + #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K. - - .. row 2 - - - .. _TRANSMISSION-MODE-AUTO: - - ``TRANSMISSION_MODE_AUTO`` - - - Autodetect transmission mode. The hardware will try to find the - correct FFT-size (if capable) to fill in the missing parameters. - - - .. row 3 - - - .. _TRANSMISSION-MODE-1K: - - ``TRANSMISSION_MODE_1K`` - - - Transmission mode 1K - - - .. row 4 - - - .. _TRANSMISSION-MODE-2K: - - ``TRANSMISSION_MODE_2K`` - - - Transmission mode 2K - - - .. row 5 - - - .. _TRANSMISSION-MODE-8K: - - ``TRANSMISSION_MODE_8K`` - - - Transmission mode 8K - - - .. row 6 - - - .. _TRANSMISSION-MODE-4K: - - ``TRANSMISSION_MODE_4K`` - - - Transmission mode 4K - - - .. row 7 - - - .. _TRANSMISSION-MODE-16K: - - ``TRANSMISSION_MODE_16K`` - - - Transmission mode 16K - - - .. row 8 - - - .. _TRANSMISSION-MODE-32K: - - ``TRANSMISSION_MODE_32K`` - - - Transmission mode 32K - - - .. row 9 - - - .. _TRANSMISSION-MODE-C1: - - ``TRANSMISSION_MODE_C1`` - - - Single Carrier (C=1) transmission mode (DTMB) - - - .. row 10 - - - .. _TRANSMISSION-MODE-C3780: - - ``TRANSMISSION_MODE_C3780`` - - - Multi Carrier (C=3780) transmission mode (DTMB) - - -Notes: - -1) ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called -'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K - -2) If ``DTV_TRANSMISSION_MODE`` is set the ``TRANSMISSION_MODE_AUTO`` -the hardware will try to find the correct FFT-size (if capable) and will -use TMCC to fill in the missing parameters. - -3) DVB-T specifies 2K and 8K as valid sizes. - -4) DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K. - -5) DTMB specifies C1 and C3780. + #. DTMB specifies C1 and C3780. .. _DTV-HIERARCHY: @@ -1779,66 +904,11 @@ use TMCC to fill in the missing parameters. DTV_HIERARCHY ============= -Frontend hierarchy +Used only on DVB-T and DVB-T2. +Frontend hierarchy. -.. c:type:: fe_hierarchy - -Frontend hierarchy ------------------- - - -.. flat-table:: enum fe_hierarchy - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _HIERARCHY-NONE: - - ``HIERARCHY_NONE`` - - - No hierarchy - - - .. row 3 - - - .. _HIERARCHY-AUTO: - - ``HIERARCHY_AUTO`` - - - Autodetect hierarchy (if supported) - - - .. row 4 - - - .. _HIERARCHY-1: - - ``HIERARCHY_1`` - - - Hierarchy 1 - - - .. row 5 - - - .. _HIERARCHY-2: - - ``HIERARCHY_2`` - - - Hierarchy 2 - - - .. row 6 - - - .. _HIERARCHY-4: - - ``HIERARCHY_4`` - - - Hierarchy 4 - +The acceptable values are defined by :c:type:`fe_hierarchy`. .. _DTV-STREAM-ID: @@ -1846,8 +916,10 @@ Frontend hierarchy DTV_STREAM_ID ============= +Used on DVB-S2, DVB-T2 and ISDB-S. + DVB-S2, DVB-T2 and ISDB-S support the transmission of several streams on -a single transport stream. This property enables the DVB driver to +a single transport stream. This property enables the digital TV driver to handle substream filtering, when supported by the hardware. By default, substream filtering is disabled. @@ -1884,60 +956,17 @@ with it, rather than trying to use FE_GET_INFO. In the case of a legacy frontend, the result is just the same as with FE_GET_INFO, but in a more structured format +The acceptable values are defined by :c:type:`fe_delivery_system`. + .. _DTV-INTERLEAVING: DTV_INTERLEAVING ================ -Time interleaving to be used. Currently, used only on DTMB. - - -.. c:type:: fe_interleaving - -.. flat-table:: enum fe_interleaving - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - .. _INTERLEAVING-NONE: - - ``INTERLEAVING_NONE`` - - - No interleaving. - - - .. row 3 - - - .. _INTERLEAVING-AUTO: - - ``INTERLEAVING_AUTO`` - - - Auto-detect interleaving. - - - .. row 4 - - - .. _INTERLEAVING-240: - - ``INTERLEAVING_240`` - - - Interleaving of 240 symbols. - - - .. row 5 - - - .. _INTERLEAVING-720: - - ``INTERLEAVING_720`` - - - Interleaving of 720 symbols. +Time interleaving to be used. +The acceptable values are defined by :c:type:`fe_interleaving`. .. _DTV-LNA: diff --git a/Documentation/media/uapi/dvb/frontend-header.rst b/Documentation/media/uapi/dvb/frontend-header.rst new file mode 100644 index 000000000000..8d8433cf1e12 --- /dev/null +++ b/Documentation/media/uapi/dvb/frontend-header.rst @@ -0,0 +1,4 @@ +Frontend uAPI data types +======================== + +.. kernel-doc:: include/uapi/linux/dvb/frontend.h diff --git a/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst b/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst index dbc717cad9ee..0beb5cb3d729 100644 --- a/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst +++ b/Documentation/media/uapi/dvb/frontend-property-terrestrial-systems.rst @@ -100,7 +100,7 @@ to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible that some very sophisticated devices won't need certain parameters to tune. The information given here should help application writers to know how -to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API. +to handle ISDB-T and ISDB-Tsb hardware using the Linux Digital TV API. The details given here about ISDB-T and ISDB-Tsb are just enough to basically show the dependencies between the needed parameter values, but diff --git a/Documentation/media/uapi/dvb/frontend.rst b/Documentation/media/uapi/dvb/frontend.rst index e051a9012540..4967c48d46ce 100644 --- a/Documentation/media/uapi/dvb/frontend.rst +++ b/Documentation/media/uapi/dvb/frontend.rst @@ -2,20 +2,22 @@ .. _dvb_frontend: -################ -DVB Frontend API -################ -The DVB frontend API was designed to support three types of delivery -systems: +####################### +Digital TV Frontend API +####################### + +The Digital TV frontend API was designed to support three groups of delivery +systems: Terrestrial, cable and Satellite. Currently, the following +delivery systems are supported: - Terrestrial systems: DVB-T, DVB-T2, ATSC, ATSC M/H, ISDB-T, DVB-H, DTMB, CMMB -- Cable systems: DVB-C Annex A/C, ClearQAM (DVB-C Annex B), ISDB-C +- Cable systems: DVB-C Annex A/C, ClearQAM (DVB-C Annex B) - Satellite systems: DVB-S, DVB-S2, DVB Turbo, ISDB-S, DSS -The DVB frontend controls several sub-devices including: +The Digital TV frontend controls several sub-devices including: - Tuner @@ -23,7 +25,7 @@ The DVB frontend controls several sub-devices including: - Low noise amplifier (LNA) -- Satellite Equipment Control (SEC) hardware (only for Satellite). +- Satellite Equipment Control (SEC) [#f1]_. The frontend can be accessed through ``/dev/dvb/adapter?/frontend?``. Data types and ioctl definitions can be accessed by including @@ -31,16 +33,18 @@ Data types and ioctl definitions can be accessed by including .. note:: - Transmission via the internet (DVB-IP) is not yet handled by this - API but a future extension is possible. + Transmission via the internet (DVB-IP) and MMT (MPEG Media Transport) + is not yet handled by this API but a future extension is possible. -On Satellite systems, the API support for the Satellite Equipment -Control (SEC) allows to power control and to send/receive signals to -control the antenna subsystem, selecting the polarization and choosing -the Intermediate Frequency IF) of the Low Noise Block Converter Feed -Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC -(digital SEC) specification is available at -`Eutelsat `__. +.. [#f1] + + On Satellite systems, the API support for the Satellite Equipment + Control (SEC) allows to power control and to send/receive signals to + control the antenna subsystem, selecting the polarization and choosing + the Intermediate Frequency IF) of the Low Noise Block Converter Feed + Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC + (digital SEC) specification is available at + `Eutelsat `__. .. toctree:: @@ -50,4 +54,3 @@ Horn (LNBf). It supports the DiSEqC and V-SEC protocols. The DiSEqC dvb-fe-read-status dvbproperty frontend_fcalls - frontend_legacy_dvbv3_api diff --git a/Documentation/media/uapi/dvb/frontend_f_close.rst b/Documentation/media/uapi/dvb/frontend_f_close.rst index f3b04b60246c..67958d73cf34 100644 --- a/Documentation/media/uapi/dvb/frontend_f_close.rst +++ b/Documentation/media/uapi/dvb/frontend_f_close.rst @@ -2,9 +2,9 @@ .. _frontend_f_close: -******************** -DVB frontend close() -******************** +*************************** +Digital TV frontend close() +*************************** Name ==== @@ -41,8 +41,10 @@ down automatically. Return Value ============ -The function returns 0 on success, -1 on failure and the ``errno`` is -set appropriately. Possible error codes: +On success 0 is returned. -EBADF - ``fd`` is not a valid open file descriptor. +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +Generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/frontend_f_open.rst b/Documentation/media/uapi/dvb/frontend_f_open.rst index 690eb375bdc1..8e8cb466c24b 100644 --- a/Documentation/media/uapi/dvb/frontend_f_open.rst +++ b/Documentation/media/uapi/dvb/frontend_f_open.rst @@ -2,9 +2,9 @@ .. _frontend_f_open: -******************* -DVB frontend open() -******************* +*************************** +Digital TV frontend open() +*************************** Name ==== @@ -79,24 +79,32 @@ On error, -1 is returned, and the ``errno`` variable is set appropriately. Possible error codes are: -EACCES - The caller has no permission to access the device. -EBUSY - The the device driver is already in use. +On success 0 is returned, and :c:type:`ca_slot_info` is filled. -ENXIO - No device corresponding to this device special file exists. +On error -1 is returned, and the ``errno`` variable is set +appropriately. -ENOMEM - Not enough kernel memory was available to complete the request. +.. tabularcolumns:: |p{2.5cm}|p{15.0cm}| -EMFILE - The process already has the maximum number of files open. +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 1 16 -ENFILE - The limit on the total number of files open on the system has been - reached. + - - ``EPERM`` + - The caller has no permission to access the device. -ENODEV - The device got removed. + - - ``EBUSY`` + - The the device driver is already in use. + + - - ``EMFILE`` + - The process already has the maximum number of files open. + + - - ``ENFILE`` + - The limit on the total number of files open on the system has been + reached. + + +The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/frontend_h.rst b/Documentation/media/uapi/dvb/frontend_h.rst deleted file mode 100644 index 15fca04d1c32..000000000000 --- a/Documentation/media/uapi/dvb/frontend_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _frontend_h: - -************************ -DVB Frontend Header File -************************ - -.. kernel-include:: $BUILDDIR/frontend.h.rst diff --git a/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst b/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst index 7d4a091b7d7f..a4d5319cb76b 100644 --- a/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst +++ b/Documentation/media/uapi/dvb/frontend_legacy_dvbv3_api.rst @@ -2,9 +2,9 @@ .. _frontend_legacy_dvbv3_api: -**************************************** -DVB Frontend legacy API (a. k. a. DVBv3) -**************************************** +*********************************************** +Digital TV Frontend legacy API (a. k. a. DVBv3) +*********************************************** The usage of this API is deprecated, as it doesn't support all digital TV standards, doesn't provide good statistics measurements and provides diff --git a/Documentation/media/uapi/dvb/headers.rst b/Documentation/media/uapi/dvb/headers.rst new file mode 100644 index 000000000000..c13fd537fbff --- /dev/null +++ b/Documentation/media/uapi/dvb/headers.rst @@ -0,0 +1,21 @@ +**************************** +Digital TV uAPI header files +**************************** + +Digital TV uAPI headers +*********************** + +.. kernel-include:: $BUILDDIR/frontend.h.rst + +.. kernel-include:: $BUILDDIR/dmx.h.rst + +.. kernel-include:: $BUILDDIR/ca.h.rst + +.. kernel-include:: $BUILDDIR/net.h.rst + +Legacy uAPI +*********** + +.. kernel-include:: $BUILDDIR/audio.h.rst + +.. kernel-include:: $BUILDDIR/video.h.rst diff --git a/Documentation/media/uapi/dvb/intro.rst b/Documentation/media/uapi/dvb/intro.rst index 652c4aacd2c6..79b4d0e4e920 100644 --- a/Documentation/media/uapi/dvb/intro.rst +++ b/Documentation/media/uapi/dvb/intro.rst @@ -13,15 +13,18 @@ What you need to know ===================== The reader of this document is required to have some knowledge in the -area of digital video broadcasting (DVB) and should be familiar with +area of digital video broadcasting (Digital TV) and should be familiar with part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e you should know what a program/transport stream (PS/TS) is and what is meant by a packetized elementary stream (PES) or an I-frame. -Various DVB standards documents are available from http://www.dvb.org -and/or http://www.etsi.org. +Various Digital TV standards documents are available for download at: -It is also necessary to know how to access unix/linux devices and how to +- European standards (DVB): http://www.dvb.org and/or http://www.etsi.org. +- American standards (ATSC): https://www.atsc.org/standards/ +- Japanese standards (ISDB): http://www.dibeg.org/ + +It is also necessary to know how to access Linux devices and how to use ioctl calls. This also includes the knowledge of C or C++. @@ -30,21 +33,25 @@ use ioctl calls. This also includes the knowledge of C or C++. History ======= -The first API for DVB cards we used at Convergence in late 1999 was an +The first API for Digital TV cards we used at Convergence in late 1999 was an extension of the Video4Linux API which was primarily developed for frame -grabber cards. As such it was not really well suited to be used for DVB -cards and their new features like recording MPEG streams and filtering +grabber cards. As such it was not really well suited to be used for Digital +TV cards and their new features like recording MPEG streams and filtering several section and PES data streams at the same time. -In early 2000, we were approached by Nokia with a proposal for a new -standard Linux DVB API. As a commitment to the development of terminals +In early 2000, Convergence was approached by Nokia with a proposal for a new +standard Linux Digital TV API. As a commitment to the development of terminals based on open standards, Nokia and Convergence made it available to all Linux developers and published it on https://linuxtv.org in September -2000. Convergence is the maintainer of the Linux DVB API. Together with -the LinuxTV community (i.e. you, the reader of this document), the Linux -DVB API will be constantly reviewed and improved. With the Linux driver -for the Siemens/Hauppauge DVB PCI card Convergence provides a first -implementation of the Linux DVB API. +2000. With the Linux driver for the Siemens/Hauppauge DVB PCI card, +Convergence provided a first implementation of the Linux Digital TV API. +Convergence was the maintainer of the Linux Digital TV API in the early +days. + +Now, the API is maintained by the LinuxTV community (i.e. you, the reader +of this document). The Linux Digital TV API is constantly reviewed and +improved together with the improvements at the subsystem's core at the +Kernel. .. _overview: @@ -59,61 +66,65 @@ Overview :alt: dvbstb.svg :align: center - Components of a DVB card/STB + Components of a Digital TV card/STB -A DVB PCI card or DVB set-top-box (STB) usually consists of the +A Digital TV card or set-top-box (STB) usually consists of the following main hardware components: -- Frontend consisting of tuner and DVB demodulator - - Here the raw signal reaches the DVB hardware from a satellite dish or +Frontend consisting of tuner and digital TV demodulator + Here the raw signal reaches the digital TV hardware from a satellite dish or antenna or directly from cable. The frontend down-converts and demodulates this signal into an MPEG transport stream (TS). In case of a satellite frontend, this includes a facility for satellite equipment control (SEC), which allows control of LNB polarization, multi feed switches or dish rotors. -- Conditional Access (CA) hardware like CI adapters and smartcard slots - +Conditional Access (CA) hardware like CI adapters and smartcard slots The complete TS is passed through the CA hardware. Programs to which the user has access (controlled by the smart card) are decoded in real time and re-inserted into the TS. -- Demultiplexer which filters the incoming DVB stream + .. note:: + Not every digital TV hardware provides conditional access hardware. + +Demultiplexer which filters the incoming Digital TV MPEG-TS stream The demultiplexer splits the TS into its components like audio and video streams. Besides usually several of such audio and video streams it also contains data streams with information about the programs offered in this or other streams of the same provider. -- MPEG2 audio and video decoder +Audio and video decoder + The main targets of the demultiplexer are audio and video + decoders. After decoding, they pass on the uncompressed audio and + video to the computer screen or to a TV set. - The main targets of the demultiplexer are the MPEG2 audio and video - decoders. After decoding they pass on the uncompressed audio and - video to the computer screen or (through a PAL/NTSC encoder) to a TV - set. + .. note:: + + Modern hardware usually doesn't have a separate decoder hardware, as + such functionality can be provided by the main CPU, by the graphics + adapter of the system or by a signal processing hardware embedded on + a Systems on a Chip (SoC) integrated circuit. + + It may also not be needed for certain usages (e.g. for data-only + uses like “internet over satellite”). :ref:`stb_components` shows a crude schematic of the control and data flow between those components. -On a DVB PCI card not all of these have to be present since some -functionality can be provided by the main CPU of the PC (e.g. MPEG -picture and sound decoding) or is not needed (e.g. for data-only uses -like “internet over satellite”). Also not every card or STB provides -conditional access hardware. .. _dvb_devices: -Linux DVB Devices -================= +Linux Digital TV Devices +======================== -The Linux DVB API lets you control these hardware components through +The Linux Digital TV API lets you control these hardware components through currently six Unix-style character devices for video, audio, frontend, demux, CA and IP-over-DVB networking. The video and audio devices control the MPEG2 decoder hardware, the frontend device the tuner and -the DVB demodulator. The demux device gives you control over the PES and -section filters of the hardware. If the hardware does not support +the Digital TV demodulator. The demux device gives you control over the PES +and section filters of the hardware. If the hardware does not support filtering these filters can be implemented in software. Finally, the CA device controls all the conditional access capabilities of the hardware. It can depend on the individual security requirements of the platform, @@ -137,9 +148,9 @@ individual devices are called: - ``/dev/dvb/adapterN/caM``, -where N enumerates the DVB PCI cards in a system starting from 0, and M -enumerates the devices of each type within each adapter, starting -from 0, too. We will omit the “ ``/dev/dvb/adapterN/``\ ” in the further +where ``N`` enumerates the Digital TV cards in a system starting from 0, and +``M`` enumerates the devices of each type within each adapter, starting +from 0, too. We will omit the “``/dev/dvb/adapterN/``\ ” in the further discussion of these devices. More details about the data structures and function calls of all the @@ -151,8 +162,8 @@ devices are described in the following chapters. API include files ================= -For each of the DVB devices a corresponding include file exists. The DVB -API include files should be included in application sources with a +For each of the Digital TV devices a corresponding include file exists. The +Digital TV API include files should be included in application sources with a partial path like: diff --git a/Documentation/media/uapi/dvb/legacy_dvb_apis.rst b/Documentation/media/uapi/dvb/legacy_dvb_apis.rst index 2957f5a988b0..e1b2c9c7b620 100644 --- a/Documentation/media/uapi/dvb/legacy_dvb_apis.rst +++ b/Documentation/media/uapi/dvb/legacy_dvb_apis.rst @@ -2,19 +2,31 @@ .. _legacy_dvb_apis: -******************* -DVB Deprecated APIs -******************* +*************************** +Digital TV Deprecated APIs +*************************** -The APIs described here are kept only for historical reasons. There's -just one driver for a very legacy hardware that uses this API. No modern -drivers should use it. Instead, audio and video should be using the V4L2 -and ALSA APIs, and the pipelines should be set using the Media -Controller API +The APIs described here **should not** be used on new drivers or applications. + +The DVBv3 frontend API has issues with new delivery systems, including +DVB-S2, DVB-T2, ISDB, etc. + +There's just one driver for a very legacy hardware using the Digital TV +audio and video APIs. No modern drivers should use it. Instead, audio and +video should be using the V4L2 and ALSA APIs, and the pipelines should +be set via the Media Controller API. + +.. attention:: + + The APIs described here doesn't necessarily reflect the current + code implementation, as this section of the document was written + for DVB version 1, while the code reflects DVB version 3 + implementation. .. toctree:: :maxdepth: 1 + frontend_legacy_dvbv3_api video audio diff --git a/Documentation/media/uapi/dvb/net-add-if.rst b/Documentation/media/uapi/dvb/net-add-if.rst index 82ce2438213f..6749b70246c5 100644 --- a/Documentation/media/uapi/dvb/net-add-if.rst +++ b/Documentation/media/uapi/dvb/net-add-if.rst @@ -41,43 +41,13 @@ created. The struct :c:type:`dvb_net_if`::ifnum field will be filled with the number of the created interface. -.. c:type:: dvb_net_if - -.. flat-table:: struct dvb_net_if - :header-rows: 1 - :stub-columns: 0 - - - - .. row 1 - - - ID - - - Description - - - .. row 2 - - - pid - - - Packet ID (PID) of the MPEG-TS that contains data - - - .. row 3 - - - ifnum - - - number of the DVB interface. - - - .. row 4 - - - feedtype - - - Encapsulation type of the feed. It can be: - ``DVB_NET_FEEDTYPE_MPE`` for MPE encoding or - ``DVB_NET_FEEDTYPE_ULE`` for ULE encoding. - - Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned, and :c:type:`ca_slot_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/net-get-if.rst b/Documentation/media/uapi/dvb/net-get-if.rst index 1bb8ee0cbced..3733b34da9db 100644 --- a/Documentation/media/uapi/dvb/net-get-if.rst +++ b/Documentation/media/uapi/dvb/net-get-if.rst @@ -43,6 +43,10 @@ the ``errno`` with ``EINVAL`` error code. Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned, and :c:type:`ca_slot_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/net-remove-if.rst b/Documentation/media/uapi/dvb/net-remove-if.rst index 646af23a925a..4ebe07a6b79a 100644 --- a/Documentation/media/uapi/dvb/net-remove-if.rst +++ b/Documentation/media/uapi/dvb/net-remove-if.rst @@ -39,6 +39,10 @@ The NET_REMOVE_IF ioctl deletes an interface previously created via Return Value ============ -On success 0 is returned, on error -1 and the ``errno`` variable is set -appropriately. The generic error codes are described at the +On success 0 is returned, and :c:type:`ca_slot_info` is filled. + +On error -1 is returned, and the ``errno`` variable is set +appropriately. + +The generic error codes are described at the :ref:`Generic Error Codes ` chapter. diff --git a/Documentation/media/uapi/dvb/net-types.rst b/Documentation/media/uapi/dvb/net-types.rst new file mode 100644 index 000000000000..e1177bdcd623 --- /dev/null +++ b/Documentation/media/uapi/dvb/net-types.rst @@ -0,0 +1,9 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _dmx_types: + +************** +Net Data Types +************** + +.. kernel-doc:: include/uapi/linux/dvb/net.h diff --git a/Documentation/media/uapi/dvb/net.rst b/Documentation/media/uapi/dvb/net.rst index eca42dd53261..e0cd4e402627 100644 --- a/Documentation/media/uapi/dvb/net.rst +++ b/Documentation/media/uapi/dvb/net.rst @@ -2,10 +2,11 @@ .. _net: -############### -DVB Network API -############### -The DVB net device controls the mapping of data packages that are part +###################### +Digital TV Network API +###################### + +The Digital TV net device controls the mapping of data packages that are part of a transport stream to be mapped into a virtual network interface, visible through the standard Linux network protocol stack. @@ -28,13 +29,13 @@ header. .. _net_fcalls: -###################### -DVB net Function Calls -###################### +Digital TV net Function Calls +############################# .. toctree:: :maxdepth: 1 + net-types net-add-if net-remove-if net-get-if diff --git a/Documentation/media/uapi/dvb/net_h.rst b/Documentation/media/uapi/dvb/net_h.rst deleted file mode 100644 index 7bcf5ba9d1eb..000000000000 --- a/Documentation/media/uapi/dvb/net_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _net_h: - -*********************** -DVB Network Header File -*********************** - -.. kernel-include:: $BUILDDIR/net.h.rst diff --git a/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst b/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst index 81cd9b92a36c..51ec0b04b496 100644 --- a/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst +++ b/Documentation/media/uapi/dvb/query-dvb-frontend-info.rst @@ -9,5 +9,5 @@ Querying frontend information Usually, the first thing to do when the frontend is opened is to check the frontend capabilities. This is done using :ref:`FE_GET_INFO`. This ioctl will enumerate the -DVB API version and other characteristics about the frontend, and can be -opened either in read only or read/write mode. +Digital TV API version and other characteristics about the frontend, and can +be opened either in read only or read/write mode. diff --git a/Documentation/media/uapi/dvb/video-continue.rst b/Documentation/media/uapi/dvb/video-continue.rst index 030c2ec98869..e65e600be632 100644 --- a/Documentation/media/uapi/dvb/video-continue.rst +++ b/Documentation/media/uapi/dvb/video-continue.rst @@ -44,7 +44,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call restarts decoding and playing processes of the video diff --git a/Documentation/media/uapi/dvb/video-freeze.rst b/Documentation/media/uapi/dvb/video-freeze.rst index 9cef65a02e8d..5a28bdc8badd 100644 --- a/Documentation/media/uapi/dvb/video-freeze.rst +++ b/Documentation/media/uapi/dvb/video-freeze.rst @@ -44,14 +44,14 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call suspends the live video stream being played. Decoding and playing are frozen. It is then possible to restart the decoding and playing process of the video stream using the VIDEO_CONTINUE command. If VIDEO_SOURCE_MEMORY is selected in the ioctl call -VIDEO_SELECT_SOURCE, the DVB subsystem will not decode any more data +VIDEO_SELECT_SOURCE, the Digital TV subsystem will not decode any more data until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed. diff --git a/Documentation/media/uapi/dvb/video-get-event.rst b/Documentation/media/uapi/dvb/video-get-event.rst index 6ad14cdb894a..b4f53616db9a 100644 --- a/Documentation/media/uapi/dvb/video-get-event.rst +++ b/Documentation/media/uapi/dvb/video-get-event.rst @@ -50,7 +50,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To get events from a V4L2 decoder +This ioctl is for Digital TV devices only. To get events from a V4L2 decoder use the V4L2 :ref:`VIDIOC_DQEVENT` ioctl instead. This ioctl call returns an event of type video_event if available. If diff --git a/Documentation/media/uapi/dvb/video-play.rst b/Documentation/media/uapi/dvb/video-play.rst index 3f66ae3b7e35..2124120aec22 100644 --- a/Documentation/media/uapi/dvb/video-play.rst +++ b/Documentation/media/uapi/dvb/video-play.rst @@ -44,7 +44,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call asks the Video Device to start playing a video stream diff --git a/Documentation/media/uapi/dvb/video-select-source.rst b/Documentation/media/uapi/dvb/video-select-source.rst index 2f4fbf4b490c..cde6542723ca 100644 --- a/Documentation/media/uapi/dvb/video-select-source.rst +++ b/Documentation/media/uapi/dvb/video-select-source.rst @@ -50,7 +50,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. This ioctl was also supported by the +This ioctl is for Digital TV devices only. This ioctl was also supported by the V4L2 ivtv driver, but that has been replaced by the ivtv-specific ``IVTV_IOC_PASSTHROUGH_MODE`` ioctl. diff --git a/Documentation/media/uapi/dvb/video-stop.rst b/Documentation/media/uapi/dvb/video-stop.rst index fb827effb276..474309ad31c2 100644 --- a/Documentation/media/uapi/dvb/video-stop.rst +++ b/Documentation/media/uapi/dvb/video-stop.rst @@ -60,7 +60,7 @@ Arguments Description ----------- -This ioctl is for DVB devices only. To control a V4L2 decoder use the +This ioctl is for Digital TV devices only. To control a V4L2 decoder use the V4L2 :ref:`VIDIOC_DECODER_CMD` instead. This ioctl call asks the Video Device to stop playing the current diff --git a/Documentation/media/uapi/dvb/video.rst b/Documentation/media/uapi/dvb/video.rst index 60d43fb7ce22..e7d68cd0cf23 100644 --- a/Documentation/media/uapi/dvb/video.rst +++ b/Documentation/media/uapi/dvb/video.rst @@ -2,20 +2,21 @@ .. _dvb_video: -################ -DVB Video Device -################ -The DVB video device controls the MPEG2 video decoder of the DVB -hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data +####################### +Digital TV Video Device +####################### + +The Digital TV video device controls the MPEG2 video decoder of the Digital +TV hardware. It can be accessed through **/dev/dvb/adapter0/video0**. Data types and and ioctl definitions can be accessed by including **linux/dvb/video.h** in your application. -Note that the DVB video device only controls decoding of the MPEG video +Note that the Digital TV video device only controls decoding of the MPEG video stream, not its presentation on the TV or computer screen. On PCs this is typically handled by an associated video4linux device, e.g. **/dev/video**, which allows scaling and defining output windows. -Some DVB cards don’t have their own MPEG decoder, which results in the +Some Digital TV cards don’t have their own MPEG decoder, which results in the omission of the audio and video device as well as the video4linux device. diff --git a/Documentation/media/uapi/dvb/video_h.rst b/Documentation/media/uapi/dvb/video_h.rst deleted file mode 100644 index 3f39b0c4879c..000000000000 --- a/Documentation/media/uapi/dvb/video_h.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _video_h: - -********************* -DVB Video Header File -********************* - -.. kernel-include:: $BUILDDIR/video.h.rst diff --git a/Documentation/media/uapi/gen-errors.rst b/Documentation/media/uapi/gen-errors.rst index d39e34d1b19d..689d3b101ede 100644 --- a/Documentation/media/uapi/gen-errors.rst +++ b/Documentation/media/uapi/gen-errors.rst @@ -17,9 +17,7 @@ Generic Error Codes :widths: 1 16 - - .. row 1 - - - ``EAGAIN`` (aka ``EWOULDBLOCK``) + - - ``EAGAIN`` (aka ``EWOULDBLOCK``) - The ioctl can't be handled because the device is in state where it can't perform it. This could happen for example in case where @@ -27,15 +25,11 @@ Generic Error Codes is also returned when the ioctl would need to wait for an event, but the device was opened in non-blocking mode. - - .. row 2 - - - ``EBADF`` + - - ``EBADF`` - The file descriptor is not a valid. - - .. row 3 - - - ``EBUSY`` + - - ``EBUSY`` - The ioctl can't be handled because the device is busy. This is typically return while device is streaming, and an ioctl tried to @@ -44,64 +38,53 @@ Generic Error Codes ioctl must not be retried without performing another action to fix the problem first (typically: stop the stream before retrying). - - .. row 4 - - - ``EFAULT`` + - - ``EFAULT`` - There was a failure while copying data from/to userspace, probably caused by an invalid pointer reference. - - .. row 5 - - - ``EINVAL`` + - - ``EINVAL`` - One or more of the ioctl parameters are invalid or out of the allowed range. This is a widely used error code. See the individual ioctl requests for specific causes. - - .. row 6 - - - ``ENODEV`` + - - ``ENODEV`` - Device not found or was removed. - - .. row 7 - - - ``ENOMEM`` + - - ``ENOMEM`` - There's not enough memory to handle the desired operation. - - .. row 8 - - - ``ENOTTY`` + - - ``ENOTTY`` - The ioctl is not supported by the driver, actually meaning that the required functionality is not available, or the file descriptor is not for a media device. - - .. row 9 - - - ``ENOSPC`` + - - ``ENOSPC`` - On USB devices, the stream ioctl's can return this error, meaning that this request would overcommit the usb bandwidth reserved for periodic transfers (up to 80% of the USB bandwidth). - - .. row 10 - - - ``EPERM`` + - - ``EPERM`` - Permission denied. Can be returned if the device needs write permission, or some special capabilities is needed (e. g. root) - - .. row 11 - - - ``EIO`` + - - ``EIO`` - I/O error. Typically used when there are problems communicating with a hardware device. This could indicate broken or flaky hardware. It's a 'Something is wrong, I give up!' type of error. + - - ``ENXIO`` + + - No device corresponding to this device special file exists. + + .. note:: #. This list is not exhaustive; ioctls may return other error codes. diff --git a/Documentation/media/uapi/mediactl/media-controller.rst b/Documentation/media/uapi/mediactl/media-controller.rst index 7ae38d48969e..0eea4f9a07d5 100644 --- a/Documentation/media/uapi/mediactl/media-controller.rst +++ b/Documentation/media/uapi/mediactl/media-controller.rst @@ -8,7 +8,9 @@ Part IV - Media Controller API ############################## -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst index 0fd329279bef..b59ce149efb5 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-enum-entities.rst @@ -51,7 +51,7 @@ id's until they get an error. .. c:type:: media_entity_desc -.. tabularcolumns:: |p{1.5cm}|p{1.5cm}|p{1.5cm}|p{1.5cm}|p{11.5cm}| +.. tabularcolumns:: |p{1.5cm}|p{1.7cm}|p{1.6cm}|p{1.5cm}|p{11.2cm}| .. flat-table:: struct media_entity_desc :header-rows: 0 diff --git a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst index add8281494f8..997e6b17440d 100644 --- a/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst +++ b/Documentation/media/uapi/mediactl/media-ioc-g-topology.rst @@ -46,7 +46,7 @@ other values untouched. If the ``topology_version`` remains the same, the ioctl should fill the desired arrays with the media graph elements. -.. tabularcolumns:: |p{1.6cm}|p{3.2cm}|p{12.7cm}| +.. tabularcolumns:: |p{1.6cm}|p{3.4cm}|p{12.5cm}| .. c:type:: media_v2_topology diff --git a/Documentation/media/uapi/mediactl/media-types.rst b/Documentation/media/uapi/mediactl/media-types.rst index 71078565d644..8d64b0c06ebc 100644 --- a/Documentation/media/uapi/mediactl/media-types.rst +++ b/Documentation/media/uapi/mediactl/media-types.rst @@ -5,7 +5,7 @@ Types and flags used to represent the media graph elements ========================================================== -.. tabularcolumns:: |p{8.0cm}|p{10.5cm}| +.. tabularcolumns:: |p{8.2cm}|p{10.3cm}| .. _media-entity-type: diff --git a/Documentation/media/uapi/rc/rc-sysfs-nodes.rst b/Documentation/media/uapi/rc/rc-sysfs-nodes.rst index 3476ae29708f..2d01358d5504 100644 --- a/Documentation/media/uapi/rc/rc-sysfs-nodes.rst +++ b/Documentation/media/uapi/rc/rc-sysfs-nodes.rst @@ -34,9 +34,9 @@ receiver device where N is the number of the receiver. /sys/class/rc/rcN/protocols =========================== -Reading this file returns a list of available protocols, something like: +Reading this file returns a list of available protocols, something like:: -``rc5 [rc6] nec jvc [sony]`` + rc5 [rc6] nec jvc [sony] Enabled protocols are shown in [] brackets. @@ -90,11 +90,11 @@ This value may be reset to 0 if the current protocol is altered. ================================== Reading this file returns a list of available protocols to use for the -wakeup filter, something like: +wakeup filter, something like:: -``rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce`` + rc-5 nec nec-x rc-6-0 rc-6-6a-24 [rc-6-6a-32] rc-6-mce -Note that protocol variants are listed, so "nec", "sony", "rc-5", "rc-6" +Note that protocol variants are listed, so ``nec``, ``sony``, ``rc-5``, ``rc-6`` have their different bit length encodings listed if available. Note that all protocol variants are listed. diff --git a/Documentation/media/uapi/rc/remote_controllers.rst b/Documentation/media/uapi/rc/remote_controllers.rst index 3e25cc9f65e0..46a8acb82125 100644 --- a/Documentation/media/uapi/rc/remote_controllers.rst +++ b/Documentation/media/uapi/rc/remote_controllers.rst @@ -8,7 +8,9 @@ Part III - Remote Controller API ################################ -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents diff --git a/Documentation/media/uapi/v4l/pixfmt-006.rst b/Documentation/media/uapi/v4l/colorspaces-defs.rst similarity index 98% rename from Documentation/media/uapi/v4l/pixfmt-006.rst rename to Documentation/media/uapi/v4l/colorspaces-defs.rst index 7ae7dcf73f63..410907fe9415 100644 --- a/Documentation/media/uapi/v4l/pixfmt-006.rst +++ b/Documentation/media/uapi/v4l/colorspaces-defs.rst @@ -76,6 +76,8 @@ whole range, 0-255, dividing the angular value by 1.41. The enum .. c:type:: v4l2_xfer_func +.. tabularcolumns:: |p{5.5cm}|p{12.0cm}| + .. flat-table:: V4L2 Transfer Function :header-rows: 1 :stub-columns: 0 @@ -97,7 +99,7 @@ whole range, 0-255, dividing the angular value by 1.41. The enum * - ``V4L2_XFER_FUNC_DCI_P3`` - Use the DCI-P3 transfer function. * - ``V4L2_XFER_FUNC_SMPTE2084`` - - Use the SMPTE 2084 transfer function. + - Use the SMPTE 2084 transfer function. See :ref:`xf-smpte-2084`. diff --git a/Documentation/media/uapi/v4l/pixfmt-007.rst b/Documentation/media/uapi/v4l/colorspaces-details.rst similarity index 92% rename from Documentation/media/uapi/v4l/pixfmt-007.rst rename to Documentation/media/uapi/v4l/colorspaces-details.rst index 0c30ee2577d3..b5d551b9cc8f 100644 --- a/Documentation/media/uapi/v4l/pixfmt-007.rst +++ b/Documentation/media/uapi/v4l/colorspaces-details.rst @@ -418,6 +418,11 @@ Inverse Transfer function: L = \left( \frac{L' + 0.099}{1.099}\right) ^{\frac{1}{0.45} }\text{, for } L' \ge 0.081 +Please note that while Rec. 709 is defined as the default transfer function +by the :ref:`itu2020` standard, in practice this colorspace is often used +with the :ref:`xf-smpte-2084`. In particular Ultra HD Blu-ray discs use +this combination. + The luminance (Y') and color difference (Cb and Cr) are obtained with the following ``V4L2_YCBCR_ENC_BT2020`` encoding: @@ -758,3 +763,45 @@ scaled to [-128…128] and then clipped to [-128…127]. ``V4L2_COLORSPACE_JPEG`` can be considered to be an abbreviation for ``V4L2_COLORSPACE_SRGB``, ``V4L2_YCBCR_ENC_601`` and ``V4L2_QUANTIZATION_FULL_RANGE``. + +*************************************** +Detailed Transfer Function Descriptions +*************************************** + +.. _xf-smpte-2084: + +Transfer Function SMPTE 2084 (V4L2_XFER_FUNC_SMPTE2084) +======================================================= + +The :ref:`smpte2084` standard defines the transfer function used by +High Dynamic Range content. + +Constants: + m1 = (2610 / 4096) / 4 + + m2 = (2523 / 4096) * 128 + + c1 = 3424 / 4096 + + c2 = (2413 / 4096) * 32 + + c3 = (2392 / 4096) * 32 + +Transfer function: + L' = ((c1 + c2 * L\ :sup:`m1`) / (1 + c3 * L\ :sup:`m1`))\ :sup:`m2` + +Inverse Transfer function: + L = (max(L':sup:`1/m2` - c1, 0) / (c2 - c3 * + L'\ :sup:`1/m2`))\ :sup:`1/m1` + +Take care when converting between this transfer function and non-HDR transfer +functions: the linear RGB values [0…1] of HDR content map to a luminance range +of 0 to 10000 cd/m\ :sup:`2` whereas the linear RGB values of non-HDR (aka +Standard Dynamic Range or SDR) map to a luminance range of 0 to 100 cd/m\ :sup:`2`. + +To go from SDR to HDR you will have to divide L by 100 first. To go in the other +direction you will have to multiply L by 100. Of course, this clamps all +luminance values over 100 cd/m\ :sup:`2` to 100 cd/m\ :sup:`2`. + +There are better methods, see e.g. :ref:`colimg` for more in-depth information +about this. diff --git a/Documentation/media/uapi/v4l/dev-meta.rst b/Documentation/media/uapi/v4l/dev-meta.rst index 62518adfe37b..f7ac8d0d3af1 100644 --- a/Documentation/media/uapi/v4l/dev-meta.rst +++ b/Documentation/media/uapi/v4l/dev-meta.rst @@ -42,6 +42,8 @@ the :c:type:`v4l2_format` structure to 0. .. _v4l2-meta-format: +.. tabularcolumns:: |p{1.4cm}|p{2.2cm}|p{13.9cm}| + .. flat-table:: struct v4l2_meta_format :header-rows: 0 :stub-columns: 0 diff --git a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst b/Documentation/media/uapi/v4l/dev-sliced-vbi.rst index 5f6d534ea73b..9d6c860271cb 100644 --- a/Documentation/media/uapi/v4l/dev-sliced-vbi.rst +++ b/Documentation/media/uapi/v4l/dev-sliced-vbi.rst @@ -105,7 +105,13 @@ which may return ``EBUSY`` can be the struct v4l2_sliced_vbi_format ----------------------------- -.. tabularcolumns:: |p{1.0cm}|p{4.5cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}| +.. raw:: latex + + \begingroup + \scriptsize + \setlength{\tabcolsep}{2pt} + +.. tabularcolumns:: |p{.75cm}|p{3.3cm}|p{3.4cm}|p{3.4cm}|p{3.4cm}| .. cssclass:: longtable @@ -199,6 +205,9 @@ struct v4l2_sliced_vbi_format Applications and drivers must set it to zero. +.. raw:: latex + + \endgroup .. _vbi-services2: @@ -207,9 +216,9 @@ Sliced VBI services .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \footnotesize -.. tabularcolumns:: |p{5.0cm}|p{1.4cm}|p{3.0cm}|p{2.5cm}|p{9.0cm}| +.. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{2.4cm}|p{2.0cm}|p{7.3cm}| .. flat-table:: :header-rows: 1 @@ -263,7 +272,7 @@ Sliced VBI services .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Drivers may return an ``EINVAL`` error code when applications attempt to @@ -457,7 +466,7 @@ number). struct v4l2_mpeg_vbi_fmt_ivtv ----------------------------- -.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{1.0cm}|p{11.5cm}| +.. tabularcolumns:: |p{1.0cm}|p{3.8cm}|p{1.0cm}|p{11.2cm}| .. flat-table:: :header-rows: 0 @@ -525,7 +534,7 @@ Magic Constants for struct v4l2_mpeg_vbi_fmt_ivtv magic field structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 ------------------------------------------------- -.. tabularcolumns:: |p{4.4cm}|p{2.4cm}|p{10.7cm}| +.. tabularcolumns:: |p{4.9cm}|p{2.4cm}|p{10.2cm}| .. flat-table:: :header-rows: 0 @@ -574,7 +583,7 @@ structs v4l2_mpeg_vbi_itv0 and v4l2_mpeg_vbi_ITV0 struct v4l2_mpeg_vbi_ITV0 ------------------------- -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| +.. tabularcolumns:: |p{4.9cm}|p{4.4cm}|p{8.2cm}| .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/dev-subdev.rst b/Documentation/media/uapi/v4l/dev-subdev.rst index f0e762167730..d20d945803a7 100644 --- a/Documentation/media/uapi/v4l/dev-subdev.rst +++ b/Documentation/media/uapi/v4l/dev-subdev.rst @@ -204,9 +204,9 @@ list entity names and pad numbers). .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \tiny -.. tabularcolumns:: |p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}|p{4.5cm}| +.. tabularcolumns:: |p{2.0cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}|p{2.3cm}| .. _sample-pipeline-config: @@ -253,7 +253,7 @@ list entity names and pad numbers). .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize 1. Initial state. The sensor source pad format is set to its native 3MP size and V4L2_MBUS_FMT_SGRBG8_1X8 media bus code. Formats on the @@ -370,7 +370,7 @@ circumstances. This may also cause the accessed rectangle to be adjusted by the driver, depending on the properties of the underlying hardware. The coordinates to a step always refer to the actual size of the -previous step. The exception to this rule is the source compose +previous step. The exception to this rule is the sink compose rectangle, which refers to the sink compose bounds rectangle --- if it is supported by the hardware. diff --git a/Documentation/media/uapi/v4l/driver.rst b/Documentation/media/uapi/v4l/driver.rst deleted file mode 100644 index 2319b383f0a4..000000000000 --- a/Documentation/media/uapi/v4l/driver.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -.. _driver: - -*********************** -V4L2 Driver Programming -*********************** - -to do diff --git a/Documentation/media/uapi/v4l/extended-controls.rst b/Documentation/media/uapi/v4l/extended-controls.rst index 9acc9cad49e2..a3e81c1d276b 100644 --- a/Documentation/media/uapi/v4l/extended-controls.rst +++ b/Documentation/media/uapi/v4l/extended-controls.rst @@ -942,21 +942,21 @@ enum v4l2_mpeg_video_mpeg4_level - :header-rows: 0 :stub-columns: 0 - * - ``V4L2_MPEG_VIDEO_LEVEL_0`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0`` - Level 0 - * - ``V4L2_MPEG_VIDEO_LEVEL_0B`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B`` - Level 0b - * - ``V4L2_MPEG_VIDEO_LEVEL_1`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_1`` - Level 1 - * - ``V4L2_MPEG_VIDEO_LEVEL_2`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_2`` - Level 2 - * - ``V4L2_MPEG_VIDEO_LEVEL_3`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3`` - Level 3 - * - ``V4L2_MPEG_VIDEO_LEVEL_3B`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B`` - Level 3b - * - ``V4L2_MPEG_VIDEO_LEVEL_4`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_4`` - Level 4 - * - ``V4L2_MPEG_VIDEO_LEVEL_5`` + * - ``V4L2_MPEG_VIDEO_MPEG4_LEVEL_5`` - Level 5 @@ -1028,15 +1028,15 @@ enum v4l2_mpeg_video_mpeg4_profile - :header-rows: 0 :stub-columns: 0 - * - ``V4L2_MPEG_VIDEO_PROFILE_SIMPLE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE`` - Simple profile - * - ``V4L2_MPEG_VIDEO_PROFILE_ADVANCED_SIMPLE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE`` - Advanced Simple profile - * - ``V4L2_MPEG_VIDEO_PROFILE_CORE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE`` - Core profile - * - ``V4L2_MPEG_VIDEO_PROFILE_SIMPLE_SCALABLE`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE`` - Simple Scalable profile - * - ``V4L2_MPEG_VIDEO_PROFILE_ADVANCED_CODING_EFFICIENCY`` + * - ``V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY`` - @@ -1922,9 +1922,9 @@ enum v4l2_vp8_golden_frame_sel - .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \footnotesize -.. tabularcolumns:: |p{11.0cm}|p{10.0cm}| +.. tabularcolumns:: |p{9.0cm}|p{8.0cm}| .. flat-table:: :header-rows: 0 @@ -1940,7 +1940,7 @@ enum v4l2_vp8_golden_frame_sel - .. raw:: latex - \end{adjustbox} + \normalsize ``V4L2_CID_MPEG_VIDEO_VPX_MIN_QP (integer)`` diff --git a/Documentation/media/uapi/v4l/format.rst b/Documentation/media/uapi/v4l/format.rst index 452c6d59cad5..3e3efb0e349e 100644 --- a/Documentation/media/uapi/v4l/format.rst +++ b/Documentation/media/uapi/v4l/format.rst @@ -78,7 +78,7 @@ output devices is available. [#f1]_ The :ref:`VIDIOC_ENUM_FMT` ioctl must be supported by all drivers exchanging image data with applications. - **Important** +.. important:: Drivers are not supposed to convert image formats in kernel space. They must enumerate only formats directly supported by the hardware. diff --git a/Documentation/media/uapi/v4l/pixfmt-008.rst b/Documentation/media/uapi/v4l/pixfmt-008.rst deleted file mode 100644 index 4bec79784bdd..000000000000 --- a/Documentation/media/uapi/v4l/pixfmt-008.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. -*- coding: utf-8; mode: rst -*- - -*************************************** -Detailed Transfer Function Descriptions -*************************************** - - -.. _xf-smpte-2084: - -Transfer Function SMPTE 2084 (V4L2_XFER_FUNC_SMPTE2084) -======================================================= - -The :ref:`smpte2084` standard defines the transfer function used by -High Dynamic Range content. - -Constants: - m1 = (2610 / 4096) / 4 - - m2 = (2523 / 4096) * 128 - - c1 = 3424 / 4096 - - c2 = (2413 / 4096) * 32 - - c3 = (2392 / 4096) * 32 - -Transfer function: - L' = ((c1 + c2 * L\ :sup:`m1`) / (1 + c3 * L\ :sup:`m1`))\ :sup:`m2` - -Inverse Transfer function: - L = (max(L':sup:`1/m2` - c1, 0) / (c2 - c3 * - L'\ :sup:`1/m2`))\ :sup:`1/m1` diff --git a/Documentation/media/uapi/v4l/pixfmt-013.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-013.rst rename to Documentation/media/uapi/v4l/pixfmt-compressed.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-004.rst b/Documentation/media/uapi/v4l/pixfmt-intro.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-004.rst rename to Documentation/media/uapi/v4l/pixfmt-intro.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-inzi.rst b/Documentation/media/uapi/v4l/pixfmt-inzi.rst index 9849e799f205..75272f80bc8a 100644 --- a/Documentation/media/uapi/v4l/pixfmt-inzi.rst +++ b/Documentation/media/uapi/v4l/pixfmt-inzi.rst @@ -34,11 +34,12 @@ The second plane provides 16-bit per-pixel Depth data arranged in Each cell is a 16-bit word with more significant data stored at higher memory address (byte order is little-endian). + .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \small -.. tabularcolumns:: |p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}| +.. tabularcolumns:: |p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}| .. flat-table:: :header-rows: 0 @@ -78,4 +79,4 @@ memory address (byte order is little-endian). .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize diff --git a/Documentation/media/uapi/v4l/pixfmt-m420.rst b/Documentation/media/uapi/v4l/pixfmt-m420.rst index 7dd47c071e2f..6703f4079c3e 100644 --- a/Documentation/media/uapi/v4l/pixfmt-m420.rst +++ b/Documentation/media/uapi/v4l/pixfmt-m420.rst @@ -66,7 +66,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-nv12.rst b/Documentation/media/uapi/v4l/pixfmt-nv12.rst index 5b45a6d2ac95..2776b41377d5 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv12.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv12.rst @@ -71,7 +71,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt-nv12m.rst b/Documentation/media/uapi/v4l/pixfmt-nv12m.rst index de3051fd6b50..c1a2779f604c 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv12m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv12m.rst @@ -83,7 +83,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-nv16.rst b/Documentation/media/uapi/v4l/pixfmt-nv16.rst index 8ceba79ff636..f0fdad3006cf 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv16.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv16.rst @@ -79,7 +79,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-nv16m.rst b/Documentation/media/uapi/v4l/pixfmt-nv16m.rst index 4d46ab39f9f1..c45f036763e7 100644 --- a/Documentation/media/uapi/v4l/pixfmt-nv16m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-nv16m.rst @@ -83,7 +83,7 @@ Each cell is one byte. - Cr\ :sub:`32` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst index 3fdb34ce2f09..8edf65c80660 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-hsv.rst @@ -17,11 +17,14 @@ cylinder: 0 being the smallest value and 255 the maximum. The values are packed in 24 or 32 bit formats. + .. raw:: latex - \newline\begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} -.. tabularcolumns:: |p{4.2cm}|p{1.0cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| +.. tabularcolumns:: |p{2.0cm}|p{0.54cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| .. _packed-hsv-formats: @@ -33,11 +36,8 @@ The values are packed in 24 or 32 bit formats. - Code - - :cspan:`7` Byte 0 in memory - - - :cspan:`7` Byte 1 - - - :cspan:`7` Byte 2 - - - :cspan:`7` Byte 3 * - - @@ -50,7 +50,7 @@ The values are packed in 24 or 32 bit formats. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -59,7 +59,7 @@ The values are packed in 24 or 32 bit formats. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -68,7 +68,7 @@ The values are packed in 24 or 32 bit formats. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -90,7 +90,7 @@ The values are packed in 24 or 32 bit formats. - - - - - + - h\ :sub:`7` - h\ :sub:`6` - h\ :sub:`5` @@ -99,7 +99,7 @@ The values are packed in 24 or 32 bit formats. - h\ :sub:`2` - h\ :sub:`1` - h\ :sub:`0` - - + - s\ :sub:`7` - s\ :sub:`6` - s\ :sub:`5` @@ -108,7 +108,7 @@ The values are packed in 24 or 32 bit formats. - s\ :sub:`2` - s\ :sub:`1` - s\ :sub:`0` - - + - v\ :sub:`7` - v\ :sub:`6` - v\ :sub:`5` @@ -130,7 +130,7 @@ The values are packed in 24 or 32 bit formats. - h\ :sub:`2` - h\ :sub:`1` - h\ :sub:`0` - - + - s\ :sub:`7` - s\ :sub:`6` - s\ :sub:`5` @@ -139,7 +139,7 @@ The values are packed in 24 or 32 bit formats. - s\ :sub:`2` - s\ :sub:`1` - s\ :sub:`0` - - + - v\ :sub:`7` - v\ :sub:`6` - v\ :sub:`5` @@ -149,9 +149,9 @@ The values are packed in 24 or 32 bit formats. - v\ :sub:`1` - v\ :sub:`0` - - - + .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup Bit 7 is the most significant bit. diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst index 84fcbcb74171..4938d9655a41 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-rgb.rst @@ -16,9 +16,12 @@ next to each other in memory. .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} + +.. tabularcolumns:: |p{2.3cm}|p{1.6cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| -.. tabularcolumns:: |p{4.5cm}|p{3.3cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| .. _rgb-formats: @@ -28,17 +31,12 @@ next to each other in memory. * - Identifier - Code - - - :cspan:`7` Byte 0 in memory - - - :cspan:`7` Byte 1 - - - :cspan:`7` Byte 2 - - - :cspan:`7` Byte 3 * - - - - Bit - 7 - 6 - 5 @@ -47,7 +45,7 @@ next to each other in memory. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -56,7 +54,7 @@ next to each other in memory. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -65,7 +63,7 @@ next to each other in memory. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -78,7 +76,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_RGB332`` - 'RGB1' - - + - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` @@ -87,11 +85,12 @@ next to each other in memory. - g\ :sub:`0` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-ARGB444: - ``V4L2_PIX_FMT_ARGB444`` - 'AR12' - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -100,7 +99,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a\ :sub:`3` - a\ :sub:`2` - a\ :sub:`1` @@ -109,11 +108,12 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-XRGB444: - ``V4L2_PIX_FMT_XRGB444`` - 'XR12' - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -122,7 +122,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - - - @@ -131,11 +131,12 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-ARGB555: - ``V4L2_PIX_FMT_ARGB555`` - 'AR15' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -144,7 +145,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -153,11 +154,12 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-XRGB555: - ``V4L2_PIX_FMT_XRGB555`` - 'XR15' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -166,7 +168,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - - r\ :sub:`4` - r\ :sub:`3` @@ -175,11 +177,12 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-RGB565: - ``V4L2_PIX_FMT_RGB565`` - 'RGBP' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -188,7 +191,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - r\ :sub:`4` - r\ :sub:`3` - r\ :sub:`2` @@ -197,11 +200,12 @@ next to each other in memory. - g\ :sub:`5` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-ARGB555X: - ``V4L2_PIX_FMT_ARGB555X`` - 'AR15' | (1 << 31) - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -210,7 +214,7 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -219,11 +223,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-XRGB555X: - ``V4L2_PIX_FMT_XRGB555X`` - 'XR15' | (1 << 31) - - + - - r\ :sub:`4` - r\ :sub:`3` @@ -232,7 +237,7 @@ next to each other in memory. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -241,11 +246,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-RGB565X: - ``V4L2_PIX_FMT_RGB565X`` - 'RGBR' - - + - r\ :sub:`4` - r\ :sub:`3` - r\ :sub:`2` @@ -254,7 +260,7 @@ next to each other in memory. - g\ :sub:`5` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -263,11 +269,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-BGR24: - ``V4L2_PIX_FMT_BGR24`` - 'BGR3' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -276,7 +283,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -285,7 +292,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -294,11 +301,12 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-RGB24: - ``V4L2_PIX_FMT_RGB24`` - 'RGB3' - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -307,7 +315,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -316,7 +324,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -325,11 +333,12 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-BGR666: - ``V4L2_PIX_FMT_BGR666`` - 'BGRH' - - + - b\ :sub:`5` - b\ :sub:`4` - b\ :sub:`3` @@ -338,7 +347,7 @@ next to each other in memory. - b\ :sub:`0` - g\ :sub:`5` - g\ :sub:`4` - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -347,7 +356,7 @@ next to each other in memory. - r\ :sub:`4` - r\ :sub:`3` - r\ :sub:`2` - - + - r\ :sub:`1` - r\ :sub:`0` - @@ -356,7 +365,7 @@ next to each other in memory. - - - - - + - - - @@ -369,7 +378,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_ABGR32`` - 'AR24' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -378,7 +387,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -387,7 +396,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -396,7 +405,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -409,7 +418,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_XBGR32`` - 'XR24' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -418,7 +427,7 @@ next to each other in memory. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -427,7 +436,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -436,7 +445,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - - - @@ -449,7 +458,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_ARGB32`` - 'BA24' - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -458,7 +467,7 @@ next to each other in memory. - a\ :sub:`2` - a\ :sub:`1` - a\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -467,7 +476,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -476,7 +485,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -489,6 +498,7 @@ next to each other in memory. - ``V4L2_PIX_FMT_XRGB32`` - 'BX24' + - - - @@ -497,8 +507,7 @@ next to each other in memory. - - - - - - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -507,7 +516,7 @@ next to each other in memory. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -516,7 +525,7 @@ next to each other in memory. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -528,7 +537,7 @@ next to each other in memory. .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup .. note:: Bit 7 is the most significant bit. @@ -562,9 +571,9 @@ Each cell is one byte. .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \small -.. tabularcolumns:: |p{4.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.1cm}|p{1.3cm}| +.. tabularcolumns:: |p{3.1cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}|p{0.8cm}| .. flat-table:: RGB byte order :header-rows: 0 @@ -626,19 +635,21 @@ Each cell is one byte. .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Formats defined in :ref:`rgb-formats-deprecated` are deprecated and must not be used by new drivers. They are documented here for reference. -The meaning of their alpha bits (a) is ill-defined and interpreted as in +The meaning of their alpha bits ``(a)`` are ill-defined and interpreted as in either the corresponding ARGB or XRGB format, depending on the driver. .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} -.. tabularcolumns:: |p{4.2cm}|p{1.0cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| +.. tabularcolumns:: |p{2.2cm}|p{0.60cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| .. _rgb-formats-deprecated: @@ -648,17 +659,15 @@ either the corresponding ARGB or XRGB format, depending on the driver. * - Identifier - Code - - - :cspan:`7` Byte 0 in memory - - + - :cspan:`7` Byte 1 - - + - :cspan:`7` Byte 2 - - + - :cspan:`7` Byte 3 * - - - - Bit - 7 - 6 - 5 @@ -667,7 +676,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -676,7 +685,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -685,7 +694,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -698,7 +707,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - ``V4L2_PIX_FMT_RGB444`` - 'R444' - - + - g\ :sub:`3` - g\ :sub:`2` - g\ :sub:`1` @@ -707,7 +716,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a\ :sub:`3` - a\ :sub:`2` - a\ :sub:`1` @@ -716,11 +725,12 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` + - * .. _V4L2-PIX-FMT-RGB555: - ``V4L2_PIX_FMT_RGB555`` - 'RGBO' - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -729,7 +739,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -738,11 +748,12 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` + - * .. _V4L2-PIX-FMT-RGB555X: - ``V4L2_PIX_FMT_RGB555X`` - 'RGBQ' - - + - a - r\ :sub:`4` - r\ :sub:`3` @@ -751,7 +762,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`0` - g\ :sub:`4` - g\ :sub:`3` - - + - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` @@ -760,11 +771,12 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` + - * .. _V4L2-PIX-FMT-BGR32: - ``V4L2_PIX_FMT_BGR32`` - 'BGR4' - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -773,7 +785,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - b\ :sub:`2` - b\ :sub:`1` - b\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -782,7 +794,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -791,7 +803,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -804,7 +816,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - ``V4L2_PIX_FMT_RGB32`` - 'RGB4' - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -813,7 +825,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - a\ :sub:`2` - a\ :sub:`1` - a\ :sub:`0` - - + - r\ :sub:`7` - r\ :sub:`6` - r\ :sub:`5` @@ -822,7 +834,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - r\ :sub:`2` - r\ :sub:`1` - r\ :sub:`0` - - + - g\ :sub:`7` - g\ :sub:`6` - g\ :sub:`5` @@ -831,7 +843,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. - g\ :sub:`2` - g\ :sub:`1` - g\ :sub:`0` - - + - b\ :sub:`7` - b\ :sub:`6` - b\ :sub:`5` @@ -843,7 +855,7 @@ either the corresponding ARGB or XRGB format, depending on the driver. .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup A test utility to determine which RGB formats a driver actually supports is available from the LinuxTV v4l-dvb repository. See diff --git a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst b/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst index ebc8fcc937ad..d7644b411ccc 100644 --- a/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-packed-yuv.rst @@ -12,13 +12,16 @@ Description Similar to the packed RGB formats these formats store the Y, Cb and Cr component of each pixel in one 16 or 32 bit word. + .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} .. _packed-yuv-formats: -.. tabularcolumns:: |p{4.5cm}|p{3.3cm}|p{0.7cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.2cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{0.4cm}|p{1.7cm}| +.. tabularcolumns:: |p{2.0cm}|p{0.67cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}|p{0.29cm}| .. flat-table:: Packed YUV Image Formats :header-rows: 2 @@ -26,17 +29,16 @@ component of each pixel in one 16 or 32 bit word. * - Identifier - Code - - + - :cspan:`7` Byte 0 in memory - - + - :cspan:`7` Byte 1 - - + - :cspan:`7` Byte 2 - - + - :cspan:`7` Byte 3 * - - - - Bit - 7 - 6 - 5 @@ -45,7 +47,7 @@ component of each pixel in one 16 or 32 bit word. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -54,7 +56,7 @@ component of each pixel in one 16 or 32 bit word. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -63,7 +65,7 @@ component of each pixel in one 16 or 32 bit word. - 2 - 1 - 0 - - + - 7 - 6 - 5 @@ -76,7 +78,7 @@ component of each pixel in one 16 or 32 bit word. - ``V4L2_PIX_FMT_YUV444`` - 'Y444' - - + - Cb\ :sub:`3` - Cb\ :sub:`2` - Cb\ :sub:`1` @@ -85,7 +87,7 @@ component of each pixel in one 16 or 32 bit word. - Cr\ :sub:`2` - Cr\ :sub:`1` - Cr\ :sub:`0` - - + - a\ :sub:`3` - a\ :sub:`2` - a\ :sub:`1` @@ -94,11 +96,12 @@ component of each pixel in one 16 or 32 bit word. - Y'\ :sub:`2` - Y'\ :sub:`1` - Y'\ :sub:`0` + - * .. _V4L2-PIX-FMT-YUV555: - ``V4L2_PIX_FMT_YUV555`` - 'YUVO' - - + - Cb\ :sub:`2` - Cb\ :sub:`1` - Cb\ :sub:`0` @@ -107,7 +110,7 @@ component of each pixel in one 16 or 32 bit word. - Cr\ :sub:`2` - Cr\ :sub:`1` - Cr\ :sub:`0` - - + - a - Y'\ :sub:`4` - Y'\ :sub:`3` @@ -116,11 +119,12 @@ component of each pixel in one 16 or 32 bit word. - Y'\ :sub:`0` - Cb\ :sub:`4` - Cb\ :sub:`3` + - * .. _V4L2-PIX-FMT-YUV565: - ``V4L2_PIX_FMT_YUV565`` - 'YUVP' - - + - Cb\ :sub:`2` - Cb\ :sub:`1` - Cb\ :sub:`0` @@ -129,7 +133,7 @@ component of each pixel in one 16 or 32 bit word. - Cr\ :sub:`2` - Cr\ :sub:`1` - Cr\ :sub:`0` - - + - Y'\ :sub:`4` - Y'\ :sub:`3` - Y'\ :sub:`2` @@ -138,11 +142,12 @@ component of each pixel in one 16 or 32 bit word. - Cb\ :sub:`5` - Cb\ :sub:`4` - Cb\ :sub:`3` + - * .. _V4L2-PIX-FMT-YUV32: - ``V4L2_PIX_FMT_YUV32`` - 'YUV4' - - + - a\ :sub:`7` - a\ :sub:`6` - a\ :sub:`5` @@ -151,7 +156,7 @@ component of each pixel in one 16 or 32 bit word. - a\ :sub:`2` - a\ :sub:`1` - a\ :sub:`0` - - + - Y'\ :sub:`7` - Y'\ :sub:`6` - Y'\ :sub:`5` @@ -160,7 +165,7 @@ component of each pixel in one 16 or 32 bit word. - Y'\ :sub:`2` - Y'\ :sub:`1` - Y'\ :sub:`0` - - + - Cb\ :sub:`7` - Cb\ :sub:`6` - Cb\ :sub:`5` @@ -169,7 +174,7 @@ component of each pixel in one 16 or 32 bit word. - Cb\ :sub:`2` - Cb\ :sub:`1` - Cb\ :sub:`0` - - + - Cr\ :sub:`7` - Cr\ :sub:`6` - Cr\ :sub:`5` @@ -181,7 +186,7 @@ component of each pixel in one 16 or 32 bit word. .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup .. note:: diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst index b0f35136021e..4cc27195dc79 100644 --- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst +++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst @@ -17,4 +17,5 @@ RGB Formats pixfmt-srggb10alaw8 pixfmt-srggb10dpcm8 pixfmt-srggb12 + pixfmt-srggb12p pixfmt-srggb16 diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst index b6d426c70ccd..d9e07a4b8b31 100644 --- a/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-srggb10p.rst @@ -33,11 +33,7 @@ of a small V4L2_PIX_FMT_SBGGR10P image: **Byte Order.** Each cell is one byte. -.. raw:: latex - - \newline\newline\begin{adjustbox}{width=\columnwidth} - -.. tabularcolumns:: |p{2.0cm}|p{1.3cm}|p{1.3cm}|p{1.3cm}|p{1.3cm}|p{10.9cm}| +.. tabularcolumns:: |p{2.0cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{1.0cm}|p{5.4cm}| .. flat-table:: :header-rows: 0 @@ -50,6 +46,7 @@ Each cell is one byte. - B\ :sub:`02high` - G\ :sub:`03high` - G\ :sub:`03low`\ (bits 7--6) B\ :sub:`02low`\ (bits 5--4) + G\ :sub:`01low`\ (bits 3--2) B\ :sub:`00low`\ (bits 1--0) * - start + 5: - G\ :sub:`10high` @@ -57,6 +54,7 @@ Each cell is one byte. - G\ :sub:`12high` - R\ :sub:`13high` - R\ :sub:`13low`\ (bits 7--6) G\ :sub:`12low`\ (bits 5--4) + R\ :sub:`11low`\ (bits 3--2) G\ :sub:`10low`\ (bits 1--0) * - start + 10: - B\ :sub:`20high` @@ -64,6 +62,7 @@ Each cell is one byte. - B\ :sub:`22high` - G\ :sub:`23high` - G\ :sub:`23low`\ (bits 7--6) B\ :sub:`22low`\ (bits 5--4) + G\ :sub:`21low`\ (bits 3--2) B\ :sub:`20low`\ (bits 1--0) * - start + 15: - G\ :sub:`30high` @@ -71,8 +70,5 @@ Each cell is one byte. - G\ :sub:`32high` - R\ :sub:`33high` - R\ :sub:`33low`\ (bits 7--6) G\ :sub:`32low`\ (bits 5--4) + R\ :sub:`31low`\ (bits 3--2) G\ :sub:`30low`\ (bits 1--0) - -.. raw:: latex - - \end{adjustbox}\newline\newline diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst new file mode 100644 index 000000000000..59918a7913fe --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-srggb12p.rst @@ -0,0 +1,86 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _V4L2-PIX-FMT-SRGGB12P: +.. _v4l2-pix-fmt-sbggr12p: +.. _v4l2-pix-fmt-sgbrg12p: +.. _v4l2-pix-fmt-sgrbg12p: + +******************************************************************************************************************************* +V4L2_PIX_FMT_SRGGB12P ('pRAA'), V4L2_PIX_FMT_SGRBG12P ('pgAA'), V4L2_PIX_FMT_SGBRG12P ('pGAA'), V4L2_PIX_FMT_SBGGR12P ('pBAA'), +******************************************************************************************************************************* + + +12-bit packed Bayer formats + + +Description +=========== + +These four pixel formats are packed raw sRGB / Bayer formats with 12 +bits per colour. Every two consecutive samples are packed into three +bytes. Each of the first two bytes contain the 8 high order bits of +the pixels, and the third byte contains the four least significants +bits of each pixel, in the same order. + +Each n-pixel row contains n/2 green samples and n/2 blue or red +samples, with alternating green-red and green-blue rows. They are +conventionally described as GRGR... BGBG..., RGRG... GBGB..., etc. +Below is an example of a small V4L2_PIX_FMT_SBGGR12P image: + +**Byte Order.** +Each cell is one byte. + +.. tabularcolumns:: |p{2.0cm}|p{1.0cm}|p{1.0cm}|p{2.7cm}|p{1.0cm}|p{1.0cm}|p{2.7cm}| + + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 2 1 1 1 1 1 1 + + + - - start + 0: + - B\ :sub:`00high` + - G\ :sub:`01high` + - G\ :sub:`01low`\ (bits 7--4) + + B\ :sub:`00low`\ (bits 3--0) + - B\ :sub:`02high` + - G\ :sub:`03high` + - G\ :sub:`03low`\ (bits 7--4) + + B\ :sub:`02low`\ (bits 3--0) + + - - start + 6: + - G\ :sub:`10high` + - R\ :sub:`11high` + - R\ :sub:`11low`\ (bits 7--4) + + G\ :sub:`10low`\ (bits 3--0) + - G\ :sub:`12high` + - R\ :sub:`13high` + - R\ :sub:`13low`\ (bits 3--2) + + G\ :sub:`12low`\ (bits 3--0) + - - start + 12: + - B\ :sub:`20high` + - G\ :sub:`21high` + - G\ :sub:`21low`\ (bits 7--4) + + B\ :sub:`20low`\ (bits 3--0) + - B\ :sub:`22high` + - G\ :sub:`23high` + - G\ :sub:`23low`\ (bits 7--4) + + B\ :sub:`22low`\ (bits 3--0) + - - start + 18: + - G\ :sub:`30high` + - R\ :sub:`31high` + - R\ :sub:`31low`\ (bits 7--4) + + G\ :sub:`30low`\ (bits 3--0) + - G\ :sub:`32high` + - R\ :sub:`33high` + - R\ :sub:`33low`\ (bits 3--2) + + G\ :sub:`32low`\ (bits 3--0) diff --git a/Documentation/media/uapi/v4l/pixfmt-uyvy.rst b/Documentation/media/uapi/v4l/pixfmt-uyvy.rst index 30660e04dd0e..ecdc2d94c209 100644 --- a/Documentation/media/uapi/v4l/pixfmt-uyvy.rst +++ b/Documentation/media/uapi/v4l/pixfmt-uyvy.rst @@ -65,7 +65,7 @@ Each cell is one byte. - Y'\ :sub:`33` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-003.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-003.rst rename to Documentation/media/uapi/v4l/pixfmt-v4l2-mplane.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-002.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst similarity index 100% rename from Documentation/media/uapi/v4l/pixfmt-002.rst rename to Documentation/media/uapi/v4l/pixfmt-v4l2.rst diff --git a/Documentation/media/uapi/v4l/pixfmt-vyuy.rst b/Documentation/media/uapi/v4l/pixfmt-vyuy.rst index a3f61f280b94..670c339c1714 100644 --- a/Documentation/media/uapi/v4l/pixfmt-vyuy.rst +++ b/Documentation/media/uapi/v4l/pixfmt-vyuy.rst @@ -65,7 +65,7 @@ Each cell is one byte. - Y'\ :sub:`33` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt-y41p.rst b/Documentation/media/uapi/v4l/pixfmt-y41p.rst index 05d040c46a47..e1fe548807a4 100644 --- a/Documentation/media/uapi/v4l/pixfmt-y41p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-y41p.rst @@ -88,7 +88,7 @@ Each cell is one byte. - Y'\ :sub:`37` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv410.rst b/Documentation/media/uapi/v4l/pixfmt-yuv410.rst index 0c49915af850..b51a0d1c6108 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv410.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv410.rst @@ -67,7 +67,7 @@ Each cell is one byte. - Cb\ :sub:`00` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst b/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst index 2cf33fad7254..2582341972db 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv411p.rst @@ -75,7 +75,7 @@ Each cell is one byte. - Cr\ :sub:`30` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv420.rst b/Documentation/media/uapi/v4l/pixfmt-yuv420.rst index fd98904058ed..a9b85c4b1dbc 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv420.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv420.rst @@ -76,7 +76,7 @@ Each cell is one byte. - Cb\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst index cce8c477fdfc..32c68c33f2b1 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv420m.rst @@ -85,7 +85,7 @@ Each cell is one byte. - Cr\ :sub:`11` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst index d986393aa934..9e7028c4967c 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv422m.rst @@ -96,7 +96,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst b/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst index e6f5de546dba..a96f836c7fa5 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv422p.rst @@ -84,7 +84,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst b/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst index 830fbf6fcd1d..8605bfaee112 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuv444m.rst @@ -106,7 +106,7 @@ Each cell is one byte. - Cr\ :sub:`33` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yuyv.rst b/Documentation/media/uapi/v4l/pixfmt-yuyv.rst index e1bdd6b1aefc..53e876d053fb 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yuyv.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yuyv.rst @@ -68,7 +68,7 @@ Each cell is one byte. - Cr\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** diff --git a/Documentation/media/uapi/v4l/pixfmt-yvyu.rst b/Documentation/media/uapi/v4l/pixfmt-yvyu.rst index 0244ce6741a6..b9c31746e565 100644 --- a/Documentation/media/uapi/v4l/pixfmt-yvyu.rst +++ b/Documentation/media/uapi/v4l/pixfmt-yvyu.rst @@ -65,7 +65,7 @@ Each cell is one byte. - Cb\ :sub:`31` -**Color Sample Location..** +**Color Sample Location:** .. flat-table:: :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/pixfmt.rst b/Documentation/media/uapi/v4l/pixfmt.rst index 00737152497b..2aa449e2da67 100644 --- a/Documentation/media/uapi/v4l/pixfmt.rst +++ b/Documentation/media/uapi/v4l/pixfmt.rst @@ -19,20 +19,19 @@ see also :ref:`VIDIOC_G_FBUF `.) .. toctree:: :maxdepth: 1 - pixfmt-002 - pixfmt-003 - pixfmt-004 - colorspaces - pixfmt-006 - pixfmt-007 - pixfmt-008 + pixfmt-v4l2 + pixfmt-v4l2-mplane + pixfmt-intro pixfmt-indexed pixfmt-rgb yuv-formats hsv-formats depth-formats - pixfmt-013 + pixfmt-compressed sdr-formats tch-formats meta-formats pixfmt-reserved + colorspaces + colorspaces-defs + colorspaces-details diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index 8e73bb00c0d5..b1eea44550e1 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -1586,7 +1586,7 @@ JEIDA defined bit mapping will be named .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \tiny .. _v4l2-mbus-pixelcode-rgb-lvds: @@ -1784,7 +1784,7 @@ JEIDA defined bit mapping will be named .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Bayer Formats @@ -7321,11 +7321,14 @@ following information. The following table lists existing HSV/HSL formats. + .. raw:: latex - \newline\newline\begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} -.. tabularcolumns:: |p{6.2cm}|p{1.6cm}|p{0.7cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}|p{0.5cm}| +.. tabularcolumns:: |p{3.0cm}|p{0.60cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}|p{0.22cm}| .. _v4l2-mbus-pixelcode-hsv: @@ -7413,7 +7416,7 @@ The following table lists existing HSV/HSL formats. .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize JPEG Compressed Formats @@ -7435,7 +7438,7 @@ The following table lists existing JPEG compressed formats. .. _v4l2-mbus-pixelcode-jpeg: -.. tabularcolumns:: |p{5.6cm}|p{1.2cm}|p{10.7cm}| +.. tabularcolumns:: |p{5.4cm}|p{1.4cm}|p{10.7cm}| .. flat-table:: JPEG Formats :header-rows: 1 @@ -7468,7 +7471,7 @@ formats. .. _v4l2-mbus-pixelcode-vendor-specific: -.. tabularcolumns:: |p{6.6cm}|p{1.2cm}|p{9.7cm}| +.. tabularcolumns:: |p{6.8cm}|p{1.4cm}|p{9.3cm}| .. flat-table:: Vendor and device specific formats :header-rows: 1 diff --git a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst b/Documentation/media/uapi/v4l/v4l2-selection-targets.rst index cab07de6f4da..87433ec76c6b 100644 --- a/Documentation/media/uapi/v4l/v4l2-selection-targets.rst +++ b/Documentation/media/uapi/v4l/v4l2-selection-targets.rst @@ -12,7 +12,7 @@ of the two interfaces they are used. .. _v4l2-selection-targets-table: -.. tabularcolumns:: |p{5.8cm}|p{1.4cm}|p{6.5cm}|p{1.2cm}|p{1.6cm}| +.. tabularcolumns:: |p{6.0cm}|p{1.4cm}|p{7.4cm}|p{1.2cm}|p{1.4cm}| .. flat-table:: Selection target definitions :header-rows: 1 diff --git a/Documentation/media/uapi/v4l/v4l2.rst b/Documentation/media/uapi/v4l/v4l2.rst index f52a11c949d3..2128717299b3 100644 --- a/Documentation/media/uapi/v4l/v4l2.rst +++ b/Documentation/media/uapi/v4l/v4l2.rst @@ -11,7 +11,9 @@ This part describes the Video for Linux API version 2 (V4L2 API) specification. **Revision 4.5** -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents @@ -23,7 +25,6 @@ This part describes the Video for Linux API version 2 (V4L2 API) specification. pixfmt io devices - driver libv4l compat user-func diff --git a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst index aaca12fca06e..a39e18d69511 100644 --- a/Documentation/media/uapi/v4l/vidioc-create-bufs.rst +++ b/Documentation/media/uapi/v4l/vidioc-create-bufs.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_create_buffers`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-cropcap.rst b/Documentation/media/uapi/v4l/vidioc-cropcap.rst index 0f80d5ca2643..a65dbec6b20b 100644 --- a/Documentation/media/uapi/v4l/vidioc-cropcap.rst +++ b/Documentation/media/uapi/v4l/vidioc-cropcap.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_cropcap`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst b/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst index e1e5507e79ff..7709852282c2 100644 --- a/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst +++ b/Documentation/media/uapi/v4l/vidioc-dbg-g-chip-info.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dbg_chip_info`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst b/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst index 5960a6547f41..f4e8dd5f7889 100644 --- a/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst +++ b/Documentation/media/uapi/v4l/vidioc-dbg-g-register.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dbg_register`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-dqevent.rst b/Documentation/media/uapi/v4l/vidioc-dqevent.rst index 8d663a73818e..cb3565f36793 100644 --- a/Documentation/media/uapi/v4l/vidioc-dqevent.rst +++ b/Documentation/media/uapi/v4l/vidioc-dqevent.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_event`. Description @@ -38,7 +39,7 @@ exceptions which the application may get by e.g. using the select system call. -.. tabularcolumns:: |p{3.0cm}|p{4.3cm}|p{2.5cm}|p{7.7cm}| +.. tabularcolumns:: |p{3.0cm}|p{4.4cm}|p{2.4cm}|p{7.7cm}| .. c:type:: v4l2_event diff --git a/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst b/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst index 424f3a1c7f56..63ead6b7a115 100644 --- a/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst +++ b/Documentation/media/uapi/v4l/vidioc-dv-timings-cap.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dv_timings_cap`. Description @@ -97,7 +98,7 @@ that doesn't support them will return an ``EINVAL`` error code. -.. tabularcolumns:: |p{1.0cm}|p{3.5cm}|p{3.5cm}|p{9.5cm}| +.. tabularcolumns:: |p{1.0cm}|p{4.0cm}|p{3.5cm}|p{9.2cm}| .. c:type:: v4l2_dv_timings_cap diff --git a/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst b/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst index ae20ee573757..5ae8c933b1b9 100644 --- a/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst +++ b/Documentation/media/uapi/v4l/vidioc-encoder-cmd.rst @@ -29,7 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - + Pointer to struct :c:type:`v4l2_encoder_cmd`. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst index 3e9d0f69cc73..63dca65f49e4 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-dv-timings.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_enum_dv_timings`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst index a2adaa4bd4dd..019c513df217 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-fmt.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_fmtdesc`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst b/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst index 39492453f02d..fea7dc3c879d 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-frameintervals.rst @@ -26,9 +26,8 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - Pointer to a struct :c:type:`v4l2_frmivalenum` - structure that contains a pixel format and size and receives a frame - interval. + Pointer to struct :c:type:`v4l2_frmivalenum` + that contains a pixel format and size and receives a frame interval. Description @@ -124,6 +123,8 @@ application should zero out all members except for the *IN* fields. .. c:type:: v4l2_frmivalenum +.. tabularcolumns:: |p{1.8cm}|p{4.4cm}|p{2.4cm}|p{8.9cm}| + .. flat-table:: struct v4l2_frmivalenum :header-rows: 0 :stub-columns: 0 diff --git a/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst b/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst index 628f1aa66338..6de117f163e0 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-framesizes.rst @@ -26,7 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - Pointer to a struct :c:type:`v4l2_frmsizeenum` + Pointer to struct :c:type:`v4l2_frmsizeenum` that contains an index and pixel format and receives a frame width and height. @@ -140,6 +140,8 @@ application should zero out all members except for the *IN* fields. .. c:type:: v4l2_frmsizeenum +.. tabularcolumns:: |p{1.4cm}|p{5.9cm}|p{2.3cm}|p{8.0cm}| + .. flat-table:: struct v4l2_frmsizeenum :header-rows: 0 :stub-columns: 0 diff --git a/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst b/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst index 4e5f5e5bf632..195cf45f3c32 100644 --- a/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst +++ b/Documentation/media/uapi/v4l/vidioc-enum-freq-bands.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_frequency_band`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumaudio.rst b/Documentation/media/uapi/v4l/vidioc-enumaudio.rst index 74bc3ed0bdd8..8e5193e8696f 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumaudio.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumaudio.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audio`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst b/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst index 4470a1ece5cf..6d2b4f6e78b0 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumaudioout.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audioout`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enuminput.rst b/Documentation/media/uapi/v4l/vidioc-enuminput.rst index 266e48ab237f..0350069a56c5 100644 --- a/Documentation/media/uapi/v4l/vidioc-enuminput.rst +++ b/Documentation/media/uapi/v4l/vidioc-enuminput.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_input`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumoutput.rst b/Documentation/media/uapi/v4l/vidioc-enumoutput.rst index 93a2cf3b310c..697dcd186ae3 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumoutput.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumoutput.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_output`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-enumstd.rst b/Documentation/media/uapi/v4l/vidioc-enumstd.rst index f2bdd45cfa0d..b7fda29f46a1 100644 --- a/Documentation/media/uapi/v4l/vidioc-enumstd.rst +++ b/Documentation/media/uapi/v4l/vidioc-enumstd.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_standard`. Description @@ -224,12 +225,15 @@ support digital TV. See also the Linux DVB API at #define V4L2_STD_ALL (V4L2_STD_525_60 | V4L2_STD_625_50) + .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \begingroup + \tiny + \setlength{\tabcolsep}{2pt} .. NTSC/M PAL/M /N /B /D /H /I SECAM/B /D /K1 /L -.. tabularcolumns:: |p{2.7cm}|p{2.6cm}|p{3.0cm}|p{3.2cm}|p{3.2cm}|p{2.2cm}|p{1.2cm}|p{3.2cm}|p{3.0cm}|p{2.0cm}|p{2.0cm}|p{2.0cm}| +.. tabularcolumns:: |p{1.43cm}|p{1.38cm}|p{1.59cm}|p{1.7cm}|p{1.7cm}|p{1.17cm}|p{0.64cm}|p{1.71cm}|p{1.6cm}|p{1.07cm}|p{1.07cm}|p{1.07cm}| .. _video-standards: @@ -293,7 +297,7 @@ support digital TV. See also the Linux DVB API at .. raw:: latex - \end{adjustbox}\newline\newline + \endgroup diff --git a/Documentation/media/uapi/v4l/vidioc-expbuf.rst b/Documentation/media/uapi/v4l/vidioc-expbuf.rst index 246e48028d40..226e83eb28a9 100644 --- a/Documentation/media/uapi/v4l/vidioc-expbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-expbuf.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_exportbuffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-audio.rst b/Documentation/media/uapi/v4l/vidioc-g-audio.rst index 5b67e81a0db6..290851f99386 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-audio.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-audio.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audio`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-audioout.rst b/Documentation/media/uapi/v4l/vidioc-g-audioout.rst index d16ecbaddc59..1c98af33ee70 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-audioout.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-audioout.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_audioout`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-crop.rst b/Documentation/media/uapi/v4l/vidioc-g-crop.rst index 13771ee3e94a..a6ed43ba9ca3 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-crop.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-crop.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_crop`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst b/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst index d8a379182a34..299b9aabbac2 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ctrl.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_control`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst index e573c74138de..2696380626d4 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst @@ -35,6 +35,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dv_timings`. Description @@ -208,7 +209,7 @@ EBUSY - 0 - BT.656/1120 timings - +.. tabularcolumns:: |p{4.5cm}|p{12.8cm}| .. _dv-bt-standards: @@ -231,7 +232,7 @@ EBUSY There are no horizontal syncs/porches at all in this format. Total blanking timings must be set in hsync or vsync fields only. -.. tabularcolumns:: |p{6.0cm}|p{11.5cm}| +.. tabularcolumns:: |p{7.0cm}|p{10.5cm}| .. _dv-bt-flags: diff --git a/Documentation/media/uapi/v4l/vidioc-g-edid.rst b/Documentation/media/uapi/v4l/vidioc-g-edid.rst index a16a193a1cbf..acab90f06e5a 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-edid.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-edid.rst @@ -36,6 +36,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_edid`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst b/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst index 418e886fd44b..9dfe64fc21a4 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-enc-index.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_enc_idx`. Description @@ -55,7 +56,7 @@ Currently this ioctl is only defined for MPEG-2 program streams and video elementary streams. -.. tabularcolumns:: |p{3.5cm}|p{5.6cm}|p{8.4cm}| +.. tabularcolumns:: |p{3.8cm}|p{5.6cm}|p{8.1cm}| .. c:type:: v4l2_enc_idx diff --git a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst index 5ab8d2ac27b9..2011c2b2ee67 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-ext-ctrls.rst @@ -34,6 +34,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_ext_controls`. Description @@ -180,7 +181,7 @@ still cause this situation. ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set for this control. -.. tabularcolumns:: |p{4.0cm}|p{2.0cm}|p{2.0cm}|p{8.5cm}| +.. tabularcolumns:: |p{4.0cm}|p{2.2cm}|p{2.1cm}|p{8.2cm}| .. c:type:: v4l2_ext_controls diff --git a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst b/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst index 4a6a03d158ca..fc73bf0f6052 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-fbuf.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_framebuffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst index d082f9a21548..3ead350e099f 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-fmt.rst @@ -31,6 +31,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_format`. Description @@ -87,7 +88,7 @@ The format as returned by :ref:`VIDIOC_TRY_FMT ` must be identical .. c:type:: v4l2_format -.. tabularcolumns:: |p{1.2cm}|p{4.3cm}|p{3.0cm}|p{9.0cm}| +.. tabularcolumns:: |p{1.2cm}|p{4.6cm}|p{3.0cm}|p{8.6cm}| .. flat-table:: struct v4l2_format :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/vidioc-g-frequency.rst b/Documentation/media/uapi/v4l/vidioc-g-frequency.rst index 46ab276f412b..c1cccb144660 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-frequency.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-frequency.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_frequency`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-input.rst b/Documentation/media/uapi/v4l/vidioc-g-input.rst index 1364a918fbce..1dcef44eef02 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-input.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-input.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer an integer with input index. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst b/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst index 8ba353067b33..a1773ea9543e 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-jpegcomp.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_jpegcompression`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-modulator.rst b/Documentation/media/uapi/v4l/vidioc-g-modulator.rst index 77d017eb3fcc..a47b6a15cfbe 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-modulator.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-modulator.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_modulator`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-output.rst b/Documentation/media/uapi/v4l/vidioc-g-output.rst index 7750948fc61b..3e0093f66834 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-output.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-output.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to an integer with output index. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-parm.rst b/Documentation/media/uapi/v4l/vidioc-g-parm.rst index 3b2e6e59a334..616a5ea3f8fa 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-parm.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-parm.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_streamparm`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-priority.rst b/Documentation/media/uapi/v4l/vidioc-g-priority.rst index a763988f64e4..c28996b4a45c 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-priority.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-priority.rst @@ -29,7 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - Pointer to an enum v4l2_priority type. + Pointer to an enum :c:type:`v4l2_priority` type. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-selection.rst b/Documentation/media/uapi/v4l/vidioc-g-selection.rst index c1ee86472918..f1d9df029e0d 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-selection.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-selection.rst @@ -29,11 +29,8 @@ Arguments ``fd`` File descriptor returned by :ref:`open() `. -``request`` - VIDIOC_G_SELECTION, VIDIOC_S_SELECTION - ``argp`` - + Pointer to struct :c:type:`v4l2_selection`. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst b/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst index d7e2b2fa8b88..a9633cae76c5 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-sliced-vbi-cap.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_sliced_vbi_cap`. Description @@ -122,9 +123,9 @@ the sliced VBI API is unsupported or ``type`` is invalid. .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \scriptsize -.. tabularcolumns:: |p{5.0cm}|p{1.4cm}|p{3.0cm}|p{2.5cm}|p{9.0cm}| +.. tabularcolumns:: |p{3.5cm}|p{1.0cm}|p{2.0cm}|p{2.0cm}|p{8.0cm}| .. _vbi-services: @@ -180,7 +181,7 @@ the sliced VBI API is unsupported or ``type`` is invalid. .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Return Value diff --git a/Documentation/media/uapi/v4l/vidioc-g-std.rst b/Documentation/media/uapi/v4l/vidioc-g-std.rst index cd856ad21a28..90791ab51a53 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-std.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-std.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to :c:type:`v4l2_std_id`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst b/Documentation/media/uapi/v4l/vidioc-g-tuner.rst index 57c79fa43866..acdd15901a51 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-tuner.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-tuner.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_tuner`. Description @@ -392,22 +393,25 @@ To change the radio frequency the .. raw:: latex - \begin{adjustbox}{width=\columnwidth} + \scriptsize + +.. tabularcolumns:: |p{1.5cm}|p{1.5cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}|p{2.9cm}| .. _tuner-matrix: .. flat-table:: Tuner Audio Matrix :header-rows: 2 :stub-columns: 0 + :widths: 7 7 14 14 14 14 * - - - :cspan:`5` Selected ``V4L2_TUNER_MODE_`` + - :cspan:`4` Selected ``V4L2_TUNER_MODE_`` * - Received ``V4L2_TUNER_SUB_`` - ``MONO`` - ``STEREO`` - ``LANG1`` - ``LANG2 = SAP`` - - ``LANG1_LANG2``\ [#f1]_ + - ``LANG1_LANG2``\ [#f1]_ * - ``MONO`` - Mono - Mono/Mono @@ -434,14 +438,14 @@ To change the radio frequency the - L+R/SAP (preferred) or L/R or L+R/L+R * - ``LANG1 | LANG2`` - Language 1 - - Lang1/Lang2 (deprecated [#f2]_) or Lang1/Lang1 + - Lang1/Lang2 (deprecated\ [#f2]_) or Lang1/Lang1 - Language 1 - Language 2 - Lang1/Lang2 (preferred) or Lang1/Lang1 .. raw:: latex - \end{adjustbox}\newline\newline + \normalsize Return Value ============ diff --git a/Documentation/media/uapi/v4l/vidioc-overlay.rst b/Documentation/media/uapi/v4l/vidioc-overlay.rst index cd7b62ebc53b..1383e3db25fc 100644 --- a/Documentation/media/uapi/v4l/vidioc-overlay.rst +++ b/Documentation/media/uapi/v4l/vidioc-overlay.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to an integer. Description diff --git a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst index bdcfd9fe550d..70687a86ae38 100644 --- a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst +++ b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_buffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-qbuf.rst b/Documentation/media/uapi/v4l/vidioc-qbuf.rst index 1f3612637200..9e448a4aa3aa 100644 --- a/Documentation/media/uapi/v4l/vidioc-qbuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-qbuf.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_buffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst index 0d16853b1b51..6c82eafd28bb 100644 --- a/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst +++ b/Documentation/media/uapi/v4l/vidioc-query-dv-timings.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_dv_timings`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-querybuf.rst b/Documentation/media/uapi/v4l/vidioc-querybuf.rst index 0bdc8e0abddc..dd54747fabc9 100644 --- a/Documentation/media/uapi/v4l/vidioc-querybuf.rst +++ b/Documentation/media/uapi/v4l/vidioc-querybuf.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_buffer`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst b/Documentation/media/uapi/v4l/vidioc-querycap.rst index 12e0d9a63cd8..66fb1b3d6e6e 100644 --- a/Documentation/media/uapi/v4l/vidioc-querycap.rst +++ b/Documentation/media/uapi/v4l/vidioc-querycap.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_capability`. Description @@ -91,12 +92,13 @@ specification the ioctl returns an ``EINVAL`` error code. stack from a newer kernel. The version number is formatted using the ``KERNEL_VERSION()`` - macro: + macro. For example if the media stack corresponds to the V4L2 + version shipped with Kernel 4.14, it would be equivalent to: * - :cspan:`2` ``#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))`` - ``__u32 version = KERNEL_VERSION(0, 8, 1);`` + ``__u32 version = KERNEL_VERSION(4, 14, 0);`` ``printf ("Version: %u.%u.%u\\n",`` @@ -131,7 +133,7 @@ specification the ioctl returns an ``EINVAL`` error code. -.. tabularcolumns:: |p{6cm}|p{2.2cm}|p{8.8cm}| +.. tabularcolumns:: |p{6.1cm}|p{2.2cm}|p{8.7cm}| .. _device-capabilities: diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst index 41c5744a1239..5bd26e8c9a1a 100644 --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst @@ -32,6 +32,8 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_queryctl`, :c:type:`v4l2_query_ext_ctrl` + or :c:type`v4l2_querymenu` (depending on the ioctl). Description @@ -274,7 +276,7 @@ See also the examples in :ref:`control`. -.. tabularcolumns:: |p{1.2cm}|p{0.6cm}|p{1.6cm}|p{13.5cm}| +.. tabularcolumns:: |p{1.2cm}|p{1.0cm}|p{1.7cm}|p{13.0cm}| .. _v4l2-querymenu: diff --git a/Documentation/media/uapi/v4l/vidioc-querystd.rst b/Documentation/media/uapi/v4l/vidioc-querystd.rst index 3ef9ab37f582..cf40bca19b9f 100644 --- a/Documentation/media/uapi/v4l/vidioc-querystd.rst +++ b/Documentation/media/uapi/v4l/vidioc-querystd.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to :c:type:`v4l2_std_id`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst index a4180d576ee5..316f52c8a310 100644 --- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst +++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst @@ -26,7 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - + Pointer to struct :c:type:`v4l2_requestbuffers`. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst b/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst index 5672ca48d2bd..b318cb8e1df3 100644 --- a/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst +++ b/Documentation/media/uapi/v4l/vidioc-s-hw-freq-seek.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_hw_freq_seek`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-streamon.rst b/Documentation/media/uapi/v4l/vidioc-streamon.rst index 972d5b3c74aa..e851a6961b78 100644 --- a/Documentation/media/uapi/v4l/vidioc-streamon.rst +++ b/Documentation/media/uapi/v4l/vidioc-streamon.rst @@ -29,7 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` - + Pointer to an integer. Description =========== diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst index 1a02c935c8b5..1bfe3865dcc2 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-interval.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_frame_interval_enum`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst index 746c24ed97a0..33fdc3ac9316 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-enum-frame-size.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_frame_size_enum`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst b/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst index 0dfee3829ee2..4e4291798e4b 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-enum-mbus-code.rst @@ -26,6 +26,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_mbus_code_enum`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst index 000e8fcd3f25..69b2ae8e7c15 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-crop.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_crop`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst index b352456dfe2c..81c5d331af9a 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_format`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst index 46159dcfce30..5af0a7179941 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-frame-interval.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_frame_interval`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst index 071d9c033db6..b1d3dbbef42a 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-selection.rst @@ -29,6 +29,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_subdev_selection`. Description diff --git a/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst b/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst index e4a51431032c..b521efa53ceb 100644 --- a/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst +++ b/Documentation/media/uapi/v4l/vidioc-subscribe-event.rst @@ -30,6 +30,7 @@ Arguments File descriptor returned by :ref:`open() `. ``argp`` + Pointer to struct :c:type:`v4l2_event_subscription`. Description @@ -39,7 +40,7 @@ Subscribe or unsubscribe V4L2 event. Subscribed events are dequeued by using the :ref:`VIDIOC_DQEVENT` ioctl. -.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| +.. tabularcolumns:: |p{4.6cm}|p{4.4cm}|p{8.7cm}| .. c:type:: v4l2_event_subscription @@ -72,7 +73,7 @@ using the :ref:`VIDIOC_DQEVENT` ioctl. -.. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}| +.. tabularcolumns:: |p{6.8cm}|p{2.2cm}|p{8.5cm}| .. _event-flags: diff --git a/Documentation/media/v4l-drivers/au0828-cardlist.rst b/Documentation/media/v4l-drivers/au0828-cardlist.rst index 82d2567bc7c1..bb87b7b36a83 100644 --- a/Documentation/media/v4l-drivers/au0828-cardlist.rst +++ b/Documentation/media/v4l-drivers/au0828-cardlist.rst @@ -1,13 +1,37 @@ AU0828 cards list ================= -=========== ========================== ======================================================================================================================= -Card number Card name USB IDs -=========== ========================== ======================================================================================================================= -0 Unknown board -1 Hauppauge HVR950Q 2040:7200, 2040:7210, 2040:7217, 2040:721b, 2040:721e, 2040:721f, 2040:7280, 0fd9:0008, 2040:7260, 2040:7213, 2040:7270 -2 Hauppauge HVR850 2040:7240 -3 DViCO FusionHDTV USB 0fe9:d620 -4 Hauppauge HVR950Q rev xxF8 2040:7201, 2040:7211, 2040:7281 -5 Hauppauge Woodbury 05e1:0480, 2040:8200 -=========== ========================== ======================================================================================================================= +.. tabularcolumns:: |p{1.4cm}|p{6.5cm}|p{10.0cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - USB IDs + + * - 0 + - Unknown board + - + + * - 1 + - Hauppauge HVR950Q + - 2040:7200, 2040:7210, 2040:7217, 2040:721b, 2040:721e, 2040:721f, 2040:7280, 0fd9:0008, 2040:7260, 2040:7213, 2040:7270 + + * - 2 + - Hauppauge HVR850 + - 2040:7240 + + * - 3 + - DViCO FusionHDTV USB + - 0fe9:d620 + + * - 4 + - Hauppauge HVR950Q rev xxF8 + - 2040:7201, 2040:7211, 2040:7281 + + * - 5 + - Hauppauge Woodbury + - 05e1:0480, 2040:8200 diff --git a/Documentation/media/v4l-drivers/bttv-cardlist.rst b/Documentation/media/v4l-drivers/bttv-cardlist.rst index 28a01cd6cf2e..8da27b924e01 100644 --- a/Documentation/media/v4l-drivers/bttv-cardlist.rst +++ b/Documentation/media/v4l-drivers/bttv-cardlist.rst @@ -1,174 +1,681 @@ BTTV cards list =============== -=========== ================================================================================= ============================================================================================================================================================================== -Card number Card name PCI IDs -=========== ================================================================================= ============================================================================================================================================================================== -0 *** UNKNOWN/GENERIC *** -1 MIRO PCTV -2 Hauppauge (bt848) -3 STB, Gateway P/N 6000699 (bt848) -4 Intel Create and Share PCI/ Smart Video Recorder III -5 Diamond DTV2000 -6 AVerMedia TVPhone -7 MATRIX-Vision MV-Delta -8 Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 -9 IMS/IXmicro TurboTV -10 Hauppauge (bt878) 0070:13eb, 0070:3900, 2636:10b4 -11 MIRO PCTV pro -12 ADS Technologies Channel Surfer TV (bt848) -13 AVerMedia TVCapture 98 1461:0002, 1461:0004, 1461:0300 -14 Aimslab Video Highway Xtreme (VHX) -15 Zoltrix TV-Max a1a0:a0fc -16 Prolink Pixelview PlayTV (bt878) -17 Leadtek WinView 601 -18 AVEC Intercapture -19 Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) -20 CEI Raffles Card -21 Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 -22 Askey CPH050/ Phoebe Tv Master + FM 14ff:3002 -23 Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 14c7:0101 -24 Askey CPH05X/06X (bt878) [many vendors] 144f:3002, 144f:3005, 144f:5000, 14ff:3000 -25 Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar -26 Hauppauge WinCam newer (bt878) -27 Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 -28 Terratec TerraTV+ Version 1.1 (bt878) 153b:1127, 1852:1852 -29 Imagenation PXC200 1295:200a -30 Lifeview FlyVideo 98 LR50 1f7f:1850 -31 Formac iProTV, Formac ProTV I (bt848) -32 Intel Create and Share PCI/ Smart Video Recorder III -33 Terratec TerraTValue Version Bt878 153b:1117, 153b:1118, 153b:1119, 153b:111a, 153b:1134, 153b:5018 -34 Leadtek WinFast 2000/ WinFast 2000 XP 107d:6606, 107d:6609, 6606:217d, f6ff:fff6 -35 Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II 1851:1850, 1851:a050 -36 Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner 1852:1852 -37 Prolink PixelView PlayTV pro -38 Askey CPH06X TView99 144f:3000, 144f:a005, a04f:a0fc -39 Pinnacle PCTV Studio/Rave 11bd:0012, bd11:1200, bd11:ff00, 11bd:ff12 -40 STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 10b4:2636, 10b4:2645, 121a:3060 -41 AVerMedia TVPhone 98 1461:0001, 1461:0003 -42 ProVideo PV951 aa0c:146c -43 Little OnAir TV -44 Sigma TVII-FM -45 MATRIX-Vision MV-Delta 2 -46 Zoltrix Genie TV/FM 15b0:4000, 15b0:400a, 15b0:400d, 15b0:4010, 15b0:4016 -47 Terratec TV/Radio+ 153b:1123 -48 Askey CPH03x/ Dynalink Magic TView -49 IODATA GV-BCTV3/PCI 10fc:4020 -50 Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP -51 Eagle Wireless Capricorn2 (bt878A) -52 Pinnacle PCTV Studio Pro -53 Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS -54 Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] -55 Askey CPH031/ BESTBUY Easy TV -56 Lifeview FlyVideo 98FM LR50 a051:41a0 -57 GrandTec 'Grand Video Capture' (Bt848) 4344:4142 -58 Askey CPH060/ Phoebe TV Master Only (No FM) -59 Askey CPH03x TV Capturer -60 Modular Technology MM100PCTV -61 AG Electronics GMV1 15cb:0101 -62 Askey CPH061/ BESTBUY Easy TV (bt878) -63 ATI TV-Wonder 1002:0001 -64 ATI TV-Wonder VE 1002:0003 -65 Lifeview FlyVideo 2000S LR90 -66 Terratec TValueRadio 153b:1135, 153b:ff3b -67 IODATA GV-BCTV4/PCI 10fc:4050 -68 3Dfx VoodooTV FM (Euro) 10b4:2637 -69 Active Imaging AIMMS -70 Prolink Pixelview PV-BT878P+ (Rev.4C,8E) -71 Lifeview FlyVideo 98EZ (capture only) LR51 1851:1851 -72 Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) 1554:4011 -73 Sensoray 311/611 6000:0311, 6000:0611 -74 RemoteVision MX (RV605) -75 Powercolor MTV878/ MTV878R/ MTV878F -76 Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) 0e11:0079 -77 GrandTec Multi Capture Card (Bt878) -78 Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF 0a01:17de -79 DSP Design TCVIDEO -80 Hauppauge WinTV PVR 0070:4500 -81 IODATA GV-BCTV5/PCI 10fc:4070, 10fc:d018 -82 Osprey 100/150 (878) 0070:ff00 -83 Osprey 100/150 (848) -84 Osprey 101 (848) -85 Osprey 101/151 -86 Osprey 101/151 w/ svid -87 Osprey 200/201/250/251 -88 Osprey 200/250 0070:ff01 -89 Osprey 210/220/230 -90 Osprey 500 0070:ff02 -91 Osprey 540 0070:ff04 -92 Osprey 2000 0070:ff03 -93 IDS Eagle -94 Pinnacle PCTV Sat 11bd:001c -95 Formac ProTV II (bt878) -96 MachTV -97 Euresys Picolo -98 ProVideo PV150 aa00:1460, aa01:1461, aa02:1462, aa03:1463, aa04:1464, aa05:1465, aa06:1466, aa07:1467 -99 AD-TVK503 -100 Hercules Smart TV Stereo -101 Pace TV & Radio Card -102 IVC-200 0000:a155, 0001:a155, 0002:a155, 0003:a155, 0100:a155, 0101:a155, 0102:a155, 0103:a155, 0800:a155, 0801:a155, 0802:a155, 0803:a155 -103 Grand X-Guard / Trust 814PCI 0304:0102 -104 Nebula Electronics DigiTV 0071:0101 -105 ProVideo PV143 aa00:1430, aa00:1431, aa00:1432, aa00:1433, aa03:1433 -106 PHYTEC VD-009-X1 VD-011 MiniDIN (bt878) -107 PHYTEC VD-009-X1 VD-011 Combi (bt878) -108 PHYTEC VD-009 MiniDIN (bt878) -109 PHYTEC VD-009 Combi (bt878) -110 IVC-100 ff00:a132 -111 IVC-120G ff00:a182, ff01:a182, ff02:a182, ff03:a182, ff04:a182, ff05:a182, ff06:a182, ff07:a182, ff08:a182, ff09:a182, ff0a:a182, ff0b:a182, ff0c:a182, ff0d:a182, ff0e:a182, ff0f:a182 -112 pcHDTV HD-2000 TV 7063:2000 -113 Twinhan DST + clones 11bd:0026, 1822:0001, 270f:fc00, 1822:0026 -114 Winfast VC100 107d:6607 -115 Teppro TEV-560/InterVision IV-560 -116 SIMUS GVC1100 aa6a:82b2 -117 NGS NGSTV+ -118 LMLBT4 -119 Tekram M205 PRO -120 Conceptronic CONTVFMi -121 Euresys Picolo Tetra 1805:0105, 1805:0106, 1805:0107, 1805:0108 -122 Spirit TV Tuner -123 AVerMedia AVerTV DVB-T 771 1461:0771 -124 AverMedia AverTV DVB-T 761 1461:0761 -125 MATRIX Vision Sigma-SQ -126 MATRIX Vision Sigma-SLC -127 APAC Viewcomp 878(AMAX) -128 DViCO FusionHDTV DVB-T Lite 18ac:db10, 18ac:db11 -129 V-Gear MyVCD -130 Super TV Tuner -131 Tibet Systems 'Progress DVR' CS16 -132 Kodicom 4400R (master) -133 Kodicom 4400R (slave) -134 Adlink RTV24 -135 DViCO FusionHDTV 5 Lite 18ac:d500 -136 Acorp Y878F 9511:1540 -137 Conceptronic CTVFMi v2 036e:109e -138 Prolink Pixelview PV-BT878P+ (Rev.2E) -139 Prolink PixelView PlayTV MPEG2 PV-M4900 -140 Osprey 440 0070:ff07 -141 Asound Skyeye PCTV -142 Sabrent TV-FM (bttv version) -143 Hauppauge ImpactVCB (bt878) 0070:13eb -144 MagicTV -145 SSAI Security Video Interface 4149:5353 -146 SSAI Ultrasound Video Interface 414a:5353 -147 VoodooTV 200 (USA) 121a:3000 -148 DViCO FusionHDTV 2 dbc0:d200 -149 Typhoon TV-Tuner PCI (50684) -150 Geovision GV-600 008a:763c -151 Kozumi KTV-01C -152 Encore ENL TV-FM-2 1000:1801 -153 PHYTEC VD-012 (bt878) -154 PHYTEC VD-012-X1 (bt878) -155 PHYTEC VD-012-X2 (bt878) -156 IVCE-8784 0000:f050, 0001:f050, 0002:f050, 0003:f050 -157 Geovision GV-800(S) (master) 800a:763d -158 Geovision GV-800(S) (slave) 800b:763d, 800c:763d, 800d:763d -159 ProVideo PV183 1830:1540, 1831:1540, 1832:1540, 1833:1540, 1834:1540, 1835:1540, 1836:1540, 1837:1540 -160 Tongwei Video Technology TD-3116 f200:3116 -161 Aposonic W-DVR 0279:0228 -162 Adlink MPG24 -163 Bt848 Capture 14MHz -164 CyberVision CV06 (SV) -165 Kworld V-Stream Xpert TV PVR878 -166 PCI-8604PW -=========== ================================================================================= ============================================================================================================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - *** UNKNOWN/GENERIC *** + - + + * - 1 + - MIRO PCTV + - + + * - 2 + - Hauppauge (bt848) + - + + * - 3 + - STB, Gateway P/N 6000699 (bt848) + - + + * - 4 + - Intel Create and Share PCI/ Smart Video Recorder III + - + + * - 5 + - Diamond DTV2000 + - + + * - 6 + - AVerMedia TVPhone + - + + * - 7 + - MATRIX-Vision MV-Delta + - + + * - 8 + - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26 + - + + * - 9 + - IMS/IXmicro TurboTV + - + + * - 10 + - Hauppauge (bt878) + - 0070:13eb, 0070:3900, 2636:10b4 + + * - 11 + - MIRO PCTV pro + - + + * - 12 + - ADS Technologies Channel Surfer TV (bt848) + - + + * - 13 + - AVerMedia TVCapture 98 + - 1461:0002, 1461:0004, 1461:0300 + + * - 14 + - Aimslab Video Highway Xtreme (VHX) + - + + * - 15 + - Zoltrix TV-Max + - a1a0:a0fc + + * - 16 + - Prolink Pixelview PlayTV (bt878) + - + + * - 17 + - Leadtek WinView 601 + - + + * - 18 + - AVEC Intercapture + - + + * - 19 + - Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only) + - + + * - 20 + - CEI Raffles Card + - + + * - 21 + - Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50 + - + + * - 22 + - Askey CPH050/ Phoebe Tv Master + FM + - 14ff:3002 + + * - 23 + - Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878 + - 14c7:0101 + + * - 24 + - Askey CPH05X/06X (bt878) [many vendors] + - 144f:3002, 144f:3005, 144f:5000, 14ff:3000 + + * - 25 + - Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar + - + + * - 26 + - Hauppauge WinCam newer (bt878) + - + + * - 27 + - Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50 + - + + * - 28 + - Terratec TerraTV+ Version 1.1 (bt878) + - 153b:1127, 1852:1852 + + * - 29 + - Imagenation PXC200 + - 1295:200a + + * - 30 + - Lifeview FlyVideo 98 LR50 + - 1f7f:1850 + + * - 31 + - Formac iProTV, Formac ProTV I (bt848) + - + + * - 32 + - Intel Create and Share PCI/ Smart Video Recorder III + - + + * - 33 + - Terratec TerraTValue Version Bt878 + - 153b:1117, 153b:1118, 153b:1119, 153b:111a, 153b:1134, 153b:5018 + + * - 34 + - Leadtek WinFast 2000/ WinFast 2000 XP + - 107d:6606, 107d:6609, 6606:217d, f6ff:fff6 + + * - 35 + - Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II + - 1851:1850, 1851:a050 + + * - 36 + - Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner + - 1852:1852 + + * - 37 + - Prolink PixelView PlayTV pro + - + + * - 38 + - Askey CPH06X TView99 + - 144f:3000, 144f:a005, a04f:a0fc + + * - 39 + - Pinnacle PCTV Studio/Rave + - 11bd:0012, bd11:1200, bd11:ff00, 11bd:ff12 + + * - 40 + - STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100 + - 10b4:2636, 10b4:2645, 121a:3060 + + * - 41 + - AVerMedia TVPhone 98 + - 1461:0001, 1461:0003 + + * - 42 + - ProVideo PV951 + - aa0c:146c + + * - 43 + - Little OnAir TV + - + + * - 44 + - Sigma TVII-FM + - + + * - 45 + - MATRIX-Vision MV-Delta 2 + - + + * - 46 + - Zoltrix Genie TV/FM + - 15b0:4000, 15b0:400a, 15b0:400d, 15b0:4010, 15b0:4016 + + * - 47 + - Terratec TV/Radio+ + - 153b:1123 + + * - 48 + - Askey CPH03x/ Dynalink Magic TView + - + + * - 49 + - IODATA GV-BCTV3/PCI + - 10fc:4020 + + * - 50 + - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP + - + + * - 51 + - Eagle Wireless Capricorn2 (bt878A) + - + + * - 52 + - Pinnacle PCTV Studio Pro + - + + * - 53 + - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS + - + + * - 54 + - Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90] + - + + * - 55 + - Askey CPH031/ BESTBUY Easy TV + - + + * - 56 + - Lifeview FlyVideo 98FM LR50 + - a051:41a0 + + * - 57 + - GrandTec 'Grand Video Capture' (Bt848) + - 4344:4142 + + * - 58 + - Askey CPH060/ Phoebe TV Master Only (No FM) + - + + * - 59 + - Askey CPH03x TV Capturer + - + + * - 60 + - Modular Technology MM100PCTV + - + + * - 61 + - AG Electronics GMV1 + - 15cb:0101 + + * - 62 + - Askey CPH061/ BESTBUY Easy TV (bt878) + - + + * - 63 + - ATI TV-Wonder + - 1002:0001 + + * - 64 + - ATI TV-Wonder VE + - 1002:0003 + + * - 65 + - Lifeview FlyVideo 2000S LR90 + - + + * - 66 + - Terratec TValueRadio + - 153b:1135, 153b:ff3b + + * - 67 + - IODATA GV-BCTV4/PCI + - 10fc:4050 + + * - 68 + - 3Dfx VoodooTV FM (Euro) + - 10b4:2637 + + * - 69 + - Active Imaging AIMMS + - + + * - 70 + - Prolink Pixelview PV-BT878P+ (Rev.4C,8E) + - + + * - 71 + - Lifeview FlyVideo 98EZ (capture only) LR51 + - 1851:1851 + + * - 72 + - Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM) + - 1554:4011 + + * - 73 + - Sensoray 311/611 + - 6000:0311, 6000:0611 + + * - 74 + - RemoteVision MX (RV605) + - + + * - 75 + - Powercolor MTV878/ MTV878R/ MTV878F + - + + * - 76 + - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP) + - 0e11:0079 + + * - 77 + - GrandTec Multi Capture Card (Bt878) + - + + * - 78 + - Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF + - 0a01:17de + + * - 79 + - DSP Design TCVIDEO + - + + * - 80 + - Hauppauge WinTV PVR + - 0070:4500 + + * - 81 + - IODATA GV-BCTV5/PCI + - 10fc:4070, 10fc:d018 + + * - 82 + - Osprey 100/150 (878) + - 0070:ff00 + + * - 83 + - Osprey 100/150 (848) + - + + * - 84 + - Osprey 101 (848) + - + + * - 85 + - Osprey 101/151 + - + + * - 86 + - Osprey 101/151 w/ svid + - + + * - 87 + - Osprey 200/201/250/251 + - + + * - 88 + - Osprey 200/250 + - 0070:ff01 + + * - 89 + - Osprey 210/220/230 + - + + * - 90 + - Osprey 500 + - 0070:ff02 + + * - 91 + - Osprey 540 + - 0070:ff04 + + * - 92 + - Osprey 2000 + - 0070:ff03 + + * - 93 + - IDS Eagle + - + + * - 94 + - Pinnacle PCTV Sat + - 11bd:001c + + * - 95 + - Formac ProTV II (bt878) + - + + * - 96 + - MachTV + - + + * - 97 + - Euresys Picolo + - + + * - 98 + - ProVideo PV150 + - aa00:1460, aa01:1461, aa02:1462, aa03:1463, aa04:1464, aa05:1465, aa06:1466, aa07:1467 + + * - 99 + - AD-TVK503 + - + + * - 100 + - Hercules Smart TV Stereo + - + + * - 101 + - Pace TV & Radio Card + - + + * - 102 + - IVC-200 + - 0000:a155, 0001:a155, 0002:a155, 0003:a155, 0100:a155, 0101:a155, 0102:a155, 0103:a155, 0800:a155, 0801:a155, 0802:a155, 0803:a155 + + * - 103 + - Grand X-Guard / Trust 814PCI + - 0304:0102 + + * - 104 + - Nebula Electronics DigiTV + - 0071:0101 + + * - 105 + - ProVideo PV143 + - aa00:1430, aa00:1431, aa00:1432, aa00:1433, aa03:1433 + + * - 106 + - PHYTEC VD-009-X1 VD-011 MiniDIN (bt878) + - + + * - 107 + - PHYTEC VD-009-X1 VD-011 Combi (bt878) + - + + * - 108 + - PHYTEC VD-009 MiniDIN (bt878) + - + + * - 109 + - PHYTEC VD-009 Combi (bt878) + - + + * - 110 + - IVC-100 + - ff00:a132 + + * - 111 + - IVC-120G + - ff00:a182, ff01:a182, ff02:a182, ff03:a182, ff04:a182, ff05:a182, ff06:a182, ff07:a182, ff08:a182, ff09:a182, ff0a:a182, ff0b:a182, ff0c:a182, ff0d:a182, ff0e:a182, ff0f:a182 + + * - 112 + - pcHDTV HD-2000 TV + - 7063:2000 + + * - 113 + - Twinhan DST + clones + - 11bd:0026, 1822:0001, 270f:fc00, 1822:0026 + + * - 114 + - Winfast VC100 + - 107d:6607 + + * - 115 + - Teppro TEV-560/InterVision IV-560 + - + + * - 116 + - SIMUS GVC1100 + - aa6a:82b2 + + * - 117 + - NGS NGSTV+ + - + + * - 118 + - LMLBT4 + - + + * - 119 + - Tekram M205 PRO + - + + * - 120 + - Conceptronic CONTVFMi + - + + * - 121 + - Euresys Picolo Tetra + - 1805:0105, 1805:0106, 1805:0107, 1805:0108 + + * - 122 + - Spirit TV Tuner + - + + * - 123 + - AVerMedia AVerTV DVB-T 771 + - 1461:0771 + + * - 124 + - AverMedia AverTV DVB-T 761 + - 1461:0761 + + * - 125 + - MATRIX Vision Sigma-SQ + - + + * - 126 + - MATRIX Vision Sigma-SLC + - + + * - 127 + - APAC Viewcomp 878(AMAX) + - + + * - 128 + - DViCO FusionHDTV DVB-T Lite + - 18ac:db10, 18ac:db11 + + * - 129 + - V-Gear MyVCD + - + + * - 130 + - Super TV Tuner + - + + * - 131 + - Tibet Systems 'Progress DVR' CS16 + - + + * - 132 + - Kodicom 4400R (master) + - + + * - 133 + - Kodicom 4400R (slave) + - + + * - 134 + - Adlink RTV24 + - + + * - 135 + - DViCO FusionHDTV 5 Lite + - 18ac:d500 + + * - 136 + - Acorp Y878F + - 9511:1540 + + * - 137 + - Conceptronic CTVFMi v2 + - 036e:109e + + * - 138 + - Prolink Pixelview PV-BT878P+ (Rev.2E) + - + + * - 139 + - Prolink PixelView PlayTV MPEG2 PV-M4900 + - + + * - 140 + - Osprey 440 + - 0070:ff07 + + * - 141 + - Asound Skyeye PCTV + - + + * - 142 + - Sabrent TV-FM (bttv version) + - + + * - 143 + - Hauppauge ImpactVCB (bt878) + - 0070:13eb + + * - 144 + - MagicTV + - + + * - 145 + - SSAI Security Video Interface + - 4149:5353 + + * - 146 + - SSAI Ultrasound Video Interface + - 414a:5353 + + * - 147 + - VoodooTV 200 (USA) + - 121a:3000 + + * - 148 + - DViCO FusionHDTV 2 + - dbc0:d200 + + * - 149 + - Typhoon TV-Tuner PCI (50684) + - + + * - 150 + - Geovision GV-600 + - 008a:763c + + * - 151 + - Kozumi KTV-01C + - + + * - 152 + - Encore ENL TV-FM-2 + - 1000:1801 + + * - 153 + - PHYTEC VD-012 (bt878) + - + + * - 154 + - PHYTEC VD-012-X1 (bt878) + - + + * - 155 + - PHYTEC VD-012-X2 (bt878) + - + + * - 156 + - IVCE-8784 + - 0000:f050, 0001:f050, 0002:f050, 0003:f050 + + * - 157 + - Geovision GV-800(S) (master) + - 800a:763d + + * - 158 + - Geovision GV-800(S) (slave) + - 800b:763d, 800c:763d, 800d:763d + + * - 159 + - ProVideo PV183 + - 1830:1540, 1831:1540, 1832:1540, 1833:1540, 1834:1540, 1835:1540, 1836:1540, 1837:1540 + + * - 160 + - Tongwei Video Technology TD-3116 + - f200:3116 + + * - 161 + - Aposonic W-DVR + - 0279:0228 + + * - 162 + - Adlink MPG24 + - + + * - 163 + - Bt848 Capture 14MHz + - + + * - 164 + - CyberVision CV06 (SV) + - + + * - 165 + - Kworld V-Stream Xpert TV PVR878 + - + + * - 166 + - PCI-8604PW + - diff --git a/Documentation/media/v4l-drivers/cx23885-cardlist.rst b/Documentation/media/v4l-drivers/cx23885-cardlist.rst index fd20b50d2c1d..3129ef04ddd3 100644 --- a/Documentation/media/v4l-drivers/cx23885-cardlist.rst +++ b/Documentation/media/v4l-drivers/cx23885-cardlist.rst @@ -1,65 +1,245 @@ cx23885 cards list ================== -=========== ==================================== ====================================================================================== -Card number Card name PCI IDs -=========== ==================================== ====================================================================================== -0 UNKNOWN/GENERIC 0070:3400 -1 Hauppauge WinTV-HVR1800lp 0070:7600 -2 Hauppauge WinTV-HVR1800 0070:7800, 0070:7801, 0070:7809 -3 Hauppauge WinTV-HVR1250 0070:7911 -4 DViCO FusionHDTV5 Express 18ac:d500 -5 Hauppauge WinTV-HVR1500Q 0070:7790, 0070:7797 -6 Hauppauge WinTV-HVR1500 0070:7710, 0070:7717 -7 Hauppauge WinTV-HVR1200 0070:71d1, 0070:71d3 -8 Hauppauge WinTV-HVR1700 0070:8101 -9 Hauppauge WinTV-HVR1400 0070:8010 -10 DViCO FusionHDTV7 Dual Express 18ac:d618 -11 DViCO FusionHDTV DVB-T Dual Express 18ac:db78 -12 Leadtek Winfast PxDVR3200 H 107d:6681 -13 Compro VideoMate E650F 185b:e800 -14 TurboSight TBS 6920 6920:8888 -15 TeVii S470 d470:9022 -16 DVBWorld DVB-S2 2005 0001:2005 -17 NetUP Dual DVB-S2 CI 1b55:2a2c -18 Hauppauge WinTV-HVR1270 0070:2211 -19 Hauppauge WinTV-HVR1275 0070:2215, 0070:221d, 0070:22f2 -20 Hauppauge WinTV-HVR1255 0070:2251, 0070:22f1 -21 Hauppauge WinTV-HVR1210 0070:2291, 0070:2295, 0070:2299, 0070:229d, 0070:22f0, 0070:22f3, 0070:22f4, 0070:22f5 -22 Mygica X8506 DMB-TH 14f1:8651 -23 Magic-Pro ProHDTV Extreme 2 14f1:8657 -24 Hauppauge WinTV-HVR1850 0070:8541 -25 Compro VideoMate E800 1858:e800 -26 Hauppauge WinTV-HVR1290 0070:8551 -27 Mygica X8558 PRO DMB-TH 14f1:8578 -28 LEADTEK WinFast PxTV1200 107d:6f22 -29 GoTView X5 3D Hybrid 5654:2390 -30 NetUP Dual DVB-T/C-CI RF 1b55:e2e4 -31 Leadtek Winfast PxDVR3200 H XC4000 107d:6f39 -32 MPX-885 -33 Mygica X8502/X8507 ISDB-T 14f1:8502 -34 TerraTec Cinergy T PCIe Dual 153b:117e -35 TeVii S471 d471:9022 -36 Hauppauge WinTV-HVR1255 0070:2259 -37 Prof Revolution DVB-S2 8000 8000:3034 -38 Hauppauge WinTV-HVR4400/HVR5500 0070:c108, 0070:c138, 0070:c1f8 -39 AVerTV Hybrid Express Slim HC81R 1461:d939 -40 TurboSight TBS 6981 6981:8888 -41 TurboSight TBS 6980 6980:8888 -42 Leadtek Winfast PxPVR2200 107d:6f21 -43 Hauppauge ImpactVCB-e 0070:7133 -44 DViCO FusionHDTV DVB-T Dual Express2 18ac:db98 -45 DVBSky T9580 4254:9580 -46 DVBSky T980C 4254:980c -47 DVBSky S950C 4254:950c -48 Technotrend TT-budget CT2-4500 CI 13c2:3013 -49 DVBSky S950 4254:0950 -50 DVBSky S952 4254:0952 -51 DVBSky T982 4254:0982 -52 Hauppauge WinTV-HVR5525 0070:f038 -53 Hauppauge WinTV Starburst 0070:c12a -54 ViewCast 260e 1576:0260 -55 ViewCast 460e 1576:0460 -56 Hauppauge WinTV-QuadHD-DVB 0070:6a28, 0070:6b28 -57 Hauppauge WinTV-QuadHD-ATSC 0070:6a18, 0070:6b18 -=========== ==================================== ====================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - UNKNOWN/GENERIC + - 0070:3400 + + * - 1 + - Hauppauge WinTV-HVR1800lp + - 0070:7600 + + * - 2 + - Hauppauge WinTV-HVR1800 + - 0070:7800, 0070:7801, 0070:7809 + + * - 3 + - Hauppauge WinTV-HVR1250 + - 0070:7911 + + * - 4 + - DViCO FusionHDTV5 Express + - 18ac:d500 + + * - 5 + - Hauppauge WinTV-HVR1500Q + - 0070:7790, 0070:7797 + + * - 6 + - Hauppauge WinTV-HVR1500 + - 0070:7710, 0070:7717 + + * - 7 + - Hauppauge WinTV-HVR1200 + - 0070:71d1, 0070:71d3 + + * - 8 + - Hauppauge WinTV-HVR1700 + - 0070:8101 + + * - 9 + - Hauppauge WinTV-HVR1400 + - 0070:8010 + + * - 10 + - DViCO FusionHDTV7 Dual Express + - 18ac:d618 + + * - 11 + - DViCO FusionHDTV DVB-T Dual Express + - 18ac:db78 + + * - 12 + - Leadtek Winfast PxDVR3200 H + - 107d:6681 + + * - 13 + - Compro VideoMate E650F + - 185b:e800 + + * - 14 + - TurboSight TBS 6920 + - 6920:8888 + + * - 15 + - TeVii S470 + - d470:9022 + + * - 16 + - DVBWorld DVB-S2 2005 + - 0001:2005 + + * - 17 + - NetUP Dual DVB-S2 CI + - 1b55:2a2c + + * - 18 + - Hauppauge WinTV-HVR1270 + - 0070:2211 + + * - 19 + - Hauppauge WinTV-HVR1275 + - 0070:2215, 0070:221d, 0070:22f2 + + * - 20 + - Hauppauge WinTV-HVR1255 + - 0070:2251, 0070:22f1 + + * - 21 + - Hauppauge WinTV-HVR1210 + - 0070:2291, 0070:2295, 0070:2299, 0070:229d, 0070:22f0, 0070:22f3, 0070:22f4, 0070:22f5 + + * - 22 + - Mygica X8506 DMB-TH + - 14f1:8651 + + * - 23 + - Magic-Pro ProHDTV Extreme 2 + - 14f1:8657 + + * - 24 + - Hauppauge WinTV-HVR1850 + - 0070:8541 + + * - 25 + - Compro VideoMate E800 + - 1858:e800 + + * - 26 + - Hauppauge WinTV-HVR1290 + - 0070:8551 + + * - 27 + - Mygica X8558 PRO DMB-TH + - 14f1:8578 + + * - 28 + - LEADTEK WinFast PxTV1200 + - 107d:6f22 + + * - 29 + - GoTView X5 3D Hybrid + - 5654:2390 + + * - 30 + - NetUP Dual DVB-T/C-CI RF + - 1b55:e2e4 + + * - 31 + - Leadtek Winfast PxDVR3200 H XC4000 + - 107d:6f39 + + * - 32 + - MPX-885 + - + + * - 33 + - Mygica X8502/X8507 ISDB-T + - 14f1:8502 + + * - 34 + - TerraTec Cinergy T PCIe Dual + - 153b:117e + + * - 35 + - TeVii S471 + - d471:9022 + + * - 36 + - Hauppauge WinTV-HVR1255 + - 0070:2259 + + * - 37 + - Prof Revolution DVB-S2 8000 + - 8000:3034 + + * - 38 + - Hauppauge WinTV-HVR4400/HVR5500 + - 0070:c108, 0070:c138, 0070:c1f8 + + * - 39 + - AVerTV Hybrid Express Slim HC81R + - 1461:d939 + + * - 40 + - TurboSight TBS 6981 + - 6981:8888 + + * - 41 + - TurboSight TBS 6980 + - 6980:8888 + + * - 42 + - Leadtek Winfast PxPVR2200 + - 107d:6f21 + + * - 43 + - Hauppauge ImpactVCB-e + - 0070:7133 + + * - 44 + - DViCO FusionHDTV DVB-T Dual Express2 + - 18ac:db98 + + * - 45 + - DVBSky T9580 + - 4254:9580 + + * - 46 + - DVBSky T980C + - 4254:980c + + * - 47 + - DVBSky S950C + - 4254:950c + + * - 48 + - Technotrend TT-budget CT2-4500 CI + - 13c2:3013 + + * - 49 + - DVBSky S950 + - 4254:0950 + + * - 50 + - DVBSky S952 + - 4254:0952 + + * - 51 + - DVBSky T982 + - 4254:0982 + + * - 52 + - Hauppauge WinTV-HVR5525 + - 0070:f038 + + * - 53 + - Hauppauge WinTV Starburst + - 0070:c12a + + * - 54 + - ViewCast 260e + - 1576:0260 + + * - 55 + - ViewCast 460e + - 1576:0460 + + * - 56 + - Hauppauge WinTV-QuadHD-DVB + - 0070:6a28, 0070:6b28 + + * - 57 + - Hauppauge WinTV-QuadHD-ATSC + - 0070:6a18, 0070:6b18 diff --git a/Documentation/media/v4l-drivers/cx88-cardlist.rst b/Documentation/media/v4l-drivers/cx88-cardlist.rst index 8cc1cea17035..21648b8c2e83 100644 --- a/Documentation/media/v4l-drivers/cx88-cardlist.rst +++ b/Documentation/media/v4l-drivers/cx88-cardlist.rst @@ -1,98 +1,377 @@ CX88 cards list =============== -=========== =================================================== ====================================================================================== -Card number Card name PCI IDs -=========== =================================================== ====================================================================================== -0 UNKNOWN/GENERIC -1 Hauppauge WinTV 34xxx models 0070:3400, 0070:3401 -2 GDI Black Gold 14c7:0106, 14c7:0107 -3 PixelView 1554:4811 -4 ATI TV Wonder Pro 1002:00f8, 1002:00f9 -5 Leadtek Winfast 2000XP Expert 107d:6611, 107d:6613 -6 AverTV Studio 303 (M126) 1461:000b -7 MSI TV-@nywhere Master 1462:8606 -8 Leadtek Winfast DV2000 107d:6620, 107d:6621 -9 Leadtek PVR 2000 107d:663b, 107d:663c, 107d:6632, 107d:6630, 107d:6638, 107d:6631, 107d:6637, 107d:663d -10 IODATA GV-VCP3/PCI 10fc:d003 -11 Prolink PlayTV PVR -12 ASUS PVR-416 1043:4823, 1461:c111 -13 MSI TV-@nywhere -14 KWorld/VStream XPert DVB-T 17de:08a6 -15 DViCO FusionHDTV DVB-T1 18ac:db00 -16 KWorld LTV883RF -17 DViCO FusionHDTV 3 Gold-Q 18ac:d810, 18ac:d800 -18 Hauppauge Nova-T DVB-T 0070:9002, 0070:9001, 0070:9000 -19 Conexant DVB-T reference design 14f1:0187 -20 Provideo PV259 1540:2580 -21 DViCO FusionHDTV DVB-T Plus 18ac:db10, 18ac:db11 -22 pcHDTV HD3000 HDTV 7063:3000 -23 digitalnow DNTV Live! DVB-T 17de:a8a6 -24 Hauppauge WinTV 28xxx (Roslyn) models 0070:2801 -25 Digital-Logic MICROSPACE Entertainment Center (MEC) 14f1:0342 -26 IODATA GV/BCTV7E 10fc:d035 -27 PixelView PlayTV Ultra Pro (Stereo) -28 DViCO FusionHDTV 3 Gold-T 18ac:d820 -29 ADS Tech Instant TV DVB-T PCI 1421:0334 -30 TerraTec Cinergy 1400 DVB-T 153b:1166 -31 DViCO FusionHDTV 5 Gold 18ac:d500 -32 AverMedia UltraTV Media Center PCI 550 1461:8011 -33 Kworld V-Stream Xpert DVD -34 ATI HDTV Wonder 1002:a101 -35 WinFast DTV1000-T 107d:665f -36 AVerTV 303 (M126) 1461:000a -37 Hauppauge Nova-S-Plus DVB-S 0070:9201, 0070:9202 -38 Hauppauge Nova-SE2 DVB-S 0070:9200 -39 KWorld DVB-S 100 17de:08b2, 1421:0341 -40 Hauppauge WinTV-HVR1100 DVB-T/Hybrid 0070:9400, 0070:9402 -41 Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) 0070:9800, 0070:9802 -42 digitalnow DNTV Live! DVB-T Pro 1822:0025, 1822:0019 -43 KWorld/VStream XPert DVB-T with cx22702 17de:08a1, 12ab:2300 -44 DViCO FusionHDTV DVB-T Dual Digital 18ac:db50, 18ac:db54 -45 KWorld HardwareMpegTV XPert 17de:0840, 1421:0305 -46 DViCO FusionHDTV DVB-T Hybrid 18ac:db40, 18ac:db44 -47 pcHDTV HD5500 HDTV 7063:5500 -48 Kworld MCE 200 Deluxe 17de:0841 -49 PixelView PlayTV P7000 1554:4813 -50 NPG Tech Real TV FM Top 10 14f1:0842 -51 WinFast DTV2000 H 107d:665e -52 Geniatech DVB-S 14f1:0084 -53 Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T 0070:1404, 0070:1400, 0070:1401, 0070:1402 -54 Norwood Micro TV Tuner -55 Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM c180:c980 -56 Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder 0070:9600, 0070:9601, 0070:9602 -57 ADS Tech Instant Video PCI 1421:0390 -58 Pinnacle PCTV HD 800i 11bd:0051 -59 DViCO FusionHDTV 5 PCI nano 18ac:d530 -60 Pinnacle Hybrid PCTV 12ab:1788 -61 Leadtek TV2000 XP Global 107d:6f18, 107d:6618, 107d:6619 -62 PowerColor RA330 14f1:ea3d -63 Geniatech X8000-MT DVBT 14f1:8852 -64 DViCO FusionHDTV DVB-T PRO 18ac:db30 -65 DViCO FusionHDTV 7 Gold 18ac:d610 -66 Prolink Pixelview MPEG 8000GT 1554:4935 -67 Kworld PlusTV HD PCI 120 (ATSC 120) 17de:08c1 -68 Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid 0070:6900, 0070:6904, 0070:6902 -69 Hauppauge WinTV-HVR4000(Lite) DVB-S/S2 0070:6905, 0070:6906 -70 TeVii S460 DVB-S/S2 d460:9022 -71 Omicom SS4 DVB-S/S2 PCI A044:2011 -72 TBS 8920 DVB-S/S2 8920:8888 -73 TeVii S420 DVB-S d420:9022 -74 Prolink Pixelview Global Extreme 1554:4976 -75 PROF 7300 DVB-S/S2 B033:3033 -76 SATTRADE ST4200 DVB-S/S2 b200:4200 -77 TBS 8910 DVB-S 8910:8888 -78 Prof 6200 DVB-S b022:3022 -79 Terratec Cinergy HT PCI MKII 153b:1177 -80 Hauppauge WinTV-IR Only 0070:9290 -81 Leadtek WinFast DTV1800 Hybrid 107d:6654 -82 WinFast DTV2000 H rev. J 107d:6f2b -83 Prof 7301 DVB-S/S2 b034:3034 -84 Samsung SMT 7020 DVB-S 18ac:dc00, 18ac:dccd -85 Twinhan VP-1027 DVB-S 1822:0023 -86 TeVii S464 DVB-S/S2 d464:9022 -87 Leadtek WinFast DTV2000 H PLUS 107d:6f42 -88 Leadtek WinFast DTV1800 H (XC4000) 107d:6f38 -89 Leadtek TV2000 XP Global (SC4100) 107d:6f36 -90 Leadtek TV2000 XP Global (XC4100) 107d:6f43 -=========== =================================================== ====================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - UNKNOWN/GENERIC + - + + * - 1 + - Hauppauge WinTV 34xxx models + - 0070:3400, 0070:3401 + + * - 2 + - GDI Black Gold + - 14c7:0106, 14c7:0107 + + * - 3 + - PixelView + - 1554:4811 + + * - 4 + - ATI TV Wonder Pro + - 1002:00f8, 1002:00f9 + + * - 5 + - Leadtek Winfast 2000XP Expert + - 107d:6611, 107d:6613 + + * - 6 + - AverTV Studio 303 (M126) + - 1461:000b + + * - 7 + - MSI TV-@nywhere Master + - 1462:8606 + + * - 8 + - Leadtek Winfast DV2000 + - 107d:6620, 107d:6621 + + * - 9 + - Leadtek PVR 2000 + - 107d:663b, 107d:663c, 107d:6632, 107d:6630, 107d:6638, 107d:6631, 107d:6637, 107d:663d + + * - 10 + - IODATA GV-VCP3/PCI + - 10fc:d003 + + * - 11 + - Prolink PlayTV PVR + - + + * - 12 + - ASUS PVR-416 + - 1043:4823, 1461:c111 + + * - 13 + - MSI TV-@nywhere + - + + * - 14 + - KWorld/VStream XPert DVB-T + - 17de:08a6 + + * - 15 + - DViCO FusionHDTV DVB-T1 + - 18ac:db00 + + * - 16 + - KWorld LTV883RF + - + + * - 17 + - DViCO FusionHDTV 3 Gold-Q + - 18ac:d810, 18ac:d800 + + * - 18 + - Hauppauge Nova-T DVB-T + - 0070:9002, 0070:9001, 0070:9000 + + * - 19 + - Conexant DVB-T reference design + - 14f1:0187 + + * - 20 + - Provideo PV259 + - 1540:2580 + + * - 21 + - DViCO FusionHDTV DVB-T Plus + - 18ac:db10, 18ac:db11 + + * - 22 + - pcHDTV HD3000 HDTV + - 7063:3000 + + * - 23 + - digitalnow DNTV Live! DVB-T + - 17de:a8a6 + + * - 24 + - Hauppauge WinTV 28xxx (Roslyn) models + - 0070:2801 + + * - 25 + - Digital-Logic MICROSPACE Entertainment Center (MEC) + - 14f1:0342 + + * - 26 + - IODATA GV/BCTV7E + - 10fc:d035 + + * - 27 + - PixelView PlayTV Ultra Pro (Stereo) + - + + * - 28 + - DViCO FusionHDTV 3 Gold-T + - 18ac:d820 + + * - 29 + - ADS Tech Instant TV DVB-T PCI + - 1421:0334 + + * - 30 + - TerraTec Cinergy 1400 DVB-T + - 153b:1166 + + * - 31 + - DViCO FusionHDTV 5 Gold + - 18ac:d500 + + * - 32 + - AverMedia UltraTV Media Center PCI 550 + - 1461:8011 + + * - 33 + - Kworld V-Stream Xpert DVD + - + + * - 34 + - ATI HDTV Wonder + - 1002:a101 + + * - 35 + - WinFast DTV1000-T + - 107d:665f + + * - 36 + - AVerTV 303 (M126) + - 1461:000a + + * - 37 + - Hauppauge Nova-S-Plus DVB-S + - 0070:9201, 0070:9202 + + * - 38 + - Hauppauge Nova-SE2 DVB-S + - 0070:9200 + + * - 39 + - KWorld DVB-S 100 + - 17de:08b2, 1421:0341 + + * - 40 + - Hauppauge WinTV-HVR1100 DVB-T/Hybrid + - 0070:9400, 0070:9402 + + * - 41 + - Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) + - 0070:9800, 0070:9802 + + * - 42 + - digitalnow DNTV Live! DVB-T Pro + - 1822:0025, 1822:0019 + + * - 43 + - KWorld/VStream XPert DVB-T with cx22702 + - 17de:08a1, 12ab:2300 + + * - 44 + - DViCO FusionHDTV DVB-T Dual Digital + - 18ac:db50, 18ac:db54 + + * - 45 + - KWorld HardwareMpegTV XPert + - 17de:0840, 1421:0305 + + * - 46 + - DViCO FusionHDTV DVB-T Hybrid + - 18ac:db40, 18ac:db44 + + * - 47 + - pcHDTV HD5500 HDTV + - 7063:5500 + + * - 48 + - Kworld MCE 200 Deluxe + - 17de:0841 + + * - 49 + - PixelView PlayTV P7000 + - 1554:4813 + + * - 50 + - NPG Tech Real TV FM Top 10 + - 14f1:0842 + + * - 51 + - WinFast DTV2000 H + - 107d:665e + + * - 52 + - Geniatech DVB-S + - 14f1:0084 + + * - 53 + - Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T + - 0070:1404, 0070:1400, 0070:1401, 0070:1402 + + * - 54 + - Norwood Micro TV Tuner + - + + * - 55 + - Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM + - c180:c980 + + * - 56 + - Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder + - 0070:9600, 0070:9601, 0070:9602 + + * - 57 + - ADS Tech Instant Video PCI + - 1421:0390 + + * - 58 + - Pinnacle PCTV HD 800i + - 11bd:0051 + + * - 59 + - DViCO FusionHDTV 5 PCI nano + - 18ac:d530 + + * - 60 + - Pinnacle Hybrid PCTV + - 12ab:1788 + + * - 61 + - Leadtek TV2000 XP Global + - 107d:6f18, 107d:6618, 107d:6619 + + * - 62 + - PowerColor RA330 + - 14f1:ea3d + + * - 63 + - Geniatech X8000-MT DVBT + - 14f1:8852 + + * - 64 + - DViCO FusionHDTV DVB-T PRO + - 18ac:db30 + + * - 65 + - DViCO FusionHDTV 7 Gold + - 18ac:d610 + + * - 66 + - Prolink Pixelview MPEG 8000GT + - 1554:4935 + + * - 67 + - Kworld PlusTV HD PCI 120 (ATSC 120) + - 17de:08c1 + + * - 68 + - Hauppauge WinTV-HVR4000 DVB-S/S2/T/Hybrid + - 0070:6900, 0070:6904, 0070:6902 + + * - 69 + - Hauppauge WinTV-HVR4000(Lite) DVB-S/S2 + - 0070:6905, 0070:6906 + + * - 70 + - TeVii S460 DVB-S/S2 + - d460:9022 + + * - 71 + - Omicom SS4 DVB-S/S2 PCI + - A044:2011 + + * - 72 + - TBS 8920 DVB-S/S2 + - 8920:8888 + + * - 73 + - TeVii S420 DVB-S + - d420:9022 + + * - 74 + - Prolink Pixelview Global Extreme + - 1554:4976 + + * - 75 + - PROF 7300 DVB-S/S2 + - B033:3033 + + * - 76 + - SATTRADE ST4200 DVB-S/S2 + - b200:4200 + + * - 77 + - TBS 8910 DVB-S + - 8910:8888 + + * - 78 + - Prof 6200 DVB-S + - b022:3022 + + * - 79 + - Terratec Cinergy HT PCI MKII + - 153b:1177 + + * - 80 + - Hauppauge WinTV-IR Only + - 0070:9290 + + * - 81 + - Leadtek WinFast DTV1800 Hybrid + - 107d:6654 + + * - 82 + - WinFast DTV2000 H rev. J + - 107d:6f2b + + * - 83 + - Prof 7301 DVB-S/S2 + - b034:3034 + + * - 84 + - Samsung SMT 7020 DVB-S + - 18ac:dc00, 18ac:dccd + + * - 85 + - Twinhan VP-1027 DVB-S + - 1822:0023 + + * - 86 + - TeVii S464 DVB-S/S2 + - d464:9022 + + * - 87 + - Leadtek WinFast DTV2000 H PLUS + - 107d:6f42 + + * - 88 + - Leadtek WinFast DTV1800 H (XC4000) + - 107d:6f38 + + * - 89 + - Leadtek TV2000 XP Global (SC4100) + - 107d:6f36 + + * - 90 + - Leadtek TV2000 XP Global (XC4100) + - 107d:6f43 diff --git a/Documentation/media/v4l-drivers/em28xx-cardlist.rst b/Documentation/media/v4l-drivers/em28xx-cardlist.rst index 76b1d301754c..ec938c08f43d 100644 --- a/Documentation/media/v4l-drivers/em28xx-cardlist.rst +++ b/Documentation/media/v4l-drivers/em28xx-cardlist.rst @@ -1,107 +1,422 @@ EM28xx cards list ================= -=========== ==================================================================== ================ ================================================================================================================================== -Card number Card name Empia Chip USB IDs -=========== ==================================================================== ================ ================================================================================================================================== -0 Unknown EM2800 video grabber em2800 eb1a:2800 -1 Unknown EM2750/28xx video grabber em2820 or em2840 eb1a:2710, eb1a:2820, eb1a:2821, eb1a:2860, eb1a:2861, eb1a:2862, eb1a:2863, eb1a:2870, eb1a:2881, eb1a:2883, eb1a:2868, eb1a:2875 -2 Terratec Cinergy 250 USB em2820 or em2840 0ccd:0036 -3 Pinnacle PCTV USB 2 em2820 or em2840 2304:0208 -4 Hauppauge WinTV USB 2 em2820 or em2840 2040:4200, 2040:4201 -5 MSI VOX USB 2.0 em2820 or em2840 -6 Terratec Cinergy 200 USB em2800 -7 Leadtek Winfast USB II em2800 0413:6023 -8 Kworld USB2800 em2800 -9 Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker em2820 or em2840 1b80:e302, 1b80:e304, 2304:0207, 2304:021a, 093b:a003 -10 Hauppauge WinTV HVR 900 em2880 2040:6500 -11 Terratec Hybrid XS em2880 -12 Kworld PVR TV 2800 RF em2820 or em2840 -13 Terratec Prodigy XS em2880 -14 SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 em2820 or em2840 -15 V-Gear PocketTV em2800 -16 Hauppauge WinTV HVR 950 em2883 2040:6513, 2040:6517, 2040:651b -17 Pinnacle PCTV HD Pro Stick em2880 2304:0227 -18 Hauppauge WinTV HVR 900 (R2) em2880 2040:6502 -19 EM2860/SAA711X Reference Design em2860 -20 AMD ATI TV Wonder HD 600 em2880 0438:b002 -21 eMPIA Technology, Inc. GrabBeeX+ Video Encoder em2800 eb1a:2801 -22 EM2710/EM2750/EM2751 webcam grabber em2750 eb1a:2750, eb1a:2751 -23 Huaqi DLCW-130 em2750 -24 D-Link DUB-T210 TV Tuner em2820 or em2840 2001:f112 -25 Gadmei UTV310 em2820 or em2840 -26 Hercules Smart TV USB 2.0 em2820 or em2840 -27 Pinnacle PCTV USB 2 (Philips FM1216ME) em2820 or em2840 -28 Leadtek Winfast USB II Deluxe em2820 or em2840 -29 EM2860/TVP5150 Reference Design em2860 -30 Videology 20K14XUSB USB2.0 em2820 or em2840 -31 Usbgear VD204v9 em2821 -32 Supercomp USB 2.0 TV em2821 -33 Elgato Video Capture em2860 0fd9:0033 -34 Terratec Cinergy A Hybrid XS em2860 0ccd:004f -35 Typhoon DVD Maker em2860 -36 NetGMBH Cam em2860 -37 Gadmei UTV330 em2860 eb1a:50a6 -38 Yakumo MovieMixer em2861 -39 KWorld PVRTV 300U em2861 eb1a:e300 -40 Plextor ConvertX PX-TV100U em2861 093b:a005 -41 Kworld 350 U DVB-T em2870 eb1a:e350 -42 Kworld 355 U DVB-T em2870 eb1a:e355, eb1a:e357, eb1a:e359 -43 Terratec Cinergy T XS em2870 -44 Terratec Cinergy T XS (MT2060) em2870 0ccd:0043 -45 Pinnacle PCTV DVB-T em2870 -46 Compro, VideoMate U3 em2870 185b:2870 -47 KWorld DVB-T 305U em2880 eb1a:e305 -48 KWorld DVB-T 310U em2880 -49 MSI DigiVox A/D em2880 eb1a:e310 -50 MSI DigiVox A/D II em2880 eb1a:e320 -51 Terratec Hybrid XS Secam em2880 0ccd:004c -52 DNT DA2 Hybrid em2881 -53 Pinnacle Hybrid Pro em2881 -54 Kworld VS-DVB-T 323UR em2882 eb1a:e323 -55 Terratec Cinnergy Hybrid T USB XS (em2882) em2882 0ccd:005e, 0ccd:0042 -56 Pinnacle Hybrid Pro (330e) em2882 2304:0226 -57 Kworld PlusTV HD Hybrid 330 em2883 eb1a:a316 -58 Compro VideoMate ForYou/Stereo em2820 or em2840 185b:2041 -59 Pinnacle PCTV HD Mini em2874 2304:023f -60 Hauppauge WinTV HVR 850 em2883 2040:651f -61 Pixelview PlayTV Box 4 USB 2.0 em2820 or em2840 -62 Gadmei TVR200 em2820 or em2840 -63 Kaiomy TVnPC U2 em2860 eb1a:e303 -64 Easy Cap Capture DC-60 em2860 1b80:e309 -65 IO-DATA GV-MVP/SZ em2820 or em2840 04bb:0515 -66 Empire dual TV em2880 -67 Terratec Grabby em2860 0ccd:0096, 0ccd:10AF -68 Terratec AV350 em2860 0ccd:0084 -69 KWorld ATSC 315U HDTV TV Box em2882 eb1a:a313 -70 Evga inDtube em2882 -71 Silvercrest Webcam 1.3mpix em2820 or em2840 -72 Gadmei UTV330+ em2861 -73 Reddo DVB-C USB TV Box em2870 -74 Actionmaster/LinXcel/Digitus VC211A em2800 -75 Dikom DK300 em2882 -76 KWorld PlusTV 340U or UB435-Q (ATSC) em2870 1b80:a340 -77 EM2874 Leadership ISDBT em2874 -78 PCTV nanoStick T2 290e em28174 2013:024f -79 Terratec Cinergy H5 em2884 eb1a:2885, 0ccd:10a2, 0ccd:10ad, 0ccd:10b6 -80 PCTV DVB-S2 Stick (460e) em28174 2013:024c -81 Hauppauge WinTV HVR 930C em2884 2040:1605 -82 Terratec Cinergy HTC Stick em2884 0ccd:00b2 -83 Honestech Vidbox NW03 em2860 eb1a:5006 -84 MaxMedia UB425-TC em2874 1b80:e425 -85 PCTV QuatroStick (510e) em2884 2304:0242 -86 PCTV QuatroStick nano (520e) em2884 2013:0251 -87 Terratec Cinergy HTC USB XS em2884 0ccd:008e, 0ccd:00ac -88 C3 Tech Digital Duo HDTV/SDTV USB em2884 1b80:e755 -89 Delock 61959 em2874 1b80:e1cc -90 KWorld USB ATSC TV Stick UB435-Q V2 em2874 1b80:e346 -91 SpeedLink Vicious And Devine Laplace webcam em2765 1ae7:9003, 1ae7:9004 -92 PCTV DVB-S2 Stick (461e) em28178 2013:0258 -93 KWorld USB ATSC TV Stick UB435-Q V3 em2874 1b80:e34c -94 PCTV tripleStick (292e) em28178 2013:025f, 2040:0264 -95 Leadtek VC100 em2861 0413:6f07 -96 Terratec Cinergy T2 Stick HD em28178 eb1a:8179 -97 Elgato EyeTV Hybrid 2008 INT em2884 0fd9:0018 -98 PLEX PX-BCUD em28178 3275:0085 -99 Hauppauge WinTV-dualHD DVB em28174 2040:0265 -=========== ==================================================================== ================ ================================================================================================================================== +.. tabularcolumns:: |p{1.4cm}|p{10.0cm}|p{1.9cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 12 3 16 + :stub-columns: 0 + + * - Card number + - Card name + - Empia Chip + - USB IDs + * - 0 + - Unknown EM2800 video grabber + - em2800 + - eb1a:2800 + * - 1 + - Unknown EM2750/28xx video grabber + - em2820 or em2840 + - eb1a:2710, eb1a:2820, eb1a:2821, eb1a:2860, eb1a:2861, eb1a:2862, eb1a:2863, eb1a:2870, eb1a:2881, eb1a:2883, eb1a:2868, eb1a:2875 + * - 2 + - Terratec Cinergy 250 USB + - em2820 or em2840 + - 0ccd:0036 + * - 3 + - Pinnacle PCTV USB 2 + - em2820 or em2840 + - 2304:0208 + * - 4 + - Hauppauge WinTV USB 2 + - em2820 or em2840 + - 2040:4200, 2040:4201 + * - 5 + - MSI VOX USB 2.0 + - em2820 or em2840 + - + * - 6 + - Terratec Cinergy 200 USB + - em2800 + - + * - 7 + - Leadtek Winfast USB II + - em2800 + - 0413:6023 + * - 8 + - Kworld USB2800 + - em2800 + - + * - 9 + - Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker / Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U + - em2820 or em2840 + - 1b80:e302, 1b80:e304, 2304:0207, 2304:021a, 093b:a003 + * - 10 + - Hauppauge WinTV HVR 900 + - em2880 + - 2040:6500 + * - 11 + - Terratec Hybrid XS + - em2880 + - + * - 12 + - Kworld PVR TV 2800 RF + - em2820 or em2840 + - + * - 13 + - Terratec Prodigy XS + - em2880 + - + * - 14 + - SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 + - em2820 or em2840 + - + * - 15 + - V-Gear PocketTV + - em2800 + - + * - 16 + - Hauppauge WinTV HVR 950 + - em2883 + - 2040:6513, 2040:6517, 2040:651b + * - 17 + - Pinnacle PCTV HD Pro Stick + - em2880 + - 2304:0227 + * - 18 + - Hauppauge WinTV HVR 900 (R2) + - em2880 + - 2040:6502 + * - 19 + - EM2860/SAA711X Reference Design + - em2860 + - + * - 20 + - AMD ATI TV Wonder HD 600 + - em2880 + - 0438:b002 + * - 21 + - eMPIA Technology, Inc. GrabBeeX+ Video Encoder + - em2800 + - eb1a:2801 + * - 22 + - EM2710/EM2750/EM2751 webcam grabber + - em2750 + - eb1a:2750, eb1a:2751 + * - 23 + - Huaqi DLCW-130 + - em2750 + - + * - 24 + - D-Link DUB-T210 TV Tuner + - em2820 or em2840 + - 2001:f112 + * - 25 + - Gadmei UTV310 + - em2820 or em2840 + - + * - 26 + - Hercules Smart TV USB 2.0 + - em2820 or em2840 + - + * - 27 + - Pinnacle PCTV USB 2 (Philips FM1216ME) + - em2820 or em2840 + - + * - 28 + - Leadtek Winfast USB II Deluxe + - em2820 or em2840 + - + * - 29 + - EM2860/TVP5150 Reference Design + - em2860 + - eb1a:5051 + * - 30 + - Videology 20K14XUSB USB2.0 + - em2820 or em2840 + - + * - 31 + - Usbgear VD204v9 + - em2821 + - + * - 32 + - Supercomp USB 2.0 TV + - em2821 + - + * - 33 + - Elgato Video Capture + - em2860 + - 0fd9:0033 + * - 34 + - Terratec Cinergy A Hybrid XS + - em2860 + - 0ccd:004f + * - 35 + - Typhoon DVD Maker + - em2860 + - + * - 36 + - NetGMBH Cam + - em2860 + - + * - 37 + - Gadmei UTV330 + - em2860 + - eb1a:50a6 + * - 38 + - Yakumo MovieMixer + - em2861 + - + * - 39 + - KWorld PVRTV 300U + - em2861 + - eb1a:e300 + * - 40 + - Plextor ConvertX PX-TV100U + - em2861 + - 093b:a005 + * - 41 + - Kworld 350 U DVB-T + - em2870 + - eb1a:e350 + * - 42 + - Kworld 355 U DVB-T + - em2870 + - eb1a:e355, eb1a:e357, eb1a:e359 + * - 43 + - Terratec Cinergy T XS + - em2870 + - + * - 44 + - Terratec Cinergy T XS (MT2060) + - em2870 + - 0ccd:0043 + * - 45 + - Pinnacle PCTV DVB-T + - em2870 + - + * - 46 + - Compro, VideoMate U3 + - em2870 + - 185b:2870 + * - 47 + - KWorld DVB-T 305U + - em2880 + - eb1a:e305 + * - 48 + - KWorld DVB-T 310U + - em2880 + - + * - 49 + - MSI DigiVox A/D + - em2880 + - eb1a:e310 + * - 50 + - MSI DigiVox A/D II + - em2880 + - eb1a:e320 + * - 51 + - Terratec Hybrid XS Secam + - em2880 + - 0ccd:004c + * - 52 + - DNT DA2 Hybrid + - em2881 + - + * - 53 + - Pinnacle Hybrid Pro + - em2881 + - + * - 54 + - Kworld VS-DVB-T 323UR + - em2882 + - eb1a:e323 + * - 55 + - Terratec Cinnergy Hybrid T USB XS (em2882) + - em2882 + - 0ccd:005e, 0ccd:0042 + * - 56 + - Pinnacle Hybrid Pro (330e) + - em2882 + - 2304:0226 + * - 57 + - Kworld PlusTV HD Hybrid 330 + - em2883 + - eb1a:a316 + * - 58 + - Compro VideoMate ForYou/Stereo + - em2820 or em2840 + - 185b:2041 + * - 59 + - Pinnacle PCTV HD Mini + - em2874 + - 2304:023f + * - 60 + - Hauppauge WinTV HVR 850 + - em2883 + - 2040:651f + * - 61 + - Pixelview PlayTV Box 4 USB 2.0 + - em2820 or em2840 + - + * - 62 + - Gadmei TVR200 + - em2820 or em2840 + - + * - 63 + - Kaiomy TVnPC U2 + - em2860 + - eb1a:e303 + * - 64 + - Easy Cap Capture DC-60 + - em2860 + - 1b80:e309 + * - 65 + - IO-DATA GV-MVP/SZ + - em2820 or em2840 + - 04bb:0515 + * - 66 + - Empire dual TV + - em2880 + - + * - 67 + - Terratec Grabby + - em2860 + - 0ccd:0096, 0ccd:10AF + * - 68 + - Terratec AV350 + - em2860 + - 0ccd:0084 + * - 69 + - KWorld ATSC 315U HDTV TV Box + - em2882 + - eb1a:a313 + * - 70 + - Evga inDtube + - em2882 + - + * - 71 + - Silvercrest Webcam 1.3mpix + - em2820 or em2840 + - + * - 72 + - Gadmei UTV330+ + - em2861 + - + * - 73 + - Reddo DVB-C USB TV Box + - em2870 + - + * - 74 + - Actionmaster/LinXcel/Digitus VC211A + - em2800 + - + * - 75 + - Dikom DK300 + - em2882 + - + * - 76 + - KWorld PlusTV 340U or UB435-Q (ATSC) + - em2870 + - 1b80:a340 + * - 77 + - EM2874 Leadership ISDBT + - em2874 + - + * - 78 + - PCTV nanoStick T2 290e + - em28174 + - 2013:024f + * - 79 + - Terratec Cinergy H5 + - em2884 + - eb1a:2885, 0ccd:10a2, 0ccd:10ad, 0ccd:10b6 + * - 80 + - PCTV DVB-S2 Stick (460e) + - em28174 + - 2013:024c + * - 81 + - Hauppauge WinTV HVR 930C + - em2884 + - 2040:1605 + * - 82 + - Terratec Cinergy HTC Stick + - em2884 + - 0ccd:00b2 + * - 83 + - Honestech Vidbox NW03 + - em2860 + - eb1a:5006 + * - 84 + - MaxMedia UB425-TC + - em2874 + - 1b80:e425 + * - 85 + - PCTV QuatroStick (510e) + - em2884 + - 2304:0242 + * - 86 + - PCTV QuatroStick nano (520e) + - em2884 + - 2013:0251 + * - 87 + - Terratec Cinergy HTC USB XS + - em2884 + - 0ccd:008e, 0ccd:00ac + * - 88 + - C3 Tech Digital Duo HDTV/SDTV USB + - em2884 + - 1b80:e755 + * - 89 + - Delock 61959 + - em2874 + - 1b80:e1cc + * - 90 + - KWorld USB ATSC TV Stick UB435-Q V2 + - em2874 + - 1b80:e346 + * - 91 + - SpeedLink Vicious And Devine Laplace webcam + - em2765 + - 1ae7:9003, 1ae7:9004 + * - 92 + - PCTV DVB-S2 Stick (461e) + - em28178 + - 2013:0258 + * - 93 + - KWorld USB ATSC TV Stick UB435-Q V3 + - em2874 + - 1b80:e34c + * - 94 + - PCTV tripleStick (292e) + - em28178 + - 2013:025f, 2040:0264 + * - 95 + - Leadtek VC100 + - em2861 + - 0413:6f07 + * - 96 + - Terratec Cinergy T2 Stick HD + - em28178 + - eb1a:8179 + * - 97 + - Elgato EyeTV Hybrid 2008 INT + - em2884 + - 0fd9:0018 + * - 98 + - PLEX PX-BCUD + - em28178 + - 3275:0085 + * - 99 + - Hauppauge WinTV-dualHD DVB + - em28174 + - 2040:0265 + * - 100 + - Hauppauge WinTV-dualHD 01595 ATSC/QAM + - em28174 + - 2040:026d + * - 101 + - Terratec Cinergy H6 rev. 2 + - em2884 + - 0ccd:10b2 diff --git a/Documentation/media/v4l-drivers/index.rst b/Documentation/media/v4l-drivers/index.rst index 10f2ce42ece2..679238e786a7 100644 --- a/Documentation/media/v4l-drivers/index.rst +++ b/Documentation/media/v4l-drivers/index.rst @@ -21,7 +21,9 @@ more details. For more details see the file COPYING in the source distribution of Linux. -.. class:: toc-title +.. only:: html + + .. class:: toc-title Table of Contents @@ -50,6 +52,7 @@ For more details see the file COPYING in the source distribution of Linux. philips pvrusb2 pxa_camera + qcom_camss radiotrack rcar-fdp1 saa7134 diff --git a/Documentation/media/v4l-drivers/ivtv-cardlist.rst b/Documentation/media/v4l-drivers/ivtv-cardlist.rst index 754ffa820b4c..022dca80c2c8 100644 --- a/Documentation/media/v4l-drivers/ivtv-cardlist.rst +++ b/Documentation/media/v4l-drivers/ivtv-cardlist.rst @@ -1,38 +1,137 @@ IVTV cards list =============== -=========== ============================================================= ==================================================== -Card number Card name PCI IDs -=========== ============================================================= ==================================================== -0 Hauppauge WinTV PVR-250 IVTV16 104d:813d -1 Hauppauge WinTV PVR-350 IVTV16 104d:813d -2 Hauppauge WinTV PVR-150 IVTV16 104d:813d -3 AVerMedia M179 IVTV15 1461:a3cf, IVTV15 1461:a3ce -4 Yuan MPG600, Kuroutoshikou ITVC16-STVLP IVTV16 12ab:fff3, IVTV16 12ab:ffff -5 YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI IVTV15 10fc:40a0 -6 Yuan PG600, Diamond PVR-550 IVTV16 ff92:0070, IVTV16 ffab:0600 -7 Adaptec VideOh! AVC-2410 IVTV16 9005:0093 -8 Adaptec VideOh! AVC-2010 IVTV16 9005:0092 -9 Nagase Transgear 5000TV IVTV16 1461:bfff -10 AOpen VA2000MAX-SNT6 IVTV16 0000:ff5f -11 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP IVTV16 12ab:0600, IVTV16 fbab:0600, IVTV16 1154:0523 -12 I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) IVTV16 10fc:d01e, IVTV16 10fc:d038, IVTV16 10fc:d039 -13 I/O Data GV-MVP/RX2E IVTV16 10fc:d025 -14 GotView PCI DVD IVTV16 12ab:0600 -15 GotView PCI DVD2 Deluxe IVTV16 ffac:0600 -16 Yuan MPC622 IVTV16 ff01:d998 -17 Digital Cowboy DCT-MTVP1 IVTV16 1461:bfff -18 Yuan PG600-2, GotView PCI DVD Lite IVTV16 ffab:0600, IVTV16 ffad:0600 -19 Club3D ZAP-TV1x01 IVTV16 ffab:0600 -20 AVerTV MCE 116 Plus IVTV16 1461:c439 -21 ASUS Falcon2 IVTV16 1043:4b66, IVTV16 1043:462e, IVTV16 1043:4b2e -22 AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner IVTV16 1461:c034, IVTV16 1461:c035 -23 AVerMedia EZMaker PCI Deluxe IVTV16 1461:c03f -24 AVerMedia M104 IVTV16 1461:c136 -25 Buffalo PC-MV5L/PCI IVTV16 1154:052b -26 AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner IVTV16 1461:c019, IVTV16 1461:c01b -27 Sony VAIO Giga Pocket (ENX Kikyou) IVTV16 104d:813d -28 Hauppauge WinTV PVR-350 (V1) IVTV16 104d:813d -29 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR) IVTV16 104d:813d -30 Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS) IVTV16 104d:813d -=========== ============================================================= ==================================================== +.. tabularcolumns:: |p{1.4cm}|p{12.7cm}|p{3.4cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - Hauppauge WinTV PVR-250 + - IVTV16 104d:813d + + * - 1 + - Hauppauge WinTV PVR-350 + - IVTV16 104d:813d + + * - 2 + - Hauppauge WinTV PVR-150 + - IVTV16 104d:813d + + * - 3 + - AVerMedia M179 + - IVTV15 1461:a3cf, IVTV15 1461:a3ce + + * - 4 + - Yuan MPG600, Kuroutoshikou ITVC16-STVLP + - IVTV16 12ab:fff3, IVTV16 12ab:ffff + + * - 5 + - YUAN MPG160, Kuroutoshikou ITVC15-STVLP, I/O Data GV-M2TV/PCI + - IVTV15 10fc:40a0 + + * - 6 + - Yuan PG600, Diamond PVR-550 + - IVTV16 ff92:0070, IVTV16 ffab:0600 + + * - 7 + - Adaptec VideOh! AVC-2410 + - IVTV16 9005:0093 + + * - 8 + - Adaptec VideOh! AVC-2010 + - IVTV16 9005:0092 + + * - 9 + - Nagase Transgear 5000TV + - IVTV16 1461:bfff + + * - 10 + - AOpen VA2000MAX-SNT6 + - IVTV16 0000:ff5f + + * - 11 + - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP + - IVTV16 12ab:0600, IVTV16 fbab:0600, IVTV16 1154:0523 + + * - 12 + - I/O Data GV-MVP/RX, GV-MVP/RX2W (dual tuner) + - IVTV16 10fc:d01e, IVTV16 10fc:d038, IVTV16 10fc:d039 + + * - 13 + - I/O Data GV-MVP/RX2E + - IVTV16 10fc:d025 + + * - 14 + - GotView PCI DVD + - IVTV16 12ab:0600 + + * - 15 + - GotView PCI DVD2 Deluxe + - IVTV16 ffac:0600 + + * - 16 + - Yuan MPC622 + - IVTV16 ff01:d998 + + * - 17 + - Digital Cowboy DCT-MTVP1 + - IVTV16 1461:bfff + + * - 18 + - Yuan PG600-2, GotView PCI DVD Lite + - IVTV16 ffab:0600, IVTV16 ffad:0600 + + * - 19 + - Club3D ZAP-TV1x01 + - IVTV16 ffab:0600 + + * - 20 + - AVerTV MCE 116 Plus + - IVTV16 1461:c439 + + * - 21 + - ASUS Falcon2 + - IVTV16 1043:4b66, IVTV16 1043:462e, IVTV16 1043:4b2e + + * - 22 + - AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner + - IVTV16 1461:c034, IVTV16 1461:c035 + + * - 23 + - AVerMedia EZMaker PCI Deluxe + - IVTV16 1461:c03f + + * - 24 + - AVerMedia M104 + - IVTV16 1461:c136 + + * - 25 + - Buffalo PC-MV5L/PCI + - IVTV16 1154:052b + + * - 26 + - AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner + - IVTV16 1461:c019, IVTV16 1461:c01b + + * - 27 + - Sony VAIO Giga Pocket (ENX Kikyou) + - IVTV16 104d:813d + + * - 28 + - Hauppauge WinTV PVR-350 (V1) + - IVTV16 104d:813d + + * - 29 + - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR) + - IVTV16 104d:813d + + * - 30 + - Yuan MPG600GR, Kuroutoshikou CX23416GYC-STVLP (no GR/YCS) + - IVTV16 104d:813d diff --git a/Documentation/media/v4l-drivers/qcom_camss.rst b/Documentation/media/v4l-drivers/qcom_camss.rst new file mode 100644 index 000000000000..9e66b7b5770f --- /dev/null +++ b/Documentation/media/v4l-drivers/qcom_camss.rst @@ -0,0 +1,156 @@ +.. include:: + +Qualcomm Camera Subsystem driver +================================ + +Introduction +------------ + +This file documents the Qualcomm Camera Subsystem driver located under +drivers/media/platform/qcom/camss-8x16. + +The current version of the driver supports the Camera Subsystem found on +Qualcomm MSM8916 and APQ8016 processors. + +The driver implements V4L2, Media controller and V4L2 subdev interfaces. +Camera sensor using V4L2 subdev interface in the kernel is supported. + +The driver is implemented using as a reference the Qualcomm Camera Subsystem +driver for Android as found in Code Aurora [#f1]_. + + +Qualcomm Camera Subsystem hardware +---------------------------------- + +The Camera Subsystem hardware found on 8x16 processors and supported by the +driver consists of: + +- 2 CSIPHY modules. They handle the Physical layer of the CSI2 receivers. + A separate camera sensor can be connected to each of the CSIPHY module; +- 2 CSID (CSI Decoder) modules. They handle the Protocol and Application layer + of the CSI2 receivers. A CSID can decode data stream from any of the CSIPHY. + Each CSID also contains a TG (Test Generator) block which can generate + artificial input data for test purposes; +- ISPIF (ISP Interface) module. Handles the routing of the data streams from + the CSIDs to the inputs of the VFE; +- VFE (Video Front End) module. Contains a pipeline of image processing hardware + blocks. The VFE has different input interfaces. The PIX (Pixel) input + interface feeds the input data to the image processing pipeline. The image + processing pipeline contains also a scale and crop module at the end. Three + RDI (Raw Dump Interface) input interfaces bypass the image processing + pipeline. The VFE also contains the AXI bus interface which writes the output + data to memory. + + +Supported functionality +----------------------- + +The current version of the driver supports: + +- Input from camera sensor via CSIPHY; +- Generation of test input data by the TG in CSID; +- RDI interface of VFE - raw dump of the input data to memory. + + Supported formats: + + - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / + V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY); + - MIPI RAW8 (8bit Bayer RAW - V4L2_PIX_FMT_SRGGB8 / + V4L2_PIX_FMT_SGRBG8 / V4L2_PIX_FMT_SGBRG8 / V4L2_PIX_FMT_SBGGR8); + - MIPI RAW10 (10bit packed Bayer RAW - V4L2_PIX_FMT_SBGGR10P / + V4L2_PIX_FMT_SGBRG10P / V4L2_PIX_FMT_SGRBG10P / V4L2_PIX_FMT_SRGGB10P); + - MIPI RAW12 (12bit packed Bayer RAW - V4L2_PIX_FMT_SRGGB12P / + V4L2_PIX_FMT_SGBRG12P / V4L2_PIX_FMT_SGRBG12P / V4L2_PIX_FMT_SRGGB12P). + +- PIX interface of VFE + + - Format conversion of the input data. + + Supported input formats: + + - YUYV/UYVY/YVYU/VYUY (packed YUV 4:2:2 - V4L2_PIX_FMT_YUYV / + V4L2_PIX_FMT_UYVY / V4L2_PIX_FMT_YVYU / V4L2_PIX_FMT_VYUY). + + Supported output formats: + + - NV12/NV21 (two plane YUV 4:2:0 - V4L2_PIX_FMT_NV12 / V4L2_PIX_FMT_NV21); + - NV16/NV61 (two plane YUV 4:2:2 - V4L2_PIX_FMT_NV16 / V4L2_PIX_FMT_NV61). + + - Scaling support. Configuration of the VFE Encoder Scale module + for downscalling with ratio up to 16x. + + - Cropping support. Configuration of the VFE Encoder Crop module. + +- Concurrent and independent usage of two data inputs - could be camera sensors + and/or TG. + + +Driver Architecture and Design +------------------------------ + +The driver implements the V4L2 subdev interface. With the goal to model the +hardware links between the modules and to expose a clean, logical and usable +interface, the driver is split into V4L2 sub-devices as follows: + +- 2 CSIPHY sub-devices - each CSIPHY is represented by a single sub-device; +- 2 CSID sub-devices - each CSID is represented by a single sub-device; +- 2 ISPIF sub-devices - ISPIF is represented by a number of sub-devices equal + to the number of CSID sub-devices; +- 4 VFE sub-devices - VFE is represented by a number of sub-devices equal to + the number of the input interfaces (3 RDI and 1 PIX). + +The considerations to split the driver in this particular way are as follows: + +- representing CSIPHY and CSID modules by a separate sub-device for each module + allows to model the hardware links between these modules; +- representing VFE by a separate sub-devices for each input interface allows + to use the input interfaces concurently and independently as this is + supported by the hardware; +- representing ISPIF by a number of sub-devices equal to the number of CSID + sub-devices allows to create linear media controller pipelines when using two + cameras simultaneously. This avoids branches in the pipelines which otherwise + will require a) userspace and b) media framework (e.g. power on/off + operations) to make assumptions about the data flow from a sink pad to a + source pad on a single media entity. + +Each VFE sub-device is linked to a separate video device node. + +The media controller pipeline graph is as follows (with connected two OV5645 +camera sensors): + +.. _qcom_camss_graph: + +.. kernel-figure:: qcom_camss_graph.dot + :alt: qcom_camss_graph.dot + :align: center + + Media pipeline graph + + +Implementation +-------------- + +Runtime configuration of the hardware (updating settings while streaming) is +not required to implement the currently supported functionality. The complete +configuration on each hardware module is applied on STREAMON ioctl based on +the current active media links, formats and controls set. + +The output size of the scaler module in the VFE is configured with the actual +compose selection rectangle on the sink pad of the 'msm_vfe0_pix' entity. + +The crop output area of the crop module in the VFE is configured with the actual +crop selection rectangle on the source pad of the 'msm_vfe0_pix' entity. + + +Documentation +------------- + +APQ8016 Specification: +https://developer.qualcomm.com/download/sd410/snapdragon-410-processor-device-specification.pdf +Referenced 2016-11-24. + + +References +---------- + +.. [#f1] https://source.codeaurora.org/quic/la/kernel/msm-3.10/ diff --git a/Documentation/media/v4l-drivers/qcom_camss_graph.dot b/Documentation/media/v4l-drivers/qcom_camss_graph.dot new file mode 100644 index 000000000000..827fc7112c1e --- /dev/null +++ b/Documentation/media/v4l-drivers/qcom_camss_graph.dot @@ -0,0 +1,41 @@ +digraph board { + rankdir=TB + n00000001 [label="{{ 0} | msm_csiphy0\n/dev/v4l-subdev0 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000001:port1 -> n00000007:port0 [style=dashed] + n00000001:port1 -> n0000000a:port0 [style=dashed] + n00000004 [label="{{ 0} | msm_csiphy1\n/dev/v4l-subdev1 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000004:port1 -> n00000007:port0 [style=dashed] + n00000004:port1 -> n0000000a:port0 [style=dashed] + n00000007 [label="{{ 0} | msm_csid0\n/dev/v4l-subdev2 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000007:port1 -> n0000000d:port0 [style=dashed] + n00000007:port1 -> n00000010:port0 [style=dashed] + n0000000a [label="{{ 0} | msm_csid1\n/dev/v4l-subdev3 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000000a:port1 -> n0000000d:port0 [style=dashed] + n0000000a:port1 -> n00000010:port0 [style=dashed] + n0000000d [label="{{ 0} | msm_ispif0\n/dev/v4l-subdev4 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000000d:port1 -> n00000013:port0 [style=dashed] + n0000000d:port1 -> n0000001c:port0 [style=dashed] + n0000000d:port1 -> n00000025:port0 [style=dashed] + n0000000d:port1 -> n0000002e:port0 [style=dashed] + n00000010 [label="{{ 0} | msm_ispif1\n/dev/v4l-subdev5 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000010:port1 -> n00000013:port0 [style=dashed] + n00000010:port1 -> n0000001c:port0 [style=dashed] + n00000010:port1 -> n00000025:port0 [style=dashed] + n00000010:port1 -> n0000002e:port0 [style=dashed] + n00000013 [label="{{ 0} | msm_vfe0_rdi0\n/dev/v4l-subdev6 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000013:port1 -> n00000016 [style=bold] + n00000016 [label="msm_vfe0_video0\n/dev/video0", shape=box, style=filled, fillcolor=yellow] + n0000001c [label="{{ 0} | msm_vfe0_rdi1\n/dev/v4l-subdev7 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000001c:port1 -> n0000001f [style=bold] + n0000001f [label="msm_vfe0_video1\n/dev/video1", shape=box, style=filled, fillcolor=yellow] + n00000025 [label="{{ 0} | msm_vfe0_rdi2\n/dev/v4l-subdev8 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n00000025:port1 -> n00000028 [style=bold] + n00000028 [label="msm_vfe0_video2\n/dev/video2", shape=box, style=filled, fillcolor=yellow] + n0000002e [label="{{ 0} | msm_vfe0_pix\n/dev/v4l-subdev9 | { 1}}", shape=Mrecord, style=filled, fillcolor=green] + n0000002e:port1 -> n00000031 [style=bold] + n00000031 [label="msm_vfe0_video3\n/dev/video3", shape=box, style=filled, fillcolor=yellow] + n00000057 [label="{{} | ov5645 1-0076\n/dev/v4l-subdev10 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] + n00000057:port0 -> n00000001:port0 [style=bold] + n00000059 [label="{{} | ov5645 1-0074\n/dev/v4l-subdev11 | { 0}}", shape=Mrecord, style=filled, fillcolor=green] + n00000059:port0 -> n00000004:port0 [style=bold] +} diff --git a/Documentation/media/v4l-drivers/saa7134-cardlist.rst b/Documentation/media/v4l-drivers/saa7134-cardlist.rst index a5efa8f4b8e4..6e4c35cbaabf 100644 --- a/Documentation/media/v4l-drivers/saa7134-cardlist.rst +++ b/Documentation/media/v4l-drivers/saa7134-cardlist.rst @@ -1,204 +1,801 @@ SAA7134 cards list ================== -=========== ======================================================= ================================================================ -Card number Card name PCI IDs -=========== ======================================================= ================================================================ -0 UNKNOWN/GENERIC -1 Proteus Pro [philips reference design] 1131:2001, 1131:2001 -2 LifeView FlyVIDEO3000 5168:0138, 4e42:0138 -3 LifeView/Typhoon FlyVIDEO2000 5168:0138, 4e42:0138 -4 EMPRESS 1131:6752 -5 SKNet Monster TV 1131:4e85 -6 Tevion MD 9717 -7 KNC One TV-Station RDS / Typhoon TV Tuner RDS 1131:fe01, 1894:fe01 -8 Terratec Cinergy 400 TV 153b:1142 -9 Medion 5044 -10 Kworld/KuroutoShikou SAA7130-TVPCI -11 Terratec Cinergy 600 TV 153b:1143 -12 Medion 7134 16be:0003, 16be:5000 -13 Typhoon TV+Radio 90031 -14 ELSA EX-VISION 300TV 1048:226b -15 ELSA EX-VISION 500TV 1048:226a -16 ASUS TV-FM 7134 1043:4842, 1043:4830, 1043:4840 -17 AOPEN VA1000 POWER 1131:7133 -18 BMK MPEX No Tuner -19 Compro VideoMate TV 185b:c100 -20 Matrox CronosPlus 102B:48d0 -21 10MOONS PCI TV CAPTURE CARD 1131:2001 -22 AverMedia M156 / Medion 2819 1461:a70b -23 BMK MPEX Tuner -24 KNC One TV-Station DVR 1894:a006 -25 ASUS TV-FM 7133 1043:4843 -26 Pinnacle PCTV Stereo (saa7134) 11bd:002b -27 Manli MuchTV M-TV002 -28 Manli MuchTV M-TV001 -29 Nagase Sangyo TransGear 3000TV 1461:050c -30 Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) 1019:4cb4 -31 Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) 1019:4cb5 -32 AVACS SmartTV -33 AVerMedia DVD EZMaker 1461:10ff -34 Noval Prime TV 7133 -35 AverMedia AverTV Studio 305 1461:2115 -36 UPMOST PURPLE TV 12ab:0800 -37 Items MuchTV Plus / IT-005 -38 Terratec Cinergy 200 TV 153b:1152 -39 LifeView FlyTV Platinum Mini 5168:0212, 4e42:0212, 5169:1502 -40 Compro VideoMate TV PVR/FM 185b:c100 -41 Compro VideoMate TV Gold+ 185b:c100 -42 Sabrent SBT-TVFM (saa7130) -43 :Zolid Xpert TV7134 -44 Empire PCI TV-Radio LE -45 Avermedia AVerTV Studio 307 1461:9715 -46 AVerMedia Cardbus TV/Radio (E500) 1461:d6ee -47 Terratec Cinergy 400 mobile 153b:1162 -48 Terratec Cinergy 600 TV MK3 153b:1158 -49 Compro VideoMate Gold+ Pal 185b:c200 -50 Pinnacle PCTV 300i DVB-T + PAL 11bd:002d -51 ProVideo PV952 1540:9524 -52 AverMedia AverTV/305 1461:2108 -53 ASUS TV-FM 7135 1043:4845 -54 LifeView FlyTV Platinum FM / Gold 5168:0214, 5168:5214, 1489:0214, 5168:0304 -55 LifeView FlyDVB-T DUO / MSI TV@nywhere Duo 5168:0306, 4E42:0306 -56 Avermedia AVerTV 307 1461:a70a -57 Avermedia AVerTV GO 007 FM 1461:f31f -58 ADS Tech Instant TV (saa7135) 1421:0350, 1421:0351, 1421:0370, 1421:1370 -59 Kworld/Tevion V-Stream Xpert TV PVR7134 -60 LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus 5168:0502, 4e42:0502, 1489:0502 -61 Philips TOUGH DVB-T reference design 1131:2004 -62 Compro VideoMate TV Gold+II -63 Kworld Xpert TV PVR7134 -64 FlyTV mini Asus Digimatrix 1043:0210 -65 V-Stream Studio TV Terminator -66 Yuan TUN-900 (saa7135) -67 Beholder BeholdTV 409 FM 0000:4091 -68 GoTView 7135 PCI 5456:7135 -69 Philips EUROPA V3 reference design 1131:2004 -70 Compro Videomate DVB-T300 185b:c900 -71 Compro Videomate DVB-T200 185b:c901 -72 RTD Embedded Technologies VFG7350 1435:7350 -73 RTD Embedded Technologies VFG7330 1435:7330 -74 LifeView FlyTV Platinum Mini2 14c0:1212 -75 AVerMedia AVerTVHD MCE A180 1461:1044 -76 SKNet MonsterTV Mobile 1131:4ee9 -77 Pinnacle PCTV 40i/50i/110i (saa7133) 11bd:002e -78 ASUSTeK P7131 Dual 1043:4862 -79 Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) -80 ASUS Digimatrix TV 1043:0210 -81 Philips Tiger reference design 1131:2018 -82 MSI TV@Anywhere plus 1462:6231, 1462:8624 -83 Terratec Cinergy 250 PCI TV 153b:1160 -84 LifeView FlyDVB Trio 5168:0319 -85 AverTV DVB-T 777 1461:2c05, 1461:2c05 -86 LifeView FlyDVB-T / Genius VideoWonder DVB-T 5168:0301, 1489:0301 -87 ADS Instant TV Duo Cardbus PTV331 0331:1421 -88 Tevion/KWorld DVB-T 220RF 17de:7201 -89 ELSA EX-VISION 700TV 1048:226c -90 Kworld ATSC110/115 17de:7350, 17de:7352 -91 AVerMedia A169 B 1461:7360 -92 AVerMedia A169 B1 1461:6360 -93 Medion 7134 Bridge #2 16be:0005 -94 LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB 5168:3306, 5168:3502, 5168:3307, 4e42:3502 -95 LifeView FlyVIDEO3000 (NTSC) 5169:0138 -96 Medion Md8800 Quadro 16be:0007, 16be:0008, 16be:000d -97 LifeView FlyDVB-S /Acorp TV134DS 5168:0300, 4e42:0300 -98 Proteus Pro 2309 0919:2003 -99 AVerMedia TV Hybrid A16AR 1461:2c00 -100 Asus Europa2 OEM 1043:4860 -101 Pinnacle PCTV 310i 11bd:002f -102 Avermedia AVerTV Studio 507 1461:9715 -103 Compro Videomate DVB-T200A -104 Hauppauge WinTV-HVR1110 DVB-T/Hybrid 0070:6700, 0070:6701, 0070:6702, 0070:6703, 0070:6704, 0070:6705 -105 Terratec Cinergy HT PCMCIA 153b:1172 -106 Encore ENLTV 1131:2342, 1131:2341, 3016:2344 -107 Encore ENLTV-FM 1131:230f -108 Terratec Cinergy HT PCI 153b:1175 -109 Philips Tiger - S Reference design -110 Avermedia M102 1461:f31e -111 ASUS P7131 4871 1043:4871 -112 ASUSTeK P7131 Hybrid 1043:4876 -113 Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) 1019:4cb6 -114 KWorld DVB-T 210 17de:7250 -115 Sabrent PCMCIA TV-PCB05 0919:2003 -116 10MOONS TM300 TV Card 1131:2304 -117 Avermedia Super 007 1461:f01d -118 Beholder BeholdTV 401 0000:4016 -119 Beholder BeholdTV 403 0000:4036 -120 Beholder BeholdTV 403 FM 0000:4037 -121 Beholder BeholdTV 405 0000:4050 -122 Beholder BeholdTV 405 FM 0000:4051 -123 Beholder BeholdTV 407 0000:4070 -124 Beholder BeholdTV 407 FM 0000:4071 -125 Beholder BeholdTV 409 0000:4090 -126 Beholder BeholdTV 505 FM 5ace:5050 -127 Beholder BeholdTV 507 FM / BeholdTV 509 FM 5ace:5070, 5ace:5090 -128 Beholder BeholdTV Columbus TV/FM 0000:5201 -129 Beholder BeholdTV 607 FM 5ace:6070 -130 Beholder BeholdTV M6 5ace:6190 -131 Twinhan Hybrid DTV-DVB 3056 PCI 1822:0022 -132 Genius TVGO AM11MCE -133 NXP Snake DVB-S reference design -134 Medion/Creatix CTX953 Hybrid 16be:0010 -135 MSI TV@nywhere A/D v1.1 1462:8625 -136 AVerMedia Cardbus TV/Radio (E506R) 1461:f436 -137 AVerMedia Hybrid TV/Radio (A16D) 1461:f936 -138 Avermedia M115 1461:a836 -139 Compro VideoMate T750 185b:c900 -140 Avermedia DVB-S Pro A700 1461:a7a1 -141 Avermedia DVB-S Hybrid+FM A700 1461:a7a2 -142 Beholder BeholdTV H6 5ace:6290 -143 Beholder BeholdTV M63 5ace:6191 -144 Beholder BeholdTV M6 Extra 5ace:6193 -145 AVerMedia MiniPCI DVB-T Hybrid M103 1461:f636, 1461:f736 -146 ASUSTeK P7131 Analog -147 Asus Tiger 3in1 1043:4878 -148 Encore ENLTV-FM v5.3 1a7f:2008 -149 Avermedia PCI pure analog (M135A) 1461:f11d -150 Zogis Real Angel 220 -151 ADS Tech Instant HDTV 1421:0380 -152 Asus Tiger Rev:1.00 1043:4857 -153 Kworld Plus TV Analog Lite PCI 17de:7128 -154 Avermedia AVerTV GO 007 FM Plus 1461:f31d -155 Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid 0070:6706, 0070:6708 -156 Hauppauge WinTV-HVR1120 DVB-T/Hybrid 0070:6707, 0070:6709, 0070:670a -157 Avermedia AVerTV Studio 507UA 1461:a11b -158 AVerMedia Cardbus TV/Radio (E501R) 1461:b7e9 -159 Beholder BeholdTV 505 RDS 0000:505B -160 Beholder BeholdTV 507 RDS 0000:5071 -161 Beholder BeholdTV 507 RDS 0000:507B -162 Beholder BeholdTV 607 FM 5ace:6071 -163 Beholder BeholdTV 609 FM 5ace:6090 -164 Beholder BeholdTV 609 FM 5ace:6091 -165 Beholder BeholdTV 607 RDS 5ace:6072 -166 Beholder BeholdTV 607 RDS 5ace:6073 -167 Beholder BeholdTV 609 RDS 5ace:6092 -168 Beholder BeholdTV 609 RDS 5ace:6093 -169 Compro VideoMate S350/S300 185b:c900 -170 AverMedia AverTV Studio 505 1461:a115 -171 Beholder BeholdTV X7 5ace:7595 -172 RoverMedia TV Link Pro FM 19d1:0138 -173 Zolid Hybrid TV Tuner PCI 1131:2004 -174 Asus Europa Hybrid OEM 1043:4847 -175 Leadtek Winfast DTV1000S 107d:6655 -176 Beholder BeholdTV 505 RDS 0000:5051 -177 Hawell HW-404M7 -178 Beholder BeholdTV H7 5ace:7190 -179 Beholder BeholdTV A7 5ace:7090 -180 Avermedia PCI M733A 1461:4155, 1461:4255 -181 TechoTrend TT-budget T-3000 13c2:2804 -182 Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid 17de:b136 -183 Compro VideoMate Vista M1F 185b:c900 -184 Encore ENLTV-FM 3 1a7f:2108 -185 MagicPro ProHDTV Pro2 DMB-TH/Hybrid 17de:d136 -186 Beholder BeholdTV 501 5ace:5010 -187 Beholder BeholdTV 503 FM 5ace:5030 -188 Sensoray 811/911 6000:0811, 6000:0911 -189 Kworld PC150-U 17de:a134 -190 Asus My Cinema PS3-100 1043:48cd -191 Hawell HW-9004V1 -192 AverMedia AverTV Satellite Hybrid+FM A706 1461:2055 -193 WIS Voyager or compatible 1905:7007 -194 AverMedia AverTV/505 1461:a10a -195 Leadtek Winfast TV2100 FM 107d:6f3a -196 SnaZio* TVPVR PRO 1779:13cf -=========== ======================================================= ================================================================ +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - UNKNOWN/GENERIC + - + + * - 1 + - Proteus Pro [philips reference design] + - 1131:2001, 1131:2001 + + * - 2 + - LifeView FlyVIDEO3000 + - 5168:0138, 4e42:0138 + + * - 3 + - LifeView/Typhoon FlyVIDEO2000 + - 5168:0138, 4e42:0138 + + * - 4 + - EMPRESS + - 1131:6752 + + * - 5 + - SKNet Monster TV + - 1131:4e85 + + * - 6 + - Tevion MD 9717 + - + + * - 7 + - KNC One TV-Station RDS / Typhoon TV Tuner RDS + - 1131:fe01, 1894:fe01 + + * - 8 + - Terratec Cinergy 400 TV + - 153b:1142 + + * - 9 + - Medion 5044 + - + + * - 10 + - Kworld/KuroutoShikou SAA7130-TVPCI + - + + * - 11 + - Terratec Cinergy 600 TV + - 153b:1143 + + * - 12 + - Medion 7134 + - 16be:0003, 16be:5000 + + * - 13 + - Typhoon TV+Radio 90031 + - + + * - 14 + - ELSA EX-VISION 300TV + - 1048:226b + + * - 15 + - ELSA EX-VISION 500TV + - 1048:226a + + * - 16 + - ASUS TV-FM 7134 + - 1043:4842, 1043:4830, 1043:4840 + + * - 17 + - AOPEN VA1000 POWER + - 1131:7133 + + * - 18 + - BMK MPEX No Tuner + - + + * - 19 + - Compro VideoMate TV + - 185b:c100 + + * - 20 + - Matrox CronosPlus + - 102B:48d0 + + * - 21 + - 10MOONS PCI TV CAPTURE CARD + - 1131:2001 + + * - 22 + - AverMedia M156 / Medion 2819 + - 1461:a70b + + * - 23 + - BMK MPEX Tuner + - + + * - 24 + - KNC One TV-Station DVR + - 1894:a006 + + * - 25 + - ASUS TV-FM 7133 + - 1043:4843 + + * - 26 + - Pinnacle PCTV Stereo (saa7134) + - 11bd:002b + + * - 27 + - Manli MuchTV M-TV002 + - + + * - 28 + - Manli MuchTV M-TV001 + - + + * - 29 + - Nagase Sangyo TransGear 3000TV + - 1461:050c + + * - 30 + - Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) + - 1019:4cb4 + + * - 31 + - Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) + - 1019:4cb5 + + * - 32 + - AVACS SmartTV + - + + * - 33 + - AVerMedia DVD EZMaker + - 1461:10ff + + * - 34 + - Noval Prime TV 7133 + - + + * - 35 + - AverMedia AverTV Studio 305 + - 1461:2115 + + * - 36 + - UPMOST PURPLE TV + - 12ab:0800 + + * - 37 + - Items MuchTV Plus / IT-005 + - + + * - 38 + - Terratec Cinergy 200 TV + - 153b:1152 + + * - 39 + - LifeView FlyTV Platinum Mini + - 5168:0212, 4e42:0212, 5169:1502 + + * - 40 + - Compro VideoMate TV PVR/FM + - 185b:c100 + + * - 41 + - Compro VideoMate TV Gold+ + - 185b:c100 + + * - 42 + - Sabrent SBT-TVFM (saa7130) + - + + * - 43 + - :Zolid Xpert TV7134 + - + + * - 44 + - Empire PCI TV-Radio LE + - + + * - 45 + - Avermedia AVerTV Studio 307 + - 1461:9715 + + * - 46 + - AVerMedia Cardbus TV/Radio (E500) + - 1461:d6ee + + * - 47 + - Terratec Cinergy 400 mobile + - 153b:1162 + + * - 48 + - Terratec Cinergy 600 TV MK3 + - 153b:1158 + + * - 49 + - Compro VideoMate Gold+ Pal + - 185b:c200 + + * - 50 + - Pinnacle PCTV 300i DVB-T + PAL + - 11bd:002d + + * - 51 + - ProVideo PV952 + - 1540:9524 + + * - 52 + - AverMedia AverTV/305 + - 1461:2108 + + * - 53 + - ASUS TV-FM 7135 + - 1043:4845 + + * - 54 + - LifeView FlyTV Platinum FM / Gold + - 5168:0214, 5168:5214, 1489:0214, 5168:0304 + + * - 55 + - LifeView FlyDVB-T DUO / MSI TV@nywhere Duo + - 5168:0306, 4E42:0306 + + * - 56 + - Avermedia AVerTV 307 + - 1461:a70a + + * - 57 + - Avermedia AVerTV GO 007 FM + - 1461:f31f + + * - 58 + - ADS Tech Instant TV (saa7135) + - 1421:0350, 1421:0351, 1421:0370, 1421:1370 + + * - 59 + - Kworld/Tevion V-Stream Xpert TV PVR7134 + - + + * - 60 + - LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus + - 5168:0502, 4e42:0502, 1489:0502 + + * - 61 + - Philips TOUGH DVB-T reference design + - 1131:2004 + + * - 62 + - Compro VideoMate TV Gold+II + - + + * - 63 + - Kworld Xpert TV PVR7134 + - + + * - 64 + - FlyTV mini Asus Digimatrix + - 1043:0210 + + * - 65 + - V-Stream Studio TV Terminator + - + + * - 66 + - Yuan TUN-900 (saa7135) + - + + * - 67 + - Beholder BeholdTV 409 FM + - 0000:4091 + + * - 68 + - GoTView 7135 PCI + - 5456:7135 + + * - 69 + - Philips EUROPA V3 reference design + - 1131:2004 + + * - 70 + - Compro Videomate DVB-T300 + - 185b:c900 + + * - 71 + - Compro Videomate DVB-T200 + - 185b:c901 + + * - 72 + - RTD Embedded Technologies VFG7350 + - 1435:7350 + + * - 73 + - RTD Embedded Technologies VFG7330 + - 1435:7330 + + * - 74 + - LifeView FlyTV Platinum Mini2 + - 14c0:1212 + + * - 75 + - AVerMedia AVerTVHD MCE A180 + - 1461:1044 + + * - 76 + - SKNet MonsterTV Mobile + - 1131:4ee9 + + * - 77 + - Pinnacle PCTV 40i/50i/110i (saa7133) + - 11bd:002e + + * - 78 + - ASUSTeK P7131 Dual + - 1043:4862 + + * - 79 + - Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B) + - + + * - 80 + - ASUS Digimatrix TV + - 1043:0210 + + * - 81 + - Philips Tiger reference design + - 1131:2018 + + * - 82 + - MSI TV@Anywhere plus + - 1462:6231, 1462:8624 + + * - 83 + - Terratec Cinergy 250 PCI TV + - 153b:1160 + + * - 84 + - LifeView FlyDVB Trio + - 5168:0319 + + * - 85 + - AverTV DVB-T 777 + - 1461:2c05, 1461:2c05 + + * - 86 + - LifeView FlyDVB-T / Genius VideoWonder DVB-T + - 5168:0301, 1489:0301 + + * - 87 + - ADS Instant TV Duo Cardbus PTV331 + - 0331:1421 + + * - 88 + - Tevion/KWorld DVB-T 220RF + - 17de:7201 + + * - 89 + - ELSA EX-VISION 700TV + - 1048:226c + + * - 90 + - Kworld ATSC110/115 + - 17de:7350, 17de:7352 + + * - 91 + - AVerMedia A169 B + - 1461:7360 + + * - 92 + - AVerMedia A169 B1 + - 1461:6360 + + * - 93 + - Medion 7134 Bridge #2 + - 16be:0005 + + * - 94 + - LifeView FlyDVB-T Hybrid Cardbus/MSI TV @nywhere A/D NB + - 5168:3306, 5168:3502, 5168:3307, 4e42:3502 + + * - 95 + - LifeView FlyVIDEO3000 (NTSC) + - 5169:0138 + + * - 96 + - Medion Md8800 Quadro + - 16be:0007, 16be:0008, 16be:000d + + * - 97 + - LifeView FlyDVB-S /Acorp TV134DS + - 5168:0300, 4e42:0300 + + * - 98 + - Proteus Pro 2309 + - 0919:2003 + + * - 99 + - AVerMedia TV Hybrid A16AR + - 1461:2c00 + + * - 100 + - Asus Europa2 OEM + - 1043:4860 + + * - 101 + - Pinnacle PCTV 310i + - 11bd:002f + + * - 102 + - Avermedia AVerTV Studio 507 + - 1461:9715 + + * - 103 + - Compro Videomate DVB-T200A + - + + * - 104 + - Hauppauge WinTV-HVR1110 DVB-T/Hybrid + - 0070:6700, 0070:6701, 0070:6702, 0070:6703, 0070:6704, 0070:6705 + + * - 105 + - Terratec Cinergy HT PCMCIA + - 153b:1172 + + * - 106 + - Encore ENLTV + - 1131:2342, 1131:2341, 3016:2344 + + * - 107 + - Encore ENLTV-FM + - 1131:230f + + * - 108 + - Terratec Cinergy HT PCI + - 153b:1175 + + * - 109 + - Philips Tiger - S Reference design + - + + * - 110 + - Avermedia M102 + - 1461:f31e + + * - 111 + - ASUS P7131 4871 + - 1043:4871 + + * - 112 + - ASUSTeK P7131 Hybrid + - 1043:4876 + + * - 113 + - Elitegroup ECS TVP3XP FM1246 Tuner Card (PAL,FM) + - 1019:4cb6 + + * - 114 + - KWorld DVB-T 210 + - 17de:7250 + + * - 115 + - Sabrent PCMCIA TV-PCB05 + - 0919:2003 + + * - 116 + - 10MOONS TM300 TV Card + - 1131:2304 + + * - 117 + - Avermedia Super 007 + - 1461:f01d + + * - 118 + - Beholder BeholdTV 401 + - 0000:4016 + + * - 119 + - Beholder BeholdTV 403 + - 0000:4036 + + * - 120 + - Beholder BeholdTV 403 FM + - 0000:4037 + + * - 121 + - Beholder BeholdTV 405 + - 0000:4050 + + * - 122 + - Beholder BeholdTV 405 FM + - 0000:4051 + + * - 123 + - Beholder BeholdTV 407 + - 0000:4070 + + * - 124 + - Beholder BeholdTV 407 FM + - 0000:4071 + + * - 125 + - Beholder BeholdTV 409 + - 0000:4090 + + * - 126 + - Beholder BeholdTV 505 FM + - 5ace:5050 + + * - 127 + - Beholder BeholdTV 507 FM / BeholdTV 509 FM + - 5ace:5070, 5ace:5090 + + * - 128 + - Beholder BeholdTV Columbus TV/FM + - 0000:5201 + + * - 129 + - Beholder BeholdTV 607 FM + - 5ace:6070 + + * - 130 + - Beholder BeholdTV M6 + - 5ace:6190 + + * - 131 + - Twinhan Hybrid DTV-DVB 3056 PCI + - 1822:0022 + + * - 132 + - Genius TVGO AM11MCE + - + + * - 133 + - NXP Snake DVB-S reference design + - + + * - 134 + - Medion/Creatix CTX953 Hybrid + - 16be:0010 + + * - 135 + - MSI TV@nywhere A/D v1.1 + - 1462:8625 + + * - 136 + - AVerMedia Cardbus TV/Radio (E506R) + - 1461:f436 + + * - 137 + - AVerMedia Hybrid TV/Radio (A16D) + - 1461:f936 + + * - 138 + - Avermedia M115 + - 1461:a836 + + * - 139 + - Compro VideoMate T750 + - 185b:c900 + + * - 140 + - Avermedia DVB-S Pro A700 + - 1461:a7a1 + + * - 141 + - Avermedia DVB-S Hybrid+FM A700 + - 1461:a7a2 + + * - 142 + - Beholder BeholdTV H6 + - 5ace:6290 + + * - 143 + - Beholder BeholdTV M63 + - 5ace:6191 + + * - 144 + - Beholder BeholdTV M6 Extra + - 5ace:6193 + + * - 145 + - AVerMedia MiniPCI DVB-T Hybrid M103 + - 1461:f636, 1461:f736 + + * - 146 + - ASUSTeK P7131 Analog + - + + * - 147 + - Asus Tiger 3in1 + - 1043:4878 + + * - 148 + - Encore ENLTV-FM v5.3 + - 1a7f:2008 + + * - 149 + - Avermedia PCI pure analog (M135A) + - 1461:f11d + + * - 150 + - Zogis Real Angel 220 + - + + * - 151 + - ADS Tech Instant HDTV + - 1421:0380 + + * - 152 + - Asus Tiger Rev:1.00 + - 1043:4857 + + * - 153 + - Kworld Plus TV Analog Lite PCI + - 17de:7128 + + * - 154 + - Avermedia AVerTV GO 007 FM Plus + - 1461:f31d + + * - 155 + - Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid + - 0070:6706, 0070:6708 + + * - 156 + - Hauppauge WinTV-HVR1120 DVB-T/Hybrid + - 0070:6707, 0070:6709, 0070:670a + + * - 157 + - Avermedia AVerTV Studio 507UA + - 1461:a11b + + * - 158 + - AVerMedia Cardbus TV/Radio (E501R) + - 1461:b7e9 + + * - 159 + - Beholder BeholdTV 505 RDS + - 0000:505B + + * - 160 + - Beholder BeholdTV 507 RDS + - 0000:5071 + + * - 161 + - Beholder BeholdTV 507 RDS + - 0000:507B + + * - 162 + - Beholder BeholdTV 607 FM + - 5ace:6071 + + * - 163 + - Beholder BeholdTV 609 FM + - 5ace:6090 + + * - 164 + - Beholder BeholdTV 609 FM + - 5ace:6091 + + * - 165 + - Beholder BeholdTV 607 RDS + - 5ace:6072 + + * - 166 + - Beholder BeholdTV 607 RDS + - 5ace:6073 + + * - 167 + - Beholder BeholdTV 609 RDS + - 5ace:6092 + + * - 168 + - Beholder BeholdTV 609 RDS + - 5ace:6093 + + * - 169 + - Compro VideoMate S350/S300 + - 185b:c900 + + * - 170 + - AverMedia AverTV Studio 505 + - 1461:a115 + + * - 171 + - Beholder BeholdTV X7 + - 5ace:7595 + + * - 172 + - RoverMedia TV Link Pro FM + - 19d1:0138 + + * - 173 + - Zolid Hybrid TV Tuner PCI + - 1131:2004 + + * - 174 + - Asus Europa Hybrid OEM + - 1043:4847 + + * - 175 + - Leadtek Winfast DTV1000S + - 107d:6655 + + * - 176 + - Beholder BeholdTV 505 RDS + - 0000:5051 + + * - 177 + - Hawell HW-404M7 + - + + * - 178 + - Beholder BeholdTV H7 + - 5ace:7190 + + * - 179 + - Beholder BeholdTV A7 + - 5ace:7090 + + * - 180 + - Avermedia PCI M733A + - 1461:4155, 1461:4255 + + * - 181 + - TechoTrend TT-budget T-3000 + - 13c2:2804 + + * - 182 + - Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid + - 17de:b136 + + * - 183 + - Compro VideoMate Vista M1F + - 185b:c900 + + * - 184 + - Encore ENLTV-FM 3 + - 1a7f:2108 + + * - 185 + - MagicPro ProHDTV Pro2 DMB-TH/Hybrid + - 17de:d136 + + * - 186 + - Beholder BeholdTV 501 + - 5ace:5010 + + * - 187 + - Beholder BeholdTV 503 FM + - 5ace:5030 + + * - 188 + - Sensoray 811/911 + - 6000:0811, 6000:0911 + + * - 189 + - Kworld PC150-U + - 17de:a134 + + * - 190 + - Asus My Cinema PS3-100 + - 1043:48cd + + * - 191 + - Hawell HW-9004V1 + - + + * - 192 + - AverMedia AverTV Satellite Hybrid+FM A706 + - 1461:2055 + + * - 193 + - WIS Voyager or compatible + - 1905:7007 + + * - 194 + - AverMedia AverTV/505 + - 1461:a10a + + * - 195 + - Leadtek Winfast TV2100 FM + - 107d:6f3a + + * - 196 + - SnaZio* TVPVR PRO + - 1779:13cf diff --git a/Documentation/media/v4l-drivers/saa7164-cardlist.rst b/Documentation/media/v4l-drivers/saa7164-cardlist.rst index 7d17d38df3bc..e28382ba82e6 100644 --- a/Documentation/media/v4l-drivers/saa7164-cardlist.rst +++ b/Documentation/media/v4l-drivers/saa7164-cardlist.rst @@ -1,21 +1,69 @@ SAA7164 cards list ================== -=========== ==================================== ==================== -Card number Card name PCI IDs -=========== ==================================== ==================== -0 Unknown -1 Generic Rev2 -2 Generic Rev3 -3 Hauppauge WinTV-HVR2250 0070:8880, 0070:8810 -4 Hauppauge WinTV-HVR2200 0070:8980 -5 Hauppauge WinTV-HVR2200 0070:8900 -6 Hauppauge WinTV-HVR2200 0070:8901 -7 Hauppauge WinTV-HVR2250 0070:8891, 0070:8851 -8 Hauppauge WinTV-HVR2250 0070:88A1 -9 Hauppauge WinTV-HVR2200 0070:8940 -10 Hauppauge WinTV-HVR2200 0070:8953 -11 Hauppauge WinTV-HVR2255(proto) 0070:f111 -12 Hauppauge WinTV-HVR2255 0070:f111 -13 Hauppauge WinTV-HVR2205 0070:f123, 0070:f120 -=========== ==================================== ==================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - PCI IDs + + * - 0 + - Unknown + - + + * - 1 + - Generic Rev2 + - + + * - 2 + - Generic Rev3 + - + + * - 3 + - Hauppauge WinTV-HVR2250 + - 0070:8880, 0070:8810 + + * - 4 + - Hauppauge WinTV-HVR2200 + - 0070:8980 + + * - 5 + - Hauppauge WinTV-HVR2200 + - 0070:8900 + + * - 6 + - Hauppauge WinTV-HVR2200 + - 0070:8901 + + * - 7 + - Hauppauge WinTV-HVR2250 + - 0070:8891, 0070:8851 + + * - 8 + - Hauppauge WinTV-HVR2250 + - 0070:88A1 + + * - 9 + - Hauppauge WinTV-HVR2200 + - 0070:8940 + + * - 10 + - Hauppauge WinTV-HVR2200 + - 0070:8953 + + * - 11 + - Hauppauge WinTV-HVR2255(proto) + - 0070:f111 + + * - 12 + - Hauppauge WinTV-HVR2255 + - 0070:f111 + + * - 13 + - Hauppauge WinTV-HVR2205 + - 0070:f123, 0070:f120 diff --git a/Documentation/media/v4l-drivers/tm6000-cardlist.rst b/Documentation/media/v4l-drivers/tm6000-cardlist.rst index ae2952683ccf..6bd083544457 100644 --- a/Documentation/media/v4l-drivers/tm6000-cardlist.rst +++ b/Documentation/media/v4l-drivers/tm6000-cardlist.rst @@ -1,24 +1,81 @@ TM6000 cards list ================= -=========== ================================================= ========================================== -Card number Card name USB IDs -=========== ================================================= ========================================== -0 Unknown tm6000 video grabber -1 Generic tm5600 board 6000:0001 -2 Generic tm6000 board -3 Generic tm6010 board 6000:0002 -4 10Moons UT 821 -5 10Moons UT 330 -6 ADSTECH Dual TV USB 06e1:f332 -7 Freecom Hybrid Stick / Moka DVB-T Receiver Dual 14aa:0620 -8 ADSTECH Mini Dual TV USB 06e1:b339 -9 Hauppauge WinTV HVR-900H / WinTV USB2-Stick 2040:6600, 2040:6601, 2040:6610, 2040:6611 -10 Beholder Wander DVB-T/TV/FM USB2.0 6000:dec0 -11 Beholder Voyager TV/FM USB2.0 6000:dec1 -12 Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick 0ccd:0086, 0ccd:00A5 -13 Twinhan TU501(704D1) 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264 -14 Beholder Wander Lite DVB-T/TV/FM USB2.0 6000:dec2 -15 Beholder Voyager Lite TV/FM USB2.0 6000:dec3 -16 Terratec Grabster AV 150/250 MX 0ccd:0079 -=========== ================================================= ========================================== +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - USB IDs + + * - 0 + - Unknown tm6000 video grabber + - + + * - 1 + - Generic tm5600 board + - 6000:0001 + + * - 2 + - Generic tm6000 board + - + + * - 3 + - Generic tm6010 board + - 6000:0002 + + * - 4 + - 10Moons UT 821 + - + + * - 5 + - 10Moons UT 330 + - + + * - 6 + - ADSTECH Dual TV USB + - 06e1:f332 + + * - 7 + - Freecom Hybrid Stick / Moka DVB-T Receiver Dual + - 14aa:0620 + + * - 8 + - ADSTECH Mini Dual TV USB + - 06e1:b339 + + * - 9 + - Hauppauge WinTV HVR-900H / WinTV USB2-Stick + - 2040:6600, 2040:6601, 2040:6610, 2040:6611 + + * - 10 + - Beholder Wander DVB-T/TV/FM USB2.0 + - 6000:dec0 + + * - 11 + - Beholder Voyager TV/FM USB2.0 + - 6000:dec1 + + * - 12 + - Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick + - 0ccd:0086, 0ccd:00A5 + + * - 13 + - Twinhan TU501(704D1) + - 13d3:3240, 13d3:3241, 13d3:3243, 13d3:3264 + + * - 14 + - Beholder Wander Lite DVB-T/TV/FM USB2.0 + - 6000:dec2 + + * - 15 + - Beholder Voyager Lite TV/FM USB2.0 + - 6000:dec3 + + * - 16 + - Terratec Grabster AV 150/250 MX + - 0ccd:0079 diff --git a/Documentation/media/v4l-drivers/usbvision-cardlist.rst b/Documentation/media/v4l-drivers/usbvision-cardlist.rst index 44d53dff0984..5a8ffbfc204e 100644 --- a/Documentation/media/v4l-drivers/usbvision-cardlist.rst +++ b/Documentation/media/v4l-drivers/usbvision-cardlist.rst @@ -1,74 +1,281 @@ USBvision cards list ==================== -=========== ======================================================== ========= -Card number Card name USB IDs -=========== ======================================================== ========= -0 Xanboo 0a6f:0400 -1 Belkin USB VideoBus II Adapter 050d:0106 -2 Belkin Components USB VideoBus 050d:0207 -3 Belkin USB VideoBus II 050d:0208 -4 echoFX InterView Lite 0571:0002 -5 USBGear USBG-V1 resp. HAMA USB 0573:0003 -6 D-Link V100 0573:0400 -7 X10 USB Camera 0573:2000 -8 Hauppauge WinTV USB Live (PAL B/G) 0573:2d00 -9 Hauppauge WinTV USB Live Pro (NTSC M/N) 0573:2d01 -10 Zoran Co. PMD (Nogatech) AV-grabber Manhattan 0573:2101 -11 Nogatech USB-TV (NTSC) FM 0573:4100 -12 PNY USB-TV (NTSC) FM 0573:4110 -13 PixelView PlayTv-USB PRO (PAL) FM 0573:4450 -14 ZTV ZT-721 2.4GHz USB A/V Receiver 0573:4550 -15 Hauppauge WinTV USB (NTSC M/N) 0573:4d00 -16 Hauppauge WinTV USB (PAL B/G) 0573:4d01 -17 Hauppauge WinTV USB (PAL I) 0573:4d02 -18 Hauppauge WinTV USB (PAL/SECAM L) 0573:4d03 -19 Hauppauge WinTV USB (PAL D/K) 0573:4d04 -20 Hauppauge WinTV USB (NTSC FM) 0573:4d10 -21 Hauppauge WinTV USB (PAL B/G FM) 0573:4d11 -22 Hauppauge WinTV USB (PAL I FM) 0573:4d12 -23 Hauppauge WinTV USB (PAL D/K FM) 0573:4d14 -24 Hauppauge WinTV USB Pro (NTSC M/N) 0573:4d2a -25 Hauppauge WinTV USB Pro (NTSC M/N) V2 0573:4d2b -26 Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) 0573:4d2c -27 Hauppauge WinTV USB Pro (NTSC M/N) V3 0573:4d20 -28 Hauppauge WinTV USB Pro (PAL B/G) 0573:4d21 -29 Hauppauge WinTV USB Pro (PAL I) 0573:4d22 -30 Hauppauge WinTV USB Pro (PAL/SECAM L) 0573:4d23 -31 Hauppauge WinTV USB Pro (PAL D/K) 0573:4d24 -32 Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) 0573:4d25 -33 Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 0573:4d26 -34 Hauppauge WinTV USB Pro (PAL B/G) V2 0573:4d27 -35 Hauppauge WinTV USB Pro (PAL B/G,D/K) 0573:4d28 -36 Hauppauge WinTV USB Pro (PAL I,D/K) 0573:4d29 -37 Hauppauge WinTV USB Pro (NTSC M/N FM) 0573:4d30 -38 Hauppauge WinTV USB Pro (PAL B/G FM) 0573:4d31 -39 Hauppauge WinTV USB Pro (PAL I FM) 0573:4d32 -40 Hauppauge WinTV USB Pro (PAL D/K FM) 0573:4d34 -41 Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) 0573:4d35 -42 Hauppauge WinTV USB Pro (Temic PAL B/G FM) 0573:4d36 -43 Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) 0573:4d37 -44 Hauppauge WinTV USB Pro (NTSC M/N FM) V2 0573:4d38 -45 Camtel Technology USB TV Genie Pro FM Model TVB330 0768:0006 -46 Digital Video Creator I 07d0:0001 -47 Global Village GV-007 (NTSC) 07d0:0002 -48 Dazzle Fusion Model DVC-50 Rev 1 (NTSC) 07d0:0003 -49 Dazzle Fusion Model DVC-80 Rev 1 (PAL) 07d0:0004 -50 Dazzle Fusion Model DVC-90 Rev 1 (SECAM) 07d0:0005 -51 Eskape Labs MyTV2Go 07f8:9104 -52 Pinnacle Studio PCTV USB (PAL) 2304:010d -53 Pinnacle Studio PCTV USB (SECAM) 2304:0109 -54 Pinnacle Studio PCTV USB (PAL) FM 2304:0110 -55 Miro PCTV USB 2304:0111 -56 Pinnacle Studio PCTV USB (NTSC) FM 2304:0112 -57 Pinnacle Studio PCTV USB (PAL) FM V2 2304:0210 -58 Pinnacle Studio PCTV USB (NTSC) FM V2 2304:0212 -59 Pinnacle Studio PCTV USB (PAL) FM V3 2304:0214 -60 Pinnacle Studio Linx Video input cable (NTSC) 2304:0300 -61 Pinnacle Studio Linx Video input cable (PAL) 2304:0301 -62 Pinnacle PCTV Bungee USB (PAL) FM 2304:0419 -63 Hauppauge WinTv-USB 2400:4200 -64 Pinnacle Studio PCTV USB (NTSC) FM V3 2304:0113 -65 Nogatech USB MicroCam NTSC (NV3000N) 0573:3000 -66 Nogatech USB MicroCam PAL (NV3001P) 0573:3001 -=========== ======================================================== ========= +.. tabularcolumns:: |p{1.4cm}|p{11.1cm}|p{4.2cm}| + +.. flat-table:: + :header-rows: 1 + :widths: 2 19 18 + :stub-columns: 0 + + * - Card number + - Card name + - USB IDs + + * - 0 + - Xanboo + - 0a6f:0400 + + * - 1 + - Belkin USB VideoBus II Adapter + - 050d:0106 + + * - 2 + - Belkin Components USB VideoBus + - 050d:0207 + + * - 3 + - Belkin USB VideoBus II + - 050d:0208 + + * - 4 + - echoFX InterView Lite + - 0571:0002 + + * - 5 + - USBGear USBG-V1 resp. HAMA USB + - 0573:0003 + + * - 6 + - D-Link V100 + - 0573:0400 + + * - 7 + - X10 USB Camera + - 0573:2000 + + * - 8 + - Hauppauge WinTV USB Live (PAL B/G) + - 0573:2d00 + + * - 9 + - Hauppauge WinTV USB Live Pro (NTSC M/N) + - 0573:2d01 + + * - 10 + - Zoran Co. PMD (Nogatech) AV-grabber Manhattan + - 0573:2101 + + * - 11 + - Nogatech USB-TV (NTSC) FM + - 0573:4100 + + * - 12 + - PNY USB-TV (NTSC) FM + - 0573:4110 + + * - 13 + - PixelView PlayTv-USB PRO (PAL) FM + - 0573:4450 + + * - 14 + - ZTV ZT-721 2.4GHz USB A/V Receiver + - 0573:4550 + + * - 15 + - Hauppauge WinTV USB (NTSC M/N) + - 0573:4d00 + + * - 16 + - Hauppauge WinTV USB (PAL B/G) + - 0573:4d01 + + * - 17 + - Hauppauge WinTV USB (PAL I) + - 0573:4d02 + + * - 18 + - Hauppauge WinTV USB (PAL/SECAM L) + - 0573:4d03 + + * - 19 + - Hauppauge WinTV USB (PAL D/K) + - 0573:4d04 + + * - 20 + - Hauppauge WinTV USB (NTSC FM) + - 0573:4d10 + + * - 21 + - Hauppauge WinTV USB (PAL B/G FM) + - 0573:4d11 + + * - 22 + - Hauppauge WinTV USB (PAL I FM) + - 0573:4d12 + + * - 23 + - Hauppauge WinTV USB (PAL D/K FM) + - 0573:4d14 + + * - 24 + - Hauppauge WinTV USB Pro (NTSC M/N) + - 0573:4d2a + + * - 25 + - Hauppauge WinTV USB Pro (NTSC M/N) V2 + - 0573:4d2b + + * - 26 + - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L) + - 0573:4d2c + + * - 27 + - Hauppauge WinTV USB Pro (NTSC M/N) V3 + - 0573:4d20 + + * - 28 + - Hauppauge WinTV USB Pro (PAL B/G) + - 0573:4d21 + + * - 29 + - Hauppauge WinTV USB Pro (PAL I) + - 0573:4d22 + + * - 30 + - Hauppauge WinTV USB Pro (PAL/SECAM L) + - 0573:4d23 + + * - 31 + - Hauppauge WinTV USB Pro (PAL D/K) + - 0573:4d24 + + * - 32 + - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) + - 0573:4d25 + + * - 33 + - Hauppauge WinTV USB Pro (PAL/SECAM BGDK/I/L) V2 + - 0573:4d26 + + * - 34 + - Hauppauge WinTV USB Pro (PAL B/G) V2 + - 0573:4d27 + + * - 35 + - Hauppauge WinTV USB Pro (PAL B/G,D/K) + - 0573:4d28 + + * - 36 + - Hauppauge WinTV USB Pro (PAL I,D/K) + - 0573:4d29 + + * - 37 + - Hauppauge WinTV USB Pro (NTSC M/N FM) + - 0573:4d30 + + * - 38 + - Hauppauge WinTV USB Pro (PAL B/G FM) + - 0573:4d31 + + * - 39 + - Hauppauge WinTV USB Pro (PAL I FM) + - 0573:4d32 + + * - 40 + - Hauppauge WinTV USB Pro (PAL D/K FM) + - 0573:4d34 + + * - 41 + - Hauppauge WinTV USB Pro (Temic PAL/SECAM B/G/I/D/K/L FM) + - 0573:4d35 + + * - 42 + - Hauppauge WinTV USB Pro (Temic PAL B/G FM) + - 0573:4d36 + + * - 43 + - Hauppauge WinTV USB Pro (PAL/SECAM B/G/I/D/K/L FM) + - 0573:4d37 + + * - 44 + - Hauppauge WinTV USB Pro (NTSC M/N FM) V2 + - 0573:4d38 + + * - 45 + - Camtel Technology USB TV Genie Pro FM Model TVB330 + - 0768:0006 + + * - 46 + - Digital Video Creator I + - 07d0:0001 + + * - 47 + - Global Village GV-007 (NTSC) + - 07d0:0002 + + * - 48 + - Dazzle Fusion Model DVC-50 Rev 1 (NTSC) + - 07d0:0003 + + * - 49 + - Dazzle Fusion Model DVC-80 Rev 1 (PAL) + - 07d0:0004 + + * - 50 + - Dazzle Fusion Model DVC-90 Rev 1 (SECAM) + - 07d0:0005 + + * - 51 + - Eskape Labs MyTV2Go + - 07f8:9104 + + * - 52 + - Pinnacle Studio PCTV USB (PAL) + - 2304:010d + + * - 53 + - Pinnacle Studio PCTV USB (SECAM) + - 2304:0109 + + * - 54 + - Pinnacle Studio PCTV USB (PAL) FM + - 2304:0110 + + * - 55 + - Miro PCTV USB + - 2304:0111 + + * - 56 + - Pinnacle Studio PCTV USB (NTSC) FM + - 2304:0112 + + * - 57 + - Pinnacle Studio PCTV USB (PAL) FM V2 + - 2304:0210 + + * - 58 + - Pinnacle Studio PCTV USB (NTSC) FM V2 + - 2304:0212 + + * - 59 + - Pinnacle Studio PCTV USB (PAL) FM V3 + - 2304:0214 + + * - 60 + - Pinnacle Studio Linx Video input cable (NTSC) + - 2304:0300 + + * - 61 + - Pinnacle Studio Linx Video input cable (PAL) + - 2304:0301 + + * - 62 + - Pinnacle PCTV Bungee USB (PAL) FM + - 2304:0419 + + * - 63 + - Hauppauge WinTv-USB + - 2400:4200 + + * - 64 + - Pinnacle Studio PCTV USB (NTSC) FM V3 + - 2304:0113 + + * - 65 + - Nogatech USB MicroCam NTSC (NV3000N) + - 0573:3000 + + * - 66 + - Nogatech USB MicroCam PAL (NV3001P) + - 0573:3001 diff --git a/Documentation/media/v4l-drivers/vivid.rst b/Documentation/media/v4l-drivers/vivid.rst index 3e44b2217f2d..089595ce11c5 100644 --- a/Documentation/media/v4l-drivers/vivid.rst +++ b/Documentation/media/v4l-drivers/vivid.rst @@ -829,6 +829,7 @@ The following two controls are only valid for video and vbi capture. The following two controls are only valid for video capture. - DV Timings Signal Mode: + selects the behavior of VIDIOC_QUERY_DV_TIMINGS: what should it return? diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index c4ddfcd5ee32..b759a60624fd 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -498,11 +498,11 @@ And a couple of implicit varieties: This means that ACQUIRE acts as a minimal "acquire" operation and RELEASE acts as a minimal "release" operation. -A subset of the atomic operations described in core-api/atomic_ops.rst have -ACQUIRE and RELEASE variants in addition to fully-ordered and relaxed (no -barrier semantics) definitions. For compound atomics performing both a load -and a store, ACQUIRE semantics apply only to the load and RELEASE semantics -apply only to the store portion of the operation. +A subset of the atomic operations described in atomic_t.txt have ACQUIRE and +RELEASE variants in addition to fully-ordered and relaxed (no barrier +semantics) definitions. For compound atomics performing both a load and a +store, ACQUIRE semantics apply only to the load and RELEASE semantics apply +only to the store portion of the operation. Memory barriers are only required where there's a possibility of interaction between two CPUs or between a CPU and a device. If it can be guaranteed that @@ -594,29 +594,6 @@ between the address load and the data load: This enforces the occurrence of one of the two implications, and prevents the third possibility from arising. -A data-dependency barrier must also order against dependent writes: - - CPU 1 CPU 2 - =============== =============== - { A == 1, B == 2, C = 3, P == &A, Q == &C } - B = 4; - - WRITE_ONCE(P, &B); - Q = READ_ONCE(P); - - *Q = 5; - -The data-dependency barrier must order the read into Q with the store -into *Q. This prohibits this outcome: - - (Q == &B) && (B == 4) - -Please note that this pattern should be rare. After all, the whole point -of dependency ordering is to -prevent- writes to the data structure, along -with the expensive cache misses associated with those writes. This pattern -can be used to record rare error conditions and the like, and the ordering -prevents such records from being lost. - [!] Note that this extremely counterintuitive situation arises most easily on machines with split caches, so that, for example, one cache bank processes @@ -628,6 +605,36 @@ odd-numbered bank is idle, one can see the new value of the pointer P (&B), but the old value of the variable B (2). +A data-dependency barrier is not required to order dependent writes +because the CPUs that the Linux kernel supports don't do writes +until they are certain (1) that the write will actually happen, (2) +of the location of the write, and (3) of the value to be written. +But please carefully read the "CONTROL DEPENDENCIES" section and the +Documentation/RCU/rcu_dereference.txt file: The compiler can and does +break dependencies in a great many highly creative ways. + + CPU 1 CPU 2 + =============== =============== + { A == 1, B == 2, C = 3, P == &A, Q == &C } + B = 4; + + WRITE_ONCE(P, &B); + Q = READ_ONCE(P); + WRITE_ONCE(*Q, 5); + +Therefore, no data-dependency barrier is required to order the read into +Q with the store into *Q. In other words, this outcome is prohibited, +even without a data-dependency barrier: + + (Q == &B) && (B == 4) + +Please note that this pattern should be rare. After all, the whole point +of dependency ordering is to -prevent- writes to the data structure, along +with the expensive cache misses associated with those writes. This pattern +can be used to record rare error conditions and the like, and the CPUs' +naturally occurring ordering prevents such records from being lost. + + The data dependency barrier is very important to the RCU system, for example. See rcu_assign_pointer() and rcu_dereference() in include/linux/rcupdate.h. This permits the current target of an RCU'd @@ -1876,8 +1883,7 @@ There are some more advanced barrier functions: This makes sure that the death mark on the object is perceived to be set *before* the reference counter is decremented. - See Documentation/core-api/atomic_ops.rst for more information. See the - "Atomic operations" subsection for information on where to use these. + See Documentation/atomic_{t,bitops}.txt for more information. (*) lockless_dereference(); @@ -1982,10 +1988,7 @@ for each construct. These operations all imply certain barriers: ACQUIRE operation has completed. Memory operations issued before the ACQUIRE may be completed after - the ACQUIRE operation has completed. An smp_mb__before_spinlock(), - combined with a following ACQUIRE, orders prior stores against - subsequent loads and stores. Note that this is weaker than smp_mb()! - The smp_mb__before_spinlock() primitive is free on many architectures. + the ACQUIRE operation has completed. (2) RELEASE operation implication: @@ -2503,88 +2506,7 @@ operations are noted specially as some of them imply full memory barriers and some don't, but they're very heavily relied on as a group throughout the kernel. -Any atomic operation that modifies some state in memory and returns information -about the state (old or new) implies an SMP-conditional general memory barrier -(smp_mb()) on each side of the actual operation (with the exception of -explicit lock operations, described later). These include: - - xchg(); - atomic_xchg(); atomic_long_xchg(); - atomic_inc_return(); atomic_long_inc_return(); - atomic_dec_return(); atomic_long_dec_return(); - atomic_add_return(); atomic_long_add_return(); - atomic_sub_return(); atomic_long_sub_return(); - atomic_inc_and_test(); atomic_long_inc_and_test(); - atomic_dec_and_test(); atomic_long_dec_and_test(); - atomic_sub_and_test(); atomic_long_sub_and_test(); - atomic_add_negative(); atomic_long_add_negative(); - test_and_set_bit(); - test_and_clear_bit(); - test_and_change_bit(); - - /* when succeeds */ - cmpxchg(); - atomic_cmpxchg(); atomic_long_cmpxchg(); - atomic_add_unless(); atomic_long_add_unless(); - -These are used for such things as implementing ACQUIRE-class and RELEASE-class -operations and adjusting reference counters towards object destruction, and as -such the implicit memory barrier effects are necessary. - - -The following operations are potential problems as they do _not_ imply memory -barriers, but might be used for implementing such things as RELEASE-class -operations: - - atomic_set(); - set_bit(); - clear_bit(); - change_bit(); - -With these the appropriate explicit memory barrier should be used if necessary -(smp_mb__before_atomic() for instance). - - -The following also do _not_ imply memory barriers, and so may require explicit -memory barriers under some circumstances (smp_mb__before_atomic() for -instance): - - atomic_add(); - atomic_sub(); - atomic_inc(); - atomic_dec(); - -If they're used for statistics generation, then they probably don't need memory -barriers, unless there's a coupling between statistical data. - -If they're used for reference counting on an object to control its lifetime, -they probably don't need memory barriers because either the reference count -will be adjusted inside a locked section, or the caller will already hold -sufficient references to make the lock, and thus a memory barrier unnecessary. - -If they're used for constructing a lock of some description, then they probably -do need memory barriers as a lock primitive generally has to do things in a -specific order. - -Basically, each usage case has to be carefully considered as to whether memory -barriers are needed or not. - -The following operations are special locking primitives: - - test_and_set_bit_lock(); - clear_bit_unlock(); - __clear_bit_unlock(); - -These implement ACQUIRE-class and RELEASE-class operations. These should be -used in preference to other operations when implementing locking primitives, -because their implementations can be optimised on many architectures. - -[!] Note that special memory barrier primitives are available for these -situations because on some CPUs the atomic instructions used imply full memory -barriers, and so barrier instructions are superfluous in conjunction with them, -and in such cases the special barrier primitives will be no-ops. - -See Documentation/core-api/atomic_ops.rst for more information. +See Documentation/atomic_t.txt for more information. ACCESSING DEVICES diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index c6beb5f1637f..7a79b3587dd3 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX @@ -30,8 +30,6 @@ atm.txt - info on where to get ATM programs and support for Linux. ax25.txt - info on using AX.25 and NET/ROM code for Linux -batman-adv.txt - - B.A.T.M.A.N routing protocol on top of layer 2 Ethernet Frames. baycom.txt - info on the driver for Baycom style amateur radio modems bonding.txt diff --git a/Documentation/networking/batman-adv.rst b/Documentation/networking/batman-adv.rst new file mode 100644 index 000000000000..a342b2cc3dc6 --- /dev/null +++ b/Documentation/networking/batman-adv.rst @@ -0,0 +1,220 @@ +========== +batman-adv +========== + +Batman advanced is a new approach to wireless networking which does no longer +operate on the IP basis. Unlike the batman daemon, which exchanges information +using UDP packets and sets routing tables, batman-advanced operates on ISO/OSI +Layer 2 only and uses and routes (or better: bridges) Ethernet Frames. It +emulates a virtual network switch of all nodes participating. Therefore all +nodes appear to be link local, thus all higher operating protocols won't be +affected by any changes within the network. You can run almost any protocol +above batman advanced, prominent examples are: IPv4, IPv6, DHCP, IPX. + +Batman advanced was implemented as a Linux kernel driver to reduce the overhead +to a minimum. It does not depend on any (other) network driver, and can be used +on wifi as well as ethernet lan, vpn, etc ... (anything with ethernet-style +layer 2). + + +Configuration +============= + +Load the batman-adv module into your kernel:: + + $ insmod batman-adv.ko + +The module is now waiting for activation. You must add some interfaces on which +batman can operate. After loading the module batman advanced will scan your +systems interfaces to search for compatible interfaces. Once found, it will +create subfolders in the ``/sys`` directories of each supported interface, +e.g.:: + + $ ls /sys/class/net/eth0/batman_adv/ + elp_interval iface_status mesh_iface throughput_override + +If an interface does not have the ``batman_adv`` subfolder, it probably is not +supported. Not supported interfaces are: loopback, non-ethernet and batman's +own interfaces. + +Note: After the module was loaded it will continuously watch for new +interfaces to verify the compatibility. There is no need to reload the module +if you plug your USB wifi adapter into your machine after batman advanced was +initially loaded. + +The batman-adv soft-interface can be created using the iproute2 tool ``ip``:: + + $ ip link add name bat0 type batadv + +To activate a given interface simply attach it to the ``bat0`` interface:: + + $ ip link set dev eth0 master bat0 + +Repeat this step for all interfaces you wish to add. Now batman starts +using/broadcasting on this/these interface(s). + +By reading the "iface_status" file you can check its status:: + + $ cat /sys/class/net/eth0/batman_adv/iface_status + active + +To deactivate an interface you have to detach it from the "bat0" interface:: + + $ ip link set dev eth0 nomaster + + +All mesh wide settings can be found in batman's own interface folder:: + + $ ls /sys/class/net/bat0/mesh/ + aggregated_ogms fragmentation isolation_mark routing_algo + ap_isolation gw_bandwidth log_level vlan0 + bonding gw_mode multicast_mode + bridge_loop_avoidance gw_sel_class network_coding + distributed_arp_table hop_penalty orig_interval + +There is a special folder for debugging information:: + + $ ls /sys/kernel/debug/batman_adv/bat0/ + bla_backbone_table log neighbors transtable_local + bla_claim_table mcast_flags originators + dat_cache nc socket + gateways nc_nodes transtable_global + +Some of the files contain all sort of status information regarding the mesh +network. For example, you can view the table of originators (mesh +participants) with:: + + $ cat /sys/kernel/debug/batman_adv/bat0/originators + +Other files allow to change batman's behaviour to better fit your requirements. +For instance, you can check the current originator interval (value in +milliseconds which determines how often batman sends its broadcast packets):: + + $ cat /sys/class/net/bat0/mesh/orig_interval + 1000 + +and also change its value:: + + $ echo 3000 > /sys/class/net/bat0/mesh/orig_interval + +In very mobile scenarios, you might want to adjust the originator interval to a +lower value. This will make the mesh more responsive to topology changes, but +will also increase the overhead. + + +Usage +===== + +To make use of your newly created mesh, batman advanced provides a new +interface "bat0" which you should use from this point on. All interfaces added +to batman advanced are not relevant any longer because batman handles them for +you. Basically, one "hands over" the data by using the batman interface and +batman will make sure it reaches its destination. + +The "bat0" interface can be used like any other regular interface. It needs an +IP address which can be either statically configured or dynamically (by using +DHCP or similar services):: + + NodeA: ip link set up dev bat0 + NodeA: ip addr add 192.168.0.1/24 dev bat0 + + NodeB: ip link set up dev bat0 + NodeB: ip addr add 192.168.0.2/24 dev bat0 + NodeB: ping 192.168.0.1 + +Note: In order to avoid problems remove all IP addresses previously assigned to +interfaces now used by batman advanced, e.g.:: + + $ ip addr flush dev eth0 + + +Logging/Debugging +================= + +All error messages, warnings and information messages are sent to the kernel +log. Depending on your operating system distribution this can be read in one of +a number of ways. Try using the commands: ``dmesg``, ``logread``, or looking in +the files ``/var/log/kern.log`` or ``/var/log/syslog``. All batman-adv messages +are prefixed with "batman-adv:" So to see just these messages try:: + + $ dmesg | grep batman-adv + +When investigating problems with your mesh network, it is sometimes necessary to +see more detail debug messages. This must be enabled when compiling the +batman-adv module. When building batman-adv as part of kernel, use "make +menuconfig" and enable the option ``B.A.T.M.A.N. debugging`` +(``CONFIG_BATMAN_ADV_DEBUG=y``). + +Those additional debug messages can be accessed using a special file in +debugfs:: + + $ cat /sys/kernel/debug/batman_adv/bat0/log + +The additional debug output is by default disabled. It can be enabled during +run time. Following log_levels are defined: + +.. flat-table:: + + * - 0 + - All debug output disabled + * - 1 + - Enable messages related to routing / flooding / broadcasting + * - 2 + - Enable messages related to route added / changed / deleted + * - 4 + - Enable messages related to translation table operations + * - 8 + - Enable messages related to bridge loop avoidance + * - 16 + - Enable messages related to DAT, ARP snooping and parsing + * - 32 + - Enable messages related to network coding + * - 64 + - Enable messages related to multicast + * - 128 + - Enable messages related to throughput meter + * - 255 + - Enable all messages + +The debug output can be changed at runtime using the file +``/sys/class/net/bat0/mesh/log_level``. e.g.:: + + $ echo 6 > /sys/class/net/bat0/mesh/log_level + +will enable debug messages for when routes change. + +Counters for different types of packets entering and leaving the batman-adv +module are available through ethtool:: + + $ ethtool --statistics bat0 + + +batctl +====== + +As batman advanced operates on layer 2, all hosts participating in the virtual +switch are completely transparent for all protocols above layer 2. Therefore +the common diagnosis tools do not work as expected. To overcome these problems, +batctl was created. At the moment the batctl contains ping, traceroute, tcpdump +and interfaces to the kernel module settings. + +For more information, please see the manpage (``man batctl``). + +batctl is available on https://www.open-mesh.org/ + + +Contact +======= + +Please send us comments, experiences, questions, anything :) + +IRC: + #batman on irc.freenode.org +Mailing-list: + b.a.t.m.a.n@open-mesh.org (optional subscription at + https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) + +You can also contact the Authors: + +* Marek Lindner +* Simon Wunderlich diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt deleted file mode 100644 index ccf94677b240..000000000000 --- a/Documentation/networking/batman-adv.txt +++ /dev/null @@ -1,215 +0,0 @@ -BATMAN-ADV ----------- - -Batman advanced is a new approach to wireless networking which -does no longer operate on the IP basis. Unlike the batman daemon, -which exchanges information using UDP packets and sets routing -tables, batman-advanced operates on ISO/OSI Layer 2 only and uses -and routes (or better: bridges) Ethernet Frames. It emulates a -virtual network switch of all nodes participating. Therefore all -nodes appear to be link local, thus all higher operating proto- -cols won't be affected by any changes within the network. You can -run almost any protocol above batman advanced, prominent examples -are: IPv4, IPv6, DHCP, IPX. - -Batman advanced was implemented as a Linux kernel driver to re- -duce the overhead to a minimum. It does not depend on any (other) -network driver, and can be used on wifi as well as ethernet lan, -vpn, etc ... (anything with ethernet-style layer 2). - - -CONFIGURATION -------------- - -Load the batman-adv module into your kernel: - -# insmod batman-adv.ko - -The module is now waiting for activation. You must add some in- -terfaces on which batman can operate. After loading the module -batman advanced will scan your systems interfaces to search for -compatible interfaces. Once found, it will create subfolders in -the /sys directories of each supported interface, e.g. - -# ls /sys/class/net/eth0/batman_adv/ -# elp_interval iface_status mesh_iface throughput_override - -If an interface does not have the "batman_adv" subfolder it prob- -ably is not supported. Not supported interfaces are: loopback, -non-ethernet and batman's own interfaces. - -Note: After the module was loaded it will continuously watch for -new interfaces to verify the compatibility. There is no need to -reload the module if you plug your USB wifi adapter into your ma- -chine after batman advanced was initially loaded. - -The batman-adv soft-interface can be created using the iproute2 -tool "ip" - -# ip link add name bat0 type batadv - -To activate a given interface simply attach it to the "bat0" -interface - -# ip link set dev eth0 master bat0 - -Repeat this step for all interfaces you wish to add. Now batman -starts using/broadcasting on this/these interface(s). - -By reading the "iface_status" file you can check its status: - -# cat /sys/class/net/eth0/batman_adv/iface_status -# active - -To deactivate an interface you have to detach it from the -"bat0" interface: - -# ip link set dev eth0 nomaster - - -All mesh wide settings can be found in batman's own interface -folder: - -# ls /sys/class/net/bat0/mesh/ -# aggregated_ogms fragmentation isolation_mark routing_algo -# ap_isolation gw_bandwidth log_level vlan0 -# bonding gw_mode multicast_mode -# bridge_loop_avoidance gw_sel_class network_coding -# distributed_arp_table hop_penalty orig_interval - -There is a special folder for debugging information: - -# ls /sys/kernel/debug/batman_adv/bat0/ -# bla_backbone_table log neighbors transtable_local -# bla_claim_table mcast_flags originators -# dat_cache nc socket -# gateways nc_nodes transtable_global - -Some of the files contain all sort of status information regard- -ing the mesh network. For example, you can view the table of -originators (mesh participants) with: - -# cat /sys/kernel/debug/batman_adv/bat0/originators - -Other files allow to change batman's behaviour to better fit your -requirements. For instance, you can check the current originator -interval (value in milliseconds which determines how often batman -sends its broadcast packets): - -# cat /sys/class/net/bat0/mesh/orig_interval -# 1000 - -and also change its value: - -# echo 3000 > /sys/class/net/bat0/mesh/orig_interval - -In very mobile scenarios, you might want to adjust the originator -interval to a lower value. This will make the mesh more respon- -sive to topology changes, but will also increase the overhead. - - -USAGE ------ - -To make use of your newly created mesh, batman advanced provides -a new interface "bat0" which you should use from this point on. -All interfaces added to batman advanced are not relevant any -longer because batman handles them for you. Basically, one "hands -over" the data by using the batman interface and batman will make -sure it reaches its destination. - -The "bat0" interface can be used like any other regular inter- -face. It needs an IP address which can be either statically con- -figured or dynamically (by using DHCP or similar services): - -# NodeA: ip link set up dev bat0 -# NodeA: ip addr add 192.168.0.1/24 dev bat0 - -# NodeB: ip link set up dev bat0 -# NodeB: ip addr add 192.168.0.2/24 dev bat0 -# NodeB: ping 192.168.0.1 - -Note: In order to avoid problems remove all IP addresses previ- -ously assigned to interfaces now used by batman advanced, e.g. - -# ip addr flush dev eth0 - - -LOGGING/DEBUGGING ------------------ - -All error messages, warnings and information messages are sent to -the kernel log. Depending on your operating system distribution -this can be read in one of a number of ways. Try using the com- -mands: dmesg, logread, or looking in the files /var/log/kern.log -or /var/log/syslog. All batman-adv messages are prefixed with -"batman-adv:" So to see just these messages try - -# dmesg | grep batman-adv - -When investigating problems with your mesh network it is some- -times necessary to see more detail debug messages. This must be -enabled when compiling the batman-adv module. When building bat- -man-adv as part of kernel, use "make menuconfig" and enable the -option "B.A.T.M.A.N. debugging". - -Those additional debug messages can be accessed using a special -file in debugfs - -# cat /sys/kernel/debug/batman_adv/bat0/log - -The additional debug output is by default disabled. It can be en- -abled during run time. Following log_levels are defined: - - 0 - All debug output disabled - 1 - Enable messages related to routing / flooding / broadcasting - 2 - Enable messages related to route added / changed / deleted - 4 - Enable messages related to translation table operations - 8 - Enable messages related to bridge loop avoidance - 16 - Enable messages related to DAT, ARP snooping and parsing - 32 - Enable messages related to network coding - 64 - Enable messages related to multicast -128 - Enable messages related to throughput meter -255 - Enable all messages - -The debug output can be changed at runtime using the file -/sys/class/net/bat0/mesh/log_level. e.g. - -# echo 6 > /sys/class/net/bat0/mesh/log_level - -will enable debug messages for when routes change. - -Counters for different types of packets entering and leaving the -batman-adv module are available through ethtool: - -# ethtool --statistics bat0 - - -BATCTL ------- - -As batman advanced operates on layer 2 all hosts participating in -the virtual switch are completely transparent for all protocols -above layer 2. Therefore the common diagnosis tools do not work -as expected. To overcome these problems batctl was created. At -the moment the batctl contains ping, traceroute, tcpdump and -interfaces to the kernel module settings. - -For more information, please see the manpage (man batctl). - -batctl is available on https://www.open-mesh.org/ - - -CONTACT -------- - -Please send us comments, experiences, questions, anything :) - -IRC: #batman on irc.freenode.org -Mailing-list: b.a.t.m.a.n@open-mesh.org (optional subscription - at https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) - -You can also contact the Authors: - -Marek Lindner -Simon Wunderlich diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 57f52cdce32e..9ba04c0bab8d 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -2387,7 +2387,7 @@ broadcast: Like active-backup, there is not much advantage to this and packet type ID), so in a "gatewayed" configuration, all outgoing traffic will generally use the same device. Incoming traffic may also end up on a single device, but that is - dependent upon the balancing policy of the peer's 8023.ad + dependent upon the balancing policy of the peer's 802.3ad implementation. In a "local" configuration, traffic will be distributed across the devices in the bond. diff --git a/Documentation/networking/dpaa.txt b/Documentation/networking/dpaa.txt index 76e016d4d344..f88194f71c54 100644 --- a/Documentation/networking/dpaa.txt +++ b/Documentation/networking/dpaa.txt @@ -13,6 +13,7 @@ Contents - Configuring DPAA Ethernet in your kernel - DPAA Ethernet Frame Processing - DPAA Ethernet Features + - DPAA IRQ Affinity and Receive Side Scaling - Debugging DPAA Ethernet Overview @@ -147,7 +148,10 @@ gradually. The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx checksum offload feature is enabled by default and cannot be controlled through -ethtool. +ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS +provides a big performance boost for the forwarding scenarios, allowing +different traffic flows received by one interface to be processed by different +CPUs in parallel. The driver has support for multiple prioritized Tx traffic classes. Priorities range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with @@ -166,6 +170,68 @@ classes as follows: tc qdisc add dev root handle 1: \ mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1 +DPAA IRQ Affinity and Receive Side Scaling +========================================== + +Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation +queues is seen by the CPU as ingress traffic on a certain portal. +The DPAA QMan portal interrupts are affined each to a certain CPU. +The same portal interrupt services all the QMan portal consumers. + +By default the DPAA Ethernet driver enables RSS, making use of the +DPAA FMan Parser and Keygen blocks to distribute traffic on 128 +hardware frame queues using a hash on IP v4/v6 source and destination +and L4 source and destination ports, in present in the received frame. +When RSS is disabled, all traffic received by a certain interface is +received on the default Rx frame queue. The default DPAA Rx frame +queues are configured to put the received traffic into a pool channel +that allows any available CPU portal to dequeue the ingress traffic. +The default frame queues have the HOLDACTIVE option set, ensuring that +traffic bursts from a certain queue are serviced by the same CPU. +This ensures a very low rate of frame reordering. A drawback of this +is that only one CPU at a time can service the traffic received by a +certain interface when RSS is not enabled. + +To implement RSS, the DPAA Ethernet driver allocates an extra set of +128 Rx frame queues that are configured to dedicated channels, in a +round-robin manner. The mapping of the frame queues to CPUs is now +hardcoded, there is no indirection table to move traffic for a certain +FQ (hash result) to another CPU. The ingress traffic arriving on one +of these frame queues will arrive at the same portal and will always +be processed by the same CPU. This ensures intra-flow order preservation +and workload distribution for multiple traffic flows. + +RSS can be turned off for a certain interface using ethtool, i.e. + + # ethtool -N fm1-mac9 rx-flow-hash tcp4 "" + +To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6: + + # ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn + +There is no independent control for individual protocols, any command +run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is +going to control the rx-flow-hashing for all protocols on that interface. + +Besides using the FMan Keygen computed hash for spreading traffic on the +128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when +the NETIF_F_RXHASH feature is on (active by default). This can be turned +on or off through ethtool, i.e.: + + # ethtool -K fm1-mac9 rx-hashing off + # ethtool -k fm1-mac9 | grep hash + receive-hashing: off + # ethtool -K fm1-mac9 rx-hashing on + Actual changes: + receive-hashing: on + # ethtool -k fm1-mac9 | grep hash + receive-hashing: on + +Please note that Rx hashing depends upon the rx-flow-hashing being on +for that interface - turning off rx-flow-hashing will also disable the +rx-hashing (without ethtool reporting it as off as that depends on the +NETIF_F_RXHASH feature flag). + Debugging ========= diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt index b69b205501de..87814859cfc2 100644 --- a/Documentation/networking/filter.txt +++ b/Documentation/networking/filter.txt @@ -45,7 +45,7 @@ in many more places. There's xt_bpf for netfilter, cls_bpf in the kernel qdisc layer, SECCOMP-BPF (SECure COMPuting [1]), and lots of other places such as team driver, PTP code, etc where BPF is being used. - [1] Documentation/prctl/seccomp_filter.txt + [1] Documentation/userspace-api/seccomp_filter.rst Original BPF paper: @@ -337,7 +337,7 @@ Examples for low-level BPF: jeq #14, good /* __NR_rt_sigprocmask */ jeq #13, good /* __NR_rt_sigaction */ jeq #35, good /* __NR_nanosleep */ - bad: ret #0 /* SECCOMP_RET_KILL */ + bad: ret #0 /* SECCOMP_RET_KILL_THREAD */ good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */ The above example code can be placed into a file (here called "foo"), and @@ -596,8 +596,8 @@ skb pointer). All constraints and restrictions from bpf_check_classic() apply before a conversion to the new layout is being done behind the scenes! Currently, the classic BPF format is being used for JITing on most 32-bit -architectures, whereas x86-64, aarch64, s390x, powerpc64, sparc64 perform JIT -compilation from eBPF instruction set. +architectures, whereas x86-64, aarch64, s390x, powerpc64, sparc64, arm32 perform +JIT compilation from eBPF instruction set. Some core changes of the new internal format: @@ -793,7 +793,7 @@ Some core changes of the new internal format: bpf_exit After the call the registers R1-R5 contain junk values and cannot be read. - In the future an eBPF verifier can be used to validate internal BPF programs. + An in-kernel eBPF verifier is used to validate internal BPF programs. Also in the new design, eBPF is limited to 4096 insns, which means that any program will terminate quickly and will only call a fixed number of kernel @@ -906,6 +906,10 @@ If BPF_CLASS(code) == BPF_JMP, BPF_OP(code) is one of: BPF_JSGE 0x70 /* eBPF only: signed '>=' */ BPF_CALL 0x80 /* eBPF only: function call */ BPF_EXIT 0x90 /* eBPF only: function return */ + BPF_JLT 0xa0 /* eBPF only: unsigned '<' */ + BPF_JLE 0xb0 /* eBPF only: unsigned '<=' */ + BPF_JSLT 0xc0 /* eBPF only: signed '<' */ + BPF_JSLE 0xd0 /* eBPF only: signed '<=' */ So BPF_ADD | BPF_X | BPF_ALU means 32-bit addition in both classic BPF and eBPF. There are only two registers in classic BPF, so it means A += X. @@ -1017,7 +1021,7 @@ At the start of the program the register R1 contains a pointer to context and has type PTR_TO_CTX. If verifier sees an insn that does R2=R1, then R2 has now type PTR_TO_CTX as well and can be used on the right hand side of expression. -If R1=PTR_TO_CTX and insn is R2=R1+R1, then R2=UNKNOWN_VALUE, +If R1=PTR_TO_CTX and insn is R2=R1+R1, then R2=SCALAR_VALUE, since addition of two valid pointers makes invalid pointer. (In 'secure' mode verifier will reject any type of pointer arithmetic to make sure that kernel addresses don't leak to unprivileged users) @@ -1039,7 +1043,7 @@ is a correct program. If there was R1 instead of R6, it would have been rejected. load/store instructions are allowed only with registers of valid types, which -are PTR_TO_CTX, PTR_TO_MAP, FRAME_PTR. They are bounds and alignment checked. +are PTR_TO_CTX, PTR_TO_MAP, PTR_TO_STACK. They are bounds and alignment checked. For example: bpf_mov R1 = 1 bpf_mov R2 = 2 @@ -1058,7 +1062,7 @@ intends to load a word from address R6 + 8 and store it into R0 If R6=PTR_TO_CTX, via is_valid_access() callback the verifier will know that offset 8 of size 4 bytes can be accessed for reading, otherwise the verifier will reject the program. -If R6=FRAME_PTR, then access should be aligned and be within +If R6=PTR_TO_STACK, then access should be aligned and be within stack bounds, which are [-MAX_BPF_STACK, 0). In this example offset is 8, so it will fail verification, since it's out of bounds. @@ -1069,7 +1073,7 @@ For example: bpf_ld R0 = *(u32 *)(R10 - 4) bpf_exit is invalid program. -Though R10 is correct read-only register and has type FRAME_PTR +Though R10 is correct read-only register and has type PTR_TO_STACK and R10 - 4 is within stack bounds, there were no stores into that location. Pointer register spill/fill is tracked as well, since four (R6-R9) @@ -1094,6 +1098,71 @@ all use cases. See details of eBPF verifier in kernel/bpf/verifier.c +Register value tracking +----------------------- +In order to determine the safety of an eBPF program, the verifier must track +the range of possible values in each register and also in each stack slot. +This is done with 'struct bpf_reg_state', defined in include/linux/ +bpf_verifier.h, which unifies tracking of scalar and pointer values. Each +register state has a type, which is either NOT_INIT (the register has not been +written to), SCALAR_VALUE (some value which is not usable as a pointer), or a +pointer type. The types of pointers describe their base, as follows: + PTR_TO_CTX Pointer to bpf_context. + CONST_PTR_TO_MAP Pointer to struct bpf_map. "Const" because arithmetic + on these pointers is forbidden. + PTR_TO_MAP_VALUE Pointer to the value stored in a map element. + PTR_TO_MAP_VALUE_OR_NULL + Either a pointer to a map value, or NULL; map accesses + (see section 'eBPF maps', below) return this type, + which becomes a PTR_TO_MAP_VALUE when checked != NULL. + Arithmetic on these pointers is forbidden. + PTR_TO_STACK Frame pointer. + PTR_TO_PACKET skb->data. + PTR_TO_PACKET_END skb->data + headlen; arithmetic forbidden. +However, a pointer may be offset from this base (as a result of pointer +arithmetic), and this is tracked in two parts: the 'fixed offset' and 'variable +offset'. The former is used when an exactly-known value (e.g. an immediate +operand) is added to a pointer, while the latter is used for values which are +not exactly known. The variable offset is also used in SCALAR_VALUEs, to track +the range of possible values in the register. +The verifier's knowledge about the variable offset consists of: +* minimum and maximum values as unsigned +* minimum and maximum values as signed +* knowledge of the values of individual bits, in the form of a 'tnum': a u64 +'mask' and a u64 'value'. 1s in the mask represent bits whose value is unknown; +1s in the value represent bits known to be 1. Bits known to be 0 have 0 in both +mask and value; no bit should ever be 1 in both. For example, if a byte is read +into a register from memory, the register's top 56 bits are known zero, while +the low 8 are unknown - which is represented as the tnum (0x0; 0xff). If we +then OR this with 0x40, we get (0x40; 0xcf), then if we add 1 we get (0x0; +0x1ff), because of potential carries. +Besides arithmetic, the register state can also be updated by conditional +branches. For instance, if a SCALAR_VALUE is compared > 8, in the 'true' branch +it will have a umin_value (unsigned minimum value) of 9, whereas in the 'false' +branch it will have a umax_value of 8. A signed compare (with BPF_JSGT or +BPF_JSGE) would instead update the signed minimum/maximum values. Information +from the signed and unsigned bounds can be combined; for instance if a value is +first tested < 8 and then tested s> 4, the verifier will conclude that the value +is also > 4 and s< 8, since the bounds prevent crossing the sign boundary. +PTR_TO_PACKETs with a variable offset part have an 'id', which is common to all +pointers sharing that same variable offset. This is important for packet range +checks: after adding some variable to a packet pointer, if you then copy it to +another register and (say) add a constant 4, both registers will share the same +'id' but one will have a fixed offset of +4. Then if it is bounds-checked and +found to be less than a PTR_TO_PACKET_END, the other register is now known to +have a safe range of at least 4 bytes. See 'Direct packet access', below, for +more on PTR_TO_PACKET ranges. +The 'id' field is also used on PTR_TO_MAP_VALUE_OR_NULL, common to all copies of +the pointer returned from a map lookup. This means that when one copy is +checked and found to be non-NULL, all copies can become PTR_TO_MAP_VALUEs. +As well as range-checking, the tracked information is also used for enforcing +alignment of pointer accesses. For instance, on most systems the packet pointer +is 2 bytes after a 4-byte alignment. If a program adds 14 bytes to that to jump +over the Ethernet header, then reads IHL and addes (IHL * 4), the resulting +pointer will have a variable offset known to be 4n+2 for some n, so adding the 2 +bytes (NET_IP_ALIGN) gives a 4-byte alignment and so word-sized accesses through +that pointer are safe. + Direct packet access -------------------- In cls_bpf and act_bpf programs the verifier allows direct access to the packet @@ -1121,7 +1190,7 @@ it now points to 'skb->data + 14' and accessible range is [R5, R5 + 14 - 14) which is zero bytes. More complex packet access may look like: - R0=imm1 R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp + R0=inv1 R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp 6: r0 = *(u8 *)(r3 +7) /* load 7th byte from the packet */ 7: r4 = *(u8 *)(r3 +12) 8: r4 *= 14 @@ -1135,26 +1204,31 @@ More complex packet access may look like: 16: r2 += 8 17: r1 = *(u32 *)(r1 +80) /* load skb->data_end */ 18: if r2 > r1 goto pc+2 - R0=inv56 R1=pkt_end R2=pkt(id=2,off=8,r=8) R3=pkt(id=2,off=0,r=8) R4=inv52 R5=pkt(id=0,off=14,r=14) R10=fp + R0=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R1=pkt_end R2=pkt(id=2,off=8,r=8) R3=pkt(id=2,off=0,r=8) R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)) R5=pkt(id=0,off=14,r=14) R10=fp 19: r1 = *(u8 *)(r3 +4) The state of the register R3 is R3=pkt(id=2,off=0,r=8) id=2 means that two 'r3 += rX' instructions were seen, so r3 points to some offset within a packet and since the program author did 'if (r3 + 8 > r1) goto err' at insn #18, the safe range is [R3, R3 + 8). -The verifier only allows 'add' operation on packet registers. Any other -operation will set the register state to 'unknown_value' and it won't be +The verifier only allows 'add'/'sub' operations on packet registers. Any other +operation will set the register state to 'SCALAR_VALUE' and it won't be available for direct packet access. Operation 'r3 += rX' may overflow and become less than original skb->data, -therefore the verifier has to prevent that. So it tracks the number of -upper zero bits in all 'uknown_value' registers, so when it sees -'r3 += rX' instruction and rX is more than 16-bit value, it will error as: -"cannot add integer value with N upper zero bits to ptr_to_packet" +therefore the verifier has to prevent that. So when it sees 'r3 += rX' +instruction and rX is more than 16-bit value, any subsequent bounds-check of r3 +against skb->data_end will not give us 'range' information, so attempts to read +through the pointer will give "invalid access to packet" error. Ex. after insn 'r4 = *(u8 *)(r3 +12)' (insn #7 above) the state of r4 is -R4=inv56 which means that upper 56 bits on the register are guaranteed -to be zero. After insn 'r4 *= 14' the state becomes R4=inv52, since -multiplying 8-bit value by constant 14 will keep upper 52 bits as zero. -Similarly 'r2 >>= 48' will make R2=inv48, since the shift is not sign -extending. This logic is implemented in evaluate_reg_alu() function. +R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) which means that upper 56 bits +of the register are guaranteed to be zero, and nothing is known about the lower +8 bits. After insn 'r4 *= 14' the state becomes +R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)), since multiplying an 8-bit +value by constant 14 will keep upper 52 bits as zero, also the least significant +bit will be zero as 14 is even. Similarly 'r2 >>= 48' will make +R2=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff)), since the shift is not sign +extending. This logic is implemented in adjust_reg_min_max_vals() function, +which calls adjust_ptr_min_max_vals() for adding pointer to scalar (or vice +versa) and adjust_scalar_min_max_vals() for operations on two scalars. The end result is that bpf program author can access packet directly using normal C code as: @@ -1214,6 +1288,22 @@ The map is defined by: . key size in bytes . value size in bytes +Pruning +------- +The verifier does not actually walk all possible paths through the program. For +each new branch to analyse, the verifier looks at all the states it's previously +been in when at this instruction. If any of them contain the current state as a +subset, the branch is 'pruned' - that is, the fact that the previous state was +accepted implies the current state would be as well. For instance, if in the +previous state, r1 held a packet-pointer, and in the current state, r1 holds a +packet-pointer with a range as long or longer and at least as strict an +alignment, then r1 is safe. Similarly, if r2 was NOT_INIT before then it can't +have been used by any path from that point, so any value in r2 (including +another NOT_INIT) is safe. The implementation is in the function regsafe(). +Pruning considers not only the registers but also the stack (and any spilled +registers it may hold). They must all be safe for the branch to be pruned. +This is implemented in states_equal(). + Understanding eBPF verifier messages ------------------------------------ diff --git a/Documentation/networking/hinic.txt b/Documentation/networking/hinic.txt new file mode 100644 index 000000000000..989366a4039c --- /dev/null +++ b/Documentation/networking/hinic.txt @@ -0,0 +1,125 @@ +Linux Kernel Driver for Huawei Intelligent NIC(HiNIC) family +============================================================ + +Overview: +========= +HiNIC is a network interface card for the Data Center Area. + +The driver supports a range of link-speed devices (10GbE, 25GbE, 40GbE, etc.). +The driver supports also a negotiated and extendable feature set. + +Some HiNIC devices support SR-IOV. This driver is used for Physical Function +(PF). + +HiNIC devices support MSI-X interrupt vector for each Tx/Rx queue and +adaptive interrupt moderation. + +HiNIC devices support also various offload features such as checksum offload, +TCP Transmit Segmentation Offload(TSO), Receive-Side Scaling(RSS) and +LRO(Large Receive Offload). + + +Supported PCI vendor ID/device IDs: +=================================== + +19e5:1822 - HiNIC PF + + +Driver Architecture and Source Code: +==================================== + +hinic_dev - Implement a Logical Network device that is independent from +specific HW details about HW data structure formats. + +hinic_hwdev - Implement the HW details of the device and include the components +for accessing the PCI NIC. + +hinic_hwdev contains the following components: +=============================================== + +HW Interface: +============= + +The interface for accessing the pci device (DMA memory and PCI BARs). +(hinic_hw_if.c, hinic_hw_if.h) + +Configuration Status Registers Area that describes the HW Registers on the +configuration and status BAR0. (hinic_hw_csr.h) + +MGMT components: +================ + +Asynchronous Event Queues(AEQs) - The event queues for receiving messages from +the MGMT modules on the cards. (hinic_hw_eqs.c, hinic_hw_eqs.h) + +Application Programmable Interface commands(API CMD) - Interface for sending +MGMT commands to the card. (hinic_hw_api_cmd.c, hinic_hw_api_cmd.h) + +Management (MGMT) - the PF to MGMT channel that uses API CMD for sending MGMT +commands to the card and receives notifications from the MGMT modules on the +card by AEQs. Also set the addresses of the IO CMDQs in HW. +(hinic_hw_mgmt.c, hinic_hw_mgmt.h) + +IO components: +============== + +Completion Event Queues(CEQs) - The completion Event Queues that describe IO +tasks that are finished. (hinic_hw_eqs.c, hinic_hw_eqs.h) + +Work Queues(WQ) - Contain the memory and operations for use by CMD queues and +the Queue Pairs. The WQ is a Memory Block in a Page. The Block contains +pointers to Memory Areas that are the Memory for the Work Queue Elements(WQEs). +(hinic_hw_wq.c, hinic_hw_wq.h) + +Command Queues(CMDQ) - The queues for sending commands for IO management and is +used to set the QPs addresses in HW. The commands completion events are +accumulated on the CEQ that is configured to receive the CMDQ completion events. +(hinic_hw_cmdq.c, hinic_hw_cmdq.h) + +Queue Pairs(QPs) - The HW Receive and Send queues for Receiving and Transmitting +Data. (hinic_hw_qp.c, hinic_hw_qp.h, hinic_hw_qp_ctxt.h) + +IO - de/constructs all the IO components. (hinic_hw_io.c, hinic_hw_io.h) + +HW device: +========== + +HW device - de/constructs the HW Interface, the MGMT components on the +initialization of the driver and the IO components on the case of Interface +UP/DOWN Events. (hinic_hw_dev.c, hinic_hw_dev.h) + + +hinic_dev contains the following components: +=============================================== + +PCI ID table - Contains the supported PCI Vendor/Device IDs. +(hinic_pci_tbl.h) + +Port Commands - Send commands to the HW device for port management +(MAC, Vlan, MTU, ...). (hinic_port.c, hinic_port.h) + +Tx Queues - Logical Tx Queues that use the HW Send Queues for transmit. +The Logical Tx queue is not dependent on the format of the HW Send Queue. +(hinic_tx.c, hinic_tx.h) + +Rx Queues - Logical Rx Queues that use the HW Receive Queues for receive. +The Logical Rx queue is not dependent on the format of the HW Receive Queue. +(hinic_rx.c, hinic_rx.h) + +hinic_dev - de/constructs the Logical Tx and Rx Queues. +(hinic_main.c, hinic_dev.h) + + +Miscellaneous: +============= + +Common functions that are used by HW and Logical Device. +(hinic_common.c, hinic_common.h) + + +Support +======= + +If an issue is identified with the released source code on the supported kernel +with a supported adapter, email the specific information related to the issue to +aviad.krawczyk@huawei.com. diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt index c4114346f054..057e9fdbfac9 100644 --- a/Documentation/networking/ieee802154.txt +++ b/Documentation/networking/ieee802154.txt @@ -84,17 +84,17 @@ Device drivers API ================== The include/net/mac802154.h defines following functions: - - struct ieee802154_dev *ieee802154_alloc_device - (size_t priv_size, struct ieee802154_ops *ops): - allocation of IEEE 802.15.4 compatible device + - struct ieee802154_hw * + ieee802154_alloc_hw(size_t priv_data_len, const struct ieee802154_ops *ops): + allocation of IEEE 802.15.4 compatible hardware device - - void ieee802154_free_device(struct ieee802154_dev *dev): - freeing allocated device + - void ieee802154_free_hw(struct ieee802154_hw *hw): + freeing allocated hardware device - - int ieee802154_register_device(struct ieee802154_dev *dev): - register PHY in the system + - int ieee802154_register_hw(struct ieee802154_hw *hw): + register PHY which is the allocated hardware device, in the system - - void ieee802154_unregister_device(struct ieee802154_dev *dev): + - void ieee802154_unregister_hw(struct ieee802154_hw *hw): freeing registered PHY Moreover IEEE 802.15.4 device operations structure should be filled. diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst index b5bd87e01f52..66e620866245 100644 --- a/Documentation/networking/index.rst +++ b/Documentation/networking/index.rst @@ -6,6 +6,7 @@ Contents: .. toctree:: :maxdepth: 2 + batman-adv kapi z8530book diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 974ab47ae53a..77f4de59dc9c 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -109,7 +109,10 @@ neigh/default/unres_qlen_bytes - INTEGER queued for each unresolved address by other network layers. (added in linux 3.3) Setting negative value is meaningless and will return error. - Default: 65536 Bytes(64KB) + Default: SK_WMEM_MAX, (same as net.core.wmem_default). + Exact value depends on architecture and kernel options, + but should be enough to allow queuing 256 packets + of medium size. neigh/default/unres_qlen - INTEGER The maximum number of packets which may be queued for each @@ -119,7 +122,7 @@ neigh/default/unres_qlen - INTEGER unexpected packet loss. The current default value is calculated according to default value of unres_qlen_bytes and true size of packet. - Default: 31 + Default: 101 mtu_expires - INTEGER Time, in seconds, that cached PMTU information is kept. @@ -353,12 +356,7 @@ tcp_l3mdev_accept - BOOLEAN compiled with CONFIG_NET_L3_MASTER_DEV. tcp_low_latency - BOOLEAN - If set, the TCP stack makes decisions that prefer lower - latency as opposed to higher throughput. By default, this - option is not set meaning that higher throughput is preferred. - An example of an application where this default should be - changed would be a Beowulf compute cluster. - Default: 0 + This is a legacy option, it has no effect anymore. tcp_max_orphans - INTEGER Maximal number of TCP sockets not attached to any user file handle, @@ -1291,8 +1289,7 @@ tag - INTEGER xfrm4_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv4 destination cache entries. At twice this value the system will - refuse new allocations. The value must be set below the flowcache - limit (4096 * number of online cpus) to take effect. + refuse new allocations. igmp_link_local_mcast_reports - BOOLEAN Enable IGMP reports for link local multicast groups in the @@ -1356,6 +1353,15 @@ flowlabel_state_ranges - BOOLEAN FALSE: disabled Default: true +flowlabel_reflect - BOOLEAN + Automatically reflect the flow label. Needed for Path MTU + Discovery to work with Equal Cost Multipath Routing in anycast + environments. See RFC 7690 and: + https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01 + TRUE: enabled + FALSE: disabled + Default: FALSE + anycast_src_echo_reply - BOOLEAN Controls the use of anycast addresses as source addresses for ICMPv6 echo reply @@ -1674,6 +1680,9 @@ accept_dad - INTEGER 2: Enable DAD, and disable IPv6 operation if MAC-based duplicate link-local address has been found. + DAD operation and mode on a given interface will be selected according + to the maximum value of conf/{all,interface}/accept_dad. + force_tllao - BOOLEAN Enable sending the target link-layer address option even when responding to a unicast neighbor solicitation. @@ -1721,16 +1730,23 @@ suppress_frag_ndisc - INTEGER optimistic_dad - BOOLEAN Whether to perform Optimistic Duplicate Address Detection (RFC 4429). - 0: disabled (default) - 1: enabled + 0: disabled (default) + 1: enabled + + Optimistic Duplicate Address Detection for the interface will be enabled + if at least one of conf/{all,interface}/optimistic_dad is set to 1, + it will be disabled otherwise. use_optimistic - BOOLEAN If enabled, do not classify optimistic addresses as deprecated during source address selection. Preferred addresses will still be chosen before optimistic addresses, subject to other ranking in the source address selection algorithm. - 0: disabled (default) - 1: enabled + 0: disabled (default) + 1: enabled + + This will be enabled if at least one of + conf/{all,interface}/use_optimistic is set to 1, disabled otherwise. stable_secret - IPv6 address This IPv6 address will be used as a secret to generate IPv6 @@ -1778,8 +1794,7 @@ ratelimit - INTEGER xfrm6_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv6 destination cache entries. At twice this value the system will - refuse new allocations. The value must be set below the flowcache - limit (4096 * number of online cpus) to take effect. + refuse new allocations. IPv6 Update by: diff --git a/Documentation/networking/msg_zerocopy.rst b/Documentation/networking/msg_zerocopy.rst new file mode 100644 index 000000000000..77f6d7e25cfd --- /dev/null +++ b/Documentation/networking/msg_zerocopy.rst @@ -0,0 +1,257 @@ + +============ +MSG_ZEROCOPY +============ + +Intro +===== + +The MSG_ZEROCOPY flag enables copy avoidance for socket send calls. +The feature is currently implemented for TCP sockets. + + +Opportunity and Caveats +----------------------- + +Copying large buffers between user process and kernel can be +expensive. Linux supports various interfaces that eschew copying, +such as sendpage and splice. The MSG_ZEROCOPY flag extends the +underlying copy avoidance mechanism to common socket send calls. + +Copy avoidance is not a free lunch. As implemented, with page pinning, +it replaces per byte copy cost with page accounting and completion +notification overhead. As a result, MSG_ZEROCOPY is generally only +effective at writes over around 10 KB. + +Page pinning also changes system call semantics. It temporarily shares +the buffer between process and network stack. Unlike with copying, the +process cannot immediately overwrite the buffer after system call +return without possibly modifying the data in flight. Kernel integrity +is not affected, but a buggy program can possibly corrupt its own data +stream. + +The kernel returns a notification when it is safe to modify data. +Converting an existing application to MSG_ZEROCOPY is not always as +trivial as just passing the flag, then. + + +More Info +--------- + +Much of this document was derived from a longer paper presented at +netdev 2.1. For more in-depth information see that paper and talk, +the excellent reporting over at LWN.net or read the original code. + + paper, slides, video + https://netdevconf.org/2.1/session.html?debruijn + + LWN article + https://lwn.net/Articles/726917/ + + patchset + [PATCH net-next v4 0/9] socket sendmsg MSG_ZEROCOPY + http://lkml.kernel.org/r/20170803202945.70750-1-willemdebruijn.kernel@gmail.com + + +Interface +========= + +Passing the MSG_ZEROCOPY flag is the most obvious step to enable copy +avoidance, but not the only one. + +Socket Setup +------------ + +The kernel is permissive when applications pass undefined flags to the +send system call. By default it simply ignores these. To avoid enabling +copy avoidance mode for legacy processes that accidentally already pass +this flag, a process must first signal intent by setting a socket option: + +:: + + if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one))) + error(1, errno, "setsockopt zerocopy"); + + +Transmission +------------ + +The change to send (or sendto, sendmsg, sendmmsg) itself is trivial. +Pass the new flag. + +:: + + ret = send(fd, buf, sizeof(buf), MSG_ZEROCOPY); + +A zerocopy failure will return -1 with errno ENOBUFS. This happens if +the socket option was not set, the socket exceeds its optmem limit or +the user exceeds its ulimit on locked pages. + + +Mixing copy avoidance and copying +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Many workloads have a mixture of large and small buffers. Because copy +avoidance is more expensive than copying for small packets, the +feature is implemented as a flag. It is safe to mix calls with the flag +with those without. + + +Notifications +------------- + +The kernel has to notify the process when it is safe to reuse a +previously passed buffer. It queues completion notifications on the +socket error queue, akin to the transmit timestamping interface. + +The notification itself is a simple scalar value. Each socket +maintains an internal unsigned 32-bit counter. Each send call with +MSG_ZEROCOPY that successfully sends data increments the counter. The +counter is not incremented on failure or if called with length zero. +The counter counts system call invocations, not bytes. It wraps after +UINT_MAX calls. + + +Notification Reception +~~~~~~~~~~~~~~~~~~~~~~ + +The below snippet demonstrates the API. In the simplest case, each +send syscall is followed by a poll and recvmsg on the error queue. + +Reading from the error queue is always a non-blocking operation. The +poll call is there to block until an error is outstanding. It will set +POLLERR in its output flags. That flag does not have to be set in the +events field. Errors are signaled unconditionally. + +:: + + pfd.fd = fd; + pfd.events = 0; + if (poll(&pfd, 1, -1) != 1 || pfd.revents & POLLERR == 0) + error(1, errno, "poll"); + + ret = recvmsg(fd, &msg, MSG_ERRQUEUE); + if (ret == -1) + error(1, errno, "recvmsg"); + + read_notification(msg); + +The example is for demonstration purpose only. In practice, it is more +efficient to not wait for notifications, but read without blocking +every couple of send calls. + +Notifications can be processed out of order with other operations on +the socket. A socket that has an error queued would normally block +other operations until the error is read. Zerocopy notifications have +a zero error code, however, to not block send and recv calls. + + +Notification Batching +~~~~~~~~~~~~~~~~~~~~~ + +Multiple outstanding packets can be read at once using the recvmmsg +call. This is often not needed. In each message the kernel returns not +a single value, but a range. It coalesces consecutive notifications +while one is outstanding for reception on the error queue. + +When a new notification is about to be queued, it checks whether the +new value extends the range of the notification at the tail of the +queue. If so, it drops the new notification packet and instead increases +the range upper value of the outstanding notification. + +For protocols that acknowledge data in-order, like TCP, each +notification can be squashed into the previous one, so that no more +than one notification is outstanding at any one point. + +Ordered delivery is the common case, but not guaranteed. Notifications +may arrive out of order on retransmission and socket teardown. + + +Notification Parsing +~~~~~~~~~~~~~~~~~~~~ + +The below snippet demonstrates how to parse the control message: the +read_notification() call in the previous snippet. A notification +is encoded in the standard error format, sock_extended_err. + +The level and type fields in the control data are protocol family +specific, IP_RECVERR or IPV6_RECVERR. + +Error origin is the new type SO_EE_ORIGIN_ZEROCOPY. ee_errno is zero, +as explained before, to avoid blocking read and write system calls on +the socket. + +The 32-bit notification range is encoded as [ee_info, ee_data]. This +range is inclusive. Other fields in the struct must be treated as +undefined, bar for ee_code, as discussed below. + +:: + + struct sock_extended_err *serr; + struct cmsghdr *cm; + + cm = CMSG_FIRSTHDR(msg); + if (cm->cmsg_level != SOL_IP && + cm->cmsg_type != IP_RECVERR) + error(1, 0, "cmsg"); + + serr = (void *) CMSG_DATA(cm); + if (serr->ee_errno != 0 || + serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) + error(1, 0, "serr"); + + printf("completed: %u..%u\n", serr->ee_info, serr->ee_data); + + +Deferred copies +~~~~~~~~~~~~~~~ + +Passing flag MSG_ZEROCOPY is a hint to the kernel to apply copy +avoidance, and a contract that the kernel will queue a completion +notification. It is not a guarantee that the copy is elided. + +Copy avoidance is not always feasible. Devices that do not support +scatter-gather I/O cannot send packets made up of kernel generated +protocol headers plus zerocopy user data. A packet may need to be +converted to a private copy of data deep in the stack, say to compute +a checksum. + +In all these cases, the kernel returns a completion notification when +it releases its hold on the shared pages. That notification may arrive +before the (copied) data is fully transmitted. A zerocopy completion +notification is not a transmit completion notification, therefore. + +Deferred copies can be more expensive than a copy immediately in the +system call, if the data is no longer warm in the cache. The process +also incurs notification processing cost for no benefit. For this +reason, the kernel signals if data was completed with a copy, by +setting flag SO_EE_CODE_ZEROCOPY_COPIED in field ee_code on return. +A process may use this signal to stop passing flag MSG_ZEROCOPY on +subsequent requests on the same socket. + + +Implementation +============== + +Loopback +-------- + +Data sent to local sockets can be queued indefinitely if the receive +process does not read its socket. Unbound notification latency is not +acceptable. For this reason all packets generated with MSG_ZEROCOPY +that are looped to a local socket will incur a deferred copy. This +includes looping onto packet sockets (e.g., tcpdump) and tun devices. + + +Testing +======= + +More realistic example code can be found in the kernel source under +tools/testing/selftests/net/msg_zerocopy.c. + +Be cognizant of the loopback constraint. The test can be run between +a pair of hosts. But if run between a local pair of processes, for +instance when run with msg_zerocopy.sh between a veth pair across +namespaces, the test will not show any improvement. For testing, the +loopback restriction can be temporarily relaxed by making +skb_orphan_frags_rx identical to skb_orphan_frags. diff --git a/Documentation/networking/netdev-FAQ.txt b/Documentation/networking/netdev-FAQ.txt index 247a30ba8e17..cfc66ea72329 100644 --- a/Documentation/networking/netdev-FAQ.txt +++ b/Documentation/networking/netdev-FAQ.txt @@ -111,6 +111,14 @@ A: Generally speaking, the patches get triaged quickly (in less than 48h). patch is a good way to ensure your patch is ignored or pushed to the bottom of the priority list. +Q: I submitted multiple versions of the patch series, should I directly update + patchwork for the previous versions of these patch series? + +A: No, please don't interfere with the patch status on patchwork, leave it to + the maintainer to figure out what is the most recent and current version that + should be applied. If there is any doubt, the maintainer will reply and ask + what should be done. + Q: How can I tell what patches are queued up for backporting to the various stable releases? diff --git a/Documentation/networking/netvsc.txt b/Documentation/networking/netvsc.txt new file mode 100644 index 000000000000..93560fb1170a --- /dev/null +++ b/Documentation/networking/netvsc.txt @@ -0,0 +1,75 @@ +Hyper-V network driver +====================== + +Compatibility +============= + +This driver is compatible with Windows Server 2012 R2, 2016 and +Windows 10. + +Features +======== + + Checksum offload + ---------------- + The netvsc driver supports checksum offload as long as the + Hyper-V host version does. Windows Server 2016 and Azure + support checksum offload for TCP and UDP for both IPv4 and + IPv6. Windows Server 2012 only supports checksum offload for TCP. + + Receive Side Scaling + -------------------- + Hyper-V supports receive side scaling. For TCP, packets are + distributed among available queues based on IP address and port + number. + + For UDP, we can switch UDP hash level between L3 and L4 by ethtool + command. UDP over IPv4 and v6 can be set differently. The default + hash level is L4. We currently only allow switching TX hash level + from within the guests. + + On Azure, fragmented UDP packets have high loss rate with L4 + hashing. Using L3 hashing is recommended in this case. + + For example, for UDP over IPv4 on eth0: + To include UDP port numbers in hashing: + ethtool -N eth0 rx-flow-hash udp4 sdfn + To exclude UDP port numbers in hashing: + ethtool -N eth0 rx-flow-hash udp4 sd + To show UDP hash level: + ethtool -n eth0 rx-flow-hash udp4 + + Generic Receive Offload, aka GRO + -------------------------------- + The driver supports GRO and it is enabled by default. GRO coalesces + like packets and significantly reduces CPU usage under heavy Rx + load. + + SR-IOV support + -------------- + Hyper-V supports SR-IOV as a hardware acceleration option. If SR-IOV + is enabled in both the vSwitch and the guest configuration, then the + Virtual Function (VF) device is passed to the guest as a PCI + device. In this case, both a synthetic (netvsc) and VF device are + visible in the guest OS and both NIC's have the same MAC address. + + The VF is enslaved by netvsc device. The netvsc driver will transparently + switch the data path to the VF when it is available and up. + Network state (addresses, firewall, etc) should be applied only to the + netvsc device; the slave device should not be accessed directly in + most cases. The exceptions are if some special queue discipline or + flow direction is desired, these should be applied directly to the + VF slave device. + + Receive Buffer + -------------- + Packets are received into a receive area which is created when device + is probed. The receive area is broken into MTU sized chunks and each may + contain one or more packets. The number of receive sections may be changed + via ethtool Rx ring parameters. + + There is a similar send buffer which is used to aggregate packets for sending. + The send area is broken into chunks of 6144 bytes, each of section may + contain one or more packets. The send buffer is an optimization, the driver + will use slower method to handle very large packets or if the send buffer + area is exhausted. diff --git a/Documentation/networking/nf_conntrack-sysctl.txt b/Documentation/networking/nf_conntrack-sysctl.txt index 497d668288f9..433b6724797a 100644 --- a/Documentation/networking/nf_conntrack-sysctl.txt +++ b/Documentation/networking/nf_conntrack-sysctl.txt @@ -96,17 +96,6 @@ nf_conntrack_max - INTEGER Size of connection tracking table. Default value is nf_conntrack_buckets value * 4. -nf_conntrack_default_on - BOOLEAN - 0 - don't register conntrack in new net namespaces - 1 - register conntrack in new net namespaces (default) - - This controls wheter newly created network namespaces have connection - tracking enabled by default. It will be enabled automatically - regardless of this setting if the new net namespace requires - connection tracking, e.g. when NAT rules are created. - This setting is only visible in initial user namespace, it has no - effect on existing namespaces. - nf_conntrack_tcp_be_liberal - BOOLEAN 0 - disabled (default) not 0 - enabled diff --git a/Documentation/networking/rmnet.txt b/Documentation/networking/rmnet.txt new file mode 100644 index 000000000000..6b341eaf2062 --- /dev/null +++ b/Documentation/networking/rmnet.txt @@ -0,0 +1,82 @@ +1. Introduction + +rmnet driver is used for supporting the Multiplexing and aggregation +Protocol (MAP). This protocol is used by all recent chipsets using Qualcomm +Technologies, Inc. modems. + +This driver can be used to register onto any physical network device in +IP mode. Physical transports include USB, HSIC, PCIe and IP accelerator. + +Multiplexing allows for creation of logical netdevices (rmnet devices) to +handle multiple private data networks (PDN) like a default internet, tethering, +multimedia messaging service (MMS) or IP media subsystem (IMS). Hardware sends +packets with MAP headers to rmnet. Based on the multiplexer id, rmnet +routes to the appropriate PDN after removing the MAP header. + +Aggregation is required to achieve high data rates. This involves hardware +sending aggregated bunch of MAP frames. rmnet driver will de-aggregate +these MAP frames and send them to appropriate PDN's. + +2. Packet format + +a. MAP packet (data / control) + +MAP header has the same endianness of the IP packet. + +Packet format - + +Bit 0 1 2-7 8 - 15 16 - 31 +Function Command / Data Reserved Pad Multiplexer ID Payload length +Bit 32 - x +Function Raw Bytes + +Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command +or data packet. Control packet is used for transport level flow control. Data +packets are standard IP packets. + +Reserved bits are usually zeroed out and to be ignored by receiver. + +Padding is number of bytes to be added for 4 byte alignment if required by +hardware. + +Multiplexer ID is to indicate the PDN on which data has to be sent. + +Payload length includes the padding length but does not include MAP header +length. + +b. MAP packet (command specific) + +Bit 0 1 2-7 8 - 15 16 - 31 +Function Command Reserved Pad Multiplexer ID Payload length +Bit 32 - 39 40 - 45 46 - 47 48 - 63 +Function Command name Reserved Command Type Reserved +Bit 64 - 95 +Function Transaction ID +Bit 96 - 127 +Function Command data + +Command 1 indicates disabling flow while 2 is enabling flow + +Command types - +0 for MAP command request +1 is to acknowledge the receipt of a command +2 is for unsupported commands +3 is for error during processing of commands + +c. Aggregation + +Aggregation is multiple MAP packets (can be data or command) delivered to +rmnet in a single linear skb. rmnet will process the individual +packets and either ACK the MAP command or deliver the IP packet to the +network stack as needed + +MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding.... +MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad... + +3. Userspace configuration + +rmnet userspace configuration is done through netlink library librmnetctl +and command line utility rmnetcli. Utility is hosted in codeaurora forum git. +The driver uses rtnl_link_ops for communication. + +https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/dataservices/tree/rmnetctl diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt index 8c70ba5dee4d..810620153a44 100644 --- a/Documentation/networking/rxrpc.txt +++ b/Documentation/networking/rxrpc.txt @@ -818,10 +818,15 @@ The kernel interface functions are as follows: (*) Send data through a call. + typedef void (*rxrpc_notify_end_tx_t)(struct sock *sk, + unsigned long user_call_ID, + struct sk_buff *skb); + int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call, struct msghdr *msg, - size_t len); + size_t len, + rxrpc_notify_end_tx_t notify_end_rx); This is used to supply either the request part of a client call or the reply part of a server call. msg.msg_iovlen and msg.msg_iov specify the @@ -832,6 +837,11 @@ The kernel interface functions are as follows: The msg must not specify a destination address, control data or any flags other than MSG_MORE. len is the total amount of data to transmit. + notify_end_rx can be NULL or it can be used to specify a function to be + called when the call changes state to end the Tx phase. This function is + called with the call-state spinlock held to prevent any reply or final ACK + from being delivered first. + (*) Receive data from a call. int rxrpc_kernel_recv_data(struct socket *sock, @@ -965,6 +975,51 @@ The kernel interface functions are as follows: size should be set when the call is begun. tx_total_len may not be less than zero. + (*) Check to see the completion state of a call so that the caller can assess + whether it needs to be retried. + + enum rxrpc_call_completion { + RXRPC_CALL_SUCCEEDED, + RXRPC_CALL_REMOTELY_ABORTED, + RXRPC_CALL_LOCALLY_ABORTED, + RXRPC_CALL_LOCAL_ERROR, + RXRPC_CALL_NETWORK_ERROR, + }; + + int rxrpc_kernel_check_call(struct socket *sock, struct rxrpc_call *call, + enum rxrpc_call_completion *_compl, + u32 *_abort_code); + + On return, -EINPROGRESS will be returned if the call is still ongoing; if + it is finished, *_compl will be set to indicate the manner of completion, + *_abort_code will be set to any abort code that occurred. 0 will be + returned on a successful completion, -ECONNABORTED will be returned if the + client failed due to a remote abort and anything else will return an + appropriate error code. + + The caller should look at this information to decide if it's worth + retrying the call. + + (*) Retry a client call. + + int rxrpc_kernel_retry_call(struct socket *sock, + struct rxrpc_call *call, + struct sockaddr_rxrpc *srx, + struct key *key); + + This attempts to partially reinitialise a call and submit it again whilst + reusing the original call's Tx queue to avoid the need to repackage and + re-encrypt the data to be sent. call indicates the call to retry, srx the + new address to send it to and key the encryption key to use for signing or + encrypting the packets. + + For this to work, the first Tx data packet must still be in the transmit + queue, and currently this is only permitted for local and network errors + and the call must not have been aborted. Any partially constructed Tx + packet is left as is and can continue being filled afterwards. + + It returns 0 if the call was requeued and an error otherwise. + ======================= CONFIGURABLE PARAMETERS diff --git a/Documentation/networking/strparser.txt b/Documentation/networking/strparser.txt index a0bf573dfa61..13081b3decef 100644 --- a/Documentation/networking/strparser.txt +++ b/Documentation/networking/strparser.txt @@ -1,45 +1,107 @@ -Stream Parser -------------- +Stream Parser (strparser) + +Introduction +============ The stream parser (strparser) is a utility that parses messages of an -application layer protocol running over a TCP connection. The stream +application layer protocol running over a data stream. The stream parser works in conjunction with an upper layer in the kernel to provide kernel support for application layer messages. For instance, Kernel Connection Multiplexor (KCM) uses the Stream Parser to parse messages using a BPF program. +The strparser works in one of two modes: receive callback or general +mode. + +In receive callback mode, the strparser is called from the data_ready +callback of a TCP socket. Messages are parsed and delivered as they are +received on the socket. + +In general mode, a sequence of skbs are fed to strparser from an +outside source. Message are parsed and delivered as the sequence is +processed. This modes allows strparser to be applied to arbitrary +streams of data. + Interface ---------- +========= The API includes a context structure, a set of callbacks, utility -functions, and a data_ready function. The callbacks include -a parse_msg function that is called to perform parsing (e.g. -BPF parsing in case of KCM), and a rcv_msg function that is called -when a full message has been completed. +functions, and a data_ready function for receive callback mode. The +callbacks include a parse_msg function that is called to perform +parsing (e.g. BPF parsing in case of KCM), and a rcv_msg function +that is called when a full message has been completed. -A stream parser can be instantiated for a TCP connection. This is done -by: +Functions +========= -strp_init(struct strparser *strp, struct sock *csk, - struct strp_callbacks *cb) +strp_init(struct strparser *strp, struct sock *sk, + const struct strp_callbacks *cb) -strp is a struct of type strparser that is allocated by the upper layer. -csk is the TCP socket associated with the stream parser. Callbacks are -called by the stream parser. + Called to initialize a stream parser. strp is a struct of type + strparser that is allocated by the upper layer. sk is the TCP + socket associated with the stream parser for use with receive + callback mode; in general mode this is set to NULL. Callbacks + are called by the stream parser (the callbacks are listed below). + +void strp_pause(struct strparser *strp) + + Temporarily pause a stream parser. Message parsing is suspended + and no new messages are delivered to the upper layer. + +void strp_pause(struct strparser *strp) + + Unpause a paused stream parser. + +void strp_stop(struct strparser *strp); + + strp_stop is called to completely stop stream parser operations. + This is called internally when the stream parser encounters an + error, and it is called from the upper layer to stop parsing + operations. + +void strp_done(struct strparser *strp); + + strp_done is called to release any resources held by the stream + parser instance. This must be called after the stream processor + has been stopped. + +int strp_process(struct strparser *strp, struct sk_buff *orig_skb, + unsigned int orig_offset, size_t orig_len, + size_t max_msg_size, long timeo) + + strp_process is called in general mode for a stream parser to + parse an sk_buff. The number of bytes processed or a negative + error number is returned. Note that strp_process does not + consume the sk_buff. max_msg_size is maximum size the stream + parser will parse. timeo is timeout for completing a message. + +void strp_data_ready(struct strparser *strp); + + The upper layer calls strp_tcp_data_ready when data is ready on + the lower socket for strparser to process. This should be called + from a data_ready callback that is set on the socket. Note that + maximum messages size is the limit of the receive socket + buffer and message timeout is the receive timeout for the socket. + +void strp_check_rcv(struct strparser *strp); + + strp_check_rcv is called to check for new messages on the socket. + This is normally called at initialization of a stream parser + instance or after strp_unpause. Callbacks ---------- +========= -There are four callbacks: +There are six callbacks: int (*parse_msg)(struct strparser *strp, struct sk_buff *skb); parse_msg is called to determine the length of the next message in the stream. The upper layer must implement this function. It should parse the sk_buff as containing the headers for the - next application layer messages in the stream. + next application layer message in the stream. - The skb->cb in the input skb is a struct strp_rx_msg. Only + The skb->cb in the input skb is a struct strp_msg. Only the offset field is relevant in parse_msg and gives the offset where the message starts in the skb. @@ -50,26 +112,41 @@ int (*parse_msg)(struct strparser *strp, struct sk_buff *skb); -ESTRPIPE : current message should not be processed by the kernel, return control of the socket to userspace which can proceed to read the messages itself - other < 0 : Error is parsing, give control back to userspace + other < 0 : Error in parsing, give control back to userspace assuming that synchronization is lost and the stream is unrecoverable (application expected to close TCP socket) In the case that an error is returned (return value is less than - zero) the stream parser will set the error on TCP socket and wake - it up. If parse_msg returned -ESTRPIPE and the stream parser had - previously read some bytes for the current message, then the error - set on the attached socket is ENODATA since the stream is - unrecoverable in that case. + zero) and the parser is in receive callback mode, then it will set + the error on TCP socket and wake it up. If parse_msg returned + -ESTRPIPE and the stream parser had previously read some bytes for + the current message, then the error set on the attached socket is + ENODATA since the stream is unrecoverable in that case. + +void (*lock)(struct strparser *strp) + + The lock callback is called to lock the strp structure when + the strparser is performing an asynchronous operation (such as + processing a timeout). In receive callback mode the default + function is to lock_sock for the associated socket. In general + mode the callback must be set appropriately. + +void (*unlock)(struct strparser *strp) + + The unlock callback is called to release the lock obtained + by the lock callback. In receive callback mode the default + function is release_sock for the associated socket. In general + mode the callback must be set appropriately. void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb); rcv_msg is called when a full message has been received and is queued. The callee must consume the sk_buff; it can call strp_pause to prevent any further messages from being - received in rcv_msg (see strp_pause below). This callback + received in rcv_msg (see strp_pause above). This callback must be set. - The skb->cb in the input skb is a struct strp_rx_msg. This + The skb->cb in the input skb is a struct strp_msg. This struct contains two fields: offset and full_len. Offset is where the message starts in the skb, and full_len is the the length of the message. skb->len - offset may be greater @@ -78,59 +155,53 @@ void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb); int (*read_sock_done)(struct strparser *strp, int err); read_sock_done is called when the stream parser is done reading - the TCP socket. The stream parser may read multiple messages - in a loop and this function allows cleanup to occur when existing - the loop. If the callback is not set (NULL in strp_init) a - default function is used. + the TCP socket in receive callback mode. The stream parser may + read multiple messages in a loop and this function allows cleanup + to occur when exiting the loop. If the callback is not set (NULL + in strp_init) a default function is used. void (*abort_parser)(struct strparser *strp, int err); This function is called when stream parser encounters an error - in parsing. The default function stops the stream parser for the - TCP socket and sets the error in the socket. The default function - can be changed by setting the callback to non-NULL in strp_init. - -Functions ---------- - -The upper layer calls strp_tcp_data_ready when data is ready on the lower -socket for strparser to process. This should be called from a data_ready -callback that is set on the socket. - -strp_stop is called to completely stop stream parser operations. This -is called internally when the stream parser encounters an error, and -it is called from the upper layer when unattaching a TCP socket. - -strp_done is called to unattach the stream parser from the TCP socket. -This must be called after the stream processor has be stopped. - -strp_check_rcv is called to check for new messages on the socket. This -is normally called at initialization of the a stream parser instance -of after strp_unpause. + in parsing. The default function stops the stream parser and + sets the error in the socket if the parser is in receive callback + mode. The default function can be changed by setting the callback + to non-NULL in strp_init. Statistics ----------- +========== -Various counters are kept for each stream parser for a TCP socket. -These are in the strp_stats structure. strp_aggr_stats is a convenience -structure for accumulating statistics for multiple stream parser -instances. save_strp_stats and aggregate_strp_stats are helper functions -to save and aggregate statistics. +Various counters are kept for each stream parser instance. These are in +the strp_stats structure. strp_aggr_stats is a convenience structure for +accumulating statistics for multiple stream parser instances. +save_strp_stats and aggregate_strp_stats are helper functions to save +and aggregate statistics. Message assembly limits ------------------------ +======================= The stream parser provide mechanisms to limit the resources consumed by message assembly. -A timer is set when assembly starts for a new message. The message -timeout is taken from rcvtime for the associated TCP socket. If the -timer fires before assembly completes the stream parser is aborted -and the ETIMEDOUT error is set on the TCP socket. +A timer is set when assembly starts for a new message. In receive +callback mode the message timeout is taken from rcvtime for the +associated TCP socket. In general mode, the timeout is passed as an +argument in strp_process. If the timer fires before assembly completes +the stream parser is aborted and the ETIMEDOUT error is set on the TCP +socket if in receive callback mode. + +In receive callback mode, message length is limited to the receive +buffer size of the associated TCP socket. If the length returned by +parse_msg is greater than the socket buffer size then the stream parser +is aborted with EMSGSIZE error set on the TCP socket. Note that this +makes the maximum size of receive skbuffs for a socket with a stream +parser to be 2*sk_rcvbuf of the TCP socket. + +In general mode the message length limit is passed in as an argument +to strp_process. + +Author +====== + +Tom Herbert (tom@quantonium.net) -Message length is limited to the receive buffer size of the associated -TCP socket. If the length returned by parse_msg is greater than -the socket buffer size then the stream parser is aborted with -EMSGSIZE error set on the TCP socket. Note that this makes the -maximum size of receive skbuffs for a socket with a stream parser -to be 2*sk_rcvbuf of the TCP socket. diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt index 5e40e1f68873..82236a17b5e6 100644 --- a/Documentation/networking/switchdev.txt +++ b/Documentation/networking/switchdev.txt @@ -13,42 +13,42 @@ an example setup using a data-center-class switch ASIC chip. Other setups with SR-IOV or soft switches, such as OVS, are possible. -                             User-space tools + User-space tools -       user space                   | -      +-------------------------------------------------------------------+ -       kernel                       | Netlink -                                    | -                     +--------------+-------------------------------+ -                     |         Network stack                        | -                     |           (Linux)                            | -                     |                                              | -                     +----------------------------------------------+ + user space | + +-------------------------------------------------------------------+ + kernel | Netlink + | + +--------------+-------------------------------+ + | Network stack | + | (Linux) | + | | + +----------------------------------------------+ sw1p2 sw1p4 sw1p6 -                      sw1p1  + sw1p3 +  sw1p5 +         eth1 -                        +    |    +    |    +    |            + -                        |    |    |    |    |    |            | -                     +--+----+----+----+-+--+----+---+  +-----+-----+ -                     |         Switch driver         |  |    mgmt   | -                     |        (this document)        |  |   driver  | -                     |                               |  |           | -                     +--------------+----------------+  +-----------+ -                                    | -       kernel                       | HW bus (eg PCI) -      +-------------------------------------------------------------------+ -       hardware                     | -                     +--------------+---+------------+ -                     |         Switch device (sw1)   | -                     |  +----+                       +--------+ -                     |  |    v offloaded data path   | mgmt port -                     |  |    |                       | -                     +--|----|----+----+----+----+---+ -                        |    |    |    |    |    | -                        +    +    +    +    +    + -                       p1   p2   p3   p4   p5   p6 + sw1p1 + sw1p3 + sw1p5 + eth1 + + | + | + | + + | | | | | | | + +--+----+----+----+----+----+---+ +-----+-----+ + | Switch driver | | mgmt | + | (this document) | | driver | + | | | | + +--------------+----------------+ +-----------+ + | + kernel | HW bus (eg PCI) + +-------------------------------------------------------------------+ + hardware | + +--------------+----------------+ + | Switch device (sw1) | + | +----+ +--------+ + | | v offloaded data path | mgmt port + | | | | + +--|----|----+----+----+----+---+ + | | | | | | + + + + + + + + p1 p2 p3 p4 p5 p6 -                             front-panel ports + front-panel ports Fig 1. diff --git a/Documentation/nvmem/nvmem.txt b/Documentation/nvmem/nvmem.txt index dbd40d879239..8d8d8f58f96f 100644 --- a/Documentation/nvmem/nvmem.txt +++ b/Documentation/nvmem/nvmem.txt @@ -112,7 +112,7 @@ take nvmem_device as parameter. 5. Releasing a reference to the NVMEM ===================================== -When a consumers no longer needs the NVMEM, it has to release the reference +When a consumer no longer needs the NVMEM, it has to release the reference to the NVMEM it has obtained using the APIs mentioned in the above section. The NVMEM framework provides 2 APIs to release a reference to the NVMEM. diff --git a/Documentation/power/states.txt b/Documentation/power/states.txt deleted file mode 100644 index bc4548245a24..000000000000 --- a/Documentation/power/states.txt +++ /dev/null @@ -1,125 +0,0 @@ -System Power Management Sleep States - -(C) 2014 Intel Corp., Rafael J. Wysocki - -The kernel supports up to four system sleep states generically, although three -of them depend on the platform support code to implement the low-level details -for each state. - -The states are represented by strings that can be read or written to the -/sys/power/state file. Those strings may be "mem", "standby", "freeze" and -"disk", where the last three always represent Power-On Suspend (if supported), -Suspend-To-Idle and hibernation (Suspend-To-Disk), respectively. - -The meaning of the "mem" string is controlled by the /sys/power/mem_sleep file. -It contains strings representing the available modes of system suspend that may -be triggered by writing "mem" to /sys/power/state. These modes are "s2idle" -(Suspend-To-Idle), "shallow" (Power-On Suspend) and "deep" (Suspend-To-RAM). -The "s2idle" mode is always available, while the other ones are only available -if supported by the platform (if not supported, the strings representing them -are not present in /sys/power/mem_sleep). The string representing the suspend -mode to be used subsequently is enclosed in square brackets. Writing one of -the other strings present in /sys/power/mem_sleep to it causes the suspend mode -to be used subsequently to change to the one represented by that string. - -Consequently, there are two ways to cause the system to go into the -Suspend-To-Idle sleep state. The first one is to write "freeze" directly to -/sys/power/state. The second one is to write "s2idle" to /sys/power/mem_sleep -and then to write "mem" to /sys/power/state. Similarly, there are two ways -to cause the system to go into the Power-On Suspend sleep state (the strings to -write to the control files in that case are "standby" or "shallow" and "mem", -respectively) if that state is supported by the platform. In turn, there is -only one way to cause the system to go into the Suspend-To-RAM state (write -"deep" into /sys/power/mem_sleep and "mem" into /sys/power/state). - -The default suspend mode (ie. the one to be used without writing anything into -/sys/power/mem_sleep) is either "deep" (if Suspend-To-RAM is supported) or -"s2idle", but it can be overridden by the value of the "mem_sleep_default" -parameter in the kernel command line. - -The properties of all of the sleep states are described below. - - -State: Suspend-To-Idle -ACPI state: S0 -Label: "s2idle" ("freeze") - -This state is a generic, pure software, light-weight, system sleep state. -It allows more energy to be saved relative to runtime idle by freezing user -space and putting all I/O devices into low-power states (possibly -lower-power than available at run time), such that the processors can -spend more time in their idle states. - -This state can be used for platforms without Power-On Suspend/Suspend-to-RAM -support, or it can be used in addition to Suspend-to-RAM to provide reduced -resume latency. It is always supported. - - -State: Standby / Power-On Suspend -ACPI State: S1 -Label: "shallow" ("standby") - -This state, if supported, offers moderate, though real, power savings, while -providing a relatively low-latency transition back to a working system. No -operating state is lost (the CPU retains power), so the system easily starts up -again where it left off. - -In addition to freezing user space and putting all I/O devices into low-power -states, which is done for Suspend-To-Idle too, nonboot CPUs are taken offline -and all low-level system functions are suspended during transitions into this -state. For this reason, it should allow more energy to be saved relative to -Suspend-To-Idle, but the resume latency will generally be greater than for that -state. - - -State: Suspend-to-RAM -ACPI State: S3 -Label: "deep" - -This state, if supported, offers significant power savings as everything in the -system is put into a low-power state, except for memory, which should be placed -into the self-refresh mode to retain its contents. All of the steps carried out -when entering Power-On Suspend are also carried out during transitions to STR. -Additional operations may take place depending on the platform capabilities. In -particular, on ACPI systems the kernel passes control to the BIOS (platform -firmware) as the last step during STR transitions and that usually results in -powering down some more low-level components that aren't directly controlled by -the kernel. - -System and device state is saved and kept in memory. All devices are suspended -and put into low-power states. In many cases, all peripheral buses lose power -when entering STR, so devices must be able to handle the transition back to the -"on" state. - -For at least ACPI, STR requires some minimal boot-strapping code to resume the -system from it. This may be the case on other platforms too. - - -State: Suspend-to-disk -ACPI State: S4 -Label: "disk" - -This state offers the greatest power savings, and can be used even in -the absence of low-level platform support for power management. This -state operates similarly to Suspend-to-RAM, but includes a final step -of writing memory contents to disk. On resume, this is read and memory -is restored to its pre-suspend state. - -STD can be handled by the firmware or the kernel. If it is handled by -the firmware, it usually requires a dedicated partition that must be -setup via another operating system for it to use. Despite the -inconvenience, this method requires minimal work by the kernel, since -the firmware will also handle restoring memory contents on resume. - -For suspend-to-disk, a mechanism called 'swsusp' (Swap Suspend) is used -to write memory contents to free swap space. swsusp has some restrictive -requirements, but should work in most cases. Some, albeit outdated, -documentation can be found in Documentation/power/swsusp.txt. -Alternatively, userspace can do most of the actual suspend to disk work, -see userland-swsusp.txt. - -Once memory state is written to disk, the system may either enter a -low-power state (like ACPI S4), or it may simply power down. Powering -down offers greater savings, and allows this mechanism to work on any -system. However, entering a real low-power state allows the user to -trigger wake up events (e.g. pressing a key or opening a laptop lid). diff --git a/Documentation/pps/pps.txt b/Documentation/pps/pps.txt index 1fdbd5447216..99f5d8c4c652 100644 --- a/Documentation/pps/pps.txt +++ b/Documentation/pps/pps.txt @@ -48,12 +48,12 @@ problem: time_pps_create(). This implies that the source has a /dev/... entry. This assumption is -ok for the serial and parallel port, where you can do something +OK for the serial and parallel port, where you can do something useful besides(!) the gathering of timestamps as it is the central -task for a PPS-API. But this assumption does not work for a single +task for a PPS API. But this assumption does not work for a single purpose GPIO line. In this case even basic file-related functionality (like read() and write()) makes no sense at all and should not be a -precondition for the use of a PPS-API. +precondition for the use of a PPS API. The problem can be simply solved if you consider that a PPS source is not always connected with a GPS data source. @@ -88,13 +88,13 @@ Coding example -------------- To register a PPS source into the kernel you should define a struct -pps_source_info_s as follows: +pps_source_info as follows: static struct pps_source_info pps_ktimer_info = { .name = "ktimer", .path = "", - .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | \ - PPS_ECHOASSERT | \ + .mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | + PPS_ECHOASSERT | PPS_CANWAIT | PPS_TSFMT_TSPEC, .echo = pps_ktimer_echo, .owner = THIS_MODULE, @@ -108,13 +108,13 @@ initialization routine as follows: The pps_register_source() prototype is: - int pps_register_source(struct pps_source_info_s *info, int default_params) + int pps_register_source(struct pps_source_info *info, int default_params) where "info" is a pointer to a structure that describes a particular PPS source, "default_params" tells the system what the initial default parameters for the device should be (it is obvious that these parameters must be a subset of ones defined in the struct -pps_source_info_s which describe the capabilities of the driver). +pps_source_info which describe the capabilities of the driver). Once you have registered a new PPS source into the system you can signal an assert event (for example in the interrupt handler routine) @@ -142,8 +142,10 @@ If the SYSFS filesystem is enabled in the kernel it provides a new class: Every directory is the ID of a PPS sources defined in the system and inside you find several files: - $ ls /sys/class/pps/pps0/ - assert clear echo mode name path subsystem@ uevent + $ ls -F /sys/class/pps/pps0/ + assert dev mode path subsystem@ + clear echo name power/ uevent + Inside each "assert" and "clear" file you can find the timestamp and a sequence number: @@ -154,32 +156,32 @@ sequence number: Where before the "#" is the timestamp in seconds; after it is the sequence number. Other files are: -* echo: reports if the PPS source has an echo function or not; + * echo: reports if the PPS source has an echo function or not; -* mode: reports available PPS functioning modes; + * mode: reports available PPS functioning modes; -* name: reports the PPS source's name; + * name: reports the PPS source's name; -* path: reports the PPS source's device path, that is the device the - PPS source is connected to (if it exists). + * path: reports the PPS source's device path, that is the device the + PPS source is connected to (if it exists). Testing the PPS support ----------------------- In order to test the PPS support even without specific hardware you can use -the ktimer driver (see the client subsection in the PPS configuration menu) +the pps-ktimer driver (see the client subsection in the PPS configuration menu) and the userland tools available in your distribution's pps-tools package, -http://linuxpps.org , or https://github.com/ago/pps-tools . +http://linuxpps.org , or https://github.com/redlab-i/pps-tools. -Once you have enabled the compilation of ktimer just modprobe it (if +Once you have enabled the compilation of pps-ktimer just modprobe it (if not statically compiled): - # modprobe ktimer + # modprobe pps-ktimer and the run ppstest as follow: - $ ./ppstest /dev/pps0 + $ ./ppstest /dev/pps1 trying PPS source "/dev/pps1" found PPS source "/dev/pps1" ok, found 1 source(s), now start fetching data... @@ -187,7 +189,7 @@ and the run ppstest as follow: source 0 - assert 1186592700.388931295, sequence: 365 - clear 0.000000000, sequence: 0 source 0 - assert 1186592701.389032765, sequence: 366 - clear 0.000000000, sequence: 0 -Please, note that to compile userland programs you need the file timepps.h . +Please note that to compile userland programs, you need the file timepps.h. This is available in the pps-tools repository mentioned above. diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index 074670b98bac..361789df51ec 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -75,6 +75,16 @@ used when printing stack backtraces. The specifier takes into consideration the effect of compiler optimisations which may occur when tail-call``s are used and marked with the noreturn GCC attribute. +Examples:: + + printk("Going to call: %pF\n", gettimeofday); + printk("Going to call: %pF\n", p->func); + printk("%s: called from %pS\n", __func__, (void *)_RET_IP_); + printk("%s: called from %pS\n", __func__, + (void *)__builtin_return_address(0)); + printk("Faulted at %pS\n", (void *)regs->ip); + printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack); + Kernel Pointers =============== diff --git a/Documentation/process/applying-patches.rst b/Documentation/process/applying-patches.rst index a0d058cc6d25..dc2ddc345044 100644 --- a/Documentation/process/applying-patches.rst +++ b/Documentation/process/applying-patches.rst @@ -6,9 +6,6 @@ Applying Patches To The Linux Kernel Original by: Jesper Juhl, August 2005 -Last update: - 2016-09-14 - .. note:: This document is obsolete. In most cases, rather than using ``patch`` @@ -344,7 +341,7 @@ possible. This is a good branch to run for people who want to help out testing development kernels but do not want to run some of the really experimental -stuff (such people should see the sections about -git and -mm kernels below). +stuff (such people should see the sections about -next and -mm kernels below). The -rc patches are not incremental, they apply to a base 4.x kernel, just like the 4.x.y patches described above. The kernel version before the -rcN @@ -380,44 +377,6 @@ Here are 3 examples of how to apply these patches:: $ mv linux-4.7.3 linux-4.8-rc5 # rename the kernel source dir -The -git kernels -================ - -These are daily snapshots of Linus' kernel tree (managed in a git -repository, hence the name). - -These patches are usually released daily and represent the current state of -Linus's tree. They are more experimental than -rc kernels since they are -generated automatically without even a cursory glance to see if they are -sane. - --git patches are not incremental and apply either to a base 4.x kernel or -a base 4.x-rc kernel -- you can see which from their name. -A patch named 4.7-git1 applies to the 4.7 kernel source and a patch -named 4.8-rc3-git2 applies to the source of the 4.8-rc3 kernel. - -Here are some examples of how to apply these patches:: - - # moving from 4.7 to 4.7-git1 - - $ cd ~/linux-4.7 # change to the kernel source dir - $ patch -p1 < ../patch-4.7-git1 # apply the 4.7-git1 patch - $ cd .. - $ mv linux-4.7 linux-4.7-git1 # rename the kernel source dir - - # moving from 4.7-git1 to 4.8-rc2-git3 - - $ cd ~/linux-4.7-git1 # change to the kernel source dir - $ patch -p1 -R < ../patch-4.7-git1 # revert the 4.7-git1 patch - # we now have a 4.7 kernel - $ patch -p1 < ../patch-4.8-rc2 # apply the 4.8-rc2 patch - # the kernel is now 4.8-rc2 - $ patch -p1 < ../patch-4.8-rc2-git3 # apply the 4.8-rc2-git3 patch - # the kernel is now 4.8-rc2-git3 - $ cd .. - $ mv linux-4.7-git1 linux-4.8-rc2-git3 # rename source dir - - The -mm patches and the linux-next tree ======================================= diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst index adbb50ae5246..560beaef5a7c 100644 --- a/Documentation/process/changes.rst +++ b/Documentation/process/changes.rst @@ -53,7 +53,7 @@ mcelog 0.6 mcelog --version iptables 1.4.2 iptables -V openssl & libcrypto 1.0.0 openssl version bc 1.06.95 bc --version -Sphinx\ [#f1]_ 1.2 sphinx-build --version +Sphinx\ [#f1]_ 1.3 sphinx-build --version ====================== =============== ======================================== .. [#f1] Sphinx is needed only to build the Kernel documentation @@ -309,18 +309,8 @@ Kernel documentation Sphinx ------ -The ReST markups currently used by the Documentation/ files are meant to be -built with ``Sphinx`` version 1.2 or upper. If you're desiring to build -PDF outputs, it is recommended to use version 1.4.6. - -.. note:: - - Please notice that, for PDF and LaTeX output, you'll also need ``XeLaTeX`` - version 3.14159265. Depending on the distribution, you may also need to - install a series of ``texlive`` packages that provide the minimal set of - functionalities required for ``XeLaTex`` to work. For PDF output you'll also - need ``convert(1)`` from ImageMagick (https://www.imagemagick.org). - +Please see :ref:`sphinx_install` in ``Documentation/doc-guide/sphinx.rst`` +for details about Sphinx requirements. Getting updated software ======================== diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst index 82fc399fcd33..61e43cc3ed17 100644 --- a/Documentation/process/index.rst +++ b/Documentation/process/index.rst @@ -25,6 +25,7 @@ Below are the essential guides that every developer should read. submitting-patches coding-style email-clients + kernel-enforcement-statement Other guides to the community that are of interest to most developers are: diff --git a/Documentation/process/kernel-enforcement-statement.rst b/Documentation/process/kernel-enforcement-statement.rst new file mode 100644 index 000000000000..b3170671a1df --- /dev/null +++ b/Documentation/process/kernel-enforcement-statement.rst @@ -0,0 +1,157 @@ +Linux Kernel Enforcement Statement +---------------------------------- + +As developers of the Linux kernel, we have a keen interest in how our software +is used and how the license for our software is enforced. Compliance with the +reciprocal sharing obligations of GPL-2.0 is critical to the long-term +sustainability of our software and community. + +Although there is a right to enforce the separate copyright interests in the +contributions made to our community, we share an interest in ensuring that +individual enforcement actions are conducted in a manner that benefits our +community and do not have an unintended negative impact on the health and +growth of our software ecosystem. In order to deter unhelpful enforcement +actions, we agree that it is in the best interests of our development +community to undertake the following commitment to users of the Linux kernel +on behalf of ourselves and any successors to our copyright interests: + + Notwithstanding the termination provisions of the GPL-2.0, we agree that + it is in the best interests of our development community to adopt the + following provisions of GPL-3.0 as additional permissions under our + license with respect to any non-defensive assertion of rights under the + license. + + However, if you cease all violation of this License, then your license + from a particular copyright holder is reinstated (a) provisionally, + unless and until the copyright holder explicitly and finally + terminates your license, and (b) permanently, if the copyright holder + fails to notify you of the violation by some reasonable means prior to + 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you have + received notice of violation of this License (for any work) from that + copyright holder, and you cure the violation prior to 30 days after + your receipt of the notice. + +Our intent in providing these assurances is to encourage more use of the +software. We want companies and individuals to use, modify and distribute +this software. We want to work with users in an open and transparent way to +eliminate any uncertainty about our expectations regarding compliance or +enforcement that might limit adoption of our software. We view legal action +as a last resort, to be initiated only when other community efforts have +failed to resolve the problem. + +Finally, once a non-compliance issue is resolved, we hope the user will feel +welcome to join us in our efforts on this project. Working together, we will +be stronger. + +Except where noted below, we speak only for ourselves, and not for any company +we might work for today, have in the past, or will in the future. + + - Laura Abbott + - Bjorn Andersson (Linaro) + - Andrea Arcangeli + - Neil Armstrong + - Jens Axboe + - Pablo Neira Ayuso + - Khalid Aziz + - Ralf Baechle + - Felipe Balbi + - Arnd Bergmann + - Ard Biesheuvel + - Tim Bird + - Paolo Bonzini + - Christian Borntraeger + - Mark Brown (Linaro) + - Paul Burton + - Javier Martinez Canillas + - Rob Clark + - Jonathan Corbet + - Dennis Dalessandro + - Vivien Didelot (Savoir-faire Linux) + - Hans de Goede + - Mel Gorman (SUSE) + - Sven Eckelmann + - Alex Elder (Linaro) + - Fabio Estevam + - Larry Finger + - Bhumika Goyal + - Andy Gross + - Juergen Gross + - Shawn Guo + - Ulf Hansson + - Stephen Hemminger (Microsoft) + - Tejun Heo + - Rob Herring + - Masami Hiramatsu + - Michal Hocko + - Simon Horman + - Johan Hovold (Hovold Consulting AB) + - Christophe JAILLET + - Olof Johansson + - Lee Jones (Linaro) + - Heiner Kallweit + - Srinivas Kandagatla + - Jan Kara + - Shuah Khan (Samsung) + - David Kershner + - Jaegeuk Kim + - Namhyung Kim + - Colin Ian King + - Jeff Kirsher + - Greg Kroah-Hartman (Linux Foundation) + - Christian König + - Vinod Koul + - Krzysztof Kozlowski + - Viresh Kumar + - Aneesh Kumar K.V + - Julia Lawall + - Doug Ledford + - Chuck Lever (Oracle) + - Daniel Lezcano + - Shaohua Li + - Xin Long + - Tony Luck + - Catalin Marinas (Arm Ltd) + - Mike Marshall + - Chris Mason + - Paul E. McKenney + - David S. Miller + - Ingo Molnar + - Kuninori Morimoto + - Trond Myklebust + - Martin K. Petersen (Oracle) + - Borislav Petkov + - Jiri Pirko + - Josh Poimboeuf + - Sebastian Reichel (Collabora) + - Guenter Roeck + - Joerg Roedel + - Leon Romanovsky + - Steven Rostedt (VMware) + - Frank Rowand + - Ivan Safonov + - Anna Schumaker + - Jes Sorensen + - K.Y. Srinivasan + - Heiko Stuebner + - Jiri Kosina (SUSE) + - Willy Tarreau + - Dmitry Torokhov + - Linus Torvalds + - Thierry Reding + - Rik van Riel + - Geert Uytterhoeven (Glider bvba) + - Eduardo Valentin (Amazon.com) + - Daniel Vetter + - Linus Walleij + - Richard Weinberger + - Dan Williams + - Rafael J. Wysocki + - Arvind Yadav + - Masahiro Yamada + - Wei Yongjun + - Lv Zheng + - Marc Zyngier (Arm Ltd) diff --git a/Documentation/process/stable-kernel-rules.rst b/Documentation/process/stable-kernel-rules.rst index 61e9c78bd6d1..36a2dded525b 100644 --- a/Documentation/process/stable-kernel-rules.rst +++ b/Documentation/process/stable-kernel-rules.rst @@ -166,12 +166,12 @@ Trees - The queues of patches, for both completed versions and in progress versions can be found at: - http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git + https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git - The finalized and tagged releases of all stable kernels can be found in separate branches per version at: - http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git Review committee diff --git a/Documentation/process/submitting-patches.rst b/Documentation/process/submitting-patches.rst index 3e10719fee35..733478ade91b 100644 --- a/Documentation/process/submitting-patches.rst +++ b/Documentation/process/submitting-patches.rst @@ -413,7 +413,7 @@ e-mail discussions. -11) Sign your work — the Developer's Certificate of Origin +11) Sign your work - the Developer's Certificate of Origin ---------------------------------------------------------- To improve tracking of who did what, especially with patches that can diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt index b8a8c70b0188..c42a21b99046 100644 --- a/Documentation/rbtree.txt +++ b/Documentation/rbtree.txt @@ -193,6 +193,39 @@ Example:: for (node = rb_first(&mytree); node; node = rb_next(node)) printk("key=%s\n", rb_entry(node, struct mytype, node)->keystring); +Cached rbtrees +-------------- + +Computing the leftmost (smallest) node is quite a common task for binary +search trees, such as for traversals or users relying on a the particular +order for their own logic. To this end, users can use 'struct rb_root_cached' +to optimize O(logN) rb_first() calls to a simple pointer fetch avoiding +potentially expensive tree iterations. This is done at negligible runtime +overhead for maintanence; albeit larger memory footprint. + +Similar to the rb_root structure, cached rbtrees are initialized to be +empty via: + + struct rb_root_cached mytree = RB_ROOT_CACHED; + +Cached rbtree is simply a regular rb_root with an extra pointer to cache the +leftmost node. This allows rb_root_cached to exist wherever rb_root does, +which permits augmented trees to be supported as well as only a few extra +interfaces: + + struct rb_node *rb_first_cached(struct rb_root_cached *tree); + void rb_insert_color_cached(struct rb_node *, struct rb_root_cached *, bool); + void rb_erase_cached(struct rb_node *node, struct rb_root_cached *); + +Both insert and erase calls have their respective counterpart of augmented +trees: + + void rb_insert_augmented_cached(struct rb_node *node, struct rb_root_cached *, + bool, struct rb_augment_callbacks *); + void rb_erase_augmented_cached(struct rb_node *, struct rb_root_cached *, + struct rb_augment_callbacks *); + + Support for Augmented rbtrees ----------------------------- diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst index 1648fa80b3bf..1266eeae45f6 100644 --- a/Documentation/security/keys/core.rst +++ b/Documentation/security/keys/core.rst @@ -16,17 +16,7 @@ The key service can be configured on by enabling: This document has the following sections: - - Key overview - - Key service overview - - Key access permissions - - SELinux support - - New procfs files - - Userspace system call interface - - Kernel services - - Notes on accessing payload contents - - Defining a key type - - Request-key callback service - - Garbage collection +.. contents:: :local: Key Overview @@ -443,7 +433,7 @@ The main syscalls are: /sbin/request-key will be invoked in an attempt to obtain a key. The callout_info string will be passed as an argument to the program. - See also Documentation/security/keys-request-key.txt. + See also Documentation/security/keys/request-key.rst. The keyctl syscall functions are: @@ -973,7 +963,7 @@ payload contents" for more information. If successful, the key will have been attached to the default keyring for implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. - See also Documentation/security/keys-request-key.txt. + See also Documentation/security/keys/request-key.rst. * To search for a key, passing auxiliary data to the upcaller, call:: diff --git a/Documentation/security/keys/request-key.rst b/Documentation/security/keys/request-key.rst index aba32784174c..b2d16abaa9e9 100644 --- a/Documentation/security/keys/request-key.rst +++ b/Documentation/security/keys/request-key.rst @@ -3,7 +3,7 @@ Key Request Service =================== The key request service is part of the key retention service (refer to -Documentation/security/keys.txt). This document explains more fully how +Documentation/security/core.rst). This document explains more fully how the requesting algorithm works. The process starts by either the kernel requesting a service by calling diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst index 7b503831bdea..3bb24e09a332 100644 --- a/Documentation/security/keys/trusted-encrypted.rst +++ b/Documentation/security/keys/trusted-encrypted.rst @@ -172,4 +172,4 @@ Other uses for trusted and encrypted keys, such as for disk and file encryption are anticipated. In particular the new format 'ecryptfs' has been defined in in order to use encrypted keys to mount an eCryptfs filesystem. More details about the usage can be found in the file -``Documentation/security/keys-ecryptfs.txt``. +``Documentation/security/keys/ecryptfs.rst``. diff --git a/Documentation/sphinx-static/theme_overrides.css b/Documentation/sphinx-static/theme_overrides.css index d5764a4de5a2..522b6d4c49d4 100644 --- a/Documentation/sphinx-static/theme_overrides.css +++ b/Documentation/sphinx-static/theme_overrides.css @@ -4,6 +4,17 @@ * */ +/* Interim: Code-blocks with line nos - lines and line numbers don't line up. + * see: https://github.com/rtfd/sphinx_rtd_theme/issues/419 + */ + +div[class^="highlight"] pre { + line-height: normal; +} +.rst-content .highlight > pre { + line-height: normal; +} + @media screen { /* content column @@ -56,6 +67,12 @@ font-family: "Courier New", Courier, monospace } + /* fix bottom margin of lists items */ + + .rst-content .section ul li:last-child, .rst-content .section ul li p:last-child { + margin-bottom: 12px; + } + /* inline literal: drop the borderbox, padding and red color */ code, .rst-content tt, .rst-content code { diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerneldoc.py index d15e07f36881..39aa9e8697cc 100644 --- a/Documentation/sphinx/kerneldoc.py +++ b/Documentation/sphinx/kerneldoc.py @@ -27,6 +27,7 @@ # Please make sure this works on both python2 and python3. # +import codecs import os import subprocess import sys @@ -88,13 +89,10 @@ class KernelDocDirective(Directive): try: env.app.verbose('calling kernel-doc \'%s\'' % (" ".join(cmd))) - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() - # python2 needs conversion to unicode. - # python3 with universal_newlines=True returns strings. - if sys.version_info.major < 3: - out, err = unicode(out, 'utf-8'), unicode(err, 'utf-8') + out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') if p.returncode != 0: sys.stderr.write(err) diff --git a/Documentation/sphinx/requirements.txt b/Documentation/sphinx/requirements.txt new file mode 100644 index 000000000000..742be3e12619 --- /dev/null +++ b/Documentation/sphinx/requirements.txt @@ -0,0 +1,3 @@ +docutils==0.12 +Sphinx==1.4.9 +sphinx_rtd_theme diff --git a/Documentation/static-keys.txt b/Documentation/static-keys.txt index b83dfa1c0602..ab16efe0c79d 100644 --- a/Documentation/static-keys.txt +++ b/Documentation/static-keys.txt @@ -149,6 +149,26 @@ static_branch_inc(), will change the branch back to true. Likewise, if the key is initialized false, a 'static_branch_inc()', will change the branch to true. And then a 'static_branch_dec()', will again make the branch false. +The state and the reference count can be retrieved with 'static_key_enabled()' +and 'static_key_count()'. In general, if you use these functions, they +should be protected with the same mutex used around the enable/disable +or increment/decrement function. + +Note that switching branches results in some locks being taken, +particularly the CPU hotplug lock (in order to avoid races against +CPUs being brought in the kernel whilst the kernel is getting +patched). Calling the static key API from within a hotplug notifier is +thus a sure deadlock recipe. In order to still allow use of the +functionnality, the following functions are provided: + + static_key_enable_cpuslocked() + static_key_disable_cpuslocked() + static_branch_enable_cpuslocked() + static_branch_disable_cpuslocked() + +These functions are *not* general purpose, and must only be used when +you really know that you're in the above context, and no other. + Where an array of keys is required, it can be defined as:: DEFINE_STATIC_KEY_ARRAY_TRUE(keys, count); diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index bac23c198360..694968c7523c 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -61,6 +61,7 @@ show up in /proc/sys/kernel: - perf_cpu_time_max_percent - perf_event_paranoid - perf_event_max_stack +- perf_event_mlock_kb - perf_event_max_contexts_per_stack - pid_max - powersave-nap [ PPC only ] @@ -74,6 +75,7 @@ show up in /proc/sys/kernel: - reboot-cmd [ SPARC only ] - rtsig-max - rtsig-nr +- seccomp/ ==> Documentation/userspace-api/seccomp_filter.rst - sem - sem_next_id [ sysv ipc ] - sg-big-buff [ generic SCSI device (sg) ] @@ -654,7 +656,9 @@ Controls use of the performance events system by unprivileged users (without CAP_SYS_ADMIN). The default value is 2. -1: Allow use of (almost) all events by all users ->=0: Disallow raw tracepoint access by users without CAP_IOC_LOCK + Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK +>=0: Disallow ftrace function tracepoint by users without CAP_SYS_ADMIN + Disallow raw tracepoint access by users without CAP_SYS_ADMIN >=1: Disallow CPU event access by users without CAP_SYS_ADMIN >=2: Disallow kernel profiling by users without CAP_SYS_ADMIN @@ -673,6 +677,14 @@ The default value is 127. ============================================================== +perf_event_mlock_kb: + +Control size of per-cpu ring buffer not counted agains mlock limit. + +The default value is 512 + 1 page + +============================================================== + perf_event_max_contexts_per_stack: Controls maximum number of stack frame context entries for diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt index 28596e03220b..b67044a2575f 100644 --- a/Documentation/sysctl/net.txt +++ b/Documentation/sysctl/net.txt @@ -46,13 +46,13 @@ translate these BPF proglets into native CPU instructions. There are two flavors of JITs, the newer eBPF JIT currently supported on: - x86_64 - arm64 + - arm32 - ppc64 - sparc64 - mips64 - s390x And the older cBPF JIT supported on the following archs: - - arm - mips - ppc - sparc diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 48244c42ff52..9baf66a9ef4e 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -572,7 +572,9 @@ See Documentation/nommu-mmap.txt for more information. numa_zonelist_order -This sysctl is only for NUMA. +This sysctl is only for NUMA and it is deprecated. Anything but +Node order will fail! + 'where the memory is allocated from' is controlled by zonelists. (This documentation ignores ZONE_HIGHMEM/ZONE_DMA32 for simple explanation. you may be able to read ZONE_DMA as ZONE_DMA32...) diff --git a/Documentation/trace/stm.txt b/Documentation/trace/stm.txt index 11cff47eecce..03765750104b 100644 --- a/Documentation/trace/stm.txt +++ b/Documentation/trace/stm.txt @@ -83,7 +83,7 @@ by writing the name of the desired stm device there, for example: $ echo dummy_stm.0 > /sys/class/stm_source/console/stm_source_link For examples on how to use stm_source interface in the kernel, refer -to stm_console or stm_heartbeat drivers. +to stm_console, stm_heartbeat or stm_ftrace drivers. Each stm_source device will need to assume a master and a range of channels, depending on how many channels it requires. These are @@ -107,5 +107,16 @@ console in the STP stream, create a "console" policy entry (see the beginning of this text on how to do that). When initialized, it will consume one channel. +stm_ftrace +========== + +This is another "stm_source" device, once the stm_ftrace has been +linked with an stm device, and if "function" tracer is enabled, +function address and parent function address which Ftrace subsystem +would store into ring buffer will be exported via the stm device at +the same time. + +Currently only Ftrace "function" tracer is supported. + [1] https://software.intel.com/sites/default/files/managed/d3/3c/intel-th-developer-manual.pdf [2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0444b/index.html diff --git a/Documentation/translations/ko_KR/memory-barriers.txt b/Documentation/translations/ko_KR/memory-barriers.txt index 38310dcd6620..a7a813258013 100644 --- a/Documentation/translations/ko_KR/memory-barriers.txt +++ b/Documentation/translations/ko_KR/memory-barriers.txt @@ -523,11 +523,11 @@ CPU 에게 기대할 수 있는 최소한의 보장사항 몇가지가 있습니 즉, ACQUIRE 는 최소한의 "취득" 동작처럼, 그리고 RELEASE 는 최소한의 "공개" 처럼 동작한다는 의미입니다. -core-api/atomic_ops.rst 에서 설명되는 어토믹 오퍼레이션들 중에는 완전히 -순서잡힌 것들과 (배리어를 사용하지 않는) 완화된 순서의 것들 외에 ACQUIRE 와 -RELEASE 부류의 것들도 존재합니다. 로드와 스토어를 모두 수행하는 조합된 어토믹 -오퍼레이션에서, ACQUIRE 는 해당 오퍼레이션의 로드 부분에만 적용되고 RELEASE 는 -해당 오퍼레이션의 스토어 부분에만 적용됩니다. +atomic_t.txt 에 설명된 어토믹 오퍼레이션들 중 일부는 완전히 순서잡힌 것들과 +(배리어를 사용하지 않는) 완화된 순서의 것들 외에 ACQUIRE 와 RELEASE 부류의 +것들도 존재합니다. 로드와 스토어를 모두 수행하는 조합된 어토믹 오퍼레이션에서, +ACQUIRE 는 해당 오퍼레이션의 로드 부분에만 적용되고 RELEASE 는 해당 +오퍼레이션의 스토어 부분에만 적용됩니다. 메모리 배리어들은 두 CPU 간, 또는 CPU 와 디바이스 간에 상호작용의 가능성이 있을 때에만 필요합니다. 만약 어떤 코드에 그런 상호작용이 없을 것이 보장된다면, 해당 @@ -617,7 +617,22 @@ RELEASE 부류의 것들도 존재합니다. 로드와 스토어를 모두 수 이 변경은 앞의 처음 두가지 결과 중 하나만이 발생할 수 있고, 세번째의 결과는 발생할 수 없도록 합니다. -데이터 의존성 배리어는 의존적 쓰기에 대해서도 순서를 잡아줍니다: + +[!] 이 상당히 반직관적인 상황은 분리된 캐시를 가지는 기계들에서 가장 잘 +발생하는데, 예를 들면 한 캐시 뱅크는 짝수 번호의 캐시 라인들을 처리하고, 다른 +뱅크는 홀수 번호의 캐시 라인들을 처리하는 경우임을 알아두시기 바랍니다. 포인터 +P 는 짝수 번호 캐시 라인에 저장되어 있고, 변수 B 는 홀수 번호 캐시 라인에 +저장되어 있을 수 있습니다. 여기서 값을 읽어오는 CPU 의 캐시의 홀수 번호 처리 +뱅크는 열심히 일감을 처리중인 반면 홀수 번호 처리 뱅크는 할 일 없이 한가한 +중이라면 포인터 P (&B) 의 새로운 값과 변수 B 의 기존 값 (2) 를 볼 수 있습니다. + + +의존적 쓰기들의 순서를 맞추는데에는 데이터 의존성 배리어가 필요치 않은데, 이는 +리눅스 커널이 지원하는 CPU 들은 (1) 쓰기가 정말로 일어날지, (2) 쓰기가 어디에 +이루어질지, 그리고 (3) 쓰여질 값을 확실히 알기 전까지는 쓰기를 수행하지 않기 +때문입니다. 하지만 "컨트롤 의존성" 섹션과 +Documentation/RCU/rcu_dereference.txt 파일을 주의 깊게 읽어 주시기 바랍니다: +컴파일러는 매우 창의적인 많은 방법으로 종속성을 깰 수 있습니다. CPU 1 CPU 2 =============== =============== @@ -626,28 +641,19 @@ RELEASE 부류의 것들도 존재합니다. 로드와 스토어를 모두 수 <쓰기 배리어> WRITE_ONCE(P, &B); Q = READ_ONCE(P); - <데이터 의존성 배리어> - *Q = 5; + WRITE_ONCE(*Q, 5); -이 데이터 의존성 배리어는 Q 로의 읽기가 *Q 로의 스토어와 순서를 맞추게 -해줍니다. 이는 다음과 같은 결과를 막습니다: +따라서, Q 로의 읽기와 *Q 로의 쓰기 사이에는 데이터 종속성 배리어가 필요치 +않습니다. 달리 말하면, 데이터 종속성 배리어가 없더라도 다음 결과는 생기지 +않습니다: (Q == &B) && (B == 4) 이런 패턴은 드물게 사용되어야 함을 알아 두시기 바랍니다. 무엇보다도, 의존성 순서 규칙의 의도는 쓰기 작업을 -예방- 해서 그로 인해 발생하는 비싼 캐시 미스도 없애려는 것입니다. 이 패턴은 드물게 발생하는 에러 조건 같은것들을 기록하는데 -사용될 수 있고, 이렇게 배리어를 사용해 순서를 지키게 함으로써 그런 기록이 -사라지는 것을 막습니다. - - -[!] 상당히 비직관적인 이 상황은 분리된 캐시를 가진 기계, 예를 들어 한 캐시 -뱅크가 짝수번 캐시 라인을 처리하고 다른 뱅크는 홀수번 캐시 라인을 처리하는 기계 -등에서 가장 잘 발생합니다. 포인터 P 는 홀수 번호의 캐시 라인에 있고, 변수 B 는 -짝수 번호 캐시 라인에 있다고 생각해 봅시다. 그런 상태에서 읽기 작업을 하는 CPU -의 짝수번 뱅크는 할 일이 쌓여 매우 바쁘지만 홀수번 뱅크는 할 일이 없어 아무 -일도 하지 않고 있었다면, 포인터 P 는 새 값 (&B) 을, 그리고 변수 B 는 옛날 값 -(2) 을 가지고 있는 상태가 보여질 수도 있습니다. +사용될 수 있으며, CPU의 자연적인 순서 보장이 그런 기록들을 사라지지 않게 +해줍니다. 데이터 의존성 배리어는 매우 중요한데, 예를 들어 RCU 시스템에서 그렇습니다. @@ -1848,8 +1854,7 @@ Mandatory 배리어들은 SMP 시스템에서도 UP 시스템에서도 SMP 효 이 코드는 객체의 업데이트된 death 마크가 레퍼런스 카운터 감소 동작 *전에* 보일 것을 보장합니다. - 더 많은 정보를 위해선 Documentation/core-api/atomic_ops.rst 문서를 참고하세요. - 어디서 이것들을 사용해야 할지 궁금하다면 "어토믹 오퍼레이션" 서브섹션을 + 더 많은 정보를 위해선 Documentation/atomic_{t,bitops}.txt 문서를 참고하세요. @@ -1956,10 +1961,7 @@ MMIO 쓰기 배리어 뒤에 완료됩니다. ACQUIRE 앞에서 요청된 메모리 오퍼레이션은 ACQUIRE 오퍼레이션이 완료된 후에 - 완료될 수 있습니다. smp_mb__before_spinlock() 뒤에 ACQUIRE 가 실행되는 - 코드 블록은 블록 앞의 스토어를 블록 뒤의 로드와 스토어에 대해 순서 - 맞춥니다. 이건 smp_mb() 보다 완화된 것임을 기억하세요! 많은 아키텍쳐에서 - smp_mb__before_spinlock() 은 사실 아무일도 하지 않습니다. + 완료될 수 있습니다. (2) RELEASE 오퍼레이션의 영향: @@ -2471,86 +2473,7 @@ _않습니다_. 전체 메모리 배리어를 내포하고 또 일부는 내포하지 않지만, 커널에서 상당히 의존적으로 사용하는 기능 중 하나입니다. -메모리의 어떤 상태를 수정하고 해당 상태에 대한 (예전의 또는 최신의) 정보를 -리턴하는 어토믹 오퍼레이션은 모두 SMP-조건적 범용 메모리 배리어(smp_mb())를 -실제 오퍼레이션의 앞과 뒤에 내포합니다. 이런 오퍼레이션은 다음의 것들을 -포함합니다: - - xchg(); - atomic_xchg(); atomic_long_xchg(); - atomic_inc_return(); atomic_long_inc_return(); - atomic_dec_return(); atomic_long_dec_return(); - atomic_add_return(); atomic_long_add_return(); - atomic_sub_return(); atomic_long_sub_return(); - atomic_inc_and_test(); atomic_long_inc_and_test(); - atomic_dec_and_test(); atomic_long_dec_and_test(); - atomic_sub_and_test(); atomic_long_sub_and_test(); - atomic_add_negative(); atomic_long_add_negative(); - test_and_set_bit(); - test_and_clear_bit(); - test_and_change_bit(); - - /* exchange 조건이 성공할 때 */ - cmpxchg(); - atomic_cmpxchg(); atomic_long_cmpxchg(); - atomic_add_unless(); atomic_long_add_unless(); - -이것들은 메모리 배리어 효과가 필요한 ACQUIRE 부류와 RELEASE 부류 오퍼레이션들을 -구현할 때, 그리고 객체 해제를 위해 레퍼런스 카운터를 조정할 때, 암묵적 메모리 -배리어 효과가 필요한 곳 등에 사용됩니다. - - -다음의 오퍼레이션들은 메모리 배리어를 내포하지 _않기_ 때문에 문제가 될 수 -있지만, RELEASE 부류의 오퍼레이션들과 같은 것들을 구현할 때 사용될 수도 -있습니다: - - atomic_set(); - set_bit(); - clear_bit(); - change_bit(); - -이것들을 사용할 때에는 필요하다면 적절한 (예를 들면 smp_mb__before_atomic() -같은) 메모리 배리어가 명시적으로 함께 사용되어야 합니다. - - -아래의 것들도 메모리 배리어를 내포하지 _않기_ 때문에, 일부 환경에서는 (예를 -들면 smp_mb__before_atomic() 과 같은) 명시적인 메모리 배리어 사용이 필요합니다. - - atomic_add(); - atomic_sub(); - atomic_inc(); - atomic_dec(); - -이것들이 통계 생성을 위해 사용된다면, 그리고 통계 데이터 사이에 관계가 존재하지 -않는다면 메모리 배리어는 필요치 않을 겁니다. - -객체의 수명을 관리하기 위해 레퍼런스 카운팅 목적으로 사용된다면, 레퍼런스 -카운터는 락으로 보호되는 섹션에서만 조정되거나 호출하는 쪽이 이미 충분한 -레퍼런스를 잡고 있을 것이기 때문에 메모리 배리어는 아마 필요 없을 겁니다. - -만약 어떤 락을 구성하기 위해 사용된다면, 락 관련 동작은 일반적으로 작업을 특정 -순서대로 진행해야 하므로 메모리 배리어가 필요할 수 있습니다. - -기본적으로, 각 사용처에서는 메모리 배리어가 필요한지 아닌지 충분히 고려해야 -합니다. - -아래의 오퍼레이션들은 특별한 락 관련 동작들입니다: - - test_and_set_bit_lock(); - clear_bit_unlock(); - __clear_bit_unlock(); - -이것들은 ACQUIRE 류와 RELEASE 류의 오퍼레이션들을 구현합니다. 락 관련 도구를 -구현할 때에는 이것들을 좀 더 선호하는 편이 나은데, 이것들의 구현은 많은 -아키텍쳐에서 최적화 될 수 있기 때문입니다. - -[!] 이런 상황에 사용할 수 있는 특수한 메모리 배리어 도구들이 있습니다만, 일부 -CPU 에서는 사용되는 어토믹 인스트럭션 자체에 메모리 배리어가 내포되어 있어서 -어토믹 오퍼레이션과 메모리 배리어를 함께 사용하는 게 불필요한 일이 될 수 -있는데, 그런 경우에 이 특수 메모리 배리어 도구들은 no-op 이 되어 실질적으로 -아무일도 하지 않습니다. - -더 많은 내용을 위해선 Documentation/core-api/atomic_ops.rst 를 참고하세요. +더 많은 내용을 위해선 Documentation/atomic_t.txt 를 참고하세요. 디바이스 액세스 diff --git a/Documentation/translations/zh_CN/HOWTO b/Documentation/translations/zh_CN/HOWTO index 11be075ba5fa..5f6d09edc9ac 100644 --- a/Documentation/translations/zh_CN/HOWTO +++ b/Documentation/translations/zh_CN/HOWTO @@ -149,9 +149,7 @@ Linux内核代码中包含有大量的文档。这些文档对于学习如何与 核源码的主目录中使用以下不同命令将会分别生成PDF、Postscript、HTML和手册 页等不同格式的文档: make pdfdocs - make psdocs make htmldocs - make mandocs 如何成为内核开发者 diff --git a/Documentation/userspace-api/seccomp_filter.rst b/Documentation/userspace-api/seccomp_filter.rst index f71eb5ef1f2d..099c412951d6 100644 --- a/Documentation/userspace-api/seccomp_filter.rst +++ b/Documentation/userspace-api/seccomp_filter.rst @@ -87,11 +87,16 @@ Return values A seccomp filter may return any of the following values. If multiple filters exist, the return value for the evaluation of a given system call will always use the highest precedent value. (For example, -``SECCOMP_RET_KILL`` will always take precedence.) +``SECCOMP_RET_KILL_PROCESS`` will always take precedence.) In precedence order, they are: -``SECCOMP_RET_KILL``: +``SECCOMP_RET_KILL_PROCESS``: + Results in the entire process exiting immediately without executing + the system call. The exit status of the task (``status & 0x7f``) + will be ``SIGSYS``, not ``SIGKILL``. + +``SECCOMP_RET_KILL_THREAD``: Results in the task exiting immediately without executing the system call. The exit status of the task (``status & 0x7f``) will be ``SIGSYS``, not ``SIGKILL``. @@ -141,6 +146,15 @@ In precedence order, they are: allow use of ptrace, even of other sandboxed processes, without extreme care; ptracers can use this mechanism to escape.) +``SECCOMP_RET_LOG``: + Results in the system call being executed after it is logged. This + should be used by application developers to learn which syscalls their + application needs without having to iterate through multiple test and + development cycles to build the list. + + This action will only be logged if "log" is present in the + actions_logged sysctl string. + ``SECCOMP_RET_ALLOW``: Results in the system call being executed. @@ -169,7 +183,41 @@ The ``samples/seccomp/`` directory contains both an x86-specific example and a more generic example of a higher level macro interface for BPF program generation. +Sysctls +======= +Seccomp's sysctl files can be found in the ``/proc/sys/kernel/seccomp/`` +directory. Here's a description of each file in that directory: + +``actions_avail``: + A read-only ordered list of seccomp return values (refer to the + ``SECCOMP_RET_*`` macros above) in string form. The ordering, from + left-to-right, is the least permissive return value to the most + permissive return value. + + The list represents the set of seccomp return values supported + by the kernel. A userspace program may use this list to + determine if the actions found in the ``seccomp.h``, when the + program was built, differs from the set of actions actually + supported in the current running kernel. + +``actions_logged``: + A read-write ordered list of seccomp return values (refer to the + ``SECCOMP_RET_*`` macros above) that are allowed to be logged. Writes + to the file do not need to be in ordered form but reads from the file + will be ordered in the same way as the actions_avail sysctl. + + It is important to note that the value of ``actions_logged`` does not + prevent certain actions from being logged when the audit subsystem is + configured to audit a task. If the action is not found in + ``actions_logged`` list, the final decision on whether to audit the + action for that task is ultimately left up to the audit subsystem to + decide for all seccomp return values other than ``SECCOMP_RET_ALLOW``. + + The ``allow`` string is not accepted in the ``actions_logged`` sysctl + as it is not possible to log ``SECCOMP_RET_ALLOW`` actions. Attempting + to write ``allow`` to the sysctl will result in an EINVAL being + returned. Adding architecture support =========================== diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt index b2f60ca8b60c..b3ce12643553 100644 --- a/Documentation/virtual/kvm/devices/arm-vgic.txt +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt @@ -83,6 +83,11 @@ Groups: Bits for undefined preemption levels are RAZ/WI. + Note that this differs from a CPU's view of the APRs on hardware in which + a GIC without the security extensions expose group 0 and group 1 active + priorities in separate register groups, whereas we show a combined view + similar to GICv2's GICH_APR. + For historical reasons and to provide ABI compatibility with userspace we export the GICC_PMR register in the format of the GICH_VMCR.VMPriMask field in the lower 5 bits of a word, meaning that userspace must always diff --git a/Documentation/virtual/kvm/devices/vm.txt b/Documentation/virtual/kvm/devices/vm.txt index 903fc926860b..95ca68d663a4 100644 --- a/Documentation/virtual/kvm/devices/vm.txt +++ b/Documentation/virtual/kvm/devices/vm.txt @@ -176,7 +176,8 @@ Architectures: s390 3.1. ATTRIBUTE: KVM_S390_VM_TOD_HIGH -Allows user space to set/get the TOD clock extension (u8). +Allows user space to set/get the TOD clock extension (u8) (superseded by +KVM_S390_VM_TOD_EXT). Parameters: address of a buffer in user space to store the data (u8) to Returns: -EFAULT if the given address is not accessible from kernel space @@ -190,6 +191,17 @@ the POP (u64). Parameters: address of a buffer in user space to store the data (u64) to Returns: -EFAULT if the given address is not accessible from kernel space +3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT +Allows user space to set/get bits 0-63 of the TOD clock register as defined in +the POP (u64). If the guest CPU model supports the TOD clock extension (u8), it +also allows user space to get/set it. If the guest CPU model does not support +it, it is stored as 0 and not allowed to be set to a value != 0. + +Parameters: address of a buffer in user space to store the data + (kvm_s390_vm_tod_clock) to +Returns: -EFAULT if the given address is not accessible from kernel space + -EINVAL if setting the TOD clock extension to != 0 is not supported + 4. GROUP: KVM_S390_VM_CRYPTO Architectures: s390 diff --git a/Documentation/vm/hmm.txt b/Documentation/vm/hmm.txt new file mode 100644 index 000000000000..4d3aac9f4a5d --- /dev/null +++ b/Documentation/vm/hmm.txt @@ -0,0 +1,384 @@ +Heterogeneous Memory Management (HMM) + +Transparently allow any component of a program to use any memory region of said +program with a device without using device specific memory allocator. This is +becoming a requirement to simplify the use of advance heterogeneous computing +where GPU, DSP or FPGA are use to perform various computations. + +This document is divided as follow, in the first section i expose the problems +related to the use of a device specific allocator. The second section i expose +the hardware limitations that are inherent to many platforms. The third section +gives an overview of HMM designs. The fourth section explains how CPU page- +table mirroring works and what is HMM purpose in this context. Fifth section +deals with how device memory is represented inside the kernel. Finaly the last +section present the new migration helper that allow to leverage the device DMA +engine. + + +1) Problems of using device specific memory allocator: +2) System bus, device memory characteristics +3) Share address space and migration +4) Address space mirroring implementation and API +5) Represent and manage device memory from core kernel point of view +6) Migrate to and from device memory +7) Memory cgroup (memcg) and rss accounting + + +------------------------------------------------------------------------------- + +1) Problems of using device specific memory allocator: + +Device with large amount of on board memory (several giga bytes) like GPU have +historically manage their memory through dedicated driver specific API. This +creates a disconnect between memory allocated and managed by device driver and +regular application memory (private anonymous, share memory or regular file +back memory). From here on i will refer to this aspect as split address space. +I use share address space to refer to the opposite situation ie one in which +any memory region can be use by device transparently. + +Split address space because device can only access memory allocated through the +device specific API. This imply that all memory object in a program are not +equal from device point of view which complicate large program that rely on a +wide set of libraries. + +Concretly this means that code that wants to leverage device like GPU need to +copy object between genericly allocated memory (malloc, mmap private/share/) +and memory allocated through the device driver API (this still end up with an +mmap but of the device file). + +For flat dataset (array, grid, image, ...) this isn't too hard to achieve but +complex data-set (list, tree, ...) are hard to get right. Duplicating a complex +data-set need to re-map all the pointer relations between each of its elements. +This is error prone and program gets harder to debug because of the duplicate +data-set. + +Split address space also means that library can not transparently use data they +are getting from core program or other library and thus each library might have +to duplicate its input data-set using specific memory allocator. Large project +suffer from this and waste resources because of the various memory copy. + +Duplicating each library API to accept as input or output memory allocted by +each device specific allocator is not a viable option. It would lead to a +combinatorial explosions in the library entry points. + +Finaly with the advance of high level language constructs (in C++ but in other +language too) it is now possible for compiler to leverage GPU or other devices +without even the programmer knowledge. Some of compiler identified patterns are +only do-able with a share address. It is as well more reasonable to use a share +address space for all the other patterns. + + +------------------------------------------------------------------------------- + +2) System bus, device memory characteristics + +System bus cripple share address due to few limitations. Most system bus only +allow basic memory access from device to main memory, even cache coherency is +often optional. Access to device memory from CPU is even more limited, most +often than not it is not cache coherent. + +If we only consider the PCIE bus than device can access main memory (often +through an IOMMU) and be cache coherent with the CPUs. However it only allows +a limited set of atomic operation from device on main memory. This is worse +in the other direction the CPUs can only access a limited range of the device +memory and can not perform atomic operations on it. Thus device memory can not +be consider like regular memory from kernel point of view. + +Another crippling factor is the limited bandwidth (~32GBytes/s with PCIE 4.0 +and 16 lanes). This is 33 times less that fastest GPU memory (1 TBytes/s). +The final limitation is latency, access to main memory from the device has an +order of magnitude higher latency than when the device access its own memory. + +Some platform are developing new system bus or additions/modifications to PCIE +to address some of those limitations (OpenCAPI, CCIX). They mainly allow two +way cache coherency between CPU and device and allow all atomic operations the +architecture supports. Saddly not all platform are following this trends and +some major architecture are left without hardware solutions to those problems. + +So for share address space to make sense not only we must allow device to +access any memory memory but we must also permit any memory to be migrated to +device memory while device is using it (blocking CPU access while it happens). + + +------------------------------------------------------------------------------- + +3) Share address space and migration + +HMM intends to provide two main features. First one is to share the address +space by duplication the CPU page table into the device page table so same +address point to same memory and this for any valid main memory address in +the process address space. + +To achieve this, HMM offer a set of helpers to populate the device page table +while keeping track of CPU page table updates. Device page table updates are +not as easy as CPU page table updates. To update the device page table you must +allow a buffer (or use a pool of pre-allocated buffer) and write GPU specifics +commands in it to perform the update (unmap, cache invalidations and flush, +...). This can not be done through common code for all device. Hence why HMM +provides helpers to factor out everything that can be while leaving the gory +details to the device driver. + +The second mechanism HMM provide is a new kind of ZONE_DEVICE memory that does +allow to allocate a struct page for each page of the device memory. Those page +are special because the CPU can not map them. They however allow to migrate +main memory to device memory using exhisting migration mechanism and everything +looks like if page was swap out to disk from CPU point of view. Using a struct +page gives the easiest and cleanest integration with existing mm mechanisms. +Again here HMM only provide helpers, first to hotplug new ZONE_DEVICE memory +for the device memory and second to perform migration. Policy decision of what +and when to migrate things is left to the device driver. + +Note that any CPU access to a device page trigger a page fault and a migration +back to main memory ie when a page backing an given address A is migrated from +a main memory page to a device page then any CPU access to address A trigger a +page fault and initiate a migration back to main memory. + + +With this two features, HMM not only allow a device to mirror a process address +space and keeps both CPU and device page table synchronize, but also allow to +leverage device memory by migrating part of data-set that is actively use by a +device. + + +------------------------------------------------------------------------------- + +4) Address space mirroring implementation and API + +Address space mirroring main objective is to allow to duplicate range of CPU +page table into a device page table and HMM helps keeping both synchronize. A +device driver that want to mirror a process address space must start with the +registration of an hmm_mirror struct: + + int hmm_mirror_register(struct hmm_mirror *mirror, + struct mm_struct *mm); + int hmm_mirror_register_locked(struct hmm_mirror *mirror, + struct mm_struct *mm); + +The locked variant is to be use when the driver is already holding the mmap_sem +of the mm in write mode. The mirror struct has a set of callback that are use +to propagate CPU page table: + + struct hmm_mirror_ops { + /* sync_cpu_device_pagetables() - synchronize page tables + * + * @mirror: pointer to struct hmm_mirror + * @update_type: type of update that occurred to the CPU page table + * @start: virtual start address of the range to update + * @end: virtual end address of the range to update + * + * This callback ultimately originates from mmu_notifiers when the CPU + * page table is updated. The device driver must update its page table + * in response to this callback. The update argument tells what action + * to perform. + * + * The device driver must not return from this callback until the device + * page tables are completely updated (TLBs flushed, etc); this is a + * synchronous call. + */ + void (*update)(struct hmm_mirror *mirror, + enum hmm_update action, + unsigned long start, + unsigned long end); + }; + +Device driver must perform update to the range following action (turn range +read only, or fully unmap, ...). Once driver callback returns the device must +be done with the update. + + +When device driver wants to populate a range of virtual address it can use +either: + int hmm_vma_get_pfns(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns); + int hmm_vma_fault(struct vm_area_struct *vma, + struct hmm_range *range, + unsigned long start, + unsigned long end, + hmm_pfn_t *pfns, + bool write, + bool block); + +First one (hmm_vma_get_pfns()) will only fetch present CPU page table entry and +will not trigger a page fault on missing or non present entry. The second one +do trigger page fault on missing or read only entry if write parameter is true. +Page fault use the generic mm page fault code path just like a CPU page fault. + +Both function copy CPU page table into their pfns array argument. Each entry in +that array correspond to an address in the virtual range. HMM provide a set of +flags to help driver identify special CPU page table entries. + +Locking with the update() callback is the most important aspect the driver must +respect in order to keep things properly synchronize. The usage pattern is : + + int driver_populate_range(...) + { + struct hmm_range range; + ... + again: + ret = hmm_vma_get_pfns(vma, &range, start, end, pfns); + if (ret) + return ret; + take_lock(driver->update); + if (!hmm_vma_range_done(vma, &range)) { + release_lock(driver->update); + goto again; + } + + // Use pfns array content to update device page table + + release_lock(driver->update); + return 0; + } + +The driver->update lock is the same lock that driver takes inside its update() +callback. That lock must be call before hmm_vma_range_done() to avoid any race +with a concurrent CPU page table update. + +HMM implements all this on top of the mmu_notifier API because we wanted to a +simpler API and also to be able to perform optimization latter own like doing +concurrent device update in multi-devices scenario. + +HMM also serve as an impedence missmatch between how CPU page table update are +done (by CPU write to the page table and TLB flushes) from how device update +their own page table. Device update is a multi-step process, first appropriate +commands are write to a buffer, then this buffer is schedule for execution on +the device. It is only once the device has executed commands in the buffer that +the update is done. Creating and scheduling update command buffer can happen +concurrently for multiple devices. Waiting for each device to report commands +as executed is serialize (there is no point in doing this concurrently). + + +------------------------------------------------------------------------------- + +5) Represent and manage device memory from core kernel point of view + +Several differents design were try to support device memory. First one use +device specific data structure to keep information about migrated memory and +HMM hooked itself in various place of mm code to handle any access to address +that were back by device memory. It turns out that this ended up replicating +most of the fields of struct page and also needed many kernel code path to be +updated to understand this new kind of memory. + +Thing is most kernel code path never try to access the memory behind a page +but only care about struct page contents. Because of this HMM switchted to +directly using struct page for device memory which left most kernel code path +un-aware of the difference. We only need to make sure that no one ever try to +map those page from the CPU side. + +HMM provide a set of helpers to register and hotplug device memory as a new +region needing struct page. This is offer through a very simple API: + + struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, + struct device *device, + unsigned long size); + void hmm_devmem_remove(struct hmm_devmem *devmem); + +The hmm_devmem_ops is where most of the important things are: + + struct hmm_devmem_ops { + void (*free)(struct hmm_devmem *devmem, struct page *page); + int (*fault)(struct hmm_devmem *devmem, + struct vm_area_struct *vma, + unsigned long addr, + struct page *page, + unsigned flags, + pmd_t *pmdp); + }; + +The first callback (free()) happens when the last reference on a device page is +drop. This means the device page is now free and no longer use by anyone. The +second callback happens whenever CPU try to access a device page which it can +not do. This second callback must trigger a migration back to system memory. + + +------------------------------------------------------------------------------- + +6) Migrate to and from device memory + +Because CPU can not access device memory, migration must use device DMA engine +to perform copy from and to device memory. For this we need a new migration +helper: + + int migrate_vma(const struct migrate_vma_ops *ops, + struct vm_area_struct *vma, + unsigned long mentries, + unsigned long start, + unsigned long end, + unsigned long *src, + unsigned long *dst, + void *private); + +Unlike other migration function it works on a range of virtual address, there +is two reasons for that. First device DMA copy has a high setup overhead cost +and thus batching multiple pages is needed as otherwise the migration overhead +make the whole excersie pointless. The second reason is because driver trigger +such migration base on range of address the device is actively accessing. + +The migrate_vma_ops struct define two callbacks. First one (alloc_and_copy()) +control destination memory allocation and copy operation. Second one is there +to allow device driver to perform cleanup operation after migration. + + struct migrate_vma_ops { + void (*alloc_and_copy)(struct vm_area_struct *vma, + const unsigned long *src, + unsigned long *dst, + unsigned long start, + unsigned long end, + void *private); + void (*finalize_and_map)(struct vm_area_struct *vma, + const unsigned long *src, + const unsigned long *dst, + unsigned long start, + unsigned long end, + void *private); + }; + +It is important to stress that this migration helpers allow for hole in the +virtual address range. Some pages in the range might not be migrated for all +the usual reasons (page is pin, page is lock, ...). This helper does not fail +but just skip over those pages. + +The alloc_and_copy() might as well decide to not migrate all pages in the +range (for reasons under the callback control). For those the callback just +have to leave the corresponding dst entry empty. + +Finaly the migration of the struct page might fails (for file back page) for +various reasons (failure to freeze reference, or update page cache, ...). If +that happens then the finalize_and_map() can catch any pages that was not +migrated. Note those page were still copied to new page and thus we wasted +bandwidth but this is considered as a rare event and a price that we are +willing to pay to keep all the code simpler. + + +------------------------------------------------------------------------------- + +7) Memory cgroup (memcg) and rss accounting + +For now device memory is accounted as any regular page in rss counters (either +anonymous if device page is use for anonymous, file if device page is use for +file back page or shmem if device page is use for share memory). This is a +deliberate choice to keep existing application that might start using device +memory without knowing about it to keep runing unimpacted. + +Drawbacks is that OOM killer might kill an application using a lot of device +memory and not a lot of regular system memory and thus not freeing much system +memory. We want to gather more real world experience on how application and +system react under memory pressure in the presence of device memory before +deciding to account device memory differently. + + +Same decision was made for memory cgroup. Device memory page are accounted +against same memory cgroup a regular page would be accounted to. This does +simplify migration to and from device memory. This also means that migration +back from device memory to regular memory can not fail because it would +go above memory cgroup limit. We might revisit this choice latter on once we +get more experience in how device memory is use and its impact on memory +resource control. + + +Note that device memory can never be pin nor by device driver nor through GUP +and thus such memory is always free upon process exit. Or when last reference +is drop in case of share memory or file back memory. diff --git a/Documentation/vm/numa b/Documentation/vm/numa index a08f71647714..a31b85b9bb88 100644 --- a/Documentation/vm/numa +++ b/Documentation/vm/numa @@ -79,11 +79,8 @@ memory, Linux must decide whether to order the zonelists such that allocations fall back to the same zone type on a different node, or to a different zone type on the same node. This is an important consideration because some zones, such as DMA or DMA32, represent relatively scarce resources. Linux chooses -a default zonelist order based on the sizes of the various zone types relative -to the total memory of the node and the total memory of the system. The -default zonelist order may be overridden using the numa_zonelist_order kernel -boot parameter or sysctl. [see Documentation/admin-guide/kernel-parameters.rst and -Documentation/sysctl/vm.txt] +a default Node ordered zonelist. This means it tries to fallback to other zones +from the same node before using remote nodes which are ordered by NUMA distance. By default, Linux will attempt to satisfy memory allocation requests from the node to which the CPU that executes the request is assigned. Specifically, diff --git a/Documentation/vm/swap_numa.txt b/Documentation/vm/swap_numa.txt new file mode 100644 index 000000000000..d5960c9124f5 --- /dev/null +++ b/Documentation/vm/swap_numa.txt @@ -0,0 +1,69 @@ +Automatically bind swap device to numa node +------------------------------------------- + +If the system has more than one swap device and swap device has the node +information, we can make use of this information to decide which swap +device to use in get_swap_pages() to get better performance. + + +How to use this feature +----------------------- + +Swap device has priority and that decides the order of it to be used. To make +use of automatically binding, there is no need to manipulate priority settings +for swap devices. e.g. on a 2 node machine, assume 2 swap devices swapA and +swapB, with swapA attached to node 0 and swapB attached to node 1, are going +to be swapped on. Simply swapping them on by doing: +# swapon /dev/swapA +# swapon /dev/swapB + +Then node 0 will use the two swap devices in the order of swapA then swapB and +node 1 will use the two swap devices in the order of swapB then swapA. Note +that the order of them being swapped on doesn't matter. + +A more complex example on a 4 node machine. Assume 6 swap devices are going to +be swapped on: swapA and swapB are attached to node 0, swapC is attached to +node 1, swapD and swapE are attached to node 2 and swapF is attached to node3. +The way to swap them on is the same as above: +# swapon /dev/swapA +# swapon /dev/swapB +# swapon /dev/swapC +# swapon /dev/swapD +# swapon /dev/swapE +# swapon /dev/swapF + +Then node 0 will use them in the order of: +swapA/swapB -> swapC -> swapD -> swapE -> swapF +swapA and swapB will be used in a round robin mode before any other swap device. + +node 1 will use them in the order of: +swapC -> swapA -> swapB -> swapD -> swapE -> swapF + +node 2 will use them in the order of: +swapD/swapE -> swapA -> swapB -> swapC -> swapF +Similaly, swapD and swapE will be used in a round robin mode before any +other swap devices. + +node 3 will use them in the order of: +swapF -> swapA -> swapB -> swapC -> swapD -> swapE + + +Implementation details +---------------------- + +The current code uses a priority based list, swap_avail_list, to decide +which swap device to use and if multiple swap devices share the same +priority, they are used round robin. This change here replaces the single +global swap_avail_list with a per-numa-node list, i.e. for each numa node, +it sees its own priority based list of available swap devices. Swap +device's priority can be promoted on its matching node's swap_avail_list. + +The current swap device's priority is set as: user can set a >=0 value, +or the system will pick one starting from -1 then downwards. The priority +value in the swap_avail_list is the negated value of the swap device's +due to plist being sorted from low to high. The new policy doesn't change +the semantics for priority >=0 cases, the previous starting from -1 then +downwards now becomes starting from -2 then downwards and -1 is reserved +as the promoted value. So if multiple swap devices are attached to the same +node, they will all be promoted to priority -1 on that node's plist and will +be used round robin before any other swap devices. diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index b3526365ea8e..6f9d7b418917 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -117,7 +117,7 @@ nowayout: Watchdog cannot be stopped once started ------------------------------------------------- iTCO_wdt: heartbeat: Watchdog heartbeat in seconds. - (5<=heartbeat<=74 (TCO v1) or 1226 (TCO v2), default=30) + (2 - -Kernel can update microcode in early phase of boot time. Loading microcode early -can fix CPU issues before they are observed during kernel boot time. - -Microcode is stored in an initrd file. The microcode is read from the initrd -file and loaded to CPUs during boot time. - -The format of the combined initrd image is microcode in cpio format followed by -the initrd image (maybe compressed). Kernel parses the combined initrd image -during boot time. The microcode file in cpio name space is: -on Intel: kernel/x86/microcode/GenuineIntel.bin -on AMD : kernel/x86/microcode/AuthenticAMD.bin - -During BSP boot (before SMP starts), if the kernel finds the microcode file in -the initrd file, it parses the microcode and saves matching microcode in memory. -If matching microcode is found, it will be uploaded in BSP and later on in all -APs. - -The cached microcode patch is applied when CPUs resume from a sleep state. - -There are two legacy user space interfaces to load microcode, either through -/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file -in sysfs. - -In addition to these two legacy methods, the early loading method described -here is the third method with which microcode can be uploaded to a system's -CPUs. - -The following example script shows how to generate a new combined initrd file in -/boot/initrd-3.5.0.ucode.img with original microcode microcode.bin and -original initrd image /boot/initrd-3.5.0.img. - -mkdir initrd -cd initrd -mkdir -p kernel/x86/microcode -cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin) -find . | cpio -o -H newc >../ucode.cpio -cd .. -cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img - -Builtin microcode -================= - -We can also load builtin microcode supplied through the regular firmware -builtin method CONFIG_FIRMWARE_IN_KERNEL. Only 64-bit is currently -supported. - -Here's an example: - -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" -CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" - -This basically means, you have the following tree structure locally: - -/lib/firmware/ -|-- amd-ucode -... -| |-- microcode_amd_fam15h.bin -... -|-- intel-ucode -... -| |-- 06-3a-09 -... - -so that the build system can find those files and integrate them into -the final kernel image. The early loader finds them and applies them. diff --git a/Documentation/x86/intel_rdt_ui.txt b/Documentation/x86/intel_rdt_ui.txt index c491a1b82de2..4d8848e4e224 100644 --- a/Documentation/x86/intel_rdt_ui.txt +++ b/Documentation/x86/intel_rdt_ui.txt @@ -6,8 +6,8 @@ Fenghua Yu Tony Luck Vikas Shivappa -This feature is enabled by the CONFIG_INTEL_RDT_A Kconfig and the -X86 /proc/cpuinfo flag bits "rdt", "cat_l3" and "cdp_l3". +This feature is enabled by the CONFIG_INTEL_RDT Kconfig and the +X86 /proc/cpuinfo flag bits "rdt", "cqm", "cat_l3" and "cdp_l3". To use the feature mount the file system: @@ -17,6 +17,13 @@ mount options are: "cdp": Enable code/data prioritization in L3 cache allocations. +RDT features are orthogonal. A particular system may support only +monitoring, only control, or both monitoring and control. + +The mount succeeds if either of allocation or monitoring is present, but +only those files and directories supported by the system will be created. +For more details on the behavior of the interface during monitoring +and allocation, see the "Resource alloc and monitor groups" section. Info directory -------------- @@ -24,7 +31,12 @@ Info directory The 'info' directory contains information about the enabled resources. Each resource has its own subdirectory. The subdirectory names reflect the resource names. -Cache resource(L3/L2) subdirectory contains the following files: + +Each subdirectory contains the following files with respect to +allocation: + +Cache resource(L3/L2) subdirectory contains the following files +related to allocation: "num_closids": The number of CLOSIDs which are valid for this resource. The kernel uses the smallest number of @@ -36,7 +48,15 @@ Cache resource(L3/L2) subdirectory contains the following files: "min_cbm_bits": The minimum number of consecutive bits which must be set when writing a mask. -Memory bandwitdh(MB) subdirectory contains the following files: +"shareable_bits": Bitmask of shareable resource with other executing + entities (e.g. I/O). User can use this when + setting up exclusive cache partitions. Note that + some platforms support devices that have their + own settings for cache use which can over-ride + these bits. + +Memory bandwitdh(MB) subdirectory contains the following files +with respect to allocation: "min_bandwidth": The minimum memory bandwidth percentage which user can request. @@ -52,48 +72,152 @@ Memory bandwitdh(MB) subdirectory contains the following files: non-linear. This field is purely informational only. -Resource groups ---------------- +If RDT monitoring is available there will be an "L3_MON" directory +with the following files: + +"num_rmids": The number of RMIDs available. This is the + upper bound for how many "CTRL_MON" + "MON" + groups can be created. + +"mon_features": Lists the monitoring events if + monitoring is enabled for the resource. + +"max_threshold_occupancy": + Read/write file provides the largest value (in + bytes) at which a previously used LLC_occupancy + counter can be considered for re-use. + + +Resource alloc and monitor groups +--------------------------------- + Resource groups are represented as directories in the resctrl file -system. The default group is the root directory. Other groups may be -created as desired by the system administrator using the "mkdir(1)" -command, and removed using "rmdir(1)". +system. The default group is the root directory which, immediately +after mounting, owns all the tasks and cpus in the system and can make +full use of all resources. -There are three files associated with each group: +On a system with RDT control features additional directories can be +created in the root directory that specify different amounts of each +resource (see "schemata" below). The root and these additional top level +directories are referred to as "CTRL_MON" groups below. -"tasks": A list of tasks that belongs to this group. Tasks can be - added to a group by writing the task ID to the "tasks" file - (which will automatically remove them from the previous - group to which they belonged). New tasks created by fork(2) - and clone(2) are added to the same group as their parent. - If a pid is not in any sub partition, it is in root partition - (i.e. default partition). +On a system with RDT monitoring the root directory and other top level +directories contain a directory named "mon_groups" in which additional +directories can be created to monitor subsets of tasks in the CTRL_MON +group that is their ancestor. These are called "MON" groups in the rest +of this document. -"cpus": A bitmask of logical CPUs assigned to this group. Writing - a new mask can add/remove CPUs from this group. Added CPUs - are removed from their previous group. Removed ones are - given to the default (root) group. You cannot remove CPUs - from the default group. +Removing a directory will move all tasks and cpus owned by the group it +represents to the parent. Removing one of the created CTRL_MON groups +will automatically remove all MON groups below it. -"cpus_list": One or more CPU ranges of logical CPUs assigned to this - group. Same rules apply like for the "cpus" file. +All groups contain the following files: -"schemata": A list of all the resources available to this group. - Each resource has its own line and format - see below for - details. +"tasks": + Reading this file shows the list of all tasks that belong to + this group. Writing a task id to the file will add a task to the + group. If the group is a CTRL_MON group the task is removed from + whichever previous CTRL_MON group owned the task and also from + any MON group that owned the task. If the group is a MON group, + then the task must already belong to the CTRL_MON parent of this + group. The task is removed from any previous MON group. -When a task is running the following rules define which resources -are available to it: + +"cpus": + Reading this file shows a bitmask of the logical CPUs owned by + this group. Writing a mask to this file will add and remove + CPUs to/from this group. As with the tasks file a hierarchy is + maintained where MON groups may only include CPUs owned by the + parent CTRL_MON group. + + +"cpus_list": + Just like "cpus", only using ranges of CPUs instead of bitmasks. + + +When control is enabled all CTRL_MON groups will also contain: + +"schemata": + A list of all the resources available to this group. + Each resource has its own line and format - see below for details. + +When monitoring is enabled all MON groups will also contain: + +"mon_data": + This contains a set of files organized by L3 domain and by + RDT event. E.g. on a system with two L3 domains there will + be subdirectories "mon_L3_00" and "mon_L3_01". Each of these + directories have one file per event (e.g. "llc_occupancy", + "mbm_total_bytes", and "mbm_local_bytes"). In a MON group these + files provide a read out of the current value of the event for + all tasks in the group. In CTRL_MON groups these files provide + the sum for all tasks in the CTRL_MON group and all tasks in + MON groups. Please see example section for more details on usage. + +Resource allocation rules +------------------------- +When a task is running the following rules define which resources are +available to it: 1) If the task is a member of a non-default group, then the schemata -for that group is used. + for that group is used. 2) Else if the task belongs to the default group, but is running on a -CPU that is assigned to some specific group, then the schemata for -the CPU's group is used. + CPU that is assigned to some specific group, then the schemata for the + CPU's group is used. 3) Otherwise the schemata for the default group is used. +Resource monitoring rules +------------------------- +1) If a task is a member of a MON group, or non-default CTRL_MON group + then RDT events for the task will be reported in that group. + +2) If a task is a member of the default CTRL_MON group, but is running + on a CPU that is assigned to some specific group, then the RDT events + for the task will be reported in that group. + +3) Otherwise RDT events for the task will be reported in the root level + "mon_data" group. + + +Notes on cache occupancy monitoring and control +----------------------------------------------- +When moving a task from one group to another you should remember that +this only affects *new* cache allocations by the task. E.g. you may have +a task in a monitor group showing 3 MB of cache occupancy. If you move +to a new group and immediately check the occupancy of the old and new +groups you will likely see that the old group is still showing 3 MB and +the new group zero. When the task accesses locations still in cache from +before the move, the h/w does not update any counters. On a busy system +you will likely see the occupancy in the old group go down as cache lines +are evicted and re-used while the occupancy in the new group rises as +the task accesses memory and loads into the cache are counted based on +membership in the new group. + +The same applies to cache allocation control. Moving a task to a group +with a smaller cache partition will not evict any cache lines. The +process may continue to use them from the old partition. + +Hardware uses CLOSid(Class of service ID) and an RMID(Resource monitoring ID) +to identify a control group and a monitoring group respectively. Each of +the resource groups are mapped to these IDs based on the kind of group. The +number of CLOSid and RMID are limited by the hardware and hence the creation of +a "CTRL_MON" directory may fail if we run out of either CLOSID or RMID +and creation of "MON" group may fail if we run out of RMIDs. + +max_threshold_occupancy - generic concepts +------------------------------------------ + +Note that an RMID once freed may not be immediately available for use as +the RMID is still tagged the cache lines of the previous user of RMID. +Hence such RMIDs are placed on limbo list and checked back if the cache +occupancy has gone down. If there is a time when system has a lot of +limbo RMIDs but which are not ready to be used, user may see an -EBUSY +during mkdir. + +max_threshold_occupancy is a user configurable value to determine the +occupancy at which an RMID can be freed. Schemata files - general concepts --------------------------------- @@ -143,22 +267,22 @@ SKUs. Using a high bandwidth and a low bandwidth setting on two threads sharing a core will result in both threads being throttled to use the low bandwidth. -L3 details (code and data prioritization disabled) --------------------------------------------------- +L3 schemata file details (code and data prioritization disabled) +---------------------------------------------------------------- With CDP disabled the L3 schemata format is: L3:=;=;... -L3 details (CDP enabled via mount option to resctrl) ----------------------------------------------------- +L3 schemata file details (CDP enabled via mount option to resctrl) +------------------------------------------------------------------ When CDP is enabled L3 control is split into two separate resources so you can specify independent masks for code and data like this: L3data:=;=;... L3code:=;=;... -L2 details ----------- +L2 schemata file details +------------------------ L2 cache does not support code and data prioritization, so the schemata format is always: @@ -185,6 +309,8 @@ L3CODE:0=fffff;1=fffff;2=fffff;3=fffff L3DATA:0=fffff;1=fffff;2=3c0;3=fffff L3CODE:0=fffff;1=fffff;2=fffff;3=fffff +Examples for RDT allocation usage: + Example 1 --------- On a two socket machine (one L3 cache per socket) with just four bits @@ -410,3 +536,124 @@ void main(void) /* code to read and write directory contents */ resctrl_release_lock(fd); } + +Examples for RDT Monitoring along with allocation usage: + +Reading monitored data +---------------------- +Reading an event file (for ex: mon_data/mon_L3_00/llc_occupancy) would +show the current snapshot of LLC occupancy of the corresponding MON +group or CTRL_MON group. + + +Example 1 (Monitor CTRL_MON group and subset of tasks in CTRL_MON group) +--------- +On a two socket machine (one L3 cache per socket) with just four bits +for cache bit masks + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir p0 p1 +# echo "L3:0=3;1=c" > /sys/fs/resctrl/p0/schemata +# echo "L3:0=3;1=3" > /sys/fs/resctrl/p1/schemata +# echo 5678 > p1/tasks +# echo 5679 > p1/tasks + +The default resource group is unmodified, so we have access to all parts +of all caches (its schemata file reads "L3:0=f;1=f"). + +Tasks that are under the control of group "p0" may only allocate from the +"lower" 50% on cache ID 0, and the "upper" 50% of cache ID 1. +Tasks in group "p1" use the "lower" 50% of cache on both sockets. + +Create monitor groups and assign a subset of tasks to each monitor group. + +# cd /sys/fs/resctrl/p1/mon_groups +# mkdir m11 m12 +# echo 5678 > m11/tasks +# echo 5679 > m12/tasks + +fetch data (data shown in bytes) + +# cat m11/mon_data/mon_L3_00/llc_occupancy +16234000 +# cat m11/mon_data/mon_L3_01/llc_occupancy +14789000 +# cat m12/mon_data/mon_L3_00/llc_occupancy +16789000 + +The parent ctrl_mon group shows the aggregated data. + +# cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy +31234000 + +Example 2 (Monitor a task from its creation) +--------- +On a two socket machine (one L3 cache per socket) + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir p0 p1 + +An RMID is allocated to the group once its created and hence the +below is monitored from its creation. + +# echo $$ > /sys/fs/resctrl/p1/tasks +# + +Fetch the data + +# cat /sys/fs/resctrl/p1/mon_data/mon_l3_00/llc_occupancy +31789000 + +Example 3 (Monitor without CAT support or before creating CAT groups) +--------- + +Assume a system like HSW has only CQM and no CAT support. In this case +the resctrl will still mount but cannot create CTRL_MON directories. +But user can create different MON groups within the root group thereby +able to monitor all tasks including kernel threads. + +This can also be used to profile jobs cache size footprint before being +able to allocate them to different allocation groups. + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir mon_groups/m01 +# mkdir mon_groups/m02 + +# echo 3478 > /sys/fs/resctrl/mon_groups/m01/tasks +# echo 2467 > /sys/fs/resctrl/mon_groups/m02/tasks + +Monitor the groups separately and also get per domain data. From the +below its apparent that the tasks are mostly doing work on +domain(socket) 0. + +# cat /sys/fs/resctrl/mon_groups/m01/mon_L3_00/llc_occupancy +31234000 +# cat /sys/fs/resctrl/mon_groups/m01/mon_L3_01/llc_occupancy +34555 +# cat /sys/fs/resctrl/mon_groups/m02/mon_L3_00/llc_occupancy +31234000 +# cat /sys/fs/resctrl/mon_groups/m02/mon_L3_01/llc_occupancy +32789 + + +Example 4 (Monitor real time tasks) +----------------------------------- + +A single socket system which has real time tasks running on cores 4-7 +and non real time tasks on other cpus. We want to monitor the cache +occupancy of the real time threads on these cores. + +# mount -t resctrl resctrl /sys/fs/resctrl +# cd /sys/fs/resctrl +# mkdir p1 + +Move the cpus 4-7 over to p1 +# echo f0 > p0/cpus + +View the llc occupancy snapshot + +# cat /sys/fs/resctrl/p1/mon_data/mon_L3_00/llc_occupancy +11234000 diff --git a/Documentation/x86/microcode.txt b/Documentation/x86/microcode.txt new file mode 100644 index 000000000000..f57e1b45e628 --- /dev/null +++ b/Documentation/x86/microcode.txt @@ -0,0 +1,137 @@ + The Linux Microcode Loader + +Authors: Fenghua Yu + Borislav Petkov + +The kernel has a x86 microcode loading facility which is supposed to +provide microcode loading methods in the OS. Potential use cases are +updating the microcode on platforms beyond the OEM End-Of-Life support, +and updating the microcode on long-running systems without rebooting. + +The loader supports three loading methods: + +1. Early load microcode +======================= + +The kernel can update microcode very early during boot. Loading +microcode early can fix CPU issues before they are observed during +kernel boot time. + +The microcode is stored in an initrd file. During boot, it is read from +it and loaded into the CPU cores. + +The format of the combined initrd image is microcode in (uncompressed) +cpio format followed by the (possibly compressed) initrd image. The +loader parses the combined initrd image during boot. + +The microcode files in cpio name space are: + +on Intel: kernel/x86/microcode/GenuineIntel.bin +on AMD : kernel/x86/microcode/AuthenticAMD.bin + +During BSP (BootStrapping Processor) boot (pre-SMP), the kernel +scans the microcode file in the initrd. If microcode matching the +CPU is found, it will be applied in the BSP and later on in all APs +(Application Processors). + +The loader also saves the matching microcode for the CPU in memory. +Thus, the cached microcode patch is applied when CPUs resume from a +sleep state. + +Here's a crude example how to prepare an initrd with microcode (this is +normally done automatically by the distribution, when recreating the +initrd, so you don't really have to do it yourself. It is documented +here for future reference only). + +--- + #!/bin/bash + + if [ -z "$1" ]; then + echo "You need to supply an initrd file" + exit 1 + fi + + INITRD="$1" + + DSTDIR=kernel/x86/microcode + TMPDIR=/tmp/initrd + + rm -rf $TMPDIR + + mkdir $TMPDIR + cd $TMPDIR + mkdir -p $DSTDIR + + if [ -d /lib/firmware/amd-ucode ]; then + cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin + fi + + if [ -d /lib/firmware/intel-ucode ]; then + cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin + fi + + find . | cpio -o -H newc >../ucode.cpio + cd .. + mv $INITRD $INITRD.orig + cat ucode.cpio $INITRD.orig > $INITRD + + rm -rf $TMPDIR +--- + +The system needs to have the microcode packages installed into +/lib/firmware or you need to fixup the paths above if yours are +somewhere else and/or you've downloaded them directly from the processor +vendor's site. + +2. Late loading +=============== + +There are two legacy user space interfaces to load microcode, either through +/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file +in sysfs. + +The /dev/cpu/microcode method is deprecated because it needs a special +userspace tool for that. + +The easier method is simply installing the microcode packages your distro +supplies and running: + +# echo 1 > /sys/devices/system/cpu/microcode/reload + +as root. + +The loading mechanism looks for microcode blobs in +/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation +packages already put them there. + +3. Builtin microcode +==================== + +The loader supports also loading of a builtin microcode supplied through +the regular firmware builtin method CONFIG_FIRMWARE_IN_KERNEL. Only +64-bit is currently supported. + +Here's an example: + +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" +CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" + +This basically means, you have the following tree structure locally: + +/lib/firmware/ +|-- amd-ucode +... +| |-- microcode_amd_fam15h.bin +... +|-- intel-ucode +... +| |-- 06-3a-09 +... + +so that the build system can find those files and integrate them into +the final kernel image. The early loader finds them and applies them. + +Needless to say, this method is not the most flexible one because it +requires rebuilding the kernel each time updated microcode from the CPU +vendor is available. diff --git a/Documentation/x86/orc-unwinder.txt b/Documentation/x86/orc-unwinder.txt new file mode 100644 index 000000000000..af0c9a4c65a6 --- /dev/null +++ b/Documentation/x86/orc-unwinder.txt @@ -0,0 +1,179 @@ +ORC unwinder +============ + +Overview +-------- + +The kernel CONFIG_ORC_UNWINDER option enables the ORC unwinder, which is +similar in concept to a DWARF unwinder. The difference is that the +format of the ORC data is much simpler than DWARF, which in turn allows +the ORC unwinder to be much simpler and faster. + +The ORC data consists of unwind tables which are generated by objtool. +They contain out-of-band data which is used by the in-kernel ORC +unwinder. Objtool generates the ORC data by first doing compile-time +stack metadata validation (CONFIG_STACK_VALIDATION). After analyzing +all the code paths of a .o file, it determines information about the +stack state at each instruction address in the file and outputs that +information to the .orc_unwind and .orc_unwind_ip sections. + +The per-object ORC sections are combined at link time and are sorted and +post-processed at boot time. The unwinder uses the resulting data to +correlate instruction addresses with their stack states at run time. + + +ORC vs frame pointers +--------------------- + +With frame pointers enabled, GCC adds instrumentation code to every +function in the kernel. The kernel's .text size increases by about +3.2%, resulting in a broad kernel-wide slowdown. Measurements by Mel +Gorman [1] have shown a slowdown of 5-10% for some workloads. + +In contrast, the ORC unwinder has no effect on text size or runtime +performance, because the debuginfo is out of band. So if you disable +frame pointers and enable the ORC unwinder, you get a nice performance +improvement across the board, and still have reliable stack traces. + +Ingo Molnar says: + + "Note that it's not just a performance improvement, but also an + instruction cache locality improvement: 3.2% .text savings almost + directly transform into a similarly sized reduction in cache + footprint. That can transform to even higher speedups for workloads + whose cache locality is borderline." + +Another benefit of ORC compared to frame pointers is that it can +reliably unwind across interrupts and exceptions. Frame pointer based +unwinds can sometimes skip the caller of the interrupted function, if it +was a leaf function or if the interrupt hit before the frame pointer was +saved. + +The main disadvantage of the ORC unwinder compared to frame pointers is +that it needs more memory to store the ORC unwind tables: roughly 2-4MB +depending on the kernel config. + + +ORC vs DWARF +------------ + +ORC debuginfo's advantage over DWARF itself is that it's much simpler. +It gets rid of the complex DWARF CFI state machine and also gets rid of +the tracking of unnecessary registers. This allows the unwinder to be +much simpler, meaning fewer bugs, which is especially important for +mission critical oops code. + +The simpler debuginfo format also enables the unwinder to be much faster +than DWARF, which is important for perf and lockdep. In a basic +performance test by Jiri Slaby [2], the ORC unwinder was about 20x +faster than an out-of-tree DWARF unwinder. (Note: That measurement was +taken before some performance tweaks were added, which doubled +performance, so the speedup over DWARF may be closer to 40x.) + +The ORC data format does have a few downsides compared to DWARF. ORC +unwind tables take up ~50% more RAM (+1.3MB on an x86 defconfig kernel) +than DWARF-based eh_frame tables. + +Another potential downside is that, as GCC evolves, it's conceivable +that the ORC data may end up being *too* simple to describe the state of +the stack for certain optimizations. But IMO this is unlikely because +GCC saves the frame pointer for any unusual stack adjustments it does, +so I suspect we'll really only ever need to keep track of the stack +pointer and the frame pointer between call frames. But even if we do +end up having to track all the registers DWARF tracks, at least we will +still be able to control the format, e.g. no complex state machines. + + +ORC unwind table generation +--------------------------- + +The ORC data is generated by objtool. With the existing compile-time +stack metadata validation feature, objtool already follows all code +paths, and so it already has all the information it needs to be able to +generate ORC data from scratch. So it's an easy step to go from stack +validation to ORC data generation. + +It should be possible to instead generate the ORC data with a simple +tool which converts DWARF to ORC data. However, such a solution would +be incomplete due to the kernel's extensive use of asm, inline asm, and +special sections like exception tables. + +That could be rectified by manually annotating those special code paths +using GNU assembler .cfi annotations in .S files, and homegrown +annotations for inline asm in .c files. But asm annotations were tried +in the past and were found to be unmaintainable. They were often +incorrect/incomplete and made the code harder to read and keep updated. +And based on looking at glibc code, annotating inline asm in .c files +might be even worse. + +Objtool still needs a few annotations, but only in code which does +unusual things to the stack like entry code. And even then, far fewer +annotations are needed than what DWARF would need, so they're much more +maintainable than DWARF CFI annotations. + +So the advantages of using objtool to generate ORC data are that it +gives more accurate debuginfo, with very few annotations. It also +insulates the kernel from toolchain bugs which can be very painful to +deal with in the kernel since we often have to workaround issues in +older versions of the toolchain for years. + +The downside is that the unwinder now becomes dependent on objtool's +ability to reverse engineer GCC code flow. If GCC optimizations become +too complicated for objtool to follow, the ORC data generation might +stop working or become incomplete. (It's worth noting that livepatch +already has such a dependency on objtool's ability to follow GCC code +flow.) + +If newer versions of GCC come up with some optimizations which break +objtool, we may need to revisit the current implementation. Some +possible solutions would be asking GCC to make the optimizations more +palatable, or having objtool use DWARF as an additional input, or +creating a GCC plugin to assist objtool with its analysis. But for now, +objtool follows GCC code quite well. + + +Unwinder implementation details +------------------------------- + +Objtool generates the ORC data by integrating with the compile-time +stack metadata validation feature, which is described in detail in +tools/objtool/Documentation/stack-validation.txt. After analyzing all +the code paths of a .o file, it creates an array of orc_entry structs, +and a parallel array of instruction addresses associated with those +structs, and writes them to the .orc_unwind and .orc_unwind_ip sections +respectively. + +The ORC data is split into the two arrays for performance reasons, to +make the searchable part of the data (.orc_unwind_ip) more compact. The +arrays are sorted in parallel at boot time. + +Performance is further improved by the use of a fast lookup table which +is created at runtime. The fast lookup table associates a given address +with a range of indices for the .orc_unwind table, so that only a small +subset of the table needs to be searched. + + +Etymology +--------- + +Orcs, fearsome creatures of medieval folklore, are the Dwarves' natural +enemies. Similarly, the ORC unwinder was created in opposition to the +complexity and slowness of DWARF. + +"Although Orcs rarely consider multiple solutions to a problem, they do +excel at getting things done because they are creatures of action, not +thought." [3] Similarly, unlike the esoteric DWARF unwinder, the +veracious ORC unwinder wastes no time or siloconic effort decoding +variable-length zero-extended unsigned-integer byte-coded +state-machine-based debug information entries. + +Similar to how Orcs frequently unravel the well-intentioned plans of +their adversaries, the ORC unwinder frequently unravels stacks with +brutal, unyielding efficiency. + +ORC stands for Oops Rewind Capability. + + +[1] https://lkml.kernel.org/r/20170602104048.jkkzssljsompjdwy@suse.de +[2] https://lkml.kernel.org/r/d2ca5435-6386-29b8-db87-7f227c2b713a@suse.cz +[3] http://dustin.wikidot.com/half-orcs-and-orcs diff --git a/Documentation/x86/protection-keys.txt b/Documentation/x86/protection-keys.txt index b64304540821..fa46dcb347bc 100644 --- a/Documentation/x86/protection-keys.txt +++ b/Documentation/x86/protection-keys.txt @@ -34,7 +34,7 @@ with a key. In this example WRPKRU is wrapped by a C function called pkey_set(). int real_prot = PROT_READ|PROT_WRITE; - pkey = pkey_alloc(0, PKEY_DENY_WRITE); + pkey = pkey_alloc(0, PKEY_DISABLE_WRITE); ptr = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); ret = pkey_mprotect(ptr, PAGE_SIZE, real_prot, pkey); ... application runs here @@ -42,9 +42,9 @@ called pkey_set(). Now, if the application needs to update the data at 'ptr', it can gain access, do the update, then remove its write access: - pkey_set(pkey, 0); // clear PKEY_DENY_WRITE + pkey_set(pkey, 0); // clear PKEY_DISABLE_WRITE *ptr = foo; // assign something - pkey_set(pkey, PKEY_DENY_WRITE); // set PKEY_DENY_WRITE again + pkey_set(pkey, PKEY_DISABLE_WRITE); // set PKEY_DISABLE_WRITE again Now when it frees the memory, it will also free the pkey since it is no longer in use: diff --git a/Documentation/x86/x86_64/5level-paging.txt b/Documentation/x86/x86_64/5level-paging.txt new file mode 100644 index 000000000000..087251a0d99c --- /dev/null +++ b/Documentation/x86/x86_64/5level-paging.txt @@ -0,0 +1,64 @@ +== Overview == + +Original x86-64 was limited by 4-level paing to 256 TiB of virtual address +space and 64 TiB of physical address space. We are already bumping into +this limit: some vendors offers servers with 64 TiB of memory today. + +To overcome the limitation upcoming hardware will introduce support for +5-level paging. It is a straight-forward extension of the current page +table structure adding one more layer of translation. + +It bumps the limits to 128 PiB of virtual address space and 4 PiB of +physical address space. This "ought to be enough for anybody" ©. + +QEMU 2.9 and later support 5-level paging. + +Virtual memory layout for 5-level paging is described in +Documentation/x86/x86_64/mm.txt + +== Enabling 5-level paging == + +CONFIG_X86_5LEVEL=y enables the feature. + +So far, a kernel compiled with the option enabled will be able to boot +only on machines that supports the feature -- see for 'la57' flag in +/proc/cpuinfo. + +The plan is to implement boot-time switching between 4- and 5-level paging +in the future. + +== User-space and large virtual address space == + +On x86, 5-level paging enables 56-bit userspace virtual address space. +Not all user space is ready to handle wide addresses. It's known that +at least some JIT compilers use higher bits in pointers to encode their +information. It collides with valid pointers with 5-level paging and +leads to crashes. + +To mitigate this, we are not going to allocate virtual address space +above 47-bit by default. + +But userspace can ask for allocation from full address space by +specifying hint address (with or without MAP_FIXED) above 47-bits. + +If hint address set above 47-bit, but MAP_FIXED is not specified, we try +to look for unmapped area by specified address. If it's already +occupied, we look for unmapped area in *full* address space, rather than +from 47-bit window. + +A high hint address would only affect the allocation in question, but not +any future mmap()s. + +Specifying high hint address on older kernel or on machine without 5-level +paging support is safe. The hint will be ignored and kernel will fall back +to allocation from 47-bit address space. + +This approach helps to easily make application's memory allocator aware +about large address space without manually tracking allocated virtual +address space. + +One important case we need to handle here is interaction with MPX. +MPX (without MAWA extension) cannot handle addresses above 47-bit, so we +need to make sure that MPX cannot be enabled we already have VMA above +the boundary and forbid creating such VMAs once MPX is enabled. + diff --git a/Kbuild b/Kbuild index 94c752762bc2..af161aa1facd 100644 --- a/Kbuild +++ b/Kbuild @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Kbuild for top-level directory of the kernel # This file takes care of the following: diff --git a/Kconfig b/Kconfig index c13f48d65898..8c4c1cb0f9cd 100644 --- a/Kconfig +++ b/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. diff --git a/MAINTAINERS b/MAINTAINERS index 1c3feffb1c1c..2811a211632c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -301,6 +301,7 @@ S: Supported F: drivers/acpi/ F: drivers/pnp/pnpacpi/ F: include/linux/acpi.h +F: include/linux/fwnode.h F: include/acpi/ F: Documentation/acpi/ F: Documentation/ABI/testing/sysfs-bus-acpi @@ -310,6 +311,14 @@ F: drivers/pci/*/*acpi* F: drivers/pci/*/*/*acpi* F: tools/power/acpi/ +ACPI APEI +M: "Rafael J. Wysocki" +M: Len Brown +L: linux-acpi@vger.kernel.org +R: Tony Luck +R: Borislav Petkov +F: drivers/acpi/apei/ + ACPI COMPONENT ARCHITECTURE (ACPICA) M: Robert Moore M: Lv Zheng @@ -343,6 +352,18 @@ L: linux-acpi@vger.kernel.org S: Maintained F: drivers/acpi/arm64 +ACPI PMIC DRIVERS +M: "Rafael J. Wysocki" +M: Len Brown +R: Andy Shevchenko +R: Mika Westerberg +L: linux-acpi@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-acpi/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm +B: https://bugzilla.kernel.org +S: Supported +F: drivers/acpi/pmic/ + ACPI THERMAL DRIVER M: Zhang Rui L: linux-acpi@vger.kernel.org @@ -635,6 +656,11 @@ ALPS PS/2 TOUCHPAD DRIVER R: Pali Rohár F: drivers/input/mouse/alps.* +ALTERA I2C CONTROLLER DRIVER +M: Thor Thayer +S: Maintained +F: drivers/i2c/busses/i2c-altera.c + ALTERA MAILBOX DRIVER M: Ley Foon Tan L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) @@ -769,6 +795,12 @@ W: http://ez.analog.com/community/linux-device-drivers S: Supported F: drivers/media/i2c/adv7180.c +ANALOG DEVICES INC ADV748X DRIVER +M: Kieran Bingham +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/i2c/adv748x/* + ANALOG DEVICES INC ADV7511 DRIVER M: Hans Verkuil L: linux-media@vger.kernel.org @@ -840,6 +872,12 @@ S: Supported F: drivers/android/ F: drivers/staging/android/ +ANDROID GOLDFISH RTC DRIVER +M: Miodrag Dinic +S: Supported +F: Documentation/devicetree/bindings/rtc/google,goldfish-rtc.txt +F: drivers/rtc/rtc-goldfish.c + ANDROID ION DRIVER M: Laura Abbott M: Sumit Semwal @@ -1153,6 +1191,7 @@ L: linux-arm-kernel@axis.com F: arch/arm/mach-artpec F: arch/arm/boot/dts/artpec6* F: drivers/clk/axis +F: drivers/crypto/axis F: drivers/pinctrl/pinctrl-artpec* F: Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt @@ -1282,10 +1321,15 @@ S: Maintained ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE M: Hans Ulli Kroll +M: Linus Walleij L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://github.com/ulli-kroll/linux.git S: Maintained +F: Documentation/devicetree/bindings/arm/gemini.txt +F: Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt +F: Documentation/devicetree/bindings/rtc/faraday,ftrtc010.txt F: arch/arm/mach-gemini/ +F: drivers/pinctrl/pinctrl-gemini.c F: drivers/rtc/rtc-ftrtc010.c ARM/CSR SIRFPRIMA2 MACHINE SUPPORT @@ -1570,7 +1614,7 @@ M: Chunfeng Yun L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) S: Maintained -F: drivers/phy/phy-mt65xx-usb3.c +F: drivers/phy/mediatek/phy-mtk-tphy.c ARM/MICREL KS8695 ARCHITECTURE M: Greg Ungerer @@ -1993,6 +2037,7 @@ F: arch/arm64/boot/dts/socionext/ F: drivers/bus/uniphier-system-bus.c F: drivers/clk/uniphier/ F: drivers/i2c/busses/i2c-uniphier* +F: drivers/irqchip/irq-uniphier-aidet.c F: drivers/pinctrl/uniphier/ F: drivers/reset/reset-uniphier.c F: drivers/tty/serial/8250/8250_uniphier.c @@ -2079,17 +2124,38 @@ F: arch/arm/mach-pxa/include/mach/z2.h ARM/ZTE ARCHITECTURE M: Jun Nie M: Baoyou Xie +M: Shawn Guo L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +F: arch/arm/boot/dts/zx2967* F: arch/arm/mach-zx/ +F: arch/arm64/boot/dts/zte/ F: drivers/clk/zte/ +F: drivers/dma/zx_dma.c +F: drivers/gpio/gpio-zx.c +F: drivers/i2c/busses/i2c-zx2967.c +F: drivers/mmc/host/dw_mmc-zx.* +F: drivers/pinctrl/zte/ F: drivers/reset/reset-zx2967.c F: drivers/soc/zte/ +F: drivers/thermal/zx2967_thermal.c +F: drivers/watchdog/zx2967_wdt.c F: Documentation/devicetree/bindings/arm/zte.txt -F: Documentation/devicetree/bindings/clock/zx296702-clk.txt +F: Documentation/devicetree/bindings/clock/zx2967*.txt +F: Documentation/devicetree/bindings/dma/zxdma.txt +F: Documentation/devicetree/bindings/gpio/zx296702-gpio.txt +F: Documentation/devicetree/bindings/i2c/i2c-zx2967.txt +F: Documentation/devicetree/bindings/mmc/zx-dw-mshc.txt +F: Documentation/devicetree/bindings/pinctrl/pinctrl-zx.txt F: Documentation/devicetree/bindings/reset/zte,zx2967-reset.txt F: Documentation/devicetree/bindings/soc/zte/ -F: include/dt-bindings/soc/zx*.h +F: Documentation/devicetree/bindings/sound/zte,*.txt +F: Documentation/devicetree/bindings/thermal/zx2967-thermal.txt +F: Documentation/devicetree/bindings/watchdog/zte,zx2967-wdt.txt +F: include/dt-bindings/clock/zx2967*.h +F: include/dt-bindings/soc/zte,*.h +F: sound/soc/codecs/zx_aud96p22.c +F: sound/soc/zte/ ARM/ZYNQ ARCHITECTURE M: Michal Simek @@ -2117,6 +2183,12 @@ S: Maintained F: arch/arm64/ F: Documentation/arm64/ +AS3645A LED FLASH CONTROLLER DRIVER +M: Sakari Ailus +L: linux-leds@vger.kernel.org +S: Maintained +F: drivers/leds/leds-as3645a.c + AS3645A LED FLASH CONTROLLER DRIVER M: Laurent Pinchart L: linux-media@vger.kernel.org @@ -2385,9 +2457,10 @@ AUDIT SUBSYSTEM M: Paul Moore M: Eric Paris L: linux-audit@redhat.com (moderated for non-subscribers) -W: http://people.redhat.com/sgrubb/audit/ -T: git git://git.infradead.org/users/pcmoore/audit -S: Maintained +W: https://github.com/linux-audit +W: https://people.redhat.com/sgrubb/audit +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git +S: Supported F: include/linux/audit.h F: include/uapi/linux/audit.h F: kernel/audit* @@ -2477,7 +2550,7 @@ Q: https://patchwork.open-mesh.org/project/batman/list/ S: Maintained F: Documentation/ABI/testing/sysfs-class-net-batman-adv F: Documentation/ABI/testing/sysfs-class-net-mesh -F: Documentation/networking/batman-adv.txt +F: Documentation/networking/batman-adv.rst F: include/uapi/linux/batman_adv.h F: net/batman-adv/ @@ -2546,13 +2619,6 @@ W: http://blackfin.uclinux.org S: Supported F: drivers/net/ethernet/adi/ -BLACKFIN I2C TWI DRIVER -M: Sonic Zhang -L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) -W: http://blackfin.uclinux.org/ -S: Supported -F: drivers/i2c/busses/i2c-bfin-twi.c - BLACKFIN MEDIA DRIVER M: Scott Jiang L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) @@ -2569,14 +2635,12 @@ S: Supported F: drivers/rtc/rtc-bfin.c BLACKFIN SDH DRIVER -M: Sonic Zhang L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) W: http://blackfin.uclinux.org S: Supported F: drivers/mmc/host/bfin_sdh.c BLACKFIN SERIAL DRIVER -M: Sonic Zhang L: adi-buildroot-devel@lists.sourceforge.net (moderated for non-subscribers) W: http://blackfin.uclinux.org S: Supported @@ -2801,7 +2865,6 @@ S: Supported F: drivers/scsi/bnx2i/ BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER -M: Yuval Mintz M: Ariel Elior M: everest-linux-l2@cavium.com L: netdev@vger.kernel.org @@ -3155,6 +3218,7 @@ S: Supported F: drivers/crypto/cavium/cpt/ CAVIUM THUNDERX2 ARM64 SOC +M: Robert Richter M: Jayachandran C L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained @@ -4108,7 +4172,9 @@ F: include/linux/dax.h F: include/trace/events/fs_dax.h DIRECTORY NOTIFICATION (DNOTIFY) -M: Eric Paris +M: Jan Kara +R: Amir Goldstein +L: linux-fsdevel@vger.kernel.org S: Maintained F: Documentation/filesystems/dnotify.txt F: fs/notify/dnotify/ @@ -4175,7 +4241,7 @@ DMA MAPPING HELPERS M: Christoph Hellwig M: Marek Szyprowski R: Robin Murphy -L: linux-kernel@vger.kernel.org +L: iommu@lists.linux-foundation.org T: git git://git.infradead.org/users/hch/dma-mapping.git W: http://git.infradead.org/users/hch/dma-mapping.git S: Supported @@ -4341,6 +4407,12 @@ S: Supported F: drivers/gpu/drm/nouveau/ F: include/uapi/drm/nouveau_drm.h +DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS +M: Noralf Trønnes +S: Maintained +F: drivers/gpu/drm/tinydrm/repaper.c +F: Documentation/devicetree/bindings/display/repaper.txt + DRM DRIVER FOR QEMU'S CIRRUS DEVICE M: Dave Airlie M: Gerd Hoffmann @@ -4374,6 +4446,12 @@ S: Orphan / Obsolete F: drivers/gpu/drm/sis/ F: include/uapi/drm/sis_drm.h +DRM DRIVER FOR SITRONIX ST7586 PANELS +M: David Lechner +S: Maintained +F: drivers/gpu/drm/tinydrm/st7586.c +F: Documentation/devicetree/bindings/display/st7586.txt + DRM DRIVER FOR TDFX VIDEO CARDS S: Orphan / Obsolete F: drivers/gpu/drm/tdfx/ @@ -4622,6 +4700,14 @@ F: drivers/gpu/drm/panel/ F: include/drm/drm_panel.h F: Documentation/devicetree/bindings/display/panel/ +DRM TINYDRM DRIVERS +M: Noralf Trønnes +W: https://github.com/notro/tinydrm/wiki/Development +T: git git://anongit.freedesktop.org/drm/drm-misc +S: Maintained +F: drivers/gpu/drm/tinydrm/ +F: include/drm/tinydrm/ + DSBR100 USB FM RADIO DRIVER M: Alexey Klimov L: linux-media@vger.kernel.org @@ -5101,6 +5187,7 @@ F: include/linux/of_net.h F: include/linux/phy.h F: include/linux/phy_fixed.h F: include/linux/platform_data/mdio-gpio.h +F: include/linux/platform_data/mdio-bcm-unimac.h F: include/trace/events/mdio.h F: include/uapi/linux/mdio.h F: include/uapi/linux/mii.h @@ -5172,7 +5259,8 @@ S: Maintained F: drivers/iommu/exynos-iommu.c EZchip NPS platform support -M: Noam Camus +M: Elad Kanfi +M: Vineet Gupta S: Supported F: arch/arc/plat-eznps F: arch/arc/boot/dts/eznps.dts @@ -5198,7 +5286,9 @@ F: Documentation/hwmon/f71805f F: drivers/hwmon/f71805f.c FANOTIFY -M: Eric Paris +M: Jan Kara +R: Amir Goldstein +L: linux-fsdevel@vger.kernel.org S: Maintained F: fs/notify/fanotify/ F: include/linux/fanotify.h @@ -5256,9 +5346,7 @@ M: "J. Bruce Fields" L: linux-fsdevel@vger.kernel.org S: Maintained F: include/linux/fcntl.h -F: include/linux/fs.h F: include/uapi/linux/fcntl.h -F: include/uapi/linux/fs.h F: fs/fcntl.c F: fs/locks.c @@ -5267,6 +5355,8 @@ M: Alexander Viro L: linux-fsdevel@vger.kernel.org S: Maintained F: fs/* +F: include/linux/fs.h +F: include/uapi/linux/fs.h FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: Riku Voipio @@ -5341,10 +5431,11 @@ K: fmc_d.*register FPGA MANAGER FRAMEWORK M: Alan Tull -R: Moritz Fischer +R: Moritz Fischer L: linux-fpga@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git +Q: http://patchwork.kernel.org/project/linux-fpga/list/ F: Documentation/fpga/ F: Documentation/devicetree/bindings/fpga/ F: drivers/fpga/ @@ -5763,6 +5854,12 @@ S: Maintained F: Documentation/acpi/gpio-properties.txt F: drivers/gpio/gpiolib-acpi.c +GPIO IR Transmitter +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/gpio-ir-tx.c + GPIO MOCKUP DRIVER M: Bamvor Jian Zhang L: linux-gpio@vger.kernel.org @@ -6032,16 +6129,6 @@ F: drivers/scsi/hpsa*.[ch] F: include/linux/cciss*.h F: include/uapi/linux/cciss*.h -HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) -M: Don Brace -L: esc.storagedev@microsemi.com -L: linux-scsi@vger.kernel.org -S: Supported -F: Documentation/blockdev/cciss.txt -F: drivers/block/cciss* -F: include/linux/cciss_ioctl.h -F: include/uapi/linux/cciss_ioctl.h - HFI1 DRIVER M: Mike Marciniszyn M: Dennis Dalessandro @@ -6138,6 +6225,14 @@ F: include/uapi/linux/if_hippi.h F: net/802/hippi.c F: drivers/net/hippi/ +HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) +M: Yisen Zhuang +M: Salil Mehta +L: netdev@vger.kernel.org +W: http://www.hisilicon.com +S: Maintained +F: drivers/net/ethernet/hisilicon/hns3/ + HISILICON NETWORK SUBSYSTEM DRIVER M: Yisen Zhuang M: Salil Mehta @@ -6162,6 +6257,13 @@ S: Supported F: drivers/scsi/hisi_sas/ F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt +HMM - Heterogeneous Memory Management +M: Jérôme Glisse +L: linux-mm@kvack.org +S: Maintained +F: mm/hmm* +F: include/linux/hmm* + HOST AP DRIVER M: Jouni Malinen L: linux-wireless@vger.kernel.org @@ -6231,6 +6333,13 @@ L: linux-input@vger.kernel.org S: Maintained F: drivers/input/touchscreen/htcpen.c +HUAWEI ETHERNET DRIVER +M: Aviad Krawczyk +L: netdev@vger.kernel.org +S: Supported +F: Documentation/networking/hinic.txt +F: drivers/net/ethernet/huawei/hinic/ + HUGETLB FILESYSTEM M: Nadia Yvette Chambers S: Maintained @@ -6257,7 +6366,9 @@ M: Haiyang Zhang M: Stephen Hemminger L: devel@linuxdriverproject.org S: Maintained +F: Documentation/networking/netvsc.txt F: arch/x86/include/asm/mshyperv.h +F: arch/x86/include/asm/trace/hyperv.h F: arch/x86/include/uapi/asm/hyperv.h F: arch/x86/kernel/cpu/mshyperv.c F: arch/x86/hyperv @@ -6269,7 +6380,9 @@ F: drivers/net/hyperv/ F: drivers/scsi/storvsc_drv.c F: drivers/uio/uio_hv_generic.c F: drivers/video/fbdev/hyperv_fb.c +F: net/vmw_vsock/hyperv_transport.c F: include/linux/hyperv.h +F: include/uapi/linux/hyperv.h F: tools/hv/ F: Documentation/ABI/stable/sysfs-bus-vmbus @@ -6371,6 +6484,12 @@ F: drivers/i2c/busses/i2c-sis96x.c F: drivers/i2c/busses/i2c-via.c F: drivers/i2c/busses/i2c-viapro.c +I2C/SMBUS INTEL CHT WHISKEY COVE PMIC DRIVER +M: Hans de Goede +L: linux-i2c@vger.kernel.org +S: Maintained +F: drivers/i2c/busses/i2c-cht-wc.c + I2C/SMBUS ISMT DRIVER M: Seth Heasley M: Neil Horman @@ -6437,6 +6556,15 @@ L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/ibm/ibmvnic.* +IBM Power Virtual Accelerator Switchboard +M: Sukadev Bhattiprolu +L: linuxppc-dev@lists.ozlabs.org +S: Supported +F: arch/powerpc/platforms/powernv/vas* +F: arch/powerpc/platforms/powernv/copy-paste.h +F: arch/powerpc/include/asm/vas.h +F: arch/powerpc/include/uapi/asm/vas.h + IBM Power Virtual Ethernet Device Driver M: Thomas Falcon L: netdev@vger.kernel.org @@ -6527,8 +6655,8 @@ M: Alexander Aring M: Stefan Schmidt L: linux-wpan@vger.kernel.org W: http://wpan.cakelab.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git -T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/sschmidt/wpan-next.git S: Maintained F: net/ieee802154/ F: net/mac802154/ @@ -6543,7 +6671,7 @@ F: include/net/ieee802154_netdev.h F: Documentation/networking/ieee802154.txt IFE PROTOCOL -M: Yotam Gigi +M: Yotam Gigi M: Jamal Hadi Salim F: net/ife F: include/net/ife.h @@ -6605,13 +6733,13 @@ S: Maintained F: drivers/usb/atm/ueagle-atm.c IMGTEC ASCII LCD DRIVER -M: Paul Burton +M: Paul Burton S: Maintained F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt F: drivers/auxdisplay/img-ascii-lcd.c IMGTEC IR DECODER DRIVER -M: James Hogan +M: James Hogan S: Maintained F: drivers/media/rc/img-ir/ @@ -6673,9 +6801,9 @@ S: Maintained F: drivers/mtd/nand/jz4780_* INOTIFY -M: John McCutchan -M: Robert Love -M: Eric Paris +M: Jan Kara +R: Amir Goldstein +L: linux-fsdevel@vger.kernel.org S: Maintained F: Documentation/filesystems/inotify.txt F: fs/notify/inotify/ @@ -6744,8 +6872,9 @@ S: Supported F: drivers/scsi/isci/ INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets) -M: Daniel Vetter M: Jani Nikula +M: Joonas Lahtinen +M: Rodrigo Vivi L: intel-gfx@lists.freedesktop.org W: https://01.org/linuxgraphics/ B: https://01.org/linuxgraphics/documentation/how-report-bugs @@ -7083,9 +7212,7 @@ W: http://irda.sourceforge.net/ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git F: Documentation/networking/irda.txt -F: drivers/net/irda/ -F: include/net/irda/ -F: net/irda/ +F: drivers/staging/irda/ IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY) M: Marc Zyngier @@ -7379,6 +7506,13 @@ S: Maintained F: tools/testing/selftests/ F: Documentation/dev-tools/kselftest* +KERNEL USERMODE HELPER +M: "Luis R. Rodriguez" +L: linux-kernel@vger.kernel.org +S: Maintained +F: kernel/umh.c +F: include/linux/umh.h + KERNEL VIRTUAL MACHINE (KVM) M: Paolo Bonzini M: Radim Krčmář @@ -7386,18 +7520,17 @@ L: kvm@vger.kernel.org W: http://www.linux-kvm.org T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git S: Supported -F: Documentation/*/kvm*.txt F: Documentation/virtual/kvm/ -F: arch/*/kvm/ -F: arch/x86/kernel/kvm.c -F: arch/x86/kernel/kvmclock.c -F: arch/*/include/asm/kvm* -F: include/linux/kvm* +F: include/trace/events/kvm.h +F: include/uapi/asm-generic/kvm* F: include/uapi/linux/kvm* -F: virt/kvm/ +F: include/asm-generic/kvm* +F: include/linux/kvm* +F: include/kvm/iodev.h +F: virt/kvm/* F: tools/kvm/ -KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V +KERNEL VIRTUAL MACHINE FOR AMD-V (KVM/amd) M: Joerg Roedel L: kvm@vger.kernel.org W: http://www.linux-kvm.org/ @@ -7405,7 +7538,7 @@ S: Maintained F: arch/x86/include/asm/svm.h F: arch/x86/kvm/svm.c -KERNEL VIRTUAL MACHINE (KVM) FOR ARM +KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm) M: Christoffer Dall M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -7419,15 +7552,6 @@ F: arch/arm/kvm/ F: virt/kvm/arm/ F: include/kvm/arm_* -KERNEL VIRTUAL MACHINE (KVM) FOR POWERPC -M: Alexander Graf -L: kvm-ppc@vger.kernel.org -W: http://www.linux-kvm.org/ -T: git git://github.com/agraf/linux-2.6.git -S: Supported -F: arch/powerpc/include/asm/kvm* -F: arch/powerpc/kvm/ - KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) M: Christoffer Dall M: Marc Zyngier @@ -7439,13 +7563,24 @@ F: arch/arm64/include/asm/kvm* F: arch/arm64/kvm/ KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips) -M: James Hogan +M: James Hogan L: linux-mips@linux-mips.org S: Supported F: arch/mips/include/uapi/asm/kvm* F: arch/mips/include/asm/kvm* F: arch/mips/kvm/ +KERNEL VIRTUAL MACHINE FOR POWERPC (KVM/powerpc) +M: Paul Mackerras +L: kvm-ppc@vger.kernel.org +W: http://www.linux-kvm.org/ +T: git git://github.com/agraf/linux-2.6.git +S: Supported +F: arch/powerpc/include/uapi/asm/kvm* +F: arch/powerpc/include/asm/kvm* +F: arch/powerpc/kvm/ +F: arch/powerpc/kernel/kvm* + KERNEL VIRTUAL MACHINE for s390 (KVM/s390) M: Christian Borntraeger M: Cornelia Huck @@ -7453,11 +7588,25 @@ L: linux-s390@vger.kernel.org W: http://www.ibm.com/developerworks/linux/linux390/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git S: Supported -F: Documentation/s390/kvm.txt +F: arch/s390/include/uapi/asm/kvm* +F: arch/s390/include/asm/gmap.h F: arch/s390/include/asm/kvm* F: arch/s390/kvm/ F: arch/s390/mm/gmap.c +KERNEL VIRTUAL MACHINE FOR X86 (KVM/x86) +M: Paolo Bonzini +M: Radim Krčmář +L: kvm@vger.kernel.org +W: http://www.linux-kvm.org +T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git +S: Supported +F: arch/x86/kvm/ +F: arch/x86/include/uapi/asm/kvm* +F: arch/x86/include/asm/kvm* +F: arch/x86/kernel/kvm.c +F: arch/x86/kernel/kvmclock.c + KERNFS M: Greg Kroah-Hartman M: Tejun Heo @@ -7539,7 +7688,7 @@ F: include/linux/kmemleak.h F: mm/kmemleak.c F: mm/kmemleak-test.c -KMOD MODULE USERMODE HELPER +KMOD KERNEL MODULE LOADER - USERMODE HELPER M: "Luis R. Rodriguez" L: linux-kernel@vger.kernel.org S: Maintained @@ -7580,6 +7729,7 @@ M: John Crispin L: linux-mips@linux-mips.org S: Maintained F: arch/mips/lantiq +F: drivers/soc/lantiq LAPB module L: linux-x25@vger.kernel.org @@ -7595,6 +7745,11 @@ S: Maintained F: Documentation/scsi/53c700.txt F: drivers/scsi/53c700* +LEAKING_ADDRESSES +M: Tobin C. Harding +S: Maintained +F: scripts/leaking_addresses.pl + LED SUBSYSTEM M: Richard Purdie M: Jacek Anaszewski @@ -7639,17 +7794,6 @@ T: git git://linuxtv.org/mkrufky/tuners.git S: Maintained F: drivers/media/dvb-frontends/lgdt3305.* -LGUEST -M: Rusty Russell -L: lguest@lists.ozlabs.org -W: http://lguest.ozlabs.org/ -S: Odd Fixes -F: arch/x86/include/asm/lguest*.h -F: arch/x86/lguest/ -F: drivers/lguest/ -F: include/linux/lguest*.h -F: tools/lguest/ - LIBATA PATA ARASAN COMPACT FLASH CONTROLLER M: Viresh Kumar L: linux-ide@vger.kernel.org @@ -7785,6 +7929,7 @@ F: drivers/pci/hotplug/rpa* F: drivers/rtc/rtc-opal.c F: drivers/scsi/ibmvscsi/ F: drivers/tty/hvc/hvc_opal.c +F: drivers/watchdog/wdrtas.c F: tools/testing/selftests/powerpc N: /pmac N: powermac @@ -8125,6 +8270,12 @@ L: libertas-dev@lists.infradead.org S: Orphan F: drivers/net/wireless/marvell/libertas/ +MARVELL MACCHIATOBIN SUPPORT +M: Russell King +L: linux-arm-kernel@lists.infradead.org +S: Maintained +F: arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts + MARVELL MV643XX ETHERNET DRIVER M: Sebastian Hesselbarth L: netdev@vger.kernel.org @@ -8301,6 +8452,14 @@ T: git git://linuxtv.org/media_tree.git S: Supported F: drivers/media/dvb-frontends/cxd2841er* +MEDIA DRIVERS FOR DIGITAL DEVICES PCIE DEVICES +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/pci/ddbridge/* + MEDIA DRIVERS FOR FREESCALE IMX M: Steve Longerbeam M: Philipp Zabel @@ -8342,6 +8501,14 @@ T: git git://linuxtv.org/media_tree.git S: Supported F: drivers/media/dvb-frontends/lnbh25* +MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/mxl5xx* + MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices M: Sergey Kozlov M: Abylay Ospan @@ -8398,6 +8565,22 @@ S: Supported F: Documentation/devicetree/bindings/media/renesas,vsp1.txt F: drivers/media/platform/vsp1/ +MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/stv0910* + +MEDIA DRIVERS FOR ST STV6111 TUNER ICs +M: Daniel Scheller +L: linux-media@vger.kernel.org +W: https://linuxtv.org +T: git git://linuxtv.org/media_tree.git +S: Maintained +F: drivers/media/dvb-frontends/stv6111* + MEDIA INPUT INFRASTRUCTURE (V4L/DVB) M: Mauro Carvalho Chehab M: Mauro Carvalho Chehab @@ -8421,9 +8604,22 @@ F: include/uapi/linux/meye.h F: include/uapi/linux/ivtv* F: include/uapi/linux/uvcvideo.h +MEDIATEK CIR DRIVER +M: Sean Wang +S: Maintained +F: drivers/media/rc/mtk-cir.c + +MEDIATEK PMIC LED DRIVER +M: Sean Wang +S: Maintained +F: drivers/leds/leds-mt6323.c +F: Documentation/devicetree/bindings/leds/leds-mt6323.txt + MEDIATEK ETHERNET DRIVER M: Felix Fietkau -M: John Crispin +M: John Crispin +M: Sean Wang +M: Nelson Chang L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/mediatek/ @@ -8464,6 +8660,14 @@ M: Sean Wang S: Maintained F: drivers/char/hw_random/mtk-rng.c +MEDIATEK USB3 DRD IP DRIVER +M: Chunfeng Yun +L: linux-usb@vger.kernel.org (moderated for non-subscribers) +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: drivers/usb/mtu3/ + MEGACHIPS STDPXXXX-GE-B850V3-FW LVDS/DP++ BRIDGES M: Peter Senna Tschudin M: Martin Donnelly @@ -8544,7 +8748,7 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/ F: drivers/net/ethernet/mellanox/mlxsw/ MELLANOX FIRMWARE FLASH LIBRARY (mlxfw) -M: Yotam Gigi +M: mlxsw@mellanox.com L: netdev@vger.kernel.org S: Supported W: http://www.mellanox.com @@ -8628,7 +8832,7 @@ M: Mathieu Desnoyers M: "Paul E. McKenney" L: linux-kernel@vger.kernel.org S: Supported -F: kernel/membarrier.c +F: kernel/sched/membarrier.c F: include/uapi/linux/membarrier.h MEMORY MANAGEMENT @@ -8682,8 +8886,18 @@ F: drivers/leds/leds-menf21bmc.c F: drivers/hwmon/menf21bmc_hwmon.c F: Documentation/hwmon/menf21bmc +MESON AO CEC DRIVER FOR AMLOGIC SOCS +M: Neil Armstrong +L: linux-media@lists.freedesktop.org +L: linux-amlogic@lists.infradead.org +W: http://linux-meson.com/ +S: Supported +F: drivers/media/platform/meson/ao-cec.c +F: Documentation/devicetree/bindings/media/meson-ao-cec.txt +T: git git://linuxtv.org/media_tree.git + METAG ARCHITECTURE -M: James Hogan +M: James Hogan L: linux-metag@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/metag.git S: Odd Fixes @@ -8718,6 +8932,12 @@ F: drivers/dma/at_hdmac.c F: drivers/dma/at_hdmac_regs.h F: include/linux/platform_data/dma-atmel.h +MICROCHIP / ATMEL ECC DRIVER +M: Tudor Ambarus +L: linux-crypto@vger.kernel.org +S: Maintained +F: drivers/crypto/atmel-ecc.* + MICROCHIP / ATMEL ISC DRIVER M: Songjun Wu L: linux-media@vger.kernel.org @@ -8778,7 +8998,7 @@ F: Documentation/mips/ F: arch/mips/ MIPS BOSTON DEVELOPMENT BOARD -M: Paul Burton +M: Paul Burton L: linux-mips@linux-mips.org S: Maintained F: Documentation/devicetree/bindings/clock/img,boston-clock.txt @@ -8788,10 +9008,11 @@ F: drivers/clk/imgtec/clk-boston.c F: include/dt-bindings/clock/boston-clock.h MIPS GENERIC PLATFORM -M: Paul Burton +M: Paul Burton L: linux-mips@linux-mips.org S: Supported F: arch/mips/generic/ +F: arch/mips/tools/generic-board-config.sh MIPS/LOONGSON1 ARCHITECTURE M: Keguang Zhang @@ -8802,6 +9023,13 @@ F: arch/mips/include/asm/mach-loongson32/ F: drivers/*/*loongson1* F: drivers/*/*/*loongson1* +MIPS RINT INSTRUCTION EMULATION +M: Aleksandar Markovic +L: linux-mips@linux-mips.org +S: Supported +F: arch/mips/math-emu/sp_rint.c +F: arch/mips/math-emu/dp_rint.c + MIROSOUND PCM20 FM RADIO RECEIVER DRIVER M: Hans Verkuil L: linux-media@vger.kernel.org @@ -8990,7 +9218,6 @@ F: include/linux/isicom.h MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER M: Bin Liu L: linux-usb@vger.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained F: drivers/usb/musb/ @@ -9027,7 +9254,7 @@ T: git git://git.infradead.org/linux-mtd.git nand/fixes T: git git://git.infradead.org/l2-mtd.git nand/next S: Maintained F: drivers/mtd/nand/ -F: include/linux/mtd/nand*.h +F: include/linux/mtd/*nand*.h NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER M: Daniel Mack @@ -9119,15 +9346,6 @@ F: net/*/netfilter/ F: net/netfilter/ F: net/bridge/br_netfilter*.c -NETLABEL -M: Paul Moore -W: http://netlabel.sf.net -L: netdev@vger.kernel.org -S: Maintained -F: Documentation/netlabel/ -F: include/net/netlabel.h -F: net/netlabel/ - NETROM NETWORK LAYER M: Ralf Baechle L: linux-hams@vger.kernel.org @@ -9147,7 +9365,7 @@ NETWORK BLOCK DEVICE (NBD) M: Josef Bacik S: Maintained L: linux-block@vger.kernel.org -L: nbd-general@lists.sourceforge.net +L: nbd@other.debian.org F: Documentation/blockdev/nbd.txt F: drivers/block/nbd.c F: include/uapi/linux/nbd.h @@ -9255,10 +9473,23 @@ F: net/ipv6/ F: include/net/ip* F: arch/x86/net/* -NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK) +NETWORKING [LABELED] (NetLabel, Labeled IPsec, SECMARK) M: Paul Moore +W: https://github.com/netlabel L: netdev@vger.kernel.org +L: linux-security-module@vger.kernel.org S: Maintained +F: Documentation/netlabel/ +F: include/net/calipso.h +F: include/net/cipso_ipv4.h +F: include/net/netlabel.h +F: include/uapi/linux/netfilter/xt_SECMARK.h +F: include/uapi/linux/netfilter/xt_CONNSECMARK.h +F: net/netlabel/ +F: net/ipv4/cipso_ipv4.c +F: net/ipv6/calipso.c +F: net/netfilter/xt_CONNSECMARK.c +F: net/netfilter/xt_SECMARK.c NETWORKING [TLS] M: Ilya Lesokhin @@ -9465,6 +9696,7 @@ M: Srinivas Kandagatla S: Maintained F: drivers/nvmem/ F: Documentation/devicetree/bindings/nvmem/ +F: Documentation/ABI/stable/sysfs-bus-nvmem F: include/linux/nvmem-consumer.h F: include/linux/nvmem-provider.h @@ -9674,6 +9906,12 @@ F: drivers/regulator/twl-regulator.c F: drivers/regulator/twl6030-regulator.c F: include/linux/i2c-omap.h +ONION OMEGA2+ BOARD +M: Harvey Hunt +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/boot/dts/ralink/omega2p.dts + OMFS FILESYSTEM M: Bob Copeland L: linux-karma-devel@lists.sourceforge.net @@ -9708,7 +9946,7 @@ S: Maintained F: drivers/media/i2c/ov5640.c OMNIVISION OV5647 SENSOR DRIVER -M: Ramiro Oliveira +M: Luis Oliveira L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git S: Maintained @@ -9945,15 +10183,14 @@ F: include/uapi/linux/ppdev.h F: Documentation/parport*.txt PARAVIRT_OPS INTERFACE -M: Jeremy Fitzhardinge -M: Chris Wright +M: Juergen Gross M: Alok Kataria M: Rusty Russell L: virtualization@lists.linux-foundation.org S: Supported F: Documentation/virtual/paravirt_ops.txt F: arch/*/kernel/paravirt* -F: arch/*/include/asm/paravirt.h +F: arch/*/include/asm/paravirt*.h F: include/linux/hypervisor.h PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES @@ -10097,13 +10334,13 @@ F: drivers/pci/dwc/*imx6* PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) M: Keith Busch +M: Jonathan Derrick L: linux-pci@vger.kernel.org S: Supported F: drivers/pci/host/vmd.c PCI DRIVER FOR MICROSEMI SWITCHTEC M: Kurt Schwemmer -M: Stephen Bates M: Logan Gunthorpe L: linux-pci@vger.kernel.org S: Maintained @@ -10143,7 +10380,7 @@ L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) S: Maintained F: drivers/pci/dwc/pci-exynos.c -PCI DRIVER FOR SYNOPSIS DESIGNWARE +PCI DRIVER FOR SYNOPSYS DESIGNWARE M: Jingoo Han M: Joao Pinto L: linux-pci@vger.kernel.org @@ -10168,6 +10405,7 @@ F: drivers/pci/dwc/*keystone* PCI ENDPOINT SUBSYSTEM M: Kishon Vijay Abraham I +M: Lorenzo Pieralisi L: linux-pci@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git S: Supported @@ -10219,6 +10457,15 @@ F: include/linux/pci* F: arch/x86/pci/ F: arch/x86/kernel/quirks.c +PCI NATIVE HOST BRIDGE AND ENDPOINT DRIVERS +M: Lorenzo Pieralisi +L: linux-pci@vger.kernel.org +Q: http://patchwork.ozlabs.org/project/linux-pci/list/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git/ +S: Supported +F: drivers/pci/host/ +F: drivers/pci/dwc/ + PCIE DRIVER FOR AXIS ARTPEC M: Niklas Cassel M: Jesper Nilsson @@ -10238,7 +10485,6 @@ F: drivers/pci/host/pci-thunder-* PCIE DRIVER FOR HISILICON M: Zhou Wang -M: Gabriele Paoloni L: linux-pci@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt @@ -10325,6 +10571,8 @@ M: Peter Zijlstra M: Ingo Molnar M: Arnaldo Carvalho de Melo R: Alexander Shishkin +R: Jiri Olsa +R: Namhyung Kim L: linux-kernel@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core S: Supported @@ -10448,10 +10696,9 @@ S: Maintained F: drivers/pinctrl/spear/ PISTACHIO SOC SUPPORT -M: James Hartley -M: Ionela Voinescu +M: James Hartley L: linux-mips@linux-mips.org -S: Maintained +S: Odd Fixes F: arch/mips/pistachio/ F: arch/mips/include/asm/mach-pistachio/ F: arch/mips/boot/dts/img/pistachio* @@ -10579,8 +10826,11 @@ W: http://wiki.enneenne.com/index.php/LinuxPPS_support L: linuxpps@ml.enneenne.com (subscribers-only) S: Maintained F: Documentation/pps/ +F: Documentation/devicetree/bindings/pps/pps-gpio.txt +F: Documentation/ABI/testing/sysfs-pps F: drivers/pps/ F: include/linux/pps*.h +F: include/uapi/linux/pps.h PPTP DRIVER M: Dmitry Kozlov @@ -10652,7 +10902,7 @@ S: Maintained F: drivers/block/ps3vram.c PSAMPLE PACKET SAMPLING SUPPORT: -M: Yotam Gigi +M: Yotam Gigi S: Maintained F: net/psample F: include/net/psample.h @@ -10706,6 +10956,7 @@ L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git S: Maintained F: drivers/media/usb/pulse8-cec/* +F: Documentation/media/cec-drivers/pulse8-cec.rst PVRUSB2 VIDEO4LINUX DRIVER M: Mike Isely @@ -10733,6 +10984,12 @@ F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt F: Documentation/hwmon/pwm-fan F: drivers/hwmon/pwm-fan.c +PWM IR Transmitter +M: Sean Young +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/rc/pwm-ir-tx.c + PWM SUBSYSTEM M: Thierry Reding L: linux-pwm@vger.kernel.org @@ -10826,7 +11083,6 @@ S: Supported F: drivers/scsi/qedi/ QLOGIC QL4xxx ETHERNET DRIVER -M: Yuval Mintz M: Ariel Elior M: everest-linux-l2@cavium.com L: netdev@vger.kernel.org @@ -10927,6 +11183,14 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k S: Supported F: drivers/net/wireless/ath/ath9k/ +QUALCOMM CAMERA SUBSYSTEM DRIVER +M: Todor Tomov +L: linux-media@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/media/qcom,camss.txt +F: Documentation/media/v4l-drivers/qcom_camss.rst +F: drivers/media/platform/qcom/camss-8x16/ + QUALCOMM EMAC GIGABIT ETHERNET DRIVER M: Timur Tabi L: netdev@vger.kernel.org @@ -10940,6 +11204,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rkuo/linux-hexagon-kernel.g S: Supported F: arch/hexagon/ +QUALCOMM IOMMU +M: Rob Clark +L: iommu@lists.linux-foundation.org +L: linux-arm-msm@vger.kernel.org +S: Maintained +F: drivers/iommu/qcom_iommu.c + QUALCOMM VENUS VIDEO ACCELERATOR DRIVER M: Stanimir Varbanov L: linux-media@vger.kernel.org @@ -11110,7 +11381,7 @@ M: Fenghua Yu L: linux-kernel@vger.kernel.org S: Supported F: arch/x86/kernel/cpu/intel_rdt* -F: arch/x86/include/asm/intel_rdt* +F: arch/x86/include/asm/intel_rdt_sched.h F: Documentation/x86/intel_rdt* READ-COPY UPDATE (RCU) @@ -11199,6 +11470,8 @@ RENESAS ETHERNET DRIVERS R: Sergei Shtylyov L: netdev@vger.kernel.org L: linux-renesas-soc@vger.kernel.org +F: Documentation/devicetree/bindings/net/renesas,*.txt +F: Documentation/devicetree/bindings/net/sh_eth.txt F: drivers/net/ethernet/renesas/ F: include/linux/sh_eth.h @@ -11280,6 +11553,17 @@ L: linux-serial@vger.kernel.org S: Odd Fixes F: drivers/tty/serial/rp2.* +ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS +M: Marek Vasut +L: linux-kernel@vger.kernel.org +L: linux-renesas-soc@vger.kernel.org +S: Supported +F: drivers/mfd/bd9571mwv.c +F: drivers/regulator/bd9571mwv-regulator.c +F: drivers/gpio/gpio-bd9571mwv.c +F: include/linux/mfd/bd9571mwv.h +F: Documentation/devicetree/bindings/mfd/bd9571mwv.txt + ROSE NETWORK LAYER M: Ralf Baechle L: linux-hams@vger.kernel.org @@ -11441,6 +11725,7 @@ F: drivers/s390/crypto/ S390 ZFCP DRIVER M: Steffen Maier +M: Benjamin Block L: linux-s390@vger.kernel.org W: http://www.ibm.com/developerworks/linux/linux390/ S: Supported @@ -11805,8 +12090,9 @@ M: Paul Moore M: Stephen Smalley M: Eric Paris L: selinux@tycho.nsa.gov (moderated for non-subscribers) -W: http://selinuxproject.org -T: git git://git.infradead.org/users/pcmoore/selinux +W: https://selinuxproject.org +W: https://github.com/SELinuxProject +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git S: Supported F: include/linux/selinux* F: security/selinux/ @@ -12293,6 +12579,7 @@ F: drivers/tty/serial/sunsab.h F: drivers/tty/serial/sunsu.c F: drivers/tty/serial/sunzilog.c F: drivers/tty/serial/sunzilog.h +F: drivers/tty/vcc.c SPARSE CHECKER M: "Christopher Li" @@ -12489,6 +12776,12 @@ M: Ion Badulescu S: Odd Fixes F: drivers/net/ethernet/adaptec/starfire* +STEC S1220 SKD DRIVER +M: Bart Van Assche +L: linux-block@vger.kernel.org +S: Maintained +F: drivers/block/skd*[ch] + STI CEC DRIVER M: Benjamin Gaignard S: Maintained @@ -12606,6 +12899,18 @@ F: drivers/clocksource/arc_timer.c F: drivers/tty/serial/arc_uart.c T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git +SYNOPSYS ARC HSDK SDP pll clock driver +M: Eugeniy Paltsev +S: Supported +F: drivers/clk/clk-hsdk-pll.c +F: Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt + +SYNOPSYS ARC SDP clock driver +M: Eugeniy Paltsev +S: Supported +F: drivers/clk/axs10x/* +F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt + SYNOPSYS ARC SDP platform support M: Alexey Brodkin S: Supported @@ -12642,6 +12947,13 @@ L: linux-mmc@vger.kernel.org S: Maintained F: drivers/mmc/host/dw_mmc* +SYNOPSYS HSDK RESET CONTROLLER DRIVER +M: Eugeniy Paltsev +S: Supported +F: drivers/reset/reset-hsdk.c +F: include/dt-bindings/reset/snps,hsdk-reset.h +F: Documentation/devicetree/bindings/reset/snps,hsdk-reset.txt + SYSTEM CONFIGURATION (SYSCON) M: Lee Jones M: Arnd Bergmann @@ -12992,6 +13304,11 @@ M: Yehezkel Bernat S: Maintained F: drivers/thunderbolt/ +THUNDERX GPIO DRIVER +M: David Daney +S: Maintained +F: drivers/gpio/gpio-thunderx.c + TI AM437X VPFE DRIVER M: "Lad, Prabhakar" L: linux-media@vger.kernel.org @@ -13294,23 +13611,14 @@ F: drivers/platform/x86/toshiba-wmi.c TPM DEVICE DRIVER M: Peter Huewe -M: Marcel Selhorst M: Jarkko Sakkinen R: Jason Gunthorpe -W: http://tpmdd.sourceforge.net -L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) -Q: https://patchwork.kernel.org/project/tpmdd-devel/list/ +L: linux-integrity@vger.kernel.org +Q: https://patchwork.kernel.org/project/linux-integrity/list/ T: git git://git.infradead.org/users/jjs/linux-tpmdd.git S: Maintained F: drivers/char/tpm/ -TPM IBM_VTPM DEVICE DRIVER -M: Ashley Lai -W: http://tpmdd.sourceforge.net -L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers) -S: Maintained -F: drivers/char/tpm/tpm_ibmvtpm* - TRACING M: Steven Rostedt M: Ingo Molnar @@ -13516,8 +13824,7 @@ F: Documentation/scsi/ufs.txt F: drivers/scsi/ufs/ UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER DWC HOOKS -M: Manjunath M Bettegowda -M: Prabu Thangamuthu +M: Joao Pinto L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/ufs/*dwc* @@ -14126,6 +14433,12 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/vmxnet3/ +VOCORE VOCORE2 BOARD +M: Harvey Hunt +L: linux-mips@linux-mips.org +S: Maintained +F: arch/mips/boot/dts/ralink/vocore2.dts + VOLTAGE AND CURRENT REGULATOR FRAMEWORK M: Liam Girdwood M: Mark Brown diff --git a/Makefile b/Makefile index ed65d7278bb3..ccd981892ef2 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 VERSION = 4 -PATCHLEVEL = 13 +PATCHLEVEL = 14 SUBLEVEL = 0 EXTRAVERSION = NAME = Fearless Coyote @@ -697,11 +698,11 @@ KBUILD_CFLAGS += $(stackp-flag) ifeq ($(cc-name),clang) ifneq ($(CROSS_COMPILE),) -CLANG_TARGET := -target $(notdir $(CROSS_COMPILE:%-=%)) +CLANG_TARGET := --target=$(notdir $(CROSS_COMPILE:%-=%)) GCC_TOOLCHAIN := $(realpath $(dir $(shell which $(LD)))/..) endif ifneq ($(GCC_TOOLCHAIN),) -CLANG_GCC_TC := -gcc-toolchain $(GCC_TOOLCHAIN) +CLANG_GCC_TC := --gcc-toolchain=$(GCC_TOOLCHAIN) endif KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) @@ -933,7 +934,11 @@ ifdef CONFIG_STACK_VALIDATION ifeq ($(has_libelf),1) objtool_target := tools/objtool FORCE else - $(warning "Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev, libelf-devel or elfutils-libelf-devel") + ifdef CONFIG_ORC_UNWINDER + $(error "Cannot generate ORC metadata for CONFIG_ORC_UNWINDER=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel") + else + $(warning "Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel") + endif SKIP_STACK_VALIDATION := 1 export SKIP_STACK_VALIDATION endif @@ -978,7 +983,7 @@ ifdef CONFIG_HEADERS_CHECK $(Q)$(MAKE) -f $(srctree)/Makefile headers_check endif ifdef CONFIG_GDB_SCRIPTS - $(Q)ln -fsn `cd $(srctree) && /bin/pwd`/scripts/gdb/vmlinux-gdb.py + $(Q)ln -fsn $(abspath $(srctree)/scripts/gdb/vmlinux-gdb.py) endif ifdef CONFIG_TRIM_UNUSED_KSYMS $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ @@ -1128,16 +1133,6 @@ headerdep: $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \ $(srctree)/scripts/headerdep.pl -I$(srctree)/include -# --------------------------------------------------------------------------- -# Firmware install -INSTALL_FW_PATH=$(INSTALL_MOD_PATH)/lib/firmware -export INSTALL_FW_PATH - -PHONY += firmware_install -firmware_install: - @mkdir -p $(objtree)/firmware - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_install - # --------------------------------------------------------------------------- # Kernel headers @@ -1182,11 +1177,11 @@ headers_check: headers_install PHONY += kselftest kselftest: - $(Q)$(MAKE) -C tools/testing/selftests run_tests + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests run_tests PHONY += kselftest-clean kselftest-clean: - $(Q)$(MAKE) -C tools/testing/selftests clean + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests clean PHONY += kselftest-merge kselftest-merge: @@ -1216,7 +1211,6 @@ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modbuild modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) $(Q)$(AWK) '!x[$$0]++' $^ > $(objtree)/modules.builtin @@ -1238,7 +1232,7 @@ _modinst_: @rm -rf $(MODLIB)/kernel @rm -f $(MODLIB)/source @mkdir -p $(MODLIB)/kernel - @ln -s `cd $(srctree) && /bin/pwd` $(MODLIB)/source + @ln -s $(abspath $(srctree)) $(MODLIB)/source @if [ ! $(objtree) -ef $(MODLIB)/build ]; then \ rm -f $(MODLIB)/build ; \ ln -s $(CURDIR) $(MODLIB)/build ; \ @@ -1252,7 +1246,6 @@ _modinst_: # boot script depmod is the master version. PHONY += _modinst_post _modinst_post: _modinst_ - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst $(call cmd,depmod) ifeq ($(CONFIG_MODULE_SIG), y) @@ -1375,8 +1368,6 @@ help: @echo '* vmlinux - Build the bare kernel' @echo '* modules - Build all modules' @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)' - @echo ' firmware_install- Install all firmware to INSTALL_FW_PATH' - @echo ' (default: $$(INSTALL_MOD_PATH)/lib/firmware)' @echo ' dir/ - Build all files in dir and below' @echo ' dir/file.[ois] - Build specified target only' @echo ' dir/file.ll - Build the LLVM assembly file' @@ -1409,7 +1400,7 @@ help: @echo ' Build, install, and boot kernel before' @echo ' running kselftest on it' @echo ' kselftest-clean - Remove all generated kselftest files' - @echo ' kselftest-merge - Merge all the config dependencies of kselftest to existed' + @echo ' kselftest-merge - Merge all the config dependencies of kselftest to existing' @echo ' .config.' @echo '' @echo 'Userspace tools targets:' @@ -1468,7 +1459,7 @@ $(help-board-dirs): help-%: # Documentation targets # --------------------------------------------------------------------------- -DOC_TARGETS := xmldocs sgmldocs psdocs latexdocs pdfdocs htmldocs mandocs installmandocs epubdocs cleandocs linkcheckdocs +DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs linkcheckdocs PHONY += $(DOC_TARGETS) $(DOC_TARGETS): scripts_basic FORCE $(Q)$(MAKE) $(build)=Documentation $@ @@ -1630,11 +1621,11 @@ image_name: # Clear a bunch of variables before executing the submake tools/: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/ tools/%: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $* + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- diff --git a/arch/Kconfig b/arch/Kconfig index 21d0089117fe..057370a0ac4e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # General architecture dependent options # @@ -458,6 +459,13 @@ config GCC_PLUGIN_STRUCTLEAK * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL + bool "Force initialize all struct type variables passed by reference" + depends on GCC_PLUGIN_STRUCTLEAK + help + Zero initialize any struct type local variable that may be passed by + reference without having been initialized. + config GCC_PLUGIN_STRUCTLEAK_VERBOSE bool "Report forcefully initialized variables" depends on GCC_PLUGIN_STRUCTLEAK @@ -473,11 +481,13 @@ config GCC_PLUGIN_RANDSTRUCT depends on GCC_PLUGINS select MODVERSIONS if MODULES help - If you say Y here, the layouts of structures explicitly - marked by __randomize_layout will be randomized at - compile-time. This can introduce the requirement of an - additional information exposure vulnerability for exploits - targeting these structure types. + If you say Y here, the layouts of structures that are entirely + function pointers (and have not been manually annotated with + __no_randomize_layout), or structures that have been explicitly + marked with __randomize_layout, will be randomized at compile-time. + This can introduce the requirement of an additional information + exposure vulnerability for exploits targeting these structure + types. Enabling this feature will introduce some performance impact, slightly increase memory usage, and prevent the use of forensic @@ -928,8 +938,17 @@ config STRICT_MODULE_RWX and non-text memory will be made non-executable. This provides protection against certain security exploits (e.g. writing to text) -config ARCH_WANT_RELAX_ORDER +config ARCH_HAS_REFCOUNT bool + help + An architecture selects this when it has implemented refcount_t + using open coded assembly primitives that provide an optimized + refcount_t implementation, possibly at the expense of some full + refcount state checks of CONFIG_REFCOUNT_FULL=y. + + The refcount overflow check behavior, however, must be retained. + Catching overflows is the primary security concern for protecting + against bugs in reference counts. config REFCOUNT_FULL bool "Perform full reference count validation at the expense of speed" diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 0e49d39ea74a..69b875880754 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ALPHA bool default y diff --git a/arch/alpha/Kconfig.debug b/arch/alpha/Kconfig.debug index 3f6265f2d9d4..5e93dffb818a 100644 --- a/arch/alpha/Kconfig.debug +++ b/arch/alpha/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/alpha/boot/bootloader.lds b/arch/alpha/boot/bootloader.lds index 31c081ce1d50..8cdff54c6e41 100644 --- a/arch/alpha/boot/bootloader.lds +++ b/arch/alpha/boot/bootloader.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ OUTPUT_FORMAT("elf64-alpha") ENTRY(__start) printk = srm_printk; diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c index 2a542a506557..95c0359f4858 100644 --- a/arch/alpha/boot/bootp.c +++ b/arch/alpha/boot/bootp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/boot/bootp.c * diff --git a/arch/alpha/boot/bootpz.c b/arch/alpha/boot/bootpz.c index d6ad191698da..99b8d7dc344b 100644 --- a/arch/alpha/boot/bootpz.c +++ b/arch/alpha/boot/bootpz.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/boot/bootpz.c * diff --git a/arch/alpha/boot/head.S b/arch/alpha/boot/head.S index 8efb26686d47..06a7c95fe9ad 100644 --- a/arch/alpha/boot/head.S +++ b/arch/alpha/boot/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/boot/head.S * diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c index dd6eb4a33582..8f5ed8610970 100644 --- a/arch/alpha/boot/main.c +++ b/arch/alpha/boot/main.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/boot/main.c * diff --git a/arch/alpha/boot/misc.c b/arch/alpha/boot/misc.c index 1b568ed74f95..d65192202703 100644 --- a/arch/alpha/boot/misc.c +++ b/arch/alpha/boot/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * misc.c * diff --git a/arch/alpha/boot/tools/mkbb.c b/arch/alpha/boot/tools/mkbb.c index 1185778e6a1e..fc47f33f8a44 100644 --- a/arch/alpha/boot/tools/mkbb.c +++ b/arch/alpha/boot/tools/mkbb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* This utility makes a bootblock suitable for the SRM console/miniloader */ /* Usage: diff --git a/arch/alpha/boot/tools/objstrip.c b/arch/alpha/boot/tools/objstrip.c index dee82695f48b..825a16f5f622 100644 --- a/arch/alpha/boot/tools/objstrip.c +++ b/arch/alpha/boot/tools/objstrip.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/boot/tools/objstrip.c * diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 539e8b5a6cbd..f4ec420d7f2d 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -19,7 +19,6 @@ CONFIG_INET_AH=m CONFIG_INET_ESP=m # CONFIG_IPV6 is not set CONFIG_NETFILTER=y -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_FILTER=m CONFIG_VLAN_8021Q=m @@ -57,7 +56,6 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_RTC=y CONFIG_EXT2_FS=y CONFIG_REISERFS_FS=m -CONFIG_AUTOFS_FS=m CONFIG_ISO9660_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index d103db5af5ff..47f3fba3e41f 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -1,8 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 generic-y += clkdev.h generic-y += exec.h generic-y += export.h +generic-y += fb.h generic-y += irq_work.h generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h diff --git a/arch/alpha/include/asm/a.out.h b/arch/alpha/include/asm/a.out.h index 9abbd2455306..d2346b7caff1 100644 --- a/arch/alpha/include/asm/a.out.h +++ b/arch/alpha/include/asm/a.out.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_A_OUT_H__ #define __ALPHA_A_OUT_H__ diff --git a/arch/alpha/include/asm/agp.h b/arch/alpha/include/asm/agp.h index a94d48b8677f..7173eada1567 100644 --- a/arch/alpha/include/asm/agp.h +++ b/arch/alpha/include/asm/agp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef AGP_H #define AGP_H 1 diff --git a/arch/alpha/include/asm/agp_backend.h b/arch/alpha/include/asm/agp_backend.h index 55dd44a2cea7..2718802407d6 100644 --- a/arch/alpha/include/asm/agp_backend.h +++ b/arch/alpha/include/asm/agp_backend.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_AGP_BACKEND_H #define _ALPHA_AGP_BACKEND_H 1 diff --git a/arch/alpha/include/asm/asm-prototypes.h b/arch/alpha/include/asm/asm-prototypes.h new file mode 100644 index 000000000000..d12c68ea340b --- /dev/null +++ b/arch/alpha/include/asm/asm-prototypes.h @@ -0,0 +1,18 @@ +#include + +#include +#include +#include +#include +#include + +#include + +extern void __divl(void); +extern void __reml(void); +extern void __divq(void); +extern void __remq(void); +extern void __divlu(void); +extern void __remlu(void); +extern void __divqu(void); +extern void __remqu(void); diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index 498933a7df97..85867d3cea64 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_ATOMIC_H #define _ALPHA_ATOMIC_H diff --git a/arch/alpha/include/asm/barrier.h b/arch/alpha/include/asm/barrier.h index 77516c87255d..92ec486a4f9e 100644 --- a/arch/alpha/include/asm/barrier.h +++ b/arch/alpha/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __BARRIER_H #define __BARRIER_H diff --git a/arch/alpha/include/asm/bitops.h b/arch/alpha/include/asm/bitops.h index 4bdfbd444e63..ca43f4d0b937 100644 --- a/arch/alpha/include/asm/bitops.h +++ b/arch/alpha/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_BITOPS_H #define _ALPHA_BITOPS_H diff --git a/arch/alpha/include/asm/bug.h b/arch/alpha/include/asm/bug.h index f091682e3cc8..b88ebdfedf7c 100644 --- a/arch/alpha/include/asm/bug.h +++ b/arch/alpha/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_BUG_H #define _ALPHA_BUG_H diff --git a/arch/alpha/include/asm/cache.h b/arch/alpha/include/asm/cache.h index ad368a93a46a..6ce508c68907 100644 --- a/arch/alpha/include/asm/cache.h +++ b/arch/alpha/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-alpha/cache.h */ diff --git a/arch/alpha/include/asm/cacheflush.h b/arch/alpha/include/asm/cacheflush.h index a9cb6aa447aa..89128489cb59 100644 --- a/arch/alpha/include/asm/cacheflush.h +++ b/arch/alpha/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_CACHEFLUSH_H #define _ALPHA_CACHEFLUSH_H diff --git a/arch/alpha/include/asm/checksum.h b/arch/alpha/include/asm/checksum.h index f2bbdd2ace51..473e6ccb65a3 100644 --- a/arch/alpha/include/asm/checksum.h +++ b/arch/alpha/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_CHECKSUM_H #define _ALPHA_CHECKSUM_H diff --git a/arch/alpha/include/asm/cmpxchg.h b/arch/alpha/include/asm/cmpxchg.h index e5117766529e..46ebf14aed4e 100644 --- a/arch/alpha/include/asm/cmpxchg.h +++ b/arch/alpha/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_CMPXCHG_H #define _ALPHA_CMPXCHG_H diff --git a/arch/alpha/include/asm/compiler.h b/arch/alpha/include/asm/compiler.h index a7720b96bcc9..5159ba259d65 100644 --- a/arch/alpha/include/asm/compiler.h +++ b/arch/alpha/include/asm/compiler.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_COMPILER_H #define __ALPHA_COMPILER_H diff --git a/arch/alpha/include/asm/console.h b/arch/alpha/include/asm/console.h index f2b584fe0994..088b7b9eb15a 100644 --- a/arch/alpha/include/asm/console.h +++ b/arch/alpha/include/asm/console.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __AXP_CONSOLE_H #define __AXP_CONSOLE_H diff --git a/arch/alpha/include/asm/core_apecs.h b/arch/alpha/include/asm/core_apecs.h index 6785ff7e02bc..0a07055bc0fe 100644 --- a/arch/alpha/include/asm/core_apecs.h +++ b/arch/alpha/include/asm/core_apecs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_APECS__H__ #define __ALPHA_APECS__H__ diff --git a/arch/alpha/include/asm/core_cia.h b/arch/alpha/include/asm/core_cia.h index 9e0516c0ca27..c706a7f2b061 100644 --- a/arch/alpha/include/asm/core_cia.h +++ b/arch/alpha/include/asm/core_cia.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_CIA__H__ #define __ALPHA_CIA__H__ diff --git a/arch/alpha/include/asm/core_irongate.h b/arch/alpha/include/asm/core_irongate.h index 24b2db541501..1c8906bf76c6 100644 --- a/arch/alpha/include/asm/core_irongate.h +++ b/arch/alpha/include/asm/core_irongate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_IRONGATE__H__ #define __ALPHA_IRONGATE__H__ diff --git a/arch/alpha/include/asm/core_lca.h b/arch/alpha/include/asm/core_lca.h index 8ee6c516279c..84d5e5b84f4f 100644 --- a/arch/alpha/include/asm/core_lca.h +++ b/arch/alpha/include/asm/core_lca.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_LCA__H__ #define __ALPHA_LCA__H__ diff --git a/arch/alpha/include/asm/core_marvel.h b/arch/alpha/include/asm/core_marvel.h index dad300fa14ce..cc6fd92d5fa9 100644 --- a/arch/alpha/include/asm/core_marvel.h +++ b/arch/alpha/include/asm/core_marvel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Marvel systems use the IO7 I/O chip provides PCI/PCIX/AGP access * @@ -312,7 +313,7 @@ struct io7 { io7_port7_csrs *csrs; struct io7_port ports[IO7_NUM_PORTS]; - spinlock_t irq_lock; + raw_spinlock_t irq_lock; }; #ifndef __EXTERN_INLINE diff --git a/arch/alpha/include/asm/core_mcpcia.h b/arch/alpha/include/asm/core_mcpcia.h index ad44bef29fba..b30dc128210d 100644 --- a/arch/alpha/include/asm/core_mcpcia.h +++ b/arch/alpha/include/asm/core_mcpcia.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_MCPCIA__H__ #define __ALPHA_MCPCIA__H__ diff --git a/arch/alpha/include/asm/core_polaris.h b/arch/alpha/include/asm/core_polaris.h index 2f966b64659d..1c56dea647b5 100644 --- a/arch/alpha/include/asm/core_polaris.h +++ b/arch/alpha/include/asm/core_polaris.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_POLARIS__H__ #define __ALPHA_POLARIS__H__ diff --git a/arch/alpha/include/asm/core_t2.h b/arch/alpha/include/asm/core_t2.h index ade9d92e68b4..e0b33d09e93a 100644 --- a/arch/alpha/include/asm/core_t2.h +++ b/arch/alpha/include/asm/core_t2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_T2__H__ #define __ALPHA_T2__H__ diff --git a/arch/alpha/include/asm/core_titan.h b/arch/alpha/include/asm/core_titan.h index 8cf79d1219e1..dcc02682c1e1 100644 --- a/arch/alpha/include/asm/core_titan.h +++ b/arch/alpha/include/asm/core_titan.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_TITAN__H__ #define __ALPHA_TITAN__H__ diff --git a/arch/alpha/include/asm/core_tsunami.h b/arch/alpha/include/asm/core_tsunami.h index 8e39ecf09419..3391e95754f2 100644 --- a/arch/alpha/include/asm/core_tsunami.h +++ b/arch/alpha/include/asm/core_tsunami.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_TSUNAMI__H__ #define __ALPHA_TSUNAMI__H__ diff --git a/arch/alpha/include/asm/core_wildfire.h b/arch/alpha/include/asm/core_wildfire.h index cd562f544ba2..5d1b37f412cd 100644 --- a/arch/alpha/include/asm/core_wildfire.h +++ b/arch/alpha/include/asm/core_wildfire.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_WILDFIRE__H__ #define __ALPHA_WILDFIRE__H__ diff --git a/arch/alpha/include/asm/delay.h b/arch/alpha/include/asm/delay.h index 2aa3f410f7e6..868aa61aba2f 100644 --- a/arch/alpha/include/asm/delay.h +++ b/arch/alpha/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_DELAY_H #define __ALPHA_DELAY_H diff --git a/arch/alpha/include/asm/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h index 5d53666935e6..e542cb272b67 100644 --- a/arch/alpha/include/asm/dma-mapping.h +++ b/arch/alpha/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_DMA_MAPPING_H #define _ALPHA_DMA_MAPPING_H diff --git a/arch/alpha/include/asm/dma.h b/arch/alpha/include/asm/dma.h index 87cfdbdf08fc..28610ea7786d 100644 --- a/arch/alpha/include/asm/dma.h +++ b/arch/alpha/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-alpha/dma.h * diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h index 968d9991f5ee..8049997fa372 100644 --- a/arch/alpha/include/asm/elf.h +++ b/arch/alpha/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ALPHA_ELF_H #define __ASM_ALPHA_ELF_H diff --git a/arch/alpha/include/asm/err_common.h b/arch/alpha/include/asm/err_common.h index c25095942107..610e01fe73ab 100644 --- a/arch/alpha/include/asm/err_common.h +++ b/arch/alpha/include/asm/err_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-alpha/err_common.h * diff --git a/arch/alpha/include/asm/err_ev7.h b/arch/alpha/include/asm/err_ev7.h index 87f99777c2e4..ab17e6333764 100644 --- a/arch/alpha/include/asm/err_ev7.h +++ b/arch/alpha/include/asm/err_ev7.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_ERR_EV7_H #define __ALPHA_ERR_EV7_H 1 diff --git a/arch/alpha/include/asm/extable.h b/arch/alpha/include/asm/extable.h index 048e209e524c..e42592390ee0 100644 --- a/arch/alpha/include/asm/extable.h +++ b/arch/alpha/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_EXTABLE_H #define _ASM_EXTABLE_H diff --git a/arch/alpha/include/asm/fb.h b/arch/alpha/include/asm/fb.h deleted file mode 100644 index fa9bbb96b2b3..000000000000 --- a/arch/alpha/include/asm/fb.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _ASM_FB_H_ -#define _ASM_FB_H_ -#include - -/* Caching is off in the I/O space quadrant by design. */ -#define fb_pgprotect(...) do {} while (0) - -static inline int fb_is_primary_device(struct fb_info *info) -{ - return 0; -} - -#endif /* _ASM_FB_H_ */ diff --git a/arch/alpha/include/asm/fpu.h b/arch/alpha/include/asm/fpu.h index 71c20956b905..b9691405e56b 100644 --- a/arch/alpha/include/asm/fpu.h +++ b/arch/alpha/include/asm/fpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ALPHA_FPU_H #define __ASM_ALPHA_FPU_H diff --git a/arch/alpha/include/asm/futex.h b/arch/alpha/include/asm/futex.h index fb01dfb760c2..d2e4da93e68c 100644 --- a/arch/alpha/include/asm/futex.h +++ b/arch/alpha/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ALPHA_FUTEX_H #define _ASM_ALPHA_FUTEX_H @@ -25,18 +26,10 @@ : "r" (uaddr), "r"(oparg) \ : "memory") -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -62,17 +55,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/alpha/include/asm/gct.h b/arch/alpha/include/asm/gct.h index 3504c704927c..2847449fb168 100644 --- a/arch/alpha/include/asm/gct.h +++ b/arch/alpha/include/asm/gct.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_GCT_H #define __ALPHA_GCT_H diff --git a/arch/alpha/include/asm/hardirq.h b/arch/alpha/include/asm/hardirq.h index 242c09ba98c4..5ce5b34e8a1a 100644 --- a/arch/alpha/include/asm/hardirq.h +++ b/arch/alpha/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_HARDIRQ_H #define _ALPHA_HARDIRQ_H diff --git a/arch/alpha/include/asm/hw_irq.h b/arch/alpha/include/asm/hw_irq.h index 5050ac81cd90..e2d81ac0d934 100644 --- a/arch/alpha/include/asm/hw_irq.h +++ b/arch/alpha/include/asm/hw_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_HW_IRQ_H #define _ALPHA_HW_IRQ_H diff --git a/arch/alpha/include/asm/hwrpb.h b/arch/alpha/include/asm/hwrpb.h index 8e8f871af7cf..d8180e527a1e 100644 --- a/arch/alpha/include/asm/hwrpb.h +++ b/arch/alpha/include/asm/hwrpb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_HWRPB_H #define __ALPHA_HWRPB_H diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h index 4d61d2a50c52..d123ff90f7a8 100644 --- a/arch/alpha/include/asm/io.h +++ b/arch/alpha/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_IO_H #define __ALPHA_IO_H diff --git a/arch/alpha/include/asm/io_trivial.h b/arch/alpha/include/asm/io_trivial.h index 1c77f10b4b36..ba3d8f0cfe0c 100644 --- a/arch/alpha/include/asm/io_trivial.h +++ b/arch/alpha/include/asm/io_trivial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Trivial implementations of basic i/o routines. Assumes that all of the hard work has been done by ioremap and ioportmap, and that access to i/o space is linear. */ diff --git a/arch/alpha/include/asm/irq.h b/arch/alpha/include/asm/irq.h index 06377400dc09..4d17cacd1462 100644 --- a/arch/alpha/include/asm/irq.h +++ b/arch/alpha/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_IRQ_H #define _ALPHA_IRQ_H diff --git a/arch/alpha/include/asm/irqflags.h b/arch/alpha/include/asm/irqflags.h index ffb1726484af..9f25d4e0d37e 100644 --- a/arch/alpha/include/asm/irqflags.h +++ b/arch/alpha/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_IRQFLAGS_H #define __ALPHA_IRQFLAGS_H diff --git a/arch/alpha/include/asm/jensen.h b/arch/alpha/include/asm/jensen.h index 964b06ead43b..436dc905b6ad 100644 --- a/arch/alpha/include/asm/jensen.h +++ b/arch/alpha/include/asm/jensen.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_JENSEN_H #define __ALPHA_JENSEN_H diff --git a/arch/alpha/include/asm/kmap_types.h b/arch/alpha/include/asm/kmap_types.h index a8d4ec8ea4b6..651714b45729 100644 --- a/arch/alpha/include/asm/kmap_types.h +++ b/arch/alpha/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H diff --git a/arch/alpha/include/asm/linkage.h b/arch/alpha/include/asm/linkage.h index 7cfd06e8c935..aa8661fa60dc 100644 --- a/arch/alpha/include/asm/linkage.h +++ b/arch/alpha/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/alpha/include/asm/local.h b/arch/alpha/include/asm/local.h index 9c94b8456043..fab26a1c93d5 100644 --- a/arch/alpha/include/asm/local.h +++ b/arch/alpha/include/asm/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_LOCAL_H #define _ALPHA_LOCAL_H diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h index 75cb3641ed2f..a6b73c6d10ee 100644 --- a/arch/alpha/include/asm/machvec.h +++ b/arch/alpha/include/asm/machvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_MACHVEC_H #define __ALPHA_MACHVEC_H 1 diff --git a/arch/alpha/include/asm/mc146818rtc.h b/arch/alpha/include/asm/mc146818rtc.h index 097703f1c8cb..2154fd4f7857 100644 --- a/arch/alpha/include/asm/mc146818rtc.h +++ b/arch/alpha/include/asm/mc146818rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine dependent access functions for RTC registers. */ diff --git a/arch/alpha/include/asm/mce.h b/arch/alpha/include/asm/mce.h index 660285b9aca8..200e04e98a2f 100644 --- a/arch/alpha/include/asm/mce.h +++ b/arch/alpha/include/asm/mce.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_MCE_H #define __ALPHA_MCE_H diff --git a/arch/alpha/include/asm/mmu.h b/arch/alpha/include/asm/mmu.h index 3dc127779329..dadfc1b6e3e7 100644 --- a/arch/alpha/include/asm/mmu.h +++ b/arch/alpha/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_MMU_H #define __ALPHA_MMU_H diff --git a/arch/alpha/include/asm/mmu_context.h b/arch/alpha/include/asm/mmu_context.h index 384bd47b5187..6d7d9bc1b4b8 100644 --- a/arch/alpha/include/asm/mmu_context.h +++ b/arch/alpha/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_MMU_CONTEXT_H #define __ALPHA_MMU_CONTEXT_H @@ -8,6 +9,7 @@ */ #include +#include #include #include diff --git a/arch/alpha/include/asm/mmzone.h b/arch/alpha/include/asm/mmzone.h index 14ce27bccd24..889b5d3ad825 100644 --- a/arch/alpha/include/asm/mmzone.h +++ b/arch/alpha/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99 * Adapted for the alpha wildfire architecture Jan 2001. diff --git a/arch/alpha/include/asm/module.h b/arch/alpha/include/asm/module.h index 9cd13b55155f..1e96e42f5d54 100644 --- a/arch/alpha/include/asm/module.h +++ b/arch/alpha/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_MODULE_H #define _ALPHA_MODULE_H diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h index 07af062544fb..f3fb2848470a 100644 --- a/arch/alpha/include/asm/page.h +++ b/arch/alpha/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_PAGE_H #define _ALPHA_PAGE_H diff --git a/arch/alpha/include/asm/pal.h b/arch/alpha/include/asm/pal.h index 5422a47646fc..db2b3b18b34c 100644 --- a/arch/alpha/include/asm/pal.h +++ b/arch/alpha/include/asm/pal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_PAL_H #define __ALPHA_PAL_H diff --git a/arch/alpha/include/asm/param.h b/arch/alpha/include/asm/param.h index a5b68b268bcf..cfe947ce9461 100644 --- a/arch/alpha/include/asm/param.h +++ b/arch/alpha/include/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ALPHA_PARAM_H #define _ASM_ALPHA_PARAM_H diff --git a/arch/alpha/include/asm/parport.h b/arch/alpha/include/asm/parport.h index 6abd0af11f13..0519a51e61f8 100644 --- a/arch/alpha/include/asm/parport.h +++ b/arch/alpha/include/asm/parport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * parport.h: platform-specific PC-style parport initialisation * diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h index a06c24b3a2e1..fc988c16e894 100644 --- a/arch/alpha/include/asm/pci.h +++ b/arch/alpha/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_PCI_H #define __ALPHA_PCI_H diff --git a/arch/alpha/include/asm/percpu.h b/arch/alpha/include/asm/percpu.h index 2c12378e3aa9..6923249f2d49 100644 --- a/arch/alpha/include/asm/percpu.h +++ b/arch/alpha/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_PERCPU_H #define __ALPHA_PERCPU_H diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h index c2ebb6f36c9d..ab3e3a8638fb 100644 --- a/arch/alpha/include/asm/pgalloc.h +++ b/arch/alpha/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_PGALLOC_H #define _ALPHA_PGALLOC_H diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h index a9a119592372..89c2032f9960 100644 --- a/arch/alpha/include/asm/pgtable.h +++ b/arch/alpha/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_PGTABLE_H #define _ALPHA_PGTABLE_H diff --git a/arch/alpha/include/asm/processor.h b/arch/alpha/include/asm/processor.h index 2fec2dee3020..bfe784f2d4af 100644 --- a/arch/alpha/include/asm/processor.h +++ b/arch/alpha/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-alpha/processor.h * diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h index 9047c2fe8f23..df5f317ab3fc 100644 --- a/arch/alpha/include/asm/ptrace.h +++ b/arch/alpha/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMAXP_PTRACE_H #define _ASMAXP_PTRACE_H diff --git a/arch/alpha/include/asm/rwsem.h b/arch/alpha/include/asm/rwsem.h index 77873d0ad293..3925f06afd6b 100644 --- a/arch/alpha/include/asm/rwsem.h +++ b/arch/alpha/include/asm/rwsem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_RWSEM_H #define _ALPHA_RWSEM_H diff --git a/arch/alpha/include/asm/serial.h b/arch/alpha/include/asm/serial.h index e31557fc06cc..91115447319c 100644 --- a/arch/alpha/include/asm/serial.h +++ b/arch/alpha/include/asm/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-alpha/serial.h */ diff --git a/arch/alpha/include/asm/shmparam.h b/arch/alpha/include/asm/shmparam.h index cc901d58aebb..0c04fde1aeba 100644 --- a/arch/alpha/include/asm/shmparam.h +++ b/arch/alpha/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMAXP_SHMPARAM_H #define _ASMAXP_SHMPARAM_H diff --git a/arch/alpha/include/asm/signal.h b/arch/alpha/include/asm/signal.h index 963f0494dca7..a40f02011667 100644 --- a/arch/alpha/include/asm/signal.h +++ b/arch/alpha/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMAXP_SIGNAL_H #define _ASMAXP_SIGNAL_H diff --git a/arch/alpha/include/asm/smp.h b/arch/alpha/include/asm/smp.h index c46e714aa3e0..2264ae72673b 100644 --- a/arch/alpha/include/asm/smp.h +++ b/arch/alpha/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SMP_H #define __ASM_SMP_H diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h index 8d806d80ed24..76a32817e7be 100644 --- a/arch/alpha/include/asm/socket.h +++ b/arch/alpha/include/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SOCKET_H #define _ASM_SOCKET_H diff --git a/arch/alpha/include/asm/special_insns.h b/arch/alpha/include/asm/special_insns.h index 88d3452b21f0..ca2c5c30b22e 100644 --- a/arch/alpha/include/asm/special_insns.h +++ b/arch/alpha/include/asm/special_insns.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_SPECIAL_INSNS_H #define __ALPHA_SPECIAL_INSNS_H diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h index a40b9fc0c6c3..aa4304afbea6 100644 --- a/arch/alpha/include/asm/spinlock.h +++ b/arch/alpha/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_SPINLOCK_H #define _ALPHA_SPINLOCK_H @@ -16,11 +17,6 @@ #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) #define arch_spin_is_locked(x) ((x)->lock != 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - static inline int arch_spin_value_unlocked(arch_spinlock_t lock) { return lock.lock == 0; diff --git a/arch/alpha/include/asm/spinlock_types.h b/arch/alpha/include/asm/spinlock_types.h index 54c2afce0a1d..1d5716bc060b 100644 --- a/arch/alpha/include/asm/spinlock_types.h +++ b/arch/alpha/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_SPINLOCK_TYPES_H #define _ALPHA_SPINLOCK_TYPES_H diff --git a/arch/alpha/include/asm/string.h b/arch/alpha/include/asm/string.h index c2911f591704..f043f91ff988 100644 --- a/arch/alpha/include/asm/string.h +++ b/arch/alpha/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_STRING_H__ #define __ALPHA_STRING_H__ @@ -65,13 +66,14 @@ extern void * memchr(const void *, int, size_t); aligned values. The DEST and COUNT parameters must be even for correct operation. */ -#define __HAVE_ARCH_MEMSETW -extern void * __memsetw(void *dest, unsigned short, size_t count); - -#define memsetw(s, c, n) \ -(__builtin_constant_p(c) \ - ? __constant_c_memset((s),0x0001000100010001UL*(unsigned short)(c),(n)) \ - : __memsetw((s),(c),(n))) +#define __HAVE_ARCH_MEMSET16 +extern void * __memset16(void *dest, unsigned short, size_t count); +static inline void *memset16(uint16_t *p, uint16_t v, size_t n) +{ + if (__builtin_constant_p(v)) + return __constant_c_memset(p, 0x0001000100010001UL * v, n * 2); + return __memset16(p, v, n * 2); +} #endif /* __KERNEL__ */ diff --git a/arch/alpha/include/asm/switch_to.h b/arch/alpha/include/asm/switch_to.h index 44c0d4f2c0b2..762b7f975310 100644 --- a/arch/alpha/include/asm/switch_to.h +++ b/arch/alpha/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_SWITCH_TO_H #define __ALPHA_SWITCH_TO_H diff --git a/arch/alpha/include/asm/syscall.h b/arch/alpha/include/asm/syscall.h index 88d28eb2a566..d73a6fcb519c 100644 --- a/arch/alpha/include/asm/syscall.h +++ b/arch/alpha/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ALPHA_SYSCALL_H #define _ASM_ALPHA_SYSCALL_H diff --git a/arch/alpha/include/asm/termios.h b/arch/alpha/include/asm/termios.h index 7fde0f88da88..6a8c53dec57e 100644 --- a/arch/alpha/include/asm/termios.h +++ b/arch/alpha/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_TERMIOS_H #define _ALPHA_TERMIOS_H diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index e9e90bfa2b50..8c20c5e35432 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_THREAD_INFO_H #define _ALPHA_THREAD_INFO_H diff --git a/arch/alpha/include/asm/timex.h b/arch/alpha/include/asm/timex.h index afa0c45e3e98..b565cc6f408e 100644 --- a/arch/alpha/include/asm/timex.h +++ b/arch/alpha/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-alpha/timex.h * diff --git a/arch/alpha/include/asm/tlb.h b/arch/alpha/include/asm/tlb.h index 42866759f3fa..8f5042b61875 100644 --- a/arch/alpha/include/asm/tlb.h +++ b/arch/alpha/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_TLB_H #define _ALPHA_TLB_H diff --git a/arch/alpha/include/asm/tlbflush.h b/arch/alpha/include/asm/tlbflush.h index e89e0c2e15b1..f8b492408f51 100644 --- a/arch/alpha/include/asm/tlbflush.h +++ b/arch/alpha/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_TLBFLUSH_H #define _ALPHA_TLBFLUSH_H diff --git a/arch/alpha/include/asm/topology.h b/arch/alpha/include/asm/topology.h index 9251e13e144f..e6e13a85796a 100644 --- a/arch/alpha/include/asm/topology.h +++ b/arch/alpha/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ALPHA_TOPOLOGY_H #define _ASM_ALPHA_TOPOLOGY_H diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h index 0bc66e1d3a7e..b60b60276484 100644 --- a/arch/alpha/include/asm/types.h +++ b/arch/alpha/include/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_TYPES_H #define _ALPHA_TYPES_H diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h index 133a4884ed44..87d8c4f0307d 100644 --- a/arch/alpha/include/asm/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ALPHA_UACCESS_H #define __ALPHA_UACCESS_H diff --git a/arch/alpha/include/asm/ucontext.h b/arch/alpha/include/asm/ucontext.h index 47578ab42152..af1f3465b8d7 100644 --- a/arch/alpha/include/asm/ucontext.h +++ b/arch/alpha/include/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMAXP_UCONTEXT_H #define _ASMAXP_UCONTEXT_H diff --git a/arch/alpha/include/asm/unaligned.h b/arch/alpha/include/asm/unaligned.h index 3787c60aed3f..863c807b66f8 100644 --- a/arch/alpha/include/asm/unaligned.h +++ b/arch/alpha/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ALPHA_UNALIGNED_H #define _ASM_ALPHA_UNALIGNED_H diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index db7fc0f511e2..d6e29a1de4cc 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_UNISTD_H #define _ALPHA_UNISTD_H diff --git a/arch/alpha/include/asm/user.h b/arch/alpha/include/asm/user.h index a4eb6a4ca8d1..3df37492c7b7 100644 --- a/arch/alpha/include/asm/user.h +++ b/arch/alpha/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_USER_H #define _ALPHA_USER_H diff --git a/arch/alpha/include/asm/vga.h b/arch/alpha/include/asm/vga.h index c00106bac521..4c347a8454c7 100644 --- a/arch/alpha/include/asm/vga.h +++ b/arch/alpha/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access to VGA videoram * @@ -34,7 +35,7 @@ static inline void scr_memsetw(u16 *s, u16 c, unsigned int count) if (__is_ioaddr(s)) memsetw_io((u16 __iomem *) s, c, count); else - memsetw(s, c, count); + memset16(s, c, count / 2); } /* Do not trust that the usage will be correct; analyze the arguments. */ diff --git a/arch/alpha/include/asm/word-at-a-time.h b/arch/alpha/include/asm/word-at-a-time.h index 902e6ab00a06..4035265f1ad9 100644 --- a/arch/alpha/include/asm/word-at-a-time.h +++ b/arch/alpha/include/asm/word-at-a-time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_WORD_AT_A_TIME_H #define _ASM_WORD_AT_A_TIME_H diff --git a/arch/alpha/include/asm/wrperfmon.h b/arch/alpha/include/asm/wrperfmon.h index 319bf6788d87..c97b82a1f7db 100644 --- a/arch/alpha/include/asm/wrperfmon.h +++ b/arch/alpha/include/asm/wrperfmon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for use with the Alpha wrperfmon PAL call. */ diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h index 0ca9724597c1..68dfb3cb7145 100644 --- a/arch/alpha/include/asm/xchg.h +++ b/arch/alpha/include/asm/xchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ALPHA_CMPXCHG_H #error Do not include xchg.h directly! #else diff --git a/arch/alpha/include/uapi/asm/a.out.h b/arch/alpha/include/uapi/asm/a.out.h index 547707246f63..7d692df04ba9 100644 --- a/arch/alpha/include/uapi/asm/a.out.h +++ b/arch/alpha/include/uapi/asm/a.out.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ALPHA_A_OUT_H__ #define _UAPI__ALPHA_A_OUT_H__ diff --git a/arch/alpha/include/uapi/asm/auxvec.h b/arch/alpha/include/uapi/asm/auxvec.h index a3a579dfdb4d..57cae8780d81 100644 --- a/arch/alpha/include/uapi/asm/auxvec.h +++ b/arch/alpha/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_ALPHA_AUXVEC_H #define __ASM_ALPHA_AUXVEC_H diff --git a/arch/alpha/include/uapi/asm/bitsperlong.h b/arch/alpha/include/uapi/asm/bitsperlong.h index ad57f7868203..6c5bf7d03f4e 100644 --- a/arch/alpha/include/uapi/asm/bitsperlong.h +++ b/arch/alpha/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_ALPHA_BITSPERLONG_H #define __ASM_ALPHA_BITSPERLONG_H diff --git a/arch/alpha/include/uapi/asm/byteorder.h b/arch/alpha/include/uapi/asm/byteorder.h index 73683093202d..efa9b51b4595 100644 --- a/arch/alpha/include/uapi/asm/byteorder.h +++ b/arch/alpha/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_BYTEORDER_H #define _ALPHA_BYTEORDER_H diff --git a/arch/alpha/include/uapi/asm/compiler.h b/arch/alpha/include/uapi/asm/compiler.h index 32cc7833f0c1..0e00c0e13374 100644 --- a/arch/alpha/include/uapi/asm/compiler.h +++ b/arch/alpha/include/uapi/asm/compiler.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ALPHA_COMPILER_H #define _UAPI__ALPHA_COMPILER_H diff --git a/arch/alpha/include/uapi/asm/console.h b/arch/alpha/include/uapi/asm/console.h index fd08a191f360..5fcb65300b56 100644 --- a/arch/alpha/include/uapi/asm/console.h +++ b/arch/alpha/include/uapi/asm/console.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__AXP_CONSOLE_H #define _UAPI__AXP_CONSOLE_H diff --git a/arch/alpha/include/uapi/asm/errno.h b/arch/alpha/include/uapi/asm/errno.h index 17f92aa76b2f..3d265f6babaf 100644 --- a/arch/alpha/include/uapi/asm/errno.h +++ b/arch/alpha/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_ERRNO_H #define _ALPHA_ERRNO_H diff --git a/arch/alpha/include/uapi/asm/fcntl.h b/arch/alpha/include/uapi/asm/fcntl.h index 09f49a6b87d1..50bdc8e8a271 100644 --- a/arch/alpha/include/uapi/asm/fcntl.h +++ b/arch/alpha/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_FCNTL_H #define _ALPHA_FCNTL_H diff --git a/arch/alpha/include/uapi/asm/fpu.h b/arch/alpha/include/uapi/asm/fpu.h index 21a053ca2233..cea9eafa056f 100644 --- a/arch/alpha/include/uapi/asm/fpu.h +++ b/arch/alpha/include/uapi/asm/fpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ASM_ALPHA_FPU_H #define _UAPI__ASM_ALPHA_FPU_H diff --git a/arch/alpha/include/uapi/asm/gentrap.h b/arch/alpha/include/uapi/asm/gentrap.h index ae50cc3192c7..c02ccc5ecec0 100644 --- a/arch/alpha/include/uapi/asm/gentrap.h +++ b/arch/alpha/include/uapi/asm/gentrap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMAXP_GENTRAP_H #define _ASMAXP_GENTRAP_H diff --git a/arch/alpha/include/uapi/asm/ioctl.h b/arch/alpha/include/uapi/asm/ioctl.h index fc63727f4178..a9d68a08ee84 100644 --- a/arch/alpha/include/uapi/asm/ioctl.h +++ b/arch/alpha/include/uapi/asm/ioctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_IOCTL_H #define _ALPHA_IOCTL_H diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h index 1cd7dc7d4870..3729d92d3fa8 100644 --- a/arch/alpha/include/uapi/asm/ioctls.h +++ b/arch/alpha/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_ALPHA_IOCTLS_H #define _ASM_ALPHA_IOCTLS_H diff --git a/arch/alpha/include/uapi/asm/ipcbuf.h b/arch/alpha/include/uapi/asm/ipcbuf.h index 84c7e51cb6d0..90d6445a14df 100644 --- a/arch/alpha/include/uapi/asm/ipcbuf.h +++ b/arch/alpha/include/uapi/asm/ipcbuf.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/alpha/include/uapi/asm/kvm_para.h b/arch/alpha/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/alpha/include/uapi/asm/kvm_para.h +++ b/arch/alpha/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/alpha/include/uapi/asm/mman.h b/arch/alpha/include/uapi/asm/mman.h index 02760f6e6ca4..6bf730063e3f 100644 --- a/arch/alpha/include/uapi/asm/mman.h +++ b/arch/alpha/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ALPHA_MMAN_H__ #define __ALPHA_MMAN_H__ @@ -64,20 +65,12 @@ overrides the coredump filter bits */ #define MADV_DODUMP 17 /* Clear the MADV_NODUMP flag */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + /* compatibility flags */ #define MAP_FILE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/arch/alpha/include/uapi/asm/msgbuf.h b/arch/alpha/include/uapi/asm/msgbuf.h index 98496501a2bb..8c5d4d8c1b16 100644 --- a/arch/alpha/include/uapi/asm/msgbuf.h +++ b/arch/alpha/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_MSGBUF_H #define _ALPHA_MSGBUF_H diff --git a/arch/alpha/include/uapi/asm/pal.h b/arch/alpha/include/uapi/asm/pal.h index dfc8140b9088..7427e028db64 100644 --- a/arch/alpha/include/uapi/asm/pal.h +++ b/arch/alpha/include/uapi/asm/pal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ALPHA_PAL_H #define _UAPI__ALPHA_PAL_H diff --git a/arch/alpha/include/uapi/asm/param.h b/arch/alpha/include/uapi/asm/param.h index dbcd9834af6d..49c7119934e2 100644 --- a/arch/alpha/include/uapi/asm/param.h +++ b/arch/alpha/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_ALPHA_PARAM_H #define _UAPI_ASM_ALPHA_PARAM_H diff --git a/arch/alpha/include/uapi/asm/poll.h b/arch/alpha/include/uapi/asm/poll.h index c98509d3149e..b7132a305a47 100644 --- a/arch/alpha/include/uapi/asm/poll.h +++ b/arch/alpha/include/uapi/asm/poll.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/alpha/include/uapi/asm/posix_types.h b/arch/alpha/include/uapi/asm/posix_types.h index 5a8a48320efe..04f1ea57505b 100644 --- a/arch/alpha/include/uapi/asm/posix_types.h +++ b/arch/alpha/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_POSIX_TYPES_H #define _ALPHA_POSIX_TYPES_H diff --git a/arch/alpha/include/uapi/asm/ptrace.h b/arch/alpha/include/uapi/asm/ptrace.h index 5ce83fa9a05b..1dfd065e45b1 100644 --- a/arch/alpha/include/uapi/asm/ptrace.h +++ b/arch/alpha/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASMAXP_PTRACE_H #define _UAPI_ASMAXP_PTRACE_H diff --git a/arch/alpha/include/uapi/asm/reg.h b/arch/alpha/include/uapi/asm/reg.h index 86ff916fb069..2652f3a385f7 100644 --- a/arch/alpha/include/uapi/asm/reg.h +++ b/arch/alpha/include/uapi/asm/reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __reg_h__ #define __reg_h__ diff --git a/arch/alpha/include/uapi/asm/regdef.h b/arch/alpha/include/uapi/asm/regdef.h index 142df9c4f8b8..cc99df0c60a5 100644 --- a/arch/alpha/include/uapi/asm/regdef.h +++ b/arch/alpha/include/uapi/asm/regdef.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __alpha_regdef_h__ #define __alpha_regdef_h__ diff --git a/arch/alpha/include/uapi/asm/resource.h b/arch/alpha/include/uapi/asm/resource.h index c10874ff5973..362423ffe10b 100644 --- a/arch/alpha/include/uapi/asm/resource.h +++ b/arch/alpha/include/uapi/asm/resource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_RESOURCE_H #define _ALPHA_RESOURCE_H diff --git a/arch/alpha/include/uapi/asm/sembuf.h b/arch/alpha/include/uapi/asm/sembuf.h index 7b38b1534784..f28ffa668b2f 100644 --- a/arch/alpha/include/uapi/asm/sembuf.h +++ b/arch/alpha/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_SEMBUF_H #define _ALPHA_SEMBUF_H diff --git a/arch/alpha/include/uapi/asm/setup.h b/arch/alpha/include/uapi/asm/setup.h index b50014b30909..13b7ee465b0e 100644 --- a/arch/alpha/include/uapi/asm/setup.h +++ b/arch/alpha/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ALPHA_SETUP_H #define __ALPHA_SETUP_H diff --git a/arch/alpha/include/uapi/asm/shmbuf.h b/arch/alpha/include/uapi/asm/shmbuf.h index 37ee84f05085..7e041ca2eb40 100644 --- a/arch/alpha/include/uapi/asm/shmbuf.h +++ b/arch/alpha/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_SHMBUF_H #define _ALPHA_SHMBUF_H diff --git a/arch/alpha/include/uapi/asm/sigcontext.h b/arch/alpha/include/uapi/asm/sigcontext.h index 323cdb026198..5428c42567e6 100644 --- a/arch/alpha/include/uapi/asm/sigcontext.h +++ b/arch/alpha/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMAXP_SIGCONTEXT_H #define _ASMAXP_SIGCONTEXT_H diff --git a/arch/alpha/include/uapi/asm/siginfo.h b/arch/alpha/include/uapi/asm/siginfo.h index 9822362a8424..0cf3b527b274 100644 --- a/arch/alpha/include/uapi/asm/siginfo.h +++ b/arch/alpha/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_SIGINFO_H #define _ALPHA_SIGINFO_H @@ -6,4 +7,18 @@ #include +/* + * SIGFPE si_codes + */ +#ifdef __KERNEL__ +#define FPE_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ + +/* + * SIGTRAP si_codes + */ +#ifdef __KERNEL__ +#define TRAP_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ + #endif diff --git a/arch/alpha/include/uapi/asm/signal.h b/arch/alpha/include/uapi/asm/signal.h index dd4ca4bcbb4a..74c750bf1c1a 100644 --- a/arch/alpha/include/uapi/asm/signal.h +++ b/arch/alpha/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASMAXP_SIGNAL_H #define _UAPI_ASMAXP_SIGNAL_H diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index 7b285dd4fe05..be14f16149d5 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_SOCKET_H #define _UAPI_ASM_SOCKET_H @@ -109,4 +110,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/alpha/include/uapi/asm/sockios.h b/arch/alpha/include/uapi/asm/sockios.h index 7932c7ab4a4d..ba287e4b01bf 100644 --- a/arch/alpha/include/uapi/asm/sockios.h +++ b/arch/alpha/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_ALPHA_SOCKIOS_H #define _ASM_ALPHA_SOCKIOS_H diff --git a/arch/alpha/include/uapi/asm/stat.h b/arch/alpha/include/uapi/asm/stat.h index 07ad3e6b3f3e..3f454fbd307a 100644 --- a/arch/alpha/include/uapi/asm/stat.h +++ b/arch/alpha/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_STAT_H #define _ALPHA_STAT_H diff --git a/arch/alpha/include/uapi/asm/statfs.h b/arch/alpha/include/uapi/asm/statfs.h index ccd2e186bfd8..95852a4f576d 100644 --- a/arch/alpha/include/uapi/asm/statfs.h +++ b/arch/alpha/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_STATFS_H #define _ALPHA_STATFS_H diff --git a/arch/alpha/include/uapi/asm/swab.h b/arch/alpha/include/uapi/asm/swab.h index 4d682b16c7c4..1cc70d2727f7 100644 --- a/arch/alpha/include/uapi/asm/swab.h +++ b/arch/alpha/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_SWAB_H #define _ALPHA_SWAB_H diff --git a/arch/alpha/include/uapi/asm/sysinfo.h b/arch/alpha/include/uapi/asm/sysinfo.h index 0b80e79d75e5..188ea76c7f2f 100644 --- a/arch/alpha/include/uapi/asm/sysinfo.h +++ b/arch/alpha/include/uapi/asm/sysinfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * include/asm-alpha/sysinfo.h */ diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h index 879dd3589921..05e0398a83a6 100644 --- a/arch/alpha/include/uapi/asm/termbits.h +++ b/arch/alpha/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ALPHA_TERMBITS_H #define _ALPHA_TERMBITS_H diff --git a/arch/alpha/include/uapi/asm/termios.h b/arch/alpha/include/uapi/asm/termios.h index 580ed1e4854c..e1b981222a24 100644 --- a/arch/alpha/include/uapi/asm/termios.h +++ b/arch/alpha/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ALPHA_TERMIOS_H #define _UAPI_ALPHA_TERMIOS_H diff --git a/arch/alpha/include/uapi/asm/types.h b/arch/alpha/include/uapi/asm/types.h index 8d1024d7be05..6c3d49938126 100644 --- a/arch/alpha/include/uapi/asm/types.h +++ b/arch/alpha/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ALPHA_TYPES_H #define _UAPI_ALPHA_TYPES_H diff --git a/arch/alpha/include/uapi/asm/unistd.h b/arch/alpha/include/uapi/asm/unistd.h index a2945fea6c86..e153ca6e15d6 100644 --- a/arch/alpha/include/uapi/asm/unistd.h +++ b/arch/alpha/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ALPHA_UNISTD_H #define _UAPI_ALPHA_UNISTD_H @@ -366,11 +367,6 @@ #define __NR_epoll_create 407 #define __NR_epoll_ctl 408 #define __NR_epoll_wait 409 -/* Feb 2007: These three sys_epoll defines shouldn't be here but culling - * them would break userspace apps ... we'll kill them off in 2010 :) */ -#define __NR_sys_epoll_create __NR_epoll_create -#define __NR_sys_epoll_ctl __NR_epoll_ctl -#define __NR_sys_epoll_wait __NR_epoll_wait #define __NR_remap_file_pages 410 #define __NR_set_tid_address 411 #define __NR_restart_syscall 412 diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 8ce13d7a2ad3..bf7b41fa7b01 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/alpha/kernel/asm-offsets.c b/arch/alpha/kernel/asm-offsets.c index 6ff8886e7e22..2e125e5c1508 100644 --- a/arch/alpha/kernel/asm-offsets.c +++ b/arch/alpha/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generate definitions needed by assembly language modules. * This code generates raw asm output which is post-processed to extract diff --git a/arch/alpha/kernel/binfmt_loader.c b/arch/alpha/kernel/binfmt_loader.c index 9525660c93c0..a8d0d6e06526 100644 --- a/arch/alpha/kernel/binfmt_loader.c +++ b/arch/alpha/kernel/binfmt_loader.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c index 6a61deed4a85..8e9a41966881 100644 --- a/arch/alpha/kernel/console.c +++ b/arch/alpha/kernel/console.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/console.c * diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c index 708c831efa76..1bf3eef34c22 100644 --- a/arch/alpha/kernel/core_apecs.c +++ b/arch/alpha/kernel/core_apecs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_apecs.c * diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c index c44339e176c1..4b38386f6e62 100644 --- a/arch/alpha/kernel/core_cia.c +++ b/arch/alpha/kernel/core_cia.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_cia.c * diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c index 83d0a359a1b2..aec757250e07 100644 --- a/arch/alpha/kernel/core_irongate.c +++ b/arch/alpha/kernel/core_irongate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_irongate.c * diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c index cb2801cfd3df..81c0c43635b0 100644 --- a/arch/alpha/kernel/core_lca.c +++ b/arch/alpha/kernel/core_lca.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_lca.c * diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index 03ff832b1cb4..bdebb8c206f1 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_marvel.c * @@ -118,7 +119,7 @@ alloc_io7(unsigned int pe) io7 = alloc_bootmem(sizeof(*io7)); io7->pe = pe; - spin_lock_init(&io7->irq_lock); + raw_spin_lock_init(&io7->irq_lock); for (h = 0; h < 4; h++) { io7->ports[h].io7 = io7; diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c index da7bcc372f16..b1549db54260 100644 --- a/arch/alpha/kernel/core_mcpcia.c +++ b/arch/alpha/kernel/core_mcpcia.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_mcpcia.c * diff --git a/arch/alpha/kernel/core_polaris.c b/arch/alpha/kernel/core_polaris.c index c5a271d37abd..75d622d96ff2 100644 --- a/arch/alpha/kernel/core_polaris.c +++ b/arch/alpha/kernel/core_polaris.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_polaris.c * diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c index 3ada4f7b085d..2c00b61ca379 100644 --- a/arch/alpha/kernel/core_t2.c +++ b/arch/alpha/kernel/core_t2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_t2.c * diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c index b532d925443d..132b06bdf903 100644 --- a/arch/alpha/kernel/core_titan.c +++ b/arch/alpha/kernel/core_titan.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_titan.c * diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c index 61893d7bdda5..e7c956ea46b6 100644 --- a/arch/alpha/kernel/core_tsunami.c +++ b/arch/alpha/kernel/core_tsunami.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_tsunami.c * diff --git a/arch/alpha/kernel/core_wildfire.c b/arch/alpha/kernel/core_wildfire.c index 7e072443d7fd..cad36fc6ed7d 100644 --- a/arch/alpha/kernel/core_wildfire.c +++ b/arch/alpha/kernel/core_wildfire.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/core_wildfire.c * diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 98703d99b565..d92abb01c249 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/kernel/entry.S * diff --git a/arch/alpha/kernel/err_common.c b/arch/alpha/kernel/err_common.c index 13d53b1c9657..94e1b3dcf6d4 100644 --- a/arch/alpha/kernel/err_common.c +++ b/arch/alpha/kernel/err_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/err_common.c * diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c index 51267ac5729b..8144f2045b5b 100644 --- a/arch/alpha/kernel/err_ev6.c +++ b/arch/alpha/kernel/err_ev6.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/err_ev6.c * diff --git a/arch/alpha/kernel/err_ev7.c b/arch/alpha/kernel/err_ev7.c index d738a67112d4..565de1acf1f5 100644 --- a/arch/alpha/kernel/err_ev7.c +++ b/arch/alpha/kernel/err_ev7.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/err_ev7.c * diff --git a/arch/alpha/kernel/err_impl.h b/arch/alpha/kernel/err_impl.h index ae529c416037..737b958a586d 100644 --- a/arch/alpha/kernel/err_impl.h +++ b/arch/alpha/kernel/err_impl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/alpha/kernel/err_impl.h * diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index ae54ad91e18f..c0c0ccefc467 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/err_marvel.c * diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c index 14b26c466c89..0ffb2feea42a 100644 --- a/arch/alpha/kernel/err_titan.c +++ b/arch/alpha/kernel/err_titan.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/err_titan.c * diff --git a/arch/alpha/kernel/es1888.c b/arch/alpha/kernel/es1888.c index d584c85fea7a..297476bb08fb 100644 --- a/arch/alpha/kernel/es1888.c +++ b/arch/alpha/kernel/es1888.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/es1888.c * diff --git a/arch/alpha/kernel/gct.c b/arch/alpha/kernel/gct.c index c0c7155448e0..8ac0088dca54 100644 --- a/arch/alpha/kernel/gct.c +++ b/arch/alpha/kernel/gct.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/gct.c */ diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S index c352499ab9f8..bb48a8ae4e79 100644 --- a/arch/alpha/kernel/head.S +++ b/arch/alpha/kernel/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/kernel/head.S * diff --git a/arch/alpha/kernel/io.c b/arch/alpha/kernel/io.c index 19c5875ab398..3e3d49c254c5 100644 --- a/arch/alpha/kernel/io.c +++ b/arch/alpha/kernel/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Alpha IO and memory functions. */ diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 2f26ae74b61a..f6d2946edbd2 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/irq.c * diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 1c8625cb0e25..da3e10d5f7fe 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Alpha specific irq code. */ diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c index e1861c77dabc..5d54c076a8ae 100644 --- a/arch/alpha/kernel/irq_i8259.c +++ b/arch/alpha/kernel/irq_i8259.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/irq_i8259.c * diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h index d507a234b05d..16f2b0276f3a 100644 --- a/arch/alpha/kernel/irq_impl.h +++ b/arch/alpha/kernel/irq_impl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/alpha/kernel/irq_impl.h * diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c index 13c97a5b31e8..a968b10e687d 100644 --- a/arch/alpha/kernel/irq_pyxis.c +++ b/arch/alpha/kernel/irq_pyxis.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/irq_pyxis.c * diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index a79fa30e7552..bfacd6a06194 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Handle interrupts from the SRM, assuming no additional weirdness. */ diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h index b7d69604b6d2..38f045ec5cd2 100644 --- a/arch/alpha/kernel/machvec_impl.h +++ b/arch/alpha/kernel/machvec_impl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/alpha/kernel/machvec_impl.h * diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index df0d0a5e9353..ce3a675c0c4b 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/osf_sys.c * diff --git a/arch/alpha/kernel/pc873xx.c b/arch/alpha/kernel/pc873xx.c index 27dcbff85613..63aee5d86e02 100644 --- a/arch/alpha/kernel/pc873xx.c +++ b/arch/alpha/kernel/pc873xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/alpha/kernel/pc873xx.h b/arch/alpha/kernel/pc873xx.h index 25e16956fe3e..043533027573 100644 --- a/arch/alpha/kernel/pc873xx.h +++ b/arch/alpha/kernel/pc873xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PC873xx_H_ #define _PC873xx_H_ diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index ffbdb3fb672f..b995987b1557 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/pci-noop.c * @@ -42,11 +43,7 @@ alloc_pci_controller(void) struct resource * __init alloc_resource(void) { - struct resource *res; - - res = alloc_bootmem(sizeof(*res)); - - return res; + return alloc_bootmem(sizeof(struct resource)); } asmlinkage long diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 92c0d460815b..f94c732fedeb 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/kernel/pci-sysfs.c * @@ -38,7 +39,7 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, unsigned long nr, start, size; int shift = sparse ? 5 : 0; - nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + nr = vma_pages(vma); start = vma->vm_pgoff; size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1; @@ -64,8 +65,7 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma, int sparse) { - struct pci_dev *pdev = to_pci_dev(container_of(kobj, - struct device, kobj)); + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); struct resource *res = attr->private; enum pci_mmap_state mmap_type; struct pci_bus_region bar; @@ -255,7 +255,7 @@ static int __legacy_mmap_fits(struct pci_controller *hose, { unsigned long nr, start, size; - nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + nr = vma_pages(vma); start = vma->vm_pgoff; size = ((res_size - 1) >> PAGE_SHIFT) + 1; diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 5f387ee5b5c5..08235bb1f035 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/pci.c * @@ -312,8 +313,9 @@ common_init_pci(void) { struct pci_controller *hose; struct list_head resources; + struct pci_host_bridge *bridge; struct pci_bus *bus; - int next_busno; + int ret, next_busno; int need_domain_info = 0; u32 pci_mem_end; u32 sg_base; @@ -336,11 +338,25 @@ common_init_pci(void) pci_add_resource_offset(&resources, hose->mem_space, hose->mem_space->start); - bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, - hose, &resources); - if (!bus) + bridge = pci_alloc_host_bridge(0); + if (!bridge) continue; - hose->bus = bus; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = alpha_mv.pci_ops; + bridge->swizzle_irq = alpha_mv.pci_swizzle; + bridge->map_irq = alpha_mv.pci_map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + continue; + } + + bus = hose->bus = bridge->bus; hose->need_domain_info = need_domain_info; next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - @@ -354,7 +370,6 @@ common_init_pci(void) pcibios_claim_console_setup(); pci_assign_unassigned_resources(); - pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); for (hose = hose_head; hose; hose = hose->next) { bus = hose->bus; if (bus) @@ -362,7 +377,6 @@ common_init_pci(void) } } - struct pci_controller * __init alloc_pci_controller(void) { @@ -379,11 +393,7 @@ alloc_pci_controller(void) struct resource * __init alloc_resource(void) { - struct resource *res; - - res = alloc_bootmem(sizeof(*res)); - - return res; + return alloc_bootmem(sizeof(struct resource)); } diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index 2b0ac429f5eb..26231601630e 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/alpha/kernel/pci_impl.h * diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 7fd2329038a3..83b34b9188ea 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/pci_iommu.c */ diff --git a/arch/alpha/kernel/perf_event.c b/arch/alpha/kernel/perf_event.c index 5c218aa3f3df..a1f6bc7f1e4c 100644 --- a/arch/alpha/kernel/perf_event.c +++ b/arch/alpha/kernel/perf_event.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Hardware performance events for the Alpha. * diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 0b9635040721..74bfb1f2d68e 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/process.c * diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index da2d6ec9c370..f1fce942fddc 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index 285a82d491ef..cb8d599e72d6 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ptrace.c */ /* By Ross Biro 1/23/92 */ /* edited by Linus Torvalds */ diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c index ceed68c7500b..b3da0dcda47d 100644 --- a/arch/alpha/kernel/rtc.c +++ b/arch/alpha/kernel/rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/rtc.c * diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 491e6a604e82..5576f7646fb6 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/setup.c * @@ -1094,8 +1095,9 @@ get_sysnames(unsigned long type, unsigned long variation, unsigned long cpu, default: /* default to variation "0" for now */ break; case ST_DEC_EB164: - if (member < ARRAY_SIZE(eb164_indices)) - *variation_name = eb164_names[eb164_indices[member]]; + if (member >= ARRAY_SIZE(eb164_indices)) + break; + *variation_name = eb164_names[eb164_indices[member]]; /* PC164 may show as EB164 variation, but with EV56 CPU, so, since no true EB164 had anything but EV5... */ if (eb164_indices[member] == 0 && cpu == EV56_CPU) diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 8129dd92cadc..9ebb3bcbc626 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/signal.c * diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c index c803fc76ae4f..4dbd4e415041 100644 --- a/arch/alpha/kernel/smc37c669.c +++ b/arch/alpha/kernel/smc37c669.c @@ -2007,11 +2007,8 @@ static void __init SMC37c669_config_mode( static unsigned char __init SMC37c669_read_config( unsigned char index ) { - unsigned char data; - - wb( &SMC37c669->index_port, index ); - data = rb( &SMC37c669->data_port ); - return data; + wb(&SMC37c669->index_port, index); + return rb(&SMC37c669->data_port); } /* diff --git a/arch/alpha/kernel/smc37c93x.c b/arch/alpha/kernel/smc37c93x.c index 6886b834f487..733f08966fd2 100644 --- a/arch/alpha/kernel/smc37c93x.c +++ b/arch/alpha/kernel/smc37c93x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SMC 37C93X initialization code */ diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index f6726a746427..d0dccae53ba9 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/smp.c * diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index e9c45b65a905..5da0aec8ce90 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/srmcons.c * diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c index 118dc6af1805..e56efd5b855f 100644 --- a/arch/alpha/kernel/sys_alcor.c +++ b/arch/alpha/kernel/sys_alcor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_alcor.c * @@ -181,10 +182,10 @@ alcor_init_irq(void) * comes in on. This makes interrupt processing much easier. */ -static int __init +static int alcor_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[7][5] __initdata = { + static char irq_tab[7][5] = { /*INT INTA INTB INTC INTD */ /* note: IDSEL 17 is XLT only */ {16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */ diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c index 4c50f8f40cbb..10bc46a4ec40 100644 --- a/arch/alpha/kernel/sys_cabriolet.c +++ b/arch/alpha/kernel/sys_cabriolet.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_cabriolet.c * @@ -173,10 +174,10 @@ pc164_init_irq(void) * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip. */ -static inline int __init +static inline int eb66p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initdata = { + static char irq_tab[5][5] = { /*INT INTA INTB INTC INTD */ {16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J25 */ {16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */ @@ -203,10 +204,10 @@ eb66p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) * because it is the Saturn IO (SIO) PCI/ISA Bridge Chip. */ -static inline int __init +static inline int cabriolet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initdata = { + static char irq_tab[5][5] = { /*INT INTA INTB INTC INTD */ { 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5, slot 2, J21 */ { 16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J19 */ @@ -287,10 +288,10 @@ cia_cab_init_pci(void) * */ -static inline int __init +static inline int alphapc164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[7][5] __initdata = { + static char irq_tab[7][5] = { /*INT INTA INTB INTC INTD */ { 16+2, 16+2, 16+9, 16+13, 16+17}, /* IdSel 5, slot 2, J20 */ { 16+0, 16+0, 16+7, 16+11, 16+15}, /* IdSel 6, slot 0, J29 */ diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 6c35159bc00e..d33508621820 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_dp264.c * @@ -356,7 +357,7 @@ clipper_init_irq(void) * 10 64 bit PCI option slot 3 (not bus 0) */ -static int __init +static int isa_irq_fixup(const struct pci_dev *dev, int irq) { u8 irq8; @@ -372,10 +373,10 @@ isa_irq_fixup(const struct pci_dev *dev, int irq) return irq8 & 0xf; } -static int __init +static int dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[6][5] __initdata = { + static char irq_tab[6][5] = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */ { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ @@ -394,10 +395,10 @@ dp264_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return isa_irq_fixup(dev, irq); } -static int __init +static int monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[13][5] __initdata = { + static char irq_tab[13][5] = { /*INT INTA INTB INTC INTD */ { 45, 45, 45, 45, 45}, /* IdSel 3 21143 PCI1 */ { -1, -1, -1, -1, -1}, /* IdSel 4 unused */ @@ -423,7 +424,7 @@ monet_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); } -static u8 __init +static u8 monet_swizzle(struct pci_dev *dev, u8 *pinp) { struct pci_controller *hose = dev->sysdata; @@ -456,10 +457,10 @@ monet_swizzle(struct pci_dev *dev, u8 *pinp) return slot; } -static int __init +static int webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[13][5] __initdata = { + static char irq_tab[13][5] = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 7 ISA Bridge */ { -1, -1, -1, -1, -1}, /* IdSel 8 unused */ @@ -478,10 +479,10 @@ webbrick_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP); } -static int __init +static int clipper_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[7][5] __initdata = { + static char irq_tab[7][5] = { /*INT INTA INTB INTC INTD */ { 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */ { 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */ diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c index ad40a425e841..5251937ec1b4 100644 --- a/arch/alpha/kernel/sys_eb64p.c +++ b/arch/alpha/kernel/sys_eb64p.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_eb64p.c * @@ -167,10 +168,10 @@ eb64p_init_irq(void) * comes in on. This makes interrupt processing much easier. */ -static int __init +static int eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initdata = { + static char irq_tab[5][5] = { /*INT INTA INTB INTC INTD */ {16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */ {16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */ diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c index 15f42083bdb3..016f79251141 100644 --- a/arch/alpha/kernel/sys_eiger.c +++ b/arch/alpha/kernel/sys_eiger.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_eiger.c * @@ -141,7 +142,7 @@ eiger_init_irq(void) } } -static int __init +static int eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u8 irq_orig; @@ -158,7 +159,7 @@ eiger_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return irq_orig - 0x80; } -static u8 __init +static u8 eiger_swizzle(struct pci_dev *dev, u8 *pinp) { struct pci_controller *hose = dev->sysdata; diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c index 608f2a7fa0a3..d0d44f543d77 100644 --- a/arch/alpha/kernel/sys_jensen.c +++ b/arch/alpha/kernel/sys_jensen.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_jensen.c * diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 24e41bd7d3c9..8d34cf6e002a 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_marvel.c * @@ -115,11 +116,11 @@ io7_enable_irq(struct irq_data *d) return; } - spin_lock(&io7->irq_lock); + raw_spin_lock(&io7->irq_lock); *ctl |= 1UL << 24; mb(); *ctl; - spin_unlock(&io7->irq_lock); + raw_spin_unlock(&io7->irq_lock); } static void @@ -136,11 +137,11 @@ io7_disable_irq(struct irq_data *d) return; } - spin_lock(&io7->irq_lock); + raw_spin_lock(&io7->irq_lock); *ctl &= ~(1UL << 24); mb(); *ctl; - spin_unlock(&io7->irq_lock); + raw_spin_unlock(&io7->irq_lock); } static void @@ -263,7 +264,7 @@ init_io7_irqs(struct io7 *io7, */ printk(" Interrupts reported to CPU at PE %u\n", boot_cpuid); - spin_lock(&io7->irq_lock); + raw_spin_lock(&io7->irq_lock); /* set up the error irqs */ io7_redirect_irq(io7, &io7->csrs->HLT_CTL.csr, boot_cpuid); @@ -295,7 +296,7 @@ init_io7_irqs(struct io7 *io7, for (i = 0; i < 16; ++i) init_one_io7_msi(io7, i, boot_cpuid); - spin_unlock(&io7->irq_lock); + raw_spin_unlock(&io7->irq_lock); } static void __init diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c index d5b9776a608d..6fa07dc5339d 100644 --- a/arch/alpha/kernel/sys_miata.c +++ b/arch/alpha/kernel/sys_miata.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_miata.c * @@ -149,10 +150,10 @@ miata_init_irq(void) * comes in on. This makes interrupt processing much easier. */ -static int __init +static int miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[18][5] __initdata = { + static char irq_tab[18][5] = { /*INT INTA INTB INTC INTD */ {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142 */ { -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */ @@ -196,7 +197,7 @@ miata_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return COMMON_TABLE_LOOKUP; } -static u8 __init +static u8 miata_swizzle(struct pci_dev *dev, u8 *pinp) { int slot, pin = *pinp; diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c index 5e82dc1ad6f2..3af4f94113e1 100644 --- a/arch/alpha/kernel/sys_mikasa.c +++ b/arch/alpha/kernel/sys_mikasa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_mikasa.c * @@ -145,10 +146,10 @@ mikasa_init_irq(void) * comes in on. This makes interrupt processing much easier. */ -static int __init +static int mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[8][5] __initdata = { + static char irq_tab[8][5] = { /*INT INTA INTB INTC INTD */ {16+12, 16+12, 16+12, 16+12, 16+12}, /* IdSel 17, SCSI */ { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */ diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 2cfaa0e5c577..239dc0e601d5 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_nautilus.c * @@ -62,7 +63,7 @@ nautilus_init_irq(void) common_init_isa_dma(); } -static int __init +static int nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* Preserve the IRQ set up by the console. */ @@ -194,22 +195,46 @@ static struct resource irongate_mem = { .name = "Irongate PCI MEM", .flags = IORESOURCE_MEM, }; +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; void __init nautilus_init_pci(void) { struct pci_controller *hose = hose_head; + struct pci_host_bridge *bridge; struct pci_bus *bus; struct pci_dev *irongate; unsigned long bus_align, bus_size, pci_mem; unsigned long memtop = max_low_pfn << PAGE_SHIFT; + int ret; - /* Scan our single hose. */ - bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); - if (!bus) + bridge = pci_alloc_host_bridge(0); + if (!bridge) return; - hose->bus = bus; + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = 0; + bridge->ops = alpha_mv.pci_ops; + bridge->swizzle_irq = alpha_mv.pci_swizzle; + bridge->map_irq = alpha_mv.pci_map_irq; + + /* Scan our single hose. */ + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + bus = hose->bus = bridge->bus; pcibios_claim_one_bus(bus); irongate = pci_get_bus_and_slot(0, 0); @@ -254,7 +279,6 @@ nautilus_init_pci(void) /* pci_common_swizzle() relies on bus->self being NULL for the root bus, so just clear it. */ bus->self = NULL; - pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq); pci_bus_add_devices(bus); } diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c index 063e594fd969..b106f327f765 100644 --- a/arch/alpha/kernel/sys_noritake.c +++ b/arch/alpha/kernel/sys_noritake.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_noritake.c * @@ -193,10 +194,10 @@ noritake_init_irq(void) * comes in on. This makes interrupt processing much easier. */ -static int __init +static int noritake_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[15][5] __initdata = { + static char irq_tab[15][5] = { /*INT INTA INTB INTC INTD */ /* note: IDSELs 16, 17, and 25 are CORELLE only */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */ @@ -221,7 +222,7 @@ noritake_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return COMMON_TABLE_LOOKUP; } -static u8 __init +static u8 noritake_swizzle(struct pci_dev *dev, u8 *pinp) { int slot, pin = *pinp; diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c index dfd510ae5d8c..b76f65d0e8b5 100644 --- a/arch/alpha/kernel/sys_rawhide.c +++ b/arch/alpha/kernel/sys_rawhide.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_rawhide.c * @@ -221,10 +222,10 @@ rawhide_init_irq(void) * */ -static int __init +static int rawhide_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initdata = { + static char irq_tab[5][5] = { /*INT INTA INTB INTC INTD */ { 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */ { 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */ diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c index a3f485257170..07830cccabf9 100644 --- a/arch/alpha/kernel/sys_ruffian.c +++ b/arch/alpha/kernel/sys_ruffian.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_ruffian.c * @@ -117,10 +118,10 @@ ruffian_kill_arch (int mode) * */ -static int __init +static int ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[11][5] __initdata = { + static char irq_tab[11][5] = { /*INT INTA INTB INTC INTD */ {-1, -1, -1, -1, -1}, /* IdSel 13, 21052 */ {-1, -1, -1, -1, -1}, /* IdSel 14, SIO */ @@ -139,7 +140,7 @@ ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return COMMON_TABLE_LOOKUP; } -static u8 __init +static u8 ruffian_swizzle(struct pci_dev *dev, u8 *pinp) { int slot, pin = *pinp; diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c index 08ee737d4fba..a3db719d3c38 100644 --- a/arch/alpha/kernel/sys_rx164.c +++ b/arch/alpha/kernel/sys_rx164.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_rx164.c * @@ -142,7 +143,7 @@ rx164_init_irq(void) * */ -static int __init +static int rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { #if 0 @@ -156,7 +157,7 @@ rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { 16+1, 16+1, 16+6, 16+11, 16+16}, /* IdSel 10, slot 4 */ }; #else - static char irq_tab[6][5] __initdata = { + static char irq_tab[6][5] = { /*INT INTA INTB INTC INTD */ { 16+0, 16+0, 16+6, 16+11, 16+16}, /* IdSel 5, slot 0 */ { 16+1, 16+1, 16+7, 16+12, 16+17}, /* IdSel 6, slot 1 */ diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c index 8a0aa6d67b53..3cf0d32da5d8 100644 --- a/arch/alpha/kernel/sys_sable.c +++ b/arch/alpha/kernel/sys_sable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_sable.c * @@ -192,10 +193,10 @@ sable_init_irq(void) * with the values in the irq swizzling tables above. */ -static int __init +static int sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[9][5] __initdata = { + static char irq_tab[9][5] = { /*INT INTA INTB INTC INTD */ { 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */ { 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */ @@ -374,10 +375,10 @@ lynx_init_irq(void) * with the values in the irq swizzling tables above. */ -static int __init +static int lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[19][5] __initdata = { + static char irq_tab[19][5] = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 13, PCEB */ { -1, -1, -1, -1, -1}, /* IdSel 14, PPB */ @@ -404,7 +405,7 @@ lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return COMMON_TABLE_LOOKUP; } -static u8 __init +static u8 lynx_swizzle(struct pci_dev *dev, u8 *pinp) { int slot, pin = *pinp; diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index febd24eba7a6..37bd6d9b8eb9 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_sio.c * @@ -144,7 +145,7 @@ sio_fixup_irq_levels(unsigned int level_bits) outb((level_bits >> 8) & 0xff, 0x4d1); } -static inline int __init +static inline int noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* @@ -165,7 +166,7 @@ noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) * that they use the default INTA line, if they are interrupt * driven at all). */ - static char irq_tab[][5] __initdata = { + static char irq_tab[][5] = { /*INT A B C D */ { 3, 3, 3, 3, 3}, /* idsel 6 (53c810) */ {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */ @@ -183,10 +184,10 @@ noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return irq >= 0 ? tmp : -1; } -static inline int __init +static inline int p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[][5] __initdata = { + static char irq_tab[][5] = { /*INT A B C D */ { 0, 0, -1, -1, -1}, /* idsel 6 (53c810) */ {-1, -1, -1, -1, -1}, /* idsel 7 (SIO: PCI/ISA bridge) */ diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c index d063b360efed..1ec638a2746a 100644 --- a/arch/alpha/kernel/sys_sx164.c +++ b/arch/alpha/kernel/sys_sx164.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_sx164.c * @@ -94,10 +95,10 @@ sx164_init_irq(void) * 9 32 bit PCI option slot 3 */ -static int __init +static int sx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[5][5] __initdata = { + static char irq_tab[5][5] = { /*INT INTA INTB INTC INTD */ { 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */ { 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */ diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index dd0f1eae3c68..e230c6864088 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_takara.c * @@ -155,10 +156,10 @@ takara_init_irq(void) * assign it whatever the hell IRQ we like and it doesn't matter. */ -static int __init +static int takara_map_irq_srm(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[15][5] __initdata = { + static char irq_tab[15][5] = { { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */ @@ -210,7 +211,7 @@ takara_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) return COMMON_TABLE_LOOKUP; } -static u8 __init +static u8 takara_swizzle(struct pci_dev *dev, u8 *pinp) { int slot = PCI_SLOT(dev->devfn); diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index a53cf03f49d5..c8390d8de140 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_titan.c * diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c index ee1874887776..8e64052811ab 100644 --- a/arch/alpha/kernel/sys_wildfire.c +++ b/arch/alpha/kernel/sys_wildfire.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/sys_wildfire.c * @@ -288,10 +289,10 @@ wildfire_device_interrupt(unsigned long vector) * 7 64 bit PCI 1 option slot 7 */ -static int __init +static int wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - static char irq_tab[8][5] __initdata = { + static char irq_tab[8][5] = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 0 ISA Bridge */ { 36, 36, 36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */ diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 5b4514abb234..1374e591511f 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/kernel/systbls.S * diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 3bfe058d75d9..0069360697ee 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/kernel/time.c * diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 65bb102d985b..4bd99a7b1c41 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/kernel/traps.c * @@ -193,8 +194,10 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15) static long dummy_emul(void) { return 0; } long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask) = (void *)dummy_emul; +EXPORT_SYMBOL_GPL(alpha_fp_emul_imprecise); long (*alpha_fp_emul) (unsigned long pc) = (void *)dummy_emul; +EXPORT_SYMBOL_GPL(alpha_fp_emul); #else long alpha_fp_emul_imprecise(struct pt_regs *regs, unsigned long writemask); long alpha_fp_emul (unsigned long pc); @@ -278,7 +281,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) case 1: /* bugcheck */ info.si_signo = SIGTRAP; info.si_errno = 0; - info.si_code = __SI_FAULT; + info.si_code = TRAP_FIXME; info.si_addr = (void __user *) regs->pc; info.si_trapno = 0; send_sig_info(SIGTRAP, &info, current); @@ -318,7 +321,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) break; case GEN_ROPRAND: signo = SIGFPE; - code = __SI_FAULT; + code = FPE_FIXME; break; case GEN_DECOVF: @@ -340,7 +343,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) case GEN_SUBRNG7: default: signo = SIGTRAP; - code = __SI_FAULT; + code = TRAP_FIXME; break; } diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index cebecfb76fbf..c4b5ceceab52 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index a80815960364..04f9729de57c 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for alpha-specific library files.. # diff --git a/arch/alpha/lib/callback_srm.S b/arch/alpha/lib/callback_srm.S index 6093addc931a..b13c4a231f1b 100644 --- a/arch/alpha/lib/callback_srm.S +++ b/arch/alpha/lib/callback_srm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/callback_srm.S */ diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c index b57f8007db14..3f35c3ed6948 100644 --- a/arch/alpha/lib/checksum.c +++ b/arch/alpha/lib/checksum.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/lib/checksum.c * diff --git a/arch/alpha/lib/clear_page.S b/arch/alpha/lib/clear_page.S index 263d7393c0e7..ce02de7b0493 100644 --- a/arch/alpha/lib/clear_page.S +++ b/arch/alpha/lib/clear_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/clear_page.S * diff --git a/arch/alpha/lib/clear_user.S b/arch/alpha/lib/clear_user.S index 006f469fef73..db6c6ca45896 100644 --- a/arch/alpha/lib/clear_user.S +++ b/arch/alpha/lib/clear_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/clear_user.S * Contributed by Richard Henderson diff --git a/arch/alpha/lib/copy_page.S b/arch/alpha/lib/copy_page.S index 2ee0bd0508c5..5439a30c77d0 100644 --- a/arch/alpha/lib/copy_page.S +++ b/arch/alpha/lib/copy_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/copy_page.S * diff --git a/arch/alpha/lib/copy_user.S b/arch/alpha/lib/copy_user.S index c277a1a4383e..32ab0344b185 100644 --- a/arch/alpha/lib/copy_user.S +++ b/arch/alpha/lib/copy_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/copy_user.S * diff --git a/arch/alpha/lib/csum_ipv6_magic.S b/arch/alpha/lib/csum_ipv6_magic.S index e74b4544b0cc..c7b213ab01ab 100644 --- a/arch/alpha/lib/csum_ipv6_magic.S +++ b/arch/alpha/lib/csum_ipv6_magic.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/csum_ipv6_magic.S * Contributed by Richard Henderson diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c index ab42afba1720..ddb9c2f376fa 100644 --- a/arch/alpha/lib/csum_partial_copy.c +++ b/arch/alpha/lib/csum_partial_copy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * csum_partial_copy - do IP checksumming and copy * diff --git a/arch/alpha/lib/dbg_current.S b/arch/alpha/lib/dbg_current.S index e6d071015f9b..be6612131277 100644 --- a/arch/alpha/lib/dbg_current.S +++ b/arch/alpha/lib/dbg_current.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/dbg_current.S * Contributed by Richard Henderson (rth@cygnus.com) diff --git a/arch/alpha/lib/dbg_stackcheck.S b/arch/alpha/lib/dbg_stackcheck.S index 78f6b924ad8f..b3b6fc94f7f3 100644 --- a/arch/alpha/lib/dbg_stackcheck.S +++ b/arch/alpha/lib/dbg_stackcheck.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/dbg_stackcheck.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/dbg_stackkill.S b/arch/alpha/lib/dbg_stackkill.S index c1e40a1a43d5..6d9197e52a42 100644 --- a/arch/alpha/lib/dbg_stackkill.S +++ b/arch/alpha/lib/dbg_stackkill.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/dbg_stackkill.S * Contributed by Richard Henderson (rth@cygnus.com) diff --git a/arch/alpha/lib/dec_and_lock.c b/arch/alpha/lib/dec_and_lock.c index 4221b40167ee..a117707f57fe 100644 --- a/arch/alpha/lib/dec_and_lock.c +++ b/arch/alpha/lib/dec_and_lock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/lib/dec_and_lock.c * diff --git a/arch/alpha/lib/divide.S b/arch/alpha/lib/divide.S index 1e33bd127621..2b60eb45e50b 100644 --- a/arch/alpha/lib/divide.S +++ b/arch/alpha/lib/divide.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/divide.S * diff --git a/arch/alpha/lib/ev6-clear_page.S b/arch/alpha/lib/ev6-clear_page.S index abe99e69a194..325864c81586 100644 --- a/arch/alpha/lib/ev6-clear_page.S +++ b/arch/alpha/lib/ev6-clear_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-clear_page.S * diff --git a/arch/alpha/lib/ev6-clear_user.S b/arch/alpha/lib/ev6-clear_user.S index e179e4757ef8..7e644f83cdf2 100644 --- a/arch/alpha/lib/ev6-clear_user.S +++ b/arch/alpha/lib/ev6-clear_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-clear_user.S * 21264 version contributed by Rick Gorton diff --git a/arch/alpha/lib/ev6-copy_page.S b/arch/alpha/lib/ev6-copy_page.S index 77935061bddb..fd7212c8dcf1 100644 --- a/arch/alpha/lib/ev6-copy_page.S +++ b/arch/alpha/lib/ev6-copy_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-copy_page.S * diff --git a/arch/alpha/lib/ev6-copy_user.S b/arch/alpha/lib/ev6-copy_user.S index 954ca03ebebe..f3e433754397 100644 --- a/arch/alpha/lib/ev6-copy_user.S +++ b/arch/alpha/lib/ev6-copy_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-copy_user.S * diff --git a/arch/alpha/lib/ev6-csum_ipv6_magic.S b/arch/alpha/lib/ev6-csum_ipv6_magic.S index de62627ac4fe..9a73f90700a1 100644 --- a/arch/alpha/lib/ev6-csum_ipv6_magic.S +++ b/arch/alpha/lib/ev6-csum_ipv6_magic.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-csum_ipv6_magic.S * 21264 version contributed by Rick Gorton diff --git a/arch/alpha/lib/ev6-divide.S b/arch/alpha/lib/ev6-divide.S index d18dc0e96e3d..137ff1a07356 100644 --- a/arch/alpha/lib/ev6-divide.S +++ b/arch/alpha/lib/ev6-divide.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-divide.S * diff --git a/arch/alpha/lib/ev6-memchr.S b/arch/alpha/lib/ev6-memchr.S index 419adc53ccb4..56bf9e14eeee 100644 --- a/arch/alpha/lib/ev6-memchr.S +++ b/arch/alpha/lib/ev6-memchr.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-memchr.S * diff --git a/arch/alpha/lib/ev6-memcpy.S b/arch/alpha/lib/ev6-memcpy.S index b19798b2efc0..ffbd056b6eb2 100644 --- a/arch/alpha/lib/ev6-memcpy.S +++ b/arch/alpha/lib/ev6-memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-memcpy.S * 21264 version by Rick Gorton diff --git a/arch/alpha/lib/ev6-memset.S b/arch/alpha/lib/ev6-memset.S index fed21c6893e8..316a99aa9efe 100644 --- a/arch/alpha/lib/ev6-memset.S +++ b/arch/alpha/lib/ev6-memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-memset.S * diff --git a/arch/alpha/lib/ev6-stxcpy.S b/arch/alpha/lib/ev6-stxcpy.S index 4643ff2ffc8d..65f5f7310d80 100644 --- a/arch/alpha/lib/ev6-stxcpy.S +++ b/arch/alpha/lib/ev6-stxcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-stxcpy.S * 21264 version contributed by Rick Gorton diff --git a/arch/alpha/lib/ev6-stxncpy.S b/arch/alpha/lib/ev6-stxncpy.S index 1aa6e97e04b5..76da205282ee 100644 --- a/arch/alpha/lib/ev6-stxncpy.S +++ b/arch/alpha/lib/ev6-stxncpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev6-stxncpy.S * 21264 version contributed by Rick Gorton diff --git a/arch/alpha/lib/ev67-strcat.S b/arch/alpha/lib/ev67-strcat.S index b69f60419be1..ec3096a9e8d4 100644 --- a/arch/alpha/lib/ev67-strcat.S +++ b/arch/alpha/lib/ev67-strcat.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev67-strcat.S * 21264 version contributed by Rick Gorton diff --git a/arch/alpha/lib/ev67-strchr.S b/arch/alpha/lib/ev67-strchr.S index ea8f2f35db9c..fbf89e0b6dc3 100644 --- a/arch/alpha/lib/ev67-strchr.S +++ b/arch/alpha/lib/ev67-strchr.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev67-strchr.S * 21264 version contributed by Rick Gorton diff --git a/arch/alpha/lib/ev67-strlen.S b/arch/alpha/lib/ev67-strlen.S index 736fd41884a8..b73106ffbbc7 100644 --- a/arch/alpha/lib/ev67-strlen.S +++ b/arch/alpha/lib/ev67-strlen.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev67-strlen.S * 21264 version by Rick Gorton diff --git a/arch/alpha/lib/ev67-strncat.S b/arch/alpha/lib/ev67-strncat.S index cd35cbade73a..ceb0ca528789 100644 --- a/arch/alpha/lib/ev67-strncat.S +++ b/arch/alpha/lib/ev67-strncat.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev67-strncat.S * 21264 version contributed by Rick Gorton diff --git a/arch/alpha/lib/ev67-strrchr.S b/arch/alpha/lib/ev67-strrchr.S index 747455f0328c..7f80e398530f 100644 --- a/arch/alpha/lib/ev67-strrchr.S +++ b/arch/alpha/lib/ev67-strrchr.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/ev67-strrchr.S * 21264 version by Rick Gorton diff --git a/arch/alpha/lib/fls.c b/arch/alpha/lib/fls.c index ddd048c0d825..02e156776645 100644 --- a/arch/alpha/lib/fls.c +++ b/arch/alpha/lib/fls.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/lib/fls.c */ diff --git a/arch/alpha/lib/fpreg.c b/arch/alpha/lib/fpreg.c index 4aa6dbfa14ee..34fea465645b 100644 --- a/arch/alpha/lib/fpreg.c +++ b/arch/alpha/lib/fpreg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/lib/fpreg.c * diff --git a/arch/alpha/lib/memcpy.c b/arch/alpha/lib/memcpy.c index 57d9291ad172..cbac3dc6d963 100644 --- a/arch/alpha/lib/memcpy.c +++ b/arch/alpha/lib/memcpy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/lib/memcpy.c * diff --git a/arch/alpha/lib/memmove.S b/arch/alpha/lib/memmove.S index 6872c85cb5e5..42d1922d0edf 100644 --- a/arch/alpha/lib/memmove.S +++ b/arch/alpha/lib/memmove.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/memmove.S * diff --git a/arch/alpha/lib/memset.S b/arch/alpha/lib/memset.S index 89a26f5e89de..00393e30df25 100644 --- a/arch/alpha/lib/memset.S +++ b/arch/alpha/lib/memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/alpha/lib/memset.S * @@ -20,7 +21,7 @@ .globl memset .globl __memset .globl ___memset - .globl __memsetw + .globl __memset16 .globl __constant_c_memset .ent ___memset @@ -110,8 +111,8 @@ EXPORT_SYMBOL(___memset) EXPORT_SYMBOL(__constant_c_memset) .align 5 - .ent __memsetw -__memsetw: + .ent __memset16 +__memset16: .prologue 0 inswl $17,0,$1 /* E0 */ @@ -123,8 +124,8 @@ __memsetw: or $1,$4,$17 /* E0 */ br __constant_c_memset /* .. E1 */ - .end __memsetw -EXPORT_SYMBOL(__memsetw) + .end __memset16 +EXPORT_SYMBOL(__memset16) memset = ___memset __memset = ___memset diff --git a/arch/alpha/lib/srm_printk.c b/arch/alpha/lib/srm_printk.c index 31b53c49435e..6276eed76276 100644 --- a/arch/alpha/lib/srm_printk.c +++ b/arch/alpha/lib/srm_printk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/lib/srm_printk.c */ diff --git a/arch/alpha/lib/srm_puts.c b/arch/alpha/lib/srm_puts.c index 7b60a6f75a78..df7991f6fc69 100644 --- a/arch/alpha/lib/srm_puts.c +++ b/arch/alpha/lib/srm_puts.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/alpha/lib/srm_puts.c */ diff --git a/arch/alpha/lib/stacktrace.c b/arch/alpha/lib/stacktrace.c index 5e832161e6d2..62454a7810e2 100644 --- a/arch/alpha/lib/stacktrace.c +++ b/arch/alpha/lib/stacktrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include typedef unsigned int instr; diff --git a/arch/alpha/lib/strcat.S b/arch/alpha/lib/strcat.S index 249837b03d4b..055877dccd27 100644 --- a/arch/alpha/lib/strcat.S +++ b/arch/alpha/lib/strcat.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/strcat.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/strchr.S b/arch/alpha/lib/strchr.S index 7412a173ea39..17871dd00280 100644 --- a/arch/alpha/lib/strchr.S +++ b/arch/alpha/lib/strchr.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/strchr.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/strcpy.S b/arch/alpha/lib/strcpy.S index 98deae1e4d08..cb74ad23a90d 100644 --- a/arch/alpha/lib/strcpy.S +++ b/arch/alpha/lib/strcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/strcpy.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/strlen.S b/arch/alpha/lib/strlen.S index 79c416f71bac..dd882fe4d7e3 100644 --- a/arch/alpha/lib/strlen.S +++ b/arch/alpha/lib/strlen.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * strlen.S (c) 1995 David Mosberger (davidm@cs.arizona.edu) * diff --git a/arch/alpha/lib/strncat.S b/arch/alpha/lib/strncat.S index 6c29ea60869a..522fee3e26ac 100644 --- a/arch/alpha/lib/strncat.S +++ b/arch/alpha/lib/strncat.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/strncat.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/strncpy.S b/arch/alpha/lib/strncpy.S index e102cf1567dd..cc57fad8b7ca 100644 --- a/arch/alpha/lib/strncpy.S +++ b/arch/alpha/lib/strncpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/strncpy.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/strrchr.S b/arch/alpha/lib/strrchr.S index 4bc6cb4b9812..7650ba99b7e2 100644 --- a/arch/alpha/lib/strrchr.S +++ b/arch/alpha/lib/strrchr.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/strrchr.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/stxcpy.S b/arch/alpha/lib/stxcpy.S index 2a8d51bfc05d..58723b0a36d4 100644 --- a/arch/alpha/lib/stxcpy.S +++ b/arch/alpha/lib/stxcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/stxcpy.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/stxncpy.S b/arch/alpha/lib/stxncpy.S index 3dece25283a3..011d9091c6e1 100644 --- a/arch/alpha/lib/stxncpy.S +++ b/arch/alpha/lib/stxncpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/alpha/lib/stxncpy.S * Contributed by Richard Henderson (rth@tamu.edu) diff --git a/arch/alpha/lib/udelay.c b/arch/alpha/lib/udelay.c index f2d81ff38aa6..873648263430 100644 --- a/arch/alpha/lib/udelay.c +++ b/arch/alpha/lib/udelay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1993, 2000 Linus Torvalds * diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c index d17d705f6545..1c2d456da7f2 100644 --- a/arch/alpha/math-emu/math.c +++ b/arch/alpha/math-emu/math.c @@ -53,6 +53,7 @@ extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val); #ifdef MODULE MODULE_DESCRIPTION("FP Software completion module"); +MODULE_LICENSE("GPL v2"); extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long); extern long (*alpha_fp_emul) (unsigned long pc); diff --git a/arch/alpha/math-emu/sfp-util.h b/arch/alpha/math-emu/sfp-util.h index f53707f77455..ae30f3417522 100644 --- a/arch/alpha/math-emu/sfp-util.h +++ b/arch/alpha/math-emu/sfp-util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index c25e8827e7cd..cd3c572ee912 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/mm/fault.c * diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 0542e973c73d..9d74520298ab 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/mm/init.c * diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index d543d71c28b4..a9e86475f169 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/alpha/mm/numa.c * diff --git a/arch/alpha/oprofile/Makefile b/arch/alpha/oprofile/Makefile index 3473de751b03..79f32820a42f 100644 --- a/arch/alpha/oprofile/Makefile +++ b/arch/alpha/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-y := -Werror -Wno-sign-compare obj-$(CONFIG_OPROFILE) += oprofile.o diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 7db85ab00c52..c84e67fdea09 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -24,7 +24,7 @@ config ARC select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK - select HAVE_FUTEX_CMPXCHG + select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_IOREMAP_PROT select HAVE_KPROBES select HAVE_KRETPROBES @@ -100,6 +100,7 @@ source "arch/arc/plat-tb10x/Kconfig" source "arch/arc/plat-axs10x/Kconfig" #New platform adds here source "arch/arc/plat-eznps/Kconfig" +source "arch/arc/plat-hsdk/Kconfig" endmenu @@ -418,7 +419,7 @@ endif # ISA_ARCV2 endmenu # "ARC CPU Configuration" config LINUX_LINK_BASE - hex "Linux Link Address" + hex "Kernel link address" default "0x80000000" help ARC700 divides the 32 bit phy address space into two equal halves @@ -431,6 +432,14 @@ config LINUX_LINK_BASE If you don't know what the above means, leave this setting alone. This needs to match memory start address specified in Device Tree +config LINUX_RAM_BASE + hex "RAM base address" + default LINUX_LINK_BASE + help + By default Linux is linked at base of RAM. However in some special + cases (such as HSDK), Linux can't be linked at start of DDR, hence + this option. + config HIGHMEM bool "High Memory Support" select ARCH_DISCONTIGMEM_ENABLE diff --git a/arch/arc/Kconfig.debug b/arch/arc/Kconfig.debug index ff6a4b5ce927..03da1a6b3072 100644 --- a/arch/arc/Kconfig.debug +++ b/arch/arc/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 3a61cfcc38c0..d37f49d6a27f 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -6,8 +6,6 @@ # published by the Free Software Foundation. # -UTS_MACHINE := arc - ifeq ($(CROSS_COMPILE),) ifndef CONFIG_CPU_BIG_ENDIAN CROSS_COMPILE := arc-linux- @@ -111,6 +109,7 @@ core-y += arch/arc/plat-sim/ core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/ core-$(CONFIG_ARC_PLAT_EZNPS) += arch/arc/plat-eznps/ +core-$(CONFIG_ARC_SOC_HSDK) += arch/arc/plat-hsdk/ ifdef CONFIG_ARC_PLAT_EZNPS KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-eznps/include diff --git a/arch/arc/boot/Makefile b/arch/arc/boot/Makefile index f94cf151e06a..538b92f4dd25 100644 --- a/arch/arc/boot/Makefile +++ b/arch/arc/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 targets := vmlinux.bin vmlinux.bin.gz uImage # uImage build relies on mkimage being availble on your host for ARC target diff --git a/arch/arc/boot/dts/Makefile b/arch/arc/boot/dts/Makefile index a09f11b71e66..83c9e076ef63 100644 --- a/arch/arc/boot/dts/Makefile +++ b/arch/arc/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Built-in dtb builtindtb-y := nsim_700 diff --git a/arch/arc/boot/dts/axc001.dtsi b/arch/arc/boot/dts/axc001.dtsi index a380ffa1a458..fdc266504ada 100644 --- a/arch/arc/boot/dts/axc001.dtsi +++ b/arch/arc/boot/dts/axc001.dtsi @@ -99,7 +99,7 @@ memory { device_type = "memory"; - /* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ reg = <0x0 0x80000000 0x0 0x1b000000>; /* (512 - 32) MiB */ }; diff --git a/arch/arc/boot/dts/axc003.dtsi b/arch/arc/boot/dts/axc003.dtsi index cc9239ef8d08..4e6e9f57e790 100644 --- a/arch/arc/boot/dts/axc003.dtsi +++ b/arch/arc/boot/dts/axc003.dtsi @@ -24,10 +24,17 @@ ranges = <0x00000000 0x0 0xf0000000 0x10000000>; - core_clk: core_clk { + input_clk: input-clk { #clock-cells = <0>; compatible = "fixed-clock"; - clock-frequency = <90000000>; + clock-frequency = <33333333>; + }; + + core_clk: core-clk@80 { + compatible = "snps,axs10x-arc-pll-clock"; + reg = <0x80 0x10>, <0x100 0x10>; + #clock-cells = <0>; + clocks = <&input_clk>; }; core_intc: archs-intc@cpu { @@ -102,7 +109,7 @@ memory { device_type = "memory"; - /* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MiB low mem */ 0x1 0xc0000000 0x0 0x40000000>; /* 1 GiB highmem */ }; diff --git a/arch/arc/boot/dts/axc003_idu.dtsi b/arch/arc/boot/dts/axc003_idu.dtsi index 4ebb2170abec..63954a8b0100 100644 --- a/arch/arc/boot/dts/axc003_idu.dtsi +++ b/arch/arc/boot/dts/axc003_idu.dtsi @@ -24,10 +24,17 @@ ranges = <0x00000000 0x0 0xf0000000 0x10000000>; - core_clk: core_clk { + input_clk: input-clk { #clock-cells = <0>; compatible = "fixed-clock"; - clock-frequency = <100000000>; + clock-frequency = <33333333>; + }; + + core_clk: core-clk@80 { + compatible = "snps,axs10x-arc-pll-clock"; + reg = <0x80 0x10>, <0x100 0x10>; + #clock-cells = <0>; + clocks = <&input_clk>; }; core_intc: archs-intc@cpu { @@ -108,7 +115,7 @@ memory { device_type = "memory"; - /* CONFIG_KERNEL_RAM_BASE_ADDRESS needs to match low mem start */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MiB low mem */ 0x1 0xc0000000 0x0 0x40000000>; /* 1 GiB highmem */ }; diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index 0ff7e07edcd4..e114000a84f5 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -44,7 +44,14 @@ mmcclk: mmcclk { compatible = "fixed-clock"; - clock-frequency = <50000000>; + /* + * DW sdio controller has external ciu clock divider + * controlled via register in SDIO IP. It divides + * sdio_ref_clk (which comes from CGU) by 16 for + * default. So default mmcclk clock (which comes + * to sdk_in) is 25000000 Hz. + */ + clock-frequency = <25000000>; #clock-cells = <0>; }; @@ -101,7 +108,6 @@ mmc@0x15000 { compatible = "altr,socfpga-dw-mshc"; reg = < 0x15000 0x400 >; - num-slots = < 1 >; fifo-depth = < 16 >; card-detect-delay = < 200 >; clocks = <&apbclk>, <&mmcclk>; diff --git a/arch/arc/boot/dts/hsdk.dts b/arch/arc/boot/dts/hsdk.dts new file mode 100644 index 000000000000..8f627c200d60 --- /dev/null +++ b/arch/arc/boot/dts/hsdk.dts @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * Device Tree for ARC HS Development Kit + */ +/dts-v1/; + +#include +#include + +/ { + model = "snps,hsdk"; + compatible = "snps,hsdk"; + + #address-cells = <1>; + #size-cells = <1>; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0xf0005000,115200n8 console=ttyS0,115200n8 debug print-fatal-signals=1"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <0>; + clocks = <&core_clk>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <1>; + clocks = <&core_clk>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <2>; + clocks = <&core_clk>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "snps,archs38"; + reg = <3>; + clocks = <&core_clk>; + }; + }; + + input_clk: input-clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <33333333>; + }; + + cpu_intc: cpu-interrupt-controller { + compatible = "snps,archs-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + + idu_intc: idu-interrupt-controller { + compatible = "snps,archs-idu-intc"; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&cpu_intc>; + }; + + arcpct: pct { + compatible = "snps,archs-pct"; + }; + + /* TIMER0 with interrupt for clockevent */ + timer { + compatible = "snps,arc-timer"; + interrupts = <16>; + interrupt-parent = <&cpu_intc>; + clocks = <&core_clk>; + }; + + /* 64-bit Global Free Running Counter */ + gfrc { + compatible = "snps,archs-timer-gfrc"; + clocks = <&core_clk>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&idu_intc>; + + ranges = <0x00000000 0xf0000000 0x10000000>; + + cgu_rst: reset-controller@8a0 { + compatible = "snps,hsdk-reset"; + #reset-cells = <1>; + reg = <0x8A0 0x4>, <0xFF0 0x4>; + }; + + core_clk: core-clk@0 { + compatible = "snps,hsdk-core-pll-clock"; + reg = <0x00 0x10>, <0x14B8 0x4>; + #clock-cells = <0>; + clocks = <&input_clk>; + }; + + serial: serial@5000 { + compatible = "snps,dw-apb-uart"; + reg = <0x5000 0x100>; + clock-frequency = <33330000>; + interrupts = <6>; + baud = <115200>; + reg-shift = <2>; + reg-io-width = <4>; + }; + + gmacclk: gmacclk { + compatible = "fixed-clock"; + clock-frequency = <400000000>; + #clock-cells = <0>; + }; + + mmcclk_ciu: mmcclk-ciu { + compatible = "fixed-clock"; + /* + * DW sdio controller has external ciu clock divider + * controlled via register in SDIO IP. Due to its + * unexpected default value (it should divide by 1 + * but it divides by 8) SDIO IP uses wrong clock and + * works unstable (see STAR 9001204800) + * We switched to the minimum possible value of the + * divisor (div-by-2) in HSDK platform code. + * So add temporary fix and change clock frequency + * to 50000000 Hz until we fix dw sdio driver itself. + */ + clock-frequency = <50000000>; + #clock-cells = <0>; + }; + + mmcclk_biu: mmcclk-biu { + compatible = "fixed-clock"; + clock-frequency = <400000000>; + #clock-cells = <0>; + }; + + ethernet@8000 { + #interrupt-cells = <1>; + compatible = "snps,dwmac"; + reg = <0x8000 0x2000>; + interrupts = <10>; + interrupt-names = "macirq"; + phy-mode = "rgmii"; + snps,pbl = <32>; + clocks = <&gmacclk>; + clock-names = "stmmaceth"; + phy-handle = <&phy0>; + resets = <&cgu_rst HSDK_ETH_RESET>; + reset-names = "stmmaceth"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy0: ethernet-phy@0 { + reg = <0>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + }; + }; + }; + + ohci@60000 { + compatible = "snps,hsdk-v1.0-ohci", "generic-ohci"; + reg = <0x60000 0x100>; + interrupts = <15>; + }; + + ehci@40000 { + compatible = "snps,hsdk-v1.0-ehci", "generic-ehci"; + reg = <0x40000 0x100>; + interrupts = <15>; + }; + + mmc@a000 { + compatible = "altr,socfpga-dw-mshc"; + reg = <0xa000 0x400>; + num-slots = <1>; + fifo-depth = <16>; + card-detect-delay = <200>; + clocks = <&mmcclk_biu>, <&mmcclk_ciu>; + clock-names = "biu", "ciu"; + interrupts = <12>; + bus-width = <4>; + }; + }; + + memory@80000000 { + #address-cells = <1>; + #size-cells = <1>; + device_type = "memory"; + reg = <0x80000000 0x40000000>; /* 1 GiB */ + }; +}; diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts index 3772c40c245e..8d787b251f73 100644 --- a/arch/arc/boot/dts/nsim_hs.dts +++ b/arch/arc/boot/dts/nsim_hs.dts @@ -18,7 +18,7 @@ memory { device_type = "memory"; - /* CONFIG_LINUX_LINK_BASE needs to match low mem start */ + /* CONFIG_LINUX_RAM_BASE needs to match low mem start */ reg = <0x0 0x80000000 0x0 0x20000000 /* 512 MB low mem */ 0x1 0x00000000 0x0 0x40000000>; /* 1 GB highmem */ }; diff --git a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi index 459fc656b759..48bb4b4cd234 100644 --- a/arch/arc/boot/dts/vdk_axs10x_mb.dtsi +++ b/arch/arc/boot/dts/vdk_axs10x_mb.dtsi @@ -104,7 +104,6 @@ mmc@0x15000 { compatible = "snps,dw-mshc"; reg = <0x15000 0x400>; - num-slots = <1>; fifo-depth = <1024>; card-detect-delay = <200>; clocks = <&apbclk>, <&mmcclk>; diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig index 6980b966a364..ec7c849a5c8e 100644 --- a/arch/arc/configs/axs101_defconfig +++ b/arch/arc/configs/axs101_defconfig @@ -105,7 +105,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index 2233f5777a71..63d3cf69e0b0 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -104,7 +104,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index 30a3d4cf53d2..f613ecac14a7 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -107,7 +107,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/haps_hs_smp_defconfig b/arch/arc/configs/haps_hs_smp_defconfig index 821a2e562f3f..3507be2af6fe 100644 --- a/arch/arc/configs/haps_hs_smp_defconfig +++ b/arch/arc/configs/haps_hs_smp_defconfig @@ -84,5 +84,5 @@ CONFIG_TMPFS=y CONFIG_NFS_FS=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/hsdk_defconfig b/arch/arc/configs/hsdk_defconfig new file mode 100644 index 000000000000..7b8f8faf8a24 --- /dev/null +++ b/arch/arc/configs/hsdk_defconfig @@ -0,0 +1,80 @@ +CONFIG_DEFAULT_HOSTNAME="ARCLinux" +CONFIG_SYSVIPC=y +# CONFIG_CROSS_MEMORY_ATTACH is not set +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_PID_NS is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="../../arc_initramfs_hs/" +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_ARC_SOC_HSDK=y +CONFIG_ISA_ARCV2=y +CONFIG_SMP=y +CONFIG_LINUX_LINK_BASE=0x90000000 +CONFIG_LINUX_RAM_BASE=0x80000000 +CONFIG_ARC_BUILTIN_DTB_NAME="hsdk" +CONFIG_PREEMPT=y +# CONFIG_COMPACTION is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_DEVTMPFS=y +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +CONFIG_MICREL_PHY=y +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +CONFIG_FB=y +CONFIG_FB_UDL=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_DW=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT3_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_NFS_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_STRIP_ASM_SYMS=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_FTRACE is not set +CONFIG_CRYPTO_ECHAINIV=y diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig index c0d6a010751a..4fcf4f2503f6 100644 --- a/arch/arc/configs/vdk_hs38_defconfig +++ b/arch/arc/configs/vdk_hs38_defconfig @@ -94,7 +94,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_SHIRQ=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index 5c0971787acf..7b71464f6c2f 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -98,7 +98,7 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_SHIRQ=y -CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=10 # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_PREEMPT is not set diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index 353dae386b2f..cd8398daccee 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 generic-y += bugs.h generic-y += clkdev.h generic-y += device.h diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index ba8e802dba80..b1c56d35f2a9 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -98,6 +98,7 @@ /* Auxiliary registers */ #define AUX_IDENTITY 4 +#define AUX_EXEC_CTRL 8 #define AUX_INTR_VEC_BASE 0x25 #define AUX_VOL 0x5e @@ -135,12 +136,12 @@ struct bcr_identity { #endif }; -struct bcr_isa { +struct bcr_isa_arcv2 { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int div_rem:4, pad2:4, ldd:1, unalign:1, atomic:1, be:1, - pad1:11, atomic1:1, ver:8; + pad1:12, ver:8; #else - unsigned int ver:8, atomic1:1, pad1:11, be:1, atomic:1, unalign:1, + unsigned int ver:8, pad1:12, be:1, atomic:1, unalign:1, ldd:1, pad2:4, div_rem:4; #endif }; @@ -263,13 +264,13 @@ struct cpuinfo_arc { struct cpuinfo_arc_mmu mmu; struct cpuinfo_arc_bpu bpu; struct bcr_identity core; - struct bcr_isa isa; + struct bcr_isa_arcv2 isa; const char *details, *name; unsigned int vec_base; struct cpuinfo_arc_ccm iccm, dccm; struct { unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2, - fpu_sp:1, fpu_dp:1, pad2:6, + fpu_sp:1, fpu_dp:1, dual_iss_enb:1, dual_iss_exist:1, pad2:4, debug:1, ap:1, smart:1, rtt:1, pad3:4, timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4; } extn; diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index 54b54da6384c..11859287c52a 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -123,6 +123,8 @@ static inline void atomic_set(atomic_t *v, int i) atomic_ops_unlock(flags); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + #endif /* diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 02fd1cece6ef..8486f328cc5d 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -47,7 +47,8 @@ : "r"(data), "r"(ptr)); \ }) -#define ARCH_DMA_MINALIGN L1_CACHE_BYTES +/* Largest line length for either L1 or L2 is 128 bytes */ +#define ARCH_DMA_MINALIGN 128 extern void arc_cache_init(void); extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); @@ -95,6 +96,8 @@ extern unsigned long perip_base, perip_end; #define ARC_REG_SLC_CTRL 0x903 #define ARC_REG_SLC_FLUSH 0x904 #define ARC_REG_SLC_INVALIDATE 0x905 +#define ARC_AUX_SLC_IVDL 0x910 +#define ARC_AUX_SLC_FLDL 0x912 #define ARC_REG_SLC_RGN_START 0x914 #define ARC_REG_SLC_RGN_START1 0x915 #define ARC_REG_SLC_RGN_END 0x916 diff --git a/arch/arc/include/asm/entry-arcv2.h b/arch/arc/include/asm/entry-arcv2.h index ac85380d14a4..257a68f3c2fe 100644 --- a/arch/arc/include/asm/entry-arcv2.h +++ b/arch/arc/include/asm/entry-arcv2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARC_ENTRY_ARCV2_H #define __ASM_ARC_ENTRY_ARCV2_H diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index 14c310f2e0b1..ec36d5b6d435 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -192,6 +192,12 @@ PUSHAX lp_start PUSHAX erbta +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + PUSHAX CTOP_AUX_GPA1 + PUSHAX CTOP_AUX_EFLAGS +#endif + lr r9, [ecr] st r9, [sp, PT_event] /* EV_Trap expects r9 to have ECR */ .endm @@ -208,6 +214,12 @@ * by hardware and that is not good. *-------------------------------------------------------------*/ .macro EXCEPTION_EPILOGUE +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + POPAX CTOP_AUX_EFLAGS + POPAX CTOP_AUX_GPA1 +#endif + POPAX erbta POPAX lp_start POPAX lp_end @@ -265,6 +277,12 @@ PUSHAX lp_end PUSHAX lp_start PUSHAX bta_l\LVL\() + +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + PUSHAX CTOP_AUX_GPA1 + PUSHAX CTOP_AUX_EFLAGS +#endif .endm /*-------------------------------------------------------------- @@ -277,6 +295,12 @@ * by hardware and that is not good. *-------------------------------------------------------------*/ .macro INTERRUPT_EPILOGUE LVL +#ifdef CONFIG_ARC_PLAT_EZNPS + .word CTOP_INST_SCHD_RW + POPAX CTOP_AUX_EFLAGS + POPAX CTOP_AUX_GPA1 +#endif + POPAX bta_l\LVL\() POPAX lp_start POPAX lp_end diff --git a/arch/arc/include/asm/fb.h b/arch/arc/include/asm/fb.h index bd3f68c9ddfc..dc2e303cdbbb 100644 --- a/arch/arc/include/asm/fb.h +++ b/arch/arc/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ diff --git a/arch/arc/include/asm/futex.h b/arch/arc/include/asm/futex.h index 11e1b1f3acda..eb887dd13e74 100644 --- a/arch/arc/include/asm/futex.h +++ b/arch/arc/include/asm/futex.h @@ -73,20 +73,11 @@ #endif -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - #ifndef CONFIG_ARC_HAS_LLSC preempt_disable(); /* to guarantee atomic r-m-w of futex op */ #endif @@ -118,30 +109,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) preempt_enable(); #endif - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h index a64c447b0337..8a4f77ea3238 100644 --- a/arch/arc/include/asm/irqflags-arcv2.h +++ b/arch/arc/include/asm/irqflags-arcv2.h @@ -47,9 +47,6 @@ #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ (ARCV2_IRQ_DEF_PRIO << 1)) -/* SLEEP needs default irq priority (<=) which can interrupt the doze */ -#define ISA_SLEEP_ARG (0x10 | ARCV2_IRQ_DEF_PRIO) - #ifndef __ASSEMBLY__ /* diff --git a/arch/arc/include/asm/irqflags-compact.h b/arch/arc/include/asm/irqflags-compact.h index 4c6eed80cd8b..fcb80171fc34 100644 --- a/arch/arc/include/asm/irqflags-compact.h +++ b/arch/arc/include/asm/irqflags-compact.h @@ -43,8 +43,6 @@ #define ISA_INIT_STATUS_BITS STATUS_IE_MASK -#define ISA_SLEEP_ARG 0x3 - #ifndef __ASSEMBLY__ /****************************************************************** diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 296c3426a6ad..109baa06831c 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -85,7 +85,7 @@ typedef pte_t * pgtable_t; */ #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE) +#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_RAM_BASE) #ifdef CONFIG_FLATMEM #define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index 4104a0839214..8ee41e988169 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h @@ -27,6 +27,13 @@ struct arc_fpu { }; #endif +#ifdef CONFIG_ARC_PLAT_EZNPS +struct eznps_dp { + unsigned int eflags; + unsigned int gpa1; +}; +#endif + /* Arch specific stuff which needs to be saved per task. * However these items are not so important so as to earn a place in * struct thread_info @@ -38,6 +45,9 @@ struct thread_struct { #ifdef CONFIG_ARC_FPU_SAVE_RESTORE struct arc_fpu fpu; #endif +#ifdef CONFIG_ARC_PLAT_EZNPS + struct eznps_dp dp; +#endif }; #define INIT_THREAD { \ @@ -68,9 +78,6 @@ struct task_struct; #endif -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - #define KSTK_EIP(tsk) (task_pt_regs(tsk)->ret) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) diff --git a/arch/arc/include/asm/ptrace.h b/arch/arc/include/asm/ptrace.h index 5297faa8a378..5a8cb22724a1 100644 --- a/arch/arc/include/asm/ptrace.h +++ b/arch/arc/include/asm/ptrace.h @@ -19,6 +19,11 @@ #ifdef CONFIG_ISA_ARCOMPACT struct pt_regs { +#ifdef CONFIG_ARC_PLAT_EZNPS + unsigned long eflags; /* Extended FLAGS */ + unsigned long gpa1; /* General Purpose Aux */ +#endif + /* Real registers */ unsigned long bta; /* bta_l1, bta_l2, erbta */ diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h index 233d5ffe6ec7..47efc8451b70 100644 --- a/arch/arc/include/asm/spinlock.h +++ b/arch/arc/include/asm/spinlock.h @@ -16,11 +16,6 @@ #define arch_spin_is_locked(x) ((x)->slock != __ARCH_SPIN_LOCK_UNLOCKED__) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->slock, !VAL); -} - #ifdef CONFIG_ARC_HAS_LLSC static inline void arch_spin_lock(arch_spinlock_t *lock) @@ -252,9 +247,15 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) __asm__ __volatile__( "1: ex %0, [%1] \n" +#ifdef CONFIG_EZNPS_MTM_EXT + " .word %3 \n" +#endif " breq %0, %2, 1b \n" : "+&r" (val) : "r"(&(lock->slock)), "ir"(__ARCH_SPIN_LOCK_LOCKED__) +#ifdef CONFIG_EZNPS_MTM_EXT + , "i"(CTOP_INST_SCHD_RW) +#endif : "memory"); /* @@ -296,6 +297,12 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) */ smp_mb(); + /* + * EX is not really required here, a simple STore of 0 suffices. + * However this causes tasklist livelocks in SystemC based SMP virtual + * platforms where the systemc core scheduler uses EX as a cue for + * moving to next core. Do a git log of this file for details + */ __asm__ __volatile__( " ex %0, [%1] \n" : "+r" (val) diff --git a/arch/arc/include/asm/switch_to.h b/arch/arc/include/asm/switch_to.h index 1b171ab5fec0..f7d07feeea61 100644 --- a/arch/arc/include/asm/switch_to.h +++ b/arch/arc/include/asm/switch_to.h @@ -26,10 +26,19 @@ extern void fpu_save_restore(struct task_struct *p, struct task_struct *n); #endif /* !CONFIG_ARC_FPU_SAVE_RESTORE */ +#ifdef CONFIG_ARC_PLAT_EZNPS +extern void dp_save_restore(struct task_struct *p, struct task_struct *n); +#define ARC_EZNPS_DP_PREV(p, n) dp_save_restore(p, n) +#else +#define ARC_EZNPS_DP_PREV(p, n) + +#endif /* !CONFIG_ARC_PLAT_EZNPS */ + struct task_struct *__switch_to(struct task_struct *p, struct task_struct *n); #define switch_to(prev, next, last) \ do { \ + ARC_EZNPS_DP_PREV(prev, next); \ ARC_FPU_PREV(prev, next); \ last = __switch_to(prev, next);\ ARC_FPU_NEXT(next); \ diff --git a/arch/arc/include/uapi/asm/byteorder.h b/arch/arc/include/uapi/asm/byteorder.h index ea5ca444c7e3..5540111531c7 100644 --- a/arch/arc/include/uapi/asm/byteorder.h +++ b/arch/arc/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/cachectl.h b/arch/arc/include/uapi/asm/cachectl.h index 51c73f0255b3..0e4f2affc7e9 100644 --- a/arch/arc/include/uapi/asm/cachectl.h +++ b/arch/arc/include/uapi/asm/cachectl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/elf.h b/arch/arc/include/uapi/asm/elf.h index 06d95e611616..3c1dae4e5aad 100644 --- a/arch/arc/include/uapi/asm/elf.h +++ b/arch/arc/include/uapi/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/page.h b/arch/arc/include/uapi/asm/page.h index 059aff38f10a..2a97e2718a21 100644 --- a/arch/arc/include/uapi/asm/page.h +++ b/arch/arc/include/uapi/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/ptrace.h b/arch/arc/include/uapi/asm/ptrace.h index dd206e6b482c..2a6eff57f6dd 100644 --- a/arch/arc/include/uapi/asm/ptrace.h +++ b/arch/arc/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/sigcontext.h b/arch/arc/include/uapi/asm/sigcontext.h index 9678a11fc158..95f8a4380e11 100644 --- a/arch/arc/include/uapi/asm/sigcontext.h +++ b/arch/arc/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/signal.h b/arch/arc/include/uapi/asm/signal.h index fad62f7f42d6..ba3143a1b375 100644 --- a/arch/arc/include/uapi/asm/signal.h +++ b/arch/arc/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/swab.h b/arch/arc/include/uapi/asm/swab.h index 71f3918b0fc3..02109cd48ee1 100644 --- a/arch/arc/include/uapi/asm/swab.h +++ b/arch/arc/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/include/uapi/asm/unistd.h b/arch/arc/include/uapi/asm/unistd.h index 9a34136d84b2..517178b1daef 100644 --- a/arch/arc/include/uapi/asm/unistd.h +++ b/arch/arc/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) * diff --git a/arch/arc/kernel/Makefile b/arch/arc/kernel/Makefile index 8942c5c3b4c5..2dc5f4296d44 100644 --- a/arch/arc/kernel/Makefile +++ b/arch/arc/kernel/Makefile @@ -12,7 +12,6 @@ obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o obj-$(CONFIG_ISA_ARCV2) += entry-arcv2.o intc-arcv2.o -obj-$(CONFIG_PCI) += pcibios.o obj-$(CONFIG_MODULES) += arcksyms.o module.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c index 3b67f538f142..521ef3521a1c 100644 --- a/arch/arc/kernel/devtree.c +++ b/arch/arc/kernel/devtree.c @@ -29,8 +29,9 @@ static void __init arc_set_early_base_baud(unsigned long dt_root) { if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x")) arc_base_baud = 166666666; /* Fixed 166.6MHz clk (TB10x) */ - else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp")) - arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x) */ + else if (of_flat_dt_is_compatible(dt_root, "snps,arc-sdp") || + of_flat_dt_is_compatible(dt_root, "snps,hsdk")) + arc_base_baud = 33333333; /* Fixed 33MHz clk (AXS10x & HSDK) */ else if (of_flat_dt_is_compatible(dt_root, "ezchip,arc-nps")) arc_base_baud = 800000000; /* Fixed 800MHz clk (NPS) */ else diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index 9211707634dc..f285dbb28066 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -25,12 +25,12 @@ * * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK) * -do_signal()invoked upon TIF_RESTORE_SIGMASK as well - * -Wrappers for sys_{,rt_}sigsuspend() nolonger needed as they don't + * -Wrappers for sys_{,rt_}sigsuspend() no longer needed as they don't * need ptregs anymore * * Vineetg: Oct 2009 * -In a rare scenario, Process gets a Priv-V exception and gets scheduled - * out. Since we don't do FAKE RTIE for Priv-V, CPU excpetion state remains + * out. Since we don't do FAKE RTIE for Priv-V, CPU exception state remains * active (AE bit enabled). This causes a double fault for a subseq valid * exception. Thus FAKE RTIE needed in low level Priv-Violation handler. * Instr Error could also cause similar scenario, so same there as well. @@ -59,7 +59,7 @@ */ #include -#include /* {EXTRY,EXIT} */ +#include /* {ENTRY,EXIT} */ #include #include @@ -80,8 +80,8 @@ .align 4 /* Each entry in the vector table must occupy 2 words. Since it is a jump - * across sections (.vector to .text) we are gauranteed that 'j somewhere' - * will use the 'j limm' form of the intrsuction as long as somewhere is in + * across sections (.vector to .text) we are guaranteed that 'j somewhere' + * will use the 'j limm' form of the instruction as long as somewhere is in * a section other than .vector. */ @@ -105,13 +105,13 @@ VECTOR handle_interrupt_level1 ; Other devices ; ******************** Exceptions ********************** VECTOR EV_MachineCheck ; 0x100, Fatal Machine check (0x20) -VECTOR EV_TLBMissI ; 0x108, Intruction TLB miss (0x21) +VECTOR EV_TLBMissI ; 0x108, Instruction TLB miss (0x21) VECTOR EV_TLBMissD ; 0x110, Data TLB miss (0x22) VECTOR EV_TLBProtV ; 0x118, Protection Violation (0x23) ; or Misaligned Access VECTOR EV_PrivilegeV ; 0x120, Privilege Violation (0x24) VECTOR EV_Trap ; 0x128, Trap exception (0x25) -VECTOR EV_Extension ; 0x130, Extn Intruction Excp (0x26) +VECTOR EV_Extension ; 0x130, Extn Instruction Excp (0x26) .rept 24 VECTOR reserved ; Reserved Exceptions @@ -199,7 +199,7 @@ END(handle_interrupt_level2) ; --------------------------------------------- ; User Mode Memory Bus Error Interrupt Handler -; (Kernel mode memory errors handled via seperate exception vectors) +; (Kernel mode memory errors handled via separate exception vectors) ; --------------------------------------------- ENTRY(mem_service) @@ -273,7 +273,7 @@ ENTRY(EV_TLBProtV) ;------ (5) Type of Protection Violation? ---------- ; ; ProtV Hardware Exception is triggered for Access Faults of 2 types - ; -Access Violaton : 00_23_(00|01|02|03)_00 + ; -Access Violation : 00_23_(00|01|02|03)_00 ; x r w r+w ; -Unaligned Access : 00_23_04_00 ; @@ -327,7 +327,7 @@ END(call_do_page_fault) .Lrestore_regs: - # Interrpts are actually disabled from this point on, but will get + # Interrupts are actually disabled from this point on, but will get # reenabled after we return from interrupt/exception. # But irq tracer needs to be told now... TRACE_ASM_IRQ_ENABLE @@ -335,7 +335,7 @@ END(call_do_page_fault) lr r10, [status32] ; Restore REG File. In case multiple Events outstanding, - ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None + ; use the same priority as rtie: EXCPN, L2 IRQ, L1 IRQ, None ; Note that we use realtime STATUS32 (not pt_regs->status32) to ; decide that. diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 1eea99beecc3..85d9ea4a0acc 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -92,6 +92,12 @@ ENTRY(EV_MachineCheck) lr r0, [efa] mov r1, sp + ; hardware auto-disables MMU, re-enable it to allow kernel vaddr + ; access for say stack unwinding of modules for crash dumps + lr r3, [ARC_REG_PID] + or r3, r3, MMU_ENABLE + sr r3, [ARC_REG_PID] + lsr r3, r2, 8 bmsk r3, r3, 7 brne r3, ECR_C_MCHK_DUP_TLB, 1f diff --git a/arch/arc/kernel/pcibios.c b/arch/arc/kernel/pcibios.c deleted file mode 100644 index 72e1d73d0bd6..000000000000 --- a/arch/arc/kernel/pcibios.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2014-2015 Synopsys, Inc. (www.synopsys.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -/* - * We don't have to worry about legacy ISA devices, so nothing to do here - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c index 2a018de6d6cd..5ac3b547453f 100644 --- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -79,15 +79,40 @@ done: return uval; } +#ifdef CONFIG_ISA_ARCV2 + void arch_cpu_idle(void) { - /* sleep, but enable all interrupts before committing */ + /* Re-enable interrupts <= default irq priority before commiting SLEEP */ + const unsigned int arg = 0x10 | ARCV2_IRQ_DEF_PRIO; + __asm__ __volatile__( "sleep %0 \n" : - :"I"(ISA_SLEEP_ARG)); /* can't be "r" has to be embedded const */ + :"I"(arg)); /* can't be "r" has to be embedded const */ } +#elif defined(CONFIG_EZNPS_MTM_EXT) /* ARC700 variant in NPS */ + +void arch_cpu_idle(void) +{ + /* only the calling HW thread needs to sleep */ + __asm__ __volatile__( + ".word %0 \n" + : + :"i"(CTOP_INST_HWSCHD_WFT_IE12)); +} + +#else /* ARC700 */ + +void arch_cpu_idle(void) +{ + /* sleep, but enable both set E1/E2 (levels of interrutps) before committing */ + __asm__ __volatile__("sleep 0x3 \n"); +} + +#endif + asmlinkage void ret_from_fork(void); /* @@ -209,6 +234,10 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp) */ regs->status32 = STATUS_U_MASK | STATUS_L_MASK | ISA_INIT_STATUS_BITS; +#ifdef CONFIG_EZNPS_MTM_EXT + regs->eflags = 0; +#endif + /* bogus seed values for debugging */ regs->lp_start = 0x10; regs->lp_end = 0x80; diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index 666613fde91d..fb83844daeea 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -51,6 +51,7 @@ static const struct id_to_str arc_cpu_rel[] = { { 0x51, "R2.0" }, { 0x52, "R2.1" }, { 0x53, "R3.0" }, + { 0x54, "R4.0" }, #endif { 0x00, NULL } }; @@ -62,6 +63,7 @@ static const struct id_to_str arc_cpu_nm[] = { #else { 0x40, "ARC EM" }, { 0x50, "ARC HS38" }, + { 0x54, "ARC HS48" }, #endif { 0x00, "Unknown" } }; @@ -119,11 +121,11 @@ static void read_arc_build_cfg_regs(void) struct bcr_generic bcr; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; const struct id_to_str *tbl; + struct bcr_isa_arcv2 isa; FIX_PTR(cpu); READ_BCR(AUX_IDENTITY, cpu->core); - READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa); for (tbl = &arc_cpu_rel[0]; tbl->id != 0; tbl++) { if (cpu->core.family == tbl->id) { @@ -133,7 +135,7 @@ static void read_arc_build_cfg_regs(void) } for (tbl = &arc_cpu_nm[0]; tbl->id != 0; tbl++) { - if ((cpu->core.family & 0xF0) == tbl->id) + if ((cpu->core.family & 0xF4) == tbl->id) break; } cpu->name = tbl->str; @@ -192,6 +194,14 @@ static void read_arc_build_cfg_regs(void) cpu->bpu.full = bpu.ft; cpu->bpu.num_cache = 256 << bpu.bce; cpu->bpu.num_pred = 2048 << bpu.pte; + + if (cpu->core.family >= 0x54) { + unsigned int exec_ctrl; + + READ_BCR(AUX_EXEC_CTRL, exec_ctrl); + cpu->extn.dual_iss_exist = 1; + cpu->extn.dual_iss_enb = exec_ctrl & 1; + } } READ_BCR(ARC_REG_AP_BCR, bcr); @@ -205,18 +215,25 @@ static void read_arc_build_cfg_regs(void) cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt; + READ_BCR(ARC_REG_ISA_CFG_BCR, isa); + /* some hacks for lack of feature BCR info in old ARC700 cores */ if (is_isa_arcompact()) { - if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */ + if (!isa.ver) /* ISA BCR absent, use Kconfig info */ cpu->isa.atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); - else - cpu->isa.atomic = cpu->isa.atomic1; + else { + /* ARC700_BUILD only has 2 bits of isa info */ + struct bcr_generic bcr = *(struct bcr_generic *)&isa; + cpu->isa.atomic = bcr.info & 1; + } cpu->isa.be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); /* there's no direct way to distinguish 750 vs. 770 */ if (unlikely(cpu->core.family < 0x34 || cpu->mmu.ver < 3)) cpu->name = "ARC750"; + } else { + cpu->isa = isa; } } @@ -232,10 +249,11 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", core->family, core->cpu_id, core->chip_id); - n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s\n", + n += scnprintf(buf + n, len - n, "processor [%d]\t: %s %s (%s ISA) %s%s%s\n", cpu_id, cpu->name, cpu->details, is_isa_arcompact() ? "ARCompact" : "ARCv2", - IS_AVAIL1(cpu->isa.be, "[Big-Endian]")); + IS_AVAIL1(cpu->isa.be, "[Big-Endian]"), + IS_AVAIL3(cpu->extn.dual_iss_exist, cpu->extn.dual_iss_enb, " Dual-Issue")); n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ", IS_AVAIL1(cpu->extn.timer0, "Timer0 "), @@ -385,13 +403,13 @@ void setup_processor(void) read_arc_build_cfg_regs(); arc_init_IRQ(); - printk(arc_cpu_mumbojumbo(cpu_id, str, sizeof(str))); + pr_info("%s", arc_cpu_mumbojumbo(cpu_id, str, sizeof(str))); arc_mmu_init(); arc_cache_init(); - printk(arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); - printk(arc_platform_smp_cpuinfo()); + pr_info("%s", arc_extn_mumbojumbo(cpu_id, str, sizeof(str))); + pr_info("%s", arc_platform_smp_cpuinfo()); arc_chk_core_config(); } @@ -510,7 +528,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) goto done; } - str = (char *)__get_free_page(GFP_TEMPORARY); + str = (char *)__get_free_page(GFP_KERNEL); if (!str) goto done; diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index f46267153ec2..6df9d94a9537 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -23,6 +23,8 @@ #include #include #include +#include + #include #include #include @@ -30,6 +32,9 @@ #ifndef CONFIG_ARC_HAS_LLSC arch_spinlock_t smp_atomic_ops_lock = __ARCH_SPIN_LOCK_UNLOCKED; arch_spinlock_t smp_bitops_lock = __ARCH_SPIN_LOCK_UNLOCKED; + +EXPORT_SYMBOL_GPL(smp_atomic_ops_lock); +EXPORT_SYMBOL_GPL(smp_bitops_lock); #endif struct plat_smp_ops __weak plat_smp_ops; diff --git a/arch/arc/kernel/sys.c b/arch/arc/kernel/sys.c index 9d6c1ca26af6..fddecc76efb7 100644 --- a/arch/arc/kernel/sys.c +++ b/arch/arc/kernel/sys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index ff83e78d0cfb..bcd7c9fc5d0f 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c @@ -80,7 +80,7 @@ int name(unsigned long address, struct pt_regs *regs) \ DO_ERROR_INFO(SIGILL, "Priv Op/Disabled Extn", do_privilege_fault, ILL_PRVOPC) DO_ERROR_INFO(SIGILL, "Invalid Extn Insn", do_extension_fault, ILL_ILLOPC) DO_ERROR_INFO(SIGILL, "Illegal Insn (or Seq)", insterror_is_error, ILL_ILLOPC) -DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", do_memory_error, BUS_ADRERR) +DO_ERROR_INFO(SIGBUS, "Invalid Mem Access", __weak do_memory_error, BUS_ADRERR) DO_ERROR_INFO(SIGTRAP, "Breakpoint Set", trap_is_brkpt, TRAP_BRKPT) DO_ERROR_INFO(SIGBUS, "Misaligned Access", do_misaligned_error, BUS_ADRALN) @@ -103,7 +103,7 @@ int do_misaligned_access(unsigned long address, struct pt_regs *regs, */ void do_machine_check_fault(unsigned long address, struct pt_regs *regs) { - die("Machine Check Exception", regs, address); + die("Unhandled Machine Check Exception", regs, address); } diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c index f9caf79186d4..7d8c1d6c2f60 100644 --- a/arch/arc/kernel/troubleshoot.c +++ b/arch/arc/kernel/troubleshoot.c @@ -140,7 +140,7 @@ static void show_ecr_verbose(struct pt_regs *regs) } else if (vec == ECR_V_ITLB_MISS) { pr_cont("Insn could not be fetched\n"); } else if (vec == ECR_V_MACH_CHK) { - pr_cont("%s\n", (cause_code == 0x0) ? + pr_cont("Machine Check (%s)\n", (cause_code == 0x0) ? "Double Fault" : "Other Fatal Err"); } else if (vec == ECR_V_PROTV) { @@ -178,7 +178,7 @@ void show_regs(struct pt_regs *regs) struct callee_regs *cregs; char *buf; - buf = (char *)__get_free_page(GFP_TEMPORARY); + buf = (char *)__get_free_page(GFP_KERNEL); if (!buf) return; @@ -233,6 +233,9 @@ void show_kernel_fault_diag(const char *str, struct pt_regs *regs, { current->thread.fault_address = address; + /* Show fault description */ + pr_info("\n%s\n", str); + /* Caller and Callee regs */ show_regs(regs); diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 7db283b46ebd..eee924dfffa6 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -652,7 +652,7 @@ static void __ic_line_inv_vaddr(phys_addr_t paddr, unsigned long vaddr, #endif /* CONFIG_ARC_HAS_ICACHE */ -noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op) +noinline void slc_op_rgn(phys_addr_t paddr, unsigned long sz, const int op) { #ifdef CONFIG_ISA_ARCV2 /* @@ -715,6 +715,58 @@ noinline void slc_op(phys_addr_t paddr, unsigned long sz, const int op) #endif } +noinline void slc_op_line(phys_addr_t paddr, unsigned long sz, const int op) +{ +#ifdef CONFIG_ISA_ARCV2 + /* + * SLC is shared between all cores and concurrent aux operations from + * multiple cores need to be serialized using a spinlock + * A concurrent operation can be silently ignored and/or the old/new + * operation can remain incomplete forever (lockup in SLC_CTRL_BUSY loop + * below) + */ + static DEFINE_SPINLOCK(lock); + + const unsigned long SLC_LINE_MASK = ~(l2_line_sz - 1); + unsigned int ctrl, cmd; + unsigned long flags; + int num_lines; + + spin_lock_irqsave(&lock, flags); + + ctrl = read_aux_reg(ARC_REG_SLC_CTRL); + + /* Don't rely on default value of IM bit */ + if (!(op & OP_FLUSH)) /* i.e. OP_INV */ + ctrl &= ~SLC_CTRL_IM; /* clear IM: Disable flush before Inv */ + else + ctrl |= SLC_CTRL_IM; + + write_aux_reg(ARC_REG_SLC_CTRL, ctrl); + + cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL; + + sz += paddr & ~SLC_LINE_MASK; + paddr &= SLC_LINE_MASK; + + num_lines = DIV_ROUND_UP(sz, l2_line_sz); + + while (num_lines-- > 0) { + write_aux_reg(cmd, paddr); + paddr += l2_line_sz; + } + + /* Make sure "busy" bit reports correct stataus, see STAR 9001165532 */ + read_aux_reg(ARC_REG_SLC_CTRL); + + while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY); + + spin_unlock_irqrestore(&lock, flags); +#endif +} + +#define slc_op(paddr, sz, op) slc_op_rgn(paddr, sz, op) + noinline static void slc_entire_op(const int op) { unsigned int ctrl, r = ARC_REG_SLC_CTRL; @@ -1095,7 +1147,7 @@ SYSCALL_DEFINE3(cacheflush, uint32_t, start, uint32_t, sz, uint32_t, flags) */ noinline void __init arc_ioc_setup(void) { - unsigned int ap_sz; + unsigned int ioc_base, mem_sz; /* Flush + invalidate + disable L1 dcache */ __dc_disable(); @@ -1104,18 +1156,29 @@ noinline void __init arc_ioc_setup(void) if (read_aux_reg(ARC_REG_SLC_BCR)) slc_entire_op(OP_FLUSH_N_INV); - /* IOC Aperture start: TDB: handle non default CONFIG_LINUX_LINK_BASE */ - write_aux_reg(ARC_REG_IO_COH_AP0_BASE, 0x80000); - /* - * IOC Aperture size: - * decoded as 2 ^ (SIZE + 2) KB: so setting 0x11 implies 512M + * currently IOC Aperture covers entire DDR * TBD: fix for PGU + 1GB of low mem * TBD: fix for PAE */ - ap_sz = order_base_2(arc_get_mem_sz()/1024) - 2; - write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, ap_sz); + mem_sz = arc_get_mem_sz(); + if (!is_power_of_2(mem_sz) || mem_sz < 4096) + panic("IOC Aperture size must be power of 2 larger than 4KB"); + + /* + * IOC Aperture size decoded as 2 ^ (SIZE + 2) KB, + * so setting 0x11 implies 512MB, 0x12 implies 1GB... + */ + write_aux_reg(ARC_REG_IO_COH_AP0_SIZE, order_base_2(mem_sz >> 10) - 2); + + /* for now assume kernel base is start of IOC aperture */ + ioc_base = CONFIG_LINUX_RAM_BASE; + + if (ioc_base % mem_sz != 0) + panic("IOC Aperture start must be aligned to the size of the aperture"); + + write_aux_reg(ARC_REG_IO_COH_AP0_BASE, ioc_base >> 12); write_aux_reg(ARC_REG_IO_COH_PARTIAL, 1); write_aux_reg(ARC_REG_IO_COH_ENABLE, 1); @@ -1207,7 +1270,7 @@ void __ref arc_cache_init(void) unsigned int __maybe_unused cpu = smp_processor_id(); char str[256]; - printk(arc_cache_mumbojumbo(0, str, sizeof(str))); + pr_info("%s", arc_cache_mumbojumbo(0, str, sizeof(str))); if (!cpu) arc_cache_init_master(); diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index 162c97528872..a0b7bd6d030d 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c @@ -207,7 +207,7 @@ no_context: /* Are we prepared to handle this kernel fault? * * (The kernel has valid exception-points in the source - * when it acesses user-memory. When it fails in one + * when it accesses user-memory. When it fails in one * of those points, we find it in a table and do a jump * to some fixup code that loads an appropriate error * code) diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index 8c9415ed6280..ba145065c579 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c @@ -26,7 +26,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __aligned(PAGE_SIZE); char empty_zero_page[PAGE_SIZE] __aligned(PAGE_SIZE); EXPORT_SYMBOL(empty_zero_page); -static const unsigned long low_mem_start = CONFIG_LINUX_LINK_BASE; +static const unsigned long low_mem_start = CONFIG_LINUX_RAM_BASE; static unsigned long low_mem_sz; #ifdef CONFIG_HIGHMEM @@ -63,7 +63,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) if (!low_mem_sz) { if (base != low_mem_start) - panic("CONFIG_LINUX_LINK_BASE != DT memory { }"); + panic("CONFIG_LINUX_RAM_BASE != DT memory { }"); low_mem_sz = size; in_use = 1; @@ -161,7 +161,7 @@ void __init setup_arch_memory(void) * We can't use the helper free_area_init(zones[]) because it uses * PAGE_OFFSET to compute the @min_low_pfn which would be wrong * when our kernel doesn't start at PAGE_OFFSET, i.e. - * PAGE_OFFSET != CONFIG_LINUX_LINK_BASE + * PAGE_OFFSET != CONFIG_LINUX_RAM_BASE */ free_area_init_node(0, /* node-id */ zones_size, /* num pages per zone */ diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index b181f3ee38aa..8ceefbf72fb0 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -821,7 +821,7 @@ void arc_mmu_init(void) char str[256]; struct cpuinfo_arc_mmu *mmu = &cpuinfo_arc700[smp_processor_id()].mmu; - printk(arc_mmu_mumbojumbo(0, str, sizeof(str))); + pr_info("%s", arc_mmu_mumbojumbo(0, str, sizeof(str))); /* * Can't be done in processor.h due to header include depenedencies @@ -908,9 +908,6 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, local_irq_save(flags); - /* re-enable the MMU */ - write_aux_reg(ARC_REG_PID, MMU_ENABLE | read_aux_reg(ARC_REG_PID)); - /* loop thru all sets of TLB */ for (set = 0; set < mmu->sets; set++) { diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S index b30e4e36bb00..0e1e47a67c73 100644 --- a/arch/arc/mm/tlbex.S +++ b/arch/arc/mm/tlbex.S @@ -274,6 +274,13 @@ ex_saved_reg1: .macro COMMIT_ENTRY_TO_MMU #if (CONFIG_ARC_MMU_VER < 4) +#ifdef CONFIG_EZNPS_MTM_EXT + /* verify if entry for this vaddr+ASID already exists */ + sr TLBProbe, [ARC_REG_TLBCOMMAND] + lr r0, [ARC_REG_TLBINDEX] + bbit0 r0, 31, 88f +#endif + /* Get free TLB slot: Set = computed from vaddr, way = random */ sr TLBGetIndex, [ARC_REG_TLBCOMMAND] @@ -287,6 +294,8 @@ ex_saved_reg1: #else sr TLBInsertEntry, [ARC_REG_TLBCOMMAND] #endif + +88: .endm diff --git a/arch/arc/oprofile/Makefile b/arch/arc/oprofile/Makefile index ce417a6e70b8..698367bb41d0 100644 --- a/arch/arc/oprofile/Makefile +++ b/arch/arc/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ diff --git a/arch/arc/plat-axs10x/axs10x.c b/arch/arc/plat-axs10x/axs10x.c index 38ff349d7f2a..cf14ebc36916 100644 --- a/arch/arc/plat-axs10x/axs10x.c +++ b/arch/arc/plat-axs10x/axs10x.c @@ -80,22 +80,6 @@ static void __init axs10x_enable_gpio_intc_wire(void) iowrite32(1 << MB_TO_GPIO_IRQ, (void __iomem *) GPIO_INTEN); } -static inline void __init -write_cgu_reg(uint32_t value, void __iomem *reg, void __iomem *lock_reg) -{ - unsigned int loops = 128 * 1024, ctr; - - iowrite32(value, reg); - - ctr = loops; - while (((ioread32(lock_reg) & 1) == 1) && ctr--) /* wait for unlock */ - cpu_relax(); - - ctr = loops; - while (((ioread32(lock_reg) & 1) == 0) && ctr--) /* wait for re-lock */ - cpu_relax(); -} - static void __init axs10x_print_board_ver(unsigned int creg, const char *str) { union ver { @@ -127,6 +111,13 @@ static void __init axs10x_early_init(void) axs10x_enable_gpio_intc_wire(); + /* + * Reset ethernet IP core. + * TODO: get rid of this quirk after axs10x reset driver (or simple + * reset driver) will be available in upstream. + */ + iowrite32((1 << 5), (void __iomem *) CREG_MB_SW_RESET); + scnprintf(mb, 32, "MainBoard v%d", mb_rev); axs10x_print_board_ver(CREG_MB_VER, mb); } @@ -314,7 +305,6 @@ static void __init axs101_early_init(void) #ifdef CONFIG_AXS103 -#define AXC003_CGU 0xF0000000 #define AXC003_CREG 0xF0001000 #define AXC003_MST_AXI_TUNNEL 0 #define AXC003_MST_HS38 1 @@ -324,131 +314,38 @@ static void __init axs101_early_init(void) #define CREG_CPU_TUN_IO_CTRL (AXC003_CREG + 0x494) -union pll_reg { - struct { -#ifdef CONFIG_CPU_BIG_ENDIAN - unsigned int pad:17, noupd:1, bypass:1, edge:1, high:6, low:6; -#else - unsigned int low:6, high:6, edge:1, bypass:1, noupd:1, pad:17; -#endif - }; - unsigned int val; -}; - -static unsigned int __init axs103_get_freq(void) -{ - union pll_reg idiv, fbdiv, odiv; - unsigned int f = 33333333; - - idiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 0); - fbdiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 4); - odiv.val = ioread32((void __iomem *)AXC003_CGU + 0x80 + 8); - - if (idiv.bypass != 1) - f = f / (idiv.low + idiv.high); - - if (fbdiv.bypass != 1) - f = f * (fbdiv.low + fbdiv.high); - - if (odiv.bypass != 1) - f = f / (odiv.low + odiv.high); - - f = (f + 500000) / 1000000; /* Rounding */ - return f; -} - -static inline unsigned int __init encode_div(unsigned int id, int upd) -{ - union pll_reg div; - - div.val = 0; - - div.noupd = !upd; - div.bypass = id == 1 ? 1 : 0; - div.edge = (id%2 == 0) ? 0 : 1; /* 0 = rising */ - div.low = (id%2 == 0) ? id >> 1 : (id >> 1)+1; - div.high = id >> 1; - - return div.val; -} - -noinline static void __init -axs103_set_freq(unsigned int id, unsigned int fd, unsigned int od) -{ - write_cgu_reg(encode_div(id, 0), - (void __iomem *)AXC003_CGU + 0x80 + 0, - (void __iomem *)AXC003_CGU + 0x110); - - write_cgu_reg(encode_div(fd, 0), - (void __iomem *)AXC003_CGU + 0x80 + 4, - (void __iomem *)AXC003_CGU + 0x110); - - write_cgu_reg(encode_div(od, 1), - (void __iomem *)AXC003_CGU + 0x80 + 8, - (void __iomem *)AXC003_CGU + 0x110); -} - static void __init axs103_early_init(void) { - int offset = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk"); - const struct fdt_property *prop = fdt_get_property(initial_boot_params, - offset, - "clock-frequency", - NULL); - u32 freq = be32_to_cpu(*(u32*)(prop->data)) / 1000000, orig = freq; - +#ifdef CONFIG_ARC_MCIP /* * AXS103 configurations for SMP/QUAD configurations share device tree - * which defaults to 90 MHz. However recent failures of Quad config + * which defaults to 100 MHz. However recent failures of Quad config * revealed P&R timing violations so clamp it down to safe 50 MHz * Instead of duplicating defconfig/DT for SMP/QUAD, add a small hack - * - * This hack is really hacky as of now. Fix it properly by getting the - * number of cores as return value of platform's early SMP callback + * of fudging the freq in DT */ -#ifdef CONFIG_ARC_MCIP unsigned int num_cores = (read_aux_reg(ARC_REG_MCIP_BCR) >> 16) & 0x3F; - if (num_cores > 2) - freq = 50; -#endif - - switch (freq) { - case 33: - axs103_set_freq(1, 1, 1); - break; - case 50: - axs103_set_freq(1, 30, 20); - break; - case 75: - axs103_set_freq(2, 45, 10); - break; - case 90: - axs103_set_freq(2, 54, 10); - break; - case 100: - axs103_set_freq(1, 30, 10); - break; - case 125: - axs103_set_freq(2, 45, 6); - break; - default: + if (num_cores > 2) { + u32 freq = 50, orig; /* - * In this case, core_frequency derived from - * DT "clock-frequency" might not match with board value. - * Hence update it to match the board value. + * TODO: use cpu node "cpu-freq" param instead of platform-specific + * "/cpu_card/core_clk" as it works only if we use fixed-clock for cpu. */ - freq = axs103_get_freq(); - break; - } + int off = fdt_path_offset(initial_boot_params, "/cpu_card/core_clk"); + const struct fdt_property *prop; - pr_info("Freq is %dMHz\n", freq); + prop = fdt_get_property(initial_boot_params, off, + "clock-frequency", NULL); + orig = be32_to_cpu(*(u32*)(prop->data)) / 1000000; - /* Patching .dtb in-place with new core clock value */ - if (freq != orig ) { - freq = cpu_to_be32(freq * 1000000); - fdt_setprop_inplace(initial_boot_params, offset, - "clock-frequency", &freq, sizeof(freq)); + /* Patching .dtb in-place with new core clock value */ + if (freq != orig ) { + freq = cpu_to_be32(freq * 1000000); + fdt_setprop_inplace(initial_boot_params, off, + "clock-frequency", &freq, sizeof(freq)); + } } +#endif /* Memory maps already config in pre-bootloader */ diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig index 1595a38e50cd..8eff057efcae 100644 --- a/arch/arc/plat-eznps/Kconfig +++ b/arch/arc/plat-eznps/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. @@ -12,8 +13,8 @@ menuconfig ARC_PLAT_EZNPS help Support for EZchip development platforms, based on ARC700 cores. - We handle few flavours: - - Hardware Emulator AKA HE which is FPGA based chasis + We handle few flavors: + - Hardware Emulator AKA HE which is FPGA based chassis - Simulator based on MetaWare nSIM - NPS400 chip based on ASIC @@ -32,3 +33,25 @@ config EZNPS_MTM_EXT any of them seem like CPU from Linux point of view. All threads within same core share the execution unit of the core and HW scheduler round robin between them. + +config EZNPS_MEM_ERROR_ALIGN + bool "ARC-EZchip Memory error as an exception" + depends on EZNPS_MTM_EXT + default n + help + On the real chip of the NPS, user memory errors are handled + as a machine check exception, which is fatal, whereas on + simulator platform for NPS, is handled as a Level 2 interrupt + (just a stock ARC700) which is recoverable. This option makes + simulator behave like hardware. + +config EZNPS_SHARED_AUX_REGS + bool "ARC-EZchip Shared Auxiliary Registers Per Core" + depends on ARC_PLAT_EZNPS + default y + help + On the real chip of the NPS, auxiliary registers are shared between + all the cpus of the core, whereas on simulator platform for NPS, + each cpu has a different set of auxiliary registers. Configuration + should be unset if auxiliary registers are not shared between the cpus + of the core, so there will be a need to initialize them per cpu. diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile index 21091b199df0..8d4371706b2f 100644 --- a/arch/arc/plat-eznps/Makefile +++ b/arch/arc/plat-eznps/Makefile @@ -2,6 +2,6 @@ # Makefile for the linux kernel. # -obj-y := entry.o platform.o +obj-y := entry.o platform.o ctop.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o diff --git a/arch/arc/plat-eznps/ctop.c b/arch/arc/plat-eznps/ctop.c new file mode 100644 index 000000000000..030bcd070a1b --- /dev/null +++ b/arch/arc/plat-eznps/ctop.c @@ -0,0 +1,32 @@ +/* + * Copyright(c) 2015 EZchip Technologies. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + */ + +#include +#include +#include + +void dp_save_restore(struct task_struct *prev, struct task_struct *next) +{ + struct eznps_dp *prev_task_dp = &prev->thread.dp; + struct eznps_dp *next_task_dp = &next->thread.dp; + + /* Here we save all Data Plane related auxiliary registers */ + prev_task_dp->eflags = read_aux_reg(CTOP_AUX_EFLAGS); + write_aux_reg(CTOP_AUX_EFLAGS, next_task_dp->eflags); + + prev_task_dp->gpa1 = read_aux_reg(CTOP_AUX_GPA1); + write_aux_reg(CTOP_AUX_GPA1, next_task_dp->gpa1); +} diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S index 328261c27cda..091c92c32ab6 100644 --- a/arch/arc/plat-eznps/entry.S +++ b/arch/arc/plat-eznps/entry.S @@ -27,7 +27,7 @@ .align 1024 ; HW requierment for restart first PC ENTRY(res_service) -#ifdef CONFIG_EZNPS_MTM_EXT +#if defined(CONFIG_EZNPS_MTM_EXT) && defined(CONFIG_EZNPS_SHARED_AUX_REGS) ; There is no work for HW thread id != 0 lr r3, [CTOP_AUX_THREAD_ID] cmp r3, 0 diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h index ee2e32df5e90..0c7d11022d0f 100644 --- a/arch/arc/plat-eznps/include/plat/ctop.h +++ b/arch/arc/plat-eznps/include/plat/ctop.h @@ -39,6 +39,7 @@ #define CTOP_AUX_LOGIC_CORE_ID (CTOP_AUX_BASE + 0x018) #define CTOP_AUX_MT_CTRL (CTOP_AUX_BASE + 0x020) #define CTOP_AUX_HW_COMPLY (CTOP_AUX_BASE + 0x024) +#define CTOP_AUX_DPC (CTOP_AUX_BASE + 0x02C) #define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030) #define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080) #define CTOP_AUX_IACK (CTOP_AUX_BASE + 0x088) @@ -46,6 +47,7 @@ #define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300) /* EZchip core instructions */ +#define CTOP_INST_HWSCHD_WFT_IE12 0x3E6F7344 #define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF #define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103 #define CTOP_INST_SCHD_RW 0x3E6F7004 diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c index aaaaffd3d940..2388de3d09ef 100644 --- a/arch/arc/plat-eznps/mtm.c +++ b/arch/arc/plat-eznps/mtm.c @@ -21,10 +21,22 @@ #include #include -#define MT_CTRL_HS_CNT 0xFF +#define MT_HS_CNT_MIN 0x01 +#define MT_HS_CNT_MAX 0xFF #define MT_CTRL_ST_CNT 0xF #define NPS_NUM_HW_THREADS 0x10 +static int mtm_hs_ctr = MT_HS_CNT_MAX; + +#ifdef CONFIG_EZNPS_MEM_ERROR_ALIGN +int do_memory_error(unsigned long address, struct pt_regs *regs) +{ + die("Invalid Mem Access", regs, address); + + return 1; +} +#endif + static void mtm_init_nat(int cpu) { struct nps_host_reg_mtm_cfg mtm_cfg; @@ -98,6 +110,18 @@ void mtm_enable_core(unsigned int cpu) int i; struct nps_host_reg_aux_mt_ctrl mt_ctrl; struct nps_host_reg_mtm_cfg mtm_cfg; + struct nps_host_reg_aux_dpc dpc; + + /* + * Initializing dpc register in each CPU. + * Overwriting the init value of the DPC + * register so that CMEM and FMT virtual address + * spaces are accessible, and Data Plane HW + * facilities are enabled. + */ + dpc.ien = 1; + dpc.men = 1; + write_aux_reg(CTOP_AUX_DPC, dpc.value); if (NPS_CPU_TO_THREAD_NUM(cpu) != 0) return; @@ -118,9 +142,7 @@ void mtm_enable_core(unsigned int cpu) /* Enable HW schedule, stall counter, mtm */ mt_ctrl.value = 0; mt_ctrl.hsen = 1; - mt_ctrl.hs_cnt = MT_CTRL_HS_CNT; - mt_ctrl.sten = 1; - mt_ctrl.st_cnt = MT_CTRL_ST_CNT; + mt_ctrl.hs_cnt = mtm_hs_ctr; mt_ctrl.mten = 1; write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value); @@ -131,3 +153,23 @@ void mtm_enable_core(unsigned int cpu) */ cpu_relax(); } + +/* Verify and set the value of the mtm hs counter */ +static int __init set_mtm_hs_ctr(char *ctr_str) +{ + long hs_ctr; + int ret; + + ret = kstrtol(ctr_str, 0, &hs_ctr); + + if (ret || hs_ctr > MT_HS_CNT_MAX || hs_ctr < MT_HS_CNT_MIN) { + pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n", + hs_ctr, MT_HS_CNT_MIN, MT_HS_CNT_MAX); + return -EINVAL; + } + + mtm_hs_ctr = hs_ctr; + + return 0; +} +early_param("nps_mtm_hs_ctr", set_mtm_hs_ctr); diff --git a/arch/arc/plat-hsdk/Kconfig b/arch/arc/plat-hsdk/Kconfig new file mode 100644 index 000000000000..19ab3cf98f0f --- /dev/null +++ b/arch/arc/plat-hsdk/Kconfig @@ -0,0 +1,11 @@ +# Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# + +menuconfig ARC_SOC_HSDK + bool "ARC HS Development Kit SOC" + select CLK_HSDK + select RESET_HSDK diff --git a/arch/arc/plat-hsdk/Makefile b/arch/arc/plat-hsdk/Makefile new file mode 100644 index 000000000000..9a50c511a672 --- /dev/null +++ b/arch/arc/plat-hsdk/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# + +obj-y := platform.o diff --git a/arch/arc/plat-hsdk/platform.c b/arch/arc/plat-hsdk/platform.c new file mode 100644 index 000000000000..fd0ae5e38639 --- /dev/null +++ b/arch/arc/plat-hsdk/platform.c @@ -0,0 +1,118 @@ +/* + * ARC HSDK Platform support code + * + * Copyright (C) 2017 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +#define ARC_CCM_UNUSED_ADDR 0x60000000 + +static void __init hsdk_init_per_cpu(unsigned int cpu) +{ + /* + * By default ICCM is mapped to 0x7z while this area is used for + * kernel virtual mappings, so move it to currently unused area. + */ + if (cpuinfo_arc700[cpu].iccm.sz) + write_aux_reg(ARC_REG_AUX_ICCM, ARC_CCM_UNUSED_ADDR); + + /* + * By default DCCM is mapped to 0x8z while this area is used by kernel, + * so move it to currently unused area. + */ + if (cpuinfo_arc700[cpu].dccm.sz) + write_aux_reg(ARC_REG_AUX_DCCM, ARC_CCM_UNUSED_ADDR); +} + +#define ARC_PERIPHERAL_BASE 0xf0000000 +#define CREG_BASE (ARC_PERIPHERAL_BASE + 0x1000) +#define CREG_PAE (CREG_BASE + 0x180) +#define CREG_PAE_UPDATE (CREG_BASE + 0x194) + +#define CREG_CORE_IF_CLK_DIV (CREG_BASE + 0x4B8) +#define CREG_CORE_IF_CLK_DIV_2 0x1 +#define CGU_BASE ARC_PERIPHERAL_BASE +#define CGU_PLL_STATUS (ARC_PERIPHERAL_BASE + 0x4) +#define CGU_PLL_CTRL (ARC_PERIPHERAL_BASE + 0x0) +#define CGU_PLL_STATUS_LOCK BIT(0) +#define CGU_PLL_STATUS_ERR BIT(1) +#define CGU_PLL_CTRL_1GHZ 0x3A10 +#define HSDK_PLL_LOCK_TIMEOUT 500 + +#define HSDK_PLL_LOCKED() \ + !!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_LOCK) + +#define HSDK_PLL_ERR() \ + !!(ioread32((void __iomem *) CGU_PLL_STATUS) & CGU_PLL_STATUS_ERR) + +static void __init hsdk_set_cpu_freq_1ghz(void) +{ + u32 timeout = HSDK_PLL_LOCK_TIMEOUT; + + /* + * As we set cpu clock which exceeds 500MHz, the divider for the interface + * clock must be programmed to div-by-2. + */ + iowrite32(CREG_CORE_IF_CLK_DIV_2, (void __iomem *) CREG_CORE_IF_CLK_DIV); + + /* Set cpu clock to 1GHz */ + iowrite32(CGU_PLL_CTRL_1GHZ, (void __iomem *) CGU_PLL_CTRL); + + while (!HSDK_PLL_LOCKED() && timeout--) + cpu_relax(); + + if (!HSDK_PLL_LOCKED() || HSDK_PLL_ERR()) + pr_err("Failed to setup CPU frequency to 1GHz!"); +} + +#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xA000) +#define SDIO_UHS_REG_EXT (SDIO_BASE + 0x108) +#define SDIO_UHS_REG_EXT_DIV_2 (2 << 30) + +static void __init hsdk_init_early(void) +{ + /* + * PAE remapping for DMA clients does not work due to an RTL bug, so + * CREG_PAE register must be programmed to all zeroes, otherwise it + * will cause problems with DMA to/from peripherals even if PAE40 is + * not used. + */ + + /* Default is 1, which means "PAE offset = 4GByte" */ + writel_relaxed(0, (void __iomem *) CREG_PAE); + + /* Really apply settings made above */ + writel(1, (void __iomem *) CREG_PAE_UPDATE); + + /* + * Switch SDIO external ciu clock divider from default div-by-8 to + * minimum possible div-by-2. + */ + iowrite32(SDIO_UHS_REG_EXT_DIV_2, (void __iomem *) SDIO_UHS_REG_EXT); + + /* + * Setup CPU frequency to 1GHz. + * TODO: remove it after smart hsdk pll driver will be introduced. + */ + hsdk_set_cpu_freq_1ghz(); +} + +static const char *hsdk_compat[] __initconst = { + "snps,hsdk", + NULL, +}; + +MACHINE_START(SIMULATION, "hsdk") + .dt_compat = hsdk_compat, + .init_early = hsdk_init_early, + .init_per_cpu = hsdk_init_per_cpu, +MACHINE_END diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 61a0cb15067e..d1346a160760 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARM bool default y @@ -50,7 +51,7 @@ config ARM select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) select HAVE_ARCH_TRACEHOOK select HAVE_ARM_SMCCC if CPU_V7 - select HAVE_CBPF_JIT + select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32 select HAVE_CC_STACKPROTECTOR select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT @@ -1531,7 +1532,6 @@ config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K default y if CPU_THUMBONLY - select AEABI select ARM_ASM_UNIFIED select ARM_UNWIND help @@ -1594,7 +1594,8 @@ config ARM_PATCH_IDIV code to do integer division. config AEABI - bool "Use the ARM EABI to compile the kernel" + bool "Use the ARM EABI to compile the kernel" if !CPU_V7 && !CPU_V7M && !CPU_V6 && !CPU_V6K + default CPU_V7 || CPU_V7M || CPU_V6 || CPU_V6K help This option allows for the kernel to be compiled using the latest ARM ABI (aka EABI). This is only useful if you are using a user diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu index b7576349528c..22f34c423be6 100644 --- a/arch/arm/Kconfig-nommu +++ b/arch/arm/Kconfig-nommu @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Kconfig for uClinux(non-paged MM) depend configurations # Hyok S. Choi diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 447629d89884..954ba8b81052 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" @@ -646,7 +647,7 @@ choice config DEBUG_OMAP2UART1 bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 help This covers at least h4, 2430sdp, 3430sdp, 3630sdp, omap3 torpedo and 3530 lv som. @@ -654,17 +655,17 @@ choice config DEBUG_OMAP2UART2 bool "Kernel low-level debugging messages via OMAP2/3/4 UART2" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP2UART3 bool "Kernel low-level debugging messages via OMAP2 UART3 (n8x0)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP3UART3 bool "Kernel low-level debugging messages via OMAP3 UART3 (most omap3 boards)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 help This covers at least cm_t3x, beagle, crane, devkit8000, igep00x0, ldp, n900, n9(50), pandora, overo, touchbook, @@ -673,17 +674,17 @@ choice config DEBUG_OMAP4UART3 bool "Kernel low-level debugging messages via OMAP4/5 UART3 (omap4 blaze, panda, omap5 sevm)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP3UART4 bool "Kernel low-level debugging messages via OMAP36XX UART4" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP4UART4 bool "Kernel low-level debugging messages via OMAP4/5 UART4" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_OMAP7XXUART1 bool "Kernel low-level debugging via OMAP730 UART1" @@ -712,22 +713,22 @@ choice config DEBUG_TI81XXUART1 bool "Kernel low-level debugging messages via TI81XX UART1 (ti8148evm)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_TI81XXUART2 bool "Kernel low-level debugging messages via TI81XX UART2" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_TI81XXUART3 bool "Kernel low-level debugging messages via TI81XX UART3 (ti8168evm)" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_AM33XXUART1 bool "Kernel low-level debugging messages via AM33XX UART1" depends on ARCH_OMAP2PLUS - select DEBUG_OMAP2PLUS_UART + select DEBUG_UART_8250 config DEBUG_ZOOM_UART bool "Kernel low-level debugging messages via Zoom2/3 UART" @@ -896,12 +897,13 @@ choice via SCIF2 on Renesas R-Car H1 (R8A7779). config DEBUG_RCAR_GEN2_SCIF0 - bool "Kernel low-level debugging messages via SCIF0 on R8A7790/R8A7791/R8A7792/R8A7793" - depends on ARCH_R8A7790 || ARCH_R8A7791 || ARCH_R8A7792 || ARCH_R8A7793 + bool "Kernel low-level debugging messages via SCIF0 on R-Car Gen2 and RZ/G1" + depends on ARCH_R8A7743 || ARCH_R8A7790 || ARCH_R8A7791 || \ + ARCH_R8A7792 || ARCH_R8A7793 help Say Y here if you want kernel low-level debugging support - via SCIF0 on Renesas R-Car H2 (R8A7790), M2-W (R8A7791), V2H - (R8A7792), or M2-N (R8A7793). + via SCIF0 on Renesas RZ/G1M (R8A7743), R-Car H2 (R8A7790), + M2-W (R8A7791), V2H (R8A7792), or M2-N (R8A7793). config DEBUG_RCAR_GEN2_SCIF2 bool "Kernel low-level debugging messages via SCIF2 on R8A7794" @@ -1523,6 +1525,17 @@ config DEBUG_UART_PHYS default 0x40090000 if DEBUG_LPC32XX default 0x40100000 if DEBUG_PXA_UART1 default 0x42000000 if DEBUG_GEMINI + default 0x44e09000 if DEBUG_AM33XXUART1 + default 0x48020000 if DEBUG_OMAP4UART3 || DEBUG_TI81XXUART1 + default 0x48022000 if DEBUG_TI81XXUART2 + default 0x48024000 if DEBUG_TI81XXUART3 + default 0x4806a000 if DEBUG_OMAP2UART1 || DEBUG_OMAP3UART1 || \ + DEBUG_OMAP4UART1 || DEBUG_OMAP5UART1 + default 0x4806c000 if DEBUG_OMAP2UART2 || DEBUG_OMAP3UART2 || \ + DEBUG_OMAP4UART2 || DEBUG_OMAP5UART2 + default 0x4806e000 if DEBUG_OMAP2UART3 || DEBUG_OMAP4UART4 + default 0x49020000 if DEBUG_OMAP3UART3 + default 0x49042000 if DEBUG_OMAP3UART4 default 0x50000000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART0 || \ DEBUG_S3C2410_UART0) default 0x50004000 if DEBUG_S3C24XX_UART && (DEBUG_S3C_UART1 || \ @@ -1641,10 +1654,21 @@ config DEBUG_UART_VIRT default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1 default 0xf8ffee00 if DEBUG_AT91_SAM9263_DBGU default 0xf8fff200 if DEBUG_AT91_RM9200_DBGU + default 0xf9e09000 if DEBUG_AM33XXUART1 + default 0xfa020000 if DEBUG_OMAP4UART3 || DEBUG_TI81XXUART1 + default 0xfa022000 if DEBUG_TI81XXUART2 + default 0xfa024000 if DEBUG_TI81XXUART3 + default 0xfa06a000 if DEBUG_OMAP2UART1 || DEBUG_OMAP3UART1 || \ + DEBUG_OMAP4UART1 || DEBUG_OMAP5UART1 + default 0xfa06c000 if DEBUG_OMAP2UART2 || DEBUG_OMAP3UART2 || \ + DEBUG_OMAP4UART2 || DEBUG_OMAP5UART2 + default 0xfa06e000 if DEBUG_OMAP2UART3 || DEBUG_OMAP4UART4 default 0xfa71e000 if DEBUG_QCOM_UARTDM default 0xfb002000 if DEBUG_CNS3XXX default 0xfb009000 if DEBUG_REALVIEW_STD_PORT default 0xfb00c000 if DEBUG_AT91_SAMA5D4_USART3 + default 0xfb020000 if DEBUG_OMAP3UART3 + default 0xfb042000 if DEBUG_OMAP3UART4 default 0xfb10c000 if DEBUG_REALVIEW_PB1176_PORT default 0xfc705000 if DEBUG_ZTE_ZX default 0xfcfe8600 if DEBUG_BCM63XX_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 47d3a1ab08d2..36ae4454554c 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -44,10 +44,12 @@ endif ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) KBUILD_CPPFLAGS += -mbig-endian +CHECKFLAGS += -D__ARMEB__ AS += -EB LD += -EB else KBUILD_CPPFLAGS += -mlittle-endian +CHECKFLAGS += -D__ARMEL__ AS += -EL LD += -EL endif @@ -131,7 +133,7 @@ endif KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float -CHECKFLAGS += -D__arm__ +CHECKFLAGS += -D__arm__ -m32 #Default value head-y := arch/arm/kernel/head$(MMUEXT).o diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile index 5e4acd253b30..83e1a076a5d6 100644 --- a/arch/arm/boot/bootp/Makefile +++ b/arch/arm/boot/bootp/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/arm/boot/bootp/Makefile # diff --git a/arch/arm/boot/bootp/initrd.S b/arch/arm/boot/bootp/initrd.S index d81ea183785c..dd3d04971c42 100644 --- a/arch/arm/boot/bootp/initrd.S +++ b/arch/arm/boot/bootp/initrd.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .type initrd_start,#object .globl initrd_start initrd_start: diff --git a/arch/arm/boot/bootp/kernel.S b/arch/arm/boot/bootp/kernel.S index b87a25c7ef88..dc6236c173d2 100644 --- a/arch/arm/boot/bootp/kernel.S +++ b/arch/arm/boot/bootp/kernel.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .globl kernel_start kernel_start: .incbin "arch/arm/boot/zImage" diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index d50430c40045..a5889238fc9f 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/arm/boot/compressed/Makefile # diff --git a/arch/arm/boot/compressed/atags_to_fdt.c b/arch/arm/boot/compressed/atags_to_fdt.c index 9448aa0c6686..41fa7316c52b 100644 --- a/arch/arm/boot/compressed/atags_to_fdt.c +++ b/arch/arm/boot/compressed/atags_to_fdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm/boot/compressed/big-endian.S b/arch/arm/boot/compressed/big-endian.S index 25ab26f1c6f0..88e2a88d324b 100644 --- a/arch/arm/boot/compressed/big-endian.S +++ b/arch/arm/boot/compressed/big-endian.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/arm/boot/compressed/big-endian.S * diff --git a/arch/arm/boot/compressed/debug.S b/arch/arm/boot/compressed/debug.S index 5392ee63338f..6bf2917a4621 100644 --- a/arch/arm/boot/compressed/debug.S +++ b/arch/arm/boot/compressed/debug.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include @@ -23,7 +24,11 @@ ENTRY(putc) strb r0, [r1] mov r0, #0x03 @ SYS_WRITEC ARM( svc #0x123456 ) +#ifdef CONFIG_CPU_V7M + THUMB( bkpt #0xab ) +#else THUMB( svc #0xab ) +#endif mov pc, lr .align 2 1: .word _GLOBAL_OFFSET_TABLE_ - . diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index f3a4bedd1afc..a2ac3fe7dbf8 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define _LINUX_STRING_H_ #include /* for inline */ diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S index a17ca8d78656..c94a88ae834d 100644 --- a/arch/arm/boot/compressed/efi-header.S +++ b/arch/arm/boot/compressed/efi-header.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2015 Linaro Ltd + * Copyright (C) 2013-2017 Linaro Ltd * Authors: Roy Franz * Ard Biesheuvel * @@ -8,6 +8,9 @@ * published by the Free Software Foundation. */ +#include +#include + .macro __nop #ifdef CONFIG_EFI_STUB @ This is almost but not quite a NOP, since it does clobber the @@ -15,7 +18,7 @@ @ PE/COFF expects the magic string "MZ" at offset 0, while the @ ARM/Linux boot protocol expects an executable instruction @ there. - .inst 'M' | ('Z' << 8) | (0x1310 << 16) @ tstne r0, #0x4d000 + .inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000 #else AR_CLASS( mov r0, r0 ) M_CLASS( nop.w ) @@ -34,96 +37,97 @@ @ The only 2 fields of the MSDOS header that are used are this @ PE/COFF offset, and the "MZ" bytes at offset 0x0. @ - .long pe_header - start @ Offset to the PE header. + .long pe_header - start @ Offset to the PE header. pe_header: - .ascii "PE\0\0" + .long PE_MAGIC coff_header: - .short 0x01c2 @ ARM or Thumb - .short 2 @ nr_sections - .long 0 @ TimeDateStamp - .long 0 @ PointerToSymbolTable - .long 1 @ NumberOfSymbols - .short section_table - optional_header - @ SizeOfOptionalHeader - .short 0x306 @ Characteristics. - @ IMAGE_FILE_32BIT_MACHINE | - @ IMAGE_FILE_DEBUG_STRIPPED | - @ IMAGE_FILE_EXECUTABLE_IMAGE | - @ IMAGE_FILE_LINE_NUMS_STRIPPED + .short IMAGE_FILE_MACHINE_THUMB @ Machine + .short section_count @ NumberOfSections + .long 0 @ TimeDateStamp + .long 0 @ PointerToSymbolTable + .long 0 @ NumberOfSymbols + .short section_table - optional_header @ SizeOfOptionalHeader + .short IMAGE_FILE_32BIT_MACHINE | \ + IMAGE_FILE_DEBUG_STRIPPED | \ + IMAGE_FILE_EXECUTABLE_IMAGE | \ + IMAGE_FILE_LINE_NUMS_STRIPPED @ Characteristics + +#define __pecoff_code_size (__pecoff_data_start - __efi_start) optional_header: - .short 0x10b @ PE32 format - .byte 0x02 @ MajorLinkerVersion - .byte 0x14 @ MinorLinkerVersion - .long _end - __efi_start @ SizeOfCode - .long 0 @ SizeOfInitializedData - .long 0 @ SizeOfUninitializedData - .long efi_stub_entry - start @ AddressOfEntryPoint - .long start_offset @ BaseOfCode - .long 0 @ data + .short PE_OPT_MAGIC_PE32 @ PE32 format + .byte 0x02 @ MajorLinkerVersion + .byte 0x14 @ MinorLinkerVersion + .long __pecoff_code_size @ SizeOfCode + .long __pecoff_data_size @ SizeOfInitializedData + .long 0 @ SizeOfUninitializedData + .long efi_stub_entry - start @ AddressOfEntryPoint + .long start_offset @ BaseOfCode + .long __pecoff_data_start - start @ BaseOfData extra_header_fields: - .long 0 @ ImageBase - .long 0x200 @ SectionAlignment - .long 0x200 @ FileAlignment - .short 0 @ MajorOperatingSystemVersion - .short 0 @ MinorOperatingSystemVersion - .short 0 @ MajorImageVersion - .short 0 @ MinorImageVersion - .short 0 @ MajorSubsystemVersion - .short 0 @ MinorSubsystemVersion - .long 0 @ Win32VersionValue + .long 0 @ ImageBase + .long SZ_4K @ SectionAlignment + .long SZ_512 @ FileAlignment + .short 0 @ MajorOsVersion + .short 0 @ MinorOsVersion + .short 0 @ MajorImageVersion + .short 0 @ MinorImageVersion + .short 0 @ MajorSubsystemVersion + .short 0 @ MinorSubsystemVersion + .long 0 @ Win32VersionValue - .long _end - start @ SizeOfImage - .long start_offset @ SizeOfHeaders - .long 0 @ CheckSum - .short 0xa @ Subsystem (EFI application) - .short 0 @ DllCharacteristics - .long 0 @ SizeOfStackReserve - .long 0 @ SizeOfStackCommit - .long 0 @ SizeOfHeapReserve - .long 0 @ SizeOfHeapCommit - .long 0 @ LoaderFlags - .long 0x6 @ NumberOfRvaAndSizes + .long __pecoff_end - start @ SizeOfImage + .long start_offset @ SizeOfHeaders + .long 0 @ CheckSum + .short IMAGE_SUBSYSTEM_EFI_APPLICATION @ Subsystem + .short 0 @ DllCharacteristics + .long 0 @ SizeOfStackReserve + .long 0 @ SizeOfStackCommit + .long 0 @ SizeOfHeapReserve + .long 0 @ SizeOfHeapCommit + .long 0 @ LoaderFlags + .long (section_table - .) / 8 @ NumberOfRvaAndSizes - .quad 0 @ ExportTable - .quad 0 @ ImportTable - .quad 0 @ ResourceTable - .quad 0 @ ExceptionTable - .quad 0 @ CertificationTable - .quad 0 @ BaseRelocationTable + .quad 0 @ ExportTable + .quad 0 @ ImportTable + .quad 0 @ ResourceTable + .quad 0 @ ExceptionTable + .quad 0 @ CertificationTable + .quad 0 @ BaseRelocationTable section_table: - @ - @ The EFI application loader requires a relocation section - @ because EFI applications must be relocatable. This is a - @ dummy section as far as we are concerned. - @ - .ascii ".reloc\0\0" - .long 0 @ VirtualSize - .long 0 @ VirtualAddress - .long 0 @ SizeOfRawData - .long 0 @ PointerToRawData - .long 0 @ PointerToRelocations - .long 0 @ PointerToLineNumbers - .short 0 @ NumberOfRelocations - .short 0 @ NumberOfLineNumbers - .long 0x42100040 @ Characteristics - .ascii ".text\0\0\0" - .long _end - __efi_start @ VirtualSize - .long __efi_start @ VirtualAddress - .long _edata - __efi_start @ SizeOfRawData - .long __efi_start @ PointerToRawData - .long 0 @ PointerToRelocations - .long 0 @ PointerToLineNumbers - .short 0 @ NumberOfRelocations - .short 0 @ NumberOfLineNumbers - .long 0xe0500020 @ Characteristics + .long __pecoff_code_size @ VirtualSize + .long __efi_start @ VirtualAddress + .long __pecoff_code_size @ SizeOfRawData + .long __efi_start @ PointerToRawData + .long 0 @ PointerToRelocations + .long 0 @ PointerToLineNumbers + .short 0 @ NumberOfRelocations + .short 0 @ NumberOfLineNumbers + .long IMAGE_SCN_CNT_CODE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE @ Characteristics - .align 9 + .ascii ".data\0\0\0" + .long __pecoff_data_size @ VirtualSize + .long __pecoff_data_start - start @ VirtualAddress + .long __pecoff_data_rawsize @ SizeOfRawData + .long __pecoff_data_start - start @ PointerToRawData + .long 0 @ PointerToRelocations + .long 0 @ PointerToLineNumbers + .short 0 @ NumberOfRelocations + .short 0 @ NumberOfLineNumbers + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE @ Characteristics + + .set section_count, (. - section_table) / 40 + + .align 12 __efi_start: #endif .endm diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S index 3115e313d9f6..95abdd850fe3 100644 --- a/arch/arm/boot/compressed/head-sa1100.S +++ b/arch/arm/boot/compressed/head-sa1100.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/arm/boot/compressed/head-sa1100.S * diff --git a/arch/arm/boot/compressed/head-sharpsl.S b/arch/arm/boot/compressed/head-sharpsl.S index eb0084ea1ec4..992e784500fa 100644 --- a/arch/arm/boot/compressed/head-sharpsl.S +++ b/arch/arm/boot/compressed/head-sharpsl.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/arm/boot/compressed/head-sharpsl.S * diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index 6ab0599c02dd..20fa44d59f82 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/arm/boot/compressed/head-xscale.S * diff --git a/arch/arm/boot/compressed/libfdt_env.h b/arch/arm/boot/compressed/libfdt_env.h index 17ae0f3efac8..07437816e098 100644 --- a/arch/arm/boot/compressed/libfdt_env.h +++ b/arch/arm/boot/compressed/libfdt_env.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARM_LIBFDT_ENV_H #define _ARM_LIBFDT_ENV_H diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index d4f891f56996..16a8a804e958 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * misc.c * diff --git a/arch/arm/boot/compressed/piggy.S b/arch/arm/boot/compressed/piggy.S index f72088495f43..0284f84dcf38 100644 --- a/arch/arm/boot/compressed/piggy.S +++ b/arch/arm/boot/compressed/piggy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .section .piggydata,#alloc .globl input_data input_data: diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c index 689467448736..309e1bbad75d 100644 --- a/arch/arm/boot/compressed/string.c +++ b/arch/arm/boot/compressed/string.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/boot/compressed/string.c * diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S index 81c493156ce8..7d06aa19c3e6 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.S +++ b/arch/arm/boot/compressed/vmlinux.lds.S @@ -48,13 +48,6 @@ SECTIONS *(.rodata) *(.rodata.*) } - .data : { - /* - * The EFI stub always executes from RAM, and runs strictly before the - * decompressor, so we can make an exception for its r/w data, and keep it - */ - *(.data.efistub) - } .piggydata : { *(.piggydata) } @@ -70,8 +63,37 @@ SECTIONS /* ensure the zImage file size is always a multiple of 64 bits */ /* (without a dummy byte, ld just ignores the empty section) */ .pad : { BYTE(0); . = ALIGN(8); } + +#ifdef CONFIG_EFI_STUB + .data : ALIGN(4096) { + __pecoff_data_start = .; + /* + * The EFI stub always executes from RAM, and runs strictly before the + * decompressor, so we can make an exception for its r/w data, and keep it + */ + *(.data.efistub) + __pecoff_data_end = .; + + /* + * PE/COFF mandates a file size which is a multiple of 512 bytes if the + * section size equals or exceeds 4 KB + */ + . = ALIGN(512); + } + __pecoff_data_rawsize = . - ADDR(.data); +#endif + _edata = .; + /* + * The image_end section appears after any additional loadable sections + * that the linker may decide to insert in the binary image. Having + * this symbol allows further debug in the near future. + */ + .image_end (NOLOAD) : { + _edata_real = .; + } + _magic_sig = ZIMAGE_MAGIC(0x016f2818); _magic_start = ZIMAGE_MAGIC(_start); _magic_end = ZIMAGE_MAGIC(_edata); @@ -84,6 +106,9 @@ SECTIONS . = ALIGN(8); /* the stack must be 64-bit aligned */ .stack : { *(.stack) } + PROVIDE(__pecoff_data_size = ALIGN(512) - ADDR(.data)); + PROVIDE(__pecoff_end = ALIGN(512)); + .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 4b17f35dc9a7..eff87a344566 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ifeq ($(CONFIG_OF),y) dtb-$(CONFIG_ARCH_ALPINE) += \ @@ -46,6 +47,7 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \ at91sam9x35ek.dtb dtb-$(CONFIG_SOC_SAM_V7) += \ at91-kizbox2.dtb \ + at91-sama5d27_som1_ek.dtb \ at91-sama5d2_xplained.dtb \ at91-sama5d3_xplained.dtb \ at91-tse850-3.dtb \ @@ -73,7 +75,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ bcm2835-rpi-a-plus.dtb \ bcm2836-rpi-2-b.dtb \ bcm2837-rpi-3-b.dtb \ - bcm2835-rpi-zero.dtb + bcm2835-rpi-zero.dtb \ + bcm2835-rpi-zero-w.dtb dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm4708-asus-rt-ac56u.dtb \ bcm4708-asus-rt-ac68u.dtb \ @@ -106,7 +109,8 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm953012hr.dtb \ bcm953012k.dtb dtb-$(CONFIG_ARCH_BCM_53573) += \ - bcm47189-tenda-ac9.dtb + bcm47189-tenda-ac9.dtb \ + bcm947189acdbmr.dtb dtb-$(CONFIG_ARCH_BCM_63XX) += \ bcm963138dvt.dtb dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \ @@ -180,6 +184,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \ exynos5440-ssdk5440.dtb \ exynos5800-peach-pi.dtb dtb-$(CONFIG_ARCH_GEMINI) += \ + gemini-dlink-dir-685.dtb \ gemini-nas4220b.dtb \ gemini-rut1xx.dtb \ gemini-sq201.dtb \ @@ -340,6 +345,7 @@ dtb-$(CONFIG_SOC_IMX51) += \ imx51-ts4800.dtb dtb-$(CONFIG_SOC_IMX53) += \ imx53-ard.dtb \ + imx53-cx9020.dtb \ imx53-m53evk.dtb \ imx53-mba53.dtb \ imx53-qsb.dtb \ @@ -391,7 +397,9 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-udoo.dtb \ imx6dl-wandboard.dtb \ imx6dl-wandboard-revb1.dtb \ + imx6q-apalis-eval.dtb \ imx6q-apalis-ixora.dtb \ + imx6q-apalis-ixora-v1.1.dtb \ imx6q-apf6dev.dtb \ imx6q-arm2.dtb \ imx6q-b450v3.dtb \ @@ -466,7 +474,7 @@ dtb-$(CONFIG_SOC_IMX6SX) += \ imx6sx-udoo-neo-full.dtb dtb-$(CONFIG_SOC_IMX6UL) += \ imx6ul-14x14-evk.dtb \ - imx6ul-geam-kit.dtb \ + imx6ul-geam.dtb \ imx6ul-isiot-emmc.dtb \ imx6ul-isiot-nand.dtb \ imx6ul-liteboard.dtb \ @@ -617,6 +625,7 @@ dtb-$(CONFIG_SOC_AM33XX) += \ am335x-evmsk.dtb \ am335x-icev2.dtb \ am335x-lxm.dtb \ + am335x-moxa-uc-8100-me-t.dtb \ am335x-nano.dtb \ am335x-pepper.dtb \ am335x-phycore-rdk.dtb \ @@ -650,6 +659,7 @@ dtb-$(CONFIG_SOC_OMAP5) += \ dtb-$(CONFIG_SOC_DRA7XX) += \ am57xx-beagle-x15.dtb \ am57xx-beagle-x15-revb1.dtb \ + am57xx-beagle-x15-revc.dtb \ am57xx-cl-som-am57x.dtb \ am57xx-sbc-am57x.dtb \ am572x-idk.dtb \ @@ -657,7 +667,8 @@ dtb-$(CONFIG_SOC_DRA7XX) += \ dra7-evm.dtb \ dra72-evm.dtb \ dra72-evm-revc.dtb \ - dra71-evm.dtb + dra71-evm.dtb \ + dra76-evm.dtb dtb-$(CONFIG_ARCH_ORION5X) += \ orion5x-kuroboxpro.dtb \ orion5x-lacie-d2-network.dtb \ @@ -903,6 +914,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-a33-q8-tablet.dtb \ sun8i-a33-sinlinx-sina33.dtb \ sun8i-a83t-allwinner-h8homlet-v2.dtb \ + sun8i-a83t-bananapi-m3.dtb \ sun8i-a83t-cubietruck-plus.dtb \ sun8i-h2-plus-orangepi-zero.dtb \ sun8i-h3-bananapi-m2-plus.dtb \ @@ -918,6 +930,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-h3-orangepi-pc-plus.dtb \ sun8i-h3-orangepi-plus.dtb \ sun8i-h3-orangepi-plus2e.dtb \ + sun8i-r16-bananapi-m2m.dtb \ sun8i-r16-parrot.dtb \ sun8i-v3s-licheepi-zero.dtb \ sun8i-v3s-licheepi-zero-dock.dtb @@ -970,7 +983,6 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-pro4-sanji.dtb \ uniphier-pxs2-gentil.dtb \ uniphier-pxs2-vodka.dtb \ - uniphier-sld3-ref.dtb \ uniphier-sld8-ref.dtb dtb-$(CONFIG_ARCH_VERSATILE) += \ versatile-ab.dtb \ @@ -1049,7 +1061,8 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt6580-evbp1.dtb \ mt6589-aquaris5.dtb \ mt6592-evb.dtb \ - mt7623-evb.dtb \ + mt7623n-rfb-nand.dtb \ + mt7623n-bananapi-bpi-r2.dtb \ mt8127-moose.dtb \ mt8135-evbp1.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index 1d154444dfef..48a15fc641f2 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -319,13 +319,10 @@ ti,pmic-shutdown-controller; charger { - interrupts = <0>, <1>; - interrupt-names = "USB", "AC"; status = "okay"; }; pwrbutton { - interrupts = <2>; status = "okay"; }; diff --git a/arch/arm/boot/dts/am335x-chiliboard.dts b/arch/arm/boot/dts/am335x-chiliboard.dts index d8769799772e..59431b235944 100644 --- a/arch/arm/boot/dts/am335x-chiliboard.dts +++ b/arch/arm/boot/dts/am335x-chiliboard.dts @@ -191,13 +191,10 @@ interrupts = <7>; /* NNMI */ charger { - interrupts = <0>, <1>; - interrupt-names = "USB", "AC"; status = "okay"; }; pwrbutton { - interrupts = <2>; status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 1c37a7c1ea17..ddd897556e03 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -531,6 +531,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <8>; diff --git a/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts b/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts new file mode 100644 index 000000000000..f82233cd18e0 --- /dev/null +++ b/arch/arm/boot/dts/am335x-moxa-uc-8100-me-t.dts @@ -0,0 +1,525 @@ +/* + * Copyright (C) 2017 MOXA Inc. - https://www.moxa.com/ + * + * Author: SZ Lin (林上智) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/dts-v1/; + +#include "am33xx.dtsi" + +/ { + model = "Moxa UC-8100-ME-T"; + compatible = "moxa,uc-8100-me-t", "ti,am33xx"; + + cpus { + cpu@0 { + cpu0-supply = <&vdd1_reg>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; + + vbat: vbat-regulator { + compatible = "regulator-fixed"; + }; + + /* Power supply provides a fixed 3.3V @3A */ + vmmcsd_fixed: vmmcsd-regulator { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + leds { + compatible = "gpio-leds"; + led1 { + label = "uc8100me:CEL1"; + gpios = <&gpio_xten 8 0>; + default-state = "off"; + }; + + led2 { + label = "uc8100me:CEL2"; + gpios = <&gpio_xten 9 0>; + default-state = "off"; + }; + + led3 { + label = "uc8100me:CEL3"; + gpios = <&gpio_xten 10 0>; + default-state = "off"; + }; + + led4 { + label = "uc8100me:DIA1"; + gpios = <&gpio_xten 11 0>; + default-state = "off"; + }; + led5 { + label = "uc8100me:DIA2"; + gpios = <&gpio_xten 12 0>; + default-state = "off"; + }; + led6 { + label = "uc8100me:DIA3"; + gpios = <&gpio_xten 13 0>; + default-state = "off"; + }; + led7 { + label = "uc8100me:SD"; + gpios = <&gpio_xten 14 0>; + default-state = "off"; + }; + led8 { + label = "uc8100me:USB"; + gpios = <&gpio_xten 15 0>; + default-state = "off"; + }; + led9 { + label = "uc8100me:USER"; + gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + buttons: push_button { + compatible = "gpio-keys"; + }; + +}; + +&am33xx_pinmux { + pinctrl-names = "default"; + pinctrl-0 = <&minipcie_pins>; + + minipcie_pins: pinmux_minipcie { + pinctrl-single,pins = < + AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_pclk.gpio2_24 */ + AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_ac_bias_en.gpio2_25 */ + AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | MUX_MODE7) /* lcd_vsync.gpio2_22 Power off PIN*/ + >; + }; + + push_button_pins: pinmux_push_button { + pinctrl-single,pins = < + AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE7) /* mcasp0_ahcklx.gpio3_21 */ + >; + }; + + i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */ + AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */ + >; + }; + + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x968, PIN_INPUT_PULLUP | MUX_MODE3) /* uart0_ctsn.i2c1_sda */ + AM33XX_IOPAD(0x96c, PIN_INPUT_PULLUP | MUX_MODE3) /* uart0_rtsn.i2c1_scl */ + >; + }; + + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ + AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ + >; + }; + + uart1_pins: pinmux_uart1_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x978, PIN_INPUT | MUX_MODE0) /* uart1_ctsn.uart1_ctsn */ + AM33XX_IOPAD(0x97C, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_rtsn.uart1_rtsn */ + AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */ + AM33XX_IOPAD(0x984, PIN_OUTPUT | MUX_MODE0) /* uart1_txd.uart1_txd */ + >; + }; + + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x8d8, PIN_INPUT | MUX_MODE6) /* lcd_data14.uart5_ctsn */ + AM33XX_IOPAD(0x8dc, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* lcd_data15.uart5_rtsn */ + AM33XX_IOPAD(0x8c4, PIN_INPUT_PULLUP | MUX_MODE4) /* lcd_data9.uart5_rxd */ + AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE4) /* lcd_data8.uart5_txd */ + >; + }; + + cpsw_default: cpsw_default { + pinctrl-single,pins = < + /* Slave 1 */ + AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mii1_crs.rmii1_crs_dv */ + AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxerr.rmii1_rxerr */ + AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txen.rmii1_txen */ + AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd1.rmii1_txd1 */ + AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE1) /* mii1_txd0.rmii1_txd0 */ + AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd1.rmii1_rxd1 */ + AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE1) /* mii1_rxd0.rmii1_rxd0 */ + AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mii1_refclk.rmii1_refclk */ + + /* Slave 2 */ + AM33XX_IOPAD(0x870, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_crs_dv */ + AM33XX_IOPAD(0x874, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rxer */ + AM33XX_IOPAD(0x840, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_txen */ + AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td1 */ + AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* rmii2_td0 */ + AM33XX_IOPAD(0x868, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd1 */ + AM33XX_IOPAD(0x86c, PIN_INPUT_PULLDOWN | MUX_MODE3) /* rmii2_rd0 */ + AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE1) /* rmii2_refclk */ + + >; + }; + + davinci_mdio_default: davinci_mdio_default { + pinctrl-single,pins = < + /* MDIO */ + AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */ + AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */ + >; + }; + + mmc0_pins_default: pinmux_mmc0_pins { + pinctrl-single,pins = < + AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3 */ + AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2 */ + AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1 */ + AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0 */ + AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk */ + AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd */ + AM33XX_IOPAD(0x990, PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkx.gpio3_14 */ + AM33XX_IOPAD(0x9a0, PIN_INPUT_PULLUP | MUX_MODE7) /* mcasp0_aclkx.gpio3_18 */ + >; + }; + + mmc2_pins_default: pinmux_mmc2_pins { + pinctrl-single,pins = < + /* eMMC */ + AM33XX_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad12.mmc2_dat0 */ + AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad13.mmc2_dat1 */ + AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad14.mmc2_dat2 */ + AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad15.mmc2_dat3 */ + AM33XX_IOPAD(0x820, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad8.mmc2_dat4 */ + AM33XX_IOPAD(0x824, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad9.mmc2_dat5 */ + AM33XX_IOPAD(0x828, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad10.mmc2_dat6 */ + AM33XX_IOPAD(0x82c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad11.mmc2_dat7 */ + AM33XX_IOPAD(0x888, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_csn3.mmc2_cmd */ + AM33XX_IOPAD(0x88c, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_clk.mmc2_clk */ + >; + }; + + spi0_pins: pinmux_spi0 { + pinctrl-single,pins = < + AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */ + AM33XX_IOPAD(0x95C, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */ + AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */ + AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */ + >; + }; + +}; + +&uart0 { + /* Console */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; +}; + +&uart1 { + /* UART 1 setting */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; +}; + +&uart5 { + /* UART 2 setting */ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins>; + + status = "okay"; + clock-frequency = <400000>; + + tpm: tpm@20 { + compatible = "infineon,slb9645tt"; + reg = <0x20>; + }; + + tps: tps@2d { + compatible = "ti,tps65910"; + reg = <0x2d>; + }; + + eeprom: eeprom@50 { + compatible = "atmel,24c16"; + pagesize = <16>; + reg = <0x50>; + }; + + rtc_wdt: rtc_wdt@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + status = "okay"; + clock-frequency = <400000>; + gpio_xten: gpio_xten@27 { + compatible = "nxp,pca9535"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x27>; + }; +}; + +&usb { + status = "okay"; +}; + +&usb_ctrl_mod { + status = "okay"; +}; + +&usb0_phy { + status = "okay"; +}; + +&usb1_phy { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; +}; + +&usb1 { + status = "okay"; + dr_mode = "host"; +}; + +&cppi41dma { + status = "okay"; +}; + +#include "tps65910.dtsi" + +&tps { + vcc1-supply = <&vbat>; + vcc2-supply = <&vbat>; + vcc3-supply = <&vbat>; + vcc4-supply = <&vbat>; + vcc5-supply = <&vbat>; + vcc6-supply = <&vbat>; + vcc7-supply = <&vbat>; + vccio-supply = <&vbat>; + + regulators { + vrtc_reg: regulator@0 { + regulator-always-on; + }; + + vio_reg: regulator@1 { + regulator-always-on; + }; + + vdd1_reg: regulator@2 { + /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */ + regulator-name = "vdd_mpu"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1378000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd2_reg: regulator@3 { + /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */ + regulator-name = "vdd_core"; + regulator-min-microvolt = <912500>; + regulator-max-microvolt = <1150000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd3_reg: regulator@4 { + regulator-always-on; + }; + + vdig1_reg: regulator@5 { + regulator-always-on; + }; + + vdig2_reg: regulator@6 { + regulator-always-on; + }; + + vpll_reg: regulator@7 { + regulator-always-on; + }; + + vdac_reg: regulator@8 { + regulator-always-on; + }; + + vaux1_reg: regulator@9 { + regulator-always-on; + }; + + vaux2_reg: regulator@10 { + regulator-always-on; + }; + + vaux33_reg: regulator@11 { + regulator-always-on; + }; + + vmmc_reg: regulator@12 { + compatible = "regulator-fixed"; + regulator-name = "vmmc_reg"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; +}; + +/* Power */ +&vbat { + regulator-name = "vbat"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +}; + +&mac { + pinctrl-names = "default"; + pinctrl-0 = <&cpsw_default>; + dual_emac = <1>; + status = "okay"; +}; + +&davinci_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&davinci_mdio_default>; + status = "okay"; +}; + +&cpsw_emac0 { + status = "okay"; + phy_id = <&davinci_mdio>, <4>; + phy-mode = "rmii"; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + status = "okay"; + phy_id = <&davinci_mdio>, <5>; + phy-mode = "rmii"; + dual_emac_res_vlan = <2>; +}; + +&phy_sel { + reg= <0x44e10650 0xf5>; + rmii-clock-ext; +}; + +&sham { + status = "okay"; +}; + +&aes { + status = "okay"; +}; + +&gpio0 { + ti,no-reset-on-init; +}; + +&mmc1 { + pinctrl-names = "default"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <4>; + pinctrl-0 = <&mmc0_pins_default>; + cd-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; + wp-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&mmc3 { + dmas = <&edma_xbar 12 0 1 + &edma_xbar 13 0 2>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + vmmc-supply = <&vmmcsd_fixed>; + bus-width = <8>; + pinctrl-0 = <&mmc2_pins_default>; + ti,non-removable; + status = "okay"; +}; + +&buttons { + pinctrl-names = "default"; + pinctrl-0 = <&push_button_pins>; + #address-cells = <1>; + #size-cells = <0>; + + button@0 { + label = "push_button"; + linux,code = <0x100>; + gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; + }; +}; + +/* SPI Busses */ +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + + m25p80@0 { + compatible = "mx25l6405d"; + spi-max-frequency = <40000000>; + + reg = <0>; + spi-cpol; + spi-cpha; + #address-cells = <1>; + #size-cells = <1>; + + /* reg : The partition's offset and size within the mtd bank. */ + partitions@0 { + label = "MLO"; + reg = <0x0 0x80000>; + }; + + partitions@1 { + label = "U-Boot"; + reg = <0x80000 0x100000>; + }; + + partitions@2 { + label = "U-Boot Env"; + reg = <0x180000 0x20000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 7d7ca054c557..e58fab8aec5d 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -36,6 +36,8 @@ phy1 = &usb1_phy; ethernet0 = &cpsw_emac0; ethernet1 = &cpsw_emac1; + spi0 = &spi0; + spi1 = &spi1; }; cpus { diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index 29a538ecd405..afb8eb0a0a16 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -149,6 +149,13 @@ system-clock-frequency = <12000000>; }; }; + + beeper: beeper { + compatible = "gpio-beeper"; + pinctrl-names = "default"; + pinctrl-0 = <&beeper_pins>; + gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; + }; }; &am43xx_pinmux { @@ -510,6 +517,13 @@ AM4372_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ >; }; + + beeper_pins: beeper_pins { + pinctrl-single,pins = < + AM4372_IOPAD(0x9e0, PIN_OUTPUT_PULLUP | MUX_MODE7) /* cam1_field.gpio4_12 */ + >; + }; + }; &uart0 { @@ -842,6 +856,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch16"; ti,elm-id = <&elm>; nand-bus-width = <8>; diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index 54f40f370011..081fa68b6f98 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -388,6 +388,7 @@ pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; + slaves = <1>; }; &davinci_mdio { @@ -402,11 +403,6 @@ phy-mode = "rmii"; }; -&cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; - phy-mode = "rmii"; -}; - &phy_sel { rmii-clock-ext; }; @@ -564,6 +560,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch16"; ti,elm-id = <&elm>; nand-bus-width = <8>; diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts index 7b207835b2d1..debf9464403e 100644 --- a/arch/arm/boot/dts/am571x-idk.dts +++ b/arch/arm/boot/dts/am571x-idk.dts @@ -11,6 +11,7 @@ #include #include #include "am57xx-idk-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" / { model = "TI AM5718 IDK"; @@ -64,13 +65,6 @@ }; }; -&mmc1 { - status = "okay"; - vmmc-supply = <&ldo1_reg>; - bus-width = <4>; - cd-gpios = <&gpio6 27 0>; /* gpio 219 */ -}; - &omap_dwc3_2 { extcon = <&extcon_usb2>; }; @@ -96,3 +90,30 @@ status = "okay"; }; }; + +&pcie1_rc { + status = "okay"; + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; +}; + +&pcie1_ep { + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; +}; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev20 &mmc1_iodelay_ddr50_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>; +}; diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts index 9da6d83ca185..a578fe97ba3b 100644 --- a/arch/arm/boot/dts/am572x-idk.dts +++ b/arch/arm/boot/dts/am572x-idk.dts @@ -12,6 +12,7 @@ #include #include #include "am57xx-idk-common.dtsi" +#include "dra74x-mmc-iodelay.dtsi" / { model = "TI AM5728 IDK"; @@ -67,6 +68,24 @@ }; }; +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20>; +}; + &omap_dwc3_2 { extcon = <&extcon_usb2>; }; @@ -76,19 +95,16 @@ vbus-gpio = <&gpio3 26 GPIO_ACTIVE_HIGH>; }; -&mmc1 { - status = "okay"; - vmmc-supply = <&v3_3d>; - vmmc_aux-supply = <&ldo1_reg>; - bus-width = <4>; - cd-gpios = <&gpio6 27 0>; /* gpio 219 */ -}; - &sn65hvs882 { load-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; }; -&pcie1 { +&pcie1_rc { + status = "okay"; + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; +}; + +&pcie1_ep { gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; }; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi index fdfe5b16b806..49aeecd312b4 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi +++ b/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi @@ -9,6 +9,7 @@ #include "dra74x.dtsi" #include "am57xx-commercial-grade.dtsi" +#include "dra74x-mmc-iodelay.dtsi" #include #include @@ -166,34 +167,6 @@ }; }; -&dra7_pmx_core { - mmc1_pins_default: mmc1_pins_default { - pinctrl-single,pins = < - DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */ - DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ - DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ - DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ - DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ - DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ - DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ - >; - }; - - mmc2_pins_default: mmc2_pins_default { - pinctrl-single,pins = < - DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ - DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ - DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ - DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ - DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ - DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ - DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ - DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ - DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ - DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ - >; - }; -}; &i2c1 { status = "okay"; clock-frequency = <400000>; @@ -570,7 +543,12 @@ }; }; -&pcie1 { +&pcie1_rc { + status = "ok"; + gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; +}; + +&pcie1_ep { gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; }; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts b/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts index 39a92aff0a0d..5a77b334923d 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts @@ -19,8 +19,23 @@ }; &mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev11_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev11_conf>; vmmc-supply = <&vdd_3v3>; - vmmc-aux-supply = <&ldo1_reg>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_3_3v_rev11 &mmc2_iodelay_ddr_3_3v_rev11_conf>; }; /* errata i880 "Ethernet RGMII2 Limited to 10/100 Mbps" */ diff --git a/arch/arm/boot/dts/am57xx-beagle-x15-revc.dts b/arch/arm/boot/dts/am57xx-beagle-x15-revc.dts new file mode 100644 index 000000000000..17c41da3b55f --- /dev/null +++ b/arch/arm/boot/dts/am57xx-beagle-x15-revc.dts @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "am57xx-beagle-x15-common.dtsi" + +/ { + model = "TI AM5728 BeagleBoard-X15 rev C"; +}; + +&tpd12s015 { + gpios = <&gpio7 10 GPIO_ACTIVE_HIGH>, /* gpio7_10, CT CP HPD */ + <&gpio2 30 GPIO_ACTIVE_HIGH>, /* gpio2_30, LS OE */ + <&gpio7 12 GPIO_ACTIVE_HIGH>; /* gpio7_12/sp1_cs2, HPD */ +}; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; + vmmc-supply = <&vdd_3v3>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20>; +}; diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 19a60a11c198..d6689106d2a8 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -20,9 +20,20 @@ }; &mmc1 { + pinctrl-names = "default", "hs"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + vmmc-supply = <&ldo1_reg>; }; +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_3_3v_rev11 &mmc2_iodelay_ddr_3_3v_rev11_conf>; +}; + /* errata i880 "Ethernet RGMII2 Limited to 10/100 Mbps" */ &phy1 { max-speed = <100>; diff --git a/arch/arm/boot/dts/am57xx-commercial-grade.dtsi b/arch/arm/boot/dts/am57xx-commercial-grade.dtsi index c183654464e9..3eed6e09c884 100644 --- a/arch/arm/boot/dts/am57xx-commercial-grade.dtsi +++ b/arch/arm/boot/dts/am57xx-commercial-grade.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 &cpu_alert0 { temperature = <80000>; /* milliCelsius */ }; diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi index c536b2f5389f..97aa8e6a56da 100644 --- a/arch/arm/boot/dts/am57xx-idk-common.dtsi +++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi @@ -399,6 +399,14 @@ dr_mode = "peripheral"; }; +&mmc1 { + status = "okay"; + vmmc-supply = <&v3_3d>; + vqmmc-supply = <&ldo1_reg>; + bus-width = <4>; + cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; /* gpio 219 */ +}; + &mmc2 { status = "okay"; vmmc-supply = <&v3_3d>; diff --git a/arch/arm/boot/dts/am57xx-industrial-grade.dtsi b/arch/arm/boot/dts/am57xx-industrial-grade.dtsi index 70c8c4ba1933..422f953fc8d8 100644 --- a/arch/arm/boot/dts/am57xx-industrial-grade.dtsi +++ b/arch/arm/boot/dts/am57xx-industrial-grade.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 &cpu_alert0 { temperature = <90000>; /* milliCelsius */ }; diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index f9cf1273f35e..b1cf5a26f3c2 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -72,7 +72,7 @@ reg = ; }; - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -100,6 +100,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -117,6 +118,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 50c5e8417802..2cb1bcd30976 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -178,9 +178,9 @@ reg = <0x8000 0x1000>; cache-unified; cache-level = <2>; - arm,double-linefill-incr = <1>; + arm,double-linefill-incr = <0>; arm,double-linefill-wrap = <0>; - arm,double-linefill = <1>; + arm,double-linefill = <0>; prefetch-data = <1>; }; @@ -582,7 +582,7 @@ }; }; - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -610,6 +610,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -627,6 +628,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/armada-380.dtsi b/arch/arm/boot/dts/armada-380.dtsi index e392f6036f39..132596fd0860 100644 --- a/arch/arm/boot/dts/armada-380.dtsi +++ b/arch/arm/boot/dts/armada-380.dtsi @@ -71,7 +71,7 @@ }; }; - pcie-controller { + pcie { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -104,6 +104,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -122,6 +123,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <1>; @@ -140,6 +142,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <2>; diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts index db5b9f6b615d..25d2d720dc0e 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -209,7 +209,7 @@ status = "okay"; }; - pcie-controller { + pcie { status = "okay"; /* diff --git a/arch/arm/boot/dts/armada-385-turris-omnia.dts b/arch/arm/boot/dts/armada-385-turris-omnia.dts index be16ce39fb3d..06831e1e3f80 100644 --- a/arch/arm/boot/dts/armada-385-turris-omnia.dts +++ b/arch/arm/boot/dts/armada-385-turris-omnia.dts @@ -96,7 +96,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; pcie@1,0 { diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi index 7fcc4c4885cf..74863aff01c6 100644 --- a/arch/arm/boot/dts/armada-385.dtsi +++ b/arch/arm/boot/dts/armada-385.dtsi @@ -70,7 +70,7 @@ }; soc { - pciec: pcie-controller { + pciec: pcie { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -109,6 +109,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -127,6 +128,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <1>; @@ -145,6 +147,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <2>; @@ -166,6 +169,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <3>; diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts index 0d5f1f062275..ee7b0089eff0 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dts +++ b/arch/arm/boot/dts/armada-388-clearfog.dts @@ -62,7 +62,7 @@ }; }; - pcie-controller { + pcie { pcie@3,0 { /* Port 2, Lane 0. CON2, nearest CPU. */ reset-gpios = <&expander0 2 GPIO_ACTIVE_LOW>; diff --git a/arch/arm/boot/dts/armada-388-clearfog.dtsi b/arch/arm/boot/dts/armada-388-clearfog.dtsi index 0f5938bede53..68acfc968706 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dtsi +++ b/arch/arm/boot/dts/armada-388-clearfog.dtsi @@ -104,7 +104,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* * The two PCIe units are accessible through diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts index 1ac923826445..a4ec1fa37529 100644 --- a/arch/arm/boot/dts/armada-388-db.dts +++ b/arch/arm/boot/dts/armada-388-db.dts @@ -172,7 +172,7 @@ status = "okay"; }; - pcie-controller { + pcie { status = "okay"; /* * The two PCIe units are accessible through diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index 563901e0ec07..f503955dbd3b 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -240,7 +240,7 @@ status = "okay"; }; - pcie-controller { + pcie { status = "okay"; /* * One PCIe units is accessible through diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts index af82f275eac2..9cc3ca0376b9 100644 --- a/arch/arm/boot/dts/armada-388-rd.dts +++ b/arch/arm/boot/dts/armada-388-rd.dts @@ -117,7 +117,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* * One PCIe units is accessible through diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index af31f5d6c0e5..00ff549d4e39 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -143,9 +143,9 @@ reg = <0x8000 0x1000>; cache-unified; cache-level = <2>; - arm,double-linefill-incr = <1>; + arm,double-linefill-incr = <0>; arm,double-linefill-wrap = <0>; - arm,double-linefill = <1>; + arm,double-linefill = <0>; prefetch-data = <1>; }; @@ -154,6 +154,13 @@ reg = <0xc000 0x58>; }; + timer@c200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0xc200 0x20>; + interrupts = ; + clocks = <&coreclk 2>; + }; + timer@c600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xc600 0x20>; @@ -171,7 +178,7 @@ }; i2c0: i2c@11000 { - compatible = "marvell,mv64xxx-i2c"; + compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c"; reg = <0x11000 0x20>; #address-cells = <1>; #size-cells = <0>; @@ -182,7 +189,7 @@ }; i2c1: i2c@11100 { - compatible = "marvell,mv64xxx-i2c"; + compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c"; reg = <0x11100 0x20>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/armada-390-db.dts b/arch/arm/boot/dts/armada-390-db.dts index 2afed2ce4741..c718a5242595 100644 --- a/arch/arm/boot/dts/armada-390-db.dts +++ b/arch/arm/boot/dts/armada-390-db.dts @@ -123,7 +123,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* CON30 */ diff --git a/arch/arm/boot/dts/armada-395-gp.dts b/arch/arm/boot/dts/armada-395-gp.dts index 2cdbba804c1e..ef491b524fd6 100644 --- a/arch/arm/boot/dts/armada-395-gp.dts +++ b/arch/arm/boot/dts/armada-395-gp.dts @@ -139,7 +139,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; /* diff --git a/arch/arm/boot/dts/armada-398-db.dts b/arch/arm/boot/dts/armada-398-db.dts index e8604281c3c9..f0e0379f7619 100644 --- a/arch/arm/boot/dts/armada-398-db.dts +++ b/arch/arm/boot/dts/armada-398-db.dts @@ -118,7 +118,7 @@ }; }; - pcie-controller { + pcie { status = "okay"; pcie@1,0 { diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi index 60fbfd5907c7..5218bd2a248d 100644 --- a/arch/arm/boot/dts/armada-39x.dtsi +++ b/arch/arm/boot/dts/armada-39x.dtsi @@ -111,9 +111,9 @@ reg = <0x8000 0x1000>; cache-unified; cache-level = <2>; - arm,double-linefill-incr = <1>; + arm,double-linefill-incr = <0>; arm,double-linefill-wrap = <0>; - arm,double-linefill = <1>; + arm,double-linefill = <0>; prefetch-data = <1>; }; @@ -442,7 +442,7 @@ }; }; - pcie-controller { + pcie { compatible = "marvell,armada-370-pcie"; status = "disabled"; device_type = "pci"; @@ -481,6 +481,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <0>; @@ -499,6 +500,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <1>; @@ -517,6 +519,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <2>; @@ -538,6 +541,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; marvell,pcie-port = <3>; diff --git a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi index be22ec5236ac..bdd4c7a45fbf 100644 --- a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi +++ b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi @@ -91,7 +91,7 @@ /* * 98DX3236 has 1 x1 PCIe unit Gen2.0 */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -116,6 +116,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts index a33974254d8c..065282c21789 100644 --- a/arch/arm/boot/dts/armada-xp-db.dts +++ b/arch/arm/boot/dts/armada-xp-db.dts @@ -242,7 +242,7 @@ /* Port 2, Lane 0 */ status = "okay"; }; - pcie@10,0 { + pcie@a,0 { /* Port 3, Lane 0 */ status = "okay"; }; diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index d62bf7bea1df..ac9eab8ac186 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts @@ -227,7 +227,7 @@ /* Port 2, Lane 0 */ status = "okay"; }; - pcie@10,0 { + pcie@a,0 { /* Port 3, Lane 0 */ status = "okay"; }; diff --git a/arch/arm/boot/dts/armada-xp-mv78230.dtsi b/arch/arm/boot/dts/armada-xp-mv78230.dtsi index 9f25814077f2..129738f7973d 100644 --- a/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -86,7 +86,7 @@ * configured as x4 or quad x1 lanes. One unit is * x1 only. */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -123,6 +123,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -140,6 +141,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -157,6 +159,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -174,6 +177,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -191,6 +195,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; diff --git a/arch/arm/boot/dts/armada-xp-mv78260.dtsi b/arch/arm/boot/dts/armada-xp-mv78260.dtsi index 2bfe07aebf1a..e58d597e37b9 100644 --- a/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -87,7 +87,7 @@ * configured as x4 or quad x1 lanes. One unit is * x4 only. */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -138,6 +138,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -155,6 +156,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -172,6 +174,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -189,6 +192,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -206,6 +210,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; @@ -223,6 +228,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0 0x81000000 0 0 0x81000000 0x6 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 63>; marvell,pcie-port = <1>; @@ -240,6 +246,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0 0x81000000 0 0 0x81000000 0x7 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 64>; marvell,pcie-port = <1>; @@ -257,6 +264,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0 0x81000000 0 0 0x81000000 0x8 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 65>; marvell,pcie-port = <1>; @@ -274,6 +282,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 0x81000000 0 0 0x81000000 0x9 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 99>; marvell,pcie-port = <2>; diff --git a/arch/arm/boot/dts/armada-xp-mv78460.dtsi b/arch/arm/boot/dts/armada-xp-mv78460.dtsi index 6c33935f7074..a5c961cee7de 100644 --- a/arch/arm/boot/dts/armada-xp-mv78460.dtsi +++ b/arch/arm/boot/dts/armada-xp-mv78460.dtsi @@ -104,7 +104,7 @@ * configured as x4 or quad x1 lanes. Two units are * x4/x1. */ - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,armada-xp-pcie"; status = "disabled"; device_type = "pci"; @@ -159,6 +159,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 58>; marvell,pcie-port = <0>; @@ -176,6 +177,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 59>; marvell,pcie-port = <0>; @@ -193,6 +195,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0 0x81000000 0 0 0x81000000 0x3 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 60>; marvell,pcie-port = <0>; @@ -210,6 +213,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0 0x81000000 0 0 0x81000000 0x4 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 61>; marvell,pcie-port = <0>; @@ -227,6 +231,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0 0x81000000 0 0 0x81000000 0x5 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 62>; marvell,pcie-port = <1>; @@ -244,6 +249,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0 0x81000000 0 0 0x81000000 0x6 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 63>; marvell,pcie-port = <1>; @@ -261,6 +267,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0 0x81000000 0 0 0x81000000 0x7 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 64>; marvell,pcie-port = <1>; @@ -278,6 +285,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0 0x81000000 0 0 0x81000000 0x8 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 65>; marvell,pcie-port = <1>; @@ -295,6 +303,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0 0x81000000 0 0 0x81000000 0x9 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 99>; marvell,pcie-port = <2>; @@ -303,7 +312,7 @@ status = "disabled"; }; - pcie10: pcie@10,0 { + pcie10: pcie@a,0 { device_type = "pci"; assigned-addresses = <0x82005000 0 0x82000 0 0x2000>; reg = <0x5000 0 0 0 0>; @@ -312,6 +321,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0 0x81000000 0 0 0x81000000 0xa 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &mpic 103>; marvell,pcie-port = <3>; diff --git a/arch/arm/boot/dts/armv7-m.dtsi b/arch/arm/boot/dts/armv7-m.dtsi index ba332e399be4..26f5443d85e1 100644 --- a/arch/arm/boot/dts/armv7-m.dtsi +++ b/arch/arm/boot/dts/armv7-m.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { nvic: interrupt-controller@e000e100 { compatible = "arm,armv7m-nvic"; diff --git a/arch/arm/boot/dts/aspeed-ast2500-evb.dts b/arch/arm/boot/dts/aspeed-ast2500-evb.dts index 7c90dac99822..f53e89d63477 100644 --- a/arch/arm/boot/dts/aspeed-ast2500-evb.dts +++ b/arch/arm/boot/dts/aspeed-ast2500-evb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "aspeed-g5.dtsi" diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts index 112551766275..e1b523bd5b8b 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-palmetto.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "aspeed-g4.dtsi" diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts index 1190fec1b5d0..6dd77cba191c 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-romulus.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "aspeed-g5.dtsi" diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi index 8a04c7e2d818..fcc5efbd0879 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "skeleton.dtsi" / { @@ -26,7 +27,7 @@ fmc: flash-controller@1e620000 { reg = < 0x1e620000 0x94 - 0x20000000 0x02000000 >; + 0x20000000 0x10000000 >; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2400-fmc"; @@ -41,7 +42,7 @@ spi: flash-controller@1e630000 { reg = < 0x1e630000 0x18 - 0x30000000 0x02000000 >; + 0x30000000 0x10000000 >; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2400-spi"; diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi index 9cffe347b828..eab8f549a6fe 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "skeleton.dtsi" / { diff --git a/arch/arm/boot/dts/at91-ariettag25.dts b/arch/arm/boot/dts/at91-ariettag25.dts index c514502081d2..21c5b56c92e0 100644 --- a/arch/arm/boot/dts/at91-ariettag25.dts +++ b/arch/arm/boot/dts/at91-ariettag25.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree file for Arietta G25 * This device tree is minimal, to activate more peripherals, see: diff --git a/arch/arm/boot/dts/at91-sama5d27_som1.dtsi b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi new file mode 100644 index 000000000000..cf0087b4c9e1 --- /dev/null +++ b/arch/arm/boot/dts/at91-sama5d27_som1.dtsi @@ -0,0 +1,102 @@ +/* + * at91-sama5d27_som1.dtsi - Device Tree file for SAMA5D27 SoM1 board + * + * Copyright (c) 2017, Microchip Technology Inc. + * 2017 Cristian Birsan + * 2017 Claudiu Beznea + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "sama5d2.dtsi" +#include "sama5d2-pinfunc.h" + +/ { + model = "Atmel SAMA5D27 SoM1"; + compatible = "atmel,sama5d27-som1", "atmel,sama5d27", "atmel,sama5d2", "atmel,sama5"; + + clocks { + slow_xtal { + clock-frequency = <32768>; + }; + + main_xtal { + clock-frequency = <24000000>; + }; + }; + + ahb { + apb { + macb0: ethernet@f8008000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_default>; + phy-mode = "rmii"; + + ethernet-phy@0 { + reg = <0x0>; + interrupt-parent = <&pioA>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_phy_irq>; + }; + }; + + pinctrl@fc038000 { + + pinctrl_macb0_default: macb0_default { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; + + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts new file mode 100644 index 000000000000..60cb084a8d92 --- /dev/null +++ b/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts @@ -0,0 +1,540 @@ +/* + * at91-sama5d27_som1_ek.dts - Device Tree file for SAMA5D27-SOM1-EK board + * + * Copyright (c) 2017, Microchip Technology Inc. + * 2016 Nicolas Ferre + * 2017 Cristian Birsan + * 2017 Claudiu Beznea + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/dts-v1/; +#include "at91-sama5d27_som1.dtsi" +#include +#include + +/ { + model = "Atmel SAMA5D27 SOM1 EK"; + compatible = "atmel,sama5d27-som1-ek", "atmel,sama5d27-som1", "atmel,sama5d27", "atmel,sama5d2", "atmel,sama5"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + ahb { + usb0: gadget@00300000 { + atmel,vbus-gpio = <&pioA PIN_PD20 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; + status = "okay"; + }; + + usb1: ohci@00400000 { + num-ports = <3>; + atmel,vbus-gpio = <0 /* &pioA PIN_PD20 GPIO_ACTIVE_HIGH */ + &pioA PIN_PA27 GPIO_ACTIVE_HIGH + 0 + >; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; + status = "okay"; + }; + + usb2: ehci@00500000 { + status = "okay"; + }; + + sdmmc0: sdio-host@a0000000 { + bus-width = <8>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdmmc0_default>; + status = "okay"; + }; + + sdmmc1: sdio-host@b0000000 { + bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdmmc1_default>; + status = "okay"; + }; + + apb { + isc: isc@f0008000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_isc_base &pinctrl_isc_data_8bit &pinctrl_isc_data_9_10 &pinctrl_isc_data_11_12>; + status = "okay"; + }; + + spi0: spi@f8000000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi0_default>; + status = "okay"; + }; + + macb0: ethernet@f8008000 { + status = "okay"; + }; + + uart1: serial@f8020000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_default>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "okay"; + }; + + uart2: serial@f8024000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus2_uart>; + atmel,use-dma-rx; + atmel,use-dma-tx; + status = "okay"; + }; + + pwm0: pwm@f802c000 { + status = "okay"; + }; + + flx1: flexcom@f8038000 { + atmel,flexcom-mode = ; + status = "disabled"; + + i2c2: i2c@600 { + compatible = "atmel,sama5d2-i2c"; + reg = <0x600 0x200>; + interrupts = <20 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <0>, <0>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&flx1_clk>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus_i2c>; + atmel,fifo-size = <16>; + status = "disabled"; + }; + }; + + shdwc@f8048010 { + atmel,shdwc-debouncer = <976>; + atmel,wakeup-rtc-timer; + + input@0 { + reg = <0>; + atmel,wakeup-type = "low"; + }; + }; + + watchdog@f8048040 { + status = "okay"; + }; + + can0: can@f8054000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can0_default>; + }; + + uart3: serial@fc008000 { + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3_default>; + status = "disabled"; + }; + + uart4: serial@fc00c000 { + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus1_uart>; + status = "okay"; + }; + + flx3: flexcom@fc014000 { + atmel,flexcom-mode = ; + status = "disabled"; + + uart7: serial@200 { + compatible = "atmel,at91sam9260-usart"; + reg = <0x200 0x200>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx3_clk>; + clock-names = "usart"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx3_default>; + atmel,fifo-size = <32>; + status = "disabled"; + }; + + spi2: spi@400 { + compatible = "atmel,at91rm9200-spi"; + reg = <0x400 0x200>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx3_clk>; + clock-names = "spi_clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx3_default>; + atmel,fifo-size = <16>; + status = "disabled"; + }; + }; + + flx4: flexcom@fc018000 { + atmel,flexcom-mode = ; + status = "okay"; + + uart6: serial@200 { + compatible = "atmel,at91sam9260-usart"; + reg = <0x200 0x200>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx4_clk>; + clock-names = "usart"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx4_default>; + atmel,fifo-size = <32>; + status = "disabled"; + }; + + spi3: spi@400 { + compatible = "atmel,at91rm9200-spi"; + reg = <0x400 0x200>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&flx4_clk>; + clock-names = "spi_clk"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mikrobus_spi &pinctrl_mikrobus1_spi_cs &pinctrl_mikrobus2_spi_cs>; + atmel,fifo-size = <16>; + status = "okay"; + }; + + i2c3: i2c@600 { + compatible = "atmel,sama5d2-i2c"; + reg = <0x600 0x200>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <0>, <0>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&flx4_clk>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx4_default>; + atmel,fifo-size = <16>; + status = "disabled"; + }; + }; + + i2c1: i2c@fc028000 { + dmas = <0>, <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_default>; + status = "okay"; + }; + + pinctrl@fc038000 { + + pinctrl_can0_default: can0_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_can1_default: can1_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_flx3_default: flx3_default { + pinmux = , + , + , + , + ; + bias-disable; + }; + + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_isc_base: isc_base { + pinmux = , + , + , + ; + bias-disable; + }; + + pinctrl_isc_data_8bit: isc_data_8bit { + pinmux = , + , + , + , + , + , + , + ; + bias-disable; + }; + + pinctrl_isc_data_9_10: isc_data_9_10 { + pinmux = , + ; + bias-disable; + }; + + pinctrl_isc_data_11_12: isc_data_11_12 { + pinmux = , + ; + bias-disable; + }; + + pinctrl_key_gpio_default: key_gpio_default { + pinmux = ; + bias-pull-up; + }; + + pinctrl_led_gpio_default: led_gpio_default { + pinmux = , + , + ; + bias-pull-up; + }; + + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_data { + pinmux = , + , + , + , + , + , + , + , + ; + bias-pull-up; + }; + + ck_cd_vddsel { + pinmux = , + , + ; + bias-disable; + }; + }; + + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_data { + pinmux = , + , + , + , + ; + bias-pull-up; + }; + + conf-ck_cd { + pinmux = , + ; + bias-disable; + }; + }; + + pinctrl_spi0_default: spi0_default { + pinmux = , + , + , + ; + bias-disable; + }; + + pinctrl_uart1_default: uart1_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_uart3_default: uart3_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_usb_default: usb_default { + pinmux = , + ; + bias-disable; + }; + + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_an: mikrobus1_an { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_an: mikrobus2_an { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_rst: mikrobus1_rst { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_rst: mikrobus2_rst { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_spi_cs: mikrobus1_spi_cs { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_spi_cs: mikrobus2_spi_cs { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus_spi: mikrobus_spi { + pinmux = , + , + ; + bias-disable; + }; + + pinctrl_mikrobus1_pwm: mikrobus1_pwm { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_pwm: mikrobus2_pwm { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_int: mikrobus1_int { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus2_int: mikrobus2_int { + pinmux = ; + bias-disable; + }; + + pinctrl_mikrobus1_uart: mikrobus1_uart { + pinmux = , + ; + bias-disable; + }; + + pinctrl_mikrobus2_uart: mikrobus2_uart { + pinmux = , + ; + bias-disable; + }; + + pinctrl_mikrobus_i2c: mikrobus1_i2c { + pinmux = , + ; + bias-disable; + }; + + pinctrl_flx4_default: flx4_uart_default { + pinmux = , + , + , + , + ; + bias-disable; + }; + }; + + can1: can@fc050000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1_default>; + status = "okay"; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio_default>; + + pb4 { + label = "USER"; + gpios = <&pioA PIN_PA29 GPIO_ACTIVE_LOW>; + linux,code = <0x104>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led_gpio_default>; + status = "okay"; + + red { + label = "red"; + gpios = <&pioA PIN_PA10 GPIO_ACTIVE_HIGH>; + }; + + green { + label = "green"; + gpios = <&pioA PIN_PB1 GPIO_ACTIVE_HIGH>; + }; + + blue { + label = "blue"; + gpios = <&pioA PIN_PA31 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index 2e2c3d1a1fa2..cbc26001247b 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -68,7 +68,7 @@ ahb { usb0: gadget@00300000 { - atmel,vbus-gpio = <&pioA 31 GPIO_ACTIVE_HIGH>; + atmel,vbus-gpio = <&pioA PIN_PA31 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usba_vbus>; status = "okay"; @@ -76,8 +76,8 @@ usb1: ohci@00400000 { num-ports = <3>; - atmel,vbus-gpio = <0 /* &pioA 41 GPIO_ACTIVE_HIGH */ - &pioA 42 GPIO_ACTIVE_HIGH + atmel,vbus-gpio = <0 /* &pioA PIN_PB9 GPIO_ACTIVE_HIGH */ + &pioA PIN_PB10 GPIO_ACTIVE_HIGH 0 >; pinctrl-names = "default"; @@ -127,7 +127,7 @@ ethernet-phy@1 { reg = <0x1>; interrupt-parent = <&pioA>; - interrupts = <73 IRQ_TYPE_LEVEL_LOW>; + interrupts = ; }; }; @@ -160,9 +160,9 @@ compatible = "active-semi,act8945a"; reg = <0x5b>; active-semi,vsel-high; - active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>; - active-semi,lbo-gpios = <&pioA 72 GPIO_ACTIVE_LOW>; - active-semi,irq_gpios = <&pioA 45 GPIO_ACTIVE_LOW>; + active-semi,chglev-gpios = <&pioA PIN_PA12 GPIO_ACTIVE_HIGH>; + active-semi,lbo-gpios = <&pioA PIN_PC8 GPIO_ACTIVE_LOW>; + active-semi,irq_gpios = <&pioA PIN_PB13 GPIO_ACTIVE_LOW>; active-semi,input-voltage-threshold-microvolt = <6600>; active-semi,precondition-timeout = <40>; active-semi,total-timeout = <3>; @@ -309,7 +309,7 @@ vddana-supply = <&vdd_3v3_lp_reg>; vref-supply = <&vdd_3v3_lp_reg>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_adc_default>; + pinctrl-0 = <&pinctrl_adc_default &pinctrl_adtrg_default>; status = "okay"; }; @@ -340,6 +340,20 @@ bias-disable; }; + /* + * The ADTRG pin can work on any edge type. + * In here it's being pulled up, so need to + * connect it to ground to get an edge e.g. + * Trigger can be configured on falling, rise + * or any edge, and the pull-up can be changed + * to pull-down or left floating according to + * needs. + */ + pinctrl_adtrg_default: adtrg_default { + pinmux = ; + bias-pull-up; + }; + pinctrl_charger_chglev: charger_chglev { pinmux = ; bias-disable; @@ -355,6 +369,14 @@ bias-pull-up; }; + pinctrl_classd_default: classd_default { + pinmux = , + , + , + ; + bias-pull-up; + }; + pinctrl_flx0_default: flx0_default { pinmux = , ; @@ -488,6 +510,14 @@ }; + classd: classd@fc048000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_classd_default>; + atmel,pwm-type = "diff"; + atmel,non-overlap-time = <10>; + status = "okay"; + }; + can1: can@fc050000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_can1_default>; @@ -504,7 +534,7 @@ bp1 { label = "PB_USER"; - gpios = <&pioA 41 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB9 GPIO_ACTIVE_LOW>; linux,code = <0x104>; }; }; @@ -517,17 +547,18 @@ red { label = "red"; - gpios = <&pioA 38 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB6 GPIO_ACTIVE_LOW>; }; + green { label = "green"; - gpios = <&pioA 37 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB5 GPIO_ACTIVE_LOW>; }; blue { label = "blue"; - gpios = <&pioA 32 GPIO_ACTIVE_LOW>; + gpios = <&pioA PIN_PB0 GPIO_ACTIVE_LOW>; linux,default-trigger = "heartbeat"; }; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index a4808c4fbc05..64fa3f9a39d3 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -455,6 +455,16 @@ >; /* shared pinctrl settings */ + ac97 { + pinctrl_ac97: ac97-0 { + atmel,pins = + ; /* AC97CK */ + }; + }; + adc0 { pinctrl_adc0_adtrg: adc0_adtrg { atmel,pins = ; @@ -1043,6 +1053,17 @@ status = "disabled"; }; + ac97: sound@fffac000 { + compatible = "atmel,at91sam9263-ac97c"; + reg = <0xfffac000 0x4000>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ac97>; + clocks = <&ac97_clk>; + clock-names = "ac97_clk"; + status = "disabled"; + }; + adc0: adc@fffb0000 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 2522c3308305..94c52c555f83 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -166,6 +166,10 @@ status = "okay"; }; + ac97: sound@fffac000 { + status = "okay"; + }; + adc0: adc@fffb0000 { pinctrl-names = "default"; pinctrl-0 = < diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index bf8c83815753..7c957ea06c66 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -55,6 +55,11 @@ /include/ "bcm-cygnus-clock.dtsi" + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = ; + }; + core { compatible = "simple-bus"; ranges = <0x00000000 0x19000000 0x1000000>; @@ -119,6 +124,21 @@ compatible = "brcm,cygnus-pinmux"; reg = <0x0301d0c8 0x30>, <0x0301d24c 0x2c>; + + spi_0: spi_0 { + function = "spi0"; + groups = "spi0_grp"; + }; + + spi_1: spi_1 { + function = "spi1"; + groups = "spi1_grp"; + }; + + spi_2: spi_2 { + function = "spi2"; + groups = "spi2_grp"; + }; }; mailbox: mailbox@03024024 { @@ -300,6 +320,23 @@ }; }; + dma0: dma@18018000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x18018000 0x1000>; + interrupts = , + , + , + , + , + , + , + , + ; + clocks = <&apb_clk>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + }; + uart0: serial@18020000 { compatible = "snps,dw-apb-uart"; reg = <0x18020000 0x100>; @@ -324,7 +361,7 @@ uart2: serial@18022000 { compatible = "snps,dw-apb-uart"; - reg = <0x18020000 0x100>; + reg = <0x18022000 0x100>; reg-shift = <2>; reg-io-width = <4>; interrupts = ; @@ -344,6 +381,52 @@ status = "disabled"; }; + spi0: spi@18028000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x18028000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + pinctrl-0 = <&spi_0>; + clocks = <&axi81_clk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + spi1: spi@18029000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x18029000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + pinctrl-0 = <&spi_1>; + clocks = <&axi81_clk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + spi2: spi@1802a000 { + compatible = "arm,pl022", "arm,primecell"; + reg = <0x1802a000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + pinctrl-0 = <&spi_2>; + clocks = <&axi81_clk>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + sdhci0: sdhci@18041000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x18041000 0x100>; + interrupts = ; + clocks = <&lcpll0 BCM_CYGNUS_LCPLL0_SDIO_CLK>; + bus-width = <4>; + sdhci,auto-cmd12; + status = "disabled"; + }; + eth0: ethernet@18042000 { compatible = "brcm,amac"; reg = <0x18042000 0x1000>, @@ -353,6 +436,16 @@ status = "disabled"; }; + sdhci1: sdhci@18043000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x18043000 0x100>; + interrupts = ; + clocks = <&lcpll0 BCM_CYGNUS_LCPLL0_SDIO_CLK>; + bus-width = <4>; + sdhci,auto-cmd12; + status = "disabled"; + }; + nand: nand@18046000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x18046000 0x600>, <0xf8105408 0x600>, @@ -366,6 +459,33 @@ brcm,nand-has-wp; }; + ehci0: usb@18048000 { + compatible = "generic-ehci"; + reg = <0x18048000 0x100>; + interrupts = ; + status = "disabled"; + }; + + ohci0: usb@18048800 { + compatible = "generic-ohci"; + reg = <0x18048800 0x100>; + interrupts = ; + status = "disabled"; + }; + + v3d: v3d@180a2000 { + compatible = "brcm,cygnus-v3d"; + reg = <0x180a2000 0x1000>; + clocks = <&mipipll BCM_CYGNUS_MIPIPLL_CH2_V3D>; + clock-names = "v3d_clk"; + interrupts = ; + status = "disabled"; + }; + + vc4: gpu { + compatible = "brcm,cygnus-vc4"; + }; + gpio_asiu: gpio@180a5000 { compatible = "brcm,cygnus-asiu-gpio"; reg = <0x180a5000 0x668>; @@ -444,19 +564,6 @@ status = "disabled"; }; - v3d: v3d@180a2000 { - compatible = "brcm,cygnus-v3d"; - reg = <0x180a2000 0x1000>; - clocks = <&mipipll BCM_CYGNUS_MIPIPLL_CH2_V3D>; - clock-names = "v3d_clk"; - interrupts = ; - status = "disabled"; - }; - - vc4: gpu { - compatible = "brcm,cygnus-vc4"; - }; - adc: adc@180a6000 { compatible = "brcm,iproc-static-adc"; #io-channel-cells = <1>; @@ -467,5 +574,19 @@ interrupts = ; status = "disabled"; }; + + keypad: keypad@180ac000 { + compatible = "brcm,bcm-keypad"; + reg = <0x180ac000 0x14c>; + interrupts = ; + clocks = <&asiu_clks BCM_CYGNUS_ASIU_KEYPAD_CLK>; + clock-names = "peri_clk"; + clock-frequency = <31250>; + pull-up-enabled; + col-debounce-filter-period = <0>; + status-debounce-filter-period = <0>; + row-output-enabled; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi index 7204d1def23d..dff66974feed 100644 --- a/arch/arm/boot/dts/bcm-nsp.dtsi +++ b/arch/arm/boot/dts/bcm-nsp.dtsi @@ -215,6 +215,7 @@ interrupts = ; sdhci,auto-cmd12; clocks = <&lcpll0 BCM_NSP_LCPLL0_SDIO_CLK>; + dma-coherent; status = "disabled"; }; @@ -224,6 +225,7 @@ <0x110000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; + dma-coherent; status = "disabled"; }; @@ -233,6 +235,7 @@ <0x111000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; + dma-coherent; status = "disabled"; }; @@ -242,6 +245,7 @@ <0x112000 0x1000>; reg-names = "amac_base", "idm_base"; interrupts = ; + dma-coherent; status = "disabled"; }; @@ -252,6 +256,7 @@ #mbox-cells = <1>; brcm,rx-status-len = <32>; brcm,use-bcm-hdr; + dma-coherent; }; nand: nand@26000 { @@ -297,6 +302,32 @@ #size-cells = <0>; }; + xhci: usb@29000 { + compatible = "generic-xhci"; + reg = <0x29000 0x1000>; + interrupts = ; + phys = <&usb3_phy>; + phy-names = "usb3-phy"; + dma-coherent; + status = "disabled"; + }; + + ehci0: usb@2a000 { + compatible = "generic-ehci"; + reg = <0x2a000 0x100>; + interrupts = ; + dma-coherent; + status = "disabled"; + }; + + ohci0: usb@2b000 { + compatible = "generic-ohci"; + reg = <0x2b000 0x100>; + interrupts = ; + dma-coherent; + status = "disabled"; + }; + crypto@2f000 { compatible = "brcm,spum-nsp-crypto"; reg = <0x2f000 0x900>; @@ -321,20 +352,6 @@ status = "disabled"; }; - ehci0: usb@2a000 { - compatible = "generic-ehci"; - reg = <0x2a000 0x100>; - interrupts = ; - status = "disabled"; - }; - - ohci0: usb@2b000 { - compatible = "generic-ohci"; - reg = <0x2b000 0x100>; - interrupts = ; - status = "disabled"; - }; - rng: rng@33000 { compatible = "brcm,bcm-nsp-rng"; reg = <0x33000 0x14>; @@ -376,6 +393,7 @@ #size-cells = <0>; interrupts = ; clock-frequency = <100000>; + dma-coherent; status = "disabled"; }; @@ -446,6 +464,7 @@ interrupts = ; #address-cells = <1>; #size-cells = <0>; + dma-coherent; status = "disabled"; sata0: sata-port@0 { @@ -460,6 +479,15 @@ phy-names = "sata-phy"; }; }; + + usb3_phy: usb3-phy@104000 { + compatible = "brcm,ns-bx-usb3-phy"; + reg = <0x104000 0x1000>, + <0x032000 0x1000>; + reg-names = "dmp", "ccb-mii"; + #phy-cells = <0>; + status = "disabled"; + }; }; pcie0: pcie@18012000 { @@ -483,6 +511,7 @@ */ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x8000000>; + dma-coherent; status = "disabled"; msi-parent = <&msi0>; @@ -519,6 +548,7 @@ */ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x8000000>; + dma-coherent; status = "disabled"; msi-parent = <&msi1>; @@ -555,6 +585,7 @@ */ ranges = <0x82000000 0 0x48000000 0x48000000 0 0x8000000>; + dma-coherent; status = "disabled"; msi-parent = <&msi2>; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts index d0704540db6b..f81ae0a10310 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2835.dtsi" #include "bcm2835-rpi.dtsi" @@ -99,3 +100,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts index 46d078e29017..7a960a048204 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-a.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2835.dtsi" #include "bcm2835-rpi.dtsi" @@ -94,3 +95,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts index 432088ebb0a1..0161a8483e39 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2835.dtsi" #include "bcm2835-rpi.dtsi" @@ -101,3 +102,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts index 4133bc2cd9be..4bc70efe43d6 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2835.dtsi" #include "bcm2835-rpi.dtsi" @@ -94,3 +95,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts index 4d56fe3006b0..cca4a75a5651 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2835.dtsi" #include "bcm2835-rpi.dtsi" @@ -89,3 +90,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts new file mode 100644 index 000000000000..b8565fc33eea --- /dev/null +++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2017 Stefan Wahren + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "bcm2835.dtsi" +#include "bcm2835-rpi.dtsi" +#include "bcm283x-rpi-usb-host.dtsi" + +/ { + compatible = "raspberrypi,model-zero-w", "brcm,bcm2835"; + model = "Raspberry Pi Zero W"; + + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; + + leds { + act { + gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + }; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wl_on>; + reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>; + }; +}; + +&gpio { + /* + * This is based on the official GPU firmware DT blob. + * + * Legend: + * "NC" = not connected (no rail from the SoC) + * "FOO" = GPIO line named "FOO" on the schematic + * "FOO_N" = GPIO line named "FOO" on schematic, active low + */ + gpio-line-names = "GPIO0", + "GPIO1", + "SDA1", + "SCL1", + "GPIO_GCLK", + "GPIO5", + "GPIO6", + "SPI_CE1_N", + "SPI_CE0_N", + "SPI_MISO", + "SPI_MOSI", + "SPI_SCLK", + "GPIO12", + "GPIO13", + /* Serial port */ + "TXD0", + "RXD0", + "GPIO16", + "GPIO17", + "GPIO18", + "GPIO19", + "GPIO20", + "GPIO21", + "GPIO22", + "GPIO23", + "GPIO24", + "GPIO25", + "GPIO26", + "GPIO27", + "SDA0", + "SCL0", + "NC", /* GPIO30 */ + "NC", /* GPIO31 */ + "NC", /* GPIO32 */ + "NC", /* GPIO33 */ + "NC", /* GPIO34 */ + "NC", /* GPIO35 */ + "NC", /* GPIO36 */ + "NC", /* GPIO37 */ + "NC", /* GPIO38 */ + "NC", /* GPIO39 */ + "CAM_GPIO1", /* GPIO40 */ + "WL_ON", /* GPIO41 */ + "NC", /* GPIO42 */ + "WIFI_CLK", /* GPIO43 */ + "CAM_GPIO0", /* GPIO44 */ + "BT_ON", /* GPIO45 */ + "HDMI_HPD_N", + "STATUS_LED_N", + /* Used by SD Card */ + "SD_CLK_R", + "SD_CMD_R", + "SD_DATA0_R", + "SD_DATA1_R", + "SD_DATA2_R", + "SD_DATA3_R"; + + pinctrl-0 = <&gpioout &alt0>; + + wl_on: wl-on { + brcm,pins = <41>; + brcm,function = ; + }; +}; + +&hdmi { + hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; +}; + +&sdhci { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>; + mmc-pwrseq = <&wifi_pwrseq>; + non-removable; + status = "okay"; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero.dts b/arch/arm/boot/dts/bcm2835-rpi-zero.dts index 79a20d520931..70362405c595 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-zero.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-zero.dts @@ -103,3 +103,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index e55b362b9d6e..e36c392a2b8f 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -39,7 +39,7 @@ }; alt0: alt0 { - brcm,pins = <4 5 7 8 9 10 11 14 15>; + brcm,pins = <4 5 7 8 9 10 11>; brcm,function = ; }; }; diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi index 659b6e9513b1..0e3d2a5ff208 100644 --- a/arch/arm/boot/dts/bcm2835.dtsi +++ b/arch/arm/boot/dts/bcm2835.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "bcm283x.dtsi" / { diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts index bf19e8cfb9e6..6669355fd655 100644 --- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2836.dtsi" #include "bcm2835-rpi.dtsi" @@ -39,3 +40,9 @@ &hdmi { hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>; }; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio14>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm2836.dtsi b/arch/arm/boot/dts/bcm2836.dtsi index da3deeb42592..61e158003509 100644 --- a/arch/arm/boot/dts/bcm2836.dtsi +++ b/arch/arm/boot/dts/bcm2836.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "bcm283x.dtsi" / { @@ -36,6 +37,7 @@ cpus: cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "brcm,bcm2836-smp"; v7_cpu0: cpu@0 { device_type = "cpu"; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts index c72a27d908b6..eb1a28da57e3 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts @@ -1 +1,57 @@ -#include "arm64/broadcom/bcm2837-rpi-3-b.dts" +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +#include "bcm2837.dtsi" +#include "bcm2835-rpi.dtsi" +#include "bcm283x-rpi-smsc9514.dtsi" +#include "bcm283x-rpi-usb-host.dtsi" + +/ { + compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; + model = "Raspberry Pi 3 Model B"; + + chosen { + /* 8250 auxiliary UART instead of pl011 */ + stdout-path = "serial1:115200n8"; + }; + + memory { + reg = <0 0x40000000>; + }; + + leds { + act { + gpios = <&gpio 47 0>; + }; + }; +}; + +/* uart0 communicates with the BT module */ +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_gpio32 &gpclk2_gpio43>; + status = "okay"; +}; + +/* uart1 is mapped to the pin header */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_gpio14>; + status = "okay"; +}; + +/* SDHCI is used to control the SDIO for wireless */ +&sdhci { + pinctrl-names = "default"; + pinctrl-0 = <&emmc_gpio34>; + status = "okay"; + bus-width = <4>; + non-removable; +}; + +/* SDHOST is used to drive the SD card */ +&sdhost { + pinctrl-names = "default"; + pinctrl-0 = <&sdhost_gpio48>; + status = "okay"; + bus-width = <4>; +}; diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm/boot/dts/bcm2837.dtsi similarity index 96% rename from arch/arm64/boot/dts/broadcom/bcm2837.dtsi rename to arch/arm/boot/dts/bcm2837.dtsi index 2d5de6f0f78d..bc1cca5cf43c 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi +++ b/arch/arm/boot/dts/bcm2837.dtsi @@ -30,6 +30,7 @@ cpus: cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit cpu0: cpu@0 { device_type = "cpu"; diff --git a/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi index 9a0599f711ff..967e081cb9c2 100644 --- a/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi +++ b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { aliases { ethernet0 = ðernet; diff --git a/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi b/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi index e7d217c967a1..e2fd9610e125 100644 --- a/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi +++ b/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 &usb { dr_mode = "otg"; g-rx-fifo-size = <256>; diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index 431dcfc900c0..013431e3d7c3 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -20,8 +20,13 @@ #address-cells = <1>; #size-cells = <1>; + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + chosen { - bootargs = "earlyprintk console=ttyAMA0"; + stdout-path = "serial0:115200n8"; }; thermal-zones { diff --git a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts index 62e1427b3f10..8b64caabaad8 100644 --- a/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts +++ b/arch/arm/boot/dts/bcm4708-buffalo-wzr-1750dhp.dts @@ -52,6 +52,10 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&hc595 0 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>, <&ohci_port2>, + <&ehci_port2>; + linux,default-trigger = "usbport"; }; power0 { diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts index a5647efe4118..d7c34fa72b4b 100644 --- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts +++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts @@ -48,6 +48,9 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; wireless { diff --git a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts index 19ee924d7d53..83a4c60bb431 100644 --- a/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts +++ b/arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts @@ -42,16 +42,22 @@ usb2 { label = "bcm53xx:white:usb2"; gpios = <&chipcommon 3 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port2>, <&ehci_port2>; + linux,default-trigger = "usbport"; }; usb3-white { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 4 GPIO_ACTIVE_HIGH>; + trigger-sources = <&xhci_port1>; + linux,default-trigger = "usbport"; }; usb3-green { label = "bcm53xx:green:usb3"; gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>; + linux,default-trigger = "usbport"; }; wps { diff --git a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts index a854a5174b7f..3ed8de42cb48 100644 --- a/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts +++ b/arch/arm/boot/dts/bcm47081-tplink-archer-c5-v2.dts @@ -36,6 +36,8 @@ usb2-port1 { label = "bcm53xx:green:usb2-port1"; gpios = <&chipcommon 2 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>; + linux,default-trigger = "usbport"; }; power { @@ -67,6 +69,8 @@ usb2-port2 { label = "bcm53xx:green:usb2-port2"; gpios = <&chipcommon 13 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port2>, <&ehci_port2>; + linux,default-trigger = "usbport"; }; }; diff --git a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts index 97aa5d59a1d8..ec4a50e440f6 100644 --- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts +++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts @@ -46,11 +46,16 @@ usb3 { label = "bcm53xx:blue:usb3"; gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; usb2 { label = "bcm53xx:blue:usb2"; gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port2>, <&ehci_port2>; + linux,default-trigger = "usbport"; }; wan-blue { diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts index 51b0641b5f79..7cc7d344fe5b 100644 --- a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts +++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts @@ -71,6 +71,9 @@ usb3-white { label = "bcm53xx:white:usb3"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; 2ghz { diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts index 5f8621d00c50..bc1d1e10d4ac 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3100.dts @@ -59,6 +59,9 @@ usb3 { label = "bcm53xx:green:usb3"; gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + trigger-sources = <&ohci_port1>, <&ehci_port1>, + <&xhci_port1>; + linux,default-trigger = "usbport"; }; status { diff --git a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts index 34417dac1cd0..19e61b5b066c 100644 --- a/arch/arm/boot/dts/bcm47189-tenda-ac9.dts +++ b/arch/arm/boot/dts/bcm47189-tenda-ac9.dts @@ -26,6 +26,8 @@ usb { label = "bcm53xx:blue:usb"; gpios = <&chipcommon 1 GPIO_ACTIVE_HIGH>; + trigger-sources = <&ohci_port1>, <&ehci_port1>; + linux,default-trigger = "usbport"; }; wps { diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index 98647d22b291..045b9bb857f9 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -272,6 +272,19 @@ reg = <0x00021000 0x1000>; interrupts = ; phys = <&usb2_phy>; + + #address-cells = <1>; + #size-cells = <0>; + + ehci_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + + ehci_port2: port@2 { + reg = <2>; + #trigger-source-cells = <0>; + }; }; ohci: ohci@22000 { @@ -280,6 +293,19 @@ compatible = "generic-ohci"; reg = <0x00022000 0x1000>; interrupts = ; + + #address-cells = <1>; + #size-cells = <0>; + + ohci_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; + + ohci_port2: port@2 { + reg = <2>; + #trigger-source-cells = <0>; + }; }; }; @@ -300,6 +326,14 @@ interrupts = ; phys = <&usb3_phy>; phy-names = "usb"; + + #address-cells = <1>; + #size-cells = <0>; + + xhci_port1: port@1 { + reg = <1>; + #trigger-source-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/bcm53573.dtsi b/arch/arm/boot/dts/bcm53573.dtsi index eae623f76401..c698a565b8ae 100644 --- a/arch/arm/boot/dts/bcm53573.dtsi +++ b/arch/arm/boot/dts/bcm53573.dtsi @@ -138,10 +138,12 @@ ehci_port1: port@1 { reg = <1>; + #trigger-source-cells = <0>; }; ehci_port2: port@2 { reg = <2>; + #trigger-source-cells = <0>; }; }; @@ -158,10 +160,12 @@ ohci_port1: port@1 { reg = <1>; + #trigger-source-cells = <0>; }; ohci_port2: port@2 { reg = <2>; + #trigger-source-cells = <0>; }; }; }; diff --git a/arch/arm/boot/dts/bcm63138.dtsi b/arch/arm/boot/dts/bcm63138.dtsi index d0560e8cd6de..43ee992ccdcf 100644 --- a/arch/arm/boot/dts/bcm63138.dtsi +++ b/arch/arm/boot/dts/bcm63138.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Broadcom BCM63138 DSL SoCs Device Tree */ diff --git a/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts b/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts index 0bb8d17e4c2d..8006c69a3fdf 100644 --- a/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts +++ b/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm7445.dtsi" diff --git a/arch/arm/boot/dts/bcm7445.dtsi b/arch/arm/boot/dts/bcm7445.dtsi index 4791321969b3..c859aa6f358c 100644 --- a/arch/arm/boot/dts/bcm7445.dtsi +++ b/arch/arm/boot/dts/bcm7445.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "skeleton.dtsi" diff --git a/arch/arm/boot/dts/bcm911360_entphn.dts b/arch/arm/boot/dts/bcm911360_entphn.dts index 000f5f19215e..53f990defd6a 100644 --- a/arch/arm/boot/dts/bcm911360_entphn.dts +++ b/arch/arm/boot/dts/bcm911360_entphn.dts @@ -39,9 +39,12 @@ model = "Cygnus Enterprise Phone (BCM911360_ENTPHN)"; compatible = "brcm,bcm11360", "brcm,cygnus"; + aliases { + serial0 = &uart3; + }; + chosen { - stdout-path = &uart3; - bootargs = "console=ttyS0,115200"; + stdout-path = "serial0:115200n8"; }; gpio_keys { diff --git a/arch/arm/boot/dts/bcm947189acdbmr.dts b/arch/arm/boot/dts/bcm947189acdbmr.dts new file mode 100644 index 000000000000..ef263412fea5 --- /dev/null +++ b/arch/arm/boot/dts/bcm947189acdbmr.dts @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017 Broadcom + * Author: Florian Fainelli + * + * Licensed under the ISC license. + */ + +/dts-v1/; + +#include "bcm53573.dtsi" + +/ { + compatible = "brcm,bcm947189acdbmr", "brcm,bcm47189", "brcm,bcm53573"; + model = "Broadcom BCM947189ACDBMR"; + + chosen { + bootargs = "console=ttyS0,115200 earlycon"; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + leds { + compatible = "gpio-leds"; + + wps { + label = "bcm53xx:blue:wps"; + gpios = <&chipcommon 10 GPIO_ACTIVE_HIGH>; + }; + + 5ghz { + label = "bcm53xx:blue:5ghz"; + gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>; + }; + + 2ghz { + label = "bcm53xx:blue:2ghz"; + gpios = <&chipcommon 12 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>; + }; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 9 GPIO_ACTIVE_LOW>; + }; + }; + + spi { + compatible = "spi-gpio"; + num-chipselects = <1>; + gpio-sck = <&chipcommon 21 0>; + gpio-miso = <&chipcommon 22 0>; + gpio-mosi = <&chipcommon 23 0>; + cs-gpios = <&chipcommon 24 0>; + #address-cells = <1>; + #size-cells = <0>; + + /* External BCM6802 MoCA chip is connected */ + }; +}; + +&pcie0 { + ranges = <0x00000000 0 0 0 0 0x00100000>; + #address-cells = <3>; + #size-cells = <2>; + + bridge@0,0,0 { + reg = <0x0000 0 0 0 0>; + ranges = <0x00000000 0 0 0 0 0 0 0x00100000>; + #address-cells = <3>; + #size-cells = <2>; + + wifi@0,1,0 { + reg = <0x0000 0 0 0 0>; + ranges = <0x00000000 0 0 0 0x00100000>; + #address-cells = <1>; + #size-cells = <1>; + }; + }; +}; + +&usb2 { + vcc-gpio = <&chipcommon 8 GPIO_ACTIVE_HIGH>; +}; diff --git a/arch/arm/boot/dts/bcm958522er.dts b/arch/arm/boot/dts/bcm958522er.dts index f5c42962c201..f9dd342cc2ae 100644 --- a/arch/arm/boot/dts/bcm958522er.dts +++ b/arch/arm/boot/dts/bcm958522er.dts @@ -170,3 +170,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958525er.dts b/arch/arm/boot/dts/bcm958525er.dts index efcb1f67bdad..374508a9cfbf 100644 --- a/arch/arm/boot/dts/bcm958525er.dts +++ b/arch/arm/boot/dts/bcm958525er.dts @@ -182,3 +182,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958525xmc.dts b/arch/arm/boot/dts/bcm958525xmc.dts index b335ce02e32f..403250c5ad8e 100644 --- a/arch/arm/boot/dts/bcm958525xmc.dts +++ b/arch/arm/boot/dts/bcm958525xmc.dts @@ -202,3 +202,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958622hr.dts b/arch/arm/boot/dts/bcm958622hr.dts index 16ab2d82a14b..fd8b8c689ffe 100644 --- a/arch/arm/boot/dts/bcm958622hr.dts +++ b/arch/arm/boot/dts/bcm958622hr.dts @@ -219,3 +219,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts index 9b921c6aa8f8..3bc50849d013 100644 --- a/arch/arm/boot/dts/bcm958623hr.dts +++ b/arch/arm/boot/dts/bcm958623hr.dts @@ -227,3 +227,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts index 006b08e41a3b..d94d14b3c745 100644 --- a/arch/arm/boot/dts/bcm958625hr.dts +++ b/arch/arm/boot/dts/bcm958625hr.dts @@ -229,3 +229,11 @@ &uart0 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts index 64740f85cf4c..2cf2392483b2 100644 --- a/arch/arm/boot/dts/bcm958625k.dts +++ b/arch/arm/boot/dts/bcm958625k.dts @@ -264,3 +264,11 @@ &uart1 { status = "okay"; }; + +&usb3_phy { + status = "okay"; +}; + +&xhci { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/bcm963138dvt.dts b/arch/arm/boot/dts/bcm963138dvt.dts index 370aa2cfddf2..c61673638fa8 100644 --- a/arch/arm/boot/dts/bcm963138dvt.dts +++ b/arch/arm/boot/dts/bcm963138dvt.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Broadcom BCM63138 Reference Board DTS */ diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts index 67e72bc72e80..c75507922f7d 100644 --- a/arch/arm/boot/dts/da850-evm.dts +++ b/arch/arm/boot/dts/da850-evm.dts @@ -15,6 +15,13 @@ compatible = "ti,da850-evm", "ti,da850"; model = "DA850/AM1808/OMAP-L138 EVM"; + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + ethernet0 = ð0; + }; + soc@1c00000 { pmx_core: pinmux@14120 { status = "okay"; diff --git a/arch/arm/boot/dts/da850-lego-ev3.dts b/arch/arm/boot/dts/da850-lego-ev3.dts index 45983c04a8a7..413dbd5d9f64 100644 --- a/arch/arm/boot/dts/da850-lego-ev3.dts +++ b/arch/arm/boot/dts/da850-lego-ev3.dts @@ -249,6 +249,15 @@ 0x4c 0x00000080 0x000000f0 >; }; + + ev3_lcd_pins: pinmux_lcd { + pinctrl-single,bits = < + /* SIMO, GP2[11], GP2[12], CLK */ + 0x14 0x00188100 0x00ffff00 + /* GP5[0] */ + 0x30 0x80000000 0xf0000000 + >; + }; }; &pinconf { @@ -357,6 +366,21 @@ }; }; +&spi1 { + status = "okay"; + pinctrl-0 = <&ev3_lcd_pins>; + pinctrl-names = "default"; + cs-gpios = <&gpio 44 GPIO_ACTIVE_LOW>; + + display@0{ + compatible = "lego,ev3-lcd"; + reg = <0>; + spi-max-frequency = <10000000>; + a0-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; + }; +}; + &ehrpwm0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/dove-cubox-es.dts b/arch/arm/boot/dts/dove-cubox-es.dts index e28ef056dd17..ad361ec1361d 100644 --- a/arch/arm/boot/dts/dove-cubox-es.dts +++ b/arch/arm/boot/dts/dove-cubox-es.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "dove-cubox.dts" / { diff --git a/arch/arm/boot/dts/dove-cubox.dts b/arch/arm/boot/dts/dove-cubox.dts index af3cb633135f..580e3cbcfbf7 100644 --- a/arch/arm/boot/dts/dove-cubox.dts +++ b/arch/arm/boot/dts/dove-cubox.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "dove.dtsi" diff --git a/arch/arm/boot/dts/dove-d2plug.dts b/arch/arm/boot/dts/dove-d2plug.dts index c11d3636c8e5..273f12ca2512 100644 --- a/arch/arm/boot/dts/dove-d2plug.dts +++ b/arch/arm/boot/dts/dove-d2plug.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "dove.dtsi" diff --git a/arch/arm/boot/dts/dove-d3plug.dts b/arch/arm/boot/dts/dove-d3plug.dts index f5f59bb5a534..826026c28f90 100644 --- a/arch/arm/boot/dts/dove-d3plug.dts +++ b/arch/arm/boot/dts/dove-d3plug.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "dove.dtsi" @@ -88,7 +89,7 @@ &pcie { status = "okay"; /* Fresco Logic USB3.0 xHCI controller */ - pcie-port@0 { + pcie@1 { status = "okay"; reset-gpios = <&gpio0 26 1>; reset-delay-us = <20000>; @@ -96,7 +97,7 @@ pinctrl-names = "default"; }; /* Mini-PCIe slot */ - pcie-port@1 { + pcie@2 { status = "okay"; reset-gpios = <&gpio0 25 1>; }; diff --git a/arch/arm/boot/dts/dove-dove-db.dts b/arch/arm/boot/dts/dove-dove-db.dts index bb725dca3a10..1754a62e014e 100644 --- a/arch/arm/boot/dts/dove-dove-db.dts +++ b/arch/arm/boot/dts/dove-dove-db.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "dove.dtsi" diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi index 698d58cea20d..f4a07bb7c3a2 100644 --- a/arch/arm/boot/dts/dove.dtsi +++ b/arch/arm/boot/dts/dove.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /include/ "skeleton.dtsi" #include @@ -89,7 +90,7 @@ MBUS_ID(0x03, 0x01) 0 0xc8000000 0x0100000 /* CESA SRAM 1M */ MBUS_ID(0x0d, 0x00) 0 0xf0000000 0x0100000>; /* PMU SRAM 1M */ - pcie: pcie-controller { + pcie: pcie { compatible = "marvell,dove-pcie"; status = "disabled"; device_type = "pci"; @@ -106,7 +107,7 @@ 0x82000000 0x2 0x0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 Mem */ 0x81000000 0x2 0x0 MBUS_ID(0x08, 0xe0) 0 1 0>; /* Port 1.0 I/O */ - pcie0: pcie-port@0 { + pcie0: pcie@1 { device_type = "pci"; status = "disabled"; assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; @@ -118,13 +119,14 @@ #size-cells = <2>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 16>; }; - pcie1: pcie-port@1 { + pcie1: pcie@2 { device_type = "pci"; status = "disabled"; assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; @@ -136,6 +138,7 @@ #size-cells = <2>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; diff --git a/arch/arm/boot/dts/dra7-evm-common.dtsi b/arch/arm/boot/dts/dra7-evm-common.dtsi new file mode 100644 index 000000000000..343e95f9a001 --- /dev/null +++ b/arch/arm/boot/dts/dra7-evm-common.dtsi @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +/ { + chosen { + stdout-path = &uart1; + }; + + extcon_usb1: extcon_usb1 { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>; + }; + + sound0: sound0 { + compatible = "simple-audio-card"; + simple-audio-card,name = "DRA7xx-EVM"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line Out", + "Microphone", "Mic Jack", + "Line", "Line In"; + simple-audio-card,routing = + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "MIC3L", "Mic Jack", + "MIC3R", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE1L", "Line In", + "LINE1R", "Line In"; + simple-audio-card,format = "dsp_b"; + simple-audio-card,bitclock-master = <&sound0_master>; + simple-audio-card,frame-master = <&sound0_master>; + simple-audio-card,bitclock-inversion; + + sound0_master: simple-audio-card,cpu { + sound-dai = <&mcasp3>; + system-clock-frequency = <5644800>; + }; + + simple-audio-card,codec { + sound-dai = <&tlv320aic3106>; + clocks = <&atl_clkin2_ck>; + }; + }; + + leds { + compatible = "gpio-leds"; + led0 { + label = "dra7:usr1"; + gpios = <&pcf_lcd 4 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led1 { + label = "dra7:usr2"; + gpios = <&pcf_lcd 5 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led2 { + label = "dra7:usr3"; + gpios = <&pcf_lcd 6 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led3 { + label = "dra7:usr4"; + gpios = <&pcf_lcd 7 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + USER1 { + label = "btnUser1"; + linux,code = ; + gpios = <&pcf_lcd 2 GPIO_ACTIVE_LOW>; + }; + + USER2 { + label = "btnUser2"; + linux,code = ; + gpios = <&pcf_lcd 3 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c3 { + status = "okay"; + clock-frequency = <400000>; +}; + +&mcspi1 { + status = "okay"; +}; + +&mcspi2 { + status = "okay"; +}; + +&uart1 { + status = "okay"; + interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, + <&dra7_pmx_core 0x3e0>; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&qspi { + status = "okay"; + + spi-max-frequency = <76800000>; + m25p80@0 { + compatible = "s25fl256s1"; + spi-max-frequency = <76800000>; + reg = <0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + #address-cells = <1>; + #size-cells = <1>; + + /* MTD partition table. + * The ROM checks the first four physical blocks + * for a valid file to boot and the flash here is + * 64KiB block size. + */ + partition@0 { + label = "QSPI.SPL"; + reg = <0x00000000 0x000010000>; + }; + partition@1 { + label = "QSPI.SPL.backup1"; + reg = <0x00010000 0x00010000>; + }; + partition@2 { + label = "QSPI.SPL.backup2"; + reg = <0x00020000 0x00010000>; + }; + partition@3 { + label = "QSPI.SPL.backup3"; + reg = <0x00030000 0x00010000>; + }; + partition@4 { + label = "QSPI.u-boot"; + reg = <0x00040000 0x00100000>; + }; + partition@5 { + label = "QSPI.u-boot-spl-os"; + reg = <0x00140000 0x00080000>; + }; + partition@6 { + label = "QSPI.u-boot-env"; + reg = <0x001c0000 0x00010000>; + }; + partition@7 { + label = "QSPI.u-boot-env.backup1"; + reg = <0x001d0000 0x0010000>; + }; + partition@8 { + label = "QSPI.kernel"; + reg = <0x001e0000 0x0800000>; + }; + partition@9 { + label = "QSPI.file-system"; + reg = <0x009e0000 0x01620000>; + }; + }; +}; + +&omap_dwc3_1 { + extcon = <&extcon_usb1>; +}; + +&usb1 { + dr_mode = "otg"; + extcon = <&extcon_usb1>; +}; + +&usb2 { + dr_mode = "host"; +}; + +&atl { + assigned-clocks = <&abe_dpll_sys_clk_mux>, + <&atl_gfclk_mux>, + <&dpll_abe_ck>, + <&dpll_abe_m2x2_ck>, + <&atl_clkin2_ck>; + assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>; + assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>; + + status = "okay"; + + atl2 { + bws = ; + aws = ; + }; +}; + +&mcasp3 { + #sound-dai-cells = <0>; + + assigned-clocks = <&mcasp3_ahclkx_mux>; + assigned-clock-parents = <&atl_clkin2_ck>; + + status = "okay"; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 4 serializer */ + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 1 2 0 0 + >; + tx-num-evt = <32>; + rx-num-evt = <32>; +}; + +&mailbox5 { + status = "okay"; + mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + status = "okay"; + }; + mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + status = "okay"; + }; +}; + +&mailbox6 { + status = "okay"; + mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + status = "okay"; + }; + mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { + status = "okay"; + }; +}; diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index f47fc4daf062..aa426dabb6c3 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -8,9 +8,8 @@ /dts-v1/; #include "dra74x.dtsi" -#include -#include -#include +#include "dra7-evm-common.dtsi" +#include "dra74x-mmc-iodelay.dtsi" / { model = "TI DRA742"; @@ -21,8 +20,12 @@ reg = <0x0 0x80000000 0x0 0x60000000>; /* 1536 MB */ }; - chosen { - stdout-path = &uart1; + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + vin-supply = <&smps9_reg>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; }; evm_3v3_sd: fixedregulator-sd { @@ -51,11 +54,6 @@ regulator-max-microvolt = <1800000>; }; - extcon_usb1: extcon_usb1 { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>; - }; - extcon_usb2: extcon_usb2 { compatible = "linux,extcon-usb-gpio"; id-gpio = <&pcf_gpio_21 2 GPIO_ACTIVE_HIGH>; @@ -73,85 +71,6 @@ gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>; }; - sound0: sound0 { - compatible = "simple-audio-card"; - simple-audio-card,name = "DRA7xx-EVM"; - simple-audio-card,widgets = - "Headphone", "Headphone Jack", - "Line", "Line Out", - "Microphone", "Mic Jack", - "Line", "Line In"; - simple-audio-card,routing = - "Headphone Jack", "HPLOUT", - "Headphone Jack", "HPROUT", - "Line Out", "LLOUT", - "Line Out", "RLOUT", - "MIC3L", "Mic Jack", - "MIC3R", "Mic Jack", - "Mic Jack", "Mic Bias", - "LINE1L", "Line In", - "LINE1R", "Line In"; - simple-audio-card,format = "dsp_b"; - simple-audio-card,bitclock-master = <&sound0_master>; - simple-audio-card,frame-master = <&sound0_master>; - simple-audio-card,bitclock-inversion; - - sound0_master: simple-audio-card,cpu { - sound-dai = <&mcasp3>; - system-clock-frequency = <5644800>; - }; - - simple-audio-card,codec { - sound-dai = <&tlv320aic3106>; - clocks = <&atl_clkin2_ck>; - }; - }; - - leds { - compatible = "gpio-leds"; - led0 { - label = "dra7:usr1"; - gpios = <&pcf_lcd 4 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - led1 { - label = "dra7:usr2"; - gpios = <&pcf_lcd 5 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - led2 { - label = "dra7:usr3"; - gpios = <&pcf_lcd 6 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - - led3 { - label = "dra7:usr4"; - gpios = <&pcf_lcd 7 GPIO_ACTIVE_LOW>; - default-state = "off"; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - autorepeat; - - USER1 { - label = "btnUser1"; - linux,code = ; - gpios = <&pcf_lcd 2 GPIO_ACTIVE_LOW>; - }; - - USER2 { - label = "btnUser2"; - linux,code = ; - gpios = <&pcf_lcd 3 GPIO_ACTIVE_LOW>; - }; - }; }; &dra7_pmx_core { @@ -406,137 +325,49 @@ }; }; -&i2c3 { - status = "okay"; - clock-frequency = <400000>; -}; - -&mcspi1 { - status = "okay"; -}; - -&mcspi2 { - status = "okay"; -}; - -&uart1 { - status = "okay"; - interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>, - <&dra7_pmx_core 0x3e0>; -}; - -&uart2 { - status = "okay"; -}; - -&uart3 { - status = "okay"; -}; - &mmc1 { status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&mmc1_pins_default>; vmmc-supply = <&evm_3v3_sd>; - vmmc_aux-supply = <&ldo1_reg>; + vqmmc-supply = <&ldo1_reg>; bus-width = <4>; /* * SDCD signal is not being used here - using the fact that GPIO mode * is always hardwired. */ cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50-rev11", "sdr104-rev11", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev11_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev11_conf>; + pinctrl-7 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>; + pinctrl-8 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; }; &mmc2 { status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&mmc2_pins_default>; - vmmc-supply = <&evm_3v3_sw>; + vmmc-supply = <&evm_1v8_sw>; bus-width = <8>; + pinctrl-names = "default", "hs", "ddr_1_8v-rev11", "ddr_1_8v", "hs200_1_8v-rev11", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_1_8v_rev11 &mmc2_iodelay_ddr_1_8v_rev11_conf>; + pinctrl-3 = <&mmc2_pins_ddr_rev20>; + pinctrl-4 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev11_conf>; + pinctrl-5 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev20_conf>; }; &cpu0 { cpu0-supply = <&smps123_reg>; }; -&qspi { - status = "okay"; - - spi-max-frequency = <76800000>; - m25p80@0 { - compatible = "s25fl256s1"; - spi-max-frequency = <76800000>; - reg = <0>; - spi-tx-bus-width = <1>; - spi-rx-bus-width = <4>; - #address-cells = <1>; - #size-cells = <1>; - - /* MTD partition table. - * The ROM checks the first four physical blocks - * for a valid file to boot and the flash here is - * 64KiB block size. - */ - partition@0 { - label = "QSPI.SPL"; - reg = <0x00000000 0x000010000>; - }; - partition@1 { - label = "QSPI.SPL.backup1"; - reg = <0x00010000 0x00010000>; - }; - partition@2 { - label = "QSPI.SPL.backup2"; - reg = <0x00020000 0x00010000>; - }; - partition@3 { - label = "QSPI.SPL.backup3"; - reg = <0x00030000 0x00010000>; - }; - partition@4 { - label = "QSPI.u-boot"; - reg = <0x00040000 0x00100000>; - }; - partition@5 { - label = "QSPI.u-boot-spl-os"; - reg = <0x00140000 0x00080000>; - }; - partition@6 { - label = "QSPI.u-boot-env"; - reg = <0x001c0000 0x00010000>; - }; - partition@7 { - label = "QSPI.u-boot-env.backup1"; - reg = <0x001d0000 0x0010000>; - }; - partition@8 { - label = "QSPI.kernel"; - reg = <0x001e0000 0x0800000>; - }; - partition@9 { - label = "QSPI.file-system"; - reg = <0x009e0000 0x01620000>; - }; - }; -}; - -&omap_dwc3_1 { - extcon = <&extcon_usb1>; -}; - &omap_dwc3_2 { extcon = <&extcon_usb2>; }; -&usb1 { - dr_mode = "otg"; - extcon = <&extcon_usb1>; -}; - -&usb2 { - dr_mode = "host"; -}; - &elm { status = "okay"; }; @@ -556,6 +387,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <16>; @@ -666,57 +498,6 @@ pinctrl-2 = <&dcan1_pins_default>; }; -&atl { - assigned-clocks = <&abe_dpll_sys_clk_mux>, - <&atl_gfclk_mux>, - <&dpll_abe_ck>, - <&dpll_abe_m2x2_ck>, - <&atl_clkin2_ck>; - assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>; - assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>; - +&pcie1_rc { status = "okay"; - - atl2 { - bws = ; - aws = ; - }; -}; - -&mcasp3 { - #sound-dai-cells = <0>; - - assigned-clocks = <&mcasp3_ahclkx_mux>; - assigned-clock-parents = <&atl_clkin2_ck>; - - status = "okay"; - - op-mode = <0>; /* MCASP_IIS_MODE */ - tdm-slots = <2>; - /* 4 serializer */ - serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ - 1 2 0 0 - >; - tx-num-evt = <32>; - rx-num-evt = <32>; -}; - -&mailbox5 { - status = "okay"; - mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { - status = "okay"; - }; - mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { - status = "okay"; - }; -}; - -&mailbox6 { - status = "okay"; - mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { - status = "okay"; - }; - mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { - status = "okay"; - }; }; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 0f0f6f58bd18..02a136a4661a 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -196,6 +196,7 @@ scm_conf1: scm_conf@1c04 { compatible = "syscon"; reg = <0x1c04 0x0020>; + #syscon-cells = <2>; }; scm_conf_pcie: scm_conf@1c24 { @@ -287,7 +288,11 @@ #address-cells = <1>; ranges = <0x51000000 0x51000000 0x3000 0x0 0x20000000 0x10000000>; - pcie1: pcie@51000000 { + /** + * To enable PCI endpoint mode, disable the pcie1_rc + * node and enable pcie1_ep mode. + */ + pcie1_rc: pcie@51000000 { compatible = "ti,dra7-pcie"; reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>; reg-names = "rc_dbics", "ti_conf", "config"; @@ -309,12 +314,28 @@ <0 0 0 2 &pcie1_intc 2>, <0 0 0 3 &pcie1_intc 3>, <0 0 0 4 &pcie1_intc 4>; + status = "disabled"; pcie1_intc: interrupt-controller { interrupt-controller; #address-cells = <0>; #interrupt-cells = <1>; }; }; + + pcie1_ep: pcie_ep@51000000 { + compatible = "ti,dra7-pcie-ep"; + reg = <0x51000000 0x28>, <0x51002000 0x14c>, <0x51001000 0x28>, <0x1000 0x10000000>; + reg-names = "ep_dbics", "ti_conf", "ep_dbics2", "addr_space"; + interrupts = <0 232 0x4>; + num-lanes = <1>; + num-ib-windows = <4>; + num-ob-windows = <16>; + ti,hwmods = "pcie1"; + phys = <&pcie1_phy>; + phy-names = "pcie-phy0"; + ti,syscon-unaligned-access = <&scm_conf1 0x14 2>; + status = "disabled"; + }; }; axi@1 { @@ -418,6 +439,14 @@ reg = <0x40d00000 0x100>; }; + dra7_iodelay_core: padconf@4844a000 { + compatible = "ti,dra7-iodelay"; + reg = <0x4844a000 0x0d1c>; + #address-cells = <1>; + #size-cells = <0>; + #pinctrl-cells = <2>; + }; + sdma: dma-controller@4a056000 { compatible = "ti,omap4430-sdma"; reg = <0x4a056000 0x1000>; @@ -1037,6 +1066,7 @@ dma-names = "tx", "rx"; status = "disabled"; pbias-supply = <&pbias_mmc_reg>; + max-frequency = <192000000>; }; mmc2: mmc@480b4000 { @@ -1048,6 +1078,7 @@ dmas = <&sdma_xbar 47>, <&sdma_xbar 48>; dma-names = "tx", "rx"; status = "disabled"; + max-frequency = <192000000>; }; mmc3: mmc@480ad000 { @@ -1059,6 +1090,8 @@ dmas = <&sdma_xbar 77>, <&sdma_xbar 78>; dma-names = "tx", "rx"; status = "disabled"; + /* Errata i887 limits max-frequency of MMC3 to 64 MHz */ + max-frequency = <64000000>; }; mmc4: mmc@480d1000 { @@ -1070,6 +1103,7 @@ dmas = <&sdma_xbar 57>, <&sdma_xbar 58>; dma-names = "tx", "rx"; status = "disabled"; + max-frequency = <192000000>; }; mmu0_dsp1: mmu@40d01000 { diff --git a/arch/arm/boot/dts/dra71-evm.dts b/arch/arm/boot/dts/dra71-evm.dts index a6298eb56978..41c9132eb550 100644 --- a/arch/arm/boot/dts/dra71-evm.dts +++ b/arch/arm/boot/dts/dra71-evm.dts @@ -7,6 +7,7 @@ */ #include "dra72-evm-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" #include / { @@ -32,6 +33,16 @@ 3000000 0x1>; }; + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&lp8732_buck0_reg>; + regulator-always-on; + regulator-boot-on; + }; + poweroff: gpio-poweroff { compatible = "gpio-poweroff"; gpios = <&gpio7 30 GPIO_ACTIVE_HIGH>; @@ -162,7 +173,24 @@ }; &mmc1 { - vmmc_aux-supply = <&vpo_sd_1v8_3v3>; + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev20 &mmc1_iodelay_ddr50_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; + vqmmc-supply = <&vpo_sd_1v8_3v3>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>; + pinctrl-3 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev20_conf>; + vmmc-supply = <&evm_1v8_sw>; }; &mac { @@ -191,6 +219,7 @@ ti,tx-internal-delay = ; ti,fifo-depth = ; ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; }; dp83867_1: ethernet-phy@3 { @@ -199,6 +228,7 @@ ti,tx-internal-delay = ; ti,fifo-depth = ; ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; }; }; diff --git a/arch/arm/boot/dts/dra72-evm-common.dtsi b/arch/arm/boot/dts/dra72-evm-common.dtsi index 85780549bc26..2e485a13dfd7 100644 --- a/arch/arm/boot/dts/dra72-evm-common.dtsi +++ b/arch/arm/boot/dts/dra72-evm-common.dtsi @@ -311,6 +311,7 @@ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */ + ti,nand-xfer-type = "prefetch-dma"; ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <16>; @@ -419,8 +420,6 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins_default>; - - vmmc-supply = <&evm_3v3_sw>; bus-width = <8>; ti,non-removable; max-frequency = <192000000>; @@ -564,3 +563,7 @@ status = "okay"; }; }; + +&pcie1_rc { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/dra72-evm-revc.dts b/arch/arm/boot/dts/dra72-evm-revc.dts index 3ecac56bf504..bf588d00728d 100644 --- a/arch/arm/boot/dts/dra72-evm-revc.dts +++ b/arch/arm/boot/dts/dra72-evm-revc.dts @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ #include "dra72-evm-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" #include / { @@ -15,6 +16,16 @@ device_type = "memory"; reg = <0x0 0x80000000 0x0 0x80000000>; /* 2GB */ }; + + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&smps4_reg>; + regulator-always-on; + regulator-boot-on; + }; }; &i2c1 { @@ -70,6 +81,7 @@ ti,min-output-impedance; interrupt-parent = <&gpio6>; interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + ti,dp83867-rxctrl-strap-quirk; }; dp83867_1: ethernet-phy@3 { @@ -80,5 +92,27 @@ ti,min-output-impedance; interrupt-parent = <&gpio6>; interrupts = <16 IRQ_TYPE_EDGE_FALLING>; + ti,dp83867-rxctrl-strap-quirk; }; }; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev20 &mmc1_iodelay_ddr50_conf>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev20 &mmc2_iodelay_ddr_conf>; + pinctrl-3 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev20_conf>; + vmmc-supply = <&evm_1v8_sw>; +}; diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi index e6df676886c0..57bfe5caf5e4 100644 --- a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi +++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi @@ -146,5 +146,5 @@ }; &mmc1 { - vmmc_aux-supply = <&ldo1_reg>; + vqmmc-supply = <&ldo1_reg>; }; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index cd9c4ff12654..c572693b1665 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ #include "dra72-evm-common.dtsi" +#include "dra72x-mmc-iodelay.dtsi" / { model = "TI DRA722"; @@ -13,6 +14,16 @@ device_type = "memory"; reg = <0x0 0x80000000 0x0 0x40000000>; /* 1024 MB */ }; + + evm_1v8_sw: fixedregulator-evm_1v8 { + compatible = "regulator-fixed"; + regulator-name = "evm_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&smps4_reg>; + regulator-always-on; + regulator-boot-on; + }; }; &i2c1 { @@ -43,3 +54,24 @@ phy_id = <&davinci_mdio>, <3>; phy-mode = "rgmii"; }; + +&mmc1 { + pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_hs>; + pinctrl-2 = <&mmc1_pins_sdr12>; + pinctrl-3 = <&mmc1_pins_sdr25>; + pinctrl-4 = <&mmc1_pins_sdr50>; + pinctrl-5 = <&mmc1_pins_ddr50_rev10>; + pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev10_conf>; + vqmmc-supply = <&ldo1_reg>; +}; + +&mmc2 { + pinctrl-names = "default", "hs", "ddr_1_8v", "hs200_1_8v"; + pinctrl-0 = <&mmc2_pins_default>; + pinctrl-1 = <&mmc2_pins_hs>; + pinctrl-2 = <&mmc2_pins_ddr_rev10>; + pinctrl-3 = <&mmc2_pins_hs200 &mmc2_iodelay_hs200_rev10_conf>; + vmmc-supply = <&evm_1v8_sw>; +}; diff --git a/arch/arm/boot/dts/dra72x-mmc-iodelay.dtsi b/arch/arm/boot/dts/dra72x-mmc-iodelay.dtsi new file mode 100644 index 000000000000..088013c6dc6e --- /dev/null +++ b/arch/arm/boot/dts/dra72x-mmc-iodelay.dtsi @@ -0,0 +1,350 @@ +/* + * MMC IOdelay values for TI's DRA72x, DRA71x and AM571x SoCs. + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Rules for modifying this file: + * a) Update of this file should typically correspond to a datamanual revision. + * Datamanual revision that was used should be updated in comment below. + * If there is no update to datamanual, do not update the values. If you + * need to use values different from that recommended by the datamanual + * for your design, then you should consider adding values to the device- + * -tree file for your board directly. + * b) We keep the mode names as close to the datamanual as possible. So + * if the manual calls a mode, DDR50, or DDR or DDR 1.8v or DDR 3.3v, + * we follow that in code too. + * c) If the values change between multiple revisions of silicon, we add + * a revision tag to both the new and old entry. Use 'rev10' for PG 1.0, + * 'rev20' for PG 2.0 and so on. + * d) The node name and node label should be the exact same string. This is + * to curb naming creativity and achieve consistency. + * e) If in future, DRA71x and DRA72x values differ, then add 'dra71_' and + * 'dra72_' tag to entries. Both the new and old entries should gain a tag. + * + * Datamanual Revisions: + * + * AM571x Silicon Revision 2.0: SPRS957D, Revised January 2017 + * AM571x Silicon Revision 1.0: SPRS919M, Revised November 2017 + * DRA71x : SPRS960B, Revised February 2017 + */ + +&dra7_pmx_core { + mmc1_pins_default: mmc1_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr12: mmc1_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_hs: mmc1_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr25: mmc1_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr50: mmc1_pins_sdr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE15 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_ddr50_rev10: mmc1_pins_ddr50_rev10 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_clk.mmc1_clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_cmd.mmc1_cmd */ + DRA7XX_CORE_IOPAD(0x375C, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat0.mmc1_dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat1.mmc1_dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat2.mmc1_dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE14 | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 */ + >; + }; + + mmc1_pins_ddr50_rev20: mmc1_pins_ddr50_rev20 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr104: mmc1_pins_sdr104 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc2_pins_default: mmc2_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs: mmc2_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_rev10: mmc2_pins_ddr_rev10 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + >; + }; + + mmc2_pins_ddr_rev20: mmc2_pins_ddr_rev20 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs200: mmc2_pins_hs200 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; +}; + +&dra7_iodelay_core { + + /* Corresponds to MMC1_MANUAL1 in datamanual */ + mmc1_iodelay_ddr50_conf: mmc1_iodelay_ddr50_conf { + pinctrl-pin-array = < + 0x618 A_DELAY_PS(588) G_DELAY_PS(0) /* CFG_MMC1_CLK_IN */ + 0x624 A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_CMD_IN */ + 0x630 A_DELAY_PS(1375) G_DELAY_PS(0) /* CFG_MMC1_DAT0_IN */ + 0x63C A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_DAT1_IN */ + 0x648 A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_DAT2_IN */ + 0x654 A_DELAY_PS(1000) G_DELAY_PS(0) /* CFG_MMC1_DAT3_IN */ + 0x620 A_DELAY_PS(1230) G_DELAY_PS(0) /* CFG_MMC1_CLK_OUT */ + 0x62C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x638 A_DELAY_PS(56) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x644 A_DELAY_PS(76) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x650 A_DELAY_PS(91) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x65C A_DELAY_PS(99) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x64C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + >; + }; + + /* Corresponds to MMC1_MANUAL2 in datamanual */ + mmc1_iodelay_sdr104_rev10_conf: mmc1_iodelay_sdr104_rev10_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(560) G_DELAY_PS(365) /* CFG_MMC1_CLK_OUT */ + 0x62c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x638 A_DELAY_PS(29) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x650 A_DELAY_PS(47) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x65c A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + 0x628 A_DELAY_PS(125) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x634 A_DELAY_PS(43) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x640 A_DELAY_PS(433) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x64c A_DELAY_PS(287) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x658 A_DELAY_PS(351) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + >; + }; + + /* Corresponds to MMC1_MANUAL2 in datamanual */ + mmc1_iodelay_sdr104_rev20_conf: mmc1_iodelay_sdr104_rev20_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(520) G_DELAY_PS(320) /* CFG_MMC1_CLK_OUT */ + 0x62c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x638 A_DELAY_PS(40) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x644 A_DELAY_PS(83) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x650 A_DELAY_PS(98) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x65c A_DELAY_PS(106) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + 0x628 A_DELAY_PS(51) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x640 A_DELAY_PS(363) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x64c A_DELAY_PS(199) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x658 A_DELAY_PS(273) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + >; + }; + + /* Corresponds to MMC2_MANUAL1 in datamanual */ + mmc2_iodelay_ddr_conf: mmc2_iodelay_ddr_conf { + pinctrl-pin-array = < + 0x18c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_IN */ + 0x1a4 A_DELAY_PS(119) G_DELAY_PS(0) /* CFG_GPMC_A20_IN */ + 0x1b0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_IN */ + 0x1bc A_DELAY_PS(18) G_DELAY_PS(0) /* CFG_GPMC_A22_IN */ + 0x1c8 A_DELAY_PS(894) G_DELAY_PS(0) /* CFG_GPMC_A23_IN */ + 0x1d4 A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_GPMC_A24_IN */ + 0x1e0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_IN */ + 0x1ec A_DELAY_PS(23) G_DELAY_PS(0) /* CFG_GPMC_A26_IN */ + 0x1f8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_IN */ + 0x360 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_IN */ + 0x194 A_DELAY_PS(152) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1ac A_DELAY_PS(206) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b8 A_DELAY_PS(78) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c4 A_DELAY_PS(2) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(266) G_DELAY_PS(0) /* CFG_GPMC_A23_OUT */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f4 A_DELAY_PS(43) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x368 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x1a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1b4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1c0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1d8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1f0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x364 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + >; + }; + + /* Corresponds to MMC2_MANUAL3 in datamanual */ + mmc2_iodelay_hs200_rev10_conf: mmc2_iodelay_hs200_rev10_conf { + pinctrl-pin-array = < + 0x194 A_DELAY_PS(150) G_DELAY_PS(95) /* CFG_GPMC_A19_OUT */ + 0x1ac A_DELAY_PS(250) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b8 A_DELAY_PS(125) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c4 A_DELAY_PS(100) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(870) G_DELAY_PS(415) /* CFG_GPMC_A23_OUT */ + 0x1dc A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e8 A_DELAY_PS(200) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f4 A_DELAY_PS(200) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x368 A_DELAY_PS(240) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + 0x190 A_DELAY_PS(695) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x1a8 A_DELAY_PS(924) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1b4 A_DELAY_PS(719) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1c0 A_DELAY_PS(824) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1d8 A_DELAY_PS(877) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1e4 A_DELAY_PS(446) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1f0 A_DELAY_PS(847) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1fc A_DELAY_PS(586) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x364 A_DELAY_PS(1039) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + >; + }; + + /* Corresponds to MMC2_MANUAL3 in datamanual */ + mmc2_iodelay_hs200_rev20_conf: mmc2_iodelay_hs200_rev20_conf { + pinctrl-pin-array = < + 0x194 A_DELAY_PS(285) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1ac A_DELAY_PS(189) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b8 A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A21_OUT */ + 0x1c4 A_DELAY_PS(0) G_DELAY_PS(70) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(730) G_DELAY_PS(360) /* CFG_GPMC_A23_OUT */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f4 A_DELAY_PS(70) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x368 A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_CS1_OUT */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x1a8 A_DELAY_PS(231) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1b4 A_DELAY_PS(39) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1c0 A_DELAY_PS(91) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1d8 A_DELAY_PS(176) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1f0 A_DELAY_PS(101) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x364 A_DELAY_PS(360) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + >; + }; +}; diff --git a/arch/arm/boot/dts/dra74x-mmc-iodelay.dtsi b/arch/arm/boot/dts/dra74x-mmc-iodelay.dtsi new file mode 100644 index 000000000000..28ebb4eb884a --- /dev/null +++ b/arch/arm/boot/dts/dra74x-mmc-iodelay.dtsi @@ -0,0 +1,647 @@ +/* + * MMC IOdelay values for TI's DRA74x, DRA75x and AM572x SoCs. + * + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Rules for modifying this file: + * a) Update of this file should typically correspond to a datamanual revision. + * Datamanual revision that was used should be updated in comment below. + * If there is no update to datamanual, do not update the values. If you + * need to use values different from that recommended by the datamanual + * for your design, then you should consider adding values to the device- + * -tree file for your board directly. + * b) We keep the mode names as close to the datamanual as possible. So + * if the manual calls a mode, DDR50, or DDR or DDR 1.8v or DDR 3.3v, + * we follow that in code too. + * c) If the values change between multiple revisions of silicon, we add + * a revision tag to both the new and old entry. Use 'rev11' for PG 1.1, + * 'rev20' for PG 2.0 and so on. + * d) The node name and node label should be the exact same string. This is + * to curb naming creativity and achieve consistency. + * + * Datamanual Revisions: + * + * AM572x Silicon Revision 2.0: SPRS953B, Revised November 2016 + * AM572x Silicon Revision 1.1: SPRS915R, Revised November 2016 + * + */ + +&dra7_pmx_core { + mmc1_pins_default: mmc1_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr12: mmc1_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_hs: mmc1_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr25: mmc1_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE11 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr50: mmc1_pins_sdr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_VIRTUAL_MODE10 | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_ddr50: mmc1_pins_ddr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr104: mmc1_pins_sdr104 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc2_pins_default: mmc2_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs: mmc2_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_3_3v_rev11: mmc2_pins_ddr_3_3v_rev11 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_1_8v_rev11: mmc2_pins_ddr_1_8v_rev11 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_ddr_rev20: mmc2_pins_ddr_rev20 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc2_pins_hs200: mmc2_pins_hs200 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; + + mmc4_pins_default: mmc4_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; + + mmc4_pins_hs: mmc4_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; + + mmc3_pins_default: mmc3_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_hs: mmc3_pins_hs { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_sdr12: mmc3_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_sdr25: mmc3_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc3_pins_sdr50: mmc3_pins_sdr50 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_clk.mmc3_clk */ + DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */ + DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */ + DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */ + DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */ + DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */ + >; + }; + + mmc4_pins_sdr12: mmc4_pins_sdr12 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; + + mmc4_pins_sdr25: mmc4_pins_sdr25 { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x37e8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_ctsn.mmc4_clk */ + DRA7XX_CORE_IOPAD(0x37ec, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart1_rtsn.mmc4_cmd */ + DRA7XX_CORE_IOPAD(0x37f0, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rxd.mmc4_dat0 */ + DRA7XX_CORE_IOPAD(0x37f4, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_txd.mmc4_dat1 */ + DRA7XX_CORE_IOPAD(0x37f8, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_ctsn.mmc4_dat2 */ + DRA7XX_CORE_IOPAD(0x37fc, PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE3) /* uart2_rtsn.mmc4_dat3 */ + >; + }; +}; + +&dra7_iodelay_core { + + /* Corresponds to MMC1_DDR_MANUAL1 in datamanual */ + mmc1_iodelay_ddr_rev11_conf: mmc1_iodelay_ddr_rev11_conf { + pinctrl-pin-array = < + 0x618 A_DELAY_PS(572) G_DELAY_PS(540) /* CFG_MMC1_CLK_IN */ + 0x620 A_DELAY_PS(1525) G_DELAY_PS(0) /* CFG_MMC1_CLK_OUT */ + 0x624 A_DELAY_PS(0) G_DELAY_PS(600) /* CFG_MMC1_CMD_IN */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62c A_DELAY_PS(55) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x630 A_DELAY_PS(403) G_DELAY_PS(120) /* CFG_MMC1_DAT0_IN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x63c A_DELAY_PS(23) G_DELAY_PS(60) /* CFG_MMC1_DAT1_IN */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x648 A_DELAY_PS(25) G_DELAY_PS(60) /* CFG_MMC1_DAT2_IN */ + 0x64c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x654 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_IN */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC1_DDR_MANUAL1 in datamanual */ + mmc1_iodelay_ddr_rev20_conf: mmc1_iodelay_ddr50_rev20_conf { + pinctrl-pin-array = < + 0x618 A_DELAY_PS(1076) G_DELAY_PS(330) /* CFG_MMC1_CLK_IN */ + 0x620 A_DELAY_PS(1271) G_DELAY_PS(0) /* CFG_MMC1_CLK_OUT */ + 0x624 A_DELAY_PS(722) G_DELAY_PS(0) /* CFG_MMC1_CMD_IN */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x630 A_DELAY_PS(751) G_DELAY_PS(0) /* CFG_MMC1_DAT0_IN */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(20) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x63C A_DELAY_PS(256) G_DELAY_PS(0) /* CFG_MMC1_DAT1_IN */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x648 A_DELAY_PS(263) G_DELAY_PS(0) /* CFG_MMC1_DAT2_IN */ + 0x64C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x654 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_IN */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65C A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC1_SDR104_MANUAL1 in datamanual */ + mmc1_iodelay_sdr104_rev11_conf: mmc1_iodelay_sdr104_rev11_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(1063) G_DELAY_PS(17) /* CFG_MMC1_CLK_OUT */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62c A_DELAY_PS(23) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(2) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x64c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC1_SDR104_MANUAL1 in datamanual */ + mmc1_iodelay_sdr104_rev20_conf: mmc1_iodelay_sdr104_rev20_conf { + pinctrl-pin-array = < + 0x620 A_DELAY_PS(600) G_DELAY_PS(400) /* CFG_MMC1_CLK_OUT */ + 0x628 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OEN */ + 0x62c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_CMD_OUT */ + 0x634 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OEN */ + 0x638 A_DELAY_PS(30) G_DELAY_PS(0) /* CFG_MMC1_DAT0_OUT */ + 0x640 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OEN */ + 0x644 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT1_OUT */ + 0x64c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OEN */ + 0x650 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT2_OUT */ + 0x658 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OEN */ + 0x65c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC1_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC2_HS200_MANUAL1 in datamanual */ + mmc2_iodelay_hs200_rev11_conf: mmc2_iodelay_hs200_rev11_conf { + pinctrl-pin-array = < + 0x190 A_DELAY_PS(621) G_DELAY_PS(600) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(300) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a8 A_DELAY_PS(739) G_DELAY_PS(600) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(240) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b4 A_DELAY_PS(812) G_DELAY_PS(600) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(240) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c0 A_DELAY_PS(954) G_DELAY_PS(600) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(60) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(1340) G_DELAY_PS(420) /* CFG_GPMC_A23_OUT */ + 0x1d8 A_DELAY_PS(935) G_DELAY_PS(600) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e4 A_DELAY_PS(525) G_DELAY_PS(600) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(120) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f0 A_DELAY_PS(767) G_DELAY_PS(600) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(225) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1fc A_DELAY_PS(565) G_DELAY_PS(600) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(60) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x364 A_DELAY_PS(969) G_DELAY_PS(600) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(180) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Corresponds to MMC2_HS200_MANUAL1 in datamanual */ + mmc2_iodelay_hs200_rev20_conf: mmc2_iodelay_hs200_rev20_conf { + pinctrl-pin-array = < + 0x190 A_DELAY_PS(274) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(162) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a8 A_DELAY_PS(401) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(73) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b4 A_DELAY_PS(465) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(115) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1c0 A_DELAY_PS(633) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(47) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1d0 A_DELAY_PS(935) G_DELAY_PS(280) /* CFG_GPMC_A23_OUT */ + 0x1d8 A_DELAY_PS(621) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e4 A_DELAY_PS(183) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1f0 A_DELAY_PS(467) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1fc A_DELAY_PS(262) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(46) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x364 A_DELAY_PS(684) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(76) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Correspnds to MMC2_DDR_3V3_MANUAL1 in datamanual */ + mmc2_iodelay_ddr_3_3v_rev11_conf: mmc2_iodelay_ddr_3_3v_rev11_conf { + pinctrl-pin-array = < + 0x18c A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A19_IN */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(174) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a4 A_DELAY_PS(265) G_DELAY_PS(360) /* CFG_GPMC_A20_IN */ + 0x1a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(168) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b0 A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A21_IN */ + 0x1b4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(136) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1bc A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A22_IN */ + 0x1c0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1c8 A_DELAY_PS(287) G_DELAY_PS(420) /* CFG_GPMC_A23_IN */ + 0x1d0 A_DELAY_PS(879) G_DELAY_PS(0) /* CFG_GPMC_A23_OUT */ + 0x1d4 A_DELAY_PS(144) G_DELAY_PS(240) /* CFG_GPMC_A24_IN */ + 0x1d8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_IN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(34) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1ec A_DELAY_PS(0) G_DELAY_PS(120) /* CFG_GPMC_A26_IN */ + 0x1f0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(120) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1f8 A_DELAY_PS(120) G_DELAY_PS(180) /* CFG_GPMC_A27_IN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x360 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_IN */ + 0x364 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(11) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Corresponds to MMC2_DDR_1V8_MANUAL1 in datamanual */ + mmc2_iodelay_ddr_1_8v_rev11_conf: mmc2_iodelay_ddr_1_8v_rev11_conf { + pinctrl-pin-array = < + 0x18c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_IN */ + 0x190 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A19_OEN */ + 0x194 A_DELAY_PS(174) G_DELAY_PS(0) /* CFG_GPMC_A19_OUT */ + 0x1a4 A_DELAY_PS(274) G_DELAY_PS(240) /* CFG_GPMC_A20_IN */ + 0x1a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A20_OEN */ + 0x1ac A_DELAY_PS(168) G_DELAY_PS(0) /* CFG_GPMC_A20_OUT */ + 0x1b0 A_DELAY_PS(0) G_DELAY_PS(60) /* CFG_GPMC_A21_IN */ + 0x1b4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A21_OEN */ + 0x1b8 A_DELAY_PS(136) G_DELAY_PS(0) /* CFG_GPMC_A21_OUT */ + 0x1bc A_DELAY_PS(0) G_DELAY_PS(60) /* CFG_GPMC_A22_IN */ + 0x1c0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OEN */ + 0x1c4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A22_OUT */ + 0x1c8 A_DELAY_PS(514) G_DELAY_PS(360) /* CFG_GPMC_A23_IN */ + 0x1d0 A_DELAY_PS(879) G_DELAY_PS(0) /* CFG_GPMC_A23_OUT */ + 0x1d4 A_DELAY_PS(187) G_DELAY_PS(120) /* CFG_GPMC_A24_IN */ + 0x1d8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OEN */ + 0x1dc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A24_OUT */ + 0x1e0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_IN */ + 0x1e4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A25_OEN */ + 0x1e8 A_DELAY_PS(34) G_DELAY_PS(0) /* CFG_GPMC_A25_OUT */ + 0x1ec A_DELAY_PS(0) G_DELAY_PS(60) /* CFG_GPMC_A26_IN */ + 0x1f0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A26_OEN */ + 0x1f4 A_DELAY_PS(120) G_DELAY_PS(0) /* CFG_GPMC_A26_OUT */ + 0x1f8 A_DELAY_PS(121) G_DELAY_PS(60) /* CFG_GPMC_A27_IN */ + 0x1fc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OEN */ + 0x200 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_A27_OUT */ + 0x360 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_IN */ + 0x364 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_GPMC_CS1_OEN */ + 0x368 A_DELAY_PS(11) G_DELAY_PS(0) /* CFG_GPMC_CS1_OUT */ + >; + }; + + /* Corresponds to MMC3_MANUAL1 in datamanual */ + mmc3_iodelay_manual1_rev20_conf: mmc3_iodelay_manual1_conf { + pinctrl-pin-array = < + 0x678 A_DELAY_PS(0) G_DELAY_PS(386) /* CFG_MMC3_CLK_IN */ + 0x680 A_DELAY_PS(605) G_DELAY_PS(0) /* CFG_MMC3_CLK_OUT */ + 0x684 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_IN */ + 0x688 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OEN */ + 0x68c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OUT */ + 0x690 A_DELAY_PS(171) G_DELAY_PS(0) /* CFG_MMC3_DAT0_IN */ + 0x694 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OEN */ + 0x698 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OUT */ + 0x69c A_DELAY_PS(221) G_DELAY_PS(0) /* CFG_MMC3_DAT1_IN */ + 0x6a0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OEN */ + 0x6a4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OUT */ + 0x6a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_IN */ + 0x6ac A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OEN */ + 0x6b0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OUT */ + 0x6b4 A_DELAY_PS(474) G_DELAY_PS(0) /* CFG_MMC3_DAT3_IN */ + 0x6b8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OEN */ + 0x6bc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC3_MANUAL1 in datamanual */ + mmc3_iodelay_manual1_rev11_conf: mmc3_iodelay_manual1_conf { + pinctrl-pin-array = < + 0x678 A_DELAY_PS(406) G_DELAY_PS(0) /* CFG_MMC3_CLK_IN */ + 0x680 A_DELAY_PS(659) G_DELAY_PS(0) /* CFG_MMC3_CLK_OUT */ + 0x684 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_IN */ + 0x688 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OEN */ + 0x68c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_CMD_OUT */ + 0x690 A_DELAY_PS(130) G_DELAY_PS(0) /* CFG_MMC3_DAT0_IN */ + 0x694 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OEN */ + 0x698 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT0_OUT */ + 0x69c A_DELAY_PS(169) G_DELAY_PS(0) /* CFG_MMC3_DAT1_IN */ + 0x6a0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OEN */ + 0x6a4 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT1_OUT */ + 0x6a8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_IN */ + 0x6ac A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OEN */ + 0x6b0 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT2_OUT */ + 0x6b4 A_DELAY_PS(457) G_DELAY_PS(0) /* CFG_MMC3_DAT3_IN */ + 0x6b8 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OEN */ + 0x6bc A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_MMC3_DAT3_OUT */ + >; + }; + + /* Corresponds to MMC4_DS_MANUAL1 in datamanual */ + mmc4_iodelay_ds_rev11_conf: mmc4_iodelay_ds_rev11_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(96) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(582) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(391) G_DELAY_PS(0) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(561) G_DELAY_PS(0) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(588) G_DELAY_PS(0) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; + + /* Corresponds to MMC4_DS_MANUAL1 in datamanual */ + mmc4_iodelay_ds_rev20_conf: mmc4_iodelay_ds_rev20_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(307) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(785) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(613) G_DELAY_PS(0) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(683) G_DELAY_PS(0) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(835) G_DELAY_PS(0) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; + + /* Corresponds to MMC4_MANUAL1 in datamanual */ + mmc4_iodelay_sdr12_hs_sdr25_rev11_conf: mmc4_iodelay_sdr12_hs_sdr25_rev11_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(2651) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(1572) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(1913) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(1721) G_DELAY_PS(0) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(1891) G_DELAY_PS(0) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(1919) G_DELAY_PS(0) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; + + /* Corresponds to MMC4_MANUAL1 in datamanual */ + mmc4_iodelay_sdr12_hs_sdr25_rev20_conf: mmc4_iodelay_sdr12_hs_sdr25_rev20_conf { + pinctrl-pin-array = < + 0x840 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_CTSN_IN */ + 0x848 A_DELAY_PS(1147) G_DELAY_PS(0) /* CFG_UART1_CTSN_OUT */ + 0x84c A_DELAY_PS(1834) G_DELAY_PS(0) /* CFG_UART1_RTSN_IN */ + 0x850 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OEN */ + 0x854 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART1_RTSN_OUT */ + 0x870 A_DELAY_PS(2165) G_DELAY_PS(0) /* CFG_UART2_CTSN_IN */ + 0x874 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OEN */ + 0x878 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_CTSN_OUT */ + 0x87c A_DELAY_PS(1929) G_DELAY_PS(64) /* CFG_UART2_RTSN_IN */ + 0x880 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OEN */ + 0x884 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RTSN_OUT */ + 0x888 A_DELAY_PS(1935) G_DELAY_PS(128) /* CFG_UART2_RXD_IN */ + 0x88c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OEN */ + 0x890 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_RXD_OUT */ + 0x894 A_DELAY_PS(2172) G_DELAY_PS(44) /* CFG_UART2_TXD_IN */ + 0x898 A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OEN */ + 0x89c A_DELAY_PS(0) G_DELAY_PS(0) /* CFG_UART2_TXD_OUT */ + >; + }; +}; diff --git a/arch/arm/boot/dts/dra76-evm.dts b/arch/arm/boot/dts/dra76-evm.dts new file mode 100644 index 000000000000..b024a65c6e27 --- /dev/null +++ b/arch/arm/boot/dts/dra76-evm.dts @@ -0,0 +1,423 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "dra76x.dtsi" +#include "dra7-evm-common.dtsi" +#include + +/ { + model = "TI DRA762 EVM"; + compatible = "ti,dra76-evm", "ti,dra762", "ti,dra7"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x80000000>; + }; + + vsys_12v0: fixedregulator-vsys12v0 { + /* main supply */ + compatible = "regulator-fixed"; + regulator-name = "vsys_12v0"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + regulator-boot-on; + }; + + vsys_5v0: fixedregulator-vsys5v0 { + /* Output of Cntlr B of TPS43351-Q1 on dra76-evm */ + compatible = "regulator-fixed"; + regulator-name = "vsys_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vsys_12v0>; + regulator-always-on; + regulator-boot-on; + }; + + vsys_3v3: fixedregulator-vsys3v3 { + /* Output of Cntlr A of TPS43351-Q1 on dra76-evm */ + compatible = "regulator-fixed"; + regulator-name = "vsys_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vsys_12v0>; + regulator-always-on; + regulator-boot-on; + }; + + vio_3v3: fixedregulator-vio_3v3 { + compatible = "regulator-fixed"; + regulator-name = "vio_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vsys_3v3>; + regulator-always-on; + regulator-boot-on; + }; + + vio_3v3_sd: fixedregulator-sd { + compatible = "regulator-fixed"; + regulator-name = "vio_3v3_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vio_3v3>; + enable-active-high; + gpio = <&gpio4 21 GPIO_ACTIVE_HIGH>; + }; + + vio_1v8: fixedregulator-vio_1v8 { + compatible = "regulator-fixed"; + regulator-name = "vio_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&smps5_reg>; + }; + + vtt_fixed: fixedregulator-vtt { + compatible = "regulator-fixed"; + regulator-name = "vtt_fixed"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + vin-supply = <&vsys_3v3>; + regulator-always-on; + regulator-boot-on; + }; + + aic_dvdd: fixedregulator-aic_dvdd { + /* TPS77018DBVT */ + compatible = "regulator-fixed"; + regulator-name = "aic_dvdd"; + vin-supply = <&vio_3v3>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; +}; + +&dra7_pmx_core { + mmc1_pins_default: mmc1_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x376c, PIN_INPUT | MUX_MODE14) /* mmc1sdcd.gpio219 */ + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc1_pins_sdr12: pinmux_mmc1_sdr12_pins { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */ + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */ + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */ + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */ + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */ + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */ + >; + }; + + mmc2_pins_default: mmc2_pins_default { + pinctrl-single,pins = < + DRA7XX_CORE_IOPAD(0x349c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a23.mmc2_clk */ + DRA7XX_CORE_IOPAD(0x34b0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_cs1.mmc2_cmd */ + DRA7XX_CORE_IOPAD(0x34a0, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a24.mmc2_dat0 */ + DRA7XX_CORE_IOPAD(0x34a4, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a25.mmc2_dat1 */ + DRA7XX_CORE_IOPAD(0x34a8, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a26.mmc2_dat2 */ + DRA7XX_CORE_IOPAD(0x34ac, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a27.mmc2_dat3 */ + DRA7XX_CORE_IOPAD(0x348c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a19.mmc2_dat4 */ + DRA7XX_CORE_IOPAD(0x3490, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a20.mmc2_dat5 */ + DRA7XX_CORE_IOPAD(0x3494, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a21.mmc2_dat6 */ + DRA7XX_CORE_IOPAD(0x3498, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_a22.mmc2_dat7 */ + >; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + + tps65917: tps65917@58 { + compatible = "ti,tps65917"; + reg = <0x58>; + ti,system-power-controller; + interrupt-controller; + #interrupt-cells = <2>; + + tps65917_pmic { + compatible = "ti,tps65917-pmic"; + + smps12-in-supply = <&vsys_3v3>; + smps3-in-supply = <&vsys_3v3>; + smps4-in-supply = <&vsys_3v3>; + smps5-in-supply = <&vsys_3v3>; + ldo1-in-supply = <&vsys_3v3>; + ldo2-in-supply = <&vsys_3v3>; + ldo3-in-supply = <&vsys_5v0>; + ldo4-in-supply = <&vsys_5v0>; + ldo5-in-supply = <&vsys_3v3>; + + tps65917_regulators: regulators { + smps12_reg: smps12 { + /* VDD_DSPEVE */ + regulator-name = "smps12"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + smps3_reg: smps3 { + /* VDD_CORE */ + regulator-name = "smps3"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-boot-on; + regulator-always-on; + }; + + smps4_reg: smps4 { + /* VDD_IVA */ + regulator-name = "smps4"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + smps5_reg: smps5 { + /* VDDS1V8 */ + regulator-name = "smps5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: ldo1 { + /* LDO1_OUT --> VDA_PHY1_1V8 */ + regulator-name = "ldo1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-allow-bypass; + }; + + ldo2_reg: ldo2 { + /* LDO2_OUT --> VDA_PHY2_1V8 */ + regulator-name = "ldo2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-allow-bypass; + regulator-always-on; + }; + + ldo3_reg: ldo3 { + /* VDA_USB_3V3 */ + regulator-name = "ldo3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo5_reg: ldo5 { + /* VDDA_1V8_PLL */ + regulator-name = "ldo5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo4_reg: ldo4 { + /* VDD_SDIO_DV */ + regulator-name = "ldo4"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + tps65917_power_button { + compatible = "ti,palmas-pwrbutton"; + interrupt-parent = <&tps65917>; + interrupts = <1 IRQ_TYPE_NONE>; + wakeup-source; + ti,palmas-long-press-seconds = <6>; + }; + }; + + lp87565: lp87565@60 { + compatible = "ti,lp87565-q1"; + reg = <0x60>; + + buck10-in-supply =<&vsys_3v3>; + buck23-in-supply =<&vsys_3v3>; + + regulators: regulators { + buck10_reg: buck10 { + /*VDD_MPU*/ + regulator-name = "buck10"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-always-on; + regulator-boot-on; + }; + + buck23_reg: buck23 { + /* VDD_GPU*/ + regulator-name = "buck23"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1250000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + pcf_lcd: pcf8757@20 { + compatible = "ti,pcf8575", "nxp,pcf8575"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&gpio1>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + }; + + pcf_gpio_21: pcf8757@21 { + compatible = "ti,pcf8575", "nxp,pcf8575"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio1>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pcf_hdmi: pcf8575@26 { + compatible = "ti,pcf8575", "nxp,pcf8575"; + reg = <0x26>; + gpio-controller; + #gpio-cells = <2>; + p1 { + /* vin6_sel_s0: high: VIN6, low: audio */ + gpio-hog; + gpios = <1 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "vin6_sel_s0"; + }; + }; + + tlv320aic3106: tlv320aic3106@19 { + #sound-dai-cells = <0>; + compatible = "ti,tlv320aic3106"; + reg = <0x19>; + adc-settle-ms = <40>; + ai3x-micbias-vg = <1>; /* 2.0V */ + status = "okay"; + + /* Regulators */ + AVDD-supply = <&vio_3v3>; + IOVDD-supply = <&vio_3v3>; + DRVDD-supply = <&vio_3v3>; + DVDD-supply = <&aic_dvdd>; + }; +}; + +&cpu0 { + vdd-supply = <&buck10_reg>; +}; + +&mmc1 { + status = "okay"; + vmmc-supply = <&vio_3v3_sd>; + vmmc_aux-supply = <&ldo4_reg>; + bus-width = <4>; + /* + * SDCD signal is not being used here - using the fact that GPIO mode + * is always hardwired. + */ + cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_default>; +}; + +&mmc2 { + status = "okay"; + vmmc-supply = <&vio_1v8>; + bus-width = <8>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins_default>; +}; + +/* No RTC on this device */ +&rtc { + status = "disabled"; +}; + +&mac { + status = "okay"; + + dual_emac; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <2>; + phy-mode = "rgmii-id"; + dual_emac_res_vlan = <1>; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <3>; + phy-mode = "rgmii-id"; + dual_emac_res_vlan = <2>; +}; + +&davinci_mdio { + dp83867_0: ethernet-phy@2 { + reg = <2>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; + }; + + dp83867_1: ethernet-phy@3 { + reg = <3>; + ti,rx-internal-delay = ; + ti,tx-internal-delay = ; + ti,fifo-depth = ; + ti,min-output-impedance; + ti,dp83867-rxctrl-strap-quirk; + }; +}; + +&usb2_phy1 { + phy-supply = <&ldo3_reg>; +}; + +&usb2_phy2 { + phy-supply = <&ldo3_reg>; +}; + +&qspi { + spi-max-frequency = <96000000>; + m25p80@0 { + spi-max-frequency = <96000000>; + }; +}; diff --git a/arch/arm/boot/dts/dra76x.dtsi b/arch/arm/boot/dts/dra76x.dtsi new file mode 100644 index 000000000000..1c88c581ff18 --- /dev/null +++ b/arch/arm/boot/dts/dra76x.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "dra74x.dtsi" + +/ { + compatible = "ti,dra762", "ti,dra7"; + +}; + +/* MCAN interrupts are hard-wired to irqs 67, 68 */ +&crossbar_mpu { + ti,irqs-skip = <10 67 68 133 139 140>; +}; diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index cf229dfabf61..e62b62875cba 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -1817,6 +1817,8 @@ clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atl_clkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; ti,bit-shift = <24>; reg = <0x1868>; + assigned-clocks = <&mcasp3_ahclkx_mux>; + assigned-clock-parents = <&abe_24m_fclk>; }; mcasp3_aux_gfclk_mux: mcasp3_aux_gfclk_mux@1868 { diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts index 98fc667d22c7..c9f3ea29cf9e 100644 --- a/arch/arm/boot/dts/efm32gg-dk3750.dts +++ b/arch/arm/boot/dts/efm32gg-dk3750.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device tree for EFM32GG-DK3750 development board. * diff --git a/arch/arm/boot/dts/efm32gg.dtsi b/arch/arm/boot/dts/efm32gg.dtsi index b78c57e51ed5..8a58e49144cc 100644 --- a/arch/arm/boot/dts/efm32gg.dtsi +++ b/arch/arm/boot/dts/efm32gg.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device tree for Energy Micro EFM32 Giant Gecko SoC. * diff --git a/arch/arm/boot/dts/elpida_ecb240abacn.dtsi b/arch/arm/boot/dts/elpida_ecb240abacn.dtsi index f97f70f83374..d87ee4794f83 100644 --- a/arch/arm/boot/dts/elpida_ecb240abacn.dtsi +++ b/arch/arm/boot/dts/elpida_ecb240abacn.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common devices used in different OMAP boards */ diff --git a/arch/arm/boot/dts/exynos3250-artik5-eval.dts b/arch/arm/boot/dts/exynos3250-artik5-eval.dts index 4bd2ee87124e..4cbfa09c6c4e 100644 --- a/arch/arm/boot/dts/exynos3250-artik5-eval.dts +++ b/arch/arm/boot/dts/exynos3250-artik5-eval.dts @@ -22,7 +22,6 @@ }; &mshc_2 { - num-slots = <1>; cap-sd-highspeed; disable-wp; vqmmc-supply = <&ldo3_reg>; diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi index 59c89d7662a8..639c2e605f3c 100644 --- a/arch/arm/boot/dts/exynos3250-artik5.dtsi +++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi @@ -304,7 +304,6 @@ }; &mshc_0 { - num-slots = <1>; non-removable; cap-mmc-highspeed; card-detect-delay = <200>; diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index accee81da266..bbdfcbc6e7d2 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -426,7 +426,6 @@ &mshc_0 { #address-cells = <1>; #size-cells = <0>; - num-slots = <1>; broken-cd; non-removable; cap-mmc-highspeed; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 443e0c98dc73..0b45467d77a8 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -220,21 +220,6 @@ samsung,pll-clock-frequency = <24000000>; status = "okay"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - remote-endpoint = <&dsi_in>; - samsung,burst-clock-frequency = <250000000>; - samsung,esc-clock-frequency = <20000000>; - }; - }; - }; - panel@0 { compatible = "samsung,s6e63j0x03"; reg = <0>; @@ -264,12 +249,6 @@ vsync-len = <2>; }; }; - - port { - dsi_in: endpoint { - remote-endpoint = <&dsi_out>; - }; - }; }; }; @@ -642,7 +621,6 @@ &mshc_0 { #address-cells = <1>; #size-cells = <0>; - num-slots = <1>; broken-cd; non-removable; cap-mmc-highspeed; diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index 645feffb9239..7b6ab7265110 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -202,21 +202,6 @@ samsung,pll-clock-frequency = <24000000>; status = "okay"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - remote-endpoint = <&dsi_in>; - samsung,burst-clock-frequency = <500000000>; - samsung,esc-clock-frequency = <20000000>; - }; - }; - }; - panel@0 { reg = <0>; compatible = "samsung,s6e8aa0"; @@ -244,12 +229,6 @@ vsync-len = <2>; }; }; - - port { - dsi_in: endpoint { - remote-endpoint = <&dsi_out>; - }; - }; }; }; diff --git a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi index 4cd62487bb16..14ce2c69bc0b 100644 --- a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi +++ b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi @@ -466,7 +466,6 @@ pinctrl-names = "default"; status = "okay"; vmmc-supply = <&buck9_reg>; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 219d587c5a85..102acd78be15 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -516,7 +516,6 @@ mmc-pwrseq = <&emmc_pwrseq>; status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 7a83e2df18a6..8a89eb893d64 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -488,7 +488,6 @@ pinctrl-names = "default"; status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 35e9b94b86b8..bceb919ac637 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -390,21 +390,6 @@ samsung,pll-clock-frequency = <24000000>; status = "okay"; - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - remote-endpoint = <&dsi_in>; - samsung,burst-clock-frequency = <500000000>; - samsung,esc-clock-frequency = <20000000>; - }; - }; - }; - panel@0 { compatible = "samsung,s6e8aa0"; reg = <0>; @@ -432,12 +417,6 @@ vsync-len = <2>; }; }; - - port { - dsi_in: endpoint { - remote-endpoint = <&dsi_out>; - }; - }; }; }; @@ -901,7 +880,6 @@ }; &mshc_0 { - num-slots = <1>; broken-cd; non-removable; card-detect-delay = <200>; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index 6a432460eb77..18a7f396ac5f 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -518,7 +518,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -533,7 +532,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index 6632f657394e..062cba4c2c31 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -346,7 +346,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -360,7 +359,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi index e1d293dbbe5d..8788880e459d 100644 --- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi +++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi @@ -530,7 +530,6 @@ /* eMMC flash */ &mmc_0 { status = "okay"; - num-slots = <1>; non-removable; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -544,7 +543,6 @@ /* uSD card */ &mmc_2 { status = "okay"; - num-slots = <1>; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -564,7 +562,6 @@ */ &mmc_3 { status = "okay"; - num-slots = <1>; non-removable; cap-sdio-irq; keep-power-in-suspend; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index 95c3bcace9dc..d53bfcbeb39c 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -427,7 +427,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -445,7 +444,6 @@ */ &mmc_1 { status = "okay"; - num-slots = <1>; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts index d0cc300cfb4b..73b7cdd5f522 100644 --- a/arch/arm/boot/dts/exynos5260-xyref5260.dts +++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts @@ -67,7 +67,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; broken-cd; bypass-smu; cap-mmc-highspeed; @@ -83,7 +82,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts index 6cc74d97daae..9cb7726ef8d0 100644 --- a/arch/arm/boot/dts/exynos5410-smdk5410.dts +++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts @@ -41,7 +41,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; cap-mmc-highspeed; broken-cd; card-detect-delay = <200>; @@ -53,7 +52,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index f9a75bfd3f2b..683a4cfb4a23 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -699,7 +699,6 @@ /* eMMC flash */ &mmc_0 { status = "okay"; - num-slots = <1>; mmc-hs200-1_8v; cap-mmc-highspeed; non-removable; @@ -717,7 +716,6 @@ /* WiFi SDIO module */ &mmc_1 { status = "okay"; - num-slots = <1>; non-removable; cap-sdio-irq; keep-power-in-suspend; @@ -737,7 +735,6 @@ /* uSD card */ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi index bc4954e69f7b..7a00be7ea6d7 100644 --- a/arch/arm/boot/dts/exynos5440.dtsi +++ b/arch/arm/boot/dts/exynos5440.dtsi @@ -317,6 +317,7 @@ phys = <&pcie_phy0>; ranges = <0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0x0 0 &gic 53>; @@ -339,6 +340,7 @@ phys = <&pcie_phy1>; ranges = <0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0x0 0 &gic 56>; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 953dc8677dc8..b2b95ff205e8 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -667,7 +667,6 @@ /* eMMC flash */ &mmc_0 { status = "okay"; - num-slots = <1>; mmc-hs200-1_8v; mmc-hs400-1_8v; cap-mmc-highspeed; @@ -686,7 +685,6 @@ /* WiFi SDIO module */ &mmc_1 { status = "okay"; - num-slots = <1>; non-removable; cap-sdio-irq; keep-power-in-suspend; @@ -706,7 +704,6 @@ /* uSD card */ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; diff --git a/arch/arm/boot/dts/gemini-dlink-dir-685.dts b/arch/arm/boot/dts/gemini-dlink-dir-685.dts new file mode 100644 index 000000000000..e75e2d44371c --- /dev/null +++ b/arch/arm/boot/dts/gemini-dlink-dir-685.dts @@ -0,0 +1,246 @@ +/* + * Device Tree file for D-Link DIR-685 Xtreme N Storage Router + */ + +/dts-v1/; + +#include "gemini.dtsi" +#include + +/ { + model = "D-Link DIR-685 Xtreme N Storage Router"; + compatible = "dlink,dir-685", "cortina,gemini"; + #address-cells = <1>; + #size-cells = <1>; + + memory { + /* 128 MB SDRAM in 2 x Hynix HY5DU121622DTP-D43 */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + chosen { + stdout-path = "uart0:115200n8"; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + button-esc { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "reset"; + /* Collides with LPC_LAD[0], UART DCD, SSP 97RST */ + gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; + }; + button-eject { + debounce_interval = <50>; + wakeup-source; + linux,code = ; + label = "unmount"; + /* Collides with LPC LFRAME, UART RTS, SSP TXD */ + gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + led-wps { + label = "dir685:blue:WPS"; + /* Collides with ICE */ + gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + /* + * These two LEDs are on the side of the device. + * For electrical reasons, both LEDs cannot be active + * at the same time so only blue or orange can on at + * one time. Enabling both makes the LED go dark. + * The LEDs both sit inside the unmount button and the + * label on the case says "unmount". + */ + led-blue-hd { + label = "dir685:blue:HD"; + /* Collides with LPC_SERIRQ, UART DTR, SSP FSC pins */ + gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + led-orange-hd { + label = "dir685:orange:HD"; + /* Collides with LPC_LAD[2], UART DSR, SSP ECLK pins */ + gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + /* + * This is a Sunon Maglev GM0502PFV2-8 cooling fan @10000 RPM. + * Since the platform has no temperature sensor, this is controlled + * from userspace by using the hard disks S.M.A.R.T. temperature + * sensor. It is turned on when the temperature exceeds 46 degrees + * and turned off when the temperatures goes below 41 degrees + * (celsius). + */ + gpio-fan { + compatible = "gpio-fan"; + /* Collides with IDE */ + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + gpio-fan,speed-map = <0 0>, <10000 1>; + #cooling-cells = <2>; + }; + + /* + * The touchpad input is connected to a GPIO bit-banged + * I2C bus. + */ + gpio-i2c { + compatible = "i2c-gpio"; + /* Collides with ICE */ + gpios = <&gpio0 5 0>, /* SDA */ + <&gpio0 6 0>; /* SCL */ + #address-cells = <1>; + #size-cells = <0>; + + touchkeys@26 { + compatible = "dlink,dir685-touchkeys"; + reg = <0x26>; + interrupt-parent = <&gpio0>; + /* Collides with NAND flash */ + interrupts = <17 IRQ_TYPE_EDGE_FALLING>; + }; + }; + + soc { + flash@30000000 { + status = "okay"; + /* 32MB of flash */ + reg = <0x30000000 0x02000000>; + + /* + * This "RedBoot" is the Storlink derivative. + */ + partition@0 { + label = "RedBoot"; + reg = <0x00000000 0x00040000>; + read-only; + }; + /* + * Between the boot loader and the rootfs is the kernel + * in a custom Storlink format flashed from the boot + * menu. The rootfs is in squashfs format. + */ + partition@1800c0 { + label = "rootfs"; + reg = <0x001800c0 0x01dbff40>; + read-only; + }; + partition@1f40000 { + label = "upgrade"; + reg = <0x01f40000 0x00040000>; + read-only; + }; + partition@1f80000 { + label = "rgdb"; + reg = <0x01f80000 0x00040000>; + read-only; + }; + /* + * This partition contains MAC addresses for WAN, + * WLAN and LAN, and the country code (for wireless + * I guess). + */ + partition@1fc0000 { + label = "nvram"; + reg = <0x01fc0000 0x00020000>; + read-only; + }; + partition@1fe0000 { + label = "LangPack"; + reg = <0x01fe0000 0x00020000>; + read-only; + }; + }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0bgrp cover line 5, 6 used by TK I2C + * gpio0bgrp cover line 7 used by WPS LED + * gpio0cgrp cover line 8, 13 used by keys + * and 11, 12 used by the HD LEDs + * gpio0egrp cover line 16 used by VDISP + * gpio0fgrp cover line 17 used by TK IRQ + * gpio0ggrp cover line 20 used by panel CS + * gpio0hgrp cover line 21,22 used by RTL8366RB + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0bgrp", + "gpio0cgrp", + "gpio0egrp", + "gpio0fgrp", + "gpio0ggrp", + "gpio0hgrp"; + }; + }; + /* + * gpio1bgrp cover line 5,8,7 used by panel SPI + * also line 6 used by the fan + * + */ + gpio1_default_pins: pinctrl-gpio1 { + mux { + function = "gpio1"; + groups = "gpio1bgrp"; + }; + }; + }; + }; + + sata: sata@46000000 { + cortina,gemini-ata-muxmode = <0>; + cortina,gemini-enable-sata-bridge; + status = "okay"; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; + + gpio1: gpio@4e000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_default_pins>; + }; + + pci@50000000 { + status = "okay"; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = + <0x4800 0 0 1 &pci_intc 0>, /* Slot 9 */ + <0x4800 0 0 2 &pci_intc 1>, + <0x4800 0 0 3 &pci_intc 2>, + <0x4800 0 0 4 &pci_intc 3>, + <0x5000 0 0 1 &pci_intc 1>, /* Slot 10 */ + <0x5000 0 0 2 &pci_intc 2>, + <0x5000 0 0 3 &pci_intc 3>, + <0x5000 0 0 4 &pci_intc 0>, + <0x5800 0 0 1 &pci_intc 2>, /* Slot 11 */ + <0x5800 0 0 2 &pci_intc 3>, + <0x5800 0 0 3 &pci_intc 0>, + <0x5800 0 0 4 &pci_intc 1>, + <0x6000 0 0 1 &pci_intc 3>, /* Slot 12 */ + <0x6000 0 0 2 &pci_intc 0>, + <0x6000 0 0 3 &pci_intc 1>, + <0x6000 0 0 4 &pci_intc 2>; + }; + + ata@63000000 { + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts index 55f6a4f1f801..d6a22e677c7a 100644 --- a/arch/arm/boot/dts/gemini-nas4220b.dts +++ b/arch/arm/boot/dts/gemini-nas4220b.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree file for the Gemini-based Raidsonic NAS IB-4220-B */ @@ -33,6 +34,7 @@ wakeup-source; linux,code = ; label = "Backup button"; + /* Conflict with TVC */ gpios = <&gpio1 29 GPIO_ACTIVE_LOW>; }; button@31 { @@ -40,6 +42,7 @@ wakeup-source; linux,code = ; label = "Softreset button"; + /* Conflict with TVC */ gpios = <&gpio1 31 GPIO_ACTIVE_LOW>; }; }; @@ -48,11 +51,13 @@ compatible = "gpio-leds"; led@28 { label = "nas4220b:orange:hdd"; + /* Conflict with TVC */ gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; default-state = "on"; }; led@30 { label = "nas4220b:green:os"; + /* Conflict with TVC */ gpios = <&gpio1 30 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; @@ -99,12 +104,32 @@ }; }; + syscon: syscon@40000000 { + pinctrl { + /* + * gpio1dgrp cover line 28-31 otherwise used + * by TVC. + */ + gpio1_default_pins: pinctrl-gpio1 { + mux { + function = "gpio1"; + groups = "gpio1dgrp"; + }; + }; + }; + }; + sata: sata@46000000 { cortina,gemini-ata-muxmode = <0>; cortina,gemini-enable-sata-bridge; status = "okay"; }; + gpio1: gpio@4e000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_default_pins>; + }; + ata@63000000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/gemini-rut1xx.dts b/arch/arm/boot/dts/gemini-rut1xx.dts index 7b920bfbda32..500057b6570e 100644 --- a/arch/arm/boot/dts/gemini-rut1xx.dts +++ b/arch/arm/boot/dts/gemini-rut1xx.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree file for Teltonika RUT1xx */ @@ -33,6 +34,7 @@ wakeup-source; linux,code = ; label = "Reset to defaults"; + /* Conflict with TVC */ gpios = <&gpio1 28 GPIO_ACTIVE_LOW>; }; }; @@ -42,12 +44,14 @@ led@7 { /* FIXME: add the LED color */ label = "rut1xx::gsm"; + /* Conflict with ICE */ gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; default-state = "on"; }; led@31 { /* FIXME: add the LED color */ label = "rut1xx::power"; + /* Conflict with NAND CE0 */ gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>; default-state = "off"; linux,default-trigger = "heartbeat"; @@ -61,5 +65,41 @@ reg = <0x30000000 0x00800000>; /* TODO: add flash partitions here */ }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0bgrp cover line 7 used by GSM LED + * gpio0fgrp cover line 17 used by power LED + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0bgrp", + "gpio0fgrp"; + }; + }; + /* + * gpio1dgrp cover line 28-31 otherwise used + * by TVC. + */ + gpio1_default_pins: pinctrl-gpio1 { + mux { + function = "gpio1"; + groups = "gpio1dgrp"; + }; + }; + }; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; + + gpio1: gpio@4e000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio1_default_pins>; + }; }; }; diff --git a/arch/arm/boot/dts/gemini-sq201.dts b/arch/arm/boot/dts/gemini-sq201.dts index 4d200f0bcd45..63c02ca9513c 100644 --- a/arch/arm/boot/dts/gemini-sq201.dts +++ b/arch/arm/boot/dts/gemini-sq201.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree file for ITian Square One SQ201 NAS */ @@ -33,6 +34,7 @@ wakeup-source; linux,code = ; label = "factory reset"; + /* Conflict with NAND flash */ gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; }; }; @@ -41,12 +43,14 @@ compatible = "gpio-leds"; led@20 { label = "sq201:green:info"; + /* Conflict with parallel flash */ gpios = <&gpio0 20 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; }; led@31 { label = "sq201:green:usb"; + /* Conflict with parallel and NAND flash */ gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; default-state = "off"; linux,default-trigger = "usb-host"; @@ -55,7 +59,15 @@ soc { flash@30000000 { - status = "okay"; + /* + * Flash access can be enabled, with the side effect + * of disabling access to GPIO LED on GPIO0[20] which + * reuse one of the parallel flash chip select lines. + * Also the default firmware on the machine has the + * problem that since it uses the flash, the two LEDS + * on the right become numb. + */ + /* status = "okay"; */ /* 16MB of flash */ reg = <0x30000000 0x01000000>; @@ -93,12 +105,35 @@ }; }; + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0fgrp cover line 18 used by reset button + * gpio0ggrp cover line 20 used by info LED + * gpio0kgrp cover line 31 used by USB LED + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0fgrp", + "gpio0ggrp", + "gpio0kgrp"; + }; + }; + }; + }; + sata: sata@46000000 { cortina,gemini-ata-muxmode = <0>; cortina,gemini-enable-sata-bridge; status = "okay"; }; + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; + pci@50000000 { status = "okay"; interrupt-map-mask = <0xf800 0 0 7>; diff --git a/arch/arm/boot/dts/gemini-wbd111.dts b/arch/arm/boot/dts/gemini-wbd111.dts index 63b756e3bf5a..b413fd12c5ba 100644 --- a/arch/arm/boot/dts/gemini-wbd111.dts +++ b/arch/arm/boot/dts/gemini-wbd111.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree file for Wiliboard WBD-111 */ @@ -33,6 +34,7 @@ wakeup-source; linux,code = ; label = "reset"; + /* Conflict with ICE */ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; }; }; @@ -42,21 +44,25 @@ led@1 { label = "wbd111:red:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@2 { label = "wbd111:green:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@3 { label = "wbd111:red:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@5 { label = "wbd111:green:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; @@ -98,5 +104,26 @@ read-only; }; }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0agrp cover line 0-4 + * gpio0bgrp cover line 5 + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0agrp", + "gpio0bgrp"; + }; + }; + }; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; }; }; diff --git a/arch/arm/boot/dts/gemini-wbd222.dts b/arch/arm/boot/dts/gemini-wbd222.dts index 9747f5a47807..3ba710538662 100644 --- a/arch/arm/boot/dts/gemini-wbd222.dts +++ b/arch/arm/boot/dts/gemini-wbd222.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree file for Wiliboard WBD-222 */ @@ -33,6 +34,7 @@ wakeup-source; linux,code = ; label = "reset"; + /* Conflict with ICE */ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; }; }; @@ -42,21 +44,25 @@ led@1 { label = "wbd111:red:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@2 { label = "wbd111:green:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@3 { label = "wbd111:red:L4"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; default-state = "off"; }; led@5 { label = "wbd111:green:L3"; + /* Conflict with TVC and extended parallel flash */ gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; default-state = "on"; linux,default-trigger = "heartbeat"; @@ -98,5 +104,26 @@ read-only; }; }; + + syscon: syscon@40000000 { + pinctrl { + /* + * gpio0agrp cover line 0-4 + * gpio0bgrp cover line 5 + */ + gpio0_default_pins: pinctrl-gpio0 { + mux { + function = "gpio0"; + groups = "gpio0agrp", + "gpio0bgrp"; + }; + }; + }; + }; + + gpio0: gpio@4d000000 { + pinctrl-names = "default"; + pinctrl-0 = <&gpio0_default_pins>; + }; }; }; diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi index 141d8d3a1d07..b9b07d0895cf 100644 --- a/arch/arm/boot/dts/gemini.dtsi +++ b/arch/arm/boot/dts/gemini.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree file for Cortina systems Gemini SoC */ @@ -5,6 +6,8 @@ /include/ "skeleton.dtsi" #include +#include +#include #include / { @@ -18,6 +21,8 @@ flash@30000000 { compatible = "cortina,gemini-flash", "cfi-flash"; syscon = <&syscon>; + pinctrl-names = "default"; + pinctrl-0 = <&pflash_default_pins>; bank-width = <2>; #address-cells = <1>; #size-cells = <1>; @@ -39,22 +44,124 @@ /* RESET_GLOBAL | RESET_CPU1 */ mask = <0xC0000000>; }; + + pinctrl { + compatible = "cortina,gemini-pinctrl"; + regmap = <&syscon>; + /* Hog the DRAM pins */ + pinctrl-names = "default"; + pinctrl-0 = <&dram_default_pins>, <&system_default_pins>, + <&vcontrol_default_pins>; + + dram_default_pins: pinctrl-dram { + mux { + function = "dram"; + groups = "dramgrp"; + }; + }; + rtc_default_pins: pinctrl-rtc { + mux { + function = "rtc"; + groups = "rtcgrp"; + }; + }; + power_default_pins: pinctrl-power { + mux { + function = "power"; + groups = "powergrp"; + }; + }; + cir_default_pins: pinctrl-cir { + mux { + function = "cir"; + groups = "cirgrp"; + }; + }; + system_default_pins: pinctrl-system { + mux { + function = "system"; + groups = "systemgrp"; + }; + }; + vcontrol_default_pins: pinctrl-vcontrol { + mux { + function = "vcontrol"; + groups = "vcontrolgrp"; + }; + }; + ice_default_pins: pinctrl-ice { + mux { + function = "ice"; + groups = "icegrp"; + }; + }; + uart_default_pins: pinctrl-uart { + mux { + function = "uart"; + groups = "uartrxtxgrp"; + }; + }; + pflash_default_pins: pinctrl-pflash { + mux { + function = "pflash"; + groups = "pflashgrp"; + }; + }; + usb_default_pins: pinctrl-usb { + mux { + function = "usb"; + groups = "usbgrp"; + }; + }; + gmii_default_pins: pinctrl-gmii { + mux { + function = "gmii"; + groups = "gmiigrp"; + }; + }; + pci_default_pins: pinctrl-pci { + mux { + function = "pci"; + groups = "pcigrp"; + }; + }; + sata_default_pins: pinctrl-sata { + mux { + function = "sata"; + groups = "satagrp"; + }; + }; + /* Activate both groups of pins for this state */ + sata_and_ide_pins: pinctrl-sata-ide { + mux0 { + function = "sata"; + groups = "satagrp"; + }; + mux1 { + function = "ide"; + groups = "idegrp"; + }; + }; + }; }; watchdog@41000000 { - compatible = "cortina,gemini-watchdog"; + compatible = "cortina,gemini-watchdog", "faraday,ftwdt010"; reg = <0x41000000 0x1000>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 23>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_WDOG>; + clocks = <&syscon GEMINI_CLK_APB>; + clock-names = "PCLK"; }; uart0: serial@42000000 { compatible = "ns16550a"; reg = <0x42000000 0x100>; - resets = <&syscon 18>; - clocks = <&syscon 6>; + resets = <&syscon GEMINI_RESET_UART>; + clocks = <&syscon GEMINI_CLK_UART>; interrupts = <18 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&uart_default_pins>; reg-shift = <2>; }; @@ -65,9 +172,9 @@ interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */ <15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */ <16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */ - resets = <&syscon 17>; + resets = <&syscon GEMINI_RESET_TIMER>; /* APB clock or RTC clock */ - clocks = <&syscon 2>, <&syscon 0>; + clocks = <&syscon GEMINI_CLK_APB>, <&syscon GEMINI_CLK_RTC>; clock-names = "PCLK", "EXTCLK"; syscon = <&syscon>; }; @@ -76,20 +183,30 @@ compatible = "cortina,gemini-rtc"; reg = <0x45000000 0x100>; interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 16>; - clocks = <&syscon 2>, <&syscon 0>; + resets = <&syscon GEMINI_RESET_RTC>; + clocks = <&syscon GEMINI_CLK_APB>, <&syscon GEMINI_CLK_RTC>; clock-names = "PCLK", "EXTCLK"; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_default_pins>; }; sata: sata@46000000 { compatible = "cortina,gemini-sata-bridge"; reg = <0x46000000 0x100>; - resets = <&syscon 26>, - <&syscon 27>; + resets = <&syscon GEMINI_RESET_SATA0>, + <&syscon GEMINI_RESET_SATA1>; reset-names = "sata0", "sata1"; - clocks = <&syscon 10>, - <&syscon 11>; + clocks = <&syscon GEMINI_CLK_GATE_SATA0>, + <&syscon GEMINI_CLK_GATE_SATA1>; clock-names = "SATA0_PCLK", "SATA1_PCLK"; + /* + * This defines the special "ide" state that needs + * to be explicitly enabled to enable the IDE pins, + * as these pins are normally used for other things. + */ + pinctrl-names = "default", "ide"; + pinctrl-0 = <&sata_default_pins>; + pinctrl-1 = <&sata_and_ide_pins>; syscon = <&syscon>; status = "disabled"; }; @@ -97,7 +214,7 @@ intcon: interrupt-controller@48000000 { compatible = "faraday,ftintc010"; reg = <0x48000000 0x1000>; - resets = <&syscon 14>; + resets = <&syscon GEMINI_RESET_INTCON0>; interrupt-controller; #interrupt-cells = <2>; }; @@ -106,14 +223,16 @@ compatible = "cortina,gemini-power-controller"; reg = <0x4b000000 0x100>; interrupts = <26 IRQ_TYPE_EDGE_RISING>; + pinctrl-names = "default"; + pinctrl-0 = <&power_default_pins>; }; gpio0: gpio@4d000000 { compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4d000000 0x100>; interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 20>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_GPIO0>; + clocks = <&syscon GEMINI_CLK_APB>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -124,8 +243,8 @@ compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4e000000 0x100>; interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 21>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_GPIO1>; + clocks = <&syscon GEMINI_CLK_APB>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -136,8 +255,8 @@ compatible = "cortina,gemini-gpio", "faraday,ftgpio010"; reg = <0x4f000000 0x100>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; - resets = <&syscon 22>; - clocks = <&syscon 2>; + resets = <&syscon GEMINI_RESET_GPIO2>; + clocks = <&syscon GEMINI_CLK_APB>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -151,9 +270,11 @@ * to configure the host bridge. */ reg = <0x50000000 0x100>; - resets = <&syscon 7>; - clocks = <&syscon 15>, <&syscon 4>; + resets = <&syscon GEMINI_RESET_PCI>; + clocks = <&syscon GEMINI_CLK_GATE_PCI>, <&syscon GEMINI_CLK_PCI>; clock-names = "PCLK", "PCICLK"; + pinctrl-names = "default"; + pinctrl-0 = <&pci_default_pins>; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; @@ -193,8 +314,8 @@ compatible = "cortina,gemini-pata", "faraday,ftide010"; reg = <0x63000000 0x1000>; interrupts = <4 IRQ_TYPE_EDGE_RISING>; - resets = <&syscon 2>; - clocks = <&syscon 14>; + resets = <&syscon GEMINI_RESET_IDE>; + clocks = <&syscon GEMINI_CLK_GATE_IDE>; clock-names = "PCLK"; sata = <&sata>; status = "disabled"; @@ -204,8 +325,8 @@ compatible = "cortina,gemini-pata", "faraday,ftide010"; reg = <0x63400000 0x1000>; interrupts = <5 IRQ_TYPE_EDGE_RISING>; - resets = <&syscon 2>; - clocks = <&syscon 14>; + resets = <&syscon GEMINI_RESET_IDE>; + clocks = <&syscon GEMINI_CLK_GATE_IDE>; clock-names = "PCLK"; sata = <&sata>; status = "disabled"; @@ -217,8 +338,8 @@ arm,primecell-periphid = <0x0003b080>; reg = <0x67000000 0x1000>; interrupts = <9 IRQ_TYPE_EDGE_RISING>; - resets = <&syscon 10>; - clocks = <&syscon 1>; + resets = <&syscon GEMINI_RESET_DMAC>; + clocks = <&syscon GEMINI_CLK_AHB>; clock-names = "apb_pclk"; /* Bus interface AHB1 (AHB0) is totally tilted */ lli-bus-interface-ahb2; diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index 0ade3619f3c3..09ce8b81fafa 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -452,6 +452,13 @@ interrupt-names = "scm", "smn"; }; + rngb: rngb@53fb0000 { + compatible = "fsl,imx25-rngb"; + reg = <0x53fb0000 0x4000>; + clocks = <&clks 109>; + interrupts = <22>; + }; + esdhc1: esdhc@53fb4000 { compatible = "fsl,imx25-esdhc"; reg = <0x53fb4000 0x4000>; diff --git a/arch/arm/boot/dts/imx28-apx4devkit.dts b/arch/arm/boot/dts/imx28-apx4devkit.dts index 1092b761d7ac..d2a91976e67f 100644 --- a/arch/arm/boot/dts/imx28-apx4devkit.dts +++ b/arch/arm/boot/dts/imx28-apx4devkit.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "imx28.dtsi" diff --git a/arch/arm/boot/dts/imx53-cx9020.dts b/arch/arm/boot/dts/imx53-cx9020.dts new file mode 100644 index 000000000000..4f54fd4418a3 --- /dev/null +++ b/arch/arm/boot/dts/imx53-cx9020.dts @@ -0,0 +1,297 @@ +/* + * Copyright 2017 Beckhoff Automation GmbH & Co. KG + * based on imx53-qsb.dts + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +#include "imx53.dtsi" + +/ { + model = "Beckhoff CX9020 Embedded PC"; + compatible = "bhf,cx9020", "fsl,imx53"; + + chosen { + stdout-path = &uart2; + }; + + memory { + reg = <0x70000000 0x20000000>, + <0xb0000000 0x20000000>; + }; + + display-0 { + #address-cells =<1>; + #size-cells = <0>; + compatible = "fsl,imx-parallel-display"; + interface-pix-fmt = "rgb24"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu_disp0>; + + port@0 { + reg = <0>; + + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; + + port@1 { + reg = <1>; + + display0_out: endpoint { + remote-endpoint = <&tfp410_in>; + }; + }; + }; + + dvi-connector { + compatible = "dvi-connector"; + ddc-i2c-bus = <&i2c2>; + digital; + + port { + dvi_connector_in: endpoint { + remote-endpoint = <&tfp410_out>; + }; + }; + }; + + dvi-converter { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ti,tfp410"; + + port@0 { + reg = <0>; + + tfp410_in: endpoint { + remote-endpoint = <&display0_out>; + }; + }; + + port@1 { + reg = <1>; + + tfp410_out: endpoint { + remote-endpoint = <&dvi_connector_in>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + pwr-r { + gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + pwr-g { + gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + pwr-b { + gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + sd1-b { + linux,default-trigger = "mmc0"; + gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; + }; + + sd2-b { + linux,default-trigger = "mmc1"; + gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>; + }; + }; + + regulator-3p2v { + compatible = "regulator-fixed"; + regulator-name = "3P2V"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-always-on; + }; + + reg_usb_vbus: regulator-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio7 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&esdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_esdhc1>; + cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + bus-width = <4>; + status = "okay"; +}; + +&esdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_esdhc2>; + cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + bus-width = <4>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec>; + phy-mode = "rmii"; + phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + fsl,dte-mode; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_vbus>; + phy_type = "utmi"; + status = "okay"; +}; + +&usbotg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&vpu { + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: hoggrp { + fsl,pins = < + MX53_PAD_GPIO_0__CCM_CLKO 0x1c4 + MX53_PAD_GPIO_16__I2C3_SDA 0x1c4 + MX53_PAD_EIM_D22__GPIO3_22 0x1c4 + MX53_PAD_EIM_D23__GPIO3_23 0x1e4 + MX53_PAD_EIM_D24__GPIO3_24 0x1e4 + >; + }; + + pinctrl_esdhc1: esdhc1grp { + fsl,pins = < + MX53_PAD_SD1_DATA0__ESDHC1_DAT0 0x1d5 + MX53_PAD_SD1_DATA1__ESDHC1_DAT1 0x1d5 + MX53_PAD_SD1_DATA2__ESDHC1_DAT2 0x1d5 + MX53_PAD_SD1_DATA3__ESDHC1_DAT3 0x1d5 + MX53_PAD_SD1_CMD__ESDHC1_CMD 0x1d5 + MX53_PAD_SD1_CLK__ESDHC1_CLK 0x1d5 + MX53_PAD_GPIO_1__ESDHC1_CD 0x1c4 + MX53_PAD_EIM_D17__GPIO3_17 0x1e4 + MX53_PAD_GPIO_3__GPIO1_3 0x1c4 + >; + }; + + pinctrl_esdhc2: esdhc2grp { + fsl,pins = < + MX53_PAD_SD2_DATA0__ESDHC2_DAT0 0x1d5 + MX53_PAD_SD2_DATA1__ESDHC2_DAT1 0x1d5 + MX53_PAD_SD2_DATA2__ESDHC2_DAT2 0x1d5 + MX53_PAD_SD2_DATA3__ESDHC2_DAT3 0x1d5 + MX53_PAD_SD2_CMD__ESDHC2_CMD 0x1d5 + MX53_PAD_SD2_CLK__ESDHC2_CLK 0x1d5 + MX53_PAD_GPIO_4__ESDHC2_CD 0x1e4 + MX53_PAD_EIM_D20__GPIO3_20 0x1e4 + MX53_PAD_GPIO_8__GPIO1_8 0x1c4 + >; + }; + + pinctrl_fec: fecgrp { + fsl,pins = < + MX53_PAD_FEC_MDC__FEC_MDC 0x4 + MX53_PAD_FEC_MDIO__FEC_MDIO 0x1fc + MX53_PAD_FEC_REF_CLK__FEC_TX_CLK 0x180 + MX53_PAD_FEC_RX_ER__FEC_RX_ER 0x180 + MX53_PAD_FEC_CRS_DV__FEC_RX_DV 0x180 + MX53_PAD_FEC_RXD1__FEC_RDATA_1 0x180 + MX53_PAD_FEC_RXD0__FEC_RDATA_0 0x180 + MX53_PAD_FEC_TX_EN__FEC_TX_EN 0x4 + MX53_PAD_FEC_TXD1__FEC_TDATA_1 0x4 + MX53_PAD_FEC_TXD0__FEC_TDATA_0 0x4 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX53_PAD_KEY_ROW3__I2C2_SDA 0xc0000000 + MX53_PAD_KEY_COL3__I2C2_SCL 0xc0000000 + >; + }; + + pinctrl_ipu_disp0: ipudisp0grp { + fsl,pins = < + MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK 0x5 + MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 0x5 + MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 0x5 + MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 0x5 + MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 0x5 + MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 0x5 + MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 0x5 + MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 0x5 + MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 0x5 + MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 0x5 + MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 0x5 + MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 0x5 + MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 0x5 + MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 0x5 + MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 0x5 + MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 0x5 + MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 0x5 + MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 0x5 + MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 0x5 + MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 0x5 + MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 0x5 + MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 0x5 + MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 0x5 + MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 0x5 + MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 0x5 + MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 0x5 + MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 0x5 + MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 0x5 + MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 0x5 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX53_PAD_EIM_D26__UART2_RXD_MUX 0x1e4 + MX53_PAD_EIM_D27__UART2_TXD_MUX 0x1e4 + MX53_PAD_EIM_D28__UART2_RTS 0x1e4 + MX53_PAD_EIM_D29__UART2_CTS 0x1e4 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx53-pinfunc.h b/arch/arm/boot/dts/imx53-pinfunc.h index aec406bc65eb..59f9c29e3fe2 100644 --- a/arch/arm/boot/dts/imx53-pinfunc.h +++ b/arch/arm/boot/dts/imx53-pinfunc.h @@ -524,6 +524,7 @@ #define MX53_PAD_EIM_D25__UART1_DSR 0x140 0x488 0x000 0x7 0x0 #define MX53_PAD_EIM_D26__EMI_WEIM_D_26 0x144 0x48c 0x000 0x0 0x0 #define MX53_PAD_EIM_D26__GPIO3_26 0x144 0x48c 0x000 0x1 0x0 +#define MX53_PAD_EIM_D26__UART2_RXD_MUX 0x144 0x48c 0x880 0x2 0x0 #define MX53_PAD_EIM_D26__UART2_TXD_MUX 0x144 0x48c 0x000 0x2 0x0 #define MX53_PAD_EIM_D26__FIRI_RXD 0x144 0x48c 0x80c 0x3 0x0 #define MX53_PAD_EIM_D26__IPU_CSI0_D_1 0x144 0x48c 0x000 0x4 0x0 @@ -533,6 +534,7 @@ #define MX53_PAD_EIM_D27__EMI_WEIM_D_27 0x148 0x490 0x000 0x0 0x0 #define MX53_PAD_EIM_D27__GPIO3_27 0x148 0x490 0x000 0x1 0x0 #define MX53_PAD_EIM_D27__UART2_RXD_MUX 0x148 0x490 0x880 0x2 0x1 +#define MX53_PAD_EIM_D27__UART2_TXD_MUX 0x148 0x490 0x000 0x2 0x0 #define MX53_PAD_EIM_D27__FIRI_TXD 0x148 0x490 0x000 0x3 0x0 #define MX53_PAD_EIM_D27__IPU_CSI0_D_0 0x148 0x490 0x000 0x4 0x0 #define MX53_PAD_EIM_D27__IPU_DI1_PIN13 0x148 0x490 0x000 0x5 0x0 @@ -541,6 +543,7 @@ #define MX53_PAD_EIM_D28__EMI_WEIM_D_28 0x14c 0x494 0x000 0x0 0x0 #define MX53_PAD_EIM_D28__GPIO3_28 0x14c 0x494 0x000 0x1 0x0 #define MX53_PAD_EIM_D28__UART2_CTS 0x14c 0x494 0x000 0x2 0x0 +#define MX53_PAD_EIM_D28__UART2_RTS 0x14c 0x494 0x87c 0x2 0x0 #define MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO 0x14c 0x494 0x82c 0x3 0x1 #define MX53_PAD_EIM_D28__CSPI_MOSI 0x14c 0x494 0x788 0x4 0x1 #define MX53_PAD_EIM_D28__I2C1_SDA 0x14c 0x494 0x818 0x5 0x1 @@ -548,6 +551,7 @@ #define MX53_PAD_EIM_D28__IPU_DI0_PIN13 0x14c 0x494 0x000 0x7 0x0 #define MX53_PAD_EIM_D29__EMI_WEIM_D_29 0x150 0x498 0x000 0x0 0x0 #define MX53_PAD_EIM_D29__GPIO3_29 0x150 0x498 0x000 0x1 0x0 +#define MX53_PAD_EIM_D29__UART2_CTS 0x150 0x498 0x000 0x2 0x0 #define MX53_PAD_EIM_D29__UART2_RTS 0x150 0x498 0x87c 0x2 0x1 #define MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS 0x150 0x498 0x000 0x3 0x0 #define MX53_PAD_EIM_D29__CSPI_SS0 0x150 0x498 0x78c 0x4 0x2 diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 2e516f4985e4..8bf0d89cdd35 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -433,6 +433,15 @@ clock-names = "ipg", "per"; }; + srtc: srtc@53fa4000 { + compatible = "fsl,imx53-rtc", "fsl,imx25-rtc"; + reg = <0x53fa4000 0x4000>; + interrupts = <24>; + interrupt-parent = <&tzic>; + clocks = <&clks IMX5_CLK_SRTC_GATE>; + clock-names = "ipg"; + }; + iomuxc: iomuxc@53fa8000 { compatible = "fsl,imx53-iomuxc"; reg = <0x53fa8000 0x4000>; diff --git a/arch/arm/boot/dts/imx6dl-gw52xx.dts b/arch/arm/boot/dts/imx6dl-gw52xx.dts index a2e0b73fdd4a..5f9f8948100d 100644 --- a/arch/arm/boot/dts/imx6dl-gw52xx.dts +++ b/arch/arm/boot/dts/imx6dl-gw52xx.dts @@ -17,3 +17,61 @@ model = "Gateworks Ventana i.MX6 DualLite/Solo GW52XX"; compatible = "gw,imx6dl-gw52xx", "gw,ventana", "fsl,imx6dl"; }; + +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi1_mux: endpoint { + remote-endpoint = <&ipu1_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi1_from_ipu1_csi1_mux { + bus-width = <8>; +}; + +&ipu1_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi1_mux>; + bus-width = <8>; +}; + +&ipu1_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu1_csi1: ipu1_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU1_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-gw53xx.dts b/arch/arm/boot/dts/imx6dl-gw53xx.dts index 6844b708d2f8..9bfc620d37bd 100644 --- a/arch/arm/boot/dts/imx6dl-gw53xx.dts +++ b/arch/arm/boot/dts/imx6dl-gw53xx.dts @@ -17,3 +17,61 @@ model = "Gateworks Ventana i.MX6 DualLite/Solo GW53XX"; compatible = "gw,imx6dl-gw53xx", "gw,ventana", "fsl,imx6dl"; }; + +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi1_mux: endpoint { + remote-endpoint = <&ipu1_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi1_from_ipu1_csi1_mux { + bus-width = <8>; +}; + +&ipu1_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi1_mux>; + bus-width = <8>; +}; + +&ipu1_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu1_csi1: ipu1_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU1_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-gw54xx.dts b/arch/arm/boot/dts/imx6dl-gw54xx.dts index be915412f852..b909bdf9a2ef 100644 --- a/arch/arm/boot/dts/imx6dl-gw54xx.dts +++ b/arch/arm/boot/dts/imx6dl-gw54xx.dts @@ -17,3 +17,61 @@ model = "Gateworks Ventana i.MX6 DualLite/Solo GW54XX"; compatible = "gw,imx6dl-gw54xx", "gw,ventana", "fsl,imx6dl"; }; + +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi1_mux: endpoint { + remote-endpoint = <&ipu1_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi1_from_ipu1_csi1_mux { + bus-width = <8>; +}; + +&ipu1_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi1_mux>; + bus-width = <8>; +}; + +&ipu1_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu1_csi1: ipu1_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU1_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU1_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU1_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU1_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU1_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU1_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU1_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU1_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU1_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU1_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU1_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts index 29b45f2e64e0..275c6c05219d 100644 --- a/arch/arm/boot/dts/imx6dl-riotboard.dts +++ b/arch/arm/boot/dts/imx6dl-riotboard.dts @@ -101,6 +101,51 @@ status = "okay"; }; +&gpio1 { + gpio-line-names = + "", "", "SD2_WP", "", "SD2_CD", "I2C3_SCL", + "I2C3_SDA", "I2C4_SCL", + "I2C4_SDA", "", "", "", "", "", "", "", + "", "PWM3", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio3 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "USB_OTG_VBUS", "", + "UART3_TXD", "UART3_RXD", "", "", "EIM_D28", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "", "UART4_TXD", "UART4_RXD", + "UART5_TXD", "UART5_RXD", "", "", "", "", "", "", + "GPIO4_16", "GPIO4_17", "GPIO4_18", "GPIO4_19", "", + "CSPI3_CLK", "CSPI3_MOSI", "CSPI3_MISO", + "CSPI3_CS0", "CSPI3_CS1", "GPIO4_26", "GPIO4_27", + "CSPI3_RDY", "PWM1", "PWM2", "GPIO4_31"; +}; + +&gpio5 { + gpio-line-names = + "", "", "EIM_A25", "", "", "GPIO5_05", "GPIO5_06", + "GPIO5_07", + "GPIO5_08", "CSPI2_CS1", "CSPI2_MOSI", "CSPI2_MISO", + "CSPI2_CS0", "CSPI2_CLK", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio7 { + gpio-line-names = + "SD3_CD", "SD3_WP", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + &hdmi { ddc-i2c-bus = <&i2c2>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6q-apalis-eval.dts b/arch/arm/boot/dts/imx6q-apalis-eval.dts new file mode 100644 index 000000000000..4bbfe3d61027 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-apalis-eval.dts @@ -0,0 +1,278 @@ +/* + * Copyright 2014-2017 Toradex AG + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include +#include +#include "imx6q.dtsi" +#include "imx6qdl-apalis.dtsi" + +/ { + model = "Toradex Apalis iMX6Q/D Module on Apalis Evaluation Board"; + compatible = "toradex,apalis_imx6q-eval", "toradex,apalis_imx6q", + "fsl,imx6q"; + + aliases { + i2c0 = &i2c1; + i2c1 = &i2c3; + i2c2 = &i2c2; + rtc0 = &rtc_i2c; + rtc1 = &snvs_rtc; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + wakeup { + label = "Wake-Up"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + }; + + lcd_display: display@di0 { + compatible = "fsl,imx-parallel-display"; + #address-cells = <1>; + #size-cells = <0>; + interface-pix-fmt = "rgb24"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_lcdif>; + status = "okay"; + + port@0 { + reg = <0>; + + lcd_display_in: endpoint { + remote-endpoint = <&ipu1_di1_disp1>; + }; + }; + + port@1 { + reg = <1>; + + lcd_display_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; + }; + + panel: panel { + /* + * edt,et057090dhu: EDT 5.7" LCD TFT + * edt,et070080dh6: EDT 7.0" LCD TFT + */ + compatible = "edt,et057090dhu"; + backlight = <&backlight>; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcd_display_out>; + }; + }; + }; + + reg_pcie_switch: regulator-pcie-switch { + compatible = "regulator-fixed"; + regulator-name = "pcie_switch"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>; + startup-delay-us = <100000>; + enable-active-high; + status = "okay"; + }; +}; + +&backlight { + brightness-levels = <0 127 191 223 239 247 251 255>; + default-brightness-level = <1>; + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&can2 { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ +&i2c1 { + status = "okay"; + + pcie-switch@58 { + compatible = "plx,pex8605"; + reg = <0x58>; + }; + + /* M41T0M6 real time clock on carrier board */ + rtc_i2c: rtc@68 { + compatible = "st,m41t00"; + reg = <0x68>; + }; +}; + +/* + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) + */ +&i2c3 { + status = "okay"; +}; + +&ipu1_di1_disp1 { + remote-endpoint = <&lcd_display_in>; +}; + +&ldb { + status = "okay"; +}; + +&pcie { + /* active-high meaning opposite of regular PERST# active-low polarity */ + reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; + reset-gpio-active-high; + vpcie-supply = <®_pcie_switch>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +®_usb_otg_vbus { + status = "okay"; +}; + +®_usb_host_vbus { + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&sound_spdif { + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&uart5 { + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + status = "okay"; +}; + +/* MMC1 */ +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit &pinctrl_mmc_cd>; + cd-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +/* SD1 */ +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_sd_cd>; + cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&iomuxc { + /* + * Mux the Apalis GPIOs + */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2 + &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4 + &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6 + &pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8 + >; +}; diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts new file mode 100644 index 000000000000..a35c7a54ad3b --- /dev/null +++ b/arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts @@ -0,0 +1,291 @@ +/* + * Copyright 2014-2017 Toradex AG + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include +#include +#include "imx6q.dtsi" +#include "imx6qdl-apalis.dtsi" + +/ { + model = "Toradex Apalis iMX6Q/D Module on Ixora Carrier Board V1.1"; + compatible = "toradex,apalis_imx6q-ixora-v1.1", + "toradex,apalis_imx6q-ixora", "toradex,apalis_imx6q", + "fsl,imx6q"; + + aliases { + i2c0 = &i2c1; + i2c1 = &i2c3; + i2c2 = &i2c2; + rtc0 = &rtc_i2c; + rtc1 = &snvs_rtc; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + wakeup { + label = "Wake-Up"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + }; + + lcd_display: display@di0 { + compatible = "fsl,imx-parallel-display"; + #address-cells = <1>; + #size-cells = <0>; + interface-pix-fmt = "rgb24"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_lcdif>; + status = "okay"; + + port@0 { + reg = <0>; + + lcd_display_in: endpoint { + remote-endpoint = <&ipu1_di1_disp1>; + }; + }; + + port@1 { + reg = <1>; + + lcd_display_out: endpoint { + remote-endpoint = <&lcd_panel_in>; + }; + }; + }; + + panel: panel { + /* + * edt,et057090dhu: EDT 5.7" LCD TFT + * edt,et070080dh6: EDT 7.0" LCD TFT + */ + compatible = "edt,et057090dhu"; + backlight = <&backlight>; + + port { + lcd_panel_in: endpoint { + remote-endpoint = <&lcd_display_out>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds_ixora>; + + led4-green { + label = "LED_4_GREEN"; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + + led4-red { + label = "LED_4_RED"; + gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>; + }; + + led5-green { + label = "LED_5_GREEN"; + gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + }; + + led5-red { + label = "LED_5_RED"; + gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&backlight { + brightness-levels = <0 127 191 223 239 247 251 255>; + default-brightness-level = <1>; + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&can2 { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ +&i2c1 { + status = "okay"; + + /* M41T0M6 real time clock on carrier board */ + rtc_i2c: rtc@68 { + compatible = "st,m41t00"; + reg = <0x68>; + }; +}; + +/* + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) + */ +&i2c3 { + status = "okay"; +}; + +&ipu1_di1_disp1 { + remote-endpoint = <&lcd_display_in>; +}; + +&ldb { + status = "okay"; +}; + +&pcie { + /* active-high meaning opposite of regular PERST# active-low polarity */ + reset-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; + reset-gpio-active-high; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +®_usb_otg_vbus { + status = "okay"; +}; + +®_usb_host_vbus { + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&sound_spdif { + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&uart5 { + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + status = "okay"; +}; + +/* MMC1 */ +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_mmc_cd>; + cd-gpios = <&gpio4 20 GPIO_ACTIVE_LOW>; + bus-width = <4>; + status = "okay"; +}; + +&iomuxc { + /* + * Mux the Apalis GPIOs + */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2 + &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4 + &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6 + &pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8 + >; + + pinctrl_leds_ixora: ledsixoragrp { + fsl,pins = < + MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0 + MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x1b0b0 + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts index 88cc7f51a4e9..60d33e99de76 100644 --- a/arch/arm/boot/dts/imx6q-apalis-ixora.dts +++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 Toradex AG + * Copyright 2014-2017 Toradex AG * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * @@ -55,13 +55,9 @@ "fsl,imx6q"; aliases { - i2c0 = &i2cddc; - i2c1 = &i2c1; + i2c0 = &i2c1; + i2c1 = &i2c3; i2c2 = &i2c2; - i2c3 = &i2c3; - }; - - aliases { rtc0 = &rtc_i2c; rtc1 = &snvs_rtc; }; @@ -164,15 +160,10 @@ }; &hdmi { - ddc-i2c-bus = <&i2cddc>; status = "okay"; }; -&i2cddc { - status = "okay"; -}; - -/* GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ &i2c1 { status = "okay"; @@ -188,6 +179,14 @@ }; }; +/* + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) + */ +&i2c3 { + status = "okay"; +}; + &ipu1_di1_disp1 { remote-endpoint = <&lcd_display_in>; }; @@ -268,16 +267,13 @@ /* SD1 */ &usdhc2 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sd_cd>; + pinctrl-0 = <&pinctrl_usdhc2 &pinctrl_sd_cd>; cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; status = "okay"; }; &iomuxc { - /* - * Mux the Apalis GPIOs - * GPIO5, 6 used by optional fusion_F0710A kernel module - */ + /* Mux the Apalis GPIOs */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2 &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4 diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts index 2c1e98e0cf7b..46bdc6722715 100644 --- a/arch/arm/boot/dts/imx6q-b850v3.dts +++ b/arch/arm/boot/dts/imx6q-b850v3.dts @@ -57,7 +57,7 @@ assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, - <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>; + <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>; assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clks IMX6QDL_CLK_PLL2_PFD2_396M>, diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi index c90b26f00e24..1015e55ca8f7 100644 --- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi +++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi @@ -111,6 +111,11 @@ }; &i2c1 { + pinctrl-names = "default", "gpio"; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + sda-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; + pca9547: mux@70 { compatible = "nxp,pca9547"; reg = <0x70>; @@ -261,6 +266,43 @@ }; }; +&i2c2 { + pinctrl-names = "default", "gpio"; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + sda-gpios = <&gpio4 13 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpio4 12 GPIO_ACTIVE_HIGH>; +}; + +&i2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-1 = <&pinctrl_i2c3_gpio>; + sda-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; +}; + +&iomuxc { + pinctrl_i2c1_gpio: i2c1gpiogrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26 0x1b0b0 + MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27 0x1b0b0 + >; + }; + + pinctrl_i2c2_gpio: i2c2gpiogrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x1b0b0 + MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x1b0b0 + >; + }; + + pinctrl_i2c3_gpio: i2c3gpiogrp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x1b0b0 + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1b0b0 + >; + }; +}; + &usdhc4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc4>; diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts index 1f0f950dc11e..e0aea782c666 100644 --- a/arch/arm/boot/dts/imx6q-evi.dts +++ b/arch/arm/boot/dts/imx6q-evi.dts @@ -94,6 +94,15 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1cs>; status = "okay"; + + fpga: fpga@0 { + compatible = "altr,fpga-passive-serial"; + spi-max-frequency = <20000000>; + reg = <0>; + pinctrl-0 = <&pinctrl_fpgaspi>; + nconfig-gpios = <&gpio4 9 GPIO_ACTIVE_LOW>; + nstat-gpios = <&gpio4 11 GPIO_ACTIVE_LOW>; + }; }; &ecspi3 { @@ -319,6 +328,13 @@ >; }; + pinctrl_fpgaspi: fpgaspigrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW1__GPIO4_IO09 0x1b0b0 + MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x1b0b0 + >; + }; + pinctrl_gpminand: gpminandgrp { fsl,pins = < MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 diff --git a/arch/arm/boot/dts/imx6q-gw52xx.dts b/arch/arm/boot/dts/imx6q-gw52xx.dts index a12c47e5ee05..0b8ae007ad73 100644 --- a/arch/arm/boot/dts/imx6q-gw52xx.dts +++ b/arch/arm/boot/dts/imx6q-gw52xx.dts @@ -18,6 +18,64 @@ compatible = "gw,imx6q-gw52xx", "gw,ventana", "fsl,imx6q"; }; +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu2_csi1_from_ipu2_csi1_mux { + bus-width = <8>; +}; + +&ipu2_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu2_csi1_mux>; + bus-width = <8>; +}; + +&ipu2_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu2_csi1>; +}; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu2_csi1: ipu2_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; + &sata { status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6q-gw53xx.dts b/arch/arm/boot/dts/imx6q-gw53xx.dts index d76aaa83dad0..a56ef77eff3f 100644 --- a/arch/arm/boot/dts/imx6q-gw53xx.dts +++ b/arch/arm/boot/dts/imx6q-gw53xx.dts @@ -18,6 +18,64 @@ compatible = "gw,imx6q-gw53xx", "gw,ventana", "fsl,imx6q"; }; +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu2_csi1_from_ipu2_csi1_mux { + bus-width = <8>; +}; + +&ipu2_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu2_csi1_mux>; + bus-width = <8>; +}; + +&ipu2_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu2_csi1>; +}; + &sata { status = "okay"; }; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu2_csi1: ipu2_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-gw54xx.dts b/arch/arm/boot/dts/imx6q-gw54xx.dts index 6e8f53e92a2d..56e5b5050fcf 100644 --- a/arch/arm/boot/dts/imx6q-gw54xx.dts +++ b/arch/arm/boot/dts/imx6q-gw54xx.dts @@ -18,6 +18,64 @@ compatible = "gw,imx6q-gw54xx", "gw,ventana", "fsl,imx6q"; }; +&i2c3 { + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu2_csi1_mux: endpoint { + remote-endpoint = <&ipu2_csi1_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu2_csi1_from_ipu2_csi1_mux { + bus-width = <8>; +}; + +&ipu2_csi1_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu2_csi1_mux>; + bus-width = <8>; +}; + +&ipu2_csi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu2_csi1>; +}; + &sata { status = "okay"; }; + +&iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x0001b0b0 + MX6QDL_PAD_EIM_D31__GPIO3_IO31 0x4001b0b0 + >; + }; + + pinctrl_ipu2_csi1: ipu2_csi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D16__IPU2_CSI1_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D18__IPU2_CSI1_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D19__IPU2_CSI1_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D20__IPU2_CSI1_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D26__IPU2_CSI1_DATA14 0x1b0b0 + MX6QDL_PAD_EIM_D27__IPU2_CSI1_DATA13 0x1b0b0 + MX6QDL_PAD_EIM_A17__IPU2_CSI1_DATA12 0x1b0b0 + MX6QDL_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x1b0b0 + MX6QDL_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x1b0b0 + MX6QDL_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi index ba01dd76d887..ea339fa58f4a 100644 --- a/arch/arm/boot/dts/imx6qdl-apalis.dtsi +++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 Toradex AG + * Copyright 2014-2017 Toradex AG * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * @@ -56,18 +56,6 @@ status = "disabled"; }; - /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */ - i2cddc: i2c@0 { - compatible = "i2c-gpio"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c_ddc>; - gpios = <&gpio3 16 GPIO_ACTIVE_HIGH /* sda */ - &gpio2 30 GPIO_ACTIVE_HIGH /* scl */ - >; - i2c-gpio,delay-us = <2>; /* ~100 kHz */ - status = "disabled"; - }; - reg_1p8v: regulator-1p8v { compatible = "regulator-fixed"; regulator-name = "1P8V"; @@ -210,10 +198,13 @@ }; }; -/* - * GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier - * board) - */ +&hdmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hdmi_ddc>; + status = "disabled"; +}; + +/* I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ &i2c1 { clock-frequency = <100000>; pinctrl-names = "default"; @@ -374,7 +365,8 @@ }; /* - * GEN2_I2C, CAM: I2C3_SDA/SCL on MXM3 201/203 (unused) + * I2C3_SDA/SCL (CAM) on MXM3 pin 201/203 (e.g. camera sensor on carrier + * board) */ &i2c3 { clock-frequency = <100000>; @@ -460,7 +452,7 @@ /* MMC1 */ &usdhc1 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-0 = <&pinctrl_usdhc1_4bit &pinctrl_usdhc1_8bit>; vqmmc-supply = <®_3p3v>; bus-width = <8>; voltage-ranges = <3300 3300>; @@ -640,11 +632,10 @@ >; }; - pinctrl_i2c_ddc: gpioi2cddcgrp { + pinctrl_hdmi_ddc: hdmiddcgrp { fsl,pins = < - /* DDC bitbang */ - MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 - MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0 + MX6QDL_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x4001b8b1 >; }; @@ -912,7 +903,7 @@ >; }; - pinctrl_usdhc1: usdhc1grp { + pinctrl_usdhc1_4bit: usdhc1grp_4bit { fsl,pins = < MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071 @@ -920,6 +911,11 @@ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + >; + }; + + pinctrl_usdhc1_8bit: usdhc1grp_8bit { + fsl,pins = < MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17071 MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17071 MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17071 diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi index d78312c63672..ebe7a8bddf04 100644 --- a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi +++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include / { diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi index e8c1edc82e6e..885556260bd0 100644 --- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi @@ -231,6 +231,37 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; + + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio5>; + interrupts = <23 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi0_from_ipu1_csi0_mux { + bus-width = <8>; +}; + +&ipu1_csi0_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi0_mux>; + bus-width = <8>; +}; + +&ipu1_csi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi0>; }; &pcie { @@ -302,6 +333,13 @@ &iomuxc { imx6qdl-gw51xx { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x0001b0b0 + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x4001b0b0 + >; + }; + pinctrl_enet: enetgrp { fsl,pins = < MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 @@ -372,6 +410,22 @@ >; }; + pinctrl_ipu1_csi0: ipu1csi0grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0 + >; + }; + pinctrl_pcie: pciegrp { fsl,pins = < MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 91991d63a69c..115d706228ef 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -377,7 +377,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi index 5bc6ed1a5b35..24be7965056c 100644 --- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi @@ -368,7 +368,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi index 66fcf838e964..4594b2279169 100644 --- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi @@ -416,7 +416,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi index 57374dddf98d..1a0faa1a14c8 100644 --- a/arch/arm/boot/dts/imx6qdl-gw553x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw553x.dtsi @@ -261,6 +261,37 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; + + adv7180: camera@20 { + compatible = "adi,adv7180"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adv7180>; + reg = <0x20>; + powerdown-gpios = <&gpio5 20 GPIO_ACTIVE_LOW>; + interrupt-parent = <&gpio5>; + interrupts = <23 IRQ_TYPE_LEVEL_LOW>; + + port { + adv7180_to_ipu1_csi0_mux: endpoint { + remote-endpoint = <&ipu1_csi0_mux_from_parallel_sensor>; + bus-width = <8>; + }; + }; + }; +}; + +&ipu1_csi0_from_ipu1_csi0_mux { + bus-width = <8>; +}; + +&ipu1_csi0_mux_from_parallel_sensor { + remote-endpoint = <&adv7180_to_ipu1_csi0_mux>; + bus-width = <8>; +}; + +&ipu1_csi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ipu1_csi0>; }; &pcie { @@ -340,6 +371,13 @@ }; &iomuxc { + pinctrl_adv7180: adv7180grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT5__GPIO5_IO23 0x0001b0b0 + MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x4001b0b0 + >; + }; + pinctrl_gpmi_nand: gpminandgrp { fsl,pins = < MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 @@ -387,6 +425,22 @@ >; }; + pinctrl_ipu1_csi0: ipu1csi0grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x1b0b0 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x1b0b0 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x1b0b0 + >; + }; + pinctrl_gpio_leds: gpioledsgrp { fsl,pins = < MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0 diff --git a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi index 5fab5be414fe..7ca291e9dbdb 100644 --- a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi +++ b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi @@ -184,7 +184,6 @@ }; &ssi1 { - fsl,mode = "i2s-slave"; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi index f22e5879340b..d309a4d0eb08 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi @@ -108,6 +108,18 @@ startup-delay-us = <70000>; enable-active-high; }; + + reg_usb_h1_vbus: regulator@5 { + compatible = "regulator-fixed"; + reg = <5>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; gpio-keys { @@ -515,6 +527,12 @@ >; }; + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x030b0 + >; + }; + pinctrl_usbotg: usbotggrp { fsl,pins = < MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 @@ -629,6 +647,7 @@ }; &usbh1 { + vbus-supply = <®_usb_h1_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi index afe7449c47da..756c5054f047 100644 --- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi @@ -123,6 +123,18 @@ regulator-max-microvolt = <2800000>; regulator-always-on; }; + + reg_usb_h1_vbus: regulator@7 { + compatible = "regulator-fixed"; + reg = <7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; mipi_xclk: mipi_xclk { @@ -610,6 +622,12 @@ >; }; + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x030b0 + >; + }; + pinctrl_usbotg: usbotggrp { fsl,pins = < MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 @@ -705,6 +723,7 @@ }; &usbh1 { + vbus-supply = <®_usb_h1_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi index 5d94b5ee6aa0..eeb7679fd348 100644 --- a/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi +++ b/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi @@ -59,6 +59,14 @@ pinctrl-0 = <&pinctrl_mdio1>; gpios = <&gpio6 5 GPIO_ACTIVE_HIGH &gpio6 4 GPIO_ACTIVE_HIGH>; + + phy: ethernet-phy@0 { + pinctrl-0 = <&pinctrl_rmii_phy_irq>; + pinctrl-names = "default"; + reg = <0>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + }; }; reg_28p0v: regulator-28p0v { @@ -615,14 +623,106 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rmii"; + phy-handle = <&phy>; phy-reset-gpios = <&gpio1 23 GPIO_ACTIVE_LOW>; phy-reset-duration = <100>; phy-supply = <®_3p3v>; status = "okay"; - fixed-link { - speed = <100>; - full-duplex; + mdio { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + switch: switch@0 { + compatible = "marvell,mv88e6085"; + pinctrl-0 = <&pinctrl_switch_irq>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + dsa,member = <0 0>; + eeprom-length = <512>; + interrupt-parent = <&gpio6>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + label = "gigabit_proc"; + phy-handle = <&switchphy0>; + }; + + port@1 { + reg = <1>; + label = "netaux"; + phy-handle = <&switchphy1>; + }; + + port@2 { + reg = <2>; + label = "cpu"; + ethernet = <&fec>; + + fixed-link { + speed = <100>; + full-duplex; + }; + }; + + port@3 { + reg = <3>; + label = "netright"; + phy-handle = <&switchphy3>; + }; + + port@4 { + reg = <4>; + label = "netleft"; + phy-handle = <&switchphy4>; + }; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + switchphy0: switchphy@0 { + reg = <0>; + interrupt-parent = <&switch>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy1: switchphy@1 { + reg = <1>; + interrupt-parent = <&switch>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy2: switchphy@2 { + reg = <2>; + interrupt-parent = <&switch>; + interrupts = <2 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy3: switchphy@3 { + reg = <3>; + interrupt-parent = <&switch>; + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; + }; + + switchphy4: switchphy@4 { + reg = <4>; + interrupt-parent = <&switch>; + interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + }; }; }; @@ -840,6 +940,12 @@ >; }; + pinctrl_switch_irq: switchgrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03 0x4001b000 + >; + }; + pinctrl_tc358767: tc358767grp { fsl,pins = < MX6QDL_PAD_GPIO_9__GPIO1_IO09 0x10 diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index a9723b94bafa..8884b4a3cafb 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -769,6 +769,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 3243af4a9984..3f76f980947e 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -655,6 +655,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index f16b9df9d0c6..6c7eb54be9e2 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -710,6 +710,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts index d2be8aa3370b..9c23e017d86a 100644 --- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts +++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts @@ -22,7 +22,7 @@ reg = <0x80000000 0x20000000>; }; - backlight { + backlight_display: backlight-display { compatible = "pwm-backlight"; pwms = <&pwm1 0 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; @@ -78,6 +78,17 @@ clocks = <&clks IMX6UL_CLK_SAI2>; }; }; + + panel { + compatible = "innolux,at043tn24"; + backlight = <&backlight_display>; + + port { + panel_in: endpoint { + remote-endpoint = <&display_out>; + }; + }; + }; }; &clks { @@ -139,31 +150,11 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; - display = <&display0>; status = "okay"; - display0: display { - bits-per-pixel = <16>; - bus-width = <24>; - - display-timings { - native-mode = <&timing0>; - - timing0: timing0 { - clock-frequency = <9200000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <8>; - hback-porch = <4>; - hsync-len = <41>; - vback-porch = <2>; - vfront-porch = <4>; - vsync-len = <10>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; + port { + display_out: endpoint { + remote-endpoint = <&panel_in>; }; }; }; @@ -316,7 +307,6 @@ MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0 MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0 MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031 - MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x17059 >; }; diff --git a/arch/arm/boot/dts/imx6ul-geam.dtsi b/arch/arm/boot/dts/imx6ul-geam.dts similarity index 87% rename from arch/arm/boot/dts/imx6ul-geam.dtsi rename to arch/arm/boot/dts/imx6ul-geam.dts index eb94d956808b..571eea7f1c6b 100644 --- a/arch/arm/boot/dts/imx6ul-geam.dtsi +++ b/arch/arm/boot/dts/imx6ul-geam.dts @@ -40,11 +40,16 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +/dts-v1/; + #include #include #include "imx6ul.dtsi" / { + model = "Engicam GEAM6UL Starter Kit"; + compatible = "engicam,imx6ul-geam", "fsl,imx6ul"; + memory { reg = <0x80000000 0x08000000>; }; @@ -87,18 +92,46 @@ regulator-always-on; regulator-boot-on; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6ul-geam-sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&sgtl5000>; + clocks = <&clks IMX6UL_CLK_SAI2>; + }; + }; }; &can1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexcan1>; xceiver-supply = <®_3p3v>; + status = "okay"; }; &can2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_flexcan2>; xceiver-supply = <®_3p3v>; + status = "okay"; }; &fec1 { @@ -144,6 +177,16 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6UL_CLK_OSC>; + clock-names = "mclk"; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + VDDD-supply = <®_1p8v>; + }; }; &i2c2 { @@ -158,6 +201,31 @@ pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <16>; + bus-width = <18>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <28000000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <30>; + hback-porch = <30>; + hsync-len = <64>; + vback-porch = <5>; + vfront-porch = <5>; + vsync-len = <20>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; }; &pwm8 { @@ -178,6 +246,12 @@ status = "okay"; }; +&tsc { + measure-delay-time = <0x1ffff>; + pre-charge-time = <0x1fff>; + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; diff --git a/arch/arm/boot/dts/imx6ul-isiot-common.dtsi b/arch/arm/boot/dts/imx6ul-isiot-common.dtsi deleted file mode 100644 index 2beaab6e272e..000000000000 --- a/arch/arm/boot/dts/imx6ul-isiot-common.dtsi +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2016 Amarula Solutions B.V. - * Copyright (C) 2016 Engicam S.r.l. - * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -&i2c1 { - stmpe811: gpio-expander@44 { - compatible = "st,stmpe811"; - reg = <0x44>; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_stmpe>; - interrupt-parent = <&gpio1>; - interrupts = <18 IRQ_TYPE_EDGE_FALLING>; - interrupt-controller; - #interrupt-cells = <2>; - - stmpe: touchscreen { - compatible = "st,stmpe-ts"; - st,sample-time = <4>; - st,mod-12b = <1>; - st,ref-sel = <0>; - st,adc-freq = <1>; - st,ave-ctrl = <1>; - st,touch-det-delay = <2>; - st,settling = <2>; - st,fraction-z = <7>; - st,i-drive = <1>; - }; - }; -}; - -&lcdif { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_lcdif_dat - &pinctrl_lcdif_ctrl>; - display = <&display0>; - status = "okay"; - - display0: display { - bits-per-pixel = <16>; - bus-width = <18>; - - display-timings { - native-mode = <&timing0>; - timing0: timing0 { - clock-frequency = <28000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <30>; - hback-porch = <30>; - hsync-len = <64>; - vback-porch = <5>; - vfront-porch = <5>; - vsync-len = <20>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; - }; - }; -}; - -&iomuxc { - pinctrl_lcdif_ctrl: lcdifctrlgrp { - fsl,pins = < - MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 - MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 - MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 - MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 - >; - }; - - pinctrl_lcdif_dat: lcdifdatgrp { - fsl,pins = < - MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 - MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 - MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 - MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 - MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 - MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 - MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 - MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 - MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 - MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 - MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 - MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 - MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 - MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 - MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 - MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 - MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 - MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 - >; - }; - - pinctrl_stmpe: stmpegrp { - fsl,pins = < - MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x1b0b0 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx6ul-isiot-emmc.dts b/arch/arm/boot/dts/imx6ul-isiot-emmc.dts index 73a1d0f0b9d5..f5b422898e61 100644 --- a/arch/arm/boot/dts/imx6ul-isiot-emmc.dts +++ b/arch/arm/boot/dts/imx6ul-isiot-emmc.dts @@ -43,7 +43,6 @@ /dts-v1/; #include "imx6ul-isiot.dtsi" -#include "imx6ul-isiot-common.dtsi" / { model = "Engicam Is.IoT MX6UL eMMC Starter kit"; diff --git a/arch/arm/boot/dts/imx6ul-isiot-nand.dts b/arch/arm/boot/dts/imx6ul-isiot-nand.dts index da29a86eb6a8..de15e1c75dd1 100644 --- a/arch/arm/boot/dts/imx6ul-isiot-nand.dts +++ b/arch/arm/boot/dts/imx6ul-isiot-nand.dts @@ -43,7 +43,6 @@ /dts-v1/; #include "imx6ul-isiot.dtsi" -#include "imx6ul-isiot-common.dtsi" / { model = "Engicam Is.IoT MX6UL NAND Starter kit"; diff --git a/arch/arm/boot/dts/imx6ul-isiot.dtsi b/arch/arm/boot/dts/imx6ul-isiot.dtsi index ea30380ad7a4..950fb28b630a 100644 --- a/arch/arm/boot/dts/imx6ul-isiot.dtsi +++ b/arch/arm/boot/dts/imx6ul-isiot.dtsi @@ -69,6 +69,68 @@ 100>; default-brightness-level = <100>; }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6ul-isiot-sgtl5000"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&sgtl5000>; + clocks = <&clks IMX6UL_CLK_SAI2>; + }; + }; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet1>; + phy-mode = "rmii"; + phy-handle = <ðphy0>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + }; }; &i2c1 { @@ -76,6 +138,42 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6UL_CLK_OSC>; + clock-names = "mclk"; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + VDDD-supply = <®_1p8v>; + }; + + stmpe811: gpio-expander@44 { + compatible = "st,stmpe811"; + reg = <0x44>; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_stmpe>; + interrupt-parent = <&gpio1>; + interrupts = <18 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <2>; + + stmpe: touchscreen { + compatible = "st,stmpe-ts"; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; + st,fraction-z = <7>; + st,i-drive = <1>; + }; + }; }; &i2c2 { @@ -85,6 +183,38 @@ status = "okay"; }; +&lcdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcdif_dat + &pinctrl_lcdif_ctrl>; + display = <&display0>; + status = "okay"; + + display0: display { + bits-per-pixel = <16>; + bus-width = <18>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <28000000>; + hactive = <800>; + vactive = <480>; + hfront-porch = <30>; + hback-porch = <30>; + hsync-len = <64>; + vback-porch = <5>; + vfront-porch = <5>; + vsync-len = <20>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + }; +}; + &pwm8 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm8>; @@ -115,6 +245,21 @@ }; &iomuxc { + pinctrl_enet1: enet1grp { + fsl,pins = < + MX6UL_PAD_ENET2_RX_DATA0__ENET1_MDIO 0x1b0b0 + MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC 0x1b0b0 + MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0 + MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0 + MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0 + MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0 + MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0 + MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0 + MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b031 + MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10 0x1b0b0 + >; + }; + pinctrl_i2c1: i2c1grp { fsl,pins = < MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 @@ -129,6 +274,38 @@ >; }; + pinctrl_lcdif_ctrl: lcdifctrlgrp { + fsl,pins = < + MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 + MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 + MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 + MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 + >; + }; + + pinctrl_lcdif_dat: lcdifdatgrp { + fsl,pins = < + MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 + MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 + MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 + MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 + MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 + MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 + MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 + MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 + MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 + MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 + MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 + MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 + MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 + MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 + MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 + MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 + MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 + MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 + >; + }; + pinctrl_pwm8: pwm8grp { fsl,pins = < MX6UL_PAD_ENET1_RX_ER__PWM8_OUT 0x110b0 @@ -145,6 +322,12 @@ >; }; + pinctrl_stmpe: stmpegrp { + fsl,pins = < + MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x1b0b0 + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1 diff --git a/arch/arm/boot/dts/imx6ul-liteboard.dts b/arch/arm/boot/dts/imx6ul-liteboard.dts index ed1d891d6a89..1d863a16bcf0 100644 --- a/arch/arm/boot/dts/imx6ul-liteboard.dts +++ b/arch/arm/boot/dts/imx6ul-liteboard.dts @@ -124,6 +124,10 @@ }; }; +&snvs_poweroff { + status = "okay"; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index 6da2b77edd46..f11a241a340d 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -614,6 +614,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi index d7753f79937a..0a3915868aa3 100644 --- a/arch/arm/boot/dts/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/imx7-colibri.dtsi @@ -106,6 +106,15 @@ fsl,magic-packet; }; +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + fsl,use-minimum-ecc; + nand-on-flash-bbt; + nand-ecc-mode = "hw"; + status = "okay"; +}; + &i2c1 { clock-frequency = <100000>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index 0a24d1bf3c39..44637cabcc56 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -117,6 +117,37 @@ regulator-max-microvolt = <3300000>; startup-delay-us = <200000>; }; + + reg_lcd_3v3: regulator-lcd-3v3 { + compatible = "regulator-fixed"; + regulator-name = "lcd-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&extended_io 7 GPIO_ACTIVE_LOW>; + }; + + reg_can2_3v3: regulator-can2-3v3 { + compatible = "regulator-fixed"; + regulator-name = "can2-3v3"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2_reg>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 14 GPIO_ACTIVE_LOW>; + }; + + panel { + compatible = "innolux,at043tn24"; + pinctrl-0 = <&pinctrl_backlight>; + enable-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>; + power-supply = <®_lcd_3v3>; + + port { + panel_in: endpoint { + remote-endpoint = <&display_out>; + }; + }; + }; }; &adc1 { @@ -168,6 +199,7 @@ phy-mode = "rgmii"; phy-handle = <ðphy0>; fsl,magic-packet; + phy-reset-gpios = <&extended_io 5 GPIO_ACTIVE_LOW>; status = "okay"; mdio { @@ -197,6 +229,13 @@ status = "okay"; }; +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + xceiver-supply = <®_can2_3v3>; + status = "okay"; +}; + &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; @@ -285,8 +324,8 @@ }; vgen6_reg: vldo4 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; regulator-always-on; }; }; @@ -322,31 +361,11 @@ &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif>; - display = <&display0>; status = "okay"; - display0: display { - bits-per-pixel = <16>; - bus-width = <24>; - - display-timings { - native-mode = <&timing0>; - - timing0: timing0 { - clock-frequency = <9200000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <8>; - hback-porch = <4>; - hsync-len = <41>; - vback-porch = <2>; - vfront-porch = <4>; - vsync-len = <10>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; + port { + display_out: endpoint { + remote-endpoint = <&panel_in>; }; }; }; @@ -356,12 +375,6 @@ status = "okay"; }; -&pwm1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm1>; - status = "okay"; -}; - &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -488,6 +501,20 @@ >; }; + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x59 + MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x59 + >; + }; + + pinctrl_flexcan2_reg: flexcan2reggrp { + fsl,pins = < + MX7D_PAD_EPDC_DATA14__GPIO2_IO14 0x59 /* CAN_STBY */ + >; + }; + + pinctrl_hog: hoggrp { fsl,pins = < MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14 @@ -701,9 +728,9 @@ >; }; - pinctrl_pwm1: pwm1grp { + pinctrl_backlight: backlightgrp { fsl,pins = < - MX7D_PAD_LPSR_GPIO1_IO01__PWM1_OUT 0x110b0 + MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x110b0 >; }; }; diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi index f46814a7ea44..4d308d17f040 100644 --- a/arch/arm/boot/dts/imx7d.dtsi +++ b/arch/arm/boot/dts/imx7d.dtsi @@ -144,10 +144,10 @@ interrupt-names = "msi"; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0x7>; - interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>, <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>, <&clks IMX7D_PCIE_PHY_ROOT_CLK>; diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi index 4cf6c458b583..82ad26e766eb 100644 --- a/arch/arm/boot/dts/imx7s.dtsi +++ b/arch/arm/boot/dts/imx7s.dtsi @@ -540,6 +540,7 @@ compatible = "syscon-poweroff"; regmap = <&snvs>; offset = <0x38>; + value = <0x60>; mask = <0x60>; }; @@ -1021,5 +1022,36 @@ status = "disabled"; }; }; + + dma_apbh: dma-apbh@33000000 { + compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh"; + reg = <0x33000000 0x2000>; + interrupts = , + , + , + ; + interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; + }; + + gpmi: gpmi-nand@33002000{ + compatible = "fsl,imx7d-gpmi-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x33002000 0x2000>, <0x33004000 0x4000>; + reg-names = "gpmi-nand", "bch"; + interrupts = ; + interrupt-names = "bch"; + clocks = <&clks IMX7D_NAND_RAWNAND_CLK>, + <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; + clock-names = "gpmi_io", "gpmi_bch_apb"; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; + status = "disabled"; + assigned-clocks = <&clks IMX7D_NAND_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_500M_CLK>; + }; }; }; diff --git a/arch/arm/boot/dts/imx7ulp-pinfunc.h b/arch/arm/boot/dts/imx7ulp-pinfunc.h new file mode 100644 index 000000000000..fe511775b518 --- /dev/null +++ b/arch/arm/boot/dts/imx7ulp-pinfunc.h @@ -0,0 +1,468 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef __DTS_IMX7ULP_PINFUNC_H +#define __DTS_IMX7ULP_PINFUNC_H + +/* + * The pin function ID is a tuple of + * + */ + +#define IMX7ULP_PAD_PTC0__PTC0 0x0000 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC0__TRACE_D15 0x0000 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC0__LPUART4_CTS_B 0x0000 0x0244 0x4 0x1 +#define IMX7ULP_PAD_PTC0__LPI2C4_SCL 0x0000 0x0278 0x5 0x1 +#define IMX7ULP_PAD_PTC0__TPM4_CLKIN 0x0000 0x0298 0x6 0x1 +#define IMX7ULP_PAD_PTC0__FB_AD0 0x0000 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC1__PTC1 0x0004 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC1__TRACE_D14 0x0004 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC1__LPUART4_RTS_B 0x0004 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC1__LPI2C4_SDA 0x0004 0x027c 0x5 0x1 +#define IMX7ULP_PAD_PTC1__TPM4_CH0 0x0004 0x0280 0x6 0x1 +#define IMX7ULP_PAD_PTC1__FB_AD1 0x0004 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC2__PTC2 0x0008 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC2__TRACE_D13 0x0008 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC2__LPUART4_TX 0x0008 0x024c 0x4 0x1 +#define IMX7ULP_PAD_PTC2__LPI2C4_HREQ 0x0008 0x0274 0x5 0x1 +#define IMX7ULP_PAD_PTC2__TPM4_CH1 0x0008 0x0284 0x6 0x1 +#define IMX7ULP_PAD_PTC2__FB_AD2 0x0008 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC3__PTC3 0x000c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC3__TRACE_D12 0x000c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC3__LPUART4_RX 0x000c 0x0248 0x4 0x1 +#define IMX7ULP_PAD_PTC3__TPM4_CH2 0x000c 0x0288 0x6 0x1 +#define IMX7ULP_PAD_PTC3__FB_AD3 0x000c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC4__PTC4 0x0010 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC4__TRACE_D11 0x0010 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC4__FXIO1_D0 0x0010 0x0204 0x2 0x1 +#define IMX7ULP_PAD_PTC4__LPSPI2_PCS1 0x0010 0x02a0 0x3 0x1 +#define IMX7ULP_PAD_PTC4__LPUART5_CTS_B 0x0010 0x0250 0x4 0x1 +#define IMX7ULP_PAD_PTC4__LPI2C5_SCL 0x0010 0x02bc 0x5 0x1 +#define IMX7ULP_PAD_PTC4__TPM4_CH3 0x0010 0x028c 0x6 0x1 +#define IMX7ULP_PAD_PTC4__FB_AD4 0x0010 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC5__PTC5 0x0014 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC5__TRACE_D10 0x0014 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC5__FXIO1_D1 0x0014 0x0208 0x2 0x1 +#define IMX7ULP_PAD_PTC5__LPSPI2_PCS2 0x0014 0x02a4 0x3 0x1 +#define IMX7ULP_PAD_PTC5__LPUART5_RTS_B 0x0014 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC5__LPI2C5_SDA 0x0014 0x02c0 0x5 0x1 +#define IMX7ULP_PAD_PTC5__TPM4_CH4 0x0014 0x0290 0x6 0x1 +#define IMX7ULP_PAD_PTC5__FB_AD5 0x0014 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC6__PTC6 0x0018 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC6__TRACE_D9 0x0018 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC6__FXIO1_D2 0x0018 0x020c 0x2 0x1 +#define IMX7ULP_PAD_PTC6__LPSPI2_PCS3 0x0018 0x02a8 0x3 0x1 +#define IMX7ULP_PAD_PTC6__LPUART5_TX 0x0018 0x0258 0x4 0x1 +#define IMX7ULP_PAD_PTC6__LPI2C5_HREQ 0x0018 0x02b8 0x5 0x1 +#define IMX7ULP_PAD_PTC6__TPM4_CH5 0x0018 0x0294 0x6 0x1 +#define IMX7ULP_PAD_PTC6__FB_AD6 0x0018 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC7__PTC7 0x001c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC7__TRACE_D8 0x001c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC7__FXIO1_D3 0x001c 0x0210 0x2 0x1 +#define IMX7ULP_PAD_PTC7__LPUART5_RX 0x001c 0x0254 0x4 0x1 +#define IMX7ULP_PAD_PTC7__TPM5_CH1 0x001c 0x02c8 0x6 0x1 +#define IMX7ULP_PAD_PTC7__FB_AD7 0x001c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC8__PTC8 0x0020 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC8__TRACE_D7 0x0020 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC8__FXIO1_D4 0x0020 0x0214 0x2 0x1 +#define IMX7ULP_PAD_PTC8__LPSPI2_SIN 0x0020 0x02b0 0x3 0x1 +#define IMX7ULP_PAD_PTC8__LPUART6_CTS_B 0x0020 0x025c 0x4 0x1 +#define IMX7ULP_PAD_PTC8__LPI2C6_SCL 0x0020 0x02fc 0x5 0x1 +#define IMX7ULP_PAD_PTC8__TPM5_CLKIN 0x0020 0x02cc 0x6 0x1 +#define IMX7ULP_PAD_PTC8__FB_AD8 0x0020 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC9__PTC9 0x0024 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC9__TRACE_D6 0x0024 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC9__FXIO1_D5 0x0024 0x0218 0x2 0x1 +#define IMX7ULP_PAD_PTC9__LPSPI2_SOUT 0x0024 0x02b4 0x3 0x1 +#define IMX7ULP_PAD_PTC9__LPUART6_RTS_B 0x0024 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC9__LPI2C6_SDA 0x0024 0x0300 0x5 0x1 +#define IMX7ULP_PAD_PTC9__TPM5_CH0 0x0024 0x02c4 0x6 0x1 +#define IMX7ULP_PAD_PTC9__FB_AD9 0x0024 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC10__PTC10 0x0028 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC10__TRACE_D5 0x0028 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC10__FXIO1_D6 0x0028 0x021c 0x2 0x1 +#define IMX7ULP_PAD_PTC10__LPSPI2_SCK 0x0028 0x02ac 0x3 0x1 +#define IMX7ULP_PAD_PTC10__LPUART6_TX 0x0028 0x0264 0x4 0x1 +#define IMX7ULP_PAD_PTC10__LPI2C6_HREQ 0x0028 0x02f8 0x5 0x1 +#define IMX7ULP_PAD_PTC10__TPM7_CH3 0x0028 0x02e8 0x6 0x1 +#define IMX7ULP_PAD_PTC10__FB_AD10 0x0028 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC11__PTC11 0x002c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC11__TRACE_D4 0x002c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC11__FXIO1_D7 0x002c 0x0220 0x2 0x1 +#define IMX7ULP_PAD_PTC11__LPSPI2_PCS0 0x002c 0x029c 0x3 0x1 +#define IMX7ULP_PAD_PTC11__LPUART6_RX 0x002c 0x0260 0x4 0x1 +#define IMX7ULP_PAD_PTC11__TPM7_CH4 0x002c 0x02ec 0x6 0x1 +#define IMX7ULP_PAD_PTC11__FB_AD11 0x002c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC12__PTC12 0x0030 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC12__TRACE_D3 0x0030 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC12__FXIO1_D8 0x0030 0x0224 0x2 0x1 +#define IMX7ULP_PAD_PTC12__LPSPI3_PCS1 0x0030 0x0314 0x3 0x1 +#define IMX7ULP_PAD_PTC12__LPUART7_CTS_B 0x0030 0x0268 0x4 0x1 +#define IMX7ULP_PAD_PTC12__LPI2C7_SCL 0x0030 0x0308 0x5 0x1 +#define IMX7ULP_PAD_PTC12__TPM7_CH5 0x0030 0x02f0 0x6 0x1 +#define IMX7ULP_PAD_PTC12__FB_AD12 0x0030 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC13__PTC13 0x0034 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC13__TRACE_D2 0x0034 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC13__FXIO1_D9 0x0034 0x0228 0x2 0x1 +#define IMX7ULP_PAD_PTC13__LPSPI3_PCS2 0x0034 0x0318 0x3 0x1 +#define IMX7ULP_PAD_PTC13__LPUART7_RTS_B 0x0034 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTC13__LPI2C7_SDA 0x0034 0x030c 0x5 0x1 +#define IMX7ULP_PAD_PTC13__TPM7_CLKIN 0x0034 0x02f4 0x6 0x1 +#define IMX7ULP_PAD_PTC13__FB_AD13 0x0034 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC14__PTC14 0x0038 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC14__TRACE_D1 0x0038 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC14__FXIO1_D10 0x0038 0x022c 0x2 0x1 +#define IMX7ULP_PAD_PTC14__LPSPI3_PCS3 0x0038 0x031c 0x3 0x1 +#define IMX7ULP_PAD_PTC14__LPUART7_TX 0x0038 0x0270 0x4 0x1 +#define IMX7ULP_PAD_PTC14__LPI2C7_HREQ 0x0038 0x0304 0x5 0x1 +#define IMX7ULP_PAD_PTC14__TPM7_CH0 0x0038 0x02dc 0x6 0x1 +#define IMX7ULP_PAD_PTC14__FB_AD14 0x0038 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC15__PTC15 0x003c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC15__TRACE_D0 0x003c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC15__FXIO1_D11 0x003c 0x0230 0x2 0x1 +#define IMX7ULP_PAD_PTC15__LPUART7_RX 0x003c 0x026c 0x4 0x1 +#define IMX7ULP_PAD_PTC15__TPM7_CH1 0x003c 0x02e0 0x6 0x1 +#define IMX7ULP_PAD_PTC15__FB_AD15 0x003c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC16__PTC16 0x0040 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC16__TRACE_CLKOUT 0x0040 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTC16__FXIO1_D12 0x0040 0x0234 0x2 0x1 +#define IMX7ULP_PAD_PTC16__LPSPI3_SIN 0x0040 0x0324 0x3 0x1 +#define IMX7ULP_PAD_PTC16__TPM7_CH2 0x0040 0x02e4 0x6 0x1 +#define IMX7ULP_PAD_PTC16__FB_ALE_FB_CS1_B_FB_TS_B 0x0040 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC17__PTC17 0x0044 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC17__FXIO1_D13 0x0044 0x0238 0x2 0x1 +#define IMX7ULP_PAD_PTC17__LPSPI3_SOUT 0x0044 0x0328 0x3 0x1 +#define IMX7ULP_PAD_PTC17__TPM6_CLKIN 0x0044 0x02d8 0x6 0x1 +#define IMX7ULP_PAD_PTC17__FB_CS0_B 0x0044 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC18__PTC18 0x0048 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC18__FXIO1_D14 0x0048 0x023c 0x2 0x1 +#define IMX7ULP_PAD_PTC18__LPSPI3_SCK 0x0048 0x0320 0x3 0x1 +#define IMX7ULP_PAD_PTC18__TPM6_CH0 0x0048 0x02d0 0x6 0x1 +#define IMX7ULP_PAD_PTC18__FB_OE_B 0x0048 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTC19__PTC19 0x004c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTC19__FXIO1_D15 0x004c 0x0240 0x2 0x1 +#define IMX7ULP_PAD_PTC19__LPSPI3_PCS0 0x004c 0x0310 0x3 0x1 +#define IMX7ULP_PAD_PTC19__TPM6_CH1 0x004c 0x02d4 0x6 0x1 +#define IMX7ULP_PAD_PTC19__FB_A16 0x004c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTD0__PTD0 0x0080 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD0__SDHC0_RESET_B 0x0080 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD1__PTD1 0x0084 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD1__SDHC0_CMD 0x0084 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD2__PTD2 0x0088 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD2__SDHC0_CLK 0x0088 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD3__PTD3 0x008c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD3__SDHC0_D7 0x008c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD4__PTD4 0x0090 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD4__SDHC0_D6 0x0090 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD5__PTD5 0x0094 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD5__SDHC0_D5 0x0094 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD6__PTD6 0x0098 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD6__SDHC0_D4 0x0098 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD7__PTD7 0x009c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD7__SDHC0_D3 0x009c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD8__PTD8 0x00a0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD8__TPM4_CLKIN 0x00a0 0x0298 0x6 0x2 +#define IMX7ULP_PAD_PTD8__SDHC0_D2 0x00a0 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD9__PTD9 0x00a4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD9__TPM4_CH0 0x00a4 0x0280 0x6 0x2 +#define IMX7ULP_PAD_PTD9__SDHC0_D1 0x00a4 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD10__PTD10 0x00a8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD10__TPM4_CH1 0x00a8 0x0284 0x6 0x2 +#define IMX7ULP_PAD_PTD10__SDHC0_D0 0x00a8 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTD11__PTD11 0x00ac 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTD11__TPM4_CH2 0x00ac 0x0288 0x6 0x2 +#define IMX7ULP_PAD_PTD11__SDHC0_DQS 0x00ac 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE0__PTE0 0x0100 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE0__FXIO1_D31 0x0100 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE0__LPSPI2_PCS1 0x0100 0x02a0 0x3 0x2 +#define IMX7ULP_PAD_PTE0__LPUART4_CTS_B 0x0100 0x0244 0x4 0x2 +#define IMX7ULP_PAD_PTE0__LPI2C4_SCL 0x0100 0x0278 0x5 0x2 +#define IMX7ULP_PAD_PTE0__SDHC1_D1 0x0100 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE0__FB_A25 0x0100 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE1__PTE1 0x0104 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE1__FXIO1_D30 0x0104 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE1__LPSPI2_PCS2 0x0104 0x02a4 0x3 0x2 +#define IMX7ULP_PAD_PTE1__LPUART4_RTS_B 0x0104 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE1__LPI2C4_SDA 0x0104 0x027c 0x5 0x2 +#define IMX7ULP_PAD_PTE1__SDHC1_D0 0x0104 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE1__FB_A26 0x0104 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE2__PTE2 0x0108 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE2__FXIO1_D29 0x0108 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE2__LPSPI2_PCS3 0x0108 0x02a8 0x3 0x2 +#define IMX7ULP_PAD_PTE2__LPUART4_TX 0x0108 0x024c 0x4 0x2 +#define IMX7ULP_PAD_PTE2__LPI2C4_HREQ 0x0108 0x0274 0x5 0x2 +#define IMX7ULP_PAD_PTE2__SDHC1_CLK 0x0108 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE3__PTE3 0x010c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE3__FXIO1_D28 0x010c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE3__LPUART4_RX 0x010c 0x0248 0x4 0x2 +#define IMX7ULP_PAD_PTE3__TPM5_CH1 0x010c 0x02c8 0x6 0x2 +#define IMX7ULP_PAD_PTE3__SDHC1_CMD 0x010c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE4__PTE4 0x0110 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE4__FXIO1_D27 0x0110 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE4__LPSPI2_SIN 0x0110 0x02b0 0x3 0x2 +#define IMX7ULP_PAD_PTE4__LPUART5_CTS_B 0x0110 0x0250 0x4 0x2 +#define IMX7ULP_PAD_PTE4__LPI2C5_SCL 0x0110 0x02bc 0x5 0x2 +#define IMX7ULP_PAD_PTE4__TPM5_CLKIN 0x0110 0x02cc 0x6 0x2 +#define IMX7ULP_PAD_PTE4__SDHC1_D3 0x0110 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE5__PTE5 0x0114 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE5__FXIO1_D26 0x0114 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE5__LPSPI2_SOUT 0x0114 0x02b4 0x3 0x2 +#define IMX7ULP_PAD_PTE5__LPUART5_RTS_B 0x0114 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE5__LPI2C5_SDA 0x0114 0x02c0 0x5 0x2 +#define IMX7ULP_PAD_PTE5__TPM5_CH0 0x0114 0x02c4 0x6 0x2 +#define IMX7ULP_PAD_PTE5__SDHC1_D2 0x0114 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE6__PTE6 0x0118 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE6__FXIO1_D25 0x0118 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE6__LPSPI2_SCK 0x0118 0x02ac 0x3 0x2 +#define IMX7ULP_PAD_PTE6__LPUART5_TX 0x0118 0x0258 0x4 0x2 +#define IMX7ULP_PAD_PTE6__LPI2C5_HREQ 0x0118 0x02b8 0x5 0x2 +#define IMX7ULP_PAD_PTE6__TPM7_CH3 0x0118 0x02e8 0x6 0x2 +#define IMX7ULP_PAD_PTE6__SDHC1_D4 0x0118 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE6__FB_A17 0x0118 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE7__PTE7 0x011c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE7__TRACE_D7 0x011c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE7__VIU_FID 0x011c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE7__FXIO1_D24 0x011c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE7__LPSPI2_PCS0 0x011c 0x029c 0x3 0x2 +#define IMX7ULP_PAD_PTE7__LPUART5_RX 0x011c 0x0254 0x4 0x2 +#define IMX7ULP_PAD_PTE7__TPM7_CH4 0x011c 0x02ec 0x6 0x2 +#define IMX7ULP_PAD_PTE7__SDHC1_D5 0x011c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE7__FB_A18 0x011c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE8__PTE8 0x0120 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE8__TRACE_D6 0x0120 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE8__VIU_D16 0x0120 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE8__FXIO1_D23 0x0120 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE8__LPSPI3_PCS1 0x0120 0x0314 0x3 0x2 +#define IMX7ULP_PAD_PTE8__LPUART6_CTS_B 0x0120 0x025c 0x4 0x2 +#define IMX7ULP_PAD_PTE8__LPI2C6_SCL 0x0120 0x02fc 0x5 0x2 +#define IMX7ULP_PAD_PTE8__TPM7_CH5 0x0120 0x02f0 0x6 0x2 +#define IMX7ULP_PAD_PTE8__SDHC1_WP 0x0120 0x0200 0x7 0x1 +#define IMX7ULP_PAD_PTE8__SDHC1_D6 0x0120 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE8__FB_CS3_B_FB_BE7_0_BLS31_24_B 0x0120 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE9__PTE9 0x0124 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE9__TRACE_D5 0x0124 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE9__VIU_D17 0x0124 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE9__FXIO1_D22 0x0124 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE9__LPSPI3_PCS2 0x0124 0x0318 0x3 0x2 +#define IMX7ULP_PAD_PTE9__LPUART6_RTS_B 0x0124 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE9__LPI2C6_SDA 0x0124 0x0300 0x5 0x2 +#define IMX7ULP_PAD_PTE9__TPM7_CLKIN 0x0124 0x02f4 0x6 0x2 +#define IMX7ULP_PAD_PTE9__SDHC1_CD 0x0124 0x032c 0x7 0x1 +#define IMX7ULP_PAD_PTE9__SDHC1_D7 0x0124 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE9__FB_TBST_B_FB_CS2_B_FB_BE15_8_BLS23_16_B 0x0124 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE10__PTE10 0x0128 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE10__TRACE_D4 0x0128 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE10__VIU_D18 0x0128 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE10__FXIO1_D21 0x0128 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE10__LPSPI3_PCS3 0x0128 0x031c 0x3 0x2 +#define IMX7ULP_PAD_PTE10__LPUART6_TX 0x0128 0x0264 0x4 0x2 +#define IMX7ULP_PAD_PTE10__LPI2C6_HREQ 0x0128 0x02f8 0x5 0x2 +#define IMX7ULP_PAD_PTE10__TPM7_CH0 0x0128 0x02dc 0x6 0x2 +#define IMX7ULP_PAD_PTE10__SDHC1_VS 0x0128 0x0000 0x7 0x0 +#define IMX7ULP_PAD_PTE10__SDHC1_DQS 0x0128 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE10__FB_A19 0x0128 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE11__PTE11 0x012c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE11__TRACE_D3 0x012c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE11__VIU_D19 0x012c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE11__FXIO1_D20 0x012c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE11__LPUART6_RX 0x012c 0x0260 0x4 0x2 +#define IMX7ULP_PAD_PTE11__TPM7_CH1 0x012c 0x02e0 0x6 0x2 +#define IMX7ULP_PAD_PTE11__SDHC1_RESET_B 0x012c 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE11__FB_A20 0x012c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE12__PTE12 0x0130 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE12__TRACE_D2 0x0130 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE12__VIU_D20 0x0130 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE12__FXIO1_D19 0x0130 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE12__LPSPI3_SIN 0x0130 0x0324 0x3 0x2 +#define IMX7ULP_PAD_PTE12__LPUART7_CTS_B 0x0130 0x0268 0x4 0x2 +#define IMX7ULP_PAD_PTE12__LPI2C7_SCL 0x0130 0x0308 0x5 0x2 +#define IMX7ULP_PAD_PTE12__TPM7_CH2 0x0130 0x02e4 0x6 0x2 +#define IMX7ULP_PAD_PTE12__SDHC1_WP 0x0130 0x0200 0x8 0x2 +#define IMX7ULP_PAD_PTE12__FB_A21 0x0130 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE13__PTE13 0x0134 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE13__TRACE_D1 0x0134 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE13__VIU_D21 0x0134 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE13__FXIO1_D18 0x0134 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE13__LPSPI3_SOUT 0x0134 0x0328 0x3 0x2 +#define IMX7ULP_PAD_PTE13__LPUART7_RTS_B 0x0134 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTE13__LPI2C7_SDA 0x0134 0x030c 0x5 0x2 +#define IMX7ULP_PAD_PTE13__TPM6_CLKIN 0x0134 0x02d8 0x6 0x2 +#define IMX7ULP_PAD_PTE13__SDHC1_CD 0x0134 0x032c 0x8 0x2 +#define IMX7ULP_PAD_PTE13__FB_A22 0x0134 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE14__PTE14 0x0138 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE14__TRACE_D0 0x0138 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE14__VIU_D22 0x0138 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE14__FXIO1_D17 0x0138 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE14__LPSPI3_SCK 0x0138 0x0320 0x3 0x2 +#define IMX7ULP_PAD_PTE14__LPUART7_TX 0x0138 0x0270 0x4 0x2 +#define IMX7ULP_PAD_PTE14__LPI2C7_HREQ 0x0138 0x0304 0x5 0x2 +#define IMX7ULP_PAD_PTE14__TPM6_CH0 0x0138 0x02d0 0x6 0x2 +#define IMX7ULP_PAD_PTE14__SDHC1_VS 0x0138 0x0000 0x8 0x0 +#define IMX7ULP_PAD_PTE14__FB_A23 0x0138 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTE15__PTE15 0x013c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTE15__TRACE_CLKOUT 0x013c 0x0000 0xa 0x0 +#define IMX7ULP_PAD_PTE15__VIU_D23 0x013c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTE15__FXIO1_D16 0x013c 0x0000 0x2 0x0 +#define IMX7ULP_PAD_PTE15__LPSPI3_PCS0 0x013c 0x0310 0x3 0x2 +#define IMX7ULP_PAD_PTE15__LPUART7_RX 0x013c 0x026c 0x4 0x2 +#define IMX7ULP_PAD_PTE15__TPM6_CH1 0x013c 0x02d4 0x6 0x2 +#define IMX7ULP_PAD_PTE15__FB_A24 0x013c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF0__PTF0 0x0180 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF0__VIU_DE 0x0180 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF0__LPUART4_CTS_B 0x0180 0x0244 0x4 0x3 +#define IMX7ULP_PAD_PTF0__LPI2C4_SCL 0x0180 0x0278 0x5 0x3 +#define IMX7ULP_PAD_PTF0__TPM4_CLKIN 0x0180 0x0298 0x6 0x3 +#define IMX7ULP_PAD_PTF0__FB_RW_B 0x0180 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF1__PTF1 0x0184 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF1__VIU_HSYNC 0x0184 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF1__LPUART4_RTS_B 0x0184 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF1__LPI2C4_SDA 0x0184 0x027c 0x5 0x3 +#define IMX7ULP_PAD_PTF1__TPM4_CH0 0x0184 0x0280 0x6 0x3 +#define IMX7ULP_PAD_PTF1__CLKOUT 0x0184 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF2__PTF2 0x0188 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF2__VIU_VSYNC 0x0188 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF2__LPUART4_TX 0x0188 0x024c 0x4 0x3 +#define IMX7ULP_PAD_PTF2__LPI2C4_HREQ 0x0188 0x0274 0x5 0x3 +#define IMX7ULP_PAD_PTF2__TPM4_CH1 0x0188 0x0284 0x6 0x3 +#define IMX7ULP_PAD_PTF2__FB_TSIZ1_FB_CS5_B_FB_BE23_16_BLS15_8_B 0x0188 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF3__PTF3 0x018c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF3__VIU_PCLK 0x018c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF3__LPUART4_RX 0x018c 0x0248 0x4 0x3 +#define IMX7ULP_PAD_PTF3__TPM4_CH2 0x018c 0x0288 0x6 0x3 +#define IMX7ULP_PAD_PTF3__FB_AD16 0x018c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF4__PTF4 0x0190 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF4__VIU_D0 0x0190 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF4__FXIO1_D0 0x0190 0x0204 0x2 0x2 +#define IMX7ULP_PAD_PTF4__LPSPI2_PCS1 0x0190 0x02a0 0x3 0x3 +#define IMX7ULP_PAD_PTF4__LPUART5_CTS_B 0x0190 0x0250 0x4 0x3 +#define IMX7ULP_PAD_PTF4__LPI2C5_SCL 0x0190 0x02bc 0x5 0x3 +#define IMX7ULP_PAD_PTF4__TPM4_CH3 0x0190 0x028c 0x6 0x2 +#define IMX7ULP_PAD_PTF4__FB_AD17 0x0190 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF5__PTF5 0x0194 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF5__VIU_D1 0x0194 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF5__FXIO1_D1 0x0194 0x0208 0x2 0x2 +#define IMX7ULP_PAD_PTF5__LPSPI2_PCS2 0x0194 0x02a4 0x3 0x3 +#define IMX7ULP_PAD_PTF5__LPUART5_RTS_B 0x0194 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF5__LPI2C5_SDA 0x0194 0x02c0 0x5 0x3 +#define IMX7ULP_PAD_PTF5__TPM4_CH4 0x0194 0x0290 0x6 0x2 +#define IMX7ULP_PAD_PTF5__FB_AD18 0x0194 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF6__PTF6 0x0198 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF6__VIU_D2 0x0198 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF6__FXIO1_D2 0x0198 0x020c 0x2 0x2 +#define IMX7ULP_PAD_PTF6__LPSPI2_PCS3 0x0198 0x02a8 0x3 0x3 +#define IMX7ULP_PAD_PTF6__LPUART5_TX 0x0198 0x0258 0x4 0x3 +#define IMX7ULP_PAD_PTF6__LPI2C5_HREQ 0x0198 0x02b8 0x5 0x3 +#define IMX7ULP_PAD_PTF6__TPM4_CH5 0x0198 0x0294 0x6 0x2 +#define IMX7ULP_PAD_PTF6__FB_AD19 0x0198 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF7__PTF7 0x019c 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF7__VIU_D3 0x019c 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF7__FXIO1_D3 0x019c 0x0210 0x2 0x2 +#define IMX7ULP_PAD_PTF7__LPUART5_RX 0x019c 0x0254 0x4 0x3 +#define IMX7ULP_PAD_PTF7__TPM5_CH1 0x019c 0x02c8 0x6 0x3 +#define IMX7ULP_PAD_PTF7__FB_AD20 0x019c 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF8__PTF8 0x01a0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF8__USB1_ULPI_CLK 0x01a0 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF8__VIU_D4 0x01a0 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF8__FXIO1_D4 0x01a0 0x0214 0x2 0x2 +#define IMX7ULP_PAD_PTF8__LPSPI2_SIN 0x01a0 0x02b0 0x3 0x3 +#define IMX7ULP_PAD_PTF8__LPUART6_CTS_B 0x01a0 0x025c 0x4 0x3 +#define IMX7ULP_PAD_PTF8__LPI2C6_SCL 0x01a0 0x02fc 0x5 0x3 +#define IMX7ULP_PAD_PTF8__TPM5_CLKIN 0x01a0 0x02cc 0x6 0x3 +#define IMX7ULP_PAD_PTF8__FB_AD21 0x01a0 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF9__PTF9 0x01a4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF9__USB1_ULPI_NXT 0x01a4 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF9__VIU_D5 0x01a4 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF9__FXIO1_D5 0x01a4 0x0218 0x2 0x2 +#define IMX7ULP_PAD_PTF9__LPSPI2_SOUT 0x01a4 0x02b4 0x3 0x3 +#define IMX7ULP_PAD_PTF9__LPUART6_RTS_B 0x01a4 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF9__LPI2C6_SDA 0x01a4 0x0300 0x5 0x3 +#define IMX7ULP_PAD_PTF9__TPM5_CH0 0x01a4 0x02c4 0x6 0x3 +#define IMX7ULP_PAD_PTF9__FB_AD22 0x01a4 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF10__PTF10 0x01a8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF10__USB1_ULPI_STP 0x01a8 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF10__VIU_D6 0x01a8 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF10__FXIO1_D6 0x01a8 0x021c 0x2 0x2 +#define IMX7ULP_PAD_PTF10__LPSPI2_SCK 0x01a8 0x02ac 0x3 0x3 +#define IMX7ULP_PAD_PTF10__LPUART6_TX 0x01a8 0x0264 0x4 0x3 +#define IMX7ULP_PAD_PTF10__LPI2C6_HREQ 0x01a8 0x02f8 0x5 0x3 +#define IMX7ULP_PAD_PTF10__TPM7_CH3 0x01a8 0x02e8 0x6 0x3 +#define IMX7ULP_PAD_PTF10__FB_AD23 0x01a8 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF11__PTF11 0x01ac 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF11__USB1_ULPI_DIR 0x01ac 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF11__VIU_D7 0x01ac 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF11__FXIO1_D7 0x01ac 0x0220 0x2 0x2 +#define IMX7ULP_PAD_PTF11__LPSPI2_PCS0 0x01ac 0x029c 0x3 0x3 +#define IMX7ULP_PAD_PTF11__LPUART6_RX 0x01ac 0x0260 0x4 0x3 +#define IMX7ULP_PAD_PTF11__TPM7_CH4 0x01ac 0x02ec 0x6 0x3 +#define IMX7ULP_PAD_PTF11__FB_CS4_B_FB_TSIZ0_FB_BE31_24_BLS7_0_B 0x01ac 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF12__PTF12 0x01b0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF12__USB1_ULPI_DATA0 0x01b0 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF12__VIU_D8 0x01b0 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF12__FXIO1_D8 0x01b0 0x0224 0x2 0x2 +#define IMX7ULP_PAD_PTF12__LPSPI3_PCS1 0x01b0 0x0314 0x3 0x3 +#define IMX7ULP_PAD_PTF12__LPUART7_CTS_B 0x01b0 0x0268 0x4 0x3 +#define IMX7ULP_PAD_PTF12__LPI2C7_SCL 0x01b0 0x0308 0x5 0x3 +#define IMX7ULP_PAD_PTF12__TPM7_CH5 0x01b0 0x02f0 0x6 0x3 +#define IMX7ULP_PAD_PTF12__FB_AD24 0x01b0 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF13__PTF13 0x01b4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF13__USB1_ULPI_DATA1 0x01b4 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF13__VIU_D9 0x01b4 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF13__FXIO1_D9 0x01b4 0x0228 0x2 0x2 +#define IMX7ULP_PAD_PTF13__LPSPI3_PCS2 0x01b4 0x0318 0x3 0x3 +#define IMX7ULP_PAD_PTF13__LPUART7_RTS_B 0x01b4 0x0000 0x4 0x0 +#define IMX7ULP_PAD_PTF13__LPI2C7_SDA 0x01b4 0x030c 0x5 0x3 +#define IMX7ULP_PAD_PTF13__TPM7_CLKIN 0x01b4 0x02f4 0x6 0x3 +#define IMX7ULP_PAD_PTF13__FB_AD25 0x01b4 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF14__PTF14 0x01b8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF14__USB1_ULPI_DATA2 0x01b8 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF14__VIU_D10 0x01b8 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF14__FXIO1_D10 0x01b8 0x022c 0x2 0x2 +#define IMX7ULP_PAD_PTF14__LPSPI3_PCS3 0x01b8 0x031c 0x3 0x3 +#define IMX7ULP_PAD_PTF14__LPUART7_TX 0x01b8 0x0270 0x4 0x3 +#define IMX7ULP_PAD_PTF14__LPI2C7_HREQ 0x01b8 0x0304 0x5 0x3 +#define IMX7ULP_PAD_PTF14__TPM7_CH0 0x01b8 0x02dc 0x6 0x3 +#define IMX7ULP_PAD_PTF14__FB_AD26 0x01b8 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF15__PTF15 0x01bc 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF15__USB1_ULPI_DATA3 0x01bc 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF15__VIU_D11 0x01bc 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF15__FXIO1_D11 0x01bc 0x0230 0x2 0x2 +#define IMX7ULP_PAD_PTF15__LPUART7_RX 0x01bc 0x026c 0x4 0x3 +#define IMX7ULP_PAD_PTF15__TPM7_CH1 0x01bc 0x02e0 0x6 0x3 +#define IMX7ULP_PAD_PTF15__FB_AD27 0x01bc 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF16__PTF16 0x01c0 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF16__USB1_ULPI_DATA4 0x01c0 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF16__VIU_D12 0x01c0 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF16__FXIO1_D12 0x01c0 0x0234 0x2 0x2 +#define IMX7ULP_PAD_PTF16__LPSPI3_SIN 0x01c0 0x0324 0x3 0x3 +#define IMX7ULP_PAD_PTF16__TPM7_CH2 0x01c0 0x02e4 0x6 0x3 +#define IMX7ULP_PAD_PTF16__FB_AD28 0x01c0 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF17__PTF17 0x01c4 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF17__USB1_ULPI_DATA5 0x01c4 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF17__VIU_D13 0x01c4 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF17__FXIO1_D13 0x01c4 0x0238 0x2 0x2 +#define IMX7ULP_PAD_PTF17__LPSPI3_SOUT 0x01c4 0x0328 0x3 0x3 +#define IMX7ULP_PAD_PTF17__TPM6_CLKIN 0x01c4 0x02d8 0x6 0x3 +#define IMX7ULP_PAD_PTF17__FB_AD29 0x01c4 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF18__PTF18 0x01c8 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF18__USB1_ULPI_DATA6 0x01c8 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF18__VIU_D14 0x01c8 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF18__FXIO1_D14 0x01c8 0x023c 0x2 0x2 +#define IMX7ULP_PAD_PTF18__LPSPI3_SCK 0x01c8 0x0320 0x3 0x3 +#define IMX7ULP_PAD_PTF18__TPM6_CH0 0x01c8 0x02d0 0x6 0x3 +#define IMX7ULP_PAD_PTF18__FB_AD30 0x01c8 0x0000 0x9 0x0 +#define IMX7ULP_PAD_PTF19__PTF19 0x01cc 0x0000 0x1 0x0 +#define IMX7ULP_PAD_PTF19__USB1_ULPI_DATA7 0x01cc 0x0000 0xb 0x0 +#define IMX7ULP_PAD_PTF19__VIU_D15 0x01cc 0x0000 0xc 0x0 +#define IMX7ULP_PAD_PTF19__FXIO1_D15 0x01cc 0x0240 0x2 0x2 +#define IMX7ULP_PAD_PTF19__LPSPI3_PCS0 0x01cc 0x0310 0x3 0x3 +#define IMX7ULP_PAD_PTF19__TPM6_CH1 0x01cc 0x02d4 0x6 0x3 +#define IMX7ULP_PAD_PTF19__FB_AD31 0x01cc 0x0000 0x9 0x0 + +#endif /* __DTS_IMX7ULP_PINFUNC_H */ diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi index 6fe0dd1d3541..380f9ae60c78 100644 --- a/arch/arm/boot/dts/integrator.dtsi +++ b/arch/arm/boot/dts/integrator.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SoC core Device Tree for the ARM Integrator platforms */ diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts index e8b249f92fb3..a5d88a213dcd 100644 --- a/arch/arm/boot/dts/integratorap.dts +++ b/arch/arm/boot/dts/integratorap.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree for the ARM Integrator/AP platform */ diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts index 97f38b57a702..a185ab8759fa 100644 --- a/arch/arm/boot/dts/integratorcp.dts +++ b/arch/arm/boot/dts/integratorcp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree for the ARM Integrator/CP platform */ diff --git a/arch/arm/boot/dts/keystone-k2e-evm.dts b/arch/arm/boot/dts/keystone-k2e-evm.dts index ae1ebe7ee021..f1f32c54e72f 100644 --- a/arch/arm/boot/dts/keystone-k2e-evm.dts +++ b/arch/arm/boot/dts/keystone-k2e-evm.dts @@ -16,6 +16,19 @@ compatible = "ti,k2e-evm", "ti,k2e", "ti,keystone"; model = "Texas Instruments Keystone 2 Edison EVM"; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + soc { clocks { @@ -160,3 +173,8 @@ reg = <1>; }; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2e.dtsi b/arch/arm/boot/dts/keystone-k2e.dtsi index 0dd4cdd6d40c..819ab8345916 100644 --- a/arch/arm/boot/dts/keystone-k2e.dtsi +++ b/arch/arm/boot/dts/keystone-k2e.dtsi @@ -45,6 +45,10 @@ }; }; + aliases { + rproc0 = &dsp0; + }; + soc { /include/ "keystone-k2e-clocks.dtsi" @@ -114,6 +118,22 @@ gpio,syscon-dev = <&devctrl 0x240>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2e-dsp"; + reg = <0x10800000 0x00080000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem0>; + ti,syscon-dev = <&devctrl 0x844>; + resets = <&pscrst 0>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + pcie1: pcie@21020000 { compatible = "ti,keystone-pcie","snps,dw-pcie"; clocks = <&clkpcie1>; diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts index 61883cb969d2..f462f1043531 100644 --- a/arch/arm/boot/dts/keystone-k2g-evm.dts +++ b/arch/arm/boot/dts/keystone-k2g-evm.dts @@ -25,6 +25,26 @@ reg = <0x00000008 0x00000000 0x00000000 0x80000000>; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + + vcc3v3_dcin_reg: fixedregulator-vcc3v3-dcin { + compatible = "regulator-fixed"; + regulator-name = "mmc0_fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; }; &k2g_pinctrl { @@ -34,6 +54,33 @@ K2G_CORE_IOPAD(0x11d0) (BUFFER_CLASS_B | PIN_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */ >; }; + + mmc0_pins: pinmux_mmc0_pins { + pinctrl-single,pins = < + K2G_CORE_IOPAD(0x1300) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat3.mmc0_dat3 */ + K2G_CORE_IOPAD(0x1304) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat2.mmc0_dat2 */ + K2G_CORE_IOPAD(0x1308) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat1.mmc0_dat1 */ + K2G_CORE_IOPAD(0x130c) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_dat0.mmc0_dat0 */ + K2G_CORE_IOPAD(0x1310) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_clk.mmc0_clk */ + K2G_CORE_IOPAD(0x1314) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE2) /* mmc0_cmd.mmc0_cmd */ + K2G_CORE_IOPAD(0x12ec) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE3) /* mmc0_sdcd.gpio1_12 */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + K2G_CORE_IOPAD(0x10ec) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat7.mmc1_dat7 */ + K2G_CORE_IOPAD(0x10f0) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat6.mmc1_dat6 */ + K2G_CORE_IOPAD(0x10f4) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat5.mmc1_dat5 */ + K2G_CORE_IOPAD(0x10f8) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat4.mmc1_dat4 */ + K2G_CORE_IOPAD(0x10fc) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 */ + K2G_CORE_IOPAD(0x1100) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat2.mmc1_dat2 */ + K2G_CORE_IOPAD(0x1104) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat1.mmc1_dat1 */ + K2G_CORE_IOPAD(0x1108) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_dat0.mmc1_dat0 */ + K2G_CORE_IOPAD(0x110c) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_clk.mmc1_clk */ + K2G_CORE_IOPAD(0x1110) (BUFFER_CLASS_B | PIN_PULLUP | MUX_MODE0) /* mmc1_cmd.mmc1_cmd */ + >; + }; }; &uart0 { @@ -41,3 +88,27 @@ pinctrl-0 = <&uart0_pins>; status = "okay"; }; + +&gpio1 { + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <&vcc3v3_dcin_reg>; + cd-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins>; + vmmc-supply = <&vcc3v3_dcin_reg>; /* VCC3V3_EMMC is connected to VCC3V3_DCIN */ + status = "okay"; +}; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2g-ice.dts b/arch/arm/boot/dts/keystone-k2g-ice.dts index d820d37b5148..78692745e0af 100644 --- a/arch/arm/boot/dts/keystone-k2g-ice.dts +++ b/arch/arm/boot/dts/keystone-k2g-ice.dts @@ -17,6 +17,19 @@ device_type = "memory"; reg = <0x00000008 0x00000000 0x00000000 0x20000000>; }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; }; &k2g_pinctrl { @@ -33,3 +46,8 @@ pinctrl-0 = <&uart0_pins>; status = "okay"; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi index a789f75a1ed5..826b286665e6 100644 --- a/arch/arm/boot/dts/keystone-k2g.dtsi +++ b/arch/arm/boot/dts/keystone-k2g.dtsi @@ -15,6 +15,7 @@ #include #include +#include / { compatible = "ti,k2g","ti,keystone"; @@ -27,6 +28,7 @@ aliases { serial0 = &uart0; + rproc0 = &dsp0; }; cpus { @@ -113,6 +115,24 @@ status = "disabled"; }; + dcan0: can@0260B200 { + compatible = "ti,am4372-d_can", "ti,am3352-d_can"; + reg = <0x0260B200 0x200>; + interrupts = ; + status = "disabled"; + power-domains = <&k2g_pds 0x0008>; + clocks = <&k2g_clks 0x0008 1>; + }; + + dcan1: can@0260B400 { + compatible = "ti,am4372-d_can", "ti,am3352-d_can"; + reg = <0x0260B400 0x200>; + interrupts = ; + status = "disabled"; + power-domains = <&k2g_pds 0x0009>; + clocks = <&k2g_clks 0x0009 1>; + }; + kirq0: keystone_irq@026202a0 { compatible = "ti,keystone-irq"; interrupts = ; @@ -128,6 +148,22 @@ gpio,syscon-dev = <&devctrl 0x240>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2g-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + power-domains = <&k2g_pds 0x0046>; + ti,syscon-dev = <&devctrl 0x844>; + resets = <&k2g_reset 0x0046 0x1>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + msgmgr: msgmgr@02a00000 { compatible = "ti,k2g-message-manager"; #mbox-cells = <2>; @@ -139,5 +175,173 @@ interrupts = , ; }; + + pmmc: pmmc@02921c00 { + compatible = "ti,k2g-sci"; + /* + * In case of rare platforms that does not use k2g as + * system master, use /delete-property/ + */ + ti,system-reboot-controller; + mbox-names = "rx", "tx"; + mboxes= <&msgmgr 5 2>, + <&msgmgr 0 0>; + reg-names = "debug_messages"; + reg = <0x02921c00 0x400>; + + k2g_pds: power-controller { + compatible = "ti,sci-pm-domain"; + #power-domain-cells = <1>; + }; + + k2g_clks: clocks { + compatible = "ti,k2g-sci-clk"; + #clock-cells = <2>; + }; + + k2g_reset: reset-controller { + compatible = "ti,sci-reset"; + #reset-cells = <2>; + }; + }; + + gpio0: gpio@2603000 { + compatible = "ti,k2g-gpio", "ti,keystone-gpio"; + reg = <0x02603000 0x100>; + gpio-controller; + #gpio-cells = <2>; + + interrupts = , + , + , + , + , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + ti,ngpio = <144>; + ti,davinci-gpio-unbanked = <0>; + clocks = <&k2g_clks 0x001b 0x0>; + clock-names = "gpio"; + }; + + gpio1: gpio@260a000 { + compatible = "ti,k2g-gpio", "ti,keystone-gpio"; + reg = <0x0260a000 0x100>; + gpio-controller; + #gpio-cells = <2>; + interrupts = , + , + , + , + ; + interrupt-controller; + #interrupt-cells = <2>; + ti,ngpio = <68>; + ti,davinci-gpio-unbanked = <0>; + clocks = <&k2g_clks 0x001c 0x0>; + clock-names = "gpio"; + }; + + edma0: edma@02700000 { + compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc"; + reg = <0x02700000 0x8000>; + reg-names = "edma3_cc"; + interrupts = , + , + ; + interrupt-names = "edma3_ccint", "emda3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma0_tptc0 7>, <&edma0_tptc1 0>; + + ti,edma-memcpy-channels = <32 33 34 35>; + + power-domains = <&k2g_pds 0x3f>; + }; + + edma0_tptc0: tptc@02760000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x02760000 0x400>; + power-domains = <&k2g_pds 0x3f>; + }; + + edma0_tptc1: tptc@02768000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x02768000 0x400>; + power-domains = <&k2g_pds 0x3f>; + }; + + edma1: edma@02728000 { + compatible = "ti,k2g-edma3-tpcc", "ti,edma3-tpcc"; + reg = <0x02728000 0x8000>; + reg-names = "edma3_cc"; + interrupts = , + , + ; + interrupt-names = "edma3_ccint", "emda3_mperr", + "edma3_ccerrint"; + dma-requests = <64>; + #dma-cells = <2>; + + ti,tptcs = <&edma1_tptc0 7>, <&edma1_tptc1 0>; + + /* + * memcpy is disabled, can be enabled with: + * ti,edma-memcpy-channels = <12 13 14 15>; + * for example. + */ + + power-domains = <&k2g_pds 0x4f>; + }; + + edma1_tptc0: tptc@027b0000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b0000 0x400>; + power-domains = <&k2g_pds 0x4f>; + }; + + edma1_tptc1: tptc@027b8000 { + compatible = "ti,k2g-edma3-tptc", "ti,edma3-tptc"; + reg = <0x027b8000 0x400>; + power-domains = <&k2g_pds 0x4f>; + }; + + mmc0: mmc@23000000 { + compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc"; + reg = <0x23000000 0x400>; + interrupts = ; + dmas = <&edma1 24 0>, <&edma1 25 0>; + dma-names = "tx", "rx"; + bus-width = <4>; + ti,needs-special-reset; + no-1-8-v; + max-frequency = <96000000>; + power-domains = <&k2g_pds 0xb>; + clocks = <&k2g_clks 0xb 1>, <&k2g_clks 0xb 2>; + clock-names = "fck", "mmchsdb_fck"; + status = "disabled"; + }; + + mmc1: mmc@23100000 { + compatible = "ti,k2g-hsmmc", "ti,omap4-hsmmc"; + reg = <0x23100000 0x400>; + interrupts = ; + dmas = <&edma1 26 0>, <&edma1 27 0>; + dma-names = "tx", "rx"; + bus-width = <8>; + ti,needs-special-reset; + ti,non-removable; + max-frequency = <96000000>; + power-domains = <&k2g_pds 0xc>; + clocks = <&k2g_clks 0xc 1>, <&k2g_clks 0xc 2>; + clock-names = "fck", "mmchsdb_fck"; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/keystone-k2hk-evm.dts b/arch/arm/boot/dts/keystone-k2hk-evm.dts index 2156ff92d08f..6dd13b98aaba 100644 --- a/arch/arm/boot/dts/keystone-k2hk-evm.dts +++ b/arch/arm/boot/dts/keystone-k2hk-evm.dts @@ -16,6 +16,19 @@ compatible = "ti,k2hk-evm", "ti,k2hk", "ti,keystone"; model = "Texas Instruments Keystone 2 Kepler/Hawking EVM"; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + soc { clocks { refclksys: refclksys { @@ -184,3 +197,43 @@ reg = <1>; }; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp1 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp2 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp3 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp4 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp5 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp6 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp7 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2hk.dtsi b/arch/arm/boot/dts/keystone-k2hk.dtsi index 69d449430511..31dc00e4e5fd 100644 --- a/arch/arm/boot/dts/keystone-k2hk.dtsi +++ b/arch/arm/boot/dts/keystone-k2hk.dtsi @@ -45,6 +45,17 @@ }; }; + aliases { + rproc0 = &dsp0; + rproc1 = &dsp1; + rproc2 = &dsp2; + rproc3 = &dsp3; + rproc4 = &dsp4; + rproc5 = &dsp5; + rproc6 = &dsp6; + rproc7 = &dsp7; + }; + soc { /include/ "keystone-k2hk-clocks.dtsi" @@ -134,6 +145,134 @@ gpio,syscon-dev = <&devctrl 0x25c>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem0>; + ti,syscon-dev = <&devctrl 0x40>; + resets = <&pscrst 0>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + + dsp1: dsp@11800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x11800000 0x00100000>, + <0x11e00000 0x00008000>, + <0x11f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem1>; + ti,syscon-dev = <&devctrl 0x44>; + resets = <&pscrst 1>; + interrupt-parent = <&kirq0>; + interrupts = <1 9>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio1 27 0>; + status = "disabled"; + }; + + dsp2: dsp@12800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x12800000 0x00100000>, + <0x12e00000 0x00008000>, + <0x12f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem2>; + ti,syscon-dev = <&devctrl 0x48>; + resets = <&pscrst 2>; + interrupt-parent = <&kirq0>; + interrupts = <2 10>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio2 27 0>; + status = "disabled"; + }; + + dsp3: dsp@13800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x13800000 0x00100000>, + <0x13e00000 0x00008000>, + <0x13f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem3>; + ti,syscon-dev = <&devctrl 0x4c>; + resets = <&pscrst 3>; + interrupt-parent = <&kirq0>; + interrupts = <3 11>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio3 27 0>; + status = "disabled"; + }; + + dsp4: dsp@14800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x14800000 0x00100000>, + <0x14e00000 0x00008000>, + <0x14f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem4>; + ti,syscon-dev = <&devctrl 0x50>; + resets = <&pscrst 4>; + interrupt-parent = <&kirq0>; + interrupts = <4 12>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio4 27 0>; + status = "disabled"; + }; + + dsp5: dsp@15800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x15800000 0x00100000>, + <0x15e00000 0x00008000>, + <0x15f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem5>; + ti,syscon-dev = <&devctrl 0x54>; + resets = <&pscrst 5>; + interrupt-parent = <&kirq0>; + interrupts = <5 13>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio5 27 0>; + status = "disabled"; + }; + + dsp6: dsp@16800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x16800000 0x00100000>, + <0x16e00000 0x00008000>, + <0x16f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem6>; + ti,syscon-dev = <&devctrl 0x58>; + resets = <&pscrst 6>; + interrupt-parent = <&kirq0>; + interrupts = <6 14>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio6 27 0>; + status = "disabled"; + }; + + dsp7: dsp@17800000 { + compatible = "ti,k2hk-dsp"; + reg = <0x17800000 0x00100000>, + <0x17e00000 0x00008000>, + <0x17f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem7>; + ti,syscon-dev = <&devctrl 0x5c>; + resets = <&pscrst 7>; + interrupt-parent = <&kirq0>; + interrupts = <7 15>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio7 27 0>; + status = "disabled"; + }; + mdio: mdio@02090300 { compatible = "ti,keystone_mdio", "ti,davinci_mdio"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/keystone-k2l-evm.dts b/arch/arm/boot/dts/keystone-k2l-evm.dts index 056b42f99d7a..528667618db4 100644 --- a/arch/arm/boot/dts/keystone-k2l-evm.dts +++ b/arch/arm/boot/dts/keystone-k2l-evm.dts @@ -16,6 +16,19 @@ compatible = "ti,k2l-evm", "ti,k2l", "ti,keystone"; model = "Texas Instruments Keystone 2 Lamarr EVM"; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + dsp_common_memory: dsp-common-memory@81f800000 { + compatible = "shared-dma-pool"; + reg = <0x00000008 0x1f800000 0x00000000 0x800000>; + reusable; + status = "okay"; + }; + }; + soc { clocks { refclksys: refclksys { @@ -133,3 +146,23 @@ reg = <1>; }; }; + +&dsp0 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp1 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp2 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; + +&dsp3 { + memory-region = <&dsp_common_memory>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2l.dtsi b/arch/arm/boot/dts/keystone-k2l.dtsi index 148650406cf7..4431310bc922 100644 --- a/arch/arm/boot/dts/keystone-k2l.dtsi +++ b/arch/arm/boot/dts/keystone-k2l.dtsi @@ -33,6 +33,13 @@ }; }; + aliases { + rproc0 = &dsp0; + rproc1 = &dsp1; + rproc2 = &dsp2; + rproc3 = &dsp3; + }; + soc { /include/ "keystone-k2l-clocks.dtsi" @@ -268,6 +275,70 @@ gpio,syscon-dev = <&devctrl 0x24c>; }; + dsp0: dsp@10800000 { + compatible = "ti,k2l-dsp"; + reg = <0x10800000 0x00100000>, + <0x10e00000 0x00008000>, + <0x10f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem0>; + ti,syscon-dev = <&devctrl 0x844>; + resets = <&pscrst 0>; + interrupt-parent = <&kirq0>; + interrupts = <0 8>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio0 27 0>; + status = "disabled"; + }; + + dsp1: dsp@11800000 { + compatible = "ti,k2l-dsp"; + reg = <0x11800000 0x00100000>, + <0x11e00000 0x00008000>, + <0x11f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem1>; + ti,syscon-dev = <&devctrl 0x848>; + resets = <&pscrst 1>; + interrupt-parent = <&kirq0>; + interrupts = <1 9>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio1 27 0>; + status = "disabled"; + }; + + dsp2: dsp@12800000 { + compatible = "ti,k2l-dsp"; + reg = <0x12800000 0x00100000>, + <0x12e00000 0x00008000>, + <0x12f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem2>; + ti,syscon-dev = <&devctrl 0x84c>; + resets = <&pscrst 2>; + interrupt-parent = <&kirq0>; + interrupts = <2 10>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio2 27 0>; + status = "disabled"; + }; + + dsp3: dsp@13800000 { + compatible = "ti,k2l-dsp"; + reg = <0x13800000 0x00100000>, + <0x13e00000 0x00008000>, + <0x13f00000 0x00008000>; + reg-names = "l2sram", "l1pram", "l1dram"; + clocks = <&clkgem3>; + ti,syscon-dev = <&devctrl 0x850>; + resets = <&pscrst 3>; + interrupt-parent = <&kirq0>; + interrupts = <3 11>; + interrupt-names = "vring", "exception"; + kick-gpios = <&dspgpio3 27 0>; + status = "disabled"; + }; + mdio: mdio@26200f00 { compatible = "ti,keystone_mdio", "ti,davinci_mdio"; #address-cells = <1>; diff --git a/arch/arm/boot/dts/kirkwood-6192.dtsi b/arch/arm/boot/dts/kirkwood-6192.dtsi index d573e03f3134..396bcba08adb 100644 --- a/arch/arm/boot/dts/kirkwood-6192.dtsi +++ b/arch/arm/boot/dts/kirkwood-6192.dtsi @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -24,6 +25,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/kirkwood-6281.dtsi b/arch/arm/boot/dts/kirkwood-6281.dtsi index 748d0b62f233..faa05849a40d 100644 --- a/arch/arm/boot/dts/kirkwood-6281.dtsi +++ b/arch/arm/boot/dts/kirkwood-6281.dtsi @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -24,6 +25,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/kirkwood-6282.dtsi b/arch/arm/boot/dts/kirkwood-6282.dtsi index bb63d2d50fc5..e84c54b77dea 100644 --- a/arch/arm/boot/dts/kirkwood-6282.dtsi +++ b/arch/arm/boot/dts/kirkwood-6282.dtsi @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -28,6 +29,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; @@ -45,6 +47,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 0x81000000 0 0 0x81000000 0x2 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 10>; marvell,pcie-port = <1>; diff --git a/arch/arm/boot/dts/kirkwood-98dx4122.dtsi b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi index 720c210d491d..299c147298c3 100644 --- a/arch/arm/boot/dts/kirkwood-98dx4122.dtsi +++ b/arch/arm/boot/dts/kirkwood-98dx4122.dtsi @@ -1,6 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 / { mbus@f1000000 { - pciec: pcie-controller@82000000 { + pciec: pcie@82000000 { compatible = "marvell,kirkwood-pcie"; status = "disabled"; device_type = "pci"; @@ -24,6 +25,7 @@ #interrupt-cells = <1>; ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 0x81000000 0 0 0x81000000 0x1 0 1 0>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0 0 0 0>; interrupt-map = <0 0 0 0 &intc 9>; marvell,pcie-port = <0>; diff --git a/arch/arm/boot/dts/kirkwood-cloudbox.dts b/arch/arm/boot/dts/kirkwood-cloudbox.dts index 555b7e4c58a5..448b0cd23b5f 100644 --- a/arch/arm/boot/dts/kirkwood-cloudbox.dts +++ b/arch/arm/boot/dts/kirkwood-cloudbox.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts index d85ef0a91b50..d6b0f418fd01 100644 --- a/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/arch/arm/boot/dts/kirkwood-dns320.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood-dnskw.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts index 5e586ed04c58..94d9c06cbbf5 100644 --- a/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/arch/arm/boot/dts/kirkwood-dns325.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood-dnskw.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi index d8fca9db46d0..cbaf06f2f78e 100644 --- a/arch/arm/boot/dts/kirkwood-dnskw.dtsi +++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "kirkwood.dtsi" #include "kirkwood-6281.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts index 849736349511..6a3f1bf6d9f1 100644 --- a/arch/arm/boot/dts/kirkwood-dockstar.dts +++ b/arch/arm/boot/dts/kirkwood-dockstar.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index e2abc8246bf3..7f326e267494 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts index aa60a0b049a7..02d87e0a1061 100644 --- a/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts index b2d9834bf458..ff1260ee3fe8 100644 --- a/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts +++ b/arch/arm/boot/dts/kirkwood-guruplug-server-plus.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index 5bf62897014c..962a910a6f5c 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index d25184ae4af3..4a512d80912c 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts index 8474bffec0ca..62272d58664f 100644 --- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts +++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-is2.dts b/arch/arm/boot/dts/kirkwood-is2.dts index 4121674abd1c..1bc16a5cdbaa 100644 --- a/arch/arm/boot/dts/kirkwood-is2.dts +++ b/arch/arm/boot/dts/kirkwood-is2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/kirkwood-km_common.dtsi b/arch/arm/boot/dts/kirkwood-km_common.dtsi index 7962bdefde49..75dc83914f56 100644 --- a/arch/arm/boot/dts/kirkwood-km_common.dtsi +++ b/arch/arm/boot/dts/kirkwood-km_common.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { chosen { bootargs = "console=ttyS0,115200n8 earlyprintk"; diff --git a/arch/arm/boot/dts/kirkwood-km_fixedeth.dts b/arch/arm/boot/dts/kirkwood-km_fixedeth.dts index 9895f2b10f8a..515be7bccc0a 100644 --- a/arch/arm/boot/dts/kirkwood-km_fixedeth.dts +++ b/arch/arm/boot/dts/kirkwood-km_fixedeth.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts index 235bf382fff9..f035eff1c111 100644 --- a/arch/arm/boot/dts/kirkwood-km_kirkwood.dts +++ b/arch/arm/boot/dts/kirkwood-km_kirkwood.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-lschlv2.dts b/arch/arm/boot/dts/kirkwood-lschlv2.dts index e2fa368aef25..1d737d903f5f 100644 --- a/arch/arm/boot/dts/kirkwood-lschlv2.dts +++ b/arch/arm/boot/dts/kirkwood-lschlv2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood-lsxl.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-lsxhl.dts b/arch/arm/boot/dts/kirkwood-lsxhl.dts index 8d89cdf8d6bf..a56e0d797778 100644 --- a/arch/arm/boot/dts/kirkwood-lsxhl.dts +++ b/arch/arm/boot/dts/kirkwood-lsxhl.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood-lsxl.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi index 8b7c6ce79a41..7b151acb9984 100644 --- a/arch/arm/boot/dts/kirkwood-lsxl.dtsi +++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "kirkwood.dtsi" #include "kirkwood-6281.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-mplcec4.dts b/arch/arm/boot/dts/kirkwood-mplcec4.dts index aa413b0bcce2..b80d12f6aa49 100644 --- a/arch/arm/boot/dts/kirkwood-mplcec4.dts +++ b/arch/arm/boot/dts/kirkwood-mplcec4.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi index 282605f4c92c..51530ea86622 100644 --- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "kirkwood.dtsi" #include "kirkwood-6281.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-ns2.dts b/arch/arm/boot/dts/kirkwood-ns2.dts index 190189d235e6..7b67083e1ec0 100644 --- a/arch/arm/boot/dts/kirkwood-ns2.dts +++ b/arch/arm/boot/dts/kirkwood-ns2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/kirkwood-ns2lite.dts b/arch/arm/boot/dts/kirkwood-ns2lite.dts index 2c661add0cc0..b0cb5907ed63 100644 --- a/arch/arm/boot/dts/kirkwood-ns2lite.dts +++ b/arch/arm/boot/dts/kirkwood-ns2lite.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood-ns2-common.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-ns2max.dts b/arch/arm/boot/dts/kirkwood-ns2max.dts index 55cc41d9c80c..c0a087e77408 100644 --- a/arch/arm/boot/dts/kirkwood-ns2max.dts +++ b/arch/arm/boot/dts/kirkwood-ns2max.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/kirkwood-ns2mini.dts b/arch/arm/boot/dts/kirkwood-ns2mini.dts index 9935f3ec29b4..5b9fa14b6428 100644 --- a/arch/arm/boot/dts/kirkwood-ns2mini.dts +++ b/arch/arm/boot/dts/kirkwood-ns2mini.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts index 0b69ee4934fa..9b861c2e76c5 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood-nsa3x0-common.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-nsa310a.dts b/arch/arm/boot/dts/kirkwood-nsa310a.dts index 3d2b3d494c19..b85e314f045a 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310a.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310a.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood-nsa3x0-common.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi index e09b79ac73fd..2c4037b07282 100644 --- a/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-nsa3x0-common.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "kirkwood.dtsi" #include "kirkwood-6281.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts index c75da5f0ca48..8ea430168ea5 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts index b2f26239d298..5ce220ac9611 100644 --- a/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts +++ b/arch/arm/boot/dts/kirkwood-pogoplug-series-4.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * kirkwood-pogoplug-series-4.dts - Device tree file for PogoPlug Series 4 * inspired by the board files made by Kevin Mihelich for ArchLinux, diff --git a/arch/arm/boot/dts/kirkwood-topkick.dts b/arch/arm/boot/dts/kirkwood-topkick.dts index 330aada6d33f..a5b51e29f63e 100644 --- a/arch/arm/boot/dts/kirkwood-topkick.dts +++ b/arch/arm/boot/dts/kirkwood-topkick.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts index ee62204e4ecd..30892c19aceb 100644 --- a/arch/arm/boot/dts/kirkwood-ts219-6281.dts +++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts index 3437bb396844..aba1205981f1 100644 --- a/arch/arm/boot/dts/kirkwood-ts219-6282.dts +++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "kirkwood.dtsi" diff --git a/arch/arm/boot/dts/kirkwood-ts219.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi index 62e5e2d5c348..4faea1d9facf 100644 --- a/arch/arm/boot/dts/kirkwood-ts219.dtsi +++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { model = "QNAP TS219 family"; compatible = "qnap,ts219", "marvell,kirkwood"; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 29b8bd7e0d93..a70fc7f01fc3 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /include/ "skeleton.dtsi" #include #include diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts index 43e9364083de..b4575bbaf085 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts +++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts @@ -192,7 +192,7 @@ interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins &mmc1_cd>; - cd-gpios = <&gpio4 31 IRQ_TYPE_LEVEL_LOW>; /* gpio127 */ + cd-gpios = <&gpio4 31 GPIO_ACTIVE_LOW>; /* gpio127 */ vmmc-supply = <&vmmc1>; bus-width = <4>; cap-power-off-card; diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 7bb9df2c1460..9319e1f0f1d8 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -129,14 +129,14 @@ }; msi1: msi-controller@1570e00 { - compatible = "fsl,1s1021a-msi"; + compatible = "fsl,ls1021a-msi"; reg = <0x0 0x1570e00 0x0 0x8>; msi-controller; interrupts = ; }; msi2: msi-controller@1570e08 { - compatible = "fsl,1s1021a-msi"; + compatible = "fsl,ls1021a-msi"; reg = <0x0 0x1570e08 0x0 0x8>; msi-controller; interrupts = ; @@ -699,7 +699,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi1>; + msi-parent = <&msi1>, <&msi2>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, @@ -722,7 +722,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi2>; + msi-parent = <&msi1>, <&msi2>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm/boot/dts/meson.dtsi b/arch/arm/boot/dts/meson.dtsi index 15204e44161d..cd6ad072e72c 100644 --- a/arch/arm/boot/dts/meson.dtsi +++ b/arch/arm/boot/dts/meson.dtsi @@ -86,14 +86,14 @@ }; uart_A: serial@84c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; reg = <0x84c0 0x18>; interrupts = ; status = "disabled"; }; uart_B: serial@84dc { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; reg = <0x84dc 0x18>; interrupts = ; status = "disabled"; @@ -108,6 +108,20 @@ status = "disabled"; }; + pwm_ab: pwm@8550 { + compatible = "amlogic,meson-pwm"; + reg = <0x8550 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm_cd: pwm@8650 { + compatible = "amlogic,meson-pwm"; + reg = <0x8650 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + saradc: adc@8680 { compatible = "amlogic,meson-saradc"; reg = <0x8680 0x34>; @@ -117,7 +131,7 @@ }; uart_C: serial@8700 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; reg = <0x8700 0x18>; interrupts = ; status = "disabled"; @@ -182,7 +196,7 @@ }; uart_AO: serial@4c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; reg = <0x4c0 0x18>; interrupts = ; status = "disabled"; @@ -230,5 +244,13 @@ interrupt-names = "macirq"; status = "disabled"; }; + + ahb_sram: sram@d9000000 { + compatible = "mmio-sram"; + reg = <0xd9000000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xd9000000 0x20000>; + }; }; }; /* end of / */ diff --git a/arch/arm/boot/dts/meson6.dtsi b/arch/arm/boot/dts/meson6.dtsi index 8557b6117a4b..ef281d290052 100644 --- a/arch/arm/boot/dts/meson6.dtsi +++ b/arch/arm/boot/dts/meson6.dtsi @@ -70,9 +70,37 @@ }; }; + xtal: xtal-clk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xtal"; + #clock-cells = <0>; + }; + clk81: clk@0 { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <200000000>; }; }; /* end of / */ + + +&uart_AO { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_A { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_B { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_C { + clocks = <&xtal>, <&clk81>, <&clk81>; + clock-names = "xtal", "pclk", "baud"; +}; diff --git a/arch/arm/boot/dts/meson8.dtsi b/arch/arm/boot/dts/meson8.dtsi index cada35828931..b98d44fde6b6 100644 --- a/arch/arm/boot/dts/meson8.dtsi +++ b/arch/arm/boot/dts/meson8.dtsi @@ -168,10 +168,18 @@ &cbus { clkc: clock-controller@4000 { #clock-cells = <1>; + #reset-cells = <1>; compatible = "amlogic,meson8-clkc"; reg = <0x8000 0x4>, <0x4000 0x460>; }; + pwm_ef: pwm@86c0 { + compatible = "amlogic,meson8-pwm", "amlogic,meson8b-pwm"; + reg = <0x86c0 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + pinctrl_cbus: pinctrl@9880 { compatible = "amlogic,meson8-cbus-pinctrl"; reg = <0x9880 0x10>; @@ -270,6 +278,14 @@ arm,filter-ranges = <0x100000 0xc0000000>; }; +&pwm_ab { + compatible = "amlogic,meson8-pwm", "amlogic,meson8b-pwm"; +}; + +&pwm_cd { + compatible = "amlogic,meson8-pwm", "amlogic,meson8b-pwm"; +}; + &saradc { compatible = "amlogic,meson8-saradc", "amlogic,meson-saradc"; clocks = <&clkc CLKID_XTAL>, diff --git a/arch/arm/boot/dts/meson8b.dtsi b/arch/arm/boot/dts/meson8b.dtsi index 72e4f425f190..bc278da7df0d 100644 --- a/arch/arm/boot/dts/meson8b.dtsi +++ b/arch/arm/boot/dts/meson8b.dtsi @@ -119,6 +119,7 @@ &cbus { clkc: clock-controller@4000 { #clock-cells = <1>; + #reset-cells = <1>; compatible = "amlogic,meson8b-clkc"; reg = <0x8000 0x4>, <0x4000 0x460>; }; @@ -129,20 +130,6 @@ #reset-cells = <1>; }; - pwm_ab: pwm@8550 { - compatible = "amlogic,meson8b-pwm"; - reg = <0x8550 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; - - pwm_cd: pwm@8650 { - compatible = "amlogic,meson8b-pwm"; - reg = <0x8650 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; - pwm_ef: pwm@86c0 { compatible = "amlogic,meson8b-pwm"; reg = <0x86c0 0x10>; @@ -150,12 +137,6 @@ status = "disabled"; }; - wdt: watchdog@9900 { - compatible = "amlogic,meson8b-wdt"; - reg = <0x9900 0x8>; - interrupts = <0 0 1>; - }; - pinctrl_cbus: pinctrl@9880 { compatible = "amlogic,meson8b-cbus-pinctrl"; reg = <0x9880 0x10>; @@ -193,6 +174,14 @@ arm,filter-ranges = <0x100000 0xc0000000>; }; +&pwm_ab { + compatible = "amlogic,meson8b-pwm"; +}; + +&pwm_cd { + compatible = "amlogic,meson8b-pwm"; +}; + &saradc { compatible = "amlogic,meson8b-saradc", "amlogic,meson-saradc"; clocks = <&clkc CLKID_XTAL>, @@ -242,3 +231,7 @@ clock-names = "usb_general", "usb"; resets = <&reset RESET_USB_OTG>; }; + +&wdt { + compatible = "amlogic,meson8b-wdt"; +}; diff --git a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi index 1eb5da1dc8f0..4d61e5b1334a 100644 --- a/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi +++ b/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi @@ -255,5 +255,6 @@ regulator-min-microvolt = <2775000>; regulator-max-microvolt = <2775000>; regulator-enable-ramp-delay = <1000>; + regulator-initial-mode = <0x00>; /* NORMAL */ }; }; diff --git a/arch/arm/boot/dts/moxart.dtsi b/arch/arm/boot/dts/moxart.dtsi index 1f4c795d3f72..da7b3237bfe9 100644 --- a/arch/arm/boot/dts/moxart.dtsi +++ b/arch/arm/boot/dts/moxart.dtsi @@ -87,9 +87,10 @@ }; watchdog: watchdog@98500000 { - compatible = "moxa,moxart-watchdog"; + compatible = "moxa,moxart-watchdog", "faraday,ftwdt010"; reg = <0x98500000 0x10>; clocks = <&clk_apb>; + clock-names = "PCLK"; }; sdhci: sdhci@98e00000 { diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi index f1efdc63656a..afe12e5b51f9 100644 --- a/arch/arm/boot/dts/mt2701.dtsi +++ b/arch/arm/boot/dts/mt2701.dtsi @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -533,6 +534,7 @@ compatible = "mediatek,mt2701-smi-larb"; reg = <0 0x14010000 0 0x1000>; mediatek,smi = <&smi_common>; + mediatek,larb-id = <0>; clocks = <&mmsys CLK_MM_SMI_LARB0>, <&mmsys CLK_MM_SMI_LARB0>; clock-names = "apb", "smi"; @@ -549,6 +551,7 @@ compatible = "mediatek,mt2701-smi-larb"; reg = <0 0x15001000 0 0x1000>; mediatek,smi = <&smi_common>; + mediatek,larb-id = <2>; clocks = <&imgsys CLK_IMG_SMI_COMM>, <&imgsys CLK_IMG_SMI_COMM>; clock-names = "apb", "smi"; @@ -579,6 +582,7 @@ compatible = "mediatek,mt2701-smi-larb"; reg = <0 0x16010000 0 0x1000>; mediatek,smi = <&smi_common>; + mediatek,larb-id = <1>; clocks = <&vdecsys CLK_VDEC_CKGEN>, <&vdecsys CLK_VDEC_LARB>; clock-names = "apb", "smi"; @@ -591,12 +595,114 @@ #clock-cells = <1>; }; + usb0: usb@1a1c0000 { + compatible = "mediatek,mt8173-xhci"; + reg = <0 0x1a1c0000 0 0x1000>, + <0 0x1a1c4700 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + clocks = <&hifsys CLK_HIFSYS_USB0PHY>, + <&topckgen CLK_TOP_ETHIF_SEL>; + clock-names = "sys_ck", "ref_ck"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + phys = <&u2port0 PHY_TYPE_USB2>, <&u3port0 PHY_TYPE_USB3>; + status = "disabled"; + }; + + u3phy0: usb-phy@1a1c4000 { + compatible = "mediatek,mt2701-u3phy"; + reg = <0 0x1a1c4000 0 0x0700>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + u2port0: usb-phy@1a1c4800 { + reg = <0 0x1a1c4800 0 0x0100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port0: usb-phy@1a1c4900 { + reg = <0 0x1a1c4900 0 0x0700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + + usb1: usb@1a240000 { + compatible = "mediatek,mt8173-xhci"; + reg = <0 0x1a240000 0 0x1000>, + <0 0x1a244700 0 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + clocks = <&hifsys CLK_HIFSYS_USB1PHY>, + <&topckgen CLK_TOP_ETHIF_SEL>; + clock-names = "sys_ck", "ref_ck"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_HIF>; + phys = <&u2port1 PHY_TYPE_USB2>, <&u3port1 PHY_TYPE_USB3>; + status = "disabled"; + }; + + u3phy1: usb-phy@1a244000 { + compatible = "mediatek,mt2701-u3phy"; + reg = <0 0x1a244000 0 0x0700>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "disabled"; + + u2port1: usb-phy@1a244800 { + reg = <0 0x1a244800 0 0x0100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port1: usb-phy@1a244900 { + reg = <0 0x1a244900 0 0x0700>; + clocks = <&clk26m>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + ethsys: syscon@1b000000 { compatible = "mediatek,mt2701-ethsys", "syscon"; reg = <0 0x1b000000 0 0x1000>; #clock-cells = <1>; }; + eth: ethernet@1b100000 { + compatible = "mediatek,mt2701-eth", "syscon"; + reg = <0 0x1b100000 0 0x20000>; + interrupts = , + , + ; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <ðsys CLK_ETHSYS_ESW>, + <ðsys CLK_ETHSYS_GP1>, + <ðsys CLK_ETHSYS_GP2>, + <&apmixedsys CLK_APMIXED_TRGPLL>; + clock-names = "ethif", "esw", "gp1", "gp2", "trgpll"; + resets = <ðsys MT2701_ETHSYS_FE_RST>, + <ðsys MT2701_ETHSYS_GMAC_RST>, + <ðsys MT2701_ETHSYS_PPE_RST>; + reset-names = "fe", "gmac", "ppe"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; + mediatek,ethsys = <ðsys>; + mediatek,pctl = <&syscfg_pctl_a>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + bdpsys: syscon@1c000000 { compatible = "mediatek,mt2701-bdpsys", "syscon"; reg = <0 0x1c000000 0 0x1000>; diff --git a/arch/arm/boot/dts/mt6323.dtsi b/arch/arm/boot/dts/mt6323.dtsi new file mode 100644 index 000000000000..7c783d6c750e --- /dev/null +++ b/arch/arm/boot/dts/mt6323.dtsi @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: John Crispin + * Sean Wang + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&pwrap { + pmic: mt6323 { + compatible = "mediatek,mt6323"; + interrupt-parent = <&pio>; + interrupts = <150 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <2>; + + mt6323regulator: mt6323regulator{ + compatible = "mediatek,mt6323-regulator"; + + mt6323_vproc_reg: buck_vproc{ + regulator-name = "vproc"; + regulator-min-microvolt = < 700000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vsys_reg: buck_vsys{ + regulator-name = "vsys"; + regulator-min-microvolt = <1400000>; + regulator-max-microvolt = <2987500>; + regulator-ramp-delay = <25000>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vpa_reg: buck_vpa{ + regulator-name = "vpa"; + regulator-min-microvolt = < 500000>; + regulator-max-microvolt = <3650000>; + }; + + mt6323_vtcxo_reg: ldo_vtcxo{ + regulator-name = "vtcxo"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <90>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcn28_reg: ldo_vcn28{ + regulator-name = "vcn28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <185>; + }; + + mt6323_vcn33_bt_reg: ldo_vcn33_bt{ + regulator-name = "vcn33_bt"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3600000>; + regulator-enable-ramp-delay = <185>; + }; + + mt6323_vcn33_wifi_reg: ldo_vcn33_wifi{ + regulator-name = "vcn33_wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3600000>; + regulator-enable-ramp-delay = <185>; + }; + + mt6323_va_reg: ldo_va{ + regulator-name = "va"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcama_reg: ldo_vcama{ + regulator-name = "vcama"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vio28_reg: ldo_vio28{ + regulator-name = "vio28"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vusb_reg: ldo_vusb{ + regulator-name = "vusb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <216>; + regulator-boot-on; + }; + + mt6323_vmc_reg: ldo_vmc{ + regulator-name = "vmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + regulator-boot-on; + }; + + mt6323_vmch_reg: ldo_vmch{ + regulator-name = "vmch"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + regulator-boot-on; + }; + + mt6323_vemc3v3_reg: ldo_vemc3v3{ + regulator-name = "vemc3v3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + regulator-boot-on; + }; + + mt6323_vgp1_reg: ldo_vgp1{ + regulator-name = "vgp1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vgp2_reg: ldo_vgp2{ + regulator-name = "vgp2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vgp3_reg: ldo_vgp3{ + regulator-name = "vgp3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vcn18_reg: ldo_vcn18{ + regulator-name = "vcn18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vsim1_reg: ldo_vsim1{ + regulator-name = "vsim1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vsim2_reg: ldo_vsim2{ + regulator-name = "vsim2"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vrtc_reg: ldo_vrtc{ + regulator-name = "vrtc"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcamaf_reg: ldo_vcamaf{ + regulator-name = "vcamaf"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vibr_reg: ldo_vibr{ + regulator-name = "vibr"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <36>; + }; + + mt6323_vrf18_reg: ldo_vrf18{ + regulator-name = "vrf18"; + regulator-min-microvolt = <1825000>; + regulator-max-microvolt = <1825000>; + regulator-enable-ramp-delay = <187>; + }; + + mt6323_vm_reg: ldo_vm{ + regulator-name = "vm"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vio18_reg: ldo_vio18{ + regulator-name = "vio18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + regulator-always-on; + regulator-boot-on; + }; + + mt6323_vcamd_reg: ldo_vcamd{ + regulator-name = "vcamd"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + + mt6323_vcamio_reg: ldo_vcamio{ + regulator-name = "vcamio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <216>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi index d81158b2b02f..ec8a07415cb3 100644 --- a/arch/arm/boot/dts/mt7623.dtsi +++ b/arch/arm/boot/dts/mt7623.dtsi @@ -21,36 +21,99 @@ #include #include #include +#include #include "skeleton64.dtsi" / { compatible = "mediatek,mt7623"; interrupt-parent = <&sysirq>; + cpu_opp_table: opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp-98000000 { + opp-hz = /bits/ 64 <98000000>; + opp-microvolt = <1050000>; + }; + + opp-198000000 { + opp-hz = /bits/ 64 <198000000>; + opp-microvolt = <1050000>; + }; + + opp-398000000 { + opp-hz = /bits/ 64 <398000000>; + opp-microvolt = <1050000>; + }; + + opp-598000000 { + opp-hz = /bits/ 64 <598000000>; + opp-microvolt = <1050000>; + }; + + opp-747500000 { + opp-hz = /bits/ 64 <747500000>; + opp-microvolt = <1050000>; + }; + + opp-1040000000 { + opp-hz = /bits/ 64 <1040000000>; + opp-microvolt = <1150000>; + }; + + opp-1196000000 { + opp-hz = /bits/ 64 <1196000000>; + opp-microvolt = <1200000>; + }; + + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1300000>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; enable-method = "mediatek,mt6589-smp"; - cpu@0 { + cpu0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x0>; + clocks = <&infracfg CLK_INFRA_CPUSEL>, + <&apmixedsys CLK_APMIXED_MAINPLL>; + clock-names = "cpu", "intermediate"; + operating-points-v2 = <&cpu_opp_table>; + #cooling-cells = <2>; + cooling-min-level = <0>; + cooling-max-level = <7>; + clock-frequency = <1300000000>; }; - cpu@1 { + + cpu1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x1>; + operating-points-v2 = <&cpu_opp_table>; + clock-frequency = <1300000000>; }; - cpu@2 { + + cpu2: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x2>; + operating-points-v2 = <&cpu_opp_table>; + clock-frequency = <1300000000>; }; - cpu@3 { + + cpu3: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0x3>; + operating-points-v2 = <&cpu_opp_table>; + clock-frequency = <1300000000>; }; }; @@ -74,6 +137,58 @@ clock-output-names = "clk26m"; }; + thermal-zones { + cpu_thermal: cpu_thermal { + polling-delay-passive = <1000>; + polling-delay = <1000>; + + thermal-sensors = <&thermal 0>; + + trips { + cpu_passive: cpu_passive { + temperature = <47000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_active: cpu_active { + temperature = <67000>; + hysteresis = <2000>; + type = "active"; + }; + + cpu_hot: cpu_hot { + temperature = <87000>; + hysteresis = <2000>; + type = "hot"; + }; + + cpu_crit { + temperature = <107000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_passive>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map1 { + trip = <&cpu_active>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + + map2 { + trip = <&cpu_hot>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupt-parent = <&gic>; @@ -172,7 +287,7 @@ clock-names = "spi", "wrap"; }; - cir: cir@0x10013000 { + cir: cir@10013000 { compatible = "mediatek,mt7623-cir"; reg = <0 0x10013000 0 0x1000>; interrupts = ; @@ -193,7 +308,7 @@ efuse: efuse@10206000 { compatible = "mediatek,mt7623-efuse", "mediatek,mt8173-efuse"; - reg = <0 0x10206000 0 0x1000>; + reg = <0 0x10206000 0 0x1000>; #address-cells = <1>; #size-cells = <1>; thermal_calibration_data: calib@424 { @@ -371,6 +486,31 @@ nvmem-cell-names = "calibration-data"; }; + nandc: nfi@1100d000 { + compatible = "mediatek,mt7623-nfc", + "mediatek,mt2701-nfc"; + reg = <0 0x1100d000 0 0x1000>; + interrupts = ; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + clocks = <&pericfg CLK_PERI_NFI>, + <&pericfg CLK_PERI_NFI_PAD>; + clock-names = "nfi_clk", "pad_clk"; + status = "disabled"; + ecc-engine = <&bch>; + #address-cells = <1>; + #size-cells = <0>; + }; + + bch: ecc@1100e000 { + compatible = "mediatek,mt7623-ecc", + "mediatek,mt2701-ecc"; + reg = <0 0x1100e000 0 0x1000>; + interrupts = ; + clocks = <&pericfg CLK_PERI_NFI_ECC>; + clock-names = "nfiecc_clk"; + status = "disabled"; + }; + spi1: spi@11016000 { compatible = "mediatek,mt7623-spi", "mediatek,mt2701-spi"; @@ -399,31 +539,6 @@ status = "disabled"; }; - nandc: nfi@1100d000 { - compatible = "mediatek,mt7623-nfc", - "mediatek,mt2701-nfc"; - reg = <0 0x1100d000 0 0x1000>; - interrupts = ; - power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; - clocks = <&pericfg CLK_PERI_NFI>, - <&pericfg CLK_PERI_NFI_PAD>; - clock-names = "nfi_clk", "pad_clk"; - status = "disabled"; - ecc-engine = <&bch>; - #address-cells = <1>; - #size-cells = <0>; - }; - - bch: ecc@1100e000 { - compatible = "mediatek,mt7623-ecc", - "mediatek,mt2701-ecc"; - reg = <0 0x1100e000 0 0x1000>; - interrupts = ; - clocks = <&pericfg CLK_PERI_NFI_ECC>; - clock-names = "nfiecc_clk"; - status = "disabled"; - }; - afe: audio-controller@11220000 { compatible = "mediatek,mt7623-audio", "mediatek,mt2701-audio"; @@ -538,13 +653,22 @@ compatible = "mediatek,mt7623-mmc", "mediatek,mt8135-mmc"; reg = <0 0x11240000 0 0x1000>; - interrupts = ; + interrupts = ; clocks = <&pericfg CLK_PERI_MSDC30_1>, <&topckgen CLK_TOP_MSDC30_1_SEL>; clock-names = "source", "hclk"; status = "disabled"; }; + hifsys: syscon@1a000000 { + compatible = "mediatek,mt7623-hifsys", + "mediatek,mt2701-hifsys", + "syscon"; + reg = <0 0x1a000000 0 0x1000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + usb1: usb@1a1c0000 { compatible = "mediatek,mt7623-xhci", "mediatek,mt8173-xhci"; @@ -561,7 +685,8 @@ }; u3phy1: usb-phy@1a1c4000 { - compatible = "mediatek,mt7623-u3phy", "mediatek,mt2701-u3phy"; + compatible = "mediatek,mt7623-u3phy", + "mediatek,mt2701-u3phy"; reg = <0 0x1a1c4000 0 0x0700>; clocks = <&clk26m>; clock-names = "u3phya_ref"; @@ -599,7 +724,8 @@ }; u3phy2: usb-phy@1a244000 { - compatible = "mediatek,mt7623-u3phy", "mediatek,mt2701-u3phy"; + compatible = "mediatek,mt7623-u3phy", + "mediatek,mt2701-u3phy"; reg = <0 0x1a244000 0 0x0700>; clocks = <&clk26m>; clock-names = "u3phya_ref"; @@ -621,15 +747,6 @@ }; }; - hifsys: syscon@1a000000 { - compatible = "mediatek,mt7623-hifsys", - "mediatek,mt2701-hifsys", - "syscon"; - reg = <0 0x1a000000 0 0x1000>; - #clock-cells = <1>; - #reset-cells = <1>; - }; - ethsys: syscon@1b000000 { compatible = "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", @@ -639,7 +756,9 @@ }; eth: ethernet@1b100000 { - compatible = "mediatek,mt2701-eth", "syscon"; + compatible = "mediatek,mt7623-eth", + "mediatek,mt2701-eth", + "syscon"; reg = <0 0x1b100000 0 0x20000>; interrupts = , , @@ -650,6 +769,10 @@ <ðsys CLK_ETHSYS_GP2>, <&apmixedsys CLK_APMIXED_TRGPLL>; clock-names = "ethif", "esw", "gp1", "gp2", "trgpll"; + resets = <ðsys MT2701_ETHSYS_FE_RST>, + <ðsys MT2701_ETHSYS_GMAC_RST>, + <ðsys MT2701_ETHSYS_PPE_RST>; + reset-names = "fe", "gmac", "ppe"; power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; mediatek,ethsys = <ðsys>; mediatek,pctl = <&syscfg_pctl_a>; diff --git a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts new file mode 100644 index 000000000000..688a86378cee --- /dev/null +++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts @@ -0,0 +1,487 @@ +/* + * Copyright 2017 Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; +#include +#include "mt7623.dtsi" +#include "mt6323.dtsi" + +/ { + model = "Bananapi BPI-R2"; + compatible = "bananapi,bpi-r2", "mediatek,mt7623"; + + aliases { + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + cpus { + cpu@0 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@1 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@2 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu@3 { + proc-supply = <&mt6323_vproc_reg>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&key_pins_a>; + + factory { + label = "factory"; + linux,code = ; + gpios = <&pio 256 GPIO_ACTIVE_LOW>; + }; + + wps { + label = "wps"; + linux,code = ; + gpios = <&pio 257 GPIO_ACTIVE_HIGH>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_a>; + + blue { + label = "bpi-r2:pio:blue"; + gpios = <&pio 241 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + green { + label = "bpi-r2:pio:green"; + gpios = <&pio 240 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + + red { + label = "bpi-r2:pio:red"; + gpios = <&pio 239 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + memory@80000000 { + reg = <0 0x80000000 0 0x40000000>; + }; +}; + +&cir { + pinctrl-names = "default"; + pinctrl-0 = <&cir_pins_a>; + status = "okay"; +}; + +&crypto { + status = "okay"; +}; + +ð { + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + pause; + }; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + switch@0 { + compatible = "mediatek,mt7530"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + pinctrl-names = "default"; + reset-gpios = <&pio 33 0>; + core-supply = <&mt6323_vpa_reg>; + io-supply = <&mt6323_vemc3v3_reg>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + port@0 { + reg = <0>; + label = "wan"; + }; + + port@1 { + reg = <1>; + label = "lan0"; + }; + + port@2 { + reg = <2>; + label = "lan1"; + }; + + port@3 { + reg = <3>; + label = "lan2"; + }; + + port@4 { + reg = <4>; + label = "lan3"; + }; + + port@6 { + reg = <6>; + label = "cpu"; + ethernet = <&gmac0>; + phy-mode = "trgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_pins_default>; + pinctrl-1 = <&mmc0_pins_uhs>; + status = "okay"; + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; + vmmc-supply = <&mt6323_vemc3v3_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; + non-removable; +}; + +&mmc1 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc1_pins_default>; + pinctrl-1 = <&mmc1_pins_uhs>; + status = "okay"; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + cd-gpios = <&pio 261 0>; + vmmc-supply = <&mt6323_vmch_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; +}; + +&pio { + cir_pins_a:cir@0 { + pins_cir { + pinmux = ; + bias-disable; + }; + }; + + i2c0_pins_a: i2c@0 { + pins_i2c0 { + pinmux = , + ; + bias-disable; + }; + }; + + i2c1_pins_a: i2c@1 { + pin_i2c1 { + pinmux = , + ; + bias-disable; + }; + }; + + i2s0_pins_a: i2s@0 { + pin_i2s0 { + pinmux = , + , + , + , + ; + drive-strength = ; + bias-pull-down; + }; + }; + + i2s1_pins_a: i2s@1 { + pin_i2s1 { + pinmux = , + , + , + , + ; + drive-strength = ; + bias-pull-down; + }; + }; + + key_pins_a: keys@0 { + pins_keys { + pinmux = , + ; + input-enable; + }; + }; + + led_pins_a: leds@0 { + pins_leds { + pinmux = , + , + ; + }; + }; + + mmc0_pins_default: mmc0default { + pins_cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + bias-pull-up; + }; + + pins_clk { + pinmux = ; + bias-pull-down; + }; + + pins_rst { + pinmux = ; + bias-pull-up; + }; + }; + + mmc0_pins_uhs: mmc0 { + pins_cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + pins_clk { + pinmux = ; + drive-strength = ; + bias-pull-down = ; + }; + + pins_rst { + pinmux = ; + bias-pull-up; + }; + }; + + mmc1_pins_default: mmc1default { + pins_cmd_dat { + pinmux = , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + pins_clk { + pinmux = ; + bias-pull-down; + drive-strength = ; + }; + + pins_wp { + pinmux = ; + input-enable; + bias-pull-up; + }; + + pins_insert { + pinmux = ; + bias-pull-up; + }; + }; + + mmc1_pins_uhs: mmc1 { + pins_cmd_dat { + pinmux = , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + pins_clk { + pinmux = ; + drive-strength = ; + bias-pull-down = ; + }; + }; + + pwm_pins_a: pwm@0 { + pins_pwm { + pinmux = , + , + , + , + ; + }; + }; + + spi0_pins_a: spi@0 { + pins_spi { + pinmux = , + , + , + ; + bias-disable; + }; + }; + + uart0_pins_a: uart@0 { + pins_dat { + pinmux = , + ; + }; + }; + + uart1_pins_a: uart@1 { + pins_dat { + pinmux = , + ; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins_a>; + status = "okay"; +}; + +&pwrap { + mt6323 { + mt6323led: led { + compatible = "mediatek,mt6323-led"; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + label = "bpi-r2:isink:green"; + default-state = "off"; + }; + + led@1 { + reg = <1>; + label = "bpi-r2:isink:red"; + default-state = "off"; + }; + + led@2 { + reg = <2>; + label = "bpi-r2:isink:blue"; + default-state = "off"; + }; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins_a>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "disabled"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_a>; + status = "disabled"; +}; + +&uart2 { + status = "okay"; +}; + +&usb1 { + vusb33-supply = <&mt6323_vusb_reg>; + status = "okay"; +}; + +&usb2 { + vusb33-supply = <&mt6323_vusb_reg>; + status = "okay"; +}; + +&u3phy1 { + status = "okay"; +}; + +&u3phy2 { + status = "okay"; +}; + diff --git a/arch/arm/boot/dts/mt7623n-rfb-nand.dts b/arch/arm/boot/dts/mt7623n-rfb-nand.dts new file mode 100644 index 000000000000..17c578f0d261 --- /dev/null +++ b/arch/arm/boot/dts/mt7623n-rfb-nand.dts @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: John Crispin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +#include "mt7623n-rfb.dtsi" + +/ { + model = "MediaTek MT7623N NAND reference board"; + compatible = "mediatek,mt7623n-rfb-nand", "mediatek,mt7623"; +}; + +&bch { + status = "okay"; +}; + +&nandc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&nand_pins_default>; + + nand@0 { + reg = <0>; + spare_per_sector = <64>; + nand-ecc-mode = "hw"; + nand-ecc-strength = <12>; + nand-ecc-step-size = <1024>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "preloader"; + reg = <0x0 0x40000>; + }; + + partition@40000 { + label = "uboot"; + reg = <0x40000 0x80000>; + }; + + partition@C0000 { + label = "uboot-env"; + reg = <0xC0000 0x40000>; + }; + + partition@140000 { + label = "bootimg"; + reg = <0x140000 0x2000000>; + }; + + partition@2140000 { + label = "recovery"; + reg = <0x2140000 0x2000000>; + }; + + partition@4140000 { + label = "rootfs"; + reg = <0x4140000 0x1000000>; + }; + + partition@5140000 { + label = "usrdata"; + reg = <0x5140000 0x1000000>; + }; + }; + }; +}; + +&pio { + nand_pins_default: nanddefault { + pins_ale { + pinmux = ; + drive-strength = ; + bias-pull-down = ; + }; + + pins_dat { + pinmux = , + , + , + , + , + , + , + , + ; + input-enable; + drive-strength = ; + bias-pull-up; + }; + + pins_we { + pinmux = ; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; diff --git a/arch/arm/boot/dts/mt7623n-rfb.dtsi b/arch/arm/boot/dts/mt7623n-rfb.dtsi new file mode 100644 index 000000000000..256c5fd947bf --- /dev/null +++ b/arch/arm/boot/dts/mt7623n-rfb.dtsi @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: John Crispin + * Sean Wang + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/dts-v1/; +#include "mt7623.dtsi" +#include "mt6323.dtsi" + +/ { + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + cpus { + cpu0 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu1 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu2 { + proc-supply = <&mt6323_vproc_reg>; + }; + + cpu3 { + proc-supply = <&mt6323_vproc_reg>; + }; + }; + + memory@80000000 { + reg = <0 0x80000000 0 0x40000000>; + }; + + usb_p1_vbus: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pio 135 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&mmc0 { + vmmc-supply = <&mt6323_vemc3v3_reg>; + vqmmc-supply = <&mt6323_vio18_reg>; +}; + +&mmc1 { + vmmc-supply = <&mt6323_vmch_reg>; + vqmmc-supply = <&mt6323_vmc_reg>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb1 { + vbus-supply = <&usb_p1_vbus>; + status = "okay"; +}; + +&u3phy1 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi index 445fafc73254..ded7e8fec9eb 100644 --- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi +++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common file for GPMC connected smsc911x on omaps * diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi index 73e272fadc20..7f6aefd13451 100644 --- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi +++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common file for GPMC connected smsc9221 on omaps * diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi index 46ef3e443861..d4ad9e58b199 100644 --- a/arch/arm/boot/dts/omap-zoom-common.dtsi +++ b/arch/arm/boot/dts/omap-zoom-common.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common features on the Zoom debug board */ diff --git a/arch/arm/boot/dts/omap2420-n800.dts b/arch/arm/boot/dts/omap2420-n800.dts index d8c1b423606a..f06d767e818b 100644 --- a/arch/arm/boot/dts/omap2420-n800.dts +++ b/arch/arm/boot/dts/omap2420-n800.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "omap2420-n8x0-common.dtsi" diff --git a/arch/arm/boot/dts/omap2420-n810-wimax.dts b/arch/arm/boot/dts/omap2420-n810-wimax.dts index 6b25b0359ac9..ac9acbd609b6 100644 --- a/arch/arm/boot/dts/omap2420-n810-wimax.dts +++ b/arch/arm/boot/dts/omap2420-n810-wimax.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "omap2420-n8x0-common.dtsi" diff --git a/arch/arm/boot/dts/omap2420-n810.dts b/arch/arm/boot/dts/omap2420-n810.dts index b604d26bd48c..7c485fbfa535 100644 --- a/arch/arm/boot/dts/omap2420-n810.dts +++ b/arch/arm/boot/dts/omap2420-n810.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "omap2420-n8x0-common.dtsi" diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi index 7e5ffc583c90..1de80c7886ab 100644 --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "omap2420.dtsi" / { @@ -15,8 +16,8 @@ >; #address-cells = <1>; #size-cells = <0>; - retu_mfd: retu@1 { - compatible = "retu-mfd"; + retu: retu@1 { + compatible = "nokia,retu"; interrupt-parent = <&gpio4>; interrupts = <12 IRQ_TYPE_EDGE_RISING>; reg = <0x1>; diff --git a/arch/arm/boot/dts/omap3-beagle-xm.dts b/arch/arm/boot/dts/omap3-beagle-xm.dts index 673cee2234b2..683b96a8f73e 100644 --- a/arch/arm/boot/dts/omap3-beagle-xm.dts +++ b/arch/arm/boot/dts/omap3-beagle-xm.dts @@ -299,7 +299,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 4be85ce59dd1..4d2eaf843fa9 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -283,7 +283,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-cm-t3517.dts b/arch/arm/boot/dts/omap3-cm-t3517.dts index 53ae04f9104d..4994e33bf663 100644 --- a/arch/arm/boot/dts/omap3-cm-t3517.dts +++ b/arch/arm/boot/dts/omap3-cm-t3517.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for CompuLab CM-T3517 */ @@ -129,7 +130,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&wl12xx_vmmc2>; - vmmc_aux-supply = <&wl12xx_vaux2>; + vqmmc-supply = <&wl12xx_vaux2>; non-removable; bus-width = <4>; cap-power-off-card; diff --git a/arch/arm/boot/dts/omap3-cm-t3530.dts b/arch/arm/boot/dts/omap3-cm-t3530.dts index 8dd14fcf6825..76e52c78cbb4 100644 --- a/arch/arm/boot/dts/omap3-cm-t3530.dts +++ b/arch/arm/boot/dts/omap3-cm-t3530.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for CompuLab CM-T3530 */ diff --git a/arch/arm/boot/dts/omap3-cm-t3730.dts b/arch/arm/boot/dts/omap3-cm-t3730.dts index 2294f5b0aa10..8c63ac5bbb12 100644 --- a/arch/arm/boot/dts/omap3-cm-t3730.dts +++ b/arch/arm/boot/dts/omap3-cm-t3730.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for CompuLab CM-T3730 */ @@ -69,7 +70,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&wl12xx_vmmc2>; - vmmc_aux-supply = <&wl12xx_vaux2>; + vqmmc-supply = <&wl12xx_vaux2>; non-removable; bus-width = <4>; cap-power-off-card; diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi index fccd5383243c..31d5ebf38892 100644 --- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi +++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common support for CompuLab CM-T3x CoMs */ diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi index 046cd7733c4f..5e8943539fcc 100644 --- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi +++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common support for CompuLab CM-T3x30 CoMs */ diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi index 82aa9c4a0f1c..0c0bb1b01b0b 100644 --- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi +++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi @@ -149,7 +149,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi index 2b1d6977a535..dbc3f030a16c 100644 --- a/arch/arm/boot/dts/omap3-evm-common.dtsi +++ b/arch/arm/boot/dts/omap3-evm-common.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common support for omap3 EVM boards */ @@ -115,7 +116,7 @@ &mmc1 { interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>; vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index 49f37084e435..4acd32a1c4ef 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -164,6 +164,29 @@ }; }; +&isp { + vdds_csib-supply = <&vaux2>; + + pinctrl-names = "default"; + pinctrl-0 = <&camera_pins>; + + ports { + port@1 { + reg = <1>; + + csi_isp: endpoint { + remote-endpoint = <&csi_cam1>; + bus-type = <3>; /* CCP2 */ + clock-lanes = <1>; + data-lanes = <0>; + lane-polarity = <0 0>; + /* Select strobe = <1> for back camera, <0> for front camera */ + strobe = <1>; + }; + }; + }; +}; + &omap3_pmx_core { pinctrl-names = "default"; @@ -328,6 +351,22 @@ OMAP3_CORE1_IOPAD(0x218e, PIN_OUTPUT | MUX_MODE4) /* gpio 157 => cmt_bsi */ >; }; + + camera_pins: pinmux_camera { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x210c, PIN_OUTPUT | MUX_MODE7) /* cam_hs */ + OMAP3_CORE1_IOPAD(0x210e, PIN_OUTPUT | MUX_MODE7) /* cam_vs */ + OMAP3_CORE1_IOPAD(0x2110, PIN_OUTPUT | MUX_MODE0) /* cam_xclka */ + OMAP3_CORE1_IOPAD(0x211e, PIN_OUTPUT | MUX_MODE7) /* cam_d4 */ + OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT | MUX_MODE0) /* cam_d6 */ + OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT | MUX_MODE0) /* cam_d7 */ + OMAP3_CORE1_IOPAD(0x2126, PIN_INPUT | MUX_MODE0) /* cam_d8 */ + OMAP3_CORE1_IOPAD(0x2128, PIN_INPUT | MUX_MODE0) /* cam_d9 */ + OMAP3_CORE1_IOPAD(0x212a, PIN_OUTPUT | MUX_MODE7) /* cam_d10 */ + OMAP3_CORE1_IOPAD(0x212e, PIN_OUTPUT | MUX_MODE7) /* cam_xclkb */ + OMAP3_CORE1_IOPAD(0x2132, PIN_OUTPUT | MUX_MODE0) /* cam_strobe */ + >; + }; }; &i2c1 { @@ -726,6 +765,40 @@ st,max-limit-y = <32>; st,max-limit-z = <32>; }; + + cam1: camera@3e { + compatible = "toshiba,et8ek8"; + reg = <0x3e>; + + vana-supply = <&vaux4>; + + clocks = <&isp 0>; + clock-names = "extclk"; + clock-frequency = <9600000>; + + reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */ + + port { + csi_cam1: endpoint { + bus-type = <3>; /* CCP2 */ + strobe = <1>; + clock-inv = <0>; + crc = <1>; + + remote-endpoint = <&csi_isp>; + }; + }; + }; + + /* D/A converter for auto-focus */ + ad5820: dac@0c { + compatible = "adi,ad5820"; + reg = <0x0c>; + + VANA-supply = <&vaux4>; + + #io-channel-cells = <0>; + }; }; &mmc1 { @@ -733,6 +806,9 @@ pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; bus-width = <4>; + /* For debugging, it is often good idea to remove this GPIO. + It means you can remove back cover (to reboot by removing + battery) and still use the MMC card. */ cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */ }; @@ -741,7 +817,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&vaux3>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <8>; non-removable; no-sdio; diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi index df3366fa5409..1b0bd72945f2 100644 --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -265,6 +265,24 @@ &i2c2 { clock-frequency = <400000>; + + as3645a@30 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x30>; + compatible = "ams,as3645a"; + flash@0 { + reg = <0x0>; + flash-timeout-us = <150000>; + flash-max-microamp = <320000>; + led-max-microamp = <60000>; + ams,input-max-microamp = <1750000>; + }; + indicator@1 { + reg = <0x1>; + led-max-microamp = <10000>; + }; + }; }; &i2c3 { diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi index cd220342a805..f25e158e7163 100644 --- a/arch/arm/boot/dts/omap3-overo-base.dtsi +++ b/arch/arm/boot/dts/omap3-overo-base.dtsi @@ -181,7 +181,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <&w3cbw003c_npoweron>; - vmmc_aux-supply = <&w3cbw003c_wifi_nreset>; + vqmmc-supply = <&w3cbw003c_wifi_nreset>; bus-width = <4>; cap-sdio-irq; non-removable; diff --git a/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi index 157345bb8e79..25e100db7b1a 100644 --- a/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi +++ b/arch/arm/boot/dts/omap3-panel-sharp-ls037v7dw01.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common file for omap dpi panels with QVGA and reset pins * diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi index 4476fb685a1b..22b4c8bdcc65 100644 --- a/arch/arm/boot/dts/omap3-sb-t35.dtsi +++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common support for CompuLab SB-T35 used on SBC-T3530, SBC-T3517 and SBC-T3730 */ diff --git a/arch/arm/boot/dts/omap3-sbc-t3517.dts b/arch/arm/boot/dts/omap3-sbc-t3517.dts index c2d5c28a1a70..a69d32860421 100644 --- a/arch/arm/boot/dts/omap3-sbc-t3517.dts +++ b/arch/arm/boot/dts/omap3-sbc-t3517.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Suppport for CompuLab SBC-T3517 with CM-T3517 */ diff --git a/arch/arm/boot/dts/omap3-sbc-t3530.dts b/arch/arm/boot/dts/omap3-sbc-t3530.dts index 834bc786cd12..ae96002abb3b 100644 --- a/arch/arm/boot/dts/omap3-sbc-t3530.dts +++ b/arch/arm/boot/dts/omap3-sbc-t3530.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Suppport for CompuLab SBC-T3530 with CM-T3530 */ diff --git a/arch/arm/boot/dts/omap3-sbc-t3730.dts b/arch/arm/boot/dts/omap3-sbc-t3730.dts index 73c7bf4a4a08..7de6df16fc17 100644 --- a/arch/arm/boot/dts/omap3-sbc-t3730.dts +++ b/arch/arm/boot/dts/omap3-sbc-t3730.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Suppport for CompuLab SBC-T3730 with CM-T3730 */ diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi index 06ac0f80bcf0..9a601d15247b 100644 --- a/arch/arm/boot/dts/omap3-tao3530.dtsi +++ b/arch/arm/boot/dts/omap3-tao3530.dtsi @@ -223,7 +223,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/omap3-zoom3.dts b/arch/arm/boot/dts/omap3-zoom3.dts index 45e2ce0803de..96d0301a336a 100644 --- a/arch/arm/boot/dts/omap3-zoom3.dts +++ b/arch/arm/boot/dts/omap3-zoom3.dts @@ -174,7 +174,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; bus-width = <4>; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index a3ff4933dbc1..bdaf30c8c405 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -713,14 +713,12 @@ usbhsohci: ohci@48064400 { compatible = "ti,ohci-omap3"; reg = <0x48064400 0x400>; - interrupt-parent = <&intc>; interrupts = <76>; }; usbhsehci: ehci@48064800 { compatible = "ti,ehci-omap"; reg = <0x48064800 0x400>; - interrupt-parent = <&intc>; interrupts = <77>; }; }; @@ -831,7 +829,6 @@ reg-names = "tx", "rx"; - interrupt-parent = <&intc>; interrupts = <67>, <68>; }; @@ -844,7 +841,6 @@ reg-names = "tx", "rx"; - interrupt-parent = <&intc>; interrupts = <69>, <70>; }; diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index abd6921143be..908951eb5943 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -33,7 +33,7 @@ &mmc1 { vmmc-supply = <&vmmc1>; - vmmc_aux-supply = <&vsim>; + vqmmc-supply = <&vsim>; /* * S6-3 must be in ON position for 8 bit mode to function * Else, use 4 bit mode diff --git a/arch/arm/boot/dts/omap4-droid4-xt894.dts b/arch/arm/boot/dts/omap4-droid4-xt894.dts index 10ca1c174995..8b93d37310f2 100644 --- a/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/omap4-droid4-xt894.dts @@ -129,6 +129,34 @@ output-high; line-name = "touchscreen-reset"; }; + + pwm8: dmtimer-pwm-8 { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_direction_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer8>; + ti,clock-source = <0x01>; + }; + + pwm9: dmtimer-pwm-9 { + pinctrl-names = "default"; + pinctrl-0 = <&vibrator_enable_pin>; + + compatible = "ti,omap-dmtimer-pwm"; + #pwm-cells = <3>; + ti,timers = <&timer9>; + ti,clock-source = <0x01>; + }; + + vibrator { + compatible = "pwm-vibrator"; + pwms = <&pwm9 0 10000000 0>, <&pwm8 0 10000000 0>; + pwm-names = "enable", "direction"; + direction-duty-cycle-ns = <10000000>; + }; + }; &dsi1 { @@ -373,7 +401,7 @@ /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) >; @@ -488,6 +516,18 @@ OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3) >; }; + + vibrator_direction_pin: pinmux_vibrator_direction_pin { + pinctrl-single,pins = < + OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE1) /* dmtimer8_pwm_evt (gpio_27) */ + >; + }; + + vibrator_enable_pin: pinmux_vibrator_enable_pin { + pinctrl-single,pins = < + OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1) /* dmtimer9_pwm_evt (gpio_28) */ + >; + }; }; &uart3 { diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts index 1b825128a7b9..a9a584b5b955 100644 --- a/arch/arm/boot/dts/omap4-duovero-parlor.dts +++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts @@ -100,7 +100,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) /* hdmi_hpd.gpio_63 */ - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_ddc_scl.hdmi_ddc_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_ddc_sda.hdmi_ddc_sda */ >; diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi index edbc4090297d..2b48e51c372a 100644 --- a/arch/arm/boot/dts/omap4-panda-common.dtsi +++ b/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -267,7 +267,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4-sdp-es23plus.dts b/arch/arm/boot/dts/omap4-sdp-es23plus.dts index b4d19a7ae393..3d3140fd9659 100644 --- a/arch/arm/boot/dts/omap4-sdp-es23plus.dts +++ b/arch/arm/boot/dts/omap4-sdp-es23plus.dts @@ -10,7 +10,7 @@ /* SDP boards with 4430 ES2.3+ or 4460 have external pullups on SCL & SDA */ &dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts index d728ec963111..280d92d42bf1 100644 --- a/arch/arm/boot/dts/omap4-sdp.dts +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -290,7 +290,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi index 74940b6d7719..676d8dd0624a 100644 --- a/arch/arm/boot/dts/omap4-var-om44customboard.dtsi +++ b/arch/arm/boot/dts/omap4-var-om44customboard.dtsi @@ -122,7 +122,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ OMAP4_IOPAD(0x09e, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_sda.hdmi_sda */ >; diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index 4caadb253249..7824b2631cb6 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -290,7 +290,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP5_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec.hdmi_cec */ + OMAP5_IOPAD(0x13c, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP5_IOPAD(0x140, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_scl.hdmi_ddc_scl */ OMAP5_IOPAD(0x142, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_sda.hdmi_ddc_sda */ >; diff --git a/arch/arm/boot/dts/omap5-cm-t54.dts b/arch/arm/boot/dts/omap5-cm-t54.dts index 78397f66d0b2..5b172a04b6f1 100644 --- a/arch/arm/boot/dts/omap5-cm-t54.dts +++ b/arch/arm/boot/dts/omap5-cm-t54.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for CompuLab CM-T54 */ @@ -266,7 +267,7 @@ dss_hdmi_pins: pinmux_dss_hdmi_pins { pinctrl-single,pins = < - OMAP5_IOPAD(0x013c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_cec */ + OMAP5_IOPAD(0x013c, PIN_INPUT | MUX_MODE0) /* hdmi_cec */ OMAP5_IOPAD(0x0140, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_scl */ OMAP5_IOPAD(0x0142, PIN_INPUT | MUX_MODE0) /* hdmi_ddc_sda */ >; diff --git a/arch/arm/boot/dts/omap5-sbc-t54.dts b/arch/arm/boot/dts/omap5-sbc-t54.dts index 7b8810d13257..657df46251c2 100644 --- a/arch/arm/boot/dts/omap5-sbc-t54.dts +++ b/arch/arm/boot/dts/omap5-sbc-t54.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Suppport for CompuLab CM-T54 on SB-T54 baseboard */ diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi index 5f1d6da02a4c..747f750f675d 100644 --- a/arch/arm/boot/dts/pxa27x.dtsi +++ b/arch/arm/boot/dts/pxa27x.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* The pxa3xx skeleton simply augments the 2xx version */ #include "pxa2xx.dtsi" #include "dt-bindings/clock/pxa-clock.h" diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi index 7a0cc4ea819a..55c75b67351c 100644 --- a/arch/arm/boot/dts/pxa3xx.dtsi +++ b/arch/arm/boot/dts/pxa3xx.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* The pxa3xx skeleton simply augments the 2xx version */ #include "pxa2xx.dtsi" diff --git a/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval-pins.dtsi b/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval-pins.dtsi index a3efb9704fcd..8df73156b73a 100644 --- a/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval-pins.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval-pins.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 &tlmm_pinmux { card_detect: card-detect { mux { diff --git a/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts b/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts index f245064f320e..76b56eafaab9 100644 --- a/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts +++ b/arch/arm/boot/dts/qcom-apq8064-arrow-sd-600eval.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8064-v2.0.dtsi" #include "qcom-apq8064-arrow-sd-600eval-pins.dtsi" #include diff --git a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts index 3483a66e44c1..a701d4bac320 100644 --- a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts +++ b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8064-v2.0.dtsi" #include #include diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts index 5b151e425530..b818ebce0978 100644 --- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts +++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8064-v2.0.dtsi" #include #include diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts index 053b5bdd7808..83aaf4a74398 100644 --- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts +++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8064-v2.0.dtsi" #include #include diff --git a/arch/arm/boot/dts/qcom-apq8064-pins.dtsi b/arch/arm/boot/dts/qcom-apq8064-pins.dtsi index 173ab7c299ce..cbe42c4153a0 100644 --- a/arch/arm/boot/dts/qcom-apq8064-pins.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064-pins.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 &tlmm_pinmux { sdc4_gpios: sdc4-gpios { diff --git a/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts b/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts index 88a9aff41e2f..8bf488fb86ad 100644 --- a/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts +++ b/arch/arm/boot/dts/qcom-apq8064-sony-xperia-yuga.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8064-v2.0.dtsi" #include #include diff --git a/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi b/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi index 935c3945fc5e..46ed48f0244f 100644 --- a/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064-v2.0.dtsi @@ -1 +1,2 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8064.dtsi" diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index f3db185a6809..6089c8d56cd5 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "skeleton.dtsi" diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts index 32f3b81f609c..244f04e19c9d 100644 --- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts +++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974.dtsi" #include "qcom-pm8841.dtsi" #include "qcom-pm8941.dtsi" diff --git a/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts index 2052b84a77c6..44cd72f1b1be 100644 --- a/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts +++ b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8084.dtsi" #include "qcom-pma8084.dtsi" diff --git a/arch/arm/boot/dts/qcom-apq8084-mtp.dts b/arch/arm/boot/dts/qcom-apq8084-mtp.dts index d174d15bcf70..c6b6680248a6 100644 --- a/arch/arm/boot/dts/qcom-apq8084-mtp.dts +++ b/arch/arm/boot/dts/qcom-apq8084-mtp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8084.dtsi" #include "qcom-pma8084.dtsi" diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index 80d48867107f..0e1e98707e3f 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "skeleton.dtsi" diff --git a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi index b9457dd21a69..e413b21ee331 100644 --- a/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019-ap.dk01.1.dtsi @@ -20,27 +20,12 @@ model = "Qualcomm Technologies, Inc. IPQ4019/AP-DK01.1"; compatible = "qcom,ipq4019"; - clocks { - xo: xo { - compatible = "fixed-clock"; - clock-frequency = <48000000>; - #clock-cells = <0>; - }; - }; - soc { - - - timer { - compatible = "arm,armv7-timer"; - interrupts = <1 2 0xf08>, - <1 3 0xf08>, - <1 4 0xf08>, - <1 1 0xf08>; - clock-frequency = <48000000>; + rng@22000 { + status = "ok"; }; - pinctrl@0x01000000 { + pinctrl@1000000 { serial_pins: serial_pinmux { mux { pins = "gpio60", "gpio61"; @@ -108,5 +93,13 @@ watchdog@b017000 { status = "ok"; }; + + wifi@a000000 { + status = "ok"; + }; + + wifi@a800000 { + status = "ok"; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi index 4b7d97275c62..10d112a4078e 100644 --- a/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi @@ -96,6 +96,21 @@ clock-frequency = <32768>; #clock-cells = <0>; }; + + xo: xo { + compatible = "fixed-clock"; + clock-frequency = <48000000>; + #clock-cells = <0>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = <1 2 0xf08>, + <1 3 0xf08>, + <1 4 0xf08>, + <1 1 0xf08>; + clock-frequency = <48000000>; }; soc { @@ -119,7 +134,15 @@ reg = <0x1800000 0x60000>; }; - tlmm: pinctrl@0x01000000 { + rng@22000 { + compatible = "qcom,prng"; + reg = <0x22000 0x140>; + clocks = <&gcc GCC_PRNG_AHB_CLK>; + clock-names = "core"; + status = "disabled"; + }; + + tlmm: pinctrl@1000000 { compatible = "qcom,ipq4019-pinctrl"; reg = <0x01000000 0x300000>; gpio-controller; @@ -269,5 +292,89 @@ compatible = "qcom,pshold"; reg = <0x4ab000 0x4>; }; + + wifi0: wifi@a000000 { + compatible = "qcom,ipq4019-wifi"; + reg = <0xa000000 0x200000>; + resets = <&gcc WIFI0_CPU_INIT_RESET>, + <&gcc WIFI0_RADIO_SRIF_RESET>, + <&gcc WIFI0_RADIO_WARM_RESET>, + <&gcc WIFI0_RADIO_COLD_RESET>, + <&gcc WIFI0_CORE_WARM_RESET>, + <&gcc WIFI0_CORE_COLD_RESET>; + reset-names = "wifi_cpu_init", "wifi_radio_srif", + "wifi_radio_warm", "wifi_radio_cold", + "wifi_core_warm", "wifi_core_cold"; + clocks = <&gcc GCC_WCSS2G_CLK>, + <&gcc GCC_WCSS2G_REF_CLK>, + <&gcc GCC_WCSS2G_RTC_CLK>; + clock-names = "wifi_wcss_cmd", "wifi_wcss_ref", + "wifi_wcss_rtc"; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7", + "msi8", "msi9", "msi10", "msi11", + "msi12", "msi13", "msi14", "msi15", + "legacy"; + status = "disabled"; + }; + + wifi1: wifi@a800000 { + compatible = "qcom,ipq4019-wifi"; + reg = <0xa800000 0x200000>; + resets = <&gcc WIFI1_CPU_INIT_RESET>, + <&gcc WIFI1_RADIO_SRIF_RESET>, + <&gcc WIFI1_RADIO_WARM_RESET>, + <&gcc WIFI1_RADIO_COLD_RESET>, + <&gcc WIFI1_CORE_WARM_RESET>, + <&gcc WIFI1_CORE_COLD_RESET>; + reset-names = "wifi_cpu_init", "wifi_radio_srif", + "wifi_radio_warm", "wifi_radio_cold", + "wifi_core_warm", "wifi_core_cold"; + clocks = <&gcc GCC_WCSS5G_CLK>, + <&gcc GCC_WCSS5G_REF_CLK>, + <&gcc GCC_WCSS5G_RTC_CLK>; + clock-names = "wifi_wcss_cmd", "wifi_wcss_ref", + "wifi_wcss_rtc"; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7", + "msi8", "msi9", "msi10", "msi11", + "msi12", "msi13", "msi14", "msi15", + "legacy"; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts index 348503d1a1c1..bcf53e37ed93 100644 --- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts +++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-ipq8064-v1.0.dtsi" / { diff --git a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi index 7093b075e408..e1181194e8d3 100644 --- a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi @@ -1 +1,2 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-ipq8064.dtsi" diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi index f1fbffe59b93..1e0a3b446f7a 100644 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "skeleton.dtsi" diff --git a/arch/arm/boot/dts/qcom-msm8660-surf.dts b/arch/arm/boot/dts/qcom-msm8660-surf.dts index 1adc04978a47..f01a11b18d6a 100644 --- a/arch/arm/boot/dts/qcom-msm8660-surf.dts +++ b/arch/arm/boot/dts/qcom-msm8660-surf.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "qcom-msm8660.dtsi" diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi index 1b5d31b33b5e..221c4584552f 100644 --- a/arch/arm/boot/dts/qcom-msm8660.dtsi +++ b/arch/arm/boot/dts/qcom-msm8660.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "skeleton.dtsi" diff --git a/arch/arm/boot/dts/qcom-msm8960-cdp.dts b/arch/arm/boot/dts/qcom-msm8960-cdp.dts index b72a55462caf..82d5d8267adf 100644 --- a/arch/arm/boot/dts/qcom-msm8960-cdp.dts +++ b/arch/arm/boot/dts/qcom-msm8960-cdp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "qcom-msm8960.dtsi" diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi index 288f56e0ccf5..1733d8f40ab1 100644 --- a/arch/arm/boot/dts/qcom-msm8960.dtsi +++ b/arch/arm/boot/dts/qcom-msm8960.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "skeleton.dtsi" diff --git a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts index 382bcc3231a9..4dc0b347b1ee 100644 --- a/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts +++ b/arch/arm/boot/dts/qcom-msm8974-lge-nexus5-hammerhead.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974.dtsi" #include "qcom-pm8841.dtsi" #include "qcom-pm8941.dtsi" diff --git a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts index 50966378f9e4..450b8321e0a6 100644 --- a/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts +++ b/arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974.dtsi" #include "qcom-pm8841.dtsi" #include "qcom-pm8941.dtsi" diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index c5ee68a3f7f5..33002fed8cc3 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include @@ -779,7 +780,7 @@ }; replicator@fc31c000 { - compatible = "qcom,coresight-replicator1x", "arm,primecell"; + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0xfc31c000 0x1000>; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; diff --git a/arch/arm/boot/dts/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom-pm8841.dtsi index 0512f645922e..2fd59c440903 100644 --- a/arch/arm/boot/dts/qcom-pm8841.dtsi +++ b/arch/arm/boot/dts/qcom-pm8841.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi index 3fc9f34f45bb..1d5ef55c7ee5 100644 --- a/arch/arm/boot/dts/qcom-pm8941.dtsi +++ b/arch/arm/boot/dts/qcom-pm8941.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/boot/dts/qcom-pma8084.dtsi b/arch/arm/boot/dts/qcom-pma8084.dtsi index 82d258094156..aac7e73b6872 100644 --- a/arch/arm/boot/dts/qcom-pma8084.dtsi +++ b/arch/arm/boot/dts/qcom-pma8084.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts index 52a7b586bac7..cd4d5ff7749e 100644 --- a/arch/arm/boot/dts/r7s72100-genmai.dts +++ b/arch/arm/boot/dts/r7s72100-genmai.dts @@ -11,6 +11,8 @@ /dts-v1/; #include "r7s72100.dtsi" +#include +#include / { model = "Genmai"; @@ -34,6 +36,54 @@ #address-cells = <1>; #size-cells = <1>; }; + + leds { + status = "okay"; + compatible = "gpio-leds"; + + led1 { + gpios = <&port4 10 GPIO_ACTIVE_LOW>; + }; + + led2 { + gpios = <&port4 11 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&pinctrl { + + scif2_pins: serial2 { + /* P3_0 as TxD2; P3_2 as RxD2 */ + pinmux = , ; + }; + + i2c2_pins: i2c2 { + /* RIIC2: P1_4 as SCL, P1_5 as SDA */ + pinmux = , ; + }; + + ether_pins: ether { + /* Ethernet on Ports 1,2,3,5 */ + pinmux = ,/* P1_14 = ET_COL */ + , /* P5_9 = ET_MDC */ + , /* P3_3 = ET_MDIO */ + , /* P3_4 = ET_RXCLK */ + , /* P3_5 = ET_RXER */ + , /* P3_6 = ET_RXDV */ + , /* P2_0 = ET_TXCLK */ + , /* P2_1 = ET_TXER */ + , /* P2_2 = ET_TXEN */ + , /* P2_3 = ET_CRS */ + , /* P2_4 = ET_TXD0 */ + , /* P2_5 = ET_TXD1 */ + , /* P2_6 = ET_TXD2 */ + , /* P2_7 = ET_TXD3 */ + , /* P2_8 = ET_RXD0 */ + , /* P2_9 = ET_RXD1 */ + ,/* P2_10 = ET_RXD2 */ + ;/* P2_11 = ET_RXD3 */ + }; }; &extal_clk { @@ -52,12 +102,28 @@ status = "okay"; }; +ðer { + pinctrl-names = "default"; + pinctrl-0 = <ðer_pins>; + + status = "okay"; + + renesas,no-ether-link; + phy-handle = <&phy0>; + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + &i2c2 { status = "okay"; clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + eeprom@50 { - compatible = "renesas,24c128"; + compatible = "renesas,24c128", "atmel,24c128"; reg = <0x50>; pagesize = <64>; }; @@ -68,6 +134,9 @@ }; &scif2 { + pinctrl-names = "default"; + pinctrl-0 = <&scif2_pins>; + status = "okay"; }; diff --git a/arch/arm/boot/dts/r7s72100-rskrza1.dts b/arch/arm/boot/dts/r7s72100-rskrza1.dts index 72df20a04320..5dcaaf131d27 100644 --- a/arch/arm/boot/dts/r7s72100-rskrza1.dts +++ b/arch/arm/boot/dts/r7s72100-rskrza1.dts @@ -10,6 +10,8 @@ /dts-v1/; #include "r7s72100.dtsi" +#include +#include / { model = "RSKRZA1"; @@ -33,6 +35,15 @@ #address-cells = <1>; #size-cells = <1>; }; + + leds { + status = "okay"; + compatible = "gpio-leds"; + + led0 { + gpios = <&port7 1 GPIO_ACTIVE_LOW>; + }; + }; }; &extal_clk { @@ -47,11 +58,57 @@ clock-frequency = <32768>; }; +&pinctrl { + + /* Serial Console */ + scif2_pins: serial2 { + pinmux = , /* TxD2 */ + ; /* RxD2 */ + }; + + /* Ethernet */ + ether_pins: ether { + /* Ethernet on Ports 1,2,3,5 */ + pinmux = , /* ET_COL */ + , /* ET_MDC */ + , /* ET_MDIO */ + , /* ET_RXCLK */ + , /* ET_RXER */ + , /* ET_RXDV */ + , /* ET_TXCLK */ + , /* ET_TXER */ + , /* ET_TXEN */ + , /* ET_CRS */ + , /* ET_TXD0 */ + , /* ET_TXD1 */ + , /* ET_TXD2 */ + , /* ET_TXD3 */ + , /* ET_RXD0 */ + , /* ET_RXD1 */ + , /* ET_RXD2 */ + ; /* ET_RXD3 */ + }; + + /* SDHI ch1 on CN1 */ + sdhi1_pins: sdhi1 { + pinmux = , /* SD_CD_1 */ + , /* SD_WP_1 */ + , /* SD_D1_1 */ + , /* SD_D0_1 */ + , /* SD_CLK_1 */ + , /* SD_CMD_1 */ + , /* SD_D3_1 */ + ; /* SD_D2_1 */ + }; +}; + &mtu2 { status = "okay"; }; ðer { + pinctrl-names = "default"; + pinctrl-0 = <ðer_pins>; status = "okay"; renesas,no-ether-link; phy-handle = <&phy0>; @@ -61,6 +118,8 @@ }; &sdhi1 { + pinctrl-names = "default"; + pinctrl-0 = <&sdhi1_pins>; bus-width = <4>; status = "okay"; }; @@ -78,5 +137,7 @@ }; &scif2 { + pinctrl-names = "default"; + pinctrl-0 = <&scif2_pins>; status = "okay"; }; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index 5cf53e9943af..4ed12a4d9d51 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -207,6 +207,84 @@ }; }; + pinctrl: pin-controller@fcfe3000 { + compatible = "renesas,r7s72100-ports"; + + reg = <0xfcfe3000 0x4230>; + + port0: gpio-0 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 0 6>; + }; + + port1: gpio-1 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 16 16>; + }; + + port2: gpio-2 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 32 16>; + }; + + port3: gpio-3 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 48 16>; + }; + + port4: gpio-4 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 64 16>; + }; + + port5: gpio-5 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 80 11>; + }; + + port6: gpio-6 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 96 16>; + }; + + port7: gpio-7 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 112 16>; + }; + + port8: gpio-8 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 128 16>; + }; + + port9: gpio-9 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 144 8>; + }; + + port10: gpio-10 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 160 16>; + }; + + port11: gpio-11 { + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 176 16>; + }; + }; + scif0: serial@e8007000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007000 64>; diff --git a/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts b/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts index 9b54783cc2a5..081af0192851 100644 --- a/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts +++ b/arch/arm/boot/dts/r8a7743-iwg20d-q7.dts @@ -17,9 +17,40 @@ aliases { serial0 = &scif0; + ethernet0 = &avb; + }; +}; + +&pfc { + scif0_pins: scif0 { + groups = "scif0_data_d"; + function = "scif0"; + }; + + avb_pins: avb { + groups = "avb_mdio", "avb_gmii"; + function = "avb"; }; }; &scif0 { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; }; + +&avb { + pinctrl-0 = <&avb_pins>; + pinctrl-names = "default"; + + phy-handle = <&phy3>; + phy-mode = "gmii"; + renesas,no-ether-link; + status = "okay"; + + phy3: ethernet-phy@3 { + reg = <3>; + micrel,led-mode = <1>; + }; +}; diff --git a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi index 001ca9144f4b..ff7993818637 100644 --- a/arch/arm/boot/dts/r8a7743-iwg20m.dtsi +++ b/arch/arm/boot/dts/r8a7743-iwg20m.dtsi @@ -22,8 +22,34 @@ device_type = "memory"; reg = <2 0x00000000 0 0x20000000>; }; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; }; &extal_clk { clock-frequency = <20000000>; }; + +&pfc { + mmcif0_pins: mmc { + groups = "mmc_data8_b", "mmc_ctrl"; + function = "mmc"; + }; +}; + +&mmcif0 { + pinctrl-0 = <&mmcif0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <®_3p3v>; + bus-width = <8>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts b/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts index 3a22538208f2..3d918d106593 100644 --- a/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts +++ b/arch/arm/boot/dts/r8a7743-sk-rzg1m.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for the SK-RZG1M board * - * Copyright (C) 2016 Cogent Embedded, Inc. + * Copyright (C) 2016-2017 Cogent Embedded, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -39,11 +39,34 @@ clock-frequency = <20000000>; }; +&pfc { + scif0_pins: scif0 { + groups = "scif0_data_d"; + function = "scif0"; + }; + + ether_pins: ether { + groups = "eth_link", "eth_mdio", "eth_rmii"; + function = "eth"; + }; + + phy1_pins: phy1 { + groups = "intc_irq0"; + function = "intc"; + }; +}; + &scif0 { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; }; ðer { + pinctrl-0 = <ðer_pins &phy1_pins>; + pinctrl-names = "default"; + phy-handle = <&phy1>; renesas,ether-link-active-low; status = "okay"; diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi index 0ddac81742e4..14222c72f0e0 100644 --- a/arch/arm/boot/dts/r8a7743.dtsi +++ b/arch/arm/boot/dts/r8a7743.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Source for the r8a7743 SoC * - * Copyright (C) 2016 Cogent Embedded Inc. + * Copyright (C) 2016-2017 Cogent Embedded Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -18,9 +18,19 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + }; + cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "renesas,apmu"; cpu0: cpu@0 { device_type = "cpu"; @@ -28,8 +38,26 @@ reg = <0>; clock-frequency = <1500000000>; clocks = <&cpg CPG_CORE R8A7743_CLK_Z>; + clock-latency = <300000>; /* 300 us */ power-domains = <&sysc R8A7743_PD_CA15_CPU0>; next-level-cache = <&L2_CA15>; + + /* kHz - uV - OPPs unknown yet */ + operating-points = <1500000 1000000>, + <1312500 1000000>, + <1125000 1000000>, + < 937500 1000000>, + < 750000 1000000>, + < 375000 1000000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + clock-frequency = <1500000000>; + power-domains = <&sysc R8A7743_PD_CA15_CPU1>; + next-level-cache = <&L2_CA15>; }; L2_CA15: cache-controller-0 { @@ -48,6 +76,12 @@ #size-cells = <2>; ranges; + apmu@e6152000 { + compatible = "renesas,r8a7743-apmu", "renesas,apmu"; + reg = <0 0xe6152000 0 0x188>; + cpus = <&cpu0 &cpu1>; + }; + gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -65,6 +99,126 @@ resets = <&cpg 408>; }; + gpio0: gpio@e6050000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6050000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 0 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 912>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 912>; + }; + + gpio1: gpio@e6051000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6051000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 32 26>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 911>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 911>; + }; + + gpio2: gpio@e6052000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6052000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 64 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 910>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 910>; + }; + + gpio3: gpio@e6053000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6053000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 96 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 909>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 909>; + }; + + gpio4: gpio@e6054000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6054000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 128 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 908>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 908>; + }; + + gpio5: gpio@e6055000 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6055000 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 160 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 907>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 907>; + }; + + gpio6: gpio@e6055400 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6055400 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 192 32>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 905>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 905>; + }; + + gpio7: gpio@e6055800 { + compatible = "renesas,gpio-r8a7743", + "renesas,gpio-rcar"; + reg = <0 0xe6055800 0 0x50>; + interrupts = ; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pfc 0 224 26>; + #interrupt-cells = <2>; + interrupt-controller; + clocks = <&cpg CPG_MOD 904>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 904>; + }; + irqc: interrupt-controller@e61c0000 { compatible = "renesas,irqc-r8a7743", "renesas,irqc"; #interrupt-cells = <2>; @@ -123,6 +277,11 @@ #power-domain-cells = <1>; }; + pfc: pin-controller@e6060000 { + compatible = "renesas,pfc-r8a7743"; + reg = <0 0xe6060000 0 0x250>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7743", "renesas,rcar-dmac"; @@ -189,6 +348,94 @@ dma-channels = <15>; }; + /* The memory map in the User's Manual maps the cores to bus + * numbers + */ + i2c0: i2c@e6508000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6508000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 931>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 931>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c1: i2c@e6518000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6518000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 930>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 930>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c2: i2c@e6530000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6530000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 929>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 929>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c3: i2c@e6540000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6540000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 928>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 928>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c4: i2c@e6520000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6520000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 927>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 927>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c5: i2c@e6528000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7743", + "renesas,rcar-gen2-i2c"; + reg = <0 0xe6528000 0 0x40>; + interrupts = ; + clocks = <&cpg CPG_MOD 925>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 925>; + i2c-scl-internal-delay-ns = <110>; + status = "disabled"; + }; + scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7743", "renesas,rcar-gen2-scifa", "renesas,scifa"; @@ -468,6 +715,29 @@ status = "disabled"; }; + icram2: sram@e6300000 { + compatible = "mmio-sram"; + reg = <0 0xe6300000 0 0x40000>; + }; + + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7743"; reg = <0 0xee700000 0 0x400>; @@ -480,6 +750,35 @@ #size-cells = <0>; status = "disabled"; }; + + avb: ethernet@e6800000 { + compatible = "renesas,etheravb-r8a7743", + "renesas,etheravb-rcar-gen2"; + reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 812>; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 812>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mmcif0: mmc@ee200000 { + compatible = "renesas,mmcif-r8a7743", + "renesas,sh-mmcif"; + reg = <0 0xee200000 0 0x80>; + interrupts = ; + clocks = <&cpg CPG_MOD 315>; + dmas = <&dmac0 0xd1>, <&dmac0 0xd2>, + <&dmac1 0xd1>, <&dmac1 0xd2>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7743_PD_ALWAYS_ON>; + resets = <&cpg 315>; + reg-io-width = <4>; + max-frequency = <97500000>; + status = "disabled"; + }; }; /* External root clock */ diff --git a/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts b/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts index 97840b340197..b4d679b04ad6 100644 --- a/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts +++ b/arch/arm/boot/dts/r8a7745-sk-rzg1e.dts @@ -1,7 +1,7 @@ /* * Device Tree Source for the SK-RZG1E board * - * Copyright (C) 2016 Cogent Embedded, Inc. + * Copyright (C) 2016-2017 Cogent Embedded, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -34,11 +34,34 @@ clock-frequency = <20000000>; }; +&pfc { + scif2_pins: scif2 { + groups = "scif2_data"; + function = "scif2"; + }; + + ether_pins: ether { + groups = "eth_link", "eth_mdio", "eth_rmii"; + function = "eth"; + }; + + phy1_pins: phy1 { + groups = "intc_irq8"; + function = "intc"; + }; +}; + &scif2 { + pinctrl-0 = <&scif2_pins>; + pinctrl-names = "default"; + status = "okay"; }; ðer { + pinctrl-0 = <ðer_pins &phy1_pins>; + pinctrl-names = "default"; + phy-handle = <&phy1>; renesas,ether-link-active-low; status = "okay"; diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi index 2feb0084bb3b..aff90dfb8b32 100644 --- a/arch/arm/boot/dts/r8a7745.dtsi +++ b/arch/arm/boot/dts/r8a7745.dtsi @@ -1,7 +1,7 @@ /* * Device Tree Source for the r8a7745 SoC * - * Copyright (C) 2016 Cogent Embedded Inc. + * Copyright (C) 2016-2017 Cogent Embedded Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -123,6 +123,11 @@ #power-domain-cells = <1>; }; + pfc: pin-controller@e6060000 { + compatible = "renesas,pfc-r8a7745"; + reg = <0 0xe6060000 0 0x11c>; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7745", "renesas,rcar-dmac"; @@ -468,6 +473,29 @@ status = "disabled"; }; + icram2: sram@e6300000 { + compatible = "mmio-sram"; + reg = <0 0xe6300000 0 0x40000>; + }; + + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7745"; reg = <0 0xee700000 0 0x400>; diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 2805a8608d4b..16358bf8d1db 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -830,6 +830,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7790"; reg = <0 0xee700000 0 0x400>; @@ -855,7 +873,7 @@ }; sata0: sata@ee300000 { - compatible = "renesas,sata-r8a7790"; + compatible = "renesas,sata-r8a7790", "renesas,rcar-gen2-sata"; reg = <0 0xee300000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA0>; @@ -864,7 +882,7 @@ }; sata1: sata@ee500000 { - compatible = "renesas,sata-r8a7790"; + compatible = "renesas,sata-r8a7790", "renesas,rcar-gen2-sata"; reg = <0 0xee500000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA1>; @@ -909,7 +927,7 @@ }; vin0: video@e6ef0000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef0000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN0>; @@ -918,7 +936,7 @@ }; vin1: video@e6ef1000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef1000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN1>; @@ -927,7 +945,7 @@ }; vin2: video@e6ef2000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef2000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN2>; @@ -936,7 +954,7 @@ }; vin3: video@e6ef3000 { - compatible = "renesas,vin-r8a7790"; + compatible = "renesas,vin-r8a7790", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef3000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN3>; diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 001e6116c47c..0ce0b278e1cb 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -642,11 +642,19 @@ }; }; + cec_clock: cec-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <12000000>; + }; + hdmi@39 { compatible = "adi,adv7511w"; reg = <0x39>; interrupt-parent = <&gpio3>; interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + clocks = <&cec_clock>; + clock-names = "cec"; adi,input-depth = <8>; adi,input-colorspace = "rgb"; @@ -702,7 +710,7 @@ }; eeprom@50 { - compatible = "renesas,24c02"; + compatible = "renesas,24c02", "atmel,24c02"; reg = <0x50>; pagesize = <16>; }; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index bd93f699ad84..f1d1a9772153 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -890,6 +890,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7791"; reg = <0 0xee700000 0 0x400>; @@ -915,7 +933,7 @@ }; sata0: sata@ee300000 { - compatible = "renesas,sata-r8a7791"; + compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata"; reg = <0 0xee300000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA0>; @@ -924,7 +942,7 @@ }; sata1: sata@ee500000 { - compatible = "renesas,sata-r8a7791"; + compatible = "renesas,sata-r8a7791", "renesas,rcar-gen2-sata"; reg = <0 0xee500000 0 0x2000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA1>; @@ -969,7 +987,7 @@ }; vin0: video@e6ef0000 { - compatible = "renesas,vin-r8a7791"; + compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef0000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN0>; @@ -978,7 +996,7 @@ }; vin1: video@e6ef1000 { - compatible = "renesas,vin-r8a7791"; + compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef1000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN1>; @@ -987,7 +1005,7 @@ }; vin2: video@e6ef2000 { - compatible = "renesas,vin-r8a7791"; + compatible = "renesas,vin-r8a7791", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef2000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN2>; diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi index 0efecb232ee5..2623f39bed2b 100644 --- a/arch/arm/boot/dts/r8a7792.dtsi +++ b/arch/arm/boot/dts/r8a7792.dtsi @@ -465,6 +465,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7792"; reg = <0 0xee100000 0 0x328>; diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index 13b980f27bbc..497716b6fbe2 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -848,6 +848,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7793"; reg = <0 0xee700000 0 0x400>; diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 7d9a81d970d8..26535414203a 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -588,6 +588,24 @@ status = "disabled"; }; + icram0: sram@e63a0000 { + compatible = "mmio-sram"; + reg = <0 0xe63a0000 0 0x12000>; + }; + + icram1: sram@e63c0000 { + compatible = "mmio-sram"; + reg = <0 0xe63c0000 0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0xe63c0000 0x1000>; + + smp-sram@0 { + compatible = "renesas,smp-sram"; + reg = <0 0x10>; + }; + }; + ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7794"; reg = <0 0xee700000 0 0x400>; @@ -783,7 +801,7 @@ }; vin0: video@e6ef0000 { - compatible = "renesas,vin-r8a7794"; + compatible = "renesas,vin-r8a7794", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef0000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN0>; @@ -792,7 +810,7 @@ }; vin1: video@e6ef1000 { - compatible = "renesas,vin-r8a7794"; + compatible = "renesas,vin-r8a7794", "renesas,rcar-gen2-vin"; reg = <0 0xe6ef1000 0 0x1000>; interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN1>; diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 5726135b7f8a..fdb1570bc7d3 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -357,7 +357,6 @@ keep-power-in-suspend; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; sd-uhs-sdr12; @@ -372,7 +371,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; }; diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index ec91325d3b6e..4916c65e0ace 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -287,7 +287,6 @@ fifo-depth = <0x100>; mmc-ddr-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; resets = <&cru SRST_EMMC>; @@ -599,7 +598,7 @@ rockchip,pins = <1 15 RK_FUNC_1 &pcfg_pull_default>; }; - sdmmc_cd: sdmcc-cd { + sdmmc_cd: sdmmc-cd { rockchip,pins = <1 17 RK_FUNC_1 &pcfg_pull_default>; }; diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index e1f5198723b2..ef1eabf2512c 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -190,7 +190,6 @@ #include "tps65910.dtsi" &mmc0 { /* sdmmc */ - num-slots = <1>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; @@ -202,7 +201,6 @@ }; &mmc1 { /* wifi */ - num-slots = <1>; status = "okay"; non-removable; diff --git a/arch/arm/boot/dts/rk3066a-mk808.dts b/arch/arm/boot/dts/rk3066a-mk808.dts index 7ca1cf5241e0..13e285c53def 100644 --- a/arch/arm/boot/dts/rk3066a-mk808.dts +++ b/arch/arm/boot/dts/rk3066a-mk808.dts @@ -132,7 +132,6 @@ bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; - num-slots = <1>; vmmc-supply = <&vcc_sd>; status = "okay"; }; @@ -141,7 +140,6 @@ bus-width = <4>; disable-wp; non-removable; - num-slots = <1>; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>; pinctrl-names = "default"; vmmc-supply = <&vcc_wifi>; diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts index 8907deaab18e..400cbf9609e3 100644 --- a/arch/arm/boot/dts/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rk3066a-rayeager.dts @@ -185,7 +185,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_rst>; vmmc-supply = <&vcc_emmc>; @@ -336,7 +335,6 @@ &mmc0 { bus-width = <4>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; vmmc-supply = <&vcc_sd>; @@ -349,7 +347,6 @@ bus-width = <4>; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>; vmmc-supply = <&vccio_wl>; diff --git a/arch/arm/boot/dts/rk3188-px3-evb.dts b/arch/arm/boot/dts/rk3188-px3-evb.dts index 5b2a0b6885cd..8ba9e06062f3 100644 --- a/arch/arm/boot/dts/rk3188-px3-evb.dts +++ b/arch/arm/boot/dts/rk3188-px3-evb.dts @@ -89,7 +89,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_rst>; status = "okay"; @@ -256,7 +255,6 @@ }; &mmc0 { - num-slots = <1>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts index ca0a1c4bc15c..53d6fc2fdbce 100644 --- a/arch/arm/boot/dts/rk3188-radxarock.dts +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -296,7 +296,6 @@ }; &mmc0 { - num-slots = <1>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; diff --git a/arch/arm/boot/dts/rk3228-evb.dts b/arch/arm/boot/dts/rk3228-evb.dts index 58834330a5ba..1be9daacc4f9 100644 --- a/arch/arm/boot/dts/rk3228-evb.dts +++ b/arch/arm/boot/dts/rk3228-evb.dts @@ -50,6 +50,16 @@ device_type = "memory"; reg = <0x60000000 0x40000000>; }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + enable-active-high; + regulator-name = "vcc_phy"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; }; &emmc { @@ -60,6 +70,30 @@ status = "okay"; }; +&gmac { + assigned-clocks = <&cru SCLK_MAC_SRC>; + assigned-clock-rates = <50000000>; + clock_in_out = "output"; + phy-supply = <&vcc_phy>; + phy-mode = "rmii"; + phy-handle = <&phy>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + phy: phy@0 { + compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + clocks = <&cru SCLK_MAC_PHY>; + resets = <&cru SRST_MACPHY>; + phy-is-integrated; + }; + }; +}; + &tsadc { status = "okay"; diff --git a/arch/arm/boot/dts/rk3229-evb.dts b/arch/arm/boot/dts/rk3229-evb.dts index 1b55192b7d04..73e384585755 100644 --- a/arch/arm/boot/dts/rk3229-evb.dts +++ b/arch/arm/boot/dts/rk3229-evb.dts @@ -40,7 +40,8 @@ /dts-v1/; -#include "rk322x.dtsi" +#include +#include "rk3229.dtsi" / { model = "Rockchip RK3229 Evaluation board"; @@ -51,6 +52,15 @@ reg = <0x60000000 0x40000000>; }; + dc_12v: dc-12v-regulator { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + ext_gmac: ext_gmac { compatible = "fixed-clock"; clock-frequency = <125000000>; @@ -67,6 +77,7 @@ regulator-name = "vcc_host"; regulator-always-on; regulator-boot-on; + vin-supply = <&vcc_sys>; }; vcc_phy: vcc-phy-regulator { @@ -77,7 +88,96 @@ regulator-max-microvolt = <1800000>; regulator-always-on; regulator-boot-on; + vin-supply = <&vccio_1v8>; }; + + vcc_sys: vcc-sys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vccio_1v8: vccio-1v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vccio_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vccio_3v3: vccio-3v3-regulator { + compatible = "regulator-fixed"; + regulator-name = "vccio_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vdd_arm: vdd-arm-regulator { + compatible = "pwm-regulator"; + pwms = <&pwm1 0 25000 1>; + pwm-supply = <&vcc_sys>; + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_log: vdd-log-regulator { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + pwm-supply = <&vcc_sys>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + }; + + gpio_keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_key>; + + power_key: power-key { + label = "GPIO Key Power"; + gpios = <&gpio3 23 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <100>; + wakeup-source; + }; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&emmc { + cap-mmc-highspeed; + disable-wp; + non-removable; + status = "okay"; }; &gmac { @@ -96,7 +196,21 @@ status = "okay"; }; +&io_domains { + status = "okay"; + + vccio1-supply = <&vccio_3v3>; + vccio2-supply = <&vccio_1v8>; + vccio4-supply = <&vccio_3v3>; +}; + &pinctrl { + keys { + pwr_key: pwr-key { + rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + usb { host_vbus_drv: host-vbus-drv { rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; @@ -104,6 +218,19 @@ }; }; +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ + status = "okay"; +}; + &uart2 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3229.dtsi b/arch/arm/boot/dts/rk3229.dtsi new file mode 100644 index 000000000000..6fe6c15fc13a --- /dev/null +++ b/arch/arm/boot/dts/rk3229.dtsi @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "rk322x.dtsi" + +/ { + compatible = "rockchip,rk3229"; + + /delete-node/ opp-table0; + + cpu0_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <975000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1000000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1175000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1275000>; + }; + opp-1296000000 { + opp-hz = /bits/ 64 <1296000000>; + opp-microvolt = <1325000>; + }; + opp-1392000000 { + opp-hz = /bits/ 64 <1392000000>; + opp-microvolt = <1375000>; + }; + opp-1464000000 { + opp-hz = /bits/ 64 <1464000000>; + opp-microvolt = <1400000>; + }; + }; +}; diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi index f3e4ffd9f818..06814421eed2 100644 --- a/arch/arm/boot/dts/rk322x.dtsi +++ b/arch/arm/boot/dts/rk322x.dtsi @@ -55,6 +55,7 @@ serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; + spi0 = &spi0; }; cpus { @@ -70,6 +71,7 @@ #cooling-cells = <2>; /* min followed by max */ clock-latency = <40000>; clocks = <&cru ARMCLK>; + enable-method = "psci"; }; cpu1: cpu@f01 { @@ -78,6 +80,7 @@ reg = <0xf01>; resets = <&cru SRST_CORE1>; operating-points-v2 = <&cpu0_opp_table>; + enable-method = "psci"; }; cpu2: cpu@f02 { @@ -86,6 +89,7 @@ reg = <0xf02>; resets = <&cru SRST_CORE2>; operating-points-v2 = <&cpu0_opp_table>; + enable-method = "psci"; }; cpu3: cpu@f03 { @@ -94,6 +98,7 @@ reg = <0xf03>; resets = <&cru SRST_CORE3>; operating-points-v2 = <&cpu0_opp_table>; + enable-method = "psci"; }; }; @@ -151,6 +156,11 @@ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + timer { compatible = "arm,armv7-timer"; arm,cpu-registers-not-fw-configured; @@ -196,6 +206,19 @@ status = "disabled"; }; + spdif: spdif@100d0000 { + compatible = "rockchip,rk3228-spdif"; + reg = <0x100d0000 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF_8CH>; + clock-names = "mclk", "hclk"; + dmas = <&pdma 10>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx>; + status = "disabled"; + }; + i2s2: i2s2@100e0000 { compatible = "rockchip,rk3228-i2s", "rockchip,rk3066-i2s"; reg = <0x100e0000 0x4000>; @@ -215,6 +238,11 @@ #address-cells = <1>; #size-cells = <1>; + io_domains: io-domains { + compatible = "rockchip,rk3228-io-voltage-domain"; + status = "disabled"; + }; + u2phy0: usb2-phy@760 { compatible = "rockchip,rk3228-usb2phy"; reg = <0x0760 0x0c>; @@ -309,6 +337,23 @@ status = "disabled"; }; + efuse: efuse@11040000 { + compatible = "rockchip,rk3228-efuse"; + reg = <0x11040000 0x20>; + clocks = <&cru PCLK_EFUSE_256>; + clock-names = "pclk_efuse"; + #address-cells = <1>; + #size-cells = <1>; + + /* Data cells */ + efuse_id: id@7 { + reg = <0x7 0x10>; + }; + cpu_leakage: cpu_leakage@17 { + reg = <0x17 0x1>; + }; + }; + i2c0: i2c@11050000 { compatible = "rockchip,rk3228-i2c"; reg = <0x11050000 0x1000>; @@ -361,6 +406,19 @@ status = "disabled"; }; + spi0: spi@11090000 { + compatible = "rockchip,rk3228-spi"; + reg = <0x11090000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; + clock-names = "spiclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0 &spi0_cs1>; + status = "disabled"; + }; + wdt: watchdog@110a0000 { compatible = "snps,dw-wdt"; reg = <0x110a0000 0x100>; @@ -500,8 +558,70 @@ status = "disabled"; }; + vpu_mmu: iommu@20020800 { + compatible = "rockchip,iommu"; + reg = <0x20020800 0x100>; + interrupts = ; + interrupt-names = "vpu_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + vdec_mmu: iommu@20030480 { + compatible = "rockchip,iommu"; + reg = <0x20030480 0x40>, <0x200304c0 0x40>; + interrupts = ; + interrupt-names = "vdec_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + vop_mmu: iommu@20053f00 { + compatible = "rockchip,iommu"; + reg = <0x20053f00 0x100>; + interrupts = ; + interrupt-names = "vop_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + iep_mmu: iommu@20070800 { + compatible = "rockchip,iommu"; + reg = <0x20070800 0x100>; + interrupts = ; + interrupt-names = "iep_mmu"; + iommu-cells = <0>; + status = "disabled"; + }; + + sdmmc: dwmmc@30000000 { + compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x30000000 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + status = "disabled"; + }; + + sdio: dwmmc@30010000 { + compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; + reg = <0x30010000 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, + <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; + status = "disabled"; + }; + emmc: dwmmc@30020000 { - compatible = "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x30020000 0x4000>; interrupts = ; clock-frequency = <37500000>; @@ -511,7 +631,6 @@ clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; bus-width = <8>; default-sample-phase = <158>; - num-slots = <1>; fifo-depth = <0x100>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; @@ -710,6 +829,40 @@ drive-strength = <12>; }; + sdmmc { + sdmmc_clk: sdmmc-clk { + rockchip,pins = <1 RK_PC0 1 &pcfg_pull_none_drv_12ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <1 RK_PB7 1 &pcfg_pull_none_drv_12ma>; + }; + + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <1 RK_PC2 1 &pcfg_pull_none_drv_12ma>, + <1 RK_PC3 1 &pcfg_pull_none_drv_12ma>, + <1 RK_PC4 1 &pcfg_pull_none_drv_12ma>, + <1 RK_PC5 1 &pcfg_pull_none_drv_12ma>; + }; + }; + + sdio { + sdio_clk: sdio-clk { + rockchip,pins = <3 RK_PA0 1 &pcfg_pull_none_drv_12ma>; + }; + + sdio_cmd: sdio-cmd { + rockchip,pins = <3 RK_PA1 1 &pcfg_pull_none_drv_12ma>; + }; + + sdio_bus4: sdio-bus4 { + rockchip,pins = <3 RK_PA2 1 &pcfg_pull_none_drv_12ma>, + <3 RK_PA3 1 &pcfg_pull_none_drv_12ma>, + <3 RK_PA4 1 &pcfg_pull_none_drv_12ma>, + <3 RK_PA5 1 &pcfg_pull_none_drv_12ma>; + }; + }; + emmc { emmc_clk: emmc-clk { rockchip,pins = <2 7 RK_FUNC_2 &pcfg_pull_none>; @@ -797,6 +950,42 @@ }; }; + spi-0 { + spi0_clk: spi0-clk { + rockchip,pins = <0 9 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_cs0: spi0-cs0 { + rockchip,pins = <0 14 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_tx: spi0-tx { + rockchip,pins = <0 11 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_rx: spi0-rx { + rockchip,pins = <0 13 RK_FUNC_2 &pcfg_pull_up>; + }; + spi0_cs1: spi0-cs1 { + rockchip,pins = <1 12 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + spi-1 { + spi1_clk: spi1-clk { + rockchip,pins = <0 23 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_cs0: spi1-cs0 { + rockchip,pins = <2 2 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_rx: spi1-rx { + rockchip,pins = <2 0 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_tx: spi1-tx { + rockchip,pins = <2 1 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_cs1: spi1-cs1 { + rockchip,pins = <2 3 RK_FUNC_2 &pcfg_pull_up>; + }; + }; + i2s1 { i2s1_bus: i2s1-bus { rockchip,pins = <0 8 RK_FUNC_1 &pcfg_pull_none>, @@ -835,6 +1024,12 @@ }; }; + spdif { + spdif_tx: spdif-tx { + rockchip,pins = <3 31 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + tsadc { otp_gpio: otp-gpio { rockchip,pins = <0 24 RK_FUNC_GPIO &pcfg_pull_none>; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 0dec94c3583b..39b61dce97ad 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -45,7 +45,44 @@ / { memory@0 { device_type = "memory"; - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + + button-up { + label = "Volume Up"; + linux,code = ; + press-threshold-microvolt = <100000>; + }; + + button-down { + label = "Volume Down"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + + menu { + label = "Menu"; + linux,code = ; + press-threshold-microvolt = <640000>; + }; + + esc { + label = "Esc"; + linux,code = ; + press-threshold-microvolt = <1000000>; + }; + + home { + label = "Home"; + linux,code = ; + press-threshold-microvolt = <1300000>; + }; }; backlight: backlight { @@ -212,19 +249,22 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; status = "okay"; }; +&saradc { + vref-supply = <&vcc_18>; + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; status = "okay"; @@ -248,6 +288,11 @@ status = "ok"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3288-fennec.dts b/arch/arm/boot/dts/rk3288-fennec.dts index 61d1c1028317..41405974253a 100644 --- a/arch/arm/boot/dts/rk3288-fennec.dts +++ b/arch/arm/boot/dts/rk3288-fennec.dts @@ -47,7 +47,7 @@ compatible = "rockchip,rk3288-fennec", "rockchip,rk3288"; memory@0 { - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; device_type = "memory"; }; @@ -77,7 +77,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; status = "okay"; @@ -99,6 +98,11 @@ status = "okay"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi index 813496618d08..5f05815f47e0 100644 --- a/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly-reload-core.dtsi @@ -47,7 +47,7 @@ / { memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -78,7 +78,6 @@ mmc-ddr-1_8v; mmc-hs200-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; diff --git a/arch/arm/boot/dts/rk3288-firefly-reload.dts b/arch/arm/boot/dts/rk3288-firefly-reload.dts index b11a282c334c..7da0947ababb 100644 --- a/arch/arm/boot/dts/rk3288-firefly-reload.dts +++ b/arch/arm/boot/dts/rk3288-firefly-reload.dts @@ -269,7 +269,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; vmmc-supply = <&vcc_sd>; @@ -284,7 +283,6 @@ disable-wp; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>, <&sdio0_int>; sd-uhs-sdr12; diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index 32dabae12e67..b9e6f3a97240 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -46,7 +46,7 @@ / { memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; adc-keys { @@ -208,7 +208,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -527,7 +526,6 @@ bus-width = <4>; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>; vmmc-supply = <&vbat_wl>; @@ -541,7 +539,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm/boot/dts/rk3288-miqi.dts b/arch/arm/boot/dts/rk3288-miqi.dts index 30e93f694ae8..4d923aa6ed11 100644 --- a/arch/arm/boot/dts/rk3288-miqi.dts +++ b/arch/arm/boot/dts/rk3288-miqi.dts @@ -54,7 +54,7 @@ memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -126,7 +126,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -404,7 +403,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm/boot/dts/rk3288-phycore-rdk.dts b/arch/arm/boot/dts/rk3288-phycore-rdk.dts index 3dda79579b51..1241cbcfc16f 100644 --- a/arch/arm/boot/dts/rk3288-phycore-rdk.dts +++ b/arch/arm/boot/dts/rk3288-phycore-rdk.dts @@ -263,7 +263,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vdd_io_sd>; diff --git a/arch/arm/boot/dts/rk3288-phycore-som.dtsi b/arch/arm/boot/dts/rk3288-phycore-som.dtsi index 26cd3ad45160..99cfae875e12 100644 --- a/arch/arm/boot/dts/rk3288-phycore-som.dtsi +++ b/arch/arm/boot/dts/rk3288-phycore-som.dtsi @@ -55,7 +55,7 @@ */ memory { device_type = "memory"; - reg = <0 0x8000000>; + reg = <0x0 0x0 0x0 0x8000000>; }; aliases { @@ -136,7 +136,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; vmmc-supply = <&vdd_3v3_io>; diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts index aa1f9ecff231..f084e0c8dcb3 100644 --- a/arch/arm/boot/dts/rk3288-popmetal.dts +++ b/arch/arm/boot/dts/rk3288-popmetal.dts @@ -50,7 +50,7 @@ memory@0 { device_type = "memory"; - reg = <0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -150,7 +150,6 @@ mmc-ddr-1_8v; mmc-hs200-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -164,7 +163,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; sd-uhs-sdr12; diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts index 1145b62edde7..e95215c9788b 100644 --- a/arch/arm/boot/dts/rk3288-r89.dts +++ b/arch/arm/boot/dts/rk3288-r89.dts @@ -50,7 +50,7 @@ memory@0 { device_type = "memory"; - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; ext_gmac: external-gmac-clock { @@ -354,7 +354,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc_sdmmc>; diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi index 749a9b86e6e2..b9c471fcbd42 100644 --- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -43,7 +43,7 @@ / { memory@0 { - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; device_type = "memory"; }; @@ -89,7 +89,6 @@ cap-mmc-highspeed; disable-wp; non-removable; - num-slots = <1>; mmc-pwrseq = <&emmc_pwrseq>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index 8ed25e9f60bc..0e084b8a86ac 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -147,7 +147,6 @@ disable-wp; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk &sdio0_int>; vmmc-supply = <&vcc_io>; @@ -161,7 +160,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm/boot/dts/rk3288-tinker.dts b/arch/arm/boot/dts/rk3288-tinker.dts index f601c78386a9..346b0d8b474d 100644 --- a/arch/arm/boot/dts/rk3288-tinker.dts +++ b/arch/arm/boot/dts/rk3288-tinker.dts @@ -50,7 +50,7 @@ compatible = "asus,rk3288-tinker", "rockchip,rk3288"; memory { - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; device_type = "memory"; }; @@ -156,6 +156,11 @@ status = "ok"; }; +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + &hdmi { ddc-i2c-bus = <&i2c5>; status = "okay"; @@ -465,7 +470,6 @@ cap-sd-highspeed; card-detect-delay = <200>; disable-wp; /* wp not hooked up */ - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi index aef07101e9ab..95e9bee8bca2 100644 --- a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi @@ -117,7 +117,6 @@ card-detect-delay = <200>; cd-gpios = <&gpio7 RK_PA5 GPIO_ACTIVE_LOW>; rockchip,default-sample-phase = <90>; - num-slots = <1>; sd-uhs-sdr12; sd-uhs-sdr25; sd-uhs-sdr50; diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index d709fa1847f9..6e5bd8974f22 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -49,7 +49,7 @@ / { memory@0 { device_type = "memory"; - reg = <0x0 0x80000000>; + reg = <0x0 0x0 0x0 0x80000000>; }; gpio_keys: gpio-keys { @@ -156,7 +156,6 @@ mmc-hs200-1_8v; mmc-pwrseq = <&emmc_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; }; @@ -372,7 +371,6 @@ keep-power-in-suspend; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_bus4>; sd-uhs-sdr12; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 858e1fed762a..356ed1e62452 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -49,8 +49,8 @@ #include / { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; compatible = "rockchip,rk3288"; @@ -139,13 +139,13 @@ amba { compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; dmac_peri: dma-controller@ff250000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0xff250000 0x4000>; + reg = <0x0 0xff250000 0x0 0x4000>; interrupts = , ; #dma-cells = <1>; @@ -156,7 +156,7 @@ dmac_bus_ns: dma-controller@ff600000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0xff600000 0x4000>; + reg = <0x0 0xff600000 0x0 0x4000>; interrupts = , ; #dma-cells = <1>; @@ -168,7 +168,7 @@ dmac_bus_s: dma-controller@ffb20000 { compatible = "arm,pl330", "arm,primecell"; - reg = <0xffb20000 0x4000>; + reg = <0x0 0xffb20000 0x0 0x4000>; interrupts = , ; #dma-cells = <1>; @@ -179,8 +179,8 @@ }; reserved-memory { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; /* @@ -194,7 +194,7 @@ * is found. */ dma-unusable@fe000000 { - reg = <0xfe000000 0x1000000>; + reg = <0x0 0xfe000000 0x0 0x1000000>; }; }; @@ -217,7 +217,7 @@ timer: timer@ff810000 { compatible = "rockchip,rk3288-timer"; - reg = <0xff810000 0x20>; + reg = <0x0 0xff810000 0x0 0x20>; interrupts = ; clocks = <&xin24m>, <&cru PCLK_TIMER>; clock-names = "timer", "pclk"; @@ -236,7 +236,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0c0000 0x4000>; + reg = <0x0 0xff0c0000 0x0 0x4000>; resets = <&cru SRST_MMC0>; reset-names = "reset"; status = "disabled"; @@ -250,7 +250,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0d0000 0x4000>; + reg = <0x0 0xff0d0000 0x0 0x4000>; resets = <&cru SRST_SDIO0>; reset-names = "reset"; status = "disabled"; @@ -264,7 +264,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0e0000 0x4000>; + reg = <0x0 0xff0e0000 0x0 0x4000>; resets = <&cru SRST_SDIO1>; reset-names = "reset"; status = "disabled"; @@ -278,7 +278,7 @@ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; - reg = <0xff0f0000 0x4000>; + reg = <0x0 0xff0f0000 0x0 0x4000>; resets = <&cru SRST_EMMC>; reset-names = "reset"; status = "disabled"; @@ -286,7 +286,7 @@ saradc: saradc@ff100000 { compatible = "rockchip,saradc"; - reg = <0xff100000 0x100>; + reg = <0x0 0xff100000 0x0 0x100>; interrupts = ; #io-channel-cells = <1>; clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; @@ -305,7 +305,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>; - reg = <0xff110000 0x1000>; + reg = <0x0 0xff110000 0x0 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -320,7 +320,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>; - reg = <0xff120000 0x1000>; + reg = <0x0 0xff120000 0x0 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -335,7 +335,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>; - reg = <0xff130000 0x1000>; + reg = <0x0 0xff130000 0x0 0x1000>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -343,7 +343,7 @@ i2c1: i2c@ff140000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff140000 0x1000>; + reg = <0x0 0xff140000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -356,7 +356,7 @@ i2c3: i2c@ff150000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff150000 0x1000>; + reg = <0x0 0xff150000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -369,7 +369,7 @@ i2c4: i2c@ff160000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff160000 0x1000>; + reg = <0x0 0xff160000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -382,7 +382,7 @@ i2c5: i2c@ff170000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff170000 0x1000>; + reg = <0x0 0xff170000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -395,7 +395,7 @@ uart0: serial@ff180000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff180000 0x100>; + reg = <0x0 0xff180000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -408,7 +408,7 @@ uart1: serial@ff190000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff190000 0x100>; + reg = <0x0 0xff190000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -421,7 +421,7 @@ uart2: serial@ff690000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff690000 0x100>; + reg = <0x0 0xff690000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -434,7 +434,7 @@ uart3: serial@ff1b0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff1b0000 0x100>; + reg = <0x0 0xff1b0000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -447,7 +447,7 @@ uart4: serial@ff1c0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; - reg = <0xff1c0000 0x100>; + reg = <0x0 0xff1c0000 0x0 0x100>; interrupts = ; reg-shift = <2>; reg-io-width = <4>; @@ -535,7 +535,7 @@ tsadc: tsadc@ff280000 { compatible = "rockchip,rk3288-tsadc"; - reg = <0xff280000 0x100>; + reg = <0x0 0xff280000 0x0 0x100>; interrupts = ; clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; clock-names = "tsadc", "apb_pclk"; @@ -552,7 +552,7 @@ gmac: ethernet@ff290000 { compatible = "rockchip,rk3288-gmac"; - reg = <0xff290000 0x10000>; + reg = <0x0 0xff290000 0x0 0x10000>; interrupts = , ; interrupt-names = "macirq", "eth_wake_irq"; @@ -572,7 +572,7 @@ usb_host0_ehci: usb@ff500000 { compatible = "generic-ehci"; - reg = <0xff500000 0x100>; + reg = <0x0 0xff500000 0x0 0x100>; interrupts = ; clocks = <&cru HCLK_USBHOST0>; clock-names = "usbhost"; @@ -586,7 +586,7 @@ usb_host1: usb@ff540000 { compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2"; - reg = <0xff540000 0x40000>; + reg = <0x0 0xff540000 0x0 0x40000>; interrupts = ; clocks = <&cru HCLK_USBHOST1>; clock-names = "otg"; @@ -599,7 +599,7 @@ usb_otg: usb@ff580000 { compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", "snps,dwc2"; - reg = <0xff580000 0x40000>; + reg = <0x0 0xff580000 0x0 0x40000>; interrupts = ; clocks = <&cru HCLK_OTG0>; clock-names = "otg"; @@ -614,7 +614,7 @@ usb_hsic: usb@ff5c0000 { compatible = "generic-ehci"; - reg = <0xff5c0000 0x100>; + reg = <0x0 0xff5c0000 0x0 0x100>; interrupts = ; clocks = <&cru HCLK_HSIC>; clock-names = "usbhost"; @@ -623,7 +623,7 @@ i2c0: i2c@ff650000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff650000 0x1000>; + reg = <0x0 0xff650000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -636,7 +636,7 @@ i2c2: i2c@ff660000 { compatible = "rockchip,rk3288-i2c"; - reg = <0xff660000 0x1000>; + reg = <0x0 0xff660000 0x0 0x1000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -649,7 +649,7 @@ pwm0: pwm@ff680000 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680000 0x10>; + reg = <0x0 0xff680000 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "default"; pinctrl-0 = <&pwm0_pin>; @@ -660,7 +660,7 @@ pwm1: pwm@ff680010 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680010 0x10>; + reg = <0x0 0xff680010 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "default"; pinctrl-0 = <&pwm1_pin>; @@ -671,7 +671,7 @@ pwm2: pwm@ff680020 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680020 0x10>; + reg = <0x0 0xff680020 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "default"; pinctrl-0 = <&pwm2_pin>; @@ -682,7 +682,7 @@ pwm3: pwm@ff680030 { compatible = "rockchip,rk3288-pwm"; - reg = <0xff680030 0x10>; + reg = <0x0 0xff680030 0x0 0x10>; #pwm-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&pwm3_pin>; @@ -693,10 +693,10 @@ bus_intmem@ff700000 { compatible = "mmio-sram"; - reg = <0xff700000 0x18000>; + reg = <0x0 0xff700000 0x0 0x18000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0 0xff700000 0x18000>; + ranges = <0 0x0 0xff700000 0x18000>; smp-sram@0 { compatible = "rockchip,rk3066-smp-sram"; reg = <0x00 0x10>; @@ -705,12 +705,12 @@ sram@ff720000 { compatible = "rockchip,rk3288-pmu-sram", "mmio-sram"; - reg = <0xff720000 0x1000>; + reg = <0x0 0xff720000 0x0 0x1000>; }; pmu: power-management@ff730000 { compatible = "rockchip,rk3288-pmu", "syscon", "simple-mfd"; - reg = <0xff730000 0x100>; + reg = <0x0 0xff730000 0x0 0x100>; power: power-controller { compatible = "rockchip,rk3288-power-controller"; @@ -831,12 +831,12 @@ sgrf: syscon@ff740000 { compatible = "rockchip,rk3288-sgrf", "syscon"; - reg = <0xff740000 0x1000>; + reg = <0x0 0xff740000 0x0 0x1000>; }; cru: clock-controller@ff760000 { compatible = "rockchip,rk3288-cru"; - reg = <0xff760000 0x1000>; + reg = <0x0 0xff760000 0x0 0x1000>; rockchip,grf = <&grf>; #clock-cells = <1>; #reset-cells = <1>; @@ -854,7 +854,7 @@ grf: syscon@ff770000 { compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd"; - reg = <0xff770000 0x1000>; + reg = <0x0 0xff770000 0x0 0x1000>; edp_phy: edp-phy { compatible = "rockchip,rk3288-dp-phy"; @@ -903,7 +903,7 @@ wdt: watchdog@ff800000 { compatible = "rockchip,rk3288-wdt", "snps,dw-wdt"; - reg = <0xff800000 0x100>; + reg = <0x0 0xff800000 0x0 0x100>; clocks = <&cru PCLK_WDT>; interrupts = ; status = "disabled"; @@ -911,7 +911,7 @@ spdif: sound@ff88b0000 { compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif"; - reg = <0xff8b0000 0x10000>; + reg = <0x0 0xff8b0000 0x0 0x10000>; #sound-dai-cells = <0>; clock-names = "hclk", "mclk"; clocks = <&cru HCLK_SPDIF8CH>, <&cru SCLK_SPDIF8CH>; @@ -926,7 +926,7 @@ i2s: i2s@ff890000 { compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; - reg = <0xff890000 0x10000>; + reg = <0x0 0xff890000 0x0 0x10000>; interrupts = ; #address-cells = <1>; #size-cells = <0>; @@ -943,7 +943,7 @@ crypto: cypto-controller@ff8a0000 { compatible = "rockchip,rk3288-crypto"; - reg = <0xff8a0000 0x4000>; + reg = <0x0 0xff8a0000 0x0 0x4000>; interrupts = ; clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>, <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>; @@ -953,9 +953,28 @@ status = "okay"; }; + iep_mmu: iommu@ff900800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff900800 0x0 0x40>; + interrupts = ; + interrupt-names = "iep_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + isp_mmu: iommu@ff914000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + vopb: vop@ff930000 { compatible = "rockchip,rk3288-vop"; - reg = <0xff930000 0x19c>; + reg = <0x0 0xff930000 0x0 0x19c>; interrupts = ; clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; @@ -988,7 +1007,7 @@ vopb_mmu: iommu@ff930300 { compatible = "rockchip,iommu"; - reg = <0xff930300 0x100>; + reg = <0x0 0xff930300 0x0 0x100>; interrupts = ; interrupt-names = "vopb_mmu"; power-domains = <&power RK3288_PD_VIO>; @@ -998,7 +1017,7 @@ vopl: vop@ff940000 { compatible = "rockchip,rk3288-vop"; - reg = <0xff940000 0x19c>; + reg = <0x0 0xff940000 0x0 0x19c>; interrupts = ; clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>; clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; @@ -1031,7 +1050,7 @@ vopl_mmu: iommu@ff940300 { compatible = "rockchip,iommu"; - reg = <0xff940300 0x100>; + reg = <0x0 0xff940300 0x0 0x100>; interrupts = ; interrupt-names = "vopl_mmu"; power-domains = <&power RK3288_PD_VIO>; @@ -1041,7 +1060,7 @@ mipi_dsi: mipi@ff960000 { compatible = "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"; - reg = <0xff960000 0x4000>; + reg = <0x0 0xff960000 0x0 0x4000>; interrupts = ; clocks = <&cru SCLK_MIPIDSI_24M>, <&cru PCLK_MIPI_DSI0>; clock-names = "ref", "pclk"; @@ -1069,7 +1088,7 @@ edp: dp@ff970000 { compatible = "rockchip,rk3288-dp"; - reg = <0xff970000 0x4000>; + reg = <0x0 0xff970000 0x0 0x4000>; interrupts = ; clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>; clock-names = "dp", "pclk"; @@ -1101,7 +1120,7 @@ hdmi: hdmi@ff980000 { compatible = "rockchip,rk3288-dw-hdmi"; - reg = <0xff980000 0x20000>; + reg = <0x0 0xff980000 0x0 0x20000>; reg-io-width = <4>; rockchip,grf = <&grf>; interrupts = ; @@ -1126,9 +1145,27 @@ }; }; + vpu_mmu: iommu@ff9a0800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9a0800 0x0 0x100>; + interrupts = ; + interrupt-names = "vpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + hevc_mmu: iommu@ff9c0440 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9c0440 0x0 0x40>, <0x0 0xff9c0480 0x0 0x40>; + interrupts = ; + interrupt-names = "hevc_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + gpu: gpu@ffa30000 { compatible = "rockchip,rk3288-mali", "arm,mali-t760"; - reg = <0xffa30000 0x10000>; + reg = <0x0 0xffa30000 0x0 0x10000>; interrupts = , , ; @@ -1170,72 +1207,72 @@ qos_gpu_r: qos@ffaa0000 { compatible = "syscon"; - reg = <0xffaa0000 0x20>; + reg = <0x0 0xffaa0000 0x0 0x20>; }; qos_gpu_w: qos@ffaa0080 { compatible = "syscon"; - reg = <0xffaa0080 0x20>; + reg = <0x0 0xffaa0080 0x0 0x20>; }; qos_vio1_vop: qos@ffad0000 { compatible = "syscon"; - reg = <0xffad0000 0x20>; + reg = <0x0 0xffad0000 0x0 0x20>; }; qos_vio1_isp_w0: qos@ffad0100 { compatible = "syscon"; - reg = <0xffad0100 0x20>; + reg = <0x0 0xffad0100 0x0 0x20>; }; qos_vio1_isp_w1: qos@ffad0180 { compatible = "syscon"; - reg = <0xffad0180 0x20>; + reg = <0x0 0xffad0180 0x0 0x20>; }; qos_vio0_vop: qos@ffad0400 { compatible = "syscon"; - reg = <0xffad0400 0x20>; + reg = <0x0 0xffad0400 0x0 0x20>; }; qos_vio0_vip: qos@ffad0480 { compatible = "syscon"; - reg = <0xffad0480 0x20>; + reg = <0x0 0xffad0480 0x0 0x20>; }; qos_vio0_iep: qos@ffad0500 { compatible = "syscon"; - reg = <0xffad0500 0x20>; + reg = <0x0 0xffad0500 0x0 0x20>; }; qos_vio2_rga_r: qos@ffad0800 { compatible = "syscon"; - reg = <0xffad0800 0x20>; + reg = <0x0 0xffad0800 0x0 0x20>; }; qos_vio2_rga_w: qos@ffad0880 { compatible = "syscon"; - reg = <0xffad0880 0x20>; + reg = <0x0 0xffad0880 0x0 0x20>; }; qos_vio1_isp_r: qos@ffad0900 { compatible = "syscon"; - reg = <0xffad0900 0x20>; + reg = <0x0 0xffad0900 0x0 0x20>; }; qos_video: qos@ffae0000 { compatible = "syscon"; - reg = <0xffae0000 0x20>; + reg = <0x0 0xffae0000 0x0 0x20>; }; qos_hevc_r: qos@ffaf0000 { compatible = "syscon"; - reg = <0xffaf0000 0x20>; + reg = <0x0 0xffaf0000 0x0 0x20>; }; qos_hevc_w: qos@ffaf0080 { compatible = "syscon"; - reg = <0xffaf0080 0x20>; + reg = <0x0 0xffaf0080 0x0 0x20>; }; gic: interrupt-controller@ffc01000 { @@ -1244,16 +1281,16 @@ #interrupt-cells = <3>; #address-cells = <0>; - reg = <0xffc01000 0x1000>, - <0xffc02000 0x2000>, - <0xffc04000 0x2000>, - <0xffc06000 0x2000>; + reg = <0x0 0xffc01000 0x0 0x1000>, + <0x0 0xffc02000 0x0 0x2000>, + <0x0 0xffc04000 0x0 0x2000>, + <0x0 0xffc06000 0x0 0x2000>; interrupts = ; }; efuse: efuse@ffb40000 { compatible = "rockchip,rk3288-efuse"; - reg = <0xffb40000 0x20>; + reg = <0x0 0xffb40000 0x0 0x20>; #address-cells = <1>; #size-cells = <1>; clocks = <&cru PCLK_EFUSE256>; @@ -1268,13 +1305,13 @@ compatible = "rockchip,rk3288-pinctrl"; rockchip,grf = <&grf>; rockchip,pmu = <&pmu>; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; ranges; gpio0: gpio0@ff750000 { compatible = "rockchip,gpio-bank"; - reg = <0xff750000 0x100>; + reg = <0x0 0xff750000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO0>; @@ -1287,7 +1324,7 @@ gpio1: gpio1@ff780000 { compatible = "rockchip,gpio-bank"; - reg = <0xff780000 0x100>; + reg = <0x0 0xff780000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO1>; @@ -1300,7 +1337,7 @@ gpio2: gpio2@ff790000 { compatible = "rockchip,gpio-bank"; - reg = <0xff790000 0x100>; + reg = <0x0 0xff790000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO2>; @@ -1313,7 +1350,7 @@ gpio3: gpio3@ff7a0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7a0000 0x100>; + reg = <0x0 0xff7a0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO3>; @@ -1326,7 +1363,7 @@ gpio4: gpio4@ff7b0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7b0000 0x100>; + reg = <0x0 0xff7b0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO4>; @@ -1339,7 +1376,7 @@ gpio5: gpio5@ff7c0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7c0000 0x100>; + reg = <0x0 0xff7c0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO5>; @@ -1352,7 +1389,7 @@ gpio6: gpio6@ff7d0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7d0000 0x100>; + reg = <0x0 0xff7d0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO6>; @@ -1365,7 +1402,7 @@ gpio7: gpio7@ff7e0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7e0000 0x100>; + reg = <0x0 0xff7e0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO7>; @@ -1378,7 +1415,7 @@ gpio8: gpio8@ff7f0000 { compatible = "rockchip,gpio-bank"; - reg = <0xff7f0000 0x100>; + reg = <0x0 0xff7f0000 0x0 0x100>; interrupts = ; clocks = <&cru PCLK_GPIO8>; diff --git a/arch/arm/boot/dts/rv1108-evb.dts b/arch/arm/boot/dts/rv1108-evb.dts index 58cf4ac079c3..86a57f823616 100644 --- a/arch/arm/boot/dts/rv1108-evb.dts +++ b/arch/arm/boot/dts/rv1108-evb.dts @@ -54,6 +54,184 @@ chosen { stdout-path = "serial2:1500000n8"; }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + pwms = <&pwm0 0 25000 0>; + }; + + vcc_sys: vsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vsys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_core>; +}; + +&i2c0 { + status = "okay"; + i2c-scl-rising-time-ns = <275>; + i2c-scl-falling-time-ns = <16>; + clock-frequency = <400000>; + + rk805: pmic@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio0>; + interrupts = ; + rockchip,system-power-controller; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + + regulators { + vdd_core: DCDC_REG1 { + regulator-name= "vdd_core"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + regulator-state-uv = <900000>; + }; + }; + + vdd_cam: DCDC_REG2 { + regulator-name= "vdd_cam"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <2000000>; + regulator-state-mem { + regulator-state-disabled; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name= "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-name= "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + regulator-state-uv = <3300000>; + }; + }; + + vdd_10: LDO_REG1 { + regulator-name= "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-disabled; + }; + }; + + vcc_18: LDO_REG2 { + regulator-name= "vcc_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-disabled; + }; + }; + + vdd10_pmu: LDO_REG3 { + regulator-name= "vdd10_pmu"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-state-enabled; + regulator-state-uv = <1000000>; + }; + }; + }; + }; + + bma250: accelerometer@19 { + compatible = "bosch,bma250e"; + reg = <0x19>; + interrupt-parent = <&gpio0>; + interrupts = ; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&sdmmc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; }; &uart0 { @@ -67,3 +245,15 @@ &uart2 { status = "okay"; }; + +&usb_host_ehci { + status = "okay"; +}; + +&usb_host_ohci { + status = "okay"; +}; + +&usb_otg { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/rv1108.dtsi b/arch/arm/boot/dts/rv1108.dtsi index 437098b556eb..e7cd1315db1b 100644 --- a/arch/arm/boot/dts/rv1108.dtsi +++ b/arch/arm/boot/dts/rv1108.dtsi @@ -52,6 +52,10 @@ interrupt-parent = <&gic>; aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -65,6 +69,33 @@ device_type = "cpu"; compatible = "arm,cortex-a7"; reg = <0xf00>; + clocks = <&cru ARMCLK>; + operating-points-v2 = <&cpu_opp_table>; + }; + }; + + cpu_opp_table: opp_table { + compatible = "operating-points-v2"; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <975000>; + clock-latency-ns = <40000>; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <975000>; + clock-latency-ns = <40000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1025000>; + clock-latency-ns = <40000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1150000>; + clock-latency-ns = <40000>; }; }; @@ -154,9 +185,221 @@ status = "disabled"; }; + i2c1: i2c@10240000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x10240000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + i2c2: i2c@10250000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x10250000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2m1_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + i2c3: i2c@10260000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x10260000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + spi: spi@10270000 { + compatible = "rockchip,rv1108-spi"; + reg = <0x10270000 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&pdma 8>, <&pdma 9>; + #dma-cells = <2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm4: pwm@10280000 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280000 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm4_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm@10280010 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280010 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm5_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm@10280020 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280020 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm6_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm@10280030 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x10280030 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm7_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + grf: syscon@10300000 { - compatible = "rockchip,rv1108-grf", "syscon"; + compatible = "rockchip,rv1108-grf", "syscon", "simple-mfd"; reg = <0x10300000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy: usb2-phy@100 { + compatible = "rockchip,rv1108-usb2phy"; + reg = <0x100 0x0c>; + clocks = <&cru SCLK_USBPHY>; + clock-names = "phyclk"; + #clock-cells = <0>; + clock-output-names = "usbphy"; + rockchip,usbgrf = <&usbgrf>; + status = "disabled"; + + u2phy_otg: otg-port { + interrupts = ; + interrupt-names = "otg-mux"; + #phy-cells = <0>; + status = "disabled"; + }; + + u2phy_host: host-port { + interrupts = ; + interrupt-names = "linestate"; + #phy-cells = <0>; + status = "disabled"; + }; + }; + }; + + watchdog: wdt@10360000 { + compatible = "snps,dw-wdt"; + reg = <0x10360000 0x100>; + interrupts = ; + clocks = <&cru PCLK_WDT>; + clock-names = "pclk_wdt"; + status = "disabled"; + }; + + adc: adc@1038c000 { + compatible = "rockchip,rv1108-saradc", "rockchip,rk3399-saradc"; + reg = <0x1038c000 0x100>; + interrupts = ; + #io-channel-cells = <1>; + clock-frequency = <1000000>; + clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + status = "disabled"; + }; + + i2c0: i2c@20000000 { + compatible = "rockchip,rv1108-i2c"; + reg = <0x20000000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru SCLK_I2C0_PMU>, <&cru PCLK_I2C0_PMU>; + clock-names = "i2c", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_xfer>; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + pwm0: pwm@20040000 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040000 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@20040010 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040010 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@20040020 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040020 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm2_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@20040030 { + compatible = "rockchip,rv1108-pwm", "rockchip,rk3288-pwm"; + reg = <0x20040030 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM0_PMU>, <&cru PCLK_PWM0_PMU>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_pin>; + #pwm-cells = <3>; + status = "disabled"; }; pmugrf: syscon@20060000 { @@ -164,6 +407,11 @@ reg = <0x20060000 0x1000>; }; + usbgrf: syscon@202a0000 { + compatible = "rockchip,rv1108-usbgrf", "syscon"; + reg = <0x202a0000 0x1000>; + }; + cru: clock-controller@20200000 { compatible = "rockchip,rv1108-cru"; reg = <0x20200000 0x1000>; @@ -174,37 +422,78 @@ emmc: dwmmc@30110000 { compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; - clock-freq-min-max = <400000 150000000>; + reg = <0x30110000 0x4000>; + interrupts = ; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; - interrupts = ; - reg = <0x30110000 0x4000>; + max-frequency = <150000000>; status = "disabled"; }; sdio: dwmmc@30120000 { compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; - clock-freq-min-max = <400000 150000000>; + reg = <0x30120000 0x4000>; + interrupts = ; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; - interrupts = ; - reg = <0x30120000 0x4000>; + max-frequency = <150000000>; status = "disabled"; }; sdmmc: dwmmc@30130000 { compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc"; - clock-freq-min-max = <400000 100000000>; + reg = <0x30130000 0x4000>; + interrupts = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; - interrupts = ; - reg = <0x30130000 0x4000>; + max-frequency = <100000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + status = "disabled"; + }; + + usb_host_ehci: usb@30140000 { + compatible = "generic-ehci"; + reg = <0x30140000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host_ohci: usb@30160000 { + compatible = "generic-ohci"; + reg = <0x30160000 0x20000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_otg: usb@30180000 { + compatible = "rockchip,rv1108-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0x30180000 0x40000>; + interrupts = ; + clocks = <&cru HCLK_OTG>; + clock-names = "otg"; + dr_mode = "otg"; + g-np-tx-fifo-size = <16>; + g-rx-fifo-size = <280>; + g-tx-fifo-size = <256 128 128 64 32 16>; + g-use-dma; + phys = <&u2phy_otg>; + phy-names = "usb2-phy"; status = "disabled"; }; @@ -301,6 +590,11 @@ drive-strength = <12>; }; + pcfg_pull_none_smt: pcfg-pull-none-smt { + bias-disable; + input-schmitt-enable; + }; + pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma { bias-pull-up; drive-strength = <8>; @@ -328,6 +622,13 @@ input-enable; }; + i2c0 { + i2c0_xfer: i2c0-xfer { + rockchip,pins = <0 RK_PB1 RK_FUNC_1 &pcfg_pull_none_smt>, + <0 RK_PB2 RK_FUNC_1 &pcfg_pull_none_smt>; + }; + }; + i2c1 { i2c1_xfer: i2c1-xfer { rockchip,pins = <2 RK_PD3 RK_FUNC_1 &pcfg_pull_up>, @@ -366,6 +667,54 @@ }; }; + pwm0 { + pwm0_pin: pwm0-pin { + rockchip,pins = <0 RK_PC5 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm1 { + pwm1_pin: pwm1-pin { + rockchip,pins = <0 RK_PC4 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm2 { + pwm2_pin: pwm2-pin { + rockchip,pins = <0 RK_PC6 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm3 { + pwm3_pin: pwm3-pin { + rockchip,pins = <0 RK_PC0 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm4 { + pwm4_pin: pwm4-pin { + rockchip,pins = <1 RK_PC1 RK_FUNC_3 &pcfg_pull_none>; + }; + }; + + pwm5 { + pwm5_pin: pwm5-pin { + rockchip,pins = <1 RK_PA7 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + pwm6 { + pwm6_pin: pwm6-pin { + rockchip,pins = <1 RK_PB0 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + pwm7 { + pwm7_pin: pwm7-pin { + rockchip,pins = <1 RK_PB1 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + sdmmc { sdmmc_clk: sdmmc-clk { rockchip,pins = <3 RK_PC4 RK_FUNC_1 &pcfg_pull_none_drv_4ma>; diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h b/arch/arm/boot/dts/sama5d2-pinfunc.h index 8a394f336003..e57191fb83de 100644 --- a/arch/arm/boot/dts/sama5d2-pinfunc.h +++ b/arch/arm/boot/dts/sama5d2-pinfunc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define PINMUX_PIN(no, func, ioset) \ (((no) & 0xffff) | (((func) & 0xf) << 16) | (((ioset) & 0xff) << 20)) diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index 60e69aeacbdb..b1a26b42d190 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -416,6 +416,17 @@ }; }; + isc: isc@f0008000 { + compatible = "atmel,sama5d2-isc"; + reg = <0xf0008000 0x4000>; + interrupts = <46 IRQ_TYPE_LEVEL_HIGH 5>; + clocks = <&isc_clk>, <&iscck>, <&isc_gclk>; + clock-names = "hclock", "iscck", "gck"; + #clock-cells = <0>; + clock-output-names = "isc-mck"; + status = "disabled"; + }; + ramc0: ramc@f000c000 { compatible = "atmel,sama5d3-ddramc"; reg = <0xf000c000 0x200>; @@ -494,6 +505,24 @@ clocks = <&plla>; }; + audio_pll_frac: audiopll_fracck { + compatible = "atmel,sama5d2-clk-audio-pll-frac"; + #clock-cells = <0>; + clocks = <&main>; + }; + + audio_pll_pad: audiopll_padck { + compatible = "atmel,sama5d2-clk-audio-pll-pad"; + #clock-cells = <0>; + clocks = <&audio_pll_frac>; + }; + + audio_pll_pmc: audiopll_pmcck { + compatible = "atmel,sama5d2-clk-audio-pll-pmc"; + #clock-cells = <0>; + clocks = <&audio_pll_frac>; + }; + utmi: utmick { compatible = "atmel,at91sam9x5-clk-utmi"; #clock-cells = <0>; @@ -895,7 +924,7 @@ #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&pmc>; - clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>; + clocks = <&clk32k>, <&main>, <&plladiv>, <&utmi>, <&mck>, <&audio_pll_pmc>; sdmmc0_gclk: sdmmc0_gclk { #clock-cells = <0>; @@ -925,6 +954,11 @@ atmel,clk-output-range = <0 83000000>; }; + isc_gclk: isc_gclk { + #clock-cells = <0>; + reg = <46>; + }; + pdmic_gclk: pdmic_gclk { #clock-cells = <0>; reg = <48>; @@ -951,9 +985,37 @@ reg = <57>; atmel,clk-output-range = <0 80000000>; }; + + classd_gclk: classd_gclk { + #clock-cells = <0>; + reg = <59>; + atmel,clk-output-range = <0 100000000>; + }; }; }; + qspi0: spi@f0020000 { + compatible = "atmel,sama5d2-qspi"; + reg = <0xf0020000 0x100>, <0xd0000000 0x08000000>; + reg-names = "qspi_base", "qspi_mmap"; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&qspi0_clk>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + qspi1: spi@f0024000 { + compatible = "atmel,sama5d2-qspi"; + reg = <0xf0024000 0x100>, <0xd8000000 0x08000000>; + reg-names = "qspi_base", "qspi_mmap"; + interrupts = <53 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&qspi1_clk>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + sha@f0028000 { compatible = "atmel,at91sam9g46-sha"; reg = <0xf0028000 0x100>; @@ -1368,6 +1430,7 @@ atmel,min-sample-rate-hz = <200000>; atmel,max-sample-rate-hz = <20000000>; atmel,startup-time-ms = <4>; + atmel,trigger-edge-type = ; status = "disabled"; }; @@ -1406,6 +1469,19 @@ status = "okay"; }; + classd: classd@fc048000 { + compatible = "atmel,sama5d2-classd"; + reg = <0xfc048000 0x100>; + interrupts = <59 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(47))>; + dma-names = "tx"; + clocks = <&classd_clk>, <&classd_gclk>; + clock-names = "pclk", "gclk"; + status = "disabled"; + }; + can1: can@fc050000 { compatible = "bosch,m_can"; reg = <0xfc050000 0x4000>, <0x210000 0x4000>; diff --git a/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi b/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi index 9657a5cbc3ad..dbdda36179ee 100644 --- a/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi +++ b/arch/arm/boot/dts/samsung_k3pe0e000b.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Timings and Geometry for Samsung K3PE0E000B memory part */ diff --git a/arch/arm/boot/dts/skeleton.dtsi b/arch/arm/boot/dts/skeleton.dtsi index 28b81d60b407..34eda68d9ea2 100644 --- a/arch/arm/boot/dts/skeleton.dtsi +++ b/arch/arm/boot/dts/skeleton.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is deprecated, and will be removed once existing users have been * updated. New dts{,i} files should *not* include skeleton.dtsi, and should diff --git a/arch/arm/boot/dts/skeleton64.dtsi b/arch/arm/boot/dts/skeleton64.dtsi index b5d7f36f33de..54e637752b9d 100644 --- a/arch/arm/boot/dts/skeleton64.dtsi +++ b/arch/arm/boot/dts/skeleton64.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Skeleton device tree in the 64 bits version; the bare minimum * needed to boot; just include and add a compatible value. The diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 54bc6d3cf290..40f4ad3c34c6 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi @@ -98,6 +98,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; @@ -116,6 +117,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x90020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x90030000 0x90030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; @@ -134,6 +136,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0xc0020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0xc0030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index df2232d767ed..5f347054527d 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi @@ -63,6 +63,7 @@ device_type = "pci"; ranges = <0x81000000 0 0 0x80020000 0 0x00010000 /* downstream I/O */ 0x82000000 0 0x80030000 0xc0030000 0 0x0ffd0000>; /* non-prefetchable memory */ + bus-range = <0x00 0xff>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/st-pincfg.h b/arch/arm/boot/dts/st-pincfg.h index 4851c387d52d..d80551202292 100644 --- a/arch/arm/boot/dts/st-pincfg.h +++ b/arch/arm/boot/dts/st-pincfg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ST_PINCFG_H_ #define _ST_PINCFG_H_ diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi index 6c5affe2d0f5..2310a4e97768 100644 --- a/arch/arm/boot/dts/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi @@ -37,6 +37,14 @@ device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <0x300>; + /* cpufreq controls */ + operating-points = <998400 0 + 800000 0 + 400000 0 + 200000 0>; + clocks = <&prcmu_clk PRCMU_ARMSS>; + clock-names = "cpu"; + clock-latency = <20000>; }; CPU1: cpu@301 { device_type = "cpu"; @@ -494,13 +502,6 @@ reg = <0x80157450 0xC>; }; - cpufreq { - compatible = "stericsson,cpufreq-ux500"; - clocks = <&prcmu_clk PRCMU_ARMSS>; - clock-names = "armss"; - status = "disabled"; - }; - thermal@801573c0 { compatible = "stericsson,db8500-thermal"; reg = <0x801573c0 0x40>; diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi index 5882a2606ac3..3f14b4df69b4 100644 --- a/arch/arm/boot/dts/ste-hrefprev60.dtsi +++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi @@ -30,7 +30,7 @@ i2c@80004000 { tps61052@33 { - compatible = "tps61052"; + compatible = "ti,tps61052"; reg = <0x33>; }; diff --git a/arch/arm/boot/dts/ste-nomadik-nhk15.dts b/arch/arm/boot/dts/ste-nomadik-nhk15.dts index 1ec46a794a4d..12afdc7467e7 100644 --- a/arch/arm/boot/dts/ste-nomadik-nhk15.dts +++ b/arch/arm/boot/dts/ste-nomadik-nhk15.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree for the ST-Ericsson Nomadik S8815 board * Produced by Calao Systems diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts index 789329030658..4445446fa828 100644 --- a/arch/arm/boot/dts/ste-nomadik-s8815.dts +++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree for the ST-Ericsson Nomadik S8815 board * Produced by Calao Systems diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index adb1c0998b81..68aab50a73ab 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree for the ST-Ericsson Nomadik 8815 STn8815 SoC */ diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts index 2f5107ffeef0..62ecb6a2fa39 100644 --- a/arch/arm/boot/dts/ste-u300.dts +++ b/arch/arm/boot/dts/ste-u300.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device Tree for the ST-Ericsson U300 Machine and SoC */ diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index dcda0bbefe5b..293ecb957227 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -47,6 +47,7 @@ /dts-v1/; #include "stm32f429.dtsi" +#include "stm32f429-pinctrl.dtsi" #include #include @@ -55,7 +56,7 @@ compatible = "st,stm32429i-eval", "st,stm32f429"; chosen { - bootargs = "root=/dev/ram rdinit=/linuxrc"; + bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; }; @@ -202,10 +203,8 @@ stmpe1600: stmpe1600@42 { compatible = "st,stmpe1600"; reg = <0x42>; - irq-gpio = <&gpioi 8 0>; - irq-trigger = <3>; interrupts = <8 3>; - interrupt-parent = <&exti>; + interrupt-parent = <&gpioi>; interrupt-controller; wakeup-source; diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi new file mode 100644 index 000000000000..7f3560c0211d --- /dev/null +++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi @@ -0,0 +1,343 @@ +/* + * Copyright 2017 - Alexandre Torgue + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +/ { + soc { + pinctrl: pin-controller { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x40020000 0x3000>; + interrupt-parent = <&exti>; + st,syscfg = <&syscfg 0x8>; + pins-are-numbered; + + gpioa: gpio@40020000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x0 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>; + st,bank-name = "GPIOA"; + }; + + gpiob: gpio@40020400 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x400 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOB)>; + st,bank-name = "GPIOB"; + }; + + gpioc: gpio@40020800 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x800 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOC)>; + st,bank-name = "GPIOC"; + }; + + gpiod: gpio@40020c00 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0xc00 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOD)>; + st,bank-name = "GPIOD"; + }; + + gpioe: gpio@40021000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1000 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOE)>; + st,bank-name = "GPIOE"; + }; + + gpiof: gpio@40021400 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1400 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOF)>; + st,bank-name = "GPIOF"; + }; + + gpiog: gpio@40021800 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1800 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOG)>; + st,bank-name = "GPIOG"; + }; + + gpioh: gpio@40021c00 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x1c00 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOH)>; + st,bank-name = "GPIOH"; + }; + + gpioi: gpio@40022000 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2000 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOI)>; + st,bank-name = "GPIOI"; + }; + + gpioj: gpio@40022400 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2400 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOJ)>; + st,bank-name = "GPIOJ"; + }; + + gpiok: gpio@40022800 { + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x2800 0x400>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOK)>; + st,bank-name = "GPIOK"; + }; + + usart1_pins_a: usart1@0 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; + + usart3_pins_a: usart3@0 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; + + usbotg_fs_pins_a: usbotg_fs@0 { + pins { + pinmux = , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + usbotg_fs_pins_b: usbotg_fs@1 { + pins { + pinmux = , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + usbotg_hs_pins_a: usbotg_hs@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + ethernet_mii: mii@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + ; + slew-rate = <2>; + }; + }; + + adc3_in8_pin: adc@200 { + pins { + pinmux = ; + }; + }; + + pwm1_pins: pwm@1 { + pins { + pinmux = , + , + ; + }; + }; + + pwm3_pins: pwm@3 { + pins { + pinmux = , + ; + }; + }; + + i2c1_pins: i2c1@0 { + pins { + pinmux = , + ; + bias-disable; + drive-open-drain; + slew-rate = <3>; + }; + }; + + ltdc_pins: ltdc@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + slew-rate = <2>; + }; + }; + + dcmi_pins: dcmi@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts index ae47cde7952f..5ceb2cf3777f 100644 --- a/arch/arm/boot/dts/stm32f429-disco.dts +++ b/arch/arm/boot/dts/stm32f429-disco.dts @@ -47,6 +47,7 @@ /dts-v1/; #include "stm32f429.dtsi" +#include "stm32f429-pinctrl.dtsi" #include / { @@ -54,7 +55,7 @@ compatible = "st,stm32f429i-disco", "st,stm32f429"; chosen { - bootargs = "root=/dev/ram rdinit=/linuxrc"; + bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/imx6ul-geam-kit.dts b/arch/arm/boot/dts/stm32f429-pinctrl.dtsi similarity index 63% rename from arch/arm/boot/dts/imx6ul-geam-kit.dts rename to arch/arm/boot/dts/stm32f429-pinctrl.dtsi index 142e60cab65f..3e7a17d9112e 100644 --- a/arch/arm/boot/dts/imx6ul-geam-kit.dts +++ b/arch/arm/boot/dts/stm32f429-pinctrl.dtsi @@ -1,6 +1,5 @@ /* - * Copyright (C) 2016 Amarula Solutions B.V. - * Copyright (C) 2016 Engicam S.r.l. + * Copyright 2017 - Alexandre Torgue * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -8,8 +7,9 @@ * whole. * * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * * This file is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -40,62 +40,56 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/dts-v1/; - -#include -#include "imx6ul-geam.dtsi" +#include "stm32f4-pinctrl.dtsi" / { - model = "Engicam GEAM6UL"; - compatible = "engicam,imx6ul-geam", "fsl,imx6ul"; -}; + soc { + pinctrl: pin-controller { + compatible = "st,stm32f429-pinctrl"; -&can1 { - status = "okay"; -}; + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; -&can2 { - status = "okay"; -}; + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; -&lcdif { - display = <&display0>; - status = "okay"; + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; - display0: display { - bits-per-pixel = <16>; - bus-width = <18>; - status = "okay"; + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; - display-timings { - native-mode = <&timing0>; - timing0: timing0 { - clock-frequency = <28000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <30>; - hback-porch = <30>; - hsync-len = <64>; - vback-porch = <5>; - vfront-porch = <5>; - vsync-len = <20>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; + }; + + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; + + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; + + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; + + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; + + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 16>; + }; + + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 0 160 8>; }; }; }; }; - -&usdhc1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usdhc1>; - status = "okay"; -}; - -&tsc { - measure-delay-time = <0x1ffff>; - pre-charge-time = <0x1fff>; - status = "okay"; -}; diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index a8113dc879cf..5b36eb114ddc 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -47,7 +47,6 @@ #include "skeleton.dtsi" #include "armv7-m.dtsi" -#include #include #include @@ -361,6 +360,31 @@ status = "disabled"; }; + dac: dac@40007400 { + compatible = "st,stm32f4-dac-core"; + reg = <0x40007400 0x400>; + resets = <&rcc STM32F4_APB1_RESET(DAC)>; + clocks = <&rcc 0 STM32F4_APB1_CLOCK(DAC)>; + clock-names = "pclk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + dac1: dac@1 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <1>; + status = "disabled"; + }; + + dac2: dac@2 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <2>; + status = "disabled"; + }; + }; + usart7: serial@40007800 { compatible = "st,stm32-usart", "st,stm32-uart"; reg = <0x40007800 0x400>; @@ -566,302 +590,6 @@ status = "disabled"; }; - pinctrl: pin-controller { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,stm32f429-pinctrl"; - ranges = <0 0x40020000 0x3000>; - interrupt-parent = <&exti>; - st,syscfg = <&syscfg 0x8>; - pins-are-numbered; - - gpioa: gpio@40020000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x0 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>; - st,bank-name = "GPIOA"; - }; - - gpiob: gpio@40020400 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x400 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOB)>; - st,bank-name = "GPIOB"; - }; - - gpioc: gpio@40020800 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x800 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOC)>; - st,bank-name = "GPIOC"; - }; - - gpiod: gpio@40020c00 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0xc00 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOD)>; - st,bank-name = "GPIOD"; - }; - - gpioe: gpio@40021000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1000 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOE)>; - st,bank-name = "GPIOE"; - }; - - gpiof: gpio@40021400 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1400 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOF)>; - st,bank-name = "GPIOF"; - }; - - gpiog: gpio@40021800 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1800 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOG)>; - st,bank-name = "GPIOG"; - }; - - gpioh: gpio@40021c00 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x1c00 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOH)>; - st,bank-name = "GPIOH"; - }; - - gpioi: gpio@40022000 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x2000 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOI)>; - st,bank-name = "GPIOI"; - }; - - gpioj: gpio@40022400 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x2400 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOJ)>; - st,bank-name = "GPIOJ"; - }; - - gpiok: gpio@40022800 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x2800 0x400>; - clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOK)>; - st,bank-name = "GPIOK"; - }; - - usart1_pins_a: usart1@0 { - pins1 { - pinmux = ; - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; - bias-disable; - }; - }; - - usart3_pins_a: usart3@0 { - pins1 { - pinmux = ; - bias-disable; - drive-push-pull; - slew-rate = <0>; - }; - pins2 { - pinmux = ; - bias-disable; - }; - }; - - usbotg_fs_pins_a: usbotg_fs@0 { - pins { - pinmux = , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <2>; - }; - }; - - usbotg_fs_pins_b: usbotg_fs@1 { - pins { - pinmux = , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <2>; - }; - }; - - usbotg_hs_pins_a: usbotg_hs@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <2>; - }; - }; - - ethernet_mii: mii@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - ; - slew-rate = <2>; - }; - }; - - adc3_in8_pin: adc@200 { - pins { - pinmux = ; - }; - }; - - pwm1_pins: pwm@1 { - pins { - pinmux = , - , - ; - }; - }; - - pwm3_pins: pwm@3 { - pins { - pinmux = , - ; - }; - }; - - i2c1_pins: i2c1@0 { - pins { - pinmux = , - ; - bias-disable; - drive-open-drain; - slew-rate = <3>; - }; - }; - - ltdc_pins: ltdc@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - slew-rate = <2>; - }; - }; - - dcmi_pins: dcmi@0 { - pins { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - drive-push-pull; - slew-rate = <3>; - }; - }; - }; - crc: crc@40023000 { compatible = "st,stm32f4-crc"; reg = <0x40023000 0x400>; diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts index 75470c34b92c..c18acbe4cf4e 100644 --- a/arch/arm/boot/dts/stm32f469-disco.dts +++ b/arch/arm/boot/dts/stm32f469-disco.dts @@ -47,13 +47,14 @@ /dts-v1/; #include "stm32f429.dtsi" +#include "stm32f469-pinctrl.dtsi" / { model = "STMicroelectronics STM32F469i-DISCO board"; compatible = "st,stm32f469i-disco", "st,stm32f469"; chosen { - bootargs = "root=/dev/ram rdinit=/linuxrc"; + bootargs = "root=/dev/ram"; stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/stm32f469-pinctrl.dtsi b/arch/arm/boot/dts/stm32f469-pinctrl.dtsi new file mode 100644 index 000000000000..fff542662eea --- /dev/null +++ b/arch/arm/boot/dts/stm32f469-pinctrl.dtsi @@ -0,0 +1,96 @@ +/* + * Copyright 2017 - Alexandre Torgue + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "stm32f4-pinctrl.dtsi" + +/ { + soc { + pinctrl: pin-controller { + compatible = "st,stm32f469-pinctrl"; + + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; + + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; + + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; + + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; + + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; + }; + + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; + + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; + + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; + + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; + + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 6>, + <&pinctrl 12 156 4>; + }; + + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 3 163 5>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi index 4506eb97a4ab..5633860037d2 100644 --- a/arch/arm/boot/dts/stm32f746.dtsi +++ b/arch/arm/boot/dts/stm32f746.dtsi @@ -167,6 +167,15 @@ status = "disabled"; }; + cec: cec@40006c00 { + compatible = "st,stm32-cec"; + reg = <0x40006C00 0x400>; + interrupts = <94>; + clocks = <&rcc 0 STM32F7_APB1_CLOCK(CEC)>, <&rcc 1 CLK_HDMI_CEC>; + clock-names = "cec", "hdmi-cec"; + status = "disabled"; + }; + usart7: serial@40007800 { compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40007800 0x400>; @@ -336,6 +345,15 @@ st,bank-name = "GPIOK"; }; + cec_pins_a: cec@0 { + pins { + pinmux = ; + slew-rate = <0>; + drive-open-drain; + bias-disable; + }; + }; + usart1_pins_a: usart1@0 { pins1 { pinmux = ; @@ -380,6 +398,39 @@ assigned-clocks = <&rcc 1 CLK_HSE_RTC>; assigned-clock-rates = <1000000>; }; + + dma1: dma@40026000 { + compatible = "st,stm32-dma"; + reg = <0x40026000 0x400>; + interrupts = <11>, + <12>, + <13>, + <14>, + <15>, + <16>, + <17>, + <47>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(DMA1)>; + #dma-cells = <4>; + status = "disabled"; + }; + + dma2: dma@40026400 { + compatible = "st,stm32-dma"; + reg = <0x40026400 0x400>; + interrupts = <56>, + <57>, + <58>, + <59>, + <60>, + <68>, + <69>, + <70>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(DMA2)>; + #dma-cells = <4>; + st,mem2mem; + status = "disabled"; + }; }; }; diff --git a/arch/arm/boot/dts/stm32f769-disco.dts b/arch/arm/boot/dts/stm32f769-disco.dts index 166728aeb166..4463ca13a740 100644 --- a/arch/arm/boot/dts/stm32f769-disco.dts +++ b/arch/arm/boot/dts/stm32f769-disco.dts @@ -63,6 +63,12 @@ }; +&cec { + pinctrl-0 = <&cec_pins_a>; + pinctrl-names = "default"; + status = "okay"; +}; + &clk_hse { clock-frequency = <25000000>; }; diff --git a/arch/arm/boot/dts/stm32h743.dtsi b/arch/arm/boot/dts/stm32h743.dtsi index 36a99db0a3b4..58ec2275181e 100644 --- a/arch/arm/boot/dts/stm32h743.dtsi +++ b/arch/arm/boot/dts/stm32h743.dtsi @@ -59,13 +59,11 @@ }; soc { - usart1: serial@40011000 { - compatible = "st,stm32f7-usart", "st,stm32f7-uart"; - reg = <0x40011000 0x400>; - interrupts = <37>; - status = "disabled"; + timer5: timer@40000c00 { + compatible = "st,stm32-timer"; + reg = <0x40000c00 0x400>; + interrupts = <50>; clocks = <&timer_clk>; - }; usart2: serial@40004400 { @@ -76,11 +74,124 @@ clocks = <&timer_clk>; }; - timer5: timer@40000c00 { - compatible = "st,stm32-timer"; - reg = <0x40000c00 0x400>; - interrupts = <50>; + dac: dac@40007400 { + compatible = "st,stm32h7-dac-core"; + reg = <0x40007400 0x400>; clocks = <&timer_clk>; + clock-names = "pclk"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + dac1: dac@1 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <1>; + status = "disabled"; + }; + + dac2: dac@2 { + compatible = "st,stm32-dac"; + #io-channels-cells = <1>; + reg = <2>; + status = "disabled"; + }; + }; + + usart1: serial@40011000 { + compatible = "st,stm32f7-usart", "st,stm32f7-uart"; + reg = <0x40011000 0x400>; + interrupts = <37>; + status = "disabled"; + clocks = <&timer_clk>; + + }; + + dma1: dma@40020000 { + compatible = "st,stm32-dma"; + reg = <0x40020000 0x400>; + interrupts = <11>, + <12>, + <13>, + <14>, + <15>, + <16>, + <17>, + <47>; + clocks = <&timer_clk>; + #dma-cells = <4>; + st,mem2mem; + status = "disabled"; + }; + + dma2: dma@40020400 { + compatible = "st,stm32-dma"; + reg = <0x40020400 0x400>; + interrupts = <56>, + <57>, + <58>, + <59>, + <60>, + <68>, + <69>, + <70>; + clocks = <&timer_clk>; + #dma-cells = <4>; + st,mem2mem; + status = "disabled"; + }; + + adc_12: adc@40022000 { + compatible = "st,stm32h7-adc-core"; + reg = <0x40022000 0x400>; + interrupts = <18>; + clocks = <&timer_clk>; + clock-names = "bus"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + adc1: adc@0 { + compatible = "st,stm32h7-adc"; + #io-channel-cells = <1>; + reg = <0x0>; + interrupt-parent = <&adc_12>; + interrupts = <0>; + status = "disabled"; + }; + + adc2: adc@100 { + compatible = "st,stm32h7-adc"; + #io-channel-cells = <1>; + reg = <0x100>; + interrupt-parent = <&adc_12>; + interrupts = <1>; + status = "disabled"; + }; + }; + + adc_3: adc@58026000 { + compatible = "st,stm32h7-adc-core"; + reg = <0x58026000 0x400>; + interrupts = <127>; + clocks = <&timer_clk>; + clock-names = "bus"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + adc3: adc@0 { + compatible = "st,stm32h7-adc"; + #io-channel-cells = <1>; + reg = <0x0>; + interrupt-parent = <&adc_3>; + interrupts = <0>; + status = "disabled"; + }; }; }; }; diff --git a/arch/arm/boot/dts/stm32h743i-eval.dts b/arch/arm/boot/dts/stm32h743i-eval.dts index c6effbb36e4a..6c07786e7ddb 100644 --- a/arch/arm/boot/dts/stm32h743i-eval.dts +++ b/arch/arm/boot/dts/stm32h743i-eval.dts @@ -60,6 +60,24 @@ aliases { serial0 = &usart1; }; + + vdda: regulator-vdda { + compatible = "regulator-fixed"; + regulator-name = "vdda"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; +}; + +&adc_12 { + vref-supply = <&vdda>; + status = "okay"; + adc1: adc@0 { + /* potentiometer */ + st,adc-channels = <0>; + status = "okay"; + }; }; &clk_hse { diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index aebc3f9dc7b6..eef072a21acc 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -311,8 +311,8 @@ #size-cells = <0>; reg = <0>; - tcon1_in_drc1: endpoint@0 { - reg = <0>; + tcon1_in_drc1: endpoint@1 { + reg = <1>; remote-endpoint = <&drc1_out_tcon1>; }; }; @@ -1012,8 +1012,8 @@ #size-cells = <0>; reg = <1>; - be1_out_drc1: endpoint@0 { - reg = <0>; + be1_out_drc1: endpoint@1 { + reg = <1>; remote-endpoint = <&drc1_in_be1>; }; }; @@ -1042,8 +1042,8 @@ #size-cells = <0>; reg = <0>; - drc1_in_be1: endpoint@0 { - reg = <0>; + drc1_in_be1: endpoint@1 { + reg = <1>; remote-endpoint = <&be1_out_drc1>; }; }; @@ -1053,8 +1053,8 @@ #size-cells = <0>; reg = <1>; - drc1_out_tcon1: endpoint@0 { - reg = <0>; + drc1_out_tcon1: endpoint@1 { + reg = <1>; remote-endpoint = <&tcon1_in_drc1>; }; }; @@ -1155,11 +1155,11 @@ ; }; - nmi_intc: interrupt-controller@01f00c0c { - compatible = "allwinner,sun6i-a31-sc-nmi"; + nmi_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun6i-a31-r-intc"; interrupt-controller; #interrupt-cells = <2>; - reg = <0x01f00c0c 0x38>; + reg = <0x01f00c00 0x400>; interrupts = ; }; diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts index bb510187602c..852a0aa24dce 100644 --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts @@ -271,6 +271,10 @@ status = "okay"; }; +&battery_power_supply { + status = "okay"; +}; + ®_dcdc2 { regulator-always-on; regulator-min-microvolt = <1000000>; diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi index a8b978d0f35b..ea50dda75adc 100644 --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi @@ -519,11 +519,11 @@ #clock-cells = <1>; }; - nmi_intc: interrupt-controller@01f00c0c { - compatible = "allwinner,sun6i-a31-sc-nmi"; + nmi_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun6i-a31-r-intc"; interrupt-controller; #interrupt-cells = <2>; - reg = <0x01f00c0c 0x38>; + reg = <0x01f00c00 0x400>; interrupts = ; }; diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts index aecdeeb368ed..1f0d60afb25b 100644 --- a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts +++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -43,6 +43,7 @@ /dts-v1/; #include "sun8i-a83t.dtsi" +#include "sunxi-common-regulators.dtsi" / { model = "Allwinner A83T H8Homlet Proto Dev Board v2.0"; @@ -57,8 +58,92 @@ }; }; +&ehci0 { + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v0>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + bus-width = <4>; + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v0>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +®_usb0_vbus { + gpio = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* PL5 */ + status = "okay"; +}; + +®_usb1_vbus { + gpio = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp81x: pmic@3a3 { + compatible = "x-powers,axp818", "x-powers,axp813"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; + + ac100: codec@e89 { + compatible = "x-powers,ac100"; + reg = <0xe89>; + + ac100_codec: codec { + compatible = "x-powers,ac100-codec"; + interrupt-parent = <&r_pio>; + interrupts = <0 11 IRQ_TYPE_LEVEL_LOW>; /* PL11 */ + #clock-cells = <0>; + clock-output-names = "4M_adda"; + }; + + ac100_rtc: rtc { + compatible = "x-powers,ac100-rtc"; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + clocks = <&ac100_codec>; + #clock-cells = <1>; + clock-output-names = "cko1_rtc", + "cko2_rtc", + "cko3_rtc"; + }; + }; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; + +&usbphy { + usb0_vbus-supply = <®_usb0_vbus>; + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts new file mode 100644 index 000000000000..2bafd7e99ef7 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts @@ -0,0 +1,148 @@ +/* + * Copyright 2017 Chen-Yu Tsai + * + * Chen-Yu Tsai + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a83t.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include + +/ { + model = "Banana Pi BPI-M3"; + compatible = "sinovoip,bpi-m3", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci0 { + /* Terminus Tech FE 1.1s 4-port USB 2.0 hub here */ + status = "okay"; + + /* TODO GL830 USB-to-SATA bridge downstream w/ GPIO power controls */ +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp81x: pmic@3a3 { + compatible = "x-powers,axp813"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; + + ac100: codec@e89 { + compatible = "x-powers,ac100"; + reg = <0xe89>; + + ac100_codec: codec { + compatible = "x-powers,ac100-codec"; + interrupt-parent = <&r_pio>; + interrupts = <0 11 IRQ_TYPE_LEVEL_LOW>; /* PL11 */ + #clock-cells = <0>; + clock-output-names = "4M_adda"; + }; + + ac100_rtc: rtc { + compatible = "x-powers,ac100-rtc"; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + clocks = <&ac100_codec>; + #clock-cells = <1>; + clock-output-names = "cko1_rtc", + "cko2_rtc", + "cko3_rtc"; + }; + }; +}; + +®_usb1_vbus { + gpio = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */ + status = "okay"; +}; + +®_vcc3v0 { + status = "disabled"; +}; + +®_vcc5v0 { + status = "disabled"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts index cff33454fc24..716a205c6dbb 100644 --- a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts +++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -44,6 +44,7 @@ /dts-v1/; #include "sun8i-a83t.dtsi" +#include "sunxi-common-regulators.dtsi" #include @@ -83,6 +84,17 @@ }; }; + usb-hub { + /* I2C is not connected */ + compatible = "smsc,usb3503"; + initial-mode = <1>; /* initialize in HUB mode */ + disabled-ports = <1>; + intn-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + reset-gpios = <&pio 4 16 GPIO_ACTIVE_HIGH>; /* PE16 */ + connect-gpios = <&pio 4 17 GPIO_ACTIVE_HIGH>; /* PE17 */ + refclk-frequency = <19200000>; + }; + sound { compatible = "simple-audio-card"; simple-audio-card,name = "On-board SPDIF"; @@ -102,6 +114,89 @@ }; }; +&ehci0 { + /* GL830 USB-to-SATA bridge here */ + status = "okay"; +}; + +&ehci1 { + /* USB3503 HSIC USB 2.0 hub here */ + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_emmc_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp81x: pmic@3a3 { + compatible = "x-powers,axp818", "x-powers,axp813"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; + + ac100: codec@e89 { + compatible = "x-powers,ac100"; + reg = <0xe89>; + + ac100_codec: codec { + compatible = "x-powers,ac100-codec"; + interrupt-parent = <&r_pio>; + interrupts = <0 11 IRQ_TYPE_LEVEL_LOW>; /* PL11 */ + #clock-cells = <0>; + clock-output-names = "4M_adda"; + }; + + ac100_rtc: rtc { + compatible = "x-powers,ac100-rtc"; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + clocks = <&ac100_codec>; + #clock-cells = <1>; + clock-output-names = "cko1_rtc", + "cko2_rtc", + "cko3_rtc"; + }; + }; +}; + +®_usb1_vbus { + gpio = <&pio 3 29 GPIO_ACTIVE_HIGH>; /* PD29 */ + status = "okay"; +}; + +®_usb2_vbus { + gpio = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */ + status = "okay"; +}; + +®_vcc3v0 { + status = "disabled"; +}; + +®_vcc5v0 { + status = "disabled"; +}; + &spdif { status = "okay"; }; @@ -111,3 +206,9 @@ pinctrl-0 = <&uart0_pb_pins>; status = "okay"; }; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index 19a8f4fcfab5..f996bd343e50 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -47,6 +47,7 @@ #include #include #include +#include / { interrupt-parent = <&gic>; @@ -182,6 +183,141 @@ #dma-cells = <1>; }; + mmc0: mmc@1c0f000 { + compatible = "allwinner,sun8i-a83t-mmc", + "allwinner,sun7i-a20-mmc"; + reg = <0x01c0f000 0x1000>; + clocks = <&ccu CLK_BUS_MMC0>, + <&ccu CLK_MMC0>, + <&ccu CLK_MMC0_OUTPUT>, + <&ccu CLK_MMC0_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc1: mmc@1c10000 { + compatible = "allwinner,sun8i-a83t-mmc", + "allwinner,sun7i-a20-mmc"; + reg = <0x01c10000 0x1000>; + clocks = <&ccu CLK_BUS_MMC1>, + <&ccu CLK_MMC1>, + <&ccu CLK_MMC1_OUTPUT>, + <&ccu CLK_MMC1_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC1>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc2: mmc@1c11000 { + compatible = "allwinner,sun8i-a83t-emmc"; + reg = <0x01c11000 0x1000>; + clocks = <&ccu CLK_BUS_MMC2>, + <&ccu CLK_MMC2>, + <&ccu CLK_MMC2_OUTPUT>, + <&ccu CLK_MMC2_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC2>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + usb_otg: usb@01c19000 { + compatible = "allwinner,sun8i-a83t-musb", + "allwinner,sun8i-a33-musb"; + reg = <0x01c19000 0x0400>; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; + interrupts = ; + interrupt-names = "mc"; + phys = <&usbphy 0>; + phy-names = "usb"; + extcon = <&usbphy 0>; + status = "disabled"; + }; + + usbphy: phy@1c19400 { + compatible = "allwinner,sun8i-a83t-usb-phy"; + reg = <0x01c19400 0x10>, + <0x01c1a800 0x14>, + <0x01c1b800 0x14>; + reg-names = "phy_ctrl", + "pmu1", + "pmu2"; + clocks = <&ccu CLK_USB_PHY0>, + <&ccu CLK_USB_PHY1>, + <&ccu CLK_USB_HSIC>, + <&ccu CLK_USB_HSIC_12M>; + clock-names = "usb0_phy", + "usb1_phy", + "usb2_phy", + "usb2_hsic_12M"; + resets = <&ccu RST_USB_PHY0>, + <&ccu RST_USB_PHY1>, + <&ccu RST_USB_HSIC>; + reset-names = "usb0_reset", + "usb1_reset", + "usb2_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ehci0: usb@1c1a000 { + compatible = "allwinner,sun8i-a83t-ehci", + "generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI0>; + resets = <&ccu RST_BUS_EHCI0>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci0: usb@1c1a400 { + compatible = "allwinner,sun8i-a83t-ohci", + "generic-ohci"; + reg = <0x01c1a400 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_OHCI0>, <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_OHCI0>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ehci1: usb@1c1b000 { + compatible = "allwinner,sun8i-a83t-ehci", + "generic-ehci"; + reg = <0x01c1b000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI1>; + resets = <&ccu RST_BUS_EHCI1>; + phys = <&usbphy 2>; + phy-names = "usb"; + status = "disabled"; + }; + ccu: clock@1c20000 { compatible = "allwinner,sun8i-a83t-ccu"; reg = <0x01c20000 0x400>; @@ -212,6 +348,15 @@ bias-pull-up; }; + mmc2_8bit_emmc_pins: mmc2-8bit-emmc-pins { + pins = "PC5", "PC6", "PC8", "PC9", + "PC10", "PC11", "PC12", "PC13", + "PC14", "PC15", "PC16"; + function = "mmc2"; + drive-strength = <30>; + bias-pull-up; + }; + spdif_tx_pin: spdif-tx-pin { pins = "PE18"; function = "spdif"; @@ -281,6 +426,15 @@ interrupts = ; }; + r_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun8i-a83t-r-intc", + "allwinner,sun6i-a31-r-intc"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x01f00c00 0x400>; + interrupts = ; + }; + r_ccu: clock@1f01400 { compatible = "allwinner,sun8i-a83t-r-ccu"; reg = <0x01f01400 0x400>; @@ -302,6 +456,28 @@ #gpio-cells = <3>; interrupt-controller; #interrupt-cells = <3>; + + r_rsb_pins: r-rsb-pins { + pins = "PL0", "PL1"; + function = "s_rsb"; + drive-strength = <20>; + bias-pull-up; + }; + }; + + r_rsb: rsb@1f03400 { + compatible = "allwinner,sun8i-a83t-rsb", + "allwinner,sun8i-a23-rsb"; + reg = <0x01f03400 0x400>; + interrupts = ; + clocks = <&r_ccu CLK_APB0_RSB>; + clock-frequency = <3000000>; + resets = <&r_ccu RST_APB0_RSB>; + pinctrl-names = "default"; + pinctrl-0 = <&r_rsb_pins>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; }; }; }; diff --git a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts index e7fae65eb5d3..10da56e86ab8 100644 --- a/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts +++ b/arch/arm/boot/dts/sun8i-h3-beelink-x2.dts @@ -100,6 +100,10 @@ }; }; +&ehci0 { + status = "okay"; +}; + &ehci1 { status = "okay"; }; @@ -147,10 +151,19 @@ status = "okay"; }; +&ohci0 { + status = "okay"; +}; + &ohci1 { status = "okay"; }; +®_usb0_vbus { + gpio = <&r_pio 0 2 GPIO_ACTIVE_HIGH>; /* PL2 */ + status = "okay"; +}; + &spdif { pinctrl-names = "default"; pinctrl-0 = <&spdif_tx_pins_a>; @@ -163,7 +176,14 @@ status = "okay"; }; -&usbphy { - /* USB VBUS is on as long as VCC-IO is on */ +&usb_otg { + dr_mode = "otg"; status = "okay"; }; + +&usbphy { + /* USB VBUS is always on except for the OTG port */ + status = "okay"; + usb0_id_det-gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA07 */ + usb0_vbus-supply = <®_usb0_vbus>; +}; diff --git a/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts new file mode 100644 index 000000000000..eaf09666720d --- /dev/null +++ b/arch/arm/boot/dts/sun8i-r16-bananapi-m2m.dts @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2017 Free Electrons + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a33.dtsi" + +#include + +/ { + model = "BananaPi M2 Magic"; + compatible = "sinovoip,bananapi-m2m", "allwinner,sun8i-a33"; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + serial0 = &uart0; + serial1 = &uart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + blue { + label = "bpi-m2m:blue:usr"; + gpios = <&pio 2 7 GPIO_ACTIVE_LOW>; + }; + + green { + label = "bpi-m2m:green:usr"; + gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; + }; + + red { + label = "bpi-m2m:red:power"; + gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; + + reg_vcc5v0: vcc5v0 { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL06 */ + }; +}; + +&codec { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <®_dcdc3>; +}; + +&cpu0_opp_table { + opp@1104000000 { + opp-hz = /bits/ 64 <1104000000>; + opp-microvolt = <1320000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; + + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1320000>; + clock-latency-ns = <244144>; /* 8 32k periods */ + }; +}; + +&dai { + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +/* This is the i2c bus exposed on the DSI connector for the touch panel */ +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "disabled"; +}; + +/* This is the i2c bus exposed on the GPIO header */ +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "disabled"; +}; + +/* This is the i2c bus exposed on the CSI connector to control the sensor */ +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>; + vmmc-supply = <®_dcdc1>; + bus-width = <4>; + cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ + cd-inverted; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_a>; + vmmc-supply = <®_aldo1>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_pins>; + vmmc-supply = <®_dcdc1>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp22x: pmic@3a3 { + compatible = "x-powers,axp223"; + reg = <0x3a3>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + eldoin-supply = <®_dcdc1>; + x-powers,drive-vbus-en; + }; +}; + +#include "axp223.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-io"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-name = "vdd-dll"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_dc1sw { + regulator-name = "vcc-lcd"; +}; + +®_dc5ldo { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpus"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-3v0"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-sys"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +/* + * Our WiFi chip needs both DLDO1 and DLDO2 to be powered at the same + * time, with the two being in sync. Since this is not really + * supported right now, just use the two as always on, and we will fix + * it later. + */ +®_dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi0"; +}; + +®_dldo2 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi1"; +}; + +®_drivevbus { + regulator-name = "usb0-vbus"; + status = "okay"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&sound { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_a>, <&uart1_pins_cts_rts_a>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>; /* PH8 */ + usb0_vbus_power-supply = <&usb_power_supply>; + usb0_vbus-supply = <®_drivevbus>; + usb1_vbus-supply = <®_vcc5v0>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/tango4-common.dtsi b/arch/arm/boot/dts/tango4-common.dtsi index 0c8cad4d6ee6..12ab6e0c0331 100644 --- a/arch/arm/boot/dts/tango4-common.dtsi +++ b/arch/arm/boot/dts/tango4-common.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Based on Mans Rullgard's Tango3 DT * https://github.com/mansr/linux-tangox diff --git a/arch/arm/boot/dts/tango4-smp8758.dtsi b/arch/arm/boot/dts/tango4-smp8758.dtsi index d2e65c46bcc7..1c6a5bf1a86b 100644 --- a/arch/arm/boot/dts/tango4-smp8758.dtsi +++ b/arch/arm/boot/dts/tango4-smp8758.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tango4-common.dtsi" / { @@ -13,7 +14,6 @@ reg = <0>; clocks = <&clkgen CPU_CLK>; clock-latency = <1>; - operating-points = <1215000 0 607500 0 405000 0 243000 0 135000 0>; }; cpu1: cpu@1 { diff --git a/arch/arm/boot/dts/tango4-vantage-1172.dts b/arch/arm/boot/dts/tango4-vantage-1172.dts index 13bcc460bcb2..d237d7f02c51 100644 --- a/arch/arm/boot/dts/tango4-vantage-1172.dts +++ b/arch/arm/boot/dts/tango4-vantage-1172.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tango4-smp8758.dtsi" diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts index 1444fbd543e7..acd6cf51b15b 100644 --- a/arch/arm/boot/dts/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/tegra114-dalmore.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This dts file supports Dalmore A04. * Other board revisions are not supported @@ -1122,6 +1123,16 @@ non-removable; }; + usb@7d000000 { + compatible = "nvidia,tegra114-udc"; + status = "okay"; + dr_mode = "peripheral"; + }; + + usb-phy@7d000000 { + status = "okay"; + }; + usb@7d008000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/tegra114-roth.dts b/arch/arm/boot/dts/tegra114-roth.dts index 966a7fc044af..7ed7370ee67a 100644 --- a/arch/arm/boot/dts/tegra114-roth.dts +++ b/arch/arm/boot/dts/tegra114-roth.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra114-tn7.dts b/arch/arm/boot/dts/tegra114-tn7.dts index a161fa1dfb61..7fc4a8b31e45 100644 --- a/arch/arm/boot/dts/tegra114-tn7.dts +++ b/arch/arm/boot/dts/tegra114-tn7.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 8932ea3afd5f..0e4a13295d8a 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi index accb7055165a..784a529e1f19 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { clock@60006000 { emc-timings-3 { diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts index 7bacb2954f58..e8e777b8ef1b 100644 --- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts +++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include @@ -1722,7 +1723,7 @@ lanes { usb2-0 { - nvidia,function = "xusb"; + nvidia,function = "snps"; status = "okay"; }; @@ -1829,6 +1830,16 @@ }; }; + usb@7d000000 { + compatible = "nvidia,tegra124-udc"; + status = "okay"; + dr_mode = "peripheral"; + }; + + usb-phy@7d000000 { + status = "okay"; + }; + /* mini-PCIe USB */ usb@7d004000 { status = "okay"; diff --git a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi index 4458e86b2769..9af21fe93a5c 100644 --- a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { clock@60006000 { emc-timings-1 { diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts index 12eb7809d9ab..d97791b98958 100644 --- a/arch/arm/boot/dts/tegra124-nyan-big.dts +++ b/arch/arm/boot/dts/tegra124-nyan-big.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra124-nyan.dtsi" diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi index 4e7b59e25728..c7c31d4c1a2b 100644 --- a/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { clock@60006000 { emc-timings-1 { diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze.dts b/arch/arm/boot/dts/tegra124-nyan-blaze.dts index 1078a73d5092..2a029ee86dd7 100644 --- a/arch/arm/boot/dts/tegra124-nyan-blaze.dts +++ b/arch/arm/boot/dts/tegra124-nyan-blaze.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra124-nyan.dtsi" diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi b/arch/arm/boot/dts/tegra124-nyan.dtsi index 5cf987b5401e..3609367037a6 100644 --- a/arch/arm/boot/dts/tegra124-nyan.dtsi +++ b/arch/arm/boot/dts/tegra124-nyan.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "tegra124.dtsi" diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts index 6e59cec0962b..32d9079f025b 100644 --- a/arch/arm/boot/dts/tegra124-venice2.dts +++ b/arch/arm/boot/dts/tegra124-venice2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 1b10b14a6abd..a7e43dcbf744 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -87,6 +88,7 @@ clocks = <&tegra_car TEGRA124_CLK_HOST1X>; resets = <&tegra_car 28>; reset-names = "host1x"; + iommus = <&mc TEGRA_SWGROUP_HC>; #address-cells = <2>; #size-cells = <2>; diff --git a/arch/arm/boot/dts/tegra20-colibri-512.dtsi b/arch/arm/boot/dts/tegra20-colibri-512.dtsi index 1242b841f147..813ae34edd6a 100644 --- a/arch/arm/boot/dts/tegra20-colibri-512.dtsi +++ b/arch/arm/boot/dts/tegra20-colibri-512.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tegra20.dtsi" / { diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts index 41749693ec3c..628a55a9318b 100644 --- a/arch/arm/boot/dts/tegra20-harmony.dts +++ b/arch/arm/boot/dts/tegra20-harmony.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra20-iris-512.dts b/arch/arm/boot/dts/tegra20-iris-512.dts index bb56dfe9e10c..40126388946d 100644 --- a/arch/arm/boot/dts/tegra20-iris-512.dts +++ b/arch/arm/boot/dts/tegra20-iris-512.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra20-colibri-512.dtsi" diff --git a/arch/arm/boot/dts/tegra20-medcom-wide.dts b/arch/arm/boot/dts/tegra20-medcom-wide.dts index 34c6588e92ef..cda5448c2ace 100644 --- a/arch/arm/boot/dts/tegra20-medcom-wide.dts +++ b/arch/arm/boot/dts/tegra20-medcom-wide.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra20-tamonten.dtsi" diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts index b4bfa5586c23..30436969adc0 100644 --- a/arch/arm/boot/dts/tegra20-paz00.dts +++ b/arch/arm/boot/dts/tegra20-paz00.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include @@ -452,7 +453,9 @@ }; usb@c5000000 { + compatible = "nvidia,tegra20-udc"; status = "okay"; + dr_mode = "peripheral"; }; usb-phy@c5000000 { diff --git a/arch/arm/boot/dts/tegra20-plutux.dts b/arch/arm/boot/dts/tegra20-plutux.dts index a10b415bbdee..429e4605fbdb 100644 --- a/arch/arm/boot/dts/tegra20-plutux.dts +++ b/arch/arm/boot/dts/tegra20-plutux.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra20-tamonten.dtsi" diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index 2017acacc00c..284aae351ff2 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi index 7361f4a82e80..872046d48709 100644 --- a/arch/arm/boot/dts/tegra20-tamonten.dtsi +++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tegra20.dtsi" / { diff --git a/arch/arm/boot/dts/tegra20-tec.dts b/arch/arm/boot/dts/tegra20-tec.dts index 9cb534f4441e..4dec27737238 100644 --- a/arch/arm/boot/dts/tegra20-tec.dts +++ b/arch/arm/boot/dts/tegra20-tec.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra20-tamonten.dtsi" diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts index b902ab594afa..d55c6b240a30 100644 --- a/arch/arm/boot/dts/tegra20-trimslice.dts +++ b/arch/arm/boot/dts/tegra20-trimslice.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts index 8f0aaabf7e28..ee3fbf941e79 100644 --- a/arch/arm/boot/dts/tegra20-ventana.dts +++ b/arch/arm/boot/dts/tegra20-ventana.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 7c85f97f72ea..914f59166a99 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts index fc530e4a96c4..07b945b0391a 100644 --- a/arch/arm/boot/dts/tegra30-apalis-eval.dts +++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi index 7a6a1a014603..faa8cd2914e8 100644 --- a/arch/arm/boot/dts/tegra30-apalis.dtsi +++ b/arch/arm/boot/dts/tegra30-apalis.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tegra30.dtsi" /* diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts index 4f41b18d9547..5331a8f7dcf8 100644 --- a/arch/arm/boot/dts/tegra30-beaver.dts +++ b/arch/arm/boot/dts/tegra30-beaver.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra30.dtsi" @@ -1927,6 +1928,16 @@ non-removable; }; + usb@7d000000 { + compatible = "nvidia,tegra30-udc"; + status = "okay"; + dr_mode = "peripheral"; + }; + + usb-phy@7d000000 { + status = "okay"; + }; + usb@7d004000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/tegra30-cardhu-a02.dts b/arch/arm/boot/dts/tegra30-cardhu-a02.dts index c9bfedcca6ed..a02ec5082287 100644 --- a/arch/arm/boot/dts/tegra30-cardhu-a02.dts +++ b/arch/arm/boot/dts/tegra30-cardhu-a02.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra30-cardhu.dtsi" diff --git a/arch/arm/boot/dts/tegra30-cardhu-a04.dts b/arch/arm/boot/dts/tegra30-cardhu-a04.dts index fadf55e46b2b..4dbd4af679f0 100644 --- a/arch/arm/boot/dts/tegra30-cardhu-a04.dts +++ b/arch/arm/boot/dts/tegra30-cardhu-a04.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra30-cardhu.dtsi" diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index 83dc14a9b353..92a9740c533f 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "tegra30.dtsi" diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts index a8c0318743b6..3c5fb2430212 100644 --- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra30-colibri.dtsi" diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi index 5360d638eedc..139bfa028b04 100644 --- a/arch/arm/boot/dts/tegra30-colibri.dtsi +++ b/arch/arm/boot/dts/tegra30-colibri.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "tegra30.dtsi" diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 13960fda7471..c3e9f1e847db 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/boot/dts/tps65217.dtsi b/arch/arm/boot/dts/tps65217.dtsi index 02de56b55823..399baaa0a2ab 100644 --- a/arch/arm/boot/dts/tps65217.dtsi +++ b/arch/arm/boot/dts/tps65217.dtsi @@ -18,11 +18,14 @@ charger { compatible = "ti,tps65217-charger"; + interrupts = <0>, <1>; + interrupt-names = "USB", "AC"; status = "disabled"; }; pwrbutton { compatible = "ti,tps65217-pwrbutton"; + interrupts = <2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/uniphier-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ld4-ref.dts index 4817ebb28eb2..b3aaab354f3e 100644 --- a/arch/arm/boot/dts/uniphier-ld4-ref.dts +++ b/arch/arm/boot/dts/uniphier-ld4-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld4.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld4.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD4 Reference Board"; @@ -64,3 +64,7 @@ &usb1 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-ld4.dtsi b/arch/arm/boot/dts/uniphier-ld4.dtsi index fb2fd9605b9d..93586faf950f 100644 --- a/arch/arm/boot/dts/uniphier-ld4.dtsi +++ b/arch/arm/boot/dts/uniphier-ld4.dtsi @@ -209,7 +209,8 @@ interrupts = <0 80 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0>; - clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>, + <&mio_clk 12>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>; }; @@ -221,7 +222,8 @@ interrupts = <0 81 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1>; - clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>, + <&mio_clk 13>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>; }; @@ -233,7 +235,8 @@ interrupts = <0 82 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb2>; - clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 10>, + <&mio_clk 14>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>, <&mio_rst 14>; }; @@ -270,6 +273,13 @@ interrupt-controller; }; + aidet: aidet@61830000 { + compatible = "socionext,uniphier-ld4-aidet"; + reg = <0x61830000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + sysctrl@61840000 { compatible = "socionext,uniphier-ld4-sysctrl", "simple-mfd", "syscon"; @@ -285,7 +295,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5a"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-ld6b-ref.dts b/arch/arm/boot/dts/uniphier-ld6b-ref.dts index 96db4abc02c3..2188d114d79b 100644 --- a/arch/arm/boot/dts/uniphier-ld6b-ref.dts +++ b/arch/arm/boot/dts/uniphier-ld6b-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld6b.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld6b.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD6b Reference Board"; @@ -58,3 +58,7 @@ &i2c0 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-ld6b.dtsi b/arch/arm/boot/dts/uniphier-ld6b.dtsi index 8b9a79731bd3..9a7b25cc8233 100644 --- a/arch/arm/boot/dts/uniphier-ld6b.dtsi +++ b/arch/arm/boot/dts/uniphier-ld6b.dtsi @@ -12,7 +12,7 @@ * The D-chip (digital chip) is the same as the PXs2 die. * Reuse the PXs2 device tree with some properties overridden. */ -/include/ "uniphier-pxs2.dtsi" +#include "uniphier-pxs2.dtsi" / { compatible = "socionext,uniphier-ld6b"; diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi b/arch/arm/boot/dts/uniphier-pinctrl.dtsi index 246f35ffb638..be82cddc4072 100644 --- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi +++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi @@ -4,51 +4,35 @@ * Copyright (C) 2015-2017 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ &pinctrl { + pinctrl_aout: aout_grp { + groups = "aout"; + function = "aout"; + }; + pinctrl_emmc: emmc_grp { groups = "emmc", "emmc_dat8"; function = "emmc"; }; + pinctrl_ether_mii: ether_mii_grp { + groups = "ether_mii"; + function = "ether_mii"; + }; + + pinctrl_ether_rgmii: ether_rgmii_grp { + groups = "ether_rgmii"; + function = "ether_rgmii"; + }; + + pinctrl_ether_rmii: ether_rmii_grp { + groups = "ether_rmii"; + function = "ether_rmii"; + }; + pinctrl_i2c0: i2c0_grp { groups = "i2c0"; function = "i2c0"; diff --git a/arch/arm/boot/dts/uniphier-pro4-ace.dts b/arch/arm/boot/dts/uniphier-pro4-ace.dts index 11690b57931c..089419cee273 100644 --- a/arch/arm/boot/dts/uniphier-pro4-ace.dts +++ b/arch/arm/boot/dts/uniphier-pro4-ace.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pro4.dtsi" +#include "uniphier-pro4.dtsi" / { model = "UniPhier Pro4 Ace Board"; diff --git a/arch/arm/boot/dts/uniphier-pro4-ref.dts b/arch/arm/boot/dts/uniphier-pro4-ref.dts index 4cf539245f2e..903df6348e77 100644 --- a/arch/arm/boot/dts/uniphier-pro4-ref.dts +++ b/arch/arm/boot/dts/uniphier-pro4-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-pro4.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-pro4.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier Pro4 Reference Board"; @@ -66,3 +66,7 @@ &usb3 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-pro4-sanji.dts b/arch/arm/boot/dts/uniphier-pro4-sanji.dts index 2763cebcd76a..adef212b45b2 100644 --- a/arch/arm/boot/dts/uniphier-pro4-sanji.dts +++ b/arch/arm/boot/dts/uniphier-pro4-sanji.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pro4.dtsi" +#include "uniphier-pro4.dtsi" / { model = "UniPhier Pro4 Sanji Board"; diff --git a/arch/arm/boot/dts/uniphier-pro4.dtsi b/arch/arm/boot/dts/uniphier-pro4.dtsi index 37400becf4ba..2a9bd7f9f5db 100644 --- a/arch/arm/boot/dts/uniphier-pro4.dtsi +++ b/arch/arm/boot/dts/uniphier-pro4.dtsi @@ -241,7 +241,8 @@ interrupts = <0 80 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb2>; - clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>, + <&mio_clk 12>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>; }; @@ -253,7 +254,8 @@ interrupts = <0 81 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb3>; - clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>, + <&mio_clk 13>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>; }; @@ -268,6 +270,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pro4-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + timer@60000200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x60000200 0x20>; @@ -305,7 +314,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5a"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-pro5.dtsi b/arch/arm/boot/dts/uniphier-pro5.dtsi index 9577769a0add..b026bcd42a06 100644 --- a/arch/arm/boot/dts/uniphier-pro5.dtsi +++ b/arch/arm/boot/dts/uniphier-pro5.dtsi @@ -4,43 +4,7 @@ * Copyright (C) 2015-2016 Socionext Inc. * Author: Masahiro Yamada * - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ / { @@ -328,7 +292,7 @@ sdctrl@59810000 { compatible = "socionext,uniphier-pro5-sdctrl", "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; + reg = <0x59810000 0x400>; sd_clk: clock { compatible = "socionext,uniphier-pro5-sd-clock"; @@ -367,6 +331,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pro5-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + timer@60000200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x60000200 0x20>; @@ -404,7 +375,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts index 81560f75bfa7..7dfae2667f50 100644 --- a/arch/arm/boot/dts/uniphier-pxs2-gentil.dts +++ b/arch/arm/boot/dts/uniphier-pxs2-gentil.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pxs2.dtsi" +#include "uniphier-pxs2.dtsi" / { model = "UniPhier PXs2 Gentil Board"; diff --git a/arch/arm/boot/dts/uniphier-pxs2-vodka.dts b/arch/arm/boot/dts/uniphier-pxs2-vodka.dts index dc2d0579c666..0cf615463a82 100644 --- a/arch/arm/boot/dts/uniphier-pxs2-vodka.dts +++ b/arch/arm/boot/dts/uniphier-pxs2-vodka.dts @@ -8,7 +8,7 @@ */ /dts-v1/; -/include/ "uniphier-pxs2.dtsi" +#include "uniphier-pxs2.dtsi" / { model = "UniPhier PXs2 Vodka Board"; diff --git a/arch/arm/boot/dts/uniphier-pxs2.dtsi b/arch/arm/boot/dts/uniphier-pxs2.dtsi index bace751d4023..90b020c95083 100644 --- a/arch/arm/boot/dts/uniphier-pxs2.dtsi +++ b/arch/arm/boot/dts/uniphier-pxs2.dtsi @@ -276,7 +276,7 @@ sdctrl@59810000 { compatible = "socionext,uniphier-pxs2-sdctrl", "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; + reg = <0x59810000 0x400>; sd_clk: clock { compatible = "socionext,uniphier-pxs2-sd-clock"; @@ -315,6 +315,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pxs2-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + timer@60000200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x60000200 0x20>; @@ -352,7 +359,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/uniphier-sld3-ref.dts b/arch/arm/boot/dts/uniphier-sld3-ref.dts deleted file mode 100644 index 70cda39a3dd2..000000000000 --- a/arch/arm/boot/dts/uniphier-sld3-ref.dts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Device Tree Source for UniPhier sLD3 Reference Board - * - * Copyright (C) 2015-2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: (GPL-2.0+ OR MIT) - */ - -/dts-v1/; -/include/ "uniphier-sld3.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" - -/ { - model = "UniPhier sLD3 Reference Board"; - compatible = "socionext,uniphier-sld3-ref", "socionext,uniphier-sld3"; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - aliases { - serial0 = &serial0; - serial1 = &serial1; - serial2 = &serial2; - i2c0 = &i2c0; - i2c1 = &i2c1; - i2c2 = &i2c2; - i2c3 = &i2c3; - i2c4 = &i2c4; - }; - - memory@8000000 { - device_type = "memory"; - reg = <0x80000000 0x20000000 - 0xc0000000 0x20000000>; - }; -}; - -ðsc { - interrupts = <0 49 4>; -}; - -&serial0 { - status = "okay"; -}; - -&serial1 { - status = "okay"; -}; - -&serial2 { - status = "okay"; -}; - -&i2c0 { - status = "okay"; -}; - -&usb0 { - status = "okay"; -}; - -&usb1 { - status = "okay"; -}; - -&usb2 { - status = "okay"; -}; - -&usb3 { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/uniphier-sld3.dtsi b/arch/arm/boot/dts/uniphier-sld3.dtsi deleted file mode 100644 index 408287936613..000000000000 --- a/arch/arm/boot/dts/uniphier-sld3.dtsi +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Device Tree Source for UniPhier sLD3 SoC - * - * Copyright (C) 2015-2016 Socionext Inc. - * Author: Masahiro Yamada - * - * SPDX-License-Identifier: (GPL-2.0+ OR MIT) - */ - -/ { - compatible = "socionext,uniphier-sld3"; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a9"; - reg = <0>; - enable-method = "psci"; - next-level-cache = <&l2>; - }; - - cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a9"; - reg = <1>; - enable-method = "psci"; - next-level-cache = <&l2>; - }; - }; - - psci { - compatible = "arm,psci-0.2"; - method = "smc"; - }; - - clocks { - refclk: ref { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <24576000>; - }; - - arm_timer_clk: arm_timer_clk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <50000000>; - }; - }; - - soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - interrupt-parent = <&intc>; - - timer@20000200 { - compatible = "arm,cortex-a9-global-timer"; - reg = <0x20000200 0x20>; - interrupts = <1 11 0x304>; - clocks = <&arm_timer_clk>; - }; - - timer@20000600 { - compatible = "arm,cortex-a9-twd-timer"; - reg = <0x20000600 0x20>; - interrupts = <1 13 0x304>; - clocks = <&arm_timer_clk>; - }; - - intc: interrupt-controller@20001000 { - compatible = "arm,cortex-a9-gic"; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0x20001000 0x1000>, - <0x20000100 0x100>; - }; - - l2: l2-cache@500c0000 { - compatible = "socionext,uniphier-system-cache"; - reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, - <0x506c0000 0x400>; - interrupts = <0 174 4>, <0 175 4>; - cache-unified; - cache-size = <(512 * 1024)>; - cache-sets = <256>; - cache-line-size = <128>; - cache-level = <2>; - }; - - serial0: serial@54006800 { - compatible = "socionext,uniphier-uart"; - status = "disabled"; - reg = <0x54006800 0x40>; - interrupts = <0 33 4>; - clocks = <&sys_clk 0>; - }; - - serial1: serial@54006900 { - compatible = "socionext,uniphier-uart"; - status = "disabled"; - reg = <0x54006900 0x40>; - interrupts = <0 35 4>; - clocks = <&sys_clk 0>; - }; - - serial2: serial@54006a00 { - compatible = "socionext,uniphier-uart"; - status = "disabled"; - reg = <0x54006a00 0x40>; - interrupts = <0 37 4>; - clocks = <&sys_clk 0>; - }; - - i2c0: i2c@58400000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58400000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 41 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - i2c1: i2c@58480000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58480000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 42 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - i2c2: i2c@58500000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58500000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 43 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - i2c3: i2c@58580000 { - compatible = "socionext,uniphier-i2c"; - status = "disabled"; - reg = <0x58580000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 44 1>; - clocks = <&sys_clk 1>; - clock-frequency = <100000>; - }; - - /* chip-internal connection for DMD */ - i2c4: i2c@58600000 { - compatible = "socionext,uniphier-i2c"; - reg = <0x58600000 0x40>; - #address-cells = <1>; - #size-cells = <0>; - interrupts = <0 45 1>; - clocks = <&sys_clk 1>; - clock-frequency = <400000>; - }; - - system_bus: system-bus@58c00000 { - compatible = "socionext,uniphier-system-bus"; - status = "disabled"; - reg = <0x58c00000 0x400>; - #address-cells = <2>; - #size-cells = <1>; - }; - - smpctrl@59801000 { - compatible = "socionext,uniphier-smpctrl"; - reg = <0x59801000 0x400>; - }; - - mioctrl@59810000 { - compatible = "socionext,uniphier-sld3-mioctrl", - "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; - - mio_clk: clock { - compatible = "socionext,uniphier-sld3-mio-clock"; - #clock-cells = <1>; - }; - - mio_rst: reset { - compatible = "socionext,uniphier-sld3-mio-reset"; - #reset-cells = <1>; - }; - }; - - usb0: usb@5a800100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a800100 0x100>; - interrupts = <0 80 4>; - clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, - <&mio_rst 12>; - }; - - usb1: usb@5a810100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a810100 0x100>; - interrupts = <0 81 4>; - clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, - <&mio_rst 13>; - }; - - usb2: usb@5a820100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a820100 0x100>; - interrupts = <0 82 4>; - clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>, - <&mio_rst 14>; - }; - - usb3: usb@5a830100 { - compatible = "socionext,uniphier-ehci", "generic-ehci"; - status = "disabled"; - reg = <0x5a830100 0x100>; - interrupts = <0 83 4>; - clocks = <&mio_clk 7>, <&mio_clk 11>, <&mio_clk 15>; - resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 11>, - <&mio_rst 15>; - }; - - sysctrl@f1840000 { - compatible = "socionext,uniphier-sld3-sysctrl", - "simple-mfd", "syscon"; - reg = <0xf1840000 0x10000>; - - sys_clk: clock { - compatible = "socionext,uniphier-sld3-clock"; - #clock-cells = <1>; - }; - - sys_rst: reset { - compatible = "socionext,uniphier-sld3-reset"; - #reset-cells = <1>; - }; - }; - }; -}; diff --git a/arch/arm/boot/dts/uniphier-sld8-ref.dts b/arch/arm/boot/dts/uniphier-sld8-ref.dts index 4536d5b71297..5accd3cc76e4 100644 --- a/arch/arm/boot/dts/uniphier-sld8-ref.dts +++ b/arch/arm/boot/dts/uniphier-sld8-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-sld8.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-sld8.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier sLD8 Reference Board"; @@ -68,3 +68,7 @@ &usb2 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-sld8.dtsi b/arch/arm/boot/dts/uniphier-sld8.dtsi index 9fb9167f2db4..ebd0c3f63e7f 100644 --- a/arch/arm/boot/dts/uniphier-sld8.dtsi +++ b/arch/arm/boot/dts/uniphier-sld8.dtsi @@ -209,7 +209,8 @@ interrupts = <0 80 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0>; - clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>, + <&mio_clk 12>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>; }; @@ -221,7 +222,8 @@ interrupts = <0 81 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1>; - clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>, + <&mio_clk 13>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>; }; @@ -233,7 +235,8 @@ interrupts = <0 82 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb2>; - clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 10>, + <&mio_clk 14>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>, <&mio_rst 14>; }; @@ -270,6 +273,13 @@ interrupt-controller; }; + aidet: aidet@61830000 { + compatible = "socionext,uniphier-sld8-aidet"; + reg = <0x61830000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + sysctrl@61840000 { compatible = "socionext,uniphier-sld8-sysctrl", "simple-mfd", "syscon"; @@ -285,7 +295,18 @@ #reset-cells = <1>; }; }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5a"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand2cs>; + clocks = <&sys_clk 2>; + }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts index 409e069b3a84..4a51612996bc 100644 --- a/arch/arm/boot/dts/versatile-ab.dts +++ b/arch/arm/boot/dts/versatile-ab.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "skeleton.dtsi" diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts index 06e2331f666d..06a0fdf24026 100644 --- a/arch/arm/boot/dts/versatile-pb.dts +++ b/arch/arm/boot/dts/versatile-pb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "versatile-ab.dts" / { @@ -39,7 +40,7 @@ clock-names = "apb_pclk"; }; - pci-controller@10001000 { + pci@10001000 { compatible = "arm,versatile-pci"; device_type = "pci"; reg = <0x10001000 0x1000 diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi index 1b6f6393be93..b0021a816028 100644 --- a/arch/arm/boot/dts/vexpress-v2m.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Versatile Express * diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts index 0c8de0ca73ee..a8ac4e2ed290 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Versatile Express * diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts index 65ecf206388c..a4c7713edfcd 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Versatile Express * diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts index 6e69b8e6c1a7..32f1906ffecf 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Versatile Express * diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts index c9305b58afc2..5814460e0549 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Versatile Express * diff --git a/arch/arm/boot/dts/xenvm-4.2.dts b/arch/arm/boot/dts/xenvm-4.2.dts index 336915151398..384cd92f1f84 100644 --- a/arch/arm/boot/dts/xenvm-4.2.dts +++ b/arch/arm/boot/dts/xenvm-4.2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Xen Virtual Machine for unprivileged guests * diff --git a/arch/arm/boot/dts/zx296702-ad1.dts b/arch/arm/boot/dts/zx296702-ad1.dts index 081f980cfbe6..eedd3fcbc002 100644 --- a/arch/arm/boot/dts/zx296702-ad1.dts +++ b/arch/arm/boot/dts/zx296702-ad1.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; @@ -18,7 +19,6 @@ }; &mmc0 { - num-slots = <1>; supports-highspeed; non-removable; disable-wp; @@ -31,7 +31,6 @@ }; &mmc1 { - num-slots = <1>; supports-highspeed; non-removable; disable-wp; diff --git a/arch/arm/boot/dts/zx296702.dtsi b/arch/arm/boot/dts/zx296702.dtsi index d45c8fcd7ab4..752d28e0f9b0 100644 --- a/arch/arm/boot/dts/zx296702.dtsi +++ b/arch/arm/boot/dts/zx296702.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "skeleton.dtsi" #include diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index f3ac9bfe580e..0f79fe1ccd9d 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -42,6 +42,14 @@ }; }; + fpga_full: fpga-full { + compatible = "fpga-region"; + fpga-mgr = <&devcfg>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + }; + pmu@f8891000 { compatible = "arm,cortex-a9-pmu"; interrupts = <0 5 4>, <0 6 4>; diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts index 64a6390fc501..0144acfa9793 100644 --- a/arch/arm/boot/dts/zynq-parallella.dts +++ b/arch/arm/boot/dts/zynq-parallella.dts @@ -34,7 +34,7 @@ }; chosen { - bootargs = "earlycon root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait"; + bootargs = "root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait"; stdout-path = "serial0:115200n8"; }; }; @@ -54,6 +54,7 @@ compatible = "ethernet-phy-id0141.0e90", "ethernet-phy-ieee802.3-c22"; reg = <0>; + device_type = "ethernet-phy"; marvell,reg-init = <0x3 0x10 0xff00 0x1e>, <0x3 0x11 0xfff0 0xa>; }; diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index 0cdad2cc8b78..34e8277fce0d 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq ZC702 Development Board"; @@ -30,7 +30,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -97,6 +97,7 @@ ethernet_phy: ethernet-phy@7 { reg = <7>; + device_type = "ethernet-phy"; }; }; @@ -131,6 +132,21 @@ }; }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + adv7511: hdmi-tx@39 { + compatible = "adi,adv7511"; + reg = <0x39>; + adi,input-depth = <8>; + adi,input-colorspace = "yuv422"; + adi,input-clock = "1x"; + adi,input-style = <3>; + adi,input-justification = "right"; + }; + }; + i2c@2 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts index ad4bb06dba25..7ebc8c5ae39d 100644 --- a/arch/arm/boot/dts/zynq-zc706.dts +++ b/arch/arm/boot/dts/zynq-zc706.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq ZC706 Development Board"; @@ -30,7 +30,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -53,6 +53,7 @@ ethernet_phy: ethernet-phy@7 { reg = <7>; + device_type = "ethernet-phy"; }; }; @@ -87,6 +88,21 @@ }; }; + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + adv7511: hdmi-tx@39 { + compatible = "adi,adv7511"; + reg = <0x39>; + adi,input-depth = <8>; + adi,input-colorspace = "yuv422"; + adi,input-clock = "1x"; + adi,input-style = <3>; + adi,input-justification = "evenly"; + }; + }; + i2c@2 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts index 325379f7983c..5e44dc12fd60 100644 --- a/arch/arm/boot/dts/zynq-zed.dts +++ b/arch/arm/boot/dts/zynq-zed.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq Zed Development Board"; @@ -29,7 +29,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -50,6 +50,7 @@ ethernet_phy: ethernet-phy@0 { reg = <0>; + device_type = "ethernet-phy"; }; }; diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts index 590ec24b8749..e40cafc5ee5b 100644 --- a/arch/arm/boot/dts/zynq-zybo.dts +++ b/arch/arm/boot/dts/zynq-zybo.dts @@ -12,7 +12,7 @@ * GNU General Public License for more details. */ /dts-v1/; -/include/ "zynq-7000.dtsi" +#include "zynq-7000.dtsi" / { model = "Zynq ZYBO Development Board"; @@ -29,7 +29,7 @@ }; chosen { - bootargs = "earlycon"; + bootargs = ""; stdout-path = "serial0:115200n8"; }; @@ -51,6 +51,7 @@ ethernet_phy: ethernet-phy@0 { reg = <0>; + device_type = "ethernet-phy"; }; }; diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 1181053e3ade..e5ad0708849a 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config SA1111 bool select DMABOUNCE if !ARCH_PXA diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index 29fdf6a3601d..70b4a14ed993 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/configs/aspeed_g4_defconfig b/arch/arm/configs/aspeed_g4_defconfig index cfc2465e8b77..d23b9d56a88b 100644 --- a/arch/arm/configs/aspeed_g4_defconfig +++ b/arch/arm/configs/aspeed_g4_defconfig @@ -24,6 +24,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_ASPEED=y CONFIG_MACH_ASPEED_G4=y +CONFIG_VMSPLIT_2G=y CONFIG_AEABI=y # CONFIG_CPU_SW_DOMAIN_PAN is not set # CONFIG_COMPACTION is not set @@ -64,6 +65,7 @@ CONFIG_MTD_UBI_FASTMAP=y CONFIG_MTD_UBI_BLOCK=y CONFIG_BLK_DEV_RAM=y CONFIG_ASPEED_LPC_CTRL=y +CONFIG_ASPEED_LPC_SNOOP=y CONFIG_EEPROM_AT24=y CONFIG_NETDEVICES=y CONFIG_NETCONSOLE=y @@ -104,6 +106,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_RUNTIME_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_ASPEED_VUART=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_ASPEED_BT_IPMI_BMC=y @@ -114,6 +117,7 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_ASPEED=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_ASPEED=y @@ -166,7 +170,6 @@ CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y -CONFIG_LOCKUP_DETECTOR=y CONFIG_WQ_WATCHDOG=y CONFIG_PANIC_TIMEOUT=-1 # CONFIG_SCHED_DEBUG is not set diff --git a/arch/arm/configs/aspeed_g5_defconfig b/arch/arm/configs/aspeed_g5_defconfig index 3c20d93de389..c0ad7b82086b 100644 --- a/arch/arm/configs/aspeed_g5_defconfig +++ b/arch/arm/configs/aspeed_g5_defconfig @@ -67,6 +67,7 @@ CONFIG_MTD_UBI_FASTMAP=y CONFIG_MTD_UBI_BLOCK=y CONFIG_BLK_DEV_RAM=y CONFIG_ASPEED_LPC_CTRL=y +CONFIG_ASPEED_LPC_SNOOP=y CONFIG_EEPROM_AT24=y CONFIG_NETDEVICES=y CONFIG_NETCONSOLE=y @@ -107,6 +108,7 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_RUNTIME_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_ASPEED_VUART=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_ASPEED_BT_IPMI_BMC=y @@ -117,6 +119,7 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_MUX_PCA9541=y CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_ASPEED=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_ASPEED=y @@ -169,7 +172,6 @@ CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_STRIP_ASM_SYMS=y CONFIG_DEBUG_FS=y -CONFIG_LOCKUP_DETECTOR=y CONFIG_WQ_WATCHDOG=y CONFIG_PANIC_TIMEOUT=-1 # CONFIG_SCHED_DEBUG is not set diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 3ee9d78c412a..43dab4890ad3 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -55,6 +55,7 @@ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=32 CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_CONSTANTS=y @@ -62,9 +63,15 @@ CONFIG_SCSI_SCAN_ASYNC=y CONFIG_NETDEVICES=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y +CONFIG_BRCMFMAC=m CONFIG_ZD1211RW=y CONFIG_INPUT_EVDEV=y # CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_TTY_PRINTK=y diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index 06e2e2a1a9be..27d9720f7207 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -143,6 +143,8 @@ CONFIG_VIDEO_ADV7343=m CONFIG_DRM=m CONFIG_DRM_TILCDC=m CONFIG_DRM_DUMB_VGA_DAC=m +CONFIG_DRM_TINYDRM=m +CONFIG_TINYDRM_ST7586=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_DA8XX=y diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 25325ed9319e..8c2a2619971b 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -3,7 +3,6 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_CGROUPS=y CONFIG_BLK_DEV_INITRD=y -CONFIG_KALLSYMS_ALL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y @@ -48,7 +47,43 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m +CONFIG_BT_LEDS=y +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_INTEL=y +CONFIG_BT_HCIUART_BCM=y +CONFIG_BT_HCIUART_QCA=y +CONFIG_BT_HCIUART_AG6XX=y +CONFIG_BT_HCIUART_MRVL=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m CONFIG_CFG80211=y +CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y +CONFIG_NFC=y +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=y +CONFIG_NFC_NCI_SPI=m +CONFIG_NFC_NCI_UART=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y +CONFIG_NFC_S3FWRN5_I2C=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_DMA_CMA=y @@ -65,7 +100,9 @@ CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=m CONFIG_NETDEVICES=y CONFIG_SMSC911X=y +CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=y +CONFIG_USB_LAN78XX=m CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y @@ -189,7 +226,25 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_EXYNOS=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_EXYNOS=y +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_UAS=m CONFIG_USB_DWC3=y CONFIG_USB_DWC2=y CONFIG_USB_HSIC_USB3503=y @@ -209,7 +264,6 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_MAX77693=y CONFIG_LEDS_MAX8997=y -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MAX8997=y @@ -253,18 +307,30 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y CONFIG_PRINTK_TIME=y CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y -CONFIG_LOCKUP_DETECTOR=y -CONFIG_DEBUG_RT_MUTEXES=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y +CONFIG_SOFTLOCKUP_DETECTOR=y +# CONFIG_DETECT_HUNG_TASK is not set +CONFIG_PROVE_LOCKING=y +CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_USER=y +CONFIG_CRYPTO_RSA=m +CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_USER=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_SHA3=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_LZ4=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m @@ -276,6 +342,7 @@ CONFIG_CRYPTO_SHA1_ARM_NEON=m CONFIG_CRYPTO_SHA256_ARM=m CONFIG_CRYPTO_SHA512_ARM=m CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRC_CCITT=y CONFIG_FONTS=y CONFIG_FONT_7x14=y diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig index 23660f3d0f7f..484e51fbd4a6 100644 --- a/arch/arm/configs/ezx_defconfig +++ b/arch/arm/configs/ezx_defconfig @@ -27,7 +27,6 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug" CONFIG_KEXEC=y CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEBUG=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_USERSPACE=m CONFIG_CPU_FREQ_GOV_ONDEMAND=m diff --git a/arch/arm/configs/gemini_defconfig b/arch/arm/configs/gemini_defconfig index d2d75fa664a6..2a63fa10c813 100644 --- a/arch/arm/configs/gemini_defconfig +++ b/arch/arm/configs/gemini_defconfig @@ -32,6 +32,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_ATA=y +CONFIG_PATA_FTIDE010=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set @@ -55,8 +56,8 @@ CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_GEMINI=y CONFIG_DMADEVICES=y +CONFIG_AMBA_PL08X=y # CONFIG_DNOTIFY is not set CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index e74de69caeab..32acac9ab81a 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -51,6 +51,7 @@ CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y CONFIG_HIGHMEM=y CONFIG_CMA=y +CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_CMDLINE="noinitrd console=ttymxc0,115200" CONFIG_KEXEC=y CONFIG_CPU_FREQ=y @@ -186,6 +187,7 @@ CONFIG_SERIAL_FSL_LPUART=y CONFIG_SERIAL_FSL_LPUART_CONSOLE=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y CONFIG_I2C_MUX_GPIO=y # CONFIG_I2C_HELPER_AUTO is not set CONFIG_I2C_ALGOPCF=m @@ -193,12 +195,14 @@ CONFIG_I2C_ALGOPCA=m CONFIG_I2C_GPIO=y CONFIG_I2C_IMX=y CONFIG_SPI=y +CONFIG_SPI_GPIO=y CONFIG_SPI_IMX=y CONFIG_SPI_FSL_DSPI=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_MC9S08DZ60=y CONFIG_GPIO_PCA953X=y CONFIG_GPIO_STMPE=y +CONFIG_GPIO_74X164=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_IMX=y CONFIG_POWER_RESET_SYSCON=y @@ -226,15 +230,21 @@ CONFIG_REGULATOR_MC13892=y CONFIG_REGULATOR_PFUZE100=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_RC_DEVICES=y CONFIG_IR_GPIO_CIR=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_MUX=y CONFIG_SOC_CAMERA=y CONFIG_V4L_MEM2MEM_DRIVERS=y -CONFIG_VIDEO_CODA=y +CONFIG_VIDEO_CODA=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_ADV7180=m +CONFIG_VIDEO_OV5640=m CONFIG_SOC_CAMERA_OV2640=y CONFIG_IMX_IPUV3_CORE=y CONFIG_DRM=y @@ -344,6 +354,9 @@ CONFIG_FSL_EDMA=y CONFIG_IMX_SDMA=y CONFIG_MXS_DMA=y CONFIG_STAGING=y +CONFIG_STAGING_MEDIA=y +CONFIG_VIDEO_IMX_MEDIA=y +CONFIG_COMMON_CLK_PWM=y CONFIG_IIO=y CONFIG_IMX7D_ADC=y CONFIG_VF610_ADC=y diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index c8378da71913..8c3c99cd6de9 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -81,12 +81,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 1331f6dc456a..f907869e0ddc 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig @@ -112,6 +112,9 @@ CONFIG_IP_NF_ARP_MANGLE=y CONFIG_IP6_NF_IPTABLES=m CONFIG_IP_SCTP=y CONFIG_VLAN_8021Q=y +CONFIG_CAN=m +CONFIG_CAN_C_CAN=m +CONFIG_CAN_C_CAN_PLATFORM=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -156,6 +159,8 @@ CONFIG_POWER_RESET_KEYSTONE=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_DAVINCI_WATCHDOG=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=y @@ -164,6 +169,8 @@ CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y CONFIG_NOP_USB_XCEIV=y CONFIG_KEYSTONE_USB_PHY=y +CONFIG_MMC=y +CONFIG_MMC_OMAP_HS=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y @@ -174,12 +181,18 @@ CONFIG_LEDS_TRIGGER_BACKLIGHT=y CONFIG_LEDS_TRIGGER_GPIO=y CONFIG_DMADEVICES=y CONFIG_TI_EDMA=y +CONFIG_MAILBOX=y +CONFIG_TI_MESSAGE_MANAGER=y CONFIG_SOC_TI=y CONFIG_KEYSTONE_NAVIGATOR_QMSS=y CONFIG_KEYSTONE_NAVIGATOR_DMA=y +CONFIG_TI_SCI_PM_DOMAINS=y CONFIG_MEMORY=y CONFIG_TI_AEMIF=y CONFIG_KEYSTONE_IRQ=y +CONFIG_RESET_TI_SCI=m +CONFIG_RESET_TI_SYSCON=m +CONFIG_TI_SCI_PROTOCOL=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_FANOTIFY=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 4d19c1b4b8e7..0cacdbf84a71 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -104,13 +104,11 @@ CONFIG_ARCH_TEGRA_2x_SOC=y CONFIG_ARCH_TEGRA_3x_SOC=y CONFIG_ARCH_TEGRA_114_SOC=y CONFIG_ARCH_TEGRA_124_SOC=y -CONFIG_TEGRA_EMC_SCALING_ENABLE=y CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_U8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_ARCH_VEXPRESS=y -CONFIG_ARCH_VEXPRESS_CA9X4=y CONFIG_ARCH_VEXPRESS_TC2_PM=y CONFIG_ARCH_WM8850=y CONFIG_ARCH_ZYNQ=y @@ -270,6 +268,7 @@ CONFIG_ICPLUS_PHY=y CONFIG_REALTEK_PHY=y CONFIG_MICREL_PHY=y CONFIG_FIXED_PHY=y +CONFIG_ROCKCHIP_PHY=y CONFIG_USB_PEGASUS=y CONFIG_USB_RTL8152=m CONFIG_USB_USBNET=y @@ -330,6 +329,7 @@ CONFIG_SERIAL_IMX_CONSOLE=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=20 CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SERIAL_VT8500=y @@ -455,6 +455,7 @@ CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_INA2XX=m CONFIG_CPU_THERMAL=y +CONFIG_BRCMSTB_THERMAL=m CONFIG_ROCKCHIP_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_ARMADA_THERMAL=y @@ -584,6 +585,7 @@ CONFIG_VIDEO_ADV7180=m CONFIG_VIDEO_ML86V7667=m CONFIG_DRM=y CONFIG_DRM_I2C_ADV7511=m +CONFIG_DRM_I2C_ADV7511_AUDIO=y # CONFIG_DRM_I2C_CH7006 is not set # CONFIG_DRM_I2C_SIL164 is not set CONFIG_DRM_DUMB_VGA_DAC=m @@ -603,7 +605,6 @@ CONFIG_ROCKCHIP_DW_MIPI_DSI=y CONFIG_ROCKCHIP_INNO_HDMI=y CONFIG_DRM_ATMEL_HLCDC=m CONFIG_DRM_RCAR_DU=m -CONFIG_DRM_RCAR_HDMI=y CONFIG_DRM_RCAR_LVDS=y CONFIG_DRM_SUN4I=m CONFIG_DRM_TEGRA=y @@ -650,9 +651,11 @@ CONFIG_SND_SOC_SMDK_WM8994_PCM=m CONFIG_SND_SOC_SNOW=m CONFIG_SND_SOC_SH4_FSI=m CONFIG_SND_SOC_RCAR=m -CONFIG_SND_SOC_RSRC_CARD=m +CONFIG_SND_SIMPLE_SCU_CARD=m CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SOC_TEGRA=m +CONFIG_SND_SOC_TEGRA20_I2S=m +CONFIG_SND_SOC_TEGRA30_I2S=m CONFIG_SND_SOC_TEGRA_RT5640=m CONFIG_SND_SOC_TEGRA_WM8753=m CONFIG_SND_SOC_TEGRA_WM8903=m @@ -695,7 +698,6 @@ CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_AB8500_USB=y CONFIG_KEYSTONE_USB_PHY=y -CONFIG_OMAP_USB3=y CONFIG_USB_GPIO_VBUS=y CONFIG_USB_ISP1301=y CONFIG_USB_MSM_OTG=m @@ -711,7 +713,7 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y CONFIG_MMC_SDHCI_OF_AT91=y -CONFIG_MMC_SDHCI_OF_ESDHC=m +CONFIG_MMC_SDHCI_OF_ESDHC=y CONFIG_MMC_SDHCI_ESDHC_IMX=y CONFIG_MMC_SDHCI_DOVE=y CONFIG_MMC_SDHCI_TEGRA=y @@ -728,7 +730,6 @@ CONFIG_MMC_SDHCI_MSM=y CONFIG_MMC_MVSDIO=y CONFIG_MMC_SDHI=y CONFIG_MMC_DW=y -CONFIG_MMC_DW_IDMAC=y CONFIG_MMC_DW_PLTFM=y CONFIG_MMC_DW_EXYNOS=y CONFIG_MMC_DW_ROCKCHIP=y @@ -825,7 +826,6 @@ CONFIG_BCMA_DRIVER_GPIO=y CONFIG_QCOM_GSBI=y CONFIG_QCOM_PM=y CONFIG_QCOM_SMEM=y -CONFIG_QCOM_SMD=y CONFIG_QCOM_SMD_RPM=y CONFIG_QCOM_SMP2P=y CONFIG_QCOM_SMSM=y @@ -837,7 +837,6 @@ CONFIG_CHROME_PLATFORMS=y CONFIG_STAGING_BOARD=y CONFIG_CROS_EC_CHARDEV=m CONFIG_COMMON_CLK_MAX77686=y -CONFIG_COMMON_CLK_MAX77802=m CONFIG_COMMON_CLK_RK808=m CONFIG_COMMON_CLK_S2MPS11=m CONFIG_APQ_MMCC_8084=y @@ -933,7 +932,6 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_LOCKUP_DETECTOR=y -CONFIG_CRYPTO_DEV_TEGRA_AES=y CONFIG_CPUFREQ_DT=y CONFIG_KEYSTONE_IRQ=y CONFIG_HW_RANDOM=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index a120ae816260..7b97200c1d64 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -170,6 +170,7 @@ CONFIG_TI_CPTS=y # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_AT803X_PHY=y CONFIG_DP83848_PHY=y +CONFIG_DP83867_PHY=y CONFIG_MICREL_PHY=y CONFIG_SMSC_PHY=y CONFIG_PPP=m @@ -250,6 +251,7 @@ CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_PCA953X=m CONFIG_GPIO_PCF857X=y +CONFIG_GPIO_LP87565=y CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TWL4030=y CONFIG_W1=m @@ -284,6 +286,7 @@ CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_PALMAS=y CONFIG_MFD_TPS65217=y CONFIG_MFD_TI_LP873X=y +CONFIG_MFD_TI_LP87565=y CONFIG_MFD_TPS65218=y CONFIG_MFD_TPS65910=y CONFIG_TWL6040_CORE=y @@ -292,6 +295,7 @@ CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_LM363X=m CONFIG_REGULATOR_LP872X=y CONFIG_REGULATOR_LP873X=y +CONFIG_REGULATOR_LP87565=y CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=y CONFIG_REGULATOR_TI_ABB=y @@ -304,7 +308,7 @@ CONFIG_REGULATOR_TPS65910=y CONFIG_REGULATOR_TWL4030=y CONFIG_MEDIA_SUPPORT=m CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=m CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_LIRC=m diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 64e3a2a8cede..d5e1370ec303 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -471,7 +471,7 @@ CONFIG_LCD_PLATFORM=m CONFIG_LCD_TOSA=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_TOSA=m -CONFIG_FRAMEBUFFER_CONSOLE=m +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y CONFIG_SOUND=m diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index b02039c712c3..879159e4ab58 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -199,7 +199,6 @@ CONFIG_QCOM_WCNSS_PIL=y CONFIG_QCOM_GSBI=y CONFIG_QCOM_PM=y CONFIG_QCOM_SMEM=y -CONFIG_QCOM_SMD=y CONFIG_QCOM_SMD_RPM=y CONFIG_QCOM_SMP2P=y CONFIG_QCOM_SMSM=y diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 3c66a422fb4d..7b4fc0143148 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -27,6 +27,7 @@ CONFIG_ARCH_SH73A0=y CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_ERRATA_754322=y CONFIG_PCI=y +CONFIG_PCI_MSI=y CONFIG_PCI_RCAR_GEN2=y CONFIG_PCIE_RCAR=y CONFIG_SMP=y @@ -83,14 +84,14 @@ CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_MICREL is not set # CONFIG_NET_VENDOR_NATSEMI is not set CONFIG_SH_ETH=y +CONFIG_RAVB=y # CONFIG_NET_VENDOR_SEEQ is not set CONFIG_SMSC911X=y # CONFIG_NET_VENDOR_STMICRO is not set # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_SMSC_PHY=y CONFIG_MICREL_PHY=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_SMSC_PHY=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set @@ -105,6 +106,7 @@ CONFIG_SERIAL_8250_EM=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=20 CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_DEMUX_PINCTRL=y @@ -121,9 +123,9 @@ CONFIG_SPI_SH_HSPI=y CONFIG_GPIO_EM=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_PCF857X=y -CONFIG_POWER_SUPPLY=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_RMOBILE=y +CONFIG_POWER_SUPPLY=y # CONFIG_HWMON is not set CONFIG_THERMAL=y CONFIG_CPU_THERMAL=y @@ -153,10 +155,11 @@ CONFIG_VIDEO_ADV7180=y CONFIG_VIDEO_ADV7604=y CONFIG_VIDEO_ML86V7667=y CONFIG_DRM=y -CONFIG_DRM_I2C_ADV7511=y CONFIG_DRM_RCAR_DU=y -CONFIG_DRM_RCAR_HDMI=y CONFIG_DRM_RCAR_LVDS=y +CONFIG_DRM_DUMB_VGA_DAC=y +CONFIG_DRM_I2C_ADV7511=y +CONFIG_DRM_I2C_ADV7511_AUDIO=y CONFIG_FB_SH_MOBILE_LCDC=y CONFIG_FB_SH_MOBILE_MERAM=y # CONFIG_LCD_CLASS_DEVICE is not set @@ -169,12 +172,12 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_SOC_SH4_FSI=y CONFIG_SND_SOC_RCAR=y -CONFIG_SND_SOC_RSRC_CARD=y CONFIG_SND_SOC_AK4642=y CONFIG_SND_SOC_WM8978=y +CONFIG_SND_SIMPLE_SCU_CARD=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_RCAR=y +CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_R8A66597_HCD=y @@ -190,6 +193,7 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RS5C372=y +CONFIG_RTC_DRV_BQ32K=y CONFIG_RTC_DRV_S35390A=y CONFIG_RTC_DRV_RX8581=y CONFIG_RTC_DRV_DA9063=y diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 0ec1d1ec130f..5caaf971fb50 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -1,4 +1,3 @@ -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_CGROUPS=y @@ -56,7 +55,6 @@ CONFIG_STMMAC_ETH=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_SUN4I_LRADC=y # CONFIG_INPUT_MOUSE is not set @@ -71,7 +69,6 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=8 CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set -CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MV64XXX=y CONFIG_I2C_SUN6I_P2WI=y @@ -80,14 +77,14 @@ CONFIG_SPI_SUN4I=y CONFIG_SPI_SUN6I=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY=y +CONFIG_CHARGER_AXP20X=y +CONFIG_BATTERY_AXP20X=y CONFIG_AXP20X_POWER=y CONFIG_THERMAL=y -CONFIG_THERMAL_OF=y CONFIG_CPU_THERMAL=y CONFIG_WATCHDOG=y CONFIG_SUNXI_WATCHDOG=y CONFIG_MFD_AC100=y -CONFIG_MFD_AXP20X=y CONFIG_MFD_AXP20X_I2C=y CONFIG_MFD_AXP20X_RSB=y CONFIG_REGULATOR=y @@ -95,16 +92,13 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y CONFIG_RC_DEVICES=y CONFIG_IR_SUNXI=y CONFIG_DRM=y -CONFIG_DRM_DUMB_VGA_DAC=y CONFIG_DRM_SUN4I=y -CONFIG_FB=y +CONFIG_DRM_DUMB_VGA_DAC=y CONFIG_FB_SIMPLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y @@ -130,12 +124,13 @@ CONFIG_RTC_CLASS=y # CONFIG_RTC_INTF_SYSFS is not set # CONFIG_RTC_INTF_PROC is not set CONFIG_RTC_DRV_AC100=y -CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y CONFIG_DMADEVICES=y CONFIG_DMA_SUN6I=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXTCON=y +CONFIG_IIO=y +CONFIG_AXP20X_ADC=y CONFIG_PWM=y CONFIG_PWM_SUN4I=y CONFIG_PHY_SUN4I_USB=y diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig index f0efc854b5a2..6678f2929356 100644 --- a/arch/arm/configs/tegra_defconfig +++ b/arch/arm/configs/tegra_defconfig @@ -121,7 +121,6 @@ CONFIG_TOUCHSCREEN_WM97XX=y CONFIG_TOUCHSCREEN_STMPE=y CONFIG_INPUT_MISC=y # CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y @@ -202,6 +201,8 @@ CONFIG_SND_HDA_CODEC_HDMI=y # CONFIG_SND_USB is not set CONFIG_SND_SOC=y CONFIG_SND_SOC_TEGRA=y +CONFIG_SND_SOC_TEGRA20_I2S=y +CONFIG_SND_SOC_TEGRA30_I2S=y CONFIG_SND_SOC_TEGRA_RT5640=y CONFIG_SND_SOC_TEGRA_WM8753=y CONFIG_SND_SOC_TEGRA_WM8903=y @@ -218,6 +219,9 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_ACM=y CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_GADGET=y CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=16 CONFIG_MMC_SDHCI=y @@ -247,8 +251,6 @@ CONFIG_RTC_DRV_TEGRA=y CONFIG_DMADEVICES=y CONFIG_TEGRA20_APB_DMA=y CONFIG_STAGING=y -CONFIG_SENSORS_ISL29018=y -CONFIG_SENSORS_ISL29028=y CONFIG_MFD_NVEC=y CONFIG_KEYBOARD_NVEC=y CONFIG_SERIO_NVEC_PS2=y @@ -263,6 +265,8 @@ CONFIG_ARCH_TEGRA_124_SOC=y CONFIG_MEMORY=y CONFIG_IIO=y CONFIG_MPU3050_I2C=y +CONFIG_SENSORS_ISL29018=y +CONFIG_SENSORS_ISL29028=y CONFIG_AK8975=y CONFIG_PWM=y CONFIG_PWM_TEGRA=y @@ -288,13 +292,11 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_SLAB=y CONFIG_DEBUG_VM=y CONFIG_DETECT_HUNG_TASK=y CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_SG=y diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig index 0fa0ed577b15..edae1c58fe80 100644 --- a/arch/arm/configs/vexpress_defconfig +++ b/arch/arm/configs/vexpress_defconfig @@ -19,7 +19,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_DEADLINE is not set # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_VEXPRESS=y -CONFIG_ARCH_VEXPRESS_CA9X4=y CONFIG_ARCH_VEXPRESS_DCSCB=y CONFIG_ARCH_VEXPRESS_TC2_PM=y # CONFIG_SWP_EMULATE is not set diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig index 44d4fa57ba0a..070e5074f1ee 100644 --- a/arch/arm/configs/viper_defconfig +++ b/arch/arm/configs/viper_defconfig @@ -113,7 +113,7 @@ CONFIG_FB_PXA_PARAMETERS=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_PWM=m # CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=m +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig index 8d4c0c926c34..09e7050d5653 100644 --- a/arch/arm/configs/zeus_defconfig +++ b/arch/arm/configs/zeus_defconfig @@ -112,7 +112,7 @@ CONFIG_FB_PXA=m CONFIG_FB_PXA_PARAMETERS=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=m +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig index b9adedcc5b2e..b8e69fe282b8 100644 --- a/arch/arm/crypto/Kconfig +++ b/arch/arm/crypto/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARM_CRYPTO bool "ARM Accelerated Cryptographic Algorithms" @@ -94,14 +95,15 @@ config CRYPTO_AES_ARM_CE ARMv8 Crypto Extensions config CRYPTO_GHASH_ARM_CE - tristate "PMULL-accelerated GHASH using ARMv8 Crypto Extensions" + tristate "PMULL-accelerated GHASH using NEON/ARMv8 Crypto Extensions" depends on KERNEL_MODE_NEON select CRYPTO_HASH select CRYPTO_CRYPTD help Use an implementation of GHASH (used by the GCM AEAD chaining mode) that uses the 64x64 to 128 bit polynomial multiplication (vmull.p64) - that is part of the ARMv8 Crypto Extensions + that is part of the ARMv8 Crypto Extensions, or a slower variant that + uses the vmull.p8 instruction that is part of the basic NEON ISA. config CRYPTO_CRCT10DIF_ARM_CE tristate "CRCT10DIF digest algorithm using PMULL instructions" diff --git a/arch/arm/crypto/Makefile b/arch/arm/crypto/Makefile index f2215fbeed13..30ef8e291271 100644 --- a/arch/arm/crypto/Makefile +++ b/arch/arm/crypto/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # diff --git a/arch/arm/crypto/aes-ce-glue.c b/arch/arm/crypto/aes-ce-glue.c index 0f966a8ca1ce..d0a9cec73707 100644 --- a/arch/arm/crypto/aes-ce-glue.c +++ b/arch/arm/crypto/aes-ce-glue.c @@ -285,9 +285,7 @@ static int ctr_encrypt(struct skcipher_request *req) ce_aes_ctr_encrypt(tail, NULL, (u8 *)ctx->key_enc, num_rounds(ctx), blocks, walk.iv); - if (tdst != tsrc) - memcpy(tdst, tsrc, nbytes); - crypto_xor(tdst, tail, nbytes); + crypto_xor_cpy(tdst, tsrc, tail, nbytes); err = skcipher_walk_done(&walk, 0); } kernel_neon_end(); diff --git a/arch/arm/crypto/aes-cipher-core.S b/arch/arm/crypto/aes-cipher-core.S index c817a86c4ca8..54b384084637 100644 --- a/arch/arm/crypto/aes-cipher-core.S +++ b/arch/arm/crypto/aes-cipher-core.S @@ -10,6 +10,7 @@ */ #include +#include .text .align 5 @@ -32,19 +33,19 @@ .endif .endm - .macro __load, out, in, idx + .macro __load, out, in, idx, sz, op .if __LINUX_ARM_ARCH__ < 7 && \idx > 0 - ldr \out, [ttab, \in, lsr #(8 * \idx) - 2] + ldr\op \out, [ttab, \in, lsr #(8 * \idx) - \sz] .else - ldr \out, [ttab, \in, lsl #2] + ldr\op \out, [ttab, \in, lsl #\sz] .endif .endm - .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc + .macro __hround, out0, out1, in0, in1, in2, in3, t3, t4, enc, sz, op __select \out0, \in0, 0 __select t0, \in1, 1 - __load \out0, \out0, 0 - __load t0, t0, 1 + __load \out0, \out0, 0, \sz, \op + __load t0, t0, 1, \sz, \op .if \enc __select \out1, \in1, 0 @@ -53,10 +54,10 @@ __select \out1, \in3, 0 __select t1, \in0, 1 .endif - __load \out1, \out1, 0 + __load \out1, \out1, 0, \sz, \op __select t2, \in2, 2 - __load t1, t1, 1 - __load t2, t2, 2 + __load t1, t1, 1, \sz, \op + __load t2, t2, 2, \sz, \op eor \out0, \out0, t0, ror #24 @@ -68,9 +69,9 @@ __select \t3, \in1, 2 __select \t4, \in2, 3 .endif - __load \t3, \t3, 2 - __load t0, t0, 3 - __load \t4, \t4, 3 + __load \t3, \t3, 2, \sz, \op + __load t0, t0, 3, \sz, \op + __load \t4, \t4, 3, \sz, \op eor \out1, \out1, t1, ror #24 eor \out0, \out0, t2, ror #16 @@ -82,14 +83,14 @@ eor \out1, \out1, t2 .endm - .macro fround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1 - __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1 + .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op + __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op .endm - .macro iround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0 - __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0 + .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op + __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op .endm .macro __rev, out, in @@ -114,7 +115,7 @@ .endif .endm - .macro do_crypt, round, ttab, ltab + .macro do_crypt, round, ttab, ltab, bsz push {r3-r11, lr} ldr r4, [in] @@ -146,9 +147,12 @@ 1: subs rounds, rounds, #4 \round r8, r9, r10, r11, r4, r5, r6, r7 - __adrl ttab, \ltab, ls + bls 2f \round r4, r5, r6, r7, r8, r9, r10, r11 - bhi 0b + b 0b + +2: __adrl ttab, \ltab + \round r4, r5, r6, r7, r8, r9, r10, r11, \bsz, b #ifdef CONFIG_CPU_BIG_ENDIAN __rev r4, r4 @@ -170,10 +174,48 @@ .ltorg .endm + .align L1_CACHE_SHIFT + .type __aes_arm_inverse_sbox, %object +__aes_arm_inverse_sbox: + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + .size __aes_arm_inverse_sbox, . - __aes_arm_inverse_sbox + ENTRY(__aes_arm_encrypt) - do_crypt fround, crypto_ft_tab, crypto_fl_tab + do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2 ENDPROC(__aes_arm_encrypt) + .align 5 ENTRY(__aes_arm_decrypt) - do_crypt iround, crypto_it_tab, crypto_il_tab + do_crypt iround, crypto_it_tab, __aes_arm_inverse_sbox, 0 ENDPROC(__aes_arm_decrypt) diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c index c76377961444..18768f330449 100644 --- a/arch/arm/crypto/aes-neonbs-glue.c +++ b/arch/arm/crypto/aes-neonbs-glue.c @@ -221,9 +221,8 @@ static int ctr_encrypt(struct skcipher_request *req) u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; - if (dst != src) - memcpy(dst, src, walk.total % AES_BLOCK_SIZE); - crypto_xor(dst, final, walk.total % AES_BLOCK_SIZE); + crypto_xor_cpy(dst, src, final, + walk.total % AES_BLOCK_SIZE); err = skcipher_walk_done(&walk, 0); break; diff --git a/arch/arm/crypto/ghash-ce-core.S b/arch/arm/crypto/ghash-ce-core.S index f6ab8bcc9efe..2f78c10b1881 100644 --- a/arch/arm/crypto/ghash-ce-core.S +++ b/arch/arm/crypto/ghash-ce-core.S @@ -1,7 +1,7 @@ /* - * Accelerated GHASH implementation with ARMv8 vmull.p64 instructions. + * Accelerated GHASH implementation with NEON/ARMv8 vmull.p8/64 instructions. * - * Copyright (C) 2015 Linaro Ltd. + * Copyright (C) 2015 - 2017 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -12,40 +12,162 @@ #include SHASH .req q0 - SHASH2 .req q1 - T1 .req q2 - T2 .req q3 - MASK .req q4 - XL .req q5 - XM .req q6 - XH .req q7 - IN1 .req q7 + T1 .req q1 + XL .req q2 + XM .req q3 + XH .req q4 + IN1 .req q4 SHASH_L .req d0 SHASH_H .req d1 - SHASH2_L .req d2 - T1_L .req d4 - MASK_L .req d8 - XL_L .req d10 - XL_H .req d11 - XM_L .req d12 - XM_H .req d13 - XH_L .req d14 + T1_L .req d2 + T1_H .req d3 + XL_L .req d4 + XL_H .req d5 + XM_L .req d6 + XM_H .req d7 + XH_L .req d8 + + t0l .req d10 + t0h .req d11 + t1l .req d12 + t1h .req d13 + t2l .req d14 + t2h .req d15 + t3l .req d16 + t3h .req d17 + t4l .req d18 + t4h .req d19 + + t0q .req q5 + t1q .req q6 + t2q .req q7 + t3q .req q8 + t4q .req q9 + T2 .req q9 + + s1l .req d20 + s1h .req d21 + s2l .req d22 + s2h .req d23 + s3l .req d24 + s3h .req d25 + s4l .req d26 + s4h .req d27 + + MASK .req d28 + SHASH2_p8 .req d28 + + k16 .req d29 + k32 .req d30 + k48 .req d31 + SHASH2_p64 .req d31 .text .fpu crypto-neon-fp-armv8 + .macro __pmull_p64, rd, rn, rm, b1, b2, b3, b4 + vmull.p64 \rd, \rn, \rm + .endm + /* - * void pmull_ghash_update(int blocks, u64 dg[], const char *src, - * struct ghash_key const *k, const char *head) + * This implementation of 64x64 -> 128 bit polynomial multiplication + * using vmull.p8 instructions (8x8 -> 16) is taken from the paper + * "Fast Software Polynomial Multiplication on ARM Processors Using + * the NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and + * Ricardo Dahab (https://hal.inria.fr/hal-01506572) + * + * It has been slightly tweaked for in-order performance, and to allow + * 'rq' to overlap with 'ad' or 'bd'. */ -ENTRY(pmull_ghash_update) - vld1.64 {SHASH}, [r3] + .macro __pmull_p8, rq, ad, bd, b1=t4l, b2=t3l, b3=t4l, b4=t3l + vext.8 t0l, \ad, \ad, #1 @ A1 + .ifc \b1, t4l + vext.8 t4l, \bd, \bd, #1 @ B1 + .endif + vmull.p8 t0q, t0l, \bd @ F = A1*B + vext.8 t1l, \ad, \ad, #2 @ A2 + vmull.p8 t4q, \ad, \b1 @ E = A*B1 + .ifc \b2, t3l + vext.8 t3l, \bd, \bd, #2 @ B2 + .endif + vmull.p8 t1q, t1l, \bd @ H = A2*B + vext.8 t2l, \ad, \ad, #3 @ A3 + vmull.p8 t3q, \ad, \b2 @ G = A*B2 + veor t0q, t0q, t4q @ L = E + F + .ifc \b3, t4l + vext.8 t4l, \bd, \bd, #3 @ B3 + .endif + vmull.p8 t2q, t2l, \bd @ J = A3*B + veor t0l, t0l, t0h @ t0 = (L) (P0 + P1) << 8 + veor t1q, t1q, t3q @ M = G + H + .ifc \b4, t3l + vext.8 t3l, \bd, \bd, #4 @ B4 + .endif + vmull.p8 t4q, \ad, \b3 @ I = A*B3 + veor t1l, t1l, t1h @ t1 = (M) (P2 + P3) << 16 + vmull.p8 t3q, \ad, \b4 @ K = A*B4 + vand t0h, t0h, k48 + vand t1h, t1h, k32 + veor t2q, t2q, t4q @ N = I + J + veor t0l, t0l, t0h + veor t1l, t1l, t1h + veor t2l, t2l, t2h @ t2 = (N) (P4 + P5) << 24 + vand t2h, t2h, k16 + veor t3l, t3l, t3h @ t3 = (K) (P6 + P7) << 32 + vmov.i64 t3h, #0 + vext.8 t0q, t0q, t0q, #15 + veor t2l, t2l, t2h + vext.8 t1q, t1q, t1q, #14 + vmull.p8 \rq, \ad, \bd @ D = A*B + vext.8 t2q, t2q, t2q, #13 + vext.8 t3q, t3q, t3q, #12 + veor t0q, t0q, t1q + veor t2q, t2q, t3q + veor \rq, \rq, t0q + veor \rq, \rq, t2q + .endm + + // + // PMULL (64x64->128) based reduction for CPUs that can do + // it in a single instruction. + // + .macro __pmull_reduce_p64 + vmull.p64 T1, XL_L, MASK + + veor XH_L, XH_L, XM_H + vext.8 T1, T1, T1, #8 + veor XL_H, XL_H, XM_L + veor T1, T1, XL + + vmull.p64 XL, T1_H, MASK + .endm + + // + // Alternative reduction for CPUs that lack support for the + // 64x64->128 PMULL instruction + // + .macro __pmull_reduce_p8 + veor XL_H, XL_H, XM_L + veor XH_L, XH_L, XM_H + + vshl.i64 T1, XL, #57 + vshl.i64 T2, XL, #62 + veor T1, T1, T2 + vshl.i64 T2, XL, #63 + veor T1, T1, T2 + veor XL_H, XL_H, T1_L + veor XH_L, XH_L, T1_H + + vshr.u64 T1, XL, #1 + veor XH, XH, XL + veor XL, XL, T1 + vshr.u64 T1, T1, #6 + vshr.u64 XL, XL, #1 + .endm + + .macro ghash_update, pn vld1.64 {XL}, [r1] - vmov.i8 MASK, #0xe1 - vext.8 SHASH2, SHASH, SHASH, #8 - vshl.u64 MASK, MASK, #57 - veor SHASH2, SHASH2, SHASH /* do the head block first, if supplied */ ldr ip, [sp] @@ -62,33 +184,59 @@ ENTRY(pmull_ghash_update) #ifndef CONFIG_CPU_BIG_ENDIAN vrev64.8 T1, T1 #endif - vext.8 T2, XL, XL, #8 vext.8 IN1, T1, T1, #8 - veor T1, T1, T2 + veor T1_L, T1_L, XL_H veor XL, XL, IN1 - vmull.p64 XH, SHASH_H, XL_H @ a1 * b1 + __pmull_\pn XH, XL_H, SHASH_H, s1h, s2h, s3h, s4h @ a1 * b1 veor T1, T1, XL - vmull.p64 XL, SHASH_L, XL_L @ a0 * b0 - vmull.p64 XM, SHASH2_L, T1_L @ (a1 + a0)(b1 + b0) + __pmull_\pn XL, XL_L, SHASH_L, s1l, s2l, s3l, s4l @ a0 * b0 + __pmull_\pn XM, T1_L, SHASH2_\pn @ (a1+a0)(b1+b0) - vext.8 T1, XL, XH, #8 - veor T2, XL, XH + veor T1, XL, XH veor XM, XM, T1 - veor XM, XM, T2 - vmull.p64 T2, XL_L, MASK_L - vmov XH_L, XM_H - vmov XM_H, XL_L + __pmull_reduce_\pn - veor XL, XM, T2 - vext.8 T2, XL, XL, #8 - vmull.p64 XL, XL_L, MASK_L - veor T2, T2, XH - veor XL, XL, T2 + veor T1, T1, XH + veor XL, XL, T1 bne 0b vst1.64 {XL}, [r1] bx lr -ENDPROC(pmull_ghash_update) + .endm + + /* + * void pmull_ghash_update(int blocks, u64 dg[], const char *src, + * struct ghash_key const *k, const char *head) + */ +ENTRY(pmull_ghash_update_p64) + vld1.64 {SHASH}, [r3] + veor SHASH2_p64, SHASH_L, SHASH_H + + vmov.i8 MASK, #0xe1 + vshl.u64 MASK, MASK, #57 + + ghash_update p64 +ENDPROC(pmull_ghash_update_p64) + +ENTRY(pmull_ghash_update_p8) + vld1.64 {SHASH}, [r3] + veor SHASH2_p8, SHASH_L, SHASH_H + + vext.8 s1l, SHASH_L, SHASH_L, #1 + vext.8 s2l, SHASH_L, SHASH_L, #2 + vext.8 s3l, SHASH_L, SHASH_L, #3 + vext.8 s4l, SHASH_L, SHASH_L, #4 + vext.8 s1h, SHASH_H, SHASH_H, #1 + vext.8 s2h, SHASH_H, SHASH_H, #2 + vext.8 s3h, SHASH_H, SHASH_H, #3 + vext.8 s4h, SHASH_H, SHASH_H, #4 + + vmov.i64 k16, #0xffff + vmov.i64 k32, #0xffffffff + vmov.i64 k48, #0xffffffffffff + + ghash_update p8 +ENDPROC(pmull_ghash_update_p8) diff --git a/arch/arm/crypto/ghash-ce-glue.c b/arch/arm/crypto/ghash-ce-glue.c index 6bac8bea9f1e..d9bb52cae2ac 100644 --- a/arch/arm/crypto/ghash-ce-glue.c +++ b/arch/arm/crypto/ghash-ce-glue.c @@ -22,6 +22,7 @@ MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("ghash"); #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 @@ -41,8 +42,17 @@ struct ghash_async_ctx { struct cryptd_ahash *cryptd_tfm; }; -asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src, - struct ghash_key const *k, const char *head); +asmlinkage void pmull_ghash_update_p64(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +asmlinkage void pmull_ghash_update_p8(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +static void (*pmull_ghash_update)(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); static int ghash_init(struct shash_desc *desc) { @@ -312,6 +322,14 @@ static int __init ghash_ce_mod_init(void) { int err; + if (!(elf_hwcap & HWCAP_NEON)) + return -ENODEV; + + if (elf_hwcap2 & HWCAP2_PMULL) + pmull_ghash_update = pmull_ghash_update_p64; + else + pmull_ghash_update = pmull_ghash_update_p8; + err = crypto_register_shash(&ghash_alg); if (err) return err; @@ -332,5 +350,5 @@ static void __exit ghash_ce_mod_exit(void) crypto_unregister_shash(&ghash_alg); } -module_cpu_feature_match(PMULL, ghash_ce_mod_init); +module_init(ghash_ce_mod_init); module_exit(ghash_ce_mod_exit); diff --git a/arch/arm/crypto/sha1.h b/arch/arm/crypto/sha1.h index ffd8bd08b1a7..758db3e9ff0a 100644 --- a/arch/arm/crypto/sha1.h +++ b/arch/arm/crypto/sha1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_ARM_CRYPTO_SHA1_H #define ASM_ARM_CRYPTO_SHA1_H diff --git a/arch/arm/crypto/sha256_glue.h b/arch/arm/crypto/sha256_glue.h index 7cf0bf786ada..9f0d578bab5f 100644 --- a/arch/arm/crypto/sha256_glue.h +++ b/arch/arm/crypto/sha256_glue.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRYPTO_SHA256_GLUE_H #define _CRYPTO_SHA256_GLUE_H diff --git a/arch/arm/crypto/sha512.h b/arch/arm/crypto/sha512.h index a75d9a82988a..e14572be76d1 100644 --- a/arch/arm/crypto/sha512.h +++ b/arch/arm/crypto/sha512.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ int sha512_arm_update(struct shash_desc *desc, const u8 *data, unsigned int len); diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 721ab5ecfb9b..0f2c8a2a8131 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -20,7 +20,6 @@ generic-y += simd.h generic-y += sizes.h generic-y += timex.h generic-y += trace_clock.h -generic-y += unaligned.h generated-y += mach-types.h generated-y += unistd-nr.h diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h index 27475904e096..eee269321923 100644 --- a/arch/arm/include/asm/arch_gicv3.h +++ b/arch/arm/include/asm/arch_gicv3.h @@ -275,6 +275,12 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr) #define gicr_read_pendbaser(c) __gic_readq_nonatomic(c) #define gicr_write_pendbaser(v, c) __gic_writeq_nonatomic(v, c) +/* + * GICR_xLPIR - only the lower bits are significant + */ +#define gic_read_lpir(c) readl_relaxed(c) +#define gic_write_lpir(v, c) writel_relaxed(lower_32_bits(v), c) + /* * GITS_TYPER is an ID register and doesn't need atomicity. */ @@ -291,5 +297,33 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr) */ #define gits_write_cwriter(v, c) __gic_writeq_nonatomic(v, c) +/* + * GITS_VPROPBASER - hi and lo bits may be accessed independently. + */ +#define gits_write_vpropbaser(v, c) __gic_writeq_nonatomic(v, c) + +/* + * GITS_VPENDBASER - the Valid bit must be cleared before changing + * anything else. + */ +static inline void gits_write_vpendbaser(u64 val, void * __iomem addr) +{ + u32 tmp; + + tmp = readl_relaxed(addr + 4); + if (tmp & (GICR_VPENDBASER_Valid >> 32)) { + tmp &= ~(GICR_VPENDBASER_Valid >> 32); + writel_relaxed(tmp, addr + 4); + } + + /* + * Use the fact that __gic_writeq_nonatomic writes the second + * half of the 64bit quantity after the first. + */ + __gic_writeq_nonatomic(val, addr); +} + +#define gits_read_vpendbaser(c) __gic_readq_nonatomic(c) + #endif /* !__ASSEMBLY__ */ #endif /* !__ASM_ARCH_GICV3_H */ diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h index d4ebf5679f1f..9327e3a101dc 100644 --- a/arch/arm/include/asm/arch_timer.h +++ b/arch/arm/include/asm/arch_timer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMARM_ARCH_TIMER_H #define __ASMARM_ARCH_TIMER_H diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h index f5d698182d50..40f5c410fd8c 100644 --- a/arch/arm/include/asm/barrier.h +++ b/arch/arm/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_BARRIER_H #define __ASM_BARRIER_H diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index f308c8c40cb9..ce5ee762ed66 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 1995, Russell King. * Various bits and pieces copyrights include: diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h index ec291c350ea3..84ad8dde62d6 100644 --- a/arch/arm/include/asm/bitrev.h +++ b/arch/arm/include/asm/bitrev.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_BITREV_H #define __ASM_BITREV_H diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h index 2244a94ed9c9..237aa52d8733 100644 --- a/arch/arm/include/asm/bug.h +++ b/arch/arm/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMARM_BUG_H #define _ASMARM_BUG_H diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index 75fe66bc02b4..1d65ed3a2755 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/cache.h */ diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h index 01509ae0bbec..e8c30430be33 100644 --- a/arch/arm/include/asm/cachetype.h +++ b/arch/arm/include/asm/cachetype.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_CACHETYPE_H #define __ASM_ARM_CACHETYPE_H diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h index 524692f4acab..20043e0ebb07 100644 --- a/arch/arm/include/asm/checksum.h +++ b/arch/arm/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/checksum.h * diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h index 97882f9bad12..8b701f8e175c 100644 --- a/arch/arm/include/asm/cmpxchg.h +++ b/arch/arm/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_CMPXCHG_H #define __ASM_ARM_CMPXCHG_H diff --git a/arch/arm/include/asm/compiler.h b/arch/arm/include/asm/compiler.h index 29fe85e59439..5e94e67d1083 100644 --- a/arch/arm/include/asm/compiler.h +++ b/arch/arm/include/asm/compiler.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_COMPILER_H #define __ASM_ARM_COMPILER_H diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h index dbdbce1b3a72..4c9fa72b59f5 100644 --- a/arch/arm/include/asm/cp15.h +++ b/arch/arm/include/asm/cp15.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_CP15_H #define __ASM_ARM_CP15_H diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h index baefe1d51517..6b2ff7243b4b 100644 --- a/arch/arm/include/asm/cpuidle.h +++ b/arch/arm/include/asm/cpuidle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_CPUIDLE_H #define __ASM_ARM_CPUIDLE_H diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index b62eaeb147aa..441933311bbf 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_CPUTYPE_H #define __ASM_ARM_CPUTYPE_H diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h index 2381199acb7d..f8500e5d6ea8 100644 --- a/arch/arm/include/asm/cti.h +++ b/arch/arm/include/asm/cti.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMARM_CTI_H #define __ASMARM_CTI_H diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h index e986b7f717c4..4f80b72372b4 100644 --- a/arch/arm/include/asm/delay.h +++ b/arch/arm/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1995-2004 Russell King * diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index 7d919a9b32e5..898e9c78a7e7 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_DIV64 #define __ASM_ARM_DIV64 diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h index 4f8e9e5514b1..d785187a6f8a 100644 --- a/arch/arm/include/asm/dma-contiguous.h +++ b/arch/arm/include/asm/dma-contiguous.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASMARM_DMA_CONTIGUOUS_H #define ASMARM_DMA_CONTIGUOUS_H diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h index c090ec675eac..0722ec6be692 100644 --- a/arch/arm/include/asm/dma-iommu.h +++ b/arch/arm/include/asm/dma-iommu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASMARM_DMA_IOMMU_H #define ASMARM_DMA_IOMMU_H diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 4e0285a66ef8..3ca119997818 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASMARM_DMA_MAPPING_H #define ASMARM_DMA_MAPPING_H diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index bb4fa67da541..a81dda65c576 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_DMA_H #define __ASM_ARM_DMA_H diff --git a/arch/arm/include/asm/ecard.h b/arch/arm/include/asm/ecard.h index eaea14676d57..4befe8d2ae19 100644 --- a/arch/arm/include/asm/ecard.h +++ b/arch/arm/include/asm/ecard.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/ecard.h * diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index f13ae153fb24..8c5ca92a87a9 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMARM_ELF_H #define __ASMARM_ELF_H diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S index 609184f522ee..dfc6bfa43012 100644 --- a/arch/arm/include/asm/entry-macro-multi.S +++ b/arch/arm/include/asm/entry-macro-multi.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h index bf1991263d2d..a7273ad9587a 100644 --- a/arch/arm/include/asm/exception.h +++ b/arch/arm/include/asm/exception.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Annotations for marking C functions as exception handlers. * diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h index d493d0b742a1..6bdfb4a47322 100644 --- a/arch/arm/include/asm/fiq.h +++ b/arch/arm/include/asm/fiq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/fiq.h * diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h index 8f967d1373f6..472c93db5dac 100644 --- a/arch/arm/include/asm/fixmap.h +++ b/arch/arm/include/asm/fixmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FIXMAP_H #define _ASM_FIXMAP_H diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h index 29d3a1524bce..f0c75ddeea23 100644 --- a/arch/arm/include/asm/flat.h +++ b/arch/arm/include/asm/flat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/flat.h -- uClinux flat-format executables */ diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h index f379881d5cc3..9e842ff41768 100644 --- a/arch/arm/include/asm/ftrace.h +++ b/arch/arm/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_FTRACE #define _ASM_ARM_FTRACE diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 6795368ad023..ffebe7b7a5b7 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_FUTEX_H #define _ASM_ARM_FUTEX_H @@ -128,20 +129,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, #endif /* !SMP */ static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - #ifndef CONFIG_SMP preempt_disable(); #endif @@ -172,17 +163,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) preempt_enable(); #endif - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h index 504dcddebfcc..c50e383358c4 100644 --- a/arch/arm/include/asm/gpio.h +++ b/arch/arm/include/asm/gpio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_ARM_GPIO_H #define _ARCH_ARM_GPIO_H diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index 3d7351c844aa..cba23eaa6072 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_HARDIRQ_H #define __ASM_HARDIRQ_H diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 076777ff3daa..e175c2384f28 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/arm/hardware/it8152.h * diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 8979fa3bbf2d..0bbf163d1ed3 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/hardware/sa1111.h * diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 0a0e2d1784c0..b03d3fa2e58d 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HIGHMEM_H #define _ASM_HIGHMEM_H diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h index afcaf8bf971b..e46e4e7bdba3 100644 --- a/arch/arm/include/asm/hw_breakpoint.h +++ b/arch/arm/include/asm/hw_breakpoint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARM_HW_BREAKPOINT_H #define _ARM_HW_BREAKPOINT_H diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h index 9beb92914f4d..cecc13214ef1 100644 --- a/arch/arm/include/asm/hw_irq.h +++ b/arch/arm/include/asm/hw_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Nothing to see here yet */ diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h index 6e183fd269fb..e31d9f1b8549 100644 --- a/arch/arm/include/asm/hwcap.h +++ b/arch/arm/include/asm/hwcap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMARM_HWCAP_H #define __ASMARM_HWCAP_H diff --git a/arch/arm/include/asm/hypervisor.h b/arch/arm/include/asm/hypervisor.h index b90d9e523d6f..df8524365637 100644 --- a/arch/arm/include/asm/hypervisor.h +++ b/arch/arm/include/asm/hypervisor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_HYPERVISOR_H #define _ASM_ARM_HYPERVISOR_H diff --git a/arch/arm/include/asm/ide.h b/arch/arm/include/asm/ide.h index b507ce8e5019..a81e0b0d6747 100644 --- a/arch/arm/include/asm/ide.h +++ b/arch/arm/include/asm/ide.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/ide.h * diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h index bf863edb517d..73ba956e379f 100644 --- a/arch/arm/include/asm/idmap.h +++ b/arch/arm/include/asm/idmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_IDMAP_H #define __ASM_IDMAP_H diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h index e96065da4dae..f20e08ac85ae 100644 --- a/arch/arm/include/asm/insn.h +++ b/arch/arm/include/asm/insn.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_INSN_H #define __ASM_ARM_INSN_H diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index e53638c8ed8a..b6f319606e30 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_IRQ_H #define __ASM_ARM_IRQ_H diff --git a/arch/arm/include/asm/irq_work.h b/arch/arm/include/asm/irq_work.h index 712d03e5973a..8895999834cc 100644 --- a/arch/arm/include/asm/irq_work.h +++ b/arch/arm/include/asm/irq_work.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_IRQ_WORK_H #define __ASM_ARM_IRQ_WORK_H diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h index e6b70d9d084e..aeec7f24eb75 100644 --- a/arch/arm/include/asm/irqflags.h +++ b/arch/arm/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_IRQFLAGS_H #define __ASM_ARM_IRQFLAGS_H diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h index 34f7b6980d21..e12d7d096fc0 100644 --- a/arch/arm/include/asm/jump_label.h +++ b/arch/arm/include/asm/jump_label.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_JUMP_LABEL_H #define _ASM_ARM_JUMP_LABEL_H diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h index 25021b798a1e..22751b5b5735 100644 --- a/arch/arm/include/asm/kexec.h +++ b/arch/arm/include/asm/kexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARM_KEXEC_H #define _ARM_KEXEC_H diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h index 0a9d5dd93294..3b73fdcf3627 100644 --- a/arch/arm/include/asm/kgdb.h +++ b/arch/arm/include/asm/kgdb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ARM KGDB support * diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index 83eb2f772911..5590940ee43d 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARM_KMAP_TYPES_H #define __ARM_KMAP_TYPES_H diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index ebf020b02bc8..c8781450905b 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -227,7 +227,6 @@ #define HSR_DABT_S1PTW (_AC(1, UL) << 7) #define HSR_DABT_CM (_AC(1, UL) << 8) -#define HSR_DABT_EA (_AC(1, UL) << 9) #define kvm_arm_exception_type \ {0, "RESET" }, \ diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h index 9a8a45aaf19a..98089ffd91bb 100644 --- a/arch/arm/include/asm/kvm_emulate.h +++ b/arch/arm/include/asm/kvm_emulate.h @@ -149,11 +149,6 @@ static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu) return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT; } -static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu) -{ - return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_EA; -} - static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW; @@ -206,6 +201,25 @@ static inline u8 kvm_vcpu_trap_get_fault_type(struct kvm_vcpu *vcpu) return kvm_vcpu_get_hsr(vcpu) & HSR_FSC_TYPE; } +static inline bool kvm_vcpu_dabt_isextabt(struct kvm_vcpu *vcpu) +{ + switch (kvm_vcpu_trap_get_fault_type(vcpu)) { + case FSC_SEA: + case FSC_SEA_TTW0: + case FSC_SEA_TTW1: + case FSC_SEA_TTW2: + case FSC_SEA_TTW3: + case FSC_SECC: + case FSC_SECC_TTW0: + case FSC_SECC_TTW1: + case FSC_SECC_TTW2: + case FSC_SECC_TTW3: + return true; + default: + return false; + } +} + static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK; diff --git a/arch/arm/include/asm/limits.h b/arch/arm/include/asm/limits.h index 08d8c6600804..ab159371d786 100644 --- a/arch/arm/include/asm/limits.h +++ b/arch/arm/include/asm/limits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_PIPE_H #define __ASM_PIPE_H diff --git a/arch/arm/include/asm/linkage.h b/arch/arm/include/asm/linkage.h index 5a25632b1bc0..c4670694ada7 100644 --- a/arch/arm/include/asm/linkage.h +++ b/arch/arm/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h index e8567bb99dfc..58922879a600 100644 --- a/arch/arm/include/asm/mc146818rtc.h +++ b/arch/arm/include/asm/mc146818rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine dependent access functions for RTC registers. */ diff --git a/arch/arm/include/asm/mcs_spinlock.h b/arch/arm/include/asm/mcs_spinlock.h index f652ad65840a..529d2cf4d06f 100644 --- a/arch/arm/include/asm/mcs_spinlock.h +++ b/arch/arm/include/asm/mcs_spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MCS_LOCK_H #define __ASM_MCS_LOCK_H diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h index bf47a6c110a2..b10fd358ccc5 100644 --- a/arch/arm/include/asm/memblock.h +++ b/arch/arm/include/asm/memblock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_MEMBLOCK_H #define _ASM_ARM_MEMBLOCK_H diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index a5b47421059d..65669b9ce128 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARM_MMU_H #define __ARM_MMU_H diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h index ed2319663a1e..89ad0596033a 100644 --- a/arch/arm/include/asm/module.h +++ b/arch/arm/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_MODULE_H #define _ASM_ARM_MODULE_H diff --git a/arch/arm/include/asm/mpu.h b/arch/arm/include/asm/mpu.h index c3247cc2fe08..0c3f774fa4b5 100644 --- a/arch/arm/include/asm/mpu.h +++ b/arch/arm/include/asm/mpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARM_MPU_H #define __ARM_MPU_H diff --git a/arch/arm/include/asm/nwflash.h b/arch/arm/include/asm/nwflash.h index 04e5a557a884..0ec6f07c2d8a 100644 --- a/arch/arm/include/asm/nwflash.h +++ b/arch/arm/include/asm/nwflash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _FLASH_H #define _FLASH_H diff --git a/arch/arm/include/asm/paravirt.h b/arch/arm/include/asm/paravirt.h index 8435ff591386..d51e5cd31d01 100644 --- a/arch/arm/include/asm/paravirt.h +++ b/arch/arm/include/asm/paravirt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_PARAVIRT_H #define _ASM_ARM_PARAVIRT_H diff --git a/arch/arm/include/asm/patch.h b/arch/arm/include/asm/patch.h index 77e054c2f6cd..0b48247c4600 100644 --- a/arch/arm/include/asm/patch.h +++ b/arch/arm/include/asm/patch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARM_KERNEL_PATCH_H #define _ARM_KERNEL_PATCH_H diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index 396c92bcc0cf..960d9dc4f380 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASMARM_PCI_H #define ASMARM_PCI_H diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h index 803bbf2b20b8..63dfe1f10335 100644 --- a/arch/arm/include/asm/sections.h +++ b/arch/arm/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_SECTIONS_H #define _ASM_ARM_SECTIONS_H diff --git a/arch/arm/include/asm/shmparam.h b/arch/arm/include/asm/shmparam.h index a5223b3a9bf9..367a9dac6150 100644 --- a/arch/arm/include/asm/shmparam.h +++ b/arch/arm/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMARM_SHMPARAM_H #define _ASMARM_SHMPARAM_H diff --git a/arch/arm/include/asm/signal.h b/arch/arm/include/asm/signal.h index c0eb412aff04..65530a042009 100644 --- a/arch/arm/include/asm/signal.h +++ b/arch/arm/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMARM_SIGNAL_H #define _ASMARM_SIGNAL_H diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index f9080717fc88..f2c36acf9886 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ARM specific SMP header, this contains our implementation * details. diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h index bfe163c40024..800f5228939f 100644 --- a/arch/arm/include/asm/smp_scu.h +++ b/arch/arm/include/asm/smp_scu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMARM_ARCH_SCU_H #define __ASMARM_ARCH_SCU_H @@ -7,6 +8,7 @@ #ifndef __ASSEMBLER__ +#include #include static inline bool scu_a9_has_base(void) diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index 7b2899c2f7fc..312784ee9936 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMARM_SMP_TWD_H #define __ASMARM_SMP_TWD_H diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h index 73e5e8513751..d362233856a5 100644 --- a/arch/arm/include/asm/sparsemem.h +++ b/arch/arm/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASMARM_SPARSEMEM_H #define ASMARM_SPARSEMEM_H diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h index 4bec45442072..25cb465c8538 100644 --- a/arch/arm/include/asm/spinlock.h +++ b/arch/arm/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H @@ -52,22 +53,6 @@ static inline void dsb_sev(void) * memory. */ -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - u16 owner = READ_ONCE(lock->tickets.owner); - - for (;;) { - arch_spinlock_t tmp = READ_ONCE(*lock); - - if (tmp.tickets.owner == tmp.tickets.next || - tmp.tickets.owner != owner) - break; - - wfe(); - } - smp_acquire__after_ctrl_dep(); -} - #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) static inline void arch_spin_lock(arch_spinlock_t *lock) diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h index 47663fcb10ad..5976958647fe 100644 --- a/arch/arm/include/asm/spinlock_types.h +++ b/arch/arm/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_TYPES_H #define __ASM_SPINLOCK_TYPES_H diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h index de003327be97..ef5f7b69443e 100644 --- a/arch/arm/include/asm/stackprotector.h +++ b/arch/arm/include/asm/stackprotector.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * GCC stack protector support. * diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h index 7722201ead19..2d76a2e29f05 100644 --- a/arch/arm/include/asm/stacktrace.h +++ b/arch/arm/include/asm/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_STACKTRACE_H #define __ASM_STACKTRACE_H diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aad0fc1..f54a3136aac6 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_STRING_H #define __ASM_ARM_STRING_H @@ -24,6 +25,20 @@ extern void * memchr(const void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMSET extern void * memset(void *, int, __kernel_size_t); +#define __HAVE_ARCH_MEMSET32 +extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); +static inline void *memset32(uint32_t *p, uint32_t v, __kernel_size_t n) +{ + return __memset32(p, v, n * 4); +} + +#define __HAVE_ARCH_MEMSET64 +extern void *__memset64(uint64_t *, uint32_t low, __kernel_size_t, uint32_t hi); +static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) +{ + return __memset64(p, v, n * 8, v >> 32); +} + extern void __memzero(void *ptr, __kernel_size_t n); #define memset(p,v,n) \ diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h index 6c7182f32cef..452bbdcbcc83 100644 --- a/arch/arm/include/asm/suspend.h +++ b/arch/arm/include/asm/suspend.h @@ -1,6 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_SUSPEND_H #define __ASM_ARM_SUSPEND_H +#include + struct sleep_save_sp { u32 *save_ptr_stash; u32 save_ptr_stash_phys; diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h index 537fc9b91889..c6051823048b 100644 --- a/arch/arm/include/asm/swab.h +++ b/arch/arm/include/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/byteorder.h * diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h index 12ebfcc1d539..d3e937dcee4d 100644 --- a/arch/arm/include/asm/switch_to.h +++ b/arch/arm/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_SWITCH_TO_H #define __ASM_ARM_SWITCH_TO_H diff --git a/arch/arm/include/asm/sync_bitops.h b/arch/arm/include/asm/sync_bitops.h index 9732b8e11e63..39ff217136d1 100644 --- a/arch/arm/include/asm/sync_bitops.h +++ b/arch/arm/include/asm/sync_bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SYNC_BITOPS_H__ #define __ASM_SYNC_BITOPS_H__ diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h index e86c985b8c7a..06dea6bce293 100644 --- a/arch/arm/include/asm/syscall.h +++ b/arch/arm/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access to user system call parameters and results * diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h index 3860cbd401ec..ef7fdb588b5f 100644 --- a/arch/arm/include/asm/system_info.h +++ b/arch/arm/include/asm/system_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_SYSTEM_INFO_H #define __ASM_ARM_SYSTEM_INFO_H diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h index 8c4a89f5ce7d..78f6db114faf 100644 --- a/arch/arm/include/asm/system_misc.h +++ b/arch/arm/include/asm/system_misc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_SYSTEM_MISC_H #define __ASM_ARM_SYSTEM_MISC_H diff --git a/arch/arm/include/asm/therm.h b/arch/arm/include/asm/therm.h index f002f0197d78..17b0bc9b5e9b 100644 --- a/arch/arm/include/asm/therm.h +++ b/arch/arm/include/asm/therm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/therm.h: Definitions for Dallas Semiconductor * DS1620 thermometer driver (as used in the Rebel.com NetWinder) diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h index 5f833f7adba1..5a66c3b13c92 100644 --- a/arch/arm/include/asm/tls.h +++ b/arch/arm/include/asm/tls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMARM_TLS_H #define __ASMARM_TLS_H diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index 370f7a732900..f59ab9bcbaf9 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_TOPOLOGY_H #define _ASM_ARM_TOPOLOGY_H diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index f555bb3664dc..f9a6c5fc3fd1 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMARM_TRAP_H #define _ASMARM_TRAP_H @@ -18,7 +19,6 @@ struct undef_hook { void register_undef_hook(struct undef_hook *hook); void unregister_undef_hook(struct undef_hook *hook); -#ifdef CONFIG_FUNCTION_GRAPH_TRACER static inline int __in_irqentry_text(unsigned long ptr) { extern char __irqentry_text_start[]; @@ -27,12 +27,6 @@ static inline int __in_irqentry_text(unsigned long ptr) return ptr >= (unsigned long)&__irqentry_text_start && ptr < (unsigned long)&__irqentry_text_end; } -#else -static inline int __in_irqentry_text(unsigned long ptr) -{ - return 0; -} -#endif static inline int in_exception_text(unsigned long ptr) { diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h index 921d8274855c..3f0d95ab14b8 100644 --- a/arch/arm/include/asm/ucontext.h +++ b/arch/arm/include/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMARM_UCONTEXT_H #define _ASMARM_UCONTEXT_H diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h new file mode 100644 index 000000000000..ab905ffcf193 --- /dev/null +++ b/arch/arm/include/asm/unaligned.h @@ -0,0 +1,27 @@ +#ifndef __ASM_ARM_UNALIGNED_H +#define __ASM_ARM_UNALIGNED_H + +/* + * We generally want to set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS on ARMv6+, + * but we don't want to use linux/unaligned/access_ok.h since that can lead + * to traps on unaligned stm/ldm or strd/ldrd. + */ +#include + +#if defined(__LITTLE_ENDIAN) +# include +# include +# include +# define get_unaligned __get_unaligned_le +# define put_unaligned __put_unaligned_le +#elif defined(__BIG_ENDIAN) +# include +# include +# include +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#else +# error need to define endianess +#endif + +#endif /* __ASM_ARM_UNALIGNED_H */ diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h index 35917b3a97f9..c799a3c49342 100644 --- a/arch/arm/include/asm/user.h +++ b/arch/arm/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARM_USER_H #define _ARM_USER_H diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h index 1fd775c1bc5d..e6d9e29fcae4 100644 --- a/arch/arm/include/asm/v7m.h +++ b/arch/arm/include/asm/v7m.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Common defines for v7m cpus */ diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h index d0295f1dd1a3..9c99e817535e 100644 --- a/arch/arm/include/asm/vdso.h +++ b/arch/arm/include/asm/vdso.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_VDSO_H #define __ASM_VDSO_H diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h index 22e414056a8c..7157d2a30a49 100644 --- a/arch/arm/include/asm/vfp.h +++ b/arch/arm/include/asm/vfp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/vfp.h * diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h index 301c1db3e99b..ef5dfedacd8d 100644 --- a/arch/arm/include/asm/vfpmacros.h +++ b/arch/arm/include/asm/vfpmacros.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/include/asm/vfpmacros.h * diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h index 91f40217bfa5..7c0bee57855a 100644 --- a/arch/arm/include/asm/vga.h +++ b/arch/arm/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASMARM_VGA_H #define ASMARM_VGA_H diff --git a/arch/arm/include/asm/word-at-a-time.h b/arch/arm/include/asm/word-at-a-time.h index 5831dce4b51c..352ab213520d 100644 --- a/arch/arm/include/asm/word-at-a-time.h +++ b/arch/arm/include/asm/word-at-a-time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARM_WORD_AT_A_TIME_H #define __ASM_ARM_WORD_AT_A_TIME_H diff --git a/arch/arm/include/asm/xen/events.h b/arch/arm/include/asm/xen/events.h index 620dc75362e5..c83086f745cf 100644 --- a/arch/arm/include/asm/xen/events.h +++ b/arch/arm/include/asm/xen/events.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM_XEN_EVENTS_H #define _ASM_ARM_XEN_EVENTS_H diff --git a/arch/arm/include/debug/omap2plus.S b/arch/arm/include/debug/omap2plus.S index 6d867aef18eb..192a7583999c 100644 --- a/arch/arm/include/debug/omap2plus.S +++ b/arch/arm/include/debug/omap2plus.S @@ -12,43 +12,6 @@ #include -/* OMAP2 serial ports */ -#define OMAP2_UART1_BASE 0x4806a000 -#define OMAP2_UART2_BASE 0x4806c000 -#define OMAP2_UART3_BASE 0x4806e000 - -/* OMAP3 serial ports */ -#define OMAP3_UART1_BASE OMAP2_UART1_BASE -#define OMAP3_UART2_BASE OMAP2_UART2_BASE -#define OMAP3_UART3_BASE 0x49020000 -#define OMAP3_UART4_BASE 0x49042000 /* Only on 36xx */ -#define OMAP3_UART4_AM35XX_BASE 0x4809E000 /* Only on AM35xx */ - -/* OMAP4 serial ports */ -#define OMAP4_UART1_BASE OMAP2_UART1_BASE -#define OMAP4_UART2_BASE OMAP2_UART2_BASE -#define OMAP4_UART3_BASE 0x48020000 -#define OMAP4_UART4_BASE 0x4806e000 - -/* TI81XX serial ports */ -#define TI81XX_UART1_BASE 0x48020000 -#define TI81XX_UART2_BASE 0x48022000 -#define TI81XX_UART3_BASE 0x48024000 - -/* AM3505/3517 UART4 */ -#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ - -/* AM33XX serial port */ -#define AM33XX_UART1_BASE 0x44E09000 - -/* OMAP5 serial ports */ -#define OMAP5_UART1_BASE OMAP2_UART1_BASE -#define OMAP5_UART2_BASE OMAP2_UART2_BASE -#define OMAP5_UART3_BASE OMAP4_UART3_BASE -#define OMAP5_UART4_BASE OMAP4_UART4_BASE -#define OMAP5_UART5_BASE 0x48066000 -#define OMAP5_UART6_BASE 0x48068000 - /* External port on Zoom2/3 */ #define ZOOM_UART_BASE 0x10000000 #define ZOOM_UART_VIRT 0xfa400000 @@ -59,6 +22,7 @@ #define UART_OFFSET(addr) ((addr) & 0x00ffffff) .pushsection .data + .align 2 omap_uart_phys: .word 0 omap_uart_virt: .word 0 omap_uart_lsr: .word 0 @@ -79,55 +43,6 @@ omap_uart_lsr: .word 0 bne 100f @ already configured /* Configure the UART offset from the phys/virt base */ -#ifdef CONFIG_DEBUG_OMAP2UART1 - mov \rp, #UART_OFFSET(OMAP2_UART1_BASE) @ omap2/3/4 - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP2UART2 - mov \rp, #UART_OFFSET(OMAP2_UART2_BASE) @ omap2/3/4 - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP2UART3 - mov \rp, #UART_OFFSET(OMAP2_UART3_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP3UART3 - mov \rp, #UART_OFFSET(OMAP3_UART1_BASE) - add \rp, \rp, #0x00fb0000 - add \rp, \rp, #0x00006000 @ OMAP3_UART3_BASE - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP4UART3 - mov \rp, #UART_OFFSET(OMAP4_UART3_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP3UART4 - mov \rp, #UART_OFFSET(OMAP3_UART1_BASE) - add \rp, \rp, #0x00fb0000 - add \rp, \rp, #0x00028000 @ OMAP3_UART4_BASE - b 98f -#endif -#ifdef CONFIG_DEBUG_OMAP4UART4 - mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_TI81XXUART1 - mov \rp, #UART_OFFSET(TI81XX_UART1_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_TI81XXUART2 - mov \rp, #UART_OFFSET(TI81XX_UART2_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_TI81XXUART3 - mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) - b 98f -#endif -#ifdef CONFIG_DEBUG_AM33XXUART1 - ldr \rp, =AM33XX_UART1_BASE - and \rp, \rp, #0x00ffffff - b 97f -#endif #ifdef CONFIG_DEBUG_ZOOM_UART ldr \rp, =ZOOM_UART_BASE str \rp, [\tmp, #0] @ omap_uart_phys @@ -138,28 +53,6 @@ omap_uart_lsr: .word 0 #endif b 10b - /* AM33XX: Store both phys and virt address for the uart */ -97: add \rp, \rp, #0x44000000 @ phys base - str \rp, [\tmp, #0] @ omap_uart_phys - sub \rp, \rp, #0x44000000 @ phys base - add \rp, \rp, #0xf9000000 @ virt base - str \rp, [\tmp, #4] @ omap_uart_virt - mov \rp, #(UART_LSR << OMAP_PORT_SHIFT) - str \rp, [\tmp, #8] @ omap_uart_lsr - - b 10b - - /* Store both phys and virt address for the uart */ -98: add \rp, \rp, #0x48000000 @ phys base - str \rp, [\tmp, #0] @ omap_uart_phys - sub \rp, \rp, #0x48000000 @ phys base - add \rp, \rp, #0xfa000000 @ virt base - str \rp, [\tmp, #4] @ omap_uart_virt - mov \rp, #(UART_LSR << OMAP_PORT_SHIFT) - str \rp, [\tmp, #8] @ omap_uart_lsr - - b 10b - .align 99: .word . .word omap_uart_phys diff --git a/arch/arm/include/debug/palmchip.S b/arch/arm/include/debug/palmchip.S index 6824b2d1c38e..aed59332e487 100644 --- a/arch/arm/include/debug/palmchip.S +++ b/arch/arm/include/debug/palmchip.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #undef UART_TX diff --git a/arch/arm/include/debug/uncompress.h b/arch/arm/include/debug/uncompress.h index 0e2949b0fae9..ff0b227290cb 100644 --- a/arch/arm/include/debug/uncompress.h +++ b/arch/arm/include/debug/uncompress.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_DEBUG_UNCOMPRESS extern void putc(int c); #else diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild index 8e17fe80b55b..4d53de308ee0 100644 --- a/arch/arm/include/uapi/asm/Kbuild +++ b/arch/arm/include/uapi/asm/Kbuild @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm diff --git a/arch/arm/include/uapi/asm/auxvec.h b/arch/arm/include/uapi/asm/auxvec.h index cb02a767a500..5c09da5965d4 100644 --- a/arch/arm/include/uapi/asm/auxvec.h +++ b/arch/arm/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_AUXVEC_H #define __ASM_AUXVEC_H diff --git a/arch/arm/include/uapi/asm/byteorder.h b/arch/arm/include/uapi/asm/byteorder.h index 77379748b171..cb8406afe162 100644 --- a/arch/arm/include/uapi/asm/byteorder.h +++ b/arch/arm/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * arch/arm/include/asm/byteorder.h * diff --git a/arch/arm/include/uapi/asm/fcntl.h b/arch/arm/include/uapi/asm/fcntl.h index a80b6607b2ef..e6b5d7141c05 100644 --- a/arch/arm/include/uapi/asm/fcntl.h +++ b/arch/arm/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ARM_FCNTL_H #define _ARM_FCNTL_H diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h index 20d12f230a2f..b5971dfa4b8c 100644 --- a/arch/arm/include/uapi/asm/hwcap.h +++ b/arch/arm/include/uapi/asm/hwcap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ASMARM_HWCAP_H #define _UAPI__ASMARM_HWCAP_H diff --git a/arch/arm/include/uapi/asm/ioctls.h b/arch/arm/include/uapi/asm/ioctls.h index 9c9629816128..1bfe2854fb51 100644 --- a/arch/arm/include/uapi/asm/ioctls.h +++ b/arch/arm/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_ARM_IOCTLS_H #define __ASM_ARM_IOCTLS_H diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h index 5db2d4c6a55f..1f57bbe82b6f 100644 --- a/arch/arm/include/uapi/asm/kvm.h +++ b/arch/arm/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 - Virtual Open Systems and Columbia University * Author: Christoffer Dall diff --git a/arch/arm/include/uapi/asm/kvm_para.h b/arch/arm/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/arm/include/uapi/asm/kvm_para.h +++ b/arch/arm/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/arm/include/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h index ce59448458b2..a3c046174e6b 100644 --- a/arch/arm/include/uapi/asm/perf_regs.h +++ b/arch/arm/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_ARM_PERF_REGS_H #define _ASM_ARM_PERF_REGS_H diff --git a/arch/arm/include/uapi/asm/posix_types.h b/arch/arm/include/uapi/asm/posix_types.h index d2de9cbbcd9b..6bf11ad5d6ba 100644 --- a/arch/arm/include/uapi/asm/posix_types.h +++ b/arch/arm/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * arch/arm/include/asm/posix_types.h * diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h index 5af0ed1b825a..b67cda536c25 100644 --- a/arch/arm/include/uapi/asm/ptrace.h +++ b/arch/arm/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * arch/arm/include/asm/ptrace.h * diff --git a/arch/arm/include/uapi/asm/setup.h b/arch/arm/include/uapi/asm/setup.h index 979ff4016404..6b335a9ff8c8 100644 --- a/arch/arm/include/uapi/asm/setup.h +++ b/arch/arm/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * linux/include/asm/setup.h * diff --git a/arch/arm/include/uapi/asm/sigcontext.h b/arch/arm/include/uapi/asm/sigcontext.h index fc0b80b6a6fc..e223c65adabd 100644 --- a/arch/arm/include/uapi/asm/sigcontext.h +++ b/arch/arm/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMARM_SIGCONTEXT_H #define _ASMARM_SIGCONTEXT_H diff --git a/arch/arm/include/uapi/asm/signal.h b/arch/arm/include/uapi/asm/signal.h index 33073bdcf091..9b4185ba4f8a 100644 --- a/arch/arm/include/uapi/asm/signal.h +++ b/arch/arm/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASMARM_SIGNAL_H #define _UAPI_ASMARM_SIGNAL_H diff --git a/arch/arm/include/uapi/asm/stat.h b/arch/arm/include/uapi/asm/stat.h index 42c0c13999d5..9c6580bfc04d 100644 --- a/arch/arm/include/uapi/asm/stat.h +++ b/arch/arm/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMARM_STAT_H #define _ASMARM_STAT_H diff --git a/arch/arm/include/uapi/asm/statfs.h b/arch/arm/include/uapi/asm/statfs.h index 079447c05ba7..177f08540079 100644 --- a/arch/arm/include/uapi/asm/statfs.h +++ b/arch/arm/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMARM_STATFS_H #define _ASMARM_STATFS_H diff --git a/arch/arm/include/uapi/asm/swab.h b/arch/arm/include/uapi/asm/swab.h index 6fcb32a5c453..301aa8d8e320 100644 --- a/arch/arm/include/uapi/asm/swab.h +++ b/arch/arm/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * arch/arm/include/asm/byteorder.h * diff --git a/arch/arm/include/uapi/asm/types.h b/arch/arm/include/uapi/asm/types.h index 9435a42f575e..1a667bc26510 100644 --- a/arch/arm/include/uapi/asm/types.h +++ b/arch/arm/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_TYPES_H #define _UAPI_ASM_TYPES_H diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index 28bd456494a3..39b2ad997e91 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * arch/arm/include/asm/unistd.h * diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index ad325a8c7e1e..499f978fb1fd 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 8e8d20cdbce7..5266fd9ad6b4 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -87,6 +87,8 @@ EXPORT_SYMBOL(__raw_writesl); EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(__memset32); +EXPORT_SYMBOL(__memset64); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memchr); diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index edfa2268c127..201100226301 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ void convert_to_tag_list(struct tag *tags); #ifdef CONFIG_ATAGS diff --git a/arch/arm/kernel/atags_proc.c b/arch/arm/kernel/atags_proc.c index 5a3379055f55..312cb89ec364 100644 --- a/arch/arm/kernel/atags_proc.c +++ b/arch/arm/kernel/atags_proc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index c1809fb549dd..0cd0aefb3a8f 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/kernel/bios32.c * diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c index a3308ad1a024..fda5579123a8 100644 --- a/arch/arm/kernel/cpuidle.c +++ b/arch/arm/kernel/cpuidle.c @@ -101,8 +101,8 @@ static int __init arm_cpuidle_read_ops(struct device_node *dn, int cpu) ops = arm_cpuidle_get_ops(enable_method); if (!ops) { - pr_warn("%s: unsupported enable-method property: %s\n", - dn->full_name, enable_method); + pr_warn("%pOF: unsupported enable-method property: %s\n", + dn, enable_method); return -EOPNOTSUPP; } diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index ea9646cc2a0e..0a498cb3fad8 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -115,7 +115,11 @@ ENTRY(printascii) mov r1, r0 mov r0, #0x04 @ SYS_WRITE0 ARM( svc #0x123456 ) +#ifdef CONFIG_CPU_V7M + THUMB( bkpt #0xab ) +#else THUMB( svc #0xab ) +#endif ret lr ENDPROC(printascii) @@ -124,7 +128,11 @@ ENTRY(printch) strb r0, [r1] mov r0, #0x03 @ SYS_WRITEC ARM( svc #0x123456 ) +#ifdef CONFIG_CPU_V7M + THUMB( bkpt #0xab ) +#else THUMB( svc #0xab ) +#endif ret lr ENDPROC(printch) diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c index f676febbb270..ecaa68dd1af5 100644 --- a/arch/arm/kernel/devtree.c +++ b/arch/arm/kernel/devtree.c @@ -95,7 +95,7 @@ void __init arm_dt_init_cpu_maps(void) if (of_node_cmp(cpu->type, "cpu")) continue; - pr_debug(" * %s...\n", cpu->full_name); + pr_debug(" * %pOF...\n", cpu); /* * A device tree containing CPU nodes with missing "reg" * properties is considered invalid to build the @@ -103,8 +103,7 @@ void __init arm_dt_init_cpu_maps(void) */ cell = of_get_property(cpu, "reg", &prop_bytes); if (!cell || prop_bytes < sizeof(*cell)) { - pr_debug(" * %s missing reg property\n", - cpu->full_name); + pr_debug(" * %pOF missing reg property\n", cpu); of_node_put(cpu); return; } diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c index d0d1e83150c9..846dda2f3c48 100644 --- a/arch/arm/kernel/elf.c +++ b/arch/arm/kernel/elf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index c731f0d2b2af..fbc707626b3e 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -721,6 +721,7 @@ do_fpe: */ .pushsection .data + .align 2 ENTRY(fp_enter) .word no_fp .popsection @@ -1224,6 +1225,7 @@ vector_addrexcptn: W(b) vector_fiq .data + .align 2 .globl cr_alignment cr_alignment: diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index eb5cd77bf1d8..99c908226065 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_AEABI #include #endif @@ -27,6 +28,14 @@ #include "entry-header.S" +saved_psr .req r8 +#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING) +saved_pc .req r9 +#define TRACE(x...) x +#else +saved_pc .req lr +#define TRACE(x...) +#endif .align 5 #if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING)) @@ -40,10 +49,14 @@ ret_fast_syscall: UNWIND(.fnstart ) UNWIND(.cantunwind ) disable_irq_notrace @ disable interrupts + ldr r2, [tsk, #TI_ADDR_LIMIT] + cmp r2, #TASK_SIZE + blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK bne fast_work_pending + /* perform architecture specific actions before user return */ arch_ret_to_user r1, lr @@ -66,6 +79,9 @@ ret_fast_syscall: UNWIND(.cantunwind ) str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 disable_irq_notrace @ disable interrupts + ldr r2, [tsk, #TI_ADDR_LIMIT] + cmp r2, #TASK_SIZE + blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK beq no_work_pending @@ -98,6 +114,9 @@ ENTRY(ret_to_user) ret_slow_syscall: disable_irq_notrace @ disable interrupts ENTRY(ret_to_user_from_irq) + ldr r2, [tsk, #TI_ADDR_LIMIT] + cmp r2, #TASK_SIZE + blne addr_limit_check_failed ldr r1, [tsk, #TI_FLAGS] tst r1, #_TIF_WORK_MASK bne slow_work_pending @@ -141,16 +160,17 @@ ENTRY(vector_swi) ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr THUMB( mov r8, sp ) THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr - mrs r8, spsr @ called from non-FIQ mode, so ok. - str lr, [sp, #S_PC] @ Save calling PC - str r8, [sp, #S_PSR] @ Save CPSR + mrs saved_psr, spsr @ called from non-FIQ mode, so ok. + TRACE( mov saved_pc, lr ) + str saved_pc, [sp, #S_PC] @ Save calling PC + str saved_psr, [sp, #S_PSR] @ Save CPSR str r0, [sp, #S_OLD_R0] @ Save OLD_R0 #endif zero_fp alignment_trap r10, ip, __cr_alignment - enable_irq - ct_user_exit - get_thread_info tsk + asm_trace_hardirqs_on save=0 + enable_irq_notrace + ct_user_exit save=0 /* * Get the system call number. @@ -163,11 +183,11 @@ ENTRY(vector_swi) * value to determine if it is an EABI or an old ABI call. */ #ifdef CONFIG_ARM_THUMB - tst r8, #PSR_T_BIT + tst saved_psr, #PSR_T_BIT movne r10, #0 @ no thumb OABI emulation - USER( ldreq r10, [lr, #-4] ) @ get SWI instruction + USER( ldreq r10, [saved_pc, #-4] ) @ get SWI instruction #else - USER( ldr r10, [lr, #-4] ) @ get SWI instruction + USER( ldr r10, [saved_pc, #-4] ) @ get SWI instruction #endif ARM_BE8(rev r10, r10) @ little endian instruction @@ -178,15 +198,17 @@ ENTRY(vector_swi) */ #elif defined(CONFIG_ARM_THUMB) /* Legacy ABI only, possibly thumb mode. */ - tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs + tst saved_psr, #PSR_T_BIT @ this is SPSR from save_user_regs addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in - USER( ldreq scno, [lr, #-4] ) + USER( ldreq scno, [saved_pc, #-4] ) #else /* Legacy ABI only. */ - USER( ldr scno, [lr, #-4] ) @ get SWI instruction + USER( ldr scno, [saved_pc, #-4] ) @ get SWI instruction #endif + /* saved_psr and saved_pc are now dead */ + uaccess_disable tbl adr tbl, sys_call_table @ load syscall table pointer @@ -205,6 +227,12 @@ ENTRY(vector_swi) bic scno, scno, #0xff000000 @ mask off SWI op-code eor scno, scno, #__NR_SYSCALL_BASE @ check OS number #endif + get_thread_info tsk + /* + * Reload the registers that may have been corrupted on entry to + * the syscall assembly (by tracing or context tracking.) + */ + TRACE( ldmia sp, {r0 - r3} ) local_restart: ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing @@ -234,8 +262,9 @@ local_restart: * current task. */ 9001: - sub lr, lr, #4 + sub lr, saved_pc, #4 str lr, [sp, #S_PC] + get_thread_info tsk b ret_fast_syscall #endif ENDPROC(vector_swi) diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 6391728c8f03..d523cd8439a3 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 059c3da0fee3..cd1234c103fc 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/kernel/fiq.c * diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 04286fd9e09c..6b1148cafffd 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -556,6 +556,7 @@ ENDPROC(__fixup_smp) .word __smpalt_end .pushsection .data + .align 2 .globl smp_on_up smp_on_up: ALT_SMP(.long 1) @@ -716,6 +717,7 @@ ENTRY(fixup_pv_table) ENDPROC(fixup_pv_table) .data + .align 2 .globl __pv_phys_pfn_offset .type __pv_phys_pfn_offset, %object __pv_phys_pfn_offset: diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index ec7e7377d423..60146e32619a 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S @@ -31,6 +31,7 @@ * zeroing of .bss would clobber it. */ .data + .align 2 ENTRY(__boot_cpu_mode) .long 0 .text diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c index b760340b7014..2e844b70386b 100644 --- a/arch/arm/kernel/insn.c +++ b/arch/arm/kernel/insn.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c index eedefe050022..60b621295d6c 100644 --- a/arch/arm/kernel/io.c +++ b/arch/arm/kernel/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index 49fadbda8c63..81cd4d43b3ec 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S @@ -367,6 +367,7 @@ ENTRY(iwmmxt_task_release) ENDPROC(iwmmxt_task_release) .data + .align 2 concan_owner: .word 0 diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c index 845a5dd9c42b..90bce3d9928e 100644 --- a/arch/arm/kernel/jump_label.c +++ b/arch/arm/kernel/jump_label.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c index 1bb4c40a3135..caa0dbe3dc61 100644 --- a/arch/arm/kernel/kgdb.c +++ b/arch/arm/kernel/kgdb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/kernel/kgdb.c * diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index fe1419eeb932..6b38d7a634c1 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * machine_kexec.c - handle transition of Linux booting another kernel */ diff --git a/arch/arm/kernel/module.lds b/arch/arm/kernel/module.lds index eacb5c67f61e..79cb6af565e5 100644 --- a/arch/arm/kernel/module.lds +++ b/arch/arm/kernel/module.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ SECTIONS { .plt : { BYTE(0) } .init.plt : { BYTE(0) } diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c index a1a34722c655..a50dc00d79a2 100644 --- a/arch/arm/kernel/patch.c +++ b/arch/arm/kernel/patch.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/kernel/perf_callchain.c b/arch/arm/kernel/perf_callchain.c index 22bf1f64d99a..08e43a32a693 100644 --- a/arch/arm/kernel/perf_callchain.c +++ b/arch/arm/kernel/perf_callchain.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM callchain support * diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index 8226d0b71fd3..1d7061a38922 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARMv6 Performance counter handling code. * diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index ab6522b43659..870b66c1e4ef 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code. * diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c index 0e51f5e4f879..fcf218da660e 100644 --- a/arch/arm/kernel/perf_event_xscale.c +++ b/arch/arm/kernel/perf_event_xscale.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARMv5 [xscale] Performance counter handling code. * diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c index c366b83bf955..05fe92aa7d98 100644 --- a/arch/arm/kernel/perf_regs.c +++ b/arch/arm/kernel/perf_regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm/kernel/reboot.h b/arch/arm/kernel/reboot.h index bf7a0b1f076e..189ab81b77b6 100644 --- a/arch/arm/kernel/reboot.h +++ b/arch/arm/kernel/reboot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef REBOOT_H #define REBOOT_H diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S index 35e72585ec1d..7eaa2ae7aff5 100644 --- a/arch/arm/kernel/relocate_kernel.S +++ b/arch/arm/kernel/relocate_kernel.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * relocate_kernel.S - put the kernel image in place to boot */ diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 5814298ef0b7..b67ae12503f3 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -673,3 +674,9 @@ struct page *get_signal_page(void) return page; } + +/* Defer to generic check */ +asmlinkage void addr_limit_check_failed(void) +{ + addr_limit_user_check(); +} diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 0f6c1000582c..a8257fc9cf2a 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include @@ -171,6 +172,7 @@ mpidr_hash_ptr: .long mpidr_hash - . @ mpidr_hash struct offset .data + .align 2 .type sleep_save_sp, #object ENTRY(sleep_save_sp) .space SLEEP_SAVE_SP_SZ @ struct sleep_save_sp diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 3a2fa203637a..65228bf4c6df 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -171,6 +171,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) { __save_stack_trace(tsk, trace, 1); } +EXPORT_SYMBOL(save_stack_trace_tsk); void save_stack_trace(struct stack_trace *trace) { diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c index ef794c799cb6..a40ebb7c0896 100644 --- a/arch/arm/kernel/suspend.c +++ b/arch/arm/kernel/suspend.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index bf949a763dbe..24ac3cab411d 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -127,8 +127,7 @@ static void __init parse_dt_topology(void) rate = of_get_property(cn, "clock-frequency", &len); if (!rate || len != 4) { - pr_err("%s missing clock-frequency property\n", - cn->full_name); + pr_err("%pOF missing clock-frequency property\n", cn); continue; } diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 948c648fea00..0fcd82f01388 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -154,30 +154,26 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom, set_fs(fs); } -static void dump_instr(const char *lvl, struct pt_regs *regs) +static void __dump_instr(const char *lvl, struct pt_regs *regs) { unsigned long addr = instruction_pointer(regs); const int thumb = thumb_mode(regs); const int width = thumb ? 4 : 8; - mm_segment_t fs; char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str; int i; /* - * We need to switch to kernel mode so that we can use __get_user - * to safely read from kernel space. Note that we now dump the - * code first, just in case the backtrace kills us. + * Note that we now dump the code first, just in case the backtrace + * kills us. */ - fs = get_fs(); - set_fs(KERNEL_DS); for (i = -4; i < 1 + !!thumb; i++) { unsigned int val, bad; if (thumb) - bad = __get_user(val, &((u16 *)addr)[i]); + bad = get_user(val, &((u16 *)addr)[i]); else - bad = __get_user(val, &((u32 *)addr)[i]); + bad = get_user(val, &((u32 *)addr)[i]); if (!bad) p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ", @@ -188,8 +184,20 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) } } printk("%sCode: %s\n", lvl, str); +} - set_fs(fs); +static void dump_instr(const char *lvl, struct pt_regs *regs) +{ + mm_segment_t fs; + + if (!user_mode(regs)) { + fs = get_fs(); + set_fs(KERNEL_DS); + __dump_instr(lvl, regs); + set_fs(fs); + } else { + __dump_instr(lvl, regs); + } } #ifdef CONFIG_ARM_UNWIND diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S index 8265b116218d..0951df916b85 100644 --- a/arch/arm/kernel/vmlinux-xip.lds.S +++ b/arch/arm/kernel/vmlinux-xip.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make ARM Linux kernel * taken from the i386 version by Russell King * Written by Martin Mares diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index c83a7ba737d6..1845a5affb44 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make ARM Linux kernel * taken from the i386 version by Russell King * Written by Martin Mares diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 90d0176fb30d..f24628db5409 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # KVM configuration # diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile index d9beee652d36..f550abd64a25 100644 --- a/arch/arm/kvm/Makefile +++ b/arch/arm/kvm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Kernel-based Virtual Machine module # diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c index 0064b86a2c87..30a13647c54c 100644 --- a/arch/arm/kvm/emulate.c +++ b/arch/arm/kvm/emulate.c @@ -227,7 +227,7 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu) u32 return_offset = (is_thumb) ? 2 : 4; kvm_update_psr(vcpu, UND_MODE); - *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) - return_offset; + *vcpu_reg(vcpu, 14) = *vcpu_pc(vcpu) + return_offset; /* Branch to exception vector */ *vcpu_pc(vcpu) = exc_vector_base(vcpu) + vect_offset; @@ -239,10 +239,8 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu) */ static void inject_abt(struct kvm_vcpu *vcpu, bool is_pabt, unsigned long addr) { - unsigned long cpsr = *vcpu_cpsr(vcpu); - bool is_thumb = (cpsr & PSR_T_BIT); u32 vect_offset; - u32 return_offset = (is_thumb) ? 4 : 0; + u32 return_offset = (is_pabt) ? 4 : 8; bool is_lpae; kvm_update_psr(vcpu, ABT_MODE); diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c index 54442e375354..cf8bf6bf87c4 100644 --- a/arch/arm/kvm/handle_exit.c +++ b/arch/arm/kvm/handle_exit.c @@ -67,7 +67,7 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run) if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE) { trace_kvm_wfx(*vcpu_pc(vcpu), true); vcpu->stat.wfe_exit_stat++; - kvm_vcpu_on_spin(vcpu); + kvm_vcpu_on_spin(vcpu, vcpu_mode_priv(vcpu)); } else { trace_kvm_wfx(*vcpu_pc(vcpu), false); vcpu->stat.wfi_exit_stat++; diff --git a/arch/arm/kvm/hyp/Makefile b/arch/arm/kvm/hyp/Makefile index 8679405b0b2b..5638ce0c9524 100644 --- a/arch/arm/kvm/hyp/Makefile +++ b/arch/arm/kvm/hyp/Makefile @@ -1,8 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Kernel-based Virtual Machine module, HYP part # -ccflags-y += -fno-stack-protector +ccflags-y += -fno-stack-protector -DDISABLE_BRANCH_PROFILING KVM=../../../../virt/kvm diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h index b0d10648c486..69a9d62a0ac6 100644 --- a/arch/arm/kvm/trace.h +++ b/arch/arm/kvm/trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_ARM_KVM_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_ARM_KVM_H diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 27f4d96258a2..4cb0b9624d8f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/arm/lib/Makefile # diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index 7d807cfd8ef5..93cddab73072 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/lib/bswapsdi2.S b/arch/arm/lib/bswapsdi2.S index 07cda737bb11..591ba077e874 100644 --- a/arch/arm/lib/bswapsdi2.S +++ b/arch/arm/lib/bswapsdi2.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S index 3c65e3bd790f..ed6d35d9cdb5 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S @@ -28,7 +28,7 @@ UNWIND( .fnstart ) 1: orr r1, r1, r1, lsl #8 orr r1, r1, r1, lsl #16 mov r3, r1 - cmp r2, #16 +7: cmp r2, #16 blt 4f #if ! CALGN(1)+0 @@ -41,7 +41,7 @@ UNWIND( .fnend ) UNWIND( .fnstart ) UNWIND( .save {r8, lr} ) mov r8, r1 - mov lr, r1 + mov lr, r3 2: subs r2, r2, #64 stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time. @@ -73,11 +73,11 @@ UNWIND( .fnend ) UNWIND( .fnstart ) UNWIND( .save {r4-r8, lr} ) mov r4, r1 - mov r5, r1 + mov r5, r3 mov r6, r1 - mov r7, r1 + mov r7, r3 mov r8, r1 - mov lr, r1 + mov lr, r3 cmp r2, #96 tstgt ip, #31 @@ -114,7 +114,7 @@ UNWIND( .fnstart ) tst r2, #4 strne r1, [ip], #4 /* - * When we get here, we've got less than 4 bytes to zero. We + * When we get here, we've got less than 4 bytes to set. We * may have an unaligned pointer as well. */ 5: tst r2, #2 @@ -135,3 +135,15 @@ UNWIND( .fnstart ) UNWIND( .fnend ) ENDPROC(memset) ENDPROC(mmioset) + +ENTRY(__memset32) +UNWIND( .fnstart ) + mov r3, r1 @ copy r1 to r3 and fall into memset64 +UNWIND( .fnend ) +ENDPROC(__memset32) +ENTRY(__memset64) +UNWIND( .fnstart ) + mov ip, r0 @ preserve r0 as return value + b 7b @ jump into the middle of memset +UNWIND( .fnend ) +ENDPROC(__memset64) diff --git a/arch/arm/mach-actions/Kconfig b/arch/arm/mach-actions/Kconfig index ad9c5c89c683..b5e0ac965ec0 100644 --- a/arch/arm/mach-actions/Kconfig +++ b/arch/arm/mach-actions/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_ACTIONS bool "Actions Semi SoCs" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-alpine/Kconfig b/arch/arm/mach-alpine/Kconfig index b41838a58ae4..e3cbb07fe1b4 100644 --- a/arch/arm/mach-alpine/Kconfig +++ b/arch/arm/mach-alpine/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_ALPINE bool "Annapurna Labs Alpine platform" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 195da38cb9a2..6d870421a7a6 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -26,6 +26,7 @@ config SOC_SAMA5D2 select HAVE_AT91_USB_CLK select HAVE_AT91_H32MX select HAVE_AT91_GENERATED_CLK + select HAVE_AT91_AUDIO_PLL select PINCTRL_AT91PIO4 help Select this if ou are using one of Atmel's SAMA5D2 family SoC. @@ -125,6 +126,9 @@ config HAVE_AT91_H32MX config HAVE_AT91_GENERATED_CLK bool +config HAVE_AT91_AUDIO_PLL + bool + config SOC_SAM_V4_V5 bool diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index ee34aa34cc51..4ea93c9df77b 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 5036f996e694..849014c01cf4 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -533,8 +533,8 @@ static void __init at91_pm_backup_init(void) } pm_bu->suspended = 0; - pm_bu->canary = virt_to_phys(&canary); - pm_bu->resume = virt_to_phys(cpu_resume); + pm_bu->canary = __pa_symbol(&canary); + pm_bu->resume = __pa_symbol(cpu_resume); return; diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c index c0a73e62b725..f2d893c03cd9 100644 --- a/arch/arm/mach-at91/pm_data-offsets.c +++ b/arch/arm/mach-at91/pm_data-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "pm.h" diff --git a/arch/arm/mach-axxia/Kconfig b/arch/arm/mach-axxia/Kconfig index fe627cbcfdc5..bb2ce1c63fd9 100644 --- a/arch/arm/mach-axxia/Kconfig +++ b/arch/arm/mach-axxia/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_AXXIA bool "LSI Axxia platforms" depends on ARCH_MULTI_V7 && ARM_LPAE diff --git a/arch/arm/mach-axxia/Makefile b/arch/arm/mach-axxia/Makefile index ec4f68b460c6..8df8fe76ad47 100644 --- a/arch/arm/mach-axxia/Makefile +++ b/arch/arm/mach-axxia/Makefile @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += axxia.o obj-$(CONFIG_SMP) += platsmp.o diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 73be3d578851..5d2925e2ce1f 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_BCM bool "Broadcom SoC Support" depends on ARCH_MULTI_V6_V7 diff --git a/arch/arm/mach-bcm/bcm63xx_smp.h b/arch/arm/mach-bcm/bcm63xx_smp.h index 9c6d50e2b111..4e742604a0fd 100644 --- a/arch/arm/mach-bcm/bcm63xx_smp.h +++ b/arch/arm/mach-bcm/bcm63xx_smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __BCM63XX_SMP_H #define __BCM63XX_SMP_H diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index f385b1fcafef..fc9188b54dd6 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_CLPS711X bool "Cirrus Logic EP721x/EP731x-based" depends on ARCH_MULTI_V4T diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile index bd0b7b5d6e9d..f18f330f5364 100644 --- a/arch/arm/mach-clps711x/Makefile +++ b/arch/arm/mach-clps711x/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += board-dt.o diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig index 5fd836be2701..1ecf5466931e 100644 --- a/arch/arm/mach-cns3xxx/Kconfig +++ b/arch/arm/mach-cns3xxx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_CNS3XXX bool "Cavium Networks CNS3XXX family" depends on ARCH_MULTI_V6 diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile index a1ff10848698..52ca6ed62304 100644 --- a/arch/arm/mach-cns3xxx/Makefile +++ b/arch/arm/mach-cns3xxx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_ARCH_CNS3XXX) += cns3xxx.o cns3xxx-y += core.o pm.o cns3xxx-$(CONFIG_ATAGS) += devices.o diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 36c8f5324e43..05c3eecf47cb 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ARCH_DAVINCI config AINTC diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index df96ca9eab6d..4e8178050027 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-davinci/Makefile.boot b/arch/arm/mach-davinci/Makefile.boot index 4b81601754a2..d36b251f325b 100644 --- a/arch/arm/mach-davinci/Makefile.boot +++ b/arch/arm/mach-davinci/Makefile.boot @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 zreladdr-$(CONFIG_ARCH_DAVINCI_DA8XX) += 0xc0008000 params_phys-$(CONFIG_ARCH_DAVINCI_DA8XX) := 0xc0000100 initrd_phys-$(CONFIG_ARCH_DAVINCI_DA8XX) := 0xc0800000 diff --git a/arch/arm/mach-davinci/asp.h b/arch/arm/mach-davinci/asp.h index 1128e1d8e4b4..495aa6907cbc 100644 --- a/arch/arm/mach-davinci/asp.h +++ b/arch/arm/mach-davinci/asp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * TI DaVinci Audio definitions */ diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index e568c8c6f69c..cbde0030c092 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index 18296a99c4d2..62e7bc3018f0 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index 284ff27c1b32..be997243447b 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 0464999b7137..e75741fb2c1d 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 70e00dbeec96..b07c9b18d427 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 1d76e7480a42..cb0a41e83582 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 41c7c9615791..d85accf7f760 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-davinci/ddr2.h b/arch/arm/mach-davinci/ddr2.h index c19e047d0e6a..4f7d7824b0c9 100644 --- a/arch/arm/mach-davinci/ddr2.h +++ b/arch/arm/mach-davinci/ddr2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define DDR2_SDRCR_OFFSET 0xc #define DDR2_SRPD_BIT (1 << 23) #define DDR2_MCLKSTOPEN_BIT (1 << 30) diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c index 9a6af0bd5dc3..d480a02e1298 100644 --- a/arch/arm/mach-davinci/usb-da8xx.c +++ b/arch/arm/mach-davinci/usb-da8xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DA8xx USB */ diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c index 0e7e89c1f331..31ed7aa47227 100644 --- a/arch/arm/mach-davinci/usb.c +++ b/arch/arm/mach-davinci/usb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * USB */ diff --git a/arch/arm/mach-digicolor/Kconfig b/arch/arm/mach-digicolor/Kconfig index 9d05c6c4181d..90394433c405 100644 --- a/arch/arm/mach-digicolor/Kconfig +++ b/arch/arm/mach-digicolor/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_DIGICOLOR bool "Conexant Digicolor SoC Support" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig index 0bd6d894c597..7747fe64420a 100644 --- a/arch/arm/mach-dove/Kconfig +++ b/arch/arm/mach-dove/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ARCH_DOVE menu "Marvell Dove Implementations" diff --git a/arch/arm/mach-dove/Makefile b/arch/arm/mach-dove/Makefile index b608a21919fb..cdf163cab738 100644 --- a/arch/arm/mach-dove/Makefile +++ b/arch/arm/mach-dove/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += common.o obj-$(CONFIG_DOVE_LEGACY) += irq.o mpp.o obj-$(CONFIG_PCI) += pcie.o diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c index bcb678fd2415..8971c3c0f0fe 100644 --- a/arch/arm/mach-dove/dove-db-setup.c +++ b/arch/arm/mach-dove/dove-db-setup.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-dove/mpp.h b/arch/arm/mach-dove/mpp.h index fbec7c52bfac..2e4b89c86ca8 100644 --- a/arch/arm/mach-dove/mpp.h +++ b/arch/arm/mach-dove/mpp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_DOVE_MPP_CODED_H #define __ARCH_DOVE_MPP_CODED_H diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c index b57980b435fd..3c44dd3596ea 100644 --- a/arch/arm/mach-ebsa110/io.c +++ b/arch/arm/mach-ebsa110/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-ebsa110/isamem.c * diff --git a/arch/arm/mach-efm32/dtmachine.c b/arch/arm/mach-efm32/dtmachine.c index 2367495193c1..e9364b843641 100644 --- a/arch/arm/mach-efm32/dtmachine.c +++ b/arch/arm/mach-efm32/dtmachine.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index b7ae4345ac08..86768495f61d 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index beec5f16443a..d2eee707d27f 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -98,6 +98,13 @@ static struct clk clk_keypad = { .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, .set_rate = set_keytchclk_rate, }; +static struct clk clk_adc = { + .parent = &clk_xtali, + .sw_locked = 1, + .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV, + .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_TSEN, + .set_rate = set_keytchclk_rate, +}; static struct clk clk_spi = { .parent = &clk_xtali, .rate = EP93XX_EXT_CLK_RATE, @@ -214,6 +221,7 @@ static struct clk_lookup clocks[] = { INIT_CK(NULL, "pll2", &clk_pll2), INIT_CK("ohci-platform", NULL, &clk_usb_host), INIT_CK("ep93xx-keypad", NULL, &clk_keypad), + INIT_CK("ep93xx-adc", NULL, &clk_adc), INIT_CK("ep93xx-fb", NULL, &clk_video), INIT_CK("ep93xx-spi.0", NULL, &clk_spi), INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk), diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index c393b1b0310d..f53c61813998 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -820,6 +820,30 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev) } EXPORT_SYMBOL(ep93xx_ide_release_gpio); +/************************************************************************* + * EP93xx ADC + *************************************************************************/ +static struct resource ep93xx_adc_resources[] = { + DEFINE_RES_MEM(EP93XX_ADC_PHYS_BASE, 0x28), + DEFINE_RES_IRQ(IRQ_EP93XX_TOUCH), +}; + +static struct platform_device ep93xx_adc_device = { + .name = "ep93xx-adc", + .id = -1, + .num_resources = ARRAY_SIZE(ep93xx_adc_resources), + .resource = ep93xx_adc_resources, +}; + +void __init ep93xx_register_adc(void) +{ + /* Power up ADC, deactivate Touch Screen Controller */ + ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_TIN, + EP93XX_SYSCON_DEVCFG_ADCPD); + + platform_device_register(&ep93xx_adc_device); +} + /************************************************************************* * EP93xx Security peripheral *************************************************************************/ diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index 0ac176386789..7a7f280b07d7 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -245,6 +245,7 @@ static void __init edb93xx_init_machine(void) edb93xx_register_pwm(); edb93xx_register_fb(); edb93xx_register_ide(); + ep93xx_register_adc(); } diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index c64d74246602..6839ea032e58 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h */ diff --git a/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h b/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h index 6d7c571a519f..242af4a401ea 100644 --- a/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h +++ b/arch/arm/mach-ep93xx/include/mach/gpio-ep93xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Include file for the EP93XX GPIO controller machine specifics */ #ifndef __GPIO_EP93XX_H diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h index efcd47815a91..8938906e780a 100644 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-ep93xx/include/mach/hardware.h */ diff --git a/arch/arm/mach-ep93xx/include/mach/irqs.h b/arch/arm/mach-ep93xx/include/mach/irqs.h index ff98390bbf0f..244daf83ce6d 100644 --- a/arch/arm/mach-ep93xx/include/mach/irqs.h +++ b/arch/arm/mach-ep93xx/include/mach/irqs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-ep93xx/include/mach/irqs.h */ diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 4c0bbd97f741..3bbe1591013e 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-ep93xx/include/mach/platform.h */ @@ -52,6 +53,7 @@ int ep93xx_i2s_acquire(void); void ep93xx_i2s_release(void); void ep93xx_register_ac97(void); void ep93xx_register_ide(void); +void ep93xx_register_adc(void); int ep93xx_ide_acquire_gpio(struct platform_device *pdev); void ep93xx_ide_release_gpio(struct platform_device *pdev); diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index b2db791b3b38..8b29398f4dc7 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h index 7bf7ff8beae7..d20e631164cf 100644 --- a/arch/arm/mach-ep93xx/soc.h +++ b/arch/arm/mach-ep93xx/soc.h @@ -95,6 +95,7 @@ #define EP93XX_KEY_MATRIX_PHYS_BASE EP93XX_APB_PHYS(0x000f0000) #define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) +#define EP93XX_ADC_PHYS_BASE EP93XX_APB_PHYS(0x00100000) #define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) #define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c index 874cbc91b669..de998830f534 100644 --- a/arch/arm/mach-ep93xx/timer-ep93xx.c +++ b/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 55b186ef863a..8745162ec05d 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-ep93xx/ts72xx.h b/arch/arm/mach-ep93xx/ts72xx.h index 2255ba29fdd6..b89850f1a965 100644 --- a/arch/arm/mach-ep93xx/ts72xx.h +++ b/arch/arm/mach-ep93xx/ts72xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-ep93xx/include/mach/ts72xx.h */ diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S index cf950790fbdc..4292cae43f3c 100644 --- a/arch/arm/mach-exynos/sleep.S +++ b/arch/arm/mach-exynos/sleep.S @@ -124,6 +124,7 @@ _cp15_save_diag: #endif /* CONFIG_CACHE_L2X0 */ .data + .align 2 .globl cp15_save_diag cp15_save_diag: .long 0 @ cp15 diagnostic diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 748cfb8d5212..b529ba04ed16 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -187,21 +187,20 @@ static int __init exynos_pmu_irq_init(struct device_node *node, struct irq_domain *parent_domain, *domain; if (!parent) { - pr_err("%s: no parent, giving up\n", node->full_name); + pr_err("%pOF: no parent, giving up\n", node); return -ENODEV; } parent_domain = irq_find_host(parent); if (!parent_domain) { - pr_err("%s: unable to obtain parent domain\n", node->full_name); + pr_err("%pOF: unable to obtain parent domain\n", node); return -ENXIO; } pmu_base_addr = of_iomap(node, 0); if (!pmu_base_addr) { - pr_err("%s: failed to find exynos pmu register\n", - node->full_name); + pr_err("%pOF: failed to find exynos pmu register\n", node); return -ENOMEM; } diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index e83d5c8396ff..a09f1041f141 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c index 8f05489671b7..e575dc0698cd 100644 --- a/arch/arm/mach-footbridge/cats-hw.c +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/cats-hw.c * diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c index 5cec2567c9c5..0b2fd7e2e9b4 100644 --- a/arch/arm/mach-footbridge/cats-pci.c +++ b/arch/arm/mach-footbridge/cats-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/cats-pci.c * diff --git a/arch/arm/mach-footbridge/common.h b/arch/arm/mach-footbridge/common.h index b911e5587ecf..e12587db59c4 100644 --- a/arch/arm/mach-footbridge/common.h +++ b/arch/arm/mach-footbridge/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include extern void footbridge_timer_init(void); diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c index 75395a720e63..f76212d2dbf1 100644 --- a/arch/arm/mach-footbridge/dc21285-timer.c +++ b/arch/arm/mach-footbridge/dc21285-timer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/dc21285-timer.c * diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c index 22536b85a81d..86618074a7a5 100644 --- a/arch/arm/mach-footbridge/dma.c +++ b/arch/arm/mach-footbridge/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/kernel/dma-ebsa285.c * diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c index fd12d8a36dc5..6f28aaa9ca79 100644 --- a/arch/arm/mach-footbridge/ebsa285-pci.c +++ b/arch/arm/mach-footbridge/ebsa285-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/ebsa285-pci.c * diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index aee8300f3490..21cf9a358b90 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/ebsa285.c * diff --git a/arch/arm/mach-footbridge/include/mach/irqs.h b/arch/arm/mach-footbridge/include/mach/irqs.h index 61c714c4920e..a5f41846ab9c 100644 --- a/arch/arm/mach-footbridge/include/mach/irqs.h +++ b/arch/arm/mach-footbridge/include/mach/irqs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-footbridge/include/mach/irqs.h * diff --git a/arch/arm/mach-footbridge/include/mach/isa-dma.h b/arch/arm/mach-footbridge/include/mach/isa-dma.h index 5bd4a0d338a8..8a1b991076e1 100644 --- a/arch/arm/mach-footbridge/include/mach/isa-dma.h +++ b/arch/arm/mach-footbridge/include/mach/isa-dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-footbridge/include/mach/isa-dma.h * diff --git a/arch/arm/mach-footbridge/isa-rtc.c b/arch/arm/mach-footbridge/isa-rtc.c index 07fde4051f78..b8f741a3a37e 100644 --- a/arch/arm/mach-footbridge/isa-rtc.c +++ b/arch/arm/mach-footbridge/isa-rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-footbridge/isa-rtc.c * diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c index b73f52e196b9..82f45591fb2c 100644 --- a/arch/arm/mach-footbridge/isa-timer.c +++ b/arch/arm/mach-footbridge/isa-timer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/isa-timer.c * diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index cdee08c6d239..5f7265b1b34c 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/netwinder-hw.c * diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c index 0fba5134e4fe..9473aa0305e5 100644 --- a/arch/arm/mach-footbridge/netwinder-pci.c +++ b/arch/arm/mach-footbridge/netwinder-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/netwinder-pci.c * diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c index 5c9ee54613b2..4391e433a4b2 100644 --- a/arch/arm/mach-footbridge/personal-pci.c +++ b/arch/arm/mach-footbridge/personal-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/personal-pci.c * diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c index 7bdeabdcd4d8..ca715754fc00 100644 --- a/arch/arm/mach-footbridge/personal.c +++ b/arch/arm/mach-footbridge/personal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-footbridge/personal.c * diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig index 06c8b095154c..70106b67631c 100644 --- a/arch/arm/mach-gemini/Kconfig +++ b/arch/arm/mach-gemini/Kconfig @@ -1,11 +1,16 @@ menuconfig ARCH_GEMINI bool "Cortina Systems Gemini" depends on ARCH_MULTI_V4 + select ARCH_HAS_RESET_CONTROLLER + select ARM_AMBA select ARM_APPENDED_DTB # Old Redboot bootloaders deployed + select COMMON_CLK_GEMINI select FARADAY_FTINTC010 select FTTMR010_TIMER select GPIO_FTGPIO010 select GPIOLIB + select PINCTRL + select PINCTRL_GEMINI select POWER_RESET select POWER_RESET_GEMINI_POWEROFF select POWER_RESET_SYSCON diff --git a/arch/arm/mach-gemini/board-dt.c b/arch/arm/mach-gemini/board-dt.c index c0c0ebdd551e..de0afcc8d94a 100644 --- a/arch/arm/mach-gemini/board-dt.c +++ b/arch/arm/mach-gemini/board-dt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Gemini Device Tree boot support */ diff --git a/arch/arm/mach-highbank/core.h b/arch/arm/mach-highbank/core.h index 7ec5edcd1336..3991a6594ae5 100644 --- a/arch/arm/mach-highbank/core.h +++ b/arch/arm/mach-highbank/core.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __HIGHBANK_CORE_H #define __HIGHBANK_CORE_H diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig index a3b091a4d344..65a048fa08ec 100644 --- a/arch/arm/mach-hisi/Kconfig +++ b/arch/arm/mach-hisi/Kconfig @@ -39,6 +39,7 @@ config ARCH_HIP04 select HAVE_ARM_ARCH_TIMER select MCPM if SMP select MCPM_QUAD_CLUSTER if SMP + select GENERIC_IRQ_EFFECTIVE_AFF_MASK help Support for Hisilicon HiP04 SoC family diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h index c58b68ab0cb6..61245274fdaf 100644 --- a/arch/arm/mach-hisi/core.h +++ b/arch/arm/mach-hisi/core.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __HISILICON_CORE_H #define __HISILICON_CORE_H diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c index 91bb02dec20f..da5689ababf7 100644 --- a/arch/arm/mach-hisi/platsmp.c +++ b/arch/arm/mach-hisi/platsmp.c @@ -109,7 +109,7 @@ static void hix5hd2_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_a virt = ioremap(start_addr, PAGE_SIZE); - writel_relaxed(0xe51ff004, virt); /* ldr pc, [rc, #-4] */ + writel_relaxed(0xe51ff004, virt); /* ldr pc, [pc, #-4] */ writel_relaxed(jump_addr, virt + 4); /* pc jump phy address */ iounmap(virt); } diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index cab128913e72..8ff71058207d 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y := cpu.o system.o irq-common.o obj-$(CONFIG_SOC_IMX21) += mm-imx21.o diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 94906ed49392..d4e55f2a897e 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile index aa6cee870795..e44758aaa11c 100644 --- a/arch/arm/mach-imx/devices/Makefile +++ b/arch/arm/mach-imx/devices/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y := devices.o obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o diff --git a/arch/arm/mach-imx/ehci.h b/arch/arm/mach-imx/ehci.h index 0e060023db8b..b7ad6175f5bf 100644 --- a/arch/arm/mach-imx/ehci.h +++ b/arch/arm/mach-imx/ehci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_IMX_EHCI_H #define __MACH_IMX_EHCI_H diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 93f584ba0130..de535cb679b3 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -224,13 +224,13 @@ static int __init imx_gpc_init(struct device_node *node, int i; if (!parent) { - pr_err("%s: no parent, giving up\n", node->full_name); + pr_err("%pOF: no parent, giving up\n", node); return -ENODEV; } parent_domain = irq_find_host(parent); if (!parent_domain) { - pr_err("%s: unable to obtain parent domain\n", node->full_name); + pr_err("%pOF: unable to obtain parent domain\n", node); return -ENXIO; } diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index dd75a4756761..5169dfba9718 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -245,7 +245,6 @@ static phys_addr_t mx2_camera_base __initdata; static void __init visstrim_analog_camera_init(void) { struct platform_device *pdev; - int dma; gpio_set_value(TVP5150_PWDN, 1); ndelay(1); @@ -258,12 +257,9 @@ static void __init visstrim_analog_camera_init(void) if (IS_ERR(pdev)) return; - dma = dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base, mx2_camera_base, - MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) - return; + dma_declare_coherent_memory(&pdev->dev, mx2_camera_base, + mx2_camera_base, MX2_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); } static void __init visstrim_reserve(void) @@ -444,16 +440,13 @@ static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = { static void __init visstrim_coda_init(void) { struct platform_device *pdev; - int dma; pdev = imx27_add_coda(); - dma = dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base + MX2_CAMERA_BUF_SIZE, - mx2_camera_base + MX2_CAMERA_BUF_SIZE, - MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) - return; + dma_declare_coherent_memory(&pdev->dev, + mx2_camera_base + MX2_CAMERA_BUF_SIZE, + mx2_camera_base + MX2_CAMERA_BUF_SIZE, + MX2_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); } /* DMA deinterlace */ @@ -466,24 +459,21 @@ static void __init visstrim_deinterlace_init(void) { int ret = -ENOMEM; struct platform_device *pdev = &visstrim_deinterlace; - int dma; ret = platform_device_register(pdev); - dma = dma_declare_coherent_memory(&pdev->dev, - mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, - mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, - MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) - return; + dma_declare_coherent_memory(&pdev->dev, + mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, + mx2_camera_base + 2 * MX2_CAMERA_BUF_SIZE, + MX2_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); } /* Emma-PrP for format conversion */ static void __init visstrim_emmaprp_init(void) { struct platform_device *pdev; - int dma; + int ret; pdev = imx27_add_mx2_emmaprp(); if (IS_ERR(pdev)) @@ -493,11 +483,11 @@ static void __init visstrim_emmaprp_init(void) * Use the same memory area as the analog camera since both * devices are, by nature, exclusive. */ - dma = dma_declare_coherent_memory(&pdev->dev, + ret = dma_declare_coherent_memory(&pdev->dev, mx2_camera_base, mx2_camera_base, MX2_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) + DMA_MEMORY_EXCLUSIVE); + if (ret) pr_err("Failed to declare memory for emmaprp\n"); } diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index bde9a9af6714..7716f83aecdd 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -475,7 +475,7 @@ static phys_addr_t mx3_camera_base __initdata; static int __init mx31moboard_init_cam(void) { - int dma, ret = -ENOMEM; + int ret; struct platform_device *pdev; imx31_add_ipu_core(); @@ -484,11 +484,11 @@ static int __init mx31moboard_init_cam(void) if (IS_ERR(pdev)) return PTR_ERR(pdev); - dma = dma_declare_coherent_memory(&pdev->dev, - mx3_camera_base, mx3_camera_base, - MX3_CAMERA_BUF_SIZE, - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); - if (!(dma & DMA_MEMORY_MAP)) + ret = dma_declare_coherent_memory(&pdev->dev, + mx3_camera_base, mx3_camera_base, + MX3_CAMERA_BUF_SIZE, + DMA_MEMORY_EXCLUSIVE); + if (ret) goto err; ret = platform_device_add(pdev); diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 8c2cbd693d21..42a700053103 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-imx/mx31.h b/arch/arm/mach-imx/mx31.h index ee9b1f9215df..d9574671ca5c 100644 --- a/arch/arm/mach-imx/mx31.h +++ b/arch/arm/mach-imx/mx31.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_MX31_H__ #define __MACH_MX31_H__ diff --git a/arch/arm/mach-imx/mx35.h b/arch/arm/mach-imx/mx35.h index 2af5d3a699c7..760de6a0af7e 100644 --- a/arch/arm/mach-imx/mx35.h +++ b/arch/arm/mach-imx/mx35.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_MX35_H__ #define __MACH_MX35_H__ diff --git a/arch/arm/mach-imx/pcm037.h b/arch/arm/mach-imx/pcm037.h index 7d167690e17d..470d3c887e14 100644 --- a/arch/arm/mach-imx/pcm037.h +++ b/arch/arm/mach-imx/pcm037.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PCM037_H__ #define __PCM037_H__ diff --git a/arch/arm/mach-imx/ulpi.h b/arch/arm/mach-imx/ulpi.h index 23f5c0349e80..b367902c9c32 100644 --- a/arch/arm/mach-imx/ulpi.h +++ b/arch/arm/mach-imx/ulpi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_ULPI_H #define __MACH_ULPI_H diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index 1ebe45356b09..a5a4470db482 100644 --- a/arch/arm/mach-integrator/Makefile +++ b/arch/arm/mach-integrator/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-integrator/cm.h b/arch/arm/mach-integrator/cm.h index 5b8ba8247f45..f09ea18a50f8 100644 --- a/arch/arm/mach-integrator/cm.h +++ b/arch/arm/mach-integrator/cm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * access the core module control register. */ diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index 96c9dc56cabf..f053aeebeb7a 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include extern struct amba_pl010_data ap_uart_data; diff --git a/arch/arm/mach-integrator/impd1.h b/arch/arm/mach-integrator/impd1.h index 76de4dc9bee4..36124d34c8f7 100644 --- a/arch/arm/mach-integrator/impd1.h +++ b/arch/arm/mach-integrator/impd1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define IMPD1_LEDS 0x0c #define IMPD1_INT 0x10 #define IMPD1_SW 0x14 diff --git a/arch/arm/mach-integrator/lm.h b/arch/arm/mach-integrator/lm.h index 28186b6f2c09..172966a699bd 100644 --- a/arch/arm/mach-integrator/lm.h +++ b/arch/arm/mach-integrator/lm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ struct lm_device { struct device dev; diff --git a/arch/arm/mach-integrator/pci_v3.h b/arch/arm/mach-integrator/pci_v3.h index 06a9e2e7d007..cafc7174baab 100644 --- a/arch/arm/mach-integrator/pci_v3.h +++ b/arch/arm/mach-integrator/pci_v3.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Simple oneliner include to the PCIv3 early init */ #ifdef CONFIG_PCI extern int pci_v3_early_init(void); diff --git a/arch/arm/mach-iop13xx/Kconfig b/arch/arm/mach-iop13xx/Kconfig index 40c2d689f2eb..c4f04070b4c1 100644 --- a/arch/arm/mach-iop13xx/Kconfig +++ b/arch/arm/mach-iop13xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ARCH_IOP13XX menu "IOP13XX Implementation Options" diff --git a/arch/arm/mach-iop13xx/Makefile b/arch/arm/mach-iop13xx/Makefile index a3d9260e335f..5757c8f6e371 100644 --- a/arch/arm/mach-iop13xx/Makefile +++ b/arch/arm/mach-iop13xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_ARCH_IOP13XX) += setup.o obj-$(CONFIG_ARCH_IOP13XX) += irq.o obj-$(CONFIG_ARCH_IOP13XX) += pci.o diff --git a/arch/arm/mach-iop13xx/include/mach/hardware.h b/arch/arm/mach-iop13xx/include/mach/hardware.h index 786fa266fab3..8c943fa6bbd7 100644 --- a/arch/arm/mach-iop13xx/include/mach/hardware.h +++ b/arch/arm/mach-iop13xx/include/mach/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H #include diff --git a/arch/arm/mach-iop13xx/include/mach/iop13xx.h b/arch/arm/mach-iop13xx/include/mach/iop13xx.h index 9311ee2126d6..04bb6aca12c5 100644 --- a/arch/arm/mach-iop13xx/include/mach/iop13xx.h +++ b/arch/arm/mach-iop13xx/include/mach/iop13xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IOP13XX_HW_H_ #define _IOP13XX_HW_H_ diff --git a/arch/arm/mach-iop13xx/include/mach/iq81340.h b/arch/arm/mach-iop13xx/include/mach/iq81340.h index ba2cf931e9ce..d7ad27a95558 100644 --- a/arch/arm/mach-iop13xx/include/mach/iq81340.h +++ b/arch/arm/mach-iop13xx/include/mach/iq81340.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IQ81340_H_ #define _IQ81340_H_ diff --git a/arch/arm/mach-iop13xx/include/mach/irqs.h b/arch/arm/mach-iop13xx/include/mach/irqs.h index e8d24d32121a..cd6b6375c050 100644 --- a/arch/arm/mach-iop13xx/include/mach/irqs.h +++ b/arch/arm/mach-iop13xx/include/mach/irqs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IOP13XX_IRQS_H_ #define _IOP13XX_IRQS_H_ diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h index 59307e787588..32da0e09c6a3 100644 --- a/arch/arm/mach-iop13xx/include/mach/memory.h +++ b/arch/arm/mach-iop13xx/include/mach/memory.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_MEMORY_H #define __ASM_ARCH_MEMORY_H diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h index c871e6874594..2c2d7532d5c3 100644 --- a/arch/arm/mach-iop13xx/include/mach/time.h +++ b/arch/arm/mach-iop13xx/include/mach/time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IOP13XX_TIME_H_ #define _IOP13XX_TIME_H_ diff --git a/arch/arm/mach-iop13xx/include/mach/uncompress.h b/arch/arm/mach-iop13xx/include/mach/uncompress.h index d3791ece2772..c62903041d11 100644 --- a/arch/arm/mach-iop13xx/include/mach/uncompress.h +++ b/arch/arm/mach-iop13xx/include/mach/uncompress.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/arm/mach-iop13xx/msi.h b/arch/arm/mach-iop13xx/msi.h index b80c5ae17e99..766dcfaaa353 100644 --- a/arch/arm/mach-iop13xx/msi.h +++ b/arch/arm/mach-iop13xx/msi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IOP13XX_MSI_H_ #define _IOP13XX_MSI_H_ #ifdef CONFIG_PCI_MSI diff --git a/arch/arm/mach-iop13xx/pci.h b/arch/arm/mach-iop13xx/pci.h index 8dc343cb887a..736168d8c7ac 100644 --- a/arch/arm/mach-iop13xx/pci.h +++ b/arch/arm/mach-iop13xx/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IOP13XX_PCI_H_ #define _IOP13XX_PCI_H_ #include diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig index 5e8c6f7dfabb..f1f342cb0509 100644 --- a/arch/arm/mach-iop32x/Kconfig +++ b/arch/arm/mach-iop32x/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ARCH_IOP32X menu "IOP32x Implementation Options" diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile index 2d4010abb82f..71d62447d4d5 100644 --- a/arch/arm/mach-iop32x/Makefile +++ b/arch/arm/mach-iop32x/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-iop32x/gpio-iop32x.h b/arch/arm/mach-iop32x/gpio-iop32x.h index 3c7309c02029..20af87e4c5e8 100644 --- a/arch/arm/mach-iop32x/gpio-iop32x.h +++ b/arch/arm/mach-iop32x/gpio-iop32x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ static struct resource iop32x_gpio_res[] = { DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x07c4), 0x10), }; diff --git a/arch/arm/mach-iop32x/include/mach/adma.h b/arch/arm/mach-iop32x/include/mach/adma.h index 5ed92037dd10..2b20063123ad 100644 --- a/arch/arm/mach-iop32x/include/mach/adma.h +++ b/arch/arm/mach-iop32x/include/mach/adma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef IOP32X_ADMA_H #define IOP32X_ADMA_H #include diff --git a/arch/arm/mach-iop32x/include/mach/glantank.h b/arch/arm/mach-iop32x/include/mach/glantank.h index 958eb91c0913..b9df2e4614cf 100644 --- a/arch/arm/mach-iop32x/include/mach/glantank.h +++ b/arch/arm/mach-iop32x/include/mach/glantank.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop32x/include/mach/glantank.h * diff --git a/arch/arm/mach-iop32x/include/mach/hardware.h b/arch/arm/mach-iop32x/include/mach/hardware.h index 48cb1b20ba91..6e5303e60226 100644 --- a/arch/arm/mach-iop32x/include/mach/hardware.h +++ b/arch/arm/mach-iop32x/include/mach/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop32x/include/mach/hardware.h */ diff --git a/arch/arm/mach-iop32x/include/mach/iq31244.h b/arch/arm/mach-iop32x/include/mach/iq31244.h index 6b6b369e781c..e62da5da6ed4 100644 --- a/arch/arm/mach-iop32x/include/mach/iq31244.h +++ b/arch/arm/mach-iop32x/include/mach/iq31244.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop32x/include/mach/iq31244.h * diff --git a/arch/arm/mach-iop32x/include/mach/iq80321.h b/arch/arm/mach-iop32x/include/mach/iq80321.h index 498819b737e7..faf62c26f6f8 100644 --- a/arch/arm/mach-iop32x/include/mach/iq80321.h +++ b/arch/arm/mach-iop32x/include/mach/iq80321.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop32x/include/mach/iq80321.h * diff --git a/arch/arm/mach-iop32x/include/mach/n2100.h b/arch/arm/mach-iop32x/include/mach/n2100.h index 40b8a532b064..70bb660b643a 100644 --- a/arch/arm/mach-iop32x/include/mach/n2100.h +++ b/arch/arm/mach-iop32x/include/mach/n2100.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop32x/include/mach/n2100.h * diff --git a/arch/arm/mach-iop32x/include/mach/time.h b/arch/arm/mach-iop32x/include/mach/time.h index 0f28c9949623..d08950ccebc4 100644 --- a/arch/arm/mach-iop32x/include/mach/time.h +++ b/arch/arm/mach-iop32x/include/mach/time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IOP32X_TIME_H_ #define _IOP32X_TIME_H_ #define IRQ_IOP_TIMER0 IRQ_IOP32X_TIMER0 diff --git a/arch/arm/mach-iop32x/include/mach/uncompress.h b/arch/arm/mach-iop32x/include/mach/uncompress.h index b3d45fd365e7..ed4ac3e28fa1 100644 --- a/arch/arm/mach-iop32x/include/mach/uncompress.h +++ b/arch/arm/mach-iop32x/include/mach/uncompress.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop32x/include/mach/uncompress.h */ diff --git a/arch/arm/mach-iop33x/include/mach/adma.h b/arch/arm/mach-iop33x/include/mach/adma.h index 4b92f795f90e..8aa7159ab6d8 100644 --- a/arch/arm/mach-iop33x/include/mach/adma.h +++ b/arch/arm/mach-iop33x/include/mach/adma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef IOP33X_ADMA_H #define IOP33X_ADMA_H #include diff --git a/arch/arm/mach-iop33x/include/mach/hardware.h b/arch/arm/mach-iop33x/include/mach/hardware.h index 839285315e4e..020bafbc36a5 100644 --- a/arch/arm/mach-iop33x/include/mach/hardware.h +++ b/arch/arm/mach-iop33x/include/mach/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop33x/include/mach/hardware.h */ diff --git a/arch/arm/mach-iop33x/include/mach/iq80331.h b/arch/arm/mach-iop33x/include/mach/iq80331.h index fe406b0127f7..c7e68d863e44 100644 --- a/arch/arm/mach-iop33x/include/mach/iq80331.h +++ b/arch/arm/mach-iop33x/include/mach/iq80331.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop33x/include/mach/iq80331.h * diff --git a/arch/arm/mach-iop33x/include/mach/iq80332.h b/arch/arm/mach-iop33x/include/mach/iq80332.h index 8325d71f2ed5..749b44bf7f62 100644 --- a/arch/arm/mach-iop33x/include/mach/iq80332.h +++ b/arch/arm/mach-iop33x/include/mach/iq80332.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop33x/include/mach/iq80332.h * diff --git a/arch/arm/mach-iop33x/include/mach/time.h b/arch/arm/mach-iop33x/include/mach/time.h index 4ac4d7664f85..801f8fd644ad 100644 --- a/arch/arm/mach-iop33x/include/mach/time.h +++ b/arch/arm/mach-iop33x/include/mach/time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IOP33X_TIME_H_ #define _IOP33X_TIME_H_ #define IRQ_IOP_TIMER0 IRQ_IOP33X_TIMER0 diff --git a/arch/arm/mach-iop33x/include/mach/uncompress.h b/arch/arm/mach-iop33x/include/mach/uncompress.h index ed282e14176d..62b71cde1f79 100644 --- a/arch/arm/mach-iop33x/include/mach/uncompress.h +++ b/arch/arm/mach-iop33x/include/mach/uncompress.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-iop33x/include/mach/uncompress.h */ diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index eded94c96dd4..f09994500a34 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c index 6beec150c060..186df64ceae7 100644 --- a/arch/arm/mach-ixp4xx/avila-setup.c +++ b/arch/arm/mach-ixp4xx/avila-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/avila-setup.c * diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 820cae8608fc..7e40fe70933b 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/coyote-setup.c * diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c index b3bd0e137f6d..db488ecc98b5 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-setup.c +++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DSM-G600 board-setup * diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c index 5c4b0c4a1b37..6e32cbc4f590 100644 --- a/arch/arm/mach-ixp4xx/fsg-setup.c +++ b/arch/arm/mach-ixp4xx/fsg-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/fsg-setup.c * diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c index 3d24b3fcee87..1be6faf6da9a 100644 --- a/arch/arm/mach-ixp4xx/gateway7001-setup.c +++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/gateway7001-setup.c * diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c index 80bd9d6d04de..145ec5c1b0eb 100644 --- a/arch/arm/mach-ixp4xx/goramo_mlr.c +++ b/arch/arm/mach-ixp4xx/goramo_mlr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Goramo MultiLink router platform code * Copyright (C) 2006-2009 Krzysztof Halasa diff --git a/arch/arm/mach-ixp4xx/include/mach/npe.h b/arch/arm/mach-ixp4xx/include/mach/npe.h index e320db2457ae..3a980845e557 100644 --- a/arch/arm/mach-ixp4xx/include/mach/npe.h +++ b/arch/arm/mach-ixp4xx/include/mach/npe.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __IXP4XX_NPE_H #define __IXP4XX_NPE_H diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h index 34b3d3f3f131..342acbe20f7c 100644 --- a/arch/arm/mach-ixp4xx/include/mach/platform.h +++ b/arch/arm/mach-ixp4xx/include/mach/platform.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-ixp4xx/include/mach/platform.h * diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 508c2d7786e2..8f5e01527b1b 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/ixdp425-setup.c * @@ -17,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index 4e0f762bc651..1b8170d65c74 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/nas100d-setup.c * diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 88c025f52d8d..bd8dc65b4ffc 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/nslu2-setup.c * diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c index d599e354ca57..731fb2019ecb 100644 --- a/arch/arm/mach-ixp4xx/vulcan-setup.c +++ b/arch/arm/mach-ixp4xx/vulcan-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/vulcan-setup.c * diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c index 8f9ea2f3a9a5..90b3c604e8b6 100644 --- a/arch/arm/mach-ixp4xx/wg302v2-setup.c +++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/arm/mach-ixp4xx/wg302-setup.c * diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile index 25d92396fbfa..f8b0dccac8dc 100644 --- a/arch/arm/mach-keystone/Makefile +++ b/arch/arm/mach-keystone/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y := keystone.o smc.o plus_sec := $(call as-instr,.arch_extension sec,+sec) diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile index 8ecb7973ae54..439b22255a32 100644 --- a/arch/arm/mach-ks8695/Makefile +++ b/arch/arm/mach-ks8695/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # arch/arm/mach-ks8695/Makefile # # Makefile for KS8695 architecture support diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c index c3cf215773b2..6910b4e0d913 100644 --- a/arch/arm/mach-mediatek/mediatek.c +++ b/arch/arm/mach-mediatek/mediatek.c @@ -30,6 +30,7 @@ static void __init mediatek_timer_init(void) if (of_machine_is_compatible("mediatek,mt6589") || of_machine_is_compatible("mediatek,mt7623") || + of_machine_is_compatible("mediatek,mt7623a") || of_machine_is_compatible("mediatek,mt8135") || of_machine_is_compatible("mediatek,mt8127")) { /* turn on GPT6 which ungates arch timer clocks */ @@ -49,6 +50,7 @@ static const char * const mediatek_board_dt_compat[] = { "mediatek,mt6589", "mediatek,mt6592", "mediatek,mt7623", + "mediatek,mt7623a", "mediatek,mt8127", "mediatek,mt8135", NULL, diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index 726eb69bb655..27d78c945caf 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -59,6 +59,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { static const struct of_device_id mtk_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot }, + { .compatible = "mediatek,mt7623a", .data = &mtk_mt7623_boot }, }; static void __iomem *mtk_smp_base; diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index 7677ad5414e9..8f267c7bc6e8 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Marvell's PXA168 processors line # diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index 5db0edf716dd..d2283009a5ff 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-mmp/clock-mmp2.c b/arch/arm/mach-mmp/clock-mmp2.c index 835c3e7cc67e..7536398bf1c1 100644 --- a/arch/arm/mach-mmp/clock-mmp2.c +++ b/arch/arm/mach-mmp/clock-mmp2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-mmp/clock-pxa168.c b/arch/arm/mach-mmp/clock-pxa168.c index f726a3692431..2d4a5d96a1ff 100644 --- a/arch/arm/mach-mmp/clock-pxa168.c +++ b/arch/arm/mach-mmp/clock-pxa168.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-mmp/clock-pxa910.c b/arch/arm/mach-mmp/clock-pxa910.c index bca60a224e07..3cd83ff91bb0 100644 --- a/arch/arm/mach-mmp/clock-pxa910.c +++ b/arch/arm/mach-mmp/clock-pxa910.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h index 7453a90c34bd..7e284d9c429f 100644 --- a/arch/arm/mach-mmp/common.h +++ b/arch/arm/mach-mmp/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) diff --git a/arch/arm/mach-mmp/cputype.h b/arch/arm/mach-mmp/cputype.h index 8a3b56dfd35d..446edaeb78a7 100644 --- a/arch/arm/mach-mmp/cputype.h +++ b/arch/arm/mach-mmp/cputype.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_CPUTYPE_H #define __ASM_MACH_CPUTYPE_H diff --git a/arch/arm/mach-mmp/devices.h b/arch/arm/mach-mmp/devices.h index 21217ef11b64..4df596c5c201 100644 --- a/arch/arm/mach-mmp/devices.h +++ b/arch/arm/mach-mmp/devices.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_DEVICE_H #define __MACH_DEVICE_H diff --git a/arch/arm/mach-mmp/irqs.h b/arch/arm/mach-mmp/irqs.h index fb492a50a817..5acc4d532a43 100644 --- a/arch/arm/mach-mmp/irqs.h +++ b/arch/arm/mach-mmp/irqs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_IRQS_H #define __ASM_MACH_IRQS_H diff --git a/arch/arm/mach-mmp/mfp-mmp2.h b/arch/arm/mach-mmp/mfp-mmp2.h index b2744349725d..1620222981e3 100644 --- a/arch/arm/mach-mmp/mfp-mmp2.h +++ b/arch/arm/mach-mmp/mfp-mmp2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_MFP_MMP2_H #define __ASM_MACH_MFP_MMP2_H diff --git a/arch/arm/mach-mmp/mfp-pxa168.h b/arch/arm/mach-mmp/mfp-pxa168.h index 9050d032377e..90d16d3419a4 100644 --- a/arch/arm/mach-mmp/mfp-pxa168.h +++ b/arch/arm/mach-mmp/mfp-pxa168.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_MFP_PXA168_H #define __ASM_MACH_MFP_PXA168_H diff --git a/arch/arm/mach-mmp/mfp-pxa910.h b/arch/arm/mach-mmp/mfp-pxa910.h index f06db5cd3ad3..6f900cade631 100644 --- a/arch/arm/mach-mmp/mfp-pxa910.h +++ b/arch/arm/mach-mmp/mfp-pxa910.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_MFP_PXA910_H #define __ASM_MACH_MFP_PXA910_H diff --git a/arch/arm/mach-mmp/mfp.h b/arch/arm/mach-mmp/mfp.h index 62e510e80a58..75a4acb33b1b 100644 --- a/arch/arm/mach-mmp/mfp.h +++ b/arch/arm/mach-mmp/mfp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_MFP_H #define __ASM_MACH_MFP_H diff --git a/arch/arm/mach-mmp/mmp2.h b/arch/arm/mach-mmp/mmp2.h index 9b5e75ee9e4d..a4b82f719de1 100644 --- a/arch/arm/mach-mmp/mmp2.h +++ b/arch/arm/mach-mmp/mmp2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_MMP2_H #define __ASM_MACH_MMP2_H diff --git a/arch/arm/mach-mmp/pxa168.h b/arch/arm/mach-mmp/pxa168.h index 75841e9ccd73..b39bff37ff11 100644 --- a/arch/arm/mach-mmp/pxa168.h +++ b/arch/arm/mach-mmp/pxa168.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_PXA168_H #define __ASM_MACH_PXA168_H diff --git a/arch/arm/mach-mmp/pxa910.h b/arch/arm/mach-mmp/pxa910.h index a211e81e5a08..cb3923dcf580 100644 --- a/arch/arm/mach-mmp/pxa910.h +++ b/arch/arm/mach-mmp/pxa910.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_PXA910_H #define __ASM_MACH_PXA910_H diff --git a/arch/arm/mach-mv78xx0/Makefile b/arch/arm/mach-mv78xx0/Makefile index ddb3aa98a3c7..a839e960b8c6 100644 --- a/arch/arm/mach-mv78xx0/Makefile +++ b/arch/arm/mach-mv78xx0/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-orion/include obj-y += common.o mpp.o irq.o pcie.o diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 541647f57192..9b49867154bf 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -60,6 +60,8 @@ config MACH_ARMADA_38X select ARM_ERRATA_720789 select ARM_ERRATA_753970 select ARM_GIC + select ARM_GLOBAL_TIMER + select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK select ARMADA_370_XP_IRQ select ARMADA_38X_CLK select HAVE_ARM_SCU diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 6c6497e80a7b..cb106899dd7c 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-orion/include AFLAGS_coherency_ll.o := -Wa,-march=armv7-a diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c index 7d9f2fd9e450..0aa88105d46e 100644 --- a/arch/arm/mach-mvebu/kirkwood.c +++ b/arch/arm/mach-mvebu/kirkwood.c @@ -107,8 +107,7 @@ static void __init kirkwood_dt_eth_fixup(void) clk_prepare_enable(clk); /* store MAC address register contents in local-mac-address */ - pr_err(FW_INFO "%s: local-mac-address is not set\n", - np->full_name); + pr_err(FW_INFO "%pOF: local-mac-address is not set\n", np); pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL); if (!pmac) diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index 0e8ea95ea822..e8ccf51c6f29 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index fad95b74bb65..b93ad58b0a63 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c index 357be2debc9d..91bda9c802ff 100644 --- a/arch/arm/mach-omap1/board-h2-mmc.c +++ b/arch/arm/mach-omap1/board-h2-mmc.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "board-h2.h" #include "mmc.h" diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 675254ee4b1e..6a38c7603064 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -24,11 +24,11 @@ #include #include #include -#include +#include #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c index 4f58bfa5e754..692c267a9a90 100644 --- a/arch/arm/mach-omap1/board-h3-mmc.c +++ b/arch/arm/mach-omap1/board-h3-mmc.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include "common.h" #include "board-h3.h" diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index e62f9d454f10..302260583e8e 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -23,12 +23,12 @@ #include #include #include -#include +#include #include #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/board-nand.c b/arch/arm/mach-omap1/board-nand.c index 7684f9203474..1bffbb4e050f 100644 --- a/arch/arm/mach-omap1/board-nand.c +++ b/arch/arm/mach-omap1/board-nand.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "common.h" diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index ee8d9f553db4..06243c0b12d2 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -233,10 +233,10 @@ static struct platform_device nokia770_cbus_device = { static struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = { { - I2C_BOARD_INFO("retu-mfd", 0x01), + I2C_BOARD_INFO("retu", 0x01), }, { - I2C_BOARD_INFO("tahvo-mfd", 0x02), + I2C_BOARD_INFO("tahvo", 0x02), }, }; diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 95ac1929aede..d579f4e04137 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 150b57ba42bf..e994a78bdd09 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap1/camera.h b/arch/arm/mach-omap1/camera.h index caa6c0d6f0ac..8018f410d024 100644 --- a/arch/arm/mach-omap1/camera.h +++ b/arch/arm/mach-omap1/camera.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_CAMERA_H_ #define __ASM_ARCH_CAMERA_H_ diff --git a/arch/arm/mach-omap1/include/mach/memory.h b/arch/arm/mach-omap1/include/mach/memory.h index d43ff0f1cbf8..1142560e0078 100644 --- a/arch/arm/mach-omap1/include/mach/memory.h +++ b/arch/arm/mach-omap1/include/mach/memory.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-omap1/include/mach/memory.h */ diff --git a/arch/arm/mach-omap1/include/mach/usb.h b/arch/arm/mach-omap1/include/mach/usb.h index eb76628ff843..77867778d4ec 100644 --- a/arch/arm/mach-omap1/include/mach/usb.h +++ b/arch/arm/mach-omap1/include/mach/usb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * FIXME correct answer depends on hmc_mode, * as does (on omap1) any nonzero value for config->otg port number diff --git a/arch/arm/mach-omap1/mmc.h b/arch/arm/mach-omap1/mmc.h index d7b46880e4ca..043bd02f3f2a 100644 --- a/arch/arm/mach-omap1/mmc.h +++ b/arch/arm/mach-omap1/mmc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/mach-omap1/reset.c b/arch/arm/mach-omap1/reset.c index 72bf4bf4a702..af2c120b0c4e 100644 --- a/arch/arm/mach-omap1/reset.c +++ b/arch/arm/mach-omap1/reset.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OMAP1 reset support */ diff --git a/arch/arm/mach-omap1/sram.h b/arch/arm/mach-omap1/sram.h index d5a6c8362301..73efabd119e8 100644 --- a/arch/arm/mach-omap1/sram.h +++ b/arch/arm/mach-omap1/sram.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 0465338183c7..e31a5a22e171 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -87,6 +87,7 @@ config SOC_DRA7XX select OMAP_INTERCONNECT_BARRIER select PM_OPP if PM select ZONE_DMA if ARM_LPAE + select PINCTRL_TI_IODELAY if OF && PINCTRL config ARCH_OMAP2PLUS bool diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 779fb1f680b3..38f1748a4500 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # @@ -8,7 +9,7 @@ ccflags-y := -I$(srctree)/$(src)/include \ # Common support obj-y := id.o io.o control.o devices.o fb.o timer.o pm.o \ common.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \ - omap_device.o omap-headsmp.o sram.o drm.o + omap_device.o omap-headsmp.o sram.o hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ omap_hwmod_common_data.o diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index b1e661bb5521..6c61ecc62905 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -33,6 +33,7 @@ static void __init __maybe_unused omap_generic_init(void) pdata_quirks_init(omap_dt_match_table); omapdss_init_of(); + omap_soc_device_init(); } #ifdef CONFIG_SOC_OMAP2420 @@ -312,6 +313,7 @@ MACHINE_END #ifdef CONFIG_SOC_DRA7XX static const char *const dra74x_boards_compat[] __initconst = { + "ti,dra762", "ti,am5728", "ti,am5726", "ti,dra742", diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h index 125c37614848..a8408f9d0f33 100644 --- a/arch/arm/mach-omap2/clock2xxx.h +++ b/arch/arm/mach-omap2/clock2xxx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * OMAP2 clock function prototypes and macros * diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h index 78d9f562e3ce..10a9f577dc1a 100644 --- a/arch/arm/mach-omap2/clock3xxx.h +++ b/arch/arm/mach-omap2/clock3xxx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * OMAP3-common clock function prototypes and macros * diff --git a/arch/arm/mach-omap2/clockdomains2420_data.c b/arch/arm/mach-omap2/clockdomains2420_data.c index 7e76becf3a4a..ac4ffb5d2ffc 100644 --- a/arch/arm/mach-omap2/clockdomains2420_data.c +++ b/arch/arm/mach-omap2/clockdomains2420_data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OMAP2420 clockdomains * diff --git a/arch/arm/mach-omap2/clockdomains2430_data.c b/arch/arm/mach-omap2/clockdomains2430_data.c index b923007e45d0..0e97e178abaa 100644 --- a/arch/arm/mach-omap2/clockdomains2430_data.c +++ b/arch/arm/mach-omap2/clockdomains2430_data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OMAP2xxx clockdomains * diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c index 4972219653ce..220c22f5e0f5 100644 --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OMAP2/3 clockdomain common data * diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c index f03dc97921ad..94bbd3831ac3 100644 --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OMAP3xxx clockdomains * diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h index 335c7822fea1..b23962c38fb2 100644 --- a/arch/arm/mach-omap2/common-board-devices.h +++ b/arch/arm/mach-omap2/common-board-devices.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __OMAP_COMMON_BOARD_DEVICES__ #define __OMAP_COMMON_BOARD_DEVICES__ diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 8cc6338fcb12..b5ad7fcb80ed 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 8fa01c0ecdb2..b3f6eb5d04a2 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -66,6 +66,7 @@ */ #define FRAMEDONE_IRQ_TIMEOUT 100 +#if defined(CONFIG_FB_OMAP2) static struct platform_device omap_display_device = { .name = "omapdss", .id = -1, @@ -163,6 +164,65 @@ static enum omapdss_version __init omap_display_get_version(void) return OMAPDSS_VER_UNKNOWN; } +static int __init omapdss_init_fbdev(void) +{ + static struct omap_dss_board_info board_data = { + .dsi_enable_pads = omap_dsi_enable_pads, + .dsi_disable_pads = omap_dsi_disable_pads, + .set_min_bus_tput = omap_dss_set_min_bus_tput, + }; + struct device_node *node; + int r; + + board_data.version = omap_display_get_version(); + if (board_data.version == OMAPDSS_VER_UNKNOWN) { + pr_err("DSS not supported on this SoC\n"); + return -ENODEV; + } + + omap_display_device.dev.platform_data = &board_data; + + r = platform_device_register(&omap_display_device); + if (r < 0) { + pr_err("Unable to register omapdss device\n"); + return r; + } + + /* create vrfb device */ + r = omap_init_vrfb(); + if (r < 0) { + pr_err("Unable to register omapvrfb device\n"); + return r; + } + + /* create FB device */ + r = omap_init_fb(); + if (r < 0) { + pr_err("Unable to register omapfb device\n"); + return r; + } + + /* create V4L2 display device */ + r = omap_init_vout(); + if (r < 0) { + pr_err("Unable to register omap_vout device\n"); + return r; + } + + /* add DSI info for omap4 */ + node = of_find_node_by_name(NULL, "omap4_padconf_global"); + if (node) + omap4_dsi_mux_syscon = syscon_node_to_regmap(node); + + return 0; +} +#else +static inline int omapdss_init_fbdev(void) +{ + return 0; +} +#endif /* CONFIG_FB_OMAP2 */ + static void dispc_disable_outputs(void) { u32 v, irq_mask = 0; @@ -335,16 +395,9 @@ static struct device_node * __init omapdss_find_dss_of_node(void) int __init omapdss_init_of(void) { int r; - enum omapdss_version ver; struct device_node *node; struct platform_device *pdev; - static struct omap_dss_board_info board_data = { - .dsi_enable_pads = omap_dsi_enable_pads, - .dsi_disable_pads = omap_dsi_disable_pads, - .set_min_bus_tput = omap_dss_set_min_bus_tput, - }; - /* only create dss helper devices if dss is enabled in the .dts */ node = omapdss_find_dss_of_node(); @@ -354,13 +407,6 @@ int __init omapdss_init_of(void) if (!of_device_is_available(node)) return 0; - ver = omap_display_get_version(); - - if (ver == OMAPDSS_VER_UNKNOWN) { - pr_err("DSS not supported on this SoC\n"); - return -ENODEV; - } - pdev = of_find_device_by_node(node); if (!pdev) { @@ -374,48 +420,5 @@ int __init omapdss_init_of(void) return r; } - board_data.version = ver; - - omap_display_device.dev.platform_data = &board_data; - - r = platform_device_register(&omap_display_device); - if (r < 0) { - pr_err("Unable to register omapdss device\n"); - return r; - } - - /* create DRM device */ - r = omap_init_drm(); - if (r < 0) { - pr_err("Unable to register omapdrm device\n"); - return r; - } - - /* create vrfb device */ - r = omap_init_vrfb(); - if (r < 0) { - pr_err("Unable to register omapvrfb device\n"); - return r; - } - - /* create FB device */ - r = omap_init_fb(); - if (r < 0) { - pr_err("Unable to register omapfb device\n"); - return r; - } - - /* create V4L2 display device */ - r = omap_init_vout(); - if (r < 0) { - pr_err("Unable to register omap_vout device\n"); - return r; - } - - /* add DSI info for omap4 */ - node = of_find_node_by_name(NULL, "omap4_padconf_global"); - if (node) - omap4_dsi_mux_syscon = syscon_node_to_regmap(node); - - return 0; + return omapdss_init_fbdev(); } diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h index 9a39646d4316..42ec2e99a2f4 100644 --- a/arch/arm/mach-omap2/display.h +++ b/arch/arm/mach-omap2/display.h @@ -26,7 +26,6 @@ struct omap_dss_dispc_dev_attr { bool has_framedonetv_irq; }; -int omap_init_drm(void); int omap_init_vrfb(void); int omap_init_fb(void); int omap_init_vout(void); diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 0b77a0176018..694ce0939d50 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -204,61 +204,6 @@ static unsigned configure_dma_errata(void) return errata; } -static const struct dma_slave_map omap24xx_sdma_map[] = { - { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, - { "omap-aes", "tx", SDMA_FILTER_PARAM(9) }, - { "omap-aes", "rx", SDMA_FILTER_PARAM(10) }, - { "omap-sham", "rx", SDMA_FILTER_PARAM(13) }, - { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, - { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, - { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, - { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, - { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, - { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, - { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, - { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, - { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, - { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, - { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, - { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, - { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, - { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, - { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, - { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, - { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, - { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, - { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, - { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, - { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, - { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, - { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, - { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, - { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, - { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, - { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, - { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, - { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, - { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, - { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, - { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, - { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, - { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, - { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, - { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, - { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, - { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, - { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, - { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, - - /* external DMA requests when tusb6010 is used */ - { "musb-tusb", "dmareq0", SDMA_FILTER_PARAM(2) }, - { "musb-tusb", "dmareq1", SDMA_FILTER_PARAM(3) }, - { "musb-tusb", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */ - { "musb-tusb", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */ - { "musb-tusb", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */ - { "musb-tusb", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */ -}; - static const struct dma_slave_map omap24xx_sdma_dt_map[] = { /* external DMA requests when tusb6010 is used */ { "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) }, @@ -269,61 +214,6 @@ static const struct dma_slave_map omap24xx_sdma_dt_map[] = { { "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */ }; -static const struct dma_slave_map omap3xxx_sdma_map[] = { - { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, - { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, - { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, - { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, - { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, - { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, - { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, - { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, - { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, - { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, - { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, - { "omap_i2c.3", "tx", SDMA_FILTER_PARAM(25) }, - { "omap_i2c.3", "rx", SDMA_FILTER_PARAM(26) }, - { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, - { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, - { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, - { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, - { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, - { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, - { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, - { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, - { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, - { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, - { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, - { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, - { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, - { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, - { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, - { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, - { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, - { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, - { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, - { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, - { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, - { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, - { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, - { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, - { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, - { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, - { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, - { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, - { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, - { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, - { "omap-aes", "tx", SDMA_FILTER_PARAM(65) }, - { "omap-aes", "rx", SDMA_FILTER_PARAM(66) }, - { "omap-sham", "rx", SDMA_FILTER_PARAM(69) }, - { "omap2_mcspi.3", "tx0", SDMA_FILTER_PARAM(70) }, - { "omap2_mcspi.3", "rx0", SDMA_FILTER_PARAM(71) }, - { "omap_hsmmc.2", "tx", SDMA_FILTER_PARAM(77) }, - { "omap_hsmmc.2", "rx", SDMA_FILTER_PARAM(78) }, - { "omap_uart.3", "tx", SDMA_FILTER_PARAM(81) }, - { "omap_uart.3", "rx", SDMA_FILTER_PARAM(82) }, -}; - static struct omap_system_dma_plat_info dma_plat_info __initdata = { .reg_map = reg_map, .channel_stride = 0x60, @@ -352,24 +242,10 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; p.errata = configure_dma_errata(); - if (!of_have_populated_dt()) { - if (soc_is_omap24xx()) { - p.slave_map = omap24xx_sdma_map; - p.slavecnt = ARRAY_SIZE(omap24xx_sdma_map); - } else if (soc_is_omap34xx() || soc_is_omap3630()) { - p.slave_map = omap3xxx_sdma_map; - p.slavecnt = ARRAY_SIZE(omap3xxx_sdma_map); - } else { - pr_err("%s: The legacy DMA map is not provided!\n", - __func__); - return -ENODEV; - } - } else { - if (soc_is_omap24xx()) { - /* DMA slave map for drivers not yet converted to DT */ - p.slave_map = omap24xx_sdma_dt_map; - p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map); - } + if (soc_is_omap24xx()) { + /* DMA slave map for drivers not yet converted to DT */ + p.slave_map = omap24xx_sdma_dt_map; + p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map); } pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); @@ -413,21 +289,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) static int __init omap2_system_dma_init(void) { - struct platform_device *pdev; - int res; - - res = omap_hwmod_for_each_by_class("dma", + return omap_hwmod_for_each_by_class("dma", omap2_system_dma_init_dev, NULL); - if (res) - return res; - - if (of_have_populated_dt()) - return res; - - pdev = platform_device_register_full(&omap_dma_dev_info); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - return res; } omap_arch_initcall(omap2_system_dma_init); diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c deleted file mode 100644 index 44fef961bb70..000000000000 --- a/arch/arm/mach-omap2/drm.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * DRM/KMS device registration for TI OMAP platforms - * - * Copyright (C) 2012 Texas Instruments - * Author: Rob Clark - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "soc.h" -#include "display.h" - -#if IS_ENABLED(CONFIG_DRM_OMAP) - -static struct omap_drm_platform_data platform_data; - -static struct platform_device omap_drm_device = { - .dev = { - .coherent_dma_mask = DMA_BIT_MASK(32), - .platform_data = &platform_data, - }, - .name = "omapdrm", - .id = 0, -}; - -int __init omap_init_drm(void) -{ - platform_data.omaprev = GET_OMAP_TYPE; - - return platform_device_register(&omap_drm_device); - -} -#else -int __init omap_init_drm(void) { return 0; } -#endif diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 5b614388d72f..6d28aa20a7d3 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -58,10 +58,10 @@ void omap_hsmmc_late_init(struct omap2_hsmmc_info *c) struct platform_device *pdev; int res; - if (omap_hsmmc_done != 1) + if (omap_hsmmc_done) return; - omap_hsmmc_done++; + omap_hsmmc_done = 1; for (; c->mmc; c++) { pdev = c->pdev; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index e2274a162b74..16cb1c195fd8 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -663,6 +663,15 @@ void __init dra7xxx_check_revision(void) hawkeye = (idcode >> 12) & 0xffff; rev = (idcode >> 28) & 0xff; switch (hawkeye) { + case 0xbb50: + switch (rev) { + case 0: + default: + omap_revision = DRA762_REV_ES1_0; + break; + } + break; + case 0xb990: switch (rev) { case 0: diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 1cd20e4d56b0..cb5d7314cf99 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -428,7 +428,6 @@ static void __init __maybe_unused omap_hwmod_init_postsetup(void) static void __init __maybe_unused omap_common_late_init(void) { omap2_common_pm_late_init(); - omap_soc_device_init(); } #ifdef CONFIG_SOC_OMAP2420 diff --git a/arch/arm/mach-omap2/mmc.h b/arch/arm/mach-omap2/mmc.h index 30d39b97e7dd..9145a6f720fc 100644 --- a/arch/arm/mach-omap2/mmc.h +++ b/arch/arm/mach-omap2/mmc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define OMAP24XX_NR_MMC 2 #define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE diff --git a/arch/arm/mach-omap2/omap-pm-noop.c b/arch/arm/mach-omap2/omap-pm-noop.c index a1ee8066958e..4ead077ea4e7 100644 --- a/arch/arm/mach-omap2/omap-pm-noop.c +++ b/arch/arm/mach-omap2/omap-pm-noop.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * omap-pm-noop.c - OMAP power management interface - dummy version * diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h index 109bef5538eb..5ba5df47f91b 100644 --- a/arch/arm/mach-omap2/omap-pm.h +++ b/arch/arm/mach-omap2/omap-pm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * omap-pm.h - OMAP power management interface * diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 33e4953c61a8..69df3620eca5 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -342,7 +342,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) c = &omap443x_cfg; else if (soc_is_omap446x()) c = &omap446x_cfg; - else if (soc_is_dra74x() || soc_is_omap54xx()) + else if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x()) c = &omap5_cfg; if (!c) { @@ -355,7 +355,7 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) cfg.startup_addr = c->startup_addr; cfg.wakeupgen_base = omap_get_wakeupgen_base(); - if (soc_is_dra74x() || soc_is_omap54xx()) { + if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x()) { if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE) cfg.startup_addr = omap5_secondary_hyp_startup; omap5_erratum_workaround_801819(); diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 33ed5d53fa45..4bb6751864a5 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -522,13 +522,13 @@ static int __init wakeupgen_init(struct device_node *node, u32 val; if (!parent) { - pr_err("%s: no parent, giving up\n", node->full_name); + pr_err("%pOF: no parent, giving up\n", node); return -ENODEV; } parent_domain = irq_find_host(parent); if (!parent_domain) { - pr_err("%s: unable to obtain parent domain\n", node->full_name); + pr_err("%pOF: unable to obtain parent domain\n", node); return -ENXIO; } /* Not supported on OMAP4 ES1.0 silicon */ diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index ef9ffb8ac912..acbede082b5b 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -672,7 +672,6 @@ static int _od_suspend_noirq(struct device *dev) if (!ret && !pm_runtime_status_suspended(dev)) { if (pm_generic_runtime_suspend(dev) == 0) { - pm_runtime_set_suspended(dev); omap_device_idle(pdev); od->flags |= OMAP_DEVICE_SUSPENDED; } @@ -689,15 +688,6 @@ static int _od_resume_noirq(struct device *dev) if (od->flags & OMAP_DEVICE_SUSPENDED) { od->flags &= ~OMAP_DEVICE_SUSPENDED; omap_device_enable(pdev); - /* - * XXX: we run before core runtime pm has resumed itself. At - * this point in time, we just restore the runtime pm state and - * considering symmetric operations in resume, we donot expect - * to fail. If we failed, something changed in core runtime_pm - * framework OR some device driver messed things up, hence, WARN - */ - WARN(pm_runtime_set_active(dev), - "Could not set %s runtime state active\n", dev_name(dev)); pm_generic_runtime_resume(dev); } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 3b47ded5fa0c..2dbd63239c54 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2417,8 +2417,8 @@ static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, if (mem) pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); else - pr_err("omap_hwmod: %s: Missing dt reg%i for %s\n", - oh->name, index, np->full_name); + pr_err("omap_hwmod: %s: Missing dt reg%i for %pOF\n", + oh->name, index, np); return -ENXIO; } diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index b3abb8d8b2f6..2f4f7002f38d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -839,6 +839,7 @@ static struct omap_hwmod dra7xx_gpio1_hwmod = { .name = "gpio1", .class = &dra7xx_gpio_hwmod_class, .clkdm_name = "wkupaon_clkdm", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .main_clk = "wkupaon_iclk_mux", .prcm = { .omap4 = { @@ -4070,6 +4071,11 @@ static struct omap_hwmod_ocp_if *dra7xx_gp_hwmod_ocp_ifs[] __initdata = { }; /* SoC variant specific hwmod links */ +static struct omap_hwmod_ocp_if *dra76x_hwmod_ocp_ifs[] __initdata = { + &dra7xx_l4_per3__usb_otg_ss4, + NULL, +}; + static struct omap_hwmod_ocp_if *dra74x_hwmod_ocp_ifs[] __initdata = { &dra7xx_l4_per3__usb_otg_ss4, NULL, @@ -4095,12 +4101,14 @@ int __init dra7xx_hwmod_init(void) ret = omap_hwmod_register_links(dra74x_hwmod_ocp_ifs); else if (!ret && soc_is_dra72x()) ret = omap_hwmod_register_links(dra72x_hwmod_ocp_ifs); + else if (!ret && soc_is_dra76x()) + ret = omap_hwmod_register_links(dra76x_hwmod_ocp_ifs); if (!ret && omap_type() == OMAP2_DEVICE_TYPE_GP) ret = omap_hwmod_register_links(dra7xx_gp_hwmod_ocp_ifs); - /* now for the IPs *NOT* in dra71 */ - if (!ret && !of_machine_is_compatible("ti,dra718")) + /* now for the IPs available only in dra74 and dra72 */ + if (!ret && !of_machine_is_compatible("ti,dra718") && !soc_is_dra76x()) ret = omap_hwmod_register_links(dra74x_dra72x_hwmod_ocp_ifs); return ret; diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 1346b3ab34a5..295124b248ae 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include "soc.h" #include "voltage.h" diff --git a/arch/arm/mach-omap2/opp2420_data.c b/arch/arm/mach-omap2/opp2420_data.c index a9e8cf21705d..18a448f938ea 100644 --- a/arch/arm/mach-omap2/opp2420_data.c +++ b/arch/arm/mach-omap2/opp2420_data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * opp2420_data.c - old-style "OPP" table for OMAP2420 * diff --git a/arch/arm/mach-omap2/opp2430_data.c b/arch/arm/mach-omap2/opp2430_data.c index b2233b72b24d..ded8b566a23a 100644 --- a/arch/arm/mach-omap2/opp2430_data.c +++ b/arch/arm/mach-omap2/opp2430_data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * opp2430_data.c - old-style "OPP" table for OMAP2430 * diff --git a/arch/arm/mach-omap2/opp2xxx.h b/arch/arm/mach-omap2/opp2xxx.h index 8fae534eb157..a451182cdc02 100644 --- a/arch/arm/mach-omap2/opp2xxx.h +++ b/arch/arm/mach-omap2/opp2xxx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * opp2xxx.h - macros for old-style OMAP2xxx "OPP" definitions * diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 9700a8ef0f16..6b433fce65a5 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -434,6 +434,26 @@ static void __init omap5_uevm_legacy_init(void) } #endif +#ifdef CONFIG_SOC_DRA7XX +static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1; +static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2; +static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3; + +static void __init dra7x_evm_mmc_quirk(void) +{ + if (omap_rev() == DRA752_REV_ES1_1 || omap_rev() == DRA752_REV_ES1_0) { + dra7_hsmmc_data_mmc1.version = "rev11"; + dra7_hsmmc_data_mmc1.max_freq = 96000000; + + dra7_hsmmc_data_mmc2.version = "rev11"; + dra7_hsmmc_data_mmc2.max_freq = 48000000; + + dra7_hsmmc_data_mmc3.version = "rev11"; + dra7_hsmmc_data_mmc3.max_freq = 48000000; + } +} +#endif + static struct pcs_pdata pcs_pdata; void omap_pcs_legacy_init(int irq, void (*rearm)(void)) @@ -560,6 +580,14 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { &omap4_iommu_pdata), OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu", &omap4_iommu_pdata), +#endif +#ifdef CONFIG_SOC_DRA7XX + OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x4809c000, "4809c000.mmc", + &dra7_hsmmc_data_mmc1), + OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480b4000, "480b4000.mmc", + &dra7_hsmmc_data_mmc2), + OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480ad000, "480ad000.mmc", + &dra7_hsmmc_data_mmc3), #endif /* Common auxdata */ OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata), @@ -589,6 +617,9 @@ static struct pdata_init pdata_quirks[] __initdata = { #endif #ifdef CONFIG_SOC_OMAP5 { "ti,omap5-uevm", omap5_uevm_legacy_init, }, +#endif +#ifdef CONFIG_SOC_DRA7XX + { "ti,dra7-evm", dra7x_evm_mmc_quirk, }, #endif { /* sentinel */ }, }; diff --git a/arch/arm/mach-omap2/powerdomains7xx_data.c b/arch/arm/mach-omap2/powerdomains7xx_data.c index eb350a673133..f50963916a21 100644 --- a/arch/arm/mach-omap2/powerdomains7xx_data.c +++ b/arch/arm/mach-omap2/powerdomains7xx_data.c @@ -29,6 +29,7 @@ #include "prcm44xx.h" #include "prm7xx.h" #include "prcm_mpu7xx.h" +#include "soc.h" /* iva_7xx_pwrdm: IVA-HD power domain */ static struct powerdomain iva_7xx_pwrdm = { @@ -63,6 +64,14 @@ static struct powerdomain custefuse_7xx_pwrdm = { .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, }; +/* custefuse_aon_7xx_pwrdm: Customer efuse controller power domain */ +static struct powerdomain custefuse_aon_7xx_pwrdm = { + .name = "custefuse_pwrdm", + .prcm_offs = DRA7XX_PRM_CUSTEFUSE_INST, + .prcm_partition = DRA7XX_PRM_PARTITION, + .pwrsts = PWRSTS_ON, +}; + /* ipu_7xx_pwrdm: Audio back end power domain */ static struct powerdomain ipu_7xx_pwrdm = { .name = "ipu_pwrdm", @@ -350,7 +359,6 @@ static struct powerdomain eve1_7xx_pwrdm = { static struct powerdomain *powerdomains_dra7xx[] __initdata = { &iva_7xx_pwrdm, &rtc_7xx_pwrdm, - &custefuse_7xx_pwrdm, &ipu_7xx_pwrdm, &dss_7xx_pwrdm, &l4per_7xx_pwrdm, @@ -374,9 +382,32 @@ static struct powerdomain *powerdomains_dra7xx[] __initdata = { NULL }; +static struct powerdomain *powerdomains_dra76x[] __initdata = { + &custefuse_aon_7xx_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_dra74x[] __initdata = { + &custefuse_7xx_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_dra72x[] __initdata = { + &custefuse_aon_7xx_pwrdm, + NULL +}; + void __init dra7xx_powerdomains_init(void) { pwrdm_register_platform_funcs(&omap4_pwrdm_operations); pwrdm_register_pwrdms(powerdomains_dra7xx); + + if (soc_is_dra76x()) + pwrdm_register_pwrdms(powerdomains_dra76x); + else if (soc_is_dra74x()) + pwrdm_register_pwrdms(powerdomains_dra74x); + else if (soc_is_dra72x()) + pwrdm_register_pwrdms(powerdomains_dra72x); + pwrdm_complete_init(); } diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 64f6451499a7..a2dd13217c89 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -706,7 +706,7 @@ static int omap3xxx_prm_late_init(void) np = of_find_matching_node(NULL, omap3_prm_dt_match_table); if (np) { irq_num = of_irq_get(np, 0); - if (irq_num >= 0) + if (irq_num > 0) omap3_prcm_irq_setup.irq = irq_num; } diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 3ab5df1ce900..1c0c1663f078 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -747,7 +747,7 @@ static int omap44xx_prm_late_init(void) * Already have OMAP4 IRQ num. For all other platforms, we need * IRQ numbers from DT */ - if (irq_num < 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) { + if (irq_num <= 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) { if (irq_num == -EPROBE_DEFER) return irq_num; @@ -756,7 +756,7 @@ static int omap44xx_prm_late_init(void) } /* Once OMAP4 DT is filled as well */ - if (irq_num >= 0) { + if (irq_num > 0) { omap4_prcm_irq_setup.irq = irq_num; omap4_prcm_irq_setup.xlate_irq = NULL; } diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 1b9f0520dea9..fa5fd24f524c 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S @@ -530,10 +530,12 @@ l2dis_3630_offset: .long l2dis_3630 - . .data + .align 2 l2dis_3630: .word 0 .data + .align 2 l2_inv_api_params: .word 0x1, 0x00 diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index c7a3b4aab4b5..56dfa2d5d0a8 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -385,6 +385,7 @@ ppa_zero_params_offset: ENDPROC(omap_do_wfi) .data + .align 2 ppa_zero_params: .word 0 diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 2aa01c270898..754cd0fc0e7b 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -167,6 +167,7 @@ IS_TI_SUBCLASS(816x, 0x816) IS_TI_SUBCLASS(814x, 0x814) IS_AM_SUBCLASS(335x, 0x335) IS_AM_SUBCLASS(437x, 0x437) +IS_DRA_SUBCLASS(76x, 0x76) IS_DRA_SUBCLASS(75x, 0x75) IS_DRA_SUBCLASS(72x, 0x72) @@ -185,6 +186,7 @@ IS_DRA_SUBCLASS(72x, 0x72) #define soc_is_omap54xx() 0 #define soc_is_omap543x() 0 #define soc_is_dra7xx() 0 +#define soc_is_dra76x() 0 #define soc_is_dra74x() 0 #define soc_is_dra72x() 0 @@ -314,9 +316,11 @@ IS_OMAP_TYPE(3430, 0x3430) #if defined(CONFIG_SOC_DRA7XX) #undef soc_is_dra7xx +#undef soc_is_dra76x #undef soc_is_dra74x #undef soc_is_dra72x #define soc_is_dra7xx() is_dra7xx() +#define soc_is_dra76x() is_dra76x() #define soc_is_dra74x() is_dra75x() #define soc_is_dra72x() is_dra72x() #endif @@ -386,6 +390,7 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8)) #define DRA7XX_CLASS 0x07000000 +#define DRA762_REV_ES1_0 (DRA7XX_CLASS | (0x62 << 16) | (0x10 << 8)) #define DRA752_REV_ES1_0 (DRA7XX_CLASS | (0x52 << 16) | (0x10 << 8)) #define DRA752_REV_ES1_1 (DRA7XX_CLASS | (0x52 << 16) | (0x11 << 8)) #define DRA752_REV_ES2_0 (DRA7XX_CLASS | (0x52 << 16) | (0x20 << 8)) diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h index 3395365ef1db..740a499befce 100644 --- a/arch/arm/mach-omap2/usb.h +++ b/arch/arm/mach-omap2/usb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* AM35x */ diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c index a3c30655aa30..a709655b978c 100644 --- a/arch/arm/mach-omap2/vp.c +++ b/arch/arm/mach-omap2/vp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index ae91872eeee4..1a585a62d5e6 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-orion/include obj-y += common.o pci.o irq.o mpp.o diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index 4c0c7de665c3..eb96009e21c4 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_ORION5X_COMMON_H #define __ARCH_ORION5X_COMMON_H diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c index 12f74b46e2ff..3f5863de766a 100644 --- a/arch/arm/mach-orion5x/db88f5281-setup.c +++ b/arch/arm/mach-orion5x/db88f5281-setup.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index 9dc3f59bed9c..83d43cff4bd7 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-orion5x/mpp.h b/arch/arm/mach-orion5x/mpp.h index db70e79a1198..be1c78663291 100644 --- a/arch/arm/mach-orion5x/mpp.h +++ b/arch/arm/mach-orion5x/mpp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_ORION5X_MPP_H #define __ARCH_ORION5X_MPP_H diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c index 7bd671b2854c..0c315515dd2d 100644 --- a/arch/arm/mach-orion5x/ts209-setup.c +++ b/arch/arm/mach-orion5x/ts209-setup.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-orion5x/ts78xx-fpga.h b/arch/arm/mach-orion5x/ts78xx-fpga.h index 97c393d39ae2..2f4fe3ca5c1a 100644 --- a/arch/arm/mach-orion5x/ts78xx-fpga.h +++ b/arch/arm/mach-orion5x/ts78xx-fpga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define TS7800_FPGA_MAGIC 0x00b480 #define FPGAID(_magic, _rev) ((_magic << 8) + _rev) diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 7ef80a8304c0..94778739e38f 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-orion5x/tsx09-common.h b/arch/arm/mach-orion5x/tsx09-common.h index 0984264616f0..72bedc6b82fb 100644 --- a/arch/arm/mach-orion5x/tsx09-common.h +++ b/arch/arm/mach-orion5x/tsx09-common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_ORION5X_TSX09_COMMON_H #define __ARCH_ORION5X_TSX09_COMMON_H diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile index d7d02b043449..0fd2763031e9 100644 --- a/arch/arm/mach-prima2/Makefile +++ b/arch/arm/mach-prima2/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += rstc.o obj-y += common.o obj-y += rtciobrg.o diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index ef25dc597f30..0a8e9611052f 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 1467c1d1e541..d6d92f388f14 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.h b/arch/arm/mach-pxa/cm-x2xx-pci.h index e24aad2e3ad7..93ffaaee75d7 100644 --- a/arch/arm/mach-pxa/cm-x2xx-pci.h +++ b/arch/arm/mach-pxa/cm-x2xx-pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ extern void __cmx2xx_pci_init_irq(int irq_gpio); extern void __cmx2xx_pci_suspend(void); extern void __cmx2xx_pci_resume(void); diff --git a/arch/arm/mach-pxa/colibri.h b/arch/arm/mach-pxa/colibri.h index cb4236e98a0f..673a131da875 100644 --- a/arch/arm/mach-pxa/colibri.h +++ b/arch/arm/mach-pxa/colibri.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _COLIBRI_H_ #define _COLIBRI_H_ diff --git a/arch/arm/mach-pxa/csb701.c b/arch/arm/mach-pxa/csb701.c index 5a221a49ea4d..527c9fdf9795 100644 --- a/arch/arm/mach-pxa/csb701.c +++ b/arch/arm/mach-pxa/csb701.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index fffb697bbf0e..5a72456a19ce 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index 04580c407276..905628dfbbbb 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ extern struct platform_device pxa_device_pmu; extern struct platform_device pxa_device_mci; extern struct platform_device pxa3xx_device_mci2; diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 811a7317f3ea..6d28035ebba5 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index fa9d71d194f0..91f7c3e40065 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/include/mach/addr-map.h b/arch/arm/mach-pxa/include/mach/addr-map.h index 07b93fd24474..93cfe7dbfec6 100644 --- a/arch/arm/mach-pxa/include/mach/addr-map.h +++ b/arch/arm/mach-pxa/include/mach/addr-map.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_ADDR_MAP_H #define __ASM_MACH_ADDR_MAP_H diff --git a/arch/arm/mach-pxa/include/mach/audio.h b/arch/arm/mach-pxa/include/mach/audio.h index a3449e35a6f5..7beebf7297b5 100644 --- a/arch/arm/mach-pxa/include/mach/audio.h +++ b/arch/arm/mach-pxa/include/mach/audio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_AUDIO_H__ #define __ASM_ARCH_AUDIO_H__ diff --git a/arch/arm/mach-pxa/include/mach/bitfield.h b/arch/arm/mach-pxa/include/mach/bitfield.h index f1f0e3387d9c..fe2ca441bc0a 100644 --- a/arch/arm/mach-pxa/include/mach/bitfield.h +++ b/arch/arm/mach-pxa/include/mach/bitfield.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * FILE bitfield.h * diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index cd78b7fe3567..d54031c4f3df 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-pxa/include/mach/io.h * diff --git a/arch/arm/mach-pxa/include/mach/regs-ac97.h b/arch/arm/mach-pxa/include/mach/regs-ac97.h index b8d14bd9ae59..1db96fd4df32 100644 --- a/arch/arm/mach-pxa/include/mach/regs-ac97.h +++ b/arch/arm/mach-pxa/include/mach/regs-ac97.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_REGS_AC97_H #define __ASM_ARCH_REGS_AC97_H diff --git a/arch/arm/mach-pxa/include/mach/regs-lcd.h b/arch/arm/mach-pxa/include/mach/regs-lcd.h index f82dcea792d9..e2b6e3d1f625 100644 --- a/arch/arm/mach-pxa/include/mach/regs-lcd.h +++ b/arch/arm/mach-pxa/include/mach/regs-lcd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_REGS_LCD_H #define __ASM_ARCH_REGS_LCD_H diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h index 628819995c52..deb564ed8ee7 100644 --- a/arch/arm/mach-pxa/include/mach/regs-ost.h +++ b/arch/arm/mach-pxa/include/mach/regs-ost.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_REGS_OST_H #define __ASM_MACH_REGS_OST_H diff --git a/arch/arm/mach-pxa/include/mach/regs-uart.h b/arch/arm/mach-pxa/include/mach/regs-uart.h index 55aeb7fb72f6..9a168f83afeb 100644 --- a/arch/arm/mach-pxa/include/mach/regs-uart.h +++ b/arch/arm/mach-pxa/include/mach/regs-uart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_REGS_UART_H #define __ASM_ARCH_REGS_UART_H diff --git a/arch/arm/mach-pxa/include/mach/reset.h b/arch/arm/mach-pxa/include/mach/reset.h index b6c10556fbc7..e1c4d100fd45 100644 --- a/arch/arm/mach-pxa/include/mach/reset.h +++ b/arch/arm/mach-pxa/include/mach/reset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_RESET_H #define __ASM_ARCH_RESET_H diff --git a/arch/arm/mach-pxa/include/mach/trizeps4.h b/arch/arm/mach-pxa/include/mach/trizeps4.h index ae3ca013afab..3cddb1428c5e 100644 --- a/arch/arm/mach-pxa/include/mach/trizeps4.h +++ b/arch/arm/mach-pxa/include/mach/trizeps4.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /************************************************************************ * Include file for TRIZEPS4 SoM and ConXS eval-board * Copyright (c) Jürgen Schindele diff --git a/arch/arm/mach-pxa/littleton.h b/arch/arm/mach-pxa/littleton.h index 8066be54e9f5..a0a8d2bf9d71 100644 --- a/arch/arm/mach-pxa/littleton.h +++ b/arch/arm/mach-pxa/littleton.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_LITTLETON_H #define __ASM_ARCH_LITTLETON_H diff --git a/arch/arm/mach-pxa/mfp-pxa25x.h b/arch/arm/mach-pxa/mfp-pxa25x.h index 1c59d4b3b19b..d0ebb2154503 100644 --- a/arch/arm/mach-pxa/mfp-pxa25x.h +++ b/arch/arm/mach-pxa/mfp-pxa25x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_MFP_PXA25X_H #define __ASM_ARCH_MFP_PXA25X_H diff --git a/arch/arm/mach-pxa/mfp-pxa27x.h b/arch/arm/mach-pxa/mfp-pxa27x.h index 9fe5601ce668..9f5ffb785ff5 100644 --- a/arch/arm/mach-pxa/mfp-pxa27x.h +++ b/arch/arm/mach-pxa/mfp-pxa27x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_MFP_PXA27X_H #define __ASM_ARCH_MFP_PXA27X_H diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.h b/arch/arm/mach-pxa/mfp-pxa2xx.h index cbf51ae81855..980145e7ee99 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.h +++ b/arch/arm/mach-pxa/mfp-pxa2xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_MFP_PXA2XX_H #define __ASM_ARCH_MFP_PXA2XX_H diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.h b/arch/arm/mach-pxa/mfp-pxa3xx.h index d375195d982b..cdd830926d1c 100644 --- a/arch/arm/mach-pxa/mfp-pxa3xx.h +++ b/arch/arm/mach-pxa/mfp-pxa3xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_MFP_PXA3XX_H #define __ASM_ARCH_MFP_PXA3XX_H diff --git a/arch/arm/mach-pxa/mioa701.h b/arch/arm/mach-pxa/mioa701.h index e57f5c724e8a..d94295c67460 100644 --- a/arch/arm/mach-pxa/mioa701.h +++ b/arch/arm/mach-pxa/mioa701.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MIOA701_H_ #define _MIOA701_H_ diff --git a/arch/arm/mach-pxa/mioa701_bootresume.S b/arch/arm/mach-pxa/mioa701_bootresume.S index 81591491ab94..42d93f40a59f 100644 --- a/arch/arm/mach-pxa/mioa701_bootresume.S +++ b/arch/arm/mach-pxa/mioa701_bootresume.S @@ -16,6 +16,7 @@ * insist on it to be truly read-only. */ .data + .align 2 ENTRY(mioa701_bootstrap) 0: b 1f @@ -34,4 +35,5 @@ ENTRY(mioa701_jumpaddr) ENTRY(mioa701_bootstrap_lg) .data + .align 2 .word 2b-0b diff --git a/arch/arm/mach-pxa/mxm8x10.h b/arch/arm/mach-pxa/mxm8x10.h index ffa15665a418..dcd32321c995 100644 --- a/arch/arm/mach-pxa/mxm8x10.h +++ b/arch/arm/mach-pxa/mxm8x10.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_MXM_8X10_H #define __MACH_MXM_8X10_H diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 36646975b5d2..47e3e38e9bec 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pxa25x.h b/arch/arm/mach-pxa/pxa25x.h index 2011e8da0592..b58d0fbdb4db 100644 --- a/arch/arm/mach-pxa/pxa25x.h +++ b/arch/arm/mach-pxa/pxa25x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_PXA25x_H #define __MACH_PXA25x_H diff --git a/arch/arm/mach-pxa/pxa27x-udc.h b/arch/arm/mach-pxa/pxa27x-udc.h index 4cf28f670706..faf73804697f 100644 --- a/arch/arm/mach-pxa/pxa27x-udc.h +++ b/arch/arm/mach-pxa/pxa27x-udc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_PXA27X_UDC_H #define _ASM_ARCH_PXA27X_UDC_H diff --git a/arch/arm/mach-pxa/pxa27x.h b/arch/arm/mach-pxa/pxa27x.h index 075131d83eab..abdc02fb4f03 100644 --- a/arch/arm/mach-pxa/pxa27x.h +++ b/arch/arm/mach-pxa/pxa27x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_PXA27x_H #define __MACH_PXA27x_H diff --git a/arch/arm/mach-pxa/pxa300.h b/arch/arm/mach-pxa/pxa300.h index 59fa41025c80..d02a8d15c7e8 100644 --- a/arch/arm/mach-pxa/pxa300.h +++ b/arch/arm/mach-pxa/pxa300.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_PXA300_H #define __MACH_PXA300_H diff --git a/arch/arm/mach-pxa/pxa320.h b/arch/arm/mach-pxa/pxa320.h index b9e5115a1c30..c701e3f663b0 100644 --- a/arch/arm/mach-pxa/pxa320.h +++ b/arch/arm/mach-pxa/pxa320.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_PXA320_H #define __MACH_PXA320_H diff --git a/arch/arm/mach-pxa/pxa3xx.h b/arch/arm/mach-pxa/pxa3xx.h index b4143fb6631f..6d4502aa9d06 100644 --- a/arch/arm/mach-pxa/pxa3xx.h +++ b/arch/arm/mach-pxa/pxa3xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_PXA3XX_H #define __MACH_PXA3XX_H diff --git a/arch/arm/mach-pxa/pxa930.h b/arch/arm/mach-pxa/pxa930.h index 4eceb02978e8..bbf25c044641 100644 --- a/arch/arm/mach-pxa/pxa930.h +++ b/arch/arm/mach-pxa/pxa930.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_PXA930_H #define __MACH_PXA930_H diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index e2c97728b3c6..9d662fed03ec 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -377,7 +377,7 @@ static struct gpiod_lookup_table raumfeld_rotary_gpios_table = { }, }; -static struct property_entry raumfeld_rotary_properties[] = { +static const struct property_entry raumfeld_rotary_properties[] __initconst = { PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24), PROPERTY_ENTRY_INTEGER("linux,axis", u32, REL_X), PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 1), diff --git a/arch/arm/mach-pxa/regs-rtc.h b/arch/arm/mach-pxa/regs-rtc.h index f0e4a589bbe1..b1f9ff14e335 100644 --- a/arch/arm/mach-pxa/regs-rtc.h +++ b/arch/arm/mach-pxa/regs-rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_REGS_RTC_H #define __ASM_MACH_REGS_RTC_H diff --git a/arch/arm/mach-pxa/regs-u2d.h b/arch/arm/mach-pxa/regs-u2d.h index c15c0c57de08..fe4c80ad87ec 100644 --- a/arch/arm/mach-pxa/regs-u2d.h +++ b/arch/arm/mach-pxa/regs-u2d.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_PXA3xx_U2D_H #define __ASM_ARCH_PXA3xx_U2D_H diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c index f38aa890b2c9..32e82cc92ea5 100644 --- a/arch/arm/mach-pxa/smemc.c +++ b/arch/arm/mach-pxa/smemc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Static Memory Controller */ diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 13de6602966f..6a386fd6363e 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-pxa/zylonite.h b/arch/arm/mach-pxa/zylonite.h index ecca976f03d2..7300ec2aac0d 100644 --- a/arch/arm/mach-pxa/zylonite.h +++ b/arch/arm/mach-pxa/zylonite.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_ZYLONITE_H #define __ASM_ARCH_ZYLONITE_H diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 9ad84cd01ba0..a4065966881a 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -3,6 +3,7 @@ config ARCH_ROCKCHIP depends on ARCH_MULTI_V7 select PINCTRL select PINCTRL_ROCKCHIP + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_HAS_RESET_CONTROLLER select ARM_AMBA select ARM_GIC @@ -16,6 +17,7 @@ config ARCH_ROCKCHIP select ROCKCHIP_TIMER select ARM_GLOBAL_TIMER select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK + select ZONE_DMA if ARM_LPAE help Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs containing the RK2928, RK30xx and RK31xx series. diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 3abafdbdd7f4..ecec340ca345 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -67,7 +67,7 @@ static struct reset_control *rockchip_get_core_reset(int cpu) else np = of_get_cpu_node(cpu, NULL); - return of_reset_control_get(np, NULL); + return of_reset_control_get_exclusive(np, NULL); } static int pmu_set_power_domain(int pd, bool on) @@ -182,8 +182,8 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node) ret = of_address_to_resource(node, 0, &res); if (ret < 0) { - pr_err("%s: could not get address for node %s\n", - __func__, node->full_name); + pr_err("%s: could not get address for node %pOF\n", + __func__, node); return ret; } diff --git a/arch/arm/mach-rockchip/sleep.S b/arch/arm/mach-rockchip/sleep.S index 2eec9a341f05..9927f06f52fe 100644 --- a/arch/arm/mach-rockchip/sleep.S +++ b/arch/arm/mach-rockchip/sleep.S @@ -23,7 +23,7 @@ * ddr to sram for system resumeing. * so it is ".data section". */ -.align + .align 2 ENTRY(rockchip_slp_cpu_resume) setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set svc, irqs off diff --git a/arch/arm/mach-rpc/fiq.S b/arch/arm/mach-rpc/fiq.S index 48ddd57db16e..0de83e9b0b39 100644 --- a/arch/arm/mach-rpc/fiq.S +++ b/arch/arm/mach-rpc/fiq.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/arm/mach-rpc/include/mach/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S index 7178368d7062..a6d1a9f4bb79 100644 --- a/arch/arm/mach-rpc/include/mach/entry-macro.S +++ b/arch/arm/mach-rpc/include/mach/entry-macro.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c index 66502e6207fe..b8a61cb11207 100644 --- a/arch/arm/mach-rpc/irq.c +++ b/arch/arm/mach-rpc/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index f07da82ebfea..b198be7d32b6 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -229,7 +229,7 @@ config ARCH_H1940 config H1940BT tristate "Control the state of H1940 bluetooth chip" depends on ARCH_H1940 - select RFKILL + depends on RFKILL help This is a simple driver that is able to control the state of built in bluetooth chip on h1940. diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c index 9e0bc46e90ec..0e116c92bf01 100644 --- a/arch/arm/mach-s3c24xx/common-smdk.c +++ b/arch/arm/mach-s3c24xx/common-smdk.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index b59f4f4f256f..5b6b94ef41e2 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c @@ -173,7 +173,7 @@ static unsigned long s3c24xx_read_idcode_v5(void) return gs; #endif -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#if defined(CONFIG_CPU_S3C2412) return __raw_readl(S3C2412_GSTATUS1); #else return 1UL; /* don't look like an 2400 */ diff --git a/arch/arm/mach-s3c24xx/include/mach/io.h b/arch/arm/mach-s3c24xx/include/mach/io.h index 235c53647aa4..f960e6d10114 100644 --- a/arch/arm/mach-s3c24xx/include/mach/io.h +++ b/arch/arm/mach-s3c24xx/include/mach/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-s3c2410/include/mach/io.h * from arch/arm/mach-rpc/include/mach/io.h diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h index 3db6c10de023..ae4a3e0f3ba2 100644 --- a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h @@ -77,7 +77,7 @@ #endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */ -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#if defined(CONFIG_CPU_S3C2412) #define S3C2412_OSCSET S3C2410_CLKREG(0x18) #define S3C2412_CLKSRC S3C2410_CLKREG(0x1C) @@ -141,7 +141,7 @@ #define S3C2412_CLKSRC_UREFCLK_EXTCLK (1<<12) #define S3C2412_CLKSRC_EREFCLK_EXTCLK (1<<14) -#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */ +#endif /* CONFIG_CPU_S3C2412 */ #define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28) diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c index 029ef1b58925..c14cab361922 100644 --- a/arch/arm/mach-s3c24xx/mach-anubis.c +++ b/arch/arm/mach-s3c24xx/mach-anubis.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c index 7b28eb623fc1..ebdbafb9382a 100644 --- a/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c index 5185036765db..704dc84b3480 100644 --- a/arch/arm/mach-s3c24xx/mach-bast.c +++ b/arch/arm/mach-s3c24xx/mach-bast.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index b0ed401da3a3..afe18baf0c84 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c index f5b5c49b56ac..17821976f769 100644 --- a/arch/arm/mach-s3c24xx/mach-jive.c +++ b/arch/arm/mach-s3c24xx/mach-jive.c @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index 71af8d2fd320..04c9f488c498 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include @@ -287,7 +287,7 @@ static struct s3c2410_platform_nand mini2440_nand_info __initdata = { .nr_sets = ARRAY_SIZE(mini2440_nand_sets), .sets = mini2440_nand_sets, .ignore_unset_ecc = 1, - .ecc_mode = NAND_ECC_SOFT, + .ecc_mode = NAND_ECC_HW, }; /* DM9000AEP 10/100 ethernet controller */ diff --git a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c index 262ab0744748..6cac7da15e2b 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c +++ b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c index 70b0eb7d3134..ed3b22ceef06 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris.c +++ b/arch/arm/mach-s3c24xx/mach-osiris.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -36,7 +36,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c index 868c82087403..84e3a9c53184 100644 --- a/arch/arm/mach-s3c24xx/mach-qt2410.c +++ b/arch/arm/mach-s3c24xx/mach-qt2410.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c index a39fb9780dd3..b5ba615cf9dd 100644 --- a/arch/arm/mach-s3c24xx/mach-rx3715.c +++ b/arch/arm/mach-s3c24xx/mach-rx3715.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/mach-s3c24xx/mach-smdk2443.c b/arch/arm/mach-s3c24xx/mach-smdk2443.c index 87fe5c5b8073..474cd81aa8ad 100644 --- a/arch/arm/mach-s3c24xx/mach-smdk2443.c +++ b/arch/arm/mach-s3c24xx/mach-smdk2443.c @@ -111,9 +111,6 @@ static struct platform_device *smdk2443_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_hsmmc1, -#ifdef CONFIG_SND_SOC_SMDK2443_WM9710 - &s3c_device_ac97, -#endif &s3c2443_device_dma, }; @@ -133,11 +130,6 @@ static void __init smdk2443_init_time(void) static void __init smdk2443_machine_init(void) { s3c_i2c0_set_platdata(NULL); - -#ifdef CONFIG_SND_SOC_SMDK2443_WM9710 - s3c24xx_ac97_setup_gpio(S3C24XX_AC97_GPE0); -#endif - platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices)); smdk_machine_init(); } diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c index f5e6322145fa..1adc957edf0f 100644 --- a/arch/arm/mach-s3c24xx/mach-vstms.c +++ b/arch/arm/mach-s3c24xx/mach-vstms.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-s3c24xx/sleep.S b/arch/arm/mach-s3c24xx/sleep.S index d833d616bd2e..b859268fa8da 100644 --- a/arch/arm/mach-s3c24xx/sleep.S +++ b/arch/arm/mach-s3c24xx/sleep.S @@ -33,10 +33,11 @@ #include #include -/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not +/* + * S3C24XX_DEBUG_RESUME is dangerous if your bootloader does not * reset the UART configuration, only enable if you really need this! -*/ -//#define CONFIG_DEBUG_RESUME + */ +//#define S3C24XX_DEBUG_RESUME .text @@ -71,13 +72,13 @@ ENTRY(s3c_cpu_resume) str r12, [ r14, #0x54 ] #endif -#ifdef CONFIG_DEBUG_RESUME +#ifdef S3C24XX_DEBUG_RESUME mov r3, #'L' strb r3, [ r2, #S3C2410_UTXH ] 1001: ldrb r14, [ r3, #S3C2410_UTRSTAT ] tst r14, #S3C2410_UTRSTAT_TXE beq 1001b -#endif /* CONFIG_DEBUG_RESUME */ +#endif /* S3C24XX_DEBUG_RESUME */ b cpu_resume diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h index 9c739eafe95c..40ca8de21096 100644 --- a/arch/arm/mach-s3c64xx/include/mach/dma.h +++ b/arch/arm/mach-s3c64xx/include/mach/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* linux/arch/arm/mach-s3c6400/include/mach/dma.h * * Copyright 2008 Openmoko, Inc. diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h index 3ceb00b5de07..c244e480e6b3 100644 --- a/arch/arm/mach-s3c64xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* linux/arch/arm/mach-s3c64xx/include/mach/irqs.h * * Copyright 2008 Openmoko, Inc. diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h index 81f7f6e6832e..592a2be3d2aa 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio.h * * Copyright 2008 Openmoko, Inc. diff --git a/arch/arm/mach-s3c64xx/regs-gpio-memport.h b/arch/arm/mach-s3c64xx/regs-gpio-memport.h index b927593019f5..589afe1132d6 100644 --- a/arch/arm/mach-s3c64xx/regs-gpio-memport.h +++ b/arch/arm/mach-s3c64xx/regs-gpio-memport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2008 Openmoko, Inc. * Copyright 2008 Simtec Electronics diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index ebc4d58e1a32..28c1cae0053f 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c index 7d52cd97d96e..b2eb3d232e39 100644 --- a/arch/arm/mach-sa1100/clock.c +++ b/arch/arm/mach-sa1100/clock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-sa1100/clock.c */ diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h index 68199b603ff7..97502922a15d 100644 --- a/arch/arm/mach-sa1100/generic.h +++ b/arch/arm/mach-sa1100/generic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/arm/mach-sa1100/generic.h * diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h index 7972617cca64..6e6ff3e18f0f 100644 --- a/arch/arm/mach-sa1100/include/mach/SA-1100.h +++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * FILE SA-1100.h * diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h index c23fcdb047a5..558b45323a2d 100644 --- a/arch/arm/mach-sa1100/include/mach/assabet.h +++ b/arch/arm/mach-sa1100/include/mach/assabet.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/assabet.h * diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h index b478ca180c19..b7bc23ffd3c6 100644 --- a/arch/arm/mach-sa1100/include/mach/collie.h +++ b/arch/arm/mach-sa1100/include/mach/collie.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/collie.h * diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h index cc43f95f33cc..6f2dbdc28663 100644 --- a/arch/arm/mach-sa1100/include/mach/hardware.h +++ b/arch/arm/mach-sa1100/include/mach/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/hardware.h * diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h index 734e30e406a3..f4a41e665262 100644 --- a/arch/arm/mach-sa1100/include/mach/irqs.h +++ b/arch/arm/mach-sa1100/include/mach/irqs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/irqs.h * diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h index 2054051eb797..fa5cf4744992 100644 --- a/arch/arm/mach-sa1100/include/mach/memory.h +++ b/arch/arm/mach-sa1100/include/mach/memory.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/memory.h * diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h index 5516a52a329d..18411cfdfe8e 100644 --- a/arch/arm/mach-sa1100/include/mach/neponset.h +++ b/arch/arm/mach-sa1100/include/mach/neponset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/neponset.h * diff --git a/arch/arm/mach-sa1100/include/mach/reset.h b/arch/arm/mach-sa1100/include/mach/reset.h index f61957e6842a..27695650a567 100644 --- a/arch/arm/mach-sa1100/include/mach/reset.h +++ b/arch/arm/mach-sa1100/include/mach/reset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ARCH_RESET_H #define __ASM_ARCH_RESET_H diff --git a/arch/arm/mach-sa1100/include/mach/shannon.h b/arch/arm/mach-sa1100/include/mach/shannon.h index fff39e02b496..d830375f329c 100644 --- a/arch/arm/mach-sa1100/include/mach/shannon.h +++ b/arch/arm/mach-sa1100/include/mach/shannon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _INCLUDE_SHANNON_H #define _INCLUDE_SHANNON_H diff --git a/arch/arm/mach-sa1100/include/mach/simpad.h b/arch/arm/mach-sa1100/include/mach/simpad.h index ac2ea767215d..d53d680de3d9 100644 --- a/arch/arm/mach-sa1100/include/mach/simpad.h +++ b/arch/arm/mach-sa1100/include/mach/simpad.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/simpad.h * diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h index a1a041b9740b..f5eaa90a4576 100644 --- a/arch/arm/mach-sa1100/include/mach/uncompress.h +++ b/arch/arm/mach-sa1100/include/mach/uncompress.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/arm/mach-sa1100/include/mach/uncompress.h * diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 51b0eb52c014..e3a0279750e3 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-sa1100/lart.c */ diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 8411985af9ff..a61a2432766b 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-sa1100/neponset.c */ diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 88149f85bc49..b2b0c9fc18f7 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-sa1100/pleb.c */ diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index c8866bce7386..856664c783d9 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-sa1100/shannon.c */ diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index bb3ca9c763de..e8d25a7bbcb8 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mach-sa1100/simpad.c */ diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index ad7d604ff001..280e7312a9e1 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -1,9 +1,6 @@ config ARCH_SHMOBILE bool -config ARCH_SHMOBILE_MULTI - bool - config PM_RMOBILE bool select PM @@ -34,7 +31,6 @@ menuconfig ARCH_RENESAS depends on ARCH_MULTI_V7 && MMU select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_SHMOBILE - select ARCH_SHMOBILE_MULTI select ARM_GIC select GPIOLIB select HAVE_ARM_SCU if SMP diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 64611a1b4276..e16b81ec4b07 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 1a8f7b3ab449..f8fcd799d677 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_MACH_COMMON_H #define __ARCH_MACH_COMMON_H diff --git a/arch/arm/mach-shmobile/emev2.h b/arch/arm/mach-shmobile/emev2.h index 916d25f6780e..39f6cd8e6003 100644 --- a/arch/arm/mach-shmobile/emev2.h +++ b/arch/arm/mach-shmobile/emev2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_EMEV2_H__ #define __ASM_EMEV2_H__ diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index 0178da7ace82..e5f215c8b218 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c @@ -11,7 +11,9 @@ */ #include +#include #include +#include #include #include #include @@ -69,8 +71,9 @@ void __init rcar_gen2_pm_init(void) struct device_node *np, *cpus; bool has_a7 = false; bool has_a15 = false; - phys_addr_t boot_vector_addr = ICRAM1; + struct resource res; u32 syscier = 0; + int error; if (once++) return; @@ -91,14 +94,38 @@ void __init rcar_gen2_pm_init(void) else if (of_machine_is_compatible("renesas,r8a7791")) syscier = 0x00111003; + np = of_find_compatible_node(NULL, NULL, "renesas,smp-sram"); + if (!np) { + /* No smp-sram in DT, fall back to hardcoded address */ + res = (struct resource)DEFINE_RES_MEM(ICRAM1, + shmobile_boot_size); + goto map; + } + + error = of_address_to_resource(np, 0, &res); + if (error) { + pr_err("Failed to get smp-sram address: %d\n", error); + return; + } + +map: /* RAM for jump stub, because BAR requires 256KB aligned address */ - p = ioremap_nocache(boot_vector_addr, shmobile_boot_size); + if (res.start & (256 * 1024 - 1) || + resource_size(&res) < shmobile_boot_size) { + pr_err("Invalid smp-sram region\n"); + return; + } + + p = ioremap(res.start, resource_size(&res)); + if (!p) + return; + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); iounmap(p); /* setup reset vectors */ p = ioremap_nocache(RST, 0x63); - bar = phys_to_sbar(boot_vector_addr); + bar = phys_to_sbar(res.start); if (has_a15) { writel_relaxed(bar, p + CA15BAR); writel_relaxed(bar | SBAR_BAREN, p + CA15BAR); diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 699429f28b73..3a4ed4c33a68 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -195,8 +195,7 @@ static void __init add_special_pd(struct device_node *np, enum pd_types type) return; } - pr_debug("Special PM domain %s type %d for %s\n", pd->name, type, - np->full_name); + pr_debug("Special PM domain %s type %d for %pOF\n", pd->name, type, np); special_pds[num_special_pds].pd = pd; special_pds[num_special_pds].type = type; @@ -331,13 +330,13 @@ static int __init rmobile_init_pm_domains(void) for_each_compatible_node(np, NULL, "renesas,sysc-rmobile") { base = of_iomap(np, 0); if (!base) { - pr_warn("%s cannot map reg 0\n", np->full_name); + pr_warn("%pOF cannot map reg 0\n", np); continue; } pmd = of_get_child_by_name(np, "pm-domains"); if (!pmd) { - pr_warn("%s lacks pm-domains node\n", np->full_name); + pr_warn("%pOF lacks pm-domains node\n", np); continue; } diff --git a/arch/arm/mach-shmobile/r8a7779.h b/arch/arm/mach-shmobile/r8a7779.h index 2a5f7730a03c..30668aa6acc3 100644 --- a/arch/arm/mach-shmobile/r8a7779.h +++ b/arch/arm/mach-shmobile/r8a7779.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_R8A7779_H__ #define __ASM_R8A7779_H__ diff --git a/arch/arm/mach-shmobile/r8a7790.h b/arch/arm/mach-shmobile/r8a7790.h index 136f3455e9c7..669c8cd09e07 100644 --- a/arch/arm/mach-shmobile/r8a7790.h +++ b/arch/arm/mach-shmobile/r8a7790.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_R8A7790_H__ #define __ASM_R8A7790_H__ diff --git a/arch/arm/mach-shmobile/r8a7791.h b/arch/arm/mach-shmobile/r8a7791.h index cf7a8405bd7f..8c794aace938 100644 --- a/arch/arm/mach-shmobile/r8a7791.h +++ b/arch/arm/mach-shmobile/r8a7791.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_R8A7791_H__ #define __ASM_R8A7791_H__ diff --git a/arch/arm/mach-shmobile/rcar-gen2.h b/arch/arm/mach-shmobile/rcar-gen2.h index 6792e249cf56..4777fff2de41 100644 --- a/arch/arm/mach-shmobile/rcar-gen2.h +++ b/arch/arm/mach-shmobile/rcar-gen2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_RCAR_GEN2_H__ #define __ASM_RCAR_GEN2_H__ diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index a6e74f481dea..7ab1690fab82 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -29,17 +29,29 @@ #include "common.h" #include "rcar-gen2.h" +static const struct of_device_id cpg_matches[] __initconst = { + { .compatible = "renesas,rcar-gen2-cpg-clocks", }, + { .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" }, + { .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" }, + { .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" }, + { .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" }, + { /* sentinel */ } +}; + static unsigned int __init get_extal_freq(void) { + const struct of_device_id *match; struct device_node *cpg, *extal; u32 freq = 20000000; + int idx = 0; - cpg = of_find_compatible_node(NULL, NULL, - "renesas,rcar-gen2-cpg-clocks"); + cpg = of_find_matching_node_and_match(NULL, cpg_matches, &match); if (!cpg) return freq; - extal = of_parse_phandle(cpg, "clocks", 0); + if (match->data) + idx = of_property_match_string(cpg, "clock-names", match->data); + extal = of_parse_phandle(cpg, "clocks", idx); of_node_put(cpg); if (!extal) return freq; @@ -58,7 +70,8 @@ void __init rcar_gen2_timer_init(void) void __iomem *base; u32 freq; - if (of_machine_is_compatible("renesas,r8a7792") || + if (of_machine_is_compatible("renesas,r8a7745") || + of_machine_is_compatible("renesas,r8a7792") || of_machine_is_compatible("renesas,r8a7794")) { freq = 260000000 / 8; /* ZS / 8 */ /* CNTVOFF has to be initialized either from non-secure diff --git a/arch/arm/mach-shmobile/sh73a0.h b/arch/arm/mach-shmobile/sh73a0.h index 50ef24f780b3..85c7c7c60b1e 100644 --- a/arch/arm/mach-shmobile/sh73a0.h +++ b/arch/arm/mach-shmobile/sh73a0.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH73A0_H__ #define __ASM_SH73A0_H__ diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index ed15db19e561..9ec31fad7136 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-spear/Makefile b/arch/arm/mach-spear/Makefile index a946c19ab31a..176b14f83089 100644 --- a/arch/arm/mach-spear/Makefile +++ b/arch/arm/mach-spear/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # SPEAr Platform specific Makefile # diff --git a/arch/arm/mach-tango/Kconfig b/arch/arm/mach-tango/Kconfig index ebe15b93bbe8..25b2fd434861 100644 --- a/arch/arm/mach-tango/Kconfig +++ b/arch/arm/mach-tango/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_TANGO bool "Sigma Designs Tango4 (SMP87xx)" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-tango/Makefile b/arch/arm/mach-tango/Makefile index 204fcd9fe180..da6c633d3cc0 100644 --- a/arch/arm/mach-tango/Makefile +++ b/arch/arm/mach-tango/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_smc.o := -Wa,-march=armv7-a$(plus_sec) diff --git a/arch/arm/mach-tango/platsmp.c b/arch/arm/mach-tango/platsmp.c index 2f0c6c050fed..65012afbc1a3 100644 --- a/arch/arm/mach-tango/platsmp.c +++ b/arch/arm/mach-tango/platsmp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-tango/pm.c b/arch/arm/mach-tango/pm.c index 406c0814eb6e..028e50c6383f 100644 --- a/arch/arm/mach-tango/pm.c +++ b/arch/arm/mach-tango/pm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mach-tango/setup.c b/arch/arm/mach-tango/setup.c index f14b6c7d255b..677dd7b5efd9 100644 --- a/arch/arm/mach-tango/setup.c +++ b/arch/arm/mach-tango/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "smc.h" diff --git a/arch/arm/mach-tango/smc.S b/arch/arm/mach-tango/smc.S index 5d932ce3c1bd..361a8dc89804 100644 --- a/arch/arm/mach-tango/smc.S +++ b/arch/arm/mach-tango/smc.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include ENTRY(tango_smc) diff --git a/arch/arm/mach-tango/smc.h b/arch/arm/mach-tango/smc.h index 57919539da1b..455ce3e06daf 100644 --- a/arch/arm/mach-tango/smc.h +++ b/arch/arm/mach-tango/smc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ extern int tango_smc(unsigned int val, unsigned int service); #define tango_set_l2_control(val) tango_smc(val, 0x102) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 329f01c5b6f8..1e0aeb47bac6 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_TEGRA bool "NVIDIA Tegra" depends on ARCH_MULTI_V7 @@ -13,5 +14,7 @@ menuconfig ARCH_TEGRA select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER select SOC_BUS + select ZONE_DMA if ARM_LPAE + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE help This enables support for NVIDIA Tegra based systems. diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 3b33f0bb78ae..6c1dff2eccc2 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 asflags-y += -march=armv7-a obj-y += io.o diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c index d3aa9be16621..e3fbcfedf845 100644 --- a/arch/arm/mach-tegra/cpuidle-tegra114.c +++ b/arch/arm/mach-tegra/cpuidle-tegra114.c @@ -60,7 +60,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev, return index; } -static void tegra114_idle_enter_freeze(struct cpuidle_device *dev, +static void tegra114_idle_enter_s2idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { @@ -77,7 +77,7 @@ static struct cpuidle_driver tegra_idle_driver = { #ifdef CONFIG_PM_SLEEP [1] = { .enter = tegra114_idle_power_down, - .enter_freeze = tegra114_idle_enter_freeze, + .enter_s2idle = tegra114_idle_enter_s2idle, .exit_latency = 500, .target_residency = 1000, .flags = CPUIDLE_FLAG_TIMER_STOP, diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 649e9e8c7bcc..02e712d2ea30 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -84,35 +84,8 @@ static void __init tegra_dt_init_irq(void) static void __init tegra_dt_init(void) { - struct soc_device_attribute *soc_dev_attr; - struct soc_device *soc_dev; - struct device *parent = NULL; + struct device *parent = tegra_soc_device_register(); - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); - if (!soc_dev_attr) - goto out; - - soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", - tegra_sku_info.revision); - soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id()); - - soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - kfree(soc_dev_attr->family); - kfree(soc_dev_attr->revision); - kfree(soc_dev_attr->soc_id); - kfree(soc_dev_attr); - goto out; - } - - parent = soc_device_to_device(soc_dev); - - /* - * Finished with the static registrations now; fill in the missing - * devices - */ -out: of_platform_default_populate(NULL, NULL, parent); } diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 22dcbf5b76b2..4f43c1cd5db0 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_U300 bool "ST-Ericsson U300 Series" depends on ARCH_MULTI_V5 && MMU diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig index 3930fbba30b4..779235a9147d 100644 --- a/arch/arm/mach-uniphier/Kconfig +++ b/arch/arm/mach-uniphier/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_UNIPHIER bool "Socionext UniPhier SoCs" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 4740ac393297..f98332ea2ef2 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_U8500 bool "ST-Ericsson U8500 Series" depends on ARCH_MULTI_V7 && MMU diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 71a34e8c345a..57058ac46f49 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -32,6 +32,7 @@ #include #include "db8500-regs.h" +#include "pm_domains.h" static int __init ux500_l2x0_unlock(void) { @@ -157,6 +158,9 @@ static const struct of_device_id u8500_local_bus_nodes[] = { static void __init u8500_init_machine(void) { + /* Initialize ux500 power domains */ + ux500_pm_domains_init(); + /* automatically probe child nodes of dbx5x0 devices */ if (of_machine_is_compatible("st-ericsson,u8540")) of_platform_populate(NULL, u8500_local_bus_nodes, diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c index a970e7fcba9e..f6c33a0c1c61 100644 --- a/arch/arm/mach-ux500/pm.c +++ b/arch/arm/mach-ux500/pm.c @@ -19,7 +19,6 @@ #include #include "db8500-regs.h" -#include "pm_domains.h" /* ARM WFI Standby signal register */ #define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130) @@ -203,7 +202,4 @@ void __init ux500_pm_init(u32 phy_base, u32 size) /* Set up ux500 suspend callbacks. */ suspend_set_ops(UX500_SUSPEND_OPS); - - /* Initialize ux500 power domains */ - ux500_pm_domains_init(); } diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig index c257d40ca51d..f5c275434d6c 100644 --- a/arch/arm/mach-versatile/Kconfig +++ b/arch/arm/mach-versatile/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_VERSATILE bool "ARM Ltd. Versatile family" depends on ARCH_MULTI_V5 diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 7c728ebc0b33..726a68085c3b 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_VEXPRESS bool "ARM Ltd. Versatile Express family" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile index 73caae71f307..51c35e2b737a 100644 --- a/arch/arm/mach-vexpress/Makefile +++ b/arch/arm/mach-vexpress/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index a0400f4cca89..95886b3bb9dd 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "core.h" diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig index c4f1dba7bd8a..1156a585dafc 100644 --- a/arch/arm/mach-vt8500/Kconfig +++ b/arch/arm/mach-vt8500/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_VT8500 bool select GPIOLIB diff --git a/arch/arm/mach-w90x900/Kconfig b/arch/arm/mach-w90x900/Kconfig index 69bab32a8bc2..b16ffc03bbe5 100644 --- a/arch/arm/mach-w90x900/Kconfig +++ b/arch/arm/mach-w90x900/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ARCH_W90X900 config CPU_W90P910 diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile index 828c0326441e..33b5bf53990f 100644 --- a/arch/arm/mach-w90x900/Makefile +++ b/arch/arm/mach-w90x900/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/mach-zx/Kconfig b/arch/arm/mach-zx/Kconfig index 209c97944de2..ea29c84a7849 100644 --- a/arch/arm/mach-zx/Kconfig +++ b/arch/arm/mach-zx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARCH_ZX bool "ZTE ZX family" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index fd0aeeb09881..1ca633e3d024 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_ZYNQ bool "Xilinx Zynq ARM Cortex A9 Platform" depends on ARCH_MULTI_V7 diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 60cdfdc151aa..fd9077a74fce 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 comment "Processor Type" # Select CPU types depending on the architecture selected. This selects diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 950d19babb5f..f353ee569f6b 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux arm-specific parts of the memory manager. # diff --git a/arch/arm/mm/abort-ev4.S b/arch/arm/mm/abort-ev4.S index b3b31e30cadd..a10bcb89594d 100644 --- a/arch/arm/mm/abort-ev4.S +++ b/arch/arm/mm/abort-ev4.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include /* diff --git a/arch/arm/mm/abort-ev4t.S b/arch/arm/mm/abort-ev4t.S index 9da704e7b86e..14743a2f6997 100644 --- a/arch/arm/mm/abort-ev4t.S +++ b/arch/arm/mm/abort-ev4t.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include "abort-macro.S" diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S index a6a381a6caa5..98c523118820 100644 --- a/arch/arm/mm/abort-ev5t.S +++ b/arch/arm/mm/abort-ev5t.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include "abort-macro.S" diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S index 00ab011bef58..fec72f4fbaf5 100644 --- a/arch/arm/mm/abort-ev5tj.S +++ b/arch/arm/mm/abort-ev5tj.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include "abort-macro.S" diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index 8801a15aa105..c58bf8b43fea 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include "abort-macro.S" diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S index e8d0e08c227f..f7cc5d68444b 100644 --- a/arch/arm/mm/abort-ev7.S +++ b/arch/arm/mm/abort-ev7.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include /* diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index 4cdfab31a0b6..fbd60a120f66 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include /* diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S index 4509bee4e081..bacf53fd0b70 100644 --- a/arch/arm/mm/abort-macro.S +++ b/arch/arm/mm/abort-macro.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * The ARM LDRD and Thumb LDRSB instructions use bit 20/11 (ARM/Thumb) * differently than every other instruction, so it is set to 0 (write) diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S index 119cb479c2ab..6e2366a26321 100644 --- a/arch/arm/mm/abort-nommu.S +++ b/arch/arm/mm/abort-nommu.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include /* diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S index 2522f8c8fbb1..a5084ec70c6e 100644 --- a/arch/arm/mm/cache-v4wb.S +++ b/arch/arm/mm/cache-v4wb.S @@ -47,6 +47,7 @@ #define CACHE_DLIMIT (CACHE_DSIZE * 4) .data + .align 2 flush_base: .long FLUSH_BASE .text diff --git a/arch/arm/mm/dma.h b/arch/arm/mm/dma.h index 70ea6852f94e..aaef64b7f177 100644 --- a/arch/arm/mm/dma.h +++ b/arch/arm/mm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DMA_H #define DMA_H diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c index f436f7439e46..fc33564597b8 100644 --- a/arch/arm/mm/extable.c +++ b/arch/arm/mm/extable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mm/extable.c */ diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index ff8b0aa2dfde..42f585379e19 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -315,8 +315,11 @@ retry: * signal first. We do not need to release the mmap_sem because * it would already be released in __lock_page_or_retry in * mm/filemap.c. */ - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { + if (!user_mode(regs)) + goto no_context; return 0; + } /* * Major/minor page fault accounting is only done on the diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h index afc1f84e763b..c063708fa503 100644 --- a/arch/arm/mm/fault.h +++ b/arch/arm/mm/fault.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_ARM_FAULT_H #define __ARCH_ARM_FAULT_H diff --git a/arch/arm/mm/fsr-2level.c b/arch/arm/mm/fsr-2level.c index 18ca74c0f341..f2be95197265 100644 --- a/arch/arm/mm/fsr-2level.c +++ b/arch/arm/mm/fsr-2level.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 static struct fsr_info fsr_info[] = { /* * The following are the standard ARMv3 and ARMv4 aborts. ARMv5 diff --git a/arch/arm/mm/fsr-3level.c b/arch/arm/mm/fsr-3level.c index ab4409a2307e..d0ae2963656a 100644 --- a/arch/arm/mm/fsr-3level.c +++ b/arch/arm/mm/fsr-3level.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 static struct fsr_info fsr_info[] = { { do_bad, SIGBUS, 0, "unknown 0" }, { do_bad, SIGBUS, 0, "unknown 1" }, diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 3e511bec69b8..10bfba85eb96 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c index 4614208369f1..091ddc56827e 100644 --- a/arch/arm/mm/iomap.c +++ b/arch/arm/mm/iomap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mm/iomap.c * diff --git a/arch/arm/mm/l2c-l2x0-resume.S b/arch/arm/mm/l2c-l2x0-resume.S index fda415e4ca8f..fc01f1b18523 100644 --- a/arch/arm/mm/l2c-l2x0-resume.S +++ b/arch/arm/mm/l2c-l2x0-resume.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * L2C-310 early resume code. This can be used by platforms to restore * the settings of their L2 cache controller before restoring the diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index ce727d47275c..6b045c6653ea 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_MMU #include #include diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index f0701d8d24df..eb1de66517d5 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/arm/mm/mmap.c */ diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 3b8e728cc944..91537d90f5f5 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -344,6 +344,11 @@ void __init arm_mm_memblock_reserve(void) * reserved here. */ #endif + /* + * In any case, always ensure address 0 is never used as many things + * get very confused if 0 is returned as a legitimate address. + */ + memblock_reserve(0, 1); } void __init adjust_lowmem_bounds(void) diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S index 8bbff025269a..b2ffce420106 100644 --- a/arch/arm/mm/pabort-legacy.S +++ b/arch/arm/mm/pabort-legacy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S index 9627646ce783..8686265dc941 100644 --- a/arch/arm/mm/pabort-v6.S +++ b/arch/arm/mm/pabort-v6.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S index 875761f44f3b..9c70b1a21dc9 100644 --- a/arch/arm/mm/pabort-v7.S +++ b/arch/arm/mm/pabort-v7.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/mm/physaddr.c b/arch/arm/mm/physaddr.c index 02e60f495608..cf75819e4c13 100644 --- a/arch/arm/mm/physaddr.c +++ b/arch/arm/mm/physaddr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index f944836da8a2..f10e31d0730a 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * We need constants.h for: * VMA_VM_MM diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S index 5e5720e8bc5f..7d16bbc4102b 100644 --- a/arch/arm/mm/proc-v7-3level.S +++ b/arch/arm/mm/proc-v7-3level.S @@ -129,8 +129,7 @@ ENDPROC(cpu_v7_set_pte_ext) .macro v7_ttb_setup, zero, ttbr0l, ttbr0h, ttbr1, tmp ldr \tmp, =swapper_pg_dir @ swapper_pg_dir virtual address cmp \ttbr1, \tmp, lsr #12 @ PHYS_OFFSET > PAGE_OFFSET? - mrc p15, 0, \tmp, c2, c0, 2 @ TTB control egister - orr \tmp, \tmp, #TTB_EAE + mov \tmp, #TTB_EAE @ for TTB control egister ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP) ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP) ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16) diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index b6bbfdb6dfdc..3d75b7972fd1 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -104,6 +104,7 @@ .endm .data + .align 2 clean_addr: .word CLEAN_ADDR .text diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index d5b9fa19b684..c199990e12b6 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1,6 +1,7 @@ /* - * Just-In-Time compiler for BPF filters on 32bit ARM + * Just-In-Time compiler for eBPF filters on 32bit ARM * + * Copyright (c) 2017 Shubham Bansal * Copyright (c) 2011 Mircea Gherzan * * This program is free software; you can redistribute it and/or modify it @@ -8,6 +9,7 @@ * Free Software Foundation; version 2 of the License. */ +#include #include #include #include @@ -18,54 +20,101 @@ #include #include -#include #include #include #include "bpf_jit_32.h" +int bpf_jit_enable __read_mostly; + +#define STACK_OFFSET(k) (k) +#define TMP_REG_1 (MAX_BPF_JIT_REG + 0) /* TEMP Register 1 */ +#define TMP_REG_2 (MAX_BPF_JIT_REG + 1) /* TEMP Register 2 */ +#define TCALL_CNT (MAX_BPF_JIT_REG + 2) /* Tail Call Count */ + +/* Flags used for JIT optimization */ +#define SEEN_CALL (1 << 0) + +#define FLAG_IMM_OVERFLOW (1 << 0) + /* - * ABI: + * Map eBPF registers to ARM 32bit registers or stack scratch space. * - * r0 scratch register - * r4 BPF register A - * r5 BPF register X - * r6 pointer to the skb - * r7 skb->data - * r8 skb_headlen(skb) + * 1. First argument is passed using the arm 32bit registers and rest of the + * arguments are passed on stack scratch space. + * 2. First callee-saved arugument is mapped to arm 32 bit registers and rest + * arguments are mapped to scratch space on stack. + * 3. We need two 64 bit temp registers to do complex operations on eBPF + * registers. + * + * As the eBPF registers are all 64 bit registers and arm has only 32 bit + * registers, we have to map each eBPF registers with two arm 32 bit regs or + * scratch memory space and we have to build eBPF 64 bit register from those. + * + */ +static const u8 bpf2a32[][2] = { + /* return value from in-kernel function, and exit value from eBPF */ + [BPF_REG_0] = {ARM_R1, ARM_R0}, + /* arguments from eBPF program to in-kernel function */ + [BPF_REG_1] = {ARM_R3, ARM_R2}, + /* Stored on stack scratch space */ + [BPF_REG_2] = {STACK_OFFSET(0), STACK_OFFSET(4)}, + [BPF_REG_3] = {STACK_OFFSET(8), STACK_OFFSET(12)}, + [BPF_REG_4] = {STACK_OFFSET(16), STACK_OFFSET(20)}, + [BPF_REG_5] = {STACK_OFFSET(24), STACK_OFFSET(28)}, + /* callee saved registers that in-kernel function will preserve */ + [BPF_REG_6] = {ARM_R5, ARM_R4}, + /* Stored on stack scratch space */ + [BPF_REG_7] = {STACK_OFFSET(32), STACK_OFFSET(36)}, + [BPF_REG_8] = {STACK_OFFSET(40), STACK_OFFSET(44)}, + [BPF_REG_9] = {STACK_OFFSET(48), STACK_OFFSET(52)}, + /* Read only Frame Pointer to access Stack */ + [BPF_REG_FP] = {STACK_OFFSET(56), STACK_OFFSET(60)}, + /* Temporary Register for internal BPF JIT, can be used + * for constant blindings and others. + */ + [TMP_REG_1] = {ARM_R7, ARM_R6}, + [TMP_REG_2] = {ARM_R10, ARM_R8}, + /* Tail call count. Stored on stack scratch space. */ + [TCALL_CNT] = {STACK_OFFSET(64), STACK_OFFSET(68)}, + /* temporary register for blinding constants. + * Stored on stack scratch space. + */ + [BPF_REG_AX] = {STACK_OFFSET(72), STACK_OFFSET(76)}, +}; + +#define dst_lo dst[1] +#define dst_hi dst[0] +#define src_lo src[1] +#define src_hi src[0] + +/* + * JIT Context: + * + * prog : bpf_prog + * idx : index of current last JITed instruction. + * prologue_bytes : bytes used in prologue. + * epilogue_offset : offset of epilogue starting. + * seen : bit mask used for JIT optimization. + * offsets : array of eBPF instruction offsets in + * JITed code. + * target : final JITed code. + * epilogue_bytes : no of bytes used in epilogue. + * imm_count : no of immediate counts used for global + * variables. + * imms : array of global variable addresses. */ -#define r_scratch ARM_R0 -/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */ -#define r_off ARM_R1 -#define r_A ARM_R4 -#define r_X ARM_R5 -#define r_skb ARM_R6 -#define r_skb_data ARM_R7 -#define r_skb_hl ARM_R8 - -#define SCRATCH_SP_OFFSET 0 -#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + 4 * (k)) - -#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1) -#define SEEN_MEM_WORD(k) (1 << (k)) -#define SEEN_X (1 << BPF_MEMWORDS) -#define SEEN_CALL (1 << (BPF_MEMWORDS + 1)) -#define SEEN_SKB (1 << (BPF_MEMWORDS + 2)) -#define SEEN_DATA (1 << (BPF_MEMWORDS + 3)) - -#define FLAG_NEED_X_RESET (1 << 0) -#define FLAG_IMM_OVERFLOW (1 << 1) - struct jit_ctx { - const struct bpf_prog *skf; - unsigned idx; - unsigned prologue_bytes; - int ret0_fp_idx; + const struct bpf_prog *prog; + unsigned int idx; + unsigned int prologue_bytes; + unsigned int epilogue_offset; u32 seen; u32 flags; u32 *offsets; u32 *target; + u32 stack_size; #if __LINUX_ARM_ARCH__ < 7 u16 epilogue_bytes; u16 imm_count; @@ -73,68 +122,16 @@ struct jit_ctx { #endif }; -int bpf_jit_enable __read_mostly; - -static inline int call_neg_helper(struct sk_buff *skb, int offset, void *ret, - unsigned int size) -{ - void *ptr = bpf_internal_load_pointer_neg_helper(skb, offset, size); - - if (!ptr) - return -EFAULT; - memcpy(ret, ptr, size); - return 0; -} - -static u64 jit_get_skb_b(struct sk_buff *skb, int offset) -{ - u8 ret; - int err; - - if (offset < 0) - err = call_neg_helper(skb, offset, &ret, 1); - else - err = skb_copy_bits(skb, offset, &ret, 1); - - return (u64)err << 32 | ret; -} - -static u64 jit_get_skb_h(struct sk_buff *skb, int offset) -{ - u16 ret; - int err; - - if (offset < 0) - err = call_neg_helper(skb, offset, &ret, 2); - else - err = skb_copy_bits(skb, offset, &ret, 2); - - return (u64)err << 32 | ntohs(ret); -} - -static u64 jit_get_skb_w(struct sk_buff *skb, int offset) -{ - u32 ret; - int err; - - if (offset < 0) - err = call_neg_helper(skb, offset, &ret, 4); - else - err = skb_copy_bits(skb, offset, &ret, 4); - - return (u64)err << 32 | ntohl(ret); -} - /* * Wrappers which handle both OABI and EABI and assures Thumb2 interworking * (where the assembly routines like __aeabi_uidiv could cause problems). */ -static u32 jit_udiv(u32 dividend, u32 divisor) +static u32 jit_udiv32(u32 dividend, u32 divisor) { return dividend / divisor; } -static u32 jit_mod(u32 dividend, u32 divisor) +static u32 jit_mod32(u32 dividend, u32 divisor) { return dividend % divisor; } @@ -158,36 +155,22 @@ static inline void emit(u32 inst, struct jit_ctx *ctx) _emit(ARM_COND_AL, inst, ctx); } -static u16 saved_regs(struct jit_ctx *ctx) +/* + * Checks if immediate value can be converted to imm12(12 bits) value. + */ +static int16_t imm8m(u32 x) { - u16 ret = 0; + u32 rot; - if ((ctx->skf->len > 1) || - (ctx->skf->insns[0].code == (BPF_RET | BPF_A))) - ret |= 1 << r_A; - -#ifdef CONFIG_FRAME_POINTER - ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC); -#else - if (ctx->seen & SEEN_CALL) - ret |= 1 << ARM_LR; -#endif - if (ctx->seen & (SEEN_DATA | SEEN_SKB)) - ret |= 1 << r_skb; - if (ctx->seen & SEEN_DATA) - ret |= (1 << r_skb_data) | (1 << r_skb_hl); - if (ctx->seen & SEEN_X) - ret |= 1 << r_X; - - return ret; -} - -static inline int mem_words_used(struct jit_ctx *ctx) -{ - /* yes, we do waste some stack space IF there are "holes" in the set" */ - return fls(ctx->seen & SEEN_MEM); + for (rot = 0; rot < 16; rot++) + if ((x & ~ror32(0xff, 2 * rot)) == 0) + return rol32(x, 2 * rot) | (rot << 8); + return -1; } +/* + * Initializes the JIT space with undefined instructions. + */ static void jit_fill_hole(void *area, unsigned int size) { u32 *ptr; @@ -196,88 +179,34 @@ static void jit_fill_hole(void *area, unsigned int size) *ptr++ = __opcode_to_mem_arm(ARM_INST_UDF); } -static void build_prologue(struct jit_ctx *ctx) -{ - u16 reg_set = saved_regs(ctx); - u16 off; +/* Stack must be multiples of 16 Bytes */ +#define STACK_ALIGN(sz) (((sz) + 3) & ~3) -#ifdef CONFIG_FRAME_POINTER - emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx); - emit(ARM_PUSH(reg_set), ctx); - emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx); -#else - if (reg_set) - emit(ARM_PUSH(reg_set), ctx); -#endif +/* Stack space for BPF_REG_2, BPF_REG_3, BPF_REG_4, + * BPF_REG_5, BPF_REG_7, BPF_REG_8, BPF_REG_9, + * BPF_REG_FP and Tail call counts. + */ +#define SCRATCH_SIZE 80 - if (ctx->seen & (SEEN_DATA | SEEN_SKB)) - emit(ARM_MOV_R(r_skb, ARM_R0), ctx); +/* total stack size used in JITed code */ +#define _STACK_SIZE \ + (ctx->prog->aux->stack_depth + \ + + SCRATCH_SIZE + \ + + 4 /* extra for skb_copy_bits buffer */) - if (ctx->seen & SEEN_DATA) { - off = offsetof(struct sk_buff, data); - emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx); - /* headlen = len - data_len */ - off = offsetof(struct sk_buff, len); - emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx); - off = offsetof(struct sk_buff, data_len); - emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); - emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx); - } +#define STACK_SIZE STACK_ALIGN(_STACK_SIZE) - if (ctx->flags & FLAG_NEED_X_RESET) - emit(ARM_MOV_I(r_X, 0), ctx); +/* Get the offset of eBPF REGISTERs stored on scratch space. */ +#define STACK_VAR(off) (STACK_SIZE-off-4) - /* do not leak kernel data to userspace */ - if (bpf_needs_clear_a(&ctx->skf->insns[0])) - emit(ARM_MOV_I(r_A, 0), ctx); - - /* stack space for the BPF_MEM words */ - if (ctx->seen & SEEN_MEM) - emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); -} - -static void build_epilogue(struct jit_ctx *ctx) -{ - u16 reg_set = saved_regs(ctx); - - if (ctx->seen & SEEN_MEM) - emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); - - reg_set &= ~(1 << ARM_LR); - -#ifdef CONFIG_FRAME_POINTER - /* the first instruction of the prologue was: mov ip, sp */ - reg_set &= ~(1 << ARM_IP); - reg_set |= (1 << ARM_SP); - emit(ARM_LDM(ARM_SP, reg_set), ctx); -#else - if (reg_set) { - if (ctx->seen & SEEN_CALL) - reg_set |= 1 << ARM_PC; - emit(ARM_POP(reg_set), ctx); - } - - if (!(ctx->seen & SEEN_CALL)) - emit(ARM_BX(ARM_LR), ctx); -#endif -} - -static int16_t imm8m(u32 x) -{ - u32 rot; - - for (rot = 0; rot < 16; rot++) - if ((x & ~ror32(0xff, 2 * rot)) == 0) - return rol32(x, 2 * rot) | (rot << 8); - - return -1; -} +/* Offset of skb_copy_bits buffer */ +#define SKB_BUFFER STACK_VAR(SCRATCH_SIZE) #if __LINUX_ARM_ARCH__ < 7 static u16 imm_offset(u32 k, struct jit_ctx *ctx) { - unsigned i = 0, offset; + unsigned int i = 0, offset; u16 imm; /* on the "fake" run we just count them (duplicates included) */ @@ -296,7 +225,7 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx) ctx->imms[i] = k; /* constants go just after the epilogue */ - offset = ctx->offsets[ctx->skf->len]; + offset = ctx->offsets[ctx->prog->len - 1] * 4; offset += ctx->prologue_bytes; offset += ctx->epilogue_bytes; offset += i * 4; @@ -320,10 +249,22 @@ static u16 imm_offset(u32 k, struct jit_ctx *ctx) #endif /* __LINUX_ARM_ARCH__ */ +static inline int bpf2a32_offset(int bpf_to, int bpf_from, + const struct jit_ctx *ctx) { + int to, from; + + if (ctx->target == NULL) + return 0; + to = ctx->offsets[bpf_to]; + from = ctx->offsets[bpf_from]; + + return to - from - 1; +} + /* * Move an immediate that's not an imm8m to a core register. */ -static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx) +static inline void emit_mov_i_no8m(const u8 rd, u32 val, struct jit_ctx *ctx) { #if __LINUX_ARM_ARCH__ < 7 emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx); @@ -334,7 +275,7 @@ static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx) #endif } -static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx) +static inline void emit_mov_i(const u8 rd, u32 val, struct jit_ctx *ctx) { int imm12 = imm8m(val); @@ -344,113 +285,9 @@ static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx) emit_mov_i_no8m(rd, val, ctx); } -#if __LINUX_ARM_ARCH__ < 6 - -static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) -{ - _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx); - _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); - _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx); - _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx); - _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx); - _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx); - _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx); - _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx); -} - -static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) -{ - _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); - _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx); - _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx); -} - -static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx) -{ - /* r_dst = (r_src << 8) | (r_src >> 8) */ - emit(ARM_LSL_I(ARM_R1, r_src, 8), ctx); - emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSR, 8), ctx); - - /* - * we need to mask out the bits set in r_dst[23:16] due to - * the first shift instruction. - * - * note that 0x8ff is the encoded immediate 0x00ff0000. - */ - emit(ARM_BIC_I(r_dst, r_dst, 0x8ff), ctx); -} - -#else /* ARMv6+ */ - -static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) -{ - _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx); -#ifdef __LITTLE_ENDIAN - _emit(cond, ARM_REV(r_res, r_res), ctx); -#endif -} - -static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) -{ - _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx); -#ifdef __LITTLE_ENDIAN - _emit(cond, ARM_REV16(r_res, r_res), ctx); -#endif -} - -static inline void emit_swap16(u8 r_dst __maybe_unused, - u8 r_src __maybe_unused, - struct jit_ctx *ctx __maybe_unused) -{ -#ifdef __LITTLE_ENDIAN - emit(ARM_REV16(r_dst, r_src), ctx); -#endif -} - -#endif /* __LINUX_ARM_ARCH__ < 6 */ - - -/* Compute the immediate value for a PC-relative branch. */ -static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx) -{ - u32 imm; - - if (ctx->target == NULL) - return 0; - /* - * BPF allows only forward jumps and the offset of the target is - * still the one computed during the first pass. - */ - imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8); - - return imm >> 2; -} - -#define OP_IMM3(op, r1, r2, imm_val, ctx) \ - do { \ - imm12 = imm8m(imm_val); \ - if (imm12 < 0) { \ - emit_mov_i_no8m(r_scratch, imm_val, ctx); \ - emit(op ## _R((r1), (r2), r_scratch), ctx); \ - } else { \ - emit(op ## _I((r1), (r2), imm12), ctx); \ - } \ - } while (0) - -static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx) -{ - if (ctx->ret0_fp_idx >= 0) { - _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx); - /* NOP to keep the size constant between passes */ - emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx); - } else { - _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx); - _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx); - } -} - static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx) { + ctx->seen |= SEEN_CALL; #if __LINUX_ARM_ARCH__ < 5 emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx); @@ -463,557 +300,1579 @@ static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx) #endif } -static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, - int bpf_op) +static inline int epilogue_offset(const struct jit_ctx *ctx) { + int to, from; + /* No need for 1st dummy run */ + if (ctx->target == NULL) + return 0; + to = ctx->epilogue_offset; + from = ctx->idx; + + return to - from - 2; +} + +static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) +{ + const u8 *tmp = bpf2a32[TMP_REG_1]; + s32 jmp_offset; + + /* checks if divisor is zero or not. If it is, then + * exit directly. + */ + emit(ARM_CMP_I(rn, 0), ctx); + _emit(ARM_COND_EQ, ARM_MOV_I(ARM_R0, 0), ctx); + jmp_offset = epilogue_offset(ctx); + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); #if __LINUX_ARM_ARCH__ == 7 if (elf_hwcap & HWCAP_IDIVA) { - if (bpf_op == BPF_DIV) + if (op == BPF_DIV) emit(ARM_UDIV(rd, rm, rn), ctx); else { - emit(ARM_UDIV(ARM_R3, rm, rn), ctx); - emit(ARM_MLS(rd, rn, ARM_R3, rm), ctx); + emit(ARM_UDIV(ARM_IP, rm, rn), ctx); + emit(ARM_MLS(rd, rn, ARM_IP, rm), ctx); } return; } #endif /* - * For BPF_ALU | BPF_DIV | BPF_K instructions, rm is ARM_R4 - * (r_A) and rn is ARM_R0 (r_scratch) so load rn first into - * ARM_R1 to avoid accidentally overwriting ARM_R0 with rm - * before using it as a source for ARM_R1. - * - * For BPF_ALU | BPF_DIV | BPF_X rm is ARM_R4 (r_A) and rn is - * ARM_R5 (r_X) so there is no particular register overlap - * issues. + * For BPF_ALU | BPF_DIV | BPF_K instructions + * As ARM_R1 and ARM_R0 contains 1st argument of bpf + * function, we need to save it on caller side to save + * it from getting destroyed within callee. + * After the return from the callee, we restore ARM_R0 + * ARM_R1. */ - if (rn != ARM_R1) + if (rn != ARM_R1) { + emit(ARM_MOV_R(tmp[0], ARM_R1), ctx); emit(ARM_MOV_R(ARM_R1, rn), ctx); - if (rm != ARM_R0) + } + if (rm != ARM_R0) { + emit(ARM_MOV_R(tmp[1], ARM_R0), ctx); emit(ARM_MOV_R(ARM_R0, rm), ctx); + } + /* Call appropriate function */ ctx->seen |= SEEN_CALL; - emit_mov_i(ARM_R3, bpf_op == BPF_DIV ? (u32)jit_udiv : (u32)jit_mod, - ctx); - emit_blx_r(ARM_R3, ctx); + emit_mov_i(ARM_IP, op == BPF_DIV ? + (u32)jit_udiv32 : (u32)jit_mod32, ctx); + emit_blx_r(ARM_IP, ctx); + /* Save return value */ if (rd != ARM_R0) emit(ARM_MOV_R(rd, ARM_R0), ctx); + + /* Restore ARM_R0 and ARM_R1 */ + if (rn != ARM_R1) + emit(ARM_MOV_R(ARM_R1, tmp[0]), ctx); + if (rm != ARM_R0) + emit(ARM_MOV_R(ARM_R0, tmp[1]), ctx); } -static inline void update_on_xread(struct jit_ctx *ctx) +/* Checks whether BPF register is on scratch stack space or not. */ +static inline bool is_on_stack(u8 bpf_reg) { - if (!(ctx->seen & SEEN_X)) - ctx->flags |= FLAG_NEED_X_RESET; + static u8 stack_regs[] = {BPF_REG_AX, BPF_REG_3, BPF_REG_4, BPF_REG_5, + BPF_REG_7, BPF_REG_8, BPF_REG_9, TCALL_CNT, + BPF_REG_2, BPF_REG_FP}; + int i, reg_len = sizeof(stack_regs); - ctx->seen |= SEEN_X; + for (i = 0 ; i < reg_len ; i++) { + if (bpf_reg == stack_regs[i]) + return true; + } + return false; +} + +static inline void emit_a32_mov_i(const u8 dst, const u32 val, + bool dstk, struct jit_ctx *ctx) +{ + const u8 *tmp = bpf2a32[TMP_REG_1]; + + if (dstk) { + emit_mov_i(tmp[1], val, ctx); + emit(ARM_STR_I(tmp[1], ARM_SP, STACK_VAR(dst)), ctx); + } else { + emit_mov_i(dst, val, ctx); + } +} + +/* Sign extended move */ +static inline void emit_a32_mov_i64(const bool is64, const u8 dst[], + const u32 val, bool dstk, + struct jit_ctx *ctx) { + u32 hi = 0; + + if (is64 && (val & (1<<31))) + hi = (u32)~0; + emit_a32_mov_i(dst_lo, val, dstk, ctx); + emit_a32_mov_i(dst_hi, hi, dstk, ctx); +} + +static inline void emit_a32_add_r(const u8 dst, const u8 src, + const bool is64, const bool hi, + struct jit_ctx *ctx) { + /* 64 bit : + * adds dst_lo, dst_lo, src_lo + * adc dst_hi, dst_hi, src_hi + * 32 bit : + * add dst_lo, dst_lo, src_lo + */ + if (!hi && is64) + emit(ARM_ADDS_R(dst, dst, src), ctx); + else if (hi && is64) + emit(ARM_ADC_R(dst, dst, src), ctx); + else + emit(ARM_ADD_R(dst, dst, src), ctx); +} + +static inline void emit_a32_sub_r(const u8 dst, const u8 src, + const bool is64, const bool hi, + struct jit_ctx *ctx) { + /* 64 bit : + * subs dst_lo, dst_lo, src_lo + * sbc dst_hi, dst_hi, src_hi + * 32 bit : + * sub dst_lo, dst_lo, src_lo + */ + if (!hi && is64) + emit(ARM_SUBS_R(dst, dst, src), ctx); + else if (hi && is64) + emit(ARM_SBC_R(dst, dst, src), ctx); + else + emit(ARM_SUB_R(dst, dst, src), ctx); +} + +static inline void emit_alu_r(const u8 dst, const u8 src, const bool is64, + const bool hi, const u8 op, struct jit_ctx *ctx){ + switch (BPF_OP(op)) { + /* dst = dst + src */ + case BPF_ADD: + emit_a32_add_r(dst, src, is64, hi, ctx); + break; + /* dst = dst - src */ + case BPF_SUB: + emit_a32_sub_r(dst, src, is64, hi, ctx); + break; + /* dst = dst | src */ + case BPF_OR: + emit(ARM_ORR_R(dst, dst, src), ctx); + break; + /* dst = dst & src */ + case BPF_AND: + emit(ARM_AND_R(dst, dst, src), ctx); + break; + /* dst = dst ^ src */ + case BPF_XOR: + emit(ARM_EOR_R(dst, dst, src), ctx); + break; + /* dst = dst * src */ + case BPF_MUL: + emit(ARM_MUL(dst, dst, src), ctx); + break; + /* dst = dst << src */ + case BPF_LSH: + emit(ARM_LSL_R(dst, dst, src), ctx); + break; + /* dst = dst >> src */ + case BPF_RSH: + emit(ARM_LSR_R(dst, dst, src), ctx); + break; + /* dst = dst >> src (signed)*/ + case BPF_ARSH: + emit(ARM_MOV_SR(dst, dst, SRTYPE_ASR, src), ctx); + break; + } +} + +/* ALU operation (32 bit) + * dst = dst (op) src + */ +static inline void emit_a32_alu_r(const u8 dst, const u8 src, + bool dstk, bool sstk, + struct jit_ctx *ctx, const bool is64, + const bool hi, const u8 op) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rn = sstk ? tmp[1] : src; + + if (sstk) + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src)), ctx); + + /* ALU operation */ + if (dstk) { + emit(ARM_LDR_I(tmp[0], ARM_SP, STACK_VAR(dst)), ctx); + emit_alu_r(tmp[0], rn, is64, hi, op, ctx); + emit(ARM_STR_I(tmp[0], ARM_SP, STACK_VAR(dst)), ctx); + } else { + emit_alu_r(dst, rn, is64, hi, op, ctx); + } +} + +/* ALU operation (64 bit) */ +static inline void emit_a32_alu_r64(const bool is64, const u8 dst[], + const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx, + const u8 op) { + emit_a32_alu_r(dst_lo, src_lo, dstk, sstk, ctx, is64, false, op); + if (is64) + emit_a32_alu_r(dst_hi, src_hi, dstk, sstk, ctx, is64, true, op); + else + emit_a32_mov_i(dst_hi, 0, dstk, ctx); +} + +/* dst = imm (4 bytes)*/ +static inline void emit_a32_mov_r(const u8 dst, const u8 src, + bool dstk, bool sstk, + struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rt = sstk ? tmp[0] : src; + + if (sstk) + emit(ARM_LDR_I(tmp[0], ARM_SP, STACK_VAR(src)), ctx); + if (dstk) + emit(ARM_STR_I(rt, ARM_SP, STACK_VAR(dst)), ctx); + else + emit(ARM_MOV_R(dst, rt), ctx); +} + +/* dst = src */ +static inline void emit_a32_mov_r64(const bool is64, const u8 dst[], + const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + emit_a32_mov_r(dst_lo, src_lo, dstk, sstk, ctx); + if (is64) { + /* complete 8 byte move */ + emit_a32_mov_r(dst_hi, src_hi, dstk, sstk, ctx); + } else { + /* Zero out high 4 bytes */ + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + } +} + +/* Shift operations */ +static inline void emit_a32_alu_i(const u8 dst, const u32 val, bool dstk, + struct jit_ctx *ctx, const u8 op) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[0] : dst; + + if (dstk) + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); + + /* Do shift operation */ + switch (op) { + case BPF_LSH: + emit(ARM_LSL_I(rd, rd, val), ctx); + break; + case BPF_RSH: + emit(ARM_LSR_I(rd, rd, val), ctx); + break; + case BPF_NEG: + emit(ARM_RSB_I(rd, rd, val), ctx); + break; + } + + if (dstk) + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); +} + +/* dst = ~dst (64 bit) */ +static inline void emit_a32_neg64(const u8 dst[], bool dstk, + struct jit_ctx *ctx){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[1] : dst[1]; + u8 rm = dstk ? tmp[0] : dst[0]; + + /* Setup Operand */ + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do Negate Operation */ + emit(ARM_RSBS_I(rd, rd, 0), ctx); + emit(ARM_RSC_I(rm, rm, 0), ctx); + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +/* dst = dst << src */ +static inline void emit_a32_lsh_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + + /* Setup Operands */ + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSH operation */ + emit(ARM_SUB_I(ARM_IP, rt, 32), ctx); + emit(ARM_RSB_I(tmp2[0], rt, 32), ctx); + /* As we are using ARM_LR */ + ctx->seen |= SEEN_CALL; + emit(ARM_MOV_SR(ARM_LR, rm, SRTYPE_ASL, rt), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rd, SRTYPE_ASL, ARM_IP), ctx); + emit(ARM_ORR_SR(ARM_IP, ARM_LR, rd, SRTYPE_LSR, tmp2[0]), ctx); + emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_ASL, rt), ctx); + + if (dstk) { + emit(ARM_STR_I(ARM_LR, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_LR), ctx); + emit(ARM_MOV_R(rm, ARM_IP), ctx); + } +} + +/* dst = dst >> src (signed)*/ +static inline void emit_a32_arsh_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup Operands */ + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do the ARSH operation */ + emit(ARM_RSB_I(ARM_IP, rt, 32), ctx); + emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx); + /* As we are using ARM_LR */ + ctx->seen |= SEEN_CALL; + emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_LSR, rt), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASL, ARM_IP), ctx); + _emit(ARM_COND_MI, ARM_B(0), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASR, tmp2[0]), ctx); + emit(ARM_MOV_SR(ARM_IP, rm, SRTYPE_ASR, rt), ctx); + if (dstk) { + emit(ARM_STR_I(ARM_LR, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_LR), ctx); + emit(ARM_MOV_R(rm, ARM_IP), ctx); + } +} + +/* dst = dst >> src */ +static inline void emit_a32_lsr_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup Operands */ + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSH operation */ + emit(ARM_RSB_I(ARM_IP, rt, 32), ctx); + emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx); + /* As we are using ARM_LR */ + ctx->seen |= SEEN_CALL; + emit(ARM_MOV_SR(ARM_LR, rd, SRTYPE_LSR, rt), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_ASL, ARM_IP), ctx); + emit(ARM_ORR_SR(ARM_LR, ARM_LR, rm, SRTYPE_LSR, tmp2[0]), ctx); + emit(ARM_MOV_SR(ARM_IP, rm, SRTYPE_LSR, rt), ctx); + if (dstk) { + emit(ARM_STR_I(ARM_LR, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_LR), ctx); + emit(ARM_MOV_R(rm, ARM_IP), ctx); + } +} + +/* dst = dst << val */ +static inline void emit_a32_lsh_i64(const u8 dst[], bool dstk, + const u32 val, struct jit_ctx *ctx){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSH operation */ + if (val < 32) { + emit(ARM_MOV_SI(tmp2[0], rm, SRTYPE_ASL, val), ctx); + emit(ARM_ORR_SI(rm, tmp2[0], rd, SRTYPE_LSR, 32 - val), ctx); + emit(ARM_MOV_SI(rd, rd, SRTYPE_ASL, val), ctx); + } else { + if (val == 32) + emit(ARM_MOV_R(rm, rd), ctx); + else + emit(ARM_MOV_SI(rm, rd, SRTYPE_ASL, val - 32), ctx); + emit(ARM_EOR_R(rd, rd, rd), ctx); + } + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +/* dst = dst >> val */ +static inline void emit_a32_lsr_i64(const u8 dst[], bool dstk, + const u32 val, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do LSR operation */ + if (val < 32) { + emit(ARM_MOV_SI(tmp2[1], rd, SRTYPE_LSR, val), ctx); + emit(ARM_ORR_SI(rd, tmp2[1], rm, SRTYPE_ASL, 32 - val), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_LSR, val), ctx); + } else if (val == 32) { + emit(ARM_MOV_R(rd, rm), ctx); + emit(ARM_MOV_I(rm, 0), ctx); + } else { + emit(ARM_MOV_SI(rd, rm, SRTYPE_LSR, val - 32), ctx); + emit(ARM_MOV_I(rm, 0), ctx); + } + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +/* dst = dst >> val (signed) */ +static inline void emit_a32_arsh_i64(const u8 dst[], bool dstk, + const u32 val, struct jit_ctx *ctx){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Do ARSH operation */ + if (val < 32) { + emit(ARM_MOV_SI(tmp2[1], rd, SRTYPE_LSR, val), ctx); + emit(ARM_ORR_SI(rd, tmp2[1], rm, SRTYPE_ASL, 32 - val), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_ASR, val), ctx); + } else if (val == 32) { + emit(ARM_MOV_R(rd, rm), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_ASR, 31), ctx); + } else { + emit(ARM_MOV_SI(rd, rm, SRTYPE_ASR, val - 32), ctx); + emit(ARM_MOV_SI(rm, rm, SRTYPE_ASR, 31), ctx); + } + + if (dstk) { + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } +} + +static inline void emit_a32_mul_r64(const u8 dst[], const u8 src[], bool dstk, + bool sstk, struct jit_ctx *ctx) { + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + /* Setup operands for multiplication */ + u8 rd = dstk ? tmp[1] : dst_lo; + u8 rm = dstk ? tmp[0] : dst_hi; + u8 rt = sstk ? tmp2[1] : src_lo; + u8 rn = sstk ? tmp2[0] : src_hi; + + if (dstk) { + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + if (sstk) { + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), ctx); + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_hi)), ctx); + } + + /* Do Multiplication */ + emit(ARM_MUL(ARM_IP, rd, rn), ctx); + emit(ARM_MUL(ARM_LR, rm, rt), ctx); + /* As we are using ARM_LR */ + ctx->seen |= SEEN_CALL; + emit(ARM_ADD_R(ARM_LR, ARM_IP, ARM_LR), ctx); + + emit(ARM_UMULL(ARM_IP, rm, rd, rt), ctx); + emit(ARM_ADD_R(rm, ARM_LR, rm), ctx); + if (dstk) { + emit(ARM_STR_I(ARM_IP, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rm, ARM_SP, STACK_VAR(dst_hi)), ctx); + } else { + emit(ARM_MOV_R(rd, ARM_IP), ctx); + } +} + +/* *(size *)(dst + off) = src */ +static inline void emit_str_r(const u8 dst, const u8 src, bool dstk, + const s32 off, struct jit_ctx *ctx, const u8 sz){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[1] : dst; + + if (dstk) + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); + if (off) { + emit_a32_mov_i(tmp[0], off, false, ctx); + emit(ARM_ADD_R(tmp[0], rd, tmp[0]), ctx); + rd = tmp[0]; + } + switch (sz) { + case BPF_W: + /* Store a Word */ + emit(ARM_STR_I(src, rd, 0), ctx); + break; + case BPF_H: + /* Store a HalfWord */ + emit(ARM_STRH_I(src, rd, 0), ctx); + break; + case BPF_B: + /* Store a Byte */ + emit(ARM_STRB_I(src, rd, 0), ctx); + break; + } +} + +/* dst = *(size*)(src + off) */ +static inline void emit_ldx_r(const u8 dst, const u8 src, bool dstk, + const s32 off, struct jit_ctx *ctx, const u8 sz){ + const u8 *tmp = bpf2a32[TMP_REG_1]; + u8 rd = dstk ? tmp[1] : dst; + u8 rm = src; + + if (off) { + emit_a32_mov_i(tmp[0], off, false, ctx); + emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx); + rm = tmp[0]; + } + switch (sz) { + case BPF_W: + /* Load a Word */ + emit(ARM_LDR_I(rd, rm, 0), ctx); + break; + case BPF_H: + /* Load a HalfWord */ + emit(ARM_LDRH_I(rd, rm, 0), ctx); + break; + case BPF_B: + /* Load a Byte */ + emit(ARM_LDRB_I(rd, rm, 0), ctx); + break; + } + if (dstk) + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst)), ctx); +} + +/* Arithmatic Operation */ +static inline void emit_ar_r(const u8 rd, const u8 rt, const u8 rm, + const u8 rn, struct jit_ctx *ctx, u8 op) { + switch (op) { + case BPF_JSET: + ctx->seen |= SEEN_CALL; + emit(ARM_AND_R(ARM_IP, rt, rn), ctx); + emit(ARM_AND_R(ARM_LR, rd, rm), ctx); + emit(ARM_ORRS_R(ARM_IP, ARM_LR, ARM_IP), ctx); + break; + case BPF_JEQ: + case BPF_JNE: + case BPF_JGT: + case BPF_JGE: + case BPF_JLE: + case BPF_JLT: + emit(ARM_CMP_R(rd, rm), ctx); + _emit(ARM_COND_EQ, ARM_CMP_R(rt, rn), ctx); + break; + case BPF_JSLE: + case BPF_JSGT: + emit(ARM_CMP_R(rn, rt), ctx); + emit(ARM_SBCS_R(ARM_IP, rm, rd), ctx); + break; + case BPF_JSLT: + case BPF_JSGE: + emit(ARM_CMP_R(rt, rn), ctx); + emit(ARM_SBCS_R(ARM_IP, rd, rm), ctx); + break; + } +} + +static int out_offset = -1; /* initialized on the first pass of build_body() */ +static int emit_bpf_tail_call(struct jit_ctx *ctx) +{ + + /* bpf_tail_call(void *prog_ctx, struct bpf_array *array, u64 index) */ + const u8 *r2 = bpf2a32[BPF_REG_2]; + const u8 *r3 = bpf2a32[BPF_REG_3]; + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + const u8 *tcc = bpf2a32[TCALL_CNT]; + const int idx0 = ctx->idx; +#define cur_offset (ctx->idx - idx0) +#define jmp_offset (out_offset - (cur_offset)) + u32 off, lo, hi; + + /* if (index >= array->map.max_entries) + * goto out; + */ + off = offsetof(struct bpf_array, map.max_entries); + /* array->map.max_entries */ + emit_a32_mov_i(tmp[1], off, false, ctx); + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r2[1])), ctx); + emit(ARM_LDR_R(tmp[1], tmp2[1], tmp[1]), ctx); + /* index (64 bit) */ + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r3[1])), ctx); + /* index >= array->map.max_entries */ + emit(ARM_CMP_R(tmp2[1], tmp[1]), ctx); + _emit(ARM_COND_CS, ARM_B(jmp_offset), ctx); + + /* if (tail_call_cnt > MAX_TAIL_CALL_CNT) + * goto out; + * tail_call_cnt++; + */ + lo = (u32)MAX_TAIL_CALL_CNT; + hi = (u32)((u64)MAX_TAIL_CALL_CNT >> 32); + emit(ARM_LDR_I(tmp[1], ARM_SP, STACK_VAR(tcc[1])), ctx); + emit(ARM_LDR_I(tmp[0], ARM_SP, STACK_VAR(tcc[0])), ctx); + emit(ARM_CMP_I(tmp[0], hi), ctx); + _emit(ARM_COND_EQ, ARM_CMP_I(tmp[1], lo), ctx); + _emit(ARM_COND_HI, ARM_B(jmp_offset), ctx); + emit(ARM_ADDS_I(tmp[1], tmp[1], 1), ctx); + emit(ARM_ADC_I(tmp[0], tmp[0], 0), ctx); + emit(ARM_STR_I(tmp[1], ARM_SP, STACK_VAR(tcc[1])), ctx); + emit(ARM_STR_I(tmp[0], ARM_SP, STACK_VAR(tcc[0])), ctx); + + /* prog = array->ptrs[index] + * if (prog == NULL) + * goto out; + */ + off = offsetof(struct bpf_array, ptrs); + emit_a32_mov_i(tmp[1], off, false, ctx); + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r2[1])), ctx); + emit(ARM_ADD_R(tmp[1], tmp2[1], tmp[1]), ctx); + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(r3[1])), ctx); + emit(ARM_MOV_SI(tmp[0], tmp2[1], SRTYPE_ASL, 2), ctx); + emit(ARM_LDR_R(tmp[1], tmp[1], tmp[0]), ctx); + emit(ARM_CMP_I(tmp[1], 0), ctx); + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); + + /* goto *(prog->bpf_func + prologue_size); */ + off = offsetof(struct bpf_prog, bpf_func); + emit_a32_mov_i(tmp2[1], off, false, ctx); + emit(ARM_LDR_R(tmp[1], tmp[1], tmp2[1]), ctx); + emit(ARM_ADD_I(tmp[1], tmp[1], ctx->prologue_bytes), ctx); + emit(ARM_BX(tmp[1]), ctx); + + /* out: */ + if (out_offset == -1) + out_offset = cur_offset; + if (cur_offset != out_offset) { + pr_err_once("tail_call out_offset = %d, expected %d!\n", + cur_offset, out_offset); + return -1; + } + return 0; +#undef cur_offset +#undef jmp_offset +} + +/* 0xabcd => 0xcdab */ +static inline void emit_rev16(const u8 rd, const u8 rn, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ < 6 + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + + emit(ARM_AND_I(tmp2[1], rn, 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], rn, SRTYPE_LSR, 8), ctx); + emit(ARM_AND_I(tmp2[0], tmp2[0], 0xff), ctx); + emit(ARM_ORR_SI(rd, tmp2[0], tmp2[1], SRTYPE_LSL, 8), ctx); +#else /* ARMv6+ */ + emit(ARM_REV16(rd, rn), ctx); +#endif +} + +/* 0xabcdefgh => 0xghefcdab */ +static inline void emit_rev32(const u8 rd, const u8 rn, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ < 6 + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + + emit(ARM_AND_I(tmp2[1], rn, 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], rn, SRTYPE_LSR, 24), ctx); + emit(ARM_ORR_SI(ARM_IP, tmp2[0], tmp2[1], SRTYPE_LSL, 24), ctx); + + emit(ARM_MOV_SI(tmp2[1], rn, SRTYPE_LSR, 8), ctx); + emit(ARM_AND_I(tmp2[1], tmp2[1], 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], rn, SRTYPE_LSR, 16), ctx); + emit(ARM_AND_I(tmp2[0], tmp2[0], 0xff), ctx); + emit(ARM_MOV_SI(tmp2[0], tmp2[0], SRTYPE_LSL, 8), ctx); + emit(ARM_ORR_SI(tmp2[0], tmp2[0], tmp2[1], SRTYPE_LSL, 16), ctx); + emit(ARM_ORR_R(rd, ARM_IP, tmp2[0]), ctx); + +#else /* ARMv6+ */ + emit(ARM_REV(rd, rn), ctx); +#endif +} + +// push the scratch stack register on top of the stack +static inline void emit_push_r64(const u8 src[], const u8 shift, + struct jit_ctx *ctx) +{ + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + u16 reg_set = 0; + + emit(ARM_LDR_I(tmp2[1], ARM_SP, STACK_VAR(src[1]+shift)), ctx); + emit(ARM_LDR_I(tmp2[0], ARM_SP, STACK_VAR(src[0]+shift)), ctx); + + reg_set = (1 << tmp2[1]) | (1 << tmp2[0]); + emit(ARM_PUSH(reg_set), ctx); +} + +static void build_prologue(struct jit_ctx *ctx) +{ + const u8 r0 = bpf2a32[BPF_REG_0][1]; + const u8 r2 = bpf2a32[BPF_REG_1][1]; + const u8 r3 = bpf2a32[BPF_REG_1][0]; + const u8 r4 = bpf2a32[BPF_REG_6][1]; + const u8 r5 = bpf2a32[BPF_REG_6][0]; + const u8 r6 = bpf2a32[TMP_REG_1][1]; + const u8 r7 = bpf2a32[TMP_REG_1][0]; + const u8 r8 = bpf2a32[TMP_REG_2][1]; + const u8 r10 = bpf2a32[TMP_REG_2][0]; + const u8 fplo = bpf2a32[BPF_REG_FP][1]; + const u8 fphi = bpf2a32[BPF_REG_FP][0]; + const u8 sp = ARM_SP; + const u8 *tcc = bpf2a32[TCALL_CNT]; + + u16 reg_set = 0; + + /* + * eBPF prog stack layout + * + * high + * original ARM_SP => +-----+ eBPF prologue + * |FP/LR| + * current ARM_FP => +-----+ + * | ... | callee saved registers + * eBPF fp register => +-----+ <= (BPF_FP) + * | ... | eBPF JIT scratch space + * | | eBPF prog stack + * +-----+ + * |RSVD | JIT scratchpad + * current A64_SP => +-----+ <= (BPF_FP - STACK_SIZE) + * | | + * | ... | Function call stack + * | | + * +-----+ + * low + */ + + /* Save callee saved registers. */ + reg_set |= (1<seen & SEEN_CALL) + reg_set |= (1<stack_size = imm8m(STACK_SIZE); + + /* Set up function call stack */ + emit(ARM_SUB_I(ARM_SP, ARM_SP, ctx->stack_size), ctx); + + /* Set up BPF prog stack base register */ + emit_a32_mov_r(fplo, ARM_IP, true, false, ctx); + emit_a32_mov_i(fphi, 0, true, ctx); + + /* mov r4, 0 */ + emit(ARM_MOV_I(r4, 0), ctx); + + /* Move BPF_CTX to BPF_R1 */ + emit(ARM_MOV_R(r3, r4), ctx); + emit(ARM_MOV_R(r2, r0), ctx); + /* Initialize Tail Count */ + emit(ARM_STR_I(r4, ARM_SP, STACK_VAR(tcc[0])), ctx); + emit(ARM_STR_I(r4, ARM_SP, STACK_VAR(tcc[1])), ctx); + /* end of prologue */ +} + +static void build_epilogue(struct jit_ctx *ctx) +{ + const u8 r4 = bpf2a32[BPF_REG_6][1]; + const u8 r5 = bpf2a32[BPF_REG_6][0]; + const u8 r6 = bpf2a32[TMP_REG_1][1]; + const u8 r7 = bpf2a32[TMP_REG_1][0]; + const u8 r8 = bpf2a32[TMP_REG_2][1]; + const u8 r10 = bpf2a32[TMP_REG_2][0]; + u16 reg_set = 0; + + /* unwind function call stack */ + emit(ARM_ADD_I(ARM_SP, ARM_SP, ctx->stack_size), ctx); + + /* restore callee saved registers. */ + reg_set |= (1<seen & SEEN_CALL) + reg_set |= (1<seen & SEEN_CALL)) + emit(ARM_BX(ARM_LR), ctx); +#endif +} + +/* + * Convert an eBPF instruction to native instruction, i.e + * JITs an eBPF instruction. + * Returns : + * 0 - Successfully JITed an 8-byte eBPF instruction + * >0 - Successfully JITed a 16-byte eBPF instruction + * <0 - Failed to JIT. + */ +static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) +{ + const u8 code = insn->code; + const u8 *dst = bpf2a32[insn->dst_reg]; + const u8 *src = bpf2a32[insn->src_reg]; + const u8 *tmp = bpf2a32[TMP_REG_1]; + const u8 *tmp2 = bpf2a32[TMP_REG_2]; + const s16 off = insn->off; + const s32 imm = insn->imm; + const int i = insn - ctx->prog->insnsi; + const bool is64 = BPF_CLASS(code) == BPF_ALU64; + const bool dstk = is_on_stack(insn->dst_reg); + const bool sstk = is_on_stack(insn->src_reg); + u8 rd, rt, rm, rn; + s32 jmp_offset; + +#define check_imm(bits, imm) do { \ + if ((((imm) > 0) && ((imm) >> (bits))) || \ + (((imm) < 0) && (~(imm) >> (bits)))) { \ + pr_info("[%2d] imm=%d(0x%x) out of range\n", \ + i, imm, imm); \ + return -EINVAL; \ + } \ +} while (0) +#define check_imm24(imm) check_imm(24, imm) + + switch (code) { + /* ALU operations */ + + /* dst = src */ + case BPF_ALU | BPF_MOV | BPF_K: + case BPF_ALU | BPF_MOV | BPF_X: + case BPF_ALU64 | BPF_MOV | BPF_K: + case BPF_ALU64 | BPF_MOV | BPF_X: + switch (BPF_SRC(code)) { + case BPF_X: + emit_a32_mov_r64(is64, dst, src, dstk, sstk, ctx); + break; + case BPF_K: + /* Sign-extend immediate value to destination reg */ + emit_a32_mov_i64(is64, dst, imm, dstk, ctx); + break; + } + break; + /* dst = dst + src/imm */ + /* dst = dst - src/imm */ + /* dst = dst | src/imm */ + /* dst = dst & src/imm */ + /* dst = dst ^ src/imm */ + /* dst = dst * src/imm */ + /* dst = dst << src */ + /* dst = dst >> src */ + case BPF_ALU | BPF_ADD | BPF_K: + case BPF_ALU | BPF_ADD | BPF_X: + case BPF_ALU | BPF_SUB | BPF_K: + case BPF_ALU | BPF_SUB | BPF_X: + case BPF_ALU | BPF_OR | BPF_K: + case BPF_ALU | BPF_OR | BPF_X: + case BPF_ALU | BPF_AND | BPF_K: + case BPF_ALU | BPF_AND | BPF_X: + case BPF_ALU | BPF_XOR | BPF_K: + case BPF_ALU | BPF_XOR | BPF_X: + case BPF_ALU | BPF_MUL | BPF_K: + case BPF_ALU | BPF_MUL | BPF_X: + case BPF_ALU | BPF_LSH | BPF_X: + case BPF_ALU | BPF_RSH | BPF_X: + case BPF_ALU | BPF_ARSH | BPF_K: + case BPF_ALU | BPF_ARSH | BPF_X: + case BPF_ALU64 | BPF_ADD | BPF_K: + case BPF_ALU64 | BPF_ADD | BPF_X: + case BPF_ALU64 | BPF_SUB | BPF_K: + case BPF_ALU64 | BPF_SUB | BPF_X: + case BPF_ALU64 | BPF_OR | BPF_K: + case BPF_ALU64 | BPF_OR | BPF_X: + case BPF_ALU64 | BPF_AND | BPF_K: + case BPF_ALU64 | BPF_AND | BPF_X: + case BPF_ALU64 | BPF_XOR | BPF_K: + case BPF_ALU64 | BPF_XOR | BPF_X: + switch (BPF_SRC(code)) { + case BPF_X: + emit_a32_alu_r64(is64, dst, src, dstk, sstk, + ctx, BPF_OP(code)); + break; + case BPF_K: + /* Move immediate value to the temporary register + * and then do the ALU operation on the temporary + * register as this will sign-extend the immediate + * value into temporary reg and then it would be + * safe to do the operation on it. + */ + emit_a32_mov_i64(is64, tmp2, imm, false, ctx); + emit_a32_alu_r64(is64, dst, tmp2, dstk, false, + ctx, BPF_OP(code)); + break; + } + break; + /* dst = dst / src(imm) */ + /* dst = dst % src(imm) */ + case BPF_ALU | BPF_DIV | BPF_K: + case BPF_ALU | BPF_DIV | BPF_X: + case BPF_ALU | BPF_MOD | BPF_K: + case BPF_ALU | BPF_MOD | BPF_X: + rt = src_lo; + rd = dstk ? tmp2[1] : dst_lo; + if (dstk) + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + switch (BPF_SRC(code)) { + case BPF_X: + rt = sstk ? tmp2[0] : rt; + if (sstk) + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(src_lo)), + ctx); + break; + case BPF_K: + rt = tmp2[0]; + emit_a32_mov_i(rt, imm, false, ctx); + break; + } + emit_udivmod(rd, rd, rt, ctx, BPF_OP(code)); + if (dstk) + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + break; + case BPF_ALU64 | BPF_DIV | BPF_K: + case BPF_ALU64 | BPF_DIV | BPF_X: + case BPF_ALU64 | BPF_MOD | BPF_K: + case BPF_ALU64 | BPF_MOD | BPF_X: + goto notyet; + /* dst = dst >> imm */ + /* dst = dst << imm */ + case BPF_ALU | BPF_RSH | BPF_K: + case BPF_ALU | BPF_LSH | BPF_K: + if (unlikely(imm > 31)) + return -EINVAL; + if (imm) + emit_a32_alu_i(dst_lo, imm, dstk, ctx, BPF_OP(code)); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + break; + /* dst = dst << imm */ + case BPF_ALU64 | BPF_LSH | BPF_K: + if (unlikely(imm > 63)) + return -EINVAL; + emit_a32_lsh_i64(dst, dstk, imm, ctx); + break; + /* dst = dst >> imm */ + case BPF_ALU64 | BPF_RSH | BPF_K: + if (unlikely(imm > 63)) + return -EINVAL; + emit_a32_lsr_i64(dst, dstk, imm, ctx); + break; + /* dst = dst << src */ + case BPF_ALU64 | BPF_LSH | BPF_X: + emit_a32_lsh_r64(dst, src, dstk, sstk, ctx); + break; + /* dst = dst >> src */ + case BPF_ALU64 | BPF_RSH | BPF_X: + emit_a32_lsr_r64(dst, src, dstk, sstk, ctx); + break; + /* dst = dst >> src (signed) */ + case BPF_ALU64 | BPF_ARSH | BPF_X: + emit_a32_arsh_r64(dst, src, dstk, sstk, ctx); + break; + /* dst = dst >> imm (signed) */ + case BPF_ALU64 | BPF_ARSH | BPF_K: + if (unlikely(imm > 63)) + return -EINVAL; + emit_a32_arsh_i64(dst, dstk, imm, ctx); + break; + /* dst = ~dst */ + case BPF_ALU | BPF_NEG: + emit_a32_alu_i(dst_lo, 0, dstk, ctx, BPF_OP(code)); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + break; + /* dst = ~dst (64 bit) */ + case BPF_ALU64 | BPF_NEG: + emit_a32_neg64(dst, dstk, ctx); + break; + /* dst = dst * src/imm */ + case BPF_ALU64 | BPF_MUL | BPF_X: + case BPF_ALU64 | BPF_MUL | BPF_K: + switch (BPF_SRC(code)) { + case BPF_X: + emit_a32_mul_r64(dst, src, dstk, sstk, ctx); + break; + case BPF_K: + /* Move immediate value to the temporary register + * and then do the multiplication on it as this + * will sign-extend the immediate value into temp + * reg then it would be safe to do the operation + * on it. + */ + emit_a32_mov_i64(is64, tmp2, imm, false, ctx); + emit_a32_mul_r64(dst, tmp2, dstk, false, ctx); + break; + } + break; + /* dst = htole(dst) */ + /* dst = htobe(dst) */ + case BPF_ALU | BPF_END | BPF_FROM_LE: + case BPF_ALU | BPF_END | BPF_FROM_BE: + rd = dstk ? tmp[0] : dst_hi; + rt = dstk ? tmp[1] : dst_lo; + if (dstk) { + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + if (BPF_SRC(code) == BPF_FROM_LE) + goto emit_bswap_uxt; + switch (imm) { + case 16: + emit_rev16(rt, rt, ctx); + goto emit_bswap_uxt; + case 32: + emit_rev32(rt, rt, ctx); + goto emit_bswap_uxt; + case 64: + /* Because of the usage of ARM_LR */ + ctx->seen |= SEEN_CALL; + emit_rev32(ARM_LR, rt, ctx); + emit_rev32(rt, rd, ctx); + emit(ARM_MOV_R(rd, ARM_LR), ctx); + break; + } + goto exit; +emit_bswap_uxt: + switch (imm) { + case 16: + /* zero-extend 16 bits into 64 bits */ +#if __LINUX_ARM_ARCH__ < 6 + emit_a32_mov_i(tmp2[1], 0xffff, false, ctx); + emit(ARM_AND_R(rt, rt, tmp2[1]), ctx); +#else /* ARMv6+ */ + emit(ARM_UXTH(rt, rt), ctx); +#endif + emit(ARM_EOR_R(rd, rd, rd), ctx); + break; + case 32: + /* zero-extend 32 bits into 64 bits */ + emit(ARM_EOR_R(rd, rd, rd), ctx); + break; + case 64: + /* nop */ + break; + } +exit: + if (dstk) { + emit(ARM_STR_I(rt, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_STR_I(rd, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + break; + /* dst = imm64 */ + case BPF_LD | BPF_IMM | BPF_DW: + { + const struct bpf_insn insn1 = insn[1]; + u32 hi, lo = imm; + + hi = insn1.imm; + emit_a32_mov_i(dst_lo, lo, dstk, ctx); + emit_a32_mov_i(dst_hi, hi, dstk, ctx); + + return 1; + } + /* LDX: dst = *(size *)(src + off) */ + case BPF_LDX | BPF_MEM | BPF_W: + case BPF_LDX | BPF_MEM | BPF_H: + case BPF_LDX | BPF_MEM | BPF_B: + case BPF_LDX | BPF_MEM | BPF_DW: + rn = sstk ? tmp2[1] : src_lo; + if (sstk) + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx); + switch (BPF_SIZE(code)) { + case BPF_W: + /* Load a Word */ + case BPF_H: + /* Load a Half-Word */ + case BPF_B: + /* Load a Byte */ + emit_ldx_r(dst_lo, rn, dstk, off, ctx, BPF_SIZE(code)); + emit_a32_mov_i(dst_hi, 0, dstk, ctx); + break; + case BPF_DW: + /* Load a double word */ + emit_ldx_r(dst_lo, rn, dstk, off, ctx, BPF_W); + emit_ldx_r(dst_hi, rn, dstk, off+4, ctx, BPF_W); + break; + } + break; + /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */ + case BPF_LD | BPF_ABS | BPF_W: + case BPF_LD | BPF_ABS | BPF_H: + case BPF_LD | BPF_ABS | BPF_B: + /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + src + imm)) */ + case BPF_LD | BPF_IND | BPF_W: + case BPF_LD | BPF_IND | BPF_H: + case BPF_LD | BPF_IND | BPF_B: + { + const u8 r4 = bpf2a32[BPF_REG_6][1]; /* r4 = ptr to sk_buff */ + const u8 r0 = bpf2a32[BPF_REG_0][1]; /*r0: struct sk_buff *skb*/ + /* rtn value */ + const u8 r1 = bpf2a32[BPF_REG_0][0]; /* r1: int k */ + const u8 r2 = bpf2a32[BPF_REG_1][1]; /* r2: unsigned int size */ + const u8 r3 = bpf2a32[BPF_REG_1][0]; /* r3: void *buffer */ + const u8 r6 = bpf2a32[TMP_REG_1][1]; /* r6: void *(*func)(..) */ + int size; + + /* Setting up first argument */ + emit(ARM_MOV_R(r0, r4), ctx); + + /* Setting up second argument */ + emit_a32_mov_i(r1, imm, false, ctx); + if (BPF_MODE(code) == BPF_IND) + emit_a32_alu_r(r1, src_lo, false, sstk, ctx, + false, false, BPF_ADD); + + /* Setting up third argument */ + switch (BPF_SIZE(code)) { + case BPF_W: + size = 4; + break; + case BPF_H: + size = 2; + break; + case BPF_B: + size = 1; + break; + default: + return -EINVAL; + } + emit_a32_mov_i(r2, size, false, ctx); + + /* Setting up fourth argument */ + emit(ARM_ADD_I(r3, ARM_SP, imm8m(SKB_BUFFER)), ctx); + + /* Setting up function pointer to call */ + emit_a32_mov_i(r6, (unsigned int)bpf_load_pointer, false, ctx); + emit_blx_r(r6, ctx); + + emit(ARM_EOR_R(r1, r1, r1), ctx); + /* Check if return address is NULL or not. + * if NULL then jump to epilogue + * else continue to load the value from retn address + */ + emit(ARM_CMP_I(r0, 0), ctx); + jmp_offset = epilogue_offset(ctx); + check_imm24(jmp_offset); + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); + + /* Load value from the address */ + switch (BPF_SIZE(code)) { + case BPF_W: + emit(ARM_LDR_I(r0, r0, 0), ctx); + emit_rev32(r0, r0, ctx); + break; + case BPF_H: + emit(ARM_LDRH_I(r0, r0, 0), ctx); + emit_rev16(r0, r0, ctx); + break; + case BPF_B: + emit(ARM_LDRB_I(r0, r0, 0), ctx); + /* No need to reverse */ + break; + } + break; + } + /* ST: *(size *)(dst + off) = imm */ + case BPF_ST | BPF_MEM | BPF_W: + case BPF_ST | BPF_MEM | BPF_H: + case BPF_ST | BPF_MEM | BPF_B: + case BPF_ST | BPF_MEM | BPF_DW: + switch (BPF_SIZE(code)) { + case BPF_DW: + /* Sign-extend immediate value into temp reg */ + emit_a32_mov_i64(true, tmp2, imm, false, ctx); + emit_str_r(dst_lo, tmp2[1], dstk, off, ctx, BPF_W); + emit_str_r(dst_lo, tmp2[0], dstk, off+4, ctx, BPF_W); + break; + case BPF_W: + case BPF_H: + case BPF_B: + emit_a32_mov_i(tmp2[1], imm, false, ctx); + emit_str_r(dst_lo, tmp2[1], dstk, off, ctx, + BPF_SIZE(code)); + break; + } + break; + /* STX XADD: lock *(u32 *)(dst + off) += src */ + case BPF_STX | BPF_XADD | BPF_W: + /* STX XADD: lock *(u64 *)(dst + off) += src */ + case BPF_STX | BPF_XADD | BPF_DW: + goto notyet; + /* STX: *(size *)(dst + off) = src */ + case BPF_STX | BPF_MEM | BPF_W: + case BPF_STX | BPF_MEM | BPF_H: + case BPF_STX | BPF_MEM | BPF_B: + case BPF_STX | BPF_MEM | BPF_DW: + { + u8 sz = BPF_SIZE(code); + + rn = sstk ? tmp2[1] : src_lo; + rm = sstk ? tmp2[0] : src_hi; + if (sstk) { + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(src_hi)), ctx); + } + + /* Store the value */ + if (BPF_SIZE(code) == BPF_DW) { + emit_str_r(dst_lo, rn, dstk, off, ctx, BPF_W); + emit_str_r(dst_lo, rm, dstk, off+4, ctx, BPF_W); + } else { + emit_str_r(dst_lo, rn, dstk, off, ctx, sz); + } + break; + } + /* PC += off if dst == src */ + /* PC += off if dst > src */ + /* PC += off if dst >= src */ + /* PC += off if dst < src */ + /* PC += off if dst <= src */ + /* PC += off if dst != src */ + /* PC += off if dst > src (signed) */ + /* PC += off if dst >= src (signed) */ + /* PC += off if dst < src (signed) */ + /* PC += off if dst <= src (signed) */ + /* PC += off if dst & src */ + case BPF_JMP | BPF_JEQ | BPF_X: + case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JNE | BPF_X: + case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSET | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: + /* Setup source registers */ + rm = sstk ? tmp2[0] : src_hi; + rn = sstk ? tmp2[1] : src_lo; + if (sstk) { + emit(ARM_LDR_I(rn, ARM_SP, STACK_VAR(src_lo)), ctx); + emit(ARM_LDR_I(rm, ARM_SP, STACK_VAR(src_hi)), ctx); + } + goto go_jmp; + /* PC += off if dst == imm */ + /* PC += off if dst > imm */ + /* PC += off if dst >= imm */ + /* PC += off if dst < imm */ + /* PC += off if dst <= imm */ + /* PC += off if dst != imm */ + /* PC += off if dst > imm (signed) */ + /* PC += off if dst >= imm (signed) */ + /* PC += off if dst < imm (signed) */ + /* PC += off if dst <= imm (signed) */ + /* PC += off if dst & imm */ + case BPF_JMP | BPF_JEQ | BPF_K: + case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JNE | BPF_K: + case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSET | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: + if (off == 0) + break; + rm = tmp2[0]; + rn = tmp2[1]; + /* Sign-extend immediate value */ + emit_a32_mov_i64(true, tmp2, imm, false, ctx); +go_jmp: + /* Setup destination register */ + rd = dstk ? tmp[0] : dst_hi; + rt = dstk ? tmp[1] : dst_lo; + if (dstk) { + emit(ARM_LDR_I(rt, ARM_SP, STACK_VAR(dst_lo)), ctx); + emit(ARM_LDR_I(rd, ARM_SP, STACK_VAR(dst_hi)), ctx); + } + + /* Check for the condition */ + emit_ar_r(rd, rt, rm, rn, ctx, BPF_OP(code)); + + /* Setup JUMP instruction */ + jmp_offset = bpf2a32_offset(i+off, i, ctx); + switch (BPF_OP(code)) { + case BPF_JNE: + case BPF_JSET: + _emit(ARM_COND_NE, ARM_B(jmp_offset), ctx); + break; + case BPF_JEQ: + _emit(ARM_COND_EQ, ARM_B(jmp_offset), ctx); + break; + case BPF_JGT: + _emit(ARM_COND_HI, ARM_B(jmp_offset), ctx); + break; + case BPF_JGE: + _emit(ARM_COND_CS, ARM_B(jmp_offset), ctx); + break; + case BPF_JSGT: + _emit(ARM_COND_LT, ARM_B(jmp_offset), ctx); + break; + case BPF_JSGE: + _emit(ARM_COND_GE, ARM_B(jmp_offset), ctx); + break; + case BPF_JLE: + _emit(ARM_COND_LS, ARM_B(jmp_offset), ctx); + break; + case BPF_JLT: + _emit(ARM_COND_CC, ARM_B(jmp_offset), ctx); + break; + case BPF_JSLT: + _emit(ARM_COND_LT, ARM_B(jmp_offset), ctx); + break; + case BPF_JSLE: + _emit(ARM_COND_GE, ARM_B(jmp_offset), ctx); + break; + } + break; + /* JMP OFF */ + case BPF_JMP | BPF_JA: + { + if (off == 0) + break; + jmp_offset = bpf2a32_offset(i+off, i, ctx); + check_imm24(jmp_offset); + emit(ARM_B(jmp_offset), ctx); + break; + } + /* tail call */ + case BPF_JMP | BPF_TAIL_CALL: + if (emit_bpf_tail_call(ctx)) + return -EFAULT; + break; + /* function call */ + case BPF_JMP | BPF_CALL: + { + const u8 *r0 = bpf2a32[BPF_REG_0]; + const u8 *r1 = bpf2a32[BPF_REG_1]; + const u8 *r2 = bpf2a32[BPF_REG_2]; + const u8 *r3 = bpf2a32[BPF_REG_3]; + const u8 *r4 = bpf2a32[BPF_REG_4]; + const u8 *r5 = bpf2a32[BPF_REG_5]; + const u32 func = (u32)__bpf_call_base + (u32)imm; + + emit_a32_mov_r64(true, r0, r1, false, false, ctx); + emit_a32_mov_r64(true, r1, r2, false, true, ctx); + emit_push_r64(r5, 0, ctx); + emit_push_r64(r4, 8, ctx); + emit_push_r64(r3, 16, ctx); + + emit_a32_mov_i(tmp[1], func, false, ctx); + emit_blx_r(tmp[1], ctx); + + emit(ARM_ADD_I(ARM_SP, ARM_SP, imm8m(24)), ctx); // callee clean + break; + } + /* function return */ + case BPF_JMP | BPF_EXIT: + /* Optimization: when last instruction is EXIT + * simply fallthrough to epilogue. + */ + if (i == ctx->prog->len - 1) + break; + jmp_offset = epilogue_offset(ctx); + check_imm24(jmp_offset); + emit(ARM_B(jmp_offset), ctx); + break; +notyet: + pr_info_once("*** NOT YET: opcode %02x ***\n", code); + return -EFAULT; + default: + pr_err_once("unknown opcode %02x\n", code); + return -EINVAL; + } + + if (ctx->flags & FLAG_IMM_OVERFLOW) + /* + * this instruction generated an overflow when + * trying to access the literal pool, so + * delegate this filter to the kernel interpreter. + */ + return -1; + return 0; } static int build_body(struct jit_ctx *ctx) { - void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w}; - const struct bpf_prog *prog = ctx->skf; - const struct sock_filter *inst; - unsigned i, load_order, off, condt; - int imm12; - u32 k; + const struct bpf_prog *prog = ctx->prog; + unsigned int i; for (i = 0; i < prog->len; i++) { - u16 code; + const struct bpf_insn *insn = &(prog->insnsi[i]); + int ret; - inst = &(prog->insns[i]); - /* K as an immediate value operand */ - k = inst->k; - code = bpf_anc_helper(inst); + ret = build_insn(insn, ctx); - /* compute offsets only in the fake pass */ - if (ctx->target == NULL) - ctx->offsets[i] = ctx->idx * 4; - - switch (code) { - case BPF_LD | BPF_IMM: - emit_mov_i(r_A, k, ctx); - break; - case BPF_LD | BPF_W | BPF_LEN: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); - emit(ARM_LDR_I(r_A, r_skb, - offsetof(struct sk_buff, len)), ctx); - break; - case BPF_LD | BPF_MEM: - /* A = scratch[k] */ - ctx->seen |= SEEN_MEM_WORD(k); - emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); - break; - case BPF_LD | BPF_W | BPF_ABS: - load_order = 2; - goto load; - case BPF_LD | BPF_H | BPF_ABS: - load_order = 1; - goto load; - case BPF_LD | BPF_B | BPF_ABS: - load_order = 0; -load: - emit_mov_i(r_off, k, ctx); -load_common: - ctx->seen |= SEEN_DATA | SEEN_CALL; - - if (load_order > 0) { - emit(ARM_SUB_I(r_scratch, r_skb_hl, - 1 << load_order), ctx); - emit(ARM_CMP_R(r_scratch, r_off), ctx); - condt = ARM_COND_GE; - } else { - emit(ARM_CMP_R(r_skb_hl, r_off), ctx); - condt = ARM_COND_HI; - } - - /* - * test for negative offset, only if we are - * currently scheduled to take the fast - * path. this will update the flags so that - * the slowpath instruction are ignored if the - * offset is negative. - * - * for loard_order == 0 the HI condition will - * make loads at offset 0 take the slow path too. - */ - _emit(condt, ARM_CMP_I(r_off, 0), ctx); - - _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data), - ctx); - - if (load_order == 0) - _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0), - ctx); - else if (load_order == 1) - emit_load_be16(condt, r_A, r_scratch, ctx); - else if (load_order == 2) - emit_load_be32(condt, r_A, r_scratch, ctx); - - _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx); - - /* the slowpath */ - emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx); - emit(ARM_MOV_R(ARM_R0, r_skb), ctx); - /* the offset is already in R1 */ - emit_blx_r(ARM_R3, ctx); - /* check the result of skb_copy_bits */ - emit(ARM_CMP_I(ARM_R1, 0), ctx); - emit_err_ret(ARM_COND_NE, ctx); - emit(ARM_MOV_R(r_A, ARM_R0), ctx); - break; - case BPF_LD | BPF_W | BPF_IND: - load_order = 2; - goto load_ind; - case BPF_LD | BPF_H | BPF_IND: - load_order = 1; - goto load_ind; - case BPF_LD | BPF_B | BPF_IND: - load_order = 0; -load_ind: - update_on_xread(ctx); - OP_IMM3(ARM_ADD, r_off, r_X, k, ctx); - goto load_common; - case BPF_LDX | BPF_IMM: - ctx->seen |= SEEN_X; - emit_mov_i(r_X, k, ctx); - break; - case BPF_LDX | BPF_W | BPF_LEN: - ctx->seen |= SEEN_X | SEEN_SKB; - emit(ARM_LDR_I(r_X, r_skb, - offsetof(struct sk_buff, len)), ctx); - break; - case BPF_LDX | BPF_MEM: - ctx->seen |= SEEN_X | SEEN_MEM_WORD(k); - emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); - break; - case BPF_LDX | BPF_B | BPF_MSH: - /* x = ((*(frame + k)) & 0xf) << 2; */ - ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL; - /* the interpreter should deal with the negative K */ - if ((int)k < 0) - return -1; - /* offset in r1: we might have to take the slow path */ - emit_mov_i(r_off, k, ctx); - emit(ARM_CMP_R(r_skb_hl, r_off), ctx); - - /* load in r0: common with the slowpath */ - _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data, - ARM_R1), ctx); - /* - * emit_mov_i() might generate one or two instructions, - * the same holds for emit_blx_r() - */ - _emit(ARM_COND_HI, ARM_B(b_imm(i + 1, ctx) - 2), ctx); - - emit(ARM_MOV_R(ARM_R0, r_skb), ctx); - /* r_off is r1 */ - emit_mov_i(ARM_R3, (u32)jit_get_skb_b, ctx); - emit_blx_r(ARM_R3, ctx); - /* check the return value of skb_copy_bits */ - emit(ARM_CMP_I(ARM_R1, 0), ctx); - emit_err_ret(ARM_COND_NE, ctx); - - emit(ARM_AND_I(r_X, ARM_R0, 0x00f), ctx); - emit(ARM_LSL_I(r_X, r_X, 2), ctx); - break; - case BPF_ST: - ctx->seen |= SEEN_MEM_WORD(k); - emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); - break; - case BPF_STX: - update_on_xread(ctx); - ctx->seen |= SEEN_MEM_WORD(k); - emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); - break; - case BPF_ALU | BPF_ADD | BPF_K: - /* A += K */ - OP_IMM3(ARM_ADD, r_A, r_A, k, ctx); - break; - case BPF_ALU | BPF_ADD | BPF_X: - update_on_xread(ctx); - emit(ARM_ADD_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_SUB | BPF_K: - /* A -= K */ - OP_IMM3(ARM_SUB, r_A, r_A, k, ctx); - break; - case BPF_ALU | BPF_SUB | BPF_X: - update_on_xread(ctx); - emit(ARM_SUB_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_MUL | BPF_K: - /* A *= K */ - emit_mov_i(r_scratch, k, ctx); - emit(ARM_MUL(r_A, r_A, r_scratch), ctx); - break; - case BPF_ALU | BPF_MUL | BPF_X: - update_on_xread(ctx); - emit(ARM_MUL(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_DIV | BPF_K: - if (k == 1) - break; - emit_mov_i(r_scratch, k, ctx); - emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_DIV); - break; - case BPF_ALU | BPF_DIV | BPF_X: - update_on_xread(ctx); - emit(ARM_CMP_I(r_X, 0), ctx); - emit_err_ret(ARM_COND_EQ, ctx); - emit_udivmod(r_A, r_A, r_X, ctx, BPF_DIV); - break; - case BPF_ALU | BPF_MOD | BPF_K: - if (k == 1) { - emit_mov_i(r_A, 0, ctx); - break; - } - emit_mov_i(r_scratch, k, ctx); - emit_udivmod(r_A, r_A, r_scratch, ctx, BPF_MOD); - break; - case BPF_ALU | BPF_MOD | BPF_X: - update_on_xread(ctx); - emit(ARM_CMP_I(r_X, 0), ctx); - emit_err_ret(ARM_COND_EQ, ctx); - emit_udivmod(r_A, r_A, r_X, ctx, BPF_MOD); - break; - case BPF_ALU | BPF_OR | BPF_K: - /* A |= K */ - OP_IMM3(ARM_ORR, r_A, r_A, k, ctx); - break; - case BPF_ALU | BPF_OR | BPF_X: - update_on_xread(ctx); - emit(ARM_ORR_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_XOR | BPF_K: - /* A ^= K; */ - OP_IMM3(ARM_EOR, r_A, r_A, k, ctx); - break; - case BPF_ANC | SKF_AD_ALU_XOR_X: - case BPF_ALU | BPF_XOR | BPF_X: - /* A ^= X */ - update_on_xread(ctx); - emit(ARM_EOR_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_AND | BPF_K: - /* A &= K */ - OP_IMM3(ARM_AND, r_A, r_A, k, ctx); - break; - case BPF_ALU | BPF_AND | BPF_X: - update_on_xread(ctx); - emit(ARM_AND_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_LSH | BPF_K: - if (unlikely(k > 31)) - return -1; - emit(ARM_LSL_I(r_A, r_A, k), ctx); - break; - case BPF_ALU | BPF_LSH | BPF_X: - update_on_xread(ctx); - emit(ARM_LSL_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_RSH | BPF_K: - if (unlikely(k > 31)) - return -1; - if (k) - emit(ARM_LSR_I(r_A, r_A, k), ctx); - break; - case BPF_ALU | BPF_RSH | BPF_X: - update_on_xread(ctx); - emit(ARM_LSR_R(r_A, r_A, r_X), ctx); - break; - case BPF_ALU | BPF_NEG: - /* A = -A */ - emit(ARM_RSB_I(r_A, r_A, 0), ctx); - break; - case BPF_JMP | BPF_JA: - /* pc += K */ - emit(ARM_B(b_imm(i + k + 1, ctx)), ctx); - break; - case BPF_JMP | BPF_JEQ | BPF_K: - /* pc += (A == K) ? pc->jt : pc->jf */ - condt = ARM_COND_EQ; - goto cmp_imm; - case BPF_JMP | BPF_JGT | BPF_K: - /* pc += (A > K) ? pc->jt : pc->jf */ - condt = ARM_COND_HI; - goto cmp_imm; - case BPF_JMP | BPF_JGE | BPF_K: - /* pc += (A >= K) ? pc->jt : pc->jf */ - condt = ARM_COND_HS; -cmp_imm: - imm12 = imm8m(k); - if (imm12 < 0) { - emit_mov_i_no8m(r_scratch, k, ctx); - emit(ARM_CMP_R(r_A, r_scratch), ctx); - } else { - emit(ARM_CMP_I(r_A, imm12), ctx); - } -cond_jump: - if (inst->jt) - _emit(condt, ARM_B(b_imm(i + inst->jt + 1, - ctx)), ctx); - if (inst->jf) - _emit(condt ^ 1, ARM_B(b_imm(i + inst->jf + 1, - ctx)), ctx); - break; - case BPF_JMP | BPF_JEQ | BPF_X: - /* pc += (A == X) ? pc->jt : pc->jf */ - condt = ARM_COND_EQ; - goto cmp_x; - case BPF_JMP | BPF_JGT | BPF_X: - /* pc += (A > X) ? pc->jt : pc->jf */ - condt = ARM_COND_HI; - goto cmp_x; - case BPF_JMP | BPF_JGE | BPF_X: - /* pc += (A >= X) ? pc->jt : pc->jf */ - condt = ARM_COND_CS; -cmp_x: - update_on_xread(ctx); - emit(ARM_CMP_R(r_A, r_X), ctx); - goto cond_jump; - case BPF_JMP | BPF_JSET | BPF_K: - /* pc += (A & K) ? pc->jt : pc->jf */ - condt = ARM_COND_NE; - /* not set iff all zeroes iff Z==1 iff EQ */ - - imm12 = imm8m(k); - if (imm12 < 0) { - emit_mov_i_no8m(r_scratch, k, ctx); - emit(ARM_TST_R(r_A, r_scratch), ctx); - } else { - emit(ARM_TST_I(r_A, imm12), ctx); - } - goto cond_jump; - case BPF_JMP | BPF_JSET | BPF_X: - /* pc += (A & X) ? pc->jt : pc->jf */ - update_on_xread(ctx); - condt = ARM_COND_NE; - emit(ARM_TST_R(r_A, r_X), ctx); - goto cond_jump; - case BPF_RET | BPF_A: - emit(ARM_MOV_R(ARM_R0, r_A), ctx); - goto b_epilogue; - case BPF_RET | BPF_K: - if ((k == 0) && (ctx->ret0_fp_idx < 0)) - ctx->ret0_fp_idx = i; - emit_mov_i(ARM_R0, k, ctx); -b_epilogue: - if (i != ctx->skf->len - 1) - emit(ARM_B(b_imm(prog->len, ctx)), ctx); - break; - case BPF_MISC | BPF_TAX: - /* X = A */ - ctx->seen |= SEEN_X; - emit(ARM_MOV_R(r_X, r_A), ctx); - break; - case BPF_MISC | BPF_TXA: - /* A = X */ - update_on_xread(ctx); - emit(ARM_MOV_R(r_A, r_X), ctx); - break; - case BPF_ANC | SKF_AD_PROTOCOL: - /* A = ntohs(skb->protocol) */ - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, - protocol) != 2); - off = offsetof(struct sk_buff, protocol); - emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx); - emit_swap16(r_A, r_scratch, ctx); - break; - case BPF_ANC | SKF_AD_CPU: - /* r_scratch = current_thread_info() */ - OP_IMM3(ARM_BIC, r_scratch, ARM_SP, THREAD_SIZE - 1, ctx); - /* A = current_thread_info()->cpu */ - BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4); - off = offsetof(struct thread_info, cpu); - emit(ARM_LDR_I(r_A, r_scratch, off), ctx); - break; - case BPF_ANC | SKF_AD_IFINDEX: - case BPF_ANC | SKF_AD_HATYPE: - /* A = skb->dev->ifindex */ - /* A = skb->dev->type */ - ctx->seen |= SEEN_SKB; - off = offsetof(struct sk_buff, dev); - emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); - - emit(ARM_CMP_I(r_scratch, 0), ctx); - emit_err_ret(ARM_COND_EQ, ctx); - - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, - ifindex) != 4); - BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, - type) != 2); - - if (code == (BPF_ANC | SKF_AD_IFINDEX)) { - off = offsetof(struct net_device, ifindex); - emit(ARM_LDR_I(r_A, r_scratch, off), ctx); - } else { - /* - * offset of field "type" in "struct - * net_device" is above what can be - * used in the ldrh rd, [rn, #imm] - * instruction, so load the offset in - * a register and use ldrh rd, [rn, rm] - */ - off = offsetof(struct net_device, type); - emit_mov_i(ARM_R3, off, ctx); - emit(ARM_LDRH_R(r_A, r_scratch, ARM_R3), ctx); - } - break; - case BPF_ANC | SKF_AD_MARK: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); - off = offsetof(struct sk_buff, mark); - emit(ARM_LDR_I(r_A, r_skb, off), ctx); - break; - case BPF_ANC | SKF_AD_RXHASH: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); - off = offsetof(struct sk_buff, hash); - emit(ARM_LDR_I(r_A, r_skb, off), ctx); - break; - case BPF_ANC | SKF_AD_VLAN_TAG: - case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2); - off = offsetof(struct sk_buff, vlan_tci); - emit(ARM_LDRH_I(r_A, r_skb, off), ctx); - if (code == (BPF_ANC | SKF_AD_VLAN_TAG)) - OP_IMM3(ARM_AND, r_A, r_A, ~VLAN_TAG_PRESENT, ctx); - else { - OP_IMM3(ARM_LSR, r_A, r_A, 12, ctx); - OP_IMM3(ARM_AND, r_A, r_A, 0x1, ctx); - } - break; - case BPF_ANC | SKF_AD_PKTTYPE: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, - __pkt_type_offset[0]) != 1); - off = PKT_TYPE_OFFSET(); - emit(ARM_LDRB_I(r_A, r_skb, off), ctx); - emit(ARM_AND_I(r_A, r_A, PKT_TYPE_MAX), ctx); -#ifdef __BIG_ENDIAN_BITFIELD - emit(ARM_LSR_I(r_A, r_A, 5), ctx); -#endif - break; - case BPF_ANC | SKF_AD_QUEUE: - ctx->seen |= SEEN_SKB; - BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, - queue_mapping) != 2); - BUILD_BUG_ON(offsetof(struct sk_buff, - queue_mapping) > 0xff); - off = offsetof(struct sk_buff, queue_mapping); - emit(ARM_LDRH_I(r_A, r_skb, off), ctx); - break; - case BPF_ANC | SKF_AD_PAY_OFFSET: - ctx->seen |= SEEN_SKB | SEEN_CALL; - - emit(ARM_MOV_R(ARM_R0, r_skb), ctx); - emit_mov_i(ARM_R3, (unsigned int)skb_get_poff, ctx); - emit_blx_r(ARM_R3, ctx); - emit(ARM_MOV_R(r_A, ARM_R0), ctx); - break; - case BPF_LDX | BPF_W | BPF_ABS: - /* - * load a 32bit word from struct seccomp_data. - * seccomp_check_filter() will already have checked - * that k is 32bit aligned and lies within the - * struct seccomp_data. - */ - ctx->seen |= SEEN_SKB; - emit(ARM_LDR_I(r_A, r_skb, k), ctx); - break; - default: - return -1; + /* It's used with loading the 64 bit immediate value. */ + if (ret > 0) { + i++; + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx; + continue; } - if (ctx->flags & FLAG_IMM_OVERFLOW) - /* - * this instruction generated an overflow when - * trying to access the literal pool, so - * delegate this filter to the kernel interpreter. - */ + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx; + + /* If unsuccesfull, return with error code */ + if (ret) + return ret; + } + return 0; +} + +static int validate_code(struct jit_ctx *ctx) +{ + int i; + + for (i = 0; i < ctx->idx; i++) { + if (ctx->target[i] == __opcode_to_mem_arm(ARM_INST_UDF)) return -1; } - /* compute offsets only during the first pass */ - if (ctx->target == NULL) - ctx->offsets[i] = ctx->idx * 4; - return 0; } - -void bpf_jit_compile(struct bpf_prog *fp) +void bpf_jit_compile(struct bpf_prog *prog) { - struct bpf_binary_header *header; - struct jit_ctx ctx; - unsigned tmp_idx; - unsigned alloc_size; - u8 *target_ptr; + /* Nothing to do here. We support Internal BPF. */ +} +struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) +{ + struct bpf_prog *tmp, *orig_prog = prog; + struct bpf_binary_header *header; + bool tmp_blinded = false; + struct jit_ctx ctx; + unsigned int tmp_idx; + unsigned int image_size; + u8 *image_ptr; + + /* If BPF JIT was not enabled then we must fall back to + * the interpreter. + */ if (!bpf_jit_enable) - return; + return orig_prog; + + /* If constant blinding was enabled and we failed during blinding + * then we must fall back to the interpreter. Otherwise, we save + * the new JITed code. + */ + tmp = bpf_jit_blind_constants(prog); + + if (IS_ERR(tmp)) + return orig_prog; + if (tmp != prog) { + tmp_blinded = true; + prog = tmp; + } memset(&ctx, 0, sizeof(ctx)); - ctx.skf = fp; - ctx.ret0_fp_idx = -1; + ctx.prog = prog; - ctx.offsets = kzalloc(4 * (ctx.skf->len + 1), GFP_KERNEL); - if (ctx.offsets == NULL) - return; - - /* fake pass to fill in the ctx->seen */ - if (unlikely(build_body(&ctx))) + /* Not able to allocate memory for offsets[] , then + * we must fall back to the interpreter + */ + ctx.offsets = kcalloc(prog->len, sizeof(int), GFP_KERNEL); + if (ctx.offsets == NULL) { + prog = orig_prog; goto out; + } + + /* 1) fake pass to find in the length of the JITed code, + * to compute ctx->offsets and other context variables + * needed to compute final JITed code. + * Also, calculate random starting pointer/start of JITed code + * which is prefixed by random number of fault instructions. + * + * If the first pass fails then there is no chance of it + * being successful in the second pass, so just fall back + * to the interpreter. + */ + if (build_body(&ctx)) { + prog = orig_prog; + goto out_off; + } tmp_idx = ctx.idx; build_prologue(&ctx); ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4; + ctx.epilogue_offset = ctx.idx; + #if __LINUX_ARM_ARCH__ < 7 tmp_idx = ctx.idx; build_epilogue(&ctx); @@ -1021,64 +1880,83 @@ void bpf_jit_compile(struct bpf_prog *fp) ctx.idx += ctx.imm_count; if (ctx.imm_count) { - ctx.imms = kzalloc(4 * ctx.imm_count, GFP_KERNEL); - if (ctx.imms == NULL) - goto out; + ctx.imms = kcalloc(ctx.imm_count, sizeof(u32), GFP_KERNEL); + if (ctx.imms == NULL) { + prog = orig_prog; + goto out_off; + } } #else - /* there's nothing after the epilogue on ARMv7 */ + /* there's nothing about the epilogue on ARMv7 */ build_epilogue(&ctx); #endif - alloc_size = 4 * ctx.idx; - header = bpf_jit_binary_alloc(alloc_size, &target_ptr, - 4, jit_fill_hole); - if (header == NULL) - goto out; + /* Now we can get the actual image size of the JITed arm code. + * Currently, we are not considering the THUMB-2 instructions + * for jit, although it can decrease the size of the image. + * + * As each arm instruction is of length 32bit, we are translating + * number of JITed intructions into the size required to store these + * JITed code. + */ + image_size = sizeof(u32) * ctx.idx; - ctx.target = (u32 *) target_ptr; + /* Now we know the size of the structure to make */ + header = bpf_jit_binary_alloc(image_size, &image_ptr, + sizeof(u32), jit_fill_hole); + /* Not able to allocate memory for the structure then + * we must fall back to the interpretation + */ + if (header == NULL) { + prog = orig_prog; + goto out_imms; + } + + /* 2.) Actual pass to generate final JIT code */ + ctx.target = (u32 *) image_ptr; ctx.idx = 0; build_prologue(&ctx); + + /* If building the body of the JITed code fails somehow, + * we fall back to the interpretation. + */ if (build_body(&ctx) < 0) { -#if __LINUX_ARM_ARCH__ < 7 - if (ctx.imm_count) - kfree(ctx.imms); -#endif + image_ptr = NULL; bpf_jit_binary_free(header); - goto out; + prog = orig_prog; + goto out_imms; } build_epilogue(&ctx); + /* 3.) Extra pass to validate JITed Code */ + if (validate_code(&ctx)) { + image_ptr = NULL; + bpf_jit_binary_free(header); + prog = orig_prog; + goto out_imms; + } flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx)); + if (bpf_jit_enable > 1) + /* there are 2 passes here */ + bpf_jit_dump(prog->len, image_size, 2, ctx.target); + + set_memory_ro((unsigned long)header, header->pages); + prog->bpf_func = (void *)ctx.target; + prog->jited = 1; + prog->jited_len = image_size; + +out_imms: #if __LINUX_ARM_ARCH__ < 7 if (ctx.imm_count) kfree(ctx.imms); #endif - - if (bpf_jit_enable > 1) - /* there are 2 passes here */ - bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); - - set_memory_ro((unsigned long)header, header->pages); - fp->bpf_func = (void *)ctx.target; - fp->jited = 1; -out: +out_off: kfree(ctx.offsets); - return; +out: + if (tmp_blinded) + bpf_jit_prog_release_other(prog, prog == orig_prog ? + tmp : orig_prog); + return prog; } -void bpf_jit_free(struct bpf_prog *fp) -{ - unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; - struct bpf_binary_header *header = (void *)addr; - - if (!fp->jited) - goto free_filter; - - set_memory_rw(addr, header->pages); - bpf_jit_binary_free(header); - -free_filter: - bpf_prog_unlock_free(fp); -} diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h index c46fca2972f7..d5cf5f6208aa 100644 --- a/arch/arm/net/bpf_jit_32.h +++ b/arch/arm/net/bpf_jit_32.h @@ -11,6 +11,7 @@ #ifndef PFILTER_OPCODES_ARM_H #define PFILTER_OPCODES_ARM_H +/* ARM 32bit Registers */ #define ARM_R0 0 #define ARM_R1 1 #define ARM_R2 2 @@ -22,38 +23,43 @@ #define ARM_R8 8 #define ARM_R9 9 #define ARM_R10 10 -#define ARM_FP 11 -#define ARM_IP 12 -#define ARM_SP 13 -#define ARM_LR 14 -#define ARM_PC 15 +#define ARM_FP 11 /* Frame Pointer */ +#define ARM_IP 12 /* Intra-procedure scratch register */ +#define ARM_SP 13 /* Stack pointer: as load/store base reg */ +#define ARM_LR 14 /* Link Register */ +#define ARM_PC 15 /* Program counter */ -#define ARM_COND_EQ 0x0 -#define ARM_COND_NE 0x1 -#define ARM_COND_CS 0x2 +#define ARM_COND_EQ 0x0 /* == */ +#define ARM_COND_NE 0x1 /* != */ +#define ARM_COND_CS 0x2 /* unsigned >= */ #define ARM_COND_HS ARM_COND_CS -#define ARM_COND_CC 0x3 +#define ARM_COND_CC 0x3 /* unsigned < */ #define ARM_COND_LO ARM_COND_CC -#define ARM_COND_MI 0x4 -#define ARM_COND_PL 0x5 -#define ARM_COND_VS 0x6 -#define ARM_COND_VC 0x7 -#define ARM_COND_HI 0x8 -#define ARM_COND_LS 0x9 -#define ARM_COND_GE 0xa -#define ARM_COND_LT 0xb -#define ARM_COND_GT 0xc -#define ARM_COND_LE 0xd -#define ARM_COND_AL 0xe +#define ARM_COND_MI 0x4 /* < 0 */ +#define ARM_COND_PL 0x5 /* >= 0 */ +#define ARM_COND_VS 0x6 /* Signed Overflow */ +#define ARM_COND_VC 0x7 /* No Signed Overflow */ +#define ARM_COND_HI 0x8 /* unsigned > */ +#define ARM_COND_LS 0x9 /* unsigned <= */ +#define ARM_COND_GE 0xa /* Signed >= */ +#define ARM_COND_LT 0xb /* Signed < */ +#define ARM_COND_GT 0xc /* Signed > */ +#define ARM_COND_LE 0xd /* Signed <= */ +#define ARM_COND_AL 0xe /* None */ /* register shift types */ #define SRTYPE_LSL 0 #define SRTYPE_LSR 1 #define SRTYPE_ASR 2 #define SRTYPE_ROR 3 +#define SRTYPE_ASL (SRTYPE_LSL) #define ARM_INST_ADD_R 0x00800000 +#define ARM_INST_ADDS_R 0x00900000 +#define ARM_INST_ADC_R 0x00a00000 +#define ARM_INST_ADC_I 0x02a00000 #define ARM_INST_ADD_I 0x02800000 +#define ARM_INST_ADDS_I 0x02900000 #define ARM_INST_AND_R 0x00000000 #define ARM_INST_AND_I 0x02000000 @@ -76,8 +82,10 @@ #define ARM_INST_LDRH_I 0x01d000b0 #define ARM_INST_LDRH_R 0x019000b0 #define ARM_INST_LDR_I 0x05900000 +#define ARM_INST_LDR_R 0x07900000 #define ARM_INST_LDM 0x08900000 +#define ARM_INST_LDM_IA 0x08b00000 #define ARM_INST_LSL_I 0x01a00000 #define ARM_INST_LSL_R 0x01a00010 @@ -86,6 +94,7 @@ #define ARM_INST_LSR_R 0x01a00030 #define ARM_INST_MOV_R 0x01a00000 +#define ARM_INST_MOVS_R 0x01b00000 #define ARM_INST_MOV_I 0x03a00000 #define ARM_INST_MOVW 0x03000000 #define ARM_INST_MOVT 0x03400000 @@ -96,17 +105,28 @@ #define ARM_INST_PUSH 0x092d0000 #define ARM_INST_ORR_R 0x01800000 +#define ARM_INST_ORRS_R 0x01900000 #define ARM_INST_ORR_I 0x03800000 #define ARM_INST_REV 0x06bf0f30 #define ARM_INST_REV16 0x06bf0fb0 #define ARM_INST_RSB_I 0x02600000 +#define ARM_INST_RSBS_I 0x02700000 +#define ARM_INST_RSC_I 0x02e00000 #define ARM_INST_SUB_R 0x00400000 +#define ARM_INST_SUBS_R 0x00500000 +#define ARM_INST_RSB_R 0x00600000 #define ARM_INST_SUB_I 0x02400000 +#define ARM_INST_SUBS_I 0x02500000 +#define ARM_INST_SBC_I 0x02c00000 +#define ARM_INST_SBC_R 0x00c00000 +#define ARM_INST_SBCS_R 0x00d00000 #define ARM_INST_STR_I 0x05800000 +#define ARM_INST_STRB_I 0x05c00000 +#define ARM_INST_STRH_I 0x01c000b0 #define ARM_INST_TST_R 0x01100000 #define ARM_INST_TST_I 0x03100000 @@ -117,6 +137,8 @@ #define ARM_INST_MLS 0x00600090 +#define ARM_INST_UXTH 0x06ff0070 + /* * Use a suitable undefined instruction to use for ARM/Thumb2 faulting. * We need to be careful not to conflict with those used by other modules @@ -135,9 +157,15 @@ #define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm)) /* immediate */ #define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm)) +/* register with register-shift */ +#define _AL3_SR(inst) (inst | (1 << 4)) #define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm) +#define ARM_ADDS_R(rd, rn, rm) _AL3_R(ARM_INST_ADDS, rd, rn, rm) #define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm) +#define ARM_ADDS_I(rd, rn, imm) _AL3_I(ARM_INST_ADDS, rd, rn, imm) +#define ARM_ADC_R(rd, rn, rm) _AL3_R(ARM_INST_ADC, rd, rn, rm) +#define ARM_ADC_I(rd, rn, imm) _AL3_I(ARM_INST_ADC, rd, rn, imm) #define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm) #define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm) @@ -156,7 +184,9 @@ #define ARM_EOR_I(rd, rn, imm) _AL3_I(ARM_INST_EOR, rd, rn, imm) #define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ - | (off)) + | ((off) & 0xfff)) +#define ARM_LDR_R(rt, rn, rm) (ARM_INST_LDR_R | (rt) << 12 | (rn) << 16 \ + | (rm)) #define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \ | (off)) #define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \ @@ -167,15 +197,23 @@ | (rm)) #define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs)) +#define ARM_LDM_IA(rn, regs) (ARM_INST_LDM_IA | (rn) << 16 | (regs)) #define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8) #define ARM_LSL_I(rd, rn, imm) (_AL3_I(ARM_INST_LSL, rd, 0, rn) | (imm) << 7) #define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8) #define ARM_LSR_I(rd, rn, imm) (_AL3_I(ARM_INST_LSR, rd, 0, rn) | (imm) << 7) +#define ARM_ASR_R(rd, rn, rm) (_AL3_R(ARM_INST_ASR, rd, 0, rn) | (rm) << 8) +#define ARM_ASR_I(rd, rn, imm) (_AL3_I(ARM_INST_ASR, rd, 0, rn) | (imm) << 7) #define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm) +#define ARM_MOVS_R(rd, rm) _AL3_R(ARM_INST_MOVS, rd, 0, rm) #define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm) +#define ARM_MOV_SR(rd, rm, type, rs) \ + (_AL3_SR(ARM_MOV_R(rd, rm)) | (type) << 5 | (rs) << 8) +#define ARM_MOV_SI(rd, rm, type, imm6) \ + (ARM_MOV_R(rd, rm) | (type) << 5 | (imm6) << 7) #define ARM_MOVW(rd, imm) \ (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff)) @@ -190,19 +228,38 @@ #define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm) #define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm) -#define ARM_ORR_S(rd, rn, rm, type, rs) \ - (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7) +#define ARM_ORR_SR(rd, rn, rm, type, rs) \ + (_AL3_SR(ARM_ORR_R(rd, rn, rm)) | (type) << 5 | (rs) << 8) +#define ARM_ORRS_R(rd, rn, rm) _AL3_R(ARM_INST_ORRS, rd, rn, rm) +#define ARM_ORRS_SR(rd, rn, rm, type, rs) \ + (_AL3_SR(ARM_ORRS_R(rd, rn, rm)) | (type) << 5 | (rs) << 8) +#define ARM_ORR_SI(rd, rn, rm, type, imm6) \ + (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (imm6) << 7) +#define ARM_ORRS_SI(rd, rn, rm, type, imm6) \ + (ARM_ORRS_R(rd, rn, rm) | (type) << 5 | (imm6) << 7) #define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm)) #define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm)) #define ARM_RSB_I(rd, rn, imm) _AL3_I(ARM_INST_RSB, rd, rn, imm) +#define ARM_RSBS_I(rd, rn, imm) _AL3_I(ARM_INST_RSBS, rd, rn, imm) +#define ARM_RSC_I(rd, rn, imm) _AL3_I(ARM_INST_RSC, rd, rn, imm) #define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm) +#define ARM_SUBS_R(rd, rn, rm) _AL3_R(ARM_INST_SUBS, rd, rn, rm) +#define ARM_RSB_R(rd, rn, rm) _AL3_R(ARM_INST_RSB, rd, rn, rm) +#define ARM_SBC_R(rd, rn, rm) _AL3_R(ARM_INST_SBC, rd, rn, rm) +#define ARM_SBCS_R(rd, rn, rm) _AL3_R(ARM_INST_SBCS, rd, rn, rm) #define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm) +#define ARM_SUBS_I(rd, rn, imm) _AL3_I(ARM_INST_SUBS, rd, rn, imm) +#define ARM_SBC_I(rd, rn, imm) _AL3_I(ARM_INST_SBC, rd, rn, imm) #define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \ - | (off)) + | ((off) & 0xfff)) +#define ARM_STRH_I(rt, rn, off) (ARM_INST_STRH_I | (rt) << 12 | (rn) << 16 \ + | (((off) & 0xf0) << 4) | ((off) & 0xf)) +#define ARM_STRB_I(rt, rn, off) (ARM_INST_STRB_I | (rt) << 12 | (rn) << 16 \ + | (((off) & 0xf0) << 4) | ((off) & 0xf)) #define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm) #define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm) @@ -214,5 +271,6 @@ #define ARM_MLS(rd, rn, rm, ra) (ARM_INST_MLS | (rd) << 16 | (rn) | (rm) << 8 \ | (ra) << 12) +#define ARM_UXTH(rd, rm) (ARM_INST_UXTH | (rd) << 12 | (rm)) #endif /* PFILTER_OPCODES_ARM_H */ diff --git a/arch/arm/nwfpe/ARM-gcc.h b/arch/arm/nwfpe/ARM-gcc.h index 436e54aa02ec..74389f5b0566 100644 --- a/arch/arm/nwfpe/ARM-gcc.h +++ b/arch/arm/nwfpe/ARM-gcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ------------------------------------------------------------------------------- The macro `BITS64' can be defined to indicate that 64-bit integer types are diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile index deb3a82ddbdf..303400fa2cdf 100644 --- a/arch/arm/nwfpe/Makefile +++ b/arch/arm/nwfpe/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Copyright (C) 1998, 1999, 2001 Philip Blundell # diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index b2215c61cdf0..39688dc9f181 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile index f2af203d601f..4d839a3cf284 100644 --- a/arch/arm/plat-iop/Makefile +++ b/arch/arm/plat-iop/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 3e27bffb352d..7276afee30b3 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ARCH_OMAP bool diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h index ba4525059a99..fb061cf0d736 100644 --- a/arch/arm/plat-omap/include/plat/sram.h +++ b/arch/arm/plat-omap/include/plat/sram.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ int omap_sram_init(void); void omap_map_sram(unsigned long start, unsigned long size, diff --git a/arch/arm/plat-samsung/include/plat/map-s3c.h b/arch/arm/plat-samsung/include/plat/map-s3c.h index 6feedd47d875..33104911862e 100644 --- a/arch/arm/plat-samsung/include/plat/map-s3c.h +++ b/arch/arm/plat-samsung/include/plat/map-s3c.h @@ -61,7 +61,7 @@ /* deal with the registers that move under the 2412/2413 */ -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) +#if defined(CONFIG_CPU_S3C2412) #ifndef __ASSEMBLY__ extern void __iomem *s3c24xx_va_gpio2; #endif diff --git a/arch/arm/plat-versatile/include/plat/sched_clock.h b/arch/arm/plat-versatile/include/plat/sched_clock.h index 5c3e4fc9fa0c..83fdaef23c2e 100644 --- a/arch/arm/plat-versatile/include/plat/sched_clock.h +++ b/arch/arm/plat-versatile/include/plat/sched_clock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARM_PLAT_SCHED_CLOCK_H #define ARM_PLAT_SCHED_CLOCK_H diff --git a/arch/arm/probes/Makefile b/arch/arm/probes/Makefile index aa1f8590dcdd..8b0ea5ace100 100644 --- a/arch/arm/probes/Makefile +++ b/arch/arm/probes/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_UPROBES) += decode.o decode-arm.o uprobes/ obj-$(CONFIG_KPROBES) += decode.o kprobes/ ifdef CONFIG_THUMB2_KERNEL diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile index 76a36bf102b7..14db56f49f0a 100644 --- a/arch/arm/probes/kprobes/Makefile +++ b/arch/arm/probes/kprobes/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o test-kprobes-objs := test-core.o diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index 92eb5c3b486c..ddb89a7db36f 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/arm/tools/Makefile # diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types index 04fef71d7be9..cbe1c33bb871 100644 --- a/arch/arm/tools/gen-mach-types +++ b/arch/arm/tools/gen-mach-types @@ -1,4 +1,5 @@ #!/bin/awk +# SPDX-License-Identifier: GPL-2.0 # # Awk script to generate include/generated/mach-types.h # diff --git a/arch/arm/tools/syscallhdr.sh b/arch/arm/tools/syscallhdr.sh index 72d4b2e3bdec..6b2f25cdd721 100644 --- a/arch/arm/tools/syscallhdr.sh +++ b/arch/arm/tools/syscallhdr.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 in="$1" out="$2" diff --git a/arch/arm/tools/syscallnr.sh b/arch/arm/tools/syscallnr.sh index d2971296469a..df3ccd0ca831 100644 --- a/arch/arm/tools/syscallnr.sh +++ b/arch/arm/tools/syscallnr.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 in="$1" out="$2" my_abis=`echo "($3)" | tr ',' '|'` diff --git a/arch/arm/tools/syscalltbl.sh b/arch/arm/tools/syscalltbl.sh index 5ca834545ed3..ae7e93cfbfd3 100644 --- a/arch/arm/tools/syscalltbl.sh +++ b/arch/arm/tools/syscalltbl.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 in="$1" out="$2" my_abis=`echo "($3)" | tr ',' '|'` diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile index 59a8fa7b8a3b..bb4118213fee 100644 --- a/arch/arm/vdso/Makefile +++ b/arch/arm/vdso/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 hostprogs-y := vdsomunge obj-vdso := vgettimeofday.o datapage.o diff --git a/arch/arm/vdso/datapage.S b/arch/arm/vdso/datapage.S index a2e60367931b..9cd73b725d9f 100644 --- a/arch/arm/vdso/datapage.S +++ b/arch/arm/vdso/datapage.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c index e71eefa2e427..0641ba54ab62 100644 --- a/arch/arm/xen/p2m.c +++ b/arch/arm/xen/p2m.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index dfd908630631..0df64a6a56d4 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -75,6 +75,7 @@ config ARM64 select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE + select HAVE_ARCH_VMAP_STACK select HAVE_ARM_SMCCC select HAVE_EBPF_JIT select HAVE_C_RECORDMCOUNT @@ -960,6 +961,18 @@ config ARM64_UAO regular load/store instructions if the cpu does not implement the feature. +config ARM64_PMEM + bool "Enable support for persistent memory" + select ARCH_HAS_PMEM_API + select ARCH_HAS_UACCESS_FLUSHCACHE + help + Say Y to enable support for the persistent memory API based on the + ARMv8.2 DCPoP feature. + + The feature is detected at runtime, and the kernel will use DC CVAC + operations if DC CVAP is not supported (following the behaviour of + DC CVAP itself if the system does not define a point of persistence). + endmenu config ARM64_MODULE_CMODEL_LARGE diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index f5f0c813dfec..6b54ee8c1262 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -184,6 +184,12 @@ config ARCH_R8A7796 help This enables support for the Renesas R-Car M3-W SoC. +config ARCH_R8A77995 + bool "Renesas R-Car D3 SoC Platform" + depends on ARCH_RENESAS + help + This enables support for the Renesas R-Car D3 SoC. + config ARCH_STRATIX10 bool "Altera's Stratix 10 SoCFPGA Family" help @@ -250,6 +256,7 @@ config ARCH_XGENE config ARCH_ZX bool "ZTE ZX SoC Family" + select PINCTRL help This enables support for ZTE ZX SoC Family diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 9b41f1e3b1a0..939b310913cf 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -50,17 +50,22 @@ KBUILD_CFLAGS += -fno-asynchronous-unwind-tables KBUILD_CFLAGS += $(call cc-option, -mpc-relative-literal-loads) KBUILD_AFLAGS += $(lseinstr) $(brokengasinst) +KBUILD_CFLAGS += $(call cc-option,-mabi=lp64) +KBUILD_AFLAGS += $(call cc-option,-mabi=lp64) + ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) KBUILD_CPPFLAGS += -mbig-endian CHECKFLAGS += -D__AARCH64EB__ AS += -EB LD += -EB +LDFLAGS += -maarch64linuxb UTS_MACHINE := aarch64_be else KBUILD_CPPFLAGS += -mlittle-endian CHECKFLAGS += -D__AARCH64EL__ AS += -EL LD += -EL +LDFLAGS += -maarch64linux UTS_MACHINE := aarch64 endif diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 8e1951273fd7..c6684ab8e201 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dts-dirs += actions dts-dirs += al dts-dirs += allwinner diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile index 108f12ce6d1d..ff35e184e422 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile +++ b/arch/arm64/boot/dts/allwinner/Makefile @@ -1,4 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb diff --git a/arch/arm64/boot/dts/allwinner/axp803.dtsi b/arch/arm64/boot/dts/allwinner/axp803.dtsi new file mode 100644 index 000000000000..ff8af52743ff --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/axp803.dtsi @@ -0,0 +1,150 @@ +/* + * Copyright 2017 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * AXP803 Integrated Power Management Chip + * http://files.pine64.org/doc/datasheet/pine64/AXP803_Datasheet_V1.0.pdf + */ + +&axp803 { + interrupt-controller; + #interrupt-cells = <1>; + + regulators { + /* Default work frequency for buck regulators */ + x-powers,dcdc-freq = <3000>; + + reg_aldo1: aldo1 { + regulator-name = "aldo1"; + }; + + reg_aldo2: aldo2 { + regulator-name = "aldo2"; + }; + + reg_aldo3: aldo3 { + regulator-name = "aldo3"; + }; + + reg_dc1sw: dc1sw { + regulator-name = "dc1sw"; + }; + + reg_dcdc1: dcdc1 { + regulator-name = "dcdc1"; + }; + + reg_dcdc2: dcdc2 { + regulator-name = "dcdc2"; + }; + + reg_dcdc3: dcdc3 { + regulator-name = "dcdc3"; + }; + + reg_dcdc4: dcdc4 { + regulator-name = "dcdc4"; + }; + + reg_dcdc5: dcdc5 { + regulator-name = "dcdc5"; + }; + + reg_dcdc6: dcdc6 { + regulator-name = "dcdc6"; + }; + + reg_dldo1: dldo1 { + regulator-name = "dldo1"; + }; + + reg_dldo2: dldo2 { + regulator-name = "dldo2"; + }; + + reg_dldo3: dldo3 { + regulator-name = "dldo3"; + }; + + reg_dldo4: dldo4 { + regulator-name = "dldo4"; + }; + + reg_eldo1: eldo1 { + regulator-name = "eldo1"; + }; + + reg_eldo2: eldo2 { + regulator-name = "eldo2"; + }; + + reg_eldo3: eldo3 { + regulator-name = "eldo3"; + }; + + reg_fldo1: fldo1 { + regulator-name = "fldo1"; + }; + + reg_fldo2: fldo2 { + regulator-name = "fldo2"; + }; + + reg_ldo_io0: ldo-io0 { + regulator-name = "ldo-io0"; + status = "disabled"; + }; + + reg_ldo_io1: ldo-io1 { + regulator-name = "ldo-io1"; + status = "disabled"; + }; + + reg_rtc_ldo: rtc-ldo { + /* RTC_LDO is a fixed, always-on regulator */ + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "rtc-ldo"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts index 6872135d7f84..d347f52e27f6 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts @@ -59,14 +59,16 @@ stdout-path = "serial0:115200n8"; }; - reg_vcc3v3: vcc3v3 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; + wifi_pwrseq: wifi_pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */ }; }; +&ehci1 { + status = "okay"; +}; + &i2c1 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins>; @@ -80,7 +82,7 @@ &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dcdc1>; cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; cd-inverted; disable-wp; @@ -91,22 +93,143 @@ &mmc1 { pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dldo2>; + vqmmc-supply = <®_dldo4>; + mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>; non-removable; status = "okay"; + + brcmf: wifi@1 { + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + interrupt-parent = <&r_pio>; + interrupts = <0 3 IRQ_TYPE_LEVEL_LOW>; /* PL3 */ + interrupt-names = "host-wake"; + }; }; &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dcdc1>; bus-width = <8>; non-removable; cap-mmc-hw-reset; status = "okay"; }; +&ohci1 { + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dc1sw { + regulator-name = "vcc-phy"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi-dsi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + +®_dldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-io"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; @@ -118,3 +241,7 @@ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; status = "okay"; }; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts new file mode 100644 index 000000000000..2beef9e6cb88 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2017 Jagan Teki + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "sun50i-a64.dtsi" + +#include + +/ { + model = "FriendlyARM NanoPi A64"; + compatible = "friendlyarm,nanopi-a64", "allwinner,sun50i-a64"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +/* i2c1 connected with gpio headers like pine64, bananapi */ +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "disabled"; +}; + +&i2c1_pins { + bias-pull-up; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_dcdc1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; + cd-inverted; + disable-wp; + bus-width = <4>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-3v"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi-dsi"; +}; + +®_dldo4 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pg-wifi-io"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts new file mode 100644 index 000000000000..338e786155b1 --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2017 Jagan Teki + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "sun50i-a64.dtsi" + +#include + +/ { + model = "Olimex A64-Olinuxino"; + compatible = "olimex,a64-olinuxino", "allwinner,sun50i-a64"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins>; + vmmc-supply = <®_dcdc1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; + cd-inverted; + disable-wp; + bus-width = <4>; + status = "okay"; +}; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "vcc-pe"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-ddr3"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-mipi"; +}; + +®_dldo3 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-name = "vcc-avdd-csi"; +}; + +®_dldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-io"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_eldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dvdd-csi"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts index 7c533b6d4ba9..d06e34b5d192 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts @@ -61,13 +61,6 @@ chosen { stdout-path = "serial0:115200n8"; }; - - reg_vcc3v3: vcc3v3 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; }; &ehci0 { @@ -91,7 +84,7 @@ &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; - vmmc-supply = <®_vcc3v3>; + vmmc-supply = <®_dcdc1>; cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; cd-inverted; disable-wp; @@ -107,6 +100,118 @@ status = "okay"; }; +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dc1sw { + regulator-name = "vcc-phy"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +/* + * The DRAM chips used by Pine64 boards are DDR3L-compatible, so they can + * work at 1.35V with less power consumption. + * As AXP803 DCDC5 cannot reach 1.35V accurately, use 1.36V instead. + */ +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1360000>; + regulator-max-microvolt = <1360000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-mipi"; +}; + +®_dldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "cpvdd"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; + /* On Exp and Euler connectors */ &uart0 { pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts index d891a1a27f6c..17ccc12b58df 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts @@ -95,6 +95,28 @@ status = "okay"; }; +®_dc1sw { + regulator-name = "vcc-phy"; +}; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi"; +}; + +®_dldo2 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-mipi"; +}; + +®_dldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_pins_a>; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi index 475518b031dd..a5da18a6f286 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi @@ -63,3 +63,89 @@ bus-width = <4>; status = "okay"; }; + +&r_rsb { + status = "okay"; + + axp803: pmic@3a3 { + compatible = "x-powers,axp803"; + reg = <0x3a3>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pl"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1040000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-cpux"; +}; + +/* DCDC3 is polyphased with DCDC2 */ + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-dram"; +}; + +®_dcdc6 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-sys"; +}; + +®_eldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vdd-1v8-lpddr"; +}; + +®_fldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vcc-1v2-hsic"; +}; + +/* + * The A64 chip cannot work without this regulator off, although + * it seems to be only driving the AR100 core. + * Maybe we don't still know well about CPUs domain. + */ +®_fldo2 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpus"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; +}; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 68aadc9b96dc..8c8db1b057df 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -467,6 +467,15 @@ ; }; + r_intc: interrupt-controller@1f00c00 { + compatible = "allwinner,sun50i-a64-r-intc", + "allwinner,sun6i-a31-r-intc"; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x01f00c00 0x400>; + interrupts = ; + }; + r_ccu: clock@1f01400 { compatible = "allwinner,sun50i-a64-r-ccu"; reg = <0x01f01400 0x100>; diff --git a/arch/arm64/boot/dts/amd/Makefile b/arch/arm64/boot/dts/amd/Makefile index ba84770f789f..f9963d63006d 100644 --- a/arch/arm64/boot/dts/amd/Makefile +++ b/arch/arm64/boot/dts/amd/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb \ amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb \ husky.dtb diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts index 8e3074a4947d..8e341be9a399 100644 --- a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DTS file for AMD Seattle Overdrive Development Board * Note: For Seattle Rev.B0 diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts index ed5e043f37aa..92cef05c6b74 100644 --- a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DTS file for AMD Seattle Overdrive Development Board * Note: For Seattle Rev.B1 diff --git a/arch/arm64/boot/dts/amd/amd-overdrive.dts b/arch/arm64/boot/dts/amd/amd-overdrive.dts index 128fa942f09e..41b3a6c0993d 100644 --- a/arch/arm64/boot/dts/amd/amd-overdrive.dts +++ b/arch/arm64/boot/dts/amd/amd-overdrive.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DTS file for AMD Seattle Overdrive Development Board * diff --git a/arch/arm64/boot/dts/amd/amd-seattle-clks.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-clks.dtsi index f623c46525a6..2dd2c28171ee 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-clks.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-clks.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DTS file for AMD Seattle Clocks * diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index bd3adeac374f..125f4deb52fe 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DTS file for AMD Seattle SoC * diff --git a/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi index 8e8631952497..d97498361ce3 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DTS file for AMD Seattle XGBE (RevB) * diff --git a/arch/arm64/boot/dts/amd/husky.dts b/arch/arm64/boot/dts/amd/husky.dts index 1381d4b2bf1b..7acde34772cb 100644 --- a/arch/arm64/boot/dts/amd/husky.dts +++ b/arch/arm64/boot/dts/amd/husky.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DTS file for AMD/Linaro 96Boards Enterprise Edition Server (Husky) Board * Note: Based-on AMD Seattle Rev.B0 diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile index 7a9f48c27b1f..543416b8dff5 100644 --- a/arch/arm64/boot/dts/amlogic/Makefile +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-odroidc2.dtb diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi index dc478d094c11..4157987f4a3d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi @@ -121,6 +121,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -161,7 +168,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -187,7 +195,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -205,10 +214,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 738ed689ff69..f175db846286 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -225,7 +225,7 @@ }; uart_A: serial@84c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; reg = <0x0 0x84c0 0x0 0x14>; interrupts = ; clocks = <&xtal>; @@ -233,7 +233,7 @@ }; uart_B: serial@84dc { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; reg = <0x0 0x84dc 0x0 0x14>; interrupts = ; clocks = <&xtal>; @@ -279,7 +279,7 @@ }; uart_C: serial@8700 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-uart"; reg = <0x0 0x8700 0x0 0x14>; interrupts = ; clocks = <&xtal>; @@ -367,26 +367,40 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>; - clkc_AO: clock-controller@040 { - compatible = "amlogic,gx-aoclkc", "amlogic,gxbb-aoclkc"; - reg = <0x0 0x00040 0x0 0x4>; - #clock-cells = <1>; - #reset-cells = <1>; + sysctrl_AO: sys-ctrl@0 { + compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"; + reg = <0x0 0x0 0x0 0x100>; + + clkc_AO: clock-controller { + compatible = "amlogic,meson-gx-aoclkc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + }; + + cec_AO: cec@100 { + compatible = "amlogic,meson-gx-ao-cec"; + reg = <0x0 0x00100 0x0 0x14>; + interrupts = ; + }; + + sec_AO: ao-secure@140 { + compatible = "amlogic,meson-gx-ao-secure", "syscon"; + reg = <0x0 0x140 0x0 0x140>; + amlogic,has-chip-id; }; uart_AO: serial@4c0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; reg = <0x0 0x004c0 0x0 0x14>; interrupts = ; - clocks = <&xtal>; status = "disabled"; }; uart_AO_B: serial@4e0 { - compatible = "amlogic,meson-uart"; + compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; reg = <0x0 0x004e0 0x0 0x14>; interrupts = ; - clocks = <&xtal>; status = "disabled"; }; @@ -437,9 +451,9 @@ mailbox: mailbox@404 { compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu"; reg = <0 0x404 0 0x4c>; - interrupts = <0 208 IRQ_TYPE_EDGE_RISING>, - <0 209 IRQ_TYPE_EDGE_RISING>, - <0 210 IRQ_TYPE_EDGE_RISING>; + interrupts = , + , + ; #mbox-cells = <1>; }; }; @@ -448,7 +462,7 @@ compatible = "amlogic,meson-gx-dwmac", "amlogic,meson-gxbb-dwmac", "snps,dwmac"; reg = <0x0 0xc9410000 0x0 0x10000 0x0 0xc8834540 0x0 0x4>; - interrupts = <0 8 1>; + interrupts = ; interrupt-names = "macirq"; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts index fa462831ccaf..4b17a76959b2 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts @@ -107,6 +107,9 @@ states = <3300000 0>, <1800000 1>; + + regulator-settling-time-up-us = <100>; + regulator-settling-time-down-us = <5000>; }; wifi_32k: wifi-32k { @@ -175,6 +178,64 @@ pinctrl-names = "default"; }; +&pinctrl_aobus { + gpio-line-names = "UART TX", "UART RX", "Power Control", "Power Key In", + "VCCK En", "CON1 Header Pin31", + "I2S Header Pin6", "IR In", "I2S Header Pin7", + "I2S Header Pin3", "I2S Header Pin4", + "I2S Header Pin5", "HDMI CEC", "SYS LED"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "Eth MDIO", "Eth MDC", "Eth RGMII RX Clk", + "Eth RX DV", "Eth RX D0", "Eth RX D1", "Eth RX D2", + "Eth RX D3", "Eth RGMII TX Clk", "Eth TX En", + "Eth TX D0", "Eth TX D1", "Eth TX D2", "Eth TX D3", + "Eth PHY nRESET", "Eth PHY Intc", + /* Bank GPIOH */ + "HDMI HPD", "HDMI DDC SDA", "HDMI DDC SCL", + "CON1 Header Pin33", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", "eMMC D4", + "eMMC D5", "eMMC D6", "eMMC D7", "eMMC Clk", + "eMMC Reset", "eMMC CMD", + "", "", "", "", "eMMC DS", + "", "", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", + "I2C A SDA", "I2C A SCK", "I2C B SDA", "I2C B SCK", + "VDDEE Regulator", "VCCK Regulator", + /* Bank GPIOY */ + "CON1 Header Pin7", "CON1 Header Pin11", + "CON1 Header Pin13", "CON1 Header Pin15", + "CON1 Header Pin18", "CON1 Header Pin19", + "CON1 Header Pin22", "CON1 Header Pin21", + "CON1 Header Pin24", "CON1 Header Pin23", + "CON1 Header Pin26", "CON1 Header Pin29", + "CON1 Header Pin32", "CON1 Header Pin8", + "CON1 Header Pin10", "CON1 Header Pin16", + "CON1 Header Pin12", + /* Bank GPIOX */ + "WIFI SDIO D0", "WIFI SDIO D1", "WIFI SDIO D2", + "WIFI SDIO D3", "WIFI SDIO CLK", "WIFI SDIO CMD", + "WIFI Power Enable", "WIFI WAKE HOST", + "Bluetooth PCM DOUT", "Bluetooth PCM DIN", + "Bluetooth PCM SYNC", "Bluetooth PCM CLK", + "Bluetooth UART TX", "Bluetooth UART RX", + "Bluetooth UART CTS", "Bluetooth UART RTS", + "", "", "", "WIFI 32K", "Bluetooth Enable", + "Bluetooth WAKE HOST", + /* Bank GPIOCLK */ + "", "CON1 Header Pin35", "", "", + /* GPIO_TEST_N */ + ""; +}; + &pwm_ef { status = "okay"; pinctrl-0 = <&pwm_e_pins>; @@ -192,7 +253,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>, <&sdio_irq_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -218,11 +280,16 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; - max-frequency = <100000000>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + max-frequency = <200000000>; disable-wp; cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>; @@ -236,10 +303,10 @@ &sd_emmc_c { status = "disabled"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; max-frequency = <200000000>; non-removable; disable-wp; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts index a1078b3e1c76..38dfdde5c147 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts @@ -51,7 +51,7 @@ / { compatible = "nexbox,a95x", "amlogic,meson-gxbb"; model = "NEXBOX A95X"; - + aliases { serial0 = &uart_AO; }; @@ -171,6 +171,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + ðmac { status = "okay"; pinctrl-0 = <ð_rmii_pins>; @@ -225,7 +232,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -246,7 +254,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -264,10 +273,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts index d147c853ab05..1ffa1c238a72 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -50,7 +50,7 @@ / { compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; model = "Hardkernel ODROID-C2"; - + aliases { serial0 = &uart_AO; }; @@ -253,7 +253,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -271,10 +272,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; max-frequency = <200000000>; non-removable; disable-wp; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi index d904deb1018c..23c08c3afd0a 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi @@ -84,6 +84,9 @@ /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */ states = <1800000 0 3300000 1>; + + regulator-settling-time-up-us = <10000>; + regulator-settling-time-down-us = <150000>; }; vddio_boot: regulator-vddio_boot { @@ -148,6 +151,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -184,7 +194,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -210,10 +221,14 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; max-frequency = <100000000>; disable-wp; @@ -228,10 +243,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi index 346753fb6324..f2bc6dea1fc6 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -155,7 +155,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins &sdio_irq_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -181,7 +182,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -198,10 +200,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts index e76ac313fef9..f7144fd5e03f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts @@ -108,6 +108,12 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; &cvbs_vdac_port { cvbs_vdac_out: endpoint { diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index 17d3efdf1469..af834cdbba79 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -307,6 +307,15 @@ }; }; +&cec_AO { + clocks = <&clkc_AO CLKID_AO_CEC_32K>; + clock-names = "core"; +}; + +&clkc_AO { + compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc"; +}; + ðmac { clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, @@ -383,6 +392,17 @@ }; }; + emmc_clk_gate_pins: emmc_clk_gate { + mux { + groups = "BOOT_8"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "BOOT_8"; + bias-pull-down; + }; + }; + nor_pins: nor { mux { groups = "nor_d", @@ -421,6 +441,17 @@ }; }; + sdcard_clk_gate_pins: sdcard_clk_gate { + mux { + groups = "CARD_2"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "CARD_2"; + bias-pull-down; + }; + }; + sdio_pins: sdio { mux { groups = "sdio_d0", @@ -433,6 +464,17 @@ }; }; + sdio_clk_gate_pins: sdio_clk_gate { + mux { + groups = "GPIOX_4"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "GPIOX_4"; + bias-pull-down; + }; + }; + sdio_irq_pins: sdio_irq { mux { groups = "sdio_irq"; @@ -652,21 +694,21 @@ &sd_emmc_a { clocks = <&clkc CLKID_SD_EMMC_A>, - <&xtal>, + <&clkc CLKID_SD_EMMC_A_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_b { clocks = <&clkc CLKID_SD_EMMC_B>, - <&xtal>, + <&clkc CLKID_SD_EMMC_B_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_c { clocks = <&clkc CLKID_SD_EMMC_C>, - <&xtal>, + <&clkc CLKID_SD_EMMC_C_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; @@ -682,6 +724,31 @@ clocks = <&clkc CLKID_SPI>; }; +&uart_A { + clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_AO { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_AO_B { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_B { + clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + +&uart_C { + clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts index 3e0c023d6abd..6827f235d7cf 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts @@ -97,6 +97,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + /* P230 has exclusive choice between internal or external PHY */ ðmac { pinctrl-0 = <ð_pins>; @@ -124,7 +131,6 @@ }; }; - &hdmi_tx { status = "okay"; pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts index 2a5804ce7f4b..977b4240f3c1 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts @@ -123,7 +123,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -141,10 +142,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <100000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts index 94567eb17875..edc512ad0bac 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts @@ -67,6 +67,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &hdmi_tx { status = "okay"; pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; @@ -105,6 +112,62 @@ linux,rc-map-name = "rc-geekbox"; }; +&pinctrl_aobus { + gpio-line-names = "UART TX", + "UART RX", + "Power Key In", + "J9 Header Pin35", + "J9 Header Pin16", + "J9 Header Pin15", + "J9 Header Pin33", + "IR In", + "HDMI CEC", + "SYS LED"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "", "", "", "", "", "", "", + "", "", "", "", "", "", "", + "Power OFF", + "VCCK Enable", + /* Bank GPIOH */ + "HDMI HPD", "HDMI SDA", "HDMI SCL", + "HDMI_5V_EN", "SPDIF", + "J9 Header Pin37", + "J9 Header Pin30", + "J9 Header Pin29", + "J9 Header Pin32", + "J9 Header Pin31", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", + "eMMC D4", "eMMC D5", "eMMC D6", "eMMC D7", + "eMMC Clk", "eMMC Reset", "eMMC CMD", + "", "BOOT_MODE", "", "", "eMMC Data Strobe", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", + "I2C A SDA", "I2C A SCK", "I2C B SDA", "I2C B SCK", + "VCCK Regulator", "VDDEE Regulator", + /* Bank GPIOX */ + "WIFI SDIO D0", "WIFI SDIO D1", "WIFI SDIO D2", + "WIFI SDIO D3", "WIFI SDIO CLK", "WIFI SDIO CMD", + "WIFI Power Enable", "WIFI WAKE HOST", + "Bluetooth PCM DOUT", "Bluetooth PCM DIN", + "Bluetooth PCM SYNC", "Bluetooth PCM CLK", + "Bluetooth UART TX", "Bluetooth UART RX", + "Bluetooth UART CTS", "Bluetooth UART RTS", + "WIFI 32K", "Bluetooth Enable", + "Bluetooth WAKE HOST", + /* Bank GPIOCLK */ + "", "J9 Header Pin39", + /* GPIO_TEST_N */ + ""; +}; + &pwm_AO_ab { status = "okay"; pinctrl-0 = <&pwm_ao_a_3_pins>, <&pwm_ao_b_pins>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts index 266fbcf3e47f..64c54c92e214 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts @@ -91,6 +91,9 @@ states = <3300000 0>, <1800000 1>; + + regulator-settling-time-up-us = <200>; + regulator-settling-time-down-us = <50000>; }; vddio_boot: regulator-vddio_boot { @@ -101,6 +104,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -129,14 +139,75 @@ }; }; +&pinctrl_aobus { + gpio-line-names = "UART TX", + "UART RX", + "Blue LED", + "SDCard Voltage Switch", + "7J1 Header Pin5", + "7J1 Header Pin3", + "7J1 Header Pin12", + "IR In", + "9J3 Switch HDMI CEC/7J1 Header Pin11", + "7J1 Header Pin13"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "", "", "", "", "", "", "", + "", "", "", "", "", "", "", + "Eth Link LED", "Eth Activity LED", + /* Bank GPIOH */ + "HDMI HPD", "HDMI SDA", "HDMI SCL", + "HDMI_5V_EN", "9J1 Header Pin2", + "Analog Audio Mute", + "2J3 Header Pin6", + "2J3 Header Pin5", + "2J3 Header Pin4", + "2J3 Header Pin3", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", + "eMMC D4", "eMMC D5", "eMMC D6", "eMMC D7", + "eMMC Clk", "eMMC Reset", "eMMC CMD", + "ALT BOOT MODE", "", "", "", "eMMC Data Strobe", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", + "Green LED", "VCCK Enable", + "7J1 Header Pin27", "7J1 Header Pin28", + "VCCK Regulator", "VDDEE Regulator", + /* Bank GPIOX */ + "7J1 Header Pin22", "7J1 Header Pin26", + "7J1 Header Pin36", "7J1 Header Pin38", + "7J1 Header Pin40", "7J1 Header Pin37", + "7J1 Header Pin33", "7J1 Header Pin35", + "7J1 Header Pin19", "7J1 Header Pin21", + "7J1 Header Pin24", "7J1 Header Pin23", + "7J1 Header Pin8", "7J1 Header Pin10", + "7J1 Header Pin16", "7J1 Header Pin18", + "7J1 Header Pin32", "7J1 Header Pin29", + "7J1 Header Pin31", + /* Bank GPIOCLK */ + "7J1 Header Pin7", "", + /* GPIO_TEST_N */ + "7J1 Header Pin15"; +}; + /* SD card */ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; max-frequency = <100000000>; disable-wp; @@ -151,10 +222,12 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; cap-mmc-highspeed; + mmc-ddr-3_3v; max-frequency = <50000000>; non-removable; disable-wp; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts index 6633a5d8fdd3..1b8f32867aa1 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts @@ -140,6 +140,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -182,7 +189,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -203,7 +211,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -221,10 +230,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts index 6ab17c1eeefd..6e2bf858291c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts @@ -71,6 +71,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi index f3eea8e89d12..129af9068814 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi @@ -95,7 +95,8 @@ &sd_emmc_a { status = "okay"; pinctrl-0 = <&sdio_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdio_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; #address-cells = <1>; #size-cells = <0>; @@ -116,7 +117,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -134,10 +136,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index 8d4f3160a0ee..d8dd3298b15c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -43,6 +43,7 @@ #include "meson-gx.dtsi" #include +#include #include #include @@ -207,6 +208,15 @@ }; }; +&cec_AO { + clocks = <&clkc_AO CLKID_AO_CEC_32K>; + clock-names = "core"; +}; + +&clkc_AO { + compatible = "amlogic,meson-gxl-aoclkc", "amlogic,meson-gx-aoclkc"; +}; + &hdmi_tx { compatible = "amlogic,meson-gxl-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; resets = <&reset RESET_HDMITX_CAPB3>, @@ -271,6 +281,17 @@ }; }; + emmc_clk_gate_pins: emmc_clk_gate { + mux { + groups = "BOOT_8"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "BOOT_8"; + bias-pull-down; + }; + }; + nor_pins: nor { mux { groups = "nor_d", @@ -309,6 +330,17 @@ }; }; + sdcard_clk_gate_pins: sdcard_clk_gate { + mux { + groups = "CARD_2"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "CARD_2"; + bias-pull-down; + }; + }; + sdio_pins: sdio { mux { groups = "sdio_d0", @@ -321,6 +353,17 @@ }; }; + sdio_clk_gate_pins: sdio_clk_gate { + mux { + groups = "GPIOX_4"; + function = "gpio_periphs"; + }; + cfg-pull-down { + pins = "GPIOX_4"; + bias-pull-down; + }; + }; + sdio_irq_pins: sdio_irq { mux { groups = "sdio_irq"; @@ -593,21 +636,21 @@ &sd_emmc_a { clocks = <&clkc CLKID_SD_EMMC_A>, - <&xtal>, + <&clkc CLKID_SD_EMMC_A_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_b { clocks = <&clkc CLKID_SD_EMMC_B>, - <&xtal>, + <&clkc CLKID_SD_EMMC_B_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; &sd_emmc_c { clocks = <&clkc CLKID_SD_EMMC_C>, - <&xtal>, + <&clkc CLKID_SD_EMMC_C_CLK0>, <&clkc CLKID_FCLK_DIV2>; clock-names = "core", "clkin0", "clkin1"; }; @@ -623,6 +666,31 @@ clocks = <&clkc CLKID_SPI>; }; +&uart_A { + clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + +&uart_AO { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_AO_B { + clocks = <&xtal>, <&clkc CLKID_CLK81>, <&xtal>; + clock-names = "xtal", "pclk", "baud"; +}; + +&uart_B { + clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + +&uart_C { + clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>; + clock-names = "xtal", "core", "baud"; +}; + &vpu { compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu"; }; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts index 5f626d683088..22c697732f66 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts @@ -113,6 +113,13 @@ }; }; +&cec_AO { + status = "okay"; + pinctrl-0 = <&ao_cec_pins>; + pinctrl-names = "default"; + hdmi-phandle = <&hdmi_tx>; +}; + &cvbs_vdac_port { cvbs_vdac_out: endpoint { remote-endpoint = <&cvbs_connector_in>; @@ -168,7 +175,8 @@ &sd_emmc_b { status = "okay"; pinctrl-0 = <&sdcard_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&sdcard_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <4>; cap-sd-highspeed; @@ -186,10 +194,10 @@ &sd_emmc_c { status = "okay"; pinctrl-0 = <&emmc_pins>; - pinctrl-names = "default"; + pinctrl-1 = <&emmc_clk_gate_pins>; + pinctrl-names = "default", "clk-gate"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts index 08f1dd69b679..470f72bb863c 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts @@ -220,7 +220,6 @@ pinctrl-names = "default"; bus-width = <8>; - cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <200000000>; non-removable; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi index fe451cce93e7..19a798d2ae2f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi @@ -117,6 +117,10 @@ }; }; +&clkc_AO { + compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc"; +}; + &saradc { compatible = "amlogic,meson-gxm-saradc", "amlogic,meson-saradc"; }; diff --git a/arch/arm64/boot/dts/apm/Makefile b/arch/arm64/boot/dts/apm/Makefile index c75f17a49471..a10fbdb34229 100644 --- a/arch/arm64/boot/dts/apm/Makefile +++ b/arch/arm64/boot/dts/apm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb dtb-$(CONFIG_ARCH_XGENE) += apm-merlin.dtb diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi index 72720e9132a1..c9ffffb96e43 100644 --- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi @@ -626,6 +626,7 @@ 0x43000000 0xe0 0x00000000 0xe0 0x00000000 0x20 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x10 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x11 0x4 @@ -651,6 +652,7 @@ 0x43000000 0xb0 0x00000000 0xb0 0x00000000 0x10 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 0x16 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 0x17 0x4 diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index 63be8e51eaa8..c09a36fed917 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -626,6 +626,7 @@ 0x43000000 0xf0 0x00000000 0xf0 0x00000000 0x10 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x4 @@ -651,6 +652,7 @@ 0x43000000 0xd8 0x00000000 0xd8 0x00000000 0x08 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc8 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xc9 0x4 @@ -676,6 +678,7 @@ 0x43000000 0x94 0x00000000 0x94 0x00000000 0x04 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xce 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xcf 0x4 @@ -701,6 +704,7 @@ 0x43000000 0xb0 0x00000000 0xb0 0x00000000 0x10 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xd4 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xd5 0x4 @@ -726,6 +730,7 @@ 0x43000000 0xc8 0x00000000 0xc8 0x00000000 0x08 0x00000000>; /* mem */ dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xda 0x4 0x0 0x0 0x0 0x2 &gic 0x0 0xdb 0x4 diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile index 75cc2aa10101..470378addca4 100644 --- a/arch/arm64/boot/dts/arm/Makefile +++ b/arch/arm64/boot/dts/arm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb foundation-v8-gicv3.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb juno-r2.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb diff --git a/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts index 35588dfa095c..4825cdbdcf46 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. * diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts index 71168077312d..8a9136f4ab74 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. * diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi index 7cfa8e414e7f..f0b67e439f58 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dtsi +++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. * @@ -226,7 +227,7 @@ clock-names = "uartclk", "apb_pclk"; }; - virtio_block@0130000 { + virtio-block@0130000 { compatible = "virtio,mmio"; reg = <0x130000 0x200>; interrupts = <42>; diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index e8b7413ec890..f165f04db0c9 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "juno-clocks.dtsi" / { @@ -201,7 +202,7 @@ }; }; - cpu_debug0: cpu_debug@22010000 { + cpu_debug0: cpu-debug@22010000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x22010000 0x0 0x1000>; @@ -260,7 +261,7 @@ }; }; - cpu_debug1: cpu_debug@22110000 { + cpu_debug1: cpu-debug@22110000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x22110000 0x0 0x1000>; @@ -283,7 +284,7 @@ }; }; - cpu_debug2: cpu_debug@23010000 { + cpu_debug2: cpu-debug@23010000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23010000 0x0 0x1000>; @@ -356,7 +357,7 @@ }; }; - cpu_debug3: cpu_debug@23110000 { + cpu_debug3: cpu-debug@23110000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23110000 0x0 0x1000>; @@ -379,7 +380,7 @@ }; }; - cpu_debug4: cpu_debug@23210000 { + cpu_debug4: cpu-debug@23210000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23210000 0x0 0x1000>; @@ -402,7 +403,7 @@ }; }; - cpu_debug5: cpu_debug@23310000 { + cpu_debug5: cpu-debug@23310000 { compatible = "arm,coresight-cpu-debug", "arm,primecell"; reg = <0x0 0x23310000 0x0 0x1000>; @@ -426,7 +427,7 @@ }; replicator@20120000 { - compatible = "qcom,coresight-replicator1x", "arm,primecell"; + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0 0x20120000 0 0x1000>; clocks = <&soc_smc50mhz>; diff --git a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi index aa03050dd7df..0c43fb3525eb 100644 --- a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi +++ b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { funnel@20130000 { /* cssys1 */ compatible = "arm,coresight-funnel", "arm,primecell"; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts index a83ed2c6bbf7..7810632d3438 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts +++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Fast Models * diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi index 161ac98418a3..e18fe006cc2a 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Fast Models * @@ -219,7 +220,7 @@ }; }; - virtio_block@0130000 { + virtio-block@0130000 { compatible = "virtio,mmio"; reg = <0x130000 0x200>; interrupts = <42>; diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts index e3a171162bb4..2cb604957808 100644 --- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts +++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ARM Ltd. Versatile Express * diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile index f11bdd6689ea..3df2db7f8878 100644 --- a/arch/arm64/boot/dts/broadcom/Makefile +++ b/arch/arm64/boot/dts/broadcom/Makefile @@ -1,7 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb -dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb ns2-xmc.dtb -dts-dirs := stingray +dts-dirs += northstar2 +dts-dirs += stingray always := $(dtb-y) subdir-y := $(dts-dirs) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi b/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi deleted file mode 120000 index 3937b77cb310..000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm2835-rpi.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm2835-rpi.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts index 972f14db28ac..89b78d6c19bf 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts @@ -1,41 +1,2 @@ -/dts-v1/; -#include "bcm2837.dtsi" -#include "bcm2835-rpi.dtsi" -#include "bcm283x-rpi-smsc9514.dtsi" -#include "bcm283x-rpi-usb-host.dtsi" - -/ { - compatible = "raspberrypi,3-model-b", "brcm,bcm2837"; - model = "Raspberry Pi 3 Model B"; - - memory { - reg = <0 0x40000000>; - }; - - leds { - act { - gpios = <&gpio 47 0>; - }; - }; -}; - -&uart1 { - status = "okay"; -}; - -/* SDHCI is used to control the SDIO for wireless */ -&sdhci { - pinctrl-names = "default"; - pinctrl-0 = <&emmc_gpio34>; - status = "okay"; - bus-width = <4>; - non-removable; -}; - -/* SDHOST is used to drive the SD card */ -&sdhost { - pinctrl-names = "default"; - pinctrl-0 = <&sdhost_gpio48>; - status = "okay"; - bus-width = <4>; -}; +// SPDX-License-Identifier: GPL-2.0 +#include "arm/bcm2837-rpi-3-b.dts" diff --git a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi deleted file mode 120000 index dca7c057d5a5..000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-smsc9514.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm283x-rpi-smsc9514.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi deleted file mode 120000 index cbeebe312ff8..000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm283x-rpi-usb-host.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm283x-rpi-usb-host.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/bcm283x.dtsi b/arch/arm64/boot/dts/broadcom/bcm283x.dtsi deleted file mode 120000 index 5f54e4cab99b..000000000000 --- a/arch/arm64/boot/dts/broadcom/bcm283x.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/bcm283x.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/broadcom/northstar2/Makefile b/arch/arm64/boot/dts/broadcom/northstar2/Makefile new file mode 100644 index 000000000000..e01a1485b813 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/northstar2/Makefile @@ -0,0 +1,6 @@ +dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb +dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-xmc.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/broadcom/ns2-clock.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2-clock.dtsi similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2-clock.dtsi rename to arch/arm64/boot/dts/broadcom/northstar2/ns2-clock.dtsi diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2-svk.dts rename to arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts diff --git a/arch/arm64/boot/dts/broadcom/ns2-xmc.dts b/arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2-xmc.dts rename to arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi similarity index 100% rename from arch/arm64/boot/dts/broadcom/ns2.dtsi rename to arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi diff --git a/arch/arm64/boot/dts/broadcom/stingray/Makefile b/arch/arm64/boot/dts/broadcom/stingray/Makefile index f70028edad63..04bb302f3233 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/Makefile +++ b/arch/arm64/boot/dts/broadcom/stingray/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_BCM_IPROC) += bcm958742k.dtb dtb-$(CONFIG_ARCH_BCM_IPROC) += bcm958742t.dtb diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi b/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi index 5dca7d10253b..8862ec907fd8 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/bcm958742-base.dtsi @@ -72,6 +72,78 @@ <0x00000008 0x80000000 0x1 0x80000000>; /* 6G @ 34G */ }; +&sata0 { + status = "okay"; +}; + +&sata_phy0{ + status = "okay"; +}; + +&sata1 { + status = "okay"; +}; + +&sata_phy1{ + status = "okay"; +}; + +&sata2 { + status = "okay"; +}; + +&sata_phy2{ + status = "okay"; +}; + +&sata3 { + status = "okay"; +}; + +&sata_phy3{ + status = "okay"; +}; + +&sata4 { + status = "okay"; +}; + +&sata_phy4{ + status = "okay"; +}; + +&sata5 { + status = "okay"; +}; + +&sata_phy5{ + status = "okay"; +}; + +&sata6 { + status = "okay"; +}; + +&sata_phy6{ + status = "okay"; +}; + +&sata7 { + status = "okay"; +}; + +&sata_phy7{ + status = "okay"; +}; + +&mdio_mux_iproc { + mdio@10 { + gphy0: eth-phy@10 { + reg = <0x10>; + }; + }; +}; + &uart1 { status = "okay"; }; @@ -102,6 +174,12 @@ }; }; +&enet { + phy-mode = "rgmii-id"; + phy-handle = <&gphy0>; + status = "okay"; +}; + &nand { status = "ok"; nandcs@0 { diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts b/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts index 5671669ba348..eb6f08cdbd79 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts +++ b/arch/arm64/boot/dts/broadcom/stingray/bcm958742k.dts @@ -39,6 +39,10 @@ model = "Stingray Combo SVK (BCM958742K)"; }; +&gphy0 { + enet-phy-lane-swap; +}; + &uart2 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts b/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts index 6ebe399fda6a..5084b037320f 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts +++ b/arch/arm64/boot/dts/broadcom/stingray/bcm958742t.dts @@ -38,3 +38,7 @@ compatible = "brcm,bcm958742t", "brcm,stingray"; model = "Stingray SST100 (BCM958742T)"; }; + +&gphy0 { + enet-phy-lane-swap; +}; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-fs4.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-fs4.dtsi new file mode 100644 index 000000000000..8bf1dc6b46ca --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-fs4.dtsi @@ -0,0 +1,118 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2016-2017 Broadcom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + fs4: fs4 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x67000000 0x00800000>; + + crypto_mbox: crypto_mbox@00000000 { + compatible = "brcm,iproc-flexrm-mbox"; + reg = <0x00000000 0x200000>; + msi-parent = <&gic_its 0x4100>; + #mbox-cells = <3>; + dma-coherent; + }; + + raid_mbox: raid_mbox@00400000 { + compatible = "brcm,iproc-flexrm-mbox"; + reg = <0x00400000 0x200000>; + dma-coherent; + msi-parent = <&gic_its 0x4300>; + #mbox-cells = <3>; + }; + + raid0: raid@0 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 0 0x1 0xff00>, + <&raid_mbox 1 0x1 0xff00>, + <&raid_mbox 2 0x1 0xff00>, + <&raid_mbox 3 0x1 0xff00>; + }; + + raid1: raid@1 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 4 0x1 0xff00>, + <&raid_mbox 5 0x1 0xff00>, + <&raid_mbox 6 0x1 0xff00>, + <&raid_mbox 7 0x1 0xff00>; + }; + + raid2: raid@2 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 8 0x1 0xff00>, + <&raid_mbox 9 0x1 0xff00>, + <&raid_mbox 10 0x1 0xff00>, + <&raid_mbox 11 0x1 0xff00>; + }; + + raid3: raid@3 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 12 0x1 0xff00>, + <&raid_mbox 13 0x1 0xff00>, + <&raid_mbox 14 0x1 0xff00>, + <&raid_mbox 15 0x1 0xff00>; + }; + + raid4: raid@4 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 16 0x1 0xff00>, + <&raid_mbox 17 0x1 0xff00>, + <&raid_mbox 18 0x1 0xff00>, + <&raid_mbox 19 0x1 0xff00>; + }; + + raid5: raid@5 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 20 0x1 0xff00>, + <&raid_mbox 21 0x1 0xff00>, + <&raid_mbox 22 0x1 0xff00>, + <&raid_mbox 23 0x1 0xff00>; + }; + + raid6: raid@6 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 24 0x1 0xff00>, + <&raid_mbox 25 0x1 0xff00>, + <&raid_mbox 26 0x1 0xff00>, + <&raid_mbox 27 0x1 0xff00>; + }; + + raid7: raid@7 { + compatible = "brcm,iproc-sba-v2"; + mboxes = <&raid_mbox 28 0x1 0xff00>, + <&raid_mbox 29 0x1 0xff00>, + <&raid_mbox 30 0x1 0xff00>, + <&raid_mbox 31 0x1 0xff00>; + }; + }; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi new file mode 100644 index 000000000000..a774709388df --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi @@ -0,0 +1,278 @@ +/* + * BSD LICENSE + * + * Copyright(c) 2016-2017 Broadcom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Broadcom nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + sata { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x67d00000 0x00800000>; + + sata0: ahci@00210000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00210000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata0_port0: sata-port@0 { + reg = <0>; + phys = <&sata0_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy0: sata_phy@00212100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00212100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata0_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata1: ahci@00310000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00310000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata1_port0: sata-port@0 { + reg = <0>; + phys = <&sata1_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy1: sata_phy@00312100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00312100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata1_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata2: ahci@00120000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00120000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata2_port0: sata-port@0 { + reg = <0>; + phys = <&sata2_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy2: sata_phy@00122100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00122100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata2_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata3: ahci@00130000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00130000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata3_port0: sata-port@0 { + reg = <0>; + phys = <&sata3_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy3: sata_phy@00132100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00132100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata3_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata4: ahci@00330000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00330000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata4_port0: sata-port@0 { + reg = <0>; + phys = <&sata4_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy4: sata_phy@00332100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00332100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata4_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata5: ahci@00400000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00400000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata5_port0: sata-port@0 { + reg = <0>; + phys = <&sata5_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy5: sata_phy@00402100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00402100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata5_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata6: ahci@00410000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00410000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata6_port0: sata-port@0 { + reg = <0>; + phys = <&sata6_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy6: sata_phy@00412100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00412100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata6_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + + sata7: ahci@00420000 { + compatible = "brcm,iproc-ahci", "generic-ahci"; + reg = <0x00420000 0x1000>; + reg-names = "ahci"; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata7_port0: sata-port@0 { + reg = <0>; + phys = <&sata7_phy0>; + phy-names = "sata-phy"; + }; + }; + + sata_phy7: sata_phy@00422100 { + compatible = "brcm,iproc-sr-sata-phy"; + reg = <0x00422100 0x1000>; + reg-names = "phy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + sata7_phy0: sata-phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + }; + }; diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi index 49933cf16c92..e6f75c633623 100644 --- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi +++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi @@ -152,6 +152,12 @@ #size-cells = <1>; ranges = <0x0 0x0 0x61000000 0x05000000>; + ccn: ccn@00000000 { + compatible = "arm,ccn-502"; + reg = <0x00000000 0x900000>; + interrupts = ; + }; + gic: interrupt-controller@02c00000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; @@ -261,6 +267,9 @@ }; }; + #include "stingray-fs4.dtsi" + #include "stingray-sata.dtsi" + hsls { compatible = "simple-bus"; #address-cells = <1>; @@ -269,6 +278,37 @@ #include "stingray-pinctrl.dtsi" + mdio_mux_iproc: mdio-mux@0002023c { + compatible = "brcm,mdio-mux-iproc"; + reg = <0x0002023c 0x14>; + #address-cells = <1>; + #size-cells = <0>; + + mdio@0 { /* PCIe serdes */ + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@2 { /* SATA */ + reg = <0x2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@3 { /* USB */ + reg = <0x3>; + #address-cells = <1>; + #size-cells = <0>; + }; + + mdio@10 { /* RGMII */ + reg = <0x10>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + pwm: pwm@00010000 { compatible = "brcm,iproc-pwm"; reg = <0x00010000 0x1000>; @@ -277,6 +317,93 @@ status = "disabled"; }; + timer0: timer@00030000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00030000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer1: timer@00040000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00040000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer2: timer@00050000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00050000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer3: timer@00060000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00060000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer4: timer@00070000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00070000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer5: timer@00080000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00080000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer6: timer@00090000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x00090000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + + timer7: timer@000a0000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x000a0000 0x1000>; + interrupts = ; + clocks = <&hsls_25m_div2_clk>, + <&hsls_25m_div2_clk>, + <&hsls_div4_clk>; + clock-names = "timer1", "timer2", "apb_pclk"; + status = "disabled"; + }; + i2c0: i2c@000b0000 { compatible = "brcm,iproc-i2c"; reg = <0x000b0000 0x100>; @@ -424,6 +551,15 @@ iommus = <&smmu 0x6000 0x0000>; }; + enet: ethernet@00340000{ + compatible = "brcm,amac"; + reg = <0x00340000 0x1000>; + reg-names = "amac_base"; + dma-coherent; + interrupts = ; + status= "disabled"; + }; + nand: nand@00360000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x00360000 0x600>, diff --git a/arch/arm64/boot/dts/cavium/Makefile b/arch/arm64/boot/dts/cavium/Makefile index 581b2c1c400a..9f68c277302b 100644 --- a/arch/arm64/boot/dts/cavium/Makefile +++ b/arch/arm64/boot/dts/cavium/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb dtb-$(CONFIG_ARCH_THUNDER2) += thunder2-99xx.dtb diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile index 7ddea53769a7..6914b2cbd397 100644 --- a/arch/arm64/boot/dts/exynos/Makefile +++ b/arch/arm64/boot/dts/exynos/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_EXYNOS) += \ exynos5433-tm2.dtb \ exynos5433-tm2e.dtb \ diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index e2b0da2c0bc7..297597442c44 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -280,9 +280,6 @@ &decon { status = "okay"; - - i80-if-timings { - }; }; &decon_tv { @@ -310,20 +307,6 @@ samsung,pll-clock-frequency = <24000000>; pinctrl-names = "default"; pinctrl-0 = <&te_irq>; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@1 { - reg = <1>; - - dsi_out: endpoint { - samsung,burst-clock-frequency = <512000000>; - samsung,esc-clock-frequency = <16000000>; - }; - }; - }; }; &hdmi { @@ -846,7 +829,6 @@ &mshc_0 { status = "okay"; - num-slots = <1>; mmc-hs200-1_8v; mmc-hs400-1_8v; cap-mmc-highspeed; @@ -868,7 +850,6 @@ &mshc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; disable-wp; cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>; @@ -1116,9 +1097,6 @@ &mic { status = "okay"; - - i80-if-timings { - }; }; &pmu_system_controller { @@ -1216,8 +1194,9 @@ status = "okay"; }; -&usbdrd_dwc3_0 { +&usbdrd_dwc3 { dr_mode = "otg"; + extcon = <&muic>; }; &usbdrd30_phy { diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index 727f36abf3d4..7fe994b750da 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -1367,7 +1367,7 @@ ranges; status = "disabled"; - dwc3@15400000 { + usbdrd_dwc3: dwc3@15400000 { compatible = "snps,dwc3"; reg = <0x15400000 0x10000>; interrupts = ; @@ -1414,7 +1414,7 @@ ranges; status = "disabled"; - usbdrd_dwc3_0: dwc3@15a00000 { + usbhost_dwc3: dwc3@15a00000 { compatible = "snps,dwc3"; reg = <0x15a00000 0x10000>; interrupts = ; diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts index e5892bb0ae6e..4a8b1fb51243 100644 --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts @@ -359,7 +359,6 @@ &mmc_0 { status = "okay"; - num-slots = <1>; cap-mmc-highspeed; mmc-hs200-1_8v; non-removable; @@ -375,7 +374,6 @@ &mmc_2 { status = "okay"; - num-slots = <1>; cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile index 72c4b525726f..dc02e82aba7c 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-qds.dtb dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-rdb.dtb diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi index b1554cbd2c54..df83915d6ea6 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -444,6 +444,15 @@ <&clockgen 4 3>; }; + usb0: usb3@2f00000 { + compatible = "snps,dwc3"; + reg = <0x0 0x2f00000 0x0 0x10000>; + interrupts = <0 60 0x4>; + dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; + snps,dis_rxdet_inp3_quirk; + }; + sata: sata@3200000 { compatible = "fsl,ls1012a-ahci", "fsl,ls1043a-ahci"; reg = <0x0 0x3200000 0x0 0x10000>, @@ -454,5 +463,13 @@ dma-coherent; status = "disabled"; }; + + usb1: usb2@8600000 { + compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr"; + reg = <0x0 0x8600000 0x0 0x1000>; + interrupts = <0 139 0x4>; + dr_mode = "host"; + phy_type = "ulpi"; + }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 31fd77f82ced..d16b9cc1e825 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -653,21 +653,21 @@ }; msi1: msi-controller1@1571000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1571000 0x0 0x8>; msi-controller; interrupts = <0 116 0x4>; }; msi2: msi-controller2@1572000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1572000 0x0 0x8>; msi-controller; interrupts = <0 126 0x4>; }; msi3: msi-controller3@1573000 { - compatible = "fsl,1s1043a-msi"; + compatible = "fsl,ls1043a-msi"; reg = <0x0 0x1573000 0x0 0x8>; msi-controller; interrupts = <0 160 0x4>; @@ -689,7 +689,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi1>; + msi-parent = <&msi1>, <&msi2>, <&msi3>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic 0 110 0x4>, @@ -714,7 +714,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi2>; + msi-parent = <&msi1>, <&msi2>, <&msi3>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic 0 120 0x4>, @@ -739,7 +739,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000 /* downstream I/O */ 0x82000000 0x0 0x40000000 0x50 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&msi3>; + msi-parent = <&msi1>, <&msi2>, <&msi3>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; interrupt-map = <0000 0 0 1 &gic 0 154 0x4>, diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi index dc1640be0345..c8ff0baddf1d 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -630,6 +630,37 @@ interrupts = ; clocks = <&clockgen 4 1>; }; + + msi1: msi-controller@1580000 { + compatible = "fsl,ls1046a-msi"; + msi-controller; + reg = <0x0 0x1580000 0x0 0x10000>; + interrupts = , + , + , + ; + }; + + msi2: msi-controller@1590000 { + compatible = "fsl,ls1046a-msi"; + msi-controller; + reg = <0x0 0x1590000 0x0 0x10000>; + interrupts = , + , + , + ; + }; + + msi3: msi-controller@15a0000 { + compatible = "fsl,ls1046a-msi"; + msi-controller; + reg = <0x0 0x15a0000 0x0 0x10000>; + interrupts = , + , + , + ; + }; + }; reserved-memory { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts index 213abb72de93..0f6fcda36b9e 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts @@ -49,7 +49,7 @@ #include "fsl-ls1088a.dtsi" / { - model = "L1088A RDB Board"; + model = "LS1088A RDB Board"; compatible = "fsl,ls1088a-rdb", "fsl,ls1088a"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index c144d06a6e33..33797b373674 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -52,6 +52,10 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + crypto = &crypto; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -62,6 +66,7 @@ compatible = "arm,cortex-a53"; reg = <0x0>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; #cooling-cells = <2>; }; @@ -70,6 +75,7 @@ compatible = "arm,cortex-a53"; reg = <0x1>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; }; cpu2: cpu@2 { @@ -77,6 +83,7 @@ compatible = "arm,cortex-a53"; reg = <0x2>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; }; cpu3: cpu@3 { @@ -84,6 +91,7 @@ compatible = "arm,cortex-a53"; reg = <0x3>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PH20>; }; cpu4: cpu@100 { @@ -91,6 +99,7 @@ compatible = "arm,cortex-a53"; reg = <0x100>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; #cooling-cells = <2>; }; @@ -99,6 +108,7 @@ compatible = "arm,cortex-a53"; reg = <0x101>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; }; cpu6: cpu@102 { @@ -106,6 +116,7 @@ compatible = "arm,cortex-a53"; reg = <0x102>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; }; cpu7: cpu@103 { @@ -113,6 +124,16 @@ compatible = "arm,cortex-a53"; reg = <0x103>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PH20>; + }; + + CPU_PH20: cpu-ph20 { + compatible = "arm,idle-state"; + idle-state-name = "PH20"; + arm,psci-suspend-param = <0x00010000>; + entry-latency-us = <1000>; + exit-latency-us = <1000>; + min-residency-us = <3000>; }; }; @@ -136,6 +157,11 @@ <1 10 IRQ_TYPE_LEVEL_LOW>;/* Hypervisor PPI */ }; + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + sysclk: sysclk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -369,6 +395,45 @@ dma-coherent; status = "disabled"; }; + + crypto: crypto@8000000 { + compatible = "fsl,sec-v5.0", "fsl,sec-v4.0"; + fsl,sec-era = <8>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x00 0x8000000 0x100000>; + reg = <0x00 0x8000000 0x0 0x100000>; + interrupts = ; + dma-coherent; + + sec_jr0: jr@10000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x10000 0x10000>; + interrupts = ; + }; + + sec_jr1: jr@20000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x20000 0x10000>; + interrupts = ; + }; + + sec_jr2: jr@30000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x30000 0x10000>; + interrupts = ; + }; + + sec_jr3: jr@40000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x40000 0x10000>; + interrupts = ; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts index ed209cd57283..3c99608b9b45 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts @@ -55,11 +55,6 @@ model = "Freescale Layerscape 2080a QDS Board"; compatible = "fsl,ls2080a-qds", "fsl,ls2080a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts index 67ec3f9c81a1..a4e7de9f70d8 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts @@ -55,11 +55,6 @@ model = "Freescale Layerscape 2080a RDB Board"; compatible = "fsl,ls2080a-rdb", "fsl,ls2080a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial1:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts index 3ee718f0aaf8..fbbb73e571c0 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-simu.dts @@ -52,11 +52,6 @@ model = "Freescale Layerscape 2080a software Simulator model"; compatible = "fsl,ls2080a-simu", "fsl,ls2080a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - ethernet@2210000 { compatible = "smsc,lan91c111"; reg = <0x0 0x2210000 0x0 0x100>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index d789c6814e6a..8d739301e7b8 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -53,6 +53,7 @@ compatible = "arm,cortex-a57"; reg = <0x0>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; #cooling-cells = <2>; }; @@ -62,6 +63,7 @@ compatible = "arm,cortex-a57"; reg = <0x1>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; }; @@ -70,6 +72,7 @@ compatible = "arm,cortex-a57"; reg = <0x100>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; #cooling-cells = <2>; }; @@ -79,6 +82,7 @@ compatible = "arm,cortex-a57"; reg = <0x101>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; }; @@ -87,6 +91,7 @@ compatible = "arm,cortex-a57"; reg = <0x200>; clocks = <&clockgen 1 2>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster2_l2>; #cooling-cells = <2>; }; @@ -96,6 +101,7 @@ compatible = "arm,cortex-a57"; reg = <0x201>; clocks = <&clockgen 1 2>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster2_l2>; }; @@ -105,6 +111,7 @@ reg = <0x300>; clocks = <&clockgen 1 3>; next-level-cache = <&cluster3_l2>; + cpu-idle-states = <&CPU_PW20>; #cooling-cells = <2>; }; @@ -113,6 +120,7 @@ compatible = "arm,cortex-a57"; reg = <0x301>; clocks = <&clockgen 1 3>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster3_l2>; }; @@ -131,6 +139,15 @@ cluster3_l2: l2-cache3 { compatible = "cache"; }; + + CPU_PW20: cpu-pw20 { + compatible = "arm,idle-state"; + idle-state-name = "PW20"; + arm,psci-suspend-param = <0x00010000>; + entry-latency-us = <2000>; + exit-latency-us = <2000>; + min-residency-us = <6000>; + }; }; &pcie1 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts index 4a1df5ce3229..eaee5b1c3a44 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts @@ -54,11 +54,6 @@ model = "Freescale Layerscape 2088A QDS Board"; compatible = "fsl,ls2088a-qds", "fsl,ls2088a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts index a76d4b4debd1..c411442cac62 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts @@ -54,11 +54,6 @@ model = "Freescale Layerscape 2088A RDB Board"; compatible = "fsl,ls2088a-rdb", "fsl,ls2088a"; - aliases { - serial0 = &serial0; - serial1 = &serial1; - }; - chosen { stdout-path = "serial1:115200n8"; }; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi index 5c695c658056..6aa319dae396 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi @@ -53,6 +53,7 @@ compatible = "arm,cortex-a72"; reg = <0x0>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; #cooling-cells = <2>; }; @@ -62,6 +63,7 @@ compatible = "arm,cortex-a72"; reg = <0x1>; clocks = <&clockgen 1 0>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster0_l2>; }; @@ -70,6 +72,7 @@ compatible = "arm,cortex-a72"; reg = <0x100>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; #cooling-cells = <2>; }; @@ -79,6 +82,7 @@ compatible = "arm,cortex-a72"; reg = <0x101>; clocks = <&clockgen 1 1>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster1_l2>; }; @@ -88,6 +92,7 @@ reg = <0x200>; clocks = <&clockgen 1 2>; next-level-cache = <&cluster2_l2>; + cpu-idle-states = <&CPU_PW20>; #cooling-cells = <2>; }; @@ -96,6 +101,7 @@ compatible = "arm,cortex-a72"; reg = <0x201>; clocks = <&clockgen 1 2>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster2_l2>; }; @@ -104,6 +110,7 @@ compatible = "arm,cortex-a72"; reg = <0x300>; clocks = <&clockgen 1 3>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster3_l2>; #cooling-cells = <2>; }; @@ -113,6 +120,7 @@ compatible = "arm,cortex-a72"; reg = <0x301>; clocks = <&clockgen 1 3>; + cpu-idle-states = <&CPU_PW20>; next-level-cache = <&cluster3_l2>; }; @@ -131,6 +139,15 @@ cluster3_l2: l2-cache3 { compatible = "cache"; }; + + CPU_PW20: cpu-pw20 { + compatible = "arm,idle-state"; + idle-state-name = "PW20"; + arm,psci-suspend-param = <0x00010000>; + entry-latency-us = <2000>; + exit-latency-us = <2000>; + min-residency-us = <6000>; + }; }; &pcie1 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 94cdd3045037..4fb9a0966a84 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -46,6 +46,7 @@ */ #include +#include / { compatible = "fsl,ls2080a"; @@ -53,6 +54,12 @@ #address-cells = <2>; #size-cells = <2>; + aliases { + crypto = &crypto; + serial0 = &serial0; + serial1 = &serial1; + }; + cpu: cpus { #address-cells = <1>; #size-cells = <0>; @@ -118,6 +125,11 @@ interrupts = <1 7 0x8>; /* PMU PPI, Level low type */ }; + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; @@ -301,6 +313,45 @@ clock-names = "apb_pclk", "wdog_clk"; }; + crypto: crypto@8000000 { + compatible = "fsl,sec-v5.0", "fsl,sec-v4.0"; + fsl,sec-era = <8>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x00 0x8000000 0x100000>; + reg = <0x00 0x8000000 0x0 0x100000>; + interrupts = ; + dma-coherent; + + sec_jr0: jr@10000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x10000 0x10000>; + interrupts = ; + }; + + sec_jr1: jr@20000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x20000 0x10000>; + interrupts = ; + }; + + sec_jr2: jr@30000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x30000 0x10000>; + interrupts = ; + }; + + sec_jr3: jr@40000 { + compatible = "fsl,sec-v5.0-job-ring", + "fsl,sec-v4.0-job-ring"; + reg = <0x40000 0x10000>; + interrupts = ; + }; + }; + fsl_mc: fsl-mc@80c000000 { compatible = "fsl,qoriq-mc"; reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */ diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile index 8960ecafd37d..521ed484a5d1 100644 --- a/arch/arm64/boot/dts/hisilicon/Makefile +++ b/arch/arm64/boot/dts/hisilicon/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_HISI) += hi3660-hikey960.dtb dtb-$(CONFIG_ARCH_HISI) += hi3798cv200-poplar.dtb dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb diff --git a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts index 6609b0fe7a8b..e9f87cb61ade 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts +++ b/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for Hisilicon HiKey960 Development Board * @@ -39,6 +40,34 @@ reg = <0x0 0x0 0x0 0x0>; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + ramoops@32000000 { + compatible = "ramoops"; + reg = <0x0 0x32000000 0x0 0x00100000>; + record-size = <0x00020000>; + console-size = <0x00020000>; + ftrace-size = <0x00020000>; + }; + }; + + reboot-mode-syscon@32100000 { + compatible = "syscon", "simple-mfd"; + reg = <0x0 0x32100000 0x0 0x00001000>; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x0>; + + mode-normal = <0x77665501>; + mode-bootloader = <0x77665500>; + mode-recovery = <0x77665502>; + }; + }; + keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -159,6 +188,13 @@ startup-delay-us = <70000>; enable-active-high; }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; }; &i2c0 { @@ -195,7 +231,7 @@ bluetooth { compatible = "ti,wl1837-st"; enable-gpios = <&gpio15 6 GPIO_ACTIVE_HIGH>; - max-speed = <921600>; + max-speed = <3000000>; }; }; diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index c6a1961e8d55..13ae69f5a327 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for Hisilicon Hi3660 SoC * @@ -58,6 +59,8 @@ device_type = "cpu"; reg = <0x0 0x0>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu1: cpu@1 { @@ -65,6 +68,8 @@ device_type = "cpu"; reg = <0x0 0x1>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu2: cpu@2 { @@ -72,6 +77,8 @@ device_type = "cpu"; reg = <0x0 0x2>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu3: cpu@3 { @@ -79,6 +86,8 @@ device_type = "cpu"; reg = <0x0 0x3>; enable-method = "psci"; + next-level-cache = <&A53_L2>; + cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP_0>; }; cpu4: cpu@100 { @@ -86,6 +95,12 @@ device_type = "cpu"; reg = <0x0 0x100>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; }; cpu5: cpu@101 { @@ -93,6 +108,12 @@ device_type = "cpu"; reg = <0x0 0x101>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; }; cpu6: cpu@102 { @@ -100,6 +121,12 @@ device_type = "cpu"; reg = <0x0 0x102>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; }; cpu7: cpu@103 { @@ -107,6 +134,59 @@ device_type = "cpu"; reg = <0x0 0x103>; enable-method = "psci"; + next-level-cache = <&A73_L2>; + cpu-idle-states = < + &CPU_NAP + &CPU_SLEEP + &CLUSTER_SLEEP_1 + >; + }; + + idle-states { + entry-method = "psci"; + + CPU_NAP: cpu-nap { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0000001>; + entry-latency-us = <7>; + exit-latency-us = <2>; + min-residency-us = <15>; + }; + + CPU_SLEEP: cpu-sleep { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x0010000>; + entry-latency-us = <40>; + exit-latency-us = <70>; + min-residency-us = <3000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <500>; + exit-latency-us = <5000>; + min-residency-us = <20000>; + }; + + CLUSTER_SLEEP_1: cluster-sleep-1 { + compatible = "arm,idle-state"; + local-timer-stop; + arm,psci-suspend-param = <0x1010000>; + entry-latency-us = <1000>; + exit-latency-us = <5000>; + min-residency-us = <20000>; + }; + }; + + A53_L2: l2-cache0 { + compatible = "cache"; + }; + + A73_L2: l2-cache1 { + compatible = "cache"; }; }; @@ -123,6 +203,26 @@ IRQ_TYPE_LEVEL_HIGH)>; }; + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = , + , + , + , + , + , + , + ; + interrupt-affinity = <&cpu0>, + <&cpu1>, + <&cpu2>, + <&cpu3>, + <&cpu4>, + <&cpu5>, + <&cpu6>, + <&cpu7>; + }; + timer { compatible = "arm,armv8-timer"; interrupt-parent = <&gic>; @@ -337,6 +437,19 @@ status = "disabled"; }; + dma0: dma@fdf30000 { + compatible = "hisilicon,k3-dma-1.0"; + reg = <0x0 0xfdf30000 0x0 0x1000>; + #dma-cells = <1>; + dma-channels = <16>; + dma-requests = <32>; + dma-min-chan = <1>; + interrupts = ; + clocks = <&crg_ctrl HI3660_CLK_GATE_DMAC>; + dma-no-cci; + dma-type = "hi3660_dma"; + }; + rtc0: rtc@fff04000 { compatible = "arm,pl031", "arm,primecell"; reg = <0x0 0Xfff04000 0x0 0x1000>; @@ -810,6 +923,7 @@ clock-names = "ciu", "biu"; clock-frequency = <3200000>; resets = <&crg_rst 0x94 18>; + reset-names = "reset"; cd-gpios = <&gpio25 3 0>; hisilicon,peripheral-syscon = <&sctrl>; pinctrl-names = "default"; @@ -839,6 +953,7 @@ <&crg_ctrl HI3660_HCLK_GATE_SDIO0>; clock-names = "ciu", "biu"; resets = <&crg_rst 0x94 20>; + reset-names = "reset"; card-detect-delay = <200>; supports-highspeed; keep-power-in-suspend; @@ -848,5 +963,21 @@ &sdio_cfg_func>; status = "disabled"; }; + + watchdog0: watchdog@e8a06000 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xe8a06000 0x0 0x1000>; + interrupts = ; + clocks = <&crg_ctrl HI3660_OSC32K>; + clock-names = "apb_pclk"; + }; + + watchdog1: watchdog@e8a07000 { + compatible = "arm,sp805-wdt", "arm,primecell"; + reg = <0x0 0xe8a07000 0x0 0x1000>; + interrupts = ; + clocks = <&crg_ctrl HI3660_OSC32K>; + clock-names = "apb_pclk"; + }; }; }; diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts index 2b526304ed27..3aee6123d161 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for Hisilicon HiKey Development Board * diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index eacbe0db5bc2..ff1dc89f599e 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for Hisilicon Hi6220 SoC * @@ -262,6 +263,12 @@ #clock-cells = <1>; }; + acpu_sctrl: acpu_sctrl@f6504000 { + compatible = "hisilicon,hi6220-acpu-sctrl", "syscon"; + reg = <0x0 0xf6504000 0x0 0x1000>; + #clock-cells = <1>; + }; + medianoc_ade: medianoc_ade@f4520000 { compatible = "syscon"; reg = <0x0 0xf4520000 0x0 0x4000>; @@ -755,7 +762,8 @@ dr_mode = "otg"; g-rx-fifo-size = <512>; g-np-tx-fifo-size = <128>; - g-tx-fifo-size = <128 128 128 128 128 128>; + g-tx-fifo-size = <128 128 128 128 128 128 128 128 + 16 16 16 16 16 16 16>; interrupts = <0 77 0x4>; }; diff --git a/arch/arm64/boot/dts/hisilicon/hikey-pinctrl.dtsi b/arch/arm64/boot/dts/hisilicon/hikey-pinctrl.dtsi index 0916e8459d6b..e7d22619a4c0 100644 --- a/arch/arm64/boot/dts/hisilicon/hikey-pinctrl.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hikey-pinctrl.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * pinctrl dts fils for Hislicon HiKey development board * diff --git a/arch/arm64/boot/dts/hisilicon/hikey960-pinctrl.dtsi b/arch/arm64/boot/dts/hisilicon/hikey960-pinctrl.dtsi index 7e542d28dadb..d11efc81958c 100644 --- a/arch/arm64/boot/dts/hisilicon/hikey960-pinctrl.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hikey960-pinctrl.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * pinctrl dts fils for Hislicon HiKey960 development board * diff --git a/arch/arm64/boot/dts/hisilicon/hip07-d05.dts b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts index f5d7f0889b41..fe7c16c36025 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07-d05.dts +++ b/arch/arm64/boot/dts/hisilicon/hip07-d05.dts @@ -84,3 +84,7 @@ &sas1 { status = "ok"; }; + +&p0_pcie2_a { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi index 283d7b532e16..2c01a21c3665 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi @@ -1534,5 +1534,27 @@ <637 1>,<638 1>,<639 1>; status = "disabled"; }; + + p0_pcie2_a: pcie@a00a0000 { + compatible = "hisilicon,hip07-pcie-ecam"; + reg = <0 0xaf800000 0 0x800000>, + <0 0xa00a0000 0 0x10000>; + bus-range = <0xf8 0xff>; + msi-map = <0xf800 &p0_its_dsa_a 0xf800 0x800>; + msi-map-mask = <0xffff>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + dma-coherent; + ranges = <0x02000000 0 0xa8000000 0 0xa8000000 0 0x77f0000 + 0x01000000 0 0 0 0xaf7f0000 0 0x10000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0x0 0 0 1 &mbigen_pcie2_a 671 4 + 0x0 0 0 2 &mbigen_pcie2_a 671 4 + 0x0 0 0 3 &mbigen_pcie2_a 671 4 + 0x0 0 0 4 &mbigen_pcie2_a 671 4>; + status = "disabled"; + }; }; }; diff --git a/arch/arm64/boot/dts/lg/Makefile b/arch/arm64/boot/dts/lg/Makefile index 5c7b54c12adc..e345b8e58efe 100644 --- a/arch/arm64/boot/dts/lg/Makefile +++ b/arch/arm64/boot/dts/lg/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_LG1K) += lg1312-ref.dtb dtb-$(CONFIG_ARCH_LG1K) += lg1313-ref.dtb diff --git a/arch/arm64/boot/dts/lg/lg1312-ref.dts b/arch/arm64/boot/dts/lg/lg1312-ref.dts index 6d78d6bc7f9c..260a2c5b19e5 100644 --- a/arch/arm64/boot/dts/lg/lg1312-ref.dts +++ b/arch/arm64/boot/dts/lg/lg1312-ref.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for lg1312 Reference Board. * diff --git a/arch/arm64/boot/dts/lg/lg1312.dtsi b/arch/arm64/boot/dts/lg/lg1312.dtsi index fbafa24cd533..860c8fb10795 100644 --- a/arch/arm64/boot/dts/lg/lg1312.dtsi +++ b/arch/arm64/boot/dts/lg/lg1312.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for lg1312 SoC * diff --git a/arch/arm64/boot/dts/lg/lg1313-ref.dts b/arch/arm64/boot/dts/lg/lg1313-ref.dts index df0ece43cfbf..e89ae853788a 100644 --- a/arch/arm64/boot/dts/lg/lg1313-ref.dts +++ b/arch/arm64/boot/dts/lg/lg1313-ref.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for lg1313 Reference Board. * diff --git a/arch/arm64/boot/dts/lg/lg1313.dtsi b/arch/arm64/boot/dts/lg/lg1313.dtsi index e703e1149c75..1887af654a7d 100644 --- a/arch/arm64/boot/dts/lg/lg1313.dtsi +++ b/arch/arm64/boot/dts/lg/lg1313.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dts file for lg1313 SoC * diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile index 3e6ce6c15a74..5633676fa9d0 100644 --- a/arch/arm64/boot/dts/marvell/Makefile +++ b/arch/arm64/boot/dts/marvell/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Berlin SoC Family dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-dmp.dtb dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb @@ -8,6 +9,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-espressobin.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-7040-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-db.dtb dtb-$(CONFIG_ARCH_MVEBU) += armada-8040-mcbin.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-8080-db.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts index e3a136ed77b0..2ce52ba74f73 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts @@ -45,6 +45,7 @@ /dts-v1/; +#include #include "armada-372x.dtsi" / { @@ -59,6 +60,20 @@ device_type = "memory"; reg = <0x00000000 0x00000000 0x00000000 0x20000000>; }; + + vcc_sd_reg1: regulator { + compatible = "regulator-gpio"; + regulator-name = "vcc_sd1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + states = <1800000 0x1 + 3300000 0x0>; + enable-active-high; + }; }; /* J9 */ @@ -71,6 +86,16 @@ status = "okay"; }; +/* J1 */ +&sdhci1 { + wp-inverted; + bus-width = <4>; + cd-gpios = <&gpionb 3 GPIO_ACTIVE_LOW>; + marvell,pad-type = "sd"; + vqmmc-supply = <&vcc_sd_reg1>; + status = "okay"; +}; + /* Exported on the micro USB connector J5 through an FTDI */ &uart0 { status = "okay"; @@ -81,6 +106,11 @@ status = "okay"; }; +/* J8 */ +&usb2 { + status = "okay"; +}; + &mdio { switch0: switch0@1 { compatible = "marvell,mv88e6085"; diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi index 51763d674050..8c0cf7efac65 100644 --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -81,6 +81,11 @@ ; }; + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; @@ -322,7 +327,11 @@ #interrupt-cells = <3>; interrupt-controller; reg = <0x1d00000 0x10000>, /* GICD */ - <0x1d40000 0x40000>; /* GICR */ + <0x1d40000 0x40000>, /* GICR */ + <0x1d80000 0x2000>, /* GICC */ + <0x1d90000 0x2000>, /* GICH */ + <0x1da0000 0x20000>; /* GICV */ + interrupts = ; }; }; diff --git a/arch/arm64/boot/dts/marvell/armada-7040-db.dts b/arch/arm64/boot/dts/marvell/armada-7040-db.dts index 92c761c380d3..9c3bdf87e543 100644 --- a/arch/arm64/boot/dts/marvell/armada-7040-db.dts +++ b/arch/arm64/boot/dts/marvell/armada-7040-db.dts @@ -44,6 +44,7 @@ * Device Tree file for Marvell Armada 7040 Development board platform */ +#include #include "armada-7040.dtsi" / { @@ -59,6 +60,34 @@ device_type = "memory"; reg = <0x0 0x0 0x0 0x80000000>; }; + + cpm_reg_usb3_0_vbus: cpm-usb3-0-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; + }; + + cpm_reg_usb3_1_vbus: cpm-usb3-1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb3h1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; + }; + + cpm_usb3_0_phy: cpm-usb3-0-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_0_vbus>; + }; + + cpm_usb3_1_phy: cpm-usb3-1-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_1_vbus>; + }; }; &i2c0 { @@ -105,6 +134,14 @@ &cpm_i2c0 { status = "okay"; clock-frequency = <100000>; + + expander0: pca9555@21 { + compatible = "nxp,pca9555"; + pinctrl-names = "default"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x21>; + }; }; &cpm_spi1 { @@ -140,10 +177,12 @@ }; &cpm_usb3_0 { + usb-phy = <&cpm_usb3_0_phy>; status = "okay"; }; &cpm_usb3_1 { + usb-phy = <&cpm_usb3_1_phy>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-db.dts b/arch/arm64/boot/dts/marvell/armada-8040-db.dts index 1e8f7242ed6f..0d7b2ae46610 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-db.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-db.dts @@ -44,6 +44,7 @@ * Device Tree file for Marvell Armada 8040 Development board platform */ +#include #include "armada-8040.dtsi" / { @@ -59,6 +60,48 @@ device_type = "memory"; reg = <0x0 0x0 0x0 0x80000000>; }; + + cpm_reg_usb3_0_vbus: cpm-usb3-0-vbus { + compatible = "regulator-fixed"; + regulator-name = "cpm-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; + }; + + cpm_reg_usb3_1_vbus: cpm-usb3-1-vbus { + compatible = "regulator-fixed"; + regulator-name = "cpm-usb3h1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; + }; + + cpm_usb3_0_phy: cpm-usb3-0-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_0_vbus>; + }; + + cpm_usb3_1_phy: cpm-usb3-1-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cpm_reg_usb3_1_vbus>; + }; + + cps_reg_usb3_0_vbus: cps-usb3-0-vbus { + compatible = "regulator-fixed"; + regulator-name = "cps-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + gpio = <&expander1 0 GPIO_ACTIVE_HIGH>; + }; + + cps_usb3_0_phy: cps-usb3-0-phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <&cps_reg_usb3_0_vbus>; + }; }; &i2c0 { @@ -107,6 +150,25 @@ &cpm_i2c0 { status = "okay"; clock-frequency = <100000>; + + /* U31 */ + expander0: pca9555@21 { + compatible = "nxp,pca9555"; + pinctrl-names = "default"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x21>; + }; + + /* U25 */ + expander1: pca9555@25 { + compatible = "nxp,pca9555"; + pinctrl-names = "default"; + gpio-controller; + #gpio-cells = <2>; + reg = <0x25>; + }; + }; /* CON4 on CP0 expansion */ @@ -116,11 +178,13 @@ /* CON9 on CP0 expansion */ &cpm_usb3_0 { + usb-phy = <&cpm_usb3_0_phy>; status = "okay"; }; /* CON10 on CP0 expansion */ &cpm_usb3_1 { + usb-phy = <&cpm_usb3_1_phy>; status = "okay"; }; @@ -159,6 +223,7 @@ /* CON9 on CP1 expansion */ &cps_usb3_0 { + usb-phy = <&cps_usb3_0_phy>; status = "okay"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts index 4968e731de61..acf5c7d16d79 100644 --- a/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts +++ b/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dts @@ -46,11 +46,17 @@ #include "armada-8040.dtsi" +#include + / { model = "Marvell 8040 MACHIATOBin"; compatible = "marvell,armada8040-mcbin", "marvell,armada8040", "marvell,armada-ap806-quad", "marvell,armada-ap806"; + chosen { + stdout-path = "serial0:115200n8"; + }; + memory@00000000 { device_type = "memory"; reg = <0x0 0x0 0x0 0x80000000>; @@ -77,11 +83,13 @@ v_5v0_usb3_hst_vbus: regulator-usb3-vbus0 { compatible = "regulator-fixed"; + enable-active-high; + gpio = <&cpm_gpio2 15 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_xhci_vbus_pins>; regulator-name = "v_5v0_usb3_hst_vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - /* actually GPIO controlled, but 8k has no GPIO support yet */ - regulator-always-on; status = "okay"; }; @@ -112,10 +120,44 @@ &cpm_i2c0 { clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c0_pins>; status = "okay"; }; +&cpm_i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c1_pins>; + status = "okay"; + + i2c-switch@70 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + + sfpp0_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + sfpp1_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + sfp_1g_i2c: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + }; + }; +}; + &cpm_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_ge_mdio_pins>; status = "okay"; ge_phy: ethernet-phy@0 { @@ -123,6 +165,67 @@ }; }; +&cpm_pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_pcie_pins>; + num-lanes = <4>; + num-viewport = <8>; + reset-gpio = <&cpm_gpio1 20 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&cpm_pinctrl { + cpm_ge_mdio_pins: ge-mdio-pins { + marvell,pins = "mpp32", "mpp34"; + marvell,function = "ge"; + }; + cpm_i2c1_pins: i2c1-pins { + marvell,pins = "mpp35", "mpp36"; + marvell,function = "i2c1"; + }; + cpm_i2c0_pins: i2c0-pins { + marvell,pins = "mpp37", "mpp38"; + marvell,function = "i2c0"; + }; + cpm_xhci_vbus_pins: xhci0-vbus-pins { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + cpm_pcie_pins: pcie-pins { + marvell,pins = "mpp52"; + marvell,function = "gpio"; + }; + cpm_sdhci_pins: sdhci-pins { + marvell,pins = "mpp55", "mpp56", "mpp57", "mpp58", "mpp59", + "mpp60", "mpp61"; + marvell,function = "sdio"; + }; +}; + +&cpm_xmdio { + status = "okay"; + + phy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + + phy8: ethernet-phy@8 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <8>; + }; +}; + +&cpm_ethernet { + status = "okay"; +}; + +&cpm_eth0 { + status = "okay"; + phy = <&phy0>; + phy-mode = "10gbase-kr"; +}; + &cpm_sata0 { /* CPM Lane 0 - U29 */ status = "okay"; @@ -132,6 +235,8 @@ /* U6 */ broken-cd; bus-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&cpm_sdhci_pins>; status = "okay"; vqmmc-supply = <&v_3_3>; }; @@ -150,6 +255,12 @@ status = "okay"; }; +&cps_eth0 { + status = "okay"; + phy = <&phy8>; + phy-mode = "10gbase-kr"; +}; + &cps_eth1 { /* CPS Lane 0 - J5 (Gigabit RJ45) */ status = "okay"; @@ -157,6 +268,13 @@ phy-mode = "sgmii"; }; +&cps_pinctrl { + cps_spi1_pins: spi1-pins { + marvell,pins = "mpp12", "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "spi1"; + }; +}; + &cps_sata0 { /* CPS Lane 1 - U32 */ /* CPS Lane 3 - U31 */ @@ -164,6 +282,8 @@ }; &cps_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cps_spi1_pins>; status = "okay"; spi-flash@0 { diff --git a/arch/arm64/boot/dts/marvell/armada-8080-db.dts b/arch/arm64/boot/dts/marvell/armada-8080-db.dts new file mode 100644 index 000000000000..707af833832b --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8080-db.dts @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada-8080 Development board platform + */ + +#include "armada-8080.dtsi" + +/ { + model = "Marvell 8080 board"; + compatible = "marvell,armada-8080-db", "marvell,armada-8080", + "marvell,armada-ap810-octa", "marvell,armada-ap810"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; + +&uart0_ap0 { + clock-frequency = <384000>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8080.dtsi b/arch/arm64/boot/dts/marvell/armada-8080.dtsi new file mode 100644 index 000000000000..d5535b716735 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8080.dtsi @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada-8080 SoC, made of an AP810 OCTA. + */ + +#include "armada-ap810-ap0-octa-core.dtsi" + +/ { + model = "Marvell 8080 board"; + compatible = "marvell,armada-8080", "marvell,armada-ap810-octa", + "marvell,armada-ap810"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi index 4d360713ed12..30d48ecf46e0 100644 --- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi @@ -254,7 +254,7 @@ ap_syscon: system-controller@6f4000 { compatible = "syscon", "simple-mfd"; - reg = <0x6f4000 0x1000>; + reg = <0x6f4000 0x2000>; ap_clk: clock { compatible = "marvell,ap806-clock"; @@ -265,7 +265,7 @@ compatible = "marvell,ap806-pinctrl"; }; - ap_gpio: gpio { + ap_gpio: gpio@1040 { compatible = "marvell,armada-8k-gpio"; offset = <0x1040>; ngpios = <20>; diff --git a/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi b/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi new file mode 100644 index 000000000000..bf1b22b70384 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap810-ap0-octa-core.dtsi @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP810 OCTA cores. + */ + +#include "armada-ap810-ap0.dtsi" + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "marvell,armada-ap810-octa"; + + cpu@000 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x000>; + enable-method = "psci"; + }; + cpu@001 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x001>; + enable-method = "psci"; + }; + cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x100>; + enable-method = "psci"; + }; + cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x101>; + enable-method = "psci"; + }; + cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x200>; + enable-method = "psci"; + }; + cpu@201 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x201>; + enable-method = "psci"; + }; + cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x300>; + enable-method = "psci"; + }; + cpu@301 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x301>; + enable-method = "psci"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi b/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi new file mode 100644 index 000000000000..7e6f039f0f80 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap810-ap0.dtsi @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2017 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP810. + */ + +#include + +/dts-v1/; + +/ { + model = "Marvell Armada AP810"; + compatible = "marvell,armada-ap810"; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0_ap0; + serial1 = &uart1_ap0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + ap810-ap0 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges; + + config-space@e8000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x0 0x0 0xe8000000 0x4000000>; + interrupt-parent = <&gic>; + + gic: interrupt-controller@3000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <1>; + #size-cells = <1>; + interrupt-controller; + interrupts = ; + ranges; + + reg = <0x3000000 0x10000>, /* GICD */ + <0x3060000 0x100000>, /* GICR */ + <0x00c0000 0x2000>, /* GICC */ + <0x00d0000 0x1000>, /* GICH */ + <0x00e0000 0x2000>; /* GICV */ + + gic_its_ap0: interrupt-controller@3040000 { + compatible = "arm,gic-v3-its"; + msi-controller; + #msi-cells = <1>; + reg = <0x3040000 0x20000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + xor@400000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x400000 0x1000>, + <0x410000 0x1000>; + msi-parent = <&gic_its_ap0 0xa0>; + dma-coherent; + }; + + xor@420000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x420000 0x1000>, + <0x430000 0x1000>; + msi-parent = <&gic_its_ap0 0xa1>; + dma-coherent; + }; + + xor@440000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x440000 0x1000>, + <0x450000 0x1000>; + msi-parent = <&gic_its_ap0 0xa2>; + dma-coherent; + }; + + xor@460000 { + compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; + reg = <0x460000 0x1000>, + <0x470000 0x1000>; + msi-parent = <&gic_its_ap0 0xa3>; + dma-coherent; + }; + + uart0_ap0: serial@512000 { + compatible = "snps,dw-apb-uart"; + reg = <0x512000 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + status = "disabled"; + }; + + uart1_ap0: serial@512100 { + compatible = "snps,dw-apb-uart"; + reg = <0x512100 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi index 4c68605675a8..f2aa2a81de4d 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi @@ -65,25 +65,44 @@ reg = <0x0 0x100000>, <0x129000 0xb000>; clocks = <&cpm_clk 1 3>, <&cpm_clk 1 9>, <&cpm_clk 1 5>; clock-names = "pp_clk", "gop_clk", "mg_clk"; + marvell,system-controller = <&cpm_syscon0>; status = "disabled"; dma-coherent; cpm_eth0: eth0 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <0>; gop-port-id = <0>; status = "disabled"; }; cpm_eth1: eth1 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <1>; gop-port-id = <2>; status = "disabled"; }; cpm_eth2: eth2 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <2>; gop-port-id = <3>; status = "disabled"; @@ -115,6 +134,13 @@ msi-parent = <&gicp>; }; + cpm_rtc: rtc@284000 { + compatible = "marvell,armada-8k-rtc"; + reg = <0x284000 0x20>, <0x284080 0x24>; + reg-names = "rtc", "rtc-soc"; + interrupts = ; + }; + cpm_syscon0: system-controller@440000 { compatible = "syscon", "simple-mfd"; reg = <0x440000 0x1000>; @@ -131,8 +157,12 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cpm_pinctrl 0 0 32>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; - }; cpm_gpio2: gpio@140 { @@ -142,26 +172,15 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cpm_pinctrl 0 32 31>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; }; }; - cpm_rtc: rtc@284000 { - compatible = "marvell,armada-8k-rtc"; - reg = <0x284000 0x20>, <0x284080 0x24>; - reg-names = "rtc", "rtc-soc"; - interrupts = ; - }; - - cpm_sata0: sata@540000 { - compatible = "marvell,armada-8k-ahci", - "generic-ahci"; - reg = <0x540000 0x30000>; - interrupts = ; - clocks = <&cpm_clk 1 15>; - status = "disabled"; - }; - cpm_usb3_0: usb3@500000 { compatible = "marvell,armada-8k-xhci", "generic-xhci"; @@ -182,6 +201,15 @@ status = "disabled"; }; + cpm_sata0: sata@540000 { + compatible = "marvell,armada-8k-ahci", + "generic-ahci"; + reg = <0x540000 0x30000>; + interrupts = ; + clocks = <&cpm_clk 1 15>; + status = "disabled"; + }; + cpm_xor0: xor@6a0000 { compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; reg = <0x6a0000 0x1000>, @@ -240,6 +268,21 @@ status = "disabled"; }; + cpm_nand: nand@720000 { + /* + * Due to the limiation of the pin available + * this controller is only usable on the CPM + * for A7K and on the CPS for A8K. + */ + compatible = "marvell,armada370-nand"; + reg = <0x720000 0x54>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = ; + clocks = <&cpm_clk 1 2>; + status = "disabled"; + }; + cpm_trng: trng@760000 { compatible = "marvell,armada-8k-rng", "inside-secure,safexcel-eip76"; reg = <0x760000 0x7d>; @@ -293,7 +336,7 @@ /* non-prefetchable memory */ 0x82000000 0 0xf6000000 0 0xf6000000 0 0xf00000>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>; interrupts = ; num-lanes = <1>; clocks = <&cpm_clk 1 13>; @@ -319,7 +362,7 @@ /* non-prefetchable memory */ 0x82000000 0 0xf7000000 0 0xf7000000 0 0xf00000>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>; interrupts = ; num-lanes = <1>; @@ -346,7 +389,7 @@ /* non-prefetchable memory */ 0x82000000 0 0xf8000000 0 0xf8000000 0 0xf00000>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>; interrupts = ; num-lanes = <1>; diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi index 923f354b02f0..4fe70323abb3 100644 --- a/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-cp110-slave.dtsi @@ -60,37 +60,49 @@ compatible = "simple-bus"; ranges = <0x0 0x0 0xf4000000 0x2000000>; - cps_rtc: rtc@284000 { - compatible = "marvell,armada-8k-rtc"; - reg = <0x284000 0x20>, <0x284080 0x24>; - reg-names = "rtc", "rtc-soc"; - interrupts = ; - }; - cps_ethernet: ethernet@0 { compatible = "marvell,armada-7k-pp22"; reg = <0x0 0x100000>, <0x129000 0xb000>; clocks = <&cps_clk 1 3>, <&cps_clk 1 9>, <&cps_clk 1 5>; clock-names = "pp_clk", "gop_clk", "mg_clk"; + marvell,system-controller = <&cps_syscon0>; status = "disabled"; dma-coherent; cps_eth0: eth0 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <0>; gop-port-id = <0>; status = "disabled"; }; cps_eth1: eth1 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <1>; gop-port-id = <2>; status = "disabled"; }; cps_eth2: eth2 { - interrupts = ; + interrupts = , + , + , + , + ; + interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2", + "tx-cpu3", "rx-shared"; port-id = <2>; gop-port-id = <3>; status = "disabled"; @@ -122,6 +134,13 @@ msi-parent = <&gicp>; }; + cps_rtc: rtc@284000 { + compatible = "marvell,armada-8k-rtc"; + reg = <0x284000 0x20>, <0x284080 0x24>; + reg-names = "rtc", "rtc-soc"; + interrupts = ; + }; + cps_syscon0: system-controller@440000 { compatible = "syscon", "simple-mfd"; reg = <0x440000 0x1000>; @@ -138,8 +157,12 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cps_pinctrl 0 0 32>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; - }; cps_gpio2: gpio@140 { @@ -149,20 +172,16 @@ gpio-controller; #gpio-cells = <2>; gpio-ranges = <&cps_pinctrl 0 32 31>; + interrupt-controller; + interrupts = , + , + , + ; status = "disabled"; }; }; - cps_sata0: sata@540000 { - compatible = "marvell,armada-8k-ahci", - "generic-ahci"; - reg = <0x540000 0x30000>; - interrupts = ; - clocks = <&cps_clk 1 15>; - status = "disabled"; - }; - cps_usb3_0: usb3@500000 { compatible = "marvell,armada-8k-xhci", "generic-xhci"; @@ -183,6 +202,15 @@ status = "disabled"; }; + cps_sata0: sata@540000 { + compatible = "marvell,armada-8k-ahci", + "generic-ahci"; + reg = <0x540000 0x30000>; + interrupts = ; + clocks = <&cps_clk 1 15>; + status = "disabled"; + }; + cps_xor0: xor@6a0000 { compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; reg = <0x6a0000 0x1000>, @@ -241,6 +269,21 @@ status = "disabled"; }; + cps_nand: nand@720000 { + /* + * Due to the limiation of the pin available + * this controller is only usable on the CPM + * for A7K and on the CPS for A8K. + */ + compatible = "marvell,armada370-nand"; + reg = <0x720000 0x54>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = ; + clocks = <&cps_clk 1 2>; + status = "disabled"; + }; + cps_trng: trng@760000 { compatible = "marvell,armada-8k-rng", "inside-secure,safexcel-eip76"; reg = <0x760000 0x7d>; @@ -292,7 +335,7 @@ /* non-prefetchable memory */ 0x82000000 0 0xfa000000 0 0xfa000000 0 0xf00000>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>; interrupts = ; num-lanes = <1>; clocks = <&cps_clk 1 13>; @@ -318,7 +361,7 @@ /* non-prefetchable memory */ 0x82000000 0 0xfb000000 0 0xfb000000 0 0xf00000>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>; interrupts = ; num-lanes = <1>; @@ -345,7 +388,7 @@ /* non-prefetchable memory */ 0x82000000 0 0xfc000000 0 0xfc000000 0 0xf00000>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>; interrupts = ; num-lanes = <1>; diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile index 015eb072ddef..1d05d1824fa9 100644 --- a/arch/arm64/boot/dts/mediatek/Makefile +++ b/arch/arm64/boot/dts/mediatek/Makefile @@ -1,6 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_MEDIATEK) += mt2712-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6755-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6795-evb.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt6797-evb.dtb +dtb-$(CONFIG_ARCH_MEDIATEK) += mt7622-rfb1.dtb dtb-$(CONFIG_ARCH_MEDIATEK) += mt8173-evb.dtb always := $(dtb-y) diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts new file mode 100644 index 000000000000..8c804df3da4e --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: YT Shen + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include "mt2712e.dtsi" + +/ { + model = "MediaTek MT2712 evaluation board"; + compatible = "mediatek,mt2712-evb", "mediatek,mt2712"; + + aliases { + serial0 = &uart0; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0 0x40000000 0 0x80000000>; + }; + + chosen { + stdout-path = "serial0:921600n8"; + }; +}; + +&uart0 { + status = "okay"; +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi new file mode 100644 index 000000000000..57d0396b7faa --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: YT Shen + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +#include +#include + +/ { + compatible = "mediatek,mt2712"; + interrupt-parent = <&sysirq>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu2>; + }; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a35"; + reg = <0x001>; + enable-method = "psci"; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x200>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + baud_clk: dummy26m { + compatible = "fixed-clock"; + clock-frequency = <26000000>; + #clock-cells = <0>; + }; + + sys_clk: dummyclk { + compatible = "fixed-clock"; + clock-frequency = <26000000>; + #clock-cells = <0>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + uart5: serial@1000f000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x1000f000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + sysirq: interrupt-controller@10220a80 { + compatible = "mediatek,mt2712-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10220a80 0 0x40>; + }; + + gic: interrupt-controller@10510000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0 0x10510000 0 0x10000>, + <0 0x10520000 0 0x20000>, + <0 0x10540000 0 0x20000>, + <0 0x10560000 0 0x20000>; + interrupts = ; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart1: serial@11003000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11003000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11004000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart3: serial@11005000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11005000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; + + uart4: serial@11019000 { + compatible = "mediatek,mt2712-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11019000 0 0x400>; + interrupts = ; + clocks = <&baud_clk>, <&sys_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt6797.dtsi b/arch/arm64/boot/dts/mediatek/mt6797.dtsi index 31088a9f71de..4beaa71107d7 100644 --- a/arch/arm64/boot/dts/mediatek/mt6797.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt6797.dtsi @@ -108,13 +108,6 @@ clock-output-names = "clk26m"; }; - clk32k: oscillator@1 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32000>; - clock-output-names = "clk32k"; - }; - timer { compatible = "arm,armv8-timer"; interrupt-parent = <&gic>; @@ -147,6 +140,11 @@ infracfg = <&infrasys>; }; + watchdog: watchdog@10007000 { + compatible = "mediatek,mt6797-wdt", "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x100>; + }; + apmixedsys: apmixed@1000c000 { compatible = "mediatek,mt6797-apmixedsys"; reg = <0 0x1000c000 0 0x1000>; diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts new file mode 100644 index 000000000000..c08309df2cc7 --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include "mt7622.dtsi" + +/ { + model = "MediaTek MT7622 RFB1 board"; + compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622"; + + chosen { + bootargs = "console=ttyS0,115200n1"; + }; + + memory { + reg = <0 0x40000000 0 0x3F000000>; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi new file mode 100644 index 000000000000..b111fec2ed9d --- /dev/null +++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017 MediaTek Inc. + * Author: Ming Huang + * Sean Wang + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +#include +#include + +/ { + compatible = "mediatek,mt7622"; + interrupt-parent = <&sysirq>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + clock-frequency = <1300000000>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + clock-frequency = <1300000000>; + }; + }; + + uart_clk: dummy25m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + bus_clk: dummy280m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <280000000>; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* 192 KiB reserved for ARM Trusted Firmware (BL31) */ + secmon_reserved: secmon@43000000 { + reg = <0 0x43000000 0 0x30000>; + no-map; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + sysirq: interrupt-controller@10200620 { + compatible = "mediatek,mt7622-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10200620 0 0x20>; + }; + + gic: interrupt-controller@10300000 { + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10310000 0 0x1000>, + <0 0x10320000 0 0x1000>, + <0 0x10340000 0 0x2000>, + <0 0x10360000 0 0x2000>; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt7622-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x400>; + interrupts = ; + clocks = <&uart_clk>, <&bus_clk>; + clock-names = "baud", "bus"; + status = "disabled"; + }; +}; diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile index 18941458cb4d..6bc0c6ab4b7f 100644 --- a/arch/arm64/boot/dts/nvidia/Makefile +++ b/arch/arm64/boot/dts/nvidia/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_TEGRA_132_SOC) += tegra132-norrin.dtb dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-0000.dtb dtb-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210-p2371-2180.dtb diff --git a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts index 759af96a6b49..a0385a386a3f 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts +++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index c2f0f2743578..fa5a7c4bc807 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts index 8daadadec63a..c71d762bf697 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi index cf84d7046ad5..54f418d05e15 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tegra186.dtsi" #include diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 0b0552c9f7dd..a9c3eef6c4e0 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi index 906fb836d241..d10d4430537a 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "tegra210.dtsi" diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts index 1ddd8512e100..21c6d3749bc6 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-0000.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra210-p2530.dtsi" diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts index 7cb95e042117..37e3c46e753f 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "tegra210-p2180.dtsi" diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi index 0ec92578cacb..be6066ff97c9 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2530.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tegra210.dtsi" / { diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts index 576957a55801..e2a347e57215 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2571.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi index e008e3364d2a..6ae292da7294 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2595.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { model = "NVIDIA Tegra210 P2595 I/O board"; compatible = "nvidia,p2595", "nvidia,tegra210"; diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi index e5fc67bf46c2..d67ef4319f3b 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include / { diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts index 7703227f5d1a..43cae4798870 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 29f471e0f22a..9bdf19f2cca7 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index cc0f02d9dd02..e7b25bee3f1e 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -1,5 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb dtb-$(CONFIG_ARCH_QCOM) += apq8096-db820c.dtb +dtb-$(CONFIG_ARCH_QCOM) += ipq8074-hk01.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8916-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-bullhead-rev-101.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8994-angler-rev-101.dtb diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index d94640812194..ec2f0de67993 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -17,6 +18,7 @@ function = PMIC_GPIO_FUNC_NORMAL; power-source = ; input-disable; + output-high; }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi index 185388de914c..21d0822f1ca6 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index bd310ac1967a..1d63e6b879de 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -88,6 +88,8 @@ interrupts = <31 2>; adi,dsi-lanes = <4>; + clocks = <&rpmcc RPM_SMD_BB_CLK2>; + clock-names = "cec"; pd-gpios = <&msmgpio 32 0>; @@ -213,11 +215,14 @@ }; usb@78d9000 { - extcon = <&usb_id>, <&usb_id>; + extcon = <&usb_id>; status = "okay"; adp-disable; hnp-disable; srp-disable; + dr_mode = "host"; + pinctrl-names = "default"; + pinctrl-0 = <&usb_sw_sel_pm>; ulpi { phy { v1p8-supply = <&pm8916_l7>; @@ -337,19 +342,11 @@ usb_id: usb-id { compatible = "linux,extcon-usb-gpio"; - id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; + vbus-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&usb_id_default>; }; - usb-switch { - compatible = "toshiba,tc7usb40mu"; - switch-gpios = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>; - extcon = <&usb_id>; - pinctrl-names = "default"; - pinctrl-0 = <&usb_sw_sel_pm>; - }; - hdmi-out { compatible = "hdmi-connector"; type = "a"; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi index b1142c45fdc9..59b29ddfb6e9 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include &pm8994_gpios { @@ -24,4 +25,28 @@ power-source = ; // 1.8V }; }; + + usb3_vbus_det_gpio: pm8996_gpio22 { + pinconf { + pins = "gpio22"; + function = PMIC_GPIO_FUNC_NORMAL; + input-enable; + bias-pull-down; + qcom,drive-strength = ; + power-source = ; // 1.8V + }; + }; +}; + +&pmi8994_gpios { + usb2_vbus_det_gpio: pmi8996_gpio6 { + pinconf { + pins = "gpio6"; + function = PMIC_GPIO_FUNC_NORMAL; + input-enable; + bias-pull-down; + qcom,drive-strength = ; + power-source = ; // 1.8V + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi index d2196fc6d739..789f3e87321e 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi @@ -13,6 +13,7 @@ #include "msm8996.dtsi" #include "pm8994.dtsi" +#include "pmi8994.dtsi" #include "apq8096-db820c-pins.dtsi" #include "apq8096-db820c-pmic-pins.dtsi" #include @@ -88,6 +89,55 @@ cd-gpios = <&msmgpio 38 0x1>; status = "okay"; }; + + phy@34000 { + status = "okay"; + }; + + phy@7410000 { + status = "okay"; + }; + + phy@7411000 { + status = "okay"; + }; + + phy@7412000 { + status = "okay"; + }; + + usb@6a00000 { + status = "okay"; + + dwc3@6a00000 { + extcon = <&usb3_id>; + dr_mode = "otg"; + }; + }; + + usb3_id: usb3-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_vbus_det_gpio>; + }; + + usb@7600000 { + status = "okay"; + + dwc3@7600000 { + extcon = <&usb2_id>; + dr_mode = "otg"; + maximum-speed = "high-speed"; + }; + }; + + usb2_id: usb2-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb2_vbus_det_gpio>; + }; }; @@ -106,4 +156,152 @@ gpios = <&pm8994_gpios 2 GPIO_ACTIVE_LOW>; }; }; + + rpm-glink { + rpm_requests { + pm8994-regulators { + vdd_l1-supply = <&pm8994_s3>; + vdd_l2_l26_l28-supply = <&pm8994_s3>; + vdd_l3_l11-supply = <&pm8994_s3>; + vdd_l4_l27_l31-supply = <&pm8994_s3>; + vdd_l5_l7-supply = <&pm8994_s5>; + vdd_l14_l15-supply = <&pm8994_s5>; + vdd_l20_l21-supply = <&pm8994_s5>; + vdd_l25-supply = <&pm8994_s3>; + + s3 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + }; + s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + s5 { + regulator-min-microvolt = <2150000>; + regulator-max-microvolt = <2150000>; + }; + s7 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <800000>; + }; + + l1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + l2 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + }; + l3 { + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + }; + l4 { + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + }; + l6 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + l8 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l10 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l11 { + regulator-min-microvolt = <1150000>; + regulator-max-microvolt = <1150000>; + }; + l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l13 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + }; + l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l16 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + }; + l17 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + }; + l18 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2900000>; + }; + l19 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + l20 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + regulator-allow-set-load; + }; + l21 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + }; + l22 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + l23 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + l24 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; + }; + l25 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-allow-set-load; + }; + l27 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + l28 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <925000>; + regulator-allow-set-load; + }; + l29 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + l30 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + l32 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts new file mode 100644 index 000000000000..6a838b5d321e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts @@ -0,0 +1,52 @@ +/dts-v1/; +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include "ipq8074.dtsi" + +/ { + #address-cells = <0x2>; + #size-cells = <0x2>; + model = "Qualcomm Technologies, Inc. IPQ8074-HK01"; + compatible = "qcom,ipq8074-hk01", "qcom,ipq8074"; + interrupt-parent = <&intc>; + + aliases { + serial0 = &blsp1_uart5; + }; + + chosen { + stdout-path = "serial0"; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000 0x0 0x20000000>; + }; + + soc { + pinctrl@1000000 { + serial_4_pins: serial4_pinmux { + mux { + pins = "gpio23", "gpio24"; + function = "blsp4_uart1"; + bias-disable; + }; + }; + }; + + serial@78b3000 { + pinctrl-0 = <&serial_4_pins>; + pinctrl-names = "default"; + status = "ok"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi new file mode 100644 index 000000000000..2bc5dec5614d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +/ { + model = "Qualcomm Technologies, Inc. IPQ8074"; + compatible = "qcom,ipq8074"; + + soc: soc { + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + pinctrl@1000000 { + compatible = "qcom,ipq8074-pinctrl"; + reg = <0x1000000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <0x2>; + interrupt-controller; + #interrupt-cells = <0x2>; + }; + + intc: interrupt-controller@b000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <0x3>; + reg = <0xb000000 0x1000>, <0xb002000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + timer@b120000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0xb120000 0x1000>; + clock-frequency = <19200000>; + + frame@b120000 { + frame-number = <0>; + interrupts = , + ; + reg = <0xb121000 0x1000>, + <0xb122000 0x1000>; + }; + + frame@b123000 { + frame-number = <1>; + interrupts = ; + reg = <0xb123000 0x1000>; + status = "disabled"; + }; + + frame@b124000 { + frame-number = <2>; + interrupts = ; + reg = <0xb124000 0x1000>; + status = "disabled"; + }; + + frame@b125000 { + frame-number = <3>; + interrupts = ; + reg = <0xb125000 0x1000>; + status = "disabled"; + }; + + frame@b126000 { + frame-number = <4>; + interrupts = ; + reg = <0xb126000 0x1000>; + status = "disabled"; + }; + + frame@b127000 { + frame-number = <5>; + interrupts = ; + reg = <0xb127000 0x1000>; + status = "disabled"; + }; + + frame@b128000 { + frame-number = <6>; + interrupts = ; + reg = <0xb128000 0x1000>; + status = "disabled"; + }; + }; + + gcc: gcc@1800000 { + compatible = "qcom,gcc-ipq8074"; + reg = <0x1800000 0x80000>; + #clock-cells = <0x1>; + #reset-cells = <0x1>; + }; + + blsp1_uart5: serial@78b3000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x78b3000 0x200>; + interrupts = ; + clocks = <&gcc GCC_BLSP1_UART5_APPS_CLK>, + <&gcc GCC_BLSP1_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + }; + + cpus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0>; + next-level-cache = <&L2_0>; + enable-method = "psci"; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + reg = <0x1>; + next-level-cache = <&L2_0>; + }; + + CPU2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + reg = <0x2>; + next-level-cache = <&L2_0>; + }; + + CPU3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + enable-method = "psci"; + reg = <0x3>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache { + compatible = "cache"; + cache-level = <0x2>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + }; + + clocks { + sleep_clk: sleep_clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + + xo: xo { + compatible = "fixed-clock"; + clock-frequency = <19200000>; + #clock-cells = <0>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 039991f80831..dc3817593e14 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -88,6 +88,11 @@ no-map; }; + venus_mem: venus@89900000 { + reg = <0x0 0x89900000 0x0 0x600000>; + no-map; + }; + mba_mem: mba@8ea00000 { no-map; reg = <0 0x8ea00000 0 0x100000>; @@ -204,6 +209,17 @@ }; + gpu_opp_table: opp_table { + compatible = "operating-points-v2"; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + }; + opp-19200000 { + opp-hz = /bits/ 64 <19200000>; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = , @@ -694,6 +710,84 @@ #thermal-sensor-cells = <1>; }; + apps_iommu: iommu@1ef0000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1e20000 0x40000>; + reg = <0x1ef0000 0x3000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_APSS_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <17>; + + // mdp_0: + iommu-ctx@4000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x4000 0x1000>; + interrupts = ; + }; + + // venus_ns: + iommu-ctx@5000 { + compatible = "qcom,msm-iommu-v1-sec"; + reg = <0x5000 0x1000>; + interrupts = ; + }; + }; + + gpu_iommu: iommu@1f08000 { + #address-cells = <1>; + #size-cells = <1>; + #iommu-cells = <1>; + compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; + ranges = <0 0x1f08000 0x10000>; + clocks = <&gcc GCC_SMMU_CFG_CLK>, + <&gcc GCC_GFX_TCU_CLK>; + clock-names = "iface", "bus"; + qcom,iommu-secure-id = <18>; + + // gfx3d_user: + iommu-ctx@1000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x1000 0x1000>; + interrupts = ; + }; + + // gfx3d_priv: + iommu-ctx@2000 { + compatible = "qcom,msm-iommu-v1-ns"; + reg = <0x2000 0x1000>; + interrupts = ; + }; + }; + + gpu@1c00000 { + compatible = "qcom,adreno-306.0", "qcom,adreno"; + reg = <0x01c00000 0x20000>; + reg-names = "kgsl_3d0_reg_memory"; + interrupts = ; + interrupt-names = "kgsl_3d0_irq"; + clock-names = + "core", + "iface", + "mem", + "mem_iface", + "alt_mem_iface", + "gfx3d"; + clocks = + <&gcc GCC_OXILI_GFX3D_CLK>, + <&gcc GCC_OXILI_AHB_CLK>, + <&gcc GCC_OXILI_GMEM_CLK>, + <&gcc GCC_BIMC_GFX_CLK>, + <&gcc GCC_BIMC_GPU_CLK>, + <&gcc GFX3D_CLK_SRC>; + power-domains = <&gcc OXILI_GDSC>; + operating-points-v2 = <&gpu_opp_table>; + iommus = <&gpu_iommu 1>, <&gpu_iommu 2>; + }; + mdss: mdss@1a00000 { compatible = "qcom,mdss"; reg = <0x1a00000 0x1000>, @@ -735,6 +829,8 @@ "core_clk", "vsync_clk"; + iommus = <&apps_iommu 4>; + ports { #address-cells = <1>; #size-cells = <0>; @@ -990,7 +1086,7 @@ }; replicator@824000 { - compatible = "qcom,coresight-replicator1x", "arm,primecell"; + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0x824000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; @@ -1207,6 +1303,28 @@ }; }; }; + + venus: video-codec@1d00000 { + compatible = "qcom,msm8916-venus"; + reg = <0x01d00000 0xff000>; + interrupts = ; + power-domains = <&gcc VENUS_GDSC>; + clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>, + <&gcc GCC_VENUS0_AHB_CLK>, + <&gcc GCC_VENUS0_AXI_CLK>; + clock-names = "core", "iface", "bus"; + iommus = <&apps_iommu 5>; + memory-region = <&venus_mem>; + status = "okay"; + + video-decoder { + compatible = "venus-decoder"; + }; + + video-encoder { + compatible = "venus-encoder"; + }; + }; }; smd { diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 8f085716e258..887b61c872dd 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -276,12 +276,83 @@ hwlocks = <&tcsr_mutex 3>; }; + rpm-glink { + compatible = "qcom,glink-rpm"; + + interrupts = ; + + qcom,rpm-msg-ram = <&rpm_msg_ram>; + + mboxes = <&apcs_glb 0>; + + rpm_requests { + compatible = "qcom,rpm-msm8996"; + qcom,glink-channels = "rpm_requests"; + + pm8994-regulators { + compatible = "qcom,rpm-pm8994-regulators"; + + pm8994_s1: s1 {}; + pm8994_s2: s2 {}; + pm8994_s3: s3 {}; + pm8994_s4: s4 {}; + pm8994_s5: s5 {}; + pm8994_s6: s6 {}; + pm8994_s7: s7 {}; + pm8994_s8: s8 {}; + pm8994_s9: s9 {}; + pm8994_s10: s10 {}; + pm8994_s11: s11 {}; + pm8994_s12: s12 {}; + + pm8994_l1: l1 {}; + pm8994_l2: l2 {}; + pm8994_l3: l3 {}; + pm8994_l4: l4 {}; + pm8994_l5: l5 {}; + pm8994_l6: l6 {}; + pm8994_l7: l7 {}; + pm8994_l8: l8 {}; + pm8994_l9: l9 {}; + pm8994_l10: l10 {}; + pm8994_l11: l11 {}; + pm8994_l12: l12 {}; + pm8994_l13: l13 {}; + pm8994_l14: l14 {}; + pm8994_l15: l15 {}; + pm8994_l16: l16 {}; + pm8994_l17: l17 {}; + pm8994_l18: l18 {}; + pm8994_l19: l19 {}; + pm8994_l20: l20 {}; + pm8994_l21: l21 {}; + pm8994_l22: l22 {}; + pm8994_l23: l23 {}; + pm8994_l24: l24 {}; + pm8994_l25: l25 {}; + pm8994_l26: l26 {}; + pm8994_l27: l27 {}; + pm8994_l28: l28 {}; + pm8994_l29: l29 {}; + pm8994_l30: l30 {}; + pm8994_l31: l31 {}; + pm8994_l32: l32 {}; + }; + + }; + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; ranges = <0 0 0 0xffffffff>; compatible = "simple-bus"; + rpm_msg_ram: memory@68000 { + compatible = "qcom,rpm-msg-ram"; + reg = <0x68000 0x6000>; + }; + tcsr_mutex_regs: syscon@740000 { compatible = "syscon"; reg = <0x740000 0x20000>; @@ -303,6 +374,13 @@ reg = <0x9820000 0x1000>; }; + apcs_glb: mailbox@9820000 { + compatible = "qcom,msm8996-apcs-hmss-global"; + reg = <0x9820000 0x1000>; + + #mbox-cells = <1>; + }; + gcc: clock-controller@300000 { compatible = "qcom,gcc-msm8996"; #clock-cells = <1>; @@ -538,6 +616,209 @@ <960000000>, <825000000>; }; + + qfprom@74000 { + compatible = "qcom,qfprom"; + reg = <0x74000 0x8ff>; + #address-cells = <1>; + #size-cells = <1>; + + qusb2p_hstx_trim: hstx_trim@24e { + reg = <0x24e 0x2>; + bits = <5 4>; + }; + + qusb2s_hstx_trim: hstx_trim@24f { + reg = <0x24f 0x1>; + bits = <1 4>; + }; + }; + + phy@34000 { + compatible = "qcom,msm8996-qmp-pcie-phy"; + reg = <0x34000 0x488>; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, + <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>, + <&gcc GCC_PCIE_CLKREF_CLK>; + clock-names = "aux", "cfg_ahb", "ref"; + + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + + resets = <&gcc GCC_PCIE_PHY_BCR>, + <&gcc GCC_PCIE_PHY_COM_BCR>, + <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>; + reset-names = "phy", "common", "cfg"; + status = "disabled"; + + pciephy_0: lane@35000 { + reg = <0x035000 0x130>, + <0x035200 0x200>, + <0x035400 0x1dc>; + #phy-cells = <0>; + + clock-output-names = "pcie_0_pipe_clk_src"; + clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; + clock-names = "pipe0"; + resets = <&gcc GCC_PCIE_0_PHY_BCR>; + reset-names = "lane0"; + }; + + pciephy_1: lane@36000 { + reg = <0x036000 0x130>, + <0x036200 0x200>, + <0x036400 0x1dc>; + #phy-cells = <0>; + + clock-output-names = "pcie_1_pipe_clk_src"; + clocks = <&gcc GCC_PCIE_1_PIPE_CLK>; + clock-names = "pipe1"; + resets = <&gcc GCC_PCIE_1_PHY_BCR>; + reset-names = "lane1"; + }; + + pciephy_2: lane@37000 { + reg = <0x037000 0x130>, + <0x037200 0x200>, + <0x037400 0x1dc>; + #phy-cells = <0>; + + clock-output-names = "pcie_2_pipe_clk_src"; + clocks = <&gcc GCC_PCIE_2_PIPE_CLK>; + clock-names = "pipe2"; + resets = <&gcc GCC_PCIE_2_PHY_BCR>; + reset-names = "lane2"; + }; + }; + + phy@7410000 { + compatible = "qcom,msm8996-qmp-usb3-phy"; + reg = <0x7410000 0x1c4>; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_USB3_PHY_AUX_CLK>, + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&gcc GCC_USB3_CLKREF_CLK>; + clock-names = "aux", "cfg_ahb", "ref"; + + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; + + resets = <&gcc GCC_USB3_PHY_BCR>, + <&gcc GCC_USB3PHY_PHY_BCR>; + reset-names = "phy", "common"; + status = "disabled"; + + ssusb_phy_0: lane@7410200 { + reg = <0x7410200 0x200>, + <0x7410400 0x130>, + <0x7410600 0x1a8>; + #phy-cells = <0>; + + clock-output-names = "usb3_phy_pipe_clk_src"; + clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>; + clock-names = "pipe0"; + }; + }; + + hsusb_phy1: phy@7411000 { + compatible = "qcom,msm8996-qusb2-phy"; + reg = <0x7411000 0x180>; + #phy-cells = <0>; + + clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&gcc GCC_RX1_USB2_CLKREF_CLK>; + clock-names = "cfg_ahb", "ref"; + + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-dpdm-supply = <&pm8994_l24>; + + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + nvmem-cells = <&qusb2p_hstx_trim>; + status = "disabled"; + }; + + hsusb_phy2: phy@7412000 { + compatible = "qcom,msm8996-qusb2-phy"; + reg = <0x7412000 0x180>; + #phy-cells = <0>; + + clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, + <&gcc GCC_RX2_USB2_CLKREF_CLK>; + clock-names = "cfg_ahb", "ref"; + + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-dpdm-supply = <&pm8994_l24>; + + resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; + nvmem-cells = <&qusb2s_hstx_trim>; + status = "disabled"; + }; + + usb2: usb@7600000 { + compatible = "qcom,dwc3"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>, + <&gcc GCC_USB20_MASTER_CLK>, + <&gcc GCC_USB20_MOCK_UTMI_CLK>, + <&gcc GCC_USB20_SLEEP_CLK>, + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + + assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>, + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <60000000>; + + power-domains = <&gcc USB30_GDSC>; + status = "disabled"; + + dwc3@7600000 { + compatible = "snps,dwc3"; + reg = <0x7600000 0xcc00>; + interrupts = <0 138 0>; + phys = <&hsusb_phy2>; + phy-names = "usb2-phy"; + }; + }; + + usb3: usb@6a00000 { + compatible = "qcom,dwc3"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = <&gcc GCC_SYS_NOC_USB3_AXI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_AGGRE2_USB3_AXI_CLK>, + <&gcc GCC_USB30_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, + <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>; + + assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_MASTER_CLK>; + assigned-clock-rates = <19200000>, <120000000>; + + power-domains = <&gcc USB30_GDSC>; + status = "disabled"; + + dwc3@6a00000 { + compatible = "snps,dwc3"; + reg = <0x6a00000 0xcc00>; + interrupts = <0 131 0>; + phys = <&hsusb_phy1>, <&ssusb_phy_0>; + phy-names = "usb2-phy", "usb3-phy"; + }; + }; }; adsp-pil { @@ -558,6 +839,15 @@ qcom,smem-states = <&adsp_smp2p_out 0>; qcom,smem-state-names = "stop"; + + smd-edge { + interrupts = ; + + label = "lpass"; + qcom,ipc = <&apcs 16 8>; + qcom,smd-edge = <1>; + qcom,remote-pid = <2>; + }; }; adsp-smp2p { @@ -584,6 +874,30 @@ }; }; + modem-smp2p { + compatible = "qcom,smp2p"; + qcom,smem = <435>, <428>; + + interrupts = ; + + qcom,ipc = <&apcs 16 14>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + modem_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + modem_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + smp2p-slpi { compatible = "qcom,smp2p"; qcom,smem = <481>, <430>; diff --git a/arch/arm64/boot/dts/qcom/pm8004.dtsi b/arch/arm64/boot/dts/qcom/pm8004.dtsi index ef2207afa86b..297b57bfa87a 100644 --- a/arch/arm64/boot/dts/qcom/pm8004.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8004.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index 53deebf9f515..0223e60d8b6a 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi b/arch/arm64/boot/dts/qcom/pm8994.dtsi index b413e44fd09e..80024c0b1c7c 100644 --- a/arch/arm64/boot/dts/qcom/pm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi index d3879a4e8076..dae1cdc23f54 100644 --- a/arch/arm64/boot/dts/qcom/pmi8994.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -8,6 +9,23 @@ reg = <0x2 SPMI_USID>; #address-cells = <1>; #size-cells = <0>; + + pmi8994_gpios: gpios@c000 { + compatible = "qcom,pmi8994-gpio", "qcom,spmi-gpio"; + reg = <0xc000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <2 0xc0 0 IRQ_TYPE_NONE>, + <2 0xc1 0 IRQ_TYPE_NONE>, + <2 0xc2 0 IRQ_TYPE_NONE>, + <2 0xc3 0 IRQ_TYPE_NONE>, + <2 0xc4 0 IRQ_TYPE_NONE>, + <2 0xc5 0 IRQ_TYPE_NONE>, + <2 0xc6 0 IRQ_TYPE_NONE>, + <2 0xc7 0 IRQ_TYPE_NONE>, + <2 0xc8 0 IRQ_TYPE_NONE>, + <2 0xc9 0 IRQ_TYPE_NONE>; + }; }; pmic@3 { diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index acc4bb30d485..d417701640bd 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile @@ -1,7 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-x.dtb r8a7795-h3ulcb.dtb dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-xs.dtb dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb r8a7795-es1-h3ulcb.dtb dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-x.dtb r8a7796-m3ulcb.dtb +dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb always := $(dtb-y) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts index 95fe207cb6a3..dd4f9b6a4254 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts @@ -9,8 +9,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795-es1.dtsi" #include "ulcb.dtsi" diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts index b84c156ed696..3f7d5f51e428 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795-es1.dtsi" #include "salvator-x.dtsi" diff --git a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi index a0ba7bd21ea3..aaa5e67a963e 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi @@ -21,6 +21,14 @@ status = "disabled"; }; + /delete-node/ usb-phy@ee0e0200; + /delete-node/ usb@ee0e0100; + /delete-node/ usb@ee0e0000; + /delete-node/ usb@e659c000; + + /delete-node/ dma-controller@e6460000; + /delete-node/ dma-controller@e6470000; + fcpf2: fcp@fe952000 { compatible = "renesas,fcpf"; reg = <0 0xfe952000 0 0x200>; @@ -79,6 +87,5 @@ }; &du { - compatible = "renesas,du-r8a7795"; vsps = <&vspd0 &vspd1 &vspd2 &vspd3>; }; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts index 0426f41765f0..0afe777973de 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts @@ -9,8 +9,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795.dtsi" #include "ulcb.dtsi" @@ -40,3 +38,17 @@ reg = <0x7 0x00000000 0x0 0x40000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 721>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&versaclock5 3>, + <&versaclock5 4>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 684fb3b9d154..17953070f38d 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795.dtsi" #include "salvator-x.dtsi" diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts index de354957144b..7675de5d4f2c 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 - /dts-v1/; #include "r8a7795.dtsi" #include "salvator-xs.dtsi" @@ -46,10 +44,12 @@ <&cpg CPG_MOD 722>, <&cpg CPG_MOD 721>, <&cpg CPG_MOD 727>, + <&versaclock6 1>, <&x21_clk>, - <&x22_clk>; + <&x22_clk>, + <&versaclock6 2>; clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0", - "dclkin.1", "dclkin.2"; + "dclkin.0", "dclkin.1", "dclkin.2", "dclkin.3"; }; &ehci2 { diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index e31c1b660b3f..2938195b9571 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -12,6 +12,8 @@ #include #include +#define CPG_AUDIO_CLK_I R8A7795_CLK_S0D4 + / { compatible = "renesas,r8a7795"; #address-cells = <2>; @@ -691,6 +693,126 @@ }; }; + drif00: rif@e6f40000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f40000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 515>; + clock-names = "fck"; + dmas = <&dmac1 0x20>, <&dmac2 0x20>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 515>; + renesas,bonding = <&drif01>; + status = "disabled"; + }; + + drif01: rif@e6f50000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f50000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>; + clock-names = "fck"; + dmas = <&dmac1 0x22>, <&dmac2 0x22>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 514>; + renesas,bonding = <&drif00>; + status = "disabled"; + }; + + drif10: rif@e6f60000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f60000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 513>; + clock-names = "fck"; + dmas = <&dmac1 0x24>, <&dmac2 0x24>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 513>; + renesas,bonding = <&drif11>; + status = "disabled"; + }; + + drif11: rif@e6f70000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f70000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 512>; + clock-names = "fck"; + dmas = <&dmac1 0x26>, <&dmac2 0x26>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 512>; + renesas,bonding = <&drif10>; + status = "disabled"; + }; + + drif20: rif@e6f80000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f80000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 511>; + clock-names = "fck"; + dmas = <&dmac1 0x28>, <&dmac2 0x28>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 511>; + renesas,bonding = <&drif21>; + status = "disabled"; + }; + + drif21: rif@e6f90000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f90000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 510>; + clock-names = "fck"; + dmas = <&dmac1 0x2a>, <&dmac2 0x2a>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 510>; + renesas,bonding = <&drif20>; + status = "disabled"; + }; + + drif30: rif@e6fa0000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fa0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 509>; + clock-names = "fck"; + dmas = <&dmac1 0x2c>, <&dmac2 0x2c>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 509>; + renesas,bonding = <&drif31>; + status = "disabled"; + }; + + drif31: rif@e6fb0000 { + compatible = "renesas,r8a7795-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fb0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 508>; + clock-names = "fck"; + dmas = <&dmac1 0x2e>, <&dmac2 0x2e>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 508>; + renesas,bonding = <&drif30>; + status = "disabled"; + }; + hscif0: serial@e6540000 { compatible = "renesas,hscif-r8a7795", "renesas,rcar-gen3-hscif", @@ -776,6 +898,68 @@ status = "disabled"; }; + msiof0: spi@e6e90000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6e90000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 211>; + dmas = <&dmac1 0x41>, <&dmac1 0x40>, + <&dmac2 0x41>, <&dmac2 0x40>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 211>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof1: spi@e6ea0000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6ea0000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 210>; + dmas = <&dmac1 0x43>, <&dmac1 0x42>, + <&dmac2 0x43>, <&dmac2 0x42>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 210>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof2: spi@e6c00000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6c00000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 209>; + dmas = <&dmac0 0x45>, <&dmac0 0x44>; + dma-names = "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 209>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof3: spi@e6c10000 { + compatible = "renesas,msiof-r8a7795", + "renesas,rcar-gen3-msiof"; + reg = <0 0xe6c10000 0 0x0064>; + interrupts = ; + clocks = <&cpg CPG_MOD 208>; + dmas = <&dmac0 0x47>, <&dmac0 0x46>; + dma-names = "tx", "rx"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 208>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + scif0: serial@e6e60000 { compatible = "renesas,scif-r8a7795", "renesas,rcar-gen3-scif", "renesas,scif"; @@ -1267,7 +1451,8 @@ }; sata: sata@ee300000 { - compatible = "renesas,sata-r8a7795"; + compatible = "renesas,sata-r8a7795", + "renesas,rcar-gen3-sata"; reg = <0 0xee300000 0 0x200000>; interrupts = ; clocks = <&cpg CPG_MOD 815>; @@ -1314,6 +1499,34 @@ dma-channels = <2>; }; + usb_dmac2: dma-controller@e6460000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe6460000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 326>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 326>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac3: dma-controller@e6470000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe6470000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 329>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 329>; + #dma-cells = <1>; + dma-channels = <2>; + }; + sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7795"; reg = <0 0xee100000 0 0x2000>; @@ -1392,6 +1605,18 @@ status = "disabled"; }; + usb2_phy3: usb-phy@ee0e0200 { + compatible = "renesas,usb2-phy-r8a7795", + "renesas,rcar-gen3-usb2-phy"; + reg = <0 0xee0e0200 0 0x700>; + interrupts = ; + clocks = <&cpg CPG_MOD 700>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 700>; + #phy-cells = <0>; + status = "disabled"; + }; + ehci0: usb@ee080100 { compatible = "generic-ehci"; reg = <0 0xee080100 0 0x100>; @@ -1399,6 +1624,7 @@ clocks = <&cpg CPG_MOD 703>; phys = <&usb2_phy0>; phy-names = "usb"; + companion = <&ohci0>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; resets = <&cpg 703>; status = "disabled"; @@ -1411,6 +1637,7 @@ clocks = <&cpg CPG_MOD 702>; phys = <&usb2_phy1>; phy-names = "usb"; + companion = <&ohci1>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; resets = <&cpg 702>; status = "disabled"; @@ -1423,11 +1650,25 @@ clocks = <&cpg CPG_MOD 701>; phys = <&usb2_phy2>; phy-names = "usb"; + companion = <&ohci2>; power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; resets = <&cpg 701>; status = "disabled"; }; + ehci3: usb@ee0e0100 { + compatible = "generic-ehci"; + reg = <0 0xee0e0100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 700>; + phys = <&usb2_phy3>; + phy-names = "usb"; + companion = <&ohci3>; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 700>; + status = "disabled"; + }; + ohci0: usb@ee080000 { compatible = "generic-ohci"; reg = <0 0xee080000 0 0x100>; @@ -1464,6 +1705,18 @@ status = "disabled"; }; + ohci3: usb@ee0e0000 { + compatible = "generic-ohci"; + reg = <0 0xee0e0000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 700>; + phys = <&usb2_phy3>; + phy-names = "usb"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 700>; + status = "disabled"; + }; + hsusb: usb@e6590000 { compatible = "renesas,usbhs-r8a7795", "renesas,rcar-gen3-usbhs"; @@ -1481,6 +1734,23 @@ status = "disabled"; }; + hsusb3: usb@e659c000 { + compatible = "renesas,usbhs-r8a7795", + "renesas,rcar-gen3-usbhs"; + reg = <0 0xe659c000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 705>; + dmas = <&usb_dmac2 0>, <&usb_dmac2 1>, + <&usb_dmac3 0>, <&usb_dmac3 1>; + dma-names = "ch0", "ch1", "ch2", "ch3"; + renesas,buswait = <11>; + phys = <&usb2_phy3>; + phy-names = "usb"; + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; + resets = <&cpg 705>; + status = "disabled"; + }; + pciec0: pcie@fe000000 { compatible = "renesas,pcie-r8a7795", "renesas,pcie-rcar-gen3"; @@ -1535,6 +1805,46 @@ status = "disabled"; }; + imr-lx4@fe860000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe860000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 823>; + }; + + imr-lx4@fe870000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe870000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 822>; + }; + + imr-lx4@fe880000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe880000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 821>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 821>; + }; + + imr-lx4@fe890000 { + compatible = "renesas,r8a7795-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe890000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 820>; + power-domains = <&sysc R8A7795_PD_A3VC>; + resets = <&cpg 820>; + }; + vspbc: vsp@fe920000 { compatible = "renesas,vsp2"; reg = <0 0xfe920000 0 0x8000>; @@ -1755,6 +2065,7 @@ }; du: display@feb00000 { + compatible = "renesas,du-r8a7795"; reg = <0 0xfeb00000 0 0x80000>, <0 0xfeb90000 0 0x14>; reg-names = "du", "lvds.0"; @@ -1768,6 +2079,7 @@ <&cpg CPG_MOD 721>, <&cpg CPG_MOD 727>; clock-names = "du.0", "du.1", "du.2", "du.3", "lvds.0"; + vsps = <&vspd0 0 &vspd1 0 &vspd2 0 &vspd0 1>; status = "disabled"; ports { diff --git a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts index 38b58b7fca4b..daee1f1a3f68 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts +++ b/arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts @@ -9,8 +9,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 - /dts-v1/; #include "r8a7796.dtsi" #include "ulcb.dtsi" @@ -30,3 +28,15 @@ reg = <0x6 0x00000000 0x0 0x40000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&versaclock5 3>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts index db4f162d6bdd..b317be03306e 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts @@ -8,8 +8,6 @@ * kind, whether express or implied. */ -#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 - /dts-v1/; #include "r8a7796.dtsi" #include "salvator-x.dtsi" @@ -29,3 +27,32 @@ reg = <0x6 0x00000000 0x0 0x80000000>; }; }; + +&du { + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 727>, + <&versaclock5 1>, + <&x21_clk>, + <&versaclock5 2>; + clock-names = "du.0", "du.1", "du.2", "lvds.0", + "dclkin.0", "dclkin.1", "dclkin.2"; +}; + +&hdmi0 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi0_out: endpoint { + remote-endpoint = <&hdmi0_con>; + }; + }; + }; +}; + +&hdmi0_con { + remote-endpoint = <&rcar_dw_hdmi0_out>; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi index 1f6710912045..369092e17e34 100644 --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi @@ -12,6 +12,8 @@ #include #include +#define CPG_AUDIO_CLK_I R8A7796_CLK_S0D4 + / { compatible = "renesas,r8a7796"; #address-cells = <2>; @@ -639,6 +641,126 @@ }; }; + drif00: rif@e6f40000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f40000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 515>; + clock-names = "fck"; + dmas = <&dmac1 0x20>, <&dmac2 0x20>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 515>; + renesas,bonding = <&drif01>; + status = "disabled"; + }; + + drif01: rif@e6f50000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f50000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 514>; + clock-names = "fck"; + dmas = <&dmac1 0x22>, <&dmac2 0x22>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 514>; + renesas,bonding = <&drif00>; + status = "disabled"; + }; + + drif10: rif@e6f60000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f60000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 513>; + clock-names = "fck"; + dmas = <&dmac1 0x24>, <&dmac2 0x24>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 513>; + renesas,bonding = <&drif11>; + status = "disabled"; + }; + + drif11: rif@e6f70000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f70000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 512>; + clock-names = "fck"; + dmas = <&dmac1 0x26>, <&dmac2 0x26>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 512>; + renesas,bonding = <&drif10>; + status = "disabled"; + }; + + drif20: rif@e6f80000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f80000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 511>; + clock-names = "fck"; + dmas = <&dmac1 0x28>, <&dmac2 0x28>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 511>; + renesas,bonding = <&drif21>; + status = "disabled"; + }; + + drif21: rif@e6f90000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6f90000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 510>; + clock-names = "fck"; + dmas = <&dmac1 0x2a>, <&dmac2 0x2a>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 510>; + renesas,bonding = <&drif20>; + status = "disabled"; + }; + + drif30: rif@e6fa0000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fa0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 509>; + clock-names = "fck"; + dmas = <&dmac1 0x2c>, <&dmac2 0x2c>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 509>; + renesas,bonding = <&drif31>; + status = "disabled"; + }; + + drif31: rif@e6fb0000 { + compatible = "renesas,r8a7796-drif", + "renesas,rcar-gen3-drif"; + reg = <0 0xe6fb0000 0 0x64>; + interrupts = ; + clocks = <&cpg CPG_MOD 508>; + clock-names = "fck"; + dmas = <&dmac1 0x2e>, <&dmac2 0x2e>; + dma-names = "rx", "rx"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 508>; + renesas,bonding = <&drif30>; + status = "disabled"; + }; + avb: ethernet@e6800000 { compatible = "renesas,etheravb-r8a7796", "renesas,etheravb-rcar-gen3"; @@ -877,7 +999,7 @@ clocks = <&cpg CPG_MOD 211>; dmas = <&dmac1 0x41>, <&dmac1 0x40>, <&dmac2 0x41>, <&dmac2 0x40>; - dma-names = "tx", "rx"; + dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; resets = <&cpg 211>; #address-cells = <1>; @@ -893,7 +1015,7 @@ clocks = <&cpg CPG_MOD 210>; dmas = <&dmac1 0x43>, <&dmac1 0x42>, <&dmac2 0x43>, <&dmac2 0x42>; - dma-names = "tx", "rx"; + dma-names = "tx", "rx", "tx", "rx"; power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; resets = <&cpg 210>; #address-cells = <1>; @@ -1101,36 +1223,133 @@ dma-channels = <16>; }; + usb_dmac0: dma-controller@e65a0000 { + compatible = "renesas,r8a7796-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65a0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 330>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 330>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac1: dma-controller@e65b0000 { + compatible = "renesas,r8a7796-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65b0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 331>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 331>; + #dma-cells = <1>; + dma-channels = <2>; + }; + hsusb: usb@e6590000 { - /* placeholder */ + compatible = "renesas,usbhs-r8a7796", + "renesas,rcar-gen3-usbhs"; + reg = <0 0xe6590000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 704>; + dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, + <&usb_dmac1 0>, <&usb_dmac1 1>; + dma-names = "ch0", "ch1", "ch2", "ch3"; + renesas,buswait = <11>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 704>; + status = "disabled"; }; xhci0: usb@ee000000 { - /* placeholder */ + compatible = "renesas,xhci-r8a7796", + "renesas,rcar-gen3-xhci"; + reg = <0 0xee000000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 328>; + status = "disabled"; }; ohci0: usb@ee080000 { - /* placeholder */ + compatible = "generic-ohci"; + reg = <0 0xee080000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 703>; + status = "disabled"; }; ehci0: usb@ee080100 { - /* placeholder */ + compatible = "generic-ehci"; + reg = <0 0xee080100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + companion= <&ohci0>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 703>; + status = "disabled"; }; usb2_phy0: usb-phy@ee080200 { - /* placeholder */ + compatible = "renesas,usb2-phy-r8a7796", + "renesas,rcar-gen3-usb2-phy"; + reg = <0 0xee080200 0 0x700>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 703>; + #phy-cells = <0>; + status = "disabled"; }; ohci1: usb@ee0a0000 { - /* placeholder */ + compatible = "generic-ohci"; + reg = <0 0xee0a0000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 702>; + status = "disabled"; }; ehci1: usb@ee0a0100 { - /* placeholder */ + compatible = "generic-ehci"; + reg = <0 0xee0a0100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + companion= <&ohci1>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 702>; + status = "disabled"; }; usb2_phy1: usb-phy@ee0a0200 { - /* placeholder */ + compatible = "renesas,usb2-phy-r8a7796", + "renesas,rcar-gen3-usb2-phy"; + reg = <0 0xee0a0200 0 0x700>; + clocks = <&cpg CPG_MOD 702>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 702>; + #phy-cells = <0>; + status = "disabled"; }; sdhi0: sd@ee100000 { @@ -1440,8 +1659,150 @@ /* placeholder */ }; + fcpf0: fcp@fe950000 { + compatible = "renesas,fcpf"; + reg = <0 0xfe950000 0 0x200>; + clocks = <&cpg CPG_MOD 615>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 615>; + }; + + vspb: vsp@fe960000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe960000 0 0x8000>; + interrupts = ; + clocks = <&cpg CPG_MOD 626>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 626>; + + renesas,fcp = <&fcpvb0>; + }; + + fcpvb0: fcp@fe96f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe96f000 0 0x200>; + clocks = <&cpg CPG_MOD 607>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 607>; + }; + + vspi0: vsp@fe9a0000 { + compatible = "renesas,vsp2"; + reg = <0 0xfe9a0000 0 0x8000>; + interrupts = ; + clocks = <&cpg CPG_MOD 631>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 631>; + + renesas,fcp = <&fcpvi0>; + }; + + fcpvi0: fcp@fe9af000 { + compatible = "renesas,fcpv"; + reg = <0 0xfe9af000 0 0x200>; + clocks = <&cpg CPG_MOD 611>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 611>; + }; + + vspd0: vsp@fea20000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea20000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 623>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 623>; + + renesas,fcp = <&fcpvd0>; + }; + + fcpvd0: fcp@fea27000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea27000 0 0x200>; + clocks = <&cpg CPG_MOD 603>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 603>; + }; + + vspd1: vsp@fea28000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea28000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 622>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 622>; + + renesas,fcp = <&fcpvd1>; + }; + + fcpvd1: fcp@fea2f000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea2f000 0 0x200>; + clocks = <&cpg CPG_MOD 602>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 602>; + }; + + vspd2: vsp@fea30000 { + compatible = "renesas,vsp2"; + reg = <0 0xfea30000 0 0x4000>; + interrupts = ; + clocks = <&cpg CPG_MOD 621>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 621>; + + renesas,fcp = <&fcpvd2>; + }; + + fcpvd2: fcp@fea37000 { + compatible = "renesas,fcpv"; + reg = <0 0xfea37000 0 0x200>; + clocks = <&cpg CPG_MOD 601>; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 601>; + }; + + hdmi0: hdmi@fead0000 { + compatible = "renesas,r8a7796-hdmi", "renesas,rcar-gen3-hdmi"; + reg = <0 0xfead0000 0 0x10000>; + interrupts = ; + clocks = <&cpg CPG_MOD 729>, <&cpg CPG_CORE R8A7796_CLK_HDMI>; + clock-names = "iahb", "isfr"; + power-domains = <&sysc R8A7796_PD_ALWAYS_ON>; + resets = <&cpg 729>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + dw_hdmi0_in: endpoint { + remote-endpoint = <&du_out_hdmi0>; + }; + }; + port@1 { + reg = <1>; + }; + }; + }; + du: display@feb00000 { - /* placeholder */ + compatible = "renesas,du-r8a7796"; + reg = <0 0xfeb00000 0 0x70000>, + <0 0xfeb90000 0 0x14>; + reg-names = "du", "lvds.0"; + interrupts = , + , + ; + clocks = <&cpg CPG_MOD 724>, + <&cpg CPG_MOD 723>, + <&cpg CPG_MOD 722>, + <&cpg CPG_MOD 727>; + clock-names = "du.0", "du.1", "du.2", "lvds.0"; + status = "disabled"; + + vsps = <&vspd0 &vspd1 &vspd2>; ports { #address-cells = <1>; @@ -1452,7 +1813,38 @@ du_out_rgb: endpoint { }; }; + port@1 { + reg = <1>; + du_out_hdmi0: endpoint { + remote-endpoint = <&dw_hdmi0_in>; + }; + }; + port@2 { + reg = <2>; + du_out_lvds0: endpoint { + }; + }; }; }; + + imr-lx4@fe860000 { + compatible = "renesas,r8a7796-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe860000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 823>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 823>; + }; + + imr-lx4@fe870000 { + compatible = "renesas,r8a7796-imr-lx4", + "renesas,imr-lx4"; + reg = <0 0xfe870000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 822>; + power-domains = <&sysc R8A7796_PD_A3VC>; + resets = <&cpg 822>; + }; }; }; diff --git a/arch/arm64/boot/dts/renesas/r8a77995-draak.dts b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts new file mode 100644 index 000000000000..d144370051d5 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -0,0 +1,46 @@ +/* + * Device Tree Source for the Draak board + * + * Copyright (C) 2016 Renesas Electronics Corp. + * Copyright (C) 2017 Glider bvba + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +#include "r8a77995.dtsi" + +/ { + model = "Renesas Draak board based on r8a77995"; + compatible = "renesas,draak", "renesas,r8a77995"; + + aliases { + serial0 = &scif2; + }; + + chosen { + bootargs = "ignore_loglevel"; + stdout-path = "serial0:115200n8"; + }; + + memory@48000000 { + device_type = "memory"; + /* first 128MB is reserved for secure area. */ + reg = <0x0 0x48000000 0x0 0x18000000>; + }; +}; + +&extal_clk { + clock-frequency = <48000000>; +}; + +&scif2 { + status = "okay"; +}; + +&rwdt { + timeout-sec = <60>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi new file mode 100644 index 000000000000..d0f95b78c022 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi @@ -0,0 +1,155 @@ +/* + * Device Tree Source for the r8a77995 SoC + * + * Copyright (C) 2016 Renesas Electronics Corp. + * Copyright (C) 2017 Glider bvba + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include + +/ { + compatible = "renesas,r8a77995"; + #address-cells = <2>; + #size-cells = <2>; + + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + a53_0: cpu@0 { + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0>; + device_type = "cpu"; + power-domains = <&sysc 5>; + next-level-cache = <&L2_CA53>; + enable-method = "psci"; + }; + + L2_CA53: cache-controller-1 { + compatible = "cache"; + power-domains = <&sysc 21>; + cache-unified; + cache-level = <2>; + }; + }; + + extal_clk: extal { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + }; + + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic: interrupt-controller@f1010000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0xf1010000 0 0x1000>, + <0x0 0xf1020000 0 0x20000>, + <0x0 0xf1040000 0 0x20000>, + <0x0 0xf1060000 0 0x20000>; + interrupts = ; + clocks = <&cpg CPG_MOD 408>; + clock-names = "clk"; + power-domains = <&sysc 32>; + resets = <&cpg 408>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + rwdt: watchdog@e6020000 { + compatible = "renesas,r8a77995-wdt", + "renesas,rcar-gen3-wdt"; + reg = <0 0xe6020000 0 0x0c>; + clocks = <&cpg CPG_MOD 402>; + power-domains = <&sysc 32>; + resets = <&cpg 402>; + status = "disabled"; + }; + + pmu_a53 { + compatible = "arm,cortex-a53-pmu"; + interrupts = ; + }; + + cpg: clock-controller@e6150000 { + compatible = "renesas,r8a77995-cpg-mssr"; + reg = <0 0xe6150000 0 0x1000>; + clocks = <&extal_clk>; + clock-names = "extal"; + #clock-cells = <2>; + #power-domain-cells = <0>; + #reset-cells = <1>; + }; + + rst: reset-controller@e6160000 { + compatible = "renesas,r8a77995-rst"; + reg = <0 0xe6160000 0 0x0200>; + }; + + pfc: pfc@e6060000 { + compatible = "renesas,pfc-r8a77995"; + reg = <0 0xe6060000 0 0x508>; + }; + + prr: chipid@fff00044 { + compatible = "renesas,prr"; + reg = <0 0xfff00044 0 4>; + }; + + sysc: system-controller@e6180000 { + compatible = "renesas,r8a77995-sysc"; + reg = <0 0xe6180000 0 0x0400>; + #power-domain-cells = <1>; + }; + + scif2: serial@e6e88000 { + compatible = "renesas,scif-r8a77995", + "renesas,rcar-gen3-scif", "renesas,scif"; + reg = <0 0xe6e88000 0 64>; + interrupts = ; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE 16>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&sysc 32>; + resets = <&cpg 310>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi index f903957da504..d9d885006a8e 100644 --- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi @@ -62,6 +62,7 @@ brightness-levels = <256 128 64 16 8 4 0>; default-brightness-level = <6>; + power-supply = <®_12v>; enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>; }; @@ -83,6 +84,15 @@ regulator-always-on; }; + reg_12v: regulator2 { + compatible = "regulator-fixed"; + regulator-name = "fixed-12V"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-boot-on; + regulator-always-on; + }; + rsnd_ak4613: sound { compatible = "simple-audio-card"; @@ -268,10 +278,6 @@ remote-endpoint = <&adv7123_in>; }; }; - port@3 { - lvds_connector: endpoint { - }; - }; }; }; diff --git a/arch/arm64/boot/dts/renesas/salvator-xs.dtsi b/arch/arm64/boot/dts/renesas/salvator-xs.dtsi index 81227e3c2c6f..bf4d200fb546 100644 --- a/arch/arm64/boot/dts/renesas/salvator-xs.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-xs.dtsi @@ -18,3 +18,13 @@ &extal_clk { clock-frequency = <16640000>; }; + +&i2c4 { + versaclock6: clock-generator@6a { + compatible = "idt,5p49v6901"; + reg = <0x6a>; + #clock-cells = <1>; + clocks = <&x23_clk>; + clock-names = "xin"; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi index d1a3f3b7a0ab..1b868df2393f 100644 --- a/arch/arm64/boot/dts/renesas/ulcb.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi @@ -34,6 +34,16 @@ clock-frequency = <11289600>; }; + hdmi0-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi0_con: endpoint { + }; + }; + }; + keyboard { compatible = "gpio-keys"; @@ -120,6 +130,12 @@ #clock-cells = <0>; clock-frequency = <24576000>; }; + + x23_clk: x23-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; }; &audio_clk_a { @@ -153,6 +169,23 @@ clock-frequency = <32768>; }; +&hdmi0 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + rcar_dw_hdmi0_out: endpoint { + remote-endpoint = <&hdmi0_con>; + }; + }; + }; +}; + +&hdmi0_con { + remote-endpoint = <&rcar_dw_hdmi0_out>; +}; + &i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; @@ -189,6 +222,24 @@ }; }; +&i2c4 { + status = "okay"; + + clock-frequency = <400000>; + + versaclock5: clock-generator@6a { + compatible = "idt,5p49v5925"; + reg = <0x6a>; + #clock-cells = <1>; + clocks = <&x23_clk>; + clock-names = "xin"; + }; +}; + +&i2c_dvfs { + status = "okay"; +}; + &ohci1 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index bcfa53b1e6b7..84801892ee61 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -1,4 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-evb-act8846.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-geekbox.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-orion-r68-meta.dtb @@ -7,6 +9,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3368-r88.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-firefly.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-puma-haikou.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts index cf272392cebf..8e6a65431756 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts @@ -50,8 +50,189 @@ chosen { stdout-path = "serial2:1500000n8"; }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; +}; + +&gmac2phy { + phy-supply = <&vcc_phy>; + clock_in_out = "output"; + assigned-clocks = <&cru SCLK_MAC2PHY_SRC>; + assigned-clock-rate = <50000000>; + assigned-clocks = <&cru SCLK_MAC2PHY>; + assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + rk805: rk805@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + gpio-controller; + #gpio-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_io>; + vcc6-supply = <&vcc_io>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_18: LDO_REG1 { + regulator-name = "vcc_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc18_emmc: LDO_REG2 { + regulator-name = "vcc18_emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + }; + }; +}; + +&pinctrl { + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&tsadc { + status = "okay"; }; &uart2 { status = "okay"; }; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&usb20_otg { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts new file mode 100644 index 000000000000..d4f80786e7c2 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2017 PINE64 + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "rk3328.dtsi" + +/ { + model = "Pine64 Rock64"; + compatible = "pine64,rock64", "rockchip,rk3328"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + gmac_clkin: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0>; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0m1_gpio>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io>; + }; + + vcc_host_5v: vcc-host-5v-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb30_host_drv>; + regulator-name = "vcc_host_5v"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb20_host_drv>; + regulator-name = "vcc_host1_5v"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc18_emmc>; + status = "okay"; +}; + +&gmac2io { + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clkin>, <&gmac_clkin>; + clock_in_out = "input"; + phy-supply = <&vcc_io>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmiim1_pins>; + snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x26>; + rx_delay = <0x11>; + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + rk805: rk805@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_io>; + vcc6-supply = <&vcc_sys>; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io: DCDC_REG4 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_18: LDO_REG1 { + regulator-name = "vdd_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc18_emmc: LDO_REG2 { + regulator-name = "vcc_18emmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + }; + }; +}; + +&io_domains { + status = "okay"; + + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io>; + vccio6-supply = <&vcc_io>; + pmuio-supply = <&vcc_io>; +}; + +&pinctrl { + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb2 { + usb20_host_drv: usb20-host-drv { + rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb3 { + usb30_host_drv: usb30-host-drv { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4>; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + dr_mode = "host"; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 0be96cee27bd..41d61840fb99 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -47,6 +47,7 @@ #include #include #include +#include / { compatible = "rockchip,rk3328"; @@ -63,6 +64,8 @@ i2c1 = &i2c1; i2c2 = &i2c2; i2c3 = &i2c3; + ethernet0 = &gmac2io; + ethernet1 = &gmac2phy; }; cpus { @@ -74,8 +77,11 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x0>; clocks = <&cru ARMCLK>; + #cooling-cells = <2>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu1: cpu@1 { @@ -83,8 +89,10 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x1>; clocks = <&cru ARMCLK>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu2: cpu@2 { @@ -92,8 +100,10 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x2>; clocks = <&cru ARMCLK>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; cpu3: cpu@3 { @@ -101,8 +111,10 @@ compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0 0x3>; clocks = <&cru ARMCLK>; + dynamic-power-coefficient = <120>; enable-method = "psci"; next-level-cache = <&l2>; + operating-points-v2 = <&cpu0_opp_table>; }; l2: l2-cache0 { @@ -110,6 +122,43 @@ }; }; + cpu0_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <950000>; + clock-latency-ns = <40000>; + }; + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <40000>; + }; + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <1100000>; + clock-latency-ns = <40000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1225000>; + clock-latency-ns = <40000>; + }; + opp-1296000000 { + opp-hz = /bits/ 64 <1296000000>; + opp-microvolt = <1300000>; + clock-latency-ns = <40000>; + }; + }; + amba { compatible = "simple-bus"; #address-cells = <2>; @@ -156,12 +205,84 @@ clock-output-names = "xin24m"; }; + i2s0: i2s@ff000000 { + compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s"; + reg = <0x0 0xff000000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>; + clock-names = "i2s_clk", "i2s_hclk"; + dmas = <&dmac 11>, <&dmac 12>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + i2s1: i2s@ff010000 { + compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s"; + reg = <0x0 0xff010000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1_8CH>; + clock-names = "i2s_clk", "i2s_hclk"; + dmas = <&dmac 14>, <&dmac 15>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + i2s2: i2s@ff020000 { + compatible = "rockchip,rk3328-i2s", "rockchip,rk3066-i2s"; + reg = <0x0 0xff020000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2_2CH>; + clock-names = "i2s_clk", "i2s_hclk"; + dmas = <&dmac 0>, <&dmac 1>; + dma-names = "tx", "rx"; + status = "disabled"; + }; + + spdif: spdif@ff030000 { + compatible = "rockchip,rk3328-spdif"; + reg = <0x0 0xff030000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF_8CH>; + clock-names = "mclk", "hclk"; + dmas = <&dmac 10>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdifm2_tx>; + status = "disabled"; + }; + + pdm: pdm@ff040000 { + compatible = "rockchip,pdm"; + reg = <0x0 0xff040000 0x0 0x1000>; + clocks = <&cru SCLK_PDM>, <&cru HCLK_PDM>; + clock-names = "pdm_clk", "pdm_hclk"; + dmas = <&dmac 16>; + dma-names = "rx"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pdmm0_clk + &pdmm0_sdi0 + &pdmm0_sdi1 + &pdmm0_sdi2 + &pdmm0_sdi3>; + pinctrl-1 = <&pdmm0_clk_sleep + &pdmm0_sdi0_sleep + &pdmm0_sdi1_sleep + &pdmm0_sdi2_sleep + &pdmm0_sdi3_sleep>; + status = "disabled"; + }; + grf: syscon@ff100000 { compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd"; reg = <0x0 0xff100000 0x0 0x1000>; #address-cells = <1>; #size-cells = <1>; + io_domains: io-domains { + compatible = "rockchip,rk3328-io-voltage-domain"; + status = "disabled"; + }; + power: power-controller { compatible = "rockchip,rk3328-power-controller"; #power-domain-cells = <1>; @@ -308,6 +429,108 @@ interrupts = ; }; + pwm0: pwm@ff1b0000 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0000 0x0 0x10>; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@ff1b0010 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0010 0x0 0x10>; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@ff1b0020 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0020 0x0 0x10>; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm2_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@ff1b0030 { + compatible = "rockchip,rk3328-pwm"; + reg = <0x0 0xff1b0030 0x0 0x10>; + interrupts = ; + clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clock-names = "pwm", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&pwmir_pin>; + #pwm-cells = <3>; + status = "disabled"; + }; + + thermal-zones { + soc_thermal: soc-thermal { + polling-delay-passive = <20>; + polling-delay = <1000>; + sustainable-power = <1000>; + + thermal-sensors = <&tsadc 0>; + + trips { + threshold: trip-point0 { + temperature = <70000>; + hysteresis = <2000>; + type = "passive"; + }; + target: trip-point1 { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + soc_crit: soc-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&target>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <4096>; + }; + }; + }; + + }; + + tsadc: tsadc@ff250000 { + compatible = "rockchip,rk3328-tsadc"; + reg = <0x0 0xff250000 0x0 0x100>; + interrupts = ; + assigned-clocks = <&cru SCLK_TSADC>; + assigned-clock-rates = <50000>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + pinctrl-names = "init", "default", "sleep"; + pinctrl-0 = <&otp_gpio>; + pinctrl-1 = <&otp_out>; + pinctrl-2 = <&otp_gpio>; + resets = <&cru SRST_TSADC>; + reset-names = "tsadc-apb"; + rockchip,grf = <&grf>; + rockchip,hw-tshut-temp = <100000>; + #thermal-sensor-cells = <1>; + status = "disabled"; + }; + saradc: adc@ff280000 { compatible = "rockchip,rk3328-saradc", "rockchip,rk3399-saradc"; reg = <0x0 0xff280000 0x0 0x100>; @@ -320,6 +543,51 @@ status = "disabled"; }; + h265e_mmu: iommu@ff330200 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff330200 0 0x100>; + interrupts = ; + interrupt-names = "h265e_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vepu_mmu: iommu@ff340800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff340800 0x0 0x40>; + interrupts = ; + interrupt-names = "vepu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vpu_mmu: iommu@ff350800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff350800 0x0 0x40>; + interrupts = ; + interrupt-names = "vpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + rkvdec_mmu: iommu@ff360480 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff360480 0x0 0x40>, <0x0 0xff3604c0 0x0 0x40>; + interrupts = ; + interrupt-names = "rkvdec_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vop_mmu: iommu@ff373f00 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff373f00 0x0 0x100>; + interrupts = ; + interrupt-names = "vop_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + cru: clock-controller@ff440000 { compatible = "rockchip,rk3328-cru", "rockchip,cru", "syscon"; reg = <0x0 0xff440000 0x0 0x1000>; @@ -372,6 +640,43 @@ <32768>; }; + usb2phy_grf: syscon@ff450000 { + compatible = "rockchip,rk3328-usb2phy-grf", "syscon", + "simple-mfd"; + reg = <0x0 0xff450000 0x0 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + u2phy: usb2-phy@100 { + compatible = "rockchip,rk3328-usb2phy"; + reg = <0x100 0x10>; + clocks = <&xin24m>; + clock-names = "phyclk"; + clock-output-names = "usb480m_phy"; + #clock-cells = <0>; + assigned-clocks = <&cru USB480M>; + assigned-clock-parents = <&u2phy>; + status = "disabled"; + + u2phy_otg: otg-port { + #phy-cells = <0>; + interrupts = , + , + ; + interrupt-names = "otg-bvalid", "otg-id", + "linestate"; + status = "disabled"; + }; + + u2phy_host: host-port { + #phy-cells = <0>; + interrupts = ; + interrupt-names = "linestate"; + status = "disabled"; + }; + }; + }; + sdmmc: dwmmc@ff500000 { compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff500000 0x0 0x4000>; @@ -424,6 +729,82 @@ status = "disabled"; }; + gmac2phy: ethernet@ff550000 { + compatible = "rockchip,rk3328-gmac"; + reg = <0x0 0xff550000 0x0 0x10000>; + rockchip,grf = <&grf>; + interrupts = ; + interrupt-names = "macirq"; + clocks = <&cru SCLK_MAC2PHY_SRC>, <&cru SCLK_MAC2PHY_RXTX>, + <&cru SCLK_MAC2PHY_RXTX>, <&cru SCLK_MAC2PHY_REF>, + <&cru ACLK_MAC2PHY>, <&cru PCLK_MAC2PHY>, + <&cru SCLK_MAC2PHY_OUT>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "aclk_mac", "pclk_mac", + "clk_macphy"; + resets = <&cru SRST_GMAC2PHY_A>, <&cru SRST_MACPHY>; + reset-names = "stmmaceth", "mac-phy"; + phy-mode = "rmii"; + phy-handle = <&phy>; + status = "disabled"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + phy: phy@0 { + compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; + reg = <0>; + clocks = <&cru SCLK_MAC2PHY_OUT>; + resets = <&cru SRST_MACPHY>; + pinctrl-names = "default"; + pinctrl-0 = <&fephyled_rxm1 &fephyled_linkm1>; + phy-is-integrated; + }; + }; + }; + + usb20_otg: usb@ff580000 { + compatible = "rockchip,rk3328-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0x0 0xff580000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_OTG>; + clock-names = "otg"; + dr_mode = "otg"; + g-np-tx-fifo-size = <16>; + g-rx-fifo-size = <280>; + g-tx-fifo-size = <256 128 128 64 32 16>; + g-use-dma; + phys = <&u2phy_otg>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + + usb_host0_ehci: usb@ff5c0000 { + compatible = "generic-ehci"; + reg = <0x0 0xff5c0000 0x0 0x10000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + + usb_host0_ohci: usb@ff5d0000 { + compatible = "generic-ohci"; + reg = <0x0 0xff5d0000 0x0 0x10000>; + interrupts = ; + clocks = <&cru HCLK_HOST0>, <&u2phy>; + clock-names = "usbhost", "utmi"; + phys = <&u2phy_host>; + phy-names = "usb"; + status = "disabled"; + }; + gic: interrupt-controller@ff811000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -610,6 +991,62 @@ }; }; + pdm-0 { + pdmm0_clk: pdmm0-clk { + rockchip,pins = <2 RK_PC2 2 &pcfg_pull_none>; + }; + + pdmm0_fsync: pdmm0-fsync { + rockchip,pins = <2 RK_PC7 2 &pcfg_pull_none>; + }; + + pdmm0_sdi0: pdmm0-sdi0 { + rockchip,pins = <2 RK_PC3 2 &pcfg_pull_none>; + }; + + pdmm0_sdi1: pdmm0-sdi1 { + rockchip,pins = <2 RK_PC4 2 &pcfg_pull_none>; + }; + + pdmm0_sdi2: pdmm0-sdi2 { + rockchip,pins = <2 RK_PC5 2 &pcfg_pull_none>; + }; + + pdmm0_sdi3: pdmm0-sdi3 { + rockchip,pins = <2 RK_PC6 2 &pcfg_pull_none>; + }; + + pdmm0_clk_sleep: pdmm0-clk-sleep { + rockchip,pins = + <2 RK_PC2 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi0_sleep: pdmm0-sdi0-sleep { + rockchip,pins = + <2 RK_PC3 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi1_sleep: pdmm0-sdi1-sleep { + rockchip,pins = + <2 RK_PC4 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi2_sleep: pdmm0-sdi2-sleep { + rockchip,pins = + <2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_sdi3_sleep: pdmm0-sdi3-sleep { + rockchip,pins = + <2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>; + }; + + pdmm0_fsync_sleep: pdmm0-fsync-sleep { + rockchip,pins = + <2 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>; + }; + }; + tsadc { otp_gpio: otp-gpio { rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi index 4772917c5f7e..a37220a9387c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi @@ -156,7 +156,6 @@ disable-wp; mmc-pwrseq = <&emmc_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts b/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts index e631d424f08e..5e4d3a7015f5 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-geekbox.dts @@ -117,7 +117,6 @@ clock-frequency = <150000000>; disable-wp; non-removable; - num-slots = <1>; vmmc-supply = <&vcc_io>; vqmmc-supply = <&vcc18_flash>; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts index fac116acc12f..d3f6c8e0d206 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts @@ -203,7 +203,6 @@ mmc-hs200-1_2v; mmc-hs200-1_8v; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; status = "okay"; @@ -347,7 +346,6 @@ max-frequency = <50000000>; cap-sd-highspeed; card-detect-delay = <200>; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc_sd>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts index ff48edd8e348..13a9e22f5d2d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-px5-evb.dts @@ -86,12 +86,10 @@ cap-mmc-highspeed; clock-frequency = <150000000>; disable-wp; - keep-power-in-suspend; mmc-hs200-1_8v; no-sdio; no-sd; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_bus8>; vmmc-supply = <&vcc_io>; @@ -281,7 +279,6 @@ card-detect-delay = <200>; no-emmc; no-sdio; - num-slots = <1>; sd-uhs-sdr12; sd-uhs-sdr25; pinctrl-names = "default"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts index 7134181f1dc2..b3510d56517a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts @@ -189,7 +189,6 @@ disable-wp; mmc-pwrseq = <&emmc_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; status = "okay"; @@ -254,7 +253,6 @@ keep-power-in-suspend; mmc-pwrseq = <&sdio_pwrseq>; non-removable; - num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_bus4>; vmmc-supply = <&vcc_io>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 6d5dc0587e59..1070c8264c13 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -700,6 +700,19 @@ interrupts = ; }; + spdif: spdif@ff880000 { + compatible = "rockchip,rk3368-spdif"; + reg = <0x0 0xff880000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF_8CH>, <&cru HCLK_SPDIF>; + clock-names = "mclk", "hclk"; + dmas = <&dmac_bus 3>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_tx>; + status = "disabled"; + }; + i2s_2ch: i2s-2ch@ff890000 { compatible = "rockchip,rk3368-i2s", "rockchip,rk3066-i2s"; reg = <0x0 0xff890000 0x0 0x1000>; @@ -724,6 +737,55 @@ status = "disabled"; }; + iep_mmu: iommu@ff900800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff900800 0x0 0x100>; + interrupts = ; + interrupt-names = "iep_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + isp_mmu: iommu@ff914000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff914000 0x0 0x100>, + <0x0 0xff915000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + + vop_mmu: iommu@ff930300 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff930300 0x0 0x100>; + interrupts = ; + interrupt-names = "vop_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + hevc_mmu: iommu@ff9a0440 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9a0440 0x0 0x40>, + <0x0 0xff9a0480 0x0 0x40>; + interrupts = ; + interrupt-names = "hevc_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vpu_mmu: iommu@ff9a0800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff9a0800 0x0 0x100>; + interrupts = , + ; + interrupt-names = "vepu_mmu", "vdpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + gic: interrupt-controller@ffb71000 { compatible = "arm,gic-400"; interrupt-controller; @@ -1024,6 +1086,12 @@ }; }; + spdif { + spdif_tx: spdif-tx { + rockchip,pins = <2 RK_PC7 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + spi0 { spi0_clk: spi0-clk { rockchip,pins = <1 29 RK_FUNC_2 &pcfg_pull_up>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts index 42033bcc614c..56533c344ef2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb.dts @@ -199,7 +199,7 @@ ep-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_HIGH>; num-lanes = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pcie_clkreqn>; + pinctrl-0 = <&pcie_clkreqn_cpm>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts index ba1d9810ad1e..fef82274a39d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts @@ -43,6 +43,7 @@ /dts-v1/; #include #include "rk3399.dtsi" +#include "rk3399-opp.dtsi" / { model = "Firefly-RK3399 Board"; @@ -370,10 +371,10 @@ regulator-always-on; regulator-boot-on; regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; + regulator-max-microvolt = <3000000>; regulator-state-mem { regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; + regulator-suspend-microvolt = <3000000>; }; }; @@ -550,7 +551,7 @@ ep-gpios = <&gpio4 RK_PD1 GPIO_ACTIVE_HIGH>; num-lanes = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pcie_clkreqn>; + pinctrl-0 = <&pcie_clkreqn_cpm>; status = "okay"; }; @@ -630,9 +631,20 @@ status = "okay"; }; +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + status = "okay"; +}; + &sdhci { bus-width = <8>; - keep-power-in-suspend; mmc-hs400-1_8v; mmc-hs400-enhanced-strobe; non-removable; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts b/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts index 7bd31066399b..a3d3cea7dc4f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts @@ -264,6 +264,50 @@ ap_i2c_dig: &i2c2 { }; }; +&ppvar_bigcpu_pwm { + regulator-min-microvolt = <798674>; + regulator-max-microvolt = <1302172>; +}; + +&ppvar_bigcpu { + regulator-min-microvolt = <798674>; + regulator-max-microvolt = <1302172>; + ctrl-voltage-range = <798674 1302172>; +}; + +&ppvar_litcpu_pwm { + regulator-min-microvolt = <799065>; + regulator-max-microvolt = <1303738>; +}; + +&ppvar_litcpu { + regulator-min-microvolt = <799065>; + regulator-max-microvolt = <1303738>; + ctrl-voltage-range = <799065 1303738>; +}; + +&ppvar_gpu_pwm { + regulator-min-microvolt = <785782>; + regulator-max-microvolt = <1217729>; +}; + +&ppvar_gpu { + regulator-min-microvolt = <785782>; + regulator-max-microvolt = <1217729>; + ctrl-voltage-range = <785782 1217729>; +}; + +&ppvar_centerlogic_pwm { + regulator-min-microvolt = <800069>; + regulator-max-microvolt = <1049692>; +}; + +&ppvar_centerlogic { + regulator-min-microvolt = <800069>; + regulator-max-microvolt = <1049692>; + ctrl-voltage-range = <800069 1049692>; +}; + &saradc { status = "okay"; vref-supply = <&pp1800_ap_io>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi index eb5059344023..199a5118b20d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -164,14 +164,9 @@ vin-supply = <&ppvar_sys>; }; - ppvar_bigcpu: ppvar-bigcpu { + ppvar_bigcpu_pwm: ppvar-bigcpu-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_bigcpu"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_bigcpu_pwm"; pwms = <&pwm1 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -181,18 +176,28 @@ /* EC turns on w/ ap_core_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <798674>; - regulator-max-microvolt = <1302172>; + regulator-min-microvolt = <800107>; + regulator-max-microvolt = <1302232>; }; - ppvar_litcpu: ppvar-litcpu { + ppvar_bigcpu: ppvar-bigcpu { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_bigcpu"; + + regulator-min-microvolt = <800107>; + regulator-max-microvolt = <1302232>; + + ctrl-supply = <&ppvar_bigcpu_pwm>; + ctrl-voltage-range = <800107 1302232>; + + regulator-settling-time-up-us = <322>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; + }; + + ppvar_litcpu_pwm: ppvar-litcpu-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_litcpu"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_litcpu_pwm"; pwms = <&pwm2 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -202,18 +207,28 @@ /* EC turns on w/ ap_core_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <799065>; - regulator-max-microvolt = <1303738>; + regulator-min-microvolt = <797743>; + regulator-max-microvolt = <1307837>; }; - ppvar_gpu: ppvar-gpu { + ppvar_litcpu: ppvar-litcpu { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_litcpu"; + + regulator-min-microvolt = <797743>; + regulator-max-microvolt = <1307837>; + + ctrl-supply = <&ppvar_litcpu_pwm>; + ctrl-voltage-range = <797743 1307837>; + + regulator-settling-time-up-us = <384>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; + }; + + ppvar_gpu_pwm: ppvar-gpu-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_gpu"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_gpu_pwm"; pwms = <&pwm0 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -223,18 +238,28 @@ /* EC turns on w/ ap_core_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <785782>; - regulator-max-microvolt = <1217729>; + regulator-min-microvolt = <786384>; + regulator-max-microvolt = <1217747>; }; - ppvar_centerlogic: ppvar-centerlogic { + ppvar_gpu: ppvar-gpu { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_gpu"; + + regulator-min-microvolt = <786384>; + regulator-max-microvolt = <1217747>; + + ctrl-supply = <&ppvar_gpu_pwm>; + ctrl-voltage-range = <786384 1217747>; + + regulator-settling-time-up-us = <390>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; + }; + + ppvar_centerlogic_pwm: ppvar-centerlogic-pwm { compatible = "pwm-regulator"; - regulator-name = "ppvar_centerlogic"; - /* - * OVP circuit requires special handling which is not yet - * represented. Keep disabled for now. - */ - status = "disabled"; + regulator-name = "ppvar_centerlogic_pwm"; pwms = <&pwm3 0 3337 0>; pwm-supply = <&ppvar_sys>; @@ -244,8 +269,23 @@ /* EC turns on w/ ppvar_centerlogic_en; always on for AP */ regulator-always-on; regulator-boot-on; - regulator-min-microvolt = <800069>; - regulator-max-microvolt = <1049692>; + regulator-min-microvolt = <799434>; + regulator-max-microvolt = <1049925>; + }; + + ppvar_centerlogic: ppvar-centerlogic { + compatible = "vctrl-regulator"; + regulator-name = "ppvar_centerlogic"; + + regulator-min-microvolt = <799434>; + regulator-max-microvolt = <1049925>; + + ctrl-supply = <&ppvar_centerlogic_pwm>; + ctrl-voltage-range = <799434 1049925>; + + regulator-settling-time-up-us = <378>; + min-slew-down-rate = <225>; + ovp-threshold-percent = <16>; }; /* Schematics call this PPVAR even though it's fixed */ @@ -555,6 +595,11 @@ status = "okay"; }; +&gpu { + mali-supply = <&ppvar_gpu>; + status = "okay"; +}; + ap_i2c_mic: &i2c1 { status = "okay"; @@ -567,12 +612,7 @@ ap_i2c_mic: &i2c1 { headsetcodec: rt5514@57 { compatible = "realtek,rt5514"; reg = <0x57>; - interrupt-parent = <&gpio1>; - interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&mic_int>; - realtek,dmic-init-delay = <20>; - wakeup-source; + realtek,dmic-init-delay-ms = <20>; }; }; @@ -781,9 +821,13 @@ ap_i2c_audio: &i2c8 { wacky_spi_audio: spi2@0 { compatible = "realtek,rt5514"; reg = <0>; - + interrupt-parent = <&gpio1>; + interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&mic_int>; /* May run faster once verified. */ spi-max-frequency = <10000000>; + wakeup-source; }; }; @@ -1031,7 +1075,7 @@ ap_i2c_audio: &i2c8 { * hurt and dw_mmc will ignore it. We make sure to disable * the pull though so we don't burn needless power. */ - sdmmc_cd: sdmcc-cd { + sdmmc_cd: sdmmc-cd { rockchip,pins = <0 7 RK_FUNC_1 &pcfg_pull_none>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi index be7fe635f7c1..d8a120f945c8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi @@ -118,6 +118,35 @@ opp-microvolt = <1250000>; }; }; + + gpu_opp_table: opp-table2 { + compatible = "operating-points-v2"; + + opp00 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <800000>; + }; + opp01 { + opp-hz = /bits/ 64 <297000000>; + opp-microvolt = <800000>; + }; + opp02 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <825000>; + }; + opp03 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <850000>; + }; + opp04 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <925000>; + }; + opp05 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1075000>; + }; + }; }; &cpu_l0 { @@ -143,3 +172,7 @@ &cpu_b1 { operating-points-v2 = <&cluster1_opp>; }; + +&gpu { + operating-points-v2 = <&gpu_opp_table>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi index c83460db130a..81617bcf2522 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi @@ -110,6 +110,35 @@ opp-microvolt = <1200000>; }; }; + + gpu_opp_table: opp-table2 { + compatible = "operating-points-v2"; + + opp00 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <800000>; + }; + opp01 { + opp-hz = /bits/ 64 <297000000>; + opp-microvolt = <800000>; + }; + opp02 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <825000>; + }; + opp03 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <875000>; + }; + opp04 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <925000>; + }; + opp05 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1100000>; + }; + }; }; &cpu_l0 { @@ -135,3 +164,7 @@ &cpu_b1 { operating-points-v2 = <&cluster1_opp>; }; + +&gpu { + operating-points-v2 = <&gpu_opp_table>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts new file mode 100644 index 000000000000..9a7486058455 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "rk3399-puma.dtsi" + +/ { + model = "Theobroma Systems RK3399-Q7 SoM"; + compatible = "tsd,rk3399-puma-haikou", "rockchip,rk3399"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + pinctrl-0 = <&led_pin_module>, <&led_sd_haikou>; + + sd-card-led { + label = "sd_card_led"; + gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "mmc0"; + }; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc3v3_baseboard: vcc3v3-baseboard { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_baseboard"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_otg: vcc5v0-otg-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&otg_vbus_drv>; + regulator-name = "vcc5v0_otg"; + regulator-always-on; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2c2 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2c3 { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&i2c4 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2c6 { + status = "okay"; + clock-frequency = <400000>; +}; + +&i2s0 { + status = "okay"; + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + ep-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_LOW>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn_cpm>; + status = "okay"; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&haikou_pin_hog>; + + hog { + haikou_pin_hog: haikou-pin-hog { + rockchip,pins = + /* LID_BTN */ + , + /* BATLOW# */ + , + /* SLP_BTN# */ + , + /* BIOS_DISABLE# */ + ; + }; + }; + + leds { + led_sd_haikou: led-sd-gpio { + rockchip,pins = + ; + }; + }; + + usb2 { + otg_vbus_drv: otg-vbus-drv { + rockchip,pins = + ; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + vmmc-supply = <&vcc3v3_baseboard>; + status = "okay"; +}; + +&spi5 { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + dr_mode = "otg"; + status = "okay"; +}; + +&u2phy0_host { + phy-supply = <&vcc5v0_otg>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi new file mode 100644 index 000000000000..910628d18add --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pin_module>; + + module-led { + label = "module_led"; + gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + panic-indicator; + }; + }; + + /* + * Overwrite the opp-table for CPUB as this board uses a different + * regulator (FAN53555) that only allows 10mV steps and therefore + * can't reach the operation point target voltages from rk3399-opp.dtsi + */ + /delete-node/ opp-table1; + cluster1_opp: opp-table1 { + compatible = "operating-points-v2"; + opp-shared; + + opp00 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <800000>; + clock-latency-ns = <40000>; + }; + opp01 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <800000>; + }; + opp02 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <830000>; + opp-suspend; + }; + opp03 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <880000>; + }; + opp04 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <950000>; + }; + opp05 { + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <1030000>; + }; + opp06 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <1100000>; + }; + opp07 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1200000>; + }; + opp08 { + opp-hz = /bits/ 64 <1992000000>; + opp-microvolt = <1230000>; + turbo-mode; + }; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + vcc1v2_phy: vcc1v2-phy { + compatible = "regulator-fixed"; + regulator-name = "vcc1v2_phy"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; + enable-active-low; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_sys: vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 0>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + status = "okay"; + }; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + clock_in_out = "input"; + phy-supply = <&vcc1v2_phy>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x10>; + rx_delay = <0x10>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + clock-frequency = <400000>; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <22 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc6-supply = <&vcc5v0_sys>; + vcc7-supply = <&vcc5v0_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc5v0_sys>; + vcc10-supply = <&vcc5v0_sys>; + vcc11-supply = <&vcc5v0_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_ldo1: LDO_REG1 { + regulator-name = "vcc_ldo1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_hdmi: LDO_REG2 { + regulator-name = "vcc1v8_hdmi"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sd: LDO_REG4 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_ldo5: LDO_REG5 { + regulator-name = "vcc_ldo5"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ldo6: LDO_REG6 { + regulator-name = "vcc_ldo6"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc0v9_hdmi: LDO_REG7 { + regulator-name = "vcc0v9_hdmi"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_efuse: LDO_REG8 { + regulator-name = "vcc_efuse"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s3: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_gpu: regulator@60 { + compatible = "fcs,fan53555"; + reg = <0x60>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1230000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc5v0_sys>; + }; +}; + +&i2c7 { + status = "okay"; + clock-frequency = <400000>; + + fan: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + cooling-min-state = <0>; + cooling-max-state = <9>; + #cooling-cells = <2>; + }; + + rtc_twi: rtc@6f { + compatible = "isil,isl1208"; + reg = <0x6f>; + }; +}; + +&i2c8 { + status = "okay"; + clock-frequency = <400000>; + + vdd_cpu_b: regulator@60 { + compatible = "fcs,fan53555"; + reg = <0x60>; + vin-supply = <&vcc5v0_sys>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1230000>; + regulator-ramp-delay = <1000>; + fcs,suspend-voltage-selector = <1>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&io_domains { + status = "okay"; + bt656-supply = <&vcc_1v8>; + audio-supply = <&vcc_1v8>; + sdmmc-supply = <&vcc_sd>; + gpio1830-supply = <&vcc_1v8>; +}; + +&pmu_io_domains { + status = "okay"; + pmu1830-supply = <&vcc_1v8>; +}; + +&pwm2 { + status = "okay"; +}; + +&pinctrl { + i2c8 { + i2c8_xfer_a: i2c8-xfer { + rockchip,pins = + , + ; + }; + }; + + leds { + led_pin_module: led-module-gpio { + rockchip,pins = + ; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + ; + }; + }; + + usb2 { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = + ; + }; + }; +}; + +&sdhci { + bus-width = <8>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + status = "okay"; +}; + +&sdmmc { + vqmmc = <&vcc_sd>; +}; + +&spi1 { + status = "okay"; + + norflash: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts new file mode 100644 index 000000000000..b7bd88fb3ae3 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include +#include "rk3399-sapphire.dtsi" + +/ { + model = "Excavator-RK3399 Board"; + compatible = "rockchip,rk3399-sapphire-excavator", "rockchip,rk3399"; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-up { + label = "Volume Up"; + linux,code = ; + press-threshold-microvolt = <100000>; + }; + + button-down { + label = "Volume Down"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + + back { + label = "Back"; + linux,code = ; + press-threshold-microvolt = <985000>; + }; + + menu { + label = "Menu"; + linux,code = ; + press-threshold-microvolt = <1314000>; + }; + }; + + edp_panel: edp-panel { + compatible ="lg,lp079qx1-sp0v", "simple-panel"; + backlight = <&backlight>; + enable-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&lcd_panel_reset>; + power-supply = <&vcc3v3_s0>; + + ports { + panel_in_edp: endpoint { + remote-endpoint = <&edp_out_panel>; + }; + }; + }; + + keys: gpio-keys { + compatible = "gpio-keys"; + autorepeat; + + power { + debounce-interval = <100>; + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + label = "GPIO Power"; + linux,code = ; + linux,input-type = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_btn>; + wakeup-source; + }; + }; + + rt5651-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "realtek,rt5651-codec"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Mic Jack", "MICBIAS1", + "IN1P", "Mic Jack", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + simple-audio-card,cpu { + sound-dai = <&i2s0>; + }; + simple-audio-card,codec { + sound-dai = <&rt5651>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + }; +}; + +&backlight { + enable-gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&edp { + status = "okay"; + + ports { + edp_out: port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + edp_out_panel: endpoint@0 { + reg = <0>; + remote-endpoint = <&panel_in_edp>; + }; + }; + }; +}; + +&i2c1 { + i2c-scl-rising-time-ns = <300>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; + + rt5651: rt5651@1a { + compatible = "rockchip,rt5651"; + reg = <0x1a>; + clocks = <&cru SCLK_I2S_8CH_OUT>; + clock-names = "mclk"; + hp-det-gpio = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>; + spk-con-gpio = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + #sound-dai-cells = <0>; + }; +}; + +&i2c4 { + i2c-scl-rising-time-ns = <600>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + + accelerometer@68 { + compatible = "invensense,mpu6500"; + reg = <0x68>; + interrupt-parent = <&gpio1>; + interrupts = ; + }; +}; + +&i2s0 { + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&i2s2 { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&pinctrl { + buttons { + pwr_btn: pwr-btn { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + lcd-panel { + lcd_panel_reset: lcd-panel-reset { + rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&spdif { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + #sound-dai-cells = <0>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi new file mode 100644 index 000000000000..0f873c897d0d --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi @@ -0,0 +1,644 @@ +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "dt-bindings/pwm/pwm.h" +#include "rk3399.dtsi" +#include "rk3399-opp.dtsi" + +/ { + compatible = "rockchip,rk3399-sapphire", "rockchip,rk3399"; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + pwms = <&pwm0 0 25000 0>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + dc_12v: dc-12v { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + /* switched by pmic_sleep */ + vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8>; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sys>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&dc_12v>; + }; + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host_en>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&emmc_phy { + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + clock_in_out = "input"; + phy-supply = <&vcc_lan>; + phy-mode = "rgmii"; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + tx_delay = <0x28>; + rx_delay = <0x11>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c3>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + status = "okay"; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l &pmic_dvs2>; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc_sys>; + vcc10-supply = <&vcc_sys>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc1v8_pmu>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v8_dvp: LDO_REG1 { + regulator-name = "vcc1v8_dvp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v0_tp: LDO_REG2 { + regulator-name = "vcc3v0_tp"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc1v8_pmu: LDO_REG3 { + regulator-name = "vcc1v8_pmu"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sdio: LDO_REG4 { + regulator-name = "vcc_sdio"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcca3v0_codec: LDO_REG5 { + regulator-name = "vcca3v0_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca1v8_codec: LDO_REG7 { + regulator-name = "vcca1v8_codec"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: vcc_lan: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; + + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: regulator@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + vin-supply = <&vcc_sys>; + }; +}; + +&i2c3 { + i2c-scl-rising-time-ns = <450>; + i2c-scl-falling-time-ns = <15>; + status = "okay"; +}; + +&io_domains { + status = "okay"; + + bt656-supply = <&vcc_3v0>; + audio-supply = <&vcca1v8_codec>; + sdmmc-supply = <&vcc_sdio>; + gpio1830-supply = <&vcc_3v0>; +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + assigned-clocks = <&cru SCLK_PCIEPHY_REF>; + assigned-clock-parents = <&cru SCLK_PCIEPHY_REF100M>; + assigned-clock-rates = <100000000>; + ep-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_HIGH>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn_cpm>; + status = "okay"; +}; + +&pmu_io_domains { + pmu1830-supply = <&vcc_3v0>; + status = "okay"; +}; + +&pinctrl { + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + pmic_dvs2: pmic-dvs2 { + rockchip,pins = + <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel1_gpio: vsel1-gpio { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_gpio: vsel2-gpio { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + usb2 { + vcc5v0_host_en: vcc5v0-host-en { + rockchip,pins = + <4 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca1v8_s3>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + keep-power-in-suspend; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + status = "okay"; +}; + +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + clock-frequency = <50000000>; + disable-wp; + keep-power-in-suspend; + max-frequency = <50000000>; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + clock-frequency = <150000000>; + disable-wp; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + vqmmc-supply = <&vcc_sdio>; + status = "okay"; +}; + +&tsadc { + /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-mode = <1>; + /* tshut polarity 0:LOW 1:HIGH */ + rockchip,hw-tshut-polarity = <1>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts>; + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + status = "okay"; + dr_mode = "otg"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + status = "okay"; + dr_mode = "host"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 69c56f7316c4..ab7629c5b856 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -110,6 +110,7 @@ enable-method = "psci"; #cooling-cells = <2>; /* min followed by max */ clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_l1: cpu@1 { @@ -118,6 +119,7 @@ reg = <0x0 0x1>; enable-method = "psci"; clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_l2: cpu@2 { @@ -126,6 +128,7 @@ reg = <0x0 0x2>; enable-method = "psci"; clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_l3: cpu@3 { @@ -134,6 +137,7 @@ reg = <0x0 0x3>; enable-method = "psci"; clocks = <&cru ARMCLKL>; + dynamic-power-coefficient = <100>; }; cpu_b0: cpu@100 { @@ -143,6 +147,7 @@ enable-method = "psci"; #cooling-cells = <2>; /* min followed by max */ clocks = <&cru ARMCLKB>; + dynamic-power-coefficient = <436>; }; cpu_b1: cpu@101 { @@ -151,9 +156,15 @@ reg = <0x0 0x101>; enable-method = "psci"; clocks = <&cru ARMCLKB>; + dynamic-power-coefficient = <436>; }; }; + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <&vopl_out>, <&vopb_out>; + }; + pmu_a53 { compatible = "arm,cortex-a53-pmu"; interrupts = ; @@ -238,8 +249,10 @@ linux,pci-domain = <0>; max-link-speed = <1>; msi-map = <0x0 &its 0x0 0x1000>; - phys = <&pcie_phy>; - phy-names = "pcie-phy"; + phys = <&pcie_phy 0>, <&pcie_phy 1>, + <&pcie_phy 2>, <&pcie_phy 3>; + phy-names = "pcie-phy-0", "pcie-phy-1", + "pcie-phy-2", "pcie-phy-3"; ranges = <0x83000000 0x0 0xfa000000 0x0 0xfa000000 0x0 0x1e00000 0x81000000 0x0 0xfbe00000 0x0 0xfbe00000 0x0 0x100000>; resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, @@ -287,6 +300,7 @@ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; resets = <&cru SRST_SDIO0>; reset-names = "reset"; status = "disabled"; @@ -400,6 +414,7 @@ snps,dis-u2-freeclk-exists-quirk; snps,dis_u2_susphy_quirk; snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; status = "disabled"; }; }; @@ -427,6 +442,7 @@ snps,dis-u2-freeclk-exists-quirk; snps,dis_u2_susphy_quirk; snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; status = "disabled"; }; }; @@ -676,6 +692,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&spi5_clk &spi5_tx &spi5_rx &spi5_cs0>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -948,6 +965,10 @@ }; /* These power domains are grouped by VD_LOGIC */ + pd_edp@RK3399_PD_EDP { + reg = ; + clocks = <&cru PCLK_EDP_CTRL>; + }; pd_emmc@RK3399_PD_EMMC { reg = ; clocks = <&cru ACLK_EMMC>; @@ -965,6 +986,11 @@ <&cru SCLK_SDMMC>; pm_qos = <&qos_sd>; }; + pd_sdioaudio@RK3399_PD_SDIOAUDIO { + reg = ; + clocks = <&cru HCLK_SDIO>; + pm_qos = <&qos_sdioaudio>; + }; pd_vio@RK3399_PD_VIO { reg = ; #address-cells = <1>; @@ -1151,6 +1177,33 @@ status = "disabled"; }; + vpu_mmu: iommu@ff650800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff650800 0x0 0x40>; + interrupts = ; + interrupt-names = "vpu_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + vdec_mmu: iommu@ff660480 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff660480 0x0 0x40>, <0x0 0xff6604c0 0x0 0x40>; + interrupts = ; + interrupt-names = "vdec_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + + iep_mmu: iommu@ff670800 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff670800 0x0 0x40>; + interrupts = ; + interrupt-names = "iep_mmu"; + #iommu-cells = <0>; + status = "disabled"; + }; + efuse0: efuse@ff690000 { compatible = "rockchip,rk3399-efuse"; reg = <0x0 0xff690000 0x0 0x80>; @@ -1295,7 +1348,7 @@ compatible = "rockchip,rk3399-pcie-phy"; clocks = <&cru SCLK_PCIEPHY_REF>; clock-names = "refclk"; - #phy-cells = <0>; + #phy-cells = <1>; resets = <&cru SRST_PCIEPHY>; reset-names = "phy"; status = "disabled"; @@ -1385,6 +1438,7 @@ clocks = <&cru SCLK_SPDIF_8CH>, <&cru HCLK_SPDIF>; pinctrl-names = "default"; pinctrl-0 = <&spdif_bus>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; status = "disabled"; }; @@ -1399,6 +1453,7 @@ clocks = <&cru SCLK_I2S0_8CH>, <&cru HCLK_I2S0_8CH>; pinctrl-names = "default"; pinctrl-0 = <&i2s0_8ch_bus>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; status = "disabled"; }; @@ -1412,6 +1467,7 @@ clocks = <&cru SCLK_I2S1_8CH>, <&cru HCLK_I2S1_8CH>; pinctrl-names = "default"; pinctrl-0 = <&i2s1_2ch_bus>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; status = "disabled"; }; @@ -1423,6 +1479,224 @@ dma-names = "tx", "rx"; clock-names = "i2s_clk", "i2s_hclk"; clocks = <&cru SCLK_I2S2_8CH>, <&cru HCLK_I2S2_8CH>; + power-domains = <&power RK3399_PD_SDIOAUDIO>; + status = "disabled"; + }; + + vopl: vop@ff8f0000 { + compatible = "rockchip,rk3399-vop-lit"; + reg = <0x0 0xff8f0000 0x0 0x3efc>; + interrupts = ; + assigned-clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>; + assigned-clock-rates = <400000000>, <100000000>; + clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + iommus = <&vopl_mmu>; + power-domains = <&power RK3399_PD_VOPL>; + resets = <&cru SRST_A_VOP1>, <&cru SRST_H_VOP1>, <&cru SRST_D_VOP1>; + reset-names = "axi", "ahb", "dclk"; + status = "disabled"; + + vopl_out: port { + #address-cells = <1>; + #size-cells = <0>; + + vopl_out_mipi: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_in_vopl>; + }; + + vopl_out_edp: endpoint@1 { + reg = <1>; + remote-endpoint = <&edp_in_vopl>; + }; + + vopl_out_hdmi: endpoint@2 { + reg = <2>; + remote-endpoint = <&hdmi_in_vopl>; + }; + }; + }; + + vopl_mmu: iommu@ff8f3f00 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff8f3f00 0x0 0x100>; + interrupts = ; + interrupt-names = "vopl_mmu"; + clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>; + clock-names = "aclk", "hclk"; + power-domains = <&power RK3399_PD_VOPL>; + #iommu-cells = <0>; + status = "disabled"; + }; + + vopb: vop@ff900000 { + compatible = "rockchip,rk3399-vop-big"; + reg = <0x0 0xff900000 0x0 0x3efc>; + interrupts = ; + assigned-clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>; + assigned-clock-rates = <400000000>, <100000000>; + clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + iommus = <&vopb_mmu>; + power-domains = <&power RK3399_PD_VOPB>; + resets = <&cru SRST_A_VOP0>, <&cru SRST_H_VOP0>, <&cru SRST_D_VOP0>; + reset-names = "axi", "ahb", "dclk"; + status = "disabled"; + + vopb_out: port { + #address-cells = <1>; + #size-cells = <0>; + + vopb_out_edp: endpoint@0 { + reg = <0>; + remote-endpoint = <&edp_in_vopb>; + }; + + vopb_out_mipi: endpoint@1 { + reg = <1>; + remote-endpoint = <&mipi_in_vopb>; + }; + + vopb_out_hdmi: endpoint@2 { + reg = <2>; + remote-endpoint = <&hdmi_in_vopb>; + }; + }; + }; + + vopb_mmu: iommu@ff903f00 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff903f00 0x0 0x100>; + interrupts = ; + interrupt-names = "vopb_mmu"; + clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>; + clock-names = "aclk", "hclk"; + power-domains = <&power RK3399_PD_VOPB>; + #iommu-cells = <0>; + status = "disabled"; + }; + + isp0_mmu: iommu@ff914000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff914000 0x0 0x100>, <0x0 0xff915000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp0_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + + isp1_mmu: iommu@ff924000 { + compatible = "rockchip,iommu"; + reg = <0x0 0xff924000 0x0 0x100>, <0x0 0xff925000 0x0 0x100>; + interrupts = ; + interrupt-names = "isp1_mmu"; + #iommu-cells = <0>; + rockchip,disable-mmu-reset; + status = "disabled"; + }; + + hdmi: hdmi@ff940000 { + compatible = "rockchip,rk3399-dw-hdmi"; + reg = <0x0 0xff940000 0x0 0x20000>; + interrupts = ; + clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_SFR>, <&cru PLL_VPLL>, <&cru PCLK_VIO_GRF>; + clock-names = "iahb", "isfr", "vpll", "grf"; + power-domains = <&power RK3399_PD_HDCP>; + reg-io-width = <4>; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_hdmi>; + }; + hdmi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_hdmi>; + }; + }; + }; + }; + + mipi_dsi: mipi@ff960000 { + compatible = "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi"; + reg = <0x0 0xff960000 0x0 0x8000>; + interrupts = ; + clocks = <&cru SCLK_DPHY_PLL>, <&cru PCLK_MIPI_DSI0>, + <&cru SCLK_DPHY_TX0_CFG>, <&cru PCLK_VIO_GRF>; + clock-names = "ref", "pclk", "phy_cfg", "grf"; + power-domains = <&power RK3399_PD_VIO>; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + mipi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_mipi>; + }; + mipi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_mipi>; + }; + }; + }; + }; + + edp: edp@ff970000 { + compatible = "rockchip,rk3399-edp"; + reg = <0x0 0xff970000 0x0 0x8000>; + interrupts = ; + clocks = <&cru PCLK_EDP>, <&cru PCLK_EDP_CTRL>; + clock-names = "dp", "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&edp_hpd>; + power-domains = <&power RK3399_PD_EDP>; + resets = <&cru SRST_P_EDP_CTRL>; + reset-names = "dp"; + rockchip,grf = <&grf>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + edp_in: port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + edp_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_edp>; + }; + + edp_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_edp>; + }; + }; + }; + }; + + gpu: gpu@ff9a0000 { + compatible = "rockchip,rk3399-mali", "arm,mali-t860"; + reg = <0x0 0xff9a0000 0x0 0x10000>; + interrupts = , + , + ; + interrupt-names = "gpu", "job", "mmu"; + clocks = <&cru ACLK_GPU>; + power-domains = <&power RK3399_PD_GPU>; status = "disabled"; }; @@ -1786,7 +2060,7 @@ <4 RK_PB5 RK_FUNC_1 &pcfg_pull_up>; }; - sdmmc_cd: sdmcc-cd { + sdmmc_cd: sdmmc-cd { rockchip,pins = <0 RK_PA7 RK_FUNC_1 &pcfg_pull_up>; }; @@ -2090,16 +2364,6 @@ }; pcie { - pcie_clkreqn: pci-clkreqn { - rockchip,pins = - <2 26 RK_FUNC_2 &pcfg_pull_none>; - }; - - pcie_clkreqnb: pci-clkreqnb { - rockchip,pins = - <4 24 RK_FUNC_1 &pcfg_pull_none>; - }; - pcie_clkreqn_cpm: pci-clkreqn-cpm { rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; diff --git a/arch/arm64/boot/dts/socionext/Makefile b/arch/arm64/boot/dts/socionext/Makefile index 4a13a3a97101..72dbe8acd9fd 100644 --- a/arch/arm64/boot/dts/socionext/Makefile +++ b/arch/arm64/boot/dts/socionext/Makefile @@ -1,8 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ld11-global.dtb \ uniphier-ld11-ref.dtb \ uniphier-ld20-global.dtb \ - uniphier-ld20-ref.dtb + uniphier-ld20-ref.dtb \ + uniphier-pxs3-ref.dtb always := $(dtb-y) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts index 115357018ef7..2452b2243f42 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "uniphier-ld11.dtsi" +#include "uniphier-ld11.dtsi" / { model = "UniPhier LD11 Global Board (REF_LD11_GP)"; @@ -68,3 +68,7 @@ &usb2 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts index cc8ebe34c27c..ffb473ad2e0f 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld11.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld11.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD11 Reference Board"; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi index bdce5b89baec..09c429cb6d61 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi @@ -150,6 +150,17 @@ clocks = <&peri_clk 3>; }; + adamv@57920000 { + compatible = "socionext,uniphier-ld11-adamv", + "simple-mfd", "syscon"; + reg = <0x57920000 0x1000>; + + adamv_rst: reset { + compatible = "socionext,uniphier-ld11-adamv-reset"; + #reset-cells = <1>; + }; + }; + i2c0: i2c@58780000 { compatible = "socionext,uniphier-fi2c"; status = "disabled"; @@ -288,7 +299,8 @@ interrupts = <0 243 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0>; - clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>, + <&mio_clk 12>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>, <&mio_rst 12>; }; @@ -300,7 +312,8 @@ interrupts = <0 244 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1>; - clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>, + <&mio_clk 13>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>, <&mio_rst 13>; }; @@ -312,7 +325,8 @@ interrupts = <0 245 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb2>; - clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>; + clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 10>, + <&mio_clk 14>; resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>, <&mio_rst 14>; }; @@ -344,6 +358,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-ld11-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gic: interrupt-controller@5fe00000 { compatible = "arm,gic-v3"; reg = <0x5fe00000 0x10000>, /* GICD */ @@ -367,8 +388,23 @@ compatible = "socionext,uniphier-ld11-reset"; #reset-cells = <1>; }; + + watchdog { + compatible = "socionext,uniphier-wdt"; + }; + }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts index 9f620d4101b5..fc2bc9d75d35 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts @@ -9,7 +9,7 @@ */ /dts-v1/; -/include/ "uniphier-ld20.dtsi" +#include "uniphier-ld20.dtsi" / { model = "UniPhier LD20 Global Board (REF_LD20_GP)"; @@ -50,3 +50,7 @@ &i2c0 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts index 494166aee24c..1ca0c8620dc5 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20-ref.dts @@ -8,9 +8,9 @@ */ /dts-v1/; -/include/ "uniphier-ld20.dtsi" -/include/ "uniphier-ref-daughter.dtsi" -/include/ "uniphier-support-card.dtsi" +#include "uniphier-ld20.dtsi" +#include "uniphier-ref-daughter.dtsi" +#include "uniphier-support-card.dtsi" / { model = "UniPhier LD20 Reference Board"; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi index de1e75362817..a29c279b6e8e 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi @@ -219,6 +219,17 @@ clocks = <&peri_clk 3>; }; + adamv@57920000 { + compatible = "socionext,uniphier-ld20-adamv", + "simple-mfd", "syscon"; + reg = <0x57920000 0x1000>; + + adamv_rst: reset { + compatible = "socionext,uniphier-ld20-adamv-reset"; + #reset-cells = <1>; + }; + }; + i2c0: i2c@58780000 { compatible = "socionext,uniphier-fi2c"; status = "disabled"; @@ -309,7 +320,7 @@ sdctrl@59810000 { compatible = "socionext,uniphier-ld20-sdctrl", "simple-mfd", "syscon"; - reg = <0x59810000 0x800>; + reg = <0x59810000 0x400>; sd_clk: clock { compatible = "socionext,uniphier-ld20-sd-clock"; @@ -365,6 +376,13 @@ }; }; + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-ld20-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + gic: interrupt-controller@5fe00000 { compatible = "arm,gic-v3"; reg = <0x5fe00000 0x10000>, /* GICD */ @@ -388,8 +406,23 @@ compatible = "socionext,uniphier-ld20-reset"; #reset-cells = <1>; }; + + watchdog { + compatible = "socionext,uniphier-wdt"; + }; + }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; }; }; }; -/include/ "uniphier-pinctrl.dtsi" +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi deleted file mode 120000 index f42fb6f38bd3..000000000000 --- a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/uniphier-pinctrl.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi new file mode 100644 index 000000000000..9caabbb8bae3 --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-pinctrl.dtsi @@ -0,0 +1 @@ +#include diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts new file mode 100644 index 000000000000..d65f746a3f9d --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3-ref.dts @@ -0,0 +1,62 @@ +/* + * Device Tree Source for UniPhier PXs3 Reference Board + * + * Copyright (C) 2017 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; +#include "uniphier-pxs3.dtsi" +#include "uniphier-support-card.dtsi" + +/ { + model = "UniPhier PXs3 Reference Board"; + compatible = "socionext,uniphier-pxs3-ref", "socionext,uniphier-pxs3"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + serial3 = &serial3; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c6 = &i2c6; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0 0x80000000 0 0xa0000000>; + }; +}; + +ðsc { + interrupts = <0 52 4>; +}; + +&serial0 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi new file mode 100644 index 000000000000..384729fa740f --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi @@ -0,0 +1,367 @@ +/* + * Device Tree Source for UniPhier PXs3 SoC + * + * Copyright (C) 2017 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/memreserve/ 0x80000000 0x02000000; + +/ { + compatible = "socionext,uniphier-pxs3"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + core2 { + cpu = <&cpu2>; + }; + core3 { + cpu = <&cpu3>; + }; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x000>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x001>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x002>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0 0x003>; + clocks = <&sys_clk 33>; + enable-method = "psci"; + operating-points-v2 = <&cluster0_opp>; + }; + }; + + cluster0_opp: opp_table { + compatible = "operating-points-v2"; + opp-shared; + + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + clock-latency-ns = <300>; + }; + opp-325000000 { + opp-hz = /bits/ 64 <325000000>; + clock-latency-ns = <300>; + }; + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + clock-latency-ns = <300>; + }; + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + clock-latency-ns = <300>; + }; + opp-666667000 { + opp-hz = /bits/ 64 <666667000>; + clock-latency-ns = <300>; + }; + opp-866667000 { + opp-hz = /bits/ 64 <866667000>; + clock-latency-ns = <300>; + }; + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + clock-latency-ns = <300>; + }; + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + clock-latency-ns = <300>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + clocks { + refclk: ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 4>, + <1 14 4>, + <1 11 4>, + <1 10 4>; + }; + + soc@0 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + + serial0: serial@54006800 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006800 0x40>; + interrupts = <0 33 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; + clocks = <&peri_clk 0>; + }; + + serial1: serial@54006900 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006900 0x40>; + interrupts = <0 35 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + clocks = <&peri_clk 1>; + }; + + serial2: serial@54006a00 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006a00 0x40>; + interrupts = <0 37 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + clocks = <&peri_clk 2>; + }; + + serial3: serial@54006b00 { + compatible = "socionext,uniphier-uart"; + status = "disabled"; + reg = <0x54006b00 0x40>; + interrupts = <0 177 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + clocks = <&peri_clk 3>; + }; + + i2c0: i2c@58780000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58780000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 41 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c0>; + clocks = <&peri_clk 4>; + clock-frequency = <100000>; + }; + + i2c1: i2c@58781000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58781000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 42 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + clocks = <&peri_clk 5>; + clock-frequency = <100000>; + }; + + i2c2: i2c@58782000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58782000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 43 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clocks = <&peri_clk 6>; + clock-frequency = <100000>; + }; + + i2c3: i2c@58783000 { + compatible = "socionext,uniphier-fi2c"; + status = "disabled"; + reg = <0x58783000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 44 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clocks = <&peri_clk 7>; + clock-frequency = <100000>; + }; + + /* chip-internal connection for HDMI */ + i2c6: i2c@58786000 { + compatible = "socionext,uniphier-fi2c"; + reg = <0x58786000 0x80>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <0 26 4>; + clocks = <&peri_clk 10>; + clock-frequency = <400000>; + }; + + system_bus: system-bus@58c00000 { + compatible = "socionext,uniphier-system-bus"; + status = "disabled"; + reg = <0x58c00000 0x400>; + #address-cells = <2>; + #size-cells = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_system_bus>; + }; + + smpctrl@59801000 { + compatible = "socionext,uniphier-smpctrl"; + reg = <0x59801000 0x400>; + }; + + sdctrl@59810000 { + compatible = "socionext,uniphier-pxs3-sdctrl", + "simple-mfd", "syscon"; + reg = <0x59810000 0x400>; + + sd_clk: clock { + compatible = "socionext,uniphier-pxs3-sd-clock"; + #clock-cells = <1>; + }; + + sd_rst: reset { + compatible = "socionext,uniphier-pxs3-sd-reset"; + #reset-cells = <1>; + }; + }; + + perictrl@59820000 { + compatible = "socionext,uniphier-pxs3-perictrl", + "simple-mfd", "syscon"; + reg = <0x59820000 0x200>; + + peri_clk: clock { + compatible = "socionext,uniphier-pxs3-peri-clock"; + #clock-cells = <1>; + }; + + peri_rst: reset { + compatible = "socionext,uniphier-pxs3-peri-reset"; + #reset-cells = <1>; + }; + }; + + emmc: sdhc@5a000000 { + compatible = "socionext,uniphier-sd4hc", "cdns,sd4hc"; + reg = <0x5a000000 0x400>; + interrupts = <0 78 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_emmc>; + clocks = <&sys_clk 4>; + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + cdns,phy-input-delay-legacy = <4>; + cdns,phy-input-delay-mmc-highspeed = <2>; + cdns,phy-input-delay-mmc-ddr = <3>; + cdns,phy-dll-delay-sdclk = <21>; + cdns,phy-dll-delay-sdclk-hsmmc = <21>; + }; + + soc-glue@5f800000 { + compatible = "socionext,uniphier-pxs3-soc-glue", + "simple-mfd", "syscon"; + reg = <0x5f800000 0x2000>; + + pinctrl: pinctrl { + compatible = "socionext,uniphier-pxs3-pinctrl"; + }; + }; + + aidet: aidet@5fc20000 { + compatible = "socionext,uniphier-pxs3-aidet"; + reg = <0x5fc20000 0x200>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gic: interrupt-controller@5fe00000 { + compatible = "arm,gic-v3"; + reg = <0x5fe00000 0x10000>, /* GICD */ + <0x5fe80000 0x80000>; /* GICR */ + interrupt-controller; + #interrupt-cells = <3>; + interrupts = <1 9 4>; + }; + + sysctrl@61840000 { + compatible = "socionext,uniphier-pxs3-sysctrl", + "simple-mfd", "syscon"; + reg = <0x61840000 0x10000>; + + sys_clk: clock { + compatible = "socionext,uniphier-pxs3-clock"; + #clock-cells = <1>; + }; + + sys_rst: reset { + compatible = "socionext,uniphier-pxs3-reset"; + #reset-cells = <1>; + }; + + watchdog { + compatible = "socionext,uniphier-wdt"; + }; + }; + + nand: nand@68000000 { + compatible = "socionext,uniphier-denali-nand-v5b"; + status = "disabled"; + reg-names = "nand_data", "denali_reg"; + reg = <0x68000000 0x20>, <0x68100000 0x1000>; + interrupts = <0 65 4>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + clocks = <&sys_clk 2>; + }; + }; +}; + +#include "uniphier-pinctrl.dtsi" diff --git a/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi deleted file mode 120000 index 4685a8d89cba..000000000000 --- a/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/uniphier-ref-daughter.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi new file mode 100644 index 000000000000..e66d999d9f5d --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-ref-daughter.dtsi @@ -0,0 +1 @@ +#include diff --git a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi deleted file mode 120000 index 1246db9be2a1..000000000000 --- a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi +++ /dev/null @@ -1 +0,0 @@ -../../../../arm/boot/dts/uniphier-support-card.dtsi \ No newline at end of file diff --git a/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi new file mode 100644 index 000000000000..28c5b4ed1d95 --- /dev/null +++ b/arch/arm64/boot/dts/socionext/uniphier-support-card.dtsi @@ -0,0 +1 @@ +#include diff --git a/arch/arm64/boot/dts/sprd/Makefile b/arch/arm64/boot/dts/sprd/Makefile index f0535e6eaaaa..d7188be103c5 100644 --- a/arch/arm64/boot/dts/sprd/Makefile +++ b/arch/arm64/boot/dts/sprd/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_SPRD) += sc9836-openphone.dtb \ sp9860g-1h10.dtb diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi index cdc6a437dcc7..b87b8316f4ac 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi @@ -11,7 +11,7 @@ * the License, or (at your option) any later version. */ -&amba { +/ { misc_clk: misc_clk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -29,12 +29,60 @@ #clock-cells = <0>; clock-frequency = <75000000>; }; + + clk100: clk100 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; + + clk600: clk600 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <600000000>; + }; }; &can0 { clocks = <&misc_clk &misc_clk>; }; +&can1 { + clocks = <&misc_clk &misc_clk>; +}; + +&fpd_dma_chan1 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan2 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan3 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan4 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan5 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan6 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan7 { + clocks = <&clk600>, <&clk100>; +}; + +&fpd_dma_chan8 { + clocks = <&clk600>, <&clk100>; +}; + &gem0 { clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts index ef1b9e573af0..bf552674a834 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts @@ -13,13 +13,15 @@ /dts-v1/; -/include/ "zynqmp.dtsi" -/include/ "zynqmp-ep108-clk.dtsi" +#include "zynqmp.dtsi" +#include "zynqmp-ep108-clk.dtsi" / { model = "ZynqMP EP108"; aliases { + mmc0 = &sdhci0; + mmc1 = &sdhci1; serial0 = &uart0; }; @@ -37,6 +39,10 @@ status = "okay"; }; +&can1 { + status = "okay"; +}; + &gem0 { status = "okay"; phy-handle = <&phy0>; @@ -55,7 +61,7 @@ status = "okay"; clock-frequency = <400000>; eeprom@54 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; reg = <0x54>; }; }; @@ -64,7 +70,7 @@ status = "okay"; clock-frequency = <400000>; eeprom@55 { - compatible = "at,24c64"; + compatible = "atmel,24c64"; reg = <0x55>; }; }; @@ -92,7 +98,7 @@ spi-max-frequency = <50000000>; reg = <0>; - spi0_flash0@00000000 { + spi0_flash0@0 { label = "spi0_flash0"; reg = <0x0 0x100000>; }; @@ -109,7 +115,7 @@ spi-max-frequency = <50000000>; reg = <0>; - spi1_flash0@00000000 { + spi1_flash0@0 { label = "spi1_flash0"; reg = <0x0 0x100000>; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 54dc28351c8c..7665fbddff28 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -20,33 +20,84 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + cpu0: cpu@0 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; + operating-points-v2 = <&cpu_opp_table>; reg = <0x0>; + cpu-idle-states = <&CPU_SLEEP_0>; }; - cpu@1 { + cpu1: cpu@1 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x1>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; }; - cpu@2 { + cpu2: cpu@2 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x2>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; }; - cpu@3 { + cpu3: cpu@3 { compatible = "arm,cortex-a53", "arm,armv8"; device_type = "cpu"; enable-method = "psci"; reg = <0x3>; + operating-points-v2 = <&cpu_opp_table>; + cpu-idle-states = <&CPU_SLEEP_0>; }; + + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x40000000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <600>; + min-residency-us = <10000>; + }; + }; + }; + + cpu_opp_table: cpu_opp_table { + compatible = "operating-points-v2"; + opp-shared; + opp00 { + opp-hz = /bits/ 64 <1199999988>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp01 { + opp-hz = /bits/ 64 <599999994>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp02 { + opp-hz = /bits/ 64 <399999996>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + opp03 { + opp-hz = /bits/ 64 <299999997>; + opp-microvolt = <1000000>; + clock-latency-ns = <500000>; + }; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "disabled"; }; pmu { @@ -119,6 +170,190 @@ rx-fifo-depth = <0x40>; }; + cci: cci@fd6e0000 { + compatible = "arm,cci-400"; + reg = <0x0 0xfd6e0000 0x0 0x9000>; + ranges = <0x0 0x0 0xfd6e0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + + pmu@9000 { + compatible = "arm,cci-400-pmu,r1"; + reg = <0x9000 0x5000>; + interrupt-parent = <&gic>; + interrupts = <0 123 4>, + <0 123 4>, + <0 123 4>, + <0 123 4>, + <0 123 4>; + }; + }; + + /* GDMA */ + fpd_dma_chan1: dma@fd500000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd500000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 124 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan2: dma@fd510000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd510000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 125 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan3: dma@fd520000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd520000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 126 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan4: dma@fd530000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd530000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 127 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan5: dma@fd540000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd540000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 128 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan6: dma@fd550000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd550000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 129 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan7: dma@fd560000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd560000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 130 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + fpd_dma_chan8: dma@fd570000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xfd570000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 131 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <128>; + }; + + /* LPDDMA default allows only secured access. inorder to enable + * These dma channels, Users should ensure that these dma + * Channels are allowed for non secure access. + */ + lpd_dma_chan1: dma@ffa80000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffa80000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 77 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan2: dma@ffa90000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffa90000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 78 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan3: dma@ffaa0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffaa0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 79 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan4: dma@ffab0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffab0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 80 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan5: dma@ffac0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffac0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 81 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan6: dma@ffad0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffad0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 82 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan7: dma@ffae0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffae0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 83 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + + lpd_dma_chan8: dma@ffaf0000 { + status = "disabled"; + compatible = "xlnx,zynqmp-dma-1.0"; + reg = <0x0 0xffaf0000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 84 4>; + clock-names = "clk_main", "clk_apb"; + xlnx,bus-width = <64>; + }; + gem0: ethernet@ff0b0000 { compatible = "cdns,gem"; status = "disabled"; @@ -215,12 +450,9 @@ <0x0 0xfd480000 0x0 0x1000>, <0x80 0x00000000 0x0 0x1000000>; reg-names = "breg", "pcireg", "cfg"; - ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 - 0xe0000000 0x00000000 0x10000000 - /* non-prefetchable memory */ - 0x43000000 0x00000006 0x00000000 0x00000006 - 0x00000000 0x00000002 0x00000000>; - /* prefetchable memory */ + ranges = <0x02000000 0x00000000 0xe0000000 0x00000000 0xe0000000 0x00000000 0x10000000 /* non-prefetchable memory */ + 0x43000000 0x00000006 0x00000000 0x00000006 0x00000000 0x00000002 0x00000000>;/* prefetchable memory */ + bus-range = <0x00 0xff>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>, <0x0 0x0 0x0 0x2 &pcie_intc 0x2>, @@ -233,6 +465,16 @@ }; }; + rtc: rtc@ffa60000 { + compatible = "xlnx,zynqmp-rtc"; + status = "disabled"; + reg = <0x0 0xffa60000 0x0 0x100>; + interrupt-parent = <&gic>; + interrupts = <0 26 4>, <0 27 4>; + interrupt-names = "alarm", "sec"; + calibration = <0x8000>; + }; + sata: ahci@fd0c0000 { compatible = "ceva,ahci-1v84"; status = "disabled"; @@ -262,13 +504,14 @@ smmu: smmu@fd800000 { compatible = "arm,mmu-500"; reg = <0x0 0xfd800000 0x0 0x20000>; + status = "disabled"; #global-interrupts = <1>; interrupt-parent = <&gic>; - interrupts = <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>, - <0 157 4>, <0 157 4>, <0 157 4>, <0 157 4>; + interrupts = <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>, + <0 155 4>, <0 155 4>, <0 155 4>, <0 155 4>; }; spi0: spi@ff040000 { @@ -330,7 +573,7 @@ }; uart0: serial@ff000000 { - compatible = "cdns,uart-r1p8"; + compatible = "cdns,uart-r1p12", "xlnx,xuartps"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 21 4>; @@ -339,7 +582,7 @@ }; uart1: serial@ff010000 { - compatible = "cdns,uart-r1p8"; + compatible = "cdns,uart-r1p12", "xlnx,xuartps"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 22 4>; diff --git a/arch/arm64/boot/dts/zte/Makefile b/arch/arm64/boot/dts/zte/Makefile index 667806620f59..d86c4def6bc9 100644 --- a/arch/arm64/boot/dts/zte/Makefile +++ b/arch/arm64/boot/dts/zte/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_ZX) += zx296718-evb.dtb +dtb-$(CONFIG_ARCH_ZX) += zx296718-pcbox.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/zte/zx296718-evb.dts b/arch/arm64/boot/dts/zte/zx296718-evb.dts index bb900d2bbcfb..cb2519ecd724 100644 --- a/arch/arm64/boot/dts/zte/zx296718-evb.dts +++ b/arch/arm64/boot/dts/zte/zx296718-evb.dts @@ -57,16 +57,28 @@ reg = <0x40000000 0x40000000>; }; - sound0 { - compatible = "simple-audio-card"; - simple-audio-card,name = "zx_snd_spdif0"; + sound-spdif0 { + compatible = "audio-graph-card"; + dais = <&spdif0_port>; + }; - simple-audio-card,cpu { - sound-dai = <&spdif0>; - }; + sound-i2s0 { + compatible = "audio-graph-card"; + dais = <&i2s0_port>; + pinctrl-names = "default"; + pinctrl-0 = <&lifier_pins>; + pa-gpios = <&bgpio4 0 GPIO_ACTIVE_HIGH>; + widgets = "Line", "Line Out Jack"; + routing = "Amplifier", "LINEOUTL", + "Amplifier", "LINEOUTR", + "Line Out Jack", "Amplifier"; + }; +}; - simple-audio-card,codec { - sound-dai = <&hdmi>; +&aud96p22 { + port { + aud96p22_endpoint: endpoint { + remote-endpoint = <&i2s0_endpoint>; }; }; }; @@ -77,6 +89,36 @@ &hdmi { status = "okay"; + + port { + hdmi_endpoint: endpoint { + remote-endpoint = <&spdif0_endpoint>; + }; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2s0 { + status = "okay"; + + i2s0_port: port { + i2s0_endpoint: endpoint { + remote-endpoint = <&aud96p22_endpoint>; + dai-format = "i2s"; + frame-master; + bitclock-master; + }; + }; +}; + +&pmm { + amplifier_pins: amplifier { + pins = "TSI3_DATA"; + function = "BGPIO"; + }; }; &sd1 { @@ -85,6 +127,16 @@ &spdif0 { status = "okay"; + + spdif0_port: port { + spdif0_endpoint: endpoint { + remote-endpoint = <&hdmi_endpoint>; + }; + }; +}; + +&tvenc { + status = "okay"; }; &uart0 { diff --git a/arch/arm64/boot/dts/zte/zx296718-pcbox.dts b/arch/arm64/boot/dts/zte/zx296718-pcbox.dts new file mode 100644 index 000000000000..e02509f7082b --- /dev/null +++ b/arch/arm64/boot/dts/zte/zx296718-pcbox.dts @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2017 Sanechips Technology Co., Ltd. + * Copyright 2017 Linaro Ltd. + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; +#include "zx296718.dtsi" +#include + +/ { + model = "ZTE ZX296718 PCBOX Board"; + compatible = "zte,zx296718-pcbox", "zte,zx296718"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + a53_vdd0v9: regulator-a53 { + compatible = "pwm-regulator"; + pwms = <&pwm 3 1250 PWM_POLARITY_INVERTED>; + regulator-name = "A53_VDD0V9"; + regulator-min-microvolt = <855000>; + regulator-max-microvolt = <1183000>; + pwm-dutycycle-unit = <100>; + pwm-dutycycle-range = <0 100>; + regulator-always-on; + regulator-boot-on; + }; + + sound-spdif0 { + compatible = "audio-graph-card"; + dais = <&spdif0_port>; + }; + + sound-i2s0 { + compatible = "audio-graph-card"; + dais = <&i2s0_port>; + }; +}; + +&aud96p22 { + port { + aud96p22_endpoint: endpoint { + remote-endpoint = <&i2s0_endpoint>; + }; + }; +}; + +&cpu0 { + cpu-supply = <&a53_vdd0v9>; +}; + +&emmc { + status = "okay"; +}; + +&hdmi { + status = "disabled"; + + port { + hdmi_endpoint: endpoint { + remote-endpoint = <&spdif0_endpoint>; + }; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2s0 { + status = "okay"; + + i2s0_port: port { + i2s0_endpoint: endpoint { + remote-endpoint = <&aud96p22_endpoint>; + dai-format = "i2s"; + frame-master; + bitclock-master; + }; + }; +}; + +&irdec { + status = "okay"; +}; + +&pmm { + pwm3_pins: pwm3 { + pins = "KEY_ROW2"; + function = "PWM"; + }; + + vga_pins: vga { + pins = "KEY_COL1", "KEY_COL2", "VGA_HS", "VGA_VS"; + function = "VGA"; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_pins>; + status = "okay"; +}; + +&sd0 { + status = "okay"; +}; + +&sd1 { + status = "okay"; +}; + +&spdif0 { + status = "okay"; + + spdif0_port: port { + spdif0_endpoint: endpoint { + remote-endpoint = <&hdmi_endpoint>; + }; + }; +}; + +&tvenc { + status = "disabled"; +}; + +&uart0 { + status = "okay"; +}; + +&vga { + pinctrl-names = "default"; + pinctrl-0 = <&vga_pins>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/zte/zx296718.dtsi b/arch/arm64/boot/dts/zte/zx296718.dtsi index d83bf789c864..6eef64761009 100644 --- a/arch/arm64/boot/dts/zte/zx296718.dtsi +++ b/arch/arm64/boot/dts/zte/zx296718.dtsi @@ -53,6 +53,13 @@ interrupt-parent = <&gic>; aliases { + gpio0 = &bgpio0; + gpio1 = &bgpio1; + gpio2 = &bgpio2; + gpio3 = &bgpio3; + gpio4 = &bgpio4; + gpio5 = &bgpio5; + gpio6 = &bgpio6; serial0 = &uart0; }; @@ -120,26 +127,31 @@ opp-500000000 { opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <866000>; clock-latency-ns = <500000>; }; opp-648000000 { opp-hz = /bits/ 64 <648000000>; + opp-microvolt = <866000>; clock-latency-ns = <500000>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <888000>; clock-latency-ns = <500000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <898000>; clock-latency-ns = <500000>; }; opp-1188000000 { opp-hz = /bits/ 64 <1188000000>; + opp-microvolt = <1015000>; clock-latency-ns = <500000>; }; }; @@ -283,11 +295,23 @@ compatible = "simple-bus"; ranges; + irdec: ir-decoder@111000 { + compatible = "zte,zx296718-irdec"; + reg = <0x111000 0x1000>; + interrupts = ; + status = "disabled"; + }; + aon_sysctrl: aon-sysctrl@116000 { compatible = "zte,zx296718-aon-sysctrl", "syscon"; reg = <0x116000 0x1000>; }; + iocfg: pin-controller@119000 { + compatible = "zte,zx296718-iocfg"; + reg = <0x119000 0x1000>; + }; + uart0: uart@11f000 { compatible = "arm,pl011", "arm,primecell"; arm,primecell-periphid = <0x001feffe>; @@ -311,7 +335,6 @@ clock-frequency = <50000000>; clocks = <&topcrm SD0_AHB>, <&topcrm SD0_WCLK>; clock-names = "biu", "ciu"; - num-slots = <1>; max-frequency = <50000000>; cap-sdio-irq; cap-sd-highspeed; @@ -336,7 +359,6 @@ clock-frequency = <167000000>; clocks = <&topcrm SD1_AHB>, <&topcrm SD1_WCLK>; clock-names = "biu", "ciu"; - num-slots = <1>; max-frequency = <167000000>; cap-sdio-irq; cap-sd-highspeed; @@ -360,12 +382,109 @@ #clock-cells = <1>; }; + bgpio0: gpio@142d000 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d000 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 48 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio1: gpio@142d040 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d040 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 80 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio2: gpio@142d080 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d080 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 80 3 + &pmm 3 32 4 + &pmm 7 83 9>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio3: gpio@142d0c0 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d0c0 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 92 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio4: gpio@142d100 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d100 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 108 12 + &pmm 12 121 4>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio5: gpio@142d140 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d140 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 125 16>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + bgpio6: gpio@142d180 { + compatible = "zte,zx296718-gpio", "zte,zx296702-gpio"; + reg = <0x142d180 0x40>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pmm 0 141 2>; + interrupts = ; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <2>; + }; + lsp1crm: clock-controller@1430000 { compatible = "zte,zx296718-lsp1crm"; reg = <0x01430000 0x1000>; #clock-cells = <1>; }; + pwm: pwm@1439000 { + compatible = "zte,zx296718-pwm"; + reg = <0x1439000 0x1000>; + clocks = <&lsp1crm LSP1_PWM_PCLK>, + <&lsp1crm LSP1_PWM_WCLK>; + clock-names = "pclk", "wclk"; + #pwm-cells = <3>; + status = "disabled"; + }; + vou: vou@1440000 { compatible = "zte,zx296718-vou"; #address-cells = <1>; @@ -387,6 +506,16 @@ "main_wclk", "aux_wclk"; }; + vga: vga@8000 { + compatible = "zte,zx296718-vga"; + reg = <0x8000 0x1000>; + interrupts = ; + clocks = <&topcrm VGA_I2C_WCLK>; + clock-names = "i2c_wclk"; + zte,vga-power-control = <&sysctrl 0x170 0xe0>; + status = "disabled"; + }; + hdmi: hdmi@c000 { compatible = "zte,zx296718-hdmi"; reg = <0xc000 0x4000>; @@ -413,6 +542,12 @@ #clock-cells = <1>; }; + pmm: pin-controller@1462000 { + compatible = "zte,zx296718-pmm"; + reg = <0x1462000 0x1000>; + zte,auxiliary-controller = <&iocfg>; + }; + sysctrl: sysctrl@1463000 { compatible = "zte,zx296718-sysctrl", "syscon"; reg = <0x1463000 0x1000>; @@ -445,6 +580,38 @@ #clock-cells = <1>; }; + i2s0: i2s@1482000 { + compatible = "zte,zx296718-i2s", "zte,zx296702-i2s"; + reg = <0x01482000 0x1000>; + clocks = <&audiocrm AUDIO_I2S0_WCLK>, + <&audiocrm AUDIO_I2S0_PCLK>; + clock-names = "wclk", "pclk"; + assigned-clocks = <&audiocrm I2S0_WCLK_MUX>; + assigned-clock-parents = <&topcrm AUDIO_99M>; + interrupts = ; + dmas = <&dma 22>, <&dma 23>; + dma-names = "tx", "rx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2c0: i2c@1486000 { + compatible = "zte,zx296718-i2c"; + reg = <0x01486000 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&audiocrm AUDIO_I2C0_WCLK>; + clock-frequency = <1600000>; + status = "disabled"; + + aud96p22: codec@22 { + compatible = "zte,zx-aud96p22"; + #sound-dai-cells = <0>; + reg = <0x22>; + }; + }; + spdif0: spdif@1488000 { compatible = "zte,zx296702-spdif"; reg = <0x1488000 0x1000>; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index b4ca115b3be1..34480e9af2e7 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -3,6 +3,7 @@ CONFIG_POSIX_MQUEUE=y CONFIG_AUDIT=y CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y +CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y @@ -68,6 +69,7 @@ CONFIG_HOTPLUG_PCI_ACPI=y CONFIG_PCI_LAYERSCAPE=y CONFIG_PCI_HISI=y CONFIG_PCIE_QCOM=y +CONFIG_PCIE_KIRIN=y CONFIG_PCIE_ARMADA_8K=y CONFIG_PCI_AARDVARK=y CONFIG_PCIE_RCAR=y @@ -88,6 +90,7 @@ CONFIG_XEN=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_HIBERNATION=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y CONFIG_CPUFREQ_DT=y @@ -164,6 +167,7 @@ CONFIG_EEPROM_AT25=m CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_HISI_SAS=y +CONFIG_SCSI_HISI_SAS_PCI=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y @@ -203,6 +207,7 @@ CONFIG_MARVELL_PHY=m CONFIG_MESON_GXL_PHY=m CONFIG_MICREL_PHY=y CONFIG_REALTEK_PHY=m +CONFIG_ROCKCHIP_PHY=y CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m CONFIG_USB_RTL8152=m @@ -250,6 +255,8 @@ CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y CONFIG_SERIAL_MVEBU_UART=y +CONFIG_SERIAL_DEV_BUS=y +CONFIG_SERIAL_DEV_CTRL_TTYPORT=y CONFIG_VIRTIO_CONSOLE=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y @@ -279,6 +286,7 @@ CONFIG_SPI_ROCKCHIP=y CONFIG_SPI_S3C64XX=y CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y +CONFIG_PINCTRL_IPQ8074=y CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_MAX77620=y CONFIG_PINCTRL_MSM8916=y @@ -297,6 +305,7 @@ CONFIG_GPIO_MAX77620=y CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y +CONFIG_SYSCON_REBOOT_MODE=y CONFIG_BATTERY_BQ27XXX=y CONFIG_SENSORS_ARM_SCPI=y CONFIG_SENSORS_LM90=m @@ -304,6 +313,7 @@ CONFIG_SENSORS_INA2XX=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y CONFIG_THERMAL_EMULATION=y +CONFIG_BRCMSTB_THERMAL=m CONFIG_EXYNOS_THERMAL=y CONFIG_ROCKCHIP_THERMAL=m CONFIG_WATCHDOG=y @@ -311,19 +321,24 @@ CONFIG_S3C2410_WATCHDOG=y CONFIG_MESON_GXBB_WATCHDOG=m CONFIG_MESON_WATCHDOG=m CONFIG_RENESAS_WDT=y +CONFIG_UNIPHIER_WATCHDOG=y CONFIG_BCM2835_WDT=y +CONFIG_MFD_AXP20X_RSB=y CONFIG_MFD_CROS_EC=y CONFIG_MFD_CROS_EC_I2C=y CONFIG_MFD_CROS_EC_SPI=y CONFIG_MFD_EXYNOS_LPASS=m +CONFIG_MFD_HI6421_PMIC=y CONFIG_MFD_HI655X_PMIC=y CONFIG_MFD_MAX77620=y CONFIG_MFD_SPMI_PMIC=y CONFIG_MFD_RK808=y CONFIG_MFD_SEC_CORE=y +CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_HI6421V530=y CONFIG_REGULATOR_HI655X=y CONFIG_REGULATOR_MAX77620=y CONFIG_REGULATOR_PWM=y @@ -358,6 +373,12 @@ CONFIG_DRM_EXYNOS_DSI=y # CONFIG_DRM_EXYNOS_DP is not set CONFIG_DRM_EXYNOS_HDMI=y CONFIG_DRM_EXYNOS_MIC=y +CONFIG_DRM_ROCKCHIP=m +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_CDN_DP=y +CONFIG_ROCKCHIP_DW_HDMI=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_ROCKCHIP_INNO_HDMI=y CONFIG_DRM_RCAR_DU=m CONFIG_DRM_RCAR_LVDS=y CONFIG_DRM_RCAR_VSP=y @@ -370,6 +391,7 @@ CONFIG_DRM_MESON=m CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_BACKLIGHT_GENERIC=m +CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_LP855X=m CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y @@ -380,8 +402,8 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_BCM2835_SOC_I2S=m CONFIG_SND_SOC_SAMSUNG=y -CONFIG_SND_SOC_RCAR=y -CONFIG_SND_SOC_AK4613=y +CONFIG_SND_SOC_RCAR=m +CONFIG_SND_SOC_AK4613=m CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_OTG=y @@ -403,6 +425,7 @@ CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y CONFIG_USB_HSIC_USB3503=y +CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_OTG=y CONFIG_USB_QCOM_8X16_PHY=y CONFIG_USB_ULPI=y @@ -451,6 +474,7 @@ CONFIG_RTC_DRV_TEGRA=y CONFIG_RTC_DRV_XGENE=y CONFIG_DMADEVICES=y CONFIG_DMA_BCM2835=m +CONFIG_K3_DMA=y CONFIG_MV_XOR_V2=y CONFIG_PL330_DMA=y CONFIG_TEGRA20_APB_DMA=y @@ -473,6 +497,7 @@ CONFIG_CLK_QORIQ=y CONFIG_COMMON_CLK_PWM=y CONFIG_COMMON_CLK_QCOM=y CONFIG_QCOM_CLK_SMD_RPM=y +CONFIG_IPQ_GCC_8074=y CONFIG_MSM_GCC_8916=y CONFIG_MSM_GCC_8994=y CONFIG_MSM_MMCC_8996=y @@ -482,6 +507,7 @@ CONFIG_ARM_MHU=y CONFIG_PLATFORM_MHU=y CONFIG_BCM2835_MBOX=y CONFIG_HI6220_MBOX=y +CONFIG_ROCKCHIP_IOMMU=y CONFIG_ARM_SMMU=y CONFIG_ARM_SMMU_V3=y CONFIG_RPMSG_QCOM_SMD=y @@ -515,6 +541,8 @@ CONFIG_PHY_XGENE=y CONFIG_PHY_TEGRA_XUSB=y CONFIG_QCOM_L2_PMU=y CONFIG_QCOM_L3_PMU=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_EFI_CAPSULE_LOADER=y @@ -563,8 +591,17 @@ CONFIG_SECURITY=y CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA256_ARM64=m +CONFIG_CRYPTO_SHA512_ARM64=m CONFIG_CRYPTO_SHA1_ARM64_CE=y CONFIG_CRYPTO_SHA2_ARM64_CE=y CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m +CONFIG_CRYPTO_CRC32_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64=m +CONFIG_CRYPTO_AES_ARM64_CE=m CONFIG_CRYPTO_AES_ARM64_CE_CCM=y CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m +CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_CRYPTO_AES_ARM64_BS=m diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig index d92293747d63..70c517aa4501 100644 --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig ARM64_CRYPTO bool "ARM64 Accelerated Cryptographic Algorithms" @@ -18,18 +19,23 @@ config CRYPTO_SHA512_ARM64 config CRYPTO_SHA1_ARM64_CE tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_HASH + select CRYPTO_SHA1 config CRYPTO_SHA2_ARM64_CE tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_HASH + select CRYPTO_SHA256_ARM64 config CRYPTO_GHASH_ARM64_CE - tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + tristate "GHASH/AES-GCM using ARMv8 Crypto Extensions" + depends on KERNEL_MODE_NEON select CRYPTO_HASH + select CRYPTO_GF128MUL + select CRYPTO_AES + select CRYPTO_AES_ARM64 config CRYPTO_CRCT10DIF_ARM64_CE tristate "CRCT10DIF digest algorithm using PMULL instructions" @@ -49,25 +55,29 @@ config CRYPTO_AES_ARM64_CE tristate "AES core cipher using ARMv8 Crypto Extensions" depends on ARM64 && KERNEL_MODE_NEON select CRYPTO_ALGAPI + select CRYPTO_AES_ARM64 config CRYPTO_AES_ARM64_CE_CCM tristate "AES in CCM mode using ARMv8 Crypto Extensions" depends on ARM64 && KERNEL_MODE_NEON select CRYPTO_ALGAPI select CRYPTO_AES_ARM64_CE + select CRYPTO_AES_ARM64 select CRYPTO_AEAD config CRYPTO_AES_ARM64_CE_BLK tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64_CE + select CRYPTO_AES_ARM64 select CRYPTO_SIMD config CRYPTO_AES_ARM64_NEON_BLK tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions" - depends on ARM64 && KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON select CRYPTO_BLKCIPHER + select CRYPTO_AES_ARM64 select CRYPTO_AES select CRYPTO_SIMD @@ -82,6 +92,7 @@ config CRYPTO_AES_ARM64_BS depends on KERNEL_MODE_NEON select CRYPTO_BLKCIPHER select CRYPTO_AES_ARM64_NEON_BLK + select CRYPTO_AES_ARM64 select CRYPTO_SIMD endif diff --git a/arch/arm64/crypto/aes-ce-ccm-core.S b/arch/arm64/crypto/aes-ce-ccm-core.S index 3363560c79b7..e3a375c4cb83 100644 --- a/arch/arm64/crypto/aes-ce-ccm-core.S +++ b/arch/arm64/crypto/aes-ce-ccm-core.S @@ -1,7 +1,7 @@ /* * aesce-ccm-core.S - AES-CCM transform for ARMv8 with Crypto Extensions * - * Copyright (C) 2013 - 2014 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -32,7 +32,7 @@ ENTRY(ce_aes_ccm_auth_data) beq 8f /* out of input? */ cbnz w8, 0b eor v0.16b, v0.16b, v1.16b -1: ld1 {v3.16b}, [x4] /* load first round key */ +1: ld1 {v3.4s}, [x4] /* load first round key */ prfm pldl1strm, [x1] cmp w5, #12 /* which key size? */ add x6, x4, #16 @@ -42,17 +42,17 @@ ENTRY(ce_aes_ccm_auth_data) mov v5.16b, v3.16b b 4f 2: mov v4.16b, v3.16b - ld1 {v5.16b}, [x6], #16 /* load 2nd round key */ + ld1 {v5.4s}, [x6], #16 /* load 2nd round key */ 3: aese v0.16b, v4.16b aesmc v0.16b, v0.16b -4: ld1 {v3.16b}, [x6], #16 /* load next round key */ +4: ld1 {v3.4s}, [x6], #16 /* load next round key */ aese v0.16b, v5.16b aesmc v0.16b, v0.16b -5: ld1 {v4.16b}, [x6], #16 /* load next round key */ +5: ld1 {v4.4s}, [x6], #16 /* load next round key */ subs w7, w7, #3 aese v0.16b, v3.16b aesmc v0.16b, v0.16b - ld1 {v5.16b}, [x6], #16 /* load next round key */ + ld1 {v5.4s}, [x6], #16 /* load next round key */ bpl 3b aese v0.16b, v4.16b subs w2, w2, #16 /* last data? */ @@ -90,7 +90,7 @@ ENDPROC(ce_aes_ccm_auth_data) * u32 rounds); */ ENTRY(ce_aes_ccm_final) - ld1 {v3.16b}, [x2], #16 /* load first round key */ + ld1 {v3.4s}, [x2], #16 /* load first round key */ ld1 {v0.16b}, [x0] /* load mac */ cmp w3, #12 /* which key size? */ sub w3, w3, #2 /* modified # of rounds */ @@ -100,17 +100,17 @@ ENTRY(ce_aes_ccm_final) mov v5.16b, v3.16b b 2f 0: mov v4.16b, v3.16b -1: ld1 {v5.16b}, [x2], #16 /* load next round key */ +1: ld1 {v5.4s}, [x2], #16 /* load next round key */ aese v0.16b, v4.16b aesmc v0.16b, v0.16b aese v1.16b, v4.16b aesmc v1.16b, v1.16b -2: ld1 {v3.16b}, [x2], #16 /* load next round key */ +2: ld1 {v3.4s}, [x2], #16 /* load next round key */ aese v0.16b, v5.16b aesmc v0.16b, v0.16b aese v1.16b, v5.16b aesmc v1.16b, v1.16b -3: ld1 {v4.16b}, [x2], #16 /* load next round key */ +3: ld1 {v4.4s}, [x2], #16 /* load next round key */ subs w3, w3, #3 aese v0.16b, v3.16b aesmc v0.16b, v0.16b @@ -137,31 +137,31 @@ CPU_LE( rev x8, x8 ) /* keep swabbed ctr in reg */ cmp w4, #12 /* which key size? */ sub w7, w4, #2 /* get modified # of rounds */ ins v1.d[1], x9 /* no carry in lower ctr */ - ld1 {v3.16b}, [x3] /* load first round key */ + ld1 {v3.4s}, [x3] /* load first round key */ add x10, x3, #16 bmi 1f bne 4f mov v5.16b, v3.16b b 3f 1: mov v4.16b, v3.16b - ld1 {v5.16b}, [x10], #16 /* load 2nd round key */ + ld1 {v5.4s}, [x10], #16 /* load 2nd round key */ 2: /* inner loop: 3 rounds, 2x interleaved */ aese v0.16b, v4.16b aesmc v0.16b, v0.16b aese v1.16b, v4.16b aesmc v1.16b, v1.16b -3: ld1 {v3.16b}, [x10], #16 /* load next round key */ +3: ld1 {v3.4s}, [x10], #16 /* load next round key */ aese v0.16b, v5.16b aesmc v0.16b, v0.16b aese v1.16b, v5.16b aesmc v1.16b, v1.16b -4: ld1 {v4.16b}, [x10], #16 /* load next round key */ +4: ld1 {v4.4s}, [x10], #16 /* load next round key */ subs w7, w7, #3 aese v0.16b, v3.16b aesmc v0.16b, v0.16b aese v1.16b, v3.16b aesmc v1.16b, v1.16b - ld1 {v5.16b}, [x10], #16 /* load next round key */ + ld1 {v5.4s}, [x10], #16 /* load next round key */ bpl 2b aese v0.16b, v4.16b aese v1.16b, v4.16b diff --git a/arch/arm64/crypto/aes-ce-ccm-glue.c b/arch/arm64/crypto/aes-ce-ccm-glue.c index 6a7dbc7c83a6..a1254036f2b1 100644 --- a/arch/arm64/crypto/aes-ce-ccm-glue.c +++ b/arch/arm64/crypto/aes-ce-ccm-glue.c @@ -1,7 +1,7 @@ /* * aes-ccm-glue.c - AES-CCM transform for ARMv8 with Crypto Extensions * - * Copyright (C) 2013 - 2014 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -44,6 +45,8 @@ asmlinkage void ce_aes_ccm_decrypt(u8 out[], u8 const in[], u32 cbytes, asmlinkage void ce_aes_ccm_final(u8 mac[], u8 const ctr[], u32 const rk[], u32 rounds); +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); + static int ccm_setkey(struct crypto_aead *tfm, const u8 *in_key, unsigned int key_len) { @@ -103,7 +106,45 @@ static int ccm_init_mac(struct aead_request *req, u8 maciv[], u32 msglen) return 0; } -static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) +static void ccm_update_mac(struct crypto_aes_ctx *key, u8 mac[], u8 const in[], + u32 abytes, u32 *macp, bool use_neon) +{ + if (likely(use_neon)) { + ce_aes_ccm_auth_data(mac, in, abytes, macp, key->key_enc, + num_rounds(key)); + } else { + if (*macp > 0 && *macp < AES_BLOCK_SIZE) { + int added = min(abytes, AES_BLOCK_SIZE - *macp); + + crypto_xor(&mac[*macp], in, added); + + *macp += added; + in += added; + abytes -= added; + } + + while (abytes > AES_BLOCK_SIZE) { + __aes_arm64_encrypt(key->key_enc, mac, mac, + num_rounds(key)); + crypto_xor(mac, in, AES_BLOCK_SIZE); + + in += AES_BLOCK_SIZE; + abytes -= AES_BLOCK_SIZE; + } + + if (abytes > 0) { + __aes_arm64_encrypt(key->key_enc, mac, mac, + num_rounds(key)); + crypto_xor(mac, in, abytes); + *macp = abytes; + } else { + *macp = 0; + } + } +} + +static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[], + bool use_neon) { struct crypto_aead *aead = crypto_aead_reqtfm(req); struct crypto_aes_ctx *ctx = crypto_aead_ctx(aead); @@ -122,8 +163,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) ltag.len = 6; } - ce_aes_ccm_auth_data(mac, (u8 *)<ag, ltag.len, &macp, ctx->key_enc, - num_rounds(ctx)); + ccm_update_mac(ctx, mac, (u8 *)<ag, ltag.len, &macp, use_neon); scatterwalk_start(&walk, req->src); do { @@ -135,8 +175,7 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) n = scatterwalk_clamp(&walk, len); } p = scatterwalk_map(&walk); - ce_aes_ccm_auth_data(mac, p, n, &macp, ctx->key_enc, - num_rounds(ctx)); + ccm_update_mac(ctx, mac, p, n, &macp, use_neon); len -= n; scatterwalk_unmap(p); @@ -145,6 +184,56 @@ static void ccm_calculate_auth_mac(struct aead_request *req, u8 mac[]) } while (len); } +static int ccm_crypt_fallback(struct skcipher_walk *walk, u8 mac[], u8 iv0[], + struct crypto_aes_ctx *ctx, bool enc) +{ + u8 buf[AES_BLOCK_SIZE]; + int err = 0; + + while (walk->nbytes) { + int blocks = walk->nbytes / AES_BLOCK_SIZE; + u32 tail = walk->nbytes % AES_BLOCK_SIZE; + u8 *dst = walk->dst.virt.addr; + u8 *src = walk->src.virt.addr; + u32 nbytes = walk->nbytes; + + if (nbytes == walk->total && tail > 0) { + blocks++; + tail = 0; + } + + do { + u32 bsize = AES_BLOCK_SIZE; + + if (nbytes < AES_BLOCK_SIZE) + bsize = nbytes; + + crypto_inc(walk->iv, AES_BLOCK_SIZE); + __aes_arm64_encrypt(ctx->key_enc, buf, walk->iv, + num_rounds(ctx)); + __aes_arm64_encrypt(ctx->key_enc, mac, mac, + num_rounds(ctx)); + if (enc) + crypto_xor(mac, src, bsize); + crypto_xor_cpy(dst, src, buf, bsize); + if (!enc) + crypto_xor(mac, dst, bsize); + dst += bsize; + src += bsize; + nbytes -= bsize; + } while (--blocks); + + err = skcipher_walk_done(walk, tail); + } + + if (!err) { + __aes_arm64_encrypt(ctx->key_enc, buf, iv0, num_rounds(ctx)); + __aes_arm64_encrypt(ctx->key_enc, mac, mac, num_rounds(ctx)); + crypto_xor(mac, buf, AES_BLOCK_SIZE); + } + return err; +} + static int ccm_encrypt(struct aead_request *req) { struct crypto_aead *aead = crypto_aead_reqtfm(req); @@ -153,39 +242,46 @@ static int ccm_encrypt(struct aead_request *req) u8 __aligned(8) mac[AES_BLOCK_SIZE]; u8 buf[AES_BLOCK_SIZE]; u32 len = req->cryptlen; + bool use_neon = may_use_simd(); int err; err = ccm_init_mac(req, mac, len); if (err) return err; - kernel_neon_begin_partial(6); + if (likely(use_neon)) + kernel_neon_begin(); if (req->assoclen) - ccm_calculate_auth_mac(req, mac); + ccm_calculate_auth_mac(req, mac, use_neon); /* preserve the original iv for the final round */ memcpy(buf, req->iv, AES_BLOCK_SIZE); err = skcipher_walk_aead_encrypt(&walk, req, true); - while (walk.nbytes) { - u32 tail = walk.nbytes % AES_BLOCK_SIZE; + if (likely(use_neon)) { + while (walk.nbytes) { + u32 tail = walk.nbytes % AES_BLOCK_SIZE; - if (walk.nbytes == walk.total) - tail = 0; + if (walk.nbytes == walk.total) + tail = 0; - ce_aes_ccm_encrypt(walk.dst.virt.addr, walk.src.virt.addr, - walk.nbytes - tail, ctx->key_enc, - num_rounds(ctx), mac, walk.iv); + ce_aes_ccm_encrypt(walk.dst.virt.addr, + walk.src.virt.addr, + walk.nbytes - tail, ctx->key_enc, + num_rounds(ctx), mac, walk.iv); - err = skcipher_walk_done(&walk, tail); + err = skcipher_walk_done(&walk, tail); + } + if (!err) + ce_aes_ccm_final(mac, buf, ctx->key_enc, + num_rounds(ctx)); + + kernel_neon_end(); + } else { + err = ccm_crypt_fallback(&walk, mac, buf, ctx, true); } - if (!err) - ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx)); - - kernel_neon_end(); - if (err) return err; @@ -205,38 +301,46 @@ static int ccm_decrypt(struct aead_request *req) u8 __aligned(8) mac[AES_BLOCK_SIZE]; u8 buf[AES_BLOCK_SIZE]; u32 len = req->cryptlen - authsize; + bool use_neon = may_use_simd(); int err; err = ccm_init_mac(req, mac, len); if (err) return err; - kernel_neon_begin_partial(6); + if (likely(use_neon)) + kernel_neon_begin(); if (req->assoclen) - ccm_calculate_auth_mac(req, mac); + ccm_calculate_auth_mac(req, mac, use_neon); /* preserve the original iv for the final round */ memcpy(buf, req->iv, AES_BLOCK_SIZE); err = skcipher_walk_aead_decrypt(&walk, req, true); - while (walk.nbytes) { - u32 tail = walk.nbytes % AES_BLOCK_SIZE; + if (likely(use_neon)) { + while (walk.nbytes) { + u32 tail = walk.nbytes % AES_BLOCK_SIZE; - if (walk.nbytes == walk.total) - tail = 0; + if (walk.nbytes == walk.total) + tail = 0; - ce_aes_ccm_decrypt(walk.dst.virt.addr, walk.src.virt.addr, - walk.nbytes - tail, ctx->key_enc, - num_rounds(ctx), mac, walk.iv); + ce_aes_ccm_decrypt(walk.dst.virt.addr, + walk.src.virt.addr, + walk.nbytes - tail, ctx->key_enc, + num_rounds(ctx), mac, walk.iv); - err = skcipher_walk_done(&walk, tail); + err = skcipher_walk_done(&walk, tail); + } + if (!err) + ce_aes_ccm_final(mac, buf, ctx->key_enc, + num_rounds(ctx)); + + kernel_neon_end(); + } else { + err = ccm_crypt_fallback(&walk, mac, buf, ctx, false); } - if (!err) - ce_aes_ccm_final(mac, buf, ctx->key_enc, num_rounds(ctx)); - - kernel_neon_end(); if (err) return err; diff --git a/arch/arm64/crypto/aes-ce-cipher.c b/arch/arm64/crypto/aes-ce-cipher.c index 50d9fe11d0c8..6a75cd75ed11 100644 --- a/arch/arm64/crypto/aes-ce-cipher.c +++ b/arch/arm64/crypto/aes-ce-cipher.c @@ -1,7 +1,7 @@ /* * aes-ce-cipher.c - core AES cipher using ARMv8 Crypto Extensions * - * Copyright (C) 2013 - 2014 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,8 @@ */ #include +#include +#include #include #include #include @@ -20,6 +22,9 @@ MODULE_DESCRIPTION("Synchronous AES cipher using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); +asmlinkage void __aes_arm64_decrypt(u32 *rk, u8 *out, const u8 *in, int rounds); + struct aes_block { u8 b[AES_BLOCK_SIZE]; }; @@ -44,27 +49,32 @@ static void aes_cipher_encrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[]) void *dummy0; int dummy1; - kernel_neon_begin_partial(4); + if (!may_use_simd()) { + __aes_arm64_encrypt(ctx->key_enc, dst, src, num_rounds(ctx)); + return; + } + + kernel_neon_begin(); __asm__(" ld1 {v0.16b}, %[in] ;" - " ld1 {v1.16b}, [%[key]], #16 ;" + " ld1 {v1.4s}, [%[key]], #16 ;" " cmp %w[rounds], #10 ;" " bmi 0f ;" " bne 3f ;" " mov v3.16b, v1.16b ;" " b 2f ;" "0: mov v2.16b, v1.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" "1: aese v0.16b, v2.16b ;" " aesmc v0.16b, v0.16b ;" - "2: ld1 {v1.16b}, [%[key]], #16 ;" + "2: ld1 {v1.4s}, [%[key]], #16 ;" " aese v0.16b, v3.16b ;" " aesmc v0.16b, v0.16b ;" - "3: ld1 {v2.16b}, [%[key]], #16 ;" + "3: ld1 {v2.4s}, [%[key]], #16 ;" " subs %w[rounds], %w[rounds], #3 ;" " aese v0.16b, v1.16b ;" " aesmc v0.16b, v0.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" " bpl 1b ;" " aese v0.16b, v2.16b ;" " eor v0.16b, v0.16b, v3.16b ;" @@ -89,27 +99,32 @@ static void aes_cipher_decrypt(struct crypto_tfm *tfm, u8 dst[], u8 const src[]) void *dummy0; int dummy1; - kernel_neon_begin_partial(4); + if (!may_use_simd()) { + __aes_arm64_decrypt(ctx->key_dec, dst, src, num_rounds(ctx)); + return; + } + + kernel_neon_begin(); __asm__(" ld1 {v0.16b}, %[in] ;" - " ld1 {v1.16b}, [%[key]], #16 ;" + " ld1 {v1.4s}, [%[key]], #16 ;" " cmp %w[rounds], #10 ;" " bmi 0f ;" " bne 3f ;" " mov v3.16b, v1.16b ;" " b 2f ;" "0: mov v2.16b, v1.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" "1: aesd v0.16b, v2.16b ;" " aesimc v0.16b, v0.16b ;" - "2: ld1 {v1.16b}, [%[key]], #16 ;" + "2: ld1 {v1.4s}, [%[key]], #16 ;" " aesd v0.16b, v3.16b ;" " aesimc v0.16b, v0.16b ;" - "3: ld1 {v2.16b}, [%[key]], #16 ;" + "3: ld1 {v2.4s}, [%[key]], #16 ;" " subs %w[rounds], %w[rounds], #3 ;" " aesd v0.16b, v1.16b ;" " aesimc v0.16b, v0.16b ;" - " ld1 {v3.16b}, [%[key]], #16 ;" + " ld1 {v3.4s}, [%[key]], #16 ;" " bpl 1b ;" " aesd v0.16b, v2.16b ;" " eor v0.16b, v0.16b, v3.16b ;" @@ -165,20 +180,16 @@ int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, key_len != AES_KEYSIZE_256) return -EINVAL; - memcpy(ctx->key_enc, in_key, key_len); ctx->key_length = key_len; + for (i = 0; i < kwords; i++) + ctx->key_enc[i] = get_unaligned_le32(in_key + i * sizeof(u32)); - kernel_neon_begin_partial(2); + kernel_neon_begin(); for (i = 0; i < sizeof(rcon); i++) { u32 *rki = ctx->key_enc + (i * kwords); u32 *rko = rki + kwords; -#ifndef CONFIG_CPU_BIG_ENDIAN rko[0] = ror32(aes_sub(rki[kwords - 1]), 8) ^ rcon[i] ^ rki[0]; -#else - rko[0] = rol32(aes_sub(rki[kwords - 1]), 8) ^ (rcon[i] << 24) ^ - rki[0]; -#endif rko[1] = rko[0] ^ rki[1]; rko[2] = rko[1] ^ rki[2]; rko[3] = rko[2] ^ rki[3]; @@ -210,9 +221,9 @@ int ce_aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, key_dec[0] = key_enc[j]; for (i = 1, j--; j > 0; i++, j--) - __asm__("ld1 {v0.16b}, %[in] ;" + __asm__("ld1 {v0.4s}, %[in] ;" "aesimc v1.16b, v0.16b ;" - "st1 {v1.16b}, %[out] ;" + "st1 {v1.4s}, %[out] ;" : [out] "=Q"(key_dec[i]) : [in] "Q"(key_enc[j]) diff --git a/arch/arm64/crypto/aes-ce-setkey.h b/arch/arm64/crypto/aes-ce-setkey.h index f08a6471d034..fd9ecf07d88c 100644 --- a/arch/arm64/crypto/aes-ce-setkey.h +++ b/arch/arm64/crypto/aes-ce-setkey.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ int ce_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len); diff --git a/arch/arm64/crypto/aes-ce.S b/arch/arm64/crypto/aes-ce.S index b46093d567e5..50330f5c3adc 100644 --- a/arch/arm64/crypto/aes-ce.S +++ b/arch/arm64/crypto/aes-ce.S @@ -2,7 +2,7 @@ * linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with * Crypto Extensions * - * Copyright (C) 2013 Linaro Ltd + * Copyright (C) 2013 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,11 +22,11 @@ cmp \rounds, #12 blo 2222f /* 128 bits */ beq 1111f /* 192 bits */ - ld1 {v17.16b-v18.16b}, [\rk], #32 -1111: ld1 {v19.16b-v20.16b}, [\rk], #32 -2222: ld1 {v21.16b-v24.16b}, [\rk], #64 - ld1 {v25.16b-v28.16b}, [\rk], #64 - ld1 {v29.16b-v31.16b}, [\rk] + ld1 {v17.4s-v18.4s}, [\rk], #32 +1111: ld1 {v19.4s-v20.4s}, [\rk], #32 +2222: ld1 {v21.4s-v24.4s}, [\rk], #64 + ld1 {v25.4s-v28.4s}, [\rk], #64 + ld1 {v29.4s-v31.4s}, [\rk] .endm /* prepare for encryption with key in rk[] */ diff --git a/arch/arm64/crypto/aes-cipher-core.S b/arch/arm64/crypto/aes-cipher-core.S index f2f9cc519309..6d2445d603cc 100644 --- a/arch/arm64/crypto/aes-cipher-core.S +++ b/arch/arm64/crypto/aes-cipher-core.S @@ -10,6 +10,7 @@ #include #include +#include .text @@ -17,94 +18,155 @@ out .req x1 in .req x2 rounds .req x3 - tt .req x4 - lt .req x2 + tt .req x2 - .macro __pair, enc, reg0, reg1, in0, in1e, in1d, shift - ubfx \reg0, \in0, #\shift, #8 - .if \enc - ubfx \reg1, \in1e, #\shift, #8 + .macro __pair1, sz, op, reg0, reg1, in0, in1e, in1d, shift + .ifc \op\shift, b0 + ubfiz \reg0, \in0, #2, #8 + ubfiz \reg1, \in1e, #2, #8 .else - ubfx \reg1, \in1d, #\shift, #8 + ubfx \reg0, \in0, #\shift, #8 + ubfx \reg1, \in1e, #\shift, #8 .endif + + /* + * AArch64 cannot do byte size indexed loads from a table containing + * 32-bit quantities, i.e., 'ldrb w12, [tt, w12, uxtw #2]' is not a + * valid instruction. So perform the shift explicitly first for the + * high bytes (the low byte is shifted implicitly by using ubfiz rather + * than ubfx above) + */ + .ifnc \op, b ldr \reg0, [tt, \reg0, uxtw #2] ldr \reg1, [tt, \reg1, uxtw #2] + .else + .if \shift > 0 + lsl \reg0, \reg0, #2 + lsl \reg1, \reg1, #2 + .endif + ldrb \reg0, [tt, \reg0, uxtw] + ldrb \reg1, [tt, \reg1, uxtw] + .endif .endm - .macro __hround, out0, out1, in0, in1, in2, in3, t0, t1, enc + .macro __pair0, sz, op, reg0, reg1, in0, in1e, in1d, shift + ubfx \reg0, \in0, #\shift, #8 + ubfx \reg1, \in1d, #\shift, #8 + ldr\op \reg0, [tt, \reg0, uxtw #\sz] + ldr\op \reg1, [tt, \reg1, uxtw #\sz] + .endm + + .macro __hround, out0, out1, in0, in1, in2, in3, t0, t1, enc, sz, op ldp \out0, \out1, [rk], #8 - __pair \enc, w13, w14, \in0, \in1, \in3, 0 - __pair \enc, w15, w16, \in1, \in2, \in0, 8 - __pair \enc, w17, w18, \in2, \in3, \in1, 16 - __pair \enc, \t0, \t1, \in3, \in0, \in2, 24 + __pair\enc \sz, \op, w12, w13, \in0, \in1, \in3, 0 + __pair\enc \sz, \op, w14, w15, \in1, \in2, \in0, 8 + __pair\enc \sz, \op, w16, w17, \in2, \in3, \in1, 16 + __pair\enc \sz, \op, \t0, \t1, \in3, \in0, \in2, 24 - eor \out0, \out0, w13 - eor \out1, \out1, w14 - eor \out0, \out0, w15, ror #24 - eor \out1, \out1, w16, ror #24 - eor \out0, \out0, w17, ror #16 - eor \out1, \out1, w18, ror #16 + eor \out0, \out0, w12 + eor \out1, \out1, w13 + eor \out0, \out0, w14, ror #24 + eor \out1, \out1, w15, ror #24 + eor \out0, \out0, w16, ror #16 + eor \out1, \out1, w17, ror #16 eor \out0, \out0, \t0, ror #8 eor \out1, \out1, \t1, ror #8 .endm - .macro fround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1 - __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1 + .macro fround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in1, \in2, \in3, \out2, \out3, 1, \sz, \op + __hround \out2, \out3, \in2, \in3, \in0, \in1, \in1, \in2, 1, \sz, \op .endm - .macro iround, out0, out1, out2, out3, in0, in1, in2, in3 - __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0 - __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0 + .macro iround, out0, out1, out2, out3, in0, in1, in2, in3, sz=2, op + __hround \out0, \out1, \in0, \in3, \in2, \in1, \out2, \out3, 0, \sz, \op + __hround \out2, \out3, \in2, \in1, \in0, \in3, \in1, \in0, 0, \sz, \op .endm - .macro do_crypt, round, ttab, ltab - ldp w5, w6, [in] - ldp w7, w8, [in, #8] - ldp w9, w10, [rk], #16 - ldp w11, w12, [rk, #-8] + .macro do_crypt, round, ttab, ltab, bsz + ldp w4, w5, [in] + ldp w6, w7, [in, #8] + ldp w8, w9, [rk], #16 + ldp w10, w11, [rk, #-8] +CPU_BE( rev w4, w4 ) CPU_BE( rev w5, w5 ) CPU_BE( rev w6, w6 ) CPU_BE( rev w7, w7 ) -CPU_BE( rev w8, w8 ) + eor w4, w4, w8 eor w5, w5, w9 eor w6, w6, w10 eor w7, w7, w11 - eor w8, w8, w12 adr_l tt, \ttab - adr_l lt, \ltab tbnz rounds, #1, 1f -0: \round w9, w10, w11, w12, w5, w6, w7, w8 - \round w5, w6, w7, w8, w9, w10, w11, w12 +0: \round w8, w9, w10, w11, w4, w5, w6, w7 + \round w4, w5, w6, w7, w8, w9, w10, w11 1: subs rounds, rounds, #4 - \round w9, w10, w11, w12, w5, w6, w7, w8 - csel tt, tt, lt, hi - \round w5, w6, w7, w8, w9, w10, w11, w12 - b.hi 0b + \round w8, w9, w10, w11, w4, w5, w6, w7 + b.ls 3f +2: \round w4, w5, w6, w7, w8, w9, w10, w11 + b 0b +3: adr_l tt, \ltab + \round w4, w5, w6, w7, w8, w9, w10, w11, \bsz, b +CPU_BE( rev w4, w4 ) CPU_BE( rev w5, w5 ) CPU_BE( rev w6, w6 ) CPU_BE( rev w7, w7 ) -CPU_BE( rev w8, w8 ) - stp w5, w6, [out] - stp w7, w8, [out, #8] + stp w4, w5, [out] + stp w6, w7, [out, #8] ret .endm - .align 5 + .align L1_CACHE_SHIFT + .type __aes_arm64_inverse_sbox, %object +__aes_arm64_inverse_sbox: + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + .size __aes_arm64_inverse_sbox, . - __aes_arm64_inverse_sbox + ENTRY(__aes_arm64_encrypt) - do_crypt fround, crypto_ft_tab, crypto_fl_tab + do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2 ENDPROC(__aes_arm64_encrypt) .align 5 ENTRY(__aes_arm64_decrypt) - do_crypt iround, crypto_it_tab, crypto_il_tab + do_crypt iround, crypto_it_tab, __aes_arm64_inverse_sbox, 0 ENDPROC(__aes_arm64_decrypt) diff --git a/arch/arm64/crypto/aes-ctr-fallback.h b/arch/arm64/crypto/aes-ctr-fallback.h new file mode 100644 index 000000000000..c9285717b6b5 --- /dev/null +++ b/arch/arm64/crypto/aes-ctr-fallback.h @@ -0,0 +1,53 @@ +/* + * Fallback for sync aes(ctr) in contexts where kernel mode NEON + * is not allowed + * + * Copyright (C) 2017 Linaro Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); + +static inline int aes_ctr_encrypt_fallback(struct crypto_aes_ctx *ctx, + struct skcipher_request *req) +{ + struct skcipher_walk walk; + u8 buf[AES_BLOCK_SIZE]; + int err; + + err = skcipher_walk_virt(&walk, req, true); + + while (walk.nbytes > 0) { + u8 *dst = walk.dst.virt.addr; + u8 *src = walk.src.virt.addr; + int nbytes = walk.nbytes; + int tail = 0; + + if (nbytes < walk.total) { + nbytes = round_down(nbytes, AES_BLOCK_SIZE); + tail = walk.nbytes % AES_BLOCK_SIZE; + } + + do { + int bsize = min(nbytes, AES_BLOCK_SIZE); + + __aes_arm64_encrypt(ctx->key_enc, buf, walk.iv, + 6 + ctx->key_length / 4); + crypto_xor_cpy(dst, src, buf, bsize); + crypto_inc(walk.iv, AES_BLOCK_SIZE); + + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + nbytes -= AES_BLOCK_SIZE; + } while (nbytes > 0); + + err = skcipher_walk_done(&walk, tail); + } + return err; +} diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c index bcf596b0197e..998ba519a026 100644 --- a/arch/arm64/crypto/aes-glue.c +++ b/arch/arm64/crypto/aes-glue.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include "aes-ce-setkey.h" +#include "aes-ctr-fallback.h" #ifdef USE_V8_CRYPTO_EXTENSIONS #define MODE "ce" @@ -241,9 +243,7 @@ static int ctr_encrypt(struct skcipher_request *req) aes_ctr_encrypt(tail, NULL, (u8 *)ctx->key_enc, rounds, blocks, walk.iv, first); - if (tdst != tsrc) - memcpy(tdst, tsrc, nbytes); - crypto_xor(tdst, tail, nbytes); + crypto_xor_cpy(tdst, tsrc, tail, nbytes); err = skcipher_walk_done(&walk, 0); } kernel_neon_end(); @@ -251,6 +251,17 @@ static int ctr_encrypt(struct skcipher_request *req) return err; } +static int ctr_encrypt_sync(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm); + + if (!may_use_simd()) + return aes_ctr_encrypt_fallback(ctx, req); + + return ctr_encrypt(req); +} + static int xts_encrypt(struct skcipher_request *req) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); @@ -357,8 +368,8 @@ static struct skcipher_alg aes_algs[] = { { .ivsize = AES_BLOCK_SIZE, .chunksize = AES_BLOCK_SIZE, .setkey = skcipher_aes_setkey, - .encrypt = ctr_encrypt, - .decrypt = ctr_encrypt, + .encrypt = ctr_encrypt_sync, + .decrypt = ctr_encrypt_sync, }, { .base = { .cra_name = "__xts(aes)", @@ -460,11 +471,35 @@ static int mac_init(struct shash_desc *desc) return 0; } +static void mac_do_update(struct crypto_aes_ctx *ctx, u8 const in[], int blocks, + u8 dg[], int enc_before, int enc_after) +{ + int rounds = 6 + ctx->key_length / 4; + + if (may_use_simd()) { + kernel_neon_begin(); + aes_mac_update(in, ctx->key_enc, rounds, blocks, dg, enc_before, + enc_after); + kernel_neon_end(); + } else { + if (enc_before) + __aes_arm64_encrypt(ctx->key_enc, dg, dg, rounds); + + while (blocks--) { + crypto_xor(dg, in, AES_BLOCK_SIZE); + in += AES_BLOCK_SIZE; + + if (blocks || enc_after) + __aes_arm64_encrypt(ctx->key_enc, dg, dg, + rounds); + } + } +} + static int mac_update(struct shash_desc *desc, const u8 *p, unsigned int len) { struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); struct mac_desc_ctx *ctx = shash_desc_ctx(desc); - int rounds = 6 + tctx->key.key_length / 4; while (len > 0) { unsigned int l; @@ -476,10 +511,8 @@ static int mac_update(struct shash_desc *desc, const u8 *p, unsigned int len) len %= AES_BLOCK_SIZE; - kernel_neon_begin(); - aes_mac_update(p, tctx->key.key_enc, rounds, blocks, - ctx->dg, (ctx->len != 0), (len != 0)); - kernel_neon_end(); + mac_do_update(&tctx->key, p, blocks, ctx->dg, + (ctx->len != 0), (len != 0)); p += blocks * AES_BLOCK_SIZE; @@ -507,11 +540,8 @@ static int cbcmac_final(struct shash_desc *desc, u8 *out) { struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); struct mac_desc_ctx *ctx = shash_desc_ctx(desc); - int rounds = 6 + tctx->key.key_length / 4; - kernel_neon_begin(); - aes_mac_update(NULL, tctx->key.key_enc, rounds, 0, ctx->dg, 1, 0); - kernel_neon_end(); + mac_do_update(&tctx->key, NULL, 0, ctx->dg, 1, 0); memcpy(out, ctx->dg, AES_BLOCK_SIZE); @@ -522,7 +552,6 @@ static int cmac_final(struct shash_desc *desc, u8 *out) { struct mac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); struct mac_desc_ctx *ctx = shash_desc_ctx(desc); - int rounds = 6 + tctx->key.key_length / 4; u8 *consts = tctx->consts; if (ctx->len != AES_BLOCK_SIZE) { @@ -530,9 +559,7 @@ static int cmac_final(struct shash_desc *desc, u8 *out) consts += AES_BLOCK_SIZE; } - kernel_neon_begin(); - aes_mac_update(consts, tctx->key.key_enc, rounds, 1, ctx->dg, 0, 1); - kernel_neon_end(); + mac_do_update(&tctx->key, consts, 1, ctx->dg, 0, 1); memcpy(out, ctx->dg, AES_BLOCK_SIZE); diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c index db2501d93550..c55d68ccb89f 100644 --- a/arch/arm64/crypto/aes-neonbs-glue.c +++ b/arch/arm64/crypto/aes-neonbs-glue.c @@ -1,7 +1,7 @@ /* * Bit sliced AES using NEON instructions * - * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2016 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,12 +9,15 @@ */ #include +#include #include #include #include #include #include +#include "aes-ctr-fallback.h" + MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); @@ -58,6 +61,11 @@ struct aesbs_cbc_ctx { u32 enc[AES_MAX_KEYLENGTH_U32]; }; +struct aesbs_ctr_ctx { + struct aesbs_ctx key; /* must be first member */ + struct crypto_aes_ctx fallback; +}; + struct aesbs_xts_ctx { struct aesbs_ctx key; u32 twkey[AES_MAX_KEYLENGTH_U32]; @@ -196,6 +204,25 @@ static int cbc_decrypt(struct skcipher_request *req) return err; } +static int aesbs_ctr_setkey_sync(struct crypto_skcipher *tfm, const u8 *in_key, + unsigned int key_len) +{ + struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm); + int err; + + err = crypto_aes_expand_key(&ctx->fallback, in_key, key_len); + if (err) + return err; + + ctx->key.rounds = 6 + key_len / 4; + + kernel_neon_begin(); + aesbs_convert_key(ctx->key.rk, ctx->fallback.key_enc, ctx->key.rounds); + kernel_neon_end(); + + return 0; +} + static int ctr_encrypt(struct skcipher_request *req) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); @@ -224,9 +251,8 @@ static int ctr_encrypt(struct skcipher_request *req) u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE; u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE; - if (dst != src) - memcpy(dst, src, walk.total % AES_BLOCK_SIZE); - crypto_xor(dst, final, walk.total % AES_BLOCK_SIZE); + crypto_xor_cpy(dst, src, final, + walk.total % AES_BLOCK_SIZE); err = skcipher_walk_done(&walk, 0); break; @@ -260,6 +286,17 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key, return aesbs_setkey(tfm, in_key, key_len); } +static int ctr_encrypt_sync(struct skcipher_request *req) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + struct aesbs_ctr_ctx *ctx = crypto_skcipher_ctx(tfm); + + if (!may_use_simd()) + return aes_ctr_encrypt_fallback(&ctx->fallback, req); + + return ctr_encrypt(req); +} + static int __xts_crypt(struct skcipher_request *req, void (*fn)(u8 out[], u8 const in[], u8 const rk[], int rounds, int blocks, u8 iv[])) @@ -356,7 +393,7 @@ static struct skcipher_alg aes_algs[] = { { .base.cra_driver_name = "ctr-aes-neonbs", .base.cra_priority = 250 - 1, .base.cra_blocksize = 1, - .base.cra_ctxsize = sizeof(struct aesbs_ctx), + .base.cra_ctxsize = sizeof(struct aesbs_ctr_ctx), .base.cra_module = THIS_MODULE, .min_keysize = AES_MIN_KEY_SIZE, @@ -364,9 +401,9 @@ static struct skcipher_alg aes_algs[] = { { .chunksize = AES_BLOCK_SIZE, .walksize = 8 * AES_BLOCK_SIZE, .ivsize = AES_BLOCK_SIZE, - .setkey = aesbs_setkey, - .encrypt = ctr_encrypt, - .decrypt = ctr_encrypt, + .setkey = aesbs_ctr_setkey_sync, + .encrypt = ctr_encrypt_sync, + .decrypt = ctr_encrypt_sync, }, { .base.cra_name = "__xts(aes)", .base.cra_driver_name = "__xts-aes-neonbs", diff --git a/arch/arm64/crypto/chacha20-neon-glue.c b/arch/arm64/crypto/chacha20-neon-glue.c index a7cd575ea223..cbdb75d15cd0 100644 --- a/arch/arm64/crypto/chacha20-neon-glue.c +++ b/arch/arm64/crypto/chacha20-neon-glue.c @@ -1,7 +1,7 @@ /* * ChaCha20 256-bit cipher algorithm, RFC7539, arm64 NEON functions * - * Copyright (C) 2016 Linaro, Ltd. + * Copyright (C) 2016 - 2017 Linaro, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -26,6 +26,7 @@ #include #include +#include asmlinkage void chacha20_block_xor_neon(u32 *state, u8 *dst, const u8 *src); asmlinkage void chacha20_4block_xor_neon(u32 *state, u8 *dst, const u8 *src); @@ -64,7 +65,7 @@ static int chacha20_neon(struct skcipher_request *req) u32 state[16]; int err; - if (req->cryptlen <= CHACHA20_BLOCK_SIZE) + if (!may_use_simd() || req->cryptlen <= CHACHA20_BLOCK_SIZE) return crypto_chacha20_crypt(req); err = skcipher_walk_virt(&walk, req, true); diff --git a/arch/arm64/crypto/crc32-ce-glue.c b/arch/arm64/crypto/crc32-ce-glue.c index eccb1ae90064..624f4137918c 100644 --- a/arch/arm64/crypto/crc32-ce-glue.c +++ b/arch/arm64/crypto/crc32-ce-glue.c @@ -1,7 +1,7 @@ /* * Accelerated CRC32(C) using arm64 NEON and Crypto Extensions instructions * - * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2016 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -19,6 +19,7 @@ #include #include +#include #include #define PMULL_MIN_LEN 64L /* minimum size of buffer @@ -105,10 +106,10 @@ static int crc32_pmull_update(struct shash_desc *desc, const u8 *data, length -= l; } - if (length >= PMULL_MIN_LEN) { + if (length >= PMULL_MIN_LEN && may_use_simd()) { l = round_down(length, SCALE_F); - kernel_neon_begin_partial(10); + kernel_neon_begin(); *crc = crc32_pmull_le(data, l, *crc); kernel_neon_end(); @@ -137,10 +138,10 @@ static int crc32c_pmull_update(struct shash_desc *desc, const u8 *data, length -= l; } - if (length >= PMULL_MIN_LEN) { + if (length >= PMULL_MIN_LEN && may_use_simd()) { l = round_down(length, SCALE_F); - kernel_neon_begin_partial(10); + kernel_neon_begin(); *crc = crc32c_pmull_le(data, l, *crc); kernel_neon_end(); diff --git a/arch/arm64/crypto/crct10dif-ce-glue.c b/arch/arm64/crypto/crct10dif-ce-glue.c index 60cb590c2590..96f0cae4a022 100644 --- a/arch/arm64/crypto/crct10dif-ce-glue.c +++ b/arch/arm64/crypto/crct10dif-ce-glue.c @@ -1,7 +1,7 @@ /* * Accelerated CRC-T10DIF using arm64 NEON and Crypto Extensions instructions * - * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2016 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -18,6 +18,7 @@ #include #include +#include #define CRC_T10DIF_PMULL_CHUNK_SIZE 16U @@ -48,9 +49,13 @@ static int crct10dif_update(struct shash_desc *desc, const u8 *data, } if (length > 0) { - kernel_neon_begin_partial(14); - *crc = crc_t10dif_pmull(*crc, data, length); - kernel_neon_end(); + if (may_use_simd()) { + kernel_neon_begin(); + *crc = crc_t10dif_pmull(*crc, data, length); + kernel_neon_end(); + } else { + *crc = crc_t10dif_generic(*crc, data, length); + } } return 0; diff --git a/arch/arm64/crypto/ghash-ce-core.S b/arch/arm64/crypto/ghash-ce-core.S index f0bb9f0b524f..11ebf1ae248a 100644 --- a/arch/arm64/crypto/ghash-ce-core.S +++ b/arch/arm64/crypto/ghash-ce-core.S @@ -1,7 +1,7 @@ /* * Accelerated GHASH implementation with ARMv8 PMULL instructions. * - * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 2014 - 2017 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -11,31 +11,215 @@ #include #include - SHASH .req v0 - SHASH2 .req v1 - T1 .req v2 - T2 .req v3 - MASK .req v4 - XL .req v5 - XM .req v6 - XH .req v7 - IN1 .req v7 + SHASH .req v0 + SHASH2 .req v1 + T1 .req v2 + T2 .req v3 + MASK .req v4 + XL .req v5 + XM .req v6 + XH .req v7 + IN1 .req v7 + + k00_16 .req v8 + k32_48 .req v9 + + t3 .req v10 + t4 .req v11 + t5 .req v12 + t6 .req v13 + t7 .req v14 + t8 .req v15 + t9 .req v16 + + perm1 .req v17 + perm2 .req v18 + perm3 .req v19 + + sh1 .req v20 + sh2 .req v21 + sh3 .req v22 + sh4 .req v23 + + ss1 .req v24 + ss2 .req v25 + ss3 .req v26 + ss4 .req v27 .text .arch armv8-a+crypto - /* - * void pmull_ghash_update(int blocks, u64 dg[], const char *src, - * struct ghash_key const *k, const char *head) - */ -ENTRY(pmull_ghash_update) + .macro __pmull_p64, rd, rn, rm + pmull \rd\().1q, \rn\().1d, \rm\().1d + .endm + + .macro __pmull2_p64, rd, rn, rm + pmull2 \rd\().1q, \rn\().2d, \rm\().2d + .endm + + .macro __pmull_p8, rq, ad, bd + ext t3.8b, \ad\().8b, \ad\().8b, #1 // A1 + ext t5.8b, \ad\().8b, \ad\().8b, #2 // A2 + ext t7.8b, \ad\().8b, \ad\().8b, #3 // A3 + + __pmull_p8_\bd \rq, \ad + .endm + + .macro __pmull2_p8, rq, ad, bd + tbl t3.16b, {\ad\().16b}, perm1.16b // A1 + tbl t5.16b, {\ad\().16b}, perm2.16b // A2 + tbl t7.16b, {\ad\().16b}, perm3.16b // A3 + + __pmull2_p8_\bd \rq, \ad + .endm + + .macro __pmull_p8_SHASH, rq, ad + __pmull_p8_tail \rq, \ad\().8b, SHASH.8b, 8b,, sh1, sh2, sh3, sh4 + .endm + + .macro __pmull_p8_SHASH2, rq, ad + __pmull_p8_tail \rq, \ad\().8b, SHASH2.8b, 8b,, ss1, ss2, ss3, ss4 + .endm + + .macro __pmull2_p8_SHASH, rq, ad + __pmull_p8_tail \rq, \ad\().16b, SHASH.16b, 16b, 2, sh1, sh2, sh3, sh4 + .endm + + .macro __pmull_p8_tail, rq, ad, bd, nb, t, b1, b2, b3, b4 + pmull\t t3.8h, t3.\nb, \bd // F = A1*B + pmull\t t4.8h, \ad, \b1\().\nb // E = A*B1 + pmull\t t5.8h, t5.\nb, \bd // H = A2*B + pmull\t t6.8h, \ad, \b2\().\nb // G = A*B2 + pmull\t t7.8h, t7.\nb, \bd // J = A3*B + pmull\t t8.8h, \ad, \b3\().\nb // I = A*B3 + pmull\t t9.8h, \ad, \b4\().\nb // K = A*B4 + pmull\t \rq\().8h, \ad, \bd // D = A*B + + eor t3.16b, t3.16b, t4.16b // L = E + F + eor t5.16b, t5.16b, t6.16b // M = G + H + eor t7.16b, t7.16b, t8.16b // N = I + J + + uzp1 t4.2d, t3.2d, t5.2d + uzp2 t3.2d, t3.2d, t5.2d + uzp1 t6.2d, t7.2d, t9.2d + uzp2 t7.2d, t7.2d, t9.2d + + // t3 = (L) (P0 + P1) << 8 + // t5 = (M) (P2 + P3) << 16 + eor t4.16b, t4.16b, t3.16b + and t3.16b, t3.16b, k32_48.16b + + // t7 = (N) (P4 + P5) << 24 + // t9 = (K) (P6 + P7) << 32 + eor t6.16b, t6.16b, t7.16b + and t7.16b, t7.16b, k00_16.16b + + eor t4.16b, t4.16b, t3.16b + eor t6.16b, t6.16b, t7.16b + + zip2 t5.2d, t4.2d, t3.2d + zip1 t3.2d, t4.2d, t3.2d + zip2 t9.2d, t6.2d, t7.2d + zip1 t7.2d, t6.2d, t7.2d + + ext t3.16b, t3.16b, t3.16b, #15 + ext t5.16b, t5.16b, t5.16b, #14 + ext t7.16b, t7.16b, t7.16b, #13 + ext t9.16b, t9.16b, t9.16b, #12 + + eor t3.16b, t3.16b, t5.16b + eor t7.16b, t7.16b, t9.16b + eor \rq\().16b, \rq\().16b, t3.16b + eor \rq\().16b, \rq\().16b, t7.16b + .endm + + .macro __pmull_pre_p64 + movi MASK.16b, #0xe1 + shl MASK.2d, MASK.2d, #57 + .endm + + .macro __pmull_pre_p8 + // k00_16 := 0x0000000000000000_000000000000ffff + // k32_48 := 0x00000000ffffffff_0000ffffffffffff + movi k32_48.2d, #0xffffffff + mov k32_48.h[2], k32_48.h[0] + ushr k00_16.2d, k32_48.2d, #32 + + // prepare the permutation vectors + mov_q x5, 0x080f0e0d0c0b0a09 + movi T1.8b, #8 + dup perm1.2d, x5 + eor perm1.16b, perm1.16b, T1.16b + ushr perm2.2d, perm1.2d, #8 + ushr perm3.2d, perm1.2d, #16 + ushr T1.2d, perm1.2d, #24 + sli perm2.2d, perm1.2d, #56 + sli perm3.2d, perm1.2d, #48 + sli T1.2d, perm1.2d, #40 + + // precompute loop invariants + tbl sh1.16b, {SHASH.16b}, perm1.16b + tbl sh2.16b, {SHASH.16b}, perm2.16b + tbl sh3.16b, {SHASH.16b}, perm3.16b + tbl sh4.16b, {SHASH.16b}, T1.16b + ext ss1.8b, SHASH2.8b, SHASH2.8b, #1 + ext ss2.8b, SHASH2.8b, SHASH2.8b, #2 + ext ss3.8b, SHASH2.8b, SHASH2.8b, #3 + ext ss4.8b, SHASH2.8b, SHASH2.8b, #4 + .endm + + // + // PMULL (64x64->128) based reduction for CPUs that can do + // it in a single instruction. + // + .macro __pmull_reduce_p64 + pmull T2.1q, XL.1d, MASK.1d + eor XM.16b, XM.16b, T1.16b + + mov XH.d[0], XM.d[1] + mov XM.d[1], XL.d[0] + + eor XL.16b, XM.16b, T2.16b + ext T2.16b, XL.16b, XL.16b, #8 + pmull XL.1q, XL.1d, MASK.1d + .endm + + // + // Alternative reduction for CPUs that lack support for the + // 64x64->128 PMULL instruction + // + .macro __pmull_reduce_p8 + eor XM.16b, XM.16b, T1.16b + + mov XL.d[1], XM.d[0] + mov XH.d[0], XM.d[1] + + shl T1.2d, XL.2d, #57 + shl T2.2d, XL.2d, #62 + eor T2.16b, T2.16b, T1.16b + shl T1.2d, XL.2d, #63 + eor T2.16b, T2.16b, T1.16b + ext T1.16b, XL.16b, XH.16b, #8 + eor T2.16b, T2.16b, T1.16b + + mov XL.d[1], T2.d[0] + mov XH.d[0], T2.d[1] + + ushr T2.2d, XL.2d, #1 + eor XH.16b, XH.16b, XL.16b + eor XL.16b, XL.16b, T2.16b + ushr T2.2d, T2.2d, #6 + ushr XL.2d, XL.2d, #1 + .endm + + .macro __pmull_ghash, pn ld1 {SHASH.2d}, [x3] ld1 {XL.2d}, [x1] - movi MASK.16b, #0xe1 ext SHASH2.16b, SHASH.16b, SHASH.16b, #8 - shl MASK.2d, MASK.2d, #57 eor SHASH2.16b, SHASH2.16b, SHASH.16b + __pmull_pre_\pn + /* do the head block first, if supplied */ cbz x4, 0f ld1 {T1.2d}, [x4] @@ -52,23 +236,17 @@ CPU_LE( rev64 T1.16b, T1.16b ) eor T1.16b, T1.16b, T2.16b eor XL.16b, XL.16b, IN1.16b - pmull2 XH.1q, SHASH.2d, XL.2d // a1 * b1 + __pmull2_\pn XH, XL, SHASH // a1 * b1 eor T1.16b, T1.16b, XL.16b - pmull XL.1q, SHASH.1d, XL.1d // a0 * b0 - pmull XM.1q, SHASH2.1d, T1.1d // (a1 + a0)(b1 + b0) + __pmull_\pn XL, XL, SHASH // a0 * b0 + __pmull_\pn XM, T1, SHASH2 // (a1 + a0)(b1 + b0) - ext T1.16b, XL.16b, XH.16b, #8 eor T2.16b, XL.16b, XH.16b - eor XM.16b, XM.16b, T1.16b + ext T1.16b, XL.16b, XH.16b, #8 eor XM.16b, XM.16b, T2.16b - pmull T2.1q, XL.1d, MASK.1d - mov XH.d[0], XM.d[1] - mov XM.d[1], XL.d[0] + __pmull_reduce_\pn - eor XL.16b, XM.16b, T2.16b - ext T2.16b, XL.16b, XL.16b, #8 - pmull XL.1q, XL.1d, MASK.1d eor T2.16b, T2.16b, XH.16b eor XL.16b, XL.16b, T2.16b @@ -76,4 +254,191 @@ CPU_LE( rev64 T1.16b, T1.16b ) st1 {XL.2d}, [x1] ret -ENDPROC(pmull_ghash_update) + .endm + + /* + * void pmull_ghash_update(int blocks, u64 dg[], const char *src, + * struct ghash_key const *k, const char *head) + */ +ENTRY(pmull_ghash_update_p64) + __pmull_ghash p64 +ENDPROC(pmull_ghash_update_p64) + +ENTRY(pmull_ghash_update_p8) + __pmull_ghash p8 +ENDPROC(pmull_ghash_update_p8) + + KS .req v8 + CTR .req v9 + INP .req v10 + + .macro load_round_keys, rounds, rk + cmp \rounds, #12 + blo 2222f /* 128 bits */ + beq 1111f /* 192 bits */ + ld1 {v17.4s-v18.4s}, [\rk], #32 +1111: ld1 {v19.4s-v20.4s}, [\rk], #32 +2222: ld1 {v21.4s-v24.4s}, [\rk], #64 + ld1 {v25.4s-v28.4s}, [\rk], #64 + ld1 {v29.4s-v31.4s}, [\rk] + .endm + + .macro enc_round, state, key + aese \state\().16b, \key\().16b + aesmc \state\().16b, \state\().16b + .endm + + .macro enc_block, state, rounds + cmp \rounds, #12 + b.lo 2222f /* 128 bits */ + b.eq 1111f /* 192 bits */ + enc_round \state, v17 + enc_round \state, v18 +1111: enc_round \state, v19 + enc_round \state, v20 +2222: .irp key, v21, v22, v23, v24, v25, v26, v27, v28, v29 + enc_round \state, \key + .endr + aese \state\().16b, v30.16b + eor \state\().16b, \state\().16b, v31.16b + .endm + + .macro pmull_gcm_do_crypt, enc + ld1 {SHASH.2d}, [x4] + ld1 {XL.2d}, [x1] + ldr x8, [x5, #8] // load lower counter + + movi MASK.16b, #0xe1 + ext SHASH2.16b, SHASH.16b, SHASH.16b, #8 +CPU_LE( rev x8, x8 ) + shl MASK.2d, MASK.2d, #57 + eor SHASH2.16b, SHASH2.16b, SHASH.16b + + .if \enc == 1 + ld1 {KS.16b}, [x7] + .endif + +0: ld1 {CTR.8b}, [x5] // load upper counter + ld1 {INP.16b}, [x3], #16 + rev x9, x8 + add x8, x8, #1 + sub w0, w0, #1 + ins CTR.d[1], x9 // set lower counter + + .if \enc == 1 + eor INP.16b, INP.16b, KS.16b // encrypt input + st1 {INP.16b}, [x2], #16 + .endif + + rev64 T1.16b, INP.16b + + cmp w6, #12 + b.ge 2f // AES-192/256? + +1: enc_round CTR, v21 + + ext T2.16b, XL.16b, XL.16b, #8 + ext IN1.16b, T1.16b, T1.16b, #8 + + enc_round CTR, v22 + + eor T1.16b, T1.16b, T2.16b + eor XL.16b, XL.16b, IN1.16b + + enc_round CTR, v23 + + pmull2 XH.1q, SHASH.2d, XL.2d // a1 * b1 + eor T1.16b, T1.16b, XL.16b + + enc_round CTR, v24 + + pmull XL.1q, SHASH.1d, XL.1d // a0 * b0 + pmull XM.1q, SHASH2.1d, T1.1d // (a1 + a0)(b1 + b0) + + enc_round CTR, v25 + + ext T1.16b, XL.16b, XH.16b, #8 + eor T2.16b, XL.16b, XH.16b + eor XM.16b, XM.16b, T1.16b + + enc_round CTR, v26 + + eor XM.16b, XM.16b, T2.16b + pmull T2.1q, XL.1d, MASK.1d + + enc_round CTR, v27 + + mov XH.d[0], XM.d[1] + mov XM.d[1], XL.d[0] + + enc_round CTR, v28 + + eor XL.16b, XM.16b, T2.16b + + enc_round CTR, v29 + + ext T2.16b, XL.16b, XL.16b, #8 + + aese CTR.16b, v30.16b + + pmull XL.1q, XL.1d, MASK.1d + eor T2.16b, T2.16b, XH.16b + + eor KS.16b, CTR.16b, v31.16b + + eor XL.16b, XL.16b, T2.16b + + .if \enc == 0 + eor INP.16b, INP.16b, KS.16b + st1 {INP.16b}, [x2], #16 + .endif + + cbnz w0, 0b + +CPU_LE( rev x8, x8 ) + st1 {XL.2d}, [x1] + str x8, [x5, #8] // store lower counter + + .if \enc == 1 + st1 {KS.16b}, [x7] + .endif + + ret + +2: b.eq 3f // AES-192? + enc_round CTR, v17 + enc_round CTR, v18 +3: enc_round CTR, v19 + enc_round CTR, v20 + b 1b + .endm + + /* + * void pmull_gcm_encrypt(int blocks, u64 dg[], u8 dst[], const u8 src[], + * struct ghash_key const *k, u8 ctr[], + * int rounds, u8 ks[]) + */ +ENTRY(pmull_gcm_encrypt) + pmull_gcm_do_crypt 1 +ENDPROC(pmull_gcm_encrypt) + + /* + * void pmull_gcm_decrypt(int blocks, u64 dg[], u8 dst[], const u8 src[], + * struct ghash_key const *k, u8 ctr[], + * int rounds) + */ +ENTRY(pmull_gcm_decrypt) + pmull_gcm_do_crypt 0 +ENDPROC(pmull_gcm_decrypt) + + /* + * void pmull_gcm_encrypt_block(u8 dst[], u8 src[], u8 rk[], int rounds) + */ +ENTRY(pmull_gcm_encrypt_block) + cbz x2, 0f + load_round_keys w3, x2 +0: ld1 {v0.16b}, [x1] + enc_block v0, w3 + st1 {v0.16b}, [x0] + ret +ENDPROC(pmull_gcm_encrypt_block) diff --git a/arch/arm64/crypto/ghash-ce-glue.c b/arch/arm64/crypto/ghash-ce-glue.c index 833ec1e3f3e9..cfc9c92814fd 100644 --- a/arch/arm64/crypto/ghash-ce-glue.c +++ b/arch/arm64/crypto/ghash-ce-glue.c @@ -1,7 +1,7 @@ /* * Accelerated GHASH implementation with ARMv8 PMULL instructions. * - * Copyright (C) 2014 Linaro Ltd. + * Copyright (C) 2014 - 2017 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -9,22 +9,33 @@ */ #include +#include #include +#include +#include +#include +#include +#include #include +#include +#include #include #include #include -MODULE_DESCRIPTION("GHASH secure hash using ARMv8 Crypto Extensions"); +MODULE_DESCRIPTION("GHASH and AES-GCM using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("ghash"); #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 +#define GCM_IV_SIZE 12 struct ghash_key { u64 a; u64 b; + be128 k; }; struct ghash_desc_ctx { @@ -33,8 +44,35 @@ struct ghash_desc_ctx { u32 count; }; -asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src, - struct ghash_key const *k, const char *head); +struct gcm_aes_ctx { + struct crypto_aes_ctx aes_key; + struct ghash_key ghash_key; +}; + +asmlinkage void pmull_ghash_update_p64(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +asmlinkage void pmull_ghash_update_p8(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +static void (*pmull_ghash_update)(int blocks, u64 dg[], const char *src, + struct ghash_key const *k, + const char *head); + +asmlinkage void pmull_gcm_encrypt(int blocks, u64 dg[], u8 dst[], + const u8 src[], struct ghash_key const *k, + u8 ctr[], int rounds, u8 ks[]); + +asmlinkage void pmull_gcm_decrypt(int blocks, u64 dg[], u8 dst[], + const u8 src[], struct ghash_key const *k, + u8 ctr[], int rounds); + +asmlinkage void pmull_gcm_encrypt_block(u8 dst[], u8 const src[], + u32 const rk[], int rounds); + +asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); static int ghash_init(struct shash_desc *desc) { @@ -44,6 +82,36 @@ static int ghash_init(struct shash_desc *desc) return 0; } +static void ghash_do_update(int blocks, u64 dg[], const char *src, + struct ghash_key *key, const char *head) +{ + if (likely(may_use_simd())) { + kernel_neon_begin(); + pmull_ghash_update(blocks, dg, src, key, head); + kernel_neon_end(); + } else { + be128 dst = { cpu_to_be64(dg[1]), cpu_to_be64(dg[0]) }; + + do { + const u8 *in = src; + + if (head) { + in = head; + blocks++; + head = NULL; + } else { + src += GHASH_BLOCK_SIZE; + } + + crypto_xor((u8 *)&dst, in, GHASH_BLOCK_SIZE); + gf128mul_lle(&dst, &key->k); + } while (--blocks); + + dg[0] = be64_to_cpu(dst.b); + dg[1] = be64_to_cpu(dst.a); + } +} + static int ghash_update(struct shash_desc *desc, const u8 *src, unsigned int len) { @@ -67,10 +135,9 @@ static int ghash_update(struct shash_desc *desc, const u8 *src, blocks = len / GHASH_BLOCK_SIZE; len %= GHASH_BLOCK_SIZE; - kernel_neon_begin_partial(8); - pmull_ghash_update(blocks, ctx->digest, src, key, - partial ? ctx->buf : NULL); - kernel_neon_end(); + ghash_do_update(blocks, ctx->digest, src, key, + partial ? ctx->buf : NULL); + src += blocks * GHASH_BLOCK_SIZE; partial = 0; } @@ -89,9 +156,7 @@ static int ghash_final(struct shash_desc *desc, u8 *dst) memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial); - kernel_neon_begin_partial(8); - pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL); - kernel_neon_end(); + ghash_do_update(1, ctx->digest, ctx->buf, key, NULL); } put_unaligned_be64(ctx->digest[1], dst); put_unaligned_be64(ctx->digest[0], dst + 8); @@ -100,16 +165,13 @@ static int ghash_final(struct shash_desc *desc, u8 *dst) return 0; } -static int ghash_setkey(struct crypto_shash *tfm, - const u8 *inkey, unsigned int keylen) +static int __ghash_setkey(struct ghash_key *key, + const u8 *inkey, unsigned int keylen) { - struct ghash_key *key = crypto_shash_ctx(tfm); u64 a, b; - if (keylen != GHASH_BLOCK_SIZE) { - crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EINVAL; - } + /* needed for the fallback */ + memcpy(&key->k, inkey, GHASH_BLOCK_SIZE); /* perform multiplication by 'x' in GF(2^128) */ b = get_unaligned_be64(inkey); @@ -124,33 +186,418 @@ static int ghash_setkey(struct crypto_shash *tfm, return 0; } +static int ghash_setkey(struct crypto_shash *tfm, + const u8 *inkey, unsigned int keylen) +{ + struct ghash_key *key = crypto_shash_ctx(tfm); + + if (keylen != GHASH_BLOCK_SIZE) { + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + return __ghash_setkey(key, inkey, keylen); +} + static struct shash_alg ghash_alg = { - .digestsize = GHASH_DIGEST_SIZE, - .init = ghash_init, - .update = ghash_update, - .final = ghash_final, - .setkey = ghash_setkey, - .descsize = sizeof(struct ghash_desc_ctx), - .base = { - .cra_name = "ghash", - .cra_driver_name = "ghash-ce", - .cra_priority = 200, - .cra_flags = CRYPTO_ALG_TYPE_SHASH, - .cra_blocksize = GHASH_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct ghash_key), - .cra_module = THIS_MODULE, - }, + .base.cra_name = "ghash", + .base.cra_driver_name = "ghash-ce", + .base.cra_priority = 200, + .base.cra_flags = CRYPTO_ALG_TYPE_SHASH, + .base.cra_blocksize = GHASH_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct ghash_key), + .base.cra_module = THIS_MODULE, + + .digestsize = GHASH_DIGEST_SIZE, + .init = ghash_init, + .update = ghash_update, + .final = ghash_final, + .setkey = ghash_setkey, + .descsize = sizeof(struct ghash_desc_ctx), +}; + +static int num_rounds(struct crypto_aes_ctx *ctx) +{ + /* + * # of rounds specified by AES: + * 128 bit key 10 rounds + * 192 bit key 12 rounds + * 256 bit key 14 rounds + * => n byte key => 6 + (n/4) rounds + */ + return 6 + ctx->key_length / 4; +} + +static int gcm_setkey(struct crypto_aead *tfm, const u8 *inkey, + unsigned int keylen) +{ + struct gcm_aes_ctx *ctx = crypto_aead_ctx(tfm); + u8 key[GHASH_BLOCK_SIZE]; + int ret; + + ret = crypto_aes_expand_key(&ctx->aes_key, inkey, keylen); + if (ret) { + tfm->base.crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + __aes_arm64_encrypt(ctx->aes_key.key_enc, key, (u8[AES_BLOCK_SIZE]){}, + num_rounds(&ctx->aes_key)); + + return __ghash_setkey(&ctx->ghash_key, key, sizeof(key)); +} + +static int gcm_setauthsize(struct crypto_aead *tfm, unsigned int authsize) +{ + switch (authsize) { + case 4: + case 8: + case 12 ... 16: + break; + default: + return -EINVAL; + } + return 0; +} + +static void gcm_update_mac(u64 dg[], const u8 *src, int count, u8 buf[], + int *buf_count, struct gcm_aes_ctx *ctx) +{ + if (*buf_count > 0) { + int buf_added = min(count, GHASH_BLOCK_SIZE - *buf_count); + + memcpy(&buf[*buf_count], src, buf_added); + + *buf_count += buf_added; + src += buf_added; + count -= buf_added; + } + + if (count >= GHASH_BLOCK_SIZE || *buf_count == GHASH_BLOCK_SIZE) { + int blocks = count / GHASH_BLOCK_SIZE; + + ghash_do_update(blocks, dg, src, &ctx->ghash_key, + *buf_count ? buf : NULL); + + src += blocks * GHASH_BLOCK_SIZE; + count %= GHASH_BLOCK_SIZE; + *buf_count = 0; + } + + if (count > 0) { + memcpy(buf, src, count); + *buf_count = count; + } +} + +static void gcm_calculate_auth_mac(struct aead_request *req, u64 dg[]) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct gcm_aes_ctx *ctx = crypto_aead_ctx(aead); + u8 buf[GHASH_BLOCK_SIZE]; + struct scatter_walk walk; + u32 len = req->assoclen; + int buf_count = 0; + + scatterwalk_start(&walk, req->src); + + do { + u32 n = scatterwalk_clamp(&walk, len); + u8 *p; + + if (!n) { + scatterwalk_start(&walk, sg_next(walk.sg)); + n = scatterwalk_clamp(&walk, len); + } + p = scatterwalk_map(&walk); + + gcm_update_mac(dg, p, n, buf, &buf_count, ctx); + len -= n; + + scatterwalk_unmap(p); + scatterwalk_advance(&walk, n); + scatterwalk_done(&walk, 0, len); + } while (len); + + if (buf_count) { + memset(&buf[buf_count], 0, GHASH_BLOCK_SIZE - buf_count); + ghash_do_update(1, dg, buf, &ctx->ghash_key, NULL); + } +} + +static void gcm_final(struct aead_request *req, struct gcm_aes_ctx *ctx, + u64 dg[], u8 tag[], int cryptlen) +{ + u8 mac[AES_BLOCK_SIZE]; + u128 lengths; + + lengths.a = cpu_to_be64(req->assoclen * 8); + lengths.b = cpu_to_be64(cryptlen * 8); + + ghash_do_update(1, dg, (void *)&lengths, &ctx->ghash_key, NULL); + + put_unaligned_be64(dg[1], mac); + put_unaligned_be64(dg[0], mac + 8); + + crypto_xor(tag, mac, AES_BLOCK_SIZE); +} + +static int gcm_encrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct gcm_aes_ctx *ctx = crypto_aead_ctx(aead); + struct skcipher_walk walk; + u8 iv[AES_BLOCK_SIZE]; + u8 ks[AES_BLOCK_SIZE]; + u8 tag[AES_BLOCK_SIZE]; + u64 dg[2] = {}; + int err; + + if (req->assoclen) + gcm_calculate_auth_mac(req, dg); + + memcpy(iv, req->iv, GCM_IV_SIZE); + put_unaligned_be32(1, iv + GCM_IV_SIZE); + + if (likely(may_use_simd())) { + kernel_neon_begin(); + + pmull_gcm_encrypt_block(tag, iv, ctx->aes_key.key_enc, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + pmull_gcm_encrypt_block(ks, iv, NULL, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(3, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_encrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + + pmull_gcm_encrypt(blocks, dg, walk.dst.virt.addr, + walk.src.virt.addr, &ctx->ghash_key, + iv, num_rounds(&ctx->aes_key), ks); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + kernel_neon_end(); + } else { + __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_encrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + u8 *dst = walk.dst.virt.addr; + u8 *src = walk.src.virt.addr; + + do { + __aes_arm64_encrypt(ctx->aes_key.key_enc, + ks, iv, + num_rounds(&ctx->aes_key)); + crypto_xor_cpy(dst, src, ks, AES_BLOCK_SIZE); + crypto_inc(iv, AES_BLOCK_SIZE); + + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + } while (--blocks > 0); + + ghash_do_update(walk.nbytes / AES_BLOCK_SIZE, dg, + walk.dst.virt.addr, &ctx->ghash_key, + NULL); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + if (walk.nbytes) + __aes_arm64_encrypt(ctx->aes_key.key_enc, ks, iv, + num_rounds(&ctx->aes_key)); + } + + /* handle the tail */ + if (walk.nbytes) { + u8 buf[GHASH_BLOCK_SIZE]; + + crypto_xor_cpy(walk.dst.virt.addr, walk.src.virt.addr, ks, + walk.nbytes); + + memcpy(buf, walk.dst.virt.addr, walk.nbytes); + memset(buf + walk.nbytes, 0, GHASH_BLOCK_SIZE - walk.nbytes); + ghash_do_update(1, dg, buf, &ctx->ghash_key, NULL); + + err = skcipher_walk_done(&walk, 0); + } + + if (err) + return err; + + gcm_final(req, ctx, dg, tag, req->cryptlen); + + /* copy authtag to end of dst */ + scatterwalk_map_and_copy(tag, req->dst, req->assoclen + req->cryptlen, + crypto_aead_authsize(aead), 1); + + return 0; +} + +static int gcm_decrypt(struct aead_request *req) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct gcm_aes_ctx *ctx = crypto_aead_ctx(aead); + unsigned int authsize = crypto_aead_authsize(aead); + struct skcipher_walk walk; + u8 iv[AES_BLOCK_SIZE]; + u8 tag[AES_BLOCK_SIZE]; + u8 buf[GHASH_BLOCK_SIZE]; + u64 dg[2] = {}; + int err; + + if (req->assoclen) + gcm_calculate_auth_mac(req, dg); + + memcpy(iv, req->iv, GCM_IV_SIZE); + put_unaligned_be32(1, iv + GCM_IV_SIZE); + + if (likely(may_use_simd())) { + kernel_neon_begin(); + + pmull_gcm_encrypt_block(tag, iv, ctx->aes_key.key_enc, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_decrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + + pmull_gcm_decrypt(blocks, dg, walk.dst.virt.addr, + walk.src.virt.addr, &ctx->ghash_key, + iv, num_rounds(&ctx->aes_key)); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + if (walk.nbytes) + pmull_gcm_encrypt_block(iv, iv, NULL, + num_rounds(&ctx->aes_key)); + + kernel_neon_end(); + } else { + __aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, + num_rounds(&ctx->aes_key)); + put_unaligned_be32(2, iv + GCM_IV_SIZE); + + err = skcipher_walk_aead_decrypt(&walk, req, true); + + while (walk.nbytes >= AES_BLOCK_SIZE) { + int blocks = walk.nbytes / AES_BLOCK_SIZE; + u8 *dst = walk.dst.virt.addr; + u8 *src = walk.src.virt.addr; + + ghash_do_update(blocks, dg, walk.src.virt.addr, + &ctx->ghash_key, NULL); + + do { + __aes_arm64_encrypt(ctx->aes_key.key_enc, + buf, iv, + num_rounds(&ctx->aes_key)); + crypto_xor_cpy(dst, src, buf, AES_BLOCK_SIZE); + crypto_inc(iv, AES_BLOCK_SIZE); + + dst += AES_BLOCK_SIZE; + src += AES_BLOCK_SIZE; + } while (--blocks > 0); + + err = skcipher_walk_done(&walk, + walk.nbytes % AES_BLOCK_SIZE); + } + if (walk.nbytes) + __aes_arm64_encrypt(ctx->aes_key.key_enc, iv, iv, + num_rounds(&ctx->aes_key)); + } + + /* handle the tail */ + if (walk.nbytes) { + memcpy(buf, walk.src.virt.addr, walk.nbytes); + memset(buf + walk.nbytes, 0, GHASH_BLOCK_SIZE - walk.nbytes); + ghash_do_update(1, dg, buf, &ctx->ghash_key, NULL); + + crypto_xor_cpy(walk.dst.virt.addr, walk.src.virt.addr, iv, + walk.nbytes); + + err = skcipher_walk_done(&walk, 0); + } + + if (err) + return err; + + gcm_final(req, ctx, dg, tag, req->cryptlen - authsize); + + /* compare calculated auth tag with the stored one */ + scatterwalk_map_and_copy(buf, req->src, + req->assoclen + req->cryptlen - authsize, + authsize, 0); + + if (crypto_memneq(tag, buf, authsize)) + return -EBADMSG; + return 0; +} + +static struct aead_alg gcm_aes_alg = { + .ivsize = GCM_IV_SIZE, + .chunksize = AES_BLOCK_SIZE, + .maxauthsize = AES_BLOCK_SIZE, + .setkey = gcm_setkey, + .setauthsize = gcm_setauthsize, + .encrypt = gcm_encrypt, + .decrypt = gcm_decrypt, + + .base.cra_name = "gcm(aes)", + .base.cra_driver_name = "gcm-aes-ce", + .base.cra_priority = 300, + .base.cra_blocksize = 1, + .base.cra_ctxsize = sizeof(struct gcm_aes_ctx), + .base.cra_module = THIS_MODULE, }; static int __init ghash_ce_mod_init(void) { - return crypto_register_shash(&ghash_alg); + int ret; + + if (!(elf_hwcap & HWCAP_ASIMD)) + return -ENODEV; + + if (elf_hwcap & HWCAP_PMULL) + pmull_ghash_update = pmull_ghash_update_p64; + + else + pmull_ghash_update = pmull_ghash_update_p8; + + ret = crypto_register_shash(&ghash_alg); + if (ret) + return ret; + + if (elf_hwcap & HWCAP_PMULL) { + ret = crypto_register_aead(&gcm_aes_alg); + if (ret) + crypto_unregister_shash(&ghash_alg); + } + return ret; } static void __exit ghash_ce_mod_exit(void) { crypto_unregister_shash(&ghash_alg); + crypto_unregister_aead(&gcm_aes_alg); } -module_cpu_feature_match(PMULL, ghash_ce_mod_init); +static const struct cpu_feature ghash_cpu_feature[] = { + { cpu_feature(PMULL) }, { } +}; +MODULE_DEVICE_TABLE(cpu, ghash_cpu_feature); + +module_init(ghash_ce_mod_init); module_exit(ghash_ce_mod_exit); diff --git a/arch/arm64/crypto/sha1-ce-glue.c b/arch/arm64/crypto/sha1-ce-glue.c index ea319c055f5d..efbeb3e0dcfb 100644 --- a/arch/arm64/crypto/sha1-ce-glue.c +++ b/arch/arm64/crypto/sha1-ce-glue.c @@ -1,7 +1,7 @@ /* * sha1-ce-glue.c - SHA-1 secure hash using ARMv8 Crypto Extensions * - * Copyright (C) 2014 Linaro Ltd + * Copyright (C) 2014 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -37,8 +38,11 @@ static int sha1_ce_update(struct shash_desc *desc, const u8 *data, { struct sha1_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) + return crypto_sha1_update(desc, data, len); + sctx->finalize = 0; - kernel_neon_begin_partial(16); + kernel_neon_begin(); sha1_base_do_update(desc, data, len, (sha1_block_fn *)sha1_ce_transform); kernel_neon_end(); @@ -52,13 +56,16 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data, struct sha1_ce_state *sctx = shash_desc_ctx(desc); bool finalize = !sctx->sst.count && !(len % SHA1_BLOCK_SIZE); + if (!may_use_simd()) + return crypto_sha1_finup(desc, data, len, out); + /* * Allow the asm code to perform the finalization if there is no * partial data and the input is a round multiple of the block size. */ sctx->finalize = finalize; - kernel_neon_begin_partial(16); + kernel_neon_begin(); sha1_base_do_update(desc, data, len, (sha1_block_fn *)sha1_ce_transform); if (!finalize) @@ -71,8 +78,11 @@ static int sha1_ce_final(struct shash_desc *desc, u8 *out) { struct sha1_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) + return crypto_sha1_finup(desc, NULL, 0, out); + sctx->finalize = 0; - kernel_neon_begin_partial(16); + kernel_neon_begin(); sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform); kernel_neon_end(); return sha1_base_finish(desc, out); diff --git a/arch/arm64/crypto/sha2-ce-glue.c b/arch/arm64/crypto/sha2-ce-glue.c index 0ed9486f75dd..fd1ff2b13dfa 100644 --- a/arch/arm64/crypto/sha2-ce-glue.c +++ b/arch/arm64/crypto/sha2-ce-glue.c @@ -1,7 +1,7 @@ /* * sha2-ce-glue.c - SHA-224/SHA-256 using ARMv8 Crypto Extensions * - * Copyright (C) 2014 Linaro Ltd + * Copyright (C) 2014 - 2017 Linaro Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -34,13 +35,19 @@ const u32 sha256_ce_offsetof_count = offsetof(struct sha256_ce_state, const u32 sha256_ce_offsetof_finalize = offsetof(struct sha256_ce_state, finalize); +asmlinkage void sha256_block_data_order(u32 *digest, u8 const *src, int blocks); + static int sha256_ce_update(struct shash_desc *desc, const u8 *data, unsigned int len) { struct sha256_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) + return sha256_base_do_update(desc, data, len, + (sha256_block_fn *)sha256_block_data_order); + sctx->finalize = 0; - kernel_neon_begin_partial(28); + kernel_neon_begin(); sha256_base_do_update(desc, data, len, (sha256_block_fn *)sha2_ce_transform); kernel_neon_end(); @@ -54,13 +61,22 @@ static int sha256_ce_finup(struct shash_desc *desc, const u8 *data, struct sha256_ce_state *sctx = shash_desc_ctx(desc); bool finalize = !sctx->sst.count && !(len % SHA256_BLOCK_SIZE); + if (!may_use_simd()) { + if (len) + sha256_base_do_update(desc, data, len, + (sha256_block_fn *)sha256_block_data_order); + sha256_base_do_finalize(desc, + (sha256_block_fn *)sha256_block_data_order); + return sha256_base_finish(desc, out); + } + /* * Allow the asm code to perform the finalization if there is no * partial data and the input is a round multiple of the block size. */ sctx->finalize = finalize; - kernel_neon_begin_partial(28); + kernel_neon_begin(); sha256_base_do_update(desc, data, len, (sha256_block_fn *)sha2_ce_transform); if (!finalize) @@ -74,8 +90,14 @@ static int sha256_ce_final(struct shash_desc *desc, u8 *out) { struct sha256_ce_state *sctx = shash_desc_ctx(desc); + if (!may_use_simd()) { + sha256_base_do_finalize(desc, + (sha256_block_fn *)sha256_block_data_order); + return sha256_base_finish(desc, out); + } + sctx->finalize = 0; - kernel_neon_begin_partial(28); + kernel_neon_begin(); sha256_base_do_finalize(desc, (sha256_block_fn *)sha2_ce_transform); kernel_neon_end(); return sha256_base_finish(desc, out); diff --git a/arch/arm64/crypto/sha256-glue.c b/arch/arm64/crypto/sha256-glue.c index a2226f841960..b064d925fe2a 100644 --- a/arch/arm64/crypto/sha256-glue.c +++ b/arch/arm64/crypto/sha256-glue.c @@ -29,6 +29,7 @@ MODULE_ALIAS_CRYPTO("sha256"); asmlinkage void sha256_block_data_order(u32 *digest, const void *data, unsigned int num_blks); +EXPORT_SYMBOL(sha256_block_data_order); asmlinkage void sha256_block_neon(u32 *digest, const void *data, unsigned int num_blks); diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index f81c7b685fc6..2326e39d5892 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -20,7 +20,6 @@ generic-y += rwsem.h generic-y += segment.h generic-y += serial.h generic-y += set_memory.h -generic-y += simd.h generic-y += sizes.h generic-y += switch_to.h generic-y += trace_clock.h diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h index 6e1cb8c5af4d..4a85c6952a22 100644 --- a/arch/arm64/include/asm/alternative.h +++ b/arch/arm64/include/asm/alternative.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ALTERNATIVE_H #define __ASM_ALTERNATIVE_H diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 8cef47fa2218..b7e3f74822da 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -116,6 +116,8 @@ static inline void gic_write_bpr1(u32 val) #define gic_read_typer(c) readq_relaxed(c) #define gic_write_irouter(v, c) writeq_relaxed(v, c) +#define gic_read_lpir(c) readq_relaxed(c) +#define gic_write_lpir(v, c) writeq_relaxed(v, c) #define gic_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) @@ -133,5 +135,10 @@ static inline void gic_write_bpr1(u32 val) #define gicr_write_pendbaser(v, c) writeq_relaxed(v, c) #define gicr_read_pendbaser(c) readq_relaxed(c) +#define gits_write_vpropbaser(v, c) writeq_relaxed(v, c) + +#define gits_write_vpendbaser(v, c) writeq_relaxed(v, c) +#define gits_read_vpendbaser(c) readq_relaxed(c) + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARCH_GICV3_H */ diff --git a/arch/arm64/include/asm/asm-bug.h b/arch/arm64/include/asm/asm-bug.h new file mode 100644 index 000000000000..636e755bcdca --- /dev/null +++ b/arch/arm64/include/asm/asm-bug.h @@ -0,0 +1,54 @@ +#ifndef __ASM_ASM_BUG_H +/* + * Copyright (C) 2017 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#define __ASM_ASM_BUG_H + +#include + +#ifdef CONFIG_DEBUG_BUGVERBOSE +#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line) +#define __BUGVERBOSE_LOCATION(file, line) \ + .pushsection .rodata.str,"aMS",@progbits,1; \ + 2: .string file; \ + .popsection; \ + \ + .long 2b - 0b; \ + .short line; +#else +#define _BUGVERBOSE_LOCATION(file, line) +#endif + +#ifdef CONFIG_GENERIC_BUG + +#define __BUG_ENTRY(flags) \ + .pushsection __bug_table,"aw"; \ + .align 2; \ + 0: .long 1f - 0b; \ +_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ + .short flags; \ + .popsection; \ + 1: +#else +#define __BUG_ENTRY(flags) +#endif + +#define ASM_BUG_FLAGS(flags) \ + __BUG_ENTRY(flags) \ + brk BUG_BRK_IMM + +#define ASM_BUG() ASM_BUG_FLAGS(0) + +#endif /* __ASM_ASM_BUG_H */ diff --git a/arch/arm64/include/asm/asm-uaccess.h b/arch/arm64/include/asm/asm-uaccess.h index ecd9788cd298..b3da6c886835 100644 --- a/arch/arm64/include/asm/asm-uaccess.h +++ b/arch/arm64/include/asm/asm-uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ASM_UACCESS_H #define __ASM_ASM_UACCESS_H diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 1b67c3782d00..d58a6253c6ab 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -230,12 +230,18 @@ lr .req x30 // link register .endm /* - * @dst: Result of per_cpu(sym, smp_processor_id()) + * @dst: Result of per_cpu(sym, smp_processor_id()), can be SP for + * non-module code * @sym: The name of the per-cpu variable * @tmp: scratch register */ .macro adr_this_cpu, dst, sym, tmp +#ifndef MODULE + adrp \tmp, \sym + add \dst, \tmp, #:lo12:\sym +#else adr_l \dst, \sym +#endif mrs \tmp, tpidr_el1 add \dst, \dst, \tmp .endm @@ -352,6 +358,12 @@ alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE dc \op, \kaddr alternative_else dc civac, \kaddr +alternative_endif + .elseif (\op == cvap) +alternative_if ARM64_HAS_DCPOP + sys 3, c7, c12, 1, \kaddr // dc cvap +alternative_else + dc cvac, \kaddr alternative_endif .else dc \op, \kaddr @@ -403,6 +415,17 @@ alternative_endif .size __pi_##x, . - x; \ ENDPROC(x) +/* + * Annotate a function as being unsuitable for kprobes. + */ +#ifdef CONFIG_KPROBES +#define NOKPROBE(x) \ + .pushsection "_kprobe_blacklist", "aw"; \ + .quad x; \ + .popsection; +#else +#define NOKPROBE(x) +#endif /* * Emit a 64-bit absolute little endian symbol reference in a way that * ensures that it will be resolved at build time, even when building a diff --git a/arch/arm64/include/asm/bitrev.h b/arch/arm64/include/asm/bitrev.h index a5a0c3660137..6faf9fba8c65 100644 --- a/arch/arm64/include/asm/bitrev.h +++ b/arch/arm64/include/asm/bitrev.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_BITREV_H #define __ASM_BITREV_H static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x) diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h index ebf2481889c3..355e552a9175 100644 --- a/arch/arm64/include/asm/boot.h +++ b/arch/arm64/include/asm/boot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_BOOT_H #define __ASM_BOOT_H diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h index a02a57186f56..d7dc43752705 100644 --- a/arch/arm64/include/asm/bug.h +++ b/arch/arm64/include/asm/bug.h @@ -18,41 +18,12 @@ #ifndef _ARCH_ARM64_ASM_BUG_H #define _ARCH_ARM64_ASM_BUG_H -#include +#include -#ifdef CONFIG_DEBUG_BUGVERBOSE -#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line) -#define __BUGVERBOSE_LOCATION(file, line) \ - ".pushsection .rodata.str,\"aMS\",@progbits,1\n" \ - "2: .string \"" file "\"\n\t" \ - ".popsection\n\t" \ - \ - ".long 2b - 0b\n\t" \ - ".short " #line "\n\t" -#else -#define _BUGVERBOSE_LOCATION(file, line) -#endif - -#ifdef CONFIG_GENERIC_BUG - -#define __BUG_ENTRY(flags) \ - ".pushsection __bug_table,\"aw\"\n\t" \ - ".align 2\n\t" \ - "0: .long 1f - 0b\n\t" \ -_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ - ".short " #flags "\n\t" \ - ".popsection\n" \ - "1: " -#else -#define __BUG_ENTRY(flags) "" -#endif +#include #define __BUG_FLAGS(flags) \ - asm volatile ( \ - __BUG_ENTRY(flags) \ - "brk %[imm]" :: [imm] "i" (BUG_BRK_IMM) \ - ); - + asm volatile (__stringify(ASM_BUG_FLAGS(flags))); #define BUG() do { \ __BUG_FLAGS(0); \ diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index d74a284abdc2..76d1cc85d5b1 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h @@ -67,7 +67,9 @@ */ extern void flush_icache_range(unsigned long start, unsigned long end); extern void __flush_dcache_area(void *addr, size_t len); +extern void __inval_dcache_area(void *addr, size_t len); extern void __clean_dcache_area_poc(void *addr, size_t len); +extern void __clean_dcache_area_pop(void *addr, size_t len); extern void __clean_dcache_area_pou(void *addr, size_t len); extern long __flush_cache_user_range(unsigned long start, unsigned long end); extern void sync_icache_aliases(void *kaddr, unsigned long len); @@ -150,6 +152,6 @@ static inline void flush_cache_vunmap(unsigned long start, unsigned long end) { } -int set_memory_valid(unsigned long addr, unsigned long size, int enable); +int set_memory_valid(unsigned long addr, int numpages, int enable); #endif diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h index 0b350a7e26f3..0ece64a26c8c 100644 --- a/arch/arm64/include/asm/clocksource.h +++ b/arch/arm64/include/asm/clocksource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CLOCKSOURCE_H #define _ASM_CLOCKSOURCE_H diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index 8d2272c6822c..8da621627d7c 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -39,7 +39,8 @@ #define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18 #define ARM64_WORKAROUND_858921 19 #define ARM64_WORKAROUND_CAVIUM_30115 20 +#define ARM64_HAS_DCPOP 21 -#define ARM64_NCAPS 21 +#define ARM64_NCAPS 22 #endif /* __ASM_CPUCAPS_H */ diff --git a/arch/arm64/include/asm/cpuidle.h b/arch/arm64/include/asm/cpuidle.h index 0f74f05d662a..3c5ddb429ea2 100644 --- a/arch/arm64/include/asm/cpuidle.h +++ b/arch/arm64/include/asm/cpuidle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPUIDLE_H #define __ASM_CPUIDLE_H diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h index f6580d4afb0e..54ceae0874c7 100644 --- a/arch/arm64/include/asm/current.h +++ b/arch/arm64/include/asm/current.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CURRENT_H #define __ASM_CURRENT_H diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 8f3043aba873..650344d01124 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -1,9 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_EFI_H #define _ASM_EFI_H #include #include +#include #include +#include #include #include #include @@ -20,8 +23,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define arch_efi_call_virt_setup() \ ({ \ - kernel_neon_begin(); \ efi_virtmap_load(); \ + __efi_fpsimd_begin(); \ }) #define arch_efi_call_virt(p, f, args...) \ @@ -33,8 +36,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); #define arch_efi_call_virt_teardown() \ ({ \ + __efi_fpsimd_end(); \ efi_virtmap_unload(); \ - kernel_neon_end(); \ }) #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) @@ -48,6 +51,13 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); */ #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ +/* + * In some configurations (e.g. VMAP_STACK && 64K pages), stacks built into the + * kernel need greater alignment than we require the segments to be padded to. + */ +#define EFI_KIMG_ALIGN \ + (SEGMENT_ALIGN > THREAD_ALIGN ? SEGMENT_ALIGN : THREAD_ALIGN) + /* on arm64, the FDT may be located anywhere in system RAM */ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) { @@ -81,6 +91,9 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, #define alloc_screen_info(x...) &screen_info #define free_screen_info(x...) +/* redeclare as 'hidden' so the compiler will generate relative references */ +extern struct screen_info screen_info __attribute__((__visibility__("hidden"))); + static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) { } diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 3288c2b36731..33be513ef24c 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -139,7 +139,6 @@ typedef struct user_fpsimd_state elf_fpregset_t; #define SET_PERSONALITY(ex) \ ({ \ - clear_bit(TIF_32BIT, ¤t->mm->context.flags); \ clear_thread_flag(TIF_32BIT); \ current->personality &= ~READ_IMPLIES_EXEC; \ }) @@ -195,7 +194,6 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; */ #define COMPAT_SET_PERSONALITY(ex) \ ({ \ - set_bit(TIF_32BIT, ¤t->mm->context.flags); \ set_thread_flag(TIF_32BIT); \ }) #define COMPAT_ARCH_DLINFO diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index 8cabd57b6348..66ed8b6b9976 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -77,16 +77,23 @@ #define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) #define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) -#define ESR_ELx_IL (UL(1) << 25) +#define ESR_ELx_IL_SHIFT (25) +#define ESR_ELx_IL (UL(1) << ESR_ELx_IL_SHIFT) #define ESR_ELx_ISS_MASK (ESR_ELx_IL - 1) /* ISS field definitions shared by different classes */ -#define ESR_ELx_WNR (UL(1) << 6) +#define ESR_ELx_WNR_SHIFT (6) +#define ESR_ELx_WNR (UL(1) << ESR_ELx_WNR_SHIFT) /* Shared ISS field definitions for Data/Instruction aborts */ -#define ESR_ELx_FnV (UL(1) << 10) -#define ESR_ELx_EA (UL(1) << 9) -#define ESR_ELx_S1PTW (UL(1) << 7) +#define ESR_ELx_SET_SHIFT (11) +#define ESR_ELx_SET_MASK (UL(3) << ESR_ELx_SET_SHIFT) +#define ESR_ELx_FnV_SHIFT (10) +#define ESR_ELx_FnV (UL(1) << ESR_ELx_FnV_SHIFT) +#define ESR_ELx_EA_SHIFT (9) +#define ESR_ELx_EA (UL(1) << ESR_ELx_EA_SHIFT) +#define ESR_ELx_S1PTW_SHIFT (7) +#define ESR_ELx_S1PTW (UL(1) << ESR_ELx_S1PTW_SHIFT) /* Shared ISS fault status code(IFSC/DFSC) for Data/Instruction aborts */ #define ESR_ELx_FSC (0x3F) @@ -97,15 +104,20 @@ #define ESR_ELx_FSC_PERM (0x0C) /* ISS field definitions for Data Aborts */ -#define ESR_ELx_ISV (UL(1) << 24) +#define ESR_ELx_ISV_SHIFT (24) +#define ESR_ELx_ISV (UL(1) << ESR_ELx_ISV_SHIFT) #define ESR_ELx_SAS_SHIFT (22) #define ESR_ELx_SAS (UL(3) << ESR_ELx_SAS_SHIFT) -#define ESR_ELx_SSE (UL(1) << 21) +#define ESR_ELx_SSE_SHIFT (21) +#define ESR_ELx_SSE (UL(1) << ESR_ELx_SSE_SHIFT) #define ESR_ELx_SRT_SHIFT (16) #define ESR_ELx_SRT_MASK (UL(0x1F) << ESR_ELx_SRT_SHIFT) -#define ESR_ELx_SF (UL(1) << 15) -#define ESR_ELx_AR (UL(1) << 14) -#define ESR_ELx_CM (UL(1) << 8) +#define ESR_ELx_SF_SHIFT (15) +#define ESR_ELx_SF (UL(1) << ESR_ELx_SF_SHIFT) +#define ESR_ELx_AR_SHIFT (14) +#define ESR_ELx_AR (UL(1) << ESR_ELx_AR_SHIFT) +#define ESR_ELx_CM_SHIFT (8) +#define ESR_ELx_CM (UL(1) << ESR_ELx_CM_SHIFT) /* ISS field definitions for exceptions taken in to Hyp */ #define ESR_ELx_CV (UL(1) << 24) @@ -157,9 +169,10 @@ /* * User space cache operations have the following sysreg encoding * in System instructions. - * op0=1, op1=3, op2=1, crn=7, crm={ 5, 10, 11, 14 }, WRITE (L=0) + * op0=1, op1=3, op2=1, crn=7, crm={ 5, 10, 11, 12, 14 }, WRITE (L=0) */ #define ESR_ELx_SYS64_ISS_CRM_DC_CIVAC 14 +#define ESR_ELx_SYS64_ISS_CRM_DC_CVAP 12 #define ESR_ELx_SYS64_ISS_CRM_DC_CVAU 11 #define ESR_ELx_SYS64_ISS_CRM_DC_CVAC 10 #define ESR_ELx_SYS64_ISS_CRM_IC_IVAU 5 @@ -209,6 +222,13 @@ #ifndef __ASSEMBLY__ #include +static inline bool esr_is_data_abort(u32 esr) +{ + const u32 ec = ESR_ELx_EC(esr); + + return ec == ESR_ELx_EC_DABT_LOW || ec == ESR_ELx_EC_DABT_CUR; +} + const char *esr_get_class_string(u32 esr); #endif /* __ASSEMBLY */ diff --git a/arch/arm64/include/asm/extable.h b/arch/arm64/include/asm/extable.h index 42f50f15a44c..56a4f68b262e 100644 --- a/arch/arm64/include/asm/extable.h +++ b/arch/arm64/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_EXTABLE_H #define __ASM_EXTABLE_H diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 50f559f574fe..410c48163c6a 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -41,16 +41,6 @@ struct fpsimd_state { unsigned int cpu; }; -/* - * Struct for stacking the bottom 'n' FP/SIMD registers. - */ -struct fpsimd_partial_state { - u32 fpsr; - u32 fpcr; - u32 num_regs; - __uint128_t vregs[32]; -}; - #if defined(__KERNEL__) && defined(CONFIG_COMPAT) /* Masks for extracting the FPSR and FPCR from the FPSCR */ @@ -77,9 +67,9 @@ extern void fpsimd_update_current_state(struct fpsimd_state *state); extern void fpsimd_flush_task_state(struct task_struct *target); -extern void fpsimd_save_partial_state(struct fpsimd_partial_state *state, - u32 num_regs); -extern void fpsimd_load_partial_state(struct fpsimd_partial_state *state); +/* For use by EFI runtime services calls only */ +extern void __efi_fpsimd_begin(void); +extern void __efi_fpsimd_end(void); #endif diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h index a2daf1293028..0f5fdd388b0d 100644 --- a/arch/arm64/include/asm/fpsimdmacros.h +++ b/arch/arm64/include/asm/fpsimdmacros.h @@ -75,59 +75,3 @@ ldr w\tmpnr, [\state, #16 * 2 + 4] fpsimd_restore_fpcr x\tmpnr, \state .endm - -.macro fpsimd_save_partial state, numnr, tmpnr1, tmpnr2 - mrs x\tmpnr1, fpsr - str w\numnr, [\state, #8] - mrs x\tmpnr2, fpcr - stp w\tmpnr1, w\tmpnr2, [\state] - adr x\tmpnr1, 0f - add \state, \state, x\numnr, lsl #4 - sub x\tmpnr1, x\tmpnr1, x\numnr, lsl #1 - br x\tmpnr1 - stp q30, q31, [\state, #-16 * 30 - 16] - stp q28, q29, [\state, #-16 * 28 - 16] - stp q26, q27, [\state, #-16 * 26 - 16] - stp q24, q25, [\state, #-16 * 24 - 16] - stp q22, q23, [\state, #-16 * 22 - 16] - stp q20, q21, [\state, #-16 * 20 - 16] - stp q18, q19, [\state, #-16 * 18 - 16] - stp q16, q17, [\state, #-16 * 16 - 16] - stp q14, q15, [\state, #-16 * 14 - 16] - stp q12, q13, [\state, #-16 * 12 - 16] - stp q10, q11, [\state, #-16 * 10 - 16] - stp q8, q9, [\state, #-16 * 8 - 16] - stp q6, q7, [\state, #-16 * 6 - 16] - stp q4, q5, [\state, #-16 * 4 - 16] - stp q2, q3, [\state, #-16 * 2 - 16] - stp q0, q1, [\state, #-16 * 0 - 16] -0: -.endm - -.macro fpsimd_restore_partial state, tmpnr1, tmpnr2 - ldp w\tmpnr1, w\tmpnr2, [\state] - msr fpsr, x\tmpnr1 - fpsimd_restore_fpcr x\tmpnr2, x\tmpnr1 - adr x\tmpnr1, 0f - ldr w\tmpnr2, [\state, #8] - add \state, \state, x\tmpnr2, lsl #4 - sub x\tmpnr1, x\tmpnr1, x\tmpnr2, lsl #1 - br x\tmpnr1 - ldp q30, q31, [\state, #-16 * 30 - 16] - ldp q28, q29, [\state, #-16 * 28 - 16] - ldp q26, q27, [\state, #-16 * 26 - 16] - ldp q24, q25, [\state, #-16 * 24 - 16] - ldp q22, q23, [\state, #-16 * 22 - 16] - ldp q20, q21, [\state, #-16 * 20 - 16] - ldp q18, q19, [\state, #-16 * 18 - 16] - ldp q16, q17, [\state, #-16 * 16 - 16] - ldp q14, q15, [\state, #-16 * 14 - 16] - ldp q12, q13, [\state, #-16 * 12 - 16] - ldp q10, q11, [\state, #-16 * 10 - 16] - ldp q8, q9, [\state, #-16 * 8 - 16] - ldp q6, q7, [\state, #-16 * 6 - 16] - ldp q4, q5, [\state, #-16 * 4 - 16] - ldp q2, q3, [\state, #-16 * 2 - 16] - ldp q0, q1, [\state, #-16 * 0 - 16] -0: -.endm diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index f32b42e8725d..5bb2fd4674e7 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -48,20 +48,10 @@ do { \ } while (0) static inline int -futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (int)(encoded_op << 8) >> 20; - int cmparg = (int)(encoded_op << 20) >> 20; int oldval = 0, ret, tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1U << (oparg & 0x1f); - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -91,17 +81,9 @@ futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h index 793bd73b0d07..1dca41bea16a 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -18,7 +18,6 @@ #ifndef __ASM_HUGETLB_H #define __ASM_HUGETLB_H -#include #include static inline pte_t huge_ptep_get(pte_t *ptep) @@ -82,6 +81,14 @@ extern void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep); extern void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); +extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long sz); +#define huge_pte_clear huge_pte_clear +extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, unsigned long sz); +#define set_huge_swap_pte_at set_huge_swap_pte_at + +#include #ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE static inline bool gigantic_page_supported(void) { return true; } diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h index d2c79049ff11..f9cc1d021791 100644 --- a/arch/arm64/include/asm/hypervisor.h +++ b/arch/arm64/include/asm/hypervisor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM64_HYPERVISOR_H #define _ASM_ARM64_HYPERVISOR_H diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h index b77197d941fc..a0fee6985e6a 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h @@ -1,45 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_IRQ_H #define __ASM_IRQ_H -#define IRQ_STACK_SIZE THREAD_SIZE -#define IRQ_STACK_START_SP THREAD_START_SP - #ifndef __ASSEMBLER__ -#include - #include -#include struct pt_regs; -DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack); - -/* - * The highest address on the stack, and the first to be used. Used to - * find the dummy-stack frame put down by el?_irq() in entry.S, which - * is structured as follows: - * - * ------------ - * | | <- irq_stack_ptr - * top ------------ - * | x19 | <- irq_stack_ptr - 0x08 - * ------------ - * | x29 | <- irq_stack_ptr - 0x10 - * ------------ - * - * where x19 holds a copy of the task stack pointer where the struct pt_regs - * from kernel_entry can be found. - * - */ -#define IRQ_STACK_PTR(cpu) ((unsigned long)per_cpu(irq_stack, cpu) + IRQ_STACK_START_SP) - -/* - * The offset from irq_stack_ptr where entry.S will store the original - * stack pointer. Used by unwind_frame() and dump_backtrace(). - */ -#define IRQ_STACK_TO_TASK_STACK(ptr) (*((unsigned long *)((ptr) - 0x08))) - extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); static inline int nr_legacy_irqs(void) @@ -47,14 +15,5 @@ static inline int nr_legacy_irqs(void) return 0; } -static inline bool on_irq_stack(unsigned long sp, int cpu) -{ - /* variable names the same as kernel/stacktrace.c */ - unsigned long low = (unsigned long)per_cpu(irq_stack, cpu); - unsigned long high = low + IRQ_STACK_START_SP; - - return (low <= sp && sp <= high); -} - #endif /* !__ASSEMBLER__ */ #endif diff --git a/arch/arm64/include/asm/irq_work.h b/arch/arm64/include/asm/irq_work.h index 8e24ef3f7c82..8a1ef1907760 100644 --- a/arch/arm64/include/asm/irq_work.h +++ b/arch/arm64/include/asm/irq_work.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_IRQ_WORK_H #define __ASM_IRQ_WORK_H diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h index 71ad0f93eb71..e266f80e45b7 100644 --- a/arch/arm64/include/asm/kasan.h +++ b/arch/arm64/include/asm/kasan.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_KASAN_H #define __ASM_KASAN_H diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index fe39e6841326..e5df3fce0008 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -188,11 +188,6 @@ static inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu) return (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT; } -static inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu) -{ - return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_EA); -} - static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) { return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW); @@ -240,6 +235,25 @@ static inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vcpu) return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC_TYPE; } +static inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu) +{ + switch (kvm_vcpu_trap_get_fault_type(vcpu)) { + case FSC_SEA: + case FSC_SEA_TTW0: + case FSC_SEA_TTW1: + case FSC_SEA_TTW2: + case FSC_SEA_TTW3: + case FSC_SECC: + case FSC_SECC_TTW0: + case FSC_SECC_TTW1: + case FSC_SECC_TTW2: + case FSC_SECC_TTW3: + return true; + default: + return false; + } +} + static inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu) { u32 esr = kvm_vcpu_get_hsr(vcpu); diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index a89cc22abadc..672c8684d5c2 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -175,18 +175,15 @@ static inline pmd_t kvm_s2pmd_mkwrite(pmd_t pmd) static inline void kvm_set_s2pte_readonly(pte_t *pte) { - pteval_t pteval; - unsigned long tmp; + pteval_t old_pteval, pteval; - asm volatile("// kvm_set_s2pte_readonly\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " and %0, %0, %3 // clear PTE_S2_RDWR\n" - " orr %0, %0, %4 // set PTE_S2_RDONLY\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*pte)) - : "L" (~PTE_S2_RDWR), "L" (PTE_S2_RDONLY)); + pteval = READ_ONCE(pte_val(*pte)); + do { + old_pteval = pteval; + pteval &= ~PTE_S2_RDWR; + pteval |= PTE_S2_RDONLY; + pteval = cmpxchg_relaxed(&pte_val(*pte), old_pteval, pteval); + } while (pteval != old_pteval); } static inline bool kvm_s2pte_readonly(pte_t *pte) diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h index 636c1bced7d4..1b266292f0be 100644 --- a/arch/arm64/include/asm/linkage.h +++ b/arch/arm64/include/asm/linkage.h @@ -1,7 +1,7 @@ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H -#define __ALIGN .align 4 -#define __ALIGN_STR ".align 4" +#define __ALIGN .align 2 +#define __ALIGN_STR ".align 2" #endif diff --git a/arch/arm64/include/asm/lse.h b/arch/arm64/include/asm/lse.h index 606b20910a5c..eec95768eaad 100644 --- a/arch/arm64/include/asm/lse.h +++ b/arch/arm64/include/asm/lse.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LSE_H #define __ASM_LSE_H diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h index ef39dcb9ca6a..f7c4d2146aed 100644 --- a/arch/arm64/include/asm/memory.h +++ b/arch/arm64/include/asm/memory.h @@ -25,6 +25,7 @@ #include #include #include +#include #include /* @@ -94,13 +95,68 @@ #define KERNEL_END _end /* - * The size of the KASAN shadow region. This should be 1/8th of the - * size of the entire kernel virtual address space. + * KASAN requires 1/8th of the kernel virtual address space for the shadow + * region. KASAN can bloat the stack significantly, so double the (minimum) + * stack size when KASAN is in use. */ #ifdef CONFIG_KASAN #define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3)) +#define KASAN_THREAD_SHIFT 1 #else #define KASAN_SHADOW_SIZE (0) +#define KASAN_THREAD_SHIFT 0 +#endif + +#define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT) + +/* + * VMAP'd stacks are allocated at page granularity, so we must ensure that such + * stacks are a multiple of page size. + */ +#if defined(CONFIG_VMAP_STACK) && (MIN_THREAD_SHIFT < PAGE_SHIFT) +#define THREAD_SHIFT PAGE_SHIFT +#else +#define THREAD_SHIFT MIN_THREAD_SHIFT +#endif + +#if THREAD_SHIFT >= PAGE_SHIFT +#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT) +#endif + +#define THREAD_SIZE (UL(1) << THREAD_SHIFT) + +/* + * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by + * checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry + * assembly. + */ +#ifdef CONFIG_VMAP_STACK +#define THREAD_ALIGN (2 * THREAD_SIZE) +#else +#define THREAD_ALIGN THREAD_SIZE +#endif + +#define IRQ_STACK_SIZE THREAD_SIZE + +#define OVERFLOW_STACK_SIZE SZ_4K + +/* + * Alignment of kernel segments (e.g. .text, .data). + */ +#if defined(CONFIG_DEBUG_ALIGN_RODATA) +/* + * 4 KB granule: 1 level 2 entry + * 16 KB granule: 128 level 3 entries, with contiguous bit + * 64 KB granule: 32 level 3 entries, with contiguous bit + */ +#define SEGMENT_ALIGN SZ_2M +#else +/* + * 4 KB granule: 16 level 3 entries, with contiguous bit + * 16 KB granule: 4 level 3 entries, without contiguous bit + * 64 KB granule: 1 level 3 entry + */ +#define SEGMENT_ALIGN SZ_64K #endif /* diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 5468c834b072..0d34bf0a89c7 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -16,6 +16,8 @@ #ifndef __ASM_MMU_H #define __ASM_MMU_H +#define MMCF_AARCH32 0x1 /* mm context flag for AArch32 executables */ + typedef struct { atomic64_t id; void *vdso; diff --git a/arch/arm64/include/asm/mmzone.h b/arch/arm64/include/asm/mmzone.h index a0de9e6ba73f..fa17e01d9ab2 100644 --- a/arch/arm64/include/asm/mmzone.h +++ b/arch/arm64/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MMZONE_H #define __ASM_MMZONE_H diff --git a/arch/arm64/include/asm/neon.h b/arch/arm64/include/asm/neon.h index ad4cdc966c0f..f922eaf780f9 100644 --- a/arch/arm64/include/asm/neon.h +++ b/arch/arm64/include/asm/neon.h @@ -8,12 +8,22 @@ * published by the Free Software Foundation. */ +#ifndef __ASM_NEON_H +#define __ASM_NEON_H + #include #include #define cpu_has_neon() system_supports_fpsimd() -#define kernel_neon_begin() kernel_neon_begin_partial(32) - -void kernel_neon_begin_partial(u32 num_regs); +void kernel_neon_begin(void); void kernel_neon_end(void); + +/* + * Temporary macro to allow the crypto code to compile. Note that the + * semantics of kernel_neon_begin_partial() are now different from the + * original as it does not allow being called in an interrupt context. + */ +#define kernel_neon_begin_partial(num_regs) kernel_neon_begin() + +#endif /* ! __ASM_NEON_H */ diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h index bf466d1876e3..01bc46d5b43a 100644 --- a/arch/arm64/include/asm/numa.h +++ b/arch/arm64/include/asm/numa.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_NUMA_H #define __ASM_NUMA_H @@ -7,9 +8,6 @@ #define NR_NODE_MEMBLKS (MAX_NUMNODES * 2) -/* currently, arm64 implements flat NUMA topology */ -#define parent_node(node) (node) - int __node_distance(int from, int to); #define node_distance(a, b) __node_distance(a, b) diff --git a/arch/arm64/include/asm/page-def.h b/arch/arm64/include/asm/page-def.h new file mode 100644 index 000000000000..01591a29dc2e --- /dev/null +++ b/arch/arm64/include/asm/page-def.h @@ -0,0 +1,34 @@ +/* + * Based on arch/arm/include/asm/page.h + * + * Copyright (C) 1995-2003 Russell King + * Copyright (C) 2017 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __ASM_PAGE_DEF_H +#define __ASM_PAGE_DEF_H + +#include + +/* PAGE_SHIFT determines the page size */ +/* CONT_SHIFT determines the number of pages which can be tracked together */ +#define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT +#define CONT_SHIFT CONFIG_ARM64_CONT_SHIFT +#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#define CONT_SIZE (_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT)) +#define CONT_MASK (~(CONT_SIZE-1)) + +#endif /* __ASM_PAGE_DEF_H */ diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 8472c6def5ef..60d02c81a3a2 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -19,17 +19,7 @@ #ifndef __ASM_PAGE_H #define __ASM_PAGE_H -#include - -/* PAGE_SHIFT determines the page size */ -/* CONT_SHIFT determines the number of pages which can be tracked together */ -#define PAGE_SHIFT CONFIG_ARM64_PAGE_SHIFT -#define CONT_SHIFT CONFIG_ARM64_CONT_SHIFT -#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) - -#define CONT_SIZE (_AC(1, UL) << (CONT_SHIFT + PAGE_SHIFT)) -#define CONT_MASK (~(CONT_SIZE-1)) +#include #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h index fd5f42886251..bb5dcea42003 100644 --- a/arch/arm64/include/asm/paravirt.h +++ b/arch/arm64/include/asm/paravirt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM64_PARAVIRT_H #define _ASM_ARM64_PARAVIRT_H diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h index 1fc19744ffe9..8747f7c5e0e7 100644 --- a/arch/arm64/include/asm/pci.h +++ b/arch/arm64/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_PCI_H #define __ASM_PCI_H #ifdef __KERNEL__ diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 2142c7726e76..0a5635fb0ef9 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -63,23 +63,21 @@ #define PAGE_S2 __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY) #define PAGE_S2_DEVICE __pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_UXN) -#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_PXN | PTE_UXN) +#define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN) #define PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_WRITE) -#define PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) -#define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) -#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) -#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) -#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN) +#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) +#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) +#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN) #define __P000 PAGE_NONE #define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY +#define __P010 PAGE_READONLY +#define __P011 PAGE_READONLY #define __P100 PAGE_EXECONLY #define __P101 PAGE_READONLY_EXEC -#define __P110 PAGE_COPY_EXEC -#define __P111 PAGE_COPY_EXEC +#define __P110 PAGE_READONLY_EXEC +#define __P111 PAGE_READONLY_EXEC #define __S000 PAGE_NONE #define __S001 PAGE_READONLY diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 6eae342ced6b..b46e54c2399b 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -39,6 +39,7 @@ #ifndef __ASSEMBLY__ +#include #include #include @@ -84,11 +85,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; (__boundary - 1 < (end) - 1) ? __boundary : (end); \ }) -#ifdef CONFIG_ARM64_HW_AFDBM #define pte_hw_dirty(pte) (pte_write(pte) && !(pte_val(pte) & PTE_RDONLY)) -#else -#define pte_hw_dirty(pte) (0) -#endif #define pte_sw_dirty(pte) (!!(pte_val(pte) & PTE_DIRTY)) #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) @@ -124,12 +121,16 @@ static inline pte_t set_pte_bit(pte_t pte, pgprot_t prot) static inline pte_t pte_wrprotect(pte_t pte) { - return clear_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); + return pte; } static inline pte_t pte_mkwrite(pte_t pte) { - return set_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = clear_pte_bit(pte, __pgprot(PTE_RDONLY)); + return pte; } static inline pte_t pte_mkclean(pte_t pte) @@ -168,11 +169,6 @@ static inline pte_t pte_mknoncont(pte_t pte) return clear_pte_bit(pte, __pgprot(PTE_CONT)); } -static inline pte_t pte_clear_rdonly(pte_t pte) -{ - return clear_pte_bit(pte, __pgprot(PTE_RDONLY)); -} - static inline pte_t pte_mkpresent(pte_t pte) { return set_pte_bit(pte, __pgprot(PTE_VALID)); @@ -220,22 +216,15 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr); static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { - if (pte_present(pte)) { - if (pte_sw_dirty(pte) && pte_write(pte)) - pte_val(pte) &= ~PTE_RDONLY; - else - pte_val(pte) |= PTE_RDONLY; - if (pte_user_exec(pte) && !pte_special(pte)) - __sync_icache_dcache(pte, addr); - } + if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) + __sync_icache_dcache(pte, addr); /* * If the existing pte is valid, check for potential race with * hardware updates of the pte (ptep_set_access_flags safely changes * valid ptes without going through an invalid entry). */ - if (IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && - pte_valid(*ptep) && pte_valid(pte)) { + if (pte_valid(*ptep) && pte_valid(pte)) { VM_WARN_ONCE(!pte_young(pte), "%s: racy access flag clearing: 0x%016llx -> 0x%016llx", __func__, pte_val(*ptep), pte_val(pte)); @@ -412,7 +401,7 @@ static inline phys_addr_t pmd_page_paddr(pmd_t pmd) /* Find an entry in the third-level page table. */ #define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) -#define pte_offset_phys(dir,addr) (pmd_page_paddr(*(dir)) + pte_index(addr) * sizeof(pte_t)) +#define pte_offset_phys(dir,addr) (pmd_page_paddr(READ_ONCE(*(dir))) + pte_index(addr) * sizeof(pte_t)) #define pte_offset_kernel(dir,addr) ((pte_t *)__va(pte_offset_phys((dir), (addr)))) #define pte_offset_map(dir,addr) pte_offset_kernel((dir), (addr)) @@ -571,7 +560,6 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) return pte_pmd(pte_modify(pmd_pte(pmd), newprot)); } -#ifdef CONFIG_ARM64_HW_AFDBM #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, @@ -593,20 +581,17 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma, #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG static inline int __ptep_test_and_clear_young(pte_t *ptep) { - pteval_t pteval; - unsigned int tmp, res; + pte_t old_pte, pte; - asm volatile("// __ptep_test_and_clear_young\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " ubfx %w3, %w0, %5, #1 // extract PTE_AF (young)\n" - " and %0, %0, %4 // clear PTE_AF\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*ptep)), "=&r" (res) - : "L" (~PTE_AF), "I" (ilog2(PTE_AF))); + pte = READ_ONCE(*ptep); + do { + old_pte = pte; + pte = pte_mkold(pte); + pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), + pte_val(old_pte), pte_val(pte)); + } while (pte_val(pte) != pte_val(old_pte)); - return res; + return pte_young(pte); } static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, @@ -630,17 +615,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma, static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - pteval_t old_pteval; - unsigned int tmp; - - asm volatile("// ptep_get_and_clear\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " stxr %w1, xzr, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))); - - return __pte(old_pteval); + return __pte(xchg_relaxed(&pte_val(*ptep), 0)); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -653,27 +628,32 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ /* - * ptep_set_wrprotect - mark read-only while trasferring potential hardware - * dirty status (PTE_DBM && !PTE_RDONLY) to the software PTE_DIRTY bit. + * ptep_set_wrprotect - mark read-only while preserving the hardware update of + * the Access Flag. */ #define __HAVE_ARCH_PTEP_SET_WRPROTECT static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - pteval_t pteval; - unsigned long tmp; + pte_t old_pte, pte; - asm volatile("// ptep_set_wrprotect\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " tst %0, %4 // check for hw dirty (!PTE_RDONLY)\n" - " csel %1, %3, xzr, eq // set PTE_DIRTY|PTE_RDONLY if dirty\n" - " orr %0, %0, %1 // if !dirty, PTE_RDONLY is already set\n" - " and %0, %0, %5 // clear PTE_WRITE/PTE_DBM\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (pteval), "=&r" (tmp), "+Q" (pte_val(*ptep)) - : "r" (PTE_DIRTY|PTE_RDONLY), "L" (PTE_RDONLY), "L" (~PTE_WRITE) - : "cc"); + /* + * ptep_set_wrprotect() is only called on CoW mappings which are + * private (!VM_SHARED) with the pte either read-only (!PTE_WRITE && + * PTE_RDONLY) or writable and software-dirty (PTE_WRITE && + * !PTE_RDONLY && PTE_DIRTY); see is_cow_mapping() and + * protection_map[]. There is no race with the hardware update of the + * dirty state: clearing of PTE_RDONLY when PTE_WRITE (a.k.a. PTE_DBM) + * is set. + */ + VM_WARN_ONCE(pte_write(*ptep) && !pte_dirty(*ptep), + "%s: potential race with hardware DBM", __func__); + pte = READ_ONCE(*ptep); + do { + old_pte = pte; + pte = pte_wrprotect(pte); + pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), + pte_val(old_pte), pte_val(pte)); + } while (pte_val(pte) != pte_val(old_pte)); } #ifdef CONFIG_TRANSPARENT_HUGEPAGE @@ -684,7 +664,6 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, ptep_set_wrprotect(mm, address, (pte_t *)pmdp); } #endif -#endif /* CONFIG_ARM64_HW_AFDBM */ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 64c9e78f9882..29adab8138c3 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -112,7 +112,7 @@ void tls_preserve_current_state(void); static inline void start_thread_common(struct pt_regs *regs, unsigned long pc) { memset(regs, 0, sizeof(*regs)); - regs->syscallno = ~0UL; + forget_syscall(regs); regs->pc = pc; } @@ -159,7 +159,7 @@ extern struct task_struct *cpu_switch_to(struct task_struct *prev, struct task_struct *next); #define task_pt_regs(p) \ - ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) + ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) #define KSTK_EIP(tsk) ((unsigned long)task_pt_regs(tsk)->pc) #define KSTK_ESP(tsk) user_stack_pointer(task_pt_regs(tsk)) diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 11403fdd0a50..6069d66e0bc2 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -72,8 +72,19 @@ #define COMPAT_PT_TEXT_ADDR 0x10000 #define COMPAT_PT_DATA_ADDR 0x10004 #define COMPAT_PT_TEXT_END_ADDR 0x10008 + +/* + * If pt_regs.syscallno == NO_SYSCALL, then the thread is not executing + * a syscall -- i.e., its most recent entry into the kernel from + * userspace was not via SVC, or otherwise a tracer cancelled the syscall. + * + * This must have the value -1, for ABI compatibility with ptrace etc. + */ +#define NO_SYSCALL (-1) + #ifndef __ASSEMBLY__ #include +#include /* sizeof(struct user) for AArch32 */ #define COMPAT_USER_SZ 296 @@ -116,11 +127,29 @@ struct pt_regs { }; }; u64 orig_x0; - u64 syscallno; +#ifdef __AARCH64EB__ + u32 unused2; + s32 syscallno; +#else + s32 syscallno; + u32 unused2; +#endif + u64 orig_addr_limit; u64 unused; // maintain 16 byte alignment + u64 stackframe[2]; }; +static inline bool in_syscall(struct pt_regs const *regs) +{ + return regs->syscallno != NO_SYSCALL; +} + +static inline void forget_syscall(struct pt_regs *regs) +{ + regs->syscallno = NO_SYSCALL; +} + #define MAX_REG_OFFSET offsetof(struct pt_regs, pstate) #define arch_has_single_step() (1) diff --git a/arch/arm64/include/asm/signal32.h b/arch/arm64/include/asm/signal32.h index eeaa97559bab..81abea0b7650 100644 --- a/arch/arm64/include/asm/signal32.h +++ b/arch/arm64/include/asm/signal32.h @@ -22,8 +22,6 @@ #define AARCH32_KERN_SIGRET_CODE_OFFSET 0x500 -extern const compat_ulong_t aarch32_sigret_code[6]; - int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs); int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h new file mode 100644 index 000000000000..fa8b3fe932e6 --- /dev/null +++ b/arch/arm64/include/asm/simd.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 Linaro Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#ifndef __ASM_SIMD_H +#define __ASM_SIMD_H + +#include +#include +#include +#include +#include + +#ifdef CONFIG_KERNEL_MODE_NEON + +DECLARE_PER_CPU(bool, kernel_neon_busy); + +/* + * may_use_simd - whether it is allowable at this time to issue SIMD + * instructions or access the SIMD register file + * + * Callers must not assume that the result remains true beyond the next + * preempt_enable() or return from softirq context. + */ +static __must_check inline bool may_use_simd(void) +{ + /* + * The raw_cpu_read() is racy if called with preemption enabled. + * This is not a bug: kernel_neon_busy is only set when + * preemption is disabled, so we cannot migrate to another CPU + * while it is set, nor can we migrate to a CPU where it is set. + * So, if we find it clear on some CPU then we're guaranteed to + * find it clear on any CPU we could migrate to. + * + * If we are in between kernel_neon_begin()...kernel_neon_end(), + * the flag will be set, but preemption is also disabled, so we + * can't migrate to another CPU and spuriously see it become + * false. + */ + return !in_irq() && !irqs_disabled() && !in_nmi() && + !raw_cpu_read(kernel_neon_busy); +} + +#else /* ! CONFIG_KERNEL_MODE_NEON */ + +static __must_check inline bool may_use_simd(void) { + return false; +} + +#endif /* ! CONFIG_KERNEL_MODE_NEON */ + +#endif diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 55f08c5acfad..f82b447bd34f 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -148,7 +148,7 @@ static inline void cpu_panic_kernel(void) */ bool cpus_are_stuck_in_kernel(void); -extern void smp_send_crash_stop(void); +extern void crash_smp_send_stop(void); extern bool smp_crash_stop_failed(void); #endif /* ifndef __ASSEMBLY__ */ diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h index cae331d553f8..95ad7102b63c 100644 --- a/arch/arm64/include/asm/spinlock.h +++ b/arch/arm64/include/asm/spinlock.h @@ -26,58 +26,6 @@ * The memory barriers are implicit with the load-acquire and store-release * instructions. */ -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - unsigned int tmp; - arch_spinlock_t lockval; - u32 owner; - - /* - * Ensure prior spin_lock operations to other locks have completed - * on this CPU before we test whether "lock" is locked. - */ - smp_mb(); - owner = READ_ONCE(lock->owner) << 16; - - asm volatile( -" sevl\n" -"1: wfe\n" -"2: ldaxr %w0, %2\n" - /* Is the lock free? */ -" eor %w1, %w0, %w0, ror #16\n" -" cbz %w1, 3f\n" - /* Lock taken -- has there been a subsequent unlock->lock transition? */ -" eor %w1, %w3, %w0, lsl #16\n" -" cbz %w1, 1b\n" - /* - * The owner has been updated, so there was an unlock->lock - * transition that we missed. That means we can rely on the - * store-release of the unlock operation paired with the - * load-acquire of the lock operation to publish any of our - * previous stores to the new lock owner and therefore don't - * need to bother with the writeback below. - */ -" b 4f\n" -"3:\n" - /* - * Serialise against any concurrent lockers by writing back the - * unlocked lock value - */ - ARM64_LSE_ATOMIC_INSN( - /* LL/SC */ -" stxr %w1, %w0, %2\n" - __nops(2), - /* LSE atomics */ -" mov %w1, %w0\n" -" cas %w0, %w0, %2\n" -" eor %w1, %w1, %w0\n") - /* Somebody else wrote to the lock, GOTO 10 and reload the value */ -" cbnz %w1, 2b\n" -"4:" - : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) - : "r" (owner) - : "memory"); -} #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) @@ -176,7 +124,11 @@ static inline int arch_spin_value_unlocked(arch_spinlock_t lock) static inline int arch_spin_is_locked(arch_spinlock_t *lock) { - smp_mb(); /* See arch_spin_unlock_wait */ + /* + * Ensure prior spin_lock operations to other locks have completed + * on this CPU before we test whether "lock" is locked. + */ + smp_mb(); /* ^^^ */ return !arch_spin_value_unlocked(READ_ONCE(*lock)); } @@ -358,14 +310,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) #define arch_read_relax(lock) cpu_relax() #define arch_write_relax(lock) cpu_relax() -/* - * Accesses appearing in program order before a spin_lock() operation - * can be reordered with accesses inside the critical section, by virtue - * of arch_spin_lock being constructed using acquire semantics. - * - * In cases where this is problematic (e.g. try_to_wake_up), an - * smp_mb__before_spinlock() can restore the required ordering. - */ -#define smp_mb__before_spinlock() smp_mb() +/* See include/linux/spinlock.h */ +#define smp_mb__after_spinlock() smp_mb() #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/arm64/include/asm/stack_pointer.h b/arch/arm64/include/asm/stack_pointer.h index ffcdf742cddf..8e57c96ad45e 100644 --- a/arch/arm64/include/asm/stack_pointer.h +++ b/arch/arm64/include/asm/stack_pointer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_STACK_POINTER_H #define __ASM_STACK_POINTER_H diff --git a/arch/arm64/include/asm/stackprotector.h b/arch/arm64/include/asm/stackprotector.h index b86a0865ddf1..58d15be11c4d 100644 --- a/arch/arm64/include/asm/stackprotector.h +++ b/arch/arm64/include/asm/stackprotector.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * GCC stack protector support. * diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h index 5b6eafccc5d8..6ad30776e984 100644 --- a/arch/arm64/include/asm/stacktrace.h +++ b/arch/arm64/include/asm/stacktrace.h @@ -16,11 +16,15 @@ #ifndef __ASM_STACKTRACE_H #define __ASM_STACKTRACE_H -struct task_struct; +#include +#include +#include + +#include +#include struct stackframe { unsigned long fp; - unsigned long sp; unsigned long pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER unsigned int graph; @@ -32,4 +36,57 @@ extern void walk_stackframe(struct task_struct *tsk, struct stackframe *frame, int (*fn)(struct stackframe *, void *), void *data); extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk); +DECLARE_PER_CPU(unsigned long *, irq_stack_ptr); + +static inline bool on_irq_stack(unsigned long sp) +{ + unsigned long low = (unsigned long)raw_cpu_read(irq_stack_ptr); + unsigned long high = low + IRQ_STACK_SIZE; + + if (!low) + return false; + + return (low <= sp && sp < high); +} + +static inline bool on_task_stack(struct task_struct *tsk, unsigned long sp) +{ + unsigned long low = (unsigned long)task_stack_page(tsk); + unsigned long high = low + THREAD_SIZE; + + return (low <= sp && sp < high); +} + +#ifdef CONFIG_VMAP_STACK +DECLARE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack); + +static inline bool on_overflow_stack(unsigned long sp) +{ + unsigned long low = (unsigned long)raw_cpu_ptr(overflow_stack); + unsigned long high = low + OVERFLOW_STACK_SIZE; + + return (low <= sp && sp < high); +} +#else +static inline bool on_overflow_stack(unsigned long sp) { return false; } +#endif + +/* + * We can only safely access per-cpu stacks from current in a non-preemptible + * context. + */ +static inline bool on_accessible_stack(struct task_struct *tsk, unsigned long sp) +{ + if (on_task_stack(tsk, sp)) + return true; + if (tsk != current || preemptible()) + return false; + if (on_irq_stack(sp)) + return true; + if (on_overflow_stack(sp)) + return true; + + return false; +} + #endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index d0aa42907569..dd95d33a5bd5 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -52,6 +52,10 @@ extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP extern int memcmp(const void *, const void *, size_t); +#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE +#define __HAVE_ARCH_MEMCPY_FLUSHCACHE +void memcpy_flushcache(void *dst, const void *src, size_t cnt); +#endif #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h index de5600f40adf..8939c87c4dce 100644 --- a/arch/arm64/include/asm/suspend.h +++ b/arch/arm64/include/asm/suspend.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SUSPEND_H #define __ASM_SUSPEND_H diff --git a/arch/arm64/include/asm/sync_bitops.h b/arch/arm64/include/asm/sync_bitops.h index 8da0bf4f7659..eee31a9f72a5 100644 --- a/arch/arm64/include/asm/sync_bitops.h +++ b/arch/arm64/include/asm/sync_bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SYNC_BITOPS_H__ #define __ASM_SYNC_BITOPS_H__ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 248339e4aaf5..f707fed5886f 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -329,6 +329,7 @@ #define ID_AA64ISAR1_LRCPC_SHIFT 20 #define ID_AA64ISAR1_FCMA_SHIFT 16 #define ID_AA64ISAR1_JSCVT_SHIFT 12 +#define ID_AA64ISAR1_DPB_SHIFT 0 /* id_aa64pfr0 */ #define ID_AA64PFR0_GIC_SHIFT 24 diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index 46c3b93cf865..ddded6497a8a 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -23,19 +23,11 @@ #include -#ifdef CONFIG_ARM64_4K_PAGES -#define THREAD_SIZE_ORDER 2 -#elif defined(CONFIG_ARM64_16K_PAGES) -#define THREAD_SIZE_ORDER 0 -#endif - -#define THREAD_SIZE 16384 -#define THREAD_START_SP (THREAD_SIZE - 16) - #ifndef __ASSEMBLY__ struct task_struct; +#include #include #include @@ -68,6 +60,9 @@ struct thread_info { #define thread_saved_fp(tsk) \ ((unsigned long)(tsk->thread.cpu_context.fp)) +void arch_setup_new_exec(void); +#define arch_setup_new_exec arch_setup_new_exec + #endif /* @@ -86,6 +81,7 @@ struct thread_info { #define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_FOREIGN_FPSTATE 3 /* CPU's FP state is not current's */ #define TIF_UPROBE 4 /* uprobe breakpoint or singlestep */ +#define TIF_FSCHECK 5 /* Check FS is USER_DS on return */ #define TIF_NOHZ 7 #define TIF_SYSCALL_TRACE 8 #define TIF_SYSCALL_AUDIT 9 @@ -107,11 +103,12 @@ struct thread_info { #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_UPROBE (1 << TIF_UPROBE) +#define _TIF_FSCHECK (1 << TIF_FSCHECK) #define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ - _TIF_UPROBE) + _TIF_UPROBE | _TIF_FSCHECK) #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h index 8b57339823e9..b3202284568b 100644 --- a/arch/arm64/include/asm/topology.h +++ b/arch/arm64/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_TOPOLOGY_H #define __ASM_TOPOLOGY_H diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h index 02e9035b0685..d131501c6222 100644 --- a/arch/arm64/include/asm/traps.h +++ b/arch/arm64/include/asm/traps.h @@ -37,18 +37,11 @@ void unregister_undef_hook(struct undef_hook *hook); void arm64_notify_segfault(struct pt_regs *regs, unsigned long addr); -#ifdef CONFIG_FUNCTION_GRAPH_TRACER static inline int __in_irqentry_text(unsigned long ptr) { return ptr >= (unsigned long)&__irqentry_text_start && ptr < (unsigned long)&__irqentry_text_end; } -#else -static inline int __in_irqentry_text(unsigned long ptr) -{ - return 0; -} -#endif static inline int in_exception_text(unsigned long ptr) { @@ -60,4 +53,9 @@ static inline int in_exception_text(unsigned long ptr) return in ? : __in_irqentry_text(ptr); } +static inline int in_entry_text(unsigned long ptr) +{ + return ptr >= (unsigned long)&__entry_text_start && + ptr < (unsigned long)&__entry_text_end; +} #endif diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index fab46a0ea223..fc0f9eb66039 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -45,6 +45,9 @@ static inline void set_fs(mm_segment_t fs) { current_thread_info()->addr_limit = fs; + /* On user-mode return, check fs is correct */ + set_thread_flag(TIF_FSCHECK); + /* * Enable/disable UAO so that copy_to_user() etc can access * kernel memory with the unprivileged instructions. @@ -347,4 +350,16 @@ extern long strncpy_from_user(char *dest, const char __user *src, long count); extern __must_check long strnlen_user(const char __user *str, long n); +#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE +struct page; +void memcpy_page_flushcache(char *to, struct page *page, size_t offset, size_t len); +extern unsigned long __must_check __copy_user_flushcache(void *to, const void __user *from, unsigned long n); + +static inline int __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size) +{ + kasan_check_write(dst, size); + return __copy_user_flushcache(dst, src, size); +} +#endif + #endif /* __ASM_UACCESS_H */ diff --git a/arch/arm64/include/asm/xen/events.h b/arch/arm64/include/asm/xen/events.h index 4318866d053c..4e22b7a8c038 100644 --- a/arch/arm64/include/asm/xen/events.h +++ b/arch/arm64/include/asm/xen/events.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARM64_XEN_EVENTS_H #define _ASM_ARM64_XEN_EVENTS_H diff --git a/arch/arm64/include/asm/xen/xen-ops.h b/arch/arm64/include/asm/xen/xen-ops.h index ec154e719b11..e6e784051932 100644 --- a/arch/arm64/include/asm/xen/xen-ops.h +++ b/arch/arm64/include/asm/xen/xen-ops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_XEN_OPS_H #define _ASM_XEN_OPS_H diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild index fc28bd95c6d3..198afbf0688f 100644 --- a/arch/arm64/include/uapi/asm/Kbuild +++ b/arch/arm64/include/uapi/asm/Kbuild @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h index 4cf0c17787a8..ec0a86d484e1 100644 --- a/arch/arm64/include/uapi/asm/auxvec.h +++ b/arch/arm64/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/bitsperlong.h b/arch/arm64/include/uapi/asm/bitsperlong.h index fce9c2924fa3..485d60bee26c 100644 --- a/arch/arm64/include/uapi/asm/bitsperlong.h +++ b/arch/arm64/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/byteorder.h b/arch/arm64/include/uapi/asm/byteorder.h index dc19e9537f0d..ca9cfdab33fc 100644 --- a/arch/arm64/include/uapi/asm/byteorder.h +++ b/arch/arm64/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/fcntl.h b/arch/arm64/include/uapi/asm/fcntl.h index cd2e630c235e..f8db34f2622d 100644 --- a/arch/arm64/include/uapi/asm/fcntl.h +++ b/arch/arm64/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h index 4e187ce2a811..b3fdeee739ea 100644 --- a/arch/arm64/include/uapi/asm/hwcap.h +++ b/arch/arm64/include/uapi/asm/hwcap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * @@ -35,5 +36,6 @@ #define HWCAP_JSCVT (1 << 13) #define HWCAP_FCMA (1 << 14) #define HWCAP_LRCPC (1 << 15) +#define HWCAP_DCPOP (1 << 16) #endif /* _UAPI__ASM_HWCAP_H */ diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 9f3ca24bbcc6..51149ec75fe4 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012,2013 - ARM Ltd * Author: Marc Zyngier diff --git a/arch/arm64/include/uapi/asm/param.h b/arch/arm64/include/uapi/asm/param.h index 8e3a281d448a..b115c5557781 100644 --- a/arch/arm64/include/uapi/asm/param.h +++ b/arch/arm64/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h index 172b8317ee49..d54daafa89e3 100644 --- a/arch/arm64/include/uapi/asm/perf_regs.h +++ b/arch/arm64/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_ARM64_PERF_REGS_H #define _ASM_ARM64_PERF_REGS_H diff --git a/arch/arm64/include/uapi/asm/posix_types.h b/arch/arm64/include/uapi/asm/posix_types.h index 7985ff60ca3f..b1c2e0df92dc 100644 --- a/arch/arm64/include/uapi/asm/posix_types.h +++ b/arch/arm64/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_POSIX_TYPES_H #define __ASM_POSIX_TYPES_H diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h index d1ff83dfe5de..67d4c33974e8 100644 --- a/arch/arm64/include/uapi/asm/ptrace.h +++ b/arch/arm64/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Based on arch/arm/include/asm/ptrace.h * diff --git a/arch/arm64/include/uapi/asm/setup.h b/arch/arm64/include/uapi/asm/setup.h index 9cf2e46fbbdf..5d703888f351 100644 --- a/arch/arm64/include/uapi/asm/setup.h +++ b/arch/arm64/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Based on arch/arm/include/asm/setup.h * diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h index f0a76b9fcd6e..f6cc3061b1ae 100644 --- a/arch/arm64/include/uapi/asm/sigcontext.h +++ b/arch/arm64/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h index 5a74a0853db0..574d12f86039 100644 --- a/arch/arm64/include/uapi/asm/siginfo.h +++ b/arch/arm64/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/signal.h b/arch/arm64/include/uapi/asm/signal.h index 991bf5db2ca1..bdf0cfb046c9 100644 --- a/arch/arm64/include/uapi/asm/signal.h +++ b/arch/arm64/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/stat.h b/arch/arm64/include/uapi/asm/stat.h index eeb702e5074a..313325fa22fa 100644 --- a/arch/arm64/include/uapi/asm/stat.h +++ b/arch/arm64/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/statfs.h b/arch/arm64/include/uapi/asm/statfs.h index 6f6219050978..615357b6ba89 100644 --- a/arch/arm64/include/uapi/asm/statfs.h +++ b/arch/arm64/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/ucontext.h b/arch/arm64/include/uapi/asm/ucontext.h index 791de8e89e35..ee02721a704d 100644 --- a/arch/arm64/include/uapi/asm/ucontext.h +++ b/arch/arm64/include/uapi/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/include/uapi/asm/unistd.h b/arch/arm64/include/uapi/asm/unistd.h index 043d17a21342..5072cbd15c82 100644 --- a/arch/arm64/include/uapi/asm/unistd.h +++ b/arch/arm64/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index f2b4e816b6de..0029e13adb59 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index e25c11e727fe..b3162715ed78 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -95,7 +95,7 @@ static int __init dt_scan_depth1_nodes(unsigned long node, * __acpi_map_table() will be called before page_init(), so early_ioremap() * or early_memremap() should be called here to for ACPI table mapping. */ -char *__init __acpi_map_table(unsigned long phys, unsigned long size) +void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) { if (!size) return NULL; @@ -103,7 +103,7 @@ char *__init __acpi_map_table(unsigned long phys, unsigned long size) return early_memremap(phys, size); } -void __init __acpi_unmap_table(char *map, unsigned long size) +void __init __acpi_unmap_table(void __iomem *map, unsigned long size) { if (!map || !size) return; diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c index f01fab637dab..d190a7b231bf 100644 --- a/arch/arm64/kernel/acpi_numa.c +++ b/arch/arm64/kernel/acpi_numa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ACPI 5.1 based NUMA setup for ARM64 * Lots of code was borrowed from arch/x86/mm/srat.c diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index f0e6d717885b..d06fbe4cd38d 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -649,4 +649,4 @@ static int __init armv8_deprecated_init(void) return 0; } -late_initcall(armv8_deprecated_init); +core_initcall(armv8_deprecated_init); diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index b3bb7ef97bc8..71bf088f1e4b 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -75,6 +75,7 @@ int main(void) DEFINE(S_ORIG_X0, offsetof(struct pt_regs, orig_x0)); DEFINE(S_SYSCALLNO, offsetof(struct pt_regs, syscallno)); DEFINE(S_ORIG_ADDR_LIMIT, offsetof(struct pt_regs, orig_addr_limit)); + DEFINE(S_STACKFRAME, offsetof(struct pt_regs, stackframe)); DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); BLANK(); DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter)); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 9f9e0064c8c1..21e2c95d24e7 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -120,6 +120,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_LRCPC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_FCMA_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_JSCVT_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, ID_AA64ISAR1_DPB_SHIFT, 4, 0), ARM64_FTR_END, }; @@ -888,6 +889,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .min_field_value = 0, .matches = has_no_fpsimd, }, +#ifdef CONFIG_ARM64_PMEM + { + .desc = "Data cache clean to Point of Persistence", + .capability = ARM64_HAS_DCPOP, + .def_scope = SCOPE_SYSTEM, + .matches = has_cpuid_feature, + .sys_reg = SYS_ID_AA64ISAR1_EL1, + .field_pos = ID_AA64ISAR1_DPB_SHIFT, + .min_field_value = 1, + }, +#endif {}, }; @@ -916,6 +928,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_FPHP), HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, HWCAP_ASIMD), HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, HWCAP_ASIMDHP), + HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_DCPOP), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_JSCVT), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_FCMA), HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_LRCPC), @@ -1294,4 +1307,4 @@ static int __init enable_mrs_emulation(void) return 0; } -late_initcall(enable_mrs_emulation); +core_initcall(enable_mrs_emulation); diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index f495ee5049fd..311885962830 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -68,6 +68,7 @@ static const char *const hwcap_str[] = { "jscvt", "fcma", "lrcpc", + "dcpop", NULL }; diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S index c44a82f146b1..6a27cd6dbfa6 100644 --- a/arch/arm64/kernel/entry-fpsimd.S +++ b/arch/arm64/kernel/entry-fpsimd.S @@ -41,27 +41,3 @@ ENTRY(fpsimd_load_state) fpsimd_restore x0, 8 ret ENDPROC(fpsimd_load_state) - -#ifdef CONFIG_KERNEL_MODE_NEON - -/* - * Save the bottom n FP registers. - * - * x0 - pointer to struct fpsimd_partial_state - */ -ENTRY(fpsimd_save_partial_state) - fpsimd_save_partial x0, 1, 8, 9 - ret -ENDPROC(fpsimd_save_partial_state) - -/* - * Load the bottom n FP registers. - * - * x0 - pointer to struct fpsimd_partial_state - */ -ENTRY(fpsimd_load_partial_state) - fpsimd_restore_partial x0, 8, 9 - ret -ENDPROC(fpsimd_load_partial_state) - -#endif diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index b738880350f9..e1c59d4008a8 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -69,8 +69,55 @@ #define BAD_FIQ 2 #define BAD_ERROR 3 - .macro kernel_entry, el, regsize = 64 + .macro kernel_ventry label + .align 7 sub sp, sp, #S_FRAME_SIZE +#ifdef CONFIG_VMAP_STACK + /* + * Test whether the SP has overflowed, without corrupting a GPR. + * Task and IRQ stacks are aligned to (1 << THREAD_SHIFT). + */ + add sp, sp, x0 // sp' = sp + x0 + sub x0, sp, x0 // x0' = sp' - x0 = (sp + x0) - x0 = sp + tbnz x0, #THREAD_SHIFT, 0f + sub x0, sp, x0 // x0'' = sp' - x0' = (sp + x0) - sp = x0 + sub sp, sp, x0 // sp'' = sp' - x0 = (sp + x0) - x0 = sp + b \label + +0: + /* + * Either we've just detected an overflow, or we've taken an exception + * while on the overflow stack. Either way, we won't return to + * userspace, and can clobber EL0 registers to free up GPRs. + */ + + /* Stash the original SP (minus S_FRAME_SIZE) in tpidr_el0. */ + msr tpidr_el0, x0 + + /* Recover the original x0 value and stash it in tpidrro_el0 */ + sub x0, sp, x0 + msr tpidrro_el0, x0 + + /* Switch to the overflow stack */ + adr_this_cpu sp, overflow_stack + OVERFLOW_STACK_SIZE, x0 + + /* + * Check whether we were already on the overflow stack. This may happen + * after panic() re-enables interrupts. + */ + mrs x0, tpidr_el0 // sp of interrupted context + sub x0, sp, x0 // delta with top of overflow stack + tst x0, #~(OVERFLOW_STACK_SIZE - 1) // within range? + b.ne __bad_stack // no? -> bad stack pointer + + /* We were already on the overflow stack. Restore sp/x0 and carry on. */ + sub sp, sp, x0 + mrs x0, tpidrro_el0 +#endif + b \label + .endm + + .macro kernel_entry, el, regsize = 64 .if \regsize == 32 mov w0, w0 // zero upper 32 bits of x0 .endif @@ -111,6 +158,18 @@ mrs x23, spsr_el1 stp lr, x21, [sp, #S_LR] + /* + * In order to be able to dump the contents of struct pt_regs at the + * time the exception was taken (in case we attempt to walk the call + * stack later), chain it together with the stack frames. + */ + .if \el == 0 + stp xzr, xzr, [sp, #S_STACKFRAME] + .else + stp x29, x22, [sp, #S_STACKFRAME] + .endif + add x29, sp, #S_STACKFRAME + #ifdef CONFIG_ARM64_SW_TTBR0_PAN /* * Set the TTBR0 PAN bit in SPSR. When the exception is taken from @@ -138,12 +197,10 @@ alternative_else_nop_endif stp x22, x23, [sp, #S_PC] - /* - * Set syscallno to -1 by default (overridden later if real syscall). - */ + /* Not in a syscall by default (el0_svc overwrites for real syscall) */ .if \el == 0 - mvn x21, xzr - str x21, [sp, #S_SYSCALLNO] + mov w21, #NO_SYSCALL + str w21, [sp, #S_SYSCALLNO] .endif /* @@ -259,20 +316,12 @@ alternative_else_nop_endif and x25, x25, #~(THREAD_SIZE - 1) cbnz x25, 9998f - adr_this_cpu x25, irq_stack, x26 - mov x26, #IRQ_STACK_START_SP + ldr_this_cpu x25, irq_stack_ptr, x26 + mov x26, #IRQ_STACK_SIZE add x26, x25, x26 /* switch to the irq stack */ mov sp, x26 - - /* - * Add a dummy stack frame, this non-standard format is fixed up - * by unwind_frame() - */ - stp x29, x19, [sp, #-16]! - mov x29, sp - 9998: .endm @@ -290,8 +339,9 @@ alternative_else_nop_endif * * x7 is reserved for the system call number in 32-bit mode. */ -sc_nr .req x25 // number of system calls -scno .req x26 // syscall number +wsc_nr .req w25 // number of system calls +wscno .req w26 // syscall number +xscno .req x26 // syscall number (zero-extended) stbl .req x27 // syscall table pointer tsk .req x28 // current thread_info @@ -315,34 +365,62 @@ tsk .req x28 // current thread_info .align 11 ENTRY(vectors) - ventry el1_sync_invalid // Synchronous EL1t - ventry el1_irq_invalid // IRQ EL1t - ventry el1_fiq_invalid // FIQ EL1t - ventry el1_error_invalid // Error EL1t + kernel_ventry el1_sync_invalid // Synchronous EL1t + kernel_ventry el1_irq_invalid // IRQ EL1t + kernel_ventry el1_fiq_invalid // FIQ EL1t + kernel_ventry el1_error_invalid // Error EL1t - ventry el1_sync // Synchronous EL1h - ventry el1_irq // IRQ EL1h - ventry el1_fiq_invalid // FIQ EL1h - ventry el1_error_invalid // Error EL1h + kernel_ventry el1_sync // Synchronous EL1h + kernel_ventry el1_irq // IRQ EL1h + kernel_ventry el1_fiq_invalid // FIQ EL1h + kernel_ventry el1_error_invalid // Error EL1h - ventry el0_sync // Synchronous 64-bit EL0 - ventry el0_irq // IRQ 64-bit EL0 - ventry el0_fiq_invalid // FIQ 64-bit EL0 - ventry el0_error_invalid // Error 64-bit EL0 + kernel_ventry el0_sync // Synchronous 64-bit EL0 + kernel_ventry el0_irq // IRQ 64-bit EL0 + kernel_ventry el0_fiq_invalid // FIQ 64-bit EL0 + kernel_ventry el0_error_invalid // Error 64-bit EL0 #ifdef CONFIG_COMPAT - ventry el0_sync_compat // Synchronous 32-bit EL0 - ventry el0_irq_compat // IRQ 32-bit EL0 - ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 - ventry el0_error_invalid_compat // Error 32-bit EL0 + kernel_ventry el0_sync_compat // Synchronous 32-bit EL0 + kernel_ventry el0_irq_compat // IRQ 32-bit EL0 + kernel_ventry el0_fiq_invalid_compat // FIQ 32-bit EL0 + kernel_ventry el0_error_invalid_compat // Error 32-bit EL0 #else - ventry el0_sync_invalid // Synchronous 32-bit EL0 - ventry el0_irq_invalid // IRQ 32-bit EL0 - ventry el0_fiq_invalid // FIQ 32-bit EL0 - ventry el0_error_invalid // Error 32-bit EL0 + kernel_ventry el0_sync_invalid // Synchronous 32-bit EL0 + kernel_ventry el0_irq_invalid // IRQ 32-bit EL0 + kernel_ventry el0_fiq_invalid // FIQ 32-bit EL0 + kernel_ventry el0_error_invalid // Error 32-bit EL0 #endif END(vectors) +#ifdef CONFIG_VMAP_STACK + /* + * We detected an overflow in kernel_ventry, which switched to the + * overflow stack. Stash the exception regs, and head to our overflow + * handler. + */ +__bad_stack: + /* Restore the original x0 value */ + mrs x0, tpidrro_el0 + + /* + * Store the original GPRs to the new stack. The orginal SP (minus + * S_FRAME_SIZE) was stashed in tpidr_el0 by kernel_ventry. + */ + sub sp, sp, #S_FRAME_SIZE + kernel_entry 1 + mrs x0, tpidr_el0 + add x0, x0, #S_FRAME_SIZE + str x0, [sp, #S_SP] + + /* Stash the regs for handle_bad_stack */ + mov x0, sp + + /* Time to die */ + bl handle_bad_stack + ASM_BUG() +#endif /* CONFIG_VMAP_STACK */ + /* * Invalid mode handlers */ @@ -351,7 +429,8 @@ END(vectors) mov x0, sp mov x1, #\reason mrs x2, esr_el1 - b bad_mode + bl bad_mode + ASM_BUG() .endm el0_sync_invalid: @@ -448,14 +527,16 @@ el1_sp_pc: mrs x0, far_el1 enable_dbg mov x2, sp - b do_sp_pc_abort + bl do_sp_pc_abort + ASM_BUG() el1_undef: /* * Undefined instruction */ enable_dbg mov x0, sp - b do_undefinstr + bl do_undefinstr + ASM_BUG() el1_dbg: /* * Debug exception handling @@ -473,7 +554,8 @@ el1_inv: mov x0, sp mov x2, x1 mov x1, #BAD_SYNC - b bad_mode + bl bad_mode + ASM_BUG() ENDPROC(el1_sync) .align 6 @@ -577,8 +659,8 @@ el0_svc_compat: * AArch32 syscall handling */ adrp stbl, compat_sys_call_table // load compat syscall table pointer - uxtw scno, w7 // syscall number in w7 (r7) - mov sc_nr, #__NR_compat_syscalls + mov wscno, w7 // syscall number in w7 (r7) + mov wsc_nr, #__NR_compat_syscalls b el0_svc_naked .align 6 @@ -706,38 +788,6 @@ el0_irq_naked: b ret_to_user ENDPROC(el0_irq) -/* - * Register switch for AArch64. The callee-saved registers need to be saved - * and restored. On entry: - * x0 = previous task_struct (must be preserved across the switch) - * x1 = next task_struct - * Previous and next are guaranteed not to be the same. - * - */ -ENTRY(cpu_switch_to) - mov x10, #THREAD_CPU_CONTEXT - add x8, x0, x10 - mov x9, sp - stp x19, x20, [x8], #16 // store callee-saved registers - stp x21, x22, [x8], #16 - stp x23, x24, [x8], #16 - stp x25, x26, [x8], #16 - stp x27, x28, [x8], #16 - stp x29, x9, [x8], #16 - str lr, [x8] - add x8, x1, x10 - ldp x19, x20, [x8], #16 // restore callee-saved registers - ldp x21, x22, [x8], #16 - ldp x23, x24, [x8], #16 - ldp x25, x26, [x8], #16 - ldp x27, x28, [x8], #16 - ldp x29, x9, [x8], #16 - ldr lr, [x8] - mov sp, x9 - msr sp_el0, x1 - ret -ENDPROC(cpu_switch_to) - /* * This is the fast syscall return path. We do as little as possible here, * and this includes saving x0 back into the kernel stack. @@ -780,37 +830,25 @@ finish_ret_to_user: kernel_exit 0 ENDPROC(ret_to_user) -/* - * This is how we return from a fork. - */ -ENTRY(ret_from_fork) - bl schedule_tail - cbz x19, 1f // not a kernel thread - mov x0, x20 - blr x19 -1: get_thread_info tsk - b ret_to_user -ENDPROC(ret_from_fork) - /* * SVC handler. */ .align 6 el0_svc: adrp stbl, sys_call_table // load syscall table pointer - uxtw scno, w8 // syscall number in w8 - mov sc_nr, #__NR_syscalls + mov wscno, w8 // syscall number in w8 + mov wsc_nr, #__NR_syscalls el0_svc_naked: // compat entry point - stp x0, scno, [sp, #S_ORIG_X0] // save the original x0 and syscall number + stp x0, xscno, [sp, #S_ORIG_X0] // save the original x0 and syscall number enable_dbg_and_irq ct_user_exit 1 ldr x16, [tsk, #TSK_TI_FLAGS] // check for syscall hooks tst x16, #_TIF_SYSCALL_WORK b.ne __sys_trace - cmp scno, sc_nr // check upper syscall limit + cmp wscno, wsc_nr // check upper syscall limit b.hs ni_sys - ldr x16, [stbl, scno, lsl #3] // address in the syscall table + ldr x16, [stbl, xscno, lsl #3] // address in the syscall table blr x16 // call sys_* routine b ret_fast_syscall ni_sys: @@ -824,24 +862,23 @@ ENDPROC(el0_svc) * switches, and waiting for our parent to respond. */ __sys_trace: - mov w0, #-1 // set default errno for - cmp scno, x0 // user-issued syscall(-1) + cmp wscno, #NO_SYSCALL // user-issued syscall(-1)? b.ne 1f - mov x0, #-ENOSYS + mov x0, #-ENOSYS // set default errno if so str x0, [sp, #S_X0] 1: mov x0, sp bl syscall_trace_enter - cmp w0, #-1 // skip the syscall? + cmp w0, #NO_SYSCALL // skip the syscall? b.eq __sys_trace_return_skipped - uxtw scno, w0 // syscall number (possibly new) + mov wscno, w0 // syscall number (possibly new) mov x1, sp // pointer to regs - cmp scno, sc_nr // check upper syscall limit + cmp wscno, wsc_nr // check upper syscall limit b.hs __ni_sys_trace ldp x0, x1, [sp] // restore the syscall args ldp x2, x3, [sp, #S_X2] ldp x4, x5, [sp, #S_X4] ldp x6, x7, [sp, #S_X6] - ldr x16, [stbl, scno, lsl #3] // address in the syscall table + ldr x16, [stbl, xscno, lsl #3] // address in the syscall table blr x16 // call sys_* routine __sys_trace_return: @@ -865,3 +902,49 @@ ENTRY(sys_rt_sigreturn_wrapper) mov x0, sp b sys_rt_sigreturn ENDPROC(sys_rt_sigreturn_wrapper) + +/* + * Register switch for AArch64. The callee-saved registers need to be saved + * and restored. On entry: + * x0 = previous task_struct (must be preserved across the switch) + * x1 = next task_struct + * Previous and next are guaranteed not to be the same. + * + */ +ENTRY(cpu_switch_to) + mov x10, #THREAD_CPU_CONTEXT + add x8, x0, x10 + mov x9, sp + stp x19, x20, [x8], #16 // store callee-saved registers + stp x21, x22, [x8], #16 + stp x23, x24, [x8], #16 + stp x25, x26, [x8], #16 + stp x27, x28, [x8], #16 + stp x29, x9, [x8], #16 + str lr, [x8] + add x8, x1, x10 + ldp x19, x20, [x8], #16 // restore callee-saved registers + ldp x21, x22, [x8], #16 + ldp x23, x24, [x8], #16 + ldp x25, x26, [x8], #16 + ldp x27, x28, [x8], #16 + ldp x29, x9, [x8], #16 + ldr lr, [x8] + mov sp, x9 + msr sp_el0, x1 + ret +ENDPROC(cpu_switch_to) +NOKPROBE(cpu_switch_to) + +/* + * This is how we return from a fork. + */ +ENTRY(ret_from_fork) + bl schedule_tail + cbz x19, 1f // not a kernel thread + mov x0, x20 + blr x19 +1: get_thread_info tsk + b ret_to_user +ENDPROC(ret_from_fork) +NOKPROBE(ret_from_fork) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index c7b4995868e1..5d547deb6996 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -17,16 +17,19 @@ * along with this program. If not, see . */ +#include #include #include #include #include +#include +#include #include #include -#include #include #include +#include #define FPEXC_IOF (1 << 0) #define FPEXC_DZF (1 << 1) @@ -62,6 +65,13 @@ * CPU currently contain the most recent userland FPSIMD state of the current * task. * + * In order to allow softirq handlers to use FPSIMD, kernel_neon_begin() may + * save the task's FPSIMD context back to task_struct from softirq context. + * To prevent this from racing with the manipulation of the task's FPSIMD state + * from task context and thereby corrupting the state, it is necessary to + * protect any manipulation of a task's fpsimd_state or TIF_FOREIGN_FPSTATE + * flag with local_bh_disable() unless softirqs are already masked. + * * For a certain task, the sequence may look something like this: * - the task gets scheduled in; if both the task's fpsimd_state.cpu field * contains the id of the current CPU, and the CPU's fpsimd_last_state per-cpu @@ -161,11 +171,14 @@ void fpsimd_flush_thread(void) { if (!system_supports_fpsimd()) return; - preempt_disable(); + + local_bh_disable(); + memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); fpsimd_flush_task_state(current); set_thread_flag(TIF_FOREIGN_FPSTATE); - preempt_enable(); + + local_bh_enable(); } /* @@ -176,10 +189,13 @@ void fpsimd_preserve_current_state(void) { if (!system_supports_fpsimd()) return; - preempt_disable(); + + local_bh_disable(); + if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) fpsimd_save_state(¤t->thread.fpsimd_state); - preempt_enable(); + + local_bh_enable(); } /* @@ -191,15 +207,18 @@ void fpsimd_restore_current_state(void) { if (!system_supports_fpsimd()) return; - preempt_disable(); + + local_bh_disable(); + if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { struct fpsimd_state *st = ¤t->thread.fpsimd_state; fpsimd_load_state(st); - this_cpu_write(fpsimd_last_state, st); + __this_cpu_write(fpsimd_last_state, st); st->cpu = smp_processor_id(); } - preempt_enable(); + + local_bh_enable(); } /* @@ -211,15 +230,18 @@ void fpsimd_update_current_state(struct fpsimd_state *state) { if (!system_supports_fpsimd()) return; - preempt_disable(); + + local_bh_disable(); + fpsimd_load_state(state); if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) { struct fpsimd_state *st = ¤t->thread.fpsimd_state; - this_cpu_write(fpsimd_last_state, st); + __this_cpu_write(fpsimd_last_state, st); st->cpu = smp_processor_id(); } - preempt_enable(); + + local_bh_enable(); } /* @@ -232,51 +254,125 @@ void fpsimd_flush_task_state(struct task_struct *t) #ifdef CONFIG_KERNEL_MODE_NEON -static DEFINE_PER_CPU(struct fpsimd_partial_state, hardirq_fpsimdstate); -static DEFINE_PER_CPU(struct fpsimd_partial_state, softirq_fpsimdstate); +DEFINE_PER_CPU(bool, kernel_neon_busy); +EXPORT_PER_CPU_SYMBOL(kernel_neon_busy); /* * Kernel-side NEON support functions */ -void kernel_neon_begin_partial(u32 num_regs) + +/* + * kernel_neon_begin(): obtain the CPU FPSIMD registers for use by the calling + * context + * + * Must not be called unless may_use_simd() returns true. + * Task context in the FPSIMD registers is saved back to memory as necessary. + * + * A matching call to kernel_neon_end() must be made before returning from the + * calling context. + * + * The caller may freely use the FPSIMD registers until kernel_neon_end() is + * called. + */ +void kernel_neon_begin(void) { if (WARN_ON(!system_supports_fpsimd())) return; - if (in_interrupt()) { - struct fpsimd_partial_state *s = this_cpu_ptr( - in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); - BUG_ON(num_regs > 32); - fpsimd_save_partial_state(s, roundup(num_regs, 2)); - } else { - /* - * Save the userland FPSIMD state if we have one and if we - * haven't done so already. Clear fpsimd_last_state to indicate - * that there is no longer userland FPSIMD state in the - * registers. - */ - preempt_disable(); - if (current->mm && - !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) - fpsimd_save_state(¤t->thread.fpsimd_state); - this_cpu_write(fpsimd_last_state, NULL); - } + BUG_ON(!may_use_simd()); + + local_bh_disable(); + + __this_cpu_write(kernel_neon_busy, true); + + /* Save unsaved task fpsimd state, if any: */ + if (current->mm && !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE)) + fpsimd_save_state(¤t->thread.fpsimd_state); + + /* Invalidate any task state remaining in the fpsimd regs: */ + __this_cpu_write(fpsimd_last_state, NULL); + + preempt_disable(); + + local_bh_enable(); } -EXPORT_SYMBOL(kernel_neon_begin_partial); +EXPORT_SYMBOL(kernel_neon_begin); +/* + * kernel_neon_end(): give the CPU FPSIMD registers back to the current task + * + * Must be called from a context in which kernel_neon_begin() was previously + * called, with no call to kernel_neon_end() in the meantime. + * + * The caller must not use the FPSIMD registers after this function is called, + * unless kernel_neon_begin() is called again in the meantime. + */ void kernel_neon_end(void) +{ + bool busy; + + if (!system_supports_fpsimd()) + return; + + busy = __this_cpu_xchg(kernel_neon_busy, false); + WARN_ON(!busy); /* No matching kernel_neon_begin()? */ + + preempt_enable(); +} +EXPORT_SYMBOL(kernel_neon_end); + +#ifdef CONFIG_EFI + +static DEFINE_PER_CPU(struct fpsimd_state, efi_fpsimd_state); +static DEFINE_PER_CPU(bool, efi_fpsimd_state_used); + +/* + * EFI runtime services support functions + * + * The ABI for EFI runtime services allows EFI to use FPSIMD during the call. + * This means that for EFI (and only for EFI), we have to assume that FPSIMD + * is always used rather than being an optional accelerator. + * + * These functions provide the necessary support for ensuring FPSIMD + * save/restore in the contexts from which EFI is used. + * + * Do not use them for any other purpose -- if tempted to do so, you are + * either doing something wrong or you need to propose some refactoring. + */ + +/* + * __efi_fpsimd_begin(): prepare FPSIMD for making an EFI runtime services call + */ +void __efi_fpsimd_begin(void) { if (!system_supports_fpsimd()) return; - if (in_interrupt()) { - struct fpsimd_partial_state *s = this_cpu_ptr( - in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate); - fpsimd_load_partial_state(s); - } else { - preempt_enable(); + + WARN_ON(preemptible()); + + if (may_use_simd()) + kernel_neon_begin(); + else { + fpsimd_save_state(this_cpu_ptr(&efi_fpsimd_state)); + __this_cpu_write(efi_fpsimd_state_used, true); } } -EXPORT_SYMBOL(kernel_neon_end); + +/* + * __efi_fpsimd_end(): clean up FPSIMD after an EFI runtime services call + */ +void __efi_fpsimd_end(void) +{ + if (!system_supports_fpsimd()) + return; + + if (__this_cpu_xchg(efi_fpsimd_state_used, false)) + fpsimd_load_state(this_cpu_ptr(&efi_fpsimd_state)); + else + kernel_neon_end(); +} + +#endif /* CONFIG_EFI */ #endif /* CONFIG_KERNEL_MODE_NEON */ @@ -348,4 +444,4 @@ static int __init fpsimd_init(void) return 0; } -late_initcall(fpsimd_init); +core_initcall(fpsimd_init); diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index adb0910b88f5..0b243ecaf7ac 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -143,8 +143,8 @@ preserve_boot_args: dmb sy // needed before dc ivac with // MMU off - add x1, x0, #0x20 // 4 x 8 bytes - b __inval_cache_range // tail call + mov x1, #0x20 // 4 x 8 bytes + b __inval_dcache_area // tail call ENDPROC(preserve_boot_args) /* @@ -221,20 +221,20 @@ __create_page_tables: * dirty cache lines being evicted. */ adrp x0, idmap_pg_dir - adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE - bl __inval_cache_range + ldr x1, =(IDMAP_DIR_SIZE + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE) + bl __inval_dcache_area /* * Clear the idmap and swapper page tables. */ adrp x0, idmap_pg_dir - adrp x6, swapper_pg_dir + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE + ldr x1, =(IDMAP_DIR_SIZE + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE) 1: stp xzr, xzr, [x0], #16 stp xzr, xzr, [x0], #16 stp xzr, xzr, [x0], #16 stp xzr, xzr, [x0], #16 - cmp x0, x6 - b.lo 1b + subs x1, x1, #64 + b.ne 1b mov x7, SWAPPER_MM_MMUFLAGS @@ -307,9 +307,9 @@ __create_page_tables: * tables again to remove any speculatively loaded cache lines. */ adrp x0, idmap_pg_dir - adrp x1, swapper_pg_dir + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE + ldr x1, =(IDMAP_DIR_SIZE + SWAPPER_DIR_SIZE + RESERVED_TTBR0_SIZE) dmb sy - bl __inval_cache_range + bl __inval_dcache_area ret x28 ENDPROC(__create_page_tables) @@ -361,6 +361,9 @@ __primary_switched: ret // to __primary_switch() 0: #endif + add sp, sp, #16 + mov x29, #0 + mov x30, #0 b start_kernel ENDPROC(__primary_switched) @@ -381,6 +384,7 @@ ENTRY(kimage_vaddr) * booted in EL1 or EL2 respectively. */ ENTRY(el2_setup) + msr SPsel, #1 // We want to use SP_EL{1,2} mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.eq 1f @@ -616,6 +620,7 @@ __secondary_switched: ldr x2, [x0, #CPU_BOOT_TASK] msr sp_el0, x2 mov x29, #0 + mov x30, #0 b secondary_start_kernel ENDPROC(__secondary_switched) diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index a44e13942d30..095d3c170f5d 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -330,7 +330,7 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr) * read only (code, rodata). Clear the RDONLY bit from * the temporary mappings we use during restore. */ - set_pte(dst_pte, pte_clear_rdonly(pte)); + set_pte(dst_pte, pte_mkwrite(pte)); } else if (debug_pagealloc_enabled() && !pte_none(pte)) { /* * debug_pagealloc will removed the PTE_VALID bit if @@ -343,7 +343,7 @@ static void _copy_pte(pte_t *dst_pte, pte_t *src_pte, unsigned long addr) */ BUG_ON(!pfn_valid(pte_pfn(pte))); - set_pte(dst_pte, pte_mkpresent(pte_clear_rdonly(pte))); + set_pte(dst_pte, pte_mkpresent(pte_mkwrite(pte))); } } diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 2386b26c0712..713561e5bcab 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -23,15 +23,16 @@ #include #include +#include #include #include #include #include +#include unsigned long irq_err_count; -/* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */ -DEFINE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack) __aligned(16); +DEFINE_PER_CPU(unsigned long *, irq_stack_ptr); int arch_show_interrupts(struct seq_file *p, int prec) { @@ -50,8 +51,43 @@ void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) handle_arch_irq = handle_irq; } +#ifdef CONFIG_VMAP_STACK +static void init_irq_stacks(void) +{ + int cpu; + unsigned long *p; + + for_each_possible_cpu(cpu) { + /* + * To ensure that VMAP'd stack overflow detection works + * correctly, the IRQ stacks need to have the same + * alignment as other stacks. + */ + p = __vmalloc_node_range(IRQ_STACK_SIZE, THREAD_ALIGN, + VMALLOC_START, VMALLOC_END, + THREADINFO_GFP, PAGE_KERNEL, + 0, cpu_to_node(cpu), + __builtin_return_address(0)); + + per_cpu(irq_stack_ptr, cpu) = p; + } +} +#else +/* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */ +DEFINE_PER_CPU_ALIGNED(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack); + +static void init_irq_stacks(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu); +} +#endif + void __init init_IRQ(void) { + init_irq_stacks(); irqchip_init(); if (!handle_arch_irq) panic("No interrupt controller found."); diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index 481f54a866c5..11121f608eb5 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -252,7 +252,7 @@ void machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); /* shutdown non-crashing cpus */ - smp_send_crash_stop(); + crash_smp_send_stop(); /* for crashing cpu */ crash_save_cpu(regs, smp_processor_id()); diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c index e2b7e4f9cc31..0e2ea1c78542 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c @@ -22,23 +22,6 @@ #include #include -/* - * Called after each bus is probed, but before its children are examined - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* nothing to do, expected to be removed in the future */ -} - -/* - * We don't have to worry about legacy ISA devices, so nothing to do here - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - #ifdef CONFIG_ACPI /* * Try to assign the IRQ number when probing a new device diff --git a/arch/arm64/kernel/perf_callchain.c b/arch/arm64/kernel/perf_callchain.c index 713ca824f266..bcafd7dcfe8b 100644 --- a/arch/arm64/kernel/perf_callchain.c +++ b/arch/arm64/kernel/perf_callchain.c @@ -162,7 +162,6 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, } frame.fp = regs->regs[29]; - frame.sp = regs->sp; frame.pc = regs->pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = current->curr_ret_stack; diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index b5798ba21189..9eaef51f83ff 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -202,55 +202,6 @@ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, }; -/* ARM Cortex-A53 HW events mapping. */ -static const unsigned armv8_a53_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, -}; - -/* ARM Cortex-A57 and Cortex-A72 events mapping. */ -static const unsigned armv8_a57_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, -}; - -static const unsigned armv8_thunder_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, -}; - -/* Broadcom Vulcan events mapping */ -static const unsigned armv8_vulcan_perf_map[PERF_COUNT_HW_MAX] = { - PERF_MAP_ALL_UNSUPPORTED, - [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, - [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INST_RETIRED, - [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_BR_RETIRED, - [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, -}; - static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { @@ -281,27 +232,10 @@ static const unsigned armv8_a53_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { PERF_CACHE_MAP_ALL_UNSUPPORTED, - [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, - [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE, - [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL, [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_A53_PERFCTR_PREF_LINEFILL, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, - - [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE, - [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL, - [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE, - [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L2D_CACHE_REFILL, - - [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1D_TLB_REFILL, - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, - - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, }; static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -314,18 +248,26 @@ static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR, [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, - [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR, - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, +}; - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, +static const unsigned armv8_a73_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + PERF_CACHE_MAP_ALL_UNSUPPORTED, + + [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD, + [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR, + + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, + + [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, + [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, }; static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -340,8 +282,6 @@ static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1D_CACHE_PREF_ACCESS, [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1D_CACHE_PREF_MISS, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1I_CACHE_PREF_ACCESS, [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1I_CACHE_PREF_MISS, @@ -349,13 +289,6 @@ static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR, [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR, - - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, - - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, }; static const unsigned armv8_vulcan_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] @@ -368,22 +301,11 @@ static const unsigned armv8_vulcan_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR, [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_CACHE_REFILL_WR, - [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE, - [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL, - - [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL, - [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1I_TLB, - [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_WR, [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_RD, [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1D_TLB_REFILL_WR, - [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_BR_PRED, - [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_BR_MIS_PRED, - [C(NODE)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_RD, [C(NODE)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_BUS_ACCESS_WR, }; @@ -846,17 +768,14 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, struct hw_perf_event *hwc = &event->hw; unsigned long evtype = hwc->config_base & ARMV8_PMU_EVTYPE_EVENT; - /* Always place a cycle counter into the cycle counter. */ + /* Always prefer to place a cycle counter into the cycle counter. */ if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { - if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) - return -EAGAIN; - - return ARMV8_IDX_CYCLE_COUNTER; + if (!test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) + return ARMV8_IDX_CYCLE_COUNTER; } /* - * For anything other than a cycle counter, try and use - * the events counters + * Otherwise use events counters */ for (idx = ARMV8_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) { if (!test_and_set_bit(idx, cpuc->used_mask)) @@ -924,7 +843,13 @@ static void armv8pmu_reset(void *info) ARMV8_PMU_PMCR_LC); } -static int armv8_pmuv3_map_event(struct perf_event *event) +static int __armv8_pmuv3_map_event(struct perf_event *event, + const unsigned (*extra_event_map) + [PERF_COUNT_HW_MAX], + const unsigned (*extra_cache_map) + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX]) { int hw_event_id; struct arm_pmu *armpmu = to_arm_pmu(event->pmu); @@ -932,44 +857,47 @@ static int armv8_pmuv3_map_event(struct perf_event *event) hw_event_id = armpmu_map_event(event, &armv8_pmuv3_perf_map, &armv8_pmuv3_perf_cache_map, ARMV8_PMU_EVTYPE_EVENT); - if (hw_event_id < 0) - return hw_event_id; - /* disable micro/arch events not supported by this PMU */ - if ((hw_event_id < ARMV8_PMUV3_MAX_COMMON_EVENTS) && - !test_bit(hw_event_id, armpmu->pmceid_bitmap)) { - return -EOPNOTSUPP; + /* Onl expose micro/arch events supported by this PMU */ + if ((hw_event_id > 0) && (hw_event_id < ARMV8_PMUV3_MAX_COMMON_EVENTS) + && test_bit(hw_event_id, armpmu->pmceid_bitmap)) { + return hw_event_id; } - return hw_event_id; + return armpmu_map_event(event, extra_event_map, extra_cache_map, + ARMV8_PMU_EVTYPE_EVENT); +} + +static int armv8_pmuv3_map_event(struct perf_event *event) +{ + return __armv8_pmuv3_map_event(event, NULL, NULL); } static int armv8_a53_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_a53_perf_map, - &armv8_a53_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, &armv8_a53_perf_cache_map); } static int armv8_a57_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_a57_perf_map, - &armv8_a57_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, &armv8_a57_perf_cache_map); +} + +static int armv8_a73_map_event(struct perf_event *event) +{ + return __armv8_pmuv3_map_event(event, NULL, &armv8_a73_perf_cache_map); } static int armv8_thunder_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_thunder_perf_map, - &armv8_thunder_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, + &armv8_thunder_perf_cache_map); } static int armv8_vulcan_map_event(struct perf_event *event) { - return armpmu_map_event(event, &armv8_vulcan_perf_map, - &armv8_vulcan_perf_cache_map, - ARMV8_PMU_EVTYPE_EVENT); + return __armv8_pmuv3_map_event(event, NULL, + &armv8_vulcan_perf_cache_map); } struct armv8pmu_probe_info { @@ -1062,6 +990,22 @@ static int armv8_pmuv3_init(struct arm_pmu *cpu_pmu) return 0; } +static int armv8_a35_pmu_init(struct arm_pmu *cpu_pmu) +{ + int ret = armv8_pmu_init(cpu_pmu); + if (ret) + return ret; + + cpu_pmu->name = "armv8_cortex_a35"; + cpu_pmu->map_event = armv8_a53_map_event; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = + &armv8_pmuv3_events_attr_group; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = + &armv8_pmuv3_format_attr_group; + + return 0; +} + static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu) { int ret = armv8_pmu_init(cpu_pmu); @@ -1110,6 +1054,22 @@ static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu) return 0; } +static int armv8_a73_pmu_init(struct arm_pmu *cpu_pmu) +{ + int ret = armv8_pmu_init(cpu_pmu); + if (ret) + return ret; + + cpu_pmu->name = "armv8_cortex_a73"; + cpu_pmu->map_event = armv8_a73_map_event; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = + &armv8_pmuv3_events_attr_group; + cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = + &armv8_pmuv3_format_attr_group; + + return 0; +} + static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu) { int ret = armv8_pmu_init(cpu_pmu); @@ -1144,9 +1104,11 @@ static int armv8_vulcan_pmu_init(struct arm_pmu *cpu_pmu) static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init}, + {.compatible = "arm,cortex-a35-pmu", .data = armv8_a35_pmu_init}, {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init}, {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init}, {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init}, + {.compatible = "arm,cortex-a73-pmu", .data = armv8_a73_pmu_init}, {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, {.compatible = "brcm,vulcan-pmu", .data = armv8_vulcan_pmu_init}, {}, diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c index bd1b74c2436f..1d091d048d04 100644 --- a/arch/arm64/kernel/perf_regs.c +++ b/arch/arm64/kernel/perf_regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile index 89b6df613dde..8e4be92e25b1 100644 --- a/arch/arm64/kernel/probes/Makefile +++ b/arch/arm64/kernel/probes/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_KPROBES) += kprobes.o decode-insn.o \ kprobes_trampoline.o \ simulate-insn.o diff --git a/arch/arm64/kernel/probes/kprobes_trampoline.S b/arch/arm64/kernel/probes/kprobes_trampoline.S index 5d6e7f14638c..45dce03aaeaf 100644 --- a/arch/arm64/kernel/probes/kprobes_trampoline.S +++ b/arch/arm64/kernel/probes/kprobes_trampoline.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * trampoline entry and return code for kretprobes. */ diff --git a/arch/arm64/kernel/probes/uprobes.c b/arch/arm64/kernel/probes/uprobes.c index 26c998534dca..636ca0119c0e 100644 --- a/arch/arm64/kernel/probes/uprobes.c +++ b/arch/arm64/kernel/probes/uprobes.c @@ -40,7 +40,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, probe_opcode_t insn; /* TODO: Currently we do not support AARCH32 instruction probing */ - if (test_bit(TIF_32BIT, &mm->context.flags)) + if (mm->context.flags & MMCF_AARCH32) return -ENOTSUPP; else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) return -EINVAL; diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 659ae8094ed5..2dc0f8482210 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -360,6 +360,8 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, /* * Complete any pending TLB or cache maintenance on this CPU in case * the thread migrates to a different CPU. + * This full barrier is also required by the membarrier system + * call. */ dsb(ish); @@ -382,15 +384,12 @@ unsigned long get_wchan(struct task_struct *p) return 0; frame.fp = thread_saved_fp(p); - frame.sp = thread_saved_sp(p); frame.pc = thread_saved_pc(p); #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = p->curr_ret_stack; #endif do { - if (frame.sp < stack_page || - frame.sp >= stack_page + THREAD_SIZE || - unwind_frame(p, &frame)) + if (unwind_frame(p, &frame)) goto out; if (!in_sched_functions(frame.pc)) { ret = frame.pc; @@ -417,3 +416,11 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) else return randomize_page(mm->brk, SZ_1G); } + +/* + * Called from setup_new_exec() after (COMPAT_)SET_PERSONALITY. + */ +void arch_setup_new_exec(void) +{ + current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0; +} diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 1b38c0150aec..9cbb6123208f 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -127,7 +128,7 @@ static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) { return ((addr & ~(THREAD_SIZE - 1)) == (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))) || - on_irq_stack(addr, raw_smp_processor_id()); + on_irq_stack(addr); } /** @@ -1363,7 +1364,7 @@ static void tracehook_report_syscall(struct pt_regs *regs, if (dir == PTRACE_SYSCALL_EXIT) tracehook_report_syscall_exit(regs, 0); else if (tracehook_report_syscall_entry(regs)) - regs->syscallno = ~0UL; + forget_syscall(regs); regs->regs[regno] = saved_reg; } diff --git a/arch/arm64/kernel/return_address.c b/arch/arm64/kernel/return_address.c index 12a87f2600f2..933adbc0f654 100644 --- a/arch/arm64/kernel/return_address.c +++ b/arch/arm64/kernel/return_address.c @@ -42,7 +42,6 @@ void *return_address(unsigned int level) data.addr = NULL; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_stack_pointer; frame.pc = (unsigned long)return_address; /* dummy */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = current->curr_ret_stack; diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 089c3747995d..0bdc96c61bc0 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include @@ -387,7 +389,7 @@ static int restore_sigframe(struct pt_regs *regs, /* * Avoid sys_rt_sigreturn() restarting. */ - regs->syscallno = ~0UL; + forget_syscall(regs); err |= !valid_user_regs(®s->user_regs, current); if (err == 0) @@ -673,13 +675,12 @@ static void do_signal(struct pt_regs *regs) { unsigned long continue_addr = 0, restart_addr = 0; int retval = 0; - int syscall = (int)regs->syscallno; struct ksignal ksig; /* * If we were from a system call, check for system call restarting... */ - if (syscall >= 0) { + if (in_syscall(regs)) { continue_addr = regs->pc; restart_addr = continue_addr - (compat_thumb_mode(regs) ? 2 : 4); retval = regs->regs[0]; @@ -687,7 +688,7 @@ static void do_signal(struct pt_regs *regs) /* * Avoid additional syscall restarting via ret_to_user. */ - regs->syscallno = ~0UL; + forget_syscall(regs); /* * Prepare for system call restart. We do this here so that a @@ -731,7 +732,7 @@ static void do_signal(struct pt_regs *regs) * Handle restarting a different system call. As above, if a debugger * has chosen to restart at a different PC, ignore the restart. */ - if (syscall >= 0 && regs->pc == restart_addr) { + if (in_syscall(regs) && regs->pc == restart_addr) { if (retval == -ERESTART_RESTARTBLOCK) setup_restart_syscall(regs); user_rewind_single_step(current); @@ -749,7 +750,11 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, * Update the trace code with the current status. */ trace_hardirqs_off(); + do { + /* Check valid user FS if needed */ + addr_limit_user_check(); + if (thread_flags & _TIF_NEED_RESCHED) { schedule(); } else { diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index c747a0fc5d7d..e09bf5d15606 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -142,25 +142,25 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); - else switch (from->si_code & __SI_MASK) { - case __SI_KILL: + else switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_TIMER: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_POLL: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_FAULT: + case SIL_FAULT: err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr, &to->si_addr); #ifdef BUS_MCEERR_AO @@ -173,29 +173,24 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); #endif break; - case __SI_CHLD: + case SIL_CHLD: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_status, &to->si_status); err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); break; - case __SI_RT: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ: /* But this is */ + case SIL_RT: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_SYS: + case SIL_SYS: err |= __put_user((compat_uptr_t)(unsigned long) from->si_call_addr, &to->si_call_addr); err |= __put_user(from->si_syscall, &to->si_syscall); err |= __put_user(from->si_arch, &to->si_arch); break; - default: /* this is just in case for now ... */ - err |= __put_user(from->si_pid, &to->si_pid); - err |= __put_user(from->si_uid, &to->si_uid); - break; } return err; } @@ -354,7 +349,7 @@ static int compat_restore_sigframe(struct pt_regs *regs, /* * Avoid compat_sys_sigreturn() restarting. */ - regs->syscallno = ~0UL; + forget_syscall(regs); err |= !valid_user_regs(®s->user_regs, current); diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S index df67652e46f0..10dd16d7902d 100644 --- a/arch/arm64/kernel/sleep.S +++ b/arch/arm64/kernel/sleep.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index dc66e6ec3a99..9f7195a5773e 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -154,7 +154,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) * page tables. */ secondary_data.task = idle; - secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; + secondary_data.stack = task_stack_page(idle) + THREAD_SIZE; update_cpu_boot_status(CPU_MMU_OFF); __flush_dcache_area(&secondary_data, sizeof(secondary_data)); @@ -690,7 +690,7 @@ void __init smp_init_cpus(void) acpi_parse_gic_cpu_interface, 0); if (cpu_count > nr_cpu_ids) - pr_warn("Number of cores (%d) exceeds configured maximum of %d - clipping\n", + pr_warn("Number of cores (%d) exceeds configured maximum of %u - clipping\n", cpu_count, nr_cpu_ids); if (!bootcpu_valid) { @@ -977,11 +977,21 @@ void smp_send_stop(void) } #ifdef CONFIG_KEXEC_CORE -void smp_send_crash_stop(void) +void crash_smp_send_stop(void) { + static int cpus_stopped; cpumask_t mask; unsigned long timeout; + /* + * This function can be called twice in panic path, but obviously + * we execute this only once. + */ + if (cpus_stopped) + return; + + cpus_stopped = 1; + if (num_online_cpus() == 1) return; diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 09d37d66b630..76809ccd309c 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -42,33 +42,17 @@ */ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) { - unsigned long high, low; unsigned long fp = frame->fp; - unsigned long irq_stack_ptr; + + if (fp & 0xf) + return -EINVAL; if (!tsk) tsk = current; - /* - * Switching between stacks is valid when tracing current and in - * non-preemptible context. - */ - if (tsk == current && !preemptible()) - irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); - else - irq_stack_ptr = 0; - - low = frame->sp; - /* irq stacks are not THREAD_SIZE aligned */ - if (on_irq_stack(frame->sp, raw_smp_processor_id())) - high = irq_stack_ptr; - else - high = ALIGN(low, THREAD_SIZE) - 0x20; - - if (fp < low || fp > high || fp & 0xf) + if (!on_accessible_stack(tsk, fp)) return -EINVAL; - frame->sp = fp + 0x10; frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp)); frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8)); @@ -86,34 +70,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ /* - * Check whether we are going to walk through from interrupt stack - * to task stack. - * If we reach the end of the stack - and its an interrupt stack, - * unpack the dummy frame to find the original elr. - * - * Check the frame->fp we read from the bottom of the irq_stack, - * and the original task stack pointer are both in current->stack. + * Frames created upon entry from EL0 have NULL FP and PC values, so + * don't bother reporting these. Frames created by __noreturn functions + * might have a valid FP even if PC is bogus, so only terminate where + * both are NULL. */ - if (frame->sp == irq_stack_ptr) { - struct pt_regs *irq_args; - unsigned long orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); - - if (object_is_on_stack((void *)orig_sp) && - object_is_on_stack((void *)frame->fp)) { - frame->sp = orig_sp; - - /* orig_sp is the saved pt_regs, find the elr */ - irq_args = (struct pt_regs *)orig_sp; - frame->pc = irq_args->pc; - } else { - /* - * This frame has a non-standard format, and we - * didn't fix it, because the data looked wrong. - * Refuse to output this frame. - */ - return -EINVAL; - } - } + if (!frame->fp && !frame->pc) + return -EINVAL; return 0; } @@ -167,7 +130,6 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) data.no_sched_functions = 0; frame.fp = regs->regs[29]; - frame.sp = regs->sp; frame.pc = regs->pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = current->curr_ret_stack; @@ -178,7 +140,8 @@ void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) trace->entries[trace->nr_entries++] = ULONG_MAX; } -void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +static noinline void __save_stack_trace(struct task_struct *tsk, + struct stack_trace *trace, unsigned int nosched) { struct stack_trace_data data; struct stackframe frame; @@ -188,17 +151,16 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) data.trace = trace; data.skip = trace->skip; + data.no_sched_functions = nosched; if (tsk != current) { - data.no_sched_functions = 1; frame.fp = thread_saved_fp(tsk); - frame.sp = thread_saved_sp(tsk); frame.pc = thread_saved_pc(tsk); } else { - data.no_sched_functions = 0; + /* We don't want this function nor the caller */ + data.skip += 2; frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_stack_pointer; - frame.pc = (unsigned long)save_stack_trace_tsk; + frame.pc = (unsigned long)__save_stack_trace; } #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = tsk->curr_ret_stack; @@ -212,9 +174,15 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) } EXPORT_SYMBOL_GPL(save_stack_trace_tsk); +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) +{ + __save_stack_trace(tsk, trace, 1); +} + void save_stack_trace(struct stack_trace *trace) { - save_stack_trace_tsk(current, trace); + __save_stack_trace(current, trace, 0); } + EXPORT_SYMBOL_GPL(save_stack_trace); #endif diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 1e3be9064cfa..77cd655e6eb7 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c index da33c90248e9..a4391280fba9 100644 --- a/arch/arm64/kernel/time.c +++ b/arch/arm64/kernel/time.c @@ -50,7 +50,6 @@ unsigned long profile_pc(struct pt_regs *regs) return regs->pc; frame.fp = regs->regs[29]; - frame.sp = regs->sp; frame.pc = regs->pc; #ifdef CONFIG_FUNCTION_GRAPH_TRACER frame.graph = -1; /* no task info */ diff --git a/arch/arm64/kernel/trace-events-emulation.h b/arch/arm64/kernel/trace-events-emulation.h index ae1dd598ea65..6c40f58b844a 100644 --- a/arch/arm64/kernel/trace-events-emulation.h +++ b/arch/arm64/kernel/trace-events-emulation.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM emulation diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 8a62648848e5..8383af15a759 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -116,7 +118,7 @@ static void __dump_instr(const char *lvl, struct pt_regs *regs) for (i = -4; i < 1; i++) { unsigned int val, bad; - bad = __get_user(val, &((u32 *)addr)[i]); + bad = get_user(val, &((u32 *)addr)[i]); if (!bad) p += sprintf(p, i == 0 ? "(%08x) " : "%08x ", val); @@ -143,7 +145,6 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) { struct stackframe frame; - unsigned long irq_stack_ptr; int skip; pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); @@ -154,25 +155,14 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) if (!try_get_task_stack(tsk)) return; - /* - * Switching between stacks is valid when tracing current and in - * non-preemptible context. - */ - if (tsk == current && !preemptible()) - irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); - else - irq_stack_ptr = 0; - if (tsk == current) { frame.fp = (unsigned long)__builtin_frame_address(0); - frame.sp = current_stack_pointer; frame.pc = (unsigned long)dump_backtrace; } else { /* * task blocked in __switch_to */ frame.fp = thread_saved_fp(tsk); - frame.sp = thread_saved_sp(tsk); frame.pc = thread_saved_pc(tsk); } #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -182,13 +172,12 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) skip = !!regs; printk("Call trace:\n"); while (1) { - unsigned long where = frame.pc; unsigned long stack; int ret; /* skip until specified stack frame */ if (!skip) { - dump_backtrace_entry(where); + dump_backtrace_entry(frame.pc); } else if (frame.fp == regs->regs[29]) { skip = 0; /* @@ -203,20 +192,12 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) ret = unwind_frame(tsk, &frame); if (ret < 0) break; - stack = frame.sp; - if (in_exception_text(where)) { - /* - * If we switched to the irq_stack before calling this - * exception handler, then the pt_regs will be on the - * task stack. The easiest way to tell is if the large - * pt_regs would overlap with the end of the irq_stack. - */ - if (stack < irq_stack_ptr && - (stack + sizeof(struct pt_regs)) > irq_stack_ptr) - stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr); + if (in_entry_text(frame.pc)) { + stack = frame.fp - offsetof(struct pt_regs, stackframe); - dump_mem("", "Exception stack", stack, - stack + sizeof(struct pt_regs)); + if (on_accessible_stack(tsk, stack)) + dump_mem("", "Exception stack", stack, + stack + sizeof(struct pt_regs)); } } @@ -257,8 +238,6 @@ static int __die(const char *str, int err, struct pt_regs *regs) end_of_stack(tsk)); if (!user_mode(regs)) { - dump_mem(KERN_EMERG, "Stack: ", regs->sp, - THREAD_SIZE + (unsigned long)task_stack_page(tsk)); dump_backtrace(regs, tsk); dump_instr(KERN_EMERG, regs); } @@ -484,6 +463,9 @@ static void user_cache_maint_handler(unsigned int esr, struct pt_regs *regs) case ESR_ELx_SYS64_ISS_CRM_DC_CVAC: /* DC CVAC, gets promoted */ __user_cache_maint("dc civac", address, ret); break; + case ESR_ELx_SYS64_ISS_CRM_DC_CVAP: /* DC CVAP */ + __user_cache_maint("sys 3, c7, c12, 1", address, ret); + break; case ESR_ELx_SYS64_ISS_CRM_DC_CIVAC: /* DC CIVAC */ __user_cache_maint("dc civac", address, ret); break; @@ -593,7 +575,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs) if (show_unhandled_signals_ratelimited()) { pr_info("%s[%d]: syscall %d\n", current->comm, - task_pid_nr(current), (int)regs->syscallno); + task_pid_nr(current), regs->syscallno); dump_instr("", regs); if (user_mode(regs)) __show_regs(regs); @@ -689,6 +671,43 @@ asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr) force_sig_info(info.si_signo, &info, current); } +#ifdef CONFIG_VMAP_STACK + +DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack) + __aligned(16); + +asmlinkage void handle_bad_stack(struct pt_regs *regs) +{ + unsigned long tsk_stk = (unsigned long)current->stack; + unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr); + unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack); + unsigned int esr = read_sysreg(esr_el1); + unsigned long far = read_sysreg(far_el1); + + console_verbose(); + pr_emerg("Insufficient stack space to handle exception!"); + + pr_emerg("ESR: 0x%08x -- %s\n", esr, esr_get_class_string(esr)); + pr_emerg("FAR: 0x%016lx\n", far); + + pr_emerg("Task stack: [0x%016lx..0x%016lx]\n", + tsk_stk, tsk_stk + THREAD_SIZE); + pr_emerg("IRQ stack: [0x%016lx..0x%016lx]\n", + irq_stk, irq_stk + THREAD_SIZE); + pr_emerg("Overflow stack: [0x%016lx..0x%016lx]\n", + ovf_stk, ovf_stk + OVERFLOW_STACK_SIZE); + + __show_regs(regs); + + /* + * We use nmi_panic to limit the potential for recusive overflows, and + * to get a better stack trace. + */ + nmi_panic(NULL, "kernel stack overflow"); + cpu_park_loop(); +} +#endif + void __pte_error(const char *file, int line, unsigned long val) { pr_err("%s:%d: bad pte %016lx.\n", file, line, val); diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index e8f759f764f2..2d419006ad43 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -110,12 +110,27 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp) } #endif /* CONFIG_COMPAT */ +static int vdso_mremap(const struct vm_special_mapping *sm, + struct vm_area_struct *new_vma) +{ + unsigned long new_size = new_vma->vm_end - new_vma->vm_start; + unsigned long vdso_size = vdso_end - vdso_start; + + if (vdso_size != new_size) + return -EINVAL; + + current->mm->context.vdso = (void *)new_vma->vm_start; + + return 0; +} + static struct vm_special_mapping vdso_spec[2] __ro_after_init = { { .name = "[vvar]", }, { .name = "[vdso]", + .mremap = vdso_mremap, }, }; diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile index 62c84f7cb01b..b215c712d897 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Building a vDSO image for AArch64. # diff --git a/arch/arm64/kernel/vdso/gen_vdso_offsets.sh b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh index 01924ff071ad..0664acaf61ff 100755 --- a/arch/arm64/kernel/vdso/gen_vdso_offsets.sh +++ b/arch/arm64/kernel/vdso/gen_vdso_offsets.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # # Match symbols in the DSO that look like VDSO_*; produce a header file diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 987a00ee446c..7da3e5c366a0 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ld script to make ARM Linux kernel * taken from the i386 version by Russell King @@ -72,22 +73,6 @@ PECOFF_FILE_ALIGNMENT = 0x200; #define PECOFF_EDATA_PADDING #endif -#if defined(CONFIG_DEBUG_ALIGN_RODATA) -/* - * 4 KB granule: 1 level 2 entry - * 16 KB granule: 128 level 3 entries, with contiguous bit - * 64 KB granule: 32 level 3 entries, with contiguous bit - */ -#define SEGMENT_ALIGN SZ_2M -#else -/* - * 4 KB granule: 16 level 3 entries, with contiguous bit - * 16 KB granule: 4 level 3 entries, without contiguous bit - * 64 KB granule: 1 level 3 entry - */ -#define SEGMENT_ALIGN SZ_64K -#endif - SECTIONS { /* @@ -192,7 +177,7 @@ SECTIONS _data = .; _sdata = .; - RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) + RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) /* * Data written with the MMU off but read with the MMU on requires diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 52cb7ad9b2fd..13f81f971390 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # KVM configuration # diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 5d9810086c25..861acbbac385 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Kernel-based Virtual Machine module # diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index 17d8a1677a0b..7debb74843a0 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -84,7 +84,7 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run) if (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WFx_ISS_WFE) { trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true); vcpu->stat.wfe_exit_stat++; - kvm_vcpu_on_spin(vcpu); + kvm_vcpu_on_spin(vcpu, vcpu_mode_priv(vcpu)); } else { trace_kvm_wfx_arm64(*vcpu_pc(vcpu), false); vcpu->stat.wfi_exit_stat++; diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile index 14c4e3b14bcb..f04400d494b7 100644 --- a/arch/arm64/kvm/hyp/Makefile +++ b/arch/arm64/kvm/hyp/Makefile @@ -1,8 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Kernel-based Virtual Machine module, HYP part # -ccflags-y += -fno-stack-protector +ccflags-y += -fno-stack-protector -DDISABLE_BRANCH_PROFILING KVM=../../../../virt/kvm diff --git a/arch/arm64/kvm/hyp/s2-setup.c b/arch/arm64/kvm/hyp/s2-setup.c index b81f4091c909..a81f5e10fc8c 100644 --- a/arch/arm64/kvm/hyp/s2-setup.c +++ b/arch/arm64/kvm/hyp/s2-setup.c @@ -70,7 +70,7 @@ u32 __hyp_text __init_stage2_translation(void) * Management in ID_AA64MMFR1_EL1 and enable the feature in VTCR_EL2. */ tmp = (read_sysreg(id_aa64mmfr1_el1) >> ID_AA64MMFR1_HADBS_SHIFT) & 0xf; - if (IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && tmp) + if (tmp) val |= VTCR_EL2_HA; /* diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c index da6a8cfa54a0..3556715a774e 100644 --- a/arch/arm64/kvm/inject_fault.c +++ b/arch/arm64/kvm/inject_fault.c @@ -33,12 +33,26 @@ #define LOWER_EL_AArch64_VECTOR 0x400 #define LOWER_EL_AArch32_VECTOR 0x600 +/* + * Table taken from ARMv8 ARM DDI0487B-B, table G1-10. + */ +static const u8 return_offsets[8][2] = { + [0] = { 0, 0 }, /* Reset, unused */ + [1] = { 4, 2 }, /* Undefined */ + [2] = { 0, 0 }, /* SVC, unused */ + [3] = { 4, 4 }, /* Prefetch abort */ + [4] = { 8, 8 }, /* Data abort */ + [5] = { 0, 0 }, /* HVC, unused */ + [6] = { 4, 4 }, /* IRQ, unused */ + [7] = { 4, 4 }, /* FIQ, unused */ +}; + static void prepare_fault32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset) { unsigned long cpsr; unsigned long new_spsr_value = *vcpu_cpsr(vcpu); bool is_thumb = (new_spsr_value & COMPAT_PSR_T_BIT); - u32 return_offset = (is_thumb) ? 4 : 0; + u32 return_offset = return_offsets[vect_offset >> 2][is_thumb]; u32 sctlr = vcpu_cp15(vcpu, c1_SCTLR); cpsr = mode | COMPAT_PSR_I_BIT; diff --git a/arch/arm64/kvm/trace.h b/arch/arm64/kvm/trace.h index 5188c7007169..3b82fb1ddd09 100644 --- a/arch/arm64/kvm/trace.h +++ b/arch/arm64/kvm/trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_ARM64_KVM_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_ARM64_KVM_H diff --git a/arch/arm64/kvm/vgic-sys-reg-v3.c b/arch/arm64/kvm/vgic-sys-reg-v3.c index 116786d2e8e8..c77d508b7462 100644 --- a/arch/arm64/kvm/vgic-sys-reg-v3.c +++ b/arch/arm64/kvm/vgic-sys-reg-v3.c @@ -208,29 +208,12 @@ static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu, static bool access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r, u8 apr) { - struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu; u8 idx = r->Op2 & 3; - /* - * num_pri_bits are initialized with HW supported values. - * We can rely safely on num_pri_bits even if VM has not - * restored ICC_CTLR_EL1 before restoring APnR registers. - */ - switch (vgic_v3_cpu->num_pri_bits) { - case 7: - vgic_v3_access_apr_reg(vcpu, p, apr, idx); - break; - case 6: - if (idx > 1) - goto err; - vgic_v3_access_apr_reg(vcpu, p, apr, idx); - break; - default: - if (idx > 0) - goto err; - vgic_v3_access_apr_reg(vcpu, p, apr, idx); - } + if (idx > vgic_v3_max_apr_idx(vcpu)) + goto err; + vgic_v3_access_apr_reg(vcpu, p, apr, idx); return true; err: if (!p->is_write) diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile index c86b7909ef31..9a8cb96555d6 100644 --- a/arch/arm64/lib/Makefile +++ b/arch/arm64/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 lib-y := bitops.o clear_user.o delay.o copy_from_user.o \ copy_to_user.o copy_in_user.o copy_page.o \ clear_page.o memchr.o memcpy.o memmove.o memset.o \ @@ -17,3 +18,5 @@ CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2 \ -fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12 \ -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15 \ -fcall-saved-x18 + +lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o diff --git a/arch/arm64/lib/uaccess_flushcache.c b/arch/arm64/lib/uaccess_flushcache.c new file mode 100644 index 000000000000..b6ceafdb8b72 --- /dev/null +++ b/arch/arm64/lib/uaccess_flushcache.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +void memcpy_flushcache(void *dst, const void *src, size_t cnt) +{ + /* + * We assume this should not be called with @dst pointing to + * non-cacheable memory, such that we don't need an explicit + * barrier to order the cache maintenance against the memcpy. + */ + memcpy(dst, src, cnt); + __clean_dcache_area_pop(dst, cnt); +} +EXPORT_SYMBOL_GPL(memcpy_flushcache); + +void memcpy_page_flushcache(char *to, struct page *page, size_t offset, + size_t len) +{ + memcpy_flushcache(to, page_address(page) + offset, len); +} + +unsigned long __copy_user_flushcache(void *to, const void __user *from, + unsigned long n) +{ + unsigned long rc = __arch_copy_from_user(to, from, n); + + /* See above */ + __clean_dcache_area_pop(to, n - rc); + return rc; +} diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile index 9b0ba191e48e..849c1df3d214 100644 --- a/arch/arm64/mm/Makefile +++ b/arch/arm64/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y := dma-mapping.o extable.o fault.o init.o \ cache.o copypage.o flush.o \ ioremap.o mmap.o pgd.o mmu.o \ diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S index 83c27b6e6dca..7f1dbe962cf5 100644 --- a/arch/arm64/mm/cache.S +++ b/arch/arm64/mm/cache.S @@ -108,6 +108,19 @@ ENTRY(__clean_dcache_area_pou) ret ENDPROC(__clean_dcache_area_pou) +/* + * __inval_dcache_area(kaddr, size) + * + * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * are invalidated. Any partial lines at the ends of the interval are + * also cleaned to PoC to prevent data loss. + * + * - kaddr - kernel address + * - size - size in question + */ +ENTRY(__inval_dcache_area) + /* FALLTHROUGH */ + /* * __dma_inv_area(start, size) * - start - virtual start address of region @@ -115,14 +128,6 @@ ENDPROC(__clean_dcache_area_pou) */ __dma_inv_area: add x1, x1, x0 - /* FALLTHROUGH */ - -/* - * __inval_cache_range(start, end) - * - start - start address of region - * - end - end address of region - */ -ENTRY(__inval_cache_range) dcache_line_size x2, x3 sub x3, x2, #1 tst x1, x3 // end cache line aligned? @@ -140,7 +145,7 @@ ENTRY(__inval_cache_range) b.lo 2b dsb sy ret -ENDPIPROC(__inval_cache_range) +ENDPIPROC(__inval_dcache_area) ENDPROC(__dma_inv_area) /* @@ -166,6 +171,20 @@ __dma_clean_area: ENDPIPROC(__clean_dcache_area_poc) ENDPROC(__dma_clean_area) +/* + * __clean_dcache_area_pop(kaddr, size) + * + * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * are cleaned to the PoP. + * + * - kaddr - kernel address + * - size - size in question + */ +ENTRY(__clean_dcache_area_pop) + dcache_by_line_op cvap, sy, x0, x1, x2, x3 + ret +ENDPIPROC(__clean_dcache_area_pop) + /* * __dma_flush_area(start, size) * diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index f27d4dd04384..614af886b7ef 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -42,7 +42,7 @@ static pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot, return prot; } -static struct gen_pool *atomic_pool; +static struct gen_pool *atomic_pool __ro_after_init; #define DEFAULT_DMA_COHERENT_POOL_SIZE SZ_256K static size_t atomic_pool_size __initdata = DEFAULT_DMA_COHERENT_POOL_SIZE; @@ -425,7 +425,7 @@ static int __init atomic_pool_init(void) gen_pool_set_algo(atomic_pool, gen_pool_first_fit_order_align, - (void *)PAGE_SHIFT); + NULL); pr_info("DMA: preallocated %zu KiB pool for atomic allocations\n", atomic_pool_size / 1024); diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c index c9f118cd812b..81e694af5f8c 100644 --- a/arch/arm64/mm/extable.c +++ b/arch/arm64/mm/extable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Based on arch/arm/mm/extable.c */ diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 1f22a41565a3..b64958b23a7f 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -82,6 +83,49 @@ static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) } #endif +static void data_abort_decode(unsigned int esr) +{ + pr_alert("Data abort info:\n"); + + if (esr & ESR_ELx_ISV) { + pr_alert(" Access size = %u byte(s)\n", + 1U << ((esr & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT)); + pr_alert(" SSE = %lu, SRT = %lu\n", + (esr & ESR_ELx_SSE) >> ESR_ELx_SSE_SHIFT, + (esr & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT); + pr_alert(" SF = %lu, AR = %lu\n", + (esr & ESR_ELx_SF) >> ESR_ELx_SF_SHIFT, + (esr & ESR_ELx_AR) >> ESR_ELx_AR_SHIFT); + } else { + pr_alert(" ISV = 0, ISS = 0x%08lx\n", esr & ESR_ELx_ISS_MASK); + } + + pr_alert(" CM = %lu, WnR = %lu\n", + (esr & ESR_ELx_CM) >> ESR_ELx_CM_SHIFT, + (esr & ESR_ELx_WNR) >> ESR_ELx_WNR_SHIFT); +} + +/* + * Decode mem abort information + */ +static void mem_abort_decode(unsigned int esr) +{ + pr_alert("Mem abort info:\n"); + + pr_alert(" Exception class = %s, IL = %u bits\n", + esr_get_class_string(esr), + (esr & ESR_ELx_IL) ? 32 : 16); + pr_alert(" SET = %lu, FnV = %lu\n", + (esr & ESR_ELx_SET_MASK) >> ESR_ELx_SET_SHIFT, + (esr & ESR_ELx_FnV) >> ESR_ELx_FnV_SHIFT); + pr_alert(" EA = %lu, S1PTW = %lu\n", + (esr & ESR_ELx_EA) >> ESR_ELx_EA_SHIFT, + (esr & ESR_ELx_S1PTW) >> ESR_ELx_S1PTW_SHIFT); + + if (esr_is_data_abort(esr)) + data_abort_decode(esr); +} + /* * Dump out the page tables associated with 'addr' in the currently active mm. */ @@ -139,7 +183,6 @@ void show_pte(unsigned long addr) pr_cont("\n"); } -#ifdef CONFIG_ARM64_HW_AFDBM /* * This function sets the access flags (dirty, accessed), as well as write * permission, and only to a more permissive setting. @@ -154,18 +197,13 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t entry, int dirty) { - pteval_t old_pteval; - unsigned int tmp; + pteval_t old_pteval, pteval; if (pte_same(*ptep, entry)) return 0; /* only preserve the access flags and write permission */ - pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY; - - /* set PTE_RDONLY if actual read-only or clean PTE */ - if (!pte_write(entry) || !pte_sw_dirty(entry)) - pte_val(entry) |= PTE_RDONLY; + pte_val(entry) &= PTE_RDONLY | PTE_AF | PTE_WRITE | PTE_DIRTY; /* * Setting the flags must be done atomically to avoid racing with the @@ -174,21 +212,18 @@ int ptep_set_access_flags(struct vm_area_struct *vma, * (calculated as: a & b == ~(~a | ~b)). */ pte_val(entry) ^= PTE_RDONLY; - asm volatile("// ptep_set_access_flags\n" - " prfm pstl1strm, %2\n" - "1: ldxr %0, %2\n" - " eor %0, %0, %3 // negate PTE_RDONLY in *ptep\n" - " orr %0, %0, %4 // set flags\n" - " eor %0, %0, %3 // negate final PTE_RDONLY\n" - " stxr %w1, %0, %2\n" - " cbnz %w1, 1b\n" - : "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep)) - : "L" (PTE_RDONLY), "r" (pte_val(entry))); + pteval = READ_ONCE(pte_val(*ptep)); + do { + old_pteval = pteval; + pteval ^= PTE_RDONLY; + pteval |= pte_val(entry); + pteval ^= PTE_RDONLY; + pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval); + } while (pteval != old_pteval); flush_tlb_fix_spurious_fault(vma, address); return 1; } -#endif static bool is_el1_instruction_abort(unsigned int esr) { @@ -248,6 +283,8 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr, pr_alert("Unable to handle kernel %s at virtual address %08lx\n", msg, addr); + mem_abort_decode(esr); + show_pte(addr); die("Oops", regs, esr); bust_spinlocks(0); @@ -614,7 +651,7 @@ static const struct fault_info fault_info[] = { { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 0 translation fault" }, { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 1 translation fault" }, { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 2 translation fault" }, - { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, + { do_translation_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, { do_bad, SIGBUS, 0, "unknown 8" }, { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" }, { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" }, @@ -705,6 +742,8 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, pr_alert("Unhandled fault: %s (0x%08x) at 0x%016lx\n", inf->name, esr, addr); + mem_abort_decode(esr); + info.si_signo = inf->sig; info.si_errno = 0; info.si_code = inf->code; diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c index 21a8d828cbf4..e36ed5087b5c 100644 --- a/arch/arm64/mm/flush.c +++ b/arch/arm64/mm/flush.c @@ -83,3 +83,19 @@ EXPORT_SYMBOL(flush_dcache_page); * Additional functions defined in assembly. */ EXPORT_SYMBOL(flush_icache_range); + +#ifdef CONFIG_ARCH_HAS_PMEM_API +void arch_wb_cache_pmem(void *addr, size_t size) +{ + /* Ensure order against any prior non-cacheable writes */ + dmb(osh); + __clean_dcache_area_pop(addr, size); +} +EXPORT_SYMBOL_GPL(arch_wb_cache_pmem); + +void arch_invalidate_pmem(void *addr, size_t size) +{ + __inval_dcache_area(addr, size); +} +EXPORT_SYMBOL_GPL(arch_invalidate_pmem); +#endif diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 656e0ece2289..6cb0fa92a651 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -41,6 +41,16 @@ int pud_huge(pud_t pud) #endif } +/* + * Select all bits except the pfn + */ +static inline pgprot_t pte_pgprot(pte_t pte) +{ + unsigned long pfn = pte_pfn(pte); + + return __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte)); +} + static int find_num_contig(struct mm_struct *mm, unsigned long addr, pte_t *ptep, size_t *pgsize) { @@ -58,15 +68,107 @@ static int find_num_contig(struct mm_struct *mm, unsigned long addr, return CONT_PTES; } +static inline int num_contig_ptes(unsigned long size, size_t *pgsize) +{ + int contig_ptes = 0; + + *pgsize = size; + + switch (size) { +#ifdef CONFIG_ARM64_4K_PAGES + case PUD_SIZE: +#endif + case PMD_SIZE: + contig_ptes = 1; + break; + case CONT_PMD_SIZE: + *pgsize = PMD_SIZE; + contig_ptes = CONT_PMDS; + break; + case CONT_PTE_SIZE: + *pgsize = PAGE_SIZE; + contig_ptes = CONT_PTES; + break; + } + + return contig_ptes; +} + +/* + * Changing some bits of contiguous entries requires us to follow a + * Break-Before-Make approach, breaking the whole contiguous set + * before we can change any entries. See ARM DDI 0487A.k_iss10775, + * "Misprogramming of the Contiguous bit", page D4-1762. + * + * This helper performs the break step. + */ +static pte_t get_clear_flush(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + struct vm_area_struct vma = { .vm_mm = mm }; + pte_t orig_pte = huge_ptep_get(ptep); + bool valid = pte_valid(orig_pte); + unsigned long i, saddr = addr; + + for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) { + pte_t pte = ptep_get_and_clear(mm, addr, ptep); + + /* + * If HW_AFDBM is enabled, then the HW could turn on + * the dirty bit for any page in the set, so check + * them all. All hugetlb entries are already young. + */ + if (pte_dirty(pte)) + orig_pte = pte_mkdirty(orig_pte); + } + + if (valid) + flush_tlb_range(&vma, saddr, addr); + return orig_pte; +} + +/* + * Changing some bits of contiguous entries requires us to follow a + * Break-Before-Make approach, breaking the whole contiguous set + * before we can change any entries. See ARM DDI 0487A.k_iss10775, + * "Misprogramming of the Contiguous bit", page D4-1762. + * + * This helper performs the break step for use cases where the + * original pte is not needed. + */ +static void clear_flush(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + struct vm_area_struct vma = { .vm_mm = mm }; + unsigned long i, saddr = addr; + + for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) + pte_clear(mm, addr, ptep); + + flush_tlb_range(&vma, saddr, addr); +} + void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) { size_t pgsize; int i; int ncontig; - unsigned long pfn; + unsigned long pfn, dpfn; pgprot_t hugeprot; + /* + * Code needs to be expanded to handle huge swap and migration + * entries. Needed for HUGETLB and MEMORY_FAILURE. + */ + WARN_ON(!pte_present(pte)); + if (!pte_cont(pte)) { set_pte_at(mm, addr, ptep, pte); return; @@ -74,17 +176,30 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, ncontig = find_num_contig(mm, addr, ptep, &pgsize); pfn = pte_pfn(pte); - hugeprot = __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ pte_val(pte)); - for (i = 0; i < ncontig; i++) { + dpfn = pgsize >> PAGE_SHIFT; + hugeprot = pte_pgprot(pte); + + clear_flush(mm, addr, ptep, pgsize, ncontig); + + for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) { pr_debug("%s: set pte %p to 0x%llx\n", __func__, ptep, pte_val(pfn_pte(pfn, hugeprot))); set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); - ptep++; - pfn += pgsize >> PAGE_SHIFT; - addr += pgsize; } } +void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, unsigned long sz) +{ + int i, ncontig; + size_t pgsize; + + ncontig = num_contig_ptes(sz, &pgsize); + + for (i = 0; i < ncontig; i++, ptep++) + set_pte(ptep, pte); +} + pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) { @@ -144,19 +259,28 @@ pte_t *huge_pte_offset(struct mm_struct *mm, return NULL; pud = pud_offset(pgd, addr); - if (pud_none(*pud)) + if (sz != PUD_SIZE && pud_none(*pud)) return NULL; - /* swap or huge page */ - if (!pud_present(*pud) || pud_huge(*pud)) + /* hugepage or swap? */ + if (pud_huge(*pud) || !pud_present(*pud)) return (pte_t *)pud; /* table; check the next level */ + if (sz == CONT_PMD_SIZE) + addr &= CONT_PMD_MASK; + pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) + if (!(sz == PMD_SIZE || sz == CONT_PMD_SIZE) && + pmd_none(*pmd)) return NULL; - if (!pmd_present(*pmd) || pmd_huge(*pmd)) + if (pmd_huge(*pmd) || !pmd_present(*pmd)) return (pte_t *)pmd; + if (sz == CONT_PTE_SIZE) { + pte_t *pte = pte_offset_kernel(pmd, (addr & CONT_PTE_MASK)); + return pte; + } + return NULL; } @@ -176,111 +300,133 @@ pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma, return entry; } +void huge_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long sz) +{ + int i, ncontig; + size_t pgsize; + + ncontig = num_contig_ptes(sz, &pgsize); + + for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) + pte_clear(mm, addr, ptep); +} + pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - pte_t pte; + int ncontig; + size_t pgsize; + pte_t orig_pte = huge_ptep_get(ptep); - if (pte_cont(*ptep)) { - int ncontig, i; - size_t pgsize; - bool is_dirty = false; - - ncontig = find_num_contig(mm, addr, ptep, &pgsize); - /* save the 1st pte to return */ - pte = ptep_get_and_clear(mm, addr, ptep); - for (i = 1, addr += pgsize; i < ncontig; ++i, addr += pgsize) { - /* - * If HW_AFDBM is enabled, then the HW could - * turn on the dirty bit for any of the page - * in the set, so check them all. - */ - ++ptep; - if (pte_dirty(ptep_get_and_clear(mm, addr, ptep))) - is_dirty = true; - } - if (is_dirty) - return pte_mkdirty(pte); - else - return pte; - } else { + if (!pte_cont(orig_pte)) return ptep_get_and_clear(mm, addr, ptep); - } + + ncontig = find_num_contig(mm, addr, ptep, &pgsize); + + return get_clear_flush(mm, addr, ptep, pgsize, ncontig); } int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty) { - if (pte_cont(pte)) { - int ncontig, i, changed = 0; - size_t pgsize = 0; - unsigned long pfn = pte_pfn(pte); - /* Select all bits except the pfn */ - pgprot_t hugeprot = - __pgprot(pte_val(pfn_pte(pfn, __pgprot(0))) ^ - pte_val(pte)); + int ncontig, i, changed = 0; + size_t pgsize = 0; + unsigned long pfn = pte_pfn(pte), dpfn; + pgprot_t hugeprot; + pte_t orig_pte; - pfn = pte_pfn(pte); - ncontig = find_num_contig(vma->vm_mm, addr, ptep, - &pgsize); - for (i = 0; i < ncontig; ++i, ++ptep, addr += pgsize) { - changed |= ptep_set_access_flags(vma, addr, ptep, - pfn_pte(pfn, - hugeprot), - dirty); - pfn += pgsize >> PAGE_SHIFT; - } - return changed; - } else { + if (!pte_cont(pte)) return ptep_set_access_flags(vma, addr, ptep, pte, dirty); - } + + ncontig = find_num_contig(vma->vm_mm, addr, ptep, &pgsize); + dpfn = pgsize >> PAGE_SHIFT; + + orig_pte = get_clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig); + if (!pte_same(orig_pte, pte)) + changed = 1; + + /* Make sure we don't lose the dirty state */ + if (pte_dirty(orig_pte)) + pte = pte_mkdirty(pte); + + hugeprot = pte_pgprot(pte); + for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) + set_pte_at(vma->vm_mm, addr, ptep, pfn_pte(pfn, hugeprot)); + + return changed; } void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - if (pte_cont(*ptep)) { - int ncontig, i; - size_t pgsize = 0; + unsigned long pfn, dpfn; + pgprot_t hugeprot; + int ncontig, i; + size_t pgsize; + pte_t pte; - ncontig = find_num_contig(mm, addr, ptep, &pgsize); - for (i = 0; i < ncontig; ++i, ++ptep, addr += pgsize) - ptep_set_wrprotect(mm, addr, ptep); - } else { + if (!pte_cont(*ptep)) { ptep_set_wrprotect(mm, addr, ptep); + return; } + + ncontig = find_num_contig(mm, addr, ptep, &pgsize); + dpfn = pgsize >> PAGE_SHIFT; + + pte = get_clear_flush(mm, addr, ptep, pgsize, ncontig); + pte = pte_wrprotect(pte); + + hugeprot = pte_pgprot(pte); + pfn = pte_pfn(pte); + + for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) + set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); } void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - if (pte_cont(*ptep)) { - int ncontig, i; - size_t pgsize = 0; + size_t pgsize; + int ncontig; - ncontig = find_num_contig(vma->vm_mm, addr, ptep, - &pgsize); - for (i = 0; i < ncontig; ++i, ++ptep, addr += pgsize) - ptep_clear_flush(vma, addr, ptep); - } else { + if (!pte_cont(*ptep)) { ptep_clear_flush(vma, addr, ptep); + return; } + + ncontig = find_num_contig(vma->vm_mm, addr, ptep, &pgsize); + clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig); } static __init int setup_hugepagesz(char *opt) { unsigned long ps = memparse(opt, &opt); - if (ps == PMD_SIZE) { - hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); - } else if (ps == PUD_SIZE) { - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); - } else { - hugetlb_bad_size(); - pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10); - return 0; + switch (ps) { +#ifdef CONFIG_ARM64_4K_PAGES + case PUD_SIZE: +#endif + case PMD_SIZE * CONT_PMDS: + case PMD_SIZE: + case PAGE_SIZE * CONT_PTES: + hugetlb_add_hstate(ilog2(ps) - PAGE_SHIFT); + return 1; } - return 1; + + hugetlb_bad_size(); + pr_err("hugepagesz: Unsupported page size %lu K\n", ps >> 10); + return 0; } __setup("hugepagesz=", setup_hugepagesz); + +#ifdef CONFIG_ARM64_64K_PAGES +static __init int add_default_hugepagesz(void) +{ + if (size_to_hstate(CONT_PTES * PAGE_SIZE) == NULL) + hugetlb_add_hstate(CONT_PTE_SHIFT); + return 0; +} +arch_initcall(add_default_hugepagesz); +#endif diff --git a/arch/arm64/mm/physaddr.c b/arch/arm64/mm/physaddr.c index 91371daf397c..67a9ba9eaa96 100644 --- a/arch/arm64/mm/physaddr.c +++ b/arch/arm64/mm/physaddr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/arm64/mm/ptdump_debugfs.c b/arch/arm64/mm/ptdump_debugfs.c index eee4d864350c..02b18f8b2905 100644 --- a/arch/arm64/mm/ptdump_debugfs.c +++ b/arch/arm64/mm/ptdump_debugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h index b02a9268dfbf..783de51a6c4e 100644 --- a/arch/arm64/net/bpf_jit.h +++ b/arch/arm64/net/bpf_jit.h @@ -44,8 +44,12 @@ #define A64_COND_NE AARCH64_INSN_COND_NE /* != */ #define A64_COND_CS AARCH64_INSN_COND_CS /* unsigned >= */ #define A64_COND_HI AARCH64_INSN_COND_HI /* unsigned > */ +#define A64_COND_LS AARCH64_INSN_COND_LS /* unsigned <= */ +#define A64_COND_CC AARCH64_INSN_COND_CC /* unsigned < */ #define A64_COND_GE AARCH64_INSN_COND_GE /* signed >= */ #define A64_COND_GT AARCH64_INSN_COND_GT /* signed > */ +#define A64_COND_LE AARCH64_INSN_COND_LE /* signed <= */ +#define A64_COND_LT AARCH64_INSN_COND_LT /* signed < */ #define A64_B_(cond, imm19) A64_COND_BRANCH(cond, (imm19) << 2) /* Unconditional branch (immediate) */ diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index f32144b2e07f..ba38d403abb2 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -527,10 +527,14 @@ emit_bswap_uxt: /* IF (dst COND src) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_X: case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: case BPF_JMP | BPF_JNE | BPF_X: case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: emit(A64_CMP(1, dst, src), ctx); emit_cond_jmp: jmp_offset = bpf2a64_offset(i + off, i, ctx); @@ -542,9 +546,15 @@ emit_cond_jmp: case BPF_JGT: jmp_cond = A64_COND_HI; break; + case BPF_JLT: + jmp_cond = A64_COND_CC; + break; case BPF_JGE: jmp_cond = A64_COND_CS; break; + case BPF_JLE: + jmp_cond = A64_COND_LS; + break; case BPF_JSET: case BPF_JNE: jmp_cond = A64_COND_NE; @@ -552,9 +562,15 @@ emit_cond_jmp: case BPF_JSGT: jmp_cond = A64_COND_GT; break; + case BPF_JSLT: + jmp_cond = A64_COND_LT; + break; case BPF_JSGE: jmp_cond = A64_COND_GE; break; + case BPF_JSLE: + jmp_cond = A64_COND_LE; + break; default: return -EFAULT; } @@ -566,10 +582,14 @@ emit_cond_jmp: /* IF (dst COND imm) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: emit_a64_mov_i(1, tmp, imm, ctx); emit(A64_CMP(1, dst, tmp), ctx); goto emit_cond_jmp; diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 89bdb8264305..af5369422032 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config MMU def_bool n diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug index f3337ee03621..4ddd1b73ee3e 100644 --- a/arch/blackfin/Kconfig.debug +++ b/arch/blackfin/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/blackfin/include/asm/bfin_twi.h b/arch/blackfin/include/asm/bfin_twi.h index aaa0834d34aa..211e9c78f6fb 100644 --- a/arch/blackfin/include/asm/bfin_twi.h +++ b/arch/blackfin/include/asm/bfin_twi.h @@ -1,7 +1,7 @@ /* * bfin_twi.h - interface to Blackfin TWIs * - * Copyright 2005-2010 Analog Devices Inc. + * Copyright 2005-2014 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -10,6 +10,138 @@ #define __ASM_BFIN_TWI_H__ #include +#include +#include + +/* + * ADI twi registers layout + */ +struct bfin_twi_regs { + u16 clkdiv; + u16 dummy1; + u16 control; + u16 dummy2; + u16 slave_ctl; + u16 dummy3; + u16 slave_stat; + u16 dummy4; + u16 slave_addr; + u16 dummy5; + u16 master_ctl; + u16 dummy6; + u16 master_stat; + u16 dummy7; + u16 master_addr; + u16 dummy8; + u16 int_stat; + u16 dummy9; + u16 int_mask; + u16 dummy10; + u16 fifo_ctl; + u16 dummy11; + u16 fifo_stat; + u16 dummy12; + u32 __pad[20]; + u16 xmt_data8; + u16 dummy13; + u16 xmt_data16; + u16 dummy14; + u16 rcv_data8; + u16 dummy15; + u16 rcv_data16; + u16 dummy16; +}; + +struct bfin_twi_iface { + int irq; + spinlock_t lock; + char read_write; + u8 command; + u8 *transPtr; + int readNum; + int writeNum; + int cur_mode; + int manual_stop; + int result; + struct i2c_adapter adap; + struct completion complete; + struct i2c_msg *pmsg; + int msg_num; + int cur_msg; + u16 saved_clkdiv; + u16 saved_control; + struct bfin_twi_regs __iomem *regs_base; +}; + +/* ******************** TWO-WIRE INTERFACE (TWI) MASKS ********************/ +/* TWI_CLKDIV Macros (Use: *pTWI_CLKDIV = CLKLOW(x)|CLKHI(y); ) */ +#define CLKLOW(x) ((x) & 0xFF) /* Periods Clock Is Held Low */ +#define CLKHI(y) (((y)&0xFF)<<0x8) /* Periods Before New Clock Low */ + +/* TWI_PRESCALE Masks */ +#define PRESCALE 0x007F /* SCLKs Per Internal Time Reference (10MHz) */ +#define TWI_ENA 0x0080 /* TWI Enable */ +#define SCCB 0x0200 /* SCCB Compatibility Enable */ + +/* TWI_SLAVE_CTL Masks */ +#define SEN 0x0001 /* Slave Enable */ +#define SADD_LEN 0x0002 /* Slave Address Length */ +#define STDVAL 0x0004 /* Slave Transmit Data Valid */ +#define NAK 0x0008 /* NAK Generated At Conclusion Of Transfer */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ + +/* TWI_SLAVE_STAT Masks */ +#define SDIR 0x0001 /* Slave Transfer Direction (RX/TX*) */ +#define GCALL 0x0002 /* General Call Indicator */ + +/* TWI_MASTER_CTL Masks */ +#define MEN 0x0001 /* Master Mode Enable */ +#define MADD_LEN 0x0002 /* Master Address Length */ +#define MDIR 0x0004 /* Master Transmit Direction (RX/TX*) */ +#define FAST 0x0008 /* Use Fast Mode Timing Specs */ +#define STOP 0x0010 /* Issue Stop Condition */ +#define RSTART 0x0020 /* Repeat Start or Stop* At End Of Transfer */ +#define DCNT 0x3FC0 /* Data Bytes To Transfer */ +#define SDAOVR 0x4000 /* Serial Data Override */ +#define SCLOVR 0x8000 /* Serial Clock Override */ + +/* TWI_MASTER_STAT Masks */ +#define MPROG 0x0001 /* Master Transfer In Progress */ +#define LOSTARB 0x0002 /* Lost Arbitration Indicator (Xfer Aborted) */ +#define ANAK 0x0004 /* Address Not Acknowledged */ +#define DNAK 0x0008 /* Data Not Acknowledged */ +#define BUFRDERR 0x0010 /* Buffer Read Error */ +#define BUFWRERR 0x0020 /* Buffer Write Error */ +#define SDASEN 0x0040 /* Serial Data Sense */ +#define SCLSEN 0x0080 /* Serial Clock Sense */ +#define BUSBUSY 0x0100 /* Bus Busy Indicator */ + +/* TWI_INT_SRC and TWI_INT_ENABLE Masks */ +#define SINIT 0x0001 /* Slave Transfer Initiated */ +#define SCOMP 0x0002 /* Slave Transfer Complete */ +#define SERR 0x0004 /* Slave Transfer Error */ +#define SOVF 0x0008 /* Slave Overflow */ +#define MCOMP 0x0010 /* Master Transfer Complete */ +#define MERR 0x0020 /* Master Transfer Error */ +#define XMTSERV 0x0040 /* Transmit FIFO Service */ +#define RCVSERV 0x0080 /* Receive FIFO Service */ + +/* TWI_FIFO_CTRL Masks */ +#define XMTFLUSH 0x0001 /* Transmit Buffer Flush */ +#define RCVFLUSH 0x0002 /* Receive Buffer Flush */ +#define XMTINTLEN 0x0004 /* Transmit Buffer Interrupt Length */ +#define RCVINTLEN 0x0008 /* Receive Buffer Interrupt Length */ + +/* TWI_FIFO_STAT Masks */ +#define XMTSTAT 0x0003 /* Transmit FIFO Status */ +#define XMT_EMPTY 0x0000 /* Transmit FIFO Empty */ +#define XMT_HALF 0x0001 /* Transmit FIFO Has 1 Byte To Write */ +#define XMT_FULL 0x0003 /* Transmit FIFO Full (2 Bytes To Write) */ + +#define RCVSTAT 0x000C /* Receive FIFO Status */ +#define RCV_EMPTY 0x0000 /* Receive FIFO Empty */ +#define RCV_HALF 0x0004 /* Receive FIFO Has 1 Byte To Read */ +#define RCV_FULL 0x000C /* Receive FIFO Full (2 Bytes To Read) */ #define DEFINE_TWI_REG(reg_name, reg) \ static inline u16 read_##reg_name(struct bfin_twi_iface *iface) \ diff --git a/arch/blackfin/include/asm/clkdev.h b/arch/blackfin/include/asm/clkdev.h index 7ac2436856a5..ded0209348c7 100644 --- a/arch/blackfin/include/asm/clkdev.h +++ b/arch/blackfin/include/asm/clkdev.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CLKDEV__H_ #define __ASM_CLKDEV__H_ diff --git a/arch/blackfin/include/asm/pci.h b/arch/blackfin/include/asm/pci.h index 11ea1cb35036..e6458ddbaf7e 100644 --- a/arch/blackfin/include/asm/pci.h +++ b/arch/blackfin/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Changed from asm-m68k version, Lineo Inc. May 2001 */ #ifndef _ASM_BFIN_PCI_H diff --git a/arch/blackfin/include/asm/rwlock.h b/arch/blackfin/include/asm/rwlock.h index 4a724b378971..98ebc07cb283 100644 --- a/arch/blackfin/include/asm/rwlock.h +++ b/arch/blackfin/include/asm/rwlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_BLACKFIN_RWLOCK_H #define _ASM_BLACKFIN_RWLOCK_H diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h index c58f4a83ed6f..f6431439d15d 100644 --- a/arch/blackfin/include/asm/spinlock.h +++ b/arch/blackfin/include/asm/spinlock.h @@ -48,11 +48,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) __raw_spin_unlock_asm(&lock->lock); } -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - static inline int arch_read_can_lock(arch_rwlock_t *rw) { return __raw_uncached_fetch_asm(&rw->lock) > 0; diff --git a/arch/blackfin/include/mach-common/ports-a.h b/arch/blackfin/include/mach-common/ports-a.h index 9f78a761c40a..71bcd74f83fd 100644 --- a/arch/blackfin/include/mach-common/ports-a.h +++ b/arch/blackfin/include/mach-common/ports-a.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port A Masks */ diff --git a/arch/blackfin/include/mach-common/ports-b.h b/arch/blackfin/include/mach-common/ports-b.h index b81702f09ec6..8013cc8e839b 100644 --- a/arch/blackfin/include/mach-common/ports-b.h +++ b/arch/blackfin/include/mach-common/ports-b.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port B Masks */ diff --git a/arch/blackfin/include/mach-common/ports-c.h b/arch/blackfin/include/mach-common/ports-c.h index 3cc665e0ba08..94e71010ffe9 100644 --- a/arch/blackfin/include/mach-common/ports-c.h +++ b/arch/blackfin/include/mach-common/ports-c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port C Masks */ diff --git a/arch/blackfin/include/mach-common/ports-d.h b/arch/blackfin/include/mach-common/ports-d.h index 868c6a01f1b2..ba84a9fb3450 100644 --- a/arch/blackfin/include/mach-common/ports-d.h +++ b/arch/blackfin/include/mach-common/ports-d.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port D Masks */ diff --git a/arch/blackfin/include/mach-common/ports-e.h b/arch/blackfin/include/mach-common/ports-e.h index c88b0d0dd443..2264fb58bc2b 100644 --- a/arch/blackfin/include/mach-common/ports-e.h +++ b/arch/blackfin/include/mach-common/ports-e.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port E Masks */ diff --git a/arch/blackfin/include/mach-common/ports-f.h b/arch/blackfin/include/mach-common/ports-f.h index d6af20633278..2b8ca3ae2a8e 100644 --- a/arch/blackfin/include/mach-common/ports-f.h +++ b/arch/blackfin/include/mach-common/ports-f.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port F Masks */ diff --git a/arch/blackfin/include/mach-common/ports-g.h b/arch/blackfin/include/mach-common/ports-g.h index 09355d333c0e..11ad917fcf91 100644 --- a/arch/blackfin/include/mach-common/ports-g.h +++ b/arch/blackfin/include/mach-common/ports-g.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port G Masks */ diff --git a/arch/blackfin/include/mach-common/ports-h.h b/arch/blackfin/include/mach-common/ports-h.h index fa3910c6fbd4..511d088b8094 100644 --- a/arch/blackfin/include/mach-common/ports-h.h +++ b/arch/blackfin/include/mach-common/ports-h.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port H Masks */ diff --git a/arch/blackfin/include/mach-common/ports-i.h b/arch/blackfin/include/mach-common/ports-i.h index f176f08af624..21bbab166ae8 100644 --- a/arch/blackfin/include/mach-common/ports-i.h +++ b/arch/blackfin/include/mach-common/ports-i.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port I Masks */ diff --git a/arch/blackfin/include/mach-common/ports-j.h b/arch/blackfin/include/mach-common/ports-j.h index 924123ecec5a..96a252b0b0bd 100644 --- a/arch/blackfin/include/mach-common/ports-j.h +++ b/arch/blackfin/include/mach-common/ports-j.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Port J Masks */ diff --git a/arch/blackfin/include/uapi/asm/bfin_sport.h b/arch/blackfin/include/uapi/asm/bfin_sport.h index c086de87ee61..86c36a208dc5 100644 --- a/arch/blackfin/include/uapi/asm/bfin_sport.h +++ b/arch/blackfin/include/uapi/asm/bfin_sport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * bfin_sport.h - interface to Blackfin SPORTs * diff --git a/arch/blackfin/include/uapi/asm/byteorder.h b/arch/blackfin/include/uapi/asm/byteorder.h index 3b125da5dcb2..bcab6670c7fe 100644 --- a/arch/blackfin/include/uapi/asm/byteorder.h +++ b/arch/blackfin/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__BFIN_ASM_BYTEORDER_H #define _UAPI__BFIN_ASM_BYTEORDER_H diff --git a/arch/blackfin/include/uapi/asm/cachectl.h b/arch/blackfin/include/uapi/asm/cachectl.h index 4fdab75dee15..b5c86fbbca94 100644 --- a/arch/blackfin/include/uapi/asm/cachectl.h +++ b/arch/blackfin/include/uapi/asm/cachectl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * based on the mips/cachectl.h * diff --git a/arch/blackfin/include/uapi/asm/fcntl.h b/arch/blackfin/include/uapi/asm/fcntl.h index f51ad9a4f617..0b02954f06c3 100644 --- a/arch/blackfin/include/uapi/asm/fcntl.h +++ b/arch/blackfin/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2004-2008 Analog Devices Inc. * diff --git a/arch/blackfin/include/uapi/asm/fixed_code.h b/arch/blackfin/include/uapi/asm/fixed_code.h index 3bef1dca379f..707b9214bb26 100644 --- a/arch/blackfin/include/uapi/asm/fixed_code.h +++ b/arch/blackfin/include/uapi/asm/fixed_code.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * This file defines the fixed addresses where userspace programs * can find atomic code sequences. diff --git a/arch/blackfin/include/uapi/asm/ioctls.h b/arch/blackfin/include/uapi/asm/ioctls.h index 9a41c20fc83d..422fee3e4776 100644 --- a/arch/blackfin/include/uapi/asm/ioctls.h +++ b/arch/blackfin/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ARCH_BFIN_IOCTLS_H__ #define _UAPI__ARCH_BFIN_IOCTLS_H__ diff --git a/arch/blackfin/include/uapi/asm/poll.h b/arch/blackfin/include/uapi/asm/poll.h index 99c7d6816da0..8b094d43e9b7 100644 --- a/arch/blackfin/include/uapi/asm/poll.h +++ b/arch/blackfin/include/uapi/asm/poll.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2004-2009 Analog Devices Inc. * diff --git a/arch/blackfin/include/uapi/asm/posix_types.h b/arch/blackfin/include/uapi/asm/posix_types.h index 9608ef64dc47..8947c75cf638 100644 --- a/arch/blackfin/include/uapi/asm/posix_types.h +++ b/arch/blackfin/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2004-2009 Analog Devices Inc. * diff --git a/arch/blackfin/include/uapi/asm/ptrace.h b/arch/blackfin/include/uapi/asm/ptrace.h index fd48bd0739d2..e4423d5560da 100644 --- a/arch/blackfin/include/uapi/asm/ptrace.h +++ b/arch/blackfin/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2004-2008 Analog Devices Inc. * diff --git a/arch/blackfin/include/uapi/asm/sigcontext.h b/arch/blackfin/include/uapi/asm/sigcontext.h index b58f12dc27bd..66b4d32af89c 100644 --- a/arch/blackfin/include/uapi/asm/sigcontext.h +++ b/arch/blackfin/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2004-2008 Analog Devices Inc. * diff --git a/arch/blackfin/include/uapi/asm/siginfo.h b/arch/blackfin/include/uapi/asm/siginfo.h index c72f4e6e386f..b1db506c8d2e 100644 --- a/arch/blackfin/include/uapi/asm/siginfo.h +++ b/arch/blackfin/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2004-2008 Analog Devices Inc. * @@ -14,28 +15,36 @@ #define si_uid16 _sifields._kill._uid -#define ILL_ILLPARAOP (__SI_FAULT|2) /* illegal opcode combine ********** */ -#define ILL_ILLEXCPT (__SI_FAULT|4) /* unrecoverable exception ********** */ -#define ILL_CPLB_VI (__SI_FAULT|9) /* D/I CPLB protect violation ******** */ -#define ILL_CPLB_MISS (__SI_FAULT|10) /* D/I CPLB miss ******** */ -#define ILL_CPLB_MULHIT (__SI_FAULT|11) /* D/I CPLB multiple hit ******** */ +#define ILL_ILLPARAOP 2 /* illegal opcode combine ********** */ +#define ILL_ILLEXCPT 4 /* unrecoverable exception ********** */ +#define ILL_CPLB_VI 9 /* D/I CPLB protect violation ******** */ +#define ILL_CPLB_MISS 10 /* D/I CPLB miss ******** */ +#define ILL_CPLB_MULHIT 11 /* D/I CPLB multiple hit ******** */ +#undef NSIGILL +#define NSIGILL 11 /* * SIGBUS si_codes */ -#define BUS_OPFETCH (__SI_FAULT|4) /* error from instruction fetch ******** */ +#define BUS_OPFETCH 4 /* error from instruction fetch ******** */ +#undef NSIGBUS +#define NSIGBUS 4 /* * SIGTRAP si_codes */ -#define TRAP_STEP (__SI_FAULT|1) /* single-step breakpoint************* */ -#define TRAP_TRACEFLOW (__SI_FAULT|2) /* trace buffer overflow ************* */ -#define TRAP_WATCHPT (__SI_FAULT|3) /* watchpoint match ************* */ -#define TRAP_ILLTRAP (__SI_FAULT|4) /* illegal trap ************* */ +#define TRAP_STEP 1 /* single-step breakpoint************* */ +#define TRAP_TRACEFLOW 2 /* trace buffer overflow ************* */ +#define TRAP_WATCHPT 3 /* watchpoint match ************* */ +#define TRAP_ILLTRAP 4 /* illegal trap ************* */ +#undef NSIGTRAP +#define NSIGTRAP 4 /* * SIGSEGV si_codes */ -#define SEGV_STACKFLOW (__SI_FAULT|3) /* stack overflow */ +#define SEGV_STACKFLOW 3 /* stack overflow */ +#undef NSIGSEGV +#define NSIGSEGV 3 #endif /* _UAPI_BFIN_SIGINFO_H */ diff --git a/arch/blackfin/include/uapi/asm/signal.h b/arch/blackfin/include/uapi/asm/signal.h index f0a0d8b6663a..f8e3b99ba0a2 100644 --- a/arch/blackfin/include/uapi/asm/signal.h +++ b/arch/blackfin/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_BLACKFIN_SIGNAL_H #define _UAPI_BLACKFIN_SIGNAL_H diff --git a/arch/blackfin/include/uapi/asm/stat.h b/arch/blackfin/include/uapi/asm/stat.h index d3068a750b94..458959d1a5ec 100644 --- a/arch/blackfin/include/uapi/asm/stat.h +++ b/arch/blackfin/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2004-2006 Analog Devices Inc. * diff --git a/arch/blackfin/include/uapi/asm/swab.h b/arch/blackfin/include/uapi/asm/swab.h index f5626b77684a..d3437933b95f 100644 --- a/arch/blackfin/include/uapi/asm/swab.h +++ b/arch/blackfin/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2009 Analog Devices Inc. * diff --git a/arch/blackfin/include/uapi/asm/unistd.h b/arch/blackfin/include/uapi/asm/unistd.h index 0cb9078ef482..2d392c09323c 100644 --- a/arch/blackfin/include/uapi/asm/unistd.h +++ b/arch/blackfin/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright 2004-2009 Analog Devices Inc. * diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 703dc7cf2ecc..1580791f0e3a 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/kernel/Makefile # diff --git a/arch/blackfin/kernel/cplb-nompu/Makefile b/arch/blackfin/kernel/cplb-nompu/Makefile index 394d0b1b28fe..81baa27bc389 100644 --- a/arch/blackfin/kernel/cplb-nompu/Makefile +++ b/arch/blackfin/kernel/cplb-nompu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/kernel/cplb-nompu/Makefile # diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c index e272bca93c64..f31ace221392 100644 --- a/arch/blackfin/kernel/debug-mmrs.c +++ b/arch/blackfin/kernel/debug-mmrs.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 0188c933b155..15af5768c403 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -4,8 +4,6 @@ * Licensed under the GPL-2 or later */ -#define pr_fmt(fmt) "module %s: " fmt, mod->name - #include #include #include @@ -16,6 +14,11 @@ #include #include +#define mod_err(mod, fmt, ...) \ + pr_err("module %s: " fmt, (mod)->name, ##__VA_ARGS__) +#define mod_debug(mod, fmt, ...) \ + pr_debug("module %s: " fmt, (mod)->name, ##__VA_ARGS__) + /* Transfer the section to the L1 memory */ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, @@ -44,7 +47,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_inst_sram_alloc(s->sh_size); mod->arch.text_l1 = dest; if (dest == NULL) { - pr_err("L1 inst memory allocation failed\n"); + mod_err(mod, "L1 inst memory allocation failed\n"); return -1; } dma_memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -56,7 +59,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_sram_alloc(s->sh_size); mod->arch.data_a_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -68,7 +71,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_sram_zalloc(s->sh_size); mod->arch.bss_a_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } @@ -77,7 +80,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.data_b_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -87,7 +90,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.bss_b_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n"); + mod_err(mod, "L1 data memory allocation failed\n"); return -1; } memset(dest, 0, s->sh_size); @@ -99,7 +102,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_alloc(s->sh_size); mod->arch.text_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n"); + mod_err(mod, "L2 SRAM allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -111,7 +114,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_alloc(s->sh_size); mod->arch.data_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n"); + mod_err(mod, "L2 SRAM allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -123,7 +126,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_zalloc(s->sh_size); mod->arch.bss_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n"); + mod_err(mod, "L2 SRAM allocation failed\n"); return -1; } @@ -157,8 +160,8 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, Elf32_Sym *sym; unsigned long location, value, size; - pr_debug("applying relocate section %u to %u\n", - relsec, sechdrs[relsec].sh_info); + mod_debug(mod, "applying relocate section %u to %u\n", + relsec, sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { /* This is where to make the change */ @@ -174,14 +177,14 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, #ifdef CONFIG_SMP if (location >= COREB_L1_DATA_A_START) { - pr_err("cannot relocate in L1: %u (SMP kernel)\n", + mod_err(mod, "cannot relocate in L1: %u (SMP kernel)\n", ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } #endif - pr_debug("location is %lx, value is %lx type is %d\n", - location, value, ELF32_R_TYPE(rel[i].r_info)); + mod_debug(mod, "location is %lx, value is %lx type is %d\n", + location, value, ELF32_R_TYPE(rel[i].r_info)); switch (ELF32_R_TYPE(rel[i].r_info)) { @@ -200,12 +203,12 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, case R_BFIN_PCREL12_JUMP: case R_BFIN_PCREL12_JUMP_S: case R_BFIN_PCREL10: - pr_err("unsupported relocation: %u (no -mlong-calls?)\n", + mod_err(mod, "unsupported relocation: %u (no -mlong-calls?)\n", ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; default: - pr_err("unknown relocation: %u\n", + mod_err(mod, "unknown relocation: %u\n", ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -222,7 +225,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, isram_memcpy((void *)location, &value, size); break; default: - pr_err("invalid relocation for %#lx\n", location); + mod_err(mod, "invalid relocation for %#lx\n", location); return -ENOEXEC; } } diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile index 42c47dc9e12f..74ddde0eb2e7 100644 --- a/arch/blackfin/lib/Makefile +++ b/arch/blackfin/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/lib/Makefile # diff --git a/arch/blackfin/mach-bf518/Kconfig b/arch/blackfin/mach-bf518/Kconfig index bde92a19970e..4731f6b27e47 100644 --- a/arch/blackfin/mach-bf518/Kconfig +++ b/arch/blackfin/mach-bf518/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config BF51x def_bool y depends on (BF512 || BF514 || BF516 || BF518) diff --git a/arch/blackfin/mach-bf518/boards/Kconfig b/arch/blackfin/mach-bf518/boards/Kconfig index 252261ec04c4..f7b93b950ef4 100644 --- a/arch/blackfin/mach-bf518/boards/Kconfig +++ b/arch/blackfin/mach-bf518/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN518F_EZBRD diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig index 0ba54701af0b..6df20f9c7bd4 100644 --- a/arch/blackfin/mach-bf527/Kconfig +++ b/arch/blackfin/mach-bf527/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config BF52x def_bool y depends on (BF522 || BF523 || BF524 || BF525 || BF526 || BF527) diff --git a/arch/blackfin/mach-bf527/boards/Kconfig b/arch/blackfin/mach-bf527/boards/Kconfig index 1cc2667c10f1..a76f02fae11c 100644 --- a/arch/blackfin/mach-bf527/boards/Kconfig +++ b/arch/blackfin/mach-bf527/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN527_EZKIT diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile index 1d67da9f05ac..6ada1537e20a 100644 --- a/arch/blackfin/mach-bf527/boards/Makefile +++ b/arch/blackfin/mach-bf527/boards/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/mach-bf527/boards/Makefile # diff --git a/arch/blackfin/mach-bf533/Kconfig b/arch/blackfin/mach-bf533/Kconfig index 4c572443147e..4e1a05be7137 100644 --- a/arch/blackfin/mach-bf533/Kconfig +++ b/arch/blackfin/mach-bf533/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if (BF533 || BF532 || BF531) source "arch/blackfin/mach-bf533/boards/Kconfig" diff --git a/arch/blackfin/mach-bf533/boards/Kconfig b/arch/blackfin/mach-bf533/boards/Kconfig index 8d8b3e7321e6..3fde0df1b5f2 100644 --- a/arch/blackfin/mach-bf533/boards/Kconfig +++ b/arch/blackfin/mach-bf533/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN533_STAMP diff --git a/arch/blackfin/mach-bf533/boards/Makefile b/arch/blackfin/mach-bf533/boards/Makefile index ff1e832f80d2..35256d2fc040 100644 --- a/arch/blackfin/mach-bf533/boards/Makefile +++ b/arch/blackfin/mach-bf533/boards/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/mach-bf533/boards/Makefile # diff --git a/arch/blackfin/mach-bf537/Kconfig b/arch/blackfin/mach-bf537/Kconfig index 08b2b343ccec..1d69b043afd4 100644 --- a/arch/blackfin/mach-bf537/Kconfig +++ b/arch/blackfin/mach-bf537/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if (BF537 || BF534 || BF536) source "arch/blackfin/mach-bf537/boards/Kconfig" diff --git a/arch/blackfin/mach-bf537/boards/Kconfig b/arch/blackfin/mach-bf537/boards/Kconfig index a44bf3a1816e..60b7b29e512e 100644 --- a/arch/blackfin/mach-bf537/boards/Kconfig +++ b/arch/blackfin/mach-bf537/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN537_STAMP diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile index fe42258fe1f4..47a1acc5f389 100644 --- a/arch/blackfin/mach-bf537/boards/Makefile +++ b/arch/blackfin/mach-bf537/boards/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/mach-bf537/boards/Makefile # diff --git a/arch/blackfin/mach-bf537/boards/dnp5370.c b/arch/blackfin/mach-bf537/boards/dnp5370.c index e79b3b810c39..c4a8ffb15417 100644 --- a/arch/blackfin/mach-bf537/boards/dnp5370.c +++ b/arch/blackfin/mach-bf537/boards/dnp5370.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 7528148dc492..400e6693643e 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/blackfin/mach-bf538/Kconfig b/arch/blackfin/mach-bf538/Kconfig index 2d280f504ab0..4aea85e4e5cf 100644 --- a/arch/blackfin/mach-bf538/Kconfig +++ b/arch/blackfin/mach-bf538/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if (BF538 || BF539) source "arch/blackfin/mach-bf538/boards/Kconfig" diff --git a/arch/blackfin/mach-bf538/boards/Kconfig b/arch/blackfin/mach-bf538/boards/Kconfig index 215249ba58bb..114cff440d43 100644 --- a/arch/blackfin/mach-bf538/boards/Kconfig +++ b/arch/blackfin/mach-bf538/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN538_EZKIT diff --git a/arch/blackfin/mach-bf548/Kconfig b/arch/blackfin/mach-bf548/Kconfig index 334ec7b12188..71c2a765af1d 100644 --- a/arch/blackfin/mach-bf548/Kconfig +++ b/arch/blackfin/mach-bf548/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config BF542 def_bool y depends on BF542_std || BF542M diff --git a/arch/blackfin/mach-bf548/boards/Kconfig b/arch/blackfin/mach-bf548/boards/Kconfig index d38e52671853..e8ce579ae8f0 100644 --- a/arch/blackfin/mach-bf548/boards/Kconfig +++ b/arch/blackfin/mach-bf548/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN548_EZKIT diff --git a/arch/blackfin/mach-bf561/Kconfig b/arch/blackfin/mach-bf561/Kconfig index cb9743641511..059c3cbdb5ec 100644 --- a/arch/blackfin/mach-bf561/Kconfig +++ b/arch/blackfin/mach-bf561/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if (BF561) source "arch/blackfin/mach-bf561/boards/Kconfig" diff --git a/arch/blackfin/mach-bf561/boards/Kconfig b/arch/blackfin/mach-bf561/boards/Kconfig index 1aa529b9f8bb..10e977b56710 100644 --- a/arch/blackfin/mach-bf561/boards/Kconfig +++ b/arch/blackfin/mach-bf561/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN561_EZKIT diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c index 37f8f25a1347..696cc9d7820a 100644 --- a/arch/blackfin/mach-bf561/boards/acvilon.c +++ b/arch/blackfin/mach-bf561/boards/acvilon.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/blackfin/mach-bf609/Kconfig b/arch/blackfin/mach-bf609/Kconfig index 6584190faeb8..7d6a8b8926ba 100644 --- a/arch/blackfin/mach-bf609/Kconfig +++ b/arch/blackfin/mach-bf609/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config BF60x def_bool y depends on (BF609) diff --git a/arch/blackfin/mach-bf609/boards/Kconfig b/arch/blackfin/mach-bf609/boards/Kconfig index 30e8b6b0d2ed..350154b2a3ee 100644 --- a/arch/blackfin/mach-bf609/boards/Kconfig +++ b/arch/blackfin/mach-bf609/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "System type" default BFIN609_EZKIT diff --git a/arch/blackfin/mach-bf609/clock.c b/arch/blackfin/mach-bf609/clock.c index 392a59b9a504..16e0b09e2197 100644 --- a/arch/blackfin/mach-bf609/clock.c +++ b/arch/blackfin/mach-bf609/clock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/blackfin/mach-bf609/dpm.S b/arch/blackfin/mach-bf609/dpm.S index 54d50c689db1..fcb8f688a8b2 100644 --- a/arch/blackfin/mach-bf609/dpm.S +++ b/arch/blackfin/mach-bf609/dpm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile index f09979204040..fcef1c8e117f 100644 --- a/arch/blackfin/mach-common/Makefile +++ b/arch/blackfin/mach-common/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/mach-common/Makefile # diff --git a/arch/blackfin/mach-common/clock.h b/arch/blackfin/mach-common/clock.h index 645ff460a1f2..fed851a51aaf 100644 --- a/arch/blackfin/mach-common/clock.h +++ b/arch/blackfin/mach-common/clock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_COMMON_CLKDEV_H #define __MACH_COMMON_CLKDEV_H diff --git a/arch/blackfin/oprofile/Makefile b/arch/blackfin/oprofile/Makefile index c70af3a01297..e89e1c9f3496 100644 --- a/arch/blackfin/oprofile/Makefile +++ b/arch/blackfin/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/blackfin/oprofile/Makefile # diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 5aa8ea8bad2d..c6b4dd1418b4 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile index 8734abee548e..842b7b0bfe80 100644 --- a/arch/c6x/boot/Makefile +++ b/arch/c6x/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for bootable kernel images # diff --git a/arch/c6x/boot/dts/Makefile b/arch/c6x/boot/dts/Makefile index c7528b02d061..7368838c6e71 100644 --- a/arch/c6x/boot/dts/Makefile +++ b/arch/c6x/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for device trees # diff --git a/arch/c6x/boot/dts/tms320c6455.dtsi b/arch/c6x/boot/dts/tms320c6455.dtsi index a804ec1e018b..0b21cb30343b 100644 --- a/arch/c6x/boot/dts/tms320c6455.dtsi +++ b/arch/c6x/boot/dts/tms320c6455.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; diff --git a/arch/c6x/boot/dts/tms320c6457.dtsi b/arch/c6x/boot/dts/tms320c6457.dtsi index 35f40709a719..e49f7ae19124 100644 --- a/arch/c6x/boot/dts/tms320c6457.dtsi +++ b/arch/c6x/boot/dts/tms320c6457.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; diff --git a/arch/c6x/boot/dts/tms320c6472.dtsi b/arch/c6x/boot/dts/tms320c6472.dtsi index b488aaec65c0..9dd4b04e78ef 100644 --- a/arch/c6x/boot/dts/tms320c6472.dtsi +++ b/arch/c6x/boot/dts/tms320c6472.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; diff --git a/arch/c6x/boot/dts/tms320c6474.dtsi b/arch/c6x/boot/dts/tms320c6474.dtsi index cc601bf348a1..0ef5333629a6 100644 --- a/arch/c6x/boot/dts/tms320c6474.dtsi +++ b/arch/c6x/boot/dts/tms320c6474.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; diff --git a/arch/c6x/boot/dts/tms320c6678.dtsi b/arch/c6x/boot/dts/tms320c6678.dtsi index 386196e5eae7..da1e3f2bf062 100644 --- a/arch/c6x/boot/dts/tms320c6678.dtsi +++ b/arch/c6x/boot/dts/tms320c6678.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; diff --git a/arch/c6x/include/asm/flat.h b/arch/c6x/include/asm/flat.h index 6f1feb00bd52..76fd0bb962a3 100644 --- a/arch/c6x/include/asm/flat.h +++ b/arch/c6x/include/asm/flat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_C6X_FLAT_H #define __ASM_C6X_FLAT_H diff --git a/arch/c6x/include/asm/linkage.h b/arch/c6x/include/asm/linkage.h index 376925c47d57..1ad615da6479 100644 --- a/arch/c6x/include/asm/linkage.h +++ b/arch/c6x/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_C6X_LINKAGE_H #define _ASM_C6X_LINKAGE_H diff --git a/arch/c6x/include/asm/megamod-pic.h b/arch/c6x/include/asm/megamod-pic.h index eca0a8678034..a0a6d596bf9b 100644 --- a/arch/c6x/include/asm/megamod-pic.h +++ b/arch/c6x/include/asm/megamod-pic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _C6X_MEGAMOD_PIC_H #define _C6X_MEGAMOD_PIC_H diff --git a/arch/c6x/include/asm/page.h b/arch/c6x/include/asm/page.h index d18e2b0c7aea..70db1e7632bc 100644 --- a/arch/c6x/include/asm/page.h +++ b/arch/c6x/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_C6X_PAGE_H #define _ASM_C6X_PAGE_H diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h index 7c87b5be53b5..8f7cce829f8e 100644 --- a/arch/c6x/include/asm/processor.h +++ b/arch/c6x/include/asm/processor.h @@ -92,9 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - /* * saved kernel SP and DP of a blocked thread. */ diff --git a/arch/c6x/include/asm/sections.h b/arch/c6x/include/asm/sections.h index f703989d837a..d6c591ab5b7e 100644 --- a/arch/c6x/include/asm/sections.h +++ b/arch/c6x/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_C6X_SECTIONS_H #define _ASM_C6X_SECTIONS_H diff --git a/arch/c6x/include/asm/timer64.h b/arch/c6x/include/asm/timer64.h index bbe27bb9887e..b850dfef1f79 100644 --- a/arch/c6x/include/asm/timer64.h +++ b/arch/c6x/include/asm/timer64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _C6X_TIMER64_H #define _C6X_TIMER64_H diff --git a/arch/c6x/include/asm/tlb.h b/arch/c6x/include/asm/tlb.h index 8709e5e29d2d..34525dea1356 100644 --- a/arch/c6x/include/asm/tlb.h +++ b/arch/c6x/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_C6X_TLB_H #define _ASM_C6X_TLB_H diff --git a/arch/c6x/include/uapi/asm/byteorder.h b/arch/c6x/include/uapi/asm/byteorder.h index 166038db342b..ab61f867391c 100644 --- a/arch/c6x/include/uapi/asm/byteorder.h +++ b/arch/c6x/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_C6X_BYTEORDER_H #define _ASM_C6X_BYTEORDER_H diff --git a/arch/c6x/include/uapi/asm/ptrace.h b/arch/c6x/include/uapi/asm/ptrace.h index cc0a4d99151e..9b51110a0842 100644 --- a/arch/c6x/include/uapi/asm/ptrace.h +++ b/arch/c6x/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) diff --git a/arch/c6x/include/uapi/asm/setup.h b/arch/c6x/include/uapi/asm/setup.h index ad9ac97a8dad..e90548cebec3 100644 --- a/arch/c6x/include/uapi/asm/setup.h +++ b/arch/c6x/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_C6X_SETUP_H #define _UAPI_ASM_C6X_SETUP_H diff --git a/arch/c6x/include/uapi/asm/sigcontext.h b/arch/c6x/include/uapi/asm/sigcontext.h index eb702f39cde7..4e5a9a260861 100644 --- a/arch/c6x/include/uapi/asm/sigcontext.h +++ b/arch/c6x/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Port on Texas Instruments TMS320C6x architecture * diff --git a/arch/c6x/include/uapi/asm/swab.h b/arch/c6x/include/uapi/asm/swab.h index fd4bb0520e5e..c407c0497718 100644 --- a/arch/c6x/include/uapi/asm/swab.h +++ b/arch/c6x/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2011 Texas Instruments Incorporated * Author: Mark Salter diff --git a/arch/c6x/include/uapi/asm/unistd.h b/arch/c6x/include/uapi/asm/unistd.h index 12d73d9d81f5..0d2daf7f9809 100644 --- a/arch/c6x/include/uapi/asm/unistd.h +++ b/arch/c6x/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2011 Texas Instruments Incorporated * diff --git a/arch/c6x/kernel/Makefile b/arch/c6x/kernel/Makefile index 580a515a9443..02f340d7b8fe 100644 --- a/arch/c6x/kernel/Makefile +++ b/arch/c6x/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for arch/c6x/kernel/ # diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c index 60f1e437745d..cff57764fcad 100644 --- a/arch/c6x/kernel/asm-offsets.c +++ b/arch/c6x/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generate definitions needed by assembly language modules. * This code generates raw asm output which is post-processed diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S index 29ebea49ddd5..1fba5b421eee 100644 --- a/arch/c6x/kernel/vmlinux.lds.S +++ b/arch/c6x/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ld script for the c6x kernel * diff --git a/arch/c6x/platforms/Kconfig b/arch/c6x/platforms/Kconfig index c4a0fad89aaf..f3a9ae6e0e82 100644 --- a/arch/c6x/platforms/Kconfig +++ b/arch/c6x/platforms/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config SOC_TMS320C6455 bool "TMS320C6455" diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 71b758dc3a96..54d3f426763b 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config MMU bool default y diff --git a/arch/cris/Kconfig.debug b/arch/cris/Kconfig.debug index 14881e81e8a3..6084d5e0c512 100644 --- a/arch/cris/Kconfig.debug +++ b/arch/cris/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config PROFILING diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig index df9a38b4f18f..d4015a931374 100644 --- a/arch/cris/arch-v10/Kconfig +++ b/arch/cris/arch-v10/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ETRAX_ARCH_V10 menu "CRIS v10 options" diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 239dab0b95c1..8792af63c049 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ETRAX_ARCH_V10 config ETRAX_ETHERNET diff --git a/arch/cris/arch-v10/drivers/Makefile b/arch/cris/arch-v10/drivers/Makefile index e5c13183b97c..d5549dca81bf 100644 --- a/arch/cris/arch-v10/drivers/Makefile +++ b/arch/cris/arch-v10/drivers/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Etrax-specific drivers # diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index 33558d270a53..2d312c8a4dd5 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /*!***************************************************************************** *! *! Implements an interface for i2c compatible eeproms to run under Linux. diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index dfd3b3ba5e4e..68dbe261dc57 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Etrax general port I/O device * diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index b3d1f9ed1b98..ec35d62e8e63 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /*!*************************************************************************** *! *! FILE NAME : i2c.c diff --git a/arch/cris/arch-v10/drivers/i2c.h b/arch/cris/arch-v10/drivers/i2c.h index e36c96276478..de45c1ffbd7b 100644 --- a/arch/cris/arch-v10/drivers/i2c.h +++ b/arch/cris/arch-v10/drivers/i2c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* i2c.h */ int i2c_init(void); diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c index cc62572c1b94..cfe9176f2205 100644 --- a/arch/cris/arch-v10/drivers/sync_serial.c +++ b/arch/cris/arch-v10/drivers/sync_serial.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Simple synchronous serial port driver for ETRAX 100LX. * diff --git a/arch/cris/arch-v10/kernel/Makefile b/arch/cris/arch-v10/kernel/Makefile index 4841e822cdd1..7ec04b4a285e 100644 --- a/arch/cris/arch-v10/kernel/Makefile +++ b/arch/cris/arch-v10/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/cris/arch-v10/kernel/crisksyms.c b/arch/cris/arch-v10/kernel/crisksyms.c index 1ca6fc283232..e1d897ed5b37 100644 --- a/arch/cris/arch-v10/kernel/crisksyms.c +++ b/arch/cris/arch-v10/kernel/crisksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c index b6549e54be29..d30834d4dd7e 100644 --- a/arch/cris/arch-v10/kernel/debugport.c +++ b/arch/cris/arch-v10/kernel/debugport.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Serialport functions for debugging * * Copyright (c) 2000-2007 Axis Communications AB diff --git a/arch/cris/arch-v10/kernel/dma.c b/arch/cris/arch-v10/kernel/dma.c index 5795047359b2..c68e978def05 100644 --- a/arch/cris/arch-v10/kernel/dma.c +++ b/arch/cris/arch-v10/kernel/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Wrapper for DMA channel allocator that updates DMA client muxing. * Copyright 2004-2007, Axis Communications AB */ diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S index b5622521dad5..1f066eebbd2b 100644 --- a/arch/cris/arch-v10/kernel/entry.S +++ b/arch/cris/arch-v10/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/cris/entry.S * diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c index e9298739d72e..94abbff557ff 100644 --- a/arch/cris/arch-v10/kernel/fasttimer.c +++ b/arch/cris/arch-v10/kernel/fasttimer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/fasttimer.c * diff --git a/arch/cris/arch-v10/kernel/head.S b/arch/cris/arch-v10/kernel/head.S index a74aa233b84e..b260a8833903 100644 --- a/arch/cris/arch-v10/kernel/head.S +++ b/arch/cris/arch-v10/kernel/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Head of the kernel - alter with care * diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c index ad64cd1c861a..13a887ce115a 100644 --- a/arch/cris/arch-v10/kernel/io_interface_mux.c +++ b/arch/cris/arch-v10/kernel/io_interface_mux.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* IO interface mux allocator for ETRAX100LX. * Copyright 2004-2007, Axis Communications AB */ diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c index 09cae80a834a..df11e383acdd 100644 --- a/arch/cris/arch-v10/kernel/irq.c +++ b/arch/cris/arch-v10/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/irq.c * diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c index ed71ade93a73..79b13564d15c 100644 --- a/arch/cris/arch-v10/kernel/kgdb.c +++ b/arch/cris/arch-v10/kernel/kgdb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /*!************************************************************************** *! *! FILE NAME : kgdb.c diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index a2cdb1521aca..16848b2c61c8 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/process.c * diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index c2f2b9b83cc4..b89f57ae096e 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2000-2003, Axis Communications AB. */ diff --git a/arch/cris/arch-v10/kernel/setup.c b/arch/cris/arch-v10/kernel/setup.c index 7ab31f1c7540..8e4fc248f96f 100644 --- a/arch/cris/arch-v10/kernel/setup.c +++ b/arch/cris/arch-v10/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * * linux/arch/cris/arch-v10/kernel/setup.c diff --git a/arch/cris/arch-v10/kernel/shadows.c b/arch/cris/arch-v10/kernel/shadows.c index 2454a0b02f54..2e9565e868f2 100644 --- a/arch/cris/arch-v10/kernel/shadows.c +++ b/arch/cris/arch-v10/kernel/shadows.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Various shadow registers. Defines for these are in include/asm-etrax100/io.h */ diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index bab4a8dd6bfd..2beffc37faf8 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/signal.c * diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index b5eb5cd2f60b..3d78373db254 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/arch-v10/kernel/time.c * diff --git a/arch/cris/arch-v10/kernel/traps.c b/arch/cris/arch-v10/kernel/traps.c index c0a501f29bd8..876d45b957f4 100644 --- a/arch/cris/arch-v10/kernel/traps.c +++ b/arch/cris/arch-v10/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Helper functions for trap handlers * diff --git a/arch/cris/arch-v10/lib/checksum.S b/arch/cris/arch-v10/lib/checksum.S index 7d552f4bd5ae..a3b96391706f 100644 --- a/arch/cris/arch-v10/lib/checksum.S +++ b/arch/cris/arch-v10/lib/checksum.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A fast checksum routine using movem * Copyright (c) 1998-2001 Axis Communications AB diff --git a/arch/cris/arch-v10/lib/checksumcopy.S b/arch/cris/arch-v10/lib/checksumcopy.S index 540db8a5f849..b21449cb1ad3 100644 --- a/arch/cris/arch-v10/lib/checksumcopy.S +++ b/arch/cris/arch-v10/lib/checksumcopy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A fast checksum+copy routine using movem * Copyright (c) 1998, 2001 Axis Communications AB diff --git a/arch/cris/arch-v10/lib/csumcpfruser.S b/arch/cris/arch-v10/lib/csumcpfruser.S index 5f41ccd62754..beb8992ed478 100644 --- a/arch/cris/arch-v10/lib/csumcpfruser.S +++ b/arch/cris/arch-v10/lib/csumcpfruser.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Add-on to transform csum_partial_copy_nocheck in checksumcopy.S into * csum_partial_copy_from_user by adding exception records. diff --git a/arch/cris/arch-v10/lib/dram_init.S b/arch/cris/arch-v10/lib/dram_init.S index 93310124333f..fd7437577938 100644 --- a/arch/cris/arch-v10/lib/dram_init.S +++ b/arch/cris/arch-v10/lib/dram_init.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * DRAM/SDRAM initialization - alter with care * This file is intended to be included from other assembler files diff --git a/arch/cris/arch-v10/lib/hw_settings.S b/arch/cris/arch-v10/lib/hw_settings.S index c09f19f478a5..0d449852517e 100644 --- a/arch/cris/arch-v10/lib/hw_settings.S +++ b/arch/cris/arch-v10/lib/hw_settings.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This table is used by some tools to extract hardware parameters. * The table should be included in the kernel and the decompressor. diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c index 48fa37fe0f9b..3f1e2f4680f7 100644 --- a/arch/cris/arch-v10/lib/usercopy.c +++ b/arch/cris/arch-v10/lib/usercopy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * User address space access functions. * The non-inlined parts of asm-cris/uaccess.h are here. diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c index 75210cbe61ce..e6c225169642 100644 --- a/arch/cris/arch-v10/mm/fault.c +++ b/arch/cris/arch-v10/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/mm/fault.c * diff --git a/arch/cris/arch-v10/mm/init.c b/arch/cris/arch-v10/mm/init.c index 85e3f1b1f3ac..4da99a0e3b57 100644 --- a/arch/cris/arch-v10/mm/init.c +++ b/arch/cris/arch-v10/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/arch-v10/mm/init.c * diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c index 3225d38bdaea..7f1f752f2445 100644 --- a/arch/cris/arch-v10/mm/tlb.c +++ b/arch/cris/arch-v10/mm/tlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/arch-v10/mm/tlb.c * diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig index 17dbe03af5f4..958dabfca7eb 100644 --- a/arch/cris/arch-v32/Kconfig +++ b/arch/cris/arch-v32/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ETRAX_ARCH_V32 source arch/cris/arch-v32/mach-fs/Kconfig diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index b7cd6b9209a9..4d2d744bced2 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ETRAX_ARCH_V32 config ETRAX_ETHERNET diff --git a/arch/cris/arch-v32/drivers/Makefile b/arch/cris/arch-v32/drivers/Makefile index b5a75fdce77b..57c9568707b0 100644 --- a/arch/cris/arch-v32/drivers/Makefile +++ b/arch/cris/arch-v32/drivers/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Etrax-specific drivers # diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index 14970f11bbf2..d688fe117dca 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Stream co-processor driver for the ETRAX FS * diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index 3f646c787e58..925a98eb6d68 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index a74540514bdb..53b56a429dde 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c index 394c2a73d5e2..6b9e6cfaa29e 100644 --- a/arch/cris/arch-v32/drivers/pci/bios.c +++ b/arch/cris/arch-v32/drivers/pci/bios.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include -void pcibios_fixup_bus(struct pci_bus *b) -{ -} - void pcibios_set_master(struct pci_dev *dev) { u8 lat; diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c index 7072341995ff..dbbd3816cc0b 100644 --- a/arch/cris/arch-v32/drivers/pci/dma.c +++ b/arch/cris/arch-v32/drivers/pci/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Dynamic DMA mapping support. * diff --git a/arch/cris/arch-v32/kernel/Makefile b/arch/cris/arch-v32/kernel/Makefile index d9fc617ea253..2db7e4f7c1fa 100644 --- a/arch/cris/arch-v32/kernel/Makefile +++ b/arch/cris/arch-v32/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/cris/arch-v32/kernel/cache.c b/arch/cris/arch-v32/kernel/cache.c index f38433b1f861..a080d2fa4803 100644 --- a/arch/cris/arch-v32/kernel/cache.c +++ b/arch/cris/arch-v32/kernel/cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/arch-v32/kernel/cacheflush.S b/arch/cris/arch-v32/kernel/cacheflush.S index 6fc3d95d7029..2a54d793f96c 100644 --- a/arch/cris/arch-v32/kernel/cacheflush.S +++ b/arch/cris/arch-v32/kernel/cacheflush.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .global cris_flush_cache_range .type cris_flush_cache_range, @function cris_flush_cache_range: diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c index b0566350a840..8cc8ad1cb532 100644 --- a/arch/cris/arch-v32/kernel/crisksyms.c +++ b/arch/cris/arch-v32/kernel/crisksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c index d2f3f9c37102..69247fd2090a 100644 --- a/arch/cris/arch-v32/kernel/debugport.c +++ b/arch/cris/arch-v32/kernel/debugport.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2003, Axis Communications AB. */ diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index b17a20999f87..0793a52b2c34 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2000-2003 Axis Communications AB * diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c index eb4e0ff36295..7452c70f61ff 100644 --- a/arch/cris/arch-v32/kernel/fasttimer.c +++ b/arch/cris/arch-v32/kernel/fasttimer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/fasttimer.c * diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S index 5ce83eb54f58..92f9fb1f6845 100644 --- a/arch/cris/arch-v32/kernel/head.S +++ b/arch/cris/arch-v32/kernel/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * CRISv32 kernel startup code. * diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index b07da4b695aa..414afd543232 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2003, Axis Communications AB. */ diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c index e0fdea706eca..3d6f516763a5 100644 --- a/arch/cris/arch-v32/kernel/kgdb.c +++ b/arch/cris/arch-v32/kernel/kgdb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/cris/arch-v32/kernel/kgdb.c * diff --git a/arch/cris/arch-v32/kernel/kgdb_asm.S b/arch/cris/arch-v32/kernel/kgdb_asm.S index f3a47605902a..c26ea6b0e334 100644 --- a/arch/cris/arch-v32/kernel/kgdb_asm.S +++ b/arch/cris/arch-v32/kernel/kgdb_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2004 Axis Communications AB * diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index fe87b383fbf3..a02f276d0ed4 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2000-2003 Axis Communications AB * diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c index 0461e95bbb62..ccac1aaadc8a 100644 --- a/arch/cris/arch-v32/kernel/ptrace.c +++ b/arch/cris/arch-v32/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2000-2007, Axis Communications AB. */ diff --git a/arch/cris/arch-v32/kernel/setup.c b/arch/cris/arch-v32/kernel/setup.c index fe50287aa928..a36372e35e96 100644 --- a/arch/cris/arch-v32/kernel/setup.c +++ b/arch/cris/arch-v32/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Display CPU info in /proc/cpuinfo. * diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index ea2e8e1398e8..4f2e3ba3bf40 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2003, Axis Communications AB. */ diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index d2a84407654a..d07a3912687e 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/arch-v32/kernel/time.c * diff --git a/arch/cris/arch-v32/kernel/traps.c b/arch/cris/arch-v32/kernel/traps.c index a34256515036..ba54c7eccbaa 100644 --- a/arch/cris/arch-v32/kernel/traps.c +++ b/arch/cris/arch-v32/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2003-2006, Axis Communications AB. */ diff --git a/arch/cris/arch-v32/lib/checksum.S b/arch/cris/arch-v32/lib/checksum.S index 4a72a94a49ad..f773d4d93609 100644 --- a/arch/cris/arch-v32/lib/checksum.S +++ b/arch/cris/arch-v32/lib/checksum.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A fast checksum routine using movem * Copyright (c) 1998-2007 Axis Communications AB diff --git a/arch/cris/arch-v32/lib/checksumcopy.S b/arch/cris/arch-v32/lib/checksumcopy.S index 54e209f18b06..a76e586d4114 100644 --- a/arch/cris/arch-v32/lib/checksumcopy.S +++ b/arch/cris/arch-v32/lib/checksumcopy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A fast checksum+copy routine using movem * Copyright (c) 1998-2007 Axis Communications AB diff --git a/arch/cris/arch-v32/lib/csumcpfruser.S b/arch/cris/arch-v32/lib/csumcpfruser.S index 600ec16b9f28..093cd757fcfa 100644 --- a/arch/cris/arch-v32/lib/csumcpfruser.S +++ b/arch/cris/arch-v32/lib/csumcpfruser.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Add-on to transform csum_partial_copy_nocheck in checksumcopy.S into * csum_partial_copy_from_user by adding exception records. diff --git a/arch/cris/arch-v32/lib/delay.c b/arch/cris/arch-v32/lib/delay.c index 39f1ac9995b4..db06a94ef646 100644 --- a/arch/cris/arch-v32/lib/delay.c +++ b/arch/cris/arch-v32/lib/delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Precise Delay Loops for ETRAX FS * diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c index 20b608026913..04e78b6ffa22 100644 --- a/arch/cris/arch-v32/lib/usercopy.c +++ b/arch/cris/arch-v32/lib/usercopy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * User address space access functions. * The non-inlined parts of asm-cris/uaccess.h are here. diff --git a/arch/cris/arch-v32/mach-a3/Kconfig b/arch/cris/arch-v32/mach-a3/Kconfig index 87547271a595..7b63755544dd 100644 --- a/arch/cris/arch-v32/mach-a3/Kconfig +++ b/arch/cris/arch-v32/mach-a3/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if CRIS_MACH_ARTPEC3 menu "Artpec-3 options" diff --git a/arch/cris/arch-v32/mach-a3/arbiter.c b/arch/cris/arch-v32/mach-a3/arbiter.c index ab5c421a4de8..076182cc65a3 100644 --- a/arch/cris/arch-v32/mach-a3/arbiter.c +++ b/arch/cris/arch-v32/mach-a3/arbiter.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Memory arbiter functions. Allocates bandwidth through the * arbiter and sets up arbiter breakpoints. @@ -227,7 +228,7 @@ static void crisv32_arbiter_config(int arbiter, int region, int unused_slots) } } -extern char _stext, _etext; +extern char _stext[], _etext[]; static void crisv32_arbiter_init(void) { @@ -265,7 +266,7 @@ static void crisv32_arbiter_init(void) #ifndef CONFIG_ETRAX_KGDB /* Global watch for writes to kernel text segment. */ - crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext, + crisv32_arbiter_watch(virt_to_phys(_stext), _etext - _stext, MARB_CLIENTS(arbiter_all_clients, arbiter_bar_all_clients), arbiter_all_write, NULL); #endif diff --git a/arch/cris/arch-v32/mach-a3/dma.c b/arch/cris/arch-v32/mach-a3/dma.c index 11f417f4da98..3f4e923b2527 100644 --- a/arch/cris/arch-v32/mach-a3/dma.c +++ b/arch/cris/arch-v32/mach-a3/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Wrapper for DMA channel allocator that starts clocks etc */ #include diff --git a/arch/cris/arch-v32/mach-a3/dram_init.S b/arch/cris/arch-v32/mach-a3/dram_init.S index 7dc26bdb26b5..733c3564ad79 100644 --- a/arch/cris/arch-v32/mach-a3/dram_init.S +++ b/arch/cris/arch-v32/mach-a3/dram_init.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * DDR SDRAM initialization - alter with care * This file is intended to be included from other assembler files diff --git a/arch/cris/arch-v32/mach-a3/hw_settings.S b/arch/cris/arch-v32/mach-a3/hw_settings.S index 0145725a1ce5..7c325cc59e1f 100644 --- a/arch/cris/arch-v32/mach-a3/hw_settings.S +++ b/arch/cris/arch-v32/mach-a3/hw_settings.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This table is used by some tools to extract hardware parameters. * The table should be included in the kernel and the decompressor. diff --git a/arch/cris/arch-v32/mach-a3/pinmux.c b/arch/cris/arch-v32/mach-a3/pinmux.c index 591f77526746..4875bf7aa53f 100644 --- a/arch/cris/arch-v32/mach-a3/pinmux.c +++ b/arch/cris/arch-v32/mach-a3/pinmux.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Allocator for I/O pins. All pins are allocated to GPIO at bootup. * Unassigned pins and GPIO pins can be allocated to a fixed interface diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig index 7d1ab972bc0f..743ba3bcbaec 100644 --- a/arch/cris/arch-v32/mach-fs/Kconfig +++ b/arch/cris/arch-v32/mach-fs/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ETRAXFS menu "ETRAX FS options" diff --git a/arch/cris/arch-v32/mach-fs/arbiter.c b/arch/cris/arch-v32/mach-fs/arbiter.c index c97f4d8120f9..c4750d97e46c 100644 --- a/arch/cris/arch-v32/mach-fs/arbiter.c +++ b/arch/cris/arch-v32/mach-fs/arbiter.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Memory arbiter functions. Allocates bandwidth through the * arbiter and sets up arbiter breakpoints. @@ -158,7 +159,7 @@ static void crisv32_arbiter_config(int region, int unused_slots) } } -extern char _stext, _etext; +extern char _stext[], _etext[]; static void crisv32_arbiter_init(void) { @@ -190,7 +191,7 @@ static void crisv32_arbiter_init(void) #ifndef CONFIG_ETRAX_KGDB /* Global watch for writes to kernel text segment. */ - crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext, + crisv32_arbiter_watch(virt_to_phys(_stext), _etext - _stext, arbiter_all_clients, arbiter_all_write, NULL); #endif } diff --git a/arch/cris/arch-v32/mach-fs/dma.c b/arch/cris/arch-v32/mach-fs/dma.c index 7c93679c02ad..c0347a4f8c65 100644 --- a/arch/cris/arch-v32/mach-fs/dma.c +++ b/arch/cris/arch-v32/mach-fs/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Wrapper for DMA channel allocator that starts clocks etc */ #include diff --git a/arch/cris/arch-v32/mach-fs/dram_init.S b/arch/cris/arch-v32/mach-fs/dram_init.S index 2ed51e247e8f..e1a01fa4c272 100644 --- a/arch/cris/arch-v32/mach-fs/dram_init.S +++ b/arch/cris/arch-v32/mach-fs/dram_init.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * DRAM/SDRAM initialization - alter with care * This file is intended to be included from other assembler files diff --git a/arch/cris/arch-v32/mach-fs/hw_settings.S b/arch/cris/arch-v32/mach-fs/hw_settings.S index 8bde93c36214..7fbadcc48c0c 100644 --- a/arch/cris/arch-v32/mach-fs/hw_settings.S +++ b/arch/cris/arch-v32/mach-fs/hw_settings.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This table is used by some tools to extract hardware parameters. * The table should be included in the kernel and the decompressor. diff --git a/arch/cris/arch-v32/mach-fs/pinmux.c b/arch/cris/arch-v32/mach-fs/pinmux.c index d8a3a3c439dd..a0b2f101003a 100644 --- a/arch/cris/arch-v32/mach-fs/pinmux.c +++ b/arch/cris/arch-v32/mach-fs/pinmux.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Allocator for I/O pins. All pins are allocated to GPIO at bootup. * Unassigned pins and GPIO pins can be allocated to a fixed interface diff --git a/arch/cris/arch-v32/mm/init.c b/arch/cris/arch-v32/mm/init.c index f5438ca8122d..784876afa001 100644 --- a/arch/cris/arch-v32/mm/init.c +++ b/arch/cris/arch-v32/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Set up paging and the MMU. * diff --git a/arch/cris/arch-v32/mm/intmem.c b/arch/cris/arch-v32/mm/intmem.c index c80728401487..928b94d1d320 100644 --- a/arch/cris/arch-v32/mm/intmem.c +++ b/arch/cris/arch-v32/mm/intmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Simple allocator for internal RAM in ETRAX FS * diff --git a/arch/cris/arch-v32/mm/l2cache.c b/arch/cris/arch-v32/mm/l2cache.c index 332ff10dcc6b..4fef321d5606 100644 --- a/arch/cris/arch-v32/mm/l2cache.c +++ b/arch/cris/arch-v32/mm/l2cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/arch-v32/mm/mmu.S b/arch/cris/arch-v32/mm/mmu.S index c0981044eccb..f24965703f6d 100644 --- a/arch/cris/arch-v32/mm/mmu.S +++ b/arch/cris/arch-v32/mm/mmu.S @@ -1,3 +1,4 @@ +; SPDX-License-Identifier: GPL-2.0 ; WARNING : The refill handler has been modified, see below !!! /* diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c index bc3de5b5e27c..9e4b5ab4971d 100644 --- a/arch/cris/arch-v32/mm/tlb.c +++ b/arch/cris/arch-v32/mm/tlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Low level TLB handling. * diff --git a/arch/cris/boot/Makefile b/arch/cris/boot/Makefile index 6e3b509fd7fc..859d275f862b 100644 --- a/arch/cris/boot/Makefile +++ b/arch/cris/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/cris/boot/Makefile # diff --git a/arch/cris/boot/compressed/Makefile b/arch/cris/boot/compressed/Makefile index e4ba0be0e782..e149c3467c93 100644 --- a/arch/cris/boot/compressed/Makefile +++ b/arch/cris/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/cris/boot/compressed/Makefile # diff --git a/arch/cris/boot/compressed/decompress_v10.lds b/arch/cris/boot/compressed/decompress_v10.lds index e80f4594d543..d8326779dda2 100644 --- a/arch/cris/boot/compressed/decompress_v10.lds +++ b/arch/cris/boot/compressed/decompress_v10.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* OUTPUT_FORMAT(elf32-us-cris) */ OUTPUT_FORMAT(elf32-cris) diff --git a/arch/cris/boot/compressed/decompress_v32.lds b/arch/cris/boot/compressed/decompress_v32.lds index 3c837feca3ac..91d311c243ed 100644 --- a/arch/cris/boot/compressed/decompress_v32.lds +++ b/arch/cris/boot/compressed/decompress_v32.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*#OUTPUT_FORMAT(elf32-us-cris) */ OUTPUT_ARCH (crisv32) diff --git a/arch/cris/boot/compressed/head_v10.S b/arch/cris/boot/compressed/head_v10.S index 9edb8ade7e1f..08198d8cd37f 100644 --- a/arch/cris/boot/compressed/head_v10.S +++ b/arch/cris/boot/compressed/head_v10.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/cris/boot/compressed/head.S * diff --git a/arch/cris/boot/compressed/head_v32.S b/arch/cris/boot/compressed/head_v32.S index f483005f3d48..a997947d31e3 100644 --- a/arch/cris/boot/compressed/head_v32.S +++ b/arch/cris/boot/compressed/head_v32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Code that sets up the DRAM registers, calls the * decompressor to unpack the piggybacked kernel, and jumps. diff --git a/arch/cris/boot/compressed/misc.c b/arch/cris/boot/compressed/misc.c index 548d886b03d3..1ad464a117b8 100644 --- a/arch/cris/boot/compressed/misc.c +++ b/arch/cris/boot/compressed/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * misc.c * diff --git a/arch/cris/boot/dts/Makefile b/arch/cris/boot/dts/Makefile index faf69fb9919f..3318c630caa2 100644 --- a/arch/cris/boot/dts/Makefile +++ b/arch/cris/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o ifneq ($(CONFIG_BUILTIN_DTB),"") obj-$(CONFIG_OF) += $(BUILTIN_DTB) diff --git a/arch/cris/boot/dts/artpec3.dtsi b/arch/cris/boot/dts/artpec3.dtsi index be15be67b653..f857300f4edd 100644 --- a/arch/cris/boot/dts/artpec3.dtsi +++ b/arch/cris/boot/dts/artpec3.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/cris/boot/dts/dev88.dts b/arch/cris/boot/dts/dev88.dts index b9a230d10874..415270ea5309 100644 --- a/arch/cris/boot/dts/dev88.dts +++ b/arch/cris/boot/dts/dev88.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/cris/boot/dts/etraxfs.dtsi b/arch/cris/boot/dts/etraxfs.dtsi index bf1b8582d4d8..4513edf72545 100644 --- a/arch/cris/boot/dts/etraxfs.dtsi +++ b/arch/cris/boot/dts/etraxfs.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/cris/boot/dts/p1343.dts b/arch/cris/boot/dts/p1343.dts index fab7bdbd0f15..6030561d4574 100644 --- a/arch/cris/boot/dts/p1343.dts +++ b/arch/cris/boot/dts/p1343.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/cris/boot/rescue/Makefile b/arch/cris/boot/rescue/Makefile index a82025940006..f73ac4c83b96 100644 --- a/arch/cris/boot/rescue/Makefile +++ b/arch/cris/boot/rescue/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for rescue (bootstrap) code # diff --git a/arch/cris/boot/rescue/head_v10.S b/arch/cris/boot/rescue/head_v10.S index 1c05492f3eb2..11eedb1bf31a 100644 --- a/arch/cris/boot/rescue/head_v10.S +++ b/arch/cris/boot/rescue/head_v10.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Rescue code, made to reside at the beginning of the * flash-memory. when it starts, it checks a partition diff --git a/arch/cris/boot/rescue/head_v32.S b/arch/cris/boot/rescue/head_v32.S index 5f846b7700a3..9eb04abaa0c0 100644 --- a/arch/cris/boot/rescue/head_v32.S +++ b/arch/cris/boot/rescue/head_v32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Just get started by jumping to CONFIG_ETRAX_PTABLE_SECTOR to start * kernel decompressor. diff --git a/arch/cris/boot/rescue/kimagerescue.S b/arch/cris/boot/rescue/kimagerescue.S index 655b511fecf3..3306098dee15 100644 --- a/arch/cris/boot/rescue/kimagerescue.S +++ b/arch/cris/boot/rescue/kimagerescue.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Rescue code to be prepended on a kimage and copied to the * rescue serial port. diff --git a/arch/cris/boot/rescue/rescue_v10.lds b/arch/cris/boot/rescue/rescue_v10.lds index 0b52a9490db6..e58a53f91728 100644 --- a/arch/cris/boot/rescue/rescue_v10.lds +++ b/arch/cris/boot/rescue/rescue_v10.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ MEMORY { flash : ORIGIN = 0x00000000, diff --git a/arch/cris/boot/rescue/rescue_v32.lds b/arch/cris/boot/rescue/rescue_v32.lds index 8ac646bc1a2b..f1542183f263 100644 --- a/arch/cris/boot/rescue/rescue_v32.lds +++ b/arch/cris/boot/rescue/rescue_v32.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*#OUTPUT_FORMAT(elf32-us-cris) */ OUTPUT_ARCH (crisv32) /* Now that NAND support has been stripped, this file could be simplified, diff --git a/arch/cris/boot/rescue/testrescue.S b/arch/cris/boot/rescue/testrescue.S index fc7ec674eca5..06f78a0b0622 100644 --- a/arch/cris/boot/rescue/testrescue.S +++ b/arch/cris/boot/rescue/testrescue.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Simple testcode to download by the rescue block. * Just lights some LEDs to show it was downloaded correctly. diff --git a/arch/cris/boot/tools/build.c b/arch/cris/boot/tools/build.c index c8adef364160..3ae485049779 100644 --- a/arch/cris/boot/tools/build.c +++ b/arch/cris/boot/tools/build.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/tools/build.c * diff --git a/arch/cris/include/arch-v10/arch/bitops.h b/arch/cris/include/arch-v10/arch/bitops.h index 03d9cfd92c8a..c18f81858899 100644 --- a/arch/cris/include/arch-v10/arch/bitops.h +++ b/arch/cris/include/arch-v10/arch/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* asm/arch/bitops.h for Linux/CRISv10 */ #ifndef _CRIS_ARCH_BITOPS_H diff --git a/arch/cris/include/arch-v10/arch/bug.h b/arch/cris/include/arch-v10/arch/bug.h index 3485d6b34bb0..905afeacfedf 100644 --- a/arch/cris/include/arch-v10/arch/bug.h +++ b/arch/cris/include/arch-v10/arch/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRISv10_ARCH_BUG_H #define __ASM_CRISv10_ARCH_BUG_H diff --git a/arch/cris/include/arch-v10/arch/cache.h b/arch/cris/include/arch-v10/arch/cache.h index aea27184d2d2..d4049bcab3c5 100644 --- a/arch/cris/include/arch-v10/arch/cache.h +++ b/arch/cris/include/arch-v10/arch/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_CACHE_H #define _ASM_ARCH_CACHE_H diff --git a/arch/cris/include/arch-v10/arch/checksum.h b/arch/cris/include/arch-v10/arch/checksum.h index d1d1bd9e1090..eb186be4fb32 100644 --- a/arch/cris/include/arch-v10/arch/checksum.h +++ b/arch/cris/include/arch-v10/arch/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_ARCH_CHECKSUM_H #define _CRIS_ARCH_CHECKSUM_H diff --git a/arch/cris/include/arch-v10/arch/delay.h b/arch/cris/include/arch-v10/arch/delay.h index 39481f6e0c30..a57d2cc0baf7 100644 --- a/arch/cris/include/arch-v10/arch/delay.h +++ b/arch/cris/include/arch-v10/arch/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_ARCH_DELAY_H #define _CRIS_ARCH_DELAY_H diff --git a/arch/cris/include/arch-v10/arch/dma.h b/arch/cris/include/arch-v10/arch/dma.h index ecb9dba6fa4f..ea794a32cf5e 100644 --- a/arch/cris/include/arch-v10/arch/dma.h +++ b/arch/cris/include/arch-v10/arch/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Defines for using and allocating dma channels. */ #ifndef _ASM_ARCH_DMA_H diff --git a/arch/cris/include/arch-v10/arch/io.h b/arch/cris/include/arch-v10/arch/io.h index 4a724172877f..bae5f77cfabc 100644 --- a/arch/cris/include/arch-v10/arch/io.h +++ b/arch/cris/include/arch-v10/arch/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_CRIS_IO_H #define _ASM_ARCH_CRIS_IO_H diff --git a/arch/cris/include/arch-v10/arch/io_interface_mux.h b/arch/cris/include/arch-v10/arch/io_interface_mux.h index d92500080883..2d5617e67ab0 100644 --- a/arch/cris/include/arch-v10/arch/io_interface_mux.h +++ b/arch/cris/include/arch-v10/arch/io_interface_mux.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* IO interface mux allocator for ETRAX100LX. * Copyright 2004, Axis Communications AB * $Id: io_interface_mux.h,v 1.1 2004/12/13 12:21:53 starvik Exp $ diff --git a/arch/cris/include/arch-v10/arch/irq.h b/arch/cris/include/arch-v10/arch/irq.h index 6aecb835037d..c4e8a78e33d1 100644 --- a/arch/cris/include/arch-v10/arch/irq.h +++ b/arch/cris/include/arch-v10/arch/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Interrupt handling assembler and defines for Linux/CRISv10 */ diff --git a/arch/cris/include/arch-v10/arch/irqflags.h b/arch/cris/include/arch-v10/arch/irqflags.h index 75ef18991240..9959b0a8a58c 100644 --- a/arch/cris/include/arch-v10/arch/irqflags.h +++ b/arch/cris/include/arch-v10/arch/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRIS_ARCH_IRQFLAGS_H #define __ASM_CRIS_ARCH_IRQFLAGS_H diff --git a/arch/cris/include/arch-v10/arch/memmap.h b/arch/cris/include/arch-v10/arch/memmap.h index 13f3b971407f..b6b171f48b29 100644 --- a/arch/cris/include/arch-v10/arch/memmap.h +++ b/arch/cris/include/arch-v10/arch/memmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_MEMMAP_H #define _ASM_ARCH_MEMMAP_H diff --git a/arch/cris/include/arch-v10/arch/mmu.h b/arch/cris/include/arch-v10/arch/mmu.h index 47a5dd21749d..74c53048be79 100644 --- a/arch/cris/include/arch-v10/arch/mmu.h +++ b/arch/cris/include/arch-v10/arch/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * CRIS MMU constants and PTE layout */ diff --git a/arch/cris/include/arch-v10/arch/offset.h b/arch/cris/include/arch-v10/arch/offset.h index 675b51d85639..6f0f2b4a163f 100644 --- a/arch/cris/include/arch-v10/arch/offset.h +++ b/arch/cris/include/arch-v10/arch/offset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_OFFSETS_H__ #define __ASM_OFFSETS_H__ /* diff --git a/arch/cris/include/arch-v10/arch/page.h b/arch/cris/include/arch-v10/arch/page.h index ffafc99c3472..a4bbff64868c 100644 --- a/arch/cris/include/arch-v10/arch/page.h +++ b/arch/cris/include/arch-v10/arch/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_ARCH_PAGE_H #define _CRIS_ARCH_PAGE_H diff --git a/arch/cris/include/arch-v10/arch/pgtable.h b/arch/cris/include/arch-v10/arch/pgtable.h index 2a2576d1fc97..a61532d06acb 100644 --- a/arch/cris/include/arch-v10/arch/pgtable.h +++ b/arch/cris/include/arch-v10/arch/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_ARCH_PGTABLE_H #define _CRIS_ARCH_PGTABLE_H diff --git a/arch/cris/include/arch-v10/arch/processor.h b/arch/cris/include/arch-v10/arch/processor.h index 93feb2a487d8..b2df646bc1eb 100644 --- a/arch/cris/include/arch-v10/arch/processor.h +++ b/arch/cris/include/arch-v10/arch/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRIS_ARCH_PROCESSOR_H #define __ASM_CRIS_ARCH_PROCESSOR_H diff --git a/arch/cris/include/arch-v10/arch/swab.h b/arch/cris/include/arch-v10/arch/swab.h index e4e847d8a05e..8cc27dfb9d3a 100644 --- a/arch/cris/include/arch-v10/arch/swab.h +++ b/arch/cris/include/arch-v10/arch/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_ARCH_SWAB_H #define _CRIS_ARCH_SWAB_H diff --git a/arch/cris/include/arch-v10/arch/system.h b/arch/cris/include/arch-v10/arch/system.h index 9b5580f58b96..4c63f728122b 100644 --- a/arch/cris/include/arch-v10/arch/system.h +++ b/arch/cris/include/arch-v10/arch/system.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRIS_ARCH_SYSTEM_H #define __ASM_CRIS_ARCH_SYSTEM_H diff --git a/arch/cris/include/arch-v10/arch/thread_info.h b/arch/cris/include/arch-v10/arch/thread_info.h index 218f4152d3e5..0ef1223998c1 100644 --- a/arch/cris/include/arch-v10/arch/thread_info.h +++ b/arch/cris/include/arch-v10/arch/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_THREAD_INFO_H #define _ASM_ARCH_THREAD_INFO_H diff --git a/arch/cris/include/arch-v10/arch/timex.h b/arch/cris/include/arch-v10/arch/timex.h index e48447d94faf..9c9583e5aed6 100644 --- a/arch/cris/include/arch-v10/arch/timex.h +++ b/arch/cris/include/arch-v10/arch/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Use prescale timer at 25000 Hz instead of the baudrate timer at * 19200 to get rid of the 64ppm to fast timer (and we get better diff --git a/arch/cris/include/arch-v10/arch/tlb.h b/arch/cris/include/arch-v10/arch/tlb.h index 31525bbe75c3..9f039d83f21b 100644 --- a/arch/cris/include/arch-v10/arch/tlb.h +++ b/arch/cris/include/arch-v10/arch/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_ARCH_TLB_H #define _CRIS_ARCH_TLB_H diff --git a/arch/cris/include/arch-v10/arch/uaccess.h b/arch/cris/include/arch-v10/arch/uaccess.h index 5477c98c2281..8d033c534f1f 100644 --- a/arch/cris/include/arch-v10/arch/uaccess.h +++ b/arch/cris/include/arch-v10/arch/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Authors: Bjorn Wesen (bjornw@axis.com) * Hans-Peter Nilsson (hp@axis.com) diff --git a/arch/cris/include/arch-v10/arch/unistd.h b/arch/cris/include/arch-v10/arch/unistd.h index d1a38b9e6264..03cd0b8652f4 100644 --- a/arch/cris/include/arch-v10/arch/unistd.h +++ b/arch/cris/include/arch-v10/arch/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_UNISTD_H_ #define _ASM_CRIS_ARCH_UNISTD_H_ diff --git a/arch/cris/include/arch-v32/arch/bitops.h b/arch/cris/include/arch-v32/arch/bitops.h index 147689d6b624..7df94798f063 100644 --- a/arch/cris/include/arch-v32/arch/bitops.h +++ b/arch/cris/include/arch-v32/arch/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_BITOPS_H #define _ASM_CRIS_ARCH_BITOPS_H diff --git a/arch/cris/include/arch-v32/arch/bug.h b/arch/cris/include/arch-v32/arch/bug.h index fb59faaaae0a..982c6b08fdf1 100644 --- a/arch/cris/include/arch-v32/arch/bug.h +++ b/arch/cris/include/arch-v32/arch/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRISv32_ARCH_BUG_H #define __ASM_CRISv32_ARCH_BUG_H diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h index 7caf25d58e6b..f61f3088c45b 100644 --- a/arch/cris/include/arch-v32/arch/cache.h +++ b/arch/cris/include/arch-v32/arch/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_CACHE_H #define _ASM_CRIS_ARCH_CACHE_H diff --git a/arch/cris/include/arch-v32/arch/checksum.h b/arch/cris/include/arch-v32/arch/checksum.h index 65cf205b1329..fea1341ef244 100644 --- a/arch/cris/include/arch-v32/arch/checksum.h +++ b/arch/cris/include/arch-v32/arch/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_CHECKSUM_H #define _ASM_CRIS_ARCH_CHECKSUM_H diff --git a/arch/cris/include/arch-v32/arch/cryptocop.h b/arch/cris/include/arch-v32/arch/cryptocop.h index a56ac61a9931..f2f8eda1ffb1 100644 --- a/arch/cris/include/arch-v32/arch/cryptocop.h +++ b/arch/cris/include/arch-v32/arch/cryptocop.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * The device /dev/cryptocop is accessible using this driver using * CRYPTOCOP_MAJOR (254) and minor number 0. diff --git a/arch/cris/include/arch-v32/arch/delay.h b/arch/cris/include/arch-v32/arch/delay.h index e9fda03810a9..94307c1fbb1c 100644 --- a/arch/cris/include/arch-v32/arch/delay.h +++ b/arch/cris/include/arch-v32/arch/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_DELAY_H #define _ASM_CRIS_ARCH_DELAY_H diff --git a/arch/cris/include/arch-v32/arch/hwregs/Makefile b/arch/cris/include/arch-v32/arch/hwregs/Makefile index b8b3f8d666e4..bb5ffa7ff9f4 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/Makefile +++ b/arch/cris/include/arch-v32/arch/hwregs/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile to generate or copy the latest register definitions # and related datastructures and helpermacros. # The official place for these files is at: diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/ata_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/ata_defs_asm.h index 866191418f9c..6886ba3c2d53 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/ata_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/ata_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ata_defs_asm_h #define __ata_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/bif_core_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/bif_core_defs_asm.h index c686cb335621..1d75d8c31cc0 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/bif_core_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/bif_core_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_core_defs_asm_h #define __bif_core_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/bif_dma_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/bif_dma_defs_asm.h index 71532aa18168..a07447fa75f8 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/bif_dma_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/bif_dma_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_dma_defs_asm_h #define __bif_dma_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/bif_slave_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/bif_slave_defs_asm.h index 031f33a365bb..55697fec603e 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/bif_slave_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/bif_slave_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_slave_defs_asm_h #define __bif_slave_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/config_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/config_defs_asm.h index e98476332e1f..6455b4897bcc 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/config_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/config_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __config_defs_asm_h #define __config_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/cris_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/cris_defs_asm.h index 7f768db272e2..bd048296d2f8 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/cris_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/cris_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __cris_defs_asm_h #define __cris_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/cris_supp_reg.h b/arch/cris/include/arch-v32/arch/hwregs/asm/cris_supp_reg.h index 7d3689a6f80d..429fe0d4ffe4 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/cris_supp_reg.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/cris_supp_reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define RW_GC_CFG 0 #define RW_GC_CCS 1 #define RW_GC_SRS 2 diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/dma_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/dma_defs_asm.h index 0cb71bc127ae..fec451d2a3db 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/dma_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/dma_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __dma_defs_asm_h #define __dma_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/eth_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/eth_defs_asm.h index c9f49864831b..97fe523d4d72 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/eth_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/eth_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __eth_defs_asm_h #define __eth_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/gio_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/gio_defs_asm.h index 35356bc08629..41bc2f83795c 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/gio_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/gio_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __gio_defs_asm_h #define __gio_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect.h b/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect.h index c8315905c571..e371052fa1bc 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Interrupt vector numbers autogenerated by /n/asic/design/tools/rdesc/src/rdes2intr version from ../../inst/intr_vect/rtl/guinness/ivmask.config.r version . */ diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect_defs_asm.h index 6df2a433b02d..8d0c788b286b 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/intr_vect_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __intr_vect_defs_asm_h #define __intr_vect_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/irq_nmi_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/irq_nmi_defs_asm.h index 0c8084054840..f624468346af 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/irq_nmi_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/irq_nmi_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __irq_nmi_defs_asm_h #define __irq_nmi_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/marb_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/marb_defs_asm.h index 45400eb8d389..6a5ce2141860 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/marb_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/marb_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __marb_defs_asm_h #define __marb_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_defs_asm.h index 505b7a16d878..083174678961 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __mmu_defs_asm_h #define __mmu_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_supp_reg.h b/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_supp_reg.h index 339500bf3bc0..fd66daa79259 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_supp_reg.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/mmu_supp_reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define RW_MM_CFG 0 #define RW_MM_KBASE_LO 1 #define RW_MM_KBASE_HI 2 diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/rt_trace_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/rt_trace_defs_asm.h index 10246f49fb28..72b3d231d80f 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/rt_trace_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/rt_trace_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __rt_trace_defs_asm_h #define __rt_trace_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/ser_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/ser_defs_asm.h index 4a2808bdf390..944f4c7666b4 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/ser_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/ser_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ser_defs_asm_h #define __ser_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/sser_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/sser_defs_asm.h index 27d4d91b3abd..607b505100fa 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/sser_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/sser_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __sser_defs_asm_h #define __sser_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/strcop_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/strcop_defs_asm.h index 55083e6aec93..fab117b00ab6 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/strcop_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/strcop_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __strcop_defs_asm_h #define __strcop_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/strmux_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/strmux_defs_asm.h index 69b299920f71..73755fa8a526 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/strmux_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/strmux_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __strmux_defs_asm_h #define __strmux_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/asm/timer_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/asm/timer_defs_asm.h index 43146021fc16..cc67986d7437 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/asm/timer_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/asm/timer_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __timer_defs_asm_h #define __timer_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/ata_defs.h b/arch/cris/include/arch-v32/arch/hwregs/ata_defs.h index 43b6643ff0d3..2a8adbcf75d8 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/ata_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/ata_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ata_defs_h #define __ata_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/bif_core_defs.h b/arch/cris/include/arch-v32/arch/hwregs/bif_core_defs.h index a56608b50359..054841c45466 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/bif_core_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/bif_core_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_core_defs_h #define __bif_core_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/bif_dma_defs.h b/arch/cris/include/arch-v32/arch/hwregs/bif_dma_defs.h index b931c1aab679..5c4abf5c0167 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/bif_dma_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/bif_dma_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_dma_defs_h #define __bif_dma_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/bif_slave_defs.h b/arch/cris/include/arch-v32/arch/hwregs/bif_slave_defs.h index d18fc3c9f569..80c740b3c785 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/bif_slave_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/bif_slave_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_slave_defs_h #define __bif_slave_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/config_defs.h b/arch/cris/include/arch-v32/arch/hwregs/config_defs.h index 45457a4e3817..1c5da14f27f3 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/config_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/config_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __config_defs_h #define __config_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/cpu_vect.h b/arch/cris/include/arch-v32/arch/hwregs/cpu_vect.h index 8370aee8a14a..913f918bba14 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/cpu_vect.h +++ b/arch/cris/include/arch-v32/arch/hwregs/cpu_vect.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Interrupt vector numbers autogenerated by /n/asic/design/tools/rdesc/src/rdes2intr version from ../../inst/crisp/doc/cpu_vect.r version . */ diff --git a/arch/cris/include/arch-v32/arch/hwregs/dma.h b/arch/cris/include/arch-v32/arch/hwregs/dma.h index 52bf67907f28..dd24c6da09e0 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/dma.h +++ b/arch/cris/include/arch-v32/arch/hwregs/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * DMA C definitions and help macros * diff --git a/arch/cris/include/arch-v32/arch/hwregs/dma_defs.h b/arch/cris/include/arch-v32/arch/hwregs/dma_defs.h index 48ac8cef7ebe..a67826f5fe21 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/dma_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/dma_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __dma_defs_h #define __dma_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h b/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h index 90fe8a28894f..d8021b44e5e6 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __eth_defs_h #define __eth_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/extmem_defs.h b/arch/cris/include/arch-v32/arch/hwregs/extmem_defs.h index c47b5ca48ece..5937ed7a5228 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/extmem_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/extmem_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __extmem_defs_h #define __extmem_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile b/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile index 0747a22e3c07..1b9467ae65c1 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # $Id: Makefile,v 1.3 2004/01/07 20:34:55 johana Exp $ # Makefile to generate or copy the latest register definitions # and related datastructures and helpermacros. diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_crc_par_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_crc_par_defs_asm.h index a4b58000c164..10443d789a66 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_crc_par_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_crc_par_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_crc_par_defs_asm_h #define __iop_crc_par_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_in_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_in_defs_asm.h index e7d539feccb1..fdee9bbe1fd4 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_in_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_in_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_dmc_in_defs_asm_h #define __iop_dmc_in_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_out_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_out_defs_asm.h index 9fe1a8054371..a97b741bd36a 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_out_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_dmc_out_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_dmc_out_defs_asm_h #define __iop_dmc_out_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_defs_asm.h index 974dee082f9f..e2c0990246f2 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_in_defs_asm_h #define __iop_fifo_in_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_extra_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_extra_defs_asm.h index e00fab0c9335..50837b989c90 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_extra_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_in_extra_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_in_extra_defs_asm_h #define __iop_fifo_in_extra_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_defs_asm.h index 9ec5f4a826df..9f06dddf33a0 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_out_defs_asm_h #define __iop_fifo_out_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_extra_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_extra_defs_asm.h index 0f84a50cf77c..e8c488c389e4 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_extra_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_fifo_out_extra_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_out_extra_defs_asm_h #define __iop_fifo_out_extra_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_mpu_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_mpu_defs_asm.h index 80490c82cc29..48869d445e07 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_mpu_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_mpu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_mpu_defs_asm_h #define __iop_mpu_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_reg_space_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_reg_space_asm.h index a20b8857b4d0..615f869a6de9 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_reg_space_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_reg_space_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Autogenerated Changes here will be lost! * generated by ../gen_sw.pl Mon Apr 11 16:10:18 2005 iop_sw.cfg */ diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_in_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_in_defs_asm.h index a4a10ff300b3..fe8c90e015b0 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_in_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_in_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_in_defs_asm_h #define __iop_sap_in_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_out_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_out_defs_asm.h index 0ec727f92a25..a5e46f0bbf6f 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_out_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sap_out_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_out_defs_asm_h #define __iop_sap_out_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_in_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_in_defs_asm.h index 2cf5721597fc..169aaf8d44b2 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_in_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_in_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_scrc_in_defs_asm_h #define __iop_scrc_in_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_out_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_out_defs_asm.h index 640a25725f20..0e9bca149bc6 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_out_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_scrc_out_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_scrc_out_defs_asm_h #define __iop_scrc_out_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_spu_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_spu_defs_asm.h index bb402c1aa761..cf2b64a9d42c 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_spu_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_spu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_spu_defs_asm_h #define __iop_spu_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cfg_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cfg_defs_asm.h index 3be60f9b024c..4f4c7340d39a 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cfg_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cfg_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cfg_defs_asm_h #define __iop_sw_cfg_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cpu_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cpu_defs_asm.h index db347bcba025..ef04a57a0680 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cpu_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_cpu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cpu_defs_asm_h #define __iop_sw_cpu_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_mpu_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_mpu_defs_asm.h index ee7dc0435b59..22292069e4fd 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_mpu_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_mpu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_mpu_defs_asm_h #define __iop_sw_mpu_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_spu_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_spu_defs_asm.h index 0929f144cfa1..82729218621c 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_spu_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_sw_spu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_spu_defs_asm_h #define __iop_sw_spu_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_timer_grp_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_timer_grp_defs_asm.h index 7129a9a4bedc..4f1cf73d86cd 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_timer_grp_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_timer_grp_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_timer_grp_defs_asm_h #define __iop_timer_grp_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_trigger_grp_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_trigger_grp_defs_asm.h index 1005d9db80dc..7bc882c62952 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_trigger_grp_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_trigger_grp_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_trigger_grp_defs_asm_h #define __iop_trigger_grp_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_version_defs_asm.h b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_version_defs_asm.h index e13feb20a7e3..2e239957e34a 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_version_defs_asm.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/asm/iop_version_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_version_defs_asm_h #define __iop_version_defs_asm_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_crc_par_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_crc_par_defs.h index 90e4785b6474..8690034d9bec 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_crc_par_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_crc_par_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_crc_par_defs_h #define __iop_crc_par_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_in_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_in_defs.h index 76aec6e37f3e..3dd4e870a3a5 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_in_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_in_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_dmc_in_defs_h #define __iop_dmc_in_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_out_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_out_defs.h index 938a0d4c4604..7ed17bc553c3 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_out_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_dmc_out_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_dmc_out_defs_h #define __iop_dmc_out_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_defs.h index e0c982b263fa..dc14868680e6 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_in_defs_h #define __iop_fifo_in_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_extra_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_extra_defs.h index 798ac95870e9..ee7dc07a7862 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_extra_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_in_extra_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_in_extra_defs_h #define __iop_fifo_in_extra_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_defs.h index 833e10f02526..ee8194fcfa82 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_out_defs_h #define __iop_fifo_out_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_extra_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_extra_defs.h index 4a840aae84ee..b9721649f6fd 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_extra_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_fifo_out_extra_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_fifo_out_extra_defs_h #define __iop_fifo_out_extra_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_defs.h index c2b0ba1be60f..28e1c5903677 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_mpu_defs_h #define __iop_mpu_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_macros.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_macros.h index 2ec897ced166..41f5178a65b8 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_macros.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_mpu_macros.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ************************************************************************* */ /* This file is autogenerated by IOPASM Version 1.2 */ /* DO NOT EDIT THIS FILE - All changes will be lost! */ diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_reg_space.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_reg_space.h index 756550f5d6cb..95e9ce8c042a 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_reg_space.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_reg_space.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Autogenerated Changes here will be lost! * generated by ../gen_sw.pl Mon Apr 11 16:10:18 2005 iop_sw.cfg */ diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_in_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_in_defs.h index 5548ac10074f..22a74eafb8b0 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_in_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_in_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_in_defs_h #define __iop_sap_in_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_out_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_out_defs.h index 273936996183..380133910105 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_out_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sap_out_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_out_defs_h #define __iop_sap_out_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_in_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_in_defs.h index 4f0a9a81e737..65d662046ca9 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_in_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_in_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_scrc_in_defs_h #define __iop_scrc_in_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_out_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_out_defs.h index fd1d6ea1d484..ba39605b9737 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_out_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_scrc_out_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_scrc_out_defs_h #define __iop_scrc_out_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_spu_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_spu_defs.h index 0fda26e2f06f..7681fdab93fc 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_spu_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_spu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_spu_defs_h #define __iop_spu_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cfg_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cfg_defs.h index d7b6d75884d2..86e5c9b3e593 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cfg_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cfg_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cfg_defs_h #define __iop_sw_cfg_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cpu_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cpu_defs.h index 5fed844b19e2..31055d3fcd76 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cpu_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_cpu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cpu_defs_h #define __iop_sw_cpu_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_mpu_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_mpu_defs.h index da718f2a8cad..5038c08e8a95 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_mpu_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_mpu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_mpu_defs_h #define __iop_sw_mpu_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_spu_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_spu_defs.h index b59dde4bd0d1..aeebd57af7f7 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_spu_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_sw_spu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_spu_defs_h #define __iop_sw_spu_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_timer_grp_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_timer_grp_defs.h index c994114f3b51..b4095422adf6 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_timer_grp_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_timer_grp_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_timer_grp_defs_h #define __iop_timer_grp_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_trigger_grp_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_trigger_grp_defs.h index 36e44282399d..aff694506e7f 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_trigger_grp_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_trigger_grp_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_trigger_grp_defs_h #define __iop_trigger_grp_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_version_defs.h b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_version_defs.h index b8d6a910c71c..53a4b8cda969 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/iop/iop_version_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/iop/iop_version_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_version_defs_h #define __iop_version_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/irq_nmi_defs.h b/arch/cris/include/arch-v32/arch/hwregs/irq_nmi_defs.h index 7b167e3c0572..63b20dee2fd1 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/irq_nmi_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/irq_nmi_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __irq_nmi_defs_h #define __irq_nmi_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/marb_bp_defs.h b/arch/cris/include/arch-v32/arch/hwregs/marb_bp_defs.h index a11fdd3cd907..da29a8a22250 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/marb_bp_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/marb_bp_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __marb_bp_defs_h #define __marb_bp_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/marb_defs.h b/arch/cris/include/arch-v32/arch/hwregs/marb_defs.h index 71e8af0bb3a4..2858de48a5e0 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/marb_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/marb_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __marb_defs_h #define __marb_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/reg_rdwr.h b/arch/cris/include/arch-v32/arch/hwregs/reg_rdwr.h index 236f91efe7e8..8fabdd211507 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/reg_rdwr.h +++ b/arch/cris/include/arch-v32/arch/hwregs/reg_rdwr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Read/write register macros used by *_defs.h */ diff --git a/arch/cris/include/arch-v32/arch/hwregs/rt_trace_defs.h b/arch/cris/include/arch-v32/arch/hwregs/rt_trace_defs.h index d9f0e924fb23..ebb6bbc6e778 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/rt_trace_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/rt_trace_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __rt_trace_defs_h #define __rt_trace_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/ser_defs.h b/arch/cris/include/arch-v32/arch/hwregs/ser_defs.h index 01c2fab97d43..3b04cf9012cf 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/ser_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/ser_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ser_defs_h #define __ser_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/sser_defs.h b/arch/cris/include/arch-v32/arch/hwregs/sser_defs.h index 8d1dab218b91..02971f9b6558 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/sser_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/sser_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __sser_defs_h #define __sser_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/strcop.h b/arch/cris/include/arch-v32/arch/hwregs/strcop.h index 35131ba466f3..2c522b024ee7 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/strcop.h +++ b/arch/cris/include/arch-v32/arch/hwregs/strcop.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ // $Id: strcop.h,v 1.3 2003/10/22 13:27:12 henriken Exp $ // Streamcop meta-data configuration structs diff --git a/arch/cris/include/arch-v32/arch/hwregs/strcop_defs.h b/arch/cris/include/arch-v32/arch/hwregs/strcop_defs.h index bd145a49b2c4..069b2ed9def5 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/strcop_defs.h +++ b/arch/cris/include/arch-v32/arch/hwregs/strcop_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __strcop_defs_h #define __strcop_defs_h diff --git a/arch/cris/include/arch-v32/arch/hwregs/supp_reg.h b/arch/cris/include/arch-v32/arch/hwregs/supp_reg.h index ffe49625ae36..c3fa0c06c558 100644 --- a/arch/cris/include/arch-v32/arch/hwregs/supp_reg.h +++ b/arch/cris/include/arch-v32/arch/hwregs/supp_reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUPP_REG_H__ #define __SUPP_REG_H__ diff --git a/arch/cris/include/arch-v32/arch/intmem.h b/arch/cris/include/arch-v32/arch/intmem.h index c0ada33bf90f..2bcb21c9b25f 100644 --- a/arch/cris/include/arch-v32/arch/intmem.h +++ b/arch/cris/include/arch-v32/arch/intmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_INTMEM_H #define _ASM_CRIS_INTMEM_H diff --git a/arch/cris/include/arch-v32/arch/irq.h b/arch/cris/include/arch-v32/arch/irq.h index 8270a1bbfdb6..5259084001d4 100644 --- a/arch/cris/include/arch-v32/arch/irq.h +++ b/arch/cris/include/arch-v32/arch/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_IRQ_H #define _ASM_ARCH_IRQ_H diff --git a/arch/cris/include/arch-v32/arch/irqflags.h b/arch/cris/include/arch-v32/arch/irqflags.h index 5f6fddf99509..d55bf82de77c 100644 --- a/arch/cris/include/arch-v32/arch/irqflags.h +++ b/arch/cris/include/arch-v32/arch/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRIS_ARCH_IRQFLAGS_H #define __ASM_CRIS_ARCH_IRQFLAGS_H diff --git a/arch/cris/include/arch-v32/arch/mmu.h b/arch/cris/include/arch-v32/arch/mmu.h index e6db1616dee5..a8eec1312de0 100644 --- a/arch/cris/include/arch-v32/arch/mmu.h +++ b/arch/cris/include/arch-v32/arch/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_MMU_H #define _ASM_CRIS_ARCH_MMU_H diff --git a/arch/cris/include/arch-v32/arch/offset.h b/arch/cris/include/arch-v32/arch/offset.h index 4442c4bd52f4..10a670443386 100644 --- a/arch/cris/include/arch-v32/arch/offset.h +++ b/arch/cris/include/arch-v32/arch/offset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_OFFSETS_H__ #define __ASM_OFFSETS_H__ /* diff --git a/arch/cris/include/arch-v32/arch/page.h b/arch/cris/include/arch-v32/arch/page.h index e5b5aab52de8..7ac04f615193 100644 --- a/arch/cris/include/arch-v32/arch/page.h +++ b/arch/cris/include/arch-v32/arch/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_PAGE_H #define _ASM_CRIS_ARCH_PAGE_H diff --git a/arch/cris/include/arch-v32/arch/pgtable.h b/arch/cris/include/arch-v32/arch/pgtable.h index c1051a8da33d..e787b19b700e 100644 --- a/arch/cris/include/arch-v32/arch/pgtable.h +++ b/arch/cris/include/arch-v32/arch/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_PGTABLE_H #define _ASM_CRIS_ARCH_PGTABLE_H diff --git a/arch/cris/include/arch-v32/arch/processor.h b/arch/cris/include/arch-v32/arch/processor.h index 568759271ab5..554088ab5f01 100644 --- a/arch/cris/include/arch-v32/arch/processor.h +++ b/arch/cris/include/arch-v32/arch/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_PROCESSOR_H #define _ASM_CRIS_ARCH_PROCESSOR_H diff --git a/arch/cris/include/arch-v32/arch/swab.h b/arch/cris/include/arch-v32/arch/swab.h index 9a4ea5e209c2..280dd7093e4f 100644 --- a/arch/cris/include/arch-v32/arch/swab.h +++ b/arch/cris/include/arch-v32/arch/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_SWAB_H #define _ASM_CRIS_ARCH_SWAB_H diff --git a/arch/cris/include/arch-v32/arch/system.h b/arch/cris/include/arch-v32/arch/system.h index db853fb3a458..84f00e5d4652 100644 --- a/arch/cris/include/arch-v32/arch/system.h +++ b/arch/cris/include/arch-v32/arch/system.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_SYSTEM_H #define _ASM_CRIS_ARCH_SYSTEM_H diff --git a/arch/cris/include/arch-v32/arch/thread_info.h b/arch/cris/include/arch-v32/arch/thread_info.h index d6936956a3c6..8514669e5fab 100644 --- a/arch/cris/include/arch-v32/arch/thread_info.h +++ b/arch/cris/include/arch-v32/arch/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_THREAD_INFO_H #define _ASM_CRIS_ARCH_THREAD_INFO_H diff --git a/arch/cris/include/arch-v32/arch/timex.h b/arch/cris/include/arch-v32/arch/timex.h index 2591d3c5ed9d..2cd8e704a73b 100644 --- a/arch/cris/include/arch-v32/arch/timex.h +++ b/arch/cris/include/arch-v32/arch/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_TIMEX_H #define _ASM_CRIS_ARCH_TIMEX_H diff --git a/arch/cris/include/arch-v32/arch/tlb.h b/arch/cris/include/arch-v32/arch/tlb.h index 4effb1253660..50452802738f 100644 --- a/arch/cris/include/arch-v32/arch/tlb.h +++ b/arch/cris/include/arch-v32/arch/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_ARCH_TLB_H #define _CRIS_ARCH_TLB_H diff --git a/arch/cris/include/arch-v32/arch/uaccess.h b/arch/cris/include/arch-v32/arch/uaccess.h index dc2ce090f624..214bd26efcd9 100644 --- a/arch/cris/include/arch-v32/arch/uaccess.h +++ b/arch/cris/include/arch-v32/arch/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Authors: Hans-Peter Nilsson (hp@axis.com) * diff --git a/arch/cris/include/arch-v32/arch/unistd.h b/arch/cris/include/arch-v32/arch/unistd.h index 0051114c63c7..764435b3b28e 100644 --- a/arch/cris/include/arch-v32/arch/unistd.h +++ b/arch/cris/include/arch-v32/arch/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_UNISTD_H_ #define _ASM_CRIS_ARCH_UNISTD_H_ diff --git a/arch/cris/include/arch-v32/mach-a3/mach/arbiter.h b/arch/cris/include/arch-v32/mach-a3/mach/arbiter.h index 65e9d6ff0520..7fafc370def2 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/arbiter.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/arbiter.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_ARBITER_H #define _ASM_CRIS_ARCH_ARBITER_H diff --git a/arch/cris/include/arch-v32/mach-a3/mach/dma.h b/arch/cris/include/arch-v32/mach-a3/mach/dma.h index f01dca1ad108..92a74eab4395 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/dma.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_CRIS_DMA_H #define _ASM_ARCH_CRIS_DMA_H diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/clkgen_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/clkgen_defs_asm.h index 02855adf63e8..3d7f12ec1c54 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/clkgen_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/clkgen_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __clkgen_defs_asm_h #define __clkgen_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/ddr2_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/ddr2_defs_asm.h index b12be03edacb..df79e5a7f02a 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/ddr2_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/ddr2_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ddr2_defs_asm_h #define __ddr2_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/gio_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/gio_defs_asm.h index df6714fda179..04b7ff3f70a2 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/gio_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/gio_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __gio_defs_asm_h #define __gio_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pinmux_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pinmux_defs_asm.h index c3dc9c666c46..a73168a8e93a 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pinmux_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pinmux_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __pinmux_defs_asm_h #define __pinmux_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pio_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pio_defs_asm.h index 3907ef4921c8..463bb9e2c38e 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pio_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/pio_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __pio_defs_asm_h #define __pio_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/reg_map_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/reg_map_asm.h index 89439e9610e2..e3bf8e0692a6 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/reg_map_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/reg_map_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __reg_map_asm_h #define __reg_map_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/timer_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/timer_defs_asm.h index b129e826fc34..82da59c382c2 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/timer_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/asm/timer_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __timer_defs_asm_h #define __timer_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/clkgen_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/clkgen_defs.h index c1e9ba93b3a3..32d58fed3b03 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/clkgen_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/clkgen_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __clkgen_defs_h #define __clkgen_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/ddr2_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/ddr2_defs.h index 0f30e8bf946d..84684c335d7d 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/ddr2_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/ddr2_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ddr2_defs_h #define __ddr2_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/gio_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/gio_defs.h index 5d88e0db23ae..83ab1f495612 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/gio_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/gio_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __gio_defs_h #define __gio_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect.h index bea699aa480e..55dab5bd7bd3 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Interrupt vector numbers autogenerated by ../../../tools/rdesc/bin/rdes2intr from intr_vect.r */ diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect_defs.h index b820f6347c74..71a28d1ed74a 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/intr_vect_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __intr_vect_defs_h #define __intr_vect_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_reg_space_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_reg_space_asm.h index d75a74e90458..5e5f4d94aecf 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_reg_space_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_reg_space_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Autogenerated Changes here will be lost! * generated by ./gen_sw.pl Wed Feb 14 09:27:48 2007 iop_sw.cfg */ diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_in_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_in_defs_asm.h index 7f90b5a0460d..ee0587ec433c 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_in_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_in_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_in_defs_asm_h #define __iop_sap_in_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_out_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_out_defs_asm.h index 399bd656406b..9bbe0b920c93 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_out_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sap_out_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_out_defs_asm_h #define __iop_sap_out_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cfg_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cfg_defs_asm.h index 3b3949b51a66..c4b8bc386cb6 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cfg_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cfg_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cfg_defs_asm_h #define __iop_sw_cfg_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cpu_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cpu_defs_asm.h index 3f4fe1b31815..89f36dc1f96d 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cpu_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_cpu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cpu_defs_asm_h #define __iop_sw_cpu_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_mpu_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_mpu_defs_asm.h index ffcc83b22d21..45e19d79dba9 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_mpu_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_mpu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_mpu_defs_asm_h #define __iop_sw_mpu_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_spu_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_spu_defs_asm.h index 67a745338087..55afb6e320e4 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_spu_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_sw_spu_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_spu_defs_asm_h #define __iop_sw_spu_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_version_defs_asm.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_version_defs_asm.h index 4ad671202af0..79ff8fafd3bf 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_version_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/asm/iop_version_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_version_defs_asm_h #define __iop_version_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_reg_space.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_reg_space.h index af3196c60a46..23d731f36145 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_reg_space.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_reg_space.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Autogenerated Changes here will be lost! * generated by ./gen_sw.pl Wed Feb 14 09:27:48 2007 iop_sw.cfg */ diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_in_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_in_defs.h index 51dde016c03a..1d6c09a3230d 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_in_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_in_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_in_defs_h #define __iop_sap_in_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_out_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_out_defs.h index 5af88baa2ac1..1cbd30efadb7 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_out_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sap_out_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sap_out_defs_h #define __iop_sap_out_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cfg_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cfg_defs.h index 98ac95275a1c..07050b053bb4 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cfg_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cfg_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cfg_defs_h #define __iop_sw_cfg_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cpu_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cpu_defs.h index a16f556370eb..b4acdae4f653 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cpu_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_cpu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_cpu_defs_h #define __iop_sw_cpu_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_mpu_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_mpu_defs.h index a2e4e1a33e57..bc1abb5fb308 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_mpu_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_mpu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_mpu_defs_h #define __iop_sw_mpu_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_spu_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_spu_defs.h index c8560b865a1a..82b64360a4d3 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_spu_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_sw_spu_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_sw_spu_defs_h #define __iop_sw_spu_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_version_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_version_defs.h index 20de425e652b..d944c6ce5f9b 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_version_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/iop/iop_version_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __iop_version_defs_h #define __iop_version_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/l2cache_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/l2cache_defs.h index 243ac3c882cb..5c72116f1067 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/l2cache_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/l2cache_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __l2cache_defs_h #define __l2cache_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_bar_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_bar_defs.h index c0e7628cbf7d..84f68755a75c 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_bar_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_bar_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __marb_bar_defs_h #define __marb_bar_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_foo_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_foo_defs.h index 2baa833f109a..13539bc5d613 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_foo_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/marb_foo_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __marb_foo_defs_h #define __marb_foo_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pinmux_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pinmux_defs.h index 4b96cd2cba8a..d604042a52bf 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pinmux_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pinmux_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __pinmux_defs_h #define __pinmux_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pio_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pio_defs.h index 2d8e4b4cc602..348e39f419e0 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pio_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/pio_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __pio_defs_h #define __pio_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/reg_map.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/reg_map.h index 36e59d6e96b6..04ef87d42513 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/reg_map.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/reg_map.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __reg_map_h #define __reg_map_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/strmux_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/strmux_defs.h index 14f718a4ecc3..a19955fa8d94 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/strmux_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/strmux_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __strmux_defs_h #define __strmux_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/timer_defs.h b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/timer_defs.h index 2c33e097d60a..de849a6362f6 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/hwregs/timer_defs.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/hwregs/timer_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __timer_defs_h #define __timer_defs_h diff --git a/arch/cris/include/arch-v32/mach-a3/mach/memmap.h b/arch/cris/include/arch-v32/mach-a3/mach/memmap.h index 7e15c9eb4e49..7b9a9a5699b2 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/memmap.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/memmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_MEMMAP_H #define _ASM_ARCH_MEMMAP_H diff --git a/arch/cris/include/arch-v32/mach-a3/mach/pinmux.h b/arch/cris/include/arch-v32/mach-a3/mach/pinmux.h index db42a7254584..35e3fc97d6a3 100644 --- a/arch/cris/include/arch-v32/mach-a3/mach/pinmux.h +++ b/arch/cris/include/arch-v32/mach-a3/mach/pinmux.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_PINMUX_H #define _ASM_CRIS_ARCH_PINMUX_H diff --git a/arch/cris/include/arch-v32/mach-fs/mach/arbiter.h b/arch/cris/include/arch-v32/mach-fs/mach/arbiter.h index a2e0ec8faa7d..f9401a3de83c 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/arbiter.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/arbiter.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_ARBITER_H #define _ASM_CRIS_ARCH_ARBITER_H diff --git a/arch/cris/include/arch-v32/mach-fs/mach/dma.h b/arch/cris/include/arch-v32/mach-fs/mach/dma.h index a8c59292586a..53a59944a48b 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/dma.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_CRIS_DMA_H #define _ASM_ARCH_CRIS_DMA_H diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/bif_core_defs_asm.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/bif_core_defs_asm.h index 0a409c92837e..092cad384b86 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/bif_core_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/bif_core_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_core_defs_asm_h #define __bif_core_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/config_defs_asm.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/config_defs_asm.h index a9908dfc2937..5b38835b42f7 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/config_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/config_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __config_defs_asm_h #define __config_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/gio_defs_asm.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/gio_defs_asm.h index be4c63936d90..3d2056892832 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/gio_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/gio_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __gio_defs_asm_h #define __gio_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/pinmux_defs_asm.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/pinmux_defs_asm.h index 30cf5a936b64..99968cfa446a 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/pinmux_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/pinmux_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __pinmux_defs_asm_h #define __pinmux_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/reg_map_asm.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/reg_map_asm.h index 87517aebd2cb..412b8748e952 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/reg_map_asm.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/reg_map_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __reg_map_h #define __reg_map_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/timer_defs_asm.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/timer_defs_asm.h index e1197194d5c1..3eb17cfbdc75 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/timer_defs_asm.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/asm/timer_defs_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __timer_defs_asm_h #define __timer_defs_asm_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_core_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_core_defs.h index 44362a62b47c..a9ffb7edaf91 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_core_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_core_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_core_defs_h #define __bif_core_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_dma_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_dma_defs.h index 3cb51a09dba7..d1fa172f58f4 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_dma_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_dma_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_dma_defs_h #define __bif_dma_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_slave_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_slave_defs.h index 0c434585a3f9..a8d7cc528546 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_slave_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/bif_slave_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __bif_slave_defs_h #define __bif_slave_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/config_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/config_defs.h index abc5f20705f7..cc8b20d17237 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/config_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/config_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __config_defs_h #define __config_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/gio_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/gio_defs.h index 26aa3efcf91b..da0b1103b66d 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/gio_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/gio_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __gio_defs_h #define __gio_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect.h index bacc2a895c21..ea752a2d8ee2 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Interrupt vector numbers autogenerated by /n/asic/design/tools/rdesc/src/rdes2intr version from ../../inst/intr_vect/rtl/guinness/ivmask.config.r version . */ diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect_defs.h index aa65128ae1aa..11ebd66585cd 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/intr_vect_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __intr_vect_defs_h #define __intr_vect_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_bp_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_bp_defs.h index dcaaec4620ba..fb7e20d77591 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_bp_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_bp_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __marb_bp_defs_h #define __marb_bp_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_defs.h index 254da0854986..872a7942916a 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/marb_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __marb_defs_h #define __marb_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/pinmux_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/pinmux_defs.h index 751eab5f191c..0a316dc36a6b 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/pinmux_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/pinmux_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __pinmux_defs_h #define __pinmux_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/reg_map.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/reg_map.h index 4146973a58b3..1bfca2666158 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/reg_map.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/reg_map.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __reg_map_h #define __reg_map_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/strmux_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/strmux_defs.h index cbfaa867829e..0ab49edb1c81 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/strmux_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/strmux_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __strmux_defs_h #define __strmux_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/timer_defs.h b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/timer_defs.h index 76bcc591921d..59c70ba9959b 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/hwregs/timer_defs.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/hwregs/timer_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __timer_defs_h #define __timer_defs_h diff --git a/arch/cris/include/arch-v32/mach-fs/mach/memmap.h b/arch/cris/include/arch-v32/mach-fs/mach/memmap.h index d29df5644d3e..94328936cc91 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/memmap.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/memmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_ARCH_MEMMAP_H #define _ASM_ARCH_MEMMAP_H diff --git a/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h b/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h index 09bf0c90d2d3..1d87f1392dc8 100644 --- a/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h +++ b/arch/cris/include/arch-v32/mach-fs/mach/pinmux.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_ARCH_PINMUX_H #define _ASM_CRIS_ARCH_PINMUX_H diff --git a/arch/cris/include/asm/axisflashmap.h b/arch/cris/include/asm/axisflashmap.h index 015ca5445ddd..185596c2caab 100644 --- a/arch/cris/include/asm/axisflashmap.h +++ b/arch/cris/include/asm/axisflashmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_AXISFLASHMAP_H #define __ASM_AXISFLASHMAP_H diff --git a/arch/cris/include/asm/bitops.h b/arch/cris/include/asm/bitops.h index 8062cb52d343..78f975ad42d9 100644 --- a/arch/cris/include/asm/bitops.h +++ b/arch/cris/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* asm/bitops.h for Linux/CRIS * * TODO: asm versions if speed is needed diff --git a/arch/cris/include/asm/bug.h b/arch/cris/include/asm/bug.h index 3b3958963801..f1fa72a426c2 100644 --- a/arch/cris/include/asm/bug.h +++ b/arch/cris/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_BUG_H #define _CRIS_BUG_H #include diff --git a/arch/cris/include/asm/cache.h b/arch/cris/include/asm/cache.h index a692b9fba8b9..8dac0922721c 100644 --- a/arch/cris/include/asm/cache.h +++ b/arch/cris/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CACHE_H #define _ASM_CACHE_H diff --git a/arch/cris/include/asm/cacheflush.h b/arch/cris/include/asm/cacheflush.h index 36795bca605e..0da1c76a2bbc 100644 --- a/arch/cris/include/asm/cacheflush.h +++ b/arch/cris/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_CACHEFLUSH_H #define _CRIS_CACHEFLUSH_H diff --git a/arch/cris/include/asm/checksum.h b/arch/cris/include/asm/checksum.h index ea949c60b190..61b6a4f6a002 100644 --- a/arch/cris/include/asm/checksum.h +++ b/arch/cris/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* TODO: csum_tcpudp_magic could be speeded up, and csum_fold as well */ #ifndef _CRIS_CHECKSUM_H diff --git a/arch/cris/include/asm/delay.h b/arch/cris/include/asm/delay.h index 75ec581bfead..2dfdb13e1a9e 100644 --- a/arch/cris/include/asm/delay.h +++ b/arch/cris/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_DELAY_H #define _CRIS_DELAY_H diff --git a/arch/cris/include/asm/dma-mapping.h b/arch/cris/include/asm/dma-mapping.h index 256169de3743..1c9bf14807db 100644 --- a/arch/cris/include/asm/dma-mapping.h +++ b/arch/cris/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_DMA_MAPPING_H #define _ASM_CRIS_DMA_MAPPING_H diff --git a/arch/cris/include/asm/dma.h b/arch/cris/include/asm/dma.h index 30fd715fa589..e1f7d6d9bfc2 100644 --- a/arch/cris/include/asm/dma.h +++ b/arch/cris/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: dma.h,v 1.2 2001/05/09 12:17:42 johana Exp $ */ #ifndef _ASM_DMA_H diff --git a/arch/cris/include/asm/eshlibld.h b/arch/cris/include/asm/eshlibld.h index 70aa448256b0..88940556c2db 100644 --- a/arch/cris/include/asm/eshlibld.h +++ b/arch/cris/include/asm/eshlibld.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*!************************************************************************** *! *! FILE NAME : eshlibld.h diff --git a/arch/cris/include/asm/etraxi2c.h b/arch/cris/include/asm/etraxi2c.h index e369a7620893..0fa6f03d93e7 100644 --- a/arch/cris/include/asm/etraxi2c.h +++ b/arch/cris/include/asm/etraxi2c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: etraxi2c.h,v 1.1 2001/01/18 15:49:57 bjornw Exp $ */ #ifndef _LINUX_ETRAXI2C_H diff --git a/arch/cris/include/asm/fasttimer.h b/arch/cris/include/asm/fasttimer.h index 8f8a8d6c9653..bc109f4a8377 100644 --- a/arch/cris/include/asm/fasttimer.h +++ b/arch/cris/include/asm/fasttimer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-cris/fasttimer.h * diff --git a/arch/cris/include/asm/fb.h b/arch/cris/include/asm/fb.h index c7df38030992..e10150073c30 100644 --- a/arch/cris/include/asm/fb.h +++ b/arch/cris/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ #include diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h index fe0b2a0ae03b..c92712d30f54 100644 --- a/arch/cris/include/asm/io.h +++ b/arch/cris/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_IO_H #define _ASM_CRIS_IO_H diff --git a/arch/cris/include/asm/irq.h b/arch/cris/include/asm/irq.h index ce0fcf540d62..6a932f7db58e 100644 --- a/arch/cris/include/asm/irq.h +++ b/arch/cris/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IRQ_H #define _ASM_IRQ_H diff --git a/arch/cris/include/asm/mmu.h b/arch/cris/include/asm/mmu.h index e06ea94ecffd..54da8f64b37a 100644 --- a/arch/cris/include/asm/mmu.h +++ b/arch/cris/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * CRIS MMU constants and PTE layout */ diff --git a/arch/cris/include/asm/mmu_context.h b/arch/cris/include/asm/mmu_context.h index 349acfd25d2f..178f3b72e9e3 100644 --- a/arch/cris/include/asm/mmu_context.h +++ b/arch/cris/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CRIS_MMU_CONTEXT_H #define __CRIS_MMU_CONTEXT_H diff --git a/arch/cris/include/asm/page.h b/arch/cris/include/asm/page.h index dfc53f9b88ec..5b5b3dad7484 100644 --- a/arch/cris/include/asm/page.h +++ b/arch/cris/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_PAGE_H #define _CRIS_PAGE_H diff --git a/arch/cris/include/asm/pci.h b/arch/cris/include/asm/pci.h index 6e505332b3e3..6f8b366a226a 100644 --- a/arch/cris/include/asm/pci.h +++ b/arch/cris/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRIS_PCI_H #define __ASM_CRIS_PCI_H diff --git a/arch/cris/include/asm/pgalloc.h b/arch/cris/include/asm/pgalloc.h index 42f1affb9c2d..d8dc1b834b7d 100644 --- a/arch/cris/include/asm/pgalloc.h +++ b/arch/cris/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_PGALLOC_H #define _CRIS_PGALLOC_H diff --git a/arch/cris/include/asm/pgtable.h b/arch/cris/include/asm/pgtable.h index fa3a73004cc5..03fca401e23c 100644 --- a/arch/cris/include/asm/pgtable.h +++ b/arch/cris/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * CRIS pgtable.h - macros and functions to manipulate page tables. */ diff --git a/arch/cris/include/asm/processor.h b/arch/cris/include/asm/processor.h index bc2729e4b2c9..124dd5ec7f65 100644 --- a/arch/cris/include/asm/processor.h +++ b/arch/cris/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-cris/processor.h * diff --git a/arch/cris/include/asm/ptrace.h b/arch/cris/include/asm/ptrace.h index 9e788d04a4ef..d69295f1a7c8 100644 --- a/arch/cris/include/asm/ptrace.h +++ b/arch/cris/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_PTRACE_H #define _CRIS_PTRACE_H diff --git a/arch/cris/include/asm/segment.h b/arch/cris/include/asm/segment.h index c067513beaaf..6ac914b098bf 100644 --- a/arch/cris/include/asm/segment.h +++ b/arch/cris/include/asm/segment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SEGMENT_H #define _ASM_SEGMENT_H diff --git a/arch/cris/include/asm/serial.h b/arch/cris/include/asm/serial.h index af7535a955fb..f51e0e10faa7 100644 --- a/arch/cris/include/asm/serial.h +++ b/arch/cris/include/asm/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SERIAL_H #define _ASM_SERIAL_H diff --git a/arch/cris/include/asm/shmparam.h b/arch/cris/include/asm/shmparam.h index d29d12270687..704a7257cb0d 100644 --- a/arch/cris/include/asm/shmparam.h +++ b/arch/cris/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_SHMPARAM_H #define _ASM_CRIS_SHMPARAM_H diff --git a/arch/cris/include/asm/signal.h b/arch/cris/include/asm/signal.h index c11b8745cece..64b0943c0b00 100644 --- a/arch/cris/include/asm/signal.h +++ b/arch/cris/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_SIGNAL_H #define _ASM_CRIS_SIGNAL_H diff --git a/arch/cris/include/asm/stacktrace.h b/arch/cris/include/asm/stacktrace.h index 2d90856943ad..154f0c90d0fa 100644 --- a/arch/cris/include/asm/stacktrace.h +++ b/arch/cris/include/asm/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CRIS_STACKTRACE_H #define __CRIS_STACKTRACE_H diff --git a/arch/cris/include/asm/string.h b/arch/cris/include/asm/string.h index d5db39f9eea1..bae5a0867785 100644 --- a/arch/cris/include/asm/string.h +++ b/arch/cris/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_STRING_H #define _ASM_CRIS_STRING_H diff --git a/arch/cris/include/asm/swab.h b/arch/cris/include/asm/swab.h index 991b6ace1ba9..5e1d8cf277fb 100644 --- a/arch/cris/include/asm/swab.h +++ b/arch/cris/include/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_SWAB_H #define _CRIS_SWAB_H diff --git a/arch/cris/include/asm/switch_to.h b/arch/cris/include/asm/switch_to.h index d842e1163ba1..dde4acf6e54d 100644 --- a/arch/cris/include/asm/switch_to.h +++ b/arch/cris/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRIS_SWITCH_TO_H #define __ASM_CRIS_SWITCH_TO_H diff --git a/arch/cris/include/asm/termios.h b/arch/cris/include/asm/termios.h index 1991cd9e4083..9832bf3221d0 100644 --- a/arch/cris/include/asm/termios.h +++ b/arch/cris/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_TERMIOS_H #define _CRIS_TERMIOS_H diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h index 4ead1b40d2d7..472830c90997 100644 --- a/arch/cris/include/asm/thread_info.h +++ b/arch/cris/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* thread_info.h: CRIS low-level thread information * * Copyright (C) 2002 David Howells (dhowells@redhat.com) diff --git a/arch/cris/include/asm/timex.h b/arch/cris/include/asm/timex.h index 980924ae7518..3840a556612b 100644 --- a/arch/cris/include/asm/timex.h +++ b/arch/cris/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-cris/timex.h * diff --git a/arch/cris/include/asm/tlb.h b/arch/cris/include/asm/tlb.h index 77384ea2f29d..1f6a8a67cfda 100644 --- a/arch/cris/include/asm/tlb.h +++ b/arch/cris/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_TLB_H #define _CRIS_TLB_H diff --git a/arch/cris/include/asm/tlbflush.h b/arch/cris/include/asm/tlbflush.h index b424f43a9fd6..e7cb964536d0 100644 --- a/arch/cris/include/asm/tlbflush.h +++ b/arch/cris/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CRIS_TLBFLUSH_H #define _CRIS_TLBFLUSH_H diff --git a/arch/cris/include/asm/uaccess.h b/arch/cris/include/asm/uaccess.h index b0c6b077b632..3b42ab0cae93 100644 --- a/arch/cris/include/asm/uaccess.h +++ b/arch/cris/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Authors: Bjorn Wesen (bjornw@axis.com) * Hans-Peter Nilsson (hp@axis.com) diff --git a/arch/cris/include/asm/ucontext.h b/arch/cris/include/asm/ucontext.h index eed6ad5eb3f2..22f7e7cf59c8 100644 --- a/arch/cris/include/asm/ucontext.h +++ b/arch/cris/include/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_UCONTEXT_H #define _ASM_CRIS_UCONTEXT_H diff --git a/arch/cris/include/asm/unaligned.h b/arch/cris/include/asm/unaligned.h index 7b3f3fec567c..21772cf600dd 100644 --- a/arch/cris/include/asm/unaligned.h +++ b/arch/cris/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_UNALIGNED_H #define _ASM_CRIS_UNALIGNED_H diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h index 9c23535821c0..6a92c0505156 100644 --- a/arch/cris/include/asm/unistd.h +++ b/arch/cris/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CRIS_UNISTD_H_ #define _ASM_CRIS_UNISTD_H_ diff --git a/arch/cris/include/asm/user.h b/arch/cris/include/asm/user.h index 59147cf43cf6..a19c39547248 100644 --- a/arch/cris/include/asm/user.h +++ b/arch/cris/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CRIS_USER_H #define __ASM_CRIS_USER_H diff --git a/arch/cris/include/uapi/arch-v10/arch/sv_addr_ag.h b/arch/cris/include/uapi/arch-v10/arch/sv_addr_ag.h index c4b6b0e9b1da..2644bcbe4490 100644 --- a/arch/cris/include/uapi/arch-v10/arch/sv_addr_ag.h +++ b/arch/cris/include/uapi/arch-v10/arch/sv_addr_ag.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /*!************************************************************************** *! *! MACROS: diff --git a/arch/cris/include/uapi/arch-v10/arch/svinto.h b/arch/cris/include/uapi/arch-v10/arch/svinto.h index da5c15272652..793a4275d26a 100644 --- a/arch/cris/include/uapi/arch-v10/arch/svinto.h +++ b/arch/cris/include/uapi/arch-v10/arch/svinto.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_CRIS_SVINTO_H #define _ASM_CRIS_SVINTO_H diff --git a/arch/cris/include/uapi/arch-v10/arch/user.h b/arch/cris/include/uapi/arch-v10/arch/user.h index 9303ea77c915..5b9288527b98 100644 --- a/arch/cris/include/uapi/arch-v10/arch/user.h +++ b/arch/cris/include/uapi/arch-v10/arch/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_CRIS_ARCH_USER_H #define __ASM_CRIS_ARCH_USER_H diff --git a/arch/cris/include/uapi/arch-v32/arch/cryptocop.h b/arch/cris/include/uapi/arch-v32/arch/cryptocop.h index 694fd13ce1cf..1072d5bf7d4f 100644 --- a/arch/cris/include/uapi/arch-v32/arch/cryptocop.h +++ b/arch/cris/include/uapi/arch-v32/arch/cryptocop.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * The device /dev/cryptocop is accessible using this driver using * CRYPTOCOP_MAJOR (254) and minor number 0. diff --git a/arch/cris/include/uapi/arch-v32/arch/user.h b/arch/cris/include/uapi/arch-v32/arch/user.h index 03fa1f3c3c00..3576b540ba78 100644 --- a/arch/cris/include/uapi/arch-v32/arch/user.h +++ b/arch/cris/include/uapi/arch-v32/arch/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_CRIS_ARCH_USER_H #define _ASM_CRIS_ARCH_USER_H diff --git a/arch/cris/include/uapi/asm/byteorder.h b/arch/cris/include/uapi/asm/byteorder.h index bcd189798e26..6e19891e06ee 100644 --- a/arch/cris/include/uapi/asm/byteorder.h +++ b/arch/cris/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _CRIS_BYTEORDER_H #define _CRIS_BYTEORDER_H diff --git a/arch/cris/include/uapi/asm/elf.h b/arch/cris/include/uapi/asm/elf.h index a5df05bfee66..ea4cbdafe885 100644 --- a/arch/cris/include/uapi/asm/elf.h +++ b/arch/cris/include/uapi/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASMCRIS_ELF_H #define __ASMCRIS_ELF_H diff --git a/arch/cris/include/uapi/asm/elf_v10.h b/arch/cris/include/uapi/asm/elf_v10.h index 3ea65cef529d..b1515f2684da 100644 --- a/arch/cris/include/uapi/asm/elf_v10.h +++ b/arch/cris/include/uapi/asm/elf_v10.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASMCRIS_ARCH_ELF_H #define __ASMCRIS_ARCH_ELF_H diff --git a/arch/cris/include/uapi/asm/elf_v32.h b/arch/cris/include/uapi/asm/elf_v32.h index f09fe49005c0..cc00ffdb7f9c 100644 --- a/arch/cris/include/uapi/asm/elf_v32.h +++ b/arch/cris/include/uapi/asm/elf_v32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_CRIS_ELF_H #define _ASM_CRIS_ELF_H diff --git a/arch/cris/include/uapi/asm/ethernet.h b/arch/cris/include/uapi/asm/ethernet.h index 4d58652c3a49..e0c1a6322824 100644 --- a/arch/cris/include/uapi/asm/ethernet.h +++ b/arch/cris/include/uapi/asm/ethernet.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * ioctl defines for ethernet driver * diff --git a/arch/cris/include/uapi/asm/etraxgpio.h b/arch/cris/include/uapi/asm/etraxgpio.h index c6e7d57c8b24..10ab0dd45bfe 100644 --- a/arch/cris/include/uapi/asm/etraxgpio.h +++ b/arch/cris/include/uapi/asm/etraxgpio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * The following devices are accessible using this driver using * GPIO_MAJOR (120) and a couple of minor numbers. diff --git a/arch/cris/include/uapi/asm/ioctls.h b/arch/cris/include/uapi/asm/ioctls.h index 488fbb3f5e84..92d654ce3d84 100644 --- a/arch/cris/include/uapi/asm/ioctls.h +++ b/arch/cris/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_CRIS_IOCTLS_H__ #define __ARCH_CRIS_IOCTLS_H__ diff --git a/arch/cris/include/uapi/asm/param.h b/arch/cris/include/uapi/asm/param.h index 484fcf8667c0..ae296115c7c9 100644 --- a/arch/cris/include/uapi/asm/param.h +++ b/arch/cris/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMCRIS_PARAM_H #define _ASMCRIS_PARAM_H diff --git a/arch/cris/include/uapi/asm/posix_types.h b/arch/cris/include/uapi/asm/posix_types.h index 0f22e6a67ea5..c75d8b0acc99 100644 --- a/arch/cris/include/uapi/asm/posix_types.h +++ b/arch/cris/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* $Id: posix_types.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */ /* We cheat a bit and use our C-coded bitops functions from asm/bitops.h */ diff --git a/arch/cris/include/uapi/asm/ptrace.h b/arch/cris/include/uapi/asm/ptrace.h index bd8946f83ed3..99de59e54613 100644 --- a/arch/cris/include/uapi/asm/ptrace.h +++ b/arch/cris/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifdef __arch_v32 #include #else diff --git a/arch/cris/include/uapi/asm/ptrace_v10.h b/arch/cris/include/uapi/asm/ptrace_v10.h index 1a232739565e..4ffffb7ab102 100644 --- a/arch/cris/include/uapi/asm/ptrace_v10.h +++ b/arch/cris/include/uapi/asm/ptrace_v10.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _CRIS_ARCH_PTRACE_H #define _CRIS_ARCH_PTRACE_H diff --git a/arch/cris/include/uapi/asm/ptrace_v32.h b/arch/cris/include/uapi/asm/ptrace_v32.h index 19773d3bd4c4..a91c4aacb14f 100644 --- a/arch/cris/include/uapi/asm/ptrace_v32.h +++ b/arch/cris/include/uapi/asm/ptrace_v32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _CRIS_ARCH_PTRACE_H #define _CRIS_ARCH_PTRACE_H diff --git a/arch/cris/include/uapi/asm/rs485.h b/arch/cris/include/uapi/asm/rs485.h index ad40f9fbcb8a..041d31fa33d5 100644 --- a/arch/cris/include/uapi/asm/rs485.h +++ b/arch/cris/include/uapi/asm/rs485.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* RS-485 structures */ /* Used with ioctl() TIOCSERSETRS485 for backward compatibility! diff --git a/arch/cris/include/uapi/asm/setup.h b/arch/cris/include/uapi/asm/setup.h index b90728652d1a..4854ace9db76 100644 --- a/arch/cris/include/uapi/asm/setup.h +++ b/arch/cris/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _CRIS_SETUP_H #define _CRIS_SETUP_H diff --git a/arch/cris/include/uapi/asm/sigcontext.h b/arch/cris/include/uapi/asm/sigcontext.h index a1d634e120df..97565ce3f0b9 100644 --- a/arch/cris/include/uapi/asm/sigcontext.h +++ b/arch/cris/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* $Id: sigcontext.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */ #ifndef _ASM_CRIS_SIGCONTEXT_H diff --git a/arch/cris/include/uapi/asm/signal.h b/arch/cris/include/uapi/asm/signal.h index ce42fa7c32ad..e4ab00f00111 100644 --- a/arch/cris/include/uapi/asm/signal.h +++ b/arch/cris/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_CRIS_SIGNAL_H #define _UAPI_ASM_CRIS_SIGNAL_H diff --git a/arch/cris/include/uapi/asm/stat.h b/arch/cris/include/uapi/asm/stat.h index 9e558cc3c43b..cdb74d5862e4 100644 --- a/arch/cris/include/uapi/asm/stat.h +++ b/arch/cris/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _CRIS_STAT_H #define _CRIS_STAT_H diff --git a/arch/cris/include/uapi/asm/sync_serial.h b/arch/cris/include/uapi/asm/sync_serial.h index 7f827fea30e7..f2d468889ba9 100644 --- a/arch/cris/include/uapi/asm/sync_serial.h +++ b/arch/cris/include/uapi/asm/sync_serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * ioctl defines for synchronous serial port driver * diff --git a/arch/cris/include/uapi/asm/termbits.h b/arch/cris/include/uapi/asm/termbits.h index 1c43bc874ccf..86925dc1fcae 100644 --- a/arch/cris/include/uapi/asm/termbits.h +++ b/arch/cris/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* $Id: termbits.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $ */ #ifndef __ARCH_ETRAX100_TERMBITS_H__ diff --git a/arch/cris/include/uapi/asm/termios.h b/arch/cris/include/uapi/asm/termios.h index 0a0386a55027..d87800a6d854 100644 --- a/arch/cris/include/uapi/asm/termios.h +++ b/arch/cris/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_CRIS_TERMIOS_H #define _UAPI_CRIS_TERMIOS_H diff --git a/arch/cris/include/uapi/asm/unistd.h b/arch/cris/include/uapi/asm/unistd.h index 062b648b27e1..7aba513b082d 100644 --- a/arch/cris/include/uapi/asm/unistd.h +++ b/arch/cris/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_CRIS_UNISTD_H_ #define _UAPI_ASM_CRIS_UNISTD_H_ diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile index 5fae398ca915..af075a5fb9aa 100644 --- a/arch/cris/kernel/Makefile +++ b/arch/cris/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # $Id: Makefile,v 1.12 2004/10/19 13:07:43 starvik Exp $ # # Makefile for the linux kernel. diff --git a/arch/cris/kernel/asm-offsets.c b/arch/cris/kernel/asm-offsets.c index a5fd88d816a6..0a5129941485 100644 --- a/arch/cris/kernel/asm-offsets.c +++ b/arch/cris/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c index 3166d1cf2f84..7024f7278c89 100644 --- a/arch/cris/kernel/crisksyms.c +++ b/arch/cris/kernel/crisksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/kernel/devicetree.c b/arch/cris/kernel/devicetree.c index 53ff8d73e7e1..36e1c658229f 100644 --- a/arch/cris/kernel/devicetree.c +++ b/arch/cris/kernel/devicetree.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c index 09b864f46f8a..726cdf4bf2d8 100644 --- a/arch/cris/kernel/irq.c +++ b/arch/cris/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * * linux/arch/cris/kernel/irq.c diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c index 0bbd3a0c3d70..50e5cf09841d 100644 --- a/arch/cris/kernel/process.c +++ b/arch/cris/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/process.c * diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c index ad56b37f8e11..d2f978ad129a 100644 --- a/arch/cris/kernel/profile.c +++ b/arch/cris/kernel/profile.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c index 806b764059d5..af42789a1544 100644 --- a/arch/cris/kernel/ptrace.c +++ b/arch/cris/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/ptrace.c * diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index 4b4853d914e2..524d47501a23 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * * linux/arch/cris/kernel/setup.c diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c index 8febb032fdd7..ecea13f1d760 100644 --- a/arch/cris/kernel/sys_cris.c +++ b/arch/cris/kernel/sys_cris.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* $Id: sys_cris.c,v 1.6 2004/03/11 11:38:40 starvik Exp $ * * linux/arch/cris/kernel/sys_cris.c diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index bc562cf511a6..593239274f98 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/kernel/time.c * diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c index a01636a12a6e..d4bc80469218 100644 --- a/arch/cris/kernel/traps.c +++ b/arch/cris/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/traps.c * @@ -42,7 +43,7 @@ void (*nmi_handler)(struct pt_regs *); void show_trace(unsigned long *stack) { unsigned long addr, module_start, module_end; - extern char _stext, _etext; + extern char _stext[], _etext[]; int i; pr_err("\nCall Trace: "); @@ -69,8 +70,8 @@ void show_trace(unsigned long *stack) * down the cause of the crash will be able to figure * out the call path that was taken. */ - if (((addr >= (unsigned long)&_stext) && - (addr <= (unsigned long)&_etext)) || + if (((addr >= (unsigned long)_stext) && + (addr <= (unsigned long)_etext)) || ((addr >= module_start) && (addr <= module_end))) { #ifdef CONFIG_KALLSYMS print_ip_sym(addr); diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S index 867f237d7c5c..6d1dbc1ba767 100644 --- a/arch/cris/kernel/vmlinux.lds.S +++ b/arch/cris/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make the Linux/CRIS kernel * Authors: Bjorn Wesen (bjornw@axis.com) * diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index 1fca464f1b9e..29cc58038b98 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/cris/mm/fault.c * diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index 1e7fd45b60f8..e41d9c833e1c 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/mm/init.c * diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c index 80fdb995a8ce..350bd2a86ade 100644 --- a/arch/cris/mm/ioremap.c +++ b/arch/cris/mm/ioremap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/cris/mm/ioremap.c * diff --git a/arch/cris/mm/tlb.c b/arch/cris/mm/tlb.c index 8413741cfa0f..e0dbea62cb81 100644 --- a/arch/cris/mm/tlb.c +++ b/arch/cris/mm/tlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/cris/mm/tlb.c * diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index eefd9a4ed156..af369b05fed5 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config FRV bool default y @@ -17,6 +18,9 @@ config FRV select HAVE_DEBUG_STACKOVERFLOW select ARCH_NO_COHERENT_DMA_MMAP +config CPU_BIG_ENDIAN + def_bool y + config ZONE_DMA bool default y diff --git a/arch/frv/Kconfig.debug b/arch/frv/Kconfig.debug index 98c99a3ed2be..ecab6d8a79ed 100644 --- a/arch/frv/Kconfig.debug +++ b/arch/frv/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/frv/include/asm/atomic_defs.h b/arch/frv/include/asm/atomic_defs.h index d4912c88b829..ce3b8a4efc12 100644 --- a/arch/frv/include/asm/atomic_defs.h +++ b/arch/frv/include/asm/atomic_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h index 354900917585..273defa02a02 100644 --- a/arch/frv/include/asm/dma-mapping.h +++ b/arch/frv/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_DMA_MAPPING_H #define _ASM_DMA_MAPPING_H diff --git a/arch/frv/include/asm/fpu.h b/arch/frv/include/asm/fpu.h index d73c60b56641..2f0929333f91 100644 --- a/arch/frv/include/asm/fpu.h +++ b/arch/frv/include/asm/fpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_FPU_H #define __ASM_FPU_H diff --git a/arch/frv/include/asm/futex.h b/arch/frv/include/asm/futex.h index 2e1da71e27a4..dfcc3484231d 100644 --- a/arch/frv/include/asm/futex.h +++ b/arch/frv/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FUTEX_H #define _ASM_FUTEX_H @@ -7,7 +8,8 @@ #include #include -extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr); +extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr); static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h index 43901f220963..0849db1362d6 100644 --- a/arch/frv/include/asm/kmap_types.h +++ b/arch/frv/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H diff --git a/arch/frv/include/asm/local.h b/arch/frv/include/asm/local.h index c27bdf04630e..259ae7b041a7 100644 --- a/arch/frv/include/asm/local.h +++ b/arch/frv/include/asm/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_LOCAL_H #define _ASM_LOCAL_H diff --git a/arch/frv/include/asm/math-emu.h b/arch/frv/include/asm/math-emu.h index 0c8f731b2180..8af762dd6109 100644 --- a/arch/frv/include/asm/math-emu.h +++ b/arch/frv/include/asm/math-emu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MATH_EMU_H #define _ASM_MATH_EMU_H diff --git a/arch/frv/include/asm/page.h b/arch/frv/include/asm/page.h index ec5eebce4fb3..0f76a0d586f6 100644 --- a/arch/frv/include/asm/page.h +++ b/arch/frv/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PAGE_H #define _ASM_PAGE_H diff --git a/arch/frv/include/asm/percpu.h b/arch/frv/include/asm/percpu.h index 2cad3f874ded..4209fe5fe0a2 100644 --- a/arch/frv/include/asm/percpu.h +++ b/arch/frv/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_PERCPU_H #define __ASM_PERCPU_H diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index e4d08d74ed9f..021cce78b401 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h @@ -92,10 +92,6 @@ static inline void release_thread(struct task_struct *dead_task) extern asmlinkage void save_user_regs(struct user_context *target); extern asmlinkage void *restore_user_regs(const struct user_context *target, ...); -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) -#define forget_segments() do { } while (0) - unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc) diff --git a/arch/frv/include/asm/shmparam.h b/arch/frv/include/asm/shmparam.h index ab711009cfaa..50ea51f26c46 100644 --- a/arch/frv/include/asm/shmparam.h +++ b/arch/frv/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SHMPARAM_H #define _ASM_SHMPARAM_H diff --git a/arch/frv/include/asm/signal.h b/arch/frv/include/asm/signal.h index eca0abcb79d6..796394113904 100644 --- a/arch/frv/include/asm/signal.h +++ b/arch/frv/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SIGNAL_H #define _ASM_SIGNAL_H diff --git a/arch/frv/include/asm/smp.h b/arch/frv/include/asm/smp.h index 38349ec8b61b..0d7fa409312d 100644 --- a/arch/frv/include/asm/smp.h +++ b/arch/frv/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SMP_H #define __ASM_SMP_H diff --git a/arch/frv/include/asm/termios.h b/arch/frv/include/asm/termios.h index 9f753fc09532..5a8c63554617 100644 --- a/arch/frv/include/asm/termios.h +++ b/arch/frv/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_TERMIOS_H #define _ASM_TERMIOS_H diff --git a/arch/frv/include/asm/timex.h b/arch/frv/include/asm/timex.h index 139093fab326..bf53166f2793 100644 --- a/arch/frv/include/asm/timex.h +++ b/arch/frv/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* timex.h: FR-V architecture timex specifications */ #ifndef _ASM_TIMEX_H diff --git a/arch/frv/include/asm/tlb.h b/arch/frv/include/asm/tlb.h index cd458eb6d75e..d3e361ad725a 100644 --- a/arch/frv/include/asm/tlb.h +++ b/arch/frv/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_TLB_H #define _ASM_TLB_H diff --git a/arch/frv/include/asm/topology.h b/arch/frv/include/asm/topology.h index 942724352705..207603071f78 100644 --- a/arch/frv/include/asm/topology.h +++ b/arch/frv/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_TOPOLOGY_H #define _ASM_TOPOLOGY_H diff --git a/arch/frv/include/asm/ucontext.h b/arch/frv/include/asm/ucontext.h index 8d8c0c948007..0cc2d95dd209 100644 --- a/arch/frv/include/asm/ucontext.h +++ b/arch/frv/include/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_UCONTEXT_H #define _ASM_UCONTEXT_H diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h index 17b5df8fc28a..b4b3f9b26b81 100644 --- a/arch/frv/include/asm/unistd.h +++ b/arch/frv/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_UNISTD_H_ #define _ASM_UNISTD_H_ diff --git a/arch/frv/include/uapi/asm/bitsperlong.h b/arch/frv/include/uapi/asm/bitsperlong.h index 6dc0bb0c13b2..76da34b10f59 100644 --- a/arch/frv/include/uapi/asm/bitsperlong.h +++ b/arch/frv/include/uapi/asm/bitsperlong.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/frv/include/uapi/asm/byteorder.h b/arch/frv/include/uapi/asm/byteorder.h index f29b7593e088..a46f6472acdc 100644 --- a/arch/frv/include/uapi/asm/byteorder.h +++ b/arch/frv/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_BYTEORDER_H #define _ASM_BYTEORDER_H diff --git a/arch/frv/include/uapi/asm/errno.h b/arch/frv/include/uapi/asm/errno.h index d010795ceefe..c5b82f2f2970 100644 --- a/arch/frv/include/uapi/asm/errno.h +++ b/arch/frv/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_ERRNO_H #define _ASM_ERRNO_H diff --git a/arch/frv/include/uapi/asm/fcntl.h b/arch/frv/include/uapi/asm/fcntl.h index 46ab12db5739..a77648c505d1 100644 --- a/arch/frv/include/uapi/asm/fcntl.h +++ b/arch/frv/include/uapi/asm/fcntl.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/frv/include/uapi/asm/ioctl.h b/arch/frv/include/uapi/asm/ioctl.h index b279fe06dfe5..b809c4566e5f 100644 --- a/arch/frv/include/uapi/asm/ioctl.h +++ b/arch/frv/include/uapi/asm/ioctl.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/frv/include/uapi/asm/ioctls.h b/arch/frv/include/uapi/asm/ioctls.h index 2f9fb436ec3c..dd9f5eb9feda 100644 --- a/arch/frv/include/uapi/asm/ioctls.h +++ b/arch/frv/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_IOCTLS_H__ #define __ASM_IOCTLS_H__ diff --git a/arch/frv/include/uapi/asm/ipcbuf.h b/arch/frv/include/uapi/asm/ipcbuf.h index 84c7e51cb6d0..90d6445a14df 100644 --- a/arch/frv/include/uapi/asm/ipcbuf.h +++ b/arch/frv/include/uapi/asm/ipcbuf.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/frv/include/uapi/asm/kvm_para.h b/arch/frv/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/frv/include/uapi/asm/kvm_para.h +++ b/arch/frv/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/frv/include/uapi/asm/mman.h b/arch/frv/include/uapi/asm/mman.h index 8eebf89f5ab1..306fc0460b80 100644 --- a/arch/frv/include/uapi/asm/mman.h +++ b/arch/frv/include/uapi/asm/mman.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/frv/include/uapi/asm/msgbuf.h b/arch/frv/include/uapi/asm/msgbuf.h index 97ceb55a06fb..156c81bb46d7 100644 --- a/arch/frv/include/uapi/asm/msgbuf.h +++ b/arch/frv/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_MSGBUF_H #define _ASM_MSGBUF_H diff --git a/arch/frv/include/uapi/asm/param.h b/arch/frv/include/uapi/asm/param.h index a52dca9a9566..d3e0168d8937 100644 --- a/arch/frv/include/uapi/asm/param.h +++ b/arch/frv/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_PARAM_H #define _ASM_PARAM_H diff --git a/arch/frv/include/uapi/asm/poll.h b/arch/frv/include/uapi/asm/poll.h index 0d01479ccc56..887b67288340 100644 --- a/arch/frv/include/uapi/asm/poll.h +++ b/arch/frv/include/uapi/asm/poll.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POLL_H #define _ASM_POLL_H diff --git a/arch/frv/include/uapi/asm/posix_types.h b/arch/frv/include/uapi/asm/posix_types.h index fe512af74a5a..2995777227b3 100644 --- a/arch/frv/include/uapi/asm/posix_types.h +++ b/arch/frv/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POSIX_TYPES_H #define _ASM_POSIX_TYPES_H diff --git a/arch/frv/include/uapi/asm/ptrace.h b/arch/frv/include/uapi/asm/ptrace.h index 3887e4934683..f1d2f652d083 100644 --- a/arch/frv/include/uapi/asm/ptrace.h +++ b/arch/frv/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* ptrace.h: ptrace() relevant definitions * * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. diff --git a/arch/frv/include/uapi/asm/registers.h b/arch/frv/include/uapi/asm/registers.h index 9666119fcf6e..4caf09b6c193 100644 --- a/arch/frv/include/uapi/asm/registers.h +++ b/arch/frv/include/uapi/asm/registers.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* registers.h: register frame declarations * * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. diff --git a/arch/frv/include/uapi/asm/resource.h b/arch/frv/include/uapi/asm/resource.h index 5fc60548fd02..2100305f9b3e 100644 --- a/arch/frv/include/uapi/asm/resource.h +++ b/arch/frv/include/uapi/asm/resource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_RESOURCE_H #define _ASM_RESOURCE_H diff --git a/arch/frv/include/uapi/asm/sembuf.h b/arch/frv/include/uapi/asm/sembuf.h index 164b12786d6d..d5477f95832b 100644 --- a/arch/frv/include/uapi/asm/sembuf.h +++ b/arch/frv/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SEMBUF_H #define _ASM_SEMBUF_H diff --git a/arch/frv/include/uapi/asm/setup.h b/arch/frv/include/uapi/asm/setup.h index fbf3fc96aae9..f54957047900 100644 --- a/arch/frv/include/uapi/asm/setup.h +++ b/arch/frv/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* setup.h: setup stuff * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. diff --git a/arch/frv/include/uapi/asm/shmbuf.h b/arch/frv/include/uapi/asm/shmbuf.h index 4c6e711a4779..1de8f892e412 100644 --- a/arch/frv/include/uapi/asm/shmbuf.h +++ b/arch/frv/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SHMBUF_H #define _ASM_SHMBUF_H diff --git a/arch/frv/include/uapi/asm/sigcontext.h b/arch/frv/include/uapi/asm/sigcontext.h index 3b263f3cc96f..8fbb0b00afdd 100644 --- a/arch/frv/include/uapi/asm/sigcontext.h +++ b/arch/frv/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* sigcontext.h: FRV signal context * * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. diff --git a/arch/frv/include/uapi/asm/siginfo.h b/arch/frv/include/uapi/asm/siginfo.h index d3fd1ca45653..4c8c975747ac 100644 --- a/arch/frv/include/uapi/asm/siginfo.h +++ b/arch/frv/include/uapi/asm/siginfo.h @@ -1,10 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SIGINFO_H #define _ASM_SIGINFO_H #include #include -#define FPE_MDAOVF (__SI_FAULT|9) /* media overflow */ +#define FPE_MDAOVF 9 /* media overflow */ #undef NSIGFPE #define NSIGFPE 9 diff --git a/arch/frv/include/uapi/asm/signal.h b/arch/frv/include/uapi/asm/signal.h index bf3b162f9bea..603bb796cf46 100644 --- a/arch/frv/include/uapi/asm/signal.h +++ b/arch/frv/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_SIGNAL_H #define _UAPI_ASM_SIGNAL_H diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index f1e3b20dce9f..9168e78fa32a 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SOCKET_H #define _ASM_SOCKET_H @@ -102,5 +103,7 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/frv/include/uapi/asm/sockios.h b/arch/frv/include/uapi/asm/sockios.h index 5dbdd13e6de3..2f62caf1ce84 100644 --- a/arch/frv/include/uapi/asm/sockios.h +++ b/arch/frv/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SOCKIOS__ #define _ASM_SOCKIOS__ diff --git a/arch/frv/include/uapi/asm/stat.h b/arch/frv/include/uapi/asm/stat.h index ce56de9b37ba..0ff9fab915a4 100644 --- a/arch/frv/include/uapi/asm/stat.h +++ b/arch/frv/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_STAT_H #define _ASM_STAT_H diff --git a/arch/frv/include/uapi/asm/statfs.h b/arch/frv/include/uapi/asm/statfs.h index 741f586045ba..2a378cbff07f 100644 --- a/arch/frv/include/uapi/asm/statfs.h +++ b/arch/frv/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_STATFS_H #define _ASM_STATFS_H diff --git a/arch/frv/include/uapi/asm/swab.h b/arch/frv/include/uapi/asm/swab.h index f305834b4799..c78257d172e5 100644 --- a/arch/frv/include/uapi/asm/swab.h +++ b/arch/frv/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SWAB_H #define _ASM_SWAB_H diff --git a/arch/frv/include/uapi/asm/termbits.h b/arch/frv/include/uapi/asm/termbits.h index 7722e19cc349..b1dcd8d0ff78 100644 --- a/arch/frv/include/uapi/asm/termbits.h +++ b/arch/frv/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_TERMBITS_H__ #define _ASM_TERMBITS_H__ diff --git a/arch/frv/include/uapi/asm/termios.h b/arch/frv/include/uapi/asm/termios.h index edcc08a22382..ae35bedae6a2 100644 --- a/arch/frv/include/uapi/asm/termios.h +++ b/arch/frv/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_TERMIOS_H #define _UAPI_ASM_TERMIOS_H diff --git a/arch/frv/include/uapi/asm/types.h b/arch/frv/include/uapi/asm/types.h index cf23149943f9..db74ad9ba6c0 100644 --- a/arch/frv/include/uapi/asm/types.h +++ b/arch/frv/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* types.h: FRV types * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. diff --git a/arch/frv/include/uapi/asm/unistd.h b/arch/frv/include/uapi/asm/unistd.h index 9e2612ff1c9d..4b46acaf832b 100644 --- a/arch/frv/include/uapi/asm/unistd.h +++ b/arch/frv/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_UNISTD_H_ #define _UAPI_ASM_UNISTD_H_ diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile index 3cbb3294b9f9..216ddf30c3c1 100644 --- a/arch/frv/kernel/Makefile +++ b/arch/frv/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/frv/kernel/asm-offsets.c b/arch/frv/kernel/asm-offsets.c index 20c5b79b55f9..0a468e9b51ad 100644 --- a/arch/frv/kernel/asm-offsets.c +++ b/arch/frv/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generate definitions needed by assembly language modules. * This code generates raw asm output which is post-processed diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c index cdb4ce9960eb..6ea430d58149 100644 --- a/arch/frv/kernel/frv_ksyms.c +++ b/arch/frv/kernel/frv_ksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c index d155ca9e5098..37f7b2bf7f73 100644 --- a/arch/frv/kernel/futex.c +++ b/arch/frv/kernel/futex.c @@ -186,20 +186,10 @@ static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_o /* * do the futex operations */ -int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -225,18 +215,9 @@ int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; break; - } - } + if (!ret) + *oval = oldval; return ret; -} /* end futex_atomic_op_inuser() */ +} /* end arch_futex_atomic_op_inuser() */ diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index 3f44dcbbad4d..42806c512758 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make FRV Linux kernel * Written by Martin Mares ; */ diff --git a/arch/frv/lib/atomic-lib.c b/arch/frv/lib/atomic-lib.c index 4d1b887c248b..3027576f7782 100644 --- a/arch/frv/lib/atomic-lib.c +++ b/arch/frv/lib/atomic-lib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile index 21f1df1b378a..bcb03ebb3583 100644 --- a/arch/frv/mb93090-mb00/Makefile +++ b/arch/frv/mb93090-mb00/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the MB93090-MB00 motherboard stuff # diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h index d51992ff5a61..41fbb6bae558 100644 --- a/arch/frv/mb93090-mb00/pci-frv.h +++ b/arch/frv/mb93090-mb00/pci-frv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Low-Level PCI Access for FRV machines. * diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c index 1c35c93f942b..a40aa8663056 100644 --- a/arch/frv/mb93090-mb00/pci-irq.c +++ b/arch/frv/mb93090-mb00/pci-irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci-irq.c: PCI IRQ routing on the FRV motherboard * * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved. diff --git a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c index 9198ddd16092..77c0c5ba88bc 100644 --- a/arch/frv/mm/extable.c +++ b/arch/frv/mm/extable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/frv/mm/extable.c */ diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c index 179e79e220e5..cbe7aec863e3 100644 --- a/arch/frv/mm/fault.c +++ b/arch/frv/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/frv/mm/fault.c * diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 6e3d36f37a02..f8d3fde08190 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config H8300 def_bool y select GENERIC_ATOMIC64 @@ -23,6 +24,9 @@ config H8300 select HAVE_ARCH_HASH select CPU_NO_EFFICIENT_FFS +config CPU_BIG_ENDIAN + def_bool y + config RWSEM_GENERIC_SPINLOCK def_bool y diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu index 8d0ff20c749a..b5e14d513e62 100644 --- a/arch/h8300/Kconfig.cpu +++ b/arch/h8300/Kconfig.cpu @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config CPU_H8300H bool diff --git a/arch/h8300/boot/Makefile b/arch/h8300/boot/Makefile index 2f6393a5da57..8e62df20ebf9 100644 --- a/arch/h8300/boot/Makefile +++ b/arch/h8300/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # arch/h8300/boot/Makefile targets := vmlinux.srec vmlinux.bin zImage diff --git a/arch/h8300/boot/compressed/Makefile b/arch/h8300/boot/compressed/Makefile index 613bfe6f5272..9e2701069bbe 100644 --- a/arch/h8300/boot/compressed/Makefile +++ b/arch/h8300/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/sh/boot/compressed/Makefile # diff --git a/arch/h8300/boot/compressed/head.S b/arch/h8300/boot/compressed/head.S index 0436350c1df5..11ef509579cf 100644 --- a/arch/h8300/boot/compressed/head.S +++ b/arch/h8300/boot/compressed/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/h8300/boot/compressed/head.S * diff --git a/arch/h8300/boot/compressed/misc.c b/arch/h8300/boot/compressed/misc.c index a947dbb4fd91..8915d8fe2e53 100644 --- a/arch/h8300/boot/compressed/misc.c +++ b/arch/h8300/boot/compressed/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/h8300/boot/compressed/misc.c * diff --git a/arch/h8300/boot/compressed/vmlinux.lds b/arch/h8300/boot/compressed/vmlinux.lds index ad848a72fd3f..7f7bb419ce15 100644 --- a/arch/h8300/boot/compressed/vmlinux.lds +++ b/arch/h8300/boot/compressed/vmlinux.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ SECTIONS { .text : diff --git a/arch/h8300/boot/dts/Makefile b/arch/h8300/boot/dts/Makefile index 6c08467c6a3a..14593b51b2b2 100644 --- a/arch/h8300/boot/dts/Makefile +++ b/arch/h8300/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ifneq '$(CONFIG_H8300_BUILTIN_DTB)' '""' BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_H8300_BUILTIN_DTB)).dtb.o endif diff --git a/arch/h8300/boot/dts/edosk2674.dts b/arch/h8300/boot/dts/edosk2674.dts index 6ae884bf66a5..d1733805ea67 100644 --- a/arch/h8300/boot/dts/edosk2674.dts +++ b/arch/h8300/boot/dts/edosk2674.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; / { compatible = "renesas,edosk2674"; diff --git a/arch/h8300/boot/dts/h8300h_sim.dts b/arch/h8300/boot/dts/h8300h_sim.dts index 9c733d920f1f..f1c31cecdec8 100644 --- a/arch/h8300/boot/dts/h8300h_sim.dts +++ b/arch/h8300/boot/dts/h8300h_sim.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; / { compatible = "gnu,gdbsim"; diff --git a/arch/h8300/boot/dts/h8s_sim.dts b/arch/h8300/boot/dts/h8s_sim.dts index 97e1f4b17ef0..932cc3c5a81b 100644 --- a/arch/h8300/boot/dts/h8s_sim.dts +++ b/arch/h8300/boot/dts/h8s_sim.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; / { compatible = "gnu,gdbsim"; diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h index 349a47a918db..941e7554e886 100644 --- a/arch/h8300/include/asm/atomic.h +++ b/arch/h8300/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_H8300_ATOMIC__ #define __ARCH_H8300_ATOMIC__ diff --git a/arch/h8300/include/asm/bitops.h b/arch/h8300/include/asm/bitops.h index 05999aba1d6a..ea0cb0cf6a8b 100644 --- a/arch/h8300/include/asm/bitops.h +++ b/arch/h8300/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_BITOPS_H #define _H8300_BITOPS_H diff --git a/arch/h8300/include/asm/bug.h b/arch/h8300/include/asm/bug.h index 1e1be8119935..00fe5e966bb5 100644 --- a/arch/h8300/include/asm/bug.h +++ b/arch/h8300/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_BUG_H #define _H8300_BUG_H diff --git a/arch/h8300/include/asm/byteorder.h b/arch/h8300/include/asm/byteorder.h index 888478a38145..ecff2d1ca5a3 100644 --- a/arch/h8300/include/asm/byteorder.h +++ b/arch/h8300/include/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __H8300_BYTEORDER_H__ #define __H8300_BYTEORDER_H__ diff --git a/arch/h8300/include/asm/cache.h b/arch/h8300/include/asm/cache.h index 0ef1edc5a6a6..4243eb319acf 100644 --- a/arch/h8300/include/asm/cache.h +++ b/arch/h8300/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_H8300_CACHE_H #define __ARCH_H8300_CACHE_H diff --git a/arch/h8300/include/asm/cmpxchg.h b/arch/h8300/include/asm/cmpxchg.h index 95fec4cd1081..c64bb38ce242 100644 --- a/arch/h8300/include/asm/cmpxchg.h +++ b/arch/h8300/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_H8300_CMPXCHG__ #define __ARCH_H8300_CMPXCHG__ diff --git a/arch/h8300/include/asm/dma-mapping.h b/arch/h8300/include/asm/dma-mapping.h index 847c7562e046..21bb1fc3a6f1 100644 --- a/arch/h8300/include/asm/dma-mapping.h +++ b/arch/h8300/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_DMA_MAPPING_H #define _H8300_DMA_MAPPING_H diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h index 09031d0127a3..029647cda44c 100644 --- a/arch/h8300/include/asm/elf.h +++ b/arch/h8300/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_H8300_ELF_H #define __ASM_H8300_ELF_H diff --git a/arch/h8300/include/asm/flat.h b/arch/h8300/include/asm/flat.h index 7e0bd6fa1532..f4cdfcbdd2ba 100644 --- a/arch/h8300/include/asm/flat.h +++ b/arch/h8300/include/asm/flat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/h8300/asm/include/flat.h -- uClinux flat-format executables */ diff --git a/arch/h8300/include/asm/hash.h b/arch/h8300/include/asm/hash.h index 04cfbd2bd850..2960b4c9e4ed 100644 --- a/arch/h8300/include/asm/hash.h +++ b/arch/h8300/include/asm/hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HASH_H #define _ASM_HASH_H diff --git a/arch/h8300/include/asm/io.h b/arch/h8300/include/asm/io.h index f86918aed9e1..096d99580db6 100644 --- a/arch/h8300/include/asm/io.h +++ b/arch/h8300/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_IO_H #define _H8300_IO_H diff --git a/arch/h8300/include/asm/irq.h b/arch/h8300/include/asm/irq.h index 69f23f0981b3..5fc5b436dde9 100644 --- a/arch/h8300/include/asm/irq.h +++ b/arch/h8300/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_IRQ_H_ #define _H8300_IRQ_H_ diff --git a/arch/h8300/include/asm/irqflags.h b/arch/h8300/include/asm/irqflags.h index 5e1e3242e470..48756b7f405e 100644 --- a/arch/h8300/include/asm/irqflags.h +++ b/arch/h8300/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_IRQFLAGS_H #define _H8300_IRQFLAGS_H diff --git a/arch/h8300/include/asm/page.h b/arch/h8300/include/asm/page.h index 3a987a567258..8da5124ad344 100644 --- a/arch/h8300/include/asm/page.h +++ b/arch/h8300/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_PAGE_H #define _H8300_PAGE_H diff --git a/arch/h8300/include/asm/pci.h b/arch/h8300/include/asm/pci.h index 0b2acaa3dd84..7c9e55d62215 100644 --- a/arch/h8300/include/asm/pci.h +++ b/arch/h8300/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_H8300_PCI_H #define _ASM_H8300_PCI_H diff --git a/arch/h8300/include/asm/pgtable.h b/arch/h8300/include/asm/pgtable.h index 7d265d28ba5e..a99caa49d265 100644 --- a/arch/h8300/include/asm/pgtable.h +++ b/arch/h8300/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_PGTABLE_H #define _H8300_PGTABLE_H #define __ARCH_USE_5LEVEL_HACK diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h index afa53147e66a..985346393e4a 100644 --- a/arch/h8300/include/asm/processor.h +++ b/arch/h8300/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-h8300/processor.h * diff --git a/arch/h8300/include/asm/ptrace.h b/arch/h8300/include/asm/ptrace.h index e693fb463ea8..313cafa85380 100644 --- a/arch/h8300/include/asm/ptrace.h +++ b/arch/h8300/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_PTRACE_H #define _H8300_PTRACE_H diff --git a/arch/h8300/include/asm/segment.h b/arch/h8300/include/asm/segment.h index 48424c6e169f..9adbf7e1aaa3 100644 --- a/arch/h8300/include/asm/segment.h +++ b/arch/h8300/include/asm/segment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_SEGMENT_H #define _H8300_SEGMENT_H diff --git a/arch/h8300/include/asm/signal.h b/arch/h8300/include/asm/signal.h index 5870835c0470..a42f32ca530f 100644 --- a/arch/h8300/include/asm/signal.h +++ b/arch/h8300/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_SIGNAL_H #define _H8300_SIGNAL_H diff --git a/arch/h8300/include/asm/string.h b/arch/h8300/include/asm/string.h index 5dc5a8ac0544..78e45bb2fef0 100644 --- a/arch/h8300/include/asm/string.h +++ b/arch/h8300/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_STRING_H_ #define _H8300_STRING_H_ diff --git a/arch/h8300/include/asm/switch_to.h b/arch/h8300/include/asm/switch_to.h index 7ad1bf92dbc3..2b7e9555bcd1 100644 --- a/arch/h8300/include/asm/switch_to.h +++ b/arch/h8300/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_SWITCH_TO_H #define _H8300_SWITCH_TO_H diff --git a/arch/h8300/include/asm/syscall.h b/arch/h8300/include/asm/syscall.h index b41f688d02cf..924990401237 100644 --- a/arch/h8300/include/asm/syscall.h +++ b/arch/h8300/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_H8300_SYSCALLS_32_H #define __ASM_H8300_SYSCALLS_32_H diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h index 3cef06875f5c..072b92c0d8b5 100644 --- a/arch/h8300/include/asm/thread_info.h +++ b/arch/h8300/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* thread_info.h: h8300 low-level thread information * adapted from the i386 and PPC versions by Yoshinori Sato * diff --git a/arch/h8300/include/asm/tlb.h b/arch/h8300/include/asm/tlb.h index 2c6fa4eed448..98f344279904 100644 --- a/arch/h8300/include/asm/tlb.h +++ b/arch/h8300/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __H8300_TLB_H__ #define __H8300_TLB_H__ diff --git a/arch/h8300/include/asm/traps.h b/arch/h8300/include/asm/traps.h index 15e701130b27..1c5a30ec2df8 100644 --- a/arch/h8300/include/asm/traps.h +++ b/arch/h8300/include/asm/traps.h @@ -33,9 +33,9 @@ extern unsigned long *_interrupt_redirect_table; #define TRAP2_VEC 10 #define TRAP3_VEC 11 -extern char _start, _etext; +extern char _start[], _etext[]; #define check_kernel_text(addr) \ - ((addr >= (unsigned long)(&_start)) && \ - (addr < (unsigned long)(&_etext)) && !(addr & 1)) + ((addr >= (unsigned long)(_start)) && \ + (addr < (unsigned long)(_etext)) && !(addr & 1)) #endif /* _H8300_TRAPS_H */ diff --git a/arch/h8300/include/asm/uaccess.h b/arch/h8300/include/asm/uaccess.h index 6f6144a240ce..bc8031949d07 100644 --- a/arch/h8300/include/asm/uaccess.h +++ b/arch/h8300/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_UACCESS_H #define _ASM_UACCESS_H diff --git a/arch/h8300/include/asm/user.h b/arch/h8300/include/asm/user.h index 2e3555f451f0..2298909f24c6 100644 --- a/arch/h8300/include/asm/user.h +++ b/arch/h8300/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _H8300_USER_H #define _H8300_USER_H diff --git a/arch/h8300/include/uapi/asm/bitsperlong.h b/arch/h8300/include/uapi/asm/bitsperlong.h index 34212608371e..a33e358f1c1b 100644 --- a/arch/h8300/include/uapi/asm/bitsperlong.h +++ b/arch/h8300/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ASM_H8300_BITS_PER_LONG #define _UAPI__ASM_H8300_BITS_PER_LONG diff --git a/arch/h8300/include/uapi/asm/byteorder.h b/arch/h8300/include/uapi/asm/byteorder.h index 13539da99efd..1fe2f9344458 100644 --- a/arch/h8300/include/uapi/asm/byteorder.h +++ b/arch/h8300/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _H8300_BYTEORDER_H #define _H8300_BYTEORDER_H diff --git a/arch/h8300/include/uapi/asm/ptrace.h b/arch/h8300/include/uapi/asm/ptrace.h index e132670d70ec..78167f517ca4 100644 --- a/arch/h8300/include/uapi/asm/ptrace.h +++ b/arch/h8300/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_H8300_PTRACE_H #define _UAPI_H8300_PTRACE_H diff --git a/arch/h8300/include/uapi/asm/sigcontext.h b/arch/h8300/include/uapi/asm/sigcontext.h index c41fdaa04657..f77273c857d7 100644 --- a/arch/h8300/include/uapi/asm/sigcontext.h +++ b/arch/h8300/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_H8300_SIGCONTEXT_H #define _ASM_H8300_SIGCONTEXT_H diff --git a/arch/h8300/include/uapi/asm/signal.h b/arch/h8300/include/uapi/asm/signal.h index af3a6c37fee6..e15521037348 100644 --- a/arch/h8300/include/uapi/asm/signal.h +++ b/arch/h8300/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_H8300_SIGNAL_H #define _UAPI_H8300_SIGNAL_H diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile index 253f8e322ecc..b62e830525c6 100644 --- a/arch/h8300/kernel/Makefile +++ b/arch/h8300/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/h8300/kernel/asm-offsets.c b/arch/h8300/kernel/asm-offsets.c index dc2d16ce8a0d..85e60509f0a8 100644 --- a/arch/h8300/kernel/asm-offsets.c +++ b/arch/h8300/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This program is used to generate definitions needed by * assembly language modules. diff --git a/arch/h8300/kernel/entry.S b/arch/h8300/kernel/entry.S index 4f67d4b350d5..4ade5f8299ba 100644 --- a/arch/h8300/kernel/entry.S +++ b/arch/h8300/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * linux/arch/h8300/kernel/entry.S diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c index a9033c838968..1c6f902e82a5 100644 --- a/arch/h8300/kernel/h8300_ksyms.c +++ b/arch/h8300/kernel/h8300_ksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/h8300/kernel/head_ram.S b/arch/h8300/kernel/head_ram.S index 84ac5c3ed31a..dbf8429f5fab 100644 --- a/arch/h8300/kernel/head_ram.S +++ b/arch/h8300/kernel/head_ram.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/h8300/kernel/head_rom.S b/arch/h8300/kernel/head_rom.S index 9868a4121a1f..ab55a9cb2f36 100644 --- a/arch/h8300/kernel/head_rom.S +++ b/arch/h8300/kernel/head_rom.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c index da79f9521699..834e4d7b1bcf 100644 --- a/arch/h8300/kernel/irq.c +++ b/arch/h8300/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/h8300/kernel/irq.c * diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c index 515f6c4e8d80..cd802cc78d97 100644 --- a/arch/h8300/kernel/module.c +++ b/arch/h8300/kernel/module.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index d1ddcabbbe83..e35cdf092e07 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/h8300/kernel/process.c * diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 6be15d634650..a4d0470c10a9 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/h8300/kernel/setup.c * diff --git a/arch/h8300/kernel/syscalls.c b/arch/h8300/kernel/syscalls.c index 1f9123a013d3..9022036fb3d2 100644 --- a/arch/h8300/kernel/syscalls.c +++ b/arch/h8300/kernel/syscalls.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S index 7f11da1b895e..35716a3048de 100644 --- a/arch/h8300/kernel/vmlinux.lds.S +++ b/arch/h8300/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/h8300/lib/abs.S b/arch/h8300/lib/abs.S index efda749db03e..6e1a4ed3af53 100644 --- a/arch/h8300/lib/abs.S +++ b/arch/h8300/lib/abs.S @@ -1,3 +1,4 @@ +;;; SPDX-License-Identifier: GPL-2.0 ;;; abs.S #include diff --git a/arch/h8300/lib/ashldi3.c b/arch/h8300/lib/ashldi3.c index c6aa8ea5f4be..430720c0c5d8 100644 --- a/arch/h8300/lib/ashldi3.c +++ b/arch/h8300/lib/ashldi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "libgcc.h" DWtype diff --git a/arch/h8300/lib/ashrdi3.c b/arch/h8300/lib/ashrdi3.c index 070adf96d3b6..2c6cd424eb3e 100644 --- a/arch/h8300/lib/ashrdi3.c +++ b/arch/h8300/lib/ashrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "libgcc.h" DWtype __ashrdi3(DWtype u, word_type b) diff --git a/arch/h8300/lib/delay.c b/arch/h8300/lib/delay.c index 463f6b3afb52..f4277529a9b9 100644 --- a/arch/h8300/lib/delay.c +++ b/arch/h8300/lib/delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * delay loops * diff --git a/arch/h8300/lib/libgcc.h b/arch/h8300/lib/libgcc.h index 468a8f78197a..b8bcf7035ff5 100644 --- a/arch/h8300/lib/libgcc.h +++ b/arch/h8300/lib/libgcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __H8300_LIBGCC_H__ #define __H8300_LIBGCC_H__ diff --git a/arch/h8300/lib/lshrdi3.c b/arch/h8300/lib/lshrdi3.c index a86bbe395f17..8dbc861ca589 100644 --- a/arch/h8300/lib/lshrdi3.c +++ b/arch/h8300/lib/lshrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "libgcc.h" DWtype __lshrdi3(DWtype u, word_type b) diff --git a/arch/h8300/lib/memcpy.S b/arch/h8300/lib/memcpy.S index 0c9a51fcdea1..f1cd67d5e3ea 100644 --- a/arch/h8300/lib/memcpy.S +++ b/arch/h8300/lib/memcpy.S @@ -1,3 +1,4 @@ +;;; SPDX-License-Identifier: GPL-2.0 ;;; memcpy.S #include diff --git a/arch/h8300/lib/memset.S b/arch/h8300/lib/memset.S index 18d4e709b5f4..2d1abc37fd08 100644 --- a/arch/h8300/lib/memset.S +++ b/arch/h8300/lib/memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* memset.S */ #include diff --git a/arch/h8300/lib/moddivsi3.S b/arch/h8300/lib/moddivsi3.S index c803129e877f..9e33ab0456c7 100644 --- a/arch/h8300/lib/moddivsi3.S +++ b/arch/h8300/lib/moddivsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include "libgcc.h" ; numerator in A0/A1 diff --git a/arch/h8300/lib/modsi3.S b/arch/h8300/lib/modsi3.S index 68b1dfc32824..bdc8a002921d 100644 --- a/arch/h8300/lib/modsi3.S +++ b/arch/h8300/lib/modsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include "libgcc.h" ; numerator in A0/A1 diff --git a/arch/h8300/lib/muldi3.c b/arch/h8300/lib/muldi3.c index 790512243531..9cb11b134e54 100644 --- a/arch/h8300/lib/muldi3.c +++ b/arch/h8300/lib/muldi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "libgcc.h" #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) diff --git a/arch/h8300/lib/mulsi3.S b/arch/h8300/lib/mulsi3.S index 451f0e0538ee..5a062fd298d1 100644 --- a/arch/h8300/lib/mulsi3.S +++ b/arch/h8300/lib/mulsi3.S @@ -1,3 +1,4 @@ +; SPDX-License-Identifier: GPL-2.0 ; ; mulsi3 for H8/300H - based on Renesas SH implementation ; diff --git a/arch/h8300/lib/strncpy.S b/arch/h8300/lib/strncpy.S index d00396a378f4..8b65d7c4727b 100644 --- a/arch/h8300/lib/strncpy.S +++ b/arch/h8300/lib/strncpy.S @@ -1,3 +1,4 @@ +;;; SPDX-License-Identifier: GPL-2.0 ;;; strncpy.S #include diff --git a/arch/h8300/lib/ucmpdi2.c b/arch/h8300/lib/ucmpdi2.c index 772399d705cb..9f646885f3d7 100644 --- a/arch/h8300/lib/ucmpdi2.c +++ b/arch/h8300/lib/ucmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "libgcc.h" word_type __ucmpdi2(DWtype a, DWtype b) diff --git a/arch/h8300/lib/udivsi3.S b/arch/h8300/lib/udivsi3.S index bbe65610f316..b810aba8e100 100644 --- a/arch/h8300/lib/udivsi3.S +++ b/arch/h8300/lib/udivsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include "libgcc.h" ;; This function also computes the remainder and stores it in er3. diff --git a/arch/h8300/mm/fault.c b/arch/h8300/mm/fault.c index 5924ff555ded..fabffb83930a 100644 --- a/arch/h8300/mm/fault.c +++ b/arch/h8300/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/h8300/mm/fault.c * diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index 495a3d6b539b..eeead51bed2d 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/h8300/mm/init.c * diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c index 4974aa40bcb8..3785f72bf3fc 100644 --- a/arch/h8300/mm/memory.c +++ b/arch/h8300/mm/memory.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/h8300/mm/memory.c * diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 1941e4baaee6..76d2f20d525e 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Hexagon configuration comment "Linux Kernel Configuration for Hexagon" diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile index 207711a0fd0c..48fe08230a80 100644 --- a/arch/hexagon/Makefile +++ b/arch/hexagon/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Hexagon arch KBUILD_DEFCONFIG = comet_defconfig diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 34013683d123..4a23e527d651 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 generic-y += barrier.h generic-y += bug.h generic-y += bugs.h diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h index a62ba368b27d..fb3dfb2a667e 100644 --- a/arch/hexagon/include/asm/atomic.h +++ b/arch/hexagon/include/asm/atomic.h @@ -42,6 +42,8 @@ static inline void atomic_set(atomic_t *v, int new) ); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + /** * atomic_read - reads a word, atomically * @v: pointer to atomic value diff --git a/arch/hexagon/include/asm/futex.h b/arch/hexagon/include/asm/futex.h index 7e597f8434da..c889f5993ecd 100644 --- a/arch/hexagon/include/asm/futex.h +++ b/arch/hexagon/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HEXAGON_FUTEX_H #define _ASM_HEXAGON_FUTEX_H @@ -31,18 +32,9 @@ static inline int -futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; pagefault_disable(); @@ -72,30 +64,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/hexagon/include/asm/spinlock.h b/arch/hexagon/include/asm/spinlock.h index a1c55788c5d6..53a8d5885887 100644 --- a/arch/hexagon/include/asm/spinlock.h +++ b/arch/hexagon/include/asm/spinlock.h @@ -179,11 +179,6 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) */ #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - #define arch_spin_is_locked(x) ((x)->lock != 0) #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) diff --git a/arch/hexagon/include/uapi/asm/bitsperlong.h b/arch/hexagon/include/uapi/asm/bitsperlong.h index 4a658151383d..5adca0d26913 100644 --- a/arch/hexagon/include/uapi/asm/bitsperlong.h +++ b/arch/hexagon/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/byteorder.h b/arch/hexagon/include/uapi/asm/byteorder.h index e31f3f7d9a45..1364fa4b27e8 100644 --- a/arch/hexagon/include/uapi/asm/byteorder.h +++ b/arch/hexagon/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/kvm_para.h b/arch/hexagon/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/hexagon/include/uapi/asm/kvm_para.h +++ b/arch/hexagon/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/hexagon/include/uapi/asm/param.h b/arch/hexagon/include/uapi/asm/param.h index 5cec8c0417fb..a1283866d599 100644 --- a/arch/hexagon/include/uapi/asm/param.h +++ b/arch/hexagon/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/ptrace.h b/arch/hexagon/include/uapi/asm/ptrace.h index 065e5b32313f..f79de05b8689 100644 --- a/arch/hexagon/include/uapi/asm/ptrace.h +++ b/arch/hexagon/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Ptrace definitions for the Hexagon architecture * diff --git a/arch/hexagon/include/uapi/asm/registers.h b/arch/hexagon/include/uapi/asm/registers.h index e7be31840a90..d51270f3b358 100644 --- a/arch/hexagon/include/uapi/asm/registers.h +++ b/arch/hexagon/include/uapi/asm/registers.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Register definitions for the Hexagon architecture */ diff --git a/arch/hexagon/include/uapi/asm/setup.h b/arch/hexagon/include/uapi/asm/setup.h index 7e3952d6221c..8ce9428b1583 100644 --- a/arch/hexagon/include/uapi/asm/setup.h +++ b/arch/hexagon/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/sigcontext.h b/arch/hexagon/include/uapi/asm/sigcontext.h index b6ba5369ccc6..7171edb1b8b7 100644 --- a/arch/hexagon/include/uapi/asm/sigcontext.h +++ b/arch/hexagon/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/signal.h b/arch/hexagon/include/uapi/asm/signal.h index 24b998888916..a08fc425387d 100644 --- a/arch/hexagon/include/uapi/asm/signal.h +++ b/arch/hexagon/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/swab.h b/arch/hexagon/include/uapi/asm/swab.h index 9069e9247a2e..b39f12104da4 100644 --- a/arch/hexagon/include/uapi/asm/swab.h +++ b/arch/hexagon/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/unistd.h b/arch/hexagon/include/uapi/asm/unistd.h index 21517600432b..ea181e79162e 100644 --- a/arch/hexagon/include/uapi/asm/unistd.h +++ b/arch/hexagon/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Syscall support for Hexagon * diff --git a/arch/hexagon/include/uapi/asm/user.h b/arch/hexagon/include/uapi/asm/user.h index 3dae94d9ced7..7327ec59b22f 100644 --- a/arch/hexagon/include/uapi/asm/user.h +++ b/arch/hexagon/include/uapi/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef HEXAGON_ASM_USER_H #define HEXAGON_ASM_USER_H diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile index 009228b8611c..fae3dce32fde 100644 --- a/arch/hexagon/kernel/Makefile +++ b/arch/hexagon/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 extra-y := head.o vmlinux.lds obj-$(CONFIG_SMP) += smp.o diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 6a15083cc366..1efc444f5fa1 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PGTABLE_LEVELS int "Page Table Levels" if !IA64_PAGE_SIZE_64KB range 3 4 if !IA64_PAGE_SIZE_64KB diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug index de9d507ba0fd..677c409425df 100644 --- a/arch/ia64/Kconfig.debug +++ b/arch/ia64/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" @@ -56,9 +57,4 @@ config IA64_DEBUG_IRQ and restore instructions. It's useful for tracking down spinlock problems, but slow! If you're unsure, select N. -config SYSVIPC_COMPAT - bool - depends on COMPAT && SYSVIPC - default y - endmenu diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile index ae16ec4f6308..e7f830825470 100644 --- a/arch/ia64/dig/Makefile +++ b/arch/ia64/dig/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # ia64/platform/dig/Makefile # diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c index 98131e1db7a0..cc14fdce6db6 100644 --- a/arch/ia64/dig/setup.c +++ b/arch/ia64/dig/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Platform dependent support for DIG64 platforms. * diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 0310078a95f8..63d8e1d2477f 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2004 Hewlett-Packard Development Company, L.P. * Contributed by David Mosberger-Tang diff --git a/arch/ia64/hp/sim/Kconfig b/arch/ia64/hp/sim/Kconfig index d84707d55203..56fb4f1d4f7c 100644 --- a/arch/ia64/hp/sim/Kconfig +++ b/arch/ia64/hp/sim/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "HP Simulator drivers" depends on IA64_HP_SIM || IA64_GENERIC diff --git a/arch/ia64/hp/sim/Makefile b/arch/ia64/hp/sim/Makefile index d10da47931d7..0224a13d2c5b 100644 --- a/arch/ia64/hp/sim/Makefile +++ b/arch/ia64/hp/sim/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # ia64/platform/hp/sim/Makefile # diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S index 8808565491fb..a7d178fb41e8 100644 --- a/arch/ia64/hp/sim/boot/boot_head.S +++ b/arch/ia64/hp/sim/boot/boot_head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang diff --git a/arch/ia64/hp/sim/boot/bootloader.c b/arch/ia64/hp/sim/boot/bootloader.c index 28f4b230b8cb..6d804608dc81 100644 --- a/arch/ia64/hp/sim/boot/bootloader.c +++ b/arch/ia64/hp/sim/boot/bootloader.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/ia64/hp/sim/boot/bootloader.c * diff --git a/arch/ia64/hp/sim/boot/bootloader.lds b/arch/ia64/hp/sim/boot/bootloader.lds index 3977f25a1265..f3f284d6514c 100644 --- a/arch/ia64/hp/sim/boot/bootloader.lds +++ b/arch/ia64/hp/sim/boot/bootloader.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ OUTPUT_FORMAT("elf64-ia64-little") OUTPUT_ARCH(ia64) ENTRY(_start) diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c index 87bf9ad8cf0f..517fb2822e04 100644 --- a/arch/ia64/hp/sim/boot/fw-emu.c +++ b/arch/ia64/hp/sim/boot/fw-emu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PAL & SAL emulation. * diff --git a/arch/ia64/hp/sim/boot/ssc.h b/arch/ia64/hp/sim/boot/ssc.h index 3b94c03e43a9..88752c7509e0 100644 --- a/arch/ia64/hp/sim/boot/ssc.h +++ b/arch/ia64/hp/sim/boot/ssc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1998-2003 Hewlett-Packard Co * David Mosberger-Tang diff --git a/arch/ia64/hp/sim/hpsim.S b/arch/ia64/hp/sim/hpsim.S index ff16e8a857d1..44b4d53e1689 100644 --- a/arch/ia64/hp/sim/hpsim.S +++ b/arch/ia64/hp/sim/hpsim.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/ia64/hp/sim/hpsim_console.c b/arch/ia64/hp/sim/hpsim_console.c index 01663bc42b1a..bffd9f67a8a1 100644 --- a/arch/ia64/hp/sim/hpsim_console.c +++ b/arch/ia64/hp/sim/hpsim_console.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Platform dependent support for HP simulator. * diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c index 0aa70ebda49d..2f1cc59650ab 100644 --- a/arch/ia64/hp/sim/hpsim_irq.c +++ b/arch/ia64/hp/sim/hpsim_irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Platform dependent support for HP simulator. * diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c index 664a5402a695..41d21d51dc4d 100644 --- a/arch/ia64/hp/sim/hpsim_setup.c +++ b/arch/ia64/hp/sim/hpsim_setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Platform dependent support for HP simulator. * diff --git a/arch/ia64/hp/sim/hpsim_ssc.h b/arch/ia64/hp/sim/hpsim_ssc.h index bfa3906274b3..6fd97a487811 100644 --- a/arch/ia64/hp/sim/hpsim_ssc.h +++ b/arch/ia64/hp/sim/hpsim_ssc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Platform dependent support for HP simulator. * diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index d1b04c4c95e3..f39ef2b4ed72 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Simulated Ethernet Driver * diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index 085047f3a545..7e1426e76d96 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Simulated SCSI driver. * diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 70d52e9bb575..a419ccf33cde 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Simulated Serial Driver (fake serial) * diff --git a/arch/ia64/include/asm/agp.h b/arch/ia64/include/asm/agp.h index 01d09c401c5c..2b451c4496da 100644 --- a/arch/ia64/include/asm/agp.h +++ b/arch/ia64/include/asm/agp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_AGP_H #define _ASM_IA64_AGP_H diff --git a/arch/ia64/include/asm/asm-prototypes.h b/arch/ia64/include/asm/asm-prototypes.h index a2c139808cfe..c711536674e3 100644 --- a/arch/ia64/include/asm/asm-prototypes.h +++ b/arch/ia64/include/asm/asm-prototypes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_ASM_PROTOTYPES_H #define _ASM_IA64_ASM_PROTOTYPES_H diff --git a/arch/ia64/include/asm/asmmacro.h b/arch/ia64/include/asm/asmmacro.h index 3ab6d75aa3db..52619c517f09 100644 --- a/arch/ia64/include/asm/asmmacro.h +++ b/arch/ia64/include/asm/asmmacro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_ASMMACRO_H #define _ASM_IA64_ASMMACRO_H diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index 65d4bb2b6685..28e02c99be6d 100644 --- a/arch/ia64/include/asm/atomic.h +++ b/arch/ia64/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_ATOMIC_H #define _ASM_IA64_ATOMIC_H diff --git a/arch/ia64/include/asm/barrier.h b/arch/ia64/include/asm/barrier.h index 588f1614cafc..751cdd353446 100644 --- a/arch/ia64/include/asm/barrier.h +++ b/arch/ia64/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Memory barrier definitions. This is based on information published * in the Processor Abstraction Layer and the System Abstraction Layer diff --git a/arch/ia64/include/asm/bitops.h b/arch/ia64/include/asm/bitops.h index 71e8145243ee..56a774bf13fa 100644 --- a/arch/ia64/include/asm/bitops.h +++ b/arch/ia64/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_BITOPS_H #define _ASM_IA64_BITOPS_H diff --git a/arch/ia64/include/asm/bug.h b/arch/ia64/include/asm/bug.h index 823616b5020b..bd3eeb8d1cfa 100644 --- a/arch/ia64/include/asm/bug.h +++ b/arch/ia64/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_BUG_H #define _ASM_IA64_BUG_H diff --git a/arch/ia64/include/asm/bugs.h b/arch/ia64/include/asm/bugs.h index 433523e3b2ed..0d6b9bded56c 100644 --- a/arch/ia64/include/asm/bugs.h +++ b/arch/ia64/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is included by init/main.c to check for architecture-dependent bugs. * diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h index 988254a7d349..4eb6f742d14f 100644 --- a/arch/ia64/include/asm/cache.h +++ b/arch/ia64/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_CACHE_H #define _ASM_IA64_CACHE_H diff --git a/arch/ia64/include/asm/cacheflush.h b/arch/ia64/include/asm/cacheflush.h index 429eefc93ee7..6d3478f8abc8 100644 --- a/arch/ia64/include/asm/cacheflush.h +++ b/arch/ia64/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_CACHEFLUSH_H #define _ASM_IA64_CACHEFLUSH_H diff --git a/arch/ia64/include/asm/checksum.h b/arch/ia64/include/asm/checksum.h index 7accf54162b2..0ed18bc3f6cf 100644 --- a/arch/ia64/include/asm/checksum.h +++ b/arch/ia64/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_CHECKSUM_H #define _ASM_IA64_CHECKSUM_H diff --git a/arch/ia64/include/asm/clocksource.h b/arch/ia64/include/asm/clocksource.h index 5c8596e4cb02..71a517751afa 100644 --- a/arch/ia64/include/asm/clocksource.h +++ b/arch/ia64/include/asm/clocksource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* IA64-specific clocksource additions */ #ifndef _ASM_IA64_CLOCKSOURCE_H diff --git a/arch/ia64/include/asm/cpu.h b/arch/ia64/include/asm/cpu.h index fcca30b9f110..db125df9e088 100644 --- a/arch/ia64/include/asm/cpu.h +++ b/arch/ia64/include/asm/cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_CPU_H_ #define _ASM_IA64_CPU_H_ diff --git a/arch/ia64/include/asm/current.h b/arch/ia64/include/asm/current.h index c659f90fbfd9..86fbcc88dff2 100644 --- a/arch/ia64/include/asm/current.h +++ b/arch/ia64/include/asm/current.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_CURRENT_H #define _ASM_IA64_CURRENT_H diff --git a/arch/ia64/include/asm/cyclone.h b/arch/ia64/include/asm/cyclone.h index 88f6500e84ab..a481393647e9 100644 --- a/arch/ia64/include/asm/cyclone.h +++ b/arch/ia64/include/asm/cyclone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_IA64_CYCLONE_H #define ASM_IA64_CYCLONE_H diff --git a/arch/ia64/include/asm/delay.h b/arch/ia64/include/asm/delay.h index a30a62f235e1..0227ac586107 100644 --- a/arch/ia64/include/asm/delay.h +++ b/arch/ia64/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_DELAY_H #define _ASM_IA64_DELAY_H diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h index 3ce5ab4339f3..5da9421fb0ff 100644 --- a/arch/ia64/include/asm/dma-mapping.h +++ b/arch/ia64/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_DMA_MAPPING_H #define _ASM_IA64_DMA_MAPPING_H diff --git a/arch/ia64/include/asm/dma.h b/arch/ia64/include/asm/dma.h index 4d97f60f1ef5..186850eec934 100644 --- a/arch/ia64/include/asm/dma.h +++ b/arch/ia64/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_DMA_H #define _ASM_IA64_DMA_H diff --git a/arch/ia64/include/asm/dmi.h b/arch/ia64/include/asm/dmi.h index f365a61f5c71..ecd9e0a0f5f9 100644 --- a/arch/ia64/include/asm/dmi.h +++ b/arch/ia64/include/asm/dmi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_DMI_H #define _ASM_DMI_H 1 diff --git a/arch/ia64/include/asm/early_ioremap.h b/arch/ia64/include/asm/early_ioremap.h index eec9e1d1b833..934191b1e2e3 100644 --- a/arch/ia64/include/asm/early_ioremap.h +++ b/arch/ia64/include/asm/early_ioremap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_EARLY_IOREMAP_H #define _ASM_IA64_EARLY_IOREMAP_H diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h index 5a83c5cc3dc8..c70bb9c11f52 100644 --- a/arch/ia64/include/asm/elf.h +++ b/arch/ia64/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_ELF_H #define _ASM_IA64_ELF_H diff --git a/arch/ia64/include/asm/esi.h b/arch/ia64/include/asm/esi.h index 40991c6ba647..56d1310af06e 100644 --- a/arch/ia64/include/asm/esi.h +++ b/arch/ia64/include/asm/esi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ESI service calls. * diff --git a/arch/ia64/include/asm/extable.h b/arch/ia64/include/asm/extable.h index 20376e71eab4..83eac6aa0639 100644 --- a/arch/ia64/include/asm/extable.h +++ b/arch/ia64/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_EXTABLE_H #define _ASM_IA64_EXTABLE_H diff --git a/arch/ia64/include/asm/fb.h b/arch/ia64/include/asm/fb.h index 89a397cee90a..5f95782bfa46 100644 --- a/arch/ia64/include/asm/fb.h +++ b/arch/ia64/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ diff --git a/arch/ia64/include/asm/fpswa.h b/arch/ia64/include/asm/fpswa.h index 62edfceadaa6..2a0c23728b26 100644 --- a/arch/ia64/include/asm/fpswa.h +++ b/arch/ia64/include/asm/fpswa.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_FPSWA_H #define _ASM_IA64_FPSWA_H diff --git a/arch/ia64/include/asm/ftrace.h b/arch/ia64/include/asm/ftrace.h index fbd1a2470cae..a07a8e575453 100644 --- a/arch/ia64/include/asm/ftrace.h +++ b/arch/ia64/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_FTRACE_H #define _ASM_IA64_FTRACE_H diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h index 76acbcd5c060..db2dd85918c2 100644 --- a/arch/ia64/include/asm/futex.h +++ b/arch/ia64/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FUTEX_H #define _ASM_FUTEX_H @@ -45,18 +46,9 @@ do { \ } while (0) static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -84,17 +76,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/ia64/include/asm/gcc_intrin.h b/arch/ia64/include/asm/gcc_intrin.h index f9495b1757a8..83f230b23867 100644 --- a/arch/ia64/include/asm/gcc_intrin.h +++ b/arch/ia64/include/asm/gcc_intrin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Copyright (C) 2002,2003 Jun Nakajima diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h index 8fb7d33a661f..bdc4669c71c3 100644 --- a/arch/ia64/include/asm/hardirq.h +++ b/arch/ia64/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_HARDIRQ_H #define _ASM_IA64_HARDIRQ_H diff --git a/arch/ia64/include/asm/hpsim.h b/arch/ia64/include/asm/hpsim.h index 0fe50225daa4..00fbd5cc8ab8 100644 --- a/arch/ia64/include/asm/hpsim.h +++ b/arch/ia64/include/asm/hpsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMIA64_HPSIM_H #define _ASMIA64_HPSIM_H diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h index ef65f026b11e..74d2a5540aaf 100644 --- a/arch/ia64/include/asm/hugetlb.h +++ b/arch/ia64/include/asm/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_HUGETLB_H #define _ASM_IA64_HUGETLB_H diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h index 74347ebf7d68..5dd3c6485c3a 100644 --- a/arch/ia64/include/asm/hw_irq.h +++ b/arch/ia64/include/asm/hw_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_HW_IRQ_H #define _ASM_IA64_HW_IRQ_H diff --git a/arch/ia64/include/asm/idle.h b/arch/ia64/include/asm/idle.h index b7685015a8ba..97c55b97e0ba 100644 --- a/arch/ia64/include/asm/idle.h +++ b/arch/ia64/include/asm/idle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_IDLE_H #define _ASM_IA64_IDLE_H diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h index ec970a920132..035b17fe12ef 100644 --- a/arch/ia64/include/asm/intrinsics.h +++ b/arch/ia64/include/asm/intrinsics.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Compiler-dependent intrinsics. * diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index a2540e21f919..fb0651961e2c 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_IO_H #define _ASM_IA64_IO_H diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h index 1d1212901ae7..156b9d8e1932 100644 --- a/arch/ia64/include/asm/iommu.h +++ b/arch/ia64/include/asm/iommu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_IOMMU_H #define _ASM_IA64_IOMMU_H 1 diff --git a/arch/ia64/include/asm/iommu_table.h b/arch/ia64/include/asm/iommu_table.h index 92c8d36ae5ae..cc96116ac276 100644 --- a/arch/ia64/include/asm/iommu_table.h +++ b/arch/ia64/include/asm/iommu_table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_IOMMU_TABLE_H #define _ASM_IA64_IOMMU_TABLE_H diff --git a/arch/ia64/include/asm/iosapic.h b/arch/ia64/include/asm/iosapic.h index 4ae1fbd7f10e..f48556cb8afc 100644 --- a/arch/ia64/include/asm/iosapic.h +++ b/arch/ia64/include/asm/iosapic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_IA64_IOSAPIC_H #define __ASM_IA64_IOSAPIC_H diff --git a/arch/ia64/include/asm/irq.h b/arch/ia64/include/asm/irq.h index 820667cbea7e..8b84a55ed38a 100644 --- a/arch/ia64/include/asm/irq.h +++ b/arch/ia64/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_IRQ_H #define _ASM_IA64_IRQ_H diff --git a/arch/ia64/include/asm/irq_remapping.h b/arch/ia64/include/asm/irq_remapping.h index a8687b1d8906..547a6e87018c 100644 --- a/arch/ia64/include/asm/irq_remapping.h +++ b/arch/ia64/include/asm/irq_remapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __IA64_INTR_REMAPPING_H #define __IA64_INTR_REMAPPING_H #define irq_remapping_enabled 0 diff --git a/arch/ia64/include/asm/irqflags.h b/arch/ia64/include/asm/irqflags.h index cec6c06b52c0..d97f8435be4f 100644 --- a/arch/ia64/include/asm/irqflags.h +++ b/arch/ia64/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IRQ flags defines. * diff --git a/arch/ia64/include/asm/kexec.h b/arch/ia64/include/asm/kexec.h index aea2b81b03a3..294b1e1ebd2d 100644 --- a/arch/ia64/include/asm/kexec.h +++ b/arch/ia64/include/asm/kexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_KEXEC_H #define _ASM_IA64_KEXEC_H diff --git a/arch/ia64/include/asm/kmap_types.h b/arch/ia64/include/asm/kmap_types.h index 05d5f9996105..5c268cf7c2bd 100644 --- a/arch/ia64/include/asm/kmap_types.h +++ b/arch/ia64/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_KMAP_TYPES_H #define _ASM_IA64_KMAP_TYPES_H diff --git a/arch/ia64/include/asm/kregs.h b/arch/ia64/include/asm/kregs.h index 39e65f6639f5..44113b75e4eb 100644 --- a/arch/ia64/include/asm/kregs.h +++ b/arch/ia64/include/asm/kregs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_KREGS_H #define _ASM_IA64_KREGS_H diff --git a/arch/ia64/include/asm/libata-portmap.h b/arch/ia64/include/asm/libata-portmap.h index 7a1f8310596b..757f84e5dc6e 100644 --- a/arch/ia64/include/asm/libata-portmap.h +++ b/arch/ia64/include/asm/libata-portmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_IA64_LIBATA_PORTMAP_H #define __ASM_IA64_LIBATA_PORTMAP_H diff --git a/arch/ia64/include/asm/linkage.h b/arch/ia64/include/asm/linkage.h index 787575701f1c..5178af560925 100644 --- a/arch/ia64/include/asm/linkage.h +++ b/arch/ia64/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h index af285c423e1e..267f4f170191 100644 --- a/arch/ia64/include/asm/machvec.h +++ b/arch/ia64/include/asm/machvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine vector for IA-64. * diff --git a/arch/ia64/include/asm/machvec_dig.h b/arch/ia64/include/asm/machvec_dig.h index 1f7403a2fbee..bc230f69faeb 100644 --- a/arch/ia64/include/asm/machvec_dig.h +++ b/arch/ia64/include/asm/machvec_dig.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_MACHVEC_DIG_h #define _ASM_IA64_MACHVEC_DIG_h diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h index 44308b4c3f6e..bb44eb9039dd 100644 --- a/arch/ia64/include/asm/machvec_dig_vtd.h +++ b/arch/ia64/include/asm/machvec_dig_vtd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_MACHVEC_DIG_VTD_h #define _ASM_IA64_MACHVEC_DIG_VTD_h diff --git a/arch/ia64/include/asm/machvec_hpsim.h b/arch/ia64/include/asm/machvec_hpsim.h index e75711279366..056f8405822e 100644 --- a/arch/ia64/include/asm/machvec_hpsim.h +++ b/arch/ia64/include/asm/machvec_hpsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_MACHVEC_HPSIM_h #define _ASM_IA64_MACHVEC_HPSIM_h diff --git a/arch/ia64/include/asm/machvec_hpzx1.h b/arch/ia64/include/asm/machvec_hpzx1.h index c74d3159e9eb..5299ac38bfb6 100644 --- a/arch/ia64/include/asm/machvec_hpzx1.h +++ b/arch/ia64/include/asm/machvec_hpzx1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_MACHVEC_HPZX1_h #define _ASM_IA64_MACHVEC_HPZX1_h diff --git a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h index 906ef6210774..5aec6a008c61 100644 --- a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h +++ b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h #define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h diff --git a/arch/ia64/include/asm/machvec_init.h b/arch/ia64/include/asm/machvec_init.h index 37a469849ab9..2b32fd06b7c6 100644 --- a/arch/ia64/include/asm/machvec_init.h +++ b/arch/ia64/include/asm/machvec_init.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/ia64/include/asm/mca.h b/arch/ia64/include/asm/mca.h index 8c7096168716..726df17f1b51 100644 --- a/arch/ia64/include/asm/mca.h +++ b/arch/ia64/include/asm/mca.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File: mca.h * Purpose: Machine check handling specific defines diff --git a/arch/ia64/include/asm/mca_asm.h b/arch/ia64/include/asm/mca_asm.h index 13c1d4994d49..e3ab1f41f1c3 100644 --- a/arch/ia64/include/asm/mca_asm.h +++ b/arch/ia64/include/asm/mca_asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File: mca_asm.h * Purpose: Machine check handling specific defines diff --git a/arch/ia64/include/asm/mman.h b/arch/ia64/include/asm/mman.h index fdd5f5229f78..15cf100add0e 100644 --- a/arch/ia64/include/asm/mman.h +++ b/arch/ia64/include/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Based on . * diff --git a/arch/ia64/include/asm/mmu.h b/arch/ia64/include/asm/mmu.h index 611432ba579c..f75f44f531c2 100644 --- a/arch/ia64/include/asm/mmu.h +++ b/arch/ia64/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MMU_H #define __MMU_H diff --git a/arch/ia64/include/asm/mmu_context.h b/arch/ia64/include/asm/mmu_context.h index 9b99368633b5..2da0e2eb036b 100644 --- a/arch/ia64/include/asm/mmu_context.h +++ b/arch/ia64/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_MMU_CONTEXT_H #define _ASM_IA64_MMU_CONTEXT_H diff --git a/arch/ia64/include/asm/module.h b/arch/ia64/include/asm/module.h index f31894b2a354..f319144260ce 100644 --- a/arch/ia64/include/asm/module.h +++ b/arch/ia64/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_MODULE_H #define _ASM_IA64_MODULE_H diff --git a/arch/ia64/include/asm/msidef.h b/arch/ia64/include/asm/msidef.h index 592c1047a0c5..18d0e4226748 100644 --- a/arch/ia64/include/asm/msidef.h +++ b/arch/ia64/include/asm/msidef.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IA64_MSI_DEF_H #define _IA64_MSI_DEF_H diff --git a/arch/ia64/include/asm/page.h b/arch/ia64/include/asm/page.h index e8c486ef0d76..5798bd2b462c 100644 --- a/arch/ia64/include/asm/page.h +++ b/arch/ia64/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PAGE_H #define _ASM_IA64_PAGE_H /* diff --git a/arch/ia64/include/asm/pal.h b/arch/ia64/include/asm/pal.h index 2e69284df8e7..f9d2b3b2dfad 100644 --- a/arch/ia64/include/asm/pal.h +++ b/arch/ia64/include/asm/pal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PAL_H #define _ASM_IA64_PAL_H diff --git a/arch/ia64/include/asm/param.h b/arch/ia64/include/asm/param.h index 1295913d6a82..f0b786227c40 100644 --- a/arch/ia64/include/asm/param.h +++ b/arch/ia64/include/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Fundamental kernel parameters. * diff --git a/arch/ia64/include/asm/parport.h b/arch/ia64/include/asm/parport.h index 638b4d271b99..360ca9bf2f6f 100644 --- a/arch/ia64/include/asm/parport.h +++ b/arch/ia64/include/asm/parport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * parport.h: platform-specific PC-style parport initialisation * diff --git a/arch/ia64/include/asm/patch.h b/arch/ia64/include/asm/patch.h index 295fe6ab4584..bd487ed22bf5 100644 --- a/arch/ia64/include/asm/patch.h +++ b/arch/ia64/include/asm/patch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PATCH_H #define _ASM_IA64_PATCH_H diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 6459f2d46200..e20d77f6a3c1 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PCI_H #define _ASM_IA64_PCI_H diff --git a/arch/ia64/include/asm/percpu.h b/arch/ia64/include/asm/percpu.h index b9295793a5e2..f357b9bb3576 100644 --- a/arch/ia64/include/asm/percpu.h +++ b/arch/ia64/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PERCPU_H #define _ASM_IA64_PERCPU_H diff --git a/arch/ia64/include/asm/perfmon.h b/arch/ia64/include/asm/perfmon.h index 15476dd3a8b0..e0545869cc8c 100644 --- a/arch/ia64/include/asm/perfmon.h +++ b/arch/ia64/include/asm/perfmon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2001-2003 Hewlett-Packard Co * Stephane Eranian diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h index f5e70e961948..3ee5362f2661 100644 --- a/arch/ia64/include/asm/pgalloc.h +++ b/arch/ia64/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PGALLOC_H #define _ASM_IA64_PGALLOC_H diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h index 6cc22c8d8923..165827774bea 100644 --- a/arch/ia64/include/asm/pgtable.h +++ b/arch/ia64/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PGTABLE_H #define _ASM_IA64_PGTABLE_H diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index ab982f07ea68..10061ccf0440 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_PROCESSOR_H #define _ASM_IA64_PROCESSOR_H diff --git a/arch/ia64/include/asm/ptrace.h b/arch/ia64/include/asm/ptrace.h index 845143990a1d..7ff574d56429 100644 --- a/arch/ia64/include/asm/ptrace.h +++ b/arch/ia64/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1998-2004 Hewlett-Packard Co * David Mosberger-Tang diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h index 8fa98dd303b4..7d6fceb3d567 100644 --- a/arch/ia64/include/asm/rwsem.h +++ b/arch/ia64/include/asm/rwsem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * R/W semaphores for ia64 * diff --git a/arch/ia64/include/asm/sal.h b/arch/ia64/include/asm/sal.h index e504f382115e..588f33156da6 100644 --- a/arch/ia64/include/asm/sal.h +++ b/arch/ia64/include/asm/sal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_SAL_H #define _ASM_IA64_SAL_H diff --git a/arch/ia64/include/asm/sections.h b/arch/ia64/include/asm/sections.h index 2ab2003698ef..f3481408594e 100644 --- a/arch/ia64/include/asm/sections.h +++ b/arch/ia64/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_SECTIONS_H #define _ASM_IA64_SECTIONS_H diff --git a/arch/ia64/include/asm/shmparam.h b/arch/ia64/include/asm/shmparam.h index d07508dc54ae..43bd8324ab71 100644 --- a/arch/ia64/include/asm/shmparam.h +++ b/arch/ia64/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_SHMPARAM_H #define _ASM_IA64_SHMPARAM_H diff --git a/arch/ia64/include/asm/signal.h b/arch/ia64/include/asm/signal.h index c62afa4a0dc2..80f067f9b3ce 100644 --- a/arch/ia64/include/asm/signal.h +++ b/arch/ia64/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Modified 1998-2001, 2003 * David Mosberger-Tang , Hewlett-Packard Co diff --git a/arch/ia64/include/asm/smp.h b/arch/ia64/include/asm/smp.h index fea21e986022..7847ae40a181 100644 --- a/arch/ia64/include/asm/smp.h +++ b/arch/ia64/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * SMP Support * diff --git a/arch/ia64/include/asm/sn/ioc3.h b/arch/ia64/include/asm/sn/ioc3.h index 6eaa3cc1e919..d4a524951df3 100644 --- a/arch/ia64/include/asm/sn/ioc3.h +++ b/arch/ia64/include/asm/sn/ioc3.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2005 Silicon Graphics, Inc. */ diff --git a/arch/ia64/include/asm/sparsemem.h b/arch/ia64/include/asm/sparsemem.h index 67a7c40ec27f..336d0570e1fa 100644 --- a/arch/ia64/include/asm/sparsemem.h +++ b/arch/ia64/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_SPARSEMEM_H #define _ASM_IA64_SPARSEMEM_H diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h index ca9e76149a4a..aa057abd948e 100644 --- a/arch/ia64/include/asm/spinlock.h +++ b/arch/ia64/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_SPINLOCK_H #define _ASM_IA64_SPINLOCK_H @@ -76,22 +77,6 @@ static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock) ACCESS_ONCE(*p) = (tmp + 2) & ~1; } -static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock) -{ - int *p = (int *)&lock->lock, ticket; - - ia64_invala(); - - for (;;) { - asm volatile ("ld4.c.nc %0=[%1]" : "=r"(ticket) : "r"(p) : "memory"); - if (!(((ticket >> TICKET_SHIFT) ^ ticket) & TICKET_MASK)) - return; - cpu_relax(); - } - - smp_acquire__after_ctrl_dep(); -} - static inline int __ticket_spin_is_locked(arch_spinlock_t *lock) { long tmp = ACCESS_ONCE(lock->lock); @@ -143,11 +128,6 @@ static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock, arch_spin_lock(lock); } -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - __ticket_spin_unlock_wait(lock); -} - #define arch_read_can_lock(rw) (*(volatile int *)(rw) >= 0) #define arch_write_can_lock(rw) (*(volatile int *)(rw) == 0) diff --git a/arch/ia64/include/asm/spinlock_types.h b/arch/ia64/include/asm/spinlock_types.h index e2b42a52a6d3..6e345fefcdca 100644 --- a/arch/ia64/include/asm/spinlock_types.h +++ b/arch/ia64/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_SPINLOCK_TYPES_H #define _ASM_IA64_SPINLOCK_TYPES_H diff --git a/arch/ia64/include/asm/string.h b/arch/ia64/include/asm/string.h index 85fd65c52a8c..8b84df0dbfad 100644 --- a/arch/ia64/include/asm/string.h +++ b/arch/ia64/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_STRING_H #define _ASM_IA64_STRING_H diff --git a/arch/ia64/include/asm/swiotlb.h b/arch/ia64/include/asm/swiotlb.h index f0acde68aaea..841e2c7d0b21 100644 --- a/arch/ia64/include/asm/swiotlb.h +++ b/arch/ia64/include/asm/swiotlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_IA64__SWIOTLB_H #define ASM_IA64__SWIOTLB_H diff --git a/arch/ia64/include/asm/switch_to.h b/arch/ia64/include/asm/switch_to.h index e8f3585e7e7a..b10f31ec522c 100644 --- a/arch/ia64/include/asm/switch_to.h +++ b/arch/ia64/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Low-level task switching. This is based on information published in * the Processor Abstraction Layer and the System Abstraction Layer diff --git a/arch/ia64/include/asm/termios.h b/arch/ia64/include/asm/termios.h index a42f870ca4f6..589c026444cc 100644 --- a/arch/ia64/include/asm/termios.h +++ b/arch/ia64/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Modified 1999 * David Mosberger-Tang , Hewlett-Packard Co diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index 8742d741d19a..1d172a4119a7 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002-2003 Hewlett-Packard Co * David Mosberger-Tang diff --git a/arch/ia64/include/asm/timex.h b/arch/ia64/include/asm/timex.h index 86c7db861180..869a3ac6bf23 100644 --- a/arch/ia64/include/asm/timex.h +++ b/arch/ia64/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_TIMEX_H #define _ASM_IA64_TIMEX_H diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h index cbe5ac3699bf..44f0ac0df308 100644 --- a/arch/ia64/include/asm/tlb.h +++ b/arch/ia64/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_TLB_H #define _ASM_IA64_TLB_H /* diff --git a/arch/ia64/include/asm/tlbflush.h b/arch/ia64/include/asm/tlbflush.h index 3be25dfed164..25e280810f6c 100644 --- a/arch/ia64/include/asm/tlbflush.h +++ b/arch/ia64/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_TLBFLUSH_H #define _ASM_IA64_TLBFLUSH_H diff --git a/arch/ia64/include/asm/types.h b/arch/ia64/include/asm/types.h index 4c351b169da2..5ddc7703de99 100644 --- a/arch/ia64/include/asm/types.h +++ b/arch/ia64/include/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is never included by application software unless explicitly * requested (e.g., via linux/types.h) in which case the application is diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h index 0890ded638f0..a74524f2d625 100644 --- a/arch/ia64/include/asm/uaccess.h +++ b/arch/ia64/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_UACCESS_H #define _ASM_IA64_UACCESS_H diff --git a/arch/ia64/include/asm/unaligned.h b/arch/ia64/include/asm/unaligned.h index 7bddc7f58584..328942e3cbce 100644 --- a/arch/ia64/include/asm/unaligned.h +++ b/arch/ia64/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_UNALIGNED_H #define _ASM_IA64_UNALIGNED_H diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 8c85209753ab..ffb705dc9c13 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IA-64 Linux syscall numbers and inline-functions. * diff --git a/arch/ia64/include/asm/unwind.h b/arch/ia64/include/asm/unwind.h index 1af3875f1a57..c5bd4b3e3a36 100644 --- a/arch/ia64/include/asm/unwind.h +++ b/arch/ia64/include/asm/unwind.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_UNWIND_H #define _ASM_IA64_UNWIND_H diff --git a/arch/ia64/include/asm/user.h b/arch/ia64/include/asm/user.h index 8b9821110348..0ba486651b7c 100644 --- a/arch/ia64/include/asm/user.h +++ b/arch/ia64/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_USER_H #define _ASM_IA64_USER_H diff --git a/arch/ia64/include/asm/ustack.h b/arch/ia64/include/asm/ustack.h index b275401b96d3..112d40a0fec2 100644 --- a/arch/ia64/include/asm/ustack.h +++ b/arch/ia64/include/asm/ustack.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_USTACK_H #define _ASM_IA64_USTACK_H diff --git a/arch/ia64/include/asm/uv/uv.h b/arch/ia64/include/asm/uv/uv.h index 8f6cbaa742e9..71df93ee3bc0 100644 --- a/arch/ia64/include/asm/uv/uv.h +++ b/arch/ia64/include/asm/uv/uv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IA64_UV_UV_H #define _ASM_IA64_UV_UV_H diff --git a/arch/ia64/include/asm/vga.h b/arch/ia64/include/asm/vga.h index 02184ecd8208..30cb373f3de8 100644 --- a/arch/ia64/include/asm/vga.h +++ b/arch/ia64/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access to VGA videoram * diff --git a/arch/ia64/include/uapi/asm/auxvec.h b/arch/ia64/include/uapi/asm/auxvec.h index 58277fc650ef..09969a5d2e0a 100644 --- a/arch/ia64/include/uapi/asm/auxvec.h +++ b/arch/ia64/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_AUXVEC_H #define _ASM_IA64_AUXVEC_H diff --git a/arch/ia64/include/uapi/asm/bitsperlong.h b/arch/ia64/include/uapi/asm/bitsperlong.h index ec4db3c970b7..1146d55563db 100644 --- a/arch/ia64/include/uapi/asm/bitsperlong.h +++ b/arch/ia64/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_IA64_BITSPERLONG_H #define __ASM_IA64_BITSPERLONG_H diff --git a/arch/ia64/include/uapi/asm/break.h b/arch/ia64/include/uapi/asm/break.h index f03402039896..5d742bcb0018 100644 --- a/arch/ia64/include/uapi/asm/break.h +++ b/arch/ia64/include/uapi/asm/break.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_BREAK_H #define _ASM_IA64_BREAK_H diff --git a/arch/ia64/include/uapi/asm/byteorder.h b/arch/ia64/include/uapi/asm/byteorder.h index a8dd73558150..f85d0faaaf34 100644 --- a/arch/ia64/include/uapi/asm/byteorder.h +++ b/arch/ia64/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_BYTEORDER_H #define _ASM_IA64_BYTEORDER_H diff --git a/arch/ia64/include/uapi/asm/cmpxchg.h b/arch/ia64/include/uapi/asm/cmpxchg.h index a0e3620f8f13..d69c979936d4 100644 --- a/arch/ia64/include/uapi/asm/cmpxchg.h +++ b/arch/ia64/include/uapi/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_CMPXCHG_H #define _ASM_IA64_CMPXCHG_H diff --git a/arch/ia64/include/uapi/asm/errno.h b/arch/ia64/include/uapi/asm/errno.h index 4c82b503d92f..9addba592646 100644 --- a/arch/ia64/include/uapi/asm/errno.h +++ b/arch/ia64/include/uapi/asm/errno.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/ia64/include/uapi/asm/fcntl.h b/arch/ia64/include/uapi/asm/fcntl.h index 7b485876cad4..7b95523efe5a 100644 --- a/arch/ia64/include/uapi/asm/fcntl.h +++ b/arch/ia64/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_FCNTL_H #define _ASM_IA64_FCNTL_H /* diff --git a/arch/ia64/include/uapi/asm/fpu.h b/arch/ia64/include/uapi/asm/fpu.h index b6395ad1500a..0df392982ce8 100644 --- a/arch/ia64/include/uapi/asm/fpu.h +++ b/arch/ia64/include/uapi/asm/fpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_FPU_H #define _ASM_IA64_FPU_H diff --git a/arch/ia64/include/uapi/asm/gcc_intrin.h b/arch/ia64/include/uapi/asm/gcc_intrin.h index 61d0d0111978..c60696fd1e37 100644 --- a/arch/ia64/include/uapi/asm/gcc_intrin.h +++ b/arch/ia64/include/uapi/asm/gcc_intrin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * * Copyright (C) 2002,2003 Jun Nakajima diff --git a/arch/ia64/include/uapi/asm/ia64regs.h b/arch/ia64/include/uapi/asm/ia64regs.h index 1757f1c11ad4..d7d10cec8b9f 100644 --- a/arch/ia64/include/uapi/asm/ia64regs.h +++ b/arch/ia64/include/uapi/asm/ia64regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2002,2003 Intel Corp. * Jun Nakajima diff --git a/arch/ia64/include/uapi/asm/intel_intrin.h b/arch/ia64/include/uapi/asm/intel_intrin.h index 53cec577558a..ab649691545a 100644 --- a/arch/ia64/include/uapi/asm/intel_intrin.h +++ b/arch/ia64/include/uapi/asm/intel_intrin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_INTEL_INTRIN_H #define _ASM_IA64_INTEL_INTRIN_H /* diff --git a/arch/ia64/include/uapi/asm/intrinsics.h b/arch/ia64/include/uapi/asm/intrinsics.h index 5829978ff466..aecc217eca63 100644 --- a/arch/ia64/include/uapi/asm/intrinsics.h +++ b/arch/ia64/include/uapi/asm/intrinsics.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Compiler-dependent intrinsics. * diff --git a/arch/ia64/include/uapi/asm/ioctl.h b/arch/ia64/include/uapi/asm/ioctl.h index b279fe06dfe5..b809c4566e5f 100644 --- a/arch/ia64/include/uapi/asm/ioctl.h +++ b/arch/ia64/include/uapi/asm/ioctl.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/ia64/include/uapi/asm/ioctls.h b/arch/ia64/include/uapi/asm/ioctls.h index f3aab5512e98..b86001940209 100644 --- a/arch/ia64/include/uapi/asm/ioctls.h +++ b/arch/ia64/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_IOCTLS_H #define _ASM_IA64_IOCTLS_H diff --git a/arch/ia64/include/uapi/asm/ipcbuf.h b/arch/ia64/include/uapi/asm/ipcbuf.h index 84c7e51cb6d0..90d6445a14df 100644 --- a/arch/ia64/include/uapi/asm/ipcbuf.h +++ b/arch/ia64/include/uapi/asm/ipcbuf.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/ia64/include/uapi/asm/mman.h b/arch/ia64/include/uapi/asm/mman.h index 8740819adc54..ce0cc3d7509e 100644 --- a/arch/ia64/include/uapi/asm/mman.h +++ b/arch/ia64/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Based on . * diff --git a/arch/ia64/include/uapi/asm/msgbuf.h b/arch/ia64/include/uapi/asm/msgbuf.h index 6c64c0d2aae1..aa25df92d9dc 100644 --- a/arch/ia64/include/uapi/asm/msgbuf.h +++ b/arch/ia64/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_MSGBUF_H #define _ASM_IA64_MSGBUF_H diff --git a/arch/ia64/include/uapi/asm/param.h b/arch/ia64/include/uapi/asm/param.h index d7da41d9497d..123ab45940b4 100644 --- a/arch/ia64/include/uapi/asm/param.h +++ b/arch/ia64/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Fundamental kernel parameters. * diff --git a/arch/ia64/include/uapi/asm/perfmon.h b/arch/ia64/include/uapi/asm/perfmon.h index 1a10a2dd58a1..017548365e5c 100644 --- a/arch/ia64/include/uapi/asm/perfmon.h +++ b/arch/ia64/include/uapi/asm/perfmon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2001-2003 Hewlett-Packard Co * Stephane Eranian diff --git a/arch/ia64/include/uapi/asm/perfmon_default_smpl.h b/arch/ia64/include/uapi/asm/perfmon_default_smpl.h index a2d560c67230..d3f36aff0e1f 100644 --- a/arch/ia64/include/uapi/asm/perfmon_default_smpl.h +++ b/arch/ia64/include/uapi/asm/perfmon_default_smpl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2002-2003 Hewlett-Packard Co * Stephane Eranian diff --git a/arch/ia64/include/uapi/asm/poll.h b/arch/ia64/include/uapi/asm/poll.h index c98509d3149e..b7132a305a47 100644 --- a/arch/ia64/include/uapi/asm/poll.h +++ b/arch/ia64/include/uapi/asm/poll.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/ia64/include/uapi/asm/posix_types.h b/arch/ia64/include/uapi/asm/posix_types.h index 99ee1d6510cf..bded40f7defe 100644 --- a/arch/ia64/include/uapi/asm/posix_types.h +++ b/arch/ia64/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_POSIX_TYPES_H #define _ASM_IA64_POSIX_TYPES_H diff --git a/arch/ia64/include/uapi/asm/ptrace.h b/arch/ia64/include/uapi/asm/ptrace.h index 0a02f634e12b..f52655b44414 100644 --- a/arch/ia64/include/uapi/asm/ptrace.h +++ b/arch/ia64/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 1998-2004 Hewlett-Packard Co * David Mosberger-Tang diff --git a/arch/ia64/include/uapi/asm/ptrace_offsets.h b/arch/ia64/include/uapi/asm/ptrace_offsets.h index b712773c759e..2847c18139ef 100644 --- a/arch/ia64/include/uapi/asm/ptrace_offsets.h +++ b/arch/ia64/include/uapi/asm/ptrace_offsets.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_PTRACE_OFFSETS_H #define _ASM_IA64_PTRACE_OFFSETS_H diff --git a/arch/ia64/include/uapi/asm/resource.h b/arch/ia64/include/uapi/asm/resource.h index ba2272a87fc7..d488d2b22ac4 100644 --- a/arch/ia64/include/uapi/asm/resource.h +++ b/arch/ia64/include/uapi/asm/resource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_RESOURCE_H #define _ASM_IA64_RESOURCE_H diff --git a/arch/ia64/include/uapi/asm/rse.h b/arch/ia64/include/uapi/asm/rse.h index 02830a3b0196..6d260af571c5 100644 --- a/arch/ia64/include/uapi/asm/rse.h +++ b/arch/ia64/include/uapi/asm/rse.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_RSE_H #define _ASM_IA64_RSE_H diff --git a/arch/ia64/include/uapi/asm/sembuf.h b/arch/ia64/include/uapi/asm/sembuf.h index 1340fbc04d3e..6ed058760afc 100644 --- a/arch/ia64/include/uapi/asm/sembuf.h +++ b/arch/ia64/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_SEMBUF_H #define _ASM_IA64_SEMBUF_H diff --git a/arch/ia64/include/uapi/asm/setup.h b/arch/ia64/include/uapi/asm/setup.h index 8d56458310b3..8d13ce8fb03a 100644 --- a/arch/ia64/include/uapi/asm/setup.h +++ b/arch/ia64/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __IA64_SETUP_H #define __IA64_SETUP_H diff --git a/arch/ia64/include/uapi/asm/shmbuf.h b/arch/ia64/include/uapi/asm/shmbuf.h index 585002a77acd..6ef57cb70dee 100644 --- a/arch/ia64/include/uapi/asm/shmbuf.h +++ b/arch/ia64/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_SHMBUF_H #define _ASM_IA64_SHMBUF_H diff --git a/arch/ia64/include/uapi/asm/sigcontext.h b/arch/ia64/include/uapi/asm/sigcontext.h index 57ff777bcc40..1bb6f0f2bd73 100644 --- a/arch/ia64/include/uapi/asm/sigcontext.h +++ b/arch/ia64/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_SIGCONTEXT_H #define _ASM_IA64_SIGCONTEXT_H diff --git a/arch/ia64/include/uapi/asm/siginfo.h b/arch/ia64/include/uapi/asm/siginfo.h index 4694c64252d6..f3a02a10c3a3 100644 --- a/arch/ia64/include/uapi/asm/siginfo.h +++ b/arch/ia64/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Based on . * @@ -98,27 +99,30 @@ typedef struct siginfo { /* * SIGILL si_codes */ -#define ILL_BADIADDR (__SI_FAULT|9) /* unimplemented instruction address */ -#define __ILL_BREAK (__SI_FAULT|10) /* illegal break */ -#define __ILL_BNDMOD (__SI_FAULT|11) /* bundle-update (modification) in progress */ +#define ILL_BADIADDR 9 /* unimplemented instruction address */ +#define __ILL_BREAK 10 /* illegal break */ +#define __ILL_BNDMOD 11 /* bundle-update (modification) in progress */ #undef NSIGILL #define NSIGILL 11 /* * SIGFPE si_codes */ -#define __FPE_DECOVF (__SI_FAULT|9) /* decimal overflow */ -#define __FPE_DECDIV (__SI_FAULT|10) /* decimal division by zero */ -#define __FPE_DECERR (__SI_FAULT|11) /* packed decimal error */ -#define __FPE_INVASC (__SI_FAULT|12) /* invalid ASCII digit */ -#define __FPE_INVDEC (__SI_FAULT|13) /* invalid decimal digit */ +#ifdef __KERNEL__ +#define FPE_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ +#define __FPE_DECOVF 9 /* decimal overflow */ +#define __FPE_DECDIV 10 /* decimal division by zero */ +#define __FPE_DECERR 11 /* packed decimal error */ +#define __FPE_INVASC 12 /* invalid ASCII digit */ +#define __FPE_INVDEC 13 /* invalid decimal digit */ #undef NSIGFPE #define NSIGFPE 13 /* * SIGSEGV si_codes */ -#define __SEGV_PSTKOVF (__SI_FAULT|4) /* paragraph stack overflow */ +#define __SEGV_PSTKOVF 4 /* paragraph stack overflow */ #undef NSIGSEGV #define NSIGSEGV 4 diff --git a/arch/ia64/include/uapi/asm/signal.h b/arch/ia64/include/uapi/asm/signal.h index c0ea2855e96b..aa98ff1b9e22 100644 --- a/arch/ia64/include/uapi/asm/signal.h +++ b/arch/ia64/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Modified 1998-2001, 2003 * David Mosberger-Tang , Hewlett-Packard Co diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index 5dd5c5d0d642..3efba40adc54 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_SOCKET_H #define _ASM_IA64_SOCKET_H @@ -111,4 +112,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/ia64/include/uapi/asm/sockios.h b/arch/ia64/include/uapi/asm/sockios.h index 15c92468ad38..f27a12f95d20 100644 --- a/arch/ia64/include/uapi/asm/sockios.h +++ b/arch/ia64/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_SOCKIOS_H #define _ASM_IA64_SOCKIOS_H diff --git a/arch/ia64/include/uapi/asm/stat.h b/arch/ia64/include/uapi/asm/stat.h index 367bb90cdffa..3265ed5aac0f 100644 --- a/arch/ia64/include/uapi/asm/stat.h +++ b/arch/ia64/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_STAT_H #define _ASM_IA64_STAT_H diff --git a/arch/ia64/include/uapi/asm/statfs.h b/arch/ia64/include/uapi/asm/statfs.h index 1e589669de56..de3bae4f137d 100644 --- a/arch/ia64/include/uapi/asm/statfs.h +++ b/arch/ia64/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_STATFS_H #define _ASM_IA64_STATFS_H diff --git a/arch/ia64/include/uapi/asm/swab.h b/arch/ia64/include/uapi/asm/swab.h index c89a8cb5d8a5..79f3fef1a05e 100644 --- a/arch/ia64/include/uapi/asm/swab.h +++ b/arch/ia64/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_SWAB_H #define _ASM_IA64_SWAB_H diff --git a/arch/ia64/include/uapi/asm/termbits.h b/arch/ia64/include/uapi/asm/termbits.h index c009b94e58d9..000a1a297c75 100644 --- a/arch/ia64/include/uapi/asm/termbits.h +++ b/arch/ia64/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_TERMBITS_H #define _ASM_IA64_TERMBITS_H diff --git a/arch/ia64/include/uapi/asm/termios.h b/arch/ia64/include/uapi/asm/termios.h index d59b48c307f8..199742d08f2c 100644 --- a/arch/ia64/include/uapi/asm/termios.h +++ b/arch/ia64/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Modified 1999 * David Mosberger-Tang , Hewlett-Packard Co diff --git a/arch/ia64/include/uapi/asm/types.h b/arch/ia64/include/uapi/asm/types.h index 321193b05eed..2000de474be6 100644 --- a/arch/ia64/include/uapi/asm/types.h +++ b/arch/ia64/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is never included by application software unless explicitly * requested (e.g., via linux/types.h) in which case the application is diff --git a/arch/ia64/include/uapi/asm/ucontext.h b/arch/ia64/include/uapi/asm/ucontext.h index bf573dc8ca6a..46f51e535e04 100644 --- a/arch/ia64/include/uapi/asm/ucontext.h +++ b/arch/ia64/include/uapi/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IA64_UCONTEXT_H #define _ASM_IA64_UCONTEXT_H diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h index ea5363daa7bd..5fe71d4a43de 100644 --- a/arch/ia64/include/uapi/asm/unistd.h +++ b/arch/ia64/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * IA-64 Linux syscall numbers and inline-functions. * diff --git a/arch/ia64/include/uapi/asm/ustack.h b/arch/ia64/include/uapi/asm/ustack.h index 1dfebc622692..703cc5f546ff 100644 --- a/arch/ia64/include/uapi/asm/ustack.h +++ b/arch/ia64/include/uapi/asm/ustack.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_IA64_USTACK_H #define _UAPI_ASM_IA64_USTACK_H diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 9edda5466020..14ad79f394e5 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/ia64/kernel/Makefile.gate b/arch/ia64/kernel/Makefile.gate index 7da7c65a9bb1..f53faf48b7ce 100644 --- a/arch/ia64/kernel/Makefile.gate +++ b/arch/ia64/kernel/Makefile.gate @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # The gate DSO image is built using a special linker script. targets += gate.so gate.lds gate.o gate-dummy.o diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 7508c306aa9e..1d29b2f8726b 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -159,12 +159,12 @@ int acpi_request_vector(u32 int_type) return vector; } -char *__init __acpi_map_table(unsigned long phys_addr, unsigned long size) +void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) { - return __va(phys_addr); + return __va(phys); } -void __init __acpi_unmap_table(char *map, unsigned long size) +void __init __acpi_unmap_table(void __iomem *map, unsigned long size) { } diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c index 798bdb209d00..b385ff2bf6ce 100644 --- a/arch/ia64/kernel/asm-offsets.c +++ b/arch/ia64/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generate definitions needed by assembly language modules. * This code generates raw asm output which is post-processed diff --git a/arch/ia64/kernel/audit.c b/arch/ia64/kernel/audit.c index 96a9d18ff4c4..5192ca899fe6 100644 --- a/arch/ia64/kernel/audit.c +++ b/arch/ia64/kernel/audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/ia64/kernel/brl_emu.c b/arch/ia64/kernel/brl_emu.c index 987b11be0021..9bcc908bc85e 100644 --- a/arch/ia64/kernel/brl_emu.c +++ b/arch/ia64/kernel/brl_emu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Emulation of the "brl" instruction for IA64 processors that * don't support it in hardware. diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c index 75859a07d75b..39f4433a6f0e 100644 --- a/arch/ia64/kernel/crash.c +++ b/arch/ia64/kernel/crash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/ia64/kernel/crash.c * diff --git a/arch/ia64/kernel/crash_dump.c b/arch/ia64/kernel/crash_dump.c index 9c12b794e774..0ed3c3dee4cd 100644 --- a/arch/ia64/kernel/crash_dump.c +++ b/arch/ia64/kernel/crash_dump.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * kernel/crash_dump.c - Memory preserving reboot related code. * diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c index ee1a4afbf9da..f80eb7fb544d 100644 --- a/arch/ia64/kernel/cyclone.c +++ b/arch/ia64/kernel/cyclone.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c index e0dd97f4eb69..7a82c9259609 100644 --- a/arch/ia64/kernel/dma-mapping.c +++ b/arch/ia64/kernel/dma-mapping.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 121295637d0d..9c09bf390cce 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Extensible Firmware Interface * @@ -757,14 +758,14 @@ efi_memmap_intersects (unsigned long phys_addr, unsigned long size) return 0; } -u32 +int efi_mem_type (unsigned long phys_addr) { efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); if (md) return md->type; - return 0; + return -EINVAL; } u64 diff --git a/arch/ia64/kernel/efi_stub.S b/arch/ia64/kernel/efi_stub.S index a56e161d7515..58233bb7976d 100644 --- a/arch/ia64/kernel/efi_stub.S +++ b/arch/ia64/kernel/efi_stub.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * EFI call stub. * diff --git a/arch/ia64/kernel/elfcore.c b/arch/ia64/kernel/elfcore.c index 04bc8fd5f893..94680521fbf9 100644 --- a/arch/ia64/kernel/elfcore.c +++ b/arch/ia64/kernel/elfcore.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index e7a716b09350..68362b30ea47 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/ia64/kernel/entry.S * diff --git a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h index b83edac02965..6463dc316263 100644 --- a/arch/ia64/kernel/entry.h +++ b/arch/ia64/kernel/entry.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Preserved registers that are shared between code in ivt.S and diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index edbf7af95849..c0e7c9af2bb9 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the light-weight system call handlers (fsyscall-handlers). * diff --git a/arch/ia64/kernel/fsyscall_gtod_data.h b/arch/ia64/kernel/fsyscall_gtod_data.h index dcc514917731..0914c02a1eb0 100644 --- a/arch/ia64/kernel/fsyscall_gtod_data.h +++ b/arch/ia64/kernel/fsyscall_gtod_data.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. * Contributed by Peter Keilty diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index 0bd1b3bfaf1c..9f235cd551ab 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the code that gets mapped at the upper end of each task's text * region. For now, it contains the signal trampoline code only. diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S index 3e8271e85a1e..461c7e69d465 100644 --- a/arch/ia64/kernel/gate.lds.S +++ b/arch/ia64/kernel/gate.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Linker script for gate DSO. The gate pages are an ELF shared object * prelinked to its virtual address, with only one read-only segment and diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index 3204fddc439c..e6f45170a4b9 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Here is where the ball gets rolling as far as the kernel is concerned. * When control is transferred to _start, the bootload has already diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index d111248af719..6b51c88e3578 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Architecture-specific kernel symbols */ diff --git a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c index fa8ee64adac2..8df9245e29d9 100644 --- a/arch/ia64/kernel/init_task.c +++ b/arch/ia64/kernel/init_task.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This is where we statically allocate and initialize the initial * task. diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 90fde5b8669d..550243a94b5d 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * I/O SAPIC support. * diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 2ff1df7b14ea..8ed81b252694 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/ia64/kernel/irq.c * diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index eaa3199f98c8..ab87d6c25b15 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/ia64/kernel/irq_ia64.c * diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c index 1b3a776e5161..23bf4499a75d 100644 --- a/arch/ia64/kernel/irq_lsapic.c +++ b/arch/ia64/kernel/irq_lsapic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * LSAPIC Interrupt Controller * diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 44a103a5de2b..1efcbe5f0c78 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/ia64/kernel/ivt.S * diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c index f5a1e5246b3e..7bfe98859911 100644 --- a/arch/ia64/kernel/machvec.c +++ b/arch/ia64/kernel/machvec.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S index d5bdf9de36b6..086cfa4999fd 100644 --- a/arch/ia64/kernel/mca_asm.S +++ b/arch/ia64/kernel/mca_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File: mca_asm.S * Purpose: assembly portion of the IA64 MCA handling diff --git a/arch/ia64/kernel/mca_drv.h b/arch/ia64/kernel/mca_drv.h index 53b8ecb5b4b9..45bc4e3ae14f 100644 --- a/arch/ia64/kernel/mca_drv.h +++ b/arch/ia64/kernel/mca_drv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File: mca_drv.h * Purpose: Define helpers for Generic MCA handling diff --git a/arch/ia64/kernel/mca_drv_asm.S b/arch/ia64/kernel/mca_drv_asm.S index 767ac2c20d16..4428f57bee73 100644 --- a/arch/ia64/kernel/mca_drv_asm.S +++ b/arch/ia64/kernel/mca_drv_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File: mca_drv_asm.S * Purpose: Assembly portion of Generic MCA handling diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h index 5704700fb703..d6eab2a1084d 100644 --- a/arch/ia64/kernel/minstate.h +++ b/arch/ia64/kernel/minstate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index d1d945c6bd05..853b5611a894 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IA-64-specific support for kernel module loader. * diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index af4eaec0f7c3..519d9432f407 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MSI hooks for standard x86 apic */ diff --git a/arch/ia64/kernel/nr-irqs.c b/arch/ia64/kernel/nr-irqs.c index f6769cd54bd9..f2633b22d3be 100644 --- a/arch/ia64/kernel/nr-irqs.c +++ b/arch/ia64/kernel/nr-irqs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * calculate * NR_IRQS = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, FOO_NR_IRQS...) diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S index 94fb2e395498..d3e22c018b68 100644 --- a/arch/ia64/kernel/pal.S +++ b/arch/ia64/kernel/pal.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PAL Firmware support * IA-64 Processor Programmers Reference Vol 2 diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c index 944a8e2438a6..7f21a8c57ed7 100644 --- a/arch/ia64/kernel/patch.c +++ b/arch/ia64/kernel/patch.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Instruction-patching support. * diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index 9094a73f996f..3ba87c22dfbc 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Dynamic DMA mapping support. */ diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c index a14989dacded..5e50939aa03e 100644 --- a/arch/ia64/kernel/pci-swiotlb.c +++ b/arch/ia64/kernel/pci-swiotlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Glue code to lib/swiotlb.c */ #include diff --git a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h index 67489478041e..96af4696cea9 100644 --- a/arch/ia64/kernel/perfmon_generic.h +++ b/arch/ia64/kernel/perfmon_generic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the generic PMU register description tables * and pmc checker used by perfmon.c. diff --git a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h index d1d508a0fbd3..f2d348648a03 100644 --- a/arch/ia64/kernel/perfmon_itanium.h +++ b/arch/ia64/kernel/perfmon_itanium.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the Itanium PMU register description tables * and pmc checker used by perfmon.c. diff --git a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h index c4bec7a9d18f..a993249e58bc 100644 --- a/arch/ia64/kernel/perfmon_mckinley.h +++ b/arch/ia64/kernel/perfmon_mckinley.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the McKinley PMU register description tables * and pmc checker used by perfmon.c. diff --git a/arch/ia64/kernel/perfmon_montecito.h b/arch/ia64/kernel/perfmon_montecito.h index 7f8da4c7ca67..c0b5b9110c88 100644 --- a/arch/ia64/kernel/perfmon_montecito.h +++ b/arch/ia64/kernel/perfmon_montecito.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the Montecito PMU register description tables * and pmc checker used by perfmon.c. diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index d344d0d691aa..dda0082056b3 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Architecture-specific setup. * diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 3f8293378a83..427cd565fd61 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel support for the ptrace() and syscall tracing interfaces. * diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 23e3fd61e335..dee56bcb993d 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Architecture-specific setup. * diff --git a/arch/ia64/kernel/sigframe.h b/arch/ia64/kernel/sigframe.h index 9fd9a1933b3d..58a36ce6c26e 100644 --- a/arch/ia64/kernel/sigframe.h +++ b/arch/ia64/kernel/sigframe.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ struct sigscratch { unsigned long scratch_unat; /* ar.unat for the general registers saved in pt */ unsigned long ar_pfs; /* for syscalls, the user-level function-state */ diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 5db52c6813c4..a254cc98f95c 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Architecture-specific signal handling support. * @@ -124,31 +125,30 @@ copy_siginfo_to_user (siginfo_t __user *to, const siginfo_t *from) */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: + err |= __put_user(from->si_code, &to->si_code); + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_FAULT: err |= __put_user(from->si_flags, &to->si_flags); err |= __put_user(from->si_isr, &to->si_isr); - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_addr, &to->si_addr); err |= __put_user(from->si_imm, &to->si_imm); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_ptr, &to->si_ptr); break; - case __SI_RT >> 16: /* Not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_ptr, &to->si_ptr); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); - default: + case SIL_KILL: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_pid, &to->si_pid); break; diff --git a/arch/ia64/kernel/stacktrace.c b/arch/ia64/kernel/stacktrace.c index 5af2783a87f4..6e583a6bd2f6 100644 --- a/arch/ia64/kernel/stacktrace.c +++ b/arch/ia64/kernel/stacktrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/ia64/kernel/stacktrace.c * diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index 5ce927c854a6..085adfcc74a4 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file contains various system calls that have different calling * conventions on different platforms. diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 7b1fe9462158..6d4e76a4267f 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Architecture-specific trap handling. * @@ -349,7 +350,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) } siginfo.si_signo = SIGFPE; siginfo.si_errno = 0; - siginfo.si_code = __SI_FAULT; /* default code */ + siginfo.si_code = FPE_FIXME; /* default code */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); if (isr & 0x11) { siginfo.si_code = FPE_FLTINV; @@ -373,7 +374,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) /* raise exception */ siginfo.si_signo = SIGFPE; siginfo.si_errno = 0; - siginfo.si_code = __SI_FAULT; /* default code */ + siginfo.si_code = FPE_FIXME; /* default code */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); if (isr & 0x880) { siginfo.si_code = FPE_FLTOVF; diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index a13680ca1e61..72e9b4242564 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Architecture-specific unaligned trap handling. * diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index 9704e2cd9878..e04efa088902 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1999-2004 Hewlett-Packard Co * David Mosberger-Tang diff --git a/arch/ia64/kernel/unwind_decoder.c b/arch/ia64/kernel/unwind_decoder.c index 50ac2d82f9bf..83f54f7929b5 100644 --- a/arch/ia64/kernel/unwind_decoder.c +++ b/arch/ia64/kernel/unwind_decoder.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2000 Hewlett-Packard Co * Copyright (C) 2000 David Mosberger-Tang diff --git a/arch/ia64/kernel/unwind_i.h b/arch/ia64/kernel/unwind_i.h index 96693a6ae370..67994a7e5816 100644 --- a/arch/ia64/kernel/unwind_i.h +++ b/arch/ia64/kernel/unwind_i.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co * David Mosberger-Tang diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 798026dde52e..58db59da0bd8 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 1a36a3a39624..82118b38532f 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ia64-specific library routines.. # diff --git a/arch/ia64/lib/carta_random.S b/arch/ia64/lib/carta_random.S index d0674c360364..1a4a639dc42f 100644 --- a/arch/ia64/lib/carta_random.S +++ b/arch/ia64/lib/carta_random.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Fast, simple, yet decent quality random number generator based on * a paper by David G. Carta ("Two Fast Implementations of the diff --git a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c index 2cb23cb0c2e1..d26517fe3500 100644 --- a/arch/ia64/lib/checksum.c +++ b/arch/ia64/lib/checksum.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Network checksum routines * diff --git a/arch/ia64/lib/clear_page.S b/arch/ia64/lib/clear_page.S index 3cf5b76e587f..65b75085c8f4 100644 --- a/arch/ia64/lib/clear_page.S +++ b/arch/ia64/lib/clear_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999-2002 Hewlett-Packard Co * Stephane Eranian diff --git a/arch/ia64/lib/clear_user.S b/arch/ia64/lib/clear_user.S index 7b40731ee5d8..a28f39d349eb 100644 --- a/arch/ia64/lib/clear_user.S +++ b/arch/ia64/lib/clear_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This routine clears to zero a linear memory buffer in user space. * diff --git a/arch/ia64/lib/copy_page.S b/arch/ia64/lib/copy_page.S index cbdb9e323ffb..176f857c522e 100644 --- a/arch/ia64/lib/copy_page.S +++ b/arch/ia64/lib/copy_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Optimized version of the standard copy_page() function diff --git a/arch/ia64/lib/copy_page_mck.S b/arch/ia64/lib/copy_page_mck.S index c13f69036876..d6fd56e4f1c1 100644 --- a/arch/ia64/lib/copy_page_mck.S +++ b/arch/ia64/lib/copy_page_mck.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * McKinley-optimized version of copy_page(). * diff --git a/arch/ia64/lib/copy_user.S b/arch/ia64/lib/copy_user.S index 66facd52e8d0..f681556c6b86 100644 --- a/arch/ia64/lib/copy_user.S +++ b/arch/ia64/lib/copy_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Optimized version of the copy_user() routine. diff --git a/arch/ia64/lib/csum_partial_copy.c b/arch/ia64/lib/csum_partial_copy.c index 42f7678ef6ad..bf9396b1ed32 100644 --- a/arch/ia64/lib/csum_partial_copy.c +++ b/arch/ia64/lib/csum_partial_copy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Network Checksum & Copy routine * diff --git a/arch/ia64/lib/do_csum.S b/arch/ia64/lib/do_csum.S index 1a431a5cf86f..6004dad2597c 100644 --- a/arch/ia64/lib/do_csum.S +++ b/arch/ia64/lib/do_csum.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Optmized version of the standard do_csum() function diff --git a/arch/ia64/lib/idiv32.S b/arch/ia64/lib/idiv32.S index 715aed79a9ce..def92b708e6e 100644 --- a/arch/ia64/lib/idiv32.S +++ b/arch/ia64/lib/idiv32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2000 Hewlett-Packard Co * Copyright (C) 2000 David Mosberger-Tang diff --git a/arch/ia64/lib/idiv64.S b/arch/ia64/lib/idiv64.S index 25840f697753..a8ba3bd3d4d8 100644 --- a/arch/ia64/lib/idiv64.S +++ b/arch/ia64/lib/idiv64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999-2000 Hewlett-Packard Co * Copyright (C) 1999-2000 David Mosberger-Tang diff --git a/arch/ia64/lib/io.c b/arch/ia64/lib/io.c index bcd16f8ad9d9..d107eaf3790d 100644 --- a/arch/ia64/lib/io.c +++ b/arch/ia64/lib/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/ia64/lib/ip_fast_csum.S b/arch/ia64/lib/ip_fast_csum.S index 648e0d4a4839..dc9e6e6fe876 100644 --- a/arch/ia64/lib/ip_fast_csum.S +++ b/arch/ia64/lib/ip_fast_csum.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Optmized version of the ip_fast_csum() function * Used for calculating IP header checksum diff --git a/arch/ia64/lib/memcpy.S b/arch/ia64/lib/memcpy.S index ba172fd6acf4..91a625fddbf0 100644 --- a/arch/ia64/lib/memcpy.S +++ b/arch/ia64/lib/memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Optimized version of the standard memcpy() function diff --git a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S index bbbadc478f5b..cc4e6ac914b6 100644 --- a/arch/ia64/lib/memcpy_mck.S +++ b/arch/ia64/lib/memcpy_mck.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Itanium 2-optimized version of memcpy and copy_user function * diff --git a/arch/ia64/lib/memset.S b/arch/ia64/lib/memset.S index 87b974704075..07a8b92c6496 100644 --- a/arch/ia64/lib/memset.S +++ b/arch/ia64/lib/memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Optimized version of the standard memset() function. Copyright (c) 2002 Hewlett-Packard Co/CERN diff --git a/arch/ia64/lib/strlen.S b/arch/ia64/lib/strlen.S index 1a6e17c657b4..d66de5966974 100644 --- a/arch/ia64/lib/strlen.S +++ b/arch/ia64/lib/strlen.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Optimized version of the standard strlen() function diff --git a/arch/ia64/lib/strncpy_from_user.S b/arch/ia64/lib/strncpy_from_user.S index ca9ccf280e2e..49eb81b69cd2 100644 --- a/arch/ia64/lib/strncpy_from_user.S +++ b/arch/ia64/lib/strncpy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Just like strncpy() except that if a fault occurs during copying, * -EFAULT is returned. diff --git a/arch/ia64/lib/strnlen_user.S b/arch/ia64/lib/strnlen_user.S index 80a5dfd1d402..4b684d4da106 100644 --- a/arch/ia64/lib/strnlen_user.S +++ b/arch/ia64/lib/strnlen_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Returns 0 if exception before NUL or reaching the supplied limit (N), * a value greater than N if the string is longer than the limit, else diff --git a/arch/ia64/mm/Makefile b/arch/ia64/mm/Makefile index bb0a01a81878..99a35039b548 100644 --- a/arch/ia64/mm/Makefile +++ b/arch/ia64/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the ia64-specific parts of the memory manager. # diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 878626805369..9b2d994cddf6 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2000, 2003 Silicon Graphics, Inc. All rights reserved. * Copyright (c) 2001 Intel Corp. diff --git a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c index 10dd4a66e167..da477c11770b 100644 --- a/arch/ia64/mm/extable.c +++ b/arch/ia64/mm/extable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel exception handling table support. Derived from arch/alpha/mm/extable.c. * diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 15f09cfff335..dfdc152d6737 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MMU fault handling support. * diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index ae35140332f7..d16e419fd712 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IA-64 Huge TLB Page Support for Kernel. * diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index a4e8d6bd9cfa..7af4e05bb61e 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Initialize MMU support. * diff --git a/arch/ia64/module.lds b/arch/ia64/module.lds index 6481f42fbd8c..eff68f362793 100644 --- a/arch/ia64/module.lds +++ b/arch/ia64/module.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ SECTIONS { /* Group unwind sections into a single section: */ .IA_64.unwind_info : { *(.IA_64.unwind_info*) } diff --git a/arch/ia64/oprofile/Makefile b/arch/ia64/oprofile/Makefile index aad27a718ee0..cd134d6643bf 100644 --- a/arch/ia64/oprofile/Makefile +++ b/arch/ia64/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c index 41caa99add51..e1fa45b2148c 100644 --- a/arch/ia64/pci/fixup.c +++ b/arch/ia64/pci/fixup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Exceptions for specific devices. Usually work-arounds for fatal design flaws. * Derived from fixup.c of i386 tree. diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 4068bde623dc..f5ec736100ee 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -411,13 +411,6 @@ pcibios_disable_device (struct pci_dev *dev) acpi_pci_irq_disable(dev); } -resource_size_t -pcibios_align_resource (void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - /** * ia64_pci_get_legacy_mem - generic legacy mem routine * @bus: bus to get legacy memory base address for diff --git a/arch/ia64/scripts/check-gas b/arch/ia64/scripts/check-gas index 2499e0b2243d..787cf9b6b04a 100755 --- a/arch/ia64/scripts/check-gas +++ b/arch/ia64/scripts/check-gas @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 dir=$(dirname $0) CC=$1 OBJDUMP=$2 diff --git a/arch/ia64/scripts/check-segrel.S b/arch/ia64/scripts/check-segrel.S index 3be4e3dbeb83..65d6378adaaa 100644 --- a/arch/ia64/scripts/check-segrel.S +++ b/arch/ia64/scripts/check-segrel.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .rodata data4 @segrel(start) .data diff --git a/arch/ia64/scripts/check-segrel.lds b/arch/ia64/scripts/check-segrel.lds index 85a0d54fb5ab..c385d246e458 100644 --- a/arch/ia64/scripts/check-segrel.lds +++ b/arch/ia64/scripts/check-segrel.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ SECTIONS { . = SIZEOF_HEADERS; .rodata : { *(.rodata) } :ro diff --git a/arch/ia64/scripts/check-text-align.S b/arch/ia64/scripts/check-text-align.S index 03f586abb734..107fa1c88c2e 100644 --- a/arch/ia64/scripts/check-text-align.S +++ b/arch/ia64/scripts/check-text-align.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .proc foo .prologue foo: .save rp, r2 diff --git a/arch/ia64/scripts/toolchain-flags b/arch/ia64/scripts/toolchain-flags index 3f0c2adacb70..12dff5c981cf 100755 --- a/arch/ia64/scripts/toolchain-flags +++ b/arch/ia64/scripts/toolchain-flags @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # # Check whether linker can handle cross-segment @segrel(): # diff --git a/arch/ia64/scripts/unwcheck.py b/arch/ia64/scripts/unwcheck.py index 2bfd941ff7c7..89f3a1480a63 100644 --- a/arch/ia64/scripts/unwcheck.py +++ b/arch/ia64/scripts/unwcheck.py @@ -1,4 +1,5 @@ #!/usr/bin/python +# SPDX-License-Identifier: GPL-2.0 # # Usage: unwcheck.py FILE # diff --git a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c index 66edc36426ed..3009d9d86f29 100644 --- a/arch/ia64/sn/kernel/sn2/timer.c +++ b/arch/ia64/sn/kernel/sn2/timer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/ia64/sn/kernel/sn2/timer.c * diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 87cde1e4b38c..0d9446c37ae8 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config M32R bool default y @@ -194,6 +195,10 @@ config TIMER_DIVIDE int "Timer divider (integer)" default "128" +config CPU_BIG_ENDIAN + bool "Generate big endian code" + default n + config CPU_LITTLE_ENDIAN bool "Generate little endian code" default n diff --git a/arch/m32r/Kconfig.debug b/arch/m32r/Kconfig.debug index 6c612b7691b0..ffca1e194f91 100644 --- a/arch/m32r/Kconfig.debug +++ b/arch/m32r/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/m32r/Makefile b/arch/m32r/Makefile index def8dd0b6bc5..d73b58c847a6 100644 --- a/arch/m32r/Makefile +++ b/arch/m32r/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # m32r/Makefile # diff --git a/arch/m32r/boot/compressed/Makefile b/arch/m32r/boot/compressed/Makefile index 0606a727aab2..abd3c75ebd32 100644 --- a/arch/m32r/boot/compressed/Makefile +++ b/arch/m32r/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/m32r/boot/compressed/Makefile # diff --git a/arch/m32r/boot/compressed/boot.h b/arch/m32r/boot/compressed/boot.h index 9272e38d1104..7fce713e8aac 100644 --- a/arch/m32r/boot/compressed/boot.h +++ b/arch/m32r/boot/compressed/boot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * 1. load vmlinuz * diff --git a/arch/m32r/boot/compressed/head.S b/arch/m32r/boot/compressed/head.S index 95a0563ff076..39b693640375 100644 --- a/arch/m32r/boot/compressed/head.S +++ b/arch/m32r/boot/compressed/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/boot/compressed/head.S * diff --git a/arch/m32r/boot/compressed/m32r_sio.c b/arch/m32r/boot/compressed/m32r_sio.c index cf3023dced49..9d34bd063c31 100644 --- a/arch/m32r/boot/compressed/m32r_sio.c +++ b/arch/m32r/boot/compressed/m32r_sio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/m32r/boot/compressed/m32r_sio.c * diff --git a/arch/m32r/boot/compressed/misc.c b/arch/m32r/boot/compressed/misc.c index 3a7692745868..43e367055669 100644 --- a/arch/m32r/boot/compressed/misc.c +++ b/arch/m32r/boot/compressed/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/m32r/boot/compressed/misc.c * diff --git a/arch/m32r/boot/compressed/vmlinux.lds.S b/arch/m32r/boot/compressed/vmlinux.lds.S index dd11963f6939..c393eb559c4c 100644 --- a/arch/m32r/boot/compressed/vmlinux.lds.S +++ b/arch/m32r/boot/compressed/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ OUTPUT_ARCH(m32r) ENTRY(startup) diff --git a/arch/m32r/boot/setup.S b/arch/m32r/boot/setup.S index ef843d63083d..5909a825e2ed 100644 --- a/arch/m32r/boot/setup.S +++ b/arch/m32r/boot/setup.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/boot/setup.S -- A setup code. * diff --git a/arch/m32r/configs/m32104ut_defconfig b/arch/m32r/configs/m32104ut_defconfig index be30e094db71..4aa42acbd512 100644 --- a/arch/m32r/configs/m32104ut_defconfig +++ b/arch/m32r/configs/m32104ut_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -40,7 +39,6 @@ CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_ECN=m @@ -48,7 +46,6 @@ CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m @@ -106,7 +103,6 @@ CONFIG_SENSORS_SMSC47M1=m CONFIG_SENSORS_W83781D=m CONFIG_SENSORS_W83L785TS=m CONFIG_SENSORS_W83627HF=m -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y diff --git a/arch/m32r/configs/m32700ut.smp_defconfig b/arch/m32r/configs/m32700ut.smp_defconfig index a3d727ed6a16..41a0495b65df 100644 --- a/arch/m32r/configs/m32700ut.smp_defconfig +++ b/arch/m32r/configs/m32700ut.smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -30,7 +29,6 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=m @@ -63,7 +61,6 @@ CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_SERIAL_M32R_PLDSIO=y CONFIG_HW_RANDOM=y CONFIG_DS1302=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_S1D13XXX=y diff --git a/arch/m32r/configs/m32700ut.up_defconfig b/arch/m32r/configs/m32700ut.up_defconfig index b8334163099d..20078a866f45 100644 --- a/arch/m32r/configs/m32700ut.up_defconfig +++ b/arch/m32r/configs/m32700ut.up_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -29,7 +28,6 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=m @@ -62,7 +60,6 @@ CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_SERIAL_M32R_PLDSIO=y CONFIG_HW_RANDOM=y CONFIG_DS1302=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_S1D13XXX=y diff --git a/arch/m32r/configs/mappi.nommu_defconfig b/arch/m32r/configs/mappi.nommu_defconfig index 7c90ce2fc42b..4bf3820e054a 100644 --- a/arch/m32r/configs/mappi.nommu_defconfig +++ b/arch/m32r/configs/mappi.nommu_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y CONFIG_LOG_BUF_SHIFT=14 @@ -39,7 +38,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_NFS_FS=y diff --git a/arch/m32r/configs/mappi.smp_defconfig b/arch/m32r/configs/mappi.smp_defconfig index 367d07cebcd3..f9ed7bdbf4de 100644 --- a/arch/m32r/configs/mappi.smp_defconfig +++ b/arch/m32r/configs/mappi.smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -31,9 +30,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set # CONFIG_STANDALONE is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m @@ -50,7 +47,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=y diff --git a/arch/m32r/configs/mappi.up_defconfig b/arch/m32r/configs/mappi.up_defconfig index cb11384386ce..289ae7421e12 100644 --- a/arch/m32r/configs/mappi.up_defconfig +++ b/arch/m32r/configs/mappi.up_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -29,9 +28,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set # CONFIG_STANDALONE is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m @@ -48,7 +45,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=y diff --git a/arch/m32r/configs/mappi2.opsp_defconfig b/arch/m32r/configs/mappi2.opsp_defconfig index 3bff779259b4..2852f6e7e246 100644 --- a/arch/m32r/configs/mappi2.opsp_defconfig +++ b/arch/m32r/configs/mappi2.opsp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -50,7 +49,6 @@ CONFIG_SMC91X=y # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m # CONFIG_VGA_CONSOLE is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y diff --git a/arch/m32r/configs/mappi2.vdec2_defconfig b/arch/m32r/configs/mappi2.vdec2_defconfig index 75246c9c1af8..8da4dbad8510 100644 --- a/arch/m32r/configs/mappi2.vdec2_defconfig +++ b/arch/m32r/configs/mappi2.vdec2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -49,7 +48,6 @@ CONFIG_SMC91X=y # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m # CONFIG_VGA_CONSOLE is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y diff --git a/arch/m32r/configs/mappi3.smp_defconfig b/arch/m32r/configs/mappi3.smp_defconfig index 27cefd41ac1f..5605b23e2faf 100644 --- a/arch/m32r/configs/mappi3.smp_defconfig +++ b/arch/m32r/configs/mappi3.smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -29,9 +28,7 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=m @@ -50,7 +47,6 @@ CONFIG_SMC91X=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=y diff --git a/arch/m32r/configs/oaks32r_defconfig b/arch/m32r/configs/oaks32r_defconfig index 5087a510ca4f..5ccab127f6ad 100644 --- a/arch/m32r/configs/oaks32r_defconfig +++ b/arch/m32r/configs/oaks32r_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -37,7 +36,6 @@ CONFIG_NETDEVICES=y # CONFIG_VT is not set CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y diff --git a/arch/m32r/configs/opsput_defconfig b/arch/m32r/configs/opsput_defconfig index 50c6f525db20..3ce1d08355e5 100644 --- a/arch/m32r/configs/opsput_defconfig +++ b/arch/m32r/configs/opsput_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -46,7 +45,6 @@ CONFIG_SERIAL_M32R_SIO_CONSOLE=y CONFIG_SERIAL_M32R_PLDSIO=y CONFIG_HW_RANDOM=y CONFIG_DS1302=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_ISO9660_FS=m diff --git a/arch/m32r/configs/usrv_defconfig b/arch/m32r/configs/usrv_defconfig index a3cfaaedab60..cb8c051c3d46 100644 --- a/arch/m32r/configs/usrv_defconfig +++ b/arch/m32r/configs/usrv_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -34,9 +33,6 @@ CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -62,7 +58,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_M32R_SIO is not set # CONFIG_HWMON is not set -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set diff --git a/arch/m32r/include/asm/assembler.h b/arch/m32r/include/asm/assembler.h index 728799fc70aa..ed90d894f285 100644 --- a/arch/m32r/include/asm/assembler.h +++ b/arch/m32r/include/asm/assembler.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_ASSEMBLER_H #define _ASM_M32R_ASSEMBLER_H diff --git a/arch/m32r/include/asm/atomic.h b/arch/m32r/include/asm/atomic.h index 640cc1c7099f..8bf67e55ff54 100644 --- a/arch/m32r/include/asm/atomic.h +++ b/arch/m32r/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_ATOMIC_H #define _ASM_M32R_ATOMIC_H diff --git a/arch/m32r/include/asm/bitops.h b/arch/m32r/include/asm/bitops.h index 86ba2b42a6cf..64e70e57c154 100644 --- a/arch/m32r/include/asm/bitops.h +++ b/arch/m32r/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_BITOPS_H #define _ASM_M32R_BITOPS_H diff --git a/arch/m32r/include/asm/bug.h b/arch/m32r/include/asm/bug.h index 4cc0462c15b8..7197688254da 100644 --- a/arch/m32r/include/asm/bug.h +++ b/arch/m32r/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M32R_BUG_H #define _M32R_BUG_H #include diff --git a/arch/m32r/include/asm/bugs.h b/arch/m32r/include/asm/bugs.h index f77214eff136..74a6d428aebe 100644 --- a/arch/m32r/include/asm/bugs.h +++ b/arch/m32r/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_BUGS_H #define _ASM_M32R_BUGS_H diff --git a/arch/m32r/include/asm/cache.h b/arch/m32r/include/asm/cache.h index 40b3ee98193d..47a766a258f8 100644 --- a/arch/m32r/include/asm/cache.h +++ b/arch/m32r/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_CACHE_H #define _ASM_M32R_CACHE_H diff --git a/arch/m32r/include/asm/cachectl.h b/arch/m32r/include/asm/cachectl.h index 2aab8f6fff41..12f73f6c1759 100644 --- a/arch/m32r/include/asm/cachectl.h +++ b/arch/m32r/include/asm/cachectl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * cachectl.h -- defines for M32R cache control system calls * diff --git a/arch/m32r/include/asm/cacheflush.h b/arch/m32r/include/asm/cacheflush.h index 8e8e04516c39..5ad2a3045483 100644 --- a/arch/m32r/include/asm/cacheflush.h +++ b/arch/m32r/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_CACHEFLUSH_H #define _ASM_M32R_CACHEFLUSH_H diff --git a/arch/m32r/include/asm/cmpxchg.h b/arch/m32r/include/asm/cmpxchg.h index 23c9d0537201..1ccdce5ff0ac 100644 --- a/arch/m32r/include/asm/cmpxchg.h +++ b/arch/m32r/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_CMPXCHG_H #define _ASM_M32R_CMPXCHG_H diff --git a/arch/m32r/include/asm/dma-mapping.h b/arch/m32r/include/asm/dma-mapping.h index aff3ae8b62f7..4abfc07f4762 100644 --- a/arch/m32r/include/asm/dma-mapping.h +++ b/arch/m32r/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_DMA_MAPPING_H #define _ASM_M32R_DMA_MAPPING_H diff --git a/arch/m32r/include/asm/dma.h b/arch/m32r/include/asm/dma.h index 52f6a22dd232..661bc3b343ed 100644 --- a/arch/m32r/include/asm/dma.h +++ b/arch/m32r/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_DMA_H #define _ASM_M32R_DMA_H diff --git a/arch/m32r/include/asm/elf.h b/arch/m32r/include/asm/elf.h index 8acc9da9a15e..576b2ff57957 100644 --- a/arch/m32r/include/asm/elf.h +++ b/arch/m32r/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R__ELF_H #define _ASM_M32R__ELF_H diff --git a/arch/m32r/include/asm/emergency-restart.h b/arch/m32r/include/asm/emergency-restart.h index 108d8c48e42e..cca44d5ae264 100644 --- a/arch/m32r/include/asm/emergency-restart.h +++ b/arch/m32r/include/asm/emergency-restart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_EMERGENCY_RESTART_H #define _ASM_EMERGENCY_RESTART_H diff --git a/arch/m32r/include/asm/fb.h b/arch/m32r/include/asm/fb.h index d92e99cd8c8a..9a0bca2686fd 100644 --- a/arch/m32r/include/asm/fb.h +++ b/arch/m32r/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ diff --git a/arch/m32r/include/asm/flat.h b/arch/m32r/include/asm/flat.h index 455ce7ddbf14..dfcb0e4eb256 100644 --- a/arch/m32r/include/asm/flat.h +++ b/arch/m32r/include/asm/flat.h @@ -95,7 +95,7 @@ static inline unsigned long m32r_flat_get_addr_from_rp (u32 *rp, return ~0; /* bogus value */ } -static inline void flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval) +static inline int flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval) { unsigned int reloc = flat_m32r_get_reloc_type (relval); if (reloc & 0xf0) { @@ -133,6 +133,7 @@ static inline void flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval) break; } } + return 0; } // kludge - text_len is a local variable in the only user. diff --git a/arch/m32r/include/asm/hardirq.h b/arch/m32r/include/asm/hardirq.h index 5f2ac4f64ddf..10c23de02b3a 100644 --- a/arch/m32r/include/asm/hardirq.h +++ b/arch/m32r/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __KERNEL__ #ifndef __ASM_HARDIRQ_H #define __ASM_HARDIRQ_H diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h index 4b0f5e001d4d..1b653bb16f9a 100644 --- a/arch/m32r/include/asm/io.h +++ b/arch/m32r/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_IO_H #define _ASM_M32R_IO_H diff --git a/arch/m32r/include/asm/irq.h b/arch/m32r/include/asm/irq.h index 242028b4d86a..85b475fff90e 100644 --- a/arch/m32r/include/asm/irq.h +++ b/arch/m32r/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __KERNEL__ #ifndef _ASM_M32R_IRQ_H #define _ASM_M32R_IRQ_H diff --git a/arch/m32r/include/asm/kmap_types.h b/arch/m32r/include/asm/kmap_types.h index 4cdb5e3a06bf..3dcba0d17d40 100644 --- a/arch/m32r/include/asm/kmap_types.h +++ b/arch/m32r/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M32R_KMAP_TYPES_H #define __M32R_KMAP_TYPES_H diff --git a/arch/m32r/include/asm/linkage.h b/arch/m32r/include/asm/linkage.h index a9fb151cf648..f1aee6ec5bc3 100644 --- a/arch/m32r/include/asm/linkage.h +++ b/arch/m32r/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/m32r/include/asm/local.h b/arch/m32r/include/asm/local.h index 4045db3e4f65..6780680c185d 100644 --- a/arch/m32r/include/asm/local.h +++ b/arch/m32r/include/asm/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M32R_LOCAL_H #define __M32R_LOCAL_H diff --git a/arch/m32r/include/asm/m32102.h b/arch/m32r/include/asm/m32102.h index 52807f8db166..f0a986fece65 100644 --- a/arch/m32r/include/asm/m32102.h +++ b/arch/m32r/include/asm/m32102.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M32102_H_ #define _M32102_H_ diff --git a/arch/m32r/include/asm/m32r.h b/arch/m32r/include/asm/m32r.h index 214b44b40757..d27f056d92f3 100644 --- a/arch/m32r/include/asm/m32r.h +++ b/arch/m32r/include/asm/m32r.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_M32R_H_ #define _ASM_M32R_M32R_H_ diff --git a/arch/m32r/include/asm/m32r_mp_fpga.h b/arch/m32r/include/asm/m32r_mp_fpga.h index 976d2b995919..8eeaa9a420c5 100644 --- a/arch/m32r/include/asm/m32r_mp_fpga.h +++ b/arch/m32r/include/asm/m32r_mp_fpga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_M32R_MP_FPGA_ #define _ASM_M32R_M32R_MP_FPGA_ diff --git a/arch/m32r/include/asm/mc146818rtc.h b/arch/m32r/include/asm/mc146818rtc.h index aa1b7bf84f51..4effa4704347 100644 --- a/arch/m32r/include/asm/mc146818rtc.h +++ b/arch/m32r/include/asm/mc146818rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine dependent access functions for RTC registers. */ diff --git a/arch/m32r/include/asm/mmu.h b/arch/m32r/include/asm/mmu.h index 150cb92bb666..34bcccd8007d 100644 --- a/arch/m32r/include/asm/mmu.h +++ b/arch/m32r/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_MMU_H #define _ASM_M32R_MMU_H diff --git a/arch/m32r/include/asm/mmu_context.h b/arch/m32r/include/asm/mmu_context.h index 1230b7050d8e..8a499d0fb3a2 100644 --- a/arch/m32r/include/asm/mmu_context.h +++ b/arch/m32r/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_MMU_CONTEXT_H #define _ASM_M32R_MMU_CONTEXT_H #ifdef __KERNEL__ diff --git a/arch/m32r/include/asm/mmzone.h b/arch/m32r/include/asm/mmzone.h index 115ced33febd..568946c13ba6 100644 --- a/arch/m32r/include/asm/mmzone.h +++ b/arch/m32r/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Written by Pat Gaughen (gone@us.ibm.com) Mar 2002 * diff --git a/arch/m32r/include/asm/page.h b/arch/m32r/include/asm/page.h index 725ede8f2889..fe4e38b394d3 100644 --- a/arch/m32r/include/asm/page.h +++ b/arch/m32r/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_PAGE_H #define _ASM_M32R_PAGE_H diff --git a/arch/m32r/include/asm/pci.h b/arch/m32r/include/asm/pci.h index 07d3834c6dec..cbcb28b5f6ff 100644 --- a/arch/m32r/include/asm/pci.h +++ b/arch/m32r/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_PCI_H #define _ASM_M32R_PCI_H diff --git a/arch/m32r/include/asm/percpu.h b/arch/m32r/include/asm/percpu.h index e3169301fe66..41e1680d1117 100644 --- a/arch/m32r/include/asm/percpu.h +++ b/arch/m32r/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_M32R_PERCPU__ #define __ARCH_M32R_PERCPU__ diff --git a/arch/m32r/include/asm/pgalloc.h b/arch/m32r/include/asm/pgalloc.h index 2d55a064ccac..eed2cad57d68 100644 --- a/arch/m32r/include/asm/pgalloc.h +++ b/arch/m32r/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_PGALLOC_H #define _ASM_M32R_PGALLOC_H diff --git a/arch/m32r/include/asm/pgtable-2level.h b/arch/m32r/include/asm/pgtable-2level.h index 421e6ba3a173..d7ab1e94e3cb 100644 --- a/arch/m32r/include/asm/pgtable-2level.h +++ b/arch/m32r/include/asm/pgtable-2level.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_PGTABLE_2LEVEL_H #define _ASM_M32R_PGTABLE_2LEVEL_H #ifdef __KERNEL__ diff --git a/arch/m32r/include/asm/pgtable.h b/arch/m32r/include/asm/pgtable.h index 8c1fb902a9ce..eb7f9050c8d6 100644 --- a/arch/m32r/include/asm/pgtable.h +++ b/arch/m32r/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_PGTABLE_H #define _ASM_M32R_PGTABLE_H diff --git a/arch/m32r/include/asm/processor.h b/arch/m32r/include/asm/processor.h index 657874eeeccc..c70fa9ac7169 100644 --- a/arch/m32r/include/asm/processor.h +++ b/arch/m32r/include/asm/processor.h @@ -118,14 +118,6 @@ struct mm_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Copy and release all segment info associated with a VM */ -extern void copy_segments(struct task_struct *p, struct mm_struct * mm); -extern void release_segments(struct mm_struct * mm); - -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) ((tsk)->thread.lr) #define KSTK_ESP(tsk) ((tsk)->thread.sp) diff --git a/arch/m32r/include/asm/rtc.h b/arch/m32r/include/asm/rtc.h index 0340633f3f4d..a94cf1edc60f 100644 --- a/arch/m32r/include/asm/rtc.h +++ b/arch/m32r/include/asm/rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __RTC_H__ #define __RTC_H__ diff --git a/arch/m32r/include/asm/s1d13806.h b/arch/m32r/include/asm/s1d13806.h index 248d36a82d79..79e98a259ebe 100644 --- a/arch/m32r/include/asm/s1d13806.h +++ b/arch/m32r/include/asm/s1d13806.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ //---------------------------------------------------------------------------- // // File generated by S1D13806CFG.EXE diff --git a/arch/m32r/include/asm/segment.h b/arch/m32r/include/asm/segment.h index 42b11aeb3249..4095f14728e5 100644 --- a/arch/m32r/include/asm/segment.h +++ b/arch/m32r/include/asm/segment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SEGMENT_H #define _ASM_M32R_SEGMENT_H diff --git a/arch/m32r/include/asm/serial.h b/arch/m32r/include/asm/serial.h index 5ac244c72f15..b1375c841b4d 100644 --- a/arch/m32r/include/asm/serial.h +++ b/arch/m32r/include/asm/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SERIAL_H #define _ASM_M32R_SERIAL_H diff --git a/arch/m32r/include/asm/setup.h b/arch/m32r/include/asm/setup.h index bbe59a9ce8c6..71b4d6514078 100644 --- a/arch/m32r/include/asm/setup.h +++ b/arch/m32r/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SETUP_H #define _ASM_M32R_SETUP_H diff --git a/arch/m32r/include/asm/shmparam.h b/arch/m32r/include/asm/shmparam.h index 35986d81a528..1af73d92c96d 100644 --- a/arch/m32r/include/asm/shmparam.h +++ b/arch/m32r/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SHMPARAM_H #define _ASM_M32R_SHMPARAM_H diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h index ed3ded6601e8..8bf57950d21e 100644 --- a/arch/m32r/include/asm/signal.h +++ b/arch/m32r/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SIGNAL_H #define _ASM_M32R_SIGNAL_H diff --git a/arch/m32r/include/asm/smp.h b/arch/m32r/include/asm/smp.h index c689b828dfe2..763f22700ce6 100644 --- a/arch/m32r/include/asm/smp.h +++ b/arch/m32r/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SMP_H #define _ASM_M32R_SMP_H diff --git a/arch/m32r/include/asm/spinlock.h b/arch/m32r/include/asm/spinlock.h index 323c7fc953cd..604af84427ff 100644 --- a/arch/m32r/include/asm/spinlock.h +++ b/arch/m32r/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SPINLOCK_H #define _ASM_M32R_SPINLOCK_H @@ -30,11 +31,6 @@ #define arch_spin_is_locked(x) (*(volatile int *)(&(x)->slock) <= 0) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->slock, VAL > 0); -} - /** * arch_spin_trylock - Try spin lock and return a result * @lock: Pointer to the lock variable diff --git a/arch/m32r/include/asm/spinlock_types.h b/arch/m32r/include/asm/spinlock_types.h index 92e27672661f..bb0d17b64198 100644 --- a/arch/m32r/include/asm/spinlock_types.h +++ b/arch/m32r/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SPINLOCK_TYPES_H #define _ASM_M32R_SPINLOCK_TYPES_H diff --git a/arch/m32r/include/asm/string.h b/arch/m32r/include/asm/string.h index e61e2b0bfc1f..a9ea3b6c3e5a 100644 --- a/arch/m32r/include/asm/string.h +++ b/arch/m32r/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_STRING_H #define _ASM_M32R_STRING_H diff --git a/arch/m32r/include/asm/syscall.h b/arch/m32r/include/asm/syscall.h index 25f316f2b78d..22c8516d3c18 100644 --- a/arch/m32r/include/asm/syscall.h +++ b/arch/m32r/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_SYSCALL_H #define _ASM_M32R_SYSCALL_H diff --git a/arch/m32r/include/asm/termios.h b/arch/m32r/include/asm/termios.h index 680898f0b3d6..40274b89cea5 100644 --- a/arch/m32r/include/asm/termios.h +++ b/arch/m32r/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M32R_TERMIOS_H #define _M32R_TERMIOS_H diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h index f630d9c30b28..b3a215b0ce0a 100644 --- a/arch/m32r/include/asm/thread_info.h +++ b/arch/m32r/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_THREAD_INFO_H #define _ASM_M32R_THREAD_INFO_H diff --git a/arch/m32r/include/asm/timex.h b/arch/m32r/include/asm/timex.h index bb9fe4feb12d..a4f9f852d9e6 100644 --- a/arch/m32r/include/asm/timex.h +++ b/arch/m32r/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_TIMEX_H #define _ASM_M32R_TIMEX_H diff --git a/arch/m32r/include/asm/tlb.h b/arch/m32r/include/asm/tlb.h index c7ebd8d48f3b..3576f88b6ea4 100644 --- a/arch/m32r/include/asm/tlb.h +++ b/arch/m32r/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M32R_TLB_H #define _M32R_TLB_H diff --git a/arch/m32r/include/asm/tlbflush.h b/arch/m32r/include/asm/tlbflush.h index 92614b0ccf17..f6c7237316d0 100644 --- a/arch/m32r/include/asm/tlbflush.h +++ b/arch/m32r/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_TLBFLUSH_H #define _ASM_M32R_TLBFLUSH_H diff --git a/arch/m32r/include/asm/topology.h b/arch/m32r/include/asm/topology.h index d607eb32bd7e..ee79404e8878 100644 --- a/arch/m32r/include/asm/topology.h +++ b/arch/m32r/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_TOPOLOGY_H #define _ASM_M32R_TOPOLOGY_H diff --git a/arch/m32r/include/asm/types.h b/arch/m32r/include/asm/types.h index 04a44c6ee34d..fce0bf60536c 100644 --- a/arch/m32r/include/asm/types.h +++ b/arch/m32r/include/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_TYPES_H #define _ASM_M32R_TYPES_H diff --git a/arch/m32r/include/asm/uaccess.h b/arch/m32r/include/asm/uaccess.h index 496c4716dbc8..9d89bc3d8181 100644 --- a/arch/m32r/include/asm/uaccess.h +++ b/arch/m32r/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_UACCESS_H #define _ASM_M32R_UACCESS_H diff --git a/arch/m32r/include/asm/ucontext.h b/arch/m32r/include/asm/ucontext.h index 09324741eec3..5f9de3736624 100644 --- a/arch/m32r/include/asm/ucontext.h +++ b/arch/m32r/include/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_UCONTEXT_H #define _ASM_M32R_UCONTEXT_H diff --git a/arch/m32r/include/asm/unaligned.h b/arch/m32r/include/asm/unaligned.h index 377eb20d1ec6..5981361672f9 100644 --- a/arch/m32r/include/asm/unaligned.h +++ b/arch/m32r/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_UNALIGNED_H #define _ASM_M32R_UNALIGNED_H diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index de602533a3bd..dee4c196972e 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_UNISTD_H #define _ASM_M32R_UNISTD_H diff --git a/arch/m32r/include/asm/user.h b/arch/m32r/include/asm/user.h index 03b3c11c2aff..489b60d4aec2 100644 --- a/arch/m32r/include/asm/user.h +++ b/arch/m32r/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_USER_H #define _ASM_M32R_USER_H diff --git a/arch/m32r/include/asm/vga.h b/arch/m32r/include/asm/vga.h index a1b63061c06f..783d5bf779c2 100644 --- a/arch/m32r/include/asm/vga.h +++ b/arch/m32r/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_VGA_H #define _ASM_M32R_VGA_H diff --git a/arch/m32r/include/asm/xor.h b/arch/m32r/include/asm/xor.h index 6d525259df3e..a4d546752c77 100644 --- a/arch/m32r/include/asm/xor.h +++ b/arch/m32r/include/asm/xor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M32R_XOR_H #define _ASM_M32R_XOR_H diff --git a/arch/m32r/include/uapi/asm/bitsperlong.h b/arch/m32r/include/uapi/asm/bitsperlong.h index 6dc0bb0c13b2..76da34b10f59 100644 --- a/arch/m32r/include/uapi/asm/bitsperlong.h +++ b/arch/m32r/include/uapi/asm/bitsperlong.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/m32r/include/uapi/asm/byteorder.h b/arch/m32r/include/uapi/asm/byteorder.h index 21855d8b028b..9b4a8ba483cd 100644 --- a/arch/m32r/include/uapi/asm/byteorder.h +++ b/arch/m32r/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_BYTEORDER_H #define _ASM_M32R_BYTEORDER_H diff --git a/arch/m32r/include/uapi/asm/errno.h b/arch/m32r/include/uapi/asm/errno.h index 777149262aad..ab38ef607882 100644 --- a/arch/m32r/include/uapi/asm/errno.h +++ b/arch/m32r/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_ERRNO_H #define _ASM_M32R_ERRNO_H diff --git a/arch/m32r/include/uapi/asm/fcntl.h b/arch/m32r/include/uapi/asm/fcntl.h index 46ab12db5739..a77648c505d1 100644 --- a/arch/m32r/include/uapi/asm/fcntl.h +++ b/arch/m32r/include/uapi/asm/fcntl.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/m32r/include/uapi/asm/ioctl.h b/arch/m32r/include/uapi/asm/ioctl.h index b279fe06dfe5..b809c4566e5f 100644 --- a/arch/m32r/include/uapi/asm/ioctl.h +++ b/arch/m32r/include/uapi/asm/ioctl.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/m32r/include/uapi/asm/ioctls.h b/arch/m32r/include/uapi/asm/ioctls.h index 349bf87bfbd0..31da4c3bab94 100644 --- a/arch/m32r/include/uapi/asm/ioctls.h +++ b/arch/m32r/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_M32R_IOCTLS_H__ #define __ARCH_M32R_IOCTLS_H__ diff --git a/arch/m32r/include/uapi/asm/ipcbuf.h b/arch/m32r/include/uapi/asm/ipcbuf.h index 84c7e51cb6d0..90d6445a14df 100644 --- a/arch/m32r/include/uapi/asm/ipcbuf.h +++ b/arch/m32r/include/uapi/asm/ipcbuf.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/m32r/include/uapi/asm/msgbuf.h b/arch/m32r/include/uapi/asm/msgbuf.h index 0d5a877b813e..4386ff2735ba 100644 --- a/arch/m32r/include/uapi/asm/msgbuf.h +++ b/arch/m32r/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_MSGBUF_H #define _ASM_M32R_MSGBUF_H diff --git a/arch/m32r/include/uapi/asm/param.h b/arch/m32r/include/uapi/asm/param.h index fa207bdf96e7..0bff6d6133f5 100644 --- a/arch/m32r/include/uapi/asm/param.h +++ b/arch/m32r/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_PARAM_H #define _ASM_M32R_PARAM_H diff --git a/arch/m32r/include/uapi/asm/poll.h b/arch/m32r/include/uapi/asm/poll.h index c98509d3149e..b7132a305a47 100644 --- a/arch/m32r/include/uapi/asm/poll.h +++ b/arch/m32r/include/uapi/asm/poll.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/m32r/include/uapi/asm/posix_types.h b/arch/m32r/include/uapi/asm/posix_types.h index 236de26a409b..63316fcb1b57 100644 --- a/arch/m32r/include/uapi/asm/posix_types.h +++ b/arch/m32r/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_POSIX_TYPES_H #define _ASM_M32R_POSIX_TYPES_H diff --git a/arch/m32r/include/uapi/asm/ptrace.h b/arch/m32r/include/uapi/asm/ptrace.h index f6930a822517..99aec86cf5c0 100644 --- a/arch/m32r/include/uapi/asm/ptrace.h +++ b/arch/m32r/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * linux/include/asm-m32r/ptrace.h * diff --git a/arch/m32r/include/uapi/asm/resource.h b/arch/m32r/include/uapi/asm/resource.h index b1ce766e37a0..3282f3c4a5ca 100644 --- a/arch/m32r/include/uapi/asm/resource.h +++ b/arch/m32r/include/uapi/asm/resource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_RESOURCE_H #define _ASM_M32R_RESOURCE_H diff --git a/arch/m32r/include/uapi/asm/sembuf.h b/arch/m32r/include/uapi/asm/sembuf.h index c9873d6890e2..de34664d8cd7 100644 --- a/arch/m32r/include/uapi/asm/sembuf.h +++ b/arch/m32r/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_SEMBUF_H #define _ASM_M32R_SEMBUF_H diff --git a/arch/m32r/include/uapi/asm/setup.h b/arch/m32r/include/uapi/asm/setup.h index 96961a42e5f4..d936a64bbafd 100644 --- a/arch/m32r/include/uapi/asm/setup.h +++ b/arch/m32r/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_M32R_SETUP_H #define _UAPI_ASM_M32R_SETUP_H diff --git a/arch/m32r/include/uapi/asm/shmbuf.h b/arch/m32r/include/uapi/asm/shmbuf.h index b0cdf0aa7d65..44c2ea924829 100644 --- a/arch/m32r/include/uapi/asm/shmbuf.h +++ b/arch/m32r/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_SHMBUF_H #define _ASM_M32R_SHMBUF_H diff --git a/arch/m32r/include/uapi/asm/sigcontext.h b/arch/m32r/include/uapi/asm/sigcontext.h index da4a9c36d09b..cc9ee73525ff 100644 --- a/arch/m32r/include/uapi/asm/sigcontext.h +++ b/arch/m32r/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_SIGCONTEXT_H #define _ASM_M32R_SIGCONTEXT_H diff --git a/arch/m32r/include/uapi/asm/signal.h b/arch/m32r/include/uapi/asm/signal.h index 54acacb1f1f7..c2ac3417fb98 100644 --- a/arch/m32r/include/uapi/asm/signal.h +++ b/arch/m32r/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_M32R_SIGNAL_H #define _UAPI_ASM_M32R_SIGNAL_H diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index f8f7b47e247f..cf5018e82c3d 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_SOCKET_H #define _ASM_M32R_SOCKET_H @@ -102,4 +103,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_M32R_SOCKET_H */ diff --git a/arch/m32r/include/uapi/asm/sockios.h b/arch/m32r/include/uapi/asm/sockios.h index 6c1fb9b43bdb..948229e474c5 100644 --- a/arch/m32r/include/uapi/asm/sockios.h +++ b/arch/m32r/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_SOCKIOS_H #define _ASM_M32R_SOCKIOS_H diff --git a/arch/m32r/include/uapi/asm/stat.h b/arch/m32r/include/uapi/asm/stat.h index 98470fe483b6..0fe9f96ce8f0 100644 --- a/arch/m32r/include/uapi/asm/stat.h +++ b/arch/m32r/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_STAT_H #define _ASM_M32R_STAT_H diff --git a/arch/m32r/include/uapi/asm/statfs.h b/arch/m32r/include/uapi/asm/statfs.h index 6eb4c6007e6b..d42ae20dbb2b 100644 --- a/arch/m32r/include/uapi/asm/statfs.h +++ b/arch/m32r/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_STATFS_H #define _ASM_M32R_STATFS_H diff --git a/arch/m32r/include/uapi/asm/swab.h b/arch/m32r/include/uapi/asm/swab.h index 54dab001d6d1..18dce47d2841 100644 --- a/arch/m32r/include/uapi/asm/swab.h +++ b/arch/m32r/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_SWAB_H #define _ASM_M32R_SWAB_H diff --git a/arch/m32r/include/uapi/asm/termbits.h b/arch/m32r/include/uapi/asm/termbits.h index 957a3c688549..6cbbae9695b4 100644 --- a/arch/m32r/include/uapi/asm/termbits.h +++ b/arch/m32r/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M32R_TERMBITS_H #define _ASM_M32R_TERMBITS_H diff --git a/arch/m32r/include/uapi/asm/termios.h b/arch/m32r/include/uapi/asm/termios.h index 07ad27b8f7db..9b80a85e83ac 100644 --- a/arch/m32r/include/uapi/asm/termios.h +++ b/arch/m32r/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_M32R_TERMIOS_H #define _UAPI_M32R_TERMIOS_H diff --git a/arch/m32r/include/uapi/asm/unistd.h b/arch/m32r/include/uapi/asm/unistd.h index 5a54f2ae3b51..adf8666a68ef 100644 --- a/arch/m32r/include/uapi/asm/unistd.h +++ b/arch/m32r/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_M32R_UNISTD_H #define _UAPI_ASM_M32R_UNISTD_H diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile index 0c09dad8b1f8..bd94dca51596 100644 --- a/arch/m32r/kernel/Makefile +++ b/arch/m32r/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/M32R kernel. # diff --git a/arch/m32r/kernel/align.c b/arch/m32r/kernel/align.c index ec51e5b34860..2919a6647aff 100644 --- a/arch/m32r/kernel/align.c +++ b/arch/m32r/kernel/align.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * align.c - address exception handler for M32R * diff --git a/arch/m32r/kernel/asm-offsets.c b/arch/m32r/kernel/asm-offsets.c index cd3d2fc9c8df..7cb90b459e07 100644 --- a/arch/m32r/kernel/asm-offsets.c +++ b/arch/m32r/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index c639bfa32232..bbf48f2aa2a7 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/kernel/entry.S * diff --git a/arch/m32r/kernel/head.S b/arch/m32r/kernel/head.S index a46652dd83e6..1f040973df1c 100644 --- a/arch/m32r/kernel/head.S +++ b/arch/m32r/kernel/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/kernel/head.S * diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c index 5537f7397297..83b5032f176c 100644 --- a/arch/m32r/kernel/irq.c +++ b/arch/m32r/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/irq.c * diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index 68da6b800453..46ebe071e4d6 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 8cd7e03f4370..a1a4cb136e99 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/process.c * diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index 2d887400e30e..d702a5ca0f92 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/ptrace.c * diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 1a9e977287e6..b72d5db39f00 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/setup.c * diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 1ed597041fba..ba4d8d6330f1 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/signal.c * diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index f34957032504..22a50fc49ab7 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/sys_m32r.c * diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S index f365c19795ef..cf0bcf014b98 100644 --- a/arch/m32r/kernel/syscall_table.S +++ b/arch/m32r/kernel/syscall_table.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ ENTRY(sys_call_table) .long sys_restart_syscall /* 0 - old "setup()" system call*/ .long sys_exit diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index 093f2761aa51..521749fbbb56 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/time.c * diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c index 647dd94a0c39..cb79fba79d43 100644 --- a/arch/m32r/kernel/traps.c +++ b/arch/m32r/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/kernel/traps.c * @@ -114,6 +115,15 @@ static void set_eit_vector_entries(void) _flush_cache_copyback_all(); } +void abort(void) +{ + BUG(); + + /* if that doesn't kill us, halt */ + panic("Oops failed to kill thread"); +} +EXPORT_SYMBOL(abort); + void __init trap_init(void) { set_eit_vector_entries(); diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S index ad1fe56455aa..7e4d957f7f7f 100644 --- a/arch/m32r/kernel/vmlinux.lds.S +++ b/arch/m32r/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make M32R Linux kernel */ diff --git a/arch/m32r/lib/ashxdi3.S b/arch/m32r/lib/ashxdi3.S index 7fc0c19801ba..cd1acca53911 100644 --- a/arch/m32r/lib/ashxdi3.S +++ b/arch/m32r/lib/ashxdi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/lib/ashxdi3.S * diff --git a/arch/m32r/lib/delay.c b/arch/m32r/lib/delay.c index 940f4837e42b..ae1fe90892f9 100644 --- a/arch/m32r/lib/delay.c +++ b/arch/m32r/lib/delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/lib/delay.c * diff --git a/arch/m32r/lib/libgcc.h b/arch/m32r/lib/libgcc.h index 267aa435bc35..4854690d944a 100644 --- a/arch/m32r/lib/libgcc.h +++ b/arch/m32r/lib/libgcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LIBGCC_H #define __ASM_LIBGCC_H diff --git a/arch/m32r/lib/memcpy.S b/arch/m32r/lib/memcpy.S index 05987cd639ef..249da3e3358d 100644 --- a/arch/m32r/lib/memcpy.S +++ b/arch/m32r/lib/memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/lib/memcpy.S * diff --git a/arch/m32r/lib/memset.S b/arch/m32r/lib/memset.S index 2b2831a37927..e7f45e6c73f5 100644 --- a/arch/m32r/lib/memset.S +++ b/arch/m32r/lib/memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/lib/memset.S * diff --git a/arch/m32r/lib/strlen.S b/arch/m32r/lib/strlen.S index 916de9e8f801..41c77e387593 100644 --- a/arch/m32r/lib/strlen.S +++ b/arch/m32r/lib/strlen.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/strlen.S -- strlen code. * diff --git a/arch/m32r/lib/ucmpdi2.c b/arch/m32r/lib/ucmpdi2.c index 9d3c682c89b5..e20fa3484fd8 100644 --- a/arch/m32r/lib/ucmpdi2.c +++ b/arch/m32r/lib/ucmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "libgcc.h" int __ucmpdi2(unsigned long long a, unsigned long long b) diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c index b723b11107c7..0892a4341b3a 100644 --- a/arch/m32r/lib/usercopy.c +++ b/arch/m32r/lib/usercopy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * User address space access functions. * The non inlined parts of asm-m32r/uaccess.h are here. diff --git a/arch/m32r/mm/Makefile b/arch/m32r/mm/Makefile index c51c1c3b4a5f..cb20d90c51d1 100644 --- a/arch/m32r/mm/Makefile +++ b/arch/m32r/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux M32R-specific parts of the memory manager. # diff --git a/arch/m32r/mm/cache.c b/arch/m32r/mm/cache.c index fac759584875..0d1ae744e56f 100644 --- a/arch/m32r/mm/cache.c +++ b/arch/m32r/mm/cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/mm/cache.c * diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c index 27196303ce36..eb8e7966dcaf 100644 --- a/arch/m32r/mm/discontig.c +++ b/arch/m32r/mm/discontig.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/mm/discontig.c * diff --git a/arch/m32r/mm/extable.c b/arch/m32r/mm/extable.c index 8ac8ba6ef60c..066982756a4e 100644 --- a/arch/m32r/mm/extable.c +++ b/arch/m32r/mm/extable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/mm/extable.c */ diff --git a/arch/m32r/mm/fault-nommu.c b/arch/m32r/mm/fault-nommu.c index e22d5ddae5cb..240e00067d5e 100644 --- a/arch/m32r/mm/fault-nommu.c +++ b/arch/m32r/mm/fault-nommu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/mm/fault.c * diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c index a05dc3184594..46d9a5ca0e3a 100644 --- a/arch/m32r/mm/fault.c +++ b/arch/m32r/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/mm/fault.c * diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c index 11fa717d93b1..93abc8c3a46e 100644 --- a/arch/m32r/mm/init.c +++ b/arch/m32r/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/mm/init.c * diff --git a/arch/m32r/mm/mmu.S b/arch/m32r/mm/mmu.S index e9491a5ae827..fd8f9c9b7b07 100644 --- a/arch/m32r/mm/mmu.S +++ b/arch/m32r/mm/mmu.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/m32r/mm/mmu.S * diff --git a/arch/m32r/oprofile/Makefile b/arch/m32r/oprofile/Makefile index 06e7c81ead2e..8e63a3a5a64c 100644 --- a/arch/m32r/oprofile/Makefile +++ b/arch/m32r/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ diff --git a/arch/m32r/platforms/Makefile b/arch/m32r/platforms/Makefile index da03e1a8fe91..9e1a82529ad9 100644 --- a/arch/m32r/platforms/Makefile +++ b/arch/m32r/platforms/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # arch/m32r/platforms/Makefile obj-$(CONFIG_PLAT_M32104UT) += m32104ut/ obj-$(CONFIG_PLAT_M32700UT) += m32700ut/ diff --git a/arch/m32r/platforms/m32104ut/io.c b/arch/m32r/platforms/m32104ut/io.c index e5d8be6fbb2d..ff2bb3b58bb5 100644 --- a/arch/m32r/platforms/m32104ut/io.c +++ b/arch/m32r/platforms/m32104ut/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/m32104ut/io.c * diff --git a/arch/m32r/platforms/m32104ut/setup.c b/arch/m32r/platforms/m32104ut/setup.c index e2dd778aeac7..297936003b1f 100644 --- a/arch/m32r/platforms/m32104ut/setup.c +++ b/arch/m32r/platforms/m32104ut/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/m32104ut/setup.c * diff --git a/arch/m32r/platforms/mappi/io.c b/arch/m32r/platforms/mappi/io.c index ac1c396d477d..06ea6d9bc576 100644 --- a/arch/m32r/platforms/mappi/io.c +++ b/arch/m32r/platforms/mappi/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/mappi/io.c * diff --git a/arch/m32r/platforms/mappi/setup.c b/arch/m32r/platforms/mappi/setup.c index 767d2f4d6ded..c8d642ec4bfb 100644 --- a/arch/m32r/platforms/mappi/setup.c +++ b/arch/m32r/platforms/mappi/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/mappi/setup.c * diff --git a/arch/m32r/platforms/mappi2/io.c b/arch/m32r/platforms/mappi2/io.c index da58960b3f8a..18a408ff3fd1 100644 --- a/arch/m32r/platforms/mappi2/io.c +++ b/arch/m32r/platforms/mappi2/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/mappi2/io.c * diff --git a/arch/m32r/platforms/mappi2/setup.c b/arch/m32r/platforms/mappi2/setup.c index 76d665abf51e..7253258a7880 100644 --- a/arch/m32r/platforms/mappi2/setup.c +++ b/arch/m32r/platforms/mappi2/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/mappi2/setup.c * diff --git a/arch/m32r/platforms/mappi3/io.c b/arch/m32r/platforms/mappi3/io.c index 1bc3f90fdc53..e7edcab72a6b 100644 --- a/arch/m32r/platforms/mappi3/io.c +++ b/arch/m32r/platforms/mappi3/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/mappi3/io.c * diff --git a/arch/m32r/platforms/mappi3/setup.c b/arch/m32r/platforms/mappi3/setup.c index a3646d4b05bd..87d2000081f7 100644 --- a/arch/m32r/platforms/mappi3/setup.c +++ b/arch/m32r/platforms/mappi3/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/mappi3/setup.c * diff --git a/arch/m32r/platforms/oaks32r/io.c b/arch/m32r/platforms/oaks32r/io.c index 364a3b2e8907..3ce1f3ac0d16 100644 --- a/arch/m32r/platforms/oaks32r/io.c +++ b/arch/m32r/platforms/oaks32r/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/oaks32r/io.c * diff --git a/arch/m32r/platforms/oaks32r/setup.c b/arch/m32r/platforms/oaks32r/setup.c index f8373c069524..8188c0baa064 100644 --- a/arch/m32r/platforms/oaks32r/setup.c +++ b/arch/m32r/platforms/oaks32r/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/oaks32r/setup.c * diff --git a/arch/m32r/platforms/usrv/setup.c b/arch/m32r/platforms/usrv/setup.c index dcde0ec777f6..ba828b16c6e3 100644 --- a/arch/m32r/platforms/usrv/setup.c +++ b/arch/m32r/platforms/usrv/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m32r/platforms/usrv/setup.c * diff --git a/arch/m68k/68000/Makefile b/arch/m68k/68000/Makefile index 1eab70c7194b..4f7d4b45a46f 100644 --- a/arch/m68k/68000/Makefile +++ b/arch/m68k/68000/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ################################################## # # Makefile for 68000 core based cpus diff --git a/arch/m68k/68000/bootlogo-vz.h b/arch/m68k/68000/bootlogo-vz.h index 6ff09beba1ba..1afa33955368 100644 --- a/arch/m68k/68000/bootlogo-vz.h +++ b/arch/m68k/68000/bootlogo-vz.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #define splash_width 640 diff --git a/arch/m68k/68000/bootlogo.h b/arch/m68k/68000/bootlogo.h index c466db3ca3a8..b4d7e6c26cad 100644 --- a/arch/m68k/68000/bootlogo.h +++ b/arch/m68k/68000/bootlogo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #define bootlogo_width 160 diff --git a/arch/m68k/68000/head.S b/arch/m68k/68000/head.S index 536ef9616dad..140220662e33 100644 --- a/arch/m68k/68000/head.S +++ b/arch/m68k/68000/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * head.S - Common startup code for 68000 core based CPU's * diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 5abb548f0e70..785612b576f7 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config M68K bool default y @@ -24,6 +25,9 @@ config M68K select OLD_SIGSUSPEND3 select OLD_SIGACTION +config CPU_BIG_ENDIAN + def_bool y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus index 675b087198f6..d5e66ec136db 100644 --- a/arch/m68k/Kconfig.bus +++ b/arch/m68k/Kconfig.bus @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if MMU comment "Bus Support" diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index d2219f30b78f..ff5f0896318b 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 comment "Processor Type" choice diff --git a/arch/m68k/Kconfig.debug b/arch/m68k/Kconfig.debug index 50a67d08aec4..04690b179a6e 100644 --- a/arch/m68k/Kconfig.debug +++ b/arch/m68k/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices index 42b6fcfc30ef..3e9b0b826f8a 100644 --- a/arch/m68k/Kconfig.devices +++ b/arch/m68k/Kconfig.devices @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if MMU config ARCH_MAY_HAVE_PC_FDC diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine index 9225b4ad9aeb..5cd57b4d3615 100644 --- a/arch/m68k/Kconfig.machine +++ b/arch/m68k/Kconfig.machine @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 comment "Machine Types" if M68KCLASSIC diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index ba03cec3f711..a537953bc10c 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ** linux/amiga/chipram.c ** diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c index 432bc8bacfc2..0d27706f14d4 100644 --- a/arch/m68k/apollo/config.c +++ b/arch/m68k/apollo/config.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index 17be1e7e2df2..02cff7efc834 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c index e4f1faffe32b..b43eeef0982c 100644 --- a/arch/m68k/bvme6000/rtc.c +++ b/arch/m68k/bvme6000/rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Real Time Clock interface for Linux on the BVME6000 * diff --git a/arch/m68k/coldfire/Makefile b/arch/m68k/coldfire/Makefile index 4aa2c57afc35..f8cef9681416 100644 --- a/arch/m68k/coldfire/Makefile +++ b/arch/m68k/coldfire/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the m68knommu kernel. # diff --git a/arch/m68k/coldfire/cache.c b/arch/m68k/coldfire/cache.c index 71beeaf0c5c4..98ee89b87439 100644 --- a/arch/m68k/coldfire/cache.c +++ b/arch/m68k/coldfire/cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/clk.c b/arch/m68k/coldfire/clk.c index 1e3c7e9193d1..849cd208e2ed 100644 --- a/arch/m68k/coldfire/clk.c +++ b/arch/m68k/coldfire/clk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* @@ -121,6 +122,9 @@ EXPORT_SYMBOL(clk_put); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } EXPORT_SYMBOL(clk_get_rate); diff --git a/arch/m68k/coldfire/dma.c b/arch/m68k/coldfire/dma.c index df5ce20d181c..c3279f7467d7 100644 --- a/arch/m68k/coldfire/dma.c +++ b/arch/m68k/coldfire/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/dma_timer.c b/arch/m68k/coldfire/dma_timer.c index 8273eea57874..cbb289439606 100644 --- a/arch/m68k/coldfire/dma_timer.c +++ b/arch/m68k/coldfire/dma_timer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dma_timer.c -- Freescale ColdFire DMA Timer. * diff --git a/arch/m68k/coldfire/firebee.c b/arch/m68k/coldfire/firebee.c index 46d50534f981..3b9d4fc6f12e 100644 --- a/arch/m68k/coldfire/firebee.c +++ b/arch/m68k/coldfire/firebee.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/head.S b/arch/m68k/coldfire/head.S index bdb472c48401..c6d7fd28c602 100644 --- a/arch/m68k/coldfire/head.S +++ b/arch/m68k/coldfire/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*****************************************************************************/ /* diff --git a/arch/m68k/coldfire/m5206.c b/arch/m68k/coldfire/m5206.c index a3bcf0883f98..2f14ea95c391 100644 --- a/arch/m68k/coldfire/m5206.c +++ b/arch/m68k/coldfire/m5206.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m520x.c b/arch/m68k/coldfire/m520x.c index 5ba69217ce6c..b5b2a267dada 100644 --- a/arch/m68k/coldfire/m520x.c +++ b/arch/m68k/coldfire/m520x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m523x.c b/arch/m68k/coldfire/m523x.c index f7a0fcc5618c..ddf2496ed117 100644 --- a/arch/m68k/coldfire/m523x.c +++ b/arch/m68k/coldfire/m523x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m5249.c b/arch/m68k/coldfire/m5249.c index b16cf9b4580c..0590f8c421f1 100644 --- a/arch/m68k/coldfire/m5249.c +++ b/arch/m68k/coldfire/m5249.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m525x.c b/arch/m68k/coldfire/m525x.c index 110e2cd34e62..1772359c416c 100644 --- a/arch/m68k/coldfire/m525x.c +++ b/arch/m68k/coldfire/m525x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m5272.c b/arch/m68k/coldfire/m5272.c index 9abb1a441da0..ad1185c68df7 100644 --- a/arch/m68k/coldfire/m5272.c +++ b/arch/m68k/coldfire/m5272.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m527x.c b/arch/m68k/coldfire/m527x.c index b10b436b5a31..cad462df6861 100644 --- a/arch/m68k/coldfire/m527x.c +++ b/arch/m68k/coldfire/m527x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m528x.c b/arch/m68k/coldfire/m528x.c index ea76998d5ab9..7ad3193887e8 100644 --- a/arch/m68k/coldfire/m528x.c +++ b/arch/m68k/coldfire/m528x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m5307.c b/arch/m68k/coldfire/m5307.c index cc5e8a50a423..64b4b1fd34ff 100644 --- a/arch/m68k/coldfire/m5307.c +++ b/arch/m68k/coldfire/m5307.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m5407.c b/arch/m68k/coldfire/m5407.c index 38863ddbeab0..0400d76115a1 100644 --- a/arch/m68k/coldfire/m5407.c +++ b/arch/m68k/coldfire/m5407.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/m5441x.c b/arch/m68k/coldfire/m5441x.c index dc589b039b62..315d14b0dca0 100644 --- a/arch/m68k/coldfire/m5441x.c +++ b/arch/m68k/coldfire/m5441x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * m5441x.c -- support for Coldfire m5441x processors * @@ -222,40 +223,3 @@ void __init config_BSP(char *commandp, int size) m5441x_uarts_init(); m5441x_fec_init(); } - - -#if IS_ENABLED(CONFIG_RTC_DRV_M5441x) -static struct resource m5441x_rtc_resources[] = { - { - .start = MCFRTC_BASE, - .end = MCFRTC_BASE + MCFRTC_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = MCF_IRQ_RTC, - .end = MCF_IRQ_RTC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device m5441x_rtc = { - .name = "mcfrtc", - .id = 0, - .resource = m5441x_rtc_resources, - .num_resources = ARRAY_SIZE(m5441x_rtc_resources), -}; -#endif - -static struct platform_device *m5441x_devices[] __initdata = { -#if IS_ENABLED(CONFIG_RTC_DRV_M5441x) - &m5441x_rtc, -#endif -}; - -static int __init init_BSP(void) -{ - platform_add_devices(m5441x_devices, ARRAY_SIZE(m5441x_devices)); - return 0; -} - -arch_initcall(init_BSP); diff --git a/arch/m68k/coldfire/m54xx.c b/arch/m68k/coldfire/m54xx.c index c552851ec617..e53ffed13ba8 100644 --- a/arch/m68k/coldfire/m54xx.c +++ b/arch/m68k/coldfire/m54xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/nettel.c b/arch/m68k/coldfire/nettel.c index ddc48ec1b800..ea8df6e7a6cc 100644 --- a/arch/m68k/coldfire/nettel.c +++ b/arch/m68k/coldfire/nettel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index 6a640be48568..3097fa2ca746 100644 --- a/arch/m68k/coldfire/pci.c +++ b/arch/m68k/coldfire/pci.c @@ -243,6 +243,13 @@ static struct resource mcf_pci_io = { .flags = IORESOURCE_IO, }; +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; + /* * Interrupt mapping and setting. */ @@ -258,6 +265,13 @@ static int mcf_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static int __init mcf_pci_init(void) { + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return -ENOMEM; + pr_info("ColdFire: PCI bus initialization...\n"); /* Reset the external PCI bus */ @@ -312,14 +326,28 @@ static int __init mcf_pci_init(void) set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(200)); - rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL); - if (!rootbus) - return -ENODEV; + + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->dev.parent = NULL; + bridge->sysdata = NULL; + bridge->busnr = 0; + bridge->ops = &mcf_pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = mcf_pci_map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return ret; + } + + rootbus = bridge->bus; rootbus->resource[0] = &mcf_pci_io; rootbus->resource[1] = &mcf_pci_mem; - pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq); pci_bus_size_bridges(rootbus); pci_bus_assign_resources(rootbus); pci_bus_add_devices(rootbus); diff --git a/arch/m68k/coldfire/pit.c b/arch/m68k/coldfire/pit.c index 6c0878018b44..eb6f16b0e2e6 100644 --- a/arch/m68k/coldfire/pit.c +++ b/arch/m68k/coldfire/pit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/sltimers.c b/arch/m68k/coldfire/sltimers.c index 3292c0d68b18..1b11e7bacab3 100644 --- a/arch/m68k/coldfire/sltimers.c +++ b/arch/m68k/coldfire/sltimers.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/timers.c b/arch/m68k/coldfire/timers.c index 2dc7a58204f6..227aa5d13709 100644 --- a/arch/m68k/coldfire/timers.c +++ b/arch/m68k/coldfire/timers.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/coldfire/vectors.c b/arch/m68k/coldfire/vectors.c index 08923fe600e0..3bf0d69eec9e 100644 --- a/arch/m68k/coldfire/vectors.c +++ b/arch/m68k/coldfire/vectors.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /***************************************************************************/ /* diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index ddff1164aff0..54191f6fc715 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -49,6 +49,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -465,8 +466,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m # CONFIG_IOMMU_SUPPORT is not set @@ -477,7 +480,6 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -587,12 +589,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 17384dc959a5..fb4663904428 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -47,6 +47,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -427,8 +428,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_HEARTBEAT=y @@ -436,7 +439,6 @@ CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -546,12 +548,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 53a641d62f85..4ab393e86e52 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -47,6 +47,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -442,7 +443,10 @@ CONFIG_DMASOUND_ATARI=m CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m +# CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_HEARTBEAT=y @@ -457,7 +461,6 @@ CONFIG_ATARI_DSP56K=m CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -567,12 +570,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 3925ae3a5eb3..1dd8d697545b 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -45,6 +45,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -420,15 +421,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -538,12 +540,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index f4a134b390b4..02b39f50076e 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -47,6 +47,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -430,15 +431,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -548,12 +550,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 9ed0cef632b7..044dcb2bf8fb 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -46,6 +46,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -452,15 +453,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -570,12 +572,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index efed0d48fd53..3ad04682077a 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -56,6 +56,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -520,8 +521,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_MSM6242=m CONFIG_RTC_DRV_RP5C01=m CONFIG_RTC_DRV_GENERIC=m @@ -540,7 +543,6 @@ CONFIG_SERIAL_CONSOLE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -650,12 +652,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 9040457c7f9c..dc2dd61948cd 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -44,6 +44,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -420,15 +421,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -538,12 +540,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 8b17f00e0484..54e7b523fc3d 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -45,6 +45,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -420,15 +421,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -538,12 +540,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 5f3718c62c85..d63d8a15f6db 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -45,6 +45,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -442,8 +443,10 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_HEARTBEAT=y @@ -451,7 +454,6 @@ CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -561,12 +563,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 8c979a68fca5..d0924c22f52a 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -42,6 +42,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -422,15 +423,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -540,12 +542,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y CONFIG_CRYPTO_RSA=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index a1e79530e806..3001ee1e5dc5 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -42,6 +42,7 @@ CONFIG_PACKET=y CONFIG_PACKET_DIAG=m CONFIG_UNIX=y CONFIG_UNIX_DIAG=m +CONFIG_TLS=m CONFIG_XFRM_MIGRATE=y CONFIG_NET_KEY=y CONFIG_INET=y @@ -422,15 +423,16 @@ CONFIG_HID=m CONFIG_HIDRAW=y CONFIG_UHID=m # CONFIG_HID_GENERIC is not set +# CONFIG_HID_ITE is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y +# CONFIG_RTC_NVMEM is not set CONFIG_RTC_DRV_GENERIC=m # CONFIG_IOMMU_SUPPORT is not set CONFIG_PROC_HARDWARE=y CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=m CONFIG_JFS_FS=m -CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set CONFIG_FS_ENCRYPTION=m @@ -540,12 +542,13 @@ CONFIG_TEST_BITMAP=m CONFIG_TEST_UUID=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_HASH=m -CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m +CONFIG_TEST_SYSCTL=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m +CONFIG_TEST_KMOD=m CONFIG_EARLY_PRINTK=y CONFIG_ENCRYPTED_KEYS=m CONFIG_HARDENED_USERCOPY=y diff --git a/arch/m68k/fpsp040/Makefile b/arch/m68k/fpsp040/Makefile index 9506d883ace5..aab04d372ae7 100644 --- a/arch/m68k/fpsp040/Makefile +++ b/arch/m68k/fpsp040/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Linux arch/m68k/fpsp040 source directory # diff --git a/arch/m68k/hp300/config.c b/arch/m68k/hp300/config.c index 7cfab158fb61..a19bcd23f80b 100644 --- a/arch/m68k/hp300/config.c +++ b/arch/m68k/hp300/config.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/hp300/config.c * diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c index 749543b425a4..289d928a46cb 100644 --- a/arch/m68k/hp300/time.c +++ b/arch/m68k/hp300/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/hp300/time.c * diff --git a/arch/m68k/include/asm/MC68328.h b/arch/m68k/include/asm/MC68328.h index b61230e74e63..6e14e92260fd 100644 --- a/arch/m68k/include/asm/MC68328.h +++ b/arch/m68k/include/asm/MC68328.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* include/asm-m68knommu/MC68328.h: '328 control registers * diff --git a/arch/m68k/include/asm/MC68EZ328.h b/arch/m68k/include/asm/MC68EZ328.h index 703331ece328..c50b9f6a8f66 100644 --- a/arch/m68k/include/asm/MC68EZ328.h +++ b/arch/m68k/include/asm/MC68EZ328.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* include/asm-m68knommu/MC68EZ328.h: 'EZ328 control registers * diff --git a/arch/m68k/include/asm/MC68VZ328.h b/arch/m68k/include/asm/MC68VZ328.h index fbaed7ddfb41..dc894cfcff68 100644 --- a/arch/m68k/include/asm/MC68VZ328.h +++ b/arch/m68k/include/asm/MC68VZ328.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* include/asm-m68knommu/MC68VZ328.h: 'VZ328 control registers * diff --git a/arch/m68k/include/asm/adb_iop.h b/arch/m68k/include/asm/adb_iop.h index 8a48e56f2d62..195d7fb1268c 100644 --- a/arch/m68k/include/asm/adb_iop.h +++ b/arch/m68k/include/asm/adb_iop.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ADB through the IOP * Written by Joshua M. Thompson diff --git a/arch/m68k/include/asm/apollohw.h b/arch/m68k/include/asm/apollohw.h index 87fc899d32ee..52066f3b8658 100644 --- a/arch/m68k/include/asm/apollohw.h +++ b/arch/m68k/include/asm/apollohw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* apollohw.h : some structures to access apollo HW */ #ifndef _ASMm68k_APOLLOHW_H_ diff --git a/arch/m68k/include/asm/asm-prototypes.h b/arch/m68k/include/asm/asm-prototypes.h new file mode 100644 index 000000000000..22ccb9c97576 --- /dev/null +++ b/arch/m68k/include/asm/asm-prototypes.h @@ -0,0 +1,5 @@ +extern int __divsi3(int, int); +extern int __modsi3(int, int); +extern int __mulsi3(int, int); +extern unsigned int __udivsi3(unsigned int, unsigned int); +extern unsigned int __umodsi3(unsigned int, unsigned int); diff --git a/arch/m68k/include/asm/atafd.h b/arch/m68k/include/asm/atafd.h index 8456889ee7da..ad7014cad633 100644 --- a/arch/m68k/include/asm/atafd.h +++ b/arch/m68k/include/asm/atafd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_FD_H #define _ASM_M68K_FD_H diff --git a/arch/m68k/include/asm/atafdreg.h b/arch/m68k/include/asm/atafdreg.h index bbf80949fd9f..c31b4919ed2d 100644 --- a/arch/m68k/include/asm/atafdreg.h +++ b/arch/m68k/include/asm/atafdreg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_FDREG_H #define _LINUX_FDREG_H diff --git a/arch/m68k/include/asm/atari_joystick.h b/arch/m68k/include/asm/atari_joystick.h index 93be7da9f2c7..c4a6a06e68c8 100644 --- a/arch/m68k/include/asm/atari_joystick.h +++ b/arch/m68k/include/asm/atari_joystick.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_ATARI_JOYSTICK_H #define _LINUX_ATARI_JOYSTICK_H diff --git a/arch/m68k/include/asm/atari_stdma.h b/arch/m68k/include/asm/atari_stdma.h index d24e34d870dc..70de9b12470a 100644 --- a/arch/m68k/include/asm/atari_stdma.h +++ b/arch/m68k/include/asm/atari_stdma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _atari_stdma_h #define _atari_stdma_h diff --git a/arch/m68k/include/asm/atari_stram.h b/arch/m68k/include/asm/atari_stram.h index 4e771c22d6a9..1fc19102aac9 100644 --- a/arch/m68k/include/asm/atari_stram.h +++ b/arch/m68k/include/asm/atari_stram.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_ATARI_STRAM_H #define _M68K_ATARI_STRAM_H diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h index cf4c3a7b1a45..e993e2860ee1 100644 --- a/arch/m68k/include/asm/atomic.h +++ b/arch/m68k/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_M68K_ATOMIC__ #define __ARCH_M68K_ATOMIC__ diff --git a/arch/m68k/include/asm/bootstd.h b/arch/m68k/include/asm/bootstd.h index e518f5a575b7..1dab93ddb090 100644 --- a/arch/m68k/include/asm/bootstd.h +++ b/arch/m68k/include/asm/bootstd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* bootstd.h: Bootloader system call interface * * (c) 1999, Rt-Control, Inc. diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h index 5bc8d91d68d4..b7e2bf1ba4a6 100644 --- a/arch/m68k/include/asm/bug.h +++ b/arch/m68k/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_BUG_H #define _M68K_BUG_H diff --git a/arch/m68k/include/asm/bugs.h b/arch/m68k/include/asm/bugs.h index d06207b9ba5a..745530651e0b 100644 --- a/arch/m68k/include/asm/bugs.h +++ b/arch/m68k/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-m68k/bugs.h * diff --git a/arch/m68k/include/asm/bvme6000hw.h b/arch/m68k/include/asm/bvme6000hw.h index f40d2f8510ee..7b1309bb2c07 100644 --- a/arch/m68k/include/asm/bvme6000hw.h +++ b/arch/m68k/include/asm/bvme6000hw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_BVME6000HW_H_ #define _M68K_BVME6000HW_H_ diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h index 0395c51e46a6..9c06458f3bc9 100644 --- a/arch/m68k/include/asm/cache.h +++ b/arch/m68k/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-m68k/cache.h */ diff --git a/arch/m68k/include/asm/cacheflush.h b/arch/m68k/include/asm/cacheflush.h index 4fc738209bd1..29b8e638b912 100644 --- a/arch/m68k/include/asm/cacheflush.h +++ b/arch/m68k/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __uClinux__ #include #else diff --git a/arch/m68k/include/asm/cacheflush_mm.h b/arch/m68k/include/asm/cacheflush_mm.h index fa2c3d681d84..1e2544ecaf88 100644 --- a/arch/m68k/include/asm/cacheflush_mm.h +++ b/arch/m68k/include/asm/cacheflush_mm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_CACHEFLUSH_H #define _M68K_CACHEFLUSH_H diff --git a/arch/m68k/include/asm/cacheflush_no.h b/arch/m68k/include/asm/cacheflush_no.h index d2b3935ae147..11e9a9dcbfb2 100644 --- a/arch/m68k/include/asm/cacheflush_no.h +++ b/arch/m68k/include/asm/cacheflush_no.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68KNOMMU_CACHEFLUSH_H #define _M68KNOMMU_CACHEFLUSH_H diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index 75e91f03b178..f9b94e4b94f9 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_CHECKSUM_H #define _M68K_CHECKSUM_H diff --git a/arch/m68k/include/asm/cmpxchg.h b/arch/m68k/include/asm/cmpxchg.h index 83b1df80f0ac..38e1d7acc44d 100644 --- a/arch/m68k/include/asm/cmpxchg.h +++ b/arch/m68k/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_M68K_CMPXCHG__ #define __ARCH_M68K_CMPXCHG__ diff --git a/arch/m68k/include/asm/coldfire.h b/arch/m68k/include/asm/coldfire.h index 50aa4dac9ca2..d9cb26fb3e65 100644 --- a/arch/m68k/include/asm/coldfire.h +++ b/arch/m68k/include/asm/coldfire.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/contregs.h b/arch/m68k/include/asm/contregs.h index d1ea750bddfe..f82ca0ab38bc 100644 --- a/arch/m68k/include/asm/contregs.h +++ b/arch/m68k/include/asm/contregs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_CONTREGS_H #define _M68K_CONTREGS_H diff --git a/arch/m68k/include/asm/current.h b/arch/m68k/include/asm/current.h index 91fcc5358cfe..6390ef2f7f86 100644 --- a/arch/m68k/include/asm/current.h +++ b/arch/m68k/include/asm/current.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_CURRENT_H #define _M68K_CURRENT_H diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h index c598d847d56b..7f474121e4ca 100644 --- a/arch/m68k/include/asm/delay.h +++ b/arch/m68k/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_DELAY_H #define _M68K_DELAY_H diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h index ef881cfbbca9..365f39f5e256 100644 --- a/arch/m68k/include/asm/div64.h +++ b/arch/m68k/include/asm/div64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_DIV64_H #define _M68K_DIV64_H diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h index 9210e470771b..3e1a3ffba291 100644 --- a/arch/m68k/include/asm/dma-mapping.h +++ b/arch/m68k/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_DMA_MAPPING_H #define _M68K_DMA_MAPPING_H diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h index 208b4daa14b3..b0978a23bad1 100644 --- a/arch/m68k/include/asm/dma.h +++ b/arch/m68k/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_DMA_H #define _M68K_DMA_H 1 diff --git a/arch/m68k/include/asm/dvma.h b/arch/m68k/include/asm/dvma.h index 890bbf7e7758..f609ec1de36d 100644 --- a/arch/m68k/include/asm/dvma.h +++ b/arch/m68k/include/asm/dvma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-m68k/dma.h * diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h index b1c26de438be..3d387ceaea3f 100644 --- a/arch/m68k/include/asm/elf.h +++ b/arch/m68k/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMm68k_ELF_H #define __ASMm68k_ELF_H diff --git a/arch/m68k/include/asm/entry.h b/arch/m68k/include/asm/entry.h index d7de0f1a8957..9b52b060c76a 100644 --- a/arch/m68k/include/asm/entry.h +++ b/arch/m68k/include/asm/entry.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M68K_ENTRY_H #define __M68K_ENTRY_H diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/fb.h index be4e4c6797e8..b86c6e2e26dd 100644 --- a/arch/m68k/include/asm/fb.h +++ b/arch/m68k/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ diff --git a/arch/m68k/include/asm/fbio.h b/arch/m68k/include/asm/fbio.h index 0a21da87f7d6..590b923c470d 100644 --- a/arch/m68k/include/asm/fbio.h +++ b/arch/m68k/include/asm/fbio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_FBIO_H #define __LINUX_FBIO_H diff --git a/arch/m68k/include/asm/flat.h b/arch/m68k/include/asm/flat.h index b2a41f5b3890..4f1d1e373420 100644 --- a/arch/m68k/include/asm/flat.h +++ b/arch/m68k/include/asm/flat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * flat.h -- uClinux flat-format executables */ diff --git a/arch/m68k/include/asm/fpu.h b/arch/m68k/include/asm/fpu.h index 526db9da9e43..ab12be88d75f 100644 --- a/arch/m68k/include/asm/fpu.h +++ b/arch/m68k/include/asm/fpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M68K_FPU_H #define __M68K_FPU_H diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h index 6c618529d9b9..11793165445d 100644 --- a/arch/m68k/include/asm/hardirq.h +++ b/arch/m68k/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M68K_HARDIRQ_H #define __M68K_HARDIRQ_H diff --git a/arch/m68k/include/asm/hash.h b/arch/m68k/include/asm/hash.h index 6407af84a994..6d0d0c893f16 100644 --- a/arch/m68k/include/asm/hash.h +++ b/arch/m68k/include/asm/hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HASH_H #define _ASM_HASH_H diff --git a/arch/m68k/include/asm/hp300hw.h b/arch/m68k/include/asm/hp300hw.h index 64f5271dd7be..0909800beef4 100644 --- a/arch/m68k/include/asm/hp300hw.h +++ b/arch/m68k/include/asm/hp300hw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_HP300HW_H #define _M68K_HP300HW_H diff --git a/arch/m68k/include/asm/hwtest.h b/arch/m68k/include/asm/hwtest.h index 402c8a4401fe..f8d646205ba3 100644 --- a/arch/m68k/include/asm/hwtest.h +++ b/arch/m68k/include/asm/hwtest.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Routines to test for presence/absence of hardware registers: * see arch/m68k/mm/hwtest.c. * -- PMM 05/1998 diff --git a/arch/m68k/include/asm/ide.h b/arch/m68k/include/asm/ide.h index 492fee8a1ab2..05cc7dc00e0c 100644 --- a/arch/m68k/include/asm/ide.h +++ b/arch/m68k/include/asm/ide.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1994-1996 Linus Torvalds & authors */ diff --git a/arch/m68k/include/asm/idprom.h b/arch/m68k/include/asm/idprom.h index 160616a89e05..13b099d011b5 100644 --- a/arch/m68k/include/asm/idprom.h +++ b/arch/m68k/include/asm/idprom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_IDPROM_H #define _M68K_IDPROM_H /* diff --git a/arch/m68k/include/asm/intersil.h b/arch/m68k/include/asm/intersil.h index f482902cac8a..b696348f9ab8 100644 --- a/arch/m68k/include/asm/intersil.h +++ b/arch/m68k/include/asm/intersil.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SUN3_INTERSIL_H #define _SUN3_INTERSIL_H /* bits 0 and 1 */ diff --git a/arch/m68k/include/asm/io.h b/arch/m68k/include/asm/io.h index bccd5a914eb6..756089cc019c 100644 --- a/arch/m68k/include/asm/io.h +++ b/arch/m68k/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __uClinux__ #include #else diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h index c98ac81582ac..ed5333e87879 100644 --- a/arch/m68k/include/asm/io_mm.h +++ b/arch/m68k/include/asm/io_mm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-m68k/io.h * diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index ad7bd40e6742..86f45b403bcc 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68KNOMMU_IO_H #define _M68KNOMMU_IO_H diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index a644f4a53b94..91dd493791d7 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_IRQ_H_ #define _M68K_IRQ_H_ diff --git a/arch/m68k/include/asm/irqflags.h b/arch/m68k/include/asm/irqflags.h index b5941818346f..3799a2481095 100644 --- a/arch/m68k/include/asm/irqflags.h +++ b/arch/m68k/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_IRQFLAGS_H #define _M68K_IRQFLAGS_H diff --git a/arch/m68k/include/asm/kexec.h b/arch/m68k/include/asm/kexec.h index 3df97abac147..f5a8b2defa4b 100644 --- a/arch/m68k/include/asm/kexec.h +++ b/arch/m68k/include/asm/kexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_KEXEC_H #define _ASM_M68K_KEXEC_H diff --git a/arch/m68k/include/asm/linkage.h b/arch/m68k/include/asm/linkage.h index 066e74f666ae..c8b84282764c 100644 --- a/arch/m68k/include/asm/linkage.h +++ b/arch/m68k/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h index 0ddf3efbcae9..ceb42670aee5 100644 --- a/arch/m68k/include/asm/m5206sim.h +++ b/arch/m68k/include/asm/m5206sim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h index 6d50cefa76c3..8b3da5624a73 100644 --- a/arch/m68k/include/asm/m520xsim.h +++ b/arch/m68k/include/asm/m520xsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h index d43f6ab1edc9..a3082411abee 100644 --- a/arch/m68k/include/asm/m523xsim.h +++ b/arch/m68k/include/asm/m523xsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m525xsim.h b/arch/m68k/include/asm/m525xsim.h index 699f20c8a0fe..de01b701d95f 100644 --- a/arch/m68k/include/asm/m525xsim.h +++ b/arch/m68k/include/asm/m525xsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h index 1fb01bb05d6c..135dd50f0f8f 100644 --- a/arch/m68k/include/asm/m5272sim.h +++ b/arch/m68k/include/asm/m5272sim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h index 35f6fbc89b92..d92814bf9915 100644 --- a/arch/m68k/include/asm/m527xsim.h +++ b/arch/m68k/include/asm/m527xsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h index 67f6182d10a4..7b60a57e9b70 100644 --- a/arch/m68k/include/asm/m528xsim.h +++ b/arch/m68k/include/asm/m528xsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m52xxacr.h b/arch/m68k/include/asm/m52xxacr.h index abc391a9ae8d..2cb29ed5266c 100644 --- a/arch/m68k/include/asm/m52xxacr.h +++ b/arch/m68k/include/asm/m52xxacr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h index d2595e04eb1d..25059f20524b 100644 --- a/arch/m68k/include/asm/m5307sim.h +++ b/arch/m68k/include/asm/m5307sim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m53xxacr.h b/arch/m68k/include/asm/m53xxacr.h index 3177ce8331d6..9138a624c5c8 100644 --- a/arch/m68k/include/asm/m53xxacr.h +++ b/arch/m68k/include/asm/m53xxacr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m53xxsim.h b/arch/m68k/include/asm/m53xxsim.h index 53329ae4d3e3..22c1c92b9811 100644 --- a/arch/m68k/include/asm/m53xxsim.h +++ b/arch/m68k/include/asm/m53xxsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h index ab40c16ba989..0c2720d8ede9 100644 --- a/arch/m68k/include/asm/m5407sim.h +++ b/arch/m68k/include/asm/m5407sim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/m5441xsim.h b/arch/m68k/include/asm/m5441xsim.h index 64f60be47066..4e9095b9480a 100644 --- a/arch/m68k/include/asm/m5441xsim.h +++ b/arch/m68k/include/asm/m5441xsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * m5441xsim.h -- Coldfire 5441x register definitions * diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h index c6ac05cda282..466df7b03c6b 100644 --- a/arch/m68k/include/asm/m54xxacr.h +++ b/arch/m68k/include/asm/m54xxacr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Bit definitions for the MCF54xx ACR and CACR registers. */ diff --git a/arch/m68k/include/asm/m54xxgpt.h b/arch/m68k/include/asm/m54xxgpt.h index 0b69cd1ed0ed..b1f912157be9 100644 --- a/arch/m68k/include/asm/m54xxgpt.h +++ b/arch/m68k/include/asm/m54xxgpt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File: m54xxgpt.h * Purpose: Register and bit definitions for the MCF54XX diff --git a/arch/m68k/include/asm/m54xxsim.h b/arch/m68k/include/asm/m54xxsim.h index 7758d0a1a84d..2a3305f6fac6 100644 --- a/arch/m68k/include/asm/m54xxsim.h +++ b/arch/m68k/include/asm/m54xxsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * m54xxsim.h -- ColdFire 547x/548x System Integration Unit support. */ diff --git a/arch/m68k/include/asm/mac_asc.h b/arch/m68k/include/asm/mac_asc.h index fc2e5467b41e..075990251345 100644 --- a/arch/m68k/include/asm/mac_asc.h +++ b/arch/m68k/include/asm/mac_asc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Apple Sound Chip */ diff --git a/arch/m68k/include/asm/mac_baboon.h b/arch/m68k/include/asm/mac_baboon.h index a2d32f6589f9..08d9b8829a1a 100644 --- a/arch/m68k/include/asm/mac_baboon.h +++ b/arch/m68k/include/asm/mac_baboon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for the "Baboon" custom IC on the PowerBook 190. */ diff --git a/arch/m68k/include/asm/mac_iop.h b/arch/m68k/include/asm/mac_iop.h index 42566fd052bc..73dae2abeba3 100644 --- a/arch/m68k/include/asm/mac_iop.h +++ b/arch/m68k/include/asm/mac_iop.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * I/O Processor (IOP) defines and structures, mostly snagged from A/UX * header files. diff --git a/arch/m68k/include/asm/mac_oss.h b/arch/m68k/include/asm/mac_oss.h index 425fbff4f4d8..56ef986c0a9b 100644 --- a/arch/m68k/include/asm/mac_oss.h +++ b/arch/m68k/include/asm/mac_oss.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * OSS * diff --git a/arch/m68k/include/asm/mac_psc.h b/arch/m68k/include/asm/mac_psc.h index 923305117a69..86a5a5eab89e 100644 --- a/arch/m68k/include/asm/mac_psc.h +++ b/arch/m68k/include/asm/mac_psc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Apple Peripheral System Controller (PSC) * diff --git a/arch/m68k/include/asm/mac_via.h b/arch/m68k/include/asm/mac_via.h index 53c632c85b03..de1470c4d829 100644 --- a/arch/m68k/include/asm/mac_via.h +++ b/arch/m68k/include/asm/mac_via.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * 6522 Versatile Interface Adapter (VIA) * diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h index 953ca21da8ee..1605da48ebf2 100644 --- a/arch/m68k/include/asm/machdep.h +++ b/arch/m68k/include/asm/machdep.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_MACHDEP_H #define _M68K_MACHDEP_H diff --git a/arch/m68k/include/asm/machines.h b/arch/m68k/include/asm/machines.h index be667e84f01b..1332bad001fa 100644 --- a/arch/m68k/include/asm/machines.h +++ b/arch/m68k/include/asm/machines.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * machines.h: Defines for taking apart the machine type value in the * idprom and determining the kind of machine we are on. diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h index 5b81ab188aa5..f42c27400dbc 100644 --- a/arch/m68k/include/asm/macintosh.h +++ b/arch/m68k/include/asm/macintosh.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACINTOSH_H #define __ASM_MACINTOSH_H diff --git a/arch/m68k/include/asm/math-emu.h b/arch/m68k/include/asm/math-emu.h index b062696d5a0d..eefaa3a2b596 100644 --- a/arch/m68k/include/asm/math-emu.h +++ b/arch/m68k/include/asm/math-emu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_SETUP_H #define _ASM_M68K_SETUP_H diff --git a/arch/m68k/include/asm/mc146818rtc.h b/arch/m68k/include/asm/mc146818rtc.h index 05b43bf5cdf3..6e9f319ce478 100644 --- a/arch/m68k/include/asm/mc146818rtc.h +++ b/arch/m68k/include/asm/mc146818rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine dependent access functions for RTC registers. */ diff --git a/arch/m68k/include/asm/mcf8390.h b/arch/m68k/include/asm/mcf8390.h index a72a20819a54..412360ef1dc1 100644 --- a/arch/m68k/include/asm/mcf8390.h +++ b/arch/m68k/include/asm/mcf8390.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h index fb95aed5f428..8b707c249026 100644 --- a/arch/m68k/include/asm/mcf_pgalloc.h +++ b/arch/m68k/include/asm/mcf_pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef M68K_MCF_PGALLOC_H #define M68K_MCF_PGALLOC_H diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h index 2500ce04fcc4..5d5502cb2b2d 100644 --- a/arch/m68k/include/asm/mcf_pgtable.h +++ b/arch/m68k/include/asm/mcf_pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MCF_PGTABLE_H #define _MCF_PGTABLE_H diff --git a/arch/m68k/include/asm/mcfclk.h b/arch/m68k/include/asm/mcfclk.h index ea4791e3a557..0aca504fae31 100644 --- a/arch/m68k/include/asm/mcfclk.h +++ b/arch/m68k/include/asm/mcfclk.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * mcfclk.h -- coldfire specific clock structure */ diff --git a/arch/m68k/include/asm/mcfdma.h b/arch/m68k/include/asm/mcfdma.h index 10bc7e391c14..6227317dd0f7 100644 --- a/arch/m68k/include/asm/mcfdma.h +++ b/arch/m68k/include/asm/mcfdma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcfintc.h b/arch/m68k/include/asm/mcfintc.h index 4183320a3813..8bcfa33efa0f 100644 --- a/arch/m68k/include/asm/mcfintc.h +++ b/arch/m68k/include/asm/mcfintc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcfpit.h b/arch/m68k/include/asm/mcfpit.h index 9fd321ca0725..20c81e07df1b 100644 --- a/arch/m68k/include/asm/mcfpit.h +++ b/arch/m68k/include/asm/mcfpit.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h index bc867de8a1e9..bef089510e55 100644 --- a/arch/m68k/include/asm/mcfsim.h +++ b/arch/m68k/include/asm/mcfsim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcfslt.h b/arch/m68k/include/asm/mcfslt.h index c2314b6f8caa..a539f0eccfcb 100644 --- a/arch/m68k/include/asm/mcfslt.h +++ b/arch/m68k/include/asm/mcfslt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcftimer.h b/arch/m68k/include/asm/mcftimer.h index 1150e42c3f19..4fe83db6497d 100644 --- a/arch/m68k/include/asm/mcftimer.h +++ b/arch/m68k/include/asm/mcftimer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcfuart.h b/arch/m68k/include/asm/mcfuart.h index b40c20f66647..a1f35352f328 100644 --- a/arch/m68k/include/asm/mcfuart.h +++ b/arch/m68k/include/asm/mcfuart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mcfwdebug.h b/arch/m68k/include/asm/mcfwdebug.h index 27f70e45d700..bbe06cf036d1 100644 --- a/arch/m68k/include/asm/mcfwdebug.h +++ b/arch/m68k/include/asm/mcfwdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/mmu.h b/arch/m68k/include/asm/mmu.h index 8a11a63ee15a..5c15aacb1370 100644 --- a/arch/m68k/include/asm/mmu.h +++ b/arch/m68k/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MMU_H #define __MMU_H diff --git a/arch/m68k/include/asm/mmu_context.h b/arch/m68k/include/asm/mmu_context.h index 4a6ae6dffa34..836acea8f758 100644 --- a/arch/m68k/include/asm/mmu_context.h +++ b/arch/m68k/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M68K_MMU_CONTEXT_H #define __M68K_MMU_CONTEXT_H diff --git a/arch/m68k/include/asm/mmzone.h b/arch/m68k/include/asm/mmzone.h index e1f1ec7b7006..64573fe8e60d 100644 --- a/arch/m68k/include/asm/mmzone.h +++ b/arch/m68k/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_MMZONE_H_ #define _ASM_M68K_MMZONE_H_ diff --git a/arch/m68k/include/asm/module.h b/arch/m68k/include/asm/module.h index 8b58fce843dd..36cb06cc03e6 100644 --- a/arch/m68k/include/asm/module.h +++ b/arch/m68k/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_MODULE_H #define _ASM_M68K_MODULE_H diff --git a/arch/m68k/include/asm/motorola_pgalloc.h b/arch/m68k/include/asm/motorola_pgalloc.h index c895b987202c..7859a86319cf 100644 --- a/arch/m68k/include/asm/motorola_pgalloc.h +++ b/arch/m68k/include/asm/motorola_pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MOTOROLA_PGALLOC_H #define _MOTOROLA_PGALLOC_H diff --git a/arch/m68k/include/asm/motorola_pgtable.h b/arch/m68k/include/asm/motorola_pgtable.h index 0085aab80e5a..7f66a7bad7a5 100644 --- a/arch/m68k/include/asm/motorola_pgtable.h +++ b/arch/m68k/include/asm/motorola_pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MOTOROLA_PGTABLE_H #define _MOTOROLA_PGTABLE_H diff --git a/arch/m68k/include/asm/movs.h b/arch/m68k/include/asm/movs.h index 67dbea36960f..390d7b47b8eb 100644 --- a/arch/m68k/include/asm/movs.h +++ b/arch/m68k/include/asm/movs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MOVS_H__ #define __MOVS_H__ diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h index b81043108472..9c7ff67c5ffd 100644 --- a/arch/m68k/include/asm/mvme147hw.h +++ b/arch/m68k/include/asm/mvme147hw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MVME147HW_H_ #define _MVME147HW_H_ diff --git a/arch/m68k/include/asm/mvme16xhw.h b/arch/m68k/include/asm/mvme16xhw.h index 1eb89de631e5..cc7f5ae1220f 100644 --- a/arch/m68k/include/asm/mvme16xhw.h +++ b/arch/m68k/include/asm/mvme16xhw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_MVME16xHW_H_ #define _M68K_MVME16xHW_H_ diff --git a/arch/m68k/include/asm/nettel.h b/arch/m68k/include/asm/nettel.h index 926375d538ec..45716ead7b9d 100644 --- a/arch/m68k/include/asm/nettel.h +++ b/arch/m68k/include/asm/nettel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************/ /* diff --git a/arch/m68k/include/asm/nubus.h b/arch/m68k/include/asm/nubus.h index d6be9976f1ae..d0d2039e434e 100644 --- a/arch/m68k/include/asm/nubus.h +++ b/arch/m68k/include/asm/nubus.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_NUBUS_H #define _ASM_M68K_NUBUS_H diff --git a/arch/m68k/include/asm/openprom.h b/arch/m68k/include/asm/openprom.h index d33cdadf78e1..dd22e649f5c5 100644 --- a/arch/m68k/include/asm/openprom.h +++ b/arch/m68k/include/asm/openprom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_OPENPROM_H #define __SPARC_OPENPROM_H diff --git a/arch/m68k/include/asm/oplib.h b/arch/m68k/include/asm/oplib.h index f082d03336bd..48cb4fd09f8d 100644 --- a/arch/m68k/include/asm/oplib.h +++ b/arch/m68k/include/asm/oplib.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * oplib.h: Describes the interface and available routines in the * Linux Prom library. diff --git a/arch/m68k/include/asm/page.h b/arch/m68k/include/asm/page.h index 430d4d54c883..700d8195880c 100644 --- a/arch/m68k/include/asm/page.h +++ b/arch/m68k/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_PAGE_H #define _M68K_PAGE_H @@ -32,7 +33,7 @@ typedef struct page *pgtable_t; #define pgprot_val(x) ((x).pgprot) #define __pte(x) ((pte_t) { (x) } ) -#define __pmd(x) ((pmd_t) { (x) } ) +#define __pmd(x) ((pmd_t) { { (x) }, }) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h index e7a1946455a8..e6b75992192b 100644 --- a/arch/m68k/include/asm/page_mm.h +++ b/arch/m68k/include/asm/page_mm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_PAGE_MM_H #define _M68K_PAGE_MM_H diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h index fa7f32d9836b..e644c4daf540 100644 --- a/arch/m68k/include/asm/page_no.h +++ b/arch/m68k/include/asm/page_no.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_PAGE_NO_H #define _M68K_PAGE_NO_H diff --git a/arch/m68k/include/asm/page_offset.h b/arch/m68k/include/asm/page_offset.h index 82626a8f1d0a..11dc3cb8c35b 100644 --- a/arch/m68k/include/asm/page_offset.h +++ b/arch/m68k/include/asm/page_offset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* This handles the memory map.. */ #if defined(CONFIG_RAMBASE) diff --git a/arch/m68k/include/asm/parport.h b/arch/m68k/include/asm/parport.h index c85cece778e8..becfebd5c6b7 100644 --- a/arch/m68k/include/asm/parport.h +++ b/arch/m68k/include/asm/parport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * parport.h: platform-specific PC-style parport initialisation * diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h index 3a3dbcf4051d..ef26fae8cf0b 100644 --- a/arch/m68k/include/asm/pci.h +++ b/arch/m68k/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_PCI_H #define _ASM_M68K_PCI_H diff --git a/arch/m68k/include/asm/pgalloc.h b/arch/m68k/include/asm/pgalloc.h index 37bee7e3223d..24ca46d2e090 100644 --- a/arch/m68k/include/asm/pgalloc.h +++ b/arch/m68k/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef M68K_PGALLOC_H #define M68K_PGALLOC_H diff --git a/arch/m68k/include/asm/pgtable.h b/arch/m68k/include/asm/pgtable.h index a3d733b524d2..ad15d655a9bf 100644 --- a/arch/m68k/include/asm/pgtable.h +++ b/arch/m68k/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __uClinux__ #include #else diff --git a/arch/m68k/include/asm/pgtable_mm.h b/arch/m68k/include/asm/pgtable_mm.h index 35ed4a9981ae..6181e4134483 100644 --- a/arch/m68k/include/asm/pgtable_mm.h +++ b/arch/m68k/include/asm/pgtable_mm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_PGTABLE_H #define _M68K_PGTABLE_H diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h index ac7d87a02335..fc3a96c77bd8 100644 --- a/arch/m68k/include/asm/pgtable_no.h +++ b/arch/m68k/include/asm/pgtable_no.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68KNOMMU_PGTABLE_H #define _M68KNOMMU_PGTABLE_H diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index 94c36030440c..464e9f5f50ee 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-m68k/processor.h * diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h index a45cb6894ad3..ea5a80ca1ab3 100644 --- a/arch/m68k/include/asm/ptrace.h +++ b/arch/m68k/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_PTRACE_H #define _M68K_PTRACE_H diff --git a/arch/m68k/include/asm/q40_master.h b/arch/m68k/include/asm/q40_master.h index c48d21b68f04..3a89c088800c 100644 --- a/arch/m68k/include/asm/q40_master.h +++ b/arch/m68k/include/asm/q40_master.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Q40 master Chip Control * RTC stuff merged for compactness. diff --git a/arch/m68k/include/asm/q40ints.h b/arch/m68k/include/asm/q40ints.h index 22f12c9eb910..7c93ac4117b8 100644 --- a/arch/m68k/include/asm/q40ints.h +++ b/arch/m68k/include/asm/q40ints.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * contains some Q40 related interrupt definitions */ diff --git a/arch/m68k/include/asm/quicc_simple.h b/arch/m68k/include/asm/quicc_simple.h index c3636932d4bc..b9e2808b44ac 100644 --- a/arch/m68k/include/asm/quicc_simple.h +++ b/arch/m68k/include/asm/quicc_simple.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*********************************** * $Id: quicc_simple.h,v 1.1 2002/03/02 15:01:10 gerg Exp $ *********************************** diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h index 932faa35655b..05e940c29b54 100644 --- a/arch/m68k/include/asm/raw_io.h +++ b/arch/m68k/include/asm/raw_io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-m68k/raw_io.h * diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h index 98216b8111f0..0b4cc1e079b5 100644 --- a/arch/m68k/include/asm/segment.h +++ b/arch/m68k/include/asm/segment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_SEGMENT_H #define _M68K_SEGMENT_H diff --git a/arch/m68k/include/asm/serial.h b/arch/m68k/include/asm/serial.h index 6d4497049b4b..3f76bc7b9edb 100644 --- a/arch/m68k/include/asm/serial.h +++ b/arch/m68k/include/asm/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-m68k/serial.h * diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h index 3bc64d02ba5f..8af85c38d377 100644 --- a/arch/m68k/include/asm/signal.h +++ b/arch/m68k/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_SIGNAL_H #define _M68K_SIGNAL_H diff --git a/arch/m68k/include/asm/string.h b/arch/m68k/include/asm/string.h index c30c03d98581..f759d944c449 100644 --- a/arch/m68k/include/asm/string.h +++ b/arch/m68k/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_STRING_H_ #define _M68K_STRING_H_ diff --git a/arch/m68k/include/asm/sun3-head.h b/arch/m68k/include/asm/sun3-head.h index 05af2f18b3bd..5656a265ea58 100644 --- a/arch/m68k/include/asm/sun3-head.h +++ b/arch/m68k/include/asm/sun3-head.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUN3_HEAD_H #define __SUN3_HEAD_H diff --git a/arch/m68k/include/asm/sun3_pgalloc.h b/arch/m68k/include/asm/sun3_pgalloc.h index 1901f61f926f..11485d38de4e 100644 --- a/arch/m68k/include/asm/sun3_pgalloc.h +++ b/arch/m68k/include/asm/sun3_pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* sun3_pgalloc.h -- * reorganization around 2.3.39, routines moved from sun3_pgtable.h * diff --git a/arch/m68k/include/asm/sun3_pgtable.h b/arch/m68k/include/asm/sun3_pgtable.h index d5104a7b5388..c987d50866b4 100644 --- a/arch/m68k/include/asm/sun3_pgtable.h +++ b/arch/m68k/include/asm/sun3_pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SUN3_PGTABLE_H #define _SUN3_PGTABLE_H diff --git a/arch/m68k/include/asm/sun3mmu.h b/arch/m68k/include/asm/sun3mmu.h index d8f17a0d8c9f..21a75daa278f 100644 --- a/arch/m68k/include/asm/sun3mmu.h +++ b/arch/m68k/include/asm/sun3mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for Sun3 custom MMU. */ diff --git a/arch/m68k/include/asm/sun3x.h b/arch/m68k/include/asm/sun3x.h index f5691a1ed7cc..b3a83bcaf47e 100644 --- a/arch/m68k/include/asm/sun3x.h +++ b/arch/m68k/include/asm/sun3x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SUN3X_H #define SUN3X_H diff --git a/arch/m68k/include/asm/sun3xflop.h b/arch/m68k/include/asm/sun3xflop.h index 159269b7f2e8..ef04c43acd13 100644 --- a/arch/m68k/include/asm/sun3xflop.h +++ b/arch/m68k/include/asm/sun3xflop.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* sun3xflop.h: Sun3/80 specific parts of the floppy driver. * * Derived partially from asm-sparc/floppy.h, which is: diff --git a/arch/m68k/include/asm/sun3xprom.h b/arch/m68k/include/asm/sun3xprom.h index 6735efcf5f6d..d244ca4a9149 100644 --- a/arch/m68k/include/asm/sun3xprom.h +++ b/arch/m68k/include/asm/sun3xprom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Useful PROM locations */ #ifndef SUN3X_PROM_H diff --git a/arch/m68k/include/asm/switch_to.h b/arch/m68k/include/asm/switch_to.h index 16fd6b634982..94f02f46c5fb 100644 --- a/arch/m68k/include/asm/switch_to.h +++ b/arch/m68k/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_SWITCH_TO_H #define _M68K_SWITCH_TO_H diff --git a/arch/m68k/include/asm/thread_info.h b/arch/m68k/include/asm/thread_info.h index cee13c2e5161..928035591f2e 100644 --- a/arch/m68k/include/asm/thread_info.h +++ b/arch/m68k/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_THREAD_INFO_H #define _ASM_M68K_THREAD_INFO_H diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h index efc1f4892357..6a21d9358280 100644 --- a/arch/m68k/include/asm/timex.h +++ b/arch/m68k/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-m68k/timex.h * diff --git a/arch/m68k/include/asm/tlb.h b/arch/m68k/include/asm/tlb.h index 1785cff73449..b4b9efb6f963 100644 --- a/arch/m68k/include/asm/tlb.h +++ b/arch/m68k/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_TLB_H #define _M68K_TLB_H diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h index 965ea35c9a40..191e75a6bb24 100644 --- a/arch/m68k/include/asm/tlbflush.h +++ b/arch/m68k/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_TLBFLUSH_H #define _M68K_TLBFLUSH_H diff --git a/arch/m68k/include/asm/uaccess.h b/arch/m68k/include/asm/uaccess.h index 63ba18e4c9a2..e896466a41a4 100644 --- a/arch/m68k/include/asm/uaccess.h +++ b/arch/m68k/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __uClinux__ #include #else diff --git a/arch/m68k/include/asm/uaccess_mm.h b/arch/m68k/include/asm/uaccess_mm.h index 1da1e23de74c..75c172e909ac 100644 --- a/arch/m68k/include/asm/uaccess_mm.h +++ b/arch/m68k/include/asm/uaccess_mm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M68K_UACCESS_H #define __M68K_UACCESS_H diff --git a/arch/m68k/include/asm/uaccess_no.h b/arch/m68k/include/asm/uaccess_no.h index 53d7b792a43d..892efb56beef 100644 --- a/arch/m68k/include/asm/uaccess_no.h +++ b/arch/m68k/include/asm/uaccess_no.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __M68KNOMMU_UACCESS_H #define __M68KNOMMU_UACCESS_H diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h index e4e22669edc0..1523a8e5ff22 100644 --- a/arch/m68k/include/asm/ucontext.h +++ b/arch/m68k/include/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_UCONTEXT_H #define _M68K_UCONTEXT_H diff --git a/arch/m68k/include/asm/unaligned.h b/arch/m68k/include/asm/unaligned.h index 2b3ca0bf7a0d..98c8930d3d35 100644 --- a/arch/m68k/include/asm/unaligned.h +++ b/arch/m68k/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_UNALIGNED_H #define _ASM_M68K_UNALIGNED_H diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index aab1edd0d4ba..30d0d3fbd4ef 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_UNISTD_H_ #define _ASM_M68K_UNISTD_H_ diff --git a/arch/m68k/include/asm/user.h b/arch/m68k/include/asm/user.h index f1f478d6e050..509d555977c8 100644 --- a/arch/m68k/include/asm/user.h +++ b/arch/m68k/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _M68K_USER_H #define _M68K_USER_H diff --git a/arch/m68k/include/asm/vga.h b/arch/m68k/include/asm/vga.h index d3aa1401e7aa..010a624d1b39 100644 --- a/arch/m68k/include/asm/vga.h +++ b/arch/m68k/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_VGA_H #define _ASM_M68K_VGA_H diff --git a/arch/m68k/include/asm/virtconvert.h b/arch/m68k/include/asm/virtconvert.h index b8a82fb1cef8..4aea6be7b220 100644 --- a/arch/m68k/include/asm/virtconvert.h +++ b/arch/m68k/include/asm/virtconvert.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __VIRT_CONVERT__ #define __VIRT_CONVERT__ diff --git a/arch/m68k/include/asm/zorro.h b/arch/m68k/include/asm/zorro.h index 5ce97c22b582..96f64bf7bcaa 100644 --- a/arch/m68k/include/asm/zorro.h +++ b/arch/m68k/include/asm/zorro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_M68K_ZORRO_H #define _ASM_M68K_ZORRO_H diff --git a/arch/m68k/include/uapi/asm/a.out.h b/arch/m68k/include/uapi/asm/a.out.h index 3885fe43432a..3eb24fd8b810 100644 --- a/arch/m68k/include/uapi/asm/a.out.h +++ b/arch/m68k/include/uapi/asm/a.out.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __M68K_A_OUT_H__ #define __M68K_A_OUT_H__ diff --git a/arch/m68k/include/uapi/asm/bootinfo-amiga.h b/arch/m68k/include/uapi/asm/bootinfo-amiga.h index daad3c58d2da..69bf4dda341e 100644 --- a/arch/m68k/include/uapi/asm/bootinfo-amiga.h +++ b/arch/m68k/include/uapi/asm/bootinfo-amiga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/bootinfo-amiga.h -- Amiga-specific boot information definitions */ diff --git a/arch/m68k/include/uapi/asm/bootinfo-apollo.h b/arch/m68k/include/uapi/asm/bootinfo-apollo.h index a93e0af1c6fe..c226f7957938 100644 --- a/arch/m68k/include/uapi/asm/bootinfo-apollo.h +++ b/arch/m68k/include/uapi/asm/bootinfo-apollo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/bootinfo-apollo.h -- Apollo-specific boot information definitions */ diff --git a/arch/m68k/include/uapi/asm/bootinfo-atari.h b/arch/m68k/include/uapi/asm/bootinfo-atari.h index a817854049bb..f2218a090fdb 100644 --- a/arch/m68k/include/uapi/asm/bootinfo-atari.h +++ b/arch/m68k/include/uapi/asm/bootinfo-atari.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/bootinfo-atari.h -- Atari-specific boot information definitions */ diff --git a/arch/m68k/include/uapi/asm/bootinfo-hp300.h b/arch/m68k/include/uapi/asm/bootinfo-hp300.h index c90cb71ed89a..2141c4f5f0a7 100644 --- a/arch/m68k/include/uapi/asm/bootinfo-hp300.h +++ b/arch/m68k/include/uapi/asm/bootinfo-hp300.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/bootinfo-hp300.h -- HP9000/300-specific boot information definitions */ diff --git a/arch/m68k/include/uapi/asm/bootinfo-mac.h b/arch/m68k/include/uapi/asm/bootinfo-mac.h index b44ff73898a9..449928cfcbf2 100644 --- a/arch/m68k/include/uapi/asm/bootinfo-mac.h +++ b/arch/m68k/include/uapi/asm/bootinfo-mac.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/bootinfo-mac.h -- Macintosh-specific boot information definitions */ diff --git a/arch/m68k/include/uapi/asm/bootinfo-q40.h b/arch/m68k/include/uapi/asm/bootinfo-q40.h index c79fea7e555b..78bda04bf788 100644 --- a/arch/m68k/include/uapi/asm/bootinfo-q40.h +++ b/arch/m68k/include/uapi/asm/bootinfo-q40.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/bootinfo-q40.h -- Q40-specific boot information definitions */ diff --git a/arch/m68k/include/uapi/asm/bootinfo-vme.h b/arch/m68k/include/uapi/asm/bootinfo-vme.h index a135eb41d672..f36a09ab5e79 100644 --- a/arch/m68k/include/uapi/asm/bootinfo-vme.h +++ b/arch/m68k/include/uapi/asm/bootinfo-vme.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/bootinfo-vme.h -- VME-specific boot information definitions */ diff --git a/arch/m68k/include/uapi/asm/bootinfo.h b/arch/m68k/include/uapi/asm/bootinfo.h index a48cf544c762..38d3140381fa 100644 --- a/arch/m68k/include/uapi/asm/bootinfo.h +++ b/arch/m68k/include/uapi/asm/bootinfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * asm/bootinfo.h -- Definition of the Linux/m68k boot information structure * diff --git a/arch/m68k/include/uapi/asm/byteorder.h b/arch/m68k/include/uapi/asm/byteorder.h index 31b260a88803..1fb5732f4a91 100644 --- a/arch/m68k/include/uapi/asm/byteorder.h +++ b/arch/m68k/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _M68K_BYTEORDER_H #define _M68K_BYTEORDER_H diff --git a/arch/m68k/include/uapi/asm/cachectl.h b/arch/m68k/include/uapi/asm/cachectl.h index 525978e959e3..6171e246ca7b 100644 --- a/arch/m68k/include/uapi/asm/cachectl.h +++ b/arch/m68k/include/uapi/asm/cachectl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _M68K_CACHECTL_H #define _M68K_CACHECTL_H diff --git a/arch/m68k/include/uapi/asm/fcntl.h b/arch/m68k/include/uapi/asm/fcntl.h index 1c369b20dc45..c6861e6ee313 100644 --- a/arch/m68k/include/uapi/asm/fcntl.h +++ b/arch/m68k/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _M68K_FCNTL_H #define _M68K_FCNTL_H diff --git a/arch/m68k/include/uapi/asm/ioctls.h b/arch/m68k/include/uapi/asm/ioctls.h index 1332bb4ca5b0..d92d7c7786bf 100644 --- a/arch/m68k/include/uapi/asm/ioctls.h +++ b/arch/m68k/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_M68K_IOCTLS_H__ #define __ARCH_M68K_IOCTLS_H__ diff --git a/arch/m68k/include/uapi/asm/param.h b/arch/m68k/include/uapi/asm/param.h index 36265ccf5c7b..726b2e7ec70d 100644 --- a/arch/m68k/include/uapi/asm/param.h +++ b/arch/m68k/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _M68K_PARAM_H #define _M68K_PARAM_H diff --git a/arch/m68k/include/uapi/asm/poll.h b/arch/m68k/include/uapi/asm/poll.h index f080fcdb61bf..c3e3fcc15e1d 100644 --- a/arch/m68k/include/uapi/asm/poll.h +++ b/arch/m68k/include/uapi/asm/poll.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __m68k_POLL_H #define __m68k_POLL_H diff --git a/arch/m68k/include/uapi/asm/posix_types.h b/arch/m68k/include/uapi/asm/posix_types.h index cf4dbf70fdc7..10a65149b5f2 100644 --- a/arch/m68k/include/uapi/asm/posix_types.h +++ b/arch/m68k/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_M68K_POSIX_TYPES_H #define __ARCH_M68K_POSIX_TYPES_H diff --git a/arch/m68k/include/uapi/asm/ptrace.h b/arch/m68k/include/uapi/asm/ptrace.h index caf92fd34939..19a1b9d0d858 100644 --- a/arch/m68k/include/uapi/asm/ptrace.h +++ b/arch/m68k/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_M68K_PTRACE_H #define _UAPI_M68K_PTRACE_H diff --git a/arch/m68k/include/uapi/asm/setup.h b/arch/m68k/include/uapi/asm/setup.h index 6a6dc636761e..25fe26d5597c 100644 --- a/arch/m68k/include/uapi/asm/setup.h +++ b/arch/m68k/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* ** asm/setup.h -- Definition of the Linux/m68k setup information ** diff --git a/arch/m68k/include/uapi/asm/sigcontext.h b/arch/m68k/include/uapi/asm/sigcontext.h index 523db2a51cf3..6cc8421c8a73 100644 --- a/arch/m68k/include/uapi/asm/sigcontext.h +++ b/arch/m68k/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_M68k_SIGCONTEXT_H #define _ASM_M68k_SIGCONTEXT_H diff --git a/arch/m68k/include/uapi/asm/signal.h b/arch/m68k/include/uapi/asm/signal.h index cba6f858bb46..915cc755a184 100644 --- a/arch/m68k/include/uapi/asm/signal.h +++ b/arch/m68k/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_M68K_SIGNAL_H #define _UAPI_M68K_SIGNAL_H diff --git a/arch/m68k/include/uapi/asm/stat.h b/arch/m68k/include/uapi/asm/stat.h index dd38bc2e9f98..1e15e6517b9c 100644 --- a/arch/m68k/include/uapi/asm/stat.h +++ b/arch/m68k/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _M68K_STAT_H #define _M68K_STAT_H diff --git a/arch/m68k/include/uapi/asm/swab.h b/arch/m68k/include/uapi/asm/swab.h index b7b37a40defc..9ef4fafba7d4 100644 --- a/arch/m68k/include/uapi/asm/swab.h +++ b/arch/m68k/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _M68K_SWAB_H #define _M68K_SWAB_H diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index 25589f5b8669..de3054f8a681 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_M68K_UNISTD_H_ #define _UAPI_ASM_M68K_UNISTD_H_ diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 74c898ced8cc..dbac7f8743fc 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c index 3a386341aa6e..ccea355052ef 100644 --- a/arch/m68k/kernel/asm-offsets.c +++ b/arch/m68k/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This program is used to generate definitions needed by * assembly language modules. diff --git a/arch/m68k/kernel/bootinfo_proc.c b/arch/m68k/kernel/bootinfo_proc.c index 2a33a9645ad8..3b9cab84917d 100644 --- a/arch/m68k/kernel/bootinfo_proc.c +++ b/arch/m68k/kernel/bootinfo_proc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Based on arch/arm/kernel/atags_proc.c */ diff --git a/arch/m68k/kernel/machine_kexec.c b/arch/m68k/kernel/machine_kexec.c index d4affc917d9d..206f84983120 100644 --- a/arch/m68k/kernel/machine_kexec.c +++ b/arch/m68k/kernel/machine_kexec.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * machine_kexec.c - handle transition of Linux booting another kernel */ diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 7df92f8b0781..4e77a06735c1 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/kernel/process.c * diff --git a/arch/m68k/kernel/relocate_kernel.S b/arch/m68k/kernel/relocate_kernel.S index 3e09a89067ad..ab0f1e7d4653 100644 --- a/arch/m68k/kernel/relocate_kernel.S +++ b/arch/m68k/kernel/relocate_kernel.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 4bf129f1d2e2..854e09f403e7 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifdef CONFIG_MMU #include "setup_mm.c" #else diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c index 7a2c21212820..657a9843ebfa 100644 --- a/arch/m68k/kernel/setup_mm.c +++ b/arch/m68k/kernel/setup_mm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/kernel/setup.c * diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c index 8afe6f651c1c..a98af1018201 100644 --- a/arch/m68k/kernel/setup_no.c +++ b/arch/m68k/kernel/setup_no.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68knommu/kernel/setup.c * diff --git a/arch/m68k/kernel/sun3-head.S b/arch/m68k/kernel/sun3-head.S index 43036bf4aeed..faf18f4fab1f 100644 --- a/arch/m68k/kernel/sun3-head.S +++ b/arch/m68k/kernel/sun3-head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 933e4815dac8..27e10af5153a 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/kernel/sys_m68k.c * diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 8c9fcfafe0dd..2c8402e75f62 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com) * diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds index d2c8abf1c8c4..3aa571a513b5 100644 --- a/arch/m68k/kernel/vmlinux-nommu.lds +++ b/arch/m68k/kernel/vmlinux-nommu.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * vmlinux.lds.S -- master linker script for m68knommu arch * diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 5b5ce1e4d1ed..89172b8974b9 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make m68k Linux kernel */ #include diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index fe5ea1974b16..293990efc917 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make m68k Linux kernel */ #include diff --git a/arch/m68k/kernel/vmlinux.lds.S b/arch/m68k/kernel/vmlinux.lds.S index 69ec79638870..d3d3c305ebc9 100644 --- a/arch/m68k/kernel/vmlinux.lds.S +++ b/arch/m68k/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) PHDRS { diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index fcd8eb1d7c7d..eca17f14b4d5 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for m68k-specific library files.. diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index 514acde3cd40..850f0dc284ca 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Baboon Custom IC Management * diff --git a/arch/m68k/mac/mac_penguin.S b/arch/m68k/mac/mac_penguin.S index b3ce30b6071d..359e63bb632d 100644 --- a/arch/m68k/mac/mac_penguin.S +++ b/arch/m68k/mac/mac_penguin.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .byte \ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xFF,0xFF,0xFF,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\ diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index ffaa1f6439ae..fa2b9604fd24 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Mac bong noise generator. Note - we ought to put a boingy noise * here 8) diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index 9637dee90dac..e3575388cd05 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Macintosh interrupts * diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c index 8aa8792e3174..4956edaac926 100644 --- a/arch/m68k/mac/misc.c +++ b/arch/m68k/mac/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Miscellaneous Mac68K-specific stuff */ @@ -357,6 +358,17 @@ static void cuda_shutdown(void) struct adb_request req; if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN) < 0) return; + + /* Avoid infinite polling loop when PSU is not under Cuda control */ + switch (macintosh_config->ident) { + case MAC_MODEL_C660: + case MAC_MODEL_Q605: + case MAC_MODEL_Q605_ACC: + case MAC_MODEL_P475: + case MAC_MODEL_P475F: + return; + } + while (!req.complete) cuda_poll(); } @@ -463,8 +475,9 @@ void mac_poweroff(void) pmu_shutdown(); #endif } - local_irq_enable(); + pr_crit("It is now safe to turn off your Macintosh.\n"); + local_irq_disable(); while(1); } @@ -554,8 +567,8 @@ void mac_reset(void) } /* should never get here */ - local_irq_enable(); pr_crit("Restart failed. Please restart manually.\n"); + local_irq_disable(); while(1); } diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index ca84dcf41fc9..34c0993dc689 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Operating System Services (OSS) chip handling * Written by Joshua M. Thompson (funaho@jurai.org) diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index 16629e91feba..9f59a662ace5 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * 6522 Versatile Interface Adapter (VIA) * diff --git a/arch/m68k/mm/Makefile b/arch/m68k/mm/Makefile index cfbf3205724a..b3adb5253393 100644 --- a/arch/m68k/mm/Makefile +++ b/arch/m68k/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux m68k-specific parts of the memory manager. # diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c index 3d84c1f2ffb2..079e64898e6a 100644 --- a/arch/m68k/mm/cache.c +++ b/arch/m68k/mm/cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/mm/cache.c * diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index 2795e4ca09d7..127d7c1f2090 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/mm/fault.c * diff --git a/arch/m68k/mm/hwtest.c b/arch/m68k/mm/hwtest.c index fb8be4dd38c4..fe99aa99987e 100644 --- a/arch/m68k/mm/hwtest.c +++ b/arch/m68k/mm/hwtest.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Tests for presence or absence of hardware registers. * This code was originally in atari/config.c, but I noticed * that it was also in drivers/nubus/nubus.c and I wanted to diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index a6ffead9bef5..e85acd131fa8 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/mm/init.c * diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index 6e4955bc542b..c2a38321c96d 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/mm/kmap.c * diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c index 87131cd3bc8f..8d1408583cf4 100644 --- a/arch/m68k/mm/mcfmmu.c +++ b/arch/m68k/mm/mcfmmu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Based upon linux/arch/m68k/mm/sun3mmu.c * Based upon linux/arch/ppc/mm/mmu_context.c diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index 4902b681a9fc..b86a2e21693b 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/mm/memory.c * diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 7cb72dbc2eaa..e490ecc7842c 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/mm/motorola.c * diff --git a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c index 177d776de1a0..4a9979908357 100644 --- a/arch/m68k/mm/sun3mmu.c +++ b/arch/m68k/mm/sun3mmu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/mm/sun3mmu.c * diff --git a/arch/m68k/mvme16x/rtc.c b/arch/m68k/mvme16x/rtc.c index 7b24577a7bd0..ccbaae1125e6 100644 --- a/arch/m68k/mvme16x/rtc.c +++ b/arch/m68k/mvme16x/rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Real Time Clock interface for Linux on the MVME16x * diff --git a/arch/m68k/sun3/dvma.c b/arch/m68k/sun3/dvma.c index ca02ee25894c..5f92c72b05c3 100644 --- a/arch/m68k/sun3/dvma.c +++ b/arch/m68k/sun3/dvma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/sun3/dvma.c * diff --git a/arch/m68k/sun3/idprom.c b/arch/m68k/sun3/idprom.c index 9c23f506d60d..1ace5353d78f 100644 --- a/arch/m68k/sun3/idprom.c +++ b/arch/m68k/sun3/idprom.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. diff --git a/arch/m68k/sun3/leds.c b/arch/m68k/sun3/leds.c index aad2e0a0682e..7c67b58ebf13 100644 --- a/arch/m68k/sun3/leds.c +++ b/arch/m68k/sun3/leds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c index 7fdc61525e0b..d30da12a1702 100644 --- a/arch/m68k/sun3/mmu_emu.c +++ b/arch/m68k/sun3/mmu_emu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ** Tablewalk MMU emulator ** diff --git a/arch/m68k/sun3/prom/console.c b/arch/m68k/sun3/prom/console.c index e92364373b07..eb4f6c903fb8 100644 --- a/arch/m68k/sun3/prom/console.c +++ b/arch/m68k/sun3/prom/console.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. diff --git a/arch/m68k/sun3/prom/init.c b/arch/m68k/sun3/prom/init.c index eeba067d565f..0c6d99df6aee 100644 --- a/arch/m68k/sun3/prom/init.c +++ b/arch/m68k/sun3/prom/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * init.c: Initialize internal variables used by the PROM * library functions. diff --git a/arch/m68k/sun3/prom/misc.c b/arch/m68k/sun3/prom/misc.c index 3d60e1337f75..b8c95940d089 100644 --- a/arch/m68k/sun3/prom/misc.c +++ b/arch/m68k/sun3/prom/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * misc.c: Miscellaneous prom functions that don't belong * anywhere else. diff --git a/arch/m68k/sun3/prom/printf.c b/arch/m68k/sun3/prom/printf.c index 5b82bea03493..b6724cc66795 100644 --- a/arch/m68k/sun3/prom/printf.c +++ b/arch/m68k/sun3/prom/printf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * printf.c: Internal prom library printf facility. * diff --git a/arch/m68k/sun3/sun3dvma.c b/arch/m68k/sun3/sun3dvma.c index d36bd15f9fdc..8546922adb47 100644 --- a/arch/m68k/sun3/sun3dvma.c +++ b/arch/m68k/sun3/sun3dvma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/sun3/sun3dvma.c * diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c index 0532d64d191e..33d3a1c6fba0 100644 --- a/arch/m68k/sun3x/config.c +++ b/arch/m68k/sun3x/config.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Setup kernel for a Sun3x machine * diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c index 9413c8724b0d..b2acbc862f60 100644 --- a/arch/m68k/sun3x/dvma.c +++ b/arch/m68k/sun3x/dvma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Virtual DMA allocation * diff --git a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c index 5d60e65c1ee5..be14c899ab7d 100644 --- a/arch/m68k/sun3x/prom.c +++ b/arch/m68k/sun3x/prom.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Prom access routines for the sun3x */ #include diff --git a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c index 431d3c4306dd..7a2c53d9f779 100644 --- a/arch/m68k/sun3x/time.c +++ b/arch/m68k/sun3x/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/m68k/sun3x/time.c * diff --git a/arch/m68k/sun3x/time.h b/arch/m68k/sun3x/time.h index a4f9126be7e2..496f406412ad 100644 --- a/arch/m68k/sun3x/time.h +++ b/arch/m68k/sun3x/time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SUN3X_TIME_H #define SUN3X_TIME_H diff --git a/arch/m68k/tools/amiga/Makefile b/arch/m68k/tools/amiga/Makefile index 113436136089..e6425b367ca8 100644 --- a/arch/m68k/tools/amiga/Makefile +++ b/arch/m68k/tools/amiga/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 CC = m68k-cbm-amigados-gcc CFLAGS = -Wall -O2 diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig index 5b7a45d99cfb..c7b62a339539 100644 --- a/arch/metag/Kconfig +++ b/arch/metag/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config METAG def_bool y select EMBEDDED @@ -26,6 +27,7 @@ config METAG select HAVE_SYSCALL_TRACEPOINTS select HAVE_UNDERSCORE_SYMBOL_PREFIX select IRQ_DOMAIN + select GENERIC_IRQ_EFFECTIVE_AFF_MASK select MODULES_USE_ELF_RELA select OF select OF_EARLY_FLATTREE diff --git a/arch/metag/Kconfig.debug b/arch/metag/Kconfig.debug index cb5c92860540..ac4516c605db 100644 --- a/arch/metag/Kconfig.debug +++ b/arch/metag/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT diff --git a/arch/metag/Kconfig.soc b/arch/metag/Kconfig.soc index 50f979c2b02d..c521f0e00d8e 100644 --- a/arch/metag/Kconfig.soc +++ b/arch/metag/Kconfig.soc @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "SoC Type" default META21_FPGA diff --git a/arch/metag/boot/dts/Makefile b/arch/metag/boot/dts/Makefile index 097c6da4547f..ad5dde558db1 100644 --- a/arch/metag/boot/dts/Makefile +++ b/arch/metag/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-y += skeleton.dtb dtb-y += tz1090_generic.dtb diff --git a/arch/metag/boot/dts/skeleton.dtsi b/arch/metag/boot/dts/skeleton.dtsi index 78229eacced7..43e2ffe73c27 100644 --- a/arch/metag/boot/dts/skeleton.dtsi +++ b/arch/metag/boot/dts/skeleton.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Skeleton device tree; the bare minimum needed to boot; just include and * add a compatible value. The bootloader will typically populate the memory diff --git a/arch/metag/include/asm/atomic.h b/arch/metag/include/asm/atomic.h index 8ff0a70865f6..97ae189c2dd8 100644 --- a/arch/metag/include/asm/atomic.h +++ b/arch/metag/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_ATOMIC_H #define __ASM_METAG_ATOMIC_H diff --git a/arch/metag/include/asm/atomic_lnkget.h b/arch/metag/include/asm/atomic_lnkget.h index def2c642f053..17e8c61c946d 100644 --- a/arch/metag/include/asm/atomic_lnkget.h +++ b/arch/metag/include/asm/atomic_lnkget.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_ATOMIC_LNKGET_H #define __ASM_METAG_ATOMIC_LNKGET_H diff --git a/arch/metag/include/asm/atomic_lock1.h b/arch/metag/include/asm/atomic_lock1.h index 6c1380a8a0d4..2ce8fa3a79c2 100644 --- a/arch/metag/include/asm/atomic_lock1.h +++ b/arch/metag/include/asm/atomic_lock1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_ATOMIC_LOCK1_H #define __ASM_METAG_ATOMIC_LOCK1_H @@ -37,6 +38,8 @@ static inline int atomic_set(atomic_t *v, int i) return i; } +#define atomic_set_release(v, i) atomic_set((v), (i)) + #define ATOMIC_OP(op, c_op) \ static inline void atomic_##op(int i, atomic_t *v) \ { \ diff --git a/arch/metag/include/asm/barrier.h b/arch/metag/include/asm/barrier.h index 5418517aa5eb..2661fec5696a 100644 --- a/arch/metag/include/asm/barrier.h +++ b/arch/metag/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_BARRIER_H #define _ASM_METAG_BARRIER_H diff --git a/arch/metag/include/asm/bitops.h b/arch/metag/include/asm/bitops.h index 2671134ee745..766ad43010ad 100644 --- a/arch/metag/include/asm/bitops.h +++ b/arch/metag/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_BITOPS_H #define __ASM_METAG_BITOPS_H diff --git a/arch/metag/include/asm/bug.h b/arch/metag/include/asm/bug.h index 9f8967f10f8c..ee07a943f931 100644 --- a/arch/metag/include/asm/bug.h +++ b/arch/metag/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_BUG_H #define _ASM_METAG_BUG_H diff --git a/arch/metag/include/asm/cache.h b/arch/metag/include/asm/cache.h index a43b650cfdc0..b5df02239c8d 100644 --- a/arch/metag/include/asm/cache.h +++ b/arch/metag/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_CACHE_H #define __ASM_METAG_CACHE_H diff --git a/arch/metag/include/asm/cacheflush.h b/arch/metag/include/asm/cacheflush.h index 7787ec5e3ed0..2584a51eca1a 100644 --- a/arch/metag/include/asm/cacheflush.h +++ b/arch/metag/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_CACHEFLUSH_H #define _METAG_CACHEFLUSH_H diff --git a/arch/metag/include/asm/cachepart.h b/arch/metag/include/asm/cachepart.h index cf6b44e916b5..79411e977586 100644 --- a/arch/metag/include/asm/cachepart.h +++ b/arch/metag/include/asm/cachepart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Meta cache partition manipulation. * diff --git a/arch/metag/include/asm/checksum.h b/arch/metag/include/asm/checksum.h index f65fe83b1730..6533d14e9789 100644 --- a/arch/metag/include/asm/checksum.h +++ b/arch/metag/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_CHECKSUM_H #define _METAG_CHECKSUM_H diff --git a/arch/metag/include/asm/cmpxchg.h b/arch/metag/include/asm/cmpxchg.h index be29e3e44321..68c4ab1466fd 100644 --- a/arch/metag/include/asm/cmpxchg.h +++ b/arch/metag/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_CMPXCHG_H #define __ASM_METAG_CMPXCHG_H diff --git a/arch/metag/include/asm/cmpxchg_irq.h b/arch/metag/include/asm/cmpxchg_irq.h index 649573168b05..5255e37f8496 100644 --- a/arch/metag/include/asm/cmpxchg_irq.h +++ b/arch/metag/include/asm/cmpxchg_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_CMPXCHG_IRQ_H #define __ASM_METAG_CMPXCHG_IRQ_H diff --git a/arch/metag/include/asm/cmpxchg_lnkget.h b/arch/metag/include/asm/cmpxchg_lnkget.h index 2369ad394876..c69be00a4739 100644 --- a/arch/metag/include/asm/cmpxchg_lnkget.h +++ b/arch/metag/include/asm/cmpxchg_lnkget.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_CMPXCHG_LNKGET_H #define __ASM_METAG_CMPXCHG_LNKGET_H diff --git a/arch/metag/include/asm/cmpxchg_lock1.h b/arch/metag/include/asm/cmpxchg_lock1.h index fd6850474969..5976e39db2b4 100644 --- a/arch/metag/include/asm/cmpxchg_lock1.h +++ b/arch/metag/include/asm/cmpxchg_lock1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_CMPXCHG_LOCK1_H #define __ASM_METAG_CMPXCHG_LOCK1_H diff --git a/arch/metag/include/asm/core_reg.h b/arch/metag/include/asm/core_reg.h index bdbc3a51f31c..ca70a0a29b61 100644 --- a/arch/metag/include/asm/core_reg.h +++ b/arch/metag/include/asm/core_reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_CORE_REG_H_ #define __ASM_METAG_CORE_REG_H_ diff --git a/arch/metag/include/asm/cpu.h b/arch/metag/include/asm/cpu.h index decf12969268..9dac67de4748 100644 --- a/arch/metag/include/asm/cpu.h +++ b/arch/metag/include/asm/cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_CPU_H #define _ASM_METAG_CPU_H diff --git a/arch/metag/include/asm/da.h b/arch/metag/include/asm/da.h index 81bd5212fb03..901daa540e6e 100644 --- a/arch/metag/include/asm/da.h +++ b/arch/metag/include/asm/da.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Meta DA JTAG debugger control. * diff --git a/arch/metag/include/asm/delay.h b/arch/metag/include/asm/delay.h index 9c92f996957a..fd73d3d5d294 100644 --- a/arch/metag/include/asm/delay.h +++ b/arch/metag/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_DELAY_H #define _METAG_DELAY_H diff --git a/arch/metag/include/asm/div64.h b/arch/metag/include/asm/div64.h index 0fdd11676212..e3686d2ae20e 100644 --- a/arch/metag/include/asm/div64.h +++ b/arch/metag/include/asm/div64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_DIV64_H__ #define __ASM_DIV64_H__ diff --git a/arch/metag/include/asm/dma-mapping.h b/arch/metag/include/asm/dma-mapping.h index fad3dc3cb210..7465ce54a4a9 100644 --- a/arch/metag/include/asm/dma-mapping.h +++ b/arch/metag/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_DMA_MAPPING_H #define _ASM_METAG_DMA_MAPPING_H @@ -9,7 +10,7 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) } /* - * dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to + * dma_alloc_attrs() always returns non-cacheable memory, so there's no need to * do any flushing here. */ static inline void diff --git a/arch/metag/include/asm/elf.h b/arch/metag/include/asm/elf.h index 87b0cf1e0acb..a6c33800ba66 100644 --- a/arch/metag/include/asm/elf.h +++ b/arch/metag/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_ELF_H #define __ASM_METAG_ELF_H diff --git a/arch/metag/include/asm/ftrace.h b/arch/metag/include/asm/ftrace.h index a2269d60a945..b1c8c76fb772 100644 --- a/arch/metag/include/asm/ftrace.h +++ b/arch/metag/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_FTRACE #define _ASM_METAG_FTRACE diff --git a/arch/metag/include/asm/global_lock.h b/arch/metag/include/asm/global_lock.h index fc831c88c22a..4d3da9682233 100644 --- a/arch/metag/include/asm/global_lock.h +++ b/arch/metag/include/asm/global_lock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_GLOBAL_LOCK_H #define __ASM_METAG_GLOBAL_LOCK_H diff --git a/arch/metag/include/asm/highmem.h b/arch/metag/include/asm/highmem.h index 9b1d172cd884..8b0dfd684e15 100644 --- a/arch/metag/include/asm/highmem.h +++ b/arch/metag/include/asm/highmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HIGHMEM_H #define _ASM_HIGHMEM_H diff --git a/arch/metag/include/asm/hugetlb.h b/arch/metag/include/asm/hugetlb.h index 905ed422dbeb..1607363d2639 100644 --- a/arch/metag/include/asm/hugetlb.h +++ b/arch/metag/include/asm/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_HUGETLB_H #define _ASM_METAG_HUGETLB_H diff --git a/arch/metag/include/asm/hwthread.h b/arch/metag/include/asm/hwthread.h index 8f9786619b1d..8d2171da5414 100644 --- a/arch/metag/include/asm/hwthread.h +++ b/arch/metag/include/asm/hwthread.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2008 Imagination Technologies */ diff --git a/arch/metag/include/asm/io.h b/arch/metag/include/asm/io.h index 9890f21eadbe..71cd2bc54718 100644 --- a/arch/metag/include/asm/io.h +++ b/arch/metag/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_IO_H #define _ASM_METAG_IO_H diff --git a/arch/metag/include/asm/irq.h b/arch/metag/include/asm/irq.h index 6ac6d4a051dd..cb02c29935a4 100644 --- a/arch/metag/include/asm/irq.h +++ b/arch/metag/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_IRQ_H #define __ASM_METAG_IRQ_H diff --git a/arch/metag/include/asm/irqflags.h b/arch/metag/include/asm/irqflags.h index 339b16f062eb..e2fe34acb93b 100644 --- a/arch/metag/include/asm/irqflags.h +++ b/arch/metag/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IRQ flags handling * diff --git a/arch/metag/include/asm/l2cache.h b/arch/metag/include/asm/l2cache.h index bffbeaa4d93b..f260b158b8fe 100644 --- a/arch/metag/include/asm/l2cache.h +++ b/arch/metag/include/asm/l2cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_L2CACHE_H #define _METAG_L2CACHE_H diff --git a/arch/metag/include/asm/linkage.h b/arch/metag/include/asm/linkage.h index 73bf25ba4e18..3a9024ecb827 100644 --- a/arch/metag/include/asm/linkage.h +++ b/arch/metag/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/metag/include/asm/mman.h b/arch/metag/include/asm/mman.h index 17999dba9275..dcb0d20a64fd 100644 --- a/arch/metag/include/asm/mman.h +++ b/arch/metag/include/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __METAG_MMAN_H__ #define __METAG_MMAN_H__ diff --git a/arch/metag/include/asm/mmu.h b/arch/metag/include/asm/mmu.h index 9c321147c0b4..cab5a01c3dcb 100644 --- a/arch/metag/include/asm/mmu.h +++ b/arch/metag/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MMU_H #define __MMU_H diff --git a/arch/metag/include/asm/mmu_context.h b/arch/metag/include/asm/mmu_context.h index 2e0312748197..7b4766379622 100644 --- a/arch/metag/include/asm/mmu_context.h +++ b/arch/metag/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __METAG_MMU_CONTEXT_H #define __METAG_MMU_CONTEXT_H diff --git a/arch/metag/include/asm/mmzone.h b/arch/metag/include/asm/mmzone.h index 9c88a9c65f59..8627fb532206 100644 --- a/arch/metag/include/asm/mmzone.h +++ b/arch/metag/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_MMZONE_H #define __ASM_METAG_MMZONE_H diff --git a/arch/metag/include/asm/module.h b/arch/metag/include/asm/module.h index e47e60941b2b..e957171c320b 100644 --- a/arch/metag/include/asm/module.h +++ b/arch/metag/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_MODULE_H #define _ASM_METAG_MODULE_H diff --git a/arch/metag/include/asm/page.h b/arch/metag/include/asm/page.h index 1e8e281b8bb7..9e994d77069d 100644 --- a/arch/metag/include/asm/page.h +++ b/arch/metag/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_PAGE_H #define _METAG_PAGE_H diff --git a/arch/metag/include/asm/pgalloc.h b/arch/metag/include/asm/pgalloc.h index c2caa1ee4360..0b9d95d78b61 100644 --- a/arch/metag/include/asm/pgalloc.h +++ b/arch/metag/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_PGALLOC_H #define _METAG_PGALLOC_H diff --git a/arch/metag/include/asm/pgtable-bits.h b/arch/metag/include/asm/pgtable-bits.h index 25ba6729f496..5f6b82282a41 100644 --- a/arch/metag/include/asm/pgtable-bits.h +++ b/arch/metag/include/asm/pgtable-bits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Meta page table definitions. */ diff --git a/arch/metag/include/asm/pgtable.h b/arch/metag/include/asm/pgtable.h index 0c151e5af079..a3422f06c03b 100644 --- a/arch/metag/include/asm/pgtable.h +++ b/arch/metag/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Macros and functions to manipulate Meta page tables. */ diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h index ec6a49076980..9a0c502cd4a0 100644 --- a/arch/metag/include/asm/processor.h +++ b/arch/metag/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2005,2006,2007,2008 Imagination Technologies */ @@ -131,9 +132,6 @@ static inline void release_thread(struct task_struct *dead_task) { } -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - /* * Return saved PC of a blocked thread. */ diff --git a/arch/metag/include/asm/ptrace.h b/arch/metag/include/asm/ptrace.h index fcabc18daf25..9074f254c9ca 100644 --- a/arch/metag/include/asm/ptrace.h +++ b/arch/metag/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_PTRACE_H #define _METAG_PTRACE_H diff --git a/arch/metag/include/asm/setup.h b/arch/metag/include/asm/setup.h index e9fdee9452b1..504621d79ef5 100644 --- a/arch/metag/include/asm/setup.h +++ b/arch/metag/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_SETUP_H #define _ASM_METAG_SETUP_H diff --git a/arch/metag/include/asm/smp.h b/arch/metag/include/asm/smp.h index 1d7e770f7a54..8d3683d83680 100644 --- a/arch/metag/include/asm/smp.h +++ b/arch/metag/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SMP_H #define __ASM_SMP_H diff --git a/arch/metag/include/asm/sparsemem.h b/arch/metag/include/asm/sparsemem.h index 03fe255d697a..2942894bace5 100644 --- a/arch/metag/include/asm/sparsemem.h +++ b/arch/metag/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_SPARSEMEM_H #define __ASM_METAG_SPARSEMEM_H diff --git a/arch/metag/include/asm/spinlock.h b/arch/metag/include/asm/spinlock.h index c0c7a22be1ae..349938c35f2d 100644 --- a/arch/metag/include/asm/spinlock.h +++ b/arch/metag/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H @@ -15,11 +16,6 @@ * locked. */ -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) diff --git a/arch/metag/include/asm/spinlock_lnkget.h b/arch/metag/include/asm/spinlock_lnkget.h index ad8436feed8d..029935560b7f 100644 --- a/arch/metag/include/asm/spinlock_lnkget.h +++ b/arch/metag/include/asm/spinlock_lnkget.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_LNKGET_H #define __ASM_SPINLOCK_LNKGET_H diff --git a/arch/metag/include/asm/spinlock_lock1.h b/arch/metag/include/asm/spinlock_lock1.h index c630444cffe9..12de9862d190 100644 --- a/arch/metag/include/asm/spinlock_lock1.h +++ b/arch/metag/include/asm/spinlock_lock1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_LOCK1_H #define __ASM_SPINLOCK_LOCK1_H diff --git a/arch/metag/include/asm/spinlock_types.h b/arch/metag/include/asm/spinlock_types.h index b76391405fea..cd197f1bed59 100644 --- a/arch/metag/include/asm/spinlock_types.h +++ b/arch/metag/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_SPINLOCK_TYPES_H #define _ASM_METAG_SPINLOCK_TYPES_H diff --git a/arch/metag/include/asm/stacktrace.h b/arch/metag/include/asm/stacktrace.h index 2830a0fe7ac9..f45e3cb2bbb5 100644 --- a/arch/metag/include/asm/stacktrace.h +++ b/arch/metag/include/asm/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_STACKTRACE_H #define __ASM_STACKTRACE_H diff --git a/arch/metag/include/asm/string.h b/arch/metag/include/asm/string.h index 53e3806eee04..86f9614d5fc6 100644 --- a/arch/metag/include/asm/string.h +++ b/arch/metag/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_STRING_H_ #define _METAG_STRING_H_ diff --git a/arch/metag/include/asm/syscalls.h b/arch/metag/include/asm/syscalls.h index a02b95556522..eac0cf120323 100644 --- a/arch/metag/include/asm/syscalls.h +++ b/arch/metag/include/asm/syscalls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_SYSCALLS_H #define _ASM_METAG_SYSCALLS_H diff --git a/arch/metag/include/asm/tcm.h b/arch/metag/include/asm/tcm.h index 7711c317b1d2..a0a4997e4b8a 100644 --- a/arch/metag/include/asm/tcm.h +++ b/arch/metag/include/asm/tcm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_TCM_H__ #define __ASM_TCM_H__ diff --git a/arch/metag/include/asm/thread_info.h b/arch/metag/include/asm/thread_info.h index 32677cc278aa..554f73a77e6e 100644 --- a/arch/metag/include/asm/thread_info.h +++ b/arch/metag/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* thread_info.h: Meta low-level thread information * * Copyright (C) 2002 David Howells (dhowells@redhat.com) diff --git a/arch/metag/include/asm/tlb.h b/arch/metag/include/asm/tlb.h index 048282f1cc1f..fbe6ee91e8e7 100644 --- a/arch/metag/include/asm/tlb.h +++ b/arch/metag/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_TLB_H #define __ASM_METAG_TLB_H diff --git a/arch/metag/include/asm/tlbflush.h b/arch/metag/include/asm/tlbflush.h index 566acf918a64..f3e5d99a3891 100644 --- a/arch/metag/include/asm/tlbflush.h +++ b/arch/metag/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_METAG_TLBFLUSH_H #define __ASM_METAG_TLBFLUSH_H diff --git a/arch/metag/include/asm/topology.h b/arch/metag/include/asm/topology.h index e95f874ded1b..df0d9e6b7f12 100644 --- a/arch/metag/include/asm/topology.h +++ b/arch/metag/include/asm/topology.h @@ -1,10 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_METAG_TOPOLOGY_H #define _ASM_METAG_TOPOLOGY_H #ifdef CONFIG_NUMA #define cpu_to_node(cpu) ((void)(cpu), 0) -#define parent_node(node) ((void)(node), 0) #define cpumask_of_node(node) ((void)node, cpu_online_mask) diff --git a/arch/metag/include/asm/uaccess.h b/arch/metag/include/asm/uaccess.h index 47469e26641a..a5311eb36e32 100644 --- a/arch/metag/include/asm/uaccess.h +++ b/arch/metag/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __METAG_UACCESS_H #define __METAG_UACCESS_H diff --git a/arch/metag/include/asm/user_gateway.h b/arch/metag/include/asm/user_gateway.h index e404c09e3b74..cf2392b95a56 100644 --- a/arch/metag/include/asm/user_gateway.h +++ b/arch/metag/include/asm/user_gateway.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2010 Imagination Technologies */ diff --git a/arch/metag/include/uapi/asm/byteorder.h b/arch/metag/include/uapi/asm/byteorder.h index 9558416d578b..e5e03ff7e20d 100644 --- a/arch/metag/include/uapi/asm/byteorder.h +++ b/arch/metag/include/uapi/asm/byteorder.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/metag/include/uapi/asm/ech.h b/arch/metag/include/uapi/asm/ech.h index ac94d1cf9be4..1e09f1ea4f7f 100644 --- a/arch/metag/include/uapi/asm/ech.h +++ b/arch/metag/include/uapi/asm/ech.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_METAG_ECH_H #define _UAPI_METAG_ECH_H diff --git a/arch/metag/include/uapi/asm/ptrace.h b/arch/metag/include/uapi/asm/ptrace.h index 45d97809d33e..8ad9daa841c3 100644 --- a/arch/metag/include/uapi/asm/ptrace.h +++ b/arch/metag/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_METAG_PTRACE_H #define _UAPI_METAG_PTRACE_H diff --git a/arch/metag/include/uapi/asm/sigcontext.h b/arch/metag/include/uapi/asm/sigcontext.h index ef79a910c1c4..ac7e1f28d584 100644 --- a/arch/metag/include/uapi/asm/sigcontext.h +++ b/arch/metag/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_METAG_SIGCONTEXT_H #define _ASM_METAG_SIGCONTEXT_H diff --git a/arch/metag/include/uapi/asm/siginfo.h b/arch/metag/include/uapi/asm/siginfo.h index b2e0c8b62aef..b54ef7186ca3 100644 --- a/arch/metag/include/uapi/asm/siginfo.h +++ b/arch/metag/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _METAG_SIGINFO_H #define _METAG_SIGINFO_H diff --git a/arch/metag/include/uapi/asm/swab.h b/arch/metag/include/uapi/asm/swab.h index 1076b3a6387a..30d696fcc237 100644 --- a/arch/metag/include/uapi/asm/swab.h +++ b/arch/metag/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_METAG_SWAB_H #define __ASM_METAG_SWAB_H diff --git a/arch/metag/include/uapi/asm/unistd.h b/arch/metag/include/uapi/asm/unistd.h index 459b6ec15848..9f72c4cfcfb5 100644 --- a/arch/metag/include/uapi/asm/unistd.h +++ b/arch/metag/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright (C) 2012 Imagination Technologies Ltd. * diff --git a/arch/metag/kernel/Makefile b/arch/metag/kernel/Makefile index d7675f4a5df8..73441d8c0369 100644 --- a/arch/metag/kernel/Makefile +++ b/arch/metag/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/Meta kernel. # diff --git a/arch/metag/kernel/asm-offsets.c b/arch/metag/kernel/asm-offsets.c index bfc9205f9647..d9b348b99ff2 100644 --- a/arch/metag/kernel/asm-offsets.c +++ b/arch/metag/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This program is used to generate definitions needed by * assembly language modules. diff --git a/arch/metag/kernel/cachepart.c b/arch/metag/kernel/cachepart.c index db944c2e7d88..6e0f8a80cc96 100644 --- a/arch/metag/kernel/cachepart.c +++ b/arch/metag/kernel/cachepart.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Meta cache partition manipulation. * diff --git a/arch/metag/kernel/core_reg.c b/arch/metag/kernel/core_reg.c index 671cce8c34f2..df2833f2766f 100644 --- a/arch/metag/kernel/core_reg.c +++ b/arch/metag/kernel/core_reg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for reading and writing Meta core internal registers. * diff --git a/arch/metag/kernel/head.S b/arch/metag/kernel/head.S index 713f71d1bdfe..3ed27813413e 100644 --- a/arch/metag/kernel/head.S +++ b/arch/metag/kernel/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ ! Copyright 2005,2006,2007,2009 Imagination Technologies #include diff --git a/arch/metag/kernel/irq.c b/arch/metag/kernel/irq.c index c9939604a38f..704cf17f8370 100644 --- a/arch/metag/kernel/irq.c +++ b/arch/metag/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Linux/Meta general interrupt handling code * diff --git a/arch/metag/kernel/machines.c b/arch/metag/kernel/machines.c index 1edf6ba193b1..e49790181051 100644 --- a/arch/metag/kernel/machines.c +++ b/arch/metag/kernel/machines.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/metag/kernel/machines.c * diff --git a/arch/metag/kernel/metag_ksyms.c b/arch/metag/kernel/metag_ksyms.c index 215c94ad63ac..e312386efb72 100644 --- a/arch/metag/kernel/metag_ksyms.c +++ b/arch/metag/kernel/metag_ksyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/metag/kernel/perf_callchain.c b/arch/metag/kernel/perf_callchain.c index 3e8e048040df..d325ba101de0 100644 --- a/arch/metag/kernel/perf_callchain.c +++ b/arch/metag/kernel/perf_callchain.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Perf callchain handling code. * diff --git a/arch/metag/kernel/process.c b/arch/metag/kernel/process.c index c4606ce743d2..0909834c83a7 100644 --- a/arch/metag/kernel/process.c +++ b/arch/metag/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2005,2006,2007,2008,2009,2010,2011 Imagination Technologies * diff --git a/arch/metag/kernel/signal.c b/arch/metag/kernel/signal.c index 338925d808e6..e64e8b0a9363 100644 --- a/arch/metag/kernel/signal.c +++ b/arch/metag/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991,1992 Linus Torvalds * Copyright (C) 2005-2012 Imagination Technologies Ltd. diff --git a/arch/metag/kernel/sys_metag.c b/arch/metag/kernel/sys_metag.c index efe833a452f7..27d96499dd38 100644 --- a/arch/metag/kernel/sys_metag.c +++ b/arch/metag/kernel/sys_metag.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file contains various random system calls that * have a non-standard calling sequence on the Linux/Meta diff --git a/arch/metag/kernel/tbiunexp.S b/arch/metag/kernel/tbiunexp.S index 907bbe0b2e68..2664808086c7 100644 --- a/arch/metag/kernel/tbiunexp.S +++ b/arch/metag/kernel/tbiunexp.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Pass a breakpoint through to Codescape */ #include diff --git a/arch/metag/kernel/tcm.c b/arch/metag/kernel/tcm.c index 5d102b31ce84..1d7b4e33b114 100644 --- a/arch/metag/kernel/tcm.c +++ b/arch/metag/kernel/tcm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2010 Imagination Technologies Ltd. */ diff --git a/arch/metag/kernel/time.c b/arch/metag/kernel/time.c index f1c8c53dace7..1e809e3b43d1 100644 --- a/arch/metag/kernel/time.c +++ b/arch/metag/kernel/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2005-2013 Imagination Technologies Ltd. * diff --git a/arch/metag/kernel/user_gateway.S b/arch/metag/kernel/user_gateway.S index 7167f3e8db6b..7833fb8f9ddd 100644 --- a/arch/metag/kernel/user_gateway.S +++ b/arch/metag/kernel/user_gateway.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2010 Imagination Technologies Ltd. * diff --git a/arch/metag/kernel/vmlinux.lds.S b/arch/metag/kernel/vmlinux.lds.S index e6c700eaf207..1efadae2ea8e 100644 --- a/arch/metag/kernel/vmlinux.lds.S +++ b/arch/metag/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make Meta Linux kernel */ #include diff --git a/arch/metag/lib/Makefile b/arch/metag/lib/Makefile index a41d24e270e6..3982850d692c 100644 --- a/arch/metag/lib/Makefile +++ b/arch/metag/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Meta-specific library files. # diff --git a/arch/metag/lib/ashldi3.S b/arch/metag/lib/ashldi3.S index 78d6974cffef..5055df9e5c7b 100644 --- a/arch/metag/lib/ashldi3.S +++ b/arch/metag/lib/ashldi3.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2012 by Imagination Technologies Ltd. ! ! 64-bit arithmetic shift left routine. diff --git a/arch/metag/lib/ashrdi3.S b/arch/metag/lib/ashrdi3.S index 7cb7ed3bb1ad..0c838fd9da85 100644 --- a/arch/metag/lib/ashrdi3.S +++ b/arch/metag/lib/ashrdi3.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2012 by Imagination Technologies Ltd. ! ! 64-bit arithmetic shift right routine. diff --git a/arch/metag/lib/clear_page.S b/arch/metag/lib/clear_page.S index 43144eebec55..87756a5d1367 100644 --- a/arch/metag/lib/clear_page.S +++ b/arch/metag/lib/clear_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ ! Copyright 2007,2008,2009 Imagination Technologies Ltd. #include diff --git a/arch/metag/lib/cmpdi2.S b/arch/metag/lib/cmpdi2.S index 9c5c663c5aea..ab70bd94fd81 100644 --- a/arch/metag/lib/cmpdi2.S +++ b/arch/metag/lib/cmpdi2.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2012 by Imagination Technologies Ltd. ! ! 64-bit signed compare routine. diff --git a/arch/metag/lib/copy_page.S b/arch/metag/lib/copy_page.S index 91f7d461239c..abbc75e94374 100644 --- a/arch/metag/lib/copy_page.S +++ b/arch/metag/lib/copy_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ ! Copyright 2007,2008 Imagination Technologies Ltd. #include diff --git a/arch/metag/lib/delay.c b/arch/metag/lib/delay.c index 0b308f48b37a..6754012a261f 100644 --- a/arch/metag/lib/delay.c +++ b/arch/metag/lib/delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Precise Delay Loops for Meta * diff --git a/arch/metag/lib/div64.S b/arch/metag/lib/div64.S index 1cfc93498f70..55eece273a6b 100644 --- a/arch/metag/lib/div64.S +++ b/arch/metag/lib/div64.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2012 Imagination Technologies Ltd. ! ! Signed/unsigned 64-bit division routines. diff --git a/arch/metag/lib/divsi3.S b/arch/metag/lib/divsi3.S index 11124cc93dee..9e31abefb160 100644 --- a/arch/metag/lib/divsi3.S +++ b/arch/metag/lib/divsi3.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 ! Imagination Technologies Ltd ! diff --git a/arch/metag/lib/ip_fast_csum.S b/arch/metag/lib/ip_fast_csum.S index 533b1e73deac..441f489d6a81 100644 --- a/arch/metag/lib/ip_fast_csum.S +++ b/arch/metag/lib/ip_fast_csum.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .text /* diff --git a/arch/metag/lib/lshrdi3.S b/arch/metag/lib/lshrdi3.S index 47f720283077..cf7ffc9b377f 100644 --- a/arch/metag/lib/lshrdi3.S +++ b/arch/metag/lib/lshrdi3.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2012 by Imagination Technologies Ltd. ! ! 64-bit logical shift right routine. diff --git a/arch/metag/lib/memcpy.S b/arch/metag/lib/memcpy.S index 46b7a2b9479e..c2e8395f9456 100644 --- a/arch/metag/lib/memcpy.S +++ b/arch/metag/lib/memcpy.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2008-2012 Imagination Technologies Ltd. .text diff --git a/arch/metag/lib/memmove.S b/arch/metag/lib/memmove.S index 228ea04d7b39..934abda0e680 100644 --- a/arch/metag/lib/memmove.S +++ b/arch/metag/lib/memmove.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2008-2012 Imagination Technologies Ltd. .text diff --git a/arch/metag/lib/memset.S b/arch/metag/lib/memset.S index 721085bad1d2..6ee246d831c7 100644 --- a/arch/metag/lib/memset.S +++ b/arch/metag/lib/memset.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2008-2012 Imagination Technologies Ltd. .text diff --git a/arch/metag/lib/modsi3.S b/arch/metag/lib/modsi3.S index 210cfa856593..d65a2e5b3154 100644 --- a/arch/metag/lib/modsi3.S +++ b/arch/metag/lib/modsi3.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 ! Imagination Technologies Ltd ! diff --git a/arch/metag/lib/muldi3.S b/arch/metag/lib/muldi3.S index ee66ca8644d0..9d106790244d 100644 --- a/arch/metag/lib/muldi3.S +++ b/arch/metag/lib/muldi3.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2012 by Imagination Technologies Ltd. ! ! 64-bit multiply routine. diff --git a/arch/metag/lib/ucmpdi2.S b/arch/metag/lib/ucmpdi2.S index 6f3347f7daeb..46f5686db8b1 100644 --- a/arch/metag/lib/ucmpdi2.S +++ b/arch/metag/lib/ucmpdi2.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! Copyright (C) 2012 by Imagination Technologies Ltd. ! ! 64-bit unsigned compare routine. diff --git a/arch/metag/lib/usercopy.c b/arch/metag/lib/usercopy.c index c941abdb8f85..a48ef522c02d 100644 --- a/arch/metag/lib/usercopy.c +++ b/arch/metag/lib/usercopy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * User address space access functions. * The non-inlined parts of asm-metag/uaccess.h are here. diff --git a/arch/metag/mm/Kconfig b/arch/metag/mm/Kconfig index 03fb8f1555a1..9d4b2c67dcc1 100644 --- a/arch/metag/mm/Kconfig +++ b/arch/metag/mm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Memory management options" config PAGE_OFFSET diff --git a/arch/metag/mm/Makefile b/arch/metag/mm/Makefile index 994331164125..0c7c91ba9fb9 100644 --- a/arch/metag/mm/Makefile +++ b/arch/metag/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux Meta-specific parts of the memory manager. # diff --git a/arch/metag/mm/extable.c b/arch/metag/mm/extable.c index 3aa90b78b43d..9b92d3ad7f9c 100644 --- a/arch/metag/mm/extable.c +++ b/arch/metag/mm/extable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/metag/mm/fault.c b/arch/metag/mm/fault.c index 5055477486b6..de54fe686080 100644 --- a/arch/metag/mm/fault.c +++ b/arch/metag/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Meta page fault handling. * diff --git a/arch/metag/mm/highmem.c b/arch/metag/mm/highmem.c index f19a87f2c1ec..83527fc7c8a7 100644 --- a/arch/metag/mm/highmem.c +++ b/arch/metag/mm/highmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c index 67fd53e2935a..012ee4c80dc7 100644 --- a/arch/metag/mm/hugetlbpage.c +++ b/arch/metag/mm/hugetlbpage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/metag/mm/hugetlbpage.c * diff --git a/arch/metag/mm/init.c b/arch/metag/mm/init.c index 188d4d9fbed4..0e2ca9058998 100644 --- a/arch/metag/mm/init.c +++ b/arch/metag/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2005,2006,2007,2008,2009,2010 Imagination Technologies * diff --git a/arch/metag/mm/ioremap.c b/arch/metag/mm/ioremap.c index a136a435fdaa..df2b59cb02eb 100644 --- a/arch/metag/mm/ioremap.c +++ b/arch/metag/mm/ioremap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Re-map IO memory to kernel address space so that we can access it. * Needed for memory-mapped I/O devices mapped outside our normal DRAM diff --git a/arch/metag/mm/l2cache.c b/arch/metag/mm/l2cache.c index c64ee615cf90..addffc58989c 100644 --- a/arch/metag/mm/l2cache.c +++ b/arch/metag/mm/l2cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/metag/mm/maccess.c b/arch/metag/mm/maccess.c index eba2cfc935b1..c22755165df9 100644 --- a/arch/metag/mm/maccess.c +++ b/arch/metag/mm/maccess.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * safe read and write memory routines callable while atomic * diff --git a/arch/metag/mm/mmu-meta1.c b/arch/metag/mm/mmu-meta1.c index 62ebab90924d..53190b13dc54 100644 --- a/arch/metag/mm/mmu-meta1.c +++ b/arch/metag/mm/mmu-meta1.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2005,2006,2007,2008,2009 Imagination Technologies * diff --git a/arch/metag/mm/mmu-meta2.c b/arch/metag/mm/mmu-meta2.c index 81dcbb0bba34..8b668a69c980 100644 --- a/arch/metag/mm/mmu-meta2.c +++ b/arch/metag/mm/mmu-meta2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2008,2009,2010,2011 Imagination Technologies Ltd. * diff --git a/arch/metag/oprofile/Makefile b/arch/metag/oprofile/Makefile index c9639d4734d6..dc92a4a3d618 100644 --- a/arch/metag/oprofile/Makefile +++ b/arch/metag/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o oprofile-core-y += buffer_sync.o diff --git a/arch/metag/oprofile/backtrace.h b/arch/metag/oprofile/backtrace.h index c0fcc4265abb..60adb862aa2c 100644 --- a/arch/metag/oprofile/backtrace.h +++ b/arch/metag/oprofile/backtrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _METAG_OPROFILE_BACKTRACE_H #define _METAG_OPROFILE_BACKTRACE_H diff --git a/arch/metag/tbx/Makefile b/arch/metag/tbx/Makefile index e994239e518c..98bc5453cf24 100644 --- a/arch/metag/tbx/Makefile +++ b/arch/metag/tbx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for TBX library files.. # diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 4ed8ebf33509..4f798aa671dd 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -36,6 +36,22 @@ config MICROBLAZE select VIRT_TO_BUS select CPU_NO_EFFICIENT_FFS +# Endianness selection +choice + prompt "Endianness selection" + default CPU_LITTLE_ENDIAN + help + microblaze architectures can be configured for either little or + big endian formats. Be sure to select the appropriate mode. + +config CPU_BIG_ENDIAN + bool "Big endian" + +config CPU_LITTLE_ENDIAN + bool "Little endian" + +endchoice + config SWAP def_bool n diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 740f2b82a182..830ee7d42fa0 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 KBUILD_DEFCONFIG := mmu_defconfig ifeq ($(CONFIG_MMU),y) @@ -35,6 +36,8 @@ endif CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) += -mxl-pattern-compare +CPUFLAGS-$(CONFIG_BIG_ENDIAN) += -mbig-endian +CPUFLAGS-$(CONFIG_LITTLE_ENDIAN) += -mlittle-endian CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER)) diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile index 91d2068da1b9..47f94cc383b6 100644 --- a/arch/microblaze/boot/Makefile +++ b/arch/microblaze/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/microblaze/boot/Makefile # diff --git a/arch/microblaze/boot/dts/Makefile b/arch/microblaze/boot/dts/Makefile index a3d2e42c3c97..1f77913d404d 100644 --- a/arch/microblaze/boot/dts/Makefile +++ b/arch/microblaze/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # obj-y += linked_dtb.o diff --git a/arch/microblaze/include/asm/asm-compat.h b/arch/microblaze/include/asm/asm-compat.h index e7bc9dc11b57..c05259ce2d2c 100644 --- a/arch/microblaze/include/asm/asm-compat.h +++ b/arch/microblaze/include/asm/asm-compat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MICROBLAZE_ASM_COMPAT_H #define _ASM_MICROBLAZE_ASM_COMPAT_H diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h index 42ac382a09da..41e9aff23a62 100644 --- a/arch/microblaze/include/asm/atomic.h +++ b/arch/microblaze/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MICROBLAZE_ATOMIC_H #define _ASM_MICROBLAZE_ATOMIC_H diff --git a/arch/microblaze/include/asm/cmpxchg.h b/arch/microblaze/include/asm/cmpxchg.h index 538afc0ab9f3..596300c74509 100644 --- a/arch/microblaze/include/asm/cmpxchg.h +++ b/arch/microblaze/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MICROBLAZE_CMPXCHG_H #define _ASM_MICROBLAZE_CMPXCHG_H diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h index f23c3d266bae..3d2747d4c967 100644 --- a/arch/microblaze/include/asm/flat.h +++ b/arch/microblaze/include/asm/flat.h @@ -60,7 +60,7 @@ static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags, * unaligned. */ -static inline void +static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 relval) { u32 *p = (__force u32 *)rp; diff --git a/arch/microblaze/include/asm/ftrace.h b/arch/microblaze/include/asm/ftrace.h index da0144f40d99..5db7f4489f05 100644 --- a/arch/microblaze/include/asm/ftrace.h +++ b/arch/microblaze/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MICROBLAZE_FTRACE #define _ASM_MICROBLAZE_FTRACE diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h index 01848f056f43..2572077b04ea 100644 --- a/arch/microblaze/include/asm/futex.h +++ b/arch/microblaze/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MICROBLAZE_FUTEX_H #define _ASM_MICROBLAZE_FUTEX_H @@ -29,18 +30,9 @@ }) static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -66,30 +58,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/microblaze/include/asm/hash.h b/arch/microblaze/include/asm/hash.h index 753513ae8cb0..ef4741a40583 100644 --- a/arch/microblaze/include/asm/hash.h +++ b/arch/microblaze/include/asm/hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HASH_H #define _ASM_HASH_H diff --git a/arch/microblaze/include/asm/highmem.h b/arch/microblaze/include/asm/highmem.h index 67925ef18cfa..332c78e15198 100644 --- a/arch/microblaze/include/asm/highmem.h +++ b/arch/microblaze/include/asm/highmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * highmem.h: virtual kernel memory mappings for high memory * diff --git a/arch/microblaze/include/asm/kgdb.h b/arch/microblaze/include/asm/kgdb.h index ad27acb2b15f..8dc5ebb07fd5 100644 --- a/arch/microblaze/include/asm/kgdb.h +++ b/arch/microblaze/include/asm/kgdb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __KERNEL__ #ifndef __MICROBLAZE_KGDB_H__ #define __MICROBLAZE_KGDB_H__ diff --git a/arch/microblaze/include/asm/mmu_context.h b/arch/microblaze/include/asm/mmu_context.h index 0ccd8c402cd9..f74f9da07fdc 100644 --- a/arch/microblaze/include/asm/mmu_context.h +++ b/arch/microblaze/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_MMU # include #else diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index efd4983cb697..114b93488193 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -81,9 +81,6 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, #define HAVE_ARCH_PCI_RESOURCE_TO_USER -extern void pcibios_setup_bus_devices(struct pci_bus *bus); -extern void pcibios_setup_bus_self(struct pci_bus *bus); - /* This part of code was originally in xilinx-pci.h */ #ifdef CONFIG_PCI_XILINX extern void __init xilinx_pci_init(void); diff --git a/arch/microblaze/include/asm/seccomp.h b/arch/microblaze/include/asm/seccomp.h index 204618a2ce84..95cdcabee28c 100644 --- a/arch/microblaze/include/asm/seccomp.h +++ b/arch/microblaze/include/asm/seccomp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MICROBLAZE_SECCOMP_H #define _ASM_MICROBLAZE_SECCOMP_H diff --git a/arch/microblaze/include/asm/syscall.h b/arch/microblaze/include/asm/syscall.h index 04a5bece8168..220decd605a4 100644 --- a/arch/microblaze/include/asm/syscall.h +++ b/arch/microblaze/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MICROBLAZE_SYSCALL_H #define __ASM_MICROBLAZE_SYSCALL_H diff --git a/arch/microblaze/include/uapi/asm/Kbuild b/arch/microblaze/include/uapi/asm/Kbuild index e77a596f3f1e..06609ca36115 100644 --- a/arch/microblaze/include/uapi/asm/Kbuild +++ b/arch/microblaze/include/uapi/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += fcntl.h generic-y += ioctl.h generic-y += ioctls.h generic-y += ipcbuf.h +generic-y += kvm_para.h generic-y += mman.h generic-y += msgbuf.h generic-y += param.h diff --git a/arch/microblaze/include/uapi/asm/auxvec.h b/arch/microblaze/include/uapi/asm/auxvec.h index 8b137891791f..93dd07bd0af7 100644 --- a/arch/microblaze/include/uapi/asm/auxvec.h +++ b/arch/microblaze/include/uapi/asm/auxvec.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ diff --git a/arch/microblaze/include/uapi/asm/byteorder.h b/arch/microblaze/include/uapi/asm/byteorder.h index 31902762a426..763660169456 100644 --- a/arch/microblaze/include/uapi/asm/byteorder.h +++ b/arch/microblaze/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_MICROBLAZE_BYTEORDER_H #define _ASM_MICROBLAZE_BYTEORDER_H diff --git a/arch/microblaze/include/uapi/asm/elf.h b/arch/microblaze/include/uapi/asm/elf.h index e9bcdb6e0086..6b656de29f00 100644 --- a/arch/microblaze/include/uapi/asm/elf.h +++ b/arch/microblaze/include/uapi/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2008-2009 Michal Simek * Copyright (C) 2008-2009 PetaLogix diff --git a/arch/microblaze/include/uapi/asm/posix_types.h b/arch/microblaze/include/uapi/asm/posix_types.h index 0e15039673e3..f3249da69121 100644 --- a/arch/microblaze/include/uapi/asm/posix_types.h +++ b/arch/microblaze/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_MICROBLAZE_POSIX_TYPES_H #define _ASM_MICROBLAZE_POSIX_TYPES_H diff --git a/arch/microblaze/include/uapi/asm/ptrace.h b/arch/microblaze/include/uapi/asm/ptrace.h index d31238a5f946..46dd94cb7802 100644 --- a/arch/microblaze/include/uapi/asm/ptrace.h +++ b/arch/microblaze/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2006 Atmark Techno, Inc. * diff --git a/arch/microblaze/include/uapi/asm/setup.h b/arch/microblaze/include/uapi/asm/setup.h index 76bc2acee6af..6831794e6f2c 100644 --- a/arch/microblaze/include/uapi/asm/setup.h +++ b/arch/microblaze/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2007-2009 Michal Simek * Copyright (C) 2007-2009 PetaLogix diff --git a/arch/microblaze/include/uapi/asm/sigcontext.h b/arch/microblaze/include/uapi/asm/sigcontext.h index 55873c80c917..47eb2e2111bb 100644 --- a/arch/microblaze/include/uapi/asm/sigcontext.h +++ b/arch/microblaze/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2006 Atmark Techno, Inc. * diff --git a/arch/microblaze/include/uapi/asm/unistd.h b/arch/microblaze/include/uapi/asm/unistd.h index a88b3c11cc20..eb156f914793 100644 --- a/arch/microblaze/include/uapi/asm/unistd.h +++ b/arch/microblaze/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2007-2008 Michal Simek * Copyright (C) 2006 Atmark Techno, Inc. diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index e098381af928..0da76fa1ab17 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile # diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile index fceed4edea41..059afc75a976 100644 --- a/arch/microblaze/kernel/cpu/Makefile +++ b/arch/microblaze/kernel/cpu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Build the appropriate CPU version support # diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index e45ada8fb006..e63f154be964 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2009-2010 PetaLogix * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation @@ -165,7 +166,7 @@ int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma, unsigned long attrs) { #ifdef CONFIG_MMU - unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; + unsigned long user_count = vma_pages(vma); unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; unsigned long off = vma->vm_pgoff; unsigned long pfn; diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index c48ff4ad2070..56bcf313121f 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ ENTRY(sys_call_table) .long sys_restart_syscall /* 0 - old "setup()" system call, * used for restarting */ diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index ea2d83f1f4bb..7de941cbbd94 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -293,7 +293,7 @@ static int __init xilinx_timer_init(struct device_node *timer) return -EINVAL; } - pr_info("%s: irq=%d\n", timer->full_name, irq); + pr_info("%pOF: irq=%d\n", timer, irq); clk = of_clk_get(timer, 0); if (IS_ERR(clk)) { diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index 70c7ae6a3fb5..9fe7ab688ca5 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile # diff --git a/arch/microblaze/lib/ashldi3.c b/arch/microblaze/lib/ashldi3.c index 1af904cd972d..4d0f9481bdb7 100644 --- a/arch/microblaze/lib/ashldi3.c +++ b/arch/microblaze/lib/ashldi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/microblaze/lib/ashrdi3.c b/arch/microblaze/lib/ashrdi3.c index 32c334c05d04..268098a962a1 100644 --- a/arch/microblaze/lib/ashrdi3.c +++ b/arch/microblaze/lib/ashrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/microblaze/lib/cmpdi2.c b/arch/microblaze/lib/cmpdi2.c index 67abc9ac1bd4..b3f89638518c 100644 --- a/arch/microblaze/lib/cmpdi2.c +++ b/arch/microblaze/lib/cmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/microblaze/lib/divsi3.S b/arch/microblaze/lib/divsi3.S index 595b02d6e86b..919fb69f8589 100644 --- a/arch/microblaze/lib/divsi3.S +++ b/arch/microblaze/lib/divsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/microblaze/lib/libgcc.h b/arch/microblaze/lib/libgcc.h index ab077ef7e14b..a909366c202e 100644 --- a/arch/microblaze/lib/libgcc.h +++ b/arch/microblaze/lib/libgcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LIBGCC_H #define __ASM_LIBGCC_H diff --git a/arch/microblaze/lib/lshrdi3.c b/arch/microblaze/lib/lshrdi3.c index adcb253f11c8..00eb8268227a 100644 --- a/arch/microblaze/lib/lshrdi3.c +++ b/arch/microblaze/lib/lshrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/microblaze/lib/modsi3.S b/arch/microblaze/lib/modsi3.S index 84e0bee6e8c7..64154865c1c5 100644 --- a/arch/microblaze/lib/modsi3.S +++ b/arch/microblaze/lib/modsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/microblaze/lib/muldi3.c b/arch/microblaze/lib/muldi3.c index a3f9a03acdcd..8e6bc17e2cd3 100644 --- a/arch/microblaze/lib/muldi3.c +++ b/arch/microblaze/lib/muldi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/microblaze/lib/mulsi3.S b/arch/microblaze/lib/mulsi3.S index 90bd7b93afe6..d6703a4d91f6 100644 --- a/arch/microblaze/lib/mulsi3.S +++ b/arch/microblaze/lib/mulsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/microblaze/lib/ucmpdi2.c b/arch/microblaze/lib/ucmpdi2.c index d05f1585121c..c60e068ff8bb 100644 --- a/arch/microblaze/lib/ucmpdi2.c +++ b/arch/microblaze/lib/ucmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/microblaze/lib/udivsi3.S b/arch/microblaze/lib/udivsi3.S index 64cf57e4bb85..acdc667235c4 100644 --- a/arch/microblaze/lib/udivsi3.S +++ b/arch/microblaze/lib/udivsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/microblaze/lib/umodsi3.S b/arch/microblaze/lib/umodsi3.S index 17d16bafae58..f4b814e88ce3 100644 --- a/arch/microblaze/lib/umodsi3.S +++ b/arch/microblaze/lib/umodsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/microblaze/mm/highmem.c b/arch/microblaze/mm/highmem.c index ed4454c5ce35..d7569f77fa15 100644 --- a/arch/microblaze/mm/highmem.c +++ b/arch/microblaze/mm/highmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * highmem.c: virtual kernel memory mappings for high memory * diff --git a/arch/microblaze/oprofile/Makefile b/arch/microblaze/oprofile/Makefile index 0d0348c8af97..107f2f55d995 100644 --- a/arch/microblaze/oprofile/Makefile +++ b/arch/microblaze/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # arch/microblaze/oprofile/Makefile # diff --git a/arch/microblaze/pci/iomap.c b/arch/microblaze/pci/iomap.c index 94149f5e6ebe..bde74af4c1cd 100644 --- a/arch/microblaze/pci/iomap.c +++ b/arch/microblaze/pci/iomap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ppc64 "iomap" interface implementation. * diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 404fb38d06b7..ae79e8638d50 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -508,8 +508,8 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, struct of_pci_range range; struct of_pci_range_parser parser; - pr_info("PCI host bridge %s %s ranges:\n", - dev->full_name, primary ? "(primary)" : ""); + pr_info("PCI host bridge %pOF %s ranges:\n", + dev, primary ? "(primary)" : ""); /* Check for ranges property */ if (of_pci_range_parser_init(&parser, dev)) @@ -678,144 +678,6 @@ static void pcibios_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); -/* This function tries to figure out if a bridge resource has been initialized - * by the firmware or not. It doesn't have to be absolutely bullet proof, but - * things go more smoothly when it gets it right. It should covers cases such - * as Apple "closed" bridge resources and bare-metal pSeries unassigned bridges - */ -static int pcibios_uninitialized_bridge_resource(struct pci_bus *bus, - struct resource *res) -{ - struct pci_controller *hose = pci_bus_to_host(bus); - struct pci_dev *dev = bus->self; - resource_size_t offset; - u16 command; - int i; - - /* Job is a bit different between memory and IO */ - if (res->flags & IORESOURCE_MEM) { - /* If the BAR is non-0 (res != pci_mem_offset) then it's - * probably been initialized by somebody - */ - if (res->start != hose->pci_mem_offset) - return 0; - - /* The BAR is 0, let's check if memory decoding is enabled on - * the bridge. If not, we consider it unassigned - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if ((command & PCI_COMMAND_MEMORY) == 0) - return 1; - - /* Memory decoding is enabled and the BAR is 0. If any of - * the bridge resources covers that starting address (0 then - * it's good enough for us for memory - */ - for (i = 0; i < 3; i++) { - if ((hose->mem_resources[i].flags & IORESOURCE_MEM) && - hose->mem_resources[i].start == hose->pci_mem_offset) - return 0; - } - - /* Well, it starts at 0 and we know it will collide so we may as - * well consider it as unassigned. That covers the Apple case. - */ - return 1; - } else { - /* If the BAR is non-0, then we consider it assigned */ - offset = (unsigned long)hose->io_base_virt - _IO_BASE; - if (((res->start - offset) & 0xfffffffful) != 0) - return 0; - - /* Here, we are a bit different than memory as typically IO - * space starting at low addresses -is- valid. What we do - * instead if that we consider as unassigned anything that - * doesn't have IO enabled in the PCI command register, - * and that's it. - */ - pci_read_config_word(dev, PCI_COMMAND, &command); - if (command & PCI_COMMAND_IO) - return 0; - - /* It's starting at 0 and IO is disabled in the bridge, consider - * it unassigned - */ - return 1; - } -} - -/* Fixup resources of a PCI<->PCI bridge */ -static void pcibios_fixup_bridge(struct pci_bus *bus) -{ - struct resource *res; - int i; - - struct pci_dev *dev = bus->self; - - pci_bus_for_each_resource(bus, res, i) { - if (!res) - continue; - if (!res->flags) - continue; - if (i >= 3 && bus->self->transparent) - continue; - - pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", - pci_name(dev), i, - (unsigned long long)res->start, - (unsigned long long)res->end, - (unsigned int)res->flags); - - /* Try to detect uninitialized P2P bridge resources, - * and clear them out so they get re-assigned later - */ - if (pcibios_uninitialized_bridge_resource(bus, res)) { - res->flags = 0; - pr_debug("PCI:%s (unassigned)\n", - pci_name(dev)); - } else { - pr_debug("PCI:%s %016llx-%016llx\n", - pci_name(dev), - (unsigned long long)res->start, - (unsigned long long)res->end); - } - } -} - -void pcibios_setup_bus_self(struct pci_bus *bus) -{ - /* Fix up the bus resources for P2P bridges */ - if (bus->self != NULL) - pcibios_fixup_bridge(bus); -} - -void pcibios_setup_bus_devices(struct pci_bus *bus) -{ - struct pci_dev *dev; - - pr_debug("PCI: Fixup bus devices %d (%s)\n", - bus->number, bus->self ? pci_name(bus->self) : "PHB"); - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* Setup OF node pointer in archdata */ - dev->dev.of_node = pci_device_to_OF_node(dev); - - /* Fixup NUMA node as it may not be setup yet by the generic - * code and is needed by the DMA init - */ - set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); - - /* Read default IRQs and fixup if necessary */ - dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); - } -} - -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* nothing to do */ -} -EXPORT_SYMBOL(pcibios_fixup_bus); - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -829,13 +691,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - int pcibios_add_device(struct pci_dev *dev) { dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); @@ -1219,8 +1074,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, if (!res->flags) { pr_warn("PCI: I/O resource not set for host "); - pr_cont("bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + pr_cont("bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); /* Workaround for lack of IO resource only on 32-bit */ res->start = (unsigned long)hose->io_base_virt - isa_io_base; res->end = res->start + IO_SPACE_LIMIT; @@ -1241,8 +1096,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, if (i > 0) continue; pr_err("PCI: Memory resource 0 not set for "); - pr_cont("host bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + pr_cont("host bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); /* Workaround for lack of MEM resource only on 32-bit */ res->start = hose->pci_mem_offset; @@ -1270,7 +1125,7 @@ static void pcibios_scan_phb(struct pci_controller *hose) struct pci_bus *bus; struct device_node *node = hose->dn; - pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node)); + pr_debug("PCI: Scanning PHB %pOF\n", node); pcibios_setup_phb_resources(hose, &resources); diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 48d91d5be4e9..5d3284d20678 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config MIPS bool default y @@ -1627,14 +1628,6 @@ config CPU_R5500 NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV instruction set. -config CPU_R6000 - bool "R6000" - depends on SYS_HAS_CPU_R6000 - select CPU_SUPPORTS_32BIT_KERNEL - help - MIPS Technologies R6000 and R6000A series processors. Note these - processors are extremely rare and the support for them is incomplete. - config CPU_NEVADA bool "RM52xx" depends on SYS_HAS_CPU_NEVADA @@ -1950,9 +1943,6 @@ config SYS_HAS_CPU_R5432 config SYS_HAS_CPU_R5500 bool -config SYS_HAS_CPU_R6000 - bool - config SYS_HAS_CPU_NEVADA bool @@ -2180,7 +2170,7 @@ config PAGE_SIZE_32KB config PAGE_SIZE_64KB bool "64kB" - depends on !CPU_R3000 && !CPU_TX39XX && !CPU_R6000 + depends on !CPU_R3000 && !CPU_TX39XX help Using 64kB page size will result in higher performance kernel at the price of higher memory consumption. This option is available on @@ -2248,11 +2238,11 @@ config CPU_HAS_PREFETCH config CPU_GENERIC_DUMP_TLB bool - default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX) + default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX) config CPU_R4K_FPU bool - default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON) + default y if !(CPU_R3000 || CPU_TX39XX) config CPU_R4K_CACHE_TLB bool @@ -2260,6 +2250,7 @@ config CPU_R4K_CACHE_TLB config MIPS_MT_SMP bool "MIPS MT SMP support (1 TC on each available VPE)" + default y depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6 && !CPU_MICROMIPS select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_EI @@ -2376,7 +2367,6 @@ config MIPS_CPS bool "MIPS Coherent Processing System support" depends on SYS_SUPPORTS_MIPS_CPS select MIPS_CM - select MIPS_CPC select MIPS_CPS_PM if HOTPLUG_CPU select SMP select SYNC_R4K if (CEVT_R4K || CSRC_R4K) @@ -2393,11 +2383,11 @@ config MIPS_CPS config MIPS_CPS_PM depends on MIPS_CPS - select MIPS_CPC bool config MIPS_CM bool + select MIPS_CPC config MIPS_CPC bool diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 42a97c59200f..464af5e025d6 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT diff --git a/arch/mips/Makefile b/arch/mips/Makefile index bc2708c9ada4..a96d97a806c9 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -151,7 +151,6 @@ cflags-y += -fno-stack-check # cflags-$(CONFIG_CPU_R3000) += -march=r3000 cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 -cflags-$(CONFIG_CPU_R6000) += -march=r6000 -Wa,--trap cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap @@ -291,7 +290,8 @@ KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ VMLINUX_ENTRY_ADDRESS=$(entry-y) \ - PLATFORM="$(platform-y)" + PLATFORM="$(platform-y)" \ + ITS_INPUTS="$(its-y)" ifdef CONFIG_32BIT bootvars-y += ADDR_BITS=32 endif @@ -299,6 +299,10 @@ ifdef CONFIG_64BIT bootvars-y += ADDR_BITS=64 endif +# This is required to get dwarf unwinding tables into .debug_frame +# instead of .eh_frame so we don't discard them. +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables + LDFLAGS += -m $(ld-emul) ifdef CONFIG_MIPS @@ -500,8 +504,14 @@ $(eval $(call gen_generic_defconfigs,micro32,r2,eb el)) .PHONY: $(generic_defconfigs) $(generic_defconfigs): $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ - -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \ - $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config) + -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ | \ + grep -Ev '^#' + $(Q)cp $(KCONFIG_CONFIG) $(objtree)/.config.$@ + $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig \ + KCONFIG_CONFIG=$(objtree)/.config.$@ >/dev/null + $(Q)$(CONFIG_SHELL) $(srctree)/arch/$(ARCH)/tools/generic-board-config.sh \ + $(srctree) $(objtree) $(objtree)/.config.$@ $(KCONFIG_CONFIG) \ + "$(origin BOARDS)" $(BOARDS) $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig # @@ -509,6 +519,19 @@ $(generic_defconfigs): # $(generic_config_dir)/%.config: ; +# +# Prevent direct use of generic_defconfig, which is intended to be used as the +# basis of the various ISA-specific targets generated above. +# +.PHONY: generic_defconfig +generic_defconfig: + $(Q)echo "generic_defconfig is not intended for direct use, but should instead be" + $(Q)echo "used via an ISA-specific target from the following list:" + $(Q)echo + $(Q)for cfg in $(generic_defconfigs); do echo " $${cfg}"; done + $(Q)echo + $(Q)false + # # Legacy defconfig compatibility - these targets used to be real defconfigs but # now that the boards have been converted to use the generic kernel they are diff --git a/arch/mips/Makefile.postlink b/arch/mips/Makefile.postlink index 4b7f5a648c79..4eea4188cb20 100644 --- a/arch/mips/Makefile.postlink +++ b/arch/mips/Makefile.postlink @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # =========================================================================== # Post-link MIPS pass # =========================================================================== diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig index 88b4d6a792c1..7d73f7f4202b 100644 --- a/arch/mips/alchemy/Kconfig +++ b/arch/mips/alchemy/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # au1000-style gpio and interrupt controllers config ALCHEMY_GPIOINT_AU1000 bool diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index 7ba7ea0a22f8..a83c7b7e2eb1 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Alchemy clocks. * diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index 992442a03d8b..da7663770425 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -344,28 +344,32 @@ static struct platform_device db1200_ide_dev = { /* SD carddetects: they're supposed to be edge-triggered, but ack * doesn't seem to work (CPLD Rev 2). Instead, the screaming one - * is disabled and its counterpart enabled. The 500ms timeout is - * because the carddetect isn't debounced in hardware. + * is disabled and its counterpart enabled. The 200ms timeout is + * because the carddetect usually triggers twice, after debounce. */ static irqreturn_t db1200_mmc_cd(int irq, void *ptr) { - void(*mmc_cd)(struct mmc_host *, unsigned long); + disable_irq_nosync(irq); + return IRQ_WAKE_THREAD; +} - if (irq == DB1200_SD0_INSERT_INT) { - disable_irq_nosync(DB1200_SD0_INSERT_INT); - enable_irq(DB1200_SD0_EJECT_INT); - } else { - disable_irq_nosync(DB1200_SD0_EJECT_INT); - enable_irq(DB1200_SD0_INSERT_INT); - } +static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr) +{ + void (*mmc_cd)(struct mmc_host *, unsigned long); /* link against CONFIG_MMC=m */ mmc_cd = symbol_get(mmc_detect_change); if (mmc_cd) { - mmc_cd(ptr, msecs_to_jiffies(500)); + mmc_cd(ptr, msecs_to_jiffies(200)); symbol_put(mmc_detect_change); } + msleep(100); /* debounce */ + if (irq == DB1200_SD0_INSERT_INT) + enable_irq(DB1200_SD0_EJECT_INT); + else + enable_irq(DB1200_SD0_INSERT_INT); + return IRQ_HANDLED; } @@ -374,13 +378,13 @@ static int db1200_mmc_cd_setup(void *mmc_host, int en) int ret; if (en) { - ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd, - 0, "sd_insert", mmc_host); + ret = request_threaded_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd, + db1200_mmc_cdfn, 0, "sd_insert", mmc_host); if (ret) goto out; - ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd, - 0, "sd_eject", mmc_host); + ret = request_threaded_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd, + db1200_mmc_cdfn, 0, "sd_eject", mmc_host); if (ret) { free_irq(DB1200_SD0_INSERT_INT, mmc_host); goto out; @@ -436,23 +440,27 @@ static struct led_classdev db1200_mmc_led = { static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr) { - void(*mmc_cd)(struct mmc_host *, unsigned long); + disable_irq_nosync(irq); + return IRQ_WAKE_THREAD; +} - if (irq == PB1200_SD1_INSERT_INT) { - disable_irq_nosync(PB1200_SD1_INSERT_INT); - enable_irq(PB1200_SD1_EJECT_INT); - } else { - disable_irq_nosync(PB1200_SD1_EJECT_INT); - enable_irq(PB1200_SD1_INSERT_INT); - } +static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr) +{ + void (*mmc_cd)(struct mmc_host *, unsigned long); /* link against CONFIG_MMC=m */ mmc_cd = symbol_get(mmc_detect_change); if (mmc_cd) { - mmc_cd(ptr, msecs_to_jiffies(500)); + mmc_cd(ptr, msecs_to_jiffies(200)); symbol_put(mmc_detect_change); } + msleep(100); /* debounce */ + if (irq == PB1200_SD1_INSERT_INT) + enable_irq(PB1200_SD1_EJECT_INT); + else + enable_irq(PB1200_SD1_INSERT_INT); + return IRQ_HANDLED; } @@ -461,13 +469,13 @@ static int pb1200_mmc1_cd_setup(void *mmc_host, int en) int ret; if (en) { - ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0, - "sd1_insert", mmc_host); + ret = request_threaded_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, + pb1200_mmc1_cdfn, 0, "sd1_insert", mmc_host); if (ret) goto out; - ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0, - "sd1_eject", mmc_host); + ret = request_threaded_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, + pb1200_mmc1_cdfn, 0, "sd1_eject", mmc_host); if (ret) { free_irq(PB1200_SD1_INSERT_INT, mmc_host); goto out; diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index a5504f57cb00..efb318e03e0a 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * DBAu1300 init and platform device setup. * @@ -18,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -450,24 +451,27 @@ static struct platform_device db1300_ide_dev = { static irqreturn_t db1300_mmc_cd(int irq, void *ptr) { - void(*mmc_cd)(struct mmc_host *, unsigned long); + disable_irq_nosync(irq); + return IRQ_WAKE_THREAD; +} - /* disable the one currently screaming. No other way to shut it up */ - if (irq == DB1300_SD1_INSERT_INT) { - disable_irq_nosync(DB1300_SD1_INSERT_INT); - enable_irq(DB1300_SD1_EJECT_INT); - } else { - disable_irq_nosync(DB1300_SD1_EJECT_INT); - enable_irq(DB1300_SD1_INSERT_INT); - } +static irqreturn_t db1300_mmc_cdfn(int irq, void *ptr) +{ + void (*mmc_cd)(struct mmc_host *, unsigned long); /* link against CONFIG_MMC=m. We can only be called once MMC core has * initialized the controller, so symbol_get() should always succeed. */ mmc_cd = symbol_get(mmc_detect_change); - mmc_cd(ptr, msecs_to_jiffies(500)); + mmc_cd(ptr, msecs_to_jiffies(200)); symbol_put(mmc_detect_change); + msleep(100); /* debounce */ + if (irq == DB1300_SD1_INSERT_INT) + enable_irq(DB1300_SD1_EJECT_INT); + else + enable_irq(DB1300_SD1_INSERT_INT); + return IRQ_HANDLED; } @@ -487,13 +491,13 @@ static int db1300_mmc_cd_setup(void *mmc_host, int en) int ret; if (en) { - ret = request_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, 0, - "sd_insert", mmc_host); + ret = request_threaded_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, + db1300_mmc_cdfn, 0, "sd_insert", mmc_host); if (ret) goto out; - ret = request_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, 0, - "sd_eject", mmc_host); + ret = request_threaded_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, + db1300_mmc_cdfn, 0, "sd_eject", mmc_host); if (ret) { free_irq(DB1300_SD1_INSERT_INT, mmc_host); goto out; diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index 1c01d6eadb08..7d3dfaa10231 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Alchemy Db1550/Pb1550 board support * @@ -12,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/alchemy/devboards/db1xxx.c b/arch/mips/alchemy/devboards/db1xxx.c index 2d47f951121a..e6d25aad8350 100644 --- a/arch/mips/alchemy/devboards/db1xxx.c +++ b/arch/mips/alchemy/devboards/db1xxx.c @@ -1,7 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Alchemy DB/PB1xxx board support. */ +#include #include #include @@ -97,6 +99,7 @@ arch_initcall(db1xxx_arch_init); static int __init db1xxx_dev_init(void) { + mips_set_machine_name(board_type_str()); switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { case BCSR_WHOAMI_DB1000: case BCSR_WHOAMI_DB1500: diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index be139a0198b0..4640edab207c 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * devoard misc stuff. */ diff --git a/arch/mips/alchemy/devboards/platform.h b/arch/mips/alchemy/devboards/platform.h index 5ac055d2cda9..23d98fc09a43 100644 --- a/arch/mips/alchemy/devboards/platform.h +++ b/arch/mips/alchemy/devboards/platform.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _DEVBOARD_PLATFORM_H_ #define _DEVBOARD_PLATFORM_H_ diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c index 93024dc6b314..73c77814687a 100644 --- a/arch/mips/alchemy/devboards/pm.c +++ b/arch/mips/alchemy/devboards/pm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Alchemy Development Board example suspend userspace interface. * diff --git a/arch/mips/ar7/Makefile b/arch/mips/ar7/Makefile index 7435e44b3964..cd51c6c6e686 100644 --- a/arch/mips/ar7/Makefile +++ b/arch/mips/ar7/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y := \ prom.o \ diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c index dda422a0f36c..0137656107a9 100644 --- a/arch/mips/ar7/clock.c +++ b/arch/mips/ar7/clock.c @@ -430,6 +430,9 @@ EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } EXPORT_SYMBOL(clk_get_rate); diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index df7acea3747a..4674f1efbe7a 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -575,6 +575,7 @@ static int __init ar7_register_uarts(void) uart_port.type = PORT_AR7; uart_port.uartclk = clk_get_rate(bus_clk) / 2; uart_port.iotype = UPIO_MEM32; + uart_port.flags = UPF_FIXED_TYPE; uart_port.regshift = 2; uart_port.line = 0; @@ -653,6 +654,10 @@ static int __init ar7_register_devices(void) u32 val; int res; + res = ar7_gpio_init(); + if (res) + pr_warn("unable to register gpios: %d\n", res); + res = ar7_register_uarts(); if (res) pr_err("unable to setup uart(s): %d\n", res); diff --git a/arch/mips/ar7/prom.c b/arch/mips/ar7/prom.c index 4fd83336131a..dd53987a690f 100644 --- a/arch/mips/ar7/prom.c +++ b/arch/mips/ar7/prom.c @@ -246,8 +246,6 @@ void __init prom_init(void) ar7_init_cmdline(fw_arg0, (char **)fw_arg1); ar7_init_env((struct env_var *)fw_arg2); console_config(); - - ar7_gpio_init(); } #define PORT(offset) (KSEG1ADDR(AR7_REGS_UART0 + (offset * 4))) diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig index fc19dd57e42d..7070b4bcd01d 100644 --- a/arch/mips/ath25/Kconfig +++ b/arch/mips/ath25/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config SOC_AR5312 bool "Atheros AR5312/AR2312+ SoC support" depends on ATH25 diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h index 877afe63eed5..fccc64f6db6c 100644 --- a/arch/mips/ath25/ar2315.h +++ b/arch/mips/ath25/ar2315.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __AR2315_H #define __AR2315_H diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h index 470abb0052bd..67518a59ac3c 100644 --- a/arch/mips/ath25/ar5312.h +++ b/arch/mips/ath25/ar5312.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __AR5312_H #define __AR5312_H diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c index 7a64567d1ac3..e1156347da53 100644 --- a/arch/mips/ath25/devices.c +++ b/arch/mips/ath25/devices.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h index 04d414115356..44cf690634b8 100644 --- a/arch/mips/ath25/devices.h +++ b/arch/mips/ath25/devices.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ATH25_DEVICES_H #define __ATH25_DEVICES_H diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index dfc60209dc63..9547cf1ea38d 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if ATH79 menu "Atheros AR71XX/AR724X/AR913X machine selection" diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index fa845953f736..6b1000b6a6a6 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -487,17 +487,16 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np) { struct clk *ref_clk; void __iomem *pll_base; - const char *dnfn = of_node_full_name(np); ref_clk = of_clk_get(np, 0); if (IS_ERR(ref_clk)) { - pr_err("%s: of_clk_get failed\n", dnfn); + pr_err("%pOF: of_clk_get failed\n", np); goto err; } pll_base = of_iomap(np, 0); if (!pll_base) { - pr_err("%s: can't map pll registers\n", dnfn); + pr_err("%pOF: can't map pll registers\n", np); goto err_clk; } @@ -506,12 +505,12 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np) else if (of_device_is_compatible(np, "qca,ar9330-pll")) ar9330_clk_init(ref_clk, pll_base); else { - pr_err("%s: could not find any appropriate clk_init()\n", dnfn); + pr_err("%pOF: could not find any appropriate clk_init()\n", np); goto err_iounmap; } if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { - pr_err("%s: could not register clk provider\n", dnfn); + pr_err("%pOF: could not register clk provider\n", np); goto err_iounmap; } diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c index 730c0b03060d..b816cb4a25ff 100644 --- a/arch/mips/ath79/pci.c +++ b/arch/mips/ath79/pci.c @@ -22,10 +22,10 @@ #include "pci.h" static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); -static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; -static unsigned ath79_pci_nr_irqs __initdata; +static const struct ath79_pci_irq *ath79_pci_irq_map; +static unsigned ath79_pci_nr_irqs; -static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { { .slot = 17, .pin = 1, @@ -41,7 +41,7 @@ static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { } }; -static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq ar724x_pci_irq_map[] = { { .slot = 0, .pin = 1, @@ -49,7 +49,7 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { } }; -static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { +static const struct ath79_pci_irq qca955x_pci_irq_map[] = { { .bus = 0, .slot = 0, @@ -64,7 +64,7 @@ static const struct ath79_pci_irq qca955x_pci_irq_map[] __initconst = { }, }; -int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) +int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) { int irq = -1; int i; diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index e970fd9cf769..29471038d817 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if BCM47XX config BCM47XX_SSB diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index 0367ac7286fe..bb96743bb92e 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LINUX_BCM47XX_PRIVATE_H_ #define LINUX_BCM47XX_PRIVATE_H_ diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index 8cbe60cc51d4..edfaef0d73a4 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c index 8a760d801895..88a8fb2bbc71 100644 --- a/arch/mips/bcm47xx/buttons.c +++ b/arch/mips/bcm47xx/buttons.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "bcm47xx_private.h" #include diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c index a35f1d5cde9f..d4f2407a42c6 100644 --- a/arch/mips/bcm47xx/leds.c +++ b/arch/mips/bcm47xx/leds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "bcm47xx_private.h" #include diff --git a/arch/mips/bcm47xx/workarounds.c b/arch/mips/bcm47xx/workarounds.c index e81ce4623070..1a8a07e7a563 100644 --- a/arch/mips/bcm47xx/workarounds.c +++ b/arch/mips/bcm47xx/workarounds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "bcm47xx_private.h" #include diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig index a057fdf111c6..96ed735a4f4a 100644 --- a/arch/mips/bcm63xx/Kconfig +++ b/arch/mips/bcm63xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "CPU support" depends on BCM63XX diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile index 9019f54aee69..c69f297fc1df 100644 --- a/arch/mips/bcm63xx/Makefile +++ b/arch/mips/bcm63xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.o \ setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \ dev-pcmcia.o dev-rng.o dev-spi.o dev-hsspi.o dev-uart.o \ diff --git a/arch/mips/bcm63xx/boards/Kconfig b/arch/mips/bcm63xx/boards/Kconfig index c6aed33d893e..6ff0a7481081 100644 --- a/arch/mips/bcm63xx/boards/Kconfig +++ b/arch/mips/bcm63xx/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "Board support" depends on BCM63XX diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index 73626040e4d6..19577f771c1f 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -339,6 +339,9 @@ EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig index 2d60f25403de..63dfc695087b 100644 --- a/arch/mips/bmips/Kconfig +++ b/arch/mips/bmips/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if BMIPS_GENERIC choice diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index 145b5ce8eb7e..1bd5c4f00d19 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -118,6 +118,12 @@ ifeq ($(ADDR_BITS),64) itb_addr_cells = 2 endif +quiet_cmd_its_cat = CAT $@ + cmd_its_cat = cat $^ >$@ + +$(obj)/vmlinux.its.S: $(addprefix $(srctree)/arch/mips/$(PLATFORM)/,$(ITS_INPUTS)) + $(call if_changed,its_cat) + quiet_cmd_cpp_its_S = ITS $@ cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ @@ -128,19 +134,19 @@ quiet_cmd_cpp_its_S = ITS $@ -DADDR_BITS=$(ADDR_BITS) \ -DADDR_CELLS=$(itb_addr_cells) -$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,none,vmlinux.bin) -$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.gz.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz) -$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.bz2.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2) -$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.lzma.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma) -$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S $(VMLINUX) FORCE +$(obj)/vmlinux.lzo.its: $(obj)/vmlinux.its.S $(VMLINUX) FORCE $(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo) quiet_cmd_itb-image = ITB $@ diff --git a/arch/mips/boot/compressed/dbg.c b/arch/mips/boot/compressed/dbg.c index 06c6a5bd175d..f6728a8fd1c3 100644 --- a/arch/mips/boot/compressed/dbg.c +++ b/arch/mips/boot/compressed/dbg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MIPS-specific debug support for pre-boot environment * diff --git a/arch/mips/boot/compressed/string.c b/arch/mips/boot/compressed/string.c index 9de9885acd0d..43beecc3587c 100644 --- a/arch/mips/boot/compressed/string.c +++ b/arch/mips/boot/compressed/string.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/mips/boot/compressed/string.c * diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c index f7521142deda..b3043c08f769 100644 --- a/arch/mips/boot/compressed/uart-16550.c +++ b/arch/mips/boot/compressed/uart-16550.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * 16550 compatible uart based serial debug support for zboot */ diff --git a/arch/mips/boot/compressed/uart-alchemy.c b/arch/mips/boot/compressed/uart-alchemy.c index 4bee55b93f6a..8ec63011e7dc 100644 --- a/arch/mips/boot/compressed/uart-alchemy.c +++ b/arch/mips/boot/compressed/uart-alchemy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include void putc(char c) diff --git a/arch/mips/boot/compressed/uart-prom.c b/arch/mips/boot/compressed/uart-prom.c index 1c3d51bc90bb..d6f0fee0a151 100644 --- a/arch/mips/boot/compressed/uart-prom.c +++ b/arch/mips/boot/compressed/uart-prom.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 extern void prom_putchar(unsigned char ch); diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index b9db49203e0c..e0a4e939f843 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dts-dirs += brcm dts-dirs += cavium-octeon dts-dirs += img @@ -5,6 +6,7 @@ dts-dirs += ingenic dts-dirs += lantiq dts-dirs += mti dts-dirs += netlogic +dts-dirs += ni dts-dirs += pic32 dts-dirs += qca dts-dirs += ralink diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index d61bc2aebf69..9e09cc4556b3 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_DT_BCM93384WVG) += bcm93384wvg.dtb dtb-$(CONFIG_DT_BCM93384WVG_VIPER) += bcm93384wvg_viper.dtb dtb-$(CONFIG_DT_BCM96368MVWG) += bcm96368mvwg.dtb diff --git a/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts b/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts index 2f2e80fdcde8..ed6023a91763 100644 --- a/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts +++ b/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm3368.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm3368.dtsi b/arch/mips/boot/dts/brcm/bcm3368.dtsi index bee855cb8073..277cde02b744 100644 --- a/arch/mips/boot/dts/brcm/bcm3368.dtsi +++ b/arch/mips/boot/dts/brcm/bcm3368.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm3384_viper.dtsi b/arch/mips/boot/dts/brcm/bcm3384_viper.dtsi index aa406b43c65f..eb2a9c6ed604 100644 --- a/arch/mips/boot/dts/brcm/bcm3384_viper.dtsi +++ b/arch/mips/boot/dts/brcm/bcm3384_viper.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm3384_zephyr.dtsi b/arch/mips/boot/dts/brcm/bcm3384_zephyr.dtsi index a7bd8564e9f6..d7ad769a42fc 100644 --- a/arch/mips/boot/dts/brcm/bcm3384_zephyr.dtsi +++ b/arch/mips/boot/dts/brcm/bcm3384_zephyr.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts b/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts index 430d35ca33d5..2bc0d8401ad6 100644 --- a/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts +++ b/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm63268.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm63268.dtsi b/arch/mips/boot/dts/brcm/bcm63268.dtsi index 7e6bf2cc0287..3b09f44e67fb 100644 --- a/arch/mips/boot/dts/brcm/bcm63268.dtsi +++ b/arch/mips/boot/dts/brcm/bcm63268.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm6328.dtsi b/arch/mips/boot/dts/brcm/bcm6328.dtsi index 5633b9d90f55..644486fe4159 100644 --- a/arch/mips/boot/dts/brcm/bcm6328.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6328.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts b/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts index 702eae2a22a0..5e62190aa3d5 100644 --- a/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts +++ b/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm6358.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm6358.dtsi b/arch/mips/boot/dts/brcm/bcm6358.dtsi index f9d8d392162b..682df7fb7069 100644 --- a/arch/mips/boot/dts/brcm/bcm6358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6358.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts b/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts index 480f2a5bf1da..3e83bee5b91e 100644 --- a/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts +++ b/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm6362.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm6362.dtsi b/arch/mips/boot/dts/brcm/bcm6362.dtsi index c507da594f2f..a82a5e5de672 100644 --- a/arch/mips/boot/dts/brcm/bcm6362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6362.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm6368.dtsi b/arch/mips/boot/dts/brcm/bcm6368.dtsi index d0e3a70b32e2..7a72f59ae457 100644 --- a/arch/mips/boot/dts/brcm/bcm6368.dtsi +++ b/arch/mips/boot/dts/brcm/bcm6368.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi index 79f838ed96c5..2f9ef565e5d0 100644 --- a/arch/mips/boot/dts/brcm/bcm7125.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index da7bfa45a57d..02e426fe6013 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index 9b05760453f0..1089d6ebc841 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index 57b613c6acf2..4b87ebec407a 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index c2a2843aaa9a..ca657df34b6d 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi index 532fc8a15796..d262e11bc3f9 100644 --- a/arch/mips/boot/dts/brcm/bcm7420.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index f56fb25f2e6b..e4fb9b6e6dce 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index f2cead2eae5c..1484e8990e52 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/brcm/bcm93384wvg.dts b/arch/mips/boot/dts/brcm/bcm93384wvg.dts index d1e44a17d41a..601e4d9293ab 100644 --- a/arch/mips/boot/dts/brcm/bcm93384wvg.dts +++ b/arch/mips/boot/dts/brcm/bcm93384wvg.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm3384_zephyr.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm93384wvg_viper.dts b/arch/mips/boot/dts/brcm/bcm93384wvg_viper.dts index 1ecb2696aca8..938a8e66128c 100644 --- a/arch/mips/boot/dts/brcm/bcm93384wvg_viper.dts +++ b/arch/mips/boot/dts/brcm/bcm93384wvg_viper.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm3384_viper.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm96368mvwg.dts b/arch/mips/boot/dts/brcm/bcm96368mvwg.dts index 8c71c6845730..6d772c394e41 100644 --- a/arch/mips/boot/dts/brcm/bcm96368mvwg.dts +++ b/arch/mips/boot/dts/brcm/bcm96368mvwg.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm6368.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts index d72bc423ceaa..7f59ea2ded6c 100644 --- a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7125.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts index ea52d7b5772f..9e7d5228f2b7 100644 --- a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7346.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97358svmb.dts b/arch/mips/boot/dts/brcm/bcm97358svmb.dts index 71357fdc19af..708207a0002d 100644 --- a/arch/mips/boot/dts/brcm/bcm97358svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97358svmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7358.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97360svmb.dts b/arch/mips/boot/dts/brcm/bcm97360svmb.dts index e2fed406c6ee..73c6dc9c8c6d 100644 --- a/arch/mips/boot/dts/brcm/bcm97360svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97360svmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7360.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97362svmb.dts b/arch/mips/boot/dts/brcm/bcm97362svmb.dts index 78bffdf11872..37bacfdcf9d9 100644 --- a/arch/mips/boot/dts/brcm/bcm97362svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97362svmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7362.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97420c.dts b/arch/mips/boot/dts/brcm/bcm97420c.dts index d62b448a152d..f96241e94874 100644 --- a/arch/mips/boot/dts/brcm/bcm97420c.dts +++ b/arch/mips/boot/dts/brcm/bcm97420c.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7420.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97425svmb.dts b/arch/mips/boot/dts/brcm/bcm97425svmb.dts index 73aa006bd9ce..ce762c7b2e54 100644 --- a/arch/mips/boot/dts/brcm/bcm97425svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97425svmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7425.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97435svmb.dts b/arch/mips/boot/dts/brcm/bcm97435svmb.dts index 0a915f3feab6..d4dd31a543fd 100644 --- a/arch/mips/boot/dts/brcm/bcm97435svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97435svmb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm7435.dtsi" diff --git a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi index 3c24f97de922..96c30d857be4 100644 --- a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi +++ b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 &nand { nandcs@1 { compatible = "brcm,nandcs"; diff --git a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi index cb531816ef4c..7b5afefbbfab 100644 --- a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi +++ b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 &nand { nandcs@1 { compatible = "brcm,nandcs"; diff --git a/arch/mips/boot/dts/brcm/bcm9ejtagprb.dts b/arch/mips/boot/dts/brcm/bcm9ejtagprb.dts index 1da4608680aa..8d58c1971b30 100644 --- a/arch/mips/boot/dts/brcm/bcm9ejtagprb.dts +++ b/arch/mips/boot/dts/brcm/bcm9ejtagprb.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "bcm6328.dtsi" diff --git a/arch/mips/boot/dts/cavium-octeon/Makefile b/arch/mips/boot/dts/cavium-octeon/Makefile index 5b99c40a058f..35300e091573 100644 --- a/arch/mips/boot/dts/cavium-octeon/Makefile +++ b/arch/mips/boot/dts/cavium-octeon/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts index ca6b4467bcd3..0fa3dd1819ff 100644 --- a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts +++ b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OCTEON 3XXX, 5XXX, 63XX device tree skeleton. * diff --git a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dtsi b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dtsi index 5302148e05a3..3c296623d870 100644 --- a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dtsi +++ b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* OCTEON 3XXX DTS common parts. */ /dts-v1/; diff --git a/arch/mips/boot/dts/cavium-octeon/octeon_68xx.dts b/arch/mips/boot/dts/cavium-octeon/octeon_68xx.dts index 79b46fcb0a11..3d0acbb2e15f 100644 --- a/arch/mips/boot/dts/cavium-octeon/octeon_68xx.dts +++ b/arch/mips/boot/dts/cavium-octeon/octeon_68xx.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /* * OCTEON 68XX device tree skeleton. diff --git a/arch/mips/boot/dts/img/Makefile b/arch/mips/boot/dts/img/Makefile index 3d70958d0f5a..139bcd887b86 100644 --- a/arch/mips/boot/dts/img/Makefile +++ b/arch/mips/boot/dts/img/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += boston.dtb dtb-$(CONFIG_MACH_PISTACHIO) += pistachio_marduk.dtb diff --git a/arch/mips/boot/dts/img/boston.dts b/arch/mips/boot/dts/img/boston.dts index 53bfa29a7093..2cd49b60e030 100644 --- a/arch/mips/boot/dts/img/boston.dts +++ b/arch/mips/boot/dts/img/boston.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/mips/boot/dts/ingenic/Makefile b/arch/mips/boot/dts/ingenic/Makefile index f2b864f07850..7798262570da 100644 --- a/arch/mips/boot/dts/ingenic/Makefile +++ b/arch/mips/boot/dts/ingenic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_JZ4740_QI_LB60) += qi_lb60.dtb dtb-$(CONFIG_JZ4780_CI20) += ci20.dtb diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index fd138d9978c1..a4cc52214dbd 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts @@ -1,6 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "jz4780.dtsi" +#include / { compatible = "img,ci20", "ingenic,jz4780"; @@ -21,6 +23,13 @@ reg = <0x0 0x10000000 0x30000000 0x30000000>; }; + + eth0_power: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "eth0_power"; + gpio = <&gpb 25 GPIO_ACTIVE_LOW>; + enable-active-high; + }; }; &ext { @@ -123,6 +132,29 @@ }; }; }; + + dm9000@6 { + compatible = "davicom,dm9000"; + davicom,no-eeprom; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_nemc_cs6>; + + reg = <6 0 1 /* addr */ + 6 2 1>; /* data */ + + ingenic,nemc-tAS = <15>; + ingenic,nemc-tAH = <10>; + ingenic,nemc-tBP = <20>; + ingenic,nemc-tAW = <50>; + ingenic,nemc-tSTRV = <100>; + + reset-gpios = <&gpf 12 GPIO_ACTIVE_HIGH>; + vcc-supply = <ð0_power>; + + interrupt-parent = <&gpe>; + interrupts = <19 4>; + }; }; &bch { @@ -165,4 +197,10 @@ groups = "nemc-cs1"; bias-disable; }; + + pins_nemc_cs6: nemc-cs6 { + function = "nemc-cs6"; + groups = "nemc-cs6"; + bias-disable; + }; }; diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi index 2ca7ce7481f1..cd5185bb90ae 100644 --- a/arch/mips/boot/dts/ingenic/jz4740.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include / { diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index 4853ef67b3ab..ff3298f29ec4 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include / { @@ -44,6 +45,17 @@ #clock-cells = <1>; }; + rtc_dev: rtc@10003000 { + compatible = "ingenic,jz4780-rtc"; + reg = <0x10003000 0x4c>; + + interrupt-parent = <&intc>; + interrupts = <32>; + + clocks = <&cgu JZ4780_CLK_RTCLK>; + clock-names = "rtc"; + }; + pinctrl: pin-controller@10010000 { compatible = "ingenic,jz4780-pinctrl"; reg = <0x10010000 0x600>; diff --git a/arch/mips/boot/dts/ingenic/qi_lb60.dts b/arch/mips/boot/dts/ingenic/qi_lb60.dts index b715ee2ac2ee..76aaf8982554 100644 --- a/arch/mips/boot/dts/ingenic/qi_lb60.dts +++ b/arch/mips/boot/dts/ingenic/qi_lb60.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "jz4740.dtsi" diff --git a/arch/mips/boot/dts/lantiq/Makefile b/arch/mips/boot/dts/lantiq/Makefile index 0906c62141b9..0c50e3246a63 100644 --- a/arch/mips/boot/dts/lantiq/Makefile +++ b/arch/mips/boot/dts/lantiq/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/lantiq/danube.dtsi b/arch/mips/boot/dts/lantiq/danube.dtsi index d4c59e003708..2dd950181f8a 100644 --- a/arch/mips/boot/dts/lantiq/danube.dtsi +++ b/arch/mips/boot/dts/lantiq/danube.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/lantiq/easy50712.dts b/arch/mips/boot/dts/lantiq/easy50712.dts index b59962585dde..c37a33962f28 100644 --- a/arch/mips/boot/dts/lantiq/easy50712.dts +++ b/arch/mips/boot/dts/lantiq/easy50712.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "danube.dtsi" diff --git a/arch/mips/boot/dts/mti/Makefile b/arch/mips/boot/dts/mti/Makefile index fcabd69b7030..5ee06f73c348 100644 --- a/arch/mips/boot/dts/mti/Makefile +++ b/arch/mips/boot/dts/mti/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_MIPS_MALTA) += malta.dtb dtb-$(CONFIG_LEGACY_BOARD_SEAD3) += sead3.dtb diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts index ffe3a1508e72..9944e716eac8 100644 --- a/arch/mips/boot/dts/mti/malta.dts +++ b/arch/mips/boot/dts/mti/malta.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index 4f8bc83c2960..192c26ff1d3d 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /memreserve/ 0x00000000 0x00001000; // reserved diff --git a/arch/mips/boot/dts/netlogic/Makefile b/arch/mips/boot/dts/netlogic/Makefile index 9868057140b5..1cb2fdbd8949 100644 --- a/arch/mips/boot/dts/netlogic/Makefile +++ b/arch/mips/boot/dts/netlogic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb dtb-$(CONFIG_DT_XLP_SVP) += xlp_svp.dtb dtb-$(CONFIG_DT_XLP_FVP) += xlp_fvp.dtb diff --git a/arch/mips/boot/dts/netlogic/xlp_evp.dts b/arch/mips/boot/dts/netlogic/xlp_evp.dts index ec16ec2d8d02..e63e55926e04 100644 --- a/arch/mips/boot/dts/netlogic/xlp_evp.dts +++ b/arch/mips/boot/dts/netlogic/xlp_evp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * XLP8XX Device Tree Source for EVP boards */ diff --git a/arch/mips/boot/dts/netlogic/xlp_fvp.dts b/arch/mips/boot/dts/netlogic/xlp_fvp.dts index 4bcebe641d8e..d05abf13fb7d 100644 --- a/arch/mips/boot/dts/netlogic/xlp_fvp.dts +++ b/arch/mips/boot/dts/netlogic/xlp_fvp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * XLP2XX Device Tree Source for FVP boards */ diff --git a/arch/mips/boot/dts/netlogic/xlp_gvp.dts b/arch/mips/boot/dts/netlogic/xlp_gvp.dts index b3ccb82ad7e4..d47de4851786 100644 --- a/arch/mips/boot/dts/netlogic/xlp_gvp.dts +++ b/arch/mips/boot/dts/netlogic/xlp_gvp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * XLP9XX Device Tree Source for GVP boards */ diff --git a/arch/mips/boot/dts/netlogic/xlp_rvp.dts b/arch/mips/boot/dts/netlogic/xlp_rvp.dts index 3783639a318a..aa0faee194ec 100644 --- a/arch/mips/boot/dts/netlogic/xlp_rvp.dts +++ b/arch/mips/boot/dts/netlogic/xlp_rvp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * XLP5XX Device Tree Source for RVP boards */ diff --git a/arch/mips/boot/dts/netlogic/xlp_svp.dts b/arch/mips/boot/dts/netlogic/xlp_svp.dts index 44d6640c1441..3bb0b2e08e4a 100644 --- a/arch/mips/boot/dts/netlogic/xlp_svp.dts +++ b/arch/mips/boot/dts/netlogic/xlp_svp.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * XLP3XX Device Tree Source for SVP boards */ diff --git a/arch/mips/boot/dts/ni/169445.dts b/arch/mips/boot/dts/ni/169445.dts new file mode 100644 index 000000000000..5389ef46c480 --- /dev/null +++ b/arch/mips/boot/dts/ni/169445.dts @@ -0,0 +1,100 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ni,169445"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "mti,mips14KEc"; + clocks = <&baseclk>; + reg = <0>; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x10000000>; + }; + + baseclk: baseclock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + interrupt-controller; + #interrupt-cells = <1>; + }; + + ahb@1f300000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x1f300000 0x80FFF>; + + gpio1: gpio@10 { + compatible = "ni,169445-nand-gpio"; + reg = <0x10 0x4>; + reg-names = "dat"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio2: gpio@14 { + compatible = "ni,169445-nand-gpio"; + reg = <0x14 0x4>; + reg-names = "dat"; + gpio-controller; + #gpio-cells = <2>; + no-output; + }; + + nand@0 { + compatible = "gpio-control-nand"; + nand-on-flash-bbt; + nand-ecc-mode = "soft_bch"; + nand-ecc-step-size = <512>; + nand-ecc-strength = <4>; + reg = <0x0 4>; + gpios = <&gpio2 0 0>, /* rdy */ + <&gpio1 1 0>, /* nce */ + <&gpio1 2 0>, /* ale */ + <&gpio1 3 0>, /* cle */ + <&gpio1 4 0>; /* nwp */ + }; + + serial@80000 { + compatible = "ns16550a"; + reg = <0x80000 0x1000>; + interrupt-parent = <&cpu_intc>; + interrupts = <6>; + clocks = <&baseclk>; + reg-shift = <0>; + }; + + ethernet@40000 { + compatible = "snps,dwmac-4.10a"; + interrupt-parent = <&cpu_intc>; + interrupts = <5>; + interrupt-names = "macirq"; + reg = <0x40000 0x2000>; + clock-names = "stmmaceth", "pclk"; + clocks = <&baseclk>, <&baseclk>; + + phy-mode = "rgmii"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; +}; diff --git a/arch/mips/boot/dts/ni/Makefile b/arch/mips/boot/dts/ni/Makefile new file mode 100644 index 000000000000..66cfdffc51c2 --- /dev/null +++ b/arch/mips/boot/dts/ni/Makefile @@ -0,0 +1,7 @@ +dtb-$(CONFIG_FIT_IMAGE_FDT_NI169445) += 169445.dtb + +# Force kbuild to make empty built-in.o if necessary +obj- += dummy.o + +always := $(dtb-y) +clean-files := *.dtb *.dtb.S diff --git a/arch/mips/boot/dts/pic32/Makefile b/arch/mips/boot/dts/pic32/Makefile index 7ac790551ec9..a86ddd289cfd 100644 --- a/arch/mips/boot/dts/pic32/Makefile +++ b/arch/mips/boot/dts/pic32/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_DTB_PIC32_MZDA_SK) += pic32mzda_sk.dtb dtb-$(CONFIG_DTB_PIC32_NONE) += \ diff --git a/arch/mips/boot/dts/qca/Makefile b/arch/mips/boot/dts/qca/Makefile index 63a9ddf048c9..eabd94eb59db 100644 --- a/arch/mips/boot/dts/qca/Makefile +++ b/arch/mips/boot/dts/qca/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # All DTBs dtb-$(CONFIG_ATH79) += ar9132_tl_wr1043nd_v1.dtb dtb-$(CONFIG_ATH79) += ar9331_dpt_module.dtb diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi index 302f0a8d2988..1fe561c5f90e 100644 --- a/arch/mips/boot/dts/qca/ar9132.dtsi +++ b/arch/mips/boot/dts/qca/ar9132.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include / { diff --git a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts index 3c3b7ce5737b..3931033e47c8 100644 --- a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts +++ b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/mips/boot/dts/qca/ar9331.dtsi b/arch/mips/boot/dts/qca/ar9331.dtsi index cf47ed4d8569..efd5f0722206 100644 --- a/arch/mips/boot/dts/qca/ar9331.dtsi +++ b/arch/mips/boot/dts/qca/ar9331.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include / { diff --git a/arch/mips/boot/dts/qca/ar9331_dpt_module.dts b/arch/mips/boot/dts/qca/ar9331_dpt_module.dts index 98e74500e79d..d4e4502daaa8 100644 --- a/arch/mips/boot/dts/qca/ar9331_dpt_module.dts +++ b/arch/mips/boot/dts/qca/ar9331_dpt_module.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/mips/boot/dts/qca/ar9331_dragino_ms14.dts b/arch/mips/boot/dts/qca/ar9331_dragino_ms14.dts index 56f832076a69..4f95ccf17c4c 100644 --- a/arch/mips/boot/dts/qca/ar9331_dragino_ms14.dts +++ b/arch/mips/boot/dts/qca/ar9331_dragino_ms14.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/mips/boot/dts/qca/ar9331_omega.dts b/arch/mips/boot/dts/qca/ar9331_omega.dts index b2be3b04479d..f70f79c4d0d5 100644 --- a/arch/mips/boot/dts/qca/ar9331_omega.dts +++ b/arch/mips/boot/dts/qca/ar9331_omega.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/mips/boot/dts/qca/ar9331_tl_mr3020.dts b/arch/mips/boot/dts/qca/ar9331_tl_mr3020.dts index 919cf3b854a5..748131aea22e 100644 --- a/arch/mips/boot/dts/qca/ar9331_tl_mr3020.dts +++ b/arch/mips/boot/dts/qca/ar9331_tl_mr3020.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include diff --git a/arch/mips/boot/dts/ralink/Makefile b/arch/mips/boot/dts/ralink/Makefile index 2a7225954bf6..a80eeeecf613 100644 --- a/arch/mips/boot/dts/ralink/Makefile +++ b/arch/mips/boot/dts/ralink/Makefile @@ -1,7 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_DTB_RT2880_EVAL) += rt2880_eval.dtb dtb-$(CONFIG_DTB_RT305X_EVAL) += rt3052_eval.dtb dtb-$(CONFIG_DTB_RT3883_EVAL) += rt3883_eval.dtb dtb-$(CONFIG_DTB_MT7620A_EVAL) += mt7620a_eval.dtb +dtb-$(CONFIG_DTB_OMEGA2P) += omega2p.dtb +dtb-$(CONFIG_DTB_VOCORE2) += vocore2.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/ralink/mt7620a.dtsi b/arch/mips/boot/dts/ralink/mt7620a.dtsi index 793c0c7ca921..1f6e5320f486 100644 --- a/arch/mips/boot/dts/ralink/mt7620a.dtsi +++ b/arch/mips/boot/dts/ralink/mt7620a.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/ralink/mt7620a_eval.dts b/arch/mips/boot/dts/ralink/mt7620a_eval.dts index 709f58132f5c..8de8f89f31b8 100644 --- a/arch/mips/boot/dts/ralink/mt7620a_eval.dts +++ b/arch/mips/boot/dts/ralink/mt7620a_eval.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "mt7620a.dtsi" diff --git a/arch/mips/boot/dts/ralink/mt7628a.dtsi b/arch/mips/boot/dts/ralink/mt7628a.dtsi new file mode 100644 index 000000000000..9ff7e8faaecc --- /dev/null +++ b/arch/mips/boot/dts/ralink/mt7628a.dtsi @@ -0,0 +1,126 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ralink,mt7628a-soc"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "mti,mips24KEc"; + device_type = "cpu"; + reg = <0>; + }; + }; + + resetc: reset-controller { + compatible = "ralink,rt2880-reset"; + #reset-cells = <1>; + }; + + cpuintc: interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + compatible = "mti,cpu-interrupt-controller"; + }; + + palmbus@10000000 { + compatible = "palmbus"; + reg = <0x10000000 0x200000>; + ranges = <0x0 0x10000000 0x1FFFFF>; + + #address-cells = <1>; + #size-cells = <1>; + + sysc: system-controller@0 { + compatible = "ralink,mt7620a-sysc", "syscon"; + reg = <0x0 0x100>; + }; + + intc: interrupt-controller@200 { + compatible = "ralink,rt2880-intc"; + reg = <0x200 0x100>; + + interrupt-controller; + #interrupt-cells = <1>; + + resets = <&resetc 9>; + reset-names = "intc"; + + interrupt-parent = <&cpuintc>; + interrupts = <2>; + + ralink,intc-registers = <0x9c 0xa0 + 0x6c 0xa4 + 0x80 0x78>; + }; + + memory-controller@300 { + compatible = "ralink,mt7620a-memc"; + reg = <0x300 0x100>; + }; + + uart0: uartlite@c00 { + compatible = "ns16550a"; + reg = <0xc00 0x100>; + + resets = <&resetc 12>; + reset-names = "uart0"; + + interrupt-parent = <&intc>; + interrupts = <20>; + + reg-shift = <2>; + }; + + uart1: uart1@d00 { + compatible = "ns16550a"; + reg = <0xd00 0x100>; + + resets = <&resetc 19>; + reset-names = "uart1"; + + interrupt-parent = <&intc>; + interrupts = <21>; + + reg-shift = <2>; + }; + + uart2: uart2@e00 { + compatible = "ns16550a"; + reg = <0xe00 0x100>; + + resets = <&resetc 20>; + reset-names = "uart2"; + + interrupt-parent = <&intc>; + interrupts = <22>; + + reg-shift = <2>; + }; + }; + + usb_phy: usb-phy@10120000 { + compatible = "mediatek,mt7628-usbphy"; + reg = <0x10120000 0x1000>; + + #phy-cells = <0>; + + ralink,sysctl = <&sysc>; + resets = <&resetc 22 &resetc 25>; + reset-names = "host", "device"; + }; + + ehci@101c0000 { + compatible = "generic-ehci"; + reg = <0x101c0000 0x1000>; + + phys = <&usb_phy>; + phy-names = "usb"; + + interrupt-parent = <&intc>; + interrupts = <18>; + }; +}; diff --git a/arch/mips/boot/dts/ralink/omega2p.dts b/arch/mips/boot/dts/ralink/omega2p.dts new file mode 100644 index 000000000000..5884fd48f59a --- /dev/null +++ b/arch/mips/boot/dts/ralink/omega2p.dts @@ -0,0 +1,18 @@ +/dts-v1/; + +/include/ "mt7628a.dtsi" + +/ { + compatible = "onion,omega2+", "ralink,mt7688a-soc", "ralink,mt7628a-soc"; + model = "Onion Omega2+"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; diff --git a/arch/mips/boot/dts/ralink/rt2880.dtsi b/arch/mips/boot/dts/ralink/rt2880.dtsi index fb2faef0ab79..8fc1987d9063 100644 --- a/arch/mips/boot/dts/ralink/rt2880.dtsi +++ b/arch/mips/boot/dts/ralink/rt2880.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/ralink/rt2880_eval.dts b/arch/mips/boot/dts/ralink/rt2880_eval.dts index 0a685db093d4..759bc1dd5b83 100644 --- a/arch/mips/boot/dts/ralink/rt2880_eval.dts +++ b/arch/mips/boot/dts/ralink/rt2880_eval.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "rt2880.dtsi" diff --git a/arch/mips/boot/dts/ralink/rt3050.dtsi b/arch/mips/boot/dts/ralink/rt3050.dtsi index d3cb57f985da..23062333a76d 100644 --- a/arch/mips/boot/dts/ralink/rt3050.dtsi +++ b/arch/mips/boot/dts/ralink/rt3050.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/ralink/rt3052_eval.dts b/arch/mips/boot/dts/ralink/rt3052_eval.dts index ec9e9a035541..674efdd42e74 100644 --- a/arch/mips/boot/dts/ralink/rt3052_eval.dts +++ b/arch/mips/boot/dts/ralink/rt3052_eval.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "rt3050.dtsi" diff --git a/arch/mips/boot/dts/ralink/rt3883.dtsi b/arch/mips/boot/dts/ralink/rt3883.dtsi index 3d6fc9afdaf6..61132cf157e5 100644 --- a/arch/mips/boot/dts/ralink/rt3883.dtsi +++ b/arch/mips/boot/dts/ralink/rt3883.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/ralink/rt3883_eval.dts b/arch/mips/boot/dts/ralink/rt3883_eval.dts index e8df21a5d10d..c22bc84df219 100644 --- a/arch/mips/boot/dts/ralink/rt3883_eval.dts +++ b/arch/mips/boot/dts/ralink/rt3883_eval.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; /include/ "rt3883.dtsi" diff --git a/arch/mips/boot/dts/ralink/vocore2.dts b/arch/mips/boot/dts/ralink/vocore2.dts new file mode 100644 index 000000000000..fa8a5f8f236a --- /dev/null +++ b/arch/mips/boot/dts/ralink/vocore2.dts @@ -0,0 +1,18 @@ +/dts-v1/; + +#include "mt7628a.dtsi" + +/ { + compatible = "vocore,vocore2", "ralink,mt7628a-soc"; + model = "VoCore2"; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x8000000>; + }; + + chosen { + bootargs = "console=ttyS2,115200"; + stdout-path = &uart2; + }; +}; diff --git a/arch/mips/boot/dts/xilfpga/Makefile b/arch/mips/boot/dts/xilfpga/Makefile index 913a752a9ff1..498ac081e2fe 100644 --- a/arch/mips/boot/dts/xilfpga/Makefile +++ b/arch/mips/boot/dts/xilfpga/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_XILFPGA_NEXYS4DDR) += nexys4ddr.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/xilfpga/microAptiv.dtsi b/arch/mips/boot/dts/xilfpga/microAptiv.dtsi index 81d518e75785..87b2b1f9a1b0 100644 --- a/arch/mips/boot/dts/xilfpga/microAptiv.dtsi +++ b/arch/mips/boot/dts/xilfpga/microAptiv.dtsi @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 / { #address-cells = <1>; #size-cells = <1>; diff --git a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts index 09a62f2e2f8f..41fee03dc312 100644 --- a/arch/mips/boot/dts/xilfpga/nexys4ddr.dts +++ b/arch/mips/boot/dts/xilfpga/nexys4ddr.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "microAptiv.dtsi" diff --git a/arch/mips/boot/ecoff.h b/arch/mips/boot/ecoff.h index 7a75ce2c1bcd..b3e73c22c345 100644 --- a/arch/mips/boot/ecoff.h +++ b/arch/mips/boot/ecoff.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Some ECOFF definitions. */ diff --git a/arch/mips/boot/tools/Makefile b/arch/mips/boot/tools/Makefile index d232a68f6c8a..5f8e737348eb 100644 --- a/arch/mips/boot/tools/Makefile +++ b/arch/mips/boot/tools/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 hostprogs-y += relocs relocs-objs += relocs_32.o diff --git a/arch/mips/boot/tools/relocs.c b/arch/mips/boot/tools/relocs.c index b9cbf78527e8..1bf53f3524b3 100644 --- a/arch/mips/boot/tools/relocs.c +++ b/arch/mips/boot/tools/relocs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* This is included from relocs_32/64.c */ #define ElfW(type) _ElfW(ELF_BITS, type) diff --git a/arch/mips/boot/tools/relocs.h b/arch/mips/boot/tools/relocs.h index 3cf676f49e18..607ff0103064 100644 --- a/arch/mips/boot/tools/relocs.h +++ b/arch/mips/boot/tools/relocs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef RELOCS_H #define RELOCS_H diff --git a/arch/mips/boot/tools/relocs_32.c b/arch/mips/boot/tools/relocs_32.c index 915bdc07f5ed..428bea489303 100644 --- a/arch/mips/boot/tools/relocs_32.c +++ b/arch/mips/boot/tools/relocs_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "relocs.h" #define ELF_BITS 32 diff --git a/arch/mips/boot/tools/relocs_64.c b/arch/mips/boot/tools/relocs_64.c index 06066e6ac2f9..154015d745d6 100644 --- a/arch/mips/boot/tools/relocs_64.c +++ b/arch/mips/boot/tools/relocs_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "relocs.h" #define ELF_BITS 64 diff --git a/arch/mips/boot/tools/relocs_main.c b/arch/mips/boot/tools/relocs_main.c index d8fe2343b8d0..e2453a564b11 100644 --- a/arch/mips/boot/tools/relocs_main.c +++ b/arch/mips/boot/tools/relocs_main.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig index 5c0b56203bae..204a1670fd9b 100644 --- a/arch/mips/cavium-octeon/Kconfig +++ b/arch/mips/cavium-octeon/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if CPU_CAVIUM_OCTEON config CAVIUM_CN63XXP1 diff --git a/arch/mips/cavium-octeon/crypto/Makefile b/arch/mips/cavium-octeon/crypto/Makefile index f7aa9d5d3b87..db26c73fa0ed 100644 --- a/arch/mips/cavium-octeon/crypto/Makefile +++ b/arch/mips/cavium-octeon/crypto/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # OCTEON-specific crypto modules. # diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile index b6d6e841a984..50b427879465 100644 --- a/arch/mips/cavium-octeon/executive/Makefile +++ b/arch/mips/cavium-octeon/executive/Makefile @@ -16,4 +16,4 @@ obj-y += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \ cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \ cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o -obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o +obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o cvmx-boot-vector.o diff --git a/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c b/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c new file mode 100644 index 000000000000..b7019d21808e --- /dev/null +++ b/arch/mips/cavium-octeon/executive/cvmx-boot-vector.c @@ -0,0 +1,167 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2004-2017 Cavium, Inc. + */ + + +/* + We install this program at the bootvector: +------------------------------------ + .set noreorder + .set nomacro + .set noat +reset_vector: + dmtc0 $k0, $31, 0 # Save $k0 to DESAVE + dmtc0 $k1, $31, 3 # Save $k1 to KScratch2 + + mfc0 $k0, $12, 0 # Status + mfc0 $k1, $15, 1 # Ebase + + ori $k0, 0x84 # Enable 64-bit addressing, set + # ERL (should already be set) + andi $k1, 0x3ff # mask out core ID + + mtc0 $k0, $12, 0 # Status + sll $k1, 5 + + lui $k0, 0xbfc0 + cache 17, 0($0) # Core-14345, clear L1 Dcache virtual + # tags if the core hit an NMI + + ld $k0, 0x78($k0) # k0 <- (bfc00078) pointer to the reset vector + synci 0($0) # Invalidate ICache to get coherent + # view of target code. + + daddu $k0, $k0, $k1 + nop + + ld $k0, 0($k0) # k0 <- core specific target address + dmfc0 $k1, $31, 3 # Restore $k1 from KScratch2 + + beqz $k0, wait_loop # Spin in wait loop + nop + + jr $k0 + nop + + nop # NOPs needed here to fill delay slots + nop # on endian reversal of previous instructions + +wait_loop: + wait + nop + + b wait_loop + nop + + nop + nop +------------------------------------ + +0000000000000000 : + 0: 40baf800 dmtc0 k0,c0_desave + 4: 40bbf803 dmtc0 k1,c0_kscratch2 + + 8: 401a6000 mfc0 k0,c0_status + c: 401b7801 mfc0 k1,c0_ebase + + 10: 375a0084 ori k0,k0,0x84 + 14: 337b03ff andi k1,k1,0x3ff + + 18: 409a6000 mtc0 k0,c0_status + 1c: 001bd940 sll k1,k1,0x5 + + 20: 3c1abfc0 lui k0,0xbfc0 + 24: bc110000 cache 0x11,0(zero) + + 28: df5a0078 ld k0,120(k0) + 2c: 041f0000 synci 0(zero) + + 30: 035bd02d daddu k0,k0,k1 + 34: 00000000 nop + + 38: df5a0000 ld k0,0(k0) + 3c: 403bf803 dmfc0 k1,c0_kscratch2 + + 40: 13400005 beqz k0,58 + 44: 00000000 nop + + 48: 03400008 jr k0 + 4c: 00000000 nop + + 50: 00000000 nop + 54: 00000000 nop + +0000000000000058 : + 58: 42000020 wait + 5c: 00000000 nop + + 60: 1000fffd b 58 + 64: 00000000 nop + + 68: 00000000 nop + 6c: 00000000 nop + + */ + +#include + +static unsigned long long _cvmx_bootvector_data[16] = { + 0x40baf80040bbf803ull, /* patch low order 8-bits if no KScratch*/ + 0x401a6000401b7801ull, + 0x375a0084337b03ffull, + 0x409a6000001bd940ull, + 0x3c1abfc0bc110000ull, + 0xdf5a0078041f0000ull, + 0x035bd02d00000000ull, + 0xdf5a0000403bf803ull, /* patch low order 8-bits if no KScratch*/ + 0x1340000500000000ull, + 0x0340000800000000ull, + 0x0000000000000000ull, + 0x4200002000000000ull, + 0x1000fffd00000000ull, + 0x0000000000000000ull, + OCTEON_BOOT_MOVEABLE_MAGIC1, + 0 /* To be filled in with address of vector block*/ +}; + +/* 2^10 CPUs */ +#define VECTOR_TABLE_SIZE (1024 * sizeof(struct cvmx_boot_vector_element)) + +static void cvmx_boot_vector_init(void *mem) +{ + uint64_t kseg0_mem; + int i; + + memset(mem, 0, VECTOR_TABLE_SIZE); + kseg0_mem = cvmx_ptr_to_phys(mem) | 0x8000000000000000ull; + + for (i = 0; i < 15; i++) { + uint64_t v = _cvmx_bootvector_data[i]; + + if (OCTEON_IS_OCTEON1PLUS() && (i == 0 || i == 7)) + v &= 0xffffffff00000000ull; /* KScratch not availble. */ + cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, i * 8); + cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, v); + } + cvmx_write_csr(CVMX_MIO_BOOT_LOC_ADR, 15 * 8); + cvmx_write_csr(CVMX_MIO_BOOT_LOC_DAT, kseg0_mem); + cvmx_write_csr(CVMX_MIO_BOOT_LOC_CFGX(0), 0x81fc0000); +} + +/** + * Get a pointer to the per-core table of reset vector pointers + * + */ +struct cvmx_boot_vector_element *cvmx_boot_vector_get(void) +{ + struct cvmx_boot_vector_element *ret; + + ret = cvmx_bootmem_alloc_named_range_once(VECTOR_TABLE_SIZE, 0, + (1ull << 32) - 1, 8, "__boot_vector1__", cvmx_boot_vector_init); + return ret; +} +EXPORT_SYMBOL(cvmx_boot_vector_get); diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c index 8d54d774933c..94d97ebfa036 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c +++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c @@ -44,6 +44,55 @@ static struct cvmx_bootmem_desc *cvmx_bootmem_desc; /* See header file for descriptions of functions */ +/** + * This macro returns the size of a member of a structure. + * Logically it is the same as "sizeof(s::field)" in C++, but + * C lacks the "::" operator. + */ +#define SIZEOF_FIELD(s, field) sizeof(((s *)NULL)->field) + +/** + * This macro returns a member of the + * cvmx_bootmem_named_block_desc_t structure. These members can't + * be directly addressed as they might be in memory not directly + * reachable. In the case where bootmem is compiled with + * LINUX_HOST, the structure itself might be located on a remote + * Octeon. The argument "field" is the member name of the + * cvmx_bootmem_named_block_desc_t to read. Regardless of the type + * of the field, the return type is always a uint64_t. The "addr" + * parameter is the physical address of the structure. + */ +#define CVMX_BOOTMEM_NAMED_GET_FIELD(addr, field) \ + __cvmx_bootmem_desc_get(addr, \ + offsetof(struct cvmx_bootmem_named_block_desc, field), \ + SIZEOF_FIELD(struct cvmx_bootmem_named_block_desc, field)) + +/** + * This function is the implementation of the get macros defined + * for individual structure members. The argument are generated + * by the macros inorder to read only the needed memory. + * + * @param base 64bit physical address of the complete structure + * @param offset Offset from the beginning of the structure to the member being + * accessed. + * @param size Size of the structure member. + * + * @return Value of the structure member promoted into a uint64_t. + */ +static inline uint64_t __cvmx_bootmem_desc_get(uint64_t base, int offset, + int size) +{ + base = (1ull << 63) | (base + offset); + switch (size) { + case 4: + return cvmx_read64_uint32(base); + case 8: + return cvmx_read64_uint64(base); + default: + return 0; + } +} + /* * Wrapper functions are provided for reading/writing the size and * next block values as these may not be directly addressible (in 32 @@ -98,6 +147,42 @@ void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment) return cvmx_bootmem_alloc_range(size, alignment, 0, 0); } +void *cvmx_bootmem_alloc_named_range_once(uint64_t size, uint64_t min_addr, + uint64_t max_addr, uint64_t align, + char *name, + void (*init) (void *)) +{ + int64_t addr; + void *ptr; + uint64_t named_block_desc_addr; + + named_block_desc_addr = (uint64_t) + cvmx_bootmem_phy_named_block_find(name, + (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); + + if (named_block_desc_addr) { + addr = CVMX_BOOTMEM_NAMED_GET_FIELD(named_block_desc_addr, + base_addr); + return cvmx_phys_to_ptr(addr); + } + + addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr, + align, name, + (uint32_t)CVMX_BOOTMEM_FLAG_NO_LOCKING); + + if (addr < 0) + return NULL; + ptr = cvmx_phys_to_ptr(addr); + + if (init) + init(ptr); + else + memset(ptr, 0, size); + + return ptr; +} +EXPORT_SYMBOL(cvmx_bootmem_alloc_named_range_once); + void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, char *name) diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index c1eb1ff7c800..5b3a3f6a9ad3 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -2963,3 +2963,12 @@ void octeon_fixup_irqs(void) } #endif /* CONFIG_HOTPLUG_CPU */ + +struct irq_domain *octeon_irq_get_block_domain(int node, uint8_t block) +{ + struct octeon_ciu3_info *ciu3_info; + + ciu3_info = octeon_ciu3_info_per_node[node & CVMX_NODE_MASK]; + return ciu3_info->domain[block]; +} +EXPORT_SYMBOL(octeon_irq_get_block_domain); diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 3de786545ded..75e7c8625659 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -205,7 +205,7 @@ int plat_post_relocation(long offset) * Firmware CPU startup hook * */ -static void octeon_boot_secondary(int cpu, struct task_struct *idle) +static int octeon_boot_secondary(int cpu, struct task_struct *idle) { int count; @@ -223,8 +223,12 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle) udelay(1); count--; } - if (count == 0) + if (count == 0) { pr_err("Secondary boot timeout\n"); + return -ETIMEDOUT; + } + + return 0; } /** @@ -408,7 +412,7 @@ late_initcall(register_cavium_notifier); #endif /* CONFIG_HOTPLUG_CPU */ -struct plat_smp_ops octeon_smp_ops = { +const struct plat_smp_ops octeon_smp_ops = { .send_ipi_single = octeon_send_ipi_single, .send_ipi_mask = octeon_send_ipi_mask, .init_secondary = octeon_init_secondary, @@ -485,7 +489,7 @@ static void octeon_78xx_send_ipi_mask(const struct cpumask *mask, octeon_78xx_send_ipi_single(cpu, action); } -static struct plat_smp_ops octeon_78xx_smp_ops = { +static const struct plat_smp_ops octeon_78xx_smp_ops = { .send_ipi_single = octeon_78xx_send_ipi_single, .send_ipi_mask = octeon_78xx_send_ipi_mask, .init_secondary = octeon_init_secondary, @@ -501,7 +505,7 @@ static struct plat_smp_ops octeon_78xx_smp_ops = { void __init octeon_setup_smp(void) { - struct plat_smp_ops *ops; + const struct plat_smp_ops *ops; if (octeon_has_feature(OCTEON_FEATURE_CIU3)) ops = &octeon_78xx_smp_ops; diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig index e5b18f1a31a0..490b12af103c 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig @@ -60,11 +60,8 @@ CONFIG_BLK_DEV_SD=y CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y -CONFIG_AHCI_OCTEON=y CONFIG_PATA_OCTEON_CF=y -CONFIG_SATA_SIL=y CONFIG_NETDEVICES=y -CONFIG_MII=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set # CONFIG_NET_VENDOR_ALTEON is not set @@ -121,22 +118,30 @@ CONFIG_SPI=y CONFIG_SPI_OCTEON=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y -CONFIG_USB=m -CONFIG_USB_EHCI_HCD=m -CONFIG_USB_EHCI_HCD_PLATFORM=m -CONFIG_USB_OHCI_HCD=m -CONFIG_USB_OHCI_HCD_PLATFORM=m +CONFIG_USB=y +# CONFIG_USB_PCI is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y CONFIG_MMC=y # CONFIG_PWRSEQ_EMMC is not set # CONFIG_PWRSEQ_SIMPLE is not set -# CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_CAVIUM_OCTEON=y +CONFIG_EDAC=y +CONFIG_EDAC_OCTEON_PC=y +CONFIG_EDAC_OCTEON_L2C=y +CONFIG_EDAC_OCTEON_LMC=y +CONFIG_EDAC_OCTEON_PCI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_STAGING=y CONFIG_OCTEON_ETHERNET=y -CONFIG_OCTEON_USB=m # CONFIG_IOMMU_SUPPORT is not set +CONFIG_RAS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index b42cfa7865f9..5ea3104a3aca 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig @@ -91,6 +91,7 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_I2C=y CONFIG_I2C_JZ4780=y CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_INGENIC=y # CONFIG_HWMON is not set CONFIG_REGULATOR=y CONFIG_REGULATOR_DEBUG=y @@ -99,6 +100,8 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set CONFIG_MMC=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_JZ4740=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_MEMORY=y # CONFIG_DNOTIFY is not set diff --git a/arch/mips/configs/generic/board-ni169445.config b/arch/mips/configs/generic/board-ni169445.config new file mode 100644 index 000000000000..f72223b366ca --- /dev/null +++ b/arch/mips/configs/generic/board-ni169445.config @@ -0,0 +1,30 @@ +# require CONFIG_CPU_MIPS32_R2=y +# require CONFIG_CPU_LITTLE_ENDIAN=y + +CONFIG_FIT_IMAGE_FDT_NI169445=y + +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y + +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC_PLATFORM=y + +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CMDLINE_PARTS=y + +CONFIG_MTD_NAND_ECC=y +CONFIG_MTD_NAND_ECC_BCH=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_GPIO=y +CONFIG_MTD_NAND_IDS=y + +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BLOCK=y + +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +CONFIG_STMMAC_PLATFORM=y +CONFIG_DWMAC_GENERIC=y diff --git a/arch/mips/configs/generic/board-sead-3.config b/arch/mips/configs/generic/board-sead-3.config index 3b5e1ac579eb..df49a592dbb5 100644 --- a/arch/mips/configs/generic/board-sead-3.config +++ b/arch/mips/configs/generic/board-sead-3.config @@ -1,3 +1,5 @@ +# require CONFIG_32BIT=y + CONFIG_LEGACY_BOARD_SEAD3=y CONFIG_AUXDISPLAY=y diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig index 91aacf2ef26d..26b1cd5ffbf5 100644 --- a/arch/mips/configs/generic_defconfig +++ b/arch/mips/configs/generic_defconfig @@ -3,7 +3,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_MIPS_CPS=y CONFIG_CPU_HAS_MSA=y CONFIG_HIGHMEM=y -CONFIG_NR_CPUS=2 +CONFIG_NR_CPUS=16 CONFIG_MIPS_O32_FP64_SUPPORT=y CONFIG_SYSVIPC=y CONFIG_NO_HZ_IDLE=y @@ -61,7 +61,6 @@ CONFIG_HID_KENSINGTON=y CONFIG_HID_LOGITECH=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y -# CONFIG_USB_SUPPORT is not set # CONFIG_MIPS_PLATFORM_DEVICES is not set # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT4_FS=y diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig index b1911816337c..55438fc9991e 100644 --- a/arch/mips/configs/gpr_defconfig +++ b/arch/mips/configs/gpr_defconfig @@ -111,12 +111,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 1ec8ed8d05d1..02be95c1b712 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig @@ -37,7 +37,6 @@ CONFIG_PM=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="/dev/hda3" CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEBUG=y CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 078ecac071ab..396408404487 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_NR_CPUS=8 CONFIG_HZ_100=y CONFIG_SYSVIPC=y diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index 80ecd94ed126..5691673a3327 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_NR_CPUS=8 CONFIG_HZ_100=y CONFIG_SYSVIPC=y diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index 35ad1f8d1a79..e9cadb37d684 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -3,6 +3,7 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_KVM_GUEST=y CONFIG_PAGE_SIZE_16KB=y +# CONFIG_MIPS_MT_SMP is not set CONFIG_HZ_100=y CONFIG_SYSVIPC=y CONFIG_NO_HZ=y diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig index 55b68b981b05..d8c8f5fb8918 100644 --- a/arch/mips/configs/maltasmvp_defconfig +++ b/arch/mips/configs/maltasmvp_defconfig @@ -2,7 +2,6 @@ CONFIG_MIPS_MALTA=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_SCHED_SMT=y CONFIG_MIPS_CPS=y CONFIG_NR_CPUS=8 diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig index 5ca590cf1635..04827bc9f87f 100644 --- a/arch/mips/configs/maltasmvp_eva_defconfig +++ b/arch/mips/configs/maltasmvp_eva_defconfig @@ -3,7 +3,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MIPS32_R2=y CONFIG_CPU_MIPS32_3_5_FEATURES=y CONFIG_PAGE_SIZE_16KB=y -CONFIG_MIPS_MT_SMP=y CONFIG_SCHED_SMT=y CONFIG_MIPS_CPS=y CONFIG_NR_CPUS=8 diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 4011f1869e72..c3d0d0a6e044 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -146,12 +146,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig index 5720ce23e9aa..7357248b3d7a 100644 --- a/arch/mips/configs/nlm_xlp_defconfig +++ b/arch/mips/configs/nlm_xlp_defconfig @@ -259,7 +259,6 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m CONFIG_WAN_ROUTER=m diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig index fea56c535d92..1e18fd7de209 100644 --- a/arch/mips/configs/nlm_xlr_defconfig +++ b/arch/mips/configs/nlm_xlr_defconfig @@ -240,12 +240,8 @@ CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m CONFIG_IPDDP=m CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y CONFIG_X25=m CONFIG_LAPB=m -CONFIG_ECONET=m -CONFIG_ECONET_AUNUDP=y -CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m CONFIG_PHONET=m CONFIG_IEEE802154=m diff --git a/arch/mips/configs/omega2p_defconfig b/arch/mips/configs/omega2p_defconfig new file mode 100644 index 000000000000..e2731c3cc7e7 --- /dev/null +++ b/arch/mips/configs/omega2p_defconfig @@ -0,0 +1,129 @@ +CONFIG_RALINK=y +CONFIG_SOC_MT7620=y +CONFIG_DTB_OMEGA2P=y +CONFIG_CPU_MIPS32_R2=y +# CONFIG_COMPACTION is not set +CONFIG_HZ_100=y +CONFIG_PREEMPT=y +# CONFIG_SECCOMP is not set +CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +# CONFIG_FW_LOADER is not set +# CONFIG_ALLOW_DEV_COREDUMP is not set +CONFIG_NETDEVICES=y +# CONFIG_ETHERNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_LEGACY_PTY_COUNT=2 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_MMC=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_MEMORY=y +CONFIG_PHY_RALINK_USB=y +# CONFIG_DNOTIFY is not set +CONFIG_PROC_KCORE=y +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=y +CONFIG_NLS_CODEPAGE_775=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +CONFIG_NLS_CODEPAGE_855=y +CONFIG_NLS_CODEPAGE_857=y +CONFIG_NLS_CODEPAGE_860=y +CONFIG_NLS_CODEPAGE_861=y +CONFIG_NLS_CODEPAGE_862=y +CONFIG_NLS_CODEPAGE_863=y +CONFIG_NLS_CODEPAGE_864=y +CONFIG_NLS_CODEPAGE_865=y +CONFIG_NLS_CODEPAGE_866=y +CONFIG_NLS_CODEPAGE_869=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +CONFIG_NLS_CODEPAGE_932=y +CONFIG_NLS_CODEPAGE_949=y +CONFIG_NLS_CODEPAGE_874=y +CONFIG_NLS_ISO8859_8=y +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +CONFIG_NLS_ISO8859_3=y +CONFIG_NLS_ISO8859_4=y +CONFIG_NLS_ISO8859_5=y +CONFIG_NLS_ISO8859_6=y +CONFIG_NLS_ISO8859_7=y +CONFIG_NLS_ISO8859_9=y +CONFIG_NLS_ISO8859_13=y +CONFIG_NLS_ISO8859_14=y +CONFIG_NLS_ISO8859_15=y +CONFIG_NLS_KOI8_R=y +CONFIG_NLS_KOI8_U=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PANIC_TIMEOUT=10 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_STACKTRACE=y +# CONFIG_FTRACE is not set +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRC16=y +CONFIG_XZ_DEC=y diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig index 7d32fbbca962..b22a3cf149b6 100644 --- a/arch/mips/configs/pistachio_defconfig +++ b/arch/mips/configs/pistachio_defconfig @@ -47,6 +47,8 @@ CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y CONFIG_IP_MROUTE=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y @@ -207,7 +209,7 @@ CONFIG_IMGPDC_WDT=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_CORE=y # CONFIG_RC_DECODERS is not set CONFIG_RC_DEVICES=y CONFIG_IR_IMG=y @@ -292,7 +294,8 @@ CONFIG_SQUASHFS_LZO=y CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y CONFIG_PSTORE_RAM=y -# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_ASCII=m diff --git a/arch/mips/configs/vocore2_defconfig b/arch/mips/configs/vocore2_defconfig new file mode 100644 index 000000000000..9121e4194a63 --- /dev/null +++ b/arch/mips/configs/vocore2_defconfig @@ -0,0 +1,129 @@ +CONFIG_RALINK=y +CONFIG_SOC_MT7620=y +CONFIG_DTB_VOCORE2=y +CONFIG_CPU_MIPS32_R2=y +# CONFIG_COMPACTION is not set +CONFIG_HZ_100=y +CONFIG_PREEMPT=y +# CONFIG_SECCOMP is not set +CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS_ALL=y +CONFIG_EMBEDDED=y +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +# CONFIG_FW_LOADER is not set +# CONFIG_ALLOW_DEV_COREDUMP is not set +CONFIG_NETDEVICES=y +# CONFIG_ETHERNET is not set +# CONFIG_WLAN is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_LEGACY_PTY_COUNT=2 +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=3 +CONFIG_SERIAL_8250_RUNTIME_UARTS=3 +CONFIG_SERIAL_OF_PLATFORM=y +# CONFIG_HW_RANDOM is not set +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_MMC=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_MEMORY=y +CONFIG_PHY_RALINK_USB=y +# CONFIG_DNOTIFY is not set +CONFIG_PROC_KCORE=y +# CONFIG_PROC_PAGE_MONITOR is not set +CONFIG_TMPFS=y +CONFIG_CONFIGFS_FS=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=y +CONFIG_NLS_CODEPAGE_775=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +CONFIG_NLS_CODEPAGE_855=y +CONFIG_NLS_CODEPAGE_857=y +CONFIG_NLS_CODEPAGE_860=y +CONFIG_NLS_CODEPAGE_861=y +CONFIG_NLS_CODEPAGE_862=y +CONFIG_NLS_CODEPAGE_863=y +CONFIG_NLS_CODEPAGE_864=y +CONFIG_NLS_CODEPAGE_865=y +CONFIG_NLS_CODEPAGE_866=y +CONFIG_NLS_CODEPAGE_869=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +CONFIG_NLS_CODEPAGE_932=y +CONFIG_NLS_CODEPAGE_949=y +CONFIG_NLS_CODEPAGE_874=y +CONFIG_NLS_ISO8859_8=y +CONFIG_NLS_CODEPAGE_1250=y +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +CONFIG_NLS_ISO8859_3=y +CONFIG_NLS_ISO8859_4=y +CONFIG_NLS_ISO8859_5=y +CONFIG_NLS_ISO8859_6=y +CONFIG_NLS_ISO8859_7=y +CONFIG_NLS_ISO8859_9=y +CONFIG_NLS_ISO8859_13=y +CONFIG_NLS_ISO8859_14=y +CONFIG_NLS_ISO8859_15=y +CONFIG_NLS_KOI8_R=y +CONFIG_NLS_KOI8_U=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_PANIC_TIMEOUT=10 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_STACKTRACE=y +# CONFIG_FTRACE is not set +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRC16=y +CONFIG_XZ_DEC=y diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index cea2bb1621e6..a25ef822e725 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki diff --git a/arch/mips/dec/prom/cmdline.c b/arch/mips/dec/prom/cmdline.c index c3490bebbc5d..3ed63280ae29 100644 --- a/arch/mips/dec/prom/cmdline.c +++ b/arch/mips/dec/prom/cmdline.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * cmdline.c: read the command line passed to us by the PROM. * diff --git a/arch/mips/dec/prom/dectypes.h b/arch/mips/dec/prom/dectypes.h index 69ea5b9c8190..9fcbcc7cdbd3 100644 --- a/arch/mips/dec/prom/dectypes.h +++ b/arch/mips/dec/prom/dectypes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DECTYPES #define DECTYPES diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c index 0c14a9d6a84a..80cd14cd1a63 100644 --- a/arch/mips/dec/prom/identify.c +++ b/arch/mips/dec/prom/identify.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * identify.c: machine identification code. * diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c index d88eb7a6662b..cc988bbd27fc 100644 --- a/arch/mips/dec/prom/init.c +++ b/arch/mips/dec/prom/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * init.c: PROM library initialisation code. * diff --git a/arch/mips/dec/prom/locore.S b/arch/mips/dec/prom/locore.S index f72b5741025f..0eb8fab62ab0 100644 --- a/arch/mips/dec/prom/locore.S +++ b/arch/mips/dec/prom/locore.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * locore.S */ diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c index 8c62316f22f4..a2acc6454cf3 100644 --- a/arch/mips/dec/prom/memory.c +++ b/arch/mips/dec/prom/memory.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * memory.c: memory initialisation code. * diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c index c15a879046e5..3df01f1da347 100644 --- a/arch/mips/dec/reset.c +++ b/arch/mips/dec/reset.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Reset a DECstation machine. * diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 1914e56f0d96..a2a150e4fbc2 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991, 1992, 1995 Linus Torvalds * Copyright (C) 2000, 2003 Maciej W. Rozycki diff --git a/arch/mips/fw/arc/Makefile b/arch/mips/fw/arc/Makefile index 4f349ec1ea2d..31dd7305d643 100644 --- a/arch/mips/fw/arc/Makefile +++ b/arch/mips/fw/arc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the ARC prom monitor library routines under Linux. # diff --git a/arch/mips/fw/arc/arc_con.c b/arch/mips/fw/arc/arc_con.c index bc32fe64f42a..769d4b9ac82e 100644 --- a/arch/mips/fw/arc/arc_con.c +++ b/arch/mips/fw/arc/arc_con.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Wrap-around code for a console using the * ARC io-routines. diff --git a/arch/mips/fw/arc/init.c b/arch/mips/fw/arc/init.c index 629b24db0d3a..008555969534 100644 --- a/arch/mips/fw/arc/init.c +++ b/arch/mips/fw/arc/init.c @@ -51,7 +51,7 @@ void __init prom_init(void) #endif #ifdef CONFIG_SGI_IP27 { - extern struct plat_smp_ops ip27_smp_ops; + extern const struct plat_smp_ops ip27_smp_ops; register_smp_ops(&ip27_smp_ops); } diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c index 0d75b5a0bad4..dd9496f26e6a 100644 --- a/arch/mips/fw/arc/memory.c +++ b/arch/mips/fw/arc/memory.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * memory.c: PROM library functions for acquiring/using memory descriptors * given to us from the ARCS firmware. diff --git a/arch/mips/fw/arc/salone.c b/arch/mips/fw/arc/salone.c index 9b568950d1fd..2d99f44d5576 100644 --- a/arch/mips/fw/arc/salone.c +++ b/arch/mips/fw/arc/salone.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Routines to load into memory and execute stand-along program images using * ARCS PROM firmware. diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index 51ffbbaddee2..0b67c46666cc 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if MIPS_GENERIC config LEGACY_BOARDS @@ -36,4 +37,10 @@ config FIT_IMAGE_FDT_BOSTON enable this if you wish to boot on a MIPS Boston board, as it is expected by the bootloader. +config FIT_IMAGE_FDT_NI169445 + bool "Include FDT for NI 169445" + help + Enable this to include the FDT for the 169445 platform from + National Instruments in the FIT kernel image. + endif diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index 56b3ea565ed9..874967363dbb 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile @@ -1,6 +1,6 @@ # # Copyright (C) 2016 Imagination Technologies -# Author: Paul Burton +# Author: Paul Burton # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform index 9a30d69e2281..b51432dd10b6 100644 --- a/arch/mips/generic/Platform +++ b/arch/mips/generic/Platform @@ -1,6 +1,6 @@ # # Copyright (C) 2016 Imagination Technologies -# Author: Paul Burton +# Author: Paul Burton # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the @@ -12,3 +12,7 @@ platform-$(CONFIG_MIPS_GENERIC) += generic/ cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb + +its-y := vmlinux.its.S +its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S +its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S diff --git a/arch/mips/generic/board-boston.its.S b/arch/mips/generic/board-boston.its.S new file mode 100644 index 000000000000..a7f51f97b910 --- /dev/null +++ b/arch/mips/generic/board-boston.its.S @@ -0,0 +1,22 @@ +/ { + images { + fdt@boston { + description = "img,boston Device Tree"; + data = /incbin/("boot/dts/img/boston.dtb"); + type = "flat_dt"; + arch = "mips"; + compression = "none"; + hash@0 { + algo = "sha1"; + }; + }; + }; + + configurations { + conf@boston { + description = "Boston Linux kernel"; + kernel = "kernel@0"; + fdt = "fdt@boston"; + }; + }; +}; diff --git a/arch/mips/generic/board-ni169445.its.S b/arch/mips/generic/board-ni169445.its.S new file mode 100644 index 000000000000..e4cb4f95a8cc --- /dev/null +++ b/arch/mips/generic/board-ni169445.its.S @@ -0,0 +1,22 @@ +/ { + images { + fdt@ni169445 { + description = "NI 169445 device tree"; + data = /incbin/("boot/dts/ni/169445.dtb"); + type = "flat_dt"; + arch = "mips"; + compression = "none"; + hash@0 { + algo = "sha1"; + }; + }; + }; + + configurations { + conf@ni169445 { + description = "NI 169445 Linux Kernel"; + kernel = "kernel@0"; + fdt = "fdt@ni169445"; + }; + }; +}; diff --git a/arch/mips/generic/board-sead3.c b/arch/mips/generic/board-sead3.c index f109a6b9fdd0..10cf93d97346 100644 --- a/arch/mips/generic/board-sead3.c +++ b/arch/mips/generic/board-sead3.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c index 3f32b376d30e..5ba6fcc26fa7 100644 --- a/arch/mips/generic/init.c +++ b/arch/mips/generic/init.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,10 +16,11 @@ #include #include +#include #include #include #include -#include +#include #include #include #include @@ -88,6 +89,8 @@ void __init *plat_get_fdt(void) return (void *)fdt; } +#ifdef CONFIG_RELOCATABLE + void __init plat_fdt_relocated(void *new_location) { /* @@ -101,6 +104,8 @@ void __init plat_fdt_relocated(void *new_location) fw_arg1 = (unsigned long)new_location; } +#endif /* CONFIG_RELOCATABLE */ + void __init plat_mem_setup(void) { if (mach && mach->fixup_fdt) diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c index 14064bdd91dd..394f8161e462 100644 --- a/arch/mips/generic/irq.c +++ b/arch/mips/generic/irq.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -12,10 +12,11 @@ #include #include #include -#include #include #include +#include +#include int get_c0_fdc_int(void) { @@ -23,7 +24,7 @@ int get_c0_fdc_int(void) if (cpu_has_veic) panic("Unimplemented!"); - else if (gic_present) + else if (mips_gic_present()) mips_cpu_fdc_irq = gic_get_c0_fdc_int(); else if (cp0_fdc_irq >= 0) mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; @@ -39,7 +40,7 @@ int get_c0_perfcount_int(void) if (cpu_has_veic) panic("Unimplemented!"); - else if (gic_present) + else if (mips_gic_present()) mips_cpu_perf_irq = gic_get_c0_perfcount_int(); else if (cp0_perfcount_irq >= 0) mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; @@ -55,7 +56,7 @@ unsigned int get_c0_compare_int(void) if (cpu_has_veic) panic("Unimplemented!"); - else if (gic_present) + else if (mips_gic_present()) mips_cpu_timer_irq = gic_get_c0_compare_int(); else mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; diff --git a/arch/mips/generic/kexec.c b/arch/mips/generic/kexec.c index e9fb735299e3..1ca409f58929 100644 --- a/arch/mips/generic/kexec.c +++ b/arch/mips/generic/kexec.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Marcin Nowakowski + * Author: Marcin Nowakowski * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/generic/proc.c b/arch/mips/generic/proc.c index 42b33250a4a2..199fb2cc57ee 100644 --- a/arch/mips/generic/proc.c +++ b/arch/mips/generic/proc.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/generic/vmlinux.its.S b/arch/mips/generic/vmlinux.its.S index 3390e2f80b80..1a08438fd893 100644 --- a/arch/mips/generic/vmlinux.its.S +++ b/arch/mips/generic/vmlinux.its.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /dts-v1/; / { @@ -29,28 +30,3 @@ }; }; }; - -#ifdef CONFIG_FIT_IMAGE_FDT_BOSTON -/ { - images { - fdt@boston { - description = "img,boston Device Tree"; - data = /incbin/("boot/dts/img/boston.dtb"); - type = "flat_dt"; - arch = "mips"; - compression = "none"; - hash@0 { - algo = "sha1"; - }; - }; - }; - - configurations { - conf@boston { - description = "Boston Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@boston"; - }; - }; -}; -#endif /* CONFIG_FIT_IMAGE_FDT_BOSTON */ diff --git a/arch/mips/generic/yamon-dt.c b/arch/mips/generic/yamon-dt.c index 6077bca9b364..b408dac722ac 100644 --- a/arch/mips/generic/yamon-dt.c +++ b/arch/mips/generic/yamon-dt.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/asm-prototypes.h b/arch/mips/include/asm/asm-prototypes.h index 6e28971fe73a..d60b57f34e92 100644 --- a/arch/mips/include/asm/asm-prototypes.h +++ b/arch/mips/include/asm/asm-prototypes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h index 859cf7048347..81fae23ce7cd 100644 --- a/arch/mips/include/asm/asm.h +++ b/arch/mips/include/asm/asm.h @@ -55,6 +55,7 @@ .type symbol, @function; \ .ent symbol, 0; \ symbol: .frame sp, 0, ra; \ + .cfi_startproc; \ .insn /* @@ -66,12 +67,14 @@ symbol: .frame sp, 0, ra; \ .type symbol, @function; \ .ent symbol, 0; \ symbol: .frame sp, framesize, rpc; \ + .cfi_startproc; \ .insn /* * END - mark end of function */ #define END(function) \ + .cfi_endproc; \ .end function; \ .size function, .-function diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h index 0ef39ad0f2d4..1c08c1f7903c 100644 --- a/arch/mips/include/asm/asmmacro-32.h +++ b/arch/mips/include/asm/asmmacro-32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * asmmacro.h: Assembler macros to make things easier to read. * diff --git a/arch/mips/include/asm/asmmacro-64.h b/arch/mips/include/asm/asmmacro-64.h index 38ea609465b1..68039dee5ba6 100644 --- a/arch/mips/include/asm/asmmacro-64.h +++ b/arch/mips/include/asm/asmmacro-64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * asmmacro.h: Assembler macros to make things easier to read. * diff --git a/arch/mips/include/asm/bitrev.h b/arch/mips/include/asm/bitrev.h index bc739a404ae3..8a2538e08a4e 100644 --- a/arch/mips/include/asm/bitrev.h +++ b/arch/mips/include/asm/bitrev.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MIPS_ASM_BITREV_H__ #define __MIPS_ASM_BITREV_H__ diff --git a/arch/mips/include/asm/bmips-spaces.h b/arch/mips/include/asm/bmips-spaces.h index eb96541ae67e..febc4c30a308 100644 --- a/arch/mips/include/asm/bmips-spaces.h +++ b/arch/mips/include/asm/bmips-spaces.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_BMIPS_SPACES_H #define __ASM_BMIPS_SPACES_H diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index a92aee7b977a..b3e2975f83d3 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h @@ -48,8 +48,8 @@ #include #include -extern struct plat_smp_ops bmips43xx_smp_ops; -extern struct plat_smp_ops bmips5000_smp_ops; +extern const struct plat_smp_ops bmips43xx_smp_ops; +extern const struct plat_smp_ops bmips5000_smp_ops; static inline int register_bmips_smp_ops(void) { diff --git a/arch/mips/include/asm/bug.h b/arch/mips/include/asm/bug.h index 540c98a810d1..745dc160a069 100644 --- a/arch/mips/include/asm/bug.h +++ b/arch/mips/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_BUG_H #define __ASM_BUG_H diff --git a/arch/mips/include/asm/bugs.h b/arch/mips/include/asm/bugs.h index b160a706795d..d8ab8b7129b5 100644 --- a/arch/mips/include/asm/bugs.h +++ b/arch/mips/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is included by init/main.c to check for architecture-dependent bugs. * diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h index 4809c29a4890..5a8f96ebe5fa 100644 --- a/arch/mips/include/asm/clock.h +++ b/arch/mips/include/asm/clock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MIPS_CLOCK_H #define __ASM_MIPS_CLOCK_H diff --git a/arch/mips/include/asm/cmp.h b/arch/mips/include/asm/cmp.h index 033d97303c85..e9e87504bb0c 100644 --- a/arch/mips/include/asm/cmp.h +++ b/arch/mips/include/asm/cmp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CMP_H #define _ASM_CMP_H diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index 903f3bf48419..7e25c5cc353a 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -155,14 +155,16 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, return __cmpxchg_small(ptr, old, new, size); case 4: - return __cmpxchg_asm("ll", "sc", (volatile u32 *)ptr, old, new); + return __cmpxchg_asm("ll", "sc", (volatile u32 *)ptr, + (u32)old, new); case 8: /* lld/scd are only available for MIPS64 */ if (!IS_ENABLED(CONFIG_64BIT)) return __cmpxchg_called_with_bad_pointer(); - return __cmpxchg_asm("lld", "scd", (volatile u64 *)ptr, old, new); + return __cmpxchg_asm("lld", "scd", (volatile u64 *)ptr, + (u64)old, new); default: return __cmpxchg_called_with_bad_pointer(); diff --git a/arch/mips/include/asm/compat-signal.h b/arch/mips/include/asm/compat-signal.h index 4c6176467146..e87cd243b0f4 100644 --- a/arch/mips/include/asm/compat-signal.h +++ b/arch/mips/include/asm/compat-signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_COMPAT_SIGNAL_H #define __ASM_COMPAT_SIGNAL_H diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index a9580097cba8..8e2b5b556488 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_COMPAT_H #define _ASM_COMPAT_H /* diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index cd6efb07c980..a41059d47d31 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -15,6 +15,8 @@ #include #include +#include + /* * Descriptor for a cache */ @@ -77,16 +79,9 @@ struct cpuinfo_mips { struct cache_desc tcache; /* Tertiary/split secondary cache */ int srsets; /* Shadow register sets */ int package;/* physical package number */ - int core; /* physical core number */ + unsigned int globalnumber; #ifdef CONFIG_64BIT int vmbits; /* Virtual memory size in bits */ -#endif -#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) - /* - * There is not necessarily a 1:1 mapping of VPE num to CPU number - * in particular on multi-core systems. - */ - int vpe_id; /* Virtual Processor number */ #endif void *data; /* Additional data */ unsigned int watch_reg_count; /* Number that exist */ @@ -144,11 +139,52 @@ struct proc_cpuinfo_notifier_args { unsigned long n; }; -#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) -# define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) -#else -# define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) -#endif +static inline unsigned int cpu_cluster(struct cpuinfo_mips *cpuinfo) +{ + /* Optimisation for systems where multiple clusters aren't used */ + if (!IS_ENABLED(CONFIG_CPU_MIPSR6)) + return 0; + + return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CLUSTER) >> + MIPS_GLOBALNUMBER_CLUSTER_SHF; +} + +static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo) +{ + return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >> + MIPS_GLOBALNUMBER_CORE_SHF; +} + +static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo) +{ + /* Optimisation for systems where VP(E)s aren't used */ + if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6)) + return 0; + + return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >> + MIPS_GLOBALNUMBER_VP_SHF; +} + +extern void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster); +extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core); +extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe); + +static inline bool cpus_are_siblings(int cpua, int cpub) +{ + struct cpuinfo_mips *infoa = &cpu_data[cpua]; + struct cpuinfo_mips *infob = &cpu_data[cpub]; + unsigned int gnuma, gnumb; + + if (infoa->package != infob->package) + return false; + + gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP; + gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP; + if (gnuma != gnumb) + return false; + + return true; +} static inline unsigned long cpu_asid_inc(void) { diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index 175fe565f4e1..a45af3de075d 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -151,11 +151,6 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_R5500: #endif -#ifdef CONFIG_SYS_HAS_CPU_R6000 - case CPU_R6000: - case CPU_R6000A: -#endif - #ifdef CONFIG_SYS_HAS_CPU_NEVADA case CPU_NEVADA: #endif diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index d0c152b989f8..d39324c4adf1 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * cpu.h: Values of the PRId register used to match up * various MIPS cpu types. @@ -285,11 +286,6 @@ enum cpu_type_enum { CPU_R2000, CPU_R3000, CPU_R3000A, CPU_R3041, CPU_R3051, CPU_R3052, CPU_R3081, CPU_R3081E, - /* - * R6000 class processors - */ - CPU_R6000, CPU_R6000A, - /* * R4000 class processors */ diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index aba71385f9d1..42f8cbad6c23 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_DMA_MAPPING_H #define _ASM_DMA_MAPPING_H diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h index 5b9ed1bffdbc..be726b943530 100644 --- a/arch/mips/include/asm/dma.h +++ b/arch/mips/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm/dma.h: Defines for using and allocating dma channels. * Written by Hennus Bergman, 1992. diff --git a/arch/mips/include/asm/dsemul.h b/arch/mips/include/asm/dsemul.h index a6e067801f23..b47a97527673 100644 --- a/arch/mips/include/asm/dsemul.h +++ b/arch/mips/include/asm/dsemul.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h index 980b16527374..fc467767329b 100644 --- a/arch/mips/include/asm/edac.h +++ b/arch/mips/include/asm/edac.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_EDAC_H #define ASM_EDAC_H diff --git a/arch/mips/include/asm/extable.h b/arch/mips/include/asm/extable.h index dce7a627a925..78d0ae156058 100644 --- a/arch/mips/include/asm/extable.h +++ b/arch/mips/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_EXTABLE_H #define _ASM_EXTABLE_H diff --git a/arch/mips/include/asm/floppy.h b/arch/mips/include/asm/floppy.h index d75aed36480a..021d09ae5670 100644 --- a/arch/mips/include/asm/floppy.h +++ b/arch/mips/include/asm/floppy.h @@ -10,11 +10,11 @@ #ifndef _ASM_FLOPPY_H #define _ASM_FLOPPY_H -#include +#include static inline void fd_cacheflush(char * addr, long size) { - dma_cache_sync(NULL, addr, size, DMA_BIDIRECTIONAL); + dma_cache_wback_inv((unsigned long)addr, size); } #define MAX_BUFFER_SECTORS 24 diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h index c05369e0b8d6..b36097d3cbf4 100644 --- a/arch/mips/include/asm/fpu_emulator.h +++ b/arch/mips/include/asm/fpu_emulator.h @@ -36,6 +36,7 @@ struct mips_fpu_emulator_stats { unsigned long emulated; unsigned long loads; unsigned long stores; + unsigned long branches; unsigned long cp1ops; unsigned long cp1xops; unsigned long errors; @@ -45,6 +46,121 @@ struct mips_fpu_emulator_stats { unsigned long ieee754_zerodiv; unsigned long ieee754_invalidop; unsigned long ds_emul; + + unsigned long abs_s; + unsigned long abs_d; + unsigned long add_s; + unsigned long add_d; + unsigned long bc1eqz; + unsigned long bc1nez; + unsigned long ceil_w_s; + unsigned long ceil_w_d; + unsigned long ceil_l_s; + unsigned long ceil_l_d; + unsigned long class_s; + unsigned long class_d; + unsigned long cmp_af_s; + unsigned long cmp_af_d; + unsigned long cmp_eq_s; + unsigned long cmp_eq_d; + unsigned long cmp_le_s; + unsigned long cmp_le_d; + unsigned long cmp_lt_s; + unsigned long cmp_lt_d; + unsigned long cmp_ne_s; + unsigned long cmp_ne_d; + unsigned long cmp_or_s; + unsigned long cmp_or_d; + unsigned long cmp_ueq_s; + unsigned long cmp_ueq_d; + unsigned long cmp_ule_s; + unsigned long cmp_ule_d; + unsigned long cmp_ult_s; + unsigned long cmp_ult_d; + unsigned long cmp_un_s; + unsigned long cmp_un_d; + unsigned long cmp_une_s; + unsigned long cmp_une_d; + unsigned long cmp_saf_s; + unsigned long cmp_saf_d; + unsigned long cmp_seq_s; + unsigned long cmp_seq_d; + unsigned long cmp_sle_s; + unsigned long cmp_sle_d; + unsigned long cmp_slt_s; + unsigned long cmp_slt_d; + unsigned long cmp_sne_s; + unsigned long cmp_sne_d; + unsigned long cmp_sor_s; + unsigned long cmp_sor_d; + unsigned long cmp_sueq_s; + unsigned long cmp_sueq_d; + unsigned long cmp_sule_s; + unsigned long cmp_sule_d; + unsigned long cmp_sult_s; + unsigned long cmp_sult_d; + unsigned long cmp_sun_s; + unsigned long cmp_sun_d; + unsigned long cmp_sune_s; + unsigned long cmp_sune_d; + unsigned long cvt_d_l; + unsigned long cvt_d_s; + unsigned long cvt_d_w; + unsigned long cvt_l_s; + unsigned long cvt_l_d; + unsigned long cvt_s_d; + unsigned long cvt_s_l; + unsigned long cvt_s_w; + unsigned long cvt_w_s; + unsigned long cvt_w_d; + unsigned long div_s; + unsigned long div_d; + unsigned long floor_w_s; + unsigned long floor_w_d; + unsigned long floor_l_s; + unsigned long floor_l_d; + unsigned long maddf_s; + unsigned long maddf_d; + unsigned long max_s; + unsigned long max_d; + unsigned long maxa_s; + unsigned long maxa_d; + unsigned long min_s; + unsigned long min_d; + unsigned long mina_s; + unsigned long mina_d; + unsigned long mov_s; + unsigned long mov_d; + unsigned long msubf_s; + unsigned long msubf_d; + unsigned long mul_s; + unsigned long mul_d; + unsigned long neg_s; + unsigned long neg_d; + unsigned long recip_s; + unsigned long recip_d; + unsigned long rint_s; + unsigned long rint_d; + unsigned long round_w_s; + unsigned long round_w_d; + unsigned long round_l_s; + unsigned long round_l_d; + unsigned long rsqrt_s; + unsigned long rsqrt_d; + unsigned long sel_s; + unsigned long sel_d; + unsigned long seleqz_s; + unsigned long seleqz_d; + unsigned long selnez_s; + unsigned long selnez_d; + unsigned long sqrt_s; + unsigned long sqrt_d; + unsigned long sub_s; + unsigned long sub_d; + unsigned long trunc_w_s; + unsigned long trunc_w_d; + unsigned long trunc_l_s; + unsigned long trunc_l_d; }; DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats); @@ -62,7 +178,7 @@ do { \ extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, int has_fpu, - void *__user *fault_addr); + void __user **fault_addr); void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, struct task_struct *tsk); int process_fpemu_return(int sig, void __user *fault_addr, diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index 1de190bdfb9c..a9e61ea54ca9 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h @@ -83,18 +83,9 @@ } static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -125,17 +116,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/mips/include/asm/fw/arc/hinv.h b/arch/mips/include/asm/fw/arc/hinv.h index 9fac64a26353..d67b6a90f9b3 100644 --- a/arch/mips/include/asm/fw/arc/hinv.h +++ b/arch/mips/include/asm/fw/arc/hinv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ARCS hardware/memory inventory/configuration and system ID definitions. */ diff --git a/arch/mips/include/asm/gio_device.h b/arch/mips/include/asm/gio_device.h index 71a986e9b694..c52948f9ca95 100644 --- a/arch/mips/include/asm/gio_device.h +++ b/arch/mips/include/asm/gio_device.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index 279b6d14ffeb..9d84aafc33d0 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * highmem.h: virtual kernel memory mappings for high memory * diff --git a/arch/mips/include/asm/hpet.h b/arch/mips/include/asm/hpet.h index 18a8f778bfaa..d47268eceabc 100644 --- a/arch/mips/include/asm/hpet.h +++ b/arch/mips/include/asm/hpet.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HPET_H #define _ASM_HPET_H diff --git a/arch/mips/include/asm/idle.h b/arch/mips/include/asm/idle.h index a2d18ab57ac6..655a6dbc861a 100644 --- a/arch/mips/include/asm/idle.h +++ b/arch/mips/include/asm/idle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_IDLE_H #define __ASM_IDLE_H diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index ecabc00c1e66..0cbf3af37eca 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -632,4 +632,6 @@ extern void (*_dma_cache_inv)(unsigned long start, unsigned long size); */ #define xlate_dev_kmem_ptr(p) p +void __ioread64_copy(void *to, const void __iomem *from, size_t count); + #endif /* _ASM_IO_H */ diff --git a/arch/mips/include/asm/isadep.h b/arch/mips/include/asm/isadep.h index b4af6eb24ab9..d1683202399b 100644 --- a/arch/mips/include/asm/isadep.h +++ b/arch/mips/include/asm/isadep.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Various ISA level dependent constants. * Most of the following constants reflect the different layout diff --git a/arch/mips/include/asm/jazzdma.h b/arch/mips/include/asm/jazzdma.h index 2cefc3c47241..d913439c738c 100644 --- a/arch/mips/include/asm/jazzdma.h +++ b/arch/mips/include/asm/jazzdma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Helpfile for jazzdma.c -- Mips Jazz R4030 DMA controller support */ diff --git a/arch/mips/include/asm/kdebug.h b/arch/mips/include/asm/kdebug.h index 8e3d08e739c1..a55a207cfaa3 100644 --- a/arch/mips/include/asm/kdebug.h +++ b/arch/mips/include/asm/kdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MIPS_KDEBUG_H #define _ASM_MIPS_KDEBUG_H diff --git a/arch/mips/include/asm/kgdb.h b/arch/mips/include/asm/kgdb.h index 69dc0df94a96..4f2302267deb 100644 --- a/arch/mips/include/asm/kgdb.h +++ b/arch/mips/include/asm/kgdb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_KGDB_H_ #define __ASM_KGDB_H_ diff --git a/arch/mips/include/asm/kmap_types.h b/arch/mips/include/asm/kmap_types.h index c1909dcada39..16665dc2431b 100644 --- a/arch/mips/include/asm/kmap_types.h +++ b/arch/mips/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H diff --git a/arch/mips/include/asm/kvm_para.h b/arch/mips/include/asm/kvm_para.h index 5a9aa918abe6..60b1aa0b7014 100644 --- a/arch/mips/include/asm/kvm_para.h +++ b/arch/mips/include/asm/kvm_para.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MIPS_KVM_PARA_H #define _ASM_MIPS_KVM_PARA_H diff --git a/arch/mips/include/asm/lasat/ds1603.h b/arch/mips/include/asm/lasat/ds1603.h index edcd7544b358..ab833be9637d 100644 --- a/arch/mips/include/asm/lasat/ds1603.h +++ b/arch/mips/include/asm/lasat/ds1603.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* Lasat 100 */ diff --git a/arch/mips/include/asm/lasat/eeprom.h b/arch/mips/include/asm/lasat/eeprom.h index d918b822e376..24001a5cbb11 100644 --- a/arch/mips/include/asm/lasat/eeprom.h +++ b/arch/mips/include/asm/lasat/eeprom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* lasat 100 */ diff --git a/arch/mips/include/asm/lasat/head.h b/arch/mips/include/asm/lasat/head.h index f5589f31a197..20b0ecedd4b5 100644 --- a/arch/mips/include/asm/lasat/head.h +++ b/arch/mips/include/asm/lasat/head.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Image header stuff */ diff --git a/arch/mips/include/asm/lasat/lasatint.h b/arch/mips/include/asm/lasat/lasatint.h index e0d2458b43d0..b2b346e0ca38 100644 --- a/arch/mips/include/asm/lasat/lasatint.h +++ b/arch/mips/include/asm/lasat/lasatint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LASAT_LASATINT_H #define __ASM_LASAT_LASATINT_H diff --git a/arch/mips/include/asm/lasat/picvue.h b/arch/mips/include/asm/lasat/picvue.h index 42a492edc40e..99987c5a4b83 100644 --- a/arch/mips/include/asm/lasat/picvue.h +++ b/arch/mips/include/asm/lasat/picvue.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Lasat 100 */ #define PVC_REG_100 KSEG1ADDR(0x1c820000) #define PVC_DATA_SHIFT_100 0 diff --git a/arch/mips/include/asm/lasat/serial.h b/arch/mips/include/asm/lasat/serial.h index a2f6c7a9cfe8..7b43d74089d1 100644 --- a/arch/mips/include/asm/lasat/serial.h +++ b/arch/mips/include/asm/lasat/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* Lasat 100 boards serial configuration */ diff --git a/arch/mips/include/asm/linkage.h b/arch/mips/include/asm/linkage.h index 99651b0ea7c7..1829c2b6da6c 100644 --- a/arch/mips/include/asm/linkage.h +++ b/arch/mips/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h index 8feaed62a2ab..ac8264eca1e9 100644 --- a/arch/mips/include/asm/local.h +++ b/arch/mips/include/asm/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_MIPS_LOCAL_H #define _ARCH_MIPS_LOCAL_H diff --git a/arch/mips/include/asm/m48t37.h b/arch/mips/include/asm/m48t37.h index e6eaf5339e4e..3687a02e692b 100644 --- a/arch/mips/include/asm/m48t37.h +++ b/arch/mips/include/asm/m48t37.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Registers for the SGS-Thomson M48T37 Timekeeper RAM chip */ diff --git a/arch/mips/include/asm/maar.h b/arch/mips/include/asm/maar.h index e10f78befbd9..1e0da80bba13 100644 --- a/arch/mips/include/asm/maar.h +++ b/arch/mips/include/asm/maar.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/mach-ath25/ath25_platform.h b/arch/mips/include/asm/mach-ath25/ath25_platform.h index 4f4ee4f9e5ec..0aacc55aa51d 100644 --- a/arch/mips/include/asm/mach-ath25/ath25_platform.h +++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_ATH25_PLATFORM_H #define __ASM_MACH_ATH25_PLATFORM_H diff --git a/arch/mips/include/asm/mach-au1x00/au1200fb.h b/arch/mips/include/asm/mach-au1x00/au1200fb.h index b3c87cc64bb9..e0e98f06c642 100644 --- a/arch/mips/include/asm/mach-au1x00/au1200fb.h +++ b/arch/mips/include/asm/mach-au1x00/au1200fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * platform data for au1200fb driver. */ diff --git a/arch/mips/include/asm/mach-au1x00/au1550_spi.h b/arch/mips/include/asm/mach-au1x00/au1550_spi.h index 08e1958e9410..fe6ca4606d77 100644 --- a/arch/mips/include/asm/mach-au1x00/au1550_spi.h +++ b/arch/mips/include/asm/mach-au1x00/au1550_spi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * au1550_spi.h - Au1550 PSC SPI controller driver - platform data structure */ diff --git a/arch/mips/include/asm/mach-au1x00/au1550nd.h b/arch/mips/include/asm/mach-au1x00/au1550nd.h index ad4c0a03afef..d26dc1dadf44 100644 --- a/arch/mips/include/asm/mach-au1x00/au1550nd.h +++ b/arch/mips/include/asm/mach-au1x00/au1550nd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * platform data for the Au1550 NAND driver */ diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h index 49dc8d9db186..9d1c8d5ed4a8 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_eth.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __AU1X00_ETH_DATA_H #define __AU1X00_ETH_DATA_H diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h index bace5b9ae4df..f439cf9cf9d1 100644 --- a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h @@ -8,12 +8,16 @@ #define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H #define cpu_has_tlb 1 +#define cpu_has_ftlb 0 #define cpu_has_tlbinv 0 #define cpu_has_segments 0 #define cpu_has_eva 0 #define cpu_has_htw 0 +#define cpu_has_ldpte 0 #define cpu_has_rixiex 0 #define cpu_has_maar 0 +#define cpu_has_rw_llb 0 +#define cpu_has_3kex 0 #define cpu_has_4kex 1 #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 @@ -30,6 +34,12 @@ #define cpu_has_mcheck 1 #define cpu_has_ejtag 1 #define cpu_has_llsc 1 +#define cpu_has_guestctl0ext 0 +#define cpu_has_guestctl1 0 +#define cpu_has_guestctl2 0 +#define cpu_has_guestid 0 +#define cpu_has_drg 0 +#define cpu_has_bp_ghist 0 #define cpu_has_mips16 0 #define cpu_has_mips16e2 0 #define cpu_has_mdmx 0 @@ -37,17 +47,23 @@ #define cpu_has_smartmips 0 #define cpu_has_rixi 0 #define cpu_has_mmips 0 +#define cpu_has_lpa 0 +#define cpu_has_mhv 0 #define cpu_has_vtag_icache 0 #define cpu_has_dc_aliases 0 #define cpu_has_ic_fills_f_dc 1 #define cpu_has_pindexed_dcache 0 #define cpu_has_mips32r1 1 #define cpu_has_mips32r2 0 +#define cpu_has_mips32r6 0 #define cpu_has_mips64r1 0 #define cpu_has_mips64r2 0 +#define cpu_has_mips64r6 0 #define cpu_has_dsp 0 #define cpu_has_dsp2 0 +#define cpu_has_dsp3 0 #define cpu_has_mipsmt 0 +#define cpu_has_vp 0 #define cpu_has_userlocal 0 #define cpu_has_nofpuex 0 #define cpu_has_64bits 0 @@ -58,9 +74,19 @@ #define cpu_dcache_line_size() 32 #define cpu_icache_line_size() 32 +#define cpu_scache_line_size() 0 #define cpu_has_perf_cntr_intr_bit 0 #define cpu_has_vz 0 #define cpu_has_msa 0 +#define cpu_has_fre 0 +#define cpu_has_cdmm 0 +#define cpu_has_small_pages 0 +#define cpu_has_nan_legacy 1 +#define cpu_has_nan_2008 1 +#define cpu_has_ebase_wg 0 +#define cpu_has_badinstr 0 +#define cpu_has_badinstrp 0 +#define cpu_has_contextconfig 0 #endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1300.h b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h index d607d643b973..d25846a1291f 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio-au1300.h +++ b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * gpio-au1300.h -- GPIO control for Au1300 GPIC and compatibles. * diff --git a/arch/mips/include/asm/mach-au1x00/prom.h b/arch/mips/include/asm/mach-au1x00/prom.h index 4c0e09cf1735..c62ee0246d76 100644 --- a/arch/mips/include/asm/mach-au1x00/prom.h +++ b/arch/mips/include/asm/mach-au1x00/prom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __AU1X00_PROM_H #define __AU1X00_PROM_H diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h index ee3d4fe515a0..cbf9da7f2f94 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __BCM47XX_BOARD_H #define __BCM47XX_BOARD_H diff --git a/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h index b7992cd4aaf9..b23ff47ea475 100644 --- a/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-bcm47xx/cpu-feature-overrides.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_BCM47XX_CPU_FEATURE_OVERRIDES_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h index fa3e7e617b09..1d19a726f86c 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_BOARD_H_ #define BCM63XX_BOARD_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h index 56bb19219d48..1cad18e6681d 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_CPU_H_ #define BCM63XX_CPU_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h index b1821c866e53..1c634d7c1597 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_CS_H #define BCM63XX_CS_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h index b587d45c3045..4e4970787371 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __BCM63XX_DSP_H #define __BCM63XX_DSP_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h index c4e856f27040..c0bd47444cff 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_DEV_ENET_H_ #define BCM63XX_DEV_ENET_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h index 354b8481ec4a..4d5005f2b8b5 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __BCM63XX_FLASH_H #define __BCM63XX_FLASH_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h index 1b1acafb3d79..f93f176c1bee 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_DEV_HSSPI_H #define BCM63XX_DEV_HSSPI_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h index c549344b70ad..1951c125cf0e 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_DEV_PCI_H_ #define BCM63XX_DEV_PCI_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h index 2beb3969ce3b..01674ac58bb5 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_DEV_PCMCIA_H_ #define BCM63XX_DEV_PCMCIA_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index dd299548860d..0ab750522324 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_DEV_SPI_H #define BCM63XX_DEV_SPI_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h index 23c705baf171..88f8cf1c7094 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_DEV_UART_H_ #define BCM63XX_DEV_UART_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h index 5d6d6986f40b..3f920baff966 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_DEV_USB_USBD_H_ #define BCM63XX_DEV_USB_USBD_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h index 565ff36a1119..8fe88c2251e4 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_GPIO_H #define BCM63XX_GPIO_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h index 7033144aab2d..31c692433ada 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_IO_H_ #define BCM63XX_IO_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h index 0c3074b871b8..7887bc6905f5 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_IRQ_H_ #define BCM63XX_IRQ_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h index 1e89df7244bd..73df916e414d 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_IUDMA_H_ #define BCM63XX_IUDMA_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 348df49dcc9f..f78d725f263f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_NVRAM_H #define BCM63XX_NVRAM_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 5035f09c5427..bc3444cd4ef2 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_REGS_H_ #define BCM63XX_REGS_H_ @@ -710,7 +711,7 @@ /* Broadcom 6345 ENET DMA definitions */ #define ENETDMA_6345_CHANCFG_REG (0x00) -#define ENETDMA_6345_MAXBURST_REG (0x40) +#define ENETDMA_6345_MAXBURST_REG (0x04) #define ENETDMA_6345_RSTART_REG (0x08) diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h index 3a6eb9c1adc6..2c0645b7da84 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_reset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __BCM63XX_RESET_H #define __BCM63XX_RESET_H diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h index c0fce833c9ed..bcbece793fd8 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_TIMER_H_ #define BCM63XX_TIMER_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h index b86a0efba665..5e5b1bc4a324 100644 --- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BOARD_BCM963XX_H_ #define BOARD_BCM963XX_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h index b56cf10b91d3..0ebecbdb9749 100644 --- a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h index aea6e64b828f..8cd261ec0a75 100644 --- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h +++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BCM63XX_IOREMAP_H_ #define BCM63XX_IOREMAP_H_ diff --git a/arch/mips/include/asm/mach-bcm63xx/irq.h b/arch/mips/include/asm/mach-bcm63xx/irq.h index 2bbfc8d1f307..b016f0615d5f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/irq.h +++ b/arch/mips/include/asm/mach-bcm63xx/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_BCM63XX_IRQ_H #define __ASM_MACH_BCM63XX_IRQ_H diff --git a/arch/mips/include/asm/mach-bmips/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bmips/cpu-feature-overrides.h index fa0583e1ce0d..68a219d80407 100644 --- a/arch/mips/include/asm/mach-bmips/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-bmips/cpu-feature-overrides.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_BMIPS_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_BMIPS_CPU_FEATURE_OVERRIDES_H diff --git a/arch/mips/include/asm/mach-bmips/ioremap.h b/arch/mips/include/asm/mach-bmips/ioremap.h index 29c7a7bb7080..52632ebc705f 100644 --- a/arch/mips/include/asm/mach-bmips/ioremap.h +++ b/arch/mips/include/asm/mach-bmips/ioremap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_BMIPS_IOREMAP_H #define __ASM_MACH_BMIPS_IOREMAP_H diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index bd8b9bbe1771..a4f798629c3d 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h @@ -46,9 +46,9 @@ #define cpu_has_64bits 1 #define cpu_has_octeon_cache 1 #define cpu_has_saa octeon_has_saa() -#define cpu_has_mips32r1 0 -#define cpu_has_mips32r2 0 -#define cpu_has_mips64r1 0 +#define cpu_has_mips32r1 1 +#define cpu_has_mips32r2 1 +#define cpu_has_mips64r1 1 #define cpu_has_mips64r2 1 #define cpu_has_dsp 0 #define cpu_has_dsp2 0 diff --git a/arch/mips/include/asm/mach-db1x00/bcsr.h b/arch/mips/include/asm/mach-db1x00/bcsr.h index 3c3ed4ae45e2..4a27738e8b22 100644 --- a/arch/mips/include/asm/mach-db1x00/bcsr.h +++ b/arch/mips/include/asm/mach-db1x00/bcsr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * bcsr.h -- Db1xxx/Pb1xxx Devboard CPLD registers ("BCSR") abstraction. * diff --git a/arch/mips/include/asm/mach-generic/kmalloc.h b/arch/mips/include/asm/mach-generic/kmalloc.h index a5d669086ed9..74207c7bd00d 100644 --- a/arch/mips/include/asm/mach-generic/kmalloc.h +++ b/arch/mips/include/asm/mach-generic/kmalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_GENERIC_KMALLOC_H #define __ASM_MACH_GENERIC_KMALLOC_H diff --git a/arch/mips/include/asm/mach-ip27/mmzone.h b/arch/mips/include/asm/mach-ip27/mmzone.h index ebc9377ff876..2ed3094dee07 100644 --- a/arch/mips/include/asm/mach-ip27/mmzone.h +++ b/arch/mips/include/asm/mach-ip27/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MACH_MMZONE_H #define _ASM_MACH_MMZONE_H diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h index defd135e7ac8..42ea1313626c 100644 --- a/arch/mips/include/asm/mach-ip27/topology.h +++ b/arch/mips/include/asm/mach-ip27/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MACH_TOPOLOGY_H #define _ASM_MACH_TOPOLOGY_H 1 @@ -23,7 +24,6 @@ struct cpuinfo_ip27 { extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS]; #define cpu_to_node(cpu) (sn_cpu_info[(cpu)].p_nodeid) -#define parent_node(node) (node) #define cpumask_of_node(node) ((node) == -1 ? \ cpu_all_mask : \ &hub_data(node)->h_cpus) diff --git a/arch/mips/include/asm/mach-ip32/kmalloc.h b/arch/mips/include/asm/mach-ip32/kmalloc.h index 042ca926c48f..07a0146ea61f 100644 --- a/arch/mips/include/asm/mach-ip32/kmalloc.h +++ b/arch/mips/include/asm/mach-ip32/kmalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_IP32_KMALLOC_H #define __ASM_MACH_IP32_KMALLOC_H diff --git a/arch/mips/include/asm/mach-jz4740/base.h b/arch/mips/include/asm/mach-jz4740/base.h index f37318605452..96b2d6674cdb 100644 --- a/arch/mips/include/asm/mach-jz4740/base.h +++ b/arch/mips/include/asm/mach-jz4740/base.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_JZ4740_BASE_H__ #define __ASM_MACH_JZ4740_BASE_H__ diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h b/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h index 8543f432b4b3..e9cc62cfac99 100644 --- a/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h +++ b/arch/mips/include/asm/mach-jz4740/jz4740_mmc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_MMC_JZ4740_MMC #define __LINUX_MMC_JZ4740_MMC diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h index 7f7b0fc554da..f381d465e768 100644 --- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h +++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h @@ -16,7 +16,7 @@ #ifndef __ASM_MACH_JZ4740_JZ4740_NAND_H__ #define __ASM_MACH_JZ4740_JZ4740_NAND_H__ -#include +#include #include #define JZ_NAND_NUM_BANKS 4 diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index 8064d7a4b33d..d750f93232e4 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h @@ -46,8 +46,6 @@ extern struct clk *clk_get_ppe(void); /* find out what bootsource we have */ extern unsigned char ltq_boot_select(void); -/* find out what caused the last cpu reset */ -extern int ltq_reset_cause(void); /* find out the soc type */ extern int ltq_soc_type(void); diff --git a/arch/mips/include/asm/mach-lasat/irq.h b/arch/mips/include/asm/mach-lasat/irq.h index 3a282419d5f9..d79cbe075084 100644 --- a/arch/mips/include/asm/mach-lasat/irq.h +++ b/arch/mips/include/asm/mach-lasat/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MACH_LASAT_IRQ_H #define _ASM_MACH_LASAT_IRQ_H diff --git a/arch/mips/include/asm/mach-lasat/mach-gt64120.h b/arch/mips/include/asm/mach-lasat/mach-gt64120.h index c253d3fa5167..6666a8871a23 100644 --- a/arch/mips/include/asm/mach-lasat/mach-gt64120.h +++ b/arch/mips/include/asm/mach-lasat/mach-gt64120.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is a direct copy of the ev96100.h file, with a global * search and replace. The numbers are the same. diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h index 9f9bb9c53785..4f69f08717f6 100644 --- a/arch/mips/include/asm/mach-loongson64/boot_param.h +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_LOONGSON64_BOOT_PARAM_H_ #define __ASM_MACH_LOONGSON64_BOOT_PARAM_H_ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h index a0ee0cb775ad..9795b3361532 100644 --- a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * The header file of cs5536 south bridge. * diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h index 021d0172dad6..52e8bb0fc04d 100644 --- a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * cs5536 mfgpt header file */ diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h index bf9dd9eb4ceb..a0d4b752899e 100644 --- a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * the definition file of cs5536 Virtual Support Module(VSM). * pci configuration space can be accessed through the VSM, so diff --git a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h index 1f17c1815ee5..70d0153cccc3 100644 --- a/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h +++ b/arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * the read/write interfaces for Virtual Support Module(VSM) * diff --git a/arch/mips/include/asm/mach-loongson64/irq.h b/arch/mips/include/asm/mach-loongson64/irq.h index d18c45c7c394..3644b68c0ccc 100644 --- a/arch/mips/include/asm/mach-loongson64/irq.h +++ b/arch/mips/include/asm/mach-loongson64/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_LOONGSON64_IRQ_H_ #define __ASM_MACH_LOONGSON64_IRQ_H_ diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h index c68c0cc879c6..d0ae5d55413b 100644 --- a/arch/mips/include/asm/mach-loongson64/loongson.h +++ b/arch/mips/include/asm/mach-loongson64/loongson.h @@ -26,7 +26,7 @@ extern void mach_prepare_shutdown(void); /* environment arguments from bootloader */ extern u32 cpu_clock_freq; extern u32 memsize, highmemsize; -extern struct plat_smp_ops loongson3_smp_ops; +extern const struct plat_smp_ops loongson3_smp_ops; /* loongson-specific command line, env and memory initialization */ extern void __init prom_init_memory(void); diff --git a/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h index 74230d0ca98b..545f91f2ae16 100644 --- a/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h +++ b/arch/mips/include/asm/mach-loongson64/loongson_hwmon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LOONGSON_HWMON_H_ #define __LOONGSON_HWMON_H_ diff --git a/arch/mips/include/asm/mach-loongson64/spaces.h b/arch/mips/include/asm/mach-loongson64/spaces.h index c6040b9fcf94..e85bc1d9c4f2 100644 --- a/arch/mips/include/asm/mach-loongson64/spaces.h +++ b/arch/mips/include/asm/mach-loongson64/spaces.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_LOONGSON64_SPACES_H_ #define __ASM_MACH_LOONGSON64_SPACES_H_ diff --git a/arch/mips/include/asm/mach-loongson64/topology.h b/arch/mips/include/asm/mach-loongson64/topology.h index 0d8f3b55bdbc..7ff819ab308a 100644 --- a/arch/mips/include/asm/mach-loongson64/topology.h +++ b/arch/mips/include/asm/mach-loongson64/topology.h @@ -1,10 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MACH_TOPOLOGY_H #define _ASM_MACH_TOPOLOGY_H #ifdef CONFIG_NUMA #define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) -#define parent_node(node) (node) #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) struct pci_bus; diff --git a/arch/mips/include/asm/mach-loongson64/workarounds.h b/arch/mips/include/asm/mach-loongson64/workarounds.h index e659f041e116..17b71172a097 100644 --- a/arch/mips/include/asm/mach-loongson64/workarounds.h +++ b/arch/mips/include/asm/mach-loongson64/workarounds.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_LOONGSON64_WORKAROUNDS_H_ #define __ASM_MACH_LOONGSON64_WORKAROUNDS_H_ diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h index 47cfe64efbb0..af9eeea250ed 100644 --- a/arch/mips/include/asm/mach-malta/irq.h +++ b/arch/mips/include/asm/mach-malta/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_MIPS_IRQ_H #define __ASM_MACH_MIPS_IRQ_H diff --git a/arch/mips/include/asm/mach-malta/mach-gt64120.h b/arch/mips/include/asm/mach-malta/mach-gt64120.h index 62a4b2889fa7..b9dee7c3e469 100644 --- a/arch/mips/include/asm/mach-malta/mach-gt64120.h +++ b/arch/mips/include/asm/mach-malta/mach-gt64120.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is a direct copy of the ev96100.h file, with a global * search and replace. The numbers are the same. diff --git a/arch/mips/include/asm/mach-malta/malta-dtshim.h b/arch/mips/include/asm/mach-malta/malta-dtshim.h index cfd777663c64..d696a7598ea7 100644 --- a/arch/mips/include/asm/mach-malta/malta-dtshim.h +++ b/arch/mips/include/asm/mach-malta/malta-dtshim.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2015 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/mach-malta/malta-pm.h b/arch/mips/include/asm/mach-malta/malta-pm.h index c2c2e201013d..347b53dbc88f 100644 --- a/arch/mips/include/asm/mach-malta/malta-pm.h +++ b/arch/mips/include/asm/mach-malta/malta-pm.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/mach-ralink/irq.h b/arch/mips/include/asm/mach-ralink/irq.h index 4321865e04b9..86473e3999aa 100644 --- a/arch/mips/include/asm/mach-ralink/irq.h +++ b/arch/mips/include/asm/mach-ralink/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_RALINK_IRQ_H #define __ASM_MACH_RALINK_IRQ_H diff --git a/arch/mips/include/asm/mach-rc32434/dma.h b/arch/mips/include/asm/mach-rc32434/dma.h index 4322191e46bf..44dc87bb8087 100644 --- a/arch/mips/include/asm/mach-rc32434/dma.h +++ b/arch/mips/include/asm/mach-rc32434/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2002 Integrated Device Technology, Inc. * All rights reserved. diff --git a/arch/mips/include/asm/mach-rc32434/dma_v.h b/arch/mips/include/asm/mach-rc32434/dma_v.h index 28c54063a345..37d73b9877c6 100644 --- a/arch/mips/include/asm/mach-rc32434/dma_v.h +++ b/arch/mips/include/asm/mach-rc32434/dma_v.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2002 Integrated Device Technology, Inc. * All rights reserved. diff --git a/arch/mips/include/asm/mach-rc32434/gpio.h b/arch/mips/include/asm/mach-rc32434/gpio.h index db211212ce79..a3192da9f227 100644 --- a/arch/mips/include/asm/mach-rc32434/gpio.h +++ b/arch/mips/include/asm/mach-rc32434/gpio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2002 Integrated Device Technology, Inc. * All rights reserved. diff --git a/arch/mips/include/asm/mach-rc32434/irq.h b/arch/mips/include/asm/mach-rc32434/irq.h index b76dec95c04e..ebe32bd5a5fb 100644 --- a/arch/mips/include/asm/mach-rc32434/irq.h +++ b/arch/mips/include/asm/mach-rc32434/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_RC32434_IRQ_H #define __ASM_RC32434_IRQ_H diff --git a/arch/mips/include/asm/mach-rc32434/rc32434.h b/arch/mips/include/asm/mach-rc32434/rc32434.h index 02fd32b4be16..1bec6cc8abf0 100644 --- a/arch/mips/include/asm/mach-rc32434/rc32434.h +++ b/arch/mips/include/asm/mach-rc32434/rc32434.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for IDT RC323434 CPU. */ diff --git a/arch/mips/include/asm/mach-tx39xx/mangle-port.h b/arch/mips/include/asm/mach-tx39xx/mangle-port.h index ef0b502fd8b7..ab7a70bd895e 100644 --- a/arch/mips/include/asm/mach-tx39xx/mangle-port.h +++ b/arch/mips/include/asm/mach-tx39xx/mangle-port.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_TX39XX_MANGLE_PORT_H #define __ASM_MACH_TX39XX_MANGLE_PORT_H diff --git a/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h index b9d39dc45420..04e4247255da 100644 --- a/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-tx49xx/cpu-feature-overrides.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_TX49XX_CPU_FEATURE_OVERRIDES_H #define __ASM_MACH_TX49XX_CPU_FEATURE_OVERRIDES_H diff --git a/arch/mips/include/asm/mach-tx49xx/kmalloc.h b/arch/mips/include/asm/mach-tx49xx/kmalloc.h index ff9a8b86cb93..c2a0a6fa483f 100644 --- a/arch/mips/include/asm/mach-tx49xx/kmalloc.h +++ b/arch/mips/include/asm/mach-tx49xx/kmalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_TX49XX_KMALLOC_H #define __ASM_MACH_TX49XX_KMALLOC_H diff --git a/arch/mips/include/asm/mach-tx49xx/mangle-port.h b/arch/mips/include/asm/mach-tx49xx/mangle-port.h index 490867b03c8f..e061ef38fb5f 100644 --- a/arch/mips/include/asm/mach-tx49xx/mangle-port.h +++ b/arch/mips/include/asm/mach-tx49xx/mangle-port.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_TX49XX_MANGLE_PORT_H #define __ASM_MACH_TX49XX_MANGLE_PORT_H diff --git a/arch/mips/include/asm/mach-vr41xx/irq.h b/arch/mips/include/asm/mach-vr41xx/irq.h index 862058d3f81b..3d63afae37a8 100644 --- a/arch/mips/include/asm/mach-vr41xx/irq.h +++ b/arch/mips/include/asm/mach-vr41xx/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MACH_VR41XX_IRQ_H #define __ASM_MACH_VR41XX_IRQ_H diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h index ecb6c7335484..e0d9b373d415 100644 --- a/arch/mips/include/asm/machine.h +++ b/arch/mips/include/asm/machine.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/mips-boards/launch.h b/arch/mips/include/asm/mips-boards/launch.h index 653477e4074d..f93aa5ee2e2e 100644 --- a/arch/mips/include/asm/mips-boards/launch.h +++ b/arch/mips/include/asm/mips-boards/launch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * */ diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index 987ff580466b..817698abf2eb 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h @@ -10,8 +10,6 @@ #ifndef _MIPS_MALTAINT_H #define _MIPS_MALTAINT_H -#include - /* * Interrupts 0..15 are used for Malta ISA compatible interrupts */ @@ -62,7 +60,4 @@ #define MSC01E_INT_PERFCTR 10 #define MSC01E_INT_CPUCTR 11 -/* GIC external interrupts */ -#define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3) - #endif /* !(_MIPS_MALTAINT_H) */ diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index cfdbab015769..8bc5df49b0e1 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -8,16 +8,18 @@ * option) any later version. */ +#ifndef __MIPS_ASM_MIPS_CPS_H__ +# error Please include asm/mips-cps.h rather than asm/mips-cm.h +#endif + #ifndef __MIPS_ASM_MIPS_CM_H__ #define __MIPS_ASM_MIPS_CM_H__ #include #include -#include -#include /* The base address of the CM GCR block */ -extern void __iomem *mips_cm_base; +extern void __iomem *mips_gcr_base; /* The base address of the CM L2-only sync region */ extern void __iomem *mips_cm_l2sync_base; @@ -80,7 +82,7 @@ static inline int mips_cm_probe(void) static inline bool mips_cm_present(void) { #ifdef CONFIG_MIPS_CM - return mips_cm_base != NULL; + return mips_gcr_base != NULL; #else return false; #endif @@ -112,321 +114,219 @@ static inline bool mips_cm_has_l2sync(void) /* Size of the L2-only sync region */ #define MIPS_CM_L2SYNC_SIZE 0x1000 -/* Macros to ease the creation of register access functions */ -#define BUILD_CM_R_(name, off) \ -static inline unsigned long __iomem *addr_gcr_##name(void) \ -{ \ - return (unsigned long __iomem *)(mips_cm_base + (off)); \ -} \ - \ -static inline u32 read32_gcr_##name(void) \ -{ \ - return __raw_readl(addr_gcr_##name()); \ -} \ - \ -static inline u64 read64_gcr_##name(void) \ -{ \ - void __iomem *addr = addr_gcr_##name(); \ - u64 ret; \ - \ - if (mips_cm_is64) { \ - ret = __raw_readq(addr); \ - } else { \ - ret = __raw_readl(addr); \ - ret |= (u64)__raw_readl(addr + 0x4) << 32; \ - } \ - \ - return ret; \ -} \ - \ -static inline unsigned long read_gcr_##name(void) \ -{ \ - if (mips_cm_is64) \ - return read64_gcr_##name(); \ - else \ - return read32_gcr_##name(); \ -} +#define GCR_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_GCB_OFS + off, name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name) -#define BUILD_CM__W(name, off) \ -static inline void write32_gcr_##name(u32 value) \ -{ \ - __raw_writel(value, addr_gcr_##name()); \ -} \ - \ -static inline void write64_gcr_##name(u64 value) \ -{ \ - __raw_writeq(value, addr_gcr_##name()); \ -} \ - \ -static inline void write_gcr_##name(unsigned long value) \ -{ \ - if (mips_cm_is64) \ - write64_gcr_##name(value); \ - else \ - write32_gcr_##name(value); \ -} +#define GCR_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_GCB_OFS + off, name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, redir_##name) -#define BUILD_CM_RW(name, off) \ - BUILD_CM_R_(name, off) \ - BUILD_CM__W(name, off) +#define GCR_CX_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RO(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name) -#define BUILD_CM_Cx_R_(name, off) \ - BUILD_CM_R_(cl_##name, MIPS_CM_CLCB_OFS + (off)) \ - BUILD_CM_R_(co_##name, MIPS_CM_COCB_OFS + (off)) +#define GCR_CX_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RW(gcr, sz, MIPS_CM_COCB_OFS + off, co_##name) -#define BUILD_CM_Cx__W(name, off) \ - BUILD_CM__W(cl_##name, MIPS_CM_CLCB_OFS + (off)) \ - BUILD_CM__W(co_##name, MIPS_CM_COCB_OFS + (off)) +/* GCR_CONFIG - Information about the system */ +GCR_ACCESSOR_RO(64, 0x000, config) +#define CM_GCR_CONFIG_CLUSTER_COH_CAPABLE BIT_ULL(43) +#define CM_GCR_CONFIG_CLUSTER_ID GENMASK_ULL(39, 32) +#define CM_GCR_CONFIG_NUM_CLUSTERS GENMASK(29, 23) +#define CM_GCR_CONFIG_NUMIOCU GENMASK(15, 8) +#define CM_GCR_CONFIG_PCORES GENMASK(7, 0) -#define BUILD_CM_Cx_RW(name, off) \ - BUILD_CM_Cx_R_(name, off) \ - BUILD_CM_Cx__W(name, off) - -/* GCB register accessor functions */ -BUILD_CM_R_(config, MIPS_CM_GCB_OFS + 0x00) -BUILD_CM_RW(base, MIPS_CM_GCB_OFS + 0x08) -BUILD_CM_RW(access, MIPS_CM_GCB_OFS + 0x20) -BUILD_CM_R_(rev, MIPS_CM_GCB_OFS + 0x30) -BUILD_CM_RW(err_control, MIPS_CM_GCB_OFS + 0x38) -BUILD_CM_RW(error_mask, MIPS_CM_GCB_OFS + 0x40) -BUILD_CM_RW(error_cause, MIPS_CM_GCB_OFS + 0x48) -BUILD_CM_RW(error_addr, MIPS_CM_GCB_OFS + 0x50) -BUILD_CM_RW(error_mult, MIPS_CM_GCB_OFS + 0x58) -BUILD_CM_RW(l2_only_sync_base, MIPS_CM_GCB_OFS + 0x70) -BUILD_CM_RW(gic_base, MIPS_CM_GCB_OFS + 0x80) -BUILD_CM_RW(cpc_base, MIPS_CM_GCB_OFS + 0x88) -BUILD_CM_RW(reg0_base, MIPS_CM_GCB_OFS + 0x90) -BUILD_CM_RW(reg0_mask, MIPS_CM_GCB_OFS + 0x98) -BUILD_CM_RW(reg1_base, MIPS_CM_GCB_OFS + 0xa0) -BUILD_CM_RW(reg1_mask, MIPS_CM_GCB_OFS + 0xa8) -BUILD_CM_RW(reg2_base, MIPS_CM_GCB_OFS + 0xb0) -BUILD_CM_RW(reg2_mask, MIPS_CM_GCB_OFS + 0xb8) -BUILD_CM_RW(reg3_base, MIPS_CM_GCB_OFS + 0xc0) -BUILD_CM_RW(reg3_mask, MIPS_CM_GCB_OFS + 0xc8) -BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0) -BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0) -BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130) -BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150) -BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300) -BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308) -BUILD_CM_RW(bev_base, MIPS_CM_GCB_OFS + 0x680) - -/* Core Local & Core Other register accessor functions */ -BUILD_CM_Cx_RW(reset_release, 0x00) -BUILD_CM_Cx_RW(coherence, 0x08) -BUILD_CM_Cx_R_(config, 0x10) -BUILD_CM_Cx_RW(other, 0x18) -BUILD_CM_Cx_RW(reset_base, 0x20) -BUILD_CM_Cx_R_(id, 0x28) -BUILD_CM_Cx_RW(reset_ext_base, 0x30) -BUILD_CM_Cx_R_(tcid_0_priority, 0x40) -BUILD_CM_Cx_R_(tcid_1_priority, 0x48) -BUILD_CM_Cx_R_(tcid_2_priority, 0x50) -BUILD_CM_Cx_R_(tcid_3_priority, 0x58) -BUILD_CM_Cx_R_(tcid_4_priority, 0x60) -BUILD_CM_Cx_R_(tcid_5_priority, 0x68) -BUILD_CM_Cx_R_(tcid_6_priority, 0x70) -BUILD_CM_Cx_R_(tcid_7_priority, 0x78) -BUILD_CM_Cx_R_(tcid_8_priority, 0x80) - -/* GCR_CONFIG register fields */ -#define CM_GCR_CONFIG_NUMIOCU_SHF 8 -#define CM_GCR_CONFIG_NUMIOCU_MSK (_ULCAST_(0xf) << 8) -#define CM_GCR_CONFIG_PCORES_SHF 0 -#define CM_GCR_CONFIG_PCORES_MSK (_ULCAST_(0xff) << 0) - -/* GCR_BASE register fields */ -#define CM_GCR_BASE_GCRBASE_SHF 15 -#define CM_GCR_BASE_GCRBASE_MSK (_ULCAST_(0x1ffff) << 15) -#define CM_GCR_BASE_CMDEFTGT_SHF 0 -#define CM_GCR_BASE_CMDEFTGT_MSK (_ULCAST_(0x3) << 0) -#define CM_GCR_BASE_CMDEFTGT_DISABLED 0 -#define CM_GCR_BASE_CMDEFTGT_MEM 1 +/* GCR_BASE - Base address of the Global Configuration Registers (GCRs) */ +GCR_ACCESSOR_RW(64, 0x008, base) +#define CM_GCR_BASE_GCRBASE GENMASK_ULL(47, 15) +#define CM_GCR_BASE_CMDEFTGT GENMASK(1, 0) +#define CM_GCR_BASE_CMDEFTGT_MEM 0 +#define CM_GCR_BASE_CMDEFTGT_RESERVED 1 #define CM_GCR_BASE_CMDEFTGT_IOCU0 2 #define CM_GCR_BASE_CMDEFTGT_IOCU1 3 -/* GCR_RESET_EXT_BASE register fields */ -#define CM_GCR_RESET_EXT_BASE_EVARESET BIT(31) -#define CM_GCR_RESET_EXT_BASE_UEB BIT(30) +/* GCR_ACCESS - Controls core/IOCU access to GCRs */ +GCR_ACCESSOR_RW(32, 0x020, access) +#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0) -/* GCR_ACCESS register fields */ -#define CM_GCR_ACCESS_ACCESSEN_SHF 0 -#define CM_GCR_ACCESS_ACCESSEN_MSK (_ULCAST_(0xff) << 0) - -/* GCR_REV register fields */ -#define CM_GCR_REV_MAJOR_SHF 8 -#define CM_GCR_REV_MAJOR_MSK (_ULCAST_(0xff) << 8) -#define CM_GCR_REV_MINOR_SHF 0 -#define CM_GCR_REV_MINOR_MSK (_ULCAST_(0xff) << 0) +/* GCR_REV - Indicates the Coherence Manager revision */ +GCR_ACCESSOR_RO(32, 0x030, rev) +#define CM_GCR_REV_MAJOR GENMASK(15, 8) +#define CM_GCR_REV_MINOR GENMASK(7, 0) #define CM_ENCODE_REV(major, minor) \ - (((major) << CM_GCR_REV_MAJOR_SHF) | \ - ((minor) << CM_GCR_REV_MINOR_SHF)) + (((major) << __ffs(CM_GCR_REV_MAJOR)) | \ + ((minor) << __ffs(CM_GCR_REV_MINOR))) #define CM_REV_CM2 CM_ENCODE_REV(6, 0) #define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) #define CM_REV_CM3 CM_ENCODE_REV(8, 0) +#define CM_REV_CM3_5 CM_ENCODE_REV(9, 0) -/* GCR_ERR_CONTROL register fields */ -#define CM_GCR_ERR_CONTROL_L2_ECC_EN_SHF 1 -#define CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK (_ULCAST_(0x1) << 1) -#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_SHF 0 -#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK (_ULCAST_(0x1) << 0) +/* GCR_ERR_CONTROL - Control error checking logic */ +GCR_ACCESSOR_RW(32, 0x038, err_control) +#define CM_GCR_ERR_CONTROL_L2_ECC_EN BIT(1) +#define CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT BIT(0) -/* GCR_ERROR_CAUSE register fields */ -#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27 -#define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27) -#define CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF 58 -#define CM3_GCR_ERROR_CAUSE_ERRTYPE_MSK GENMASK_ULL(63, 58) -#define CM_GCR_ERROR_CAUSE_ERRINFO_SHF 0 -#define CM_GCR_ERROR_CAUSE_ERRINGO_MSK (_ULCAST_(0x7ffffff) << 0) +/* GCR_ERR_MASK - Control which errors are reported as interrupts */ +GCR_ACCESSOR_RW(64, 0x040, error_mask) -/* GCR_ERROR_MULT register fields */ -#define CM_GCR_ERROR_MULT_ERR2ND_SHF 0 -#define CM_GCR_ERROR_MULT_ERR2ND_MSK (_ULCAST_(0x1f) << 0) +/* GCR_ERR_CAUSE - Indicates the type of error that occurred */ +GCR_ACCESSOR_RW(64, 0x048, error_cause) +#define CM_GCR_ERROR_CAUSE_ERRTYPE GENMASK(31, 27) +#define CM3_GCR_ERROR_CAUSE_ERRTYPE GENMASK_ULL(63, 58) +#define CM_GCR_ERROR_CAUSE_ERRINFO GENMASK(26, 0) -/* GCR_L2_ONLY_SYNC_BASE register fields */ -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_SHF 12 -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK (_ULCAST_(0xfffff) << 12) -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_SHF 0 -#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK (_ULCAST_(0x1) << 0) +/* GCR_ERR_ADDR - Indicates the address associated with an error */ +GCR_ACCESSOR_RW(64, 0x050, error_addr) -/* GCR_GIC_BASE register fields */ -#define CM_GCR_GIC_BASE_GICBASE_SHF 17 -#define CM_GCR_GIC_BASE_GICBASE_MSK (_ULCAST_(0x7fff) << 17) -#define CM_GCR_GIC_BASE_GICEN_SHF 0 -#define CM_GCR_GIC_BASE_GICEN_MSK (_ULCAST_(0x1) << 0) +/* GCR_ERR_MULT - Indicates when multiple errors have occurred */ +GCR_ACCESSOR_RW(64, 0x058, error_mult) +#define CM_GCR_ERROR_MULT_ERR2ND GENMASK(4, 0) -/* GCR_CPC_BASE register fields */ -#define CM_GCR_CPC_BASE_CPCBASE_SHF 15 -#define CM_GCR_CPC_BASE_CPCBASE_MSK (_ULCAST_(0x1ffff) << 15) -#define CM_GCR_CPC_BASE_CPCEN_SHF 0 -#define CM_GCR_CPC_BASE_CPCEN_MSK (_ULCAST_(0x1) << 0) +/* GCR_L2_ONLY_SYNC_BASE - Base address of the L2 cache-only sync region */ +GCR_ACCESSOR_RW(64, 0x070, l2_only_sync_base) +#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE GENMASK(31, 12) +#define CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN BIT(0) -/* GCR_GIC_STATUS register fields */ -#define CM_GCR_GIC_STATUS_GICEX_SHF 0 -#define CM_GCR_GIC_STATUS_GICEX_MSK (_ULCAST_(0x1) << 0) +/* GCR_GIC_BASE - Base address of the Global Interrupt Controller (GIC) */ +GCR_ACCESSOR_RW(64, 0x080, gic_base) +#define CM_GCR_GIC_BASE_GICBASE GENMASK(31, 17) +#define CM_GCR_GIC_BASE_GICEN BIT(0) -/* GCR_REGn_BASE register fields */ -#define CM_GCR_REGn_BASE_BASEADDR_SHF 16 -#define CM_GCR_REGn_BASE_BASEADDR_MSK (_ULCAST_(0xffff) << 16) +/* GCR_CPC_BASE - Base address of the Cluster Power Controller (CPC) */ +GCR_ACCESSOR_RW(64, 0x088, cpc_base) +#define CM_GCR_CPC_BASE_CPCBASE GENMASK(31, 15) +#define CM_GCR_CPC_BASE_CPCEN BIT(0) -/* GCR_REGn_MASK register fields */ -#define CM_GCR_REGn_MASK_ADDRMASK_SHF 16 -#define CM_GCR_REGn_MASK_ADDRMASK_MSK (_ULCAST_(0xffff) << 16) -#define CM_GCR_REGn_MASK_CCAOVR_SHF 5 -#define CM_GCR_REGn_MASK_CCAOVR_MSK (_ULCAST_(0x3) << 5) -#define CM_GCR_REGn_MASK_CCAOVREN_SHF 4 -#define CM_GCR_REGn_MASK_CCAOVREN_MSK (_ULCAST_(0x1) << 4) -#define CM_GCR_REGn_MASK_DROPL2_SHF 2 -#define CM_GCR_REGn_MASK_DROPL2_MSK (_ULCAST_(0x1) << 2) -#define CM_GCR_REGn_MASK_CMTGT_SHF 0 -#define CM_GCR_REGn_MASK_CMTGT_MSK (_ULCAST_(0x3) << 0) -#define CM_GCR_REGn_MASK_CMTGT_DISABLED (_ULCAST_(0x0) << 0) -#define CM_GCR_REGn_MASK_CMTGT_MEM (_ULCAST_(0x1) << 0) -#define CM_GCR_REGn_MASK_CMTGT_IOCU0 (_ULCAST_(0x2) << 0) -#define CM_GCR_REGn_MASK_CMTGT_IOCU1 (_ULCAST_(0x3) << 0) +/* GCR_REGn_BASE - Base addresses of CM address regions */ +GCR_ACCESSOR_RW(64, 0x090, reg0_base) +GCR_ACCESSOR_RW(64, 0x0a0, reg1_base) +GCR_ACCESSOR_RW(64, 0x0b0, reg2_base) +GCR_ACCESSOR_RW(64, 0x0c0, reg3_base) +#define CM_GCR_REGn_BASE_BASEADDR GENMASK(31, 16) -/* GCR_GIC_STATUS register fields */ -#define CM_GCR_GIC_STATUS_EX_SHF 0 -#define CM_GCR_GIC_STATUS_EX_MSK (_ULCAST_(0x1) << 0) +/* GCR_REGn_MASK - Size & destination of CM address regions */ +GCR_ACCESSOR_RW(64, 0x098, reg0_mask) +GCR_ACCESSOR_RW(64, 0x0a8, reg1_mask) +GCR_ACCESSOR_RW(64, 0x0b8, reg2_mask) +GCR_ACCESSOR_RW(64, 0x0c8, reg3_mask) +#define CM_GCR_REGn_MASK_ADDRMASK GENMASK(31, 16) +#define CM_GCR_REGn_MASK_CCAOVR GENMASK(7, 5) +#define CM_GCR_REGn_MASK_CCAOVREN BIT(4) +#define CM_GCR_REGn_MASK_DROPL2 BIT(2) +#define CM_GCR_REGn_MASK_CMTGT GENMASK(1, 0) +#define CM_GCR_REGn_MASK_CMTGT_DISABLED 0x0 +#define CM_GCR_REGn_MASK_CMTGT_MEM 0x1 +#define CM_GCR_REGn_MASK_CMTGT_IOCU0 0x2 +#define CM_GCR_REGn_MASK_CMTGT_IOCU1 0x3 -/* GCR_CPC_STATUS register fields */ -#define CM_GCR_CPC_STATUS_EX_SHF 0 -#define CM_GCR_CPC_STATUS_EX_MSK (_ULCAST_(0x1) << 0) +/* GCR_GIC_STATUS - Indicates presence of a Global Interrupt Controller (GIC) */ +GCR_ACCESSOR_RO(32, 0x0d0, gic_status) +#define CM_GCR_GIC_STATUS_EX BIT(0) -/* GCR_L2_CONFIG register fields */ -#define CM_GCR_L2_CONFIG_BYPASS_SHF 20 -#define CM_GCR_L2_CONFIG_BYPASS_MSK (_ULCAST_(0x1) << 20) -#define CM_GCR_L2_CONFIG_SET_SIZE_SHF 12 -#define CM_GCR_L2_CONFIG_SET_SIZE_MSK (_ULCAST_(0xf) << 12) -#define CM_GCR_L2_CONFIG_LINE_SIZE_SHF 8 -#define CM_GCR_L2_CONFIG_LINE_SIZE_MSK (_ULCAST_(0xf) << 8) -#define CM_GCR_L2_CONFIG_ASSOC_SHF 0 -#define CM_GCR_L2_CONFIG_ASSOC_MSK (_ULCAST_(0xff) << 0) +/* GCR_CPC_STATUS - Indicates presence of a Cluster Power Controller (CPC) */ +GCR_ACCESSOR_RO(32, 0x0f0, cpc_status) +#define CM_GCR_CPC_STATUS_EX BIT(0) -/* GCR_SYS_CONFIG2 register fields */ -#define CM_GCR_SYS_CONFIG2_MAXVPW_SHF 0 -#define CM_GCR_SYS_CONFIG2_MAXVPW_MSK (_ULCAST_(0xf) << 0) +/* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */ +GCR_ACCESSOR_RW(32, 0x130, l2_config) +#define CM_GCR_L2_CONFIG_BYPASS BIT(20) +#define CM_GCR_L2_CONFIG_SET_SIZE GENMASK(15, 12) +#define CM_GCR_L2_CONFIG_LINE_SIZE GENMASK(11, 8) +#define CM_GCR_L2_CONFIG_ASSOC GENMASK(7, 0) -/* GCR_L2_PFT_CONTROL register fields */ -#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF 12 -#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK (_ULCAST_(0xfffff) << 12) -#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF 8 -#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK (_ULCAST_(0x1) << 8) -#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF 0 -#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK (_ULCAST_(0xff) << 0) +/* GCR_SYS_CONFIG2 - Further information about the system */ +GCR_ACCESSOR_RO(32, 0x150, sys_config2) +#define CM_GCR_SYS_CONFIG2_MAXVPW GENMASK(3, 0) -/* GCR_L2_PFT_CONTROL_B register fields */ -#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF 8 -#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK (_ULCAST_(0x1) << 8) -#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF 0 -#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK (_ULCAST_(0xff) << 0) +/* GCR_L2_PFT_CONTROL - Controls hardware L2 prefetching */ +GCR_ACCESSOR_RW(32, 0x300, l2_pft_control) +#define CM_GCR_L2_PFT_CONTROL_PAGEMASK GENMASK(31, 12) +#define CM_GCR_L2_PFT_CONTROL_PFTEN BIT(8) +#define CM_GCR_L2_PFT_CONTROL_NPFT GENMASK(7, 0) -/* GCR_Cx_COHERENCE register fields */ -#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0 -#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0) -#define CM3_GCR_Cx_COHERENCE_COHEN_MSK (_ULCAST_(0x1) << 0) +/* GCR_L2_PFT_CONTROL_B - Controls hardware L2 prefetching */ +GCR_ACCESSOR_RW(32, 0x308, l2_pft_control_b) +#define CM_GCR_L2_PFT_CONTROL_B_CEN BIT(8) +#define CM_GCR_L2_PFT_CONTROL_B_PORTID GENMASK(7, 0) -/* GCR_Cx_CONFIG register fields */ -#define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10 -#define CM_GCR_Cx_CONFIG_IOCUTYPE_MSK (_ULCAST_(0x3) << 10) -#define CM_GCR_Cx_CONFIG_PVPE_SHF 0 -#define CM_GCR_Cx_CONFIG_PVPE_MSK (_ULCAST_(0x3ff) << 0) +/* GCR_L2SM_COP - L2 cache op state machine control */ +GCR_ACCESSOR_RW(32, 0x620, l2sm_cop) +#define CM_GCR_L2SM_COP_PRESENT BIT(31) +#define CM_GCR_L2SM_COP_RESULT GENMASK(8, 6) +#define CM_GCR_L2SM_COP_RESULT_DONTCARE 0 +#define CM_GCR_L2SM_COP_RESULT_DONE_OK 1 +#define CM_GCR_L2SM_COP_RESULT_DONE_ERROR 2 +#define CM_GCR_L2SM_COP_RESULT_ABORT_OK 3 +#define CM_GCR_L2SM_COP_RESULT_ABORT_ERROR 4 +#define CM_GCR_L2SM_COP_RUNNING BIT(5) +#define CM_GCR_L2SM_COP_TYPE GENMASK(4, 2) +#define CM_GCR_L2SM_COP_TYPE_IDX_WBINV 0 +#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAG 1 +#define CM_GCR_L2SM_COP_TYPE_IDX_STORETAGDATA 2 +#define CM_GCR_L2SM_COP_TYPE_HIT_INV 4 +#define CM_GCR_L2SM_COP_TYPE_HIT_WBINV 5 +#define CM_GCR_L2SM_COP_TYPE_HIT_WB 6 +#define CM_GCR_L2SM_COP_TYPE_FETCHLOCK 7 +#define CM_GCR_L2SM_COP_CMD GENMASK(1, 0) +#define CM_GCR_L2SM_COP_CMD_START 1 /* only when idle */ +#define CM_GCR_L2SM_COP_CMD_ABORT 3 /* only when running */ -/* GCR_Cx_OTHER register fields */ -#define CM_GCR_Cx_OTHER_CORENUM_SHF 16 -#define CM_GCR_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xffff) << 16) -#define CM3_GCR_Cx_OTHER_CORE_SHF 8 -#define CM3_GCR_Cx_OTHER_CORE_MSK (_ULCAST_(0x3f) << 8) -#define CM3_GCR_Cx_OTHER_VP_SHF 0 -#define CM3_GCR_Cx_OTHER_VP_MSK (_ULCAST_(0x7) << 0) +/* GCR_L2SM_TAG_ADDR_COP - L2 cache op state machine address control */ +GCR_ACCESSOR_RW(64, 0x628, l2sm_tag_addr_cop) +#define CM_GCR_L2SM_TAG_ADDR_COP_NUM_LINES GENMASK_ULL(63, 48) +#define CM_GCR_L2SM_TAG_ADDR_COP_START_TAG GENMASK_ULL(47, 6) -/* GCR_Cx_RESET_BASE register fields */ -#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_SHF 12 -#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE_MSK (_ULCAST_(0xfffff) << 12) +/* GCR_BEV_BASE - Controls the location of the BEV for powered up cores */ +GCR_ACCESSOR_RW(64, 0x680, bev_base) -/* GCR_Cx_RESET_EXT_BASE register fields */ -#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_SHF 31 -#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET_MSK (_ULCAST_(0x1) << 31) -#define CM_GCR_Cx_RESET_EXT_BASE_UEB_SHF 30 -#define CM_GCR_Cx_RESET_EXT_BASE_UEB_MSK (_ULCAST_(0x1) << 30) -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_SHF 20 -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK_MSK (_ULCAST_(0xff) << 20) -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_SHF 1 -#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA_MSK (_ULCAST_(0x7f) << 1) -#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_SHF 0 -#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT_MSK (_ULCAST_(0x1) << 0) +/* GCR_Cx_RESET_RELEASE - Controls core reset for CM 1.x */ +GCR_CX_ACCESSOR_RW(32, 0x000, reset_release) -/** - * mips_cm_numcores - return the number of cores present in the system - * - * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or - * zero if no Coherence Manager is present. - */ -static inline unsigned mips_cm_numcores(void) -{ - if (!mips_cm_present()) - return 0; +/* GCR_Cx_COHERENCE - Controls core coherence */ +GCR_CX_ACCESSOR_RW(32, 0x008, coherence) +#define CM_GCR_Cx_COHERENCE_COHDOMAINEN GENMASK(7, 0) +#define CM3_GCR_Cx_COHERENCE_COHEN BIT(0) - return ((read_gcr_config() & CM_GCR_CONFIG_PCORES_MSK) - >> CM_GCR_CONFIG_PCORES_SHF) + 1; -} +/* GCR_Cx_CONFIG - Information about a core's configuration */ +GCR_CX_ACCESSOR_RO(32, 0x010, config) +#define CM_GCR_Cx_CONFIG_IOCUTYPE GENMASK(11, 10) +#define CM_GCR_Cx_CONFIG_PVPE GENMASK(9, 0) -/** - * mips_cm_numiocu - return the number of IOCUs present in the system - * - * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero - * if no Coherence Manager is present. - */ -static inline unsigned mips_cm_numiocu(void) -{ - if (!mips_cm_present()) - return 0; +/* GCR_Cx_OTHER - Configure the core-other/redirect GCR block */ +GCR_CX_ACCESSOR_RW(32, 0x018, other) +#define CM_GCR_Cx_OTHER_CORENUM GENMASK(31, 16) /* CM < 3 */ +#define CM_GCR_Cx_OTHER_CLUSTER_EN BIT(31) /* CM >= 3.5 */ +#define CM_GCR_Cx_OTHER_GIC_EN BIT(30) /* CM >= 3.5 */ +#define CM_GCR_Cx_OTHER_BLOCK GENMASK(25, 24) /* CM >= 3.5 */ +#define CM_GCR_Cx_OTHER_BLOCK_LOCAL 0 +#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL 1 +#define CM_GCR_Cx_OTHER_BLOCK_USER 2 +#define CM_GCR_Cx_OTHER_BLOCK_GLOBAL_HIGH 3 +#define CM_GCR_Cx_OTHER_CLUSTER GENMASK(21, 16) /* CM >= 3.5 */ +#define CM3_GCR_Cx_OTHER_CORE GENMASK(13, 8) /* CM >= 3 */ +#define CM_GCR_Cx_OTHER_CORE_CM 32 +#define CM3_GCR_Cx_OTHER_VP GENMASK(2, 0) /* CM >= 3 */ - return (read_gcr_config() & CM_GCR_CONFIG_NUMIOCU_MSK) - >> CM_GCR_CONFIG_NUMIOCU_SHF; -} +/* GCR_Cx_RESET_BASE - Configure where powered up cores will fetch from */ +GCR_CX_ACCESSOR_RW(32, 0x020, reset_base) +#define CM_GCR_Cx_RESET_BASE_BEVEXCBASE GENMASK(31, 12) + +/* GCR_Cx_ID - Identify the current core */ +GCR_CX_ACCESSOR_RO(32, 0x028, id) +#define CM_GCR_Cx_ID_CLUSTER GENMASK(15, 8) +#define CM_GCR_Cx_ID_CORE GENMASK(7, 0) + +/* GCR_Cx_RESET_EXT_BASE - Configure behaviour when cores reset or power up */ +GCR_CX_ACCESSOR_RW(32, 0x030, reset_ext_base) +#define CM_GCR_Cx_RESET_EXT_BASE_EVARESET BIT(31) +#define CM_GCR_Cx_RESET_EXT_BASE_UEB BIT(30) +#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCMASK GENMASK(27, 20) +#define CM_GCR_Cx_RESET_EXT_BASE_BEVEXCPA GENMASK(7, 1) +#define CM_GCR_Cx_RESET_EXT_BASE_PRESENT BIT(0) /** * mips_cm_l2sync - perform an L2-only sync operation @@ -469,7 +369,7 @@ static inline unsigned int mips_cm_max_vp_width(void) uint32_t cfg; if (mips_cm_revision() >= CM_REV_CM3) - return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK; + return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW; if (mips_cm_present()) { /* @@ -477,8 +377,8 @@ static inline unsigned int mips_cm_max_vp_width(void) * number of VP(E)s, and if that ever changes then this will * need revisiting. */ - cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE_MSK; - return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1; + cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE; + return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1; } if (IS_ENABLED(CONFIG_SMP)) @@ -499,7 +399,7 @@ static inline unsigned int mips_cm_max_vp_width(void) */ static inline unsigned int mips_cm_vp_id(unsigned int cpu) { - unsigned int core = cpu_data[cpu].core; + unsigned int core = cpu_core(&cpu_data[cpu]); unsigned int vp = cpu_vpe_id(&cpu_data[cpu]); return (core * mips_cm_max_vp_width()) + vp; @@ -508,29 +408,56 @@ static inline unsigned int mips_cm_vp_id(unsigned int cpu) #ifdef CONFIG_MIPS_CM /** - * mips_cm_lock_other - lock access to another core + * mips_cm_lock_other - lock access to redirect/other region + * @cluster: the other cluster to be accessed * @core: the other core to be accessed * @vp: the VP within the other core to be accessed + * @block: the register block to be accessed * - * Call before operating upon a core via the 'other' register region in - * order to prevent the region being moved during access. Must be followed - * by a call to mips_cm_unlock_other. + * Configure the redirect/other region for the local core/VP (depending upon + * the CM revision) to target the specified @cluster, @core, @vp & register + * @block. Must be called before using the redirect/other region, and followed + * by a call to mips_cm_unlock_other() when access to the redirect/other region + * is complete. + * + * This function acquires a spinlock such that code between it & + * mips_cm_unlock_other() calls cannot be pre-empted by anything which may + * reconfigure the redirect/other region, and cannot be interfered with by + * another VP in the core. As such calls to this function should not be nested. */ -extern void mips_cm_lock_other(unsigned int core, unsigned int vp); +extern void mips_cm_lock_other(unsigned int cluster, unsigned int core, + unsigned int vp, unsigned int block); /** - * mips_cm_unlock_other - unlock access to another core + * mips_cm_unlock_other - unlock access to redirect/other region * - * Call after operating upon another core via the 'other' register region. - * Must be called after mips_cm_lock_other. + * Must be called after mips_cm_lock_other() once all required access to the + * redirect/other region has been completed. */ extern void mips_cm_unlock_other(void); #else /* !CONFIG_MIPS_CM */ -static inline void mips_cm_lock_other(unsigned int core, unsigned int vp) { } +static inline void mips_cm_lock_other(unsigned int cluster, unsigned int core, + unsigned int vp, unsigned int block) { } static inline void mips_cm_unlock_other(void) { } #endif /* !CONFIG_MIPS_CM */ +/** + * mips_cm_lock_other_cpu - lock access to redirect/other region + * @cpu: the other CPU whose register we want to access + * + * Configure the redirect/other region for the local core/VP (depending upon + * the CM revision) to target the specified @cpu & register @block. This is + * equivalent to calling mips_cm_lock_other() but accepts a Linux CPU number + * for convenience. + */ +static inline void mips_cm_lock_other_cpu(unsigned int cpu, unsigned int block) +{ + struct cpuinfo_mips *d = &cpu_data[cpu]; + + mips_cm_lock_other(cpu_cluster(d), cpu_core(d), cpu_vpe_id(d), block); +} + #endif /* __MIPS_ASM_MIPS_CM_H__ */ diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index 8c519f9827a3..b55e335cfba4 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -8,11 +8,15 @@ * option) any later version. */ +#ifndef __MIPS_ASM_MIPS_CPS_H__ +# error Please include asm/mips-cps.h rather than asm/mips-cpc.h +#endif + #ifndef __MIPS_ASM_MIPS_CPC_H__ #define __MIPS_ASM_MIPS_CPC_H__ -#include -#include +#include +#include /* The base address of the CPC registers */ extern void __iomem *mips_cpc_base; @@ -61,89 +65,92 @@ static inline bool mips_cpc_present(void) #define MIPS_CPC_CLCB_OFS 0x2000 #define MIPS_CPC_COCB_OFS 0x4000 -/* Macros to ease the creation of register access functions */ -#define BUILD_CPC_R_(name, off) \ -static inline u32 *addr_cpc_##name(void) \ -{ \ - return (u32 *)(mips_cpc_base + (off)); \ -} \ - \ -static inline u32 read_cpc_##name(void) \ -{ \ - return __raw_readl(mips_cpc_base + (off)); \ -} +#define CPC_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_GCB_OFS + off, name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name) -#define BUILD_CPC__W(name, off) \ -static inline void write_cpc_##name(u32 value) \ -{ \ - __raw_writel(value, mips_cpc_base + (off)); \ -} +#define CPC_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_GCB_OFS + off, name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, redir_##name) -#define BUILD_CPC_RW(name, off) \ - BUILD_CPC_R_(name, off) \ - BUILD_CPC__W(name, off) +#define CPC_CX_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RO(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name) -#define BUILD_CPC_Cx_R_(name, off) \ - BUILD_CPC_R_(cl_##name, MIPS_CPC_CLCB_OFS + (off)) \ - BUILD_CPC_R_(co_##name, MIPS_CPC_COCB_OFS + (off)) +#define CPC_CX_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_CLCB_OFS + off, cl_##name) \ + CPS_ACCESSOR_RW(cpc, sz, MIPS_CPC_COCB_OFS + off, co_##name) -#define BUILD_CPC_Cx__W(name, off) \ - BUILD_CPC__W(cl_##name, MIPS_CPC_CLCB_OFS + (off)) \ - BUILD_CPC__W(co_##name, MIPS_CPC_COCB_OFS + (off)) +/* CPC_ACCESS - Control core/IOCU access to CPC registers prior to CM 3 */ +CPC_ACCESSOR_RW(32, 0x000, access) -#define BUILD_CPC_Cx_RW(name, off) \ - BUILD_CPC_Cx_R_(name, off) \ - BUILD_CPC_Cx__W(name, off) +/* CPC_SEQDEL - Configure delays between command sequencer steps */ +CPC_ACCESSOR_RW(32, 0x008, seqdel) -/* GCB register accessor functions */ -BUILD_CPC_RW(access, MIPS_CPC_GCB_OFS + 0x00) -BUILD_CPC_RW(seqdel, MIPS_CPC_GCB_OFS + 0x08) -BUILD_CPC_RW(rail, MIPS_CPC_GCB_OFS + 0x10) -BUILD_CPC_RW(resetlen, MIPS_CPC_GCB_OFS + 0x18) -BUILD_CPC_R_(revision, MIPS_CPC_GCB_OFS + 0x20) +/* CPC_RAIL - Configure the delay from rail power-up to stability */ +CPC_ACCESSOR_RW(32, 0x010, rail) -/* Core Local & Core Other accessor functions */ -BUILD_CPC_Cx_RW(cmd, 0x00) -BUILD_CPC_Cx_RW(stat_conf, 0x08) -BUILD_CPC_Cx_RW(other, 0x10) -BUILD_CPC_Cx_RW(vp_stop, 0x20) -BUILD_CPC_Cx_RW(vp_run, 0x28) -BUILD_CPC_Cx_RW(vp_running, 0x30) +/* CPC_RESETLEN - Configure the length of reset sequences */ +CPC_ACCESSOR_RW(32, 0x018, resetlen) -/* CPC_Cx_CMD register fields */ -#define CPC_Cx_CMD_SHF 0 -#define CPC_Cx_CMD_MSK (_ULCAST_(0xf) << 0) -#define CPC_Cx_CMD_CLOCKOFF (_ULCAST_(0x1) << 0) -#define CPC_Cx_CMD_PWRDOWN (_ULCAST_(0x2) << 0) -#define CPC_Cx_CMD_PWRUP (_ULCAST_(0x3) << 0) -#define CPC_Cx_CMD_RESET (_ULCAST_(0x4) << 0) +/* CPC_REVISION - Indicates the revisison of the CPC */ +CPC_ACCESSOR_RO(32, 0x020, revision) -/* CPC_Cx_STAT_CONF register fields */ -#define CPC_Cx_STAT_CONF_PWRUPE_SHF 23 -#define CPC_Cx_STAT_CONF_PWRUPE_MSK (_ULCAST_(0x1) << 23) -#define CPC_Cx_STAT_CONF_SEQSTATE_SHF 19 -#define CPC_Cx_STAT_CONF_SEQSTATE_MSK (_ULCAST_(0xf) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D0 (_ULCAST_(0x0) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U0 (_ULCAST_(0x1) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U1 (_ULCAST_(0x2) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U2 (_ULCAST_(0x3) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U3 (_ULCAST_(0x4) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U4 (_ULCAST_(0x5) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U5 (_ULCAST_(0x6) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_U6 (_ULCAST_(0x7) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D1 (_ULCAST_(0x8) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D3 (_ULCAST_(0x9) << 19) -#define CPC_Cx_STAT_CONF_SEQSTATE_D2 (_ULCAST_(0xa) << 19) -#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_SHF 17 -#define CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK (_ULCAST_(0x1) << 17) -#define CPC_Cx_STAT_CONF_PWRDN_IMPL_SHF 16 -#define CPC_Cx_STAT_CONF_PWRDN_IMPL_MSK (_ULCAST_(0x1) << 16) -#define CPC_Cx_STAT_CONF_EJTAG_PROBE_SHF 15 -#define CPC_Cx_STAT_CONF_EJTAG_PROBE_MSK (_ULCAST_(0x1) << 15) +/* CPC_PWRUP_CTL - Control power to the Coherence Manager (CM) */ +CPC_ACCESSOR_RW(32, 0x030, pwrup_ctl) +#define CPC_PWRUP_CTL_CM_PWRUP BIT(0) -/* CPC_Cx_OTHER register fields */ -#define CPC_Cx_OTHER_CORENUM_SHF 16 -#define CPC_Cx_OTHER_CORENUM_MSK (_ULCAST_(0xff) << 16) +/* CPC_CONFIG - Mirrors GCR_CONFIG */ +CPC_ACCESSOR_RW(64, 0x138, config) + +/* CPC_SYS_CONFIG - Control cluster endianness */ +CPC_ACCESSOR_RW(32, 0x140, sys_config) +#define CPC_SYS_CONFIG_BE_IMMEDIATE BIT(2) +#define CPC_SYS_CONFIG_BE_STATUS BIT(1) +#define CPC_SYS_CONFIG_BE BIT(0) + +/* CPC_Cx_CMD - Instruct the CPC to take action on a core */ +CPC_CX_ACCESSOR_RW(32, 0x000, cmd) +#define CPC_Cx_CMD GENMASK(3, 0) +#define CPC_Cx_CMD_CLOCKOFF 0x1 +#define CPC_Cx_CMD_PWRDOWN 0x2 +#define CPC_Cx_CMD_PWRUP 0x3 +#define CPC_Cx_CMD_RESET 0x4 + +/* CPC_Cx_STAT_CONF - Indicates core configuration & state */ +CPC_CX_ACCESSOR_RW(32, 0x008, stat_conf) +#define CPC_Cx_STAT_CONF_PWRUPE BIT(23) +#define CPC_Cx_STAT_CONF_SEQSTATE GENMASK(22, 19) +#define CPC_Cx_STAT_CONF_SEQSTATE_D0 0x0 +#define CPC_Cx_STAT_CONF_SEQSTATE_U0 0x1 +#define CPC_Cx_STAT_CONF_SEQSTATE_U1 0x2 +#define CPC_Cx_STAT_CONF_SEQSTATE_U2 0x3 +#define CPC_Cx_STAT_CONF_SEQSTATE_U3 0x4 +#define CPC_Cx_STAT_CONF_SEQSTATE_U4 0x5 +#define CPC_Cx_STAT_CONF_SEQSTATE_U5 0x6 +#define CPC_Cx_STAT_CONF_SEQSTATE_U6 0x7 +#define CPC_Cx_STAT_CONF_SEQSTATE_D1 0x8 +#define CPC_Cx_STAT_CONF_SEQSTATE_D3 0x9 +#define CPC_Cx_STAT_CONF_SEQSTATE_D2 0xa +#define CPC_Cx_STAT_CONF_CLKGAT_IMPL BIT(17) +#define CPC_Cx_STAT_CONF_PWRDN_IMPL BIT(16) +#define CPC_Cx_STAT_CONF_EJTAG_PROBE BIT(15) + +/* CPC_Cx_OTHER - Configure the core-other register block prior to CM 3 */ +CPC_CX_ACCESSOR_RW(32, 0x010, other) +#define CPC_Cx_OTHER_CORENUM GENMASK(23, 16) + +/* CPC_Cx_VP_STOP - Stop Virtual Processors (VPs) within a core from running */ +CPC_CX_ACCESSOR_RW(32, 0x020, vp_stop) + +/* CPC_Cx_VP_START - Start Virtual Processors (VPs) within a core running */ +CPC_CX_ACCESSOR_RW(32, 0x028, vp_run) + +/* CPC_Cx_VP_RUNNING - Indicate which Virtual Processors (VPs) are running */ +CPC_CX_ACCESSOR_RW(32, 0x030, vp_running) + +/* CPC_Cx_CONFIG - Mirrors GCR_Cx_CONFIG */ +CPC_CX_ACCESSOR_RW(32, 0x090, config) #ifdef CONFIG_MIPS_CPC diff --git a/arch/mips/include/asm/mips-cps.h b/arch/mips/include/asm/mips-cps.h new file mode 100644 index 000000000000..8ad4a85eed0c --- /dev/null +++ b/arch/mips/include/asm/mips-cps.h @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2017 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MIPS_ASM_MIPS_CPS_H__ +#define __MIPS_ASM_MIPS_CPS_H__ + +#include +#include + +extern unsigned long __cps_access_bad_size(void) + __compiletime_error("Bad size for CPS accessor"); + +#define CPS_ACCESSOR_A(unit, off, name) \ +static inline void *addr_##unit##_##name(void) \ +{ \ + return mips_##unit##_base + (off); \ +} + +#define CPS_ACCESSOR_R(unit, sz, name) \ +static inline uint##sz##_t read_##unit##_##name(void) \ +{ \ + uint64_t val64; \ + \ + switch (sz) { \ + case 32: \ + return __raw_readl(addr_##unit##_##name()); \ + \ + case 64: \ + if (mips_cm_is64) \ + return __raw_readq(addr_##unit##_##name()); \ + \ + val64 = __raw_readl(addr_##unit##_##name() + 4); \ + val64 <<= 32; \ + val64 |= __raw_readl(addr_##unit##_##name()); \ + return val64; \ + \ + default: \ + return __cps_access_bad_size(); \ + } \ +} + +#define CPS_ACCESSOR_W(unit, sz, name) \ +static inline void write_##unit##_##name(uint##sz##_t val) \ +{ \ + switch (sz) { \ + case 32: \ + __raw_writel(val, addr_##unit##_##name()); \ + break; \ + \ + case 64: \ + if (mips_cm_is64) { \ + __raw_writeq(val, addr_##unit##_##name()); \ + break; \ + } \ + \ + __raw_writel((uint64_t)val >> 32, \ + addr_##unit##_##name() + 4); \ + __raw_writel(val, addr_##unit##_##name()); \ + break; \ + \ + default: \ + __cps_access_bad_size(); \ + break; \ + } \ +} + +#define CPS_ACCESSOR_M(unit, sz, name) \ +static inline void change_##unit##_##name(uint##sz##_t mask, \ + uint##sz##_t val) \ +{ \ + uint##sz##_t reg_val = read_##unit##_##name(); \ + reg_val &= ~mask; \ + reg_val |= val; \ + write_##unit##_##name(reg_val); \ +} \ + \ +static inline void set_##unit##_##name(uint##sz##_t val) \ +{ \ + change_##unit##_##name(val, val); \ +} \ + \ +static inline void clear_##unit##_##name(uint##sz##_t val) \ +{ \ + change_##unit##_##name(val, 0); \ +} + +#define CPS_ACCESSOR_RO(unit, sz, off, name) \ + CPS_ACCESSOR_A(unit, off, name) \ + CPS_ACCESSOR_R(unit, sz, name) + +#define CPS_ACCESSOR_WO(unit, sz, off, name) \ + CPS_ACCESSOR_A(unit, off, name) \ + CPS_ACCESSOR_W(unit, sz, name) + +#define CPS_ACCESSOR_RW(unit, sz, off, name) \ + CPS_ACCESSOR_A(unit, off, name) \ + CPS_ACCESSOR_R(unit, sz, name) \ + CPS_ACCESSOR_W(unit, sz, name) \ + CPS_ACCESSOR_M(unit, sz, name) + +#include +#include +#include + +/** + * mips_cps_numclusters - return the number of clusters present in the system + * + * Returns the number of clusters in the system. + */ +static inline unsigned int mips_cps_numclusters(void) +{ + unsigned int num_clusters; + + if (mips_cm_revision() < CM_REV_CM3_5) + return 1; + + num_clusters = read_gcr_config() & CM_GCR_CONFIG_NUM_CLUSTERS; + num_clusters >>= __ffs(CM_GCR_CONFIG_NUM_CLUSTERS); + return num_clusters; +} + +/** + * mips_cps_cluster_config - return (GCR|CPC)_CONFIG from a cluster + * @cluster: the ID of the cluster whose config we want + * + * Read the value of GCR_CONFIG (or its CPC_CONFIG mirror) from a @cluster. + * + * Returns the value of GCR_CONFIG. + */ +static inline uint64_t mips_cps_cluster_config(unsigned int cluster) +{ + uint64_t config; + + if (mips_cm_revision() < CM_REV_CM3_5) { + /* + * Prior to CM 3.5 we don't have the notion of multiple + * clusters so we can trivially read the GCR_CONFIG register + * within this cluster. + */ + WARN_ON(cluster != 0); + config = read_gcr_config(); + } else { + /* + * From CM 3.5 onwards we read the CPC_CONFIG mirror of + * GCR_CONFIG via the redirect region, since the CPC is always + * powered up allowing us not to need to power up the CM. + */ + mips_cm_lock_other(cluster, 0, 0, CM_GCR_Cx_OTHER_BLOCK_GLOBAL); + config = read_cpc_redir_config(); + mips_cm_unlock_other(); + } + + return config; +} + +/** + * mips_cps_numcores - return the number of cores present in a cluster + * @cluster: the ID of the cluster whose core count we want + * + * Returns the value of the PCORES field of the GCR_CONFIG register plus 1, or + * zero if no Coherence Manager is present. + */ +static inline unsigned int mips_cps_numcores(unsigned int cluster) +{ + if (!mips_cm_present()) + return 0; + + /* Add one before masking to handle 0xff indicating no cores */ + return (mips_cps_cluster_config(cluster) + 1) & CM_GCR_CONFIG_PCORES; +} + +/** + * mips_cps_numiocu - return the number of IOCUs present in a cluster + * @cluster: the ID of the cluster whose IOCU count we want + * + * Returns the value of the NUMIOCU field of the GCR_CONFIG register, or zero + * if no Coherence Manager is present. + */ +static inline unsigned int mips_cps_numiocu(unsigned int cluster) +{ + unsigned int num_iocu; + + if (!mips_cm_present()) + return 0; + + num_iocu = mips_cps_cluster_config(cluster) & CM_GCR_CONFIG_NUMIOCU; + num_iocu >>= __ffs(CM_GCR_CONFIG_NUMIOCU); + return num_iocu; +} + +/** + * mips_cps_numvps - return the number of VPs (threads) supported by a core + * @cluster: the ID of the cluster containing the core we want to examine + * @core: the ID of the core whose VP count we want + * + * Returns the number of Virtual Processors (VPs, ie. hardware threads) that + * are supported by the given @core in the given @cluster. If the core or the + * kernel do not support hardware mutlti-threading this returns 1. + */ +static inline unsigned int mips_cps_numvps(unsigned int cluster, unsigned int core) +{ + unsigned int cfg; + + if (!mips_cm_present()) + return 1; + + if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) + && (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp)) + return 1; + + mips_cm_lock_other(cluster, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); + + if (mips_cm_revision() < CM_REV_CM3_5) { + /* + * Prior to CM 3.5 we can only have one cluster & don't have + * CPC_Cx_CONFIG, so we read GCR_Cx_CONFIG. + */ + cfg = read_gcr_co_config(); + } else { + /* + * From CM 3.5 onwards we read CPC_Cx_CONFIG because the CPC is + * always powered, which allows us to not worry about powering + * up the cluster's CM here. + */ + cfg = read_cpc_co_config(); + } + + mips_cm_unlock_other(); + + return (cfg + 1) & CM_GCR_Cx_CONFIG_PVPE; +} + +#endif /* __MIPS_ASM_MIPS_CPS_H__ */ diff --git a/arch/mips/include/asm/mips-gic.h b/arch/mips/include/asm/mips-gic.h new file mode 100644 index 000000000000..558059a8f218 --- /dev/null +++ b/arch/mips/include/asm/mips-gic.h @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2017 Imagination Technologies + * Author: Paul Burton + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MIPS_ASM_MIPS_CPS_H__ +# error Please include asm/mips-cps.h rather than asm/mips-gic.h +#endif + +#ifndef __MIPS_ASM_MIPS_GIC_H__ +#define __MIPS_ASM_MIPS_GIC_H__ + +#include + +/* The base address of the GIC registers */ +extern void __iomem *mips_gic_base; + +/* Offsets from the GIC base address to various control blocks */ +#define MIPS_GIC_SHARED_OFS 0x00000 +#define MIPS_GIC_SHARED_SZ 0x08000 +#define MIPS_GIC_LOCAL_OFS 0x08000 +#define MIPS_GIC_LOCAL_SZ 0x04000 +#define MIPS_GIC_REDIR_OFS 0x0c000 +#define MIPS_GIC_REDIR_SZ 0x04000 +#define MIPS_GIC_USER_OFS 0x10000 +#define MIPS_GIC_USER_SZ 0x10000 + +/* For read-only shared registers */ +#define GIC_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_SHARED_OFS + off, name) + +/* For read-write shared registers */ +#define GIC_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_SHARED_OFS + off, name) + +/* For read-only local registers */ +#define GIC_VX_ACCESSOR_RO(sz, off, name) \ + CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name) \ + CPS_ACCESSOR_RO(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name) + +/* For read-write local registers */ +#define GIC_VX_ACCESSOR_RW(sz, off, name) \ + CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_LOCAL_OFS + off, vl_##name) \ + CPS_ACCESSOR_RW(gic, sz, MIPS_GIC_REDIR_OFS + off, vo_##name) + +/* For read-only shared per-interrupt registers */ +#define GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \ +static inline void __iomem *addr_gic_##name(unsigned int intr) \ +{ \ + return mips_gic_base + (off) + (intr * (stride)); \ +} \ + \ +static inline unsigned int read_gic_##name(unsigned int intr) \ +{ \ + BUILD_BUG_ON(sz != 32); \ + return __raw_readl(addr_gic_##name(intr)); \ +} + +/* For read-write shared per-interrupt registers */ +#define GIC_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \ + GIC_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \ + \ +static inline void write_gic_##name(unsigned int intr, \ + unsigned int val) \ +{ \ + BUILD_BUG_ON(sz != 32); \ + __raw_writel(val, addr_gic_##name(intr)); \ +} + +/* For read-only local per-interrupt registers */ +#define GIC_VX_ACCESSOR_RO_INTR_REG(sz, off, stride, name) \ + GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \ + stride, vl_##name) \ + GIC_ACCESSOR_RO_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \ + stride, vo_##name) + +/* For read-write local per-interrupt registers */ +#define GIC_VX_ACCESSOR_RW_INTR_REG(sz, off, stride, name) \ + GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_LOCAL_OFS + off, \ + stride, vl_##name) \ + GIC_ACCESSOR_RW_INTR_REG(sz, MIPS_GIC_REDIR_OFS + off, \ + stride, vo_##name) + +/* For read-only shared bit-per-interrupt registers */ +#define GIC_ACCESSOR_RO_INTR_BIT(off, name) \ +static inline void __iomem *addr_gic_##name(void) \ +{ \ + return mips_gic_base + (off); \ +} \ + \ +static inline unsigned int read_gic_##name(unsigned int intr) \ +{ \ + void __iomem *addr = addr_gic_##name(); \ + unsigned int val; \ + \ + if (mips_cm_is64) { \ + addr += (intr / 64) * sizeof(uint64_t); \ + val = __raw_readq(addr) >> intr % 64; \ + } else { \ + addr += (intr / 32) * sizeof(uint32_t); \ + val = __raw_readl(addr) >> intr % 32; \ + } \ + \ + return val & 0x1; \ +} + +/* For read-write shared bit-per-interrupt registers */ +#define GIC_ACCESSOR_RW_INTR_BIT(off, name) \ + GIC_ACCESSOR_RO_INTR_BIT(off, name) \ + \ +static inline void write_gic_##name(unsigned int intr) \ +{ \ + void __iomem *addr = addr_gic_##name(); \ + \ + if (mips_cm_is64) { \ + addr += (intr / 64) * sizeof(uint64_t); \ + __raw_writeq(BIT(intr % 64), addr); \ + } else { \ + addr += (intr / 32) * sizeof(uint32_t); \ + __raw_writel(BIT(intr % 32), addr); \ + } \ +} \ + \ +static inline void change_gic_##name(unsigned int intr, \ + unsigned int val) \ +{ \ + void __iomem *addr = addr_gic_##name(); \ + \ + if (mips_cm_is64) { \ + uint64_t _val; \ + \ + addr += (intr / 64) * sizeof(uint64_t); \ + _val = __raw_readq(addr); \ + _val &= ~BIT_ULL(intr % 64); \ + _val |= (uint64_t)val << (intr % 64); \ + __raw_writeq(_val, addr); \ + } else { \ + uint32_t _val; \ + \ + addr += (intr / 32) * sizeof(uint32_t); \ + _val = __raw_readl(addr); \ + _val &= ~BIT(intr % 32); \ + _val |= val << (intr % 32); \ + __raw_writel(_val, addr); \ + } \ +} + +/* For read-only local bit-per-interrupt registers */ +#define GIC_VX_ACCESSOR_RO_INTR_BIT(sz, off, name) \ + GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \ + vl_##name) \ + GIC_ACCESSOR_RO_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \ + vo_##name) + +/* For read-write local bit-per-interrupt registers */ +#define GIC_VX_ACCESSOR_RW_INTR_BIT(sz, off, name) \ + GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_LOCAL_OFS + off, \ + vl_##name) \ + GIC_ACCESSOR_RW_INTR_BIT(sz, MIPS_GIC_REDIR_OFS + off, \ + vo_##name) + +/* GIC_SH_CONFIG - Information about the GIC configuration */ +GIC_ACCESSOR_RW(32, 0x000, config) +#define GIC_CONFIG_COUNTSTOP BIT(28) +#define GIC_CONFIG_COUNTBITS GENMASK(27, 24) +#define GIC_CONFIG_NUMINTERRUPTS GENMASK(23, 16) +#define GIC_CONFIG_PVPS GENMASK(6, 0) + +/* GIC_SH_COUNTER - Shared global counter value */ +GIC_ACCESSOR_RW(64, 0x010, counter) +GIC_ACCESSOR_RW(32, 0x010, counter_32l) +GIC_ACCESSOR_RW(32, 0x014, counter_32h) + +/* GIC_SH_POL_* - Configures interrupt polarity */ +GIC_ACCESSOR_RW_INTR_BIT(0x100, pol) +#define GIC_POL_ACTIVE_LOW 0 /* when level triggered */ +#define GIC_POL_ACTIVE_HIGH 1 /* when level triggered */ +#define GIC_POL_FALLING_EDGE 0 /* when single-edge triggered */ +#define GIC_POL_RISING_EDGE 1 /* when single-edge triggered */ + +/* GIC_SH_TRIG_* - Configures interrupts to be edge or level triggered */ +GIC_ACCESSOR_RW_INTR_BIT(0x180, trig) +#define GIC_TRIG_LEVEL 0 +#define GIC_TRIG_EDGE 1 + +/* GIC_SH_DUAL_* - Configures whether interrupts trigger on both edges */ +GIC_ACCESSOR_RW_INTR_BIT(0x200, dual) +#define GIC_DUAL_SINGLE 0 /* when edge-triggered */ +#define GIC_DUAL_DUAL 1 /* when edge-triggered */ + +/* GIC_SH_WEDGE - Write an 'edge', ie. trigger an interrupt */ +GIC_ACCESSOR_RW(32, 0x280, wedge) +#define GIC_WEDGE_RW BIT(31) +#define GIC_WEDGE_INTR GENMASK(7, 0) + +/* GIC_SH_RMASK_* - Reset/clear shared interrupt mask bits */ +GIC_ACCESSOR_RW_INTR_BIT(0x300, rmask) + +/* GIC_SH_SMASK_* - Set shared interrupt mask bits */ +GIC_ACCESSOR_RW_INTR_BIT(0x380, smask) + +/* GIC_SH_MASK_* - Read the current shared interrupt mask */ +GIC_ACCESSOR_RO_INTR_BIT(0x400, mask) + +/* GIC_SH_PEND_* - Read currently pending shared interrupts */ +GIC_ACCESSOR_RO_INTR_BIT(0x480, pend) + +/* GIC_SH_MAPx_PIN - Map shared interrupts to a particular CPU pin */ +GIC_ACCESSOR_RW_INTR_REG(32, 0x500, 0x4, map_pin) +#define GIC_MAP_PIN_MAP_TO_PIN BIT(31) +#define GIC_MAP_PIN_MAP_TO_NMI BIT(30) +#define GIC_MAP_PIN_MAP GENMASK(5, 0) + +/* GIC_SH_MAPx_VP - Map shared interrupts to a particular Virtual Processor */ +GIC_ACCESSOR_RW_INTR_REG(32, 0x2000, 0x20, map_vp) + +/* GIC_Vx_CTL - VP-level interrupt control */ +GIC_VX_ACCESSOR_RW(32, 0x000, ctl) +#define GIC_VX_CTL_FDC_ROUTABLE BIT(4) +#define GIC_VX_CTL_SWINT_ROUTABLE BIT(3) +#define GIC_VX_CTL_PERFCNT_ROUTABLE BIT(2) +#define GIC_VX_CTL_TIMER_ROUTABLE BIT(1) +#define GIC_VX_CTL_EIC BIT(0) + +/* GIC_Vx_PEND - Read currently pending local interrupts */ +GIC_VX_ACCESSOR_RO(32, 0x004, pend) + +/* GIC_Vx_MASK - Read the current local interrupt mask */ +GIC_VX_ACCESSOR_RO(32, 0x008, mask) + +/* GIC_Vx_RMASK - Reset/clear local interrupt mask bits */ +GIC_VX_ACCESSOR_RW(32, 0x00c, rmask) + +/* GIC_Vx_SMASK - Set local interrupt mask bits */ +GIC_VX_ACCESSOR_RW(32, 0x010, smask) + +/* GIC_Vx_*_MAP - Route local interrupts to the desired pins */ +GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x040, 0x4, map) + +/* GIC_Vx_WD_MAP - Route the local watchdog timer interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x040, wd_map) + +/* GIC_Vx_COMPARE_MAP - Route the local count/compare interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x044, compare_map) + +/* GIC_Vx_TIMER_MAP - Route the local CPU timer (cp0 count/compare) interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x048, timer_map) + +/* GIC_Vx_FDC_MAP - Route the local fast debug channel interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x04c, fdc_map) + +/* GIC_Vx_PERFCTR_MAP - Route the local performance counter interrupt */ +GIC_VX_ACCESSOR_RW(32, 0x050, perfctr_map) + +/* GIC_Vx_SWINT0_MAP - Route the local software interrupt 0 */ +GIC_VX_ACCESSOR_RW(32, 0x054, swint0_map) + +/* GIC_Vx_SWINT1_MAP - Route the local software interrupt 1 */ +GIC_VX_ACCESSOR_RW(32, 0x058, swint1_map) + +/* GIC_Vx_OTHER - Configure access to other Virtual Processor registers */ +GIC_VX_ACCESSOR_RW(32, 0x080, other) +#define GIC_VX_OTHER_VPNUM GENMASK(5, 0) + +/* GIC_Vx_IDENT - Retrieve the local Virtual Processor's ID */ +GIC_VX_ACCESSOR_RO(32, 0x088, ident) +#define GIC_VX_IDENT_VPNUM GENMASK(5, 0) + +/* GIC_Vx_COMPARE - Value to compare with GIC_SH_COUNTER */ +GIC_VX_ACCESSOR_RW(64, 0x0a0, compare) + +/* GIC_Vx_EIC_SHADOW_SET_BASE - Set shadow register set for each interrupt */ +GIC_VX_ACCESSOR_RW_INTR_REG(32, 0x100, 0x4, eic_shadow_set) + +/** + * enum mips_gic_local_interrupt - GIC local interrupts + * @GIC_LOCAL_INT_WD: GIC watchdog timer interrupt + * @GIC_LOCAL_INT_COMPARE: GIC count/compare interrupt + * @GIC_LOCAL_INT_TIMER: CP0 count/compare interrupt + * @GIC_LOCAL_INT_PERFCTR: Performance counter interrupt + * @GIC_LOCAL_INT_SWINT0: Software interrupt 0 + * @GIC_LOCAL_INT_SWINT1: Software interrupt 1 + * @GIC_LOCAL_INT_FDC: Fast debug channel interrupt + * @GIC_NUM_LOCAL_INTRS: The number of local interrupts + * + * Enumerates interrupts provided by the GIC that are local to a VP. + */ +enum mips_gic_local_interrupt { + GIC_LOCAL_INT_WD, + GIC_LOCAL_INT_COMPARE, + GIC_LOCAL_INT_TIMER, + GIC_LOCAL_INT_PERFCTR, + GIC_LOCAL_INT_SWINT0, + GIC_LOCAL_INT_SWINT1, + GIC_LOCAL_INT_FDC, + GIC_NUM_LOCAL_INTRS +}; + +/** + * mips_gic_present() - Determine whether a GIC is present + * + * Determines whether a MIPS Global Interrupt Controller (GIC) is present in + * the system that the kernel is running on. + * + * Return true if a GIC is present, else false. + */ +static inline bool mips_gic_present(void) +{ + return IS_ENABLED(CONFIG_MIPS_GIC) && mips_gic_base; +} + +/** + * gic_get_c0_compare_int() - Return cp0 count/compare interrupt virq + * + * Determine the virq number to use for the coprocessor 0 count/compare + * interrupt, which may be routed via the GIC. + * + * Returns the virq number or a negative error number. + */ +extern int gic_get_c0_compare_int(void); + +/** + * gic_get_c0_perfcount_int() - Return performance counter interrupt virq + * + * Determine the virq number to use for CPU performance counter interrupts, + * which may be routed via the GIC. + * + * Returns the virq number or a negative error number. + */ +extern int gic_get_c0_perfcount_int(void); + +/** + * gic_get_c0_fdc_int() - Return fast debug channel interrupt virq + * + * Determine the virq number to use for fast debug channel (FDC) interrupts, + * which may be routed via the GIC. + * + * Returns the virq number or a negative error number. + */ +extern int gic_get_c0_fdc_int(void); + +#endif /* __MIPS_ASM_MIPS_CPS_H__ */ diff --git a/arch/mips/include/asm/mips_mt.h b/arch/mips/include/asm/mips_mt.h index aa4cca060e0a..b444523ecd50 100644 --- a/arch/mips/include/asm/mips_mt.h +++ b/arch/mips/include/asm/mips_mt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions and declarations for MIPS MT support that are common between * the VSMP, and AP/SP kernel models. diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h index 5f8052ce43bf..212336b7c0f4 100644 --- a/arch/mips/include/asm/mipsmtregs.h +++ b/arch/mips/include/asm/mipsmtregs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * MT regs definitions, follows on from mipsregs.h * Copyright (C) 2004 - 2005 MIPS Technologies, Inc. All rights reserved. diff --git a/arch/mips/include/asm/mipsprom.h b/arch/mips/include/asm/mipsprom.h index e93943fabeac..2eda19f8fd4c 100644 --- a/arch/mips/include/asm/mipsprom.h +++ b/arch/mips/include/asm/mipsprom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MIPSPROM_H #define __ASM_MIPSPROM_H diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index dbb0eceda2c6..a6810923b3f0 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -48,6 +48,7 @@ #define CP0_ENTRYLO0 $2 #define CP0_ENTRYLO1 $3 #define CP0_CONF $3 +#define CP0_GLOBALNUMBER $3, 1 #define CP0_CONTEXT $4 #define CP0_PAGEMASK $5 #define CP0_SEGCTL0 $5, 2 @@ -147,6 +148,16 @@ #define MIPS_ENTRYLO_XI (_ULCAST_(1) << (BITS_PER_LONG - 2)) #define MIPS_ENTRYLO_RI (_ULCAST_(1) << (BITS_PER_LONG - 1)) +/* + * MIPSr6+ GlobalNumber register definitions + */ +#define MIPS_GLOBALNUMBER_VP_SHF 0 +#define MIPS_GLOBALNUMBER_VP (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_VP_SHF) +#define MIPS_GLOBALNUMBER_CORE_SHF 8 +#define MIPS_GLOBALNUMBER_CORE (_ULCAST_(0xff) << MIPS_GLOBALNUMBER_CORE_SHF) +#define MIPS_GLOBALNUMBER_CLUSTER_SHF 16 +#define MIPS_GLOBALNUMBER_CLUSTER (_ULCAST_(0xf) << MIPS_GLOBALNUMBER_CLUSTER_SHF) + /* * Values for PageMask register */ @@ -1366,29 +1377,32 @@ do { \ #define __write_64bit_c0_split(source, sel, val) \ do { \ + unsigned long long __tmp; \ unsigned long __flags; \ \ local_irq_save(__flags); \ if (sel == 0) \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ - "dsll\t%L0, %L0, 32\n\t" \ + "dsll\t%L0, %L1, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ - "dsll\t%M0, %M0, 32\n\t" \ + "dsll\t%M0, %M1, 32\n\t" \ "or\t%L0, %L0, %M0\n\t" \ "dmtc0\t%L0, " #source "\n\t" \ ".set\tmips0" \ - : : "r" (val)); \ + : "=&r,r" (__tmp) \ + : "r,0" (val)); \ else \ __asm__ __volatile__( \ ".set\tmips64\n\t" \ - "dsll\t%L0, %L0, 32\n\t" \ + "dsll\t%L0, %L1, 32\n\t" \ "dsrl\t%L0, %L0, 32\n\t" \ - "dsll\t%M0, %M0, 32\n\t" \ + "dsll\t%M0, %M1, 32\n\t" \ "or\t%L0, %L0, %M0\n\t" \ "dmtc0\t%L0, " #source ", " #sel "\n\t" \ ".set\tmips0" \ - : : "r" (val)); \ + : "=&r,r" (__tmp) \ + : "r,0" (val)); \ local_irq_restore(__flags); \ } while (0) @@ -1446,6 +1460,8 @@ do { \ #define read_c0_conf() __read_32bit_c0_register($3, 0) #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) +#define read_c0_globalnumber() __read_32bit_c0_register($3, 1) + #define read_c0_context() __read_ulong_c0_register($4, 0) #define write_c0_context(val) __write_ulong_c0_register($4, 0, val) diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h index f6ba08d77931..0740be7d5d4a 100644 --- a/arch/mips/include/asm/mmu.h +++ b/arch/mips/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MMU_H #define __ASM_MMU_H diff --git a/arch/mips/include/asm/mmzone.h b/arch/mips/include/asm/mmzone.h index f53ec54c92ff..f085fba41da5 100644 --- a/arch/mips/include/asm/mmzone.h +++ b/arch/mips/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99 * Rewritten for Linux 2.6 by Christoph Hellwig (hch@lst.de) Jan 2004 diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index e51add184717..6dc0b21b8acd 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_MODULE_H #define _ASM_MODULE_H @@ -114,8 +115,6 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "R5432 " #elif defined CONFIG_CPU_R5500 #define MODULE_PROC_FAMILY "R5500 " -#elif defined CONFIG_CPU_R6000 -#define MODULE_PROC_FAMILY "R6000 " #elif defined CONFIG_CPU_NEVADA #define MODULE_PROC_FAMILY "NEVADA " #elif defined CONFIG_CPU_R8000 diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h index 8967b475ab10..b1845102f8f9 100644 --- a/arch/mips/include/asm/msa.h +++ b/arch/mips/include/asm/msa.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h index e0717d10e650..a6e6cbebe046 100644 --- a/arch/mips/include/asm/netlogic/common.h +++ b/arch/mips/include/asm/netlogic/common.h @@ -84,7 +84,7 @@ nlm_set_nmi_handler(void *handler) */ void nlm_init_boot_cpu(void); unsigned int nlm_get_cpu_frequency(void); -extern struct plat_smp_ops nlm_smp_ops; +extern const struct plat_smp_ops nlm_smp_ops; extern char nlm_reset_entry[], nlm_reset_entry_end[]; /* SWIOTLB */ diff --git a/arch/mips/include/asm/nile4.h b/arch/mips/include/asm/nile4.h index 99e97f8bfbca..9d36b7823603 100644 --- a/arch/mips/include/asm/nile4.h +++ b/arch/mips/include/asm/nile4.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * asm-mips/nile4.h -- NEC Vrc-5074 Nile 4 definitions * diff --git a/arch/mips/include/asm/octeon/cvmx-boot-vector.h b/arch/mips/include/asm/octeon/cvmx-boot-vector.h new file mode 100644 index 000000000000..8db08241d53c --- /dev/null +++ b/arch/mips/include/asm/octeon/cvmx-boot-vector.h @@ -0,0 +1,53 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003-2017 Cavium, Inc. + */ + +#ifndef __CVMX_BOOT_VECTOR_H__ +#define __CVMX_BOOT_VECTOR_H__ + +#include + +/* + * The boot vector table is made up of an array of 1024 elements of + * struct cvmx_boot_vector_element. There is one entry for each + * possible MIPS CPUNum, indexed by the CPUNum. + * + * Once cvmx_boot_vector_get() returns a non-NULL value (indicating + * success), NMI to a core will cause execution to transfer to the + * target_ptr location for that core's entry in the vector table. + * + * The struct cvmx_boot_vector_element fields app0, app1, and app2 can + * be used by the application that has set the target_ptr in any + * application specific manner, they are not touched by the vectoring + * code. + * + * The boot vector code clobbers the CP0_DESAVE register, and on + * OCTEON II and later CPUs also clobbers CP0_KScratch2. All GP + * registers are preserved, except on pre-OCTEON II CPUs, where k1 is + * clobbered. + * + */ + + +/* + * Applications install the boot bus code in cvmx-boot-vector.c, which + * uses this magic: + */ +#define OCTEON_BOOT_MOVEABLE_MAGIC1 0xdb00110ad358eacdull + +struct cvmx_boot_vector_element { + /* kseg0 or xkphys address of target code. */ + uint64_t target_ptr; + /* Three application specific arguments. */ + uint64_t app0; + uint64_t app1; + uint64_t app2; +}; + +struct cvmx_boot_vector_element *cvmx_boot_vector_get(void); + +#endif /* __CVMX_BOOT_VECTOR_H__ */ diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h index 374562507d0b..72d2e403a6e4 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootmem.h +++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h @@ -255,6 +255,34 @@ extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr, uint64_t max_addr, uint64_t align, char *name); +/** + * Allocate if needed a block of memory from a specific range of the + * free list that was passed to the application by the bootloader, and + * assign it a name in the global named block table. (part of the + * cvmx_bootmem_descriptor_t structure) Named blocks can later be + * freed. If the requested name block is already allocated, return + * the pointer to block of memory. If request cannot be satisfied + * within the address range specified, NULL is returned + * + * @param size Size in bytes of block to allocate + * @param min_addr minimum address of range + * @param max_addr maximum address of range + * @param align Alignment of memory to be allocated. (must be a power of 2) + * @param name name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes + * @param init Initialization function + * + * The initialization function is optional, if omitted the named block + * is initialized to all zeros when it is created, i.e. once. + * + * @return pointer to block of memory, NULL on error + */ +void *cvmx_bootmem_alloc_named_range_once(uint64_t size, + uint64_t min_addr, + uint64_t max_addr, + uint64_t align, + char *name, + void (*init) (void *)); + extern int cvmx_bootmem_free_named(char *name); /** diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h index 0dd0e40c96d4..6e61792d9248 100644 --- a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h +++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h @@ -128,6 +128,7 @@ static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset) case OCTEON_CN52XX & OCTEON_FAMILY_MASK: case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CN70XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; case OCTEON_CN31XX & OCTEON_FAMILY_MASK: case OCTEON_CN50XX & OCTEON_FAMILY_MASK: @@ -143,6 +144,10 @@ static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset) return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; case OCTEON_CN68XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070100100200ull) + (offset) * 8; + case OCTEON_CNF75XX & OCTEON_FAMILY_MASK: + case OCTEON_CN73XX & OCTEON_FAMILY_MASK: + case OCTEON_CN78XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001010000030000ull) + (offset) * 8; } return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8; } @@ -180,6 +185,7 @@ static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset) case OCTEON_CN52XX & OCTEON_FAMILY_MASK: case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: case OCTEON_CN61XX & OCTEON_FAMILY_MASK: + case OCTEON_CN70XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; case OCTEON_CN31XX & OCTEON_FAMILY_MASK: case OCTEON_CN50XX & OCTEON_FAMILY_MASK: @@ -195,6 +201,10 @@ static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset) return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; case OCTEON_CN68XX & OCTEON_FAMILY_MASK: return CVMX_ADD_IO_SEG(0x0001070100100000ull) + (offset) * 8; + case OCTEON_CNF75XX & OCTEON_FAMILY_MASK: + case OCTEON_CN73XX & OCTEON_FAMILY_MASK: + case OCTEON_CN78XX & OCTEON_FAMILY_MASK: + return CVMX_ADD_IO_SEG(0x0001010000020000ull) + (offset) * 8; } return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8; } diff --git a/arch/mips/include/asm/octeon/cvmx-config.h b/arch/mips/include/asm/octeon/cvmx-config.h index f4f1996e0fac..a8c358c02b05 100644 --- a/arch/mips/include/asm/octeon/cvmx-config.h +++ b/arch/mips/include/asm/octeon/cvmx-config.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CVMX_CONFIG_H__ #define __CVMX_CONFIG_H__ diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index e638735cc3ac..205ab2ce10f8 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -357,6 +357,34 @@ static inline unsigned int cvmx_get_local_core_num(void) return cvmx_get_core_num() & ((1 << CVMX_NODE_NO_SHIFT) - 1); } +#define CVMX_NODE_BITS (2) /* Number of bits to define a node */ +#define CVMX_MAX_NODES (1 << CVMX_NODE_BITS) +#define CVMX_NODE_IO_SHIFT (36) +#define CVMX_NODE_MEM_SHIFT (40) +#define CVMX_NODE_IO_MASK ((uint64_t)CVMX_NODE_MASK << CVMX_NODE_IO_SHIFT) + +static inline void cvmx_write_csr_node(uint64_t node, uint64_t csr_addr, + uint64_t val) +{ + uint64_t composite_csr_addr, node_addr; + + node_addr = (node & CVMX_NODE_MASK) << CVMX_NODE_IO_SHIFT; + composite_csr_addr = (csr_addr & ~CVMX_NODE_IO_MASK) | node_addr; + + cvmx_write64_uint64(composite_csr_addr, val); + if (((csr_addr >> 40) & 0x7ffff) == (0x118)) + cvmx_read64_uint64(CVMX_MIO_BOOT_BIST_STAT | node_addr); +} + +static inline uint64_t cvmx_read_csr_node(uint64_t node, uint64_t csr_addr) +{ + uint64_t node_addr; + + node_addr = (csr_addr & ~CVMX_NODE_IO_MASK) | + (node & CVMX_NODE_MASK) << CVMX_NODE_IO_SHIFT; + return cvmx_read_csr(node_addr); +} + /** * Returns the number of bits set in the provided value. * Simple wrapper for POP instruction. diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h index 07c0516ef4d5..c99c4b6a79f4 100644 --- a/arch/mips/include/asm/octeon/octeon.h +++ b/arch/mips/include/asm/octeon/octeon.h @@ -362,4 +362,6 @@ extern void octeon_fixup_irqs(void); extern struct semaphore octeon_bootbus_sem; +struct irq_domain *octeon_irq_get_block_domain(int node, uint8_t block); + #endif /* __ASM_OCTEON_OCTEON_H */ diff --git a/arch/mips/include/asm/pm-cps.h b/arch/mips/include/asm/pm-cps.h index 89d58d80b77b..bb0616967342 100644 --- a/arch/mips/include/asm/pm-cps.h +++ b/arch/mips/include/asm/pm-cps.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/seccomp.h b/arch/mips/include/asm/seccomp.h index d886d6f7687a..e383d7e27b93 100644 --- a/arch/mips/include/asm/seccomp.h +++ b/arch/mips/include/asm/seccomp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SECCOMP_H #include diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h index 4f5279a8308d..d49d247d48a1 100644 --- a/arch/mips/include/asm/setup.h +++ b/arch/mips/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MIPS_SETUP_H #define _MIPS_SETUP_H diff --git a/arch/mips/include/asm/sgi/pi1.h b/arch/mips/include/asm/sgi/pi1.h index 96b1a0771ec3..88b814ef3f18 100644 --- a/arch/mips/include/asm/sgi/pi1.h +++ b/arch/mips/include/asm/sgi/pi1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * pi1.h: Definitions for SGI PI1 parallel port */ diff --git a/arch/mips/include/asm/smp-cps.h b/arch/mips/include/asm/smp-cps.h index 2ae1f61a4a95..16b4ee3feb98 100644 --- a/arch/mips/include/asm/smp-cps.h +++ b/arch/mips/include/asm/smp-cps.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h index db7c322f057f..53b2cb8e5966 100644 --- a/arch/mips/include/asm/smp-ops.h +++ b/arch/mips/include/asm/smp-ops.h @@ -13,7 +13,7 @@ #include -#include +#include #ifdef CONFIG_SMP @@ -26,7 +26,7 @@ struct plat_smp_ops { void (*send_ipi_mask)(const struct cpumask *mask, unsigned int action); void (*init_secondary)(void); void (*smp_finish)(void); - void (*boot_secondary)(int cpu, struct task_struct *idle); + int (*boot_secondary)(int cpu, struct task_struct *idle); void (*smp_setup)(void); void (*prepare_cpus)(unsigned int max_cpus); #ifdef CONFIG_HOTPLUG_CPU @@ -35,11 +35,11 @@ struct plat_smp_ops { #endif }; -extern void register_smp_ops(struct plat_smp_ops *ops); +extern void register_smp_ops(const struct plat_smp_ops *ops); static inline void plat_smp_setup(void) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->smp_setup(); } @@ -57,7 +57,7 @@ static inline void plat_smp_setup(void) /* UP, nothing to do ... */ } -static inline void register_smp_ops(struct plat_smp_ops *ops) +static inline void register_smp_ops(const struct plat_smp_ops *ops) { } @@ -66,7 +66,7 @@ static inline void register_smp_ops(struct plat_smp_ops *ops) static inline int register_up_smp_ops(void) { #ifdef CONFIG_SMP_UP - extern struct plat_smp_ops up_smp_ops; + extern const struct plat_smp_ops up_smp_ops; register_smp_ops(&up_smp_ops); @@ -79,7 +79,7 @@ static inline int register_up_smp_ops(void) static inline int register_cmp_smp_ops(void) { #ifdef CONFIG_MIPS_CMP - extern struct plat_smp_ops cmp_smp_ops; + extern const struct plat_smp_ops cmp_smp_ops; if (!mips_cm_present()) return -ENODEV; @@ -95,7 +95,7 @@ static inline int register_cmp_smp_ops(void) static inline int register_vsmp_smp_ops(void) { #ifdef CONFIG_MIPS_MT_SMP - extern struct plat_smp_ops vsmp_smp_ops; + extern const struct plat_smp_ops vsmp_smp_ops; register_smp_ops(&vsmp_smp_ops); diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index bab3d41e5987..9e494f8d9c03 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -58,7 +58,7 @@ extern void calculate_cpu_foreign_map(void); */ static inline void smp_send_reschedule(int cpu) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->send_ipi_single(cpu, SMP_RESCHEDULE_YOURSELF); } @@ -66,14 +66,14 @@ static inline void smp_send_reschedule(int cpu) #ifdef CONFIG_HOTPLUG_CPU static inline int __cpu_disable(void) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ return mp_ops->cpu_disable(); } static inline void __cpu_die(unsigned int cpu) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->cpu_die(cpu); } @@ -97,14 +97,14 @@ int mips_smp_ipi_free(const struct cpumask *mask); static inline void arch_send_call_function_single_ipi(int cpu) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->send_ipi_mask(cpumask_of(cpu), SMP_CALL_FUNCTION); } static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) { - extern struct plat_smp_ops *mp_ops; /* private */ + extern const struct plat_smp_ops *mp_ops; /* private */ mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION); } diff --git a/arch/mips/include/asm/sn/hub.h b/arch/mips/include/asm/sn/hub.h index 1992d9254a08..338f7eed74f1 100644 --- a/arch/mips/include/asm/sn/hub.h +++ b/arch/mips/include/asm/sn/hub.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SN_HUB_H #define __ASM_SN_HUB_H diff --git a/arch/mips/include/asm/sn/ioc3.h b/arch/mips/include/asm/sn/ioc3.h index feb385180f87..25c8dccab51f 100644 --- a/arch/mips/include/asm/sn/ioc3.h +++ b/arch/mips/include/asm/sn/ioc3.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999, 2000 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. diff --git a/arch/mips/include/asm/sn/klkernvars.h b/arch/mips/include/asm/sn/klkernvars.h index 6af25ba41ade..ea6b21795163 100644 --- a/arch/mips/include/asm/sn/klkernvars.h +++ b/arch/mips/include/asm/sn/klkernvars.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File ported from IRIX to Linux by Kanoj Sarcar, 06/08/00. * Copyright 2000 Silicon Graphics, Inc. diff --git a/arch/mips/include/asm/sn/mapped_kernel.h b/arch/mips/include/asm/sn/mapped_kernel.h index 401f3b0eee17..2f3efa91c16e 100644 --- a/arch/mips/include/asm/sn/mapped_kernel.h +++ b/arch/mips/include/asm/sn/mapped_kernel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * File created by Kanoj Sarcar 06/06/00. * Copyright 2000 Silicon Graphics, Inc. diff --git a/arch/mips/include/asm/sn/sn_private.h b/arch/mips/include/asm/sn/sn_private.h index fdfae43d8b99..f09ba846c644 100644 --- a/arch/mips/include/asm/sn/sn_private.h +++ b/arch/mips/include/asm/sn/sn_private.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SN_SN_PRIVATE_H #define __ASM_SN_SN_PRIVATE_H diff --git a/arch/mips/include/asm/sparsemem.h b/arch/mips/include/asm/sparsemem.h index b1071c1e54f5..b0686ca3d8bf 100644 --- a/arch/mips/include/asm/sparsemem.h +++ b/arch/mips/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MIPS_SPARSEMEM_H #define _MIPS_SPARSEMEM_H #ifdef CONFIG_SPARSEMEM diff --git a/arch/mips/include/asm/spinlock_types.h b/arch/mips/include/asm/spinlock_types.h index 177e722eb96c..28fd4b140bea 100644 --- a/arch/mips/include/asm/spinlock_types.h +++ b/arch/mips/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPINLOCK_TYPES_H #define _ASM_SPINLOCK_TYPES_H diff --git a/arch/mips/include/asm/spram.h b/arch/mips/include/asm/spram.h index 0f90d88e464d..63cb90fd4148 100644 --- a/arch/mips/include/asm/spram.h +++ b/arch/mips/include/asm/spram.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MIPS_SPRAM_H #define _MIPS_SPRAM_H diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index eaa5a4d7d5e5..2161357cc68f 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -19,20 +19,43 @@ #include #include +/* Make the addition of cfi info a little easier. */ + .macro cfi_rel_offset reg offset=0 docfi=0 + .if \docfi + .cfi_rel_offset \reg, \offset + .endif + .endm + + .macro cfi_st reg offset=0 docfi=0 + LONG_S \reg, \offset(sp) + cfi_rel_offset \reg, \offset, \docfi + .endm + + .macro cfi_restore reg offset=0 docfi=0 + .if \docfi + .cfi_restore \reg + .endif + .endm + + .macro cfi_ld reg offset=0 docfi=0 + LONG_L \reg, \offset(sp) + cfi_restore \reg \offset \docfi + .endm + #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) #define STATMASK 0x3f #else #define STATMASK 0x1f #endif - .macro SAVE_AT + .macro SAVE_AT docfi=0 .set push .set noat - LONG_S $1, PT_R1(sp) + cfi_st $1, PT_R1, \docfi .set pop .endm - .macro SAVE_TEMP + .macro SAVE_TEMP docfi=0 #ifdef CONFIG_CPU_HAS_SMARTMIPS mflhxu v1 LONG_S v1, PT_LO(sp) @@ -44,20 +67,20 @@ mfhi v1 #endif #ifdef CONFIG_32BIT - LONG_S $8, PT_R8(sp) - LONG_S $9, PT_R9(sp) + cfi_st $8, PT_R8, \docfi + cfi_st $9, PT_R9, \docfi #endif - LONG_S $10, PT_R10(sp) - LONG_S $11, PT_R11(sp) - LONG_S $12, PT_R12(sp) + cfi_st $10, PT_R10, \docfi + cfi_st $11, PT_R11, \docfi + cfi_st $12, PT_R12, \docfi #if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6) LONG_S v1, PT_HI(sp) mflo v1 #endif - LONG_S $13, PT_R13(sp) - LONG_S $14, PT_R14(sp) - LONG_S $15, PT_R15(sp) - LONG_S $24, PT_R24(sp) + cfi_st $13, PT_R13, \docfi + cfi_st $14, PT_R14, \docfi + cfi_st $15, PT_R15, \docfi + cfi_st $24, PT_R24, \docfi #if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6) LONG_S v1, PT_LO(sp) #endif @@ -71,20 +94,28 @@ #endif .endm - .macro SAVE_STATIC - LONG_S $16, PT_R16(sp) - LONG_S $17, PT_R17(sp) - LONG_S $18, PT_R18(sp) - LONG_S $19, PT_R19(sp) - LONG_S $20, PT_R20(sp) - LONG_S $21, PT_R21(sp) - LONG_S $22, PT_R22(sp) - LONG_S $23, PT_R23(sp) - LONG_S $30, PT_R30(sp) + .macro SAVE_STATIC docfi=0 + cfi_st $16, PT_R16, \docfi + cfi_st $17, PT_R17, \docfi + cfi_st $18, PT_R18, \docfi + cfi_st $19, PT_R19, \docfi + cfi_st $20, PT_R20, \docfi + cfi_st $21, PT_R21, \docfi + cfi_st $22, PT_R22, \docfi + cfi_st $23, PT_R23, \docfi + cfi_st $30, PT_R30, \docfi .endm +/* + * get_saved_sp returns the SP for the current CPU by looking in the + * kernelsp array for it. If tosp is set, it stores the current sp in + * k0 and loads the new value in sp. If not, it clobbers k0 and + * stores the new value in k1, leaving sp unaffected. + */ #ifdef CONFIG_SMP - .macro get_saved_sp /* SMP variation */ + + /* SMP variation */ + .macro get_saved_sp docfi=0 tosp=0 ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) lui k1, %hi(kernelsp) @@ -97,7 +128,15 @@ #endif LONG_SRL k0, SMP_CPUID_PTRSHIFT LONG_ADDU k1, k0 + .if \tosp + move k0, sp + .if \docfi + .cfi_register sp, k0 + .endif + LONG_L sp, %lo(kernelsp)(k1) + .else LONG_L k1, %lo(kernelsp)(k1) + .endif .endm .macro set_saved_sp stackp temp temp2 @@ -106,7 +145,8 @@ LONG_S \stackp, kernelsp(\temp) .endm #else /* !CONFIG_SMP */ - .macro get_saved_sp /* Uniprocessor variation */ + /* Uniprocessor variation */ + .macro get_saved_sp docfi=0 tosp=0 #ifdef CONFIG_CPU_JUMP_WORKAROUNDS /* * Clear BTB (branch target buffer), forbid RAS (return address @@ -135,7 +175,15 @@ daddiu k1, %hi(kernelsp) dsll k1, k1, 16 #endif + .if \tosp + move k0, sp + .if \docfi + .cfi_register sp, k0 + .endif + LONG_L sp, %lo(kernelsp)(k1) + .else LONG_L k1, %lo(kernelsp)(k1) + .endif .endm .macro set_saved_sp stackp temp temp2 @@ -143,7 +191,7 @@ .endm #endif - .macro SAVE_SOME + .macro SAVE_SOME docfi=0 .set push .set noat .set reorder @@ -151,7 +199,10 @@ sll k0, 3 /* extract cu0 bit */ .set noreorder bltz k0, 8f - move k1, sp + move k0, sp + .if \docfi + .cfi_register sp, k0 + .endif #ifdef CONFIG_EVA /* * Flush interAptiv's Return Prediction Stack (RPS) by writing @@ -179,19 +230,21 @@ #endif .set reorder /* Called from user mode, new stack. */ - get_saved_sp -#ifndef CONFIG_CPU_DADDI_WORKAROUNDS -8: move k0, sp - PTR_SUBU sp, k1, PT_SIZE -#else - .set at=k0 -8: PTR_SUBU k1, PT_SIZE - .set noat - move k0, sp - move sp, k1 + get_saved_sp docfi=\docfi tosp=1 +8: +#ifdef CONFIG_CPU_DADDI_WORKAROUNDS + .set at=k1 #endif - LONG_S k0, PT_R29(sp) - LONG_S $3, PT_R3(sp) + PTR_SUBU sp, PT_SIZE +#ifdef CONFIG_CPU_DADDI_WORKAROUNDS + .set noat +#endif + .if \docfi + .cfi_def_cfa sp,0 + .endif + cfi_st k0, PT_R29, \docfi + cfi_rel_offset sp, PT_R29, \docfi + cfi_st v1, PT_R3, \docfi /* * You might think that you don't need to save $0, * but the FPU emulator and gdb remote debug stub @@ -199,23 +252,26 @@ */ LONG_S $0, PT_R0(sp) mfc0 v1, CP0_STATUS - LONG_S $2, PT_R2(sp) + cfi_st v0, PT_R2, \docfi LONG_S v1, PT_STATUS(sp) - LONG_S $4, PT_R4(sp) + cfi_st $4, PT_R4, \docfi mfc0 v1, CP0_CAUSE - LONG_S $5, PT_R5(sp) + cfi_st $5, PT_R5, \docfi LONG_S v1, PT_CAUSE(sp) - LONG_S $6, PT_R6(sp) - MFC0 v1, CP0_EPC - LONG_S $7, PT_R7(sp) + cfi_st $6, PT_R6, \docfi + cfi_st ra, PT_R31, \docfi + MFC0 ra, CP0_EPC + cfi_st $7, PT_R7, \docfi #ifdef CONFIG_64BIT - LONG_S $8, PT_R8(sp) - LONG_S $9, PT_R9(sp) + cfi_st $8, PT_R8, \docfi + cfi_st $9, PT_R9, \docfi #endif - LONG_S v1, PT_EPC(sp) - LONG_S $25, PT_R25(sp) - LONG_S $28, PT_R28(sp) - LONG_S $31, PT_R31(sp) + LONG_S ra, PT_EPC(sp) + .if \docfi + .cfi_rel_offset ra, PT_EPC + .endif + cfi_st $25, PT_R25, \docfi + cfi_st $28, PT_R28, \docfi /* Set thread_info if we're coming from user mode */ mfc0 k0, CP0_STATUS @@ -232,21 +288,21 @@ .set pop .endm - .macro SAVE_ALL - SAVE_SOME - SAVE_AT - SAVE_TEMP - SAVE_STATIC + .macro SAVE_ALL docfi=0 + SAVE_SOME \docfi + SAVE_AT \docfi + SAVE_TEMP \docfi + SAVE_STATIC \docfi .endm - .macro RESTORE_AT + .macro RESTORE_AT docfi=0 .set push .set noat - LONG_L $1, PT_R1(sp) + cfi_ld $1, PT_R1, \docfi .set pop .endm - .macro RESTORE_TEMP + .macro RESTORE_TEMP docfi=0 #ifdef CONFIG_CPU_CAVIUM_OCTEON /* Restore the Octeon multiplier state */ jal octeon_mult_restore @@ -265,33 +321,37 @@ mthi $24 #endif #ifdef CONFIG_32BIT - LONG_L $8, PT_R8(sp) - LONG_L $9, PT_R9(sp) + cfi_ld $8, PT_R8, \docfi + cfi_ld $9, PT_R9, \docfi #endif - LONG_L $10, PT_R10(sp) - LONG_L $11, PT_R11(sp) - LONG_L $12, PT_R12(sp) - LONG_L $13, PT_R13(sp) - LONG_L $14, PT_R14(sp) - LONG_L $15, PT_R15(sp) - LONG_L $24, PT_R24(sp) + cfi_ld $10, PT_R10, \docfi + cfi_ld $11, PT_R11, \docfi + cfi_ld $12, PT_R12, \docfi + cfi_ld $13, PT_R13, \docfi + cfi_ld $14, PT_R14, \docfi + cfi_ld $15, PT_R15, \docfi + cfi_ld $24, PT_R24, \docfi .endm - .macro RESTORE_STATIC - LONG_L $16, PT_R16(sp) - LONG_L $17, PT_R17(sp) - LONG_L $18, PT_R18(sp) - LONG_L $19, PT_R19(sp) - LONG_L $20, PT_R20(sp) - LONG_L $21, PT_R21(sp) - LONG_L $22, PT_R22(sp) - LONG_L $23, PT_R23(sp) - LONG_L $30, PT_R30(sp) + .macro RESTORE_STATIC docfi=0 + cfi_ld $16, PT_R16, \docfi + cfi_ld $17, PT_R17, \docfi + cfi_ld $18, PT_R18, \docfi + cfi_ld $19, PT_R19, \docfi + cfi_ld $20, PT_R20, \docfi + cfi_ld $21, PT_R21, \docfi + cfi_ld $22, PT_R22, \docfi + cfi_ld $23, PT_R23, \docfi + cfi_ld $30, PT_R30, \docfi + .endm + + .macro RESTORE_SP docfi=0 + cfi_ld sp, PT_R29, \docfi .endm #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) - .macro RESTORE_SOME + .macro RESTORE_SOME docfi=0 .set push .set reorder .set noat @@ -306,30 +366,30 @@ and v0, v1 or v0, a0 mtc0 v0, CP0_STATUS - LONG_L $31, PT_R31(sp) - LONG_L $28, PT_R28(sp) - LONG_L $25, PT_R25(sp) - LONG_L $7, PT_R7(sp) - LONG_L $6, PT_R6(sp) - LONG_L $5, PT_R5(sp) - LONG_L $4, PT_R4(sp) - LONG_L $3, PT_R3(sp) - LONG_L $2, PT_R2(sp) + cfi_ld $31, PT_R31, \docfi + cfi_ld $28, PT_R28, \docfi + cfi_ld $25, PT_R25, \docfi + cfi_ld $7, PT_R7, \docfi + cfi_ld $6, PT_R6, \docfi + cfi_ld $5, PT_R5, \docfi + cfi_ld $4, PT_R4, \docfi + cfi_ld $3, PT_R3, \docfi + cfi_ld $2, PT_R2, \docfi .set pop .endm - .macro RESTORE_SP_AND_RET + .macro RESTORE_SP_AND_RET docfi=0 .set push .set noreorder LONG_L k0, PT_EPC(sp) - LONG_L sp, PT_R29(sp) + RESTORE_SP \docfi jr k0 rfe .set pop .endm #else - .macro RESTORE_SOME + .macro RESTORE_SOME docfi=0 .set push .set reorder .set noat @@ -346,24 +406,24 @@ mtc0 v0, CP0_STATUS LONG_L v1, PT_EPC(sp) MTC0 v1, CP0_EPC - LONG_L $31, PT_R31(sp) - LONG_L $28, PT_R28(sp) - LONG_L $25, PT_R25(sp) + cfi_ld $31, PT_R31, \docfi + cfi_ld $28, PT_R28, \docfi + cfi_ld $25, PT_R25, \docfi #ifdef CONFIG_64BIT - LONG_L $8, PT_R8(sp) - LONG_L $9, PT_R9(sp) + cfi_ld $8, PT_R8, \docfi + cfi_ld $9, PT_R9, \docfi #endif - LONG_L $7, PT_R7(sp) - LONG_L $6, PT_R6(sp) - LONG_L $5, PT_R5(sp) - LONG_L $4, PT_R4(sp) - LONG_L $3, PT_R3(sp) - LONG_L $2, PT_R2(sp) + cfi_ld $7, PT_R7, \docfi + cfi_ld $6, PT_R6, \docfi + cfi_ld $5, PT_R5, \docfi + cfi_ld $4, PT_R4, \docfi + cfi_ld $3, PT_R3, \docfi + cfi_ld $2, PT_R2, \docfi .set pop .endm - .macro RESTORE_SP_AND_RET - LONG_L sp, PT_R29(sp) + .macro RESTORE_SP_AND_RET docfi=0 + RESTORE_SP \docfi #ifdef CONFIG_CPU_MIPSR6 eretnc #else @@ -375,16 +435,12 @@ #endif - .macro RESTORE_SP - LONG_L sp, PT_R29(sp) - .endm - - .macro RESTORE_ALL - RESTORE_TEMP - RESTORE_STATIC - RESTORE_AT - RESTORE_SOME - RESTORE_SP + .macro RESTORE_ALL docfi=0 + RESTORE_TEMP \docfi + RESTORE_STATIC \docfi + RESTORE_AT \docfi + RESTORE_SOME \docfi + RESTORE_SP \docfi .endm /* diff --git a/arch/mips/include/asm/stackprotector.h b/arch/mips/include/asm/stackprotector.h index eb9b1035e926..68d4be9e1254 100644 --- a/arch/mips/include/asm/stackprotector.h +++ b/arch/mips/include/asm/stackprotector.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * GCC stack protector support. * diff --git a/arch/mips/include/asm/stacktrace.h b/arch/mips/include/asm/stacktrace.h index 780ee2c2a2ac..8ad25c25b4f8 100644 --- a/arch/mips/include/asm/stacktrace.h +++ b/arch/mips/include/asm/stacktrace.h @@ -1,7 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_STACKTRACE_H #define _ASM_STACKTRACE_H #include +#include +#include #ifdef CONFIG_KALLSYMS extern int raw_show_trace; @@ -20,6 +23,14 @@ static inline unsigned long unwind_stack(struct task_struct *task, } #endif +#define STR_PTR_LA __stringify(PTR_LA) +#define STR_LONG_S __stringify(LONG_S) +#define STR_LONG_L __stringify(LONG_L) +#define STR_LONGSIZE __stringify(LONGSIZE) + +#define STORE_ONE_REG(r) \ + STR_LONG_S " $" __stringify(r)",("STR_LONGSIZE"*"__stringify(r)")(%1)\n\t" + static __always_inline void prepare_frametrace(struct pt_regs *regs) { #ifndef CONFIG_KALLSYMS @@ -32,21 +43,47 @@ static __always_inline void prepare_frametrace(struct pt_regs *regs) __asm__ __volatile__( ".set push\n\t" ".set noat\n\t" -#ifdef CONFIG_64BIT - "1: dla $1, 1b\n\t" - "sd $1, %0\n\t" - "sd $29, %1\n\t" - "sd $31, %2\n\t" -#else - "1: la $1, 1b\n\t" - "sw $1, %0\n\t" - "sw $29, %1\n\t" - "sw $31, %2\n\t" -#endif + /* Store $1 so we can use it */ + STR_LONG_S " $1,"STR_LONGSIZE"(%1)\n\t" + /* Store the PC */ + "1: " STR_PTR_LA " $1, 1b\n\t" + STR_LONG_S " $1,%0\n\t" + STORE_ONE_REG(2) + STORE_ONE_REG(3) + STORE_ONE_REG(4) + STORE_ONE_REG(5) + STORE_ONE_REG(6) + STORE_ONE_REG(7) + STORE_ONE_REG(8) + STORE_ONE_REG(9) + STORE_ONE_REG(10) + STORE_ONE_REG(11) + STORE_ONE_REG(12) + STORE_ONE_REG(13) + STORE_ONE_REG(14) + STORE_ONE_REG(15) + STORE_ONE_REG(16) + STORE_ONE_REG(17) + STORE_ONE_REG(18) + STORE_ONE_REG(19) + STORE_ONE_REG(20) + STORE_ONE_REG(21) + STORE_ONE_REG(22) + STORE_ONE_REG(23) + STORE_ONE_REG(24) + STORE_ONE_REG(25) + STORE_ONE_REG(26) + STORE_ONE_REG(27) + STORE_ONE_REG(28) + STORE_ONE_REG(29) + STORE_ONE_REG(30) + STORE_ONE_REG(31) + /* Restore $1 */ + STR_LONG_L " $1,"STR_LONGSIZE"(%1)\n\t" ".set pop\n\t" - : "=m" (regs->cp0_epc), - "=m" (regs->regs[29]), "=m" (regs->regs[31]) - : : "memory"); + : "=m" (regs->cp0_epc) + : "r" (regs->regs) + : "memory"); } #endif /* _ASM_STACKTRACE_H */ diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index b439e512792b..5e8927f99a76 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* thread_info.h: MIPS low-level thread information * * Copyright (C) 2002 David Howells (dhowells@redhat.com) diff --git a/arch/mips/include/asm/tlb.h b/arch/mips/include/asm/tlb.h index 939734de4359..b6823b9e94da 100644 --- a/arch/mips/include/asm/tlb.h +++ b/arch/mips/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_TLB_H #define __ASM_TLB_H diff --git a/arch/mips/include/asm/tlbex.h b/arch/mips/include/asm/tlbex.h index 53050e9dd2c9..4ed7ebed3bf1 100644 --- a/arch/mips/include/asm/tlbex.h +++ b/arch/mips/include/asm/tlbex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_TLBEX_H #define __ASM_TLBEX_H diff --git a/arch/mips/include/asm/tlbflush.h b/arch/mips/include/asm/tlbflush.h index 86b21de12e91..40a361092491 100644 --- a/arch/mips/include/asm/tlbflush.h +++ b/arch/mips/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_TLBFLUSH_H #define __ASM_TLBFLUSH_H diff --git a/arch/mips/include/asm/tlbmisc.h b/arch/mips/include/asm/tlbmisc.h index 3a452282cba0..c1a540669c23 100644 --- a/arch/mips/include/asm/tlbmisc.h +++ b/arch/mips/include/asm/tlbmisc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_TLBMISC_H #define __ASM_TLBMISC_H diff --git a/arch/mips/include/asm/topology.h b/arch/mips/include/asm/topology.h index 7afda4150a59..0673d2d0f2e6 100644 --- a/arch/mips/include/asm/topology.h +++ b/arch/mips/include/asm/topology.h @@ -13,7 +13,7 @@ #ifdef CONFIG_SMP #define topology_physical_package_id(cpu) (cpu_data[cpu].package) -#define topology_core_id(cpu) (cpu_data[cpu].core) +#define topology_core_id(cpu) (cpu_core(&cpu_data[cpu])) #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) #define topology_sibling_cpumask(cpu) (&cpu_sibling_map[cpu]) #endif diff --git a/arch/mips/include/asm/txx9/boards.h b/arch/mips/include/asm/txx9/boards.h index cbe9476d963e..d45237befd3e 100644 --- a/arch/mips/include/asm/txx9/boards.h +++ b/arch/mips/include/asm/txx9/boards.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_TOSHIBA_JMR3927 BOARD_VEC(jmr3927_vec) #endif diff --git a/arch/mips/include/asm/vga.h b/arch/mips/include/asm/vga.h index f82c83749a08..0136e0366698 100644 --- a/arch/mips/include/asm/vga.h +++ b/arch/mips/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access to VGA videoram * @@ -6,6 +7,7 @@ #ifndef _ASM_VGA_H #define _ASM_VGA_H +#include #include #include @@ -40,9 +42,15 @@ static inline u16 scr_readw(volatile const u16 *addr) return le16_to_cpu(*addr); } +static inline void scr_memsetw(u16 *s, u16 v, unsigned int count) +{ + memset16(s, cpu_to_le16(v), count / 2); +} + #define scr_memcpyw(d, s, c) memcpy(d, s, c) #define scr_memmovew(d, s, c) memmove(d, s, c) #define VT_BUF_HAVE_MEMCPYW #define VT_BUF_HAVE_MEMMOVEW +#define VT_BUF_HAVE_MEMSETW #endif /* _ASM_VGA_H */ diff --git a/arch/mips/include/asm/yamon-dt.h b/arch/mips/include/asm/yamon-dt.h index 485cfe3e45e1..10a073e6877a 100644 --- a/arch/mips/include/asm/yamon-dt.h +++ b/arch/mips/include/asm/yamon-dt.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/include/uapi/asm/auxvec.h b/arch/mips/include/uapi/asm/auxvec.h index 45ba259a3618..612c2c41f60b 100644 --- a/arch/mips/include/uapi/asm/auxvec.h +++ b/arch/mips/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright (C) 2015 Imagination Technologies * Author: Alex Smith diff --git a/arch/mips/include/uapi/asm/bitfield.h b/arch/mips/include/uapi/asm/bitfield.h index ad9861359cea..b11713d8743e 100644 --- a/arch/mips/include/uapi/asm/bitfield.h +++ b/arch/mips/include/uapi/asm/bitfield.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/bitsperlong.h b/arch/mips/include/uapi/asm/bitsperlong.h index 3e4c10a8e787..7268380d8d28 100644 --- a/arch/mips/include/uapi/asm/bitsperlong.h +++ b/arch/mips/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_MIPS_BITSPERLONG_H #define __ASM_MIPS_BITSPERLONG_H diff --git a/arch/mips/include/uapi/asm/break.h b/arch/mips/include/uapi/asm/break.h index 9c4265cbf151..10380b1bc601 100644 --- a/arch/mips/include/uapi/asm/break.h +++ b/arch/mips/include/uapi/asm/break.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/byteorder.h b/arch/mips/include/uapi/asm/byteorder.h index 9579051ff1c7..b4edc85f9c30 100644 --- a/arch/mips/include/uapi/asm/byteorder.h +++ b/arch/mips/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/cachectl.h b/arch/mips/include/uapi/asm/cachectl.h index 230390908773..af7639ff423b 100644 --- a/arch/mips/include/uapi/asm/cachectl.h +++ b/arch/mips/include/uapi/asm/cachectl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/errno.h b/arch/mips/include/uapi/asm/errno.h index 02d645d7aa9a..2fb714e2d6d8 100644 --- a/arch/mips/include/uapi/asm/errno.h +++ b/arch/mips/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h index 6ca432f00860..42e13dead543 100644 --- a/arch/mips/include/uapi/asm/fcntl.h +++ b/arch/mips/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/hwcap.h b/arch/mips/include/uapi/asm/hwcap.h index c7484a7ca686..600ad8fd6835 100644 --- a/arch/mips/include/uapi/asm/hwcap.h +++ b/arch/mips/include/uapi/asm/hwcap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_HWCAP_H #define _UAPI_ASM_HWCAP_H diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index d61897535926..c05dcf5ab414 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Format of an instruction in memory. * @@ -981,7 +982,7 @@ struct mm16_r3_format { /* Load from global pointer format */ struct mm16_r5_format { /* Load/store from stack pointer format */ __BITFIELD_FIELD(unsigned int opcode : 6, __BITFIELD_FIELD(unsigned int rt : 5, - __BITFIELD_FIELD(signed int simmediate : 5, + __BITFIELD_FIELD(unsigned int imm : 5, __BITFIELD_FIELD(unsigned int : 16, /* Ignored */ ;)))) }; diff --git a/arch/mips/include/uapi/asm/ioctl.h b/arch/mips/include/uapi/asm/ioctl.h index c515a1a4c47c..1050a6ea211c 100644 --- a/arch/mips/include/uapi/asm/ioctl.h +++ b/arch/mips/include/uapi/asm/ioctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h index 1609cb0907ac..890245a9f0c4 100644 --- a/arch/mips/include/uapi/asm/ioctls.h +++ b/arch/mips/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h index 0318c6b442ab..edcf717c4327 100644 --- a/arch/mips/include/uapi/asm/kvm.h +++ b/arch/mips/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/mman.h b/arch/mips/include/uapi/asm/mman.h index 655e2fb5395b..20c3df7a8fdd 100644 --- a/arch/mips/include/uapi/asm/mman.h +++ b/arch/mips/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -91,20 +92,12 @@ overrides the coredump filter bits */ #define MADV_DODUMP 17 /* Clear the MADV_NODUMP flag */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + /* compatibility flags */ #define MAP_FILE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/arch/mips/include/uapi/asm/msgbuf.h b/arch/mips/include/uapi/asm/msgbuf.h index df849e87d9ae..eb4d0f9d7364 100644 --- a/arch/mips/include/uapi/asm/msgbuf.h +++ b/arch/mips/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_MSGBUF_H #define _ASM_MSGBUF_H diff --git a/arch/mips/include/uapi/asm/param.h b/arch/mips/include/uapi/asm/param.h index da3920fce9ad..3f337ed66f6a 100644 --- a/arch/mips/include/uapi/asm/param.h +++ b/arch/mips/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/poll.h b/arch/mips/include/uapi/asm/poll.h index 47b952080431..ad289d7b7434 100644 --- a/arch/mips/include/uapi/asm/poll.h +++ b/arch/mips/include/uapi/asm/poll.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_POLL_H #define __ASM_POLL_H diff --git a/arch/mips/include/uapi/asm/posix_types.h b/arch/mips/include/uapi/asm/posix_types.h index fa03ec3fbf89..6aa49c10f88f 100644 --- a/arch/mips/include/uapi/asm/posix_types.h +++ b/arch/mips/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/ptrace.h b/arch/mips/include/uapi/asm/ptrace.h index 91a3d197ede3..f3c025445e45 100644 --- a/arch/mips/include/uapi/asm/ptrace.h +++ b/arch/mips/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/reg.h b/arch/mips/include/uapi/asm/reg.h index 081e377f4f02..56d15cb8109f 100644 --- a/arch/mips/include/uapi/asm/reg.h +++ b/arch/mips/include/uapi/asm/reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Various register offset definitions for debuggers, core file * examiners and whatnot. diff --git a/arch/mips/include/uapi/asm/resource.h b/arch/mips/include/uapi/asm/resource.h index b26439d4ab0b..372ff8f4bc06 100644 --- a/arch/mips/include/uapi/asm/resource.h +++ b/arch/mips/include/uapi/asm/resource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/sembuf.h b/arch/mips/include/uapi/asm/sembuf.h index e1085ac880f2..2c0f507ab7d1 100644 --- a/arch/mips/include/uapi/asm/sembuf.h +++ b/arch/mips/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SEMBUF_H #define _ASM_SEMBUF_H diff --git a/arch/mips/include/uapi/asm/setup.h b/arch/mips/include/uapi/asm/setup.h index 93f237bb1353..7d48c433b0c2 100644 --- a/arch/mips/include/uapi/asm/setup.h +++ b/arch/mips/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_MIPS_SETUP_H #define _UAPI_MIPS_SETUP_H diff --git a/arch/mips/include/uapi/asm/sgidefs.h b/arch/mips/include/uapi/asm/sgidefs.h index 876442fcfb32..26143e3b7c26 100644 --- a/arch/mips/include/uapi/asm/sgidefs.h +++ b/arch/mips/include/uapi/asm/sgidefs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/shmbuf.h b/arch/mips/include/uapi/asm/shmbuf.h index f994438277bf..379e6bca518b 100644 --- a/arch/mips/include/uapi/asm/shmbuf.h +++ b/arch/mips/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SHMBUF_H #define _ASM_SHMBUF_H diff --git a/arch/mips/include/uapi/asm/sigcontext.h b/arch/mips/include/uapi/asm/sigcontext.h index 5cbd9ae6421f..d0a540e88bb4 100644 --- a/arch/mips/include/uapi/asm/sigcontext.h +++ b/arch/mips/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h index 8069cf766603..f17d8163dec6 100644 --- a/arch/mips/include/uapi/asm/siginfo.h +++ b/arch/mips/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -120,7 +121,7 @@ typedef struct siginfo { #undef SI_TIMER #undef SI_MESGQ #define SI_ASYNCIO -2 /* sent by AIO completion */ -#define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */ -#define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */ +#define SI_TIMER -3 /* sent by timer expiration */ +#define SI_MESGQ -4 /* sent by real time mesq state change */ #endif /* _UAPI_ASM_SIGINFO_H */ diff --git a/arch/mips/include/uapi/asm/signal.h b/arch/mips/include/uapi/asm/signal.h index addb9f556b71..53104b10aae2 100644 --- a/arch/mips/include/uapi/asm/signal.h +++ b/arch/mips/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 882823bec153..49c3d4795963 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -120,4 +121,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/mips/include/uapi/asm/sockios.h b/arch/mips/include/uapi/asm/sockios.h index 419fbe661da3..5b40a88593fa 100644 --- a/arch/mips/include/uapi/asm/sockios.h +++ b/arch/mips/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Socket-level I/O control calls. * diff --git a/arch/mips/include/uapi/asm/stat.h b/arch/mips/include/uapi/asm/stat.h index b47bc541bbc0..95416f366d7f 100644 --- a/arch/mips/include/uapi/asm/stat.h +++ b/arch/mips/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/statfs.h b/arch/mips/include/uapi/asm/statfs.h index 3305c834fc16..f4174dcaef5e 100644 --- a/arch/mips/include/uapi/asm/statfs.h +++ b/arch/mips/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/swab.h b/arch/mips/include/uapi/asm/swab.h index 23cd9b118c9e..d6795fe4ec59 100644 --- a/arch/mips/include/uapi/asm/swab.h +++ b/arch/mips/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/sysmips.h b/arch/mips/include/uapi/asm/sysmips.h index ae637e907856..4c009e10dfd2 100644 --- a/arch/mips/include/uapi/asm/sysmips.h +++ b/arch/mips/include/uapi/asm/sysmips.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Definitions for the MIPS sysmips(2) call * diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h index 2750203e1e7d..dfeffba729b7 100644 --- a/arch/mips/include/uapi/asm/termbits.h +++ b/arch/mips/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/termios.h b/arch/mips/include/uapi/asm/termios.h index baeb2fa87451..d6c576794178 100644 --- a/arch/mips/include/uapi/asm/termios.h +++ b/arch/mips/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/types.h b/arch/mips/include/uapi/asm/types.h index f3dd9ff0cc0c..6b21504842a4 100644 --- a/arch/mips/include/uapi/asm/types.h +++ b/arch/mips/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/include/uapi/asm/ucontext.h b/arch/mips/include/uapi/asm/ucontext.h index 2320144ce858..2d3bf8eebf1f 100644 --- a/arch/mips/include/uapi/asm/ucontext.h +++ b/arch/mips/include/uapi/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __MIPS_UAPI_ASM_UCONTEXT_H #define __MIPS_UAPI_ASM_UCONTEXT_H diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h index 78faf4292e90..bb05e9916a5f 100644 --- a/arch/mips/include/uapi/asm/unistd.h +++ b/arch/mips/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig index fb1e072da30b..06838f80a5d7 100644 --- a/arch/mips/jazz/Kconfig +++ b/arch/mips/jazz/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ACER_PICA_61 bool "Support for Acer PICA 1 chipset" depends on MACH_JAZZ diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index 11172fdaeffc..d626a9a391cc 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Mips Jazz DMA controller support * Copyright (C) 1995, 1996 by Andreas Busse diff --git a/arch/mips/jazz/reset.c b/arch/mips/jazz/reset.c index dd889fe86bd1..052b01f5d935 100644 --- a/arch/mips/jazz/reset.c +++ b/arch/mips/jazz/reset.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Reset a Jazz machine. * diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig index 36f82017695d..643af2012e14 100644 --- a/arch/mips/jz4740/Kconfig +++ b/arch/mips/jz4740/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "Machine type" depends on MACH_INGENIC diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index 6b9c1f7c31c9..88d6aa7d000b 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Ingenic JZ4740. # diff --git a/arch/mips/jz4740/reset.h b/arch/mips/jz4740/reset.h index 5202ab4ad9db..4e8746ee9b61 100644 --- a/arch/mips/jz4740/reset.h +++ b/arch/mips/jz4740/reset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MIPS_JZ4740_RESET_H__ #define __MIPS_JZ4740_RESET_H__ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 46c0581256f1..f10e1e15e1c6 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/MIPS kernel. # @@ -35,11 +36,15 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o -obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o -obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o -obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o -obj-$(CONFIG_CPU_CAVIUM_OCTEON) += r4k_fpu.o octeon_switch.o +sw-y := r4k_switch.o +sw-$(CONFIG_CPU_R3000) := r2300_switch.o +sw-$(CONFIG_CPU_TX39XX) := r2300_switch.o +sw-$(CONFIG_CPU_CAVIUM_OCTEON) := octeon_switch.o +obj-y += $(sw-y) + +obj-$(CONFIG_CPU_R4K_FPU) += r4k_fpu.o +obj-$(CONFIG_CPU_R3000) += r2300_fpu.o +obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP_UP) += smp-up.o diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index a670c0c11875..c1cd41456d42 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * asm-offsets.c: Calculate pt_regs and task_struct offsets. * diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 4a2ff3953b99..89b234844534 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for n32 Linux/MIPS ELF binaries. * Author: Ralf Baechle (ralf@linux-mips.org) diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 3916404e7fd1..a88c59db3d48 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for o32 Linux/MIPS ELF binaries. * Author: Ralf Baechle (ralf@linux-mips.org) diff --git a/arch/mips/kernel/cmpxchg.c b/arch/mips/kernel/cmpxchg.c index 7730f1d3434f..0b9535bc2c53 100644 --- a/arch/mips/kernel/cmpxchg.c +++ b/arch/mips/kernel/cmpxchg.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2017 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/kernel/cps-vec-ns16550.S b/arch/mips/kernel/cps-vec-ns16550.S index 6d246ad05638..b37af23a5358 100644 --- a/arch/mips/kernel/cps-vec-ns16550.S +++ b/arch/mips/kernel/cps-vec-ns16550.S @@ -1,6 +1,6 @@ /* * Copyright (C) 2015 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S index b849fe6aad94..c7ed26029cbb 100644 --- a/arch/mips/kernel/cps-vec.S +++ b/arch/mips/kernel/cps-vec.S @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -327,8 +327,8 @@ LEAF(mips_cps_get_bootcfg) * to handle contiguous VP numbering, but no such systems yet * exist. */ - mfc0 t9, $3, 1 - andi t9, t9, 0xff + mfc0 t9, CP0_GLOBALNUMBER + andi t9, t9, MIPS_GLOBALNUMBER_VP #elif defined(CONFIG_MIPS_MT_SMP) has_mt ta2, 1f diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index d08afc7dc507..cf3fd549e16d 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -326,7 +326,7 @@ static int __init fpu_disable(char *s) __setup("nofpu", fpu_disable); -int mips_dsp_disabled; +static int mips_dsp_disabled; static int __init dsp_disable(char *s) { @@ -919,9 +919,12 @@ static void decode_configs(struct cpuinfo_mips *c) #ifndef CONFIG_MIPS_CPS if (cpu_has_mips_r2_r6) { - c->core = get_ebase_cpunum(); + unsigned int core; + + core = get_ebase_cpunum(); if (cpu_has_mipsmt) - c->core >>= fls(core_nvpes()) - 1; + core >>= fls(core_nvpes()) - 1; + cpu_set_core(c, core); } #endif } @@ -1394,24 +1397,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) MIPS_CPU_DIVEC | MIPS_CPU_LLSC; c->tlbsize = 48; break; - case PRID_IMP_R6000: - c->cputype = CPU_R6000; - __cpu_name[cpu] = "R6000"; - set_isa(c, MIPS_CPU_ISA_II); - c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; - case PRID_IMP_R6000A: - c->cputype = CPU_R6000A; - __cpu_name[cpu] = "R6000A"; - set_isa(c, MIPS_CPU_ISA_II); - c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS; - c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | - MIPS_CPU_LLSC; - c->tlbsize = 32; - break; case PRID_IMP_RM7000: c->cputype = CPU_RM7000; __cpu_name[cpu] = "RM7000"; @@ -2113,3 +2098,35 @@ void cpu_report(void) if (cpu_has_msa) pr_info("MSA revision is: %08x\n", c->msa_id); } + +void cpu_set_cluster(struct cpuinfo_mips *cpuinfo, unsigned int cluster) +{ + /* Ensure the core number fits in the field */ + WARN_ON(cluster > (MIPS_GLOBALNUMBER_CLUSTER >> + MIPS_GLOBALNUMBER_CLUSTER_SHF)); + + cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CLUSTER; + cpuinfo->globalnumber |= cluster << MIPS_GLOBALNUMBER_CLUSTER_SHF; +} + +void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core) +{ + /* Ensure the core number fits in the field */ + WARN_ON(core > (MIPS_GLOBALNUMBER_CORE >> MIPS_GLOBALNUMBER_CORE_SHF)); + + cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CORE; + cpuinfo->globalnumber |= core << MIPS_GLOBALNUMBER_CORE_SHF; +} + +void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe) +{ + /* Ensure the VP(E) ID fits in the field */ + WARN_ON(vpe > (MIPS_GLOBALNUMBER_VP >> MIPS_GLOBALNUMBER_VP_SHF)); + + /* Ensure we're not using VP(E)s without support */ + WARN_ON(vpe && !IS_ENABLED(CONFIG_MIPS_MT_SMP) && + !IS_ENABLED(CONFIG_CPU_MIPSR6)); + + cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_VP; + cpuinfo->globalnumber |= vpe << MIPS_GLOBALNUMBER_VP_SHF; +} diff --git a/arch/mips/kernel/crash.c b/arch/mips/kernel/crash.c index ca25cd393b1c..d455363d51c3 100644 --- a/arch/mips/kernel/crash.c +++ b/arch/mips/kernel/crash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c index 77ee99a2d0aa..a8657d29c62e 100644 --- a/arch/mips/kernel/crash_dump.c +++ b/arch/mips/kernel/crash_dump.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 5c429d70e17f..731325a61a78 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -87,6 +87,7 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, bool elf32; u32 flags; int ret; + loff_t pos; elf32 = ehdr->e32.e_ident[EI_CLASS] == ELFCLASS32; flags = elf32 ? ehdr->e32.e_flags : ehdr->e64.e_flags; @@ -108,21 +109,16 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, if (phdr32->p_filesz < sizeof(abiflags)) return -EINVAL; - - ret = kernel_read(elf, phdr32->p_offset, - (char *)&abiflags, - sizeof(abiflags)); + pos = phdr32->p_offset; } else { if (phdr64->p_type != PT_MIPS_ABIFLAGS) return 0; if (phdr64->p_filesz < sizeof(abiflags)) return -EINVAL; - - ret = kernel_read(elf, phdr64->p_offset, - (char *)&abiflags, - sizeof(abiflags)); + pos = phdr64->p_offset; } + ret = kernel_read(elf, &abiflags, sizeof(abiflags), &pos); if (ret < 0) return ret; if (ret != sizeof(abiflags)) diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 9d9b8fbae202..99285be0e088 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Code for replacing ftrace calls with jumps. * diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index ae810da4d499..37b9383eacd3 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -150,6 +150,7 @@ LEAF(__r4k_wait) .align 5 BUILD_ROLLBACK_PROLOGUE handle_int NESTED(handle_int, PT_SIZE, sp) + .cfi_signal_frame #ifdef CONFIG_TRACE_IRQFLAGS /* * Check to see if the interrupted code has just disabled @@ -181,7 +182,7 @@ NESTED(handle_int, PT_SIZE, sp) 1: .set pop #endif - SAVE_ALL + SAVE_ALL docfi=1 CLI TRACE_IRQS_OFF @@ -269,8 +270,8 @@ NESTED(except_vec_ejtag_debug, 0, sp) */ BUILD_ROLLBACK_PROLOGUE except_vec_vi NESTED(except_vec_vi, 0, sp) - SAVE_SOME - SAVE_AT + SAVE_SOME docfi=1 + SAVE_AT docfi=1 .set push .set noreorder PTR_LA v1, except_vec_vi_handler @@ -396,6 +397,7 @@ NESTED(except_vec_nmi, 0, sp) __FINIT NESTED(nmi_handler, PT_SIZE, sp) + .cfi_signal_frame .set push .set noat /* @@ -478,6 +480,7 @@ NESTED(nmi_handler, PT_SIZE, sp) .macro __BUILD_HANDLER exception handler clear verbose ext .align 5 NESTED(handle_\exception, PT_SIZE, sp) + .cfi_signal_frame .set noat SAVE_ALL FEXPORT(handle_\exception\ext) @@ -485,8 +488,8 @@ NESTED(nmi_handler, PT_SIZE, sp) .set at __BUILD_\verbose \exception move a0, sp - PTR_LA ra, ret_from_exception - j do_\handler + jal do_\handler + j ret_from_exception END(handle_\exception) .endm diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c index c5bc344fc745..5f209f111e59 100644 --- a/arch/mips/kernel/i8253.c +++ b/arch/mips/kernel/i8253.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * i8253.c 8253/PIT functions * diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c index 60ab4c44d305..7c246b69c545 100644 --- a/arch/mips/kernel/idle.c +++ b/arch/mips/kernel/idle.c @@ -11,6 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include #include #include #include diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index b01bdef101a8..b332f6fc1e72 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Conversion between 32-bit and 64-bit native system calls. * diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index cb0c57f860d4..dd5567b1e305 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -12,10 +12,10 @@ #include #include -#include +#include #include -void __iomem *mips_cm_base; +void __iomem *mips_gcr_base; void __iomem *mips_cm_l2sync_base; int mips_cm_is64; @@ -167,8 +167,8 @@ phys_addr_t __mips_cm_l2sync_phys_base(void) * current location. */ base_reg = read_gcr_l2_only_sync_base(); - if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK) - return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK; + if (base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN) + return base_reg & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE; /* Default to following the CM */ return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; @@ -183,19 +183,19 @@ static void mips_cm_probe_l2sync(void) phys_addr_t addr; /* L2-only sync was introduced with CM major revision 6 */ - major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> - CM_GCR_REV_MAJOR_SHF; + major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >> + __ffs(CM_GCR_REV_MAJOR); if (major_rev < 6) return; /* Find a location for the L2 sync region */ addr = mips_cm_l2sync_phys_base(); - BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE_MSK) != addr); + BUG_ON((addr & CM_GCR_L2_ONLY_SYNC_BASE_SYNCBASE) != addr); if (!addr) return; /* Set the region base address & enable it */ - write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN_MSK); + write_gcr_l2_only_sync_base(addr | CM_GCR_L2_ONLY_SYNC_BASE_SYNCEN); /* Map the region */ mips_cm_l2sync_base = ioremap_nocache(addr, MIPS_CM_L2SYNC_SIZE); @@ -211,41 +211,39 @@ int mips_cm_probe(void) * No need to probe again if we have already been * here before. */ - if (mips_cm_base) + if (mips_gcr_base) return 0; addr = mips_cm_phys_base(); - BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr); + BUG_ON((addr & CM_GCR_BASE_GCRBASE) != addr); if (!addr) return -ENODEV; - mips_cm_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE); - if (!mips_cm_base) + mips_gcr_base = ioremap_nocache(addr, MIPS_CM_GCR_SIZE); + if (!mips_gcr_base) return -ENXIO; /* sanity check that we're looking at a CM */ base_reg = read_gcr_base(); - if ((base_reg & CM_GCR_BASE_GCRBASE_MSK) != addr) { + if ((base_reg & CM_GCR_BASE_GCRBASE) != addr) { pr_err("GCRs appear to have been moved (expected them at 0x%08lx)!\n", (unsigned long)addr); - mips_cm_base = NULL; + mips_gcr_base = NULL; return -ENODEV; } /* set default target to memory */ - base_reg &= ~CM_GCR_BASE_CMDEFTGT_MSK; - base_reg |= CM_GCR_BASE_CMDEFTGT_MEM; - write_gcr_base(base_reg); + change_gcr_base(CM_GCR_BASE_CMDEFTGT, CM_GCR_BASE_CMDEFTGT_MEM); /* disable CM regions */ - write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); - write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); - write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); - write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR_MSK); - write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK_MSK); + write_gcr_reg0_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg0_mask(CM_GCR_REGn_MASK_ADDRMASK); + write_gcr_reg1_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg1_mask(CM_GCR_REGn_MASK_ADDRMASK); + write_gcr_reg2_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg2_mask(CM_GCR_REGn_MASK_ADDRMASK); + write_gcr_reg3_base(CM_GCR_REGn_BASE_BASEADDR); + write_gcr_reg3_mask(CM_GCR_REGn_MASK_ADDRMASK); /* probe for an L2-only sync region */ mips_cm_probe_l2sync(); @@ -259,16 +257,27 @@ int mips_cm_probe(void) return 0; } -void mips_cm_lock_other(unsigned int core, unsigned int vp) +void mips_cm_lock_other(unsigned int cluster, unsigned int core, + unsigned int vp, unsigned int block) { - unsigned curr_core; + unsigned int curr_core, cm_rev; u32 val; + cm_rev = mips_cm_revision(); preempt_disable(); - if (mips_cm_revision() >= CM_REV_CM3) { - val = core << CM3_GCR_Cx_OTHER_CORE_SHF; - val |= vp << CM3_GCR_Cx_OTHER_VP_SHF; + if (cm_rev >= CM_REV_CM3) { + val = core << __ffs(CM3_GCR_Cx_OTHER_CORE); + val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP); + + if (cm_rev >= CM_REV_CM3_5) { + val |= CM_GCR_Cx_OTHER_CLUSTER_EN; + val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER); + val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK); + } else { + WARN_ON(cluster != 0); + WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL); + } /* * We need to disable interrupts in SMP systems in order to @@ -282,18 +291,20 @@ void mips_cm_lock_other(unsigned int core, unsigned int vp) spin_lock_irqsave(this_cpu_ptr(&cm_core_lock), *this_cpu_ptr(&cm_core_lock_flags)); } else { + WARN_ON(cluster != 0); WARN_ON(vp != 0); + WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL); /* * We only have a GCR_CL_OTHER per core in systems with * CM 2.5 & older, so have to ensure other VP(E)s don't * race with us. */ - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core)); - val = core << CM_GCR_Cx_OTHER_CORENUM_SHF; + val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM); } write_gcr_cl_other(val); @@ -310,7 +321,7 @@ void mips_cm_unlock_other(void) unsigned int curr_core; if (mips_cm_revision() < CM_REV_CM3) { - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_unlock_irqrestore(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core)); } else { @@ -332,13 +343,13 @@ void mips_cm_error_report(void) return; revision = mips_cm_revision(); + cm_error = read_gcr_error_cause(); + cm_addr = read_gcr_error_addr(); + cm_other = read_gcr_error_mult(); if (revision < CM_REV_CM3) { /* CM2 */ - cm_error = read_gcr_error_cause(); - cm_addr = read_gcr_error_addr(); - cm_other = read_gcr_error_mult(); - cause = cm_error >> CM_GCR_ERROR_CAUSE_ERRTYPE_SHF; - ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF; + cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE); + ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); if (!cause) return; @@ -380,11 +391,8 @@ void mips_cm_error_report(void) ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits; ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit; - cm_error = read64_gcr_error_cause(); - cm_addr = read64_gcr_error_addr(); - cm_other = read64_gcr_error_mult(); - cause = cm_error >> CM3_GCR_ERROR_CAUSE_ERRTYPE_SHF; - ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF; + cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE); + ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); if (!cause) return; diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index a4964c334cab..19c88d770054 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -12,8 +12,7 @@ #include #include -#include -#include +#include void __iomem *mips_cpc_base; @@ -40,13 +39,13 @@ static phys_addr_t mips_cpc_phys_base(void) if (!mips_cm_present()) return 0; - if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX_MSK)) + if (!(read_gcr_cpc_status() & CM_GCR_CPC_STATUS_EX)) return 0; /* If the CPC is already enabled, leave it so */ cpc_base = read_gcr_cpc_base(); - if (cpc_base & CM_GCR_CPC_BASE_CPCEN_MSK) - return cpc_base & CM_GCR_CPC_BASE_CPCBASE_MSK; + if (cpc_base & CM_GCR_CPC_BASE_CPCEN) + return cpc_base & CM_GCR_CPC_BASE_CPCBASE; /* Otherwise, use the default address */ cpc_base = mips_cpc_default_phys_base(); @@ -54,7 +53,7 @@ static phys_addr_t mips_cpc_phys_base(void) return cpc_base; /* Enable the CPC, mapped at the default address */ - write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN_MSK); + write_gcr_cpc_base(cpc_base | CM_GCR_CPC_BASE_CPCEN); return cpc_base; } @@ -86,10 +85,10 @@ void mips_cpc_lock_other(unsigned int core) return; preempt_disable(); - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); - write_cpc_cl_other(core << CPC_Cx_OTHER_CORENUM_SHF); + write_cpc_cl_other(core << __ffs(CPC_Cx_OTHER_CORENUM)); /* * Ensure the core-other region reflects the appropriate core & @@ -106,7 +105,7 @@ void mips_cpc_unlock_other(void) /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ return; - curr_core = current_cpu_data.core; + curr_core = cpu_core(¤t_cpu_data); spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); preempt_enable(); diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c index 8cab633e0e5a..a7c0f97e4b0d 100644 --- a/arch/mips/kernel/mips-mt-fpaff.c +++ b/arch/mips/kernel/mips-mt-fpaff.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * General MIPS MT support routines, usable in AP/SP and SMVP. * Copyright (C) 2005 Mips Technologies, Inc diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c index 88b1ef5f868a..efaa2527657d 100644 --- a/arch/mips/kernel/mips-mt.c +++ b/arch/mips/kernel/mips-mt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * General MIPS MT support routines, usable in AP/SP and SMVP. * Copyright (C) 2005 Mips Technologies, Inc diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index ae64c8f56a8c..eb18b186e858 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -46,9 +46,11 @@ #define LL "ll " #define SC "sc " -DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats); -DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats); -DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats); +#ifdef CONFIG_DEBUG_FS +static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2emustats); +static DEFINE_PER_CPU(struct mips_r2_emulator_stats, mipsr2bdemustats); +static DEFINE_PER_CPU(struct mips_r2br_emulator_stats, mipsr2bremustats); +#endif extern const unsigned int fpucondbit[8]; @@ -600,7 +602,7 @@ static int ddivu_func(struct pt_regs *regs, u32 ir) } /* R6 removed instructions for the SPECIAL opcode */ -static struct r2_decoder_table spec_op_table[] = { +static const struct r2_decoder_table spec_op_table[] = { { 0xfc1ff83f, 0x00000008, jr_func }, { 0xfc00ffff, 0x00000018, mult_func }, { 0xfc00ffff, 0x00000019, multu_func }, @@ -867,7 +869,7 @@ static int dclo_func(struct pt_regs *regs, u32 ir) } /* R6 removed instructions for the SPECIAL2 opcode */ -static struct r2_decoder_table spec2_op_table[] = { +static const struct r2_decoder_table spec2_op_table[] = { { 0xfc00ffff, 0x70000000, madd_func }, { 0xfc00ffff, 0x70000001, maddu_func }, { 0xfc0007ff, 0x70000002, mul_func }, @@ -881,9 +883,9 @@ static struct r2_decoder_table spec2_op_table[] = { }; static inline int mipsr2_find_op_func(struct pt_regs *regs, u32 inst, - struct r2_decoder_table *table) + const struct r2_decoder_table *table) { - struct r2_decoder_table *p; + const struct r2_decoder_table *p; int err; for (p = table; p->func; p++) { diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S index 3375745b9198..e42113fe2762 100644 --- a/arch/mips/kernel/octeon_switch.S +++ b/arch/mips/kernel/octeon_switch.S @@ -10,12 +10,13 @@ * Copyright (C) 2000 MIPS Technologies, Inc. * written by Carsten Langgaard, carstenl@mips.com */ +#include +#include +#include +#include +#include +#include -#define USE_ALTERNATE_RESUME_IMPL 1 - .set push - .set arch=mips64r2 -#include "r4k_switch.S" - .set pop /* * task_struct *resume(task_struct *prev, task_struct *next, * struct thread_info *next_ti) diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 9e6c74bf66c4..6668f67a61c3 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -618,8 +618,7 @@ static int mipspmu_event_init(struct perf_event *event) return -ENOENT; } - if ((unsigned int)event->cpu >= nr_cpumask_bits || - (event->cpu >= 0 && !cpu_online(event->cpu))) + if (event->cpu >= 0 && !cpu_online(event->cpu)) return -ENODEV; if (!atomic_inc_not_zero(&active_events)) { diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index d99416094ba9..9dd624c2fe56 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,8 +17,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -49,7 +48,7 @@ static DEFINE_PER_CPU_READ_MOSTLY(cps_nc_entry_fn[CPS_PM_STATE_COUNT], nc_asm_enter); /* Bitmap indicating which states are supported by the system */ -DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT); +static DECLARE_BITMAP(state_support, CPS_PM_STATE_COUNT); /* * Indicates the number of coupled VPEs ready to operate in a non-coherent @@ -114,7 +113,7 @@ static void coupled_barrier(atomic_t *a, unsigned online) int cps_pm_enter_state(enum cps_pm_state state) { unsigned cpu = smp_processor_id(); - unsigned core = current_cpu_data.core; + unsigned core = cpu_core(¤t_cpu_data); unsigned online, left; cpumask_t *coupled_mask = this_cpu_ptr(&online_coupled); u32 *core_ready_count, *nc_core_ready_count; @@ -486,7 +485,7 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * defined by the interAptiv & proAptiv SUMs as ensuring that the * operation resulting from the preceding store is complete. */ - uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); + uasm_i_addiu(&p, t0, zero, 1 << cpu_core(&cpu_data[cpu])); uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); @@ -569,8 +568,8 @@ static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * rest will just be performing a rather unusual nop. */ uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3 - ? CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK - : CM3_GCR_Cx_COHERENCE_COHEN_MSK); + ? CM_GCR_Cx_COHERENCE_COHDOMAINEN + : CM3_GCR_Cx_COHERENCE_COHEN); uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); @@ -640,7 +639,7 @@ out_err: static int cps_pm_online_cpu(unsigned int cpu) { enum cps_pm_state state; - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); void *entry_fn, *core_rc; for (state = CPS_PM_NC_WAIT; state < CPS_PM_STATE_COUNT; state++) { @@ -692,7 +691,7 @@ static int __init cps_pm_init(void) /* Detect whether a CPC is present */ if (mips_cpc_present()) { /* Detect whether clock gating is implemented */ - if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL_MSK) + if (read_cpc_cl_stat_conf() & CPC_Cx_STAT_CONF_CLKGAT_IMPL) set_bit(CPS_PM_CLOCK_GATED, state_support); else pr_warn("pm-cps: CPC does not support clock gating\n"); diff --git a/arch/mips/kernel/probes-common.h b/arch/mips/kernel/probes-common.h index dd08e41134b6..d2bf77b18822 100644 --- a/arch/mips/kernel/probes-common.h +++ b/arch/mips/kernel/probes-common.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Marcin Nowakowski + * Author: Marcin Nowakowski * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 70604c753aa4..b2de408a259e 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1995, 1996, 2001 Ralf Baechle * Copyright (C) 2001, 2004 MIPS Technologies, Inc. @@ -134,13 +135,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "kscratch registers\t: %d\n", hweight8(cpu_data[n].kscratch_mask)); seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); - seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); + seq_printf(m, "core\t\t\t: %d\n", cpu_core(&cpu_data[n])); #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) if (cpu_has_mipsmt) - seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); + seq_printf(m, "VPE\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n])); else if (cpu_has_vp) - seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id); + seq_printf(m, "VP\t\t\t: %d\n", cpu_vpe_id(&cpu_data[n])); #endif sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 5351e1f3950d..c5ff6bfe2825 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -208,13 +208,13 @@ static inline int is_ra_save_ins(union mips_instruction *ip, int *poff) * * microMIPS is way more fun... */ - if (mm_insn_16bit(ip->halfword[1])) { + if (mm_insn_16bit(ip->word >> 16)) { switch (ip->mm16_r5_format.opcode) { case mm_swsp16_op: if (ip->mm16_r5_format.rt != 31) return 0; - *poff = ip->mm16_r5_format.simmediate; + *poff = ip->mm16_r5_format.imm; *poff = (*poff << 2) / sizeof(ulong); return 1; @@ -287,7 +287,7 @@ static inline int is_jump_ins(union mips_instruction *ip) * * microMIPS is kind of more fun... */ - if (mm_insn_16bit(ip->halfword[1])) { + if (mm_insn_16bit(ip->word >> 16)) { if ((ip->mm16_r5_format.opcode == mm_pool16c_op && (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op)) return 1; @@ -313,9 +313,11 @@ static inline int is_jump_ins(union mips_instruction *ip) #endif } -static inline int is_sp_move_ins(union mips_instruction *ip) +static inline int is_sp_move_ins(union mips_instruction *ip, int *frame_size) { #ifdef CONFIG_CPU_MICROMIPS + unsigned short tmp; + /* * addiusp -imm * addius5 sp,-imm @@ -324,21 +326,40 @@ static inline int is_sp_move_ins(union mips_instruction *ip) * * microMIPS is not more fun... */ - if (mm_insn_16bit(ip->halfword[1])) { - return (ip->mm16_r3_format.opcode == mm_pool16d_op && - ip->mm16_r3_format.simmediate && mm_addiusp_func) || - (ip->mm16_r5_format.opcode == mm_pool16d_op && - ip->mm16_r5_format.rt == 29); + if (mm_insn_16bit(ip->word >> 16)) { + if (ip->mm16_r3_format.opcode == mm_pool16d_op && + ip->mm16_r3_format.simmediate & mm_addiusp_func) { + tmp = ip->mm_b0_format.simmediate >> 1; + tmp = ((tmp & 0x1ff) ^ 0x100) - 0x100; + if ((tmp + 2) < 4) /* 0x0,0x1,0x1fe,0x1ff are special */ + tmp ^= 0x100; + *frame_size = -(signed short)(tmp << 2); + return 1; + } + if (ip->mm16_r5_format.opcode == mm_pool16d_op && + ip->mm16_r5_format.rt == 29) { + tmp = ip->mm16_r5_format.imm >> 1; + *frame_size = -(signed short)(tmp & 0xf); + return 1; + } + return 0; } - return ip->mm_i_format.opcode == mm_addiu32_op && - ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; + if (ip->mm_i_format.opcode == mm_addiu32_op && + ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29) { + *frame_size = -ip->i_format.simmediate; + return 1; + } #else /* addiu/daddiu sp,sp,-imm */ if (ip->i_format.rs != 29 || ip->i_format.rt != 29) return 0; - if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) + + if (ip->i_format.opcode == addiu_op || + ip->i_format.opcode == daddiu_op) { + *frame_size = -ip->i_format.simmediate; return 1; + } #endif return 0; } @@ -348,7 +369,9 @@ static int get_frame_info(struct mips_frame_info *info) bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS); union mips_instruction insn, *ip, *ip_end; const unsigned int max_insns = 128; + unsigned int last_insn_size = 0; unsigned int i; + bool saw_jump = false; info->pc_offset = -1; info->frame_size = 0; @@ -359,47 +382,44 @@ static int get_frame_info(struct mips_frame_info *info) ip_end = (void *)ip + info->func_size; - for (i = 0; i < max_insns && ip < ip_end; i++, ip++) { + for (i = 0; i < max_insns && ip < ip_end; i++) { + ip = (void *)ip + last_insn_size; if (is_mmips && mm_insn_16bit(ip->halfword[0])) { - insn.halfword[0] = 0; - insn.halfword[1] = ip->halfword[0]; + insn.word = ip->halfword[0] << 16; + last_insn_size = 2; } else if (is_mmips) { - insn.halfword[0] = ip->halfword[1]; - insn.halfword[1] = ip->halfword[0]; + insn.word = ip->halfword[0] << 16 | ip->halfword[1]; + last_insn_size = 4; } else { insn.word = ip->word; + last_insn_size = 4; } - if (is_jump_ins(&insn)) - break; - if (!info->frame_size) { - if (is_sp_move_ins(&insn)) - { -#ifdef CONFIG_CPU_MICROMIPS - if (mm_insn_16bit(ip->halfword[0])) - { - unsigned short tmp; - - if (ip->halfword[0] & mm_addiusp_func) - { - tmp = (((ip->halfword[0] >> 1) & 0x1ff) << 2); - info->frame_size = -(signed short)(tmp | ((tmp & 0x100) ? 0xfe00 : 0)); - } else { - tmp = (ip->halfword[0] >> 1); - info->frame_size = -(signed short)(tmp & 0xf); - } - ip = (void *) &ip->halfword[1]; - ip--; - } else -#endif - info->frame_size = - ip->i_format.simmediate; - } + is_sp_move_ins(&insn, &info->frame_size); + continue; + } else if (!saw_jump && is_jump_ins(ip)) { + /* + * If we see a jump instruction, we are finished + * with the frame save. + * + * Some functions can have a shortcut return at + * the beginning of the function, so don't start + * looking for jump instruction until we see the + * frame setup. + * + * The RA save instruction can get put into the + * delay slot of the jump instruction, so look + * at the next instruction, too. + */ + saw_jump = true; continue; } if (info->pc_offset == -1 && is_ra_save_ins(&insn, &info->pc_offset)) break; + if (saw_jump) + break; } if (info->frame_size && info->pc_offset >= 0) /* nested */ return 0; diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S index 918f2f6d3861..3062ba66c563 100644 --- a/arch/mips/kernel/r2300_fpu.S +++ b/arch/mips/kernel/r2300_fpu.S @@ -12,7 +12,9 @@ * Copyright (c) 1998 Harald Koerfgen */ #include +#include #include +#include #include #include #include @@ -31,9 +33,85 @@ PTR 9b+4,bad_stack; \ .previous - .set noreorder .set mips1 +/* + * Save a thread's fp context. + */ +LEAF(_save_fp) +EXPORT_SYMBOL(_save_fp) + fpu_save_single a0, t1 # clobbers t1 + jr ra + END(_save_fp) + +/* + * Restore a thread's fp context. + */ +LEAF(_restore_fp) + fpu_restore_single a0, t1 # clobbers t1 + jr ra + END(_restore_fp) + +/* + * Load the FPU with signalling NANS. This bit pattern we're using has + * the property that no matter whether considered as single or as double + * precision represents signaling NANS. + * + * The value to initialize fcr31 to comes in $a0. + */ + + .set push + SET_HARDFLOAT + +LEAF(_init_fpu) + mfc0 t0, CP0_STATUS + li t1, ST0_CU1 + or t0, t1 + mtc0 t0, CP0_STATUS + + ctc1 a0, fcr31 + + li t0, -1 + + mtc1 t0, $f0 + mtc1 t0, $f1 + mtc1 t0, $f2 + mtc1 t0, $f3 + mtc1 t0, $f4 + mtc1 t0, $f5 + mtc1 t0, $f6 + mtc1 t0, $f7 + mtc1 t0, $f8 + mtc1 t0, $f9 + mtc1 t0, $f10 + mtc1 t0, $f11 + mtc1 t0, $f12 + mtc1 t0, $f13 + mtc1 t0, $f14 + mtc1 t0, $f15 + mtc1 t0, $f16 + mtc1 t0, $f17 + mtc1 t0, $f18 + mtc1 t0, $f19 + mtc1 t0, $f20 + mtc1 t0, $f21 + mtc1 t0, $f22 + mtc1 t0, $f23 + mtc1 t0, $f24 + mtc1 t0, $f25 + mtc1 t0, $f26 + mtc1 t0, $f27 + mtc1 t0, $f28 + mtc1 t0, $f29 + mtc1 t0, $f30 + mtc1 t0, $f31 + jr ra + END(_init_fpu) + + .set pop + + .set noreorder + /** * _save_fp_context() - save FP context from the FPU * @a0 - pointer to fpregs field of sigcontext diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 1049eeafd97d..665897139f30 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * r2300_switch.S: R2300 specific task switching code. * @@ -25,12 +26,6 @@ .set mips1 .align 5 -/* - * Offset to the current process status flags, the first 32 bytes of the - * stack are not used. - */ -#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS) - /* * task_struct *resume(task_struct *prev, task_struct *next, * struct thread_info *next_ti) @@ -68,78 +63,3 @@ LEAF(resume) move v0, a0 jr ra END(resume) - -/* - * Save a thread's fp context. - */ -LEAF(_save_fp) -EXPORT_SYMBOL(_save_fp) - fpu_save_single a0, t1 # clobbers t1 - jr ra - END(_save_fp) - -/* - * Restore a thread's fp context. - */ -LEAF(_restore_fp) - fpu_restore_single a0, t1 # clobbers t1 - jr ra - END(_restore_fp) - -/* - * Load the FPU with signalling NANS. This bit pattern we're using has - * the property that no matter whether considered as single or as double - * precision represents signaling NANS. - * - * The value to initialize fcr31 to comes in $a0. - */ - - .set push - SET_HARDFLOAT - -LEAF(_init_fpu) - mfc0 t0, CP0_STATUS - li t1, ST0_CU1 - or t0, t1 - mtc0 t0, CP0_STATUS - - ctc1 a0, fcr31 - - li t0, -1 - - mtc1 t0, $f0 - mtc1 t0, $f1 - mtc1 t0, $f2 - mtc1 t0, $f3 - mtc1 t0, $f4 - mtc1 t0, $f5 - mtc1 t0, $f6 - mtc1 t0, $f7 - mtc1 t0, $f8 - mtc1 t0, $f9 - mtc1 t0, $f10 - mtc1 t0, $f11 - mtc1 t0, $f12 - mtc1 t0, $f13 - mtc1 t0, $f14 - mtc1 t0, $f15 - mtc1 t0, $f16 - mtc1 t0, $f17 - mtc1 t0, $f18 - mtc1 t0, $f19 - mtc1 t0, $f20 - mtc1 t0, $f21 - mtc1 t0, $f22 - mtc1 t0, $f23 - mtc1 t0, $f24 - mtc1 t0, $f25 - mtc1 t0, $f26 - mtc1 t0, $f27 - mtc1 t0, $f28 - mtc1 t0, $f29 - mtc1 t0, $f30 - mtc1 t0, $f31 - jr ra - END(_init_fpu) - - .set pop diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 56d86b09c917..0a83b1708b3c 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,201 @@ .previous .endm +/* + * Save a thread's fp context. + */ +LEAF(_save_fp) +EXPORT_SYMBOL(_save_fp) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ + defined(CONFIG_CPU_MIPS32_R6) + mfc0 t0, CP0_STATUS +#endif + fpu_save_double a0 t0 t1 # clobbers t1 + jr ra + END(_save_fp) + +/* + * Restore a thread's fp context. + */ +LEAF(_restore_fp) +#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ + defined(CONFIG_CPU_MIPS32_R6) + mfc0 t0, CP0_STATUS +#endif + fpu_restore_double a0 t0 t1 # clobbers t1 + jr ra + END(_restore_fp) + +#ifdef CONFIG_CPU_HAS_MSA + +/* + * Save a thread's MSA vector context. + */ +LEAF(_save_msa) +EXPORT_SYMBOL(_save_msa) + msa_save_all a0 + jr ra + END(_save_msa) + +/* + * Restore a thread's MSA vector context. + */ +LEAF(_restore_msa) + msa_restore_all a0 + jr ra + END(_restore_msa) + +LEAF(_init_msa_upper) + msa_init_all_upper + jr ra + END(_init_msa_upper) + +#endif + +/* + * Load the FPU with signalling NANS. This bit pattern we're using has + * the property that no matter whether considered as single or as double + * precision represents signaling NANS. + * + * The value to initialize fcr31 to comes in $a0. + */ + + .set push + SET_HARDFLOAT + +LEAF(_init_fpu) + mfc0 t0, CP0_STATUS + li t1, ST0_CU1 + or t0, t1 + mtc0 t0, CP0_STATUS + enable_fpu_hazard + + ctc1 a0, fcr31 + + li t1, -1 # SNaN + +#ifdef CONFIG_64BIT + sll t0, t0, 5 + bgez t0, 1f # 16 / 32 register mode? + + dmtc1 t1, $f1 + dmtc1 t1, $f3 + dmtc1 t1, $f5 + dmtc1 t1, $f7 + dmtc1 t1, $f9 + dmtc1 t1, $f11 + dmtc1 t1, $f13 + dmtc1 t1, $f15 + dmtc1 t1, $f17 + dmtc1 t1, $f19 + dmtc1 t1, $f21 + dmtc1 t1, $f23 + dmtc1 t1, $f25 + dmtc1 t1, $f27 + dmtc1 t1, $f29 + dmtc1 t1, $f31 +1: +#endif + +#ifdef CONFIG_CPU_MIPS32 + mtc1 t1, $f0 + mtc1 t1, $f1 + mtc1 t1, $f2 + mtc1 t1, $f3 + mtc1 t1, $f4 + mtc1 t1, $f5 + mtc1 t1, $f6 + mtc1 t1, $f7 + mtc1 t1, $f8 + mtc1 t1, $f9 + mtc1 t1, $f10 + mtc1 t1, $f11 + mtc1 t1, $f12 + mtc1 t1, $f13 + mtc1 t1, $f14 + mtc1 t1, $f15 + mtc1 t1, $f16 + mtc1 t1, $f17 + mtc1 t1, $f18 + mtc1 t1, $f19 + mtc1 t1, $f20 + mtc1 t1, $f21 + mtc1 t1, $f22 + mtc1 t1, $f23 + mtc1 t1, $f24 + mtc1 t1, $f25 + mtc1 t1, $f26 + mtc1 t1, $f27 + mtc1 t1, $f28 + mtc1 t1, $f29 + mtc1 t1, $f30 + mtc1 t1, $f31 + +#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6) + .set push + .set MIPS_ISA_LEVEL_RAW + .set fp=64 + sll t0, t0, 5 # is Status.FR set? + bgez t0, 1f # no: skip setting upper 32b + + mthc1 t1, $f0 + mthc1 t1, $f1 + mthc1 t1, $f2 + mthc1 t1, $f3 + mthc1 t1, $f4 + mthc1 t1, $f5 + mthc1 t1, $f6 + mthc1 t1, $f7 + mthc1 t1, $f8 + mthc1 t1, $f9 + mthc1 t1, $f10 + mthc1 t1, $f11 + mthc1 t1, $f12 + mthc1 t1, $f13 + mthc1 t1, $f14 + mthc1 t1, $f15 + mthc1 t1, $f16 + mthc1 t1, $f17 + mthc1 t1, $f18 + mthc1 t1, $f19 + mthc1 t1, $f20 + mthc1 t1, $f21 + mthc1 t1, $f22 + mthc1 t1, $f23 + mthc1 t1, $f24 + mthc1 t1, $f25 + mthc1 t1, $f26 + mthc1 t1, $f27 + mthc1 t1, $f28 + mthc1 t1, $f29 + mthc1 t1, $f30 + mthc1 t1, $f31 +1: .set pop +#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */ +#else + .set MIPS_ISA_ARCH_LEVEL_RAW + dmtc1 t1, $f0 + dmtc1 t1, $f2 + dmtc1 t1, $f4 + dmtc1 t1, $f6 + dmtc1 t1, $f8 + dmtc1 t1, $f10 + dmtc1 t1, $f12 + dmtc1 t1, $f14 + dmtc1 t1, $f16 + dmtc1 t1, $f18 + dmtc1 t1, $f20 + dmtc1 t1, $f22 + dmtc1 t1, $f24 + dmtc1 t1, $f26 + dmtc1 t1, $f28 + dmtc1 t1, $f30 +#endif + jr ra + END(_init_fpu) + + .set pop /* SET_HARDFLOAT */ + .set noreorder /** diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 7b386d54fd65..17cf9341c1cf 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -12,8 +12,6 @@ */ #include #include -#include -#include #include #include #include @@ -22,10 +20,6 @@ #include -/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ -#undef fp - -#ifndef USE_ALTERNATE_RESUME_IMPL /* * task_struct *resume(task_struct *prev, task_struct *next, * struct thread_info *next_ti) @@ -63,200 +57,3 @@ move v0, a0 jr ra END(resume) - -#endif /* USE_ALTERNATE_RESUME_IMPL */ - -/* - * Save a thread's fp context. - */ -LEAF(_save_fp) -EXPORT_SYMBOL(_save_fp) -#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ - defined(CONFIG_CPU_MIPS32_R6) - mfc0 t0, CP0_STATUS -#endif - fpu_save_double a0 t0 t1 # clobbers t1 - jr ra - END(_save_fp) - -/* - * Restore a thread's fp context. - */ -LEAF(_restore_fp) -#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \ - defined(CONFIG_CPU_MIPS32_R6) - mfc0 t0, CP0_STATUS -#endif - fpu_restore_double a0 t0 t1 # clobbers t1 - jr ra - END(_restore_fp) - -#ifdef CONFIG_CPU_HAS_MSA - -/* - * Save a thread's MSA vector context. - */ -LEAF(_save_msa) -EXPORT_SYMBOL(_save_msa) - msa_save_all a0 - jr ra - END(_save_msa) - -/* - * Restore a thread's MSA vector context. - */ -LEAF(_restore_msa) - msa_restore_all a0 - jr ra - END(_restore_msa) - -LEAF(_init_msa_upper) - msa_init_all_upper - jr ra - END(_init_msa_upper) - -#endif - -/* - * Load the FPU with signalling NANS. This bit pattern we're using has - * the property that no matter whether considered as single or as double - * precision represents signaling NANS. - * - * The value to initialize fcr31 to comes in $a0. - */ - - .set push - SET_HARDFLOAT - -LEAF(_init_fpu) - mfc0 t0, CP0_STATUS - li t1, ST0_CU1 - or t0, t1 - mtc0 t0, CP0_STATUS - enable_fpu_hazard - - ctc1 a0, fcr31 - - li t1, -1 # SNaN - -#ifdef CONFIG_64BIT - sll t0, t0, 5 - bgez t0, 1f # 16 / 32 register mode? - - dmtc1 t1, $f1 - dmtc1 t1, $f3 - dmtc1 t1, $f5 - dmtc1 t1, $f7 - dmtc1 t1, $f9 - dmtc1 t1, $f11 - dmtc1 t1, $f13 - dmtc1 t1, $f15 - dmtc1 t1, $f17 - dmtc1 t1, $f19 - dmtc1 t1, $f21 - dmtc1 t1, $f23 - dmtc1 t1, $f25 - dmtc1 t1, $f27 - dmtc1 t1, $f29 - dmtc1 t1, $f31 -1: -#endif - -#ifdef CONFIG_CPU_MIPS32 - mtc1 t1, $f0 - mtc1 t1, $f1 - mtc1 t1, $f2 - mtc1 t1, $f3 - mtc1 t1, $f4 - mtc1 t1, $f5 - mtc1 t1, $f6 - mtc1 t1, $f7 - mtc1 t1, $f8 - mtc1 t1, $f9 - mtc1 t1, $f10 - mtc1 t1, $f11 - mtc1 t1, $f12 - mtc1 t1, $f13 - mtc1 t1, $f14 - mtc1 t1, $f15 - mtc1 t1, $f16 - mtc1 t1, $f17 - mtc1 t1, $f18 - mtc1 t1, $f19 - mtc1 t1, $f20 - mtc1 t1, $f21 - mtc1 t1, $f22 - mtc1 t1, $f23 - mtc1 t1, $f24 - mtc1 t1, $f25 - mtc1 t1, $f26 - mtc1 t1, $f27 - mtc1 t1, $f28 - mtc1 t1, $f29 - mtc1 t1, $f30 - mtc1 t1, $f31 - -#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6) - .set push - .set MIPS_ISA_LEVEL_RAW - .set fp=64 - sll t0, t0, 5 # is Status.FR set? - bgez t0, 1f # no: skip setting upper 32b - - mthc1 t1, $f0 - mthc1 t1, $f1 - mthc1 t1, $f2 - mthc1 t1, $f3 - mthc1 t1, $f4 - mthc1 t1, $f5 - mthc1 t1, $f6 - mthc1 t1, $f7 - mthc1 t1, $f8 - mthc1 t1, $f9 - mthc1 t1, $f10 - mthc1 t1, $f11 - mthc1 t1, $f12 - mthc1 t1, $f13 - mthc1 t1, $f14 - mthc1 t1, $f15 - mthc1 t1, $f16 - mthc1 t1, $f17 - mthc1 t1, $f18 - mthc1 t1, $f19 - mthc1 t1, $f20 - mthc1 t1, $f21 - mthc1 t1, $f22 - mthc1 t1, $f23 - mthc1 t1, $f24 - mthc1 t1, $f25 - mthc1 t1, $f26 - mthc1 t1, $f27 - mthc1 t1, $f28 - mthc1 t1, $f29 - mthc1 t1, $f30 - mthc1 t1, $f31 -1: .set pop -#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */ -#else - .set MIPS_ISA_ARCH_LEVEL_RAW - dmtc1 t1, $f0 - dmtc1 t1, $f2 - dmtc1 t1, $f4 - dmtc1 t1, $f6 - dmtc1 t1, $f8 - dmtc1 t1, $f10 - dmtc1 t1, $f12 - dmtc1 t1, $f14 - dmtc1 t1, $f16 - dmtc1 t1, $f18 - dmtc1 t1, $f20 - dmtc1 t1, $f22 - dmtc1 t1, $f24 - dmtc1 t1, $f26 - dmtc1 t1, $f28 - dmtc1 t1, $f30 -#endif - jr ra - END(_init_fpu) - - .set pop /* SET_HARDFLOAT */ diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S deleted file mode 100644 index 9cc7bfab3419..000000000000 --- a/arch/mips/kernel/r6000_fpu.S +++ /dev/null @@ -1,99 +0,0 @@ -/* - * r6000_fpu.S: Save/restore floating point context for signal handlers. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996 by Ralf Baechle - * - * Multi-arch abstraction and asm macros for easier reading: - * Copyright (C) 1996 David S. Miller (davem@davemloft.net) - */ -#include -#include -#include -#include -#include - - .set noreorder - .set mips2 - .set push - SET_HARDFLOAT - -/** - * _save_fp_context() - save FP context from the FPU - * @a0 - pointer to fpregs field of sigcontext - * @a1 - pointer to fpc_csr field of sigcontext - * - * Save FP context, including the 32 FP data registers and the FP - * control & status register, from the FPU to signal context. - */ - LEAF(_save_fp_context) - mfc0 t0,CP0_STATUS - sll t0,t0,2 - bgez t0,1f - nop - - cfc1 t1,fcr31 - /* Store the 16 double precision registers */ - sdc1 $f0,0(a0) - sdc1 $f2,16(a0) - sdc1 $f4,32(a0) - sdc1 $f6,48(a0) - sdc1 $f8,64(a0) - sdc1 $f10,80(a0) - sdc1 $f12,96(a0) - sdc1 $f14,112(a0) - sdc1 $f16,128(a0) - sdc1 $f18,144(a0) - sdc1 $f20,160(a0) - sdc1 $f22,176(a0) - sdc1 $f24,192(a0) - sdc1 $f26,208(a0) - sdc1 $f28,224(a0) - sdc1 $f30,240(a0) - jr ra - sw t0,(a1) -1: jr ra - nop - END(_save_fp_context) - -/** - * _restore_fp_context() - restore FP context to the FPU - * @a0 - pointer to fpregs field of sigcontext - * @a1 - pointer to fpc_csr field of sigcontext - * - * Restore FP context, including the 32 FP data registers and the FP - * control & status register, from signal context to the FPU. - */ - LEAF(_restore_fp_context) - mfc0 t0,CP0_STATUS - sll t0,t0,2 - - bgez t0,1f - lw t0,(a1) - /* Restore the 16 double precision registers */ - ldc1 $f0,0(a0) - ldc1 $f2,16(a0) - ldc1 $f4,32(a0) - ldc1 $f6,48(a0) - ldc1 $f8,64(a0) - ldc1 $f10,80(a0) - ldc1 $f12,96(a0) - ldc1 $f14,112(a0) - ldc1 $f16,128(a0) - ldc1 $f18,144(a0) - ldc1 $f20,160(a0) - ldc1 $f22,176(a0) - ldc1 $f24,192(a0) - ldc1 $f26,208(a0) - ldc1 $f28,224(a0) - ldc1 $f30,240(a0) - jr ra - ctc1 t0,fcr31 -1: jr ra - nop - END(_restore_fp_context) - - .set pop /* SET_HARDFLOAT */ diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c index 2d1a0c438771..cbf4cc0b0b6c 100644 --- a/arch/mips/kernel/relocate.c +++ b/arch/mips/kernel/relocate.c @@ -6,7 +6,7 @@ * Support for Kernel relocation at boot time * * Copyright (C) 2015, Imagination Technologies Ltd. - * Authors: Matt Redfearn (matt.redfearn@imgtec.com) + * Authors: Matt Redfearn (matt.redfearn@mips.com) */ #include #include diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 84165f2b31ff..cf5c7c05e5a3 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -93,38 +93,37 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_TIMER >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); - default: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user((unsigned long)from->si_addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_SYS >> 16: + case SIL_SYS: err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr, sizeof(compat_uptr_t)); err |= __put_user(from->si_syscall, &to->si_syscall); diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 1b070a76fcdd..87dcac2447c8 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c @@ -179,7 +179,7 @@ static void bmips_prepare_cpus(unsigned int max_cpus) /* * Tell the hardware to boot CPUx - runs on CPU0 */ -static void bmips_boot_secondary(int cpu, struct task_struct *idle) +static int bmips_boot_secondary(int cpu, struct task_struct *idle) { bmips_smp_boot_sp = __KSTK_TOS(idle); bmips_smp_boot_gp = (unsigned long)task_thread_info(idle); @@ -231,6 +231,8 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) } cpumask_set_cpu(cpu, &bmips_booted_mask); } + + return 0; } /* @@ -245,7 +247,7 @@ static void bmips_init_secondary(void) break; case CPU_BMIPS5000: write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); - current_cpu_data.core = (read_c0_brcm_config() >> 25) & 3; + cpu_set_core(¤t_cpu_data, (read_c0_brcm_config() >> 25) & 3); break; } } @@ -409,7 +411,7 @@ void __ref play_dead(void) #endif /* CONFIG_HOTPLUG_CPU */ -struct plat_smp_ops bmips43xx_smp_ops = { +const struct plat_smp_ops bmips43xx_smp_ops = { .smp_setup = bmips_smp_setup, .prepare_cpus = bmips_prepare_cpus, .boot_secondary = bmips_boot_secondary, @@ -423,7 +425,7 @@ struct plat_smp_ops bmips43xx_smp_ops = { #endif }; -struct plat_smp_ops bmips5000_smp_ops = { +const struct plat_smp_ops bmips5000_smp_ops = { .smp_setup = bmips_smp_setup, .prepare_cpus = bmips_prepare_cpus, .boot_secondary = bmips_boot_secondary, @@ -589,11 +591,11 @@ void __init bmips_cpu_setup(void) /* Flush and enable RAC */ cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); - __raw_writel(cfg | 0x100, BMIPS_RAC_CONFIG); + __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG); __raw_readl(cbr + BMIPS_RAC_CONFIG); cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); - __raw_writel(cfg | 0xf, BMIPS_RAC_CONFIG); + __raw_writel(cfg | 0xf, cbr + BMIPS_RAC_CONFIG); __raw_readl(cbr + BMIPS_RAC_CONFIG); cfg = __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE); diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index 76923349b4fe..a2322009cac3 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c @@ -19,12 +19,11 @@ #undef DEBUG #include -#include +#include #include #include #include #include -#include #include #include @@ -51,8 +50,8 @@ static void cmp_init_secondary(void) #ifdef CONFIG_MIPS_MT_SMP if (cpu_has_mipsmt) - c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & - TCBIND_CURVPE; + cpu_set_vpe_id(c, (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & + TCBIND_CURVPE); #endif } @@ -78,7 +77,7 @@ static void cmp_smp_finish(void) * __KSTK_TOS(idle) is apparently the stack pointer * (unsigned long)idle->thread_info the gp */ -static void cmp_boot_secondary(int cpu, struct task_struct *idle) +static int cmp_boot_secondary(int cpu, struct task_struct *idle) { struct thread_info *gp = task_thread_info(idle); unsigned long sp = __KSTK_TOS(idle); @@ -95,6 +94,7 @@ static void cmp_boot_secondary(int cpu, struct task_struct *idle) #endif amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0); + return 0; } /* @@ -148,7 +148,7 @@ void __init cmp_prepare_cpus(unsigned int max_cpus) } -struct plat_smp_ops cmp_smp_ops = { +const struct plat_smp_ops cmp_smp_ops = { .send_ipi_single = mips_smp_send_ipi_single, .send_ipi_mask = mips_smp_send_ipi_mask, .init_secondary = cmp_init_secondary, diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index f832e99ad4c3..ecc1a853f48d 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -19,8 +18,7 @@ #include #include -#include -#include +#include #include #include #include @@ -41,55 +39,58 @@ static int __init setup_nothreads(char *s) } early_param("nothreads", setup_nothreads); -static unsigned core_vpe_count(unsigned core) +static unsigned core_vpe_count(unsigned int cluster, unsigned core) { - unsigned cfg; - if (threads_disabled) return 1; - if ((!IS_ENABLED(CONFIG_MIPS_MT_SMP) || !cpu_has_mipsmt) - && (!IS_ENABLED(CONFIG_CPU_MIPSR6) || !cpu_has_vp)) - return 1; - - mips_cm_lock_other(core, 0); - cfg = read_gcr_co_config() & CM_GCR_Cx_CONFIG_PVPE_MSK; - mips_cm_unlock_other(); - return (cfg >> CM_GCR_Cx_CONFIG_PVPE_SHF) + 1; + return mips_cps_numvps(cluster, core); } static void __init cps_smp_setup(void) { - unsigned int ncores, nvpes, core_vpes; + unsigned int nclusters, ncores, nvpes, core_vpes; unsigned long core_entry; - int c, v; + int cl, c, v; /* Detect & record VPE topology */ - ncores = mips_cm_numcores(); + nvpes = 0; + nclusters = mips_cps_numclusters(); pr_info("%s topology ", cpu_has_mips_r6 ? "VP" : "VPE"); - for (c = nvpes = 0; c < ncores; c++) { - core_vpes = core_vpe_count(c); - pr_cont("%c%u", c ? ',' : '{', core_vpes); + for (cl = 0; cl < nclusters; cl++) { + if (cl > 0) + pr_cont(","); + pr_cont("{"); - /* Use the number of VPEs in core 0 for smp_num_siblings */ - if (!c) - smp_num_siblings = core_vpes; + ncores = mips_cps_numcores(cl); + for (c = 0; c < ncores; c++) { + core_vpes = core_vpe_count(cl, c); - for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { - cpu_data[nvpes + v].core = c; -#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) - cpu_data[nvpes + v].vpe_id = v; -#endif + if (c > 0) + pr_cont(","); + pr_cont("%u", core_vpes); + + /* Use the number of VPEs in cluster 0 core 0 for smp_num_siblings */ + if (!cl && !c) + smp_num_siblings = core_vpes; + + for (v = 0; v < min_t(int, core_vpes, NR_CPUS - nvpes); v++) { + cpu_set_cluster(&cpu_data[nvpes + v], cl); + cpu_set_core(&cpu_data[nvpes + v], c); + cpu_set_vpe_id(&cpu_data[nvpes + v], v); + } + + nvpes += core_vpes; } - nvpes += core_vpes; + pr_cont("}"); } - pr_cont("} total %u\n", nvpes); + pr_cont(" total %u\n", nvpes); /* Indicate present CPUs (CPU being synonymous with VPE) */ for (v = 0; v < min_t(unsigned, nvpes, NR_CPUS); v++) { - set_cpu_possible(v, true); - set_cpu_present(v, true); + set_cpu_possible(v, cpu_cluster(&cpu_data[v]) == 0); + set_cpu_present(v, cpu_cluster(&cpu_data[v]) == 0); __cpu_number_map[v] = v; __cpu_logical_map[v] = v; } @@ -121,7 +122,7 @@ static void __init cps_smp_setup(void) static void __init cps_prepare_cpus(unsigned int max_cpus) { unsigned ncores, core_vpes, c, cca; - bool cca_unsuitable; + bool cca_unsuitable, cores_limited; u32 *entry_code; mips_mt_set_cpuoptions(); @@ -141,19 +142,22 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) } /* Warn the user if the CCA prevents multi-core */ - ncores = mips_cm_numcores(); - if ((cca_unsuitable || cpu_has_dc_aliases) && ncores > 1) { + cores_limited = false; + if (cca_unsuitable || cpu_has_dc_aliases) { + for_each_present_cpu(c) { + if (cpus_are_siblings(smp_processor_id(), c)) + continue; + + set_cpu_present(c, false); + cores_limited = true; + } + } + if (cores_limited) pr_warn("Using only one core due to %s%s%s\n", cca_unsuitable ? "unsuitable CCA" : "", (cca_unsuitable && cpu_has_dc_aliases) ? " & " : "", cpu_has_dc_aliases ? "dcache aliasing" : ""); - for_each_present_cpu(c) { - if (cpu_data[c].core) - set_cpu_present(c, false); - } - } - /* * Patch the start of mips_cps_core_entry to provide: * @@ -168,6 +172,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) __sync(); /* Allocate core boot configuration structs */ + ncores = mips_cps_numcores(0); mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg), GFP_KERNEL); if (!mips_cps_core_bootcfg) { @@ -177,7 +182,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) /* Allocate VPE boot configuration structs */ for (c = 0; c < ncores; c++) { - core_vpes = core_vpe_count(c); + core_vpes = core_vpe_count(0, c); mips_cps_core_bootcfg[c].vpe_config = kcalloc(core_vpes, sizeof(*mips_cps_core_bootcfg[c].vpe_config), GFP_KERNEL); @@ -189,7 +194,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) } /* Mark this CPU as booted */ - atomic_set(&mips_cps_core_bootcfg[current_cpu_data.core].vpe_mask, + atomic_set(&mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)].vpe_mask, 1 << cpu_vpe_id(¤t_cpu_data)); return; @@ -212,11 +217,11 @@ err_out: static void boot_core(unsigned int core, unsigned int vpe_id) { - u32 access, stat, seq_state; + u32 stat, seq_state; unsigned timeout; /* Select the appropriate core */ - mips_cm_lock_other(core, 0); + mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); /* Set its reset vector */ write_gcr_co_reset_base(CKSEG1ADDR((unsigned long)mips_cps_core_entry)); @@ -225,12 +230,10 @@ static void boot_core(unsigned int core, unsigned int vpe_id) write_gcr_co_coherence(0); /* Start it with the legacy memory map and exception base */ - write_gcr_co_reset_ext_base(CM_GCR_RESET_EXT_BASE_UEB); + write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB); /* Ensure the core can access the GCRs */ - access = read_gcr_access(); - access |= 1 << (CM_GCR_ACCESS_ACCESSEN_SHF + core); - write_gcr_access(access); + set_gcr_access(1 << core); if (mips_cpc_present()) { /* Reset the core */ @@ -253,7 +256,8 @@ static void boot_core(unsigned int core, unsigned int vpe_id) timeout = 100; while (true) { stat = read_cpc_co_stat_conf(); - seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE_MSK; + seq_state = stat & CPC_Cx_STAT_CONF_SEQSTATE; + seq_state >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE); /* U6 == coherent execution, ie. the core is up */ if (seq_state == CPC_Cx_STAT_CONF_SEQSTATE_U6) @@ -285,15 +289,15 @@ static void boot_core(unsigned int core, unsigned int vpe_id) static void remote_vpe_boot(void *dummy) { - unsigned core = current_cpu_data.core; + unsigned core = cpu_core(¤t_cpu_data); struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; mips_cps_boot_vpes(core_cfg, cpu_vpe_id(¤t_cpu_data)); } -static void cps_boot_secondary(int cpu, struct task_struct *idle) +static int cps_boot_secondary(int cpu, struct task_struct *idle) { - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); struct core_boot_config *core_cfg = &mips_cps_core_bootcfg[core]; struct vpe_boot_config *vpe_cfg = &core_cfg->vpe_config[vpe_id]; @@ -301,6 +305,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) unsigned int remote; int err; + /* We don't yet support booting CPUs in other clusters */ + if (cpu_cluster(&cpu_data[cpu]) != cpu_cluster(&raw_current_cpu_data)) + return -ENOSYS; + vpe_cfg->pc = (unsigned long)&smp_bootstrap; vpe_cfg->sp = __KSTK_TOS(idle); vpe_cfg->gp = (unsigned long)task_thread_info(idle); @@ -316,16 +324,16 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) } if (cpu_has_vp) { - mips_cm_lock_other(core, vpe_id); + mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL); core_entry = CKSEG1ADDR((unsigned long)mips_cps_core_entry); write_gcr_co_reset_base(core_entry); mips_cm_unlock_other(); } - if (core != current_cpu_data.core) { + if (!cpus_are_siblings(cpu, smp_processor_id())) { /* Boot a VPE on another powered up core */ for (remote = 0; remote < NR_CPUS; remote++) { - if (cpu_data[remote].core != core) + if (!cpus_are_siblings(cpu, remote)) continue; if (cpu_online(remote)) break; @@ -349,6 +357,7 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle) mips_cps_boot_vpes(core_cfg, vpe_id); out: preempt_enable(); + return 0; } static void cps_init_secondary(void) @@ -358,7 +367,7 @@ static void cps_init_secondary(void) dmt(); if (mips_cm_revision() >= CM_REV_CM3) { - unsigned ident = gic_read_local_vp_id(); + unsigned int ident = read_gic_vl_ident(); /* * Ensure that our calculation of the VP ID matches up with @@ -402,7 +411,7 @@ static int cps_cpu_disable(void) if (!cps_pm_support_state(CPS_PM_POWER_GATED)) return -EINVAL; - core_cfg = &mips_cps_core_bootcfg[current_cpu_data.core]; + core_cfg = &mips_cps_core_bootcfg[cpu_core(¤t_cpu_data)]; atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask); smp_mb__after_atomic(); set_cpu_online(cpu, false); @@ -424,15 +433,17 @@ void play_dead(void) local_irq_disable(); idle_task_exit(); cpu = smp_processor_id(); - core = cpu_data[cpu].core; + core = cpu_core(&cpu_data[cpu]); cpu_death = CPU_DEATH_POWER; pr_debug("CPU%d going offline\n", cpu); if (cpu_has_mipsmt || cpu_has_vp) { + core = cpu_core(&cpu_data[cpu]); + /* Look for another online VPE within the core */ for_each_online_cpu(cpu_death_sibling) { - if (cpu_data[cpu_death_sibling].core != core) + if (!cpus_are_siblings(cpu, cpu_death_sibling)) continue; /* @@ -488,7 +499,7 @@ static void wait_for_sibling_halt(void *ptr_cpu) static void cps_cpu_die(unsigned int cpu) { - unsigned core = cpu_data[cpu].core; + unsigned core = cpu_core(&cpu_data[cpu]); unsigned int vpe_id = cpu_vpe_id(&cpu_data[cpu]); ktime_t fail_time; unsigned stat; @@ -519,10 +530,11 @@ static void cps_cpu_die(unsigned int cpu) */ fail_time = ktime_add_ms(ktime_get(), 2000); do { - mips_cm_lock_other(core, 0); + mips_cm_lock_other(0, core, 0, CM_GCR_Cx_OTHER_BLOCK_LOCAL); mips_cpc_lock_other(core); stat = read_cpc_co_stat_conf(); - stat &= CPC_Cx_STAT_CONF_SEQSTATE_MSK; + stat &= CPC_Cx_STAT_CONF_SEQSTATE; + stat >>= __ffs(CPC_Cx_STAT_CONF_SEQSTATE); mips_cpc_unlock_other(); mips_cm_unlock_other(); @@ -544,7 +556,7 @@ static void cps_cpu_die(unsigned int cpu) */ if (WARN(ktime_after(ktime_get(), fail_time), "CPU%u hasn't powered down, seq. state %u\n", - cpu, stat >> CPC_Cx_STAT_CONF_SEQSTATE_SHF)) + cpu, stat)) break; } while (1); @@ -562,7 +574,7 @@ static void cps_cpu_die(unsigned int cpu) panic("Failed to call remote sibling CPU\n"); } else if (cpu_has_vp) { do { - mips_cm_lock_other(core, vpe_id); + mips_cm_lock_other(0, core, vpe_id, CM_GCR_Cx_OTHER_BLOCK_LOCAL); stat = read_cpc_co_vp_running(); mips_cm_unlock_other(); } while (stat & (1 << vpe_id)); @@ -571,7 +583,7 @@ static void cps_cpu_die(unsigned int cpu) #endif /* CONFIG_HOTPLUG_CPU */ -static struct plat_smp_ops cps_smp_ops = { +static const struct plat_smp_ops cps_smp_ops = { .smp_setup = cps_smp_setup, .prepare_cpus = cps_prepare_cpus, .boot_secondary = cps_boot_secondary, @@ -587,7 +599,7 @@ static struct plat_smp_ops cps_smp_ops = { bool mips_cps_smp_in_use(void) { - extern struct plat_smp_ops *mp_ops; + extern const struct plat_smp_ops *mp_ops; return mp_ops == &cps_smp_ops; } @@ -599,7 +611,7 @@ int register_cps_smp_ops(void) } /* check we have a GIC - we need one for IPIs */ - if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX_MSK)) { + if (!(read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX)) { pr_warn("MIPS CPS SMP unable to proceed without a GIC\n"); return -ENODEV; } diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index ed6b4df583ea..94ab3276b48c 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include static void __init smvp_copy_vpe_config(void) { @@ -83,7 +83,7 @@ static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0, if (tc != 0) smvp_copy_vpe_config(); - cpu_data[ncpu].vpe_id = tc; + cpu_set_vpe_id(&cpu_data[ncpu], tc); return ncpu; } @@ -118,14 +118,12 @@ static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0) static void vsmp_init_secondary(void) { -#ifdef CONFIG_MIPS_GIC /* This is Malta specific: IPI,performance and timer interrupts */ - if (gic_present) + if (mips_gic_present()) change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); else -#endif change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7); } @@ -152,7 +150,7 @@ static void vsmp_smp_finish(void) * (unsigned long)idle->thread_info the gp * assumes a 1:1 mapping of TC => VPE */ -static void vsmp_boot_secondary(int cpu, struct task_struct *idle) +static int vsmp_boot_secondary(int cpu, struct task_struct *idle) { struct thread_info *gp = task_thread_info(idle); dvpe(); @@ -184,6 +182,8 @@ static void vsmp_boot_secondary(int cpu, struct task_struct *idle) clear_c0_mvpcontrol(MVPCONTROL_VPC); evpe(EVPE_ENABLE); + + return 0; } /* @@ -239,7 +239,7 @@ static void __init vsmp_prepare_cpus(unsigned int max_cpus) mips_mt_set_cpuoptions(); } -struct plat_smp_ops vsmp_smp_ops = { +const struct plat_smp_ops vsmp_smp_ops = { .send_ipi_single = mips_smp_send_ipi_single, .send_ipi_mask = mips_smp_send_ipi_mask, .init_secondary = vsmp_init_secondary, diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c index 17878d71ef2b..525d3196f793 100644 --- a/arch/mips/kernel/smp-up.c +++ b/arch/mips/kernel/smp-up.c @@ -39,8 +39,9 @@ static void up_smp_finish(void) /* * Firmware CPU startup hook */ -static void up_boot_secondary(int cpu, struct task_struct *idle) +static int up_boot_secondary(int cpu, struct task_struct *idle) { + return 0; } static void __init up_smp_setup(void) @@ -63,7 +64,7 @@ static void up_cpu_die(unsigned int cpu) } #endif -struct plat_smp_ops up_smp_ops = { +const struct plat_smp_ops up_smp_ops = { .send_ipi_single = up_send_ipi_single, .send_ipi_mask = up_send_ipi_mask, .init_secondary = up_init_secondary, diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 6bace7695788..88be966d3e61 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -66,6 +66,7 @@ EXPORT_SYMBOL(cpu_sibling_map); cpumask_t cpu_core_map[NR_CPUS] __read_mostly; EXPORT_SYMBOL(cpu_core_map); +static DECLARE_COMPLETION(cpu_starting); static DECLARE_COMPLETION(cpu_running); /* @@ -96,8 +97,7 @@ static inline void set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu(i, &cpu_sibling_setup_map) { - if (cpu_data[cpu].package == cpu_data[i].package && - cpu_data[cpu].core == cpu_data[i].core) { + if (cpus_are_siblings(cpu, i)) { cpumask_set_cpu(i, &cpu_sibling_map[cpu]); cpumask_set_cpu(cpu, &cpu_sibling_map[i]); } @@ -134,8 +134,7 @@ void calculate_cpu_foreign_map(void) for_each_online_cpu(i) { core_present = 0; for_each_cpu(k, &temp_foreign_map) - if (cpu_data[i].package == cpu_data[k].package && - cpu_data[i].core == cpu_data[k].core) + if (cpus_are_siblings(i, k)) core_present = 1; if (!core_present) cpumask_set_cpu(i, &temp_foreign_map); @@ -146,10 +145,10 @@ void calculate_cpu_foreign_map(void) &temp_foreign_map, &cpu_sibling_map[i]); } -struct plat_smp_ops *mp_ops; +const struct plat_smp_ops *mp_ops; EXPORT_SYMBOL(mp_ops); -void register_smp_ops(struct plat_smp_ops *ops) +void register_smp_ops(const struct plat_smp_ops *ops) { if (mp_ops) printk(KERN_WARNING "Overriding previously set SMP ops\n"); @@ -186,13 +185,13 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action) if (mips_cpc_present()) { for_each_cpu(cpu, mask) { - core = cpu_data[cpu].core; - - if (core == current_cpu_data.core) + if (cpus_are_siblings(cpu, smp_processor_id())) continue; + core = cpu_core(&cpu_data[cpu]); + while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { - mips_cm_lock_other(core, 0); + mips_cm_lock_other_cpu(cpu, CM_GCR_Cx_OTHER_BLOCK_LOCAL); mips_cpc_lock_other(core); write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); mips_cpc_unlock_other(); @@ -376,6 +375,12 @@ asmlinkage void start_secondary(void) cpumask_set_cpu(cpu, &cpu_coherent_mask); notify_cpu_starting(cpu); + /* Notify boot CPU that we're starting & ready to sync counters */ + complete(&cpu_starting); + + synchronise_count_slave(cpu); + + /* The CPU is running and counters synchronised, now mark it online */ set_cpu_online(cpu, true); set_cpu_sibling_map(cpu); @@ -383,8 +388,11 @@ asmlinkage void start_secondary(void) calculate_cpu_foreign_map(); + /* + * Notify boot CPU that we're up & online and it can safely return + * from __cpu_up + */ complete(&cpu_running); - synchronise_count_slave(cpu); /* * irq will be enabled in ->smp_finish(), enabling it too early @@ -441,19 +449,23 @@ void smp_prepare_boot_cpu(void) int __cpu_up(unsigned int cpu, struct task_struct *tidle) { - mp_ops->boot_secondary(cpu, tidle); + int err; - /* - * We must check for timeout here, as the CPU will not be marked - * online until the counters are synchronised. - */ - if (!wait_for_completion_timeout(&cpu_running, + err = mp_ops->boot_secondary(cpu, tidle); + if (err) + return err; + + /* Wait for CPU to start and be ready to sync counters */ + if (!wait_for_completion_timeout(&cpu_starting, msecs_to_jiffies(1000))) { pr_crit("CPU%u: failed to start\n", cpu); return -EIO; } synchronise_count_master(cpu); + + /* Wait for CPU to finish startup & mark itself online before return */ + wait_for_completion(&cpu_running); return 0; } @@ -648,12 +660,12 @@ EXPORT_SYMBOL(flush_tlb_one); #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST static DEFINE_PER_CPU(atomic_t, tick_broadcast_count); -static DEFINE_PER_CPU(struct call_single_data, tick_broadcast_csd); +static DEFINE_PER_CPU(call_single_data_t, tick_broadcast_csd); void tick_broadcast(const struct cpumask *mask) { atomic_t *count; - struct call_single_data *csd; + call_single_data_t *csd; int cpu; for_each_cpu(cpu, mask) { @@ -674,7 +686,7 @@ static void tick_broadcast_callee(void *info) static int __init tick_broadcast_init(void) { - struct call_single_data *csd; + call_single_data_t *csd; int cpu; for (cpu = 0; cpu < NR_CPUS; cpu++) { diff --git a/arch/mips/kernel/spinlock_test.c b/arch/mips/kernel/spinlock_test.c index f7d86955d1b8..eaed550e79a2 100644 --- a/arch/mips/kernel/spinlock_test.c +++ b/arch/mips/kernel/spinlock_test.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c index 1df1160b6a47..f2973ce87f53 100644 --- a/arch/mips/kernel/sync-r4k.c +++ b/arch/mips/kernel/sync-r4k.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Count register synchronisation. * diff --git a/arch/mips/kernel/sysrq.c b/arch/mips/kernel/sysrq.c index 5f055393092d..e5a2a6ab71ac 100644 --- a/arch/mips/kernel/sysrq.c +++ b/arch/mips/kernel/sysrq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MIPS specific sysrq operations. * diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index c036157fb891..a6ebc8135112 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -72,20 +72,6 @@ EXPORT_SYMBOL(perf_irq); unsigned int mips_hpt_frequency; EXPORT_SYMBOL_GPL(mips_hpt_frequency); -/* - * This function exists in order to cause an error due to a duplicate - * definition if platform code should have its own implementation. The hook - * to use instead is plat_time_init. plat_time_init does not receive the - * irqaction pointer argument anymore. This is because any function which - * initializes an interrupt timer now takes care of its own request_irq rsp. - * setup_irq calls and each clock_event_device should use its own - * struct irqrequest. - */ -void __init plat_timer_setup(void) -{ - BUG(); -} - static __init int cpu_has_mfc0_count_bug(void) { switch (current_cpu_type()) { diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c index cf3eb61fad12..cd3e1f82e1a5 100644 --- a/arch/mips/kernel/topology.c +++ b/arch/mips/kernel/topology.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b68b4d0726d3..5669d3b8bd38 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -50,9 +50,8 @@ #include #include #include -#include +#include #include -#include #include #include #include @@ -734,8 +733,7 @@ void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, si.si_code = FPE_FLTUND; else if (fcr31 & FPU_CSR_INE_X) si.si_code = FPE_FLTRES; - else - si.si_code = __SI_FAULT; + force_sig_info(SIGFPE, &si, tsk); } @@ -1673,7 +1671,7 @@ static inline void parity_protection_init(void) /* Probe L2 ECC support */ gcr_ectl = read_gcr_err_control(); - if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT_MSK) || + if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT) || !(cp0_ectl & ERRCTL_PE)) { /* * One of L1 or L2 ECC checking isn't supported, @@ -1693,12 +1691,12 @@ static inline void parity_protection_init(void) /* Configure L2 ECC checking */ if (l2parity) - gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; + gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN; else - gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; + gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN; write_gcr_err_control(gcr_ectl); gcr_ectl = read_gcr_err_control(); - gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN_MSK; + gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN; WARN_ON(!!gcr_ectl != l2parity); pr_info("Cache parity protection %sabled\n", @@ -2428,21 +2426,6 @@ void __init trap_init(void) set_except_vector(EXCCODE_TR, handle_tr); set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe); - if (current_cpu_type() == CPU_R6000 || - current_cpu_type() == CPU_R6000A) { - /* - * The R6000 is the only R-series CPU that features a machine - * check exception (similar to the R4000 cache error) and - * unaligned ldc1/sdc1 exception. The handlers have not been - * written yet. Well, anyway there is no R6000 machine on the - * current list of targets for Linux/MIPS. - * (Duh, crap, there is someone with a triple R6k machine) - */ - //set_except_vector(14, handle_mc); - //set_except_vector(15, handle_ndc); - } - - if (board_nmi_handler_setup) board_nmi_handler_setup(); diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 5eaf2578ac04..2d0b912f9e3e 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -1378,7 +1378,7 @@ sigill: const int reg16to32[] = { 16, 17, 2, 3, 4, 5, 6, 7 }; /* Recode table from 16-bit STORE register notation to 32-bit GPR. */ -const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; +static const int reg16to32st[] = { 0, 17, 2, 3, 4, 5, 6, 7 }; static void emulate_load_store_microMIPS(struct pt_regs *regs, void __user *addr) diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c index e99e3fae5326..f7a0645ccb82 100644 --- a/arch/mips/kernel/uprobes.c +++ b/arch/mips/kernel/uprobes.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 093517e85a6c..019035d7225c 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c @@ -13,13 +13,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include /* Kernel-provided data used by the VDSO. */ @@ -99,9 +99,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { struct mips_vdso_image *image = current->thread.abi->vdso; struct mm_struct *mm = current->mm; - unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr; + unsigned long gic_size, vvar_size, size, base, data_addr, vdso_addr, gic_pfn; struct vm_area_struct *vma; - struct resource gic_res; int ret; if (down_write_killable(&mm->mmap_sem)) @@ -125,7 +124,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * only map a page even though the total area is 64K, as we only need * the counter registers at the start. */ - gic_size = gic_present ? PAGE_SIZE : 0; + gic_size = mips_gic_present() ? PAGE_SIZE : 0; vvar_size = gic_size + PAGE_SIZE; size = vvar_size + image->size; @@ -148,13 +147,9 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) /* Map GIC user page. */ if (gic_size) { - ret = gic_get_usm_range(&gic_res); - if (ret) - goto out; + gic_pfn = virt_to_phys(mips_gic_base + MIPS_GIC_USER_OFS) >> PAGE_SHIFT; - ret = io_remap_pfn_range(vma, base, - gic_res.start >> PAGE_SHIFT, - gic_size, + ret = io_remap_pfn_range(vma, base, gic_pfn, gic_size, pgprot_noncached(PAGE_READONLY)); if (ret) goto out; diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 8ca2371aa684..971a504001c2 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/mips/kvm/Kconfig b/arch/mips/kvm/Kconfig index 50a722dfb236..b17447ce8873 100644 --- a/arch/mips/kvm/Kconfig +++ b/arch/mips/kvm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # KVM configuration # diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile index 45d90f5d5177..01affc1d21c5 100644 --- a/arch/mips/kvm/Makefile +++ b/arch/mips/kvm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for KVM support for MIPS # diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index d4b2ad18eef2..d535edc01434 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -98,6 +98,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) return !!(vcpu->arch.pending_exceptions); } +bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) +{ + return false; +} + int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) { return 1; @@ -509,7 +514,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, dvcpu->arch.wait = 0; - if (swait_active(&dvcpu->wq)) + if (swq_has_sleeper(&dvcpu->wq)) swake_up(&dvcpu->wq); return 0; @@ -1174,7 +1179,7 @@ static void kvm_mips_comparecount_func(unsigned long data) kvm_mips_callbacks->queue_timer_int(vcpu); vcpu->arch.wait = 0; - if (swait_active(&vcpu->wq)) + if (swq_has_sleeper(&vcpu->wq)) swake_up(&vcpu->wq); } diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 177769dbb0e8..692ae85a3e3d 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if LANTIQ config SOC_TYPE_XWAY @@ -17,6 +18,8 @@ config SOC_XWAY bool "XWAY" select SOC_TYPE_XWAY select HW_HAS_PCI + select MFD_SYSCON + select MFD_CORE config SOC_FALCON bool "FALCON" diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c index 7a535d72f541..058b85578cf7 100644 --- a/arch/mips/lantiq/falcon/reset.c +++ b/arch/mips/lantiq/falcon/reset.c @@ -15,28 +15,15 @@ #include -/* CPU0 Reset Source Register */ -#define SYS1_CPU0RS 0x0040 -/* reset cause mask */ -#define CPU0RS_MASK 0x0003 -/* CPU0 Boot Mode Register */ -#define SYS1_BM 0x00a0 -/* boot mode mask */ -#define BM_MASK 0x0005 - -/* allow platform code to find out what surce we booted from */ +/* + * Dummy implementation. Used to allow platform code to find out what + * source was booted from + */ unsigned char ltq_boot_select(void) { - return ltq_sys1_r32(SYS1_BM) & BM_MASK; + return BS_SPI; } -/* allow the watchdog driver to find out what the boot reason was */ -int ltq_reset_cause(void) -{ - return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK; -} -EXPORT_SYMBOL_GPL(ltq_reset_cause); - #define BOOT_REG_BASE (KSEG1 | 0x1F200000) #define BOOT_PW1_REG (BOOT_REG_BASE | 0x20) #define BOOT_PW2_REG (BOOT_REG_BASE | 0x24) diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 33728b7af426..f0bc3312ed11 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c @@ -61,10 +61,6 @@ /* we have a cascade of 8 irqs */ #define MIPS_CPU_IRQ_CASCADE 8 -#ifdef CONFIG_MIPS_MT_SMP -int gic_present; -#endif - static int exin_avail; static u32 ltq_eiu_irq[MAX_EIU]; static void __iomem *ltq_icu_membase[MAX_IM]; diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 96773bed8a8a..9ff7ccde9de0 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c @@ -117,7 +117,7 @@ void __init prom_init(void) int __init plat_of_setup(void) { - return __dt_register_buses(soc_info.compatible, "simple-bus"); + return of_platform_default_populate(NULL, NULL, NULL); } arch_initcall(plat_of_setup); diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index a2edc538f477..fbb0747c70b7 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile @@ -1,5 +1,3 @@ -obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o +obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o obj-y += vmmc.o - -obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c deleted file mode 100644 index 83fd65d76e81..000000000000 --- a/arch/mips/lantiq/xway/reset.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * Copyright (C) 2010 John Crispin - * Copyright (C) 2013-2015 Lantiq Beteiligungs-GmbH & Co.KG - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "../prom.h" - -/* reset request register */ -#define RCU_RST_REQ 0x0010 -/* reset status register */ -#define RCU_RST_STAT 0x0014 -/* vr9 gphy registers */ -#define RCU_GFS_ADD0_XRX200 0x0020 -#define RCU_GFS_ADD1_XRX200 0x0068 -/* xRX300 gphy registers */ -#define RCU_GFS_ADD0_XRX300 0x0020 -#define RCU_GFS_ADD1_XRX300 0x0058 -#define RCU_GFS_ADD2_XRX300 0x00AC -/* xRX330 gphy registers */ -#define RCU_GFS_ADD0_XRX330 0x0020 -#define RCU_GFS_ADD1_XRX330 0x0058 -#define RCU_GFS_ADD2_XRX330 0x00AC -#define RCU_GFS_ADD3_XRX330 0x0264 - -/* xbar BE flag */ -#define RCU_AHB_ENDIAN 0x004C -#define RCU_VR9_BE_AHB1S 0x00000008 - -/* reboot bit */ -#define RCU_RD_GPHY0_XRX200 BIT(31) -#define RCU_RD_SRST BIT(30) -#define RCU_RD_GPHY1_XRX200 BIT(29) -/* xRX300 bits */ -#define RCU_RD_GPHY0_XRX300 BIT(31) -#define RCU_RD_GPHY1_XRX300 BIT(29) -#define RCU_RD_GPHY2_XRX300 BIT(28) -/* xRX330 bits */ -#define RCU_RD_GPHY0_XRX330 BIT(31) -#define RCU_RD_GPHY1_XRX330 BIT(29) -#define RCU_RD_GPHY2_XRX330 BIT(28) -#define RCU_RD_GPHY3_XRX330 BIT(10) - -/* reset cause */ -#define RCU_STAT_SHIFT 26 -/* boot selection */ -#define RCU_BOOT_SEL(x) ((x >> 18) & 0x7) -#define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10)) - -/* dwc2 USB configuration registers */ -#define RCU_USB1CFG 0x0018 -#define RCU_USB2CFG 0x0034 - -/* USB DMA endianness bits */ -#define RCU_USBCFG_HDSEL_BIT BIT(11) -#define RCU_USBCFG_HOST_END_BIT BIT(10) -#define RCU_USBCFG_SLV_END_BIT BIT(9) - -/* USB reset bits */ -#define RCU_USBRESET 0x0010 - -#define USBRESET_BIT BIT(4) - -#define RCU_USBRESET2 0x0048 - -#define USB1RESET_BIT BIT(4) -#define USB2RESET_BIT BIT(5) - -#define RCU_CFG1A 0x0038 -#define RCU_CFG1B 0x003C - -/* USB PMU devices */ -#define PMU_AHBM BIT(15) -#define PMU_USB0 BIT(6) -#define PMU_USB1 BIT(27) - -/* USB PHY PMU devices */ -#define PMU_USB0_P BIT(0) -#define PMU_USB1_P BIT(26) - -/* remapped base addr of the reset control unit */ -static void __iomem *ltq_rcu_membase; -static struct device_node *ltq_rcu_np; -static DEFINE_SPINLOCK(ltq_rcu_lock); - -static void ltq_rcu_w32(uint32_t val, uint32_t reg_off) -{ - ltq_w32(val, ltq_rcu_membase + reg_off); -} - -static uint32_t ltq_rcu_r32(uint32_t reg_off) -{ - return ltq_r32(ltq_rcu_membase + reg_off); -} - -static void ltq_rcu_w32_mask(uint32_t clr, uint32_t set, uint32_t reg_off) -{ - unsigned long flags; - - spin_lock_irqsave(<q_rcu_lock, flags); - ltq_rcu_w32((ltq_rcu_r32(reg_off) & ~(clr)) | (set), reg_off); - spin_unlock_irqrestore(<q_rcu_lock, flags); -} - -/* This function is used by the watchdog driver */ -int ltq_reset_cause(void) -{ - u32 val = ltq_rcu_r32(RCU_RST_STAT); - return val >> RCU_STAT_SHIFT; -} -EXPORT_SYMBOL_GPL(ltq_reset_cause); - -/* allow platform code to find out what source we booted from */ -unsigned char ltq_boot_select(void) -{ - u32 val = ltq_rcu_r32(RCU_RST_STAT); - - if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) - return RCU_BOOT_SEL_XRX200(val); - - return RCU_BOOT_SEL(val); -} - -struct ltq_gphy_reset { - u32 rd; - u32 addr; -}; - -/* reset / boot a gphy */ -static struct ltq_gphy_reset xrx200_gphy[] = { - {RCU_RD_GPHY0_XRX200, RCU_GFS_ADD0_XRX200}, - {RCU_RD_GPHY1_XRX200, RCU_GFS_ADD1_XRX200}, -}; - -/* reset / boot a gphy */ -static struct ltq_gphy_reset xrx300_gphy[] = { - {RCU_RD_GPHY0_XRX300, RCU_GFS_ADD0_XRX300}, - {RCU_RD_GPHY1_XRX300, RCU_GFS_ADD1_XRX300}, - {RCU_RD_GPHY2_XRX300, RCU_GFS_ADD2_XRX300}, -}; - -/* reset / boot a gphy */ -static struct ltq_gphy_reset xrx330_gphy[] = { - {RCU_RD_GPHY0_XRX330, RCU_GFS_ADD0_XRX330}, - {RCU_RD_GPHY1_XRX330, RCU_GFS_ADD1_XRX330}, - {RCU_RD_GPHY2_XRX330, RCU_GFS_ADD2_XRX330}, - {RCU_RD_GPHY3_XRX330, RCU_GFS_ADD3_XRX330}, -}; - -static void xrx200_gphy_boot_addr(struct ltq_gphy_reset *phy_regs, - dma_addr_t dev_addr) -{ - ltq_rcu_w32_mask(0, phy_regs->rd, RCU_RST_REQ); - ltq_rcu_w32(dev_addr, phy_regs->addr); - ltq_rcu_w32_mask(phy_regs->rd, 0, RCU_RST_REQ); -} - -/* reset and boot a gphy. these phys only exist on xrx200 SoC */ -int xrx200_gphy_boot(struct device *dev, unsigned int id, dma_addr_t dev_addr) -{ - struct clk *clk; - - if (!of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) { - dev_err(dev, "this SoC has no GPHY\n"); - return -EINVAL; - } - - if (of_machine_is_compatible("lantiq,vr9")) { - clk = clk_get_sys("1f203000.rcu", "gphy"); - if (IS_ERR(clk)) - return PTR_ERR(clk); - clk_enable(clk); - } - - dev_info(dev, "booting GPHY%u firmware at %X\n", id, dev_addr); - - if (of_machine_is_compatible("lantiq,vr9")) { - if (id >= ARRAY_SIZE(xrx200_gphy)) { - dev_err(dev, "%u is an invalid gphy id\n", id); - return -EINVAL; - } - xrx200_gphy_boot_addr(&xrx200_gphy[id], dev_addr); - } else if (of_machine_is_compatible("lantiq,ar10")) { - if (id >= ARRAY_SIZE(xrx300_gphy)) { - dev_err(dev, "%u is an invalid gphy id\n", id); - return -EINVAL; - } - xrx200_gphy_boot_addr(&xrx300_gphy[id], dev_addr); - } else if (of_machine_is_compatible("lantiq,grx390")) { - if (id >= ARRAY_SIZE(xrx330_gphy)) { - dev_err(dev, "%u is an invalid gphy id\n", id); - return -EINVAL; - } - xrx200_gphy_boot_addr(&xrx330_gphy[id], dev_addr); - } - return 0; -} - -/* reset a io domain for u micro seconds */ -void ltq_reset_once(unsigned int module, ulong u) -{ - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); - udelay(u); - ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); -} - -static int ltq_assert_device(struct reset_controller_dev *rcdev, - unsigned long id) -{ - u32 val; - - if (id < 8) - return -1; - - val = ltq_rcu_r32(RCU_RST_REQ); - val |= BIT(id); - ltq_rcu_w32(val, RCU_RST_REQ); - - return 0; -} - -static int ltq_deassert_device(struct reset_controller_dev *rcdev, - unsigned long id) -{ - u32 val; - - if (id < 8) - return -1; - - val = ltq_rcu_r32(RCU_RST_REQ); - val &= ~BIT(id); - ltq_rcu_w32(val, RCU_RST_REQ); - - return 0; -} - -static int ltq_reset_device(struct reset_controller_dev *rcdev, - unsigned long id) -{ - ltq_assert_device(rcdev, id); - return ltq_deassert_device(rcdev, id); -} - -static const struct reset_control_ops reset_ops = { - .reset = ltq_reset_device, - .assert = ltq_assert_device, - .deassert = ltq_deassert_device, -}; - -static struct reset_controller_dev reset_dev = { - .ops = &reset_ops, - .owner = THIS_MODULE, - .nr_resets = 32, - .of_reset_n_cells = 1, -}; - -void ltq_rst_init(void) -{ - reset_dev.of_node = of_find_compatible_node(NULL, NULL, - "lantiq,xway-reset"); - if (!reset_dev.of_node) - pr_err("Failed to find reset controller node"); - else - reset_controller_register(&reset_dev); -} - -static void ltq_machine_restart(char *command) -{ - u32 val = ltq_rcu_r32(RCU_RST_REQ); - - if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) - val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200; - - val |= RCU_RD_SRST; - - local_irq_disable(); - ltq_rcu_w32(val, RCU_RST_REQ); - unreachable(); -} - -static void ltq_machine_halt(void) -{ - local_irq_disable(); - unreachable(); -} - -static void ltq_machine_power_off(void) -{ - local_irq_disable(); - unreachable(); -} - -static void ltq_usb_init(void) -{ - /* Power for USB cores 1 & 2 */ - ltq_pmu_enable(PMU_AHBM); - ltq_pmu_enable(PMU_USB0); - ltq_pmu_enable(PMU_USB1); - - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A); - ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B); - - /* Enable USB PHY power for cores 1 & 2 */ - ltq_pmu_enable(PMU_USB0_P); - ltq_pmu_enable(PMU_USB1_P); - - /* Configure cores to host mode */ - ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT, - RCU_USB1CFG); - ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT, - RCU_USB2CFG); - - /* Select DMA endianness (Host-endian: big-endian) */ - ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT) - | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG); - ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT) - | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG); - - /* Hard reset USB state machines */ - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET); - udelay(50 * 1000); - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET); - - /* Soft reset USB state machines */ - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) - | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2); - udelay(50 * 1000); - ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) - & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2); -} - -static int __init mips_reboot_setup(void) -{ - struct resource res; - - ltq_rcu_np = of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); - if (!ltq_rcu_np) - ltq_rcu_np = of_find_compatible_node(NULL, NULL, - "lantiq,rcu-xrx200"); - - /* check if all the reset register range is available */ - if (!ltq_rcu_np) - panic("Failed to load reset resources from devicetree"); - - if (of_address_to_resource(ltq_rcu_np, 0, &res)) - panic("Failed to get rcu memory range"); - - if (!request_mem_region(res.start, resource_size(&res), res.name)) - pr_err("Failed to request rcu memory"); - - ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res)); - if (!ltq_rcu_membase) - panic("Failed to remap core memory"); - - if (of_machine_is_compatible("lantiq,ar9") || - of_machine_is_compatible("lantiq,vr9")) - ltq_usb_init(); - - if (of_machine_is_compatible("lantiq,vr9")) - ltq_rcu_w32(ltq_rcu_r32(RCU_AHB_ENDIAN) | RCU_VR9_BE_AHB1S, - RCU_AHB_ENDIAN); - - _machine_restart = ltq_machine_restart; - _machine_halt = ltq_machine_halt; - pm_power_off = ltq_machine_power_off; - - return 0; -} - -arch_initcall(mips_reboot_setup); diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index 95bec460b651..7611c3013793 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -145,15 +145,7 @@ static u32 pmu_clk_cr_b[] = { #define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y)) #define pmu_r32(x) ltq_r32(pmu_membase + (x)) -#define XBAR_ALWAYS_LAST 0x430 -#define XBAR_FPI_BURST_EN BIT(1) -#define XBAR_AHB_BURST_EN BIT(2) - -#define xbar_w32(x, y) ltq_w32((x), ltq_xbar_membase + (y)) -#define xbar_r32(x) ltq_r32(ltq_xbar_membase + (x)) - static void __iomem *pmu_membase; -static void __iomem *ltq_xbar_membase; void __iomem *ltq_cgu_membase; void __iomem *ltq_ebu_membase; @@ -293,16 +285,6 @@ static void pci_ext_disable(struct clk *clk) ltq_cgu_w32((1 << 31) | (1 << 30), pcicr); } -static void xbar_fpi_burst_disable(void) -{ - u32 reg; - - /* bit 1 as 1 --burst; bit 1 as 0 -- single */ - reg = xbar_r32(XBAR_ALWAYS_LAST); - reg &= ~XBAR_FPI_BURST_EN; - xbar_w32(reg, XBAR_ALWAYS_LAST); -} - /* enable a clockout source */ static int clkout_enable(struct clk *clk) { @@ -459,26 +441,6 @@ void __init ltq_soc_init(void) if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase) panic("Failed to remap core resources"); - if (of_machine_is_compatible("lantiq,vr9")) { - struct resource res_xbar; - struct device_node *np_xbar = - of_find_compatible_node(NULL, NULL, - "lantiq,xbar-xway"); - - if (!np_xbar) - panic("Failed to load xbar nodes from devicetree"); - if (of_address_to_resource(np_xbar, 0, &res_xbar)) - panic("Failed to get xbar resources"); - if (!request_mem_region(res_xbar.start, resource_size(&res_xbar), - res_xbar.name)) - panic("Failed to get xbar resources"); - - ltq_xbar_membase = ioremap_nocache(res_xbar.start, - resource_size(&res_xbar)); - if (!ltq_xbar_membase) - panic("Failed to remap xbar resources"); - } - /* make sure to unprotect the memory region where flash is located */ ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); @@ -507,8 +469,8 @@ void __init ltq_soc_init(void) if (of_machine_is_compatible("lantiq,grx390") || of_machine_is_compatible("lantiq,ar10")) { - clkdev_add_pmu("1e101000.usb", "phy", 1, 2, PMU_ANALOG_USB0_P); - clkdev_add_pmu("1e106000.usb", "phy", 1, 2, PMU_ANALOG_USB1_P); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P); + clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P); /* rc 0 */ clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); @@ -528,8 +490,8 @@ void __init ltq_soc_init(void) else clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M, CLOCK_133M); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); clkdev_add_pmu("1e180000.etop", "ppe", 1, 0, PMU_PPE); clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY); clkdev_add_pmu("1e180000.etop", "ephy", 1, 0, PMU_EPHY); @@ -538,8 +500,8 @@ void __init ltq_soc_init(void) } else if (of_machine_is_compatible("lantiq,grx390")) { clkdev_add_static(ltq_grx390_cpu_hz(), ltq_grx390_fpi_hz(), ltq_grx390_fpi_hz(), ltq_grx390_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); /* rc 2 */ clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); @@ -551,22 +513,23 @@ void __init ltq_soc_init(void) } else if (of_machine_is_compatible("lantiq,ar10")) { clkdev_add_static(ltq_ar10_cpu_hz(), ltq_ar10_fpi_hz(), ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP | PMU_PPE_TC); clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); - clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY); + clkdev_add_pmu("1f203020.gphy", NULL, 1, 0, PMU_GPHY); + clkdev_add_pmu("1f203068.gphy", NULL, 1, 0, PMU_GPHY); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); } else if (of_machine_is_compatible("lantiq,vr9")) { clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), ltq_vr9_fpi_hz(), ltq_vr9_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0 | PMU_AHBM); - clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1 | PMU_AHBM); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); + clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY); clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK); clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); @@ -579,17 +542,18 @@ void __init ltq_soc_init(void) PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | PMU_PPE_QSB | PMU_PPE_TOP); - clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY); + clkdev_add_pmu("1f203020.gphy", NULL, 0, 0, PMU_GPHY); + clkdev_add_pmu("1f203068.gphy", NULL, 0, 0, PMU_GPHY); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); } else if (of_machine_is_compatible("lantiq,ar9")) { clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), ltq_ar9_fpi_hz(), CLOCK_250M); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); - clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1); - clkdev_add_pmu("1e106000.usb", "phy", 1, 0, PMU_USB1_P); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); + clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); + clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); clkdev_add_pmu("1e180000.etop", "switch", 1, 0, PMU_SWITCH); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); @@ -598,14 +562,11 @@ void __init ltq_soc_init(void) } else { clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), ltq_danube_fpi_hz(), ltq_danube_pp32_hz()); - clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0); - clkdev_add_pmu("1e101000.usb", "phy", 1, 0, PMU_USB0_P); + clkdev_add_pmu("1f203018.usb2-phy", "ctrl", 1, 0, PMU_USB0); + clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 0, PMU_USB0_P); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0); } - - if (of_machine_is_compatible("lantiq,vr9")) - xbar_fpi_burst_disable(); } diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c deleted file mode 100644 index f0a0f2d431b2..000000000000 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Lantiq XRX200 PHY Firmware Loader - * Author: John Crispin - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * Copyright (C) 2012 John Crispin - */ - -#include -#include -#include -#include - -#include - -#define XRX200_GPHY_FW_ALIGN (16 * 1024) - -static dma_addr_t xway_gphy_load(struct platform_device *pdev) -{ - const struct firmware *fw; - dma_addr_t dev_addr = 0; - const char *fw_name; - void *fw_addr; - size_t size; - - if (of_get_property(pdev->dev.of_node, "firmware1", NULL) || - of_get_property(pdev->dev.of_node, "firmware2", NULL)) { - switch (ltq_soc_type()) { - case SOC_TYPE_VR9: - if (of_property_read_string(pdev->dev.of_node, - "firmware1", &fw_name)) { - dev_err(&pdev->dev, - "failed to load firmware filename\n"); - return 0; - } - break; - case SOC_TYPE_VR9_2: - if (of_property_read_string(pdev->dev.of_node, - "firmware2", &fw_name)) { - dev_err(&pdev->dev, - "failed to load firmware filename\n"); - return 0; - } - break; - } - } else if (of_property_read_string(pdev->dev.of_node, - "firmware", &fw_name)) { - dev_err(&pdev->dev, "failed to load firmware filename\n"); - return 0; - } - - dev_info(&pdev->dev, "requesting %s\n", fw_name); - if (request_firmware(&fw, fw_name, &pdev->dev)) { - dev_err(&pdev->dev, "failed to load firmware: %s\n", fw_name); - return 0; - } - - /* - * GPHY cores need the firmware code in a persistent and contiguous - * memory area with a 16 kB boundary aligned start address - */ - size = fw->size + XRX200_GPHY_FW_ALIGN; - - fw_addr = dma_alloc_coherent(&pdev->dev, size, &dev_addr, GFP_KERNEL); - if (fw_addr) { - fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN); - dev_addr = ALIGN(dev_addr, XRX200_GPHY_FW_ALIGN); - memcpy(fw_addr, fw->data, fw->size); - } else { - dev_err(&pdev->dev, "failed to alloc firmware memory\n"); - } - - release_firmware(fw); - return dev_addr; -} - -static int xway_phy_fw_probe(struct platform_device *pdev) -{ - dma_addr_t fw_addr; - struct property *pp; - unsigned char *phyids; - int i, ret = 0; - - fw_addr = xway_gphy_load(pdev); - if (!fw_addr) - return -EINVAL; - pp = of_find_property(pdev->dev.of_node, "phys", NULL); - if (!pp) - return -ENOENT; - phyids = pp->value; - for (i = 0; i < pp->length && !ret; i++) - ret = xrx200_gphy_boot(&pdev->dev, phyids[i], fw_addr); - if (!ret) - mdelay(100); - return ret; -} - -static const struct of_device_id xway_phy_match[] = { - { .compatible = "lantiq,phy-xrx200" }, - {}, -}; - -static struct platform_driver xway_phy_driver = { - .probe = xway_phy_fw_probe, - .driver = { - .name = "phy-xrx200", - .of_match_table = xway_phy_match, - }, -}; -builtin_platform_driver(xway_phy_driver); diff --git a/arch/mips/lasat/Kconfig b/arch/mips/lasat/Kconfig index 8776d0a34274..11b89e94b835 100644 --- a/arch/mips/lasat/Kconfig +++ b/arch/mips/lasat/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PICVUE tristate "PICVUE LCD display driver" depends on LASAT diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile index 869bd3b37c17..1789b227ef20 100644 --- a/arch/mips/lasat/Makefile +++ b/arch/mips/lasat/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the LASAT specific kernel interface routines under Linux. # diff --git a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c index 4e272a2622a4..f895fe94b937 100644 --- a/arch/mips/lasat/at93c.c +++ b/arch/mips/lasat/at93c.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Atmel AT93C46 serial eeprom driver * diff --git a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h index cfe2f99b1d44..7a99a02d81d0 100644 --- a/arch/mips/lasat/at93c.h +++ b/arch/mips/lasat/at93c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Atmel AT93C46 serial eeprom driver * diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c index c6fd96ff118d..8bd5cf820eed 100644 --- a/arch/mips/lasat/ds1603.c +++ b/arch/mips/lasat/ds1603.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Dallas Semiconductors 1603 RTC driver * diff --git a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h index 3e718b1cca02..00987d3bdc21 100644 --- a/arch/mips/lasat/ds1603.h +++ b/arch/mips/lasat/ds1603.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Dallas Semiconductors 1603 RTC driver * diff --git a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile index fd32075679c6..9ab1326f57c9 100644 --- a/arch/mips/lasat/image/Makefile +++ b/arch/mips/lasat/image/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER # diff --git a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S index 41babbe43a8e..1a27312d4c2e 100644 --- a/arch/mips/lasat/image/head.S +++ b/arch/mips/lasat/image/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include .text diff --git a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h index e1cbd26ae1b3..474e57342484 100644 --- a/arch/mips/lasat/lasat_models.h +++ b/arch/mips/lasat/lasat_models.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Model description tables */ diff --git a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h index d0119fca3862..161d3bf50811 100644 --- a/arch/mips/lasat/picvue.h +++ b/arch/mips/lasat/picvue.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Picvue PVC160206 display driver * diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c index 20fde19a5fbf..17e15b50a551 100644 --- a/arch/mips/lasat/prom.c +++ b/arch/mips/lasat/prom.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PROM interface routines. */ diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h index 337acbc27442..3d1df853e9d3 100644 --- a/arch/mips/lasat/prom.h +++ b/arch/mips/lasat/prom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PROM_H #define __PROM_H diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index a37fe3d1ee2f..78c2affeabf8 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for MIPS-specific library files.. # @@ -6,7 +7,7 @@ lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ mips-atomic.o strncpy_user.o \ strnlen_user.o uncached.o -obj-y += iomap.o +obj-y += iomap.o iomap_copy.o obj-$(CONFIG_PCI) += iomap-pci.o lib-$(CONFIG_GENERIC_CSUM) := $(filter-out csum_partial.o, $(lib-y)) diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c index c3e22053d13e..24cd6903e797 100644 --- a/arch/mips/lib/ashldi3.c +++ b/arch/mips/lib/ashldi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c index 17456024873d..23f5295af51e 100644 --- a/arch/mips/lib/ashrdi3.c +++ b/arch/mips/lib/ashrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/mips/lib/bswapdi.c b/arch/mips/lib/bswapdi.c index a8114148f82a..fcef74084492 100644 --- a/arch/mips/lib/bswapdi.c +++ b/arch/mips/lib/bswapdi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/mips/lib/bswapsi.c b/arch/mips/lib/bswapsi.c index 106fd978317d..22d8e4f6d66e 100644 --- a/arch/mips/lib/bswapsi.c +++ b/arch/mips/lib/bswapsi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/mips/lib/cmpdi2.c b/arch/mips/lib/cmpdi2.c index 9d849d8743c9..93cfc785927d 100644 --- a/arch/mips/lib/cmpdi2.c +++ b/arch/mips/lib/cmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 2307a3cb2714..68c495ed71e3 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -8,6 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2007, 2014 Maciej W. Rozycki */ +#include #include #include #include diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 6eb50a7137db..781ad96b78c4 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Dump R4x00 TLB for debugging purposes. * diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c index 8ed3f25a9047..4850509c5534 100644 --- a/arch/mips/lib/iomap-pci.c +++ b/arch/mips/lib/iomap-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implement the default iomap interfaces * diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index 9daa92428e23..9b31653f318c 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implement the default iomap interfaces * diff --git a/arch/mips/lib/iomap_copy.c b/arch/mips/lib/iomap_copy.c new file mode 100644 index 000000000000..368bb38267c5 --- /dev/null +++ b/arch/mips/lib/iomap_copy.c @@ -0,0 +1,42 @@ +/* + * This file is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +/** + * __ioread64_copy - copy data from MMIO space, in 64-bit units + * @to: destination (must be 64-bit aligned) + * @from: source, in MMIO space (must be 64-bit aligned) + * @count: number of 64-bit quantities to copy + * + * Copy data from MMIO space to kernel space, in units of 32 or 64 bits at a + * time. Order of access is not guaranteed, nor is a memory barrier + * performed afterwards. + */ +void __ioread64_copy(void *to, const void __iomem *from, size_t count) +{ +#ifdef CONFIG_64BIT + u64 *dst = to; + const u64 __iomem *src = from; + const u64 __iomem *end = src + count; + + while (src < end) + *dst++ = __raw_readq(src++); +#else + __ioread32_copy(to, from, count * 2); +#endif +} +EXPORT_SYMBOL_GPL(__ioread64_copy); diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h index 05909d58e2fe..28002ed90c2c 100644 --- a/arch/mips/lib/libgcc.h +++ b/arch/mips/lib/libgcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LIBGCC_H #define __ASM_LIBGCC_H diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c index 221167c1be55..914b971aca3b 100644 --- a/arch/mips/lib/lshrdi3.c +++ b/arch/mips/lib/lshrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index 85b4086e553e..b97d9c5d8323 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Dump R3000 TLB for debugging purposes. * diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c index 08067fa538f2..c31c78ca4175 100644 --- a/arch/mips/lib/ucmpdi2.c +++ b/arch/mips/lib/ucmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/mips/loongson32/Kconfig b/arch/mips/loongson32/Kconfig index 3c0c2f2096cd..462b126f45aa 100644 --- a/arch/mips/loongson32/Kconfig +++ b/arch/mips/loongson32/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if MACH_LOONGSON32 choice diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c index 100f23dfa438..ac584c5823d0 100644 --- a/arch/mips/loongson32/common/platform.c +++ b/arch/mips/loongson32/common/platform.c @@ -183,18 +183,20 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) } static struct plat_stmmacenet_data ls1x_eth0_pdata = { - .bus_id = 0, - .phy_addr = -1, + .bus_id = 0, + .phy_addr = -1, #if defined(CONFIG_LOONGSON1_LS1B) - .interface = PHY_INTERFACE_MODE_MII, + .interface = PHY_INTERFACE_MODE_MII, #elif defined(CONFIG_LOONGSON1_LS1C) - .interface = PHY_INTERFACE_MODE_RMII, + .interface = PHY_INTERFACE_MODE_RMII, #endif - .mdio_bus_data = &ls1x_mdio_bus_data, - .dma_cfg = &ls1x_eth_dma_cfg, - .has_gmac = 1, - .tx_coe = 1, - .init = ls1x_eth_mux_init, + .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, + .has_gmac = 1, + .tx_coe = 1, + .rx_queues_to_use = 1, + .tx_queues_to_use = 1, + .init = ls1x_eth_mux_init, }; static struct resource ls1x_eth0_resources[] = { @@ -222,14 +224,16 @@ struct platform_device ls1x_eth0_pdev = { #ifdef CONFIG_LOONGSON1_LS1B static struct plat_stmmacenet_data ls1x_eth1_pdata = { - .bus_id = 1, - .phy_addr = -1, - .interface = PHY_INTERFACE_MODE_MII, - .mdio_bus_data = &ls1x_mdio_bus_data, - .dma_cfg = &ls1x_eth_dma_cfg, - .has_gmac = 1, - .tx_coe = 1, - .init = ls1x_eth_mux_init, + .bus_id = 1, + .phy_addr = -1, + .interface = PHY_INTERFACE_MODE_MII, + .mdio_bus_data = &ls1x_mdio_bus_data, + .dma_cfg = &ls1x_eth_dma_cfg, + .has_gmac = 1, + .tx_coe = 1, + .rx_queues_to_use = 1, + .tx_queues_to_use = 1, + .init = ls1x_eth_mux_init, }; static struct resource ls1x_eth1_resources[] = { diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig index 8e6e292675b2..0d249fc3cfe9 100644 --- a/arch/mips/loongson64/Kconfig +++ b/arch/mips/loongson64/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if MACH_LOONGSON64 choice diff --git a/arch/mips/loongson64/common/Makefile b/arch/mips/loongson64/common/Makefile index 074d9cb15cd2..8235ac7eac95 100644 --- a/arch/mips/loongson64/common/Makefile +++ b/arch/mips/loongson64/common/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for loongson based machines. # diff --git a/arch/mips/loongson64/common/dma-swiotlb.c b/arch/mips/loongson64/common/dma-swiotlb.c index 34486c138206..ef07740cee61 100644 --- a/arch/mips/loongson64/common/dma-swiotlb.c +++ b/arch/mips/loongson64/common/dma-swiotlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/loongson64/lemote-2f/clock.c b/arch/mips/loongson64/lemote-2f/clock.c index a78fb657068c..8281334df9c8 100644 --- a/arch/mips/loongson64/lemote-2f/clock.c +++ b/arch/mips/loongson64/lemote-2f/clock.c @@ -80,6 +80,9 @@ EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return (unsigned long)clk->rate; } EXPORT_SYMBOL(clk_get_rate); diff --git a/arch/mips/loongson64/loongson-3/acpi_init.c b/arch/mips/loongson64/loongson-3/acpi_init.c index dbdad79ead8f..8d7c119ddf91 100644 --- a/arch/mips/loongson64/loongson-3/acpi_init.c +++ b/arch/mips/loongson64/loongson-3/acpi_init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/loongson64/loongson-3/hpet.c b/arch/mips/loongson64/loongson-3/hpet.c index 4df9d4b7356a..ed15430ad64f 100644 --- a/arch/mips/loongson64/loongson-3/hpet.c +++ b/arch/mips/loongson64/loongson-3/hpet.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/loongson64/loongson-3/irq.c b/arch/mips/loongson64/loongson-3/irq.c index 7202e52cd046..cbeb20f9fc95 100644 --- a/arch/mips/loongson64/loongson-3/irq.c +++ b/arch/mips/loongson64/loongson-3/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index b7a355c3c408..8501109bb0f0 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c @@ -319,8 +319,8 @@ static void loongson3_init_secondary(void) loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); per_cpu(cpu_state, cpu) = CPU_ONLINE; - cpu_data[cpu].core = - cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; + cpu_set_core(&cpu_data[cpu], + cpu_logical_map(cpu) % loongson_sysconf.cores_per_package); cpu_data[cpu].package = cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; @@ -386,7 +386,8 @@ static void __init loongson3_smp_setup(void) ipi_status0_regs_init(); ipi_en0_regs_init(); ipi_mailbox_buf_init(); - cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; + cpu_set_core(&cpu_data[0], + cpu_logical_map(0) % loongson_sysconf.cores_per_package); cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; } @@ -399,7 +400,7 @@ static void __init loongson3_prepare_cpus(unsigned int max_cpus) /* * Setup the PC, SP, and GP of a secondary processor and start it runing! */ -static void loongson3_boot_secondary(int cpu, struct task_struct *idle) +static int loongson3_boot_secondary(int cpu, struct task_struct *idle) { unsigned long startargs[4]; @@ -422,6 +423,7 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle) (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8)); loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); + return 0; } #ifdef CONFIG_HOTPLUG_CPU @@ -697,7 +699,7 @@ void play_dead(void) static int loongson3_disable_clock(unsigned int cpu) { - uint64_t core_id = cpu_data[cpu].core; + uint64_t core_id = cpu_core(&cpu_data[cpu]); uint64_t package_id = cpu_data[cpu].package; if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { @@ -711,7 +713,7 @@ static int loongson3_disable_clock(unsigned int cpu) static int loongson3_enable_clock(unsigned int cpu) { - uint64_t core_id = cpu_data[cpu].core; + uint64_t core_id = cpu_core(&cpu_data[cpu]); uint64_t package_id = cpu_data[cpu].package; if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) { @@ -734,7 +736,7 @@ early_initcall(register_loongson3_notifier); #endif -struct plat_smp_ops loongson3_smp_ops = { +const struct plat_smp_ops loongson3_smp_ops = { .send_ipi_single = loongson3_send_ipi_single, .send_ipi_mask = loongson3_send_ipi_mask, .init_secondary = loongson3_init_secondary, diff --git a/arch/mips/loongson64/loongson-3/smp.h b/arch/mips/loongson64/loongson-3/smp.h index d98ff654b7d7..957bde81e0e4 100644 --- a/arch/mips/loongson64/loongson-3/smp.h +++ b/arch/mips/loongson64/loongson-3/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LOONGSON_SMP_H_ #define __LOONGSON_SMP_H_ diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile index e9bbc2a6526f..81d25ff328a7 100644 --- a/arch/mips/math-emu/Makefile +++ b/arch/mips/math-emu/Makefile @@ -1,12 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/MIPS kernel FPU emulation. # obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \ dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \ - dp_tint.o dp_fint.o dp_maddf.o dp_2008class.o dp_fmin.o dp_fmax.o \ + dp_tint.o dp_fint.o dp_rint.o dp_maddf.o dp_2008class.o dp_fmin.o \ + dp_fmax.o \ sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \ - sp_tint.o sp_fint.o sp_maddf.o sp_2008class.o sp_fmin.o sp_fmax.o \ + sp_tint.o sp_fint.o sp_rint.o sp_maddf.o sp_2008class.o sp_fmin.o \ + sp_fmax.o \ dsemul.o lib-y += ieee754d.o \ diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index f08a7b4facb9..16d9ef5a78c5 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -58,7 +58,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, mips_instruction); static int fpux_emu(struct pt_regs *, - struct mips_fpu_struct *, mips_instruction, void *__user *); + struct mips_fpu_struct *, mips_instruction, void __user **); /* Control registers */ @@ -830,12 +830,12 @@ do { \ } while (0) #define DIFROMREG(di, x) \ - ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) == 0)], 0)) + ((di) = get_fpr64(&ctx->fpr[(x) & ~(cop1_64bit(xcp) ^ 1)], 0)) #define DITOREG(di, x) \ do { \ unsigned fpr, i; \ - fpr = (x) & ~(cop1_64bit(xcp) == 0); \ + fpr = (x) & ~(cop1_64bit(xcp) ^ 1); \ set_fpr64(&ctx->fpr[fpr], 0, di); \ for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val64); i++) \ set_fpr64(&ctx->fpr[fpr], i, 0); \ @@ -973,7 +973,7 @@ static inline void cop1_ctc(struct pt_regs *xcp, struct mips_fpu_struct *ctx, */ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, - struct mm_decoded_insn dec_insn, void *__user *fault_addr) + struct mm_decoded_insn dec_insn, void __user **fault_addr) { unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc; unsigned int cond, cbit, bit0; @@ -1195,9 +1195,11 @@ emul: bit0 = get_fpr32(fpr, 0) & 0x1; switch (MIPSInst_RS(ir)) { case bc1eqz_op: + MIPS_FPU_EMU_INC_STATS(bc1eqz); cond = bit0 == 0; break; case bc1nez_op: + MIPS_FPU_EMU_INC_STATS(bc1nez); cond = bit0 != 0; break; } @@ -1230,6 +1232,7 @@ emul: break; } branch_common: + MIPS_FPU_EMU_INC_STATS(branches); set_delay_slot(xcp); if (cond) { /* @@ -1460,7 +1463,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, - mips_instruction ir, void *__user *fault_addr) + mips_instruction ir, void __user **fault_addr) { unsigned rcsr = 0; /* resulting csr */ @@ -1682,15 +1685,19 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, switch (MIPSInst_FUNC(ir)) { /* binary ops */ case fadd_op: + MIPS_FPU_EMU_INC_STATS(add_s); handler.b = ieee754sp_add; goto scopbop; case fsub_op: + MIPS_FPU_EMU_INC_STATS(sub_s); handler.b = ieee754sp_sub; goto scopbop; case fmul_op: + MIPS_FPU_EMU_INC_STATS(mul_s); handler.b = ieee754sp_mul; goto scopbop; case fdiv_op: + MIPS_FPU_EMU_INC_STATS(div_s); handler.b = ieee754sp_div; goto scopbop; @@ -1699,6 +1706,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sqrt_s); handler.u = ieee754sp_sqrt; goto scopuop; @@ -1711,6 +1719,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rsqrt_s); handler.u = fpemu_sp_rsqrt; goto scopuop; @@ -1718,6 +1727,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(recip_s); handler.u = fpemu_sp_recip; goto scopuop; @@ -1754,6 +1764,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(seleqz_s); SPFROMREG(rv.s, MIPSInst_FT(ir)); if (rv.w & 0x1) rv.w = 0; @@ -1765,6 +1776,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(selnez_s); SPFROMREG(rv.s, MIPSInst_FT(ir)); if (rv.w & 0x1) SPFROMREG(rv.s, MIPSInst_FS(ir)); @@ -1778,6 +1790,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maddf_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(fd, MIPSInst_FD(ir)); @@ -1791,6 +1804,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(msubf_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(fd, MIPSInst_FD(ir)); @@ -1804,9 +1818,9 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rint_s); SPFROMREG(fs, MIPSInst_FS(ir)); - rv.l = ieee754sp_tlong(fs); - rv.s = ieee754sp_flong(rv.l); + rv.s = ieee754sp_rint(fs); goto copcsr; } @@ -1816,6 +1830,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(class_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.w = ieee754sp_2008class(fs); rfmt = w_fmt; @@ -1828,6 +1843,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(min_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmin(fs, ft); @@ -1840,6 +1856,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(mina_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmina(fs, ft); @@ -1852,6 +1869,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(max_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmax(fs, ft); @@ -1864,6 +1882,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maxa_s); SPFROMREG(ft, MIPSInst_FT(ir)); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fmaxa(fs, ft); @@ -1871,15 +1890,18 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, } case fabs_op: + MIPS_FPU_EMU_INC_STATS(abs_s); handler.u = ieee754sp_abs; goto scopuop; case fneg_op: + MIPS_FPU_EMU_INC_STATS(neg_s); handler.u = ieee754sp_neg; goto scopuop; case fmov_op: /* an easy one */ + MIPS_FPU_EMU_INC_STATS(mov_s); SPFROMREG(rv.s, MIPSInst_FS(ir)); goto copcsr; @@ -1922,12 +1944,14 @@ copcsr: return SIGILL; /* not defined */ case fcvtd_op: + MIPS_FPU_EMU_INC_STATS(cvt_d_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fsp(fs); rfmt = d_fmt; goto copcsr; case fcvtw_op: + MIPS_FPU_EMU_INC_STATS(cvt_w_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.w = ieee754sp_tint(fs); rfmt = w_fmt; @@ -1940,6 +1964,15 @@ copcsr: if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + if (MIPSInst_FUNC(ir) == fceil_op) + MIPS_FPU_EMU_INC_STATS(ceil_w_s); + if (MIPSInst_FUNC(ir) == ffloor_op) + MIPS_FPU_EMU_INC_STATS(floor_w_s); + if (MIPSInst_FUNC(ir) == fround_op) + MIPS_FPU_EMU_INC_STATS(round_w_s); + if (MIPSInst_FUNC(ir) == ftrunc_op) + MIPS_FPU_EMU_INC_STATS(trunc_w_s); + oldrm = ieee754_csr.rm; SPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -1952,6 +1985,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sel_s); SPFROMREG(fd, MIPSInst_FD(ir)); if (fd.bits & 0x1) SPFROMREG(rv.s, MIPSInst_FT(ir)); @@ -1963,6 +1997,7 @@ copcsr: if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(cvt_l_s); SPFROMREG(fs, MIPSInst_FS(ir)); rv.l = ieee754sp_tlong(fs); rfmt = l_fmt; @@ -1975,6 +2010,15 @@ copcsr: if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + if (MIPSInst_FUNC(ir) == fceill_op) + MIPS_FPU_EMU_INC_STATS(ceil_l_s); + if (MIPSInst_FUNC(ir) == ffloorl_op) + MIPS_FPU_EMU_INC_STATS(floor_l_s); + if (MIPSInst_FUNC(ir) == froundl_op) + MIPS_FPU_EMU_INC_STATS(round_l_s); + if (MIPSInst_FUNC(ir) == ftruncl_op) + MIPS_FPU_EMU_INC_STATS(trunc_l_s); + oldrm = ieee754_csr.rm; SPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -2016,15 +2060,19 @@ copcsr: switch (MIPSInst_FUNC(ir)) { /* binary ops */ case fadd_op: + MIPS_FPU_EMU_INC_STATS(add_d); handler.b = ieee754dp_add; goto dcopbop; case fsub_op: + MIPS_FPU_EMU_INC_STATS(sub_d); handler.b = ieee754dp_sub; goto dcopbop; case fmul_op: + MIPS_FPU_EMU_INC_STATS(mul_d); handler.b = ieee754dp_mul; goto dcopbop; case fdiv_op: + MIPS_FPU_EMU_INC_STATS(div_d); handler.b = ieee754dp_div; goto dcopbop; @@ -2033,6 +2081,7 @@ copcsr: if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sqrt_d); handler.u = ieee754dp_sqrt; goto dcopuop; /* @@ -2044,12 +2093,14 @@ copcsr: if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rsqrt_d); handler.u = fpemu_dp_rsqrt; goto dcopuop; case frecip_op: if (!cpu_has_mips_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(recip_d); handler.u = fpemu_dp_recip; goto dcopuop; case fmovc_op: @@ -2083,6 +2134,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(seleqz_d); DPFROMREG(rv.d, MIPSInst_FT(ir)); if (rv.l & 0x1) rv.l = 0; @@ -2094,6 +2146,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(selnez_d); DPFROMREG(rv.d, MIPSInst_FT(ir)); if (rv.l & 0x1) DPFROMREG(rv.d, MIPSInst_FS(ir)); @@ -2107,6 +2160,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maddf_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(fd, MIPSInst_FD(ir)); @@ -2120,6 +2174,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(msubf_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(fd, MIPSInst_FD(ir)); @@ -2133,9 +2188,9 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(rint_d); DPFROMREG(fs, MIPSInst_FS(ir)); - rv.l = ieee754dp_tlong(fs); - rv.d = ieee754dp_flong(rv.l); + rv.d = ieee754dp_rint(fs); goto copcsr; } @@ -2145,9 +2200,10 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(class_d); DPFROMREG(fs, MIPSInst_FS(ir)); - rv.w = ieee754dp_2008class(fs); - rfmt = w_fmt; + rv.l = ieee754dp_2008class(fs); + rfmt = l_fmt; break; } @@ -2157,6 +2213,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(min_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmin(fs, ft); @@ -2169,6 +2226,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(mina_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmina(fs, ft); @@ -2181,6 +2239,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(max_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmax(fs, ft); @@ -2193,6 +2252,7 @@ copcsr: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(maxa_d); DPFROMREG(ft, MIPSInst_FT(ir)); DPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fmaxa(fs, ft); @@ -2200,15 +2260,18 @@ copcsr: } case fabs_op: + MIPS_FPU_EMU_INC_STATS(abs_d); handler.u = ieee754dp_abs; goto dcopuop; case fneg_op: + MIPS_FPU_EMU_INC_STATS(neg_d); handler.u = ieee754dp_neg; goto dcopuop; case fmov_op: /* an easy one */ + MIPS_FPU_EMU_INC_STATS(mov_d); DPFROMREG(rv.d, MIPSInst_FS(ir)); goto copcsr; @@ -2228,6 +2291,7 @@ dcopuop: * unary conv ops */ case fcvts_op: + MIPS_FPU_EMU_INC_STATS(cvt_s_d); DPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fdp(fs); rfmt = s_fmt; @@ -2237,6 +2301,7 @@ dcopuop: return SIGILL; /* not defined */ case fcvtw_op: + MIPS_FPU_EMU_INC_STATS(cvt_w_d); DPFROMREG(fs, MIPSInst_FS(ir)); rv.w = ieee754dp_tint(fs); /* wrong */ rfmt = w_fmt; @@ -2249,6 +2314,15 @@ dcopuop: if (!cpu_has_mips_2_3_4_5_r) return SIGILL; + if (MIPSInst_FUNC(ir) == fceil_op) + MIPS_FPU_EMU_INC_STATS(ceil_w_d); + if (MIPSInst_FUNC(ir) == ffloor_op) + MIPS_FPU_EMU_INC_STATS(floor_w_d); + if (MIPSInst_FUNC(ir) == fround_op) + MIPS_FPU_EMU_INC_STATS(round_w_d); + if (MIPSInst_FUNC(ir) == ftrunc_op) + MIPS_FPU_EMU_INC_STATS(trunc_w_d); + oldrm = ieee754_csr.rm; DPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -2261,6 +2335,7 @@ dcopuop: if (!cpu_has_mips_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(sel_d); DPFROMREG(fd, MIPSInst_FD(ir)); if (fd.bits & 0x1) DPFROMREG(rv.d, MIPSInst_FT(ir)); @@ -2272,6 +2347,7 @@ dcopuop: if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + MIPS_FPU_EMU_INC_STATS(cvt_l_d); DPFROMREG(fs, MIPSInst_FS(ir)); rv.l = ieee754dp_tlong(fs); rfmt = l_fmt; @@ -2284,6 +2360,15 @@ dcopuop: if (!cpu_has_mips_3_4_5_64_r2_r6) return SIGILL; + if (MIPSInst_FUNC(ir) == fceill_op) + MIPS_FPU_EMU_INC_STATS(ceil_l_d); + if (MIPSInst_FUNC(ir) == ffloorl_op) + MIPS_FPU_EMU_INC_STATS(floor_l_d); + if (MIPSInst_FUNC(ir) == froundl_op) + MIPS_FPU_EMU_INC_STATS(round_l_d); + if (MIPSInst_FUNC(ir) == ftruncl_op) + MIPS_FPU_EMU_INC_STATS(trunc_l_d); + oldrm = ieee754_csr.rm; DPFROMREG(fs, MIPSInst_FS(ir)); ieee754_csr.rm = MIPSInst_FUNC(ir); @@ -2325,12 +2410,14 @@ dcopuop: switch (MIPSInst_FUNC(ir)) { case fcvts_op: /* convert word to single precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_s_w); SPFROMREG(fs, MIPSInst_FS(ir)); rv.s = ieee754sp_fint(fs.bits); rfmt = s_fmt; goto copcsr; case fcvtd_op: /* convert word to double precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_d_w); SPFROMREG(fs, MIPSInst_FS(ir)); rv.d = ieee754dp_fint(fs.bits); rfmt = d_fmt; @@ -2350,6 +2437,90 @@ dcopuop: (MIPSInst_FUNC(ir) & 0x20)) return SIGILL; + if (!sig) { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_af_s); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_un_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_eq_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ueq_s); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_lt_s); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_ult_s); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_le_s); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_ule_s); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_or_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_une_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ne_s); + break; + } + } + } else { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_saf_s); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sun_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_seq_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sueq_s); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_slt_s); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_sult_s); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_sle_s); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_sule_s); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sor_s); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_sune_s); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sne_s); + break; + } + } + } + /* fmt is w_fmt for single precision so fix it */ rfmt = s_fmt; /* default to false */ @@ -2387,13 +2558,13 @@ dcopuop: break; default: /* Reserved R6 ops */ - pr_err("Reserved MIPS R6 CMP.condn.S operation\n"); return SIGILL; } } break; } } + break; } case l_fmt: @@ -2406,11 +2577,13 @@ dcopuop: switch (MIPSInst_FUNC(ir)) { case fcvts_op: /* convert long to single precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_s_l); rv.s = ieee754sp_flong(bits); rfmt = s_fmt; goto copcsr; case fcvtd_op: /* convert long to double precision real */ + MIPS_FPU_EMU_INC_STATS(cvt_d_l); rv.d = ieee754dp_flong(bits); rfmt = d_fmt; goto copcsr; @@ -2424,6 +2597,90 @@ dcopuop: (MIPSInst_FUNC(ir) & 0x20)) return SIGILL; + if (!sig) { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_af_d); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_un_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_eq_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ueq_d); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_lt_d); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_ult_d); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_le_d); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_ule_d); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_or_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_une_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_ne_d); + break; + } + } + } else { + if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) { + switch (cmpop) { + case 0: + MIPS_FPU_EMU_INC_STATS(cmp_saf_d); + break; + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sun_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_seq_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sueq_d); + break; + case 4: + MIPS_FPU_EMU_INC_STATS(cmp_slt_d); + break; + case 5: + MIPS_FPU_EMU_INC_STATS(cmp_sult_d); + break; + case 6: + MIPS_FPU_EMU_INC_STATS(cmp_sle_d); + break; + case 7: + MIPS_FPU_EMU_INC_STATS(cmp_sule_d); + break; + } + } else { + switch (cmpop) { + case 1: + MIPS_FPU_EMU_INC_STATS(cmp_sor_d); + break; + case 2: + MIPS_FPU_EMU_INC_STATS(cmp_sune_d); + break; + case 3: + MIPS_FPU_EMU_INC_STATS(cmp_sne_d); + break; + } + } + } + /* fmt is l_fmt for double precision so fix it */ rfmt = d_fmt; /* default to false */ @@ -2461,13 +2718,14 @@ dcopuop: break; default: /* Reserved R6 ops */ - pr_err("Reserved MIPS R6 CMP.condn.D operation\n"); return SIGILL; } } break; } } + break; + default: return SIGILL; } @@ -2553,7 +2811,7 @@ dcopuop: * For simplicity we always terminate upon an ISA mode switch. */ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, - int has_fpu, void *__user *fault_addr) + int has_fpu, void __user **fault_addr) { unsigned long oldepc, prevepc; struct mm_decoded_insn dec_insn; diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c index fd71b8daaaf2..5bec64f2884e 100644 --- a/arch/mips/math-emu/dp_fmax.c +++ b/arch/mips/math-emu/dp_fmax.c @@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) return ys ? x : y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) else if (xs < ys) return x; - /* Compare exponent */ - if (xe > ye) - return x; - else if (xe < ye) - return y; + /* Signs of inputs are equal, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } else { + /* Inputs are both negative */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return y; + return x; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return y; - return x; + return x; + return y; } union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) @@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754dp_inf(xs & ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): @@ -171,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): return x; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): @@ -180,9 +220,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) return y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) return y; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) return y; - return x; + else if (xm > ym) + return x; + else if (xs == 0) + return x; + return y; } diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c index c1072b0dfb95..a287b23818d8 100644 --- a/arch/mips/math-emu/dp_fmin.c +++ b/arch/mips/math-emu/dp_fmin.c @@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) return ys ? y : x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) else if (xs < ys) return y; - /* Compare exponent */ - if (xe > ye) - return y; - else if (xe < ye) - return x; + /* Signs of inputs are the same, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } else { + /* Inputs are both negative */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return x; + return y; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return x; - return y; + return y; + return x; } union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) @@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754dp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,25 +202,25 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754dp_inf(xs | ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; + return y; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return y; + return x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754dp_zero(1); + return ieee754dp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; @@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) return x; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) + return x; + else if (xm > ym) + return y; + else if (xs == 1) return x; return y; } diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c index caa62f20a888..e0d9be5fbf4c 100644 --- a/arch/mips/math-emu/dp_maddf.c +++ b/arch/mips/math-emu/dp_maddf.c @@ -14,22 +14,45 @@ #include "ieee754dp.h" -enum maddf_flags { - maddf_negate_product = 1 << 0, -}; + +/* 128 bits shift right logical with rounding. */ +void srl128(u64 *hptr, u64 *lptr, int count) +{ + u64 low; + + if (count >= 128) { + *lptr = *hptr != 0 || *lptr != 0; + *hptr = 0; + } else if (count >= 64) { + if (count == 64) { + *lptr = *hptr | (*lptr != 0); + } else { + low = *lptr; + *lptr = *hptr >> (count - 64); + *lptr |= (*hptr << (128 - count)) != 0 || low != 0; + } + *hptr = 0; + } else { + low = *lptr; + *lptr = low >> count | *hptr << (64 - count); + *lptr |= (low << (64 - count)) != 0; + *hptr = *hptr >> count; + } +} static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, union ieee754dp y, enum maddf_flags flags) { int re; int rs; - u64 rm; unsigned lxm; unsigned hxm; unsigned lym; unsigned hym; u64 lrm; u64 hrm; + u64 lzm; + u64 hzm; u64 t; u64 at; int s; @@ -48,52 +71,34 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, ieee754_clearcx(); - switch (zc) { - case IEEE754_CLASS_SNAN: - ieee754_setcx(IEEE754_INVALID_OPERATION); + /* + * Handle the cases when at least one of x, y or z is a NaN. + * Order of precedence is sNaN, qNaN and z, x, y. + */ + if (zc == IEEE754_CLASS_SNAN) return ieee754dp_nanxcpt(z); - case IEEE754_CLASS_DNORM: - DPDNORMZ; - /* QNAN and ZERO cases are handled separately below */ - } - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + if (xc == IEEE754_CLASS_SNAN) return ieee754dp_nanxcpt(x); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + if (yc == IEEE754_CLASS_SNAN) + return ieee754dp_nanxcpt(y); + if (zc == IEEE754_CLASS_QNAN) + return z; + if (xc == IEEE754_CLASS_QNAN) + return x; + if (yc == IEEE754_CLASS_QNAN) return y; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; + if (zc == IEEE754_CLASS_DNORM) + DPDNORMZ; + /* ZERO z cases are handled separately below */ + switch (CLPAIR(xc, yc)) { /* * Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; ieee754_setcx(IEEE754_INVALID_OPERATION); return ieee754dp_indef(); @@ -102,9 +107,27 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; - return ieee754dp_inf(xs ^ ys); + if ((zc == IEEE754_CLASS_INF) && + ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { + /* + * Cases of addition of infinities with opposite signs + * or subtraction of infinities with same signs. + */ + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754dp_indef(); + } + /* + * z is here either not an infinity, or an infinity having the + * same sign as product (x*y) (in case of MADDF.D instruction) + * or product -(x*y) (in MSUBF.D case). The result must be an + * infinity, and its sign is determined only by the value of + * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. + */ + if (flags & MADDF_NEGATE_PRODUCT) + return ieee754dp_inf(1 ^ (xs ^ ys)); + else + return ieee754dp_inf(xs ^ ys); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): @@ -113,32 +136,42 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); - /* Multiplication is 0 so just return z */ + if (zc == IEEE754_CLASS_ZERO) { + /* Handle cases +0 + (-0) and similar ones. */ + if ((!(flags & MADDF_NEGATE_PRODUCT) + && (zs == (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) + && (zs != (xs ^ ys)))) + /* + * Cases of addition of zeros of equal signs + * or subtraction of zeroes of opposite signs. + * The sign of the resulting zero is in any + * such case determined only by the sign of z. + */ + return z; + + return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); + } + /* x*y is here 0, and z is not 0, so just return z */ return z; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): DPDNORMX; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); DPDNORMY; break; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); DPDNORMX; break; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754dp_inf(zs); /* fall through to real computations */ } @@ -157,7 +190,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, re = xe + ye; rs = xs ^ ys; - if (flags & maddf_negate_product) + if (flags & MADDF_NEGATE_PRODUCT) rs ^= 1; /* shunt to top of word */ @@ -165,7 +198,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, ym <<= 64 - (DP_FBITS + 1); /* - * Multiply 64 bits xm, ym to give high 64 bits rm with stickness. + * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm. */ /* 32 * 32 => 64 */ @@ -195,81 +228,110 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, hrm = hrm + (t >> 32); - rm = hrm | (lrm != 0); - - /* - * Sticky shift down to normal rounding precision. - */ - if ((s64) rm < 0) { - rm = (rm >> (64 - (DP_FBITS + 1 + 3))) | - ((rm << (DP_FBITS + 1 + 3)) != 0); + /* Put explicit bit at bit 126 if necessary */ + if ((int64_t)hrm < 0) { + lrm = (hrm << 63) | (lrm >> 1); + hrm = hrm >> 1; re++; - } else { - rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) | - ((rm << (DP_FBITS + 1 + 3 + 1)) != 0); } - assert(rm & (DP_HIDDEN_BIT << 3)); - if (zc == IEEE754_CLASS_ZERO) - return ieee754dp_format(rs, re, rm); + assert(hrm & (1 << 62)); - /* And now the addition */ - assert(zm & DP_HIDDEN_BIT); + if (zc == IEEE754_CLASS_ZERO) { + /* + * Move explicit bit from bit 126 to bit 55 since the + * ieee754dp_format code expects the mantissa to be + * 56 bits wide (53 + 3 rounding bits). + */ + srl128(&hrm, &lrm, (126 - 55)); + return ieee754dp_format(rs, re, lrm); + } - /* - * Provide guard,round and stick bit space. - */ - zm <<= 3; + /* Move explicit bit from bit 52 to bit 126 */ + lzm = 0; + hzm = zm << 10; + assert(hzm & (1 << 62)); + /* Make the exponents the same */ if (ze > re) { /* * Have to shift y fraction right to align. */ s = ze - re; - rm = XDPSRS(rm, s); + srl128(&hrm, &lrm, s); re += s; } else if (re > ze) { /* * Have to shift x fraction right to align. */ s = re - ze; - zm = XDPSRS(zm, s); + srl128(&hzm, &lzm, s); ze += s; } assert(ze == re); assert(ze <= DP_EMAX); + /* Do the addition */ if (zs == rs) { /* - * Generate 28 bit result of adding two 27 bit numbers - * leaving result in xm, xs and xe. + * Generate 128 bit result by adding two 127 bit numbers + * leaving result in hzm:lzm, zs and ze. */ - zm = zm + rm; - - if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */ - zm = XDPSRS1(zm); + hzm = hzm + hrm + (lzm > (lzm + lrm)); + lzm = lzm + lrm; + if ((int64_t)hzm < 0) { /* carry out */ + srl128(&hzm, &lzm, 1); ze++; } } else { - if (zm >= rm) { - zm = zm - rm; + if (hzm > hrm || (hzm == hrm && lzm >= lrm)) { + hzm = hzm - hrm - (lzm < lrm); + lzm = lzm - lrm; } else { - zm = rm - zm; + hzm = hrm - hzm - (lrm < lzm); + lzm = lrm - lzm; zs = rs; } - if (zm == 0) + if (lzm == 0 && hzm == 0) return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD); /* - * Normalize to rounding precision. + * Put explicit bit at bit 126 if necessary. */ - while ((zm >> (DP_FBITS + 3)) == 0) { - zm <<= 1; - ze--; + if (hzm == 0) { + /* left shift by 63 or 64 bits */ + if ((int64_t)lzm < 0) { + /* MSB of lzm is the explicit bit */ + hzm = lzm >> 1; + lzm = lzm << 63; + ze -= 63; + } else { + hzm = lzm; + lzm = 0; + ze -= 64; + } + } + + t = 0; + while ((hzm >> (62 - t)) == 0) + t++; + + assert(t <= 62); + if (t) { + hzm = hzm << t | lzm >> (64 - t); + lzm = lzm << t; + ze -= t; } } - return ieee754dp_format(zs, ze, zm); + /* + * Move explicit bit from bit 126 to bit 55 since the + * ieee754dp_format code expects the mantissa to be + * 56 bits wide (53 + 3 rounding bits). + */ + srl128(&hzm, &lzm, (126 - 55)); + + return ieee754dp_format(zs, ze, lzm); } union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, @@ -281,5 +343,5 @@ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x, union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x, union ieee754dp y) { - return _dp_maddf(z, x, y, maddf_negate_product); + return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); } diff --git a/arch/mips/math-emu/dp_rint.c b/arch/mips/math-emu/dp_rint.c new file mode 100644 index 000000000000..c3b9077ff357 --- /dev/null +++ b/arch/mips/math-emu/dp_rint.c @@ -0,0 +1,89 @@ +/* IEEE754 floating point arithmetic + * double precision: common utilities + */ +/* + * MIPS floating point support + * Copyright (C) 1994-2000 Algorithmics Ltd. + * Copyright (C) 2017 Imagination Technologies, Ltd. + * Author: Aleksandar Markovic + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. + */ + +#include "ieee754dp.h" + +union ieee754dp ieee754dp_rint(union ieee754dp x) +{ + union ieee754dp ret; + u64 residue; + int sticky; + int round; + int odd; + + COMPXDP; + + ieee754_clearcx(); + + EXPLODEXDP; + FLUSHXDP; + + if (xc == IEEE754_CLASS_SNAN) + return ieee754dp_nanxcpt(x); + + if ((xc == IEEE754_CLASS_QNAN) || + (xc == IEEE754_CLASS_INF) || + (xc == IEEE754_CLASS_ZERO)) + return x; + + if (xe >= DP_FBITS) + return x; + + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; + } else { + residue = xm << (64 - DP_FBITS + xe); + round = (residue >> 63) != 0; + sticky = (residue << 1) != 0; + xm >>= DP_FBITS - xe; + } + + odd = (xm & 0x1) != 0x0; + + switch (ieee754_csr.rm) { + case FPU_CSR_RN: /* toward nearest */ + if (round && (sticky || odd)) + xm++; + break; + case FPU_CSR_RZ: /* toward zero */ + break; + case FPU_CSR_RU: /* toward +infinity */ + if ((round || sticky) && !xs) + xm++; + break; + case FPU_CSR_RD: /* toward -infinity */ + if ((round || sticky) && xs) + xm++; + break; + } + + if (round || sticky) + ieee754_setcx(IEEE754_INEXACT); + + ret = ieee754dp_flong(xm); + DPSIGN(ret) = xs; + + return ret; +} diff --git a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c index b6bfd3625369..5450f4d1c920 100644 --- a/arch/mips/math-emu/dsemul.c +++ b/arch/mips/math-emu/dsemul.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h index d3be351aed15..92dc8fa565cb 100644 --- a/arch/mips/math-emu/ieee754.h +++ b/arch/mips/math-emu/ieee754.h @@ -67,6 +67,7 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y); union ieee754sp ieee754sp_fint(int x); union ieee754sp ieee754sp_flong(s64 x); union ieee754sp ieee754sp_fdp(union ieee754dp x); +union ieee754sp ieee754sp_rint(union ieee754sp x); int ieee754sp_tint(union ieee754sp x); s64 ieee754sp_tlong(union ieee754sp x); @@ -101,6 +102,7 @@ union ieee754dp ieee754dp_neg(union ieee754dp x); union ieee754dp ieee754dp_fint(int x); union ieee754dp ieee754dp_flong(s64 x); union ieee754dp ieee754dp_fsp(union ieee754sp x); +union ieee754dp ieee754dp_rint(union ieee754dp x); int ieee754dp_tint(union ieee754dp x); s64 ieee754dp_tlong(union ieee754dp x); diff --git a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h index 8bc2f6963324..dd2071f430e0 100644 --- a/arch/mips/math-emu/ieee754int.h +++ b/arch/mips/math-emu/ieee754int.h @@ -26,6 +26,10 @@ #define CLPAIR(x, y) ((x)*6+(y)) +enum maddf_flags { + MADDF_NEGATE_PRODUCT = 1 << 0, +}; + static inline void ieee754_clearcx(void) { ieee754_csr.cx = 0; diff --git a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h index 8476067075fe..0f63e4202cff 100644 --- a/arch/mips/math-emu/ieee754sp.h +++ b/arch/mips/math-emu/ieee754sp.h @@ -45,6 +45,10 @@ static inline int ieee754sp_finite(union ieee754sp x) return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS; } +/* 64 bit right shift with rounding */ +#define XSPSRS64(v, rs) \ + (((rs) >= 64) ? ((v) != 0) : ((v) >> (rs)) | ((v) << (64-(rs)) != 0)) + /* 3bit extended single precision sticky right shift */ #define XSPSRS(v, rs) \ ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0)) diff --git a/arch/mips/math-emu/me-debugfs.c b/arch/mips/math-emu/me-debugfs.c index be650ed7db59..62566385ce0e 100644 --- a/arch/mips/math-emu/me-debugfs.c +++ b/arch/mips/math-emu/me-debugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -28,14 +29,190 @@ static int fpuemu_stat_get(void *data, u64 *val) } DEFINE_SIMPLE_ATTRIBUTE(fops_fpuemu_stat, fpuemu_stat_get, NULL, "%llu\n"); +/* + * Used to obtain names for a debugfs instruction counter, given field name + * in fpuemustats structure. For example, for input "cmp_sueq_d", the output + * would be "cmp.sueq.d". This is needed since dots are not allowed to be + * used in structure field names, and are, on the other hand, desired to be + * used in debugfs item names to be clearly associated to corresponding + * MIPS FPU instructions. + */ +static void adjust_instruction_counter_name(char *out_name, char *in_name) +{ + int i = 0; + + strcpy(out_name, in_name); + while (in_name[i] != '\0') { + if (out_name[i] == '_') + out_name[i] = '.'; + i++; + } +} + +static int fpuemustats_clear_show(struct seq_file *s, void *unused) +{ + __this_cpu_write((fpuemustats).emulated, 0); + __this_cpu_write((fpuemustats).loads, 0); + __this_cpu_write((fpuemustats).stores, 0); + __this_cpu_write((fpuemustats).branches, 0); + __this_cpu_write((fpuemustats).cp1ops, 0); + __this_cpu_write((fpuemustats).cp1xops, 0); + __this_cpu_write((fpuemustats).errors, 0); + __this_cpu_write((fpuemustats).ieee754_inexact, 0); + __this_cpu_write((fpuemustats).ieee754_underflow, 0); + __this_cpu_write((fpuemustats).ieee754_overflow, 0); + __this_cpu_write((fpuemustats).ieee754_zerodiv, 0); + __this_cpu_write((fpuemustats).ieee754_invalidop, 0); + __this_cpu_write((fpuemustats).ds_emul, 0); + + __this_cpu_write((fpuemustats).abs_s, 0); + __this_cpu_write((fpuemustats).abs_d, 0); + __this_cpu_write((fpuemustats).add_s, 0); + __this_cpu_write((fpuemustats).add_d, 0); + __this_cpu_write((fpuemustats).bc1eqz, 0); + __this_cpu_write((fpuemustats).bc1nez, 0); + __this_cpu_write((fpuemustats).ceil_w_s, 0); + __this_cpu_write((fpuemustats).ceil_w_d, 0); + __this_cpu_write((fpuemustats).ceil_l_s, 0); + __this_cpu_write((fpuemustats).ceil_l_d, 0); + __this_cpu_write((fpuemustats).class_s, 0); + __this_cpu_write((fpuemustats).class_d, 0); + __this_cpu_write((fpuemustats).cmp_af_s, 0); + __this_cpu_write((fpuemustats).cmp_af_d, 0); + __this_cpu_write((fpuemustats).cmp_eq_s, 0); + __this_cpu_write((fpuemustats).cmp_eq_d, 0); + __this_cpu_write((fpuemustats).cmp_le_s, 0); + __this_cpu_write((fpuemustats).cmp_le_d, 0); + __this_cpu_write((fpuemustats).cmp_lt_s, 0); + __this_cpu_write((fpuemustats).cmp_lt_d, 0); + __this_cpu_write((fpuemustats).cmp_ne_s, 0); + __this_cpu_write((fpuemustats).cmp_ne_d, 0); + __this_cpu_write((fpuemustats).cmp_or_s, 0); + __this_cpu_write((fpuemustats).cmp_or_d, 0); + __this_cpu_write((fpuemustats).cmp_ueq_s, 0); + __this_cpu_write((fpuemustats).cmp_ueq_d, 0); + __this_cpu_write((fpuemustats).cmp_ule_s, 0); + __this_cpu_write((fpuemustats).cmp_ule_d, 0); + __this_cpu_write((fpuemustats).cmp_ult_s, 0); + __this_cpu_write((fpuemustats).cmp_ult_d, 0); + __this_cpu_write((fpuemustats).cmp_un_s, 0); + __this_cpu_write((fpuemustats).cmp_un_d, 0); + __this_cpu_write((fpuemustats).cmp_une_s, 0); + __this_cpu_write((fpuemustats).cmp_une_d, 0); + __this_cpu_write((fpuemustats).cmp_saf_s, 0); + __this_cpu_write((fpuemustats).cmp_saf_d, 0); + __this_cpu_write((fpuemustats).cmp_seq_s, 0); + __this_cpu_write((fpuemustats).cmp_seq_d, 0); + __this_cpu_write((fpuemustats).cmp_sle_s, 0); + __this_cpu_write((fpuemustats).cmp_sle_d, 0); + __this_cpu_write((fpuemustats).cmp_slt_s, 0); + __this_cpu_write((fpuemustats).cmp_slt_d, 0); + __this_cpu_write((fpuemustats).cmp_sne_s, 0); + __this_cpu_write((fpuemustats).cmp_sne_d, 0); + __this_cpu_write((fpuemustats).cmp_sor_s, 0); + __this_cpu_write((fpuemustats).cmp_sor_d, 0); + __this_cpu_write((fpuemustats).cmp_sueq_s, 0); + __this_cpu_write((fpuemustats).cmp_sueq_d, 0); + __this_cpu_write((fpuemustats).cmp_sule_s, 0); + __this_cpu_write((fpuemustats).cmp_sule_d, 0); + __this_cpu_write((fpuemustats).cmp_sult_s, 0); + __this_cpu_write((fpuemustats).cmp_sult_d, 0); + __this_cpu_write((fpuemustats).cmp_sun_s, 0); + __this_cpu_write((fpuemustats).cmp_sun_d, 0); + __this_cpu_write((fpuemustats).cmp_sune_s, 0); + __this_cpu_write((fpuemustats).cmp_sune_d, 0); + __this_cpu_write((fpuemustats).cvt_d_l, 0); + __this_cpu_write((fpuemustats).cvt_d_s, 0); + __this_cpu_write((fpuemustats).cvt_d_w, 0); + __this_cpu_write((fpuemustats).cvt_l_s, 0); + __this_cpu_write((fpuemustats).cvt_l_d, 0); + __this_cpu_write((fpuemustats).cvt_s_d, 0); + __this_cpu_write((fpuemustats).cvt_s_l, 0); + __this_cpu_write((fpuemustats).cvt_s_w, 0); + __this_cpu_write((fpuemustats).cvt_w_s, 0); + __this_cpu_write((fpuemustats).cvt_w_d, 0); + __this_cpu_write((fpuemustats).div_s, 0); + __this_cpu_write((fpuemustats).div_d, 0); + __this_cpu_write((fpuemustats).floor_w_s, 0); + __this_cpu_write((fpuemustats).floor_w_d, 0); + __this_cpu_write((fpuemustats).floor_l_s, 0); + __this_cpu_write((fpuemustats).floor_l_d, 0); + __this_cpu_write((fpuemustats).maddf_s, 0); + __this_cpu_write((fpuemustats).maddf_d, 0); + __this_cpu_write((fpuemustats).max_s, 0); + __this_cpu_write((fpuemustats).max_d, 0); + __this_cpu_write((fpuemustats).maxa_s, 0); + __this_cpu_write((fpuemustats).maxa_d, 0); + __this_cpu_write((fpuemustats).min_s, 0); + __this_cpu_write((fpuemustats).min_d, 0); + __this_cpu_write((fpuemustats).mina_s, 0); + __this_cpu_write((fpuemustats).mina_d, 0); + __this_cpu_write((fpuemustats).mov_s, 0); + __this_cpu_write((fpuemustats).mov_d, 0); + __this_cpu_write((fpuemustats).msubf_s, 0); + __this_cpu_write((fpuemustats).msubf_d, 0); + __this_cpu_write((fpuemustats).mul_s, 0); + __this_cpu_write((fpuemustats).mul_d, 0); + __this_cpu_write((fpuemustats).neg_s, 0); + __this_cpu_write((fpuemustats).neg_d, 0); + __this_cpu_write((fpuemustats).recip_s, 0); + __this_cpu_write((fpuemustats).recip_d, 0); + __this_cpu_write((fpuemustats).rint_s, 0); + __this_cpu_write((fpuemustats).rint_d, 0); + __this_cpu_write((fpuemustats).round_w_s, 0); + __this_cpu_write((fpuemustats).round_w_d, 0); + __this_cpu_write((fpuemustats).round_l_s, 0); + __this_cpu_write((fpuemustats).round_l_d, 0); + __this_cpu_write((fpuemustats).rsqrt_s, 0); + __this_cpu_write((fpuemustats).rsqrt_d, 0); + __this_cpu_write((fpuemustats).sel_s, 0); + __this_cpu_write((fpuemustats).sel_d, 0); + __this_cpu_write((fpuemustats).seleqz_s, 0); + __this_cpu_write((fpuemustats).seleqz_d, 0); + __this_cpu_write((fpuemustats).selnez_s, 0); + __this_cpu_write((fpuemustats).selnez_d, 0); + __this_cpu_write((fpuemustats).sqrt_s, 0); + __this_cpu_write((fpuemustats).sqrt_d, 0); + __this_cpu_write((fpuemustats).sub_s, 0); + __this_cpu_write((fpuemustats).sub_d, 0); + __this_cpu_write((fpuemustats).trunc_w_s, 0); + __this_cpu_write((fpuemustats).trunc_w_d, 0); + __this_cpu_write((fpuemustats).trunc_l_s, 0); + __this_cpu_write((fpuemustats).trunc_l_d, 0); + + return 0; +} + +static int fpuemustats_clear_open(struct inode *inode, struct file *file) +{ + return single_open(file, fpuemustats_clear_show, inode->i_private); +} + +static const struct file_operations fpuemustats_clear_fops = { + .open = fpuemustats_clear_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int __init debugfs_fpuemu(void) { - struct dentry *d, *dir; + struct dentry *fpuemu_debugfs_base_dir; + struct dentry *fpuemu_debugfs_inst_dir; + struct dentry *d, *reset_file; if (!mips_debugfs_dir) return -ENODEV; - dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); - if (!dir) + + fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats", + mips_debugfs_dir); + if (!fpuemu_debugfs_base_dir) + return -ENOMEM; + + reset_file = debugfs_create_file("fpuemustats_clear", 0444, + mips_debugfs_dir, NULL, + &fpuemustats_clear_fops); + if (!reset_file) return -ENOMEM; #define FPU_EMU_STAT_OFFSET(m) \ @@ -43,7 +220,7 @@ static int __init debugfs_fpuemu(void) #define FPU_STAT_CREATE(m) \ do { \ - d = debugfs_create_file(#m , S_IRUGO, dir, \ + d = debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \ (void *)FPU_EMU_STAT_OFFSET(m), \ &fops_fpuemu_stat); \ if (!d) \ @@ -53,6 +230,7 @@ do { \ FPU_STAT_CREATE(emulated); FPU_STAT_CREATE(loads); FPU_STAT_CREATE(stores); + FPU_STAT_CREATE(branches); FPU_STAT_CREATE(cp1ops); FPU_STAT_CREATE(cp1xops); FPU_STAT_CREATE(errors); @@ -63,6 +241,139 @@ do { \ FPU_STAT_CREATE(ieee754_invalidop); FPU_STAT_CREATE(ds_emul); + fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions", + fpuemu_debugfs_base_dir); + if (!fpuemu_debugfs_inst_dir) + return -ENOMEM; + +#define FPU_STAT_CREATE_EX(m) \ +do { \ + char name[32]; \ + \ + adjust_instruction_counter_name(name, #m); \ + \ + d = debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \ + (void *)FPU_EMU_STAT_OFFSET(m), \ + &fops_fpuemu_stat); \ + if (!d) \ + return -ENOMEM; \ +} while (0) + + FPU_STAT_CREATE_EX(abs_s); + FPU_STAT_CREATE_EX(abs_d); + FPU_STAT_CREATE_EX(add_s); + FPU_STAT_CREATE_EX(add_d); + FPU_STAT_CREATE_EX(bc1eqz); + FPU_STAT_CREATE_EX(bc1nez); + FPU_STAT_CREATE_EX(ceil_w_s); + FPU_STAT_CREATE_EX(ceil_w_d); + FPU_STAT_CREATE_EX(ceil_l_s); + FPU_STAT_CREATE_EX(ceil_l_d); + FPU_STAT_CREATE_EX(class_s); + FPU_STAT_CREATE_EX(class_d); + FPU_STAT_CREATE_EX(cmp_af_s); + FPU_STAT_CREATE_EX(cmp_af_d); + FPU_STAT_CREATE_EX(cmp_eq_s); + FPU_STAT_CREATE_EX(cmp_eq_d); + FPU_STAT_CREATE_EX(cmp_le_s); + FPU_STAT_CREATE_EX(cmp_le_d); + FPU_STAT_CREATE_EX(cmp_lt_s); + FPU_STAT_CREATE_EX(cmp_lt_d); + FPU_STAT_CREATE_EX(cmp_ne_s); + FPU_STAT_CREATE_EX(cmp_ne_d); + FPU_STAT_CREATE_EX(cmp_or_s); + FPU_STAT_CREATE_EX(cmp_or_d); + FPU_STAT_CREATE_EX(cmp_ueq_s); + FPU_STAT_CREATE_EX(cmp_ueq_d); + FPU_STAT_CREATE_EX(cmp_ule_s); + FPU_STAT_CREATE_EX(cmp_ule_d); + FPU_STAT_CREATE_EX(cmp_ult_s); + FPU_STAT_CREATE_EX(cmp_ult_d); + FPU_STAT_CREATE_EX(cmp_un_s); + FPU_STAT_CREATE_EX(cmp_un_d); + FPU_STAT_CREATE_EX(cmp_une_s); + FPU_STAT_CREATE_EX(cmp_une_d); + FPU_STAT_CREATE_EX(cmp_saf_s); + FPU_STAT_CREATE_EX(cmp_saf_d); + FPU_STAT_CREATE_EX(cmp_seq_s); + FPU_STAT_CREATE_EX(cmp_seq_d); + FPU_STAT_CREATE_EX(cmp_sle_s); + FPU_STAT_CREATE_EX(cmp_sle_d); + FPU_STAT_CREATE_EX(cmp_slt_s); + FPU_STAT_CREATE_EX(cmp_slt_d); + FPU_STAT_CREATE_EX(cmp_sne_s); + FPU_STAT_CREATE_EX(cmp_sne_d); + FPU_STAT_CREATE_EX(cmp_sor_s); + FPU_STAT_CREATE_EX(cmp_sor_d); + FPU_STAT_CREATE_EX(cmp_sueq_s); + FPU_STAT_CREATE_EX(cmp_sueq_d); + FPU_STAT_CREATE_EX(cmp_sule_s); + FPU_STAT_CREATE_EX(cmp_sule_d); + FPU_STAT_CREATE_EX(cmp_sult_s); + FPU_STAT_CREATE_EX(cmp_sult_d); + FPU_STAT_CREATE_EX(cmp_sun_s); + FPU_STAT_CREATE_EX(cmp_sun_d); + FPU_STAT_CREATE_EX(cmp_sune_s); + FPU_STAT_CREATE_EX(cmp_sune_d); + FPU_STAT_CREATE_EX(cvt_d_l); + FPU_STAT_CREATE_EX(cvt_d_s); + FPU_STAT_CREATE_EX(cvt_d_w); + FPU_STAT_CREATE_EX(cvt_l_s); + FPU_STAT_CREATE_EX(cvt_l_d); + FPU_STAT_CREATE_EX(cvt_s_d); + FPU_STAT_CREATE_EX(cvt_s_l); + FPU_STAT_CREATE_EX(cvt_s_w); + FPU_STAT_CREATE_EX(cvt_w_s); + FPU_STAT_CREATE_EX(cvt_w_d); + FPU_STAT_CREATE_EX(div_s); + FPU_STAT_CREATE_EX(div_d); + FPU_STAT_CREATE_EX(floor_w_s); + FPU_STAT_CREATE_EX(floor_w_d); + FPU_STAT_CREATE_EX(floor_l_s); + FPU_STAT_CREATE_EX(floor_l_d); + FPU_STAT_CREATE_EX(maddf_s); + FPU_STAT_CREATE_EX(maddf_d); + FPU_STAT_CREATE_EX(max_s); + FPU_STAT_CREATE_EX(max_d); + FPU_STAT_CREATE_EX(maxa_s); + FPU_STAT_CREATE_EX(maxa_d); + FPU_STAT_CREATE_EX(min_s); + FPU_STAT_CREATE_EX(min_d); + FPU_STAT_CREATE_EX(mina_s); + FPU_STAT_CREATE_EX(mina_d); + FPU_STAT_CREATE_EX(mov_s); + FPU_STAT_CREATE_EX(mov_d); + FPU_STAT_CREATE_EX(msubf_s); + FPU_STAT_CREATE_EX(msubf_d); + FPU_STAT_CREATE_EX(mul_s); + FPU_STAT_CREATE_EX(mul_d); + FPU_STAT_CREATE_EX(neg_s); + FPU_STAT_CREATE_EX(neg_d); + FPU_STAT_CREATE_EX(recip_s); + FPU_STAT_CREATE_EX(recip_d); + FPU_STAT_CREATE_EX(rint_s); + FPU_STAT_CREATE_EX(rint_d); + FPU_STAT_CREATE_EX(round_w_s); + FPU_STAT_CREATE_EX(round_w_d); + FPU_STAT_CREATE_EX(round_l_s); + FPU_STAT_CREATE_EX(round_l_d); + FPU_STAT_CREATE_EX(rsqrt_s); + FPU_STAT_CREATE_EX(rsqrt_d); + FPU_STAT_CREATE_EX(sel_s); + FPU_STAT_CREATE_EX(sel_d); + FPU_STAT_CREATE_EX(seleqz_s); + FPU_STAT_CREATE_EX(seleqz_d); + FPU_STAT_CREATE_EX(selnez_s); + FPU_STAT_CREATE_EX(selnez_d); + FPU_STAT_CREATE_EX(sqrt_s); + FPU_STAT_CREATE_EX(sqrt_d); + FPU_STAT_CREATE_EX(sub_s); + FPU_STAT_CREATE_EX(sub_d); + FPU_STAT_CREATE_EX(trunc_w_s); + FPU_STAT_CREATE_EX(trunc_w_d); + FPU_STAT_CREATE_EX(trunc_l_s); + FPU_STAT_CREATE_EX(trunc_l_d); + return 0; } arch_initcall(debugfs_fpuemu); diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c index 4d000844e48e..74a5a00d2f22 100644 --- a/arch/mips/math-emu/sp_fmax.c +++ b/arch/mips/math-emu/sp_fmax.c @@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) return ys ? x : y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) else if (xs < ys) return x; - /* Compare exponent */ - if (xe > ye) - return x; - else if (xe < ye) - return y; + /* Signs of inputs are equal, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } else { + /* Inputs are both negative */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return y; + return x; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return y; - return x; + return x; + return y; } union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) @@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754sp_inf(xs & ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): @@ -171,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): return x; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): @@ -180,9 +220,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) return y; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs & ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) return y; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) return y; - return x; + else if (xm > ym) + return x; + else if (xs == 0) + return x; + return y; } diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c index 4eb1bb9e9dec..c51385f46b09 100644 --- a/arch/mips/math-emu/sp_fmin.c +++ b/arch/mips/math-emu/sp_fmin.c @@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) return ys ? y : x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) else if (xs < ys) return y; - /* Compare exponent */ - if (xe > ye) - return y; - else if (xe < ye) - return x; + /* Signs of inputs are the same, let's compare exponents */ + if (xs == 0) { + /* Inputs are both positive */ + if (xe > ye) + return y; + else if (xe < ye) + return x; + } else { + /* Inputs are both negative */ + if (xe > ye) + return x; + else if (xe < ye) + return y; + } - /* Compare mantissa */ + /* Signs and exponents of inputs are equal, let's compare mantissas */ + if (xs == 0) { + /* Inputs are both positive, with equal signs and exponents */ + if (xm <= ym) + return x; + return y; + } + /* Inputs are both negative, with equal signs and exponents */ if (xm <= ym) - return x; - return y; + return y; + return x; } union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) @@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): return ieee754sp_nanxcpt(x); - /* numbers are preferred to NaNs */ + /* + * Quiet NaN handling + */ + + /* + * The case of both inputs quiet NaNs + */ + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + return x; + + /* + * The cases of exactly one input quiet NaN (numbers + * are here preferred as returned values to NaNs) + */ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return x; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -164,25 +202,25 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) /* * Infinity and zero handling */ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + return ieee754sp_inf(xs | ys); + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; + return y; - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return y; + return x; case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - return ieee754sp_zero(1); + return ieee754sp_zero(xs | ys); case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; @@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) return x; /* Compare mantissa */ - if (xm <= ym) + if (xm < ym) + return x; + else if (xm > ym) + return y; + else if (xs == 1) return x; return y; } diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c index c91d5e5d9b5f..7195fe785d81 100644 --- a/arch/mips/math-emu/sp_maddf.c +++ b/arch/mips/math-emu/sp_maddf.c @@ -14,9 +14,6 @@ #include "ieee754sp.h" -enum maddf_flags { - maddf_negate_product = 1 << 0, -}; static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, union ieee754sp y, enum maddf_flags flags) @@ -24,14 +21,8 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, int re; int rs; unsigned rm; - unsigned short lxm; - unsigned short hxm; - unsigned short lym; - unsigned short hym; - unsigned lrm; - unsigned hrm; - unsigned t; - unsigned at; + uint64_t rm64; + uint64_t zm64; int s; COMPXSP; @@ -48,51 +39,35 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, ieee754_clearcx(); - switch (zc) { - case IEEE754_CLASS_SNAN: - ieee754_setcx(IEEE754_INVALID_OPERATION); + /* + * Handle the cases when at least one of x, y or z is a NaN. + * Order of precedence is sNaN, qNaN and z, x, y. + */ + if (zc == IEEE754_CLASS_SNAN) return ieee754sp_nanxcpt(z); - case IEEE754_CLASS_DNORM: - SPDNORMZ; - /* QNAN and ZERO cases are handled separately below */ - } - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + if (xc == IEEE754_CLASS_SNAN) return ieee754sp_nanxcpt(x); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + if (yc == IEEE754_CLASS_SNAN) + return ieee754sp_nanxcpt(y); + if (zc == IEEE754_CLASS_QNAN) + return z; + if (xc == IEEE754_CLASS_QNAN) + return x; + if (yc == IEEE754_CLASS_QNAN) return y; - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; + if (zc == IEEE754_CLASS_DNORM) + SPDNORMZ; + /* ZERO z cases are handled separately below */ + + switch (CLPAIR(xc, yc)) { + /* * Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; ieee754_setcx(IEEE754_INVALID_OPERATION); return ieee754sp_indef(); @@ -101,9 +76,27 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (zc == IEEE754_CLASS_QNAN) - return z; - return ieee754sp_inf(xs ^ ys); + if ((zc == IEEE754_CLASS_INF) && + ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) { + /* + * Cases of addition of infinities with opposite signs + * or subtraction of infinities with same signs. + */ + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754sp_indef(); + } + /* + * z is here either not an infinity, or an infinity having the + * same sign as product (x*y) (in case of MADDF.D instruction) + * or product -(x*y) (in MSUBF.D case). The result must be an + * infinity, and its sign is determined only by the value of + * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y. + */ + if (flags & MADDF_NEGATE_PRODUCT) + return ieee754sp_inf(1 ^ (xs ^ ys)); + else + return ieee754sp_inf(xs ^ ys); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): @@ -112,32 +105,42 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); - /* Multiplication is 0 so just return z */ + if (zc == IEEE754_CLASS_ZERO) { + /* Handle cases +0 + (-0) and similar ones. */ + if ((!(flags & MADDF_NEGATE_PRODUCT) + && (zs == (xs ^ ys))) || + ((flags & MADDF_NEGATE_PRODUCT) + && (zs != (xs ^ ys)))) + /* + * Cases of addition of zeros of equal signs + * or subtraction of zeroes of opposite signs. + * The sign of the resulting zero is in any + * such case determined only by the sign of z. + */ + return z; + + return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); + } + /* x*y is here 0, and z is not 0, so just return z */ return z; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): SPDNORMX; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); SPDNORMY; break; case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); SPDNORMX; break; case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - if (zc == IEEE754_CLASS_QNAN) - return z; - else if (zc == IEEE754_CLASS_INF) + if (zc == IEEE754_CLASS_INF) return ieee754sp_inf(zs); /* fall through to real computations */ } @@ -158,111 +161,93 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, re = xe + ye; rs = xs ^ ys; - if (flags & maddf_negate_product) + if (flags & MADDF_NEGATE_PRODUCT) rs ^= 1; - /* shunt to top of word */ - xm <<= 32 - (SP_FBITS + 1); - ym <<= 32 - (SP_FBITS + 1); + /* Multiple 24 bit xm and ym to give 48 bit results */ + rm64 = (uint64_t)xm * ym; - /* - * Multiply 32 bits xm, ym to give high 32 bits rm with stickness. - */ - lxm = xm & 0xffff; - hxm = xm >> 16; - lym = ym & 0xffff; - hym = ym >> 16; + /* Shunt to top of word */ + rm64 = rm64 << 16; - lrm = lxm * lym; /* 16 * 16 => 32 */ - hrm = hxm * hym; /* 16 * 16 => 32 */ - - t = lxm * hym; /* 16 * 16 => 32 */ - at = lrm + (t << 16); - hrm += at < lrm; - lrm = at; - hrm = hrm + (t >> 16); - - t = hxm * lym; /* 16 * 16 => 32 */ - at = lrm + (t << 16); - hrm += at < lrm; - lrm = at; - hrm = hrm + (t >> 16); - - rm = hrm | (lrm != 0); - - /* - * Sticky shift down to normal rounding precision. - */ - if ((int) rm < 0) { - rm = (rm >> (32 - (SP_FBITS + 1 + 3))) | - ((rm << (SP_FBITS + 1 + 3)) != 0); + /* Put explicit bit at bit 62 if necessary */ + if ((int64_t) rm64 < 0) { + rm64 = rm64 >> 1; re++; - } else { - rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) | - ((rm << (SP_FBITS + 1 + 3 + 1)) != 0); } - assert(rm & (SP_HIDDEN_BIT << 3)); - if (zc == IEEE754_CLASS_ZERO) + assert(rm64 & (1 << 62)); + + if (zc == IEEE754_CLASS_ZERO) { + /* + * Move explicit bit from bit 62 to bit 26 since the + * ieee754sp_format code expects the mantissa to be + * 27 bits wide (24 + 3 rounding bits). + */ + rm = XSPSRS64(rm64, (62 - 26)); return ieee754sp_format(rs, re, rm); + } - /* And now the addition */ - - assert(zm & SP_HIDDEN_BIT); - - /* - * Provide guard,round and stick bit space. - */ - zm <<= 3; + /* Move explicit bit from bit 23 to bit 62 */ + zm64 = (uint64_t)zm << (62 - 23); + assert(zm64 & (1 << 62)); + /* Make the exponents the same */ if (ze > re) { /* * Have to shift r fraction right to align. */ s = ze - re; - rm = XSPSRS(rm, s); + rm64 = XSPSRS64(rm64, s); re += s; } else if (re > ze) { /* * Have to shift z fraction right to align. */ s = re - ze; - zm = XSPSRS(zm, s); + zm64 = XSPSRS64(zm64, s); ze += s; } assert(ze == re); assert(ze <= SP_EMAX); + /* Do the addition */ if (zs == rs) { /* - * Generate 28 bit result of adding two 27 bit numbers - * leaving result in zm, zs and ze. + * Generate 64 bit result by adding two 63 bit numbers + * leaving result in zm64, zs and ze. */ - zm = zm + rm; - - if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ - zm = XSPSRS1(zm); + zm64 = zm64 + rm64; + if ((int64_t)zm64 < 0) { /* carry out */ + zm64 = XSPSRS1(zm64); ze++; } } else { - if (zm >= rm) { - zm = zm - rm; + if (zm64 >= rm64) { + zm64 = zm64 - rm64; } else { - zm = rm - zm; + zm64 = rm64 - zm64; zs = rs; } - if (zm == 0) + if (zm64 == 0) return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD); /* - * Normalize in extended single precision + * Put explicit bit at bit 62 if necessary. */ - while ((zm >> (SP_MBITS + 3)) == 0) { - zm <<= 1; + while ((zm64 >> 62) == 0) { + zm64 <<= 1; ze--; } - } + + /* + * Move explicit bit from bit 62 to bit 26 since the + * ieee754sp_format code expects the mantissa to be + * 27 bits wide (24 + 3 rounding bits). + */ + zm = XSPSRS64(zm64, (62 - 26)); + return ieee754sp_format(zs, ze, zm); } @@ -275,5 +260,5 @@ union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x, union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x, union ieee754sp y) { - return _sp_maddf(z, x, y, maddf_negate_product); + return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT); } diff --git a/arch/mips/math-emu/sp_rint.c b/arch/mips/math-emu/sp_rint.c new file mode 100644 index 000000000000..70765b17e196 --- /dev/null +++ b/arch/mips/math-emu/sp_rint.c @@ -0,0 +1,90 @@ +/* IEEE754 floating point arithmetic + * single precision + */ +/* + * MIPS floating point support + * Copyright (C) 1994-2000 Algorithmics Ltd. + * Copyright (C) 2017 Imagination Technologies, Ltd. + * Author: Aleksandar Markovic + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. + */ + +#include "ieee754sp.h" + +union ieee754sp ieee754sp_rint(union ieee754sp x) +{ + union ieee754sp ret; + u32 residue; + int sticky; + int round; + int odd; + + COMPXDP; /* <-- DP needed for 64-bit mantissa tmp */ + + ieee754_clearcx(); + + EXPLODEXSP; + FLUSHXSP; + + if (xc == IEEE754_CLASS_SNAN) + return ieee754sp_nanxcpt(x); + + if ((xc == IEEE754_CLASS_QNAN) || + (xc == IEEE754_CLASS_INF) || + (xc == IEEE754_CLASS_ZERO)) + return x; + + if (xe >= SP_FBITS) + return x; + + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; + } else { + residue = xm << (xe + 1); + residue <<= 31 - SP_FBITS; + round = (residue >> 31) != 0; + sticky = (residue << 1) != 0; + xm >>= SP_FBITS - xe; + } + + odd = (xm & 0x1) != 0x0; + + switch (ieee754_csr.rm) { + case FPU_CSR_RN: /* toward nearest */ + if (round && (sticky || odd)) + xm++; + break; + case FPU_CSR_RZ: /* toward zero */ + break; + case FPU_CSR_RU: /* toward +infinity */ + if ((round || sticky) && !xs) + xm++; + break; + case FPU_CSR_RD: /* toward -infinity */ + if ((round || sticky) && xs) + xm++; + break; + } + + if (round || sticky) + ieee754_setcx(IEEE754_INEXACT); + + ret = ieee754sp_flong(xm); + SPSIGN(ret) = xs; + + return ret; +} diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index b4cc8811a664..c463bdad45c7 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/MIPS-specific parts of the memory manager. # diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 21e4e662c1fa..3466fcdae0ca 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r2300.c: R2000 and R3000 specific mmu/cache code. * diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 81d6a15c93d0..6f534b209971 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -37,7 +37,7 @@ #include /* for run_uncached() */ #include #include -#include +#include /* * Bits describing what cache ops an SMP callback function may perform. diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 5c282583edf1..5f6c099a9457 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r2300.c: R2000 and R3000 specific mmu/cache code. * diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 899e46279902..44ac64d51827 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Cache operations. */ void (*flush_cache_all)(void); @@ -44,7 +45,6 @@ void (*__flush_cache_vunmap)(void); void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); -void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 8e78251eccc2..c01bd20d0208 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -127,23 +127,6 @@ static gfp_t massage_gfp_flags(const struct device *dev, gfp_t gfp) return gfp | dma_flag; } -static void *mips_dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t gfp) -{ - void *ret; - - gfp = massage_gfp_flags(dev, gfp); - - ret = (void *) __get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = plat_map_dma_mem(dev, ret, size); - } - - return ret; -} - static void *mips_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) { @@ -151,13 +134,6 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, struct page *page = NULL; unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; - /* - * XXX: seems like the coherent and non-coherent implementations could - * be consolidated. - */ - if (attrs & DMA_ATTR_NON_CONSISTENT) - return mips_dma_alloc_noncoherent(dev, size, dma_handle, gfp); - gfp = massage_gfp_flags(dev, gfp); if (IS_ENABLED(CONFIG_DMA_CMA) && gfpflags_allow_blocking(gfp)) @@ -172,7 +148,8 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, ret = page_address(page); memset(ret, 0, size); *dma_handle = plat_map_dma_mem(dev, ret, size); - if (!plat_device_is_coherent(dev)) { + if (!(attrs & DMA_ATTR_NON_CONSISTENT) && + !plat_device_is_coherent(dev)) { dma_cache_wback_inv((unsigned long) ret, size); ret = UNCAC_ADDR(ret); } @@ -180,14 +157,6 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, return ret; } - -static void mips_dma_free_noncoherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); - free_pages((unsigned long) vaddr, get_order(size)); -} - static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, unsigned long attrs) { @@ -195,14 +164,9 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT; struct page *page = NULL; - if (attrs & DMA_ATTR_NON_CONSISTENT) { - mips_dma_free_noncoherent(dev, size, vaddr, dma_handle); - return; - } - plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); - if (!plat_device_is_coherent(dev)) + if (!(attrs & DMA_ATTR_NON_CONSISTENT) && !plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); page = virt_to_page((void *) addr); @@ -409,12 +373,12 @@ static void mips_dma_sync_sg_for_device(struct device *dev, } } -int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } -int mips_dma_supported(struct device *dev, u64 mask) +static int mips_dma_supported(struct device *dev, u64 mask) { return plat_dma_supported(dev, mask); } diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index d8c3c159289a..1e4658eee13f 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Lockless get_user_pages_fast for MIPS * diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index f13f51003bd8..d08e6d7d533b 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 8ce2983a7015..5f6ea7d746de 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 28adeabe851f..33d3251ecd37 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -7,6 +7,7 @@ * written by Ralf Baechle */ #include +#include #include #include #include diff --git a/arch/mips/mm/sc-debugfs.c b/arch/mips/mm/sc-debugfs.c index 7e945e310b44..2e2132d3f5c7 100644 --- a/arch/mips/mm/sc-debugfs.c +++ b/arch/mips/mm/sc-debugfs.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2015 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c index f293a97cb885..ea059cd86496 100644 --- a/arch/mips/mm/sc-ip22.c +++ b/arch/mips/mm/sc-ip22.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sc-ip22.c: Indy cache management functions. * diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index c909c3342729..548acb7f8557 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2006 Chris Dearman (chris@mips.com), */ @@ -14,7 +15,7 @@ #include #include #include -#include +#include /* * MIPS32/MIPS64 L2 cache handling @@ -63,34 +64,25 @@ static void mips_sc_prefetch_enable(void) * prefetching for both code & data, for all ports. */ pftctl = read_gcr_l2_pft_control(); - if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) { - pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; - pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK; - pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; + if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT) { + pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK; + pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK; + pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN; write_gcr_l2_pft_control(pftctl); - pftctl = read_gcr_l2_pft_control_b(); - pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; - pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; - write_gcr_l2_pft_control_b(pftctl); + set_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID | + CM_GCR_L2_PFT_CONTROL_B_CEN); } } static void mips_sc_prefetch_disable(void) { - unsigned long pftctl; - if (mips_cm_revision() < CM_REV_CM2_5) return; - pftctl = read_gcr_l2_pft_control(); - pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK; - write_gcr_l2_pft_control(pftctl); - - pftctl = read_gcr_l2_pft_control_b(); - pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK; - pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK; - write_gcr_l2_pft_control_b(pftctl); + clear_gcr_l2_pft_control(CM_GCR_L2_PFT_CONTROL_PFTEN); + clear_gcr_l2_pft_control_b(CM_GCR_L2_PFT_CONTROL_B_PORTID | + CM_GCR_L2_PFT_CONTROL_B_CEN); } static bool mips_sc_prefetch_is_enabled(void) @@ -101,9 +93,9 @@ static bool mips_sc_prefetch_is_enabled(void) return false; pftctl = read_gcr_l2_pft_control(); - if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK)) + if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT)) return false; - return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK); + return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN); } static struct bcache_ops mips_sc_ops = { @@ -160,21 +152,21 @@ static int __init mips_sc_probe_cm3(void) unsigned long cfg = read_gcr_l2_config(); unsigned long sets, line_sz, assoc; - if (cfg & CM_GCR_L2_CONFIG_BYPASS_MSK) + if (cfg & CM_GCR_L2_CONFIG_BYPASS) return 0; - sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK; - sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF; + sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE; + sets >>= __ffs(CM_GCR_L2_CONFIG_SET_SIZE); if (sets) c->scache.sets = 64 << sets; - line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK; - line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF; + line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE; + line_sz >>= __ffs(CM_GCR_L2_CONFIG_LINE_SIZE); if (line_sz) c->scache.linesz = 2 << line_sz; - assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK; - assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF; + assoc = cfg & CM_GCR_L2_CONFIG_ASSOC; + assoc >>= __ffs(CM_GCR_L2_CONFIG_ASSOC); c->scache.ways = assoc + 1; c->scache.waysize = c->scache.sets * c->scache.linesz; c->scache.waybit = __ffs(c->scache.waysize); diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c index 751b5cd18bf2..c7b94c951d98 100644 --- a/arch/mips/mm/sc-r5k.c +++ b/arch/mips/mm/sc-r5k.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), * derived from r4xx0.c by David S. Miller (davem@davemloft.net). diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 78f900c59276..e9e3777a7848 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sc-rm7k.c: RM7000 cache management functions. * diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index 1290b995695d..6f589e0112ce 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r2300.c: R2000 and R3000 specific mmu/cache code. * diff --git a/arch/mips/mm/tlbex-fault.S b/arch/mips/mm/tlbex-fault.S index 318855eb5f80..77db401fc620 100644 --- a/arch/mips/mm/tlbex-fault.S +++ b/arch/mips/mm/tlbex-fault.S @@ -12,14 +12,15 @@ .macro tlb_do_page_fault, write NESTED(tlb_do_page_fault_\write, PT_SIZE, sp) - SAVE_ALL + .cfi_signal_frame + SAVE_ALL docfi=1 MFC0 a2, CP0_BADVADDR KMODE move a0, sp REG_S a2, PT_BVADDR(sp) li a1, \write - PTR_LA ra, ret_from_exception - j do_page_fault + jal do_page_fault + j ret_from_exception END(tlb_do_page_fault_\write) .endm diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 5aadc69c8ce3..79b9f2ad3ff5 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -2634,11 +2634,6 @@ void build_tlb_refill_handler(void) #endif break; - case CPU_R6000: - case CPU_R6000A: - panic("No R6000 TLB refill handler yet"); - break; - case CPU_R8000: panic("No R8000 TLB refill handler yet"); break; diff --git a/arch/mips/mm/uasm-micromips.c b/arch/mips/mm/uasm-micromips.c index c28ff53c8da0..cdb5a191b9d5 100644 --- a/arch/mips/mm/uasm-micromips.c +++ b/arch/mips/mm/uasm-micromips.c @@ -80,7 +80,7 @@ static const struct insn const insn_table_MM[insn_invalid] = { [insn_jr] = {M(mm_pool32a_op, 0, 0, 0, mm_jalr_op, mm_pool32axf_op), RS}, [insn_lb] = {M(mm_lb32_op, 0, 0, 0, 0, 0), RT | RS | SIMM}, [insn_ld] = {0, 0}, - [insn_lh] = {M(mm_lh32_op, 0, 0, 0, 0, 0), RS | RS | SIMM}, + [insn_lh] = {M(mm_lh32_op, 0, 0, 0, 0, 0), RT | RS | SIMM}, [insn_ll] = {M(mm_pool32c_op, 0, 0, (mm_ll_func << 1), 0, 0), RS | RT | SIMM}, [insn_lld] = {0, 0}, [insn_lui] = {M(mm_pool32i_op, mm_lui_op, 0, 0, 0, 0), RS | SIMM}, diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile index 5827af77c18e..63940bdce698 100644 --- a/arch/mips/mti-malta/Makefile +++ b/arch/mips/mti-malta/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Carsten Langgaard, carstenl@mips.com # Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. diff --git a/arch/mips/mti-malta/malta-dt.c b/arch/mips/mti-malta/malta-dt.c index 4822943100f3..b397117033aa 100644 --- a/arch/mips/mti-malta/malta-dt.c +++ b/arch/mips/mti-malta/malta-dt.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2015 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c index c398582c316f..7859b6e49863 100644 --- a/arch/mips/mti-malta/malta-dtshim.c +++ b/arch/mips/mti-malta/malta-dtshim.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2015 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #define ROCIT_REG_BASE 0x1f403000 @@ -236,7 +236,7 @@ static void __init remove_gic(void *fdt) /* if we have a CM which reports a GIC is present, leave the DT alone */ err = mips_cm_probe(); - if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX_MSK)) + if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_EX)) return; if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 0f3b881a3190..009f2918b320 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -21,8 +21,7 @@ #include #include #include -#include -#include +#include #include #include diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index b0f9b188e833..a840e0c1642c 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -29,9 +28,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -215,7 +214,7 @@ void __init arch_init_irq(void) msc_nr_irqs); } - if (gic_present) { + if (mips_gic_present()) { corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } else if (cpu_has_veic) { set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); diff --git a/arch/mips/mti-malta/malta-pm.c b/arch/mips/mti-malta/malta-pm.c index c1e456c01a44..efbd659fb602 100644 --- a/arch/mips/mti-malta/malta-pm.c +++ b/arch/mips/mti-malta/malta-pm.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index a01d5debfcaf..de34adb76157 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include #include @@ -128,7 +128,7 @@ static int __init plat_enable_iocoherency(void) BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); pr_info("Enabled Bonito IOBC coherency\n"); } - } else if (mips_cm_numiocu() != 0) { + } else if (mips_cps_numiocu(0) != 0) { /* Nothing special needs to be done to enable coherency */ pr_info("CMP IOCU detected\n"); cfg = __raw_readl((u32 *)CKSEG1ADDR(ROCIT_CONFIG_GEN0)); diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index cea4ec909806..66c866740ff2 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #include @@ -85,8 +85,8 @@ static void __init estimate_frequencies(void) local_irq_save(flags); - if (gic_present) - gic_start_count(); + if (mips_gic_present()) + clear_gic_config(GIC_CONFIG_COUNTSTOP); /* * Read counters exactly on rising edge of update flag. @@ -95,8 +95,8 @@ static void __init estimate_frequencies(void) while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); start = read_c0_count(); - if (gic_present) - gicstart = gic_read_count(); + if (mips_gic_present()) + gicstart = read_gic_counter(); /* Wait for falling edge before reading RTC. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); @@ -105,8 +105,8 @@ static void __init estimate_frequencies(void) /* Read counters again exactly on rising edge of update flag. */ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); count = read_c0_count(); - if (gic_present) - giccount = gic_read_count(); + if (mips_gic_present()) + giccount = read_gic_counter(); /* Wait for falling edge before reading RTC again. */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); @@ -128,7 +128,7 @@ static void __init estimate_frequencies(void) count /= secs; mips_hpt_frequency = count; - if (gic_present) { + if (mips_gic_present()) { giccount = div_u64(giccount - gicstart, secs); gic_frequency = giccount; } @@ -154,7 +154,7 @@ int get_c0_fdc_int(void) if (cpu_has_veic) return -1; - else if (gic_present) + else if (mips_gic_present()) return gic_get_c0_fdc_int(); else if (cp0_fdc_irq >= 0) return MIPS_CPU_IRQ_BASE + cp0_fdc_irq; @@ -167,7 +167,7 @@ int get_c0_perfcount_int(void) if (cpu_has_veic) { set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; - } else if (gic_present) { + } else if (mips_gic_present()) { mips_cpu_perf_irq = gic_get_c0_perfcount_int(); } else if (cp0_perfcount_irq >= 0) { mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; @@ -184,7 +184,7 @@ unsigned int get_c0_compare_int(void) if (cpu_has_veic) { set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; - } else if (gic_present) { + } else if (mips_gic_present()) { mips_cpu_timer_irq = gic_get_c0_compare_int(); } else { mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; @@ -258,8 +258,7 @@ void __init plat_time_init(void) setup_pit_timer(); #endif -#ifdef CONFIG_MIPS_GIC - if (gic_present) { + if (mips_gic_present()) { freq = freqround(gic_frequency, 5000); printk("GIC frequency %d.%02d MHz\n", freq/1000000, (freq%1000000)*100/1000000); @@ -268,5 +267,4 @@ void __init plat_time_init(void) timer_probe(); #endif } -#endif } diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c index 3f87b96da5c4..962b0259b4b6 100644 --- a/arch/mips/net/ebpf_jit.c +++ b/arch/mips/net/ebpf_jit.c @@ -113,6 +113,7 @@ struct jit_ctx { u64 *reg_val_types; unsigned int long_b_conversion:1; unsigned int gen_b_offsets:1; + unsigned int use_bbit_insns:1; }; static void set_reg_val_type(u64 *rvt, int reg, enum reg_val_type type) @@ -655,19 +656,6 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int this_idx) return build_int_epilogue(ctx, MIPS_R_T9); } -static bool use_bbit_insns(void) -{ - switch (current_cpu_type()) { - case CPU_CAVIUM_OCTEON: - case CPU_CAVIUM_OCTEON_PLUS: - case CPU_CAVIUM_OCTEON2: - case CPU_CAVIUM_OCTEON3: - return true; - default: - return false; - } -} - static bool is_bad_offset(int b_off) { return b_off > 0x1ffff || b_off < -0x20000; @@ -679,9 +667,10 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, { int src, dst, r, td, ts, mem_off, b_off; bool need_swap, did_move, cmp_eq; - unsigned int target; + unsigned int target = 0; u64 t64; s64 t64s; + int bpf_op = BPF_OP(insn->code); switch (insn->code) { case BPF_ALU64 | BPF_ADD | BPF_K: /* ALU64_IMM */ @@ -770,13 +759,13 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, sll, dst, dst, 0); if (insn->imm == 1) { /* div by 1 is a nop, mod by 1 is zero */ - if (BPF_OP(insn->code) == BPF_MOD) + if (bpf_op == BPF_MOD) emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO); break; } gen_imm_to_reg(insn, MIPS_R_AT, ctx); emit_instr(ctx, divu, dst, MIPS_R_AT); - if (BPF_OP(insn->code) == BPF_DIV) + if (bpf_op == BPF_DIV) emit_instr(ctx, mflo, dst); else emit_instr(ctx, mfhi, dst); @@ -798,13 +787,13 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, if (insn->imm == 1) { /* div by 1 is a nop, mod by 1 is zero */ - if (BPF_OP(insn->code) == BPF_MOD) + if (bpf_op == BPF_MOD) emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO); break; } gen_imm_to_reg(insn, MIPS_R_AT, ctx); emit_instr(ctx, ddivu, dst, MIPS_R_AT); - if (BPF_OP(insn->code) == BPF_DIV) + if (bpf_op == BPF_DIV) emit_instr(ctx, mflo, dst); else emit_instr(ctx, mfhi, dst); @@ -829,7 +818,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32); did_move = false; if (insn->src_reg == BPF_REG_10) { - if (BPF_OP(insn->code) == BPF_MOV) { + if (bpf_op == BPF_MOV) { emit_instr(ctx, daddiu, dst, MIPS_R_SP, MAX_BPF_STACK); did_move = true; } else { @@ -839,7 +828,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, } else if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) { int tmp_reg = MIPS_R_AT; - if (BPF_OP(insn->code) == BPF_MOV) { + if (bpf_op == BPF_MOV) { tmp_reg = dst; did_move = true; } @@ -847,7 +836,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, dinsu, tmp_reg, MIPS_R_ZERO, 32, 32); src = MIPS_R_AT; } - switch (BPF_OP(insn->code)) { + switch (bpf_op) { case BPF_MOV: if (!did_move) emit_instr(ctx, daddu, dst, src, MIPS_R_ZERO); @@ -879,7 +868,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off); emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src); emit_instr(ctx, ddivu, dst, src); - if (BPF_OP(insn->code) == BPF_DIV) + if (bpf_op == BPF_DIV) emit_instr(ctx, mflo, dst); else emit_instr(ctx, mfhi, dst); @@ -923,7 +912,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, if (ts == REG_64BIT || ts == REG_32BIT_ZERO_EX) { int tmp_reg = MIPS_R_AT; - if (BPF_OP(insn->code) == BPF_MOV) { + if (bpf_op == BPF_MOV) { tmp_reg = dst; did_move = true; } @@ -931,7 +920,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, sll, tmp_reg, src, 0); src = MIPS_R_AT; } - switch (BPF_OP(insn->code)) { + switch (bpf_op) { case BPF_MOV: if (!did_move) emit_instr(ctx, addu, dst, src, MIPS_R_ZERO); @@ -962,7 +951,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off); emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src); emit_instr(ctx, divu, dst, src); - if (BPF_OP(insn->code) == BPF_DIV) + if (bpf_op == BPF_DIV) emit_instr(ctx, mflo, dst); else emit_instr(ctx, mfhi, dst); @@ -989,7 +978,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, break; case BPF_JMP | BPF_JEQ | BPF_K: /* JMP_IMM */ case BPF_JMP | BPF_JNE | BPF_K: /* JMP_IMM */ - cmp_eq = (BPF_OP(insn->code) == BPF_JEQ); + cmp_eq = (bpf_op == BPF_JEQ); dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok); if (dst < 0) return dst; @@ -1002,8 +991,12 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, goto jeq_common; case BPF_JMP | BPF_JEQ | BPF_X: /* JMP_REG */ case BPF_JMP | BPF_JNE | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: case BPF_JMP | BPF_JSGT | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: case BPF_JMP | BPF_JGT | BPF_X: case BPF_JMP | BPF_JGE | BPF_X: case BPF_JMP | BPF_JSET | BPF_X: @@ -1020,33 +1013,39 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, sll, MIPS_R_AT, dst, 0); dst = MIPS_R_AT; } - if (BPF_OP(insn->code) == BPF_JSET) { + if (bpf_op == BPF_JSET) { emit_instr(ctx, and, MIPS_R_AT, dst, src); cmp_eq = false; dst = MIPS_R_AT; src = MIPS_R_ZERO; - } else if (BPF_OP(insn->code) == BPF_JSGT) { + } else if (bpf_op == BPF_JSGT || bpf_op == BPF_JSLE) { emit_instr(ctx, dsubu, MIPS_R_AT, dst, src); if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) { b_off = b_imm(exit_idx, ctx); if (is_bad_offset(b_off)) return -E2BIG; - emit_instr(ctx, blez, MIPS_R_AT, b_off); + if (bpf_op == BPF_JSGT) + emit_instr(ctx, blez, MIPS_R_AT, b_off); + else + emit_instr(ctx, bgtz, MIPS_R_AT, b_off); emit_instr(ctx, nop); return 2; /* We consumed the exit. */ } b_off = b_imm(this_idx + insn->off + 1, ctx); if (is_bad_offset(b_off)) return -E2BIG; - emit_instr(ctx, bgtz, MIPS_R_AT, b_off); + if (bpf_op == BPF_JSGT) + emit_instr(ctx, bgtz, MIPS_R_AT, b_off); + else + emit_instr(ctx, blez, MIPS_R_AT, b_off); emit_instr(ctx, nop); break; - } else if (BPF_OP(insn->code) == BPF_JSGE) { + } else if (bpf_op == BPF_JSGE || bpf_op == BPF_JSLT) { emit_instr(ctx, slt, MIPS_R_AT, dst, src); - cmp_eq = true; + cmp_eq = bpf_op == BPF_JSGE; dst = MIPS_R_AT; src = MIPS_R_ZERO; - } else if (BPF_OP(insn->code) == BPF_JGT) { + } else if (bpf_op == BPF_JGT || bpf_op == BPF_JLE) { /* dst or src could be AT */ emit_instr(ctx, dsubu, MIPS_R_T8, dst, src); emit_instr(ctx, sltu, MIPS_R_AT, dst, src); @@ -1054,16 +1053,16 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit_instr(ctx, movz, MIPS_R_T9, MIPS_R_SP, MIPS_R_T8); emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_ZERO, MIPS_R_T8); emit_instr(ctx, or, MIPS_R_AT, MIPS_R_T9, MIPS_R_AT); - cmp_eq = true; + cmp_eq = bpf_op == BPF_JGT; dst = MIPS_R_AT; src = MIPS_R_ZERO; - } else if (BPF_OP(insn->code) == BPF_JGE) { + } else if (bpf_op == BPF_JGE || bpf_op == BPF_JLT) { emit_instr(ctx, sltu, MIPS_R_AT, dst, src); - cmp_eq = true; + cmp_eq = bpf_op == BPF_JGE; dst = MIPS_R_AT; src = MIPS_R_ZERO; } else { /* JNE/JEQ case */ - cmp_eq = (BPF_OP(insn->code) == BPF_JEQ); + cmp_eq = (bpf_op == BPF_JEQ); } jeq_common: /* @@ -1122,7 +1121,9 @@ jeq_common: break; case BPF_JMP | BPF_JSGT | BPF_K: /* JMP_IMM */ case BPF_JMP | BPF_JSGE | BPF_K: /* JMP_IMM */ - cmp_eq = (BPF_OP(insn->code) == BPF_JSGE); + case BPF_JMP | BPF_JSLT | BPF_K: /* JMP_IMM */ + case BPF_JMP | BPF_JSLE | BPF_K: /* JMP_IMM */ + cmp_eq = (bpf_op == BPF_JSGE); dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok); if (dst < 0) return dst; @@ -1132,65 +1133,92 @@ jeq_common: b_off = b_imm(exit_idx, ctx); if (is_bad_offset(b_off)) return -E2BIG; - if (cmp_eq) - emit_instr(ctx, bltz, dst, b_off); - else + switch (bpf_op) { + case BPF_JSGT: emit_instr(ctx, blez, dst, b_off); + break; + case BPF_JSGE: + emit_instr(ctx, bltz, dst, b_off); + break; + case BPF_JSLT: + emit_instr(ctx, bgez, dst, b_off); + break; + case BPF_JSLE: + emit_instr(ctx, bgtz, dst, b_off); + break; + } emit_instr(ctx, nop); return 2; /* We consumed the exit. */ } b_off = b_imm(this_idx + insn->off + 1, ctx); if (is_bad_offset(b_off)) return -E2BIG; - if (cmp_eq) - emit_instr(ctx, bgez, dst, b_off); - else + switch (bpf_op) { + case BPF_JSGT: emit_instr(ctx, bgtz, dst, b_off); + break; + case BPF_JSGE: + emit_instr(ctx, bgez, dst, b_off); + break; + case BPF_JSLT: + emit_instr(ctx, bltz, dst, b_off); + break; + case BPF_JSLE: + emit_instr(ctx, blez, dst, b_off); + break; + } emit_instr(ctx, nop); break; } /* * only "LT" compare available, so we must use imm + 1 - * to generate "GT" + * to generate "GT" and imm -1 to generate LE */ - t64s = insn->imm + (cmp_eq ? 0 : 1); + if (bpf_op == BPF_JSGT) + t64s = insn->imm + 1; + else if (bpf_op == BPF_JSLE) + t64s = insn->imm + 1; + else + t64s = insn->imm; + + cmp_eq = bpf_op == BPF_JSGT || bpf_op == BPF_JSGE; if (t64s >= S16_MIN && t64s <= S16_MAX) { emit_instr(ctx, slti, MIPS_R_AT, dst, (int)t64s); src = MIPS_R_AT; dst = MIPS_R_ZERO; - cmp_eq = true; goto jeq_common; } emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s); emit_instr(ctx, slt, MIPS_R_AT, dst, MIPS_R_AT); src = MIPS_R_AT; dst = MIPS_R_ZERO; - cmp_eq = true; goto jeq_common; case BPF_JMP | BPF_JGT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: - cmp_eq = (BPF_OP(insn->code) == BPF_JGE); + case BPF_JMP | BPF_JLT | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: + cmp_eq = (bpf_op == BPF_JGE); dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok); if (dst < 0) return dst; /* * only "LT" compare available, so we must use imm + 1 - * to generate "GT" + * to generate "GT" and imm -1 to generate LE */ - t64s = (u64)(u32)(insn->imm) + (cmp_eq ? 0 : 1); - if (t64s >= 0 && t64s <= S16_MAX) { - emit_instr(ctx, sltiu, MIPS_R_AT, dst, (int)t64s); - src = MIPS_R_AT; - dst = MIPS_R_ZERO; - cmp_eq = true; - goto jeq_common; - } + if (bpf_op == BPF_JGT) + t64s = (u64)(u32)(insn->imm) + 1; + else if (bpf_op == BPF_JLE) + t64s = (u64)(u32)(insn->imm) + 1; + else + t64s = (u64)(u32)(insn->imm); + + cmp_eq = bpf_op == BPF_JGT || bpf_op == BPF_JGE; + emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s); emit_instr(ctx, sltu, MIPS_R_AT, dst, MIPS_R_AT); src = MIPS_R_AT; dst = MIPS_R_ZERO; - cmp_eq = true; goto jeq_common; case BPF_JMP | BPF_JSET | BPF_K: /* JMP_IMM */ @@ -1198,7 +1226,7 @@ jeq_common: if (dst < 0) return dst; - if (use_bbit_insns() && hweight32((u32)insn->imm) == 1) { + if (ctx->use_bbit_insns && hweight32((u32)insn->imm) == 1) { if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) { b_off = b_imm(exit_idx, ctx); if (is_bad_offset(b_off)) @@ -1485,7 +1513,7 @@ ld_skb_common: } src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp); if (src < 0) - return dst; + return src; if (BPF_MODE(insn->code) == BPF_XADD) { switch (BPF_SIZE(insn->code)) { case BPF_W: @@ -1724,10 +1752,14 @@ static int reg_val_propagate_range(struct jit_ctx *ctx, u64 initial_rvt, case BPF_JEQ: case BPF_JGT: case BPF_JGE: + case BPF_JLT: + case BPF_JLE: case BPF_JSET: case BPF_JNE: case BPF_JSGT: case BPF_JSGE: + case BPF_JSLT: + case BPF_JSLE: if (follow_taken) { rvt[idx] |= RVT_BRANCH_TAKEN; idx += insn->off; @@ -1853,6 +1885,19 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) memset(&ctx, 0, sizeof(ctx)); + preempt_disable(); + switch (current_cpu_type()) { + case CPU_CAVIUM_OCTEON: + case CPU_CAVIUM_OCTEON_PLUS: + case CPU_CAVIUM_OCTEON2: + case CPU_CAVIUM_OCTEON3: + ctx.use_bbit_insns = 1; + break; + default: + ctx.use_bbit_insns = 0; + } + preempt_enable(); + ctx.offsets = kcalloc(prog->len + 1, sizeof(*ctx.offsets), GFP_KERNEL); if (ctx.offsets == NULL) goto out_err; diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig index fb00606e352d..8296b13affd2 100644 --- a/arch/mips/netlogic/Kconfig +++ b/arch/mips/netlogic/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if NLM_XLP_BOARD || NLM_XLR_BOARD if NLM_XLP_BOARD diff --git a/arch/mips/netlogic/common/Makefile b/arch/mips/netlogic/common/Makefile index 362739d62b1d..60d00b5d748e 100644 --- a/arch/mips/netlogic/common/Makefile +++ b/arch/mips/netlogic/common/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += irq.o time.o obj-y += nlm-dma.o obj-y += reset.o diff --git a/arch/mips/netlogic/common/smp.c b/arch/mips/netlogic/common/smp.c index bddf1ef553a4..39a300bd6cc2 100644 --- a/arch/mips/netlogic/common/smp.c +++ b/arch/mips/netlogic/common/smp.c @@ -122,7 +122,7 @@ static void nlm_init_secondary(void) int hwtid; hwtid = hard_smp_processor_id(); - current_cpu_data.core = hwtid / NLM_THREADS_PER_CORE; + cpu_set_core(¤t_cpu_data, hwtid / NLM_THREADS_PER_CORE); current_cpu_data.package = nlm_nodeid(); nlm_percpu_init(hwtid); nlm_smp_irq_init(hwtid); @@ -147,7 +147,7 @@ unsigned long nlm_next_gp; unsigned long nlm_next_sp; static cpumask_t phys_cpu_present_mask; -void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) +int nlm_boot_secondary(int logical_cpu, struct task_struct *idle) { uint64_t picbase; int hwtid; @@ -161,6 +161,8 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle) /* barrier for sp/gp store above */ __sync(); nlm_pic_send_ipi(picbase, hwtid, 1, 1); /* NMI */ + + return 0; } void __init nlm_smp_setup(void) @@ -272,7 +274,7 @@ int nlm_wakeup_secondary_cpus(void) return 0; } -struct plat_smp_ops nlm_smp_ops = { +const struct plat_smp_ops nlm_smp_ops = { .send_ipi_single = nlm_send_ipi_single, .send_ipi_mask = nlm_send_ipi_mask, .init_secondary = nlm_init_secondary, diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile index 6b43af0a34d9..d62465717393 100644 --- a/arch/mips/netlogic/xlp/Makefile +++ b/arch/mips/netlogic/xlp/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += setup.o nlm_hal.o cop2-ex.o dt.o obj-$(CONFIG_SMP) += wakeup.o ifdef CONFIG_USB diff --git a/arch/mips/netlogic/xlr/platform-flash.c b/arch/mips/netlogic/xlr/platform-flash.c index f03131fec41d..4d1b4c003376 100644 --- a/arch/mips/netlogic/xlr/platform-flash.c +++ b/arch/mips/netlogic/xlr/platform-flash.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 070afdb297df..011cf9f891e7 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c index 16ace558cd9d..806fb798091f 100644 --- a/arch/mips/oprofile/backtrace.c +++ b/arch/mips/oprofile/backtrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index c57da6f13929..c3e4c18ef8d4 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -38,9 +38,9 @@ static int perfcount_irq; #ifdef CONFIG_MIPS_MT_SMP static int cpu_has_mipsmt_pertccounters; #define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \ - M_PERFCTL_VPEID(cpu_data[smp_processor_id()].vpe_id)) + M_PERFCTL_VPEID(cpu_vpe_id(¤t_cpu_data))) #define vpe_id() (cpu_has_mipsmt_pertccounters ? \ - 0 : cpu_data[smp_processor_id()].vpe_id) + 0 : cpu_vpe_id(¤t_cpu_data)) /* * The number of bits to shift to convert between counters per core and diff --git a/arch/mips/paravirt/Kconfig b/arch/mips/paravirt/Kconfig index ecae5861b601..46b110fec967 100644 --- a/arch/mips/paravirt/Kconfig +++ b/arch/mips/paravirt/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if MIPS_PARAVIRT config MIPS_PCI_VIRTIO diff --git a/arch/mips/paravirt/paravirt-smp.c b/arch/mips/paravirt/paravirt-smp.c index 72eb1a56c645..107d9f90d668 100644 --- a/arch/mips/paravirt/paravirt-smp.c +++ b/arch/mips/paravirt/paravirt-smp.c @@ -100,11 +100,12 @@ static void paravirt_smp_finish(void) local_irq_enable(); } -static void paravirt_boot_secondary(int cpu, struct task_struct *idle) +static int paravirt_boot_secondary(int cpu, struct task_struct *idle) { paravirt_smp_gp[cpu] = (unsigned long)task_thread_info(idle); smp_wmb(); paravirt_smp_sp[cpu] = __KSTK_TOS(idle); + return 0; } static irqreturn_t paravirt_reched_interrupt(int irq, void *dev_id) @@ -133,7 +134,7 @@ static void paravirt_prepare_cpus(unsigned int max_cpus) } } -struct plat_smp_ops paravirt_smp_ops = { +const struct plat_smp_ops paravirt_smp_ops = { .send_ipi_single = paravirt_send_ipi_single, .send_ipi_mask = paravirt_send_ipi_mask, .init_secondary = paravirt_init_secondary, diff --git a/arch/mips/paravirt/setup.c b/arch/mips/paravirt/setup.c index cb8448b373a7..d2ffec1409a7 100644 --- a/arch/mips/paravirt/setup.c +++ b/arch/mips/paravirt/setup.c @@ -14,7 +14,7 @@ #include #include -extern struct plat_smp_ops paravirt_smp_ops; +extern const struct plat_smp_ops paravirt_smp_ops; const char *get_system_type(void) { diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 4b821481dd44..8185a2bfaf09 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PCI specific kernel interface routines under Linux. # diff --git a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c index 1c02f5737367..b4c263f16b15 100644 --- a/arch/mips/pci/fixup-capcella.c +++ b/arch/mips/pci/fixup-capcella.c @@ -32,13 +32,13 @@ #define INTC PC104PLUS_INTC_IRQ #define INTD PC104PLUS_INTD_IRQ -static char irq_tab_capcella[][5] __initdata = { +static char irq_tab_capcella[][5] = { [11] = { -1, INT1, INT1, INT1, INT1 }, [12] = { -1, INT2, INT2, INT2, INT2 }, [14] = { -1, INTA, INTB, INTC, INTD } }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_capcella[slot][pin]; } diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index b3ab59318d91..44be65c3e6bb 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c @@ -147,7 +147,7 @@ static void qube_raq_via_board_id_fixup(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, qube_raq_via_board_id_fixup); -static char irq_tab_qube1[] __initdata = { +static char irq_tab_qube1[] = { [COBALT_PCICONF_CPU] = 0, [COBALT_PCICONF_ETH0] = QUBE1_ETH0_IRQ, [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, @@ -156,7 +156,7 @@ static char irq_tab_qube1[] __initdata = { [COBALT_PCICONF_ETH1] = 0 }; -static char irq_tab_cobalt[] __initdata = { +static char irq_tab_cobalt[] = { [COBALT_PCICONF_CPU] = 0, [COBALT_PCICONF_ETH0] = ETH0_IRQ, [COBALT_PCICONF_RAQSCSI] = SCSI_IRQ, @@ -165,7 +165,7 @@ static char irq_tab_cobalt[] __initdata = { [COBALT_PCICONF_ETH1] = ETH1_IRQ }; -static char irq_tab_raq2[] __initdata = { +static char irq_tab_raq2[] = { [COBALT_PCICONF_CPU] = 0, [COBALT_PCICONF_ETH0] = ETH0_IRQ, [COBALT_PCICONF_RAQSCSI] = RAQ2_SCSI_IRQ, @@ -174,7 +174,7 @@ static char irq_tab_raq2[] __initdata = { [COBALT_PCICONF_ETH1] = ETH1_IRQ }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (cobalt_board_id <= COBALT_BRD_ID_QUBE1) return irq_tab_qube1[slot]; diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c index 19caf775c206..c31cb6af1cd0 100644 --- a/arch/mips/pci/fixup-emma2rh.c +++ b/arch/mips/pci/fixup-emma2rh.c @@ -43,7 +43,7 @@ */ #define MAX_SLOT_NUM 10 -static unsigned char irq_map[][5] __initdata = { +static unsigned char irq_map[][5] = { [3] = {0, MARKEINS_PCI_IRQ_INTB, MARKEINS_PCI_IRQ_INTC, MARKEINS_PCI_IRQ_INTD, 0,}, [4] = {0, MARKEINS_PCI_IRQ_INTA, 0, 0, 0,}, @@ -85,7 +85,7 @@ static void emma2rh_pci_host_fixup(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_EMMA2RH, emma2rh_pci_host_fixup); -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_map[slot][pin]; } diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c index 50da773faede..b47c2771dc99 100644 --- a/arch/mips/pci/fixup-fuloong2e.c +++ b/arch/mips/pci/fixup-fuloong2e.c @@ -19,7 +19,7 @@ /* South bridge slot number is set by the pci probe process */ static u8 sb_slot = 5; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = 0; diff --git a/arch/mips/pci/fixup-ip32.c b/arch/mips/pci/fixup-ip32.c index 133685e215ee..d091ffc53569 100644 --- a/arch/mips/pci/fixup-ip32.c +++ b/arch/mips/pci/fixup-ip32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -21,7 +22,7 @@ #define INTB MACEPCI_SHARED0_IRQ #define INTC MACEPCI_SHARED1_IRQ #define INTD MACEPCI_SHARED2_IRQ -static char irq_tab_mace[][5] __initdata = { +static char irq_tab_mace[][5] = { /* Dummy INT#A INT#B INT#C INT#D */ {0, 0, 0, 0, 0}, /* This is placeholder row - never used */ {0, SCSI0, SCSI0, SCSI0, SCSI0}, @@ -39,7 +40,7 @@ static char irq_tab_mace[][5] __initdata = { * irqs. I suppose a device without a pin A will thank us for doing it * right if there exists such a broken piece of crap. */ -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return irq_tab_mace[slot][pin]; } diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index 0f1069527cba..d3102eeea898 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -31,7 +31,7 @@ #include #include -int __init jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int jmr3927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c index 2b5427d3f35c..81530a13b349 100644 --- a/arch/mips/pci/fixup-lantiq.c +++ b/arch/mips/pci/fixup-lantiq.c @@ -23,7 +23,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return of_irq_parse_and_map_pci(dev, slot, pin); } diff --git a/arch/mips/pci/fixup-lemote2f.c b/arch/mips/pci/fixup-lemote2f.c index 95ab9a1bd010..20cdfdc08938 100644 --- a/arch/mips/pci/fixup-lemote2f.c +++ b/arch/mips/pci/fixup-lemote2f.c @@ -30,7 +30,7 @@ #define PCID 7 /* all the pci device has the PCIA pin, check the datasheet. */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0}, /* 11: Unused */ {0, 0, 0, 0, 0}, /* 12: Unused */ @@ -51,7 +51,7 @@ static char irq_tab[][5] __initdata = { {0, 0, 0, 0, 0}, /* 27: Unused */ }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int virq; diff --git a/arch/mips/pci/fixup-loongson3.c b/arch/mips/pci/fixup-loongson3.c index 2b6d5e196f99..8a741c2c6685 100644 --- a/arch/mips/pci/fixup-loongson3.c +++ b/arch/mips/pci/fixup-loongson3.c @@ -32,7 +32,7 @@ static void print_fixup_info(const struct pci_dev *pdev) pdev->vendor, pdev->device, pdev->irq); } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { print_fixup_info(dev); return dev->irq; diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c index 40e920c653cc..8131e0ffe735 100644 --- a/arch/mips/pci/fixup-malta.c +++ b/arch/mips/pci/fixup-malta.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -12,7 +13,7 @@ static char pci_irq[5] = { }; -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* 0: GT64120 PCI bridge */ {0, 0, 0, 0, 0 }, /* 1: Unused */ @@ -38,7 +39,7 @@ static char irq_tab[][5] __initdata = { {0, PCID, PCIA, PCIB, PCIC } /* 21: PCI Slot 4 */ }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int virq; virq = irq_tab[slot][pin]; diff --git a/arch/mips/pci/fixup-mpc30x.c b/arch/mips/pci/fixup-mpc30x.c index 8e4f8288eca2..66eaf456bc89 100644 --- a/arch/mips/pci/fixup-mpc30x.c +++ b/arch/mips/pci/fixup-mpc30x.c @@ -22,19 +22,19 @@ #include -static const int internal_func_irqs[] __initconst = { +static const int internal_func_irqs[] = { VRC4173_CASCADE_IRQ, VRC4173_AC97_IRQ, VRC4173_USB_IRQ, }; -static const int irq_tab_mpc30x[] __initconst = { +static const int irq_tab_mpc30x[] = { [12] = VRC4173_PCMCIA1_IRQ, [13] = VRC4173_PCMCIA2_IRQ, [29] = MQ200_IRQ, }; -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (slot == 30) return internal_func_irqs[PCI_FUNC(dev->devfn)]; diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c index fab405c21c2f..4ad2ef02087b 100644 --- a/arch/mips/pci/fixup-pmcmsp.c +++ b/arch/mips/pci/fixup-pmcmsp.c @@ -47,7 +47,7 @@ #if defined(CONFIG_PMC_MSP7120_GW) /* Garibaldi Board IRQ wiring to PCI slots */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ @@ -86,7 +86,7 @@ static char irq_tab[][5] __initdata = { #elif defined(CONFIG_PMC_MSP7120_EVAL) /* MSP7120 Eval Board IRQ wiring to PCI slots */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ @@ -125,7 +125,7 @@ static char irq_tab[][5] __initdata = { #else /* Unknown board -- don't assign any IRQs */ -static char irq_tab[][5] __initdata = { +static char irq_tab[][5] = { /* INTA INTB INTC INTD */ {0, 0, 0, 0, 0 }, /* (AD[0]): Unused */ {0, 0, 0, 0, 0 }, /* (AD[1]): Unused */ @@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) * RETURNS: IRQ number * ****************************************************************************/ -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { #if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL) printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n"); diff --git a/arch/mips/pci/fixup-rbtx4927.c b/arch/mips/pci/fixup-rbtx4927.c index 321db265829c..d6aaed1d6be9 100644 --- a/arch/mips/pci/fixup-rbtx4927.c +++ b/arch/mips/pci/fixup-rbtx4927.c @@ -36,7 +36,7 @@ #include #include -int __init rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int rbtx4927_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; diff --git a/arch/mips/pci/fixup-rbtx4938.c b/arch/mips/pci/fixup-rbtx4938.c index a80579af609b..ff22a22db73e 100644 --- a/arch/mips/pci/fixup-rbtx4938.c +++ b/arch/mips/pci/fixup-rbtx4938.c @@ -13,7 +13,7 @@ #include #include -int __init rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int rbtx4938_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = tx4938_pcic1_map_irq(dev, slot); diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c index f67ebeeb4200..adb9a58641e8 100644 --- a/arch/mips/pci/fixup-sni.c +++ b/arch/mips/pci/fixup-sni.c @@ -40,7 +40,7 @@ * seem to be a documentation error. At least on my RM200C the Cirrus * Logic CL-GD5434 VGA is device 3. */ -static char irq_tab_rm200[8][5] __initdata = { +static char irq_tab_rm200[8][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* EISA bridge */ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ @@ -57,7 +57,7 @@ static char irq_tab_rm200[8][5] __initdata = { * * The VGA card is optional for RM300 systems. */ -static char irq_tab_rm300d[8][5] __initdata = { +static char irq_tab_rm300d[8][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* EISA bridge */ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ @@ -69,7 +69,7 @@ static char irq_tab_rm300d[8][5] __initdata = { { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */ }; -static char irq_tab_rm300e[5][5] __initdata = { +static char irq_tab_rm300e[5][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* HOST bridge */ { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ @@ -96,7 +96,7 @@ static char irq_tab_rm300e[5][5] __initdata = { #define INTC PCIT_IRQ_INTC #define INTD PCIT_IRQ_INTD -static char irq_tab_pcit[13][5] __initdata = { +static char irq_tab_pcit[13][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* HOST bridge */ { SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 }, /* SCSI */ @@ -113,7 +113,7 @@ static char irq_tab_pcit[13][5] __initdata = { { 0, INTA, INTB, INTC, INTD }, /* Slot 5 */ }; -static char irq_tab_pcit_cplus[13][5] __initdata = { +static char irq_tab_pcit_cplus[13][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* HOST bridge */ { 0, INTB, INTC, INTD, INTA }, /* PCI Slot 9 */ @@ -130,7 +130,7 @@ static inline int is_rm300_revd(void) return (csmsr & 0xa0) == 0x20; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (sni_brd_type) { case SNI_BRD_PCI_TOWER_CPLUS: diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c index d0b0083fbd27..cc581535f257 100644 --- a/arch/mips/pci/fixup-tb0219.c +++ b/arch/mips/pci/fixup-tb0219.c @@ -23,7 +23,7 @@ #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c index 4196ccf3ea3d..b827b5cad5fd 100644 --- a/arch/mips/pci/fixup-tb0226.c +++ b/arch/mips/pci/fixup-tb0226.c @@ -23,7 +23,7 @@ #include #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/mips/pci/fixup-tb0287.c b/arch/mips/pci/fixup-tb0287.c index 8c5039ed75d7..98f26285f2e3 100644 --- a/arch/mips/pci/fixup-tb0287.c +++ b/arch/mips/pci/fixup-tb0287.c @@ -22,7 +22,7 @@ #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char bus; int irq = -1; diff --git a/arch/mips/pci/ops-loongson3.c b/arch/mips/pci/ops-loongson3.c index 46ed541a3ec7..9e118431e226 100644 --- a/arch/mips/pci/ops-loongson3.c +++ b/arch/mips/pci/ops-loongson3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c index b9d1fd0ff7e2..b00658d19116 100644 --- a/arch/mips/pci/ops-nile4.c +++ b/arch/mips/pci/ops-nile4.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index e99ca7702d8a..4f2411f489af 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Alchemy PCI host mode support. * @@ -522,7 +523,7 @@ static int __init alchemy_pci_init(void) arch_initcall(alchemy_pci_init); -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct alchemy_pci_context *ctx = dev->sysdata; if (ctx && ctx->board_map_irq) diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c index 76f16eaed0ad..230d7dd273e2 100644 --- a/arch/mips/pci/pci-bcm47xx.c +++ b/arch/mips/pci/pci-bcm47xx.c @@ -28,7 +28,7 @@ #include #include -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return 0; } diff --git a/arch/mips/pci/pci-bcm63xx.h b/arch/mips/pci/pci-bcm63xx.h index ffab4da7bd00..214def1e45a5 100644 --- a/arch/mips/pci/pci-bcm63xx.h +++ b/arch/mips/pci/pci-bcm63xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PCI_BCM63XX_H_ #define PCI_BCM63XX_H_ diff --git a/arch/mips/pci/pci-generic.c b/arch/mips/pci/pci-generic.c index dce304dc3d62..676348164027 100644 --- a/arch/mips/pci/pci-generic.c +++ b/arch/mips/pci/pci-generic.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2016 Imagination Technologies - * Author: Paul Burton + * Author: Paul Burton * * pcibios_align_resource taken from arch/arm/kernel/bios32.c. * diff --git a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c index 40d2797d2bc4..47f4ee6bbb3b 100644 --- a/arch/mips/pci/pci-lasat.c +++ b/arch/mips/pci/pci-lasat.c @@ -61,7 +61,7 @@ arch_initcall(lasat_pci_setup); #define LASAT_IRQ_PCIC (LASAT_IRQ_BASE + 7) #define LASAT_IRQ_PCID (LASAT_IRQ_BASE + 8) -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (slot) { case 1: diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 174575a9a112..0c65c38e05d6 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -78,6 +78,12 @@ static void pcibios_scanbus(struct pci_controller *hose) static int need_domain_info; LIST_HEAD(resources); struct pci_bus *bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) next_busno = (*hose->get_busno)(); @@ -87,18 +93,24 @@ static void pcibios_scanbus(struct pci_controller *hose) pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset); pci_add_resource(&resources, hose->busn_resource); - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - hose->bus = bus; + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = hose->pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pcibios_map_irq; + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + hose->bus = bus = bridge->bus; need_domain_info = need_domain_info || pci_domain_nr(bus); set_pci_need_domain_info(hose, need_domain_info); - if (!bus) { - pci_free_resource_list(&resources); - return; - } - next_busno = bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ @@ -127,7 +139,7 @@ void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) struct of_pci_range range; struct of_pci_range_parser parser; - pr_info("PCI host bridge %s ranges:\n", node->full_name); + pr_info("PCI host bridge %pOF ranges:\n", node); hose->of_node = node; if (of_pci_range_parser_init(&parser, node)) @@ -224,8 +236,6 @@ static int __init pcibios_init(void) list_for_each_entry(hose, &controllers, list) pcibios_scanbus(hose); - pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); - pci_initialized = 1; return 0; diff --git a/arch/mips/pci/pci-malta.c b/arch/mips/pci/pci-malta.c index cfbbc3e3e914..88e625fb3a47 100644 --- a/arch/mips/pci/pci-malta.c +++ b/arch/mips/pci/pci-malta.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include @@ -201,7 +201,7 @@ void __init mips_pcibios_init(void) msc_mem_resource.start = start & mask; msc_mem_resource.end = (start & mask) | ~mask; msc_controller.mem_offset = (start & mask) - (map & mask); - if (mips_cm_numiocu()) { + if (mips_cps_numiocu(0)) { write_gcr_reg0_base(start); write_gcr_reg0_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); @@ -213,7 +213,7 @@ void __init mips_pcibios_init(void) msc_io_resource.end = (map & mask) | ~mask; msc_controller.io_offset = 0; ioport_resource.end = ~mask; - if (mips_cm_numiocu()) { + if (mips_cps_numiocu(0)) { write_gcr_reg1_base(start); write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c index 628c5132b3d8..90fba9bf98da 100644 --- a/arch/mips/pci/pci-mt7620.c +++ b/arch/mips/pci/pci-mt7620.c @@ -291,7 +291,7 @@ static int mt7620_pci_probe(struct platform_device *pdev) IORESOURCE_MEM, 1); u32 val = 0; - rstpcie0 = devm_reset_control_get(&pdev->dev, "pcie0"); + rstpcie0 = devm_reset_control_get_exclusive(&pdev->dev, "pcie0"); if (IS_ERR(rstpcie0)) return PTR_ERR(rstpcie0); @@ -361,7 +361,7 @@ static int mt7620_pci_probe(struct platform_device *pdev) return 0; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u16 cmd; u32 val; diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index 9ee01936862e..3e92a06fa772 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -59,8 +59,7 @@ union octeon_pci_address { } s; }; -int __initconst (*octeon_pcibios_map_irq)(const struct pci_dev *dev, - u8 slot, u8 pin); +int (*octeon_pcibios_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; /** @@ -74,7 +73,7 @@ enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID; * as it goes through each bridge. * Returns Interrupt number for the device */ -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (octeon_pcibios_map_irq) return octeon_pcibios_map_irq(dev, slot, pin); diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c index d6360fe73d05..711cdccdf65b 100644 --- a/arch/mips/pci/pci-rt2880.c +++ b/arch/mips/pci/pci-rt2880.c @@ -181,7 +181,7 @@ static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) spin_unlock_irqrestore(&rt2880_pci_lock, flags); } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { u16 cmd; int irq = -1; diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 3520e9b414e7..958899ffe99c 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -207,8 +207,7 @@ static int rt3883_pci_irq_init(struct device *dev, irq = irq_of_parse_and_map(rpc->intc_of_node, 0); if (irq == 0) { - dev_err(dev, "%s has no IRQ", - of_node_full_name(rpc->intc_of_node)); + dev_err(dev, "%pOF has no IRQ", rpc->intc_of_node); return -EINVAL; } @@ -438,8 +437,8 @@ static int rt3883_pci_probe(struct platform_device *pdev) } if (!rpc->intc_of_node) { - dev_err(dev, "%s has no %s child node", - of_node_full_name(rpc->intc_of_node), + dev_err(dev, "%pOF has no %s child node", + rpc->intc_of_node, "interrupt controller"); return -EINVAL; } @@ -454,8 +453,8 @@ static int rt3883_pci_probe(struct platform_device *pdev) } if (!rpc->pci_controller.of_node) { - dev_err(dev, "%s has no %s child node", - of_node_full_name(rpc->intc_of_node), + dev_err(dev, "%pOF has no %s child node", + rpc->intc_of_node, "PCI host bridge"); err = -EINVAL; goto err_put_intc_node; @@ -565,7 +564,7 @@ err_put_intc_node: return err; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return of_irq_parse_and_map_pci(dev, slot, pin); } diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c index 000c0e1f9ef8..a6418460e3c4 100644 --- a/arch/mips/pci/pci-tx4938.c +++ b/arch/mips/pci/pci-tx4938.c @@ -112,7 +112,7 @@ int __init tx4938_pciclk66_setup(void) return pciclk; } -int __init tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot) { if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4938_pcic1ptr) { switch (slot) { diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c index 9d6acc00f348..09a65f7dbe7c 100644 --- a/arch/mips/pci/pci-tx4939.c +++ b/arch/mips/pci/pci-tx4939.c @@ -48,7 +48,7 @@ void __init tx4939_report_pci1clk(void) ((pciclk + 50000) / 100000) % 10); } -int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) +int tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) { if (get_tx4927_pcicptr(dev->bus->sysdata) == tx4939_pcic1ptr) { switch (slot) { @@ -68,7 +68,7 @@ int __init tx4939_pcic1_map_irq(const struct pci_dev *dev, u8 slot) return -1; } -int __init tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int tx4939_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq = tx4939_pcic1_map_irq(dev, slot); diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c index 7babf01600cb..9eff9137f78e 100644 --- a/arch/mips/pci/pci-xlp.c +++ b/arch/mips/pci/pci-xlp.c @@ -205,7 +205,7 @@ int xlp_socdev_to_node(const struct pci_dev *lnkdev) return PCI_SLOT(lnkdev->devfn) / 8; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_dev *lnkdev; int lnkfunc, node; diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 26d2dabef281..2a1c81a129ba 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c @@ -315,7 +315,7 @@ static void xls_pcie_ack_b(struct irq_data *d) } } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { return get_irq_vector(dev); } diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index ad3584dbc9d7..fd2887415bc8 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -1464,8 +1464,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port) * as it goes through each bridge. * Returns Interrupt number for the device */ -int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, - u8 slot, u8 pin) +int octeon_pcie_pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* * The EBH5600 board with the PCI to PCIe bridge mistakenly diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig index 527d37da05ac..e284e89183cc 100644 --- a/arch/mips/pic32/Kconfig +++ b/arch/mips/pic32/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if MACH_PIC32 choice diff --git a/arch/mips/pistachio/Kconfig b/arch/mips/pistachio/Kconfig index 97731ea94322..9a0e06c95184 100644 --- a/arch/mips/pistachio/Kconfig +++ b/arch/mips/pistachio/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PISTACHIO_GPTIMER_CLKSRC bool "Enable General Purpose Timer based clocksource" depends on MACH_PISTACHIO diff --git a/arch/mips/pistachio/init.c b/arch/mips/pistachio/init.c index 1c91cad7988f..0b06c953d293 100644 --- a/arch/mips/pistachio/init.c +++ b/arch/mips/pistachio/init.c @@ -19,8 +19,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/arch/mips/pistachio/irq.c b/arch/mips/pistachio/irq.c index 0a6b24c24652..709a8219073a 100644 --- a/arch/mips/pistachio/irq.c +++ b/arch/mips/pistachio/irq.c @@ -10,7 +10,6 @@ #include #include -#include #include #include diff --git a/arch/mips/pistachio/time.c b/arch/mips/pistachio/time.c index 17a0f1dec05b..8a6af9b76202 100644 --- a/arch/mips/pistachio/time.c +++ b/arch/mips/pistachio/time.c @@ -12,9 +12,9 @@ #include #include #include -#include #include +#include #include unsigned int get_c0_compare_int(void) diff --git a/arch/mips/pmcs-msp71xx/Kconfig b/arch/mips/pmcs-msp71xx/Kconfig index 4190093d3053..d319bc0c3df6 100644 --- a/arch/mips/pmcs-msp71xx/Kconfig +++ b/arch/mips/pmcs-msp71xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "PMC-Sierra MSP SOC type" depends on PMC_MSP diff --git a/arch/mips/pmcs-msp71xx/Makefile b/arch/mips/pmcs-msp71xx/Makefile index d4f7220f2485..c040bd6ed62d 100644 --- a/arch/mips/pmcs-msp71xx/Makefile +++ b/arch/mips/pmcs-msp71xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PMC-Sierra MSP SOCs # diff --git a/arch/mips/pmcs-msp71xx/msp_smp.c b/arch/mips/pmcs-msp71xx/msp_smp.c index ffa0f7101a97..2b08242ade62 100644 --- a/arch/mips/pmcs-msp71xx/msp_smp.c +++ b/arch/mips/pmcs-msp71xx/msp_smp.c @@ -22,6 +22,8 @@ #include #include +#include + #ifdef CONFIG_MIPS_MT_SMP #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */ diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index 7cf4eb50fc72..a7a4e9f5146d 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/mips/power/hibernate.c b/arch/mips/power/hibernate.c index 19a9af68bcdb..94ab17c3c49d 100644 --- a/arch/mips/power/hibernate.c +++ b/arch/mips/power/hibernate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include extern int restore_image(void); diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 710b04cf4851..f26736b7080b 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if RALINK config CLKEVT_RT3352 @@ -82,6 +83,16 @@ choice depends on SOC_MT7620 select BUILTIN_DTB + config DTB_OMEGA2P + bool "Onion Omega2+" + depends on SOC_MT7620 + select BUILTIN_DTB + + config DTB_VOCORE2 + bool "VoCore2" + depends on SOC_MT7620 + select BUILTIN_DTB + endchoice endif diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index eb1c61917eb7..1b7df115eb60 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c @@ -53,6 +53,9 @@ EXPORT_SYMBOL_GPL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { + if (!clk) + return 0; + return clk->rate; } EXPORT_SYMBOL_GPL(clk_get_rate); diff --git a/arch/mips/ralink/irq-gic.c b/arch/mips/ralink/irq-gic.c index 2058280450b5..bda576f2cad8 100644 --- a/arch/mips/ralink/irq-gic.c +++ b/arch/mips/ralink/irq-gic.c @@ -11,7 +11,7 @@ #include #include -#include +#include int get_c0_perfcount_int(void) { diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c index 0695c2d64e49..1b274742077d 100644 --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c @@ -12,8 +12,7 @@ #include #include -#include -#include +#include #include #include @@ -199,7 +198,7 @@ void prom_soc_init(struct ralink_soc_info *soc_info) mips_cm_probe(); mips_cpc_probe(); - if (mips_cm_numiocu()) { + if (mips_cps_numiocu(0)) { /* * mips_cm_probe() wipes out bootloader * config for CM regions and we have to configure them diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 0966adccf520..32ea3e6731d6 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/mips/rb532/setup.c b/arch/mips/rb532/setup.c index d0c64e71d532..1aa4df1385cb 100644 --- a/arch/mips/rb532/setup.c +++ b/arch/mips/rb532/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * setup.c - boot time setup code */ diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index 411cda9ee030..45f42fa08faa 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the SGI specific kernel interface routines # under Linux. diff --git a/arch/mips/sgi-ip22/ip22-berr.c b/arch/mips/sgi-ip22/ip22-berr.c index ff8e1935c873..34bb9801d5ff 100644 --- a/arch/mips/sgi-ip22/ip22-berr.c +++ b/arch/mips/sgi-ip22/ip22-berr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip22-berr.c: Bus error handling. * diff --git a/arch/mips/sgi-ip22/ip22-hpc.c b/arch/mips/sgi-ip22/ip22-hpc.c index 396956e07307..49922e86cf1d 100644 --- a/arch/mips/sgi-ip22/ip22-hpc.c +++ b/arch/mips/sgi-ip22/ip22-hpc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip22-hpc.c: Routines for generic manipulation of the HPC controllers. * diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index c66889fc4913..3804895fa697 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC * found on INDY and Indigo2 workstations. diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index db5a64026443..1944d41507ef 100644 --- a/arch/mips/sgi-ip22/ip22-mc.c +++ b/arch/mips/sgi-ip22/ip22-mc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip22-mc.c: Routines for manipulating SGI Memory Controller. * diff --git a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c index cc6133bb57ca..e727ef519acf 100644 --- a/arch/mips/sgi-ip22/ip22-nvram.c +++ b/arch/mips/sgi-ip22/ip22-nvram.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip22-nvram.c: NVRAM and serial EEPROM handling. * diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c index a14fd32b76bd..37ad26716579 100644 --- a/arch/mips/sgi-ip22/ip22-platform.c +++ b/arch/mips/sgi-ip22/ip22-platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c index 872159970935..b69daa02401b 100644 --- a/arch/mips/sgi-ip22/ip22-setup.c +++ b/arch/mips/sgi-ip22/ip22-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip22-setup.c: SGI specific setup, including init of the feature struct. * diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c index 75460e1e106b..2ed8e4990b7a 100644 --- a/arch/mips/sgi-ip22/ip28-berr.c +++ b/arch/mips/sgi-ip22/ip28-berr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip28-berr.c: Bus error handling. * diff --git a/arch/mips/sgi-ip27/Kconfig b/arch/mips/sgi-ip27/Kconfig index 4d8705a65e4a..ef3847e7aee0 100644 --- a/arch/mips/sgi-ip27/Kconfig +++ b/arch/mips/sgi-ip27/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "Node addressing mode" depends on SGI_IP27 diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile index ab4affa626c7..73502fda13ee 100644 --- a/arch/mips/sgi-ip27/Makefile +++ b/arch/mips/sgi-ip27/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the IP27 specific kernel interface routines under Linux. # diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c index 2a1c40784bd9..cd449e90b917 100644 --- a/arch/mips/sgi-ip27/ip27-irq-pci.c +++ b/arch/mips/sgi-ip27/ip27-irq-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip27-irq.c: Highlevel interrupt handling for IP27 architecture. * diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 16ec4e12daa3..0dde6164a06f 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ip27-irq.c: Highlevel interrupt handling for IP27 architecture. * diff --git a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c index c873d62ff083..41171ff0c75e 100644 --- a/arch/mips/sgi-ip27/ip27-klconfig.c +++ b/arch/mips/sgi-ip27/ip27-klconfig.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999, 2000 Silicon Graphics, Inc. diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c index 2beb03907d09..a4f01328de62 100644 --- a/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/arch/mips/sgi-ip27/ip27-klnuma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00. * Copyright 2000 - 2001 Silicon Graphics, Inc. diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c index cfceaea92724..8ac2bfa35fb6 100644 --- a/arch/mips/sgi-ip27/ip27-nmi.c +++ b/arch/mips/sgi-ip27/ip27-nmi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c index 4cd47d23d81a..545446dfe7fa 100644 --- a/arch/mips/sgi-ip27/ip27-smp.c +++ b/arch/mips/sgi-ip27/ip27-smp.c @@ -195,7 +195,7 @@ static void ip27_smp_finish(void) * set sp to the kernel stack of the newly created idle process, gp to the proc * struct so that current_thread_info() will work. */ -static void ip27_boot_secondary(int cpu, struct task_struct *idle) +static int ip27_boot_secondary(int cpu, struct task_struct *idle) { unsigned long gp = (unsigned long)task_thread_info(idle); unsigned long sp = __KSTK_TOS(idle); @@ -203,6 +203,7 @@ static void ip27_boot_secondary(int cpu, struct task_struct *idle) LAUNCH_SLAVE(cputonasid(cpu), cputoslice(cpu), (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), 0, (void *) sp, (void *) gp); + return 0; } static void __init ip27_smp_setup(void) @@ -231,7 +232,7 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus) /* We already did everything necessary earlier */ } -struct plat_smp_ops ip27_smp_ops = { +const struct plat_smp_ops ip27_smp_ops = { .send_ipi_single = ip27_send_ipi_single, .send_ipi_mask = ip27_send_ipi_mask, .init_secondary = ip27_init_secondary, diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index a53f0c8c901e..9d55247533a5 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copytight (C) 1999, 2000, 05, 06 Ralf Baechle (ralf@linux-mips.org) * Copytight (C) 1999, 2000 Silicon Graphics, Inc. diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index 707b88441567..f4dbce25bc6a 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config SIBYTE_SB1250 bool select CEVT_SB1250 diff --git a/arch/mips/sibyte/Makefile b/arch/mips/sibyte/Makefile index 455c40d6d625..d015c4d79c3e 100644 --- a/arch/mips/sibyte/Makefile +++ b/arch/mips/sibyte/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Sibyte SB1250 / BCM1480 family of SOCs # diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c index d0e94ffcc1b8..90c9d1255ad7 100644 --- a/arch/mips/sibyte/bcm1480/smp.c +++ b/arch/mips/sibyte/bcm1480/smp.c @@ -117,7 +117,7 @@ static void bcm1480_smp_finish(void) * Setup the PC, SP, and GP of a secondary processor and start it * running! */ -static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) +static int bcm1480_boot_secondary(int cpu, struct task_struct *idle) { int retval; @@ -126,6 +126,7 @@ static void bcm1480_boot_secondary(int cpu, struct task_struct *idle) (unsigned long)task_thread_info(idle), 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); + return retval; } /* @@ -157,7 +158,7 @@ static void __init bcm1480_prepare_cpus(unsigned int max_cpus) { } -struct plat_smp_ops bcm1480_smp_ops = { +const struct plat_smp_ops bcm1480_smp_ops = { .send_ipi_single = bcm1480_send_ipi_single, .send_ipi_mask = bcm1480_send_ipi_mask, .init_secondary = bcm1480_init_secondary, diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index c1a11a11db7f..115399202eab 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c @@ -229,8 +229,8 @@ static int __init initrd_setup(char *str) #endif -extern struct plat_smp_ops sb_smp_ops; -extern struct plat_smp_ops bcm1480_smp_ops; +extern const struct plat_smp_ops sb_smp_ops; +extern const struct plat_smp_ops bcm1480_smp_ops; /* * prom_init is called just after the cpu type is determined, from setup_arch() diff --git a/arch/mips/sibyte/common/cfe_console.c b/arch/mips/sibyte/common/cfe_console.c index 1ad2da103fe9..8af7b41f7c19 100644 --- a/arch/mips/sibyte/common/cfe_console.c +++ b/arch/mips/sibyte/common/cfe_console.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c index 0a4a2c3982d8..5baabca52f25 100644 --- a/arch/mips/sibyte/sb1250/smp.c +++ b/arch/mips/sibyte/sb1250/smp.c @@ -106,7 +106,7 @@ static void sb1250_smp_finish(void) * Setup the PC, SP, and GP of a secondary processor and start it * running! */ -static void sb1250_boot_secondary(int cpu, struct task_struct *idle) +static int sb1250_boot_secondary(int cpu, struct task_struct *idle) { int retval; @@ -115,6 +115,7 @@ static void sb1250_boot_secondary(int cpu, struct task_struct *idle) (unsigned long)task_thread_info(idle), 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); + return retval; } /* @@ -146,7 +147,7 @@ static void __init sb1250_prepare_cpus(unsigned int max_cpus) { } -struct plat_smp_ops sb_smp_ops = { +const struct plat_smp_ops sb_smp_ops = { .send_ipi_single = sb1250_send_ipi_single, .send_ipi_mask = sb1250_send_ipi_mask, .init_secondary = sb1250_init_secondary, diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c index 1cecdcf85cf1..484969db7713 100644 --- a/arch/mips/sibyte/swarm/platform.c +++ b/arch/mips/sibyte/swarm/platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/sni/reset.c b/arch/mips/sni/reset.c index 6afa34346b81..66f963d8da7e 100644 --- a/arch/mips/sni/reset.c +++ b/arch/mips/sni/reset.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/mips/sni/process.c * diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c index 7ee14f41fc25..0eb7d1e8821b 100644 --- a/arch/mips/sni/time.c +++ b/arch/mips/sni/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/mips/tools/generic-board-config.sh b/arch/mips/tools/generic-board-config.sh new file mode 100755 index 000000000000..08849f83ef6c --- /dev/null +++ b/arch/mips/tools/generic-board-config.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# +# Copyright (C) 2017 Imagination Technologies +# Author: Paul Burton +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This script merges configuration fragments for boards supported by the +# generic MIPS kernel. It checks each for requirements specified using +# formatted comments, and then calls merge_config.sh to merge those +# fragments which have no unmet requirements. +# +# An example of requirements in your board config fragment might be: +# +# # require CONFIG_CPU_MIPS32_R2=y +# # require CONFIG_CPU_LITTLE_ENDIAN=y +# +# This would mean that your board is only included in kernels which are +# configured for little endian MIPS32r2 CPUs, and not for example in kernels +# configured for 64 bit or big endian systems. +# + +srctree="$1" +objtree="$2" +ref_cfg="$3" +cfg="$4" +boards_origin="$5" +shift 5 + +# Only print Skipping... lines if the user explicitly specified BOARDS=. In the +# general case it only serves to obscure the useful output about what actually +# was included. +case ${boards_origin} in +"command line") + print_skipped=1 + ;; +environment*) + print_skipped=1 + ;; +*) + print_skipped=0 + ;; +esac + +for board in $@; do + board_cfg="${srctree}/arch/mips/configs/generic/board-${board}.config" + if [ ! -f "${board_cfg}" ]; then + echo "WARNING: Board config '${board_cfg}' not found" + continue + fi + + # For each line beginning with # require, cut out the field following + # it & search for that in the reference config file. If the requirement + # is not found then the subshell will exit with code 1, and we'll + # continue on to the next board. + grep -E '^# require ' "${board_cfg}" | \ + cut -d' ' -f 3- | \ + while read req; do + case ${req} in + *=y) + # If we require something =y then we check that a line + # containing it is present in the reference config. + grep -Eq "^${req}\$" "${ref_cfg}" && continue + ;; + *=n) + # If we require something =n then we just invert that + # check, considering the requirement met if there isn't + # a line containing the value =y in the reference + # config. + grep -Eq "^${req/%=n/=y}\$" "${ref_cfg}" || continue + ;; + *) + echo "WARNING: Unhandled requirement '${req}'" + ;; + esac + + [ ${print_skipped} -eq 1 ] && echo "Skipping ${board_cfg}" + exit 1 + done || continue + + # Merge this board config fragment into our final config file + ${srctree}/scripts/kconfig/merge_config.sh \ + -m -O ${objtree} ${cfg} ${board_cfg} \ + | grep -Ev '^(#|Using)' +done diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 42923478d45c..d2509c93f0ee 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config MACH_TX39XX bool select MACH_TXX9 diff --git a/arch/mips/txx9/Makefile b/arch/mips/txx9/Makefile index 34787dabff06..195295937282 100644 --- a/arch/mips/txx9/Makefile +++ b/arch/mips/txx9/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Common TXx9 # diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index 1863c167e66e..6d00580fc81d 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for common code for TXx9 based systems # diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 0bd2a1e1ff9a..fb998726bd5d 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -386,9 +386,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } -int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int (*txx9_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin); +int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - return txx9_board_vec->pci_map_irq(dev, slot, pin); + return txx9_pci_map_irq(dev, slot, pin); } char * (*txx9_board_pcibios_setup)(char *str) __initdata; @@ -424,5 +425,8 @@ char *__init txx9_pcibios_setup(char *str) txx9_pci_err_action = TXX9_PCI_ERR_IGNORE; return NULL; } + + txx9_pci_map_irq = txx9_board_vec->pci_map_irq; + return str; } diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index b47d2a45dbf4..ce196046ac3e 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Objects to go into the VDSO. obj-vdso-y := elf.o gettimeofday.o sigreturn.o diff --git a/arch/mips/vdso/gettimeofday.c b/arch/mips/vdso/gettimeofday.c index e2690d7ca4dd..e22b422f282c 100644 --- a/arch/mips/vdso/gettimeofday.c +++ b/arch/mips/vdso/gettimeofday.c @@ -11,12 +11,10 @@ #include "vdso.h" #include -#include #include #include #include -#include #include #include @@ -126,9 +124,9 @@ static __always_inline u64 read_gic_count(const union mips_vdso_data *data) u32 hi, hi2, lo; do { - hi = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); - lo = __raw_readl(gic + GIC_UMV_SH_COUNTER_31_00_OFS); - hi2 = __raw_readl(gic + GIC_UMV_SH_COUNTER_63_32_OFS); + hi = __raw_readl(gic + sizeof(lo)); + lo = __raw_readl(gic); + hi2 = __raw_readl(gic + sizeof(lo)); } while (hi2 != hi); return (((u64)hi) << 32) + lo; diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S index 715bf5993529..30c6219912ac 100644 --- a/arch/mips/vdso/sigreturn.S +++ b/arch/mips/vdso/sigreturn.S @@ -19,31 +19,21 @@ .cfi_sections .debug_frame LEAF(__vdso_rt_sigreturn) - .cfi_startproc - .frame sp, 0, ra - .mask 0x00000000, 0 - .fmask 0x00000000, 0 .cfi_signal_frame li v0, __NR_rt_sigreturn syscall - .cfi_endproc END(__vdso_rt_sigreturn) #if _MIPS_SIM == _MIPS_SIM_ABI32 LEAF(__vdso_sigreturn) - .cfi_startproc - .frame sp, 0, ra - .mask 0x00000000, 0 - .fmask 0x00000000, 0 .cfi_signal_frame li v0, __NR_sigreturn syscall - .cfi_endproc END(__vdso_sigreturn) #endif diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index 74927b4d4f0b..992c988b83b0 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "Machine type" depends on MACH_VR41XX diff --git a/arch/mips/xilfpga/Kconfig b/arch/mips/xilfpga/Kconfig index 42a030a0edba..ca7b2368eab7 100644 --- a/arch/mips/xilfpga/Kconfig +++ b/arch/mips/xilfpga/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 choice prompt "Machine type" depends on MACH_XILFPGA diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 38e3494bfb63..e9d8d60bd28b 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config MN10300 def_bool y select HAVE_EXIT_THREAD diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug index 94efb3ed223f..37ada651f756 100644 --- a/arch/mn10300/Kconfig.debug +++ b/arch/mn10300/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/mn10300/boot/compressed/Makefile b/arch/mn10300/boot/compressed/Makefile index 5f56f9de1061..9b9a48fc8e53 100644 --- a/arch/mn10300/boot/compressed/Makefile +++ b/arch/mn10300/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Create a compressed vmlinux image from the original vmlinux # diff --git a/arch/mn10300/boot/tools/build.c b/arch/mn10300/boot/tools/build.c index 4f552ead0f8e..3ce158fe07b0 100644 --- a/arch/mn10300/boot/tools/build.c +++ b/arch/mn10300/boot/tools/build.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1997 Martin Mares diff --git a/arch/mn10300/configs/asb2303_defconfig b/arch/mn10300/configs/asb2303_defconfig index 1fd41ec1dfb5..d06dae131139 100644 --- a/arch/mn10300/configs/asb2303_defconfig +++ b/arch/mn10300/configs/asb2303_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_TINY_RCU=y @@ -28,16 +27,13 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_MTD=y CONFIG_MTD_DEBUG=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -CONFIG_MTD_CHAR=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -48,8 +44,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set diff --git a/arch/mn10300/configs/asb2364_defconfig b/arch/mn10300/configs/asb2364_defconfig index cd0a6cb17dee..b1d80cee97ee 100644 --- a/arch/mn10300/configs/asb2364_defconfig +++ b/arch/mn10300/configs/asb2364_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -40,7 +39,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set @@ -50,10 +48,8 @@ CONFIG_IPV6=y CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_DEBUG=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -CONFIG_MTD_CHAR=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -64,8 +60,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -77,7 +71,6 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_PROC_KCORE=y # CONFIG_PROC_PAGE_MONITOR is not set @@ -93,4 +86,3 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/mn10300/include/asm/kmap_types.h b/arch/mn10300/include/asm/kmap_types.h index 76d093b58d4f..f444d7ffa766 100644 --- a/arch/mn10300/include/asm/kmap_types.h +++ b/arch/mn10300/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H diff --git a/arch/mn10300/include/asm/mmu.h b/arch/mn10300/include/asm/mmu.h index 2d2d097e7309..b9d6d41adace 100644 --- a/arch/mn10300/include/asm/mmu.h +++ b/arch/mn10300/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* MN10300 Memory management context * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. diff --git a/arch/mn10300/include/asm/page_offset.h b/arch/mn10300/include/asm/page_offset.h index 8eb5b16ad86b..1e869aa09418 100644 --- a/arch/mn10300/include/asm/page_offset.h +++ b/arch/mn10300/include/asm/page_offset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* MN10300 Kernel base address * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. diff --git a/arch/mn10300/include/asm/shmparam.h b/arch/mn10300/include/asm/shmparam.h index ab666ed1a070..3a31faaa4353 100644 --- a/arch/mn10300/include/asm/shmparam.h +++ b/arch/mn10300/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SHMPARAM_H #define _ASM_SHMPARAM_H diff --git a/arch/mn10300/include/asm/spinlock.h b/arch/mn10300/include/asm/spinlock.h index 9c7b8f7942d8..fe413b41df6c 100644 --- a/arch/mn10300/include/asm/spinlock.h +++ b/arch/mn10300/include/asm/spinlock.h @@ -26,11 +26,6 @@ #define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) != 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->slock, !VAL); -} - static inline void arch_spin_unlock(arch_spinlock_t *lock) { asm volatile( diff --git a/arch/mn10300/include/asm/spinlock_types.h b/arch/mn10300/include/asm/spinlock_types.h index 653dc519b405..32abdc89bbc7 100644 --- a/arch/mn10300/include/asm/spinlock_types.h +++ b/arch/mn10300/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPINLOCK_TYPES_H #define _ASM_SPINLOCK_TYPES_H diff --git a/arch/mn10300/include/asm/termios.h b/arch/mn10300/include/asm/termios.h index c2e29c75dfac..4010edcaa08e 100644 --- a/arch/mn10300/include/asm/termios.h +++ b/arch/mn10300/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_TERMIOS_H #define _ASM_TERMIOS_H diff --git a/arch/mn10300/include/uapi/asm/bitsperlong.h b/arch/mn10300/include/uapi/asm/bitsperlong.h index 6dc0bb0c13b2..76da34b10f59 100644 --- a/arch/mn10300/include/uapi/asm/bitsperlong.h +++ b/arch/mn10300/include/uapi/asm/bitsperlong.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/byteorder.h b/arch/mn10300/include/uapi/asm/byteorder.h index 5dd0bdd9feee..3467df91216c 100644 --- a/arch/mn10300/include/uapi/asm/byteorder.h +++ b/arch/mn10300/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_BYTEORDER_H #define _ASM_BYTEORDER_H diff --git a/arch/mn10300/include/uapi/asm/errno.h b/arch/mn10300/include/uapi/asm/errno.h index 4c82b503d92f..9addba592646 100644 --- a/arch/mn10300/include/uapi/asm/errno.h +++ b/arch/mn10300/include/uapi/asm/errno.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/fcntl.h b/arch/mn10300/include/uapi/asm/fcntl.h index 46ab12db5739..a77648c505d1 100644 --- a/arch/mn10300/include/uapi/asm/fcntl.h +++ b/arch/mn10300/include/uapi/asm/fcntl.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/ioctl.h b/arch/mn10300/include/uapi/asm/ioctl.h index b279fe06dfe5..b809c4566e5f 100644 --- a/arch/mn10300/include/uapi/asm/ioctl.h +++ b/arch/mn10300/include/uapi/asm/ioctl.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/ioctls.h b/arch/mn10300/include/uapi/asm/ioctls.h index 0212f4b22557..0955d4f854e9 100644 --- a/arch/mn10300/include/uapi/asm/ioctls.h +++ b/arch/mn10300/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_IOCTLS_H #define _ASM_IOCTLS_H diff --git a/arch/mn10300/include/uapi/asm/ipcbuf.h b/arch/mn10300/include/uapi/asm/ipcbuf.h index 84c7e51cb6d0..90d6445a14df 100644 --- a/arch/mn10300/include/uapi/asm/ipcbuf.h +++ b/arch/mn10300/include/uapi/asm/ipcbuf.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/kvm_para.h b/arch/mn10300/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/mn10300/include/uapi/asm/kvm_para.h +++ b/arch/mn10300/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/mman.h b/arch/mn10300/include/uapi/asm/mman.h index db5c53da73ce..eb7f4798c036 100644 --- a/arch/mn10300/include/uapi/asm/mman.h +++ b/arch/mn10300/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include #define MIN_MAP_ADDR PAGE_SIZE /* minimum fixed mmap address */ diff --git a/arch/mn10300/include/uapi/asm/msgbuf.h b/arch/mn10300/include/uapi/asm/msgbuf.h index 8b602450cc4a..5982def83355 100644 --- a/arch/mn10300/include/uapi/asm/msgbuf.h +++ b/arch/mn10300/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_MSGBUF_H #define _ASM_MSGBUF_H diff --git a/arch/mn10300/include/uapi/asm/param.h b/arch/mn10300/include/uapi/asm/param.h index 02a0ca6f13ce..e0020d7742bd 100644 --- a/arch/mn10300/include/uapi/asm/param.h +++ b/arch/mn10300/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 Kernel parameters * * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. diff --git a/arch/mn10300/include/uapi/asm/poll.h b/arch/mn10300/include/uapi/asm/poll.h index c98509d3149e..b7132a305a47 100644 --- a/arch/mn10300/include/uapi/asm/poll.h +++ b/arch/mn10300/include/uapi/asm/poll.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/posix_types.h b/arch/mn10300/include/uapi/asm/posix_types.h index d31eeea480cf..6b4cfc7136e9 100644 --- a/arch/mn10300/include/uapi/asm/posix_types.h +++ b/arch/mn10300/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 POSIX types * * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. diff --git a/arch/mn10300/include/uapi/asm/ptrace.h b/arch/mn10300/include/uapi/asm/ptrace.h index 71b2251b7bff..f485c481a266 100644 --- a/arch/mn10300/include/uapi/asm/ptrace.h +++ b/arch/mn10300/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 Exception frame layout and ptrace constants * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. diff --git a/arch/mn10300/include/uapi/asm/resource.h b/arch/mn10300/include/uapi/asm/resource.h index 04bc4db8921b..49a81fbab43d 100644 --- a/arch/mn10300/include/uapi/asm/resource.h +++ b/arch/mn10300/include/uapi/asm/resource.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/mn10300/include/uapi/asm/sembuf.h b/arch/mn10300/include/uapi/asm/sembuf.h index 301f3f9d8aa9..ef44c42c7e0f 100644 --- a/arch/mn10300/include/uapi/asm/sembuf.h +++ b/arch/mn10300/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SEMBUF_H #define _ASM_SEMBUF_H diff --git a/arch/mn10300/include/uapi/asm/setup.h b/arch/mn10300/include/uapi/asm/setup.h index ae5704fa77ad..043dd4b92026 100644 --- a/arch/mn10300/include/uapi/asm/setup.h +++ b/arch/mn10300/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * There isn't anything here anymore, but the file must not be empty or patch * will delete it. diff --git a/arch/mn10300/include/uapi/asm/shmbuf.h b/arch/mn10300/include/uapi/asm/shmbuf.h index 8f300cc35d6c..6e81f74f51c6 100644 --- a/arch/mn10300/include/uapi/asm/shmbuf.h +++ b/arch/mn10300/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SHMBUF_H #define _ASM_SHMBUF_H diff --git a/arch/mn10300/include/uapi/asm/sigcontext.h b/arch/mn10300/include/uapi/asm/sigcontext.h index 4de3afff4ad7..1c361fabb977 100644 --- a/arch/mn10300/include/uapi/asm/sigcontext.h +++ b/arch/mn10300/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 Userspace signal context * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. diff --git a/arch/mn10300/include/uapi/asm/signal.h b/arch/mn10300/include/uapi/asm/signal.h index f423a08d7eeb..566cb199d5ac 100644 --- a/arch/mn10300/include/uapi/asm/signal.h +++ b/arch/mn10300/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 Signal definitions * * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index c710db354ff2..b35eee132142 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SOCKET_H #define _ASM_SOCKET_H @@ -102,4 +103,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/mn10300/include/uapi/asm/sockios.h b/arch/mn10300/include/uapi/asm/sockios.h index b03043a1c564..5706baa3cd0d 100644 --- a/arch/mn10300/include/uapi/asm/sockios.h +++ b/arch/mn10300/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SOCKIOS_H #define _ASM_SOCKIOS_H diff --git a/arch/mn10300/include/uapi/asm/stat.h b/arch/mn10300/include/uapi/asm/stat.h index 63ff8371cf2c..769f5f8829d4 100644 --- a/arch/mn10300/include/uapi/asm/stat.h +++ b/arch/mn10300/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_STAT_H #define _ASM_STAT_H diff --git a/arch/mn10300/include/uapi/asm/swab.h b/arch/mn10300/include/uapi/asm/swab.h index bd818a820ca8..d2284dd27ad4 100644 --- a/arch/mn10300/include/uapi/asm/swab.h +++ b/arch/mn10300/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 Byte-order primitive construction * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. diff --git a/arch/mn10300/include/uapi/asm/termbits.h b/arch/mn10300/include/uapi/asm/termbits.h index 130d42495972..fca82ea2ca2c 100644 --- a/arch/mn10300/include/uapi/asm/termbits.h +++ b/arch/mn10300/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_TERMBITS_H #define _ASM_TERMBITS_H diff --git a/arch/mn10300/include/uapi/asm/termios.h b/arch/mn10300/include/uapi/asm/termios.h index 11d3cc9d3162..25981aadb8cd 100644 --- a/arch/mn10300/include/uapi/asm/termios.h +++ b/arch/mn10300/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_TERMIOS_H #define _UAPI_ASM_TERMIOS_H diff --git a/arch/mn10300/include/uapi/asm/types.h b/arch/mn10300/include/uapi/asm/types.h index 8b3f0501b9bc..7d2a697e2937 100644 --- a/arch/mn10300/include/uapi/asm/types.h +++ b/arch/mn10300/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 Basic type definitions * * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd. diff --git a/arch/mn10300/include/uapi/asm/unistd.h b/arch/mn10300/include/uapi/asm/unistd.h index e28ac3f42479..c0c96b650692 100644 --- a/arch/mn10300/include/uapi/asm/unistd.h +++ b/arch/mn10300/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* MN10300 System call number list * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile index 561029f7fa44..de32af0e4b6e 100644 --- a/arch/mn10300/kernel/Makefile +++ b/arch/mn10300/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the MN10300-specific core kernel code # diff --git a/arch/mn10300/kernel/asm-offsets.c b/arch/mn10300/kernel/asm-offsets.c index e5a61c659b5a..57e6cc96267b 100644 --- a/arch/mn10300/kernel/asm-offsets.c +++ b/arch/mn10300/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generate definitions needed by assembly language modules. * This code generates raw asm output which is post-processed diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c index a128c57b586b..3399d5699804 100644 --- a/arch/mn10300/kernel/gdb-stub.c +++ b/arch/mn10300/kernel/gdb-stub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* MN10300 GDB stub * * Originally written by Glenn Engel, Lake Stevens Instrument Division diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c index 89e8027e07fb..7c475fd99c46 100644 --- a/arch/mn10300/kernel/process.c +++ b/arch/mn10300/kernel/process.c @@ -59,10 +59,6 @@ void arch_cpu_idle(void) } #endif -void release_segments(struct mm_struct *mm) -{ -} - void machine_restart(char *cmd) { #ifdef CONFIG_KERNEL_DEBUGGER @@ -112,14 +108,6 @@ void release_thread(struct task_struct *dead_task) { } -/* - * we do not have to muck with descriptors here, that is - * done in switch_mm() as needed. - */ -void copy_segments(struct task_struct *p, struct mm_struct *new_mm) -{ -} - /* * this gets called so that we can store lazy state into memory and copy the * current task into the new thread. diff --git a/arch/mn10300/mm/Kconfig.cache b/arch/mn10300/mm/Kconfig.cache index bfbe52691f2c..8cc5d9ec3b6c 100644 --- a/arch/mn10300/mm/Kconfig.cache +++ b/arch/mn10300/mm/Kconfig.cache @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # MN10300 CPU cache options # diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile index 11f38466ac28..048ba6f67f9a 100644 --- a/arch/mn10300/mm/Makefile +++ b/arch/mn10300/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the MN10300-specific memory management code # diff --git a/arch/mn10300/oprofile/Makefile b/arch/mn10300/oprofile/Makefile index 918dbe60ebb6..9fa95aaf496b 100644 --- a/arch/mn10300/oprofile/Makefile +++ b/arch/mn10300/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the MN10300-specific profiling code # diff --git a/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h b/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h index f537801a44ba..516afe824055 100644 --- a/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h +++ b/arch/mn10300/proc-mn103e010/include/proc/intctl-regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PROC_INTCTL_REGS_H #define _ASM_PROC_INTCTL_REGS_H diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h b/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h index a1e977273d19..4d4084ea6694 100644 --- a/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h +++ b/arch/mn10300/proc-mn2ws0050/include/proc/intctl-regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PROC_INTCTL_REGS_H #define _ASM_PROC_INTCTL_REGS_H diff --git a/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h b/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h index 33f100f9b468..2901ed344b3d 100644 --- a/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h +++ b/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ASB2364 FPGA registers */ diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig index c587764b9c5a..60fae03dac79 100644 --- a/arch/nios2/Kconfig +++ b/arch/nios2/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config NIOS2 def_bool y select TIMER_OF diff --git a/arch/nios2/Kconfig.debug b/arch/nios2/Kconfig.debug index 55105220370c..edfeef049a51 100644 --- a/arch/nios2/Kconfig.debug +++ b/arch/nios2/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT diff --git a/arch/nios2/boot/compressed/Makefile b/arch/nios2/boot/compressed/Makefile index d5921c9a9726..791e4309250a 100644 --- a/arch/nios2/boot/compressed/Makefile +++ b/arch/nios2/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # create a compressed vmlinux image from the original vmlinux # diff --git a/arch/nios2/boot/dts/3c120_devboard.dts b/arch/nios2/boot/dts/3c120_devboard.dts index 31c51f9a2f09..36ccdf05837d 100644 --- a/arch/nios2/boot/dts/3c120_devboard.dts +++ b/arch/nios2/boot/dts/3c120_devboard.dts @@ -159,6 +159,7 @@ }; chosen { - bootargs = "debug console=ttyJ0,115200"; + bootargs = "debug earlycon console=ttyJ0,115200"; + stdout-path = &jtag_uart; }; }; diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h index 7b3c6f280293..f8dc62222741 100644 --- a/arch/nios2/include/asm/dma-mapping.h +++ b/arch/nios2/include/asm/dma-mapping.h @@ -18,7 +18,7 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) } /* - * dma_alloc_noncoherent() returns non-cacheable memory, so there's no need to + * dma_alloc_attrs() always returns non-cacheable memory, so there's no need to * do any flushing here. */ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/arch/nios2/include/uapi/asm/byteorder.h b/arch/nios2/include/uapi/asm/byteorder.h index 3ab5dc20d757..639007a5544e 100644 --- a/arch/nios2/include/uapi/asm/byteorder.h +++ b/arch/nios2/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright (C) 2009 Thomas Chou * Copyright (C) 2004 Microtronix Datacom Ltd diff --git a/arch/nios2/include/uapi/asm/elf.h b/arch/nios2/include/uapi/asm/elf.h index 6f06d3b2949e..ab0df71f81b2 100644 --- a/arch/nios2/include/uapi/asm/elf.h +++ b/arch/nios2/include/uapi/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright (C) 2011 Tobias Klauser * diff --git a/arch/nios2/include/uapi/asm/ptrace.h b/arch/nios2/include/uapi/asm/ptrace.h index 1d35de90a977..2b91dbe5bcfe 100644 --- a/arch/nios2/include/uapi/asm/ptrace.h +++ b/arch/nios2/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2010 Tobias Klauser * Copyright (C) 2004 Microtronix Datacom Ltd diff --git a/arch/nios2/include/uapi/asm/sigcontext.h b/arch/nios2/include/uapi/asm/sigcontext.h index b67944a50927..204ae3475b4e 100644 --- a/arch/nios2/include/uapi/asm/sigcontext.h +++ b/arch/nios2/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright (C) 2004, Microtronix Datacom Ltd. * diff --git a/arch/nios2/include/uapi/asm/signal.h b/arch/nios2/include/uapi/asm/signal.h index f29ee6314481..b0d983068fa5 100644 --- a/arch/nios2/include/uapi/asm/signal.h +++ b/arch/nios2/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright Altera Corporation (C) 2013. All rights reserved * diff --git a/arch/nios2/include/uapi/asm/swab.h b/arch/nios2/include/uapi/asm/swab.h index b4e22ebaeb17..9750547a5f82 100644 --- a/arch/nios2/include/uapi/asm/swab.h +++ b/arch/nios2/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 Tobias Klauser * Copyright (C) 2011 Pyramid Technical Consultants, Inc. diff --git a/arch/nios2/include/uapi/asm/unistd.h b/arch/nios2/include/uapi/asm/unistd.h index 51a32c71ce2b..b6bdae04bc84 100644 --- a/arch/nios2/include/uapi/asm/unistd.h +++ b/arch/nios2/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2013 Altera Corporation * diff --git a/arch/nios2/kernel/Makefile b/arch/nios2/kernel/Makefile index 06d07432b38d..0b645e1e3158 100644 --- a/arch/nios2/kernel/Makefile +++ b/arch/nios2/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the nios2 linux kernel. # diff --git a/arch/nios2/kernel/time.c b/arch/nios2/kernel/time.c index 645129aaa9a0..20e86209ef2e 100644 --- a/arch/nios2/kernel/time.c +++ b/arch/nios2/kernel/time.c @@ -107,7 +107,10 @@ static struct nios2_clocksource nios2_cs = { cycles_t get_cycles(void) { - return nios2_timer_read(&nios2_cs.cs); + /* Only read timer if it has been initialized */ + if (nios2_cs.timer.base) + return nios2_timer_read(&nios2_cs.cs); + return 0; } EXPORT_SYMBOL(get_cycles); diff --git a/arch/nios2/mm/Makefile b/arch/nios2/mm/Makefile index 3cbd0840873c..9d37fafd1dd1 100644 --- a/arch/nios2/mm/Makefile +++ b/arch/nios2/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Nios2-specific parts of the memory manager. # diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig index 1e95920b0737..df2136ab1dcc 100644 --- a/arch/openrisc/Kconfig +++ b/arch/openrisc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. @@ -29,6 +30,9 @@ config OPENRISC select CPU_NO_EFFICIENT_FFS if !OPENRISC_HAVE_INST_FF1 select NO_BOOTMEM +config CPU_BIG_ENDIAN + def_bool y + config MMU def_bool y diff --git a/arch/openrisc/boot/dts/Makefile b/arch/openrisc/boot/dts/Makefile index b092d30d6c23..792ce7143c3a 100644 --- a/arch/openrisc/boot/dts/Makefile +++ b/arch/openrisc/boot/dts/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ifneq '$(CONFIG_OPENRISC_BUILTIN_DTB)' '""' BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_OPENRISC_BUILTIN_DTB)).dtb.o else diff --git a/arch/openrisc/boot/dts/or1ksim.dts b/arch/openrisc/boot/dts/or1ksim.dts index 5d4f9027afaf..9f4b856da580 100644 --- a/arch/openrisc/boot/dts/or1ksim.dts +++ b/arch/openrisc/boot/dts/or1ksim.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; / { compatible = "opencores,or1ksim"; diff --git a/arch/openrisc/include/asm/futex.h b/arch/openrisc/include/asm/futex.h index 778087341977..618da4a1bffb 100644 --- a/arch/openrisc/include/asm/futex.h +++ b/arch/openrisc/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_OPENRISC_FUTEX_H #define __ASM_OPENRISC_FUTEX_H @@ -30,20 +31,10 @@ }) static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -68,30 +59,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/openrisc/include/asm/pgtable.h b/arch/openrisc/include/asm/pgtable.h index ff97374ca069..71a6f08de8f2 100644 --- a/arch/openrisc/include/asm/pgtable.h +++ b/arch/openrisc/include/asm/pgtable.h @@ -414,6 +414,8 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */ +struct vm_area_struct; + /* * or32 doesn't have any external MMU info: the kernel page * tables contain all the necessary information. diff --git a/arch/openrisc/include/asm/string.h b/arch/openrisc/include/asm/string.h index 64939ccd7531..69b975454ff2 100644 --- a/arch/openrisc/include/asm/string.h +++ b/arch/openrisc/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_OPENRISC_STRING_H #define __ASM_OPENRISC_STRING_H diff --git a/arch/openrisc/include/uapi/asm/elf.h b/arch/openrisc/include/uapi/asm/elf.h index 88842760e66f..e892d5061685 100644 --- a/arch/openrisc/include/uapi/asm/elf.h +++ b/arch/openrisc/include/uapi/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * OpenRISC Linux * diff --git a/arch/openrisc/include/uapi/asm/param.h b/arch/openrisc/include/uapi/asm/param.h index c39a336610e2..103471e310ca 100644 --- a/arch/openrisc/include/uapi/asm/param.h +++ b/arch/openrisc/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * OpenRISC Linux * diff --git a/arch/openrisc/include/uapi/asm/ptrace.h b/arch/openrisc/include/uapi/asm/ptrace.h index 9760bd17fbcc..d4fab268f6aa 100644 --- a/arch/openrisc/include/uapi/asm/ptrace.h +++ b/arch/openrisc/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * OpenRISC Linux * diff --git a/arch/openrisc/include/uapi/asm/sigcontext.h b/arch/openrisc/include/uapi/asm/sigcontext.h index b79c2b19afbe..8ab775fc3450 100644 --- a/arch/openrisc/include/uapi/asm/sigcontext.h +++ b/arch/openrisc/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * OpenRISC Linux * diff --git a/arch/openrisc/include/uapi/asm/unistd.h b/arch/openrisc/include/uapi/asm/unistd.h index 471905bd7745..9a3ee389631e 100644 --- a/arch/openrisc/include/uapi/asm/unistd.h +++ b/arch/openrisc/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * OpenRISC Linux * diff --git a/arch/openrisc/kernel/Makefile b/arch/openrisc/kernel/Makefile index ec6d9d37cefd..c4ea6cabad46 100644 --- a/arch/openrisc/kernel/Makefile +++ b/arch/openrisc/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/openrisc/kernel/vmlinux.h b/arch/openrisc/kernel/vmlinux.h index bbcdf21b0b35..bdea46c617c7 100644 --- a/arch/openrisc/kernel/vmlinux.h +++ b/arch/openrisc/kernel/vmlinux.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __OPENRISC_VMLINUX_H_ #define __OPENRISC_VMLINUX_H_ diff --git a/arch/openrisc/lib/memcpy.c b/arch/openrisc/lib/memcpy.c index 669887a60e27..fe2177628fd9 100644 --- a/arch/openrisc/lib/memcpy.c +++ b/arch/openrisc/lib/memcpy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/openrisc/lib/memcpy.c * diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index dda1f558ef35..1fd3eb5b66c6 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PARISC def_bool y select ARCH_MIGHT_HAVE_PC_PARPORT @@ -9,6 +10,9 @@ config PARISC select ARCH_WANT_FRAME_POINTERS select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_STRICT_KERNEL_RWX + select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_WANTS_UBSAN_NO_NULL + select ARCH_SUPPORTS_MEMORY_FAILURE select RTC_CLASS select RTC_DRV_GENERIC select INIT_ALL_POSSIBLE @@ -17,6 +21,12 @@ config PARISC select BUG select BUILDTIME_EXTABLE_SORT select HAVE_PERF_EVENTS + select HAVE_KERNEL_BZIP2 + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZ4 + select HAVE_KERNEL_LZMA + select HAVE_KERNEL_LZO + select HAVE_KERNEL_XZ select GENERIC_ATOMIC64 if !64BIT select GENERIC_IRQ_PROBE select GENERIC_PCI_IOMAP @@ -50,6 +60,9 @@ config PARISC config CPU_BIG_ENDIAN def_bool y +config CPU_BIG_ENDIAN + def_bool y + config MMU def_bool y @@ -245,6 +258,18 @@ config PARISC_PAGE_SIZE_64KB endchoice +config PARISC_SELF_EXTRACT + bool "Build kernel as self-extracting executable" + default y + help + Say Y if you want to build the parisc kernel as a kind of + self-extracting executable. + + If you say N here, the kernel will be compressed with gzip + which can be loaded by the palo bootloader directly too. + + If you don't know what to do here, say Y. + config SMP bool "Symmetric multi-processing support" ---help--- diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug index 0d856b94c9b1..fb3507f9b14a 100644 --- a/arch/parisc/Kconfig.debug +++ b/arch/parisc/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 75cb451b1f03..01946ebaff72 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -24,15 +24,20 @@ KBUILD_DEFCONFIG := default_defconfig NM = sh $(srctree)/arch/parisc/nm CHECKFLAGS += -D__hppa__=1 LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) +export LIBGCC ifdef CONFIG_64BIT UTS_MACHINE := parisc64 CHECKFLAGS += -D__LP64__=1 -m64 CC_ARCHES = hppa64 +LD_BFD := elf64-hppa-linux else # 32-bit CC_ARCHES = hppa hppa2.0 hppa1.1 +LD_BFD := elf32-hppa-linux endif +export LD_BFD + ifneq ($(SUBARCH),$(UTS_MACHINE)) ifeq ($(CROSS_COMPILE),) CC_SUFFIXES = linux linux-gnu unknown-linux-gnu @@ -88,6 +93,8 @@ libs-y += arch/parisc/lib/ $(LIBGCC) drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ +boot := arch/parisc/boot + PALO := $(shell if (which palo 2>&1); then : ; \ elif [ -x /sbin/palo ]; then echo /sbin/palo; \ fi) @@ -116,11 +123,19 @@ INSTALL_TARGETS = zinstall install PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS) -bzImage zImage: vmlinuz +zImage: vmlinuz Image: vmlinux +bzImage: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ + +ifdef CONFIG_PARISC_SELF_EXTRACT +vmlinuz: bzImage + $(OBJCOPY) $(boot)/bzImage $@ +else vmlinuz: vmlinux @gzip -cf -9 $< > $@ +endif install: $(CONFIG_SHELL) $(src)/arch/parisc/install.sh \ diff --git a/arch/parisc/boot/.gitignore b/arch/parisc/boot/.gitignore new file mode 100644 index 000000000000..017d5912ad2d --- /dev/null +++ b/arch/parisc/boot/.gitignore @@ -0,0 +1,2 @@ +image +bzImage diff --git a/arch/parisc/boot/Makefile b/arch/parisc/boot/Makefile new file mode 100644 index 000000000000..cad68a584884 --- /dev/null +++ b/arch/parisc/boot/Makefile @@ -0,0 +1,26 @@ +# +# Makefile for the linux parisc-specific parts of the boot image creator. +# + +COMPILE_VERSION := __linux_compile_version_id__`hostname | \ + tr -c '[0-9A-Za-z]' '_'`__`date | \ + tr -c '[0-9A-Za-z]' '_'`_t + +ccflags-y := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I. + +targets := image +targets += bzImage +subdir- := compressed + +$(obj)/image: vmlinux FORCE + $(call if_changed,objcopy) + +$(obj)/bzImage: $(obj)/compressed/vmlinux FORCE + $(call if_changed,objcopy) + +$(obj)/compressed/vmlinux: FORCE + $(Q)$(MAKE) $(build)=$(obj)/compressed $@ + +install: $(CONFIGURE) $(obj)/bzImage + sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ + System.map "$(INSTALL_PATH)" diff --git a/arch/parisc/boot/compressed/.gitignore b/arch/parisc/boot/compressed/.gitignore new file mode 100644 index 000000000000..ae06b9b4c02f --- /dev/null +++ b/arch/parisc/boot/compressed/.gitignore @@ -0,0 +1,3 @@ +sizes.h +vmlinux +vmlinux.lds diff --git a/arch/parisc/boot/compressed/Makefile b/arch/parisc/boot/compressed/Makefile new file mode 100644 index 000000000000..7d7e594bda36 --- /dev/null +++ b/arch/parisc/boot/compressed/Makefile @@ -0,0 +1,86 @@ +# +# linux/arch/parisc/boot/compressed/Makefile +# +# create a compressed self-extracting vmlinux image from the original vmlinux +# + +KCOV_INSTRUMENT := n +GCOV_PROFILE := n +UBSAN_SANITIZE := n + +targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 +targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4 +targets += misc.o piggy.o sizes.h head.o real2.o firmware.o + +KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER +KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING +KBUILD_CFLAGS += $(cflags-y) -fno-delete-null-pointer-checks +KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os +ifndef CONFIG_64BIT +KBUILD_CFLAGS += -mfast-indirect-calls +endif + +OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o + +# LDFLAGS_vmlinux := -X --whole-archive -e startup -T +LDFLAGS_vmlinux := -X -e startup --as-needed -T +$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC) + $(call if_changed,ld) + +sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\)$$/\#define SZ\2 0x\1/p' + +quiet_cmd_sizes = GEN $@ + cmd_sizes = $(NM) $< | sed -n $(sed-sizes) > $@ + +$(obj)/sizes.h: vmlinux + $(call if_changed,sizes) + +AFLAGS_head.o += -I$(objtree)/$(obj) -DBOOTLOADER +$(obj)/head.o: $(obj)/sizes.h + +CFLAGS_misc.o += -I$(objtree)/$(obj) +$(obj)/misc.o: $(obj)/sizes.h + +$(obj)/firmware.o: $(obj)/firmware.c +$(obj)/firmware.c: $(srctree)/arch/$(SRCARCH)/kernel/firmware.c + $(call cmd,shipped) + +AFLAGS_real2.o += -DBOOTLOADER +$(obj)/real2.o: $(obj)/real2.S +$(obj)/real2.S: $(srctree)/arch/$(SRCARCH)/kernel/real2.S + $(call cmd,shipped) + +$(obj)/misc.o: $(obj)/sizes.h + +CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER +$(obj)/vmlinux.lds: $(obj)/sizes.h + +OBJCOPYFLAGS_vmlinux.bin := -O binary -R .comment -S +$(obj)/vmlinux.bin: vmlinux + $(call if_changed,objcopy) + +vmlinux.bin.all-y := $(obj)/vmlinux.bin + +suffix-$(CONFIG_KERNEL_GZIP) := gz +suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +suffix-$(CONFIG_KERNEL_LZ4) := lz4 +suffix-$(CONFIG_KERNEL_LZMA) := lzma +suffix-$(CONFIG_KERNEL_LZO) := lzo +suffix-$(CONFIG_KERNEL_XZ) := xz + +$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) + $(call if_changed,gzip) +$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) + $(call if_changed,bzip2) +$(obj)/vmlinux.bin.lz4: $(vmlinux.bin.all-y) + $(call if_changed,lz4) +$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) + $(call if_changed,lzma) +$(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) + $(call if_changed,lzo) +$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) + $(call if_changed,xzkern) + +LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T +$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) + $(call if_changed,ld) diff --git a/arch/parisc/boot/compressed/head.S b/arch/parisc/boot/compressed/head.S new file mode 100644 index 000000000000..5aba20fa48aa --- /dev/null +++ b/arch/parisc/boot/compressed/head.S @@ -0,0 +1,85 @@ +/* + * Startup glue code to uncompress the kernel + * + * (C) 2017 Helge Deller + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sizes.h" + +#define BOOTADDR(x) (x) + +#ifndef CONFIG_64BIT + .import $global$ /* forward declaration */ +#endif /*!CONFIG_64BIT*/ + + __HEAD + +ENTRY(startup) + .level LEVEL + +#define PSW_W_SM 0x200 +#define PSW_W_BIT 36 + + ;! nuke the W bit, saving original value + .level 2.0 + rsm PSW_W_SM, %r1 + + .level 1.1 + extrw,u %r1, PSW_W_BIT-32, 1, %r1 + copy %r1, %arg0 + + /* Make sure sr4-sr7 are set to zero for the kernel address space */ + mtsp %r0,%sr4 + mtsp %r0,%sr5 + mtsp %r0,%sr6 + mtsp %r0,%sr7 + + /* Clear BSS */ + + .import _bss,data + .import _ebss,data + + load32 BOOTADDR(_bss),%r3 + load32 BOOTADDR(_ebss),%r4 + ldo FRAME_SIZE(%r4),%sp /* stack at end of bss */ +$bss_loop: + cmpb,<<,n %r3,%r4,$bss_loop + stw,ma %r0,4(%r3) + + /* Initialize the global data pointer */ + loadgp + + /* arg0..arg4 were set by palo. */ + copy %arg1, %r6 /* command line */ + copy %arg2, %r7 /* rd-start */ + copy %arg3, %r8 /* rd-end */ + load32 BOOTADDR(decompress_kernel),%r3 + +#ifdef CONFIG_64BIT + .level LEVEL + ssm PSW_W_SM, %r0 /* set W-bit */ + depdi 0, 31, 32, %r3 +#endif + load32 BOOTADDR(startup_continue), %r2 + bv,n 0(%r3) + +startup_continue: +#ifdef CONFIG_64BIT + .level LEVEL + rsm PSW_W_SM, %r0 /* clear W-bit */ +#endif + + load32 KERNEL_BINARY_TEXT_START, %arg0 /* free mem */ + copy %r6, %arg1 /* command line */ + copy %r7, %arg2 /* rd-start */ + copy %r8, %arg3 /* rd-end */ + + bv,n 0(%ret0) +END(startup) diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c new file mode 100644 index 000000000000..9345b44b86f0 --- /dev/null +++ b/arch/parisc/boot/compressed/misc.c @@ -0,0 +1,302 @@ +/* + * Definitions and wrapper functions for kernel decompressor + * + * (C) 2017 Helge Deller + */ + +#include +#include +#include +#include "sizes.h" + +/* + * gzip declarations + */ +#define STATIC static + +#undef memmove +#define memmove memmove +#define memzero(s, n) memset((s), 0, (n)) + +#define malloc malloc_gzip +#define free free_gzip + +/* Symbols defined by linker scripts */ +extern char input_data[]; +extern int input_len; +/* output_len is inserted by the linker possibly at an unaligned address */ +extern __le32 output_len __aligned(1); +extern char _text, _end; +extern char _bss, _ebss; +extern char _startcode_end; +extern void startup_continue(void *entry, unsigned long cmdline, + unsigned long rd_start, unsigned long rd_end) __noreturn; + +void error(char *m) __noreturn; + +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; + +#ifdef CONFIG_KERNEL_GZIP +#include "../../../../lib/decompress_inflate.c" +#endif + +#ifdef CONFIG_KERNEL_BZIP2 +#include "../../../../lib/decompress_bunzip2.c" +#endif + +#ifdef CONFIG_KERNEL_LZ4 +#include "../../../../lib/decompress_unlz4.c" +#endif + +#ifdef CONFIG_KERNEL_LZMA +#include "../../../../lib/decompress_unlzma.c" +#endif + +#ifdef CONFIG_KERNEL_LZO +#include "../../../../lib/decompress_unlzo.c" +#endif + +#ifdef CONFIG_KERNEL_XZ +#include "../../../../lib/decompress_unxz.c" +#endif + +void *memmove(void *dest, const void *src, size_t n) +{ + const char *s = src; + char *d = dest; + + if (d <= s) { + while (n--) + *d++ = *s++; + } else { + d += n; + s += n; + while (n--) + *--d = *--s; + } + return dest; +} + +void *memset(void *s, int c, size_t count) +{ + char *xs = (char *)s; + + while (count--) + *xs++ = c; + return s; +} + +void *memcpy(void *d, const void *s, size_t len) +{ + char *dest = (char *)d; + const char *source = (const char *)s; + + while (len--) + *dest++ = *source++; + return d; +} + +size_t strlen(const char *s) +{ + const char *sc; + + for (sc = s; *sc != '\0'; ++sc) + ; + return sc - s; +} + +char *strchr(const char *s, int c) +{ + while (*s) { + if (*s == (char)c) + return (char *)s; + ++s; + } + return NULL; +} + +int puts(const char *s) +{ + const char *nuline = s; + + while ((nuline = strchr(s, '\n')) != NULL) { + if (nuline != s) + pdc_iodc_print(s, nuline - s); + pdc_iodc_print("\r\n", 2); + s = nuline + 1; + } + if (*s != '\0') + pdc_iodc_print(s, strlen(s)); + + return 0; +} + +static int putchar(int c) +{ + char buf[2]; + + buf[0] = c; + buf[1] = '\0'; + puts(buf); + return c; +} + +void __noreturn error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + while (1) /* wait forever */ + ; +} + +static int print_hex(unsigned long num) +{ + const char hex[] = "0123456789abcdef"; + char str[40]; + int i = sizeof(str)-1; + + str[i--] = '\0'; + do { + str[i--] = hex[num & 0x0f]; + num >>= 4; + } while (num); + + str[i--] = 'x'; + str[i] = '0'; + puts(&str[i]); + + return 0; +} + +int printf(const char *fmt, ...) +{ + va_list args; + int i = 0; + + va_start(args, fmt); + + while (fmt[i]) { + if (fmt[i] != '%') { +put: + putchar(fmt[i++]); + continue; + } + + if (fmt[++i] == '%') + goto put; + ++i; + print_hex(va_arg(args, unsigned long)); + } + + va_end(args); + return 0; +} + +/* helper functions for libgcc */ +void abort(void) +{ + error("aborted."); +} + +#undef malloc +void *malloc(size_t size) +{ + return malloc_gzip(size); +} + +#undef free +void free(void *ptr) +{ + return free_gzip(ptr); +} + + +static void flush_data_cache(char *start, unsigned long length) +{ + char *end = start + length; + + do { + asm volatile("fdc 0(%0)" : : "r" (start)); + asm volatile("fic 0(%%sr0,%0)" : : "r" (start)); + start += 16; + } while (start < end); + asm volatile("fdc 0(%0)" : : "r" (end)); + + asm ("sync"); +} + +unsigned long decompress_kernel(unsigned int started_wide, + unsigned int command_line, + const unsigned int rd_start, + const unsigned int rd_end) +{ + char *output; + unsigned long len, len_all; + +#ifdef CONFIG_64BIT + parisc_narrow_firmware = 0; +#endif + + set_firmware_width_unlocked(); + + putchar('U'); /* if you get this p and no more, string storage */ + /* in $GLOBAL$ is wrong or %dp is wrong */ + puts("ncompressing ...\n"); + + output = (char *) KERNEL_BINARY_TEXT_START; + len_all = __pa(SZ_end) - __pa(SZparisc_kernel_start); + + if ((unsigned long) &_startcode_end > (unsigned long) output) + error("Bootcode overlaps kernel code"); + + len = get_unaligned_le32(&output_len); + if (len > len_all) + error("Output len too big."); + else + memset(&output[len], 0, len_all - len); + + /* + * Initialize free_mem_ptr and free_mem_end_ptr. + */ + free_mem_ptr = (unsigned long) &_ebss; + free_mem_ptr += 2*1024*1024; /* leave 2 MB for stack */ + + /* Limit memory for bootoader to 1GB */ + #define ARTIFICIAL_LIMIT (1*1024*1024*1024) + free_mem_end_ptr = PAGE0->imm_max_mem; + if (free_mem_end_ptr > ARTIFICIAL_LIMIT) + free_mem_end_ptr = ARTIFICIAL_LIMIT; + +#ifdef CONFIG_BLK_DEV_INITRD + /* if we have ramdisk this is at end of memory */ + if (rd_start && rd_start < free_mem_end_ptr) + free_mem_end_ptr = rd_start; +#endif + +#ifdef DEBUG + printf("startcode_end = %x\n", &_startcode_end); + printf("commandline = %x\n", command_line); + printf("rd_start = %x\n", rd_start); + printf("rd_end = %x\n", rd_end); + + printf("free_ptr = %x\n", free_mem_ptr); + printf("free_ptr_end = %x\n", free_mem_end_ptr); + + printf("input_data = %x\n", input_data); + printf("input_len = %x\n", input_len); + printf("output = %x\n", output); + printf("output_len = %x\n", len); + printf("output_max = %x\n", len_all); +#endif + + __decompress(input_data, input_len, NULL, NULL, + output, 0, NULL, error); + + flush_data_cache(output, len); + + printf("Booting kernel ...\n\n"); + + return (unsigned long) output; +} diff --git a/arch/parisc/boot/compressed/vmlinux.lds.S b/arch/parisc/boot/compressed/vmlinux.lds.S new file mode 100644 index 000000000000..a4ce3314e78e --- /dev/null +++ b/arch/parisc/boot/compressed/vmlinux.lds.S @@ -0,0 +1,101 @@ +#include +#include +#include "sizes.h" + +#ifndef CONFIG_64BIT +OUTPUT_FORMAT("elf32-hppa-linux") +OUTPUT_ARCH(hppa) +#else +OUTPUT_FORMAT("elf64-hppa-linux") +OUTPUT_ARCH(hppa:hppa2.0w) +#endif + +ENTRY(startup) + +SECTIONS +{ + /* palo loads at 0x60000 */ + /* loaded kernel will move to 0x10000 */ + . = 0xe0000; /* should not overwrite palo code */ + + .head.text : { + _head = . ; + HEAD_TEXT + _ehead = . ; + } + + /* keep __gp below 0x1000000 */ +#ifdef CONFIG_64BIT + . = ALIGN(16); + /* Linkage tables */ + .opd : { + *(.opd) + } PROVIDE (__gp = .); + .plt : { + *(.plt) + } + .dlt : { + *(.dlt) + } +#endif + _startcode_end = .; + + /* bootloader code and data starts behind area of extracted kernel */ + . = (SZ_end - SZparisc_kernel_start + KERNEL_BINARY_TEXT_START); + + /* align on next page boundary */ + . = ALIGN(4096); + .text : { + _text = .; /* Text */ + *(.text) + *(.text.*) + _etext = . ; + } + . = ALIGN(8); + .data : { + _data = . ; + *(.data) + *(.data.*) + _edata = . ; + } + . = ALIGN(8); + .rodata : { + _rodata = . ; + *(.rodata) /* read-only data */ + *(.rodata.*) + _erodata = . ; + } + . = ALIGN(8); + .rodata.compressed : { + *(.rodata.compressed) + } + . = ALIGN(8); + .bss : { + _bss = . ; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4096); + _ebss = .; + } + + STABS_DEBUG + .note 0 : { *(.note) } + + /* Sections to be discarded */ + DISCARDS + /DISCARD/ : { +#ifdef CONFIG_64BIT + /* temporary hack until binutils is fixed to not emit these + * for static binaries + */ + *(.PARISC.unwind) /* no unwind data */ + *(.interp) + *(.dynsym) + *(.dynstr) + *(.dynamic) + *(.hash) + *(.gnu.hash) +#endif + } +} diff --git a/arch/parisc/boot/compressed/vmlinux.scr b/arch/parisc/boot/compressed/vmlinux.scr new file mode 100644 index 000000000000..dac2d142bcfa --- /dev/null +++ b/arch/parisc/boot/compressed/vmlinux.scr @@ -0,0 +1,10 @@ +SECTIONS +{ + .rodata.compressed : { + input_len = .; + LONG(input_data_end - input_data) input_data = .; + *(.data) + output_len = . - 4; /* can be at unaligned address */ + input_data_end = .; + } +} diff --git a/arch/parisc/boot/install.sh b/arch/parisc/boot/install.sh new file mode 100644 index 000000000000..8f7c365fad83 --- /dev/null +++ b/arch/parisc/boot/install.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# +# arch/parisc/install.sh, derived from arch/i386/boot/install.sh +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1995 by Linus Torvalds +# +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin +# +# "make install" script for i386 architecture +# +# Arguments: +# $1 - kernel version +# $2 - kernel image file +# $3 - kernel map file +# $4 - default install path (blank if root directory) +# + +verify () { + if [ ! -f "$1" ]; then + echo "" 1>&2 + echo " *** Missing file: $1" 1>&2 + echo ' *** You need to run "make" before "make install".' 1>&2 + echo "" 1>&2 + exit 1 + fi +} + +# Make sure the files actually exist + +verify "$2" +verify "$3" + +# User may have a custom install script + +if [ -n "${INSTALLKERNEL}" ]; then + if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi + if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi +fi + +# Default install + +if [ "$(basename $2)" = "zImage" ]; then +# Compressed install + echo "Installing compressed kernel" + base=vmlinuz +else +# Normal install + echo "Installing normal kernel" + base=vmlinux +fi + +if [ -f $4/$base-$1 ]; then + mv $4/$base-$1 $4/$base-$1.old +fi +cat $2 > $4/$base-$1 + +# Install system map file +if [ -f $4/System.map-$1 ]; then + mv $4/System.map-$1 $4/System.map-$1.old +fi +cp $3 $4/System.map-$1 diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index 0764d3971cf6..8d41a73bd71b 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y CONFIG_INET6_IPCOMP=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y CONFIG_NET_PKTGEN=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y diff --git a/arch/parisc/include/asm/agp.h b/arch/parisc/include/asm/agp.h index d226ffa8fc12..cb04470e63d0 100644 --- a/arch/parisc/include/asm/agp.h +++ b/arch/parisc/include/asm/agp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_AGP_H #define _ASM_PARISC_AGP_H diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 5394b9c5f914..bc54addd589f 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2006 Kyle McMartin */ @@ -65,6 +66,8 @@ static __inline__ void atomic_set(atomic_t *v, int i) _atomic_spin_unlock_irqrestore(v, flags); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + static __inline__ int atomic_read(const atomic_t *v) { return READ_ONCE((v)->counter); diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bitops.h index da87943328a5..53252d4f9a57 100644 --- a/arch/parisc/include/asm/bitops.h +++ b/arch/parisc/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_BITOPS_H #define _PARISC_BITOPS_H diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h index 07ea467f22fc..4b6d60b94124 100644 --- a/arch/parisc/include/asm/bug.h +++ b/arch/parisc/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_BUG_H #define _PARISC_BUG_H diff --git a/arch/parisc/include/asm/bugs.h b/arch/parisc/include/asm/bugs.h index 9e6284342a5f..0a7f9db6bd1c 100644 --- a/arch/parisc/include/asm/bugs.h +++ b/arch/parisc/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-parisc/bugs.h * diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h index df0f52bd18b4..150b7f30ea90 100644 --- a/arch/parisc/include/asm/cache.h +++ b/arch/parisc/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-parisc/cache.h */ diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index c7e15cc5c668..3742508cc534 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_CACHEFLUSH_H #define _PARISC_CACHEFLUSH_H diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h index 60c2c42619c9..3cbf1f1c1188 100644 --- a/arch/parisc/include/asm/checksum.h +++ b/arch/parisc/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_CHECKSUM_H #define _PARISC_CHECKSUM_H diff --git a/arch/parisc/include/asm/cmpxchg.h b/arch/parisc/include/asm/cmpxchg.h index 7ada30900807..f627c37dad9c 100644 --- a/arch/parisc/include/asm/cmpxchg.h +++ b/arch/parisc/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * forked from parisc asm/atomic.h which was: * Copyright (C) 2000 Philipp Rumpf diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 3387307cc33e..07f48827afda 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_COMPAT_H #define _ASM_PARISC_COMPAT_H /* diff --git a/arch/parisc/include/asm/compat_ucontext.h b/arch/parisc/include/asm/compat_ucontext.h index 2f7292afde3c..c606f1bc891d 100644 --- a/arch/parisc/include/asm/compat_ucontext.h +++ b/arch/parisc/include/asm/compat_ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_COMPAT_UCONTEXT_H #define _ASM_PARISC_COMPAT_UCONTEXT_H diff --git a/arch/parisc/include/asm/delay.h b/arch/parisc/include/asm/delay.h index 08e58e679e3e..841b506b702a 100644 --- a/arch/parisc/include/asm/delay.h +++ b/arch/parisc/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_DELAY_H #define _ASM_PARISC_DELAY_H diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h index 2b16282add69..7af4a00b5ce2 100644 --- a/arch/parisc/include/asm/dma-mapping.h +++ b/arch/parisc/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_DMA_MAPPING_H #define _PARISC_DMA_MAPPING_H diff --git a/arch/parisc/include/asm/dma.h b/arch/parisc/include/asm/dma.h index fd48ae2de950..eea80ed34e6d 100644 --- a/arch/parisc/include/asm/dma.h +++ b/arch/parisc/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* asm/dma.h: Defines for using and allocating dma channels. * Written by Hennus Bergman, 1992. * High DMA channel support & info by Hannu Savolainen diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h index a6b2a421571e..382d75a2ee4f 100644 --- a/arch/parisc/include/asm/elf.h +++ b/arch/parisc/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMPARISC_ELF_H #define __ASMPARISC_ELF_H diff --git a/arch/parisc/include/asm/fb.h b/arch/parisc/include/asm/fb.h index 4d503a023ab2..c4cd6360f996 100644 --- a/arch/parisc/include/asm/fb.h +++ b/arch/parisc/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ diff --git a/arch/parisc/include/asm/fixmap.h b/arch/parisc/include/asm/fixmap.h index 6fec4d4a1a18..f7c3a0905de4 100644 --- a/arch/parisc/include/asm/fixmap.h +++ b/arch/parisc/include/asm/fixmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FIXMAP_H #define _ASM_FIXMAP_H diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h index d635c6b0269d..42b2c75a1645 100644 --- a/arch/parisc/include/asm/ftrace.h +++ b/arch/parisc/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_FTRACE_H #define _ASM_PARISC_FTRACE_H diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 0ba14300cd8e..cf7ba058f619 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_FUTEX_H #define _ASM_PARISC_FUTEX_H @@ -32,22 +33,12 @@ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) } static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { unsigned long int flags; - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval, ret; u32 tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) - return -EFAULT; - _futex_spin_lock_irqsave(uaddr, &flags); pagefault_disable(); @@ -85,17 +76,9 @@ out_pagefault_enable: pagefault_enable(); _futex_spin_unlock_irqrestore(uaddr, &flags); - if (ret == 0) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h index 9b3bd039a609..077815169258 100644 --- a/arch/parisc/include/asm/hardirq.h +++ b/arch/parisc/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* hardirq.h: PA-RISC hard IRQ support. * * Copyright (C) 2001 Matthew Wilcox diff --git a/arch/parisc/include/asm/hardware.h b/arch/parisc/include/asm/hardware.h index d1d864b81bae..d6e1ed145031 100644 --- a/arch/parisc/include/asm/hardware.h +++ b/arch/parisc/include/asm/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_HARDWARE_H #define _PARISC_HARDWARE_H diff --git a/arch/parisc/include/asm/hash.h b/arch/parisc/include/asm/hash.h index dbe93311aa26..525950ed862d 100644 --- a/arch/parisc/include/asm/hash.h +++ b/arch/parisc/include/asm/hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HASH_H #define _ASM_HASH_H diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h index a65d888716c4..58e0f4620426 100644 --- a/arch/parisc/include/asm/hugetlb.h +++ b/arch/parisc/include/asm/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC64_HUGETLB_H #define _ASM_PARISC64_HUGETLB_H diff --git a/arch/parisc/include/asm/ide.h b/arch/parisc/include/asm/ide.h index 81700a2321cf..34cdac01ed35 100644 --- a/arch/parisc/include/asm/ide.h +++ b/arch/parisc/include/asm/ide.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-parisc/ide.h * diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h index af98254f7257..27c62baa9c4e 100644 --- a/arch/parisc/include/asm/io.h +++ b/arch/parisc/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IO_H #define _ASM_IO_H diff --git a/arch/parisc/include/asm/irq.h b/arch/parisc/include/asm/irq.h index 1073599a7be9..959e79cd2c14 100644 --- a/arch/parisc/include/asm/irq.h +++ b/arch/parisc/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-parisc/irq.h * diff --git a/arch/parisc/include/asm/irqflags.h b/arch/parisc/include/asm/irqflags.h index 34f9cb9b4754..38a19c0bac3a 100644 --- a/arch/parisc/include/asm/irqflags.h +++ b/arch/parisc/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PARISC_IRQFLAGS_H #define __PARISC_IRQFLAGS_H diff --git a/arch/parisc/include/asm/kbdleds.h b/arch/parisc/include/asm/kbdleds.h index 2e2e75a83c28..50fcce810655 100644 --- a/arch/parisc/include/asm/kbdleds.h +++ b/arch/parisc/include/asm/kbdleds.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_KBDLEDS_H #define _ASM_PARISC_KBDLEDS_H diff --git a/arch/parisc/include/asm/kmap_types.h b/arch/parisc/include/asm/kmap_types.h index 58e91ed0388f..3e70b5cd1123 100644 --- a/arch/parisc/include/asm/kmap_types.h +++ b/arch/parisc/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h index 8be707e1b6c7..dd5a08aaa4da 100644 --- a/arch/parisc/include/asm/ldcw.h +++ b/arch/parisc/include/asm/ldcw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PARISC_LDCW_H #define __PARISC_LDCW_H diff --git a/arch/parisc/include/asm/led.h b/arch/parisc/include/asm/led.h index c3405ab9d60a..6de13d08a388 100644 --- a/arch/parisc/include/asm/led.h +++ b/arch/parisc/include/asm/led.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LED_H #define LED_H diff --git a/arch/parisc/include/asm/linkage.h b/arch/parisc/include/asm/linkage.h index 67e6b433d399..9a69bf6fc4b6 100644 --- a/arch/parisc/include/asm/linkage.h +++ b/arch/parisc/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_PARISC_LINKAGE_H #define __ASM_PARISC_LINKAGE_H diff --git a/arch/parisc/include/asm/machdep.h b/arch/parisc/include/asm/machdep.h index a231c97d703e..215d2c43989d 100644 --- a/arch/parisc/include/asm/machdep.h +++ b/arch/parisc/include/asm/machdep.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_MACHDEP_H #define _PARISC_MACHDEP_H diff --git a/arch/parisc/include/asm/mckinley.h b/arch/parisc/include/asm/mckinley.h index d1ea6f12915e..eb84dbeb7fd9 100644 --- a/arch/parisc/include/asm/mckinley.h +++ b/arch/parisc/include/asm/mckinley.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_PARISC_MCKINLEY_H #define ASM_PARISC_MCKINLEY_H #ifdef __KERNEL__ diff --git a/arch/parisc/include/asm/mmu.h b/arch/parisc/include/asm/mmu.h index 6a310cf8b734..3fb70a601d5c 100644 --- a/arch/parisc/include/asm/mmu.h +++ b/arch/parisc/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_MMU_H_ #define _PARISC_MMU_H_ diff --git a/arch/parisc/include/asm/mmu_context.h b/arch/parisc/include/asm/mmu_context.h index a81226257878..697a906ab1b0 100644 --- a/arch/parisc/include/asm/mmu_context.h +++ b/arch/parisc/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PARISC_MMU_CONTEXT_H #define __PARISC_MMU_CONTEXT_H @@ -63,6 +64,9 @@ static inline void switch_mm(struct mm_struct *prev, { unsigned long flags; + if (prev == next) + return; + local_irq_save(flags); switch_mm_irqs_off(prev, next, tsk); local_irq_restore(flags); diff --git a/arch/parisc/include/asm/mmzone.h b/arch/parisc/include/asm/mmzone.h index b6b34a0987e7..fafa3893fd70 100644 --- a/arch/parisc/include/asm/mmzone.h +++ b/arch/parisc/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_MMZONE_H #define _PARISC_MMZONE_H diff --git a/arch/parisc/include/asm/module.h b/arch/parisc/include/asm/module.h index bab37e99168a..c8c131a74919 100644 --- a/arch/parisc/include/asm/module.h +++ b/arch/parisc/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_MODULE_H #define _ASM_PARISC_MODULE_H diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index 80e742a1c162..af00fe9bf846 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_PAGE_H #define _PARISC_PAGE_H @@ -116,11 +117,15 @@ extern int npmem_ranges; /* This governs the relationship between virtual and physical addresses. * If you alter it, make sure to take care of our various fixed mapping * segments in fixmap.h */ +#if defined(BOOTLOADER) +#define __PAGE_OFFSET (0) /* bootloader uses physical addresses */ +#else #ifdef CONFIG_64BIT #define __PAGE_OFFSET (0x40000000) /* 1GB */ #else #define __PAGE_OFFSET (0x10000000) /* 256MB */ #endif +#endif /* BOOTLOADER */ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) diff --git a/arch/parisc/include/asm/parisc-device.h b/arch/parisc/include/asm/parisc-device.h index eaf4dc1c7294..d02d144c6012 100644 --- a/arch/parisc/include/asm/parisc-device.h +++ b/arch/parisc/include/asm/parisc-device.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_PARISC_DEVICE_H_ #define _ASM_PARISC_PARISC_DEVICE_H_ diff --git a/arch/parisc/include/asm/parport.h b/arch/parisc/include/asm/parport.h index c391d7cbc223..2c8e2321c24d 100644 --- a/arch/parisc/include/asm/parport.h +++ b/arch/parisc/include/asm/parport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * parport.h: ia32-compatible parport initialisation diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index 1de1a3f412ec..6108e9df0296 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_PARISC_PCI_H #define __ASM_PARISC_PCI_H diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 7569627a032b..efee44a5e063 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_PDC_H #define _PARISC_PDC_H @@ -5,6 +6,8 @@ #if !defined(__ASSEMBLY__) +extern int parisc_narrow_firmware; + extern int pdc_type; extern unsigned long parisc_cell_num; /* cell number the CPU runs on (PAT) */ extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */ @@ -278,6 +281,7 @@ void setup_pdc(void); /* in inventory.c */ /* wrapper-functions from pdc.c */ int pdc_add_valid(unsigned long address); +int pdc_instr(unsigned int *instr); int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len); int pdc_chassis_disp(unsigned long disp); int pdc_chassis_warn(unsigned long *warn); diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h index e3c0586260d8..a468a172ee33 100644 --- a/arch/parisc/include/asm/pdcpat.h +++ b/arch/parisc/include/asm/pdcpat.h @@ -223,6 +223,18 @@ struct pdc_pat_mem_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_INFO (return info) */ unsigned long clear_time; /* last PDT clear time (since Jan 1970) */ }; +struct pdc_pat_mem_cell_pdt_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_CELL_INFO */ + u64 reserved:32; + u64 cs:1; /* clear status: cleared since the last call? */ + u64 current_pdt_entries:15; + u64 ic:1; /* interleaving had to be changed ? */ + u64 max_pdt_entries:15; + unsigned long good_mem; + unsigned long first_dbe_loc; /* first location of double bit error */ + unsigned long clear_time; /* last PDT clear time (since Jan 1970) */ +}; + + struct pdc_pat_mem_read_pd_retinfo { /* PDC_PAT_MEM/PDC_PAT_MEM_PD_READ */ unsigned long actual_count_bytes; unsigned long pdt_entries; @@ -325,6 +337,8 @@ extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *va extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); extern int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo); +extern int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo, + unsigned long cell); extern int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, unsigned long *pdt_entries_ptr, unsigned long max_entries); extern int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, diff --git a/arch/parisc/include/asm/perf.h b/arch/parisc/include/asm/perf.h index a18e11972c09..2a5a60affe70 100644 --- a/arch/parisc/include/asm/perf.h +++ b/arch/parisc/include/asm/perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PERF_H_ #define _ASM_PERF_H_ diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h index f08dda3f0995..cf13275f7c6d 100644 --- a/arch/parisc/include/asm/pgalloc.h +++ b/arch/parisc/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PGALLOC_H #define _ASM_PGALLOC_H diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 71ca86cb0f16..fa6b7c78f18a 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_PGTABLE_H #define _PARISC_PGTABLE_H diff --git a/arch/parisc/include/asm/prefetch.h b/arch/parisc/include/asm/prefetch.h index 1ee7c82672c1..6e63f720024d 100644 --- a/arch/parisc/include/asm/prefetch.h +++ b/arch/parisc/include/asm/prefetch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-parisc/prefetch.h * diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index b3b66c3d6f3c..0e6ab6e4a4e9 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-parisc/processor.h * diff --git a/arch/parisc/include/asm/psw.h b/arch/parisc/include/asm/psw.h index ad69a35e9c0f..76c301146c31 100644 --- a/arch/parisc/include/asm/psw.h +++ b/arch/parisc/include/asm/psw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_PSW_H diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h index 3c3cb004b7e2..46da07670c2b 100644 --- a/arch/parisc/include/asm/ptrace.h +++ b/arch/parisc/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* written by Philipp Rumpf, Copyright (C) 1999 SuSE GmbH Nuernberg ** Copyright (C) 2000 Grant Grundler, Hewlett-Packard */ diff --git a/arch/parisc/include/asm/ropes.h b/arch/parisc/include/asm/ropes.h index 09f51d5ab57c..8e51c775c80a 100644 --- a/arch/parisc/include/asm/ropes.h +++ b/arch/parisc/include/asm/ropes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_ROPES_H_ #define _ASM_PARISC_ROPES_H_ diff --git a/arch/parisc/include/asm/rt_sigframe.h b/arch/parisc/include/asm/rt_sigframe.h index f0dd3b30f6c4..2b3010ade00e 100644 --- a/arch/parisc/include/asm/rt_sigframe.h +++ b/arch/parisc/include/asm/rt_sigframe.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_RT_SIGFRAME_H #define _ASM_PARISC_RT_SIGFRAME_H diff --git a/arch/parisc/include/asm/runway.h b/arch/parisc/include/asm/runway.h index 5bea02da7e22..f3cfe69439f6 100644 --- a/arch/parisc/include/asm/runway.h +++ b/arch/parisc/include/asm/runway.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_PARISC_RUNWAY_H #define ASM_PARISC_RUNWAY_H #ifdef __KERNEL__ diff --git a/arch/parisc/include/asm/sections.h b/arch/parisc/include/asm/sections.h index 9d13c3507ad6..accdf40aa5b7 100644 --- a/arch/parisc/include/asm/sections.h +++ b/arch/parisc/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_SECTIONS_H #define _PARISC_SECTIONS_H diff --git a/arch/parisc/include/asm/shmparam.h b/arch/parisc/include/asm/shmparam.h index afe1300ab667..74f74e4d35b7 100644 --- a/arch/parisc/include/asm/shmparam.h +++ b/arch/parisc/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMPARISC_SHMPARAM_H #define _ASMPARISC_SHMPARAM_H diff --git a/arch/parisc/include/asm/signal.h b/arch/parisc/include/asm/signal.h index 81a545773971..eeb5c8858663 100644 --- a/arch/parisc/include/asm/signal.h +++ b/arch/parisc/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_SIGNAL_H #define _ASM_PARISC_SIGNAL_H diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h index a5dc9066c6d8..b9a18db4b05a 100644 --- a/arch/parisc/include/asm/smp.h +++ b/arch/parisc/include/asm/smp.h @@ -1,6 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SMP_H #define __ASM_SMP_H +extern int init_per_cpu(int cpuid); #if defined(CONFIG_SMP) diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h index 748016cb122d..79feff1b0721 100644 --- a/arch/parisc/include/asm/socket.h +++ b/arch/parisc/include/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SOCKET_H #define _ASM_SOCKET_H diff --git a/arch/parisc/include/asm/special_insns.h b/arch/parisc/include/asm/special_insns.h index e1509308899f..3d4dd68e181b 100644 --- a/arch/parisc/include/asm/special_insns.h +++ b/arch/parisc/include/asm/special_insns.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PARISC_SPECIAL_INSNS_H #define __PARISC_SPECIAL_INSNS_H diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index e32936cd7f10..af03359e6ac5 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_H #define __ASM_SPINLOCK_H @@ -14,13 +15,6 @@ static inline int arch_spin_is_locked(arch_spinlock_t *x) #define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *x) -{ - volatile unsigned int *a = __ldcw_align(x); - - smp_cond_load_acquire(a, VAL); -} - static inline void arch_spin_lock_flags(arch_spinlock_t *x, unsigned long flags) { diff --git a/arch/parisc/include/asm/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h index 8c373aa28a86..42979c5704dc 100644 --- a/arch/parisc/include/asm/spinlock_types.h +++ b/arch/parisc/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_TYPES_H #define __ASM_SPINLOCK_TYPES_H diff --git a/arch/parisc/include/asm/string.h b/arch/parisc/include/asm/string.h index eda01be65e35..f6e1132f4e35 100644 --- a/arch/parisc/include/asm/string.h +++ b/arch/parisc/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PA_STRING_H_ #define _PA_STRING_H_ diff --git a/arch/parisc/include/asm/superio.h b/arch/parisc/include/asm/superio.h index 6598acb4d46d..5e11c11d4395 100644 --- a/arch/parisc/include/asm/superio.h +++ b/arch/parisc/include/asm/superio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_SUPERIO_H #define _PARISC_SUPERIO_H diff --git a/arch/parisc/include/asm/switch_to.h b/arch/parisc/include/asm/switch_to.h index 8ed8fea1e784..f2ac9cc0de60 100644 --- a/arch/parisc/include/asm/switch_to.h +++ b/arch/parisc/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PARISC_SWITCH_TO_H #define __PARISC_SWITCH_TO_H diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h index 5e0b4e6bd99d..8bff1a58c97f 100644 --- a/arch/parisc/include/asm/syscall.h +++ b/arch/parisc/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* syscall.h */ #ifndef _ASM_PARISC_SYSCALL_H_ diff --git a/arch/parisc/include/asm/termios.h b/arch/parisc/include/asm/termios.h index 9bbc0c8974ea..cded9dc90c1b 100644 --- a/arch/parisc/include/asm/termios.h +++ b/arch/parisc/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_TERMIOS_H #define _PARISC_TERMIOS_H diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index bc208136bbb2..c980a02a52bc 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_THREAD_INFO_H #define _ASM_PARISC_THREAD_INFO_H diff --git a/arch/parisc/include/asm/timex.h b/arch/parisc/include/asm/timex.h index 2bd51f6d832b..45537cd4d1d3 100644 --- a/arch/parisc/include/asm/timex.h +++ b/arch/parisc/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-parisc/timex.h * diff --git a/arch/parisc/include/asm/tlb.h b/arch/parisc/include/asm/tlb.h index 07924903989e..0c881e74d8a6 100644 --- a/arch/parisc/include/asm/tlb.h +++ b/arch/parisc/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_TLB_H #define _PARISC_TLB_H diff --git a/arch/parisc/include/asm/tlbflush.h b/arch/parisc/include/asm/tlbflush.h index e84b96478193..14668bd52d60 100644 --- a/arch/parisc/include/asm/tlbflush.h +++ b/arch/parisc/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PARISC_TLBFLUSH_H #define _PARISC_TLBFLUSH_H diff --git a/arch/parisc/include/asm/traps.h b/arch/parisc/include/asm/traps.h index 63670231f48a..e00013248907 100644 --- a/arch/parisc/include/asm/traps.h +++ b/arch/parisc/include/asm/traps.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_TRAPS_H #define __ASM_TRAPS_H diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index cab33a0d0e82..ea70e36ce6af 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PARISC_UACCESS_H #define __PARISC_UACCESS_H diff --git a/arch/parisc/include/asm/ucontext.h b/arch/parisc/include/asm/ucontext.h index 6c8883e4b0bd..ac7f863864c5 100644 --- a/arch/parisc/include/asm/ucontext.h +++ b/arch/parisc/include/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_UCONTEXT_H #define _ASM_PARISC_UCONTEXT_H diff --git a/arch/parisc/include/asm/unaligned.h b/arch/parisc/include/asm/unaligned.h index dfc5d3321a54..e9029c7c2a69 100644 --- a/arch/parisc/include/asm/unaligned.h +++ b/arch/parisc/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_UNALIGNED_H #define _ASM_PARISC_UNALIGNED_H diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index 7dc31c84dd37..3d507d04eb4c 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_PARISC_UNISTD_H_ #define _ASM_PARISC_UNISTD_H_ diff --git a/arch/parisc/include/asm/unwind.h b/arch/parisc/include/asm/unwind.h index 52482e4fc20d..c73a3ee20226 100644 --- a/arch/parisc/include/asm/unwind.h +++ b/arch/parisc/include/asm/unwind.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _UNWIND_H_ #define _UNWIND_H_ diff --git a/arch/parisc/include/uapi/asm/bitsperlong.h b/arch/parisc/include/uapi/asm/bitsperlong.h index 07fa7e50bdc0..307e2ef1c62d 100644 --- a/arch/parisc/include/uapi/asm/bitsperlong.h +++ b/arch/parisc/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_PARISC_BITSPERLONG_H #define __ASM_PARISC_BITSPERLONG_H diff --git a/arch/parisc/include/uapi/asm/byteorder.h b/arch/parisc/include/uapi/asm/byteorder.h index 58af2c5f5d61..a59d9b7e35a8 100644 --- a/arch/parisc/include/uapi/asm/byteorder.h +++ b/arch/parisc/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_BYTEORDER_H #define _PARISC_BYTEORDER_H diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h index 274d5bc6ecce..fc0df353ff0d 100644 --- a/arch/parisc/include/uapi/asm/errno.h +++ b/arch/parisc/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_ERRNO_H #define _PARISC_ERRNO_H diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index 34a46cbc76ed..03ce20e5ad7d 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_FCNTL_H #define _PARISC_FCNTL_H diff --git a/arch/parisc/include/uapi/asm/ioctl.h b/arch/parisc/include/uapi/asm/ioctl.h index ec8efa02beda..b509bcc94a03 100644 --- a/arch/parisc/include/uapi/asm/ioctl.h +++ b/arch/parisc/include/uapi/asm/ioctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Linux/PA-RISC Project (http://www.parisc-linux.org/) * Copyright (C) 1999,2003 Matthew Wilcox < willy at debian . org > diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index d0e3321403be..aafb1c0ca0af 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_PARISC_IOCTLS_H__ #define __ARCH_PARISC_IOCTLS_H__ diff --git a/arch/parisc/include/uapi/asm/ipcbuf.h b/arch/parisc/include/uapi/asm/ipcbuf.h index 790c4119f647..edf266204b49 100644 --- a/arch/parisc/include/uapi/asm/ipcbuf.h +++ b/arch/parisc/include/uapi/asm/ipcbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __PARISC_IPCBUF_H__ #define __PARISC_IPCBUF_H__ diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h index 5979745815a5..d1af0d74a188 100644 --- a/arch/parisc/include/uapi/asm/mman.h +++ b/arch/parisc/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __PARISC_MMAN_H__ #define __PARISC_MMAN_H__ @@ -40,9 +41,6 @@ #define MADV_SEQUENTIAL 2 /* expect sequential page references */ #define MADV_WILLNEED 3 /* will need these pages */ #define MADV_DONTNEED 4 /* don't need these pages */ -#define MADV_SPACEAVAIL 5 /* insure that resources are reserved */ -#define MADV_VPS_PURGE 6 /* Purge pages from VM page cache */ -#define MADV_VPS_INHERIT 7 /* Inherit parents page size */ /* common/generic parameters */ #define MADV_FREE 8 /* free pages only if memory pressure */ @@ -60,21 +58,16 @@ overrides the coredump filter bits */ #define MADV_DODUMP 70 /* Clear the MADV_NODUMP flag */ +#define MADV_WIPEONFORK 71 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 72 /* Undo MADV_WIPEONFORK */ + +#define MADV_HWPOISON 100 /* poison a page for testing */ +#define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */ + /* compatibility flags */ #define MAP_FILE 0 #define MAP_VARIABLE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/arch/parisc/include/uapi/asm/msgbuf.h b/arch/parisc/include/uapi/asm/msgbuf.h index 2e83ac758e19..b48b810e626b 100644 --- a/arch/parisc/include/uapi/asm/msgbuf.h +++ b/arch/parisc/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_MSGBUF_H #define _PARISC_MSGBUF_H diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h index 1f30b49772aa..0ad117617f1a 100644 --- a/arch/parisc/include/uapi/asm/pdc.h +++ b/arch/parisc/include/uapi/asm/pdc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_PARISC_PDC_H #define _UAPI_PARISC_PDC_H diff --git a/arch/parisc/include/uapi/asm/posix_types.h b/arch/parisc/include/uapi/asm/posix_types.h index f3b5f70b9a5f..2785632c85e7 100644 --- a/arch/parisc/include/uapi/asm/posix_types.h +++ b/arch/parisc/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_PARISC_POSIX_TYPES_H #define __ARCH_PARISC_POSIX_TYPES_H diff --git a/arch/parisc/include/uapi/asm/ptrace.h b/arch/parisc/include/uapi/asm/ptrace.h index 02ce2eb99a7f..e72e06247f51 100644 --- a/arch/parisc/include/uapi/asm/ptrace.h +++ b/arch/parisc/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* written by Philipp Rumpf, Copyright (C) 1999 SuSE GmbH Nuernberg ** Copyright (C) 2000 Grant Grundler, Hewlett-Packard */ diff --git a/arch/parisc/include/uapi/asm/sembuf.h b/arch/parisc/include/uapi/asm/sembuf.h index c20971bf520f..746c5d86a9b1 100644 --- a/arch/parisc/include/uapi/asm/sembuf.h +++ b/arch/parisc/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_SEMBUF_H #define _PARISC_SEMBUF_H diff --git a/arch/parisc/include/uapi/asm/setup.h b/arch/parisc/include/uapi/asm/setup.h index 7da2e5b8747e..78b2f4ec7d65 100644 --- a/arch/parisc/include/uapi/asm/setup.h +++ b/arch/parisc/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_SETUP_H #define _PARISC_SETUP_H diff --git a/arch/parisc/include/uapi/asm/shmbuf.h b/arch/parisc/include/uapi/asm/shmbuf.h index 750e13e77991..cd4dbce55d0b 100644 --- a/arch/parisc/include/uapi/asm/shmbuf.h +++ b/arch/parisc/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_SHMBUF_H #define _PARISC_SHMBUF_H diff --git a/arch/parisc/include/uapi/asm/sigcontext.h b/arch/parisc/include/uapi/asm/sigcontext.h index 27ef31bb3b6e..be404bb0f8e3 100644 --- a/arch/parisc/include/uapi/asm/sigcontext.h +++ b/arch/parisc/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMPARISC_SIGCONTEXT_H #define _ASMPARISC_SIGCONTEXT_H diff --git a/arch/parisc/include/uapi/asm/siginfo.h b/arch/parisc/include/uapi/asm/siginfo.h index 8fd10f85c50e..4a1062e05aaf 100644 --- a/arch/parisc/include/uapi/asm/siginfo.h +++ b/arch/parisc/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_SIGINFO_H #define _PARISC_SIGINFO_H diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index e26043b73f5d..d38563a394f2 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_PARISC_SIGNAL_H #define _UAPI_ASM_PARISC_SIGNAL_H diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index a0d4dc9f4eb2..1d0fdc3b5d22 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_SOCKET_H #define _UAPI_ASM_SOCKET_H @@ -101,4 +102,6 @@ #define SO_PEERGROUPS 0x4034 +#define SO_ZEROCOPY 0x4035 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/parisc/include/uapi/asm/sockios.h b/arch/parisc/include/uapi/asm/sockios.h index dabfbc7483f6..66a3ba64d53f 100644 --- a/arch/parisc/include/uapi/asm/sockios.h +++ b/arch/parisc/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_PARISC_SOCKIOS__ #define __ARCH_PARISC_SOCKIOS__ diff --git a/arch/parisc/include/uapi/asm/stat.h b/arch/parisc/include/uapi/asm/stat.h index 3310d2a49759..b5bbf6704cae 100644 --- a/arch/parisc/include/uapi/asm/stat.h +++ b/arch/parisc/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_STAT_H #define _PARISC_STAT_H diff --git a/arch/parisc/include/uapi/asm/statfs.h b/arch/parisc/include/uapi/asm/statfs.h index 324bea905dc6..e5de020c21ab 100644 --- a/arch/parisc/include/uapi/asm/statfs.h +++ b/arch/parisc/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_STATFS_H #define _PARISC_STATFS_H diff --git a/arch/parisc/include/uapi/asm/swab.h b/arch/parisc/include/uapi/asm/swab.h index 928e1bbac98f..35fb2d1bfbbd 100644 --- a/arch/parisc/include/uapi/asm/swab.h +++ b/arch/parisc/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_SWAB_H #define _PARISC_SWAB_H diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h index d1ab92177a5c..40e920f8d683 100644 --- a/arch/parisc/include/uapi/asm/termbits.h +++ b/arch/parisc/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_PARISC_TERMBITS_H__ #define __ARCH_PARISC_TERMBITS_H__ diff --git a/arch/parisc/include/uapi/asm/termios.h b/arch/parisc/include/uapi/asm/termios.h index f3377395070d..aba174f23ef0 100644 --- a/arch/parisc/include/uapi/asm/termios.h +++ b/arch/parisc/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_PARISC_TERMIOS_H #define _UAPI_PARISC_TERMIOS_H diff --git a/arch/parisc/include/uapi/asm/types.h b/arch/parisc/include/uapi/asm/types.h index 8866f9bbdeaf..28c7d7453b10 100644 --- a/arch/parisc/include/uapi/asm/types.h +++ b/arch/parisc/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _PARISC_TYPES_H #define _PARISC_TYPES_H diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h index 667c99421003..4872e77aa96b 100644 --- a/arch/parisc/include/uapi/asm/unistd.h +++ b/arch/parisc/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_PARISC_UNISTD_H_ #define _UAPI_ASM_PARISC_UNISTD_H_ diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index c4294df69fb6..649dc3eda448 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for arch/parisc/kernel # diff --git a/arch/parisc/kernel/audit.c b/arch/parisc/kernel/audit.c index eb64a6148c82..9eb47b2225d2 100644 --- a/arch/parisc/kernel/audit.c +++ b/arch/parisc/kernel/audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c index f2adcf33f8f2..20dfa081ed0b 100644 --- a/arch/parisc/kernel/binfmt_elf32.c +++ b/arch/parisc/kernel/binfmt_elf32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels * diff --git a/arch/parisc/kernel/compat_audit.c b/arch/parisc/kernel/compat_audit.c index c74478f6bc74..20c39c9d86a9 100644 --- a/arch/parisc/kernel/compat_audit.c +++ b/arch/parisc/kernel/compat_audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include unsigned int parisc32_dir_class[] = { diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index f622a311d04a..6d471c00c71a 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -69,7 +69,15 @@ #include #include /* for boot_cpu_data */ +#if defined(BOOTLOADER) +# undef spin_lock_irqsave +# define spin_lock_irqsave(a, b) { b = 1; } +# undef spin_unlock_irqrestore +# define spin_unlock_irqrestore(a, b) +#else static DEFINE_SPINLOCK(pdc_lock); +#endif + extern unsigned long pdc_result[NUM_PDC_RESULT]; extern unsigned long pdc_result2[NUM_PDC_RESULT]; @@ -142,8 +150,8 @@ static void convert_to_wide(unsigned long *addr) int i; unsigned int *p = (unsigned int *)addr; - if(unlikely(parisc_narrow_firmware)) { - for(i = 31; i >= 0; --i) + if (unlikely(parisc_narrow_firmware)) { + for (i = (NUM_PDC_RESULT-1); i >= 0; --i) addr[i] = p[i]; } #endif @@ -186,6 +194,8 @@ void set_firmware_width(void) } #endif /*CONFIG_64BIT*/ + +#if !defined(BOOTLOADER) /** * pdc_emergency_unlock - Unlock the linux pdc lock * @@ -222,6 +232,26 @@ int pdc_add_valid(unsigned long address) } EXPORT_SYMBOL(pdc_add_valid); +/** + * pdc_instr - Get instruction that invokes PDCE_CHECK in HPMC handler. + * @instr: Pointer to variable which will get instruction opcode. + * + * The return value is PDC_OK (0) in case call succeeded. + */ +int __init pdc_instr(unsigned int *instr) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_INSTR, 0UL, __pa(pdc_result)); + convert_to_wide(pdc_result); + *instr = pdc_result[0]; + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + /** * pdc_chassis_info - Return chassis information. * @result: The return buffer. @@ -979,16 +1009,22 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret, spin_lock_irqsave(&pdc_lock, flags); retval = mem_pdc_call(PDC_MEM, PDC_MEM_READ_PDT, __pa(pdc_result), - __pa(pdc_result2)); + __pa(pdt_entries_ptr)); if (retval == PDC_OK) { convert_to_wide(pdc_result); memcpy(pret, pdc_result, sizeof(*pret)); - convert_to_wide(pdc_result2); - memcpy(pdt_entries_ptr, pdc_result2, - pret->pdt_entries * sizeof(*pdt_entries_ptr)); } spin_unlock_irqrestore(&pdc_lock, flags); +#ifdef CONFIG_64BIT + /* + * 64-bit kernels should not call this PDT function in narrow mode. + * The pdt_entries_ptr array above will now contain 32-bit values + */ + if (WARN_ON_ONCE((retval == PDC_OK) && parisc_narrow_firmware)) + return PDC_ERROR; +#endif + return retval; } @@ -1143,6 +1179,8 @@ void pdc_io_reset_devices(void) spin_unlock_irqrestore(&pdc_lock, flags); } +#endif /* defined(BOOTLOADER) */ + /* locked by pdc_console_lock */ static int __attribute__((aligned(8))) iodc_retbuf[32]; static char __attribute__((aligned(64))) iodc_dbuf[4096]; @@ -1187,6 +1225,7 @@ print: return i; } +#if !defined(BOOTLOADER) /** * pdc_iodc_getc - Read a character (non-blocking) from the PDC console. * @@ -1439,6 +1478,29 @@ int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo) return retval; } +/** + * pdc_pat_mem_pdt_cell_info - Retrieve information about page deallocation + * table of a cell + * @rinfo: memory pdt information + * @cell: cell number + * + */ +int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo, + unsigned long cell) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_INFO, + __pa(&pdc_result), cell); + if (retval == PDC_OK) + memcpy(rinfo, &pdc_result, sizeof(*rinfo)); + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} + /** * pdc_pat_mem_read_cell_pdt - Read PDT entries from (old) PAT firmware * @pret: array of PDT entries @@ -1455,14 +1517,14 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, spin_lock_irqsave(&pdc_lock, flags); /* PDC_PAT_MEM_CELL_READ is available on early PAT machines only */ retval = mem_pdc_call(PDC_PAT_MEM, PDC_PAT_MEM_CELL_READ, - __pa(&pdc_result), parisc_cell_num, __pa(&pdc_result2)); + __pa(&pdc_result), parisc_cell_num, + __pa(pdt_entries_ptr)); if (retval == PDC_OK) { /* build up return value as for PDC_PAT_MEM_PD_READ */ entries = min(pdc_result[0], max_entries); pret->pdt_entries = entries; pret->actual_count_bytes = entries * sizeof(unsigned long); - memcpy(pdt_entries_ptr, &pdc_result2, pret->actual_count_bytes); } spin_unlock_irqrestore(&pdc_lock, flags); @@ -1474,6 +1536,8 @@ int pdc_pat_mem_read_cell_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, * pdc_pat_mem_read_pd_pdt - Read PDT entries from (newer) PAT firmware * @pret: array of PDT entries * @pdt_entries_ptr: ptr to hold number of PDT entries + * @count: number of bytes to read + * @offset: offset to start (in bytes) * */ int pdc_pat_mem_read_pd_pdt(struct pdc_pat_mem_read_pd_retinfo *pret, @@ -1524,6 +1588,7 @@ int pdc_pat_mem_get_dimm_phys_location( return retval; } #endif /* CONFIG_64BIT */ +#endif /* defined(BOOTLOADER) */ /***************** 32-bit real-mode calls ***********/ @@ -1633,4 +1698,3 @@ long real64_call(unsigned long fn, ...) } #endif /* CONFIG_64BIT */ - diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c index 5a5506a35395..6fa8535d3cce 100644 --- a/arch/parisc/kernel/ftrace.c +++ b/arch/parisc/kernel/ftrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Code for tracing calls in Linux kernel. * Copyright (C) 2009-2016 Helge Deller diff --git a/arch/parisc/kernel/pa7300lc.c b/arch/parisc/kernel/pa7300lc.c index 9b245fc67560..0d770ac83f70 100644 --- a/arch/parisc/kernel/pa7300lc.c +++ b/arch/parisc/kernel/pa7300lc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/parisc/kernel/pa7300lc.c * - PA7300LC-specific functions diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index c6d6272a934f..7baa2265d439 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -35,12 +35,12 @@ EXPORT_SYMBOL(memset); EXPORT_SYMBOL(__xchg8); EXPORT_SYMBOL(__xchg32); EXPORT_SYMBOL(__cmpxchg_u32); +EXPORT_SYMBOL(__cmpxchg_u64); #ifdef CONFIG_SMP EXPORT_SYMBOL(__atomic_hash); #endif #ifdef CONFIG_64BIT EXPORT_SYMBOL(__xchg64); -EXPORT_SYMBOL(__cmpxchg_u64); #endif #include diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 5f0067a62738..412231d101f9 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ** PARISC 1.1 Dynamic DMA mapping support. ** This implementation is for PA-RISC platforms that do not support @@ -41,7 +42,7 @@ static unsigned long pcxl_used_bytes __read_mostly = 0; static unsigned long pcxl_used_pages __read_mostly = 0; extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */ -static spinlock_t pcxl_res_lock; +static DEFINE_SPINLOCK(pcxl_res_lock); static char *pcxl_res_map; static int pcxl_res_hint; static int pcxl_res_size; @@ -390,7 +391,6 @@ pcxl_dma_init(void) if (pcxl_dma_start == 0) return 0; - spin_lock_init(&pcxl_res_lock); pcxl_res_size = PCXL_DMA_MAP_SIZE >> (PAGE_SHIFT + 3); pcxl_res_hint = 0; pcxl_res_map = (char *)__get_free_pages(GFP_KERNEL, diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c index d02874ecb94d..e07eb34c8750 100644 --- a/arch/parisc/kernel/pdt.c +++ b/arch/parisc/kernel/pdt.c @@ -1,19 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Page Deallocation Table (PDT) support * - * The Page Deallocation Table (PDT) holds a table with pointers to bad - * memory (broken RAM modules) which is maintained by firmware. + * The Page Deallocation Table (PDT) is maintained by firmware and holds a + * list of memory addresses in which memory errors were detected. + * The list contains both single-bit (correctable) and double-bit + * (uncorrectable) errors. * * Copyright 2017 by Helge Deller * - * TODO: - * - check regularily for new bad memory - * - add userspace interface with procfs or sysfs - * - increase number of PDT entries dynamically + * possible future enhancements: + * - add userspace interface via procfs or sysfs to clear PDT */ #include #include +#include +#include #include #include @@ -24,11 +27,16 @@ enum pdt_access_type { PDT_NONE, PDT_PDC, PDT_PAT_NEW, - PDT_PAT_OLD + PDT_PAT_CELL }; static enum pdt_access_type pdt_type; +/* PDT poll interval: 1 minute if errors, 5 minutes if everything OK. */ +#define PDT_POLL_INTERVAL_DEFAULT (5*60*HZ) +#define PDT_POLL_INTERVAL_SHORT (1*60*HZ) +static unsigned long pdt_poll_interval = PDT_POLL_INTERVAL_DEFAULT; + /* global PDT status information */ static struct pdc_mem_retinfo pdt_status; @@ -36,6 +44,21 @@ static struct pdc_mem_retinfo pdt_status; #define MAX_PDT_ENTRIES (MAX_PDT_TABLE_SIZE / sizeof(unsigned long)) static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss; +/* + * Constants for the pdt_entry format: + * A pdt_entry holds the physical address in bits 0-57, bits 58-61 are + * reserved, bit 62 is the perm bit and bit 63 is the error_type bit. + * The perm bit indicates whether the error have been verified as a permanent + * error (value of 1) or has not been verified, and may be transient (value + * of 0). The error_type bit indicates whether the error is a single bit error + * (value of 1) or a multiple bit error. + * On non-PAT machines phys_addr is encoded in bits 0-59 and error_type in bit + * 63. Those machines don't provide the perm bit. + */ + +#define PDT_ADDR_PHYS_MASK (pdt_type != PDT_PDC ? ~0x3f : ~0x0f) +#define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL) +#define PDT_ADDR_SINGLE_ERR 1UL /* report PDT entries via /proc/meminfo */ void arch_report_meminfo(struct seq_file *m) @@ -49,6 +72,68 @@ void arch_report_meminfo(struct seq_file *m) pdt_status.pdt_entries); } +static int get_info_pat_new(void) +{ + struct pdc_pat_mem_retinfo pat_rinfo; + int ret; + + /* newer PAT machines like C8000 report info for all cells */ + if (is_pdc_pat()) + ret = pdc_pat_mem_pdt_info(&pat_rinfo); + else + return PDC_BAD_PROC; + + pdt_status.pdt_size = pat_rinfo.max_pdt_entries; + pdt_status.pdt_entries = pat_rinfo.current_pdt_entries; + pdt_status.pdt_status = 0; + pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc; + pdt_status.good_mem = pat_rinfo.good_mem; + + return ret; +} + +static int get_info_pat_cell(void) +{ + struct pdc_pat_mem_cell_pdt_retinfo cell_rinfo; + int ret; + + /* older PAT machines like rp5470 report cell info only */ + if (is_pdc_pat()) + ret = pdc_pat_mem_pdt_cell_info(&cell_rinfo, parisc_cell_num); + else + return PDC_BAD_PROC; + + pdt_status.pdt_size = cell_rinfo.max_pdt_entries; + pdt_status.pdt_entries = cell_rinfo.current_pdt_entries; + pdt_status.pdt_status = 0; + pdt_status.first_dbe_loc = cell_rinfo.first_dbe_loc; + pdt_status.good_mem = cell_rinfo.good_mem; + + return ret; +} + +static void report_mem_err(unsigned long pde) +{ + struct pdc_pat_mem_phys_mem_location loc; + unsigned long addr; + char dimm_txt[32]; + + addr = pde & PDT_ADDR_PHYS_MASK; + + /* show DIMM slot description on PAT machines */ + if (is_pdc_pat()) { + pdc_pat_mem_get_dimm_phys_location(&loc, addr); + sprintf(dimm_txt, "DIMM slot %02x, ", loc.dimm_slot); + } else + dimm_txt[0] = 0; + + pr_warn("PDT: BAD MEMORY at 0x%08lx, %s%s%s-bit error.\n", + addr, dimm_txt, + pde & PDT_ADDR_PERM_ERR ? "permanent ":"", + pde & PDT_ADDR_SINGLE_ERR ? "single":"multi"); +} + + /* * pdc_pdt_init() * @@ -63,18 +148,17 @@ void __init pdc_pdt_init(void) unsigned long entries; struct pdc_mem_read_pdt pdt_read_ret; - if (is_pdc_pat()) { - struct pdc_pat_mem_retinfo pat_rinfo; + pdt_type = PDT_PAT_NEW; + ret = get_info_pat_new(); - pdt_type = PDT_PAT_NEW; - ret = pdc_pat_mem_pdt_info(&pat_rinfo); - pdt_status.pdt_size = pat_rinfo.max_pdt_entries; - pdt_status.pdt_entries = pat_rinfo.current_pdt_entries; - pdt_status.pdt_status = 0; - pdt_status.first_dbe_loc = pat_rinfo.first_dbe_loc; - pdt_status.good_mem = pat_rinfo.good_mem; - } else { + if (ret != PDC_OK) { + pdt_type = PDT_PAT_CELL; + ret = get_info_pat_cell(); + } + + if (ret != PDC_OK) { pdt_type = PDT_PDC; + /* non-PAT machines provide the standard PDC call */ ret = pdc_mem_pdt_info(&pdt_status); } @@ -86,13 +170,17 @@ void __init pdc_pdt_init(void) } entries = pdt_status.pdt_entries; - WARN_ON(entries > MAX_PDT_ENTRIES); + if (WARN_ON(entries > MAX_PDT_ENTRIES)) + entries = pdt_status.pdt_entries = MAX_PDT_ENTRIES; - pr_info("PDT: size %lu, entries %lu, status %lu, dbe_loc 0x%lx," - " good_mem %lu\n", + pr_info("PDT: type %s, size %lu, entries %lu, status %lu, dbe_loc 0x%lx," + " good_mem %lu MB\n", + pdt_type == PDT_PDC ? __stringify(PDT_PDC) : + pdt_type == PDT_PAT_CELL ? __stringify(PDT_PAT_CELL) + : __stringify(PDT_PAT_NEW), pdt_status.pdt_size, pdt_status.pdt_entries, pdt_status.pdt_status, pdt_status.first_dbe_loc, - pdt_status.good_mem); + pdt_status.good_mem / 1024 / 1024); if (entries == 0) { pr_info("PDT: Firmware reports all memory OK.\n"); @@ -112,15 +200,12 @@ void __init pdc_pdt_init(void) #ifdef CONFIG_64BIT struct pdc_pat_mem_read_pd_retinfo pat_pret; - /* try old obsolete PAT firmware function first */ - pdt_type = PDT_PAT_OLD; - ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, - MAX_PDT_ENTRIES); - if (ret != PDC_OK) { - pdt_type = PDT_PAT_NEW; + if (pdt_type == PDT_PAT_CELL) + ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, + MAX_PDT_ENTRIES); + else ret = pdc_pat_mem_read_pd_pdt(&pat_pret, pdt_entry, MAX_PDT_TABLE_SIZE, 0); - } #else ret = PDC_BAD_PROC; #endif @@ -128,27 +213,150 @@ void __init pdc_pdt_init(void) if (ret != PDC_OK) { pdt_type = PDT_NONE; - pr_debug("PDT type %d, retval = %d\n", pdt_type, ret); + pr_warn("PDT: Get PDT entries failed with %d\n", ret); return; } for (i = 0; i < pdt_status.pdt_entries; i++) { - struct pdc_pat_mem_phys_mem_location loc; + unsigned long addr; - /* get DIMM slot number */ - loc.dimm_slot = 0xff; -#ifdef CONFIG_64BIT - pdc_pat_mem_get_dimm_phys_location(&loc, pdt_entry[i]); -#endif + report_mem_err(pdt_entry[i]); - pr_warn("PDT: BAD PAGE #%d at 0x%08lx, " - "DIMM slot %02x (error_type = %lu)\n", - i, - pdt_entry[i] & PAGE_MASK, - loc.dimm_slot, - pdt_entry[i] & 1); + addr = pdt_entry[i] & PDT_ADDR_PHYS_MASK; + if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && + addr >= initrd_start && addr < initrd_end) + pr_crit("CRITICAL: initrd possibly broken " + "due to bad memory!\n"); /* mark memory page bad */ memblock_reserve(pdt_entry[i] & PAGE_MASK, PAGE_SIZE); } } + + +/* + * This is the PDT kernel thread main loop. + */ + +static int pdt_mainloop(void *unused) +{ + struct pdc_mem_read_pdt pdt_read_ret; + struct pdc_pat_mem_read_pd_retinfo pat_pret __maybe_unused; + unsigned long old_num_entries; + unsigned long *bad_mem_ptr; + int num, ret; + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + + old_num_entries = pdt_status.pdt_entries; + + schedule_timeout(pdt_poll_interval); + if (kthread_should_stop()) + break; + + /* Do we have new PDT entries? */ + switch (pdt_type) { + case PDT_PAT_NEW: + ret = get_info_pat_new(); + break; + case PDT_PAT_CELL: + ret = get_info_pat_cell(); + break; + default: + ret = pdc_mem_pdt_info(&pdt_status); + break; + } + + if (ret != PDC_OK) { + pr_warn("PDT: unexpected failure %d\n", ret); + return -EINVAL; + } + + /* if no new PDT entries, just wait again */ + num = pdt_status.pdt_entries - old_num_entries; + if (num <= 0) + continue; + + /* decrease poll interval in case we found memory errors */ + if (pdt_status.pdt_entries && + pdt_poll_interval == PDT_POLL_INTERVAL_DEFAULT) + pdt_poll_interval = PDT_POLL_INTERVAL_SHORT; + + /* limit entries to get */ + if (num > MAX_PDT_ENTRIES) { + num = MAX_PDT_ENTRIES; + pdt_status.pdt_entries = old_num_entries + num; + } + + /* get new entries */ + switch (pdt_type) { +#ifdef CONFIG_64BIT + case PDT_PAT_CELL: + if (pdt_status.pdt_entries > MAX_PDT_ENTRIES) { + pr_crit("PDT: too many entries.\n"); + return -ENOMEM; + } + ret = pdc_pat_mem_read_cell_pdt(&pat_pret, pdt_entry, + MAX_PDT_ENTRIES); + bad_mem_ptr = &pdt_entry[old_num_entries]; + break; + case PDT_PAT_NEW: + ret = pdc_pat_mem_read_pd_pdt(&pat_pret, + pdt_entry, + num * sizeof(unsigned long), + old_num_entries * sizeof(unsigned long)); + bad_mem_ptr = &pdt_entry[0]; + break; +#endif + default: + ret = pdc_mem_pdt_read_entries(&pdt_read_ret, + pdt_entry); + bad_mem_ptr = &pdt_entry[old_num_entries]; + break; + } + + /* report and mark memory broken */ + while (num--) { + unsigned long pde = *bad_mem_ptr++; + + report_mem_err(pde); + +#ifdef CONFIG_MEMORY_FAILURE + if ((pde & PDT_ADDR_PERM_ERR) || + ((pde & PDT_ADDR_SINGLE_ERR) == 0)) + memory_failure(pde >> PAGE_SHIFT, 0, 0); + else + soft_offline_page( + pfn_to_page(pde >> PAGE_SHIFT), 0); +#else + pr_crit("PDT: memory error at 0x%lx ignored.\n" + "Rebuild kernel with CONFIG_MEMORY_FAILURE=y " + "for real handling.\n", + pde & PDT_ADDR_PHYS_MASK); +#endif + + } + } + + return 0; +} + + +static int __init pdt_initcall(void) +{ + struct task_struct *kpdtd_task; + + if (pdt_type == PDT_NONE) + return -ENODEV; + + kpdtd_task = kthread_create(pdt_mainloop, NULL, "kpdtd"); + if (IS_ERR(kpdtd_task)) + return PTR_ERR(kpdtd_task); + + wake_up_process(kpdtd_task); + + return 0; +} + +late_initcall(pdt_initcall); diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index 6017a5af2e6e..0813359049ae 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -69,7 +69,7 @@ struct rdr_tbl_ent { static int perf_processor_interface __read_mostly = UNKNOWN_INTF; static int perf_enabled __read_mostly; -static spinlock_t perf_lock; +static DEFINE_SPINLOCK(perf_lock); struct parisc_device *cpu_device __read_mostly; /* RDRs to write for PCX-W */ @@ -533,8 +533,6 @@ static int __init perf_init(void) /* Patch the images to match the system */ perf_patch_images(); - spin_lock_init(&perf_lock); - /* TODO: this only lets us access the first cpu.. what to do for SMP? */ cpu_device = per_cpu(cpu_data, 0).dev; printk("Performance monitoring counters enabled for %s\n", diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index a45a67d526f8..30f92391a93e 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -146,7 +146,7 @@ void machine_power_off(void) /* prevent soft lockup/stalled CPU messages for endless loop. */ rcu_sysrq_start(); - lockup_detector_suspend(); + lockup_detector_soft_poweroff(); for (;;); } diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 0ab32779dfa7..e120d63c1b28 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -89,7 +90,7 @@ init_percpu_prof(unsigned long cpunum) * (return 1). If so, initialize the chip and tell other partners in crime * they have work to do. */ -static int processor_probe(struct parisc_device *dev) +static int __init processor_probe(struct parisc_device *dev) { unsigned long txn_addr; unsigned long cpuid; @@ -237,28 +238,45 @@ static int processor_probe(struct parisc_device *dev) */ void __init collect_boot_cpu_data(void) { + unsigned long cr16_seed; + memset(&boot_cpu_data, 0, sizeof(boot_cpu_data)); + cr16_seed = get_cycles(); + add_device_randomness(&cr16_seed, sizeof(cr16_seed)); + boot_cpu_data.cpu_hz = 100 * PAGE0->mem_10msec; /* Hz of this PARISC */ /* get CPU-Model Information... */ #define p ((unsigned long *)&boot_cpu_data.pdc.model) - if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) + if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) { printk(KERN_INFO "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); + + add_device_randomness(&boot_cpu_data.pdc.model, + sizeof(boot_cpu_data.pdc.model)); + } #undef p - if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) + if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) { printk(KERN_INFO "vers %08lx\n", boot_cpu_data.pdc.versions); - if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) + add_device_randomness(&boot_cpu_data.pdc.versions, + sizeof(boot_cpu_data.pdc.versions)); + } + + if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) { printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n", (boot_cpu_data.pdc.cpuid >> 5) & 127, boot_cpu_data.pdc.cpuid & 31, boot_cpu_data.pdc.cpuid); + add_device_randomness(&boot_cpu_data.pdc.cpuid, + sizeof(boot_cpu_data.pdc.cpuid)); + } + if (pdc_model_capabilities(&boot_cpu_data.pdc.capabilities) == PDC_OK) printk(KERN_INFO "capabilities 0x%lx\n", boot_cpu_data.pdc.capabilities); @@ -299,7 +317,7 @@ void __init collect_boot_cpu_data(void) * * o Enable CPU profiling hooks. */ -int init_per_cpu(int cpunum) +int __init init_per_cpu(int cpunum) { int ret; struct pdc_coproc_cfg coproc_cfg; @@ -414,12 +432,12 @@ show_cpuinfo (struct seq_file *m, void *v) return 0; } -static const struct parisc_device_id processor_tbl[] = { +static const struct parisc_device_id processor_tbl[] __initconst = { { HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID }, { 0, } }; -static struct parisc_driver cpu_driver = { +static struct parisc_driver cpu_driver __refdata = { .name = "CPU", .id_table = processor_tbl, .probe = processor_probe diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index f8b6959d2d97..1a2be6e639b5 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel support for the ptrace() and syscall tracing interfaces. * diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S index 1db58e546230..cc9963421a19 100644 --- a/arch/parisc/kernel/real2.S +++ b/arch/parisc/kernel/real2.S @@ -162,6 +162,7 @@ ENDPROC_CFI(restore_control_regs) .text .align 128 ENTRY_CFI(rfi_virt2real) +#if !defined(BOOTLOADER) /* switch to real mode... */ rsm PSW_SM_I,%r0 load32 PA(rfi_v2r_1), %r1 @@ -191,6 +192,7 @@ ENTRY_CFI(rfi_virt2real) nop rfi_v2r_1: tophys_r1 %r2 +#endif /* defined(BOOTLOADER) */ bv 0(%r2) nop ENDPROC_CFI(rfi_virt2real) @@ -198,6 +200,7 @@ ENDPROC_CFI(rfi_virt2real) .text .align 128 ENTRY_CFI(rfi_real2virt) +#if !defined(BOOTLOADER) rsm PSW_SM_I,%r0 load32 (rfi_r2v_1), %r1 nop @@ -226,6 +229,7 @@ ENTRY_CFI(rfi_real2virt) nop rfi_r2v_1: tovirt_r1 %r2 +#endif /* defined(BOOTLOADER) */ bv 0(%r2) nop ENDPROC_CFI(rfi_real2virt) diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index dee6f9d6a153..f7d0c3b33d70 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include static char __initdata command_line[COMMAND_LINE_SIZE]; @@ -115,7 +117,6 @@ void __init dma_ops_init(void) } #endif -extern int init_per_cpu(int cpuid); extern void collect_boot_cpu_data(void); void __init setup_arch(char **cmdline_p) @@ -398,9 +399,8 @@ static int __init parisc_init(void) } arch_initcall(parisc_init); -void start_parisc(void) +void __init start_parisc(void) { - extern void start_kernel(void); extern void early_trap_init(void); int ret, cpunum; diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 26f12f45b4bb..f2a4038e275b 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/parisc/kernel/signal.c: Architecture-specific signal * handling support. diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 70aaabb8b3cb..9e0cb6a577d6 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -290,25 +290,25 @@ copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) if (to->si_code < 0) err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (to->si_code >> 16) { - case __SI_CHLD >> 16: + switch (siginfo_layout(to->si_signo, to->si_code)) { + case SIL_CHLD: err |= __get_user(to->si_utime, &from->si_utime); err |= __get_user(to->si_stime, &from->si_stime); err |= __get_user(to->si_status, &from->si_status); default: + case SIL_KILL: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __get_user(addr, &from->si_addr); to->si_addr = compat_ptr(addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __get_user(to->si_band, &from->si_band); err |= __get_user(to->si_fd, &from->si_fd); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); err |= __get_user(to->si_int, &from->si_int); @@ -337,41 +337,40 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_CHLD >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); - default: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: addr = ptr_to_compat(from->si_addr); err |= __put_user(addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); val = (compat_int_t)from->si_int; err |= __put_user(val, &to->si_int); break; - case __SI_RT >> 16: /* Not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_pid, &to->si_pid); val = (compat_int_t)from->si_int; err |= __put_user(val, &to->si_int); break; - case __SI_SYS >> 16: + case SIL_SYS: err |= __put_user(ptr_to_compat(from->si_call_addr), &to->si_call_addr); err |= __put_user(from->si_syscall, &to->si_syscall); err |= __put_user(from->si_arch, &to->si_arch); diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 63365106ea19..30c28ab14540 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -255,12 +255,11 @@ void arch_send_call_function_single_ipi(int cpu) static void __init smp_cpu_init(int cpunum) { - extern int init_per_cpu(int); /* arch/parisc/kernel/processor.c */ extern void init_IRQ(void); /* arch/parisc/kernel/irq.c */ extern void start_cpu_itimer(void); /* arch/parisc/kernel/time.c */ /* Set modes and Enable floating point coprocessor */ - (void) init_per_cpu(cpunum); + init_per_cpu(cpunum); disable_sr_hashing(); diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 93c1963d76fe..2a12a547b447 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sys_parisc32.c: Conversion between 32bit and 64bit native syscalls. * diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 23de307c3052..41e60a9c7db2 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -742,7 +742,7 @@ lws_compare_and_swap_2: 10: ldd 0(%r25), %r25 11: ldd 0(%r24), %r24 #else - /* Load new value into r22/r23 - high/low */ + /* Load old value into r22/r23 - high/low */ 10: ldw 0(%r25), %r22 11: ldw 4(%r25), %r23 /* Load new value into fr4 for atomic store later */ @@ -834,11 +834,11 @@ cas2_action: copy %r0, %r28 #else /* Compare first word */ -19: ldw,ma 0(%r26), %r29 +19: ldw 0(%r26), %r29 sub,= %r29, %r22, %r0 b,n cas2_end /* Compare second word */ -20: ldw,ma 4(%r26), %r29 +20: ldw 4(%r26), %r29 sub,= %r29, %r23, %r0 b,n cas2_end /* Perform the store */ diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 2d956aa0a38a..4b8fd6dc22da 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/parisc/kernel/time.c * @@ -253,7 +254,10 @@ static int __init init_cr16_clocksource(void) cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; for_each_online_cpu(cpu) { - if (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc) + if (cpu == 0) + continue; + if ((cpu0_loc != 0) && + (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)) continue; clocksource_cr16.name = "cr16_unstable"; diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 991654c88eec..8453724b8009 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/parisc/traps.c * @@ -817,7 +818,7 @@ void __init initialize_ivt(const void *iva) u32 check = 0; u32 *ivap; u32 *hpmcp; - u32 length; + u32 length, instr; if (strcmp((const char *)iva, "cows can fly")) panic("IVT invalid"); @@ -827,6 +828,14 @@ void __init initialize_ivt(const void *iva) for (i = 0; i < 8; i++) *ivap++ = 0; + /* + * Use PDC_INSTR firmware function to get instruction that invokes + * PDCE_CHECK in HPMC handler. See programming note at page 1-31 of + * the PA 1.1 Firmware Architecture document. + */ + if (pdc_instr(&instr) == PDC_OK) + ivap[0] = instr; + /* Compute Checksum for HPMC handler */ length = os_hpmc_size; ivap[7] = length; diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 1b73690477c5..5a657986ebbf 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel unwinding support * @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -34,7 +36,7 @@ extern struct unwind_table_entry __start___unwind[]; extern struct unwind_table_entry __stop___unwind[]; -static spinlock_t unwind_lock; +static DEFINE_SPINLOCK(unwind_lock); /* * the kernel unwind block is not dynamically allocated so that * we can call unwind_init as early in the bootup process as @@ -181,8 +183,6 @@ int __init unwind_init(void) start = (long)&__start___unwind[0]; stop = (long)&__stop___unwind[0]; - spin_lock_init(&unwind_lock); - printk("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n", start, stop, (stop - start) / sizeof(struct unwind_table_entry)); @@ -281,6 +281,17 @@ static void unwind_frame_regs(struct unwind_frame_info *info) info->prev_sp = sp - 64; info->prev_ip = 0; + + /* The stack is at the end inside the thread_union + * struct. If we reach data, we have reached the + * beginning of the stack and should stop unwinding. */ + if (info->prev_sp >= (unsigned long) task_thread_info(info->t) && + info->prev_sp < ((unsigned long) task_thread_info(info->t) + + THREAD_SZ_ALGN)) { + info->prev_sp = 0; + break; + } + if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET))) break; info->prev_ip = tmp; diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index ffe2cbf52d1a..159a2ec0b4e0 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Kernel link layout for various "sections" * * Copyright (C) 1999-2003 Matthew Wilcox diff --git a/arch/parisc/lib/bitops.c b/arch/parisc/lib/bitops.c index 8e45b0a97abf..70ffbcf889b8 100644 --- a/arch/parisc/lib/bitops.c +++ b/arch/parisc/lib/bitops.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * bitops.c: atomic operations which got too long to be inlined all over * the place. diff --git a/arch/parisc/lib/delay.c b/arch/parisc/lib/delay.c index ec9255f27a81..7eab4bb8abe6 100644 --- a/arch/parisc/lib/delay.c +++ b/arch/parisc/lib/delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Precise Delay Loops for parisc * diff --git a/arch/parisc/lib/io.c b/arch/parisc/lib/io.c index 7c1406ff825e..7c00496b47d4 100644 --- a/arch/parisc/lib/io.c +++ b/arch/parisc/lib/io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/parisc/lib/io.c * diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c index eaffbb90aa14..4b19e6e64fb7 100644 --- a/arch/parisc/lib/iomap.c +++ b/arch/parisc/lib/iomap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * iomap.c - Implement iomap interface for PA-RISC * Copyright (c) 2004 Matthew Wilcox diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index 99115cd9e790..865a7f796c7f 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -27,8 +27,6 @@ #include #include -DECLARE_PER_CPU(struct exception_data, exception_data); - #define get_user_space() (uaccess_kernel() ? 0 : mfsp(3)) #define get_kernel_space() (0) diff --git a/arch/parisc/lib/ucmpdi2.c b/arch/parisc/lib/ucmpdi2.c index 149c016f32c5..8e6014a142ef 100644 --- a/arch/parisc/lib/ucmpdi2.c +++ b/arch/parisc/lib/ucmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include union ull_union { diff --git a/arch/parisc/math-emu/Makefile b/arch/parisc/math-emu/Makefile index 0bd63b08a79a..b6c4b254901a 100644 --- a/arch/parisc/math-emu/Makefile +++ b/arch/parisc/math-emu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux/parisc floating point code # diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 5b101f6a5607..e247edbca68e 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -261,7 +262,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, struct task_struct *tsk; struct mm_struct *mm; unsigned long acc_type; - int fault; + int fault = 0; unsigned int flags; if (faulthandler_disabled()) @@ -315,7 +316,8 @@ good_area: goto out_of_memory; else if (fault & VM_FAULT_SIGSEGV) goto bad_area; - else if (fault & VM_FAULT_SIGBUS) + else if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| + VM_FAULT_HWPOISON_LARGE)) goto bad_area; BUG(); } @@ -352,8 +354,7 @@ bad_area: if (user_mode(regs)) { struct siginfo si; - - show_signal_msg(regs, code, address, tsk, vma); + unsigned int lsb = 0; switch (code) { case 15: /* Data TLB miss fault/Data page fault */ @@ -386,6 +387,30 @@ bad_area: si.si_code = (code == 26) ? SEGV_ACCERR : SEGV_MAPERR; break; } + +#ifdef CONFIG_MEMORY_FAILURE + if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { + printk(KERN_ERR + "MCE: Killing %s:%d due to hardware memory corruption fault at %08lx\n", + tsk->comm, tsk->pid, address); + si.si_signo = SIGBUS; + si.si_code = BUS_MCEERR_AR; + } +#endif + + /* + * Either small page or large page may be poisoned. + * In other words, VM_FAULT_HWPOISON_LARGE and + * VM_FAULT_HWPOISON are mutually exclusive. + */ + if (fault & VM_FAULT_HWPOISON_LARGE) + lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); + else if (fault & VM_FAULT_HWPOISON) + lsb = PAGE_SHIFT; + else + show_signal_msg(regs, code, address, tsk, vma); + si.si_addr_lsb = lsb; + si.si_errno = 0; si.si_addr = (void __user *) address; force_sig_info(si.si_signo, &si, current); diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c index 5eb8f633b282..d77479ae3af2 100644 --- a/arch/parisc/mm/hugetlbpage.c +++ b/arch/parisc/mm/hugetlbpage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PARISC64 Huge TLB page support. * diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 1ca9a2b4239f..13f7854e0d49 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/parisc/mm/init.c * diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c index 838d0259cd27..92a9b5f12f98 100644 --- a/arch/parisc/mm/ioremap.c +++ b/arch/parisc/mm/ioremap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/parisc/mm/ioremap.c * diff --git a/arch/parisc/oprofile/Makefile b/arch/parisc/oprofile/Makefile index e9feca1ca28b..86a1ccc328eb 100644 --- a/arch/parisc/oprofile/Makefile +++ b/arch/parisc/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 81b0031f909f..cb782ac1c35d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 source "arch/powerpc/platforms/Kconfig.cputype" config PPC32 @@ -85,6 +86,17 @@ config NMI_IPI depends on SMP && (DEBUGGER || KEXEC_CORE || HARDLOCKUP_DETECTOR) default y +config PPC_WATCHDOG + bool + depends on HARDLOCKUP_DETECTOR + depends on HAVE_HARDLOCKUP_DETECTOR_ARCH + default y + help + This is a placeholder when the powerpc hardlockup detector + watchdog is selected (arch/powerpc/kernel/watchdog.c). It is + seleted via the generic lockup detector menu which is why we + have no standalone config option for it here. + config STACKTRACE_SUPPORT bool default y @@ -165,7 +177,7 @@ config PPC select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK - select ARCH_HAS_STRICT_KERNEL_RWX if (PPC_BOOK3S_64 && !RELOCATABLE && !HIBERNATION) + select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX select HAVE_CBPF_JIT if !PPC64 select HAVE_CONTEXT_TRACKING if PPC64 @@ -356,10 +368,6 @@ config PPC_ADV_DEBUG_DAC_RANGE depends on PPC_ADV_DEBUG_REGS && 44x default y -config PPC_EMULATE_SSTEP - bool - default y if KPROBES || UPROBES || XMON || HAVE_HW_BREAKPOINT - config ZONE_DMA32 bool default y if PPC64 @@ -394,7 +402,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE config MATH_EMULATION bool "Math emulation" - depends on 4xx || 8xx || PPC_MPC832x || BOOKE + depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE ---help--- Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the @@ -956,9 +964,9 @@ config PPC_PCI_CHOICE config PCI bool "PCI support" if PPC_PCI_CHOICE - default y if !40x && !CPM2 && !8xx && !PPC_83xx \ + default y if !40x && !CPM2 && !PPC_8xx && !PPC_83xx \ && !PPC_85xx && !PPC_86xx && !GAMECUBE_COMMON - default PCI_QSPAN if !4xx && !CPM2 && 8xx + default PCI_QSPAN if PPC_8xx select GENERIC_PCI_IOMAP help Find out whether your system includes a PCI bus. PCI is the name of @@ -974,7 +982,7 @@ config PCI_SYSCALL config PCI_QSPAN bool "QSpan PCI" - depends on !4xx && !CPM2 && 8xx + depends on PPC_8xx select PPC_I8259 help Say Y here if you have a system based on a Motorola 8xx-series @@ -1165,12 +1173,23 @@ config CONSISTENT_SIZE config PIN_TLB bool "Pinned Kernel TLBs (860 ONLY)" - depends on ADVANCED_OPTIONS && 8xx + depends on ADVANCED_OPTIONS && PPC_8xx && \ + !DEBUG_PAGEALLOC && !STRICT_KERNEL_RWX + +config PIN_TLB_DATA + bool "Pinned TLB for DATA" + depends on PIN_TLB + default y config PIN_TLB_IMMR bool "Pinned TLB for IMMR" depends on PIN_TLB default y + +config PIN_TLB_TEXT + bool "Pinned TLB for TEXT" + depends on PIN_TLB + default y endmenu if PPC64 diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index c86df246339e..be1c8c5beb61 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index e2b3e7a00c9e..1381693a4a51 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -250,7 +250,7 @@ KBUILD_AFLAGS += $(aflags-y) KBUILD_CFLAGS += $(cflags-y) head-y := arch/powerpc/kernel/head_$(BITS).o -head-$(CONFIG_8xx) := arch/powerpc/kernel/head_8xx.o +head-$(CONFIG_PPC_8xx) := arch/powerpc/kernel/head_8xx.o head-$(CONFIG_40x) := arch/powerpc/kernel/head_40x.o head-$(CONFIG_44x) := arch/powerpc/kernel/head_44x.o head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o @@ -317,6 +317,10 @@ PHONY += ppc64le_defconfig ppc64le_defconfig: $(call merge_into_defconfig,ppc64_defconfig,le) +PHONY += powernv_be_defconfig +powernv_be_defconfig: + $(call merge_into_defconfig,powernv_defconfig,be) + PHONY += mpc85xx_defconfig mpc85xx_defconfig: $(call merge_into_defconfig,mpc85xx_basic_defconfig,\ diff --git a/arch/powerpc/Makefile.postlink b/arch/powerpc/Makefile.postlink index 5db43ebbe2df..83f8e5ba2722 100644 --- a/arch/powerpc/Makefile.postlink +++ b/arch/powerpc/Makefile.postlink @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # =========================================================================== # Post-link powerpc pass # =========================================================================== diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c index 9d3bd4c45a24..f7da65169124 100644 --- a/arch/powerpc/boot/4xx.c +++ b/arch/powerpc/boot/4xx.c @@ -564,7 +564,7 @@ void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) fbdv = 16; cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */ opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */ - ppdv = ((pllmr & 0x00001800) >> 13) + 1; /* PLB:PCI */ + ppdv = ((pllmr & 0x00006000) >> 13) + 1; /* PLB:PCI */ epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */ udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1; diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 6f952fe1f084..651974192c4d 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for making ELF bootable images for booting on CHRP # using Open Firmware. # @@ -107,17 +108,18 @@ src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \ $(libfdt) libfdt-wrapper.c \ ns16550.c serial.c simple_alloc.c div64.S util.S \ elf_util.c $(zlib-y) devtree.c stdlib.c \ - oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \ - uartlite.c mpc52xx-psc.c opal.c + oflib.c ofconsole.c cuboot.c cpm-serial.c \ + uartlite.c opal.c +src-wlib-$(CONFIG_PPC_MPC52XX) += mpc52xx-psc.c src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S ifndef CONFIG_PPC64_BOOT_WRAPPER src-wlib-y += crtsavres.S endif src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c -src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c +src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c -src-wlib-$(CONFIG_EMBEDDED6xx) += mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c +src-wlib-$(CONFIG_EMBEDDED6xx) += mpsc.c mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c src-plat-y := of.c epapr.c src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \ @@ -132,7 +134,7 @@ src-plat-$(CONFIG_44x) += treeboot-ebony.c cuboot-ebony.c treeboot-bamboo.c \ treeboot-iss4xx.c treeboot-currituck.c \ treeboot-akebono.c \ simpleboot.c fixed-head.S virtex.c -src-plat-$(CONFIG_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c +src-plat-$(CONFIG_PPC_8xx) += cuboot-8xx.c fixed-head.S ep88xc.c redboot-8xx.c src-plat-$(CONFIG_PPC_MPC52xx) += cuboot-52xx.c src-plat-$(CONFIG_PPC_82xx) += cuboot-pq2.c fixed-head.S ep8248e.c cuboot-824x.c src-plat-$(CONFIG_PPC_83xx) += cuboot-83xx.c fixed-head.S redboot-83xx.c diff --git a/arch/powerpc/boot/cpm-serial.c b/arch/powerpc/boot/cpm-serial.c index 19dc15abe43d..dfb56829cace 100644 --- a/arch/powerpc/boot/cpm-serial.c +++ b/arch/powerpc/boot/cpm-serial.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * CPM serial console support. * diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 12866ccb5694..dcf2f15e6797 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S @@ -26,17 +26,17 @@ _zimage_start_opd: #ifdef __powerpc64__ .balign 8 -p_start: .llong _start -p_etext: .llong _etext -p_bss_start: .llong __bss_start -p_end: .llong _end +p_start: .8byte _start +p_etext: .8byte _etext +p_bss_start: .8byte __bss_start +p_end: .8byte _end -p_toc: .llong __toc_start + 0x8000 - p_base -p_dyn: .llong __dynamic_start - p_base -p_rela: .llong __rela_dyn_start - p_base -p_prom: .llong 0 +p_toc: .8byte __toc_start + 0x8000 - p_base +p_dyn: .8byte __dynamic_start - p_base +p_rela: .8byte __rela_dyn_start - p_base +p_prom: .8byte 0 .weak _platform_stack_top -p_pstack: .llong _platform_stack_top +p_pstack: .8byte _platform_stack_top #else p_start: .long _start p_etext: .long _etext diff --git a/arch/powerpc/boot/cuboot.h b/arch/powerpc/boot/cuboot.h index cd2aa7f348f3..c2b2c58eaa0b 100644 --- a/arch/powerpc/boot/cuboot.h +++ b/arch/powerpc/boot/cuboot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_CUBOOT_H_ #define _PPC_BOOT_CUBOOT_H_ diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h index bf8f4ede1928..334ab8b5a668 100644 --- a/arch/powerpc/boot/dcr.h +++ b/arch/powerpc/boot/dcr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_DCR_H_ #define _PPC_BOOT_DCR_H_ diff --git a/arch/powerpc/boot/dts/fsp2.dts b/arch/powerpc/boot/dts/fsp2.dts index 475953ada707..f10a64aeb83b 100644 --- a/arch/powerpc/boot/dts/fsp2.dts +++ b/arch/powerpc/boot/dts/fsp2.dts @@ -52,6 +52,7 @@ clocks { mmc_clk: mmc_clk { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <50000000>; clock-output-names = "mmc_clk"; }; @@ -359,20 +360,6 @@ interrupts = <31 0x4 15 0x84>; }; - mmc0: sdhci@020c0000 { - compatible = "st,sdhci-stih407", "st,sdhci"; - status = "disabled"; - reg = <0x020c0000 0x20000>; - reg-names = "mmc"; - interrupt-parent = <&UIC1_3>; - interrupts = <21 0x4 22 0x4>; - interrupt-names = "mmcirq"; - pinctrl-names = "default"; - pinctrl-0 = <>; - clock-names = "mmc"; - clocks = <&mmc_clk>; - }; - plb6 { compatible = "ibm,plb6"; #address-cells = <2>; @@ -501,6 +488,24 @@ /*RXDE*/ 4 &UIC1_2 13 0x4>; }; + mmc0: mmc@20c0000 { + compatible = "st,sdhci-stih407", "st,sdhci"; + reg = <0x020c0000 0x20000>; + reg-names = "mmc"; + interrupts = <21 0x4>; + interrupt-parent = <&UIC1_3>; + interrupt-names = "mmcirq"; + pinctrl-names = "default"; + pinctrl-0 = <>; + clock-names = "mmc"; + clocks = <&mmc_clk>; + bus-width = <4>; + non-removable; + sd-uhs-sdr50; + sd-uhs-sdr104; + sd-uhs-ddr50; + }; + opb { compatible = "ibm,opb"; #address-cells = <1>; diff --git a/arch/powerpc/boot/dts/virtex440-ml510.dts b/arch/powerpc/boot/dts/virtex440-ml510.dts index 81a8dc2c6365..81201d3907e2 100644 --- a/arch/powerpc/boot/dts/virtex440-ml510.dts +++ b/arch/powerpc/boot/dts/virtex440-ml510.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Xilinx ML510 Reference Design support * diff --git a/arch/powerpc/boot/elf.h b/arch/powerpc/boot/elf.h index 1941bc50d4c5..f6aa7c20fcaf 100644 --- a/arch/powerpc/boot/elf.h +++ b/arch/powerpc/boot/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_ELF_H_ #define _PPC_BOOT_ELF_H_ diff --git a/arch/powerpc/boot/epapr-wrapper.c b/arch/powerpc/boot/epapr-wrapper.c index c10191006673..01262f50b769 100644 --- a/arch/powerpc/boot/epapr-wrapper.c +++ b/arch/powerpc/boot/epapr-wrapper.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 extern void epapr_platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); diff --git a/arch/powerpc/boot/fixed-head.S b/arch/powerpc/boot/fixed-head.S index 8e14cd9e1a54..4346c750cac1 100644 --- a/arch/powerpc/boot/fixed-head.S +++ b/arch/powerpc/boot/fixed-head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .text .global _zimage_start _zimage_start: diff --git a/arch/powerpc/boot/fsl-soc.h b/arch/powerpc/boot/fsl-soc.h index 5da26fc6e3cf..00b2cb89ff2f 100644 --- a/arch/powerpc/boot/fsl-soc.h +++ b/arch/powerpc/boot/fsl-soc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_FSL_SOC_H_ #define _PPC_BOOT_FSL_SOC_H_ diff --git a/arch/powerpc/boot/io.h b/arch/powerpc/boot/io.h index 394da5500466..5c6f90c34923 100644 --- a/arch/powerpc/boot/io.h +++ b/arch/powerpc/boot/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IO_H #define _IO_H diff --git a/arch/powerpc/boot/libfdt_env.h b/arch/powerpc/boot/libfdt_env.h index 7e3789ea396b..f52c31b1f48f 100644 --- a/arch/powerpc/boot/libfdt_env.h +++ b/arch/powerpc/boot/libfdt_env.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_POWERPC_BOOT_LIBFDT_ENV_H #define _ARCH_POWERPC_BOOT_LIBFDT_ENV_H diff --git a/arch/powerpc/boot/mktree.c b/arch/powerpc/boot/mktree.c index e2ae24340fc8..dc603f3c15be 100644 --- a/arch/powerpc/boot/mktree.c +++ b/arch/powerpc/boot/mktree.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Makes a tree bootable image for IBM Evaluation boards. * Basically, just take a zImage, skip the ELF header, and stuff diff --git a/arch/powerpc/boot/motload-head.S b/arch/powerpc/boot/motload-head.S index 41cabb4b63fa..826dad0c19d9 100644 --- a/arch/powerpc/boot/motload-head.S +++ b/arch/powerpc/boot/motload-head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include "ppc_asm.h" .text diff --git a/arch/powerpc/boot/mpc52xx-psc.c b/arch/powerpc/boot/mpc52xx-psc.c index d4cb4e4e0938..c2c08633ee35 100644 --- a/arch/powerpc/boot/mpc52xx-psc.c +++ b/arch/powerpc/boot/mpc52xx-psc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MPC5200 PSC serial console support. * diff --git a/arch/powerpc/boot/mpc8xx.h b/arch/powerpc/boot/mpc8xx.h index 3f59901ab1c0..3852ed90047f 100644 --- a/arch/powerpc/boot/mpc8xx.h +++ b/arch/powerpc/boot/mpc8xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_MPC8xx_H_ #define _PPC_BOOT_MPC8xx_H_ diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c index 8c9ead94be06..b0da4466d419 100644 --- a/arch/powerpc/boot/ns16550.c +++ b/arch/powerpc/boot/ns16550.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * 16550 serial console support. * diff --git a/arch/powerpc/boot/of.h b/arch/powerpc/boot/of.h index 53f8f27f94e4..31b2f5dfd589 100644 --- a/arch/powerpc/boot/of.h +++ b/arch/powerpc/boot/of.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_OF_H_ #define _PPC_BOOT_OF_H_ diff --git a/arch/powerpc/boot/planetcore.h b/arch/powerpc/boot/planetcore.h index d53c733cc463..5311db06c62b 100644 --- a/arch/powerpc/boot/planetcore.h +++ b/arch/powerpc/boot/planetcore.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_PLANETCORE_H_ #define _PPC_BOOT_PLANETCORE_H_ diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h index 68e388ee94fe..c63299f9fdd9 100644 --- a/arch/powerpc/boot/ppc_asm.h +++ b/arch/powerpc/boot/ppc_asm.h @@ -80,4 +80,12 @@ .long 0xa6037b7d; /* mtsrr1 r11 */ \ .long 0x2400004c /* rfid */ +#ifdef CONFIG_PPC_8xx +#define MFTBL(dest) mftb dest +#define MFTBU(dest) mftbu dest +#else +#define MFTBL(dest) mfspr dest, SPRN_TBRL +#define MFTBU(dest) mfspr dest, SPRN_TBRU +#endif + #endif /* _PPC64_PPC_ASM_H */ diff --git a/arch/powerpc/boot/pq2.h b/arch/powerpc/boot/pq2.h index 481698c7a51a..f577b3bec60b 100644 --- a/arch/powerpc/boot/pq2.h +++ b/arch/powerpc/boot/pq2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_PQ2_H_ #define _PPC_BOOT_PQ2_H_ diff --git a/arch/powerpc/boot/pseries-head.S b/arch/powerpc/boot/pseries-head.S index 6ef6e02e80f9..1b1a638ce6e8 100644 --- a/arch/powerpc/boot/pseries-head.S +++ b/arch/powerpc/boot/pseries-head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include "ppc_asm.h" .text diff --git a/arch/powerpc/boot/redboot.h b/arch/powerpc/boot/redboot.h index ace0b7fed8eb..8f319b1add32 100644 --- a/arch/powerpc/boot/redboot.h +++ b/arch/powerpc/boot/redboot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_REDBOOT_H #define _PPC_REDBOOT_H diff --git a/arch/powerpc/boot/rs6000.h b/arch/powerpc/boot/rs6000.h index d70517ccc0f7..a9d879155ef9 100644 --- a/arch/powerpc/boot/rs6000.h +++ b/arch/powerpc/boot/rs6000.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* IBM RS/6000 "XCOFF" file definitions for BFD. Copyright (C) 1990, 1991 Free Software Foundation, Inc. FIXME: Can someone provide a transliteration of this name into ASCII? diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c index e04c1e4063ae..7b5c02b1afd0 100644 --- a/arch/powerpc/boot/serial.c +++ b/arch/powerpc/boot/serial.c @@ -120,15 +120,19 @@ int serial_console_init(void) if (dt_is_compatible(devp, "ns16550") || dt_is_compatible(devp, "pnpPNP,501")) rc = ns16550_console_init(devp, &serial_cd); +#ifdef CONFIG_EMBEDDED6xx else if (dt_is_compatible(devp, "marvell,mv64360-mpsc")) rc = mpsc_console_init(devp, &serial_cd); +#endif else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") || dt_is_compatible(devp, "fsl,cpm1-smc-uart") || dt_is_compatible(devp, "fsl,cpm2-scc-uart") || dt_is_compatible(devp, "fsl,cpm2-smc-uart")) rc = cpm_console_init(devp, &serial_cd); +#ifdef CONFIG_PPC_MPC52XX else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart")) rc = mpc5200_psc_console_init(devp, &serial_cd); +#endif else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") || dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a")) rc = uartlite_console_init(devp, &serial_cd); diff --git a/arch/powerpc/boot/stdio.h b/arch/powerpc/boot/stdio.h index adffc58412d4..884d5959a9ae 100644 --- a/arch/powerpc/boot/stdio.h +++ b/arch/powerpc/boot/stdio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_STDIO_H_ #define _PPC_BOOT_STDIO_H_ diff --git a/arch/powerpc/boot/stdlib.h b/arch/powerpc/boot/stdlib.h index 1bf01ac73aba..0a61fcd10fdb 100644 --- a/arch/powerpc/boot/stdlib.h +++ b/arch/powerpc/boot/stdlib.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_STDLIB_H_ #define _PPC_BOOT_STDLIB_H_ diff --git a/arch/powerpc/boot/string.h b/arch/powerpc/boot/string.h index 50091cc0eed9..3fb71171da49 100644 --- a/arch/powerpc/boot/string.h +++ b/arch/powerpc/boot/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_STRING_H_ #define _PPC_BOOT_STRING_H_ #include diff --git a/arch/powerpc/boot/swab.h b/arch/powerpc/boot/swab.h index d0e1431084ca..11d2069fbb66 100644 --- a/arch/powerpc/boot/swab.h +++ b/arch/powerpc/boot/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_BOOT_SWAB_H_ #define _PPC_BOOT_SWAB_H_ diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h index af6b66b842c4..8a4c418b7260 100644 --- a/arch/powerpc/boot/types.h +++ b/arch/powerpc/boot/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TYPES_H_ #define _TYPES_H_ diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S index 243b8497d58b..ec069177d942 100644 --- a/arch/powerpc/boot/util.S +++ b/arch/powerpc/boot/util.S @@ -71,32 +71,18 @@ udelay: add r4,r4,r5 addi r4,r4,-1 divw r4,r4,r5 /* BUS ticks */ -#ifdef CONFIG_8xx -1: mftbu r5 - mftb r6 - mftbu r7 -#else -1: mfspr r5, SPRN_TBRU - mfspr r6, SPRN_TBRL - mfspr r7, SPRN_TBRU -#endif +1: MFTBU(r5) + MFTBL(r6) + MFTBU(r7) cmpw 0,r5,r7 bne 1b /* Get [synced] base time */ addc r9,r6,r4 /* Compute end time */ addze r8,r5 -#ifdef CONFIG_8xx -2: mftbu r5 -#else -2: mfspr r5, SPRN_TBRU -#endif +2: MFTBU(r5) cmpw 0,r5,r8 blt 2b bgt 3f -#ifdef CONFIG_8xx - mftb r6 -#else - mfspr r6, SPRN_TBRL -#endif + MFTBL(r6) cmpw 0,r6,r9 blt 2b 3: blr diff --git a/arch/powerpc/boot/virtex405-head.S b/arch/powerpc/boot/virtex405-head.S index 3edb13f94669..00bab7d7c48c 100644 --- a/arch/powerpc/boot/virtex405-head.S +++ b/arch/powerpc/boot/virtex405-head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include "ppc_asm.h" .text diff --git a/arch/powerpc/boot/xz_config.h b/arch/powerpc/boot/xz_config.h index 5c6afdbca642..e22e5b3770dd 100644 --- a/arch/powerpc/boot/xz_config.h +++ b/arch/powerpc/boot/xz_config.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __XZ_CONFIG_H__ #define __XZ_CONFIG_H__ diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S index de4c9e3c9344..117951295117 100644 --- a/arch/powerpc/boot/zImage.coff.lds.S +++ b/arch/powerpc/boot/zImage.coff.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ OUTPUT_ARCH(powerpc:common) ENTRY(_zimage_start_opd) EXTERN(_zimage_start_opd) diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index f080abfc2f83..4ac1e36edfe7 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #ifdef CONFIG_PPC64_BOOT_WRAPPER diff --git a/arch/powerpc/boot/zImage.ps3.lds.S b/arch/powerpc/boot/zImage.ps3.lds.S index aaa469c1e60d..7b2ff2eaa73a 100644 --- a/arch/powerpc/boot/zImage.ps3.lds.S +++ b/arch/powerpc/boot/zImage.ps3.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ OUTPUT_ARCH(powerpc:common) ENTRY(_zimage_start) EXTERN(_zimage_start) diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig index 3438ed99c088..e57344c3b0d7 100644 --- a/arch/powerpc/configs/40x/acadia_defconfig +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -64,4 +64,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/ep405_defconfig b/arch/powerpc/configs/40x/ep405_defconfig index 36c44c0b560c..0f66f8a87be8 100644 --- a/arch/powerpc/configs/40x/ep405_defconfig +++ b/arch/powerpc/configs/40x/ep405_defconfig @@ -64,4 +64,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index ad2156c6e2fc..b5cc7426c21f 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig @@ -72,4 +72,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/klondike_defconfig b/arch/powerpc/configs/40x/klondike_defconfig index 28adb782ec51..caab658d1da1 100644 --- a/arch/powerpc/configs/40x/klondike_defconfig +++ b/arch/powerpc/configs/40x/klondike_defconfig @@ -26,7 +26,6 @@ CONFIG_SCSI_SAS_ATTRS=y # CONFIG_VT is not set # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig index a00f434c4d47..e0b1489b7c7b 100644 --- a/arch/powerpc/configs/40x/makalu_defconfig +++ b/arch/powerpc/configs/40x/makalu_defconfig @@ -62,4 +62,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/obs600_defconfig b/arch/powerpc/configs/40x/obs600_defconfig index e500e6a12b3e..aac06d2ad01a 100644 --- a/arch/powerpc/configs/40x/obs600_defconfig +++ b/arch/powerpc/configs/40x/obs600_defconfig @@ -72,4 +72,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig index 65dc084a154c..a2b2770eee8f 100644 --- a/arch/powerpc/configs/40x/virtex_defconfig +++ b/arch/powerpc/configs/40x/virtex_defconfig @@ -41,9 +41,9 @@ CONFIG_NETDEVICES=y CONFIG_SERIO_XILINX_XPS_PS2=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_XILINX_HWICAP=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -74,4 +74,3 @@ CONFIG_FONT_8x16=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/40x/walnut_defconfig b/arch/powerpc/configs/40x/walnut_defconfig index 567f99bd64a3..6faa03cd661c 100644 --- a/arch/powerpc/configs/40x/walnut_defconfig +++ b/arch/powerpc/configs/40x/walnut_defconfig @@ -57,4 +57,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/akebono_defconfig b/arch/powerpc/configs/44x/akebono_defconfig index 143b2fbddb46..9fcd361607e2 100644 --- a/arch/powerpc/configs/44x/akebono_defconfig +++ b/arch/powerpc/configs/44x/akebono_defconfig @@ -123,7 +123,6 @@ CONFIG_NLS_DEFAULT="n" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y @@ -135,5 +134,4 @@ CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1_PPC=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/bamboo_defconfig b/arch/powerpc/configs/44x/bamboo_defconfig index 477d99fefd9a..6f3a6ecc81e7 100644 --- a/arch/powerpc/configs/44x/bamboo_defconfig +++ b/arch/powerpc/configs/44x/bamboo_defconfig @@ -55,4 +55,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/currituck_defconfig b/arch/powerpc/configs/44x/currituck_defconfig index 3799a26de6f4..5f1df5fe4453 100644 --- a/arch/powerpc/configs/44x/currituck_defconfig +++ b/arch/powerpc/configs/44x/currituck_defconfig @@ -81,7 +81,6 @@ CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_NLS_DEFAULT="n" CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y @@ -94,5 +93,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/ebony_defconfig b/arch/powerpc/configs/44x/ebony_defconfig index c265f54ab9e5..e2b6578993d5 100644 --- a/arch/powerpc/configs/44x/ebony_defconfig +++ b/arch/powerpc/configs/44x/ebony_defconfig @@ -59,5 +59,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig index bb6bd6d90821..f6dc23fef683 100644 --- a/arch/powerpc/configs/44x/eiger_defconfig +++ b/arch/powerpc/configs/44x/eiger_defconfig @@ -84,18 +84,14 @@ CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTS=y -CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_XTS=y -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_BLOWFISH=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/fsp2_defconfig b/arch/powerpc/configs/44x/fsp2_defconfig index e8e6a6999852..bae6b26bcfba 100644 --- a/arch/powerpc/configs/44x/fsp2_defconfig +++ b/arch/powerpc/configs/44x/fsp2_defconfig @@ -92,8 +92,10 @@ CONFIG_MMC_DEBUG=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_SDHCI_ST=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_M41T80=y +CONFIG_RESET_CONTROLLER=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y @@ -115,7 +117,6 @@ CONFIG_PRINTK_TIME=y CONFIG_MESSAGE_LOGLEVEL_DEFAULT=3 CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_CBC=y diff --git a/arch/powerpc/configs/44x/icon_defconfig b/arch/powerpc/configs/44x/icon_defconfig index 060f2edddb71..4453a4590b1a 100644 --- a/arch/powerpc/configs/44x/icon_defconfig +++ b/arch/powerpc/configs/44x/icon_defconfig @@ -47,8 +47,6 @@ CONFIG_FUSION_LOGGING=y CONFIG_NETDEVICES=y CONFIG_IBM_EMAC=y # CONFIG_WLAN is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 # CONFIG_MOUSE_PS2_ALPS is not set # CONFIG_MOUSE_PS2_LOGIPS2PP is not set # CONFIG_MOUSE_PS2_SYNAPTICS is not set @@ -94,4 +92,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/iss476-smp_defconfig b/arch/powerpc/configs/44x/iss476-smp_defconfig index 115a6b2be18b..d24bfa6ecd62 100644 --- a/arch/powerpc/configs/44x/iss476-smp_defconfig +++ b/arch/powerpc/configs/44x/iss476-smp_defconfig @@ -63,7 +63,6 @@ CONFIG_TMPFS=y CONFIG_CRAMFS=y # CONFIG_NETWORK_FILESYSTEMS is not set CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_PPC_EARLY_DEBUG=y @@ -72,5 +71,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/44x/katmai_defconfig b/arch/powerpc/configs/44x/katmai_defconfig index b999048c4ae6..5d3f685a7af8 100644 --- a/arch/powerpc/configs/44x/katmai_defconfig +++ b/arch/powerpc/configs/44x/katmai_defconfig @@ -60,4 +60,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/rainier_defconfig b/arch/powerpc/configs/44x/rainier_defconfig index b8c9ee45d0a2..7b8355a5698d 100644 --- a/arch/powerpc/configs/44x/rainier_defconfig +++ b/arch/powerpc/configs/44x/rainier_defconfig @@ -66,4 +66,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig index a4bb048448da..918cfb63f0c8 100644 --- a/arch/powerpc/configs/44x/redwood_defconfig +++ b/arch/powerpc/configs/44x/redwood_defconfig @@ -83,18 +83,14 @@ CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTS=y -CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_XTS=y -CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=y -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_BLOWFISH=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/sequoia_defconfig b/arch/powerpc/configs/44x/sequoia_defconfig index b3792fd8111d..1e04122912f3 100644 --- a/arch/powerpc/configs/44x/sequoia_defconfig +++ b/arch/powerpc/configs/44x/sequoia_defconfig @@ -67,4 +67,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/taishan_defconfig b/arch/powerpc/configs/44x/taishan_defconfig index ff6f86241418..42cc7b4ed95f 100644 --- a/arch/powerpc/configs/44x/taishan_defconfig +++ b/arch/powerpc/configs/44x/taishan_defconfig @@ -61,4 +61,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/virtex5_defconfig b/arch/powerpc/configs/44x/virtex5_defconfig index ce052064bcbb..99cc3dc02df1 100644 --- a/arch/powerpc/configs/44x/virtex5_defconfig +++ b/arch/powerpc/configs/44x/virtex5_defconfig @@ -40,9 +40,9 @@ CONFIG_NETDEVICES=y CONFIG_SERIO_XILINX_XPS_PS2=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_XILINX_HWICAP=y CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y @@ -73,4 +73,3 @@ CONFIG_FONT_8x16=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/44x/warp_defconfig b/arch/powerpc/configs/44x/warp_defconfig index ab932488e68b..b5c866073efd 100644 --- a/arch/powerpc/configs/44x/warp_defconfig +++ b/arch/powerpc/configs/44x/warp_defconfig @@ -97,4 +97,3 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig index c1faac800806..73948e88ac82 100644 --- a/arch/powerpc/configs/52xx/cm5200_defconfig +++ b/arch/powerpc/configs/52xx/cm5200_defconfig @@ -77,4 +77,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig index 9493b02ac660..6fc7f786c83c 100644 --- a/arch/powerpc/configs/52xx/lite5200b_defconfig +++ b/arch/powerpc/configs/52xx/lite5200b_defconfig @@ -14,6 +14,7 @@ CONFIG_PPC_MPC52xx=y CONFIG_PPC_MPC5200_SIMPLE=y CONFIG_PPC_LITE5200=y # CONFIG_PPC_PMAC is not set +CONFIG_GEN_RTC=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -44,7 +45,6 @@ CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -62,4 +62,3 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig index fe8126bc1655..ae2a1f74103b 100644 --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -41,16 +41,16 @@ CONFIG_ATA=y CONFIG_PATA_MPC52xx=y CONFIG_NETDEVICES=y CONFIG_FEC_MPC52xx=y -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_ICPLUS_PHY=y CONFIG_MDIO_BITBANG=y +CONFIG_BROADCOM_PHY=y +CONFIG_CICADA_PHY=y +CONFIG_DAVICOM_PHY=y +CONFIG_ICPLUS_PHY=y +CONFIG_LXT_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_QSEMI_PHY=y +CONFIG_SMSC_PHY=y +CONFIG_VITESSE_PHY=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -90,4 +90,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index b8b316b884aa..0777e6efd22d 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -48,7 +48,6 @@ CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_FEC_MPC52xx=y CONFIG_LXT_PHY=y -CONFIG_FIXED_PHY=y CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 @@ -92,4 +91,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/asp8347_defconfig b/arch/powerpc/configs/83xx/asp8347_defconfig index b60cac088a7b..dd884df32dfd 100644 --- a/arch/powerpc/configs/83xx/asp8347_defconfig +++ b/arch/powerpc/configs/83xx/asp8347_defconfig @@ -42,7 +42,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_GIANFAR=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -71,4 +70,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/kmeter1_defconfig b/arch/powerpc/configs/83xx/kmeter1_defconfig index 9547dcdd6489..d21b5cb365f2 100644 --- a/arch/powerpc/configs/83xx/kmeter1_defconfig +++ b/arch/powerpc/configs/83xx/kmeter1_defconfig @@ -55,7 +55,6 @@ CONFIG_HDLC=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig index 80aa844c1428..1f69f4edf074 100644 --- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig @@ -48,8 +48,6 @@ CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y CONFIG_CICADA_PHY=y -CONFIG_FIXED_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -87,4 +85,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig index d89d13bc6901..797fc3ffddee 100644 --- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig @@ -47,7 +47,6 @@ CONFIG_MD_RAID1=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -85,4 +84,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig index e789518a2881..4f914906ee4b 100644 --- a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig @@ -14,7 +14,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC832x_MDS=y -CONFIG_QUICC_ENGINE=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -36,7 +35,6 @@ CONFIG_SCSI=y CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_DAVICOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -50,6 +48,7 @@ CONFIG_I2C_MPC=y CONFIG_WATCHDOG=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1374=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -59,4 +58,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig index 917a49ca2bd1..a484eb8401e8 100644 --- a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig @@ -14,7 +14,7 @@ CONFIG_LDM_PARTITION=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC832x_RDB=y -CONFIG_QUICC_ENGINE=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -38,7 +38,6 @@ CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_E1000=y CONFIG_ICPLUS_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -46,7 +45,6 @@ CONFIG_ICPLUS_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -62,6 +60,7 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y CONFIG_USB_STORAGE=y CONFIG_MMC=y CONFIG_MMC_SPI=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_MSDOS_FS=y @@ -78,4 +77,3 @@ CONFIG_NLS_ISO8859_1=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig index 00f636e95cc8..37f4d93b3f81 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig @@ -49,7 +49,6 @@ CONFIG_MD_RAID1=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_CICADA_PHY=y -CONFIG_FIXED_PHY=y # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -84,4 +83,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig index a539d44d1dba..7adb6708a761 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig @@ -75,4 +75,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig index 9f0ddc830c82..d7ce3551529d 100644 --- a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig @@ -35,7 +35,6 @@ CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -58,4 +57,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig index ceed4c1f0ab5..92134cee3f37 100644 --- a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig @@ -14,7 +14,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC836x_MDS=y -CONFIG_QUICC_ENGINE=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -41,7 +40,6 @@ CONFIG_SCSI=y CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -55,6 +53,7 @@ CONFIG_I2C_MPC=y CONFIG_WATCHDOG=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1374=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -64,4 +63,3 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig index a6819bf3ef5e..97f7ea5f205f 100644 --- a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig +++ b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig @@ -12,7 +12,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC836x_RDK=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_PCI=y CONFIG_NET=y @@ -39,11 +38,9 @@ CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_QE=y @@ -63,6 +60,7 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_USB_SUPPORT is not set +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -72,4 +70,3 @@ CONFIG_NFS_FS=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_PPC_EARLY_DEBUG=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig index 4bd1992e4d98..ee7510a33d06 100644 --- a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC837x_MDS=y +CONFIG_GEN_RTC=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -35,7 +36,6 @@ CONFIG_SATA_FSL=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -43,7 +43,6 @@ CONFIG_MARVELL_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig index 2d4bb63882b8..8966a9af4230 100644 --- a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_MPC837x_RDB=y +CONFIG_GEN_RTC=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -41,9 +42,7 @@ CONFIG_MD_RAID456=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -CONFIG_FIXED_PHY=y CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -51,7 +50,6 @@ CONFIG_INPUT_FF_MEMLESS=m CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -86,4 +84,3 @@ CONFIG_CRC_T10DIF=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/83xx/sbc834x_defconfig b/arch/powerpc/configs/83xx/sbc834x_defconfig index b3380dbd1925..7d74699334da 100644 --- a/arch/powerpc/configs/83xx/sbc834x_defconfig +++ b/arch/powerpc/configs/83xx/sbc834x_defconfig @@ -11,6 +11,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_83xx=y CONFIG_SBC834x=y +CONFIG_GEN_RTC=y CONFIG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -41,7 +42,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -52,7 +52,6 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=2 CONFIG_SERIAL_8250_RUNTIME_UARTS=2 # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -72,5 +71,4 @@ CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/85xx/ge_imp3a_defconfig b/arch/powerpc/configs/85xx/ge_imp3a_defconfig index a917f7afb4f9..dd98f43b2fb8 100644 --- a/arch/powerpc/configs/85xx/ge_imp3a_defconfig +++ b/arch/powerpc/configs/85xx/ge_imp3a_defconfig @@ -22,7 +22,6 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_GE_IMP3A=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_CPM2=y CONFIG_HIGHMEM=y @@ -161,6 +160,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RX8581=y CONFIG_DMADEVICES=y CONFIG_FSL_DMA=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -233,5 +233,4 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_TALITOS=y diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig index bd814dfb0bbd..9ce6f48cfb61 100644 --- a/arch/powerpc/configs/85xx/ksi8560_defconfig +++ b/arch/powerpc/configs/85xx/ksi8560_defconfig @@ -8,6 +8,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_KSI8560=y CONFIG_CPM2=y +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y @@ -39,14 +40,12 @@ CONFIG_FS_ENET=y CONFIG_FS_ENET_MDIO_FCC=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_VT is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -57,4 +56,3 @@ CONFIG_DEBUG_FS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig index 32af10def641..5fbc3f904046 100644 --- a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig +++ b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_MPC8540_ADS=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -30,7 +31,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_GIANFAR=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -38,7 +38,6 @@ CONFIG_GIANFAR=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -47,4 +46,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig index a52b2170ee33..ff981d7905c7 100644 --- a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig +++ b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig @@ -7,6 +7,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_MPC8560_ADS=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -32,16 +33,14 @@ CONFIG_FS_ENET=y # CONFIG_FS_ENET_HAS_SCC is not set CONFIG_GIANFAR=y CONFIG_E1000=y -CONFIG_MARVELL_PHY=y CONFIG_DAVICOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_MARVELL_PHY=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_VT is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -50,4 +49,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig index 002bb48abaa3..974f0706d777 100644 --- a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig +++ b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_MPC85xx_CDS=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E1000=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -43,7 +43,6 @@ CONFIG_E1000=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -52,4 +51,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/sbc8548_defconfig b/arch/powerpc/configs/85xx/sbc8548_defconfig index 97ae02377cf3..7e3e84a842e4 100644 --- a/arch/powerpc/configs/85xx/sbc8548_defconfig +++ b/arch/powerpc/configs/85xx/sbc8548_defconfig @@ -6,6 +6,7 @@ CONFIG_EXPERT=y CONFIG_SLAB=y # CONFIG_BLK_DEV_BSG is not set CONFIG_SBC8548=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -36,7 +37,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,10 +44,8 @@ CONFIG_BROADCOM_PHY=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y # CONFIG_USB_SUPPORT is not set CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/socrates_defconfig b/arch/powerpc/configs/85xx/socrates_defconfig index 13579cb30539..6106fadbbd8b 100644 --- a/arch/powerpc/configs/85xx/socrates_defconfig +++ b/arch/powerpc/configs/85xx/socrates_defconfig @@ -42,8 +42,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=800 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -86,4 +84,3 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_FONTS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig index 384926f3ce1d..5b9cc01b9098 100644 --- a/arch/powerpc/configs/85xx/stx_gp3_defconfig +++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig @@ -39,8 +39,6 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_MARVELL_PHY=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024 CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=m # CONFIG_VT is not set @@ -68,4 +66,3 @@ CONFIG_CRC_T10DIF=m CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_BDI_SWITCH=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8540_defconfig b/arch/powerpc/configs/85xx/tqm8540_defconfig index 908f3885f4a5..98982a0e82d8 100644 --- a/arch/powerpc/configs/85xx/tqm8540_defconfig +++ b/arch/powerpc/configs/85xx/tqm8540_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8540=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,14 +36,12 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set # CONFIG_VT is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -56,4 +55,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8541_defconfig b/arch/powerpc/configs/85xx/tqm8541_defconfig index f47e57610b7c..a6e21db1dafe 100644 --- a/arch/powerpc/configs/85xx/tqm8541_defconfig +++ b/arch/powerpc/configs/85xx/tqm8541_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8541=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,7 +44,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8548_defconfig b/arch/powerpc/configs/85xx/tqm8548_defconfig index 42f5d0a7698e..2697e4e8a761 100644 --- a/arch/powerpc/configs/85xx/tqm8548_defconfig +++ b/arch/powerpc/configs/85xx/tqm8548_defconfig @@ -43,7 +43,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_NETDEVICES=y CONFIG_GIANFAR=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -66,4 +65,3 @@ CONFIG_ROOT_NFS=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8555_defconfig b/arch/powerpc/configs/85xx/tqm8555_defconfig index 71552b7929cd..ca1de3979474 100644 --- a/arch/powerpc/configs/85xx/tqm8555_defconfig +++ b/arch/powerpc/configs/85xx/tqm8555_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8555=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,7 +44,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/tqm8560_defconfig b/arch/powerpc/configs/85xx/tqm8560_defconfig index 25aac973d6d7..ca3b8c8ef30f 100644 --- a/arch/powerpc/configs/85xx/tqm8560_defconfig +++ b/arch/powerpc/configs/85xx/tqm8560_defconfig @@ -9,6 +9,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set CONFIG_TQM8560=y +CONFIG_GEN_RTC=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y CONFIG_NET=y @@ -35,7 +36,6 @@ CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y CONFIG_E100=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -44,7 +44,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y @@ -58,4 +57,3 @@ CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig index 72900b84d3e0..6531139a8a8d 100644 --- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig +++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig @@ -54,7 +54,6 @@ CONFIG_IP_PIMSM_V2=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_IPV6=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_REDBOOT_PARTS=y @@ -86,7 +85,6 @@ CONFIG_DUMMY=y CONFIG_GIANFAR=y CONFIG_E1000=y CONFIG_BROADCOM_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set CONFIG_SERIO_LIBPS2=y @@ -107,8 +105,8 @@ CONFIG_SENSORS_LM90=y CONFIG_WATCHDOG=y CONFIG_USB=y CONFIG_USB_MON=y -CONFIG_USB_ISP1760=y CONFIG_USB_STORAGE=y +CONFIG_USB_ISP1760=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_PCA955X=y @@ -143,4 +141,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig index 6a3f825452e9..935ea3ade7de 100644 --- a/arch/powerpc/configs/adder875_defconfig +++ b/arch/powerpc/configs/adder875_defconfig @@ -12,6 +12,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set CONFIG_PPC_ADDER875=y CONFIG_8xx_COPYBACK=y +CONFIG_GEN_RTC=y CONFIG_HZ_1000=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -41,7 +42,6 @@ CONFIG_DAVICOM_PHY=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set CONFIG_THERMAL=y # CONFIG_USB_SUPPORT is not set diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig index 8d3e3c41258d..12f397d403c6 100644 --- a/arch/powerpc/configs/amigaone_defconfig +++ b/arch/powerpc/configs/amigaone_defconfig @@ -45,7 +45,6 @@ CONFIG_PARPORT_PC_FIFO=y CONFIG_BLK_DEV_FD=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y @@ -120,5 +119,4 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/be.config b/arch/powerpc/configs/be.config new file mode 100644 index 000000000000..c5cdc99a6530 --- /dev/null +++ b/arch/powerpc/configs/be.config @@ -0,0 +1 @@ +CONFIG_CPU_BIG_ENDIAN=y diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig index 7c9d95370150..f1552af9eecc 100644 --- a/arch/powerpc/configs/c2k_defconfig +++ b/arch/powerpc/configs/c2k_defconfig @@ -27,6 +27,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_BINFMT_MISC=y @@ -197,7 +198,6 @@ CONFIG_TUN=m # CONFIG_ATM_DRIVERS is not set CONFIG_MV643XX_ETH=y CONFIG_VITESSE_PHY=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -209,7 +209,6 @@ CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_MPSC=y CONFIG_SERIAL_MPSC_CONSOLE=y CONFIG_NVRAM=m -CONFIG_GEN_RTC=m CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=8192 CONFIG_I2C=m @@ -390,7 +389,6 @@ CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_DISABLE=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=y @@ -402,4 +400,3 @@ CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index aa564599e368..560a93a84efe 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -4,7 +4,6 @@ CONFIG_ALTIVEC=y CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_SYSVIPC=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y @@ -34,10 +33,10 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=m CONFIG_IRQ_ALL_CPUS=y CONFIG_NUMA=y -CONFIG_MEMORY_HOTREMOVE=y CONFIG_PPC_64K_PAGES=y CONFIG_SCHED_SMT=y CONFIG_PCIEPORTBUS=y @@ -53,7 +52,6 @@ CONFIG_IP_PNP_RARP=y CONFIG_NET_IPIP=y CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_IPV6=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -141,7 +139,6 @@ CONFIG_SKY2=m CONFIG_GELIC_NET=m CONFIG_GELIC_WIRELESS=y CONFIG_SPIDER_NET=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO_I8042 is not set @@ -149,8 +146,6 @@ CONFIG_SPIDER_NET=y CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_TXX9_NR_UARTS=2 -CONFIG_SERIAL_TXX9_CONSOLE=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_HVC_RTAS=y CONFIG_IPMI_HANDLER=m @@ -159,7 +154,6 @@ CONFIG_IPMI_SI=m CONFIG_IPMI_WATCHDOG=m CONFIG_IPMI_POWEROFF=m # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_WATCHDOG=y # CONFIG_VGA_CONSOLE is not set @@ -207,7 +201,6 @@ CONFIG_NLS_ISO8859_13=m CONFIG_NLS_ISO8859_14=m CONFIG_NLS_ISO8859_15=m # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MUTEXES=y diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig index 1f6f90cd8aff..a203b1cf67d3 100644 --- a/arch/powerpc/configs/chrp32_defconfig +++ b/arch/powerpc/configs/chrp32_defconfig @@ -16,6 +16,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y # CONFIG_PPC_PMAC is not set +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_BINFMT_MISC=y CONFIG_IRQ_ALL_CPUS=y @@ -79,7 +80,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_NVRAM=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y @@ -124,5 +124,4 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig index 3403b85f9d81..2e6c8a45ae88 100644 --- a/arch/powerpc/configs/ep8248e_defconfig +++ b/arch/powerpc/configs/ep8248e_defconfig @@ -70,5 +70,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig index 95411aeeeb8d..7cb590e8f8fd 100644 --- a/arch/powerpc/configs/ep88xc_defconfig +++ b/arch/powerpc/configs/ep88xc_defconfig @@ -14,6 +14,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set CONFIG_PPC_EP88XC=y CONFIG_8xx_COPYBACK=y +CONFIG_GEN_RTC=y CONFIG_HZ_100=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -45,7 +46,6 @@ CONFIG_LXT_PHY=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set # CONFIG_DNOTIFY is not set diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index e18f2e06553f..063817fee61c 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -4,7 +4,6 @@ CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y @@ -25,6 +24,7 @@ CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_PMAC64=y +CONFIG_GEN_RTC=y CONFIG_KEXEC=y CONFIG_IRQ_ALL_CPUS=y CONFIG_PCI_MSI=y @@ -115,7 +115,6 @@ CONFIG_USB_USBNET=m # CONFIG_USB_NET_NET1080 is not set # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -123,7 +122,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_RAW_DRIVER=y CONFIG_I2C_CHARDEV=y CONFIG_AGP=m @@ -140,10 +138,11 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_POWERMAC=m CONFIG_SND_AOA=m CONFIG_SND_AOA_FABRIC_LAYOUT=m @@ -213,20 +212,20 @@ CONFIG_USB_SERIAL_CYBERJACK=m CONFIG_USB_SERIAL_XIRCOM=m CONFIG_USB_SERIAL_OMNINET=m CONFIG_USB_APPLEDISPLAY=m -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_FS=y CONFIG_REISERFS_FS=y CONFIG_REISERFS_FS_XATTR=y CONFIG_REISERFS_FS_POSIX_ACL=y CONFIG_REISERFS_FS_SECURITY=y CONFIG_XFS_FS=m CONFIG_XFS_POSIX_ACL=y +CONFIG_FS_DAX=y CONFIG_ISO9660_FS=y CONFIG_JOLIET=y CONFIG_ZISOFS=y @@ -254,14 +253,12 @@ CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_15=y CONFIG_NLS_UTF8=y CONFIG_CRC_T10DIF=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MUTEXES=y CONFIG_LATENCYTOP=y CONFIG_BOOTX_TEXT=y CONFIG_PPC_EARLY_DEBUG=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_HMAC=y @@ -276,5 +273,4 @@ CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig index c0eec4a5df4e..805b0f87653c 100644 --- a/arch/powerpc/configs/gamecube_defconfig +++ b/arch/powerpc/configs/gamecube_defconfig @@ -45,7 +45,6 @@ CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_NETDEVICES=y # CONFIG_WLAN is not set CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -54,7 +53,6 @@ CONFIG_INPUT_JOYSTICK=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set CONFIG_LEGACY_PTY_COUNT=64 -# CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set CONFIG_FB=y @@ -66,11 +64,12 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set CONFIG_SOUND=y CONFIG_SND=y -CONFIG_SND_SEQUENCER=y +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y -CONFIG_SND_SEQUENCER_OSS=y # CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQUENCER_OSS=y # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_GENERIC=y diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig index e56e80090529..71d8d2430b6c 100644 --- a/arch/powerpc/configs/holly_defconfig +++ b/arch/powerpc/configs/holly_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_EMBEDDED6xx=y CONFIG_PPC_HOLLY=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0,115200" @@ -37,7 +38,6 @@ CONFIG_NETDEVICES=y CONFIG_VORTEX=y CONFIG_TSI108_ETH=y CONFIG_PHYLIB=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -49,7 +49,6 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig index b413c19d7031..477794c41d50 100644 --- a/arch/powerpc/configs/linkstation_defconfig +++ b/arch/powerpc/configs/linkstation_defconfig @@ -26,7 +26,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m @@ -79,7 +78,6 @@ CONFIG_NET_TULIP=y CONFIG_TULIP=y CONFIG_TULIP_MMIO=y CONFIG_R8169=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -142,4 +140,3 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index c4018179e219..078cdb427fc9 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -3,7 +3,6 @@ CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y @@ -24,6 +23,7 @@ CONFIG_MAC_PARTITION=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_MAPLE=y CONFIG_UDBG_RTAS_CONSOLE=y +CONFIG_GEN_RTC=y CONFIG_KEXEC=y CONFIG_IRQ_ALL_CPUS=y CONFIG_PCI_MSI=y @@ -53,9 +53,6 @@ CONFIG_AMD8111_ETH=y CONFIG_TIGON3=y CONFIG_E1000=y CONFIG_USB_PEGASUS=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1600 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -63,7 +60,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HVC_RTAS=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_AMD8111=y @@ -100,8 +96,8 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49W=y CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y CONFIG_USB_SERIAL_TI=m CONFIG_EXT2_FS=y -CONFIG_FS_DAX=y CONFIG_EXT4_FS=y +CONFIG_FS_DAX=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_PROC_KCORE=y @@ -127,5 +123,4 @@ CONFIG_BOOTX_TEXT=y CONFIG_PPC_EARLY_DEBUG=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig index 197acaa026eb..5d5f08e5b8d9 100644 --- a/arch/powerpc/configs/mgcoge_defconfig +++ b/arch/powerpc/configs/mgcoge_defconfig @@ -46,7 +46,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y CONFIG_FS_ENET_MDIO_FCC=y -CONFIG_FIXED_PHY=y # CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set @@ -83,5 +82,4 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_BDI_SWITCH=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index 0b4854cf26cb..10be5773ad5d 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig @@ -12,6 +12,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set # CONFIG_PPC_CHRP is not set CONFIG_PPC_MPC512x=y +CONFIG_MPC512x_LPBFIFO=y CONFIG_MPC5121_ADS=y CONFIG_MPC512x_GENERIC=y CONFIG_PDM360NG=y @@ -61,25 +62,22 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_ICPLUS_PHY=y -CONFIG_REALTEK_PHY=y -CONFIG_NATIONAL_PHY=y -CONFIG_STE10XP=y -CONFIG_LSI_ET1011C_PHY=y -CONFIG_FIXED_PHY=y CONFIG_MDIO_BITBANG=y +CONFIG_BROADCOM_PHY=y +CONFIG_CICADA_PHY=y +CONFIG_DAVICOM_PHY=y +CONFIG_ICPLUS_PHY=y +CONFIG_LSI_ET1011C_PHY=y +CONFIG_LXT_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_NATIONAL_PHY=y +CONFIG_QSEMI_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_SMSC_PHY=y +CONFIG_STE10XP=y +CONFIG_VITESSE_PHY=y # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 @@ -111,10 +109,9 @@ CONFIG_RTC_DRV_M41T80=y CONFIG_RTC_DRV_MPC5121=y CONFIG_DMADEVICES=y CONFIG_MPC512X_DMA=y -CONFIG_MPC512x_LPBFIFO=y -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y +CONFIG_FS_DAX=y # CONFIG_DNOTIFY is not set CONFIG_VFAT_FS=y CONFIG_TMPFS=y @@ -126,5 +123,4 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index 88336d0df0d6..7a2b2aa37def 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -50,7 +50,6 @@ CONFIG_NETDEVICES=y CONFIG_FEC_MPC52xx=y CONFIG_AMD_PHY=y CONFIG_LXT_PHY=y -CONFIG_FIXED_PHY=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -71,12 +70,10 @@ CONFIG_SENSORS_LM87=m CONFIG_WATCHDOG=y CONFIG_MFD_SM501=m CONFIG_DRM=y -CONFIG_FB=y CONFIG_FB_FOREIGN_ENDIAN=y CONFIG_FB_RADEON=y CONFIG_FB_SM501=m # CONFIG_VGA_CONSOLE is not set -CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y @@ -130,4 +127,3 @@ CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig index d933326b4cf9..4b14c02b437c 100644 --- a/arch/powerpc/configs/mpc7448_hpc2_defconfig +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -11,6 +11,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PPC_PMAC is not set CONFIG_EMBEDDED6xx=y CONFIG_MPC7448HPC2=y +CONFIG_GEN_RTC=y CONFIG_BINFMT_MISC=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -38,7 +39,6 @@ CONFIG_8139TOO=y # CONFIG_8139TOO_PIO is not set CONFIG_TSI108_ETH=y CONFIG_PHYLIB=y -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -46,7 +46,6 @@ CONFIG_PHYLIB=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -54,4 +53,3 @@ CONFIG_TMPFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/mpc8272_ads_defconfig b/arch/powerpc/configs/mpc8272_ads_defconfig index 4cb0f617c0d6..b1e88b64536b 100644 --- a/arch/powerpc/configs/mpc8272_ads_defconfig +++ b/arch/powerpc/configs/mpc8272_ads_defconfig @@ -77,5 +77,4 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig index 6574477fd726..d1b82035d35f 100644 --- a/arch/powerpc/configs/mpc83xx_defconfig +++ b/arch/powerpc/configs/mpc83xx_defconfig @@ -21,7 +21,6 @@ CONFIG_MPC837x_MDS=y CONFIG_MPC837x_RDB=y CONFIG_SBC834x=y CONFIG_ASP834x=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_MATH_EMULATION=y CONFIG_PCI=y @@ -60,13 +59,11 @@ CONFIG_SATA_SIL=y CONFIG_NETDEVICES=y CONFIG_UCC_GETH=y CONFIG_GIANFAR=y -CONFIG_MARVELL_PHY=y CONFIG_DAVICOM_PHY=y -CONFIG_VITESSE_PHY=y CONFIG_ICPLUS_PHY=y -CONFIG_FIXED_PHY=y +CONFIG_MARVELL_PHY=y +CONFIG_VITESSE_PHY=y CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -99,6 +96,7 @@ CONFIG_USB_EHCI_FSL=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_RTC_DRV_DS1374=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_PROC_KCORE=y @@ -109,7 +107,5 @@ CONFIG_ROOT_NFS=y CONFIG_CRC_T10DIF=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_TALITOS=y diff --git a/arch/powerpc/configs/mpc866_ads_defconfig b/arch/powerpc/configs/mpc866_ads_defconfig index 998454471a48..f1f176c29fa3 100644 --- a/arch/powerpc/configs/mpc866_ads_defconfig +++ b/arch/powerpc/configs/mpc866_ads_defconfig @@ -14,6 +14,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_MPC86XADS=y CONFIG_8xx_COPYBACK=y CONFIG_8xx_CPU6=y +CONFIG_GEN_RTC=y CONFIG_HZ_1000=y CONFIG_MATH_EMULATION=y # CONFIG_SECCOMP is not set @@ -28,12 +29,10 @@ CONFIG_SYN_COOKIES=y CONFIG_BLK_DEV_LOOP=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y -CONFIG_FIXED_PHY=y # CONFIG_VT is not set # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT4_FS=y @@ -43,4 +42,3 @@ CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_CRC_CCITT=y CONFIG_CRC32_SLICEBY4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/mpc86xx_basic_defconfig b/arch/powerpc/configs/mpc86xx_basic_defconfig index 3283f0586e11..67bd1fa036ee 100644 --- a/arch/powerpc/configs/mpc86xx_basic_defconfig +++ b/arch/powerpc/configs/mpc86xx_basic_defconfig @@ -1,11 +1,11 @@ -CONFIG_HIGHMEM=y -CONFIG_KEXEC=y CONFIG_PPC_86xx=y -CONFIG_PROC_KCORE=y +CONFIG_MPC8641_HPCN=y +CONFIG_SBC8641D=y +CONFIG_MPC8610_HPCD=y CONFIG_GEF_PPC9A=y CONFIG_GEF_SBC310=y CONFIG_GEF_SBC610=y -CONFIG_MPC8610_HPCD=y -CONFIG_MPC8641_HPCN=y -CONFIG_SBC8641D=y CONFIG_MVME7100=y +CONFIG_HIGHMEM=y +CONFIG_KEXEC=y +CONFIG_PROC_KCORE=y diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig index 91f53f1bec5d..ec3fcc2bf737 100644 --- a/arch/powerpc/configs/mpc885_ads_defconfig +++ b/arch/powerpc/configs/mpc885_ads_defconfig @@ -13,6 +13,7 @@ CONFIG_EXPERT=y CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set CONFIG_8xx_COPYBACK=y +CONFIG_GEN_RTC=y CONFIG_HZ_100=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -51,7 +52,6 @@ CONFIG_DAVICOM_PHY=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set # CONFIG_DNOTIFY is not set diff --git a/arch/powerpc/configs/mvme5100_defconfig b/arch/powerpc/configs/mvme5100_defconfig index 139add95a16a..63e38c7220f1 100644 --- a/arch/powerpc/configs/mvme5100_defconfig +++ b/arch/powerpc/configs/mvme5100_defconfig @@ -35,7 +35,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_PROTO_SCTP=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m @@ -70,7 +69,6 @@ CONFIG_TUN=m # CONFIG_NET_VENDOR_3COM is not set CONFIG_E100=y # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_SERIO is not set @@ -130,4 +128,3 @@ CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index fe43ff47bd2f..6daa56f8895c 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -3,7 +3,6 @@ CONFIG_ALTIVEC=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_SYSVIPC=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y @@ -116,9 +115,10 @@ CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y -CONFIG_SND_SEQUENCER=y +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y +CONFIG_SND_SEQUENCER=y CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_USB_AUDIO=y CONFIG_SND_USB_USX2Y=y @@ -145,6 +145,7 @@ CONFIG_EDAC=y CONFIG_EDAC_PASEMI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y +CONFIG_RAS=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -167,7 +168,6 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_CRC_CCITT=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y @@ -175,7 +175,5 @@ CONFIG_DETECT_HUNG_TASK=y CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_BLOWFISH=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index fc1e7a7388b8..1aab9a62a681 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -21,6 +21,7 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_PMAC=y CONFIG_PPC601_SYNC_FIX=y +CONFIG_GEN_RTC=y CONFIG_HIGHMEM=y CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -179,10 +180,10 @@ CONFIG_PPP_ASYNC=y CONFIG_PPP_SYNC_TTY=m CONFIG_USB_USBNET=m # CONFIG_USB_NET_CDC_SUBSET is not set -CONFIG_PRISM54=m CONFIG_B43=m CONFIG_B43LEGACY=m CONFIG_P54_COMMON=m +CONFIG_PRISM54=m CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_MOUSE_PS2 is not set @@ -193,7 +194,6 @@ CONFIG_SERIAL_8250=m CONFIG_SERIAL_PMACZILOG=m CONFIG_SERIAL_PMACZILOG_TTYS=y CONFIG_NVRAM=y -CONFIG_GEN_RTC=y CONFIG_I2C_CHARDEV=m CONFIG_APM_POWER=y CONFIG_BATTERY_PMU=y @@ -201,8 +201,9 @@ CONFIG_HWMON=m CONFIG_AGP=m CONFIG_AGP_UNINORTH=m CONFIG_DRM=m -CONFIG_DRM_R128=m CONFIG_DRM_RADEON=m +CONFIG_DRM_LEGACY=y +CONFIG_DRM_R128=m CONFIG_FB=y CONFIG_FB_OF=y CONFIG_FB_CONTROL=y @@ -226,11 +227,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_DUMMY=m CONFIG_SND_POWERMAC=m CONFIG_SND_AOA=m @@ -300,8 +302,6 @@ CONFIG_NFSD_V4=y CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_ISO8859_1=m CONFIG_CRC_T10DIF=y -CONFIG_LIBCRC32C=m -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y @@ -310,7 +310,6 @@ CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_BOOTX_TEXT=y CONFIG_PPC_EARLY_DEBUG=y -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_SHA512=m @@ -325,4 +324,3 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig index 34fc9bbfca9e..caee834760d2 100644 --- a/arch/powerpc/configs/powernv_defconfig +++ b/arch/powerpc/configs/powernv_defconfig @@ -1,10 +1,8 @@ CONFIG_PPC64=y -CONFIG_SMP=y CONFIG_NR_CPUS=2048 CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_AUDIT=y CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_NO_HZ=y @@ -26,8 +24,8 @@ CONFIG_CGROUP_FREEZER=y CONFIG_CPUSETS=y CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_BPF=y CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_BPF_SYSCALL=y @@ -62,7 +60,6 @@ CONFIG_PPC_64K_PAGES=y CONFIG_PPC_SUBPAGE_PROT=y CONFIG_SCHED_SMT=y CONFIG_PM=y -CONFIG_PCI_MSI=y CONFIG_HOTPLUG_PCI=y CONFIG_NET=y CONFIG_PACKET=y @@ -158,7 +155,6 @@ CONFIG_NETCONSOLE=y CONFIG_TUN=m CONFIG_VETH=m CONFIG_VIRTIO_NET=m -CONFIG_VHOST_NET=m CONFIG_VORTEX=m CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -184,16 +180,13 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y # CONFIG_SERIO_SERPORT is not set -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_JSM=m CONFIG_VIRTIO_CONSOLE=m -CONFIG_POWERNV_OP_PANEL=m CONFIG_IPMI_HANDLER=y CONFIG_IPMI_DEVICE_INTERFACE=y CONFIG_IPMI_POWERNV=y @@ -296,9 +289,12 @@ CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_LATENCYTOP=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_SCHED_TRACER=y +CONFIG_FTRACE_SYSCALLS=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_UPROBE_EVENT=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y @@ -310,6 +306,7 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_CRC32C_VPMSUM=m CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m @@ -318,14 +315,13 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_DEV_NX=y CONFIG_CRYPTO_DEV_VMX=y -CONFIG_CRYPTO_DEV_VMX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=m +CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig index 370c0bbcff71..10fb1df63b46 100644 --- a/arch/powerpc/configs/ppc40x_defconfig +++ b/arch/powerpc/configs/ppc40x_defconfig @@ -51,9 +51,9 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_XILINX_HWICAP=m CONFIG_I2C=m @@ -85,4 +85,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index 2766e8f590bc..66dd6bf45cde 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig @@ -68,9 +68,9 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_PCI is not set CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=y CONFIG_SERIAL_UARTLITE_CONSOLE=y -CONFIG_SERIAL_OF_PLATFORM=y # CONFIG_HW_RANDOM is not set CONFIG_XILINX_HWICAP=m CONFIG_I2C=m @@ -94,7 +94,6 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_UBIFS_FS=m -CONFIG_LOGFS=m CONFIG_CRAMFS=y CONFIG_SQUASHFS=m CONFIG_SQUASHFS_XATTR=y @@ -108,6 +107,5 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set CONFIG_VIRTUALIZATION=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index c5246d29f385..6ddca80c52c3 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -1,8 +1,6 @@ CONFIG_PPC64=y -CONFIG_SMP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -28,9 +26,10 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y CONFIG_PPC_SPLPAR=y +CONFIG_DTL=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y -CONFIG_DTL=y +CONFIG_IBMEBUS=y CONFIG_PPC_MAPLE=y CONFIG_PPC_PASEMI=y CONFIG_PPC_PASEMI_IOMMU=y @@ -41,9 +40,8 @@ CONFIG_PS3_FLASH=m CONFIG_PS3_LPM=m CONFIG_PPC_IBM_CELL_BLADE=y CONFIG_RTAS_FLASH=m -CONFIG_IBMEBUS=y -CONFIG_CPU_FREQ_PMAC64=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_PMAC64=y CONFIG_HZ_100=y CONFIG_BINFMT_MISC=m CONFIG_PPC_TRANSACTIONAL_MEM=y @@ -51,14 +49,15 @@ CONFIG_KEXEC=y CONFIG_KEXEC_FILE=y CONFIG_CRASH_DUMP=y CONFIG_IRQ_ALL_CPUS=y -CONFIG_MEMORY_HOTREMOVE=y CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_PPC_64K_PAGES=y CONFIG_SCHED_SMT=y -CONFIG_PCCARD=y -CONFIG_ELECTRA_CF=y CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA_DLPAR=m +CONFIG_PCCARD=y +CONFIG_ELECTRA_CF=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -154,7 +153,6 @@ CONFIG_DUMMY=m CONFIG_NETCONSOLE=y CONFIG_TUN=m CONFIG_VIRTIO_NET=m -CONFIG_VHOST_NET=m CONFIG_VORTEX=m CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -181,15 +179,14 @@ CONFIG_SUNGEM=y CONFIG_GELIC_NET=m CONFIG_GELIC_WIRELESS=y CONFIG_SPIDER_NET=m -CONFIG_MARVELL_PHY=y CONFIG_BROADCOM_PHY=m +CONFIG_MARVELL_PHY=y CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m @@ -197,7 +194,6 @@ CONFIG_INPUT_PCSPKR=m CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_ICOM=m -CONFIG_SERIAL_TXX9_CONSOLE=y CONFIG_SERIAL_JSM=m CONFIG_HVC_CONSOLE=y CONFIG_HVC_RTAS=y @@ -226,11 +222,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_POWERMAC=m CONFIG_SND_AOA=m CONFIG_SND_AOA_FABRIC_LAYOUT=m @@ -250,6 +247,9 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=m CONFIG_USB_APPLEDISPLAY=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_POWERNV=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m @@ -267,7 +267,7 @@ CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_BALLOON=m -CONFIG_FS_DAX=y +CONFIG_RAS=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -287,6 +287,7 @@ CONFIG_XFS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_NILFS2_FS=m +CONFIG_FS_DAX=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m CONFIG_OVERLAY_FS=m @@ -328,9 +329,11 @@ CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_DEBUG_MUTEXES=y CONFIG_LATENCYTOP=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_UPROBE_EVENT=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y @@ -343,6 +346,7 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_CRC32C_VPMSUM=m CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m @@ -351,19 +355,14 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_NX=y CONFIG_CRYPTO_DEV_NX_ENCRYPT=m CONFIG_CRYPTO_DEV_VMX=y -CONFIG_CRYPTO_DEV_VMX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m -CONFIG_LEDS_POWERNV=m +CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 6340e6c53c54..41d85cb3c9a2 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -3,7 +3,6 @@ CONFIG_PPC_BOOK3E_64=y CONFIG_SMP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_TASKSTATS=y @@ -30,8 +29,8 @@ CONFIG_BINFMT_MISC=m CONFIG_IRQ_ALL_CPUS=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_PCI_MSI=y -CONFIG_PCCARD=y CONFIG_HOTPLUG_PCI=y +CONFIG_PCCARD=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -108,15 +107,14 @@ CONFIG_E100=y CONFIG_E1000=y CONFIG_IXGB=m CONFIG_SUNGEM=y -CONFIG_MARVELL_PHY=y CONFIG_BROADCOM_PHY=m +CONFIG_MARVELL_PHY=y CONFIG_PPP=m CONFIG_PPP_BSDCOMP=m CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y # CONFIG_SERIO_SERPORT is not set @@ -143,11 +141,12 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_HID_DRAGONRISE=y CONFIG_HID_GYRATION=y CONFIG_HID_TWINHAN=y @@ -172,10 +171,8 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_ISER=m -CONFIG_EDAC=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -192,6 +189,7 @@ CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_SECURITY=y CONFIG_XFS_FS=m CONFIG_XFS_POSIX_ACL=y +CONFIG_FS_DAX=y CONFIG_AUTOFS4_FS=m CONFIG_ISO9660_FS=y CONFIG_UDF_FS=m @@ -251,5 +249,4 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 18d0d60dadbf..da0e8d535eb8 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -11,10 +11,10 @@ CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y CONFIG_CGROUPS=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y # CONFIG_COMPAT_BRK is not set @@ -61,7 +61,7 @@ CONFIG_SBC8641D=y CONFIG_MPC8610_HPCD=y CONFIG_GEF_SBC610=y CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=m @@ -70,7 +70,6 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m CONFIG_CPU_FREQ_PMAC=y CONFIG_TAU=y CONFIG_TAU_AVERAGE=y -CONFIG_QUICC_ENGINE=y CONFIG_QE_GPIO=y CONFIG_MCU_MPC8349EMITX=y CONFIG_HIGHMEM=y @@ -141,7 +140,6 @@ CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_UDPLITE=m CONFIG_NF_CONNTRACK_AMANDA=m CONFIG_NF_CONNTRACK_FTP=m CONFIG_NF_CONNTRACK_H323=m @@ -187,7 +185,6 @@ CONFIG_NETFILTER_XT_MATCH_QUOTA=m CONFIG_NETFILTER_XT_MATCH_RATEEST=m CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SOCKET=m CONFIG_NETFILTER_XT_MATCH_STATE=m CONFIG_NETFILTER_XT_MATCH_STATISTIC=m CONFIG_NETFILTER_XT_MATCH_STRING=m @@ -195,7 +192,6 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_TIME=m CONFIG_NETFILTER_XT_MATCH_U32=m CONFIG_NF_CONNTRACK_IPV4=m -# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_ECN=m @@ -334,9 +330,7 @@ CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_BNEP_PROTO_FILTER=y CONFIG_BT_HIDP=m CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m @@ -370,7 +364,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_CDROM_PKTCDVD=m CONFIG_VIRTIO_BLK=m -CONFIG_BLK_DEV_HD=y CONFIG_ENCLOSURE_SERVICES=m CONFIG_SENSORS_TSL2550=m CONFIG_EEPROM_AT24=m @@ -548,16 +541,16 @@ CONFIG_PCMCIA_XIRC2PS=m CONFIG_FDDI=y CONFIG_SKFP=m CONFIG_NET_SB1000=m -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -CONFIG_VITESSE_PHY=m -CONFIG_SMSC_PHY=m CONFIG_BROADCOM_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_DAVICOM_PHY=m CONFIG_ICPLUS_PHY=m +CONFIG_LXT_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_QSEMI_PHY=m CONFIG_REALTEK_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_VITESSE_PHY=m CONFIG_PLIP=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_FILTER=y @@ -585,7 +578,6 @@ CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=y CONFIG_MOUSE_SERIAL=m @@ -647,7 +639,6 @@ CONFIG_SYNCLINKMP=m CONFIG_SYNCLINK_GT=m CONFIG_NOZOMI=m CONFIG_N_HDLC=m -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m @@ -657,13 +648,13 @@ CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_UARTLITE=m CONFIG_SERIAL_PMACZILOG=m CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 CONFIG_SERIAL_JSM=m -CONFIG_SERIAL_OF_PLATFORM=y CONFIG_PRINTER=m CONFIG_LP_CONSOLE=y CONFIG_PPDEV=m @@ -748,9 +739,10 @@ CONFIG_MFD_SM501_GPIO=y CONFIG_AGP=y CONFIG_AGP_UNINORTH=y CONFIG_DRM=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_LEGACY=y CONFIG_DRM_TDFX=m CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m CONFIG_DRM_MGA=m CONFIG_DRM_SIS=m CONFIG_DRM_VIA=m @@ -797,17 +789,18 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_SUPPORT_OLD_API is not set CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_DEBUG=y CONFIG_SND_DEBUG_VERBOSE=y CONFIG_SND_PCM_XRUN_DEBUG=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m CONFIG_SND_DUMMY=m CONFIG_SND_VIRMIDI=m CONFIG_SND_MTPAV=m @@ -899,7 +892,7 @@ CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=m -CONFIG_USB_EHCI_FSL=y +CONFIG_USB_EHCI_FSL=m CONFIG_USB_OHCI_HCD=m CONFIG_USB_OHCI_HCD_PPC_OF_BE=y CONFIG_USB_OHCI_HCD_PPC_OF_LE=y @@ -967,7 +960,6 @@ CONFIG_USB_ADUTUX=m CONFIG_USB_SEVSEG=m CONFIG_USB_LEGOTOWER=m CONFIG_USB_LCD=m -CONFIG_USB_LED=m CONFIG_USB_IDMOUSE=m CONFIG_USB_FTDI_ELAN=m CONFIG_USB_APPLEDISPLAY=m @@ -1020,15 +1012,14 @@ CONFIG_UIO_CIF=m CONFIG_UIO_PDRV_GENIRQ=m CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_BALLOON=m -CONFIG_FS_DAX=y +CONFIG_QUICC_ENGINE=y CONFIG_EXT2_FS=m CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT4_FS=m +CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXT4_FS=y CONFIG_JBD2_DEBUG=y CONFIG_REISERFS_FS=m CONFIG_REISERFS_PROC_INFO=y @@ -1042,6 +1033,7 @@ CONFIG_XFS_FS=m CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_GFS2_FS=m +CONFIG_FS_DAX=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m @@ -1146,7 +1138,6 @@ CONFIG_DEBUG_VM=y CONFIG_DEBUG_HIGHMEM=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_SHIRQ=y -CONFIG_TIMER_STATS=y CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y @@ -1173,7 +1164,6 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m @@ -1201,7 +1191,6 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_HIFN_795X=m CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y CONFIG_CRYPTO_DEV_TALITOS=m diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig index 50b2bad51d0a..0ededa8c837d 100644 --- a/arch/powerpc/configs/pq2fads_defconfig +++ b/arch/powerpc/configs/pq2fads_defconfig @@ -79,4 +79,3 @@ CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index ee0ec5a682fc..2efa025bf483 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -5,7 +5,6 @@ CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -94,7 +93,6 @@ CONFIG_USB_USBNET=m # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_JOYDEV=m CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_KEYBOARD is not set @@ -161,7 +159,6 @@ CONFIG_NLS_ISO8859_1=y CONFIG_CRC_CCITT=m CONFIG_CRC_T10DIF=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_STACKOVERFLOW=y diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index fd5d98a0b95c..3d935969e5a2 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -1,11 +1,8 @@ CONFIG_PPC64=y -CONFIG_SMP=y CONFIG_NR_CPUS=2048 CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y CONFIG_IRQ_DOMAIN_DEBUG=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -18,17 +15,16 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 CONFIG_NUMA_BALANCING=y -CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y CONFIG_CGROUPS=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CPUSETS=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_BPF=y CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y -CONFIG_CGROUP_PERF=y CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y CONFIG_USER_NS=y CONFIG_BLK_DEV_INITRD=y CONFIG_BPF_SYSCALL=y @@ -43,12 +39,12 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_PARTITION_ADVANCED=y CONFIG_PPC_SPLPAR=y +CONFIG_DTL=y CONFIG_SCANLOG=m CONFIG_PPC_SMLPAR=y -CONFIG_DTL=y +CONFIG_IBMEBUS=y # CONFIG_PPC_PMAC is not set CONFIG_RTAS_FLASH=m -CONFIG_IBMEBUS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_HZ_100=y CONFIG_BINFMT_MISC=m @@ -155,7 +151,6 @@ CONFIG_NETCONSOLE=y CONFIG_TUN=m CONFIG_VETH=m CONFIG_VIRTIO_NET=m -CONFIG_VHOST_NET=m CONFIG_VORTEX=m CONFIG_ACENIC=m CONFIG_ACENIC_OMIT_TIGON_I=y @@ -183,12 +178,10 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPPOE=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=m CONFIG_INPUT_MISC=y CONFIG_INPUT_PCSPKR=m # CONFIG_SERIO_SERPORT is not set -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_ICOM=m @@ -198,8 +191,6 @@ CONFIG_HVC_RTAS=y CONFIG_HVCS=m CONFIG_VIRTIO_CONSOLE=m CONFIG_IBM_BSR=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_GENERIC=y CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=1024 CONFIG_FB=y @@ -227,6 +218,9 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_HCD_PPC_OF is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_POWERNV=m CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m @@ -238,9 +232,10 @@ CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_CM=y CONFIG_INFINIBAND_SRP=m CONFIG_INFINIBAND_ISER=m +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=y CONFIG_VIRTIO_PCI=m CONFIG_VIRTIO_BALLOON=m -CONFIG_FS_DAX=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -256,6 +251,7 @@ CONFIG_XFS_POSIX_ACL=y CONFIG_BTRFS_FS=m CONFIG_BTRFS_FS_POSIX_ACL=y CONFIG_NILFS2_FS=m +CONFIG_FS_DAX=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m CONFIG_OVERLAY_FS=m @@ -294,9 +290,11 @@ CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_LATENCYTOP=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y -CONFIG_UPROBE_EVENT=y CONFIG_CODE_PATCHING_SELFTEST=y CONFIG_FTR_FIXUP_SELFTEST=y CONFIG_MSI_BITMAP_SELFTEST=y @@ -307,6 +305,7 @@ CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_CRC32C_VPMSUM=m CONFIG_CRYPTO_MD5_PPC=m CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m @@ -315,19 +314,14 @@ CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_KHAZAD=m CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SHA1_PPC=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_NX=y CONFIG_CRYPTO_DEV_NX_ENCRYPT=m CONFIG_CRYPTO_DEV_VMX=y -CONFIG_CRYPTO_DEV_VMX_ENCRYPT=m CONFIG_VIRTUALIZATION=y CONFIG_KVM_BOOK3S_64=m CONFIG_KVM_BOOK3S_64_HV=m -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=m -CONFIG_LEDS_POWERNV=m +CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/tqm8xx_defconfig b/arch/powerpc/configs/tqm8xx_defconfig index 78fddf24b5d3..cd72193fac0a 100644 --- a/arch/powerpc/configs/tqm8xx_defconfig +++ b/arch/powerpc/configs/tqm8xx_defconfig @@ -18,6 +18,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_TQM8XX=y CONFIG_8xx_COPYBACK=y # CONFIG_8xx_CPU15 is not set +CONFIG_GEN_RTC=y CONFIG_HZ_100=y # CONFIG_SECCOMP is not set CONFIG_NET=y @@ -44,7 +45,6 @@ CONFIG_MTD_PHYSMAP_OF=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y CONFIG_DAVICOM_PHY=y -CONFIG_FIXED_PHY=y # CONFIG_WLAN is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set @@ -53,7 +53,6 @@ CONFIG_FIXED_PHY=y CONFIG_SERIAL_CPM=y CONFIG_SERIAL_CPM_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_GEN_RTC=y # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set # CONFIG_DNOTIFY is not set diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig index dcdd51b57783..9c7400a19e9d 100644 --- a/arch/powerpc/configs/wii_defconfig +++ b/arch/powerpc/configs/wii_defconfig @@ -55,9 +55,6 @@ CONFIG_B43_SDIO=y # CONFIG_B43_PHY_LP is not set CONFIG_B43_DEBUG=y CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=640 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480 CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -68,7 +65,6 @@ CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set CONFIG_LEGACY_PTY_COUNT=64 -# CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set CONFIG_NVRAM=y CONFIG_I2C=y @@ -83,11 +79,12 @@ CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_SOUND=y CONFIG_SND=y -CONFIG_SND_SEQUENCER=y +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y -CONFIG_SND_SEQUENCER_OSS=y # CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQUENCER_OSS=y CONFIG_HID_APPLE=m CONFIG_HID_WACOM=m CONFIG_MMC=y @@ -119,5 +116,4 @@ CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_DMA_API_DEBUG=y CONFIG_PPC_EARLY_DEBUG=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile index 67eca3af9fc7..4808d97fede5 100644 --- a/arch/powerpc/crypto/Makefile +++ b/arch/powerpc/crypto/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # powerpc/crypto/Makefile # diff --git a/arch/powerpc/crypto/sha1-powerpc-asm.S b/arch/powerpc/crypto/sha1-powerpc-asm.S index 82ddc9bdfeb1..c8951ce0dcc4 100644 --- a/arch/powerpc/crypto/sha1-powerpc-asm.S +++ b/arch/powerpc/crypto/sha1-powerpc-asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * SHA-1 implementation for PowerPC. * diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index 5c4fbc80dc6c..2542ea15d338 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -8,3 +8,4 @@ generic-y += mcs_spinlock.h generic-y += preempt.h generic-y += rwsem.h generic-y += vtime.h +generic-y += msi.h diff --git a/arch/powerpc/include/asm/agp.h b/arch/powerpc/include/asm/agp.h index 416e12c2d505..b29b1186f819 100644 --- a/arch/powerpc/include/asm/agp.h +++ b/arch/powerpc/include/asm/agp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_AGP_H #define _ASM_POWERPC_AGP_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h index 85e88f7a59c0..9c63b596e6ce 100644 --- a/arch/powerpc/include/asm/archrandom.h +++ b/arch/powerpc/include/asm/archrandom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_ARCHRANDOM_H #define _ASM_POWERPC_ARCHRANDOM_H diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index cee3aa087653..7f2a7702596c 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -25,7 +25,7 @@ #define PPC_LCMPI stringify_in_c(cmpdi) #define PPC_LCMPLI stringify_in_c(cmpldi) #define PPC_LCMP stringify_in_c(cmpd) -#define PPC_LONG stringify_in_c(.llong) +#define PPC_LONG stringify_in_c(.8byte) #define PPC_LONG_ALIGN stringify_in_c(.balign 8) #define PPC_TLNEI stringify_in_c(tdnei) #define PPC_LLARX(t, a, b, eh) PPC_LDARX(t, a, b, eh) diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index a2cc8010cd72..682b3e6a1e21 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_ATOMIC_H_ #define _ASM_POWERPC_ATOMIC_H_ diff --git a/arch/powerpc/include/asm/backlight.h b/arch/powerpc/include/asm/backlight.h index 8cf5c37c3817..1b5eab62ed04 100644 --- a/arch/powerpc/include/asm/backlight.h +++ b/arch/powerpc/include/asm/backlight.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Routines for handling backlight control on PowerBooks * diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h index 25d42bd3f114..10daa1d56e0a 100644 --- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999 Cort Dougan */ @@ -74,13 +75,6 @@ do { \ ___p1; \ }) -/* - * This must resolve to hwsync on SMP for the context switch path. - * See _switch, and core scheduler context switch memory ordering - * comments. - */ -#define smp_mb__before_spinlock() smp_mb() - #include #endif /* _ASM_POWERPC_BARRIER_H */ diff --git a/arch/powerpc/include/asm/book3s/32/hash.h b/arch/powerpc/include/asm/book3s/32/hash.h index 880db13a2e9f..f2892c7ab73e 100644 --- a/arch/powerpc/include/asm/book3s/32/hash.h +++ b/arch/powerpc/include/asm/book3s/32/hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_32_HASH_H #define _ASM_POWERPC_BOOK3S_32_HASH_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/book3s/32/mmu-hash.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h index b82e063494dd..e38c91388c40 100644 --- a/arch/powerpc/include/asm/book3s/32/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/32/mmu-hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_32_MMU_HASH_H_ #define _ASM_POWERPC_BOOK3S_32_MMU_HASH_H_ /* diff --git a/arch/powerpc/include/asm/book3s/32/pgalloc.h b/arch/powerpc/include/asm/book3s/32/pgalloc.h index a120e7f8d535..5073cc75f1c8 100644 --- a/arch/powerpc/include/asm/book3s/32/pgalloc.h +++ b/arch/powerpc/include/asm/book3s/32/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_32_PGALLOC_H #define _ASM_POWERPC_BOOK3S_32_PGALLOC_H diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h index 7fb755880409..016579ef16d3 100644 --- a/arch/powerpc/include/asm/book3s/32/pgtable.h +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_32_PGTABLE_H #define _ASM_POWERPC_BOOK3S_32_PGTABLE_H @@ -294,13 +295,11 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm, #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 }) -extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, - pmd_t **pmdp); - int map_kernel_page(unsigned long va, phys_addr_t pa, int flags); /* Generic accessors to PTE bits */ static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} +static inline int pte_read(pte_t pte) { return 1; } static inline int pte_dirty(pte_t pte) { return !!(pte_val(pte) & _PAGE_DIRTY); } static inline int pte_young(pte_t pte) { return !!(pte_val(pte) & _PAGE_ACCESSED); } static inline int pte_special(pte_t pte) { return !!(pte_val(pte) & _PAGE_SPECIAL); } diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index 0c4e470571ca..197ced1eaaa0 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_HASH_4K_H #define _ASM_POWERPC_BOOK3S_64_HASH_4K_H /* diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 9732837aaae8..8d40cf03cb67 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H #define _ASM_POWERPC_BOOK3S_64_HASH_64K_H diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 36fc7bfe9e11..ecb1239d74f4 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_HASH_H #define _ASM_POWERPC_BOOK3S_64_HASH_H #ifdef __KERNEL__ @@ -40,7 +41,7 @@ * Define the address range of the kernel non-linear virtual area */ #define H_KERN_VIRT_START ASM_CONST(0xD000000000000000) -#define H_KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) +#define H_KERN_VIRT_SIZE ASM_CONST(0x0000400000000000) /* 64T */ /* * The vmalloc space starts at the beginning of that region, and @@ -48,9 +49,11 @@ * (we keep a quarter for the virtual memmap) */ #define H_VMALLOC_START H_KERN_VIRT_START -#define H_VMALLOC_SIZE (H_KERN_VIRT_SIZE >> 1) +#define H_VMALLOC_SIZE ASM_CONST(0x380000000000) /* 56T */ #define H_VMALLOC_END (H_VMALLOC_START + H_VMALLOC_SIZE) +#define H_KERN_IO_START H_VMALLOC_END + /* * Region IDs */ diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h index 5c28bd6f2ae1..c459f937d484 100644 --- a/arch/powerpc/include/asm/book3s/64/hugetlb.h +++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_HUGETLB_H #define _ASM_POWERPC_BOOK3S_64_HUGETLB_H /* @@ -54,9 +55,7 @@ static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma, #ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE static inline bool gigantic_page_supported(void) { - if (radix_enabled()) - return true; - return false; + return true; } #endif diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h index 6981a52b3887..508275bb05d5 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -104,6 +104,7 @@ #define HPTE_R_C ASM_CONST(0x0000000000000080) #define HPTE_R_R ASM_CONST(0x0000000000000100) #define HPTE_R_KEY_LO ASM_CONST(0x0000000000000e00) +#define HPTE_R_KEY (HPTE_R_KEY_LO | HPTE_R_KEY_HI) #define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000) #define HPTE_V_VRMA_MASK ASM_CONST(0x4001ffffff000000) @@ -468,7 +469,7 @@ extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, int psize, int ssize); int htab_remove_mapping(unsigned long vstart, unsigned long vend, int psize, int ssize); -extern void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages); +extern void pseries_add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages); extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr); #ifdef CONFIG_PPC_PSERIES diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 5b4023c616f7..37fdede5a24c 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_MMU_H_ #define _ASM_POWERPC_BOOK3S_64_MMU_H_ @@ -83,6 +84,9 @@ typedef struct { mm_context_id_t id; u16 user_psize; /* page size index */ + /* Number of bits in the mm_cpumask */ + atomic_t active_cpus; + /* NPU NMMU context */ struct npu_context *npu_context; @@ -97,11 +101,6 @@ typedef struct { #ifdef CONFIG_PPC_SUBPAGE_PROT struct subpage_prot_table spt; #endif /* CONFIG_PPC_SUBPAGE_PROT */ -#ifdef CONFIG_PPC_ICSWX - struct spinlock *cop_lockp; /* guard acop and cop_pid */ - unsigned long acop; /* mask of enabled coprocessor types */ - unsigned int cop_pid; /* pid value used with coprocessors */ -#endif /* CONFIG_PPC_ICSWX */ #ifdef CONFIG_PPC_64K_PAGES /* for 4K PTE fragment support */ void *pte_frag; diff --git a/arch/powerpc/include/asm/book3s/64/pgalloc.h b/arch/powerpc/include/asm/book3s/64/pgalloc.h index e2329db9d6f4..1fcfa425cefa 100644 --- a/arch/powerpc/include/asm/book3s/64/pgalloc.h +++ b/arch/powerpc/include/asm/book3s/64/pgalloc.h @@ -41,8 +41,6 @@ extern struct kmem_cache *pgtable_cache[]; pgtable_cache[(shift) - 1]; \ }) -#define PGALLOC_GFP GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO - extern pte_t *pte_fragment_alloc(struct mm_struct *, unsigned long, int); extern void pte_fragment_free(unsigned long *, int); extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift); diff --git a/arch/powerpc/include/asm/book3s/64/pgtable-4k.h b/arch/powerpc/include/asm/book3s/64/pgtable-4k.h index 8708a0239a56..af5f2baac80f 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable-4k.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable-4k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_PGTABLE_4K_H #define _ASM_POWERPC_BOOK3S_64_PGTABLE_4K_H /* diff --git a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h index 2ce4209399ed..fb4b3ba52339 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable-64k.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable-64k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_PGTABLE_64K_H #define _ASM_POWERPC_BOOK3S_64_PGTABLE_64K_H diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 818a58fc3f4f..9a677cd5997f 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ #define _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ @@ -272,8 +273,10 @@ extern unsigned long __vmalloc_end; extern unsigned long __kernel_virt_start; extern unsigned long __kernel_virt_size; +extern unsigned long __kernel_io_start; #define KERN_VIRT_START __kernel_virt_start #define KERN_VIRT_SIZE __kernel_virt_size +#define KERN_IO_START __kernel_io_start extern struct page *vmemmap; extern unsigned long ioremap_bot; extern unsigned long pci_io_base; @@ -298,7 +301,6 @@ extern unsigned long pci_io_base; * PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE */ -#define KERN_IO_START (KERN_VIRT_START + (KERN_VIRT_SIZE >> 1)) #define FULL_IO_SIZE 0x80000000ul #define ISA_IO_BASE (KERN_IO_START) #define ISA_IO_END (KERN_IO_START + 0x10000ul) @@ -409,6 +411,11 @@ static inline int pte_write(pte_t pte) return __pte_write(pte) || pte_savedwrite(pte); } +static inline int pte_read(pte_t pte) +{ + return !!(pte_raw(pte) & cpu_to_be64(_PAGE_READ)); +} + #define __HAVE_ARCH_PTEP_SET_WRPROTECT static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -1167,6 +1174,7 @@ static inline bool arch_needs_pgtable_deposit(void) return false; return true; } +extern void serialize_against_pte_lookup(struct mm_struct *mm); static inline pmd_t pmd_mkdevmap(pmd_t pmd) diff --git a/arch/powerpc/include/asm/book3s/64/radix-4k.h b/arch/powerpc/include/asm/book3s/64/radix-4k.h index 7c3b1fe1619e..a61aa9cd63ec 100644 --- a/arch/powerpc/include/asm/book3s/64/radix-4k.h +++ b/arch/powerpc/include/asm/book3s/64/radix-4k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGTABLE_RADIX_4K_H #define _ASM_POWERPC_PGTABLE_RADIX_4K_H diff --git a/arch/powerpc/include/asm/book3s/64/radix-64k.h b/arch/powerpc/include/asm/book3s/64/radix-64k.h index 82dc355f0b45..c7e71ba29555 100644 --- a/arch/powerpc/include/asm/book3s/64/radix-64k.h +++ b/arch/powerpc/include/asm/book3s/64/radix-64k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGTABLE_RADIX_64K_H #define _ASM_POWERPC_PGTABLE_RADIX_64K_H diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index 544440b5aff3..19c44e1495ae 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGTABLE_RADIX_H #define _ASM_POWERPC_PGTABLE_RADIX_H @@ -110,6 +111,8 @@ */ #define RADIX_VMEMMAP_BASE (RADIX_VMALLOC_END) +#define RADIX_KERN_IO_START (RADIX_KERN_VIRT_START + (RADIX_KERN_VIRT_SIZE >> 1)) + #ifndef __ASSEMBLY__ #define RADIX_PTE_TABLE_SIZE (sizeof(pte_t) << RADIX_PTE_INDEX_SIZE) #define RADIX_PMD_TABLE_SIZE (sizeof(pmd_t) << RADIX_PMD_INDEX_SIZE) diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h index 2f6373144e2c..42178897a050 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H #define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h index cc7fbde4f53c..c2115dfcef0c 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-radix.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_TLBFLUSH_RADIX_H #define _ASM_POWERPC_TLBFLUSH_RADIX_H @@ -22,22 +23,21 @@ extern void radix__flush_tlb_kernel_range(unsigned long start, unsigned long end extern void radix__local_flush_tlb_mm(struct mm_struct *mm); extern void radix__local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); -extern void radix__local_flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); extern void radix__local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize); extern void radix__tlb_flush(struct mmu_gather *tlb); #ifdef CONFIG_SMP extern void radix__flush_tlb_mm(struct mm_struct *mm); extern void radix__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); -extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); extern void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize); #else #define radix__flush_tlb_mm(mm) radix__local_flush_tlb_mm(mm) #define radix__flush_tlb_page(vma,addr) radix__local_flush_tlb_page(vma,addr) #define radix__flush_tlb_page_psize(mm,addr,p) radix__local_flush_tlb_page_psize(mm,addr,p) -#define radix__flush_tlb_pwc(tlb, addr) radix__local_flush_tlb_pwc(tlb, addr) #endif +extern void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr); +extern void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr); extern void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa, unsigned long page_size); extern void radix__flush_tlb_lpid(unsigned long lpid); diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush.h b/arch/powerpc/include/asm/book3s/64/tlbflush.h index 72b925f97bab..fcffddbb3102 100644 --- a/arch/powerpc/include/asm/book3s/64/tlbflush.h +++ b/arch/powerpc/include/asm/book3s/64/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H #define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_H diff --git a/arch/powerpc/include/asm/book3s/pgalloc.h b/arch/powerpc/include/asm/book3s/pgalloc.h index c0a69ae92256..6b178ca143e7 100644 --- a/arch/powerpc/include/asm/book3s/pgalloc.h +++ b/arch/powerpc/include/asm/book3s/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_PGALLOC_H #define _ASM_POWERPC_BOOK3S_PGALLOC_H diff --git a/arch/powerpc/include/asm/book3s/pgtable.h b/arch/powerpc/include/asm/book3s/pgtable.h index 8b0f4a29259a..6436b65ac7bc 100644 --- a/arch/powerpc/include/asm/book3s/pgtable.h +++ b/arch/powerpc/include/asm/book3s/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_PGTABLE_H #define _ASM_POWERPC_BOOK3S_PGTABLE_H diff --git a/arch/powerpc/include/asm/bootx.h b/arch/powerpc/include/asm/bootx.h index dd9461003dfa..1c121f3c524f 100644 --- a/arch/powerpc/include/asm/bootx.h +++ b/arch/powerpc/include/asm/bootx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file describes the structure passed from the BootX application * (for MacOS) when it is used to boot Linux. diff --git a/arch/powerpc/include/asm/btext.h b/arch/powerpc/include/asm/btext.h index 89fc382648bc..3ffad030393c 100644 --- a/arch/powerpc/include/asm/btext.h +++ b/arch/powerpc/include/asm/btext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for using the procedures in btext.c. * diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index 87fcc1948817..3c04249bcf39 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BUG_H #define _ASM_POWERPC_BUG_H #ifdef __KERNEL__ @@ -133,6 +134,7 @@ extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); extern void bad_page_fault(struct pt_regs *, unsigned long, int); extern void _exception(int, struct pt_regs *, int, unsigned long); extern void die(const char *, struct pt_regs *, long); +extern bool die_will_crash(void); #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 5a90292afbad..c1d257aa4c2d 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_CACHE_H #define _ASM_POWERPC_CACHE_H @@ -5,7 +6,7 @@ /* bytes per L1 cache line */ -#if defined(CONFIG_8xx) || defined(CONFIG_403GCX) +#if defined(CONFIG_PPC_8xx) || defined(CONFIG_403GCX) #define L1_CACHE_SHIFT 4 #define MAX_COPY_PREFETCH 1 #elif defined(CONFIG_PPC_E500MC) diff --git a/arch/powerpc/include/asm/cell-regs.h b/arch/powerpc/include/asm/cell-regs.h index fdf64fd25950..e1c431ef30e0 100644 --- a/arch/powerpc/include/asm/cell-regs.h +++ b/arch/powerpc/include/asm/cell-regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * cbe_regs.h * diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h index fc46b664c49e..9b001f1f6b32 100644 --- a/arch/powerpc/include/asm/cmpxchg.h +++ b/arch/powerpc/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_CMPXCHG_H_ #define _ASM_POWERPC_CMPXCHG_H_ diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 5482928eea1b..abef812de7f8 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -83,16 +83,8 @@ static inline unsigned long ppc_function_entry(void *func) * On PPC64 ABIv1 the function pointer actually points to the * function's descriptor. The first entry in the descriptor is the * address of the function text. - * - * However, we may also receive pointer to an assembly symbol. To - * detect that, we first check if the function pointer we receive - * already points to kernel/module text and we only dereference it - * if it doesn't. */ - if (kernel_text_address((unsigned long)func)) - return (unsigned long)func; - else - return ((func_descr_t *)func)->entry; + return ((func_descr_t *)func)->entry; #else return (unsigned long)func; #endif diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h index f256e1d14a14..a035b1e5dfa7 100644 --- a/arch/powerpc/include/asm/compat.h +++ b/arch/powerpc/include/asm/compat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_COMPAT_H #define _ASM_POWERPC_COMPAT_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/context_tracking.h b/arch/powerpc/include/asm/context_tracking.h index 40014921ffff..f2682b28b050 100644 --- a/arch/powerpc/include/asm/context_tracking.h +++ b/arch/powerpc/include/asm/context_tracking.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_CONTEXT_TRACKING_H #define _ASM_POWERPC_CONTEXT_TRACKING_H diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h index 2c5c5b476804..b925df1b87d0 100644 --- a/arch/powerpc/include/asm/cpm.h +++ b/arch/powerpc/include/asm/cpm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPM_H #define __CPM_H diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h index 14ad37865000..3db821876d48 100644 --- a/arch/powerpc/include/asm/cpm1.h +++ b/arch/powerpc/include/asm/cpm1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * MPC8xx Communication Processor Module. * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) diff --git a/arch/powerpc/include/asm/cpm2.h b/arch/powerpc/include/asm/cpm2.h index 7c8608b09694..2211b934ecb4 100644 --- a/arch/powerpc/include/asm/cpm2.h +++ b/arch/powerpc/include/asm/cpm2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Communication Processor Module v2. * diff --git a/arch/powerpc/include/asm/cpu_has_feature.h b/arch/powerpc/include/asm/cpu_has_feature.h index 0d1df02bf99d..7897d16e0990 100644 --- a/arch/powerpc/include/asm/cpu_has_feature.h +++ b/arch/powerpc/include/asm/cpu_has_feature.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_POWERPC_CPU_HAS_FEATURE_H #define __ASM_POWERPC_CPU_HAS_FEATURE_H diff --git a/arch/powerpc/include/asm/cpuidle.h b/arch/powerpc/include/asm/cpuidle.h index 52586f9956bb..e210a83eb196 100644 --- a/arch/powerpc/include/asm/cpuidle.h +++ b/arch/powerpc/include/asm/cpuidle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_CPUIDLE_H #define _ASM_POWERPC_CPUIDLE_H @@ -67,6 +68,17 @@ #define ERR_DEEP_STATE_ESL_MISMATCH -2 #ifndef __ASSEMBLY__ +/* Additional SPRs that need to be saved/restored during stop */ +struct stop_sprs { + u64 pid; + u64 ldbar; + u64 fscr; + u64 hfscr; + u64 mmcr1; + u64 mmcr2; + u64 mmcra; +}; + extern u32 pnv_fastsleep_workaround_at_entry[]; extern u32 pnv_fastsleep_workaround_at_exit[]; @@ -90,20 +102,4 @@ static inline void report_invalid_psscr_val(u64 psscr_val, int err) #endif -/* Idle state entry routines */ -#ifdef CONFIG_PPC_P7_NAP -#define IDLE_STATE_ENTER_SEQ(IDLE_INST) \ - /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ - std r0,0(r1); \ - ptesync; \ - ld r0,0(r1); \ -236: cmpd cr0,r0,r0; \ - bne 236b; \ - IDLE_INST; \ - -#define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ - IDLE_STATE_ENTER_SEQ(IDLE_INST) \ - b . -#endif /* CONFIG_PPC_P7_NAP */ - #endif diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index d02ad93bf708..53b31c2bcdf4 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_POWERPC_CPUTABLE_H #define __ASM_POWERPC_CPUTABLE_H @@ -513,7 +514,7 @@ enum { #else CPU_FTRS_GENERIC_32 | #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx CPU_FTRS_8XX | #endif #ifdef CONFIG_40x @@ -565,7 +566,7 @@ enum { #else CPU_FTRS_GENERIC_32 & #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx CPU_FTRS_8XX & #endif #ifdef CONFIG_40x diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index 9377bdf42eb8..d71a90924f3b 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_CPUTHREADS_H #define _ASM_POWERPC_CPUTHREADS_H diff --git a/arch/powerpc/include/asm/dbdma.h b/arch/powerpc/include/asm/dbdma.h index 6c69836b4ec2..4785c1716b3e 100644 --- a/arch/powerpc/include/asm/dbdma.h +++ b/arch/powerpc/include/asm/dbdma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for using the Apple Descriptor-Based DMA controller * in Power Macintosh computers. diff --git a/arch/powerpc/include/asm/dcr-regs.h b/arch/powerpc/include/asm/dcr-regs.h index 380274de429f..5c1a4973f46a 100644 --- a/arch/powerpc/include/asm/dcr-regs.h +++ b/arch/powerpc/include/asm/dcr-regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Common DCR / SDR / CPR register definitions used on various IBM/AMCC * 4xx processors diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h index 5d5af3fddfd8..14e71ff6579e 100644 --- a/arch/powerpc/include/asm/debug.h +++ b/arch/powerpc/include/asm/debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999 Cort Dougan */ diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index eaece3d3e225..ee1e38ff1b77 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2004 IBM * diff --git a/arch/powerpc/include/asm/dma.h b/arch/powerpc/include/asm/dma.h index a5c6d83b5f60..1b4f0254868f 100644 --- a/arch/powerpc/include/asm/dma.h +++ b/arch/powerpc/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_DMA_H #define _ASM_POWERPC_DMA_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/dt_cpu_ftrs.h b/arch/powerpc/include/asm/dt_cpu_ftrs.h index 7a34fc11bf63..71515d909ed1 100644 --- a/arch/powerpc/include/asm/dt_cpu_ftrs.h +++ b/arch/powerpc/include/asm/dt_cpu_ftrs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_POWERPC_DT_CPU_FTRS_H #define __ASM_POWERPC_DT_CPU_FTRS_H diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 8e37b71674f4..9847ae3a12d1 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -131,7 +131,6 @@ static inline bool eeh_pe_passed(struct eeh_pe *pe) struct eeh_dev { int mode; /* EEH mode */ int class_code; /* Class code of the device */ - int config_addr; /* Config address */ int pe_config_addr; /* PE config address */ u32 config_space[16]; /* Saved PCI config space */ int pcix_cap; /* Saved PCIx capability */ @@ -141,7 +140,6 @@ struct eeh_dev { struct eeh_pe *pe; /* Associated PE */ struct list_head list; /* Form link list in the PE */ struct list_head rmv_list; /* Record the removed edevs */ - struct pci_controller *phb; /* Associated PHB */ struct pci_dn *pdn; /* Associated PCI device node */ struct pci_dev *pdev; /* Associated PCI device */ bool in_error; /* Error flag for edev */ @@ -262,7 +260,8 @@ typedef void *(*eeh_traverse_func)(void *data, void *flag); void eeh_set_pe_aux_size(int size); int eeh_phb_pe_create(struct pci_controller *phb); struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb); -struct eeh_pe *eeh_pe_get(struct eeh_dev *edev); +struct eeh_pe *eeh_pe_get(struct pci_controller *phb, + int pe_no, int config_addr); int eeh_add_to_parent_pe(struct eeh_dev *edev); int eeh_rmv_from_parent_pe(struct eeh_dev *edev); void eeh_pe_update_time_stamp(struct eeh_pe *pe); diff --git a/arch/powerpc/include/asm/exec.h b/arch/powerpc/include/asm/exec.h index 8196e9c7d7e8..92cac4851275 100644 --- a/arch/powerpc/include/asm/exec.h +++ b/arch/powerpc/include/asm/exec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999 Cort Dougan */ diff --git a/arch/powerpc/include/asm/extable.h b/arch/powerpc/include/asm/extable.h index 07cc45cd86d9..eb91b2d2935a 100644 --- a/arch/powerpc/include/asm/extable.h +++ b/arch/powerpc/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_POWERPC_EXTABLE_H #define _ARCH_POWERPC_EXTABLE_H diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h index ce88bbe1d809..5a23010af600 100644 --- a/arch/powerpc/include/asm/fadump.h +++ b/arch/powerpc/include/asm/fadump.h @@ -209,11 +209,13 @@ extern int early_init_dt_scan_fw_dump(unsigned long node, extern int fadump_reserve_mem(void); extern int setup_fadump(void); extern int is_fadump_active(void); +extern int should_fadump_crash(void); extern void crash_fadump(struct pt_regs *, const char *); extern void fadump_cleanup(void); #else /* CONFIG_FA_DUMP */ static inline int is_fadump_active(void) { return 0; } +static inline int should_fadump_crash(void) { return 0; } static inline void crash_fadump(struct pt_regs *regs, const char *str) { } #endif #endif diff --git a/arch/powerpc/include/asm/fb.h b/arch/powerpc/include/asm/fb.h index 411af8d17a69..6541ab77c5b9 100644 --- a/arch/powerpc/include/asm/fb.h +++ b/arch/powerpc/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_FB_H_ #define _ASM_FB_H_ diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h index 2de2319b99e2..8f88f771cc55 100644 --- a/arch/powerpc/include/asm/feature-fixups.h +++ b/arch/powerpc/include/asm/feature-fixups.h @@ -19,11 +19,11 @@ */ #if defined(CONFIG_PPC64) && !defined(__powerpc64__) /* 64 bits kernel, 32 bits code (ie. vdso32) */ -#define FTR_ENTRY_LONG .llong +#define FTR_ENTRY_LONG .8byte #define FTR_ENTRY_OFFSET .long 0xffffffff; .long #elif defined(CONFIG_PPC64) -#define FTR_ENTRY_LONG .llong -#define FTR_ENTRY_OFFSET .llong +#define FTR_ENTRY_LONG .8byte +#define FTR_ENTRY_OFFSET .8byte #else #define FTR_ENTRY_LONG .long #define FTR_ENTRY_OFFSET .long diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h index 4508b322f2cd..6c40dfda5912 100644 --- a/arch/powerpc/include/asm/fixmap.h +++ b/arch/powerpc/include/asm/fixmap.h @@ -17,6 +17,7 @@ #ifndef __ASSEMBLY__ #include #include +#include #ifdef CONFIG_HIGHMEM #include #include @@ -62,9 +63,6 @@ enum fixed_addresses { __end_of_fixed_addresses }; -extern void __set_fixmap (enum fixed_addresses idx, - phys_addr_t phys, pgprot_t flags); - #define __FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - __FIXADDR_SIZE) @@ -72,5 +70,11 @@ extern void __set_fixmap (enum fixed_addresses idx, #include +static inline void __set_fixmap(enum fixed_addresses idx, + phys_addr_t phys, pgprot_t flags) +{ + map_kernel_page(fix_to_virt(idx), phys, pgprot_val(flags)); +} + #endif /* !__ASSEMBLY__ */ #endif diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h index f79d6c74eb2a..8def56ec05c6 100644 --- a/arch/powerpc/include/asm/fs_pd.h +++ b/arch/powerpc/include/asm/fs_pd.h @@ -26,7 +26,7 @@ #define cpm2_unmap(addr) do {} while(0) #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx #include extern immap_t __iomem *mpc8xx_immr; diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index 686c5f70eb84..9abddde372ab 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_FTRACE #define _ASM_POWERPC_FTRACE diff --git a/arch/powerpc/include/asm/futex.h b/arch/powerpc/include/asm/futex.h index eaada6c92344..1a944c18c539 100644 --- a/arch/powerpc/include/asm/futex.h +++ b/arch/powerpc/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_FUTEX_H #define _ASM_POWERPC_FUTEX_H @@ -29,18 +30,10 @@ : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \ : "cr0", "memory") -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -66,17 +59,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/powerpc/include/asm/grackle.h b/arch/powerpc/include/asm/grackle.h index bd7812a519d4..7376e3fa1570 100644 --- a/arch/powerpc/include/asm/grackle.h +++ b/arch/powerpc/include/asm/grackle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_GRACKLE_H #define _ASM_POWERPC_GRACKLE_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h index 8add8b861e8d..456f9e7b8d83 100644 --- a/arch/powerpc/include/asm/hardirq.h +++ b/arch/powerpc/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_HARDIRQ_H #define _ASM_POWERPC_HARDIRQ_H @@ -12,6 +13,10 @@ typedef struct { unsigned int mce_exceptions; unsigned int spurious_irqs; unsigned int hmi_exceptions; + unsigned int sreset_irqs; +#ifdef CONFIG_PPC_WATCHDOG + unsigned int soft_nmi_irqs; +#endif #ifdef CONFIG_PPC_DOORBELL unsigned int doorbell_irqs; #endif diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index d81eac5b509f..fdcff76e9a25 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_HEAD_64_H #define _ASM_POWERPC_HEAD_64_H diff --git a/arch/powerpc/include/asm/heathrow.h b/arch/powerpc/include/asm/heathrow.h index 93f54958a9d1..8bc5b168762e 100644 --- a/arch/powerpc/include/asm/heathrow.h +++ b/arch/powerpc/include/asm/heathrow.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_HEATHROW_H #define _ASM_POWERPC_HEATHROW_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index 01c2c23b307e..cec820f961da 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * highmem.h: virtual kernel memory mappings for high memory * diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 7f4025a6c69e..93f98239159f 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_HUGETLB_H #define _ASM_POWERPC_HUGETLB_H @@ -218,18 +219,4 @@ static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr, } #endif /* CONFIG_HUGETLB_PAGE */ -/* - * FSL Book3E platforms require special gpage handling - the gpages - * are reserved early in the boot process by memblock instead of via - * the .dts as on IBM platforms. - */ -#if defined(CONFIG_HUGETLB_PAGE) && (defined(CONFIG_PPC_FSL_BOOK3E) || \ - defined(CONFIG_PPC_8xx)) -extern void __init reserve_hugetlb_gpages(void); -#else -static inline void reserve_hugetlb_gpages(void) -{ -} -#endif - #endif /* _ASM_POWERPC_HUGETLB_H */ diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index 57d38b504ff7..a409177be8bd 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_HVCALL_H #define _ASM_POWERPC_HVCALL_H #ifdef __KERNEL__ @@ -280,7 +281,18 @@ #define H_RESIZE_HPT_COMMIT 0x370 #define H_REGISTER_PROC_TBL 0x37C #define H_SIGNAL_SYS_RESET 0x380 -#define MAX_HCALL_OPCODE H_SIGNAL_SYS_RESET +#define H_INT_GET_SOURCE_INFO 0x3A8 +#define H_INT_SET_SOURCE_CONFIG 0x3AC +#define H_INT_GET_SOURCE_CONFIG 0x3B0 +#define H_INT_GET_QUEUE_INFO 0x3B4 +#define H_INT_SET_QUEUE_CONFIG 0x3B8 +#define H_INT_GET_QUEUE_CONFIG 0x3BC +#define H_INT_SET_OS_REPORTING_LINE 0x3C0 +#define H_INT_GET_OS_REPORTING_LINE 0x3C4 +#define H_INT_ESB 0x3C8 +#define H_INT_SYNC 0x3CC +#define H_INT_RESET 0x3D0 +#define MAX_HCALL_OPCODE H_INT_RESET /* H_VIOCTL functions */ #define H_GET_VIOA_DUMP_SIZE 0x01 diff --git a/arch/powerpc/include/asm/hvsi.h b/arch/powerpc/include/asm/hvsi.h index d4a5315718ca..3fdc54df63c9 100644 --- a/arch/powerpc/include/asm/hvsi.h +++ b/arch/powerpc/include/asm/hvsi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _HVSI_H #define _HVSI_H diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index c1dd1929342d..abd04c36c251 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999 Cort Dougan */ diff --git a/arch/powerpc/include/asm/i8259.h b/arch/powerpc/include/asm/i8259.h index c3fdfbd5a673..d7f08ae49e12 100644 --- a/arch/powerpc/include/asm/i8259.h +++ b/arch/powerpc/include/asm/i8259.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_I8259_H #define _ASM_POWERPC_I8259_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/icswx.h b/arch/powerpc/include/asm/icswx.h index 27e588f6c72e..6a2c87577541 100644 --- a/arch/powerpc/include/asm/icswx.h +++ b/arch/powerpc/include/asm/icswx.h @@ -69,7 +69,10 @@ struct coprocessor_completion_block { #define CSB_CC_WR_PROTECTION (16) #define CSB_CC_UNKNOWN_CODE (17) #define CSB_CC_ABORT (18) +#define CSB_CC_EXCEED_BYTE_COUNT (19) /* P9 or later */ #define CSB_CC_TRANSPORT (20) +#define CSB_CC_INVALID_CRB (21) /* P9 or later */ +#define CSB_CC_INVALID_DDE (30) /* P9 or later */ #define CSB_CC_SEGMENTED_DDL (31) #define CSB_CC_PROGRESS_POINT (32) #define CSB_CC_DDE_OVERFLOW (33) diff --git a/arch/powerpc/include/asm/ide.h b/arch/powerpc/include/asm/ide.h index da01b20aea59..ce87a4441ca3 100644 --- a/arch/powerpc/include/asm/ide.h +++ b/arch/powerpc/include/asm/ide.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1994-1996 Linus Torvalds & authors * diff --git a/arch/powerpc/include/asm/ima.h b/arch/powerpc/include/asm/ima.h index 2313bdface34..ead488cf3981 100644 --- a/arch/powerpc/include/asm/ima.h +++ b/arch/powerpc/include/asm/ima.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_IMA_H #define _ASM_POWERPC_IMA_H diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h new file mode 100644 index 000000000000..7f74c282710f --- /dev/null +++ b/arch/powerpc/include/asm/imc-pmu.h @@ -0,0 +1,128 @@ +#ifndef __ASM_POWERPC_IMC_PMU_H +#define __ASM_POWERPC_IMC_PMU_H + +/* + * IMC Nest Performance Monitor counter support. + * + * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation. + * (C) 2017 Anju T Sudhakar, IBM Corporation. + * (C) 2017 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or later version. + */ + +#include +#include +#include +#include +#include + +/* + * For static allocation of some of the structures. + */ +#define IMC_MAX_PMUS 32 + +/* + * Compatibility macros for IMC devices + */ +#define IMC_DTB_COMPAT "ibm,opal-in-memory-counters" +#define IMC_DTB_UNIT_COMPAT "ibm,imc-counters" + + +/* + * LDBAR: Counter address and Enable/Disable macro. + * perf/imc-pmu.c has the LDBAR layout information. + */ +#define THREAD_IMC_LDBAR_MASK 0x0003ffffffffe000ULL +#define THREAD_IMC_ENABLE 0x8000000000000000ULL + +/* + * Structure to hold memory address information for imc units. + */ +struct imc_mem_info { + u64 *vbase; + u32 id; +}; + +/* + * Place holder for nest pmu events and values. + */ +struct imc_events { + u32 value; + char *name; + char *unit; + char *scale; +}; + +/* Event attribute array index */ +#define IMC_FORMAT_ATTR 0 +#define IMC_EVENT_ATTR 1 +#define IMC_CPUMASK_ATTR 2 +#define IMC_NULL_ATTR 3 + +/* PMU Format attribute macros */ +#define IMC_EVENT_OFFSET_MASK 0xffffffffULL + +/* + * Device tree parser code detects IMC pmu support and + * registers new IMC pmus. This structure will hold the + * pmu functions, events, counter memory information + * and attrs for each imc pmu and will be referenced at + * the time of pmu registration. + */ +struct imc_pmu { + struct pmu pmu; + struct imc_mem_info *mem_info; + struct imc_events **events; + /* + * Attribute groups for the PMU. Slot 0 used for + * format attribute, slot 1 used for cpusmask attribute, + * slot 2 used for event attribute. Slot 3 keep as + * NULL. + */ + const struct attribute_group *attr_groups[4]; + u32 counter_mem_size; + int domain; + /* + * flag to notify whether the memory is mmaped + * or allocated by kernel. + */ + bool imc_counter_mmaped; +}; + +/* + * Structure to hold id, lock and reference count for the imc events which + * are inited. + */ +struct imc_pmu_ref { + struct mutex lock; + unsigned int id; + int refc; +}; + +/* + * In-Memory Collection Counters type. + * Data comes from Device tree. + * Three device type are supported. + */ + +enum { + IMC_TYPE_THREAD = 0x1, + IMC_TYPE_CORE = 0x4, + IMC_TYPE_CHIP = 0x10, +}; + +/* + * Domains for IMC PMUs + */ +#define IMC_DOMAIN_NEST 1 +#define IMC_DOMAIN_CORE 2 +#define IMC_DOMAIN_THREAD 3 + +extern int init_imc_pmu(struct device_node *parent, + struct imc_pmu *pmu_ptr, int pmu_id); +extern void thread_imc_disable(void); +#endif /* __ASM_POWERPC_IMC_PMU_H */ diff --git a/arch/powerpc/include/asm/immap_cpm2.h b/arch/powerpc/include/asm/immap_cpm2.h index 7c64fda5357b..845d5b3fb212 100644 --- a/arch/powerpc/include/asm/immap_cpm2.h +++ b/arch/powerpc/include/asm/immap_cpm2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * CPM2 Internal Memory Map * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) diff --git a/arch/powerpc/include/asm/io-defs.h b/arch/powerpc/include/asm/io-defs.h index 44d7927aec69..faf8617cc574 100644 --- a/arch/powerpc/include/asm/io-defs.h +++ b/arch/powerpc/include/asm/io-defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* This file is meant to be include multiple times by other headers */ /* last 2 argments are used by platforms/cell/io-workarounds.[ch] */ diff --git a/arch/powerpc/include/asm/irq_work.h b/arch/powerpc/include/asm/irq_work.h index 744fd54de374..c6d3078bd8c3 100644 --- a/arch/powerpc/include/asm/irq_work.h +++ b/arch/powerpc/include/asm/irq_work.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_IRQ_WORK_H #define _ASM_POWERPC_IRQ_WORK_H diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h index f2149066fe5d..1aeb5f13b8c4 100644 --- a/arch/powerpc/include/asm/irqflags.h +++ b/arch/powerpc/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IRQ flags handling */ diff --git a/arch/powerpc/include/asm/isa-bridge.h b/arch/powerpc/include/asm/isa-bridge.h index a3a7c1d63a7c..47295894bf91 100644 --- a/arch/powerpc/include/asm/isa-bridge.h +++ b/arch/powerpc/include/asm/isa-bridge.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ISA_BRIDGE_H #define __ISA_BRIDGE_H diff --git a/arch/powerpc/include/asm/kdebug.h b/arch/powerpc/include/asm/kdebug.h index ae6d206728af..0f7c1ef37d0d 100644 --- a/arch/powerpc/include/asm/kdebug.h +++ b/arch/powerpc/include/asm/kdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_KDEBUG_H #define _ASM_POWERPC_KDEBUG_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/kdump.h b/arch/powerpc/include/asm/kdump.h index c9776202d7ec..fd128d1e52b3 100644 --- a/arch/powerpc/include/asm/kdump.h +++ b/arch/powerpc/include/asm/kdump.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC64_KDUMP_H #define _PPC64_KDUMP_H diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index 25668bc8cb2a..4419d435639a 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_KEXEC_H #define _ASM_POWERPC_KEXEC_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/keylargo.h b/arch/powerpc/include/asm/keylargo.h index 2156315d8a90..debdf548009d 100644 --- a/arch/powerpc/include/asm/keylargo.h +++ b/arch/powerpc/include/asm/keylargo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_KEYLARGO_H #define _ASM_POWERPC_KEYLARGO_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index 7cea76f11c26..83596f32f50b 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -104,6 +104,10 @@ struct kvmppc_host_state { u8 napping; #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + /* + * hwthread_req/hwthread_state pair is used to pull sibling threads + * out of guest on pre-ISAv3.0B CPUs where threads share MMU. + */ u8 hwthread_req; u8 hwthread_state; u8 host_ipi; diff --git a/arch/powerpc/include/asm/libata-portmap.h b/arch/powerpc/include/asm/libata-portmap.h index 4396db57b8be..7c602da62560 100644 --- a/arch/powerpc/include/asm/libata-portmap.h +++ b/arch/powerpc/include/asm/libata-portmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_POWERPC_LIBATA_PORTMAP_H #define __ASM_POWERPC_LIBATA_PORTMAP_H diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/linkage.h index 0cf5e21179fc..1f00d2891d69 100644 --- a/arch/powerpc/include/asm/linkage.h +++ b/arch/powerpc/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_LINKAGE_H #define _ASM_POWERPC_LINKAGE_H diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h index b8da91363864..600a68bd77f5 100644 --- a/arch/powerpc/include/asm/local.h +++ b/arch/powerpc/include/asm/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_POWERPC_LOCAL_H #define _ARCH_POWERPC_LOCAL_H diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index cd2fc1cc1cc7..73b92017b6d7 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -76,7 +76,6 @@ struct machdep_calls { void __noreturn (*restart)(char *cmd); void __noreturn (*halt)(void); - void (*panic)(char *str); void (*cpu_die)(void); long (*time_init)(void); /* Optional, may be NULL */ diff --git a/arch/powerpc/include/asm/macio.h b/arch/powerpc/include/asm/macio.h index 27af7f8bbb8d..ff5fd82d9ff0 100644 --- a/arch/powerpc/include/asm/macio.h +++ b/arch/powerpc/include/asm/macio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACIO_ASIC_H__ #define __MACIO_ASIC_H__ #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/mediabay.h b/arch/powerpc/include/asm/mediabay.h index 11037a4133ee..230fda4707b8 100644 --- a/arch/powerpc/include/asm/mediabay.h +++ b/arch/powerpc/include/asm/mediabay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * mediabay.h: definitions for using the media bay * on PowerBook 3400 and similar computers. diff --git a/arch/powerpc/include/asm/mmu-40x.h b/arch/powerpc/include/asm/mmu-40x.h index 34916865eaef..74f4edb5916e 100644 --- a/arch/powerpc/include/asm/mmu-40x.h +++ b/arch/powerpc/include/asm/mmu-40x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_MMU_40X_H_ #define _ASM_POWERPC_MMU_40X_H_ diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/mmu-44x.h index bf52d704fc47..cb57f29f531d 100644 --- a/arch/powerpc/include/asm/mmu-44x.h +++ b/arch/powerpc/include/asm/mmu-44x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_MMU_44X_H_ #define _ASM_POWERPC_MMU_44X_H_ /* diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h index 798b5bf91427..5bb3dbede41a 100644 --- a/arch/powerpc/include/asm/mmu-8xx.h +++ b/arch/powerpc/include/asm/mmu-8xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_MMU_8XX_H_ #define _ASM_POWERPC_MMU_8XX_H_ /* diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h index 7ca8d8e80ffa..cda94a0f5146 100644 --- a/arch/powerpc/include/asm/mmu-book3e.h +++ b/arch/powerpc/include/asm/mmu-book3e.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_MMU_BOOK3E_H_ #define _ASM_POWERPC_MMU_BOOK3E_H_ /* diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 78260409dc9c..6364f5c2cc3e 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_MMU_H_ #define _ASM_POWERPC_MMU_H_ #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 35bec1c5bd5a..492d8140a395 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_POWERPC_MMU_CONTEXT_H #define __ASM_POWERPC_MMU_CONTEXT_H #ifdef __KERNEL__ @@ -77,76 +78,8 @@ extern void switch_cop(struct mm_struct *next); extern int use_cop(unsigned long acop, struct mm_struct *mm); extern void drop_cop(unsigned long acop, struct mm_struct *mm); -/* - * switch_mm is the entry point called from the architecture independent - * code in kernel/sched/core.c - */ -static inline void switch_mm_irqs_off(struct mm_struct *prev, - struct mm_struct *next, - struct task_struct *tsk) -{ - bool new_on_cpu = false; - - /* Mark this context has been used on the new CPU */ - if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) { - cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); - - /* - * This full barrier orders the store to the cpumask above vs - * a subsequent operation which allows this CPU to begin loading - * translations for next. - * - * When using the radix MMU that operation is the load of the - * MMU context id, which is then moved to SPRN_PID. - * - * For the hash MMU it is either the first load from slb_cache - * in switch_slb(), and/or the store of paca->mm_ctx_id in - * copy_mm_to_paca(). - * - * On the read side the barrier is in pte_xchg(), which orders - * the store to the PTE vs the load of mm_cpumask. - */ - smp_mb(); - - new_on_cpu = true; - } - - /* 32-bit keeps track of the current PGDIR in the thread struct */ -#ifdef CONFIG_PPC32 - tsk->thread.pgdir = next->pgd; -#endif /* CONFIG_PPC32 */ - - /* 64-bit Book3E keeps track of current PGD in the PACA */ -#ifdef CONFIG_PPC_BOOK3E_64 - get_paca()->pgd = next->pgd; -#endif - /* Nothing else to do if we aren't actually switching */ - if (prev == next) - return; - -#ifdef CONFIG_PPC_ICSWX - /* Switch coprocessor context only if prev or next uses a coprocessor */ - if (prev->context.acop || next->context.acop) - switch_cop(next); -#endif /* CONFIG_PPC_ICSWX */ - - /* We must stop all altivec streams before changing the HW - * context - */ -#ifdef CONFIG_ALTIVEC - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - asm volatile ("dssall"); -#endif /* CONFIG_ALTIVEC */ - - if (new_on_cpu) - radix_kvm_prefetch_workaround(next); - - /* - * The actual HW switching method differs between the various - * sub architectures. Out of line for now - */ - switch_mmu_context(prev, next, tsk); -} +extern void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk); static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) @@ -168,11 +101,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, */ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { - unsigned long flags; - - local_irq_save(flags); switch_mm(prev, next, current); - local_irq_restore(flags); } /* We don't currently use enter_lazy_tlb() for anything */ diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h index 4d52ccfc2366..91c69ff53a8a 100644 --- a/arch/powerpc/include/asm/mmzone.h +++ b/arch/powerpc/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99 * diff --git a/arch/powerpc/include/asm/mpc6xx.h b/arch/powerpc/include/asm/mpc6xx.h index effc2291beb2..6ed9f4ccc7b9 100644 --- a/arch/powerpc/include/asm/mpc6xx.h +++ b/arch/powerpc/include/asm/mpc6xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_POWERPC_MPC6xx_H #define __ASM_POWERPC_MPC6xx_H diff --git a/arch/powerpc/include/asm/mpc8260.h b/arch/powerpc/include/asm/mpc8260.h index 03317e1e6185..fd8c5707425b 100644 --- a/arch/powerpc/include/asm/mpc8260.h +++ b/arch/powerpc/include/asm/mpc8260.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Since there are many different boards and no standard configuration, * we have a unique include file for each. Rather than change every diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h index 98697611e7b3..fad8ddd697ac 100644 --- a/arch/powerpc/include/asm/mpic.h +++ b/arch/powerpc/include/asm/mpic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_MPIC_H #define _ASM_POWERPC_MPIC_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/nmi.h b/arch/powerpc/include/asm/nmi.h index 6f8e79cd35d8..e97f58689ca7 100644 --- a/arch/powerpc/include/asm/nmi.h +++ b/arch/powerpc/include/asm/nmi.h @@ -1,9 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_NMI_H #define _ASM_NMI_H -#ifdef CONFIG_HARDLOCKUP_DETECTOR +#ifdef CONFIG_PPC_WATCHDOG extern void arch_touch_nmi_watchdog(void); - extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self); #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace diff --git a/arch/powerpc/include/asm/nohash/32/pgalloc.h b/arch/powerpc/include/asm/nohash/32/pgalloc.h index cc369a70f2bb..d072139ff2e5 100644 --- a/arch/powerpc/include/asm/nohash/32/pgalloc.h +++ b/arch/powerpc/include/asm/nohash/32/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGALLOC_32_H #define _ASM_POWERPC_PGALLOC_32_H diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index 91314268f04f..cc2bfec3aa3b 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_32_PGTABLE_H #define _ASM_POWERPC_NOHASH_32_PGTABLE_H @@ -121,7 +122,7 @@ extern int icache_44x_need_flush; #include #elif defined(CONFIG_FSL_BOOKE) #include -#elif defined(CONFIG_8xx) +#elif defined(CONFIG_PPC_8xx) #include #endif @@ -337,9 +338,6 @@ static inline void __ptep_set_access_flags(struct mm_struct *mm, #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) >> 3 }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val << 3 }) -extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, - pmd_t **pmdp); - int map_kernel_page(unsigned long va, phys_addr_t pa, int flags); #endif /* !__ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/nohash/32/pte-40x.h b/arch/powerpc/include/asm/nohash/32/pte-40x.h index 9624ebdacc47..124f9ac23a1e 100644 --- a/arch/powerpc/include/asm/nohash/32/pte-40x.h +++ b/arch/powerpc/include/asm/nohash/32/pte-40x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_32_PTE_40x_H #define _ASM_POWERPC_NOHASH_32_PTE_40x_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/nohash/32/pte-44x.h b/arch/powerpc/include/asm/nohash/32/pte-44x.h index 0656ff81e5b0..f812c0272364 100644 --- a/arch/powerpc/include/asm/nohash/32/pte-44x.h +++ b/arch/powerpc/include/asm/nohash/32/pte-44x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_32_PTE_44x_H #define _ASM_POWERPC_NOHASH_32_PTE_44x_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h index b4df2734c078..6dc0180fd5c7 100644 --- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_32_PTE_8xx_H #define _ASM_POWERPC_NOHASH_32_PTE_8xx_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h b/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h index 5422d00c6145..d1ee24e9e137 100644 --- a/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h +++ b/arch/powerpc/include/asm/nohash/32/pte-fsl-booke.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H #define _ASM_POWERPC_NOHASH_32_PTE_FSL_BOOKE_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h index 9f4de0a1035e..c40ec32b8194 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H #define _ASM_POWERPC_NOHASH_64_PGTABLE_4K_H diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h index 1facb584dd29..7210c2818e41 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable-64k.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable-64k.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H #define _ASM_POWERPC_NOHASH_64_PGTABLE_64K_H diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index f0ff384d4ca5..265bbd7cba73 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_64_PGTABLE_H #define _ASM_POWERPC_NOHASH_64_PGTABLE_H /* diff --git a/arch/powerpc/include/asm/nohash/pgalloc.h b/arch/powerpc/include/asm/nohash/pgalloc.h index b39ec956d71e..0634f2949438 100644 --- a/arch/powerpc/include/asm/nohash/pgalloc.h +++ b/arch/powerpc/include/asm/nohash/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_PGALLOC_H #define _ASM_POWERPC_NOHASH_PGALLOC_H diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h index e5805ad78e12..5c68f4a59f75 100644 --- a/arch/powerpc/include/asm/nohash/pgtable.h +++ b/arch/powerpc/include/asm/nohash/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_PGTABLE_H #define _ASM_POWERPC_NOHASH_PGTABLE_H @@ -14,6 +15,7 @@ static inline int pte_write(pte_t pte) { return (pte_val(pte) & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO; } +static inline int pte_read(pte_t pte) { return 1; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } diff --git a/arch/powerpc/include/asm/nohash/pte-book3e.h b/arch/powerpc/include/asm/nohash/pte-book3e.h index e16807b78edf..2da4532ca377 100644 --- a/arch/powerpc/include/asm/nohash/pte-book3e.h +++ b/arch/powerpc/include/asm/nohash/pte-book3e.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_NOHASH_PTE_BOOK3E_H #define _ASM_POWERPC_NOHASH_PTE_BOOK3E_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/ohare.h b/arch/powerpc/include/asm/ohare.h index 0d030f9dea24..da3371fc348c 100644 --- a/arch/powerpc/include/asm/ohare.h +++ b/arch/powerpc/include/asm/ohare.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_OHARE_H #define _ASM_POWERPC_OHARE_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 3130a73652c7..450a60b81d2a 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -42,6 +42,7 @@ #define OPAL_I2C_STOP_ERR -24 #define OPAL_XIVE_PROVISIONING -31 #define OPAL_XIVE_FREE_ACTIVE -32 +#define OPAL_TIMEOUT -33 /* API Tokens (in r0) */ #define OPAL_INVALID_CALL -1 @@ -190,7 +191,16 @@ #define OPAL_NPU_INIT_CONTEXT 146 #define OPAL_NPU_DESTROY_CONTEXT 147 #define OPAL_NPU_MAP_LPAR 148 -#define OPAL_LAST 148 +#define OPAL_IMC_COUNTERS_INIT 149 +#define OPAL_IMC_COUNTERS_START 150 +#define OPAL_IMC_COUNTERS_STOP 151 +#define OPAL_GET_POWERCAP 152 +#define OPAL_SET_POWERCAP 153 +#define OPAL_GET_POWER_SHIFT_RATIO 154 +#define OPAL_SET_POWER_SHIFT_RATIO 155 +#define OPAL_SENSOR_GROUP_CLEAR 156 +#define OPAL_PCI_SET_P2P 157 +#define OPAL_LAST 157 /* Device tree flags */ @@ -1084,6 +1094,18 @@ enum { XIVE_DUMP_EMU_STATE = 5, }; +/* "type" argument options for OPAL_IMC_COUNTERS_* calls */ +enum { + OPAL_IMC_COUNTERS_NEST = 1, + OPAL_IMC_COUNTERS_CORE = 2, +}; + + +/* PCI p2p descriptor */ +#define OPAL_PCI_P2P_ENABLE 0x1 +#define OPAL_PCI_P2P_LOAD 0x2 +#define OPAL_PCI_P2P_STORE 0x4 + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_API_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 588fb1c23af9..726c23304a57 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -50,7 +50,7 @@ int64_t opal_tpo_write(uint64_t token, uint32_t year_mon_day, uint32_t hour_min); int64_t opal_cec_power_down(uint64_t request); int64_t opal_cec_reboot(void); -int64_t opal_cec_reboot2(uint32_t reboot_type, char *diag); +int64_t opal_cec_reboot2(uint32_t reboot_type, const char *diag); int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset); int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset); int64_t opal_handle_interrupt(uint64_t isn, __be64 *outstanding_event_mask); @@ -267,6 +267,19 @@ int64_t opal_xive_allocate_irq(uint32_t chip_id); int64_t opal_xive_free_irq(uint32_t girq); int64_t opal_xive_sync(uint32_t type, uint32_t id); int64_t opal_xive_dump(uint32_t type, uint32_t id); +int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target, + uint64_t desc, uint16_t pe_number); + +int64_t opal_imc_counters_init(uint32_t type, uint64_t address, + uint64_t cpu_pir); +int64_t opal_imc_counters_start(uint32_t type, uint64_t cpu_pir); +int64_t opal_imc_counters_stop(uint32_t type, uint64_t cpu_pir); + +int opal_get_powercap(u32 handle, int token, u32 *pcap); +int opal_set_powercap(u32 handle, int token, u32 pcap); +int opal_get_power_shift_ratio(u32 handle, int token, u32 *psr); +int opal_set_power_shift_ratio(u32 handle, int token, u32 psr); +int opal_sensor_group_clear(u32 group_hndl, int token); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, @@ -345,6 +358,10 @@ static inline int opal_get_async_rc(struct opal_msg msg) void opal_wake_poller(void); +void opal_powercap_init(void); +void opal_psr_init(void); +void opal_sensor_groups_init(void); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_OPAL_H */ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index dc88a31cc79a..04b60af027ae 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -31,6 +31,7 @@ #endif #include #include +#include register struct paca_struct *local_paca asm("r13"); @@ -183,6 +184,12 @@ struct paca_struct { struct paca_struct **thread_sibling_pacas; /* The PSSCR value that the kernel requested before going to stop */ u64 requested_psscr; + + /* + * Save area for additional SPRs that need to be + * saved/restored during cpuidle stop. + */ + struct stop_sprs stop_sprs; #endif #ifdef CONFIG_PPC_STD_MMU_64 diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h index 6a8e1797f223..5c378e9b78c8 100644 --- a/arch/powerpc/include/asm/page_32.h +++ b/arch/powerpc/include/asm/page_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PAGE_32_H #define _ASM_POWERPC_PAGE_32_H diff --git a/arch/powerpc/include/asm/parport.h b/arch/powerpc/include/asm/parport.h index 6595ad1d18cc..8abfb8f7c33d 100644 --- a/arch/powerpc/include/asm/parport.h +++ b/arch/powerpc/include/asm/parport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * parport.h: platform-specific PC-style parport initialisation * diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 56c67d3f0108..0b8aa1fe2d5f 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -195,7 +195,6 @@ struct pci_dn { struct pci_dn *parent; struct pci_controller *phb; /* for pci devices */ struct iommu_table_group *table_group; /* for phb's or bridges */ - struct device_node *node; /* back-pointer to the device_node */ int pci_ext_config_space; /* for pci devices */ diff --git a/arch/powerpc/include/asm/percpu.h b/arch/powerpc/include/asm/percpu.h index 2cedefddba37..dce863a7635c 100644 --- a/arch/powerpc/include/asm/percpu.h +++ b/arch/powerpc/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PERCPU_H_ #define _ASM_POWERPC_PERCPU_H_ #ifdef __powerpc64__ diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h index d795c5d5789c..a14203c005f1 100644 --- a/arch/powerpc/include/asm/pgalloc.h +++ b/arch/powerpc/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGALLOC_H #define _ASM_POWERPC_PGALLOC_H @@ -17,6 +18,8 @@ static inline gfp_t pgtable_gfp_flags(struct mm_struct *mm, gfp_t gfp) } #endif /* MODULE */ +#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) + #ifdef CONFIG_PPC_BOOK3S #include #else diff --git a/arch/powerpc/include/asm/pgtable-be-types.h b/arch/powerpc/include/asm/pgtable-be-types.h index 67e7e3d990f4..beb6e3e79788 100644 --- a/arch/powerpc/include/asm/pgtable-be-types.h +++ b/arch/powerpc/include/asm/pgtable-be-types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGTABLE_BE_TYPES_H #define _ASM_POWERPC_PGTABLE_BE_TYPES_H diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h index 369a164b545c..cfe89a6fc308 100644 --- a/arch/powerpc/include/asm/pgtable-types.h +++ b/arch/powerpc/include/asm/pgtable-types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGTABLE_TYPES_H #define _ASM_POWERPC_PGTABLE_TYPES_H diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index afae9a336136..ab7d2d996be4 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PGTABLE_H #define _ASM_POWERPC_PGTABLE_H @@ -66,22 +67,14 @@ extern int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, #ifndef CONFIG_TRANSPARENT_HUGEPAGE #define pmd_large(pmd) 0 #endif -pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, - bool *is_thp, unsigned *shift); -static inline pte_t *find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, - bool *is_thp, unsigned *shift) -{ - VM_WARN(!arch_irqs_disabled(), - "%s called with irq enabled\n", __func__); - return __find_linux_pte_or_hugepte(pgdir, ea, is_thp, shift); -} +/* can we use this in kvm */ unsigned long vmalloc_to_phys(void *vmalloc_addr); void pgtable_cache_add(unsigned shift, void (*ctor)(void *)); void pgtable_cache_init(void); -#ifdef CONFIG_STRICT_KERNEL_RWX +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_PPC32) void mark_initmem_nx(void); #else static inline void mark_initmem_nx(void) { } diff --git a/arch/powerpc/include/asm/plpar_wrappers.h b/arch/powerpc/include/asm/plpar_wrappers.h index c7b164836bc3..7f01b22fa6cb 100644 --- a/arch/powerpc/include/asm/plpar_wrappers.h +++ b/arch/powerpc/include/asm/plpar_wrappers.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_PLPAR_WRAPPERS_H #define _ASM_POWERPC_PLPAR_WRAPPERS_H diff --git a/arch/powerpc/include/asm/pmac_pfunc.h b/arch/powerpc/include/asm/pmac_pfunc.h index 1330d6a58c57..73bd8f28f2a8 100644 --- a/arch/powerpc/include/asm/pmac_pfunc.h +++ b/arch/powerpc/include/asm/pmac_pfunc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PMAC_PFUNC_H__ #define __PMAC_PFUNC_H__ diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h index de9681034353..3e5cf251ad9a 100644 --- a/arch/powerpc/include/asm/pnv-pci.h +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -26,6 +26,8 @@ extern int pnv_pci_get_presence_state(uint64_t id, uint8_t *state); extern int pnv_pci_get_power_state(uint64_t id, uint8_t *state); extern int pnv_pci_set_power_state(uint64_t id, uint8_t state, struct opal_msg *msg); +extern int pnv_pci_set_p2p(struct pci_dev *initiator, struct pci_dev *target, + u64 desc); int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode); int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq, diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index fa9ebaead91e..ce0930d68857 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -193,6 +193,7 @@ #define PPC_INST_CLRBHRB 0x7c00035c #define PPC_INST_COPY 0x7c20060c #define PPC_INST_CP_ABORT 0x7c00068c +#define PPC_INST_DARN 0x7c0005e6 #define PPC_INST_DCBA 0x7c0005ec #define PPC_INST_DCBA_MASK 0xfc0007fe #define PPC_INST_DCBAL 0x7c2005ec @@ -204,6 +205,8 @@ #define PPC_INST_ISEL_MASK 0xfc00003e #define PPC_INST_LDARX 0x7c0000a8 #define PPC_INST_STDCX 0x7c0001ad +#define PPC_INST_LQARX 0x7c000228 +#define PPC_INST_STQCX 0x7c00016d #define PPC_INST_LSWI 0x7c0004aa #define PPC_INST_LSWX 0x7c00042a #define PPC_INST_LWARX 0x7c000028 @@ -261,7 +264,7 @@ #define PPC_INST_TLBSRX_DOT 0x7c0006a5 #define PPC_INST_VPMSUMW 0x10000488 #define PPC_INST_VPMSUMD 0x100004c8 -#define PPC_INST_XXLOR 0xf0000510 +#define PPC_INST_XXLOR 0xf0000490 #define PPC_INST_XXSWAPD 0xf0000250 #define PPC_INST_XVCPSGNDP 0xf0000780 #define PPC_INST_TRECHKPT 0x7c0007dd @@ -395,16 +398,25 @@ #define PPC_CP_ABORT stringify_in_c(.long PPC_INST_CP_ABORT) #define PPC_COPY(a, b) stringify_in_c(.long PPC_INST_COPY | \ ___PPC_RA(a) | ___PPC_RB(b)) +#define PPC_DARN(t, l) stringify_in_c(.long PPC_INST_DARN | \ + ___PPC_RT(t) | \ + (((l) & 0x3) << 16)) #define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \ __PPC_RA(a) | __PPC_RB(b)) #define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \ __PPC_RA(a) | __PPC_RB(b)) +#define PPC_LQARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LQARX | \ + ___PPC_RT(t) | ___PPC_RA(a) | \ + ___PPC_RB(b) | __PPC_EH(eh)) #define PPC_LDARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LDARX | \ ___PPC_RT(t) | ___PPC_RA(a) | \ ___PPC_RB(b) | __PPC_EH(eh)) #define PPC_LWARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LWARX | \ ___PPC_RT(t) | ___PPC_RA(a) | \ ___PPC_RB(b) | __PPC_EH(eh)) +#define PPC_STQCX(t, a, b) stringify_in_c(.long PPC_INST_STQCX | \ + ___PPC_RT(t) | ___PPC_RA(a) | \ + ___PPC_RB(b)) #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ ___PPC_RB(b)) #define PPC_MSGSYNC stringify_in_c(.long PPC_INST_MSGSYNC) @@ -414,6 +426,8 @@ ___PPC_RB(b)) #define PPC_MSGCLRP(b) stringify_in_c(.long PPC_INST_MSGCLRP | \ ___PPC_RB(b)) +#define PPC_PASTE(a, b) stringify_in_c(.long PPC_INST_PASTE | \ + ___PPC_RA(a) | ___PPC_RB(b)) #define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ __PPC_RA(a) | __PPC_RS(s)) #define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \ diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 6baeeb9acd0d..36f3e41c9fbe 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -378,10 +378,16 @@ BEGIN_FTR_SECTION_NESTED(96); \ cmpwi dest,0; \ beq- 90b; \ END_FTR_SECTION_NESTED(CPU_FTR_CELL_TB_BUG, CPU_FTR_CELL_TB_BUG, 96) -#elif defined(CONFIG_8xx) -#define MFTB(dest) mftb dest #else -#define MFTB(dest) mfspr dest, SPRN_TBRL +#define MFTB(dest) MFTBL(dest) +#endif + +#ifdef CONFIG_PPC_8xx +#define MFTBL(dest) mftb dest +#define MFTBU(dest) mftbu dest +#else +#define MFTBL(dest) mfspr dest, SPRN_TBRL +#define MFTBU(dest) mfspr dest, SPRN_TBRU #endif #ifndef CONFIG_SMP @@ -411,7 +417,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) * and they must be used. */ -#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) +#if !defined(CONFIG_4xx) && !defined(CONFIG_PPC_8xx) #define tlbia \ li r4,1024; \ mtctr r4; \ @@ -439,7 +445,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) .machine push ; \ .machine "power4" ; \ lis scratch,0x60000000@h; \ - dcbt r0,scratch,0b01010; \ + dcbt 0,scratch,0b01010; \ .machine pop /* diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 35c00d7a0cf8..825bd5998701 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -159,7 +159,10 @@ struct of_drconf_cell { #define OV5_PFO_HW_842 0x1140 /* PFO Compression Accelerator */ #define OV5_PFO_HW_ENCR 0x1120 /* PFO Encryption Accelerator */ #define OV5_SUB_PROCESSORS 0x1501 /* 1,2,or 4 Sub-Processors supported */ -#define OV5_XIVE_EXPLOIT 0x1701 /* XIVE exploitation supported */ +#define OV5_XIVE_SUPPORT 0x17C0 /* XIVE Exploitation Support Mask */ +#define OV5_XIVE_LEGACY 0x1700 /* XIVE legacy mode Only */ +#define OV5_XIVE_EXPLOIT 0x1740 /* XIVE exploitation mode Only */ +#define OV5_XIVE_EITHER 0x1780 /* XIVE legacy or exploitation mode */ /* MMU Base Architecture */ #define OV5_MMU_SUPPORT 0x18C0 /* MMU Mode Support Mask */ #define OV5_MMU_HASH 0x1800 /* Hash MMU Only */ diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h index 4ba26dd259fd..ce142ef99ba7 100644 --- a/arch/powerpc/include/asm/pte-common.h +++ b/arch/powerpc/include/asm/pte-common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Included from asm/pgtable-*.h only ! */ /* diff --git a/arch/powerpc/include/asm/pte-walk.h b/arch/powerpc/include/asm/pte-walk.h new file mode 100644 index 000000000000..2d633e9d686c --- /dev/null +++ b/arch/powerpc/include/asm/pte-walk.h @@ -0,0 +1,35 @@ +#ifndef _ASM_POWERPC_PTE_WALK_H +#define _ASM_POWERPC_PTE_WALK_H + +#include + +/* Don't use this directly */ +extern pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hshift); + +static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hshift) +{ + VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__); + return __find_linux_pte(pgdir, ea, is_thp, hshift); +} + +static inline pte_t *find_init_mm_pte(unsigned long ea, unsigned *hshift) +{ + pgd_t *pgdir = init_mm.pgd; + return __find_linux_pte(pgdir, ea, NULL, hshift); +} +/* + * This is what we should always use. Any other lockless page table lookup needs + * careful audit against THP split. + */ +static inline pte_t *find_current_mm_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hshift) +{ + VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__); + VM_WARN(pgdir != current->mm->pgd, + "%s lock less page table lookup called on wrong mm\n", __func__); + return __find_linux_pte(pgdir, ea, is_thp, hshift); +} + +#endif /* _ASM_POWERPC_PTE_WALK_H */ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a3b6575c7842..b779f3ccd412 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Contains the definition of registers common to all PowerPC variants. * If a register definition has been changed in a different PowerPC @@ -22,9 +23,9 @@ #include #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx #include -#endif /* CONFIG_8xx */ +#endif /* CONFIG_PPC_8xx */ #define MSR_SF_LG 63 /* Enable 64 bit mode */ #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ @@ -135,7 +136,7 @@ #define MSR_KERNEL (MSR_ | MSR_64BIT) #define MSR_USER32 (MSR_ | MSR_PR | MSR_EE) #define MSR_USER64 (MSR_USER32 | MSR_64BIT) -#elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_8xx) +#elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_8xx) /* Default MSR for kernel mode. */ #define MSR_KERNEL (MSR_ME|MSR_RI|MSR_IR|MSR_DR) #define MSR_USER (MSR_KERNEL|MSR_PR|MSR_EE) @@ -272,16 +273,65 @@ #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ -#define DSISR_NOHPTE 0x40000000 /* no translation found */ -#define DSISR_PROTFAULT 0x08000000 /* protection fault */ -#define DSISR_BADACCESS 0x04000000 /* bad access to CI or G */ -#define DSISR_ISSTORE 0x02000000 /* access was a store */ -#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ -#define DSISR_NOSEGMENT 0x00200000 /* SLB miss */ -#define DSISR_KEYFAULT 0x00200000 /* Key fault */ -#define DSISR_UNSUPP_MMU 0x00080000 /* Unsupported MMU config */ -#define DSISR_SET_RC 0x00040000 /* Failed setting of R/C bits */ -#define DSISR_PGDIRFAULT 0x00020000 /* Fault on page directory */ +#define DSISR_BAD_DIRECT_ST 0x80000000 /* Obsolete: Direct store error */ +#define DSISR_NOHPTE 0x40000000 /* no translation found */ +#define DSISR_ATTR_CONFLICT 0x20000000 /* P9: Process vs. Partition attr */ +#define DSISR_NOEXEC_OR_G 0x10000000 /* Alias of SRR1 bit, see below */ +#define DSISR_PROTFAULT 0x08000000 /* protection fault */ +#define DSISR_BADACCESS 0x04000000 /* bad access to CI or G */ +#define DSISR_ISSTORE 0x02000000 /* access was a store */ +#define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ +#define DSISR_NOSEGMENT 0x00200000 /* STAB miss (unsupported) */ +#define DSISR_KEYFAULT 0x00200000 /* Storage Key fault */ +#define DSISR_BAD_EXT_CTRL 0x00100000 /* Obsolete: External ctrl error */ +#define DSISR_UNSUPP_MMU 0x00080000 /* P9: Unsupported MMU config */ +#define DSISR_SET_RC 0x00040000 /* P9: Failed setting of R/C bits */ +#define DSISR_PRTABLE_FAULT 0x00020000 /* P9: Fault on process table */ +#define DSISR_ICSWX_NO_CT 0x00004000 /* P7: icswx unavailable cp type */ +#define DSISR_BAD_COPYPASTE 0x00000008 /* P9: Copy/Paste on wrong memtype */ +#define DSISR_BAD_AMO 0x00000004 /* P9: Incorrect AMO opcode */ +#define DSISR_BAD_CI_LDST 0x00000002 /* P8: Bad HV CI load/store */ + +/* + * DSISR_NOEXEC_OR_G doesn't actually exist. This bit is always + * 0 on DSIs. However, on ISIs, the corresponding bit in SRR1 + * indicates an attempt at executing from a no-execute PTE + * or segment or from a guarded page. + * + * We add a definition here for completeness as we alias + * DSISR and SRR1 in do_page_fault. + */ + +/* + * DSISR bits that are treated as a fault. Any bit set + * here will skip hash_page, and cause do_page_fault to + * trigger a SIGBUS or SIGSEGV: + */ +#define DSISR_BAD_FAULT_32S (DSISR_BAD_DIRECT_ST | \ + DSISR_BADACCESS | \ + DSISR_BAD_EXT_CTRL) +#define DSISR_BAD_FAULT_64S (DSISR_BAD_FAULT_32S | \ + DSISR_ATTR_CONFLICT | \ + DSISR_KEYFAULT | \ + DSISR_UNSUPP_MMU | \ + DSISR_PRTABLE_FAULT | \ + DSISR_ICSWX_NO_CT | \ + DSISR_BAD_COPYPASTE | \ + DSISR_BAD_AMO | \ + DSISR_BAD_CI_LDST) +/* + * These bits are equivalent in SRR1 and DSISR for 0x400 + * instruction access interrupts on Book3S + */ +#define DSISR_SRR1_MATCH_32S (DSISR_NOHPTE | \ + DSISR_NOEXEC_OR_G | \ + DSISR_PROTFAULT) +#define DSISR_SRR1_MATCH_64S (DSISR_SRR1_MATCH_32S | \ + DSISR_KEYFAULT | \ + DSISR_UNSUPP_MMU | \ + DSISR_SET_RC | \ + DSISR_PRTABLE_FAULT) + #define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ #define SPRN_CIR 0x11B /* Chip Information Register (hyper, R/0) */ @@ -307,6 +357,7 @@ #define SPRN_PMSR 0x355 /* Power Management Status Reg */ #define SPRN_PMMAR 0x356 /* Power Management Memory Activity Register */ #define SPRN_PSSCR 0x357 /* Processor Stop Status and Control Register (ISA 3.0) */ +#define SPRN_PSSCR_PR 0x337 /* PSSCR ISA 3.0, privileged mode access */ #define SPRN_PMCR 0x374 /* Power Management Control Register */ /* HFSCR and FSCR bit numbers are the same */ @@ -675,6 +726,7 @@ * may not be recoverable */ #define SRR1_WS_DEEPER 0x00020000 /* Some resources not maintained */ #define SRR1_WS_DEEP 0x00010000 /* All resources maintained */ +#define SRR1_PROGTM 0x00200000 /* TM Bad Thing */ #define SRR1_PROGFPE 0x00100000 /* Floating Point Enabled */ #define SRR1_PROGILL 0x00080000 /* Illegal instruction */ #define SRR1_PROGPRIV 0x00040000 /* Privileged instruction */ @@ -1114,7 +1166,7 @@ #endif #endif -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx #define SPRN_SPRG_SCRATCH0 SPRN_SPRG0 #define SPRN_SPRG_SCRATCH1 SPRN_SPRG1 #define SPRN_SPRG_SCRATCH2 SPRN_SPRG2 @@ -1197,10 +1249,8 @@ * differentiated by the version number in the Communication Processor * Module (CPM). */ -#define PVR_821 0x00500000 -#define PVR_823 PVR_821 -#define PVR_850 PVR_821 -#define PVR_860 PVR_821 +#define PVR_8xx 0x00500000 + #define PVR_8240 0x00810100 #define PVR_8245 0x80811014 #define PVR_8260 PVR_8240 @@ -1295,12 +1345,12 @@ static inline void msr_check_and_clear(unsigned long bits) ".section __ftr_fixup,\"a\"\n" \ ".align 3\n" \ "98:\n" \ - " .llong %1\n" \ - " .llong %1\n" \ - " .llong 97b-98b\n" \ - " .llong 99b-98b\n" \ - " .llong 0\n" \ - " .llong 0\n" \ + " .8byte %1\n" \ + " .8byte %1\n" \ + " .8byte 97b-98b\n" \ + " .8byte 99b-98b\n" \ + " .8byte 0\n" \ + " .8byte 0\n" \ ".previous" \ : "=r" (rval) \ : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \ @@ -1313,7 +1363,7 @@ static inline void msr_check_and_clear(unsigned long bits) #else /* __powerpc64__ */ -#if defined(CONFIG_8xx) +#if defined(CONFIG_PPC_8xx) #define mftbl() ({unsigned long rval; \ asm volatile("mftbl %0" : "=r" (rval)); rval;}) #define mftbu() ({unsigned long rval; \ diff --git a/arch/powerpc/include/asm/reg_8xx.h b/arch/powerpc/include/asm/reg_8xx.h index ae16fef7a4d6..53a7e2955d3e 100644 --- a/arch/powerpc/include/asm/reg_8xx.h +++ b/arch/powerpc/include/asm/reg_8xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Contains register definitions common to PowerPC 8xx CPUs. Notice */ diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 737e012ef56e..eb2a33d5df26 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -221,10 +221,7 @@ #define SPRN_CSRR0 SPRN_SRR2 /* Critical Save and Restore Register 0 */ #define SPRN_CSRR1 SPRN_SRR3 /* Critical Save and Restore Register 1 */ #endif - -#ifdef CONFIG_PPC_ICSWX #define SPRN_HACOP 0x15F /* Hypervisor Available Coprocessor Register */ -#endif /* Bit definitions for CCR1. */ #define CCR1_DPC 0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */ diff --git a/arch/powerpc/include/asm/reg_fsl_emb.h b/arch/powerpc/include/asm/reg_fsl_emb.h index 0e3ddf5177f6..d7ccf93e6279 100644 --- a/arch/powerpc/include/asm/reg_fsl_emb.h +++ b/arch/powerpc/include/asm/reg_fsl_emb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Contains register definitions for the Freescale Embedded Performance * Monitor. diff --git a/arch/powerpc/include/asm/runlatch.h b/arch/powerpc/include/asm/runlatch.h index 54e9b963876e..cfb390edf7d0 100644 --- a/arch/powerpc/include/asm/runlatch.h +++ b/arch/powerpc/include/asm/runlatch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999 Cort Dougan */ diff --git a/arch/powerpc/include/asm/seccomp.h b/arch/powerpc/include/asm/seccomp.h index c1818e35cf02..51209f6071c5 100644 --- a/arch/powerpc/include/asm/seccomp.h +++ b/arch/powerpc/include/asm/seccomp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SECCOMP_H #define _ASM_POWERPC_SECCOMP_H diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index 7902d6358854..82bec63bbd4f 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SECTIONS_H #define _ASM_POWERPC_SECTIONS_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h index 654d64c9f3ac..257d23dbf55d 100644 --- a/arch/powerpc/include/asm/setup.h +++ b/arch/powerpc/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SETUP_H #define _ASM_POWERPC_SETUP_H @@ -23,7 +24,6 @@ extern void reloc_got2(unsigned long); void check_for_initrd(void); void initmem_init(void); -void setup_panic(void); #define ARCH_PANIC_TIMEOUT 180 #ifdef CONFIG_PPC_PSERIES diff --git a/arch/powerpc/include/asm/shmparam.h b/arch/powerpc/include/asm/shmparam.h index 5cda42a6d39e..bc0968839565 100644 --- a/arch/powerpc/include/asm/shmparam.h +++ b/arch/powerpc/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SHMPARAM_H #define _ASM_POWERPC_SHMPARAM_H diff --git a/arch/powerpc/include/asm/signal.h b/arch/powerpc/include/asm/signal.h index 5ff77722a52d..0803ca8b9149 100644 --- a/arch/powerpc/include/asm/signal.h +++ b/arch/powerpc/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SIGNAL_H #define _ASM_POWERPC_SIGNAL_H diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 8ea98504f900..fac963e10d39 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -97,6 +97,7 @@ static inline void set_hard_smp_processor_id(int cpu, int phys) #endif DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map); +DECLARE_PER_CPU(cpumask_var_t, cpu_l2_cache_map); DECLARE_PER_CPU(cpumask_var_t, cpu_core_map); static inline struct cpumask *cpu_sibling_mask(int cpu) @@ -109,6 +110,11 @@ static inline struct cpumask *cpu_core_mask(int cpu) return per_cpu(cpu_core_map, cpu); } +static inline struct cpumask *cpu_l2_cache_mask(int cpu) +{ + return per_cpu(cpu_l2_cache_map, cpu); +} + extern int cpu_to_core_id(int cpu); /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h index 09f98e861869..8dff086c0cab 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SMU_H #define _SMU_H diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h index c88930c9db7f..a7916ee6dfb6 100644 --- a/arch/powerpc/include/asm/sparsemem.h +++ b/arch/powerpc/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SPARSEMEM_H #define _ASM_POWERPC_SPARSEMEM_H 1 #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index 8c1b913de6d7..edbe571bcc54 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -170,39 +170,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) lock->slock = 0; } -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - arch_spinlock_t lock_val; - - smp_mb(); - - /* - * Atomically load and store back the lock value (unchanged). This - * ensures that our observation of the lock value is ordered with - * respect to other lock operations. - */ - __asm__ __volatile__( -"1: " PPC_LWARX(%0, 0, %2, 0) "\n" -" stwcx. %0, 0, %2\n" -" bne- 1b\n" - : "=&r" (lock_val), "+m" (*lock) - : "r" (lock) - : "cr0", "xer"); - - if (arch_spin_value_unlocked(lock_val)) - goto out; - - while (lock->slock) { - HMT_low(); - if (SHARED_PROCESSOR) - __spin_yield(lock); - } - HMT_medium(); - -out: - smp_mb(); -} - /* * Read-write spinlocks, allowing multiple readers * but only one writer. @@ -342,5 +309,8 @@ static inline void arch_write_unlock(arch_rwlock_t *rw) #define arch_read_relax(lock) __rw_yield(lock) #define arch_write_relax(lock) __rw_yield(lock) +/* See include/linux/spinlock.h */ +#define smp_mb__after_spinlock() smp_mb() + #endif /* __KERNEL__ */ #endif /* __ASM_SPINLOCK_H */ diff --git a/arch/powerpc/include/asm/spinlock_types.h b/arch/powerpc/include/asm/spinlock_types.h index 2351adc4fdc4..87adaf13b7e8 100644 --- a/arch/powerpc/include/asm/spinlock_types.h +++ b/arch/powerpc/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SPINLOCK_TYPES_H #define _ASM_POWERPC_SPINLOCK_TYPES_H diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index d3a42cc45a82..ab9d849644d0 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -23,12 +23,9 @@ struct pt_regs; #define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) #define IS_RFI(instr) (((instr) & 0xfc0007fe) == 0x4c000064) -/* Emulate instructions that cause a transfer of control. */ -extern int emulate_step(struct pt_regs *regs, unsigned int instr); - enum instruction_type { COMPUTE, /* arith/logical/CR op, etc. */ - LOAD, + LOAD, /* load and store types need to be contiguous */ LOAD_MULTI, LOAD_FP, LOAD_VMX, @@ -55,10 +52,31 @@ enum instruction_type { #define INSTR_TYPE_MASK 0x1f +#define OP_IS_LOAD_STORE(type) (LOAD <= (type) && (type) <= STCX) + +/* Compute flags, ORed in with type */ +#define SETREG 0x20 +#define SETCC 0x40 +#define SETXER 0x80 + +/* Branch flags, ORed in with type */ +#define SETLK 0x20 +#define BRTAKEN 0x40 +#define DECCTR 0x80 + /* Load/store flags, ORed in with type */ #define SIGNEXT 0x20 #define UPDATE 0x40 /* matches bit in opcode 31 instructions */ #define BYTEREV 0x80 +#define FPCONV 0x100 + +/* Barrier type field, ORed in with type */ +#define BARRIER_MASK 0xe0 +#define BARRIER_SYNC 0x00 +#define BARRIER_ISYNC 0x20 +#define BARRIER_EIEIO 0x40 +#define BARRIER_LWSYNC 0x60 +#define BARRIER_PTESYNC 0x80 /* Cacheop values, ORed in with type */ #define CACHEOP_MASK 0x700 @@ -67,10 +85,17 @@ enum instruction_type { #define DCBTST 0x200 #define DCBT 0x300 #define ICBI 0x400 +#define DCBZ 0x500 + +/* VSX flags values */ +#define VSX_FPCONV 1 /* do floating point SP/DP conversion */ +#define VSX_SPLAT 2 /* store loaded value into all elements */ +#define VSX_LDLEFT 4 /* load VSX register from left */ +#define VSX_CHECK_VEC 8 /* check MSR_VEC not MSR_VSX for reg >= 32 */ /* Size field in type word */ -#define SIZE(n) ((n) << 8) -#define GETSIZE(w) ((w) >> 8) +#define SIZE(n) ((n) << 12) +#define GETSIZE(w) ((w) >> 12) #define MKOP(t, f, s) ((t) | (f) | SIZE(s)) @@ -83,7 +108,63 @@ struct instruction_op { int update_reg; /* For MFSPR */ int spr; + u32 ccval; + u32 xerval; + u8 element_size; /* for VSX/VMX loads/stores */ + u8 vsx_flags; }; -extern int analyse_instr(struct instruction_op *op, struct pt_regs *regs, +union vsx_reg { + u8 b[16]; + u16 h[8]; + u32 w[4]; + unsigned long d[2]; + float fp[4]; + double dp[2]; + __vector128 v; +}; + +/* + * Decode an instruction, and return information about it in *op + * without changing *regs. + * + * Return value is 1 if the instruction can be emulated just by + * updating *regs with the information in *op, -1 if we need the + * GPRs but *regs doesn't contain the full register set, or 0 + * otherwise. + */ +extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, unsigned int instr); + +/* + * Emulate an instruction that can be executed just by updating + * fields in *regs. + */ +void emulate_update_regs(struct pt_regs *reg, struct instruction_op *op); + +/* + * Emulate instructions that cause a transfer of control, + * arithmetic/logical instructions, loads and stores, + * cache operations and barriers. + * + * Returns 1 if the instruction was emulated successfully, + * 0 if it could not be emulated, or -1 for an instruction that + * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.). + */ +extern int emulate_step(struct pt_regs *regs, unsigned int instr); + +/* + * Emulate a load or store instruction by reading/writing the + * memory of the current process. FP/VMX/VSX registers are assumed + * to hold live values if the appropriate enable bit in regs->msr is + * set; otherwise this will use the saved values in the thread struct + * for user-mode accesses. + */ +extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op); + +extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, + const void *mem, bool cross_endian); +extern void emulate_vsx_store(struct instruction_op *op, + const union vsx_reg *reg, void *mem, + bool cross_endian); +extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs); diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index da3cdffca440..d98ac188cedb 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_STRING_H #define _ASM_POWERPC_STRING_H @@ -10,6 +11,7 @@ #define __HAVE_ARCH_MEMMOVE #define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCHR +#define __HAVE_ARCH_MEMSET16 extern char * strcpy(char *,const char *); extern char * strncpy(char *,const char *, __kernel_size_t); @@ -23,6 +25,31 @@ extern void * memmove(void *,const void *,__kernel_size_t); extern int memcmp(const void *,const void *,__kernel_size_t); extern void * memchr(const void *,int,__kernel_size_t); +#ifdef CONFIG_PPC64 +#define __HAVE_ARCH_MEMSET32 +#define __HAVE_ARCH_MEMSET64 + +extern void *__memset16(uint16_t *, uint16_t v, __kernel_size_t); +extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); +extern void *__memset64(uint64_t *, uint64_t v, __kernel_size_t); + +static inline void *memset16(uint16_t *p, uint16_t v, __kernel_size_t n) +{ + return __memset16(p, v, n * 2); +} + +static inline void *memset32(uint32_t *p, uint32_t v, __kernel_size_t n) +{ + return __memset32(p, v, n * 4); +} + +static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) +{ + return __memset64(p, v, n * 8); +} +#else +extern void *memset16(uint16_t *, uint16_t, __kernel_size_t); +#endif #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_STRING_H */ diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 17c8380673a6..bf820f53e27e 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999 Cort Dougan */ diff --git a/arch/powerpc/include/asm/synch.h b/arch/powerpc/include/asm/synch.h index 78efe8d5d775..63e7f5a1f105 100644 --- a/arch/powerpc/include/asm/synch.h +++ b/arch/powerpc/include/asm/synch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_SYNCH_H #define _ASM_POWERPC_SYNCH_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h index 16fab6898240..1b90a3516a35 100644 --- a/arch/powerpc/include/asm/syscalls.h +++ b/arch/powerpc/include/asm/syscalls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_POWERPC_SYSCALLS_H #define __ASM_POWERPC_SYSCALLS_H #ifdef __KERNEL__ diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index 1c9470881c4a..449912f057f6 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * List of powerpc syscalls. For the meaning of the _SPU suffix see * arch/powerpc/platforms/cell/spu_callbacks.c diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index a941cc6fc3e9..a264c3ad366b 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* thread_info.h: PowerPC low-level thread information * adapted from the i386 version by Paul Mackerras * diff --git a/arch/powerpc/include/asm/timex.h b/arch/powerpc/include/asm/timex.h index 2cf846edb3fc..926b9f91a3ef 100644 --- a/arch/powerpc/include/asm/timex.h +++ b/arch/powerpc/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_TIMEX_H #define _ASM_POWERPC_TIMEX_H @@ -29,7 +30,7 @@ static inline cycles_t get_cycles(void) ret = 0; __asm__ __volatile__( -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx "97: mftb %0\n" #else "97: mfspr %0, %2\n" @@ -45,11 +46,7 @@ static inline cycles_t get_cycles(void) " .long 0\n" " .long 0\n" ".previous" -#ifdef CONFIG_8xx - : "=r" (ret) : "i" (CPU_FTR_601)); -#else : "=r" (ret) : "i" (CPU_FTR_601), "i" (SPRN_TBRL)); -#endif return ret; #endif } diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h index 609557569f65..a7eabff27a0f 100644 --- a/arch/powerpc/include/asm/tlb.h +++ b/arch/powerpc/include/asm/tlb.h @@ -69,13 +69,22 @@ static inline int mm_is_core_local(struct mm_struct *mm) topology_sibling_cpumask(smp_processor_id())); } +#ifdef CONFIG_PPC_BOOK3S_64 +static inline int mm_is_thread_local(struct mm_struct *mm) +{ + if (atomic_read(&mm->context.active_cpus) > 1) + return false; + return cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)); +} +#else /* CONFIG_PPC_BOOK3S_64 */ static inline int mm_is_thread_local(struct mm_struct *mm) { return cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())); } +#endif /* !CONFIG_PPC_BOOK3S_64 */ -#else +#else /* CONFIG_SMP */ static inline int mm_is_core_local(struct mm_struct *mm) { return 1; diff --git a/arch/powerpc/include/asm/tm.h b/arch/powerpc/include/asm/tm.h index 82e06ca3a49b..a8bc72a7f4be 100644 --- a/arch/powerpc/include/asm/tm.h +++ b/arch/powerpc/include/asm/tm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Transactional memory support routines to reclaim and recheckpoint * transactional process state. diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index dc4e15937ccf..023ff9f17501 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_TOPOLOGY_H #define _ASM_POWERPC_TOPOLOGY_H #ifdef __KERNEL__ @@ -16,8 +17,6 @@ struct device_node; #include -#define parent_node(node) (node) - #define cpumask_of_node(node) ((node) == -1 ? \ cpu_all_mask : \ node_to_cpumask_map[node]) diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h index 18f168aebae3..33f3b479138b 100644 --- a/arch/powerpc/include/asm/trace.h +++ b/arch/powerpc/include/asm/trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM powerpc diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index 9c0e60ca1666..11f4bd07cce0 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_POWERPC_UACCESS_H #define _ARCH_POWERPC_UACCESS_H diff --git a/arch/powerpc/include/asm/unaligned.h b/arch/powerpc/include/asm/unaligned.h index 8296381ae432..ce69c5eff95e 100644 --- a/arch/powerpc/include/asm/unaligned.h +++ b/arch/powerpc/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_UNALIGNED_H #define _ASM_POWERPC_UNALIGNED_H diff --git a/arch/powerpc/include/asm/uninorth.h b/arch/powerpc/include/asm/uninorth.h index a1d112979fd2..e278299b9b37 100644 --- a/arch/powerpc/include/asm/uninorth.h +++ b/arch/powerpc/include/asm/uninorth.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * uninorth.h: definitions for using the "UniNorth" host bridge chip * from Apple. This chip is used on "Core99" machines diff --git a/arch/powerpc/include/asm/user.h b/arch/powerpc/include/asm/user.h index 3fd4545dd74e..5c0e082eae7b 100644 --- a/arch/powerpc/include/asm/user.h +++ b/arch/powerpc/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_USER_H #define _ASM_POWERPC_USER_H diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h new file mode 100644 index 000000000000..fd5963acd658 --- /dev/null +++ b/arch/powerpc/include/asm/vas.h @@ -0,0 +1,159 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _ASM_POWERPC_VAS_H +#define _ASM_POWERPC_VAS_H + +/* + * Min and max FIFO sizes are based on Version 1.05 Section 3.1.4.25 + * (Local FIFO Size Register) of the VAS workbook. + */ +#define VAS_RX_FIFO_SIZE_MIN (1 << 10) /* 1KB */ +#define VAS_RX_FIFO_SIZE_MAX (8 << 20) /* 8MB */ + +/* + * Threshold Control Mode: Have paste operation fail if the number of + * requests in receive FIFO exceeds a threshold. + * + * NOTE: No special error code yet if paste is rejected because of these + * limits. So users can't distinguish between this and other errors. + */ +#define VAS_THRESH_DISABLED 0 +#define VAS_THRESH_FIFO_GT_HALF_FULL 1 +#define VAS_THRESH_FIFO_GT_QTR_FULL 2 +#define VAS_THRESH_FIFO_GT_EIGHTH_FULL 3 + +/* + * Get/Set bit fields + */ +#define GET_FIELD(m, v) (((v) & (m)) >> MASK_LSH(m)) +#define MASK_LSH(m) (__builtin_ffsl(m) - 1) +#define SET_FIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_LSH(m)) & (m))) + +/* + * Co-processor Engine type. + */ +enum vas_cop_type { + VAS_COP_TYPE_FAULT, + VAS_COP_TYPE_842, + VAS_COP_TYPE_842_HIPRI, + VAS_COP_TYPE_GZIP, + VAS_COP_TYPE_GZIP_HIPRI, + VAS_COP_TYPE_FTW, + VAS_COP_TYPE_MAX, +}; + +/* + * Receive window attributes specified by the (in-kernel) owner of window. + */ +struct vas_rx_win_attr { + void *rx_fifo; + int rx_fifo_size; + int wcreds_max; + + bool pin_win; + bool rej_no_credit; + bool tx_wcred_mode; + bool rx_wcred_mode; + bool tx_win_ord_mode; + bool rx_win_ord_mode; + bool data_stamp; + bool nx_win; + bool fault_win; + bool user_win; + bool notify_disable; + bool intr_disable; + bool notify_early; + + int lnotify_lpid; + int lnotify_pid; + int lnotify_tid; + u32 pswid; + + int tc_mode; +}; + +/* + * Window attributes specified by the in-kernel owner of a send window. + */ +struct vas_tx_win_attr { + enum vas_cop_type cop; + int wcreds_max; + int lpid; + int pidr; /* hardware PID (from SPRN_PID) */ + int pid; /* linux process id */ + int pswid; + int rsvd_txbuf_count; + int tc_mode; + + bool user_win; + bool pin_win; + bool rej_no_credit; + bool rsvd_txbuf_enable; + bool tx_wcred_mode; + bool rx_wcred_mode; + bool tx_win_ord_mode; + bool rx_win_ord_mode; +}; + +/* + * Helper to initialize receive window attributes to defaults for an + * NX window. + */ +void vas_init_rx_win_attr(struct vas_rx_win_attr *rxattr, enum vas_cop_type cop); + +/* + * Open a VAS receive window for the instance of VAS identified by @vasid + * Use @attr to initialize the attributes of the window. + * + * Return a handle to the window or ERR_PTR() on error. + */ +struct vas_window *vas_rx_win_open(int vasid, enum vas_cop_type cop, + struct vas_rx_win_attr *attr); + +/* + * Helper to initialize send window attributes to defaults for an NX window. + */ +extern void vas_init_tx_win_attr(struct vas_tx_win_attr *txattr, + enum vas_cop_type cop); + +/* + * Open a VAS send window for the instance of VAS identified by @vasid + * and the co-processor type @cop. Use @attr to initialize attributes + * of the window. + * + * Note: The instance of VAS must already have an open receive window for + * the coprocessor type @cop. + * + * Return a handle to the send window or ERR_PTR() on error. + */ +struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, + struct vas_tx_win_attr *attr); + +/* + * Close the send or receive window identified by @win. For receive windows + * return -EAGAIN if there are active send windows attached to this receive + * window. + */ +int vas_win_close(struct vas_window *win); + +/* + * Copy the co-processor request block (CRB) @crb into the local L2 cache. + */ +int vas_copy_crb(void *crb, int offset); + +/* + * Paste a previously copied CRB (see vas_copy_crb()) from the L2 cache to + * the hardware address associated with the window @win. @re is expected/ + * assumed to be true for NX windows. + */ +int vas_paste_crb(struct vas_window *win, int offset, bool re); + +#endif /* __ASM_POWERPC_VAS_H */ diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h index c53f5f6d1761..b5e1f8f8a05c 100644 --- a/arch/powerpc/include/asm/vdso.h +++ b/arch/powerpc/include/asm/vdso.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PPC64_VDSO_H__ #define __PPC64_VDSO_H__ diff --git a/arch/powerpc/include/asm/vga.h b/arch/powerpc/include/asm/vga.h index ab3acd2f2786..fcf721682a71 100644 --- a/arch/powerpc/include/asm/vga.h +++ b/arch/powerpc/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_VGA_H_ #define _ASM_POWERPC_VGA_H_ @@ -33,8 +34,16 @@ static inline u16 scr_readw(volatile const u16 *addr) return le16_to_cpu(*addr); } +#define VT_BUF_HAVE_MEMSETW +static inline void scr_memsetw(u16 *s, u16 v, unsigned int n) +{ + memset16(s, cpu_to_le16(v), n / 2); +} + #define VT_BUF_HAVE_MEMCPYW +#define VT_BUF_HAVE_MEMMOVEW #define scr_memcpyw memcpy +#define scr_memmovew memmove #endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */ diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index 7ce2c3ac2964..8e903b3f9c24 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Common definitions across all variants of ICP and ICS interrupt * controllers. diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h index c23ff4389ca2..371fbebf1ec9 100644 --- a/arch/powerpc/include/asm/xive.h +++ b/arch/powerpc/include/asm/xive.h @@ -45,6 +45,7 @@ struct xive_irq_data { void __iomem *trig_mmio; u32 esb_shift; int src_chip; + u32 hw_irq; /* Setup/used by frontend */ int target; @@ -55,6 +56,7 @@ struct xive_irq_data { #define XIVE_IRQ_FLAG_SHIFT_BUG 0x04 #define XIVE_IRQ_FLAG_MASK_FW 0x08 #define XIVE_IRQ_FLAG_EOI_FW 0x10 +#define XIVE_IRQ_FLAG_H_INT_ESB 0x20 #define XIVE_INVALID_CHIP_ID -1 @@ -110,11 +112,13 @@ extern bool __xive_enabled; static inline bool xive_enabled(void) { return __xive_enabled; } +extern bool xive_spapr_init(void); extern bool xive_native_init(void); extern void xive_smp_probe(void); extern int xive_smp_prepare_cpu(unsigned int cpu); extern void xive_smp_setup_cpu(void); extern void xive_smp_disable_cpu(void); +extern void xive_teardown_cpu(void); extern void xive_kexec_teardown_cpu(int secondary); extern void xive_shutdown(void); extern void xive_flush_interrupt(void); @@ -147,6 +151,7 @@ extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id) static inline bool xive_enabled(void) { return false; } +static inline bool xive_spapr_init(void) { return false; } static inline bool xive_native_init(void) { return false; } static inline void xive_smp_probe(void) { } extern inline int xive_smp_prepare_cpu(unsigned int cpu) { return -EINVAL; } diff --git a/arch/powerpc/include/uapi/asm/auxvec.h b/arch/powerpc/include/uapi/asm/auxvec.h index be6e94ecec42..7af21dc0e320 100644 --- a/arch/powerpc/include/uapi/asm/auxvec.h +++ b/arch/powerpc/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_AUXVEC_H #define _ASM_POWERPC_AUXVEC_H diff --git a/arch/powerpc/include/uapi/asm/bitsperlong.h b/arch/powerpc/include/uapi/asm/bitsperlong.h index 5f1659032c40..46ece3ecff31 100644 --- a/arch/powerpc/include/uapi/asm/bitsperlong.h +++ b/arch/powerpc/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_POWERPC_BITSPERLONG_H #define __ASM_POWERPC_BITSPERLONG_H diff --git a/arch/powerpc/include/uapi/asm/bootx.h b/arch/powerpc/include/uapi/asm/bootx.h index 6e51cf0708a1..6728c7e24e58 100644 --- a/arch/powerpc/include/uapi/asm/bootx.h +++ b/arch/powerpc/include/uapi/asm/bootx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file describes the structure passed from the BootX application * (for MacOS) when it is used to boot Linux. diff --git a/arch/powerpc/include/uapi/asm/byteorder.h b/arch/powerpc/include/uapi/asm/byteorder.h index ca931d074000..8ef66f7d9db9 100644 --- a/arch/powerpc/include/uapi/asm/byteorder.h +++ b/arch/powerpc/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_BYTEORDER_H #define _ASM_POWERPC_BYTEORDER_H diff --git a/arch/powerpc/include/uapi/asm/cputable.h b/arch/powerpc/include/uapi/asm/cputable.h index 4d877144f377..50bcb4295de4 100644 --- a/arch/powerpc/include/uapi/asm/cputable.h +++ b/arch/powerpc/include/uapi/asm/cputable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ASM_POWERPC_CPUTABLE_H #define _UAPI__ASM_POWERPC_CPUTABLE_H diff --git a/arch/powerpc/include/uapi/asm/eeh.h b/arch/powerpc/include/uapi/asm/eeh.h index 291b7d1814a6..28186071fafc 100644 --- a/arch/powerpc/include/uapi/asm/eeh.h +++ b/arch/powerpc/include/uapi/asm/eeh.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index b2c6fdd5ac30..5f201d40bcca 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * ELF register definitions.. * diff --git a/arch/powerpc/include/uapi/asm/epapr_hcalls.h b/arch/powerpc/include/uapi/asm/epapr_hcalls.h index b4504f394427..90a0ee6d0bb3 100644 --- a/arch/powerpc/include/uapi/asm/epapr_hcalls.h +++ b/arch/powerpc/include/uapi/asm/epapr_hcalls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */ /* * ePAPR hcall interface * diff --git a/arch/powerpc/include/uapi/asm/errno.h b/arch/powerpc/include/uapi/asm/errno.h index e8b6b5f7de7c..cc79856896a1 100644 --- a/arch/powerpc/include/uapi/asm/errno.h +++ b/arch/powerpc/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_ERRNO_H #define _ASM_POWERPC_ERRNO_H diff --git a/arch/powerpc/include/uapi/asm/fcntl.h b/arch/powerpc/include/uapi/asm/fcntl.h index ce5c4516d404..65ce08322a89 100644 --- a/arch/powerpc/include/uapi/asm/fcntl.h +++ b/arch/powerpc/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_FCNTL_H #define _ASM_FCNTL_H diff --git a/arch/powerpc/include/uapi/asm/ioctl.h b/arch/powerpc/include/uapi/asm/ioctl.h index 57d68304218b..d623af4b9cd6 100644 --- a/arch/powerpc/include/uapi/asm/ioctl.h +++ b/arch/powerpc/include/uapi/asm/ioctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_IOCTL_H #define _ASM_POWERPC_IOCTL_H diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h index e3b10469f787..41b1a5c15734 100644 --- a/arch/powerpc/include/uapi/asm/ioctls.h +++ b/arch/powerpc/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_IOCTLS_H #define _ASM_POWERPC_IOCTLS_H diff --git a/arch/powerpc/include/uapi/asm/ipcbuf.h b/arch/powerpc/include/uapi/asm/ipcbuf.h index 2c3e1d94db1d..21e1e0ec0ba2 100644 --- a/arch/powerpc/include/uapi/asm/ipcbuf.h +++ b/arch/powerpc/include/uapi/asm/ipcbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_IPCBUF_H #define _ASM_POWERPC_IPCBUF_H diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h index 8cf8f0c96906..61d6049f4c1e 100644 --- a/arch/powerpc/include/uapi/asm/kvm.h +++ b/arch/powerpc/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as diff --git a/arch/powerpc/include/uapi/asm/kvm_para.h b/arch/powerpc/include/uapi/asm/kvm_para.h index 91e42f09b323..01555c6ae0f5 100644 --- a/arch/powerpc/include/uapi/asm/kvm_para.h +++ b/arch/powerpc/include/uapi/asm/kvm_para.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as diff --git a/arch/powerpc/include/uapi/asm/mman.h b/arch/powerpc/include/uapi/asm/mman.h index ab45cc2f3101..e63bc37e33af 100644 --- a/arch/powerpc/include/uapi/asm/mman.h +++ b/arch/powerpc/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,20 +30,4 @@ #define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ #define MAP_HUGETLB 0x40000 /* create a huge page mapping */ -/* - * When MAP_HUGETLB is set, bits [26:31] of the flags argument to mmap(2), - * encode the log2 of the huge page size. A value of zero indicates that the - * default huge page size should be used. To use a non-default huge page size, - * one of these defines can be used, or the size can be encoded by hand. Note - * that on most systems only a subset, or possibly none, of these sizes will be - * available. - */ -#define MAP_HUGE_512KB (19 << MAP_HUGE_SHIFT) /* 512KB HugeTLB Page */ -#define MAP_HUGE_1MB (20 << MAP_HUGE_SHIFT) /* 1MB HugeTLB Page */ -#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) /* 2MB HugeTLB Page */ -#define MAP_HUGE_8MB (23 << MAP_HUGE_SHIFT) /* 8MB HugeTLB Page */ -#define MAP_HUGE_16MB (24 << MAP_HUGE_SHIFT) /* 16MB HugeTLB Page */ -#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) /* 1GB HugeTLB Page */ -#define MAP_HUGE_16GB (34 << MAP_HUGE_SHIFT) /* 16GB HugeTLB Page */ - #endif /* _UAPI_ASM_POWERPC_MMAN_H */ diff --git a/arch/powerpc/include/uapi/asm/msgbuf.h b/arch/powerpc/include/uapi/asm/msgbuf.h index dd76743c7537..65beb0942500 100644 --- a/arch/powerpc/include/uapi/asm/msgbuf.h +++ b/arch/powerpc/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_MSGBUF_H #define _ASM_POWERPC_MSGBUF_H diff --git a/arch/powerpc/include/uapi/asm/nvram.h b/arch/powerpc/include/uapi/asm/nvram.h index 608bdc8aedd1..c92c7f056a91 100644 --- a/arch/powerpc/include/uapi/asm/nvram.h +++ b/arch/powerpc/include/uapi/asm/nvram.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * NVRAM definitions and access functions. * diff --git a/arch/powerpc/include/uapi/asm/opal-prd.h b/arch/powerpc/include/uapi/asm/opal-prd.h index 319ff4a26158..1869cf83a870 100644 --- a/arch/powerpc/include/uapi/asm/opal-prd.h +++ b/arch/powerpc/include/uapi/asm/opal-prd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * OPAL Runtime Diagnostics interface driver * Supported on POWERNV platform diff --git a/arch/powerpc/include/uapi/asm/perf_event.h b/arch/powerpc/include/uapi/asm/perf_event.h index 80a4d40cf5bc..ce488e48db44 100644 --- a/arch/powerpc/include/uapi/asm/perf_event.h +++ b/arch/powerpc/include/uapi/asm/perf_event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2013 Michael Ellerman, IBM Corp. * diff --git a/arch/powerpc/include/uapi/asm/perf_regs.h b/arch/powerpc/include/uapi/asm/perf_regs.h index 6a93209748a1..9e52c86ccbd3 100644 --- a/arch/powerpc/include/uapi/asm/perf_regs.h +++ b/arch/powerpc/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_POWERPC_PERF_REGS_H #define _UAPI_ASM_POWERPC_PERF_REGS_H diff --git a/arch/powerpc/include/uapi/asm/posix_types.h b/arch/powerpc/include/uapi/asm/posix_types.h index 2958c5b97b2d..f698400e4bb0 100644 --- a/arch/powerpc/include/uapi/asm/posix_types.h +++ b/arch/powerpc/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_POSIX_TYPES_H #define _ASM_POWERPC_POSIX_TYPES_H diff --git a/arch/powerpc/include/uapi/asm/ps3fb.h b/arch/powerpc/include/uapi/asm/ps3fb.h index e7233a849680..fd7e3a0d35d5 100644 --- a/arch/powerpc/include/uapi/asm/ps3fb.h +++ b/arch/powerpc/include/uapi/asm/ps3fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2006 Sony Computer Entertainment Inc. * Copyright 2006, 2007 Sony Corporation diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h index 8036b385417d..5e3edc2a7634 100644 --- a/arch/powerpc/include/uapi/asm/ptrace.h +++ b/arch/powerpc/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Copyright (C) 2001 PPC64 Team, IBM Corp * diff --git a/arch/powerpc/include/uapi/asm/sembuf.h b/arch/powerpc/include/uapi/asm/sembuf.h index 99a41938ae3d..8f393d60f02d 100644 --- a/arch/powerpc/include/uapi/asm/sembuf.h +++ b/arch/powerpc/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_SEMBUF_H #define _ASM_POWERPC_SEMBUF_H diff --git a/arch/powerpc/include/uapi/asm/setup.h b/arch/powerpc/include/uapi/asm/setup.h index ae3fb68cb28e..c54940b09d06 100644 --- a/arch/powerpc/include/uapi/asm/setup.h +++ b/arch/powerpc/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_POWERPC_SETUP_H #define _UAPI_ASM_POWERPC_SETUP_H diff --git a/arch/powerpc/include/uapi/asm/shmbuf.h b/arch/powerpc/include/uapi/asm/shmbuf.h index 8efa39698b6c..deb1c3e503d3 100644 --- a/arch/powerpc/include/uapi/asm/shmbuf.h +++ b/arch/powerpc/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_SHMBUF_H #define _ASM_POWERPC_SHMBUF_H diff --git a/arch/powerpc/include/uapi/asm/sigcontext.h b/arch/powerpc/include/uapi/asm/sigcontext.h index 3ad0c7f001a9..2fbe485acdb4 100644 --- a/arch/powerpc/include/uapi/asm/sigcontext.h +++ b/arch/powerpc/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_SIGCONTEXT_H #define _ASM_POWERPC_SIGCONTEXT_H diff --git a/arch/powerpc/include/uapi/asm/siginfo.h b/arch/powerpc/include/uapi/asm/siginfo.h index ccce3ef5cd86..1a691141e49f 100644 --- a/arch/powerpc/include/uapi/asm/siginfo.h +++ b/arch/powerpc/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_SIGINFO_H #define _ASM_POWERPC_SIGINFO_H diff --git a/arch/powerpc/include/uapi/asm/signal.h b/arch/powerpc/include/uapi/asm/signal.h index 6c69ee94fd8d..85b0a7aa43e7 100644 --- a/arch/powerpc/include/uapi/asm/signal.h +++ b/arch/powerpc/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_POWERPC_SIGNAL_H #define _UAPI_ASM_POWERPC_SIGNAL_H diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index 3c590c7c42c0..94de465e0920 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_SOCKET_H #define _ASM_POWERPC_SOCKET_H diff --git a/arch/powerpc/include/uapi/asm/spu_info.h b/arch/powerpc/include/uapi/asm/spu_info.h index ed071bf97707..cabfcbba9eac 100644 --- a/arch/powerpc/include/uapi/asm/spu_info.h +++ b/arch/powerpc/include/uapi/asm/spu_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * SPU info structures * diff --git a/arch/powerpc/include/uapi/asm/stat.h b/arch/powerpc/include/uapi/asm/stat.h index 84880b80cc1c..afd25f2ff4e8 100644 --- a/arch/powerpc/include/uapi/asm/stat.h +++ b/arch/powerpc/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_STAT_H #define _ASM_POWERPC_STAT_H /* diff --git a/arch/powerpc/include/uapi/asm/swab.h b/arch/powerpc/include/uapi/asm/swab.h index b6c368aa5c05..17b16c44d20c 100644 --- a/arch/powerpc/include/uapi/asm/swab.h +++ b/arch/powerpc/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h index 549d700e18f2..ed18bc61f63d 100644 --- a/arch/powerpc/include/uapi/asm/termbits.h +++ b/arch/powerpc/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_TERMBITS_H #define _ASM_POWERPC_TERMBITS_H diff --git a/arch/powerpc/include/uapi/asm/termios.h b/arch/powerpc/include/uapi/asm/termios.h index 6cca5cdfec04..5d07fc89bcb6 100644 --- a/arch/powerpc/include/uapi/asm/termios.h +++ b/arch/powerpc/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Liberally adapted from alpha/termios.h. In particular, the c_cc[] * fields have been reordered so that termio & termios share the diff --git a/arch/powerpc/include/uapi/asm/tm.h b/arch/powerpc/include/uapi/asm/tm.h index 5047659815a5..e1bf0e2fac43 100644 --- a/arch/powerpc/include/uapi/asm/tm.h +++ b/arch/powerpc/include/uapi/asm/tm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_TM_H #define _ASM_POWERPC_TM_H diff --git a/arch/powerpc/include/uapi/asm/types.h b/arch/powerpc/include/uapi/asm/types.h index 4b8ab990a3c1..327616fb70e4 100644 --- a/arch/powerpc/include/uapi/asm/types.h +++ b/arch/powerpc/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * This file is never included by application software unless * explicitly requested (e.g., via linux/types.h) in which case the diff --git a/arch/powerpc/include/uapi/asm/ucontext.h b/arch/powerpc/include/uapi/asm/ucontext.h index d9a4ddf0cc86..6f14a96d4985 100644 --- a/arch/powerpc/include/uapi/asm/ucontext.h +++ b/arch/powerpc/include/uapi/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_POWERPC_UCONTEXT_H #define _ASM_POWERPC_UCONTEXT_H diff --git a/arch/powerpc/include/uapi/asm/unistd.h b/arch/powerpc/include/uapi/asm/unistd.h index b85f14228857..df8684f31919 100644 --- a/arch/powerpc/include/uapi/asm/unistd.h +++ b/arch/powerpc/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * This file contains the system call numbers. * diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 4aa7c147e447..6c6cce937dd8 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # @@ -38,7 +39,7 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o nvram_64.o firmware.o obj-$(CONFIG_VDSO32) += vdso32/ -obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog.o +obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o @@ -83,7 +84,7 @@ extra-y := head_$(BITS).o extra-$(CONFIG_40x) := head_40x.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o -extra-$(CONFIG_8xx) := head_8xx.o +extra-$(CONFIG_PPC_8xx) := head_8xx.o extra-y += vmlinux.lds obj-$(CONFIG_RELOCATABLE) += reloc_$(BITS).o diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index ec7a8b099dd9..3e6c0744c174 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -27,6 +27,7 @@ #include #include #include +#include struct aligninfo { unsigned char len; @@ -40,364 +41,9 @@ struct aligninfo { #define LD 0 /* load */ #define ST 1 /* store */ #define SE 2 /* sign-extend value, or FP ld/st as word */ -#define F 4 /* to/from fp regs */ -#define U 8 /* update index register */ -#define M 0x10 /* multiple load/store */ #define SW 0x20 /* byte swap */ -#define S 0x40 /* single-precision fp or... */ -#define SX 0x40 /* ... byte count in XER */ -#define HARD 0x80 /* string, stwcx. */ #define E4 0x40 /* SPE endianness is word */ #define E8 0x80 /* SPE endianness is double word */ -#define SPLT 0x80 /* VSX SPLAT load */ - -/* DSISR bits reported for a DCBZ instruction: */ -#define DCBZ 0x5f /* 8xx/82xx dcbz faults when cache not enabled */ - -/* - * The PowerPC stores certain bits of the instruction that caused the - * alignment exception in the DSISR register. This array maps those - * bits to information about the operand length and what the - * instruction would do. - */ -static struct aligninfo aligninfo[128] = { - { 4, LD }, /* 00 0 0000: lwz / lwarx */ - INVALID, /* 00 0 0001 */ - { 4, ST }, /* 00 0 0010: stw */ - INVALID, /* 00 0 0011 */ - { 2, LD }, /* 00 0 0100: lhz */ - { 2, LD+SE }, /* 00 0 0101: lha */ - { 2, ST }, /* 00 0 0110: sth */ - { 4, LD+M }, /* 00 0 0111: lmw */ - { 4, LD+F+S }, /* 00 0 1000: lfs */ - { 8, LD+F }, /* 00 0 1001: lfd */ - { 4, ST+F+S }, /* 00 0 1010: stfs */ - { 8, ST+F }, /* 00 0 1011: stfd */ - { 16, LD }, /* 00 0 1100: lq */ - { 8, LD }, /* 00 0 1101: ld/ldu/lwa */ - INVALID, /* 00 0 1110 */ - { 8, ST }, /* 00 0 1111: std/stdu */ - { 4, LD+U }, /* 00 1 0000: lwzu */ - INVALID, /* 00 1 0001 */ - { 4, ST+U }, /* 00 1 0010: stwu */ - INVALID, /* 00 1 0011 */ - { 2, LD+U }, /* 00 1 0100: lhzu */ - { 2, LD+SE+U }, /* 00 1 0101: lhau */ - { 2, ST+U }, /* 00 1 0110: sthu */ - { 4, ST+M }, /* 00 1 0111: stmw */ - { 4, LD+F+S+U }, /* 00 1 1000: lfsu */ - { 8, LD+F+U }, /* 00 1 1001: lfdu */ - { 4, ST+F+S+U }, /* 00 1 1010: stfsu */ - { 8, ST+F+U }, /* 00 1 1011: stfdu */ - { 16, LD+F }, /* 00 1 1100: lfdp */ - INVALID, /* 00 1 1101 */ - { 16, ST+F }, /* 00 1 1110: stfdp */ - INVALID, /* 00 1 1111 */ - { 8, LD }, /* 01 0 0000: ldx */ - INVALID, /* 01 0 0001 */ - { 8, ST }, /* 01 0 0010: stdx */ - INVALID, /* 01 0 0011 */ - INVALID, /* 01 0 0100 */ - { 4, LD+SE }, /* 01 0 0101: lwax */ - INVALID, /* 01 0 0110 */ - INVALID, /* 01 0 0111 */ - { 4, LD+M+HARD+SX }, /* 01 0 1000: lswx */ - { 4, LD+M+HARD }, /* 01 0 1001: lswi */ - { 4, ST+M+HARD+SX }, /* 01 0 1010: stswx */ - { 4, ST+M+HARD }, /* 01 0 1011: stswi */ - INVALID, /* 01 0 1100 */ - { 8, LD+U }, /* 01 0 1101: ldu */ - INVALID, /* 01 0 1110 */ - { 8, ST+U }, /* 01 0 1111: stdu */ - { 8, LD+U }, /* 01 1 0000: ldux */ - INVALID, /* 01 1 0001 */ - { 8, ST+U }, /* 01 1 0010: stdux */ - INVALID, /* 01 1 0011 */ - INVALID, /* 01 1 0100 */ - { 4, LD+SE+U }, /* 01 1 0101: lwaux */ - INVALID, /* 01 1 0110 */ - INVALID, /* 01 1 0111 */ - INVALID, /* 01 1 1000 */ - INVALID, /* 01 1 1001 */ - INVALID, /* 01 1 1010 */ - INVALID, /* 01 1 1011 */ - INVALID, /* 01 1 1100 */ - INVALID, /* 01 1 1101 */ - INVALID, /* 01 1 1110 */ - INVALID, /* 01 1 1111 */ - INVALID, /* 10 0 0000 */ - INVALID, /* 10 0 0001 */ - INVALID, /* 10 0 0010: stwcx. */ - INVALID, /* 10 0 0011 */ - INVALID, /* 10 0 0100 */ - INVALID, /* 10 0 0101 */ - INVALID, /* 10 0 0110 */ - INVALID, /* 10 0 0111 */ - { 4, LD+SW }, /* 10 0 1000: lwbrx */ - INVALID, /* 10 0 1001 */ - { 4, ST+SW }, /* 10 0 1010: stwbrx */ - INVALID, /* 10 0 1011 */ - { 2, LD+SW }, /* 10 0 1100: lhbrx */ - { 4, LD+SE }, /* 10 0 1101 lwa */ - { 2, ST+SW }, /* 10 0 1110: sthbrx */ - { 16, ST }, /* 10 0 1111: stq */ - INVALID, /* 10 1 0000 */ - INVALID, /* 10 1 0001 */ - INVALID, /* 10 1 0010 */ - INVALID, /* 10 1 0011 */ - INVALID, /* 10 1 0100 */ - INVALID, /* 10 1 0101 */ - INVALID, /* 10 1 0110 */ - INVALID, /* 10 1 0111 */ - INVALID, /* 10 1 1000 */ - INVALID, /* 10 1 1001 */ - INVALID, /* 10 1 1010 */ - INVALID, /* 10 1 1011 */ - INVALID, /* 10 1 1100 */ - INVALID, /* 10 1 1101 */ - INVALID, /* 10 1 1110 */ - { 0, ST+HARD }, /* 10 1 1111: dcbz */ - { 4, LD }, /* 11 0 0000: lwzx */ - INVALID, /* 11 0 0001 */ - { 4, ST }, /* 11 0 0010: stwx */ - INVALID, /* 11 0 0011 */ - { 2, LD }, /* 11 0 0100: lhzx */ - { 2, LD+SE }, /* 11 0 0101: lhax */ - { 2, ST }, /* 11 0 0110: sthx */ - INVALID, /* 11 0 0111 */ - { 4, LD+F+S }, /* 11 0 1000: lfsx */ - { 8, LD+F }, /* 11 0 1001: lfdx */ - { 4, ST+F+S }, /* 11 0 1010: stfsx */ - { 8, ST+F }, /* 11 0 1011: stfdx */ - { 16, LD+F }, /* 11 0 1100: lfdpx */ - { 4, LD+F+SE }, /* 11 0 1101: lfiwax */ - { 16, ST+F }, /* 11 0 1110: stfdpx */ - { 4, ST+F }, /* 11 0 1111: stfiwx */ - { 4, LD+U }, /* 11 1 0000: lwzux */ - INVALID, /* 11 1 0001 */ - { 4, ST+U }, /* 11 1 0010: stwux */ - INVALID, /* 11 1 0011 */ - { 2, LD+U }, /* 11 1 0100: lhzux */ - { 2, LD+SE+U }, /* 11 1 0101: lhaux */ - { 2, ST+U }, /* 11 1 0110: sthux */ - INVALID, /* 11 1 0111 */ - { 4, LD+F+S+U }, /* 11 1 1000: lfsux */ - { 8, LD+F+U }, /* 11 1 1001: lfdux */ - { 4, ST+F+S+U }, /* 11 1 1010: stfsux */ - { 8, ST+F+U }, /* 11 1 1011: stfdux */ - INVALID, /* 11 1 1100 */ - { 4, LD+F }, /* 11 1 1101: lfiwzx */ - INVALID, /* 11 1 1110 */ - INVALID, /* 11 1 1111 */ -}; - -/* - * The dcbz (data cache block zero) instruction - * gives an alignment fault if used on non-cacheable - * memory. We handle the fault mainly for the - * case when we are running with the cache disabled - * for debugging. - */ -static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) -{ - long __user *p; - int i, size; - -#ifdef __powerpc64__ - size = ppc64_caches.l1d.block_size; -#else - size = L1_CACHE_BYTES; -#endif - p = (long __user *) (regs->dar & -size); - if (user_mode(regs) && !access_ok(VERIFY_WRITE, p, size)) - return -EFAULT; - for (i = 0; i < size / sizeof(long); ++i) - if (__put_user_inatomic(0, p+i)) - return -EFAULT; - return 1; -} - -/* - * Emulate load & store multiple instructions - * On 64-bit machines, these instructions only affect/use the - * bottom 4 bytes of each register, and the loads clear the - * top 4 bytes of the affected register. - */ -#ifdef __BIG_ENDIAN__ -#ifdef CONFIG_PPC64 -#define REG_BYTE(rp, i) *((u8 *)((rp) + ((i) >> 2)) + ((i) & 3) + 4) -#else -#define REG_BYTE(rp, i) *((u8 *)(rp) + (i)) -#endif -#else -#define REG_BYTE(rp, i) (*(((u8 *)((rp) + ((i)>>2)) + ((i)&3)))) -#endif - -#define SWIZ_PTR(p) ((unsigned char __user *)((p) ^ swiz)) - -static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, - unsigned int reg, unsigned int nb, - unsigned int flags, unsigned int instr, - unsigned long swiz) -{ - unsigned long *rptr; - unsigned int nb0, i, bswiz; - unsigned long p; - - /* - * We do not try to emulate 8 bytes multiple as they aren't really - * available in our operating environments and we don't try to - * emulate multiples operations in kernel land as they should never - * be used/generated there at least not on unaligned boundaries - */ - if (unlikely((nb > 4) || !user_mode(regs))) - return 0; - - /* lmw, stmw, lswi/x, stswi/x */ - nb0 = 0; - if (flags & HARD) { - if (flags & SX) { - nb = regs->xer & 127; - if (nb == 0) - return 1; - } else { - unsigned long pc = regs->nip ^ (swiz & 4); - - if (__get_user_inatomic(instr, - (unsigned int __user *)pc)) - return -EFAULT; - if (swiz == 0 && (flags & SW)) - instr = cpu_to_le32(instr); - nb = (instr >> 11) & 0x1f; - if (nb == 0) - nb = 32; - } - if (nb + reg * 4 > 128) { - nb0 = nb + reg * 4 - 128; - nb = 128 - reg * 4; - } -#ifdef __LITTLE_ENDIAN__ - /* - * String instructions are endian neutral but the code - * below is not. Force byte swapping on so that the - * effects of swizzling are undone in the load/store - * loops below. - */ - flags ^= SW; -#endif - } else { - /* lwm, stmw */ - nb = (32 - reg) * 4; - } - - if (!access_ok((flags & ST ? VERIFY_WRITE: VERIFY_READ), addr, nb+nb0)) - return -EFAULT; /* bad address */ - - rptr = ®s->gpr[reg]; - p = (unsigned long) addr; - bswiz = (flags & SW)? 3: 0; - - if (!(flags & ST)) { - /* - * This zeroes the top 4 bytes of the affected registers - * in 64-bit mode, and also zeroes out any remaining - * bytes of the last register for lsw*. - */ - memset(rptr, 0, ((nb + 3) / 4) * sizeof(unsigned long)); - if (nb0 > 0) - memset(®s->gpr[0], 0, - ((nb0 + 3) / 4) * sizeof(unsigned long)); - - for (i = 0; i < nb; ++i, ++p) - if (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - if (nb0 > 0) { - rptr = ®s->gpr[0]; - addr += nb; - for (i = 0; i < nb0; ++i, ++p) - if (__get_user_inatomic(REG_BYTE(rptr, - i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - } - - } else { - for (i = 0; i < nb; ++i, ++p) - if (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - if (nb0 > 0) { - rptr = ®s->gpr[0]; - addr += nb; - for (i = 0; i < nb0; ++i, ++p) - if (__put_user_inatomic(REG_BYTE(rptr, - i ^ bswiz), - SWIZ_PTR(p))) - return -EFAULT; - } - } - return 1; -} - -/* - * Emulate floating-point pair loads and stores. - * Only POWER6 has these instructions, and it does true little-endian, - * so we don't need the address swizzling. - */ -static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, - unsigned int flags) -{ - char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); - char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); - int i, ret, sw = 0; - - if (reg & 1) - return 0; /* invalid form: FRS/FRT must be even */ - if (flags & SW) - sw = 7; - ret = 0; - for (i = 0; i < 8; ++i) { - if (!(flags & ST)) { - ret |= __get_user(ptr0[i^sw], addr + i); - ret |= __get_user(ptr1[i^sw], addr + i + 8); - } else { - ret |= __put_user(ptr0[i^sw], addr + i); - ret |= __put_user(ptr1[i^sw], addr + i + 8); - } - } - if (ret) - return -EFAULT; - return 1; /* exception handled and fixed up */ -} - -#ifdef CONFIG_PPC64 -static int emulate_lq_stq(struct pt_regs *regs, unsigned char __user *addr, - unsigned int reg, unsigned int flags) -{ - char *ptr0 = (char *)®s->gpr[reg]; - char *ptr1 = (char *)®s->gpr[reg+1]; - int i, ret, sw = 0; - - if (reg & 1) - return 0; /* invalid form: GPR must be even */ - if (flags & SW) - sw = 7; - ret = 0; - for (i = 0; i < 8; ++i) { - if (!(flags & ST)) { - ret |= __get_user(ptr0[i^sw], addr + i); - ret |= __get_user(ptr1[i^sw], addr + i + 8); - } else { - ret |= __put_user(ptr0[i^sw], addr + i); - ret |= __put_user(ptr1[i^sw], addr + i + 8); - } - } - if (ret) - return -EFAULT; - return 1; /* exception handled and fixed up */ -} -#endif /* CONFIG_PPC64 */ #ifdef CONFIG_SPE @@ -636,133 +282,21 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, } #endif /* CONFIG_SPE */ -#ifdef CONFIG_VSX -/* - * Emulate VSX instructions... - */ -static int emulate_vsx(unsigned char __user *addr, unsigned int reg, - unsigned int areg, struct pt_regs *regs, - unsigned int flags, unsigned int length, - unsigned int elsize) -{ - char *ptr; - unsigned long *lptr; - int ret = 0; - int sw = 0; - int i, j; - - /* userland only */ - if (unlikely(!user_mode(regs))) - return 0; - - flush_vsx_to_thread(current); - - if (reg < 32) - ptr = (char *) ¤t->thread.fp_state.fpr[reg][0]; - else - ptr = (char *) ¤t->thread.vr_state.vr[reg - 32]; - - lptr = (unsigned long *) ptr; - -#ifdef __LITTLE_ENDIAN__ - if (flags & SW) { - elsize = length; - sw = length-1; - } else { - /* - * The elements are BE ordered, even in LE mode, so process - * them in reverse order. - */ - addr += length - elsize; - - /* 8 byte memory accesses go in the top 8 bytes of the VR */ - if (length == 8) - ptr += 8; - } -#else - if (flags & SW) - sw = elsize-1; -#endif - - for (j = 0; j < length; j += elsize) { - for (i = 0; i < elsize; ++i) { - if (flags & ST) - ret |= __put_user(ptr[i^sw], addr + i); - else - ret |= __get_user(ptr[i^sw], addr + i); - } - ptr += elsize; -#ifdef __LITTLE_ENDIAN__ - addr -= elsize; -#else - addr += elsize; -#endif - } - -#ifdef __BIG_ENDIAN__ -#define VSX_HI 0 -#define VSX_LO 1 -#else -#define VSX_HI 1 -#define VSX_LO 0 -#endif - - if (!ret) { - if (flags & U) - regs->gpr[areg] = regs->dar; - - /* Splat load copies the same data to top and bottom 8 bytes */ - if (flags & SPLT) - lptr[VSX_LO] = lptr[VSX_HI]; - /* For 8 byte loads, zero the low 8 bytes */ - else if (!(flags & ST) && (8 == length)) - lptr[VSX_LO] = 0; - } else - return -EFAULT; - - return 1; -} -#endif - /* * Called on alignment exception. Attempts to fixup * * Return 1 on success * Return 0 if unable to handle the interrupt * Return -EFAULT if data address is bad + * Other negative return values indicate that the instruction can't + * be emulated, and the process should be given a SIGBUS. */ int fix_alignment(struct pt_regs *regs) { - unsigned int instr, nb, flags, instruction = 0; - unsigned int reg, areg; - unsigned int dsisr; - unsigned char __user *addr; - unsigned long p, swiz; - int ret, i; - union data { - u64 ll; - double dd; - unsigned char v[8]; - struct { -#ifdef __LITTLE_ENDIAN__ - int low32; - unsigned hi32; -#else - unsigned hi32; - int low32; -#endif - } x32; - struct { -#ifdef __LITTLE_ENDIAN__ - short low16; - unsigned char hi48[6]; -#else - unsigned char hi48[6]; - short low16; -#endif - } x16; - } data; + unsigned int instr; + struct instruction_op op; + int r, type; /* * We require a complete register set, if not, then our assembly @@ -770,121 +304,23 @@ int fix_alignment(struct pt_regs *regs) */ CHECK_FULL_REGS(regs); - dsisr = regs->dsisr; - - /* Some processors don't provide us with a DSISR we can use here, - * let's make one up from the instruction - */ - if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) { - unsigned long pc = regs->nip; - - if (cpu_has_feature(CPU_FTR_PPC_LE) && (regs->msr & MSR_LE)) - pc ^= 4; - if (unlikely(__get_user_inatomic(instr, - (unsigned int __user *)pc))) - return -EFAULT; - if (cpu_has_feature(CPU_FTR_REAL_LE) && (regs->msr & MSR_LE)) - instr = cpu_to_le32(instr); - dsisr = make_dsisr(instr); - instruction = instr; + if (unlikely(__get_user(instr, (unsigned int __user *)regs->nip))) + return -EFAULT; + if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { + /* We don't handle PPC little-endian any more... */ + if (cpu_has_feature(CPU_FTR_PPC_LE)) + return -EIO; + instr = swab32(instr); } - /* extract the operation and registers from the dsisr */ - reg = (dsisr >> 5) & 0x1f; /* source/dest register */ - areg = dsisr & 0x1f; /* register to update */ - #ifdef CONFIG_SPE if ((instr >> 26) == 0x4) { + int reg = (instr >> 21) & 0x1f; PPC_WARN_ALIGNMENT(spe, regs); return emulate_spe(regs, reg, instr); } #endif - instr = (dsisr >> 10) & 0x7f; - instr |= (dsisr >> 13) & 0x60; - - /* Lookup the operation in our table */ - nb = aligninfo[instr].len; - flags = aligninfo[instr].flags; - - /* - * Handle some cases which give overlaps in the DSISR values. - */ - if (IS_XFORM(instruction)) { - switch (get_xop(instruction)) { - case 532: /* ldbrx */ - nb = 8; - flags = LD+SW; - break; - case 660: /* stdbrx */ - nb = 8; - flags = ST+SW; - break; - case 20: /* lwarx */ - case 84: /* ldarx */ - case 116: /* lharx */ - case 276: /* lqarx */ - return 0; /* not emulated ever */ - } - } - - /* Byteswap little endian loads and stores */ - swiz = 0; - if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { - flags ^= SW; -#ifdef __BIG_ENDIAN__ - /* - * So-called "PowerPC little endian" mode works by - * swizzling addresses rather than by actually doing - * any byte-swapping. To emulate this, we XOR each - * byte address with 7. We also byte-swap, because - * the processor's address swizzling depends on the - * operand size (it xors the address with 7 for bytes, - * 6 for halfwords, 4 for words, 0 for doublewords) but - * we will xor with 7 and load/store each byte separately. - */ - if (cpu_has_feature(CPU_FTR_PPC_LE)) - swiz = 7; -#endif - } - - /* DAR has the operand effective address */ - addr = (unsigned char __user *)regs->dar; - -#ifdef CONFIG_VSX - if ((instruction & 0xfc00003e) == 0x7c000018) { - unsigned int elsize; - - /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */ - reg |= (instruction & 0x1) << 5; - /* Simple inline decoder instead of a table */ - /* VSX has only 8 and 16 byte memory accesses */ - nb = 8; - if (instruction & 0x200) - nb = 16; - - /* Vector stores in little-endian mode swap individual - elements, so process them separately */ - elsize = 4; - if (instruction & 0x80) - elsize = 8; - - flags = 0; - if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) - flags |= SW; - if (instruction & 0x100) - flags |= ST; - if (instruction & 0x040) - flags |= U; - /* splat load needs a special decoder */ - if ((instruction & 0x400) == 0){ - flags |= SPLT; - nb = 8; - } - PPC_WARN_ALIGNMENT(vsx, regs); - return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize); - } -#endif /* * ISA 3.0 (such as P9) copy, copy_first, paste and paste_last alignment @@ -896,173 +332,27 @@ int fix_alignment(struct pt_regs *regs) * when pasting to a co-processor. Furthermore, paste_last is the * synchronisation point for preceding copy/paste sequences. */ - if ((instruction & 0xfc0006fe) == PPC_INST_COPY) + if ((instr & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe)) return -EIO; - /* A size of 0 indicates an instruction we don't support, with - * the exception of DCBZ which is handled as a special case here - */ - if (instr == DCBZ) { + r = analyse_instr(&op, regs, instr); + if (r < 0) + return -EINVAL; + + type = op.type & INSTR_TYPE_MASK; + if (!OP_IS_LOAD_STORE(type)) { + if (op.type != CACHEOP + DCBZ) + return -EINVAL; PPC_WARN_ALIGNMENT(dcbz, regs); - return emulate_dcbz(regs, addr); - } - if (unlikely(nb == 0)) - return 0; - - /* Load/Store Multiple instructions are handled in their own - * function - */ - if (flags & M) { - PPC_WARN_ALIGNMENT(multiple, regs); - return emulate_multiple(regs, addr, reg, nb, - flags, instr, swiz); + r = emulate_dcbz(op.ea, regs); + } else { + if (type == LARX || type == STCX) + return -EIO; + PPC_WARN_ALIGNMENT(unaligned, regs); + r = emulate_loadstore(regs, &op); } - /* Verify the address of the operand */ - if (unlikely(user_mode(regs) && - !access_ok((flags & ST ? VERIFY_WRITE : VERIFY_READ), - addr, nb))) - return -EFAULT; - - /* Force the fprs into the save area so we can reference them */ - if (flags & F) { - /* userland only */ - if (unlikely(!user_mode(regs))) - return 0; - flush_fp_to_thread(current); - } - - if (nb == 16) { - if (flags & F) { - /* Special case for 16-byte FP loads and stores */ - PPC_WARN_ALIGNMENT(fp_pair, regs); - return emulate_fp_pair(addr, reg, flags); - } else { -#ifdef CONFIG_PPC64 - /* Special case for 16-byte loads and stores */ - PPC_WARN_ALIGNMENT(lq_stq, regs); - return emulate_lq_stq(regs, addr, reg, flags); -#else - return 0; -#endif - } - } - - PPC_WARN_ALIGNMENT(unaligned, regs); - - /* If we are loading, get the data from user space, else - * get it from register values - */ - if (!(flags & ST)) { - unsigned int start = 0; - - switch (nb) { - case 4: - start = offsetof(union data, x32.low32); - break; - case 2: - start = offsetof(union data, x16.low16); - break; - } - - data.ll = 0; - ret = 0; - p = (unsigned long)addr; - - for (i = 0; i < nb; i++) - ret |= __get_user_inatomic(data.v[start + i], - SWIZ_PTR(p++)); - - if (unlikely(ret)) - return -EFAULT; - - } else if (flags & F) { - data.ll = current->thread.TS_FPR(reg); - if (flags & S) { - /* Single-precision FP store requires conversion... */ -#ifdef CONFIG_PPC_FPU - preempt_disable(); - enable_kernel_fp(); - cvt_df(&data.dd, (float *)&data.x32.low32); - disable_kernel_fp(); - preempt_enable(); -#else - return 0; -#endif - } - } else - data.ll = regs->gpr[reg]; - - if (flags & SW) { - switch (nb) { - case 8: - data.ll = swab64(data.ll); - break; - case 4: - data.x32.low32 = swab32(data.x32.low32); - break; - case 2: - data.x16.low16 = swab16(data.x16.low16); - break; - } - } - - /* Perform other misc operations like sign extension - * or floating point single precision conversion - */ - switch (flags & ~(U|SW)) { - case LD+SE: /* sign extending integer loads */ - case LD+F+SE: /* sign extend for lfiwax */ - if ( nb == 2 ) - data.ll = data.x16.low16; - else /* nb must be 4 */ - data.ll = data.x32.low32; - break; - - /* Single-precision FP load requires conversion... */ - case LD+F+S: -#ifdef CONFIG_PPC_FPU - preempt_disable(); - enable_kernel_fp(); - cvt_fd((float *)&data.x32.low32, &data.dd); - disable_kernel_fp(); - preempt_enable(); -#else - return 0; -#endif - break; - } - - /* Store result to memory or update registers */ - if (flags & ST) { - unsigned int start = 0; - - switch (nb) { - case 4: - start = offsetof(union data, x32.low32); - break; - case 2: - start = offsetof(union data, x16.low16); - break; - } - - ret = 0; - p = (unsigned long)addr; - - for (i = 0; i < nb; i++) - ret |= __put_user_inatomic(data.v[start + i], - SWIZ_PTR(p++)); - - if (unlikely(ret)) - return -EFAULT; - } else if (flags & F) - current->thread.TS_FPR(reg) = data.ll; - else - regs->gpr[reg] = data.ll; - - /* Update RA as needed */ - if (flags & U) - regs->gpr[areg] = regs->dar; - - return 1; + if (!r) + return 1; + return r; } diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 6e95c2c19a7e..8cfb20e38cfe 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -746,6 +746,14 @@ int main(void) OFFSET(PACA_SUBCORE_SIBLING_MASK, paca_struct, subcore_sibling_mask); OFFSET(PACA_SIBLING_PACA_PTRS, paca_struct, thread_sibling_pacas); OFFSET(PACA_REQ_PSSCR, paca_struct, requested_psscr); +#define STOP_SPR(x, f) OFFSET(x, paca_struct, stop_sprs.f) + STOP_SPR(STOP_PID, pid); + STOP_SPR(STOP_LDBAR, ldbar); + STOP_SPR(STOP_FSCR, fscr); + STOP_SPR(STOP_HFSCR, hfscr); + STOP_SPR(STOP_MMCR1, mmcr1); + STOP_SPR(STOP_MMCR2, mmcr2); + STOP_SPR(STOP_MMCRA, mmcra); #endif DEFINE(PPC_DBELL_SERVER, PPC_DBELL_SERVER); diff --git a/arch/powerpc/kernel/audit.c b/arch/powerpc/kernel/audit.c index a4dab7cab348..a2dddd7f3d09 100644 --- a/arch/powerpc/kernel/audit.c +++ b/arch/powerpc/kernel/audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 8275858a434d..6537cba1a758 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Procedures for drawing on the screen early on in the boot process. * @@ -253,7 +254,7 @@ int __init btext_find_display(int allow_nonstdout) for_each_node_by_type(np, "display") { if (of_get_property(np, "linux,opened", NULL)) { - printk("trying %s ...\n", np->full_name); + printk("trying %pOF ...\n", np); rc = btext_initialize(np); printk("result: %d\n", rc); } diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index c641983bbdd6..a8f20e5928e1 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -167,10 +167,10 @@ static void release_cache_debugcheck(struct cache *cache) list_for_each_entry(iter, &cache_list, list) WARN_ONCE(iter->next_local == cache, - "cache for %s(%s) refers to cache for %s(%s)\n", - iter->ofnode->full_name, + "cache for %pOF(%s) refers to cache for %pOF(%s)\n", + iter->ofnode, cache_type_string(iter), - cache->ofnode->full_name, + cache->ofnode, cache_type_string(cache)); } @@ -179,8 +179,8 @@ static void release_cache(struct cache *cache) if (!cache) return; - pr_debug("freeing L%d %s cache for %s\n", cache->level, - cache_type_string(cache), cache->ofnode->full_name); + pr_debug("freeing L%d %s cache for %pOF\n", cache->level, + cache_type_string(cache), cache->ofnode); release_cache_debugcheck(cache); list_del(&cache->list); @@ -194,8 +194,8 @@ static void cache_cpu_set(struct cache *cache, int cpu) while (next) { WARN_ONCE(cpumask_test_cpu(cpu, &next->shared_cpu_map), - "CPU %i already accounted in %s(%s)\n", - cpu, next->ofnode->full_name, + "CPU %i already accounted in %pOF(%s)\n", + cpu, next->ofnode, cache_type_string(next)); cpumask_set_cpu(cpu, &next->shared_cpu_map); next = next->next_local; @@ -355,7 +355,7 @@ static int cache_is_unified_d(const struct device_node *np) */ static struct cache *cache_do_one_devnode_unified(struct device_node *node, int level) { - pr_debug("creating L%d ucache for %s\n", level, node->full_name); + pr_debug("creating L%d ucache for %pOF\n", level, node); return new_cache(cache_is_unified_d(node), level, node); } @@ -365,8 +365,8 @@ static struct cache *cache_do_one_devnode_split(struct device_node *node, { struct cache *dcache, *icache; - pr_debug("creating L%d dcache and icache for %s\n", level, - node->full_name); + pr_debug("creating L%d dcache and icache for %pOF\n", level, + node); dcache = new_cache(CACHE_TYPE_DATA, level, node); icache = new_cache(CACHE_TYPE_INSTRUCTION, level, node); @@ -679,7 +679,6 @@ static struct kobj_type cache_index_type = { static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir) { - const char *cache_name; const char *cache_type; struct cache *cache; char *buf; @@ -690,7 +689,6 @@ static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir) return; cache = dir->cache; - cache_name = cache->ofnode->full_name; cache_type = cache_type_string(cache); /* We don't want to create an attribute that can't provide a @@ -707,14 +705,14 @@ static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir) rc = attr->show(&dir->kobj, attr, buf); if (rc <= 0) { pr_debug("not creating %s attribute for " - "%s(%s) (rc = %zd)\n", - attr->attr.name, cache_name, + "%pOF(%s) (rc = %zd)\n", + attr->attr.name, cache->ofnode, cache_type, rc); continue; } if (sysfs_create_file(&dir->kobj, &attr->attr)) - pr_debug("could not create %s attribute for %s(%s)\n", - attr->attr.name, cache_name, cache_type); + pr_debug("could not create %s attribute for %pOF(%s)\n", + attr->attr.name, cache->ofnode, cache_type); } kfree(buf); @@ -831,8 +829,8 @@ static void cache_cpu_clear(struct cache *cache, int cpu) struct cache *next = cache->next_local; WARN_ONCE(!cpumask_test_cpu(cpu, &cache->shared_cpu_map), - "CPU %i not accounted in %s(%s)\n", - cpu, cache->ofnode->full_name, + "CPU %i not accounted in %pOF(%s)\n", + cpu, cache->ofnode, cache_type_string(cache)); cpumask_clear_cpu(cpu, &cache->shared_cpu_map); diff --git a/arch/powerpc/kernel/cacheinfo.h b/arch/powerpc/kernel/cacheinfo.h index a7b74d36acd7..955f5e999f1b 100644 --- a/arch/powerpc/kernel/cacheinfo.h +++ b/arch/powerpc/kernel/cacheinfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_CACHEINFO_H #define _PPC_CACHEINFO_H diff --git a/arch/powerpc/kernel/compat_audit.c b/arch/powerpc/kernel/compat_audit.c index 108ff14e2122..55c6ccda0a85 100644 --- a/arch/powerpc/kernel/compat_audit.c +++ b/arch/powerpc/kernel/compat_audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #undef __powerpc64__ #include diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 6f849832a669..760872916013 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1259,10 +1259,10 @@ static struct cpu_spec __initdata cpu_specs[] = { .platform = "ppc603", }, #endif /* CONFIG_PPC_BOOK3S_32 */ -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx { /* 8xx */ .pvr_mask = 0xffff0000, - .pvr_value = 0x00500000, + .pvr_value = PVR_8xx, .cpu_name = "8xx", /* CPU_FTR_MAYBE_CAN_DOZE is possible, * if the 8xx code is there.... */ @@ -1274,7 +1274,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_8xx, .platform = "ppc823", }, -#endif /* CONFIG_8xx */ +#endif /* CONFIG_PPC_8xx */ #ifdef CONFIG_40x { /* 403GC */ .pvr_mask = 0xffffff00, @@ -1936,6 +1936,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, +#ifdef CONFIG_PPC_47x { /* 476 DD2 core */ .pvr_mask = 0xffffffff, .pvr_value = 0x11a52080, @@ -1992,6 +1993,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_47x, .platform = "ppc470", }, +#endif /* CONFIG_PPC_47x */ { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 8f7abf9baa63..66f33e7f8d40 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation * diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 1df770e8cbe0..7275fed271af 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -102,10 +102,10 @@ static void cpufeatures_flush_tlb(void) case PVR_POWER8: case PVR_POWER8E: case PVR_POWER8NVL: - __flush_tlb_power8(POWER8_TLB_SETS); + __flush_tlb_power8(TLB_INVAL_SCOPE_GLOBAL); break; case PVR_POWER9: - __flush_tlb_power9(POWER9_TLB_SETS_HASH); + __flush_tlb_power9(TLB_INVAL_SCOPE_GLOBAL); break; default: pr_err("unknown CPU version for boot TLB flush\n"); diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 63992b2d8e15..116000b45531 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -44,6 +44,7 @@ #include #include #include +#include /** Overview: @@ -169,10 +170,10 @@ static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len) char buffer[128]; n += scnprintf(buf+n, len-n, "%04x:%02x:%02x.%01x\n", - edev->phb->global_number, pdn->busno, + pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); pr_warn("EEH: of node=%04x:%02x:%02x.%01x\n", - edev->phb->global_number, pdn->busno, + pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); eeh_ops->read_config(pdn, PCI_VENDOR_ID, 4, &cfg); @@ -352,8 +353,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) * worried about _PAGE_SPLITTING/collapse. Also we will not hit * page table free, because of init_mm. */ - ptep = __find_linux_pte_or_hugepte(init_mm.pgd, token, - NULL, &hugepage_shift); + ptep = find_init_mm_pte(token, &hugepage_shift); if (!ptep) return token; WARN_ON(hugepage_shift); @@ -435,7 +435,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) int ret; int active_flags = (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE); unsigned long flags; - struct pci_dn *pdn; + struct device_node *dn; struct pci_dev *dev; struct eeh_pe *pe, *parent_pe, *phb_pe; int rc = 0; @@ -493,9 +493,10 @@ int eeh_dev_check_failure(struct eeh_dev *edev) if (pe->state & EEH_PE_ISOLATED) { pe->check_count++; if (pe->check_count % EEH_MAX_FAILS == 0) { - pdn = eeh_dev_to_pdn(edev); - if (pdn->node) - location = of_get_property(pdn->node, "ibm,loc-code", NULL); + dn = pci_device_to_OF_node(dev); + if (dn) + location = of_get_property(dn, "ibm,loc-code", + NULL); printk(KERN_ERR "EEH: %d reads ignored for recovering device at " "location=%s driver=%s pci addr=%s\n", pe->check_count, @@ -1018,6 +1019,10 @@ int eeh_init(void) } else if ((ret = eeh_ops->init())) return ret; + /* Initialize PHB PEs */ + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) + eeh_dev_phb_init_dynamic(hose); + /* Initialize EEH event */ ret = eeh_event_init(); if (ret) @@ -1064,7 +1069,7 @@ core_initcall_sync(eeh_init); */ void eeh_add_device_early(struct pci_dn *pdn) { - struct pci_controller *phb; + struct pci_controller *phb = pdn ? pdn->phb : NULL; struct eeh_dev *edev = pdn_to_eeh_dev(pdn); if (!edev) @@ -1074,7 +1079,6 @@ void eeh_add_device_early(struct pci_dn *pdn) return; /* USB Bus children of PCI devices will not have BUID's */ - phb = edev->phb; if (NULL == phb || (eeh_has_flag(EEH_PROBE_MODE_DEVTREE) && 0 == phb->buid)) return; diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c index d6b2ca70d14d..a34e6912c15e 100644 --- a/arch/powerpc/kernel/eeh_dev.c +++ b/arch/powerpc/kernel/eeh_dev.c @@ -50,21 +50,16 @@ */ struct eeh_dev *eeh_dev_init(struct pci_dn *pdn) { - struct pci_controller *phb = pdn->phb; struct eeh_dev *edev; /* Allocate EEH device */ edev = kzalloc(sizeof(*edev), GFP_KERNEL); - if (!edev) { - pr_warn("%s: out of memory\n", - __func__); + if (!edev) return NULL; - } /* Associate EEH device with OF node */ pdn->edev = edev; edev->pdn = pdn; - edev->phb = phb; INIT_LIST_HEAD(&edev->list); INIT_LIST_HEAD(&edev->rmv_list); @@ -83,21 +78,3 @@ void eeh_dev_phb_init_dynamic(struct pci_controller *phb) /* EEH PE for PHB */ eeh_phb_pe_create(phb); } - -/** - * eeh_dev_phb_init - Create EEH devices for devices included in existing PHBs - * - * Scan all the existing PHBs and create EEH devices for their OF - * nodes and their children OF nodes - */ -static int __init eeh_dev_phb_init(void) -{ - struct pci_controller *phb, *tmp; - - list_for_each_entry_safe(phb, tmp, &hose_list, list_node) - eeh_dev_phb_init_dynamic(phb); - - return 0; -} - -core_initcall(eeh_dev_phb_init); diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index c405c79e50cd..8b840191df59 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -428,7 +428,7 @@ static void *eeh_add_virt_device(void *data, void *userdata) if (!(edev->physfn)) { pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n", - __func__, edev->phb->global_number, pdn->busno, + __func__, pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); return NULL; } diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index cc4b206f77e4..2e8d1b2b5af4 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -230,10 +230,15 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root, * Bus/Device/Function number. The extra data referred by flag * indicates which type of address should be used. */ +struct eeh_pe_get_flag { + int pe_no; + int config_addr; +}; + static void *__eeh_pe_get(void *data, void *flag) { struct eeh_pe *pe = (struct eeh_pe *)data; - struct eeh_dev *edev = (struct eeh_dev *)flag; + struct eeh_pe_get_flag *tmp = (struct eeh_pe_get_flag *) flag; /* Unexpected PHB PE */ if (pe->type & EEH_PE_PHB) @@ -244,17 +249,17 @@ static void *__eeh_pe_get(void *data, void *flag) * have non-zero PE address */ if (eeh_has_flag(EEH_VALID_PE_ZERO)) { - if (edev->pe_config_addr == pe->addr) + if (tmp->pe_no == pe->addr) return pe; } else { - if (edev->pe_config_addr && - (edev->pe_config_addr == pe->addr)) + if (tmp->pe_no && + (tmp->pe_no == pe->addr)) return pe; } /* Try BDF address */ - if (edev->config_addr && - (edev->config_addr == pe->config_addr)) + if (tmp->config_addr && + (tmp->config_addr == pe->config_addr)) return pe; return NULL; @@ -262,7 +267,9 @@ static void *__eeh_pe_get(void *data, void *flag) /** * eeh_pe_get - Search PE based on the given address - * @edev: EEH device + * @phb: PCI controller + * @pe_no: PE number + * @config_addr: Config address * * Search the corresponding PE based on the specified address which * is included in the eeh device. The function is used to check if @@ -271,12 +278,14 @@ static void *__eeh_pe_get(void *data, void *flag) * which is composed of PCI bus/device/function number, or unified * PE address. */ -struct eeh_pe *eeh_pe_get(struct eeh_dev *edev) +struct eeh_pe *eeh_pe_get(struct pci_controller *phb, + int pe_no, int config_addr) { - struct eeh_pe *root = eeh_phb_pe_get(edev->phb); + struct eeh_pe *root = eeh_phb_pe_get(phb); + struct eeh_pe_get_flag tmp = { pe_no, config_addr }; struct eeh_pe *pe; - pe = eeh_pe_traverse(root, __eeh_pe_get, edev); + pe = eeh_pe_traverse(root, __eeh_pe_get, &tmp); return pe; } @@ -330,11 +339,13 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev) int eeh_add_to_parent_pe(struct eeh_dev *edev) { struct eeh_pe *pe, *parent; + struct pci_dn *pdn = eeh_dev_to_pdn(edev); + int config_addr = (pdn->busno << 8) | (pdn->devfn); /* Check if the PE number is valid */ if (!eeh_has_flag(EEH_VALID_PE_ZERO) && !edev->pe_config_addr) { pr_err("%s: Invalid PE#0 for edev 0x%x on PHB#%x\n", - __func__, edev->config_addr, edev->phb->global_number); + __func__, config_addr, pdn->phb->global_number); return -EINVAL; } @@ -344,7 +355,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) * PE should be composed of PCI bus and its subordinate * components. */ - pe = eeh_pe_get(edev); + pe = eeh_pe_get(pdn->phb, edev->pe_config_addr, config_addr); if (pe && !(pe->type & EEH_PE_INVALID)) { /* Mark the PE as type of PCI bus */ pe->type = EEH_PE_BUS; @@ -353,11 +364,11 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) /* Put the edev to PE */ list_add_tail(&edev->list, &pe->edevs); pr_debug("EEH: Add %04x:%02x:%02x.%01x to Bus PE#%x\n", - edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF), - pe->addr); + pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn), + pe->addr); return 0; } else if (pe && (pe->type & EEH_PE_INVALID)) { list_add_tail(&edev->list, &pe->edevs); @@ -376,25 +387,25 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) pr_debug("EEH: Add %04x:%02x:%02x.%01x to Device " "PE#%x, Parent PE#%x\n", - edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF), - pe->addr, pe->parent->addr); + pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn), + pe->addr, pe->parent->addr); return 0; } /* Create a new EEH PE */ if (edev->physfn) - pe = eeh_pe_alloc(edev->phb, EEH_PE_VF); + pe = eeh_pe_alloc(pdn->phb, EEH_PE_VF); else - pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); + pe = eeh_pe_alloc(pdn->phb, EEH_PE_DEVICE); if (!pe) { pr_err("%s: out of memory!\n", __func__); return -ENOMEM; } pe->addr = edev->pe_config_addr; - pe->config_addr = edev->config_addr; + pe->config_addr = config_addr; /* * Put the new EEH PE into hierarchy tree. If the parent @@ -404,10 +415,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) */ parent = eeh_pe_get_parent(edev); if (!parent) { - parent = eeh_phb_pe_get(edev->phb); + parent = eeh_phb_pe_get(pdn->phb); if (!parent) { pr_err("%s: No PHB PE is found (PHB Domain=%d)\n", - __func__, edev->phb->global_number); + __func__, pdn->phb->global_number); edev->pe = NULL; kfree(pe); return -EEXIST; @@ -424,10 +435,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) edev->pe = pe; pr_debug("EEH: Add %04x:%02x:%02x.%01x to " "Device PE#%x, Parent PE#%x\n", - edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF), + pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn), pe->addr, pe->parent->addr); return 0; @@ -446,13 +457,14 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev) { struct eeh_pe *pe, *parent, *child; int cnt; + struct pci_dn *pdn = eeh_dev_to_pdn(edev); if (!edev->pe) { pr_debug("%s: No PE found for device %04x:%02x:%02x.%01x\n", - __func__, edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF)); + __func__, pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn)); return -EEXIST; } @@ -712,10 +724,10 @@ static void eeh_bridge_check_link(struct eeh_dev *edev) return; pr_debug("%s: Check PCIe link for %04x:%02x:%02x.%01x ...\n", - __func__, edev->phb->global_number, - edev->config_addr >> 8, - PCI_SLOT(edev->config_addr & 0xFF), - PCI_FUNC(edev->config_addr & 0xFF)); + __func__, pdn->phb->global_number, + pdn->busno, + PCI_SLOT(pdn->devfn), + PCI_FUNC(pdn->devfn)); /* Check slot status */ cap = edev->pcie_cap; diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index 1ceecdda810b..797549289798 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c @@ -51,7 +51,6 @@ static ssize_t eeh_show_##_name(struct device *dev, \ static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL); EEH_SHOW_ATTR(eeh_mode, mode, "0x%x"); -EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x"); EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); static ssize_t eeh_pe_state_show(struct device *dev, @@ -103,7 +102,6 @@ void eeh_sysfs_add_device(struct pci_dev *pdev) return; rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); - rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_state); @@ -128,7 +126,6 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev) } device_remove_file(&pdev->dev, &dev_attr_eeh_mode); - device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); device_remove_file(&pdev->dev, &dev_attr_eeh_pe_state); diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 8587059ad848..e780e1fbf6c2 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -43,6 +43,13 @@ #define LOAD_MSR_KERNEL(r, x) li r,(x) #endif +/* + * Align to 4k in order to ensure that all functions modyfing srr0/srr1 + * fit into one page in order to not encounter a TLB miss between the + * modification of srr0/srr1 and the associated rfi. + */ + .align 12 + #ifdef CONFIG_BOOKE .globl mcheck_transfer_to_handler mcheck_transfer_to_handler: @@ -586,6 +593,10 @@ ppc_swapcontext: handle_page_fault: stw r4,_DAR(r1) addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_6xx + andis. r0,r5,DSISR_DABRMATCH@h + bne- handle_dabr_fault +#endif bl do_page_fault cmpwi r3,0 beq+ ret_from_except @@ -599,6 +610,17 @@ handle_page_fault: bl bad_page_fault b ret_from_except_full +#ifdef CONFIG_6xx + /* We have a data breakpoint exception - handle it */ +handle_dabr_fault: + SAVE_NVGPRS(r1) + lwz r0,_TRAP(r1) + clrrwi r0,r0,1 + stw r0,_TRAP(r1) + bl do_break + b ret_from_except_full +#endif + /* * This routine switches between two different tasks. The process * state of one is saved on its kernel stack. Then the state diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index e925c1c99c71..4a0fd4f40245 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -966,16 +966,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) #ifdef CONFIG_PPC_BOOK3E cmpwi cr0,r3,0x280 #else - BEGIN_FTR_SECTION - cmpwi cr0,r3,0xe80 - FTR_SECTION_ELSE - cmpwi cr0,r3,0xa00 - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) + cmpwi cr0,r3,0xa00 #endif /* CONFIG_PPC_BOOK3E */ bne 1f addi r3,r1,STACK_FRAME_OVERHEAD; bl doorbell_exception - b ret_from_except #endif /* CONFIG_PPC_DOORBELL */ 1: b ret_from_except /* What else to do here ? */ @@ -1109,7 +1104,7 @@ _ASM_NOKPROBE_SYMBOL(__enter_rtas) _ASM_NOKPROBE_SYMBOL(rtas_return_loc) .align 3 -1: .llong rtas_restore_regs +1: .8byte rtas_restore_regs rtas_restore_regs: /* relocation is on at this point */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index f14f3c04ec7e..1c80bd292e48 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the 64-bit "server" PowerPC variant * of the low level exception handling including exception @@ -541,7 +542,7 @@ EXC_COMMON_BEGIN(instruction_access_common) RECONCILE_IRQ_STATE(r10, r11) ld r12,_MSR(r1) ld r3,_NIP(r1) - andis. r4,r12,0x5820 + andis. r4,r12,DSISR_BAD_FAULT_64S@h li r5,0x400 std r3,_DAR(r1) std r4,_DSISR(r1) @@ -734,7 +735,29 @@ EXC_REAL(program_check, 0x700, 0x100) EXC_VIRT(program_check, 0x4700, 0x100, 0x700) TRAMP_KVM(PACA_EXGEN, 0x700) EXC_COMMON_BEGIN(program_check_common) - EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) + /* + * It's possible to receive a TM Bad Thing type program check with + * userspace register values (in particular r1), but with SRR1 reporting + * that we came from the kernel. Normally that would confuse the bad + * stack logic, and we would report a bad kernel stack pointer. Instead + * we switch to the emergency stack if we're taking a TM Bad Thing from + * the kernel. + */ + li r10,MSR_PR /* Build a mask of MSR_PR .. */ + oris r10,r10,0x200000@h /* .. and SRR1_PROGTM */ + and r10,r10,r12 /* Mask SRR1 with that. */ + srdi r10,r10,8 /* Shift it so we can compare */ + cmpldi r10,(0x200000 >> 8) /* .. with an immediate. */ + bne 1f /* If != go to normal path. */ + + /* SRR1 had PR=0 and SRR1_PROGTM=1, so use the emergency stack */ + andi. r10,r12,MSR_PR; /* Set CR0 correctly for label */ + /* 3 in EXCEPTION_PROLOG_COMMON */ + mr r10,r1 /* Save r1 */ + ld r1,PACAEMERGSP(r13) /* Use emergency stack */ + subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ + b 3f /* Jump into the macro !! */ +1: EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD @@ -1314,7 +1337,7 @@ EXC_REAL_NONE(0x1800, 0x100) EXC_VIRT_NONE(0x5800, 0x100) #endif -#if defined(CONFIG_HARDLOCKUP_DETECTOR) && defined(CONFIG_HAVE_HARDLOCKUP_DETECTOR_ARCH) +#ifdef CONFIG_PPC_WATCHDOG #define MASKED_DEC_HANDLER_LABEL 3f @@ -1343,10 +1366,10 @@ EXC_COMMON_BEGIN(soft_nmi_common) ADD_NVGPRS;ADD_RECONCILE) b ret_from_except -#else +#else /* CONFIG_PPC_WATCHDOG */ #define MASKED_DEC_HANDLER_LABEL 2f /* normal return */ #define MASKED_DEC_HANDLER(_H) -#endif +#endif /* CONFIG_PPC_WATCHDOG */ /* * An interrupt came in while soft-disabled. We set paca->irq_happened, then: @@ -1370,19 +1393,16 @@ masked_##_H##interrupt: \ ori r10,r10,0xffff; \ mtspr SPRN_DEC,r10; \ b MASKED_DEC_HANDLER_LABEL; \ -1: cmpwi r10,PACA_IRQ_DBELL; \ - beq 2f; \ - cmpwi r10,PACA_IRQ_HMI; \ - beq 2f; \ +1: andi. r10,r10,(PACA_IRQ_DBELL|PACA_IRQ_HMI); \ + bne 2f; \ mfspr r10,SPRN_##_H##SRR1; \ - rldicl r10,r10,48,1; /* clear MSR_EE */ \ - rotldi r10,r10,16; \ + xori r10,r10,MSR_EE; /* clear MSR_EE */ \ mtspr SPRN_##_H##SRR1,r10; \ 2: mtcrf 0x80,r9; \ ld r9,PACA_EXGEN+EX_R9(r13); \ ld r10,PACA_EXGEN+EX_R10(r13); \ ld r11,PACA_EXGEN+EX_R11(r13); \ - GET_SCRATCH0(r13); \ + /* returns to kernel where r13 must be set up, so don't restore it */ \ ##_H##rfid; \ b .; \ MASKED_DEC_HANDLER(_H) @@ -1485,8 +1505,10 @@ USE_TEXT_SECTION() */ .balign IFETCH_ALIGN_BYTES do_hash_page: -#ifdef CONFIG_PPC_STD_MMU_64 - andis. r0,r4,0xa450 /* weird error? */ + #ifdef CONFIG_PPC_STD_MMU_64 + lis r0,DSISR_BAD_FAULT_64S@h + ori r0,r0,DSISR_BAD_FAULT_64S@l + and. r0,r4,r0 /* weird error? */ bne- handle_page_fault /* if not, try to insert a HPTE */ CURRENT_THREAD_INFO(r11, r1) lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ @@ -1669,25 +1691,27 @@ _GLOBAL(__replay_interrupt) * we don't give a damn about, so we don't bother storing them. */ mfmsr r12 - LOAD_REG_ADDR(r11, 1f) + LOAD_REG_ADDR(r11, replay_interrupt_return) mfcr r9 ori r12,r12,MSR_EE cmpwi r3,0x900 beq decrementer_common cmpwi r3,0x500 - beq hardware_interrupt_common BEGIN_FTR_SECTION - cmpwi r3,0xe80 - beq h_doorbell_common_msgclr - cmpwi r3,0xea0 beq h_virt_irq_common +FTR_SECTION_ELSE + beq hardware_interrupt_common +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_300) +BEGIN_FTR_SECTION + cmpwi r3,0xa00 + beq h_doorbell_common_msgclr cmpwi r3,0xe60 beq hmi_exception_common FTR_SECTION_ELSE cmpwi r3,0xa00 beq doorbell_super_common_msgclr ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) -1: +replay_interrupt_return: blr _ASM_NOKPROBE_SYMBOL(__replay_interrupt) diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index dc0c49cfd90a..e1431800bfb9 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -125,6 +125,13 @@ int is_fadump_boot_memory_area(u64 addr, ulong size) return (addr + size) > RMA_START && addr <= fw_dump.boot_memory_size; } +int should_fadump_crash(void) +{ + if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr) + return 0; + return 1; +} + int is_fadump_active(void) { return fw_dump.dump_active; @@ -518,7 +525,7 @@ void crash_fadump(struct pt_regs *regs, const char *str) struct fadump_crash_info_header *fdh = NULL; int old_cpu, this_cpu; - if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr) + if (!should_fadump_crash()) return; /* @@ -1446,6 +1453,25 @@ static void fadump_init_files(void) return; } +static int fadump_panic_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + /* + * If firmware-assisted dump has been registered then trigger + * firmware-assisted dump and let firmware handle everything + * else. If this returns, then fadump was not registered, so + * go through the rest of the panic path. + */ + crash_fadump(NULL, ptr); + + return NOTIFY_DONE; +} + +static struct notifier_block fadump_panic_block = { + .notifier_call = fadump_panic_event, + .priority = INT_MIN /* may not return; must be done last */ +}; + /* * Prepare for firmware-assisted dump. */ @@ -1478,6 +1504,9 @@ int __init setup_fadump(void) init_fadump_mem_struct(&fdm, fw_dump.reserve_dump_area_start); fadump_init_files(); + atomic_notifier_chain_register(&panic_notifier_list, + &fadump_panic_block); + return 1; } subsys_initcall(setup_fadump); diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S index 83dd0f6776b3..ea065282b303 100644 --- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* 1. Find the index of the entry we're executing in */ bl invstr /* Find our address */ diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index e22734278458..8c54166491e7 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -388,7 +388,7 @@ DataAccess: EXCEPTION_PROLOG mfspr r10,SPRN_DSISR stw r10,_DSISR(r11) - andis. r0,r10,0xa470 /* weird error? */ + andis. r0,r10,DSISR_BAD_FAULT_32S@h bne 1f /* if not, try to put a PTE */ mfspr r4,SPRN_DAR /* into the hash table */ rlwinm r3,r10,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ @@ -403,13 +403,13 @@ DataAccess: DO_KVM 0x400 InstructionAccess: EXCEPTION_PROLOG - andis. r0,r9,0x4000 /* no pte found? */ + andis. r0,r9,SRR1_ISI_NOPT@h /* no pte found? */ beq 1f /* if so, try to put a PTE */ li r3,0 /* into the hash table */ mr r4,r12 /* SRR0 is fault address */ bl hash_page 1: mr r4,r12 - mr r5,r9 + andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ EXC_XFER_LITE(0x400, handle_page_fault) /* External interrupt */ diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 0ddc602b33a4..ff8511d6d8ea 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -92,13 +92,13 @@ END_FTR_SECTION(0, 1) .balign 8 .globl __secondary_hold_spinloop __secondary_hold_spinloop: - .llong 0x0 + .8byte 0x0 /* Secondary processors write this value with their cpu # */ /* after they enter the spin loop immediately below. */ .globl __secondary_hold_acknowledge __secondary_hold_acknowledge: - .llong 0x0 + .8byte 0x0 #ifdef CONFIG_RELOCATABLE /* This flag is set to 1 by a loader if the kernel should run @@ -650,7 +650,7 @@ __after_prom_start: bctr .balign 8 -p_end: .llong _end - copy_to_here +p_end: .8byte _end - copy_to_here 4: /* @@ -892,7 +892,7 @@ _GLOBAL(relative_toc) blr .balign 8 -p_toc: .llong __toc_start + 0x8000 - 0b +p_toc: .8byte __toc_start + 0x8000 - 0b /* * This is where the main kernel code starts. diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index c032fe8c2d26..4fee00d414e8 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -50,18 +50,20 @@ mtspr spr, reg #endif -/* Macro to test if an address is a kernel address */ #if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000 -#define IS_KERNEL(tmp, addr) \ - andis. tmp, addr, 0x8000 /* Address >= 0x80000000 */ -#define BRANCH_UNLESS_KERNEL(label) beq label -#else -#define IS_KERNEL(tmp, addr) \ - rlwinm tmp, addr, 16, 16, 31; \ - cmpli cr0, tmp, PAGE_OFFSET >> 16 -#define BRANCH_UNLESS_KERNEL(label) blt label +/* By simply checking Address >= 0x80000000, we know if its a kernel address */ +#define SIMPLE_KERNEL_ADDRESS 1 #endif +/* + * We need an ITLB miss handler for kernel addresses if: + * - Either we have modules + * - Or we have not pinned the first 8M + */ +#if defined(CONFIG_MODULES) || !defined(CONFIG_PIN_TLB_TEXT) || \ + defined(CONFIG_DEBUG_PAGEALLOC) +#define ITLB_MISS_KERNEL 1 +#endif /* * Value for the bits that have fixed value in RPN entries. @@ -123,7 +125,6 @@ turn_on_mmu: lis r0,start_here@h ori r0,r0,start_here@l mtspr SPRN_SRR0,r0 - SYNC rfi /* enables MMU */ /* @@ -170,7 +171,7 @@ turn_on_mmu: stw r1,0(r11); \ tovirt(r1,r11); /* set new kernel sp */ \ li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \ - MTMSRD(r10); /* (except for mach check in rtas) */ \ + mtmsr r10; \ stw r0,GPR0(r11); \ SAVE_4GPRS(3, r11); \ SAVE_2GPRS(7, r11) @@ -300,7 +301,7 @@ SystemCall: /* On the MPC8xx, this is a software emulation interrupt. It occurs * for all unimplemented and illegal instructions. */ - EXCEPTION(0x1000, SoftEmu, SoftwareEmulation, EXC_XFER_STD) + EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD) . = 0x1100 /* @@ -325,7 +326,7 @@ SystemCall: #endif InstructionTLBMiss: -#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(CONFIG_8xx_CPU6) || defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mtspr SPRN_SPRG_SCRATCH2, r3 #endif EXCEPTION_PROLOG_0 @@ -343,15 +344,32 @@ InstructionTLBMiss: INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10) /* Only modules will cause ITLB Misses as we always * pin the first 8MB of kernel memory */ -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mfcr r3 #endif -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) - IS_KERNEL(r11, r10) +#ifdef ITLB_MISS_KERNEL +#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT) + andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ +#else + rlwinm r11, r10, 16, 0xfff8 + cmpli cr0, r11, PAGE_OFFSET@h +#ifndef CONFIG_PIN_TLB_TEXT + /* It is assumed that kernel code fits into the first 8M page */ +_ENTRY(ITLBMiss_cmp) + cmpli cr7, r11, (PAGE_OFFSET + 0x0800000)@h +#endif +#endif #endif mfspr r11, SPRN_M_TW /* Get level 1 table */ -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) - BRANCH_UNLESS_KERNEL(3f) +#ifdef ITLB_MISS_KERNEL +#if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT) + beq+ 3f +#else + blt+ 3f +#endif +#ifndef CONFIG_PIN_TLB_TEXT + blt cr7, ITLBMissLinear +#endif lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha 3: #endif @@ -369,7 +387,7 @@ InstructionTLBMiss: rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */ lwz r10, 0(r10) /* Get the pte */ 4: -#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mtcr r3 #endif /* Insert the APG into the TWC from the Linux PTE. */ @@ -400,7 +418,7 @@ InstructionTLBMiss: MTSPR_CPU6(SPRN_MI_RPN, r10, r3) /* Update TLB entry */ /* Restore registers */ -#if defined(CONFIG_8xx_CPU6) || defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) || defined (CONFIG_HUGETLB_PAGE) +#if defined(CONFIG_8xx_CPU6) || defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE) mfspr r3, SPRN_SPRG_SCRATCH2 #endif EXCEPTION_EPILOG_0 @@ -447,23 +465,23 @@ DataStoreTLBMiss: * kernel page tables. */ mfspr r10, SPRN_MD_EPN - rlwinm r10, r10, 16, 0xfff8 - cmpli cr0, r10, PAGE_OFFSET@h + rlwinm r11, r10, 16, 0xfff8 + cmpli cr0, r11, PAGE_OFFSET@h mfspr r11, SPRN_M_TW /* Get level 1 table */ blt+ 3f + rlwinm r11, r10, 16, 0xfff8 #ifndef CONFIG_PIN_TLB_IMMR - cmpli cr0, r10, VIRT_IMMR_BASE@h + cmpli cr0, r11, VIRT_IMMR_BASE@h #endif _ENTRY(DTLBMiss_cmp) - cmpli cr7, r10, (PAGE_OFFSET + 0x1800000)@h - lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha + cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h #ifndef CONFIG_PIN_TLB_IMMR _ENTRY(DTLBMiss_jmp) beq- DTLBMissIMMR #endif blt cr7, DTLBMissLinear + lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha 3: - mfspr r10, SPRN_MD_EPN /* Insert level 1 index */ rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 @@ -569,8 +587,8 @@ _ENTRY(DTLBMiss_jmp) InstructionTLBError: EXCEPTION_PROLOG mr r4,r12 - mr r5,r9 - andis. r10,r5,0x4000 + andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ + andis. r10,r9,SRR1_ISI_NOPT@h beq+ 1f tlbie r4 itlbie: @@ -595,7 +613,7 @@ DARFixed:/* Return from dcbx instruction bug workaround */ mfspr r5,SPRN_DSISR stw r5,_DSISR(r11) mfspr r4,SPRN_DAR - andis. r10,r5,0x4000 + andis. r10,r5,DSISR_NOHPTE@h beq+ 1f tlbie r4 dtlbie: @@ -684,7 +702,7 @@ DTLBMissLinear: /* Set 8M byte page and mark it valid */ li r11, MD_PS8MEG | MD_SVALID MTSPR_CPU6(SPRN_MD_TWC, r11, r3) - rlwinm r10, r10, 16, 0x0f800000 /* 8xx supports max 256Mb RAM */ + rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ _PAGE_PRESENT MTSPR_CPU6(SPRN_MD_RPN, r10, r11) /* Update TLB entry */ @@ -695,6 +713,22 @@ DTLBMissLinear: EXCEPTION_EPILOG_0 rfi +#ifndef CONFIG_PIN_TLB_TEXT +ITLBMissLinear: + mtcr r3 + /* Set 8M byte page and mark it valid */ + li r11, MI_PS8MEG | MI_SVALID | _PAGE_EXEC + MTSPR_CPU6(SPRN_MI_TWC, r11, r3) + rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */ + ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ + _PAGE_PRESENT + MTSPR_CPU6(SPRN_MI_RPN, r10, r11) /* Update TLB entry */ + + mfspr r3, SPRN_SPRG_SCRATCH2 + EXCEPTION_EPILOG_0 + rfi +#endif + /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions * by decoding the registers used by the dcbx instruction and adding them. * DAR is set to the calculated address. @@ -705,9 +739,10 @@ FixupDAR:/* Entry point for dcbx workaround. */ mtspr SPRN_SPRG_SCRATCH2, r10 /* fetch instruction from memory. */ mfspr r10, SPRN_SRR0 - IS_KERNEL(r11, r10) + rlwinm r11, r10, 16, 0xfff8 + cmpli cr0, r11, PAGE_OFFSET@h mfspr r11, SPRN_M_TW /* Get level 1 table */ - BRANCH_UNLESS_KERNEL(3f) + blt+ 3f rlwinm r11, r10, 16, 0xfff8 _ENTRY(FixupDAR_cmp) cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h @@ -915,10 +950,8 @@ start_here: rfi /* Load up the kernel context */ 2: - SYNC /* Force all PTE updates to finish */ tlbia /* Clear all TLB entries */ sync /* wait for tlbia/tlbie to finish */ - TLBSYNC /* ... on all CPUs */ /* set up the PTE pointers for the Abatron bdiGDB. */ @@ -955,15 +988,14 @@ initial_mmu: mtspr SPRN_MD_CTR, r10 /* remove PINNED DTLB entries */ tlbia /* Invalidate all TLB entries */ -/* Always pin the first 8 MB ITLB to prevent ITLB - misses while mucking around with SRR0/SRR1 in asm -*/ +#ifdef CONFIG_PIN_TLB_TEXT lis r8, MI_RSV4I@h ori r8, r8, 0x1c00 mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ +#endif -#ifdef CONFIG_PIN_TLB +#ifdef CONFIG_PIN_TLB_DATA oris r10, r10, MD_RSV4I@h mtspr SPRN_MD_CTR, r10 /* Set data TLB control */ #endif @@ -989,6 +1021,7 @@ initial_mmu: * internal registers (among other things). */ #ifdef CONFIG_PIN_TLB_IMMR + oris r10, r10, MD_RSV4I@h ori r10, r10, 0x1c00 mtspr SPRN_MD_CTR, r10 diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index a620203f7de3..d0862a100d29 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __HEAD_BOOKE_H__ #define __HEAD_BOOKE_H__ diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index e6252c5a57a4..1125c9be9e06 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -85,7 +85,61 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300) std r3,_WORT(r1) mfspr r3,SPRN_WORC std r3,_WORC(r1) +/* + * On POWER9, there are idle states such as stop4, invoked via cpuidle, + * that lose hypervisor resources. In such cases, we need to save + * additional SPRs before entering those idle states so that they can + * be restored to their older values on wakeup from the idle state. + * + * On POWER8, the only such deep idle state is winkle which is used + * only in the context of CPU-Hotplug, where these additional SPRs are + * reinitiazed to a sane value. Hence there is no need to save/restore + * these SPRs. + */ +BEGIN_FTR_SECTION + blr +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) +power9_save_additional_sprs: + mfspr r3, SPRN_PID + mfspr r4, SPRN_LDBAR + std r3, STOP_PID(r13) + std r4, STOP_LDBAR(r13) + + mfspr r3, SPRN_FSCR + mfspr r4, SPRN_HFSCR + std r3, STOP_FSCR(r13) + std r4, STOP_HFSCR(r13) + + mfspr r3, SPRN_MMCRA + mfspr r4, SPRN_MMCR1 + std r3, STOP_MMCRA(r13) + std r4, STOP_MMCR1(r13) + + mfspr r3, SPRN_MMCR2 + std r3, STOP_MMCR2(r13) + blr + +power9_restore_additional_sprs: + ld r3,_LPCR(r1) + ld r4, STOP_PID(r13) + mtspr SPRN_LPCR,r3 + mtspr SPRN_PID, r4 + + ld r3, STOP_LDBAR(r13) + ld r4, STOP_FSCR(r13) + mtspr SPRN_LDBAR, r3 + mtspr SPRN_FSCR, r4 + + ld r3, STOP_HFSCR(r13) + ld r4, STOP_MMCRA(r13) + mtspr SPRN_HFSCR, r3 + mtspr SPRN_MMCRA, r4 + /* We have already restored PACA_MMCR0 */ + ld r3, STOP_MMCR1(r13) + ld r4, STOP_MMCR2(r13) + mtspr SPRN_MMCR1, r3 + mtspr SPRN_MMCR2, r4 blr /* @@ -141,7 +195,16 @@ pnv_powersave_common: std r5,_CCR(r1) std r1,PACAR1(r13) +BEGIN_FTR_SECTION /* + * POWER9 does not require real mode to stop, and presently does not + * set hwthread_state for KVM (threads don't share MMU context), so + * we can remain in virtual mode for this. + */ + bctr +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + /* + * POWER8 * Go to real mode to do the nap, as required by the architecture. * Also, we need to be in real mode before setting hwthread_state, * because as soon as we do that, another thread can switch @@ -151,6 +214,20 @@ pnv_powersave_common: mtmsrd r7,0 bctr +/* + * This is the sequence required to execute idle instructions, as + * specified in ISA v2.07 (and earlier). MSR[IR] and MSR[DR] must be 0. + */ +#define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ + /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ + std r0,0(r1); \ + ptesync; \ + ld r0,0(r1); \ +236: cmpd cr0,r0,r0; \ + bne 236b; \ + IDLE_INST; + + .globl pnv_enter_arch207_idle_mode pnv_enter_arch207_idle_mode: #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE @@ -242,20 +319,27 @@ enter_winkle: /* * r3 - PSSCR value corresponding to the requested stop state. */ -power_enter_stop: #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE - /* Tell KVM we're entering idle */ +power_enter_stop_kvm_rm: + /* + * This is currently unused because POWER9 KVM does not have to + * gather secondary threads into sibling mode, but the code is + * here in case that function is required. + * + * Tell KVM we're entering idle. + */ li r4,KVM_HWTHREAD_IN_IDLE /* DO THIS IN REAL MODE! See comment above. */ stb r4,HSTATE_HWTHREAD_STATE(r13) #endif +power_enter_stop: /* * Check if we are executing the lite variant with ESL=EC=0 */ andis. r4,r3,PSSCR_EC_ESL_MASK_SHIFTED clrldi r3,r3,60 /* r3 = Bits[60:63] = Requested Level (RL) */ bne .Lhandle_esl_ec_set - IDLE_STATE_ENTER_SEQ(PPC_STOP) + PPC_STOP li r3,0 /* Since we didn't lose state, return 0 */ /* @@ -288,7 +372,8 @@ power_enter_stop: ld r4,ADDROFF(pnv_first_deep_stop_state)(r5) cmpd r3,r4 bge .Lhandle_deep_stop - IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP) + PPC_STOP /* Does not return (system reset interrupt) */ + .Lhandle_deep_stop: /* * Entering deep idle state. @@ -310,7 +395,7 @@ lwarx_loop_stop: bl save_sprs_to_stack - IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP) + PPC_STOP /* Does not return (system reset interrupt) */ /* * Entered with MSR[EE]=0 and no soft-masked interrupts pending. @@ -411,6 +496,18 @@ pnv_powersave_wakeup_mce: b pnv_powersave_wakeup +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +kvm_start_guest_check: + li r0,KVM_HWTHREAD_IN_KERNEL + stb r0,HSTATE_HWTHREAD_STATE(r13) + /* Order setting hwthread_state vs. testing hwthread_req */ + sync + lbz r0,HSTATE_HWTHREAD_REQ(r13) + cmpwi r0,0 + beqlr + b kvm_start_guest +#endif + /* * Called from reset vector for powersave wakeups. * cr3 - set to gt if waking up with partial/complete hypervisor state loss @@ -435,15 +532,9 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300) mr r3,r12 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE - li r0,KVM_HWTHREAD_IN_KERNEL - stb r0,HSTATE_HWTHREAD_STATE(r13) - /* Order setting hwthread_state vs. testing hwthread_req */ - sync - lbz r0,HSTATE_HWTHREAD_REQ(r13) - cmpwi r0,0 - beq 1f - b kvm_start_guest -1: +BEGIN_FTR_SECTION + bl kvm_start_guest_check +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) #endif /* Return SRR1 from power7_nap() */ @@ -809,9 +900,16 @@ no_segments: mtctr r12 bctrl +/* + * On POWER9, we can come here on wakeup from a cpuidle stop state. + * Hence restore the additional SPRs to the saved value. + * + * On POWER8, we come here only on winkle. Since winkle is used + * only in the case of CPU-Hotplug, we don't need to restore + * the additional SPRs. + */ BEGIN_FTR_SECTION - ld r4,_LPCR(r1) - mtspr SPRN_LPCR,r4 + bl power9_restore_additional_sprs END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) hypervisor_state_restored: diff --git a/arch/powerpc/kernel/io-workarounds.c b/arch/powerpc/kernel/io-workarounds.c index a582e0d42525..aa9f1b8261db 100644 --- a/arch/powerpc/kernel/io-workarounds.c +++ b/arch/powerpc/kernel/io-workarounds.c @@ -19,6 +19,8 @@ #include #include #include +#include + #define IOWA_MAX_BUS 8 @@ -75,8 +77,7 @@ struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr) * We won't find huge pages here (iomem). Also can't hit * a page table free due to init_mm */ - ptep = __find_linux_pte_or_hugepte(init_mm.pgd, vaddr, - NULL, &hugepage_shift); + ptep = find_init_mm_pte(vaddr, &hugepage_shift); if (ptep == NULL) paddr = 0; else { @@ -192,7 +193,7 @@ void iowa_register_bus(struct pci_controller *phb, struct ppc_pci_io *ops, if (iowa_bus_count >= IOWA_MAX_BUS) { pr_err("IOWA:Too many pci bridges, " - "workarounds disabled for %s\n", np->full_name); + "workarounds disabled for %pOF\n", np); return; } @@ -207,6 +208,6 @@ void iowa_register_bus(struct pci_controller *phb, struct ppc_pci_io *ops, iowa_bus_count++; - pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name); + pr_debug("IOWA:[%d]Add bus, %pOF.\n", iowa_bus_count-1, np); } diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c index a1854d1ded8b..aab456ed2a00 100644 --- a/arch/powerpc/kernel/iomap.c +++ b/arch/powerpc/kernel/iomap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ppc64 "iomap" interface implementation. * diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 233ca3fe4754..af7a20dc6e09 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -127,8 +127,7 @@ static ssize_t fail_iommu_store(struct device *dev, return count; } -static DEVICE_ATTR(fail_iommu, S_IRUGO|S_IWUSR, fail_iommu_show, - fail_iommu_store); +static DEVICE_ATTR_RW(fail_iommu); static int fail_iommu_bus_notify(struct notifier_block *nb, unsigned long action, void *data) @@ -190,7 +189,7 @@ static unsigned long iommu_range_alloc(struct device *dev, unsigned int pool_nr; struct iommu_pool *pool; - align_mask = 0xffffffffffffffffl >> (64 - align_order); + align_mask = (1ull << align_order) - 1; /* This allocator was derived from x86_64's bit string search */ @@ -208,7 +207,7 @@ static unsigned long iommu_range_alloc(struct device *dev, * We don't need to disable preemption here because any CPU can * safely use any IOMMU pool. */ - pool_nr = __this_cpu_read(iommu_pool_hash) & (tbl->nr_pools - 1); + pool_nr = raw_cpu_read(iommu_pool_hash) & (tbl->nr_pools - 1); if (largealloc) pool = &(tbl->large_pool); diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index f291f7826abc..4e65bf82f5e0 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -24,7 +24,7 @@ * mask register (of which only 16 are defined), hence the weird shifting * and complement of the cached_irq_mask. I want to be able to stuff * this right into the SIU SMASK register. - * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx + * Many of the prep/chrp functions are conditional compiled on CONFIG_PPC_8xx * to reduce code space and undefined function references. */ @@ -143,9 +143,10 @@ notrace unsigned int __check_irq_replay(void) */ unsigned char happened = local_paca->irq_happened; - /* Clear bit 0 which we wouldn't clear otherwise */ - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; if (happened & PACA_IRQ_HARD_DIS) { + /* Clear bit 0 which we wouldn't clear otherwise */ + local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS; + /* * We may have missed a decrementer interrupt if hard disabled. * Check the decrementer register in case we had a rollover @@ -173,41 +174,39 @@ notrace unsigned int __check_irq_replay(void) * This is a higher priority interrupt than the others, so * replay it first. */ - local_paca->irq_happened &= ~PACA_IRQ_HMI; - if (happened & PACA_IRQ_HMI) + if (happened & PACA_IRQ_HMI) { + local_paca->irq_happened &= ~PACA_IRQ_HMI; return 0xe60; + } - /* - * We may have missed a decrementer interrupt. We check the - * decrementer itself rather than the paca irq_happened field - * in case we also had a rollover while hard disabled - */ - local_paca->irq_happened &= ~PACA_IRQ_DEC; - if (happened & PACA_IRQ_DEC) + if (happened & PACA_IRQ_DEC) { + local_paca->irq_happened &= ~PACA_IRQ_DEC; return 0x900; + } - /* Finally check if an external interrupt happened */ - local_paca->irq_happened &= ~PACA_IRQ_EE; - if (happened & PACA_IRQ_EE) + if (happened & PACA_IRQ_EE) { + local_paca->irq_happened &= ~PACA_IRQ_EE; return 0x500; + } #ifdef CONFIG_PPC_BOOK3E - /* Finally check if an EPR external interrupt happened - * this bit is typically set if we need to handle another - * "edge" interrupt from within the MPIC "EPR" handler + /* + * Check if an EPR external interrupt happened this bit is typically + * set if we need to handle another "edge" interrupt from within the + * MPIC "EPR" handler. */ - local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; - if (happened & PACA_IRQ_EE_EDGE) + if (happened & PACA_IRQ_EE_EDGE) { + local_paca->irq_happened &= ~PACA_IRQ_EE_EDGE; return 0x500; + } - local_paca->irq_happened &= ~PACA_IRQ_DBELL; - if (happened & PACA_IRQ_DBELL) - return 0x280; -#else - local_paca->irq_happened &= ~PACA_IRQ_DBELL; if (happened & PACA_IRQ_DBELL) { - if (cpu_has_feature(CPU_FTR_HVMODE)) - return 0xe80; + local_paca->irq_happened &= ~PACA_IRQ_DBELL; + return 0x280; + } +#else + if (happened & PACA_IRQ_DBELL) { + local_paca->irq_happened &= ~PACA_IRQ_DBELL; return 0xa00; } #endif /* CONFIG_PPC_BOOK3E */ @@ -483,6 +482,18 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, " Hypervisor Maintenance Interrupts\n"); } + seq_printf(p, "%*s: ", prec, "NMI"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", per_cpu(irq_stat, j).sreset_irqs); + seq_printf(p, " System Reset interrupts\n"); + +#ifdef CONFIG_PPC_WATCHDOG + seq_printf(p, "%*s: ", prec, "WDG"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", per_cpu(irq_stat, j).soft_nmi_irqs); + seq_printf(p, " Watchdog soft-NMI interrupts\n"); +#endif + #ifdef CONFIG_PPC_DOORBELL if (cpu_has_feature(CPU_FTR_DBELL)) { seq_printf(p, "%*s: ", prec, "DBL"); @@ -507,6 +518,10 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum += per_cpu(irq_stat, cpu).spurious_irqs; sum += per_cpu(irq_stat, cpu).timer_irqs_others; sum += per_cpu(irq_stat, cpu).hmi_exceptions; + sum += per_cpu(irq_stat, cpu).sreset_irqs; +#ifdef CONFIG_PPC_WATCHDOG + sum += per_cpu(irq_stat, cpu).soft_nmi_irqs; +#endif #ifdef CONFIG_PPC_DOORBELL sum += per_cpu(irq_stat, cpu).doorbell_irqs; #endif diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c index bb6f8993412e..1df6c74aa731 100644 --- a/arch/powerpc/kernel/isa-bridge.c +++ b/arch/powerpc/kernel/isa-bridge.c @@ -164,7 +164,7 @@ void __init isa_bridge_find_early(struct pci_controller *hose) /* Set the global ISA io base to indicate we have an ISA bridge */ isa_io_base = ISA_IO_BASE; - pr_debug("ISA bridge (early) is %s\n", np->full_name); + pr_debug("ISA bridge (early) is %pOF\n", np); } /** @@ -187,15 +187,15 @@ void __init isa_bridge_init_non_pci(struct device_node *np) pna = of_n_addr_cells(np); if (of_property_read_u32(np, "#address-cells", &na) || of_property_read_u32(np, "#size-cells", &ns)) { - pr_warn("ISA: Non-PCI bridge %s is missing address format\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF is missing address format\n", + np); return; } /* Check it's a supported address format */ if (na != 2 || ns != 1) { - pr_warn("ISA: Non-PCI bridge %s has unsupported address format\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has unsupported address format\n", + np); return; } rs = na + ns + pna; @@ -203,8 +203,8 @@ void __init isa_bridge_init_non_pci(struct device_node *np) /* Grab the ranges property */ ranges = of_get_property(np, "ranges", &rlen); if (ranges == NULL || rlen < rs) { - pr_warn("ISA: Non-PCI bridge %s has absent or invalid ranges\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has absent or invalid ranges\n", + np); return; } @@ -220,8 +220,8 @@ void __init isa_bridge_init_non_pci(struct device_node *np) /* Got something ? */ if (!size || !pbasep) { - pr_warn("ISA: Non-PCI bridge %s has no usable IO range\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has no usable IO range\n", + np); return; } @@ -233,15 +233,15 @@ void __init isa_bridge_init_non_pci(struct device_node *np) /* Map pbase */ pbase = of_translate_address(np, pbasep); if (pbase == OF_BAD_ADDR) { - pr_warn("ISA: Non-PCI bridge %s failed to translate IO base\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF failed to translate IO base\n", + np); return; } /* We need page alignment */ if ((cbase & ~PAGE_MASK) || (pbase & ~PAGE_MASK)) { - pr_warn("ISA: Non-PCI bridge %s has non aligned IO range\n", - np->full_name); + pr_warn("ISA: Non-PCI bridge %pOF has non aligned IO range\n", + np); return; } @@ -255,7 +255,7 @@ void __init isa_bridge_init_non_pci(struct device_node *np) __ioremap_at(pbase, (void *)ISA_IO_BASE, size, pgprot_val(pgprot_noncached(__pgprot(0)))); - pr_debug("ISA: Non-PCI bridge is %s\n", np->full_name); + pr_debug("ISA: Non-PCI bridge is %pOF\n", np); } /** @@ -277,8 +277,8 @@ static void isa_bridge_find_late(struct pci_dev *pdev, /* Set the global ISA io base to indicate we have an ISA bridge */ isa_io_base = ISA_IO_BASE; - pr_debug("ISA bridge (late) is %s on %s\n", - devnode->full_name, pci_name(pdev)); + pr_debug("ISA bridge (late) is %pOF on %s\n", + devnode, pci_name(pdev)); } /** diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index dbf098121ce6..35e240a0a408 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -67,9 +67,9 @@ static struct hard_trap_info #endif #else /* ! (defined(CONFIG_40x) || defined(CONFIG_BOOKE)) */ { 0x0d00, 0x05 /* SIGTRAP */ }, /* single-step */ -#if defined(CONFIG_8xx) +#if defined(CONFIG_PPC_8xx) { 0x1000, 0x04 /* SIGILL */ }, /* software emulation */ -#else /* ! CONFIG_8xx */ +#else /* ! CONFIG_PPC_8xx */ { 0x0f00, 0x04 /* SIGILL */ }, /* performance monitor */ { 0x0f20, 0x08 /* SIGFPE */ }, /* altivec unavailable */ { 0x1300, 0x05 /* SIGTRAP */ }, /* instruction address break */ diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 367494dc67d9..bebc3007a793 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -600,7 +600,12 @@ NOKPROBE_SYMBOL(kprobe_fault_handler); unsigned long arch_deref_entry_point(void *entry) { - return ppc_global_function_entry(entry); +#ifdef PPC64_ELF_ABI_v1 + if (!kernel_text_address((unsigned long)entry)) + return ppc_global_function_entry(entry); + else +#endif + return (unsigned long)entry; } NOKPROBE_SYMBOL(arch_deref_entry_point); diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 1086ea37c832..9ad37f827a97 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -25,7 +25,6 @@ #include #include #include -#include /* hardlockup_detector_disable() */ #include #include @@ -719,12 +718,6 @@ static __init void kvm_free_tmp(void) static int __init kvm_guest_init(void) { - /* - * The hardlockup detector is likely to get false positives in - * KVM guests, so disable it by default. - */ - hardlockup_detector_disable(); - if (!kvm_para_available()) goto free_tmp; diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S index 97ec8557f974..6408f09dbbd9 100644 --- a/arch/powerpc/kernel/l2cr_6xx.S +++ b/arch/powerpc/kernel/l2cr_6xx.S @@ -181,7 +181,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450) mtctr r4 li r4,0 1: - lwzx r0,r0,r4 + lwzx r0,0,r4 addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b isync @@ -328,7 +328,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_L3CR) mtctr r4 li r4,0 1: - lwzx r0,r0,r4 + lwzx r0,0,r4 dcbf 0,r4 addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c index 0694d20f85b6..33b34a58fc62 100644 --- a/arch/powerpc/kernel/legacy_serial.c +++ b/arch/powerpc/kernel/legacy_serial.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -147,8 +148,8 @@ static int __init add_legacy_port(struct device_node *np, int want_index, legacy_serial_ports[index].serial_out = tsi_serial_out; } - printk(KERN_DEBUG "Found legacy serial port %d for %s\n", - index, np->full_name); + printk(KERN_DEBUG "Found legacy serial port %d for %pOF\n", + index, np); printk(KERN_DEBUG " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", (iotype == UPIO_PORT) ? "port" : "mem", (unsigned long long)base, (unsigned long long)taddr, irq, @@ -207,7 +208,7 @@ static int __init add_legacy_isa_port(struct device_node *np, int index = -1; u64 taddr; - DBG(" -> add_legacy_isa_port(%s)\n", np->full_name); + DBG(" -> add_legacy_isa_port(%pOF)\n", np); /* Get the ISA port number */ reg = of_get_property(np, "reg", NULL); @@ -256,7 +257,7 @@ static int __init add_legacy_pci_port(struct device_node *np, unsigned int flags; int iotype, index = -1, lindex = 0; - DBG(" -> add_legacy_pci_port(%s)\n", np->full_name); + DBG(" -> add_legacy_pci_port(%pOF)\n", np); /* We only support ports that have a clock frequency properly * encoded in the device-tree (that is have an fcode). Anything @@ -374,7 +375,7 @@ void __init find_legacy_serial_ports(void) if (path != NULL) { stdout = of_find_node_by_path(path); if (stdout) - DBG("stdout is %s\n", stdout->full_name); + DBG("stdout is %pOF\n", stdout); } else { DBG(" no linux,stdout-path !\n"); } @@ -603,7 +604,7 @@ static int __init check_legacy_serial_console(void) DBG(" can't find stdout package %s !\n", name); return -ENODEV; } - DBG("stdout is %s\n", prom_stdout->full_name); + DBG("stdout is %pOF\n", prom_stdout); name = of_get_property(prom_stdout, "name", NULL); if (!name) { diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index e0e131e662ed..9b2ea7e71c06 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -22,11 +22,14 @@ #undef DEBUG #define pr_fmt(fmt) "mce: " fmt +#include #include #include #include #include #include + +#include #include static DEFINE_PER_CPU(int, mce_nest_count); @@ -446,3 +449,33 @@ uint64_t get_mce_fault_addr(struct machine_check_event *evt) return 0; } EXPORT_SYMBOL(get_mce_fault_addr); + +/* + * This function is called in real mode. Strictly no printk's please. + * + * regs->nip and regs->msr contains srr0 and ssr1. + */ +long machine_check_early(struct pt_regs *regs) +{ + long handled = 0; + + __this_cpu_inc(irq_stat.mce_exceptions); + + if (cur_cpu_spec && cur_cpu_spec->machine_check_early) + handled = cur_cpu_spec->machine_check_early(regs); + return handled; +} + +long hmi_exception_realmode(struct pt_regs *regs) +{ + __this_cpu_inc(irq_stat.hmi_exceptions); + + wait_for_subcore_guest_exit(); + + if (ppc_md.hmi_exception_early) + ppc_md.hmi_exception_early(regs); + + wait_for_tb_resync(); + + return 0; +} diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index b76ca198e09c..72f153c6f3fa 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -624,5 +624,18 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs) long __machine_check_early_realmode_p9(struct pt_regs *regs) { + /* + * On POWER9 DD2.1 and below, it's possible to get a machine check + * caused by a paste instruction where only DSISR bit 25 is set. This + * will result in the MCE handler seeing an unknown event and the kernel + * crashing. An MCE that occurs like this is spurious, so we don't need + * to do anything in terms of servicing it. If there is something that + * needs to be serviced, the CPU will raise the MCE again with the + * correct DSISR so that it can be serviced properly. So detect this + * case and mark it as handled. + */ + if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000) + return 1; + return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table); } diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 34aeac54f120..becaec990140 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -45,7 +45,7 @@ static int of_pci_phb_probe(struct platform_device *dev) if (ppc_md.pci_setup_phb == NULL) return -ENODEV; - pr_info("Setting up PCI bus %s\n", dev->dev.of_node->full_name); + pr_info("Setting up PCI bus %pOF\n", dev->dev.of_node); /* Alloc and setup PHB data structure */ phb = pcibios_alloc_controller(dev->dev.of_node); diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index 6f8273f5e988..91e037ab20a1 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -104,8 +104,10 @@ static unsigned long can_optimize(struct kprobe *p) * and that can be emulated. */ if (!is_conditional_branch(*p->ainsn.insn) && - analyse_instr(&op, ®s, *p->ainsn.insn)) + analyse_instr(&op, ®s, *p->ainsn.insn) == 1) { + emulate_update_regs(®s, &op); nip = regs.nip; + } return nip; } diff --git a/arch/powerpc/kernel/optprobes_head.S b/arch/powerpc/kernel/optprobes_head.S index 4937bef7652f..52fc864cdec4 100644 --- a/arch/powerpc/kernel/optprobes_head.S +++ b/arch/powerpc/kernel/optprobes_head.S @@ -60,10 +60,6 @@ optprobe_template_entry: std r5,_CCR(r1) lbz r5,PACASOFTIRQEN(r13) std r5,SOFTE(r1) - mfdar r5 - std r5,_DAR(r1) - mfdsisr r5 - std r5,_DSISR(r1) /* * We may get here from a module, so load the kernel TOC in r2. @@ -122,10 +118,6 @@ optprobe_template_call_emulate: mtxer r5 ld r5,_CCR(r1) mtcr r5 - ld r5,_DAR(r1) - mtdar r5 - ld r5,_DSISR(r1) - mtdsisr r5 REST_GPR(0,r1) REST_10GPRS(2,r1) REST_10GPRS(12,r1) diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 8d63627e067f..2ff2b8a19f71 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -99,18 +99,27 @@ static inline void free_lppacas(void) { } * If you make the number of persistent SLB entries dynamic, please also * update PR KVM to flush and restore them accordingly. */ -static struct slb_shadow *slb_shadow; +static struct slb_shadow * __initdata slb_shadow; static void __init allocate_slb_shadows(int nr_cpus, int limit) { int size = PAGE_ALIGN(sizeof(struct slb_shadow) * nr_cpus); + + if (early_radix_enabled()) + return; + slb_shadow = __va(memblock_alloc_base(size, PAGE_SIZE, limit)); memset(slb_shadow, 0, size); } static struct slb_shadow * __init init_slb_shadow(int cpu) { - struct slb_shadow *s = &slb_shadow[cpu]; + struct slb_shadow *s; + + if (early_radix_enabled()) + return NULL; + + s = &slb_shadow[cpu]; /* * When we come through here to initialise boot_paca, the slb_shadow @@ -215,7 +224,7 @@ void __init allocate_pacas(void) paca = __va(memblock_alloc_base(paca_size, PAGE_SIZE, limit)); memset(paca, 0, paca_size); - printk(KERN_DEBUG "Allocated %u bytes for %d pacas at %p\n", + printk(KERN_DEBUG "Allocated %u bytes for %u pacas at %p\n", paca_size, nr_cpu_ids, paca); allocate_lppacas(nr_cpu_ids, limit); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 341a7469cab8..02831a396419 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -373,9 +373,8 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) if (virq) irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); } else { - pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", - oirq.args_count, oirq.args[0], oirq.args[1], - of_node_full_name(oirq.np)); + pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %pOF\n", + oirq.args_count, oirq.args[0], oirq.args[1], oirq.np); virq = irq_create_of_mapping(&oirq); } @@ -741,8 +740,8 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose, struct of_pci_range range; struct of_pci_range_parser parser; - printk(KERN_INFO "PCI host bridge %s %s ranges:\n", - dev->full_name, primary ? "(primary)" : ""); + printk(KERN_INFO "PCI host bridge %pOF %s ranges:\n", + dev, primary ? "(primary)" : ""); /* Check for ranges property */ if (of_pci_range_parser_init(&parser, dev)) @@ -1556,8 +1555,8 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, if (!res->flags) { pr_debug("PCI: I/O resource not set for host" - " bridge %s (domain %d)\n", - hose->dn->full_name, hose->global_number); + " bridge %pOF (domain %d)\n", + hose->dn, hose->global_number); } else { offset = pcibios_io_space_offset(hose); @@ -1668,7 +1667,7 @@ void pcibios_scan_phb(struct pci_controller *hose) struct device_node *node = hose->dn; int mode; - pr_debug("PCI: Scanning PHB %s\n", of_node_full_name(node)); + pr_debug("PCI: Scanning PHB %pOF\n", node); /* Get some IO space for the new PHB */ pcibios_setup_phb_io_space(hose); diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 41c86c6b6e4d..1d817f4d97d9 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -79,8 +79,8 @@ make_one_node_map(struct device_node* node, u8 pci_bus) return; bus_range = of_get_property(node, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, " - "assuming it starts at 0\n", node->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, " + "assuming it starts at 0\n", node); pci_to_OF_bus_map[pci_bus] = 0; } else pci_to_OF_bus_map[pci_bus] = bus_range[0]; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index ed5e9ff61a68..932b9741aa8f 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -111,7 +111,7 @@ int pcibios_unmap_io_space(struct pci_bus *bus) if (hose->io_base_alloc == NULL) return 0; - pr_debug("IO unmapping for PHB %s\n", hose->dn->full_name); + pr_debug("IO unmapping for PHB %pOF\n", hose->dn); pr_debug(" alloc=0x%p\n", hose->io_base_alloc); /* This is a PHB, we fully unmap the IO area */ @@ -151,7 +151,7 @@ static int pcibios_map_phb_io_space(struct pci_controller *hose) hose->io_base_virt = (void __iomem *)(area->addr + hose->io_base_phys - phys_page); - pr_debug("IO mapping for PHB %s\n", hose->dn->full_name); + pr_debug("IO mapping for PHB %pOF\n", hose->dn); pr_debug(" phys=0x%016llx, virt=0x%p (alloc=0x%p)\n", hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); pr_debug(" size=0x%016llx (alloc=0x%016lx)\n", diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index 592693437070..0e395afbf0f4 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -139,7 +139,6 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev) #ifdef CONFIG_PCI_IOV static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, - struct pci_dev *pdev, int vf_index, int busno, int devfn) { @@ -150,10 +149,8 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, return NULL; pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); - if (!pdn) { - dev_warn(&pdev->dev, "%s: Out of memory!\n", __func__); + if (!pdn) return NULL; - } pdn->phb = parent->phb; pdn->parent = parent; @@ -167,13 +164,6 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, INIT_LIST_HEAD(&pdn->list); list_add_tail(&pdn->list, &parent->child_list); - /* - * If we already have PCI device instance, lets - * bind them. - */ - if (pdev) - pdev->dev.archdata.pci_data = pdn; - return pdn; } #endif @@ -201,7 +191,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { struct eeh_dev *edev __maybe_unused; - pdn = add_one_dev_pci_data(parent, NULL, i, + pdn = add_one_dev_pci_data(parent, i, pci_iov_virtfn_bus(pdev, i), pci_iov_virtfn_devfn(pdev, i)); if (!pdn) { @@ -303,7 +293,6 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose, if (pdn == NULL) return NULL; dn->data = pdn; - pdn->node = dn; pdn->phb = hose; #ifdef CONFIG_PPC_POWERNV pdn->pe_number = IODA_INVALID_PE; @@ -352,6 +341,7 @@ EXPORT_SYMBOL_GPL(pci_add_device_node_info); void pci_remove_device_node_info(struct device_node *dn) { struct pci_dn *pdn = dn ? PCI_DN(dn) : NULL; + struct device_node *parent; #ifdef CONFIG_EEH struct eeh_dev *edev = pdn_to_eeh_dev(pdn); @@ -364,8 +354,10 @@ void pci_remove_device_node_info(struct device_node *dn) WARN_ON(!list_empty(&pdn->child_list)); list_del(&pdn->list); - if (pdn->parent) - of_node_put(pdn->parent->node); + + parent = of_get_parent(dn); + if (parent) + of_node_put(parent); dn->data = NULL; kfree(pdn); diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index ea3d98115b88..0d790f8432d2 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -211,19 +211,19 @@ void of_scan_pci_bridge(struct pci_dev *dev) unsigned int flags; u64 size; - pr_debug("of_scan_pci_bridge(%s)\n", node->full_name); + pr_debug("of_scan_pci_bridge(%pOF)\n", node); /* parse bus-range property */ busrange = of_get_property(node, "bus-range", &len); if (busrange == NULL || len != 8) { - printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", - node->full_name); + printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %pOF\n", + node); return; } ranges = of_get_property(node, "ranges", &len); if (ranges == NULL) { - printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", - node->full_name); + printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %pOF\n", + node); return; } @@ -233,8 +233,8 @@ void of_scan_pci_bridge(struct pci_dev *dev) bus = pci_add_new_bus(dev->bus, dev, of_read_number(busrange, 1)); if (!bus) { - printk(KERN_ERR "Failed to create pci bus for %s\n", - node->full_name); + printk(KERN_ERR "Failed to create pci bus for %pOF\n", + node); return; } } @@ -262,13 +262,13 @@ void of_scan_pci_bridge(struct pci_dev *dev) res = bus->resource[0]; if (res->flags) { printk(KERN_ERR "PCI: ignoring extra I/O range" - " for bridge %s\n", node->full_name); + " for bridge %pOF\n", node); continue; } } else { if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { printk(KERN_ERR "PCI: too many memory ranges" - " for bridge %s\n", node->full_name); + " for bridge %pOF\n", node); continue; } res = bus->resource[i]; @@ -307,7 +307,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, struct eeh_dev *edev = pdn_to_eeh_dev(PCI_DN(dn)); #endif - pr_debug(" * %s\n", dn->full_name); + pr_debug(" * %pOF\n", dn); if (!of_device_is_available(dn)) return NULL; @@ -350,8 +350,8 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus, struct device_node *child; struct pci_dev *dev; - pr_debug("of_scan_bus(%s) bus no %d...\n", - node->full_name, bus->number); + pr_debug("of_scan_bus(%pOF) bus no %d...\n", + node, bus->number); /* Scan direct children */ for_each_child_of_node(node, child) { diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 1f0fd361e09b..a0c74bbf3454 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -230,7 +230,8 @@ void enable_kernel_fp(void) } EXPORT_SYMBOL(enable_kernel_fp); -static int restore_fp(struct task_struct *tsk) { +static int restore_fp(struct task_struct *tsk) +{ if (tsk->thread.load_fp || msr_tm_active(tsk->thread.regs->msr)) { load_fp_state(¤t->thread.fp_state); current->thread.load_fp++; @@ -330,11 +331,19 @@ static inline int restore_altivec(struct task_struct *tsk) { return 0; } #ifdef CONFIG_VSX static void __giveup_vsx(struct task_struct *tsk) { - if (tsk->thread.regs->msr & MSR_FP) + unsigned long msr = tsk->thread.regs->msr; + + /* + * We should never be ssetting MSR_VSX without also setting + * MSR_FP and MSR_VEC + */ + WARN_ON((msr & MSR_VSX) && !((msr & MSR_FP) && (msr & MSR_VEC))); + + /* __giveup_fpu will clear MSR_VSX */ + if (msr & MSR_FP) __giveup_fpu(tsk); - if (tsk->thread.regs->msr & MSR_VEC) + if (msr & MSR_VEC) __giveup_altivec(tsk); - tsk->thread.regs->msr &= ~MSR_VSX; } static void giveup_vsx(struct task_struct *tsk) @@ -346,14 +355,6 @@ static void giveup_vsx(struct task_struct *tsk) msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); } -static void save_vsx(struct task_struct *tsk) -{ - if (tsk->thread.regs->msr & MSR_FP) - save_fpu(tsk); - if (tsk->thread.regs->msr & MSR_VEC) - save_altivec(tsk); -} - void enable_kernel_vsx(void) { unsigned long cpumsr; @@ -374,10 +375,6 @@ void enable_kernel_vsx(void) */ if(!msr_tm_active(cpumsr) && msr_tm_active(current->thread.regs->msr)) return; - if (current->thread.regs->msr & MSR_FP) - __giveup_fpu(current); - if (current->thread.regs->msr & MSR_VEC) - __giveup_altivec(current); __giveup_vsx(current); } } @@ -407,7 +404,6 @@ static int restore_vsx(struct task_struct *tsk) } #else static inline int restore_vsx(struct task_struct *tsk) { return 0; } -static inline void save_vsx(struct task_struct *tsk) { } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE @@ -487,6 +483,8 @@ void giveup_all(struct task_struct *tsk) msr_check_and_set(msr_all_available); check_if_tm_restore_required(tsk); + WARN_ON((usermsr & MSR_VSX) && !((usermsr & MSR_FP) && (usermsr & MSR_VEC))); + #ifdef CONFIG_PPC_FPU if (usermsr & MSR_FP) __giveup_fpu(tsk); @@ -495,10 +493,6 @@ void giveup_all(struct task_struct *tsk) if (usermsr & MSR_VEC) __giveup_altivec(tsk); #endif -#ifdef CONFIG_VSX - if (usermsr & MSR_VSX) - __giveup_vsx(tsk); -#endif #ifdef CONFIG_SPE if (usermsr & MSR_SPE) __giveup_spe(tsk); @@ -553,19 +547,13 @@ void save_all(struct task_struct *tsk) msr_check_and_set(msr_all_available); - /* - * Saving the way the register space is in hardware, save_vsx boils - * down to a save_fpu() and save_altivec() - */ - if (usermsr & MSR_VSX) { - save_vsx(tsk); - } else { - if (usermsr & MSR_FP) - save_fpu(tsk); + WARN_ON((usermsr & MSR_VSX) && !((usermsr & MSR_FP) && (usermsr & MSR_VEC))); - if (usermsr & MSR_VEC) - save_altivec(tsk); - } + if (usermsr & MSR_FP) + save_fpu(tsk); + + if (usermsr & MSR_VEC) + save_altivec(tsk); if (usermsr & MSR_SPE) __giveup_spe(tsk); @@ -1392,13 +1380,13 @@ void show_regs(struct pt_regs * regs) show_regs_print_info(KERN_DEFAULT); - printk("NIP: "REG" LR: "REG" CTR: "REG"\n", + printk("NIP: "REG" LR: "REG" CTR: "REG"\n", regs->nip, regs->link, regs->ctr); printk("REGS: %p TRAP: %04lx %s (%s)\n", regs, regs->trap, print_tainted(), init_utsname()->release); - printk("MSR: "REG" ", regs->msr); + printk("MSR: "REG" ", regs->msr); print_msr_bits(regs->msr); - printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); + pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); trap = TRAP(regs); if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) pr_cont("CFAR: "REG" ", regs->orig_gpr3); @@ -1991,11 +1979,25 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) void notrace __ppc64_runlatch_on(void) { struct thread_info *ti = current_thread_info(); - unsigned long ctrl; - ctrl = mfspr(SPRN_CTRLF); - ctrl |= CTRL_RUNLATCH; - mtspr(SPRN_CTRLT, ctrl); + if (cpu_has_feature(CPU_FTR_ARCH_206)) { + /* + * Least significant bit (RUN) is the only writable bit of + * the CTRL register, so we can avoid mfspr. 2.06 is not the + * earliest ISA where this is the case, but it's convenient. + */ + mtspr(SPRN_CTRLT, CTRL_RUNLATCH); + } else { + unsigned long ctrl; + + /* + * Some architectures (e.g., Cell) have writable fields other + * than RUN, so do the read-modify-write. + */ + ctrl = mfspr(SPRN_CTRLF); + ctrl |= CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); + } ti->local_flags |= _TLF_RUNLATCH; } @@ -2004,13 +2006,18 @@ void notrace __ppc64_runlatch_on(void) void notrace __ppc64_runlatch_off(void) { struct thread_info *ti = current_thread_info(); - unsigned long ctrl; ti->local_flags &= ~_TLF_RUNLATCH; - ctrl = mfspr(SPRN_CTRLF); - ctrl &= ~CTRL_RUNLATCH; - mtspr(SPRN_CTRLT, ctrl); + if (cpu_has_feature(CPU_FTR_ARCH_206)) { + mtspr(SPRN_CTRLT, 0); + } else { + unsigned long ctrl; + + ctrl = mfspr(SPRN_CTRLF); + ctrl &= ~CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); + } } #endif /* CONFIG_PPC64 */ diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 613f79f03877..02190e90c7ae 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -177,6 +177,7 @@ struct platform_support { bool hash_mmu; bool radix_mmu; bool radix_gtse; + bool xive; }; /* Platforms codes are now obsolete in the kernel. Now only used within this @@ -1041,6 +1042,27 @@ static void __init prom_parse_mmu_model(u8 val, } } +static void __init prom_parse_xive_model(u8 val, + struct platform_support *support) +{ + switch (val) { + case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */ + prom_debug("XIVE - either mode supported\n"); + support->xive = true; + break; + case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */ + prom_debug("XIVE - exploitation mode supported\n"); + support->xive = true; + break; + case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */ + prom_debug("XIVE - legacy mode supported\n"); + break; + default: + prom_debug("Unknown xive support option: 0x%x\n", val); + break; + } +} + static void __init prom_parse_platform_support(u8 index, u8 val, struct platform_support *support) { @@ -1054,6 +1076,10 @@ static void __init prom_parse_platform_support(u8 index, u8 val, support->radix_gtse = true; } break; + case OV5_INDX(OV5_XIVE_SUPPORT): /* Interrupt mode */ + prom_parse_xive_model(val & OV5_FEAT(OV5_XIVE_SUPPORT), + support); + break; } } @@ -1062,7 +1088,8 @@ static void __init prom_check_platform_support(void) struct platform_support supported = { .hash_mmu = false, .radix_mmu = false, - .radix_gtse = false + .radix_gtse = false, + .xive = false }; int prop_len = prom_getproplen(prom.chosen, "ibm,arch-vec-5-platform-support"); @@ -1095,6 +1122,11 @@ static void __init prom_check_platform_support(void) /* We're probably on a legacy hypervisor */ prom_debug("Assuming legacy hash support\n"); } + + if (supported.xive) { + prom_debug("Asking for XIVE\n"); + ibm_architecture_vec.vec5.intarch = OV5_FEAT(OV5_XIVE_EXPLOIT); + } } static void __init prom_send_capabilities(void) diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 6295e646f78c..9cb7f88df563 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #undef DEBUG #include diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 660ed39e9c9a..f52ad5bb7109 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -131,7 +131,7 @@ static void flush_tmregs_to_thread(struct task_struct *tsk) * in the appropriate thread structures from live. */ - if (tsk != current) + if ((!cpu_has_feature(CPU_FTR_TM)) || (tsk != current)) return; if (MSR_TM_SUSPENDED(mfmsr())) { @@ -1594,11 +1594,8 @@ static int ppr_get(struct task_struct *target, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - int ret; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.ppr, 0, sizeof(u64)); - return ret; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.ppr, 0, sizeof(u64)); } static int ppr_set(struct task_struct *target, @@ -1606,11 +1603,8 @@ static int ppr_set(struct task_struct *target, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - int ret; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.ppr, 0, sizeof(u64)); - return ret; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.ppr, 0, sizeof(u64)); } static int dscr_get(struct task_struct *target, @@ -1618,22 +1612,16 @@ static int dscr_get(struct task_struct *target, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - int ret; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.dscr, 0, sizeof(u64)); - return ret; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.dscr, 0, sizeof(u64)); } static int dscr_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; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.dscr, 0, sizeof(u64)); - return ret; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.dscr, 0, sizeof(u64)); } #endif #ifdef CONFIG_PPC_BOOK3S_64 @@ -1642,22 +1630,16 @@ static int tar_get(struct task_struct *target, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { - int ret; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.tar, 0, sizeof(u64)); - return ret; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.tar, 0, sizeof(u64)); } static int tar_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; - - ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, - &target->thread.tar, 0, sizeof(u64)); - return ret; + return user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &target->thread.tar, 0, sizeof(u64)); } static int ebb_active(struct task_struct *target, diff --git a/arch/powerpc/kernel/reloc_64.S b/arch/powerpc/kernel/reloc_64.S index d88736fbece6..e8cfc69f59ae 100644 --- a/arch/powerpc/kernel/reloc_64.S +++ b/arch/powerpc/kernel/reloc_64.S @@ -82,7 +82,7 @@ _GLOBAL(relocate) 6: blr .balign 8 -p_dyn: .llong __dynamic_start - 0b -p_rela: .llong __rela_dyn_start - 0b -p_st: .llong _stext - 0b +p_dyn: .8byte __dynamic_start - 0b +p_rela: .8byte __rela_dyn_start - 0b +p_st: .8byte _stext - 0b diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index df56dfc4b681..c8c5f3a550c2 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2000 Tilmann Bitterberg * (tilmann@bitterberg.de) diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c index c57c19358a26..49600985c7ef 100644 --- a/arch/powerpc/kernel/rtas-rtc.c +++ b/arch/powerpc/kernel/rtas-rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index b8a4987f58cf..1643e9e53655 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -914,7 +914,7 @@ int rtas_online_cpus_mask(cpumask_var_t cpus) if (ret) { cpumask_var_t tmp_mask; - if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY)) + if (!alloc_cpumask_var(&tmp_mask, GFP_KERNEL)) return ret; /* Use tmp_mask to preserve cpus mask from first failure */ @@ -962,7 +962,7 @@ int rtas_ibm_suspend_me(u64 handle) return -EIO; } - if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) + if (!alloc_cpumask_var(&offline_mask, GFP_KERNEL)) return -ENOMEM; atomic_set(&data.working, 0); diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 73f1934582c2..c2b148b1634a 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -91,26 +91,14 @@ static int rtas_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { - struct device_node *busdn, *dn; struct pci_dn *pdn; - bool found = false; int ret; - /* Search only direct children of the bus */ *val = 0xFFFFFFFF; - busdn = pci_bus_to_OF_node(bus); - for (dn = busdn->child; dn; dn = dn->sibling) { - pdn = PCI_DN(dn); - if (pdn && pdn->devfn == devfn - && of_device_is_available(dn)) { - found = true; - break; - } - } - if (!found) - return PCIBIOS_DEVICE_NOT_FOUND; + pdn = pci_get_pdn_by_devfn(bus, devfn); + /* Validity of pdn is checked in here */ ret = rtas_read_config(pdn, where, size, val); if (*val == EEH_IO_ERROR_VALUE(size) && eeh_dev_check_failure(pdn_to_eeh_dev(pdn))) @@ -153,24 +141,11 @@ static int rtas_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - struct device_node *busdn, *dn; struct pci_dn *pdn; - bool found = false; - /* Search only direct children of the bus */ - busdn = pci_bus_to_OF_node(bus); - for (dn = busdn->child; dn; dn = dn->sibling) { - pdn = PCI_DN(dn); - if (pdn && pdn->devfn == devfn - && of_device_is_available(dn)) { - found = true; - break; - } - } - - if (!found) - return PCIBIOS_DEVICE_NOT_FOUND; + pdn = pci_get_pdn_by_devfn(bus, devfn); + /* Validity of pdn is checked in here. */ return rtas_write_config(pdn, where, size, val); } diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 94a948207cd2..2e3bc16d02b2 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -481,7 +481,7 @@ void __init smp_setup_cpu_maps(void) __be32 cpu_be; int j, len; - DBG(" * %s...\n", dn->full_name); + DBG(" * %pOF...\n", dn); intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len); @@ -551,7 +551,7 @@ void __init smp_setup_cpu_maps(void) if (maxcpus > nr_cpu_ids) { printk(KERN_WARNING "Partition configured for %d cpus, " - "operating system maximum is %d.\n", + "operating system maximum is %u.\n", maxcpus, nr_cpu_ids); maxcpus = nr_cpu_ids; } else @@ -704,30 +704,6 @@ int check_legacy_ioport(unsigned long base_port) } EXPORT_SYMBOL(check_legacy_ioport); -static int ppc_panic_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - /* - * If firmware-assisted dump has been registered then trigger - * firmware-assisted dump and let firmware handle everything else. - */ - crash_fadump(NULL, ptr); - ppc_md.panic(ptr); /* May not return */ - return NOTIFY_DONE; -} - -static struct notifier_block ppc_panic_block = { - .notifier_call = ppc_panic_event, - .priority = INT_MIN /* may not return; must be done last */ -}; - -void __init setup_panic(void) -{ - if (!ppc_md.panic) - return; - atomic_notifier_chain_register(&panic_notifier_list, &ppc_panic_block); -} - #ifdef CONFIG_CHECK_CACHE_COHERENCY /* * For platforms that have configurable cache-coherency. This function @@ -872,9 +848,6 @@ void __init setup_arch(char **cmdline_p) /* Probe the machine type, establish ppc_md. */ probe_machine(); - /* Setup panic notifier if requested by the platform. */ - setup_panic(); - /* * Configure ppc_md.power_save (ppc32 only, 64-bit machines do * it from their respective probe() function. @@ -916,13 +889,6 @@ void __init setup_arch(char **cmdline_p) /* Reserve large chunks of memory for use by CMA for KVM. */ kvm_cma_reserve(); - /* - * Reserve any gigantic pages requested on the command line. - * memblock needs to have been initialized by the time this is - * called since this will reserve memory. - */ - reserve_hugetlb_gpages(); - klp_init_thread_info(&init_thread_info); init_mm.start_code = (unsigned long)_stext; @@ -938,9 +904,6 @@ void __init setup_arch(char **cmdline_p) #endif #endif -#ifdef CONFIG_PPC_64K_PAGES - init_mm.context.pte_frag = NULL; -#endif #ifdef CONFIG_SPAPR_TCE_IOMMU mm_iommu_init(&init_mm); #endif diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 2f88f6cf1a42..51ebc01fff52 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -98,6 +98,9 @@ extern unsigned int memset_nocache_branch; /* Insn to be replaced by NOP */ notrace void __init machine_init(u64 dt_ptr) { + unsigned int *addr = &memset_nocache_branch; + unsigned long insn; + /* Configure static keys first, now that we're relocated. */ setup_feature_keys(); @@ -105,7 +108,9 @@ notrace void __init machine_init(u64 dt_ptr) udbg_early_init(); patch_instruction((unsigned int *)&memcpy, PPC_INST_NOP); - patch_instruction(&memset_nocache_branch, PPC_INST_NOP); + + insn = create_cond_branch(addr, branch_target(addr), 0x820000); + patch_instruction(addr, insn); /* replace b by bne cr0 */ /* Do some early initialization based on the flat device tree */ early_init_devtree(__va(dt_ptr)); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index af23d4b576ec..b89c6aac48c9 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -564,6 +564,9 @@ static __init u64 safe_stack_limit(void) /* Other BookE, we assume the first GB is bolted */ return 1ul << 30; #else + if (early_radix_enabled()) + return ULONG_MAX; + /* BookS, the first segment is bolted */ if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) return 1UL << SID_SHIFT_1T; @@ -578,7 +581,8 @@ void __init irqstack_early_init(void) /* * Interrupt stacks must be in the first segment since we - * cannot afford to take SLB misses on them. + * cannot afford to take SLB misses on them. They are not + * accessed in realmode. */ for_each_possible_cpu(i) { softirq_ctx[i] = (struct thread_info *) @@ -649,8 +653,9 @@ void __init emergency_stack_init(void) * aligned. * * Since we use these as temporary stacks during secondary CPU - * bringup, we need to get at them in real mode. This means they - * must also be within the RMO region. + * bringup, machine check, system reset, and HMI, we need to get + * at them in real mode. This means they must also be within the RMO + * region. * * The IRQ stacks allocated elsewhere in this file are zeroed and * initialized in kernel/irq.c. These are initialized here in order @@ -751,3 +756,31 @@ unsigned long memory_block_size_bytes(void) struct ppc_pci_io ppc_pci_io; EXPORT_SYMBOL(ppc_pci_io); #endif + +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF +u64 hw_nmi_get_sample_period(int watchdog_thresh) +{ + return ppc_proc_freq * watchdog_thresh; +} +#endif + +/* + * The perf based hardlockup detector breaks PMU event based branches, so + * disable it by default. Book3S has a soft-nmi hardlockup detector based + * on the decrementer interrupt, so it does not suffer from this problem. + * + * It is likely to get false positives in VM guests, so disable it there + * by default too. + */ +static int __init disable_hardlockup_detector(void) +{ +#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF + hardlockup_detector_disable(); +#else + if (firmware_has_feature(FW_FEATURE_LPAR)) + hardlockup_detector_disable(); +#endif + + return 0; +} +early_initcall(disable_hardlockup_detector); diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 97bb1385e771..92fb1c8dbbd8 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -913,42 +913,40 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, const siginfo_t *s) */ err = __put_user(s->si_signo, &d->si_signo); err |= __put_user(s->si_errno, &d->si_errno); - err |= __put_user((short)s->si_code, &d->si_code); + err |= __put_user(s->si_code, &d->si_code); if (s->si_code < 0) err |= __copy_to_user(&d->_sifields._pad, &s->_sifields._pad, SI_PAD_SIZE32); - else switch(s->si_code >> 16) { - case __SI_CHLD >> 16: + else switch(siginfo_layout(s->si_signo, s->si_code)) { + case SIL_CHLD: err |= __put_user(s->si_pid, &d->si_pid); err |= __put_user(s->si_uid, &d->si_uid); err |= __put_user(s->si_utime, &d->si_utime); err |= __put_user(s->si_stime, &d->si_stime); err |= __put_user(s->si_status, &d->si_status); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user((unsigned int)(unsigned long)s->si_addr, &d->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(s->si_band, &d->si_band); err |= __put_user(s->si_fd, &d->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(s->si_tid, &d->si_tid); err |= __put_user(s->si_overrun, &d->si_overrun); err |= __put_user(s->si_int, &d->si_int); break; - case __SI_SYS >> 16: + case SIL_SYS: err |= __put_user(ptr_to_compat(s->si_call_addr), &d->si_call_addr); err |= __put_user(s->si_syscall, &d->si_syscall); err |= __put_user(s->si_arch, &d->si_arch); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(s->si_int, &d->si_int); /* fallthrough */ - case __SI_KILL >> 16: - default: + case SIL_KILL: err |= __put_user(s->si_pid, &d->si_pid); err |= __put_user(s->si_uid, &d->si_uid); break; diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index c83c115858c1..b2c002993d78 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -452,9 +452,20 @@ static long restore_tm_sigcontexts(struct task_struct *tsk, if (MSR_TM_RESV(msr)) return -EINVAL; - /* pull in MSR TM from user context */ + /* pull in MSR TS bits from user context */ regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK); + /* + * Ensure that TM is enabled in regs->msr before we leave the signal + * handler. It could be the case that (a) user disabled the TM bit + * through the manipulation of the MSR bits in uc_mcontext or (b) the + * TM bit was disabled because a sufficient number of context switches + * happened whilst in the signal handler and load_tm overflowed, + * disabling the TM bit. In either case we can end up with an illegal + * TM state leading to a TM Bad Thing when we return to userspace. + */ + regs->msr |= MSR_TM; + /* pull in MSR LE from user context */ regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE); diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index 7a37ecd3afa3..21c39355b25e 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Smp timebase synchronization for ppc. * diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 8d3320562c70..e0a4c1f82e25 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -75,9 +75,11 @@ static DEFINE_PER_CPU(int, cpu_state) = { 0 }; struct thread_info *secondary_ti; DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); +DEFINE_PER_CPU(cpumask_var_t, cpu_l2_cache_map); DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); +EXPORT_PER_CPU_SYMBOL(cpu_l2_cache_map); EXPORT_PER_CPU_SYMBOL(cpu_core_map); /* SMP operations for this machine */ @@ -571,6 +573,26 @@ static void smp_store_cpu_info(int id) #endif } +/* + * Relationships between CPUs are maintained in a set of per-cpu cpumasks so + * rather than just passing around the cpumask we pass around a function that + * returns the that cpumask for the given CPU. + */ +static void set_cpus_related(int i, int j, struct cpumask *(*get_cpumask)(int)) +{ + cpumask_set_cpu(i, get_cpumask(j)); + cpumask_set_cpu(j, get_cpumask(i)); +} + +#ifdef CONFIG_HOTPLUG_CPU +static void set_cpus_unrelated(int i, int j, + struct cpumask *(*get_cpumask)(int)) +{ + cpumask_clear_cpu(i, get_cpumask(j)); + cpumask_clear_cpu(j, get_cpumask(i)); +} +#endif + void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int cpu; @@ -590,6 +612,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) for_each_possible_cpu(cpu) { zalloc_cpumask_var_node(&per_cpu(cpu_sibling_map, cpu), GFP_KERNEL, cpu_to_node(cpu)); + zalloc_cpumask_var_node(&per_cpu(cpu_l2_cache_map, cpu), + GFP_KERNEL, cpu_to_node(cpu)); zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu), GFP_KERNEL, cpu_to_node(cpu)); /* @@ -602,7 +626,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } } + /* Init the cpumasks so the boot CPU is related to itself */ cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid)); + cpumask_set_cpu(boot_cpuid, cpu_l2_cache_mask(boot_cpuid)); cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid)); if (smp_ops && smp_ops->probe) @@ -828,33 +854,6 @@ int cpu_first_thread_of_core(int core) } EXPORT_SYMBOL_GPL(cpu_first_thread_of_core); -static void traverse_siblings_chip_id(int cpu, bool add, int chipid) -{ - const struct cpumask *mask; - struct device_node *np; - int i, plen; - const __be32 *prop; - - mask = add ? cpu_online_mask : cpu_present_mask; - for_each_cpu(i, mask) { - np = of_get_cpu_node(i, NULL); - if (!np) - continue; - prop = of_get_property(np, "ibm,chip-id", &plen); - if (prop && plen == sizeof(int) && - of_read_number(prop, 1) == chipid) { - if (add) { - cpumask_set_cpu(cpu, cpu_core_mask(i)); - cpumask_set_cpu(i, cpu_core_mask(cpu)); - } else { - cpumask_clear_cpu(cpu, cpu_core_mask(i)); - cpumask_clear_cpu(i, cpu_core_mask(cpu)); - } - } - of_node_put(np); - } -} - /* Must be called when no change can occur to cpu_present_mask, * i.e. during cpu online or offline. */ @@ -877,52 +876,93 @@ static struct device_node *cpu_to_l2cache(int cpu) return cache; } -static void traverse_core_siblings(int cpu, bool add) +static bool update_mask_by_l2(int cpu, struct cpumask *(*mask_fn)(int)) { struct device_node *l2_cache, *np; - const struct cpumask *mask; - int i, chip, plen; - const __be32 *prop; - - /* First see if we have ibm,chip-id properties in cpu nodes */ - np = of_get_cpu_node(cpu, NULL); - if (np) { - chip = -1; - prop = of_get_property(np, "ibm,chip-id", &plen); - if (prop && plen == sizeof(int)) - chip = of_read_number(prop, 1); - of_node_put(np); - if (chip >= 0) { - traverse_siblings_chip_id(cpu, add, chip); - return; - } - } + int i; l2_cache = cpu_to_l2cache(cpu); - mask = add ? cpu_online_mask : cpu_present_mask; - for_each_cpu(i, mask) { + if (!l2_cache) + return false; + + for_each_cpu(i, cpu_online_mask) { + /* + * when updating the marks the current CPU has not been marked + * online, but we need to update the cache masks + */ np = cpu_to_l2cache(i); if (!np) continue; - if (np == l2_cache) { - if (add) { - cpumask_set_cpu(cpu, cpu_core_mask(i)); - cpumask_set_cpu(i, cpu_core_mask(cpu)); - } else { - cpumask_clear_cpu(cpu, cpu_core_mask(i)); - cpumask_clear_cpu(i, cpu_core_mask(cpu)); - } - } + + if (np == l2_cache) + set_cpus_related(cpu, i, mask_fn); + of_node_put(np); } of_node_put(l2_cache); + + return true; } +#ifdef CONFIG_HOTPLUG_CPU +static void remove_cpu_from_masks(int cpu) +{ + int i; + + /* NB: cpu_core_mask is a superset of the others */ + for_each_cpu(i, cpu_core_mask(cpu)) { + set_cpus_unrelated(cpu, i, cpu_core_mask); + set_cpus_unrelated(cpu, i, cpu_l2_cache_mask); + set_cpus_unrelated(cpu, i, cpu_sibling_mask); + } +} +#endif + +static void add_cpu_to_masks(int cpu) +{ + int first_thread = cpu_first_thread_sibling(cpu); + int chipid = cpu_to_chip_id(cpu); + int i; + + /* + * This CPU will not be in the online mask yet so we need to manually + * add it to it's own thread sibling mask. + */ + cpumask_set_cpu(cpu, cpu_sibling_mask(cpu)); + + for (i = first_thread; i < first_thread + threads_per_core; i++) + if (cpu_online(i)) + set_cpus_related(i, cpu, cpu_sibling_mask); + + /* + * Copy the thread sibling mask into the cache sibling mask + * and mark any CPUs that share an L2 with this CPU. + */ + for_each_cpu(i, cpu_sibling_mask(cpu)) + set_cpus_related(cpu, i, cpu_l2_cache_mask); + update_mask_by_l2(cpu, cpu_l2_cache_mask); + + /* + * Copy the cache sibling mask into core sibling mask and mark + * any CPUs on the same chip as this CPU. + */ + for_each_cpu(i, cpu_l2_cache_mask(cpu)) + set_cpus_related(cpu, i, cpu_core_mask); + + if (chipid == -1) + return; + + for_each_cpu(i, cpu_online_mask) + if (cpu_to_chip_id(i) == chipid) + set_cpus_related(cpu, i, cpu_core_mask); +} + +static bool shared_caches; + /* Activate a secondary processor. */ void start_secondary(void *unused) { unsigned int cpu = smp_processor_id(); - int i, base; mmgrab(&init_mm); current->active_mm = &init_mm; @@ -945,22 +985,15 @@ void start_secondary(void *unused) vdso_getcpu_init(); #endif - /* Update sibling maps */ - base = cpu_first_thread_sibling(cpu); - for (i = 0; i < threads_per_core; i++) { - if (cpu_is_offline(base + i) && (cpu != base + i)) - continue; - cpumask_set_cpu(cpu, cpu_sibling_mask(base + i)); - cpumask_set_cpu(base + i, cpu_sibling_mask(cpu)); + /* Update topology CPU masks */ + add_cpu_to_masks(cpu); - /* cpu_core_map should be a superset of - * cpu_sibling_map even if we don't have cache - * information, so update the former here, too. - */ - cpumask_set_cpu(cpu, cpu_core_mask(base + i)); - cpumask_set_cpu(base + i, cpu_core_mask(cpu)); - } - traverse_core_siblings(cpu, true); + /* + * Check for any shared caches. Note that this must be done on a + * per-core basis because one core in the pair might be disabled. + */ + if (!cpumask_equal(cpu_l2_cache_mask(cpu), cpu_sibling_mask(cpu))) + shared_caches = true; set_numa_node(numa_cpu_lookup_table[cpu]); set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu])); @@ -1003,6 +1036,35 @@ static struct sched_domain_topology_level powerpc_topology[] = { { NULL, }, }; +/* + * P9 has a slightly odd architecture where pairs of cores share an L2 cache. + * This topology makes it *much* cheaper to migrate tasks between adjacent cores + * since the migrated task remains cache hot. We want to take advantage of this + * at the scheduler level so an extra topology level is required. + */ +static int powerpc_shared_cache_flags(void) +{ + return SD_SHARE_PKG_RESOURCES; +} + +/* + * We can't just pass cpu_l2_cache_mask() directly because + * returns a non-const pointer and the compiler barfs on that. + */ +static const struct cpumask *shared_cache_mask(int cpu) +{ + return cpu_l2_cache_mask(cpu); +} + +static struct sched_domain_topology_level power9_topology[] = { +#ifdef CONFIG_SCHED_SMT + { cpu_smt_mask, powerpc_smt_flags, SD_INIT_NAME(SMT) }, +#endif + { shared_cache_mask, powerpc_shared_cache_flags, SD_INIT_NAME(CACHE) }, + { cpu_cpu_mask, SD_INIT_NAME(DIE) }, + { NULL, }, +}; + void __init smp_cpus_done(unsigned int max_cpus) { /* @@ -1016,14 +1078,23 @@ void __init smp_cpus_done(unsigned int max_cpus) dump_numa_cpu_topology(); - set_sched_topology(powerpc_topology); + /* + * If any CPU detects that it's sharing a cache with another CPU then + * use the deeper topology that is aware of this sharing. + */ + if (shared_caches) { + pr_info("Using shared cache scheduler topology\n"); + set_sched_topology(power9_topology); + } else { + pr_info("Using standard scheduler topology\n"); + set_sched_topology(powerpc_topology); + } } #ifdef CONFIG_HOTPLUG_CPU int __cpu_disable(void) { int cpu = smp_processor_id(); - int base, i; int err; if (!smp_ops->cpu_disable) @@ -1034,14 +1105,7 @@ int __cpu_disable(void) return err; /* Update sibling maps */ - base = cpu_first_thread_sibling(cpu); - for (i = 0; i < threads_per_core && base + i < nr_cpu_ids; i++) { - cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); - cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); - cpumask_clear_cpu(cpu, cpu_core_mask(base + i)); - cpumask_clear_cpu(base + i, cpu_core_mask(cpu)); - } - traverse_core_siblings(cpu, false); + remove_cpu_from_masks(cpu); return 0; } diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S index ba4dee3d233f..34b73a262709 100644 --- a/arch/powerpc/kernel/swsusp_32.S +++ b/arch/powerpc/kernel/swsusp_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/powerpc/kernel/swsusp_asm64.S b/arch/powerpc/kernel/swsusp_asm64.S index 988f38dced0f..82d8aae81c6a 100644 --- a/arch/powerpc/kernel/swsusp_asm64.S +++ b/arch/powerpc/kernel/swsusp_asm64.S @@ -179,7 +179,7 @@ nothing_to_copy: sld r3, r3, r0 li r0, 0 1: - dcbf r0,r3 + dcbf 0,r3 addi r3,r3,0x20 bdnz 1b diff --git a/arch/powerpc/kernel/swsusp_booke.S b/arch/powerpc/kernel/swsusp_booke.S index 553c1405ee05..88cfdbd530f1 100644 --- a/arch/powerpc/kernel/swsusp_booke.S +++ b/arch/powerpc/kernel/swsusp_booke.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Based on swsusp_32.S, modified for FSL BookE by * Anton Vorontsov diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index 4d6b1d3a747f..7ccb7f81f8db 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S @@ -17,13 +17,13 @@ #include #ifdef CONFIG_PPC64 -#define SYSCALL(func) .llong DOTSYM(sys_##func),DOTSYM(sys_##func) -#define COMPAT_SYS(func) .llong DOTSYM(sys_##func),DOTSYM(compat_sys_##func) -#define PPC_SYS(func) .llong DOTSYM(ppc_##func),DOTSYM(ppc_##func) -#define OLDSYS(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(sys_ni_syscall) -#define SYS32ONLY(func) .llong DOTSYM(sys_ni_syscall),DOTSYM(compat_sys_##func) -#define PPC64ONLY(func) .llong DOTSYM(ppc_##func),DOTSYM(sys_ni_syscall) -#define SYSX(f, f3264, f32) .llong DOTSYM(f),DOTSYM(f3264) +#define SYSCALL(func) .8byte DOTSYM(sys_##func),DOTSYM(sys_##func) +#define COMPAT_SYS(func) .8byte DOTSYM(sys_##func),DOTSYM(compat_sys_##func) +#define PPC_SYS(func) .8byte DOTSYM(ppc_##func),DOTSYM(ppc_##func) +#define OLDSYS(func) .8byte DOTSYM(sys_ni_syscall),DOTSYM(sys_ni_syscall) +#define SYS32ONLY(func) .8byte DOTSYM(sys_ni_syscall),DOTSYM(compat_sys_##func) +#define PPC64ONLY(func) .8byte DOTSYM(ppc_##func),DOTSYM(sys_ni_syscall) +#define SYSX(f, f3264, f32) .8byte DOTSYM(f),DOTSYM(f3264) #else #define SYSCALL(func) .long sys_##func #define COMPAT_SYS(func) .long sys_##func diff --git a/arch/powerpc/kernel/tau_6xx.c b/arch/powerpc/kernel/tau_6xx.c index a753b72efbc0..a3374e8a258c 100644 --- a/arch/powerpc/kernel/tau_6xx.c +++ b/arch/powerpc/kernel/tau_6xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * temp.c Thermal management for cpu's with Thermal Assist Units * diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index c4ba37822ba0..1da12f521cb7 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Transactional memory support routines to reclaim and recheckpoint * transactional process state. diff --git a/arch/powerpc/kernel/trace/Makefile b/arch/powerpc/kernel/trace/Makefile index 729dffc5f7bc..d22d8bafb643 100644 --- a/arch/powerpc/kernel/trace/Makefile +++ b/arch/powerpc/kernel/trace/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the powerpc trace subsystem # diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 32509de6ce4c..4741fe112f05 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Code for replacing ftrace calls with jumps. * diff --git a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S index c98e90b4ea7b..b4e2b7165f79 100644 --- a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S +++ b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S @@ -181,34 +181,25 @@ _GLOBAL(ftrace_stub) * - we have no stack frame and can not allocate one * - LR points back to the original caller (in A) * - CTR holds the new NIP in C - * - r0 & r12 are free - * - * r0 can't be used as the base register for a DS-form load or store, so - * we temporarily shuffle r1 (stack pointer) into r0 and then put it back. + * - r0, r11 & r12 are free */ livepatch_handler: CURRENT_THREAD_INFO(r12, r1) - /* Save stack pointer into r0 */ - mr r0, r1 - /* Allocate 3 x 8 bytes */ - ld r1, TI_livepatch_sp(r12) - addi r1, r1, 24 - std r1, TI_livepatch_sp(r12) + ld r11, TI_livepatch_sp(r12) + addi r11, r11, 24 + std r11, TI_livepatch_sp(r12) /* Save toc & real LR on livepatch stack */ - std r2, -24(r1) + std r2, -24(r11) mflr r12 - std r12, -16(r1) + std r12, -16(r11) /* Store stack end marker */ lis r12, STACK_END_MAGIC@h ori r12, r12, STACK_END_MAGIC@l - std r12, -8(r1) - - /* Restore real stack pointer */ - mr r1, r0 + std r12, -8(r11) /* Put ctr in r12 for global entry and branch there */ mfctr r12 @@ -216,36 +207,30 @@ livepatch_handler: /* * Now we are returning from the patched function to the original - * caller A. We are free to use r0 and r12, and we can use r2 until we + * caller A. We are free to use r11, r12 and we can use r2 until we * restore it. */ CURRENT_THREAD_INFO(r12, r1) - /* Save stack pointer into r0 */ - mr r0, r1 - - ld r1, TI_livepatch_sp(r12) + ld r11, TI_livepatch_sp(r12) /* Check stack marker hasn't been trashed */ lis r2, STACK_END_MAGIC@h ori r2, r2, STACK_END_MAGIC@l - ld r12, -8(r1) + ld r12, -8(r11) 1: tdne r12, r2 EMIT_BUG_ENTRY 1b, __FILE__, __LINE__ - 1, 0 /* Restore LR & toc from livepatch stack */ - ld r12, -16(r1) + ld r12, -16(r11) mtlr r12 - ld r2, -24(r1) + ld r2, -24(r11) /* Pop livepatch stack frame */ - CURRENT_THREAD_INFO(r12, r0) - subi r1, r1, 24 - std r1, TI_livepatch_sp(r12) - - /* Restore real stack pointer */ - mr r1, r0 + CURRENT_THREAD_INFO(r12, r1) + subi r11, r11, 24 + std r11, TI_livepatch_sp(r12) /* Return to original caller of live patched function */ blr diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index bfcfd9ef09f2..13c9dcdcba69 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -114,6 +114,28 @@ static void pmac_backlight_unblank(void) static inline void pmac_backlight_unblank(void) { } #endif +/* + * If oops/die is expected to crash the machine, return true here. + * + * This should not be expected to be 100% accurate, there may be + * notifiers registered or other unexpected conditions that may bring + * down the kernel. Or if the current process in the kernel is holding + * locks or has other critical state, the kernel may become effectively + * unusable anyway. + */ +bool die_will_crash(void) +{ + if (should_fadump_crash()) + return true; + if (kexec_should_crash(current)) + return true; + if (in_interrupt() || panic_on_oops || + !current->pid || is_global_init(current)) + return true; + + return false; +} + static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED; static int die_owner = -1; static unsigned int die_nest_count; @@ -162,21 +184,9 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, crash_fadump(regs, "die oops"); - /* - * A system reset (0x100) is a request to dump, so we always send - * it through the crashdump code. - */ - if (kexec_should_crash(current) || (TRAP(regs) == 0x100)) { + if (kexec_should_crash(current)) crash_kexec(regs); - /* - * We aren't the primary crash CPU. We need to send it - * to a holding pattern to avoid it ending up in the panic - * code. - */ - crash_kexec_secondary(regs); - } - if (!signr) return; @@ -202,18 +212,25 @@ NOKPROBE_SYMBOL(oops_end); static int __die(const char *str, struct pt_regs *regs, long err) { printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); -#ifdef CONFIG_PREEMPT - printk("PREEMPT "); -#endif -#ifdef CONFIG_SMP - printk("SMP NR_CPUS=%d ", NR_CPUS); -#endif + + if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) + printk("LE "); + else + printk("BE "); + + if (IS_ENABLED(CONFIG_PREEMPT)) + pr_cont("PREEMPT "); + + if (IS_ENABLED(CONFIG_SMP)) + pr_cont("SMP NR_CPUS=%d ", NR_CPUS); + if (debug_pagealloc_enabled()) - printk("DEBUG_PAGEALLOC "); -#ifdef CONFIG_NUMA - printk("NUMA "); -#endif - printk("%s\n", ppc_md.name ? ppc_md.name : ""); + pr_cont("DEBUG_PAGEALLOC "); + + if (IS_ENABLED(CONFIG_NUMA)) + pr_cont("NUMA "); + + pr_cont("%s\n", ppc_md.name ? ppc_md.name : ""); if (notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV) == NOTIFY_STOP) return 1; @@ -288,23 +305,52 @@ void system_reset_exception(struct pt_regs *regs) if (!nested) nmi_enter(); + __this_cpu_inc(irq_stat.sreset_irqs); + /* See if any machine dependent calls */ if (ppc_md.system_reset_exception) { if (ppc_md.system_reset_exception(regs)) goto out; } - die("System Reset", regs, SIGABRT); + if (debugger(regs)) + goto out; + + /* + * A system reset is a request to dump, so we always send + * it through the crashdump code (if fadump or kdump are + * registered). + */ + crash_fadump(regs, "System Reset"); + + crash_kexec(regs); + + /* + * We aren't the primary crash CPU. We need to send it + * to a holding pattern to avoid it ending up in the panic + * code. + */ + crash_kexec_secondary(regs); + + /* + * No debugger or crash dump registered, print logs then + * panic. + */ + __die("System Reset", regs, SIGABRT); + + mdelay(2*MSEC_PER_SEC); /* Wait a little while for others to print */ + add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); + nmi_panic(regs, "System Reset"); out: #ifdef CONFIG_PPC_BOOK3S_64 BUG_ON(get_paca()->in_nmi == 0); if (get_paca()->in_nmi > 1) - panic("Unrecoverable nested System Reset"); + nmi_panic(regs, "Unrecoverable nested System Reset"); #endif /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) - panic("Unrecoverable System Reset"); + nmi_panic(regs, "Unrecoverable System Reset"); if (!nested) nmi_exit(); @@ -312,39 +358,6 @@ out: /* What should we do here? We could issue a shutdown or hard reset. */ } -#ifdef CONFIG_PPC64 -/* - * This function is called in real mode. Strictly no printk's please. - * - * regs->nip and regs->msr contains srr0 and ssr1. - */ -long machine_check_early(struct pt_regs *regs) -{ - long handled = 0; - - __this_cpu_inc(irq_stat.mce_exceptions); - - if (cur_cpu_spec && cur_cpu_spec->machine_check_early) - handled = cur_cpu_spec->machine_check_early(regs); - return handled; -} - -long hmi_exception_realmode(struct pt_regs *regs) -{ - __this_cpu_inc(irq_stat.hmi_exceptions); - - wait_for_subcore_guest_exit(); - - if (ppc_md.hmi_exception_early) - ppc_md.hmi_exception_early(regs); - - wait_for_tb_resync(); - - return 0; -} - -#endif - /* * I/O accesses can cause machine checks on powermacs. * Check if the NIP corresponds to the address of a sync @@ -397,11 +410,6 @@ static inline int check_io_access(struct pt_regs *regs) /* On 4xx, the reason for the machine check or program exception is in the ESR. */ #define get_reason(regs) ((regs)->dsisr) -#ifndef CONFIG_FSL_BOOKE -#define get_mc_reason(regs) ((regs)->dsisr) -#else -#define get_mc_reason(regs) (mfspr(SPRN_MCSR)) -#endif #define REASON_FP ESR_FP #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) #define REASON_PRIVILEGED ESR_PPR @@ -415,111 +423,21 @@ static inline int check_io_access(struct pt_regs *regs) /* On non-4xx, the reason for the machine check or program exception is in the MSR. */ #define get_reason(regs) ((regs)->msr) -#define get_mc_reason(regs) ((regs)->msr) -#define REASON_TM 0x200000 -#define REASON_FP 0x100000 -#define REASON_ILLEGAL 0x80000 -#define REASON_PRIVILEGED 0x40000 -#define REASON_TRAP 0x20000 +#define REASON_TM SRR1_PROGTM +#define REASON_FP SRR1_PROGFPE +#define REASON_ILLEGAL SRR1_PROGILL +#define REASON_PRIVILEGED SRR1_PROGPRIV +#define REASON_TRAP SRR1_PROGTRAP #define single_stepping(regs) ((regs)->msr & MSR_SE) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif -#if defined(CONFIG_4xx) -int machine_check_4xx(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - - if (reason & ESR_IMCP) { - printk("Instruction"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - } else - printk("Data"); - printk(" machine check in kernel mode.\n"); - - return 0; -} - -int machine_check_440A(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - - printk("Machine check in kernel mode.\n"); - if (reason & ESR_IMCP){ - printk("Instruction Synchronous Machine Check exception\n"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - } - else { - u32 mcsr = mfspr(SPRN_MCSR); - if (mcsr & MCSR_IB) - printk("Instruction Read PLB Error\n"); - if (mcsr & MCSR_DRB) - printk("Data Read PLB Error\n"); - if (mcsr & MCSR_DWB) - printk("Data Write PLB Error\n"); - if (mcsr & MCSR_TLBP) - printk("TLB Parity Error\n"); - if (mcsr & MCSR_ICP){ - flush_instruction_cache(); - printk("I-Cache Parity Error\n"); - } - if (mcsr & MCSR_DCSP) - printk("D-Cache Search Parity Error\n"); - if (mcsr & MCSR_DCFP) - printk("D-Cache Flush Parity Error\n"); - if (mcsr & MCSR_IMPE) - printk("Machine Check exception is imprecise\n"); - - /* Clear MCSR */ - mtspr(SPRN_MCSR, mcsr); - } - return 0; -} - -int machine_check_47x(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - u32 mcsr; - - printk(KERN_ERR "Machine check in kernel mode.\n"); - if (reason & ESR_IMCP) { - printk(KERN_ERR - "Instruction Synchronous Machine Check exception\n"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - return 0; - } - mcsr = mfspr(SPRN_MCSR); - if (mcsr & MCSR_IB) - printk(KERN_ERR "Instruction Read PLB Error\n"); - if (mcsr & MCSR_DRB) - printk(KERN_ERR "Data Read PLB Error\n"); - if (mcsr & MCSR_DWB) - printk(KERN_ERR "Data Write PLB Error\n"); - if (mcsr & MCSR_TLBP) - printk(KERN_ERR "TLB Parity Error\n"); - if (mcsr & MCSR_ICP) { - flush_instruction_cache(); - printk(KERN_ERR "I-Cache Parity Error\n"); - } - if (mcsr & MCSR_DCSP) - printk(KERN_ERR "D-Cache Search Parity Error\n"); - if (mcsr & PPC47x_MCSR_GPR) - printk(KERN_ERR "GPR Parity Error\n"); - if (mcsr & PPC47x_MCSR_FPR) - printk(KERN_ERR "FPR Parity Error\n"); - if (mcsr & PPC47x_MCSR_IPR) - printk(KERN_ERR "Machine Check exception is imprecise\n"); - - /* Clear MCSR */ - mtspr(SPRN_MCSR, mcsr); - - return 0; -} -#elif defined(CONFIG_E500) +#if defined(CONFIG_E500) int machine_check_e500mc(struct pt_regs *regs) { unsigned long mcsr = mfspr(SPRN_MCSR); + unsigned long pvr = mfspr(SPRN_PVR); unsigned long reason = mcsr; int recoverable = 1; @@ -561,8 +479,15 @@ int machine_check_e500mc(struct pt_regs *regs) * may still get logged and cause a machine check. We should * only treat the non-write shadow case as non-recoverable. */ - if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS)) - recoverable = 0; + /* On e6500 core, L1 DCWS (Data cache write shadow mode) bit + * is not implemented but L1 data cache always runs in write + * shadow mode. Hence on data cache parity errors HW will + * automatically invalidate the L1 Data Cache. + */ + if (PVR_VER(pvr) != PVR_VER_E6500) { + if (!(mfspr(SPRN_L1CSR2) & L1CSR2_DCWS)) + recoverable = 0; + } } if (reason & MCSR_L2MMU_MHIT) { @@ -618,7 +543,7 @@ silent_out: int machine_check_e500(struct pt_regs *regs) { - unsigned long reason = get_mc_reason(regs); + unsigned long reason = mfspr(SPRN_MCSR); if (reason & MCSR_BUS_RBERR) { if (fsl_rio_mcheck_exception(regs)) @@ -665,7 +590,7 @@ int machine_check_generic(struct pt_regs *regs) #elif defined(CONFIG_E200) int machine_check_e200(struct pt_regs *regs) { - unsigned long reason = get_mc_reason(regs); + unsigned long reason = mfspr(SPRN_MCSR); printk("Machine check in kernel mode.\n"); printk("Caused by (from MCSR=%lx): ", reason); @@ -687,35 +612,10 @@ int machine_check_e200(struct pt_regs *regs) return 0; } -#elif defined(CONFIG_PPC_8xx) -int machine_check_8xx(struct pt_regs *regs) -{ - unsigned long reason = get_mc_reason(regs); - - pr_err("Machine check in kernel mode.\n"); - pr_err("Caused by (from SRR1=%lx): ", reason); - if (reason & 0x40000000) - pr_err("Fetch error at address %lx\n", regs->nip); - else - pr_err("Data access error at address %lx\n", regs->dar); - -#ifdef CONFIG_PCI - /* the qspan pci read routines can cause machine checks -- Cort - * - * yuck !!! that totally needs to go away ! There are better ways - * to deal with that than having a wart in the mcheck handler. - * -- BenH - */ - bad_page_fault(regs, regs->dar, SIGBUS); - return 1; -#else - return 0; -#endif -} -#else +#elif defined(CONFIG_PPC32) int machine_check_generic(struct pt_regs *regs) { - unsigned long reason = get_mc_reason(regs); + unsigned long reason = regs->msr; printk("Machine check in kernel mode.\n"); printk("Caused by (from SRR1=%lx): ", reason); @@ -752,10 +652,14 @@ int machine_check_generic(struct pt_regs *regs) void machine_check_exception(struct pt_regs *regs) { - enum ctx_state prev_state = exception_enter(); int recover = 0; + bool nested = in_nmi(); + if (!nested) + nmi_enter(); - __this_cpu_inc(irq_stat.mce_exceptions); + /* 64s accounts the mce in machine_check_early when in HVMODE */ + if (!IS_ENABLED(CONFIG_PPC_BOOK3S_64) || !cpu_has_feature(CPU_FTR_HVMODE)) + __this_cpu_inc(irq_stat.mce_exceptions); add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); @@ -783,10 +687,11 @@ void machine_check_exception(struct pt_regs *regs) /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) - panic("Unrecoverable Machine check"); + nmi_panic(regs, "Unrecoverable Machine check"); bail: - exception_exit(prev_state); + if (!nested) + nmi_exit(); } void SMIException(struct pt_regs *regs) @@ -1672,24 +1577,6 @@ void performance_monitor_exception(struct pt_regs *regs) perf_irq(regs); } -#ifdef CONFIG_8xx -void SoftwareEmulation(struct pt_regs *regs) -{ - CHECK_FULL_REGS(regs); - - if (!user_mode(regs)) { - debugger(regs); - die("Kernel Mode Unimplemented Instruction or SW FPU Emulation", - regs, SIGFPE); - } - - if (!emulate_math(regs)) - return; - - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); -} -#endif /* CONFIG_8xx */ - #ifdef CONFIG_PPC_ADV_DEBUG_REGS static void handle_debug(struct pt_regs *regs, unsigned long debug_status) { diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index 003b20964ea0..5d105b8eeece 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c @@ -205,3 +205,12 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs return orig_ret_vaddr; } + +bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx, + struct pt_regs *regs) +{ + if (ctx == RP_CHECK_CHAIN_CALL) + return regs->gpr[1] <= ret->stack; + else + return regs->gpr[1] < ret->stack; +} diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index 78a7449bf489..b8c434d1d459 100644 --- a/arch/powerpc/kernel/vdso32/Makefile +++ b/arch/powerpc/kernel/vdso32/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # List of files in the vdso, has to be asm only for now diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 6b2b69616e77..769c2624e0a6 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -232,15 +232,9 @@ __do_get_tspec: lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) /* Get a stable TB value */ -#ifdef CONFIG_8xx -2: mftbu r3 - mftbl r4 - mftbu r0 -#else -2: mfspr r3, SPRN_TBRU - mfspr r4, SPRN_TBRL - mfspr r0, SPRN_TBRU -#endif +2: MFTBU(r3) + MFTBL(r4) + MFTBU(r0) cmplw cr0,r3,r0 bne- 2b diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index e58ee10fa5c0..099a6db14e67 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is the infamous ld script for the 32 bits vdso * library diff --git a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S index 6ac107ac402a..3f5ef035b0a9 100644 --- a/arch/powerpc/kernel/vdso32/vdso32_wrapper.S +++ b/arch/powerpc/kernel/vdso32/vdso32_wrapper.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile index 31107bf5a61f..69cecb346269 100644 --- a/arch/powerpc/kernel/vdso64/Makefile +++ b/arch/powerpc/kernel/vdso64/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # List of files in the vdso, has to be asm only for now obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 64fb183a47c2..256fb9720298 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is the infamous ld script for the 64 bits vdso * library diff --git a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S index df60fca6a13d..1d56d81fe3b3 100644 --- a/arch/powerpc/kernel/vdso64/vdso64_wrapper.S +++ b/arch/powerpc/kernel/vdso64/vdso64_wrapper.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/powerpc/kernel/vecemu.c b/arch/powerpc/kernel/vecemu.c index 2d8f6d8ccafc..8812085883fd 100644 --- a/arch/powerpc/kernel/vecemu.c +++ b/arch/powerpc/kernel/vecemu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Routines to emulate some Altivec/VMX instructions, specifically * those that can trap when given denormalized operands in Java mode. diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 0c123f3406cd..f314fd475491 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index b1a250560198..0494e1566ee2 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_PPC64 #define PROVIDE32(x) PROVIDE(__unused__##x) #else @@ -8,7 +9,7 @@ #include #include -#ifdef CONFIG_STRICT_KERNEL_RWX +#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_PPC32) #define STRICT_ALIGN_SIZE (1 << 24) #else #define STRICT_ALIGN_SIZE PAGE_SIZE diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c index 34721a257a77..57190f384f63 100644 --- a/arch/powerpc/kernel/watchdog.c +++ b/arch/powerpc/kernel/watchdog.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Watchdog support on powerpc systems. * @@ -216,6 +217,9 @@ void soft_nmi_interrupt(struct pt_regs *regs) return; nmi_enter(); + + __this_cpu_inc(irq_stat.soft_nmi_irqs); + tb = get_tb(); if (tb - per_cpu(wd_timer_tb, cpu) >= wd_panic_timeout_tb) { per_cpu(wd_timer_tb, cpu) = tb; @@ -307,9 +311,6 @@ static int start_wd_on_cpu(unsigned int cpu) if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) return 0; - if (watchdog_suspended) - return 0; - if (!cpumask_test_cpu(cpu, &watchdog_cpumask)) return 0; @@ -355,36 +356,39 @@ static void watchdog_calc_timeouts(void) wd_timer_period_ms = watchdog_thresh * 1000 * 2 / 5; } -void watchdog_nmi_reconfigure(void) +void watchdog_nmi_stop(void) +{ + int cpu; + + for_each_cpu(cpu, &wd_cpus_enabled) + stop_wd_on_cpu(cpu); +} + +void watchdog_nmi_start(void) { int cpu; watchdog_calc_timeouts(); - - for_each_cpu(cpu, &wd_cpus_enabled) - stop_wd_on_cpu(cpu); - for_each_cpu_and(cpu, cpu_online_mask, &watchdog_cpumask) start_wd_on_cpu(cpu); } /* - * This runs after lockup_detector_init() which sets up watchdog_cpumask. + * Invoked from core watchdog init. */ -static int __init powerpc_watchdog_init(void) +int __init watchdog_nmi_probe(void) { int err; - watchdog_calc_timeouts(); - - err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/watchdog:online", - start_wd_on_cpu, stop_wd_on_cpu); - if (err < 0) + err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "powerpc/watchdog:online", + start_wd_on_cpu, stop_wd_on_cpu); + if (err < 0) { pr_warn("Watchdog could not be initialized"); - + return err; + } return 0; } -arch_initcall(powerpc_watchdog_init); static void handle_backtrace_ipi(struct pt_regs *regs) { diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index 0c52cb5d43f5..b12b8eb39c29 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # KVM configuration # diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 381a6ec0ff3b..85ba80de7133 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Kernel-based Virtual Machine module # diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index b42812e014c0..59247af5fd45 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "trace_hv.h" @@ -599,8 +600,8 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, * hugepage split and collapse. */ local_irq_save(flags); - ptep = find_linux_pte_or_hugepte(current->mm->pgd, - hva, NULL, NULL); + ptep = find_current_mm_pte(current->mm->pgd, + hva, NULL, NULL); if (ptep) { pte = kvmppc_read_update_linux_pte(ptep, 1); if (__pte_write(pte)) @@ -645,6 +646,16 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, hnow_v = hpte_new_to_old_v(hnow_v, hnow_r); hnow_r = hpte_new_to_old_r(hnow_r); } + + /* + * If the HPT is being resized, don't update the HPTE, + * instead let the guest retry after the resize operation is complete. + * The synchronization for hpte_setup_done test vs. set is provided + * by the HPTE lock. + */ + if (!kvm->arch.hpte_setup_done) + goto out_unlock; + if ((hnow_v & ~HPTE_V_HVLOCK) != hpte[0] || hnow_r != hpte[1] || rev->guest_rpte != hpte[2]) /* HPTE has been changed under us; let the guest retry */ @@ -1940,6 +1951,7 @@ int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *ghf) rwflag = (ghf->flags & KVM_GET_HTAB_WRITE) ? O_WRONLY : O_RDONLY; ret = anon_inode_getfd("kvm-htab", &kvm_htab_fops, ctx, rwflag | O_CLOEXEC); if (ret < 0) { + kfree(ctx); kvm_put_kvm(kvm); return ret; } diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index f6b3e67c5762..c5d7435455f1 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -17,6 +17,7 @@ #include #include #include +#include /* * Supported radix tree geometry. @@ -322,13 +323,13 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, gpa = vcpu->arch.fault_gpa & ~0xfffUL; gpa &= ~0xF000000000000000ul; gfn = gpa >> PAGE_SHIFT; - if (!(dsisr & DSISR_PGDIRFAULT)) + if (!(dsisr & DSISR_PRTABLE_FAULT)) gpa |= ea & 0xfff; memslot = gfn_to_memslot(kvm, gfn); /* No memslot means it's an emulated MMIO region */ if (!memslot || (memslot->flags & KVM_MEMSLOT_INVALID)) { - if (dsisr & (DSISR_PGDIRFAULT | DSISR_BADACCESS | + if (dsisr & (DSISR_PRTABLE_FAULT | DSISR_BADACCESS | DSISR_SET_RC)) { /* * Bad address in guest page table tree, or other @@ -359,8 +360,7 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, if (writing) pgflags |= _PAGE_DIRTY; local_irq_save(flags); - ptep = __find_linux_pte_or_hugepte(current->mm->pgd, hva, - NULL, NULL); + ptep = find_current_mm_pte(current->mm->pgd, hva, NULL, NULL); if (ptep) { pte = READ_ONCE(*ptep); if (pte_present(pte) && @@ -374,8 +374,12 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, spin_unlock(&kvm->mmu_lock); return RESUME_GUEST; } - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, - gpa, NULL, &shift); + /* + * We are walking the secondary page table here. We can do this + * without disabling irq. + */ + ptep = __find_linux_pte(kvm->arch.pgtable, + gpa, NULL, &shift); if (ptep && pte_present(*ptep)) { kvmppc_radix_update_pte(kvm, ptep, 0, pgflags, gpa, shift); @@ -427,8 +431,8 @@ int kvmppc_book3s_radix_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, pgflags |= _PAGE_WRITE; } else { local_irq_save(flags); - ptep = __find_linux_pte_or_hugepte(current->mm->pgd, - hva, NULL, NULL); + ptep = find_current_mm_pte(current->mm->pgd, + hva, NULL, NULL); if (ptep && pte_write(*ptep) && pte_dirty(*ptep)) pgflags |= _PAGE_WRITE; local_irq_restore(flags); @@ -499,8 +503,7 @@ int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned int shift; unsigned long old; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep)) { old = kvmppc_radix_update_pte(kvm, ptep, _PAGE_PRESENT, 0, gpa, shift); @@ -525,8 +528,7 @@ int kvm_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned int shift; int ref = 0; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep) && pte_young(*ptep)) { kvmppc_radix_update_pte(kvm, ptep, _PAGE_ACCESSED, 0, gpa, shift); @@ -545,8 +547,7 @@ int kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, unsigned int shift; int ref = 0; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep) && pte_young(*ptep)) ref = 1; return ref; @@ -562,8 +563,7 @@ static int kvm_radix_test_clear_dirty(struct kvm *kvm, unsigned int shift; int ret = 0; - ptep = __find_linux_pte_or_hugepte(kvm->arch.pgtable, gpa, - NULL, &shift); + ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift); if (ptep && pte_present(*ptep) && pte_dirty(*ptep)) { ret = 1; if (shift) diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 53766e2bc029..4dffa611376d 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -265,8 +265,11 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) { struct kvmppc_spapr_tce_table *stt = filp->private_data; struct kvmppc_spapr_tce_iommu_table *stit, *tmp; + struct kvm *kvm = stt->kvm; + mutex_lock(&kvm->lock); list_del_rcu(&stt->list); + mutex_unlock(&kvm->lock); list_for_each_entry_safe(stit, tmp, &stt->iommu_tables, next) { WARN_ON(!kref_read(&stit->kref)); @@ -298,7 +301,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, unsigned long npages, size; int ret = -ENOMEM; int i; - int fd = -1; if (!args->size) return -EINVAL; @@ -328,11 +330,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, goto fail; } - ret = fd = anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, - stt, O_RDWR | O_CLOEXEC); - if (ret < 0) - goto fail; - mutex_lock(&kvm->lock); /* Check this LIOBN hasn't been previously allocated */ @@ -344,17 +341,19 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, } } - if (!ret) { + if (!ret) + ret = anon_inode_getfd("kvm-spapr-tce", &kvm_spapr_tce_fops, + stt, O_RDWR | O_CLOEXEC); + + if (ret >= 0) { list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables); kvm_get_kvm(kvm); } mutex_unlock(&kvm->lock); - if (!ret) - return fd; - - put_unused_fd(fd); + if (ret >= 0) + return ret; fail: for (i = 0; i < npages; i++) @@ -479,28 +478,30 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, return ret; dir = iommu_tce_direction(tce); + + idx = srcu_read_lock(&vcpu->kvm->srcu); + if ((dir != DMA_NONE) && kvmppc_gpa_to_ua(vcpu->kvm, - tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL)) - return H_PARAMETER; + tce & ~(TCE_PCI_READ | TCE_PCI_WRITE), &ua, NULL)) { + ret = H_PARAMETER; + goto unlock_exit; + } entry = ioba >> stt->page_shift; list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { - if (dir == DMA_NONE) { + if (dir == DMA_NONE) ret = kvmppc_tce_iommu_unmap(vcpu->kvm, stit->tbl, entry); - } else { - idx = srcu_read_lock(&vcpu->kvm->srcu); + else ret = kvmppc_tce_iommu_map(vcpu->kvm, stit->tbl, entry, ua, dir); - srcu_read_unlock(&vcpu->kvm->srcu, idx); - } if (ret == H_SUCCESS) continue; if (ret == H_TOO_HARD) - return ret; + goto unlock_exit; WARN_ON_ONCE(1); kvmppc_clear_tce(stit->tbl, entry); @@ -508,7 +509,10 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, kvmppc_tce_put(stt, entry, tce); - return H_SUCCESS; +unlock_exit: + srcu_read_unlock(&vcpu->kvm->srcu, idx); + + return ret; } EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index 3adfd2f5301c..c32e9bfe75b1 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef CONFIG_BUG @@ -353,7 +354,16 @@ static long kvmppc_rm_ua_to_hpa(struct kvm_vcpu *vcpu, pte_t *ptep, pte; unsigned shift = 0; - ptep = __find_linux_pte_or_hugepte(vcpu->arch.pgdir, ua, NULL, &shift); + /* + * Called in real mode with MSR_EE = 0. We are safe here. + * It is ok to do the lookup with arch.pgdir here, because + * we are doing this on secondary cpus and current task there + * is not the hypervisor. Also this is safe against THP in the + * host, because an IPI to primary thread will wait for the secondary + * to exit which will agains result in the below page table walk + * to finish. + */ + ptep = __find_linux_pte(vcpu->arch.pgdir, ua, NULL, &shift); if (!ptep || !pte_present(*ptep)) return -ENXIO; pte = *ptep; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 359c79cdf0cc..8d43cf205d34 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -181,7 +181,7 @@ static void kvmppc_fast_vcpu_kick_hv(struct kvm_vcpu *vcpu) struct swait_queue_head *wqp; wqp = kvm_arch_vcpu_wq(vcpu); - if (swait_active(wqp)) { + if (swq_has_sleeper(wqp)) { swake_up(wqp); ++vcpu->stat.halt_wakeup; } @@ -485,7 +485,13 @@ static unsigned long do_h_register_vpa(struct kvm_vcpu *vcpu, switch (subfunc) { case H_VPA_REG_VPA: /* register VPA */ - if (len < sizeof(struct lppaca)) + /* + * The size of our lppaca is 1kB because of the way we align + * it for the guest to avoid crossing a 4kB boundary. We only + * use 640 bytes of the structure though, so we should accept + * clients that set a size of 640. + */ + if (len < 640) break; vpap = &tvcpu->arch.vpa; err = 0; @@ -2111,6 +2117,15 @@ static int kvmppc_grab_hwthread(int cpu) struct paca_struct *tpaca; long timeout = 10000; + /* + * ISA v3.0 idle routines do not set hwthread_state or test + * hwthread_req, so they can not grab idle threads. + */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + WARN(1, "KVM: can not control sibling threads\n"); + return -EBUSY; + } + tpaca = &paca[cpu]; /* Ensure the thread won't go into the kernel if it wakes */ @@ -2145,10 +2160,12 @@ static void kvmppc_release_hwthread(int cpu) struct paca_struct *tpaca; tpaca = &paca[cpu]; - tpaca->kvm_hstate.hwthread_req = 0; tpaca->kvm_hstate.kvm_vcpu = NULL; tpaca->kvm_hstate.kvm_vcore = NULL; tpaca->kvm_hstate.kvm_split_mode = NULL; + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + tpaca->kvm_hstate.hwthread_req = 0; + } static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) @@ -2688,11 +2705,14 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore *vc) * Hard-disable interrupts, and check resched flag and signals. * If we need to reschedule or deliver a signal, clean up * and return without going into the guest(s). + * If the hpte_setup_done flag has been cleared, don't go into the + * guest because that means a HPT resize operation is in progress. */ local_irq_disable(); hard_irq_disable(); if (lazy_irq_pending() || need_resched() || - recheck_signals(&core_info)) { + recheck_signals(&core_info) || + (!kvm_is_radix(vc->kvm) && !vc->kvm->arch.hpte_setup_done)) { local_irq_enable(); vc->vcore_state = VCORE_INACTIVE; /* Unlock all except the primary vcore */ @@ -3061,7 +3081,7 @@ out: static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) { - int n_ceded, i; + int n_ceded, i, r; struct kvmppc_vcore *vc; struct kvm_vcpu *v; @@ -3115,6 +3135,20 @@ static int kvmppc_run_vcpu(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) while (vcpu->arch.state == KVMPPC_VCPU_RUNNABLE && !signal_pending(current)) { + /* See if the HPT and VRMA are ready to go */ + if (!kvm_is_radix(vcpu->kvm) && + !vcpu->kvm->arch.hpte_setup_done) { + spin_unlock(&vc->lock); + r = kvmppc_hv_setup_htab_rma(vcpu); + spin_lock(&vc->lock); + if (r) { + kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; + kvm_run->fail_entry.hardware_entry_failure_reason = 0; + vcpu->arch.ret = r; + break; + } + } + if (vc->vcore_state == VCORE_PREEMPT && vc->runner == NULL) kvmppc_vcore_end_preempt(vc); @@ -3232,13 +3266,6 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) /* Order vcpus_running vs. hpte_setup_done, see kvmppc_alloc_reset_hpt */ smp_mb(); - /* On the first time here, set up HTAB and VRMA */ - if (!kvm_is_radix(vcpu->kvm) && !vcpu->kvm->arch.hpte_setup_done) { - r = kvmppc_hv_setup_htab_rma(vcpu); - if (r) - goto out; - } - flush_all_to_thread(current); /* Save userspace EBB and other register values */ @@ -3286,7 +3313,6 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) } mtspr(SPRN_VRSAVE, user_vrsave); - out: vcpu->arch.state = KVMPPC_VCPU_NOTREADY; atomic_dec(&vcpu->kvm->arch.vcpus_running); return r; @@ -3325,6 +3351,14 @@ static int kvm_vm_ioctl_get_smmu_info_hv(struct kvm *kvm, if (radix_enabled()) return -EINVAL; + /* + * POWER7, POWER8 and POWER9 all support 32 storage keys for data. + * POWER7 doesn't support keys for instruction accesses, + * POWER8 and POWER9 do. + */ + info->data_keys = 32; + info->instr_keys = cpu_has_feature(CPU_FTR_ARCH_207S) ? 32 : 0; + info->flags = KVM_PPC_PAGE_SIZES_REAL; if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) info->flags |= KVM_PPC_1T_SEGMENTS; @@ -4187,11 +4221,13 @@ static int kvmhv_configure_mmu(struct kvm *kvm, struct kvm_ppc_mmuv3_cfg *cfg) if ((cfg->process_table & PRTS_MASK) > 24) return -EINVAL; + mutex_lock(&kvm->lock); kvm->arch.process_table = cfg->process_table; kvmppc_setup_partition_table(kvm); lpcr = (cfg->flags & KVM_PPC_MMUV3_GTSE) ? LPCR_GTSE : 0; kvmppc_update_lpcr(kvm, lpcr, LPCR_GTSE); + mutex_unlock(&kvm->lock); return 0; } diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 584c74c8119f..4efe364f1188 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Translate address of a vmalloc'd thing to a linear map address */ static void *real_vmalloc_addr(void *x) @@ -31,9 +32,9 @@ static void *real_vmalloc_addr(void *x) /* * assume we don't have huge pages in vmalloc space... * So don't worry about THP collapse/split. Called - * Only in realmode, hence won't need irq_save/restore. + * Only in realmode with MSR_EE = 0, hence won't need irq_save/restore. */ - p = __find_linux_pte_or_hugepte(swapper_pg_dir, addr, NULL, NULL); + p = find_init_mm_pte(addr, NULL); if (!p || !pte_present(*p)) return NULL; addr = (pte_pfn(*p) << PAGE_SHIFT) | (addr & ~PAGE_MASK); @@ -230,14 +231,13 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, * If we had a page table table change after lookup, we would * retry via mmu_notifier_retry. */ - if (realmode) - ptep = __find_linux_pte_or_hugepte(pgdir, hva, NULL, - &hpage_shift); - else { + if (!realmode) local_irq_save(irq_flags); - ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL, - &hpage_shift); - } + /* + * If called in real mode we have MSR_EE = 0. Otherwise + * we disable irq above. + */ + ptep = __find_linux_pte(pgdir, hva, NULL, &hpage_shift); if (ptep) { pte_t pte; unsigned int host_pte_size; @@ -269,7 +269,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, if (!realmode) local_irq_restore(irq_flags); - ptel &= ~(HPTE_R_PP0 - psize); + ptel &= HPTE_R_KEY | HPTE_R_PP0 | (psize-1); ptel |= pa; if (pa) diff --git a/arch/powerpc/kvm/book3s_hv_rm_xive.c b/arch/powerpc/kvm/book3s_hv_rm_xive.c index abf5f01b6eb1..174d75e476fa 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xive.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xive.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -38,7 +39,6 @@ static inline void __iomem *get_tima_phys(void) #define __x_tima get_tima_phys() #define __x_eoi_page(xd) ((void __iomem *)((xd)->eoi_page)) #define __x_trig_page(xd) ((void __iomem *)((xd)->trig_page)) -#define __x_readb __raw_rm_readb #define __x_writeb __raw_rm_writeb #define __x_readw __raw_rm_readw #define __x_readq __raw_rm_readq diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 9c9c983b864f..42639fba89e8 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -149,9 +149,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) subf r4, r4, r3 mtspr SPRN_DEC, r4 +BEGIN_FTR_SECTION /* hwthread_req may have got set by cede or no vcpu, so clear it */ li r0, 0 stb r0, HSTATE_HWTHREAD_REQ(r13) +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) /* * For external interrupts we need to call the Linux @@ -314,6 +316,7 @@ kvm_novcpu_exit: * Relocation is off and most register values are lost. * r13 points to the PACA. * r3 contains the SRR1 wakeup value, SRR1 is trashed. + * This is not used by ISAv3.0B processors. */ .globl kvm_start_guest kvm_start_guest: @@ -432,6 +435,9 @@ kvm_secondary_got_guest: * While waiting we also need to check if we get given a vcpu to run. */ kvm_no_guest: +BEGIN_FTR_SECTION + twi 31,0,0 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) lbz r3, HSTATE_HWTHREAD_REQ(r13) cmpwi r3, 0 bne 53f @@ -765,6 +771,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ bl kvmppc_restore_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif @@ -976,17 +985,18 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300) #ifdef CONFIG_KVM_XICS /* We are entering the guest on that thread, push VCPU to XIVE */ ld r10, HSTATE_XIVE_TIMA_PHYS(r13) - cmpldi cr0, r10, r0 + cmpldi cr0, r10, 0 beq no_xive ld r11, VCPU_XIVE_SAVED_STATE(r4) li r9, TM_QW1_OS - stdcix r11,r9,r10 eieio + stdcix r11,r9,r10 lwz r11, VCPU_XIVE_CAM_WORD(r4) li r9, TM_QW1_OS + TM_WORD2 stwcix r11,r9,r10 li r9, 1 stw r9, VCPU_XIVE_PUSHED(r4) + eieio no_xive: #endif /* CONFIG_KVM_XICS */ @@ -1112,6 +1122,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) BEGIN_FTR_SECTION mtspr SPRN_PPR, r0 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) + +/* Move canary into DSISR to check for later */ +BEGIN_FTR_SECTION + li r0, 0x7fff + mtspr SPRN_HDSISR, r0 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + ld r0, VCPU_GPR(R0)(r4) ld r4, VCPU_GPR(R4)(r4) @@ -1280,7 +1297,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER bne 2f mfspr r3,SPRN_HDEC - cmpwi r3,0 + EXTEND_HDEC(r3) + cmpdi r3,0 mr r4,r9 bge fast_guest_return 2: @@ -1293,6 +1311,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR) bne 3f BEGIN_FTR_SECTION PPC_MSGSYNC + lwsync END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) lbz r0, HSTATE_HOST_IPI(r13) cmpwi r0, 0 @@ -1383,8 +1402,8 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */ cmpldi cr0, r10, 0 beq 1f /* First load to pull the context, we ignore the value */ - lwzx r11, r7, r10 eieio + lwzx r11, r7, r10 /* Second load to recover the context state (Words 0 and 1) */ ldx r11, r6, r10 b 3f @@ -1392,8 +1411,8 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */ cmpldi cr0, r10, 0 beq 1f /* First load to pull the context, we ignore the value */ - lwzcix r11, r7, r10 eieio + lwzcix r11, r7, r10 /* Second load to recover the context state (Words 0 and 1) */ ldcix r11, r6, r10 3: std r11, VCPU_XIVE_SAVED_STATE(r9) @@ -1403,6 +1422,7 @@ guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */ stw r10, VCPU_XIVE_PUSHED(r9) stb r10, (VCPU_XIVE_SAVED_STATE+3)(r9) stb r0, (VCPU_XIVE_SAVED_STATE+4)(r9) + eieio 1: #endif /* CONFIG_KVM_XICS */ /* Save more register state */ @@ -1623,6 +1643,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ bl kvmppc_save_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif @@ -1742,7 +1765,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) /* * Are we running hash or radix ? */ - beq cr2,3f + ld r5, VCPU_KVM(r9) + lbz r0, KVM_RADIX(r5) + cmpwi cr2, r0, 0 + beq cr2, 3f /* Radix: Handle the case where the guest used an illegal PID */ LOAD_REG_ADDR(r4, mmu_base_pid) @@ -1940,9 +1966,14 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX) kvmppc_hdsi: ld r3, VCPU_KVM(r9) lbz r0, KVM_RADIX(r3) - cmpwi r0, 0 mfspr r4, SPRN_HDAR mfspr r6, SPRN_HDSISR +BEGIN_FTR_SECTION + /* Look for DSISR canary. If we find it, retry instruction */ + cmpdi r6, 0x7fff + beq 6f +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + cmpwi r0, 0 bne .Lradix_hdsi /* on radix, just save DAR/DSISR/ASDR */ /* HPTE not found fault or protection fault? */ andis. r0, r6, (DSISR_NOHPTE | DSISR_PROTFAULT)@h @@ -2459,6 +2490,9 @@ _GLOBAL(kvmppc_h_cede) /* r3 = vcpu pointer, r11 = msr, r13 = paca */ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ ld r9, HSTATE_KVM_VCPU(r13) bl kvmppc_save_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) @@ -2512,8 +2546,10 @@ kvm_do_nap: clrrdi r0, r0, 1 mtspr SPRN_CTRLT, r0 +BEGIN_FTR_SECTION li r0,1 stb r0,HSTATE_HWTHREAD_REQ(r13) +END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_300) mfspr r5,SPRN_LPCR ori r5,r5,LPCR_PECE0 | LPCR_PECE1 BEGIN_FTR_SECTION @@ -2569,6 +2605,9 @@ kvm_end_cede: #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BEGIN_FTR_SECTION + /* + * NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS INCLUDING CR + */ bl kvmppc_restore_tm END_FTR_SECTION_IFSET(CPU_FTR_TM) #endif @@ -2752,6 +2791,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) PPC_MSGCLR(6) /* see if it's a host IPI */ li r3, 1 +BEGIN_FTR_SECTION + PPC_MSGSYNC + lwsync +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) lbz r0, HSTATE_HOST_IPI(r13) cmpwi r0, 0 bnelr diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 08b200a0bbce..bf457843e032 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -48,7 +48,6 @@ #define __x_tima xive_tima #define __x_eoi_page(xd) ((void __iomem *)((xd)->eoi_mmio)) #define __x_trig_page(xd) ((void __iomem *)((xd)->trig_mmio)) -#define __x_readb __raw_readb #define __x_writeb __raw_writeb #define __x_readw __raw_readw #define __x_readq __raw_readq @@ -623,7 +622,7 @@ int kvmppc_xive_get_xive(struct kvm *kvm, u32 irq, u32 *server, return -EINVAL; state = &sb->irq_state[idx]; arch_spin_lock(&sb->lock); - *server = state->guest_server; + *server = state->act_server; *priority = state->guest_priority; arch_spin_unlock(&sb->lock); @@ -1332,7 +1331,7 @@ static int xive_get_source(struct kvmppc_xive *xive, long irq, u64 addr) xive->saved_src_count++; /* Convert saved state into something compatible with xics */ - val = state->guest_server; + val = state->act_server; prio = state->saved_scan_prio; if (prio == MASKED) { @@ -1508,7 +1507,6 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr) /* First convert prio and mark interrupt as untargetted */ act_prio = xive_prio_from_guest(guest_prio); state->act_priority = MASKED; - state->guest_server = server; /* * We need to drop the lock due to the mutex below. Hopefully diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h index 5938f7644dc1..6ba63f8e8a61 100644 --- a/arch/powerpc/kvm/book3s_xive.h +++ b/arch/powerpc/kvm/book3s_xive.h @@ -35,7 +35,6 @@ struct kvmppc_xive_irq_state { struct xive_irq_data *pt_data; /* XIVE Pass-through associated data */ /* Targetting as set by guest */ - u32 guest_server; /* Current guest selected target */ u8 guest_priority; /* Guest set priority */ u8 saved_priority; /* Saved priority when masking */ diff --git a/arch/powerpc/kvm/book3s_xive_template.c b/arch/powerpc/kvm/book3s_xive_template.c index d1ed2c41b5d2..c7a5deadd1cc 100644 --- a/arch/powerpc/kvm/book3s_xive_template.c +++ b/arch/powerpc/kvm/book3s_xive_template.c @@ -28,7 +28,8 @@ static void GLUE(X_PFX,ack_pending)(struct kvmppc_xive_vcpu *xc) * bit. */ if (cpu_has_feature(CPU_FTR_POWER9_DD1)) { - u8 pipr = __x_readb(__x_tima + TM_QW1_OS + TM_PIPR); + __be64 qw1 = __x_readq(__x_tima + TM_QW1_OS); + u8 pipr = be64_to_cpu(qw1) & 0xff; if (pipr >= xc->hw_cppr) return; } @@ -336,7 +337,6 @@ X_STATIC unsigned long GLUE(X_PFX,h_ipoll)(struct kvm_vcpu *vcpu, unsigned long struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; u8 pending = xc->pending; u32 hirq; - u8 pipr; pr_devel("H_IPOLL(server=%ld)\n", server); @@ -353,7 +353,8 @@ X_STATIC unsigned long GLUE(X_PFX,h_ipoll)(struct kvm_vcpu *vcpu, unsigned long pending = 0xff; } else { /* Grab pending interrupt if any */ - pipr = __x_readb(__x_tima + TM_QW1_OS + TM_PIPR); + __be64 qw1 = __x_readq(__x_tima + TM_QW1_OS); + u8 pipr = be64_to_cpu(qw1) & 0xff; if (pipr < 8) pending |= 1 << pipr; } diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 32fdab57d604..f9f6468f4171 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -455,16 +455,20 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_e500(struct kvm *kvm, if (err) goto free_vcpu; - if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) + if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) { + err = -ENOMEM; goto uninit_vcpu; + } err = kvmppc_e500_tlb_init(vcpu_e500); if (err) goto uninit_id; vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); - if (!vcpu->arch.shared) + if (!vcpu->arch.shared) { + err = -ENOMEM; goto uninit_tlb; + } return vcpu; diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 77fd043b3ecc..c6c734424c70 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "e500.h" #include "timing.h" @@ -476,7 +477,7 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, * can't run hence pfn won't change. */ local_irq_save(flags); - ptep = find_linux_pte_or_hugepte(pgdir, hva, NULL, NULL); + ptep = find_linux_pte(pgdir, hva, NULL, NULL); if (ptep) { pte_t pte = READ_ONCE(*ptep); diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index f48a0c22e8f9..d0b6b5788afc 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -331,8 +331,10 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_e500mc(struct kvm *kvm, goto uninit_vcpu; vcpu->arch.shared = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); - if (!vcpu->arch.shared) + if (!vcpu->arch.shared) { + err = -ENOMEM; goto uninit_tlb; + } return vcpu; diff --git a/arch/powerpc/kvm/irq.h b/arch/powerpc/kvm/irq.h index 3f1be85a83bc..e6463f866abc 100644 --- a/arch/powerpc/kvm/irq.h +++ b/arch/powerpc/kvm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __IRQ_H #define __IRQ_H diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 1a75c0b5f4ca..ee279c7f4802 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -58,6 +58,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v) return !!(v->arch.pending_exceptions) || kvm_request_pending(v); } +bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) +{ + return false; +} + int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) { return 1; @@ -639,8 +644,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) break; #endif case KVM_CAP_PPC_HTM: - r = cpu_has_feature(CPU_FTR_TM_COMP) && - is_kvmppc_hv_enabled(kvm); + r = cpu_has_feature(CPU_FTR_TM_COMP) && hv_enabled; break; default: r = 0; diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h index 2e0e67ef3544..491b0f715d6b 100644 --- a/arch/powerpc/kvm/trace.h +++ b/arch/powerpc/kvm/trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KVM_H diff --git a/arch/powerpc/kvm/trace_book3s.h b/arch/powerpc/kvm/trace_book3s.h index f647ce0f428b..f3b23759e017 100644 --- a/arch/powerpc/kvm/trace_book3s.h +++ b/arch/powerpc/kvm/trace_book3s.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_KVM_BOOK3S_H) #define _TRACE_KVM_BOOK3S_H diff --git a/arch/powerpc/kvm/trace_booke.h b/arch/powerpc/kvm/trace_booke.h index 7ec534d1db9f..ac640e81fdc5 100644 --- a/arch/powerpc/kvm/trace_booke.h +++ b/arch/powerpc/kvm/trace_booke.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_KVM_BOOKE_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KVM_BOOKE_H diff --git a/arch/powerpc/kvm/trace_hv.h b/arch/powerpc/kvm/trace_hv.h index ebc6dd449556..bcfe8a987f6a 100644 --- a/arch/powerpc/kvm/trace_hv.h +++ b/arch/powerpc/kvm/trace_hv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_KVM_HV_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KVM_HV_H diff --git a/arch/powerpc/kvm/trace_pr.h b/arch/powerpc/kvm/trace_pr.h index d44f324184fb..85785a370c0e 100644 --- a/arch/powerpc/kvm/trace_pr.h +++ b/arch/powerpc/kvm/trace_pr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_KVM_PR_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KVM_PR_H diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 3c3146ba62da..c66c3626a216 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ppc-specific library files.. # @@ -31,7 +32,8 @@ obj64-$(CONFIG_KPROBES_SANITY_TEST) += test_emulate_step.o obj-y += checksum_$(BITS).o checksum_wrappers.o -obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o +obj-y += sstep.o ldstfp.o quad.o +obj64-y += quad.o obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o diff --git a/arch/powerpc/lib/alloc.c b/arch/powerpc/lib/alloc.c index a58abe4afbd1..06796dec01ea 100644 --- a/arch/powerpc/lib/alloc.c +++ b/arch/powerpc/lib/alloc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index 8aedbb5f4b86..da425bb6b369 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S @@ -67,6 +67,20 @@ CACHELINE_BYTES = L1_CACHE_BYTES LG_CACHELINE_BYTES = L1_CACHE_SHIFT CACHELINE_MASK = (L1_CACHE_BYTES-1) +_GLOBAL(memset16) + rlwinm. r0 ,r5, 31, 1, 31 + addi r6, r3, -4 + beq- 2f + rlwimi r4 ,r4 ,16 ,0 ,15 + mtctr r0 +1: stwu r4, 4(r6) + bdnz 1b +2: andi. r0, r5, 1 + beqlr + sth r4, 4(r6) + blr +EXPORT_SYMBOL(memset16) + /* * Use dcbz on the complete cache lines in the destination * to set them to zero. This requires that the destination @@ -77,22 +91,24 @@ CACHELINE_MASK = (L1_CACHE_BYTES-1) * replaced by a nop once cache is active. This is done in machine_init() */ _GLOBAL(memset) + cmplwi 0,r5,4 + blt 7f + rlwimi r4,r4,8,16,23 rlwimi r4,r4,16,0,15 - addi r6,r3,-4 - cmplwi 0,r5,4 - blt 7f - stwu r4,4(r6) + stw r4,0(r3) beqlr - andi. r0,r6,3 + andi. r0,r3,3 add r5,r0,r5 - subf r6,r0,r6 + subf r6,r0,r3 cmplwi 0,r4,0 - bne 2f /* Use normal procedure if r4 is not zero */ -EXPORT_SYMBOL(memset) + /* + * Skip optimised bloc until cache is enabled. Will be replaced + * by 'bne' during boot to use normal procedure if r4 is not zero + */ _GLOBAL(memset_nocache_branch) - b 2f /* Skip optimised bloc until cache is enabled */ + b 2f clrlwi r7,r6,32-LG_CACHELINE_BYTES add r8,r7,r5 @@ -119,7 +135,6 @@ _GLOBAL(memset_nocache_branch) 1: stwu r4,4(r6) bdnz 1b 6: andi. r5,r5,3 -7: cmpwi 0,r5,0 beqlr mtctr r5 addi r6,r6,3 @@ -127,6 +142,15 @@ _GLOBAL(memset_nocache_branch) bdnz 8b blr +7: cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r6,r3,-1 +9: stbu r4,1(r6) + bdnz 9b + blr +EXPORT_SYMBOL(memset) + /* * This version uses dcbz on the complete cache lines in the * destination area to reduce memory traffic. This requires that diff --git a/arch/powerpc/lib/copypage_power7.S b/arch/powerpc/lib/copypage_power7.S index a84d333ecb09..ca5fc8fa7efc 100644 --- a/arch/powerpc/lib/copypage_power7.S +++ b/arch/powerpc/lib/copypage_power7.S @@ -45,13 +45,13 @@ _GLOBAL(copypage_power7) .machine push .machine "power4" /* setup read stream 0 */ - dcbt r0,r4,0b01000 /* addr from */ - dcbt r0,r7,0b01010 /* length and depth from */ + dcbt 0,r4,0b01000 /* addr from */ + dcbt 0,r7,0b01010 /* length and depth from */ /* setup write stream 1 */ - dcbtst r0,r9,0b01000 /* addr to */ - dcbtst r0,r10,0b01010 /* length and depth to */ + dcbtst 0,r9,0b01000 /* addr to */ + dcbtst 0,r10,0b01010 /* length and depth to */ eieio - dcbt r0,r8,0b01010 /* all streams GO */ + dcbt 0,r8,0b01010 /* all streams GO */ .machine pop #ifdef CONFIG_ALTIVEC @@ -83,7 +83,7 @@ _GLOBAL(copypage_power7) li r12,112 .align 5 -1: lvx v7,r0,r4 +1: lvx v7,0,r4 lvx v6,r4,r6 lvx v5,r4,r7 lvx v4,r4,r8 @@ -92,7 +92,7 @@ _GLOBAL(copypage_power7) lvx v1,r4,r11 lvx v0,r4,r12 addi r4,r4,128 - stvx v7,r0,r3 + stvx v7,0,r3 stvx v6,r3,r6 stvx v5,r3,r7 stvx v4,r3,r8 diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index 706b7cc19846..d416a4a66578 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -315,13 +315,13 @@ err1; stb r0,0(r3) .machine push .machine "power4" /* setup read stream 0 */ - dcbt r0,r6,0b01000 /* addr from */ - dcbt r0,r7,0b01010 /* length and depth from */ + dcbt 0,r6,0b01000 /* addr from */ + dcbt 0,r7,0b01010 /* length and depth from */ /* setup write stream 1 */ - dcbtst r0,r9,0b01000 /* addr to */ - dcbtst r0,r10,0b01010 /* length and depth to */ + dcbtst 0,r9,0b01000 /* addr to */ + dcbtst 0,r10,0b01010 /* length and depth to */ eieio - dcbt r0,r8,0b01010 /* all streams GO */ + dcbt 0,r8,0b01010 /* all streams GO */ .machine pop beq cr1,.Lunwind_stack_nonvmx_copy @@ -376,26 +376,26 @@ err3; std r0,0(r3) li r11,48 bf cr7*4+3,5f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 addi r4,r4,16 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 addi r3,r3,16 5: bf cr7*4+2,6f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 err3; lvx v0,r4,r9 addi r4,r4,32 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 err3; stvx v0,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 err3; lvx v2,r4,r9 err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 addi r4,r4,64 -err3; stvx v3,r0,r3 +err3; stvx v3,0,r3 err3; stvx v2,r3,r9 err3; stvx v1,r3,r10 err3; stvx v0,r3,r11 @@ -421,7 +421,7 @@ err3; stvx v0,r3,r11 */ .align 5 8: -err4; lvx v7,r0,r4 +err4; lvx v7,0,r4 err4; lvx v6,r4,r9 err4; lvx v5,r4,r10 err4; lvx v4,r4,r11 @@ -430,7 +430,7 @@ err4; lvx v2,r4,r14 err4; lvx v1,r4,r15 err4; lvx v0,r4,r16 addi r4,r4,128 -err4; stvx v7,r0,r3 +err4; stvx v7,0,r3 err4; stvx v6,r3,r9 err4; stvx v5,r3,r10 err4; stvx v4,r3,r11 @@ -451,29 +451,29 @@ err4; stvx v0,r3,r16 mtocrf 0x01,r6 bf cr7*4+1,9f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 err3; lvx v2,r4,r9 err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 addi r4,r4,64 -err3; stvx v3,r0,r3 +err3; stvx v3,0,r3 err3; stvx v2,r3,r9 err3; stvx v1,r3,r10 err3; stvx v0,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 err3; lvx v0,r4,r9 addi r4,r4,32 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 err3; stvx v0,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 addi r4,r4,16 -err3; stvx v1,r0,r3 +err3; stvx v1,0,r3 addi r3,r3,16 /* Up to 15B to go */ @@ -553,25 +553,25 @@ err3; lvx v0,0,r4 addi r4,r4,16 bf cr7*4+3,5f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 addi r3,r3,16 vor v0,v1,v1 5: bf cr7*4+2,6f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) err3; lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 VPERM(v8,v0,v3,v16) err3; lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -580,7 +580,7 @@ err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 err3; stvx v10,r3,r10 err3; stvx v11,r3,r11 @@ -606,7 +606,7 @@ err3; stvx v11,r3,r11 */ .align 5 8: -err4; lvx v7,r0,r4 +err4; lvx v7,0,r4 VPERM(v8,v0,v7,v16) err4; lvx v6,r4,r9 VPERM(v9,v7,v6,v16) @@ -623,7 +623,7 @@ err4; lvx v1,r4,r15 err4; lvx v0,r4,r16 VPERM(v15,v1,v0,v16) addi r4,r4,128 -err4; stvx v8,r0,r3 +err4; stvx v8,0,r3 err4; stvx v9,r3,r9 err4; stvx v10,r3,r10 err4; stvx v11,r3,r11 @@ -644,7 +644,7 @@ err4; stvx v15,r3,r16 mtocrf 0x01,r6 bf cr7*4+1,9f -err3; lvx v3,r0,r4 +err3; lvx v3,0,r4 VPERM(v8,v0,v3,v16) err3; lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -653,27 +653,27 @@ err3; lvx v1,r4,r10 err3; lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 err3; stvx v10,r3,r10 err3; stvx v11,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) err3; lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 err3; stvx v9,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f -err3; lvx v1,r0,r4 +err3; lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 -err3; stvx v8,r0,r3 +err3; stvx v8,0,r3 addi r3,r3,16 /* Up to 15B to go */ diff --git a/arch/powerpc/lib/ldstfp.S b/arch/powerpc/lib/ldstfp.S index a58777c1b2cb..ae15eba49c1f 100644 --- a/arch/powerpc/lib/ldstfp.S +++ b/arch/powerpc/lib/ldstfp.S @@ -21,27 +21,19 @@ #define STKFRM (PPC_MIN_STKFRM + 16) - .macro inst32 op -reg = 0 - .rept 32 -20: \op reg,0,r4 - b 3f - EX_TABLE(20b,99f) -reg = reg + 1 - .endr - .endm - -/* Get the contents of frN into fr0; N is in r3. */ +/* Get the contents of frN into *p; N is in r3 and p is in r4. */ _GLOBAL(get_fpr) mflr r0 + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* fr0 is already in fr0 */ - nop -reg = 1 - .rept 31 - fmr fr0,reg - blr +reg = 0 + .rept 32 + stfd reg, 0(r4) + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -49,18 +41,23 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr +2: MTMSRD(r6) + isync + blr -/* Put the contents of fr0 into frN; N is in r3. */ +/* Put the contents of *p into frN; N is in r3 and p is in r4. */ _GLOBAL(put_fpr) mflr r0 + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* fr0 is already in fr0 */ - nop -reg = 1 - .rept 31 - fmr reg,fr0 - blr +reg = 0 + .rept 32 + lfd reg, 0(r4) + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -68,127 +65,24 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr - -/* Load FP reg N from float at *p. N is in r3, p in r4. */ -_GLOBAL(do_lfs) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 - MTMSRD(r7) +2: MTMSRD(r6) isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) -1: li r9,-EFAULT -2: lfs fr0,0(r4) - li r9,0 -3: bl put_fpr - beq cr7,4f - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) - -/* Load FP reg N from double at *p. N is in r3, p in r4. */ -_GLOBAL(do_lfd) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 - MTMSRD(r7) - isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) -1: li r9,-EFAULT -2: lfd fr0,0(r4) - li r9,0 -3: beq cr7,4f - bl put_fpr - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) - -/* Store FP reg N to float at *p. N is in r3, p in r4. */ -_GLOBAL(do_stfs) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 - MTMSRD(r7) - isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) - bl get_fpr -1: li r9,-EFAULT -2: stfs fr0,0(r4) - li r9,0 -3: beq cr7,4f - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) - -/* Store FP reg N to double at *p. N is in r3, p in r4. */ -_GLOBAL(do_stfd) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - ori r7,r6,MSR_FP - cmpwi cr7,r3,0 - MTMSRD(r7) - isync - beq cr7,1f - stfd fr0,STKFRM-16(r1) - bl get_fpr -1: li r9,-EFAULT -2: stfd fr0,0(r4) - li r9,0 -3: beq cr7,4f - lfd fr0,STKFRM-16(r1) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) #ifdef CONFIG_ALTIVEC -/* Get the contents of vrN into v0; N is in r3. */ +/* Get the contents of vrN into *p; N is in r3 and p is in r4. */ _GLOBAL(get_vr) mflr r0 + mfmsr r6 + oris r7, r6, MSR_VEC@h + MTMSRD(r7) + isync rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* v0 is already in v0 */ - nop -reg = 1 - .rept 31 - vor v0,reg,reg /* assembler doesn't know vmr? */ - blr +reg = 0 + .rept 32 + stvx reg, 0, r4 + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -196,18 +90,23 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr +2: MTMSRD(r6) + isync + blr -/* Put the contents of v0 into vrN; N is in r3. */ +/* Put the contents of *p into vrN; N is in r3 and p is in r4. */ _GLOBAL(put_vr) mflr r0 + mfmsr r6 + oris r7, r6, MSR_VEC@h + MTMSRD(r7) + isync rlwinm r3,r3,3,0xf8 bcl 20,31,1f - blr /* v0 is already in v0 */ - nop -reg = 1 - .rept 31 - vor reg,v0,v0 - blr +reg = 0 + .rept 32 + lvx reg, 0, r4 + b 2f reg = reg + 1 .endr 1: mflr r5 @@ -215,62 +114,9 @@ reg = reg + 1 mtctr r5 mtlr r0 bctr - -/* Load vector reg N from *p. N is in r3, p in r4. */ -_GLOBAL(do_lvx) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - oris r7,r6,MSR_VEC@h - cmpwi cr7,r3,0 - li r8,STKFRM-16 - MTMSRD(r7) +2: MTMSRD(r6) isync - beq cr7,1f - stvx v0,r1,r8 -1: li r9,-EFAULT -2: lvx v0,0,r4 - li r9,0 -3: beq cr7,4f - bl put_vr - lvx v0,r1,r8 -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) - -/* Store vector reg N to *p. N is in r3, p in r4. */ -_GLOBAL(do_stvx) - PPC_STLU r1,-STKFRM(r1) - mflr r0 - PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) - mfmsr r6 - oris r7,r6,MSR_VEC@h - cmpwi cr7,r3,0 - li r8,STKFRM-16 - MTMSRD(r7) - isync - beq cr7,1f - stvx v0,r1,r8 - bl get_vr -1: li r9,-EFAULT -2: stvx v0,0,r4 - li r9,0 -3: beq cr7,4f - lvx v0,r1,r8 -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) - mtlr r0 - MTMSRD(r6) - isync - mr r3,r9 - addi r1,r1,STKFRM - blr - EX_TABLE(2b,3b) #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX @@ -313,7 +159,7 @@ reg = reg + 1 bctr /* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */ -_GLOBAL(do_lxvd2x) +_GLOBAL(load_vsrn) PPC_STLU r1,-STKFRM(r1) mflr r0 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) @@ -325,49 +171,74 @@ _GLOBAL(do_lxvd2x) isync beq cr7,1f STXVD2X(0,R1,R8) -1: li r9,-EFAULT -2: LXVD2X(0,R0,R4) - li r9,0 -3: beq cr7,4f +1: LXVD2X(0,R0,R4) +#ifdef __LITTLE_ENDIAN__ + XXSWAPD(0,0) +#endif + beq cr7,4f bl put_vsr LXVD2X(0,R1,R8) 4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) mtlr r0 MTMSRD(r6) isync - mr r3,r9 addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) /* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */ -_GLOBAL(do_stxvd2x) +_GLOBAL(store_vsrn) PPC_STLU r1,-STKFRM(r1) mflr r0 PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1) mfmsr r6 oris r7,r6,MSR_VSX@h - cmpwi cr7,r3,0 li r8,STKFRM-16 MTMSRD(r7) isync - beq cr7,1f STXVD2X(0,R1,R8) bl get_vsr -1: li r9,-EFAULT -2: STXVD2X(0,R0,R4) - li r9,0 -3: beq cr7,4f +#ifdef __LITTLE_ENDIAN__ + XXSWAPD(0,0) +#endif + STXVD2X(0,R0,R4) LXVD2X(0,R1,R8) -4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) + PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1) mtlr r0 MTMSRD(r6) isync mr r3,r9 addi r1,r1,STKFRM blr - EX_TABLE(2b,3b) - #endif /* CONFIG_VSX */ +/* Convert single-precision to double, without disturbing FPRs. */ +/* conv_sp_to_dp(float *sp, double *dp) */ +_GLOBAL(conv_sp_to_dp) + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync + stfd fr0, -16(r1) + lfs fr0, 0(r3) + stfd fr0, 0(r4) + lfd fr0, -16(r1) + MTMSRD(r6) + isync + blr + +/* Convert single-precision to double, without disturbing FPRs. */ +/* conv_sp_to_dp(double *dp, float *sp) */ +_GLOBAL(conv_dp_to_sp) + mfmsr r6 + ori r7, r6, MSR_FP + MTMSRD(r7) + isync + stfd fr0, -16(r1) + lfd fr0, 0(r3) + stfs fr0, 0(r4) + lfd fr0, -16(r1) + MTMSRD(r6) + isync + blr + #endif /* CONFIG_PPC_FPU */ diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S index 85fa9869aec5..ec531de99996 100644 --- a/arch/powerpc/lib/mem_64.S +++ b/arch/powerpc/lib/mem_64.S @@ -13,6 +13,23 @@ #include #include +_GLOBAL(__memset16) + rlwimi r4,r4,16,0,15 + /* fall through */ + +_GLOBAL(__memset32) + rldimi r4,r4,32,0 + /* fall through */ + +_GLOBAL(__memset64) + neg r0,r3 + andi. r0,r0,7 + cmplw cr1,r5,r0 + b .Lms +EXPORT_SYMBOL(__memset16) +EXPORT_SYMBOL(__memset32) +EXPORT_SYMBOL(__memset64) + _GLOBAL(memset) neg r0,r3 rlwimi r4,r4,8,16,23 @@ -20,7 +37,7 @@ _GLOBAL(memset) rlwimi r4,r4,16,0,15 cmplw cr1,r5,r0 /* do we get that far? */ rldimi r4,r4,32,0 - PPC_MTOCRF(1,r0) +.Lms: PPC_MTOCRF(1,r0) mr r6,r3 blt cr1,8f beq+ 3f /* if already 8-byte aligned */ diff --git a/arch/powerpc/lib/memcpy_power7.S b/arch/powerpc/lib/memcpy_power7.S index 786234fd4e91..193909abd18b 100644 --- a/arch/powerpc/lib/memcpy_power7.S +++ b/arch/powerpc/lib/memcpy_power7.S @@ -261,12 +261,12 @@ _GLOBAL(memcpy_power7) .machine push .machine "power4" - dcbt r0,r6,0b01000 - dcbt r0,r7,0b01010 - dcbtst r0,r9,0b01000 - dcbtst r0,r10,0b01010 + dcbt 0,r6,0b01000 + dcbt 0,r7,0b01010 + dcbtst 0,r9,0b01000 + dcbtst 0,r10,0b01010 eieio - dcbt r0,r8,0b01010 /* GO */ + dcbt 0,r8,0b01010 /* GO */ .machine pop beq cr1,.Lunwind_stack_nonvmx_copy @@ -321,26 +321,26 @@ _GLOBAL(memcpy_power7) li r11,48 bf cr7*4+3,5f - lvx v1,r0,r4 + lvx v1,0,r4 addi r4,r4,16 - stvx v1,r0,r3 + stvx v1,0,r3 addi r3,r3,16 5: bf cr7*4+2,6f - lvx v1,r0,r4 + lvx v1,0,r4 lvx v0,r4,r9 addi r4,r4,32 - stvx v1,r0,r3 + stvx v1,0,r3 stvx v0,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f - lvx v3,r0,r4 + lvx v3,0,r4 lvx v2,r4,r9 lvx v1,r4,r10 lvx v0,r4,r11 addi r4,r4,64 - stvx v3,r0,r3 + stvx v3,0,r3 stvx v2,r3,r9 stvx v1,r3,r10 stvx v0,r3,r11 @@ -366,7 +366,7 @@ _GLOBAL(memcpy_power7) */ .align 5 8: - lvx v7,r0,r4 + lvx v7,0,r4 lvx v6,r4,r9 lvx v5,r4,r10 lvx v4,r4,r11 @@ -375,7 +375,7 @@ _GLOBAL(memcpy_power7) lvx v1,r4,r15 lvx v0,r4,r16 addi r4,r4,128 - stvx v7,r0,r3 + stvx v7,0,r3 stvx v6,r3,r9 stvx v5,r3,r10 stvx v4,r3,r11 @@ -396,29 +396,29 @@ _GLOBAL(memcpy_power7) mtocrf 0x01,r6 bf cr7*4+1,9f - lvx v3,r0,r4 + lvx v3,0,r4 lvx v2,r4,r9 lvx v1,r4,r10 lvx v0,r4,r11 addi r4,r4,64 - stvx v3,r0,r3 + stvx v3,0,r3 stvx v2,r3,r9 stvx v1,r3,r10 stvx v0,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f - lvx v1,r0,r4 + lvx v1,0,r4 lvx v0,r4,r9 addi r4,r4,32 - stvx v1,r0,r3 + stvx v1,0,r3 stvx v0,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f - lvx v1,r0,r4 + lvx v1,0,r4 addi r4,r4,16 - stvx v1,r0,r3 + stvx v1,0,r3 addi r3,r3,16 /* Up to 15B to go */ @@ -499,25 +499,25 @@ _GLOBAL(memcpy_power7) addi r4,r4,16 bf cr7*4+3,5f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 - stvx v8,r0,r3 + stvx v8,0,r3 addi r3,r3,16 vor v0,v1,v1 5: bf cr7*4+2,6f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 addi r3,r3,32 6: bf cr7*4+1,7f - lvx v3,r0,r4 + lvx v3,0,r4 VPERM(v8,v0,v3,v16) lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -526,7 +526,7 @@ _GLOBAL(memcpy_power7) lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 stvx v10,r3,r10 stvx v11,r3,r11 @@ -552,7 +552,7 @@ _GLOBAL(memcpy_power7) */ .align 5 8: - lvx v7,r0,r4 + lvx v7,0,r4 VPERM(v8,v0,v7,v16) lvx v6,r4,r9 VPERM(v9,v7,v6,v16) @@ -569,7 +569,7 @@ _GLOBAL(memcpy_power7) lvx v0,r4,r16 VPERM(v15,v1,v0,v16) addi r4,r4,128 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 stvx v10,r3,r10 stvx v11,r3,r11 @@ -590,7 +590,7 @@ _GLOBAL(memcpy_power7) mtocrf 0x01,r6 bf cr7*4+1,9f - lvx v3,r0,r4 + lvx v3,0,r4 VPERM(v8,v0,v3,v16) lvx v2,r4,r9 VPERM(v9,v3,v2,v16) @@ -599,27 +599,27 @@ _GLOBAL(memcpy_power7) lvx v0,r4,r11 VPERM(v11,v1,v0,v16) addi r4,r4,64 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 stvx v10,r3,r10 stvx v11,r3,r11 addi r3,r3,64 9: bf cr7*4+2,10f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) lvx v0,r4,r9 VPERM(v9,v1,v0,v16) addi r4,r4,32 - stvx v8,r0,r3 + stvx v8,0,r3 stvx v9,r3,r9 addi r3,r3,32 10: bf cr7*4+3,11f - lvx v1,r0,r4 + lvx v1,0,r4 VPERM(v8,v0,v1,v16) addi r4,r4,16 - stvx v8,r0,r3 + stvx v8,0,r3 addi r3,r3,16 /* Up to 15B to go */ diff --git a/arch/powerpc/lib/quad.S b/arch/powerpc/lib/quad.S new file mode 100644 index 000000000000..c4d12fae8724 --- /dev/null +++ b/arch/powerpc/lib/quad.S @@ -0,0 +1,62 @@ +/* + * Quadword loads and stores + * for use in instruction emulation. + * + * Copyright 2017 Paul Mackerras, IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +/* do_lq(unsigned long ea, unsigned long *regs) */ +_GLOBAL(do_lq) +1: lq r6, 0(r3) + std r6, 0(r4) + std r7, 8(r4) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) + +/* do_stq(unsigned long ea, unsigned long val0, unsigned long val1) */ +_GLOBAL(do_stq) +1: stq r4, 0(r3) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) + +/* do_lqarx(unsigned long ea, unsigned long *regs) */ +_GLOBAL(do_lqarx) +1: PPC_LQARX(6, 0, 3, 0) + std r6, 0(r4) + std r7, 8(r4) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) + +/* do_stqcx(unsigned long ea, unsigned long val0, unsigned long val1, + unsigned int *crp) */ + +_GLOBAL(do_stqcx) +1: PPC_STQCX(4, 0, 3) + mfcr r5 + stw r5, 0(r6) + li r3, 0 + blr +2: li r3, -EFAULT + blr + EX_TABLE(1b, 2b) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index ee33327686ae..f208f560aecd 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -36,14 +36,33 @@ extern char system_call_common[]; /* * Functions in ldstfp.S */ -extern int do_lfs(int rn, unsigned long ea); -extern int do_lfd(int rn, unsigned long ea); -extern int do_stfs(int rn, unsigned long ea); -extern int do_stfd(int rn, unsigned long ea); -extern int do_lvx(int rn, unsigned long ea); -extern int do_stvx(int rn, unsigned long ea); -extern int do_lxvd2x(int rn, unsigned long ea); -extern int do_stxvd2x(int rn, unsigned long ea); +extern void get_fpr(int rn, double *p); +extern void put_fpr(int rn, const double *p); +extern void get_vr(int rn, __vector128 *p); +extern void put_vr(int rn, __vector128 *p); +extern void load_vsrn(int vsr, const void *p); +extern void store_vsrn(int vsr, void *p); +extern void conv_sp_to_dp(const float *sp, double *dp); +extern void conv_dp_to_sp(const double *dp, float *sp); +#endif + +#ifdef __powerpc64__ +/* + * Functions in quad.S + */ +extern int do_lq(unsigned long ea, unsigned long *regs); +extern int do_stq(unsigned long ea, unsigned long val0, unsigned long val1); +extern int do_lqarx(unsigned long ea, unsigned long *regs); +extern int do_stqcx(unsigned long ea, unsigned long val0, unsigned long val1, + unsigned int *crp); +#endif + +#ifdef __LITTLE_ENDIAN__ +#define IS_LE 1 +#define IS_BE 0 +#else +#define IS_LE 0 +#define IS_BE 1 #endif /* @@ -62,15 +81,17 @@ static nokprobe_inline unsigned long truncate_if_32bit(unsigned long msr, /* * Determine whether a conditional branch instruction would branch. */ -static nokprobe_inline int branch_taken(unsigned int instr, struct pt_regs *regs) +static nokprobe_inline int branch_taken(unsigned int instr, + const struct pt_regs *regs, + struct instruction_op *op) { unsigned int bo = (instr >> 21) & 0x1f; unsigned int bi; if ((bo & 4) == 0) { /* decrement counter */ - --regs->ctr; - if (((bo >> 1) & 1) ^ (regs->ctr == 0)) + op->type |= DECCTR; + if (((bo >> 1) & 1) ^ (regs->ctr == 1)) return 0; } if ((bo & 0x10) == 0) { @@ -82,17 +103,26 @@ static nokprobe_inline int branch_taken(unsigned int instr, struct pt_regs *regs return 1; } -static nokprobe_inline long address_ok(struct pt_regs *regs, unsigned long ea, int nb) +static nokprobe_inline long address_ok(struct pt_regs *regs, + unsigned long ea, int nb) { if (!user_mode(regs)) return 1; - return __access_ok(ea, nb, USER_DS); + if (__access_ok(ea, nb, USER_DS)) + return 1; + if (__access_ok(ea, 1, USER_DS)) + /* Access overlaps the end of the user region */ + regs->dar = USER_DS.seg; + else + regs->dar = ea; + return 0; } /* * Calculate effective address for a D-form instruction */ -static nokprobe_inline unsigned long dform_ea(unsigned int instr, struct pt_regs *regs) +static nokprobe_inline unsigned long dform_ea(unsigned int instr, + const struct pt_regs *regs) { int ra; unsigned long ea; @@ -102,14 +132,15 @@ static nokprobe_inline unsigned long dform_ea(unsigned int instr, struct pt_regs if (ra) ea += regs->gpr[ra]; - return truncate_if_32bit(regs->msr, ea); + return ea; } #ifdef __powerpc64__ /* * Calculate effective address for a DS-form instruction */ -static nokprobe_inline unsigned long dsform_ea(unsigned int instr, struct pt_regs *regs) +static nokprobe_inline unsigned long dsform_ea(unsigned int instr, + const struct pt_regs *regs) { int ra; unsigned long ea; @@ -119,7 +150,24 @@ static nokprobe_inline unsigned long dsform_ea(unsigned int instr, struct pt_reg if (ra) ea += regs->gpr[ra]; - return truncate_if_32bit(regs->msr, ea); + return ea; +} + +/* + * Calculate effective address for a DQ-form instruction + */ +static nokprobe_inline unsigned long dqform_ea(unsigned int instr, + const struct pt_regs *regs) +{ + int ra; + unsigned long ea; + + ra = (instr >> 16) & 0x1f; + ea = (signed short) (instr & ~0xf); /* sign-extend */ + if (ra) + ea += regs->gpr[ra]; + + return ea; } #endif /* __powerpc64 */ @@ -127,7 +175,7 @@ static nokprobe_inline unsigned long dsform_ea(unsigned int instr, struct pt_reg * Calculate effective address for an X-form instruction */ static nokprobe_inline unsigned long xform_ea(unsigned int instr, - struct pt_regs *regs) + const struct pt_regs *regs) { int ra, rb; unsigned long ea; @@ -138,7 +186,7 @@ static nokprobe_inline unsigned long xform_ea(unsigned int instr, if (ra) ea += regs->gpr[ra]; - return truncate_if_32bit(regs->msr, ea); + return ea; } /* @@ -151,7 +199,6 @@ static nokprobe_inline unsigned long max_align(unsigned long x) return x & -x; /* isolates rightmost bit */ } - static nokprobe_inline unsigned long byterev_2(unsigned long x) { return ((x >> 8) & 0xff) | ((x & 0xff) << 8); @@ -170,8 +217,36 @@ static nokprobe_inline unsigned long byterev_8(unsigned long x) } #endif +static nokprobe_inline void do_byte_reverse(void *ptr, int nb) +{ + switch (nb) { + case 2: + *(u16 *)ptr = byterev_2(*(u16 *)ptr); + break; + case 4: + *(u32 *)ptr = byterev_4(*(u32 *)ptr); + break; +#ifdef __powerpc64__ + case 8: + *(unsigned long *)ptr = byterev_8(*(unsigned long *)ptr); + break; + case 16: { + unsigned long *up = (unsigned long *)ptr; + unsigned long tmp; + tmp = byterev_8(up[0]); + up[0] = byterev_8(up[1]); + up[1] = tmp; + break; + } +#endif + default: + WARN_ON_ONCE(1); + } +} + static nokprobe_inline int read_mem_aligned(unsigned long *dest, - unsigned long ea, int nb) + unsigned long ea, int nb, + struct pt_regs *regs) { int err = 0; unsigned long x = 0; @@ -194,59 +269,77 @@ static nokprobe_inline int read_mem_aligned(unsigned long *dest, } if (!err) *dest = x; + else + regs->dar = ea; return err; } -static nokprobe_inline int read_mem_unaligned(unsigned long *dest, - unsigned long ea, int nb, struct pt_regs *regs) +/* + * Copy from userspace to a buffer, using the largest possible + * aligned accesses, up to sizeof(long). + */ +static int nokprobe_inline copy_mem_in(u8 *dest, unsigned long ea, int nb, + struct pt_regs *regs) { - int err; - unsigned long x, b, c; -#ifdef __LITTLE_ENDIAN__ - int len = nb; /* save a copy of the length for byte reversal */ -#endif + int err = 0; + int c; - /* unaligned, do this in pieces */ - x = 0; for (; nb > 0; nb -= c) { -#ifdef __LITTLE_ENDIAN__ - c = 1; -#endif -#ifdef __BIG_ENDIAN__ c = max_align(ea); -#endif if (c > nb) c = max_align(nb); - err = read_mem_aligned(&b, ea, c); - if (err) + switch (c) { + case 1: + err = __get_user(*dest, (unsigned char __user *) ea); + break; + case 2: + err = __get_user(*(u16 *)dest, + (unsigned short __user *) ea); + break; + case 4: + err = __get_user(*(u32 *)dest, + (unsigned int __user *) ea); + break; +#ifdef __powerpc64__ + case 8: + err = __get_user(*(unsigned long *)dest, + (unsigned long __user *) ea); + break; +#endif + } + if (err) { + regs->dar = ea; return err; - x = (x << (8 * c)) + b; + } + dest += c; ea += c; } -#ifdef __LITTLE_ENDIAN__ - switch (len) { - case 2: - *dest = byterev_2(x); - break; - case 4: - *dest = byterev_4(x); - break; -#ifdef __powerpc64__ - case 8: - *dest = byterev_8(x); - break; -#endif - } -#endif -#ifdef __BIG_ENDIAN__ - *dest = x; -#endif return 0; } +static nokprobe_inline int read_mem_unaligned(unsigned long *dest, + unsigned long ea, int nb, + struct pt_regs *regs) +{ + union { + unsigned long ul; + u8 b[sizeof(unsigned long)]; + } u; + int i; + int err; + + u.ul = 0; + i = IS_BE ? sizeof(unsigned long) - nb : 0; + err = copy_mem_in(&u.b[i], ea, nb, regs); + if (!err) + *dest = u.ul; + return err; +} + /* * Read memory at address ea for nb bytes, return 0 for success - * or -EFAULT if an error occurred. + * or -EFAULT if an error occurred. N.B. nb must be 1, 2, 4 or 8. + * If nb < sizeof(long), the result is right-justified on BE systems. */ static int read_mem(unsigned long *dest, unsigned long ea, int nb, struct pt_regs *regs) @@ -254,13 +347,14 @@ static int read_mem(unsigned long *dest, unsigned long ea, int nb, if (!address_ok(regs, ea, nb)) return -EFAULT; if ((ea & (nb - 1)) == 0) - return read_mem_aligned(dest, ea, nb); + return read_mem_aligned(dest, ea, nb, regs); return read_mem_unaligned(dest, ea, nb, regs); } NOKPROBE_SYMBOL(read_mem); static nokprobe_inline int write_mem_aligned(unsigned long val, - unsigned long ea, int nb) + unsigned long ea, int nb, + struct pt_regs *regs) { int err = 0; @@ -280,51 +374,72 @@ static nokprobe_inline int write_mem_aligned(unsigned long val, break; #endif } + if (err) + regs->dar = ea; return err; } -static nokprobe_inline int write_mem_unaligned(unsigned long val, - unsigned long ea, int nb, struct pt_regs *regs) +/* + * Copy from a buffer to userspace, using the largest possible + * aligned accesses, up to sizeof(long). + */ +static int nokprobe_inline copy_mem_out(u8 *dest, unsigned long ea, int nb, + struct pt_regs *regs) { - int err; - unsigned long c; + int err = 0; + int c; -#ifdef __LITTLE_ENDIAN__ - switch (nb) { - case 2: - val = byterev_2(val); - break; - case 4: - val = byterev_4(val); - break; -#ifdef __powerpc64__ - case 8: - val = byterev_8(val); - break; -#endif - } -#endif - /* unaligned or little-endian, do this in pieces */ for (; nb > 0; nb -= c) { -#ifdef __LITTLE_ENDIAN__ - c = 1; -#endif -#ifdef __BIG_ENDIAN__ c = max_align(ea); -#endif if (c > nb) c = max_align(nb); - err = write_mem_aligned(val >> (nb - c) * 8, ea, c); - if (err) + switch (c) { + case 1: + err = __put_user(*dest, (unsigned char __user *) ea); + break; + case 2: + err = __put_user(*(u16 *)dest, + (unsigned short __user *) ea); + break; + case 4: + err = __put_user(*(u32 *)dest, + (unsigned int __user *) ea); + break; +#ifdef __powerpc64__ + case 8: + err = __put_user(*(unsigned long *)dest, + (unsigned long __user *) ea); + break; +#endif + } + if (err) { + regs->dar = ea; return err; + } + dest += c; ea += c; } return 0; } +static nokprobe_inline int write_mem_unaligned(unsigned long val, + unsigned long ea, int nb, + struct pt_regs *regs) +{ + union { + unsigned long ul; + u8 b[sizeof(unsigned long)]; + } u; + int i; + + u.ul = val; + i = IS_BE ? sizeof(unsigned long) - nb : 0; + return copy_mem_out(&u.b[i], ea, nb, regs); +} + /* * Write memory at address ea for nb bytes, return 0 for success - * or -EFAULT if an error occurred. + * or -EFAULT if an error occurred. N.B. nb must be 1, 2, 4 or 8. */ static int write_mem(unsigned long val, unsigned long ea, int nb, struct pt_regs *regs) @@ -332,163 +447,465 @@ static int write_mem(unsigned long val, unsigned long ea, int nb, if (!address_ok(regs, ea, nb)) return -EFAULT; if ((ea & (nb - 1)) == 0) - return write_mem_aligned(val, ea, nb); + return write_mem_aligned(val, ea, nb, regs); return write_mem_unaligned(val, ea, nb, regs); } NOKPROBE_SYMBOL(write_mem); #ifdef CONFIG_PPC_FPU /* - * Check the address and alignment, and call func to do the actual - * load or store. + * These access either the real FP register or the image in the + * thread_struct, depending on regs->msr & MSR_FP. */ -static int do_fp_load(int rn, int (*func)(int, unsigned long), - unsigned long ea, int nb, - struct pt_regs *regs) +static int do_fp_load(struct instruction_op *op, unsigned long ea, + struct pt_regs *regs, bool cross_endian) { - int err; + int err, rn, nb; union { - double dbl; - unsigned long ul[2]; - struct { -#ifdef __BIG_ENDIAN__ - unsigned _pad_; - unsigned word; -#endif -#ifdef __LITTLE_ENDIAN__ - unsigned word; - unsigned _pad_; -#endif - } single; - } data; - unsigned long ptr; + int i; + unsigned int u; + float f; + double d[2]; + unsigned long l[2]; + u8 b[2 * sizeof(double)]; + } u; + nb = GETSIZE(op->type); if (!address_ok(regs, ea, nb)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - ptr = (unsigned long) &data.ul; - if (sizeof(unsigned long) == 8 || nb == 4) { - err = read_mem_unaligned(&data.ul[0], ea, nb, regs); - if (nb == 4) - ptr = (unsigned long)&(data.single.word); - } else { - /* reading a double on 32-bit */ - err = read_mem_unaligned(&data.ul[0], ea, 4, regs); - if (!err) - err = read_mem_unaligned(&data.ul[1], ea + 4, 4, regs); - } + rn = op->reg; + err = copy_mem_in(u.b, ea, nb, regs); if (err) return err; - return (*func)(rn, ptr); + if (unlikely(cross_endian)) { + do_byte_reverse(u.b, min(nb, 8)); + if (nb == 16) + do_byte_reverse(&u.b[8], 8); + } + preempt_disable(); + if (nb == 4) { + if (op->type & FPCONV) + conv_sp_to_dp(&u.f, &u.d[0]); + else if (op->type & SIGNEXT) + u.l[0] = u.i; + else + u.l[0] = u.u; + } + if (regs->msr & MSR_FP) + put_fpr(rn, &u.d[0]); + else + current->thread.TS_FPR(rn) = u.l[0]; + if (nb == 16) { + /* lfdp */ + rn |= 1; + if (regs->msr & MSR_FP) + put_fpr(rn, &u.d[1]); + else + current->thread.TS_FPR(rn) = u.l[1]; + } + preempt_enable(); + return 0; } NOKPROBE_SYMBOL(do_fp_load); -static int do_fp_store(int rn, int (*func)(int, unsigned long), - unsigned long ea, int nb, - struct pt_regs *regs) +static int do_fp_store(struct instruction_op *op, unsigned long ea, + struct pt_regs *regs, bool cross_endian) { - int err; + int rn, nb; union { - double dbl; - unsigned long ul[2]; - struct { -#ifdef __BIG_ENDIAN__ - unsigned _pad_; - unsigned word; -#endif -#ifdef __LITTLE_ENDIAN__ - unsigned word; - unsigned _pad_; -#endif - } single; - } data; - unsigned long ptr; + unsigned int u; + float f; + double d[2]; + unsigned long l[2]; + u8 b[2 * sizeof(double)]; + } u; + nb = GETSIZE(op->type); if (!address_ok(regs, ea, nb)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - ptr = (unsigned long) &data.ul[0]; - if (sizeof(unsigned long) == 8 || nb == 4) { - if (nb == 4) - ptr = (unsigned long)&(data.single.word); - err = (*func)(rn, ptr); - if (err) - return err; - err = write_mem_unaligned(data.ul[0], ea, nb, regs); - } else { - /* writing a double on 32-bit */ - err = (*func)(rn, ptr); - if (err) - return err; - err = write_mem_unaligned(data.ul[0], ea, 4, regs); - if (!err) - err = write_mem_unaligned(data.ul[1], ea + 4, 4, regs); + rn = op->reg; + preempt_disable(); + if (regs->msr & MSR_FP) + get_fpr(rn, &u.d[0]); + else + u.l[0] = current->thread.TS_FPR(rn); + if (nb == 4) { + if (op->type & FPCONV) + conv_dp_to_sp(&u.d[0], &u.f); + else + u.u = u.l[0]; } - return err; + if (nb == 16) { + rn |= 1; + if (regs->msr & MSR_FP) + get_fpr(rn, &u.d[1]); + else + u.l[1] = current->thread.TS_FPR(rn); + } + preempt_enable(); + if (unlikely(cross_endian)) { + do_byte_reverse(u.b, min(nb, 8)); + if (nb == 16) + do_byte_reverse(&u.b[8], 8); + } + return copy_mem_out(u.b, ea, nb, regs); } NOKPROBE_SYMBOL(do_fp_store); #endif #ifdef CONFIG_ALTIVEC /* For Altivec/VMX, no need to worry about alignment */ -static nokprobe_inline int do_vec_load(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +static nokprobe_inline int do_vec_load(int rn, unsigned long ea, + int size, struct pt_regs *regs, + bool cross_endian) { + int err; + union { + __vector128 v; + u8 b[sizeof(__vector128)]; + } u = {}; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; - return (*func)(rn, ea); + /* align to multiple of size */ + ea &= ~(size - 1); + err = copy_mem_in(&u.b[ea & 0xf], ea, size, regs); + if (err) + return err; + if (unlikely(cross_endian)) + do_byte_reverse(&u.b[ea & 0xf], size); + preempt_disable(); + if (regs->msr & MSR_VEC) + put_vr(rn, &u.v); + else + current->thread.vr_state.vr[rn] = u.v; + preempt_enable(); + return 0; } -static nokprobe_inline int do_vec_store(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +static nokprobe_inline int do_vec_store(int rn, unsigned long ea, + int size, struct pt_regs *regs, + bool cross_endian) { + union { + __vector128 v; + u8 b[sizeof(__vector128)]; + } u; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; - return (*func)(rn, ea); + /* align to multiple of size */ + ea &= ~(size - 1); + + preempt_disable(); + if (regs->msr & MSR_VEC) + get_vr(rn, &u.v); + else + u.v = current->thread.vr_state.vr[rn]; + preempt_enable(); + if (unlikely(cross_endian)) + do_byte_reverse(&u.b[ea & 0xf], size); + return copy_mem_out(&u.b[ea & 0xf], ea, size, regs); } #endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_VSX -static nokprobe_inline int do_vsx_load(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +#ifdef __powerpc64__ +static nokprobe_inline int emulate_lq(struct pt_regs *regs, unsigned long ea, + int reg, bool cross_endian) { int err; - unsigned long val[2]; if (!address_ok(regs, ea, 16)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - err = read_mem_unaligned(&val[0], ea, 8, regs); - if (!err) - err = read_mem_unaligned(&val[1], ea + 8, 8, regs); - if (!err) - err = (*func)(rn, (unsigned long) &val[0]); + /* if aligned, should be atomic */ + if ((ea & 0xf) == 0) { + err = do_lq(ea, ®s->gpr[reg]); + } else { + err = read_mem(®s->gpr[reg + IS_LE], ea, 8, regs); + if (!err) + err = read_mem(®s->gpr[reg + IS_BE], ea + 8, 8, regs); + } + if (!err && unlikely(cross_endian)) + do_byte_reverse(®s->gpr[reg], 16); return err; } -static nokprobe_inline int do_vsx_store(int rn, int (*func)(int, unsigned long), - unsigned long ea, struct pt_regs *regs) +static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea, + int reg, bool cross_endian) { int err; - unsigned long val[2]; + unsigned long vals[2]; if (!address_ok(regs, ea, 16)) return -EFAULT; - if ((ea & 3) == 0) - return (*func)(rn, ea); - err = (*func)(rn, (unsigned long) &val[0]); - if (err) - return err; - err = write_mem_unaligned(val[0], ea, 8, regs); + vals[0] = regs->gpr[reg]; + vals[1] = regs->gpr[reg + 1]; + if (unlikely(cross_endian)) + do_byte_reverse(vals, 16); + + /* if aligned, should be atomic */ + if ((ea & 0xf) == 0) + return do_stq(ea, vals[0], vals[1]); + + err = write_mem(vals[IS_LE], ea, 8, regs); if (!err) - err = write_mem_unaligned(val[1], ea + 8, 8, regs); + err = write_mem(vals[IS_BE], ea + 8, 8, regs); return err; } +#endif /* __powerpc64 */ + +#ifdef CONFIG_VSX +void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, + const void *mem, bool rev) +{ + int size, read_size; + int i, j; + const unsigned int *wp; + const unsigned short *hp; + const unsigned char *bp; + + size = GETSIZE(op->type); + reg->d[0] = reg->d[1] = 0; + + switch (op->element_size) { + case 16: + /* whole vector; lxv[x] or lxvl[l] */ + if (size == 0) + break; + memcpy(reg, mem, size); + if (IS_LE && (op->vsx_flags & VSX_LDLEFT)) + rev = !rev; + if (rev) + do_byte_reverse(reg, 16); + break; + case 8: + /* scalar loads, lxvd2x, lxvdsx */ + read_size = (size >= 8) ? 8 : size; + i = IS_LE ? 8 : 8 - read_size; + memcpy(®->b[i], mem, read_size); + if (rev) + do_byte_reverse(®->b[i], 8); + if (size < 8) { + if (op->type & SIGNEXT) { + /* size == 4 is the only case here */ + reg->d[IS_LE] = (signed int) reg->d[IS_LE]; + } else if (op->vsx_flags & VSX_FPCONV) { + preempt_disable(); + conv_sp_to_dp(®->fp[1 + IS_LE], + ®->dp[IS_LE]); + preempt_enable(); + } + } else { + if (size == 16) { + unsigned long v = *(unsigned long *)(mem + 8); + reg->d[IS_BE] = !rev ? v : byterev_8(v); + } else if (op->vsx_flags & VSX_SPLAT) + reg->d[IS_BE] = reg->d[IS_LE]; + } + break; + case 4: + /* lxvw4x, lxvwsx */ + wp = mem; + for (j = 0; j < size / 4; ++j) { + i = IS_LE ? 3 - j : j; + reg->w[i] = !rev ? *wp++ : byterev_4(*wp++); + } + if (op->vsx_flags & VSX_SPLAT) { + u32 val = reg->w[IS_LE ? 3 : 0]; + for (; j < 4; ++j) { + i = IS_LE ? 3 - j : j; + reg->w[i] = val; + } + } + break; + case 2: + /* lxvh8x */ + hp = mem; + for (j = 0; j < size / 2; ++j) { + i = IS_LE ? 7 - j : j; + reg->h[i] = !rev ? *hp++ : byterev_2(*hp++); + } + break; + case 1: + /* lxvb16x */ + bp = mem; + for (j = 0; j < size; ++j) { + i = IS_LE ? 15 - j : j; + reg->b[i] = *bp++; + } + break; + } +} +EXPORT_SYMBOL_GPL(emulate_vsx_load); +NOKPROBE_SYMBOL(emulate_vsx_load); + +void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, + void *mem, bool rev) +{ + int size, write_size; + int i, j; + union vsx_reg buf; + unsigned int *wp; + unsigned short *hp; + unsigned char *bp; + + size = GETSIZE(op->type); + + switch (op->element_size) { + case 16: + /* stxv, stxvx, stxvl, stxvll */ + if (size == 0) + break; + if (IS_LE && (op->vsx_flags & VSX_LDLEFT)) + rev = !rev; + if (rev) { + /* reverse 16 bytes */ + buf.d[0] = byterev_8(reg->d[1]); + buf.d[1] = byterev_8(reg->d[0]); + reg = &buf; + } + memcpy(mem, reg, size); + break; + case 8: + /* scalar stores, stxvd2x */ + write_size = (size >= 8) ? 8 : size; + i = IS_LE ? 8 : 8 - write_size; + if (size < 8 && op->vsx_flags & VSX_FPCONV) { + buf.d[0] = buf.d[1] = 0; + preempt_disable(); + conv_dp_to_sp(®->dp[IS_LE], &buf.fp[1 + IS_LE]); + preempt_enable(); + reg = &buf; + } + memcpy(mem, ®->b[i], write_size); + if (size == 16) + memcpy(mem + 8, ®->d[IS_BE], 8); + if (unlikely(rev)) { + do_byte_reverse(mem, write_size); + if (size == 16) + do_byte_reverse(mem + 8, 8); + } + break; + case 4: + /* stxvw4x */ + wp = mem; + for (j = 0; j < size / 4; ++j) { + i = IS_LE ? 3 - j : j; + *wp++ = !rev ? reg->w[i] : byterev_4(reg->w[i]); + } + break; + case 2: + /* stxvh8x */ + hp = mem; + for (j = 0; j < size / 2; ++j) { + i = IS_LE ? 7 - j : j; + *hp++ = !rev ? reg->h[i] : byterev_2(reg->h[i]); + } + break; + case 1: + /* stvxb16x */ + bp = mem; + for (j = 0; j < size; ++j) { + i = IS_LE ? 15 - j : j; + *bp++ = reg->b[i]; + } + break; + } +} +EXPORT_SYMBOL_GPL(emulate_vsx_store); +NOKPROBE_SYMBOL(emulate_vsx_store); + +static nokprobe_inline int do_vsx_load(struct instruction_op *op, + unsigned long ea, struct pt_regs *regs, + bool cross_endian) +{ + int reg = op->reg; + u8 mem[16]; + union vsx_reg buf; + int size = GETSIZE(op->type); + + if (!address_ok(regs, ea, size) || copy_mem_in(mem, ea, size, regs)) + return -EFAULT; + + emulate_vsx_load(op, &buf, mem, cross_endian); + preempt_disable(); + if (reg < 32) { + /* FP regs + extensions */ + if (regs->msr & MSR_FP) { + load_vsrn(reg, &buf); + } else { + current->thread.fp_state.fpr[reg][0] = buf.d[0]; + current->thread.fp_state.fpr[reg][1] = buf.d[1]; + } + } else { + if (regs->msr & MSR_VEC) + load_vsrn(reg, &buf); + else + current->thread.vr_state.vr[reg - 32] = buf.v; + } + preempt_enable(); + return 0; +} + +static nokprobe_inline int do_vsx_store(struct instruction_op *op, + unsigned long ea, struct pt_regs *regs, + bool cross_endian) +{ + int reg = op->reg; + u8 mem[16]; + union vsx_reg buf; + int size = GETSIZE(op->type); + + if (!address_ok(regs, ea, size)) + return -EFAULT; + + preempt_disable(); + if (reg < 32) { + /* FP regs + extensions */ + if (regs->msr & MSR_FP) { + store_vsrn(reg, &buf); + } else { + buf.d[0] = current->thread.fp_state.fpr[reg][0]; + buf.d[1] = current->thread.fp_state.fpr[reg][1]; + } + } else { + if (regs->msr & MSR_VEC) + store_vsrn(reg, &buf); + else + buf.v = current->thread.vr_state.vr[reg - 32]; + } + preempt_enable(); + emulate_vsx_store(op, &buf, mem, cross_endian); + return copy_mem_out(mem, ea, size, regs); +} #endif /* CONFIG_VSX */ +int emulate_dcbz(unsigned long ea, struct pt_regs *regs) +{ + int err; + unsigned long i, size; + +#ifdef __powerpc64__ + size = ppc64_caches.l1d.block_size; + if (!(regs->msr & MSR_64BIT)) + ea &= 0xffffffffUL; +#else + size = L1_CACHE_BYTES; +#endif + ea &= ~(size - 1); + if (!address_ok(regs, ea, size)) + return -EFAULT; + for (i = 0; i < size; i += sizeof(long)) { + err = __put_user(0, (unsigned long __user *) (ea + i)); + if (err) { + regs->dar = ea; + return err; + } + } + return 0; +} +NOKPROBE_SYMBOL(emulate_dcbz); + #define __put_user_asmx(x, addr, err, op, cr) \ __asm__ __volatile__( \ "1: " op " %2,0,%3\n" \ @@ -526,24 +943,27 @@ static nokprobe_inline int do_vsx_store(int rn, int (*func)(int, unsigned long), : "=r" (err) \ : "r" (addr), "i" (-EFAULT), "0" (err)) -static nokprobe_inline void set_cr0(struct pt_regs *regs, int rd) +static nokprobe_inline void set_cr0(const struct pt_regs *regs, + struct instruction_op *op) { - long val = regs->gpr[rd]; + long val = op->val; - regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); + op->type |= SETCC; + op->ccval = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000); #ifdef __powerpc64__ if (!(regs->msr & MSR_64BIT)) val = (int) val; #endif if (val < 0) - regs->ccr |= 0x80000000; + op->ccval |= 0x80000000; else if (val > 0) - regs->ccr |= 0x40000000; + op->ccval |= 0x40000000; else - regs->ccr |= 0x20000000; + op->ccval |= 0x20000000; } -static nokprobe_inline void add_with_carry(struct pt_regs *regs, int rd, +static nokprobe_inline void add_with_carry(const struct pt_regs *regs, + struct instruction_op *op, int rd, unsigned long val1, unsigned long val2, unsigned long carry_in) { @@ -551,24 +971,29 @@ static nokprobe_inline void add_with_carry(struct pt_regs *regs, int rd, if (carry_in) ++val; - regs->gpr[rd] = val; + op->type = COMPUTE + SETREG + SETXER; + op->reg = rd; + op->val = val; #ifdef __powerpc64__ if (!(regs->msr & MSR_64BIT)) { val = (unsigned int) val; val1 = (unsigned int) val1; } #endif + op->xerval = regs->xer; if (val < val1 || (carry_in && val == val1)) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; } -static nokprobe_inline void do_cmp_signed(struct pt_regs *regs, long v1, long v2, - int crfld) +static nokprobe_inline void do_cmp_signed(const struct pt_regs *regs, + struct instruction_op *op, + long v1, long v2, int crfld) { unsigned int crval, shift; + op->type = COMPUTE + SETCC; crval = (regs->xer >> 31) & 1; /* get SO bit */ if (v1 < v2) crval |= 8; @@ -577,14 +1002,17 @@ static nokprobe_inline void do_cmp_signed(struct pt_regs *regs, long v1, long v2 else crval |= 2; shift = (7 - crfld) * 4; - regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); + op->ccval = (regs->ccr & ~(0xf << shift)) | (crval << shift); } -static nokprobe_inline void do_cmp_unsigned(struct pt_regs *regs, unsigned long v1, - unsigned long v2, int crfld) +static nokprobe_inline void do_cmp_unsigned(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, + unsigned long v2, int crfld) { unsigned int crval, shift; + op->type = COMPUTE + SETCC; crval = (regs->xer >> 31) & 1; /* get SO bit */ if (v1 < v2) crval |= 8; @@ -593,7 +1021,90 @@ static nokprobe_inline void do_cmp_unsigned(struct pt_regs *regs, unsigned long else crval |= 2; shift = (7 - crfld) * 4; - regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift); + op->ccval = (regs->ccr & ~(0xf << shift)) | (crval << shift); +} + +static nokprobe_inline void do_cmpb(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, unsigned long v2) +{ + unsigned long long out_val, mask; + int i; + + out_val = 0; + for (i = 0; i < 8; i++) { + mask = 0xffUL << (i * 8); + if ((v1 & mask) == (v2 & mask)) + out_val |= mask; + } + op->val = out_val; +} + +/* + * The size parameter is used to adjust the equivalent popcnt instruction. + * popcntb = 8, popcntw = 32, popcntd = 64 + */ +static nokprobe_inline void do_popcnt(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, int size) +{ + unsigned long long out = v1; + + out -= (out >> 1) & 0x5555555555555555; + out = (0x3333333333333333 & out) + (0x3333333333333333 & (out >> 2)); + out = (out + (out >> 4)) & 0x0f0f0f0f0f0f0f0f; + + if (size == 8) { /* popcntb */ + op->val = out; + return; + } + out += out >> 8; + out += out >> 16; + if (size == 32) { /* popcntw */ + op->val = out & 0x0000003f0000003f; + return; + } + + out = (out + (out >> 32)) & 0x7f; + op->val = out; /* popcntd */ +} + +#ifdef CONFIG_PPC64 +static nokprobe_inline void do_bpermd(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v1, unsigned long v2) +{ + unsigned char perm, idx; + unsigned int i; + + perm = 0; + for (i = 0; i < 8; i++) { + idx = (v1 >> (i * 8)) & 0xff; + if (idx < 64) + if (v2 & PPC_BIT(idx)) + perm |= 1 << i; + } + op->val = perm; +} +#endif /* CONFIG_PPC64 */ +/* + * The size parameter adjusts the equivalent prty instruction. + * prtyw = 32, prtyd = 64 + */ +static nokprobe_inline void do_prty(const struct pt_regs *regs, + struct instruction_op *op, + unsigned long v, int size) +{ + unsigned long long res = v ^ (v >> 8); + + res ^= res >> 16; + if (size == 32) { /* prtyw */ + op->val = res & 0x0000000100000001; + return; + } + + res ^= res >> 32; + op->val = res & 1; /*prtyd */ } static nokprobe_inline int trap_compare(long v1, long v2) @@ -629,14 +1140,18 @@ static nokprobe_inline int trap_compare(long v1, long v2) #define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long) - (n)))) : (x)) /* - * Decode an instruction, and execute it if that can be done just by - * modifying *regs (i.e. integer arithmetic and logical instructions, - * branches, and barrier instructions). - * Returns 1 if the instruction has been executed, or 0 if not. - * Sets *op to indicate what the instruction does. + * Decode an instruction, and return information about it in *op + * without changing *regs. + * Integer arithmetic and logical instructions, branches, and barrier + * instructions can be emulated just using the information in *op. + * + * Return value is 1 if the instruction can be emulated just by + * updating *regs with the information in *op, -1 if we need the + * GPRs but *regs doesn't contain the full register set, or 0 + * otherwise. */ -int analyse_instr(struct instruction_op *op, struct pt_regs *regs, - unsigned int instr) +int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, + unsigned int instr) { unsigned int opcode, ra, rb, rd, spr, u; unsigned long int imm; @@ -653,12 +1168,11 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, imm = (signed short)(instr & 0xfffc); if ((instr & 2) == 0) imm += regs->nip; - regs->nip += 4; - regs->nip = truncate_if_32bit(regs->msr, regs->nip); + op->val = truncate_if_32bit(regs->msr, imm); if (instr & 1) - regs->link = regs->nip; - if (branch_taken(instr, regs)) - regs->nip = truncate_if_32bit(regs->msr, imm); + op->type |= SETLK; + if (branch_taken(instr, regs, op)) + op->type |= BRTAKEN; return 1; #ifdef CONFIG_PPC64 case 17: /* sc */ @@ -669,38 +1183,37 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, return 0; #endif case 18: /* b */ - op->type = BRANCH; + op->type = BRANCH | BRTAKEN; imm = instr & 0x03fffffc; if (imm & 0x02000000) imm -= 0x04000000; if ((instr & 2) == 0) imm += regs->nip; + op->val = truncate_if_32bit(regs->msr, imm); if (instr & 1) - regs->link = truncate_if_32bit(regs->msr, regs->nip + 4); - imm = truncate_if_32bit(regs->msr, imm); - regs->nip = imm; + op->type |= SETLK; return 1; case 19: switch ((instr >> 1) & 0x3ff) { case 0: /* mcrf */ + op->type = COMPUTE + SETCC; rd = 7 - ((instr >> 23) & 0x7); ra = 7 - ((instr >> 18) & 0x7); rd *= 4; ra *= 4; val = (regs->ccr >> ra) & 0xf; - regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd); - goto instr_done; + op->ccval = (regs->ccr & ~(0xfUL << rd)) | (val << rd); + return 1; case 16: /* bclr */ case 528: /* bcctr */ op->type = BRANCH; imm = (instr & 0x400)? regs->ctr: regs->link; - regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); - imm = truncate_if_32bit(regs->msr, imm); + op->val = truncate_if_32bit(regs->msr, imm); if (instr & 1) - regs->link = regs->nip; - if (branch_taken(instr, regs)) - regs->nip = imm; + op->type |= SETLK; + if (branch_taken(instr, regs, op)) + op->type |= BRTAKEN; return 1; case 18: /* rfid, scary */ @@ -710,9 +1223,8 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, return 0; case 150: /* isync */ - op->type = BARRIER; - isync(); - goto instr_done; + op->type = BARRIER | BARRIER_ISYNC; + return 1; case 33: /* crnor */ case 129: /* crandc */ @@ -722,45 +1234,44 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 289: /* creqv */ case 417: /* crorc */ case 449: /* cror */ + op->type = COMPUTE + SETCC; ra = (instr >> 16) & 0x1f; rb = (instr >> 11) & 0x1f; rd = (instr >> 21) & 0x1f; ra = (regs->ccr >> (31 - ra)) & 1; rb = (regs->ccr >> (31 - rb)) & 1; val = (instr >> (6 + ra * 2 + rb)) & 1; - regs->ccr = (regs->ccr & ~(1UL << (31 - rd))) | + op->ccval = (regs->ccr & ~(1UL << (31 - rd))) | (val << (31 - rd)); - goto instr_done; + return 1; } break; case 31: switch ((instr >> 1) & 0x3ff) { case 598: /* sync */ - op->type = BARRIER; + op->type = BARRIER + BARRIER_SYNC; #ifdef __powerpc64__ switch ((instr >> 21) & 3) { case 1: /* lwsync */ - asm volatile("lwsync" : : : "memory"); - goto instr_done; + op->type = BARRIER + BARRIER_LWSYNC; + break; case 2: /* ptesync */ - asm volatile("ptesync" : : : "memory"); - goto instr_done; + op->type = BARRIER + BARRIER_PTESYNC; + break; } #endif - mb(); - goto instr_done; + return 1; case 854: /* eieio */ - op->type = BARRIER; - eieio(); - goto instr_done; + op->type = BARRIER + BARRIER_EIEIO; + return 1; } break; } /* Following cases refer to regs->gpr[], so we need all regs */ if (!FULL_REGS(regs)) - return 0; + return -1; rd = (instr >> 21) & 0x1f; ra = (instr >> 16) & 0x1f; @@ -771,21 +1282,21 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 2: /* tdi */ if (rd & trap_compare(regs->gpr[ra], (short) instr)) goto trap; - goto instr_done; + return 1; #endif case 3: /* twi */ if (rd & trap_compare((int)regs->gpr[ra], (short) instr)) goto trap; - goto instr_done; + return 1; case 7: /* mulli */ - regs->gpr[rd] = regs->gpr[ra] * (short) instr; - goto instr_done; + op->val = regs->gpr[ra] * (short) instr; + goto compute_done; case 8: /* subfic */ imm = (short) instr; - add_with_carry(regs, rd, ~regs->gpr[ra], imm, 1); - goto instr_done; + add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1); + return 1; case 10: /* cmpli */ imm = (unsigned short) instr; @@ -794,8 +1305,8 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, if ((rd & 1) == 0) val = (unsigned int) val; #endif - do_cmp_unsigned(regs, val, imm, rd >> 2); - goto instr_done; + do_cmp_unsigned(regs, op, val, imm, rd >> 2); + return 1; case 11: /* cmpi */ imm = (short) instr; @@ -804,47 +1315,58 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, if ((rd & 1) == 0) val = (int) val; #endif - do_cmp_signed(regs, val, imm, rd >> 2); - goto instr_done; + do_cmp_signed(regs, op, val, imm, rd >> 2); + return 1; case 12: /* addic */ imm = (short) instr; - add_with_carry(regs, rd, regs->gpr[ra], imm, 0); - goto instr_done; + add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); + return 1; case 13: /* addic. */ imm = (short) instr; - add_with_carry(regs, rd, regs->gpr[ra], imm, 0); - set_cr0(regs, rd); - goto instr_done; + add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); + set_cr0(regs, op); + return 1; case 14: /* addi */ imm = (short) instr; if (ra) imm += regs->gpr[ra]; - regs->gpr[rd] = imm; - goto instr_done; + op->val = imm; + goto compute_done; case 15: /* addis */ imm = ((short) instr) << 16; if (ra) imm += regs->gpr[ra]; - regs->gpr[rd] = imm; - goto instr_done; + op->val = imm; + goto compute_done; + + case 19: + if (((instr >> 1) & 0x1f) == 2) { + /* addpcis */ + imm = (short) (instr & 0xffc1); /* d0 + d2 fields */ + imm |= (instr >> 15) & 0x3e; /* d1 field */ + op->val = regs->nip + (imm << 16) + 4; + goto compute_done; + } + op->type = UNKNOWN; + return 0; case 20: /* rlwimi */ mb = (instr >> 6) & 0x1f; me = (instr >> 1) & 0x1f; val = DATA32(regs->gpr[rd]); imm = MASK32(mb, me); - regs->gpr[ra] = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); + op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); goto logical_done; case 21: /* rlwinm */ mb = (instr >> 6) & 0x1f; me = (instr >> 1) & 0x1f; val = DATA32(regs->gpr[rd]); - regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); + op->val = ROTATE(val, rb) & MASK32(mb, me); goto logical_done; case 23: /* rlwnm */ @@ -852,40 +1374,37 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, me = (instr >> 1) & 0x1f; rb = regs->gpr[rb] & 0x1f; val = DATA32(regs->gpr[rd]); - regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me); + op->val = ROTATE(val, rb) & MASK32(mb, me); goto logical_done; case 24: /* ori */ - imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] | imm; - goto instr_done; + op->val = regs->gpr[rd] | (unsigned short) instr; + goto logical_done_nocc; case 25: /* oris */ imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] | (imm << 16); - goto instr_done; + op->val = regs->gpr[rd] | (imm << 16); + goto logical_done_nocc; case 26: /* xori */ - imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] ^ imm; - goto instr_done; + op->val = regs->gpr[rd] ^ (unsigned short) instr; + goto logical_done_nocc; case 27: /* xoris */ imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] ^ (imm << 16); - goto instr_done; + op->val = regs->gpr[rd] ^ (imm << 16); + goto logical_done_nocc; case 28: /* andi. */ - imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] & imm; - set_cr0(regs, ra); - goto instr_done; + op->val = regs->gpr[rd] & (unsigned short) instr; + set_cr0(regs, op); + goto logical_done_nocc; case 29: /* andis. */ imm = (unsigned short) instr; - regs->gpr[ra] = regs->gpr[rd] & (imm << 16); - set_cr0(regs, ra); - goto instr_done; + op->val = regs->gpr[rd] & (imm << 16); + set_cr0(regs, op); + goto logical_done_nocc; #ifdef __powerpc64__ case 30: /* rld* */ @@ -896,48 +1415,60 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, val = ROTATE(val, sh); switch ((instr >> 2) & 3) { case 0: /* rldicl */ - regs->gpr[ra] = val & MASK64_L(mb); - goto logical_done; + val &= MASK64_L(mb); + break; case 1: /* rldicr */ - regs->gpr[ra] = val & MASK64_R(mb); - goto logical_done; + val &= MASK64_R(mb); + break; case 2: /* rldic */ - regs->gpr[ra] = val & MASK64(mb, 63 - sh); - goto logical_done; + val &= MASK64(mb, 63 - sh); + break; case 3: /* rldimi */ imm = MASK64(mb, 63 - sh); - regs->gpr[ra] = (regs->gpr[ra] & ~imm) | + val = (regs->gpr[ra] & ~imm) | (val & imm); - goto logical_done; } + op->val = val; + goto logical_done; } else { sh = regs->gpr[rb] & 0x3f; val = ROTATE(val, sh); switch ((instr >> 1) & 7) { case 0: /* rldcl */ - regs->gpr[ra] = val & MASK64_L(mb); + op->val = val & MASK64_L(mb); goto logical_done; case 1: /* rldcr */ - regs->gpr[ra] = val & MASK64_R(mb); + op->val = val & MASK64_R(mb); goto logical_done; } } #endif - break; /* illegal instruction */ + op->type = UNKNOWN; /* illegal instruction */ + return 0; case 31: + /* isel occupies 32 minor opcodes */ + if (((instr >> 1) & 0x1f) == 15) { + mb = (instr >> 6) & 0x1f; /* bc field */ + val = (regs->ccr >> (31 - mb)) & 1; + val2 = (ra) ? regs->gpr[ra] : 0; + + op->val = (val) ? val2 : regs->gpr[rb]; + goto compute_done; + } + switch ((instr >> 1) & 0x3ff) { case 4: /* tw */ if (rd == 0x1f || (rd & trap_compare((int)regs->gpr[ra], (int)regs->gpr[rb]))) goto trap; - goto instr_done; + return 1; #ifdef __powerpc64__ case 68: /* td */ if (rd & trap_compare(regs->gpr[ra], regs->gpr[rb])) goto trap; - goto instr_done; + return 1; #endif case 83: /* mfmsr */ if (regs->msr & MSR_PR) @@ -966,74 +1497,50 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, #endif case 19: /* mfcr */ + imm = 0xffffffffUL; if ((instr >> 20) & 1) { imm = 0xf0000000UL; for (sh = 0; sh < 8; ++sh) { - if (instr & (0x80000 >> sh)) { - regs->gpr[rd] = regs->ccr & imm; + if (instr & (0x80000 >> sh)) break; - } imm >>= 4; } - - goto instr_done; } - - regs->gpr[rd] = regs->ccr; - regs->gpr[rd] &= 0xffffffffUL; - goto instr_done; + op->val = regs->ccr & imm; + goto compute_done; case 144: /* mtcrf */ + op->type = COMPUTE + SETCC; imm = 0xf0000000UL; val = regs->gpr[rd]; + op->ccval = regs->ccr; for (sh = 0; sh < 8; ++sh) { if (instr & (0x80000 >> sh)) - regs->ccr = (regs->ccr & ~imm) | + op->ccval = (op->ccval & ~imm) | (val & imm); imm >>= 4; } - goto instr_done; + return 1; case 339: /* mfspr */ spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); - switch (spr) { - case SPRN_XER: /* mfxer */ - regs->gpr[rd] = regs->xer; - regs->gpr[rd] &= 0xffffffffUL; - goto instr_done; - case SPRN_LR: /* mflr */ - regs->gpr[rd] = regs->link; - goto instr_done; - case SPRN_CTR: /* mfctr */ - regs->gpr[rd] = regs->ctr; - goto instr_done; - default: - op->type = MFSPR; - op->reg = rd; - op->spr = spr; - return 0; - } - break; + op->type = MFSPR; + op->reg = rd; + op->spr = spr; + if (spr == SPRN_XER || spr == SPRN_LR || + spr == SPRN_CTR) + return 1; + return 0; case 467: /* mtspr */ spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); - switch (spr) { - case SPRN_XER: /* mtxer */ - regs->xer = (regs->gpr[rd] & 0xffffffffUL); - goto instr_done; - case SPRN_LR: /* mtlr */ - regs->link = regs->gpr[rd]; - goto instr_done; - case SPRN_CTR: /* mtctr */ - regs->ctr = regs->gpr[rd]; - goto instr_done; - default: - op->type = MTSPR; - op->val = regs->gpr[rd]; - op->spr = spr; - return 0; - } - break; + op->type = MTSPR; + op->val = regs->gpr[rd]; + op->spr = spr; + if (spr == SPRN_XER || spr == SPRN_LR || + spr == SPRN_CTR) + return 1; + return 0; /* * Compare instructions @@ -1048,8 +1555,8 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, val2 = (int) val2; } #endif - do_cmp_signed(regs, val, val2, rd >> 2); - goto instr_done; + do_cmp_signed(regs, op, val, val2, rd >> 2); + return 1; case 32: /* cmpl */ val = regs->gpr[ra]; @@ -1061,109 +1568,114 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, val2 = (unsigned int) val2; } #endif - do_cmp_unsigned(regs, val, val2, rd >> 2); - goto instr_done; + do_cmp_unsigned(regs, op, val, val2, rd >> 2); + return 1; + + case 508: /* cmpb */ + do_cmpb(regs, op, regs->gpr[rd], regs->gpr[rb]); + goto logical_done_nocc; /* * Arithmetic instructions */ case 8: /* subfc */ - add_with_carry(regs, rd, ~regs->gpr[ra], + add_with_carry(regs, op, rd, ~regs->gpr[ra], regs->gpr[rb], 1); goto arith_done; #ifdef __powerpc64__ case 9: /* mulhdu */ - asm("mulhdu %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhdu %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; #endif case 10: /* addc */ - add_with_carry(regs, rd, regs->gpr[ra], + add_with_carry(regs, op, rd, regs->gpr[ra], regs->gpr[rb], 0); goto arith_done; case 11: /* mulhwu */ - asm("mulhwu %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhwu %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; case 40: /* subf */ - regs->gpr[rd] = regs->gpr[rb] - regs->gpr[ra]; + op->val = regs->gpr[rb] - regs->gpr[ra]; goto arith_done; #ifdef __powerpc64__ case 73: /* mulhd */ - asm("mulhd %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhd %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; #endif case 75: /* mulhw */ - asm("mulhw %0,%1,%2" : "=r" (regs->gpr[rd]) : + asm("mulhw %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); goto arith_done; case 104: /* neg */ - regs->gpr[rd] = -regs->gpr[ra]; + op->val = -regs->gpr[ra]; goto arith_done; case 136: /* subfe */ - add_with_carry(regs, rd, ~regs->gpr[ra], regs->gpr[rb], - regs->xer & XER_CA); + add_with_carry(regs, op, rd, ~regs->gpr[ra], + regs->gpr[rb], regs->xer & XER_CA); goto arith_done; case 138: /* adde */ - add_with_carry(regs, rd, regs->gpr[ra], regs->gpr[rb], - regs->xer & XER_CA); + add_with_carry(regs, op, rd, regs->gpr[ra], + regs->gpr[rb], regs->xer & XER_CA); goto arith_done; case 200: /* subfze */ - add_with_carry(regs, rd, ~regs->gpr[ra], 0L, + add_with_carry(regs, op, rd, ~regs->gpr[ra], 0L, regs->xer & XER_CA); goto arith_done; case 202: /* addze */ - add_with_carry(regs, rd, regs->gpr[ra], 0L, + add_with_carry(regs, op, rd, regs->gpr[ra], 0L, regs->xer & XER_CA); goto arith_done; case 232: /* subfme */ - add_with_carry(regs, rd, ~regs->gpr[ra], -1L, + add_with_carry(regs, op, rd, ~regs->gpr[ra], -1L, regs->xer & XER_CA); goto arith_done; #ifdef __powerpc64__ case 233: /* mulld */ - regs->gpr[rd] = regs->gpr[ra] * regs->gpr[rb]; + op->val = regs->gpr[ra] * regs->gpr[rb]; goto arith_done; #endif case 234: /* addme */ - add_with_carry(regs, rd, regs->gpr[ra], -1L, + add_with_carry(regs, op, rd, regs->gpr[ra], -1L, regs->xer & XER_CA); goto arith_done; case 235: /* mullw */ - regs->gpr[rd] = (unsigned int) regs->gpr[ra] * - (unsigned int) regs->gpr[rb]; + op->val = (long)(int) regs->gpr[ra] * + (int) regs->gpr[rb]; + goto arith_done; case 266: /* add */ - regs->gpr[rd] = regs->gpr[ra] + regs->gpr[rb]; + op->val = regs->gpr[ra] + regs->gpr[rb]; goto arith_done; #ifdef __powerpc64__ case 457: /* divdu */ - regs->gpr[rd] = regs->gpr[ra] / regs->gpr[rb]; + op->val = regs->gpr[ra] / regs->gpr[rb]; goto arith_done; #endif case 459: /* divwu */ - regs->gpr[rd] = (unsigned int) regs->gpr[ra] / + op->val = (unsigned int) regs->gpr[ra] / (unsigned int) regs->gpr[rb]; goto arith_done; #ifdef __powerpc64__ case 489: /* divd */ - regs->gpr[rd] = (long int) regs->gpr[ra] / + op->val = (long int) regs->gpr[ra] / (long int) regs->gpr[rb]; goto arith_done; #endif case 491: /* divw */ - regs->gpr[rd] = (int) regs->gpr[ra] / + op->val = (int) regs->gpr[ra] / (int) regs->gpr[rb]; goto arith_done; @@ -1172,57 +1684,81 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, * Logical instructions */ case 26: /* cntlzw */ - asm("cntlzw %0,%1" : "=r" (regs->gpr[ra]) : - "r" (regs->gpr[rd])); + val = (unsigned int) regs->gpr[rd]; + op->val = ( val ? __builtin_clz(val) : 32 ); goto logical_done; #ifdef __powerpc64__ case 58: /* cntlzd */ - asm("cntlzd %0,%1" : "=r" (regs->gpr[ra]) : - "r" (regs->gpr[rd])); + val = regs->gpr[rd]; + op->val = ( val ? __builtin_clzl(val) : 64 ); goto logical_done; #endif case 28: /* and */ - regs->gpr[ra] = regs->gpr[rd] & regs->gpr[rb]; + op->val = regs->gpr[rd] & regs->gpr[rb]; goto logical_done; case 60: /* andc */ - regs->gpr[ra] = regs->gpr[rd] & ~regs->gpr[rb]; + op->val = regs->gpr[rd] & ~regs->gpr[rb]; goto logical_done; + case 122: /* popcntb */ + do_popcnt(regs, op, regs->gpr[rd], 8); + goto logical_done_nocc; + case 124: /* nor */ - regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]); + op->val = ~(regs->gpr[rd] | regs->gpr[rb]); goto logical_done; + case 154: /* prtyw */ + do_prty(regs, op, regs->gpr[rd], 32); + goto logical_done_nocc; + + case 186: /* prtyd */ + do_prty(regs, op, regs->gpr[rd], 64); + goto logical_done_nocc; +#ifdef CONFIG_PPC64 + case 252: /* bpermd */ + do_bpermd(regs, op, regs->gpr[rd], regs->gpr[rb]); + goto logical_done_nocc; +#endif case 284: /* xor */ - regs->gpr[ra] = ~(regs->gpr[rd] ^ regs->gpr[rb]); + op->val = ~(regs->gpr[rd] ^ regs->gpr[rb]); goto logical_done; case 316: /* xor */ - regs->gpr[ra] = regs->gpr[rd] ^ regs->gpr[rb]; + op->val = regs->gpr[rd] ^ regs->gpr[rb]; goto logical_done; + case 378: /* popcntw */ + do_popcnt(regs, op, regs->gpr[rd], 32); + goto logical_done_nocc; + case 412: /* orc */ - regs->gpr[ra] = regs->gpr[rd] | ~regs->gpr[rb]; + op->val = regs->gpr[rd] | ~regs->gpr[rb]; goto logical_done; case 444: /* or */ - regs->gpr[ra] = regs->gpr[rd] | regs->gpr[rb]; + op->val = regs->gpr[rd] | regs->gpr[rb]; goto logical_done; case 476: /* nand */ - regs->gpr[ra] = ~(regs->gpr[rd] & regs->gpr[rb]); + op->val = ~(regs->gpr[rd] & regs->gpr[rb]); goto logical_done; - +#ifdef CONFIG_PPC64 + case 506: /* popcntd */ + do_popcnt(regs, op, regs->gpr[rd], 64); + goto logical_done_nocc; +#endif case 922: /* extsh */ - regs->gpr[ra] = (signed short) regs->gpr[rd]; + op->val = (signed short) regs->gpr[rd]; goto logical_done; case 954: /* extsb */ - regs->gpr[ra] = (signed char) regs->gpr[rd]; + op->val = (signed char) regs->gpr[rd]; goto logical_done; #ifdef __powerpc64__ case 986: /* extsw */ - regs->gpr[ra] = (signed int) regs->gpr[rd]; + op->val = (signed int) regs->gpr[rd]; goto logical_done; #endif @@ -1232,75 +1768,83 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 24: /* slw */ sh = regs->gpr[rb] & 0x3f; if (sh < 32) - regs->gpr[ra] = (regs->gpr[rd] << sh) & 0xffffffffUL; + op->val = (regs->gpr[rd] << sh) & 0xffffffffUL; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 536: /* srw */ sh = regs->gpr[rb] & 0x3f; if (sh < 32) - regs->gpr[ra] = (regs->gpr[rd] & 0xffffffffUL) >> sh; + op->val = (regs->gpr[rd] & 0xffffffffUL) >> sh; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 792: /* sraw */ + op->type = COMPUTE + SETREG + SETXER; sh = regs->gpr[rb] & 0x3f; ival = (signed int) regs->gpr[rd]; - regs->gpr[ra] = ival >> (sh < 32 ? sh : 31); + op->val = ival >> (sh < 32 ? sh : 31); + op->xerval = regs->xer; if (ival < 0 && (sh >= 32 || (ival & ((1ul << sh) - 1)) != 0)) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; case 824: /* srawi */ + op->type = COMPUTE + SETREG + SETXER; sh = rb; ival = (signed int) regs->gpr[rd]; - regs->gpr[ra] = ival >> sh; + op->val = ival >> sh; + op->xerval = regs->xer; if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; #ifdef __powerpc64__ case 27: /* sld */ sh = regs->gpr[rb] & 0x7f; if (sh < 64) - regs->gpr[ra] = regs->gpr[rd] << sh; + op->val = regs->gpr[rd] << sh; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 539: /* srd */ sh = regs->gpr[rb] & 0x7f; if (sh < 64) - regs->gpr[ra] = regs->gpr[rd] >> sh; + op->val = regs->gpr[rd] >> sh; else - regs->gpr[ra] = 0; + op->val = 0; goto logical_done; case 794: /* srad */ + op->type = COMPUTE + SETREG + SETXER; sh = regs->gpr[rb] & 0x7f; ival = (signed long int) regs->gpr[rd]; - regs->gpr[ra] = ival >> (sh < 64 ? sh : 63); + op->val = ival >> (sh < 64 ? sh : 63); + op->xerval = regs->xer; if (ival < 0 && (sh >= 64 || (ival & ((1ul << sh) - 1)) != 0)) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; case 826: /* sradi with sh_5 = 0 */ case 827: /* sradi with sh_5 = 1 */ + op->type = COMPUTE + SETREG + SETXER; sh = rb | ((instr & 2) << 4); ival = (signed long int) regs->gpr[rd]; - regs->gpr[ra] = ival >> sh; + op->val = ival >> sh; + op->xerval = regs->xer; if (ival < 0 && (ival & ((1ul << sh) - 1)) != 0) - regs->xer |= XER_CA; + op->xerval |= XER_CA; else - regs->xer &= ~XER_CA; + op->xerval &= ~XER_CA; goto logical_done; #endif /* __powerpc64__ */ @@ -1333,18 +1877,24 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->type = MKOP(CACHEOP, ICBI, 0); op->ea = xform_ea(instr, regs); return 0; + + case 1014: /* dcbz */ + op->type = MKOP(CACHEOP, DCBZ, 0); + op->ea = xform_ea(instr, regs); + return 0; } break; } - /* - * Loads and stores. - */ +/* + * Loads and stores. + */ op->type = UNKNOWN; op->update_reg = ra; op->reg = rd; op->val = regs->gpr[rd]; u = (instr >> 20) & UPDATE; + op->vsx_flags = 0; switch (opcode) { case 31: @@ -1368,9 +1918,30 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->type = MKOP(STCX, 0, 8); break; - case 21: /* ldx */ - case 53: /* ldux */ - op->type = MKOP(LOAD, u, 8); + case 52: /* lbarx */ + op->type = MKOP(LARX, 0, 1); + break; + + case 694: /* stbcx. */ + op->type = MKOP(STCX, 0, 1); + break; + + case 116: /* lharx */ + op->type = MKOP(LARX, 0, 2); + break; + + case 726: /* sthcx. */ + op->type = MKOP(STCX, 0, 2); + break; + + case 276: /* lqarx */ + if (!((rd & 1) || rd == ra || rd == rb)) + op->type = MKOP(LARX, 0, 16); + break; + + case 182: /* stqcx. */ + if (!(rd & 1)) + op->type = MKOP(STCX, 0, 16); break; #endif @@ -1385,22 +1956,58 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; #ifdef CONFIG_ALTIVEC + /* + * Note: for the load/store vector element instructions, + * bits of the EA say which field of the VMX register to use. + */ + case 7: /* lvebx */ + op->type = MKOP(LOAD_VMX, 0, 1); + op->element_size = 1; + break; + + case 39: /* lvehx */ + op->type = MKOP(LOAD_VMX, 0, 2); + op->element_size = 2; + break; + + case 71: /* lvewx */ + op->type = MKOP(LOAD_VMX, 0, 4); + op->element_size = 4; + break; + case 103: /* lvx */ case 359: /* lvxl */ - if (!(regs->msr & MSR_VEC)) - goto vecunavail; op->type = MKOP(LOAD_VMX, 0, 16); + op->element_size = 16; + break; + + case 135: /* stvebx */ + op->type = MKOP(STORE_VMX, 0, 1); + op->element_size = 1; + break; + + case 167: /* stvehx */ + op->type = MKOP(STORE_VMX, 0, 2); + op->element_size = 2; + break; + + case 199: /* stvewx */ + op->type = MKOP(STORE_VMX, 0, 4); + op->element_size = 4; break; case 231: /* stvx */ case 487: /* stvxl */ - if (!(regs->msr & MSR_VEC)) - goto vecunavail; op->type = MKOP(STORE_VMX, 0, 16); break; #endif /* CONFIG_ALTIVEC */ #ifdef __powerpc64__ + case 21: /* ldx */ + case 53: /* ldux */ + op->type = MKOP(LOAD, u, 8); + break; + case 149: /* stdx */ case 181: /* stdux */ op->type = MKOP(STORE, u, 8); @@ -1457,41 +2064,52 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, if (rb == 0) rb = 32; /* # bytes to load */ op->type = MKOP(LOAD_MULTI, 0, rb); - op->ea = 0; - if (ra) - op->ea = truncate_if_32bit(regs->msr, - regs->gpr[ra]); + op->ea = ra ? regs->gpr[ra] : 0; break; #ifdef CONFIG_PPC_FPU case 535: /* lfsx */ case 567: /* lfsux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(LOAD_FP, u, 4); + op->type = MKOP(LOAD_FP, u | FPCONV, 4); break; case 599: /* lfdx */ case 631: /* lfdux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(LOAD_FP, u, 8); break; case 663: /* stfsx */ case 695: /* stfsux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(STORE_FP, u, 4); + op->type = MKOP(STORE_FP, u | FPCONV, 4); break; case 727: /* stfdx */ case 759: /* stfdux */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(STORE_FP, u, 8); break; -#endif + +#ifdef __powerpc64__ + case 791: /* lfdpx */ + op->type = MKOP(LOAD_FP, 0, 16); + break; + + case 855: /* lfiwax */ + op->type = MKOP(LOAD_FP, SIGNEXT, 4); + break; + + case 887: /* lfiwzx */ + op->type = MKOP(LOAD_FP, 0, 4); + break; + + case 919: /* stfdpx */ + op->type = MKOP(STORE_FP, 0, 16); + break; + + case 983: /* stfiwx */ + op->type = MKOP(STORE_FP, 0, 4); + break; +#endif /* __powerpc64 */ +#endif /* CONFIG_PPC_FPU */ #ifdef __powerpc64__ case 660: /* stdbrx */ @@ -1509,14 +2127,11 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->val = byterev_4(regs->gpr[rd]); break; - case 725: + case 725: /* stswi */ if (rb == 0) rb = 32; /* # bytes to store */ op->type = MKOP(STORE_MULTI, 0, rb); - op->ea = 0; - if (ra) - op->ea = truncate_if_32bit(regs->msr, - regs->gpr[ra]); + op->ea = ra ? regs->gpr[ra] : 0; break; case 790: /* lhbrx */ @@ -1529,20 +2144,184 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; #ifdef CONFIG_VSX - case 844: /* lxvd2x */ - case 876: /* lxvd2ux */ - if (!(regs->msr & MSR_VSX)) - goto vsxunavail; + case 12: /* lxsiwzx */ op->reg = rd | ((instr & 1) << 5); - op->type = MKOP(LOAD_VSX, u, 16); + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 8; + break; + + case 76: /* lxsiwax */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, SIGNEXT, 4); + op->element_size = 8; + break; + + case 140: /* stxsiwx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 4); + op->element_size = 8; + break; + + case 268: /* lxvx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 269: /* lxvl */ + case 301: { /* lxvll */ + int nb; + op->reg = rd | ((instr & 1) << 5); + op->ea = ra ? regs->gpr[ra] : 0; + nb = regs->gpr[rb] & 0xff; + if (nb > 16) + nb = 16; + op->type = MKOP(LOAD_VSX, 0, nb); + op->element_size = 16; + op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | + VSX_CHECK_VEC; + break; + } + case 332: /* lxvdsx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 8); + op->element_size = 8; + op->vsx_flags = VSX_SPLAT; + break; + + case 364: /* lxvwsx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 4; + op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC; + break; + + case 396: /* stxvx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 397: /* stxvl */ + case 429: { /* stxvll */ + int nb; + op->reg = rd | ((instr & 1) << 5); + op->ea = ra ? regs->gpr[ra] : 0; + nb = regs->gpr[rb] & 0xff; + if (nb > 16) + nb = 16; + op->type = MKOP(STORE_VSX, 0, nb); + op->element_size = 16; + op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | + VSX_CHECK_VEC; + break; + } + case 524: /* lxsspx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV; + break; + + case 588: /* lxsdx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 8); + op->element_size = 8; + break; + + case 652: /* stxsspx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV; + break; + + case 716: /* stxsdx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 8); + op->element_size = 8; + break; + + case 780: /* lxvw4x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 4; + break; + + case 781: /* lxsibzx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 1); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 812: /* lxvh8x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 2; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 813: /* lxsihzx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 2); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 844: /* lxvd2x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 8; + break; + + case 876: /* lxvb16x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 1; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 908: /* stxvw4x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 4; + break; + + case 909: /* stxsibx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 1); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 940: /* stxvh8x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 2; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 941: /* stxsihx */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 2); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; break; case 972: /* stxvd2x */ - case 1004: /* stxvd2ux */ - if (!(regs->msr & MSR_VSX)) - goto vsxunavail; op->reg = rd | ((instr & 1) << 5); - op->type = MKOP(STORE_VSX, u, 16); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 8; + break; + + case 1004: /* stxvb16x */ + op->reg = rd | ((instr & 1) << 5); + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 1; + op->vsx_flags = VSX_CHECK_VEC; break; #endif /* CONFIG_VSX */ @@ -1606,37 +2385,62 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, #ifdef CONFIG_PPC_FPU case 48: /* lfs */ case 49: /* lfsu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(LOAD_FP, u, 4); + op->type = MKOP(LOAD_FP, u | FPCONV, 4); op->ea = dform_ea(instr, regs); break; case 50: /* lfd */ case 51: /* lfdu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(LOAD_FP, u, 8); op->ea = dform_ea(instr, regs); break; case 52: /* stfs */ case 53: /* stfsu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; - op->type = MKOP(STORE_FP, u, 4); + op->type = MKOP(STORE_FP, u | FPCONV, 4); op->ea = dform_ea(instr, regs); break; case 54: /* stfd */ case 55: /* stfdu */ - if (!(regs->msr & MSR_FP)) - goto fpunavail; op->type = MKOP(STORE_FP, u, 8); op->ea = dform_ea(instr, regs); break; #endif +#ifdef __powerpc64__ + case 56: /* lq */ + if (!((rd & 1) || (rd == ra))) + op->type = MKOP(LOAD, 0, 16); + op->ea = dqform_ea(instr, regs); + break; +#endif + +#ifdef CONFIG_VSX + case 57: /* lfdp, lxsd, lxssp */ + op->ea = dsform_ea(instr, regs); + switch (instr & 3) { + case 0: /* lfdp */ + if (rd & 1) + break; /* reg must be even */ + op->type = MKOP(LOAD_FP, 0, 16); + break; + case 2: /* lxsd */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, 0, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 3: /* lxssp */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + } + break; +#endif /* CONFIG_VSX */ + #ifdef __powerpc64__ case 58: /* ld[u], lwa */ op->ea = dsform_ea(instr, regs); @@ -1652,7 +2456,57 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, break; } break; +#endif +#ifdef CONFIG_VSX + case 61: /* stfdp, lxv, stxsd, stxssp, stxv */ + switch (instr & 7) { + case 0: /* stfdp with LSB of DS field = 0 */ + case 4: /* stfdp with LSB of DS field = 1 */ + op->ea = dsform_ea(instr, regs); + op->type = MKOP(STORE_FP, 0, 16); + break; + + case 1: /* lxv */ + op->ea = dqform_ea(instr, regs); + if (instr & 8) + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 2: /* stxsd with LSB of DS field = 0 */ + case 6: /* stxsd with LSB of DS field = 1 */ + op->ea = dsform_ea(instr, regs); + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, 0, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + + case 3: /* stxssp with LSB of DS field = 0 */ + case 7: /* stxssp with LSB of DS field = 1 */ + op->ea = dsform_ea(instr, regs); + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, 0, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + + case 5: /* stxv */ + op->ea = dqform_ea(instr, regs); + if (instr & 8) + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, 0, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + } + break; +#endif /* CONFIG_VSX */ + +#ifdef __powerpc64__ case 62: /* std[u] */ op->ea = dsform_ea(instr, regs); switch (instr & 3) { @@ -1662,6 +2516,10 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, case 1: /* stdu */ op->type = MKOP(STORE, UPDATE, 8); break; + case 2: /* stq */ + if (!(rd & 1)) + op->type = MKOP(STORE, 0, 16); + break; } break; #endif /* __powerpc64__ */ @@ -1671,15 +2529,18 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, logical_done: if (instr & 1) - set_cr0(regs, ra); - goto instr_done; + set_cr0(regs, op); + logical_done_nocc: + op->reg = ra; + op->type |= SETREG; + return 1; arith_done: if (instr & 1) - set_cr0(regs, rd); - - instr_done: - regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); + set_cr0(regs, op); + compute_done: + op->reg = rd; + op->type |= SETREG; return 1; priv: @@ -1691,24 +2552,6 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs, op->type = INTERRUPT | 0x700; op->val = SRR1_PROGTRAP; return 0; - -#ifdef CONFIG_PPC_FPU - fpunavail: - op->type = INTERRUPT | 0x800; - return 0; -#endif - -#ifdef CONFIG_ALTIVEC - vecunavail: - op->type = INTERRUPT | 0xf20; - return 0; -#endif - -#ifdef CONFIG_VSX - vsxunavail: - op->type = INTERRUPT | 0xf40; - return 0; -#endif } EXPORT_SYMBOL_GPL(analyse_instr); NOKPROBE_SYMBOL(analyse_instr); @@ -1770,6 +2613,351 @@ static nokprobe_inline void do_byterev(unsigned long *valp, int size) } } +/* + * Emulate an instruction that can be executed just by updating + * fields in *regs. + */ +void emulate_update_regs(struct pt_regs *regs, struct instruction_op *op) +{ + unsigned long next_pc; + + next_pc = truncate_if_32bit(regs->msr, regs->nip + 4); + switch (op->type & INSTR_TYPE_MASK) { + case COMPUTE: + if (op->type & SETREG) + regs->gpr[op->reg] = op->val; + if (op->type & SETCC) + regs->ccr = op->ccval; + if (op->type & SETXER) + regs->xer = op->xerval; + break; + + case BRANCH: + if (op->type & SETLK) + regs->link = next_pc; + if (op->type & BRTAKEN) + next_pc = op->val; + if (op->type & DECCTR) + --regs->ctr; + break; + + case BARRIER: + switch (op->type & BARRIER_MASK) { + case BARRIER_SYNC: + mb(); + break; + case BARRIER_ISYNC: + isync(); + break; + case BARRIER_EIEIO: + eieio(); + break; + case BARRIER_LWSYNC: + asm volatile("lwsync" : : : "memory"); + break; + case BARRIER_PTESYNC: + asm volatile("ptesync" : : : "memory"); + break; + } + break; + + case MFSPR: + switch (op->spr) { + case SPRN_XER: + regs->gpr[op->reg] = regs->xer & 0xffffffffUL; + break; + case SPRN_LR: + regs->gpr[op->reg] = regs->link; + break; + case SPRN_CTR: + regs->gpr[op->reg] = regs->ctr; + break; + default: + WARN_ON_ONCE(1); + } + break; + + case MTSPR: + switch (op->spr) { + case SPRN_XER: + regs->xer = op->val & 0xffffffffUL; + break; + case SPRN_LR: + regs->link = op->val; + break; + case SPRN_CTR: + regs->ctr = op->val; + break; + default: + WARN_ON_ONCE(1); + } + break; + + default: + WARN_ON_ONCE(1); + } + regs->nip = next_pc; +} + +/* + * Emulate a previously-analysed load or store instruction. + * Return values are: + * 0 = instruction emulated successfully + * -EFAULT = address out of range or access faulted (regs->dar + * contains the faulting address) + * -EACCES = misaligned access, instruction requires alignment + * -EINVAL = unknown operation in *op + */ +int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op) +{ + int err, size, type; + int i, rd, nb; + unsigned int cr; + unsigned long val; + unsigned long ea; + bool cross_endian; + + err = 0; + size = GETSIZE(op->type); + type = op->type & INSTR_TYPE_MASK; + cross_endian = (regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE); + ea = truncate_if_32bit(regs->msr, op->ea); + + switch (type) { + case LARX: + if (ea & (size - 1)) + return -EACCES; /* can't handle misaligned */ + if (!address_ok(regs, ea, size)) + return -EFAULT; + err = 0; + val = 0; + switch (size) { +#ifdef __powerpc64__ + case 1: + __get_user_asmx(val, ea, err, "lbarx"); + break; + case 2: + __get_user_asmx(val, ea, err, "lharx"); + break; +#endif + case 4: + __get_user_asmx(val, ea, err, "lwarx"); + break; +#ifdef __powerpc64__ + case 8: + __get_user_asmx(val, ea, err, "ldarx"); + break; + case 16: + err = do_lqarx(ea, ®s->gpr[op->reg]); + break; +#endif + default: + return -EINVAL; + } + if (err) { + regs->dar = ea; + break; + } + if (size < 16) + regs->gpr[op->reg] = val; + break; + + case STCX: + if (ea & (size - 1)) + return -EACCES; /* can't handle misaligned */ + if (!address_ok(regs, ea, size)) + return -EFAULT; + err = 0; + switch (size) { +#ifdef __powerpc64__ + case 1: + __put_user_asmx(op->val, ea, err, "stbcx.", cr); + break; + case 2: + __put_user_asmx(op->val, ea, err, "stbcx.", cr); + break; +#endif + case 4: + __put_user_asmx(op->val, ea, err, "stwcx.", cr); + break; +#ifdef __powerpc64__ + case 8: + __put_user_asmx(op->val, ea, err, "stdcx.", cr); + break; + case 16: + err = do_stqcx(ea, regs->gpr[op->reg], + regs->gpr[op->reg + 1], &cr); + break; +#endif + default: + return -EINVAL; + } + if (!err) + regs->ccr = (regs->ccr & 0x0fffffff) | + (cr & 0xe0000000) | + ((regs->xer >> 3) & 0x10000000); + else + regs->dar = ea; + break; + + case LOAD: +#ifdef __powerpc64__ + if (size == 16) { + err = emulate_lq(regs, ea, op->reg, cross_endian); + break; + } +#endif + err = read_mem(®s->gpr[op->reg], ea, size, regs); + if (!err) { + if (op->type & SIGNEXT) + do_signext(®s->gpr[op->reg], size); + if ((op->type & BYTEREV) == (cross_endian ? 0 : BYTEREV)) + do_byterev(®s->gpr[op->reg], size); + } + break; + +#ifdef CONFIG_PPC_FPU + case LOAD_FP: + /* + * If the instruction is in userspace, we can emulate it even + * if the VMX state is not live, because we have the state + * stored in the thread_struct. If the instruction is in + * the kernel, we must not touch the state in the thread_struct. + */ + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP)) + return 0; + err = do_fp_load(op, ea, regs, cross_endian); + break; +#endif +#ifdef CONFIG_ALTIVEC + case LOAD_VMX: + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC)) + return 0; + err = do_vec_load(op->reg, ea, size, regs, cross_endian); + break; +#endif +#ifdef CONFIG_VSX + case LOAD_VSX: { + unsigned long msrbit = MSR_VSX; + + /* + * Some VSX instructions check the MSR_VEC bit rather than MSR_VSX + * when the target of the instruction is a vector register. + */ + if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC)) + msrbit = MSR_VEC; + if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit)) + return 0; + err = do_vsx_load(op, ea, regs, cross_endian); + break; + } +#endif + case LOAD_MULTI: + if (!address_ok(regs, ea, size)) + return -EFAULT; + rd = op->reg; + for (i = 0; i < size; i += 4) { + unsigned int v32 = 0; + + nb = size - i; + if (nb > 4) + nb = 4; + err = copy_mem_in((u8 *) &v32, ea, nb, regs); + if (err) + break; + if (unlikely(cross_endian)) + v32 = byterev_4(v32); + regs->gpr[rd] = v32; + ea += 4; + /* reg number wraps from 31 to 0 for lsw[ix] */ + rd = (rd + 1) & 0x1f; + } + break; + + case STORE: +#ifdef __powerpc64__ + if (size == 16) { + err = emulate_stq(regs, ea, op->reg, cross_endian); + break; + } +#endif + if ((op->type & UPDATE) && size == sizeof(long) && + op->reg == 1 && op->update_reg == 1 && + !(regs->msr & MSR_PR) && + ea >= regs->gpr[1] - STACK_INT_FRAME_SIZE) { + err = handle_stack_update(ea, regs); + break; + } + if (unlikely(cross_endian)) + do_byterev(&op->val, size); + err = write_mem(op->val, ea, size, regs); + break; + +#ifdef CONFIG_PPC_FPU + case STORE_FP: + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_FP)) + return 0; + err = do_fp_store(op, ea, regs, cross_endian); + break; +#endif +#ifdef CONFIG_ALTIVEC + case STORE_VMX: + if (!(regs->msr & MSR_PR) && !(regs->msr & MSR_VEC)) + return 0; + err = do_vec_store(op->reg, ea, size, regs, cross_endian); + break; +#endif +#ifdef CONFIG_VSX + case STORE_VSX: { + unsigned long msrbit = MSR_VSX; + + /* + * Some VSX instructions check the MSR_VEC bit rather than MSR_VSX + * when the target of the instruction is a vector register. + */ + if (op->reg >= 32 && (op->vsx_flags & VSX_CHECK_VEC)) + msrbit = MSR_VEC; + if (!(regs->msr & MSR_PR) && !(regs->msr & msrbit)) + return 0; + err = do_vsx_store(op, ea, regs, cross_endian); + break; + } +#endif + case STORE_MULTI: + if (!address_ok(regs, ea, size)) + return -EFAULT; + rd = op->reg; + for (i = 0; i < size; i += 4) { + unsigned int v32 = regs->gpr[rd]; + + nb = size - i; + if (nb > 4) + nb = 4; + if (unlikely(cross_endian)) + v32 = byterev_4(v32); + err = copy_mem_out((u8 *) &v32, ea, nb, regs); + if (err) + break; + ea += 4; + /* reg number wraps from 31 to 0 for stsw[ix] */ + rd = (rd + 1) & 0x1f; + } + break; + + default: + return -EINVAL; + } + + if (err) + return err; + + if (op->type & UPDATE) + regs->gpr[op->update_reg] = op->ea; + + return 0; +} +NOKPROBE_SYMBOL(emulate_loadstore); + /* * Emulate instructions that cause a transfer of control, * loads and stores, and a few other instructions. @@ -1780,182 +2968,59 @@ static nokprobe_inline void do_byterev(unsigned long *valp, int size) int emulate_step(struct pt_regs *regs, unsigned int instr) { struct instruction_op op; - int r, err, size; + int r, err, type; unsigned long val; - unsigned int cr; - int i, rd, nb; + unsigned long ea; r = analyse_instr(&op, regs, instr); - if (r != 0) + if (r < 0) return r; + if (r > 0) { + emulate_update_regs(regs, &op); + return 1; + } err = 0; - size = GETSIZE(op.type); - switch (op.type & INSTR_TYPE_MASK) { - case CACHEOP: - if (!address_ok(regs, op.ea, 8)) - return 0; - switch (op.type & CACHEOP_MASK) { - case DCBST: - __cacheop_user_asmx(op.ea, err, "dcbst"); - break; - case DCBF: - __cacheop_user_asmx(op.ea, err, "dcbf"); - break; - case DCBTST: - if (op.reg == 0) - prefetchw((void *) op.ea); - break; - case DCBT: - if (op.reg == 0) - prefetch((void *) op.ea); - break; - case ICBI: - __cacheop_user_asmx(op.ea, err, "icbi"); - break; - } + type = op.type & INSTR_TYPE_MASK; + + if (OP_IS_LOAD_STORE(type)) { + err = emulate_loadstore(regs, &op); if (err) return 0; goto instr_done; + } - case LARX: - if (op.ea & (size - 1)) - break; /* can't handle misaligned */ - if (!address_ok(regs, op.ea, size)) + switch (type) { + case CACHEOP: + ea = truncate_if_32bit(regs->msr, op.ea); + if (!address_ok(regs, ea, 8)) return 0; - err = 0; - switch (size) { - case 4: - __get_user_asmx(val, op.ea, err, "lwarx"); + switch (op.type & CACHEOP_MASK) { + case DCBST: + __cacheop_user_asmx(ea, err, "dcbst"); break; -#ifdef __powerpc64__ - case 8: - __get_user_asmx(val, op.ea, err, "ldarx"); + case DCBF: + __cacheop_user_asmx(ea, err, "dcbf"); break; -#endif - default: - return 0; - } - if (!err) - regs->gpr[op.reg] = val; - goto ldst_done; - - case STCX: - if (op.ea & (size - 1)) - break; /* can't handle misaligned */ - if (!address_ok(regs, op.ea, size)) - return 0; - err = 0; - switch (size) { - case 4: - __put_user_asmx(op.val, op.ea, err, "stwcx.", cr); + case DCBTST: + if (op.reg == 0) + prefetchw((void *) ea); break; -#ifdef __powerpc64__ - case 8: - __put_user_asmx(op.val, op.ea, err, "stdcx.", cr); + case DCBT: + if (op.reg == 0) + prefetch((void *) ea); break; -#endif - default: + case ICBI: + __cacheop_user_asmx(ea, err, "icbi"); + break; + case DCBZ: + err = emulate_dcbz(ea, regs); + break; + } + if (err) { + regs->dar = ea; return 0; } - if (!err) - regs->ccr = (regs->ccr & 0x0fffffff) | - (cr & 0xe0000000) | - ((regs->xer >> 3) & 0x10000000); - goto ldst_done; - - case LOAD: - err = read_mem(®s->gpr[op.reg], op.ea, size, regs); - if (!err) { - if (op.type & SIGNEXT) - do_signext(®s->gpr[op.reg], size); - if (op.type & BYTEREV) - do_byterev(®s->gpr[op.reg], size); - } - goto ldst_done; - -#ifdef CONFIG_PPC_FPU - case LOAD_FP: - if (size == 4) - err = do_fp_load(op.reg, do_lfs, op.ea, size, regs); - else - err = do_fp_load(op.reg, do_lfd, op.ea, size, regs); - goto ldst_done; -#endif -#ifdef CONFIG_ALTIVEC - case LOAD_VMX: - err = do_vec_load(op.reg, do_lvx, op.ea & ~0xfUL, regs); - goto ldst_done; -#endif -#ifdef CONFIG_VSX - case LOAD_VSX: - err = do_vsx_load(op.reg, do_lxvd2x, op.ea, regs); - goto ldst_done; -#endif - case LOAD_MULTI: - if (regs->msr & MSR_LE) - return 0; - rd = op.reg; - for (i = 0; i < size; i += 4) { - nb = size - i; - if (nb > 4) - nb = 4; - err = read_mem(®s->gpr[rd], op.ea, nb, regs); - if (err) - return 0; - if (nb < 4) /* left-justify last bytes */ - regs->gpr[rd] <<= 32 - 8 * nb; - op.ea += 4; - ++rd; - } - goto instr_done; - - case STORE: - if ((op.type & UPDATE) && size == sizeof(long) && - op.reg == 1 && op.update_reg == 1 && - !(regs->msr & MSR_PR) && - op.ea >= regs->gpr[1] - STACK_INT_FRAME_SIZE) { - err = handle_stack_update(op.ea, regs); - goto ldst_done; - } - err = write_mem(op.val, op.ea, size, regs); - goto ldst_done; - -#ifdef CONFIG_PPC_FPU - case STORE_FP: - if (size == 4) - err = do_fp_store(op.reg, do_stfs, op.ea, size, regs); - else - err = do_fp_store(op.reg, do_stfd, op.ea, size, regs); - goto ldst_done; -#endif -#ifdef CONFIG_ALTIVEC - case STORE_VMX: - err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs); - goto ldst_done; -#endif -#ifdef CONFIG_VSX - case STORE_VSX: - err = do_vsx_store(op.reg, do_stxvd2x, op.ea, regs); - goto ldst_done; -#endif - case STORE_MULTI: - if (regs->msr & MSR_LE) - return 0; - rd = op.reg; - for (i = 0; i < size; i += 4) { - val = regs->gpr[rd]; - nb = size - i; - if (nb > 4) - nb = 4; - else - val >>= 32 - 8 * nb; - err = write_mem(val, op.ea, nb, regs); - if (err) - return 0; - op.ea += 4; - ++rd; - } goto instr_done; case MFMSR: @@ -1998,12 +3063,6 @@ int emulate_step(struct pt_regs *regs, unsigned int instr) } return 0; - ldst_done: - if (err) - return 0; - if (op.type & UPDATE) - regs->gpr[op.update_reg] = op.ea; - instr_done: regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4); return 1; diff --git a/arch/powerpc/lib/string_64.S b/arch/powerpc/lib/string_64.S index d5b4d9498c54..56aac4c22025 100644 --- a/arch/powerpc/lib/string_64.S +++ b/arch/powerpc/lib/string_64.S @@ -184,7 +184,7 @@ err1; std r0,8(r3) mtctr r6 mr r8,r3 14: -err1; dcbz r0,r3 +err1; dcbz 0,r3 add r3,r3,r9 bdnz 14b diff --git a/arch/powerpc/lib/xor_vmx.h b/arch/powerpc/lib/xor_vmx.h index 4746708451ae..5c2b0839b179 100644 --- a/arch/powerpc/lib/xor_vmx.h +++ b/arch/powerpc/lib/xor_vmx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Simple interface to link xor_vmx.c and xor_vmx_glue.c * diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile index 1b46ab4f6417..494df26c5988 100644 --- a/arch/powerpc/math-emu/Makefile +++ b/arch/powerpc/math-emu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 math-emu-common-objs = math.o fre.o fsqrt.o fsqrts.o frsqrtes.o mtfsf.o mtfsfi.o obj-$(CONFIG_MATH_EMULATION_HW_UNIMPLEMENTED) += $(math-emu-common-objs) obj-$(CONFIG_MATH_EMULATION_FULL) += $(math-emu-common-objs) fabs.o fadd.o \ diff --git a/arch/powerpc/math-emu/fabs.c b/arch/powerpc/math-emu/fabs.c index a5e7ad1384ee..3b62fd70b77e 100644 --- a/arch/powerpc/math-emu/fabs.c +++ b/arch/powerpc/math-emu/fabs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fadd.c b/arch/powerpc/math-emu/fadd.c index 29de37e0e0da..727e49ad55d1 100644 --- a/arch/powerpc/math-emu/fadd.c +++ b/arch/powerpc/math-emu/fadd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fadds.c b/arch/powerpc/math-emu/fadds.c index 7093c5b58002..45254be05662 100644 --- a/arch/powerpc/math-emu/fadds.c +++ b/arch/powerpc/math-emu/fadds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fcmpo.c b/arch/powerpc/math-emu/fcmpo.c index 5d644467221c..f437d0896c59 100644 --- a/arch/powerpc/math-emu/fcmpo.c +++ b/arch/powerpc/math-emu/fcmpo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fcmpu.c b/arch/powerpc/math-emu/fcmpu.c index 0f9bf4864832..65631fa5dc39 100644 --- a/arch/powerpc/math-emu/fcmpu.c +++ b/arch/powerpc/math-emu/fcmpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fctiw.c b/arch/powerpc/math-emu/fctiw.c index 716d6da7f204..ebb0f11e735e 100644 --- a/arch/powerpc/math-emu/fctiw.c +++ b/arch/powerpc/math-emu/fctiw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fctiwz.c b/arch/powerpc/math-emu/fctiwz.c index 7212fa7cfd36..426271c4f004 100644 --- a/arch/powerpc/math-emu/fctiwz.c +++ b/arch/powerpc/math-emu/fctiwz.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fdiv.c b/arch/powerpc/math-emu/fdiv.c index e1e452069e49..6e64ece2d395 100644 --- a/arch/powerpc/math-emu/fdiv.c +++ b/arch/powerpc/math-emu/fdiv.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fdivs.c b/arch/powerpc/math-emu/fdivs.c index 5511e2d1c3ad..f9f7adf46262 100644 --- a/arch/powerpc/math-emu/fdivs.c +++ b/arch/powerpc/math-emu/fdivs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fmadd.c b/arch/powerpc/math-emu/fmadd.c index 2b6fae0bc8c2..e8458aed5edb 100644 --- a/arch/powerpc/math-emu/fmadd.c +++ b/arch/powerpc/math-emu/fmadd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fmadds.c b/arch/powerpc/math-emu/fmadds.c index aff35f24a236..a6d3f9842f19 100644 --- a/arch/powerpc/math-emu/fmadds.c +++ b/arch/powerpc/math-emu/fmadds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fmr.c b/arch/powerpc/math-emu/fmr.c index f6347911f6a3..48c64374286e 100644 --- a/arch/powerpc/math-emu/fmr.c +++ b/arch/powerpc/math-emu/fmr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fmsub.c b/arch/powerpc/math-emu/fmsub.c index 1fb26cebe04e..605cda49e7b2 100644 --- a/arch/powerpc/math-emu/fmsub.c +++ b/arch/powerpc/math-emu/fmsub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fmsubs.c b/arch/powerpc/math-emu/fmsubs.c index f73965453e05..f26ec0acf0a5 100644 --- a/arch/powerpc/math-emu/fmsubs.c +++ b/arch/powerpc/math-emu/fmsubs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fmul.c b/arch/powerpc/math-emu/fmul.c index ffd31b549290..d114f7acdbb1 100644 --- a/arch/powerpc/math-emu/fmul.c +++ b/arch/powerpc/math-emu/fmul.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fmuls.c b/arch/powerpc/math-emu/fmuls.c index 21aee431ca9d..aaeba0acb47f 100644 --- a/arch/powerpc/math-emu/fmuls.c +++ b/arch/powerpc/math-emu/fmuls.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fnabs.c b/arch/powerpc/math-emu/fnabs.c index af877a53d264..6c439e6c2c58 100644 --- a/arch/powerpc/math-emu/fnabs.c +++ b/arch/powerpc/math-emu/fnabs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fneg.c b/arch/powerpc/math-emu/fneg.c index 8417d174758c..791e724f712f 100644 --- a/arch/powerpc/math-emu/fneg.c +++ b/arch/powerpc/math-emu/fneg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fnmadd.c b/arch/powerpc/math-emu/fnmadd.c index 6316ef0e0874..02a7099b26af 100644 --- a/arch/powerpc/math-emu/fnmadd.c +++ b/arch/powerpc/math-emu/fnmadd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fnmadds.c b/arch/powerpc/math-emu/fnmadds.c index 9ffe037df2b9..ce42a7a44d2e 100644 --- a/arch/powerpc/math-emu/fnmadds.c +++ b/arch/powerpc/math-emu/fnmadds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fnmsub.c b/arch/powerpc/math-emu/fnmsub.c index f97a9cfb54ea..eade699c51d5 100644 --- a/arch/powerpc/math-emu/fnmsub.c +++ b/arch/powerpc/math-emu/fnmsub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fnmsubs.c b/arch/powerpc/math-emu/fnmsubs.c index 7fa1217bd930..4e1f6c2b7c40 100644 --- a/arch/powerpc/math-emu/fnmsubs.c +++ b/arch/powerpc/math-emu/fnmsubs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fre.c b/arch/powerpc/math-emu/fre.c index b621a790aa67..584b16f53304 100644 --- a/arch/powerpc/math-emu/fre.c +++ b/arch/powerpc/math-emu/fre.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fres.c b/arch/powerpc/math-emu/fres.c index 211c30d0145f..f7d5654ce7d6 100644 --- a/arch/powerpc/math-emu/fres.c +++ b/arch/powerpc/math-emu/fres.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/frsp.c b/arch/powerpc/math-emu/frsp.c index 3e3bc73e27ae..cb33e3d9bbb2 100644 --- a/arch/powerpc/math-emu/frsp.c +++ b/arch/powerpc/math-emu/frsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/frsqrte.c b/arch/powerpc/math-emu/frsqrte.c index 7c2ce43750dc..72955b27c3ca 100644 --- a/arch/powerpc/math-emu/frsqrte.c +++ b/arch/powerpc/math-emu/frsqrte.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/frsqrtes.c b/arch/powerpc/math-emu/frsqrtes.c index 269951a8c650..a036f7b7140c 100644 --- a/arch/powerpc/math-emu/frsqrtes.c +++ b/arch/powerpc/math-emu/frsqrtes.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fsel.c b/arch/powerpc/math-emu/fsel.c index 32b62c6c7f48..b0d15e15a5d3 100644 --- a/arch/powerpc/math-emu/fsel.c +++ b/arch/powerpc/math-emu/fsel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fsqrt.c b/arch/powerpc/math-emu/fsqrt.c index 0e2a34b616dc..05438590388e 100644 --- a/arch/powerpc/math-emu/fsqrt.c +++ b/arch/powerpc/math-emu/fsqrt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fsqrts.c b/arch/powerpc/math-emu/fsqrts.c index 420cf19b5fd4..1624f97c69cc 100644 --- a/arch/powerpc/math-emu/fsqrts.c +++ b/arch/powerpc/math-emu/fsqrts.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fsub.c b/arch/powerpc/math-emu/fsub.c index feedd705cf62..47a8f847b422 100644 --- a/arch/powerpc/math-emu/fsub.c +++ b/arch/powerpc/math-emu/fsub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/fsubs.c b/arch/powerpc/math-emu/fsubs.c index 74190514063e..fa1b3b18c379 100644 --- a/arch/powerpc/math-emu/fsubs.c +++ b/arch/powerpc/math-emu/fsubs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/lfd.c b/arch/powerpc/math-emu/lfd.c index d998a50740a0..3a6b03d999ab 100644 --- a/arch/powerpc/math-emu/lfd.c +++ b/arch/powerpc/math-emu/lfd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/lfs.c b/arch/powerpc/math-emu/lfs.c index 1ee10b83d7e3..7fd3d0854cd8 100644 --- a/arch/powerpc/math-emu/lfs.c +++ b/arch/powerpc/math-emu/lfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/math.c b/arch/powerpc/math-emu/math.c index 76ee2e5dba65..30b4b69c6941 100644 --- a/arch/powerpc/math-emu/math.c +++ b/arch/powerpc/math-emu/math.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com) */ diff --git a/arch/powerpc/math-emu/mcrfs.c b/arch/powerpc/math-emu/mcrfs.c index 8e8e72397ebc..9c4fdaace475 100644 --- a/arch/powerpc/math-emu/mcrfs.c +++ b/arch/powerpc/math-emu/mcrfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/mffs.c b/arch/powerpc/math-emu/mffs.c index e00fdc22a0bc..d42f1278e958 100644 --- a/arch/powerpc/math-emu/mffs.c +++ b/arch/powerpc/math-emu/mffs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/mtfsb0.c b/arch/powerpc/math-emu/mtfsb0.c index 5ed3e7d5063e..5753170b5dfd 100644 --- a/arch/powerpc/math-emu/mtfsb0.c +++ b/arch/powerpc/math-emu/mtfsb0.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/mtfsb1.c b/arch/powerpc/math-emu/mtfsb1.c index 602aa16eda81..8162c3bfd149 100644 --- a/arch/powerpc/math-emu/mtfsb1.c +++ b/arch/powerpc/math-emu/mtfsb1.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/mtfsf.c b/arch/powerpc/math-emu/mtfsf.c index b0d5593ad357..7ae990f6b58b 100644 --- a/arch/powerpc/math-emu/mtfsf.c +++ b/arch/powerpc/math-emu/mtfsf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/mtfsfi.c b/arch/powerpc/math-emu/mtfsfi.c index 5df30541a784..45f1edbda357 100644 --- a/arch/powerpc/math-emu/mtfsfi.c +++ b/arch/powerpc/math-emu/mtfsfi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/stfd.c b/arch/powerpc/math-emu/stfd.c index 6baeaec134a2..463d2f0832d9 100644 --- a/arch/powerpc/math-emu/stfd.c +++ b/arch/powerpc/math-emu/stfd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/stfiwx.c b/arch/powerpc/math-emu/stfiwx.c index 9da7c5d1a872..24ae9622fed6 100644 --- a/arch/powerpc/math-emu/stfiwx.c +++ b/arch/powerpc/math-emu/stfiwx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/stfs.c b/arch/powerpc/math-emu/stfs.c index 62bd25264fb5..ddf9bbdb5b55 100644 --- a/arch/powerpc/math-emu/stfs.c +++ b/arch/powerpc/math-emu/stfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/math-emu/udivmodti4.c b/arch/powerpc/math-emu/udivmodti4.c index 6172044ab003..1e52633dcbb7 100644 --- a/arch/powerpc/math-emu/udivmodti4.c +++ b/arch/powerpc/math-emu/udivmodti4.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */ #include diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c index f4c6472f2fc4..f29212e40f40 100644 --- a/arch/powerpc/mm/8xx_mmu.c +++ b/arch/powerpc/mm/8xx_mmu.c @@ -22,8 +22,11 @@ extern int __map_without_ltlbs; +static unsigned long block_mapped_ram; + /* - * Return PA for this VA if it is in IMMR area, or 0 + * Return PA for this VA if it is in an area mapped with LTLBs. + * Otherwise, returns 0 */ phys_addr_t v_block_mapped(unsigned long va) { @@ -33,11 +36,13 @@ phys_addr_t v_block_mapped(unsigned long va) return 0; if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE) return p + va - VIRT_IMMR_BASE; + if (va >= PAGE_OFFSET && va < PAGE_OFFSET + block_mapped_ram) + return __pa(va); return 0; } /* - * Return VA for a given PA or 0 if not mapped + * Return VA for a given PA mapped with LTLBs or 0 if not mapped */ unsigned long p_block_mapped(phys_addr_t pa) { @@ -47,6 +52,8 @@ unsigned long p_block_mapped(phys_addr_t pa) return 0; if (pa >= p && pa < p + IMMR_SIZE) return VIRT_IMMR_BASE + pa - p; + if (pa < block_mapped_ram) + return (unsigned long)__va(pa); return 0; } @@ -58,7 +65,7 @@ unsigned long p_block_mapped(phys_addr_t pa) void __init MMU_init_hw(void) { /* PIN up to the 3 first 8Mb after IMMR in DTLB table */ -#ifdef CONFIG_PIN_TLB +#ifdef CONFIG_PIN_TLB_DATA unsigned long ctr = mfspr(SPRN_MD_CTR) & 0xfe000000; unsigned long flags = 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY; #ifdef CONFIG_PIN_TLB_IMMR @@ -80,7 +87,7 @@ void __init MMU_init_hw(void) #endif } -static void mmu_mapin_immr(void) +static void __init mmu_mapin_immr(void) { unsigned long p = PHYS_IMMR_BASE; unsigned long v = VIRT_IMMR_BASE; @@ -96,8 +103,11 @@ static void mmu_mapin_immr(void) extern unsigned int DTLBMiss_jmp; #endif extern unsigned int DTLBMiss_cmp, FixupDAR_cmp; +#ifndef CONFIG_PIN_TLB_TEXT +extern unsigned int ITLBMiss_cmp; +#endif -void mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped) +static void __init mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped) { unsigned int instr = *addr; @@ -115,6 +125,9 @@ unsigned long __init mmu_mapin_ram(unsigned long top) mmu_mapin_immr(); #ifndef CONFIG_PIN_TLB_IMMR patch_instruction(&DTLBMiss_jmp, PPC_INST_NOP); +#endif +#ifndef CONFIG_PIN_TLB_TEXT + mmu_patch_cmp_limit(&ITLBMiss_cmp, 0); #endif } else { mapped = top & ~(LARGE_PAGE_SIZE_8M - 1); @@ -133,11 +146,13 @@ unsigned long __init mmu_mapin_ram(unsigned long top) if (mapped) memblock_set_current_limit(mapped); + block_mapped_ram = mapped; + return mapped; } -void setup_initial_memory_limit(phys_addr_t first_memblock_base, - phys_addr_t first_memblock_size) +void __init setup_initial_memory_limit(phys_addr_t first_memblock_base, + phys_addr_t first_memblock_size) { /* We don't currently support the first MEMBLOCK not mapping 0 * physical on those processors diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 7414034df1c3..a0c327d544d1 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux ppc-specific parts of the memory manager. # @@ -8,7 +9,7 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) obj-y := fault.o mem.o pgtable.o mmap.o \ init_$(BITS).o pgtable_$(BITS).o \ - init-common.o + init-common.o mmu_context.o obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \ tlb_nohash_low.o obj-$(CONFIG_PPC_BOOK3E) += tlb_low_$(BITS)e.o @@ -22,8 +23,6 @@ ifeq ($(CONFIG_PPC_STD_MMU_64),y) obj-$(CONFIG_PPC_4K_PAGES) += hash64_4k.o obj-$(CONFIG_PPC_64K_PAGES) += hash64_64k.o endif -obj-$(CONFIG_PPC_ICSWX) += icswx.o -obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o obj-$(CONFIG_40x) += 40x_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_PPC_8xx) += 8xx_mmu.o diff --git a/arch/powerpc/mm/dump_hashpagetable.c b/arch/powerpc/mm/dump_hashpagetable.c index b1c144b03fcf..5c4c93dcff19 100644 --- a/arch/powerpc/mm/dump_hashpagetable.c +++ b/arch/powerpc/mm/dump_hashpagetable.c @@ -205,7 +205,7 @@ static void dump_hpte_info(struct pg_state *st, unsigned long ea, u64 v, u64 r, aps_index = calculate_pagesize(st, aps, "actual"); if (aps_index != 2) seq_printf(st->seq, "LP enc: %lx", lp); - seq_puts(st->seq, "\n"); + seq_putc(st->seq, '\n'); } diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c index 44fe4833910f..c9282d27b203 100644 --- a/arch/powerpc/mm/dump_linuxpagetables.c +++ b/arch/powerpc/mm/dump_linuxpagetables.c @@ -350,7 +350,7 @@ static void note_page(struct pg_state *st, unsigned long addr, st->current_flags, pg_level[st->level].num); - seq_puts(st->seq, "\n"); + seq_putc(st->seq, '\n'); } /* diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 4c422632047b..4797d08581ce 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -45,43 +45,39 @@ #include #include -#include "icswx.h" +static inline bool notify_page_fault(struct pt_regs *regs) +{ + bool ret = false; #ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs) -{ - int ret = 0; - /* kprobe_running() needs smp_processor_id() */ if (!user_mode(regs)) { preempt_disable(); if (kprobe_running() && kprobe_fault_handler(regs, 11)) - ret = 1; + ret = true; preempt_enable(); } +#endif /* CONFIG_KPROBES */ + + if (unlikely(debugger_fault_handler(regs))) + ret = true; return ret; } -#else -static inline int notify_page_fault(struct pt_regs *regs) -{ - return 0; -} -#endif /* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1. */ -static int store_updates_sp(struct pt_regs *regs) +static bool store_updates_sp(struct pt_regs *regs) { unsigned int inst; if (get_user(inst, (unsigned int __user *)regs->nip)) - return 0; + return false; /* check for 1 in the rA field */ if (((inst >> 16) & 0x1f) != 1) - return 0; + return false; /* check major opcode */ switch (inst >> 26) { case 37: /* stwu */ @@ -89,7 +85,7 @@ static int store_updates_sp(struct pt_regs *regs) case 45: /* sthu */ case 53: /* stfsu */ case 55: /* stfdu */ - return 1; + return true; case 62: /* std or stdu */ return (inst & 3) == 1; case 31: @@ -101,18 +97,53 @@ static int store_updates_sp(struct pt_regs *regs) case 439: /* sthux */ case 695: /* stfsux */ case 759: /* stfdux */ - return 1; + return true; } } - return 0; + return false; } /* * do_page_fault error handling helpers */ -#define MM_FAULT_RETURN 0 -#define MM_FAULT_CONTINUE -1 -#define MM_FAULT_ERR(sig) (sig) +static int +__bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code) +{ + /* + * If we are in kernel mode, bail out with a SEGV, this will + * be caught by the assembly which will restore the non-volatile + * registers before calling bad_page_fault() + */ + if (!user_mode(regs)) + return SIGSEGV; + + _exception(SIGSEGV, regs, si_code, address); + + return 0; +} + +static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long address) +{ + return __bad_area_nosemaphore(regs, address, SEGV_MAPERR); +} + +static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code) +{ + struct mm_struct *mm = current->mm; + + /* + * Something tried to access memory that isn't in our memory map.. + * Fix it, but check if it's kernel or user first.. + */ + up_read(&mm->mmap_sem); + + return __bad_area_nosemaphore(regs, address, si_code); +} + +static noinline int bad_area(struct pt_regs *regs, unsigned long address) +{ + return __bad_area(regs, address, SEGV_MAPERR); +} static int do_sigbus(struct pt_regs *regs, unsigned long address, unsigned int fault) @@ -121,7 +152,7 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address, unsigned int lsb = 0; if (!user_mode(regs)) - return MM_FAULT_ERR(SIGBUS); + return SIGBUS; current->thread.trap_nr = BUS_ADRERR; info.si_signo = SIGBUS; @@ -142,25 +173,17 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address, #endif info.si_addr_lsb = lsb; force_sig_info(SIGBUS, &info, current); - return MM_FAULT_RETURN; + return 0; } static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault) { /* - * Pagefault was interrupted by SIGKILL. We have no reason to - * continue the pagefault. + * Kernel page fault interrupted by SIGKILL. We have no reason to + * continue processing. */ - if (fatal_signal_pending(current)) { - /* Coming from kernel, we need to deal with uaccess fixups */ - if (user_mode(regs)) - return MM_FAULT_RETURN; - return MM_FAULT_ERR(SIGKILL); - } - - /* No fault: be happy */ - if (!(fault & VM_FAULT_ERROR)) - return MM_FAULT_CONTINUE; + if (fatal_signal_pending(current) && !user_mode(regs)) + return SIGKILL; /* Out of memory */ if (fault & VM_FAULT_OOM) { @@ -169,169 +192,38 @@ static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault) * made us unable to handle the page fault gracefully. */ if (!user_mode(regs)) - return MM_FAULT_ERR(SIGKILL); + return SIGSEGV; pagefault_out_of_memory(); - return MM_FAULT_RETURN; + } else { + if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| + VM_FAULT_HWPOISON_LARGE)) + return do_sigbus(regs, addr, fault); + else if (fault & VM_FAULT_SIGSEGV) + return bad_area_nosemaphore(regs, addr); + else + BUG(); } - - if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) - return do_sigbus(regs, addr, fault); - - /* We don't understand the fault code, this is fatal */ - BUG(); - return MM_FAULT_CONTINUE; + return 0; } -/* - * For 600- and 800-family processors, the error_code parameter is DSISR - * for a data fault, SRR1 for an instruction fault. For 400-family processors - * the error_code parameter is ESR for a data fault, 0 for an instruction - * fault. - * For 64-bit processors, the error_code parameter is - * - DSISR for a non-SLB data access fault, - * - SRR1 & 0x08000000 for a non-SLB instruction access fault - * - 0 any SLB fault. - * - * The return value is 0 if the fault was handled, or the signal - * number if this is a kernel fault that can't be handled here. - */ -int do_page_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) +/* Is this a bad kernel fault ? */ +static bool bad_kernel_fault(bool is_exec, unsigned long error_code, + unsigned long address) { - enum ctx_state prev_state = exception_enter(); - struct vm_area_struct * vma; - struct mm_struct *mm = current->mm; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; - int code = SEGV_MAPERR; - int is_write = 0; - int trap = TRAP(regs); - int is_exec = trap == 0x400; - int is_user = user_mode(regs); - int fault; - int rc = 0, store_update_sp = 0; - -#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) - /* - * Fortunately the bit assignments in SRR1 for an instruction - * fault and DSISR for a data fault are mostly the same for the - * bits we are interested in. But there are some bits which - * indicate errors in DSISR but can validly be set in SRR1. - */ - if (is_exec) - error_code &= 0x48200000; - else - is_write = error_code & DSISR_ISSTORE; -#else - is_write = error_code & ESR_DST; -#endif /* CONFIG_4xx || CONFIG_BOOKE */ - -#ifdef CONFIG_PPC_ICSWX - /* - * we need to do this early because this "data storage - * interrupt" does not update the DAR/DEAR so we don't want to - * look at it - */ - if (error_code & ICSWX_DSI_UCT) { - rc = acop_handle_fault(regs, address, error_code); - if (rc) - goto bail; + if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT))) { + printk_ratelimited(KERN_CRIT "kernel tried to execute" + " exec-protected page (%lx) -" + "exploit attempt? (uid: %d)\n", + address, from_kuid(&init_user_ns, + current_uid())); } -#endif /* CONFIG_PPC_ICSWX */ - - if (notify_page_fault(regs)) - goto bail; - - if (unlikely(debugger_fault_handler(regs))) - goto bail; - - /* - * The kernel should never take an execute fault nor should it - * take a page fault to a kernel address. - */ - if (!is_user && (is_exec || (address >= TASK_SIZE))) { - rc = SIGSEGV; - goto bail; - } - -#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \ - defined(CONFIG_PPC_BOOK3S_64) || defined(CONFIG_PPC_8xx)) - if (error_code & DSISR_DABRMATCH) { - /* breakpoint match */ - do_break(regs, address, error_code); - goto bail; - } -#endif - - /* We restore the interrupt state now */ - if (!arch_irq_disabled_regs(regs)) - local_irq_enable(); - - if (faulthandler_disabled() || mm == NULL) { - if (!is_user) { - rc = SIGSEGV; - goto bail; - } - /* faulthandler_disabled() in user mode is really bad, - as is current->mm == NULL. */ - printk(KERN_EMERG "Page fault in user mode with " - "faulthandler_disabled() = %d mm = %p\n", - faulthandler_disabled(), mm); - printk(KERN_EMERG "NIP = %lx MSR = %lx\n", - regs->nip, regs->msr); - die("Weird page fault", regs, SIGSEGV); - } - - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); - - /* - * We want to do this outside mmap_sem, because reading code around nip - * can result in fault, which will cause a deadlock when called with - * mmap_sem held - */ - if (is_write && is_user) - store_update_sp = store_updates_sp(regs); - - if (is_user) - flags |= FAULT_FLAG_USER; - - /* When running in the kernel we expect faults to occur only to - * addresses in user space. All other faults represent errors in the - * kernel and should generate an OOPS. Unfortunately, in the case of an - * erroneous fault occurring in a code path which already holds mmap_sem - * we will deadlock attempting to validate the fault against the - * address space. Luckily the kernel only validly references user - * space from well defined areas of code, which are listed in the - * exceptions table. - * - * As the vast majority of faults will be valid we will only perform - * the source reference check when there is a possibility of a deadlock. - * Attempt to lock the address space, if we cannot we then validate the - * source. If this is invalid we can skip the address space check, - * thus avoiding the deadlock. - */ - if (!down_read_trylock(&mm->mmap_sem)) { - if (!is_user && !search_exception_tables(regs->nip)) - goto bad_area_nosemaphore; - -retry: - down_read(&mm->mmap_sem); - } else { - /* - * The above down_read_trylock() might have succeeded in - * which case we'll have missed the might_sleep() from - * down_read(): - */ - might_sleep(); - } - - vma = find_vma(mm, address); - if (!vma) - goto bad_area; - if (vma->vm_start <= address) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; + return is_exec || (address >= TASK_SIZE); +} +static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address, + struct vm_area_struct *vma, + bool store_update_sp) +{ /* * N.B. The POWER/Open ABI allows programs to access up to * 288 bytes below the stack pointer. @@ -345,7 +237,7 @@ retry: /* get user regs even if this fault is in kernel mode */ struct pt_regs *uregs = current->thread.regs; if (uregs == NULL) - goto bad_area; + return true; /* * A user-mode access to an address a long way below @@ -360,55 +252,62 @@ retry: * expand the stack rather than segfaulting. */ if (address + 2048 < uregs->gpr[1] && !store_update_sp) - goto bad_area; + return true; } - if (expand_stack(vma, address)) - goto bad_area; - -good_area: - code = SEGV_ACCERR; -#if defined(CONFIG_6xx) - if (error_code & 0x95700000) - /* an error such as lwarx to I/O controller space, - address matching DABR, eciwx, etc. */ - goto bad_area; -#endif /* CONFIG_6xx */ -#if defined(CONFIG_8xx) - /* The MPC8xx seems to always set 0x80000000, which is - * "undefined". Of those that can be set, this is the only - * one which seems bad. - */ - if (error_code & 0x10000000) - /* Guarded storage error. */ - goto bad_area; -#endif /* CONFIG_8xx */ + return false; +} +static bool access_error(bool is_write, bool is_exec, + struct vm_area_struct *vma) +{ + /* + * Allow execution from readable areas if the MMU does not + * provide separate controls over reading and executing. + * + * Note: That code used to not be enabled for 4xx/BookE. + * It is now as I/D cache coherency for these is done at + * set_pte_at() time and I see no reason why the test + * below wouldn't be valid on those processors. This -may- + * break programs compiled with a really old ABI though. + */ if (is_exec) { - /* - * Allow execution from readable areas if the MMU does not - * provide separate controls over reading and executing. - * - * Note: That code used to not be enabled for 4xx/BookE. - * It is now as I/D cache coherency for these is done at - * set_pte_at() time and I see no reason why the test - * below wouldn't be valid on those processors. This -may- - * break programs compiled with a really old ABI though. - */ - if (!(vma->vm_flags & VM_EXEC) && - (cpu_has_feature(CPU_FTR_NOEXECUTE) || - !(vma->vm_flags & (VM_READ | VM_WRITE)))) - goto bad_area; - /* a write */ - } else if (is_write) { - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - flags |= FAULT_FLAG_WRITE; - /* a read */ - } else { - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) - goto bad_area; + return !(vma->vm_flags & VM_EXEC) && + (cpu_has_feature(CPU_FTR_NOEXECUTE) || + !(vma->vm_flags & (VM_READ | VM_WRITE))); } + + if (is_write) { + if (unlikely(!(vma->vm_flags & VM_WRITE))) + return true; + return false; + } + + if (unlikely(!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))) + return true; + + return false; +} + +#ifdef CONFIG_PPC_SMLPAR +static inline void cmo_account_page_fault(void) +{ + if (firmware_has_feature(FW_FEATURE_CMO)) { + u32 page_ins; + + preempt_disable(); + page_ins = be32_to_cpu(get_lppaca()->page_ins); + page_ins += 1 << PAGE_FACTOR; + get_lppaca()->page_ins = cpu_to_be32(page_ins); + preempt_enable(); + } +} +#else +static inline void cmo_account_page_fault(void) { } +#endif /* CONFIG_PPC_SMLPAR */ + #ifdef CONFIG_PPC_STD_MMU +static void sanity_check_fault(bool is_write, unsigned long error_code) +{ /* * For hash translation mode, we should never get a * PROTFAULT. Any update to pte to reduce access will result in us @@ -440,14 +339,166 @@ good_area: */ if (!radix_enabled() && !is_write) WARN_ON_ONCE(error_code & DSISR_PROTFAULT); +} +#else +static void sanity_check_fault(bool is_write, unsigned long error_code) { } #endif /* CONFIG_PPC_STD_MMU */ +/* + * Define the correct "is_write" bit in error_code based + * on the processor family + */ +#if (defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) +#define page_fault_is_write(__err) ((__err) & ESR_DST) +#define page_fault_is_bad(__err) (0) +#else +#define page_fault_is_write(__err) ((__err) & DSISR_ISSTORE) +#if defined(CONFIG_PPC_8xx) +#define page_fault_is_bad(__err) ((__err) & DSISR_NOEXEC_OR_G) +#elif defined(CONFIG_PPC64) +#define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_64S) +#else +#define page_fault_is_bad(__err) ((__err) & DSISR_BAD_FAULT_32S) +#endif +#endif + +/* + * For 600- and 800-family processors, the error_code parameter is DSISR + * for a data fault, SRR1 for an instruction fault. For 400-family processors + * the error_code parameter is ESR for a data fault, 0 for an instruction + * fault. + * For 64-bit processors, the error_code parameter is + * - DSISR for a non-SLB data access fault, + * - SRR1 & 0x08000000 for a non-SLB instruction access fault + * - 0 any SLB fault. + * + * The return value is 0 if the fault was handled, or the signal + * number if this is a kernel fault that can't be handled here. + */ +static int __do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ + struct vm_area_struct * vma; + struct mm_struct *mm = current->mm; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; + int is_exec = TRAP(regs) == 0x400; + int is_user = user_mode(regs); + int is_write = page_fault_is_write(error_code); + int fault, major = 0; + bool store_update_sp = false; + + if (notify_page_fault(regs)) + return 0; + + if (unlikely(page_fault_is_bad(error_code))) { + if (is_user) { + _exception(SIGBUS, regs, BUS_OBJERR, address); + return 0; + } + return SIGBUS; + } + + /* Additional sanity check(s) */ + sanity_check_fault(is_write, error_code); + + /* + * The kernel should never take an execute fault nor should it + * take a page fault to a kernel address. + */ + if (unlikely(!is_user && bad_kernel_fault(is_exec, error_code, address))) + return SIGSEGV; + + /* + * If we're in an interrupt, have no user context or are running + * in a region with pagefaults disabled then we must not take the fault + */ + if (unlikely(faulthandler_disabled() || !mm)) { + if (is_user) + printk_ratelimited(KERN_ERR "Page fault in user mode" + " with faulthandler_disabled()=%d" + " mm=%p\n", + faulthandler_disabled(), mm); + return bad_area_nosemaphore(regs, address); + } + + /* We restore the interrupt state now */ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); + + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); + + /* + * We want to do this outside mmap_sem, because reading code around nip + * can result in fault, which will cause a deadlock when called with + * mmap_sem held + */ + if (is_write && is_user) + store_update_sp = store_updates_sp(regs); + + if (is_user) + flags |= FAULT_FLAG_USER; + if (is_write) + flags |= FAULT_FLAG_WRITE; + if (is_exec) + flags |= FAULT_FLAG_INSTRUCTION; + + /* When running in the kernel we expect faults to occur only to + * addresses in user space. All other faults represent errors in the + * kernel and should generate an OOPS. Unfortunately, in the case of an + * erroneous fault occurring in a code path which already holds mmap_sem + * we will deadlock attempting to validate the fault against the + * address space. Luckily the kernel only validly references user + * space from well defined areas of code, which are listed in the + * exceptions table. + * + * As the vast majority of faults will be valid we will only perform + * the source reference check when there is a possibility of a deadlock. + * Attempt to lock the address space, if we cannot we then validate the + * source. If this is invalid we can skip the address space check, + * thus avoiding the deadlock. + */ + if (unlikely(!down_read_trylock(&mm->mmap_sem))) { + if (!is_user && !search_exception_tables(regs->nip)) + return bad_area_nosemaphore(regs, address); + +retry: + down_read(&mm->mmap_sem); + } else { + /* + * The above down_read_trylock() might have succeeded in + * which case we'll have missed the might_sleep() from + * down_read(): + */ + might_sleep(); + } + + vma = find_vma(mm, address); + if (unlikely(!vma)) + return bad_area(regs, address); + if (likely(vma->vm_start <= address)) + goto good_area; + if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) + return bad_area(regs, address); + + /* The stack is being expanded, check if it's valid */ + if (unlikely(bad_stack_expansion(regs, address, vma, store_update_sp))) + return bad_area(regs, address); + + /* Try to expand it */ + if (unlikely(expand_stack(vma, address))) + return bad_area(regs, address); + +good_area: + if (unlikely(access_error(is_write, is_exec, vma))) + return bad_area(regs, address); + /* * If for any reason at all we couldn't handle the fault, * make sure we exit gracefully rather than endlessly redo * the fault. */ fault = handle_mm_fault(vma, address, flags); + major |= fault & VM_FAULT_MAJOR; /* * Handle the retry right now, the mmap_sem has been released in that @@ -465,64 +516,39 @@ good_area: if (!fatal_signal_pending(current)) goto retry; } - /* We will enter mm_fault_error() below */ - } else - up_read(¤t->mm->mmap_sem); - if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) { - if (fault & VM_FAULT_SIGSEGV) - goto bad_area_nosemaphore; - rc = mm_fault_error(regs, address, fault); - if (rc >= MM_FAULT_RETURN) - goto bail; - else - rc = 0; + /* + * User mode? Just return to handle the fatal exception otherwise + * return to bad_page_fault + */ + return is_user ? 0 : SIGBUS; } + up_read(¤t->mm->mmap_sem); + + if (unlikely(fault & VM_FAULT_ERROR)) + return mm_fault_error(regs, address, fault); + /* * Major/minor page fault accounting. */ - if (fault & VM_FAULT_MAJOR) { + if (major) { current->maj_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, - regs, address); -#ifdef CONFIG_PPC_SMLPAR - if (firmware_has_feature(FW_FEATURE_CMO)) { - u32 page_ins; - - preempt_disable(); - page_ins = be32_to_cpu(get_lppaca()->page_ins); - page_ins += 1 << PAGE_FACTOR; - get_lppaca()->page_ins = cpu_to_be32(page_ins); - preempt_enable(); - } -#endif /* CONFIG_PPC_SMLPAR */ + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); + cmo_account_page_fault(); } else { current->min_flt++; - perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, - regs, address); + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); } + return 0; +} +NOKPROBE_SYMBOL(__do_page_fault); - goto bail; - -bad_area: - up_read(&mm->mmap_sem); - -bad_area_nosemaphore: - /* User mode accesses cause a SIGSEGV */ - if (is_user) { - _exception(SIGSEGV, regs, code, address); - goto bail; - } - - if (is_exec && (error_code & DSISR_PROTFAULT)) - printk_ratelimited(KERN_CRIT "kernel tried to execute NX-protected" - " page (%lx) - exploit attempt? (uid: %d)\n", - address, from_kuid(&init_user_ns, current_uid())); - - rc = SIGSEGV; - -bail: +int do_page_fault(struct pt_regs *regs, unsigned long address, + unsigned long error_code) +{ + enum ctx_state prev_state = exception_enter(); + int rc = __do_page_fault(regs, address, error_code); exception_exit(prev_state); return rc; } diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S index 6f962e5cb5e1..ffbd7c0bda96 100644 --- a/arch/powerpc/mm/hash_low_32.S +++ b/arch/powerpc/mm/hash_low_32.S @@ -575,7 +575,6 @@ _GLOBAL(flush_hash_pages) rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */ stwcx. r8,0,r5 /* update the pte */ bne- 33b -EXPORT_SYMBOL(flush_hash_pages) /* Get the address of the primary PTE group in the hash table (r3) */ _GLOBAL(flush_hash_patch_A) @@ -634,6 +633,7 @@ _GLOBAL(flush_hash_patch_B) SYNC_601 isync blr +EXPORT_SYMBOL(flush_hash_pages) /* * Flush an entry from the TLB diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 7a20669c19e7..67ec2e927253 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -61,6 +61,7 @@ #include #include #include +#include #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -507,9 +508,9 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, printk(KERN_INFO "Huge page(16GB) memory: " "addr = 0x%lX size = 0x%lX pages = %d\n", phys_addr, block_size, expected_pages); - if (phys_addr + (16 * GB) <= memblock_end_of_DRAM()) { + if (phys_addr + block_size * expected_pages <= memblock_end_of_DRAM()) { memblock_reserve(phys_addr, block_size * expected_pages); - add_gpage(phys_addr, block_size, expected_pages); + pseries_add_gpage(phys_addr, block_size, expected_pages); } return 0; } @@ -1019,6 +1020,7 @@ void __init hash__early_init_mmu(void) __kernel_virt_size = H_KERN_VIRT_SIZE; __vmalloc_start = H_VMALLOC_START; __vmalloc_end = H_VMALLOC_END; + __kernel_io_start = H_KERN_IO_START; vmemmap = (struct page *)H_VMEMMAP_BASE; ioremap_bot = IOREMAP_BASE; @@ -1228,7 +1230,6 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, unsigned long vsid; pte_t *ptep; unsigned hugeshift; - const struct cpumask *tmp; int rc, user_region = 0; int psize, ssize; @@ -1280,8 +1281,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, } /* Check CPU locality */ - tmp = cpumask_of(smp_processor_id()); - if (user_region && cpumask_equal(mm_cpumask(mm), tmp)) + if (user_region && mm_is_thread_local(mm)) flags |= HPTE_LOCAL_UPDATE; #ifndef CONFIG_PPC_64K_PAGES @@ -1297,7 +1297,7 @@ int hash_page_mm(struct mm_struct *mm, unsigned long ea, #endif /* CONFIG_PPC_64K_PAGES */ /* Get PTE and page size from page tables */ - ptep = __find_linux_pte_or_hugepte(pgdir, ea, &is_thp, &hugeshift); + ptep = find_linux_pte(pgdir, ea, &is_thp, &hugeshift); if (ptep == NULL || !pte_present(*ptep)) { DBG_LOW(" no PTE !\n"); rc = 1; @@ -1526,7 +1526,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, * THP pages use update_mmu_cache_pmd. We don't do * hash preload there. Hence can ignore THP here */ - ptep = find_linux_pte_or_hugepte(pgdir, ea, NULL, &hugepage_shift); + ptep = find_current_mm_pte(pgdir, ea, NULL, &hugepage_shift); if (!ptep) goto out_exit; @@ -1543,7 +1543,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, #endif /* CONFIG_PPC_64K_PAGES */ /* Is that local to this CPU ? */ - if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) + if (mm_is_thread_local(mm)) update_flags |= HPTE_LOCAL_UPDATE; /* Hash it in */ diff --git a/arch/powerpc/mm/highmem.c b/arch/powerpc/mm/highmem.c index e292c8a60952..668e87d03f9e 100644 --- a/arch/powerpc/mm/highmem.c +++ b/arch/powerpc/mm/highmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * highmem.c: virtual kernel memory mappings for high memory * diff --git a/arch/powerpc/mm/hugetlbpage-book3e.c b/arch/powerpc/mm/hugetlbpage-book3e.c index bfe4e8526b2d..f84ec46cdb26 100644 --- a/arch/powerpc/mm/hugetlbpage-book3e.c +++ b/arch/powerpc/mm/hugetlbpage-book3e.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PPC Huge TLB Page Support for Book3E MMU * diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index a84bb44497f9..0c2a91df3210 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PPC64 Huge TLB Page Support for hash based MMUs (POWER4 and later) * diff --git a/arch/powerpc/mm/hugetlbpage-radix.c b/arch/powerpc/mm/hugetlbpage-radix.c index a12e86395025..558e9d3891bf 100644 --- a/arch/powerpc/mm/hugetlbpage-radix.c +++ b/arch/powerpc/mm/hugetlbpage-radix.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index e1bf5ca397fe..1571a498a33f 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -24,6 +24,8 @@ #include #include #include +#include + #ifdef CONFIG_HUGETLB_PAGE @@ -36,32 +38,15 @@ unsigned int HPAGE_SHIFT; EXPORT_SYMBOL(HPAGE_SHIFT); -/* - * Tracks gpages after the device tree is scanned and before the - * huge_boot_pages list is ready. On non-Freescale implementations, this is - * just used to track 16G pages and so is a single array. FSL-based - * implementations may have more than one gpage size, so we need multiple - * arrays - */ -#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx) -#define MAX_NUMBER_GPAGES 128 -struct psize_gpages { - u64 gpage_list[MAX_NUMBER_GPAGES]; - unsigned int nr_gpages; -}; -static struct psize_gpages gpage_freearray[MMU_PAGE_COUNT]; -#else -#define MAX_NUMBER_GPAGES 1024 -static u64 gpage_freearray[MAX_NUMBER_GPAGES]; -static unsigned nr_gpages; -#endif - #define hugepd_none(hpd) (hpd_val(hpd) == 0) pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr, unsigned long sz) { - /* Only called for hugetlbfs pages, hence can ignore THP */ - return __find_linux_pte_or_hugepte(mm->pgd, addr, NULL, NULL); + /* + * Only called for hugetlbfs pages, hence can ignore THP and the + * irq disabled walk. + */ + return __find_linux_pte(mm->pgd, addr, NULL, NULL); } static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, @@ -210,145 +195,20 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz return hugepte_offset(*hpdp, addr, pdshift); } -#if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx) -/* Build list of addresses of gigantic pages. This function is used in early +#ifdef CONFIG_PPC_BOOK3S_64 +/* + * Tracks gpages after the device tree is scanned and before the + * huge_boot_pages list is ready on pseries. + */ +#define MAX_NUMBER_GPAGES 1024 +__initdata static u64 gpage_freearray[MAX_NUMBER_GPAGES]; +__initdata static unsigned nr_gpages; + +/* + * Build list of addresses of gigantic pages. This function is used in early * boot before the buddy allocator is setup. */ -void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) -{ - unsigned int idx = shift_to_mmu_psize(__ffs(page_size)); - int i; - - if (addr == 0) - return; - - gpage_freearray[idx].nr_gpages = number_of_pages; - - for (i = 0; i < number_of_pages; i++) { - gpage_freearray[idx].gpage_list[i] = addr; - addr += page_size; - } -} - -/* - * Moves the gigantic page addresses from the temporary list to the - * huge_boot_pages list. - */ -int alloc_bootmem_huge_page(struct hstate *hstate) -{ - struct huge_bootmem_page *m; - int idx = shift_to_mmu_psize(huge_page_shift(hstate)); - int nr_gpages = gpage_freearray[idx].nr_gpages; - - if (nr_gpages == 0) - return 0; - -#ifdef CONFIG_HIGHMEM - /* - * If gpages can be in highmem we can't use the trick of storing the - * data structure in the page; allocate space for this - */ - m = memblock_virt_alloc(sizeof(struct huge_bootmem_page), 0); - m->phys = gpage_freearray[idx].gpage_list[--nr_gpages]; -#else - m = phys_to_virt(gpage_freearray[idx].gpage_list[--nr_gpages]); -#endif - - list_add(&m->list, &huge_boot_pages); - gpage_freearray[idx].nr_gpages = nr_gpages; - gpage_freearray[idx].gpage_list[nr_gpages] = 0; - m->hstate = hstate; - - return 1; -} -/* - * Scan the command line hugepagesz= options for gigantic pages; store those in - * a list that we use to allocate the memory once all options are parsed. - */ - -unsigned long gpage_npages[MMU_PAGE_COUNT]; - -static int __init do_gpage_early_setup(char *param, char *val, - const char *unused, void *arg) -{ - static phys_addr_t size; - unsigned long npages; - - /* - * The hugepagesz and hugepages cmdline options are interleaved. We - * use the size variable to keep track of whether or not this was done - * properly and skip over instances where it is incorrect. Other - * command-line parsing code will issue warnings, so we don't need to. - * - */ - if ((strcmp(param, "default_hugepagesz") == 0) || - (strcmp(param, "hugepagesz") == 0)) { - size = memparse(val, NULL); - } else if (strcmp(param, "hugepages") == 0) { - if (size != 0) { - if (sscanf(val, "%lu", &npages) <= 0) - npages = 0; - if (npages > MAX_NUMBER_GPAGES) { - pr_warn("MMU: %lu pages requested for page " -#ifdef CONFIG_PHYS_ADDR_T_64BIT - "size %llu KB, limiting to " -#else - "size %u KB, limiting to " -#endif - __stringify(MAX_NUMBER_GPAGES) "\n", - npages, size / 1024); - npages = MAX_NUMBER_GPAGES; - } - gpage_npages[shift_to_mmu_psize(__ffs(size))] = npages; - size = 0; - } - } - return 0; -} - - -/* - * This function allocates physical space for pages that are larger than the - * buddy allocator can handle. We want to allocate these in highmem because - * the amount of lowmem is limited. This means that this function MUST be - * called before lowmem_end_addr is set up in MMU_init() in order for the lmb - * allocate to grab highmem. - */ -void __init reserve_hugetlb_gpages(void) -{ - static __initdata char cmdline[COMMAND_LINE_SIZE]; - phys_addr_t size, base; - int i; - - strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); - parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0, - NULL, &do_gpage_early_setup); - - /* - * Walk gpage list in reverse, allocating larger page sizes first. - * Skip over unsupported sizes, or sizes that have 0 gpages allocated. - * When we reach the point in the list where pages are no longer - * considered gpages, we're done. - */ - for (i = MMU_PAGE_COUNT-1; i >= 0; i--) { - if (mmu_psize_defs[i].shift == 0 || gpage_npages[i] == 0) - continue; - else if (mmu_psize_to_shift(i) < (MAX_ORDER + PAGE_SHIFT)) - break; - - size = (phys_addr_t)(1ULL << mmu_psize_to_shift(i)); - base = memblock_alloc_base(size * gpage_npages[i], size, - MEMBLOCK_ALLOC_ANYWHERE); - add_gpage(base, size, gpage_npages[i]); - } -} - -#else /* !PPC_FSL_BOOK3E */ - -/* Build list of addresses of gigantic pages. This function is used in early - * boot before the buddy allocator is setup. - */ -void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) +void __init pseries_add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) { if (!addr) return; @@ -360,10 +220,7 @@ void add_gpage(u64 addr, u64 page_size, unsigned long number_of_pages) } } -/* Moves the gigantic page addresses from the temporary list to the - * huge_boot_pages list. - */ -int alloc_bootmem_huge_page(struct hstate *hstate) +int __init pseries_alloc_bootmem_huge_page(struct hstate *hstate) { struct huge_bootmem_page *m; if (nr_gpages == 0) @@ -376,6 +233,17 @@ int alloc_bootmem_huge_page(struct hstate *hstate) } #endif + +int __init alloc_bootmem_huge_page(struct hstate *h) +{ + +#ifdef CONFIG_PPC_BOOK3S_64 + if (firmware_has_feature(FW_FEATURE_LPAR) && !radix_enabled()) + return pseries_alloc_bootmem_huge_page(h); +#endif + return __alloc_bootmem_huge_page(h); +} + #if defined(CONFIG_PPC_FSL_BOOK3E) || defined(CONFIG_PPC_8xx) #define HUGEPD_FREELIST_SIZE \ ((PAGE_SIZE - sizeof(struct hugepd_freelist)) / sizeof(pte_t)) @@ -407,8 +275,7 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte) batchp = &get_cpu_var(hugepd_freelist_cur); if (atomic_read(&tlb->mm->mm_users) < 2 || - cpumask_equal(mm_cpumask(tlb->mm), - cpumask_of(smp_processor_id()))) { + mm_is_thread_local(tlb->mm)) { kmem_cache_free(hugepte_cache, hugepte); put_cpu_var(hugepd_freelist_cur); return; @@ -886,9 +753,8 @@ void flush_dcache_icache_hugepage(struct page *page) * This function need to be called with interrupts disabled. We use this variant * when we have MSR[EE] = 0 but the paca->soft_enabled = 1 */ - -pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, - bool *is_thp, unsigned *shift) +pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, + bool *is_thp, unsigned *hpage_shift) { pgd_t pgd, *pgdp; pud_t pud, *pudp; @@ -897,8 +763,8 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, hugepd_t *hpdp = NULL; unsigned pdshift = PGDIR_SHIFT; - if (shift) - *shift = 0; + if (hpage_shift) + *hpage_shift = 0; if (is_thp) *is_thp = false; @@ -968,16 +834,15 @@ pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea, ret_pte = hugepte_offset(*hpdp, ea, pdshift); pdshift = hugepd_shift(*hpdp); out: - if (shift) - *shift = pdshift; + if (hpage_shift) + *hpage_shift = pdshift; return ret_pte; } -EXPORT_SYMBOL_GPL(__find_linux_pte_or_hugepte); +EXPORT_SYMBOL_GPL(__find_linux_pte); int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { - unsigned long mask; unsigned long pte_end; struct page *head, *page; pte_t pte; @@ -988,18 +853,10 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr, end = pte_end; pte = READ_ONCE(*ptep); - mask = _PAGE_PRESENT | _PAGE_READ; - /* - * On some CPUs like the 8xx, _PAGE_RW hence _PAGE_WRITE is defined - * as 0 and _PAGE_RO has to be set when a page is not writable - */ - if (write) - mask |= _PAGE_WRITE; - else - mask |= _PAGE_RO; - - if ((pte_val(pte) & mask) != mask) + if (!pte_present(pte) || !pte_read(pte)) + return 0; + if (write && !pte_write(pte)) return 0; /* hugepages are never "special" */ diff --git a/arch/powerpc/mm/icswx.c b/arch/powerpc/mm/icswx.c deleted file mode 100644 index 1fa794d7d59f..000000000000 --- a/arch/powerpc/mm/icswx.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * ICSWX and ACOP Management - * - * Copyright (C) 2011 Anton Blanchard, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "icswx.h" - -/* - * The processor and its L2 cache cause the icswx instruction to - * generate a COP_REQ transaction on PowerBus. The transaction has no - * address, and the processor does not perform an MMU access to - * authenticate the transaction. The command portion of the PowerBus - * COP_REQ transaction includes the LPAR_ID (LPID) and the coprocessor - * Process ID (PID), which the coprocessor compares to the authorized - * LPID and PID held in the coprocessor, to determine if the process - * is authorized to generate the transaction. The data of the COP_REQ - * transaction is 128-byte or less in size and is placed in cacheable - * memory on a 128-byte cache line boundary. - * - * The task to use a coprocessor should use use_cop() to mark the use - * of the Coprocessor Type (CT) and context switching. On a server - * class processor, the PID register is used only for coprocessor - * management + * and so a coprocessor PID is allocated before - * executing icswx + * instruction. Drop_cop() is used to free the - * coprocessor PID. - * - * Example: - * Host Fabric Interface (HFI) is a PowerPC network coprocessor. - * Each HFI have multiple windows. Each HFI window serves as a - * network device sending to and receiving from HFI network. - * HFI immediate send function uses icswx instruction. The immediate - * send function allows small (single cache-line) packets be sent - * without using the regular HFI send FIFO and doorbell, which are - * much slower than immediate send. - * - * For each task intending to use HFI immediate send, the HFI driver - * calls use_cop() to obtain a coprocessor PID for the task. - * The HFI driver then allocate a free HFI window and save the - * coprocessor PID to the HFI window to allow the task to use the - * HFI window. - * - * The HFI driver repeatedly creates immediate send packets and - * issues icswx instruction to send data through the HFI window. - * The HFI compares the coprocessor PID in the CPU PID register - * to the PID held in the HFI window to determine if the transaction - * is allowed. - * - * When the task to release the HFI window, the HFI driver calls - * drop_cop() to release the coprocessor PID. - */ - -void switch_cop(struct mm_struct *next) -{ -#ifdef CONFIG_PPC_ICSWX_PID - mtspr(SPRN_PID, next->context.cop_pid); -#endif - mtspr(SPRN_ACOP, next->context.acop); -} - -/** - * Start using a coprocessor. - * @acop: mask of coprocessor to be used. - * @mm: The mm the coprocessor to associate with. Most likely current mm. - * - * Return a positive PID if successful. Negative errno otherwise. - * The returned PID will be fed to the coprocessor to determine if an - * icswx transaction is authenticated. - */ -int use_cop(unsigned long acop, struct mm_struct *mm) -{ - int ret; - - if (!cpu_has_feature(CPU_FTR_ICSWX)) - return -ENODEV; - - if (!mm || !acop) - return -EINVAL; - - /* The page_table_lock ensures mm_users won't change under us */ - spin_lock(&mm->page_table_lock); - spin_lock(mm->context.cop_lockp); - - ret = get_cop_pid(mm); - if (ret < 0) - goto out; - - /* update acop */ - mm->context.acop |= acop; - - sync_cop(mm); - - /* - * If this is a threaded process then there might be other threads - * running. We need to send an IPI to force them to pick up any - * change in PID and ACOP. - */ - if (atomic_read(&mm->mm_users) > 1) - smp_call_function(sync_cop, mm, 1); - -out: - spin_unlock(mm->context.cop_lockp); - spin_unlock(&mm->page_table_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(use_cop); - -/** - * Stop using a coprocessor. - * @acop: mask of coprocessor to be stopped. - * @mm: The mm the coprocessor associated with. - */ -void drop_cop(unsigned long acop, struct mm_struct *mm) -{ - int free_pid; - - if (!cpu_has_feature(CPU_FTR_ICSWX)) - return; - - if (WARN_ON_ONCE(!mm)) - return; - - /* The page_table_lock ensures mm_users won't change under us */ - spin_lock(&mm->page_table_lock); - spin_lock(mm->context.cop_lockp); - - mm->context.acop &= ~acop; - - free_pid = disable_cop_pid(mm); - sync_cop(mm); - - /* - * If this is a threaded process then there might be other threads - * running. We need to send an IPI to force them to pick up any - * change in PID and ACOP. - */ - if (atomic_read(&mm->mm_users) > 1) - smp_call_function(sync_cop, mm, 1); - - if (free_pid != COP_PID_NONE) - free_cop_pid(free_pid); - - spin_unlock(mm->context.cop_lockp); - spin_unlock(&mm->page_table_lock); -} -EXPORT_SYMBOL_GPL(drop_cop); - -static int acop_use_cop(int ct) -{ - /* There is no alternate policy, yet */ - return -1; -} - -/* - * Get the instruction word at the NIP - */ -static u32 acop_get_inst(struct pt_regs *regs) -{ - u32 inst; - u32 __user *p; - - p = (u32 __user *)regs->nip; - if (!access_ok(VERIFY_READ, p, sizeof(*p))) - return 0; - - if (__get_user(inst, p)) - return 0; - - return inst; -} - -/** - * @regs: registers at time of interrupt - * @address: storage address - * @error_code: Fault code, usually the DSISR or ESR depending on - * processor type - * - * Return 0 if we are able to resolve the data storage fault that - * results from a CT miss in the ACOP register. - */ -int acop_handle_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code) -{ - int ct; - u32 inst = 0; - - if (!cpu_has_feature(CPU_FTR_ICSWX)) { - pr_info("No coprocessors available"); - _exception(SIGILL, regs, ILL_ILLOPN, address); - } - - if (!user_mode(regs)) { - /* this could happen if the HV denies the - * kernel access, for now we just die */ - die("ICSWX from kernel failed", regs, SIGSEGV); - } - - /* Some implementations leave us a hint for the CT */ - ct = ICSWX_GET_CT_HINT(error_code); - if (ct < 0) { - /* we have to peek at the instruction word to figure out CT */ - u32 ccw; - u32 rs; - - inst = acop_get_inst(regs); - if (inst == 0) - return -1; - - rs = (inst >> (31 - 10)) & 0x1f; - ccw = regs->gpr[rs]; - ct = (ccw >> 16) & 0x3f; - } - - /* - * We could be here because another thread has enabled acop - * but the ACOP register has yet to be updated. - * - * This should have been taken care of by the IPI to sync all - * the threads (see smp_call_function(sync_cop, mm, 1)), but - * that could take forever if there are a significant amount - * of threads. - * - * Given the number of threads on some of these systems, - * perhaps this is the best way to sync ACOP rather than whack - * every thread with an IPI. - */ - if ((acop_copro_type_bit(ct) & current->active_mm->context.acop) != 0) { - sync_cop(current->active_mm); - return 0; - } - - /* check for alternate policy */ - if (!acop_use_cop(ct)) - return 0; - - /* at this point the CT is unknown to the system */ - pr_warn("%s[%d]: Coprocessor %d is unavailable\n", - current->comm, current->pid, ct); - - /* get inst if we don't already have it */ - if (inst == 0) { - inst = acop_get_inst(regs); - if (inst == 0) - return -1; - } - - /* Check if the instruction is the "record form" */ - if (inst & 1) { - /* - * the instruction is "record" form so we can reject - * using CR0 - */ - regs->ccr &= ~(0xful << 28); - regs->ccr |= ICSWX_RC_NOT_FOUND << 28; - - /* Move on to the next instruction */ - regs->nip += 4; - } else { - /* - * There is no architected mechanism to report a bad - * CT so we could either SIGILL or report nothing. - * Since the non-record version should only bu used - * for "hints" or "don't care" we should probably do - * nothing. However, I could see how some people - * might want an SIGILL so it here if you want it. - */ -#ifdef CONFIG_PPC_ICSWX_USE_SIGILL - _exception(SIGILL, regs, ILL_ILLOPN, address); -#else - regs->nip += 4; -#endif - } - - return 0; -} -EXPORT_SYMBOL_GPL(acop_handle_fault); diff --git a/arch/powerpc/mm/icswx.h b/arch/powerpc/mm/icswx.h deleted file mode 100644 index 6dedc08e62c8..000000000000 --- a/arch/powerpc/mm/icswx.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _ARCH_POWERPC_MM_ICSWX_H_ -#define _ARCH_POWERPC_MM_ICSWX_H_ - -/* - * ICSWX and ACOP Management - * - * Copyright (C) 2011 Anton Blanchard, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include - -/* also used to denote that PIDs are not used */ -#define COP_PID_NONE 0 - -static inline void sync_cop(void *arg) -{ - struct mm_struct *mm = arg; - - if (mm == current->active_mm) - switch_cop(current->active_mm); -} - -#ifdef CONFIG_PPC_ICSWX_PID -extern int get_cop_pid(struct mm_struct *mm); -extern int disable_cop_pid(struct mm_struct *mm); -extern void free_cop_pid(int free_pid); -#else -#define get_cop_pid(m) (COP_PID_NONE) -#define disable_cop_pid(m) (COP_PID_NONE) -#define free_cop_pid(p) -#endif - -/* - * These are implementation bits for architected registers. If this - * ever becomes architecture the should be moved to reg.h et. al. - */ -/* UCT is the same bit for Server and Embedded */ -#define ICSWX_DSI_UCT 0x00004000 /* Unavailable Coprocessor Type */ - -#ifdef CONFIG_PPC_BOOK3E -/* Embedded implementation gives us no hints as to what the CT is */ -#define ICSWX_GET_CT_HINT(x) (-1) -#else -/* Server implementation contains the CT value in the DSISR */ -#define ICSWX_DSISR_CTMASK 0x00003f00 -#define ICSWX_GET_CT_HINT(x) (((x) & ICSWX_DSISR_CTMASK) >> 8) -#endif - -#define ICSWX_RC_STARTED 0x8 /* The request has been started */ -#define ICSWX_RC_NOT_IDLE 0x4 /* No coprocessor found idle */ -#define ICSWX_RC_NOT_FOUND 0x2 /* No coprocessor found */ -#define ICSWX_RC_UNDEFINED 0x1 /* Reserved */ - -extern int acop_handle_fault(struct pt_regs *regs, unsigned long address, - unsigned long error_code); - -static inline u64 acop_copro_type_bit(unsigned int type) -{ - return 1ULL << (63 - type); -} - -#endif /* !_ARCH_POWERPC_MM_ICSWX_H_ */ diff --git a/arch/powerpc/mm/icswx_pid.c b/arch/powerpc/mm/icswx_pid.c deleted file mode 100644 index 91e30eb7d054..000000000000 --- a/arch/powerpc/mm/icswx_pid.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * ICSWX and ACOP/PID Management - * - * Copyright (C) 2011 Anton Blanchard, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "icswx.h" - -#define COP_PID_MIN (COP_PID_NONE + 1) -#define COP_PID_MAX (0xFFFF) - -static DEFINE_SPINLOCK(mmu_context_acop_lock); -static DEFINE_IDA(cop_ida); - -static int new_cop_pid(struct ida *ida, int min_id, int max_id, - spinlock_t *lock) -{ - int index; - int err; - -again: - if (!ida_pre_get(ida, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(lock); - err = ida_get_new_above(ida, min_id, &index); - spin_unlock(lock); - - if (err == -EAGAIN) - goto again; - else if (err) - return err; - - if (index > max_id) { - spin_lock(lock); - ida_remove(ida, index); - spin_unlock(lock); - return -ENOMEM; - } - - return index; -} - -int get_cop_pid(struct mm_struct *mm) -{ - int pid; - - if (mm->context.cop_pid == COP_PID_NONE) { - pid = new_cop_pid(&cop_ida, COP_PID_MIN, COP_PID_MAX, - &mmu_context_acop_lock); - if (pid >= 0) - mm->context.cop_pid = pid; - } - return mm->context.cop_pid; -} - -int disable_cop_pid(struct mm_struct *mm) -{ - int free_pid = COP_PID_NONE; - - if ((!mm->context.acop) && (mm->context.cop_pid != COP_PID_NONE)) { - free_pid = mm->context.cop_pid; - mm->context.cop_pid = COP_PID_NONE; - } - return free_pid; -} - -void free_cop_pid(int free_pid) -{ - spin_lock(&mmu_context_acop_lock); - ida_remove(&cop_ida, free_pid); - spin_unlock(&mmu_context_acop_lock); -} diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 8a7c38b8d335..6419b33ca309 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -113,6 +113,12 @@ void __init MMU_setup(void) __map_without_bats = 1; __map_without_ltlbs = 1; } +#ifdef CONFIG_STRICT_KERNEL_RWX + if (rodata_enabled) { + __map_without_bats = 1; + __map_without_ltlbs = 1; + } +#endif } /* @@ -132,8 +138,6 @@ void __init MMU_init(void) * Reserve gigantic pages for hugetlb. This MUST occur before * lowmem_end_addr is initialized below. */ - reserve_hugetlb_gpages(); - if (memblock.memory.cnt > 1) { #ifndef CONFIG_WII memblock_enforce_memory_limit(memblock.memory.regions[0].size); diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 5b4c25d12ff3..588a521966ec 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -356,7 +356,7 @@ struct page *realmode_pfn_to_page(unsigned long pfn) } EXPORT_SYMBOL_GPL(realmode_pfn_to_page); -#elif defined(CONFIG_FLATMEM) +#else struct page *realmode_pfn_to_page(unsigned long pfn) { @@ -365,7 +365,7 @@ struct page *realmode_pfn_to_page(unsigned long pfn) } EXPORT_SYMBOL_GPL(realmode_pfn_to_page); -#endif /* CONFIG_SPARSEMEM_VMEMMAP/CONFIG_FLATMEM */ +#endif /* CONFIG_SPARSEMEM_VMEMMAP */ #ifdef CONFIG_PPC_STD_MMU_64 static bool disable_radix; @@ -381,7 +381,7 @@ early_param("disable_radix", parse_disable_radix); * /chosen/ibm,architecture-vec-5 to see if the hypervisor is willing to do * radix. If not, we clear the radix feature bit so we fall back to hash. */ -static void early_check_vec5(void) +static void __init early_check_vec5(void) { unsigned long root, chosen; int size; diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 46b4e67d2372..4362b86ef84c 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -436,7 +436,7 @@ void flush_dcache_icache_page(struct page *page) return; } #endif -#if defined(CONFIG_8xx) || defined(CONFIG_PPC64) +#if defined(CONFIG_PPC_8xx) || defined(CONFIG_PPC64) /* On 8xx there is no need to kmap since highmem is not supported */ __flush_dcache_icache(page_address(page)); #else diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c new file mode 100644 index 000000000000..0f613bc63c50 --- /dev/null +++ b/arch/powerpc/mm/mmu_context.c @@ -0,0 +1,99 @@ +/* + * Common implementation of switch_mm_irqs_off + * + * Copyright IBM Corp. 2017 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include + +#include + +#if defined(CONFIG_PPC32) +static inline void switch_mm_pgdir(struct task_struct *tsk, + struct mm_struct *mm) +{ + /* 32-bit keeps track of the current PGDIR in the thread struct */ + tsk->thread.pgdir = mm->pgd; +} +#elif defined(CONFIG_PPC_BOOK3E_64) +static inline void switch_mm_pgdir(struct task_struct *tsk, + struct mm_struct *mm) +{ + /* 64-bit Book3E keeps track of current PGD in the PACA */ + get_paca()->pgd = mm->pgd; +} +#else +static inline void switch_mm_pgdir(struct task_struct *tsk, + struct mm_struct *mm) { } +#endif + +#ifdef CONFIG_PPC_BOOK3S_64 +static inline void inc_mm_active_cpus(struct mm_struct *mm) +{ + atomic_inc(&mm->context.active_cpus); +} +#else +static inline void inc_mm_active_cpus(struct mm_struct *mm) { } +#endif + +void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ + bool new_on_cpu = false; + + /* Mark this context has been used on the new CPU */ + if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) { + cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); + inc_mm_active_cpus(next); + + /* + * This full barrier orders the store to the cpumask above vs + * a subsequent operation which allows this CPU to begin loading + * translations for next. + * + * When using the radix MMU that operation is the load of the + * MMU context id, which is then moved to SPRN_PID. + * + * For the hash MMU it is either the first load from slb_cache + * in switch_slb(), and/or the store of paca->mm_ctx_id in + * copy_mm_to_paca(). + * + * On the read side the barrier is in pte_xchg(), which orders + * the store to the PTE vs the load of mm_cpumask. + */ + smp_mb(); + + new_on_cpu = true; + } + + /* Some subarchs need to track the PGD elsewhere */ + switch_mm_pgdir(tsk, next); + + /* Nothing else to do if we aren't actually switching */ + if (prev == next) + return; + + /* + * We must stop all altivec streams before changing the HW + * context + */ + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + asm volatile ("dssall"); + + if (new_on_cpu) + radix_kvm_prefetch_workaround(next); + + /* + * The actual HW switching method differs between the various + * sub architectures. Out of line for now + */ + switch_mmu_context(prev, next, tsk); +} + diff --git a/arch/powerpc/mm/mmu_context_book3s64.c b/arch/powerpc/mm/mmu_context_book3s64.c index a75f63833284..05e15386d4cb 100644 --- a/arch/powerpc/mm/mmu_context_book3s64.c +++ b/arch/powerpc/mm/mmu_context_book3s64.c @@ -25,8 +25,6 @@ #include #include -#include "icswx.h" - static DEFINE_SPINLOCK(mmu_context_lock); static DEFINE_IDA(mmu_context_ida); @@ -165,16 +163,6 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) return index; mm->context.id = index; -#ifdef CONFIG_PPC_ICSWX - mm->context.cop_lockp = kmalloc(sizeof(spinlock_t), GFP_KERNEL); - if (!mm->context.cop_lockp) { - __destroy_context(index); - subpage_prot_free(mm); - mm->context.id = MMU_NO_CONTEXT; - return -ENOMEM; - } - spin_lock_init(mm->context.cop_lockp); -#endif /* CONFIG_PPC_ICSWX */ #ifdef CONFIG_PPC_64K_PAGES mm->context.pte_frag = NULL; @@ -182,6 +170,8 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) #ifdef CONFIG_SPAPR_TCE_IOMMU mm_iommu_init(mm); #endif + atomic_set(&mm->context.active_cpus, 0); + return 0; } @@ -226,12 +216,6 @@ void destroy_context(struct mm_struct *mm) #ifdef CONFIG_SPAPR_TCE_IOMMU WARN_ON_ONCE(!list_empty(&mm->context.iommu_group_mem_list)); #endif -#ifdef CONFIG_PPC_ICSWX - drop_cop(mm->context.acop, mm); - kfree(mm->context.cop_lockp); - mm->context.cop_lockp = NULL; -#endif /* CONFIG_PPC_ICSWX */ - if (radix_enabled()) { /* * Radix doesn't have a valid bit in the process table diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index d46128b22150..57fbc554c785 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -27,7 +27,7 @@ /* * On 40x and 8xx, we directly inline tlbia and tlbivax */ -#if defined(CONFIG_40x) || defined(CONFIG_8xx) +#if defined(CONFIG_40x) || defined(CONFIG_PPC_8xx) static inline void _tlbil_all(void) { asm volatile ("sync; tlbia; isync" : : : "memory"); @@ -38,7 +38,7 @@ static inline void _tlbil_pid(unsigned int pid) } #define _tlbil_pid_noind(pid) _tlbil_pid(pid) -#else /* CONFIG_40x || CONFIG_8xx */ +#else /* CONFIG_40x || CONFIG_PPC_8xx */ extern void _tlbil_all(void); extern void _tlbil_pid(unsigned int pid); #ifdef CONFIG_PPC_BOOK3E @@ -46,12 +46,12 @@ extern void _tlbil_pid_noind(unsigned int pid); #else #define _tlbil_pid_noind(pid) _tlbil_pid(pid) #endif -#endif /* !(CONFIG_40x || CONFIG_8xx) */ +#endif /* !(CONFIG_40x || CONFIG_PPC_8xx) */ /* * On 8xx, we directly inline tlbie, on others, it's extern */ -#ifdef CONFIG_8xx +#ifdef CONFIG_PPC_8xx static inline void _tlbil_va(unsigned long address, unsigned int pid, unsigned int tsize, unsigned int ind) { @@ -67,7 +67,7 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid, { __tlbil_va(address, pid); } -#endif /* CONFIG_8xx */ +#endif /* CONFIG_PPC_8xx */ #if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x) extern void _tlbivax_bcast(unsigned long address, unsigned int pid, diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index b95c584ce19d..a51df9ef529d 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1438,7 +1438,6 @@ out: int arch_update_cpu_topology(void) { - lockdep_assert_cpus_held(); return numa_update_cpu_topology(true); } diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c index 31eed8fa8e99..3b65917785a5 100644 --- a/arch/powerpc/mm/pgtable-book3s64.c +++ b/arch/powerpc/mm/pgtable-book3s64.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -64,6 +65,27 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, trace_hugepage_set_pmd(addr, pmd_val(pmd)); return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd)); } + +static void do_nothing(void *unused) +{ + +} +/* + * Serialize against find_current_mm_pte which does lock-less + * lookup in page tables with local interrupts disabled. For huge pages + * it casts pmd_t to pte_t. Since format of pte_t is different from + * pmd_t we want to prevent transit from pmd pointing to page table + * to pmd pointing to huge page (and back) while interrupts are disabled. + * We clear pmd to possibly replace it with page table pointer in + * different code paths. So make sure we wait for the parallel + * find_current_mm_pte to finish. + */ +void serialize_against_pte_lookup(struct mm_struct *mm) +{ + smp_mb(); + smp_call_function_many(mm_cpumask(mm), do_nothing, NULL, 1); +} + /* * We use this to invalidate a pmdp entry before switching from a * hugepte to regular pmd entry. @@ -77,7 +99,7 @@ void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, * This ensures that generic code that rely on IRQ disabling * to prevent a parallel THP split work as expected. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(vma->vm_mm); } static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot) diff --git a/arch/powerpc/mm/pgtable-hash64.c b/arch/powerpc/mm/pgtable-hash64.c index 443a2c66a304..ec277913e01b 100644 --- a/arch/powerpc/mm/pgtable-hash64.c +++ b/arch/powerpc/mm/pgtable-hash64.c @@ -239,7 +239,7 @@ pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addres * by sending an IPI to all the cpus and executing a dummy * function there. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(vma->vm_mm); /* * Now invalidate the hpte entries in the range * covered by pmd. This make sure we take a @@ -329,7 +329,6 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, unsigned int psize; unsigned long vsid; unsigned long flags = 0; - const struct cpumask *tmp; /* get the base page size,vsid and segment size */ #ifdef CONFIG_DEBUG_VM @@ -350,8 +349,7 @@ void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr, ssize = mmu_kernel_ssize; } - tmp = cpumask_of(smp_processor_id()); - if (cpumask_equal(mm_cpumask(mm), tmp)) + if (mm_is_thread_local(mm)) flags |= HPTE_LOCAL_UPDATE; return flush_hash_hugepage(vsid, addr, pmdp, psize, ssize, flags); @@ -380,16 +378,16 @@ pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm, */ memset(pgtable, 0, PTE_FRAG_SIZE); /* - * Serialize against find_linux_pte_or_hugepte which does lock-less + * Serialize against find_current_mm_pte variants which does lock-less * lookup in page tables with local interrupts disabled. For huge pages * it casts pmd_t to pte_t. Since format of pte_t is different from * pmd_t we want to prevent transit from pmd pointing to page table * to pmd pointing to huge page (and back) while interrupts are disabled. * We clear pmd to possibly replace it with page table pointer in * different code paths. So make sure we wait for the parallel - * find_linux_pte_or_hugepage to finish. + * find_curren_mm_pte to finish. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(mm); return old_pmd; } diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c index 671a45d86c18..39c252b54d16 100644 --- a/arch/powerpc/mm/pgtable-radix.c +++ b/arch/powerpc/mm/pgtable-radix.c @@ -8,10 +8,15 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ + +#define pr_fmt(fmt) "radix-mmu: " fmt + +#include #include #include #include #include +#include #include #include @@ -31,9 +36,13 @@ unsigned int mmu_base_pid; static int native_register_process_table(unsigned long base, unsigned long pg_sz, unsigned long table_size) { - unsigned long patb1 = base | table_size | PATB_GR; + unsigned long patb0, patb1; + + patb0 = be64_to_cpu(partition_tb[0].patb0); + patb1 = base | table_size | PATB_GR; + + mmu_partition_table_set_entry(0, patb0, patb1); - partition_tb->patb1 = cpu_to_be64(patb1); return 0; } @@ -179,10 +188,14 @@ static inline void __meminit print_mapping(unsigned long start, unsigned long end, unsigned long size) { + char buf[10]; + if (end <= start) return; - pr_info("Mapped range 0x%lx - 0x%lx with 0x%lx\n", start, end, size); + string_get_size(size, 1, STRING_UNITS_2, buf, sizeof(buf)); + + pr_info("Mapped 0x%016lx-0x%016lx with %s pages\n", start, end, buf); } static int __meminit create_physical_mapping(unsigned long start, @@ -526,6 +539,7 @@ void __init radix__early_init_mmu(void) __kernel_virt_size = RADIX_KERN_VIRT_SIZE; __vmalloc_start = RADIX_VMALLOC_START; __vmalloc_end = RADIX_VMALLOC_END; + __kernel_io_start = RADIX_KERN_IO_START; vmemmap = (struct page *)RADIX_VMEMMAP_BASE; ioremap_bot = IOREMAP_BASE; @@ -836,9 +850,12 @@ pmd_t radix__pmdp_collapse_flush(struct vm_area_struct *vma, unsigned long addre */ pmd = *pmdp; pmd_clear(pmdp); + /*FIXME!! Verify whether we need this kick below */ - kick_all_cpus_sync(); - flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); + serialize_against_pte_lookup(vma->vm_mm); + + radix__flush_tlb_collapsed_pmd(vma->vm_mm, address); + return pmd; } @@ -897,16 +914,16 @@ pmd_t radix__pmdp_huge_get_and_clear(struct mm_struct *mm, old = radix__pmd_hugepage_update(mm, addr, pmdp, ~0UL, 0); old_pmd = __pmd(old); /* - * Serialize against find_linux_pte_or_hugepte which does lock-less + * Serialize against find_current_mm_pte which does lock-less * lookup in page tables with local interrupts disabled. For huge pages * it casts pmd_t to pte_t. Since format of pte_t is different from * pmd_t we want to prevent transit from pmd pointing to page table * to pmd pointing to huge page (and back) while interrupts are disabled. * We clear pmd to possibly replace it with page table pointer in * different code paths. So make sure we wait for the parallel - * find_linux_pte_or_hugepage to finish. + * find_current_mm_pte to finish. */ - kick_all_cpus_sync(); + serialize_against_pte_lookup(mm); return old_pmd; } diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index a9e4bfc025bc..f6c7f54c0515 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "mmu_decl.h" @@ -242,7 +243,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, int flags) /* * Map in a chunk of physical memory starting at start. */ -void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) +static void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) { unsigned long v, s, f; phys_addr_t p; @@ -294,7 +295,7 @@ void __init mapin_ram(void) * Returns true (1) if PTE was found, zero otherwise. The pointer to * the PTE pointer is unmodified if PTE is not found. */ -int +static int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) { pgd_t *pgd; @@ -323,9 +324,7 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) return(retval); } -#ifdef CONFIG_DEBUG_PAGEALLOC - -static int __change_page_attr(struct page *page, pgprot_t prot) +static int __change_page_attr_noflush(struct page *page, pgprot_t prot) { pte_t *kpte; pmd_t *kpmd; @@ -339,8 +338,6 @@ static int __change_page_attr(struct page *page, pgprot_t prot) if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) return -EINVAL; __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0); - wmb(); - flush_tlb_page(NULL, address); pte_unmap(kpte); return 0; @@ -349,24 +346,60 @@ static int __change_page_attr(struct page *page, pgprot_t prot) /* * Change the page attributes of an page in the linear mapping. * - * THIS CONFLICTS WITH BAT MAPPINGS, DEBUG USE ONLY + * THIS DOES NOTHING WITH BAT MAPPINGS, DEBUG USE ONLY */ static int change_page_attr(struct page *page, int numpages, pgprot_t prot) { int i, err = 0; unsigned long flags; + struct page *start = page; local_irq_save(flags); for (i = 0; i < numpages; i++, page++) { - err = __change_page_attr(page, prot); + err = __change_page_attr_noflush(page, prot); if (err) break; } + wmb(); local_irq_restore(flags); + flush_tlb_kernel_range((unsigned long)page_address(start), + (unsigned long)page_address(page)); return err; } +void mark_initmem_nx(void) +{ + struct page *page = virt_to_page(_sinittext); + unsigned long numpages = PFN_UP((unsigned long)_einittext) - + PFN_DOWN((unsigned long)_sinittext); + change_page_attr(page, numpages, PAGE_KERNEL); +} + +#ifdef CONFIG_STRICT_KERNEL_RWX +void mark_rodata_ro(void) +{ + struct page *page; + unsigned long numpages; + + page = virt_to_page(_stext); + numpages = PFN_UP((unsigned long)_etext) - + PFN_DOWN((unsigned long)_stext); + + change_page_attr(page, numpages, PAGE_KERNEL_ROX); + /* + * mark .rodata as read only. Use __init_begin rather than __end_rodata + * to cover NOTES and EXCEPTION_TABLE. + */ + page = virt_to_page(__start_rodata); + numpages = PFN_UP((unsigned long)__init_begin) - + PFN_DOWN((unsigned long)__start_rodata); + + change_page_attr(page, numpages, PAGE_KERNEL_RO); +} +#endif + +#ifdef CONFIG_DEBUG_PAGEALLOC void __kernel_map_pages(struct page *page, int numpages, int enable) { if (PageHighMem(page)) @@ -375,18 +408,3 @@ void __kernel_map_pages(struct page *page, int numpages, int enable) change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0)); } #endif /* CONFIG_DEBUG_PAGEALLOC */ - -static int fixmaps; - -void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) -{ - unsigned long address = __fix_to_virt(idx); - - if (idx >= __end_of_fixed_addresses) { - BUG(); - return; - } - - map_kernel_page(address, phys, pgprot_val(flags)); - fixmaps++; -} diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 0736e94c7615..ac0717a90ca6 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -104,6 +104,8 @@ unsigned long __vmalloc_start; EXPORT_SYMBOL(__vmalloc_start); unsigned long __vmalloc_end; EXPORT_SYMBOL(__vmalloc_end); +unsigned long __kernel_io_start; +EXPORT_SYMBOL(__kernel_io_start); struct page *vmemmap; EXPORT_SYMBOL(vmemmap); unsigned long __pte_frag_nr; diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S index bde378559d01..906a86fe457b 100644 --- a/arch/powerpc/mm/slb_low.S +++ b/arch/powerpc/mm/slb_low.S @@ -121,12 +121,25 @@ slb_miss_kernel_load_vmemmap: 1: #endif /* CONFIG_SPARSEMEM_VMEMMAP */ - /* vmalloc mapping gets the encoding from the PACA as the mapping - * can be demoted from 64K -> 4K dynamically on some machines + /* + * r10 contains the ESID, which is the original faulting EA shifted + * right by 28 bits. We need to compare that with (H_VMALLOC_END >> 28) + * which is 0xd00038000. That can't be used as an immediate, even if we + * ignored the 0xd, so we have to load it into a register, and we only + * have one register free. So we must load all of (H_VMALLOC_END >> 28) + * into a register and compare ESID against that. + */ + lis r11,(H_VMALLOC_END >> 32)@h // r11 = 0xffffffffd0000000 + ori r11,r11,(H_VMALLOC_END >> 32)@l // r11 = 0xffffffffd0003800 + // Rotate left 4, then mask with 0xffffffff0 + rldic r11,r11,4,28 // r11 = 0xd00038000 + cmpld r10,r11 // if r10 >= r11 + bge 5f // goto io_mapping + + /* + * vmalloc mapping gets the encoding from the PACA as the mapping + * can be demoted from 64K -> 4K dynamically on some machines. */ - clrldi r11,r10,48 - cmpldi r11,(H_VMALLOC_SIZE >> 28) - 1 - bgt 5f lhz r11,PACAVMALLOCSLLP(r13) b 6f 5: diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c index 16ae1bbe13f0..d304028641a2 100644 --- a/arch/powerpc/mm/tlb-radix.c +++ b/arch/powerpc/mm/tlb-radix.c @@ -54,23 +54,15 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) */ __tlbiel_pid(pid, 0, ric); - if (ric == RIC_FLUSH_ALL) - /* For the remaining sets, just flush the TLB */ - ric = RIC_FLUSH_TLB; + /* For PWC, only one flush is needed */ + if (ric == RIC_FLUSH_PWC) { + asm volatile("ptesync": : :"memory"); + return; + } + /* For the remaining sets, just flush the TLB */ for (set = 1; set < POWER9_TLB_SETS_RADIX ; set++) - __tlbiel_pid(pid, set, ric); - - asm volatile("ptesync": : :"memory"); - asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); -} - -static inline void tlbiel_pwc(unsigned long pid) -{ - asm volatile("ptesync": : :"memory"); - - /* For PWC flush, we don't look at set number */ - __tlbiel_pid(pid, 0, RIC_FLUSH_PWC); + __tlbiel_pid(pid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); @@ -146,31 +138,23 @@ void radix__local_flush_tlb_mm(struct mm_struct *mm) preempt_disable(); pid = mm->context.id; if (pid != MMU_NO_CONTEXT) - _tlbiel_pid(pid, RIC_FLUSH_ALL); + _tlbiel_pid(pid, RIC_FLUSH_TLB); preempt_enable(); } EXPORT_SYMBOL(radix__local_flush_tlb_mm); -void radix__local_flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr) +#ifndef CONFIG_SMP +static void radix__local_flush_all_mm(struct mm_struct *mm) { unsigned long pid; - struct mm_struct *mm = tlb->mm; - /* - * If we are doing a full mm flush, we will do a tlb flush - * with RIC_FLUSH_ALL later. - */ - if (tlb->fullmm) - return; preempt_disable(); - pid = mm->context.id; if (pid != MMU_NO_CONTEXT) - tlbiel_pwc(pid); - + _tlbiel_pid(pid, RIC_FLUSH_ALL); preempt_enable(); } -EXPORT_SYMBOL(radix__local_flush_tlb_pwc); +#endif /* CONFIG_SMP */ void radix__local_flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr, int psize) @@ -202,6 +186,24 @@ void radix__flush_tlb_mm(struct mm_struct *mm) { unsigned long pid; + preempt_disable(); + pid = mm->context.id; + if (unlikely(pid == MMU_NO_CONTEXT)) + goto no_context; + + if (!mm_is_thread_local(mm)) + _tlbie_pid(pid, RIC_FLUSH_TLB); + else + _tlbiel_pid(pid, RIC_FLUSH_TLB); +no_context: + preempt_enable(); +} +EXPORT_SYMBOL(radix__flush_tlb_mm); + +static void radix__flush_all_mm(struct mm_struct *mm) +{ + unsigned long pid; + preempt_disable(); pid = mm->context.id; if (unlikely(pid == MMU_NO_CONTEXT)) @@ -214,31 +216,10 @@ void radix__flush_tlb_mm(struct mm_struct *mm) no_context: preempt_enable(); } -EXPORT_SYMBOL(radix__flush_tlb_mm); void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr) { - unsigned long pid; - struct mm_struct *mm = tlb->mm; - - /* - * If we are doing a full mm flush, we will do a tlb flush - * with RIC_FLUSH_ALL later. - */ - if (tlb->fullmm) - return; - preempt_disable(); - - pid = mm->context.id; - if (unlikely(pid == MMU_NO_CONTEXT)) - goto no_context; - - if (!mm_is_thread_local(mm)) - _tlbie_pid(pid, RIC_FLUSH_PWC); - else - tlbiel_pwc(pid); -no_context: - preempt_enable(); + tlb->need_flush_all = 1; } EXPORT_SYMBOL(radix__flush_tlb_pwc); @@ -271,6 +252,8 @@ void radix__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) } EXPORT_SYMBOL(radix__flush_tlb_page); +#else /* CONFIG_SMP */ +#define radix__flush_all_mm radix__local_flush_all_mm #endif /* CONFIG_SMP */ void radix__flush_tlb_kernel_range(unsigned long start, unsigned long end) @@ -288,6 +271,7 @@ void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start, { struct mm_struct *mm = vma->vm_mm; + radix__flush_tlb_mm(mm); } EXPORT_SYMBOL(radix__flush_tlb_range); @@ -319,7 +303,10 @@ void radix__tlb_flush(struct mmu_gather *tlb) */ if (psize != -1 && !tlb->fullmm && !tlb->need_flush_all) radix__flush_tlb_range_psize(mm, tlb->start, tlb->end, psize); - else + else if (tlb->need_flush_all) { + tlb->need_flush_all = 0; + radix__flush_all_mm(mm); + } else radix__flush_tlb_mm(mm); } @@ -364,6 +351,45 @@ err_out: preempt_enable(); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +void radix__flush_tlb_collapsed_pmd(struct mm_struct *mm, unsigned long addr) +{ + int local = mm_is_thread_local(mm); + unsigned long ap = mmu_get_ap(mmu_virtual_psize); + unsigned long pid, end; + + + pid = mm ? mm->context.id : 0; + preempt_disable(); + if (unlikely(pid == MMU_NO_CONTEXT)) + goto no_context; + + /* 4k page size, just blow the world */ + if (PAGE_SIZE == 0x1000) { + radix__flush_all_mm(mm); + preempt_enable(); + return; + } + + /* Otherwise first do the PWC */ + if (local) + _tlbiel_pid(pid, RIC_FLUSH_PWC); + else + _tlbie_pid(pid, RIC_FLUSH_PWC); + + /* Then iterate the pages */ + end = addr + HPAGE_PMD_SIZE; + for (; addr < end; addr += PAGE_SIZE) { + if (local) + _tlbiel_va(addr, pid, ap, RIC_FLUSH_TLB); + else + _tlbie_va(addr, pid, ap, RIC_FLUSH_TLB); + } +no_context: + preempt_enable(); +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + void radix__flush_tlb_lpid_va(unsigned long lpid, unsigned long gpa, unsigned long page_size) { diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c index b5b0fb97b9c0..881ebd53ffc2 100644 --- a/arch/powerpc/mm/tlb_hash64.c +++ b/arch/powerpc/mm/tlb_hash64.c @@ -29,6 +29,8 @@ #include #include #include +#include + #include @@ -138,13 +140,10 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, */ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) { - const struct cpumask *tmp; - int i, local = 0; + int i, local; i = batch->index; - tmp = cpumask_of(smp_processor_id()); - if (cpumask_equal(mm_cpumask(batch->mm), tmp)) - local = 1; + local = mm_is_thread_local(batch->mm); if (i == 1) flush_hash_page(batch->vpn[0], batch->pte[0], batch->psize, batch->ssize, local); @@ -207,8 +206,8 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, local_irq_save(flags); arch_enter_lazy_mmu_mode(); for (; start < end; start += PAGE_SIZE) { - pte_t *ptep = find_linux_pte_or_hugepte(mm->pgd, start, &is_thp, - &hugepage_shift); + pte_t *ptep = find_current_mm_pte(mm->pgd, start, &is_thp, + &hugepage_shift); unsigned long pte; if (ptep == NULL) diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index eabecfcaef7c..048b8e9f4492 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -60,7 +60,7 @@ _GLOBAL(__tlbil_va) isync 1: blr -#elif defined(CONFIG_8xx) +#elif defined(CONFIG_PPC_8xx) /* * Nothing to do for 8xx, everything is inline diff --git a/arch/powerpc/mm/vphn.c b/arch/powerpc/mm/vphn.c index 5f8ef50e5c66..f83044faac23 100644 --- a/arch/powerpc/mm/vphn.c +++ b/arch/powerpc/mm/vphn.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "vphn.h" diff --git a/arch/powerpc/mm/vphn.h b/arch/powerpc/mm/vphn.h index fe8b7805b78f..f9ffdb3942fc 100644 --- a/arch/powerpc/mm/vphn.h +++ b/arch/powerpc/mm/vphn.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_POWERPC_MM_VPHN_H_ #define _ARCH_POWERPC_MM_VPHN_H_ diff --git a/arch/powerpc/net/Makefile b/arch/powerpc/net/Makefile index c1ff16a6eb51..02d369ca6a53 100644 --- a/arch/powerpc/net/Makefile +++ b/arch/powerpc/net/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Arch-specific network modules # diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index 30cf03f53428..47fc6660845d 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -263,6 +263,7 @@ static inline bool is_nearbranch(int offset) #define COND_EQ (CR0_EQ | COND_CMP_TRUE) #define COND_NE (CR0_EQ | COND_CMP_FALSE) #define COND_LT (CR0_LT | COND_CMP_TRUE) +#define COND_LE (CR0_GT | COND_CMP_FALSE) #endif diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index 861c5af1c9c4..a66e64b0b251 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -25,11 +25,7 @@ int bpf_jit_enable __read_mostly; static void bpf_jit_fill_ill_insns(void *area, unsigned int size) { - int *p = area; - - /* Fill whole space with trap instructions */ - while (p < (int *)((char *)area + size)) - *p++ = BREAKPOINT_INSTRUCTION; + memset32(area, BREAKPOINT_INSTRUCTION, size/4); } static inline void bpf_flush_icache(void *start, void *end) @@ -795,12 +791,24 @@ emit_clear: case BPF_JMP | BPF_JSGT | BPF_X: true_cond = COND_GT; goto cond_branch; + case BPF_JMP | BPF_JLT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_X: + true_cond = COND_LT; + goto cond_branch; case BPF_JMP | BPF_JGE | BPF_K: case BPF_JMP | BPF_JGE | BPF_X: case BPF_JMP | BPF_JSGE | BPF_K: case BPF_JMP | BPF_JSGE | BPF_X: true_cond = COND_GE; goto cond_branch; + case BPF_JMP | BPF_JLE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_X: + true_cond = COND_LE; + goto cond_branch; case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JEQ | BPF_X: true_cond = COND_EQ; @@ -817,14 +825,18 @@ emit_clear: cond_branch: switch (code) { case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: case BPF_JMP | BPF_JEQ | BPF_X: case BPF_JMP | BPF_JNE | BPF_X: /* unsigned comparison */ PPC_CMPLD(dst_reg, src_reg); break; case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: /* signed comparison */ PPC_CMPD(dst_reg, src_reg); break; @@ -834,7 +846,9 @@ cond_branch: case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: /* * Need sign-extended load, so only positive * values can be used as imm in cmpldi @@ -849,7 +863,9 @@ cond_branch: } break; case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: /* * signed comparison, so any 16-bit value * can be used in cmpdi diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index cedbbeced632..7a7834c39f64 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile index 4d606b99a5cb..225c9c86d7c0 100644 --- a/arch/powerpc/perf/Makefile +++ b/arch/powerpc/perf/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o @@ -8,6 +9,7 @@ obj64-$(CONFIG_PPC_PERF_CTRS) += power4-pmu.o ppc970-pmu.o power5-pmu.o \ isa207-common.o power8-pmu.o power9-pmu.o obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o +obj-$(CONFIG_PPC_POWERNV) += imc-pmu.o obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c index 0fc26714780a..0af051a1974e 100644 --- a/arch/powerpc/perf/callchain.c +++ b/arch/powerpc/perf/callchain.c @@ -22,6 +22,7 @@ #ifdef CONFIG_PPC64 #include "../kernel/ppc32.h" #endif +#include /* @@ -127,7 +128,7 @@ static int read_user_stack_slow(void __user *ptr, void *buf, int nb) return -EFAULT; local_irq_save(flags); - ptep = find_linux_pte_or_hugepte(pgdir, addr, NULL, &shift); + ptep = find_current_mm_pte(pgdir, addr, NULL, &shift); if (!ptep) goto err_out; if (!shift) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 6c2d4168daec..9e3da168d54c 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -793,6 +793,11 @@ void perf_event_print_debug(void) u32 pmcs[MAX_HWEVENTS]; int i; + if (!ppmu) { + pr_info("Performance monitor hardware not registered.\n"); + return; + } + if (!ppmu->n_counter) return; @@ -2039,7 +2044,8 @@ static void record_and_restart(struct perf_event *event, unsigned long val, perf_sample_data_init(&data, ~0ULL, event->hw.last_period); - if (event->attr.sample_type & PERF_SAMPLE_ADDR) + if (event->attr.sample_type & + (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) perf_get_data_addr(regs, &data.addr); if (event->attr.sample_type & PERF_SAMPLE_BRANCH_STACK) { diff --git a/arch/powerpc/perf/hv-24x7-catalog.h b/arch/powerpc/perf/hv-24x7-catalog.h index 69e2e1faf902..5fab5a397da9 100644 --- a/arch/powerpc/perf/hv-24x7-catalog.h +++ b/arch/powerpc/perf/hv-24x7-catalog.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_ #define LINUX_POWERPC_PERF_HV_24X7_CATALOG_H_ diff --git a/arch/powerpc/perf/hv-24x7-domains.h b/arch/powerpc/perf/hv-24x7-domains.h index 49c1efd50045..6f91f62e0aa6 100644 --- a/arch/powerpc/perf/hv-24x7-domains.h +++ b/arch/powerpc/perf/hv-24x7-domains.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * DOMAIN(name, num, index_kind, is_physical) diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h index 5092c4a222a6..ae4ae4813e16 100644 --- a/arch/powerpc/perf/hv-24x7.h +++ b/arch/powerpc/perf/hv-24x7.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LINUX_POWERPC_PERF_HV_24X7_H_ #define LINUX_POWERPC_PERF_HV_24X7_H_ diff --git a/arch/powerpc/perf/hv-common.c b/arch/powerpc/perf/hv-common.c index 7dce8f109967..0370518edd20 100644 --- a/arch/powerpc/perf/hv-common.c +++ b/arch/powerpc/perf/hv-common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/powerpc/perf/hv-common.h b/arch/powerpc/perf/hv-common.h index 349aaba4d2d1..2cce17bc321c 100644 --- a/arch/powerpc/perf/hv-common.h +++ b/arch/powerpc/perf/hv-common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LINUX_POWERPC_PERF_HV_COMMON_H_ #define LINUX_POWERPC_PERF_HV_COMMON_H_ diff --git a/arch/powerpc/perf/hv-gpci-requests.h b/arch/powerpc/perf/hv-gpci-requests.h index acd17648cd18..e608f9db12dd 100644 --- a/arch/powerpc/perf/hv-gpci-requests.h +++ b/arch/powerpc/perf/hv-gpci-requests.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include "req-gen/_begin.h" diff --git a/arch/powerpc/perf/hv-gpci.h b/arch/powerpc/perf/hv-gpci.h index 86ede8275961..a3053eda5dcc 100644 --- a/arch/powerpc/perf/hv-gpci.h +++ b/arch/powerpc/perf/hv-gpci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LINUX_POWERPC_PERF_HV_GPCI_H_ #define LINUX_POWERPC_PERF_HV_GPCI_H_ diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c new file mode 100644 index 000000000000..36344117c680 --- /dev/null +++ b/arch/powerpc/perf/imc-pmu.c @@ -0,0 +1,1349 @@ +/* + * In-Memory Collection (IMC) Performance Monitor counter support. + * + * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation. + * (C) 2017 Anju T Sudhakar, IBM Corporation. + * (C) 2017 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or later version. + */ +#include +#include +#include +#include +#include +#include +#include + +/* Nest IMC data structures and variables */ + +/* + * Used to avoid races in counting the nest-pmu units during hotplug + * register and unregister + */ +static DEFINE_MUTEX(nest_init_lock); +static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc); +static struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS]; +static cpumask_t nest_imc_cpumask; +struct imc_pmu_ref *nest_imc_refc; +static int nest_pmus; + +/* Core IMC data structures and variables */ + +static cpumask_t core_imc_cpumask; +struct imc_pmu_ref *core_imc_refc; +static struct imc_pmu *core_imc_pmu; + +/* Thread IMC data structures and variables */ + +static DEFINE_PER_CPU(u64 *, thread_imc_mem); +static struct imc_pmu *thread_imc_pmu; +static int thread_imc_mem_size; + +struct imc_pmu *imc_event_to_pmu(struct perf_event *event) +{ + return container_of(event->pmu, struct imc_pmu, pmu); +} + +PMU_FORMAT_ATTR(event, "config:0-40"); +PMU_FORMAT_ATTR(offset, "config:0-31"); +PMU_FORMAT_ATTR(rvalue, "config:32"); +PMU_FORMAT_ATTR(mode, "config:33-40"); +static struct attribute *imc_format_attrs[] = { + &format_attr_event.attr, + &format_attr_offset.attr, + &format_attr_rvalue.attr, + &format_attr_mode.attr, + NULL, +}; + +static struct attribute_group imc_format_group = { + .name = "format", + .attrs = imc_format_attrs, +}; + +/* Get the cpumask printed to a buffer "buf" */ +static ssize_t imc_pmu_cpumask_get_attr(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct pmu *pmu = dev_get_drvdata(dev); + struct imc_pmu *imc_pmu = container_of(pmu, struct imc_pmu, pmu); + cpumask_t *active_mask; + + switch(imc_pmu->domain){ + case IMC_DOMAIN_NEST: + active_mask = &nest_imc_cpumask; + break; + case IMC_DOMAIN_CORE: + active_mask = &core_imc_cpumask; + break; + default: + return 0; + } + + return cpumap_print_to_pagebuf(true, buf, active_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL); + +static struct attribute *imc_pmu_cpumask_attrs[] = { + &dev_attr_cpumask.attr, + NULL, +}; + +static struct attribute_group imc_pmu_cpumask_attr_group = { + .attrs = imc_pmu_cpumask_attrs, +}; + +/* device_str_attr_create : Populate event "name" and string "str" in attribute */ +static struct attribute *device_str_attr_create(const char *name, const char *str) +{ + struct perf_pmu_events_attr *attr; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) + return NULL; + sysfs_attr_init(&attr->attr.attr); + + attr->event_str = str; + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = perf_event_sysfs_show; + + return &attr->attr.attr; +} + +struct imc_events *imc_parse_event(struct device_node *np, const char *scale, + const char *unit, const char *prefix, u32 base) +{ + struct imc_events *event; + const char *s; + u32 reg; + + event = kzalloc(sizeof(struct imc_events), GFP_KERNEL); + if (!event) + return NULL; + + if (of_property_read_u32(np, "reg", ®)) + goto error; + /* Add the base_reg value to the "reg" */ + event->value = base + reg; + + if (of_property_read_string(np, "event-name", &s)) + goto error; + + event->name = kasprintf(GFP_KERNEL, "%s%s", prefix, s); + if (!event->name) + goto error; + + if (of_property_read_string(np, "scale", &s)) + s = scale; + + if (s) { + event->scale = kstrdup(s, GFP_KERNEL); + if (!event->scale) + goto error; + } + + if (of_property_read_string(np, "unit", &s)) + s = unit; + + if (s) { + event->unit = kstrdup(s, GFP_KERNEL); + if (!event->unit) + goto error; + } + + return event; +error: + kfree(event->unit); + kfree(event->scale); + kfree(event->name); + kfree(event); + + return NULL; +} + +/* + * update_events_in_group: Update the "events" information in an attr_group + * and assign the attr_group to the pmu "pmu". + */ +static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) +{ + struct attribute_group *attr_group; + struct attribute **attrs, *dev_str; + struct device_node *np, *pmu_events; + struct imc_events *ev; + u32 handle, base_reg; + int i=0, j=0, ct; + const char *prefix, *g_scale, *g_unit; + const char *ev_val_str, *ev_scale_str, *ev_unit_str; + + if (!of_property_read_u32(node, "events", &handle)) + pmu_events = of_find_node_by_phandle(handle); + else + return 0; + + /* Did not find any node with a given phandle */ + if (!pmu_events) + return 0; + + /* Get a count of number of child nodes */ + ct = of_get_child_count(pmu_events); + + /* Get the event prefix */ + if (of_property_read_string(node, "events-prefix", &prefix)) + return 0; + + /* Get a global unit and scale data if available */ + if (of_property_read_string(node, "scale", &g_scale)) + g_scale = NULL; + + if (of_property_read_string(node, "unit", &g_unit)) + g_unit = NULL; + + /* "reg" property gives out the base offset of the counters data */ + of_property_read_u32(node, "reg", &base_reg); + + /* Allocate memory for the events */ + pmu->events = kcalloc(ct, sizeof(struct imc_events), GFP_KERNEL); + if (!pmu->events) + return -ENOMEM; + + ct = 0; + /* Parse the events and update the struct */ + for_each_child_of_node(pmu_events, np) { + ev = imc_parse_event(np, g_scale, g_unit, prefix, base_reg); + if (ev) + pmu->events[ct++] = ev; + } + + /* Allocate memory for attribute group */ + attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); + if (!attr_group) + return -ENOMEM; + + /* + * Allocate memory for attributes. + * Since we have count of events for this pmu, we also allocate + * memory for the scale and unit attribute for now. + * "ct" has the total event structs added from the events-parent node. + * So allocate three times the "ct" (this includes event, event_scale and + * event_unit). + */ + attrs = kcalloc(((ct * 3) + 1), sizeof(struct attribute *), GFP_KERNEL); + if (!attrs) { + kfree(attr_group); + kfree(pmu->events); + return -ENOMEM; + } + + attr_group->name = "events"; + attr_group->attrs = attrs; + do { + ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i]->value); + dev_str = device_str_attr_create(pmu->events[i]->name, ev_val_str); + if (!dev_str) + continue; + + attrs[j++] = dev_str; + if (pmu->events[i]->scale) { + ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale",pmu->events[i]->name); + dev_str = device_str_attr_create(ev_scale_str, pmu->events[i]->scale); + if (!dev_str) + continue; + + attrs[j++] = dev_str; + } + + if (pmu->events[i]->unit) { + ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit",pmu->events[i]->name); + dev_str = device_str_attr_create(ev_unit_str, pmu->events[i]->unit); + if (!dev_str) + continue; + + attrs[j++] = dev_str; + } + } while (++i < ct); + + /* Save the event attribute */ + pmu->attr_groups[IMC_EVENT_ATTR] = attr_group; + + kfree(pmu->events); + return 0; +} + +/* get_nest_pmu_ref: Return the imc_pmu_ref struct for the given node */ +static struct imc_pmu_ref *get_nest_pmu_ref(int cpu) +{ + return per_cpu(local_nest_imc_refc, cpu); +} + +static void nest_change_cpu_context(int old_cpu, int new_cpu) +{ + struct imc_pmu **pn = per_nest_pmu_arr; + int i; + + if (old_cpu < 0 || new_cpu < 0) + return; + + for (i = 0; *pn && i < IMC_MAX_PMUS; i++, pn++) + perf_pmu_migrate_context(&(*pn)->pmu, old_cpu, new_cpu); +} + +static int ppc_nest_imc_cpu_offline(unsigned int cpu) +{ + int nid, target = -1; + const struct cpumask *l_cpumask; + struct imc_pmu_ref *ref; + + /* + * Check in the designated list for this cpu. Dont bother + * if not one of them. + */ + if (!cpumask_test_and_clear_cpu(cpu, &nest_imc_cpumask)) + return 0; + + /* + * Now that this cpu is one of the designated, + * find a next cpu a) which is online and b) in same chip. + */ + nid = cpu_to_node(cpu); + l_cpumask = cpumask_of_node(nid); + target = cpumask_any_but(l_cpumask, cpu); + + /* + * Update the cpumask with the target cpu and + * migrate the context if needed + */ + if (target >= 0 && target < nr_cpu_ids) { + cpumask_set_cpu(target, &nest_imc_cpumask); + nest_change_cpu_context(cpu, target); + } else { + opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(cpu)); + /* + * If this is the last cpu in this chip then, skip the reference + * count mutex lock and make the reference count on this chip zero. + */ + ref = get_nest_pmu_ref(cpu); + if (!ref) + return -EINVAL; + + ref->refc = 0; + } + return 0; +} + +static int ppc_nest_imc_cpu_online(unsigned int cpu) +{ + const struct cpumask *l_cpumask; + static struct cpumask tmp_mask; + int res; + + /* Get the cpumask of this node */ + l_cpumask = cpumask_of_node(cpu_to_node(cpu)); + + /* + * If this is not the first online CPU on this node, then + * just return. + */ + if (cpumask_and(&tmp_mask, l_cpumask, &nest_imc_cpumask)) + return 0; + + /* + * If this is the first online cpu on this node + * disable the nest counters by making an OPAL call. + */ + res = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(cpu)); + if (res) + return res; + + /* Make this CPU the designated target for counter collection */ + cpumask_set_cpu(cpu, &nest_imc_cpumask); + return 0; +} + +static int nest_pmu_cpumask_init(void) +{ + return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE, + "perf/powerpc/imc:online", + ppc_nest_imc_cpu_online, + ppc_nest_imc_cpu_offline); +} + +static void nest_imc_counters_release(struct perf_event *event) +{ + int rc, node_id; + struct imc_pmu_ref *ref; + + if (event->cpu < 0) + return; + + node_id = cpu_to_node(event->cpu); + + /* + * See if we need to disable the nest PMU. + * If no events are currently in use, then we have to take a + * mutex to ensure that we don't race with another task doing + * enable or disable the nest counters. + */ + ref = get_nest_pmu_ref(event->cpu); + if (!ref) + return; + + /* Take the mutex lock for this node and then decrement the reference count */ + mutex_lock(&ref->lock); + if (ref->refc == 0) { + /* + * The scenario where this is true is, when perf session is + * started, followed by offlining of all cpus in a given node. + * + * In the cpuhotplug offline path, ppc_nest_imc_cpu_offline() + * function set the ref->count to zero, if the cpu which is + * about to offline is the last cpu in a given node and make + * an OPAL call to disable the engine in that node. + * + */ + mutex_unlock(&ref->lock); + return; + } + ref->refc--; + if (ref->refc == 0) { + rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("nest-imc: Unable to stop the counters for core %d\n", node_id); + return; + } + } else if (ref->refc < 0) { + WARN(1, "nest-imc: Invalid event reference count\n"); + ref->refc = 0; + } + mutex_unlock(&ref->lock); +} + +static int nest_imc_event_init(struct perf_event *event) +{ + int chip_id, rc, node_id; + u32 l_config, config = event->attr.config; + struct imc_mem_info *pcni; + struct imc_pmu *pmu; + struct imc_pmu_ref *ref; + bool flag = false; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + pmu = imc_event_to_pmu(event); + + /* Sanity check for config (event offset) */ + if ((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size) + return -EINVAL; + + /* + * Nest HW counter memory resides in a per-chip reserve-memory (HOMER). + * Get the base memory addresss for this cpu. + */ + chip_id = topology_physical_package_id(event->cpu); + pcni = pmu->mem_info; + do { + if (pcni->id == chip_id) { + flag = true; + break; + } + pcni++; + } while (pcni); + + if (!flag) + return -ENODEV; + + /* + * Add the event offset to the base address. + */ + l_config = config & IMC_EVENT_OFFSET_MASK; + event->hw.event_base = (u64)pcni->vbase + l_config; + node_id = cpu_to_node(event->cpu); + + /* + * Get the imc_pmu_ref struct for this node. + * Take the mutex lock and then increment the count of nest pmu events + * inited. + */ + ref = get_nest_pmu_ref(event->cpu); + if (!ref) + return -EINVAL; + + mutex_lock(&ref->lock); + if (ref->refc == 0) { + rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("nest-imc: Unable to start the counters for node %d\n", + node_id); + return rc; + } + } + ++ref->refc; + mutex_unlock(&ref->lock); + + event->destroy = nest_imc_counters_release; + return 0; +} + +/* + * core_imc_mem_init : Initializes memory for the current core. + * + * Uses alloc_pages_node() and uses the returned address as an argument to + * an opal call to configure the pdbar. The address sent as an argument is + * converted to physical address before the opal call is made. This is the + * base address at which the core imc counters are populated. + */ +static int core_imc_mem_init(int cpu, int size) +{ + int phys_id, rc = 0, core_id = (cpu / threads_per_core); + struct imc_mem_info *mem_info; + + /* + * alloc_pages_node() will allocate memory for core in the + * local node only. + */ + phys_id = topology_physical_package_id(cpu); + mem_info = &core_imc_pmu->mem_info[core_id]; + mem_info->id = core_id; + + /* We need only vbase for core counters */ + mem_info->vbase = page_address(alloc_pages_node(phys_id, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | + __GFP_NOWARN, get_order(size))); + if (!mem_info->vbase) + return -ENOMEM; + + /* Init the mutex */ + core_imc_refc[core_id].id = core_id; + mutex_init(&core_imc_refc[core_id].lock); + + rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_CORE, + __pa((void *)mem_info->vbase), + get_hard_smp_processor_id(cpu)); + if (rc) { + free_pages((u64)mem_info->vbase, get_order(size)); + mem_info->vbase = NULL; + } + + return rc; +} + +static bool is_core_imc_mem_inited(int cpu) +{ + struct imc_mem_info *mem_info; + int core_id = (cpu / threads_per_core); + + mem_info = &core_imc_pmu->mem_info[core_id]; + if (!mem_info->vbase) + return false; + + return true; +} + +static int ppc_core_imc_cpu_online(unsigned int cpu) +{ + const struct cpumask *l_cpumask; + static struct cpumask tmp_mask; + int ret = 0; + + /* Get the cpumask for this core */ + l_cpumask = cpu_sibling_mask(cpu); + + /* If a cpu for this core is already set, then, don't do anything */ + if (cpumask_and(&tmp_mask, l_cpumask, &core_imc_cpumask)) + return 0; + + if (!is_core_imc_mem_inited(cpu)) { + ret = core_imc_mem_init(cpu, core_imc_pmu->counter_mem_size); + if (ret) { + pr_info("core_imc memory allocation for cpu %d failed\n", cpu); + return ret; + } + } + + /* set the cpu in the mask */ + cpumask_set_cpu(cpu, &core_imc_cpumask); + return 0; +} + +static int ppc_core_imc_cpu_offline(unsigned int cpu) +{ + unsigned int ncpu, core_id; + struct imc_pmu_ref *ref; + + /* + * clear this cpu out of the mask, if not present in the mask, + * don't bother doing anything. + */ + if (!cpumask_test_and_clear_cpu(cpu, &core_imc_cpumask)) + return 0; + + /* + * Check whether core_imc is registered. We could end up here + * if the cpuhotplug callback registration fails. i.e, callback + * invokes the offline path for all sucessfully registered cpus. + * At this stage, core_imc pmu will not be registered and we + * should return here. + * + * We return with a zero since this is not an offline failure. + * And cpuhp_setup_state() returns the actual failure reason + * to the caller, which inturn will call the cleanup routine. + */ + if (!core_imc_pmu->pmu.event_init) + return 0; + + /* Find any online cpu in that core except the current "cpu" */ + ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu); + + if (ncpu >= 0 && ncpu < nr_cpu_ids) { + cpumask_set_cpu(ncpu, &core_imc_cpumask); + perf_pmu_migrate_context(&core_imc_pmu->pmu, cpu, ncpu); + } else { + /* + * If this is the last cpu in this core then, skip taking refernce + * count mutex lock for this core and directly zero "refc" for + * this core. + */ + opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(cpu)); + core_id = cpu / threads_per_core; + ref = &core_imc_refc[core_id]; + if (!ref) + return -EINVAL; + + ref->refc = 0; + } + return 0; +} + +static int core_imc_pmu_cpumask_init(void) +{ + return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE, + "perf/powerpc/imc_core:online", + ppc_core_imc_cpu_online, + ppc_core_imc_cpu_offline); +} + +static void core_imc_counters_release(struct perf_event *event) +{ + int rc, core_id; + struct imc_pmu_ref *ref; + + if (event->cpu < 0) + return; + /* + * See if we need to disable the IMC PMU. + * If no events are currently in use, then we have to take a + * mutex to ensure that we don't race with another task doing + * enable or disable the core counters. + */ + core_id = event->cpu / threads_per_core; + + /* Take the mutex lock and decrement the refernce count for this core */ + ref = &core_imc_refc[core_id]; + if (!ref) + return; + + mutex_lock(&ref->lock); + if (ref->refc == 0) { + /* + * The scenario where this is true is, when perf session is + * started, followed by offlining of all cpus in a given core. + * + * In the cpuhotplug offline path, ppc_core_imc_cpu_offline() + * function set the ref->count to zero, if the cpu which is + * about to offline is the last cpu in a given core and make + * an OPAL call to disable the engine in that core. + * + */ + mutex_unlock(&ref->lock); + return; + } + ref->refc--; + if (ref->refc == 0) { + rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("IMC: Unable to stop the counters for core %d\n", core_id); + return; + } + } else if (ref->refc < 0) { + WARN(1, "core-imc: Invalid event reference count\n"); + ref->refc = 0; + } + mutex_unlock(&ref->lock); +} + +static int core_imc_event_init(struct perf_event *event) +{ + int core_id, rc; + u64 config = event->attr.config; + struct imc_mem_info *pcmi; + struct imc_pmu *pmu; + struct imc_pmu_ref *ref; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + event->hw.idx = -1; + pmu = imc_event_to_pmu(event); + + /* Sanity check for config (event offset) */ + if (((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size)) + return -EINVAL; + + if (!is_core_imc_mem_inited(event->cpu)) + return -ENODEV; + + core_id = event->cpu / threads_per_core; + pcmi = &core_imc_pmu->mem_info[core_id]; + if ((!pcmi->vbase)) + return -ENODEV; + + /* Get the core_imc mutex for this core */ + ref = &core_imc_refc[core_id]; + if (!ref) + return -EINVAL; + + /* + * Core pmu units are enabled only when it is used. + * See if this is triggered for the first time. + * If yes, take the mutex lock and enable the core counters. + * If not, just increment the count in core_imc_refc struct. + */ + mutex_lock(&ref->lock); + if (ref->refc == 0) { + rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(event->cpu)); + if (rc) { + mutex_unlock(&ref->lock); + pr_err("core-imc: Unable to start the counters for core %d\n", + core_id); + return rc; + } + } + ++ref->refc; + mutex_unlock(&ref->lock); + + event->hw.event_base = (u64)pcmi->vbase + (config & IMC_EVENT_OFFSET_MASK); + event->destroy = core_imc_counters_release; + return 0; +} + +/* + * Allocates a page of memory for each of the online cpus, and write the + * physical base address of that page to the LDBAR for that cpu. + * + * LDBAR Register Layout: + * + * 0 4 8 12 16 20 24 28 + * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | + * | | [ ] [ Counter Address [8:50] + * | * Mode | + * | * PB Scope + * * Enable/Disable + * + * 32 36 40 44 48 52 56 60 + * | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | - - - - | + * Counter Address [8:50] ] + * + */ +static int thread_imc_mem_alloc(int cpu_id, int size) +{ + u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, cpu_id); + int phys_id = topology_physical_package_id(cpu_id); + + if (!local_mem) { + /* + * This case could happen only once at start, since we dont + * free the memory in cpu offline path. + */ + local_mem = page_address(alloc_pages_node(phys_id, + GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | + __GFP_NOWARN, get_order(size))); + if (!local_mem) + return -ENOMEM; + + per_cpu(thread_imc_mem, cpu_id) = local_mem; + } + + ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | THREAD_IMC_ENABLE; + + mtspr(SPRN_LDBAR, ldbar_value); + return 0; +} + +static int ppc_thread_imc_cpu_online(unsigned int cpu) +{ + return thread_imc_mem_alloc(cpu, thread_imc_mem_size); +} + +static int ppc_thread_imc_cpu_offline(unsigned int cpu) +{ + mtspr(SPRN_LDBAR, 0); + return 0; +} + +static int thread_imc_cpu_init(void) +{ + return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE, + "perf/powerpc/imc_thread:online", + ppc_thread_imc_cpu_online, + ppc_thread_imc_cpu_offline); +} + +void thread_imc_pmu_sched_task(struct perf_event_context *ctx, + bool sched_in) +{ + int core_id; + struct imc_pmu_ref *ref; + + if (!is_core_imc_mem_inited(smp_processor_id())) + return; + + core_id = smp_processor_id() / threads_per_core; + /* + * imc pmus are enabled only when it is used. + * See if this is triggered for the first time. + * If yes, take the mutex lock and enable the counters. + * If not, just increment the count in ref count struct. + */ + ref = &core_imc_refc[core_id]; + if (!ref) + return; + + if (sched_in) { + mutex_lock(&ref->lock); + if (ref->refc == 0) { + if (opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(smp_processor_id()))) { + mutex_unlock(&ref->lock); + pr_err("thread-imc: Unable to start the counter\ + for core %d\n", core_id); + return; + } + } + ++ref->refc; + mutex_unlock(&ref->lock); + } else { + mutex_lock(&ref->lock); + ref->refc--; + if (ref->refc == 0) { + if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(smp_processor_id()))) { + mutex_unlock(&ref->lock); + pr_err("thread-imc: Unable to stop the counters\ + for core %d\n", core_id); + return; + } + } else if (ref->refc < 0) { + ref->refc = 0; + } + mutex_unlock(&ref->lock); + } + + return; +} + +static int thread_imc_event_init(struct perf_event *event) +{ + u32 config = event->attr.config; + struct task_struct *target; + struct imc_pmu *pmu; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported */ + if (event->hw.sample_period) + return -EINVAL; + + event->hw.idx = -1; + pmu = imc_event_to_pmu(event); + + /* Sanity check for config offset */ + if (((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size)) + return -EINVAL; + + target = event->hw.target; + if (!target) + return -EINVAL; + + event->pmu->task_ctx_nr = perf_sw_context; + return 0; +} + +static bool is_thread_imc_pmu(struct perf_event *event) +{ + if (!strncmp(event->pmu->name, "thread_imc", strlen("thread_imc"))) + return true; + + return false; +} + +static u64 * get_event_base_addr(struct perf_event *event) +{ + u64 addr; + + if (is_thread_imc_pmu(event)) { + addr = (u64)per_cpu(thread_imc_mem, smp_processor_id()); + return (u64 *)(addr + (event->attr.config & IMC_EVENT_OFFSET_MASK)); + } + + return (u64 *)event->hw.event_base; +} + +static void thread_imc_pmu_start_txn(struct pmu *pmu, + unsigned int txn_flags) +{ + if (txn_flags & ~PERF_PMU_TXN_ADD) + return; + perf_pmu_disable(pmu); +} + +static void thread_imc_pmu_cancel_txn(struct pmu *pmu) +{ + perf_pmu_enable(pmu); +} + +static int thread_imc_pmu_commit_txn(struct pmu *pmu) +{ + perf_pmu_enable(pmu); + return 0; +} + +static u64 imc_read_counter(struct perf_event *event) +{ + u64 *addr, data; + + /* + * In-Memory Collection (IMC) counters are free flowing counters. + * So we take a snapshot of the counter value on enable and save it + * to calculate the delta at later stage to present the event counter + * value. + */ + addr = get_event_base_addr(event); + data = be64_to_cpu(READ_ONCE(*addr)); + local64_set(&event->hw.prev_count, data); + + return data; +} + +static void imc_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count; + + counter_prev = local64_read(&event->hw.prev_count); + counter_new = imc_read_counter(event); + final_count = counter_new - counter_prev; + + /* Update the delta to the event count */ + local64_add(final_count, &event->count); +} + +static void imc_event_start(struct perf_event *event, int flags) +{ + /* + * In Memory Counters are free flowing counters. HW or the microcode + * keeps adding to the counter offset in memory. To get event + * counter value, we snapshot the value here and we calculate + * delta at later point. + */ + imc_read_counter(event); +} + +static void imc_event_stop(struct perf_event *event, int flags) +{ + /* + * Take a snapshot and calculate the delta and update + * the event counter values. + */ + imc_event_update(event); +} + +static int imc_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + imc_event_start(event, flags); + + return 0; +} + +static int thread_imc_event_add(struct perf_event *event, int flags) +{ + if (flags & PERF_EF_START) + imc_event_start(event, flags); + + /* Enable the sched_task to start the engine */ + perf_sched_cb_inc(event->ctx->pmu); + return 0; +} + +static void thread_imc_event_del(struct perf_event *event, int flags) +{ + /* + * Take a snapshot and calculate the delta and update + * the event counter values. + */ + imc_event_update(event); + perf_sched_cb_dec(event->ctx->pmu); +} + +/* update_pmu_ops : Populate the appropriate operations for "pmu" */ +static int update_pmu_ops(struct imc_pmu *pmu) +{ + pmu->pmu.task_ctx_nr = perf_invalid_context; + pmu->pmu.add = imc_event_add; + pmu->pmu.del = imc_event_stop; + pmu->pmu.start = imc_event_start; + pmu->pmu.stop = imc_event_stop; + pmu->pmu.read = imc_event_update; + pmu->pmu.attr_groups = pmu->attr_groups; + pmu->attr_groups[IMC_FORMAT_ATTR] = &imc_format_group; + + switch (pmu->domain) { + case IMC_DOMAIN_NEST: + pmu->pmu.event_init = nest_imc_event_init; + pmu->attr_groups[IMC_CPUMASK_ATTR] = &imc_pmu_cpumask_attr_group; + break; + case IMC_DOMAIN_CORE: + pmu->pmu.event_init = core_imc_event_init; + pmu->attr_groups[IMC_CPUMASK_ATTR] = &imc_pmu_cpumask_attr_group; + break; + case IMC_DOMAIN_THREAD: + pmu->pmu.event_init = thread_imc_event_init; + pmu->pmu.sched_task = thread_imc_pmu_sched_task; + pmu->pmu.add = thread_imc_event_add; + pmu->pmu.del = thread_imc_event_del; + pmu->pmu.start_txn = thread_imc_pmu_start_txn; + pmu->pmu.cancel_txn = thread_imc_pmu_cancel_txn; + pmu->pmu.commit_txn = thread_imc_pmu_commit_txn; + break; + default: + break; + } + + return 0; +} + +/* init_nest_pmu_ref: Initialize the imc_pmu_ref struct for all the nodes */ +static int init_nest_pmu_ref(void) +{ + int nid, i, cpu; + + nest_imc_refc = kcalloc(num_possible_nodes(), sizeof(*nest_imc_refc), + GFP_KERNEL); + + if (!nest_imc_refc) + return -ENOMEM; + + i = 0; + for_each_node(nid) { + /* + * Mutex lock to avoid races while tracking the number of + * sessions using the chip's nest pmu units. + */ + mutex_init(&nest_imc_refc[i].lock); + + /* + * Loop to init the "id" with the node_id. Variable "i" initialized to + * 0 and will be used as index to the array. "i" will not go off the + * end of the array since the "for_each_node" loops for "N_POSSIBLE" + * nodes only. + */ + nest_imc_refc[i++].id = nid; + } + + /* + * Loop to init the per_cpu "local_nest_imc_refc" with the proper + * "nest_imc_refc" index. This makes get_nest_pmu_ref() alot simple. + */ + for_each_possible_cpu(cpu) { + nid = cpu_to_node(cpu); + for (i = 0; i < num_possible_nodes(); i++) { + if (nest_imc_refc[i].id == nid) { + per_cpu(local_nest_imc_refc, cpu) = &nest_imc_refc[i]; + break; + } + } + } + return 0; +} + +static void cleanup_all_core_imc_memory(void) +{ + int i, nr_cores = DIV_ROUND_UP(num_present_cpus(), threads_per_core); + struct imc_mem_info *ptr = core_imc_pmu->mem_info; + int size = core_imc_pmu->counter_mem_size; + + /* mem_info will never be NULL */ + for (i = 0; i < nr_cores; i++) { + if (ptr[i].vbase) + free_pages((u64)ptr->vbase, get_order(size)); + } + + kfree(ptr); + kfree(core_imc_refc); +} + +static void thread_imc_ldbar_disable(void *dummy) +{ + /* + * By Zeroing LDBAR, we disable thread-imc + * updates. + */ + mtspr(SPRN_LDBAR, 0); +} + +void thread_imc_disable(void) +{ + on_each_cpu(thread_imc_ldbar_disable, NULL, 1); +} + +static void cleanup_all_thread_imc_memory(void) +{ + int i, order = get_order(thread_imc_mem_size); + + for_each_online_cpu(i) { + if (per_cpu(thread_imc_mem, i)) + free_pages((u64)per_cpu(thread_imc_mem, i), order); + + } +} + +/* + * Common function to unregister cpu hotplug callback and + * free the memory. + * TODO: Need to handle pmu unregistering, which will be + * done in followup series. + */ +static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr) +{ + if (pmu_ptr->domain == IMC_DOMAIN_NEST) { + mutex_lock(&nest_init_lock); + if (nest_pmus == 1) { + cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE); + kfree(nest_imc_refc); + } + + if (nest_pmus > 0) + nest_pmus--; + mutex_unlock(&nest_init_lock); + } + + /* Free core_imc memory */ + if (pmu_ptr->domain == IMC_DOMAIN_CORE) { + cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE); + cleanup_all_core_imc_memory(); + } + + /* Free thread_imc memory */ + if (pmu_ptr->domain == IMC_DOMAIN_THREAD) { + cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE); + cleanup_all_thread_imc_memory(); + } + + /* Only free the attr_groups which are dynamically allocated */ + if (pmu_ptr->attr_groups[IMC_EVENT_ATTR]) + kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs); + kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]); + kfree(pmu_ptr); + return; +} + + +/* + * imc_mem_init : Function to support memory allocation for core imc. + */ +static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent, + int pmu_index) +{ + const char *s; + int nr_cores, cpu, res; + + if (of_property_read_string(parent, "name", &s)) + return -ENODEV; + + switch (pmu_ptr->domain) { + case IMC_DOMAIN_NEST: + /* Update the pmu name */ + pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s_imc", "nest_", s); + if (!pmu_ptr->pmu.name) + return -ENOMEM; + + /* Needed for hotplug/migration */ + per_nest_pmu_arr[pmu_index] = pmu_ptr; + break; + case IMC_DOMAIN_CORE: + /* Update the pmu name */ + pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc"); + if (!pmu_ptr->pmu.name) + return -ENOMEM; + + nr_cores = DIV_ROUND_UP(num_present_cpus(), threads_per_core); + pmu_ptr->mem_info = kcalloc(nr_cores, sizeof(struct imc_mem_info), + GFP_KERNEL); + + if (!pmu_ptr->mem_info) + return -ENOMEM; + + core_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref), + GFP_KERNEL); + + if (!core_imc_refc) + return -ENOMEM; + + core_imc_pmu = pmu_ptr; + break; + case IMC_DOMAIN_THREAD: + /* Update the pmu name */ + pmu_ptr->pmu.name = kasprintf(GFP_KERNEL, "%s%s", s, "_imc"); + if (!pmu_ptr->pmu.name) + return -ENOMEM; + + thread_imc_mem_size = pmu_ptr->counter_mem_size; + for_each_online_cpu(cpu) { + res = thread_imc_mem_alloc(cpu, pmu_ptr->counter_mem_size); + if (res) + return res; + } + + thread_imc_pmu = pmu_ptr; + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * init_imc_pmu : Setup and register the IMC pmu device. + * + * @parent: Device tree unit node + * @pmu_ptr: memory allocated for this pmu + * @pmu_idx: Count of nest pmc registered + * + * init_imc_pmu() setup pmu cpumask and registers for a cpu hotplug callback. + * Handles failure cases and accordingly frees memory. + */ +int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_idx) +{ + int ret; + + ret = imc_mem_init(pmu_ptr, parent, pmu_idx); + if (ret) + goto err_free; + + switch (pmu_ptr->domain) { + case IMC_DOMAIN_NEST: + /* + * Nest imc pmu need only one cpu per chip, we initialize the + * cpumask for the first nest imc pmu and use the same for the + * rest. To handle the cpuhotplug callback unregister, we track + * the number of nest pmus in "nest_pmus". + */ + mutex_lock(&nest_init_lock); + if (nest_pmus == 0) { + ret = init_nest_pmu_ref(); + if (ret) { + mutex_unlock(&nest_init_lock); + goto err_free; + } + /* Register for cpu hotplug notification. */ + ret = nest_pmu_cpumask_init(); + if (ret) { + mutex_unlock(&nest_init_lock); + goto err_free; + } + } + nest_pmus++; + mutex_unlock(&nest_init_lock); + break; + case IMC_DOMAIN_CORE: + ret = core_imc_pmu_cpumask_init(); + if (ret) { + cleanup_all_core_imc_memory(); + return ret; + } + + break; + case IMC_DOMAIN_THREAD: + ret = thread_imc_cpu_init(); + if (ret) { + cleanup_all_thread_imc_memory(); + return ret; + } + + break; + default: + return -1; /* Unknown domain */ + } + + ret = update_events_in_group(parent, pmu_ptr); + if (ret) + goto err_free; + + ret = update_pmu_ops(pmu_ptr); + if (ret) + goto err_free; + + ret = perf_pmu_register(&pmu_ptr->pmu, pmu_ptr->pmu.name, -1); + if (ret) + goto err_free; + + pr_info("%s performance monitor hardware support registered\n", + pmu_ptr->pmu.name); + + return 0; + +err_free: + imc_common_cpuhp_mem_free(pmu_ptr); + return ret; +} diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 3f3aa9a7063a..2efee3f196f5 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -99,7 +99,7 @@ static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) else if (!cpu_has_feature(CPU_FTR_POWER9_DD1) && p9_SDAR_MODE(event)) *mmcra |= p9_SDAR_MODE(event) << MMCRA_SDAR_MODE_SHIFT; else - *mmcra |= MMCRA_SDAR_MODE_TLB; + *mmcra |= MMCRA_SDAR_MODE_DCACHE; } else *mmcra |= MMCRA_SDAR_MODE_TLB; } @@ -488,8 +488,8 @@ static int find_alternative(u64 event, const unsigned int ev_alt[][MAX_ALT], int return -1; } -int isa207_get_alternatives(u64 event, u64 alt[], - const unsigned int ev_alt[][MAX_ALT], int size) +int isa207_get_alternatives(u64 event, u64 alt[], int size, unsigned int flags, + const unsigned int ev_alt[][MAX_ALT]) { int i, j, num_alt = 0; u64 alt_event; @@ -505,5 +505,30 @@ int isa207_get_alternatives(u64 event, u64 alt[], } } + if (flags & PPMU_ONLY_COUNT_RUN) { + /* + * We're only counting in RUN state, so PM_CYC is equivalent to + * PM_RUN_CYC and PM_INST_CMPL === PM_RUN_INST_CMPL. + */ + j = num_alt; + for (i = 0; i < num_alt; ++i) { + switch (alt[i]) { + case 0x1e: /* PMC_CYC */ + alt[j++] = 0x600f4; /* PM_RUN_CYC */ + break; + case 0x600f4: + alt[j++] = 0x1e; + break; + case 0x2: /* PM_INST_CMPL */ + alt[j++] = 0x500fa; /* PM_RUN_INST_CMPL */ + break; + case 0x500fa: + alt[j++] = 0x2; + break; + } + } + num_alt = j; + } + return num_alt; } diff --git a/arch/powerpc/perf/isa207-common.h b/arch/powerpc/perf/isa207-common.h index 8acbe6e802c7..6c737d675792 100644 --- a/arch/powerpc/perf/isa207-common.h +++ b/arch/powerpc/perf/isa207-common.h @@ -247,6 +247,7 @@ #define MMCRA_SDAR_MODE_SHIFT 42 #define MMCRA_SDAR_MODE_TLB (1ull << MMCRA_SDAR_MODE_SHIFT) #define MMCRA_SDAR_MODE_NO_UPDATES ~(0x3ull << MMCRA_SDAR_MODE_SHIFT) +#define MMCRA_SDAR_MODE_DCACHE (2ull << MMCRA_SDAR_MODE_SHIFT) #define MMCRA_IFM_SHIFT 30 #define MMCRA_THR_CTR_MANT_SHIFT 19 #define MMCRA_THR_CTR_MANT_MASK 0x7Ful @@ -287,8 +288,8 @@ int isa207_compute_mmcr(u64 event[], int n_ev, unsigned int hwc[], unsigned long mmcr[], struct perf_event *pevents[]); void isa207_disable_pmc(unsigned int pmc, unsigned long mmcr[]); -int isa207_get_alternatives(u64 event, u64 alt[], - const unsigned int ev_alt[][MAX_ALT], int size); +int isa207_get_alternatives(u64 event, u64 alt[], int size, unsigned int flags, + const unsigned int ev_alt[][MAX_ALT]); void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, u32 flags, struct pt_regs *regs); void isa207_get_mem_weight(u64 *weight); diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 5463516e369b..c9356955cab4 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c @@ -50,34 +50,11 @@ static const unsigned int event_alternatives[][MAX_ALT] = { static int power8_get_alternatives(u64 event, unsigned int flags, u64 alt[]) { - int i, j, num_alt = 0; + int num_alt = 0; - num_alt = isa207_get_alternatives(event, alt, event_alternatives, - (int)ARRAY_SIZE(event_alternatives)); - if (flags & PPMU_ONLY_COUNT_RUN) { - /* - * We're only counting in RUN state, so PM_CYC is equivalent to - * PM_RUN_CYC and PM_INST_CMPL === PM_RUN_INST_CMPL. - */ - j = num_alt; - for (i = 0; i < num_alt; ++i) { - switch (alt[i]) { - case PM_CYC: - alt[j++] = PM_RUN_CYC; - break; - case PM_RUN_CYC: - alt[j++] = PM_CYC; - break; - case PM_INST_CMPL: - alt[j++] = PM_RUN_INST_CMPL; - break; - case PM_RUN_INST_CMPL: - alt[j++] = PM_INST_CMPL; - break; - } - } - num_alt = j; - } + num_alt = isa207_get_alternatives(event, alt, + ARRAY_SIZE(event_alternatives), flags, + event_alternatives); return num_alt; } diff --git a/arch/powerpc/perf/power9-events-list.h b/arch/powerpc/perf/power9-events-list.h index 50689180a6c1..e99c6bf4d391 100644 --- a/arch/powerpc/perf/power9-events-list.h +++ b/arch/powerpc/perf/power9-events-list.h @@ -16,13 +16,16 @@ EVENT(PM_CYC, 0x0001e) EVENT(PM_ICT_NOSLOT_CYC, 0x100f8) EVENT(PM_CMPLU_STALL, 0x1e054) EVENT(PM_INST_CMPL, 0x00002) -EVENT(PM_BRU_CMPL, 0x4d05e) +EVENT(PM_BR_CMPL, 0x4d05e) EVENT(PM_BR_MPRED_CMPL, 0x400f6) /* All L1 D cache load references counted at finish, gated by reject */ EVENT(PM_LD_REF_L1, 0x100fc) /* Load Missed L1 */ EVENT(PM_LD_MISS_L1_FIN, 0x2c04e) +EVENT(PM_LD_MISS_L1, 0x3e054) +/* Alternate event code for PM_LD_MISS_L1 */ +EVENT(PM_LD_MISS_L1_ALT, 0x400f0) /* Store Missed L1 */ EVENT(PM_ST_MISS_L1, 0x300f0) /* L1 cache data prefetches */ @@ -62,3 +65,7 @@ EVENT(PM_INST_DISP, 0x200f2) EVENT(PM_INST_DISP_ALT, 0x300f2) /* Alternate Branch event code */ EVENT(PM_BR_CMPL_ALT, 0x10012) +/* Branch event that are not strongly biased */ +EVENT(PM_BR_2PATH, 0x20036) +/* ALternate branch event that are not strongly biased */ +EVENT(PM_BR_2PATH_ALT, 0x40036) diff --git a/arch/powerpc/perf/power9-pmu.c b/arch/powerpc/perf/power9-pmu.c index 2280cf87ff9c..24b5b5b7a206 100644 --- a/arch/powerpc/perf/power9-pmu.c +++ b/arch/powerpc/perf/power9-pmu.c @@ -109,14 +109,17 @@ static const unsigned int power9_event_alternatives[][MAX_ALT] = { { PM_INST_DISP, PM_INST_DISP_ALT }, { PM_RUN_CYC_ALT, PM_RUN_CYC }, { PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL }, + { PM_LD_MISS_L1, PM_LD_MISS_L1_ALT }, + { PM_BR_2PATH, PM_BR_2PATH_ALT }, }; static int power9_get_alternatives(u64 event, unsigned int flags, u64 alt[]) { int num_alt = 0; - num_alt = isa207_get_alternatives(event, alt, power9_event_alternatives, - (int)ARRAY_SIZE(power9_event_alternatives)); + num_alt = isa207_get_alternatives(event, alt, + ARRAY_SIZE(power9_event_alternatives), flags, + power9_event_alternatives); return num_alt; } @@ -125,7 +128,7 @@ GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_ICT_NOSLOT_CYC); GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL); GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); -GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_CMPL); +GENERIC_EVENT_ATTR(branch-instructions, PM_BR_CMPL); GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL); GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1_FIN); @@ -143,7 +146,7 @@ CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL); CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS); CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST); CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL); -CACHE_EVENT_ATTR(branch-loads, PM_BRU_CMPL); +CACHE_EVENT_ATTR(branch-loads, PM_BR_CMPL); CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS); CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS); @@ -152,7 +155,7 @@ static struct attribute *power9_events_attr[] = { GENERIC_EVENT_PTR(PM_ICT_NOSLOT_CYC), GENERIC_EVENT_PTR(PM_CMPLU_STALL), GENERIC_EVENT_PTR(PM_INST_CMPL), - GENERIC_EVENT_PTR(PM_BRU_CMPL), + GENERIC_EVENT_PTR(PM_BR_CMPL), GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL), GENERIC_EVENT_PTR(PM_LD_REF_L1), GENERIC_EVENT_PTR(PM_LD_MISS_L1_FIN), @@ -169,7 +172,7 @@ static struct attribute *power9_events_attr[] = { CACHE_EVENT_PTR(PM_L2_ST_MISS), CACHE_EVENT_PTR(PM_L2_ST), CACHE_EVENT_PTR(PM_BR_MPRED_CMPL), - CACHE_EVENT_PTR(PM_BRU_CMPL), + CACHE_EVENT_PTR(PM_BR_CMPL), CACHE_EVENT_PTR(PM_DTLB_MISS), CACHE_EVENT_PTR(PM_ITLB_MISS), NULL @@ -244,7 +247,7 @@ static int power9_generic_events[] = { [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_ICT_NOSLOT_CYC, [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL, [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_CMPL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_CMPL, [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL, [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1_FIN, @@ -370,7 +373,7 @@ static int power9_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { }, [ C(BPU) ] = { [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = PM_BRU_CMPL, + [ C(RESULT_ACCESS) ] = PM_BR_CMPL, [ C(RESULT_MISS) ] = PM_BR_MPRED_CMPL, }, [ C(OP_WRITE) ] = { @@ -459,8 +462,8 @@ static int __init init_power9_pmu(void) * Power9 DD1 should use PM_BR_CMPL_ALT event code for * "branches" to provide correct counter value. */ - EVENT_VAR(PM_BRU_CMPL, _g).id = PM_BR_CMPL_ALT; - EVENT_VAR(PM_BRU_CMPL, _c).id = PM_BR_CMPL_ALT; + EVENT_VAR(PM_BR_CMPL, _g).id = PM_BR_CMPL_ALT; + EVENT_VAR(PM_BR_CMPL, _c).id = PM_BR_CMPL_ALT; rc = register_power_pmu(&power9_isa207_pmu); } else { rc = register_power_pmu(&power9_pmu); diff --git a/arch/powerpc/perf/req-gen/_begin.h b/arch/powerpc/perf/req-gen/_begin.h index acfb17a55c16..549f8782c52d 100644 --- a/arch/powerpc/perf/req-gen/_begin.h +++ b/arch/powerpc/perf/req-gen/_begin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Include paths to be used in interface defining headers */ #ifndef POWERPC_PERF_REQ_GEN_H_ #define POWERPC_PERF_REQ_GEN_H_ diff --git a/arch/powerpc/perf/req-gen/_clear.h b/arch/powerpc/perf/req-gen/_clear.h index 422974f89573..67c3859157f3 100644 --- a/arch/powerpc/perf/req-gen/_clear.h +++ b/arch/powerpc/perf/req-gen/_clear.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef __field_ #undef __count_ diff --git a/arch/powerpc/perf/req-gen/_request-begin.h b/arch/powerpc/perf/req-gen/_request-begin.h index f6d98642cf1d..7c74c2ab4c0c 100644 --- a/arch/powerpc/perf/req-gen/_request-begin.h +++ b/arch/powerpc/perf/req-gen/_request-begin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define REQUEST(r_contents) \ REQUEST_(REQUEST_NAME, REQUEST_NUM, REQUEST_IDX_KIND, I(r_contents)) diff --git a/arch/powerpc/perf/req-gen/_request-end.h b/arch/powerpc/perf/req-gen/_request-end.h index 5573be6c3588..7d9f4046c2ca 100644 --- a/arch/powerpc/perf/req-gen/_request-end.h +++ b/arch/powerpc/perf/req-gen/_request-end.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef REQUEST #undef __field #undef __array diff --git a/arch/powerpc/perf/req-gen/perf.h b/arch/powerpc/perf/req-gen/perf.h index 1b122469323d..871a9a1766c2 100644 --- a/arch/powerpc/perf/req-gen/perf.h +++ b/arch/powerpc/perf/req-gen/perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ #define LINUX_POWERPC_PERF_REQ_GEN_PERF_H_ diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index abc24501c4c0..60254a321a91 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config ACADIA bool "Acadia" depends on 40x diff --git a/arch/powerpc/platforms/44x/44x.h b/arch/powerpc/platforms/44x/44x.h index 63f703ecd23c..0e912a6a0b9a 100644 --- a/arch/powerpc/platforms/44x/44x.h +++ b/arch/powerpc/platforms/44x/44x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __POWERPC_PLATFORMS_44X_44X_H #define __POWERPC_PLATFORMS_44X_44X_H diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 01cb109ebf17..a6011422b861 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_47x bool "Support for 47x variant" depends on 44x diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index 72b824160660..1b78c6af821a 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -1,6 +1,7 @@ -obj-$(CONFIG_44x) += misc_44x.o +# SPDX-License-Identifier: GPL-2.0 +obj-y += misc_44x.o machine_check.o ifneq ($(CONFIG_PPC4xx_CPM),y) -obj-$(CONFIG_44x) += idle.o +obj-y += idle.o endif obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o obj-$(CONFIG_EBONY) += ebony.o diff --git a/arch/powerpc/platforms/44x/machine_check.c b/arch/powerpc/platforms/44x/machine_check.c new file mode 100644 index 000000000000..034d70d6d335 --- /dev/null +++ b/arch/powerpc/platforms/44x/machine_check.c @@ -0,0 +1,89 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +#include + +int machine_check_440A(struct pt_regs *regs) +{ + unsigned long reason = regs->dsisr; + + printk("Machine check in kernel mode.\n"); + if (reason & ESR_IMCP){ + printk("Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } + else { + u32 mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk("Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk("Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk("Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk("TLB Parity Error\n"); + if (mcsr & MCSR_ICP){ + flush_instruction_cache(); + printk("I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk("D-Cache Search Parity Error\n"); + if (mcsr & MCSR_DCFP) + printk("D-Cache Flush Parity Error\n"); + if (mcsr & MCSR_IMPE) + printk("Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + } + return 0; +} + +#ifdef CONFIG_PPC_47x +int machine_check_47x(struct pt_regs *regs) +{ + unsigned long reason = regs->dsisr; + u32 mcsr; + + printk(KERN_ERR "Machine check in kernel mode.\n"); + if (reason & ESR_IMCP) { + printk(KERN_ERR "Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + return 0; + } + mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk(KERN_ERR "Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk(KERN_ERR "Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk(KERN_ERR "Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk(KERN_ERR "TLB Parity Error\n"); + if (mcsr & MCSR_ICP) { + flush_instruction_cache(); + printk(KERN_ERR "I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk(KERN_ERR "D-Cache Search Parity Error\n"); + if (mcsr & PPC47x_MCSR_GPR) + printk(KERN_ERR "GPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_FPR) + printk(KERN_ERR "FPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_IPR) + printk(KERN_ERR "Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + + return 0; +} +#endif /* CONFIG_PPC_47x */ diff --git a/arch/powerpc/platforms/44x/virtex_ml510.c b/arch/powerpc/platforms/44x/virtex_ml510.c index 1fdb8748638d..349f218b335c 100644 --- a/arch/powerpc/platforms/44x/virtex_ml510.c +++ b/arch/powerpc/platforms/44x/virtex_ml510.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "44x.h" diff --git a/arch/powerpc/platforms/4xx/Makefile b/arch/powerpc/platforms/4xx/Makefile new file mode 100644 index 000000000000..9779c32db34e --- /dev/null +++ b/arch/powerpc/platforms/4xx/Makefile @@ -0,0 +1,8 @@ +obj-y += uic.o machine_check.o +obj-$(CONFIG_PPC4xx_OCM) += ocm.o +obj-$(CONFIG_4xx_SOC) += soc.o +obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_PPC4xx_HSTA_MSI) += hsta_msi.o +obj-$(CONFIG_PPC4xx_MSI) += msi.o +obj-$(CONFIG_PPC4xx_CPM) += cpm.o +obj-$(CONFIG_PPC4xx_GPIO) += gpio.o diff --git a/arch/powerpc/sysdev/ppc4xx_cpm.c b/arch/powerpc/platforms/4xx/cpm.c similarity index 97% rename from arch/powerpc/sysdev/ppc4xx_cpm.c rename to arch/powerpc/platforms/4xx/cpm.c index ba95adf81d8d..53ff81ca8a3c 100644 --- a/arch/powerpc/sysdev/ppc4xx_cpm.c +++ b/arch/powerpc/platforms/4xx/cpm.c @@ -240,7 +240,7 @@ static int cpm_suspend_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops cpm_suspend_ops = { +static const struct platform_suspend_ops cpm_suspend_ops = { .valid = cpm_suspend_valid, .enter = cpm_suspend_enter, }; @@ -278,8 +278,8 @@ static int __init cpm_init(void) dcr_len = dcr_resource_len(np, 0); if (dcr_base == 0 || dcr_len == 0) { - printk(KERN_ERR "cpm: could not parse dcr property for %s\n", - np->full_name); + printk(KERN_ERR "cpm: could not parse dcr property for %pOF\n", + np); ret = -EINVAL; goto node_put; } @@ -287,8 +287,8 @@ static int __init cpm_init(void) cpm.dcr_host = dcr_map(np, dcr_base, dcr_len); if (!DCR_MAP_OK(cpm.dcr_host)) { - printk(KERN_ERR "cpm: failed to map dcr property for %s\n", - np->full_name); + printk(KERN_ERR "cpm: failed to map dcr property for %pOF\n", + np); ret = -EINVAL; goto node_put; } diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/platforms/4xx/gpio.c similarity index 98% rename from arch/powerpc/sysdev/ppc4xx_gpio.c rename to arch/powerpc/platforms/4xx/gpio.c index 5382d04dd872..2238e369cde4 100644 --- a/arch/powerpc/sysdev/ppc4xx_gpio.c +++ b/arch/powerpc/platforms/4xx/gpio.c @@ -198,8 +198,7 @@ static int __init ppc4xx_add_gpiochips(void) goto err; continue; err: - pr_err("%s: registration failed with status %d\n", - np->full_name, ret); + pr_err("%pOF: registration failed with status %d\n", np, ret); kfree(ppc4xx_gc); /* try others anyway */ } diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/platforms/4xx/hsta_msi.c similarity index 100% rename from arch/powerpc/sysdev/ppc4xx_hsta_msi.c rename to arch/powerpc/platforms/4xx/hsta_msi.c diff --git a/arch/powerpc/platforms/4xx/machine_check.c b/arch/powerpc/platforms/4xx/machine_check.c new file mode 100644 index 000000000000..aa039dfaf82f --- /dev/null +++ b/arch/powerpc/platforms/4xx/machine_check.c @@ -0,0 +1,26 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +#include + +int machine_check_4xx(struct pt_regs *regs) +{ + unsigned long reason = regs->dsisr; + + if (reason & ESR_IMCP) { + printk("Instruction"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } else + printk("Data"); + printk(" machine check in kernel mode.\n"); + + return 0; +} diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/platforms/4xx/msi.c similarity index 98% rename from arch/powerpc/sysdev/ppc4xx_msi.c rename to arch/powerpc/platforms/4xx/msi.c index 590dab4f47d6..d50417e23add 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/platforms/4xx/msi.c @@ -233,8 +233,7 @@ static int ppc4xx_msi_probe(struct platform_device *dev) /* Get MSI ranges */ err = of_address_to_resource(dev->dev.of_node, 0, &res); if (err) { - dev_err(&dev->dev, "%s resource error!\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF resource error!\n", dev->dev.of_node); goto error_out; } diff --git a/arch/powerpc/sysdev/ppc4xx_ocm.c b/arch/powerpc/platforms/4xx/ocm.c similarity index 100% rename from arch/powerpc/sysdev/ppc4xx_ocm.c rename to arch/powerpc/platforms/4xx/ocm.c diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/platforms/4xx/pci.c similarity index 95% rename from arch/powerpc/sysdev/ppc4xx_pci.c rename to arch/powerpc/platforms/4xx/pci.c index 086aca69ecae..73e6b36bcd51 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/platforms/4xx/pci.c @@ -32,7 +32,7 @@ #include #include -#include "ppc4xx_pci.h" +#include "pci.h" static int dma_offset_set; @@ -127,9 +127,9 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, * within 32 bits space */ if (cpu_addr != 0 || pci_addr > 0xffffffff) { - printk(KERN_WARNING "%s: Ignored unsupported dma range" + printk(KERN_WARNING "%pOF: Ignored unsupported dma range" " 0x%016llx...0x%016llx -> 0x%016llx\n", - hose->dn->full_name, + hose->dn, pci_addr, pci_addr + size - 1, cpu_addr); continue; } @@ -152,8 +152,7 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, /* We only support one global DMA offset */ if (dma_offset_set && pci_dram_offset != res->start) { - printk(KERN_ERR "%s: dma-ranges(s) mismatch\n", - hose->dn->full_name); + printk(KERN_ERR "%pOF: dma-ranges(s) mismatch\n", hose->dn); return -ENXIO; } @@ -161,17 +160,16 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, * DMA bounce buffers */ if (size < total_memory) { - printk(KERN_ERR "%s: dma-ranges too small " + printk(KERN_ERR "%pOF: dma-ranges too small " "(size=%llx total_memory=%llx)\n", - hose->dn->full_name, size, (u64)total_memory); + hose->dn, size, (u64)total_memory); return -ENXIO; } /* Check we are a power of 2 size and that base is a multiple of size*/ if ((size & (size - 1)) != 0 || (res->start & (size - 1)) != 0) { - printk(KERN_ERR "%s: dma-ranges unaligned\n", - hose->dn->full_name); + printk(KERN_ERR "%pOF: dma-ranges unaligned\n", hose->dn); return -ENXIO; } @@ -181,8 +179,8 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, if (res->end > 0xffffffff && !(of_device_is_compatible(hose->dn, "ibm,plb-pciex-460sx") || of_device_is_compatible(hose->dn, "ibm,plb-pciex-476fpe"))) { - printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n", - hose->dn->full_name); + printk(KERN_ERR "%pOF: dma-ranges outside of 32 bits space\n", + hose->dn); return -ENXIO; } out: @@ -233,8 +231,7 @@ static int __init ppc4xx_setup_one_pci_PMM(struct pci_controller *hose, */ if ((plb_addr + size) > 0xffffffffull || !is_power_of_2(size) || size < 0x1000 || (plb_addr & (size - 1)) != 0) { - printk(KERN_WARNING "%s: Resource out of range\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Resource out of range\n", hose->dn); return -1; } ma = (0xffffffffu << ilog2(size)) | 1; @@ -266,8 +263,7 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, if (!(res->flags & IORESOURCE_MEM)) continue; if (j > 2) { - printk(KERN_WARNING "%s: Too many ranges\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Too many ranges\n", hose->dn); break; } @@ -292,8 +288,8 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, if (j <= 2 && !found_isa_hole && hose->isa_mem_size) if (ppc4xx_setup_one_pci_PMM(hose, reg, hose->isa_mem_phys, 0, hose->isa_mem_size, 0, j) == 0) - printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", - hose->dn->full_name); + printk(KERN_INFO "%pOF: Legacy ISA memory support enabled\n", + hose->dn); } static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, @@ -333,21 +329,20 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np) /* Check if device is enabled */ if (!of_device_is_available(np)) { - printk(KERN_INFO "%s: Port disabled via device-tree\n", - np->full_name); + printk(KERN_INFO "%pOF: Port disabled via device-tree\n", np); return; } /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &rsrc_cfg)) { - printk(KERN_ERR "%s: Can't get PCI config register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI config register base !", + np); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 3, &rsrc_reg)) { - printk(KERN_ERR "%s: Can't get PCI internal register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI internal register base !", + np); return; } @@ -361,7 +356,7 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np) /* Map registers */ reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); if (reg == NULL) { - printk(KERN_ERR "%s: Can't map registers !", np->full_name); + printk(KERN_ERR "%pOF: Can't map registers !", np); goto fail; } @@ -423,8 +418,8 @@ static int __init ppc4xx_setup_one_pcix_POM(struct pci_controller *hose, if (!is_power_of_2(size) || size < 0x1000 || (plb_addr & (size - 1)) != 0) { - printk(KERN_WARNING "%s: Resource out of range\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Resource out of range\n", + hose->dn); return -1; } @@ -467,8 +462,7 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, if (!(res->flags & IORESOURCE_MEM)) continue; if (j > 1) { - printk(KERN_WARNING "%s: Too many ranges\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Too many ranges\n", hose->dn); break; } @@ -493,8 +487,8 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, if (j <= 1 && !found_isa_hole && hose->isa_mem_size) if (ppc4xx_setup_one_pcix_POM(hose, reg, hose->isa_mem_phys, 0, hose->isa_mem_size, 0, j) == 0) - printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", - hose->dn->full_name); + printk(KERN_INFO "%pOF: Legacy ISA memory support enabled\n", + hose->dn); } static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, @@ -539,14 +533,14 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &rsrc_cfg)) { - printk(KERN_ERR "%s:Can't get PCI-X config register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI-X config register base !", + np); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 3, &rsrc_reg)) { - printk(KERN_ERR "%s: Can't get PCI-X internal register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI-X internal register base !", + np); return; } @@ -568,7 +562,7 @@ static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) /* Map registers */ reg = ioremap(rsrc_reg.start, resource_size(&rsrc_reg)); if (reg == NULL) { - printk(KERN_ERR "%s: Can't map registers !", np->full_name); + printk(KERN_ERR "%pOF: Can't map registers !", np); goto fail; } @@ -1246,8 +1240,8 @@ static void __init ppc460sx_pciex_check_link(struct ppc4xx_pciex_port *port) mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); if (mbase == NULL) { - printk(KERN_ERR "%s: Can't map internal config space !", - port->node->full_name); + printk(KERN_ERR "%pOF: Can't map internal config space !", + port->node); goto done; } @@ -1389,7 +1383,7 @@ static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port) port->index); return; } - + while (timeout_ms--) { val = in_le32(mbase + PECFG_TLDLP); @@ -1448,8 +1442,7 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) ppc4xx_pciex_hwops = &ppc_476fpe_pcie_hwops; #endif if (ppc4xx_pciex_hwops == NULL) { - printk(KERN_WARNING "PCIE: unknown host type %s\n", - np->full_name); + printk(KERN_WARNING "PCIE: unknown host type %pOF\n", np); return -ENODEV; } @@ -1730,8 +1723,7 @@ static int __init ppc4xx_setup_one_pciex_POM(struct ppc4xx_pciex_port *port, (index < 2 && size < 0x100000) || (index == 2 && size < 0x100) || (plb_addr & (size - 1)) != 0) { - printk(KERN_WARNING "%s: Resource out of range\n", - hose->dn->full_name); + printk(KERN_WARNING "%pOF: Resource out of range\n", hose->dn); return -1; } @@ -1807,8 +1799,8 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, if (!(res->flags & IORESOURCE_MEM)) continue; if (j > 1) { - printk(KERN_WARNING "%s: Too many ranges\n", - port->node->full_name); + printk(KERN_WARNING "%pOF: Too many ranges\n", + port->node); break; } @@ -1834,8 +1826,8 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, if (ppc4xx_setup_one_pciex_POM(port, hose, mbase, hose->isa_mem_phys, 0, hose->isa_mem_size, 0, j) == 0) - printk(KERN_INFO "%s: Legacy ISA memory support enabled\n", - hose->dn->full_name); + printk(KERN_INFO "%pOF: Legacy ISA memory support enabled\n", + hose->dn); /* Configure IO, always 64K starting at 0. We hard wire it to 64K ! * Note also that it -has- to be region index 2 on this HW @@ -1970,8 +1962,8 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) (hose->first_busno + 1) * 0x100000, busses * 0x100000); if (cfg_data == NULL) { - printk(KERN_ERR "%s: Can't map external config space !", - port->node->full_name); + printk(KERN_ERR "%pOF: Can't map external config space !", + port->node); goto fail; } hose->cfg_data = cfg_data; @@ -1982,13 +1974,13 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) */ mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); if (mbase == NULL) { - printk(KERN_ERR "%s: Can't map internal config space !", - port->node->full_name); + printk(KERN_ERR "%pOF: Can't map internal config space !", + port->node); goto fail; } hose->cfg_addr = mbase; - pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name, + pr_debug("PCIE %pOF, bus %d..%d\n", port->node, hose->first_busno, hose->last_busno); pr_debug(" config space mapped at: root @0x%p, other @0x%p\n", hose->cfg_addr, hose->cfg_data); @@ -2100,14 +2092,13 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) /* Get the port number from the device-tree */ pval = of_get_property(np, "port", NULL); if (pval == NULL) { - printk(KERN_ERR "PCIE: Can't find port number for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: Can't find port number for %pOF\n", np); return; } portno = *pval; if (portno >= ppc4xx_pciex_port_count) { - printk(KERN_ERR "PCIE: port number out of range for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: port number out of range for %pOF\n", + np); return; } port = &ppc4xx_pciex_ports[portno]; @@ -2125,8 +2116,8 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) if (ppc4xx_pciex_hwops->want_sdr) { pval = of_get_property(np, "sdr-base", NULL); if (pval == NULL) { - printk(KERN_ERR "PCIE: missing sdr-base for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: missing sdr-base for %pOF\n", + np); return; } port->sdr_base = *pval; @@ -2142,29 +2133,26 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) } else if (!strcmp(val, "pci")) { port->endpoint = 0; } else { - printk(KERN_ERR "PCIE: missing or incorrect device_type for %s\n", - np->full_name); + printk(KERN_ERR "PCIE: missing or incorrect device_type for %pOF\n", + np); return; } /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &port->cfg_space)) { - printk(KERN_ERR "%s: Can't get PCI-E config space !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get PCI-E config space !", np); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 1, &port->utl_regs)) { - printk(KERN_ERR "%s: Can't get UTL register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get UTL register base !", np); return; } /* Map DCRs */ dcrs = dcr_resource_start(np, 0); if (dcrs == 0) { - printk(KERN_ERR "%s: Can't get DCR register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get DCR register base !", np); return; } port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/platforms/4xx/pci.h similarity index 100% rename from arch/powerpc/sysdev/ppc4xx_pci.h rename to arch/powerpc/platforms/4xx/pci.h diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/platforms/4xx/soc.c similarity index 97% rename from arch/powerpc/sysdev/ppc4xx_soc.c rename to arch/powerpc/platforms/4xx/soc.c index d41134d2f786..5e36508b2a70 100644 --- a/arch/powerpc/sysdev/ppc4xx_soc.c +++ b/arch/powerpc/platforms/4xx/soc.c @@ -90,7 +90,7 @@ static int __init ppc4xx_l2c_probe(void) /* Get l2 cache size */ prop = of_get_property(np, "cache-size", NULL); if (prop == NULL) { - printk(KERN_ERR "%s: Can't get cache-size!\n", np->full_name); + printk(KERN_ERR "%pOF: Can't get cache-size!\n", np); of_node_put(np); return -ENODEV; } @@ -99,8 +99,7 @@ static int __init ppc4xx_l2c_probe(void) /* Map DCRs */ dcrreg = of_get_property(np, "dcr-reg", &len); if (!dcrreg || (len != 4 * sizeof(u32))) { - printk(KERN_ERR "%s: Can't get DCR register base !", - np->full_name); + printk(KERN_ERR "%pOF: Can't get DCR register base !", np); of_node_put(np); return -ENODEV; } diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/platforms/4xx/uic.c similarity index 95% rename from arch/powerpc/sysdev/uic.c rename to arch/powerpc/platforms/4xx/uic.c index a00949f3e378..8b4dd0da0839 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/platforms/4xx/uic.c @@ -243,16 +243,16 @@ static struct uic * __init uic_init_one(struct device_node *node) raw_spin_lock_init(&uic->lock); indexp = of_get_property(node, "cell-index", &len); if (!indexp || (len != sizeof(u32))) { - printk(KERN_ERR "uic: Device node %s has missing or invalid " - "cell-index property\n", node->full_name); + printk(KERN_ERR "uic: Device node %pOF has missing or invalid " + "cell-index property\n", node); return NULL; } uic->index = *indexp; dcrreg = of_get_property(node, "dcr-reg", &len); if (!dcrreg || (len != 2*sizeof(u32))) { - printk(KERN_ERR "uic: Device node %s has missing or invalid " - "dcr-reg property\n", node->full_name); + printk(KERN_ERR "uic: Device node %pOF has missing or invalid " + "dcr-reg property\n", node); return NULL; } uic->dcrbase = *dcrreg; @@ -292,7 +292,7 @@ void __init uic_init_tree(void) * top-level interrupt controller */ primary_uic = uic_init_one(np); if (!primary_uic) - panic("Unable to initialize primary UIC %s\n", np->full_name); + panic("Unable to initialize primary UIC %pOF\n", np); irq_set_default_host(primary_uic->irqhost); of_node_put(np); @@ -306,8 +306,8 @@ void __init uic_init_tree(void) uic = uic_init_one(np); if (! uic) - panic("Unable to initialize a secondary UIC %s\n", - np->full_name); + panic("Unable to initialize a secondary UIC %pOF\n", + np); cascade_virq = irq_of_parse_and_map(np, 0); diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index bf7ae5cbd07a..b59eab6cbb1b 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_MPC512x bool "512x-based boards" depends on 6xx diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index f47d422953df..2daf22ee26a0 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Freescale PowerPC 512x linux kernel. # diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c index add5a5374fa0..b3097fe6441b 100644 --- a/arch/powerpc/platforms/512x/clock-commonclk.c +++ b/arch/powerpc/platforms/512x/clock-commonclk.c @@ -363,7 +363,7 @@ static int get_cpmf_mult_x2(void) */ /* applies to the IPS_DIV, and PCI_DIV values */ -static struct clk_div_table divtab_2346[] = { +static const struct clk_div_table divtab_2346[] = { { .val = 2, .div = 2, }, { .val = 3, .div = 3, }, { .val = 4, .div = 4, }, @@ -372,7 +372,7 @@ static struct clk_div_table divtab_2346[] = { }; /* applies to the MBX_DIV, LPC_DIV, and NFC_DIV values */ -static struct clk_div_table divtab_1234[] = { +static const struct clk_div_table divtab_1234[] = { { .val = 1, .div = 1, }, { .val = 2, .div = 2, }, { .val = 3, .div = 3, }, diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index 6b4f4cb7009a..f99e79ee060e 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -387,8 +387,8 @@ static unsigned int __init get_fifo_size(struct device_node *np, if (fp) return *fp; - pr_warning("no %s property in %s node, defaulting to %d\n", - prop_name, np->full_name, DEFAULT_FIFO_SIZE); + pr_warning("no %s property in %pOF node, defaulting to %d\n", + prop_name, np, DEFAULT_FIFO_SIZE); return DEFAULT_FIFO_SIZE; } @@ -426,15 +426,15 @@ static void __init mpc512x_psc_fifo_init(void) psc = of_iomap(np, 0); if (!psc) { - pr_err("%s: Can't map %s device\n", - __func__, np->full_name); + pr_err("%s: Can't map %pOF device\n", + __func__, np); continue; } /* FIFO space is 4KiB, check if requested size is available */ if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { - pr_err("%s: no fifo space available for %s\n", - __func__, np->full_name); + pr_err("%s: no fifo space available for %pOF\n", + __func__, np); iounmap(psc); /* * chances are that another device requests less diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig index e4c745981912..55a587070342 100644 --- a/arch/powerpc/platforms/52xx/Kconfig +++ b/arch/powerpc/platforms/52xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_MPC52xx bool "52xx-based boards" depends on 6xx diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile index 4e62486791e9..ff2f86fe5429 100644 --- a/arch/powerpc/platforms/52xx/Makefile +++ b/arch/powerpc/platforms/52xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for 52xx based boards # diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c index 39b49822ace1..1ecbf176d35a 100644 --- a/arch/powerpc/platforms/52xx/efika.c +++ b/arch/powerpc/platforms/52xx/efika.c @@ -99,7 +99,7 @@ static void __init efika_pcisetup(void) bus_range = of_get_property(pcictrl, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Can't get bus-range for %s\n", pcictrl->full_name); + ": Can't get bus-range for %pOF\n", pcictrl); goto out_put; } @@ -109,14 +109,14 @@ static void __init efika_pcisetup(void) else printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", bus_range[0], bus_range[1]); - printk(" controlled by %s\n", pcictrl->full_name); + printk(" controlled by %pOF\n", pcictrl); printk("\n"); hose = pcibios_alloc_controller(pcictrl); if (!hose) { printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Can't allocate PCI controller structure for %s\n", - pcictrl->full_name); + ": Can't allocate PCI controller structure for %pOF\n", + pcictrl); goto out_put; } diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index 870b70f5d1bd..e7da22d1df87 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/platforms/52xx/lite5200_sleep.S b/arch/powerpc/platforms/52xx/lite5200_sleep.S index 08ab6fefcf7a..3a9969c429b3 100644 --- a/arch/powerpc/platforms/52xx/lite5200_sleep.S +++ b/arch/powerpc/platforms/52xx/lite5200_sleep.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c index a3227040cc86..1fcab233d2f2 100644 --- a/arch/powerpc/platforms/52xx/media5200.c +++ b/arch/powerpc/platforms/52xx/media5200.c @@ -156,7 +156,7 @@ static void __init media5200_init_irq(void) fpga_np = of_find_compatible_node(NULL, NULL, "fsl,media5200-fpga"); if (!fpga_np) goto out; - pr_debug("%s: found fpga node: %s\n", __func__, fpga_np->full_name); + pr_debug("%s: found fpga node: %pOF\n", __func__, fpga_np); media5200_irq.regs = of_iomap(fpga_np, 0); if (!media5200_irq.regs) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index 22645a7c6b8a..9e974b1e1697 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c @@ -226,7 +226,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct, dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]); if ((intsize < 1) || (intspec[0] > 3)) { - dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name); + dev_err(gpt->dev, "bad irq specifier in %pOF\n", ct); return -EINVAL; } @@ -331,7 +331,7 @@ mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node) if (!of_find_property(node, "gpio-controller", NULL)) return; - gpt->gc.label = kstrdup(node->full_name, GFP_KERNEL); + gpt->gc.label = kasprintf(GFP_KERNEL, "%pOF", node); if (!gpt->gc.label) { dev_err(gpt->dev, "out of memory\n"); return; diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index 00282c2b0cae..af0f79995214 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -369,19 +369,19 @@ mpc52xx_add_bridge(struct device_node *node) const int *bus_range; struct resource rsrc; - pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); + pr_debug("Adding MPC52xx PCI host bridge %pOF\n", node); pci_add_flags(PCI_REASSIGN_ALL_BUS); if (of_address_to_resource(node, 0, &rsrc) != 0) { - printk(KERN_ERR "Can't get %s resources\n", node->full_name); + printk(KERN_ERR "Can't get %pOF resources\n", node); return -EINVAL; } bus_range = of_get_property(node, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get %s bus-range, assume bus 0\n", - node->full_name); + printk(KERN_WARNING "Can't get %pOF bus-range, assume bus 0\n", + node); bus_range = NULL; } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index 8310e8b5b57f..31d3515672f3 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/platforms/52xx/mpc52xx_sleep.S b/arch/powerpc/platforms/52xx/mpc52xx_sleep.S index 4dc170b0ae18..a66eb311b639 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_sleep.S +++ b/arch/powerpc/platforms/52xx/mpc52xx_sleep.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig index 994d1a959e20..6e04099361b9 100644 --- a/arch/powerpc/platforms/82xx/Kconfig +++ b/arch/powerpc/platforms/82xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig PPC_82xx bool "82xx-based boards (PQ II)" depends on 6xx diff --git a/arch/powerpc/platforms/82xx/Makefile b/arch/powerpc/platforms/82xx/Makefile index 455fe21e37c4..8d713c601bf2 100644 --- a/arch/powerpc/platforms/82xx/Makefile +++ b/arch/powerpc/platforms/82xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PowerPC 82xx linux kernel. # diff --git a/arch/powerpc/platforms/82xx/pq2.h b/arch/powerpc/platforms/82xx/pq2.h index 3080ce3441c1..902ef0bd4949 100644 --- a/arch/powerpc/platforms/82xx/pq2.h +++ b/arch/powerpc/platforms/82xx/pq2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PQ2_H #define _PQ2_H diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index 4ef7f1cd05b7..7e38b7b71a5a 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig PPC_83xx bool "83xx-based boards" depends on 6xx diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index ed95bfcbcbff..bb4720897f6a 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PowerPC 83xx linux kernel. # diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 63c5ab6489c9..96bb55ca61d3 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -128,7 +128,7 @@ static int mcu_gpiochip_add(struct mcu *mcu) return -ENODEV; gc->owner = THIS_MODULE; - gc->label = np->full_name; + gc->label = kasprintf(GFP_KERNEL, "%pOF", np); gc->can_sleep = 1; gc->ngpio = MCU_NUM_GPIO; gc->base = -1; @@ -141,6 +141,7 @@ static int mcu_gpiochip_add(struct mcu *mcu) static int mcu_gpiochip_remove(struct mcu *mcu) { + kfree(mcu->gc.label); gpiochip_remove(&mcu->gc); return 0; } diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c index 763ffca9628d..a4539c5accb0 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -113,7 +113,7 @@ static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk, unreg: platform_device_del(pdev); err: - pr_err("%s: registration failed\n", np->full_name); + pr_err("%pOF: registration failed\n", np); next: i++; } diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index 636eb9d0401a..459145623334 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MPC83XX_H__ #define __MPC83XX_H__ diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 978b85bb3233..7fa3e197871a 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -361,7 +361,7 @@ static int pmc_probe(struct platform_device *ofdev) return -EBUSY; } - pmc_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc)); + pmc_regs = ioremap(res.start, sizeof(*pmc_regs)); if (!pmc_regs) { ret = -ENOMEM; @@ -374,7 +374,7 @@ static int pmc_probe(struct platform_device *ofdev) goto out_pmc; } - clock_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc)); + clock_regs = ioremap(res.start, sizeof(*clock_regs)); if (!clock_regs) { ret = -ENOMEM; diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 47b389dc4938..68920d42b4bc 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig FSL_SOC_BOOKE bool "Freescale Book-E Machine Type" depends on PPC_85xx || PPC_BOOK3E diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index fe19dad568e2..d1dd0dca5ebf 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PowerPC 85xx linux kernel. # diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h index 39056f6befeb..fa23f9b0592c 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx.h +++ b/arch/powerpc/platforms/85xx/mpc85xx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef MPC85xx_H #define MPC85xx_H extern int mpc85xx_common_publish_devices(void); diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 0908abd7e36f..9fb57f78cdbe 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -508,8 +508,8 @@ static void __init p1022_ds_setup_arch(void) * allocate one static local variable for each * call to this function. */ - pr_info("p1022ds: disabling %s node", - np2->full_name); + pr_info("p1022ds: disabling %pOF node", + np2); of_update_property(np2, &nor_status); of_node_put(np2); } @@ -524,8 +524,8 @@ static void __init p1022_ds_setup_arch(void) .length = sizeof("disabled"), }; - pr_info("p1022ds: disabling %s node", - np2->full_name); + pr_info("p1022ds: disabling %pOF node", + np2); of_update_property(np2, &nand_status); of_node_put(np2); } diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h index 0b20ae315c53..3936ff6dfbdb 100644 --- a/arch/powerpc/platforms/85xx/smp.h +++ b/arch/powerpc/platforms/85xx/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef POWERPC_85XX_SMP_H_ #define POWERPC_85XX_SMP_H_ 1 diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c index cd6ce845f398..77e618dce4a8 100644 --- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c @@ -100,8 +100,8 @@ static void xes_mpc85xx_fixups(void) err = of_address_to_resource(np, 0, &r[0]); if (err) { printk(KERN_WARNING "xes_mpc85xx: Could not get " - "resource for device tree node '%s'", - np->full_name); + "resource for device tree node '%pOF'", + np); continue; } diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index ce619bd1f82d..bcd179d3ed92 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_86xx menuconfig PPC_86xx bool "86xx-based boards" diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index 01958fedc3f2..2c04449be107 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PowerPC 86xx linux kernel. # diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig index 80cbcb0ad9b1..e2089d3de00c 100644 --- a/arch/powerpc/platforms/8xx/Kconfig +++ b/arch/powerpc/platforms/8xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config CPM1 bool select CPM @@ -5,7 +6,6 @@ config CPM1 choice prompt "8xx Machine Type" depends on PPC_8xx - depends on 8xx default MPC885ADS config MPC8XXFADS @@ -92,7 +92,7 @@ endmenu # menu "MPC8xx CPM Options" - depends on 8xx + depends on PPC_8xx # This doesn't really belong here, but it is convenient to ask # 8xx specific questions. diff --git a/arch/powerpc/platforms/8xx/Makefile b/arch/powerpc/platforms/8xx/Makefile index 76a81c3350a8..708ab099e886 100644 --- a/arch/powerpc/platforms/8xx/Makefile +++ b/arch/powerpc/platforms/8xx/Makefile @@ -1,7 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PowerPC 8xx linux kernel. # -obj-$(CONFIG_PPC_8xx) += m8xx_setup.o +obj-y += m8xx_setup.o machine_check.o pic.o obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o obj-$(CONFIG_PPC_EP88XC) += ep88xc.o diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c index f81069f79a94..e1274db53d48 100644 --- a/arch/powerpc/platforms/8xx/m8xx_setup.c +++ b/arch/powerpc/platforms/8xx/m8xx_setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1995 Linus Torvalds * Adapted from 'alpha' version by Gary Thomas @@ -23,7 +24,7 @@ #include #include -#include +#include "pic.h" #include "mpc8xx.h" diff --git a/arch/powerpc/platforms/8xx/machine_check.c b/arch/powerpc/platforms/8xx/machine_check.c new file mode 100644 index 000000000000..402016705a39 --- /dev/null +++ b/arch/powerpc/platforms/8xx/machine_check.c @@ -0,0 +1,37 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include + +#include + +int machine_check_8xx(struct pt_regs *regs) +{ + unsigned long reason = regs->msr; + + pr_err("Machine check in kernel mode.\n"); + pr_err("Caused by (from SRR1=%lx): ", reason); + if (reason & 0x40000000) + pr_err("Fetch error at address %lx\n", regs->nip); + else + pr_err("Data access error at address %lx\n", regs->dar); + +#ifdef CONFIG_PCI + /* the qspan pci read routines can cause machine checks -- Cort + * + * yuck !!! that totally needs to go away ! There are better ways + * to deal with that than having a wart in the mcheck handler. + * -- BenH + */ + bad_page_fault(regs, regs->dar, SIGBUS); + return 1; +#else + return 0; +#endif +} diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/platforms/8xx/pic.c similarity index 99% rename from arch/powerpc/sysdev/mpc8xx_pic.c rename to arch/powerpc/platforms/8xx/pic.c index 2842f9d63d21..8d5a25d43ef3 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/platforms/8xx/pic.c @@ -9,7 +9,7 @@ #include #include -#include "mpc8xx_pic.h" +#include "pic.h" #define PIC_VEC_SPURRIOUS 15 diff --git a/arch/powerpc/sysdev/mpc8xx_pic.h b/arch/powerpc/platforms/8xx/pic.h similarity index 100% rename from arch/powerpc/sysdev/mpc8xx_pic.h rename to arch/powerpc/platforms/8xx/pic.h diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 4fd64d3f5c44..d5e34ce5fd5d 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Platform support" source "arch/powerpc/platforms/powernv/Kconfig" diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 2f629e0551e9..a78f255111f2 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC64 bool "64-bit kernel" default n @@ -32,7 +33,6 @@ config PPC_85xx config PPC_8xx bool "Freescale 8xx" select FSL_SOC - select 8xx select PPC_LIB_RHEAP select SYS_SUPPORTS_HUGETLBFS @@ -149,10 +149,6 @@ config 6xx depends on PPC32 && PPC_BOOK3S select PPC_HAVE_PMU_SUPPORT -# this is temp to handle compat with arch=ppc -config 8xx - bool - config E500 select FSL_EMB_PERFMON select PPC_FSL_BOOK3E @@ -271,44 +267,6 @@ config VSX If in doubt, say Y here. -config PPC_ICSWX - bool "Support for PowerPC icswx coprocessor instruction" - depends on PPC_BOOK3S_64 - default n - ---help--- - - This option enables kernel support for the PowerPC Initiate - Coprocessor Store Word (icswx) coprocessor instruction on POWER7 - and POWER8 processors. POWER9 uses new copy/paste instructions - to invoke the coprocessor. - - This option is only useful if you have a processor that supports - the icswx coprocessor instruction. It does not have any effect - on processors without the icswx coprocessor instruction. - - This option slightly increases kernel memory usage. - - If in doubt, say N here. - -config PPC_ICSWX_PID - bool "icswx requires direct PID management" - depends on PPC_ICSWX - default y - ---help--- - The PID register in server is used explicitly for ICSWX. In - embedded systems PID management is done by the system. - -config PPC_ICSWX_USE_SIGILL - bool "Should a bad CT cause a SIGILL?" - depends on PPC_ICSWX - default n - ---help--- - Should a bad CT used for "non-record form ICSWX" cause an - illegal instruction signal or should it be silent as - architected. - - If in doubt, say N here. - config SPE_POSSIBLE def_bool y depends on E200 || (E500 && !PPC_E500MC) @@ -413,7 +371,7 @@ config NR_CPUS config NOT_COHERENT_CACHE bool - depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON + depends on 4xx || PPC_8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON default n if PPC_47x default y diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 469ef170d218..e46bb7ea710f 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror @@ -5,6 +6,7 @@ obj-$(CONFIG_FSL_ULI1575) += fsl_uli1575.o obj-$(CONFIG_PPC_PMAC) += powermac/ obj-$(CONFIG_PPC_CHRP) += chrp/ +obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_40x) += 40x/ obj-$(CONFIG_44x) += 44x/ obj-$(CONFIG_PPC_MPC512x) += 512x/ diff --git a/arch/powerpc/platforms/amigaone/Kconfig b/arch/powerpc/platforms/amigaone/Kconfig index 128de25cc284..03dc1e37c25b 100644 --- a/arch/powerpc/platforms/amigaone/Kconfig +++ b/arch/powerpc/platforms/amigaone/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config AMIGAONE bool "Eyetech AmigaOne/MAI Teron" depends on 6xx && BROKEN_ON_SMP diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c index 45cb9821173c..b9d466cc2b8a 100644 --- a/arch/powerpc/platforms/amigaone/setup.c +++ b/arch/powerpc/platforms/amigaone/setup.c @@ -40,7 +40,7 @@ static int __init amigaone_add_bridge(struct device_node *dev) const int *bus_range; struct pci_controller *hose; - printk(KERN_INFO "Adding PCI host bridge %s\n", dev->full_name); + printk(KERN_INFO "Adding PCI host bridge %pOF\n", dev); cfg_addr = of_get_address(dev, 0, NULL, NULL); cfg_data = of_get_address(dev, 1, NULL, NULL); @@ -49,8 +49,8 @@ static int __init amigaone_add_bridge(struct device_node *dev) bus_range = of_get_property(dev, "bus-range", &len); if ((bus_range == NULL) || (len < 2 * sizeof(int))) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); hose = pcibios_alloc_controller(dev); if (hose == NULL) diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index a4522f09d65e..9f5958f16923 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_CELL bool default n diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 00464305763d..d5f808e8a5f3 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PPC_CELL_COMMON) += cbe_regs.o interrupt.o pervasive.o obj-$(CONFIG_PPC_CELL_NATIVE) += iommu.o setup.o spider-pic.o \ diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c index 8d3ae2cc52bf..6ea3f248b155 100644 --- a/arch/powerpc/platforms/cell/axon_msi.c +++ b/arch/powerpc/platforms/cell/axon_msi.c @@ -187,8 +187,8 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev) irq_domain = irq_find_host(dn); if (!irq_domain) { - dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n", - dn->full_name); + dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %pOF\n", + dn); goto out_error; } @@ -326,8 +326,8 @@ static void axon_msi_shutdown(struct platform_device *device) struct axon_msic *msic = dev_get_drvdata(&device->dev); u32 tmp; - pr_devel("axon_msi: disabling %s\n", - irq_domain_get_of_node(msic->irq_domain)->full_name); + pr_devel("axon_msi: disabling %pOF\n", + irq_domain_get_of_node(msic->irq_domain)); tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG); tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE; msic_dcr_write(msic, MSIC_CTRL_REG, tmp); @@ -340,12 +340,12 @@ static int axon_msi_probe(struct platform_device *device) unsigned int virq; int dcr_base, dcr_len; - pr_devel("axon_msi: setting up dn %s\n", dn->full_name); + pr_devel("axon_msi: setting up dn %pOF\n", dn); msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL); if (!msic) { - printk(KERN_ERR "axon_msi: couldn't allocate msic for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: couldn't allocate msic for %pOF\n", + dn); goto out; } @@ -354,30 +354,30 @@ static int axon_msi_probe(struct platform_device *device) if (dcr_base == 0 || dcr_len == 0) { printk(KERN_ERR - "axon_msi: couldn't parse dcr properties on %s\n", - dn->full_name); + "axon_msi: couldn't parse dcr properties on %pOF\n", + dn); goto out_free_msic; } msic->dcr_host = dcr_map(dn, dcr_base, dcr_len); if (!DCR_MAP_OK(msic->dcr_host)) { - printk(KERN_ERR "axon_msi: dcr_map failed for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: dcr_map failed for %pOF\n", + dn); goto out_free_msic; } msic->fifo_virt = dma_alloc_coherent(&device->dev, MSIC_FIFO_SIZE_BYTES, &msic->fifo_phys, GFP_KERNEL); if (!msic->fifo_virt) { - printk(KERN_ERR "axon_msi: couldn't allocate fifo for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: couldn't allocate fifo for %pOF\n", + dn); goto out_free_msic; } virq = irq_of_parse_and_map(dn, 0); if (!virq) { - printk(KERN_ERR "axon_msi: irq parse and map failed for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: irq parse and map failed for %pOF\n", + dn); goto out_free_fifo; } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); @@ -385,8 +385,8 @@ static int axon_msi_probe(struct platform_device *device) /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); if (!msic->irq_domain) { - printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", - dn->full_name); + printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %pOF\n", + dn); goto out_free_fifo; } @@ -412,7 +412,7 @@ static int axon_msi_probe(struct platform_device *device) axon_msi_debug_setup(dn, msic); - printk(KERN_DEBUG "axon_msi: setup MSIC on %s\n", dn->full_name); + printk(KERN_DEBUG "axon_msi: setup MSIC on %pOF\n", dn); return 0; diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 871d38479a25..6fc85e29dc08 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -303,8 +303,8 @@ static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr, iic->node = of_node_get(node); out_be64(&iic->regs->prio, 0); - printk(KERN_INFO "IIC for CPU %d target id 0x%x : %s\n", - hw_cpu, iic->target_id, node->full_name); + printk(KERN_INFO "IIC for CPU %d target id 0x%x : %pOF\n", + hw_cpu, iic->target_id, node); } static int __init setup_iic(void) diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h index 4f60ae6ca358..a47902248541 100644 --- a/arch/powerpc/platforms/cell/interrupt.h +++ b/arch/powerpc/platforms/cell/interrupt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_CELL_PIC_H #define ASM_CELL_PIC_H #ifdef __KERNEL__ diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 29d4f96ed33e..4b91ad08eefd 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -278,8 +278,8 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base) if (of_node_to_nid(np) != nid) continue; if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "iommu: can't get address for %s\n", - np->full_name); + printk(KERN_ERR "iommu: can't get address for %pOF\n", + np); continue; } *base = r.start; @@ -458,8 +458,8 @@ static inline u32 cell_iommu_get_ioid(struct device_node *np) ioid = of_get_property(np, "ioid", NULL); if (ioid == NULL) { - printk(KERN_WARNING "iommu: missing ioid for %s using 0\n", - np->full_name); + printk(KERN_WARNING "iommu: missing ioid for %pOF using 0\n", + np); return 0; } @@ -559,8 +559,8 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev) */ iommu = cell_iommu_for_node(dev_to_node(dev)); if (iommu == NULL || list_empty(&iommu->windows)) { - dev_err(dev, "iommu: missing iommu for %s (node %d)\n", - of_node_full_name(dev->of_node), dev_to_node(dev)); + dev_err(dev, "iommu: missing iommu for %pOF (node %d)\n", + dev->of_node, dev_to_node(dev)); return NULL; } window = list_entry(iommu->windows.next, struct iommu_window, list); @@ -720,12 +720,12 @@ static struct cbe_iommu * __init cell_iommu_alloc(struct device_node *np) /* Get node ID */ nid = of_node_to_nid(np); if (nid < 0) { - printk(KERN_ERR "iommu: failed to get node for %s\n", - np->full_name); + printk(KERN_ERR "iommu: failed to get node for %pOF\n", + np); return NULL; } - pr_debug("iommu: setting up iommu for node %d (%s)\n", - nid, np->full_name); + pr_debug("iommu: setting up iommu for node %d (%pOF)\n", + nid, np); /* XXX todo: If we can have multiple windows on the same IOMMU, which * isn't the case today, we probably want here to check whether the @@ -736,8 +736,8 @@ static struct cbe_iommu * __init cell_iommu_alloc(struct device_node *np) */ if (cbe_nr_iommus >= NR_IOMMUS) { - printk(KERN_ERR "iommu: too many IOMMUs detected ! (%s)\n", - np->full_name); + printk(KERN_ERR "iommu: too many IOMMUs detected ! (%pOF)\n", + np); return NULL; } diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 460ab392f0e7..2f704afe9af3 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -196,8 +196,8 @@ static int __init cbe_ptcal_enable(void) for_each_node_by_type(np, "cpu") { const u32 *nid = of_get_property(np, "node-id", NULL); if (!nid) { - printk(KERN_ERR "%s: node %s is missing node-id?\n", - __func__, np->full_name); + printk(KERN_ERR "%s: node %pOF is missing node-id?\n", + __func__, np); continue; } cbe_ptcal_enable_on_node(*nid, order); diff --git a/arch/powerpc/platforms/cell/ras.h b/arch/powerpc/platforms/cell/ras.h index eb7ee54c82a0..6c2e6bc0062e 100644 --- a/arch/powerpc/platforms/cell/ras.h +++ b/arch/powerpc/platforms/cell/ras.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef RAS_H #define RAS_H diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c index f1f7878893f3..d1e61e273e64 100644 --- a/arch/powerpc/platforms/cell/spider-pci.c +++ b/arch/powerpc/platforms/cell/spider-pci.c @@ -130,8 +130,8 @@ int __init spiderpci_iowa_init(struct iowa_bus *bus, void *data) struct resource r; unsigned long offset = (unsigned long)data; - pr_debug("SPIDERPCI-IOWA:Bus initialize for spider(%s)\n", - np->full_name); + pr_debug("SPIDERPCI-IOWA:Bus initialize for spider(%pOF)\n", + np); priv = kzalloc(sizeof(struct spiderpci_iowa_private), GFP_KERNEL); if (!priv) { diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c index ff924af00e78..aa44bfc46467 100644 --- a/arch/powerpc/platforms/cell/spider-pic.c +++ b/arch/powerpc/platforms/cell/spider-pic.c @@ -323,8 +323,8 @@ static void __init spider_init_one(struct device_node *of_node, int chip, irq_set_handler_data(virq, pic); irq_set_chained_handler(virq, spider_irq_cascade); - printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %s\n", - pic->node_id, addr, of_node->full_name); + printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %pOF\n", + pic->node_id, addr, of_node); /* Enable the interrupt detection enable bit. Do this last! */ out_be32(pic->regs + TIR_DEN, in_be32(pic->regs + TIR_DEN) | 0x1); diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 672d310dcf14..f636ee22b203 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -191,8 +191,8 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) goto err; } ret = -EINVAL; - pr_debug(" irq %d no 0x%x on %s\n", i, oirq.args[0], - oirq.np->full_name); + pr_debug(" irq %d no 0x%x on %pOF\n", i, oirq.args[0], + oirq.np); spu->irqs[i] = irq_create_of_mapping(&oirq); if (!spu->irqs[i]) { pr_debug("spu_new: failed to map it !\n"); @@ -243,32 +243,32 @@ static int __init spu_map_device(struct spu *spu) ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, &spu->local_store_phys); if (ret) { - pr_debug("spu_new: failed to map %s resource 0\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 0\n", + np); goto out; } ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, &spu->problem_phys); if (ret) { - pr_debug("spu_new: failed to map %s resource 1\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 1\n", + np); goto out_unmap; } ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); if (ret) { - pr_debug("spu_new: failed to map %s resource 2\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 2\n", + np); goto out_unmap; } if (!firmware_has_feature(FW_FEATURE_LPAR)) ret = spu_map_resource(spu, 3, (void __iomem**)&spu->priv1, NULL); if (ret) { - pr_debug("spu_new: failed to map %s resource 3\n", - np->full_name); + pr_debug("spu_new: failed to map %pOF resource 3\n", + np); goto out_unmap; } - pr_debug("spu_new: %s maps:\n", np->full_name); + pr_debug("spu_new: %pOF maps:\n", np); pr_debug(" local store : 0x%016lx -> 0x%p\n", spu->local_store_phys, spu->local_store); pr_debug(" problem state : 0x%016lx -> 0x%p\n", @@ -316,8 +316,8 @@ static int __init of_create_spu(struct spu *spu, void *data) spu->node = of_node_to_nid(spe); if (spu->node >= MAX_NUMNODES) { - printk(KERN_WARNING "SPE %s on node %d ignored," - " node number too big\n", spe->full_name, spu->node); + printk(KERN_WARNING "SPE %pOF on node %d ignored," + " node number too big\n", spe, spu->node); printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); ret = -ENODEV; goto out; diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile index 52a7d2596d30..52e4c80ec8d0 100644 --- a/arch/powerpc/platforms/cell/spufs/Makefile +++ b/arch/powerpc/platforms/cell/spufs/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SPU_FS) += spufs.o spufs-y += inode.o file.o context.o syscalls.o diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index ae2f740a82f1..5ffcdeb1eb17 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1749,7 +1749,7 @@ out: static int spufs_mfc_fsync(struct file *file, loff_t start, loff_t end, int datasync) { struct inode *inode = file_inode(file); - int err = filemap_write_and_wait_range(inode->i_mapping, start, end); + int err = file_write_and_wait_range(file, start, end); if (!err) { inode_lock(inode); err = spufs_mfc_flush(file, NULL); diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index cfacbee24d7b..07f82d7395ff 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define DEBUG #include diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.h b/arch/powerpc/platforms/cell/spufs/sputrace.h index db2656aa4103..d557e999b662 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.h +++ b/arch/powerpc/platforms/cell/spufs/sputrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_SPUFS_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_SPUFS_H diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index 0d290ea83dc1..157e046e6e93 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig index d3cdab582c5d..ead99eff875a 100644 --- a/arch/powerpc/platforms/chrp/Kconfig +++ b/arch/powerpc/platforms/chrp/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_CHRP bool "Common Hardware Reference Platform (CHRP) based machines" depends on 6xx diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 63f0aee4c158..a5a7c338caf9 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Declarations of CHRP platform-specific things. */ diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 1b87e198faa7..0f512d35f7c5 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * CHRP pci routines. */ @@ -235,14 +236,14 @@ chrp_find_bridges(void) ++index; /* The GG2 bridge on the LongTrail doesn't have an address */ if (of_address_to_resource(dev, 0, &r) && !is_longtrail) { - printk(KERN_WARNING "Can't use %s: no address\n", - dev->full_name); + printk(KERN_WARNING "Can't use %pOF: no address\n", + dev); continue; } bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF\n", + dev); continue; } if (bus_range[1] == bus_range[0]) @@ -250,15 +251,15 @@ chrp_find_bridges(void) else printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); - printk(" controlled by %s", dev->full_name); + printk(" controlled by %pOF", dev); if (!is_longtrail) printk(" at %llx", (unsigned long long)r.start); printk("\n"); hose = pcibios_alloc_controller(dev); if (!hose) { - printk("Can't allocate PCI controller structure for %s\n", - dev->full_name); + printk("Can't allocate PCI controller structure for %pOF\n", + dev); continue; } hose->first_busno = hose->self_busno = bus_range[0]; @@ -297,8 +298,8 @@ chrp_find_bridges(void) } } } else { - printk("No methods for %s (model %s), using RTAS\n", - dev->full_name, model); + printk("No methods for %pOF (model %s), using RTAS\n", + dev, model); hose->ops = &rtas_pci_ops; } diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 2b4dc6abde6c..485cf5ef73d4 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2005 Sven Luther * Thanks to : @@ -63,7 +64,7 @@ static struct platform_device mv643xx_eth_mvmdio_device = { .name = "orion-mdio", .id = -1, .num_resources = ARRAY_SIZE(mv643xx_eth_mvmdio_resources), - .resource = mv643xx_eth_shared_resources, + .resource = mv643xx_eth_mvmdio_resources, }; static struct resource mv643xx_eth_port1_resources[] = { diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 0ce1b45f02a8..481ed133e04b 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1995 Linus Torvalds * Adapted from 'alpha' version by Gary Thomas diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index 14515040f7cd..f7bb6cb8d1e3 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Smp support for CHRP machines. * diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c index f803f4b8ab6f..03d115aaa191 100644 --- a/arch/powerpc/platforms/chrp/time.c +++ b/arch/powerpc/platforms/chrp/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991, 1992, 1995 Linus Torvalds * diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index a25f496c2ef9..9fb2d5912c5a 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config EMBEDDED6xx bool "Embedded 6xx/7xx/7xxx-based boards" depends on 6xx && BROKEN_ON_SMP diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index f126a2a09981..12154e3257ad 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the 6xx/7xx/7xxxx linux kernel. # diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c index f29cf29b11f8..f514d5d28cd4 100644 --- a/arch/powerpc/platforms/embedded6xx/linkstation.c +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -41,12 +41,12 @@ static int __init linkstation_add_bridge(struct device_node *dev) struct pci_controller *hose; const int *bus_range; - printk("Adding PCI host bridge %s\n", dev->full_name); + printk("Adding PCI host bridge %pOF\n", dev); bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); hose = pcibios_alloc_controller(dev); if (hose == NULL) diff --git a/arch/powerpc/platforms/embedded6xx/mvme5100.c b/arch/powerpc/platforms/embedded6xx/mvme5100.c index 8e3590941960..273dfa3f0252 100644 --- a/arch/powerpc/platforms/embedded6xx/mvme5100.c +++ b/arch/powerpc/platforms/embedded6xx/mvme5100.c @@ -115,7 +115,7 @@ static int __init mvme5100_add_bridge(struct device_node *dev) struct pci_controller *hose; unsigned short devid; - pr_info("Adding PCI host bridge %s\n", dev->full_name); + pr_info("Adding PCI host bridge %pOF\n", dev); bus_range = of_get_property(dev, "bus-range", &len); diff --git a/arch/powerpc/platforms/embedded6xx/storcenter.c b/arch/powerpc/platforms/embedded6xx/storcenter.c index 471a50bcd074..ed1914dd34bb 100644 --- a/arch/powerpc/platforms/embedded6xx/storcenter.c +++ b/arch/powerpc/platforms/embedded6xx/storcenter.c @@ -44,7 +44,7 @@ static int __init storcenter_add_bridge(struct device_node *dev) struct pci_controller *hose; const int *bus_range; - printk("Adding PCI host bridge %s\n", dev->full_name); + printk("Adding PCI host bridge %pOF\n", dev); hose = pcibios_alloc_controller(dev); if (hose == NULL) diff --git a/arch/powerpc/platforms/maple/Kconfig b/arch/powerpc/platforms/maple/Kconfig index e359d0db092c..376d0be36b66 100644 --- a/arch/powerpc/platforms/maple/Kconfig +++ b/arch/powerpc/platforms/maple/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_MAPLE depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN bool "Maple 970FX Evaluation Board" diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h index eecfa182b06e..d10f4af3a42e 100644 --- a/arch/powerpc/platforms/maple/maple.h +++ b/arch/powerpc/platforms/maple/maple.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Declarations for maple-specific code. * diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 69794d9389c2..e3821379e86f 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -73,8 +73,8 @@ static void __init fixup_bus_range(struct device_node *bridge) /* Lookup the "bus-range" property for the hose */ prop = of_find_property(bridge, "bus-range", &len); if (prop == NULL || prop->value == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - bridge->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF\n", + bridge); return; } bus_range = prop->value; @@ -498,12 +498,12 @@ static int __init maple_add_bridge(struct device_node *dev) const int *bus_range; int primary = 1; - DBG("Adding PCI host bridge %s\n", dev->full_name); + DBG("Adding PCI host bridge %pOF\n", dev); bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", - dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume bus 0\n", + dev); } hose = pcibios_alloc_controller(dev); diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig index c7f1dbe94de7..d458a791d35b 100644 --- a/arch/powerpc/platforms/pasemi/Kconfig +++ b/arch/powerpc/platforms/pasemi/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_PASEMI depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN bool "PA Semi SoC-based platforms" diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h index 74cbcb357612..329d2a619254 100644 --- a/arch/powerpc/platforms/pasemi/pasemi.h +++ b/arch/powerpc/platforms/pasemi/pasemi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PASEMI_PASEMI_H #define _PASEMI_PASEMI_H diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c index 10c4e8fc6ea9..5ff6108f19e9 100644 --- a/arch/powerpc/platforms/pasemi/pci.c +++ b/arch/powerpc/platforms/pasemi/pci.c @@ -193,7 +193,7 @@ static int __init pas_add_bridge(struct device_node *dev) { struct pci_controller *hose; - pr_debug("Adding PCI host bridge %s\n", dev->full_name); + pr_debug("Adding PCI host bridge %pOF\n", dev); hose = pcibios_alloc_controller(dev); if (!hose) diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig index 43c606268baf..fc90cb35cea3 100644 --- a/arch/powerpc/platforms/powermac/Kconfig +++ b/arch/powerpc/platforms/powermac/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_PMAC bool "Apple PowerMac based machines" depends on PPC_BOOK3S && CPU_BIG_ENDIAN diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 1eb7b45e017d..f2839eed0f89 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 CFLAGS_bootx_init.o += -fPIC ifdef CONFIG_FUNCTION_TRACER diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 1e02328c3f2d..9e3f39d36e88 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -2658,25 +2658,25 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ if (i >= MAX_MACIO_CHIPS) { printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); - printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); + printk(KERN_ERR "pmac_feature: %pOF skipped\n", node); return; } addrp = of_get_pci_address(node, 0, &size, NULL); if (addrp == NULL) { - printk(KERN_ERR "pmac_feature: %s: can't find base !\n", - node->full_name); + printk(KERN_ERR "pmac_feature: %pOF: can't find base !\n", + node); return; } addr = of_translate_address(node, addrp); if (addr == 0) { - printk(KERN_ERR "pmac_feature: %s, can't translate base !\n", - node->full_name); + printk(KERN_ERR "pmac_feature: %pOF, can't translate base !\n", + node); return; } base = ioremap(addr, (unsigned long)size); if (!base) { - printk(KERN_ERR "pmac_feature: %s, can't map mac-io chip !\n", - node->full_name); + printk(KERN_ERR "pmac_feature: %pOF, can't map mac-io chip !\n", + node); return; } if (type == macio_keylargo || type == macio_keylargo2) { diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index f627c9fd7b48..70183eb3d5c8 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -494,8 +494,8 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); if (host == NULL) { - printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", - np->full_name); + printk(KERN_ERR "low_i2c: Can't allocate host for %pOF\n", + np); return NULL; } @@ -505,8 +505,8 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) */ addrp = of_get_property(np, "AAPL,address", NULL); if (addrp == NULL) { - printk(KERN_ERR "low_i2c: Can't find address for %s\n", - np->full_name); + printk(KERN_ERR "low_i2c: Can't find address for %pOF\n", + np); kfree(host); return NULL; } @@ -538,13 +538,13 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) host->irq = irq_of_parse_and_map(np, 0); if (!host->irq) printk(KERN_WARNING - "low_i2c: Failed to map interrupt for %s\n", - np->full_name); + "low_i2c: Failed to map interrupt for %pOF\n", + np); host->base = ioremap((*addrp), 0x1000); if (host->base == NULL) { - printk(KERN_ERR "low_i2c: Can't map registers for %s\n", - np->full_name); + printk(KERN_ERR "low_i2c: Can't map registers for %pOF\n", + np); kfree(host); return NULL; } @@ -560,8 +560,8 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) "keywest i2c", host)) host->irq = 0; - printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", - *addrp, host->irq, np->full_name); + printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %pOF\n", + *addrp, host->irq, np); return host; } @@ -798,7 +798,7 @@ static void __init pmu_i2c_probe(void) if (busnode == NULL) return; - printk(KERN_INFO "PMU i2c %s\n", busnode->full_name); + printk(KERN_INFO "PMU i2c %pOF\n", busnode); /* * We add bus 1 and 2 only for now, bus 0 is "special" @@ -913,7 +913,7 @@ static void __init smu_i2c_probe(void) if (controller == NULL) return; - printk(KERN_INFO "SMU i2c %s\n", controller->full_name); + printk(KERN_INFO "SMU i2c %pOF\n", controller); /* Look for childs, note that they might not be of the right * type as older device trees mix i2c busses and other things @@ -945,8 +945,8 @@ static void __init smu_i2c_probe(void) bus->flags = 0; list_add(&bus->link, &pmac_i2c_busses); - printk(KERN_INFO " channel %x bus %s\n", - bus->channel, busnode->full_name); + printk(KERN_INFO " channel %x bus %pOF\n", + bus->channel, busnode); } } @@ -1129,7 +1129,7 @@ int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode) */ if (mode < pmac_i2c_mode_dumb || mode > pmac_i2c_mode_combined) { printk(KERN_ERR "low_i2c: Invalid mode %d requested on" - " bus %s !\n", mode, bus->busnode->full_name); + " bus %pOF !\n", mode, bus->busnode); return -EINVAL; } bus->mode = mode; @@ -1146,8 +1146,8 @@ int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, WARN_ON(!bus->opened); DBG("xfer() chan=%d, addrdir=0x%x, mode=%d, subsize=%d, subaddr=0x%x," - " %d bytes, bus %s\n", bus->channel, addrdir, bus->mode, subsize, - subaddr, len, bus->busnode->full_name); + " %d bytes, bus %pOF\n", bus->channel, addrdir, bus->mode, subsize, + subaddr, len, bus->busnode); rc = bus->xfer(bus, addrdir, subsize, subaddr, data, len); @@ -1241,13 +1241,13 @@ static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args) bus = pmac_i2c_find_bus(func->node); if (bus == NULL) { - printk(KERN_ERR "low_i2c: Can't find bus for %s (pfunc)\n", - func->node->full_name); + printk(KERN_ERR "low_i2c: Can't find bus for %pOF (pfunc)\n", + func->node); return NULL; } if (pmac_i2c_open(bus, 0)) { - printk(KERN_ERR "low_i2c: Can't open i2c bus for %s (pfunc)\n", - func->node->full_name); + printk(KERN_ERR "low_i2c: Can't open i2c bus for %pOF (pfunc)\n", + func->node); return NULL; } @@ -1417,7 +1417,7 @@ static struct pmf_handlers pmac_i2c_pfunc_handlers = { static void __init pmac_i2c_dev_create(struct device_node *np, int quirks) { - DBG("dev_create(%s)\n", np->full_name); + DBG("dev_create(%pOF)\n", np); pmf_register_driver(np, &pmac_i2c_pfunc_handlers, (void *)(long)quirks); @@ -1425,20 +1425,20 @@ static void __init pmac_i2c_dev_create(struct device_node *np, int quirks) static void __init pmac_i2c_dev_init(struct device_node *np, int quirks) { - DBG("dev_create(%s)\n", np->full_name); + DBG("dev_create(%pOF)\n", np); pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_INIT, NULL); } static void pmac_i2c_dev_suspend(struct device_node *np, int quirks) { - DBG("dev_suspend(%s)\n", np->full_name); + DBG("dev_suspend(%pOF)\n", np); pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_SLEEP, NULL); } static void pmac_i2c_dev_resume(struct device_node *np, int quirks) { - DBG("dev_resume(%s)\n", np->full_name); + DBG("dev_resume(%pOF)\n", np); pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_WAKE, NULL); } diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 6e06c3be2e9a..0b8174a79993 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -783,7 +783,7 @@ static int __init pmac_add_bridge(struct device_node *dev) const int *bus_range; int primary = 1, has_address = 0; - DBG("Adding PCI host bridge %s\n", dev->full_name); + DBG("Adding PCI host bridge %pOF\n", dev); /* Fetch host bridge registers address */ has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); @@ -791,8 +791,8 @@ static int __init pmac_add_bridge(struct device_node *dev) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); } hose = pcibios_alloc_controller(dev); diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c index 459138ed4571..fd2e210559c8 100644 --- a/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/arch/powerpc/platforms/powermac/pfunc_base.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -54,8 +55,8 @@ static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask) raw_spin_lock_irqsave(&feature_lock, flags); tmp = readb(addr); tmp = (tmp & ~mask) | (value & mask); - DBG("Do write 0x%02x to GPIO %s (%p)\n", - tmp, func->node->full_name, addr); + DBG("Do write 0x%02x to GPIO %pOF (%p)\n", + tmp, func->node, addr); writeb(tmp, addr); raw_spin_unlock_irqrestore(&feature_lock, flags); @@ -107,8 +108,8 @@ static void macio_gpio_init_one(struct macio_chip *macio) if (gparent == NULL) return; - DBG("Installing GPIO functions for macio %s\n", - macio->of_node->full_name); + DBG("Installing GPIO functions for macio %pOF\n", + macio->of_node); /* * Ok, got one, we dont need anything special to track them down, so @@ -129,8 +130,8 @@ static void macio_gpio_init_one(struct macio_chip *macio) pmf_register_driver(gp, &macio_gpio_handlers, (void *)offset); } - DBG("Calling initial GPIO functions for macio %s\n", - macio->of_node->full_name); + DBG("Calling initial GPIO functions for macio %pOF\n", + macio->of_node); /* And now we run all the init ones */ for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) @@ -267,8 +268,8 @@ static struct pmf_handlers macio_mmio_handlers = { static void macio_mmio_init_one(struct macio_chip *macio) { - DBG("Installing MMIO functions for macio %s\n", - macio->of_node->full_name); + DBG("Installing MMIO functions for macio %pOF\n", + macio->of_node); pmf_register_driver(macio->of_node, &macio_mmio_handlers, macio); } @@ -298,8 +299,8 @@ static void uninorth_install_pfunc(void) { struct device_node *np; - DBG("Installing functions for UniN %s\n", - uninorth_node->full_name); + DBG("Installing functions for UniN %pOF\n", + uninorth_node); /* * Install handlers for the bridge itself @@ -317,8 +318,8 @@ static void uninorth_install_pfunc(void) break; } if (unin_hwclock) { - DBG("Installing functions for UniN clock %s\n", - unin_hwclock->full_name); + DBG("Installing functions for UniN clock %pOF\n", + unin_hwclock); pmf_register_driver(unin_hwclock, &unin_mmio_handlers, NULL); pmf_do_functions(unin_hwclock, NULL, 0, PMF_FLAGS_ON_INIT, NULL); diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 695e8c4d4224..df3c93bef228 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -708,7 +708,7 @@ int pmf_register_driver(struct device_node *np, if (handlers == NULL) return -EINVAL; - DBG("pmf: registering driver for node %s\n", np->full_name); + DBG("pmf: registering driver for node %pOF\n", np); spin_lock_irqsave(&pmf_lock, flags); dev = pmf_find_device(np); @@ -781,7 +781,7 @@ void pmf_unregister_driver(struct device_node *np) struct pmf_device *dev; unsigned long flags; - DBG("pmf: unregistering driver for node %s\n", np->full_name); + DBG("pmf: unregistering driver for node %pOF\n", np); spin_lock_irqsave(&pmf_lock, flags); dev = pmf_find_device(np); @@ -940,7 +940,7 @@ int pmf_call_one(struct pmf_function *func, struct pmf_args *args) void *instdata = NULL; int rc = 0; - DBG(" ** pmf_call_one(%s/%s) **\n", dev->node->full_name, func->name); + DBG(" ** pmf_call_one(%pOF/%s) **\n", dev->node, func->name); if (dev->handlers->begin) instdata = dev->handlers->begin(func, args); diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index f5f9ad7c3398..5e0719b27294 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -364,8 +364,8 @@ static void __init pmac_pic_probe_oldstyle(void) (addr + 0x10); of_node_put(master); - printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n", - master->full_name, max_real_irqs); + printk(KERN_INFO "irq: Found primary Apple PIC %pOF for %d irqs\n", + master, max_real_irqs); /* Map interrupts of cascaded controller */ if (slave && !of_address_to_resource(slave, 0, &r)) { @@ -378,8 +378,8 @@ static void __init pmac_pic_probe_oldstyle(void) (addr + 0x10); pmac_irq_cascade = irq_of_parse_and_map(slave, 0); - printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs" - " cascade: %d\n", slave->full_name, + printk(KERN_INFO "irq: Found slave Apple PIC %pOF for %d irqs" + " cascade: %d\n", slave, max_irqs - max_real_irqs, pmac_irq_cascade); } of_node_put(slave); diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index e7f8163d6769..6f15b8804e9b 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PMAC_H__ #define __PMAC_H__ diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 6b4e9d181126..ab668cb72263 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -556,7 +556,7 @@ static int __init check_pmac_serial_console(void) pr_debug(" can't find stdout package %s !\n", name); return -ENODEV; } - pr_debug("stdout is %s\n", prom_stdout->full_name); + pr_debug("stdout is %pOF\n", prom_stdout); name = of_get_property(prom_stdout, "name", NULL); if (!name) { diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c index 8680bb69795d..274af6fa388e 100644 --- a/arch/powerpc/platforms/powermac/time.c +++ b/arch/powerpc/platforms/powermac/time.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Support for periodic interrupts (100 per second) and for getting * the current time from the RTC on Power Macintoshes. diff --git a/arch/powerpc/platforms/powermac/udbg_adb.c b/arch/powerpc/platforms/powermac/udbg_adb.c index 366bd221edec..64f38f0d15ed 100644 --- a/arch/powerpc/platforms/powermac/udbg_adb.c +++ b/arch/powerpc/platforms/powermac/udbg_adb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index 6a6f4ef46b9e..f8dc98d3dc01 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_POWERNV depends on PPC64 && PPC_BOOK3S bool "IBM PowerNV (Non-Virtualized) platform support" @@ -30,3 +31,25 @@ config OPAL_PRD help This enables the opal-prd driver, a facility to run processor recovery diagnostics on OpenPower machines + +config PPC_MEMTRACE + bool "Enable removal of RAM from kernel mappings for tracing" + depends on PPC_POWERNV && MEMORY_HOTREMOVE + default n + help + Enabling this option allows for the removal of memory (RAM) + from the kernel mappings to be used for hardware tracing. + +config PPC_VAS + bool "IBM Virtual Accelerator Switchboard (VAS)" + depends on PPC_POWERNV && PPC_64K_PAGES + default y + help + This enables support for IBM Virtual Accelerator Switchboard (VAS). + + VAS allows accelerators in co-processors like NX-GZIP and NX-842 + to be accessible to kernel subsystems and user processes. + + VAS adapters are found in POWER9 based systems. + + If unsure, say N. diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index b5d98cb3f482..7a31c26500e6 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -1,8 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += setup.o opal-wrappers.o opal.o opal-async.o idle.o obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o -obj-y += opal-kmsg.o +obj-y += opal-kmsg.o opal-powercap.o opal-psr.o opal-sensor-groups.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o @@ -12,3 +13,6 @@ obj-$(CONFIG_PPC_SCOM) += opal-xscom.o obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o obj-$(CONFIG_TRACEPOINTS) += opal-tracepoints.o obj-$(CONFIG_OPAL_PRD) += opal-prd.o +obj-$(CONFIG_PERF_EVENTS) += opal-imc.o +obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o +obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o diff --git a/arch/powerpc/platforms/powernv/copy-paste.h b/arch/powerpc/platforms/powernv/copy-paste.h new file mode 100644 index 000000000000..c9a503623431 --- /dev/null +++ b/arch/powerpc/platforms/powernv/copy-paste.h @@ -0,0 +1,46 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include + +#define CR0_SHIFT 28 +#define CR0_MASK 0xF +/* + * Copy/paste instructions: + * + * copy RA,RB + * Copy contents of address (RA) + effective_address(RB) + * to internal copy-buffer. + * + * paste RA,RB + * Paste contents of internal copy-buffer to the address + * (RA) + effective_address(RB) + */ +static inline int vas_copy(void *crb, int offset) +{ + asm volatile(PPC_COPY(%0, %1)";" + : + : "b" (offset), "b" (crb) + : "memory"); + + return 0; +} + +static inline int vas_paste(void *paste_address, int offset) +{ + u32 cr; + + cr = 0; + asm volatile(PPC_PASTE(%1, %2)";" + "mfocrf %0, 0x80;" + : "=r" (cr) + : "b" (offset), "b" (paste_address) + : "memory", "cr0"); + + return (cr >> CR0_SHIFT) & CR0_MASK; +} diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 3f48f6df1cf3..8864065eba22 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -113,7 +113,6 @@ static ssize_t pnv_eeh_ei_write(struct file *filp, size_t count, loff_t *ppos) { struct pci_controller *hose = filp->private_data; - struct eeh_dev *edev; struct eeh_pe *pe; int pe_no, type, func; unsigned long addr, mask; @@ -135,13 +134,7 @@ static ssize_t pnv_eeh_ei_write(struct file *filp, return -EINVAL; /* Retrieve PE */ - edev = kzalloc(sizeof(*edev), GFP_KERNEL); - if (!edev) - return -ENOMEM; - edev->phb = hose; - edev->pe_config_addr = pe_no; - pe = eeh_pe_get(edev); - kfree(edev); + pe = eeh_pe_get(hose, pe_no, 0); if (!pe) return -ENODEV; @@ -359,6 +352,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) struct eeh_dev *edev = pdn_to_eeh_dev(pdn); uint32_t pcie_flags; int ret; + int config_addr = (pdn->busno << 8) | (pdn->devfn); /* * When probing the root bridge, which doesn't have any @@ -393,8 +387,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) } } - edev->config_addr = (pdn->busno << 8) | (pdn->devfn); - edev->pe_config_addr = phb->ioda.pe_rmap[edev->config_addr]; + edev->pe_config_addr = phb->ioda.pe_rmap[config_addr]; /* Create PE */ ret = eeh_add_to_parent_pe(edev); @@ -933,7 +926,6 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev) static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type, int pos, u16 mask) { - struct eeh_dev *edev = pdn_to_eeh_dev(pdn); int i, status = 0; /* Wait for Transaction Pending bit to be cleared */ @@ -947,7 +939,7 @@ static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type, pr_warn("%s: Pending transaction while issuing %sFLR to %04x:%02x:%02x.%01x\n", __func__, type, - edev->phb->global_number, pdn->busno, + pdn->phb->global_number, pdn->busno, PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); } @@ -1381,7 +1373,6 @@ static int pnv_eeh_get_pe(struct pci_controller *hose, struct pnv_phb *phb = hose->private_data; struct pnv_ioda_pe *pnv_pe; struct eeh_pe *dev_pe; - struct eeh_dev edev; /* * If PHB supports compound PE, to fetch @@ -1397,10 +1388,7 @@ static int pnv_eeh_get_pe(struct pci_controller *hose, } /* Find the PE according to PE# */ - memset(&edev, 0, sizeof(struct eeh_dev)); - edev.phb = hose; - edev.pe_config_addr = pe_no; - dev_pe = eeh_pe_get(&edev); + dev_pe = eeh_pe_get(hose, pe_no, 0); if (!dev_pe) return -EEXIST; @@ -1711,6 +1699,7 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn) struct eeh_dev *edev = pdn_to_eeh_dev(pdn); struct pnv_phb *phb; s64 ret; + int config_addr = (pdn->busno << 8) | (pdn->devfn); if (!edev) return -EEXIST; @@ -1725,14 +1714,14 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn) if (edev->physfn) { ret = pnv_eeh_restore_vf_config(pdn); } else { - phb = edev->phb->private_data; + phb = pdn->phb->private_data; ret = opal_pci_reinit(phb->opal_id, - OPAL_REINIT_PCI_DEV, edev->config_addr); + OPAL_REINIT_PCI_DEV, config_addr); } if (ret) { pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n", - __func__, edev->config_addr, ret); + __func__, config_addr, ret); return -EIO; } diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index a553aeea7af6..443d5ca71995 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -69,7 +69,7 @@ static int pnv_save_sprs_for_deep_states(void) * all cpus at boot. Get these reg values of current cpu and use the * same across all cpus. */ - uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; + uint64_t lpcr_val = mfspr(SPRN_LPCR); uint64_t hid0_val = mfspr(SPRN_HID0); uint64_t hid1_val = mfspr(SPRN_HID1); uint64_t hid4_val = mfspr(SPRN_HID4); @@ -388,6 +388,20 @@ void power9_idle(void) } #ifdef CONFIG_HOTPLUG_CPU +static void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val) +{ + u64 pir = get_hard_smp_processor_id(cpu); + + mtspr(SPRN_LPCR, lpcr_val); + + /* + * Program the LPCR via stop-api only if the deepest stop state + * can lose hypervisor context. + */ + if (supported_cpuidle_states & OPAL_PM_LOSE_FULL_CONTEXT) + opal_slw_set_reg(pir, SPRN_LPCR, lpcr_val); +} + /* * pnv_cpu_offline: A function that puts the CPU into the deepest * available platform idle state on a CPU-Offline. @@ -397,6 +411,20 @@ unsigned long pnv_cpu_offline(unsigned int cpu) { unsigned long srr1; u32 idle_states = pnv_get_supported_cpuidle_states(); + u64 lpcr_val; + + /* + * We don't want to take decrementer interrupts while we are + * offline, so clear LPCR:PECE1. We keep PECE2 (and + * LPCR_PECE_HVEE on P9) enabled as to let IPIs in. + * + * If the CPU gets woken up by a special wakeup, ensure that + * the SLW engine sets LPCR with decrementer bit cleared, else + * the CPU will come back to the kernel due to a spurious + * wakeup. + */ + lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; + pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val); __ppc64_runlatch_off(); @@ -428,6 +456,16 @@ unsigned long pnv_cpu_offline(unsigned int cpu) __ppc64_runlatch_on(); + /* + * Re-enable decrementer interrupts in LPCR. + * + * Further, we want stop states to be woken up by decrementer + * for non-hotplug cases. So program the LPCR via stop api as + * well. + */ + lpcr_val = mfspr(SPRN_LPCR) | (u64)LPCR_PECE1; + pnv_program_cpu_hotplug_lpcr(cpu, lpcr_val); + return srr1; } #endif diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c new file mode 100644 index 000000000000..de470caf0784 --- /dev/null +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -0,0 +1,282 @@ +/* + * Copyright (C) IBM Corporation, 2014, 2017 + * Anton Blanchard, Rashmica Gupta. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#define pr_fmt(fmt) "memtrace: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* This enables us to keep track of the memory removed from each node. */ +struct memtrace_entry { + void *mem; + u64 start; + u64 size; + u32 nid; + struct dentry *dir; + char name[16]; +}; + +static u64 memtrace_size; + +static struct memtrace_entry *memtrace_array; +static unsigned int memtrace_array_nr; + + +static ssize_t memtrace_read(struct file *filp, char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct memtrace_entry *ent = filp->private_data; + + return simple_read_from_buffer(ubuf, count, ppos, ent->mem, ent->size); +} + +static bool valid_memtrace_range(struct memtrace_entry *dev, + unsigned long start, unsigned long size) +{ + if ((start >= dev->start) && + ((start + size) <= (dev->start + dev->size))) + return true; + + return false; +} + +static int memtrace_mmap(struct file *filp, struct vm_area_struct *vma) +{ + unsigned long size = vma->vm_end - vma->vm_start; + struct memtrace_entry *dev = filp->private_data; + + if (!valid_memtrace_range(dev, vma->vm_pgoff << PAGE_SHIFT, size)) + return -EINVAL; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, + vma->vm_pgoff + (dev->start >> PAGE_SHIFT), + size, vma->vm_page_prot)) + return -EAGAIN; + + return 0; +} + +static const struct file_operations memtrace_fops = { + .llseek = default_llseek, + .read = memtrace_read, + .mmap = memtrace_mmap, + .open = simple_open, +}; + +static void flush_memory_region(u64 base, u64 size) +{ + unsigned long line_size = ppc64_caches.l1d.size; + u64 end = base + size; + u64 addr; + + base = round_down(base, line_size); + end = round_up(end, line_size); + + for (addr = base; addr < end; addr += line_size) + asm volatile("dcbf 0,%0" : "=r" (addr) :: "memory"); +} + +static int check_memblock_online(struct memory_block *mem, void *arg) +{ + if (mem->state != MEM_ONLINE) + return -1; + + return 0; +} + +static int change_memblock_state(struct memory_block *mem, void *arg) +{ + unsigned long state = (unsigned long)arg; + + mem->state = state; + + return 0; +} + +static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages) +{ + u64 end_pfn = start_pfn + nr_pages - 1; + + if (walk_memory_range(start_pfn, end_pfn, NULL, + check_memblock_online)) + return false; + + walk_memory_range(start_pfn, end_pfn, (void *)MEM_GOING_OFFLINE, + change_memblock_state); + + if (offline_pages(start_pfn, nr_pages)) { + walk_memory_range(start_pfn, end_pfn, (void *)MEM_ONLINE, + change_memblock_state); + return false; + } + + walk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE, + change_memblock_state); + + /* RCU grace period? */ + flush_memory_region((u64)__va(start_pfn << PAGE_SHIFT), + nr_pages << PAGE_SHIFT); + + lock_device_hotplug(); + remove_memory(nid, start_pfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT); + unlock_device_hotplug(); + + return true; +} + +static u64 memtrace_alloc_node(u32 nid, u64 size) +{ + u64 start_pfn, end_pfn, nr_pages; + u64 base_pfn; + + if (!NODE_DATA(nid) || !node_spanned_pages(nid)) + return 0; + + start_pfn = node_start_pfn(nid); + end_pfn = node_end_pfn(nid); + nr_pages = size >> PAGE_SHIFT; + + /* Trace memory needs to be aligned to the size */ + end_pfn = round_down(end_pfn - nr_pages, nr_pages); + + for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) { + if (memtrace_offline_pages(nid, base_pfn, nr_pages) == true) + return base_pfn << PAGE_SHIFT; + } + + return 0; +} + +static int memtrace_init_regions_runtime(u64 size) +{ + u32 nid; + u64 m; + + memtrace_array = kcalloc(num_online_nodes(), + sizeof(struct memtrace_entry), GFP_KERNEL); + if (!memtrace_array) { + pr_err("Failed to allocate memtrace_array\n"); + return -EINVAL; + } + + for_each_online_node(nid) { + m = memtrace_alloc_node(nid, size); + + /* + * A node might not have any local memory, so warn but + * continue on. + */ + if (!m) { + pr_err("Failed to allocate trace memory on node %d\n", nid); + continue; + } + + pr_info("Allocated trace memory on node %d at 0x%016llx\n", nid, m); + + memtrace_array[memtrace_array_nr].start = m; + memtrace_array[memtrace_array_nr].size = size; + memtrace_array[memtrace_array_nr].nid = nid; + memtrace_array_nr++; + } + + return 0; +} + +static struct dentry *memtrace_debugfs_dir; + +static int memtrace_init_debugfs(void) +{ + int ret = 0; + int i; + + for (i = 0; i < memtrace_array_nr; i++) { + struct dentry *dir; + struct memtrace_entry *ent = &memtrace_array[i]; + + ent->mem = ioremap(ent->start, ent->size); + /* Warn but continue on */ + if (!ent->mem) { + pr_err("Failed to map trace memory at 0x%llx\n", + ent->start); + ret = -1; + continue; + } + + snprintf(ent->name, 16, "%08x", ent->nid); + dir = debugfs_create_dir(ent->name, memtrace_debugfs_dir); + if (!dir) + return -1; + + ent->dir = dir; + debugfs_create_file("trace", 0400, dir, ent, &memtrace_fops); + debugfs_create_x64("start", 0400, dir, &ent->start); + debugfs_create_x64("size", 0400, dir, &ent->size); + } + + return ret; +} + +static int memtrace_enable_set(void *data, u64 val) +{ + if (memtrace_size) + return -EINVAL; + + if (!val) + return -EINVAL; + + /* Make sure size is aligned to a memory block */ + if (val & (memory_block_size_bytes() - 1)) + return -EINVAL; + + if (memtrace_init_regions_runtime(val)) + return -EINVAL; + + if (memtrace_init_debugfs()) + return -EINVAL; + + memtrace_size = val; + + return 0; +} + +static int memtrace_enable_get(void *data, u64 *val) +{ + *val = memtrace_size; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(memtrace_init_fops, memtrace_enable_get, + memtrace_enable_set, "0x%016llx\n"); + +static int memtrace_init(void) +{ + memtrace_debugfs_dir = debugfs_create_dir("memtrace", + powerpc_debugfs_root); + if (!memtrace_debugfs_dir) + return -1; + + debugfs_create_file("enable", 0600, memtrace_debugfs_dir, + NULL, &memtrace_init_fops); + + return 0; +} +machine_device_initcall(powernv, memtrace_init); diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index 4c7b8591f737..2cb6cbea4b3b 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -545,6 +545,12 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]; unsigned long pid = npu_context->mm->context.id; + /* + * Unfortunately the nest mmu does not support flushing specific + * addresses so we have to flush the whole mm. + */ + flush_tlb_mm(npu_context->mm); + /* * Loop over all the NPUs this process is active on and launch * an invalidate. @@ -576,12 +582,6 @@ static void mmio_invalidate(struct npu_context *npu_context, int va, } } - /* - * Unfortunately the nest mmu does not support flushing specific - * addresses so we have to flush the whole mm. - */ - flush_tlb_mm(npu_context->mm); - mmio_invalidate_wait(mmio_atsd_reg, flush); if (flush) /* Wait for the flush to complete */ diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c index 83bebeec0fea..cf33769a7b72 100644 --- a/arch/powerpc/platforms/powernv/opal-async.c +++ b/arch/powerpc/platforms/powernv/opal-async.c @@ -171,8 +171,8 @@ int __init opal_async_comp_init(void) async = of_get_property(opal_node, "opal-msg-async-num", NULL); if (!async) { - pr_err("%s: %s has no opal-msg-async-num\n", - __func__, opal_node->full_name); + pr_err("%s: %pOF has no opal-msg-async-num\n", + __func__, opal_node); err = -ENOENT; goto out_opal_node; } diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c index 4ec6219287fc..2fa3ac80cb4e 100644 --- a/arch/powerpc/platforms/powernv/opal-flash.c +++ b/arch/powerpc/platforms/powernv/opal-flash.c @@ -520,7 +520,7 @@ out: * update_flash : Flash new firmware image * */ -static struct bin_attribute image_data_attr = { +static const struct bin_attribute image_data_attr = { .attr = {.name = "image", .mode = 0200}, .size = MAX_IMAGE_SIZE, /* Limit image size */ .write = image_data_write, diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c index 88f3c61eec95..d78fed728cdf 100644 --- a/arch/powerpc/platforms/powernv/opal-hmi.c +++ b/arch/powerpc/platforms/powernv/opal-hmi.c @@ -30,6 +30,8 @@ #include #include +#include "powernv.h" + static int opal_hmi_handler_nb_init; struct OpalHmiEvtNode { struct list_head list; @@ -267,8 +269,6 @@ static void hmi_event_handler(struct work_struct *work) spin_unlock_irqrestore(&opal_hmi_evt_lock, flags); if (unrecoverable) { - int ret; - /* Pull all HMI events from OPAL before we panic. */ while (opal_get_msg(__pa(&msg), sizeof(msg)) == OPAL_SUCCESS) { u32 type; @@ -284,23 +284,7 @@ static void hmi_event_handler(struct work_struct *work) print_hmi_event_info(hmi_evt); } - /* - * Unrecoverable HMI exception. We need to inform BMC/OCC - * about this error so that it can collect relevant data - * for error analysis before rebooting. - */ - ret = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, - "Unrecoverable HMI exception"); - if (ret == OPAL_UNSUPPORTED) { - pr_emerg("Reboot type %d not supported\n", - OPAL_REBOOT_PLATFORM_ERROR); - } - - /* - * Fall through and panic if opal_cec_reboot2() returns - * OPAL_UNSUPPORTED. - */ - panic("Unrecoverable HMI exception"); + pnv_platform_error_reboot(NULL, "Unrecoverable HMI exception"); } } diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c new file mode 100644 index 000000000000..21f6531fae20 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -0,0 +1,226 @@ +/* + * OPAL IMC interface detection driver + * Supported on POWERNV platform + * + * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation. + * (C) 2017 Anju T Sudhakar, IBM Corporation. + * (C) 2017 Hemant K Shaw, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * imc_get_mem_addr_nest: Function to get nest counter memory region + * for each chip + */ +static int imc_get_mem_addr_nest(struct device_node *node, + struct imc_pmu *pmu_ptr, + u32 offset) +{ + int nr_chips = 0, i; + u64 *base_addr_arr, baddr; + u32 *chipid_arr; + + nr_chips = of_property_count_u32_elems(node, "chip-id"); + if (nr_chips <= 0) + return -ENODEV; + + base_addr_arr = kcalloc(nr_chips, sizeof(u64), GFP_KERNEL); + if (!base_addr_arr) + return -ENOMEM; + + chipid_arr = kcalloc(nr_chips, sizeof(u32), GFP_KERNEL); + if (!chipid_arr) + return -ENOMEM; + + if (of_property_read_u32_array(node, "chip-id", chipid_arr, nr_chips)) + goto error; + + if (of_property_read_u64_array(node, "base-addr", base_addr_arr, + nr_chips)) + goto error; + + pmu_ptr->mem_info = kcalloc(nr_chips, sizeof(struct imc_mem_info), + GFP_KERNEL); + if (!pmu_ptr->mem_info) + goto error; + + for (i = 0; i < nr_chips; i++) { + pmu_ptr->mem_info[i].id = chipid_arr[i]; + baddr = base_addr_arr[i] + offset; + pmu_ptr->mem_info[i].vbase = phys_to_virt(baddr); + } + + pmu_ptr->imc_counter_mmaped = true; + kfree(base_addr_arr); + kfree(chipid_arr); + return 0; + +error: + kfree(pmu_ptr->mem_info); + kfree(base_addr_arr); + kfree(chipid_arr); + return -1; +} + +/* + * imc_pmu_create : Takes the parent device which is the pmu unit, pmu_index + * and domain as the inputs. + * Allocates memory for the struct imc_pmu, sets up its domain, size and offsets + */ +static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain) +{ + int ret = 0; + struct imc_pmu *pmu_ptr; + u32 offset; + + /* memory for pmu */ + pmu_ptr = kzalloc(sizeof(struct imc_pmu), GFP_KERNEL); + if (!pmu_ptr) + return -ENOMEM; + + /* Set the domain */ + pmu_ptr->domain = domain; + + ret = of_property_read_u32(parent, "size", &pmu_ptr->counter_mem_size); + if (ret) { + ret = -EINVAL; + goto free_pmu; + } + + if (!of_property_read_u32(parent, "offset", &offset)) { + if (imc_get_mem_addr_nest(parent, pmu_ptr, offset)) { + ret = -EINVAL; + goto free_pmu; + } + } + + /* Function to register IMC pmu */ + ret = init_imc_pmu(parent, pmu_ptr, pmu_index); + if (ret) + pr_err("IMC PMU %s Register failed\n", pmu_ptr->pmu.name); + + return 0; + +free_pmu: + kfree(pmu_ptr); + return ret; +} + +static void disable_nest_pmu_counters(void) +{ + int nid, cpu; + const struct cpumask *l_cpumask; + + get_online_cpus(); + for_each_online_node(nid) { + l_cpumask = cpumask_of_node(nid); + cpu = cpumask_first(l_cpumask); + opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, + get_hard_smp_processor_id(cpu)); + } + put_online_cpus(); +} + +static void disable_core_pmu_counters(void) +{ + cpumask_t cores_map; + int cpu, rc; + + get_online_cpus(); + /* Disable the IMC Core functions */ + cores_map = cpu_online_cores_map(); + for_each_cpu(cpu, &cores_map) { + rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, + get_hard_smp_processor_id(cpu)); + if (rc) + pr_err("%s: Failed to stop Core (cpu = %d)\n", + __FUNCTION__, cpu); + } + put_online_cpus(); +} + +static int opal_imc_counters_probe(struct platform_device *pdev) +{ + struct device_node *imc_dev = pdev->dev.of_node; + int pmu_count = 0, domain; + u32 type; + + /* + * Check whether this is kdump kernel. If yes, force the engines to + * stop and return. + */ + if (is_kdump_kernel()) { + disable_nest_pmu_counters(); + disable_core_pmu_counters(); + return -ENODEV; + } + + for_each_compatible_node(imc_dev, NULL, IMC_DTB_UNIT_COMPAT) { + if (of_property_read_u32(imc_dev, "type", &type)) { + pr_warn("IMC Device without type property\n"); + continue; + } + + switch (type) { + case IMC_TYPE_CHIP: + domain = IMC_DOMAIN_NEST; + break; + case IMC_TYPE_CORE: + domain =IMC_DOMAIN_CORE; + break; + case IMC_TYPE_THREAD: + domain = IMC_DOMAIN_THREAD; + break; + default: + pr_warn("IMC Unknown Device type \n"); + domain = -1; + break; + } + + if (!imc_pmu_create(imc_dev, pmu_count, domain)) + pmu_count++; + } + + return 0; +} + +static void opal_imc_counters_shutdown(struct platform_device *pdev) +{ + /* + * Function only stops the engines which is bare minimum. + * TODO: Need to handle proper memory cleanup and pmu + * unregister. + */ + disable_nest_pmu_counters(); + disable_core_pmu_counters(); +} + +static const struct of_device_id opal_imc_match[] = { + { .compatible = IMC_DTB_COMPAT }, + {}, +}; + +static struct platform_driver opal_imc_driver = { + .driver = { + .name = "opal-imc-counters", + .of_match_table = opal_imc_match, + }, + .probe = opal_imc_counters_probe, + .shutdown = opal_imc_counters_shutdown, +}; + +builtin_platform_driver(opal_imc_driver); diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c new file mode 100644 index 000000000000..badb29bde93f --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-powercap.c @@ -0,0 +1,244 @@ +/* + * PowerNV OPAL Powercap interface + * + * Copyright 2017 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "opal-powercap: " fmt + +#include +#include +#include + +#include + +DEFINE_MUTEX(powercap_mutex); + +static struct kobject *powercap_kobj; + +struct powercap_attr { + u32 handle; + struct kobj_attribute attr; +}; + +static struct pcap { + struct attribute_group pg; + struct powercap_attr *pattrs; +} *pcaps; + +static ssize_t powercap_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct powercap_attr *pcap_attr = container_of(attr, + struct powercap_attr, attr); + struct opal_msg msg; + u32 pcap; + int ret, token; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&powercap_mutex); + if (ret) + goto out_token; + + ret = opal_get_powercap(pcap_attr->handle, token, (u32 *)__pa(&pcap)); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) { + ret = sprintf(buf, "%u\n", be32_to_cpu(pcap)); + if (ret < 0) + ret = -EIO; + } + break; + case OPAL_SUCCESS: + ret = sprintf(buf, "%u\n", be32_to_cpu(pcap)); + if (ret < 0) + ret = -EIO; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&powercap_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static ssize_t powercap_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + struct powercap_attr *pcap_attr = container_of(attr, + struct powercap_attr, attr); + struct opal_msg msg; + u32 pcap; + int ret, token; + + ret = kstrtoint(buf, 0, &pcap); + if (ret) + return ret; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&powercap_mutex); + if (ret) + goto out_token; + + ret = opal_set_powercap(pcap_attr->handle, token, pcap); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) + ret = count; + break; + case OPAL_SUCCESS: + ret = count; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&powercap_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static void powercap_add_attr(int handle, const char *name, + struct powercap_attr *attr) +{ + attr->handle = handle; + sysfs_attr_init(&attr->attr.attr); + attr->attr.attr.name = name; + attr->attr.attr.mode = 0444; + attr->attr.show = powercap_show; +} + +void __init opal_powercap_init(void) +{ + struct device_node *powercap, *node; + int i = 0; + + powercap = of_find_compatible_node(NULL, NULL, "ibm,opal-powercap"); + if (!powercap) { + pr_devel("Powercap node not found\n"); + return; + } + + pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps), + GFP_KERNEL); + if (!pcaps) + return; + + powercap_kobj = kobject_create_and_add("powercap", opal_kobj); + if (!powercap_kobj) { + pr_warn("Failed to create powercap kobject\n"); + goto out_pcaps; + } + + i = 0; + for_each_child_of_node(powercap, node) { + u32 cur, min, max; + int j = 0; + bool has_cur = false, has_min = false, has_max = false; + + if (!of_property_read_u32(node, "powercap-min", &min)) { + j++; + has_min = true; + } + + if (!of_property_read_u32(node, "powercap-max", &max)) { + j++; + has_max = true; + } + + if (!of_property_read_u32(node, "powercap-current", &cur)) { + j++; + has_cur = true; + } + + pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr), + GFP_KERNEL); + if (!pcaps[i].pattrs) + goto out_pcaps_pattrs; + + pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *), + GFP_KERNEL); + if (!pcaps[i].pg.attrs) { + kfree(pcaps[i].pattrs); + goto out_pcaps_pattrs; + } + + j = 0; + pcaps[i].pg.name = node->name; + if (has_min) { + powercap_add_attr(min, "powercap-min", + &pcaps[i].pattrs[j]); + pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr; + j++; + } + + if (has_max) { + powercap_add_attr(max, "powercap-max", + &pcaps[i].pattrs[j]); + pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr; + j++; + } + + if (has_cur) { + powercap_add_attr(cur, "powercap-current", + &pcaps[i].pattrs[j]); + pcaps[i].pattrs[j].attr.attr.mode |= 0220; + pcaps[i].pattrs[j].attr.store = powercap_store; + pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr; + j++; + } + + if (sysfs_create_group(powercap_kobj, &pcaps[i].pg)) { + pr_warn("Failed to create powercap attribute group %s\n", + pcaps[i].pg.name); + goto out_pcaps_pattrs; + } + i++; + } + + return; + +out_pcaps_pattrs: + while (--i >= 0) { + kfree(pcaps[i].pattrs); + kfree(pcaps[i].pg.attrs); + } + kobject_put(powercap_kobj); +out_pcaps: + kfree(pcaps); +} diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c index 2d6ee1c5ad85..de4dd09f4a15 100644 --- a/arch/powerpc/platforms/powernv/opal-prd.c +++ b/arch/powerpc/platforms/powernv/opal-prd.c @@ -241,15 +241,9 @@ static ssize_t opal_prd_write(struct file *file, const char __user *buf, size = be16_to_cpu(hdr.size); - msg = kmalloc(size, GFP_KERNEL); - if (!msg) - return -ENOMEM; - - rc = copy_from_user(msg, buf, size); - if (rc) { - size = -EFAULT; - goto out_free; - } + msg = memdup_user(buf, size); + if (IS_ERR(msg)) + return PTR_ERR(msg); rc = opal_prd_msg(msg); if (rc) { @@ -257,7 +251,6 @@ static ssize_t opal_prd_write(struct file *file, const char __user *buf, size = -EIO; } -out_free: kfree(msg); return size; diff --git a/arch/powerpc/platforms/powernv/opal-psr.c b/arch/powerpc/platforms/powernv/opal-psr.c new file mode 100644 index 000000000000..7313b7fc9071 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-psr.c @@ -0,0 +1,175 @@ +/* + * PowerNV OPAL Power-Shift-Ratio interface + * + * Copyright 2017 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "opal-psr: " fmt + +#include +#include +#include + +#include + +DEFINE_MUTEX(psr_mutex); + +static struct kobject *psr_kobj; + +struct psr_attr { + u32 handle; + struct kobj_attribute attr; +} *psr_attrs; + +static ssize_t psr_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct psr_attr *psr_attr = container_of(attr, struct psr_attr, attr); + struct opal_msg msg; + int psr, ret, token; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&psr_mutex); + if (ret) + goto out_token; + + ret = opal_get_power_shift_ratio(psr_attr->handle, token, + (u32 *)__pa(&psr)); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) { + ret = sprintf(buf, "%u\n", be32_to_cpu(psr)); + if (ret < 0) + ret = -EIO; + } + break; + case OPAL_SUCCESS: + ret = sprintf(buf, "%u\n", be32_to_cpu(psr)); + if (ret < 0) + ret = -EIO; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&psr_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static ssize_t psr_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct psr_attr *psr_attr = container_of(attr, struct psr_attr, attr); + struct opal_msg msg; + int psr, ret, token; + + ret = kstrtoint(buf, 0, &psr); + if (ret) + return ret; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&psr_mutex); + if (ret) + goto out_token; + + ret = opal_set_power_shift_ratio(psr_attr->handle, token, psr); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) + ret = count; + break; + case OPAL_SUCCESS: + ret = count; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&psr_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +void __init opal_psr_init(void) +{ + struct device_node *psr, *node; + int i = 0; + + psr = of_find_compatible_node(NULL, NULL, + "ibm,opal-power-shift-ratio"); + if (!psr) { + pr_devel("Power-shift-ratio node not found\n"); + return; + } + + psr_attrs = kcalloc(of_get_child_count(psr), sizeof(struct psr_attr), + GFP_KERNEL); + if (!psr_attrs) + return; + + psr_kobj = kobject_create_and_add("psr", opal_kobj); + if (!psr_kobj) { + pr_warn("Failed to create psr kobject\n"); + goto out; + } + + for_each_child_of_node(psr, node) { + if (of_property_read_u32(node, "handle", + &psr_attrs[i].handle)) + goto out_kobj; + + sysfs_attr_init(&psr_attrs[i].attr.attr); + if (of_property_read_string(node, "label", + &psr_attrs[i].attr.attr.name)) + goto out_kobj; + psr_attrs[i].attr.attr.mode = 0664; + psr_attrs[i].attr.show = psr_show; + psr_attrs[i].attr.store = psr_store; + if (sysfs_create_file(psr_kobj, &psr_attrs[i].attr.attr)) { + pr_devel("Failed to create psr sysfs file %s\n", + psr_attrs[i].attr.attr.name); + goto out_kobj; + } + i++; + } + + return; +out_kobj: + kobject_put(psr_kobj); +out: + kfree(psr_attrs); +} diff --git a/arch/powerpc/platforms/powernv/opal-sensor-groups.c b/arch/powerpc/platforms/powernv/opal-sensor-groups.c new file mode 100644 index 000000000000..7e5a235ebf76 --- /dev/null +++ b/arch/powerpc/platforms/powernv/opal-sensor-groups.c @@ -0,0 +1,212 @@ +/* + * PowerNV OPAL Sensor-groups interface + * + * Copyright 2017 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "opal-sensor-groups: " fmt + +#include +#include +#include + +#include + +DEFINE_MUTEX(sg_mutex); + +static struct kobject *sg_kobj; + +struct sg_attr { + u32 handle; + struct kobj_attribute attr; +}; + +static struct sensor_group { + char name[20]; + struct attribute_group sg; + struct sg_attr *sgattrs; +} *sgs; + +static ssize_t sg_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct sg_attr *sattr = container_of(attr, struct sg_attr, attr); + struct opal_msg msg; + u32 data; + int ret, token; + + ret = kstrtoint(buf, 0, &data); + if (ret) + return ret; + + if (data != 1) + return -EINVAL; + + token = opal_async_get_token_interruptible(); + if (token < 0) { + pr_devel("Failed to get token\n"); + return token; + } + + ret = mutex_lock_interruptible(&sg_mutex); + if (ret) + goto out_token; + + ret = opal_sensor_group_clear(sattr->handle, token); + switch (ret) { + case OPAL_ASYNC_COMPLETION: + ret = opal_async_wait_response(token, &msg); + if (ret) { + pr_devel("Failed to wait for the async response\n"); + ret = -EIO; + goto out; + } + ret = opal_error_code(opal_get_async_rc(msg)); + if (!ret) + ret = count; + break; + case OPAL_SUCCESS: + ret = count; + break; + default: + ret = opal_error_code(ret); + } + +out: + mutex_unlock(&sg_mutex); +out_token: + opal_async_release_token(token); + return ret; +} + +static struct sg_ops_info { + int opal_no; + const char *attr_name; + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); +} ops_info[] = { + { OPAL_SENSOR_GROUP_CLEAR, "clear", sg_store }, +}; + +static void add_attr(int handle, struct sg_attr *attr, int index) +{ + attr->handle = handle; + sysfs_attr_init(&attr->attr.attr); + attr->attr.attr.name = ops_info[index].attr_name; + attr->attr.attr.mode = 0220; + attr->attr.store = ops_info[index].store; +} + +static int add_attr_group(const __be32 *ops, int len, struct sensor_group *sg, + u32 handle) +{ + int i, j; + int count = 0; + + for (i = 0; i < len; i++) + for (j = 0; j < ARRAY_SIZE(ops_info); j++) + if (be32_to_cpu(ops[i]) == ops_info[j].opal_no) { + add_attr(handle, &sg->sgattrs[count], j); + sg->sg.attrs[count] = + &sg->sgattrs[count].attr.attr; + count++; + } + + return sysfs_create_group(sg_kobj, &sg->sg); +} + +static int get_nr_attrs(const __be32 *ops, int len) +{ + int i, j; + int nr_attrs = 0; + + for (i = 0; i < len; i++) + for (j = 0; j < ARRAY_SIZE(ops_info); j++) + if (be32_to_cpu(ops[i]) == ops_info[j].opal_no) + nr_attrs++; + + return nr_attrs; +} + +void __init opal_sensor_groups_init(void) +{ + struct device_node *sg, *node; + int i = 0; + + sg = of_find_compatible_node(NULL, NULL, "ibm,opal-sensor-group"); + if (!sg) { + pr_devel("Sensor groups node not found\n"); + return; + } + + sgs = kcalloc(of_get_child_count(sg), sizeof(*sgs), GFP_KERNEL); + if (!sgs) + return; + + sg_kobj = kobject_create_and_add("sensor_groups", opal_kobj); + if (!sg_kobj) { + pr_warn("Failed to create sensor group kobject\n"); + goto out_sgs; + } + + for_each_child_of_node(sg, node) { + const __be32 *ops; + u32 sgid, len, nr_attrs, chipid; + + ops = of_get_property(node, "ops", &len); + if (!ops) + continue; + + nr_attrs = get_nr_attrs(ops, len); + if (!nr_attrs) + continue; + + sgs[i].sgattrs = kcalloc(nr_attrs, sizeof(struct sg_attr), + GFP_KERNEL); + if (!sgs[i].sgattrs) + goto out_sgs_sgattrs; + + sgs[i].sg.attrs = kcalloc(nr_attrs + 1, + sizeof(struct attribute *), + GFP_KERNEL); + + if (!sgs[i].sg.attrs) { + kfree(sgs[i].sgattrs); + goto out_sgs_sgattrs; + } + + if (of_property_read_u32(node, "sensor-group-id", &sgid)) { + pr_warn("sensor-group-id property not found\n"); + goto out_sgs_sgattrs; + } + + if (!of_property_read_u32(node, "ibm,chip-id", &chipid)) + sprintf(sgs[i].name, "%s%d", node->name, chipid); + else + sprintf(sgs[i].name, "%s", node->name); + + sgs[i].sg.name = sgs[i].name; + if (add_attr_group(ops, len, &sgs[i], sgid)) { + pr_warn("Failed to create sensor attribute group %s\n", + sgs[i].sg.name); + goto out_sgs_sgattrs; + } + i++; + } + + return; + +out_sgs_sgattrs: + while (--i >= 0) { + kfree(sgs[i].sgattrs); + kfree(sgs[i].sg.attrs); + } + kobject_put(sg_kobj); +out_sgs: + kfree(sgs); +} diff --git a/arch/powerpc/platforms/powernv/opal-tracepoints.c b/arch/powerpc/platforms/powernv/opal-tracepoints.c index 3c447002edff..1ab7d26c0a2c 100644 --- a/arch/powerpc/platforms/powernv/opal-tracepoints.c +++ b/arch/powerpc/platforms/powernv/opal-tracepoints.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 4ca6c26a56d5..8c1ede2d3f7e 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S @@ -27,7 +27,7 @@ .globl opal_tracepoint_refcount opal_tracepoint_refcount: - .llong 0 + .8byte 0 .section ".text" @@ -310,3 +310,12 @@ OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP); OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT); OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT); OPAL_CALL(opal_npu_map_lpar, OPAL_NPU_MAP_LPAR); +OPAL_CALL(opal_imc_counters_init, OPAL_IMC_COUNTERS_INIT); +OPAL_CALL(opal_imc_counters_start, OPAL_IMC_COUNTERS_START); +OPAL_CALL(opal_imc_counters_stop, OPAL_IMC_COUNTERS_STOP); +OPAL_CALL(opal_pci_set_p2p, OPAL_PCI_SET_P2P); +OPAL_CALL(opal_get_powercap, OPAL_GET_POWERCAP); +OPAL_CALL(opal_set_powercap, OPAL_SET_POWERCAP); +OPAL_CALL(opal_get_power_shift_ratio, OPAL_GET_POWER_SHIFT_RATIO); +OPAL_CALL(opal_set_power_shift_ratio, OPAL_SET_POWER_SHIFT_RATIO); +OPAL_CALL(opal_sensor_group_clear, OPAL_SENSOR_GROUP_CLEAR); diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c index 28651fb25417..81c0a943dea9 100644 --- a/arch/powerpc/platforms/powernv/opal-xscom.c +++ b/arch/powerpc/platforms/powernv/opal-xscom.c @@ -36,14 +36,14 @@ static scom_map_t opal_scom_map(struct device_node *dev, u64 reg, u64 count) const __be32 *gcid; if (!of_get_property(dev, "scom-controller", NULL)) { - pr_err("%s: device %s is not a SCOM controller\n", - __func__, dev->full_name); + pr_err("%s: device %pOF is not a SCOM controller\n", + __func__, dev); return SCOM_MAP_INVALID; } gcid = of_get_property(dev, "ibm,chip-id", NULL); if (!gcid) { - pr_err("%s: device %s has no ibm,chip-id\n", - __func__, dev->full_name); + pr_err("%s: device %pOF has no ibm,chip-id\n", + __func__, dev); return SCOM_MAP_INVALID; } m = kmalloc(sizeof(struct opal_scom_map), GFP_KERNEL); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index cad6b57ce494..65c79ecf5a4d 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -25,11 +26,17 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include +#include +#include #include "powernv.h" @@ -162,12 +169,9 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node, sizeof(struct mcheck_recoverable_range); /* - * Allocate a buffer to hold the MC recoverable ranges. We would be - * accessing them in real mode, hence it needs to be within - * RMO region. + * Allocate a buffer to hold the MC recoverable ranges. */ - mc_recoverable_range =__va(memblock_alloc_base(size, __alignof__(u64), - ppc64_rma_size)); + mc_recoverable_range =__va(memblock_alloc(size, __alignof__(u64))); memset(mc_recoverable_range, 0, size); for (i = 0; i < mc_recoverable_range_len; i++) { @@ -422,24 +426,88 @@ static int opal_recover_mce(struct pt_regs *regs, /* Fatal machine check */ pr_err("Machine check interrupt is fatal\n"); recovered = 0; - } else if ((evt->severity == MCE_SEV_ERROR_SYNC) && - (user_mode(regs) && !is_global_init(current))) { + } + + if (!recovered && evt->severity == MCE_SEV_ERROR_SYNC) { /* - * For now, kill the task if we have received exception when - * in userspace. + * Try to kill processes if we get a synchronous machine check + * (e.g., one caused by execution of this instruction). This + * will devolve into a panic if we try to kill init or are in + * an interrupt etc. * * TODO: Queue up this address for hwpoisioning later. + * TODO: This is not quite right for d-side machine + * checks ->nip is not necessarily the important + * address. */ - _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip); - recovered = 1; + if ((user_mode(regs))) { + _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip); + recovered = 1; + } else if (die_will_crash()) { + /* + * die() would kill the kernel, so better to go via + * the platform reboot code that will log the + * machine check. + */ + recovered = 0; + } else { + die("Machine check", regs, SIGBUS); + recovered = 1; + } } + return recovered; } +void pnv_platform_error_reboot(struct pt_regs *regs, const char *msg) +{ + /* + * This is mostly taken from kernel/panic.c, but tries to do + * relatively minimal work. Don't use delay functions (TB may + * be broken), don't crash dump (need to set a firmware log), + * don't run notifiers. We do want to get some information to + * Linux console. + */ + console_verbose(); + bust_spinlocks(1); + pr_emerg("Hardware platform error: %s\n", msg); + if (regs) + show_regs(regs); + smp_send_stop(); + printk_safe_flush_on_panic(); + kmsg_dump(KMSG_DUMP_PANIC); + bust_spinlocks(0); + debug_locks_off(); + console_flush_on_panic(); + + /* + * Don't bother to shut things down because this will + * xstop the system. + */ + if (opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, msg) + == OPAL_UNSUPPORTED) { + pr_emerg("Reboot type %d not supported for %s\n", + OPAL_REBOOT_PLATFORM_ERROR, msg); + } + + /* + * We reached here. There can be three possibilities: + * 1. We are running on a firmware level that do not support + * opal_cec_reboot2() + * 2. We are running on a firmware level that do not support + * OPAL_REBOOT_PLATFORM_ERROR reboot type. + * 3. We are running on FSP based system that does not need + * opal to trigger checkstop explicitly for error analysis. + * The FSP PRD component would have already got notified + * about this error through other channels. + */ + + ppc_md.restart(NULL); +} + int opal_machine_check(struct pt_regs *regs) { struct machine_check_event evt; - int ret; if (!get_mce_event(&evt, MCE_EVENT_RELEASE)) return 0; @@ -455,43 +523,7 @@ int opal_machine_check(struct pt_regs *regs) if (opal_recover_mce(regs, &evt)) return 1; - /* - * Unrecovered machine check, we are heading to panic path. - * - * We may have hit this MCE in very early stage of kernel - * initialization even before opal-prd has started running. If - * this is the case then this MCE error may go un-noticed or - * un-analyzed if we go down panic path. We need to inform - * BMC/OCC about this error so that they can collect relevant - * data for error analysis before rebooting. - * Use opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR) to do so. - * This function may not return on BMC based system. - */ - ret = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, - "Unrecoverable Machine Check exception"); - if (ret == OPAL_UNSUPPORTED) { - pr_emerg("Reboot type %d not supported\n", - OPAL_REBOOT_PLATFORM_ERROR); - } - - /* - * We reached here. There can be three possibilities: - * 1. We are running on a firmware level that do not support - * opal_cec_reboot2() - * 2. We are running on a firmware level that do not support - * OPAL_REBOOT_PLATFORM_ERROR reboot type. - * 3. We are running on FSP based system that does not need opal - * to trigger checkstop explicitly for error analysis. The FSP - * PRD component would have already got notified about this - * error through other channels. - * - * If hardware marked this as an unrecoverable MCE, we are - * going to panic anyway. Even if it didn't, it's not safe to - * continue at this point, so we should explicitly panic. - */ - - panic("PowerNV Unrecovered Machine Check"); - return 0; + pnv_platform_error_reboot(regs, "Unrecoverable Machine Check exception"); } /* Early hmi handler called in real mode. */ @@ -720,6 +752,15 @@ static void opal_pdev_init(const char *compatible) of_platform_device_create(np, NULL, NULL); } +static void __init opal_imc_init_dev(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, IMC_DTB_COMPAT); + if (np) + of_platform_device_create(np, NULL, NULL); +} + static int kopald(void *unused) { unsigned long timeout = msecs_to_jiffies(opal_heartbeat) + 1; @@ -793,6 +834,9 @@ static int __init opal_init(void) /* Setup a heatbeat thread if requested by OPAL */ opal_init_heartbeat(); + /* Detect In-Memory Collection counters and create devices*/ + opal_imc_init_dev(); + /* Create leds platform devices */ leds = of_find_node_by_path("/ibm,opal/leds"); if (leds) { @@ -836,6 +880,15 @@ static int __init opal_init(void) /* Initialise OPAL kmsg dumper for flushing console on panic */ opal_kmsg_init(); + /* Initialise OPAL powercap interface */ + opal_powercap_init(); + + /* Initialise OPAL Power-Shifting-Ratio interface */ + opal_psr_init(); + + /* Initialise OPAL sensor groups */ + opal_sensor_groups_init(); + return 0; } machine_subsys_initcall(powernv, opal_init); @@ -952,6 +1005,7 @@ int opal_error_code(int rc) case OPAL_UNSUPPORTED: return -EIO; case OPAL_HARDWARE: return -EIO; case OPAL_INTERNAL_ERROR: return -EIO; + case OPAL_TIMEOUT: return -ETIMEDOUT; default: pr_err("%s: unexpected OPAL error %d\n", __func__, rc); return -EIO; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index b900eb1d5e17..57f9e55f4352 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -444,8 +444,8 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) r = of_get_property(dn, "ibm,opal-m64-window", NULL); if (!r) { - pr_info(" No on %s\n", - dn->full_name); + pr_info(" No on %pOF\n", + dn); return; } @@ -1408,7 +1408,6 @@ m64_failed: static long pnv_pci_ioda2_unset_window(struct iommu_table_group *table_group, int num); -static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable); static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe *pe) { @@ -2402,7 +2401,7 @@ static long pnv_pci_ioda2_set_window(struct iommu_table_group *table_group, return 0; } -static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable) +void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable) { uint16_t window_id = (pe->pe_number << 1 ) + 1; int64_t rc; @@ -3797,8 +3796,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, if (!of_device_is_available(np)) return; - pr_info("Initializing %s PHB (%s)\n", - pnv_phb_names[ioda_type], of_node_full_name(np)); + pr_info("Initializing %s PHB (%pOF)\n", pnv_phb_names[ioda_type], np); prop64 = of_get_property(np, "ibm,opal-phbid", NULL); if (!prop64) { @@ -3813,8 +3811,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, /* Allocate PCI controller */ phb->hose = hose = pcibios_alloc_controller(np); if (!phb->hose) { - pr_err(" Can't allocate PCI controller for %s\n", - np->full_name); + pr_err(" Can't allocate PCI controller for %pOF\n", + np); memblock_free(__pa(phb), sizeof(struct pnv_phb)); return; } @@ -3825,7 +3823,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, hose->first_busno = be32_to_cpu(prop32[0]); hose->last_busno = be32_to_cpu(prop32[1]); } else { - pr_warn(" Broken on %s\n", np->full_name); + pr_warn(" Broken on %pOF\n", np); hose->first_busno = 0; hose->last_busno = 0xff; } @@ -4046,7 +4044,7 @@ void __init pnv_pci_init_ioda_hub(struct device_node *np) const __be64 *prop64; u64 hub_id; - pr_info("Probing IODA IO-Hub %s\n", np->full_name); + pr_info("Probing IODA IO-Hub %pOF\n", np); prop64 = of_get_property(np, "ibm,opal-hubid", NULL); if (!prop64) { diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 7905d179d036..5422f4a6317c 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -37,6 +37,8 @@ #include "powernv.h" #include "pci.h" +static DEFINE_MUTEX(p2p_mutex); + int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id) { struct device_node *parent = np; @@ -1017,6 +1019,79 @@ void pnv_pci_dma_bus_setup(struct pci_bus *bus) } } +int pnv_pci_set_p2p(struct pci_dev *initiator, struct pci_dev *target, u64 desc) +{ + struct pci_controller *hose; + struct pnv_phb *phb_init, *phb_target; + struct pnv_ioda_pe *pe_init; + int rc; + + if (!opal_check_token(OPAL_PCI_SET_P2P)) + return -ENXIO; + + hose = pci_bus_to_host(initiator->bus); + phb_init = hose->private_data; + + hose = pci_bus_to_host(target->bus); + phb_target = hose->private_data; + + pe_init = pnv_ioda_get_pe(initiator); + if (!pe_init) + return -ENODEV; + + /* + * Configuring the initiator's PHB requires to adjust its + * TVE#1 setting. Since the same device can be an initiator + * several times for different target devices, we need to keep + * a reference count to know when we can restore the default + * bypass setting on its TVE#1 when disabling. Opal is not + * tracking PE states, so we add a reference count on the PE + * in linux. + * + * For the target, the configuration is per PHB, so we keep a + * target reference count on the PHB. + */ + mutex_lock(&p2p_mutex); + + if (desc & OPAL_PCI_P2P_ENABLE) { + /* always go to opal to validate the configuration */ + rc = opal_pci_set_p2p(phb_init->opal_id, phb_target->opal_id, + desc, pe_init->pe_number); + + if (rc != OPAL_SUCCESS) { + rc = -EIO; + goto out; + } + + pe_init->p2p_initiator_count++; + phb_target->p2p_target_count++; + } else { + if (!pe_init->p2p_initiator_count || + !phb_target->p2p_target_count) { + rc = -EINVAL; + goto out; + } + + if (--pe_init->p2p_initiator_count == 0) + pnv_pci_ioda2_set_bypass(pe_init, true); + + if (--phb_target->p2p_target_count == 0) { + rc = opal_pci_set_p2p(phb_init->opal_id, + phb_target->opal_id, desc, + pe_init->pe_number); + if (rc != OPAL_SUCCESS) { + rc = -EIO; + goto out; + } + } + } + rc = 0; +out: + mutex_unlock(&p2p_mutex); + return rc; +} +EXPORT_SYMBOL_GPL(pnv_pci_set_p2p); + void pnv_pci_shutdown(void) { struct pci_controller *hose; diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index f16bc403ec03..b47f9406d97e 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __POWERNV_PCI_H #define __POWERNV_PCI_H @@ -78,6 +79,9 @@ struct pnv_ioda_pe { struct pnv_ioda_pe *master; struct list_head slaves; + /* PCI peer-to-peer*/ + int p2p_initiator_count; + /* Link in list of PE#s */ struct list_head list; }; @@ -189,6 +193,7 @@ struct pnv_phb { #ifdef CONFIG_CXL_BASE struct cxl_afu *cxl_afu; #endif + int p2p_target_count; }; extern struct pci_ops pnv_pci_ops; @@ -229,6 +234,7 @@ extern void pnv_teardown_msi_irqs(struct pci_dev *pdev); extern struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev); extern void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq); extern bool pnv_pci_enable_device_hook(struct pci_dev *dev); +extern void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable); extern void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, const char *fmt, ...); diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h index 6dbc0a1da1f6..94f17ab1374b 100644 --- a/arch/powerpc/platforms/powernv/powernv.h +++ b/arch/powerpc/platforms/powernv/powernv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _POWERNV_H #define _POWERNV_H @@ -7,6 +8,8 @@ extern void pnv_smp_init(void); static inline void pnv_smp_init(void) { } #endif +extern void pnv_platform_error_reboot(struct pt_regs *regs, const char *msg) __noreturn; + struct pci_dev; #ifdef CONFIG_PCI diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 1a9d84371a4d..718f50ed22f1 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -16,11 +16,13 @@ #include #include #include +#include #include #include #include #include +#define DARN_ERR 0xFFFFFFFFFFFFFFFFul struct powernv_rng { void __iomem *regs; @@ -67,6 +69,41 @@ int powernv_get_random_real_mode(unsigned long *v) return 1; } +int powernv_get_random_darn(unsigned long *v) +{ + unsigned long val; + + /* Using DARN with L=1 - 64-bit conditioned random number */ + asm volatile(PPC_DARN(%0, 1) : "=r"(val)); + + if (val == DARN_ERR) + return 0; + + *v = val; + + return 1; +} + +static int initialise_darn(void) +{ + unsigned long val; + int i; + + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + return -ENODEV; + + for (i = 0; i < 10; i++) { + if (powernv_get_random_darn(&val)) { + ppc_md.get_random_seed = powernv_get_random_darn; + return 0; + } + } + + pr_warn("Unable to use DARN for get_random_seed()\n"); + + return -EIO; +} + int powernv_get_random_long(unsigned long *v) { struct powernv_rng *rng; @@ -88,7 +125,7 @@ static __init void rng_init_per_cpu(struct powernv_rng *rng, chip_id = of_get_ibm_chip_id(dn); if (chip_id == -1) - pr_warn("No ibm,chip-id found for %s.\n", dn->full_name); + pr_warn("No ibm,chip-id found for %pOF.\n", dn); for_each_possible_cpu(cpu) { if (per_cpu(powernv_rng, cpu) == NULL || @@ -141,8 +178,8 @@ static __init int rng_init(void) for_each_compatible_node(dn, NULL, "ibm,power-rng") { rc = rng_create(dn); if (rc) { - pr_err("Failed creating rng for %s (%d).\n", - dn->full_name, rc); + pr_err("Failed creating rng for %pOF (%d).\n", + dn, rc); continue; } @@ -150,6 +187,8 @@ static __init int rng_init(void) of_platform_device_create(dn, NULL, NULL); } + initialise_darn(); + return 0; } machine_subsys_initcall(powernv, rng_init); diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 897aa1400eb8..bbb73aa0eb8f 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -272,7 +272,15 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE static unsigned long pnv_memory_block_size(void) { - return 256UL * 1024 * 1024; + /* + * We map the kernel linear region with 1GB large pages on radix. For + * memory hot unplug to work our memory block size must be at least + * this size. + */ + if (radix_enabled()) + return 1UL * 1024 * 1024 * 1024; + else + return 256UL * 1024 * 1024; } #endif diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 40dae96f7e20..c17f81e433f7 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -57,7 +57,7 @@ static void pnv_smp_setup_cpu(int cpu) static int pnv_smp_kick_cpu(int nr) { - unsigned int pcpu = get_hard_smp_processor_id(nr); + unsigned int pcpu; unsigned long start_here = __pa(ppc_function_entry(generic_secondary_smp_init)); long rc; @@ -66,6 +66,7 @@ static int pnv_smp_kick_cpu(int nr) if (nr < 0 || nr >= nr_cpu_ids) return -EINVAL; + pcpu = get_hard_smp_processor_id(nr); /* * If we already started or OPAL is not supported, we just * kick the CPU via the PACA @@ -164,12 +165,6 @@ static void pnv_smp_cpu_kill_self(void) if (cpu_has_feature(CPU_FTR_ARCH_207S)) wmask = SRR1_WAKEMASK_P8; - /* We don't want to take decrementer interrupts while we are offline, - * so clear LPCR:PECE1. We keep PECE2 (and LPCR_PECE_HVEE on P9) - * enabled as to let IPIs in. - */ - mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); - while (!generic_check_cpu_restart(cpu)) { /* * Clear IPI flag, since we don't handle IPIs while @@ -219,8 +214,6 @@ static void pnv_smp_cpu_kill_self(void) } - /* Re-enable decrementer interrupts */ - mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) | LPCR_PECE1); DBG("CPU%d coming online...\n", cpu); } diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c new file mode 100644 index 000000000000..5aae845b8cd9 --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -0,0 +1,1134 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "vas: " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include "vas.h" +#include "copy-paste.h" + +/* + * Compute the paste address region for the window @window using the + * ->paste_base_addr and ->paste_win_id_shift we got from device tree. + */ +static void compute_paste_address(struct vas_window *window, u64 *addr, int *len) +{ + int winid; + u64 base, shift; + + base = window->vinst->paste_base_addr; + shift = window->vinst->paste_win_id_shift; + winid = window->winid; + + *addr = base + (winid << shift); + if (len) + *len = PAGE_SIZE; + + pr_debug("Txwin #%d: Paste addr 0x%llx\n", winid, *addr); +} + +static inline void get_hvwc_mmio_bar(struct vas_window *window, + u64 *start, int *len) +{ + u64 pbaddr; + + pbaddr = window->vinst->hvwc_bar_start; + *start = pbaddr + window->winid * VAS_HVWC_SIZE; + *len = VAS_HVWC_SIZE; +} + +static inline void get_uwc_mmio_bar(struct vas_window *window, + u64 *start, int *len) +{ + u64 pbaddr; + + pbaddr = window->vinst->uwc_bar_start; + *start = pbaddr + window->winid * VAS_UWC_SIZE; + *len = VAS_UWC_SIZE; +} + +/* + * Map the paste bus address of the given send window into kernel address + * space. Unlike MMIO regions (map_mmio_region() below), paste region must + * be mapped cache-able and is only applicable to send windows. + */ +static void *map_paste_region(struct vas_window *txwin) +{ + int len; + void *map; + char *name; + u64 start; + + name = kasprintf(GFP_KERNEL, "window-v%d-w%d", txwin->vinst->vas_id, + txwin->winid); + if (!name) + goto free_name; + + txwin->paste_addr_name = name; + compute_paste_address(txwin, &start, &len); + + if (!request_mem_region(start, len, name)) { + pr_devel("%s(): request_mem_region(0x%llx, %d) failed\n", + __func__, start, len); + goto free_name; + } + + map = ioremap_cache(start, len); + if (!map) { + pr_devel("%s(): ioremap_cache(0x%llx, %d) failed\n", __func__, + start, len); + goto free_name; + } + + pr_devel("Mapped paste addr 0x%llx to kaddr 0x%p\n", start, map); + return map; + +free_name: + kfree(name); + return ERR_PTR(-ENOMEM); +} + +static void *map_mmio_region(char *name, u64 start, int len) +{ + void *map; + + if (!request_mem_region(start, len, name)) { + pr_devel("%s(): request_mem_region(0x%llx, %d) failed\n", + __func__, start, len); + return NULL; + } + + map = ioremap(start, len); + if (!map) { + pr_devel("%s(): ioremap(0x%llx, %d) failed\n", __func__, start, + len); + return NULL; + } + + return map; +} + +static void unmap_region(void *addr, u64 start, int len) +{ + iounmap(addr); + release_mem_region((phys_addr_t)start, len); +} + +/* + * Unmap the paste address region for a window. + */ +static void unmap_paste_region(struct vas_window *window) +{ + int len; + u64 busaddr_start; + + if (window->paste_kaddr) { + compute_paste_address(window, &busaddr_start, &len); + unmap_region(window->paste_kaddr, busaddr_start, len); + window->paste_kaddr = NULL; + kfree(window->paste_addr_name); + window->paste_addr_name = NULL; + } +} + +/* + * Unmap the MMIO regions for a window. + */ +static void unmap_winctx_mmio_bars(struct vas_window *window) +{ + int len; + u64 busaddr_start; + + if (window->hvwc_map) { + get_hvwc_mmio_bar(window, &busaddr_start, &len); + unmap_region(window->hvwc_map, busaddr_start, len); + window->hvwc_map = NULL; + } + + if (window->uwc_map) { + get_uwc_mmio_bar(window, &busaddr_start, &len); + unmap_region(window->uwc_map, busaddr_start, len); + window->uwc_map = NULL; + } +} + +/* + * Find the Hypervisor Window Context (HVWC) MMIO Base Address Region and the + * OS/User Window Context (UWC) MMIO Base Address Region for the given window. + * Map these bus addresses and save the mapped kernel addresses in @window. + */ +int map_winctx_mmio_bars(struct vas_window *window) +{ + int len; + u64 start; + + get_hvwc_mmio_bar(window, &start, &len); + window->hvwc_map = map_mmio_region("HVWCM_Window", start, len); + + get_uwc_mmio_bar(window, &start, &len); + window->uwc_map = map_mmio_region("UWCM_Window", start, len); + + if (!window->hvwc_map || !window->uwc_map) { + unmap_winctx_mmio_bars(window); + return -1; + } + + return 0; +} + +/* + * Reset all valid registers in the HV and OS/User Window Contexts for + * the window identified by @window. + * + * NOTE: We cannot really use a for loop to reset window context. Not all + * offsets in a window context are valid registers and the valid + * registers are not sequential. And, we can only write to offsets + * with valid registers. + */ +void reset_window_regs(struct vas_window *window) +{ + write_hvwc_reg(window, VREG(LPID), 0ULL); + write_hvwc_reg(window, VREG(PID), 0ULL); + write_hvwc_reg(window, VREG(XLATE_MSR), 0ULL); + write_hvwc_reg(window, VREG(XLATE_LPCR), 0ULL); + write_hvwc_reg(window, VREG(XLATE_CTL), 0ULL); + write_hvwc_reg(window, VREG(AMR), 0ULL); + write_hvwc_reg(window, VREG(SEIDR), 0ULL); + write_hvwc_reg(window, VREG(FAULT_TX_WIN), 0ULL); + write_hvwc_reg(window, VREG(OSU_INTR_SRC_RA), 0ULL); + write_hvwc_reg(window, VREG(HV_INTR_SRC_RA), 0ULL); + write_hvwc_reg(window, VREG(PSWID), 0ULL); + write_hvwc_reg(window, VREG(LFIFO_BAR), 0ULL); + write_hvwc_reg(window, VREG(LDATA_STAMP_CTL), 0ULL); + write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), 0ULL); + write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL); + write_hvwc_reg(window, VREG(CURR_MSG_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_AFTER_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LRX_WCRED), 0ULL); + write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); + write_hvwc_reg(window, VREG(TX_WCRED), 0ULL); + write_hvwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); + write_hvwc_reg(window, VREG(LFIFO_SIZE), 0ULL); + write_hvwc_reg(window, VREG(WINCTL), 0ULL); + write_hvwc_reg(window, VREG(WIN_STATUS), 0ULL); + write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), 0ULL); + write_hvwc_reg(window, VREG(TX_RSVD_BUF_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LRFIFO_WIN_PTR), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_CTL), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_PID), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_LPID), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_TID), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_SCOPE), 0ULL); + write_hvwc_reg(window, VREG(NX_UTIL_ADDER), 0ULL); + + /* Skip read-only registers: NX_UTIL and NX_UTIL_SE */ + + /* + * The send and receive window credit adder registers are also + * accessible from HVWC and have been initialized above. We don't + * need to initialize from the OS/User Window Context, so skip + * following calls: + * + * write_uwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); + * write_uwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); + */ +} + +/* + * Initialize window context registers related to Address Translation. + * These registers are common to send/receive windows although they + * differ for user/kernel windows. As we resolve the TODOs we may + * want to add fields to vas_winctx and move the initialization to + * init_vas_winctx_regs(). + */ +static void init_xlate_regs(struct vas_window *window, bool user_win) +{ + u64 lpcr, val; + + /* + * MSR_TA, MSR_US are false for both kernel and user. + * MSR_DR and MSR_PR are false for kernel. + */ + val = 0ULL; + val = SET_FIELD(VAS_XLATE_MSR_HV, val, 1); + val = SET_FIELD(VAS_XLATE_MSR_SF, val, 1); + if (user_win) { + val = SET_FIELD(VAS_XLATE_MSR_DR, val, 1); + val = SET_FIELD(VAS_XLATE_MSR_PR, val, 1); + } + write_hvwc_reg(window, VREG(XLATE_MSR), val); + + lpcr = mfspr(SPRN_LPCR); + val = 0ULL; + /* + * NOTE: From Section 5.7.8.1 Segment Lookaside Buffer of the + * Power ISA, v3.0B, Page size encoding is 0 = 4KB, 5 = 64KB. + * + * NOTE: From Section 1.3.1, Address Translation Context of the + * Nest MMU Workbook, LPCR_SC should be 0 for Power9. + */ + val = SET_FIELD(VAS_XLATE_LPCR_PAGE_SIZE, val, 5); + val = SET_FIELD(VAS_XLATE_LPCR_ISL, val, lpcr & LPCR_ISL); + val = SET_FIELD(VAS_XLATE_LPCR_TC, val, lpcr & LPCR_TC); + val = SET_FIELD(VAS_XLATE_LPCR_SC, val, 0); + write_hvwc_reg(window, VREG(XLATE_LPCR), val); + + /* + * Section 1.3.1 (Address translation Context) of NMMU workbook. + * 0b00 Hashed Page Table mode + * 0b01 Reserved + * 0b10 Radix on HPT + * 0b11 Radix on Radix + */ + val = 0ULL; + val = SET_FIELD(VAS_XLATE_MODE, val, radix_enabled() ? 3 : 2); + write_hvwc_reg(window, VREG(XLATE_CTL), val); + + /* + * TODO: Can we mfspr(AMR) even for user windows? + */ + val = 0ULL; + val = SET_FIELD(VAS_AMR, val, mfspr(SPRN_AMR)); + write_hvwc_reg(window, VREG(AMR), val); + + val = 0ULL; + val = SET_FIELD(VAS_SEIDR, val, 0); + write_hvwc_reg(window, VREG(SEIDR), val); +} + +/* + * Initialize Reserved Send Buffer Count for the send window. It involves + * writing to the register, reading it back to confirm that the hardware + * has enough buffers to reserve. See section 1.3.1.2.1 of VAS workbook. + * + * Since we can only make a best-effort attempt to fulfill the request, + * we don't return any errors if we cannot. + * + * TODO: Reserved (aka dedicated) send buffers are not supported yet. + */ +static void init_rsvd_tx_buf_count(struct vas_window *txwin, + struct vas_winctx *winctx) +{ + write_hvwc_reg(txwin, VREG(TX_RSVD_BUF_COUNT), 0ULL); +} + +/* + * init_winctx_regs() + * Initialize window context registers for a receive window. + * Except for caching control and marking window open, the registers + * are initialized in the order listed in Section 3.1.4 (Window Context + * Cache Register Details) of the VAS workbook although they don't need + * to be. + * + * Design note: For NX receive windows, NX allocates the FIFO buffer in OPAL + * (so that it can get a large contiguous area) and passes that buffer + * to kernel via device tree. We now write that buffer address to the + * FIFO BAR. Would it make sense to do this all in OPAL? i.e have OPAL + * write the per-chip RX FIFO addresses to the windows during boot-up + * as a one-time task? That could work for NX but what about other + * receivers? Let the receivers tell us the rx-fifo buffers for now. + */ +int init_winctx_regs(struct vas_window *window, struct vas_winctx *winctx) +{ + u64 val; + int fifo_size; + + reset_window_regs(window); + + val = 0ULL; + val = SET_FIELD(VAS_LPID, val, winctx->lpid); + write_hvwc_reg(window, VREG(LPID), val); + + val = 0ULL; + val = SET_FIELD(VAS_PID_ID, val, winctx->pidr); + write_hvwc_reg(window, VREG(PID), val); + + init_xlate_regs(window, winctx->user_win); + + val = 0ULL; + val = SET_FIELD(VAS_FAULT_TX_WIN, val, 0); + write_hvwc_reg(window, VREG(FAULT_TX_WIN), val); + + /* In PowerNV, interrupts go to HV. */ + write_hvwc_reg(window, VREG(OSU_INTR_SRC_RA), 0ULL); + + val = 0ULL; + val = SET_FIELD(VAS_HV_INTR_SRC_RA, val, winctx->irq_port); + write_hvwc_reg(window, VREG(HV_INTR_SRC_RA), val); + + val = 0ULL; + val = SET_FIELD(VAS_PSWID_EA_HANDLE, val, winctx->pswid); + write_hvwc_reg(window, VREG(PSWID), val); + + write_hvwc_reg(window, VREG(SPARE1), 0ULL); + write_hvwc_reg(window, VREG(SPARE2), 0ULL); + write_hvwc_reg(window, VREG(SPARE3), 0ULL); + + /* + * NOTE: VAS expects the FIFO address to be copied into the LFIFO_BAR + * register as is - do NOT shift the address into VAS_LFIFO_BAR + * bit fields! Ok to set the page migration select fields - + * VAS ignores the lower 10+ bits in the address anyway, because + * the minimum FIFO size is 1K? + * + * See also: Design note in function header. + */ + val = __pa(winctx->rx_fifo); + val = SET_FIELD(VAS_PAGE_MIGRATION_SELECT, val, 0); + write_hvwc_reg(window, VREG(LFIFO_BAR), val); + + val = 0ULL; + val = SET_FIELD(VAS_LDATA_STAMP, val, winctx->data_stamp); + write_hvwc_reg(window, VREG(LDATA_STAMP_CTL), val); + + val = 0ULL; + val = SET_FIELD(VAS_LDMA_TYPE, val, winctx->dma_type); + val = SET_FIELD(VAS_LDMA_FIFO_DISABLE, val, winctx->fifo_disable); + write_hvwc_reg(window, VREG(LDMA_CACHE_CTL), val); + + write_hvwc_reg(window, VREG(LRFIFO_PUSH), 0ULL); + write_hvwc_reg(window, VREG(CURR_MSG_COUNT), 0ULL); + write_hvwc_reg(window, VREG(LNOTIFY_AFTER_COUNT), 0ULL); + + val = 0ULL; + val = SET_FIELD(VAS_LRX_WCRED, val, winctx->wcreds_max); + write_hvwc_reg(window, VREG(LRX_WCRED), val); + + val = 0ULL; + val = SET_FIELD(VAS_TX_WCRED, val, winctx->wcreds_max); + write_hvwc_reg(window, VREG(TX_WCRED), val); + + write_hvwc_reg(window, VREG(LRX_WCRED_ADDER), 0ULL); + write_hvwc_reg(window, VREG(TX_WCRED_ADDER), 0ULL); + + fifo_size = winctx->rx_fifo_size / 1024; + + val = 0ULL; + val = SET_FIELD(VAS_LFIFO_SIZE, val, ilog2(fifo_size)); + write_hvwc_reg(window, VREG(LFIFO_SIZE), val); + + /* Update window control and caching control registers last so + * we mark the window open only after fully initializing it and + * pushing context to cache. + */ + + write_hvwc_reg(window, VREG(WIN_STATUS), 0ULL); + + init_rsvd_tx_buf_count(window, winctx); + + /* for a send window, point to the matching receive window */ + val = 0ULL; + val = SET_FIELD(VAS_LRX_WIN_ID, val, winctx->rx_win_id); + write_hvwc_reg(window, VREG(LRFIFO_WIN_PTR), val); + + write_hvwc_reg(window, VREG(SPARE4), 0ULL); + + val = 0ULL; + val = SET_FIELD(VAS_NOTIFY_DISABLE, val, winctx->notify_disable); + val = SET_FIELD(VAS_INTR_DISABLE, val, winctx->intr_disable); + val = SET_FIELD(VAS_NOTIFY_EARLY, val, winctx->notify_early); + val = SET_FIELD(VAS_NOTIFY_OSU_INTR, val, winctx->notify_os_intr_reg); + write_hvwc_reg(window, VREG(LNOTIFY_CTL), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_PID, val, winctx->lnotify_pid); + write_hvwc_reg(window, VREG(LNOTIFY_PID), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_LPID, val, winctx->lnotify_lpid); + write_hvwc_reg(window, VREG(LNOTIFY_LPID), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_TID, val, winctx->lnotify_tid); + write_hvwc_reg(window, VREG(LNOTIFY_TID), val); + + val = 0ULL; + val = SET_FIELD(VAS_LNOTIFY_MIN_SCOPE, val, winctx->min_scope); + val = SET_FIELD(VAS_LNOTIFY_MAX_SCOPE, val, winctx->max_scope); + write_hvwc_reg(window, VREG(LNOTIFY_SCOPE), val); + + /* Skip read-only registers NX_UTIL and NX_UTIL_SE */ + + write_hvwc_reg(window, VREG(SPARE5), 0ULL); + write_hvwc_reg(window, VREG(NX_UTIL_ADDER), 0ULL); + write_hvwc_reg(window, VREG(SPARE6), 0ULL); + + /* Finally, push window context to memory and... */ + val = 0ULL; + val = SET_FIELD(VAS_PUSH_TO_MEM, val, 1); + write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), val); + + /* ... mark the window open for business */ + val = 0ULL; + val = SET_FIELD(VAS_WINCTL_REJ_NO_CREDIT, val, winctx->rej_no_credit); + val = SET_FIELD(VAS_WINCTL_PIN, val, winctx->pin_win); + val = SET_FIELD(VAS_WINCTL_TX_WCRED_MODE, val, winctx->tx_wcred_mode); + val = SET_FIELD(VAS_WINCTL_RX_WCRED_MODE, val, winctx->rx_wcred_mode); + val = SET_FIELD(VAS_WINCTL_TX_WORD_MODE, val, winctx->tx_word_mode); + val = SET_FIELD(VAS_WINCTL_RX_WORD_MODE, val, winctx->rx_word_mode); + val = SET_FIELD(VAS_WINCTL_FAULT_WIN, val, winctx->fault_win); + val = SET_FIELD(VAS_WINCTL_NX_WIN, val, winctx->nx_win); + val = SET_FIELD(VAS_WINCTL_OPEN, val, 1); + write_hvwc_reg(window, VREG(WINCTL), val); + + return 0; +} + +static DEFINE_SPINLOCK(vas_ida_lock); + +static void vas_release_window_id(struct ida *ida, int winid) +{ + spin_lock(&vas_ida_lock); + ida_remove(ida, winid); + spin_unlock(&vas_ida_lock); +} + +static int vas_assign_window_id(struct ida *ida) +{ + int rc, winid; + + do { + rc = ida_pre_get(ida, GFP_KERNEL); + if (!rc) + return -EAGAIN; + + spin_lock(&vas_ida_lock); + rc = ida_get_new(ida, &winid); + spin_unlock(&vas_ida_lock); + } while (rc == -EAGAIN); + + if (rc) + return rc; + + if (winid > VAS_WINDOWS_PER_CHIP) { + pr_err("Too many (%d) open windows\n", winid); + vas_release_window_id(ida, winid); + return -EAGAIN; + } + + return winid; +} + +static void vas_window_free(struct vas_window *window) +{ + int winid = window->winid; + struct vas_instance *vinst = window->vinst; + + unmap_winctx_mmio_bars(window); + kfree(window); + + vas_release_window_id(&vinst->ida, winid); +} + +static struct vas_window *vas_window_alloc(struct vas_instance *vinst) +{ + int winid; + struct vas_window *window; + + winid = vas_assign_window_id(&vinst->ida); + if (winid < 0) + return ERR_PTR(winid); + + window = kzalloc(sizeof(*window), GFP_KERNEL); + if (!window) + goto out_free; + + window->vinst = vinst; + window->winid = winid; + + if (map_winctx_mmio_bars(window)) + goto out_free; + + return window; + +out_free: + kfree(window); + vas_release_window_id(&vinst->ida, winid); + return ERR_PTR(-ENOMEM); +} + +static void put_rx_win(struct vas_window *rxwin) +{ + /* Better not be a send window! */ + WARN_ON_ONCE(rxwin->tx_win); + + atomic_dec(&rxwin->num_txwins); +} + +/* + * Get the VAS receive window associated with NX engine identified + * by @cop and if applicable, @pswid. + * + * See also function header of set_vinst_win(). + */ +static struct vas_window *get_vinst_rxwin(struct vas_instance *vinst, + enum vas_cop_type cop, u32 pswid) +{ + struct vas_window *rxwin; + + mutex_lock(&vinst->mutex); + + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) + rxwin = vinst->rxwin[cop] ?: ERR_PTR(-EINVAL); + else + rxwin = ERR_PTR(-EINVAL); + + if (!IS_ERR(rxwin)) + atomic_inc(&rxwin->num_txwins); + + mutex_unlock(&vinst->mutex); + + return rxwin; +} + +/* + * We have two tables of windows in a VAS instance. The first one, + * ->windows[], contains all the windows in the instance and allows + * looking up a window by its id. It is used to look up send windows + * during fault handling and receive windows when pairing user space + * send/receive windows. + * + * The second table, ->rxwin[], contains receive windows that are + * associated with NX engines. This table has VAS_COP_TYPE_MAX + * entries and is used to look up a receive window by its + * coprocessor type. + * + * Here, we save @window in the ->windows[] table. If it is a receive + * window, we also save the window in the ->rxwin[] table. + */ +static void set_vinst_win(struct vas_instance *vinst, + struct vas_window *window) +{ + int id = window->winid; + + mutex_lock(&vinst->mutex); + + /* + * There should only be one receive window for a coprocessor type + * unless its a user (FTW) window. + */ + if (!window->user_win && !window->tx_win) { + WARN_ON_ONCE(vinst->rxwin[window->cop]); + vinst->rxwin[window->cop] = window; + } + + WARN_ON_ONCE(vinst->windows[id] != NULL); + vinst->windows[id] = window; + + mutex_unlock(&vinst->mutex); +} + +/* + * Clear this window from the table(s) of windows for this VAS instance. + * See also function header of set_vinst_win(). + */ +static void clear_vinst_win(struct vas_window *window) +{ + int id = window->winid; + struct vas_instance *vinst = window->vinst; + + mutex_lock(&vinst->mutex); + + if (!window->user_win && !window->tx_win) { + WARN_ON_ONCE(!vinst->rxwin[window->cop]); + vinst->rxwin[window->cop] = NULL; + } + + WARN_ON_ONCE(vinst->windows[id] != window); + vinst->windows[id] = NULL; + + mutex_unlock(&vinst->mutex); +} + +static void init_winctx_for_rxwin(struct vas_window *rxwin, + struct vas_rx_win_attr *rxattr, + struct vas_winctx *winctx) +{ + /* + * We first zero (memset()) all fields and only set non-zero fields. + * Following fields are 0/false but maybe deserve a comment: + * + * ->notify_os_intr_reg In powerNV, send intrs to HV + * ->notify_disable False for NX windows + * ->intr_disable False for Fault Windows + * ->xtra_write False for NX windows + * ->notify_early NA for NX windows + * ->rsvd_txbuf_count NA for Rx windows + * ->lpid, ->pid, ->tid NA for Rx windows + */ + + memset(winctx, 0, sizeof(struct vas_winctx)); + + winctx->rx_fifo = rxattr->rx_fifo; + winctx->rx_fifo_size = rxattr->rx_fifo_size; + winctx->wcreds_max = rxattr->wcreds_max ?: VAS_WCREDS_DEFAULT; + winctx->pin_win = rxattr->pin_win; + + winctx->nx_win = rxattr->nx_win; + winctx->fault_win = rxattr->fault_win; + winctx->rx_word_mode = rxattr->rx_win_ord_mode; + winctx->tx_word_mode = rxattr->tx_win_ord_mode; + winctx->rx_wcred_mode = rxattr->rx_wcred_mode; + winctx->tx_wcred_mode = rxattr->tx_wcred_mode; + + if (winctx->nx_win) { + winctx->data_stamp = true; + winctx->intr_disable = true; + winctx->pin_win = true; + + WARN_ON_ONCE(winctx->fault_win); + WARN_ON_ONCE(!winctx->rx_word_mode); + WARN_ON_ONCE(!winctx->tx_word_mode); + WARN_ON_ONCE(winctx->notify_after_count); + } else if (winctx->fault_win) { + winctx->notify_disable = true; + } else if (winctx->user_win) { + /* + * Section 1.8.1 Low Latency Core-Core Wake up of + * the VAS workbook: + * + * - disable credit checks ([tr]x_wcred_mode = false) + * - disable FIFO writes + * - enable ASB_Notify, disable interrupt + */ + winctx->fifo_disable = true; + winctx->intr_disable = true; + winctx->rx_fifo = NULL; + } + + winctx->lnotify_lpid = rxattr->lnotify_lpid; + winctx->lnotify_pid = rxattr->lnotify_pid; + winctx->lnotify_tid = rxattr->lnotify_tid; + winctx->pswid = rxattr->pswid; + winctx->dma_type = VAS_DMA_TYPE_INJECT; + winctx->tc_mode = rxattr->tc_mode; + + winctx->min_scope = VAS_SCOPE_LOCAL; + winctx->max_scope = VAS_SCOPE_VECTORED_GROUP; +} + +static bool rx_win_args_valid(enum vas_cop_type cop, + struct vas_rx_win_attr *attr) +{ + dump_rx_win_attr(attr); + + if (cop >= VAS_COP_TYPE_MAX) + return false; + + if (cop != VAS_COP_TYPE_FTW && + attr->rx_fifo_size < VAS_RX_FIFO_SIZE_MIN) + return false; + + if (attr->rx_fifo_size > VAS_RX_FIFO_SIZE_MAX) + return false; + + if (attr->nx_win) { + /* cannot be fault or user window if it is nx */ + if (attr->fault_win || attr->user_win) + return false; + /* + * Section 3.1.4.32: NX Windows must not disable notification, + * and must not enable interrupts or early notification. + */ + if (attr->notify_disable || !attr->intr_disable || + attr->notify_early) + return false; + } else if (attr->fault_win) { + /* cannot be both fault and user window */ + if (attr->user_win) + return false; + + /* + * Section 3.1.4.32: Fault windows must disable notification + * but not interrupts. + */ + if (!attr->notify_disable || attr->intr_disable) + return false; + + } else if (attr->user_win) { + /* + * User receive windows are only for fast-thread-wakeup + * (FTW). They don't need a FIFO and must disable interrupts + */ + if (attr->rx_fifo || attr->rx_fifo_size || !attr->intr_disable) + return false; + } else { + /* Rx window must be one of NX or Fault or User window. */ + return false; + } + + return true; +} + +void vas_init_rx_win_attr(struct vas_rx_win_attr *rxattr, enum vas_cop_type cop) +{ + memset(rxattr, 0, sizeof(*rxattr)); + + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) { + rxattr->pin_win = true; + rxattr->nx_win = true; + rxattr->fault_win = false; + rxattr->intr_disable = true; + rxattr->rx_wcred_mode = true; + rxattr->tx_wcred_mode = true; + rxattr->rx_win_ord_mode = true; + rxattr->tx_win_ord_mode = true; + } else if (cop == VAS_COP_TYPE_FAULT) { + rxattr->pin_win = true; + rxattr->fault_win = true; + rxattr->notify_disable = true; + rxattr->rx_wcred_mode = true; + rxattr->tx_wcred_mode = true; + rxattr->rx_win_ord_mode = true; + rxattr->tx_win_ord_mode = true; + } else if (cop == VAS_COP_TYPE_FTW) { + rxattr->user_win = true; + rxattr->intr_disable = true; + + /* + * As noted in the VAS Workbook we disable credit checks. + * If we enable credit checks in the future, we must also + * implement a mechanism to return the user credits or new + * paste operations will fail. + */ + } +} +EXPORT_SYMBOL_GPL(vas_init_rx_win_attr); + +struct vas_window *vas_rx_win_open(int vasid, enum vas_cop_type cop, + struct vas_rx_win_attr *rxattr) +{ + struct vas_window *rxwin; + struct vas_winctx winctx; + struct vas_instance *vinst; + + if (!rx_win_args_valid(cop, rxattr)) + return ERR_PTR(-EINVAL); + + vinst = find_vas_instance(vasid); + if (!vinst) { + pr_devel("vasid %d not found!\n", vasid); + return ERR_PTR(-EINVAL); + } + pr_devel("Found instance %d\n", vasid); + + rxwin = vas_window_alloc(vinst); + if (IS_ERR(rxwin)) { + pr_devel("Unable to allocate memory for Rx window\n"); + return rxwin; + } + + rxwin->tx_win = false; + rxwin->nx_win = rxattr->nx_win; + rxwin->user_win = rxattr->user_win; + rxwin->cop = cop; + if (rxattr->user_win) + rxwin->pid = task_pid_vnr(current); + + init_winctx_for_rxwin(rxwin, rxattr, &winctx); + init_winctx_regs(rxwin, &winctx); + + set_vinst_win(vinst, rxwin); + + return rxwin; +} +EXPORT_SYMBOL_GPL(vas_rx_win_open); + +void vas_init_tx_win_attr(struct vas_tx_win_attr *txattr, enum vas_cop_type cop) +{ + memset(txattr, 0, sizeof(*txattr)); + + if (cop == VAS_COP_TYPE_842 || cop == VAS_COP_TYPE_842_HIPRI) { + txattr->rej_no_credit = false; + txattr->rx_wcred_mode = true; + txattr->tx_wcred_mode = true; + txattr->rx_win_ord_mode = true; + txattr->tx_win_ord_mode = true; + } else if (cop == VAS_COP_TYPE_FTW) { + txattr->user_win = true; + } +} +EXPORT_SYMBOL_GPL(vas_init_tx_win_attr); + +static void init_winctx_for_txwin(struct vas_window *txwin, + struct vas_tx_win_attr *txattr, + struct vas_winctx *winctx) +{ + /* + * We first zero all fields and only set non-zero ones. Following + * are some fields set to 0/false for the stated reason: + * + * ->notify_os_intr_reg In powernv, send intrs to HV + * ->rsvd_txbuf_count Not supported yet. + * ->notify_disable False for NX windows + * ->xtra_write False for NX windows + * ->notify_early NA for NX windows + * ->lnotify_lpid NA for Tx windows + * ->lnotify_pid NA for Tx windows + * ->lnotify_tid NA for Tx windows + * ->tx_win_cred_mode Ignore for now for NX windows + * ->rx_win_cred_mode Ignore for now for NX windows + */ + memset(winctx, 0, sizeof(struct vas_winctx)); + + winctx->wcreds_max = txattr->wcreds_max ?: VAS_WCREDS_DEFAULT; + + winctx->user_win = txattr->user_win; + winctx->nx_win = txwin->rxwin->nx_win; + winctx->pin_win = txattr->pin_win; + + winctx->rx_wcred_mode = txattr->rx_wcred_mode; + winctx->tx_wcred_mode = txattr->tx_wcred_mode; + winctx->rx_word_mode = txattr->rx_win_ord_mode; + winctx->tx_word_mode = txattr->tx_win_ord_mode; + + if (winctx->nx_win) { + winctx->data_stamp = true; + winctx->intr_disable = true; + } + + winctx->lpid = txattr->lpid; + winctx->pidr = txattr->pidr; + winctx->rx_win_id = txwin->rxwin->winid; + + winctx->dma_type = VAS_DMA_TYPE_INJECT; + winctx->tc_mode = txattr->tc_mode; + winctx->min_scope = VAS_SCOPE_LOCAL; + winctx->max_scope = VAS_SCOPE_VECTORED_GROUP; + + winctx->pswid = 0; +} + +static bool tx_win_args_valid(enum vas_cop_type cop, + struct vas_tx_win_attr *attr) +{ + if (attr->tc_mode != VAS_THRESH_DISABLED) + return false; + + if (cop > VAS_COP_TYPE_MAX) + return false; + + if (attr->user_win && + (cop != VAS_COP_TYPE_FTW || attr->rsvd_txbuf_count)) + return false; + + return true; +} + +struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, + struct vas_tx_win_attr *attr) +{ + int rc; + struct vas_window *txwin; + struct vas_window *rxwin; + struct vas_winctx winctx; + struct vas_instance *vinst; + + if (!tx_win_args_valid(cop, attr)) + return ERR_PTR(-EINVAL); + + vinst = find_vas_instance(vasid); + if (!vinst) { + pr_devel("vasid %d not found!\n", vasid); + return ERR_PTR(-EINVAL); + } + + rxwin = get_vinst_rxwin(vinst, cop, attr->pswid); + if (IS_ERR(rxwin)) { + pr_devel("No RxWin for vasid %d, cop %d\n", vasid, cop); + return rxwin; + } + + txwin = vas_window_alloc(vinst); + if (IS_ERR(txwin)) { + rc = PTR_ERR(txwin); + goto put_rxwin; + } + + txwin->tx_win = 1; + txwin->rxwin = rxwin; + txwin->nx_win = txwin->rxwin->nx_win; + txwin->pid = attr->pid; + txwin->user_win = attr->user_win; + + init_winctx_for_txwin(txwin, attr, &winctx); + + init_winctx_regs(txwin, &winctx); + + /* + * If its a kernel send window, map the window address into the + * kernel's address space. For user windows, user must issue an + * mmap() to map the window into their address space. + * + * NOTE: If kernel ever resubmits a user CRB after handling a page + * fault, we will need to map this into kernel as well. + */ + if (!txwin->user_win) { + txwin->paste_kaddr = map_paste_region(txwin); + if (IS_ERR(txwin->paste_kaddr)) { + rc = PTR_ERR(txwin->paste_kaddr); + goto free_window; + } + } + + set_vinst_win(vinst, txwin); + + return txwin; + +free_window: + vas_window_free(txwin); + +put_rxwin: + put_rx_win(rxwin); + return ERR_PTR(rc); + +} +EXPORT_SYMBOL_GPL(vas_tx_win_open); + +int vas_copy_crb(void *crb, int offset) +{ + return vas_copy(crb, offset); +} +EXPORT_SYMBOL_GPL(vas_copy_crb); + +#define RMA_LSMP_REPORT_ENABLE PPC_BIT(53) +int vas_paste_crb(struct vas_window *txwin, int offset, bool re) +{ + int rc; + void *addr; + uint64_t val; + + /* + * Only NX windows are supported for now and hardware assumes + * report-enable flag is set for NX windows. Ensure software + * complies too. + */ + WARN_ON_ONCE(txwin->nx_win && !re); + + addr = txwin->paste_kaddr; + if (re) { + /* + * Set the REPORT_ENABLE bit (equivalent to writing + * to 1K offset of the paste address) + */ + val = SET_FIELD(RMA_LSMP_REPORT_ENABLE, 0ULL, 1); + addr += val; + } + + /* + * Map the raw CR value from vas_paste() to an error code (there + * is just pass or fail for now though). + */ + rc = vas_paste(addr, offset); + if (rc == 2) + rc = 0; + else + rc = -EINVAL; + + print_fifo_msg_count(txwin); + + return rc; +} +EXPORT_SYMBOL_GPL(vas_paste_crb); + +static void poll_window_busy_state(struct vas_window *window) +{ + int busy; + u64 val; + +retry: + /* + * Poll Window Busy flag + */ + val = read_hvwc_reg(window, VREG(WIN_STATUS)); + busy = GET_FIELD(VAS_WIN_BUSY, val); + if (busy) { + val = 0; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto retry; + } +} + +static void poll_window_castout(struct vas_window *window) +{ + int cached; + u64 val; + + /* Cast window context out of the cache */ +retry: + val = read_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL)); + cached = GET_FIELD(VAS_WIN_CACHE_STATUS, val); + if (cached) { + val = 0ULL; + val = SET_FIELD(VAS_CASTOUT_REQ, val, 1); + val = SET_FIELD(VAS_PUSH_TO_MEM, val, 0); + write_hvwc_reg(window, VREG(WIN_CTX_CACHING_CTL), val); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto retry; + } +} + +/* + * Close a window. + * + * See Section 1.12.1 of VAS workbook v1.05 for details on closing window: + * - Disable new paste operations (unmap paste address) + * - Poll for the "Window Busy" bit to be cleared + * - Clear the Open/Enable bit for the Window. + * - Poll for return of window Credits (implies FIFO empty for Rx win?) + * - Unpin and cast window context out of cache + * + * Besides the hardware, kernel has some bookkeeping of course. + */ +int vas_win_close(struct vas_window *window) +{ + u64 val; + + if (!window) + return 0; + + if (!window->tx_win && atomic_read(&window->num_txwins) != 0) { + pr_devel("Attempting to close an active Rx window!\n"); + WARN_ON_ONCE(1); + return -EBUSY; + } + + unmap_paste_region(window); + + clear_vinst_win(window); + + poll_window_busy_state(window); + + /* Unpin window from cache and close it */ + val = read_hvwc_reg(window, VREG(WINCTL)); + val = SET_FIELD(VAS_WINCTL_PIN, val, 0); + val = SET_FIELD(VAS_WINCTL_OPEN, val, 0); + write_hvwc_reg(window, VREG(WINCTL), val); + + poll_window_castout(window); + + /* if send window, drop reference to matching receive window */ + if (window->tx_win) + put_rx_win(window->rxwin); + + vas_window_free(window); + + return 0; +} +EXPORT_SYMBOL_GPL(vas_win_close); diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c new file mode 100644 index 000000000000..565a4878fefa --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas.c @@ -0,0 +1,151 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "vas: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vas.h" + +static DEFINE_MUTEX(vas_mutex); +static LIST_HEAD(vas_instances); + +static int init_vas_instance(struct platform_device *pdev) +{ + int rc, vasid; + struct resource *res; + struct vas_instance *vinst; + struct device_node *dn = pdev->dev.of_node; + + rc = of_property_read_u32(dn, "ibm,vas-id", &vasid); + if (rc) { + pr_err("No ibm,vas-id property for %s?\n", pdev->name); + return -ENODEV; + } + + if (pdev->num_resources != 4) { + pr_err("Unexpected DT configuration for [%s, %d]\n", + pdev->name, vasid); + return -ENODEV; + } + + vinst = kzalloc(sizeof(*vinst), GFP_KERNEL); + if (!vinst) + return -ENOMEM; + + INIT_LIST_HEAD(&vinst->node); + ida_init(&vinst->ida); + mutex_init(&vinst->mutex); + vinst->vas_id = vasid; + vinst->pdev = pdev; + + res = &pdev->resource[0]; + vinst->hvwc_bar_start = res->start; + + res = &pdev->resource[1]; + vinst->uwc_bar_start = res->start; + + res = &pdev->resource[2]; + vinst->paste_base_addr = res->start; + + res = &pdev->resource[3]; + if (res->end > 62) { + pr_err("Bad 'paste_win_id_shift' in DT, %llx\n", res->end); + goto free_vinst; + } + + vinst->paste_win_id_shift = 63 - res->end; + + pr_devel("Initialized instance [%s, %d], paste_base 0x%llx, " + "paste_win_id_shift 0x%llx\n", pdev->name, vasid, + vinst->paste_base_addr, vinst->paste_win_id_shift); + + mutex_lock(&vas_mutex); + list_add(&vinst->node, &vas_instances); + mutex_unlock(&vas_mutex); + + dev_set_drvdata(&pdev->dev, vinst); + + return 0; + +free_vinst: + kfree(vinst); + return -ENODEV; + +} + +/* + * Although this is read/used multiple times, it is written to only + * during initialization. + */ +struct vas_instance *find_vas_instance(int vasid) +{ + struct list_head *ent; + struct vas_instance *vinst; + + mutex_lock(&vas_mutex); + list_for_each(ent, &vas_instances) { + vinst = list_entry(ent, struct vas_instance, node); + if (vinst->vas_id == vasid) { + mutex_unlock(&vas_mutex); + return vinst; + } + } + mutex_unlock(&vas_mutex); + + pr_devel("Instance %d not found\n", vasid); + return NULL; +} + +static int vas_probe(struct platform_device *pdev) +{ + return init_vas_instance(pdev); +} + +static const struct of_device_id powernv_vas_match[] = { + { .compatible = "ibm,vas",}, + {}, +}; + +static struct platform_driver vas_driver = { + .driver = { + .name = "vas", + .of_match_table = powernv_vas_match, + }, + .probe = vas_probe, +}; + +static int __init vas_init(void) +{ + int found = 0; + struct device_node *dn; + + platform_driver_register(&vas_driver); + + for_each_compatible_node(dn, NULL, "ibm,vas") { + of_platform_device_create(dn, NULL, NULL); + found++; + } + + if (!found) + return -ENODEV; + + pr_devel("Found %d instances\n", found); + + return 0; +} +device_initcall(vas_init); diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h new file mode 100644 index 000000000000..38dee5d50f31 --- /dev/null +++ b/arch/powerpc/platforms/powernv/vas.h @@ -0,0 +1,467 @@ +/* + * Copyright 2016-17 IBM Corp. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _VAS_H +#define _VAS_H +#include +#include +#include +#include + +/* + * Overview of Virtual Accelerator Switchboard (VAS). + * + * VAS is a hardware "switchboard" that allows senders and receivers to + * exchange messages with _minimal_ kernel involvment. The receivers are + * typically NX coprocessor engines that perform compression or encryption + * in hardware, but receivers can also be other software threads. + * + * Senders are user/kernel threads that submit compression/encryption or + * other requests to the receivers. Senders must format their messages as + * Coprocessor Request Blocks (CRB)s and submit them using the "copy" and + * "paste" instructions which were introduced in Power9. + * + * A Power node can have (upto?) 8 Power chips. There is one instance of + * VAS in each Power9 chip. Each instance of VAS has 64K windows or ports, + * Senders and receivers must each connect to a separate window before they + * can exchange messages through the switchboard. + * + * Each window is described by two types of window contexts: + * + * Hypervisor Window Context (HVWC) of size VAS_HVWC_SIZE bytes + * + * OS/User Window Context (UWC) of size VAS_UWC_SIZE bytes. + * + * A window context can be viewed as a set of 64-bit registers. The settings + * in these registers configure/control/determine the behavior of the VAS + * hardware when messages are sent/received through the window. The registers + * in the HVWC are configured by the kernel while the registers in the UWC can + * be configured by the kernel or by the user space application that is using + * the window. + * + * The HVWCs for all windows on a specific instance of VAS are in a contiguous + * range of hardware addresses or Base address region (BAR) referred to as the + * HVWC BAR for the instance. Similarly the UWCs for all windows on an instance + * are referred to as the UWC BAR for the instance. + * + * The two BARs for each instance are defined Power9 MMIO Ranges spreadsheet + * and available to the kernel in the VAS node's "reg" property in the device + * tree: + * + * /proc/device-tree/vasm@.../reg + * + * (see vas_probe() for details on the reg property). + * + * The kernel maps the HVWC and UWC BAR regions into the kernel address + * space (hvwc_map and uwc_map). The kernel can then access the window + * contexts of a specific window using: + * + * hvwc = hvwc_map + winid * VAS_HVWC_SIZE. + * uwc = uwc_map + winid * VAS_UWC_SIZE. + * + * where winid is the window index (0..64K). + * + * As mentioned, a window context is used to "configure" a window. Besides + * this configuration address, each _send_ window also has a unique hardware + * "paste" address that is used to submit requests/CRBs (see vas_paste_crb()). + * + * The hardware paste address for a window is computed using the "paste + * base address" and "paste win id shift" reg properties in the VAS device + * tree node using: + * + * paste_addr = paste_base + ((winid << paste_win_id_shift)) + * + * (again, see vas_probe() for ->paste_base_addr and ->paste_win_id_shift). + * + * The kernel maps this hardware address into the sender's address space + * after which they can use the 'paste' instruction (new in Power9) to + * send a message (submit a request aka CRB) to the coprocessor. + * + * NOTE: In the initial version, senders can only in-kernel drivers/threads. + * Support for user space threads will be added in follow-on patches. + * + * TODO: Do we need to map the UWC into user address space so they can return + * credits? Its NA for NX but may be needed for other receive windows. + * + */ + +#define VAS_WINDOWS_PER_CHIP (64 << 10) + +/* + * Hypervisor and OS/USer Window Context sizes + */ +#define VAS_HVWC_SIZE 512 +#define VAS_UWC_SIZE PAGE_SIZE + +/* + * Initial per-process credits. + * Max send window credits: 4K-1 (12-bits in VAS_TX_WCRED) + * Max receive window credits: 64K-1 (16 bits in VAS_LRX_WCRED) + * + * TODO: Needs tuning for per-process credits + */ +#define VAS_WCREDS_MIN 16 +#define VAS_WCREDS_MAX ((64 << 10) - 1) +#define VAS_WCREDS_DEFAULT (1 << 10) + +/* + * VAS Window Context Register Offsets and bitmasks. + * See Section 3.1.4 of VAS Work book + */ +#define VAS_LPID_OFFSET 0x010 +#define VAS_LPID PPC_BITMASK(0, 11) + +#define VAS_PID_OFFSET 0x018 +#define VAS_PID_ID PPC_BITMASK(0, 19) + +#define VAS_XLATE_MSR_OFFSET 0x020 +#define VAS_XLATE_MSR_DR PPC_BIT(0) +#define VAS_XLATE_MSR_TA PPC_BIT(1) +#define VAS_XLATE_MSR_PR PPC_BIT(2) +#define VAS_XLATE_MSR_US PPC_BIT(3) +#define VAS_XLATE_MSR_HV PPC_BIT(4) +#define VAS_XLATE_MSR_SF PPC_BIT(5) + +#define VAS_XLATE_LPCR_OFFSET 0x028 +#define VAS_XLATE_LPCR_PAGE_SIZE PPC_BITMASK(0, 2) +#define VAS_XLATE_LPCR_ISL PPC_BIT(3) +#define VAS_XLATE_LPCR_TC PPC_BIT(4) +#define VAS_XLATE_LPCR_SC PPC_BIT(5) + +#define VAS_XLATE_CTL_OFFSET 0x030 +#define VAS_XLATE_MODE PPC_BITMASK(0, 1) + +#define VAS_AMR_OFFSET 0x040 +#define VAS_AMR PPC_BITMASK(0, 63) + +#define VAS_SEIDR_OFFSET 0x048 +#define VAS_SEIDR PPC_BITMASK(0, 63) + +#define VAS_FAULT_TX_WIN_OFFSET 0x050 +#define VAS_FAULT_TX_WIN PPC_BITMASK(48, 63) + +#define VAS_OSU_INTR_SRC_RA_OFFSET 0x060 +#define VAS_OSU_INTR_SRC_RA PPC_BITMASK(8, 63) + +#define VAS_HV_INTR_SRC_RA_OFFSET 0x070 +#define VAS_HV_INTR_SRC_RA PPC_BITMASK(8, 63) + +#define VAS_PSWID_OFFSET 0x078 +#define VAS_PSWID_EA_HANDLE PPC_BITMASK(0, 31) + +#define VAS_SPARE1_OFFSET 0x080 +#define VAS_SPARE2_OFFSET 0x088 +#define VAS_SPARE3_OFFSET 0x090 +#define VAS_SPARE4_OFFSET 0x130 +#define VAS_SPARE5_OFFSET 0x160 +#define VAS_SPARE6_OFFSET 0x188 + +#define VAS_LFIFO_BAR_OFFSET 0x0A0 +#define VAS_LFIFO_BAR PPC_BITMASK(8, 53) +#define VAS_PAGE_MIGRATION_SELECT PPC_BITMASK(54, 56) + +#define VAS_LDATA_STAMP_CTL_OFFSET 0x0A8 +#define VAS_LDATA_STAMP PPC_BITMASK(0, 1) +#define VAS_XTRA_WRITE PPC_BIT(2) + +#define VAS_LDMA_CACHE_CTL_OFFSET 0x0B0 +#define VAS_LDMA_TYPE PPC_BITMASK(0, 1) +#define VAS_LDMA_FIFO_DISABLE PPC_BIT(2) + +#define VAS_LRFIFO_PUSH_OFFSET 0x0B8 +#define VAS_LRFIFO_PUSH PPC_BITMASK(0, 15) + +#define VAS_CURR_MSG_COUNT_OFFSET 0x0C0 +#define VAS_CURR_MSG_COUNT PPC_BITMASK(0, 7) + +#define VAS_LNOTIFY_AFTER_COUNT_OFFSET 0x0C8 +#define VAS_LNOTIFY_AFTER_COUNT PPC_BITMASK(0, 7) + +#define VAS_LRX_WCRED_OFFSET 0x0E0 +#define VAS_LRX_WCRED PPC_BITMASK(0, 15) + +#define VAS_LRX_WCRED_ADDER_OFFSET 0x190 +#define VAS_LRX_WCRED_ADDER PPC_BITMASK(0, 15) + +#define VAS_TX_WCRED_OFFSET 0x0F0 +#define VAS_TX_WCRED PPC_BITMASK(4, 15) + +#define VAS_TX_WCRED_ADDER_OFFSET 0x1A0 +#define VAS_TX_WCRED_ADDER PPC_BITMASK(4, 15) + +#define VAS_LFIFO_SIZE_OFFSET 0x100 +#define VAS_LFIFO_SIZE PPC_BITMASK(0, 3) + +#define VAS_WINCTL_OFFSET 0x108 +#define VAS_WINCTL_OPEN PPC_BIT(0) +#define VAS_WINCTL_REJ_NO_CREDIT PPC_BIT(1) +#define VAS_WINCTL_PIN PPC_BIT(2) +#define VAS_WINCTL_TX_WCRED_MODE PPC_BIT(3) +#define VAS_WINCTL_RX_WCRED_MODE PPC_BIT(4) +#define VAS_WINCTL_TX_WORD_MODE PPC_BIT(5) +#define VAS_WINCTL_RX_WORD_MODE PPC_BIT(6) +#define VAS_WINCTL_RSVD_TXBUF PPC_BIT(7) +#define VAS_WINCTL_THRESH_CTL PPC_BITMASK(8, 9) +#define VAS_WINCTL_FAULT_WIN PPC_BIT(10) +#define VAS_WINCTL_NX_WIN PPC_BIT(11) + +#define VAS_WIN_STATUS_OFFSET 0x110 +#define VAS_WIN_BUSY PPC_BIT(1) + +#define VAS_WIN_CTX_CACHING_CTL_OFFSET 0x118 +#define VAS_CASTOUT_REQ PPC_BIT(0) +#define VAS_PUSH_TO_MEM PPC_BIT(1) +#define VAS_WIN_CACHE_STATUS PPC_BIT(4) + +#define VAS_TX_RSVD_BUF_COUNT_OFFSET 0x120 +#define VAS_RXVD_BUF_COUNT PPC_BITMASK(58, 63) + +#define VAS_LRFIFO_WIN_PTR_OFFSET 0x128 +#define VAS_LRX_WIN_ID PPC_BITMASK(0, 15) + +/* + * Local Notification Control Register controls what happens in _response_ + * to a paste command and hence applies only to receive windows. + */ +#define VAS_LNOTIFY_CTL_OFFSET 0x138 +#define VAS_NOTIFY_DISABLE PPC_BIT(0) +#define VAS_INTR_DISABLE PPC_BIT(1) +#define VAS_NOTIFY_EARLY PPC_BIT(2) +#define VAS_NOTIFY_OSU_INTR PPC_BIT(3) + +#define VAS_LNOTIFY_PID_OFFSET 0x140 +#define VAS_LNOTIFY_PID PPC_BITMASK(0, 19) + +#define VAS_LNOTIFY_LPID_OFFSET 0x148 +#define VAS_LNOTIFY_LPID PPC_BITMASK(0, 11) + +#define VAS_LNOTIFY_TID_OFFSET 0x150 +#define VAS_LNOTIFY_TID PPC_BITMASK(0, 15) + +#define VAS_LNOTIFY_SCOPE_OFFSET 0x158 +#define VAS_LNOTIFY_MIN_SCOPE PPC_BITMASK(0, 1) +#define VAS_LNOTIFY_MAX_SCOPE PPC_BITMASK(2, 3) + +#define VAS_NX_UTIL_OFFSET 0x1B0 +#define VAS_NX_UTIL PPC_BITMASK(0, 63) + +/* SE: Side effects */ +#define VAS_NX_UTIL_SE_OFFSET 0x1B8 +#define VAS_NX_UTIL_SE PPC_BITMASK(0, 63) + +#define VAS_NX_UTIL_ADDER_OFFSET 0x180 +#define VAS_NX_UTIL_ADDER PPC_BITMASK(32, 63) + +/* + * Local Notify Scope Control Register. (Receive windows only). + */ +enum vas_notify_scope { + VAS_SCOPE_LOCAL, + VAS_SCOPE_GROUP, + VAS_SCOPE_VECTORED_GROUP, + VAS_SCOPE_UNUSED, +}; + +/* + * Local DMA Cache Control Register (Receive windows only). + */ +enum vas_dma_type { + VAS_DMA_TYPE_INJECT, + VAS_DMA_TYPE_WRITE, +}; + +/* + * Local Notify Scope Control Register. (Receive windows only). + * Not applicable to NX receive windows. + */ +enum vas_notify_after_count { + VAS_NOTIFY_AFTER_256 = 0, + VAS_NOTIFY_NONE, + VAS_NOTIFY_AFTER_2 +}; + +/* + * One per instance of VAS. Each instance will have a separate set of + * receive windows, one per coprocessor type. + * + * See also function header of set_vinst_win() for details on ->windows[] + * and ->rxwin[] tables. + */ +struct vas_instance { + int vas_id; + struct ida ida; + struct list_head node; + struct platform_device *pdev; + + u64 hvwc_bar_start; + u64 uwc_bar_start; + u64 paste_base_addr; + u64 paste_win_id_shift; + + struct mutex mutex; + struct vas_window *rxwin[VAS_COP_TYPE_MAX]; + struct vas_window *windows[VAS_WINDOWS_PER_CHIP]; +}; + +/* + * In-kernel state a VAS window. One per window. + */ +struct vas_window { + /* Fields common to send and receive windows */ + struct vas_instance *vinst; + int winid; + bool tx_win; /* True if send window */ + bool nx_win; /* True if NX window */ + bool user_win; /* True if user space window */ + void *hvwc_map; /* HV window context */ + void *uwc_map; /* OS/User window context */ + pid_t pid; /* Linux process id of owner */ + + /* Fields applicable only to send windows */ + void *paste_kaddr; + char *paste_addr_name; + struct vas_window *rxwin; + + /* Feilds applicable only to receive windows */ + enum vas_cop_type cop; + atomic_t num_txwins; +}; + +/* + * Container for the hardware state of a window. One per-window. + * + * A VAS Window context is a 512-byte area in the hardware that contains + * a set of 64-bit registers. Individual bit-fields in these registers + * determine the configuration/operation of the hardware. struct vas_winctx + * is a container for the register fields in the window context. + */ +struct vas_winctx { + void *rx_fifo; + int rx_fifo_size; + int wcreds_max; + int rsvd_txbuf_count; + + bool user_win; + bool nx_win; + bool fault_win; + bool rsvd_txbuf_enable; + bool pin_win; + bool rej_no_credit; + bool tx_wcred_mode; + bool rx_wcred_mode; + bool tx_word_mode; + bool rx_word_mode; + bool data_stamp; + bool xtra_write; + bool notify_disable; + bool intr_disable; + bool fifo_disable; + bool notify_early; + bool notify_os_intr_reg; + + int lpid; + int pidr; /* value from SPRN_PID, not linux pid */ + int lnotify_lpid; + int lnotify_pid; + int lnotify_tid; + u32 pswid; + int rx_win_id; + int fault_win_id; + int tc_mode; + + u64 irq_port; + + enum vas_dma_type dma_type; + enum vas_notify_scope min_scope; + enum vas_notify_scope max_scope; + enum vas_notify_after_count notify_after_count; +}; + +extern struct vas_instance *find_vas_instance(int vasid); + +/* + * VREG(x): + * Expand a register's short name (eg: LPID) into two parameters: + * - the register's short name in string form ("LPID"), and + * - the name of the macro (eg: VAS_LPID_OFFSET), defining the + * register's offset in the window context + */ +#define VREG_SFX(n, s) __stringify(n), VAS_##n##s +#define VREG(r) VREG_SFX(r, _OFFSET) + +#ifdef vas_debug +static inline void dump_rx_win_attr(struct vas_rx_win_attr *attr) +{ + pr_err("fault %d, notify %d, intr %d early %d\n", + attr->fault_win, attr->notify_disable, + attr->intr_disable, attr->notify_early); + + pr_err("rx_fifo_size %d, max value %d\n", + attr->rx_fifo_size, VAS_RX_FIFO_SIZE_MAX); +} + +static inline void vas_log_write(struct vas_window *win, char *name, + void *regptr, u64 val) +{ + if (val) + pr_err("%swin #%d: %s reg %p, val 0x%016llx\n", + win->tx_win ? "Tx" : "Rx", win->winid, name, + regptr, val); +} + +#else /* vas_debug */ + +#define vas_log_write(win, name, reg, val) +#define dump_rx_win_attr(attr) + +#endif /* vas_debug */ + +static inline void write_uwc_reg(struct vas_window *win, char *name, + s32 reg, u64 val) +{ + void *regptr; + + regptr = win->uwc_map + reg; + vas_log_write(win, name, regptr, val); + + out_be64(regptr, val); +} + +static inline void write_hvwc_reg(struct vas_window *win, char *name, + s32 reg, u64 val) +{ + void *regptr; + + regptr = win->hvwc_map + reg; + vas_log_write(win, name, regptr, val); + + out_be64(regptr, val); +} + +static inline u64 read_hvwc_reg(struct vas_window *win, + char *name __maybe_unused, s32 reg) +{ + return in_be64(win->hvwc_map+reg); +} + +#ifdef vas_debug + +static void print_fifo_msg_count(struct vas_window *txwin) +{ + uint64_t read_hvwc_reg(struct vas_window *w, char *n, uint64_t o); + pr_devel("Winid %d, Msg count %llu\n", txwin->winid, + (uint64_t)read_hvwc_reg(txwin, VREG(LRFIFO_PUSH))); +} +#else /* vas_debug */ + +#define print_fifo_msg_count(window) + +#endif /* vas_debug */ + +#endif /* _VAS_H */ diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index b27f40f26efc..6f7525555b19 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_PS3 bool "Sony PS3" depends on PPC64 && PPC_BOOK3S && CPU_BIG_ENDIAN diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile index 02b9e636dab7..86bf2967a8d4 100644 --- a/arch/powerpc/platforms/ps3/Makefile +++ b/arch/powerpc/platforms/ps3/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o obj-y += interrupt.o exports.o os-area.o obj-y += system-bus.o diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 814a7eaa7769..50dbaf24b1ee 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -170,14 +170,8 @@ int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id) { - int result; - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("id", 0), - 0, 0, - bus_id, NULL); - return result; + return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), + make_field("id", 0), 0, 0, bus_id, NULL); } int ps3_repository_read_bus_type(unsigned int bus_index, @@ -224,15 +218,9 @@ int ps3_repository_read_dev_str(unsigned int bus_index, int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, u64 *dev_id) { - int result; - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("id", 0), - 0, - dev_id, NULL); - return result; + return read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), + make_field("dev", dev_index), make_field("id", 0), 0, + dev_id, NULL); } int ps3_repository_read_dev_type(unsigned int bus_index, diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 6244bc849469..9dabea6e1443 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -104,20 +104,6 @@ static void __noreturn ps3_halt(void) ps3_sys_manager_halt(); /* never returns */ } -static void ps3_panic(char *str) -{ - DBG("%s:%d %s\n", __func__, __LINE__, str); - - smp_send_stop(); - printk("\n"); - printk(" System does not reboot automatically.\n"); - printk(" Please press POWER button.\n"); - printk("\n"); - - while(1) - lv1_pause(1); -} - #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \ defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) static void __init prealloc(struct ps3_prealloc *p) @@ -269,7 +255,6 @@ define_machine(ps3) { .probe = ps3_probe, .setup_arch = ps3_setup_arch, .init_IRQ = ps3_init_IRQ, - .panic = ps3_panic, .get_boot_time = ps3_get_boot_time, .set_dabr = ps3_set_dabr, .calibrate_decr = ps3_calibrate_decr, diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 3a6dfd14f64b..0c698fd6d491 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_PSERIES depends on PPC64 && PPC_BOOK3S bool "IBM pSeries & new (POWER5-based) iSeries" @@ -7,6 +8,7 @@ config PPC_PSERIES select PCI select PCI_MSI select PPC_XICS + select PPC_XIVE_SPAPR select PPC_ICP_NATIVE select PPC_ICP_HV select PPC_ICS_RTAS diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 8f4ba089e802..13eede60c24d 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) ccflags-$(CONFIG_PPC_PSERIES_DEBUG) += -DDEBUG diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 39187696ee74..e45b5f10645a 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -254,22 +254,18 @@ cc_error: return first_dn; } -int dlpar_attach_node(struct device_node *dn) +int dlpar_attach_node(struct device_node *dn, struct device_node *parent) { int rc; - dn->parent = pseries_of_derive_parent(dn->full_name); - if (IS_ERR(dn->parent)) - return PTR_ERR(dn->parent); + dn->parent = parent; rc = of_attach_node(dn); if (rc) { - printk(KERN_ERR "Failed to add device node %s\n", - dn->full_name); + printk(KERN_ERR "Failed to add device node %pOF\n", dn); return rc; } - of_node_put(dn->parent); return 0; } diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 1eef46d9cf30..6b812ad990e4 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -247,14 +247,13 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) /* Initialize the fake PE */ memset(&pe, 0, sizeof(struct eeh_pe)); - pe.phb = edev->phb; + pe.phb = pdn->phb; pe.config_addr = (pdn->busno << 16) | (pdn->devfn << 8); /* Enable EEH on the device */ ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); if (!ret) { /* Retrieve PE address */ - edev->config_addr = (pdn->busno << 16) | (pdn->devfn << 8); edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); pe.addr = edev->pe_config_addr; @@ -279,7 +278,6 @@ static void *pseries_eeh_probe(struct pci_dn *pdn, void *data) /* This device doesn't support EEH, but it may have an * EEH parent, in which case we mark it as supported. */ - edev->config_addr = pdn_to_eeh_dev(pdn->parent)->config_addr; edev->pe_config_addr = pdn_to_eeh_dev(pdn->parent)->pe_config_addr; eeh_add_to_parent_pe(edev); } diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c index 32187dc76730..6eeb0d4bab61 100644 --- a/arch/powerpc/platforms/pseries/event_sources.c +++ b/arch/powerpc/platforms/pseries/event_sources.c @@ -36,8 +36,8 @@ void request_event_sources_irqs(struct device_node *np, virqs[count] = irq_create_of_mapping(&oirq); if (!virqs[count]) { pr_err("event-sources: Unable to allocate " - "interrupt number for %s\n", - np->full_name); + "interrupt number for %pOF\n", + np); WARN_ON(1); } else { count++; @@ -48,7 +48,7 @@ void request_event_sources_irqs(struct device_node *np, for (i = 0; i < count; i++) { if (request_irq(virqs[i], handler, 0, name, NULL)) { pr_err("event-sources: Unable to request interrupt " - "%d for %s\n", virqs[i], np->full_name); + "%d for %pOF\n", virqs[i], np); WARN_ON(1); return; } diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6afd1efd3633..fadb95efbb9e 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "pseries.h" @@ -109,7 +110,10 @@ static void pseries_mach_cpu_die(void) local_irq_disable(); idle_task_exit(); - xics_teardown_cpu(); + if (xive_enabled()) + xive_teardown_cpu(); + else + xics_teardown_cpu(); if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { set_cpu_current_state(cpu, CPU_STATE_INACTIVE); @@ -174,7 +178,10 @@ static int pseries_cpu_disable(void) boot_cpuid = cpumask_any(cpu_online_mask); /* FIXME: abstract this to not be platform specific later on */ - xics_migrate_irqs_away(); + if (xive_enabled()) + xive_smp_disable_cpu(); + else + xics_migrate_irqs_away(); return 0; } @@ -264,8 +271,8 @@ static int pseries_add_processor(struct device_node *np) /* If we get here, it most likely means that NR_CPUS is * less than the partition's max processors setting. */ - printk(KERN_ERR "Cannot add cpu %s; this system configuration" - " supports %d logical cpus.\n", np->full_name, + printk(KERN_ERR "Cannot add cpu %pOF; this system configuration" + " supports %d logical cpus.\n", np, num_possible_cpus()); goto out_unlock; } @@ -455,15 +462,19 @@ static ssize_t dlpar_cpu_add(u32 drc_index) } dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); - of_node_put(parent); if (!dn) { pr_warn("Failed call to configure-connector, drc index: %x\n", drc_index); dlpar_release_drc(drc_index); + of_node_put(parent); return -EINVAL; } - rc = dlpar_attach_node(dn); + rc = dlpar_attach_node(dn, parent); + + /* Regardless we are done with parent now */ + of_node_put(parent); + if (rc) { saved_rc = rc; pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n", diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index ca9b2f4aaa22..1d48ab424bd9 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -336,7 +336,38 @@ static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb) return mem_block; } +static int dlpar_change_lmb_state(struct of_drconf_cell *lmb, bool online) +{ + struct memory_block *mem_block; + int rc; + + mem_block = lmb_to_memblock(lmb); + if (!mem_block) + return -EINVAL; + + if (online && mem_block->dev.offline) + rc = device_online(&mem_block->dev); + else if (!online && !mem_block->dev.offline) + rc = device_offline(&mem_block->dev); + else + rc = 0; + + put_device(&mem_block->dev); + + return rc; +} + +static int dlpar_online_lmb(struct of_drconf_cell *lmb) +{ + return dlpar_change_lmb_state(lmb, true); +} + #ifdef CONFIG_MEMORY_HOTREMOVE +static int dlpar_offline_lmb(struct of_drconf_cell *lmb) +{ + return dlpar_change_lmb_state(lmb, false); +} + static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) { unsigned long block_sz, start_pfn; @@ -431,19 +462,13 @@ static int dlpar_add_lmb(struct of_drconf_cell *); static int dlpar_remove_lmb(struct of_drconf_cell *lmb) { - struct memory_block *mem_block; unsigned long block_sz; int nid, rc; if (!lmb_is_removable(lmb)) return -EINVAL; - mem_block = lmb_to_memblock(lmb); - if (!mem_block) - return -EINVAL; - - rc = device_offline(&mem_block->dev); - put_device(&mem_block->dev); + rc = dlpar_offline_lmb(lmb); if (rc) return rc; @@ -737,20 +762,6 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index, } #endif /* CONFIG_MEMORY_HOTREMOVE */ -static int dlpar_online_lmb(struct of_drconf_cell *lmb) -{ - struct memory_block *mem_block; - int rc; - - mem_block = lmb_to_memblock(lmb); - if (!mem_block) - return -EINVAL; - - rc = device_online(&mem_block->dev); - put_device(&mem_block->dev); - return rc; -} - static int dlpar_add_lmb(struct of_drconf_cell *lmb) { unsigned long block_sz; @@ -817,6 +828,9 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop) return -EINVAL; for (i = 0; i < num_lmbs && lmbs_to_add != lmbs_added; i++) { + if (lmbs[i].flags & DRCONF_MEM_ASSIGNED) + continue; + rc = dlpar_acquire_drc(lmbs[i].drc_index); if (rc) continue; @@ -859,6 +873,7 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop) lmbs[i].base_addr, lmbs[i].drc_index); lmbs[i].reserved = 0; } + rc = 0; } return rc; diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 74b5b8e239c8..c511a1743a44 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S @@ -23,7 +23,7 @@ .globl hcall_tracepoint_refcount hcall_tracepoint_refcount: - .llong 0 + .8byte 0 .section ".text" #endif diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c index 52146b1356d2..408a86044133 100644 --- a/arch/powerpc/platforms/pseries/ibmebus.c +++ b/arch/powerpc/platforms/pseries/ibmebus.c @@ -150,8 +150,7 @@ static const struct dma_map_ops ibmebus_dma_ops = { static int ibmebus_match_path(struct device *dev, void *data) { struct device_node *dn = to_platform_device(dev)->dev.of_node; - return (dn->full_name && - (strcasecmp((char *)data, dn->full_name) == 0)); + return (of_find_node_by_path(data) == dn); } static int ibmebus_match_node(struct device *dev, void *data) @@ -395,7 +394,7 @@ static ssize_t devspec_show(struct device *dev, struct platform_device *ofdev; ofdev = to_platform_device(dev); - return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); + return sprintf(buf, "%pOF\n", ofdev->dev.of_node); } static DEVICE_ATTR_RO(devspec); diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 8374adee27e3..7c181467d0ad 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -511,8 +511,8 @@ static void iommu_table_setparms(struct pci_controller *phb, basep = of_get_property(node, "linux,tce-base", NULL); sizep = of_get_property(node, "linux,tce-size", NULL); if (basep == NULL || sizep == NULL) { - printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %s has " - "missing tce entries !\n", dn->full_name); + printk(KERN_ERR "PCI_DMA: iommu_table_setparms: %pOF has " + "missing tce entries !\n", dn); return; } @@ -587,7 +587,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) dn = pci_bus_to_OF_node(bus); - pr_debug("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name); + pr_debug("pci_dma_bus_setup_pSeries: setting up bus %pOF\n", dn); if (bus->self) { /* This is not a root bus, any setup will be done for the @@ -701,8 +701,8 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) dn = pci_bus_to_OF_node(bus); - pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", - dn->full_name); + pr_debug("pci_dma_bus_setup_pSeriesLP: setting up bus %pOF\n", + dn); /* Find nearest ibm,dma-window, walking up the device tree */ for (pdn = dn; pdn != NULL; pdn = pdn->parent) { @@ -718,8 +718,8 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) ppci = PCI_DN(pdn); - pr_debug(" parent is %s, iommu_table: 0x%p\n", - pdn->full_name, ppci->table_group); + pr_debug(" parent is %pOF, iommu_table: 0x%p\n", + pdn, ppci->table_group); if (!ppci->table_group) { ppci->table_group = iommu_pseries_alloc_group(ppci->phb->node); @@ -817,28 +817,28 @@ static void remove_ddw(struct device_node *np, bool remove_prop) ret = tce_clearrange_multi_pSeriesLP(0, 1ULL << (be32_to_cpu(dwp->window_shift) - PAGE_SHIFT), dwp); if (ret) - pr_warning("%s failed to clear tces in window.\n", - np->full_name); + pr_warning("%pOF failed to clear tces in window.\n", + np); else - pr_debug("%s successfully cleared tces in window.\n", - np->full_name); + pr_debug("%pOF successfully cleared tces in window.\n", + np); ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn); if (ret) - pr_warning("%s: failed to remove direct window: rtas returned " + pr_warning("%pOF: failed to remove direct window: rtas returned " "%d to ibm,remove-pe-dma-window(%x) %llx\n", - np->full_name, ret, ddw_avail[2], liobn); + np, ret, ddw_avail[2], liobn); else - pr_debug("%s: successfully removed direct window: rtas returned " + pr_debug("%pOF: successfully removed direct window: rtas returned " "%d to ibm,remove-pe-dma-window(%x) %llx\n", - np->full_name, ret, ddw_avail[2], liobn); + np, ret, ddw_avail[2], liobn); delprop: if (remove_prop) ret = of_remove_property(np, win64); if (ret) - pr_warning("%s: failed to remove direct window property: %d\n", - np->full_name, ret); + pr_warning("%pOF: failed to remove direct window property: %d\n", + np, ret); } static u64 find_existing_ddw(struct device_node *pdn) @@ -1004,7 +1004,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) * list. */ list_for_each_entry(fpdn, &failed_ddw_pdn_list, list) { - if (!strcmp(fpdn->pdn->full_name, pdn->full_name)) + if (fpdn->pdn == pdn) goto out_unlock; } @@ -1087,8 +1087,8 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) ddwprop->tce_shift = cpu_to_be32(page_shift); ddwprop->window_shift = cpu_to_be32(len); - dev_dbg(&dev->dev, "created tce table LIOBN 0x%x for %s\n", - create.liobn, dn->full_name); + dev_dbg(&dev->dev, "created tce table LIOBN 0x%x for %pOF\n", + create.liobn, dn); window = kzalloc(sizeof(*window), GFP_KERNEL); if (!window) @@ -1097,15 +1097,15 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn) ret = walk_system_ram_range(0, memblock_end_of_DRAM() >> PAGE_SHIFT, win64->value, tce_setrange_multi_pSeriesLP_walk); if (ret) { - dev_info(&dev->dev, "failed to map direct window for %s: %d\n", - dn->full_name, ret); + dev_info(&dev->dev, "failed to map direct window for %pOF: %d\n", + dn, ret); goto out_free_window; } ret = of_add_property(pdn, win64); if (ret) { - dev_err(&dev->dev, "unable to add dma window property for %s: %d", - pdn->full_name, ret); + dev_err(&dev->dev, "unable to add dma window property for %pOF: %d", + pdn, ret); goto out_free_window; } @@ -1158,7 +1158,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) * already allocated. */ dn = pci_device_to_OF_node(dev); - pr_debug(" node is %s\n", dn->full_name); + pr_debug(" node is %pOF\n", dn); for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->table_group; pdn = pdn->parent) { @@ -1169,11 +1169,11 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) if (!pdn || !PCI_DN(pdn)) { printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: " - "no DMA window found for pci dev=%s dn=%s\n", - pci_name(dev), of_node_full_name(dn)); + "no DMA window found for pci dev=%s dn=%pOF\n", + pci_name(dev), dn); return; } - pr_debug(" parent is %s\n", pdn->full_name); + pr_debug(" parent is %pOF\n", pdn); pci = PCI_DN(pdn); if (!pci->table_group) { @@ -1213,7 +1213,7 @@ static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask) /* only attempt to use a new window if 64-bit DMA is requested */ if (!disable_ddw && dma_mask == DMA_BIT_MASK(64)) { dn = pci_device_to_OF_node(pdev); - dev_dbg(dev, "node is %s\n", dn->full_name); + dev_dbg(dev, "node is %pOF\n", dn); /* * the device tree might contain the dma-window properties diff --git a/arch/powerpc/platforms/pseries/kexec.c b/arch/powerpc/platforms/pseries/kexec.c index 6681ac97fb18..eeb13429d685 100644 --- a/arch/powerpc/platforms/pseries/kexec.c +++ b/arch/powerpc/platforms/pseries/kexec.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -51,5 +52,8 @@ void pseries_kexec_cpu_down(int crash_shutdown, int secondary) } } - xics_kexec_teardown_cpu(secondary); + if (xive_enabled()) + xive_kexec_teardown_cpu(secondary); + else + xics_kexec_teardown_cpu(secondary); } diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 2da4851eff99..f7042ad492ba 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -226,10 +226,12 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index) return -ENOENT; dn = dlpar_configure_connector(drc_index, parent_dn); - if (!dn) + if (!dn) { + of_node_put(parent_dn); return -ENOENT; + } - rc = dlpar_attach_node(dn); + rc = dlpar_attach_node(dn, parent_dn); if (rc) dlpar_free_cc_nodes(dn); diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 326ef0dd6038..b7496948129e 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -132,19 +132,14 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev) static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) { struct device_node *dn; - struct pci_dn *pdn; const __be32 *p; u32 req_msi; - pdn = pci_get_pdn(pdev); - if (!pdn) - return -ENODEV; - - dn = pdn->node; + dn = pci_device_to_OF_node(pdev); p = of_get_property(dn, prop_name, NULL); if (!p) { - pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name); + pr_debug("rtas_msi: No %s on %pOF\n", prop_name, dn); return -ENOENT; } @@ -182,8 +177,8 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) while (dn) { p = of_get_property(dn, "ibm,pe-total-#msi", NULL); if (p) { - pr_debug("rtas_msi: found prop on dn %s\n", - dn->full_name); + pr_debug("rtas_msi: found prop on dn %pOF\n", + dn); *total = be32_to_cpup(p); return dn; } @@ -197,7 +192,6 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) { struct device_node *dn; - struct pci_dn *pdn; struct eeh_dev *edev; /* Found our PE and assume 8 at that point. */ @@ -210,8 +204,7 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) edev = pdn_to_eeh_dev(PCI_DN(dn)); if (edev->pe) edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); - pdn = eeh_dev_to_pdn(edev); - dn = pdn ? pdn->node : NULL; + dn = pci_device_to_OF_node(edev->pdev); if (!dn) return NULL; @@ -222,7 +215,7 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) /* Hardcode of 8 for old firmwares */ *total = 8; - pr_debug("rtas_msi: using PE dn %s\n", dn->full_name); + pr_debug("rtas_msi: using PE dn %pOF\n", dn); return dn; } @@ -242,7 +235,7 @@ static void *count_non_bridge_devices(struct device_node *dn, void *data) const __be32 *p; u32 class; - pr_debug("rtas_msi: counting %s\n", dn->full_name); + pr_debug("rtas_msi: counting %pOF\n", dn); p = of_get_property(dn, "class-code", NULL); class = p ? be32_to_cpup(p) : 0; @@ -300,7 +293,7 @@ static int msi_quota_for_device(struct pci_dev *dev, int request) goto out; } - pr_debug("rtas_msi: found PE %s\n", pe_dn->full_name); + pr_debug("rtas_msi: found PE %pOF\n", pe_dn); memset(&counts, 0, sizeof(struct msi_counts)); diff --git a/arch/powerpc/platforms/pseries/of_helpers.c b/arch/powerpc/platforms/pseries/of_helpers.c index 2798933c0e38..7e75101fa522 100644 --- a/arch/powerpc/platforms/pseries/of_helpers.c +++ b/arch/powerpc/platforms/pseries/of_helpers.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/platforms/pseries/of_helpers.h b/arch/powerpc/platforms/pseries/of_helpers.h index bb83d39aef65..decad6553d8f 100644 --- a/arch/powerpc/platforms/pseries/of_helpers.h +++ b/arch/powerpc/platforms/pseries/of_helpers.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PSERIES_OF_HELPERS_H #define _PSERIES_OF_HELPERS_H diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h index 08672d9136ab..51414aee2862 100644 --- a/arch/powerpc/platforms/pseries/offline_states.h +++ b/arch/powerpc/platforms/pseries/offline_states.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _OFFLINE_STATES_H_ #define _OFFLINE_STATES_H_ diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 547fd13e4f8e..561917fa54a8 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -38,7 +38,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn) { struct pci_controller *phb; - pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name); + pr_debug("PCI: Initializing new hotplug PHB %pOF\n", dn); phb = pcibios_alloc_controller(dn); if (!phb) diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h index 1361a9db534b..4470a3194311 100644 --- a/arch/powerpc/platforms/pseries/pseries.h +++ b/arch/powerpc/platforms/pseries/pseries.h @@ -46,7 +46,7 @@ extern void dlpar_free_cc_nodes(struct device_node *); extern void dlpar_free_cc_property(struct property *); extern struct device_node *dlpar_configure_connector(__be32, struct device_node *); -extern int dlpar_attach_node(struct device_node *); +extern int dlpar_attach_node(struct device_node *, struct device_node *); extern int dlpar_detach_node(struct device_node *); extern int dlpar_acquire_drc(u32 drc_index); extern int dlpar_release_drc(u32 drc_index); diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c index 164a13d3998a..35c891aabef0 100644 --- a/arch/powerpc/platforms/pseries/pseries_energy.c +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -229,10 +229,9 @@ static int __init pseries_energy_init(void) int cpu, err; struct device *cpu_dev; - if (!firmware_has_feature(FW_FEATURE_BEST_ENERGY)) { - printk(KERN_INFO "Hypercall H_BEST_ENERGY not supported\n"); - return 0; - } + if (!firmware_has_feature(FW_FEATURE_BEST_ENERGY)) + return 0; /* H_BEST_ENERGY hcall not supported */ + /* Create the sysfs files */ err = device_create_file(cpu_subsys.dev_root, &attr_cpu_activate_hint_list); diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index bb70b26334f0..4923ffe230cf 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -379,6 +379,21 @@ static void fwnmi_release_errinfo(void) int pSeries_system_reset_exception(struct pt_regs *regs) { +#ifdef __LITTLE_ENDIAN__ + /* + * Some firmware byteswaps SRR registers and gives incorrect SRR1. Try + * to detect the bad SRR1 pattern here. Flip the NIP back to correct + * endian for reporting purposes. Unfortunately the MSR can't be fixed, + * so clear it. It will be missing MSR_RI so we won't try to recover. + */ + if ((be64_to_cpu(regs->msr) & + (MSR_LE|MSR_RI|MSR_DR|MSR_IR|MSR_ME|MSR_PR| + MSR_ILE|MSR_HV|MSR_SF)) == (MSR_DR|MSR_SF)) { + regs->nip = be64_to_cpu((__be64)regs->nip); + regs->msr = 0; + } +#endif + if (fwnmi_active) { struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs); if (errhdr) { diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 011ef2180fe6..296c188fd5ca 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -362,20 +362,13 @@ static int do_update_property(char *buf, size_t bufsize) static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - int rv = 0; + int rv; char *kbuf; char *tmp; - if (!(kbuf = kmalloc(count + 1, GFP_KERNEL))) { - rv = -ENOMEM; - goto out; - } - if (copy_from_user(kbuf, buf, count)) { - rv = -EFAULT; - goto out; - } - - kbuf[count] = '\0'; + kbuf = memdup_user_nul(buf, count); + if (IS_ERR(kbuf)) + return PTR_ERR(kbuf); tmp = strchr(kbuf, ' '); if (!tmp) { diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index b5d86426e97b..5f1beb8367ac 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -176,8 +177,11 @@ static void __init pseries_setup_i8259_cascade(void) static void __init pseries_init_irq(void) { - xics_init(); - pseries_setup_i8259_cascade(); + /* Try using a XIVE if available, otherwise use a XICS */ + if (!xive_spapr_init()) { + xics_init(); + pseries_setup_i8259_cascade(); + } } static void pseries_lpar_enable_pmcs(void) @@ -722,7 +726,6 @@ define_machine(pseries) { .pcibios_fixup = pSeries_final_fixup, .restart = rtas_restart, .halt = rtas_halt, - .panic = rtas_os_term, .get_boot_time = rtas_get_boot_time, .get_rtc_time = rtas_get_rtc_time, .set_rtc_time = rtas_set_rtc_time, diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 24785f63fb40..2e184829e5d4 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -136,7 +137,9 @@ out: static void smp_setup_cpu(int cpu) { - if (cpu != boot_cpuid) + if (xive_enabled()) + xive_smp_setup_cpu(); + else if (cpu != boot_cpuid) xics_setup_cpu(); if (firmware_has_feature(FW_FEATURE_SPLPAR)) @@ -181,6 +184,13 @@ static int smp_pSeries_kick_cpu(int nr) return 0; } +static int pseries_smp_prepare_cpu(int cpu) +{ + if (xive_enabled()) + return xive_smp_prepare_cpu(cpu); + return 0; +} + static void smp_pseries_cause_ipi(int cpu) { /* POWER9 should not use this handler */ @@ -211,7 +221,7 @@ static int pseries_cause_nmi_ipi(int cpu) return 0; } -static __init void pSeries_smp_probe(void) +static __init void pSeries_smp_probe_xics(void) { xics_smp_probe(); @@ -221,11 +231,24 @@ static __init void pSeries_smp_probe(void) smp_ops->cause_ipi = icp_ops->cause_ipi; } +static __init void pSeries_smp_probe(void) +{ + if (xive_enabled()) + /* + * Don't use P9 doorbells when XIVE is enabled. IPIs + * using MMIOs should be faster + */ + xive_smp_probe(); + else + pSeries_smp_probe_xics(); +} + static struct smp_ops_t pseries_smp_ops = { .message_pass = NULL, /* Use smp_muxed_ipi_message_pass */ .cause_ipi = NULL, /* Filled at runtime by pSeries_smp_probe() */ .cause_nmi_ipi = pseries_cause_nmi_ipi, .probe = pSeries_smp_probe, + .prepare_cpu = pseries_smp_prepare_cpu, .kick_cpu = smp_pSeries_kick_cpu, .setup_cpu = smp_setup_cpu, .cpu_bootable = smp_generic_cpu_bootable, diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index e76aefae2aa2..89726f07d249 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c @@ -151,7 +151,7 @@ static ssize_t store_hibernate(struct device *dev, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) + if (!alloc_cpumask_var(&offline_mask, GFP_KERNEL)) return -ENOMEM; stream_id = simple_strtoul(buf, NULL, 16); diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index 8a47f168476b..12277bc9fd9e 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -1357,14 +1357,14 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) */ parent_node = of_get_parent(of_node); if (parent_node) { - if (!strcmp(parent_node->full_name, "/ibm,platform-facilities")) + if (!strcmp(parent_node->type, "ibm,platform-facilities")) family = PFO; - else if (!strcmp(parent_node->full_name, "/vdevice")) + else if (!strcmp(parent_node->type, "vdevice")) family = VDEVICE; else { - pr_warn("%s: parent(%s) of %s not recognized.\n", + pr_warn("%s: parent(%pOF) of %s not recognized.\n", __func__, - parent_node->full_name, + parent_node, of_node_name); of_node_put(parent_node); return NULL; @@ -1555,7 +1555,7 @@ static ssize_t devspec_show(struct device *dev, { struct device_node *of_node = dev->of_node; - return sprintf(buf, "%s\n", of_node_full_name(of_node)); + return sprintf(buf, "%pOF\n", of_node); } static DEVICE_ATTR_RO(devspec); diff --git a/arch/powerpc/purgatory/Makefile b/arch/powerpc/purgatory/Makefile index ac8793c13348..30e05decbb4c 100644 --- a/arch/powerpc/purgatory/Makefile +++ b/arch/powerpc/purgatory/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 targets += trampoline.o purgatory.ro kexec-purgatory.c LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined diff --git a/arch/powerpc/purgatory/trampoline.S b/arch/powerpc/purgatory/trampoline.S index 3696ea6c4826..4aad9dd10ace 100644 --- a/arch/powerpc/purgatory/trampoline.S +++ b/arch/powerpc/purgatory/trampoline.S @@ -67,7 +67,7 @@ master: mr %r16,%r3 /* save dt address in reg16 */ li %r4,20 LWZX_BE %r6,%r3,%r4 /* fetch __be32 version number at byte 20 */ - cmpwi %r0,%r6,2 /* v2 or later? */ + cmpwi %cr0,%r6,2 /* v2 or later? */ blt 1f li %r4,28 STWX_BE %r17,%r3,%r4 /* Store my cpu as __be32 at byte 28 */ @@ -104,13 +104,13 @@ master: .balign 8 .globl kernel kernel: - .llong 0x0 + .8byte 0x0 .size kernel, . - kernel .balign 8 .globl dt_offset dt_offset: - .llong 0x0 + .8byte 0x0 .size dt_offset, . - dt_offset diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index caf882e749dc..bcef2ac56479 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. # diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index c0ae11d4f62f..0baba21404dc 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) @@ -36,25 +37,15 @@ obj-$(CONFIG_AXON_RAM) += axonram.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_IPIC) += ipic.o -obj-$(CONFIG_4xx) += uic.o -obj-$(CONFIG_PPC4xx_OCM) += ppc4xx_ocm.o -obj-$(CONFIG_4xx_SOC) += ppc4xx_soc.o obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o obj-$(CONFIG_XILINX_PCI) += xilinx_pci.o obj-$(CONFIG_OF_RTC) += of_rtc.o -ifeq ($(CONFIG_PCI),y) -obj-$(CONFIG_4xx) += ppc4xx_pci.o -endif -obj-$(CONFIG_PPC4xx_HSTA_MSI) += ppc4xx_hsta_msi.o -obj-$(CONFIG_PPC4xx_MSI) += ppc4xx_msi.o -obj-$(CONFIG_PPC4xx_CPM) += ppc4xx_cpm.o -obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o obj-$(CONFIG_CPM) += cpm_common.o +obj-$(CONFIG_CPM1) += cpm1.o obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o obj-$(CONFIG_QUICC_ENGINE) += cpm_common.o obj-$(CONFIG_PPC_DCR) += dcr.o -obj-$(CONFIG_8xx) += mpc8xx_pic.o cpm1.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o obj-$(CONFIG_PPC_MPC512x) += mpc5xxx_clocks.o diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index 2799706106c6..c60e84e4558d 100644 --- a/arch/powerpc/sysdev/axonram.c +++ b/arch/powerpc/sysdev/axonram.c @@ -110,7 +110,7 @@ axon_ram_irq_handler(int irq, void *dev) static blk_qc_t axon_ram_make_request(struct request_queue *queue, struct bio *bio) { - struct axon_ram_bank *bank = bio->bi_bdev->bd_disk->private_data; + struct axon_ram_bank *bank = bio->bi_disk->private_data; unsigned long phys_mem, phys_end; void *user_mem; struct bio_vec vec; @@ -188,15 +188,12 @@ static int axon_ram_probe(struct platform_device *device) axon_ram_bank_id++; - dev_info(&device->dev, "Found memory controller on %s\n", - device->dev.of_node->full_name); + dev_info(&device->dev, "Found memory controller on %pOF\n", + device->dev.of_node); - bank = kzalloc(sizeof(struct axon_ram_bank), GFP_KERNEL); - if (bank == NULL) { - dev_err(&device->dev, "Out of memory\n"); - rc = -ENOMEM; - goto failed; - } + bank = kzalloc(sizeof(*bank), GFP_KERNEL); + if (!bank) + return -ENOMEM; device->dev.platform_data = bank; @@ -292,25 +289,22 @@ static int axon_ram_probe(struct platform_device *device) return 0; failed: - if (bank != NULL) { - if (bank->irq_id) - free_irq(bank->irq_id, device); - if (bank->disk != NULL) { - if (bank->disk->major > 0) - unregister_blkdev(bank->disk->major, - bank->disk->disk_name); - if (bank->disk->flags & GENHD_FL_UP) - del_gendisk(bank->disk); - put_disk(bank->disk); - } - kill_dax(bank->dax_dev); - put_dax(bank->dax_dev); - device->dev.platform_data = NULL; - if (bank->io_addr != 0) - iounmap((void __iomem *) bank->io_addr); - kfree(bank); + if (bank->irq_id) + free_irq(bank->irq_id, device); + if (bank->disk != NULL) { + if (bank->disk->major > 0) + unregister_blkdev(bank->disk->major, + bank->disk->disk_name); + if (bank->disk->flags & GENHD_FL_UP) + del_gendisk(bank->disk); + put_disk(bank->disk); } - + kill_dax(bank->dax_dev); + put_dax(bank->dax_dev); + device->dev.platform_data = NULL; + if (bank->io_addr != 0) + iounmap((void __iomem *) bank->io_addr); + kfree(bank); return rc; } diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index c651e668996b..c6f154b602fb 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * General Purpose functions for the global management of the * Communication Processor Module. diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/cpm2_pic.h index 2c5f70c24485..a8a26951f311 100644 --- a/arch/powerpc/sysdev/cpm2_pic.h +++ b/arch/powerpc/sysdev/cpm2_pic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PPC_KERNEL_CPM2_H #define _PPC_KERNEL_CPM2_H diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c index 121e26fffd50..d72eda568b7d 100644 --- a/arch/powerpc/sysdev/dcr.c +++ b/arch/powerpc/sysdev/dcr.c @@ -195,8 +195,8 @@ dcr_host_mmio_t dcr_map_mmio(struct device_node *dev, dcr_host_mmio_t ret = { .token = NULL, .stride = 0, .base = dcr_n }; u64 addr; - pr_debug("dcr_map(%s, 0x%x, 0x%x)\n", - dev->full_name, dcr_n, dcr_c); + pr_debug("dcr_map(%pOF, 0x%x, 0x%x)\n", + dev, dcr_n, dcr_c); addr = of_translate_dcr_address(dev, dcr_n, &ret.stride); pr_debug("translates to addr: 0x%llx, stride: 0x%x\n", diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c index 37a69097e022..00ccf3e4fcb4 100644 --- a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c +++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c @@ -101,8 +101,8 @@ int __init instantiate_cache_sram(struct platform_device *dev, if (!request_mem_region(cache_sram->base_phys, cache_sram->size, "fsl_85xx_cache_sram")) { - dev_err(&dev->dev, "%s: request memory failed\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF: request memory failed\n", + dev->dev.of_node); ret = -ENXIO; goto out_free; } @@ -110,16 +110,16 @@ int __init instantiate_cache_sram(struct platform_device *dev, cache_sram->base_virt = ioremap_prot(cache_sram->base_phys, cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL); if (!cache_sram->base_virt) { - dev_err(&dev->dev, "%s: ioremap_prot failed\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF: ioremap_prot failed\n", + dev->dev.of_node); ret = -ENOMEM; goto out_release; } cache_sram->rh = rh_create(sizeof(unsigned int)); if (IS_ERR(cache_sram->rh)) { - dev_err(&dev->dev, "%s: Unable to create remote heap\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "%pOF: Unable to create remote heap\n", + dev->dev.of_node); ret = PTR_ERR(cache_sram->rh); goto out_unmap; } diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index a6f0b96ce2c9..d902306f4718 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -388,8 +388,8 @@ static int __init fsl_gtm_init(void) gtm = kzalloc(sizeof(*gtm), GFP_KERNEL); if (!gtm) { - pr_err("%s: unable to allocate memory\n", - np->full_name); + pr_err("%pOF: unable to allocate memory\n", + np); continue; } @@ -397,7 +397,7 @@ static int __init fsl_gtm_init(void) clock = of_get_property(np, "clock-frequency", &size); if (!clock || size != sizeof(*clock)) { - pr_err("%s: no clock-frequency\n", np->full_name); + pr_err("%pOF: no clock-frequency\n", np); goto err; } gtm->clock = *clock; @@ -407,8 +407,8 @@ static int __init fsl_gtm_init(void) irq = irq_of_parse_and_map(np, i); if (!irq) { - pr_err("%s: not enough interrupts specified\n", - np->full_name); + pr_err("%pOF: not enough interrupts specified\n", + np); goto err; } gtm->timers[i].irq = irq; @@ -417,8 +417,8 @@ static int __init fsl_gtm_init(void) gtm->regs = of_iomap(np, 0); if (!gtm->regs) { - pr_err("%s: unable to iomap registers\n", - np->full_name); + pr_err("%pOF: unable to iomap registers\n", + np); goto err; } diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 8a244828782e..44cbf4c12ea1 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -214,8 +214,8 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) phandle = np->phandle; else { dev_err(&pdev->dev, - "node %s has an invalid fsl,msi phandle %u\n", - hose->dn->full_name, np->phandle); + "node %pOF has an invalid fsl,msi phandle %u\n", + hose->dn, np->phandle); return -EINVAL; } } @@ -438,16 +438,16 @@ static int fsl_of_msi_probe(struct platform_device *dev) if ((features->fsl_pic_ip & FSL_PIC_IP_MASK) != FSL_PIC_IP_VMPIC) { err = of_address_to_resource(dev->dev.of_node, 0, &res); if (err) { - dev_err(&dev->dev, "invalid resource for node %s\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "invalid resource for node %pOF\n", + dev->dev.of_node); goto error_out; } msi->msi_regs = ioremap(res.start, resource_size(&res)); if (!msi->msi_regs) { err = -ENOMEM; - dev_err(&dev->dev, "could not map node %s\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "could not map node %pOF\n", + dev->dev.of_node); goto error_out; } msi->msiir_offset = @@ -522,8 +522,8 @@ static int fsl_of_msi_probe(struct platform_device *dev) for (irq_index = 0, i = 0; i < len / (2 * sizeof(u32)); i++) { if (p[i * 2] % IRQS_PER_MSI_REG || p[i * 2 + 1] % IRQS_PER_MSI_REG) { - pr_warn("%s: %s: msi available range of %u at %u is not IRQ-aligned\n", - __func__, dev->dev.of_node->full_name, + pr_warn("%s: %pOF: msi available range of %u at %u is not IRQ-aligned\n", + __func__, dev->dev.of_node, p[i * 2 + 1], p[i * 2]); err = -EINVAL; goto error_out; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index d3a597456b6e..22d98057f773 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -202,7 +202,6 @@ static void setup_pci_atmu(struct pci_controller *hose) u32 pcicsrbar = 0, pcicsrbar_sz; u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; - const char *name = hose->dn->full_name; const u64 *reg; int len; bool setup_inbound; @@ -290,12 +289,12 @@ static void setup_pci_atmu(struct pci_controller *hose) paddr_lo -= offset; if (paddr_hi == paddr_lo) { - pr_err("%s: No outbound window space\n", name); + pr_err("%pOF: No outbound window space\n", hose->dn); return; } if (paddr_lo == 0) { - pr_err("%s: No space for inbound window\n", name); + pr_err("%pOF: No space for inbound window\n", hose->dn); return; } @@ -313,7 +312,7 @@ static void setup_pci_atmu(struct pci_controller *hose) paddr_lo = min(paddr_lo, (u64)pcicsrbar); - pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar); + pr_info("%pOF: PCICSRBAR @ 0x%x\n", hose->dn, pcicsrbar); /* Setup inbound mem window */ mem = memblock_end_of_DRAM(); @@ -336,12 +335,12 @@ static void setup_pci_atmu(struct pci_controller *hose) u64 address = be64_to_cpup(reg); if ((address >= mem) && (address < (mem + PAGE_SIZE))) { - pr_info("%s: extending DDR ATMU to cover MSIIR", name); + pr_info("%pOF: extending DDR ATMU to cover MSIIR", hose->dn); mem += PAGE_SIZE; } else { /* TODO: Create a new ATMU for MSIIR */ - pr_warn("%s: msi-address-64 address of %llx is " - "unsupported\n", name, address); + pr_warn("%pOF: msi-address-64 address of %llx is " + "unsupported\n", hose->dn, address); } } @@ -354,8 +353,8 @@ static void setup_pci_atmu(struct pci_controller *hose) if ((1ull << mem_log) != mem) { mem_log++; if ((1ull << mem_log) > mem) - pr_info("%s: Setting PCI inbound window " - "greater than memory size\n", name); + pr_info("%pOF: Setting PCI inbound window " + "greater than memory size\n", hose->dn); } piwar |= ((mem_log - 1) & PIWAR_SZ_MASK); @@ -402,7 +401,7 @@ static void setup_pci_atmu(struct pci_controller *hose) */ ppc_md.dma_set_mask = fsl_pci_dma_set_mask; - pr_info("%s: Setup 64-bit PCI DMA window\n", name); + pr_info("%pOF: Setup 64-bit PCI DMA window\n", hose->dn); } } else { u64 paddr = 0; @@ -443,18 +442,18 @@ static void setup_pci_atmu(struct pci_controller *hose) #ifdef CONFIG_SWIOTLB ppc_swiotlb_enable = 1; #else - pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to " + pr_err("%pOF: ERROR: Memory size exceeds PCI ATMU ability to " "map - enable CONFIG_SWIOTLB to avoid dma errors.\n", - name); + hose->dn); #endif /* adjusting outbound windows could reclaim space in mem map */ if (paddr_hi < 0xffffffffull) - pr_warning("%s: WARNING: Outbound window cfg leaves " + pr_warning("%pOF: WARNING: Outbound window cfg leaves " "gaps in memory map. Adjusting the memory map " "could reduce unnecessary bounce buffering.\n", - name); + hose->dn); - pr_info("%s: DMA window size is 0x%llx\n", name, + pr_info("%pOF: DMA window size is 0x%llx\n", hose->dn, (u64)hose->dma_window_size); } } @@ -532,11 +531,11 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary) dev = pdev->dev.of_node; if (!of_device_is_available(dev)) { - pr_warning("%s: disabled\n", dev->full_name); + pr_warning("%pOF: disabled\n", dev); return -ENODEV; } - pr_debug("Adding PCI host bridge %s\n", dev->full_name); + pr_debug("Adding PCI host bridge %pOF\n", dev); /* Fetch host bridge registers address */ if (of_address_to_resource(dev, 0, &rsrc)) { @@ -547,8 +546,8 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); pci_add_flags(PCI_REASSIGN_ALL_BUS); hose = pcibios_alloc_controller(dev); @@ -809,11 +808,11 @@ int __init mpc83xx_add_bridge(struct device_node *dev) is_mpc83xx_pci = 1; if (!of_device_is_available(dev)) { - pr_warning("%s: disabled by the firmware.\n", - dev->full_name); + pr_warning("%pOF: disabled by the firmware.\n", + dev); return -ENODEV; } - pr_debug("Adding PCI host bridge %s\n", dev->full_name); + pr_debug("Adding PCI host bridge %pOF\n", dev); /* Fetch host bridge registers address */ if (of_address_to_resource(dev, 0, &rsrc_reg)) { @@ -848,8 +847,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); } pci_add_flags(PCI_REASSIGN_ALL_BUS); diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index 1c41c51f22cb..5011ffea4e4b 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -71,6 +71,8 @@ #define RIWAR_WRTYP_ALLOC 0x00006000 #define RIWAR_SIZE_MASK 0x0000003F +static DEFINE_SPINLOCK(fsl_rio_config_lock); + #define __fsl_read_rio_config(x, addr, err, op) \ __asm__ __volatile__( \ "1: "op" %1,0(%2)\n" \ @@ -184,6 +186,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, u8 hopcount, u32 offset, int len, u32 *val) { struct rio_priv *priv = mport->priv; + unsigned long flags; u8 *data; u32 rval, err = 0; @@ -197,6 +200,8 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) return -EINVAL; + spin_lock_irqsave(&fsl_rio_config_lock, flags); + out_be32(&priv->maint_atmu_regs->rowtar, (destid << 22) | (hopcount << 12) | (offset >> 12)); out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -213,6 +218,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, __fsl_read_rio_config(rval, data, err, "lwz"); break; default: + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); return -EINVAL; } @@ -221,6 +227,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid, err, destid, hopcount, offset); } + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); *val = rval; return err; @@ -244,7 +251,10 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, u8 hopcount, u32 offset, int len, u32 val) { struct rio_priv *priv = mport->priv; + unsigned long flags; u8 *data; + int ret = 0; + pr_debug ("fsl_rio_config_write:" " index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", @@ -255,6 +265,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len)) return -EINVAL; + spin_lock_irqsave(&fsl_rio_config_lock, flags); + out_be32(&priv->maint_atmu_regs->rowtar, (destid << 22) | (hopcount << 12) | (offset >> 12)); out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10)); @@ -271,10 +283,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid, out_be32((u32 *) data, val); break; default: - return -EINVAL; + ret = -EINVAL; } + spin_unlock_irqrestore(&fsl_rio_config_lock, flags); - return 0; + return ret; } static void fsl_rio_inbound_mem_init(struct rio_priv *priv) @@ -450,12 +463,12 @@ int fsl_rio_setup(struct platform_device *dev) rc = of_address_to_resource(dev->dev.of_node, 0, ®s); if (rc) { - dev_err(&dev->dev, "Can't get %s property 'reg'\n", - dev->dev.of_node->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'reg'\n", + dev->dev.of_node); return -EFAULT; } - dev_info(&dev->dev, "Of-device full name %s\n", - dev->dev.of_node->full_name); + dev_info(&dev->dev, "Of-device full name %pOF\n", + dev->dev.of_node); dev_info(&dev->dev, "Regs: %pR\n", ®s); rio_regs_win = ioremap(regs.start, resource_size(®s)); @@ -494,8 +507,8 @@ int fsl_rio_setup(struct platform_device *dev) } rc = of_address_to_resource(rmu_node, 0, &rmu_regs); if (rc) { - dev_err(&dev->dev, "Can't get %s property 'reg'\n", - rmu_node->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'reg'\n", + rmu_node); goto err_rmu; } rmu_regs_win = ioremap(rmu_regs.start, resource_size(&rmu_regs)); @@ -529,8 +542,8 @@ int fsl_rio_setup(struct platform_device *dev) aw = of_n_addr_cells(np); dt_range = of_get_property(np, "reg", &rlen); if (!dt_range) { - pr_err("%s: unable to find 'reg' property\n", - np->full_name); + pr_err("%pOF: unable to find 'reg' property\n", + np); rc = -ENOMEM; goto err_pw; } @@ -557,8 +570,8 @@ int fsl_rio_setup(struct platform_device *dev) aw = of_n_addr_cells(np); dt_range = of_get_property(np, "reg", &rlen); if (!dt_range) { - pr_err("%s: unable to find 'reg' property\n", - np->full_name); + pr_err("%pOF: unable to find 'reg' property\n", + np); rc = -ENOMEM; goto err; } @@ -569,15 +582,15 @@ int fsl_rio_setup(struct platform_device *dev) for_each_child_of_node(dev->dev.of_node, np) { port_index = of_get_property(np, "cell-index", NULL); if (!port_index) { - dev_err(&dev->dev, "Can't get %s property 'cell-index'\n", - np->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'cell-index'\n", + np); continue; } dt_range = of_get_property(np, "ranges", &rlen); if (!dt_range) { - dev_err(&dev->dev, "Can't get %s property 'ranges'\n", - np->full_name); + dev_err(&dev->dev, "Can't get %pOF property 'ranges'\n", + np); continue; } @@ -598,8 +611,8 @@ int fsl_rio_setup(struct platform_device *dev) range_start = of_read_number(dt_range + aw, paw); range_size = of_read_number(dt_range + aw + paw, sw); - dev_info(&dev->dev, "%s: LAW start 0x%016llx, size 0x%016llx.\n", - np->full_name, range_start, range_size); + dev_info(&dev->dev, "%pOF: LAW start 0x%016llx, size 0x%016llx.\n", + np, range_start, range_size); port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); if (!port) @@ -757,8 +770,8 @@ err_rio_regs: */ static int fsl_of_rio_rpn_probe(struct platform_device *dev) { - printk(KERN_INFO "Setting up RapidIO peer-to-peer network %s\n", - dev->dev.of_node->full_name); + printk(KERN_INFO "Setting up RapidIO peer-to-peer network %pOF\n", + dev->dev.of_node); return fsl_rio_setup(dev); }; diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index c1826de4e749..88b35a3dcdc5 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -104,6 +104,8 @@ #define DOORBELL_MESSAGE_SIZE 0x08 +static DEFINE_SPINLOCK(fsl_rio_doorbell_lock); + struct rio_msg_regs { u32 omr; u32 osr; @@ -626,9 +628,13 @@ err_out: int fsl_rio_doorbell_send(struct rio_mport *mport, int index, u16 destid, u16 data) { + unsigned long flags; + pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n", index, destid, data); + spin_lock_irqsave(&fsl_rio_doorbell_lock, flags); + /* In the serial version silicons, such as MPC8548, MPC8641, * below operations is must be. */ @@ -638,6 +644,8 @@ int fsl_rio_doorbell_send(struct rio_mport *mport, out_be32(&dbell->dbell_regs->oddatr, (index << 20) | data); out_be32(&dbell->dbell_regs->odmr, 0x00000001); + spin_unlock_irqrestore(&fsl_rio_doorbell_lock, flags); + return 0; } @@ -1074,8 +1082,8 @@ int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node) priv = mport->priv; if (!node) { - dev_warn(priv->dev, "Can't get %s property 'fsl,rmu'\n", - priv->dev->of_node->full_name); + dev_warn(priv->dev, "Can't get %pOF property 'fsl,rmu'\n", + priv->dev->of_node); return -EINVAL; } @@ -1086,8 +1094,8 @@ int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node) aw = of_n_addr_cells(node); msg_addr = of_get_property(node, "reg", &mlen); if (!msg_addr) { - pr_err("%s: unable to find 'reg' property of message-unit\n", - node->full_name); + pr_err("%pOF: unable to find 'reg' property of message-unit\n", + node); kfree(rmu); return -ENOMEM; } @@ -1098,8 +1106,8 @@ int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node) rmu->txirq = irq_of_parse_and_map(node, 0); rmu->rxirq = irq_of_parse_and_map(node, 1); - printk(KERN_INFO "%s: txirq: %d, rxirq %d\n", - node->full_name, rmu->txirq, rmu->rxirq); + printk(KERN_INFO "%pOF: txirq: %d, rxirq %d\n", + node, rmu->txirq, rmu->rxirq); priv->rmm_handle = rmu; diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 19101f9cfcfc..1f614fb2be56 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -98,7 +98,7 @@ u32 fsl_get_sys_freq(void) } EXPORT_SYMBOL(fsl_get_sys_freq); -#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) +#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) u32 get_brgfreq(void) { diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h index d73daa4f0ccf..db11b06eb38f 100644 --- a/arch/powerpc/sysdev/fsl_soc.h +++ b/arch/powerpc/sysdev/fsl_soc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PPC_FSL_SOC_H #define __PPC_FSL_SOC_H #ifdef __KERNEL__ @@ -7,7 +8,7 @@ struct spi_device; extern phys_addr_t get_immrbase(void); -#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) +#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) extern u32 get_brgfreq(void); extern u32 get_baudrate(void); #else diff --git a/arch/powerpc/sysdev/ge/ge_pic.h b/arch/powerpc/sysdev/ge/ge_pic.h index 5bf7e4b81e36..923dedba3c9c 100644 --- a/arch/powerpc/sysdev/ge/ge_pic.h +++ b/arch/powerpc/sysdev/ge/ge_pic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __GEF_PIC_H__ #define __GEF_PIC_H__ diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index f267ee0afc08..16f1edd78c40 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -315,6 +315,7 @@ static struct ipic_info ipic_info[] = { .prio_mask = 7, }, [48] = { + .ack = IPIC_SEPNR, .mask = IPIC_SEMSR, .prio = IPIC_SMPRR_A, .force = IPIC_SEFCR, diff --git a/arch/powerpc/sysdev/micropatch.c b/arch/powerpc/sysdev/micropatch.c index 6727dc54d549..33a9042fca80 100644 --- a/arch/powerpc/sysdev/micropatch.c +++ b/arch/powerpc/sysdev/micropatch.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Microcode patches for the CPM as supplied by Motorola. * This is the one for IIC/SPI. There is a newer one that diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/mpc5xxx_clocks.c index 573292663cf2..834a6d7fbd88 100644 --- a/arch/powerpc/sysdev/mpc5xxx_clocks.c +++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /** * mpc5xxx_get_bus_frequency - Find the bus frequency for a device * @node: device node diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index b9aac951a90f..ead3e2549ebf 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1650,8 +1650,8 @@ void __init mpic_init(struct mpic *mpic) if (mpic->flags & MPIC_SECONDARY) { int virq = irq_of_parse_and_map(mpic->node, 0); if (virq) { - printk(KERN_INFO "%s: hooking up to IRQ %d\n", - mpic->node->full_name, virq); + printk(KERN_INFO "%pOF: hooking up to IRQ %d\n", + mpic->node, virq); irq_set_handler_data(virq, mpic); irq_set_chained_handler(virq, &mpic_cascade); } diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index db2286be5d9a..eb69a5186243 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -192,7 +192,7 @@ static int mpic_msgr_probe(struct platform_device *dev) return -ENOMEM; } } - dev_info(&dev->dev, "Of-device full name %s\n", np->full_name); + dev_info(&dev->dev, "Of-device full name %pOF\n", np); /* IO map the message register block. */ of_address_to_resource(np, 0, &rsrc); diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c index 1d48a5385905..9ed860aee9c3 100644 --- a/arch/powerpc/sysdev/mpic_msi.c +++ b/arch/powerpc/sysdev/mpic_msi.c @@ -60,7 +60,7 @@ static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) np = NULL; while ((np = of_find_all_nodes(np))) { - pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); + pr_debug("mpic: mapping hwirqs for %pOF\n", np); index = 0; while (of_irq_parse_one(np, index++, &oirq) == 0) { diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c index 9d9b06217f8b..a418579591be 100644 --- a/arch/powerpc/sysdev/mpic_timer.c +++ b/arch/powerpc/sysdev/mpic_timer.c @@ -466,8 +466,7 @@ static int timer_group_get_irq(struct device_node *np, p = of_get_property(np, "fsl,available-ranges", &len); if (p && len % (2 * sizeof(u32)) != 0) { - pr_err("%s: malformed available-ranges property.\n", - np->full_name); + pr_err("%pOF: malformed available-ranges property.\n", np); return -EINVAL; } @@ -484,8 +483,7 @@ static int timer_group_get_irq(struct device_node *np, for (j = 0; j < count; j++) { irq = irq_of_parse_and_map(np, irq_index); if (!irq) { - pr_err("%s: irq parse and map failed.\n", - np->full_name); + pr_err("%pOF: irq parse and map failed.\n", np); return -EINVAL; } @@ -508,8 +506,7 @@ static void timer_group_init(struct device_node *np) priv = kzalloc(sizeof(struct timer_group_priv), GFP_KERNEL); if (!priv) { - pr_err("%s: cannot allocate memory for group.\n", - np->full_name); + pr_err("%pOF: cannot allocate memory for group.\n", np); return; } @@ -518,29 +515,27 @@ static void timer_group_init(struct device_node *np) priv->regs = of_iomap(np, i++); if (!priv->regs) { - pr_err("%s: cannot ioremap timer register address.\n", - np->full_name); + pr_err("%pOF: cannot ioremap timer register address.\n", np); goto out; } if (priv->flags & FSL_GLOBAL_TIMER) { priv->group_tcr = of_iomap(np, i++); if (!priv->group_tcr) { - pr_err("%s: cannot ioremap tcr address.\n", - np->full_name); + pr_err("%pOF: cannot ioremap tcr address.\n", np); goto out; } } ret = timer_group_get_freq(np, priv); if (ret < 0) { - pr_err("%s: cannot get timer frequency.\n", np->full_name); + pr_err("%pOF: cannot get timer frequency.\n", np); goto out; } ret = timer_group_get_irq(np, priv); if (ret < 0) { - pr_err("%s: cannot get timer irqs.\n", np->full_name); + pr_err("%pOF: cannot get timer irqs.\n", np); goto out; } diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c index 5ebd3f018295..c4dae27172b3 100644 --- a/arch/powerpc/sysdev/msi_bitmap.c +++ b/arch/powerpc/sysdev/msi_bitmap.c @@ -86,13 +86,13 @@ int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp) p = of_get_property(bmp->of_node, "msi-available-ranges", &len); if (!p) { pr_debug("msi_bitmap: no msi-available-ranges property " \ - "found on %s\n", bmp->of_node->full_name); + "found on %pOF\n", bmp->of_node); return 1; } if (len % (2 * sizeof(u32)) != 0) { printk(KERN_WARNING "msi_bitmap: Malformed msi-available-ranges" - " property on %s\n", bmp->of_node->full_name); + " property on %pOF\n", bmp->of_node); return -EINVAL; } diff --git a/arch/powerpc/sysdev/mv64x60.h b/arch/powerpc/sysdev/mv64x60.h index 4f618fa465c0..60cfcb90d1fa 100644 --- a/arch/powerpc/sysdev/mv64x60.h +++ b/arch/powerpc/sysdev/mv64x60.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MV64X60_H__ #define __MV64X60_H__ diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 026bbc3b2c47..185a67e742a6 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -452,8 +452,8 @@ static int __init mv64x60_device_setup(void) err = mv64x60_mpsc_device_setup(np, id++); if (err) printk(KERN_ERR "Failed to initialize MV64x60 " - "serial device %s: error %d.\n", - np->full_name, err); + "serial device %pOF: error %d.\n", + np, err); } id = 0; @@ -463,8 +463,8 @@ static int __init mv64x60_device_setup(void) if (IS_ERR(pdev)) { err = PTR_ERR(pdev); printk(KERN_ERR "Failed to initialize MV64x60 " - "network block %s: error %d.\n", - np->full_name, err); + "network block %pOF: error %d.\n", + np, err); continue; } for_each_child_of_node(np, np2) { @@ -474,9 +474,9 @@ static int __init mv64x60_device_setup(void) err = mv64x60_eth_device_setup(np2, id2++, pdev); if (err) printk(KERN_ERR "Failed to initialize " - "MV64x60 network device %s: " + "MV64x60 network device %pOF: " "error %d.\n", - np2->full_name, err); + np2, err); } } @@ -485,8 +485,8 @@ static int __init mv64x60_device_setup(void) err = mv64x60_i2c_device_setup(np, id++); if (err) printk(KERN_ERR "Failed to initialize MV64x60 I2C " - "bus %s: error %d.\n", - np->full_name, err); + "bus %pOF: error %d.\n", + np, err); } /* support up to one watchdog timer */ @@ -494,8 +494,8 @@ static int __init mv64x60_device_setup(void) if (np) { if ((err = mv64x60_wdt_device_setup(np, id))) printk(KERN_ERR "Failed to initialize MV64x60 " - "Watchdog %s: error %d.\n", - np->full_name, err); + "Watchdog %pOF: error %d.\n", + np, err); of_node_put(np); } diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c index 330d56613c5a..d52b3b81e05f 100644 --- a/arch/powerpc/sysdev/mv64x60_pci.c +++ b/arch/powerpc/sysdev/mv64x60_pci.c @@ -70,7 +70,7 @@ static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj, return count; } -static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */ +static const struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */ .attr = { .name = "hs_reg", .mode = S_IRUGO | S_IWUSR, @@ -136,8 +136,8 @@ static int __init mv64x60_add_bridge(struct device_node *dev) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); hose = pcibios_alloc_controller(dev); if (!hose) diff --git a/arch/powerpc/sysdev/of_rtc.c b/arch/powerpc/sysdev/of_rtc.c index 6f54b54b1328..153fdac4720f 100644 --- a/arch/powerpc/sysdev/of_rtc.c +++ b/arch/powerpc/sysdev/of_rtc.c @@ -38,21 +38,21 @@ void __init of_instantiate_rtc(void) res = kmalloc(sizeof(*res), GFP_KERNEL); if (!res) { printk(KERN_ERR "OF RTC: Out of memory " - "allocating resource structure for %s\n", - node->full_name); + "allocating resource structure for %pOF\n", + node); continue; } err = of_address_to_resource(node, 0, res); if (err) { printk(KERN_ERR "OF RTC: Error " - "translating resources for %s\n", - node->full_name); + "translating resources for %pOF\n", + node); continue; } - printk(KERN_INFO "OF_RTC: %s is a %s @ 0x%llx-0x%llx\n", - node->full_name, plat_name, + printk(KERN_INFO "OF_RTC: %pOF is a %s @ 0x%llx-0x%llx\n", + node, plat_name, (unsigned long long)res->start, (unsigned long long)res->end); platform_device_register_simple(plat_name, -1, res, 1); diff --git a/arch/powerpc/sysdev/scom.c b/arch/powerpc/sysdev/scom.c index 76ea32c1b664..0f6fd5d04d33 100644 --- a/arch/powerpc/sysdev/scom.c +++ b/arch/powerpc/sysdev/scom.c @@ -194,12 +194,13 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, ent->dn = of_node_get(dn); snprintf(ent->name, 16, "%08x", i); - ent->path.data = (void*) dn->full_name; - ent->path.size = strlen(dn->full_name); + ent->path.data = (void*)kasprintf(GFP_KERNEL, "%pOF", dn); + ent->path.size = strlen((char *)ent->path.data); dir = debugfs_create_dir(ent->name, root); if (!dir) { of_node_put(dn); + kfree(ent->path.data); kfree(ent); return -1; } diff --git a/arch/powerpc/sysdev/simple_gpio.c b/arch/powerpc/sysdev/simple_gpio.c index 6afddae2fb47..f02d4576138c 100644 --- a/arch/powerpc/sysdev/simple_gpio.c +++ b/arch/powerpc/sysdev/simple_gpio.c @@ -142,7 +142,6 @@ void __init simple_gpiochip_init(const char *compatible) } continue; err: - pr_err("%s: registration failed, status %d\n", - np->full_name, ret); + pr_err("%pOF: registration failed, status %d\n", np, ret); } } diff --git a/arch/powerpc/sysdev/simple_gpio.h b/arch/powerpc/sysdev/simple_gpio.h index 3a7b0c513c76..f3f3a20d39e2 100644 --- a/arch/powerpc/sysdev/simple_gpio.h +++ b/arch/powerpc/sysdev/simple_gpio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SYSDEV_SIMPLE_GPIO_H #define __SYSDEV_SIMPLE_GPIO_H diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 5692dd569b9b..28ff1f53cefc 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -213,8 +213,8 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary) /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); + printk(KERN_WARNING "Can't get bus-range for %pOF, assume" + " bus 0\n", dev); } hose = pcibios_alloc_controller(dev); diff --git a/arch/powerpc/sysdev/xics/Kconfig b/arch/powerpc/sysdev/xics/Kconfig index 385e7aa9e273..86fee428f5f1 100644 --- a/arch/powerpc/sysdev/xics/Kconfig +++ b/arch/powerpc/sysdev/xics/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_XICS def_bool n select PPC_SMP_MUXED_IPI diff --git a/arch/powerpc/sysdev/xics/Makefile b/arch/powerpc/sysdev/xics/Makefile index 5d7f5a6564de..5d438d92472b 100644 --- a/arch/powerpc/sysdev/xics/Makefile +++ b/arch/powerpc/sysdev/xics/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-y += xics-common.o diff --git a/arch/powerpc/sysdev/xics/ics-rtas.c b/arch/powerpc/sysdev/xics/ics-rtas.c index 78ee5c778ef8..42e0c56ff81c 100644 --- a/arch/powerpc/sysdev/xics/ics-rtas.c +++ b/arch/powerpc/sysdev/xics/ics-rtas.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/powerpc/sysdev/xive/Kconfig b/arch/powerpc/sysdev/xive/Kconfig index 12ccd7373d2f..70ee976e1de0 100644 --- a/arch/powerpc/sysdev/xive/Kconfig +++ b/arch/powerpc/sysdev/xive/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config PPC_XIVE bool default n @@ -9,3 +10,8 @@ config PPC_XIVE_NATIVE default n select PPC_XIVE depends on PPC_POWERNV + +config PPC_XIVE_SPAPR + bool + default n + select PPC_XIVE diff --git a/arch/powerpc/sysdev/xive/Makefile b/arch/powerpc/sysdev/xive/Makefile index 3fab303fc169..536d6e5706e3 100644 --- a/arch/powerpc/sysdev/xive/Makefile +++ b/arch/powerpc/sysdev/xive/Makefile @@ -2,3 +2,4 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror obj-y += common.o obj-$(CONFIG_PPC_XIVE_NATIVE) += native.o +obj-$(CONFIG_PPC_XIVE_SPAPR) += spapr.o diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 6595462b1fc8..a3b8d7d1316e 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -40,7 +40,8 @@ #undef DEBUG_ALL #ifdef DEBUG_ALL -#define DBG_VERBOSE(fmt...) pr_devel(fmt) +#define DBG_VERBOSE(fmt, ...) pr_devel("cpu %d - " fmt, \ + smp_processor_id(), ## __VA_ARGS__) #else #define DBG_VERBOSE(fmt...) do { } while(0) #endif @@ -190,7 +191,7 @@ static u32 xive_scan_interrupts(struct xive_cpu *xc, bool just_peek) * This is used to perform the magic loads from an ESB * described in xive.h */ -static u8 xive_poke_esb(struct xive_irq_data *xd, u32 offset) +static notrace u8 xive_esb_read(struct xive_irq_data *xd, u32 offset) { u64 val; @@ -198,13 +199,28 @@ static u8 xive_poke_esb(struct xive_irq_data *xd, u32 offset) if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) offset |= offset << 4; - val = in_be64(xd->eoi_mmio + offset); + if ((xd->flags & XIVE_IRQ_FLAG_H_INT_ESB) && xive_ops->esb_rw) + val = xive_ops->esb_rw(xd->hw_irq, offset, 0, 0); + else + val = in_be64(xd->eoi_mmio + offset); return (u8)val; } +static void xive_esb_write(struct xive_irq_data *xd, u32 offset, u64 data) +{ + /* Handle HW errata */ + if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG) + offset |= offset << 4; + + if ((xd->flags & XIVE_IRQ_FLAG_H_INT_ESB) && xive_ops->esb_rw) + xive_ops->esb_rw(xd->hw_irq, offset, data, 1); + else + out_be64(xd->eoi_mmio + offset, data); +} + #ifdef CONFIG_XMON -static void xive_dump_eq(const char *name, struct xive_q *q) +static notrace void xive_dump_eq(const char *name, struct xive_q *q) { u32 i0, i1, idx; @@ -218,7 +234,7 @@ static void xive_dump_eq(const char *name, struct xive_q *q) q->toggle, i0, i1); } -void xmon_xive_do_dump(int cpu) +notrace void xmon_xive_do_dump(int cpu) { struct xive_cpu *xc = per_cpu(xive_cpu, cpu); @@ -227,7 +243,7 @@ void xmon_xive_do_dump(int cpu) xive_dump_eq("IRQ", &xc->queue[xive_irq_priority]); #ifdef CONFIG_SMP { - u64 val = xive_poke_esb(&xc->ipi_data, XIVE_ESB_GET); + u64 val = xive_esb_read(&xc->ipi_data, XIVE_ESB_GET); xmon_printf(" IPI state: %x:%c%c\n", xc->hw_ipi, val & XIVE_ESB_VAL_P ? 'P' : 'p', val & XIVE_ESB_VAL_P ? 'Q' : 'q'); @@ -297,7 +313,7 @@ void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd) { /* If the XIVE supports the new "store EOI facility, use it */ if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI) - out_be64(xd->eoi_mmio + XIVE_ESB_STORE_EOI, 0); + xive_esb_write(xd, XIVE_ESB_STORE_EOI, 0); else if (hw_irq && xd->flags & XIVE_IRQ_FLAG_EOI_FW) { /* * The FW told us to call it. This happens for some @@ -326,10 +342,10 @@ void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd) * properly. */ if (xd->flags & XIVE_IRQ_FLAG_LSI) - in_be64(xd->eoi_mmio); + xive_esb_read(xd, XIVE_ESB_LOAD_EOI); else { - eoi_val = xive_poke_esb(xd, XIVE_ESB_SET_PQ_00); - DBG_VERBOSE("eoi_val=%x\n", offset, eoi_val); + eoi_val = xive_esb_read(xd, XIVE_ESB_SET_PQ_00); + DBG_VERBOSE("eoi_val=%x\n", eoi_val); /* Re-trigger if needed */ if ((eoi_val & XIVE_ESB_VAL_Q) && xd->trig_mmio) @@ -383,12 +399,12 @@ static void xive_do_source_set_mask(struct xive_irq_data *xd, * ESB accordingly on unmask. */ if (mask) { - val = xive_poke_esb(xd, XIVE_ESB_SET_PQ_01); + val = xive_esb_read(xd, XIVE_ESB_SET_PQ_01); xd->saved_p = !!(val & XIVE_ESB_VAL_P); } else if (xd->saved_p) - xive_poke_esb(xd, XIVE_ESB_SET_PQ_10); + xive_esb_read(xd, XIVE_ESB_SET_PQ_10); else - xive_poke_esb(xd, XIVE_ESB_SET_PQ_00); + xive_esb_read(xd, XIVE_ESB_SET_PQ_00); } /* @@ -447,7 +463,7 @@ static int xive_find_target_in_mask(const struct cpumask *mask, int cpu, first, num, i; /* Pick up a starting point CPU in the mask based on fuzz */ - num = cpumask_weight(mask); + num = min_t(int, cpumask_weight(mask), nr_cpu_ids); first = fuzz % num; /* Locate it */ @@ -672,6 +688,10 @@ static int xive_irq_set_affinity(struct irq_data *d, if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) return -EINVAL; + /* Don't do anything if the interrupt isn't started */ + if (!irqd_is_started(d)) + return IRQ_SET_MASK_OK; + /* * If existing target is already in the new mask, and is * online then do nothing. @@ -768,7 +788,7 @@ static int xive_irq_retrigger(struct irq_data *d) * To perform a retrigger, we first set the PQ bits to * 11, then perform an EOI. */ - xive_poke_esb(xd, XIVE_ESB_SET_PQ_11); + xive_esb_read(xd, XIVE_ESB_SET_PQ_11); /* * Note: We pass "0" to the hw_irq argument in order to @@ -803,7 +823,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state) irqd_set_forwarded_to_vcpu(d); /* Set it to PQ=10 state to prevent further sends */ - pq = xive_poke_esb(xd, XIVE_ESB_SET_PQ_10); + pq = xive_esb_read(xd, XIVE_ESB_SET_PQ_10); /* No target ? nothing to do */ if (xd->target == XIVE_INVALID_TARGET) { @@ -832,7 +852,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state) * for sure the queue slot is no longer in use. */ if (pq & 2) { - pq = xive_poke_esb(xd, XIVE_ESB_SET_PQ_11); + pq = xive_esb_read(xd, XIVE_ESB_SET_PQ_11); xd->saved_p = true; /* @@ -989,6 +1009,9 @@ static void xive_ipi_eoi(struct irq_data *d) { struct xive_cpu *xc = __this_cpu_read(xive_cpu); + DBG_VERBOSE("IPI eoi: irq=%d [0x%lx] (HW IRQ 0x%x) pending=%02x\n", + d->irq, irqd_to_hwirq(d), xc->hw_ipi, xc->pending_prio); + /* Handle possible race with unplug and drop stale IPIs */ if (!xc) return; @@ -1368,6 +1391,27 @@ void xive_flush_interrupt(void) #endif /* CONFIG_SMP */ +void xive_teardown_cpu(void) +{ + struct xive_cpu *xc = __this_cpu_read(xive_cpu); + unsigned int cpu = smp_processor_id(); + + /* Set CPPR to 0 to disable flow of interrupts */ + xc->cppr = 0; + out_8(xive_tima + xive_tima_offset + TM_CPPR, 0); + + if (xive_ops->teardown_cpu) + xive_ops->teardown_cpu(cpu, xc); + +#ifdef CONFIG_SMP + /* Get rid of IPI */ + xive_cleanup_cpu_ipi(cpu, xc); +#endif + + /* Disable and free the queues */ + xive_cleanup_cpu_queues(cpu, xc); +} + void xive_kexec_teardown_cpu(int secondary) { struct xive_cpu *xc = __this_cpu_read(xive_cpu); @@ -1395,8 +1439,8 @@ void xive_shutdown(void) xive_ops->shutdown(); } -bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, - u8 max_prio) +bool __init xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, + u8 max_prio) { xive_tima = area; xive_tima_offset = offset; @@ -1424,6 +1468,22 @@ bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, return true; } +__be32 *xive_queue_page_alloc(unsigned int cpu, u32 queue_shift) +{ + unsigned int alloc_order; + struct page *pages; + __be32 *qpage; + + alloc_order = xive_alloc_order(queue_shift); + pages = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL, alloc_order); + if (!pages) + return ERR_PTR(-ENOMEM); + qpage = (__be32 *)page_address(pages); + memset(qpage, 0, 1 << queue_shift); + + return qpage; +} + static int __init xive_off(char *arg) { xive_cmdline_disabled = true; diff --git a/arch/powerpc/sysdev/xive/native.c b/arch/powerpc/sysdev/xive/native.c index 0f95476b01f6..ebc244b08d67 100644 --- a/arch/powerpc/sysdev/xive/native.c +++ b/arch/powerpc/sysdev/xive/native.c @@ -82,6 +82,8 @@ int xive_native_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) return -ENOMEM; } + data->hw_irq = hw_irq; + if (!data->trig_page) return 0; if (data->trig_page == data->eoi_page) { @@ -202,17 +204,12 @@ EXPORT_SYMBOL_GPL(xive_native_disable_queue); static int xive_native_setup_queue(unsigned int cpu, struct xive_cpu *xc, u8 prio) { struct xive_q *q = &xc->queue[prio]; - unsigned int alloc_order; - struct page *pages; __be32 *qpage; - alloc_order = (xive_queue_shift > PAGE_SHIFT) ? - (xive_queue_shift - PAGE_SHIFT) : 0; - pages = alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL, alloc_order); - if (!pages) - return -ENOMEM; - qpage = (__be32 *)page_address(pages); - memset(qpage, 0, 1 << xive_queue_shift); + qpage = xive_queue_page_alloc(cpu, xive_queue_shift); + if (IS_ERR(qpage)) + return PTR_ERR(qpage); + return xive_native_configure_queue(get_hard_smp_processor_id(cpu), q, prio, qpage, xive_queue_shift, false); } @@ -227,8 +224,7 @@ static void xive_native_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, u8 * from an IPI and iounmap isn't safe */ __xive_native_disable_queue(get_hard_smp_processor_id(cpu), q, prio); - alloc_order = (xive_queue_shift > PAGE_SHIFT) ? - (xive_queue_shift - PAGE_SHIFT) : 0; + alloc_order = xive_alloc_order(xive_queue_shift); free_pages((unsigned long)q->qpage, alloc_order); q->qpage = NULL; } @@ -515,13 +511,13 @@ static bool xive_parse_provisioning(struct device_node *np) static void xive_native_setup_pools(void) { /* Allocate a pool big enough */ - pr_debug("XIVE: Allocating VP block for pool size %d\n", nr_cpu_ids); + pr_debug("XIVE: Allocating VP block for pool size %u\n", nr_cpu_ids); xive_pool_vps = xive_native_alloc_vp_block(nr_cpu_ids); if (WARN_ON(xive_pool_vps == XIVE_INVALID_VP)) pr_err("XIVE: Failed to allocate pool VP, KVM might not function\n"); - pr_debug("XIVE: Pool VPs allocated at 0x%x for %d max CPUs\n", + pr_debug("XIVE: Pool VPs allocated at 0x%x for %u max CPUs\n", xive_pool_vps, nr_cpu_ids); } @@ -531,7 +527,7 @@ u32 xive_native_default_eq_shift(void) } EXPORT_SYMBOL_GPL(xive_native_default_eq_shift); -bool xive_native_init(void) +bool __init xive_native_init(void) { struct device_node *np; struct resource r; @@ -551,7 +547,7 @@ bool xive_native_init(void) pr_devel("not found !\n"); return false; } - pr_devel("Found %s\n", np->full_name); + pr_devel("Found %pOF\n", np); /* Resource 1 is HV window */ if (of_address_to_resource(np, 1, &r)) { diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c new file mode 100644 index 000000000000..d9c4c9366049 --- /dev/null +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -0,0 +1,666 @@ +/* + * Copyright 2016,2017 IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) "xive: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xive-internal.h" + +static u32 xive_queue_shift; + +struct xive_irq_bitmap { + unsigned long *bitmap; + unsigned int base; + unsigned int count; + spinlock_t lock; + struct list_head list; +}; + +static LIST_HEAD(xive_irq_bitmaps); + +static int xive_irq_bitmap_add(int base, int count) +{ + struct xive_irq_bitmap *xibm; + + xibm = kzalloc(sizeof(*xibm), GFP_ATOMIC); + if (!xibm) + return -ENOMEM; + + spin_lock_init(&xibm->lock); + xibm->base = base; + xibm->count = count; + xibm->bitmap = kzalloc(xibm->count, GFP_KERNEL); + list_add(&xibm->list, &xive_irq_bitmaps); + + pr_info("Using IRQ range [%x-%x]", xibm->base, + xibm->base + xibm->count - 1); + return 0; +} + +static int __xive_irq_bitmap_alloc(struct xive_irq_bitmap *xibm) +{ + int irq; + + irq = find_first_zero_bit(xibm->bitmap, xibm->count); + if (irq != xibm->count) { + set_bit(irq, xibm->bitmap); + irq += xibm->base; + } else { + irq = -ENOMEM; + } + + return irq; +} + +static int xive_irq_bitmap_alloc(void) +{ + struct xive_irq_bitmap *xibm; + unsigned long flags; + int irq = -ENOENT; + + list_for_each_entry(xibm, &xive_irq_bitmaps, list) { + spin_lock_irqsave(&xibm->lock, flags); + irq = __xive_irq_bitmap_alloc(xibm); + spin_unlock_irqrestore(&xibm->lock, flags); + if (irq >= 0) + break; + } + return irq; +} + +static void xive_irq_bitmap_free(int irq) +{ + unsigned long flags; + struct xive_irq_bitmap *xibm; + + list_for_each_entry(xibm, &xive_irq_bitmaps, list) { + if ((irq >= xibm->base) && (irq < xibm->base + xibm->count)) { + spin_lock_irqsave(&xibm->lock, flags); + clear_bit(irq - xibm->base, xibm->bitmap); + spin_unlock_irqrestore(&xibm->lock, flags); + break; + } + } +} + +static long plpar_int_get_source_info(unsigned long flags, + unsigned long lisn, + unsigned long *src_flags, + unsigned long *eoi_page, + unsigned long *trig_page, + unsigned long *esb_shift) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + long rc; + + rc = plpar_hcall(H_INT_GET_SOURCE_INFO, retbuf, flags, lisn); + if (rc) { + pr_err("H_INT_GET_SOURCE_INFO lisn=%ld failed %ld\n", lisn, rc); + return rc; + } + + *src_flags = retbuf[0]; + *eoi_page = retbuf[1]; + *trig_page = retbuf[2]; + *esb_shift = retbuf[3]; + + pr_devel("H_INT_GET_SOURCE_INFO flags=%lx eoi=%lx trig=%lx shift=%lx\n", + retbuf[0], retbuf[1], retbuf[2], retbuf[3]); + + return 0; +} + +#define XIVE_SRC_SET_EISN (1ull << (63 - 62)) +#define XIVE_SRC_MASK (1ull << (63 - 63)) /* unused */ + +static long plpar_int_set_source_config(unsigned long flags, + unsigned long lisn, + unsigned long target, + unsigned long prio, + unsigned long sw_irq) +{ + long rc; + + + pr_devel("H_INT_SET_SOURCE_CONFIG flags=%lx lisn=%lx target=%lx prio=%lx sw_irq=%lx\n", + flags, lisn, target, prio, sw_irq); + + + rc = plpar_hcall_norets(H_INT_SET_SOURCE_CONFIG, flags, lisn, + target, prio, sw_irq); + if (rc) { + pr_err("H_INT_SET_SOURCE_CONFIG lisn=%ld target=%lx prio=%lx failed %ld\n", + lisn, target, prio, rc); + return rc; + } + + return 0; +} + +static long plpar_int_get_queue_info(unsigned long flags, + unsigned long target, + unsigned long priority, + unsigned long *esn_page, + unsigned long *esn_size) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + long rc; + + rc = plpar_hcall(H_INT_GET_QUEUE_INFO, retbuf, flags, target, priority); + if (rc) { + pr_err("H_INT_GET_QUEUE_INFO cpu=%ld prio=%ld failed %ld\n", + target, priority, rc); + return rc; + } + + *esn_page = retbuf[0]; + *esn_size = retbuf[1]; + + pr_devel("H_INT_GET_QUEUE_INFO page=%lx size=%lx\n", + retbuf[0], retbuf[1]); + + return 0; +} + +#define XIVE_EQ_ALWAYS_NOTIFY (1ull << (63 - 63)) + +static long plpar_int_set_queue_config(unsigned long flags, + unsigned long target, + unsigned long priority, + unsigned long qpage, + unsigned long qsize) +{ + long rc; + + pr_devel("H_INT_SET_QUEUE_CONFIG flags=%lx target=%lx priority=%lx qpage=%lx qsize=%lx\n", + flags, target, priority, qpage, qsize); + + rc = plpar_hcall_norets(H_INT_SET_QUEUE_CONFIG, flags, target, + priority, qpage, qsize); + if (rc) { + pr_err("H_INT_SET_QUEUE_CONFIG cpu=%ld prio=%ld qpage=%lx returned %ld\n", + target, priority, qpage, rc); + return rc; + } + + return 0; +} + +static long plpar_int_sync(unsigned long flags, unsigned long lisn) +{ + long rc; + + rc = plpar_hcall_norets(H_INT_SYNC, flags, lisn); + if (rc) { + pr_err("H_INT_SYNC lisn=%ld returned %ld\n", lisn, rc); + return rc; + } + + return 0; +} + +#define XIVE_ESB_FLAG_STORE (1ull << (63 - 63)) + +static long plpar_int_esb(unsigned long flags, + unsigned long lisn, + unsigned long offset, + unsigned long in_data, + unsigned long *out_data) +{ + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + long rc; + + pr_devel("H_INT_ESB flags=%lx lisn=%lx offset=%lx in=%lx\n", + flags, lisn, offset, in_data); + + rc = plpar_hcall(H_INT_ESB, retbuf, flags, lisn, offset, in_data); + if (rc) { + pr_err("H_INT_ESB lisn=%ld offset=%ld returned %ld\n", + lisn, offset, rc); + return rc; + } + + *out_data = retbuf[0]; + + return 0; +} + +static u64 xive_spapr_esb_rw(u32 lisn, u32 offset, u64 data, bool write) +{ + unsigned long read_data; + long rc; + + rc = plpar_int_esb(write ? XIVE_ESB_FLAG_STORE : 0, + lisn, offset, data, &read_data); + if (rc) + return -1; + + return write ? 0 : read_data; +} + +#define XIVE_SRC_H_INT_ESB (1ull << (63 - 60)) +#define XIVE_SRC_LSI (1ull << (63 - 61)) +#define XIVE_SRC_TRIGGER (1ull << (63 - 62)) +#define XIVE_SRC_STORE_EOI (1ull << (63 - 63)) + +static int xive_spapr_populate_irq_data(u32 hw_irq, struct xive_irq_data *data) +{ + long rc; + unsigned long flags; + unsigned long eoi_page; + unsigned long trig_page; + unsigned long esb_shift; + + memset(data, 0, sizeof(*data)); + + rc = plpar_int_get_source_info(0, hw_irq, &flags, &eoi_page, &trig_page, + &esb_shift); + if (rc) + return -EINVAL; + + if (flags & XIVE_SRC_H_INT_ESB) + data->flags |= XIVE_IRQ_FLAG_H_INT_ESB; + if (flags & XIVE_SRC_STORE_EOI) + data->flags |= XIVE_IRQ_FLAG_STORE_EOI; + if (flags & XIVE_SRC_LSI) + data->flags |= XIVE_IRQ_FLAG_LSI; + data->eoi_page = eoi_page; + data->esb_shift = esb_shift; + data->trig_page = trig_page; + + /* + * No chip-id for the sPAPR backend. This has an impact how we + * pick a target. See xive_pick_irq_target(). + */ + data->src_chip = XIVE_INVALID_CHIP_ID; + + data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); + if (!data->eoi_mmio) { + pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); + return -ENOMEM; + } + + data->hw_irq = hw_irq; + + /* Full function page supports trigger */ + if (flags & XIVE_SRC_TRIGGER) { + data->trig_mmio = data->eoi_mmio; + return 0; + } + + data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift); + if (!data->trig_mmio) { + pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq); + return -ENOMEM; + } + return 0; +} + +static int xive_spapr_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq) +{ + long rc; + + rc = plpar_int_set_source_config(XIVE_SRC_SET_EISN, hw_irq, target, + prio, sw_irq); + + return rc == 0 ? 0 : -ENXIO; +} + +/* This can be called multiple time to change a queue configuration */ +static int xive_spapr_configure_queue(u32 target, struct xive_q *q, u8 prio, + __be32 *qpage, u32 order) +{ + s64 rc = 0; + unsigned long esn_page; + unsigned long esn_size; + u64 flags, qpage_phys; + + /* If there's an actual queue page, clean it */ + if (order) { + if (WARN_ON(!qpage)) + return -EINVAL; + qpage_phys = __pa(qpage); + } else { + qpage_phys = 0; + } + + /* Initialize the rest of the fields */ + q->msk = order ? ((1u << (order - 2)) - 1) : 0; + q->idx = 0; + q->toggle = 0; + + rc = plpar_int_get_queue_info(0, target, prio, &esn_page, &esn_size); + if (rc) { + pr_err("Error %lld getting queue info prio %d\n", rc, prio); + rc = -EIO; + goto fail; + } + + /* TODO: add support for the notification page */ + q->eoi_phys = esn_page; + + /* Default is to always notify */ + flags = XIVE_EQ_ALWAYS_NOTIFY; + + /* Configure and enable the queue in HW */ + rc = plpar_int_set_queue_config(flags, target, prio, qpage_phys, order); + if (rc) { + pr_err("Error %lld setting queue for prio %d\n", rc, prio); + rc = -EIO; + } else { + q->qpage = qpage; + } +fail: + return rc; +} + +static int xive_spapr_setup_queue(unsigned int cpu, struct xive_cpu *xc, + u8 prio) +{ + struct xive_q *q = &xc->queue[prio]; + __be32 *qpage; + + qpage = xive_queue_page_alloc(cpu, xive_queue_shift); + if (IS_ERR(qpage)) + return PTR_ERR(qpage); + + return xive_spapr_configure_queue(cpu, q, prio, qpage, + xive_queue_shift); +} + +static void xive_spapr_cleanup_queue(unsigned int cpu, struct xive_cpu *xc, + u8 prio) +{ + struct xive_q *q = &xc->queue[prio]; + unsigned int alloc_order; + long rc; + + rc = plpar_int_set_queue_config(0, cpu, prio, 0, 0); + if (rc) + pr_err("Error %ld setting queue for prio %d\n", rc, prio); + + alloc_order = xive_alloc_order(xive_queue_shift); + free_pages((unsigned long)q->qpage, alloc_order); + q->qpage = NULL; +} + +static bool xive_spapr_match(struct device_node *node) +{ + /* Ignore cascaded controllers for the moment */ + return 1; +} + +#ifdef CONFIG_SMP +static int xive_spapr_get_ipi(unsigned int cpu, struct xive_cpu *xc) +{ + int irq = xive_irq_bitmap_alloc(); + + if (irq < 0) { + pr_err("Failed to allocate IPI on CPU %d\n", cpu); + return -ENXIO; + } + + xc->hw_ipi = irq; + return 0; +} + +static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc) +{ + if (!xc->hw_ipi) + return; + + xive_irq_bitmap_free(xc->hw_ipi); + xc->hw_ipi = 0; +} +#endif /* CONFIG_SMP */ + +static void xive_spapr_shutdown(void) +{ + long rc; + + rc = plpar_hcall_norets(H_INT_RESET, 0); + if (rc) + pr_err("H_INT_RESET failed %ld\n", rc); +} + +/* + * Perform an "ack" cycle on the current thread. Grab the pending + * active priorities and update the CPPR to the most favored one. + */ +static void xive_spapr_update_pending(struct xive_cpu *xc) +{ + u8 nsr, cppr; + u16 ack; + + /* + * Perform the "Acknowledge O/S to Register" cycle. + * + * Let's speedup the access to the TIMA using the raw I/O + * accessor as we don't need the synchronisation routine of + * the higher level ones + */ + ack = be16_to_cpu(__raw_readw(xive_tima + TM_SPC_ACK_OS_REG)); + + /* Synchronize subsequent queue accesses */ + mb(); + + /* + * Grab the CPPR and the "NSR" field which indicates the source + * of the interrupt (if any) + */ + cppr = ack & 0xff; + nsr = ack >> 8; + + if (nsr & TM_QW1_NSR_EO) { + if (cppr == 0xff) + return; + /* Mark the priority pending */ + xc->pending_prio |= 1 << cppr; + + /* + * A new interrupt should never have a CPPR less favored + * than our current one. + */ + if (cppr >= xc->cppr) + pr_err("CPU %d odd ack CPPR, got %d at %d\n", + smp_processor_id(), cppr, xc->cppr); + + /* Update our idea of what the CPPR is */ + xc->cppr = cppr; + } +} + +static void xive_spapr_eoi(u32 hw_irq) +{ + /* Not used */; +} + +static void xive_spapr_setup_cpu(unsigned int cpu, struct xive_cpu *xc) +{ + /* Only some debug on the TIMA settings */ + pr_debug("(HW value: %08x %08x %08x)\n", + in_be32(xive_tima + TM_QW1_OS + TM_WORD0), + in_be32(xive_tima + TM_QW1_OS + TM_WORD1), + in_be32(xive_tima + TM_QW1_OS + TM_WORD2)); +} + +static void xive_spapr_teardown_cpu(unsigned int cpu, struct xive_cpu *xc) +{ + /* Nothing to do */; +} + +static void xive_spapr_sync_source(u32 hw_irq) +{ + /* Specs are unclear on what this is doing */ + plpar_int_sync(0, hw_irq); +} + +static const struct xive_ops xive_spapr_ops = { + .populate_irq_data = xive_spapr_populate_irq_data, + .configure_irq = xive_spapr_configure_irq, + .setup_queue = xive_spapr_setup_queue, + .cleanup_queue = xive_spapr_cleanup_queue, + .match = xive_spapr_match, + .shutdown = xive_spapr_shutdown, + .update_pending = xive_spapr_update_pending, + .eoi = xive_spapr_eoi, + .setup_cpu = xive_spapr_setup_cpu, + .teardown_cpu = xive_spapr_teardown_cpu, + .sync_source = xive_spapr_sync_source, + .esb_rw = xive_spapr_esb_rw, +#ifdef CONFIG_SMP + .get_ipi = xive_spapr_get_ipi, + .put_ipi = xive_spapr_put_ipi, +#endif /* CONFIG_SMP */ + .name = "spapr", +}; + +/* + * get max priority from "/ibm,plat-res-int-priorities" + */ +static bool xive_get_max_prio(u8 *max_prio) +{ + struct device_node *rootdn; + const __be32 *reg; + u32 len; + int prio, found; + + rootdn = of_find_node_by_path("/"); + if (!rootdn) { + pr_err("not root node found !\n"); + return false; + } + + reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len); + if (!reg) { + pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n"); + return false; + } + + if (len % (2 * sizeof(u32)) != 0) { + pr_err("invalid 'ibm,plat-res-int-priorities' property\n"); + return false; + } + + /* HW supports priorities in the range [0-7] and 0xFF is a + * wildcard priority used to mask. We scan the ranges reserved + * by the hypervisor to find the lowest priority we can use. + */ + found = 0xFF; + for (prio = 0; prio < 8; prio++) { + int reserved = 0; + int i; + + for (i = 0; i < len / (2 * sizeof(u32)); i++) { + int base = be32_to_cpu(reg[2 * i]); + int range = be32_to_cpu(reg[2 * i + 1]); + + if (prio >= base && prio < base + range) + reserved++; + } + + if (!reserved) + found = prio; + } + + if (found == 0xFF) { + pr_err("no valid priority found in 'ibm,plat-res-int-priorities'\n"); + return false; + } + + *max_prio = found; + return true; +} + +bool __init xive_spapr_init(void) +{ + struct device_node *np; + struct resource r; + void __iomem *tima; + struct property *prop; + u8 max_prio; + u32 val; + u32 len; + const __be32 *reg; + int i; + + if (xive_cmdline_disabled) + return false; + + pr_devel("%s()\n", __func__); + np = of_find_compatible_node(NULL, NULL, "ibm,power-ivpe"); + if (!np) { + pr_devel("not found !\n"); + return false; + } + pr_devel("Found %s\n", np->full_name); + + /* Resource 1 is the OS ring TIMA */ + if (of_address_to_resource(np, 1, &r)) { + pr_err("Failed to get thread mgmnt area resource\n"); + return false; + } + tima = ioremap(r.start, resource_size(&r)); + if (!tima) { + pr_err("Failed to map thread mgmnt area\n"); + return false; + } + + if (!xive_get_max_prio(&max_prio)) + return false; + + /* Feed the IRQ number allocator with the ranges given in the DT */ + reg = of_get_property(np, "ibm,xive-lisn-ranges", &len); + if (!reg) { + pr_err("Failed to read 'ibm,xive-lisn-ranges' property\n"); + return false; + } + + if (len % (2 * sizeof(u32)) != 0) { + pr_err("invalid 'ibm,xive-lisn-ranges' property\n"); + return false; + } + + for (i = 0; i < len / (2 * sizeof(u32)); i++, reg += 2) + xive_irq_bitmap_add(be32_to_cpu(reg[0]), + be32_to_cpu(reg[1])); + + /* Iterate the EQ sizes and pick one */ + of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) { + xive_queue_shift = val; + if (val == PAGE_SHIFT) + break; + } + + /* Initialize XIVE core with our backend */ + if (!xive_core_init(&xive_spapr_ops, tima, TM_QW1_OS, max_prio)) + return false; + + pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); + return true; +} diff --git a/arch/powerpc/sysdev/xive/xive-internal.h b/arch/powerpc/sysdev/xive/xive-internal.h index d07ef2d29caf..f34abed0c05f 100644 --- a/arch/powerpc/sysdev/xive/xive-internal.h +++ b/arch/powerpc/sysdev/xive/xive-internal.h @@ -47,6 +47,7 @@ struct xive_ops { void (*update_pending)(struct xive_cpu *xc); void (*eoi)(u32 hw_irq); void (*sync_source)(u32 hw_irq); + u64 (*esb_rw)(u32 hw_irq, u32 offset, u64 data, bool write); #ifdef CONFIG_SMP int (*get_ipi)(unsigned int cpu, struct xive_cpu *xc); void (*put_ipi)(unsigned int cpu, struct xive_cpu *xc); @@ -56,6 +57,12 @@ struct xive_ops { bool xive_core_init(const struct xive_ops *ops, void __iomem *area, u32 offset, u8 max_prio); +__be32 *xive_queue_page_alloc(unsigned int cpu, u32 queue_shift); + +static inline u32 xive_alloc_order(u32 queue_shift) +{ + return (queue_shift > PAGE_SHIFT) ? (queue_shift - PAGE_SHIFT) : 0; +} extern bool xive_cmdline_disabled; diff --git a/arch/powerpc/tools/gcc-check-mprofile-kernel.sh b/arch/powerpc/tools/gcc-check-mprofile-kernel.sh index c658d8cf760b..061f8035bdbe 100755 --- a/arch/powerpc/tools/gcc-check-mprofile-kernel.sh +++ b/arch/powerpc/tools/gcc-check-mprofile-kernel.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 set -e set -o pipefail diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 0b2f771593eb..1bc3abb237cd 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for xmon subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror @@ -5,6 +6,10 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror GCOV_PROFILE := n UBSAN_SANITIZE := n +# Disable ftrace for the entire directory +ORIG_CFLAGS := $(KBUILD_CFLAGS) +KBUILD_CFLAGS = $(subst -mno-sched-epilog,,$(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS))) + ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) obj-y += xmon.o nonstdio.o spr_access.o diff --git a/arch/powerpc/xmon/nonstdio.h b/arch/powerpc/xmon/nonstdio.h index f8653365667e..2202ec61972c 100644 --- a/arch/powerpc/xmon/nonstdio.h +++ b/arch/powerpc/xmon/nonstdio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define EOF (-1) #define printf xmon_printf diff --git a/arch/powerpc/xmon/spr_access.S b/arch/powerpc/xmon/spr_access.S index 7d8b0e8ed6d9..4099cbcddaaa 100644 --- a/arch/powerpc/xmon/spr_access.S +++ b/arch/powerpc/xmon/spr_access.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* unsigned long xmon_mfspr(sprn, default_value) */ diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 08e367e3e8c3..33351c6704b1 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -89,6 +89,7 @@ static unsigned long nidump = 16; static unsigned long ncsum = 4096; static int termch; static char tmpstr[128]; +static int tracing_enabled; static long bus_error_jmp[JMP_BUF_LEN]; static int catch_memory_errors; @@ -234,6 +235,7 @@ Commands:\n\ "\ dr dump stream of raw bytes\n\ dt dump the tracing buffers (uses printk)\n\ + dtc dump the tracing buffers for current CPU (uses printk)\n\ " #ifdef CONFIG_PPC_POWERNV " dx# dump xive on CPU #\n\ @@ -461,6 +463,9 @@ static int xmon_core(struct pt_regs *regs, int fromipi) local_irq_save(flags); hard_irq_disable(); + tracing_enabled = tracing_is_on(); + tracing_off(); + bp = in_breakpoint_table(regs->nip, &offset); if (bp != NULL) { regs->nip = bp->address + offset; @@ -981,6 +986,8 @@ cmds(struct pt_regs *excp) break; case 'x': case 'X': + if (tracing_enabled) + tracing_on(); return cmd; case EOF: printf(" \n"); @@ -1732,23 +1739,25 @@ static void dump_206_sprs(void) /* Actually some of these pre-date 2.06, but whatevs */ - printf("srr0 = %.16x srr1 = %.16x dsisr = %.8x\n", + printf("srr0 = %.16lx srr1 = %.16lx dsisr = %.8x\n", mfspr(SPRN_SRR0), mfspr(SPRN_SRR1), mfspr(SPRN_DSISR)); - printf("dscr = %.16x ppr = %.16x pir = %.8x\n", + printf("dscr = %.16lx ppr = %.16lx pir = %.8x\n", mfspr(SPRN_DSCR), mfspr(SPRN_PPR), mfspr(SPRN_PIR)); + printf("amr = %.16lx uamor = %.16lx\n", + mfspr(SPRN_AMR), mfspr(SPRN_UAMOR)); if (!(mfmsr() & MSR_HV)) return; - printf("sdr1 = %.16x hdar = %.16x hdsisr = %.8x\n", + printf("sdr1 = %.16lx hdar = %.16lx hdsisr = %.8x\n", mfspr(SPRN_SDR1), mfspr(SPRN_HDAR), mfspr(SPRN_HDSISR)); - printf("hsrr0 = %.16x hsrr1 = %.16x hdec = %.8x\n", + printf("hsrr0 = %.16lx hsrr1 = %.16lx hdec = %.16lx\n", mfspr(SPRN_HSRR0), mfspr(SPRN_HSRR1), mfspr(SPRN_HDEC)); - printf("lpcr = %.16x pcr = %.16x lpidr = %.8x\n", + printf("lpcr = %.16lx pcr = %.16lx lpidr = %.8x\n", mfspr(SPRN_LPCR), mfspr(SPRN_PCR), mfspr(SPRN_LPID)); - printf("hsprg0 = %.16x hsprg1 = %.16x\n", - mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1)); - printf("dabr = %.16x dabrx = %.16x\n", + printf("hsprg0 = %.16lx hsprg1 = %.16lx amor = %.16lx\n", + mfspr(SPRN_HSPRG0), mfspr(SPRN_HSPRG1), mfspr(SPRN_AMOR)); + printf("dabr = %.16lx dabrx = %.16lx\n", mfspr(SPRN_DABR), mfspr(SPRN_DABRX)); #endif } @@ -1761,42 +1770,65 @@ static void dump_207_sprs(void) if (!cpu_has_feature(CPU_FTR_ARCH_207S)) return; - printf("dpdes = %.16x tir = %.16x cir = %.8x\n", + printf("dpdes = %.16lx tir = %.16lx cir = %.8x\n", mfspr(SPRN_DPDES), mfspr(SPRN_TIR), mfspr(SPRN_CIR)); - printf("fscr = %.16x tar = %.16x pspb = %.8x\n", + printf("fscr = %.16lx tar = %.16lx pspb = %.8x\n", mfspr(SPRN_FSCR), mfspr(SPRN_TAR), mfspr(SPRN_PSPB)); msr = mfmsr(); if (msr & MSR_TM) { /* Only if TM has been enabled in the kernel */ - printf("tfhar = %.16x tfiar = %.16x texasr = %.16x\n", + printf("tfhar = %.16lx tfiar = %.16lx texasr = %.16lx\n", mfspr(SPRN_TFHAR), mfspr(SPRN_TFIAR), mfspr(SPRN_TEXASR)); } - printf("mmcr0 = %.16x mmcr1 = %.16x mmcr2 = %.16x\n", + printf("mmcr0 = %.16lx mmcr1 = %.16lx mmcr2 = %.16lx\n", mfspr(SPRN_MMCR0), mfspr(SPRN_MMCR1), mfspr(SPRN_MMCR2)); printf("pmc1 = %.8x pmc2 = %.8x pmc3 = %.8x pmc4 = %.8x\n", mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), mfspr(SPRN_PMC3), mfspr(SPRN_PMC4)); - printf("mmcra = %.16x siar = %.16x pmc5 = %.8x\n", + printf("mmcra = %.16lx siar = %.16lx pmc5 = %.8x\n", mfspr(SPRN_MMCRA), mfspr(SPRN_SIAR), mfspr(SPRN_PMC5)); - printf("sdar = %.16x sier = %.16x pmc6 = %.8x\n", + printf("sdar = %.16lx sier = %.16lx pmc6 = %.8x\n", mfspr(SPRN_SDAR), mfspr(SPRN_SIER), mfspr(SPRN_PMC6)); - printf("ebbhr = %.16x ebbrr = %.16x bescr = %.16x\n", + printf("ebbhr = %.16lx ebbrr = %.16lx bescr = %.16lx\n", mfspr(SPRN_EBBHR), mfspr(SPRN_EBBRR), mfspr(SPRN_BESCR)); + printf("iamr = %.16lx\n", mfspr(SPRN_IAMR)); if (!(msr & MSR_HV)) return; - printf("hfscr = %.16x dhdes = %.16x rpr = %.16x\n", + printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n", mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR)); - printf("dawr = %.16x dawrx = %.16x ciabr = %.16x\n", + printf("dawr = %.16lx dawrx = %.16lx ciabr = %.16lx\n", mfspr(SPRN_DAWR), mfspr(SPRN_DAWRX), mfspr(SPRN_CIABR)); #endif } +static void dump_300_sprs(void) +{ +#ifdef CONFIG_PPC64 + bool hv = mfmsr() & MSR_HV; + + if (!cpu_has_feature(CPU_FTR_ARCH_300)) + return; + + printf("pidr = %.16lx tidr = %.16lx\n", + mfspr(SPRN_PID), mfspr(SPRN_TIDR)); + printf("asdr = %.16lx psscr = %.16lx\n", + mfspr(SPRN_ASDR), hv ? mfspr(SPRN_PSSCR) + : mfspr(SPRN_PSSCR_PR)); + + if (!hv) + return; + + printf("ptcr = %.16lx\n", + mfspr(SPRN_PTCR)); +#endif +} + static void dump_one_spr(int spr, bool show_unimplemented) { unsigned long val; @@ -1850,6 +1882,7 @@ static void super_regs(void) dump_206_sprs(); dump_207_sprs(); + dump_300_sprs(); return; } @@ -2231,6 +2264,17 @@ static void xmon_rawdump (unsigned long adrs, long ndump) printf("\n"); } +static void dump_tracing(void) +{ + int c; + + c = inchar(); + if (c == 'c') + ftrace_dump(DUMP_ORIG); + else + ftrace_dump(DUMP_ALL); +} + #ifdef CONFIG_PPC64 static void dump_one_paca(int cpu) { @@ -2507,6 +2551,11 @@ dump(void) } #endif + if (c == 't') { + dump_tracing(); + return; + } + if (c == '\n') termch = c; @@ -2525,9 +2574,6 @@ dump(void) dump_log_buf(); } else if (c == 'o') { dump_opal_msglog(); - } else if (c == 't') { - ftrace_dump(DUMP_ALL); - tracing_on(); } else if (c == 'r') { scanhex(&ndump); if (ndump == 0) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 7eeb75d758c1..ae55e715cc74 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config MMU def_bool y @@ -222,6 +223,10 @@ config HAVE_MARCH_Z13_FEATURES def_bool n select HAVE_MARCH_ZEC12_FEATURES +config HAVE_MARCH_Z14_FEATURES + def_bool n + select HAVE_MARCH_Z13_FEATURES + choice prompt "Processor type" default MARCH_Z196 @@ -282,6 +287,14 @@ config MARCH_Z13 2964 series). The kernel will be slightly faster but will not work on older machines. +config MARCH_Z14 + bool "IBM z14" + select HAVE_MARCH_Z14_FEATURES + help + Select this to enable optimizations for IBM z14 (3906 series). + The kernel will be slightly faster but will not work on older + machines. + endchoice config MARCH_Z900_TUNE @@ -305,6 +318,9 @@ config MARCH_ZEC12_TUNE config MARCH_Z13_TUNE def_bool TUNE_Z13 || MARCH_Z13 && TUNE_DEFAULT +config MARCH_Z14_TUNE + def_bool TUNE_Z14 || MARCH_Z14 && TUNE_DEFAULT + choice prompt "Tune code generation" default TUNE_DEFAULT @@ -343,6 +359,9 @@ config TUNE_ZEC12 config TUNE_Z13 bool "IBM z13" +config TUNE_Z14 + bool "IBM z14" + endchoice config 64BIT diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug index ba5f878a295c..2cfdfbf8d320 100644 --- a/arch/s390/Kconfig.debug +++ b/arch/s390/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 54e00526b8df..dac821cfcd43 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -31,7 +31,8 @@ mflags-$(CONFIG_MARCH_Z9_109) := -march=z9-109 mflags-$(CONFIG_MARCH_Z10) := -march=z10 mflags-$(CONFIG_MARCH_Z196) := -march=z196 mflags-$(CONFIG_MARCH_ZEC12) := -march=zEC12 -mflags-$(CONFIG_MARCH_Z13) := -march=z13 +mflags-$(CONFIG_MARCH_Z13) := -march=z13 +mflags-$(CONFIG_MARCH_Z14) := -march=z14 export CC_FLAGS_MARCH := $(mflags-y) @@ -44,7 +45,8 @@ cflags-$(CONFIG_MARCH_Z9_109_TUNE) += -mtune=z9-109 cflags-$(CONFIG_MARCH_Z10_TUNE) += -mtune=z10 cflags-$(CONFIG_MARCH_Z196_TUNE) += -mtune=z196 cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12 -cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 +cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 +cflags-$(CONFIG_MARCH_Z14_TUNE) += -mtune=z14 cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include diff --git a/arch/s390/appldata/appldata.h b/arch/s390/appldata/appldata.h index 4a67f2b5f6aa..10346d2f3d4f 100644 --- a/arch/s390/appldata/appldata.h +++ b/arch/s390/appldata/appldata.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions and interface for Linux - z/VM Monitor Stream. * diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index 9a42ecec5647..da9dad35c28e 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux s390-specific parts of the memory manager. # diff --git a/arch/s390/boot/compressed/Makefile b/arch/s390/boot/compressed/Makefile index f7e4c834ea24..3df10c989893 100644 --- a/arch/s390/boot/compressed/Makefile +++ b/arch/s390/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/s390/boot/compressed/Makefile # diff --git a/arch/s390/boot/compressed/head.S b/arch/s390/boot/compressed/head.S index 11f6254c561e..231d1491d431 100644 --- a/arch/s390/boot/compressed/head.S +++ b/arch/s390/boot/compressed/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Startup glue code to uncompress the kernel * diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c index 33ca29333e18..77633200f42c 100644 --- a/arch/s390/boot/compressed/misc.c +++ b/arch/s390/boot/compressed/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Definitions and wrapper functions for kernel decompressor * diff --git a/arch/s390/boot/compressed/vmlinux.lds.S b/arch/s390/boot/compressed/vmlinux.lds.S index 747735f83426..88e46d4a7784 100644 --- a/arch/s390/boot/compressed/vmlinux.lds.S +++ b/arch/s390/boot/compressed/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index afa46a7406ea..04e042edbab7 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig @@ -27,6 +27,7 @@ CONFIG_NET=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_BLK_DEV_RAM=y # CONFIG_BLK_DEV_XPRAM is not set # CONFIG_DCSSBLK is not set # CONFIG_DASD is not set @@ -59,6 +60,7 @@ CONFIG_CONFIGFS_FS=y # CONFIG_NETWORK_FILESYSTEMS is not set CONFIG_PRINTK_TIME=y CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y CONFIG_PANIC_ON_OOPS=y # CONFIG_SCHED_DEBUG is not set diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile index ad4bd777768d..a51010ea62fa 100644 --- a/arch/s390/crypto/Makefile +++ b/arch/s390/crypto/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Cryptographic API # diff --git a/arch/s390/crypto/crc32be-vx.S b/arch/s390/crypto/crc32be-vx.S index 8013989cd2e5..e8077f0971f8 100644 --- a/arch/s390/crypto/crc32be-vx.S +++ b/arch/s390/crypto/crc32be-vx.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Hardware-accelerated CRC-32 variants for Linux on z Systems * diff --git a/arch/s390/crypto/crc32le-vx.S b/arch/s390/crypto/crc32le-vx.S index 17f2504c2633..d8c67a58c0c5 100644 --- a/arch/s390/crypto/crc32le-vx.S +++ b/arch/s390/crypto/crc32le-vx.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Hardware-accelerated CRC-32 variants for Linux on z Systems * diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index eecde500ed49..52348e0a812e 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Hypervisor filesystem for Linux on s390. * diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 752f6df3e697..b9bdf5c1918e 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Hypervisor filesystem for Linux on s390 - debugfs interface * diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 794bebb43d23..be8cc53204b5 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Hypervisor filesystem for Linux on s390. Diag 204 and 224 * implementation. diff --git a/arch/s390/hypfs/hypfs_diag0c.c b/arch/s390/hypfs/hypfs_diag0c.c index 0f1927cbba31..dce87f1bec94 100644 --- a/arch/s390/hypfs/hypfs_diag0c.c +++ b/arch/s390/hypfs/hypfs_diag0c.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Hypervisor filesystem for Linux on s390 * diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c index c9e5c72f78bd..ae0ed8dd5f1b 100644 --- a/arch/s390/hypfs/hypfs_sprp.c +++ b/arch/s390/hypfs/hypfs_sprp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Hypervisor filesystem for Linux on s390. * Set Partition-Resource Parameter interface. diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c index 012919d9833b..c4b7b681e055 100644 --- a/arch/s390/hypfs/hypfs_vm.c +++ b/arch/s390/hypfs/hypfs_vm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Hypervisor filesystem for Linux on s390. z/VM implementation. * diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index b3c88479feba..6e2c9f7e47fa 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -16,4 +16,5 @@ generic-y += mcs_spinlock.h generic-y += mm-arch-hooks.h generic-y += preempt.h generic-y += trace_clock.h +generic-y += unaligned.h generic-y += word-at-a-time.h diff --git a/arch/s390/include/asm/airq.h b/arch/s390/include/asm/airq.h index bd93ff6661b8..fcf539efb32f 100644 --- a/arch/s390/include/asm/airq.h +++ b/arch/s390/include/asm/airq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2002, 2007 * Author(s): Ingo Adlung diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h new file mode 100644 index 000000000000..c02f4aba88a6 --- /dev/null +++ b/arch/s390/include/asm/ap.h @@ -0,0 +1,126 @@ +/* + * Adjunct processor (AP) interfaces + * + * Copyright IBM Corp. 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Tony Krowiak + * Martin Schwidefsky + * Harald Freudenberger + */ + +#ifndef _ASM_S390_AP_H_ +#define _ASM_S390_AP_H_ + +/** + * The ap_qid_t identifier of an ap queue. + * If the AP facilities test (APFT) facility is available, + * card and queue index are 8 bit values, otherwise + * card index is 6 bit and queue index a 4 bit value. + */ +typedef unsigned int ap_qid_t; + +#define AP_MKQID(_card, _queue) (((_card) & 63) << 8 | ((_queue) & 255)) +#define AP_QID_CARD(_qid) (((_qid) >> 8) & 63) +#define AP_QID_QUEUE(_qid) ((_qid) & 255) + +/** + * struct ap_queue_status - Holds the AP queue status. + * @queue_empty: Shows if queue is empty + * @replies_waiting: Waiting replies + * @queue_full: Is 1 if the queue is full + * @irq_enabled: Shows if interrupts are enabled for the AP + * @response_code: Holds the 8 bit response code + * + * The ap queue status word is returned by all three AP functions + * (PQAP, NQAP and DQAP). There's a set of flags in the first + * byte, followed by a 1 byte response code. + */ +struct ap_queue_status { + unsigned int queue_empty : 1; + unsigned int replies_waiting : 1; + unsigned int queue_full : 1; + unsigned int _pad1 : 4; + unsigned int irq_enabled : 1; + unsigned int response_code : 8; + unsigned int _pad2 : 16; +}; + +/** + * ap_test_queue(): Test adjunct processor queue. + * @qid: The AP queue number + * @tbit: Test facilities bit + * @info: Pointer to queue descriptor + * + * Returns AP queue status structure. + */ +struct ap_queue_status ap_test_queue(ap_qid_t qid, + int tbit, + unsigned long *info); + +struct ap_config_info { + unsigned int apsc : 1; /* S bit */ + unsigned int apxa : 1; /* N bit */ + unsigned int qact : 1; /* C bit */ + unsigned int rc8a : 1; /* R bit */ + unsigned char _reserved1 : 4; + unsigned char _reserved2[3]; + unsigned char Na; /* max # of APs - 1 */ + unsigned char Nd; /* max # of Domains - 1 */ + unsigned char _reserved3[10]; + unsigned int apm[8]; /* AP ID mask */ + unsigned int aqm[8]; /* AP queue mask */ + unsigned int adm[8]; /* AP domain mask */ + unsigned char _reserved4[16]; +} __aligned(8); + +/* + * ap_query_configuration(): Fetch cryptographic config info + * + * Returns the ap configuration info fetched via PQAP(QCI). + * On success 0 is returned, on failure a negative errno + * is returned, e.g. if the PQAP(QCI) instruction is not + * available, the return value will be -EOPNOTSUPP. + */ +int ap_query_configuration(struct ap_config_info *info); + +/* + * struct ap_qirq_ctrl - convenient struct for easy invocation + * of the ap_queue_irq_ctrl() function. This struct is passed + * as GR1 parameter to the PQAP(AQIC) instruction. For details + * please see the AR documentation. + */ +struct ap_qirq_ctrl { + unsigned int _res1 : 8; + unsigned int zone : 8; /* zone info */ + unsigned int ir : 1; /* ir flag: enable (1) or disable (0) irq */ + unsigned int _res2 : 4; + unsigned int gisc : 3; /* guest isc field */ + unsigned int _res3 : 6; + unsigned int gf : 2; /* gisa format */ + unsigned int _res4 : 1; + unsigned int gisa : 27; /* gisa origin */ + unsigned int _res5 : 1; + unsigned int isc : 3; /* irq sub class */ +}; + +/** + * ap_queue_irq_ctrl(): Control interruption on a AP queue. + * @qid: The AP queue number + * @qirqctrl: struct ap_qirq_ctrl, see above + * @ind: The notification indicator byte + * + * Returns AP queue status. + * + * Control interruption on the given AP queue. + * Just a simple wrapper function for the low level PQAP(AQIC) + * instruction available for other kernel modules. + */ +struct ap_queue_status ap_queue_irq_ctrl(ap_qid_t qid, + struct ap_qirq_ctrl qirqctrl, + void *ind); + +#endif /* _ASM_S390_AP_H_ */ diff --git a/arch/s390/include/asm/appldata.h b/arch/s390/include/asm/appldata.h index a6263d4e8e56..4afbb5938726 100644 --- a/arch/s390/include/asm/appldata.h +++ b/arch/s390/include/asm/appldata.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2006 * diff --git a/arch/s390/include/asm/archrandom.h b/arch/s390/include/asm/archrandom.h index 6033901a40b2..e9f7d7a57f99 100644 --- a/arch/s390/include/asm/archrandom.h +++ b/arch/s390/include/asm/archrandom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Kernel interface for the s390 arch_random_* functions * diff --git a/arch/s390/include/asm/asm-prototypes.h b/arch/s390/include/asm/asm-prototypes.h index 2c3413b0ca52..c37eb921bfbf 100644 --- a/arch/s390/include/asm/asm-prototypes.h +++ b/arch/s390/include/asm/asm-prototypes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_PROTOTYPES_H #include diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index f7f69dfd2db2..4b55532f15c4 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2016 * Author(s): Martin Schwidefsky , diff --git a/arch/s390/include/asm/atomic_ops.h b/arch/s390/include/asm/atomic_ops.h index ba6d29412344..f479e4c0b87e 100644 --- a/arch/s390/include/asm/atomic_ops.h +++ b/arch/s390/include/asm/atomic_ops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Low level function for atomic operations * diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h index 5c8db3ce61c8..10432607a573 100644 --- a/arch/s390/include/asm/barrier.h +++ b/arch/s390/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2009 * diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 99902b7b9f0c..31e400c1a1f3 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999,2013 * diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h index ce9cc123988b..429f43a8a8e8 100644 --- a/arch/s390/include/asm/bug.h +++ b/arch/s390/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_BUG_H #define _ASM_S390_BUG_H diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h index 05219a5e0b2f..d5e22e837416 100644 --- a/arch/s390/include/asm/cache.h +++ b/arch/s390/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index b80e456d6428..633f8da86137 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2002, 2009 * diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index 057ce0ca6377..b00777ce93b4 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef S390_CCWGROUP_H #define S390_CCWGROUP_H diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index 12bf4fef2a68..91e376b0d28c 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 fast network checksum routines * diff --git a/arch/s390/include/asm/chpid.h b/arch/s390/include/asm/chpid.h index 7298eec98541..4773f747915c 100644 --- a/arch/s390/include/asm/chpid.h +++ b/arch/s390/include/asm/chpid.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2007, 2012 * Author(s): Peter Oberparleiter diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 7a38ca85190b..dc84a0171bb3 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Common interface for I/O on S/390 */ diff --git a/arch/s390/include/asm/clp.h b/arch/s390/include/asm/clp.h index 5687d62fb0cb..3925b0f085b7 100644 --- a/arch/s390/include/asm/clp.h +++ b/arch/s390/include/asm/clp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_CLP_H #define _ASM_S390_CLP_H diff --git a/arch/s390/include/asm/cmb.h b/arch/s390/include/asm/cmb.h index ed2630c23f90..599594c3720f 100644 --- a/arch/s390/include/asm/cmb.h +++ b/arch/s390/include/asm/cmb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef S390_CMB_H #define S390_CMB_H diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h index 24ea6948e32b..af99c1f66f12 100644 --- a/arch/s390/include/asm/cmpxchg.h +++ b/arch/s390/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2011 * diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index b9300f8aee10..1b60eb3676d5 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390X_COMPAT_H #define _ASM_S390X_COMPAT_H /* @@ -8,11 +9,12 @@ #include #include -#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p(typeof(0?(t)0:0ULL), u64)) +#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \ + typeof(0?(__force t)0:0ULL), u64)) #define __SC_DELOUSE(t,v) ({ \ BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \ - (t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ + (__force t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \ }) #define PSW32_MASK_PER 0x40000000UL diff --git a/arch/s390/include/asm/cpacf.h b/arch/s390/include/asm/cpacf.h index e06f2556b316..056670ebba67 100644 --- a/arch/s390/include/asm/cpacf.h +++ b/arch/s390/include/asm/cpacf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * CP Assist for Cryptographic Functions (CPACF) * diff --git a/arch/s390/include/asm/cpcmd.h b/arch/s390/include/asm/cpcmd.h index 3dfadb5d648f..c3c993abe964 100644 --- a/arch/s390/include/asm/cpcmd.h +++ b/arch/s390/include/asm/cpcmd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 @@ -10,9 +11,8 @@ /* * the lowlevel function for cpcmd - * the caller of __cpcmd has to ensure that the response buffer is below 2 GB */ -extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); +int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); /* * cpcmd is the in-kernel interface for issuing CP commands @@ -25,8 +25,8 @@ extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code * response_code: return pointer for VM's error code * return value: the size of the response. The caller can check if the buffer * was large enough by comparing the return value and rlen - * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep + * NOTE: If the response buffer is not in real storage, cpcmd can sleep */ -extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code); +int cpcmd(const char *cmd, char *response, int rlen, int *response_code); #endif /* _ASM_S390_CPCMD_H */ diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h index 91541000378e..62228a884e06 100644 --- a/arch/s390/include/asm/cpu.h +++ b/arch/s390/include/asm/cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2000, 2009 * Author(s): Hartmut Penner , diff --git a/arch/s390/include/asm/cpufeature.h b/arch/s390/include/asm/cpufeature.h index fa7e69b7c299..1d007c6ede95 100644 --- a/arch/s390/include/asm/cpufeature.h +++ b/arch/s390/include/asm/cpufeature.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Module interface for CPU features * diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 9072bf63a846..cb729d111e20 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2004 * diff --git a/arch/s390/include/asm/crw.h b/arch/s390/include/asm/crw.h index bcb9cd2a730a..c6ebfd31f1db 100644 --- a/arch/s390/include/asm/crw.h +++ b/arch/s390/include/asm/crw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Data definitions for channel report processing * Copyright IBM Corp. 2000, 2009 diff --git a/arch/s390/include/asm/css_chars.h b/arch/s390/include/asm/css_chars.h index 09d1dd46bd57..a478eb61aaf7 100644 --- a/arch/s390/include/asm/css_chars.h +++ b/arch/s390/include/asm/css_chars.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CSS_CHARS_H #define _ASM_CSS_CHARS_H diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h index e508dff92535..93e0d72f6c94 100644 --- a/arch/s390/include/asm/ctl_reg.h +++ b/arch/s390/include/asm/ctl_reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2009 * diff --git a/arch/s390/include/asm/current.h b/arch/s390/include/asm/current.h index b80941f30df5..68f84315277c 100644 --- a/arch/s390/include/asm/current.h +++ b/arch/s390/include/asm/current.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index df7b54ea956d..a4ed25dd3278 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S/390 debug facility * diff --git a/arch/s390/include/asm/delay.h b/arch/s390/include/asm/delay.h index 3f6e4095f471..898323fd93d2 100644 --- a/arch/s390/include/asm/delay.h +++ b/arch/s390/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h index 88162bb5c190..6db78567294c 100644 --- a/arch/s390/include/asm/diag.h +++ b/arch/s390/include/asm/diag.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * s390 diagnose functions * diff --git a/arch/s390/include/asm/dis.h b/arch/s390/include/asm/dis.h index 37f617dfbede..78d1b2d725b9 100644 --- a/arch/s390/include/asm/dis.h +++ b/arch/s390/include/asm/dis.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Disassemble s390 instructions. * diff --git a/arch/s390/include/asm/dma-mapping.h b/arch/s390/include/asm/dma-mapping.h index 512ad0eaa11a..8fc8764fe5ee 100644 --- a/arch/s390/include/asm/dma-mapping.h +++ b/arch/s390/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_DMA_MAPPING_H #define _ASM_S390_DMA_MAPPING_H diff --git a/arch/s390/include/asm/dma.h b/arch/s390/include/asm/dma.h index bb9bdcd20864..6f26f35d4a71 100644 --- a/arch/s390/include/asm/dma.h +++ b/arch/s390/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_DMA_H #define _ASM_S390_DMA_H diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index 144809a3f4f6..eb5323161f11 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_EADM_H #define _ASM_S390_EADM_H diff --git a/arch/s390/include/asm/ebcdic.h b/arch/s390/include/asm/ebcdic.h index c5befc5a3bf5..29441beb92e6 100644 --- a/arch/s390/include/asm/ebcdic.h +++ b/arch/s390/include/asm/ebcdic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * EBCDIC -> ASCII, ASCII -> EBCDIC conversion routines. * @@ -9,9 +10,7 @@ #ifndef _EBCDIC_H #define _EBCDIC_H -#ifndef _S390_TYPES_H -#include -#endif +#include extern __u8 _ascebc_500[256]; /* ASCII -> EBCDIC 500 conversion table */ extern __u8 _ebcasc_500[256]; /* EBCDIC 500 -> ASCII conversion table */ diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index c92ed0170be2..9a3cb3983c01 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * @@ -191,7 +192,7 @@ struct arch_elf_state { } while (0) #define CORE_DUMP_USE_REGSET -#define ELF_EXEC_PAGESIZE 4096 +#define ELF_EXEC_PAGESIZE PAGE_SIZE /* * This is the base location for PIE (ET_DYN with INTERP) loads. On diff --git a/arch/s390/include/asm/exec.h b/arch/s390/include/asm/exec.h index c4a93d6327fa..641bfbec9d52 100644 --- a/arch/s390/include/asm/exec.h +++ b/arch/s390/include/asm/exec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2009 * diff --git a/arch/s390/include/asm/extable.h b/arch/s390/include/asm/extable.h index 16cfe2d62eeb..80a4e5a9cb46 100644 --- a/arch/s390/include/asm/extable.h +++ b/arch/s390/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __S390_EXTABLE_H #define __S390_EXTABLE_H /* diff --git a/arch/s390/include/asm/extmem.h b/arch/s390/include/asm/extmem.h index 6276002d76ba..568fd81bb77b 100644 --- a/arch/s390/include/asm/extmem.h +++ b/arch/s390/include/asm/extmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * definitions for external memory segment support * Copyright IBM Corp. 2003 diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h index cb60d5c5755d..f040644575b7 100644 --- a/arch/s390/include/asm/facility.h +++ b/arch/s390/include/asm/facility.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2009 * diff --git a/arch/s390/include/asm/fcx.h b/arch/s390/include/asm/fcx.h index 04cb4b4bcc5f..cff0749e9657 100644 --- a/arch/s390/include/asm/fcx.h +++ b/arch/s390/include/asm/fcx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Functions for assembling fcx enabled I/O control blocks. * diff --git a/arch/s390/include/asm/fpu/api.h b/arch/s390/include/asm/fpu/api.h index 02124d66bfb5..34a7ae68485c 100644 --- a/arch/s390/include/asm/fpu/api.h +++ b/arch/s390/include/asm/fpu/api.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * In-kernel FPU support functions * diff --git a/arch/s390/include/asm/fpu/internal.h b/arch/s390/include/asm/fpu/internal.h index 629c90865a07..4a71dbbf76fb 100644 --- a/arch/s390/include/asm/fpu/internal.h +++ b/arch/s390/include/asm/fpu/internal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * FPU state and register content conversion primitives * diff --git a/arch/s390/include/asm/fpu/types.h b/arch/s390/include/asm/fpu/types.h index bce255ead72b..d889e9436865 100644 --- a/arch/s390/include/asm/fpu/types.h +++ b/arch/s390/include/asm/fpu/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * FPU data structures * diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index 836c56290499..cfccc0edd00d 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_FTRACE_H #define _ASM_S390_FTRACE_H diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h index a4811aa0304d..9b5a3469fed9 100644 --- a/arch/s390/include/asm/futex.h +++ b/arch/s390/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_FUTEX_H #define _ASM_S390_FUTEX_H @@ -21,17 +22,12 @@ : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ "m" (*uaddr) : "cc"); -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, newval, ret; load_kernel_asce(); - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; pagefault_disable(); switch (op) { @@ -60,17 +56,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) } pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h index 741ddba0bf11..e07cce88dfb0 100644 --- a/arch/s390/include/asm/gmap.h +++ b/arch/s390/include/asm/gmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * KVM guest address space mapping code * diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index b7eabaaeffbd..a296c6acfd07 100644 --- a/arch/s390/include/asm/hardirq.h +++ b/arch/s390/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999, 2000 diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index d95869ce3ca2..9c5fc50204dd 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IBM System z Huge TLB Page Support for Kernel. * diff --git a/arch/s390/include/asm/hw_irq.h b/arch/s390/include/asm/hw_irq.h index ee96a8b697f9..adae176757ae 100644 --- a/arch/s390/include/asm/hw_irq.h +++ b/arch/s390/include/asm/hw_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _HW_IRQ_H #define _HW_IRQ_H diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h index 280b60a0bcd4..15578fd762f6 100644 --- a/arch/s390/include/asm/idals.h +++ b/arch/s390/include/asm/idals.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Author(s)......: Holger Smolinski * Martin Schwidefsky diff --git a/arch/s390/include/asm/idle.h b/arch/s390/include/asm/idle.h index 51ff96d9f287..6d4226dcf42a 100644 --- a/arch/s390/include/asm/idle.h +++ b/arch/s390/include/asm/idle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2014 * diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index 904e4b3af95d..f34d729347e4 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index edb5161df7e2..5a8d92758a58 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * s390 (re)ipl support * @@ -81,7 +82,7 @@ struct ipl_parameter_block { struct ipl_block_fcp fcp; struct ipl_block_ccw ccw; } ipl_info; -} __attribute__((packed,aligned(4096))); +} __packed __aligned(PAGE_SIZE); /* * IPL validity flags diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index 70c9bce766f5..2f7f27e5493f 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IRQ_H #define _ASM_IRQ_H diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h index 595a275c36f8..586df4c9e2f2 100644 --- a/arch/s390/include/asm/irqflags.h +++ b/arch/s390/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2006, 2010 * Author(s): Martin Schwidefsky diff --git a/arch/s390/include/asm/isc.h b/arch/s390/include/asm/isc.h index 8a0b721a9b8d..6cb9e2ed05b6 100644 --- a/arch/s390/include/asm/isc.h +++ b/arch/s390/include/asm/isc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_ISC_H #define _ASM_S390_ISC_H diff --git a/arch/s390/include/asm/itcw.h b/arch/s390/include/asm/itcw.h index fb1bedd3dc0d..59b73961320d 100644 --- a/arch/s390/include/asm/itcw.h +++ b/arch/s390/include/asm/itcw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Functions for incremental construction of fcx enabled I/O control blocks. * diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h index 9be198f5ee79..40f651292aa7 100644 --- a/arch/s390/include/asm/jump_label.h +++ b/arch/s390/include/asm/jump_label.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_JUMP_LABEL_H #define _ASM_S390_JUMP_LABEL_H diff --git a/arch/s390/include/asm/kdebug.h b/arch/s390/include/asm/kdebug.h index 5c1abd47612a..d5327f064799 100644 --- a/arch/s390/include/asm/kdebug.h +++ b/arch/s390/include/asm/kdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _S390_KDEBUG_H #define _S390_KDEBUG_H diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h index dccf24ee26d3..1d708a419326 100644 --- a/arch/s390/include/asm/kexec.h +++ b/arch/s390/include/asm/kexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2005 * diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index a409d5991934..51375e766e90 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h @@ -226,7 +226,9 @@ struct kvm_s390_sie_block { #define ECB3_RI 0x01 __u8 ecb3; /* 0x0063 */ __u32 scaol; /* 0x0064 */ - __u8 reserved68[4]; /* 0x0068 */ + __u8 reserved68; /* 0x0068 */ + __u8 epdx; /* 0x0069 */ + __u8 reserved6a[2]; /* 0x006a */ __u32 todpr; /* 0x006c */ __u8 reserved70[16]; /* 0x0070 */ __u64 mso; /* 0x0080 */ @@ -265,6 +267,7 @@ struct kvm_s390_sie_block { __u64 cbrlo; /* 0x01b8 */ __u8 reserved1c0[8]; /* 0x01c0 */ #define ECD_HOSTREGMGMT 0x20000000 +#define ECD_MEF 0x08000000 __u32 ecd; /* 0x01c8 */ __u8 reserved1cc[18]; /* 0x01cc */ __u64 pp; /* 0x01de */ @@ -739,6 +742,7 @@ struct kvm_arch{ struct kvm_s390_cpu_model model; struct kvm_s390_crypto crypto; struct kvm_s390_vsie vsie; + u8 epdx; u64 epoch; struct kvm_s390_migration_state *migration_state; /* subset of available cpu features enabled by user space */ diff --git a/arch/s390/include/asm/linkage.h b/arch/s390/include/asm/linkage.h index 27da78cf416d..1b95da3fdd64 100644 --- a/arch/s390/include/asm/linkage.h +++ b/arch/s390/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 8a5b082797f8..917f7344cab6 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2012 * Author(s): Hartmut Penner , @@ -95,46 +96,46 @@ struct lowcore { __u64 int_clock; /* 0x0310 */ __u64 mcck_clock; /* 0x0318 */ __u64 clock_comparator; /* 0x0320 */ + __u64 boot_clock[2]; /* 0x0328 */ /* Current process. */ - __u64 current_task; /* 0x0328 */ - __u8 pad_0x318[0x320-0x318]; /* 0x0330 */ - __u64 kernel_stack; /* 0x0338 */ + __u64 current_task; /* 0x0338 */ + __u64 kernel_stack; /* 0x0340 */ /* Interrupt, panic and restart stack. */ - __u64 async_stack; /* 0x0340 */ - __u64 panic_stack; /* 0x0348 */ - __u64 restart_stack; /* 0x0350 */ + __u64 async_stack; /* 0x0348 */ + __u64 panic_stack; /* 0x0350 */ + __u64 restart_stack; /* 0x0358 */ /* Restart function and parameter. */ - __u64 restart_fn; /* 0x0358 */ - __u64 restart_data; /* 0x0360 */ - __u64 restart_source; /* 0x0368 */ + __u64 restart_fn; /* 0x0360 */ + __u64 restart_data; /* 0x0368 */ + __u64 restart_source; /* 0x0370 */ /* Address space pointer. */ - __u64 kernel_asce; /* 0x0370 */ - __u64 user_asce; /* 0x0378 */ + __u64 kernel_asce; /* 0x0378 */ + __u64 user_asce; /* 0x0380 */ /* * The lpp and current_pid fields form a * 64-bit value that is set as program * parameter with the LPP instruction. */ - __u32 lpp; /* 0x0380 */ - __u32 current_pid; /* 0x0384 */ + __u32 lpp; /* 0x0388 */ + __u32 current_pid; /* 0x038c */ /* SMP info area */ - __u32 cpu_nr; /* 0x0388 */ - __u32 softirq_pending; /* 0x038c */ - __u64 percpu_offset; /* 0x0390 */ - __u64 vdso_per_cpu_data; /* 0x0398 */ - __u64 machine_flags; /* 0x03a0 */ - __u32 preempt_count; /* 0x03a8 */ - __u8 pad_0x03ac[0x03b0-0x03ac]; /* 0x03ac */ - __u64 gmap; /* 0x03b0 */ - __u32 spinlock_lockval; /* 0x03b8 */ - __u32 fpu_flags; /* 0x03bc */ - __u8 pad_0x03c0[0x0400-0x03c0]; /* 0x03c0 */ + __u32 cpu_nr; /* 0x0390 */ + __u32 softirq_pending; /* 0x0394 */ + __u64 percpu_offset; /* 0x0398 */ + __u64 vdso_per_cpu_data; /* 0x03a0 */ + __u64 machine_flags; /* 0x03a8 */ + __u32 preempt_count; /* 0x03b0 */ + __u8 pad_0x03b4[0x03b8-0x03b4]; /* 0x03b4 */ + __u64 gmap; /* 0x03b8 */ + __u32 spinlock_lockval; /* 0x03c0 */ + __u32 fpu_flags; /* 0x03c4 */ + __u8 pad_0x03c8[0x0400-0x03c8]; /* 0x03c8 */ /* Per cpu primary space access list */ __u32 paste[16]; /* 0x0400 */ diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h deleted file mode 100644 index b79813d9cf68..000000000000 --- a/arch/s390/include/asm/mman.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * S390 version - * - * Derived from "include/asm-i386/mman.h" - */ -#ifndef __S390_MMAN_H__ -#define __S390_MMAN_H__ - -#include - -#endif /* __S390_MMAN_H__ */ diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index bd6f30304518..db35c41a59d5 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MMU_H #define __MMU_H @@ -5,12 +6,11 @@ #include typedef struct { + spinlock_t lock; cpumask_t cpu_attach_mask; atomic_t flush_count; unsigned int flush_mm; - spinlock_t pgtable_lock; struct list_head pgtable_list; - spinlock_t gmap_lock; struct list_head gmap_list; unsigned long gmap_asce; unsigned long asce; @@ -27,10 +27,8 @@ typedef struct { } mm_context_t; #define INIT_MM_CONTEXT(name) \ - .context.pgtable_lock = \ - __SPIN_LOCK_UNLOCKED(name.context.pgtable_lock), \ + .context.lock = __SPIN_LOCK_UNLOCKED(name.context.lock), \ .context.pgtable_list = LIST_HEAD_INIT(name.context.pgtable_list), \ - .context.gmap_lock = __SPIN_LOCK_UNLOCKED(name.context.gmap_lock), \ .context.gmap_list = LIST_HEAD_INIT(name.context.gmap_list), static inline int tprot(unsigned long addr) diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 24bc41622a98..43607bb12cc2 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * @@ -12,13 +13,13 @@ #include #include #include +#include static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { - spin_lock_init(&mm->context.pgtable_lock); + spin_lock_init(&mm->context.lock); INIT_LIST_HEAD(&mm->context.pgtable_list); - spin_lock_init(&mm->context.gmap_lock); INIT_LIST_HEAD(&mm->context.gmap_list); cpumask_clear(&mm->context.cpu_attach_mask); atomic_set(&mm->context.flush_count, 0); @@ -33,7 +34,7 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.use_cmma = 0; #endif switch (mm->context.asce_limit) { - case 1UL << 42: + case _REGION2_SIZE: /* * forked 3-level task, fall through to set new asce with new * mm->pgd @@ -49,12 +50,12 @@ static inline int init_new_context(struct task_struct *tsk, mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION1; break; - case 1UL << 53: + case _REGION1_SIZE: /* forked 4-level task, set new asce with new mm->pgd */ mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION2; break; - case 1UL << 31: + case _REGION3_SIZE: /* forked 2-level compat task, set new asce with new mm->pgd */ mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; @@ -102,7 +103,6 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, if (prev == next) return; cpumask_set_cpu(cpu, &next->context.cpu_attach_mask); - cpumask_set_cpu(cpu, mm_cpumask(next)); /* Clear old ASCE by loading the kernel ASCE. */ __ctl_load(S390_lowcore.kernel_asce, 1, 1); __ctl_load(S390_lowcore.kernel_asce, 7, 7); @@ -120,9 +120,8 @@ static inline void finish_arch_post_lock_switch(void) preempt_disable(); while (atomic_read(&mm->context.flush_count)) cpu_relax(); - - if (mm->context.flush_mm) - __tlb_flush_mm(mm); + cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); + __tlb_flush_mm_lazy(mm); preempt_enable(); } set_fs(current->thread.mm_segment); @@ -135,33 +134,8 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { switch_mm(prev, next, current); + cpumask_set_cpu(smp_processor_id(), mm_cpumask(next)); set_user_asce(next); } -static inline void arch_dup_mmap(struct mm_struct *oldmm, - struct mm_struct *mm) -{ -} - -static inline void arch_exit_mmap(struct mm_struct *mm) -{ -} - -static inline void arch_unmap(struct mm_struct *mm, - struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ -} - -static inline void arch_bprm_mm_init(struct mm_struct *mm, - struct vm_area_struct *vma) -{ -} - -static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, - bool write, bool execute, bool foreign) -{ - /* by default, allow everything */ - return true; -} #endif /* __S390_MMU_CONTEXT_H */ diff --git a/arch/s390/include/asm/mmzone.h b/arch/s390/include/asm/mmzone.h index a9e834e60b84..73e3e7c6976c 100644 --- a/arch/s390/include/asm/mmzone.h +++ b/arch/s390/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * NUMA support for s390 * diff --git a/arch/s390/include/asm/module.h b/arch/s390/include/asm/module.h index df1f861a848a..e0a6d29846e2 100644 --- a/arch/s390/include/asm/module.h +++ b/arch/s390/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_MODULE_H #define _ASM_S390_MODULE_H diff --git a/arch/s390/include/asm/nmi.h b/arch/s390/include/asm/nmi.h index 9d91cf3e427f..c8a7beadd3d4 100644 --- a/arch/s390/include/asm/nmi.h +++ b/arch/s390/include/asm/nmi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine check handler definitions * @@ -72,7 +73,7 @@ union mci { u64 ar : 1; /* 33 access register validity */ u64 da : 1; /* 34 delayed access exception */ u64 : 1; /* 35 */ - u64 gs : 1; /* 36 guarded storage registers */ + u64 gs : 1; /* 36 guarded storage registers validity */ u64 : 5; /* 37-41 */ u64 pr : 1; /* 42 tod programmable register validity */ u64 fc : 1; /* 43 fp control register validity */ diff --git a/arch/s390/include/asm/numa.h b/arch/s390/include/asm/numa.h index dc19ee0c92aa..35f8cbe7e5bb 100644 --- a/arch/s390/include/asm/numa.h +++ b/arch/s390/include/asm/numa.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * NUMA support for s390 * diff --git a/arch/s390/include/asm/os_info.h b/arch/s390/include/asm/os_info.h index 943475382d51..3c89279d2a4b 100644 --- a/arch/s390/include/asm/os_info.h +++ b/arch/s390/include/asm/os_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * OS info memory interface * diff --git a/arch/s390/include/asm/page-states.h b/arch/s390/include/asm/page-states.h index 42267a2fe29e..c33c4deb545f 100644 --- a/arch/s390/include/asm/page-states.h +++ b/arch/s390/include/asm/page-states.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2017 * Author(s): Claudio Imbrenda @@ -13,7 +14,8 @@ #define ESSA_SET_POT_VOLATILE 4 #define ESSA_SET_STABLE_RESIDENT 5 #define ESSA_SET_STABLE_IF_RESIDENT 6 +#define ESSA_SET_STABLE_NODAT 7 -#define ESSA_MAX ESSA_SET_STABLE_IF_RESIDENT +#define ESSA_MAX ESSA_SET_STABLE_NODAT #endif diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 624deaa44230..41e3908b397f 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999, 2000 @@ -10,10 +11,14 @@ #include #include +#define _PAGE_SHIFT 12 +#define _PAGE_SIZE (_AC(1, UL) << _PAGE_SHIFT) +#define _PAGE_MASK (~(_PAGE_SIZE - 1)) + /* PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#define PAGE_SHIFT _PAGE_SHIFT +#define PAGE_SIZE _PAGE_SIZE +#define PAGE_MASK _PAGE_MASK #define PAGE_DEFAULT_ACC 0 #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) @@ -133,6 +138,9 @@ static inline int page_reset_referenced(unsigned long addr) struct page; void arch_free_page(struct page *page, int order); void arch_alloc_page(struct page *page, int order); +void arch_set_page_dat(struct page *page, int order); +void arch_set_page_nodat(struct page *page, int order); +int arch_test_page_nodat(struct page *page); void arch_set_page_states(int make_stable); static inline int devmem_is_allowed(unsigned long pfn) @@ -145,16 +153,26 @@ static inline int devmem_is_allowed(unsigned long pfn) #endif /* !__ASSEMBLY__ */ -#define __PAGE_OFFSET 0x0UL -#define PAGE_OFFSET 0x0UL -#define __pa(x) (unsigned long)(x) -#define __va(x) (void *)(unsigned long)(x) -#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) -#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define __PAGE_OFFSET 0x0UL +#define PAGE_OFFSET 0x0UL + +#define __pa(x) ((unsigned long)(x)) +#define __va(x) ((void *)(unsigned long)(x)) + +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) #define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) + +#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) #define page_to_virt(page) pfn_to_virt(page_to_pfn(page)) +#define phys_to_pfn(kaddr) ((kaddr) >> PAGE_SHIFT) +#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) + +#define phys_to_page(kaddr) pfn_to_page(phys_to_pfn(kaddr)) +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) + +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) + #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index f36b4b726057..12fe3591034f 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_S390_PCI_H #define __ASM_S390_PCI_H @@ -8,6 +9,7 @@ #include #include +#include #include #include #include @@ -122,6 +124,8 @@ struct zpci_dev { unsigned long iommu_pages; unsigned int next_bit; + struct iommu_device iommu_dev; /* IOMMU core handle */ + char res_name[16]; struct zpci_bar_struct bars[PCI_BAR_COUNT]; @@ -174,6 +178,10 @@ int clp_enable_fh(struct zpci_dev *, u8); int clp_disable_fh(struct zpci_dev *); int clp_get_state(u32 fid, enum zpci_state *state); +/* IOMMU Interface */ +int zpci_init_iommu(struct zpci_dev *zdev); +void zpci_destroy_iommu(struct zpci_dev *zdev); + #ifdef CONFIG_PCI /* Error handling and recovery */ void zpci_event_error(void *); diff --git a/arch/s390/include/asm/pci_clp.h b/arch/s390/include/asm/pci_clp.h index 938b8cc19fc6..b3b31b31f0d3 100644 --- a/arch/s390/include/asm/pci_clp.h +++ b/arch/s390/include/asm/pci_clp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_PCI_CLP_H #define _ASM_S390_PCI_CLP_H diff --git a/arch/s390/include/asm/pci_debug.h b/arch/s390/include/asm/pci_debug.h index ac24b26fc065..6c2c38060f8b 100644 --- a/arch/s390/include/asm/pci_debug.h +++ b/arch/s390/include/asm/pci_debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _S390_ASM_PCI_DEBUG_H #define _S390_ASM_PCI_DEBUG_H diff --git a/arch/s390/include/asm/pci_dma.h b/arch/s390/include/asm/pci_dma.h index 92df3eb8d14e..e8d9161fa17a 100644 --- a/arch/s390/include/asm/pci_dma.h +++ b/arch/s390/include/asm/pci_dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_PCI_DMA_H #define _ASM_S390_PCI_DMA_H diff --git a/arch/s390/include/asm/pci_insn.h b/arch/s390/include/asm/pci_insn.h index 34abcf275799..419e83fa4721 100644 --- a/arch/s390/include/asm/pci_insn.h +++ b/arch/s390/include/asm/pci_insn.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_PCI_INSN_H #define _ASM_S390_PCI_INSN_H diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h index 69aa18be61af..cbb9cb9c6547 100644 --- a/arch/s390/include/asm/pci_io.h +++ b/arch/s390/include/asm/pci_io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_PCI_IO_H #define _ASM_S390_PCI_IO_H diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h index 90240dfef76a..0095ddb58ff6 100644 --- a/arch/s390/include/asm/percpu.h +++ b/arch/s390/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_S390_PERCPU__ #define __ARCH_S390_PERCPU__ diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h index dd32beb9d30c..79aa6421fedb 100644 --- a/arch/s390/include/asm/perf_event.h +++ b/arch/s390/include/asm/perf_event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Performance event support - s390 specific definitions. * diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index bb0ff1bb0c4a..bbe99cb8219d 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999, 2000 @@ -15,6 +16,8 @@ #include #include +#define CRST_ALLOC_ORDER 2 + unsigned long *crst_table_alloc(struct mm_struct *); void crst_table_free(struct mm_struct *, unsigned long *); @@ -42,16 +45,16 @@ static inline void clear_table(unsigned long *s, unsigned long val, size_t n) static inline void crst_table_init(unsigned long *crst, unsigned long entry) { - clear_table(crst, entry, sizeof(unsigned long)*2048); + clear_table(crst, entry, _CRST_TABLE_SIZE); } static inline unsigned long pgd_entry_type(struct mm_struct *mm) { - if (mm->context.asce_limit <= (1UL << 31)) + if (mm->context.asce_limit <= _REGION3_SIZE) return _SEGMENT_ENTRY_EMPTY; - if (mm->context.asce_limit <= (1UL << 42)) + if (mm->context.asce_limit <= _REGION2_SIZE) return _REGION3_ENTRY_EMPTY; - if (mm->context.asce_limit <= (1UL << 53)) + if (mm->context.asce_limit <= _REGION1_SIZE) return _REGION2_ENTRY_EMPTY; return _REGION1_ENTRY_EMPTY; } @@ -119,7 +122,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) if (!table) return NULL; - if (mm->context.asce_limit == (1UL << 31)) { + if (mm->context.asce_limit == _REGION3_SIZE) { /* Forking a compat process with 2 page table levels */ if (!pgtable_pmd_page_ctor(virt_to_page(table))) { crst_table_free(mm, table); @@ -131,7 +134,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) { - if (mm->context.asce_limit == (1UL << 31)) + if (mm->context.asce_limit == _REGION3_SIZE) pgtable_pmd_page_dtor(virt_to_page(pgd)); crst_table_free(mm, (unsigned long *) pgd); } @@ -158,4 +161,8 @@ static inline void pmd_populate(struct mm_struct *mm, extern void rcu_table_freelist_finish(void); +void vmem_map_init(void); +void *vmem_crst_alloc(unsigned long val); +pte_t *vmem_pte_alloc(void); + #endif /* _S390_PGALLOC_H */ diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 57057fb1cc07..d7fe9838084d 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999, 2000 @@ -11,19 +12,6 @@ #ifndef _ASM_S390_PGTABLE_H #define _ASM_S390_PGTABLE_H -/* - * The Linux memory management assumes a three-level page table setup. - * For s390 64 bit we use up to four of the five levels the hardware - * provides (region first tables are not used). - * - * The "pgd_xxx()" functions are trivial for a folded two-level - * setup: the pgd is never bad, and a pmd always exists (as it's folded - * into the pgd entry) - * - * This file contains the functions and defines necessary to modify and use - * the S390 page table tree. - */ -#ifndef __ASSEMBLY__ #include #include #include @@ -34,9 +22,6 @@ extern pgd_t swapper_pg_dir[]; extern void paging_init(void); -extern void vmem_map_init(void); -pmd_t *vmem_pmd_alloc(void); -pte_t *vmem_pte_alloc(void); enum { PG_DIRECT_MAP_4K = 0, @@ -77,38 +62,6 @@ extern unsigned long zero_page_mask; #define __HAVE_COLOR_ZERO_PAGE /* TODO: s390 cannot support io_remap_pfn_range... */ -#endif /* !__ASSEMBLY__ */ - -/* - * PMD_SHIFT determines the size of the area a second-level page - * table can map - * PGDIR_SHIFT determines what a third-level page table entry can map - */ -#define PMD_SHIFT 20 -#define PUD_SHIFT 31 -#define P4D_SHIFT 42 -#define PGDIR_SHIFT 53 - -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) -#define PUD_SIZE (1UL << PUD_SHIFT) -#define PUD_MASK (~(PUD_SIZE-1)) -#define P4D_SIZE (1UL << P4D_SHIFT) -#define P4D_MASK (~(P4D_SIZE-1)) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -/* - * entries per page directory level: the S390 is two-level, so - * we don't really have any PMD directory physically. - * for S390 segment-table entries are combined to one PGD - * that leads to 1024 pte per pgd - */ -#define PTRS_PER_PTE 256 -#define PTRS_PER_PMD 2048 -#define PTRS_PER_PUD 2048 -#define PTRS_PER_P4D 2048 -#define PTRS_PER_PGD 2048 #define FIRST_USER_ADDRESS 0UL @@ -123,7 +76,6 @@ extern unsigned long zero_page_mask; #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) -#ifndef __ASSEMBLY__ /* * The vmalloc and module area will always be on the topmost area of the * kernel mapping. We reserve 128GB (64bit) for vmalloc and modules. @@ -269,7 +221,7 @@ static inline int is_module_addr(void *addr) */ /* Bits in the segment/region table address-space-control-element */ -#define _ASCE_ORIGIN ~0xfffUL/* segment table origin */ +#define _ASCE_ORIGIN ~0xfffUL/* region/segment table origin */ #define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ #define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ #define _ASCE_SPACE_SWITCH 0x40 /* space switch event */ @@ -320,9 +272,9 @@ static inline int is_module_addr(void *addr) #define _SEGMENT_ENTRY_BITS 0xfffffffffffffe33UL #define _SEGMENT_ENTRY_BITS_LARGE 0xfffffffffff0ff33UL #define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ -#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ -#define _SEGMENT_ENTRY_PROTECT 0x200 /* page protection bit */ -#define _SEGMENT_ENTRY_NOEXEC 0x100 /* region no-execute bit */ +#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* page table origin */ +#define _SEGMENT_ENTRY_PROTECT 0x200 /* segment protection bit */ +#define _SEGMENT_ENTRY_NOEXEC 0x100 /* segment no-execute bit */ #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ #define _SEGMENT_ENTRY (0) @@ -340,6 +292,54 @@ static inline int is_module_addr(void *addr) #define _SEGMENT_ENTRY_SOFT_DIRTY 0x0000 /* SW segment soft dirty bit */ #endif +#define _CRST_ENTRIES 2048 /* number of region/segment table entries */ +#define _PAGE_ENTRIES 256 /* number of page table entries */ + +#define _CRST_TABLE_SIZE (_CRST_ENTRIES * 8) +#define _PAGE_TABLE_SIZE (_PAGE_ENTRIES * 8) + +#define _REGION1_SHIFT 53 +#define _REGION2_SHIFT 42 +#define _REGION3_SHIFT 31 +#define _SEGMENT_SHIFT 20 + +#define _REGION1_INDEX (0x7ffUL << _REGION1_SHIFT) +#define _REGION2_INDEX (0x7ffUL << _REGION2_SHIFT) +#define _REGION3_INDEX (0x7ffUL << _REGION3_SHIFT) +#define _SEGMENT_INDEX (0x7ffUL << _SEGMENT_SHIFT) +#define _PAGE_INDEX (0xffUL << _PAGE_SHIFT) + +#define _REGION1_SIZE (1UL << _REGION1_SHIFT) +#define _REGION2_SIZE (1UL << _REGION2_SHIFT) +#define _REGION3_SIZE (1UL << _REGION3_SHIFT) +#define _SEGMENT_SIZE (1UL << _SEGMENT_SHIFT) + +#define _REGION1_MASK (~(_REGION1_SIZE - 1)) +#define _REGION2_MASK (~(_REGION2_SIZE - 1)) +#define _REGION3_MASK (~(_REGION3_SIZE - 1)) +#define _SEGMENT_MASK (~(_SEGMENT_SIZE - 1)) + +#define PMD_SHIFT _SEGMENT_SHIFT +#define PUD_SHIFT _REGION3_SHIFT +#define P4D_SHIFT _REGION2_SHIFT +#define PGDIR_SHIFT _REGION1_SHIFT + +#define PMD_SIZE _SEGMENT_SIZE +#define PUD_SIZE _REGION3_SIZE +#define P4D_SIZE _REGION2_SIZE +#define PGDIR_SIZE _REGION1_SIZE + +#define PMD_MASK _SEGMENT_MASK +#define PUD_MASK _REGION3_MASK +#define P4D_MASK _REGION2_MASK +#define PGDIR_MASK _REGION1_MASK + +#define PTRS_PER_PTE _PAGE_ENTRIES +#define PTRS_PER_PMD _CRST_ENTRIES +#define PTRS_PER_PUD _CRST_ENTRIES +#define PTRS_PER_P4D _CRST_ENTRIES +#define PTRS_PER_PGD _CRST_ENTRIES + /* * Segment table and region3 table entry encoding * (R = read-only, I = invalid, y = young bit): @@ -376,6 +376,7 @@ static inline int is_module_addr(void *addr) /* Guest Page State used for virtualization */ #define _PGSTE_GPS_ZERO 0x0000000080000000UL +#define _PGSTE_GPS_NODAT 0x0000000040000000UL #define _PGSTE_GPS_USAGE_MASK 0x0000000003000000UL #define _PGSTE_GPS_USAGE_STABLE 0x0000000000000000UL #define _PGSTE_GPS_USAGE_UNUSED 0x0000000001000000UL @@ -505,7 +506,7 @@ static inline int mm_alloc_pgste(struct mm_struct *mm) * In the case that a guest uses storage keys * faults should no longer be backed by zero pages */ -#define mm_forbids_zeropage mm_use_skey +#define mm_forbids_zeropage mm_has_pgste static inline int mm_use_skey(struct mm_struct *mm) { #ifdef CONFIG_PGSTE @@ -952,15 +953,30 @@ static inline pte_t pte_mkhuge(pte_t pte) #define IPTE_GLOBAL 0 #define IPTE_LOCAL 1 -static inline void __ptep_ipte(unsigned long address, pte_t *ptep, int local) +#define IPTE_NODAT 0x400 +#define IPTE_GUEST_ASCE 0x800 + +static inline void __ptep_ipte(unsigned long address, pte_t *ptep, + unsigned long opt, unsigned long asce, + int local) { unsigned long pto = (unsigned long) ptep; - /* Invalidation + TLB flush for the pte */ + if (__builtin_constant_p(opt) && opt == 0) { + /* Invalidation + TLB flush for the pte */ + asm volatile( + " .insn rrf,0xb2210000,%[r1],%[r2],0,%[m4]" + : "+m" (*ptep) : [r1] "a" (pto), [r2] "a" (address), + [m4] "i" (local)); + return; + } + + /* Invalidate ptes with options + TLB flush of the ptes */ + opt = opt | (asce & _ASCE_ORIGIN); asm volatile( - " .insn rrf,0xb2210000,%[r1],%[r2],0,%[m4]" - : "+m" (*ptep) : [r1] "a" (pto), [r2] "a" (address), - [m4] "i" (local)); + " .insn rrf,0xb2210000,%[r1],%[r2],%[r3],%[m4]" + : [r2] "+a" (address), [r3] "+a" (opt) + : [r1] "a" (pto), [m4] "i" (local) : "memory"); } static inline void __ptep_ipte_range(unsigned long address, int nr, @@ -1341,31 +1357,61 @@ static inline void __pmdp_csp(pmd_t *pmdp) #define IDTE_GLOBAL 0 #define IDTE_LOCAL 1 -static inline void __pmdp_idte(unsigned long address, pmd_t *pmdp, int local) +#define IDTE_PTOA 0x0800 +#define IDTE_NODAT 0x1000 +#define IDTE_GUEST_ASCE 0x2000 + +static inline void __pmdp_idte(unsigned long addr, pmd_t *pmdp, + unsigned long opt, unsigned long asce, + int local) { unsigned long sto; - sto = (unsigned long) pmdp - pmd_index(address) * sizeof(pmd_t); - asm volatile( - " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" - : "+m" (*pmdp) - : [r1] "a" (sto), [r2] "a" ((address & HPAGE_MASK)), - [m4] "i" (local) - : "cc" ); + sto = (unsigned long) pmdp - pmd_index(addr) * sizeof(pmd_t); + if (__builtin_constant_p(opt) && opt == 0) { + /* flush without guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" + : "+m" (*pmdp) + : [r1] "a" (sto), [r2] "a" ((addr & HPAGE_MASK)), + [m4] "i" (local) + : "cc" ); + } else { + /* flush with guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],%[r3],%[m4]" + : "+m" (*pmdp) + : [r1] "a" (sto), [r2] "a" ((addr & HPAGE_MASK) | opt), + [r3] "a" (asce), [m4] "i" (local) + : "cc" ); + } } -static inline void __pudp_idte(unsigned long address, pud_t *pudp, int local) +static inline void __pudp_idte(unsigned long addr, pud_t *pudp, + unsigned long opt, unsigned long asce, + int local) { unsigned long r3o; - r3o = (unsigned long) pudp - pud_index(address) * sizeof(pud_t); + r3o = (unsigned long) pudp - pud_index(addr) * sizeof(pud_t); r3o |= _ASCE_TYPE_REGION3; - asm volatile( - " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" - : "+m" (*pudp) - : [r1] "a" (r3o), [r2] "a" ((address & PUD_MASK)), - [m4] "i" (local) - : "cc"); + if (__builtin_constant_p(opt) && opt == 0) { + /* flush without guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],0,%[m4]" + : "+m" (*pudp) + : [r1] "a" (r3o), [r2] "a" ((addr & PUD_MASK)), + [m4] "i" (local) + : "cc"); + } else { + /* flush with guest asce */ + asm volatile( + " .insn rrf,0xb98e0000,%[r1],%[r2],%[r3],%[m4]" + : "+m" (*pudp) + : [r1] "a" (r3o), [r2] "a" ((addr & PUD_MASK) | opt), + [r3] "a" (asce), [m4] "i" (local) + : "cc" ); + } } pmd_t pmdp_xchg_direct(struct mm_struct *, unsigned long, pmd_t *, pmd_t); @@ -1462,7 +1508,9 @@ static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma, static inline void pmdp_invalidate(struct vm_area_struct *vma, unsigned long addr, pmd_t *pmdp) { - pmdp_xchg_direct(vma->vm_mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY)); + pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); + + pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd); } #define __HAVE_ARCH_PMDP_SET_WRPROTECT @@ -1548,8 +1596,6 @@ 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 }) -#endif /* !__ASSEMBLY__ */ - #define kern_addr_valid(addr) (1) extern int vmem_add_mapping(unsigned long start, unsigned long size); diff --git a/arch/s390/include/asm/pkey.h b/arch/s390/include/asm/pkey.h index 4c484590d858..053117ba7328 100644 --- a/arch/s390/include/asm/pkey.h +++ b/arch/s390/include/asm/pkey.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Kernelspace interface to the pkey device driver * diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h index b0776b2c8dcf..23a14d187fb1 100644 --- a/arch/s390/include/asm/preempt.h +++ b/arch/s390/include/asm/preempt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_PREEMPT_H #define __ASM_PREEMPT_H diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index c25d57e0aad3..9cf92abe23c3 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 853b01245c20..2f84e77f1f1b 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999, 2000 diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 998b61cd0e56..de11ecc99c7c 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2000, 2008 * Author(s): Utz Bacher @@ -80,7 +81,7 @@ struct qdr { u32 qkey : 4; u32 : 28; struct qdesfmt0 qdf0[126]; -} __attribute__ ((packed, aligned(4096))); +} __packed __aligned(PAGE_SIZE); #define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40 #define QIB_RFLAGS_ENABLE_QEBSM 0x80 diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h index fe11fa88a0e0..6450b31ade03 100644 --- a/arch/s390/include/asm/reset.h +++ b/arch/s390/include/asm/reset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2006 * Author(s): Heiko Carstens diff --git a/arch/s390/include/asm/runtime_instr.h b/arch/s390/include/asm/runtime_instr.h index 402ad6df4897..ea8896ba5afc 100644 --- a/arch/s390/include/asm/runtime_instr.h +++ b/arch/s390/include/asm/runtime_instr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _RUNTIME_INSTR_H #define _RUNTIME_INSTR_H diff --git a/arch/s390/include/asm/rwsem.h b/arch/s390/include/asm/rwsem.h index 597e7e96b59e..f731b7b518bd 100644 --- a/arch/s390/include/asm/rwsem.h +++ b/arch/s390/include/asm/rwsem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _S390_RWSEM_H #define _S390_RWSEM_H diff --git a/arch/s390/include/asm/schid.h b/arch/s390/include/asm/schid.h index 40b47dfa9d66..3ac405a67ff0 100644 --- a/arch/s390/include/asm/schid.h +++ b/arch/s390/include/asm/schid.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_SCHID_H #define ASM_SCHID_H diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 6f5167bc1928..d3c1a8a2e3ad 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2007 * Author(s): Heiko Carstens diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h index 17a7904f001a..79b7ffa91832 100644 --- a/arch/s390/include/asm/scsw.h +++ b/arch/s390/include/asm/scsw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Helper functions for scsw access. * diff --git a/arch/s390/include/asm/seccomp.h b/arch/s390/include/asm/seccomp.h index e10f8337367b..795bbe0d7ca6 100644 --- a/arch/s390/include/asm/seccomp.h +++ b/arch/s390/include/asm/seccomp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_SECCOMP_H #define _ASM_S390_SECCOMP_H diff --git a/arch/s390/include/asm/sections.h b/arch/s390/include/asm/sections.h index fbd9116eb17b..0ac3e8166e85 100644 --- a/arch/s390/include/asm/sections.h +++ b/arch/s390/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _S390_SECTIONS_H #define _S390_SECTIONS_H diff --git a/arch/s390/include/asm/serial.h b/arch/s390/include/asm/serial.h index 5b3e48ef534b..aaf85a69061c 100644 --- a/arch/s390/include/asm/serial.h +++ b/arch/s390/include/asm/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_SERIAL_H #define _ASM_S390_SERIAL_H diff --git a/arch/s390/include/asm/set_memory.h b/arch/s390/include/asm/set_memory.h index 46a4db44c47a..c59a83536c70 100644 --- a/arch/s390/include/asm/set_memory.h +++ b/arch/s390/include/asm/set_memory.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMS390_SET_MEMORY_H #define _ASMS390_SET_MEMORY_H diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index cd78155b1829..f2c2b7cd9099 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999, 2010 @@ -29,8 +30,10 @@ #define MACHINE_FLAG_TE _BITUL(11) #define MACHINE_FLAG_TLB_LC _BITUL(12) #define MACHINE_FLAG_VX _BITUL(13) -#define MACHINE_FLAG_NX _BITUL(14) -#define MACHINE_FLAG_GS _BITUL(15) +#define MACHINE_FLAG_TLB_GUEST _BITUL(14) +#define MACHINE_FLAG_NX _BITUL(15) +#define MACHINE_FLAG_GS _BITUL(16) +#define MACHINE_FLAG_SCC _BITUL(17) #define LPP_MAGIC _BITUL(31) #define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL) @@ -68,8 +71,10 @@ extern void detect_memory_memblock(void); #define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) #define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) #define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX) +#define MACHINE_HAS_TLB_GUEST (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_GUEST) #define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX) #define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS) +#define MACHINE_HAS_SCC (S390_lowcore.machine_flags & MACHINE_FLAG_SCC) /* * Console mode. Override with conmode= @@ -104,9 +109,16 @@ extern void pfault_fini(void); #define pfault_fini() do { } while (0) #endif /* CONFIG_PFAULT */ +#ifdef CONFIG_VMCP +void vmcp_cma_reserve(void); +#else +static inline void vmcp_cma_reserve(void) { } +#endif + void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault); -extern void cmma_init(void); +void cmma_init(void); +void cmma_init_nodat(void); extern void (*_machine_restart)(char *command); extern void (*_machine_halt)(void); diff --git a/arch/s390/include/asm/shmparam.h b/arch/s390/include/asm/shmparam.h index e985182738f8..e75d45649c54 100644 --- a/arch/s390/include/asm/shmparam.h +++ b/arch/s390/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * diff --git a/arch/s390/include/asm/signal.h b/arch/s390/include/asm/signal.h index abf9e5735943..7daf4d8b5ee5 100644 --- a/arch/s390/include/asm/signal.h +++ b/arch/s390/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 020a8814d511..53ee795cd3d3 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __S390_ASM_SIGP_H #define __S390_ASM_SIGP_H diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 3deb134587b7..babe83ed416c 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2012 * Author(s): Denis Joseph Barrow, diff --git a/arch/s390/include/asm/sparsemem.h b/arch/s390/include/asm/sparsemem.h index 334e279f1bce..c549893602ea 100644 --- a/arch/s390/include/asm/sparsemem.h +++ b/arch/s390/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_SPARSEMEM_H #define _ASM_S390_SPARSEMEM_H diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index f7838ecd83c6..f3f5e0155b10 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 @@ -92,17 +93,11 @@ static inline void arch_spin_unlock(arch_spinlock_t *lp) { typecheck(int, lp->lock); asm volatile( - "st %1,%0\n" - : "+Q" (lp->lock) - : "d" (0) - : "cc", "memory"); -} - -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - while (arch_spin_is_locked(lock)) - arch_spin_relax(lock); - smp_acquire__after_ctrl_dep(); +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + " .long 0xb2fa0070\n" /* NIAI 7 */ +#endif + " st %1,%0\n" + : "=Q" (lp->lock) : "d" (0) : "cc", "memory"); } /* diff --git a/arch/s390/include/asm/spinlock_types.h b/arch/s390/include/asm/spinlock_types.h index fe755eec275f..1861a0c5dd47 100644 --- a/arch/s390/include/asm/spinlock_types.h +++ b/arch/s390/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPINLOCK_TYPES_H #define __ASM_SPINLOCK_TYPES_H diff --git a/arch/s390/include/asm/stp.h b/arch/s390/include/asm/stp.h index 7689727585b2..f0ddefb06ec8 100644 --- a/arch/s390/include/asm/stp.h +++ b/arch/s390/include/asm/stp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2006 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h index e5f5c7074f2c..27ce494198f5 100644 --- a/arch/s390/include/asm/string.h +++ b/arch/s390/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 diff --git a/arch/s390/include/asm/switch_to.h b/arch/s390/include/asm/switch_to.h index f6c2b5814ab0..c21fe1d57c00 100644 --- a/arch/s390/include/asm/switch_to.h +++ b/arch/s390/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2009 * diff --git a/arch/s390/include/asm/termios.h b/arch/s390/include/asm/termios.h index db028d17f061..46fa3020b41e 100644 --- a/arch/s390/include/asm/termios.h +++ b/arch/s390/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 1aecf432c48d..0880a37b6d3b 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 2002, 2006 diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index 118535123f34..64539c221672 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999 @@ -15,6 +16,8 @@ /* The value of the TOD clock for 1.1.1970. */ #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL +extern u64 clock_comparator_max; + /* Inline functions for clock register access. */ static inline int set_tod_clock(__u64 time) { @@ -126,7 +129,7 @@ static inline unsigned long long local_tick_disable(void) unsigned long long old; old = S390_lowcore.clock_comparator; - S390_lowcore.clock_comparator = -1ULL; + S390_lowcore.clock_comparator = clock_comparator_max; set_clock_comparator(S390_lowcore.clock_comparator); return old; } @@ -174,24 +177,24 @@ static inline cycles_t get_cycles(void) return (cycles_t) get_tod_clock() >> 2; } -int get_phys_clock(unsigned long long *clock); +int get_phys_clock(unsigned long *clock); void init_cpu_timer(void); unsigned long long monotonic_clock(void); -extern u64 sched_clock_base_cc; +extern unsigned char tod_clock_base[16] __aligned(8); /** * get_clock_monotonic - returns current time in clock rate units * * The caller must ensure that preemption is disabled. - * The clock and sched_clock_base get changed via stop_machine. + * The clock and tod_clock_base get changed via stop_machine. * Therefore preemption must be disabled when calling this * function, otherwise the returned value is not guaranteed to * be monotonic. */ static inline unsigned long long get_tod_clock_monotonic(void) { - return get_tod_clock() - sched_clock_base_cc; + return get_tod_clock() - *(unsigned long long *) &tod_clock_base[1]; } /** @@ -218,4 +221,32 @@ static inline unsigned long long tod_to_ns(unsigned long long todval) return ((todval >> 9) * 125) + (((todval & 0x1ff) * 125) >> 9); } +/** + * tod_after - compare two 64 bit TOD values + * @a: first 64 bit TOD timestamp + * @b: second 64 bit TOD timestamp + * + * Returns: true if a is later than b + */ +static inline int tod_after(unsigned long long a, unsigned long long b) +{ + if (MACHINE_HAS_SCC) + return (long long) a > (long long) b; + return a > b; +} + +/** + * tod_after_eq - compare two 64 bit TOD values + * @a: first 64 bit TOD timestamp + * @b: second 64 bit TOD timestamp + * + * Returns: true if a is later than b + */ +static inline int tod_after_eq(unsigned long long a, unsigned long long b) +{ + if (MACHINE_HAS_SCC) + return (long long) a >= (long long) b; + return a >= b; +} + #endif diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index 2eb8ff0d6fca..457b7ba0fbb6 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _S390_TLB_H #define _S390_TLB_H @@ -135,7 +136,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, unsigned long address) { - if (tlb->mm->context.asce_limit <= (1UL << 31)) + if (tlb->mm->context.asce_limit <= _REGION3_SIZE) return; pgtable_pmd_page_dtor(virt_to_page(pmd)); tlb_remove_table(tlb, pmd); @@ -151,7 +152,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, unsigned long address) { - if (tlb->mm->context.asce_limit <= (1UL << 53)) + if (tlb->mm->context.asce_limit <= _REGION1_SIZE) return; tlb_remove_table(tlb, p4d); } @@ -166,7 +167,7 @@ static inline void p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d, static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, unsigned long address) { - if (tlb->mm->context.asce_limit <= (1UL << 42)) + if (tlb->mm->context.asce_limit <= _REGION2_SIZE) return; tlb_remove_table(tlb, pud); } diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h index 39846100682a..8c840f0904f3 100644 --- a/arch/s390/include/asm/tlbflush.h +++ b/arch/s390/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _S390_TLBFLUSH_H #define _S390_TLBFLUSH_H @@ -20,10 +21,15 @@ static inline void __tlb_flush_local(void) */ static inline void __tlb_flush_idte(unsigned long asce) { + unsigned long opt; + + opt = IDTE_PTOA; + if (MACHINE_HAS_TLB_GUEST) + opt |= IDTE_GUEST_ASCE; /* Global TLB flush for the mm */ asm volatile( " .insn rrf,0xb98e0000,0,%0,%1,0" - : : "a" (2048), "a" (asce) : "cc"); + : : "a" (opt), "a" (asce) : "cc"); } #ifdef CONFIG_SMP @@ -43,23 +49,6 @@ static inline void __tlb_flush_global(void) * Flush TLB entries for a specific mm on all CPUs (in case gmap is used * this implicates multiple ASCEs!). */ -static inline void __tlb_flush_full(struct mm_struct *mm) -{ - preempt_disable(); - atomic_inc(&mm->context.flush_count); - if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) { - /* Local TLB flush */ - __tlb_flush_local(); - } else { - /* Global TLB flush */ - __tlb_flush_global(); - /* Reset TLB flush mask */ - cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); - } - atomic_dec(&mm->context.flush_count); - preempt_enable(); -} - static inline void __tlb_flush_mm(struct mm_struct *mm) { unsigned long gmap_asce; @@ -71,16 +60,18 @@ static inline void __tlb_flush_mm(struct mm_struct *mm) */ preempt_disable(); atomic_inc(&mm->context.flush_count); + /* Reset TLB flush mask */ + cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); + barrier(); gmap_asce = READ_ONCE(mm->context.gmap_asce); if (MACHINE_HAS_IDTE && gmap_asce != -1UL) { if (gmap_asce) __tlb_flush_idte(gmap_asce); __tlb_flush_idte(mm->context.asce); } else { - __tlb_flush_full(mm); + /* Global TLB flush */ + __tlb_flush_global(); } - /* Reset TLB flush mask */ - cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask); atomic_dec(&mm->context.flush_count); preempt_enable(); } @@ -94,7 +85,6 @@ static inline void __tlb_flush_kernel(void) } #else #define __tlb_flush_global() __tlb_flush_local() -#define __tlb_flush_full(mm) __tlb_flush_local() /* * Flush TLB entries for a specific ASCE on all CPUs. @@ -112,10 +102,12 @@ static inline void __tlb_flush_kernel(void) static inline void __tlb_flush_mm_lazy(struct mm_struct * mm) { + spin_lock(&mm->context.lock); if (mm->context.flush_mm) { - __tlb_flush_mm(mm); mm->context.flush_mm = 0; + __tlb_flush_mm(mm); } + spin_unlock(&mm->context.lock); } /* diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index fa1bfce10370..55de4eb73604 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_TOPOLOGY_H #define _ASM_S390_TOPOLOGY_H @@ -77,12 +78,6 @@ static inline const struct cpumask *cpumask_of_node(int node) return &node_to_cpumask_map[node]; } -/* - * Returns the number of the node containing node 'node'. This - * architecture is flat, so it is a pretty simple function! - */ -#define parent_node(node) (node) - #define pcibus_to_node(bus) __pcibus_to_node(bus) #define node_distance(a, b) __node_distance(a, b) diff --git a/arch/s390/include/asm/trace/diag.h b/arch/s390/include/asm/trace/diag.h index cc6cfe7889da..22fcac4ff9f0 100644 --- a/arch/s390/include/asm/trace/diag.h +++ b/arch/s390/include/asm/trace/diag.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Tracepoint header for s390 diagnose calls * diff --git a/arch/s390/include/asm/trace/zcrypt.h b/arch/s390/include/asm/trace/zcrypt.h index adcb77fafa9d..457ddaa99e19 100644 --- a/arch/s390/include/asm/trace/zcrypt.h +++ b/arch/s390/include/asm/trace/zcrypt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Tracepoint definitions for the s390 zcrypt device driver * diff --git a/arch/s390/include/asm/types.h b/arch/s390/include/asm/types.h deleted file mode 100644 index 6740f4f9781f..000000000000 --- a/arch/s390/include/asm/types.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * S390 version - * - * Derived from "include/asm-i386/types.h" - */ -#ifndef _S390_TYPES_H -#define _S390_TYPES_H - -#include - -#endif /* _S390_TYPES_H */ diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 304cfe44df50..cdd0f0d999e2 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * Copyright IBM Corp. 1999, 2000 diff --git a/arch/s390/include/asm/unaligned.h b/arch/s390/include/asm/unaligned.h deleted file mode 100644 index da9627afe5d8..000000000000 --- a/arch/s390/include/asm/unaligned.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _ASM_S390_UNALIGNED_H -#define _ASM_S390_UNALIGNED_H - -/* - * The S390 can do unaligned accesses itself. - */ -#include -#include - -#define get_unaligned __get_unaligned_be -#define put_unaligned __put_unaligned_be - -#endif /* _ASM_S390_UNALIGNED_H */ diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h index 3066031a73fe..7807093b73be 100644 --- a/arch/s390/include/asm/unistd.h +++ b/arch/s390/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * diff --git a/arch/s390/include/asm/uprobes.h b/arch/s390/include/asm/uprobes.h index 658393c65d7e..b60b3c7ef699 100644 --- a/arch/s390/include/asm/uprobes.h +++ b/arch/s390/include/asm/uprobes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * User-space Probes (UProbes) for s390 * diff --git a/arch/s390/include/asm/user.h b/arch/s390/include/asm/user.h index 6ed1d1886333..0ca572ced21b 100644 --- a/arch/s390/include/asm/user.h +++ b/arch/s390/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 version * diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index 88bdc477a843..bb2ce72300b0 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __S390_VDSO_H__ #define __S390_VDSO_H__ diff --git a/arch/s390/include/asm/vtime.h b/arch/s390/include/asm/vtime.h index af9896c53eb3..3622d4ebc73a 100644 --- a/arch/s390/include/asm/vtime.h +++ b/arch/s390/include/asm/vtime.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _S390_VTIME_H #define _S390_VTIME_H diff --git a/arch/s390/include/asm/vtimer.h b/arch/s390/include/asm/vtimer.h index 10a179af62d8..42f707d1c1e8 100644 --- a/arch/s390/include/asm/vtimer.h +++ b/arch/s390/include/asm/vtimer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2003, 2012 * Virtual CPU timer diff --git a/arch/s390/include/asm/vx-insn.h b/arch/s390/include/asm/vx-insn.h index 49c24a2afce0..266a72320e05 100644 --- a/arch/s390/include/asm/vx-insn.h +++ b/arch/s390/include/asm/vx-insn.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Support for Vector Instructions * diff --git a/arch/s390/include/asm/xor.h b/arch/s390/include/asm/xor.h index c988df744a70..857d6759b67f 100644 --- a/arch/s390/include/asm/xor.h +++ b/arch/s390/include/asm/xor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Optimited xor routines * diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild index ca62066895e0..098f28778a13 100644 --- a/arch/s390/include/uapi/asm/Kbuild +++ b/arch/s390/include/uapi/asm/Kbuild @@ -9,4 +9,5 @@ generic-y += param.h generic-y += poll.h generic-y += resource.h generic-y += sockios.h +generic-y += swab.h generic-y += termbits.h diff --git a/arch/s390/include/uapi/asm/auxvec.h b/arch/s390/include/uapi/asm/auxvec.h index c53e08442255..a056c4637ffc 100644 --- a/arch/s390/include/uapi/asm/auxvec.h +++ b/arch/s390/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASMS390_AUXVEC_H #define __ASMS390_AUXVEC_H diff --git a/arch/s390/include/uapi/asm/bitsperlong.h b/arch/s390/include/uapi/asm/bitsperlong.h index 6b235aea9c66..cceaf47b021a 100644 --- a/arch/s390/include/uapi/asm/bitsperlong.h +++ b/arch/s390/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_S390_BITSPERLONG_H #define __ASM_S390_BITSPERLONG_H diff --git a/arch/s390/include/uapi/asm/byteorder.h b/arch/s390/include/uapi/asm/byteorder.h index a332e59e26fc..1442b57dd91b 100644 --- a/arch/s390/include/uapi/asm/byteorder.h +++ b/arch/s390/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _S390_BYTEORDER_H #define _S390_BYTEORDER_H diff --git a/arch/s390/include/uapi/asm/chpid.h b/arch/s390/include/uapi/asm/chpid.h index 6b4fb29cc197..2ae2ed8c0963 100644 --- a/arch/s390/include/uapi/asm/chpid.h +++ b/arch/s390/include/uapi/asm/chpid.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright IBM Corp. 2007, 2012 * Author(s): Peter Oberparleiter diff --git a/arch/s390/include/uapi/asm/chsc.h b/arch/s390/include/uapi/asm/chsc.h index 65dc694725a8..dc329aa03f76 100644 --- a/arch/s390/include/uapi/asm/chsc.h +++ b/arch/s390/include/uapi/asm/chsc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * ioctl interface for /dev/chsc * diff --git a/arch/s390/include/uapi/asm/clp.h b/arch/s390/include/uapi/asm/clp.h index ab72d9d24373..b36d9e9cdde6 100644 --- a/arch/s390/include/uapi/asm/clp.h +++ b/arch/s390/include/uapi/asm/clp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * ioctl interface for /dev/clp * diff --git a/arch/s390/include/uapi/asm/cmb.h b/arch/s390/include/uapi/asm/cmb.h index 0c086d00d89e..ecbe94941403 100644 --- a/arch/s390/include/uapi/asm/cmb.h +++ b/arch/s390/include/uapi/asm/cmb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPIS390_CMB_H #define _UAPIS390_CMB_H diff --git a/arch/s390/include/uapi/asm/dasd.h b/arch/s390/include/uapi/asm/dasd.h index 1340311dab77..451c601406b6 100644 --- a/arch/s390/include/uapi/asm/dasd.h +++ b/arch/s390/include/uapi/asm/dasd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Author(s)......: Holger Smolinski * Bugreports.to..: @@ -72,7 +73,10 @@ typedef struct dasd_information2_t { * 0x02: use diag discipline (diag) * 0x04: set the device initially online (internal use only) * 0x08: enable ERP related logging - * 0x20: give access to raw eckd data + * 0x10: allow I/O to fail on lost paths + * 0x20: allow I/O to fail when a lock was stolen + * 0x40: give access to raw eckd data + * 0x80: enable discard support */ #define DASD_FEATURE_DEFAULT 0x00 #define DASD_FEATURE_READONLY 0x01 @@ -82,6 +86,7 @@ typedef struct dasd_information2_t { #define DASD_FEATURE_FAILFAST 0x10 #define DASD_FEATURE_FAILONSLCK 0x20 #define DASD_FEATURE_USERAW 0x40 +#define DASD_FEATURE_DISCARD 0x80 #define DASD_PARTN_BITS 2 diff --git a/arch/s390/include/uapi/asm/debug.h b/arch/s390/include/uapi/asm/debug.h index c59fc79125f2..c7c564d9aea4 100644 --- a/arch/s390/include/uapi/asm/debug.h +++ b/arch/s390/include/uapi/asm/debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S/390 debug facility * diff --git a/arch/s390/include/uapi/asm/guarded_storage.h b/arch/s390/include/uapi/asm/guarded_storage.h index 852850e8e17e..666af1c33b59 100644 --- a/arch/s390/include/uapi/asm/guarded_storage.h +++ b/arch/s390/include/uapi/asm/guarded_storage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _GUARDED_STORAGE_H #define _GUARDED_STORAGE_H diff --git a/arch/s390/include/uapi/asm/hypfs.h b/arch/s390/include/uapi/asm/hypfs.h index b3fe12d8dd87..fe6174e142cf 100644 --- a/arch/s390/include/uapi/asm/hypfs.h +++ b/arch/s390/include/uapi/asm/hypfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Structures for hypfs interface * diff --git a/arch/s390/include/uapi/asm/ioctls.h b/arch/s390/include/uapi/asm/ioctls.h index 960a4c1ebdf1..342a3284e69a 100644 --- a/arch/s390/include/uapi/asm/ioctls.h +++ b/arch/s390/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ARCH_S390_IOCTLS_H__ #define __ARCH_S390_IOCTLS_H__ diff --git a/arch/s390/include/uapi/asm/ipcbuf.h b/arch/s390/include/uapi/asm/ipcbuf.h index 37f293d12c8f..5b1c4f47c656 100644 --- a/arch/s390/include/uapi/asm/ipcbuf.h +++ b/arch/s390/include/uapi/asm/ipcbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __S390_IPCBUF_H__ #define __S390_IPCBUF_H__ diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h index 69d09c39bbcd..9ad172dcd912 100644 --- a/arch/s390/include/uapi/asm/kvm.h +++ b/arch/s390/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __LINUX_KVM_S390_H #define __LINUX_KVM_S390_H /* @@ -88,6 +89,12 @@ struct kvm_s390_io_adapter_req { /* kvm attributes for KVM_S390_VM_TOD */ #define KVM_S390_VM_TOD_LOW 0 #define KVM_S390_VM_TOD_HIGH 1 +#define KVM_S390_VM_TOD_EXT 2 + +struct kvm_s390_vm_tod_clock { + __u8 epoch_idx; + __u64 tod; +}; /* kvm attributes for KVM_S390_VM_CPU_MODEL */ /* processor related attributes are r/w */ diff --git a/arch/s390/include/uapi/asm/kvm_para.h b/arch/s390/include/uapi/asm/kvm_para.h index ff1f4e7b3015..0dc86b3a7cb0 100644 --- a/arch/s390/include/uapi/asm/kvm_para.h +++ b/arch/s390/include/uapi/asm/kvm_para.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * User API definitions for paravirtual devices on s390 * diff --git a/arch/s390/include/uapi/asm/kvm_perf.h b/arch/s390/include/uapi/asm/kvm_perf.h index 397282727e21..c36c97ffdc6f 100644 --- a/arch/s390/include/uapi/asm/kvm_perf.h +++ b/arch/s390/include/uapi/asm/kvm_perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Definitions for perf-kvm on s390 * diff --git a/arch/s390/include/uapi/asm/kvm_virtio.h b/arch/s390/include/uapi/asm/kvm_virtio.h index 44a438ca9e72..73283677a132 100644 --- a/arch/s390/include/uapi/asm/kvm_virtio.h +++ b/arch/s390/include/uapi/asm/kvm_virtio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * definition for virtio for kvm on s390 * diff --git a/arch/s390/include/uapi/asm/monwriter.h b/arch/s390/include/uapi/asm/monwriter.h index f845c8e2f861..03d172f314a3 100644 --- a/arch/s390/include/uapi/asm/monwriter.h +++ b/arch/s390/include/uapi/asm/monwriter.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright IBM Corp. 2006 * Character device driver for writing z/VM APPLDATA monitor records diff --git a/arch/s390/include/uapi/asm/msgbuf.h b/arch/s390/include/uapi/asm/msgbuf.h index 1bbdee927924..604f847cd68c 100644 --- a/arch/s390/include/uapi/asm/msgbuf.h +++ b/arch/s390/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _S390_MSGBUF_H #define _S390_MSGBUF_H diff --git a/arch/s390/include/uapi/asm/pkey.h b/arch/s390/include/uapi/asm/pkey.h index e6c04faf8a6c..6f84a53c3270 100644 --- a/arch/s390/include/uapi/asm/pkey.h +++ b/arch/s390/include/uapi/asm/pkey.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Userspace interface to the pkey device driver * diff --git a/arch/s390/include/uapi/asm/posix_types.h b/arch/s390/include/uapi/asm/posix_types.h index bf2a2ad2f800..2a3fc638414b 100644 --- a/arch/s390/include/uapi/asm/posix_types.h +++ b/arch/s390/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 77630c74f13b..0d23c8ff2900 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * Copyright IBM Corp. 1999, 2000 diff --git a/arch/s390/include/uapi/asm/qeth.h b/arch/s390/include/uapi/asm/qeth.h index 3a896cf52589..fac9995dfe33 100644 --- a/arch/s390/include/uapi/asm/qeth.h +++ b/arch/s390/include/uapi/asm/qeth.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * ioctl definitions for qeth driver * diff --git a/arch/s390/include/uapi/asm/schid.h b/arch/s390/include/uapi/asm/schid.h index 32f3ab2a8200..58fca6f48410 100644 --- a/arch/s390/include/uapi/asm/schid.h +++ b/arch/s390/include/uapi/asm/schid.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPIASM_SCHID_H #define _UAPIASM_SCHID_H diff --git a/arch/s390/include/uapi/asm/sclp_ctl.h b/arch/s390/include/uapi/asm/sclp_ctl.h index f2818613ee41..e4e8c4dcd126 100644 --- a/arch/s390/include/uapi/asm/sclp_ctl.h +++ b/arch/s390/include/uapi/asm/sclp_ctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * IOCTL interface for SCLP * diff --git a/arch/s390/include/uapi/asm/sembuf.h b/arch/s390/include/uapi/asm/sembuf.h index 32626b0cac4b..3e917697b668 100644 --- a/arch/s390/include/uapi/asm/sembuf.h +++ b/arch/s390/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _S390_SEMBUF_H #define _S390_SEMBUF_H diff --git a/arch/s390/include/uapi/asm/setup.h b/arch/s390/include/uapi/asm/setup.h index 5a637e3e385e..1f8803a31079 100644 --- a/arch/s390/include/uapi/asm/setup.h +++ b/arch/s390/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * Copyright IBM Corp. 1999, 2010 diff --git a/arch/s390/include/uapi/asm/shmbuf.h b/arch/s390/include/uapi/asm/shmbuf.h index eed2e280ce37..9cdce8d7ce60 100644 --- a/arch/s390/include/uapi/asm/shmbuf.h +++ b/arch/s390/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _S390_SHMBUF_H #define _S390_SHMBUF_H diff --git a/arch/s390/include/uapi/asm/sie.h b/arch/s390/include/uapi/asm/sie.h index 3ac634368939..6ca1e68d7103 100644 --- a/arch/s390/include/uapi/asm/sie.h +++ b/arch/s390/include/uapi/asm/sie.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_S390_SIE_H #define _UAPI_ASM_S390_SIE_H diff --git a/arch/s390/include/uapi/asm/sigcontext.h b/arch/s390/include/uapi/asm/sigcontext.h index 5f0b8d7ddb0b..8b35033334c4 100644 --- a/arch/s390/include/uapi/asm/sigcontext.h +++ b/arch/s390/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * Copyright IBM Corp. 1999, 2000 diff --git a/arch/s390/include/uapi/asm/siginfo.h b/arch/s390/include/uapi/asm/siginfo.h index 91fd3e4b70ce..6984820f2f1c 100644 --- a/arch/s390/include/uapi/asm/siginfo.h +++ b/arch/s390/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/signal.h b/arch/s390/include/uapi/asm/signal.h index 2f43cfbf5f1a..c57f9d28d894 100644 --- a/arch/s390/include/uapi/asm/signal.h +++ b/arch/s390/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index 52a63f4175cb..3510c0fd06f4 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * @@ -108,4 +109,6 @@ #define SO_PEERGROUPS 59 +#define SO_ZEROCOPY 60 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/s390/include/uapi/asm/stat.h b/arch/s390/include/uapi/asm/stat.h index b4ca97d91466..ac253d23606b 100644 --- a/arch/s390/include/uapi/asm/stat.h +++ b/arch/s390/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/statfs.h b/arch/s390/include/uapi/asm/statfs.h index 471eb09184d4..72604f7792c3 100644 --- a/arch/s390/include/uapi/asm/statfs.h +++ b/arch/s390/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/swab.h b/arch/s390/include/uapi/asm/swab.h deleted file mode 100644 index da3bfe5cc161..000000000000 --- a/arch/s390/include/uapi/asm/swab.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef _S390_SWAB_H -#define _S390_SWAB_H - -/* - * S390 version - * Copyright IBM Corp. 1999 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) - */ - -#include - -#ifndef __s390x__ -# define __SWAB_64_THRU_32__ -#endif - -#ifdef __s390x__ -static inline __u64 __arch_swab64p(const __u64 *x) -{ - __u64 result; - - asm volatile("lrvg %0,%1" : "=d" (result) : "m" (*x)); - return result; -} -#define __arch_swab64p __arch_swab64p - -static inline __u64 __arch_swab64(__u64 x) -{ - __u64 result; - - asm volatile("lrvgr %0,%1" : "=d" (result) : "d" (x)); - return result; -} -#define __arch_swab64 __arch_swab64 - -static inline void __arch_swab64s(__u64 *x) -{ - *x = __arch_swab64p(x); -} -#define __arch_swab64s __arch_swab64s -#endif /* __s390x__ */ - -static inline __u32 __arch_swab32p(const __u32 *x) -{ - __u32 result; - - asm volatile( -#ifndef __s390x__ - " icm %0,8,%O1+3(%R1)\n" - " icm %0,4,%O1+2(%R1)\n" - " icm %0,2,%O1+1(%R1)\n" - " ic %0,%1" - : "=&d" (result) : "Q" (*x) : "cc"); -#else /* __s390x__ */ - " lrv %0,%1" - : "=d" (result) : "m" (*x)); -#endif /* __s390x__ */ - return result; -} -#define __arch_swab32p __arch_swab32p - -#ifdef __s390x__ -static inline __u32 __arch_swab32(__u32 x) -{ - __u32 result; - - asm volatile("lrvr %0,%1" : "=d" (result) : "d" (x)); - return result; -} -#define __arch_swab32 __arch_swab32 -#endif /* __s390x__ */ - -static inline __u16 __arch_swab16p(const __u16 *x) -{ - __u16 result; - - asm volatile( -#ifndef __s390x__ - " icm %0,2,%O1+1(%R1)\n" - " ic %0,%1\n" - : "=&d" (result) : "Q" (*x) : "cc"); -#else /* __s390x__ */ - " lrvh %0,%1" - : "=d" (result) : "m" (*x)); -#endif /* __s390x__ */ - return result; -} -#define __arch_swab16p __arch_swab16p - -#endif /* _S390_SWAB_H */ diff --git a/arch/s390/include/uapi/asm/tape390.h b/arch/s390/include/uapi/asm/tape390.h index b2bc4bab7929..90266c696486 100644 --- a/arch/s390/include/uapi/asm/tape390.h +++ b/arch/s390/include/uapi/asm/tape390.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /************************************************************************* * * enables user programs to display messages and control encryption diff --git a/arch/s390/include/uapi/asm/termios.h b/arch/s390/include/uapi/asm/termios.h index 554f973db1e6..54223169c806 100644 --- a/arch/s390/include/uapi/asm/termios.h +++ b/arch/s390/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/types.h b/arch/s390/include/uapi/asm/types.h index 3c3951e3415b..da034c606314 100644 --- a/arch/s390/include/uapi/asm/types.h +++ b/arch/s390/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/ucontext.h b/arch/s390/include/uapi/asm/ucontext.h index 64a69aa5dde0..c95f42e85337 100644 --- a/arch/s390/include/uapi/asm/ucontext.h +++ b/arch/s390/include/uapi/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index ea42290e7d51..b52bce8ee941 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * S390 version * diff --git a/arch/s390/include/uapi/asm/virtio-ccw.h b/arch/s390/include/uapi/asm/virtio-ccw.h index a9a4ebf79fa7..967aad390105 100644 --- a/arch/s390/include/uapi/asm/virtio-ccw.h +++ b/arch/s390/include/uapi/asm/virtio-ccw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Definitions for virtio-ccw devices. * diff --git a/drivers/s390/char/vmcp.h b/arch/s390/include/uapi/asm/vmcp.h similarity index 56% rename from drivers/s390/char/vmcp.h rename to arch/s390/include/uapi/asm/vmcp.h index 1e29b0418382..4caf71714a55 100644 --- a/drivers/s390/char/vmcp.h +++ b/arch/s390/include/uapi/asm/vmcp.h @@ -12,19 +12,13 @@ * The idea of this driver is based on cpint from Neale Ferguson */ +#ifndef _UAPI_ASM_VMCP_H +#define _UAPI_ASM_VMCP_H + #include -#include -#define VMCP_GETCODE _IOR(0x10, 1, int) -#define VMCP_SETBUF _IOW(0x10, 2, int) -#define VMCP_GETSIZE _IOR(0x10, 3, int) +#define VMCP_GETCODE _IOR(0x10, 1, int) +#define VMCP_SETBUF _IOW(0x10, 2, int) +#define VMCP_GETSIZE _IOR(0x10, 3, int) -struct vmcp_session { - unsigned int bufsize; - char *response; - int resp_size; - int resp_code; - /* As we use copy_from/to_user, which might * - * sleep and cannot use a spinlock */ - struct mutex mutex; -}; +#endif /* _UAPI_ASM_VMCP_H */ diff --git a/arch/s390/include/uapi/asm/vtoc.h b/arch/s390/include/uapi/asm/vtoc.h index 221419de275e..50c1d7b9e844 100644 --- a/arch/s390/include/uapi/asm/vtoc.h +++ b/arch/s390/include/uapi/asm/vtoc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file contains volume label definitions for DASD devices. * diff --git a/arch/s390/include/uapi/asm/zcrypt.h b/arch/s390/include/uapi/asm/zcrypt.h index a777f87ef889..137ef473584e 100644 --- a/arch/s390/include/uapi/asm/zcrypt.h +++ b/arch/s390/include/uapi/asm/zcrypt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * include/asm-s390/zcrypt.h * diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index adb3fe2e3d42..4ce2d05929a7 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/s390/kernel/als.c b/arch/s390/kernel/als.c index 14769eb52a33..d1892bf36cab 100644 --- a/arch/s390/kernel/als.c +++ b/arch/s390/kernel/als.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2016 */ diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index b65c414b6c0e..0e6d2b032484 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generate definitions needed by assembly language modules. * This code generates raw asm output which is post-processed to extract @@ -158,6 +159,7 @@ int main(void) OFFSET(__LC_LAST_UPDATE_CLOCK, lowcore, last_update_clock); OFFSET(__LC_INT_CLOCK, lowcore, int_clock); OFFSET(__LC_MCCK_CLOCK, lowcore, mcck_clock); + OFFSET(__LC_BOOT_CLOCK, lowcore, boot_clock); OFFSET(__LC_CURRENT, lowcore, current_task); OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack); OFFSET(__LC_ASYNC_STACK, lowcore, async_stack); diff --git a/arch/s390/kernel/audit.c b/arch/s390/kernel/audit.c index f4932c22ebe4..d395c6c9944c 100644 --- a/arch/s390/kernel/audit.c +++ b/arch/s390/kernel/audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/s390/kernel/audit.h b/arch/s390/kernel/audit.h index 12b56f4b5a73..4d4b596412ec 100644 --- a/arch/s390/kernel/audit.h +++ b/arch/s390/kernel/audit.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_S390_KERNEL_AUDIT_H #define __ARCH_S390_KERNEL_AUDIT_H diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 326f717df587..f6c56009e822 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/s390/kernel/base.S * diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c index c8a83276a4dc..d66825e53fce 100644 --- a/arch/s390/kernel/cache.c +++ b/arch/s390/kernel/cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Extract CPU cache information and expose them via sysfs. * diff --git a/arch/s390/kernel/compat_audit.c b/arch/s390/kernel/compat_audit.c index d6487bf879e5..444fb1f66944 100644 --- a/arch/s390/kernel/compat_audit.c +++ b/arch/s390/kernel/compat_audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #undef __s390x__ #include #include "audit.h" diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index a3d14161abcb..f04db3779b34 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 version * Copyright IBM Corp. 2000 diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h index a0a886c04977..64509e7dbd3b 100644 --- a/arch/s390/kernel/compat_linux.h +++ b/arch/s390/kernel/compat_linux.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390X_S390_H #define _ASM_S390X_S390_H diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h index 12b823833510..3c400fc7e987 100644 --- a/arch/s390/kernel/compat_ptrace.h +++ b/arch/s390/kernel/compat_ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PTRACE32_H #define _PTRACE32_H diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index c620049c61f2..a4a1208e3df3 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2000, 2006 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) @@ -75,35 +76,34 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_RT: err |= __put_user(from->si_int, &to->si_int); /* fallthrough */ - case __SI_KILL >> 16: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user((unsigned long) from->si_addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); @@ -127,32 +127,31 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) if (to->si_code < 0) err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (to->si_code >> 16) { - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + switch (siginfo_layout(to->si_signo, to->si_code)) { + case SIL_RT: err |= __get_user(to->si_int, &from->si_int); /* fallthrough */ - case __SI_KILL >> 16: + case SIL_KILL: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __get_user(to->si_pid, &from->si_pid); err |= __get_user(to->si_uid, &from->si_uid); err |= __get_user(to->si_utime, &from->si_utime); err |= __get_user(to->si_stime, &from->si_stime); err |= __get_user(to->si_status, &from->si_status); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __get_user(tmp, &from->si_addr); to->si_addr = (void __force __user *) (u64) (tmp & PSW32_ADDR_INSN); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __get_user(to->si_band, &from->si_band); err |= __get_user(to->si_fd, &from->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __get_user(to->si_tid, &from->si_tid); err |= __get_user(to->si_overrun, &from->si_overrun); err |= __get_user(to->si_int, &from->si_int); diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index 986642a3543b..d04918583971 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Compat system call wrappers. * diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 9f0e4a2785f7..af013b4244d3 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 version * Copyright IBM Corp. 1999, 2007 @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -28,9 +30,7 @@ static int diag8_noresponse(int cmdlen) register unsigned long reg3 asm ("3") = cmdlen; asm volatile( - " sam31\n" " diag %1,%0,0x8\n" - " sam64\n" : "+d" (reg3) : "d" (reg2) : "cc"); return reg3; } @@ -43,9 +43,7 @@ static int diag8_response(int cmdlen, char *response, int *rlen) register unsigned long reg5 asm ("5") = *rlen; asm volatile( - " sam31\n" " diag %2,%0,0x8\n" - " sam64\n" " brc 8,1f\n" " agr %1,%4\n" "1:\n" @@ -57,7 +55,6 @@ static int diag8_response(int cmdlen, char *response, int *rlen) /* * __cpcmd has some restrictions over cpcmd - * - the response buffer must reside below 2GB (if any) * - __cpcmd is unlocked and therefore not SMP-safe */ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) @@ -88,13 +85,12 @@ EXPORT_SYMBOL(__cpcmd); int cpcmd(const char *cmd, char *response, int rlen, int *response_code) { + unsigned long flags; char *lowbuf; int len; - unsigned long flags; - if ((virt_to_phys(response) != (unsigned long) response) || - (((unsigned long)response + rlen) >> 31)) { - lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); + if (is_vmalloc_or_module_addr(response)) { + lowbuf = kmalloc(rlen, GFP_KERNEL); if (!lowbuf) { pr_warn("The cpcmd kernel function failed to allocate a response buffer\n"); return -ENOMEM; diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index d628afc26708..9f5ea9d87069 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 kdump implementation * diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 86b3e74f569e..05a9cf4ae9c2 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S/390 debug facility * @@ -866,7 +867,8 @@ static inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, int exception) { - active->id.stck = get_tod_clock_fast() - sched_clock_base_cc; + active->id.stck = get_tod_clock_fast() - + *(unsigned long long *) &tod_clock_base[1]; active->id.fields.cpuid = smp_processor_id(); active->caller = __builtin_return_address(0); active->id.fields.exception = exception; @@ -1455,15 +1457,15 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, int area, debug_entry_t * entry, char *out_buf) { - unsigned long sec, usec; + unsigned long base, sec, usec; char *except_str; unsigned long caller; int rc = 0; unsigned int level; level = entry->id.fields.level; - sec = (entry->id.stck >> 12) + (sched_clock_base_cc >> 12); - sec = sec - (TOD_UNIX_EPOCH >> 12); + base = (*(unsigned long *) &tod_clock_base[0]) >> 4; + sec = (entry->id.stck >> 12) + base - (TOD_UNIX_EPOCH >> 12); usec = do_div(sec, USEC_PER_SEC); if (entry->id.fields.exception) diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c index 349914571772..53a5316cc4b7 100644 --- a/arch/s390/kernel/diag.c +++ b/arch/s390/kernel/diag.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implementation of s390 diagnose codes * diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index dab78babfab6..2aa545dca4d5 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -76,7 +76,7 @@ void dump_trace(dump_trace_func_t func, void *data, struct task_struct *task, frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); #ifdef CONFIG_CHECK_STACK sp = __dump_trace(func, data, sp, - S390_lowcore.panic_stack + frame_size - 4096, + S390_lowcore.panic_stack + frame_size - PAGE_SIZE, S390_lowcore.panic_stack + frame_size); #endif sp = __dump_trace(func, data, sp, diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 5d20182ee8ae..b945448b9eae 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2007, 2009 * Author(s): Hongjie Yang , @@ -53,8 +54,9 @@ static void __init reset_tod_clock(void) if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0) disabled_wait(0); - sched_clock_base_cc = TOD_UNIX_EPOCH; - S390_lowcore.last_update_clock = sched_clock_base_cc; + memset(tod_clock_base, 0, 16); + *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH; + S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; } #ifdef CONFIG_SHARED_KERNEL @@ -165,8 +167,8 @@ static noinline __init void create_kernel_nss(void) } /* re-initialize cputime accounting. */ - sched_clock_base_cc = get_tod_clock(); - S390_lowcore.last_update_clock = sched_clock_base_cc; + get_tod_clock_ext(tod_clock_base); + S390_lowcore.last_update_clock = *(__u64 *) &tod_clock_base[1]; S390_lowcore.last_update_timer = 0x7fffffffffffffffULL; S390_lowcore.user_timer = 0; S390_lowcore.system_timer = 0; @@ -387,6 +389,12 @@ static __init void detect_machine_facilities(void) } if (test_facility(133)) S390_lowcore.machine_flags |= MACHINE_FLAG_GS; + if (test_facility(139) && (tod_clock_base[1] & 0x80)) { + /* Enabled signed clock comparator comparisons */ + S390_lowcore.machine_flags |= MACHINE_FLAG_SCC; + clock_comparator_max = -1ULL >> 1; + __ctl_set_bit(0, 53); + } } static inline void save_vector_registers(void) @@ -397,23 +405,11 @@ static inline void save_vector_registers(void) #endif } -static int __init topology_setup(char *str) -{ - bool enabled; - int rc; - - rc = kstrtobool(str, &enabled); - if (!rc && !enabled) - S390_lowcore.machine_flags &= ~MACHINE_FLAG_TOPOLOGY; - return rc; -} -early_param("topology", topology_setup); - static int __init disable_vector_extension(char *str) { S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; __ctl_clear_bit(0, 17); - return 1; + return 0; } early_param("novx", disable_vector_extension); diff --git a/arch/s390/kernel/early_printk.c b/arch/s390/kernel/early_printk.c index 819cb15c67e8..9431784d7796 100644 --- a/arch/s390/kernel/early_printk.c +++ b/arch/s390/kernel/early_printk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2017 */ diff --git a/arch/s390/kernel/ebcdic.c b/arch/s390/kernel/ebcdic.c index 1d5392b36ad8..c15caeab1dbf 100644 --- a/arch/s390/kernel/ebcdic.c +++ b/arch/s390/kernel/ebcdic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ECBDIC -> ASCII, ASCII -> ECBDIC, * upper to lower case (EBCDIC) conversion tables. diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 21900e1cee9c..7c6904d616d8 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 low-level entry points. * @@ -521,12 +522,15 @@ ENTRY(pgm_check_handler) tmhh %r8,0x0001 # test problem state bit jnz 2f # -> fault in user space #if IS_ENABLED(CONFIG_KVM) - # cleanup critical section for sie64a + # cleanup critical section for program checks in sie64a lgr %r14,%r9 slg %r14,BASED(.Lsie_critical_start) clg %r14,BASED(.Lsie_critical_length) jhe 0f - brasl %r14,.Lcleanup_sie + lg %r14,__SF_EMPTY(%r15) # get control block pointer + ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE + lctlg %c1,%c1,__LC_USER_ASCE # load primary asce + larl %r9,sie_exit # skip forward to sie_exit #endif 0: tmhh %r8,0x4000 # PER bit set in old PSW ? jnz 1f # -> enabled, can't be a double fault diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index dbf5f7e18246..905bde782490 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ENTRY_H #define _ENTRY_H diff --git a/arch/s390/kernel/fpu.c b/arch/s390/kernel/fpu.c index 1235b9438df4..594464f2129d 100644 --- a/arch/s390/kernel/fpu.c +++ b/arch/s390/kernel/fpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * In-kernel vector facility support functions * diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index d03a6d12c4bd..dc76d813e420 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Dynamic function tracer architecture backend. * diff --git a/arch/s390/kernel/guarded_storage.c b/arch/s390/kernel/guarded_storage.c index 6f064745c3b1..bff39b66c9ff 100644 --- a/arch/s390/kernel/guarded_storage.c +++ b/arch/s390/kernel/guarded_storage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2016 * Author(s): Martin Schwidefsky diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index eff5b31671d4..b86fa3ee4927 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2010 * @@ -302,7 +303,8 @@ ENTRY(startup_kdump) xc 0xe00(256),0xe00 xc 0xf00(256),0xf00 lctlg %c0,%c15,0x200(%r0) # initialize control registers - stck __LC_LAST_UPDATE_CLOCK + stcke __LC_BOOT_CLOCK + mvc __LC_LAST_UPDATE_CLOCK(8),__LC_BOOT_CLOCK+1 spt 6f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) l %r15,.Lstack-.LPG0(%r13) diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 31c91f24e562..172002da7075 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 1999, 2010 * @@ -21,8 +22,8 @@ ENTRY(startup_continue) xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid mvi __LC_LPP,0x80 # and set LPP_MAGIC .insn s,0xb2800000,__LC_LPP # load program parameter -0: larl %r1,sched_clock_base_cc - mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK +0: larl %r1,tod_clock_base + mvc 0(16,%r1),__LC_BOOT_CLOCK larl %r13,.LPG1 # get base lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area diff --git a/arch/s390/kernel/head_kdump.S b/arch/s390/kernel/head_kdump.S index d05950f02c34..174d6959bf5b 100644 --- a/arch/s390/kernel/head_kdump.S +++ b/arch/s390/kernel/head_kdump.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 kdump lowlevel functions (new kernel) * diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index 9340b2a07935..b9d8fe45737a 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Idle functions for s390. * diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 6dca93b29bed..94f2099bceb0 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2004, 2011 * Author(s): Martin Schwidefsky , @@ -105,7 +106,8 @@ void do_IRQ(struct pt_regs *regs, int irq) old_regs = set_irq_regs(regs); irq_enter(); - if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) + if (tod_after_eq(S390_lowcore.int_clock, + S390_lowcore.clock_comparator)) /* Serve timer interrupts first. */ clock_comparator_work(); generic_handle_irq(irq); diff --git a/arch/s390/kernel/jump_label.c b/arch/s390/kernel/jump_label.c index 262506cee4c3..43f8430fb67d 100644 --- a/arch/s390/kernel/jump_label.c +++ b/arch/s390/kernel/jump_label.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Jump label s390 support * diff --git a/arch/s390/kernel/kdebugfs.c b/arch/s390/kernel/kdebugfs.c index ee85e17dd79d..2c46bd6c6fd2 100644 --- a/arch/s390/kernel/kdebugfs.c +++ b/arch/s390/kernel/kdebugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 3d0b14afa232..b0ba2c26b45e 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2005, 2011 * diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 9a17e4475d27..82df7d80fab2 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2008, 2009 * diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index 753ba63182b9..0a5e4bafb6ad 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * OS info memory interface * diff --git a/arch/s390/kernel/perf_cpum_cf_events.c b/arch/s390/kernel/perf_cpum_cf_events.c index d3133285b7d1..08bfa17ba0a0 100644 --- a/arch/s390/kernel/perf_cpum_cf_events.c +++ b/arch/s390/kernel/perf_cpum_cf_events.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Perf PMU sysfs events attributes for available CPU-measurement counters * diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index c1bf75ffb875..7e1e40323b78 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -823,9 +823,12 @@ static int cpumsf_pmu_event_init(struct perf_event *event) } /* Check online status of the CPU to which the event is pinned */ - if ((unsigned int)event->cpu >= nr_cpumask_bits || - (event->cpu >= 0 && !cpu_online(event->cpu))) - return -ENODEV; + if (event->cpu >= 0) { + if ((unsigned int)event->cpu >= nr_cpumask_bits) + return -ENODEV; + if (!cpu_online(event->cpu)) + return -ENODEV; + } /* Force reset of idle/hv excludes regardless of what the * user requested. diff --git a/arch/s390/kernel/pgm_check.S b/arch/s390/kernel/pgm_check.S index 036aa01d06a9..3e62aae34ea3 100644 --- a/arch/s390/kernel/pgm_check.S +++ b/arch/s390/kernel/pgm_check.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Program check table. * diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index bb32b8618bf6..a4a84fb08046 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file handles the architecture dependent parts of process handling. * diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index 778cd6536175..5362fd868d0d 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2008 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 252ed61a128b..1427d60ce628 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Ptrace user space interface. * diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index 89ea8c213d82..a40ebd1d29d0 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp 2000, 2011 * Author(s): Holger Smolinski , diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index cfac28330b03..ca37e5d5b40c 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright IBM Corp. 2005 * @@ -7,6 +8,7 @@ */ #include +#include #include /* @@ -55,8 +57,8 @@ ENTRY(relocate_kernel) .back_pgm: lmg %r0,%r15,gprregs-.base(%r13) .top: - lghi %r7,4096 # load PAGE_SIZE in r7 - lghi %r9,4096 # load PAGE_SIZE in r9 + lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7 + lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9 lg %r5,0(%r2) # read another word for indirection page aghi %r2,8 # increment pointer tml %r5,0x1 # is it a destination page? diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c index 429d3a782f1c..32aefb215e59 100644 --- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2012 * Author(s): Jan Glauber diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 3d1d808ea8a9..164a1e16b53e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -305,7 +305,7 @@ static void __init setup_lowcore(void) /* * Setup lowcore for boot cpu */ - BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096); + BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * PAGE_SIZE); lc = memblock_virt_alloc_low(sizeof(*lc), sizeof(*lc)); lc->restart_psw.mask = PSW_KERNEL_BITS; lc->restart_psw.addr = (unsigned long) restart_int_handler; @@ -323,7 +323,7 @@ static void __init setup_lowcore(void) lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT | PSW_MASK_MCHECK; lc->io_new_psw.addr = (unsigned long) io_int_handler; - lc->clock_comparator = -1ULL; + lc->clock_comparator = clock_comparator_max; lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); lc->async_stack = (unsigned long) @@ -469,10 +469,10 @@ static void __init setup_memory_end(void) vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN; tmp = (memory_end ?: max_physmem_end) / PAGE_SIZE; tmp = tmp * (sizeof(struct page) + PAGE_SIZE); - if (tmp + vmalloc_size + MODULES_LEN <= (1UL << 42)) - vmax = 1UL << 42; /* 3-level kernel page table */ + if (tmp + vmalloc_size + MODULES_LEN <= _REGION2_SIZE) + vmax = _REGION2_SIZE; /* 3-level kernel page table */ else - vmax = 1UL << 53; /* 4-level kernel page table */ + vmax = _REGION1_SIZE; /* 4-level kernel page table */ /* module area is at the end of the kernel address space. */ MODULES_END = vmax; MODULES_VADDR = MODULES_END - MODULES_LEN; @@ -818,6 +818,9 @@ static int __init setup_hwcaps(void) case 0x2965: strcpy(elf_platform, "z13"); break; + case 0x3906: + strcpy(elf_platform, "z14"); + break; } /* @@ -922,6 +925,7 @@ void __init setup_arch(char **cmdline_p) setup_memory_end(); setup_memory(); dma_contiguous_reserve(memory_end); + vmcp_cma_reserve(); check_initrd(); reserve_crashkernel(); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 289dd50f9744..2d2960ab3e10 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 1999, 2006 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 1020a11a24e5..092c4154abd7 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SMP related functions * @@ -293,7 +294,10 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) lc->lpp = LPP_MAGIC; lc->current_pid = tsk->pid; lc->user_timer = tsk->thread.user_timer; + lc->guest_timer = tsk->thread.guest_timer; lc->system_timer = tsk->thread.system_timer; + lc->hardirq_timer = tsk->thread.hardirq_timer; + lc->softirq_timer = tsk->thread.softirq_timer; lc->steal_timer = 0; } @@ -1181,6 +1185,7 @@ static int __init s390_smp_init(void) rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "s390/smp:online", smp_cpu_online, smp_cpu_pre_down); + rc = rc <= 0 ? rc : 0; out: return rc; } diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c index 39e2f41b6cf0..a8af9c825628 100644 --- a/arch/s390/kernel/suspend.c +++ b/arch/s390/kernel/suspend.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Suspend support specific for s390. * @@ -98,10 +99,16 @@ int page_key_alloc(unsigned long pages) */ void page_key_read(unsigned long *pfn) { + struct page *page; unsigned long addr; + unsigned char key; - addr = (unsigned long) page_address(pfn_to_page(*pfn)); - *(unsigned char *) pfn = (unsigned char) page_get_storage_key(addr); + page = pfn_to_page(*pfn); + addr = (unsigned long) page_address(page); + key = (unsigned char) page_get_storage_key(addr) & 0x7f; + if (arch_test_page_nodat(page)) + key |= 0x80; + *(unsigned char *) pfn = key; } /* @@ -126,8 +133,16 @@ void page_key_memorize(unsigned long *pfn) */ void page_key_write(void *address) { - page_set_storage_key((unsigned long) address, - page_key_rp->data[page_key_rx], 0); + struct page *page; + unsigned char key; + + key = page_key_rp->data[page_key_rx]; + page_set_storage_key((unsigned long) address, key & 0x7f, 0); + page = virt_to_page(address); + if (key & 0x80) + arch_set_page_nodat(page, 0); + else + arch_set_page_dat(page, 0); if (++page_key_rx >= PAGE_KEY_DATA_SIZE) return; page_key_rp = page_key_rp->next; diff --git a/arch/s390/kernel/swsusp.S b/arch/s390/kernel/swsusp.S index 6bebc935e9c2..e99187149f17 100644 --- a/arch/s390/kernel/swsusp.S +++ b/arch/s390/kernel/swsusp.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * S390 64-bit swsusp implementation * diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index b7af452978ca..0090037ab148 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 version * Copyright IBM Corp. 1999, 2000 diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 54fce7b065de..d39f121e67a9 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * definitions for sys_call_table, each line represents an * entry in the table in the form diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index fb869b103825..a441cba8d165 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2001, 2009 * Author(s): Ulrich Weigand , diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 192efdfac918..5cbd52169348 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -51,8 +51,15 @@ #include #include "entry.h" -u64 sched_clock_base_cc = -1; /* Force to data section. */ -EXPORT_SYMBOL_GPL(sched_clock_base_cc); +unsigned char tod_clock_base[16] __aligned(8) = { + /* Force to data section. */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; +EXPORT_SYMBOL_GPL(tod_clock_base); + +u64 clock_comparator_max = -1ULL; +EXPORT_SYMBOL_GPL(clock_comparator_max); static DEFINE_PER_CPU(struct clock_event_device, comparators); @@ -75,7 +82,7 @@ void __init time_early_init(void) struct ptff_qui qui; /* Initialize TOD steering parameters */ - tod_steering_end = sched_clock_base_cc; + tod_steering_end = *(unsigned long long *) &tod_clock_base[1]; vdso_data->ts_end = tod_steering_end; if (!test_facility(28)) @@ -111,22 +118,27 @@ unsigned long long monotonic_clock(void) } EXPORT_SYMBOL(monotonic_clock); -static void tod_to_timeval(__u64 todval, struct timespec64 *xt) +static void ext_to_timespec64(unsigned char *clk, struct timespec64 *xt) { - unsigned long long sec; + unsigned long long high, low, rem, sec, nsec; + + /* Split extendnd TOD clock to micro-seconds and sub-micro-seconds */ + high = (*(unsigned long long *) clk) >> 4; + low = (*(unsigned long long *)&clk[7]) << 4; + /* Calculate seconds and nano-seconds */ + sec = high; + rem = do_div(sec, 1000000); + nsec = (((low >> 32) + (rem << 32)) * 1000) >> 32; - sec = todval >> 12; - do_div(sec, 1000000); xt->tv_sec = sec; - todval -= (sec * 1000000) << 12; - xt->tv_nsec = ((todval * 1000) >> 12); + xt->tv_nsec = nsec; } void clock_comparator_work(void) { struct clock_event_device *cd; - S390_lowcore.clock_comparator = -1ULL; + S390_lowcore.clock_comparator = clock_comparator_max; cd = this_cpu_ptr(&comparators); cd->event_handler(cd); } @@ -148,7 +160,7 @@ void init_cpu_timer(void) struct clock_event_device *cd; int cpu; - S390_lowcore.clock_comparator = -1ULL; + S390_lowcore.clock_comparator = clock_comparator_max; set_clock_comparator(S390_lowcore.clock_comparator); cpu = smp_processor_id(); @@ -179,7 +191,7 @@ static void clock_comparator_interrupt(struct ext_code ext_code, unsigned long param64) { inc_irq_stat(IRQEXT_CLK); - if (S390_lowcore.clock_comparator == -1ULL) + if (S390_lowcore.clock_comparator == clock_comparator_max) set_clock_comparator(S390_lowcore.clock_comparator); } @@ -197,18 +209,28 @@ static void stp_reset(void); void read_persistent_clock64(struct timespec64 *ts) { - __u64 clock; + unsigned char clk[STORE_CLOCK_EXT_SIZE]; + __u64 delta; - clock = get_tod_clock() - initial_leap_seconds; - tod_to_timeval(clock - TOD_UNIX_EPOCH, ts); + delta = initial_leap_seconds + TOD_UNIX_EPOCH; + get_tod_clock_ext(clk); + *(__u64 *) &clk[1] -= delta; + if (*(__u64 *) &clk[1] > delta) + clk[0]--; + ext_to_timespec64(clk, ts); } void read_boot_clock64(struct timespec64 *ts) { - __u64 clock; + unsigned char clk[STORE_CLOCK_EXT_SIZE]; + __u64 delta; - clock = sched_clock_base_cc - initial_leap_seconds; - tod_to_timeval(clock - TOD_UNIX_EPOCH, ts); + delta = initial_leap_seconds + TOD_UNIX_EPOCH; + memcpy(clk, tod_clock_base, 16); + *(__u64 *) &clk[1] -= delta; + if (*(__u64 *) &clk[1] > delta) + clk[0]--; + ext_to_timespec64(clk, ts); } static u64 read_tod_clock(struct clocksource *cs) @@ -335,7 +357,7 @@ static unsigned long clock_sync_flags; * source. If the clock mode is local it will return -EOPNOTSUPP and * -EAGAIN if the clock is not in sync with the external reference. */ -int get_phys_clock(unsigned long long *clock) +int get_phys_clock(unsigned long *clock) { atomic_t *sw_ptr; unsigned int sw0, sw1; @@ -406,7 +428,10 @@ static void clock_sync_global(unsigned long long delta) struct ptff_qto qto; /* Fixup the monotonic sched clock. */ - sched_clock_base_cc += delta; + *(unsigned long long *) &tod_clock_base[1] += delta; + if (*(unsigned long long *) &tod_clock_base[1] < delta) + /* Epoch overflow */ + tod_clock_base[0]++; /* Adjust TOD steering parameters. */ vdso_data->tb_update_count++; now = get_tod_clock(); @@ -437,7 +462,7 @@ static void clock_sync_global(unsigned long long delta) static void clock_sync_local(unsigned long long delta) { /* Add the delta to the clock comparator. */ - if (S390_lowcore.clock_comparator != -1ULL) { + if (S390_lowcore.clock_comparator != clock_comparator_max) { S390_lowcore.clock_comparator += delta; set_clock_comparator(S390_lowcore.clock_comparator); } diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index bb47c92476f0..ed0bdd220e1a 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -8,6 +8,8 @@ #include #include +#include +#include #include #include #include @@ -29,12 +31,20 @@ #define PTF_VERTICAL (1UL) #define PTF_CHECK (2UL) +enum { + TOPOLOGY_MODE_HW, + TOPOLOGY_MODE_SINGLE, + TOPOLOGY_MODE_PACKAGE, + TOPOLOGY_MODE_UNINITIALIZED +}; + struct mask_info { struct mask_info *next; unsigned char id; cpumask_t mask; }; +static int topology_mode = TOPOLOGY_MODE_UNINITIALIZED; static void set_topology_timer(void); static void topology_work_fn(struct work_struct *work); static struct sysinfo_15_1_x *tl_info; @@ -59,11 +69,26 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) cpumask_t mask; cpumask_copy(&mask, cpumask_of(cpu)); - if (!MACHINE_HAS_TOPOLOGY) - return mask; - for (; info; info = info->next) { - if (cpumask_test_cpu(cpu, &info->mask)) - return info->mask; + switch (topology_mode) { + case TOPOLOGY_MODE_HW: + while (info) { + if (cpumask_test_cpu(cpu, &info->mask)) { + mask = info->mask; + break; + } + info = info->next; + } + if (cpumask_empty(&mask)) + cpumask_copy(&mask, cpumask_of(cpu)); + break; + case TOPOLOGY_MODE_PACKAGE: + cpumask_copy(&mask, cpu_present_mask); + break; + default: + /* fallthrough */ + case TOPOLOGY_MODE_SINGLE: + cpumask_copy(&mask, cpumask_of(cpu)); + break; } return mask; } @@ -74,7 +99,7 @@ static cpumask_t cpu_thread_map(unsigned int cpu) int i; cpumask_copy(&mask, cpumask_of(cpu)); - if (!MACHINE_HAS_TOPOLOGY) + if (topology_mode != TOPOLOGY_MODE_HW) return mask; cpu -= cpu % (smp_cpu_mtid + 1); for (i = 0; i <= smp_cpu_mtid; i++) @@ -184,10 +209,8 @@ static void topology_update_polarization_simple(void) { int cpu; - mutex_lock(&smp_cpu_state_mutex); for_each_possible_cpu(cpu) smp_cpu_set_polarization(cpu, POLARIZATION_HRZ); - mutex_unlock(&smp_cpu_state_mutex); } static int ptf(unsigned long fc) @@ -223,7 +246,7 @@ int topology_set_cpu_management(int fc) static void update_cpu_masks(void) { struct cpu_topology_s390 *topo; - int cpu; + int cpu, id; for_each_possible_cpu(cpu) { topo = &cpu_topology[cpu]; @@ -231,12 +254,13 @@ static void update_cpu_masks(void) topo->core_mask = cpu_group_map(&socket_info, cpu); topo->book_mask = cpu_group_map(&book_info, cpu); topo->drawer_mask = cpu_group_map(&drawer_info, cpu); - if (!MACHINE_HAS_TOPOLOGY) { + if (topology_mode != TOPOLOGY_MODE_HW) { + id = topology_mode == TOPOLOGY_MODE_PACKAGE ? 0 : cpu; topo->thread_id = cpu; topo->core_id = cpu; - topo->socket_id = cpu; - topo->book_id = cpu; - topo->drawer_id = cpu; + topo->socket_id = id; + topo->book_id = id; + topo->drawer_id = id; if (cpu_present(cpu)) cpumask_set_cpu(cpu, &cpus_with_topology); } @@ -254,6 +278,7 @@ static int __arch_update_cpu_topology(void) struct sysinfo_15_1_x *info = tl_info; int rc = 0; + mutex_lock(&smp_cpu_state_mutex); cpumask_clear(&cpus_with_topology); if (MACHINE_HAS_TOPOLOGY) { rc = 1; @@ -263,6 +288,7 @@ static int __arch_update_cpu_topology(void) update_cpu_masks(); if (!MACHINE_HAS_TOPOLOGY) topology_update_polarization_simple(); + mutex_unlock(&smp_cpu_state_mutex); return rc; } @@ -289,6 +315,11 @@ void topology_schedule_update(void) schedule_work(&topology_work); } +static void topology_flush_work(void) +{ + flush_work(&topology_work); +} + static void topology_timer_fn(unsigned long ignored) { if (ptf(PTF_CHECK)) @@ -459,6 +490,12 @@ void __init topology_init_early(void) struct sysinfo_15_1_x *info; set_sched_topology(s390_topology); + if (topology_mode == TOPOLOGY_MODE_UNINITIALIZED) { + if (MACHINE_HAS_TOPOLOGY) + topology_mode = TOPOLOGY_MODE_HW; + else + topology_mode = TOPOLOGY_MODE_SINGLE; + } if (!MACHINE_HAS_TOPOLOGY) goto out; tl_info = memblock_virt_alloc(PAGE_SIZE, PAGE_SIZE); @@ -474,12 +511,97 @@ out: __arch_update_cpu_topology(); } +static inline int topology_get_mode(int enabled) +{ + if (!enabled) + return TOPOLOGY_MODE_SINGLE; + return MACHINE_HAS_TOPOLOGY ? TOPOLOGY_MODE_HW : TOPOLOGY_MODE_PACKAGE; +} + +static inline int topology_is_enabled(void) +{ + return topology_mode != TOPOLOGY_MODE_SINGLE; +} + +static int __init topology_setup(char *str) +{ + bool enabled; + int rc; + + rc = kstrtobool(str, &enabled); + if (rc) + return rc; + topology_mode = topology_get_mode(enabled); + return 0; +} +early_param("topology", topology_setup); + +static int topology_ctl_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + unsigned int len; + int new_mode; + char buf[2]; + + if (!*lenp || *ppos) { + *lenp = 0; + return 0; + } + if (!write) { + strncpy(buf, topology_is_enabled() ? "1\n" : "0\n", + ARRAY_SIZE(buf)); + len = strnlen(buf, ARRAY_SIZE(buf)); + if (len > *lenp) + len = *lenp; + if (copy_to_user(buffer, buf, len)) + return -EFAULT; + goto out; + } + len = *lenp; + if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) + return -EFAULT; + if (buf[0] != '0' && buf[0] != '1') + return -EINVAL; + mutex_lock(&smp_cpu_state_mutex); + new_mode = topology_get_mode(buf[0] == '1'); + if (topology_mode != new_mode) { + topology_mode = new_mode; + topology_schedule_update(); + } + mutex_unlock(&smp_cpu_state_mutex); + topology_flush_work(); +out: + *lenp = len; + *ppos += len; + return 0; +} + +static struct ctl_table topology_ctl_table[] = { + { + .procname = "topology", + .mode = 0644, + .proc_handler = topology_ctl_handler, + }, + { }, +}; + +static struct ctl_table topology_dir_table[] = { + { + .procname = "s390", + .maxlen = 0, + .mode = 0555, + .child = topology_ctl_table, + }, + { }, +}; + static int __init topology_init(void) { if (MACHINE_HAS_TOPOLOGY) set_topology_timer(); else topology_update_polarization_simple(); + register_sysctl_table(topology_dir_table); return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); } device_initcall(topology_init); diff --git a/arch/s390/kernel/trace.c b/arch/s390/kernel/trace.c index dde7654f5c68..490b52e85014 100644 --- a/arch/s390/kernel/trace.c +++ b/arch/s390/kernel/trace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Tracepoint definitions for s390 * diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 442e5423ce3d..a5297a22bc1e 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 version * Copyright IBM Corp. 1999, 2000 diff --git a/arch/s390/kernel/uprobes.c b/arch/s390/kernel/uprobes.c index d94baa8db507..d9d1f512f019 100644 --- a/arch/s390/kernel/uprobes.c +++ b/arch/s390/kernel/uprobes.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * User-space Probes (UProbes) for s390 * diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index b89d19f6f2ab..eacda05b45d7 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -157,6 +157,8 @@ int vdso_alloc_per_cpu(struct lowcore *lowcore) page_frame = get_zeroed_page(GFP_KERNEL); if (!segment_table || !page_table || !page_frame) goto out; + arch_set_page_dat(virt_to_page(segment_table), SEGMENT_ORDER); + arch_set_page_dat(virt_to_page(page_table), 0); /* Initialize per-cpu vdso data page */ vd = (struct vdso_per_cpu_data *) page_frame; diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile index 6cc947896c77..308564b9bf68 100644 --- a/arch/s390/kernel/vdso32/Makefile +++ b/arch/s390/kernel/vdso32/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # List of files in the vdso, has to be asm only for now KCOV_INSTRUMENT := n diff --git a/arch/s390/kernel/vdso32/getcpu.S b/arch/s390/kernel/vdso32/getcpu.S index c1ed0b72030f..6e30769dd017 100644 --- a/arch/s390/kernel/vdso32/getcpu.S +++ b/arch/s390/kernel/vdso32/getcpu.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Userland implementation of getcpu() for 32 bits processes in a * s390 kernel for use in the vDSO diff --git a/arch/s390/kernel/vdso32/note.S b/arch/s390/kernel/vdso32/note.S index 79a071e4357e..db19d0680a0a 100644 --- a/arch/s390/kernel/vdso32/note.S +++ b/arch/s390/kernel/vdso32/note.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. * Here we can supply some information useful to userland. diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S index 8f048c2d6d13..721c4954cb6e 100644 --- a/arch/s390/kernel/vdso32/vdso32.lds.S +++ b/arch/s390/kernel/vdso32/vdso32.lds.S @@ -1,7 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is the infamous ld script for the 32 bits vdso * library */ + +#include #include OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") @@ -91,7 +94,7 @@ SECTIONS .debug_ranges 0 : { *(.debug_ranges) } .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); PROVIDE(_vdso_data = .); /DISCARD/ : { diff --git a/arch/s390/kernel/vdso32/vdso32_wrapper.S b/arch/s390/kernel/vdso32/vdso32_wrapper.S index ae42f8ce350b..de2fb930471a 100644 --- a/arch/s390/kernel/vdso32/vdso32_wrapper.S +++ b/arch/s390/kernel/vdso32/vdso32_wrapper.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index 2d54c18089eb..f81ae7998883 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # List of files in the vdso, has to be asm only for now KCOV_INSTRUMENT := n diff --git a/arch/s390/kernel/vdso64/getcpu.S b/arch/s390/kernel/vdso64/getcpu.S index 4cbe98291931..43983764b959 100644 --- a/arch/s390/kernel/vdso64/getcpu.S +++ b/arch/s390/kernel/vdso64/getcpu.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Userland implementation of getcpu() for 64 bits processes in a * s390 kernel for use in the vDSO diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S index f35455d497fe..7ddb116b5e2e 100644 --- a/arch/s390/kernel/vdso64/vdso64.lds.S +++ b/arch/s390/kernel/vdso64/vdso64.lds.S @@ -1,7 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This is the infamous ld script for the 64 bits vdso * library */ + +#include #include OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") @@ -91,7 +94,7 @@ SECTIONS .debug_ranges 0 : { *(.debug_ranges) } .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); PROVIDE(_vdso_data = .); /DISCARD/ : { diff --git a/arch/s390/kernel/vdso64/vdso64_wrapper.S b/arch/s390/kernel/vdso64/vdso64_wrapper.S index c245842b516f..672184998623 100644 --- a/arch/s390/kernel/vdso64/vdso64_wrapper.S +++ b/arch/s390/kernel/vdso64/vdso64_wrapper.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 6e2c42bd1c3b..96a713a470e7 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script to make s390 Linux kernel * Written by Martin Schwidefsky (schwidefsky@de.ibm.com) */ diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index b1900239b0ab..9a4594e0a1ff 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # KVM configuration # diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index ce865bd4f81d..d93a2c0474bf 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c @@ -27,7 +27,7 @@ static int diag_release_pages(struct kvm_vcpu *vcpu) unsigned long prefix = kvm_s390_get_prefix(vcpu); start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; - end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096; + end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + PAGE_SIZE; vcpu->stat.diagnose_10++; if (start & ~PAGE_MASK || end & ~PAGE_MASK || start >= end @@ -51,9 +51,9 @@ static int diag_release_pages(struct kvm_vcpu *vcpu) */ gmap_discard(vcpu->arch.gmap, start, prefix); if (start <= prefix) - gmap_discard(vcpu->arch.gmap, 0, 4096); - if (end > prefix + 4096) - gmap_discard(vcpu->arch.gmap, 4096, 8192); + gmap_discard(vcpu->arch.gmap, 0, PAGE_SIZE); + if (end > prefix + PAGE_SIZE) + gmap_discard(vcpu->arch.gmap, PAGE_SIZE, 2 * PAGE_SIZE); gmap_discard(vcpu->arch.gmap, prefix + 2 * PAGE_SIZE, end); } return 0; @@ -150,7 +150,7 @@ static int __diag_time_slice_end(struct kvm_vcpu *vcpu) { VCPU_EVENT(vcpu, 5, "%s", "diag time slice end"); vcpu->stat.diagnose_44++; - kvm_vcpu_on_spin(vcpu); + kvm_vcpu_on_spin(vcpu, true); return 0; } diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index 653cae5e1ee1..c24bfa72baf7 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * guest access functions * @@ -629,7 +630,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, iep = ctlreg0.iep && test_kvm_facility(vcpu->kvm, 130); if (asce.r) goto real_address; - ptr = asce.origin * 4096; + ptr = asce.origin * PAGE_SIZE; switch (asce.dt) { case ASCE_TYPE_REGION1: if (vaddr.rfx01 > asce.tl) @@ -674,7 +675,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, return PGM_REGION_SECOND_TRANS; if (edat1) dat_protection |= rfte.p; - ptr = rfte.rto * 4096 + vaddr.rsx * 8; + ptr = rfte.rto * PAGE_SIZE + vaddr.rsx * 8; } /* fallthrough */ case ASCE_TYPE_REGION2: { @@ -692,7 +693,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, return PGM_REGION_THIRD_TRANS; if (edat1) dat_protection |= rste.p; - ptr = rste.rto * 4096 + vaddr.rtx * 8; + ptr = rste.rto * PAGE_SIZE + vaddr.rtx * 8; } /* fallthrough */ case ASCE_TYPE_REGION3: { @@ -720,7 +721,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, return PGM_SEGMENT_TRANSLATION; if (edat1) dat_protection |= rtte.fc0.p; - ptr = rtte.fc0.sto * 4096 + vaddr.sx * 8; + ptr = rtte.fc0.sto * PAGE_SIZE + vaddr.sx * 8; } /* fallthrough */ case ASCE_TYPE_SEGMENT: { @@ -743,7 +744,7 @@ static unsigned long guest_translate(struct kvm_vcpu *vcpu, unsigned long gva, goto absolute_address; } dat_protection |= ste.fc0.p; - ptr = ste.fc0.pto * 2048 + vaddr.px * 8; + ptr = ste.fc0.pto * (PAGE_SIZE / 2) + vaddr.px * 8; } } if (kvm_is_error_gpa(vcpu->kvm, ptr)) @@ -993,7 +994,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, parent = sg->parent; vaddr.addr = saddr; asce.val = sg->orig_asce; - ptr = asce.origin * 4096; + ptr = asce.origin * PAGE_SIZE; if (asce.r) { *fake = 1; ptr = 0; @@ -1029,7 +1030,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, union region1_table_entry rfte; if (*fake) { - ptr += (unsigned long) vaddr.rfx << 53; + ptr += vaddr.rfx * _REGION1_SIZE; rfte.val = ptr; goto shadow_r2t; } @@ -1044,7 +1045,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, return PGM_REGION_SECOND_TRANS; if (sg->edat_level >= 1) *dat_protection |= rfte.p; - ptr = rfte.rto << 12UL; + ptr = rfte.rto * PAGE_SIZE; shadow_r2t: rc = gmap_shadow_r2t(sg, saddr, rfte.val, *fake); if (rc) @@ -1055,7 +1056,7 @@ shadow_r2t: union region2_table_entry rste; if (*fake) { - ptr += (unsigned long) vaddr.rsx << 42; + ptr += vaddr.rsx * _REGION2_SIZE; rste.val = ptr; goto shadow_r3t; } @@ -1070,7 +1071,7 @@ shadow_r2t: return PGM_REGION_THIRD_TRANS; if (sg->edat_level >= 1) *dat_protection |= rste.p; - ptr = rste.rto << 12UL; + ptr = rste.rto * PAGE_SIZE; shadow_r3t: rste.p |= *dat_protection; rc = gmap_shadow_r3t(sg, saddr, rste.val, *fake); @@ -1082,7 +1083,7 @@ shadow_r3t: union region3_table_entry rtte; if (*fake) { - ptr += (unsigned long) vaddr.rtx << 31; + ptr += vaddr.rtx * _REGION3_SIZE; rtte.val = ptr; goto shadow_sgt; } @@ -1098,7 +1099,7 @@ shadow_r3t: if (rtte.fc && sg->edat_level >= 2) { *dat_protection |= rtte.fc0.p; *fake = 1; - ptr = rtte.fc1.rfaa << 31UL; + ptr = rtte.fc1.rfaa * _REGION3_SIZE; rtte.val = ptr; goto shadow_sgt; } @@ -1106,7 +1107,7 @@ shadow_r3t: return PGM_SEGMENT_TRANSLATION; if (sg->edat_level >= 1) *dat_protection |= rtte.fc0.p; - ptr = rtte.fc0.sto << 12UL; + ptr = rtte.fc0.sto * PAGE_SIZE; shadow_sgt: rtte.fc0.p |= *dat_protection; rc = gmap_shadow_sgt(sg, saddr, rtte.val, *fake); @@ -1118,7 +1119,7 @@ shadow_sgt: union segment_table_entry ste; if (*fake) { - ptr += (unsigned long) vaddr.sx << 20; + ptr += vaddr.sx * _SEGMENT_SIZE; ste.val = ptr; goto shadow_pgt; } @@ -1134,11 +1135,11 @@ shadow_sgt: *dat_protection |= ste.fc0.p; if (ste.fc && sg->edat_level >= 1) { *fake = 1; - ptr = ste.fc1.sfaa << 20UL; + ptr = ste.fc1.sfaa * _SEGMENT_SIZE; ste.val = ptr; goto shadow_pgt; } - ptr = ste.fc0.pto << 11UL; + ptr = ste.fc0.pto * (PAGE_SIZE / 2); shadow_pgt: ste.fc0.p |= *dat_protection; rc = gmap_shadow_pgt(sg, saddr, ste.val, *fake); @@ -1187,8 +1188,7 @@ int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg, vaddr.addr = saddr; if (fake) { - /* offset in 1MB guest memory block */ - pte.val = pgt + ((unsigned long) vaddr.px << 12UL); + pte.val = pgt + vaddr.px * PAGE_SIZE; goto shadow_page; } if (!rc) diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index c2e0ddc1356e..bcbd86621d01 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c @@ -308,7 +308,7 @@ static inline int in_addr_range(u64 addr, u64 a, u64 b) return (addr >= a) && (addr <= b); else /* "overflowing" interval */ - return (addr <= a) && (addr >= b); + return (addr >= a) || (addr <= b); } #define end_of_range(bp_info) (bp_info->addr + bp_info->len - 1) diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index a619ddae610d..a832ad031cee 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -2479,6 +2479,7 @@ void kvm_s390_reinject_machine_check(struct kvm_vcpu *vcpu, struct kvm_s390_mchk_info *mchk; union mci mci; __u64 cr14 = 0; /* upper bits are not used */ + int rc; mci.val = mcck_info->mcic; if (mci.sr) @@ -2496,12 +2497,13 @@ void kvm_s390_reinject_machine_check(struct kvm_vcpu *vcpu, if (mci.ck) { /* Inject the floating machine check */ inti.type = KVM_S390_MCHK; - WARN_ON_ONCE(__inject_vm(vcpu->kvm, &inti)); + rc = __inject_vm(vcpu->kvm, &inti); } else { /* Inject the machine check to specified vcpu */ irq.type = KVM_S390_MCHK; - WARN_ON_ONCE(kvm_s390_inject_vcpu(vcpu, &irq)); + rc = kvm_s390_inject_vcpu(vcpu, &irq); } + WARN_ON_ONCE(rc); } int kvm_set_routing_entry(struct kvm *kvm, diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index af09d3437631..40d0a1a97889 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -130,6 +130,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { NULL } }; +struct kvm_s390_tod_clock_ext { + __u8 epoch_idx; + __u64 tod; + __u8 reserved[7]; +} __packed; + /* allow nested virtualization in KVM (if enabled by user space) */ static int nested; module_param(nested, int, S_IRUGO); @@ -874,6 +880,26 @@ static int kvm_s390_vm_get_migration(struct kvm *kvm, return 0; } +static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) +{ + struct kvm_s390_vm_tod_clock gtod; + + if (copy_from_user(>od, (void __user *)attr->addr, sizeof(gtod))) + return -EFAULT; + + if (test_kvm_facility(kvm, 139)) + kvm_s390_set_tod_clock_ext(kvm, >od); + else if (gtod.epoch_idx == 0) + kvm_s390_set_tod_clock(kvm, gtod.tod); + else + return -EINVAL; + + VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx", + gtod.epoch_idx, gtod.tod); + + return 0; +} + static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr) { u8 gtod_high; @@ -909,6 +935,9 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr) return -EINVAL; switch (attr->attr) { + case KVM_S390_VM_TOD_EXT: + ret = kvm_s390_set_tod_ext(kvm, attr); + break; case KVM_S390_VM_TOD_HIGH: ret = kvm_s390_set_tod_high(kvm, attr); break; @@ -922,6 +951,43 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr) return ret; } +static void kvm_s390_get_tod_clock_ext(struct kvm *kvm, + struct kvm_s390_vm_tod_clock *gtod) +{ + struct kvm_s390_tod_clock_ext htod; + + preempt_disable(); + + get_tod_clock_ext((char *)&htod); + + gtod->tod = htod.tod + kvm->arch.epoch; + gtod->epoch_idx = htod.epoch_idx + kvm->arch.epdx; + + if (gtod->tod < htod.tod) + gtod->epoch_idx += 1; + + preempt_enable(); +} + +static int kvm_s390_get_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) +{ + struct kvm_s390_vm_tod_clock gtod; + + memset(>od, 0, sizeof(gtod)); + + if (test_kvm_facility(kvm, 139)) + kvm_s390_get_tod_clock_ext(kvm, >od); + else + gtod.tod = kvm_s390_get_tod_clock_fast(kvm); + + if (copy_to_user((void __user *)attr->addr, >od, sizeof(gtod))) + return -EFAULT; + + VM_EVENT(kvm, 3, "QUERY: TOD extension: 0x%x, TOD base: 0x%llx", + gtod.epoch_idx, gtod.tod); + return 0; +} + static int kvm_s390_get_tod_high(struct kvm *kvm, struct kvm_device_attr *attr) { u8 gtod_high = 0; @@ -954,6 +1020,9 @@ static int kvm_s390_get_tod(struct kvm *kvm, struct kvm_device_attr *attr) return -EINVAL; switch (attr->attr) { + case KVM_S390_VM_TOD_EXT: + ret = kvm_s390_get_tod_ext(kvm, attr); + break; case KVM_S390_VM_TOD_HIGH: ret = kvm_s390_get_tod_high(kvm, attr); break; @@ -1505,7 +1574,7 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm, if (r < 0) pgstev = 0; /* save the value */ - res[i++] = (pgstev >> 24) & 0x3; + res[i++] = (pgstev >> 24) & 0x43; /* * if the next bit is too far away, stop. * if we reached the previous "next", find the next one @@ -1583,7 +1652,7 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm, pgstev = bits[i]; pgstev = pgstev << 24; - mask &= _PGSTE_GPS_USAGE_MASK; + mask &= _PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT; set_pgste_bits(kvm->mm, hva, mask, pgstev); } srcu_read_unlock(&kvm->srcu, srcu_idx); @@ -1858,8 +1927,16 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) memcpy(kvm->arch.model.fac_list, kvm->arch.model.fac_mask, S390_ARCH_FAC_LIST_SIZE_BYTE); + /* we are always in czam mode - even on pre z14 machines */ + set_kvm_facility(kvm->arch.model.fac_mask, 138); + set_kvm_facility(kvm->arch.model.fac_list, 138); + /* we emulate STHYI in kvm */ set_kvm_facility(kvm->arch.model.fac_mask, 74); set_kvm_facility(kvm->arch.model.fac_list, 74); + if (MACHINE_HAS_TLB_GUEST) { + set_kvm_facility(kvm->arch.model.fac_mask, 147); + set_kvm_facility(kvm->arch.model.fac_list, 147); + } kvm->arch.model.cpuid = kvm_s390_get_initial_cpuid(); kvm->arch.model.ibc = sclp.ibc & 0x0fff; @@ -2369,6 +2446,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->eca |= ECA_VX; vcpu->arch.sie_block->ecd |= ECD_HOSTREGMGMT; } + if (test_kvm_facility(vcpu->kvm, 139)) + vcpu->arch.sie_block->ecd |= ECD_MEF; + vcpu->arch.sie_block->sdnxo = ((unsigned long) &vcpu->run->s.regs.sdnx) | SDNXC; vcpu->arch.sie_block->riccbd = (unsigned long) &vcpu->run->s.regs.riccb; @@ -2447,6 +2527,11 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) return kvm_s390_vcpu_has_irq(vcpu, 0); } +bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) +{ + return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE); +} + void kvm_s390_vcpu_block(struct kvm_vcpu *vcpu) { atomic_or(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20); @@ -2855,6 +2940,35 @@ retry: return 0; } +void kvm_s390_set_tod_clock_ext(struct kvm *kvm, + const struct kvm_s390_vm_tod_clock *gtod) +{ + struct kvm_vcpu *vcpu; + struct kvm_s390_tod_clock_ext htod; + int i; + + mutex_lock(&kvm->lock); + preempt_disable(); + + get_tod_clock_ext((char *)&htod); + + kvm->arch.epoch = gtod->tod - htod.tod; + kvm->arch.epdx = gtod->epoch_idx - htod.epoch_idx; + + if (kvm->arch.epoch > gtod->tod) + kvm->arch.epdx -= 1; + + kvm_s390_vcpu_block_all(kvm); + kvm_for_each_vcpu(i, vcpu, kvm) { + vcpu->arch.sie_block->epoch = kvm->arch.epoch; + vcpu->arch.sie_block->epdx = kvm->arch.epdx; + } + + kvm_s390_vcpu_unblock_all(kvm); + preempt_enable(); + mutex_unlock(&kvm->lock); +} + void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod) { struct kvm_vcpu *vcpu; diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 6fedc8bc7a37..9f8fdd7b2311 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h @@ -272,6 +272,8 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); int handle_sthyi(struct kvm_vcpu *vcpu); /* implemented in kvm-s390.c */ +void kvm_s390_set_tod_clock_ext(struct kvm *kvm, + const struct kvm_s390_vm_tod_clock *gtod); void kvm_s390_set_tod_clock(struct kvm *kvm, u64 tod); long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 8a1dac793d6b..c954ac49eee4 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -329,7 +329,7 @@ static int handle_sske(struct kvm_vcpu *vcpu) start = kvm_s390_logical_to_effective(vcpu, start); if (m3 & SSKE_MB) { /* start already designates an absolute address */ - end = (start + (1UL << 20)) & ~((1UL << 20) - 1); + end = (start + _SEGMENT_SIZE) & ~(_SEGMENT_SIZE - 1); } else { start = kvm_s390_real_to_abs(vcpu, start); end = start + PAGE_SIZE; @@ -893,10 +893,10 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) case 0x00000000: /* only 4k frames specify a real address */ start = kvm_s390_real_to_abs(vcpu, start); - end = (start + (1UL << 12)) & ~((1UL << 12) - 1); + end = (start + PAGE_SIZE) & ~(PAGE_SIZE - 1); break; case 0x00001000: - end = (start + (1UL << 20)) & ~((1UL << 20) - 1); + end = (start + _SEGMENT_SIZE) & ~(_SEGMENT_SIZE - 1); break; case 0x00002000: /* only support 2G frame size if EDAT2 is available and we are @@ -904,7 +904,7 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) if (!test_kvm_facility(vcpu->kvm, 78) || psw_bits(vcpu->arch.sie_block->gpsw).eaba == PSW_BITS_AMODE_24BIT) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - end = (start + (1UL << 31)) & ~((1UL << 31) - 1); + end = (start + _REGION3_SIZE) & ~(_REGION3_SIZE - 1); break; default: return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); @@ -988,6 +988,8 @@ static inline int do_essa(struct kvm_vcpu *vcpu, const int orc) if (pgstev & _PGSTE_GPS_ZERO) res |= 1; } + if (pgstev & _PGSTE_GPS_NODAT) + res |= 0x20; vcpu->run->s.regs.gprs[r1] = res; /* * It is possible that all the normal 511 slots were full, in which case @@ -1027,7 +1029,9 @@ static int handle_essa(struct kvm_vcpu *vcpu) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); /* Check for invalid operation request code */ orc = (vcpu->arch.sie_block->ipb & 0xf0000000) >> 28; - if (orc > ESSA_MAX) + /* ORCs 0-6 are always valid */ + if (orc > (test_kvm_facility(vcpu->kvm, 147) ? ESSA_SET_STABLE_NODAT + : ESSA_SET_STABLE_IF_RESIDENT)) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); if (likely(!vcpu->kvm->arch.migration_state)) { diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 1a252f537081..9d592ef4104b 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c @@ -155,29 +155,26 @@ static int __sigp_stop_and_store_status(struct kvm_vcpu *vcpu, return rc; } -static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) +static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter, + u64 *status_reg) { - int rc; unsigned int i; struct kvm_vcpu *v; + bool all_stopped = true; - switch (parameter & 0xff) { - case 0: - rc = SIGP_CC_NOT_OPERATIONAL; - break; - case 1: - case 2: - kvm_for_each_vcpu(i, v, vcpu->kvm) { - v->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; - kvm_clear_async_pf_completion_queue(v); - } - - rc = SIGP_CC_ORDER_CODE_ACCEPTED; - break; - default: - rc = -EOPNOTSUPP; + kvm_for_each_vcpu(i, v, vcpu->kvm) { + if (v == vcpu) + continue; + if (!is_vcpu_stopped(v)) + all_stopped = false; } - return rc; + + *status_reg &= 0xffffffff00000000UL; + + /* Reject set arch order, with czam we're always in z/Arch mode. */ + *status_reg |= (all_stopped ? SIGP_STATUS_INVALID_PARAMETER : + SIGP_STATUS_INCORRECT_STATE); + return SIGP_CC_STATUS_STORED; } static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu, @@ -446,7 +443,8 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) switch (order_code) { case SIGP_SET_ARCHITECTURE: vcpu->stat.instruction_sigp_arch++; - rc = __sigp_set_arch(vcpu, parameter); + rc = __sigp_set_arch(vcpu, parameter, + &vcpu->run->s.regs.gprs[r1]); break; default: rc = handle_sigp_dst(vcpu, order_code, cpu_addr, diff --git a/arch/s390/kvm/sthyi.c b/arch/s390/kvm/sthyi.c index a2e5c24f47a7..395926b8c1ed 100644 --- a/arch/s390/kvm/sthyi.c +++ b/arch/s390/kvm/sthyi.c @@ -436,14 +436,6 @@ int handle_sthyi(struct kvm_vcpu *vcpu) if (addr & ~PAGE_MASK) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - /* - * If the page has not yet been faulted in, we want to do that - * now and not after all the expensive calculations. - */ - r = write_guest(vcpu, addr, reg2, &cc, 1); - if (r) - return kvm_s390_inject_prog_cond(vcpu, r); - sctns = (void *)get_zeroed_page(GFP_KERNEL); if (!sctns) return -ENOMEM; diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h index 78b7e847984a..6f0209d45164 100644 --- a/arch/s390/kvm/trace-s390.h +++ b/arch/s390/kvm/trace-s390.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_KVMS390_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KVMS390_H diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h index 4fc9d4e5be89..aa419eb6a0c8 100644 --- a/arch/s390/kvm/trace.h +++ b/arch/s390/kvm/trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_KVM_H diff --git a/arch/s390/kvm/vsie.c b/arch/s390/kvm/vsie.c index 715c19c45d9a..b18b5652e5c5 100644 --- a/arch/s390/kvm/vsie.c +++ b/arch/s390/kvm/vsie.c @@ -349,6 +349,9 @@ static int shadow_scb(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) scb_s->eca |= scb_o->eca & ECA_IB; if (test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_CEI)) scb_s->eca |= scb_o->eca & ECA_CEI; + /* Epoch Extension */ + if (test_kvm_facility(vcpu->kvm, 139)) + scb_s->ecd |= scb_o->ecd & ECD_MEF; prepare_ibc(vcpu, vsie_page); rc = shadow_crycb(vcpu, vsie_page); @@ -806,8 +809,6 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) { struct kvm_s390_sie_block *scb_s = &vsie_page->scb_s; struct kvm_s390_sie_block *scb_o = vsie_page->scb_o; - struct mcck_volatile_info *mcck_info; - struct sie_page *sie_page; int rc; handle_last_fault(vcpu, vsie_page); @@ -831,9 +832,7 @@ static int do_vsie_run(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page) if (rc == -EINTR) { VCPU_EVENT(vcpu, 3, "%s", "machine check"); - sie_page = container_of(scb_s, struct sie_page, sie_block); - mcck_info = &sie_page->mcck_info; - kvm_s390_reinject_machine_check(vcpu, mcck_info); + kvm_s390_reinject_machine_check(vcpu, &vsie_page->mcck_info); return 0; } @@ -919,6 +918,13 @@ static void register_shadow_scb(struct kvm_vcpu *vcpu, */ preempt_disable(); scb_s->epoch += vcpu->kvm->arch.epoch; + + if (scb_s->ecd & ECD_MEF) { + scb_s->epdx += vcpu->kvm->arch.epdx; + if (scb_s->epoch < vcpu->kvm->arch.epoch) + scb_s->epdx += 1; + } + preempt_enable(); } @@ -1069,7 +1075,7 @@ int kvm_s390_handle_vsie(struct kvm_vcpu *vcpu) if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); - BUILD_BUG_ON(sizeof(struct vsie_page) != 4096); + BUILD_BUG_ON(sizeof(struct vsie_page) != PAGE_SIZE); scb_addr = kvm_s390_get_base_disp_s(vcpu, NULL); /* 512 byte alignment */ diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index 1d1af31e8354..9bfe0802684b 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for s390-specific library files.. # diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 92e90e40b6fb..d4aa10795605 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Precise Delay Loops for S390 * @@ -57,7 +58,7 @@ static void __udelay_enabled(unsigned long long usecs) end = get_tod_clock_fast() + (usecs << 12); do { clock_saved = 0; - if (end < S390_lowcore.clock_comparator) { + if (tod_after(S390_lowcore.clock_comparator, end)) { clock_saved = local_tick_disable(); set_clock_comparator(end); } diff --git a/arch/s390/lib/find.c b/arch/s390/lib/find.c index d90b9245ea41..96a8a2e2d067 100644 --- a/arch/s390/lib/find.c +++ b/arch/s390/lib/find.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MSB0 numbered special bitops handling. * diff --git a/arch/s390/lib/mem.S b/arch/s390/lib/mem.S index 7ff79a4ff00c..d66751397e72 100644 --- a/arch/s390/lib/mem.S +++ b/arch/s390/lib/mem.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * String handling functions. * diff --git a/arch/s390/lib/probes.c b/arch/s390/lib/probes.c index 1963ddbf4ab3..1e184a03442d 100644 --- a/arch/s390/lib/probes.c +++ b/arch/s390/lib/probes.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common helper functions for kprobes and uprobes * diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index ffb15bd4c593..1dc85f552f48 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Out of line spinlock code. * @@ -32,42 +33,63 @@ static int __init spin_retry_setup(char *str) } __setup("spin_retry=", spin_retry_setup); +static inline int arch_load_niai4(int *lock) +{ + int owner; + + asm volatile( +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + " .long 0xb2fa0040\n" /* NIAI 4 */ +#endif + " l %0,%1\n" + : "=d" (owner) : "Q" (*lock) : "memory"); + return owner; +} + +static inline int arch_cmpxchg_niai8(int *lock, int old, int new) +{ + int expected = old; + + asm volatile( +#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES + " .long 0xb2fa0080\n" /* NIAI 8 */ +#endif + " cs %0,%3,%1\n" + : "=d" (old), "=Q" (*lock) + : "0" (old), "d" (new), "Q" (*lock) + : "cc", "memory"); + return expected == old; +} + void arch_spin_lock_wait(arch_spinlock_t *lp) { int cpu = SPINLOCK_LOCKVAL; - int owner, count, first_diag; + int owner, count; - first_diag = 1; + /* Pass the virtual CPU to the lock holder if it is not running */ + owner = arch_load_niai4(&lp->lock); + if (owner && arch_vcpu_is_preempted(~owner)) + smp_yield_cpu(~owner); + + count = spin_retry; while (1) { - owner = ACCESS_ONCE(lp->lock); + owner = arch_load_niai4(&lp->lock); /* Try to get the lock if it is free. */ if (!owner) { - if (__atomic_cmpxchg_bool(&lp->lock, 0, cpu)) + if (arch_cmpxchg_niai8(&lp->lock, 0, cpu)) return; continue; } - /* First iteration: check if the lock owner is running. */ - if (first_diag && arch_vcpu_is_preempted(~owner)) { - smp_yield_cpu(~owner); - first_diag = 0; + if (count-- >= 0) continue; - } - /* Loop for a while on the lock value. */ count = spin_retry; - do { - owner = ACCESS_ONCE(lp->lock); - } while (owner && count-- > 0); - if (!owner) - continue; /* * For multiple layers of hypervisors, e.g. z/VM + LPAR * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) { + if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) smp_yield_cpu(~owner); - first_diag = 0; - } } } EXPORT_SYMBOL(arch_spin_lock_wait); @@ -75,42 +97,36 @@ EXPORT_SYMBOL(arch_spin_lock_wait); void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) { int cpu = SPINLOCK_LOCKVAL; - int owner, count, first_diag; + int owner, count; local_irq_restore(flags); - first_diag = 1; + + /* Pass the virtual CPU to the lock holder if it is not running */ + owner = arch_load_niai4(&lp->lock); + if (owner && arch_vcpu_is_preempted(~owner)) + smp_yield_cpu(~owner); + + count = spin_retry; while (1) { - owner = ACCESS_ONCE(lp->lock); + owner = arch_load_niai4(&lp->lock); /* Try to get the lock if it is free. */ if (!owner) { local_irq_disable(); - if (__atomic_cmpxchg_bool(&lp->lock, 0, cpu)) + if (arch_cmpxchg_niai8(&lp->lock, 0, cpu)) return; local_irq_restore(flags); continue; } - /* Check if the lock owner is running. */ - if (first_diag && arch_vcpu_is_preempted(~owner)) { - smp_yield_cpu(~owner); - first_diag = 0; + if (count-- >= 0) continue; - } - /* Loop for a while on the lock value. */ count = spin_retry; - do { - owner = ACCESS_ONCE(lp->lock); - } while (owner && count-- > 0); - if (!owner) - continue; /* * For multiple layers of hypervisors, e.g. z/VM + LPAR * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) { + if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) smp_yield_cpu(~owner); - first_diag = 0; - } } } EXPORT_SYMBOL(arch_spin_lock_wait_flags); diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c index 4ee27339c792..dbf2fdad2724 100644 --- a/arch/s390/lib/string.c +++ b/arch/s390/lib/string.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Optimized string functions * diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index b3bd3f23b8e8..802903c50de1 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Standard user space access functions based on mvcp/mvcs and doing * interesting things in the secondary space mode. @@ -15,8 +16,30 @@ #include #include +#ifndef CONFIG_HAVE_MARCH_Z10_FEATURES static DEFINE_STATIC_KEY_FALSE(have_mvcos); +static int __init uaccess_init(void) +{ + if (test_facility(27)) + static_branch_enable(&have_mvcos); + return 0; +} +early_initcall(uaccess_init); + +static inline int copy_with_mvcos(void) +{ + if (static_branch_likely(&have_mvcos)) + return 1; + return 0; +} +#else +static inline int copy_with_mvcos(void) +{ + return 1; +} +#endif + static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr, unsigned long size) { @@ -84,7 +107,7 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr, unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return copy_from_user_mvcos(to, from, n); return copy_from_user_mvcp(to, from, n); } @@ -157,7 +180,7 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x, unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return copy_to_user_mvcos(to, from, n); return copy_to_user_mvcs(to, from, n); } @@ -220,7 +243,7 @@ static inline unsigned long copy_in_user_mvc(void __user *to, const void __user unsigned long raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return copy_in_user_mvcos(to, from, n); return copy_in_user_mvc(to, from, n); } @@ -292,7 +315,7 @@ static inline unsigned long clear_user_xc(void __user *to, unsigned long size) unsigned long __clear_user(void __user *to, unsigned long size) { - if (static_branch_likely(&have_mvcos)) + if (copy_with_mvcos()) return clear_user_mvcos(to, size); return clear_user_xc(to, size); } @@ -349,11 +372,3 @@ long __strncpy_from_user(char *dst, const char __user *src, long size) return done; } EXPORT_SYMBOL(__strncpy_from_user); - -static int __init uaccess_init(void) -{ - if (test_facility(27)) - static_branch_enable(&have_mvcos); - return 0; -} -early_initcall(uaccess_init); diff --git a/arch/s390/lib/xor.c b/arch/s390/lib/xor.c index b4fd05c36151..96580590ccaf 100644 --- a/arch/s390/lib/xor.c +++ b/arch/s390/lib/xor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Optimized xor_block operation for RAID4/5 * diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index 0aa0ad165d8b..33fe418506bc 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux s390-specific parts of the memory manager. # diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c index 049c3c455b32..507f23ba2034 100644 --- a/arch/s390/mm/dump_pagetables.c +++ b/arch/s390/mm/dump_pagetables.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 9f118629b55f..920d40894535 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Author(s)......: Carsten Otte * Rob M van der Heij diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 14f25798b001..242b78c0a9ec 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 version * Copyright IBM Corp. 1999 @@ -135,7 +136,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) pr_alert("AS:%016lx ", asce); switch (asce & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: - table = table + ((address >> 53) & 0x7ff); + table += (address & _REGION1_INDEX) >> _REGION1_SHIFT; if (bad_address(table)) goto bad; pr_cont("R1:%016lx ", *table); @@ -144,7 +145,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_REGION2: - table = table + ((address >> 42) & 0x7ff); + table += (address & _REGION2_INDEX) >> _REGION2_SHIFT; if (bad_address(table)) goto bad; pr_cont("R2:%016lx ", *table); @@ -153,7 +154,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_REGION3: - table = table + ((address >> 31) & 0x7ff); + table += (address & _REGION3_INDEX) >> _REGION3_SHIFT; if (bad_address(table)) goto bad; pr_cont("R3:%016lx ", *table); @@ -162,7 +163,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* fallthrough */ case _ASCE_TYPE_SEGMENT: - table = table + ((address >> 20) & 0x7ff); + table += (address & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; if (bad_address(table)) goto bad; pr_cont("S:%016lx ", *table); @@ -170,7 +171,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) goto out; table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); } - table = table + ((address >> 12) & 0xff); + table += (address & _PAGE_INDEX) >> _PAGE_SHIFT; if (bad_address(table)) goto bad; pr_cont("P:%016lx ", *table); diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 4fb3d3cdb370..2f66290c9b92 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -36,16 +36,16 @@ static struct gmap *gmap_alloc(unsigned long limit) unsigned long *table; unsigned long etype, atype; - if (limit < (1UL << 31)) { - limit = (1UL << 31) - 1; + if (limit < _REGION3_SIZE) { + limit = _REGION3_SIZE - 1; atype = _ASCE_TYPE_SEGMENT; etype = _SEGMENT_ENTRY_EMPTY; - } else if (limit < (1UL << 42)) { - limit = (1UL << 42) - 1; + } else if (limit < _REGION2_SIZE) { + limit = _REGION2_SIZE - 1; atype = _ASCE_TYPE_REGION3; etype = _REGION3_ENTRY_EMPTY; - } else if (limit < (1UL << 53)) { - limit = (1UL << 53) - 1; + } else if (limit < _REGION1_SIZE) { + limit = _REGION1_SIZE - 1; atype = _ASCE_TYPE_REGION2; etype = _REGION2_ENTRY_EMPTY; } else { @@ -65,7 +65,7 @@ static struct gmap *gmap_alloc(unsigned long limit) spin_lock_init(&gmap->guest_table_lock); spin_lock_init(&gmap->shadow_lock); atomic_set(&gmap->ref_count, 1); - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) goto out_free; page->index = 0; @@ -100,14 +100,14 @@ struct gmap *gmap_create(struct mm_struct *mm, unsigned long limit) if (!gmap) return NULL; gmap->mm = mm; - spin_lock(&mm->context.gmap_lock); + spin_lock(&mm->context.lock); list_add_rcu(&gmap->list, &mm->context.gmap_list); if (list_is_singular(&mm->context.gmap_list)) gmap_asce = gmap->asce; else gmap_asce = -1UL; WRITE_ONCE(mm->context.gmap_asce, gmap_asce); - spin_unlock(&mm->context.gmap_lock); + spin_unlock(&mm->context.lock); return gmap; } EXPORT_SYMBOL_GPL(gmap_create); @@ -186,7 +186,7 @@ static void gmap_free(struct gmap *gmap) gmap_flush_tlb(gmap); /* Free all segment & region tables. */ list_for_each_entry_safe(page, next, &gmap->crst_list, lru) - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); gmap_radix_tree_free(&gmap->guest_to_host); gmap_radix_tree_free(&gmap->host_to_guest); @@ -248,7 +248,7 @@ void gmap_remove(struct gmap *gmap) spin_unlock(&gmap->shadow_lock); } /* Remove gmap from the pre-mm list */ - spin_lock(&gmap->mm->context.gmap_lock); + spin_lock(&gmap->mm->context.lock); list_del_rcu(&gmap->list); if (list_empty(&gmap->mm->context.gmap_list)) gmap_asce = 0; @@ -258,7 +258,7 @@ void gmap_remove(struct gmap *gmap) else gmap_asce = -1UL; WRITE_ONCE(gmap->mm->context.gmap_asce, gmap_asce); - spin_unlock(&gmap->mm->context.gmap_lock); + spin_unlock(&gmap->mm->context.lock); synchronize_rcu(); /* Put reference */ gmap_put(gmap); @@ -306,7 +306,7 @@ static int gmap_alloc_table(struct gmap *gmap, unsigned long *table, unsigned long *new; /* since we dont free the gmap table until gmap_free we can unlock */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; new = (unsigned long *) page_to_phys(page); @@ -321,7 +321,7 @@ static int gmap_alloc_table(struct gmap *gmap, unsigned long *table, } spin_unlock(&gmap->guest_table_lock); if (page) - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return 0; } @@ -546,30 +546,30 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) /* Create higher level tables in the gmap page table */ table = gmap->table; if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION1) { - table += (gaddr >> 53) & 0x7ff; + table += (gaddr & _REGION1_INDEX) >> _REGION1_SHIFT; if ((*table & _REGION_ENTRY_INVALID) && gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY, - gaddr & 0xffe0000000000000UL)) + gaddr & _REGION1_MASK)) return -ENOMEM; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); } if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION2) { - table += (gaddr >> 42) & 0x7ff; + table += (gaddr & _REGION2_INDEX) >> _REGION2_SHIFT; if ((*table & _REGION_ENTRY_INVALID) && gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY, - gaddr & 0xfffffc0000000000UL)) + gaddr & _REGION2_MASK)) return -ENOMEM; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); } if ((gmap->asce & _ASCE_TYPE_MASK) >= _ASCE_TYPE_REGION3) { - table += (gaddr >> 31) & 0x7ff; + table += (gaddr & _REGION3_INDEX) >> _REGION3_SHIFT; if ((*table & _REGION_ENTRY_INVALID) && gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY, - gaddr & 0xffffffff80000000UL)) + gaddr & _REGION3_MASK)) return -ENOMEM; table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); } - table += (gaddr >> 20) & 0x7ff; + table += (gaddr & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; /* Walk the parent mm page table */ mm = gmap->mm; pgd = pgd_offset(mm, vmaddr); @@ -771,7 +771,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = gmap->table; switch (gmap->asce & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: - table += (gaddr >> 53) & 0x7ff; + table += (gaddr & _REGION1_INDEX) >> _REGION1_SHIFT; if (level == 4) break; if (*table & _REGION_ENTRY_INVALID) @@ -779,7 +779,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* Fallthrough */ case _ASCE_TYPE_REGION2: - table += (gaddr >> 42) & 0x7ff; + table += (gaddr & _REGION2_INDEX) >> _REGION2_SHIFT; if (level == 3) break; if (*table & _REGION_ENTRY_INVALID) @@ -787,7 +787,7 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* Fallthrough */ case _ASCE_TYPE_REGION3: - table += (gaddr >> 31) & 0x7ff; + table += (gaddr & _REGION3_INDEX) >> _REGION3_SHIFT; if (level == 2) break; if (*table & _REGION_ENTRY_INVALID) @@ -795,13 +795,13 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); /* Fallthrough */ case _ASCE_TYPE_SEGMENT: - table += (gaddr >> 20) & 0x7ff; + table += (gaddr & _SEGMENT_INDEX) >> _SEGMENT_SHIFT; if (level == 1) break; if (*table & _REGION_ENTRY_INVALID) return NULL; table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); - table += (gaddr >> 12) & 0xff; + table += (gaddr & _PAGE_INDEX) >> _PAGE_SHIFT; } return table; } @@ -1126,7 +1126,7 @@ static void gmap_unshadow_page(struct gmap *sg, unsigned long raddr) table = gmap_table_walk(sg, raddr, 0); /* get page table pointer */ if (!table || *table & _PAGE_INVALID) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 12) - 1); + gmap_call_notifier(sg, raddr, raddr + _PAGE_SIZE - 1); ptep_unshadow_pte(sg->mm, raddr, (pte_t *) table); } @@ -1144,7 +1144,7 @@ static void __gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr, int i; BUG_ON(!gmap_is_shadow(sg)); - for (i = 0; i < 256; i++, raddr += 1UL << 12) + for (i = 0; i < _PAGE_ENTRIES; i++, raddr += _PAGE_SIZE) pgt[i] = _PAGE_INVALID; } @@ -1164,8 +1164,8 @@ static void gmap_unshadow_pgt(struct gmap *sg, unsigned long raddr) ste = gmap_table_walk(sg, raddr, 1); /* get segment pointer */ if (!ste || !(*ste & _SEGMENT_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 20) - 1); - sto = (unsigned long) (ste - ((raddr >> 20) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _SEGMENT_SIZE - 1); + sto = (unsigned long) (ste - ((raddr & _SEGMENT_INDEX) >> _SEGMENT_SHIFT)); gmap_idte_one(sto | _ASCE_TYPE_SEGMENT, raddr); pgt = (unsigned long *)(*ste & _SEGMENT_ENTRY_ORIGIN); *ste = _SEGMENT_ENTRY_EMPTY; @@ -1193,7 +1193,7 @@ static void __gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) sgt | _ASCE_TYPE_SEGMENT; - for (i = 0; i < 2048; i++, raddr += 1UL << 20) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _SEGMENT_SIZE) { if (!(sgt[i] & _SEGMENT_ENTRY_ORIGIN)) continue; pgt = (unsigned long *)(sgt[i] & _REGION_ENTRY_ORIGIN); @@ -1222,8 +1222,8 @@ static void gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr) r3e = gmap_table_walk(sg, raddr, 2); /* get region-3 pointer */ if (!r3e || !(*r3e & _REGION_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 31) - 1); - r3o = (unsigned long) (r3e - ((raddr >> 31) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _REGION3_SIZE - 1); + r3o = (unsigned long) (r3e - ((raddr & _REGION3_INDEX) >> _REGION3_SHIFT)); gmap_idte_one(r3o | _ASCE_TYPE_REGION3, raddr); sgt = (unsigned long *)(*r3e & _REGION_ENTRY_ORIGIN); *r3e = _REGION3_ENTRY_EMPTY; @@ -1231,7 +1231,7 @@ static void gmap_unshadow_sgt(struct gmap *sg, unsigned long raddr) /* Free segment table */ page = pfn_to_page(__pa(sgt) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } /** @@ -1251,7 +1251,7 @@ static void __gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) r3t | _ASCE_TYPE_REGION3; - for (i = 0; i < 2048; i++, raddr += 1UL << 31) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _REGION3_SIZE) { if (!(r3t[i] & _REGION_ENTRY_ORIGIN)) continue; sgt = (unsigned long *)(r3t[i] & _REGION_ENTRY_ORIGIN); @@ -1260,7 +1260,7 @@ static void __gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr, /* Free segment table */ page = pfn_to_page(__pa(sgt) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } } @@ -1280,8 +1280,8 @@ static void gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr) r2e = gmap_table_walk(sg, raddr, 3); /* get region-2 pointer */ if (!r2e || !(*r2e & _REGION_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 42) - 1); - r2o = (unsigned long) (r2e - ((raddr >> 42) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _REGION2_SIZE - 1); + r2o = (unsigned long) (r2e - ((raddr & _REGION2_INDEX) >> _REGION2_SHIFT)); gmap_idte_one(r2o | _ASCE_TYPE_REGION2, raddr); r3t = (unsigned long *)(*r2e & _REGION_ENTRY_ORIGIN); *r2e = _REGION2_ENTRY_EMPTY; @@ -1289,7 +1289,7 @@ static void gmap_unshadow_r3t(struct gmap *sg, unsigned long raddr) /* Free region 3 table */ page = pfn_to_page(__pa(r3t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } /** @@ -1309,7 +1309,7 @@ static void __gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) r2t | _ASCE_TYPE_REGION2; - for (i = 0; i < 2048; i++, raddr += 1UL << 42) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _REGION2_SIZE) { if (!(r2t[i] & _REGION_ENTRY_ORIGIN)) continue; r3t = (unsigned long *)(r2t[i] & _REGION_ENTRY_ORIGIN); @@ -1318,7 +1318,7 @@ static void __gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr, /* Free region 3 table */ page = pfn_to_page(__pa(r3t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } } @@ -1338,8 +1338,8 @@ static void gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr) r1e = gmap_table_walk(sg, raddr, 4); /* get region-1 pointer */ if (!r1e || !(*r1e & _REGION_ENTRY_ORIGIN)) return; - gmap_call_notifier(sg, raddr, raddr + (1UL << 53) - 1); - r1o = (unsigned long) (r1e - ((raddr >> 53) & 0x7ff)); + gmap_call_notifier(sg, raddr, raddr + _REGION1_SIZE - 1); + r1o = (unsigned long) (r1e - ((raddr & _REGION1_INDEX) >> _REGION1_SHIFT)); gmap_idte_one(r1o | _ASCE_TYPE_REGION1, raddr); r2t = (unsigned long *)(*r1e & _REGION_ENTRY_ORIGIN); *r1e = _REGION1_ENTRY_EMPTY; @@ -1347,7 +1347,7 @@ static void gmap_unshadow_r2t(struct gmap *sg, unsigned long raddr) /* Free region 2 table */ page = pfn_to_page(__pa(r2t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } /** @@ -1367,7 +1367,7 @@ static void __gmap_unshadow_r1t(struct gmap *sg, unsigned long raddr, BUG_ON(!gmap_is_shadow(sg)); asce = (unsigned long) r1t | _ASCE_TYPE_REGION1; - for (i = 0; i < 2048; i++, raddr += 1UL << 53) { + for (i = 0; i < _CRST_ENTRIES; i++, raddr += _REGION1_SIZE) { if (!(r1t[i] & _REGION_ENTRY_ORIGIN)) continue; r2t = (unsigned long *)(r1t[i] & _REGION_ENTRY_ORIGIN); @@ -1378,7 +1378,7 @@ static void __gmap_unshadow_r1t(struct gmap *sg, unsigned long raddr, /* Free region 2 table */ page = pfn_to_page(__pa(r2t) >> PAGE_SHIFT); list_del(&page->lru); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); } } @@ -1535,7 +1535,7 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce, /* protect after insertion, so it will get properly invalidated */ down_read(&parent->mm->mmap_sem); rc = gmap_protect_range(parent, asce & _ASCE_ORIGIN, - ((asce & _ASCE_TABLE_LENGTH) + 1) * 4096, + ((asce & _ASCE_TABLE_LENGTH) + 1) * PAGE_SIZE, PROT_READ, PGSTE_VSIE_BIT); up_read(&parent->mm->mmap_sem); spin_lock(&parent->shadow_lock); @@ -1578,7 +1578,7 @@ int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t, BUG_ON(!gmap_is_shadow(sg)); /* Allocate a shadow region second table */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = r2t & _REGION_ENTRY_ORIGIN; @@ -1614,10 +1614,10 @@ int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t, } spin_unlock(&sg->guest_table_lock); /* Make r2t read-only in parent gmap page table */ - raddr = (saddr & 0xffe0000000000000UL) | _SHADOW_RMAP_REGION1; + raddr = (saddr & _REGION1_MASK) | _SHADOW_RMAP_REGION1; origin = r2t & _REGION_ENTRY_ORIGIN; - offset = ((r2t & _REGION_ENTRY_OFFSET) >> 6) * 4096; - len = ((r2t & _REGION_ENTRY_LENGTH) + 1) * 4096 - offset; + offset = ((r2t & _REGION_ENTRY_OFFSET) >> 6) * PAGE_SIZE; + len = ((r2t & _REGION_ENTRY_LENGTH) + 1) * PAGE_SIZE - offset; rc = gmap_protect_rmap(sg, raddr, origin + offset, len, PROT_READ); spin_lock(&sg->guest_table_lock); if (!rc) { @@ -1634,7 +1634,7 @@ int gmap_shadow_r2t(struct gmap *sg, unsigned long saddr, unsigned long r2t, return rc; out_free: spin_unlock(&sg->guest_table_lock); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return rc; } EXPORT_SYMBOL_GPL(gmap_shadow_r2t); @@ -1662,7 +1662,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, BUG_ON(!gmap_is_shadow(sg)); /* Allocate a shadow region second table */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = r3t & _REGION_ENTRY_ORIGIN; @@ -1697,10 +1697,10 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, } spin_unlock(&sg->guest_table_lock); /* Make r3t read-only in parent gmap page table */ - raddr = (saddr & 0xfffffc0000000000UL) | _SHADOW_RMAP_REGION2; + raddr = (saddr & _REGION2_MASK) | _SHADOW_RMAP_REGION2; origin = r3t & _REGION_ENTRY_ORIGIN; - offset = ((r3t & _REGION_ENTRY_OFFSET) >> 6) * 4096; - len = ((r3t & _REGION_ENTRY_LENGTH) + 1) * 4096 - offset; + offset = ((r3t & _REGION_ENTRY_OFFSET) >> 6) * PAGE_SIZE; + len = ((r3t & _REGION_ENTRY_LENGTH) + 1) * PAGE_SIZE - offset; rc = gmap_protect_rmap(sg, raddr, origin + offset, len, PROT_READ); spin_lock(&sg->guest_table_lock); if (!rc) { @@ -1717,7 +1717,7 @@ int gmap_shadow_r3t(struct gmap *sg, unsigned long saddr, unsigned long r3t, return rc; out_free: spin_unlock(&sg->guest_table_lock); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return rc; } EXPORT_SYMBOL_GPL(gmap_shadow_r3t); @@ -1745,7 +1745,7 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt, BUG_ON(!gmap_is_shadow(sg) || (sgt & _REGION3_ENTRY_LARGE)); /* Allocate a shadow segment table */ - page = alloc_pages(GFP_KERNEL, 2); + page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); if (!page) return -ENOMEM; page->index = sgt & _REGION_ENTRY_ORIGIN; @@ -1781,10 +1781,10 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt, } spin_unlock(&sg->guest_table_lock); /* Make sgt read-only in parent gmap page table */ - raddr = (saddr & 0xffffffff80000000UL) | _SHADOW_RMAP_REGION3; + raddr = (saddr & _REGION3_MASK) | _SHADOW_RMAP_REGION3; origin = sgt & _REGION_ENTRY_ORIGIN; - offset = ((sgt & _REGION_ENTRY_OFFSET) >> 6) * 4096; - len = ((sgt & _REGION_ENTRY_LENGTH) + 1) * 4096 - offset; + offset = ((sgt & _REGION_ENTRY_OFFSET) >> 6) * PAGE_SIZE; + len = ((sgt & _REGION_ENTRY_LENGTH) + 1) * PAGE_SIZE - offset; rc = gmap_protect_rmap(sg, raddr, origin + offset, len, PROT_READ); spin_lock(&sg->guest_table_lock); if (!rc) { @@ -1801,7 +1801,7 @@ int gmap_shadow_sgt(struct gmap *sg, unsigned long saddr, unsigned long sgt, return rc; out_free: spin_unlock(&sg->guest_table_lock); - __free_pages(page, 2); + __free_pages(page, CRST_ALLOC_ORDER); return rc; } EXPORT_SYMBOL_GPL(gmap_shadow_sgt); @@ -1902,7 +1902,7 @@ int gmap_shadow_pgt(struct gmap *sg, unsigned long saddr, unsigned long pgt, } spin_unlock(&sg->guest_table_lock); /* Make pgt read-only in parent gmap page table (not the pgste) */ - raddr = (saddr & 0xfffffffffff00000UL) | _SHADOW_RMAP_SEGMENT; + raddr = (saddr & _SEGMENT_MASK) | _SHADOW_RMAP_SEGMENT; origin = pgt & _SEGMENT_ENTRY_ORIGIN & PAGE_MASK; rc = gmap_protect_rmap(sg, raddr, origin, PAGE_SIZE, PROT_READ); spin_lock(&sg->guest_table_lock); @@ -2021,7 +2021,7 @@ static void gmap_shadow_notify(struct gmap *sg, unsigned long vmaddr, } /* Check for top level table */ start = sg->orig_asce & _ASCE_ORIGIN; - end = start + ((sg->orig_asce & _ASCE_TABLE_LENGTH) + 1) * 4096; + end = start + ((sg->orig_asce & _ASCE_TABLE_LENGTH) + 1) * PAGE_SIZE; if (!(sg->orig_asce & _ASCE_REAL_SPACE) && gaddr >= start && gaddr < end) { /* The complete shadow table has to go */ @@ -2032,7 +2032,7 @@ static void gmap_shadow_notify(struct gmap *sg, unsigned long vmaddr, return; } /* Remove the page table tree from on specific entry */ - head = radix_tree_delete(&sg->host_to_rmap, vmaddr >> 12); + head = radix_tree_delete(&sg->host_to_rmap, vmaddr >> PAGE_SHIFT); gmap_for_each_rmap_safe(rmap, rnext, head) { bits = rmap->raddr & _SHADOW_RMAP_MASK; raddr = rmap->raddr ^ bits; @@ -2076,7 +2076,7 @@ void ptep_notify(struct mm_struct *mm, unsigned long vmaddr, struct gmap *gmap, *sg, *next; offset = ((unsigned long) pte) & (255 * sizeof(pte_t)); - offset = offset * (4096 / sizeof(pte_t)); + offset = offset * (PAGE_SIZE / sizeof(pte_t)); rcu_read_lock(); list_for_each_entry_rcu(gmap, &mm->context.gmap_list, list) { spin_lock(&gmap->guest_table_lock); @@ -2120,6 +2120,37 @@ static inline void thp_split_mm(struct mm_struct *mm) #endif } +/* + * Remove all empty zero pages from the mapping for lazy refaulting + * - This must be called after mm->context.has_pgste is set, to avoid + * future creation of zero pages + * - This must be called after THP was enabled + */ +static int __zap_zero_pages(pmd_t *pmd, unsigned long start, + unsigned long end, struct mm_walk *walk) +{ + unsigned long addr; + + for (addr = start; addr != end; addr += PAGE_SIZE) { + pte_t *ptep; + spinlock_t *ptl; + + ptep = pte_offset_map_lock(walk->mm, pmd, addr, &ptl); + if (is_zero_pfn(pte_pfn(*ptep))) + ptep_xchg_direct(walk->mm, addr, ptep, __pte(_PAGE_INVALID)); + pte_unmap_unlock(ptep, ptl); + } + return 0; +} + +static inline void zap_zero_pages(struct mm_struct *mm) +{ + struct mm_walk walk = { .pmd_entry = __zap_zero_pages }; + + walk.mm = mm; + walk_page_range(0, TASK_SIZE, &walk); +} + /* * switch on pgstes for its userspace process (for kvm) */ @@ -2137,6 +2168,7 @@ int s390_enable_sie(void) mm->context.has_pgste = 1; /* split thp mappings and disable thp for future mappings */ thp_split_mm(mm); + zap_zero_pages(mm); up_write(&mm->mmap_sem); return 0; } @@ -2149,13 +2181,6 @@ EXPORT_SYMBOL_GPL(s390_enable_sie); static int __s390_enable_skey(pte_t *pte, unsigned long addr, unsigned long next, struct mm_walk *walk) { - /* - * Remove all zero page mappings, - * after establishing a policy to forbid zero page mappings - * following faults for that page will get fresh anonymous pages - */ - if (is_zero_pfn(pte_pfn(*pte))) - ptep_xchg_direct(walk->mm, addr, pte, __pte(_PAGE_INVALID)); /* Clear storage key */ ptep_zap_key(walk->mm, addr, pte); return 0; diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 8ecc25e760fa..05c8abd864f1 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Lockless get_user_pages_fast for s390 * @@ -56,13 +57,12 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { - unsigned long mask, result; struct page *head, *page; + unsigned long mask; int refs; - result = write ? 0 : _SEGMENT_ENTRY_PROTECT; - mask = result | _SEGMENT_ENTRY_INVALID; - if ((pmd_val(pmd) & mask) != result) + mask = (write ? _SEGMENT_ENTRY_PROTECT : 0) | _SEGMENT_ENTRY_INVALID; + if ((pmd_val(pmd) & mask) != 0) return 0; VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT)); diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 44a8e6f0391e..e804090f4470 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IBM System z Huge TLB Page Support for Kernel. * diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 8111694ce55a..41ba9bd53e48 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 version * Copyright IBM Corp. 1999 @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -84,7 +86,7 @@ void __init paging_init(void) psw_t psw; init_mm.pgd = swapper_pg_dir; - if (VMALLOC_END > (1UL << 42)) { + if (VMALLOC_END > _REGION2_SIZE) { asce_bits = _ASCE_TYPE_REGION2 | _ASCE_TABLE_LENGTH; pgd_type = _REGION2_ENTRY_EMPTY; } else { @@ -93,8 +95,7 @@ void __init paging_init(void) } init_mm.context.asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits; S390_lowcore.kernel_asce = init_mm.context.asce; - clear_table((unsigned long *) init_mm.pgd, pgd_type, - sizeof(unsigned long)*2048); + crst_table_init((unsigned long *) init_mm.pgd, pgd_type); vmem_map_init(); /* enable virtual mapping in kernel mode */ @@ -137,6 +138,8 @@ void __init mem_init(void) free_all_bootmem(); setup_zero_pages(); /* Setup zeroed pages. */ + cmma_init_nodat(); + mem_init_print_info(NULL); } @@ -166,6 +169,58 @@ unsigned long memory_block_size_bytes(void) } #ifdef CONFIG_MEMORY_HOTPLUG + +#ifdef CONFIG_CMA + +/* Prevent memory blocks which contain cma regions from going offline */ + +struct s390_cma_mem_data { + unsigned long start; + unsigned long end; +}; + +static int s390_cma_check_range(struct cma *cma, void *data) +{ + struct s390_cma_mem_data *mem_data; + unsigned long start, end; + + mem_data = data; + start = cma_get_base(cma); + end = start + cma_get_size(cma); + if (end < mem_data->start) + return 0; + if (start >= mem_data->end) + return 0; + return -EBUSY; +} + +static int s390_cma_mem_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct s390_cma_mem_data mem_data; + struct memory_notify *arg; + int rc = 0; + + arg = data; + mem_data.start = arg->start_pfn << PAGE_SHIFT; + mem_data.end = mem_data.start + (arg->nr_pages << PAGE_SHIFT); + if (action == MEM_GOING_OFFLINE) + rc = cma_for_each_area(s390_cma_check_range, &mem_data); + return notifier_from_errno(rc); +} + +static struct notifier_block s390_cma_mem_nb = { + .notifier_call = s390_cma_mem_notifier, +}; + +static int __init s390_cma_mem_init(void) +{ + return register_memory_notifier(&s390_cma_mem_nb); +} +device_initcall(s390_cma_mem_init); + +#endif /* CONFIG_CMA */ + int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock) { unsigned long start_pfn = PFN_DOWN(start); diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 792f9c63fbca..7be06475809b 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Access kernel memory without faulting -- s390 specific implementation. * diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c index e58dca05b962..21f6c82c8296 100644 --- a/arch/s390/mm/mem_detect.c +++ b/arch/s390/mm/mem_detect.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2008, 2009 * diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index 69a7b01ae746..382153ff17e3 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2008 * @@ -10,9 +11,10 @@ #include #include #include +#include #include #include - +#include #include static int cmma_flag = 1; @@ -36,14 +38,16 @@ __setup("cmma=", cmma); static inline int cmma_test_essa(void) { register unsigned long tmp asm("0") = 0; - register int rc asm("1") = -EOPNOTSUPP; + register int rc asm("1"); + /* test ESSA_GET_STATE */ asm volatile( - " .insn rrf,0xb9ab0000,%1,%1,0,0\n" + " .insn rrf,0xb9ab0000,%1,%1,%2,0\n" "0: la %0,0\n" "1:\n" EX_TABLE(0b,1b) - : "+&d" (rc), "+&d" (tmp)); + : "=&d" (rc), "+&d" (tmp) + : "i" (ESSA_GET_STATE), "0" (-EOPNOTSUPP)); return rc; } @@ -51,11 +55,26 @@ void __init cmma_init(void) { if (!cmma_flag) return; - if (cmma_test_essa()) + if (cmma_test_essa()) { cmma_flag = 0; + return; + } + if (test_facility(147)) + cmma_flag = 2; } -static inline void set_page_unstable(struct page *page, int order) +static inline unsigned char get_page_state(struct page *page) +{ + unsigned char state; + + asm volatile(" .insn rrf,0xb9ab0000,%0,%1,%2,0" + : "=&d" (state) + : "a" (page_to_phys(page)), + "i" (ESSA_GET_STATE)); + return state & 0x3f; +} + +static inline void set_page_unused(struct page *page, int order) { int i, rc; @@ -66,14 +85,7 @@ static inline void set_page_unstable(struct page *page, int order) "i" (ESSA_SET_UNUSED)); } -void arch_free_page(struct page *page, int order) -{ - if (!cmma_flag) - return; - set_page_unstable(page, order); -} - -static inline void set_page_stable(struct page *page, int order) +static inline void set_page_stable_dat(struct page *page, int order) { int i, rc; @@ -84,11 +96,162 @@ static inline void set_page_stable(struct page *page, int order) "i" (ESSA_SET_STABLE)); } +static inline void set_page_stable_nodat(struct page *page, int order) +{ + int i, rc; + + for (i = 0; i < (1 << order); i++) + asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" + : "=&d" (rc) + : "a" (page_to_phys(page + i)), + "i" (ESSA_SET_STABLE_NODAT)); +} + +static void mark_kernel_pmd(pud_t *pud, unsigned long addr, unsigned long end) +{ + unsigned long next; + struct page *page; + pmd_t *pmd; + + pmd = pmd_offset(pud, addr); + do { + next = pmd_addr_end(addr, end); + if (pmd_none(*pmd) || pmd_large(*pmd)) + continue; + page = virt_to_page(pmd_val(*pmd)); + set_bit(PG_arch_1, &page->flags); + } while (pmd++, addr = next, addr != end); +} + +static void mark_kernel_pud(p4d_t *p4d, unsigned long addr, unsigned long end) +{ + unsigned long next; + struct page *page; + pud_t *pud; + int i; + + pud = pud_offset(p4d, addr); + do { + next = pud_addr_end(addr, end); + if (pud_none(*pud) || pud_large(*pud)) + continue; + if (!pud_folded(*pud)) { + page = virt_to_page(pud_val(*pud)); + for (i = 0; i < 3; i++) + set_bit(PG_arch_1, &page[i].flags); + } + mark_kernel_pmd(pud, addr, next); + } while (pud++, addr = next, addr != end); +} + +static void mark_kernel_p4d(pgd_t *pgd, unsigned long addr, unsigned long end) +{ + unsigned long next; + struct page *page; + p4d_t *p4d; + int i; + + p4d = p4d_offset(pgd, addr); + do { + next = p4d_addr_end(addr, end); + if (p4d_none(*p4d)) + continue; + if (!p4d_folded(*p4d)) { + page = virt_to_page(p4d_val(*p4d)); + for (i = 0; i < 3; i++) + set_bit(PG_arch_1, &page[i].flags); + } + mark_kernel_pud(p4d, addr, next); + } while (p4d++, addr = next, addr != end); +} + +static void mark_kernel_pgd(void) +{ + unsigned long addr, next; + struct page *page; + pgd_t *pgd; + int i; + + addr = 0; + pgd = pgd_offset_k(addr); + do { + next = pgd_addr_end(addr, MODULES_END); + if (pgd_none(*pgd)) + continue; + if (!pgd_folded(*pgd)) { + page = virt_to_page(pgd_val(*pgd)); + for (i = 0; i < 3; i++) + set_bit(PG_arch_1, &page[i].flags); + } + mark_kernel_p4d(pgd, addr, next); + } while (pgd++, addr = next, addr != MODULES_END); +} + +void __init cmma_init_nodat(void) +{ + struct memblock_region *reg; + struct page *page; + unsigned long start, end, ix; + + if (cmma_flag < 2) + return; + /* Mark pages used in kernel page tables */ + mark_kernel_pgd(); + + /* Set all kernel pages not used for page tables to stable/no-dat */ + for_each_memblock(memory, reg) { + start = memblock_region_memory_base_pfn(reg); + end = memblock_region_memory_end_pfn(reg); + page = pfn_to_page(start); + for (ix = start; ix < end; ix++, page++) { + if (__test_and_clear_bit(PG_arch_1, &page->flags)) + continue; /* skip page table pages */ + if (!list_empty(&page->lru)) + continue; /* skip free pages */ + set_page_stable_nodat(page, 0); + } + } +} + +void arch_free_page(struct page *page, int order) +{ + if (!cmma_flag) + return; + set_page_unused(page, order); +} + void arch_alloc_page(struct page *page, int order) { if (!cmma_flag) return; - set_page_stable(page, order); + if (cmma_flag < 2) + set_page_stable_dat(page, order); + else + set_page_stable_nodat(page, order); +} + +void arch_set_page_dat(struct page *page, int order) +{ + if (!cmma_flag) + return; + set_page_stable_dat(page, order); +} + +void arch_set_page_nodat(struct page *page, int order) +{ + if (cmma_flag < 2) + return; + set_page_stable_nodat(page, order); +} + +int arch_test_page_nodat(struct page *page) +{ + unsigned char state; + + if (cmma_flag < 2) + return 0; + state = get_page_state(page); + return !!(state & 0x20); } void arch_set_page_states(int make_stable) @@ -108,9 +271,9 @@ void arch_set_page_states(int make_stable) list_for_each(l, &zone->free_area[order].free_list[t]) { page = list_entry(l, struct page, lru); if (make_stable) - set_page_stable(page, order); + set_page_stable_dat(page, 0); else - set_page_unstable(page, order); + set_page_unused(page, order); } } spin_unlock_irqrestore(&zone->lock, flags); diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index 180481589246..c44171588d08 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2011 * Author(s): Jan Glauber @@ -7,6 +8,7 @@ #include #include #include +#include #include #include @@ -191,7 +193,7 @@ static int split_pud_page(pud_t *pudp, unsigned long addr) pud_t new; int i, ro, nx; - pm_dir = vmem_pmd_alloc(); + pm_dir = vmem_crst_alloc(_SEGMENT_ENTRY_EMPTY); if (!pm_dir) return -ENOMEM; pmd_addr = pud_pfn(*pudp) << PAGE_SHIFT; @@ -328,7 +330,7 @@ static void ipte_range(pte_t *pte, unsigned long address, int nr) return; } for (i = 0; i < nr; i++) { - __ptep_ipte(address, pte, IPTE_GLOBAL); + __ptep_ipte(address, pte, 0, 0, IPTE_GLOBAL); address += PAGE_SIZE; pte++; } diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c index 18918e394ce4..cc2faffa7d6e 100644 --- a/arch/s390/mm/pgalloc.c +++ b/arch/s390/mm/pgalloc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Page table allocation functions * @@ -57,6 +58,7 @@ unsigned long *crst_table_alloc(struct mm_struct *mm) if (!page) return NULL; + arch_set_page_dat(page, 2); return (unsigned long *) page_to_phys(page); } @@ -82,7 +84,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long end) int rc, notify; /* upgrade should only happen from 3 to 4, 3 to 5, or 4 to 5 levels */ - BUG_ON(mm->context.asce_limit < (1UL << 42)); + VM_BUG_ON(mm->context.asce_limit < _REGION2_SIZE); if (end >= TASK_SIZE_MAX) return -ENOMEM; rc = 0; @@ -95,11 +97,11 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long end) } spin_lock_bh(&mm->page_table_lock); pgd = (unsigned long *) mm->pgd; - if (mm->context.asce_limit == (1UL << 42)) { + if (mm->context.asce_limit == _REGION2_SIZE) { crst_table_init(table, _REGION2_ENTRY_EMPTY); p4d_populate(mm, (p4d_t *) table, (pud_t *) pgd); mm->pgd = (pgd_t *) table; - mm->context.asce_limit = 1UL << 53; + mm->context.asce_limit = _REGION1_SIZE; mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_REGION2; } else { @@ -123,7 +125,7 @@ void crst_table_downgrade(struct mm_struct *mm) pgd_t *pgd; /* downgrade should only happen from 3 to 2 levels (compat only) */ - BUG_ON(mm->context.asce_limit != (1UL << 42)); + VM_BUG_ON(mm->context.asce_limit != _REGION2_SIZE); if (current->active_mm == mm) { clear_user_asce(); @@ -132,7 +134,7 @@ void crst_table_downgrade(struct mm_struct *mm) pgd = mm->pgd; mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); - mm->context.asce_limit = 1UL << 31; + mm->context.asce_limit = _REGION3_SIZE; mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH | _ASCE_USER_BITS | _ASCE_TYPE_SEGMENT; crst_table_free(mm, (unsigned long *) pgd); @@ -187,7 +189,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) /* Try to get a fragment of a 4K page as a 2K page table */ if (!mm_alloc_pgste(mm)) { table = NULL; - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); if (!list_empty(&mm->context.pgtable_list)) { page = list_first_entry(&mm->context.pgtable_list, struct page, lru); @@ -202,7 +204,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) list_del(&page->lru); } } - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); if (table) return table; } @@ -214,6 +216,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) __free_page(page); return NULL; } + arch_set_page_dat(page, 0); /* Initialize page table */ table = (unsigned long *) page_to_phys(page); if (mm_alloc_pgste(mm)) { @@ -225,9 +228,9 @@ unsigned long *page_table_alloc(struct mm_struct *mm) /* Return the first 2K fragment of the page */ atomic_set(&page->_mapcount, 1); clear_table(table, _PAGE_INVALID, PAGE_SIZE); - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); list_add(&page->lru, &mm->context.pgtable_list); - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); } return table; } @@ -241,13 +244,13 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) if (!mm_alloc_pgste(mm)) { /* Free 2K page table fragment of a 4K page */ bit = (__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t)); - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); mask = atomic_xor_bits(&page->_mapcount, 1U << bit); if (mask & 3) list_add(&page->lru, &mm->context.pgtable_list); else list_del(&page->lru); - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); if (mask != 0) return; } @@ -273,13 +276,13 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table, return; } bit = (__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t)); - spin_lock_bh(&mm->context.pgtable_lock); + spin_lock_bh(&mm->context.lock); mask = atomic_xor_bits(&page->_mapcount, 0x11U << bit); if (mask & 3) list_add_tail(&page->lru, &mm->context.pgtable_list); else list_del(&page->lru); - spin_unlock_bh(&mm->context.pgtable_lock); + spin_unlock_bh(&mm->context.lock); table = (unsigned long *) (__pa(table) | (1U << bit)); tlb_remove_table(tlb, table); } diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 4a1f7366b17a..ae677f814bc0 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -25,8 +25,49 @@ #include #include +static inline void ptep_ipte_local(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, int nodat) +{ + unsigned long opt, asce; + + if (MACHINE_HAS_TLB_GUEST) { + opt = 0; + asce = READ_ONCE(mm->context.gmap_asce); + if (asce == 0UL || nodat) + opt |= IPTE_NODAT; + if (asce != -1UL) { + asce = asce ? : mm->context.asce; + opt |= IPTE_GUEST_ASCE; + } + __ptep_ipte(addr, ptep, opt, asce, IPTE_LOCAL); + } else { + __ptep_ipte(addr, ptep, 0, 0, IPTE_LOCAL); + } +} + +static inline void ptep_ipte_global(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, int nodat) +{ + unsigned long opt, asce; + + if (MACHINE_HAS_TLB_GUEST) { + opt = 0; + asce = READ_ONCE(mm->context.gmap_asce); + if (asce == 0UL || nodat) + opt |= IPTE_NODAT; + if (asce != -1UL) { + asce = asce ? : mm->context.asce; + opt |= IPTE_GUEST_ASCE; + } + __ptep_ipte(addr, ptep, opt, asce, IPTE_GLOBAL); + } else { + __ptep_ipte(addr, ptep, 0, 0, IPTE_GLOBAL); + } +} + static inline pte_t ptep_flush_direct(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) + unsigned long addr, pte_t *ptep, + int nodat) { pte_t old; @@ -36,15 +77,16 @@ static inline pte_t ptep_flush_direct(struct mm_struct *mm, atomic_inc(&mm->context.flush_count); if (MACHINE_HAS_TLB_LC && cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __ptep_ipte(addr, ptep, IPTE_LOCAL); + ptep_ipte_local(mm, addr, ptep, nodat); else - __ptep_ipte(addr, ptep, IPTE_GLOBAL); + ptep_ipte_global(mm, addr, ptep, nodat); atomic_dec(&mm->context.flush_count); return old; } static inline pte_t ptep_flush_lazy(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) + unsigned long addr, pte_t *ptep, + int nodat) { pte_t old; @@ -57,7 +99,7 @@ static inline pte_t ptep_flush_lazy(struct mm_struct *mm, pte_val(*ptep) |= _PAGE_INVALID; mm->context.flush_mm = 1; } else - __ptep_ipte(addr, ptep, IPTE_GLOBAL); + ptep_ipte_global(mm, addr, ptep, nodat); atomic_dec(&mm->context.flush_count); return old; } @@ -229,10 +271,12 @@ pte_t ptep_xchg_direct(struct mm_struct *mm, unsigned long addr, { pgste_t pgste; pte_t old; + int nodat; preempt_disable(); pgste = ptep_xchg_start(mm, addr, ptep); - old = ptep_flush_direct(mm, addr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + old = ptep_flush_direct(mm, addr, ptep, nodat); old = ptep_xchg_commit(mm, addr, ptep, pgste, old, new); preempt_enable(); return old; @@ -244,10 +288,12 @@ pte_t ptep_xchg_lazy(struct mm_struct *mm, unsigned long addr, { pgste_t pgste; pte_t old; + int nodat; preempt_disable(); pgste = ptep_xchg_start(mm, addr, ptep); - old = ptep_flush_lazy(mm, addr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + old = ptep_flush_lazy(mm, addr, ptep, nodat); old = ptep_xchg_commit(mm, addr, ptep, pgste, old, new); preempt_enable(); return old; @@ -259,10 +305,12 @@ pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, { pgste_t pgste; pte_t old; + int nodat; preempt_disable(); pgste = ptep_xchg_start(mm, addr, ptep); - old = ptep_flush_lazy(mm, addr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + old = ptep_flush_lazy(mm, addr, ptep, nodat); if (mm_has_pgste(mm)) { pgste = pgste_update_all(old, pgste, mm); pgste_set(ptep, pgste); @@ -290,6 +338,28 @@ void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, } EXPORT_SYMBOL(ptep_modify_prot_commit); +static inline void pmdp_idte_local(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp) +{ + if (MACHINE_HAS_TLB_GUEST) + __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_LOCAL); + else + __pmdp_idte(addr, pmdp, 0, 0, IDTE_LOCAL); +} + +static inline void pmdp_idte_global(struct mm_struct *mm, + unsigned long addr, pmd_t *pmdp) +{ + if (MACHINE_HAS_TLB_GUEST) + __pmdp_idte(addr, pmdp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_GLOBAL); + else if (MACHINE_HAS_IDTE) + __pmdp_idte(addr, pmdp, 0, 0, IDTE_GLOBAL); + else + __pmdp_csp(pmdp); +} + static inline pmd_t pmdp_flush_direct(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp) { @@ -298,16 +368,12 @@ static inline pmd_t pmdp_flush_direct(struct mm_struct *mm, old = *pmdp; if (pmd_val(old) & _SEGMENT_ENTRY_INVALID) return old; - if (!MACHINE_HAS_IDTE) { - __pmdp_csp(pmdp); - return old; - } atomic_inc(&mm->context.flush_count); if (MACHINE_HAS_TLB_LC && cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __pmdp_idte(addr, pmdp, IDTE_LOCAL); + pmdp_idte_local(mm, addr, pmdp); else - __pmdp_idte(addr, pmdp, IDTE_GLOBAL); + pmdp_idte_global(mm, addr, pmdp); atomic_dec(&mm->context.flush_count); return old; } @@ -325,10 +391,9 @@ static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm, cpumask_of(smp_processor_id()))) { pmd_val(*pmdp) |= _SEGMENT_ENTRY_INVALID; mm->context.flush_mm = 1; - } else if (MACHINE_HAS_IDTE) - __pmdp_idte(addr, pmdp, IDTE_GLOBAL); - else - __pmdp_csp(pmdp); + } else { + pmdp_idte_global(mm, addr, pmdp); + } atomic_dec(&mm->context.flush_count); return old; } @@ -359,6 +424,32 @@ pmd_t pmdp_xchg_lazy(struct mm_struct *mm, unsigned long addr, } EXPORT_SYMBOL(pmdp_xchg_lazy); +static inline void pudp_idte_local(struct mm_struct *mm, + unsigned long addr, pud_t *pudp) +{ + if (MACHINE_HAS_TLB_GUEST) + __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_LOCAL); + else + __pudp_idte(addr, pudp, 0, 0, IDTE_LOCAL); +} + +static inline void pudp_idte_global(struct mm_struct *mm, + unsigned long addr, pud_t *pudp) +{ + if (MACHINE_HAS_TLB_GUEST) + __pudp_idte(addr, pudp, IDTE_NODAT | IDTE_GUEST_ASCE, + mm->context.asce, IDTE_GLOBAL); + else if (MACHINE_HAS_IDTE) + __pudp_idte(addr, pudp, 0, 0, IDTE_GLOBAL); + else + /* + * Invalid bit position is the same for pmd and pud, so we can + * re-use _pmd_csp() here + */ + __pmdp_csp((pmd_t *) pudp); +} + static inline pud_t pudp_flush_direct(struct mm_struct *mm, unsigned long addr, pud_t *pudp) { @@ -367,20 +458,12 @@ static inline pud_t pudp_flush_direct(struct mm_struct *mm, old = *pudp; if (pud_val(old) & _REGION_ENTRY_INVALID) return old; - if (!MACHINE_HAS_IDTE) { - /* - * Invalid bit position is the same for pmd and pud, so we can - * re-use _pmd_csp() here - */ - __pmdp_csp((pmd_t *) pudp); - return old; - } atomic_inc(&mm->context.flush_count); if (MACHINE_HAS_TLB_LC && cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) - __pudp_idte(addr, pudp, IDTE_LOCAL); + pudp_idte_local(mm, addr, pudp); else - __pudp_idte(addr, pudp, IDTE_GLOBAL); + pudp_idte_global(mm, addr, pudp); atomic_dec(&mm->context.flush_count); return old; } @@ -482,7 +565,7 @@ int ptep_force_prot(struct mm_struct *mm, unsigned long addr, { pte_t entry; pgste_t pgste; - int pte_i, pte_p; + int pte_i, pte_p, nodat; pgste = pgste_get_lock(ptep); entry = *ptep; @@ -495,13 +578,14 @@ int ptep_force_prot(struct mm_struct *mm, unsigned long addr, return -EAGAIN; } /* Change access rights and set pgste bit */ + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); if (prot == PROT_NONE && !pte_i) { - ptep_flush_direct(mm, addr, ptep); + ptep_flush_direct(mm, addr, ptep, nodat); pgste = pgste_update_all(entry, pgste, mm); pte_val(entry) |= _PAGE_INVALID; } if (prot == PROT_READ && !pte_p) { - ptep_flush_direct(mm, addr, ptep); + ptep_flush_direct(mm, addr, ptep, nodat); pte_val(entry) &= ~_PAGE_INVALID; pte_val(entry) |= _PAGE_PROTECT; } @@ -541,10 +625,12 @@ int ptep_shadow_pte(struct mm_struct *mm, unsigned long saddr, void ptep_unshadow_pte(struct mm_struct *mm, unsigned long saddr, pte_t *ptep) { pgste_t pgste; + int nodat; pgste = pgste_get_lock(ptep); /* notifier is called by the caller */ - ptep_flush_direct(mm, saddr, ptep); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + ptep_flush_direct(mm, saddr, ptep, nodat); /* don't touch the storage key - it belongs to parent pgste */ pgste = pgste_set_pte(ptep, pgste, __pte(_PAGE_INVALID)); pgste_set_unlock(ptep, pgste); @@ -617,6 +703,7 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr) pte_t *ptep; pte_t pte; bool dirty; + int nodat; pgd = pgd_offset(mm, addr); p4d = p4d_alloc(mm, pgd, addr); @@ -645,7 +732,8 @@ bool test_and_clear_guest_dirty(struct mm_struct *mm, unsigned long addr) pte = *ptep; if (dirty && (pte_val(pte) & _PAGE_PRESENT)) { pgste = pgste_pte_notify(mm, addr, ptep, pgste); - __ptep_ipte(addr, ptep, IPTE_GLOBAL); + nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT); + ptep_ipte_global(mm, addr, ptep, nodat); if (MACHINE_HAS_ESOP || !(pte_val(pte) & _PAGE_WRITE)) pte_val(pte) |= _PAGE_PROTECT; else @@ -831,7 +919,7 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, case ESSA_GET_STATE: break; case ESSA_SET_STABLE: - pgstev &= ~_PGSTE_GPS_USAGE_MASK; + pgstev &= ~(_PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT); pgstev |= _PGSTE_GPS_USAGE_STABLE; break; case ESSA_SET_UNUSED: @@ -877,6 +965,10 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, pgstev |= _PGSTE_GPS_USAGE_STABLE; } break; + case ESSA_SET_STABLE_NODAT: + pgstev &= ~_PGSTE_GPS_USAGE_MASK; + pgstev |= _PGSTE_GPS_USAGE_STABLE | _PGSTE_GPS_NODAT; + break; default: /* we should never get here! */ break; diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index d8398962a723..f2ada0bc08e6 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2006 * Author(s): Heiko Carstens @@ -38,37 +39,14 @@ static void __ref *vmem_alloc_pages(unsigned int order) return (void *) memblock_alloc(size, size); } -static inline p4d_t *vmem_p4d_alloc(void) +void *vmem_crst_alloc(unsigned long val) { - p4d_t *p4d = NULL; + unsigned long *table; - p4d = vmem_alloc_pages(2); - if (!p4d) - return NULL; - clear_table((unsigned long *) p4d, _REGION2_ENTRY_EMPTY, PAGE_SIZE * 4); - return p4d; -} - -static inline pud_t *vmem_pud_alloc(void) -{ - pud_t *pud = NULL; - - pud = vmem_alloc_pages(2); - if (!pud) - return NULL; - clear_table((unsigned long *) pud, _REGION3_ENTRY_EMPTY, PAGE_SIZE * 4); - return pud; -} - -pmd_t *vmem_pmd_alloc(void) -{ - pmd_t *pmd = NULL; - - pmd = vmem_alloc_pages(2); - if (!pmd) - return NULL; - clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE * 4); - return pmd; + table = vmem_alloc_pages(CRST_ALLOC_ORDER); + if (table) + crst_table_init(table, val); + return table; } pte_t __ref *vmem_pte_alloc(void) @@ -114,14 +92,14 @@ static int vmem_add_mem(unsigned long start, unsigned long size) while (address < end) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { - p4_dir = vmem_p4d_alloc(); + p4_dir = vmem_crst_alloc(_REGION2_ENTRY_EMPTY); if (!p4_dir) goto out; pgd_populate(&init_mm, pg_dir, p4_dir); } p4_dir = p4d_offset(pg_dir, address); if (p4d_none(*p4_dir)) { - pu_dir = vmem_pud_alloc(); + pu_dir = vmem_crst_alloc(_REGION3_ENTRY_EMPTY); if (!pu_dir) goto out; p4d_populate(&init_mm, p4_dir, pu_dir); @@ -136,7 +114,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size) continue; } if (pud_none(*pu_dir)) { - pm_dir = vmem_pmd_alloc(); + pm_dir = vmem_crst_alloc(_SEGMENT_ENTRY_EMPTY); if (!pm_dir) goto out; pud_populate(&init_mm, pu_dir, pm_dir); @@ -253,7 +231,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) for (address = start; address < end;) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { - p4_dir = vmem_p4d_alloc(); + p4_dir = vmem_crst_alloc(_REGION2_ENTRY_EMPTY); if (!p4_dir) goto out; pgd_populate(&init_mm, pg_dir, p4_dir); @@ -261,7 +239,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) p4_dir = p4d_offset(pg_dir, address); if (p4d_none(*p4_dir)) { - pu_dir = vmem_pud_alloc(); + pu_dir = vmem_crst_alloc(_REGION3_ENTRY_EMPTY); if (!pu_dir) goto out; p4d_populate(&init_mm, p4_dir, pu_dir); @@ -269,7 +247,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) pu_dir = pud_offset(p4_dir, address); if (pud_none(*pu_dir)) { - pm_dir = vmem_pmd_alloc(); + pm_dir = vmem_crst_alloc(_SEGMENT_ENTRY_EMPTY); if (!pm_dir) goto out; pud_populate(&init_mm, pu_dir, pm_dir); diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S index a1c917d881ec..25bb4643c4f4 100644 --- a/arch/s390/net/bpf_jit.S +++ b/arch/s390/net/bpf_jit.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * BPF Jit compiler for s390, help functions. * diff --git a/arch/s390/net/bpf_jit.h b/arch/s390/net/bpf_jit.h index fda605dbc1b4..7fa55ccffe48 100644 --- a/arch/s390/net/bpf_jit.h +++ b/arch/s390/net/bpf_jit.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * BPF Jit compiler defines * diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 1803797fc885..b15cd2f0320f 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * BPF Jit compiler for s390. * @@ -1093,15 +1094,27 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i case BPF_JMP | BPF_JSGT | BPF_K: /* ((s64) dst > (s64) imm) */ mask = 0x2000; /* jh */ goto branch_ks; + case BPF_JMP | BPF_JSLT | BPF_K: /* ((s64) dst < (s64) imm) */ + mask = 0x4000; /* jl */ + goto branch_ks; case BPF_JMP | BPF_JSGE | BPF_K: /* ((s64) dst >= (s64) imm) */ mask = 0xa000; /* jhe */ goto branch_ks; + case BPF_JMP | BPF_JSLE | BPF_K: /* ((s64) dst <= (s64) imm) */ + mask = 0xc000; /* jle */ + goto branch_ks; case BPF_JMP | BPF_JGT | BPF_K: /* (dst_reg > imm) */ mask = 0x2000; /* jh */ goto branch_ku; + case BPF_JMP | BPF_JLT | BPF_K: /* (dst_reg < imm) */ + mask = 0x4000; /* jl */ + goto branch_ku; case BPF_JMP | BPF_JGE | BPF_K: /* (dst_reg >= imm) */ mask = 0xa000; /* jhe */ goto branch_ku; + case BPF_JMP | BPF_JLE | BPF_K: /* (dst_reg <= imm) */ + mask = 0xc000; /* jle */ + goto branch_ku; case BPF_JMP | BPF_JNE | BPF_K: /* (dst_reg != imm) */ mask = 0x7000; /* jne */ goto branch_ku; @@ -1119,15 +1132,27 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i case BPF_JMP | BPF_JSGT | BPF_X: /* ((s64) dst > (s64) src) */ mask = 0x2000; /* jh */ goto branch_xs; + case BPF_JMP | BPF_JSLT | BPF_X: /* ((s64) dst < (s64) src) */ + mask = 0x4000; /* jl */ + goto branch_xs; case BPF_JMP | BPF_JSGE | BPF_X: /* ((s64) dst >= (s64) src) */ mask = 0xa000; /* jhe */ goto branch_xs; + case BPF_JMP | BPF_JSLE | BPF_X: /* ((s64) dst <= (s64) src) */ + mask = 0xc000; /* jle */ + goto branch_xs; case BPF_JMP | BPF_JGT | BPF_X: /* (dst > src) */ mask = 0x2000; /* jh */ goto branch_xu; + case BPF_JMP | BPF_JLT | BPF_X: /* (dst < src) */ + mask = 0x4000; /* jl */ + goto branch_xu; case BPF_JMP | BPF_JGE | BPF_X: /* (dst >= src) */ mask = 0xa000; /* jhe */ goto branch_xu; + case BPF_JMP | BPF_JLE | BPF_X: /* (dst <= src) */ + mask = 0xc000; /* jle */ + goto branch_xu; case BPF_JMP | BPF_JNE | BPF_X: /* (dst != src) */ mask = 0x7000; /* jne */ goto branch_xu; diff --git a/arch/s390/numa/mode_emu.c b/arch/s390/numa/mode_emu.c index cfd08384f0ab..83b222c57609 100644 --- a/arch/s390/numa/mode_emu.c +++ b/arch/s390/numa/mode_emu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NUMA support for s390 * diff --git a/arch/s390/numa/numa.c b/arch/s390/numa/numa.c index f576f1073378..06a80434cfe6 100644 --- a/arch/s390/numa/numa.c +++ b/arch/s390/numa/numa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NUMA support for s390 * diff --git a/arch/s390/numa/numa_mode.h b/arch/s390/numa/numa_mode.h index 08953b0b1c7f..dfd3e2784081 100644 --- a/arch/s390/numa/numa_mode.h +++ b/arch/s390/numa/numa_mode.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * NUMA support for s390 * diff --git a/arch/s390/numa/toptree.c b/arch/s390/numa/toptree.c index 26f622b1cd11..21d1e8a1546d 100644 --- a/arch/s390/numa/toptree.c +++ b/arch/s390/numa/toptree.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NUMA support for s390 * diff --git a/arch/s390/numa/toptree.h b/arch/s390/numa/toptree.h index bdf502027af4..5246371ec713 100644 --- a/arch/s390/numa/toptree.h +++ b/arch/s390/numa/toptree.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * NUMA support for s390 * diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile index e9dd41b0b8d3..36261f9d360b 100644 --- a/arch/s390/oprofile/Makefile +++ b/arch/s390/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 9a4de4599c7b..43d9525c36fc 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * S390 Version * Copyright IBM Corp. 2002, 2011 diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 7b30af5da222..a25d95a6612d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -262,10 +262,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) return rc; } -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - resource_size_t pcibios_align_resource(void *data, const struct resource *res, resource_size_t size, resource_size_t align) @@ -776,6 +772,7 @@ void pcibios_remove_bus(struct pci_bus *bus) zpci_exit_slot(zdev); zpci_cleanup_bus_resources(zdev); + zpci_destroy_iommu(zdev); zpci_free_domain(zdev); spin_lock(&zpci_list_lock); @@ -848,11 +845,15 @@ int zpci_create_device(struct zpci_dev *zdev) if (rc) goto out; + rc = zpci_init_iommu(zdev); + if (rc) + goto out_free; + mutex_init(&zdev->lock); if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { rc = zpci_enable_device(zdev); if (rc) - goto out_free; + goto out_destroy_iommu; } rc = zpci_scan_bus(zdev); if (rc) @@ -869,6 +870,8 @@ int zpci_create_device(struct zpci_dev *zdev) out_disable: if (zdev->state == ZPCI_FN_STATE_ONLINE) zpci_disable_device(zdev); +out_destroy_iommu: + zpci_destroy_iommu(zdev); out_free: zpci_free_domain(zdev); out: diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index bd534b4d40e3..93cd0f1ca12b 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2012 * @@ -24,6 +25,14 @@ bool zpci_unique_uid; +static void update_uid_checking(bool new) +{ + if (zpci_unique_uid != new) + zpci_dbg(1, "uid checking:%d\n", new); + + zpci_unique_uid = new; +} + static inline void zpci_err_clp(unsigned int rsp, int rc) { struct { @@ -319,7 +328,7 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, void *data, goto out; } - zpci_unique_uid = rrb->response.uid_checking; + update_uid_checking(rrb->response.uid_checking); WARN_ON_ONCE(rrb->response.entry_size != sizeof(struct clp_fh_list_entry)); diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index 0bbc04af4418..8d6ee4af4230 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2012 * diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c index b1bb2b72302c..7d42a8794f10 100644 --- a/arch/s390/pci/pci_mmio.c +++ b/arch/s390/pci/pci_mmio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Access to PCI I/O memory from user space programs. * diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c index ed484dc84d14..430c14b006d1 100644 --- a/arch/s390/pci/pci_sysfs.c +++ b/arch/s390/pci/pci_sysfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2012 * diff --git a/arch/s390/tools/Makefile b/arch/s390/tools/Makefile index 4b5e1e499527..d54c149fbb6b 100644 --- a/arch/s390/tools/Makefile +++ b/arch/s390/tools/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for s390 specific build tools # diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c index 025ea20fc4b4..0373801d9860 100644 --- a/arch/s390/tools/gen_facilities.c +++ b/arch/s390/tools/gen_facilities.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Simple program to generate defines out of facility lists that use the bit * numbering scheme from the Princples of Operations: most significant bit @@ -41,7 +42,7 @@ static struct facility_def facility_defs[] = { 27, /* mvcos */ 32, /* compare and swap and store */ 33, /* compare and swap and store 2 */ - 34, /* general extension facility */ + 34, /* general instructions extension */ 35, /* execute extensions */ #endif #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES @@ -53,6 +54,9 @@ static struct facility_def facility_defs[] = { #endif #ifdef CONFIG_HAVE_MARCH_Z13_FEATURES 53, /* load-and-zero-rightmost-byte, etc. */ +#endif +#ifdef CONFIG_HAVE_MARCH_Z14_FEATURES + 58, /* miscellaneous-instruction-extension 2 */ #endif -1 /* END */ } @@ -80,6 +84,7 @@ static struct facility_def facility_defs[] = { 78, /* enhanced-DAT 2 */ 130, /* instruction-execution-protection */ 131, /* enhanced-SOP 2 and side-effect */ + 139, /* multiple epoch facility */ 146, /* msa extension 8 */ -1 /* END */ } diff --git a/arch/score/Kconfig b/arch/score/Kconfig index 507d63181389..d881f99c9ddd 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Machine selection" config SCORE diff --git a/arch/score/Kconfig.debug b/arch/score/Kconfig.debug index d8a9b2d146ee..041e51dcdafb 100644 --- a/arch/score/Kconfig.debug +++ b/arch/score/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT diff --git a/arch/score/include/asm/asmmacro.h b/arch/score/include/asm/asmmacro.h index a04a54cea25d..7370a35d17d1 100644 --- a/arch/score/include/asm/asmmacro.h +++ b/arch/score/include/asm/asmmacro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_ASMMACRO_H #define _ASM_SCORE_ASMMACRO_H diff --git a/arch/score/include/asm/atomic.h b/arch/score/include/asm/atomic.h index edf33dbded1e..56700980b9be 100644 --- a/arch/score/include/asm/atomic.h +++ b/arch/score/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_ATOMIC_H #define _ASM_SCORE_ATOMIC_H diff --git a/arch/score/include/asm/bitops.h b/arch/score/include/asm/bitops.h index c1bf8d6d0fb0..6342b0123725 100644 --- a/arch/score/include/asm/bitops.h +++ b/arch/score/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_BITOPS_H #define _ASM_SCORE_BITOPS_H diff --git a/arch/score/include/asm/bug.h b/arch/score/include/asm/bug.h index fd7164af1f04..966b2e9e8d74 100644 --- a/arch/score/include/asm/bug.h +++ b/arch/score/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_BUG_H #define _ASM_SCORE_BUG_H diff --git a/arch/score/include/asm/bugs.h b/arch/score/include/asm/bugs.h index a062e1056bb3..81185dced763 100644 --- a/arch/score/include/asm/bugs.h +++ b/arch/score/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_BUGS_H #define _ASM_SCORE_BUGS_H diff --git a/arch/score/include/asm/cache.h b/arch/score/include/asm/cache.h index ae3d59f2d2c4..d55de3cbbb9f 100644 --- a/arch/score/include/asm/cache.h +++ b/arch/score/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_CACHE_H #define _ASM_SCORE_CACHE_H diff --git a/arch/score/include/asm/cacheflush.h b/arch/score/include/asm/cacheflush.h index 1d545d0ce206..cf1e609634fd 100644 --- a/arch/score/include/asm/cacheflush.h +++ b/arch/score/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_CACHEFLUSH_H #define _ASM_SCORE_CACHEFLUSH_H diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h index 0338927f4826..9f00ca5fd49d 100644 --- a/arch/score/include/asm/checksum.h +++ b/arch/score/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_CHECKSUM_H #define _ASM_SCORE_CHECKSUM_H diff --git a/arch/score/include/asm/cmpxchg.h b/arch/score/include/asm/cmpxchg.h index cc3f6420b71c..e503073c8978 100644 --- a/arch/score/include/asm/cmpxchg.h +++ b/arch/score/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_CMPXCHG_H #define _ASM_SCORE_CMPXCHG_H diff --git a/arch/score/include/asm/delay.h b/arch/score/include/asm/delay.h index 529e494712a5..a4bd2c748ab4 100644 --- a/arch/score/include/asm/delay.h +++ b/arch/score/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_DELAY_H #define _ASM_SCORE_DELAY_H diff --git a/arch/score/include/asm/device.h b/arch/score/include/asm/device.h index 2dc7cc5d5ef9..818ad4d01197 100644 --- a/arch/score/include/asm/device.h +++ b/arch/score/include/asm/device.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_DEVICE_H #define _ASM_SCORE_DEVICE_H diff --git a/arch/score/include/asm/div64.h b/arch/score/include/asm/div64.h index 75fae19824eb..cf73dc218bec 100644 --- a/arch/score/include/asm/div64.h +++ b/arch/score/include/asm/div64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_DIV64_H #define _ASM_SCORE_DIV64_H diff --git a/arch/score/include/asm/dma.h b/arch/score/include/asm/dma.h index 9f44185298bf..fd44a9cbee4f 100644 --- a/arch/score/include/asm/dma.h +++ b/arch/score/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_DMA_H #define _ASM_SCORE_DMA_H diff --git a/arch/score/include/asm/elf.h b/arch/score/include/asm/elf.h index 6a9421c693ca..c970ac160f3c 100644 --- a/arch/score/include/asm/elf.h +++ b/arch/score/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_ELF_H #define _ASM_SCORE_ELF_H diff --git a/arch/score/include/asm/emergency-restart.h b/arch/score/include/asm/emergency-restart.h index ca31e9803a8a..b0612c677764 100644 --- a/arch/score/include/asm/emergency-restart.h +++ b/arch/score/include/asm/emergency-restart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_EMERGENCY_RESTART_H #define _ASM_SCORE_EMERGENCY_RESTART_H diff --git a/arch/score/include/asm/exec.h b/arch/score/include/asm/exec.h index f9f3cd59c860..a1f95e1d8a31 100644 --- a/arch/score/include/asm/exec.h +++ b/arch/score/include/asm/exec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_EXEC_H #define _ASM_SCORE_EXEC_H diff --git a/arch/score/include/asm/fixmap.h b/arch/score/include/asm/fixmap.h index ee1676694024..68ca314830c9 100644 --- a/arch/score/include/asm/fixmap.h +++ b/arch/score/include/asm/fixmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_FIXMAP_H #define _ASM_SCORE_FIXMAP_H diff --git a/arch/score/include/asm/futex.h b/arch/score/include/asm/futex.h index 1dca2420f8db..ec247fb364c9 100644 --- a/arch/score/include/asm/futex.h +++ b/arch/score/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_FUTEX_H #define _ASM_SCORE_FUTEX_H diff --git a/arch/score/include/asm/hardirq.h b/arch/score/include/asm/hardirq.h index dc932c50d3ee..d8dd8909cb18 100644 --- a/arch/score/include/asm/hardirq.h +++ b/arch/score/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_HARDIRQ_H #define _ASM_SCORE_HARDIRQ_H diff --git a/arch/score/include/asm/io.h b/arch/score/include/asm/io.h index 574c8827abe2..37ce8723b06b 100644 --- a/arch/score/include/asm/io.h +++ b/arch/score/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_IO_H #define _ASM_SCORE_IO_H diff --git a/arch/score/include/asm/irq.h b/arch/score/include/asm/irq.h index c883f3df33fa..c1434c889de2 100644 --- a/arch/score/include/asm/irq.h +++ b/arch/score/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_IRQ_H #define _ASM_SCORE_IRQ_H diff --git a/arch/score/include/asm/irq_regs.h b/arch/score/include/asm/irq_regs.h index b8e881c9a69f..740b2315d848 100644 --- a/arch/score/include/asm/irq_regs.h +++ b/arch/score/include/asm/irq_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_IRQ_REGS_H #define _ASM_SCORE_IRQ_REGS_H diff --git a/arch/score/include/asm/irqflags.h b/arch/score/include/asm/irqflags.h index 37c6ac9dd6e8..354c1979ea8d 100644 --- a/arch/score/include/asm/irqflags.h +++ b/arch/score/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_IRQFLAGS_H #define _ASM_SCORE_IRQFLAGS_H diff --git a/arch/score/include/asm/kdebug.h b/arch/score/include/asm/kdebug.h index a666e513f747..481ba1fb5372 100644 --- a/arch/score/include/asm/kdebug.h +++ b/arch/score/include/asm/kdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_KDEBUG_H #define _ASM_SCORE_KDEBUG_H diff --git a/arch/score/include/asm/kmap_types.h b/arch/score/include/asm/kmap_types.h index 6c46eb5077d3..14261872c9c7 100644 --- a/arch/score/include/asm/kmap_types.h +++ b/arch/score/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_KMAP_TYPES_H #define _ASM_SCORE_KMAP_TYPES_H diff --git a/arch/score/include/asm/linkage.h b/arch/score/include/asm/linkage.h index 2323a8ecf445..0c11c009969a 100644 --- a/arch/score/include/asm/linkage.h +++ b/arch/score/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_LINKAGE_H #define _ASM_SCORE_LINKAGE_H diff --git a/arch/score/include/asm/local.h b/arch/score/include/asm/local.h index 7e02f13dbba8..00bdebdf75f2 100644 --- a/arch/score/include/asm/local.h +++ b/arch/score/include/asm/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_LOCAL_H #define _ASM_SCORE_LOCAL_H diff --git a/arch/score/include/asm/mmu.h b/arch/score/include/asm/mmu.h index 676828e4c10a..d913369adda3 100644 --- a/arch/score/include/asm/mmu.h +++ b/arch/score/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_MMU_H #define _ASM_SCORE_MMU_H diff --git a/arch/score/include/asm/mmu_context.h b/arch/score/include/asm/mmu_context.h index 073f95d350de..d0aa2a5aebca 100644 --- a/arch/score/include/asm/mmu_context.h +++ b/arch/score/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_MMU_CONTEXT_H #define _ASM_SCORE_MMU_CONTEXT_H diff --git a/arch/score/include/asm/module.h b/arch/score/include/asm/module.h index 6dc1f2935eef..33777ed32e9e 100644 --- a/arch/score/include/asm/module.h +++ b/arch/score/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_MODULE_H #define _ASM_SCORE_MODULE_H diff --git a/arch/score/include/asm/page.h b/arch/score/include/asm/page.h index 1e9ade8e77e6..17d9c68b6bd5 100644 --- a/arch/score/include/asm/page.h +++ b/arch/score/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_PAGE_H #define _ASM_SCORE_PAGE_H diff --git a/arch/score/include/asm/percpu.h b/arch/score/include/asm/percpu.h index e7bd4e05b475..5a6a2f7e5d62 100644 --- a/arch/score/include/asm/percpu.h +++ b/arch/score/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_PERCPU_H #define _ASM_SCORE_PERCPU_H diff --git a/arch/score/include/asm/pgalloc.h b/arch/score/include/asm/pgalloc.h index 49b012d78c1a..7dfc5c163093 100644 --- a/arch/score/include/asm/pgalloc.h +++ b/arch/score/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_PGALLOC_H #define _ASM_SCORE_PGALLOC_H diff --git a/arch/score/include/asm/pgtable-bits.h b/arch/score/include/asm/pgtable-bits.h index 0e5c6f466520..fb8f306f4d11 100644 --- a/arch/score/include/asm/pgtable-bits.h +++ b/arch/score/include/asm/pgtable-bits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_PGTABLE_BITS_H #define _ASM_SCORE_PGTABLE_BITS_H diff --git a/arch/score/include/asm/pgtable.h b/arch/score/include/asm/pgtable.h index 46ff8fd678a7..c14226be0559 100644 --- a/arch/score/include/asm/pgtable.h +++ b/arch/score/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_PGTABLE_H #define _ASM_SCORE_PGTABLE_H diff --git a/arch/score/include/asm/processor.h b/arch/score/include/asm/processor.h index 299274581968..1412c774c6b1 100644 --- a/arch/score/include/asm/processor.h +++ b/arch/score/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_PROCESSOR_H #define _ASM_SCORE_PROCESSOR_H diff --git a/arch/score/include/asm/ptrace.h b/arch/score/include/asm/ptrace.h index abc279d96b73..026b9c51bee8 100644 --- a/arch/score/include/asm/ptrace.h +++ b/arch/score/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_PTRACE_H #define _ASM_SCORE_PTRACE_H diff --git a/arch/score/include/asm/scoreregs.h b/arch/score/include/asm/scoreregs.h index d0ad29204518..ff8d20a49aa7 100644 --- a/arch/score/include/asm/scoreregs.h +++ b/arch/score/include/asm/scoreregs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_SCOREREGS_H #define _ASM_SCORE_SCOREREGS_H diff --git a/arch/score/include/asm/segment.h b/arch/score/include/asm/segment.h index e16cf6afb495..b00c277e17ff 100644 --- a/arch/score/include/asm/segment.h +++ b/arch/score/include/asm/segment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_SEGMENT_H #define _ASM_SCORE_SEGMENT_H diff --git a/arch/score/include/asm/setup.h b/arch/score/include/asm/setup.h index 1f3aa7262fa3..a596d0bd0632 100644 --- a/arch/score/include/asm/setup.h +++ b/arch/score/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_SETUP_H #define _ASM_SCORE_SETUP_H diff --git a/arch/score/include/asm/shmparam.h b/arch/score/include/asm/shmparam.h index 1d60813141b6..01a3d0eaed80 100644 --- a/arch/score/include/asm/shmparam.h +++ b/arch/score/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_SHMPARAM_H #define _ASM_SCORE_SHMPARAM_H diff --git a/arch/score/include/asm/string.h b/arch/score/include/asm/string.h index 8a6bf5063aa5..3debf3b234b7 100644 --- a/arch/score/include/asm/string.h +++ b/arch/score/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_STRING_H #define _ASM_SCORE_STRING_H diff --git a/arch/score/include/asm/switch_to.h b/arch/score/include/asm/switch_to.h index fda3f83308d2..ce730e60cd43 100644 --- a/arch/score/include/asm/switch_to.h +++ b/arch/score/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_SWITCH_TO_H #define _ASM_SCORE_SWITCH_TO_H diff --git a/arch/score/include/asm/syscalls.h b/arch/score/include/asm/syscalls.h index 98d1df92fbd1..caa099fd9a8e 100644 --- a/arch/score/include/asm/syscalls.h +++ b/arch/score/include/asm/syscalls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_SYSCALLS_H #define _ASM_SCORE_SYSCALLS_H diff --git a/arch/score/include/asm/thread_info.h b/arch/score/include/asm/thread_info.h index 7d9ffb15c477..ad51b56e51bd 100644 --- a/arch/score/include/asm/thread_info.h +++ b/arch/score/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_THREAD_INFO_H #define _ASM_SCORE_THREAD_INFO_H diff --git a/arch/score/include/asm/timex.h b/arch/score/include/asm/timex.h index a524ae0c5e7b..ea8e7ff49e57 100644 --- a/arch/score/include/asm/timex.h +++ b/arch/score/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_TIMEX_H #define _ASM_SCORE_TIMEX_H diff --git a/arch/score/include/asm/tlb.h b/arch/score/include/asm/tlb.h index 46882ed524e6..6e7206428877 100644 --- a/arch/score/include/asm/tlb.h +++ b/arch/score/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_TLB_H #define _ASM_SCORE_TLB_H diff --git a/arch/score/include/asm/tlbflush.h b/arch/score/include/asm/tlbflush.h index 9cce978367d5..f48722f4b00e 100644 --- a/arch/score/include/asm/tlbflush.h +++ b/arch/score/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_TLBFLUSH_H #define _ASM_SCORE_TLBFLUSH_H diff --git a/arch/score/include/asm/topology.h b/arch/score/include/asm/topology.h index 425fba381f88..06577d2a1808 100644 --- a/arch/score/include/asm/topology.h +++ b/arch/score/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_TOPOLOGY_H #define _ASM_SCORE_TOPOLOGY_H diff --git a/arch/score/include/asm/uaccess.h b/arch/score/include/asm/uaccess.h index 0ef220474d9b..a233f3236846 100644 --- a/arch/score/include/asm/uaccess.h +++ b/arch/score/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SCORE_UACCESS_H #define __SCORE_UACCESS_H diff --git a/arch/score/include/asm/unaligned.h b/arch/score/include/asm/unaligned.h index 2fc06de51c62..5db6c805ce7e 100644 --- a/arch/score/include/asm/unaligned.h +++ b/arch/score/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_UNALIGNED_H #define _ASM_SCORE_UNALIGNED_H diff --git a/arch/score/include/asm/user.h b/arch/score/include/asm/user.h index 7bfb8e2c8054..f7b0f3434e72 100644 --- a/arch/score/include/asm/user.h +++ b/arch/score/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SCORE_USER_H #define _ASM_SCORE_USER_H diff --git a/arch/score/include/uapi/asm/bitsperlong.h b/arch/score/include/uapi/asm/bitsperlong.h index 86ff337aa459..df48f2717da2 100644 --- a/arch/score/include/uapi/asm/bitsperlong.h +++ b/arch/score/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_BITSPERLONG_H #define _ASM_SCORE_BITSPERLONG_H diff --git a/arch/score/include/uapi/asm/byteorder.h b/arch/score/include/uapi/asm/byteorder.h index 88cbebc79212..a5247ea66c03 100644 --- a/arch/score/include/uapi/asm/byteorder.h +++ b/arch/score/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_BYTEORDER_H #define _ASM_SCORE_BYTEORDER_H diff --git a/arch/score/include/uapi/asm/errno.h b/arch/score/include/uapi/asm/errno.h index 29ff39d5ab47..1b914865714f 100644 --- a/arch/score/include/uapi/asm/errno.h +++ b/arch/score/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_ERRNO_H #define _ASM_SCORE_ERRNO_H diff --git a/arch/score/include/uapi/asm/fcntl.h b/arch/score/include/uapi/asm/fcntl.h index 03968a3103a4..9c5053b87c66 100644 --- a/arch/score/include/uapi/asm/fcntl.h +++ b/arch/score/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_FCNTL_H #define _ASM_SCORE_FCNTL_H diff --git a/arch/score/include/uapi/asm/ioctl.h b/arch/score/include/uapi/asm/ioctl.h index a351d2194bfd..d6cb6dc33d5f 100644 --- a/arch/score/include/uapi/asm/ioctl.h +++ b/arch/score/include/uapi/asm/ioctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_IOCTL_H #define _ASM_SCORE_IOCTL_H diff --git a/arch/score/include/uapi/asm/ioctls.h b/arch/score/include/uapi/asm/ioctls.h index ed01d2b9aeab..b93b011f02aa 100644 --- a/arch/score/include/uapi/asm/ioctls.h +++ b/arch/score/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_IOCTLS_H #define _ASM_SCORE_IOCTLS_H diff --git a/arch/score/include/uapi/asm/ipcbuf.h b/arch/score/include/uapi/asm/ipcbuf.h index e082ceff1818..195ee525308d 100644 --- a/arch/score/include/uapi/asm/ipcbuf.h +++ b/arch/score/include/uapi/asm/ipcbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_IPCBUF_H #define _ASM_SCORE_IPCBUF_H diff --git a/arch/score/include/uapi/asm/kvm_para.h b/arch/score/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/score/include/uapi/asm/kvm_para.h +++ b/arch/score/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/score/include/uapi/asm/mman.h b/arch/score/include/uapi/asm/mman.h index 84d85ddfed8d..b22b83809432 100644 --- a/arch/score/include/uapi/asm/mman.h +++ b/arch/score/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_MMAN_H #define _ASM_SCORE_MMAN_H diff --git a/arch/score/include/uapi/asm/msgbuf.h b/arch/score/include/uapi/asm/msgbuf.h index 7506721e29fa..b05a238756ab 100644 --- a/arch/score/include/uapi/asm/msgbuf.h +++ b/arch/score/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_MSGBUF_H #define _ASM_SCORE_MSGBUF_H diff --git a/arch/score/include/uapi/asm/param.h b/arch/score/include/uapi/asm/param.h index 916b8690b6aa..ce09e2632681 100644 --- a/arch/score/include/uapi/asm/param.h +++ b/arch/score/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_PARAM_H #define _ASM_SCORE_PARAM_H diff --git a/arch/score/include/uapi/asm/poll.h b/arch/score/include/uapi/asm/poll.h index 18532db02861..c636b85843cd 100644 --- a/arch/score/include/uapi/asm/poll.h +++ b/arch/score/include/uapi/asm/poll.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_POLL_H #define _ASM_SCORE_POLL_H diff --git a/arch/score/include/uapi/asm/posix_types.h b/arch/score/include/uapi/asm/posix_types.h index b88acf80048a..63200d56a4a9 100644 --- a/arch/score/include/uapi/asm/posix_types.h +++ b/arch/score/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_POSIX_TYPES_H #define _ASM_SCORE_POSIX_TYPES_H diff --git a/arch/score/include/uapi/asm/ptrace.h b/arch/score/include/uapi/asm/ptrace.h index 5c5e794058be..e8bd4923f96e 100644 --- a/arch/score/include/uapi/asm/ptrace.h +++ b/arch/score/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_SCORE_PTRACE_H #define _UAPI_ASM_SCORE_PTRACE_H diff --git a/arch/score/include/uapi/asm/resource.h b/arch/score/include/uapi/asm/resource.h index 9ce22bc7b475..df3fb9c942c4 100644 --- a/arch/score/include/uapi/asm/resource.h +++ b/arch/score/include/uapi/asm/resource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_RESOURCE_H #define _ASM_SCORE_RESOURCE_H diff --git a/arch/score/include/uapi/asm/sembuf.h b/arch/score/include/uapi/asm/sembuf.h index dae5e835ce9e..c16e7a94725d 100644 --- a/arch/score/include/uapi/asm/sembuf.h +++ b/arch/score/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_SEMBUF_H #define _ASM_SCORE_SEMBUF_H diff --git a/arch/score/include/uapi/asm/setup.h b/arch/score/include/uapi/asm/setup.h index ab9dbdb59bba..dee58323847e 100644 --- a/arch/score/include/uapi/asm/setup.h +++ b/arch/score/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_SCORE_SETUP_H #define _UAPI_ASM_SCORE_SETUP_H diff --git a/arch/score/include/uapi/asm/shmbuf.h b/arch/score/include/uapi/asm/shmbuf.h index c85b2429ba21..f38acfe733cd 100644 --- a/arch/score/include/uapi/asm/shmbuf.h +++ b/arch/score/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_SHMBUF_H #define _ASM_SCORE_SHMBUF_H diff --git a/arch/score/include/uapi/asm/sigcontext.h b/arch/score/include/uapi/asm/sigcontext.h index 5ffda39ddb90..2b0cd93a71f6 100644 --- a/arch/score/include/uapi/asm/sigcontext.h +++ b/arch/score/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_SIGCONTEXT_H #define _ASM_SCORE_SIGCONTEXT_H diff --git a/arch/score/include/uapi/asm/signal.h b/arch/score/include/uapi/asm/signal.h index 2605bc06b64f..7fb694972302 100644 --- a/arch/score/include/uapi/asm/signal.h +++ b/arch/score/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_SIGNAL_H #define _ASM_SCORE_SIGNAL_H diff --git a/arch/score/include/uapi/asm/socket.h b/arch/score/include/uapi/asm/socket.h index 612a70e385ba..f76ba1f72354 100644 --- a/arch/score/include/uapi/asm/socket.h +++ b/arch/score/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_SOCKET_H #define _ASM_SCORE_SOCKET_H diff --git a/arch/score/include/uapi/asm/sockios.h b/arch/score/include/uapi/asm/sockios.h index ba8256480189..d0af8ce4373b 100644 --- a/arch/score/include/uapi/asm/sockios.h +++ b/arch/score/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_SOCKIOS_H #define _ASM_SCORE_SOCKIOS_H diff --git a/arch/score/include/uapi/asm/stat.h b/arch/score/include/uapi/asm/stat.h index 5037055500a2..669b69f764df 100644 --- a/arch/score/include/uapi/asm/stat.h +++ b/arch/score/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_STAT_H #define _ASM_SCORE_STAT_H diff --git a/arch/score/include/uapi/asm/statfs.h b/arch/score/include/uapi/asm/statfs.h index 36e41004e996..bb92b3e5525d 100644 --- a/arch/score/include/uapi/asm/statfs.h +++ b/arch/score/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_STATFS_H #define _ASM_SCORE_STATFS_H diff --git a/arch/score/include/uapi/asm/swab.h b/arch/score/include/uapi/asm/swab.h index fadc3cc6d8a2..52b0927282b1 100644 --- a/arch/score/include/uapi/asm/swab.h +++ b/arch/score/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_SWAB_H #define _ASM_SCORE_SWAB_H diff --git a/arch/score/include/uapi/asm/termbits.h b/arch/score/include/uapi/asm/termbits.h index 9a95c1412437..4a6f5511cd56 100644 --- a/arch/score/include/uapi/asm/termbits.h +++ b/arch/score/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_TERMBITS_H #define _ASM_SCORE_TERMBITS_H diff --git a/arch/score/include/uapi/asm/termios.h b/arch/score/include/uapi/asm/termios.h index 40984e811ad6..fabb598ecfa3 100644 --- a/arch/score/include/uapi/asm/termios.h +++ b/arch/score/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_TERMIOS_H #define _ASM_SCORE_TERMIOS_H diff --git a/arch/score/include/uapi/asm/types.h b/arch/score/include/uapi/asm/types.h index 2140032778ee..8515287f412a 100644 --- a/arch/score/include/uapi/asm/types.h +++ b/arch/score/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_TYPES_H #define _ASM_SCORE_TYPES_H diff --git a/arch/score/include/uapi/asm/unistd.h b/arch/score/include/uapi/asm/unistd.h index d4008c339e89..04da47bd3d46 100644 --- a/arch/score/include/uapi/asm/unistd.h +++ b/arch/score/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #define __ARCH_HAVE_MMU #define __ARCH_WANT_RENAMEAT diff --git a/arch/score/kernel/Makefile b/arch/score/kernel/Makefile index fb1802b3f542..42def8cff873 100644 --- a/arch/score/kernel/Makefile +++ b/arch/score/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SCORE kernel. # diff --git a/arch/score/kernel/sys_call_table.c b/arch/score/kernel/sys_call_table.c index 287369b88c43..9e6ae793e690 100644 --- a/arch/score/kernel/sys_call_table.c +++ b/arch/score/kernel/sys_call_table.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 640a85925060..97fe29316476 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config SUPERH def_bool y select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST diff --git a/arch/sh/Kconfig.cpu b/arch/sh/Kconfig.cpu index 05b518e90cf7..4a4edc7e03d4 100644 --- a/arch/sh/Kconfig.cpu +++ b/arch/sh/Kconfig.cpu @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Processor features" choice diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 5f2bb4242c0f..d0767672640d 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 3554fcaa023b..6394b4f0a69b 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Board support" config SOLUTION_ENGINE diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index cea300362035..4002a22a7c40 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Specific board support, not covered by a mach group. # diff --git a/arch/sh/boards/board-edosk7705.c b/arch/sh/boards/board-edosk7705.c index 5e24c17bbdad..67a8803eb3f9 100644 --- a/arch/sh/boards/board-edosk7705.c +++ b/arch/sh/boards/board-edosk7705.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sh/boards/renesas/edosk7705/setup.c * diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c index 37a08d094727..3de7bac01903 100644 --- a/arch/sh/boards/board-polaris.c +++ b/arch/sh/boards/board-polaris.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * June 2006 Steve Glendinning * diff --git a/arch/sh/boards/board-secureedge5410.c b/arch/sh/boards/board-secureedge5410.c index 97ec67ffec2b..603a82325c65 100644 --- a/arch/sh/boards/board-secureedge5410.c +++ b/arch/sh/boards/board-secureedge5410.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2002 David McCullough * Copyright (C) 2003 Paul Mundt diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c index 1980bb7e5780..ef9c87deeb08 100644 --- a/arch/sh/boards/board-sh2007.c +++ b/arch/sh/boards/board-sh2007.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SH-2007 board support. * diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c index 325bed53b87e..83296c0b75c4 100644 --- a/arch/sh/boards/board-shmin.c +++ b/arch/sh/boards/board-shmin.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sh/boards/shmin/setup.c * diff --git a/arch/sh/boards/mach-highlander/Kconfig b/arch/sh/boards/mach-highlander/Kconfig index 42f5589b4bf3..b0abd03cac4e 100644 --- a/arch/sh/boards/mach-highlander/Kconfig +++ b/arch/sh/boards/mach-highlander/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if SH_HIGHLANDER choice diff --git a/arch/sh/boards/mach-highlander/Makefile b/arch/sh/boards/mach-highlander/Makefile index d93aaf880134..880ed68138b0 100644 --- a/arch/sh/boards/mach-highlander/Makefile +++ b/arch/sh/boards/mach-highlander/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Highlander specific parts of the kernel # diff --git a/arch/sh/boards/mach-migor/Kconfig b/arch/sh/boards/mach-migor/Kconfig index a7b3b728ec3c..fb64a10e2170 100644 --- a/arch/sh/boards/mach-migor/Kconfig +++ b/arch/sh/boards/mach-migor/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if SH_MIGOR choice diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 5de60a77eaa1..0bcbe58b11e9 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/sh/boards/mach-r2d/Kconfig b/arch/sh/boards/mach-r2d/Kconfig index 8122a9667fc9..21770e668de2 100644 --- a/arch/sh/boards/mach-r2d/Kconfig +++ b/arch/sh/boards/mach-r2d/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if SH_RTS7751R2D menu "RTS7751R2D Board Revision" diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c index 574f009c3c31..e34f81e9ae81 100644 --- a/arch/sh/boards/mach-r2d/irq.c +++ b/arch/sh/boards/mach-r2d/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/renesas/rts7751r2d/irq.c * diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig index 0b9b2c4952c1..f0299bc4416f 100644 --- a/arch/sh/boards/mach-rsk/Kconfig +++ b/arch/sh/boards/mach-rsk/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if SH_RSK choice diff --git a/arch/sh/boards/mach-sdk7780/Kconfig b/arch/sh/boards/mach-sdk7780/Kconfig index 065f1df09bf1..d4392efd2f74 100644 --- a/arch/sh/boards/mach-sdk7780/Kconfig +++ b/arch/sh/boards/mach-sdk7780/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 if SH_SDK7780 choice diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c index 0db058e709e9..2b15370829ae 100644 --- a/arch/sh/boards/mach-se/7206/irq.c +++ b/arch/sh/boards/mach-se/7206/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/se/7206/irq.c * diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c index 68883ec95682..dc55d3a69665 100644 --- a/arch/sh/boards/mach-se/7206/setup.c +++ b/arch/sh/boards/mach-se/7206/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * * linux/arch/sh/boards/se/7206/setup.c diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c index 8ce4f2a202a8..fe0e550601a2 100644 --- a/arch/sh/boards/mach-se/7343/setup.c +++ b/arch/sh/boards/mach-se/7343/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/boards/mach-se/770x/irq.c b/arch/sh/boards/mach-se/770x/irq.c index 1028c17b81bc..66e2c8aa0b69 100644 --- a/arch/sh/boards/mach-se/770x/irq.c +++ b/arch/sh/boards/mach-se/770x/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/se/770x/irq.c * diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c index 658326f44df8..77c35350ee77 100644 --- a/arch/sh/boards/mach-se/770x/setup.c +++ b/arch/sh/boards/mach-se/770x/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/se/770x/setup.c * diff --git a/arch/sh/boards/mach-se/7751/irq.c b/arch/sh/boards/mach-se/7751/irq.c index 5c9847ea1e7c..dcefe58d8753 100644 --- a/arch/sh/boards/mach-se/7751/irq.c +++ b/arch/sh/boards/mach-se/7751/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/se/7751/irq.c * diff --git a/arch/sh/boards/mach-se/7751/setup.c b/arch/sh/boards/mach-se/7751/setup.c index 820f4e7ba0d2..4c480605557f 100644 --- a/arch/sh/boards/mach-se/7751/setup.c +++ b/arch/sh/boards/mach-se/7751/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/se/7751/setup.c * diff --git a/arch/sh/boards/mach-se/Makefile b/arch/sh/boards/mach-se/Makefile index b537e238c6bc..8f69fc147c73 100644 --- a/arch/sh/boards/mach-se/Makefile +++ b/arch/sh/boards/mach-se/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SH_7619_SOLUTION_ENGINE) += board-se7619.o obj-$(CONFIG_SH_SOLUTION_ENGINE) += 770x/ diff --git a/arch/sh/boards/mach-se/board-se7619.c b/arch/sh/boards/mach-se/board-se7619.c index 958bcd7aacc5..4431da64a56f 100644 --- a/arch/sh/boards/mach-se/board-se7619.c +++ b/arch/sh/boards/mach-se/board-se7619.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sh/boards/se/7619/setup.c * diff --git a/arch/sh/boards/mach-sh03/rtc.c b/arch/sh/boards/mach-sh03/rtc.c index f83ac7995d0f..dc3d50e3b7a2 100644 --- a/arch/sh/boards/mach-sh03/rtc.c +++ b/arch/sh/boards/mach-sh03/rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/sh03/rtc.c -- CTP/PCI-SH03 on-chip RTC support * diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c index f582dab59343..85e7059a77e9 100644 --- a/arch/sh/boards/mach-sh03/setup.c +++ b/arch/sh/boards/mach-sh03/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/boards/sh03/setup.c * diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index c4c47ea9fa94..f5e1bd779789 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/sh/boot/compressed/Makefile # diff --git a/arch/sh/boot/compressed/cache.c b/arch/sh/boot/compressed/cache.c index d0b77b68a4d0..31e04ff4841e 100644 --- a/arch/sh/boot/compressed/cache.c +++ b/arch/sh/boot/compressed/cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int cache_control(unsigned int command) { volatile unsigned int *p = (volatile unsigned int *) 0x80000000; diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S index 3e150326f1fd..7bb168133dbb 100644 --- a/arch/sh/boot/compressed/head_32.S +++ b/arch/sh/boot/compressed/head_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/sh/boot/compressed/head.S * diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index ae1dfdb0013b..f2d9d3079d4e 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sh/boot/compressed/misc.c * diff --git a/arch/sh/boot/dts/j2_mimas_v2.dts b/arch/sh/boot/dts/j2_mimas_v2.dts index 880de75360b3..9f4742fab329 100644 --- a/arch/sh/boot/dts/j2_mimas_v2.dts +++ b/arch/sh/boot/dts/j2_mimas_v2.dts @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /dts-v1/; / { diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile index 43c41191de5d..c7c8be58400c 100644 --- a/arch/sh/boot/romimage/Makefile +++ b/arch/sh/boot/romimage/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/sh/boot/romimage/Makefile # diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S index 4671d1b82150..81a0652a3dff 100644 --- a/arch/sh/boot/romimage/head.S +++ b/arch/sh/boot/romimage/head.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/sh/boot/romimage/head.S * diff --git a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig index a5ab2eccdaa6..6be5ddec14d3 100644 --- a/arch/sh/cchips/Kconfig +++ b/arch/sh/cchips/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Companion Chips" config HD6446X_SERIES diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index 8180092502f7..f3fba967445a 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2000 YAEGASHI Takeshi * Hitachi HD64461 companion chip support diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig index e5335123b5e9..72b72e50a92e 100644 --- a/arch/sh/configs/ap325rxa_defconfig +++ b/arch/sh/configs/ap325rxa_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -28,14 +27,10 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -51,8 +46,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -82,7 +75,6 @@ CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_MMC=y CONFIG_MMC_SPI=y @@ -110,8 +102,6 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/apsh4a3a_defconfig b/arch/sh/configs/apsh4a3a_defconfig index 6cb327977d13..4710df43a5b5 100644 --- a/arch/sh/configs/apsh4a3a_defconfig +++ b/arch/sh/configs/apsh4a3a_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -28,15 +27,11 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -46,8 +41,6 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set @@ -66,7 +59,6 @@ CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y @@ -96,7 +88,6 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_PREEMPT is not set # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_FTRACE is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig index fe45d2c9b151..825c641726c4 100644 --- a/arch/sh/configs/apsh4ad0a_defconfig +++ b/arch/sh/configs/apsh4ad0a_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -53,7 +52,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_NET_KEY=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -70,8 +68,6 @@ CONFIG_NETDEVICES=y CONFIG_MDIO_BITBANG=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set @@ -83,7 +79,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FB_SH7785FB=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -124,6 +119,5 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_VM=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_DWARF_UNWINDER=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig index 67e150631ea5..5a90e24aa8a6 100644 --- a/arch/sh/configs/cayman_defconfig +++ b/arch/sh/configs/cayman_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_POSIX_MQUEUE=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -19,7 +18,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -38,7 +36,6 @@ CONFIG_NET_ETHERNET=y CONFIG_HW_RANDOM=y CONFIG_I2C=m CONFIG_WATCHDOG=y -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y @@ -67,5 +64,4 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_SCHEDSTATS=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index ec243ca29529..3f08dc54480b 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 @@ -32,7 +31,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set @@ -43,8 +41,6 @@ CONFIG_NET_ETHERNET=y CONFIG_NET_PCI=y CONFIG_8139TOO=y # CONFIG_8139TOO_PIO is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_MAPLE=y # CONFIG_MOUSE_PS2 is not set @@ -56,7 +52,6 @@ CONFIG_HW_RANDOM=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_SH_WDT=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_PVR2=y @@ -74,5 +69,4 @@ CONFIG_LOGO=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_HUGETLBFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig index 5fcb17bff24a..0c5dfccbfe37 100644 --- a/arch/sh/configs/ecovec24-romimage_defconfig +++ b/arch/sh/configs/ecovec24-romimage_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -26,19 +25,15 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -51,7 +46,6 @@ CONFIG_I2C=y CONFIG_I2C_SH_MOBILE=y CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y @@ -64,4 +58,3 @@ CONFIG_TMPFS=y # CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 0b364e3b0ff8..3568310c2c2f 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -29,16 +28,12 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_IRDA=y CONFIG_SH_SIR=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -53,8 +48,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -140,8 +133,6 @@ CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig index 41fa3a7eed96..db756e099052 100644 --- a/arch/sh/configs/edosk7705_defconfig +++ b/arch/sh/configs/edosk7705_defconfig @@ -20,7 +20,6 @@ CONFIG_CPU_SUBTYPE_SH7705=y CONFIG_SH_EDOSK7705=y CONFIG_SH_PCLK_FREQ=31250000 # CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -35,5 +34,4 @@ CONFIG_SH_PCLK_FREQ=31250000 # CONFIG_SYSFS is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig index e1077a041ac3..aab4ff1e247c 100644 --- a/arch/sh/configs/edosk7760_defconfig +++ b/arch/sh/configs/edosk7760_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="_edosk7760" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -31,7 +30,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -39,10 +37,7 @@ CONFIG_DEBUG_DRIVER=y CONFIG_DEBUG_DEVRES=y CONFIG_MTD=y CONFIG_MTD_DEBUG=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y @@ -62,12 +57,9 @@ CONFIG_MTD_ABSENT=y CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=26000 -# CONFIG_MISC_DEVICES is not set CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -92,7 +84,6 @@ CONFIG_SND=y # CONFIG_SND_VERBOSE_PROCFS is not set CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_SOC=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y @@ -119,8 +110,6 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig index 67cb1094a033..2985fe7c6d50 100644 --- a/arch/sh/configs/espt_defconfig +++ b/arch/sh/configs/espt_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -26,13 +25,10 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_JEDECPROBE=y @@ -43,14 +39,11 @@ CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -65,7 +58,6 @@ CONFIG_FB_FOREIGN_ENDIAN=y CONFIG_FB_SH7760=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y @@ -73,7 +65,6 @@ CONFIG_USB_STORAGE=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y @@ -123,6 +114,5 @@ CONFIG_NLS_UTF8=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig index 496edcdf95a3..4dcf7f552582 100644 --- a/arch/sh/configs/hp6xx_defconfig +++ b/arch/sh/configs/hp6xx_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -37,7 +36,6 @@ CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_LEGACY_PTY_COUNT=64 # CONFIG_HWMON is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_HIT=y @@ -46,7 +44,6 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FONTS=y CONFIG_FONT_PEARL_8x8=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_SH=y @@ -55,7 +52,6 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_PROC_KCORE=y CONFIG_NLS_CODEPAGE_850=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_ECB=y diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig index 029a506ca325..9cc37f29e3b4 100644 --- a/arch/sh/configs/kfr2r09-romimage_defconfig +++ b/arch/sh/configs/kfr2r09-romimage_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -26,12 +25,10 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -44,7 +41,6 @@ CONFIG_I2C=y CONFIG_I2C_SH_MOBILE=y CONFIG_GPIO_SYSFS=y # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y CONFIG_USB_CDC_COMPOSITE=y # CONFIG_DNOTIFY is not set @@ -55,5 +51,4 @@ CONFIG_TMPFS=y # CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig index fac13ded07b2..46693d033644 100644 --- a/arch/sh/configs/kfr2r09_defconfig +++ b/arch/sh/configs/kfr2r09_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -33,15 +32,12 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y @@ -49,7 +45,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_MTD_ONENAND=y CONFIG_MTD_ONENAND_GENERIC=y CONFIG_MTD_UBI=y -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -77,7 +72,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set # CONFIG_LOGO_SUPERH_MONO is not set # CONFIG_LOGO_SUPERH_CLUT224 is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y @@ -91,4 +85,3 @@ CONFIG_TMPFS=y # CONFIG_NETWORK_FILESYSTEMS is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index 6783f31315c7..467f4d2d8e87 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_SYSCTL_SYSCALL is not set @@ -24,10 +23,8 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y -CONFIG_IP_NF_QUEUE=m CONFIG_ATALK=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y @@ -118,7 +115,6 @@ CONFIG_NFSD_V3=y CONFIG_SMB_FS=m CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_932=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig index e3c0894b1bb4..9e3edfdf9b2e 100644 --- a/arch/sh/configs/lboxre2_defconfig +++ b/arch/sh/configs/lboxre2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_SYSCTL_SYSCALL is not set @@ -28,7 +27,6 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -61,7 +59,6 @@ CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_ROMFS_FS=y CONFIG_NLS_CODEPAGE_437=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig index 9479872b1ae6..fb7415dbc102 100644 --- a/arch/sh/configs/magicpanelr2_defconfig +++ b/arch/sh/configs/magicpanelr2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -35,16 +34,13 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -55,8 +51,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_EVDEV=y # CONFIG_MOUSE_PS2 is not set CONFIG_SERIAL_8250=y @@ -68,7 +62,6 @@ CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set @@ -96,7 +89,5 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_KOBJECT=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig index f1d2e1b5ee41..c3f7d5899922 100644 --- a/arch/sh/configs/microdev_defconfig +++ b/arch/sh/configs/microdev_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y @@ -19,7 +18,6 @@ CONFIG_SUPERHYWAY=y CONFIG_NET=y CONFIG_INET=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -45,6 +43,5 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_ECB=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index cc61eda44922..e04f21be0756 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -26,15 +25,11 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -47,8 +42,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -101,7 +94,6 @@ CONFIG_TMPFS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig index f3d5d9f76310..0a432b5f50e7 100644 --- a/arch/sh/configs/polaris_defconfig +++ b/arch/sh/configs/polaris_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -37,14 +36,11 @@ CONFIG_IP_MULTICAST=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FIRMWARE_IN_KERNEL is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -57,8 +53,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -71,7 +65,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_SH=y @@ -91,5 +84,3 @@ CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_SG=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index 920b8471ceb7..435bcd66c667 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -35,13 +34,11 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_BRIDGE=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_COMPLEX_MAPPINGS=y @@ -110,7 +107,6 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_HMAC=y diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig index c77da6be06b8..5877e6d1f285 100644 --- a/arch/sh/configs/r7785rp_defconfig +++ b/arch/sh/configs/r7785rp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -42,7 +41,6 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_BRIDGE=m CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -104,7 +102,6 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_LOCK_ALLOC=y CONFIG_DEBUG_LOCKING_API_SELFTESTS=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_4KSTACKS=y diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig index 5df916d931c5..b195bc01e406 100644 --- a/arch/sh/configs/rsk7201_defconfig +++ b/arch/sh/configs/rsk7201_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -37,10 +36,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,8 +54,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set CONFIG_THERMAL=y -CONFIG_VIDEO_OUTPUT_CONTROL=y -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_SH=y @@ -71,5 +65,3 @@ CONFIG_ROMFS_FS=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig index 3c4f6f4d52b0..8c471959bbc7 100644 --- a/arch/sh/configs/rsk7203_defconfig +++ b/arch/sh/configs/rsk7203_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -44,7 +43,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -52,10 +50,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -64,8 +59,6 @@ CONFIG_NETDEVICES=y CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set @@ -81,7 +74,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_THERMAL=y CONFIG_REGULATOR=y -CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y @@ -130,6 +122,4 @@ CONFIG_DEBUG_VM=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_SG=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_DEBUG_STACK_USAGE=y diff --git a/arch/sh/configs/rsk7264_defconfig b/arch/sh/configs/rsk7264_defconfig index eecdf65bb789..2b9b731fc86b 100644 --- a/arch/sh/configs/rsk7264_defconfig +++ b/arch/sh/configs/rsk7264_defconfig @@ -35,7 +35,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -61,11 +60,9 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DEBUG=y -CONFIG_USB_LIBUSUAL=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set diff --git a/arch/sh/configs/rsk7269_defconfig b/arch/sh/configs/rsk7269_defconfig index 8370b10df357..d041f7bcb84c 100644 --- a/arch/sh/configs/rsk7269_defconfig +++ b/arch/sh/configs/rsk7269_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -44,11 +43,9 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DEBUG=y -CONFIG_USB_LIBUSUAL=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set @@ -60,5 +57,4 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_FTRACE is not set diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index a3d081095ce2..379d673f5ce8 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -22,7 +21,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m @@ -48,7 +46,6 @@ CONFIG_HW_RANDOM=y CONFIG_SPI=y CONFIG_SPI_SH_SCI=y CONFIG_MFD_SM501=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=m CONFIG_FB_SM501=y @@ -83,7 +80,6 @@ CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_R9701=y CONFIG_EXT2_FS=y @@ -94,6 +90,5 @@ CONFIG_TMPFS=y CONFIG_MINIX_FS=y CONFIG_NLS_CODEPAGE_932=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index b1a04f3c598b..11177bceda83 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set @@ -22,15 +21,11 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_FW_LOADER=m CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_PHYSMAP=y @@ -56,7 +51,6 @@ CONFIG_HW_RANDOM=y CONFIG_SPI=y CONFIG_SPI_SH_SCI=y CONFIG_MFD_SM501=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=m CONFIG_FB_SM501=y @@ -91,7 +85,6 @@ CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_R9701=y CONFIG_EXT2_FS=y @@ -102,6 +95,5 @@ CONFIG_TMPFS=y CONFIG_MINIX_FS=y CONFIG_NLS_CODEPAGE_932=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig index bbd4c2298708..95e5208b8260 100644 --- a/arch/sh/configs/sdk7780_defconfig +++ b/arch/sh/configs/sdk7780_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_LOCALVERSION="_SDK7780" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -39,7 +38,6 @@ CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_BEET is not set CONFIG_NET_SCHED=y @@ -47,7 +45,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_PARPORT=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_PLATFORM=y @@ -63,8 +60,6 @@ CONFIG_BLK_DEV_DM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_NETCONSOLE=y CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_EVDEV=y @@ -78,7 +73,6 @@ CONFIG_SSB=y CONFIG_SSB_DRIVER_PCICORE=y CONFIG_FB=y CONFIG_FB_SH_MOBILE_LCDC=m -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y @@ -101,7 +95,6 @@ CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_TT_NEWSCHED is not set @@ -144,8 +137,6 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set CONFIG_TIMER_STATS=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_SH_STANDARD_BIOS=y CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_DES=y diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 36642ec2cb97..e9ee0c878ead 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_KERNEL_LZO=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -90,13 +89,11 @@ CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_FTL=y @@ -119,7 +116,6 @@ CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_PLATFORM=y @@ -140,8 +136,6 @@ CONFIG_MDIO_BITBANG=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_SERIAL_SH_SCI=y @@ -157,7 +151,6 @@ CONFIG_SPI=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_SH_WDT=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y @@ -223,9 +216,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_TIMER_STATS=y CONFIG_DEBUG_MEMORY_INIT=y -# CONFIG_RCU_CPU_STALL_VERBOSE is not set CONFIG_LATENCYTOP=y -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_FUNCTION_TRACER=y # CONFIG_FUNCTION_GRAPH_TRACER is not set CONFIG_DMA_API_DEBUG=y diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 91853a67ec34..3553acd5edb1 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -57,7 +56,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -65,9 +63,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -78,8 +73,6 @@ CONFIG_EEPROM_93CX6=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -109,7 +102,6 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_VM=y CONFIG_DEBUG_LIST=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_DEBUG_STACK_USAGE=y CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_LZO=y diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig index 201acb4652f7..fc77a67b16e7 100644 --- a/arch/sh/configs/se7343_defconfig +++ b/arch/sh/configs/se7343_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -27,26 +26,19 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_RAM=y CONFIG_MTD_PHYSMAP=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_NETDEVICES=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_USB_USBNET=y # CONFIG_USB_NET_AX8817X is not set CONFIG_USB_NET_DM9601=y @@ -104,5 +96,4 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFSD=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig index 9a9ad9adf959..f54722dbc8f5 100644 --- a/arch/sh/configs/se7619_defconfig +++ b/arch/sh/configs/se7619_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_UID16 is not set @@ -24,10 +23,7 @@ CONFIG_BINFMT_ZFLAT=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -48,4 +44,3 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_SYSFS is not set CONFIG_ROMFS_FS=y # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig index 044e0844fda1..ddfc69841955 100644 --- a/arch/sh/configs/se7705_defconfig +++ b/arch/sh/configs/se7705_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y @@ -27,11 +26,8 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,5 +54,4 @@ CONFIG_PROC_KCORE=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y CONFIG_ROOT_NFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig index 1248635e4f88..5a1097641247 100644 --- a/arch/sh/configs/se7712_defconfig +++ b/arch/sh/configs/se7712_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -47,7 +46,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_NET_SCHED=y @@ -68,9 +66,6 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_IND=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -104,8 +99,6 @@ CONFIG_ROOT_NFS=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig index c3ba6e8a9818..9c0ef13bee10 100644 --- a/arch/sh/configs/se7721_defconfig +++ b/arch/sh/configs/se7721_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -46,7 +45,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_NET_SCHED=y @@ -67,9 +65,6 @@ CONFIG_NET_CLS_FW=y CONFIG_NET_CLS_IND=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -132,6 +127,5 @@ CONFIG_NLS_ISO8859_1=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_CCITT=y diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig index ae998c7e2ee0..ccc7fc423fde 100644 --- a/arch/sh/configs/se7722_defconfig +++ b/arch/sh/configs/se7722_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -26,7 +25,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set @@ -57,6 +55,5 @@ CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index 1faa788aecae..aedb3a2d9a10 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -30,14 +29,10 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -53,8 +48,6 @@ CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -137,8 +130,6 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO=y CONFIG_CRYPTO_CBC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig index 912c98590e22..b23f67542728 100644 --- a/arch/sh/configs/se7750_defconfig +++ b/arch/sh/configs/se7750_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y @@ -25,11 +24,8 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,5 +54,4 @@ CONFIG_ROOT_NFS=y CONFIG_PARTITION_ADVANCED=y # CONFIG_MSDOS_PARTITION is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig index 75c92fc1876b..162343683937 100644 --- a/arch/sh/configs/se7751_defconfig +++ b/arch/sh/configs/se7751_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_LOG_BUF_SHIFT=14 @@ -25,13 +24,9 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y -CONFIG_NETFILTER_DEBUG=y -CONFIG_IP_NF_QUEUE=y CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -49,5 +44,4 @@ CONFIG_EXT2_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index b0ef63ce525a..ec32c82646ed 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig @@ -24,7 +24,6 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set # CONFIG_INET6_XFRM_MODE_TUNNEL is not set @@ -32,8 +31,6 @@ CONFIG_IPV6=y # CONFIG_IPV6_SIT is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -54,8 +51,6 @@ CONFIG_SMSC_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y CONFIG_NET_PCI=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_INPUT_KEYBOARD is not set @@ -94,7 +89,6 @@ CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y @@ -110,5 +104,4 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/secureedge5410_defconfig b/arch/sh/configs/secureedge5410_defconfig index 7eae4e59d7f0..360592d63a2f 100644 --- a/arch/sh/configs/secureedge5410_defconfig +++ b/arch/sh/configs/secureedge5410_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y @@ -18,12 +17,9 @@ CONFIG_INET=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK_RO=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y @@ -34,14 +30,11 @@ CONFIG_MTD_CFI_GEOMETRY=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_PLATRAM=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_NET_PCI=y CONFIG_8139CP=y CONFIG_8139TOO=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -51,7 +44,6 @@ CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set -# CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1302=y @@ -60,4 +52,3 @@ CONFIG_EXT2_FS=y CONFIG_TMPFS=y CONFIG_CRAMFS=y CONFIG_ROMFS_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index 0cf4097b71e8..2156223405a1 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -34,7 +33,6 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_RARP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set @@ -70,7 +68,6 @@ CONFIG_EXT2_FS_XATTR=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_ISO9660_FS=m CONFIG_JOLIET=y @@ -126,7 +123,6 @@ CONFIG_NLS_KOI8_R=m CONFIG_NLS_KOI8_U=m CONFIG_NLS_UTF8=m CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_HMAC=y diff --git a/arch/sh/configs/sh2007_defconfig b/arch/sh/configs/sh2007_defconfig index df25ae774ee0..34094e05e892 100644 --- a/arch/sh/configs/sh2007_defconfig +++ b/arch/sh/configs/sh2007_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -42,7 +41,6 @@ CONFIG_NET_IPIP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_NETWORK_SECMARK=y CONFIG_NET_PKTGEN=y @@ -50,7 +48,6 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_CDROM_PKTCDVD=y -# CONFIG_MISC_DEVICES is not set CONFIG_RAID_ATTRS=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y @@ -72,8 +69,6 @@ CONFIG_TUN=y CONFIG_VETH=y CONFIG_NET_ETHERNET=y CONFIG_SMSC911X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_MOUSEDEV is not set @@ -95,9 +90,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_MON=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y @@ -172,7 +165,6 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_SCHED_DEBUG is not set CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_AUTHENC=y diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig index f92ad17cd629..65a1aad899c8 100644 --- a/arch/sh/configs/sh7710voipgw_defconfig +++ b/arch/sh/configs/sh7710voipgw_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -24,7 +23,6 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_SYN_COOKIES=y -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_NETFILTER=y @@ -36,8 +34,6 @@ CONFIG_NET_CLS_ROUTE4=y CONFIG_NET_CLS_U32=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -59,5 +55,4 @@ CONFIG_THERMAL=y # CONFIG_DNOTIFY is not set CONFIG_JFFS2_FS=y CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig index f83ac7b0b031..d15e53647983 100644 --- a/arch/sh/configs/sh7724_generic_defconfig +++ b/arch/sh/configs/sh7724_generic_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_CGROUPS=y @@ -18,7 +17,6 @@ CONFIG_HIBERNATION=y CONFIG_CPU_IDLE=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -44,5 +42,4 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_MISC_FILESYSTEMS is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig index cfde98ddb29d..b0c4bc830fb8 100644 --- a/arch/sh/configs/sh7757lcr_defconfig +++ b/arch/sh/configs/sh7757lcr_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -32,13 +31,11 @@ CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set CONFIG_IPV6=y # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_M25P80=y CONFIG_BLK_DEV_RAM=y @@ -48,7 +45,6 @@ CONFIG_NETDEVICES=y CONFIG_VITESSE_PHY=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_MOUSE_PS2 is not set diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig index 479536440264..2ef780fb9813 100644 --- a/arch/sh/configs/sh7763rdp_defconfig +++ b/arch/sh/configs/sh7763rdp_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -26,11 +25,9 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLKDEVS=y CONFIG_MTD_CFI=y @@ -43,14 +40,11 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SH_ETH=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -65,7 +59,6 @@ CONFIG_FB_FOREIGN_ENDIAN=y CONFIG_FB_SH7760=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_OHCI_HCD=y @@ -74,7 +67,6 @@ CONFIG_MMC=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y @@ -124,6 +116,5 @@ CONFIG_NLS_UTF8=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_DEBUG_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC_T10DIF=y diff --git a/arch/sh/configs/sh7770_generic_defconfig b/arch/sh/configs/sh7770_generic_defconfig index 025bd3ac5ab0..742634b37c0a 100644 --- a/arch/sh/configs/sh7770_generic_defconfig +++ b/arch/sh/configs/sh7770_generic_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_CGROUPS=y @@ -20,7 +19,6 @@ CONFIG_HIBERNATION=y CONFIG_CPU_IDLE=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -46,5 +44,4 @@ CONFIG_UIO_PDRV_GENIRQ=y # CONFIG_MISC_FILESYSTEMS is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_CRC32 is not set diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig index 2fce54d9c388..2ddf5ca7094e 100644 --- a/arch/sh/configs/sh7785lcr_32bit_defconfig +++ b/arch/sh/configs/sh7785lcr_32bit_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -44,13 +43,9 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -58,7 +53,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set @@ -69,7 +63,6 @@ CONFIG_NET_ETHERNET=y CONFIG_NET_VENDOR_3COM=y CONFIG_VORTEX=y CONFIG_R8169=y -# CONFIG_NETDEV_10000 is not set # CONFIG_WLAN is not set CONFIG_INPUT_FF_MEMLESS=m CONFIG_INPUT_EVDEV=y @@ -113,7 +106,6 @@ CONFIG_SND_CMIPCI=y CONFIG_SND_EMU10K1=y # CONFIG_SND_SUPERH is not set CONFIG_USB=y -# CONFIG_USB_DEVICE_CLASS is not set CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y CONFIG_MMC=y @@ -154,9 +146,7 @@ CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_LATENCYTOP=y -CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_FTRACE is not set CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig index d29da4a0f6c2..7098828d392e 100644 --- a/arch/sh/configs/sh7785lcr_defconfig +++ b/arch/sh/configs/sh7785lcr_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -26,27 +25,21 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_ATA=y CONFIG_SATA_SIL=y CONFIG_NETDEVICES=y CONFIG_R8169=y -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_KEYBOARD_ATKBD is not set @@ -121,8 +114,6 @@ CONFIG_NLS_ISO8859_1=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig index 4802e14a4649..d589cfdfb7eb 100644 --- a/arch/sh/configs/shmin_defconfig +++ b/arch/sh/configs/shmin_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_SWAP is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_UID16 is not set @@ -28,10 +27,8 @@ CONFIG_NET=y CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_MTD=y -CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y @@ -53,6 +50,5 @@ CONFIG_CRAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_ROOT_NFS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index 4a4269ad5b04..755c4f73c718 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -56,7 +55,6 @@ CONFIG_NET=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set CONFIG_CAN=m CONFIG_CAN_RAW=m CONFIG_CAN_BCM=m @@ -70,8 +68,6 @@ CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_SMC91X=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set # CONFIG_INPUT is not set # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -82,7 +78,6 @@ CONFIG_I2C=m CONFIG_SPI=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y -CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_R8A66597_HCD=m @@ -104,7 +99,6 @@ CONFIG_DEBUG_SHIRQ=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_VM=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SH_STANDARD_BIOS=y CONFIG_DEBUG_STACK_USAGE=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig index a77b778c745b..ceb48e9b70f4 100644 --- a/arch/sh/configs/titan_defconfig +++ b/arch/sh/configs/titan_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y @@ -49,7 +48,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_IPV6=y CONFIG_IPV6_PRIVACY=y @@ -79,7 +77,6 @@ CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_AH=m @@ -88,7 +85,6 @@ CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m @@ -96,7 +92,6 @@ CONFIG_IP_NF_RAW=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IP6_NF_QUEUE=m CONFIG_IP6_NF_IPTABLES=m CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m @@ -106,7 +101,6 @@ CONFIG_IP6_NF_MATCH_HL=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m @@ -154,7 +148,6 @@ CONFIG_FW_LOADER=m CONFIG_CONNECTOR=m CONFIG_MTD=m CONFIG_MTD_DEBUG=y -CONFIG_MTD_CHAR=m CONFIG_MTD_BLOCK=m CONFIG_FTL=m CONFIG_NFTL=m @@ -261,7 +254,6 @@ CONFIG_NLS_UTF8=m CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_MD4=m diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig index 2d288b887fbd..5f2921a85192 100644 --- a/arch/sh/configs/ul2_defconfig +++ b/arch/sh/configs/ul2_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y @@ -29,7 +28,6 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_CFG80211=y CONFIG_MAC80211=y @@ -37,9 +35,6 @@ CONFIG_MAC80211_RC_PID=y # CONFIG_MAC80211_RC_MINSTREL is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y @@ -50,8 +45,6 @@ CONFIG_ATA=y CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set CONFIG_LIBERTAS=m CONFIG_LIBERTAS_SDIO=m CONFIG_LIBERTAS_DEBUG=y @@ -70,7 +63,6 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_HW_RANDOM is not set -# CONFIG_HID_SUPPORT is not set CONFIG_USB=y CONFIG_USB_MON=y CONFIG_USB_R8A66597_HCD=y @@ -92,6 +84,5 @@ CONFIG_NLS_CODEPAGE_932=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index 01c9a91ee896..7d5591b7c088 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig @@ -1,4 +1,3 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y @@ -46,20 +45,15 @@ CONFIG_INET=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set CONFIG_ATA=y @@ -73,7 +67,6 @@ CONFIG_NET_PCI=y CONFIG_8139CP=y CONFIG_SKY2=y CONFIG_SKY2_DEBUG=y -# CONFIG_NETDEV_10000 is not set CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV_PSAUX is not set # CONFIG_KEYBOARD_ATKBD is not set @@ -150,8 +143,6 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -CONFIG_SYSCTL_SYSCALL_CHECK=y # CONFIG_FTRACE is not set # CONFIG_DUMP_CODE is not set CONFIG_CRYPTO_HMAC=y diff --git a/arch/sh/drivers/Kconfig b/arch/sh/drivers/Kconfig index 420c6b2f33a5..80a45ad2852f 100644 --- a/arch/sh/drivers/Kconfig +++ b/arch/sh/drivers/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 source "arch/sh/drivers/dma/Kconfig" source "arch/sh/cchips/Kconfig" diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile index e13f06bebd92..3e93b434e604 100644 --- a/arch/sh/drivers/Makefile +++ b/arch/sh/drivers/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux SuperH-specific device drivers. # diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index 78bc97b1d027..d0de378beefe 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "DMA support" diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 82f0a335fd19..947bfe8bb0a7 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the PCI specific kernel interface routines under Linux. # diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c index dbf138199871..cae707f3472d 100644 --- a/arch/sh/drivers/pci/common.c +++ b/arch/sh/drivers/pci/common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index edc2fb7a5bb2..c797bfbe2e98 100644 --- a/arch/sh/drivers/pci/fixups-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -5,7 +6,7 @@ #include #include "pci-sh5.h" -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int result = -1; diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 1d1c5a227e50..48aaefd8f5d6 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -63,11 +63,10 @@ static void gapspci_fixup_resources(struct pci_dev *dev) res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1; res.flags = IORESOURCE_MEM; pcibios_resource_to_bus(dev->bus, ®ion, &res); - BUG_ON(!dma_declare_coherent_memory(&dev->dev, + BUG_ON(dma_declare_coherent_memory(&dev->dev, res.start, region.start, resource_size(&res), - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)); break; default: @@ -76,7 +75,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { /* * The interrupt routing semantics here are quite trivial. diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 57ed3f09d0c2..2c9b58f848dd 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -15,7 +15,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return evt2irq(0xa20) + slot; } diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index eaddb56c45c6..358ac104f08c 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -20,18 +20,18 @@ #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB -static u8 rts7751r2d_irq_tab[] __initdata = { +static u8 rts7751r2d_irq_tab[] = { IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_PCI_INTC, IRQ_PCI_INTD, }; -static char lboxre2_irq_tab[] __initdata = { +static char lboxre2_irq_tab[] = { IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { if (mach_is_lboxre2()) return lboxre2_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c index c0a015ae6ecf..24e96dfbdb22 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -22,7 +22,7 @@ #define IRQ_INTD evt2irq(0xa80) /* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ -static char sdk7780_irq_tab[4][16] __initdata = { +static char sdk7780_irq_tab[4][16] = { /* INTA */ { IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, @@ -37,7 +37,7 @@ static char sdk7780_irq_tab[4][16] __initdata = { -1, -1, -1 }, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return sdk7780_irq_tab[pin-1][slot]; } diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index 84a88ca92008..608f6521ceff 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -7,7 +8,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin) { switch (slot) { case 0: return evt2irq(0x3a0); diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 16207bef9f52..7ec4a74ab12c 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c @@ -1,10 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include #include #include -int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin) { int irq; diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c index 6e33ba4cd076..a931e5928f58 100644 --- a/arch/sh/drivers/pci/fixups-snapgear.c +++ b/arch/sh/drivers/pci/fixups-snapgear.c @@ -19,7 +19,7 @@ #include #include "pci-sh4.h" -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = -1; diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c index bd1addb1b8be..a9d563e479d5 100644 --- a/arch/sh/drivers/pci/fixups-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c @@ -19,7 +19,7 @@ #include #include "pci-sh4.h" -static char titan_irq_tab[] __initdata = { +static char titan_irq_tab[] = { TITAN_IRQ_WAN, TITAN_IRQ_LAN, TITAN_IRQ_MPCIA, @@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = { TITAN_IRQ_USB, }; -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { int irq = titan_irq_tab[slot]; diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h index 0288efc17ff3..1543c50b6503 100644 --- a/arch/sh/drivers/pci/pci-sh4.h +++ b/arch/sh/drivers/pci/pci-sh4.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PCI_SH4_H #define __PCI_SH4_H diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index c99ee286b69f..5976a2c8a3e3 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -39,8 +39,12 @@ static void pcibios_scanbus(struct pci_channel *hose) LIST_HEAD(resources); struct resource *res; resource_size_t offset; - int i; - struct pci_bus *bus; + int i, ret; + struct pci_host_bridge *bridge; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; for (i = 0; i < hose->nr_resources; i++) { res = hose->resources + i; @@ -52,19 +56,26 @@ static void pcibios_scanbus(struct pci_channel *hose) pci_add_resource_offset(&resources, res, offset); } - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - hose->bus = bus; + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = hose; + bridge->busnr = next_busno; + bridge->ops = hose->pci_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pcibios_map_platform_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + hose->bus = bridge->bus; need_domain_info = need_domain_info || hose->index; hose->need_domain_info = need_domain_info; - if (!bus) { - pci_free_resource_list(&resources); - return; - } - - next_busno = bus->busn_res.end + 1; + next_busno = hose->bus->busn_res.end + 1; /* Don't allow 8-bit bus number overflow inside the hose - reserve some space for bridges. */ if (next_busno > 224) { @@ -72,9 +83,9 @@ static void pcibios_scanbus(struct pci_channel *hose) need_domain_info = 1; } - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - pci_bus_add_devices(bus); + pci_bus_size_bridges(hose->bus); + pci_bus_assign_resources(hose->bus); + pci_bus_add_devices(hose->bus); } /* @@ -144,8 +155,6 @@ static int __init pcibios_init(void) for (hose = hose_head; hose; hose = hose->next) pcibios_scanbus(hose); - pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); - dma_debug_add_bus(&pci_bus_type); pci_initialized = 1; @@ -154,14 +163,6 @@ static int __init pcibios_init(void) } subsys_initcall(pcibios_init); -/* - * Called after each bus is probed, but before its children - * are examined. - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index a162a7f86b2e..0167a7352719 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -467,7 +467,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port) return 0; } -int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { return evt2irq(0xae0); } diff --git a/arch/sh/include/asm/adc.h b/arch/sh/include/asm/adc.h index 48824c1fab80..99ec66849559 100644 --- a/arch/sh/include/asm/adc.h +++ b/arch/sh/include/asm/adc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_ADC_H #define __ASM_ADC_H #ifdef __KERNEL__ diff --git a/arch/sh/include/asm/alignment.h b/arch/sh/include/asm/alignment.h index b12efecf5294..4f3e715b8c26 100644 --- a/arch/sh/include/asm/alignment.h +++ b/arch/sh/include/asm/alignment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_ALIGNMENT_H #define __ASM_SH_ALIGNMENT_H diff --git a/arch/sh/include/asm/atomic-grb.h b/arch/sh/include/asm/atomic-grb.h index d755e96c3064..aace62d42288 100644 --- a/arch/sh/include/asm/atomic-grb.h +++ b/arch/sh/include/asm/atomic-grb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_ATOMIC_GRB_H #define __ASM_SH_ATOMIC_GRB_H diff --git a/arch/sh/include/asm/atomic-irq.h b/arch/sh/include/asm/atomic-irq.h index 8e2da5fa0178..ee523bd2120f 100644 --- a/arch/sh/include/asm/atomic-irq.h +++ b/arch/sh/include/asm/atomic-irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_ATOMIC_IRQ_H #define __ASM_SH_ATOMIC_IRQ_H diff --git a/arch/sh/include/asm/atomic-llsc.h b/arch/sh/include/asm/atomic-llsc.h index 1d159ce50f5a..1d06e4d288dc 100644 --- a/arch/sh/include/asm/atomic-llsc.h +++ b/arch/sh/include/asm/atomic-llsc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_ATOMIC_LLSC_H #define __ASM_SH_ATOMIC_LLSC_H diff --git a/arch/sh/include/asm/atomic.h b/arch/sh/include/asm/atomic.h index 8a7bd80c8b33..0fd0099f43cc 100644 --- a/arch/sh/include/asm/atomic.h +++ b/arch/sh/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_ATOMIC_H #define __ASM_SH_ATOMIC_H diff --git a/arch/sh/include/asm/barrier.h b/arch/sh/include/asm/barrier.h index 3c30b6e166b6..66faae19d254 100644 --- a/arch/sh/include/asm/barrier.h +++ b/arch/sh/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * Copyright (C) 2002 Paul Mundt diff --git a/arch/sh/include/asm/bitops-cas.h b/arch/sh/include/asm/bitops-cas.h index 88f793c04d3c..ba517b3f24da 100644 --- a/arch/sh/include/asm/bitops-cas.h +++ b/arch/sh/include/asm/bitops-cas.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BITOPS_CAS_H #define __ASM_SH_BITOPS_CAS_H diff --git a/arch/sh/include/asm/bitops-grb.h b/arch/sh/include/asm/bitops-grb.h index e73af33acbf4..75b5980399d4 100644 --- a/arch/sh/include/asm/bitops-grb.h +++ b/arch/sh/include/asm/bitops-grb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BITOPS_GRB_H #define __ASM_SH_BITOPS_GRB_H diff --git a/arch/sh/include/asm/bitops-llsc.h b/arch/sh/include/asm/bitops-llsc.h index d8328be06191..47036845fc68 100644 --- a/arch/sh/include/asm/bitops-llsc.h +++ b/arch/sh/include/asm/bitops-llsc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BITOPS_LLSC_H #define __ASM_SH_BITOPS_LLSC_H diff --git a/arch/sh/include/asm/bitops-op32.h b/arch/sh/include/asm/bitops-op32.h index f0ae7e9218e0..466880362ad1 100644 --- a/arch/sh/include/asm/bitops-op32.h +++ b/arch/sh/include/asm/bitops-op32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BITOPS_OP32_H #define __ASM_SH_BITOPS_OP32_H diff --git a/arch/sh/include/asm/bitops.h b/arch/sh/include/asm/bitops.h index a8699d60a8c4..8c3578288db5 100644 --- a/arch/sh/include/asm/bitops.h +++ b/arch/sh/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BITOPS_H #define __ASM_SH_BITOPS_H diff --git a/arch/sh/include/asm/bl_bit.h b/arch/sh/include/asm/bl_bit.h index 06e4163c6746..7e3d81691ad5 100644 --- a/arch/sh/include/asm/bl_bit.h +++ b/arch/sh/include/asm/bl_bit.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BL_BIT_H #define __ASM_SH_BL_BIT_H diff --git a/arch/sh/include/asm/bl_bit_32.h b/arch/sh/include/asm/bl_bit_32.h index fd21eee62149..1f7d225fc604 100644 --- a/arch/sh/include/asm/bl_bit_32.h +++ b/arch/sh/include/asm/bl_bit_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BL_BIT_32_H #define __ASM_SH_BL_BIT_32_H diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h index 5b5086367639..05a485c4fabc 100644 --- a/arch/sh/include/asm/bug.h +++ b/arch/sh/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BUG_H #define __ASM_SH_BUG_H diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h index 02a19a1c033a..030df56bfdb2 100644 --- a/arch/sh/include/asm/bugs.h +++ b/arch/sh/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BUGS_H #define __ASM_SH_BUGS_H diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h index ef9e555aafba..2408ac4873aa 100644 --- a/arch/sh/include/asm/cache.h +++ b/arch/sh/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: cache.h,v 1.6 2004/03/11 18:08:05 lethal Exp $ * * include/asm-sh/cache.h diff --git a/arch/sh/include/asm/cache_insns.h b/arch/sh/include/asm/cache_insns.h index 355cb06b7a30..c5a4acdc53f9 100644 --- a/arch/sh/include/asm/cache_insns.h +++ b/arch/sh/include/asm/cache_insns.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CACHE_INSNS_H #define __ASM_SH_CACHE_INSNS_H diff --git a/arch/sh/include/asm/cache_insns_32.h b/arch/sh/include/asm/cache_insns_32.h index b92fe5416092..470880b972cb 100644 --- a/arch/sh/include/asm/cache_insns_32.h +++ b/arch/sh/include/asm/cache_insns_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CACHE_INSNS_32_H #define __ASM_SH_CACHE_INSNS_32_H diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h index 82e1eabeac98..d103ab5a4e4b 100644 --- a/arch/sh/include/asm/cacheflush.h +++ b/arch/sh/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CACHEFLUSH_H #define __ASM_SH_CACHEFLUSH_H diff --git a/arch/sh/include/asm/checksum.h b/arch/sh/include/asm/checksum.h index 34ae26204524..a460a108969d 100644 --- a/arch/sh/include/asm/checksum.h +++ b/arch/sh/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_SUPERH32 # include #else diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 0390a07e7e3b..b65bc2908e8a 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CLOCK_H #define __ASM_SH_CLOCK_H diff --git a/arch/sh/include/asm/cmpxchg-cas.h b/arch/sh/include/asm/cmpxchg-cas.h index d0d86649e8c1..f508db6eaf31 100644 --- a/arch/sh/include/asm/cmpxchg-cas.h +++ b/arch/sh/include/asm/cmpxchg-cas.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CMPXCHG_CAS_H #define __ASM_SH_CMPXCHG_CAS_H diff --git a/arch/sh/include/asm/cmpxchg-grb.h b/arch/sh/include/asm/cmpxchg-grb.h index 2ed557b31bd9..e12279ea35cf 100644 --- a/arch/sh/include/asm/cmpxchg-grb.h +++ b/arch/sh/include/asm/cmpxchg-grb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CMPXCHG_GRB_H #define __ASM_SH_CMPXCHG_GRB_H diff --git a/arch/sh/include/asm/cmpxchg-irq.h b/arch/sh/include/asm/cmpxchg-irq.h index f88877257171..07d3e7f08389 100644 --- a/arch/sh/include/asm/cmpxchg-irq.h +++ b/arch/sh/include/asm/cmpxchg-irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CMPXCHG_IRQ_H #define __ASM_SH_CMPXCHG_IRQ_H diff --git a/arch/sh/include/asm/cmpxchg-llsc.h b/arch/sh/include/asm/cmpxchg-llsc.h index fcfd32271bff..d5270cd297c1 100644 --- a/arch/sh/include/asm/cmpxchg-llsc.h +++ b/arch/sh/include/asm/cmpxchg-llsc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CMPXCHG_LLSC_H #define __ASM_SH_CMPXCHG_LLSC_H diff --git a/arch/sh/include/asm/cmpxchg.h b/arch/sh/include/asm/cmpxchg.h index 3dfe0467a773..e9501d85c278 100644 --- a/arch/sh/include/asm/cmpxchg.h +++ b/arch/sh/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CMPXCHG_H #define __ASM_SH_CMPXCHG_H diff --git a/arch/sh/include/asm/dma-mapping.h b/arch/sh/include/asm/dma-mapping.h index 9b06be07db4d..68c1536b3aab 100644 --- a/arch/sh/include/asm/dma-mapping.h +++ b/arch/sh/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_DMA_MAPPING_H #define __ASM_SH_DMA_MAPPING_H diff --git a/arch/sh/include/asm/dmabrg.h b/arch/sh/include/asm/dmabrg.h index c5edba216cf1..69e119cfd711 100644 --- a/arch/sh/include/asm/dmabrg.h +++ b/arch/sh/include/asm/dmabrg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * SH7760 DMABRG (USB/Audio) support */ diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h index bf9f44f17c29..5ec8db1ddc20 100644 --- a/arch/sh/include/asm/elf.h +++ b/arch/sh/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_ELF_H #define __ASM_SH_ELF_H diff --git a/arch/sh/include/asm/entry-macros.S b/arch/sh/include/asm/entry-macros.S index cc43a55e1fcf..5ce142d8c5a8 100644 --- a/arch/sh/include/asm/entry-macros.S +++ b/arch/sh/include/asm/entry-macros.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! entry.S macro define .macro cli diff --git a/arch/sh/include/asm/extable.h b/arch/sh/include/asm/extable.h index df2ee2fcb8d3..ed46f8bebb9f 100644 --- a/arch/sh/include/asm/extable.h +++ b/arch/sh/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_EXTABLE_H #define __ASM_SH_EXTABLE_H diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h index 50921c7cc3f0..43cfaf929aa7 100644 --- a/arch/sh/include/asm/fpu.h +++ b/arch/sh/include/asm/fpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_FPU_H #define __ASM_SH_FPU_H diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h index 1f157b86eaa7..b1c1dc0cc261 100644 --- a/arch/sh/include/asm/ftrace.h +++ b/arch/sh/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_FTRACE_H #define __ASM_SH_FTRACE_H diff --git a/arch/sh/include/asm/futex-cas.h b/arch/sh/include/asm/futex-cas.h index 267cb7a5f101..ed738e32b5ec 100644 --- a/arch/sh/include/asm/futex-cas.h +++ b/arch/sh/include/asm/futex-cas.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_FUTEX_CAS_H #define __ASM_SH_FUTEX_CAS_H diff --git a/arch/sh/include/asm/futex-irq.h b/arch/sh/include/asm/futex-irq.h index ab01dbee0a82..9bc053242ea0 100644 --- a/arch/sh/include/asm/futex-irq.h +++ b/arch/sh/include/asm/futex-irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_FUTEX_IRQ_H #define __ASM_SH_FUTEX_IRQ_H diff --git a/arch/sh/include/asm/futex-llsc.h b/arch/sh/include/asm/futex-llsc.h index 23591703bec0..6e1570752bc1 100644 --- a/arch/sh/include/asm/futex-llsc.h +++ b/arch/sh/include/asm/futex-llsc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_FUTEX_LLSC_H #define __ASM_SH_FUTEX_LLSC_H diff --git a/arch/sh/include/asm/futex.h b/arch/sh/include/asm/futex.h index d0078747d308..15bf07bfa96b 100644 --- a/arch/sh/include/asm/futex.h +++ b/arch/sh/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_FUTEX_H #define __ASM_SH_FUTEX_H @@ -27,21 +28,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return atomic_futex_op_cmpxchg_inatomic(uval, uaddr, oldval, newval); } -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - u32 oparg = (encoded_op << 8) >> 20; - u32 cmparg = (encoded_op << 20) >> 20; u32 oldval, newval, prev; int ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); do { @@ -80,17 +72,8 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = ((int)oldval < (int)cmparg); break; - case FUTEX_OP_CMP_GE: ret = ((int)oldval >= (int)cmparg); break; - case FUTEX_OP_CMP_LE: ret = ((int)oldval <= (int)cmparg); break; - case FUTEX_OP_CMP_GT: ret = ((int)oldval > (int)cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; return ret; } diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h index 48b191313a99..edaea3559a23 100644 --- a/arch/sh/include/asm/hardirq.h +++ b/arch/sh/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HARDIRQ_H #define __ASM_SH_HARDIRQ_H diff --git a/arch/sh/include/asm/hd64461.h b/arch/sh/include/asm/hd64461.h index 977355f0a483..afb24cb034b1 100644 --- a/arch/sh/include/asm/hd64461.h +++ b/arch/sh/include/asm/hd64461.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HD64461 #define __ASM_SH_HD64461 /* diff --git a/arch/sh/include/asm/heartbeat.h b/arch/sh/include/asm/heartbeat.h index caaafe5a3ef1..4028ca4058d1 100644 --- a/arch/sh/include/asm/heartbeat.h +++ b/arch/sh/include/asm/heartbeat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HEARTBEAT_H #define __ASM_SH_HEARTBEAT_H diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h index ef489a56fcce..735939c0f513 100644 --- a/arch/sh/include/asm/hugetlb.h +++ b/arch/sh/include/asm/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SH_HUGETLB_H #define _ASM_SH_HUGETLB_H diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index ec9ad593c3da..7431c172c0cb 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HW_BREAKPOINT_H #define __ASM_SH_HW_BREAKPOINT_H diff --git a/arch/sh/include/asm/hw_irq.h b/arch/sh/include/asm/hw_irq.h index 693d44184058..ce23e3332f9c 100644 --- a/arch/sh/include/asm/hw_irq.h +++ b/arch/sh/include/asm/hw_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HW_IRQ_H #define __ASM_SH_HW_IRQ_H diff --git a/arch/sh/include/asm/i2c-sh7760.h b/arch/sh/include/asm/i2c-sh7760.h index 69fee1239b03..a777f1410a6e 100644 --- a/arch/sh/include/asm/i2c-sh7760.h +++ b/arch/sh/include/asm/i2c-sh7760.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * MMIO/IRQ and platform data for SH7760 I2C channels */ diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 3280a6bfa503..98cb8c802b1a 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_IO_H #define __ASM_SH_IO_H diff --git a/arch/sh/include/asm/io_generic.h b/arch/sh/include/asm/io_generic.h index b5f6956f19c8..87ec38f4e532 100644 --- a/arch/sh/include/asm/io_generic.h +++ b/arch/sh/include/asm/io_generic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Trivial I/O routine definitions, intentionally meant to be included * multiple times. Ugly I/O routine concatenation helpers taken from diff --git a/arch/sh/include/asm/io_noioport.h b/arch/sh/include/asm/io_noioport.h index c727e6ddf69e..90d6109f1622 100644 --- a/arch/sh/include/asm/io_noioport.h +++ b/arch/sh/include/asm/io_noioport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_IO_NOIOPORT_H #define __ASM_SH_IO_NOIOPORT_H diff --git a/arch/sh/include/asm/io_trapped.h b/arch/sh/include/asm/io_trapped.h index 4ab94ef51071..ac01b201d9aa 100644 --- a/arch/sh/include/asm/io_trapped.h +++ b/arch/sh/include/asm/io_trapped.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_IO_TRAPPED_H #define __ASM_SH_IO_TRAPPED_H diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h index 0e4f532e4737..8065a3222e19 100644 --- a/arch/sh/include/asm/irq.h +++ b/arch/sh/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_IRQ_H #define __ASM_SH_IRQ_H diff --git a/arch/sh/include/asm/irqflags.h b/arch/sh/include/asm/irqflags.h index 43b7608606c3..25f6cfef3f04 100644 --- a/arch/sh/include/asm/irqflags.h +++ b/arch/sh/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_IRQFLAGS_H #define __ASM_SH_IRQFLAGS_H diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h index 8d6a831e7ba1..5212f5fcd752 100644 --- a/arch/sh/include/asm/kdebug.h +++ b/arch/sh/include/asm/kdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_KDEBUG_H #define __ASM_SH_KDEBUG_H diff --git a/arch/sh/include/asm/kexec.h b/arch/sh/include/asm/kexec.h index ad6ef8a275ee..fd5f331a3912 100644 --- a/arch/sh/include/asm/kexec.h +++ b/arch/sh/include/asm/kexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_KEXEC_H #define __ASM_SH_KEXEC_H diff --git a/arch/sh/include/asm/kgdb.h b/arch/sh/include/asm/kgdb.h index 9e7d2d1b03e0..0d5b840cb289 100644 --- a/arch/sh/include/asm/kgdb.h +++ b/arch/sh/include/asm/kgdb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_KGDB_H #define __ASM_SH_KGDB_H diff --git a/arch/sh/include/asm/kmap_types.h b/arch/sh/include/asm/kmap_types.h index 5962b08b6dd8..b78107f923dd 100644 --- a/arch/sh/include/asm/kmap_types.h +++ b/arch/sh/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SH_KMAP_TYPES_H #define __SH_KMAP_TYPES_H diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h index f0986f9b3844..85d8bcaa8493 100644 --- a/arch/sh/include/asm/kprobes.h +++ b/arch/sh/include/asm/kprobes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_KPROBES_H #define __ASM_SH_KPROBES_H diff --git a/arch/sh/include/asm/linkage.h b/arch/sh/include/asm/linkage.h index 3565a4f4009f..7c2fa27a43f8 100644 --- a/arch/sh/include/asm/linkage.h +++ b/arch/sh/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LINKAGE_H #define __ASM_LINKAGE_H diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h index 56e4418c19b9..172e329fd92d 100644 --- a/arch/sh/include/asm/mmu.h +++ b/arch/sh/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MMU_H #define __MMU_H diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h index eb6ac3c10c44..2d09650093c7 100644 --- a/arch/sh/include/asm/mmu_context.h +++ b/arch/sh/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2003 - 2007 Paul Mundt diff --git a/arch/sh/include/asm/mmu_context_32.h b/arch/sh/include/asm/mmu_context_32.h index 10e2e17210d2..71bf12ef1f65 100644 --- a/arch/sh/include/asm/mmu_context_32.h +++ b/arch/sh/include/asm/mmu_context_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_MMU_CONTEXT_32_H #define __ASM_SH_MMU_CONTEXT_32_H diff --git a/arch/sh/include/asm/mmzone.h b/arch/sh/include/asm/mmzone.h index 15a8496960e6..cbaee1d1b673 100644 --- a/arch/sh/include/asm/mmzone.h +++ b/arch/sh/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_MMZONE_H #define __ASM_SH_MMZONE_H diff --git a/arch/sh/include/asm/module.h b/arch/sh/include/asm/module.h index 81300d8b5448..9f38fb35fe96 100644 --- a/arch/sh/include/asm/module.h +++ b/arch/sh/include/asm/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SH_MODULE_H #define _ASM_SH_MODULE_H diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index ceb5201a30ed..5eef8be3e59f 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PAGE_H #define __ASM_SH_PAGE_H diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 17fa69bc814d..53f7ae6abaa7 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PCI_H #define __ASM_SH_PCI_H diff --git a/arch/sh/include/asm/perf_event.h b/arch/sh/include/asm/perf_event.h index 14308bed7ea5..468c7ca8bd2e 100644 --- a/arch/sh/include/asm/perf_event.h +++ b/arch/sh/include/asm/perf_event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PERF_EVENT_H #define __ASM_SH_PERF_EVENT_H diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h index f3f42c84c40f..ed053a359ab7 100644 --- a/arch/sh/include/asm/pgalloc.h +++ b/arch/sh/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PGALLOC_H #define __ASM_SH_PGALLOC_H diff --git a/arch/sh/include/asm/pgtable-2level.h b/arch/sh/include/asm/pgtable-2level.h index f75cf4387257..bf1eb51c3ee5 100644 --- a/arch/sh/include/asm/pgtable-2level.h +++ b/arch/sh/include/asm/pgtable-2level.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PGTABLE_2LEVEL_H #define __ASM_SH_PGTABLE_2LEVEL_H diff --git a/arch/sh/include/asm/pgtable-3level.h b/arch/sh/include/asm/pgtable-3level.h index 9b1e776eca31..7d8587eb65ff 100644 --- a/arch/sh/include/asm/pgtable-3level.h +++ b/arch/sh/include/asm/pgtable-3level.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PGTABLE_3LEVEL_H #define __ASM_SH_PGTABLE_3LEVEL_H diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h index c646e563abce..29274f0e428e 100644 --- a/arch/sh/include/asm/pgtable_32.h +++ b/arch/sh/include/asm/pgtable_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PGTABLE_32_H #define __ASM_SH_PGTABLE_32_H diff --git a/arch/sh/include/asm/posix_types.h b/arch/sh/include/asm/posix_types.h index 1aa781079b1e..0d670fd94fe7 100644 --- a/arch/sh/include/asm/posix_types.h +++ b/arch/sh/include/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ # ifdef CONFIG_SUPERH32 # include # else diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h index 5addd69f70ef..6fbf8c80e498 100644 --- a/arch/sh/include/asm/processor.h +++ b/arch/sh/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PROCESSOR_H #define __ASM_SH_PROCESSOR_H diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index 18e0377f72bb..95100d8a0b7b 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-sh/processor.h * @@ -136,10 +137,6 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned lo /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while(0) -#define release_segments(mm) do { } while(0) - /* * FPU lazy state save handling. */ diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h index eedd4f625d07..777a16318aff 100644 --- a/arch/sh/include/asm/processor_64.h +++ b/arch/sh/include/asm/processor_64.h @@ -170,10 +170,6 @@ struct mm_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Copy and release all segment info associated with a VM */ -#define copy_segments(p, mm) do { } while (0) -#define release_segments(mm) do { } while (0) -#define forget_segments() do { } while (0) /* * FPU lazy state save handling. */ diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 2506c7db76b7..9143c7babcbe 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1999, 2000 Niibe Yutaka */ diff --git a/arch/sh/include/asm/ptrace_32.h b/arch/sh/include/asm/ptrace_32.h index 1dd4480c5363..5f37ad7c6065 100644 --- a/arch/sh/include/asm/ptrace_32.h +++ b/arch/sh/include/asm/ptrace_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PTRACE_32_H #define __ASM_SH_PTRACE_32_H diff --git a/arch/sh/include/asm/ptrace_64.h b/arch/sh/include/asm/ptrace_64.h index 97f4b5660f2c..6ee08229b433 100644 --- a/arch/sh/include/asm/ptrace_64.h +++ b/arch/sh/include/asm/ptrace_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PTRACE_64_H #define __ASM_SH_PTRACE_64_H diff --git a/arch/sh/include/asm/push-switch.h b/arch/sh/include/asm/push-switch.h index 4903f9e52dd8..c5f072572fd1 100644 --- a/arch/sh/include/asm/push-switch.h +++ b/arch/sh/include/asm/push-switch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_PUSH_SWITCH_H #define __ASM_SH_PUSH_SWITCH_H diff --git a/arch/sh/include/asm/reboot.h b/arch/sh/include/asm/reboot.h index b3da0c63fc3d..5c445c90df14 100644 --- a/arch/sh/include/asm/reboot.h +++ b/arch/sh/include/asm/reboot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_REBOOT_H #define __ASM_SH_REBOOT_H diff --git a/arch/sh/include/asm/romimage-macros.h b/arch/sh/include/asm/romimage-macros.h index ae17a150bb58..f9352ee7c21b 100644 --- a/arch/sh/include/asm/romimage-macros.h +++ b/arch/sh/include/asm/romimage-macros.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ROMIMAGE_MACRO_H #define __ROMIMAGE_MACRO_H diff --git a/arch/sh/include/asm/rtc.h b/arch/sh/include/asm/rtc.h index f7b010d48af7..c63555ee1255 100644 --- a/arch/sh/include/asm/rtc.h +++ b/arch/sh/include/asm/rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_RTC_H #define _ASM_RTC_H diff --git a/arch/sh/include/asm/seccomp.h b/arch/sh/include/asm/seccomp.h index 3280ed3802ef..54111e4d32b8 100644 --- a/arch/sh/include/asm/seccomp.h +++ b/arch/sh/include/asm/seccomp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SECCOMP_H #include diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h index 7a99e6af6372..8edb824049b9 100644 --- a/arch/sh/include/asm/sections.h +++ b/arch/sh/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SECTIONS_H #define __ASM_SH_SECTIONS_H diff --git a/arch/sh/include/asm/segment.h b/arch/sh/include/asm/segment.h index ff795d3a6909..101c13c0c6ad 100644 --- a/arch/sh/include/asm/segment.h +++ b/arch/sh/include/asm/segment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SEGMENT_H #define __ASM_SH_SEGMENT_H diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h index 99238108e7a5..fc807011187f 100644 --- a/arch/sh/include/asm/setup.h +++ b/arch/sh/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SH_SETUP_H #define _SH_SETUP_H diff --git a/arch/sh/include/asm/sh7760fb.h b/arch/sh/include/asm/sh7760fb.h index 8767f61aceca..2d9433d75402 100644 --- a/arch/sh/include/asm/sh7760fb.h +++ b/arch/sh/include/asm/sh7760fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * sh7760fb.h -- platform data for SH7760/SH7763 LCDC framebuffer driver. * diff --git a/arch/sh/include/asm/sh_bios.h b/arch/sh/include/asm/sh_bios.h index 95714c28422b..ab693b982442 100644 --- a/arch/sh/include/asm/sh_bios.h +++ b/arch/sh/include/asm/sh_bios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_BIOS_H #define __ASM_SH_BIOS_H diff --git a/arch/sh/include/asm/smc37c93x.h b/arch/sh/include/asm/smc37c93x.h index 585da2a8fc45..f054c30a171a 100644 --- a/arch/sh/include/asm/smc37c93x.h +++ b/arch/sh/include/asm/smc37c93x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SMC37C93X_H #define __ASM_SH_SMC37C93X_H diff --git a/arch/sh/include/asm/smp-ops.h b/arch/sh/include/asm/smp-ops.h index c590f76856f1..e27702130eb6 100644 --- a/arch/sh/include/asm/smp-ops.h +++ b/arch/sh/include/asm/smp-ops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SMP_OPS_H #define __ASM_SH_SMP_OPS_H diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index c9f8bbdb1bf8..1a0d7cf71c10 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SMP_H #define __ASM_SH_SMP_H diff --git a/arch/sh/include/asm/sparsemem.h b/arch/sh/include/asm/sparsemem.h index 547a540b6667..4eb899751e45 100644 --- a/arch/sh/include/asm/sparsemem.h +++ b/arch/sh/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SPARSEMEM_H #define __ASM_SH_SPARSEMEM_H diff --git a/arch/sh/include/asm/spi.h b/arch/sh/include/asm/spi.h index e96f5b0953c8..6780753bd249 100644 --- a/arch/sh/include/asm/spi.h +++ b/arch/sh/include/asm/spi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPI_H__ #define __ASM_SPI_H__ diff --git a/arch/sh/include/asm/spinlock-cas.h b/arch/sh/include/asm/spinlock-cas.h index c46e8cc7b515..5ed7dbbd94ff 100644 --- a/arch/sh/include/asm/spinlock-cas.h +++ b/arch/sh/include/asm/spinlock-cas.h @@ -29,11 +29,6 @@ static inline unsigned __sl_cas(volatile unsigned *p, unsigned old, unsigned new #define arch_spin_is_locked(x) ((x)->lock <= 0) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, VAL > 0); -} - static inline void arch_spin_lock(arch_spinlock_t *lock) { while (!__sl_cas(&lock->lock, 1, 0)); diff --git a/arch/sh/include/asm/spinlock-llsc.h b/arch/sh/include/asm/spinlock-llsc.h index cec78143fa83..f77263aae760 100644 --- a/arch/sh/include/asm/spinlock-llsc.h +++ b/arch/sh/include/asm/spinlock-llsc.h @@ -21,11 +21,6 @@ #define arch_spin_is_locked(x) ((x)->lock <= 0) #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, VAL > 0); -} - /* * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. diff --git a/arch/sh/include/asm/spinlock_types.h b/arch/sh/include/asm/spinlock_types.h index 9b7560db06ca..e82369f286a2 100644 --- a/arch/sh/include/asm/spinlock_types.h +++ b/arch/sh/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SPINLOCK_TYPES_H #define __ASM_SH_SPINLOCK_TYPES_H diff --git a/arch/sh/include/asm/sram.h b/arch/sh/include/asm/sram.h index a2808ce4c0aa..c125cf219868 100644 --- a/arch/sh/include/asm/sram.h +++ b/arch/sh/include/asm/sram.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SRAM_H #define __ASM_SRAM_H diff --git a/arch/sh/include/asm/stackprotector.h b/arch/sh/include/asm/stackprotector.h index 141515a43b78..35616841d0a1 100644 --- a/arch/sh/include/asm/stackprotector.h +++ b/arch/sh/include/asm/stackprotector.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_STACKPROTECTOR_H #define __ASM_SH_STACKPROTECTOR_H diff --git a/arch/sh/include/asm/stacktrace.h b/arch/sh/include/asm/stacktrace.h index a7e2d4dfd087..50c173c0b9f5 100644 --- a/arch/sh/include/asm/stacktrace.h +++ b/arch/sh/include/asm/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2009 Matt Fleming * diff --git a/arch/sh/include/asm/string.h b/arch/sh/include/asm/string.h index 114011fa08af..84fc5ed9c5b3 100644 --- a/arch/sh/include/asm/string.h +++ b/arch/sh/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_SUPERH32 # include #else diff --git a/arch/sh/include/asm/string_64.h b/arch/sh/include/asm/string_64.h index 742007172624..d51d6150a4e2 100644 --- a/arch/sh/include/asm/string_64.h +++ b/arch/sh/include/asm/string_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_STRING_64_H #define __ASM_SH_STRING_64_H diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h index 70ae0b2888ab..47db17520261 100644 --- a/arch/sh/include/asm/suspend.h +++ b/arch/sh/include/asm/suspend.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SH_SUSPEND_H #define _ASM_SH_SUSPEND_H diff --git a/arch/sh/include/asm/switch_to_32.h b/arch/sh/include/asm/switch_to_32.h index 7661b4ba8259..9c93fb91adb4 100644 --- a/arch/sh/include/asm/switch_to_32.h +++ b/arch/sh/include/asm/switch_to_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SWITCH_TO_32_H #define __ASM_SH_SWITCH_TO_32_H diff --git a/arch/sh/include/asm/syscall.h b/arch/sh/include/asm/syscall.h index 847128da6eac..90ba00002626 100644 --- a/arch/sh/include/asm/syscall.h +++ b/arch/sh/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SYSCALL_H #define __ASM_SH_SYSCALL_H diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h index 95be3b0ce0ac..6e118799831c 100644 --- a/arch/sh/include/asm/syscall_32.h +++ b/arch/sh/include/asm/syscall_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SYSCALL_32_H #define __ASM_SH_SYSCALL_32_H diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h index c6a797b90b80..43882580c7f9 100644 --- a/arch/sh/include/asm/syscall_64.h +++ b/arch/sh/include/asm/syscall_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SYSCALL_64_H #define __ASM_SH_SYSCALL_64_H diff --git a/arch/sh/include/asm/syscalls.h b/arch/sh/include/asm/syscalls.h index 3dbfef06f6b2..995ef046232c 100644 --- a/arch/sh/include/asm/syscalls.h +++ b/arch/sh/include/asm/syscalls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SYSCALLS_H #define __ASM_SH_SYSCALLS_H diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h index 4f643aa718e3..9f9faf63b48c 100644 --- a/arch/sh/include/asm/syscalls_32.h +++ b/arch/sh/include/asm/syscalls_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SYSCALLS_32_H #define __ASM_SH_SYSCALLS_32_H diff --git a/arch/sh/include/asm/syscalls_64.h b/arch/sh/include/asm/syscalls_64.h index d62e8eb22f74..df42656cebea 100644 --- a/arch/sh/include/asm/syscalls_64.h +++ b/arch/sh/include/asm/syscalls_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SYSCALLS_64_H #define __ASM_SH_SYSCALLS_64_H diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index 6c65dcd470ab..becb798f1b04 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_THREAD_INFO_H #define __ASM_SH_THREAD_INFO_H diff --git a/arch/sh/include/asm/timex.h b/arch/sh/include/asm/timex.h index 18bf06d9c764..f53f95bf4288 100644 --- a/arch/sh/include/asm/timex.h +++ b/arch/sh/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm-sh/timex.h * diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 51a8bc967e75..77abe192fb43 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_TLB_H #define __ASM_SH_TLB_H diff --git a/arch/sh/include/asm/tlbflush.h b/arch/sh/include/asm/tlbflush.h index 0df66f0c7284..8f180cd3bcd6 100644 --- a/arch/sh/include/asm/tlbflush.h +++ b/arch/sh/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_TLBFLUSH_H #define __ASM_SH_TLBFLUSH_H diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h index 358e3f516ef6..9a32eb4098df 100644 --- a/arch/sh/include/asm/topology.h +++ b/arch/sh/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SH_TOPOLOGY_H #define _ASM_SH_TOPOLOGY_H diff --git a/arch/sh/include/asm/traps.h b/arch/sh/include/asm/traps.h index 9cc149a0dbd1..8844ed0c0fde 100644 --- a/arch/sh/include/asm/traps.h +++ b/arch/sh/include/asm/traps.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_TRAPS_H #define __ASM_SH_TRAPS_H diff --git a/arch/sh/include/asm/traps_32.h b/arch/sh/include/asm/traps_32.h index 17e129fe459c..8c5bbb7b6053 100644 --- a/arch/sh/include/asm/traps_32.h +++ b/arch/sh/include/asm/traps_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_TRAPS_32_H #define __ASM_SH_TRAPS_32_H diff --git a/arch/sh/include/asm/types.h b/arch/sh/include/asm/types.h index 6a31053fa5e3..df96c511bb6e 100644 --- a/arch/sh/include/asm/types.h +++ b/arch/sh/include/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_TYPES_H #define __ASM_SH_TYPES_H diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h index 211b44920dbe..32eb56e00c11 100644 --- a/arch/sh/include/asm/uaccess.h +++ b/arch/sh/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_UACCESS_H #define __ASM_SH_UACCESS_H diff --git a/arch/sh/include/asm/uaccess_32.h b/arch/sh/include/asm/uaccess_32.h index c0de7ee35ab7..624cf55acc27 100644 --- a/arch/sh/include/asm/uaccess_32.h +++ b/arch/sh/include/asm/uaccess_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * User space memory access functions * diff --git a/arch/sh/include/asm/unaligned-sh4a.h b/arch/sh/include/asm/unaligned-sh4a.h index 95adc500cabc..d311f00ed530 100644 --- a/arch/sh/include/asm/unaligned-sh4a.h +++ b/arch/sh/include/asm/unaligned-sh4a.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_UNALIGNED_SH4A_H #define __ASM_SH_UNALIGNED_SH4A_H diff --git a/arch/sh/include/asm/unaligned.h b/arch/sh/include/asm/unaligned.h index 7d14e0669961..0c92e2c73af4 100644 --- a/arch/sh/include/asm/unaligned.h +++ b/arch/sh/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SH_UNALIGNED_H #define _ASM_SH_UNALIGNED_H diff --git a/arch/sh/include/asm/uncached.h b/arch/sh/include/asm/uncached.h index 6f8816b79cf1..e7f68ec61014 100644 --- a/arch/sh/include/asm/uncached.h +++ b/arch/sh/include/asm/uncached.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_UNCACHED_H #define __ASM_SH_UNCACHED_H diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h index 126fe8340b22..b36200af9ce7 100644 --- a/arch/sh/include/asm/unistd.h +++ b/arch/sh/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ # ifdef CONFIG_SUPERH32 # include # else diff --git a/arch/sh/include/asm/unwinder.h b/arch/sh/include/asm/unwinder.h index 1e65c07b3e18..ce82c96c7899 100644 --- a/arch/sh/include/asm/unwinder.h +++ b/arch/sh/include/asm/unwinder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_UNWINDER_H #define _LINUX_UNWINDER_H diff --git a/arch/sh/include/asm/user.h b/arch/sh/include/asm/user.h index 8fd3cf6c58d4..e97f2efed527 100644 --- a/arch/sh/include/asm/user.h +++ b/arch/sh/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_USER_H #define __ASM_SH_USER_H diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h index d58ad493b3a6..f312813f39d8 100644 --- a/arch/sh/include/asm/vmlinux.lds.h +++ b/arch/sh/include/asm/vmlinux.lds.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_VMLINUX_LDS_H #define __ASM_SH_VMLINUX_LDS_H diff --git a/arch/sh/include/asm/word-at-a-time.h b/arch/sh/include/asm/word-at-a-time.h index 6e38953ff7fd..4aa398455b94 100644 --- a/arch/sh/include/asm/word-at-a-time.h +++ b/arch/sh/include/asm/word-at-a-time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_WORD_AT_A_TIME_H #define __ASM_SH_WORD_AT_A_TIME_H diff --git a/arch/sh/include/cpu-common/cpu/rtc.h b/arch/sh/include/cpu-common/cpu/rtc.h index 39e2d6e94782..5fe726acd9f8 100644 --- a/arch/sh/include/cpu-common/cpu/rtc.h +++ b/arch/sh/include/cpu-common/cpu/rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH2_RTC_H #define __ASM_SH_CPU_SH2_RTC_H diff --git a/arch/sh/include/cpu-common/cpu/sigcontext.h b/arch/sh/include/cpu-common/cpu/sigcontext.h index fe5c15dd6e87..e005dd176ff2 100644 --- a/arch/sh/include/cpu-common/cpu/sigcontext.h +++ b/arch/sh/include/cpu-common/cpu/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPU_SH2_SIGCONTEXT_H #define __ASM_CPU_SH2_SIGCONTEXT_H diff --git a/arch/sh/include/cpu-sh2a/cpu/addrspace.h b/arch/sh/include/cpu-sh2a/cpu/addrspace.h index 31eb4b58aa6d..3afa46c09fb5 100644 --- a/arch/sh/include/cpu-sh2a/cpu/addrspace.h +++ b/arch/sh/include/cpu-sh2a/cpu/addrspace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH2A_ADDRSPACE_H #define __ASM_SH_CPU_SH2A_ADDRSPACE_H diff --git a/arch/sh/include/cpu-sh2a/cpu/rtc.h b/arch/sh/include/cpu-sh2a/cpu/rtc.h index afb511e2bed7..6b6c7ee752de 100644 --- a/arch/sh/include/cpu-sh2a/cpu/rtc.h +++ b/arch/sh/include/cpu-sh2a/cpu/rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH2A_RTC_H #define __ASM_SH_CPU_SH2A_RTC_H diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7203.h b/arch/sh/include/cpu-sh2a/cpu/sh7203.h index 79f93159018d..f250adfa46c6 100644 --- a/arch/sh/include/cpu-sh2a/cpu/sh7203.h +++ b/arch/sh/include/cpu-sh2a/cpu/sh7203.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7203_H__ #define __ASM_SH7203_H__ diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7264.h b/arch/sh/include/cpu-sh2a/cpu/sh7264.h index 4d1ef6d74bd6..d12c19186845 100644 --- a/arch/sh/include/cpu-sh2a/cpu/sh7264.h +++ b/arch/sh/include/cpu-sh2a/cpu/sh7264.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7264_H__ #define __ASM_SH7264_H__ @@ -43,9 +44,7 @@ enum { GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4, GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0, - /* Port H */ - GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4, - GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0, + /* Port H - Port H does not have a Data Register */ /* Port I - not on device */ diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7269.h b/arch/sh/include/cpu-sh2a/cpu/sh7269.h index 2a0ca8780f0d..d516e5d48818 100644 --- a/arch/sh/include/cpu-sh2a/cpu/sh7269.h +++ b/arch/sh/include/cpu-sh2a/cpu/sh7269.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7269_H__ #define __ASM_SH7269_H__ @@ -45,9 +46,7 @@ enum { GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4, GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0, - /* Port H */ - GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4, - GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0, + /* Port H - Port H does not have a Data Register */ /* Port I - not on device */ diff --git a/arch/sh/include/cpu-sh3/cpu/adc.h b/arch/sh/include/cpu-sh3/cpu/adc.h index b289e3ca19a6..2ee206c9bf1a 100644 --- a/arch/sh/include/cpu-sh3/cpu/adc.h +++ b/arch/sh/include/cpu-sh3/cpu/adc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPU_SH3_ADC_H #define __ASM_CPU_SH3_ADC_H diff --git a/arch/sh/include/cpu-sh3/cpu/dac.h b/arch/sh/include/cpu-sh3/cpu/dac.h index 98f1d15f0ab5..fd02331608a8 100644 --- a/arch/sh/include/cpu-sh3/cpu/dac.h +++ b/arch/sh/include/cpu-sh3/cpu/dac.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPU_SH3_DAC_H #define __ASM_CPU_SH3_DAC_H diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h index bccb4144a5e3..cd139681af4b 100644 --- a/arch/sh/include/cpu-sh3/cpu/dma.h +++ b/arch/sh/include/cpu-sh3/cpu/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPU_SH3_DMA_H #define __ASM_CPU_SH3_DMA_H diff --git a/arch/sh/include/cpu-sh3/cpu/serial.h b/arch/sh/include/cpu-sh3/cpu/serial.h index 7766329bc103..7b2ce6e3003e 100644 --- a/arch/sh/include/cpu-sh3/cpu/serial.h +++ b/arch/sh/include/cpu-sh3/cpu/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPU_SH3_SERIAL_H #define __CPU_SH3_SERIAL_H diff --git a/arch/sh/include/cpu-sh3/cpu/sh7720.h b/arch/sh/include/cpu-sh3/cpu/sh7720.h index 41c1406d6da2..449790c9eb77 100644 --- a/arch/sh/include/cpu-sh3/cpu/sh7720.h +++ b/arch/sh/include/cpu-sh3/cpu/sh7720.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7720_H__ #define __ASM_SH7720_H__ diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h index a520eb219621..38187d06b234 100644 --- a/arch/sh/include/cpu-sh4/cpu/dma.h +++ b/arch/sh/include/cpu-sh4/cpu/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPU_SH4_DMA_H #define __ASM_CPU_SH4_DMA_H diff --git a/arch/sh/include/cpu-sh4/cpu/rtc.h b/arch/sh/include/cpu-sh4/cpu/rtc.h index 95e6fb76c24d..45647566940f 100644 --- a/arch/sh/include/cpu-sh4/cpu/rtc.h +++ b/arch/sh/include/cpu-sh4/cpu/rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH4_RTC_H #define __ASM_SH_CPU_SH4_RTC_H diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h index 3bb74e534d0f..2306c79f4b5e 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7722.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7722_H__ #define __ASM_SH7722_H__ @@ -67,7 +68,7 @@ enum { GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0, /* PTQ */ - GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4, + GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4, GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0, /* PTR */ diff --git a/arch/sh/include/cpu-sh4/cpu/sh7723.h b/arch/sh/include/cpu-sh4/cpu/sh7723.h index 668da89bdac4..41f675307503 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7723.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7723.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7723_H__ #define __ASM_SH7723_H__ diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h index 38859f96d4e5..b3a7caf54c9d 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7724.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7724_H__ #define __ASM_SH7724_H__ diff --git a/arch/sh/include/cpu-sh4/cpu/sh7734.h b/arch/sh/include/cpu-sh4/cpu/sh7734.h index 2fb9a7b71b41..96f0246ad2f2 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7734.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7734.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7734_H__ #define __ASM_SH7734_H__ diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h index 5340f3bc1863..6781d41b7467 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7757_H__ #define __ASM_SH7757_H__ @@ -40,7 +41,7 @@ enum { /* PTJ */ GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3, - GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV, + GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, /* PTK */ GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3, @@ -48,7 +49,7 @@ enum { /* PTL */ GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3, - GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV, + GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, /* PTM */ GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3, @@ -56,7 +57,7 @@ enum { /* PTN */ GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3, - GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV, + GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, /* PTO */ GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3, @@ -68,7 +69,7 @@ enum { /* PTQ */ GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3, - GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV, + GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, /* PTR */ GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3, diff --git a/arch/sh/include/cpu-sh4/cpu/sh7785.h b/arch/sh/include/cpu-sh4/cpu/sh7785.h index 9dc9d91e0a8e..37f42071e7d3 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7785.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7785.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH7785_H__ #define __ASM_SH7785_H__ diff --git a/arch/sh/include/cpu-sh4/cpu/shx3.h b/arch/sh/include/cpu-sh4/cpu/shx3.h index 68d9080a8da9..f356810b0bea 100644 --- a/arch/sh/include/cpu-sh4/cpu/shx3.h +++ b/arch/sh/include/cpu-sh4/cpu/shx3.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPU_SHX3_H #define __CPU_SHX3_H diff --git a/arch/sh/include/cpu-sh4/cpu/sigcontext.h b/arch/sh/include/cpu-sh4/cpu/sigcontext.h index ab392f120e06..2cc5f55dcadd 100644 --- a/arch/sh/include/cpu-sh4/cpu/sigcontext.h +++ b/arch/sh/include/cpu-sh4/cpu/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPU_SH4_SIGCONTEXT_H #define __ASM_CPU_SH4_SIGCONTEXT_H diff --git a/arch/sh/include/cpu-sh4a/cpu/dma.h b/arch/sh/include/cpu-sh4a/cpu/dma.h index 8ceccceae844..bdbbba8a784a 100644 --- a/arch/sh/include/cpu-sh4a/cpu/dma.h +++ b/arch/sh/include/cpu-sh4a/cpu/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH4_DMA_SH7780_H #define __ASM_SH_CPU_SH4_DMA_SH7780_H diff --git a/arch/sh/include/cpu-sh4a/cpu/serial.h b/arch/sh/include/cpu-sh4a/cpu/serial.h index ff1bc275d210..fc206c0bf6fb 100644 --- a/arch/sh/include/cpu-sh4a/cpu/serial.h +++ b/arch/sh/include/cpu-sh4a/cpu/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPU_SH4A_SERIAL_H #define __CPU_SH4A_SERIAL_H diff --git a/arch/sh/include/cpu-sh5/cpu/addrspace.h b/arch/sh/include/cpu-sh5/cpu/addrspace.h index dc36b9a03af6..6dd1e72f31b2 100644 --- a/arch/sh/include/cpu-sh5/cpu/addrspace.h +++ b/arch/sh/include/cpu-sh5/cpu/addrspace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH5_ADDRSPACE_H #define __ASM_SH_CPU_SH5_ADDRSPACE_H diff --git a/arch/sh/include/cpu-sh5/cpu/mmu_context.h b/arch/sh/include/cpu-sh5/cpu/mmu_context.h index 68a1d2cff457..23c53be945b7 100644 --- a/arch/sh/include/cpu-sh5/cpu/mmu_context.h +++ b/arch/sh/include/cpu-sh5/cpu/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH5_MMU_CONTEXT_H #define __ASM_SH_CPU_SH5_MMU_CONTEXT_H diff --git a/arch/sh/include/cpu-sh5/cpu/rtc.h b/arch/sh/include/cpu-sh5/cpu/rtc.h index 12ea0ed144e1..d7e25d435f4a 100644 --- a/arch/sh/include/cpu-sh5/cpu/rtc.h +++ b/arch/sh/include/cpu-sh5/cpu/rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_CPU_SH5_RTC_H #define __ASM_SH_CPU_SH5_RTC_H diff --git a/arch/sh/include/mach-common/mach/highlander.h b/arch/sh/include/mach-common/mach/highlander.h index 6ce944e33e59..66d3e40fd046 100644 --- a/arch/sh/include/mach-common/mach/highlander.h +++ b/arch/sh/include/mach-common/mach/highlander.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_RENESAS_R7780RP_H #define __ASM_SH_RENESAS_R7780RP_H diff --git a/arch/sh/include/mach-common/mach/r2d.h b/arch/sh/include/mach-common/mach/r2d.h index e04f75eaa153..0d7e483c7d3f 100644 --- a/arch/sh/include/mach-common/mach/r2d.h +++ b/arch/sh/include/mach-common/mach/r2d.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_RENESAS_RTS7751R2D_H #define __ASM_SH_RENESAS_RTS7751R2D_H diff --git a/arch/sh/include/mach-common/mach/romimage.h b/arch/sh/include/mach-common/mach/romimage.h index 3670455faaac..1915714263aa 100644 --- a/arch/sh/include/mach-common/mach/romimage.h +++ b/arch/sh/include/mach-common/mach/romimage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __ASSEMBLY__ /* do nothing here by default */ diff --git a/arch/sh/include/mach-common/mach/sh2007.h b/arch/sh/include/mach-common/mach/sh2007.h index 48180b9aa03d..eeb12901a44a 100644 --- a/arch/sh/include/mach-common/mach/sh2007.h +++ b/arch/sh/include/mach-common/mach/sh2007.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_SH2007_H #define __MACH_SH2007_H diff --git a/arch/sh/include/mach-common/mach/sh7785lcr.h b/arch/sh/include/mach-common/mach/sh7785lcr.h index 1292ae5c21b3..0f3dc3a1329e 100644 --- a/arch/sh/include/mach-common/mach/sh7785lcr.h +++ b/arch/sh/include/mach-common/mach/sh7785lcr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_RENESAS_SH7785LCR_H #define __ASM_SH_RENESAS_SH7785LCR_H diff --git a/arch/sh/include/mach-common/mach/shmin.h b/arch/sh/include/mach-common/mach/shmin.h index 36ba138a81fb..c2c3e26d1453 100644 --- a/arch/sh/include/mach-common/mach/shmin.h +++ b/arch/sh/include/mach-common/mach/shmin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SHMIN_H #define __ASM_SH_SHMIN_H diff --git a/arch/sh/include/mach-common/mach/titan.h b/arch/sh/include/mach-common/mach/titan.h index fa3cd801cf2e..54df351de5e4 100644 --- a/arch/sh/include/mach-common/mach/titan.h +++ b/arch/sh/include/mach-common/mach/titan.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Platform definitions for Titan */ diff --git a/arch/sh/include/mach-common/mach/urquell.h b/arch/sh/include/mach-common/mach/urquell.h index 14b3e1d01777..6c9bff3f93f1 100644 --- a/arch/sh/include/mach-common/mach/urquell.h +++ b/arch/sh/include/mach-common/mach/urquell.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_URQUELL_H #define __MACH_URQUELL_H diff --git a/arch/sh/include/mach-dreamcast/mach/maple.h b/arch/sh/include/mach-dreamcast/mach/maple.h index 51f6a87f1f11..169bdf415d89 100644 --- a/arch/sh/include/mach-dreamcast/mach/maple.h +++ b/arch/sh/include/mach-dreamcast/mach/maple.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_MAPLE_H #define __ASM_MAPLE_H diff --git a/arch/sh/include/mach-ecovec24/mach/romimage.h b/arch/sh/include/mach-ecovec24/mach/romimage.h index 60f3e8af05fa..2da6ff326cbd 100644 --- a/arch/sh/include/mach-ecovec24/mach/romimage.h +++ b/arch/sh/include/mach-ecovec24/mach/romimage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __ASSEMBLY__ /* EcoVec board specific boot code: diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h index 79f154e5cb9c..0e97473afe0b 100644 --- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h +++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_KFR2R09_H #define __ASM_SH_KFR2R09_H diff --git a/arch/sh/include/mach-kfr2r09/mach/romimage.h b/arch/sh/include/mach-kfr2r09/mach/romimage.h index 1afae21ced5f..209275872ff0 100644 --- a/arch/sh/include/mach-kfr2r09/mach/romimage.h +++ b/arch/sh/include/mach-kfr2r09/mach/romimage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef __ASSEMBLY__ /* kfr2r09 board specific boot code: diff --git a/arch/sh/include/mach-landisk/mach/gio.h b/arch/sh/include/mach-landisk/mach/gio.h index 35d7368b718a..b954de617b49 100644 --- a/arch/sh/include/mach-landisk/mach/gio.h +++ b/arch/sh/include/mach-landisk/mach/gio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_LANDISK_GIO_H #define __ASM_SH_LANDISK_GIO_H diff --git a/arch/sh/include/mach-landisk/mach/iodata_landisk.h b/arch/sh/include/mach-landisk/mach/iodata_landisk.h index ceeea48cc7af..b41308c94d1e 100644 --- a/arch/sh/include/mach-landisk/mach/iodata_landisk.h +++ b/arch/sh/include/mach-landisk/mach/iodata_landisk.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_IODATA_LANDISK_H #define __ASM_SH_IODATA_LANDISK_H diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h index 7de7bb74c290..2a422b778e00 100644 --- a/arch/sh/include/mach-migor/mach/migor.h +++ b/arch/sh/include/mach-migor/mach/migor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_MIGOR_H #define __ASM_SH_MIGOR_H diff --git a/arch/sh/include/mach-sdk7786/mach/fpga.h b/arch/sh/include/mach-sdk7786/mach/fpga.h index a9cdac469927..76c2e84893cc 100644 --- a/arch/sh/include/mach-sdk7786/mach/fpga.h +++ b/arch/sh/include/mach-sdk7786/mach/fpga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_SDK7786_FPGA_H #define __MACH_SDK7786_FPGA_H diff --git a/arch/sh/include/mach-sdk7786/mach/irq.h b/arch/sh/include/mach-sdk7786/mach/irq.h index 0f584635e6e5..3343380907b2 100644 --- a/arch/sh/include/mach-sdk7786/mach/irq.h +++ b/arch/sh/include/mach-sdk7786/mach/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_SDK7786_IRQ_H #define __MACH_SDK7786_IRQ_H diff --git a/arch/sh/include/mach-se/mach/mrshpc.h b/arch/sh/include/mach-se/mach/mrshpc.h index 56287ee8563a..4e260f399b79 100644 --- a/arch/sh/include/mach-se/mach/mrshpc.h +++ b/arch/sh/include/mach-se/mach/mrshpc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_SE_MRSHPC_H #define __MACH_SE_MRSHPC_H diff --git a/arch/sh/include/mach-se/mach/se.h b/arch/sh/include/mach-se/mach/se.h index 8a6d44b4987b..4246ef9b07a3 100644 --- a/arch/sh/include/mach-se/mach/se.h +++ b/arch/sh/include/mach-se/mach/se.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HITACHI_SE_H #define __ASM_SH_HITACHI_SE_H diff --git a/arch/sh/include/mach-se/mach/se7206.h b/arch/sh/include/mach-se/mach/se7206.h index 698eb80389ab..cf190279bb1d 100644 --- a/arch/sh/include/mach-se/mach/se7206.h +++ b/arch/sh/include/mach-se/mach/se7206.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SE7206_H #define __ASM_SH_SE7206_H diff --git a/arch/sh/include/mach-se/mach/se7343.h b/arch/sh/include/mach-se/mach/se7343.h index 542521c970c6..107fb5f3ef80 100644 --- a/arch/sh/include/mach-se/mach/se7343.h +++ b/arch/sh/include/mach-se/mach/se7343.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HITACHI_SE7343_H #define __ASM_SH_HITACHI_SE7343_H diff --git a/arch/sh/include/mach-se/mach/se7751.h b/arch/sh/include/mach-se/mach/se7751.h index 271871793d59..ee5b5e6e5979 100644 --- a/arch/sh/include/mach-se/mach/se7751.h +++ b/arch/sh/include/mach-se/mach/se7751.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_HITACHI_7751SE_H #define __ASM_SH_HITACHI_7751SE_H diff --git a/arch/sh/include/mach-sh03/mach/io.h b/arch/sh/include/mach-sh03/mach/io.h index c39c785bba94..5eacdabd71b6 100644 --- a/arch/sh/include/mach-sh03/mach/io.h +++ b/arch/sh/include/mach-sh03/mach/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm-sh/sh03/io.h * diff --git a/arch/sh/include/mach-sh03/mach/sh03.h b/arch/sh/include/mach-sh03/mach/sh03.h index 19c40b80428d..4ced684b16a4 100644 --- a/arch/sh/include/mach-sh03/mach/sh03.h +++ b/arch/sh/include/mach-sh03/mach/sh03.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_SH03_H #define __ASM_SH_SH03_H diff --git a/arch/sh/include/mach-x3proto/mach/hardware.h b/arch/sh/include/mach-x3proto/mach/hardware.h index 52bca57bfeb6..57ea4a5cca35 100644 --- a/arch/sh/include/mach-x3proto/mach/hardware.h +++ b/arch/sh/include/mach-x3proto/mach/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MACH_X3PROTO_HARDWARE_H #define __MACH_X3PROTO_HARDWARE_H diff --git a/arch/sh/include/mach-x3proto/mach/ilsel.h b/arch/sh/include/mach-x3proto/mach/ilsel.h index e3d304b280f6..47aeb4b55ea1 100644 --- a/arch/sh/include/mach-x3proto/mach/ilsel.h +++ b/arch/sh/include/mach-x3proto/mach/ilsel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SH_ILSEL_H #define __ASM_SH_ILSEL_H diff --git a/arch/sh/include/uapi/asm/auxvec.h b/arch/sh/include/uapi/asm/auxvec.h index 8bcc51af9367..8eb47ede7193 100644 --- a/arch/sh/include/uapi/asm/auxvec.h +++ b/arch/sh/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_AUXVEC_H #define __ASM_SH_AUXVEC_H diff --git a/arch/sh/include/uapi/asm/byteorder.h b/arch/sh/include/uapi/asm/byteorder.h index db2f5d7cb17d..e27d6da3212c 100644 --- a/arch/sh/include/uapi/asm/byteorder.h +++ b/arch/sh/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_BYTEORDER_H #define __ASM_SH_BYTEORDER_H diff --git a/arch/sh/include/uapi/asm/cachectl.h b/arch/sh/include/uapi/asm/cachectl.h index 6ffb4b7a212e..79c5663251a5 100644 --- a/arch/sh/include/uapi/asm/cachectl.h +++ b/arch/sh/include/uapi/asm/cachectl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SH_CACHECTL_H #define _SH_CACHECTL_H diff --git a/arch/sh/include/uapi/asm/cpu-features.h b/arch/sh/include/uapi/asm/cpu-features.h index 2f1bc851042a..6de5f65194e6 100644 --- a/arch/sh/include/uapi/asm/cpu-features.h +++ b/arch/sh/include/uapi/asm/cpu-features.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_CPU_FEATURES_H #define __ASM_SH_CPU_FEATURES_H diff --git a/arch/sh/include/uapi/asm/hw_breakpoint.h b/arch/sh/include/uapi/asm/hw_breakpoint.h index ae5704fa77ad..043dd4b92026 100644 --- a/arch/sh/include/uapi/asm/hw_breakpoint.h +++ b/arch/sh/include/uapi/asm/hw_breakpoint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * There isn't anything here anymore, but the file must not be empty or patch * will delete it. diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h index 787bac9f67da..cc62f6f98103 100644 --- a/arch/sh/include/uapi/asm/ioctls.h +++ b/arch/sh/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_IOCTLS_H #define __ASM_SH_IOCTLS_H diff --git a/arch/sh/include/uapi/asm/posix_types.h b/arch/sh/include/uapi/asm/posix_types.h index dc55e5adfe1e..2644fdd444e6 100644 --- a/arch/sh/include/uapi/asm/posix_types.h +++ b/arch/sh/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __KERNEL__ # ifdef __SH5__ # include diff --git a/arch/sh/include/uapi/asm/posix_types_32.h b/arch/sh/include/uapi/asm/posix_types_32.h index ba0bdc423b07..ea0f51d1ac55 100644 --- a/arch/sh/include/uapi/asm/posix_types_32.h +++ b/arch/sh/include/uapi/asm/posix_types_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_POSIX_TYPES_32_H #define __ASM_SH_POSIX_TYPES_32_H diff --git a/arch/sh/include/uapi/asm/posix_types_64.h b/arch/sh/include/uapi/asm/posix_types_64.h index 244f7e950e17..3a9128d4aee3 100644 --- a/arch/sh/include/uapi/asm/posix_types_64.h +++ b/arch/sh/include/uapi/asm/posix_types_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_POSIX_TYPES_64_H #define __ASM_SH_POSIX_TYPES_64_H diff --git a/arch/sh/include/uapi/asm/ptrace.h b/arch/sh/include/uapi/asm/ptrace.h index 8b8c5aca9c28..4ec9c2b65fdb 100644 --- a/arch/sh/include/uapi/asm/ptrace.h +++ b/arch/sh/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 1999, 2000 Niibe Yutaka */ diff --git a/arch/sh/include/uapi/asm/ptrace_32.h b/arch/sh/include/uapi/asm/ptrace_32.h index 926e0cefc2bb..dc8a26015018 100644 --- a/arch/sh/include/uapi/asm/ptrace_32.h +++ b/arch/sh/include/uapi/asm/ptrace_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ASM_SH_PTRACE_32_H #define _UAPI__ASM_SH_PTRACE_32_H diff --git a/arch/sh/include/uapi/asm/ptrace_64.h b/arch/sh/include/uapi/asm/ptrace_64.h index 0e52ee83e946..a6f84eba5277 100644 --- a/arch/sh/include/uapi/asm/ptrace_64.h +++ b/arch/sh/include/uapi/asm/ptrace_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__ASM_SH_PTRACE_64_H #define _UAPI__ASM_SH_PTRACE_64_H diff --git a/arch/sh/include/uapi/asm/sigcontext.h b/arch/sh/include/uapi/asm/sigcontext.h index faa5d0833412..d2b7e4f033c0 100644 --- a/arch/sh/include/uapi/asm/sigcontext.h +++ b/arch/sh/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_SIGCONTEXT_H #define __ASM_SH_SIGCONTEXT_H diff --git a/arch/sh/include/uapi/asm/signal.h b/arch/sh/include/uapi/asm/signal.h index cb96d02f55a4..97299daddef5 100644 --- a/arch/sh/include/uapi/asm/signal.h +++ b/arch/sh/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_SIGNAL_H #define __ASM_SH_SIGNAL_H diff --git a/arch/sh/include/uapi/asm/sockios.h b/arch/sh/include/uapi/asm/sockios.h index cf8b96b1f9ab..17313d2c3527 100644 --- a/arch/sh/include/uapi/asm/sockios.h +++ b/arch/sh/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_SOCKIOS_H #define __ASM_SH_SOCKIOS_H diff --git a/arch/sh/include/uapi/asm/stat.h b/arch/sh/include/uapi/asm/stat.h index e1810cc6e3da..659b87c7c25a 100644 --- a/arch/sh/include/uapi/asm/stat.h +++ b/arch/sh/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_STAT_H #define __ASM_SH_STAT_H diff --git a/arch/sh/include/uapi/asm/swab.h b/arch/sh/include/uapi/asm/swab.h index 1cd09767a7a3..f0b02152745c 100644 --- a/arch/sh/include/uapi/asm/swab.h +++ b/arch/sh/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_SWAB_H #define __ASM_SH_SWAB_H diff --git a/arch/sh/include/uapi/asm/unistd.h b/arch/sh/include/uapi/asm/unistd.h index eeef88dd53ce..9e0b4e5e6da2 100644 --- a/arch/sh/include/uapi/asm/unistd.h +++ b/arch/sh/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __KERNEL__ # ifdef __SH5__ # include diff --git a/arch/sh/include/uapi/asm/unistd_32.h b/arch/sh/include/uapi/asm/unistd_32.h index c801bde9e6f5..58f04cf3d1d9 100644 --- a/arch/sh/include/uapi/asm/unistd_32.h +++ b/arch/sh/include/uapi/asm/unistd_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_UNISTD_32_H #define __ASM_SH_UNISTD_32_H diff --git a/arch/sh/include/uapi/asm/unistd_64.h b/arch/sh/include/uapi/asm/unistd_64.h index ce0cb3598b62..6f809a53aa24 100644 --- a/arch/sh/include/uapi/asm/unistd_64.h +++ b/arch/sh/include/uapi/asm/unistd_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_SH_UNISTD_64_H #define __ASM_SH_UNISTD_64_H diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 09040fd07d2e..dc80041f7363 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SuperH kernel. # diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c index 4bd44da910f3..a0322e832845 100644 --- a/arch/sh/kernel/asm-offsets.c +++ b/arch/sh/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This program is used to generate definitions needed by * assembly language modules. diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 252e9fee687f..f7c22ea98b0f 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SuperH CPU-specific backends. # diff --git a/arch/sh/kernel/cpu/adc.c b/arch/sh/kernel/cpu/adc.c index d307571d54b6..509136715ed5 100644 --- a/arch/sh/kernel/cpu/adc.c +++ b/arch/sh/kernel/cpu/adc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/kernel/adc.c -- SH3 on-chip ADC support * diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c index 786c0769b4c3..5b75a384cbf3 100644 --- a/arch/sh/kernel/cpu/clock-cpg.c +++ b/arch/sh/kernel/cpu/clock-cpg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c index 547c73478459..ae354a2931e7 100644 --- a/arch/sh/kernel/cpu/fpu.c +++ b/arch/sh/kernel/cpu/fpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index e7f1745bd121..572585c3f2fd 100644 --- a/arch/sh/kernel/cpu/irq/imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sh/kernel/cpu/irq/imask.c * diff --git a/arch/sh/kernel/cpu/proc.c b/arch/sh/kernel/cpu/proc.c index 4df4b284f591..85961b4f9c69 100644 --- a/arch/sh/kernel/cpu/proc.c +++ b/arch/sh/kernel/cpu/proc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile index 990195d98456..2a7515b658fd 100644 --- a/arch/sh/kernel/cpu/sh2a/Makefile +++ b/arch/sh/kernel/cpu/sh2a/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SuperH SH-2A backends. # diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index d3634ae7b71a..1dcb43d93c86 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SuperH SH-3 backends. # diff --git a/arch/sh/kernel/cpu/sh3/serial-sh770x.c b/arch/sh/kernel/cpu/sh3/serial-sh770x.c index 4f7242c676b3..dec027f233f2 100644 --- a/arch/sh/kernel/cpu/sh3/serial-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/serial-sh770x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7710.c b/arch/sh/kernel/cpu/sh3/serial-sh7710.c index 42190ef6aebf..ee04052e5bdd 100644 --- a/arch/sh/kernel/cpu/sh3/serial-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/serial-sh7710.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/sh3/serial-sh7720.c b/arch/sh/kernel/cpu/sh3/serial-sh7720.c index c4a0336660dd..75aaea49de43 100644 --- a/arch/sh/kernel/cpu/sh3/serial-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/serial-sh7720.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 3a1dbc709831..00c16331e07e 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SuperH SH-4 backends. # diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index 0705df775208..baf73a8fc2a0 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SuperH SH-4 backends. # diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c index 271bbc864929..0dd5312f930b 100644 --- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/sh4a/serial-sh7722.c b/arch/sh/kernel/cpu/sh4a/serial-sh7722.c index 59bc3a72702e..6ecc8b6e133c 100644 --- a/arch/sh/kernel/cpu/sh4a/serial-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/serial-sh7722.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/cpu/sh5/Makefile b/arch/sh/kernel/cpu/sh5/Makefile index a184a31e686e..97d23ec3005f 100644 --- a/arch/sh/kernel/cpu/sh5/Makefile +++ b/arch/sh/kernel/cpu/sh5/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/SuperH SH-5 backends. # diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c index b33be505361e..a9086127b16d 100644 --- a/arch/sh/kernel/crash_dump.c +++ b/arch/sh/kernel/crash_dump.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * crash_dump.c - Memory preserving reboot related code. * diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c index d18724d186f3..96dd9f7da250 100644 --- a/arch/sh/kernel/ftrace.c +++ b/arch/sh/kernel/ftrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2008 Matt Fleming * Copyright (C) 2008 Paul Mundt diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 04487e8fc9b1..245dbeb20afe 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/kernel/irq.c * diff --git a/arch/sh/kernel/kdebugfs.c b/arch/sh/kernel/kdebugfs.c index e11c30bb100c..95428e05d212 100644 --- a/arch/sh/kernel/kdebugfs.c +++ b/arch/sh/kernel/kdebugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index f8a695a223dd..b2d9963d5978 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 0a05983633ca..bfc59f2c2602 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include /** diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c index 04afe5b20663..11001a8a5fe0 100644 --- a/arch/sh/kernel/reboot.c +++ b/arch/sh/kernel/reboot.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 3a44c753b642..b95c411d0333 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sh/kernel/setup.c * diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 0b30b9dfc87f..282774472603 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 08bce11badc6..c46c0020ff55 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/kernel/signal.c * diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 6576e5ee1fc3..724911c59e7d 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/kernel/sys_sh.c * diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index a2e1231a90a3..f8dc8bfd4606 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index b32d1c3a4655..8b49cced663d 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 5b9a3cc90c58..77a59d8c6b4d 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ld script to make SuperH Linux kernel * Written by Niibe Yutaka and Paul Mundt diff --git a/arch/sh/kernel/vsyscall/Makefile b/arch/sh/kernel/vsyscall/Makefile index 6ab108f1a0c6..5db6579bc44c 100644 --- a/arch/sh/kernel/vsyscall/Makefile +++ b/arch/sh/kernel/vsyscall/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y += vsyscall.o vsyscall-syscall.o vsyscall-syms.o $(obj)/vsyscall-syscall.o: \ diff --git a/arch/sh/kernel/vsyscall/vsyscall-note.S b/arch/sh/kernel/vsyscall/vsyscall-note.S index d4b5be4f3d5f..bb350918bebd 100644 --- a/arch/sh/kernel/vsyscall/vsyscall-note.S +++ b/arch/sh/kernel/vsyscall/vsyscall-note.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. * Here we can supply some information useful to userland. diff --git a/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S b/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S index 23af17584054..bece5fa73618 100644 --- a/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S +++ b/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include .text diff --git a/arch/sh/kernel/vsyscall/vsyscall-syscall.S b/arch/sh/kernel/vsyscall/vsyscall-syscall.S index c2ac7f0282b3..2aeaa2ddee50 100644 --- a/arch/sh/kernel/vsyscall/vsyscall-syscall.S +++ b/arch/sh/kernel/vsyscall/vsyscall-syscall.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include __INITDATA diff --git a/arch/sh/kernel/vsyscall/vsyscall-trapa.S b/arch/sh/kernel/vsyscall/vsyscall-trapa.S index 0eb74d00690a..854ea3235704 100644 --- a/arch/sh/kernel/vsyscall/vsyscall-trapa.S +++ b/arch/sh/kernel/vsyscall/vsyscall-trapa.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .text .globl __kernel_vsyscall .type __kernel_vsyscall,@function diff --git a/arch/sh/kernel/vsyscall/vsyscall.lds.S b/arch/sh/kernel/vsyscall/vsyscall.lds.S index 6d59ee7c23dd..e3582e03c0eb 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.lds.S +++ b/arch/sh/kernel/vsyscall/vsyscall.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Linker script for vsyscall DSO. The vsyscall page is an ELF shared * object prelinked to its virtual address, and with only one read-only diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index 3baff31e58cf..d0abbe5e38b0 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for SuperH-specific library files.. # diff --git a/arch/sh/lib/__clear_user.S b/arch/sh/lib/__clear_user.S index db1dca7aad14..0978606907ed 100644 --- a/arch/sh/lib/__clear_user.S +++ b/arch/sh/lib/__clear_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * __clear_user_page, __clear_user, clear_page implementation of SuperH * diff --git a/arch/sh/lib/ashldi3.c b/arch/sh/lib/ashldi3.c index beb80f316095..e5afe0935847 100644 --- a/arch/sh/lib/ashldi3.c +++ b/arch/sh/lib/ashldi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/sh/lib/ashrdi3.c b/arch/sh/lib/ashrdi3.c index c884a912b660..ae263fbf2538 100644 --- a/arch/sh/lib/ashrdi3.c +++ b/arch/sh/lib/ashrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/sh/lib/copy_page.S b/arch/sh/lib/copy_page.S index 9d7b8bc51866..d4e9d18cee0b 100644 --- a/arch/sh/lib/copy_page.S +++ b/arch/sh/lib/copy_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * copy_page, __copy_user_page, __copy_user implementation of SuperH * diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c index 0901b2f14e15..dad8e6a54906 100644 --- a/arch/sh/lib/delay.c +++ b/arch/sh/lib/delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Precise Delay Loops for SuperH * diff --git a/arch/sh/lib/div64-generic.c b/arch/sh/lib/div64-generic.c index 60e76aa8b53e..0b67fbc44f6f 100644 --- a/arch/sh/lib/div64-generic.c +++ b/arch/sh/lib/div64-generic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generic __div64_32 wrapper for __xdiv64_32. */ diff --git a/arch/sh/lib/div64.S b/arch/sh/lib/div64.S index 5ee7334ea64f..4a9a966e71b0 100644 --- a/arch/sh/lib/div64.S +++ b/arch/sh/lib/div64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * unsigned long __xdiv64_32(unsigned long long n, unsigned long d); */ diff --git a/arch/sh/lib/lshrdi3.c b/arch/sh/lib/lshrdi3.c index dcf8d6810b7c..33eaa1edbc3c 100644 --- a/arch/sh/lib/lshrdi3.c +++ b/arch/sh/lib/lshrdi3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/sh/lib/memchr.S b/arch/sh/lib/memchr.S index bc6036ad5706..8ded104077aa 100644 --- a/arch/sh/lib/memchr.S +++ b/arch/sh/lib/memchr.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: memchr.S,v 1.1 2000/04/14 16:49:01 mjd Exp $ * * "memchr" implementation of SuperH diff --git a/arch/sh/lib/memcpy-sh4.S b/arch/sh/lib/memcpy-sh4.S index 459fa92a7c53..a2435c0f6302 100644 --- a/arch/sh/lib/memcpy-sh4.S +++ b/arch/sh/lib/memcpy-sh4.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * "memcpy" implementation of SuperH * diff --git a/arch/sh/lib/memcpy.S b/arch/sh/lib/memcpy.S index 232fab34c261..08ab3062c4b2 100644 --- a/arch/sh/lib/memcpy.S +++ b/arch/sh/lib/memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $ * * "memcpy" implementation of SuperH diff --git a/arch/sh/lib/memmove.S b/arch/sh/lib/memmove.S index 5a2211f09202..bdca321814a9 100644 --- a/arch/sh/lib/memmove.S +++ b/arch/sh/lib/memmove.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: memmove.S,v 1.2 2001/07/27 11:51:09 gniibe Exp $ * * "memmove" implementation of SuperH diff --git a/arch/sh/lib/memset-sh4.S b/arch/sh/lib/memset-sh4.S index 1a6e32cc4e4d..10649c4cdab8 100644 --- a/arch/sh/lib/memset-sh4.S +++ b/arch/sh/lib/memset-sh4.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * "memset" implementation for SH4 * diff --git a/arch/sh/lib/memset.S b/arch/sh/lib/memset.S index af91fe2b72a6..a6d5ec0bd9cf 100644 --- a/arch/sh/lib/memset.S +++ b/arch/sh/lib/memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: memset.S,v 1.1 2000/04/14 16:49:01 mjd Exp $ * * "memset" implementation of SuperH diff --git a/arch/sh/lib/strlen.S b/arch/sh/lib/strlen.S index 1bcc13f05962..80ea53dd34f6 100644 --- a/arch/sh/lib/strlen.S +++ b/arch/sh/lib/strlen.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $Id: strlen.S,v 1.2 2001/06/29 14:07:15 gniibe Exp $ * * "strlen" implementation of SuperH diff --git a/arch/sh/lib64/copy_user_memcpy.S b/arch/sh/lib64/copy_user_memcpy.S index 49aeabeba2c2..515f81b00202 100644 --- a/arch/sh/lib64/copy_user_memcpy.S +++ b/arch/sh/lib64/copy_user_memcpy.S @@ -1,3 +1,4 @@ +! SPDX-License-Identifier: GPL-2.0 ! ! Fast SH memcpy ! diff --git a/arch/sh/lib64/memcpy.S b/arch/sh/lib64/memcpy.S index 5d682e0ee24f..231ea595b39a 100644 --- a/arch/sh/lib64/memcpy.S +++ b/arch/sh/lib64/memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Cloned and hacked for uClibc by Paul Mundt, December 2003 */ /* Modified by SuperH, Inc. September 2003 */ ! diff --git a/arch/sh/lib64/memset.S b/arch/sh/lib64/memset.S index 2d37b0488552..453aa5f1d263 100644 --- a/arch/sh/lib64/memset.S +++ b/arch/sh/lib64/memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Cloned and hacked for uClibc by Paul Mundt, December 2003 */ /* Modified by SuperH, Inc. September 2003 */ ! diff --git a/arch/sh/lib64/sdivsi3.S b/arch/sh/lib64/sdivsi3.S index 1963bbd42288..b422e2374430 100644 --- a/arch/sh/lib64/sdivsi3.S +++ b/arch/sh/lib64/sdivsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .global __sdivsi3 .global __sdivsi3_1 .global __sdivsi3_2 diff --git a/arch/sh/lib64/strcpy.S b/arch/sh/lib64/strcpy.S index ea7c9c533eea..b61631e523d4 100644 --- a/arch/sh/lib64/strcpy.S +++ b/arch/sh/lib64/strcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Cloned and hacked for uClibc by Paul Mundt, December 2003 */ /* Modified by SuperH, Inc. September 2003 */ ! Entry: arg0: destination diff --git a/arch/sh/lib64/strlen.S b/arch/sh/lib64/strlen.S index cbc0d912e5f3..c00b972f9999 100644 --- a/arch/sh/lib64/strlen.S +++ b/arch/sh/lib64/strlen.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Simplistic strlen() implementation for SHmedia. * diff --git a/arch/sh/lib64/udivdi3.S b/arch/sh/lib64/udivdi3.S index 6895c0225b85..c032cb157589 100644 --- a/arch/sh/lib64/udivdi3.S +++ b/arch/sh/lib64/udivdi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .section .text..SHmedia32,"ax" .align 2 .global __udivdi3 diff --git a/arch/sh/lib64/udivsi3.S b/arch/sh/lib64/udivsi3.S index e68120e4b847..e4788fb4fe82 100644 --- a/arch/sh/lib64/udivsi3.S +++ b/arch/sh/lib64/udivsi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .global __udivsi3 .section .text..SHmedia32,"ax" .align 2 diff --git a/arch/sh/math-emu/sfp-util.h b/arch/sh/math-emu/sfp-util.h index 8ae1bd310ad0..784f541344f3 100644 --- a/arch/sh/math-emu/sfp-util.h +++ b/arch/sh/math-emu/sfp-util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * These are copied from glibc/stdlib/longlong.h */ diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index dba285e86808..50cdd1349015 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Memory management options" config QUICKLIST diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile index 92c3bd96aee5..fbe5e79751b3 100644 --- a/arch/sh/mm/Makefile +++ b/arch/sh/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux SuperH-specific parts of the memory manager. # diff --git a/arch/sh/mm/extable_32.c b/arch/sh/mm/extable_32.c index 940e871bc816..14312027bb08 100644 --- a/arch/sh/mm/extable_32.c +++ b/arch/sh/mm/extable_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sh/mm/extable.c * Taken from: diff --git a/arch/sh/mm/flush-sh4.c b/arch/sh/mm/flush-sh4.c index 0b85dd9dd3a7..8b8ef8972104 100644 --- a/arch/sh/mm/flush-sh4.c +++ b/arch/sh/mm/flush-sh4.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/mm/gup.c b/arch/sh/mm/gup.c index 063c298ba56c..8045b5bb7075 100644 --- a/arch/sh/mm/gup.c +++ b/arch/sh/mm/gup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Lockless get_user_pages_fast for SuperH * diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c index d2412d2d6462..960deb1f24a1 100644 --- a/arch/sh/mm/hugetlbpage.c +++ b/arch/sh/mm/hugetlbpage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sh/mm/hugetlbpage.c * diff --git a/arch/sh/mm/ioremap_fixed.c b/arch/sh/mm/ioremap_fixed.c index efbe84af9983..927a1294c465 100644 --- a/arch/sh/mm/ioremap_fixed.c +++ b/arch/sh/mm/ioremap_fixed.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Re-map IO memory to kernel address space so that we can access it. * diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c index a62bd8696779..5c8f9247c3c2 100644 --- a/arch/sh/mm/pgtable.c +++ b/arch/sh/mm/pgtable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c index a7767da815e9..010010bf205a 100644 --- a/arch/sh/mm/uncached.c +++ b/arch/sh/mm/uncached.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile index ce3b119021e7..d478dd8dac0b 100644 --- a/arch/sh/oprofile/Makefile +++ b/arch/sh/oprofile/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPROFILE) += oprofile.o CFLAGS_common.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' diff --git a/arch/sh/tools/gen-mach-types b/arch/sh/tools/gen-mach-types index f5ff7c5d8913..6d7c2d8eaf55 100644 --- a/arch/sh/tools/gen-mach-types +++ b/arch/sh/tools/gen-mach-types @@ -1,4 +1,5 @@ #!/bin/awk +# SPDX-License-Identifier: GPL-2.0 # # Awk script to generate include/generated/machtypes.h # Heavily based on arch/arm/tools/gen-mach-types diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index a4a626199c47..4e83f950713e 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -44,7 +44,6 @@ config SPARC select ARCH_HAS_SG_CHAIN select CPU_NO_EFFICIENT_FFS select LOCKDEP_SMALL if LOCKDEP - select ARCH_WANT_RELAX_ORDER config SPARC32 def_bool !64BIT @@ -97,6 +96,9 @@ config ARCH_PROC_KCORE_TEXT config CPU_BIG_ENDIAN def_bool y +config CPU_BIG_ENDIAN + def_bool y + config ARCH_ATU bool default y if SPARC64 diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug index 6db35fba79fd..4aef29a11925 100644 --- a/arch/sparc/Kconfig.debug +++ b/arch/sparc/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 8496a074bd0e..dbc448923f48 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # sparc/Makefile # diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index 6a4ceae5ec67..ec8cd703b708 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Sparc boot stuff. # # Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index ca8609d7292f..4d4e1cc6402f 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -238,3 +238,4 @@ CONFIG_CRYPTO_TWOFISH=m # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRC16=m CONFIG_LIBCRC32C=m +CONFIG_VCC=m diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index 5d469d81761f..818d3aa5172e 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # diff --git a/arch/sparc/crypto/aes_asm.S b/arch/sparc/crypto/aes_asm.S index 1cda8aa7cb85..155cefb98520 100644 --- a/arch/sparc/crypto/aes_asm.S +++ b/arch/sparc/crypto/aes_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/crypto/aes_glue.c b/arch/sparc/crypto/aes_glue.c index c90930de76ba..3cd4f6b198b6 100644 --- a/arch/sparc/crypto/aes_glue.c +++ b/arch/sparc/crypto/aes_glue.c @@ -344,8 +344,7 @@ static void ctr_crypt_final(struct crypto_sparc64_aes_ctx *ctx, ctx->ops->ecb_encrypt(&ctx->key[0], (const u64 *)ctrblk, keystream, AES_BLOCK_SIZE); - crypto_xor((u8 *) keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, (u8 *) keystream, src, nbytes); crypto_inc(ctrblk, AES_BLOCK_SIZE); } diff --git a/arch/sparc/crypto/camellia_asm.S b/arch/sparc/crypto/camellia_asm.S index cc39553a4e43..dcdc9193fcd7 100644 --- a/arch/sparc/crypto/camellia_asm.S +++ b/arch/sparc/crypto/camellia_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/crypto/crc32c_asm.S b/arch/sparc/crypto/crc32c_asm.S index 2b1976e765b5..b8659a479242 100644 --- a/arch/sparc/crypto/crc32c_asm.S +++ b/arch/sparc/crypto/crc32c_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/sparc/crypto/crop_devid.c b/arch/sparc/crypto/crop_devid.c index 5f5724a0ae22..83fc4536dcd5 100644 --- a/arch/sparc/crypto/crop_devid.c +++ b/arch/sparc/crypto/crop_devid.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/sparc/crypto/des_asm.S b/arch/sparc/crypto/des_asm.S index b5c8fc269b5f..7157468a679d 100644 --- a/arch/sparc/crypto/des_asm.S +++ b/arch/sparc/crypto/des_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/crypto/md5_asm.S b/arch/sparc/crypto/md5_asm.S index 3150404e602e..7a6637455f37 100644 --- a/arch/sparc/crypto/md5_asm.S +++ b/arch/sparc/crypto/md5_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/crypto/opcodes.h b/arch/sparc/crypto/opcodes.h index 19cbaea6976f..417b6a10a337 100644 --- a/arch/sparc/crypto/opcodes.h +++ b/arch/sparc/crypto/opcodes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _OPCODES_H #define _OPCODES_H diff --git a/arch/sparc/crypto/sha1_asm.S b/arch/sparc/crypto/sha1_asm.S index 219d10c5ae0e..7d8bf354f0e7 100644 --- a/arch/sparc/crypto/sha1_asm.S +++ b/arch/sparc/crypto/sha1_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/crypto/sha256_asm.S b/arch/sparc/crypto/sha256_asm.S index b5f3d5826eb4..0b39ec7d7ca2 100644 --- a/arch/sparc/crypto/sha256_asm.S +++ b/arch/sparc/crypto/sha256_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/crypto/sha512_asm.S b/arch/sparc/crypto/sha512_asm.S index 54bfba713c0e..b2f6e6728802 100644 --- a/arch/sparc/crypto/sha512_asm.S +++ b/arch/sparc/crypto/sha512_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/include/asm/agp.h b/arch/sparc/include/asm/agp.h index 70f52c1661bc..efe0d6a12e5a 100644 --- a/arch/sparc/include/asm/agp.h +++ b/arch/sparc/include/asm/agp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef AGP_H #define AGP_H 1 diff --git a/arch/sparc/include/asm/apb.h b/arch/sparc/include/asm/apb.h index 8f3b57db810f..b1dfb1a99f07 100644 --- a/arch/sparc/include/asm/apb.h +++ b/arch/sparc/include/asm/apb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * apb.h: Advanced PCI Bridge Configuration Registers and Bits * diff --git a/arch/sparc/include/asm/asm-prototypes.h b/arch/sparc/include/asm/asm-prototypes.h index d381e11c5dbb..96e0972e8dbf 100644 --- a/arch/sparc/include/asm/asm-prototypes.h +++ b/arch/sparc/include/asm/asm-prototypes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved. */ diff --git a/arch/sparc/include/asm/asm.h b/arch/sparc/include/asm/asm.h index e8e1d94b4cc9..eaed0117a838 100644 --- a/arch/sparc/include/asm/asm.h +++ b/arch/sparc/include/asm/asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_ASM_H #define _SPARC_ASM_H diff --git a/arch/sparc/include/asm/asmmacro.h b/arch/sparc/include/asm/asmmacro.h index a0e28ef02558..49aaf6f3bc55 100644 --- a/arch/sparc/include/asm/asmmacro.h +++ b/arch/sparc/include/asm/asmmacro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* asmmacro.h: Assembler macros. * * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) diff --git a/arch/sparc/include/asm/atomic.h b/arch/sparc/include/asm/atomic.h index 8ff83d8cc33f..425151cc4808 100644 --- a/arch/sparc/include/asm/atomic.h +++ b/arch/sparc/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_ATOMIC_H #define ___ASM_SPARC_ATOMIC_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h index ee3f11c43cda..0c3b3b4a9963 100644 --- a/arch/sparc/include/asm/atomic_32.h +++ b/arch/sparc/include/asm/atomic_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* atomic.h: These still suck, but the I-cache hit rate is higher. * * Copyright (C) 1996 David S. Miller (davem@davemloft.net) @@ -29,6 +30,8 @@ int atomic_xchg(atomic_t *, int); int __atomic_add_unless(atomic_t *, int, int); void atomic_set(atomic_t *, int); +#define atomic_set_release(v, i) atomic_set((v), (i)) + #define atomic_read(v) ACCESS_ONCE((v)->counter) #define atomic_add(i, v) ((void)atomic_add_return( (int)(i), (v))) diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index 24827a3f733a..abad97edf736 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* atomic.h: Thankfully the V9 is at least reasonable for this * stuff. * diff --git a/arch/sparc/include/asm/auxio.h b/arch/sparc/include/asm/auxio.h index 3e09a07b77e9..a2681052e900 100644 --- a/arch/sparc/include/asm/auxio.h +++ b/arch/sparc/include/asm/auxio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_AUXIO_H #define ___ASM_SPARC_AUXIO_H diff --git a/arch/sparc/include/asm/auxio_32.h b/arch/sparc/include/asm/auxio_32.h index 5d685df427b4..852457c7a265 100644 --- a/arch/sparc/include/asm/auxio_32.h +++ b/arch/sparc/include/asm/auxio_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * auxio.h: Definitions and code for the Auxiliary I/O register. * diff --git a/arch/sparc/include/asm/auxio_64.h b/arch/sparc/include/asm/auxio_64.h index 6079e59a7ad1..ae1ed41987db 100644 --- a/arch/sparc/include/asm/auxio_64.h +++ b/arch/sparc/include/asm/auxio_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * auxio.h: Definitions and code for the Auxiliary I/O registers. * diff --git a/arch/sparc/include/asm/backoff.h b/arch/sparc/include/asm/backoff.h index 4e02086b839c..8625946d8d00 100644 --- a/arch/sparc/include/asm/backoff.h +++ b/arch/sparc/include/asm/backoff.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_BACKOFF_H #define _SPARC64_BACKOFF_H diff --git a/arch/sparc/include/asm/barrier.h b/arch/sparc/include/asm/barrier.h index b25f02a029e0..c10b4164be59 100644 --- a/arch/sparc/include/asm/barrier.h +++ b/arch/sparc/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_BARRIER_H #define ___ASM_SPARC_BARRIER_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/barrier_32.h b/arch/sparc/include/asm/barrier_32.h index 8059130a6cee..304f9c3f7c4a 100644 --- a/arch/sparc/include/asm/barrier_32.h +++ b/arch/sparc/include/asm/barrier_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_BARRIER_H #define __SPARC_BARRIER_H diff --git a/arch/sparc/include/asm/barrier_64.h b/arch/sparc/include/asm/barrier_64.h index c9f6ee64f41d..9fb148bd3c97 100644 --- a/arch/sparc/include/asm/barrier_64.h +++ b/arch/sparc/include/asm/barrier_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC64_BARRIER_H #define __SPARC64_BARRIER_H diff --git a/arch/sparc/include/asm/bbc.h b/arch/sparc/include/asm/bbc.h index 423a85800aae..00a4f116144d 100644 --- a/arch/sparc/include/asm/bbc.h +++ b/arch/sparc/include/asm/bbc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * bbc.h: Defines for BootBus Controller found on UltraSPARC-III * systems. diff --git a/arch/sparc/include/asm/bitext.h b/arch/sparc/include/asm/bitext.h index 9c988bf3adb6..2c2a2d85e8ec 100644 --- a/arch/sparc/include/asm/bitext.h +++ b/arch/sparc/include/asm/bitext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * bitext.h: Bit string operations on the sparc, specific to architecture. * diff --git a/arch/sparc/include/asm/bitops.h b/arch/sparc/include/asm/bitops.h index b1edd94bd64f..4c431d274926 100644 --- a/arch/sparc/include/asm/bitops.h +++ b/arch/sparc/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_BITOPS_H #define ___ASM_SPARC_BITOPS_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/bitops_32.h b/arch/sparc/include/asm/bitops_32.h index 600ed1d9c8c8..0ceff3b915a8 100644 --- a/arch/sparc/include/asm/bitops_32.h +++ b/arch/sparc/include/asm/bitops_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * bitops.h: Bit string operations on the Sparc. * diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h index 2d522402a937..a90eea24b286 100644 --- a/arch/sparc/include/asm/bitops_64.h +++ b/arch/sparc/include/asm/bitops_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * bitops.h: Bit string operations on the V9. * diff --git a/arch/sparc/include/asm/btext.h b/arch/sparc/include/asm/btext.h index 75a32b109e15..01cdc4265733 100644 --- a/arch/sparc/include/asm/btext.h +++ b/arch/sparc/include/asm/btext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_BTEXT_H #define _SPARC_BTEXT_H diff --git a/arch/sparc/include/asm/bug.h b/arch/sparc/include/asm/bug.h index eaa8f8d38125..6f17528356b2 100644 --- a/arch/sparc/include/asm/bug.h +++ b/arch/sparc/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_BUG_H #define _SPARC_BUG_H diff --git a/arch/sparc/include/asm/bugs.h b/arch/sparc/include/asm/bugs.h index 61d86bbbe2b2..02fa369b9c21 100644 --- a/arch/sparc/include/asm/bugs.h +++ b/arch/sparc/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* include/asm/bugs.h: Sparc probes for various bugs. * * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h index 5bb6991b4857..dcfd58118c11 100644 --- a/arch/sparc/include/asm/cache.h +++ b/arch/sparc/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* cache.h: Cache specific code for the Sparc. These include flushing * and direct tag/data line access. * diff --git a/arch/sparc/include/asm/cacheflush.h b/arch/sparc/include/asm/cacheflush.h index f6c4839b8388..881ac76eab93 100644 --- a/arch/sparc/include/asm/cacheflush.h +++ b/arch/sparc/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_CACHEFLUSH_H #define ___ASM_SPARC_CACHEFLUSH_H diff --git a/arch/sparc/include/asm/cacheflush_32.h b/arch/sparc/include/asm/cacheflush_32.h index 12164006181c..fb66094a2c30 100644 --- a/arch/sparc/include/asm/cacheflush_32.h +++ b/arch/sparc/include/asm/cacheflush_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_CACHEFLUSH_H #define _SPARC_CACHEFLUSH_H diff --git a/arch/sparc/include/asm/cacheflush_64.h b/arch/sparc/include/asm/cacheflush_64.h index 68513c41e10d..e7517434d1fa 100644 --- a/arch/sparc/include/asm/cacheflush_64.h +++ b/arch/sparc/include/asm/cacheflush_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_CACHEFLUSH_H #define _SPARC64_CACHEFLUSH_H diff --git a/arch/sparc/include/asm/cachetlb_32.h b/arch/sparc/include/asm/cachetlb_32.h index efb19889a083..534da70c6357 100644 --- a/arch/sparc/include/asm/cachetlb_32.h +++ b/arch/sparc/include/asm/cachetlb_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_CACHETLB_H #define _SPARC_CACHETLB_H diff --git a/arch/sparc/include/asm/chafsr.h b/arch/sparc/include/asm/chafsr.h index 85c69b38220b..01540eca1671 100644 --- a/arch/sparc/include/asm/chafsr.h +++ b/arch/sparc/include/asm/chafsr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_CHAFSR_H #define _SPARC64_CHAFSR_H diff --git a/arch/sparc/include/asm/checksum.h b/arch/sparc/include/asm/checksum.h index 7ac0d7497bc5..c3be56e2e768 100644 --- a/arch/sparc/include/asm/checksum.h +++ b/arch/sparc/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_CHECKSUM_H #define ___ASM_SPARC_CHECKSUM_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/checksum_32.h b/arch/sparc/include/asm/checksum_32.h index e25af5fc99fd..d1e53d7aed39 100644 --- a/arch/sparc/include/asm/checksum_32.h +++ b/arch/sparc/include/asm/checksum_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_CHECKSUM_H #define __SPARC_CHECKSUM_H diff --git a/arch/sparc/include/asm/checksum_64.h b/arch/sparc/include/asm/checksum_64.h index 96a5ed58cea6..e52450930e4e 100644 --- a/arch/sparc/include/asm/checksum_64.h +++ b/arch/sparc/include/asm/checksum_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC64_CHECKSUM_H #define __SPARC64_CHECKSUM_H diff --git a/arch/sparc/include/asm/chmctrl.h b/arch/sparc/include/asm/chmctrl.h index 859b4a4b0d30..96f043cb2c3e 100644 --- a/arch/sparc/include/asm/chmctrl.h +++ b/arch/sparc/include/asm/chmctrl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_CHMCTRL_H #define _SPARC64_CHMCTRL_H diff --git a/arch/sparc/include/asm/cmpxchg.h b/arch/sparc/include/asm/cmpxchg.h index 9355893efa52..b7955c6b91fc 100644 --- a/arch/sparc/include/asm/cmpxchg.h +++ b/arch/sparc/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_CMPXCHG_H #define ___ASM_SPARC_CMPXCHG_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/cmpxchg_32.h b/arch/sparc/include/asm/cmpxchg_32.h index 83ffb83c5397..3e3823db303e 100644 --- a/arch/sparc/include/asm/cmpxchg_32.h +++ b/arch/sparc/include/asm/cmpxchg_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* 32-bit atomic xchg() and cmpxchg() definitions. * * Copyright (C) 1996 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/cmpxchg_64.h b/arch/sparc/include/asm/cmpxchg_64.h index 4028f4f1e561..f71ef3729888 100644 --- a/arch/sparc/include/asm/cmpxchg_64.h +++ b/arch/sparc/include/asm/cmpxchg_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* 64-bit atomic xchg() and cmpxchg() definitions. * * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index 6f251c4d613e..977c3f280ba1 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC64_COMPAT_H #define _ASM_SPARC64_COMPAT_H /* diff --git a/arch/sparc/include/asm/compat_signal.h b/arch/sparc/include/asm/compat_signal.h index 4b027b1044fa..e5f7a7f281d2 100644 --- a/arch/sparc/include/asm/compat_signal.h +++ b/arch/sparc/include/asm/compat_signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _COMPAT_SIGNAL_H #define _COMPAT_SIGNAL_H diff --git a/arch/sparc/include/asm/contregs.h b/arch/sparc/include/asm/contregs.h index b8abdfcf5555..4df56a6ba7d9 100644 --- a/arch/sparc/include/asm/contregs.h +++ b/arch/sparc/include/asm/contregs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_CONTREGS_H #define _SPARC_CONTREGS_H diff --git a/arch/sparc/include/asm/cpu_type.h b/arch/sparc/include/asm/cpu_type.h index 84d7d83b8084..2b59799859d1 100644 --- a/arch/sparc/include/asm/cpu_type.h +++ b/arch/sparc/include/asm/cpu_type.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_CPU_TYPE_H #define __ASM_CPU_TYPE_H diff --git a/arch/sparc/include/asm/cpudata.h b/arch/sparc/include/asm/cpudata.h index 128b56b08676..d213165ee713 100644 --- a/arch/sparc/include/asm/cpudata.h +++ b/arch/sparc/include/asm/cpudata.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_CPUDATA_H #define ___ASM_SPARC_CPUDATA_H diff --git a/arch/sparc/include/asm/cpudata_32.h b/arch/sparc/include/asm/cpudata_32.h index 05f366379f53..895d0964b802 100644 --- a/arch/sparc/include/asm/cpudata_32.h +++ b/arch/sparc/include/asm/cpudata_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* cpudata.h: Per-cpu parameters. * * Copyright (C) 2004 Keith M Wesolowski (wesolows@foobazco.org) diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h index 5b0ed48e5b0c..666d6b5c0440 100644 --- a/arch/sparc/include/asm/cpudata_64.h +++ b/arch/sparc/include/asm/cpudata_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* cpudata.h: Per-cpu parameters. * * Copyright (C) 2003, 2005, 2006 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/current.h b/arch/sparc/include/asm/current.h index 10a0df55a574..c68312a89d14 100644 --- a/arch/sparc/include/asm/current.h +++ b/arch/sparc/include/asm/current.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* include/asm/current.h * * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation diff --git a/arch/sparc/include/asm/dcr.h b/arch/sparc/include/asm/dcr.h index 620c9ba642e9..c810e1b4285c 100644 --- a/arch/sparc/include/asm/dcr.h +++ b/arch/sparc/include/asm/dcr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_DCR_H #define _SPARC64_DCR_H diff --git a/arch/sparc/include/asm/dcu.h b/arch/sparc/include/asm/dcu.h index 0f704e106a1b..93f32507125e 100644 --- a/arch/sparc/include/asm/dcu.h +++ b/arch/sparc/include/asm/dcu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_DCU_H #define _SPARC64_DCU_H diff --git a/arch/sparc/include/asm/delay.h b/arch/sparc/include/asm/delay.h index 467caa2a97a0..c96af9b91661 100644 --- a/arch/sparc/include/asm/delay.h +++ b/arch/sparc/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_DELAY_H #define ___ASM_SPARC_DELAY_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/delay_32.h b/arch/sparc/include/asm/delay_32.h index 3fb8ca144b4f..0e6dfe857d67 100644 --- a/arch/sparc/include/asm/delay_32.h +++ b/arch/sparc/include/asm/delay_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * delay.h: Linux delay routines on the Sparc. * diff --git a/arch/sparc/include/asm/delay_64.h b/arch/sparc/include/asm/delay_64.h index 0ba5424856d8..22213b1c119d 100644 --- a/arch/sparc/include/asm/delay_64.h +++ b/arch/sparc/include/asm/delay_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* delay.h: Linux delay routines on sparc64. * * Copyright (C) 1996, 2004, 2007 David S. Miller (davem@davemloft.net). diff --git a/arch/sparc/include/asm/dma-mapping.h b/arch/sparc/include/asm/dma-mapping.h index 60bf1633d554..2f3490dd37de 100644 --- a/arch/sparc/include/asm/dma-mapping.h +++ b/arch/sparc/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_DMA_MAPPING_H #define ___ASM_SPARC_DMA_MAPPING_H diff --git a/arch/sparc/include/asm/dma.h b/arch/sparc/include/asm/dma.h index 3d434ef5eae3..a1d7c86917c6 100644 --- a/arch/sparc/include/asm/dma.h +++ b/arch/sparc/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC_DMA_H #define _ASM_SPARC_DMA_H diff --git a/arch/sparc/include/asm/ebus_dma.h b/arch/sparc/include/asm/ebus_dma.h index fcfb4948147f..75563ed090f5 100644 --- a/arch/sparc/include/asm/ebus_dma.h +++ b/arch/sparc/include/asm/ebus_dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPARC_EBUS_DMA_H #define __ASM_SPARC_EBUS_DMA_H diff --git a/arch/sparc/include/asm/ecc.h b/arch/sparc/include/asm/ecc.h index ccb84b66fef1..3d5edee36b4c 100644 --- a/arch/sparc/include/asm/ecc.h +++ b/arch/sparc/include/asm/ecc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ecc.h: Definitions and defines for the external cache/memory * controller on the sun4m. diff --git a/arch/sparc/include/asm/elf.h b/arch/sparc/include/asm/elf.h index 0a2816c50b07..bbfb4b002ff3 100644 --- a/arch/sparc/include/asm/elf.h +++ b/arch/sparc/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_ELF_H #define ___ASM_SPARC_ELF_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h index a24e41fcdde1..37a6016c9ccd 100644 --- a/arch/sparc/include/asm/elf_32.h +++ b/arch/sparc/include/asm/elf_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASMSPARC_ELF_H #define __ASMSPARC_ELF_H diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h index 3f2d403873bd..5894389f5ed5 100644 --- a/arch/sparc/include/asm/elf_64.h +++ b/arch/sparc/include/asm/elf_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPARC64_ELF_H #define __ASM_SPARC64_ELF_H diff --git a/arch/sparc/include/asm/estate.h b/arch/sparc/include/asm/estate.h index 520c08560d1b..e5e0f84accea 100644 --- a/arch/sparc/include/asm/estate.h +++ b/arch/sparc/include/asm/estate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_ESTATE_H #define _SPARC64_ESTATE_H diff --git a/arch/sparc/include/asm/extable_64.h b/arch/sparc/include/asm/extable_64.h index 1121cb056ffb..5a0171907b7e 100644 --- a/arch/sparc/include/asm/extable_64.h +++ b/arch/sparc/include/asm/extable_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_EXTABLE64_H #define __ASM_EXTABLE64_H /* diff --git a/arch/sparc/include/asm/fb.h b/arch/sparc/include/asm/fb.h index 2173432ad7f7..f699962e9ddf 100644 --- a/arch/sparc/include/asm/fb.h +++ b/arch/sparc/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_FB_H_ #define _SPARC_FB_H_ #include diff --git a/arch/sparc/include/asm/fbio.h b/arch/sparc/include/asm/fbio.h index 1d9afe277e9c..02654cb95dec 100644 --- a/arch/sparc/include/asm/fbio.h +++ b/arch/sparc/include/asm/fbio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_FBIO_H #define __LINUX_FBIO_H diff --git a/arch/sparc/include/asm/fhc.h b/arch/sparc/include/asm/fhc.h index 57f1b303ad54..0627fa126540 100644 --- a/arch/sparc/include/asm/fhc.h +++ b/arch/sparc/include/asm/fhc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* fhc.h: FHC and Clock board register definitions. * * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/include/asm/floppy.h b/arch/sparc/include/asm/floppy.h index faebd335b600..4b315802e635 100644 --- a/arch/sparc/include/asm/floppy.h +++ b/arch/sparc/include/asm/floppy.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_FLOPPY_H #define ___ASM_SPARC_FLOPPY_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h index 071b83e52f15..dd63aa301658 100644 --- a/arch/sparc/include/asm/floppy_32.h +++ b/arch/sparc/include/asm/floppy_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* asm/floppy.h: Sparc specific parts of the Floppy driver. * * Copyright (C) 1995 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index 625756406a7e..22fbeab92a4c 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* floppy.h: Sparc specific parts of the Floppy driver. * * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/fpumacro.h b/arch/sparc/include/asm/fpumacro.h index cc463fec806f..bc378df97fa8 100644 --- a/arch/sparc/include/asm/fpumacro.h +++ b/arch/sparc/include/asm/fpumacro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* fpumacro.h: FPU related macros. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/include/asm/ftrace.h b/arch/sparc/include/asm/ftrace.h index 62755a339a59..d3aa1a524431 100644 --- a/arch/sparc/include/asm/ftrace.h +++ b/arch/sparc/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC64_FTRACE #define _ASM_SPARC64_FTRACE diff --git a/arch/sparc/include/asm/futex.h b/arch/sparc/include/asm/futex.h index 736335f36713..75a13a20cc64 100644 --- a/arch/sparc/include/asm/futex.h +++ b/arch/sparc/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_FUTEX_H #define ___ASM_SPARC_FUTEX_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h index 4e899b0dabf7..0865ce77ec00 100644 --- a/arch/sparc/include/asm/futex_64.h +++ b/arch/sparc/include/asm/futex_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_FUTEX_H #define _SPARC64_FUTEX_H @@ -29,22 +30,14 @@ : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \ : "memory") -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tem; - if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))) - return -EFAULT; if (unlikely((((unsigned long) uaddr) & 0x3UL))) return -EINVAL; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - pagefault_disable(); switch (op) { @@ -69,17 +62,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/sparc/include/asm/hardirq.h b/arch/sparc/include/asm/hardirq.h index 44d4e2345148..a185f6647348 100644 --- a/arch/sparc/include/asm/hardirq.h +++ b/arch/sparc/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_HARDIRQ_H #define ___ASM_SPARC_HARDIRQ_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/hardirq_32.h b/arch/sparc/include/asm/hardirq_32.h index ee93923b7f82..9830d8731a09 100644 --- a/arch/sparc/include/asm/hardirq_32.h +++ b/arch/sparc/include/asm/hardirq_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* hardirq.h: 32-bit Sparc hard IRQ support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/include/asm/hardirq_64.h b/arch/sparc/include/asm/hardirq_64.h index f478ff1ddd02..f56540271993 100644 --- a/arch/sparc/include/asm/hardirq_64.h +++ b/arch/sparc/include/asm/hardirq_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* hardirq.h: 64-bit Sparc hard IRQ support. * * Copyright (C) 1997, 1998, 2005 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/head.h b/arch/sparc/include/asm/head.h index be8f03f3e731..25299b701df5 100644 --- a/arch/sparc/include/asm/head.h +++ b/arch/sparc/include/asm/head.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_HEAD_H #define ___ASM_SPARC_HEAD_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/head_32.h b/arch/sparc/include/asm/head_32.h index 6fc60fd182c4..d2809c859d0c 100644 --- a/arch/sparc/include/asm/head_32.h +++ b/arch/sparc/include/asm/head_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_HEAD_H #define __SPARC_HEAD_H diff --git a/arch/sparc/include/asm/head_64.h b/arch/sparc/include/asm/head_64.h index f0700cfeedd7..69a2062d992c 100644 --- a/arch/sparc/include/asm/head_64.h +++ b/arch/sparc/include/asm/head_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_HEAD_H #define _SPARC64_HEAD_H diff --git a/arch/sparc/include/asm/hibernate.h b/arch/sparc/include/asm/hibernate.h index 2ec34f842249..3bb0a96ec4ef 100644 --- a/arch/sparc/include/asm/hibernate.h +++ b/arch/sparc/include/asm/hibernate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * hibernate.h: Hibernaton support specific for sparc64. * diff --git a/arch/sparc/include/asm/highmem.h b/arch/sparc/include/asm/highmem.h index 92ded294a4ec..18d776925c45 100644 --- a/arch/sparc/include/asm/highmem.h +++ b/arch/sparc/include/asm/highmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * highmem.h: virtual kernel memory mappings for high memory * diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h index d1f837dc77a4..300557c66698 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h @@ -1,9 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC64_HUGETLB_H #define _ASM_SPARC64_HUGETLB_H #include #include +#ifdef CONFIG_HUGETLB_PAGE +struct pud_huge_patch_entry { + unsigned int addr; + unsigned int insn; +}; +extern struct pud_huge_patch_entry __pud_huge_patch, __pud_huge_patch_end; +#endif void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); diff --git a/arch/sparc/include/asm/hvtramp.h b/arch/sparc/include/asm/hvtramp.h index 04b56f862bbe..688ea43af0f5 100644 --- a/arch/sparc/include/asm/hvtramp.h +++ b/arch/sparc/include/asm/hvtramp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_HVTRAP_H #define _SPARC64_HVTRAP_H diff --git a/arch/sparc/include/asm/hypervisor.h b/arch/sparc/include/asm/hypervisor.h index 73cb8978df58..89a0c57aed59 100644 --- a/arch/sparc/include/asm/hypervisor.h +++ b/arch/sparc/include/asm/hypervisor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_HYPERVISOR_H #define _SPARC64_HYPERVISOR_H @@ -298,6 +299,24 @@ unsigned long sun4v_cpu_stop(unsigned long cpuid); unsigned long sun4v_cpu_yield(void); #endif +/* cpu_poke() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_CPU_POKE + * RET0: status + * ERRORS: ENOCPU cpuid refers to a CPU that does not exist + * EINVAL cpuid is current CPU + * + * Poke CPU cpuid. If the target CPU is currently suspended having + * invoked the cpu-yield service, that vCPU will be resumed. + * Poke interrupts may only be sent to valid, non-local CPUs. + * It is not legal to poke the current vCPU. + */ +#define HV_FAST_CPU_POKE 0x13 + +#ifndef __ASSEMBLY__ +unsigned long sun4v_cpu_poke(unsigned long cpuid); +#endif + /* cpu_qconf() * TRAP: HV_FAST_TRAP * FUNCTION: HV_FAST_CPU_QCONF diff --git a/arch/sparc/include/asm/ide.h b/arch/sparc/include/asm/ide.h index b7af3d658239..09f026585550 100644 --- a/arch/sparc/include/asm/ide.h +++ b/arch/sparc/include/asm/ide.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ide.h: SPARC PCI specific IDE glue. * * Copyright (C) 1997 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/idprom.h b/arch/sparc/include/asm/idprom.h index 3793f7f91c42..4c372199cd70 100644 --- a/arch/sparc/include/asm/idprom.h +++ b/arch/sparc/include/asm/idprom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * idprom.h: Macros and defines for idprom routines * diff --git a/arch/sparc/include/asm/intr_queue.h b/arch/sparc/include/asm/intr_queue.h index 206077dedc2a..d61be2a3aac1 100644 --- a/arch/sparc/include/asm/intr_queue.h +++ b/arch/sparc/include/asm/intr_queue.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_INTR_QUEUE_H #define _SPARC64_INTR_QUEUE_H diff --git a/arch/sparc/include/asm/io-unit.h b/arch/sparc/include/asm/io-unit.h index 04a9701e7202..3ce96e8c088f 100644 --- a/arch/sparc/include/asm/io-unit.h +++ b/arch/sparc/include/asm/io-unit.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* io-unit.h: Definitions for the sun4d IO-UNIT. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/include/asm/io.h b/arch/sparc/include/asm/io.h index f6902cf3cbe9..2eefa526b38f 100644 --- a/arch/sparc/include/asm/io.h +++ b/arch/sparc/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_IO_H #define ___ASM_SPARC_IO_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h index 4dd268a3a8b0..cd51a89b393c 100644 --- a/arch/sparc/include/asm/io_32.h +++ b/arch/sparc/include/asm/io_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_IO_H #define __SPARC_IO_H diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index c32fa3f752c8..9a1e9cbc7e6d 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC64_IO_H #define __SPARC64_IO_H diff --git a/arch/sparc/include/asm/ioctls.h b/arch/sparc/include/asm/ioctls.h index 77413b7e3a18..c92ac780c39f 100644 --- a/arch/sparc/include/asm/ioctls.h +++ b/arch/sparc/include/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC_IOCTLS_H #define _ASM_SPARC_IOCTLS_H diff --git a/arch/sparc/include/asm/iommu.h b/arch/sparc/include/asm/iommu.h index e650965b4a8d..37935cb34865 100644 --- a/arch/sparc/include/asm/iommu.h +++ b/arch/sparc/include/asm/iommu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_IOMMU_H #define ___ASM_SPARC_IOMMU_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/iommu_32.h b/arch/sparc/include/asm/iommu_32.h index f6c066b52fd6..af51cd5ea3c1 100644 --- a/arch/sparc/include/asm/iommu_32.h +++ b/arch/sparc/include/asm/iommu_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* iommu.h: Definitions for the sun4m IOMMU. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/include/asm/iommu_64.h b/arch/sparc/include/asm/iommu_64.h index f24f356f2503..9ed6b54caa4b 100644 --- a/arch/sparc/include/asm/iommu_64.h +++ b/arch/sparc/include/asm/iommu_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* iommu.h: Definitions for the sun5 IOMMU. * * Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/irq.h b/arch/sparc/include/asm/irq.h index 3b44a6a14074..a2efc274dbb0 100644 --- a/arch/sparc/include/asm/irq.h +++ b/arch/sparc/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_IRQ_H #define ___ASM_SPARC_IRQ_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/irq_32.h b/arch/sparc/include/asm/irq_32.h index eecd3d8442c9..43ec2609b811 100644 --- a/arch/sparc/include/asm/irq_32.h +++ b/arch/sparc/include/asm/irq_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* irq.h: IRQ registers on the Sparc. * * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h index 1d51a11fb261..4d748e93b974 100644 --- a/arch/sparc/include/asm/irq_64.h +++ b/arch/sparc/include/asm/irq_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* irq.h: IRQ registers on the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/irqflags.h b/arch/sparc/include/asm/irqflags.h index 1e138632bd3f..d1bdf6c398d1 100644 --- a/arch/sparc/include/asm/irqflags.h +++ b/arch/sparc/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_IRQFLAGS_H #define ___ASM_SPARC_IRQFLAGS_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/irqflags_32.h b/arch/sparc/include/asm/irqflags_32.h index 71cc284f55c5..7ca3eaf3dace 100644 --- a/arch/sparc/include/asm/irqflags_32.h +++ b/arch/sparc/include/asm/irqflags_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm/irqflags.h * diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h index 23cd27f6beb4..c29ed571ae49 100644 --- a/arch/sparc/include/asm/irqflags_64.h +++ b/arch/sparc/include/asm/irqflags_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm/irqflags.h * diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h index 62d0354d1727..94eb529dcb77 100644 --- a/arch/sparc/include/asm/jump_label.h +++ b/arch/sparc/include/asm/jump_label.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC_JUMP_LABEL_H #define _ASM_SPARC_JUMP_LABEL_H diff --git a/arch/sparc/include/asm/kdebug.h b/arch/sparc/include/asm/kdebug.h index 8d12581ca386..830053f91da1 100644 --- a/arch/sparc/include/asm/kdebug.h +++ b/arch/sparc/include/asm/kdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_KDEBUG_H #define ___ASM_SPARC_KDEBUG_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/kdebug_32.h b/arch/sparc/include/asm/kdebug_32.h index 1d0b240222ef..763d423823bd 100644 --- a/arch/sparc/include/asm/kdebug_32.h +++ b/arch/sparc/include/asm/kdebug_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * kdebug.h: Defines and definitions for debugging the Linux kernel * under various kernel debuggers. diff --git a/arch/sparc/include/asm/kdebug_64.h b/arch/sparc/include/asm/kdebug_64.h index 867286bf7b1a..89428bd4f94b 100644 --- a/arch/sparc/include/asm/kdebug_64.h +++ b/arch/sparc/include/asm/kdebug_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_KDEBUG_H #define _SPARC64_KDEBUG_H diff --git a/arch/sparc/include/asm/kgdb.h b/arch/sparc/include/asm/kgdb.h index a6ad7bf84bac..deabe0279cd9 100644 --- a/arch/sparc/include/asm/kgdb.h +++ b/arch/sparc/include/asm/kgdb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_KGDB_H #define _SPARC_KGDB_H diff --git a/arch/sparc/include/asm/kmap_types.h b/arch/sparc/include/asm/kmap_types.h index aad21745fbb9..55a99b6bd91e 100644 --- a/arch/sparc/include/asm/kmap_types.h +++ b/arch/sparc/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KMAP_TYPES_H #define _ASM_KMAP_TYPES_H diff --git a/arch/sparc/include/asm/kprobes.h b/arch/sparc/include/asm/kprobes.h index 49f8402035d7..3704490b4488 100644 --- a/arch/sparc/include/asm/kprobes.h +++ b/arch/sparc/include/asm/kprobes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_KPROBES_H #define _SPARC64_KPROBES_H diff --git a/arch/sparc/include/asm/ldc.h b/arch/sparc/include/asm/ldc.h index 698738a10414..ca973955ca86 100644 --- a/arch/sparc/include/asm/ldc.h +++ b/arch/sparc/include/asm/ldc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_LDC_H #define _SPARC64_LDC_H diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index 204771cd74a5..c68bb5b76e3d 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com) Gaisler Research * Copyright (C) 2004 Stefan Holst (mail@s-holst.de) Uni-Stuttgart diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h index 24ec48c3ff90..6433a93f5126 100644 --- a/arch/sparc/include/asm/leon_amba.h +++ b/arch/sparc/include/asm/leon_amba.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* *Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com), Gaisler Research *Copyright (C) 2004 Stefan Holst (mail@s-holst.de), Uni-Stuttgart diff --git a/arch/sparc/include/asm/leon_pci.h b/arch/sparc/include/asm/leon_pci.h index 049d067ed8be..484a56e81dcc 100644 --- a/arch/sparc/include/asm/leon_pci.h +++ b/arch/sparc/include/asm/leon_pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * asm/leon_pci.h * diff --git a/arch/sparc/include/asm/lsu.h b/arch/sparc/include/asm/lsu.h index 7190f8de90a0..154ae76c0244 100644 --- a/arch/sparc/include/asm/lsu.h +++ b/arch/sparc/include/asm/lsu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_LSU_H #define _SPARC64_LSU_H diff --git a/arch/sparc/include/asm/machines.h b/arch/sparc/include/asm/machines.h index fd6ddb05d1b7..9f78f70c6f11 100644 --- a/arch/sparc/include/asm/machines.h +++ b/arch/sparc/include/asm/machines.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * machines.h: Defines for taking apart the machine type value in the * idprom and determining the kind of machine we are on. diff --git a/arch/sparc/include/asm/mbus.h b/arch/sparc/include/asm/mbus.h index 14128bcc5821..8b6dbe701b9b 100644 --- a/arch/sparc/include/asm/mbus.h +++ b/arch/sparc/include/asm/mbus.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * mbus.h: Various defines for MBUS modules. * diff --git a/arch/sparc/include/asm/mc146818rtc.h b/arch/sparc/include/asm/mc146818rtc.h index d8e72f37dc4b..07faf754eb71 100644 --- a/arch/sparc/include/asm/mc146818rtc.h +++ b/arch/sparc/include/asm/mc146818rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_MC146818RTC_H #define ___ASM_SPARC_MC146818RTC_H diff --git a/arch/sparc/include/asm/mc146818rtc_32.h b/arch/sparc/include/asm/mc146818rtc_32.h index fa7eac926582..d8fd75da8d49 100644 --- a/arch/sparc/include/asm/mc146818rtc_32.h +++ b/arch/sparc/include/asm/mc146818rtc_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine dependent access functions for RTC registers. */ diff --git a/arch/sparc/include/asm/mc146818rtc_64.h b/arch/sparc/include/asm/mc146818rtc_64.h index 7238d174e0e3..b1708a7e5735 100644 --- a/arch/sparc/include/asm/mc146818rtc_64.h +++ b/arch/sparc/include/asm/mc146818rtc_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine dependent access functions for RTC registers. */ diff --git a/arch/sparc/include/asm/mdesc.h b/arch/sparc/include/asm/mdesc.h index e8a4c413a1c7..ec31a06d04cc 100644 --- a/arch/sparc/include/asm/mdesc.h +++ b/arch/sparc/include/asm/mdesc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_MDESC_H #define _SPARC64_MDESC_H diff --git a/arch/sparc/include/asm/memctrl.h b/arch/sparc/include/asm/memctrl.h index 4065c56af7b6..6790ed608cbc 100644 --- a/arch/sparc/include/asm/memctrl.h +++ b/arch/sparc/include/asm/memctrl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_MEMCTRL_H #define _SPARC_MEMCTRL_H diff --git a/arch/sparc/include/asm/mman.h b/arch/sparc/include/asm/mman.h index 59bb5938d852..7e9472143f9b 100644 --- a/arch/sparc/include/asm/mman.h +++ b/arch/sparc/include/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_MMAN_H__ #define __SPARC_MMAN_H__ diff --git a/arch/sparc/include/asm/mmu.h b/arch/sparc/include/asm/mmu.h index 88fa313887db..286457e589a6 100644 --- a/arch/sparc/include/asm/mmu.h +++ b/arch/sparc/include/asm/mmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_MMU_H #define ___ASM_SPARC_MMU_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/mmu_32.h b/arch/sparc/include/asm/mmu_32.h index 6f056e535cf8..d5b220ca7f40 100644 --- a/arch/sparc/include/asm/mmu_32.h +++ b/arch/sparc/include/asm/mmu_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MMU_H #define __MMU_H diff --git a/arch/sparc/include/asm/mmu_64.h b/arch/sparc/include/asm/mmu_64.h index 83b36a5371ff..5fe64a57b4ba 100644 --- a/arch/sparc/include/asm/mmu_64.h +++ b/arch/sparc/include/asm/mmu_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MMU_H #define __MMU_H diff --git a/arch/sparc/include/asm/mmu_context.h b/arch/sparc/include/asm/mmu_context.h index 5531346c64f9..5e1ea38511f4 100644 --- a/arch/sparc/include/asm/mmu_context.h +++ b/arch/sparc/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_MMU_CONTEXT_H #define ___ASM_SPARC_MMU_CONTEXT_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/mmu_context_32.h b/arch/sparc/include/asm/mmu_context_32.h index 2df2a9be8f6d..7ddcb8badf70 100644 --- a/arch/sparc/include/asm/mmu_context_32.h +++ b/arch/sparc/include/asm/mmu_context_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_MMU_CONTEXT_H #define __SPARC_MMU_CONTEXT_H diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h index 87841d687f8d..e25d25b0a34b 100644 --- a/arch/sparc/include/asm/mmu_context_64.h +++ b/arch/sparc/include/asm/mmu_context_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC64_MMU_CONTEXT_H #define __SPARC64_MMU_CONTEXT_H diff --git a/arch/sparc/include/asm/mmzone.h b/arch/sparc/include/asm/mmzone.h index 99d9b9f577bf..6543fb97a849 100644 --- a/arch/sparc/include/asm/mmzone.h +++ b/arch/sparc/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_MMZONE_H #define _SPARC64_MMZONE_H diff --git a/arch/sparc/include/asm/msi.h b/arch/sparc/include/asm/msi.h index 724ca5667052..3c17c1074431 100644 --- a/arch/sparc/include/asm/msi.h +++ b/arch/sparc/include/asm/msi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * msi.h: Defines specific to the MBus - Sbus - Interface. * diff --git a/arch/sparc/include/asm/mxcc.h b/arch/sparc/include/asm/mxcc.h index c0517bd05bde..3a2561bea4dd 100644 --- a/arch/sparc/include/asm/mxcc.h +++ b/arch/sparc/include/asm/mxcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * mxcc.h: Definitions of the Viking MXCC registers * diff --git a/arch/sparc/include/asm/nmi.h b/arch/sparc/include/asm/nmi.h index 284eac3ffaf2..90ee7863d9fe 100644 --- a/arch/sparc/include/asm/nmi.h +++ b/arch/sparc/include/asm/nmi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __NMI_H #define __NMI_H diff --git a/arch/sparc/include/asm/ns87303.h b/arch/sparc/include/asm/ns87303.h index 6b947ee0f6aa..5401894a6065 100644 --- a/arch/sparc/include/asm/ns87303.h +++ b/arch/sparc/include/asm/ns87303.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ns87303.h: Configuration Register Description for the * National Semiconductor PC87303 (SuperIO). * diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h index 426ad75103fb..1b151f738b00 100644 --- a/arch/sparc/include/asm/obio.h +++ b/arch/sparc/include/asm/obio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * obio.h: Some useful locations in 0xFXXXXXXXX PA obio space on sun4d. * diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index 63374c4413a8..69545b3e5454 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_OPENPROM_H #define __SPARC_OPENPROM_H diff --git a/arch/sparc/include/asm/oplib.h b/arch/sparc/include/asm/oplib.h index 72e04e13a6b4..df49a7700d73 100644 --- a/arch/sparc/include/asm/oplib.h +++ b/arch/sparc/include/asm/oplib.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_OPLIB_H #define ___ASM_SPARC_OPLIB_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 56a09b9d7b1b..d1cf3a27a40d 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * oplib.h: Describes the interface and available routines in the * Linux Prom library. diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index 2e3a4add8591..a67abebd4359 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* oplib.h: Describes the interface and available routines in the * Linux Prom library. * diff --git a/arch/sparc/include/asm/page.h b/arch/sparc/include/asm/page.h index 1be2fdec6268..5e44cdf2a8f2 100644 --- a/arch/sparc/include/asm/page.h +++ b/arch/sparc/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_PAGE_H #define ___ASM_SPARC_PAGE_H diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h index 6249214148c2..b76d59edec8c 100644 --- a/arch/sparc/include/asm/page_32.h +++ b/arch/sparc/include/asm/page_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * page.h: Various defines and such for MMU operations on the Sparc for * the Linux kernel. diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h index 5961b2d8398a..c28379b1b0fc 100644 --- a/arch/sparc/include/asm/page_64.h +++ b/arch/sparc/include/asm/page_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_PAGE_H #define _SPARC64_PAGE_H @@ -17,6 +18,7 @@ #define HPAGE_SHIFT 23 #define REAL_HPAGE_SHIFT 22 +#define HPAGE_16GB_SHIFT 34 #define HPAGE_2GB_SHIFT 31 #define HPAGE_256MB_SHIFT 28 #define HPAGE_64K_SHIFT 16 @@ -28,7 +30,7 @@ #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA #define REAL_HPAGE_PER_HPAGE (_AC(1,UL) << (HPAGE_SHIFT - REAL_HPAGE_SHIFT)) -#define HUGE_MAX_HSTATE 4 +#define HUGE_MAX_HSTATE 5 #endif #ifndef __ASSEMBLY__ diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h index f005ccac91cc..05df5f043053 100644 --- a/arch/sparc/include/asm/parport.h +++ b/arch/sparc/include/asm/parport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* parport.h: sparc64 specific parport initialization and dma. * * Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be) diff --git a/arch/sparc/include/asm/pbm.h b/arch/sparc/include/asm/pbm.h index 458a4916d14d..0c86261721e7 100644 --- a/arch/sparc/include/asm/pbm.h +++ b/arch/sparc/include/asm/pbm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * pbm.h: PCI bus module pseudo driver software state diff --git a/arch/sparc/include/asm/pci.h b/arch/sparc/include/asm/pci.h index 6e14fd179335..cad79a6ce0e4 100644 --- a/arch/sparc/include/asm/pci.h +++ b/arch/sparc/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_PCI_H #define ___ASM_SPARC_PCI_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h index b7c092df3134..fe361d3d180d 100644 --- a/arch/sparc/include/asm/pci_32.h +++ b/arch/sparc/include/asm/pci_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_PCI_H #define __SPARC_PCI_H diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index b957ca5527a3..671274e36cfa 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC64_PCI_H #define __SPARC64_PCI_H diff --git a/arch/sparc/include/asm/pcic.h b/arch/sparc/include/asm/pcic.h index f41706792592..238376b1ffcc 100644 --- a/arch/sparc/include/asm/pcic.h +++ b/arch/sparc/include/asm/pcic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * pcic.h: JavaEngine 1 specific PCI definitions. * diff --git a/arch/sparc/include/asm/pcr.h b/arch/sparc/include/asm/pcr.h index cdf800c3326c..da834ffbe75d 100644 --- a/arch/sparc/include/asm/pcr.h +++ b/arch/sparc/include/asm/pcr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PCR_H #define __PCR_H diff --git a/arch/sparc/include/asm/percpu.h b/arch/sparc/include/asm/percpu.h index bfb1d19ff1bf..0cd704ef5ff9 100644 --- a/arch/sparc/include/asm/percpu.h +++ b/arch/sparc/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_PERCPU_H #define ___ASM_SPARC_PERCPU_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/percpu_32.h b/arch/sparc/include/asm/percpu_32.h index 06066a7aaec3..ee6c7c1934f6 100644 --- a/arch/sparc/include/asm/percpu_32.h +++ b/arch/sparc/include/asm/percpu_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_SPARC_PERCPU__ #define __ARCH_SPARC_PERCPU__ diff --git a/arch/sparc/include/asm/percpu_64.h b/arch/sparc/include/asm/percpu_64.h index 007aafb4ae97..32ef6f05cc56 100644 --- a/arch/sparc/include/asm/percpu_64.h +++ b/arch/sparc/include/asm/percpu_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ARCH_SPARC64_PERCPU__ #define __ARCH_SPARC64_PERCPU__ diff --git a/arch/sparc/include/asm/perf_event.h b/arch/sparc/include/asm/perf_event.h index 4d3dbe3703e9..c2aec0c7f4f5 100644 --- a/arch/sparc/include/asm/perf_event.h +++ b/arch/sparc/include/asm/perf_event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPARC_PERF_EVENT_H #define __ASM_SPARC_PERF_EVENT_H diff --git a/arch/sparc/include/asm/pgalloc.h b/arch/sparc/include/asm/pgalloc.h index b6db1f7cdcab..9ea0b37586c9 100644 --- a/arch/sparc/include/asm/pgalloc.h +++ b/arch/sparc/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_PGALLOC_H #define ___ASM_SPARC_PGALLOC_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h index 0346c7e62452..90459481c6c7 100644 --- a/arch/sparc/include/asm/pgalloc_32.h +++ b/arch/sparc/include/asm/pgalloc_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_PGALLOC_H #define _SPARC_PGALLOC_H diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h index 3529f1378cd8..874632f34f62 100644 --- a/arch/sparc/include/asm/pgalloc_64.h +++ b/arch/sparc/include/asm/pgalloc_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_PGALLOC_H #define _SPARC64_PGALLOC_H diff --git a/arch/sparc/include/asm/pgtable.h b/arch/sparc/include/asm/pgtable.h index 59ba6f620732..e48891170f84 100644 --- a/arch/sparc/include/asm/pgtable.h +++ b/arch/sparc/include/asm/pgtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_PGTABLE_H #define ___ASM_SPARC_PGTABLE_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h index cf190728360b..4eebed6c6781 100644 --- a/arch/sparc/include/asm/pgtable_32.h +++ b/arch/sparc/include/asm/pgtable_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_PGTABLE_H #define _SPARC_PGTABLE_H diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 6fbd931f0570..fd9d9bac7cfa 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * pgtable.h: SpitFire page table operations. * @@ -414,6 +415,11 @@ static inline bool is_hugetlb_pmd(pmd_t pmd) return !!(pmd_val(pmd) & _PAGE_PMD_HUGE); } +static inline bool is_hugetlb_pud(pud_t pud) +{ + return !!(pud_val(pud) & _PAGE_PUD_HUGE); +} + #ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline pmd_t pmd_mkhuge(pmd_t pmd) { @@ -687,6 +693,8 @@ static inline unsigned long pmd_write(pmd_t pmd) return pte_write(pte); } +#define pud_write(pud) pte_write(__pte(pud_val(pud))) + #ifdef CONFIG_TRANSPARENT_HUGEPAGE static inline unsigned long pmd_dirty(pmd_t pmd) { @@ -823,9 +831,18 @@ static inline unsigned long __pmd_page(pmd_t pmd) return ((unsigned long) __va(pfn << PAGE_SHIFT)); } + +static inline unsigned long pud_page_vaddr(pud_t pud) +{ + pte_t pte = __pte(pud_val(pud)); + unsigned long pfn; + + pfn = pte_pfn(pte); + + return ((unsigned long) __va(pfn << PAGE_SHIFT)); +} + #define pmd_page(pmd) virt_to_page((void *)__pmd_page(pmd)) -#define pud_page_vaddr(pud) \ - ((unsigned long) __va(pud_val(pud))) #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) #define pud_present(pud) (pud_val(pud) != 0U) diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h index ae51a111a8c7..32a508897501 100644 --- a/arch/sparc/include/asm/pgtsrmmu.h +++ b/arch/sparc/include/asm/pgtsrmmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * pgtsrmmu.h: SRMMU page table defines and code. * diff --git a/arch/sparc/include/asm/pil.h b/arch/sparc/include/asm/pil.h index 522b43db2ed3..4003c35304bd 100644 --- a/arch/sparc/include/asm/pil.h +++ b/arch/sparc/include/asm/pil.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_PIL_H #define _SPARC64_PIL_H diff --git a/arch/sparc/include/asm/processor.h b/arch/sparc/include/asm/processor.h index 9da9646bf6c6..18295ea625dd 100644 --- a/arch/sparc/include/asm/processor.h +++ b/arch/sparc/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_PROCESSOR_H #define ___ASM_SPARC_PROCESSOR_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index b395e5620c0b..192493c257fa 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* include/asm/processor.h * * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index f04dc5a43062..c7c79fe8d265 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm/processor.h * diff --git a/arch/sparc/include/asm/psr.h b/arch/sparc/include/asm/psr.h index e71eb57945e0..65127ce565ab 100644 --- a/arch/sparc/include/asm/psr.h +++ b/arch/sparc/include/asm/psr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * psr.h: This file holds the macros for masking off various parts of * the processor status register on the Sparc. This is valid diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h index d73428e4333c..6a339a78f4f4 100644 --- a/arch/sparc/include/asm/ptrace.h +++ b/arch/sparc/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_PTRACE_H #define __SPARC_PTRACE_H diff --git a/arch/sparc/include/asm/qrwlock.h b/arch/sparc/include/asm/qrwlock.h index d68a4b102100..c277729152c6 100644 --- a/arch/sparc/include/asm/qrwlock.h +++ b/arch/sparc/include/asm/qrwlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC_QRWLOCK_H #define _ASM_SPARC_QRWLOCK_H diff --git a/arch/sparc/include/asm/qspinlock.h b/arch/sparc/include/asm/qspinlock.h index 5ae9a2802846..48808f3d9dd7 100644 --- a/arch/sparc/include/asm/qspinlock.h +++ b/arch/sparc/include/asm/qspinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC_QSPINLOCK_H #define _ASM_SPARC_QSPINLOCK_H diff --git a/arch/sparc/include/asm/ross.h b/arch/sparc/include/asm/ross.h index ecb6e81786a6..79a54d66a2c0 100644 --- a/arch/sparc/include/asm/ross.h +++ b/arch/sparc/include/asm/ross.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ross.h: Ross module specific definitions and defines. * diff --git a/arch/sparc/include/asm/sbi.h b/arch/sparc/include/asm/sbi.h index 5eb7f1965d33..4d6026c1e446 100644 --- a/arch/sparc/include/asm/sbi.h +++ b/arch/sparc/include/asm/sbi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * sbi.h: SBI (Sbus Interface on sun4d) definitions * diff --git a/arch/sparc/include/asm/scratchpad.h b/arch/sparc/include/asm/scratchpad.h index 5e8b01fb3343..958351190788 100644 --- a/arch/sparc/include/asm/scratchpad.h +++ b/arch/sparc/include/asm/scratchpad.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_SCRATCHPAD_H #define _SPARC64_SCRATCHPAD_H diff --git a/arch/sparc/include/asm/seccomp.h b/arch/sparc/include/asm/seccomp.h index 5ef8826d44f8..62d4579efb1a 100644 --- a/arch/sparc/include/asm/seccomp.h +++ b/arch/sparc/include/asm/seccomp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SECCOMP_H #define _ASM_SECCOMP_H diff --git a/arch/sparc/include/asm/sections.h b/arch/sparc/include/asm/sections.h index f300d1a9b2b6..08f833453ab3 100644 --- a/arch/sparc/include/asm/sections.h +++ b/arch/sparc/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_SECTIONS_H #define __SPARC_SECTIONS_H diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h index 8b32538084f7..72205684e51e 100644 --- a/arch/sparc/include/asm/setup.h +++ b/arch/sparc/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Just a place holder. */ diff --git a/arch/sparc/include/asm/sfafsr.h b/arch/sparc/include/asm/sfafsr.h index e96137b04a4f..9c98f4fc8839 100644 --- a/arch/sparc/include/asm/sfafsr.h +++ b/arch/sparc/include/asm/sfafsr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_SFAFSR_H #define _SPARC64_SFAFSR_H diff --git a/arch/sparc/include/asm/sfp-machine.h b/arch/sparc/include/asm/sfp-machine.h index 4ebc3823ed4f..4a247b40573c 100644 --- a/arch/sparc/include/asm/sfp-machine.h +++ b/arch/sparc/include/asm/sfp-machine.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_SFP_MACHINE_H #define ___ASM_SPARC_SFP_MACHINE_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/shmparam.h b/arch/sparc/include/asm/shmparam.h index 8bf0cfe0694f..951a4525fa4b 100644 --- a/arch/sparc/include/asm/shmparam.h +++ b/arch/sparc/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_SHMPARAM_H #define ___ASM_SPARC_SHMPARAM_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/shmparam_32.h b/arch/sparc/include/asm/shmparam_32.h index 142825c8d3ac..9767a8b30242 100644 --- a/arch/sparc/include/asm/shmparam_32.h +++ b/arch/sparc/include/asm/shmparam_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMSPARC_SHMPARAM_H #define _ASMSPARC_SHMPARAM_H diff --git a/arch/sparc/include/asm/shmparam_64.h b/arch/sparc/include/asm/shmparam_64.h index 1ed0d6701a9b..c0731b57124c 100644 --- a/arch/sparc/include/asm/shmparam_64.h +++ b/arch/sparc/include/asm/shmparam_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASMSPARC64_SHMPARAM_H #define _ASMSPARC64_SHMPARAM_H diff --git a/arch/sparc/include/asm/sigcontext.h b/arch/sparc/include/asm/sigcontext.h index f4eb630a58ed..ee05f9d2bcf2 100644 --- a/arch/sparc/include/asm/sigcontext.h +++ b/arch/sparc/include/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_SIGCONTEXT_H #define __SPARC_SIGCONTEXT_H diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h index c33ce3f2ba84..827b73a97f8a 100644 --- a/arch/sparc/include/asm/signal.h +++ b/arch/sparc/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_SIGNAL_H #define __SPARC_SIGNAL_H diff --git a/arch/sparc/include/asm/smp.h b/arch/sparc/include/asm/smp.h index b59672d0e19b..dea59f6ce79f 100644 --- a/arch/sparc/include/asm/smp.h +++ b/arch/sparc/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_SMP_H #define ___ASM_SPARC_SMP_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h index 7c24e08a88d2..856081761b0f 100644 --- a/arch/sparc/include/asm/smp_32.h +++ b/arch/sparc/include/asm/smp_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* smp.h: Sparc specific SMP stuff. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index ce2233f7e662..e75783b6abc4 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* smp.h: Sparc64 specific SMP stuff. * * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net) @@ -33,6 +34,9 @@ DECLARE_PER_CPU(cpumask_t, cpu_sibling_map); extern cpumask_t cpu_core_map[NR_CPUS]; +void smp_init_cpu_poke(void); +void scheduler_poke(void); + void arch_send_call_function_single_ipi(int cpu); void arch_send_call_function_ipi_mask(const struct cpumask *mask); @@ -74,6 +78,8 @@ void __cpu_die(unsigned int cpu); #define smp_fetch_global_regs() do { } while (0) #define smp_fetch_global_pmu() do { } while (0) #define smp_fill_in_cpu_possible_map() do { } while (0) +#define smp_init_cpu_poke() do { } while (0) +#define scheduler_poke() do { } while (0) #endif /* !(CONFIG_SMP) */ diff --git a/arch/sparc/include/asm/sparsemem.h b/arch/sparc/include/asm/sparsemem.h index e5e1752d5d78..1dd1b61432db 100644 --- a/arch/sparc/include/asm/sparsemem.h +++ b/arch/sparc/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_SPARSEMEM_H #define _SPARC64_SPARSEMEM_H diff --git a/arch/sparc/include/asm/spinlock.h b/arch/sparc/include/asm/spinlock.h index f276b0036b2c..3f4ce55bc4d6 100644 --- a/arch/sparc/include/asm/spinlock.h +++ b/arch/sparc/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_SPINLOCK_H #define ___ASM_SPARC_SPINLOCK_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h index 8011e79f59c9..26f00ac2b470 100644 --- a/arch/sparc/include/asm/spinlock_32.h +++ b/arch/sparc/include/asm/spinlock_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* spinlock.h: 32-bit Sparc spinlock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -14,11 +15,6 @@ #define arch_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0) -static inline void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - smp_cond_load_acquire(&lock->lock, !VAL); -} - static inline void arch_spin_lock(arch_spinlock_t *lock) { __asm__ __volatile__( diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h index f7028f5e1a5a..4822a7e94a30 100644 --- a/arch/sparc/include/asm/spinlock_64.h +++ b/arch/sparc/include/asm/spinlock_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* spinlock.h: 64-bit Sparc spinlock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/include/asm/spinlock_types.h b/arch/sparc/include/asm/spinlock_types.h index bce8ef44dfa9..ed1d569b638e 100644 --- a/arch/sparc/include/asm/spinlock_types.h +++ b/arch/sparc/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_SPINLOCK_TYPES_H #define __SPARC_SPINLOCK_TYPES_H diff --git a/arch/sparc/include/asm/spitfire.h b/arch/sparc/include/asm/spitfire.h index 1b1286d05069..e9b7d25b29fa 100644 --- a/arch/sparc/include/asm/spitfire.h +++ b/arch/sparc/include/asm/spitfire.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations. * * Copyright (C) 1996 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/stacktrace.h b/arch/sparc/include/asm/stacktrace.h index c30d066f3048..556ec5d59c88 100644 --- a/arch/sparc/include/asm/stacktrace.h +++ b/arch/sparc/include/asm/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_STACKTRACE_H #define _SPARC64_STACKTRACE_H diff --git a/arch/sparc/include/asm/starfire.h b/arch/sparc/include/asm/starfire.h index 176fa0ad19f1..fb1a8c499cb0 100644 --- a/arch/sparc/include/asm/starfire.h +++ b/arch/sparc/include/asm/starfire.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * starfire.h: Group all starfire specific code together. * diff --git a/arch/sparc/include/asm/string.h b/arch/sparc/include/asm/string.h index 86f34be14ce0..3d9cd082716b 100644 --- a/arch/sparc/include/asm/string.h +++ b/arch/sparc/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_STRING_H #define ___ASM_SPARC_STRING_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/string_32.h b/arch/sparc/include/asm/string_32.h index 649412476a69..f488946bd7d6 100644 --- a/arch/sparc/include/asm/string_32.h +++ b/arch/sparc/include/asm/string_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * string.h: External definitions for optimized assembly string * routines for the Linux Kernel. diff --git a/arch/sparc/include/asm/string_64.h b/arch/sparc/include/asm/string_64.h index 6b9ccb308605..ee9ba67321bd 100644 --- a/arch/sparc/include/asm/string_64.h +++ b/arch/sparc/include/asm/string_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * string.h: External definitions for optimized assembly string * routines for the Linux Kernel. diff --git a/arch/sparc/include/asm/sunbpp.h b/arch/sparc/include/asm/sunbpp.h index d81a02eaf78b..55de4da70dff 100644 --- a/arch/sparc/include/asm/sunbpp.h +++ b/arch/sparc/include/asm/sunbpp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * include/asm/sunbpp.h */ diff --git a/arch/sparc/include/asm/swift.h b/arch/sparc/include/asm/swift.h index e535061bf755..96f6526b964e 100644 --- a/arch/sparc/include/asm/swift.h +++ b/arch/sparc/include/asm/swift.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* swift.h: Specific definitions for the _broken_ Swift SRMMU * MMU module. * diff --git a/arch/sparc/include/asm/switch_to.h b/arch/sparc/include/asm/switch_to.h index 2dc4fa5c6f8c..7cf1c5dc734c 100644 --- a/arch/sparc/include/asm/switch_to.h +++ b/arch/sparc/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_SWITCH_TO_H #define ___ASM_SPARC_SWITCH_TO_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/switch_to_32.h b/arch/sparc/include/asm/switch_to_32.h index 475dd4158ae4..42eeafcb8a41 100644 --- a/arch/sparc/include/asm/switch_to_32.h +++ b/arch/sparc/include/asm/switch_to_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_SWITCH_TO_H #define __SPARC_SWITCH_TO_H diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h index 10e76332dc99..4ff29b1406a9 100644 --- a/arch/sparc/include/asm/switch_to_64.h +++ b/arch/sparc/include/asm/switch_to_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC64_SWITCH_TO_64_H #define __SPARC64_SWITCH_TO_64_H diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h index 1757cd6c521b..053989e3f6a6 100644 --- a/arch/sparc/include/asm/syscall.h +++ b/arch/sparc/include/asm/syscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_SPARC_SYSCALL_H #define __ASM_SPARC_SYSCALL_H diff --git a/arch/sparc/include/asm/syscalls.h b/arch/sparc/include/asm/syscalls.h index b0a0db8ea61a..1d819f5e21da 100644 --- a/arch/sparc/include/asm/syscalls.h +++ b/arch/sparc/include/asm/syscalls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_SYSCALLS_H #define _SPARC64_SYSCALLS_H diff --git a/arch/sparc/include/asm/termbits.h b/arch/sparc/include/asm/termbits.h index 948067065ac5..fa9de4a46d36 100644 --- a/arch/sparc/include/asm/termbits.h +++ b/arch/sparc/include/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_TERMBITS_H #define _SPARC_TERMBITS_H diff --git a/arch/sparc/include/asm/termios.h b/arch/sparc/include/asm/termios.h index 0c2414ddd52c..4a558efdfa93 100644 --- a/arch/sparc/include/asm/termios.h +++ b/arch/sparc/include/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_TERMIOS_H #define _SPARC_TERMIOS_H diff --git a/arch/sparc/include/asm/thread_info.h b/arch/sparc/include/asm/thread_info.h index 122d7acc07e6..740b1743ed8c 100644 --- a/arch/sparc/include/asm/thread_info.h +++ b/arch/sparc/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_THREAD_INFO_H #define ___ASM_SPARC_THREAD_INFO_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h index 229475f0d7ce..febaaeb1a0fe 100644 --- a/arch/sparc/include/asm/thread_info_32.h +++ b/arch/sparc/include/asm/thread_info_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * thread_info.h: sparc low-level thread information * adapted from the ppc version by Pete Zaitcev, which was diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 38a24f257b85..caf915321ba9 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* thread_info.h: sparc64 low-level thread information * * Copyright (C) 2002 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/include/asm/timer.h b/arch/sparc/include/asm/timer.h index 612fd2779d9e..eaf6195d17e2 100644 --- a/arch/sparc/include/asm/timer.h +++ b/arch/sparc/include/asm/timer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_TIMER_H #define ___ASM_SPARC_TIMER_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/timer_32.h b/arch/sparc/include/asm/timer_32.h index f8e708a0aa58..eecd2696922d 100644 --- a/arch/sparc/include/asm/timer_32.h +++ b/arch/sparc/include/asm/timer_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * timer.h: Definitions for the timer chips on the Sparc. * diff --git a/arch/sparc/include/asm/timer_64.h b/arch/sparc/include/asm/timer_64.h index 51bc3bc54bfe..c7e4fb601a57 100644 --- a/arch/sparc/include/asm/timer_64.h +++ b/arch/sparc/include/asm/timer_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* timer.h: System timer definitions for sun5. * * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/include/asm/timex.h b/arch/sparc/include/asm/timex.h index 70cc37b73827..9aac26b1f45f 100644 --- a/arch/sparc/include/asm/timex.h +++ b/arch/sparc/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_TIMEX_H #define ___ASM_SPARC_TIMEX_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/timex_32.h b/arch/sparc/include/asm/timex_32.h index b6ccdb0d6f7d..542915b46209 100644 --- a/arch/sparc/include/asm/timex_32.h +++ b/arch/sparc/include/asm/timex_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm/timex.h * diff --git a/arch/sparc/include/asm/timex_64.h b/arch/sparc/include/asm/timex_64.h index 18b30bc9823b..076c44f6845d 100644 --- a/arch/sparc/include/asm/timex_64.h +++ b/arch/sparc/include/asm/timex_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm/timex.h * diff --git a/arch/sparc/include/asm/tlb.h b/arch/sparc/include/asm/tlb.h index 92d0393bbcdc..7146a577257f 100644 --- a/arch/sparc/include/asm/tlb.h +++ b/arch/sparc/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_TLB_H #define ___ASM_SPARC_TLB_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/tlb_32.h b/arch/sparc/include/asm/tlb_32.h index 6d02d1ce53f3..343cea19e573 100644 --- a/arch/sparc/include/asm/tlb_32.h +++ b/arch/sparc/include/asm/tlb_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_TLB_H #define _SPARC_TLB_H diff --git a/arch/sparc/include/asm/tlb_64.h b/arch/sparc/include/asm/tlb_64.h index 4cb392f75d2b..a2f3fa61ee36 100644 --- a/arch/sparc/include/asm/tlb_64.h +++ b/arch/sparc/include/asm/tlb_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_TLB_H #define _SPARC64_TLB_H diff --git a/arch/sparc/include/asm/tlbflush.h b/arch/sparc/include/asm/tlbflush.h index 2c9629fad1e2..30ae3ea21054 100644 --- a/arch/sparc/include/asm/tlbflush.h +++ b/arch/sparc/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_TLBFLUSH_H #define ___ASM_SPARC_TLBFLUSH_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/tlbflush_32.h b/arch/sparc/include/asm/tlbflush_32.h index a5c4142130f5..470531991a08 100644 --- a/arch/sparc/include/asm/tlbflush_32.h +++ b/arch/sparc/include/asm/tlbflush_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_TLBFLUSH_H #define _SPARC_TLBFLUSH_H diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h index 54be88a6774c..8b8cdaa69272 100644 --- a/arch/sparc/include/asm/tlbflush_64.h +++ b/arch/sparc/include/asm/tlbflush_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_TLBFLUSH_H #define _SPARC64_TLBFLUSH_H diff --git a/arch/sparc/include/asm/topology.h b/arch/sparc/include/asm/topology.h index ee4f191d394a..ba7b9d9d91cf 100644 --- a/arch/sparc/include/asm/topology.h +++ b/arch/sparc/include/asm/topology.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_TOPOLOGY_H #define ___ASM_SPARC_TOPOLOGY_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/topology_32.h b/arch/sparc/include/asm/topology_32.h index ee5ac9c9da28..66c4f9ff700d 100644 --- a/arch/sparc/include/asm/topology_32.h +++ b/arch/sparc/include/asm/topology_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC_TOPOLOGY_H #define _ASM_SPARC_TOPOLOGY_H diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h index ad5293f89680..3831b1911a19 100644 --- a/arch/sparc/include/asm/topology_64.h +++ b/arch/sparc/include/asm/topology_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC64_TOPOLOGY_H #define _ASM_SPARC64_TOPOLOGY_H diff --git a/arch/sparc/include/asm/trap_block.h b/arch/sparc/include/asm/trap_block.h index ff05992dae7a..6a4c8652ad67 100644 --- a/arch/sparc/include/asm/trap_block.h +++ b/arch/sparc/include/asm/trap_block.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_TRAP_BLOCK_H #define _SPARC_TRAP_BLOCK_H @@ -73,6 +74,8 @@ struct sun4v_1insn_patch_entry { }; extern struct sun4v_1insn_patch_entry __sun4v_1insn_patch, __sun4v_1insn_patch_end; +extern struct sun4v_1insn_patch_entry __fast_win_ctrl_1insn_patch, + __fast_win_ctrl_1insn_patch_end; struct sun4v_2insn_patch_entry { unsigned int addr; diff --git a/arch/sparc/include/asm/traps.h b/arch/sparc/include/asm/traps.h index 51abcb1f9b3b..2fba2602ba69 100644 --- a/arch/sparc/include/asm/traps.h +++ b/arch/sparc/include/asm/traps.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * traps.h: Format of entries for the Sparc trap table. * diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 32258e08da03..25b6abdb3908 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_TSB_H #define _SPARC64_TSB_H @@ -195,6 +196,41 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; nop; \ 699: + /* PUD has been loaded into REG1, interpret the value, seeing + * if it is a HUGE PUD or a normal one. If it is not valid + * then jump to FAIL_LABEL. If it is a HUGE PUD, and it + * translates to a valid PTE, branch to PTE_LABEL. + * + * We have to propagate bits [32:22] from the virtual address + * to resolve at 4M granularity. + */ +#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) +#define USER_PGTABLE_CHECK_PUD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \ +700: ba 700f; \ + nop; \ + .section .pud_huge_patch, "ax"; \ + .word 700b; \ + nop; \ + .previous; \ + brz,pn REG1, FAIL_LABEL; \ + sethi %uhi(_PAGE_PUD_HUGE), REG2; \ + sllx REG2, 32, REG2; \ + andcc REG1, REG2, %g0; \ + be,pt %xcc, 700f; \ + sethi %hi(0x1ffc0000), REG2; \ + sllx REG2, 1, REG2; \ + brgez,pn REG1, FAIL_LABEL; \ + andn REG1, REG2, REG1; \ + and VADDR, REG2, REG2; \ + brlz,pt REG1, PTE_LABEL; \ + or REG1, REG2, REG1; \ +700: +#else +#define USER_PGTABLE_CHECK_PUD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \ + brz,pn REG1, FAIL_LABEL; \ + nop; +#endif + /* PMD has been loaded into REG1, interpret the value, seeing * if it is a HUGE PMD or a normal one. If it is not valid * then jump to FAIL_LABEL. If it is a HUGE PMD, and it @@ -242,6 +278,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; srlx REG2, 64 - PAGE_SHIFT, REG2; \ andn REG2, 0x7, REG2; \ ldxa [REG1 + REG2] ASI_PHYS_USE_EC, REG1; \ + USER_PGTABLE_CHECK_PUD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, 800f) \ brz,pn REG1, FAIL_LABEL; \ sllx VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \ srlx REG2, 64 - PAGE_SHIFT, REG2; \ diff --git a/arch/sparc/include/asm/tsunami.h b/arch/sparc/include/asm/tsunami.h index 5bbd1d523baa..acaf014eff46 100644 --- a/arch/sparc/include/asm/tsunami.h +++ b/arch/sparc/include/asm/tsunami.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * tsunami.h: Module specific definitions for Tsunami V8 Sparcs * diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h index 82e7df296abc..ede2b66cf4a0 100644 --- a/arch/sparc/include/asm/ttable.h +++ b/arch/sparc/include/asm/ttable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_TTABLE_H #define _SPARC64_TTABLE_H diff --git a/arch/sparc/include/asm/turbosparc.h b/arch/sparc/include/asm/turbosparc.h index 17c73282db0a..23df777f9cea 100644 --- a/arch/sparc/include/asm/turbosparc.h +++ b/arch/sparc/include/asm/turbosparc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * turbosparc.h: Defines specific to the TurboSparc module. * This is SRMMU stuff. diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h index 9e068bf9060a..dd85bc2c2cad 100644 --- a/arch/sparc/include/asm/uaccess.h +++ b/arch/sparc/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_UACCESS_H #define ___ASM_SPARC_UACCESS_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h index bdb1447aa1bb..de71c65b99f0 100644 --- a/arch/sparc/include/asm/uaccess_32.h +++ b/arch/sparc/include/asm/uaccess_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * uaccess.h: User space memore access functions. * diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h index 6d4c997d1a9e..cbb308cee394 100644 --- a/arch/sparc/include/asm/uaccess_64.h +++ b/arch/sparc/include/asm/uaccess_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_UACCESS_H #define _ASM_UACCESS_H diff --git a/arch/sparc/include/asm/unaligned.h b/arch/sparc/include/asm/unaligned.h index 11d2d5fb5902..7971d89d2f54 100644 --- a/arch/sparc/include/asm/unaligned.h +++ b/arch/sparc/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_SPARC_UNALIGNED_H #define _ASM_SPARC_UNALIGNED_H diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 0aac1e8f2968..b2a6a955113e 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * System calls under the Sparc. * diff --git a/arch/sparc/include/asm/upa.h b/arch/sparc/include/asm/upa.h index 5b1633223f92..782691b30f54 100644 --- a/arch/sparc/include/asm/upa.h +++ b/arch/sparc/include/asm/upa.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_UPA_H #define _SPARC64_UPA_H diff --git a/arch/sparc/include/asm/vaddrs.h b/arch/sparc/include/asm/vaddrs.h index c3dbcf902034..84d054b07a6f 100644 --- a/arch/sparc/include/asm/vaddrs.h +++ b/arch/sparc/include/asm/vaddrs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC_VADDRS_H #define _SPARC_VADDRS_H diff --git a/arch/sparc/include/asm/vga.h b/arch/sparc/include/asm/vga.h index ec0e9967d93d..2952d667d936 100644 --- a/arch/sparc/include/asm/vga.h +++ b/arch/sparc/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access to VGA videoram * @@ -8,9 +9,13 @@ #define _LINUX_ASM_VGA_H_ #include +#include #include #define VT_BUF_HAVE_RW +#define VT_BUF_HAVE_MEMSETW +#define VT_BUF_HAVE_MEMCPYW +#define VT_BUF_HAVE_MEMMOVEW #undef scr_writew #undef scr_readw @@ -29,6 +34,27 @@ static inline u16 scr_readw(const u16 *addr) return *addr; } +static inline void scr_memsetw(u16 *p, u16 v, unsigned int n) +{ + BUG_ON((long) p >= 0); + + memset16(p, cpu_to_le16(v), n / 2); +} + +static inline void scr_memcpyw(u16 *d, u16 *s, unsigned int n) +{ + BUG_ON((long) d >= 0); + + memcpy(d, s, n); +} + +static inline void scr_memmovew(u16 *d, u16 *s, unsigned int n) +{ + BUG_ON((long) d >= 0); + + memmove(d, s, n); +} + #define VGA_MAP_MEM(x,s) (x) #endif diff --git a/arch/sparc/include/asm/viking.h b/arch/sparc/include/asm/viking.h index 989930aeb093..0bbefd184221 100644 --- a/arch/sparc/include/asm/viking.h +++ b/arch/sparc/include/asm/viking.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * viking.h: Defines specific to the GNU/Viking MBUS module. * This is SRMMU stuff. diff --git a/arch/sparc/include/asm/vio.h b/arch/sparc/include/asm/vio.h index d1c47e9f0090..059f0eb678e0 100644 --- a/arch/sparc/include/asm/vio.h +++ b/arch/sparc/include/asm/vio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_VIO_H #define _SPARC64_VIO_H @@ -52,6 +53,7 @@ struct vio_ver_info { #define VDEV_NETWORK_SWITCH 0x02 #define VDEV_DISK 0x03 #define VDEV_DISK_SERVER 0x04 +#define VDEV_CONSOLE_CON 0x05 u8 resv1[3]; u64 resv2[5]; @@ -282,6 +284,14 @@ struct vio_dring_state { struct ldc_trans_cookie cookies[VIO_MAX_RING_COOKIES]; }; +#define VIO_TAG_SIZE ((int)sizeof(struct vio_msg_tag)) +#define VIO_VCC_MTU_SIZE (LDC_PACKET_SIZE - VIO_TAG_SIZE) + +struct vio_vcc { + struct vio_msg_tag tag; + char data[VIO_VCC_MTU_SIZE]; +}; + static inline void *vio_dring_cur(struct vio_dring_state *dr) { return dr->base + (dr->entry_size * dr->prod); diff --git a/arch/sparc/include/asm/visasm.h b/arch/sparc/include/asm/visasm.h index 6424249d5f78..7903e84e09e0 100644 --- a/arch/sparc/include/asm/visasm.h +++ b/arch/sparc/include/asm/visasm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_VISASM_H #define _SPARC64_VISASM_H diff --git a/arch/sparc/include/asm/winmacro.h b/arch/sparc/include/asm/winmacro.h index 9b7b21764cde..b6e911f5d93c 100644 --- a/arch/sparc/include/asm/winmacro.h +++ b/arch/sparc/include/asm/winmacro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * winmacro.h: Window loading-unloading macros. * diff --git a/arch/sparc/include/asm/xor.h b/arch/sparc/include/asm/xor.h index 8ed591c7db2d..f4c651e203c4 100644 --- a/arch/sparc/include/asm/xor.h +++ b/arch/sparc/include/asm/xor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___ASM_SPARC_XOR_H #define ___ASM_SPARC_XOR_H #if defined(__sparc__) && defined(__arch64__) diff --git a/arch/sparc/include/uapi/asm/apc.h b/arch/sparc/include/uapi/asm/apc.h index 24e9a7d4d97e..aeb369b87fcd 100644 --- a/arch/sparc/include/uapi/asm/apc.h +++ b/arch/sparc/include/uapi/asm/apc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* apc - Driver definitions for power management functions * of Aurora Personality Chip (APC) on SPARCstation-4/5 and * derivatives diff --git a/arch/sparc/include/uapi/asm/asi.h b/arch/sparc/include/uapi/asm/asi.h index 7ad7203deaec..d371b269571a 100644 --- a/arch/sparc/include/uapi/asm/asi.h +++ b/arch/sparc/include/uapi/asm/asi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_ASI_H #define _SPARC_ASI_H diff --git a/arch/sparc/include/uapi/asm/bitsperlong.h b/arch/sparc/include/uapi/asm/bitsperlong.h index 40dcaa3aaa56..cd9a432278d2 100644 --- a/arch/sparc/include/uapi/asm/bitsperlong.h +++ b/arch/sparc/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_ALPHA_BITSPERLONG_H #define __ASM_ALPHA_BITSPERLONG_H diff --git a/arch/sparc/include/uapi/asm/byteorder.h b/arch/sparc/include/uapi/asm/byteorder.h index ccc1b6b7de6c..216b8e59372f 100644 --- a/arch/sparc/include/uapi/asm/byteorder.h +++ b/arch/sparc/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_BYTEORDER_H #define _SPARC_BYTEORDER_H diff --git a/arch/sparc/include/uapi/asm/display7seg.h b/arch/sparc/include/uapi/asm/display7seg.h index 86d4a901df24..7e9fef0c6efe 100644 --- a/arch/sparc/include/uapi/asm/display7seg.h +++ b/arch/sparc/include/uapi/asm/display7seg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * * display7seg - Driver interface for the 7-segment display diff --git a/arch/sparc/include/uapi/asm/envctrl.h b/arch/sparc/include/uapi/asm/envctrl.h index 624fa7e2da8e..cf8aa0a14f40 100644 --- a/arch/sparc/include/uapi/asm/envctrl.h +++ b/arch/sparc/include/uapi/asm/envctrl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * * envctrl.h: Definitions for access to the i2c environment diff --git a/arch/sparc/include/uapi/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h index 20423e172853..81a732b902ee 100644 --- a/arch/sparc/include/uapi/asm/errno.h +++ b/arch/sparc/include/uapi/asm/errno.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_ERRNO_H #define _SPARC_ERRNO_H diff --git a/arch/sparc/include/uapi/asm/fbio.h b/arch/sparc/include/uapi/asm/fbio.h index d6cea07afb61..0dafe2c1eab7 100644 --- a/arch/sparc/include/uapi/asm/fbio.h +++ b/arch/sparc/include/uapi/asm/fbio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__LINUX_FBIO_H #define _UAPI__LINUX_FBIO_H diff --git a/arch/sparc/include/uapi/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h index 7e8ace5bf760..67dae75e5274 100644 --- a/arch/sparc/include/uapi/asm/fcntl.h +++ b/arch/sparc/include/uapi/asm/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_FCNTL_H #define _SPARC_FCNTL_H diff --git a/arch/sparc/include/uapi/asm/ioctl.h b/arch/sparc/include/uapi/asm/ioctl.h index 7d6bd51321b9..96c598fe746e 100644 --- a/arch/sparc/include/uapi/asm/ioctl.h +++ b/arch/sparc/include/uapi/asm/ioctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_IOCTL_H #define _SPARC_IOCTL_H diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h index f5df72b93bb2..2df52711e170 100644 --- a/arch/sparc/include/uapi/asm/ioctls.h +++ b/arch/sparc/include/uapi/asm/ioctls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_SPARC_IOCTLS_H #define _UAPI_ASM_SPARC_IOCTLS_H diff --git a/arch/sparc/include/uapi/asm/ipcbuf.h b/arch/sparc/include/uapi/asm/ipcbuf.h index 66013b4fe10d..9d0d125500e2 100644 --- a/arch/sparc/include/uapi/asm/ipcbuf.h +++ b/arch/sparc/include/uapi/asm/ipcbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __SPARC_IPCBUF_H #define __SPARC_IPCBUF_H diff --git a/arch/sparc/include/uapi/asm/jsflash.h b/arch/sparc/include/uapi/asm/jsflash.h index 0717d9e39d2d..68c98a54281a 100644 --- a/arch/sparc/include/uapi/asm/jsflash.h +++ b/arch/sparc/include/uapi/asm/jsflash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * jsflash.h: OS Flash SIMM support for JavaStations. * diff --git a/arch/sparc/include/uapi/asm/kvm_para.h b/arch/sparc/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/sparc/include/uapi/asm/kvm_para.h +++ b/arch/sparc/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/sparc/include/uapi/asm/mman.h b/arch/sparc/include/uapi/asm/mman.h index 9765896ecb2c..715a2c927e79 100644 --- a/arch/sparc/include/uapi/asm/mman.h +++ b/arch/sparc/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__SPARC_MMAN_H__ #define _UAPI__SPARC_MMAN_H__ diff --git a/arch/sparc/include/uapi/asm/msgbuf.h b/arch/sparc/include/uapi/asm/msgbuf.h index efc7cbe9788f..b601c4f4d956 100644 --- a/arch/sparc/include/uapi/asm/msgbuf.h +++ b/arch/sparc/include/uapi/asm/msgbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_MSGBUF_H #define _SPARC_MSGBUF_H diff --git a/arch/sparc/include/uapi/asm/openpromio.h b/arch/sparc/include/uapi/asm/openpromio.h index 917fb8e9c633..8817f7d1a70c 100644 --- a/arch/sparc/include/uapi/asm/openpromio.h +++ b/arch/sparc/include/uapi/asm/openpromio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_OPENPROMIO_H #define _SPARC_OPENPROMIO_H diff --git a/arch/sparc/include/uapi/asm/param.h b/arch/sparc/include/uapi/asm/param.h index 0bc356bf8c50..057d7135e4d0 100644 --- a/arch/sparc/include/uapi/asm/param.h +++ b/arch/sparc/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASMSPARC_PARAM_H #define _ASMSPARC_PARAM_H diff --git a/arch/sparc/include/uapi/asm/perfctr.h b/arch/sparc/include/uapi/asm/perfctr.h index 214feefa577c..316b837bcb8f 100644 --- a/arch/sparc/include/uapi/asm/perfctr.h +++ b/arch/sparc/include/uapi/asm/perfctr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /*---------------------------------------- PERFORMANCE INSTRUMENTATION Guillaume Thouvenin 08/10/98 diff --git a/arch/sparc/include/uapi/asm/poll.h b/arch/sparc/include/uapi/asm/poll.h index 091d3ad2e830..72356c999125 100644 --- a/arch/sparc/include/uapi/asm/poll.h +++ b/arch/sparc/include/uapi/asm/poll.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __SPARC_POLL_H #define __SPARC_POLL_H diff --git a/arch/sparc/include/uapi/asm/posix_types.h b/arch/sparc/include/uapi/asm/posix_types.h index 156220ed99eb..fec499d6efb7 100644 --- a/arch/sparc/include/uapi/asm/posix_types.h +++ b/arch/sparc/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is generally used by user-level software, so you need to * be a little careful about namespace pollution etc. Also, we cannot diff --git a/arch/sparc/include/uapi/asm/psr.h b/arch/sparc/include/uapi/asm/psr.h index 2f0ed856530b..e41f65f0aebd 100644 --- a/arch/sparc/include/uapi/asm/psr.h +++ b/arch/sparc/include/uapi/asm/psr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * psr.h: This file holds the macros for masking off various parts of * the processor status register on the Sparc. This is valid diff --git a/arch/sparc/include/uapi/asm/psrcompat.h b/arch/sparc/include/uapi/asm/psrcompat.h index 44b6327dbbf5..1eaffbe0d1e2 100644 --- a/arch/sparc/include/uapi/asm/psrcompat.h +++ b/arch/sparc/include/uapi/asm/psrcompat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC64_PSRCOMPAT_H #define _SPARC64_PSRCOMPAT_H diff --git a/arch/sparc/include/uapi/asm/pstate.h b/arch/sparc/include/uapi/asm/pstate.h index cf832e14aa05..b6999c9e7e86 100644 --- a/arch/sparc/include/uapi/asm/pstate.h +++ b/arch/sparc/include/uapi/asm/pstate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC64_PSTATE_H #define _SPARC64_PSTATE_H diff --git a/arch/sparc/include/uapi/asm/ptrace.h b/arch/sparc/include/uapi/asm/ptrace.h index 56fe4ea73feb..abe640037a55 100644 --- a/arch/sparc/include/uapi/asm/ptrace.h +++ b/arch/sparc/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__SPARC_PTRACE_H #define _UAPI__SPARC_PTRACE_H diff --git a/arch/sparc/include/uapi/asm/resource.h b/arch/sparc/include/uapi/asm/resource.h index fe163cafb4c7..cbe2de778838 100644 --- a/arch/sparc/include/uapi/asm/resource.h +++ b/arch/sparc/include/uapi/asm/resource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * resource.h: Resource definitions. * diff --git a/arch/sparc/include/uapi/asm/sembuf.h b/arch/sparc/include/uapi/asm/sembuf.h index faee1be08d67..f49b0ffa0ab8 100644 --- a/arch/sparc/include/uapi/asm/sembuf.h +++ b/arch/sparc/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_SEMBUF_H #define _SPARC_SEMBUF_H diff --git a/arch/sparc/include/uapi/asm/setup.h b/arch/sparc/include/uapi/asm/setup.h index 533768450872..3c208a4dd464 100644 --- a/arch/sparc/include/uapi/asm/setup.h +++ b/arch/sparc/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Just a place holder. */ diff --git a/arch/sparc/include/uapi/asm/shmbuf.h b/arch/sparc/include/uapi/asm/shmbuf.h index 83a16055363f..286631db705c 100644 --- a/arch/sparc/include/uapi/asm/shmbuf.h +++ b/arch/sparc/include/uapi/asm/shmbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_SHMBUF_H #define _SPARC_SHMBUF_H diff --git a/arch/sparc/include/uapi/asm/sigcontext.h b/arch/sparc/include/uapi/asm/sigcontext.h index ae5704fa77ad..043dd4b92026 100644 --- a/arch/sparc/include/uapi/asm/sigcontext.h +++ b/arch/sparc/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * There isn't anything here anymore, but the file must not be empty or patch * will delete it. diff --git a/arch/sparc/include/uapi/asm/siginfo.h b/arch/sparc/include/uapi/asm/siginfo.h index 2d9b79ccaa50..896ce447d16a 100644 --- a/arch/sparc/include/uapi/asm/siginfo.h +++ b/arch/sparc/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__SPARC_SIGINFO_H #define _UAPI__SPARC_SIGINFO_H @@ -16,10 +17,17 @@ #define SI_NOINFO 32767 /* no information in siginfo_t */ +/* + * SIGFPE si_codes + */ +#ifdef __KERNEL__ +#define FPE_FIXME 0 /* Broken dup of SI_USER */ +#endif /* __KERNEL__ */ + /* * SIGEMT si_codes */ -#define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */ +#define EMT_TAGOVF 1 /* tag overflow */ #define NSIGEMT 1 #endif /* _UAPI__SPARC_SIGINFO_H */ diff --git a/arch/sparc/include/uapi/asm/signal.h b/arch/sparc/include/uapi/asm/signal.h index f387400fcfdf..ff9505923b9a 100644 --- a/arch/sparc/include/uapi/asm/signal.h +++ b/arch/sparc/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__SPARC_SIGNAL_H #define _UAPI__SPARC_SIGNAL_H diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 186fd8199f54..d58520c2e6ff 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SOCKET_H #define _ASM_SOCKET_H @@ -98,6 +99,8 @@ #define SO_PEERGROUPS 0x003d +#define SO_ZEROCOPY 0x003e + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/arch/sparc/include/uapi/asm/sockios.h b/arch/sparc/include/uapi/asm/sockios.h index 990ea746486b..18a3ec14a847 100644 --- a/arch/sparc/include/uapi/asm/sockios.h +++ b/arch/sparc/include/uapi/asm/sockios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SPARC_SOCKIOS_H #define _ASM_SPARC_SOCKIOS_H diff --git a/arch/sparc/include/uapi/asm/stat.h b/arch/sparc/include/uapi/asm/stat.h index 2f0583a2c689..b6ec4eb217f7 100644 --- a/arch/sparc/include/uapi/asm/stat.h +++ b/arch/sparc/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __SPARC_STAT_H #define __SPARC_STAT_H diff --git a/arch/sparc/include/uapi/asm/statfs.h b/arch/sparc/include/uapi/asm/statfs.h index 55e607ad461d..20c8f5bd340e 100644 --- a/arch/sparc/include/uapi/asm/statfs.h +++ b/arch/sparc/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef ___ASM_SPARC_STATFS_H #define ___ASM_SPARC_STATFS_H diff --git a/arch/sparc/include/uapi/asm/swab.h b/arch/sparc/include/uapi/asm/swab.h index 4c7c12d69bea..6b1b3f1ad725 100644 --- a/arch/sparc/include/uapi/asm/swab.h +++ b/arch/sparc/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _SPARC_SWAB_H #define _SPARC_SWAB_H diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h index dd91642fcca7..ce5ad5d0f105 100644 --- a/arch/sparc/include/uapi/asm/termbits.h +++ b/arch/sparc/include/uapi/asm/termbits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_SPARC_TERMBITS_H #define _UAPI_SPARC_TERMBITS_H diff --git a/arch/sparc/include/uapi/asm/termios.h b/arch/sparc/include/uapi/asm/termios.h index ea6f09e51e53..ee86f4093d83 100644 --- a/arch/sparc/include/uapi/asm/termios.h +++ b/arch/sparc/include/uapi/asm/termios.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_SPARC_TERMIOS_H #define _UAPI_SPARC_TERMIOS_H diff --git a/arch/sparc/include/uapi/asm/traps.h b/arch/sparc/include/uapi/asm/traps.h index a4eceace6ccf..930db746f8bd 100644 --- a/arch/sparc/include/uapi/asm/traps.h +++ b/arch/sparc/include/uapi/asm/traps.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * traps.h: Format of entries for the Sparc trap table. * diff --git a/arch/sparc/include/uapi/asm/uctx.h b/arch/sparc/include/uapi/asm/uctx.h index dc937c75ffdd..13a13198e04f 100644 --- a/arch/sparc/include/uapi/asm/uctx.h +++ b/arch/sparc/include/uapi/asm/uctx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * uctx.h: Sparc64 {set,get}context() register state layouts. * diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index ae77df75bffa..09acf0ddec10 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * System calls under the Sparc. * diff --git a/arch/sparc/include/uapi/asm/utrap.h b/arch/sparc/include/uapi/asm/utrap.h index b10e527c22d9..d890b7fc6e83 100644 --- a/arch/sparc/include/uapi/asm/utrap.h +++ b/arch/sparc/include/uapi/asm/utrap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * include/asm/utrap.h * diff --git a/arch/sparc/include/uapi/asm/watchdog.h b/arch/sparc/include/uapi/asm/watchdog.h index 5baf2d3919cf..497ac19a9e4e 100644 --- a/arch/sparc/include/uapi/asm/watchdog.h +++ b/arch/sparc/include/uapi/asm/watchdog.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * * watchdog - Driver interface for the hardware watchdog timers diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index aac609889ee4..8de9617589a5 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c index c988e7fa069b..ecd05bc0a104 100644 --- a/arch/sparc/kernel/apc.c +++ b/arch/sparc/kernel/apc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* apc - Driver implementation for power management functions * of Aurora Personality Chip (APC) on SPARCstation-4/5 and * derivatives. diff --git a/arch/sparc/kernel/asm-offsets.c b/arch/sparc/kernel/asm-offsets.c index 3f09e1c83f58..5784f2df489a 100644 --- a/arch/sparc/kernel/asm-offsets.c +++ b/arch/sparc/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This program is used to generate definitions needed by * assembly language modules. diff --git a/arch/sparc/kernel/audit.c b/arch/sparc/kernel/audit.c index 2585c1e14bcc..a6e91bf34d48 100644 --- a/arch/sparc/kernel/audit.c +++ b/arch/sparc/kernel/audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c index ae88c223e4d3..a32d588174f2 100644 --- a/arch/sparc/kernel/auxio_32.c +++ b/arch/sparc/kernel/auxio_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* auxio.c: Probing for the Sparc AUXIO register at boot time. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 086435c17981..4e8f56c3793c 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* auxio.c: Probing for the Sparc AUXIO register at boot time. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/kernel/btext.c b/arch/sparc/kernel/btext.c index 987f7ec497cc..5869773f3dc4 100644 --- a/arch/sparc/kernel/btext.c +++ b/arch/sparc/kernel/btext.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Procedures for drawing on the screen early on in the boot process. * diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 4696958299e9..38ae4fdc9eb4 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* central.c: Central FHC driver for Sunfire/Starfire/Wildfire. * * Copyright (C) 1997, 1999, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/cherrs.S b/arch/sparc/kernel/cherrs.S index 655628def68e..7f3d3d264390 100644 --- a/arch/sparc/kernel/cherrs.S +++ b/arch/sparc/kernel/cherrs.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* These get patched into the trap table at boot time * once we know we have a cheetah processor. */ diff --git a/arch/sparc/kernel/compat_audit.c b/arch/sparc/kernel/compat_audit.c index e5611cd428f1..10eeb4f15b20 100644 --- a/arch/sparc/kernel/compat_audit.c +++ b/arch/sparc/kernel/compat_audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define __32bit_syscall_numbers__ #include #include "kernel.h" diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index ef4f18f7a674..4401dee30018 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* cpu.c: Dinky routines to look for the kind of Sparc cpu * we are on. * diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index 90d550bbfeef..d1d52822603d 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* cpumap.c: used for optimizing CPU assignment * * Copyright (C) 2009 Hong H. Pham diff --git a/arch/sparc/kernel/cpumap.h b/arch/sparc/kernel/cpumap.h index 9dac398c434a..7d5b774862e7 100644 --- a/arch/sparc/kernel/cpumap.h +++ b/arch/sparc/kernel/cpumap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CPUMAP_H #define _CPUMAP_H diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index 8d5d09f09caf..23b6e50d4ada 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* devices.c: Initial scan of the prom device tree for important * Sparc device nodes which we need to find. * diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c index b667aa6f28f6..f73e7597c971 100644 --- a/arch/sparc/kernel/dma.c +++ b/arch/sparc/kernel/dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/dtlb_miss.S b/arch/sparc/kernel/dtlb_miss.S index 09a6a15a7105..fb9c788437b0 100644 --- a/arch/sparc/kernel/dtlb_miss.S +++ b/arch/sparc/kernel/dtlb_miss.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* DTLB ** ICACHE line 1: Context 0 check and TSB load */ ldxa [%g0] ASI_DMMU_TSB_8KB_PTR, %g1 ! Get TSB 8K pointer ldxa [%g0] ASI_DMMU, %g6 ! Get TAG TARGET diff --git a/arch/sparc/kernel/dtlb_prot.S b/arch/sparc/kernel/dtlb_prot.S index 4087a62f96b0..9f945771bbd1 100644 --- a/arch/sparc/kernel/dtlb_prot.S +++ b/arch/sparc/kernel/dtlb_prot.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * dtlb_prot.S: DTLB protection trap strategy. * This is included directly into the trap table. diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index acf8314cec48..264b186478f3 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ebus.c: EBUS DMA library code. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index d85bdb999819..358fe4ef08a2 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* arch/sparc/kernel/entry.S: Sparc trap low-level entry points. * * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index 0f679421b468..7378567b601f 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ENTRY_H #define _ENTRY_H diff --git a/arch/sparc/kernel/etrap_32.S b/arch/sparc/kernel/etrap_32.S index e3e80d65e39a..9f243f918619 100644 --- a/arch/sparc/kernel/etrap_32.S +++ b/arch/sparc/kernel/etrap_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * etrap.S: Sparc trap window preparation for entry into the * Linux kernel. diff --git a/arch/sparc/kernel/etrap_64.S b/arch/sparc/kernel/etrap_64.S index 1276ca2567ba..5c77a2e0e991 100644 --- a/arch/sparc/kernel/etrap_64.S +++ b/arch/sparc/kernel/etrap_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * etrap.S: Preparing for entry into the kernel on Sparc V9. * @@ -38,7 +39,11 @@ etrap_syscall: TRAP_LOAD_THREAD_REG(%g6, %g1) or %g1, %g3, %g1 bne,pn %xcc, 1f sub %sp, STACKFRAME_SZ+TRACEREG_SZ-STACK_BIAS, %g2 - wrpr %g0, 7, %cleanwin +661: wrpr %g0, 7, %cleanwin + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + .word 0x85880000 ! allclean + .previous sethi %hi(TASK_REGOFF), %g2 sethi %hi(TSTATE_PEF), %g3 @@ -88,16 +93,30 @@ etrap_save: save %g2, -STACK_BIAS, %sp bne,pn %xcc, 3f mov PRIMARY_CONTEXT, %l4 - rdpr %canrestore, %g3 +661: rdpr %canrestore, %g3 + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + nop + .previous + rdpr %wstate, %g2 - wrpr %g0, 0, %canrestore +661: wrpr %g0, 0, %canrestore + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + nop + .previous sll %g2, 3, %g2 /* Set TI_SYS_FPDEPTH to 1 and clear TI_SYS_NOERROR. */ mov 1, %l5 sth %l5, [%l6 + TI_SYS_NOERROR] - wrpr %g3, 0, %otherwin +661: wrpr %g3, 0, %otherwin + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + .word 0x87880000 ! otherw + .previous + wrpr %g2, 0, %wstate sethi %hi(sparc64_kern_pri_context), %g2 ldx [%g2 + %lo(sparc64_kern_pri_context)], %g3 diff --git a/arch/sparc/kernel/fpu_traps.S b/arch/sparc/kernel/fpu_traps.S index 336d2750fe78..051659e29c7a 100644 --- a/arch/sparc/kernel/fpu_traps.S +++ b/arch/sparc/kernel/fpu_traps.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* This is trivial with the new code... */ .globl do_fpdis .type do_fpdis,#function diff --git a/arch/sparc/kernel/ftrace.c b/arch/sparc/kernel/ftrace.c index cec54dc4ab81..915dda4ae412 100644 --- a/arch/sparc/kernel/ftrace.c +++ b/arch/sparc/kernel/ftrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/getsetcc.S b/arch/sparc/kernel/getsetcc.S index a14d272d2061..181e09fd1c55 100644 --- a/arch/sparc/kernel/getsetcc.S +++ b/arch/sparc/kernel/getsetcc.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .globl getcc .type getcc,#function getcc: diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S index 7274e43ff9be..e55f2c075165 100644 --- a/arch/sparc/kernel/head_32.S +++ b/arch/sparc/kernel/head_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * head.S: The initial boot code for the Sparc port of Linux. * diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 78e0211753d2..9e293de12052 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* head.S: Initial boot code for the Sparc64 port of Linux. * * Copyright (C) 1996, 1997, 2007 David S. Miller (davem@davemloft.net) @@ -603,10 +604,10 @@ niagara_tlb_fixup: be,pt %xcc, niagara4_patch nop cmp %g1, SUN4V_CHIP_SPARC_M7 - be,pt %xcc, niagara4_patch + be,pt %xcc, sparc_m7_patch nop cmp %g1, SUN4V_CHIP_SPARC_M8 - be,pt %xcc, niagara4_patch + be,pt %xcc, sparc_m7_patch nop cmp %g1, SUN4V_CHIP_SPARC_SN be,pt %xcc, niagara4_patch @@ -621,6 +622,18 @@ niagara_tlb_fixup: ba,a,pt %xcc, 80f nop + +sparc_m7_patch: + call m7_patch_copyops + nop + call m7_patch_bzero + nop + call m7_patch_pageops + nop + + ba,a,pt %xcc, 80f + nop + niagara4_patch: call niagara4_patch_copyops nop @@ -881,7 +894,6 @@ sparc64_boot_end: #include "misctrap.S" #include "syscalls.S" #include "helpers.S" -#include "hvcalls.S" #include "sun4v_tlb_miss.S" #include "sun4v_ivec.S" #include "ktlb.S" @@ -926,6 +938,7 @@ swapper_4m_tsb: ! 0x0000000000428000 +#include "hvcalls.S" #include "systbls_64.S" .data diff --git a/arch/sparc/kernel/hvapi.c b/arch/sparc/kernel/hvapi.c index 267731234ce8..a2bc1b2955b4 100644 --- a/arch/sparc/kernel/hvapi.c +++ b/arch/sparc/kernel/hvapi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* hvapi.c: Hypervisor API management. * * Copyright (C) 2007 David S. Miller @@ -189,7 +190,7 @@ void __init sun4v_hvapi_init(void) group = HV_GRP_CORE; major = 1; - minor = 1; + minor = 6; if (sun4v_hvapi_register(group, major, &minor)) goto bad; diff --git a/arch/sparc/kernel/hvcalls.S b/arch/sparc/kernel/hvcalls.S index 4116ee5c7791..bdfd3d8c6707 100644 --- a/arch/sparc/kernel/hvcalls.S +++ b/arch/sparc/kernel/hvcalls.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* %o0: devhandle * %o1: devino * @@ -106,6 +107,17 @@ ENTRY(sun4v_cpu_yield) nop ENDPROC(sun4v_cpu_yield) + /* %o0: cpuid + * + * returns %o0: status + */ +ENTRY(sun4v_cpu_poke) + mov HV_FAST_CPU_POKE, %o5 + ta HV_FAST_TRAP + retl + nop +ENDPROC(sun4v_cpu_poke) + /* %o0: type * %o1: queue paddr * %o2: num queue entries diff --git a/arch/sparc/kernel/hvtramp.S b/arch/sparc/kernel/hvtramp.S index cdbfec299f2f..f39220471b65 100644 --- a/arch/sparc/kernel/hvtramp.S +++ b/arch/sparc/kernel/hvtramp.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* hvtramp.S: Hypervisor start-cpu trampoline code. * * Copyright (C) 2007, 2008 David S. Miller diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c index f95dd11b75ea..d6c46d512220 100644 --- a/arch/sparc/kernel/idprom.c +++ b/arch/sparc/kernel/idprom.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * idprom.c: Routines to load the idprom into kernel addresses and * interpret the data contained within. diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index fcbcc031f615..b08dc3416f06 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* iommu.c: Generic sparc64 IOMMU support. * * Copyright (C) 1999, 2007, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/iommu_common.h b/arch/sparc/kernel/iommu_common.h index 5ea5c192b1d9..e3c02ba32500 100644 --- a/arch/sparc/kernel/iommu_common.h +++ b/arch/sparc/kernel/iommu_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* iommu_common.h: UltraSparc SBUS/PCI common iommu declarations. * * Copyright (C) 1999, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 12894f259bea..7eeef80c02f7 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ioport.c: Simple io mapping allocator. * diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 70a0b8ddd0ba..b02026ad6e34 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index cac4a5554c0e..e8452be5123b 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Interrupt request handling routines. On the * Sparc the IRQs are basically 'cast in stone' diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 99dd133a029f..d66dde833f5e 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997, 2007, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/itlb_miss.S b/arch/sparc/kernel/itlb_miss.S index 5a8377b54955..5a5d92482e8d 100644 --- a/arch/sparc/kernel/itlb_miss.S +++ b/arch/sparc/kernel/itlb_miss.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ITLB ** ICACHE line 1: Context 0 check and TSB load */ ldxa [%g0] ASI_IMMU_TSB_8KB_PTR, %g1 ! Get TSB 8K pointer ldxa [%g0] ASI_IMMU, %g6 ! Get TAG TARGET diff --git a/arch/sparc/kernel/ivec.S b/arch/sparc/kernel/ivec.S index d29f92ebca5e..94ba2c3a29c1 100644 --- a/arch/sparc/kernel/ivec.S +++ b/arch/sparc/kernel/ivec.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* The registers for cross calls will be: * * DATA 0: [low 32-bits] Address of function to call, jmp to this diff --git a/arch/sparc/kernel/jump_label.c b/arch/sparc/kernel/jump_label.c index 93adde1ac166..7f8eac51df33 100644 --- a/arch/sparc/kernel/jump_label.c +++ b/arch/sparc/kernel/jump_label.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index b625db4cfb78..ddffd368e057 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SPARC_KERNEL_H #define __SPARC_KERNEL_H diff --git a/arch/sparc/kernel/kgdb_32.c b/arch/sparc/kernel/kgdb_32.c index 6e8e318c57be..5868fc333ea8 100644 --- a/arch/sparc/kernel/kgdb_32.c +++ b/arch/sparc/kernel/kgdb_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* kgdb.c: KGDB support for 32-bit sparc. * * Copyright (C) 2008 David S. Miller diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c index cbf21d0870e0..d5f7dc6323d5 100644 --- a/arch/sparc/kernel/kgdb_64.c +++ b/arch/sparc/kernel/kgdb_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* kgdb.c: KGDB support for 64-bit sparc. * * Copyright (C) 2008 David S. Miller diff --git a/arch/sparc/kernel/kprobes.c b/arch/sparc/kernel/kprobes.c index 2d13a4fc0384..ab4ba4347941 100644 --- a/arch/sparc/kernel/kprobes.c +++ b/arch/sparc/kernel/kprobes.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* arch/sparc64/kernel/kprobes.c * * Copyright (C) 2004 David S. Miller diff --git a/arch/sparc/kernel/kstack.h b/arch/sparc/kernel/kstack.h index 53dfb92e09fb..b3c5e8f2443a 100644 --- a/arch/sparc/kernel/kstack.h +++ b/arch/sparc/kernel/kstack.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _KSTACK_H #define _KSTACK_H diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index f22bec0db645..1cf91c05e275 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* arch/sparc64/kernel/ktlb.S: Kernel mapping TLB miss handling. * * Copyright (C) 1995, 1997, 2005, 2008 David S. Miller diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 840e0b21bfe3..86b625f9d8dc 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ldc.c: Logical Domain Channel link-layer protocol driver. * * Copyright (C) 2007, 2008 David S. Miller @@ -1480,6 +1481,7 @@ int ldc_rx_reset(struct ldc_channel *lp) { return __set_rx_head(lp, lp->rx_tail); } +EXPORT_SYMBOL(ldc_rx_reset); void __ldc_print(struct ldc_channel *lp, const char *caller) { @@ -1493,6 +1495,7 @@ void __ldc_print(struct ldc_channel *lp, const char *caller) lp->tx_head, lp->tx_tail, lp->tx_num_entries, lp->rcv_nxt, lp->snd_nxt); } +EXPORT_SYMBOL(__ldc_print); static int write_raw(struct ldc_channel *lp, const void *buf, unsigned int size) { diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index afcdd5e4f43f..84b233752f28 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index 4371f72ff025..15b59169c535 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * leon_pci.c: LEON Host PCI support * @@ -25,6 +26,12 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) { LIST_HEAD(resources); struct pci_bus *root_bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return; pci_add_resource_offset(&resources, &info->io_space, info->io_space.start - 0x1000); @@ -32,15 +39,21 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) info->busn.flags = IORESOURCE_BUS; pci_add_resource(&resources, &info->busn); - root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, - &resources); - if (!root_bus) { - pci_free_resource_list(&resources); + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = &ofdev->dev; + bridge->sysdata = info; + bridge->busnr = 0; + bridge->ops = info->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = info->map_irq; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); return; } - /* Setup IRQs of all devices using custom routines */ - pci_fixup_irqs(pci_common_swizzle, info->map_irq); + root_bus = bridge->bus; /* Assign devices with resources */ pci_assign_unassigned_resources(); @@ -94,9 +107,3 @@ void pcibios_fixup_bus(struct pci_bus *pbus) } } } - -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} diff --git a/arch/sparc/kernel/leon_pci_grpci1.c b/arch/sparc/kernel/leon_pci_grpci1.c index 1e77128a8f88..e6935d0ac1ec 100644 --- a/arch/sparc/kernel/leon_pci_grpci1.c +++ b/arch/sparc/kernel/leon_pci_grpci1.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * leon_pci_grpci1.c: GRPCI1 Host PCI driver * @@ -695,7 +696,7 @@ err1: return err; } -static struct of_device_id grpci1_of_match[] = { +static const struct of_device_id grpci1_of_match[] __initconst = { { .name = "GAISLER_PCIFBRG", }, diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index f727c4de1316..ca22f93d9045 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * leon_pci_grpci2.c: GRPCI2 Host PCI driver * @@ -886,7 +887,7 @@ err1: return err; } -static struct of_device_id grpci2_of_match[] = { +static const struct of_device_id grpci2_of_match[] __initconst = { { .name = "GAISLER_GRPCI2", }, diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c index ddcf950282ed..065e2d4b7290 100644 --- a/arch/sparc/kernel/leon_pmc.c +++ b/arch/sparc/kernel/leon_pmc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* leon_pmc.c: LEON Power-down cpu_idle() handler * * Copyright (C) 2011 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index db7acf27bea2..da6f1486318e 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* leon_smp.c: Sparc-Leon SMP support. * * based on sun4m_smp.c diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index fa466ce45bc9..1ef6156b1530 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* mdesc.c: Sun4V machine description handling. * * Copyright (C) 2007, 2008 David S. Miller diff --git a/arch/sparc/kernel/misctrap.S b/arch/sparc/kernel/misctrap.S index 9276d2f0dd86..b5c84177521e 100644 --- a/arch/sparc/kernel/misctrap.S +++ b/arch/sparc/kernel/misctrap.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_KGDB .globl arch_kgdb_breakpoint .type arch_kgdb_breakpoint,#function diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index 192a617a32f3..df39580f398d 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Kernel module help for sparc64. * * Copyright (C) 2001 Rusty Russell. diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 185aa96fa5be..3641a294ed54 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index 7bbdc26d9512..44e4d4435bed 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/of_device_common.h b/arch/sparc/kernel/of_device_common.h index cdfd23992841..3d66230c61b6 100644 --- a/arch/sparc/kernel/of_device_common.h +++ b/arch/sparc/kernel/of_device_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _OF_DEVICE_COMMON_H #define _OF_DEVICE_COMMON_H diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 7eceaa10836f..220d0f36560a 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -690,16 +691,6 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, return bus; } -void pcibios_fixup_bus(struct pci_bus *pbus) -{ -} - -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - int pcibios_enable_device(struct pci_dev *dev, int mask) { u16 cmd, oldcmd; diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 33524c1d5328..1e10fb26fa88 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci_common.c: PCI controller common support. * * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 11a1f0d289d2..be71ae086622 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci_fire.c: Sun4u platform PCI-E controller support. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 37222ca849df..ac172961d276 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* pci_impl.h: Helper definitions for PCI controller support. * * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index 84e16d81a6d8..1994d7638406 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci_msi.c: Sparc64 MSI support common layer. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 7dce27b3c761..f413371da387 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci_psycho.c: PSYCHO/U2P specific PCI controller support. * * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 00a616ffa35b..8107286be9ab 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index c664d3e3aa8d..934b97c72f7c 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support. * * Copyright (C) 2001, 2002, 2003, 2007, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 9ebebf1fd93d..249367228c33 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pci_sun4v.c: SUN4V specific PCI controller support. * * Copyright (C) 2006, 2007, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_sun4v.h b/arch/sparc/kernel/pci_sun4v.h index 22603a4e48bf..d47263a9901a 100644 --- a/arch/sparc/kernel/pci_sun4v.h +++ b/arch/sparc/kernel/pci_sun4v.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* pci_sun4v.h: SUN4V specific PCI controller support. * * Copyright (C) 2006 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/pci_sun4v_asm.S b/arch/sparc/kernel/pci_sun4v_asm.S index 578f09657916..2b8051871a15 100644 --- a/arch/sparc/kernel/pci_sun4v_asm.S +++ b/arch/sparc/kernel/pci_sun4v_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* pci_sun4v_asm: Hypervisor calls for PCI support. * * Copyright (C) 2006, 2008 David S. Miller diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 732af9a9f6dd..22f8774977d5 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * pcic.c: MicroSPARC-IIep PCI controller support * @@ -746,12 +747,6 @@ static void watchdog_reset() { } #endif -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} - int pcibios_enable_device(struct pci_dev *pdev, int mask) { return 0; diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 710f3278d448..5c1f54758312 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Performance event support for sparc64. * * Copyright (C) 2009, 2010 David S. Miller diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c index 3b26cf62df6d..b5c1eb33b951 100644 --- a/arch/sparc/kernel/pmc.c +++ b/arch/sparc/kernel/pmc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* pmc - Driver implementation for power management functions * of Power Management Controller (PMC) on SPARCstation-Voyager. * diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index 4b60f385c98f..92627abce311 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* power.c: Power management driver. * * Copyright (C) 1999, 2007, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 9245f93398c7..d9662cf7e648 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* linux/arch/sparc/kernel/process.c * * Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index b96104da5bd6..318efd784a0b 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996, 2008 David S. Miller (davem@davemloft.net) @@ -77,8 +78,13 @@ void arch_cpu_idle(void) : "=&r" (pstate) : "i" (PSTATE_IE)); - if (!need_resched() && !cpu_is_offline(smp_processor_id())) + if (!need_resched() && !cpu_is_offline(smp_processor_id())) { sun4v_cpu_yield(); + /* If resumed by cpu_poke then we need to explicitly + * call scheduler_ipi(). + */ + scheduler_poke(); + } /* Re-enable interrupts. */ __asm__ __volatile__( diff --git a/arch/sparc/kernel/prom.h b/arch/sparc/kernel/prom.h index 890281b12b28..26a1cca7c761 100644 --- a/arch/sparc/kernel/prom.h +++ b/arch/sparc/kernel/prom.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PROM_H #define __PROM_H diff --git a/arch/sparc/kernel/prom_irqtrans.c b/arch/sparc/kernel/prom_irqtrans.c index 40e4936bd479..f3fecac7facb 100644 --- a/arch/sparc/kernel/prom_irqtrans.c +++ b/arch/sparc/kernel/prom_irqtrans.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c index 8db48e808ed4..81aa91e5c0e6 100644 --- a/arch/sparc/kernel/psycho_common.c +++ b/arch/sparc/kernel/psycho_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* psycho_common.c: Code common to PSYCHO and derivative PCI controllers. * * Copyright (C) 2008 David S. Miller diff --git a/arch/sparc/kernel/psycho_common.h b/arch/sparc/kernel/psycho_common.h index 05a6e30a928e..6925231c50e4 100644 --- a/arch/sparc/kernel/psycho_common.h +++ b/arch/sparc/kernel/psycho_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PSYCHO_COMMON_H #define _PSYCHO_COMMON_H diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index eca3dc76793c..16b50afe7b52 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ptrace.c: Sparc process tracing support. * * Copyright (C) 1996, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/reboot.c b/arch/sparc/kernel/reboot.c index eba7d918162a..7933ee365207 100644 --- a/arch/sparc/kernel/reboot.c +++ b/arch/sparc/kernel/reboot.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* reboot.c: reboot/shutdown/halt/poweroff handling * * Copyright (C) 2008 David S. Miller diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S index 6c34de0c2abd..dca8ed810046 100644 --- a/arch/sparc/kernel/rtrap_32.S +++ b/arch/sparc/kernel/rtrap_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * rtrap.S: Return from Sparc trap low-level code. * diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 709a82ebd294..0b21042ab181 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * rtrap.S: Preparing for return from trap on Sparc V9. * @@ -224,10 +225,19 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 rdpr %otherwin, %l2 srl %l1, 3, %l1 - wrpr %l2, %g0, %canrestore +661: wrpr %l2, %g0, %canrestore + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + .word 0x89880000 ! normalw + .previous + wrpr %l1, %g0, %wstate brnz,pt %l2, user_rtt_restore - wrpr %g0, %g0, %otherwin +661: wrpr %g0, %g0, %otherwin + .section .fast_win_ctrl_1insn_patch, "ax" + .word 661b + nop + .previous ldx [%g6 + TI_FLAGS], %g3 wr %g0, ASI_AIUP, %asi diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index be5bdf93c767..c133dfc37c5c 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sbus.c: UltraSparc SBUS controller support. * diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 6722308d1a98..2e3a3e203061 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sparc/kernel/setup.c * diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 150ee7d4b059..34f7a533a74f 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sparc64/kernel/setup.c * @@ -300,6 +301,11 @@ static void __init sun4v_patch(void) break; } + if (sun4v_chip_type != SUN4V_CHIP_NIAGARA1) { + sun4v_patch_1insn_range(&__fast_win_ctrl_1insn_patch, + &__fast_win_ctrl_1insn_patch_end); + } + sun4v_hvapi_init(); } @@ -363,6 +369,7 @@ void __init start_early_boot(void) check_if_starfire(); per_cpu_patch(); sun4v_patch(); + smp_init_cpu_poke(); cpu = hard_smp_processor_id(); if (cpu >= NR_CPUS) { diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index b4096bb665b2..5c572de64c74 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -85,34 +86,34 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) at the same time. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); else { - switch (from->si_code >> 16) { - case __SI_TIMER >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_TIMER: err |= __put_user(from->si_tid, &to->si_tid); err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); default: + case SIL_KILL: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_FAULT >> 16: + case SIL_FAULT: err |= __put_user(from->si_trapno, &to->si_trapno); err |= __put_user((unsigned long)from->si_addr, &to->si_addr); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_band, &to->si_band); err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_pid, &to->si_pid); err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 62c3e255ae7c..5665261cee37 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* linux/arch/sparc/kernel/signal.c * * Copyright (C) 1991, 1992 Linus Torvalds diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 965d50e833e7..20426a1c28f2 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sparc64/kernel/signal.c * diff --git a/arch/sparc/kernel/sigutil.h b/arch/sparc/kernel/sigutil.h index d223aa432bb6..21d332d8bddd 100644 --- a/arch/sparc/kernel/sigutil.h +++ b/arch/sparc/kernel/sigutil.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SIGUTIL_H #define _SIGUTIL_H diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c index e5fe8cef9a69..1e9fae56a853 100644 --- a/arch/sparc/kernel/sigutil_32.c +++ b/arch/sparc/kernel/sigutil_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c index 36aadcbeac69..512e4639e4a1 100644 --- a/arch/sparc/kernel/sigutil_64.c +++ b/arch/sparc/kernel/sigutil_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index e80e6ba3d500..e078680a1768 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* smp.c: Sparc SMP support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 3218bc43302e..c50182cd2f64 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* smp.c: Sparc64 SMP support. * * Copyright (C) 1997, 2007, 2008 David S. Miller (davem@davemloft.net) @@ -74,6 +75,9 @@ EXPORT_SYMBOL(cpu_core_sib_cache_map); static cpumask_t smp_commenced_mask; +static DEFINE_PER_CPU(bool, poke); +static bool cpu_poke; + void smp_info(struct seq_file *m) { int i; @@ -1439,15 +1443,86 @@ void __init smp_cpus_done(unsigned int max_cpus) { } +static void send_cpu_ipi(int cpu) +{ + xcall_deliver((u64) &xcall_receive_signal, + 0, 0, cpumask_of(cpu)); +} + +void scheduler_poke(void) +{ + if (!cpu_poke) + return; + + if (!__this_cpu_read(poke)) + return; + + __this_cpu_write(poke, false); + set_softint(1 << PIL_SMP_RECEIVE_SIGNAL); +} + +static unsigned long send_cpu_poke(int cpu) +{ + unsigned long hv_err; + + per_cpu(poke, cpu) = true; + hv_err = sun4v_cpu_poke(cpu); + if (hv_err != HV_EOK) { + per_cpu(poke, cpu) = false; + pr_err_ratelimited("%s: sun4v_cpu_poke() fails err=%lu\n", + __func__, hv_err); + } + + return hv_err; +} + void smp_send_reschedule(int cpu) { if (cpu == smp_processor_id()) { WARN_ON_ONCE(preemptible()); set_softint(1 << PIL_SMP_RECEIVE_SIGNAL); - } else { - xcall_deliver((u64) &xcall_receive_signal, - 0, 0, cpumask_of(cpu)); + return; } + + /* Use cpu poke to resume idle cpu if supported. */ + if (cpu_poke && idle_cpu(cpu)) { + unsigned long ret; + + ret = send_cpu_poke(cpu); + if (ret == HV_EOK) + return; + } + + /* Use IPI in following cases: + * - cpu poke not supported + * - cpu not idle + * - send_cpu_poke() returns with error + */ + send_cpu_ipi(cpu); +} + +void smp_init_cpu_poke(void) +{ + unsigned long major; + unsigned long minor; + int ret; + + if (tlb_type != hypervisor) + return; + + ret = sun4v_hvapi_get(HV_GRP_CORE, &major, &minor); + if (ret) { + pr_debug("HV_GRP_CORE is not registered\n"); + return; + } + + if (major == 1 && minor >= 6) { + /* CPU POKE is registered. */ + cpu_poke = true; + return; + } + + pr_debug("CPU_POKE not supported\n"); } void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs) diff --git a/arch/sparc/kernel/spiterrs.S b/arch/sparc/kernel/spiterrs.S index d7e540842809..5427af44099a 100644 --- a/arch/sparc/kernel/spiterrs.S +++ b/arch/sparc/kernel/spiterrs.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* We need to carefully read the error status, ACK the errors, * prevent recursive traps, and pass the information on to C * code for logging. diff --git a/arch/sparc/kernel/sstate.c b/arch/sparc/kernel/sstate.c index 3caed4023589..ac8677c3841e 100644 --- a/arch/sparc/kernel/sstate.c +++ b/arch/sparc/kernel/sstate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* sstate.c: System soft state support. * * Copyright (C) 2007, 2008 David S. Miller diff --git a/arch/sparc/kernel/starfire.c b/arch/sparc/kernel/starfire.c index 167fdfd9c837..b8cd57d9182b 100644 --- a/arch/sparc/kernel/starfire.c +++ b/arch/sparc/kernel/starfire.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * starfire.c: Starfire/E10000 support. * diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index a87d0e47c168..d869d409fce6 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SS1000/SC2000 interrupt handling. * diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index af93b50e3ce4..ff30f03beb7c 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Sparc SS1000/SC2000 SMP support. * * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index aa84da0b2d30..c01767a0480e 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sun4m irq support * diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 5547fcb1d72d..228a6527082d 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sun4m SMP support. * diff --git a/arch/sparc/kernel/sun4v_ivec.S b/arch/sparc/kernel/sun4v_ivec.S index 34631995859a..6478ef4f6a15 100644 --- a/arch/sparc/kernel/sun4v_ivec.S +++ b/arch/sparc/kernel/sun4v_ivec.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* sun4v_ivec.S: Sun4v interrupt vector handling. * * Copyright (C) 2006 diff --git a/arch/sparc/kernel/sun4v_tlb_miss.S b/arch/sparc/kernel/sun4v_tlb_miss.S index c19f352f46c7..7ac9f3367674 100644 --- a/arch/sparc/kernel/sun4v_tlb_miss.S +++ b/arch/sparc/kernel/sun4v_tlb_miss.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* sun4v_tlb_miss.S: Sun4v TLB miss handlers. * * Copyright (C) 2006 diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index f834224208ed..7e7011a1e712 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * sys32.S: I-cache tricks for 32-bit compatibility layer simple * conversions. diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index bca44f3e6b86..b4e1478413a1 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c index 7aecb239626d..990703b7cf4d 100644 --- a/arch/sparc/kernel/sys_sparc_32.c +++ b/arch/sparc/kernel/sys_sparc_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 043544d0cda3..55416db482ad 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index c4a1b5c40e4e..c5f9ec8c52eb 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* SunOS's execv() call only specifies the argv argument, the * environment settings are the same as the calling processes. */ diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index 5fd352b759af..6d60d416f0dd 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* sysfs.c: Topology sysfs support code for sparc64. * * Copyright (C) 2007 David S. Miller diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h index 2dab8236d490..5a01cfe19a0e 100644 --- a/arch/sparc/kernel/systbls.h +++ b/arch/sparc/kernel/systbls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SYSTBLS_H #define _SYSTBLS_H diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 5253e895b81b..731b25d572a1 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 82339f6be0b2..293c1cb31262 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 2ce2e7b2abbb..8a08830e4a65 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 564f0e46ffd4..3b397081047a 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S index 3eed99fc6989..82fafeeb3a62 100644 --- a/arch/sparc/kernel/trampoline_32.S +++ b/arch/sparc/kernel/trampoline_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * trampoline.S: SMP cpu boot-up trampoline code. * diff --git a/arch/sparc/kernel/trampoline_64.S b/arch/sparc/kernel/trampoline_64.S index 88ede1d53b4c..fe59122d257d 100644 --- a/arch/sparc/kernel/trampoline_64.S +++ b/arch/sparc/kernel/trampoline_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * trampoline.S: Jump start slave processors on sparc64. * diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index 466d4aed06c7..b1ed763e4787 100644 --- a/arch/sparc/kernel/traps_32.c +++ b/arch/sparc/kernel/traps_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sparc/kernel/traps.c * @@ -306,7 +307,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, info.si_errno = 0; info.si_addr = (void __user *)pc; info.si_trapno = 0; - info.si_code = __SI_FAULT; + info.si_code = FPE_FIXME; if ((fsr & 0x1c000) == (1 << 14)) { if (fsr & 0x10) info.si_code = FPE_FLTINV; diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index ad31af1dd726..0a56dc257cb9 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -265,6 +265,45 @@ void sun4v_insn_access_exception_tl1(struct pt_regs *regs, unsigned long addr, u sun4v_insn_access_exception(regs, addr, type_ctx); } +bool is_no_fault_exception(struct pt_regs *regs) +{ + unsigned char asi; + u32 insn; + + if (get_user(insn, (u32 __user *)regs->tpc) == -EFAULT) + return false; + + /* + * Must do a little instruction decoding here in order to + * decide on a course of action. The bits of interest are: + * insn[31:30] = op, where 3 indicates the load/store group + * insn[24:19] = op3, which identifies individual opcodes + * insn[13] indicates an immediate offset + * op3[4]=1 identifies alternate space instructions + * op3[5:4]=3 identifies floating point instructions + * op3[2]=1 identifies stores + * See "Opcode Maps" in the appendix of any Sparc V9 + * architecture spec for full details. + */ + if ((insn & 0xc0800000) == 0xc0800000) { /* op=3, op3[4]=1 */ + if (insn & 0x2000) /* immediate offset */ + asi = (regs->tstate >> 24); /* saved %asi */ + else + asi = (insn >> 5); /* immediate asi */ + if ((asi & 0xf2) == ASI_PNF) { + if (insn & 0x1000000) { /* op3[5:4]=3 */ + handle_ldf_stq(insn, regs); + return true; + } else if (insn & 0x200000) { /* op3[2], stores */ + return false; + } + handle_ld_nf(insn, regs); + return true; + } + } + return false; +} + void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, unsigned long sfar) { enum ctx_state prev_state = exception_enter(); @@ -296,6 +335,9 @@ void spitfire_data_access_exception(struct pt_regs *regs, unsigned long sfsr, un die_if_kernel("Dax", regs); } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = SEGV_MAPERR; @@ -352,6 +394,9 @@ void sun4v_data_access_exception(struct pt_regs *regs, unsigned long addr, unsig regs->tpc &= 0xffffffff; regs->tnpc &= 0xffffffff; } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = SEGV_MAPERR; @@ -2258,7 +2303,7 @@ static void do_fpe_common(struct pt_regs *regs) info.si_errno = 0; info.si_addr = (void __user *)regs->tpc; info.si_trapno = 0; - info.si_code = __SI_FAULT; + info.si_code = FPE_FIXME; if ((fsr & 0x1c000) == (1 << 14)) { if (fsr & 0x10) info.si_code = FPE_FLTINV; @@ -2575,6 +2620,9 @@ void mem_address_unaligned(struct pt_regs *regs, unsigned long sfar, unsigned lo kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc)); goto out; } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; @@ -2597,6 +2645,9 @@ void sun4v_do_mna(struct pt_regs *regs, unsigned long addr, unsigned long type_c kernel_unaligned_trap(regs, *((unsigned int *)regs->tpc)); return; } + if (is_no_fault_exception(regs)) + return; + info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S index db872dbfafe9..eaed39ce8938 100644 --- a/arch/sparc/kernel/tsb.S +++ b/arch/sparc/kernel/tsb.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* tsb.S: Sparc64 TSB table handling. * * Copyright (C) 2006 David S. Miller @@ -117,7 +118,7 @@ tsb_miss_page_table_walk_sun4v_fastpath: /* Valid PTE is now in %g5. */ #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) - sethi %uhi(_PAGE_PMD_HUGE), %g7 + sethi %uhi(_PAGE_PMD_HUGE | _PAGE_PUD_HUGE), %g7 sllx %g7, 32, %g7 andcc %g5, %g7, %g0 diff --git a/arch/sparc/kernel/ttable_32.S b/arch/sparc/kernel/ttable_32.S index 8a7a96ca676f..e79fd786fbbb 100644 --- a/arch/sparc/kernel/ttable_32.S +++ b/arch/sparc/kernel/ttable_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* The Sparc trap table, bootloader gives us control at _start. */ __HEAD diff --git a/arch/sparc/kernel/ttable_64.S b/arch/sparc/kernel/ttable_64.S index efe93ab4a9c0..18685fe69b91 100644 --- a/arch/sparc/kernel/ttable_64.S +++ b/arch/sparc/kernel/ttable_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ttable.S: Sparc V9 Trap Table(s) with SpitFire/Cheetah/SUN4V extensions. * * Copyright (C) 1996, 2001, 2006 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/una_asm_32.S b/arch/sparc/kernel/una_asm_32.S index 8f096e84a937..f8bf839289fb 100644 --- a/arch/sparc/kernel/una_asm_32.S +++ b/arch/sparc/kernel/una_asm_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* una_asm.S: Kernel unaligned trap assembler helpers. * * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/una_asm_64.S b/arch/sparc/kernel/una_asm_64.S index 1c8d33228b2a..e256f395e9f6 100644 --- a/arch/sparc/kernel/una_asm_64.S +++ b/arch/sparc/kernel/una_asm_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* una_asm.S: Kernel unaligned trap assembler helpers. * * Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/unaligned_32.c b/arch/sparc/kernel/unaligned_32.c index 8367dce5f41b..7642d7e4f0d9 100644 --- a/arch/sparc/kernel/unaligned_32.c +++ b/arch/sparc/kernel/unaligned_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index cda7fd367c4f..23db2efda570 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * unaligned.c: Unaligned load/store trap handling with special * cases for the kernel to do them more quickly. diff --git a/arch/sparc/kernel/urtt_fill.S b/arch/sparc/kernel/urtt_fill.S index 364af3250646..44183aa59168 100644 --- a/arch/sparc/kernel/urtt_fill.S +++ b/arch/sparc/kernel/urtt_fill.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/sparc/kernel/utrap.S b/arch/sparc/kernel/utrap.S index c731e8023d3e..7a2d9a9bea59 100644 --- a/arch/sparc/kernel/utrap.S +++ b/arch/sparc/kernel/utrap.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ .globl utrap_trap .type utrap_trap,#function utrap_trap: /* %g3=handler,%g4=level */ diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 1c8763c9c52b..1a0fa10cb6b7 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* vio.c: Virtual I/O channel devices probing infrastructure. * * Copyright (c) 2003-2005 IBM Corp. @@ -246,6 +247,7 @@ u64 vio_vdev_node(struct mdesc_handle *hp, struct vio_dev *vdev) return node; } +EXPORT_SYMBOL(vio_vdev_node); static void vio_fill_channel_info(struct mdesc_handle *hp, u64 mp, struct vio_dev *vdev) diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c index d4f13c037a40..c858f5f3ce2c 100644 --- a/arch/sparc/kernel/viohs.c +++ b/arch/sparc/kernel/viohs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* viohs.c: LDOM Virtual I/O handshake helper layer. * * Copyright (C) 2007 David S. Miller @@ -814,15 +815,21 @@ int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, case VDEV_NETWORK_SWITCH: case VDEV_DISK: case VDEV_DISK_SERVER: + case VDEV_CONSOLE_CON: break; default: return -EINVAL; } - if (!ops || !ops->send_attr || !ops->handle_attr || - !ops->handshake_complete) - return -EINVAL; + if (dev_class == VDEV_NETWORK || + dev_class == VDEV_NETWORK_SWITCH || + dev_class == VDEV_DISK || + dev_class == VDEV_DISK_SERVER) { + if (!ops || !ops->send_attr || !ops->handle_attr || + !ops->handshake_complete) + return -EINVAL; + } if (!ver_table || ver_table_size < 0) return -EINVAL; diff --git a/arch/sparc/kernel/visemul.c b/arch/sparc/kernel/visemul.c index 8f35eea2103a..64ed80ed6cc2 100644 --- a/arch/sparc/kernel/visemul.c +++ b/arch/sparc/kernel/visemul.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* visemul.c: Emulation of VIS instructions. * * Copyright (C) 2006 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 03b3d65d1266..5a2344574f39 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ld script for sparc32/sparc64 kernel */ #include @@ -154,6 +155,16 @@ SECTIONS *(.get_tick_patch) __get_tick_patch_end = .; } + .pud_huge_patch : { + __pud_huge_patch = .; + *(.pud_huge_patch) + __pud_huge_patch_end = .; + } + .fast_win_ctrl_1insn_patch : { + __fast_win_ctrl_1insn_patch = .; + *(.fast_win_ctrl_1insn_patch) + __fast_win_ctrl_1insn_patch_end = .; + } PERCPU_SECTION(SMP_CACHE_BYTES) #ifdef CONFIG_JUMP_LABEL diff --git a/arch/sparc/kernel/windows.c b/arch/sparc/kernel/windows.c index 435a467b0595..69a6ba6e9293 100644 --- a/arch/sparc/kernel/windows.c +++ b/arch/sparc/kernel/windows.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* windows.c: Routines to deal with register window management * at the C-code level. * diff --git a/arch/sparc/kernel/winfixup.S b/arch/sparc/kernel/winfixup.S index 1ee173cc3c39..448accee090f 100644 --- a/arch/sparc/kernel/winfixup.S +++ b/arch/sparc/kernel/winfixup.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* winfixup.S: Handle cases where user stack pointer is found to be bogus. * * Copyright (C) 1997, 2006 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S index 28a7bc69f82b..96a3a112423a 100644 --- a/arch/sparc/kernel/wof.S +++ b/arch/sparc/kernel/wof.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * wof.S: Sparc window overflow handler. * diff --git a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S index 2c21cc59683e..1a4ca490e9c2 100644 --- a/arch/sparc/kernel/wuf.S +++ b/arch/sparc/kernel/wuf.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * wuf.S: Window underflow trap handler for the Sparc. * diff --git a/arch/sparc/lib/GENbzero.S b/arch/sparc/lib/GENbzero.S index 2fbf6297d57c..63d618857d49 100644 --- a/arch/sparc/lib/GENbzero.S +++ b/arch/sparc/lib/GENbzero.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* GENbzero.S: Generic sparc64 memset/clear_user. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/GENcopy_from_user.S b/arch/sparc/lib/GENcopy_from_user.S index 8aa16ef113f2..6891a5678ea3 100644 --- a/arch/sparc/lib/GENcopy_from_user.S +++ b/arch/sparc/lib/GENcopy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* GENcopy_from_user.S: Generic sparc64 copy from userspace. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/GENcopy_to_user.S b/arch/sparc/lib/GENcopy_to_user.S index 311c8fa5e98e..df75b532a934 100644 --- a/arch/sparc/lib/GENcopy_to_user.S +++ b/arch/sparc/lib/GENcopy_to_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* GENcopy_to_user.S: Generic sparc64 copy to userspace. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/GENmemcpy.S b/arch/sparc/lib/GENmemcpy.S index 059ea24ad73d..114340a0d36e 100644 --- a/arch/sparc/lib/GENmemcpy.S +++ b/arch/sparc/lib/GENmemcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* GENmemcpy.S: Generic sparc64 memcpy. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/GENpage.S b/arch/sparc/lib/GENpage.S index 2ef9d05f21bc..c143c4d1de3f 100644 --- a/arch/sparc/lib/GENpage.S +++ b/arch/sparc/lib/GENpage.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* GENpage.S: Generic clear and copy page. * * Copyright (C) 2007 (davem@davemloft.net) diff --git a/arch/sparc/lib/GENpatch.S b/arch/sparc/lib/GENpatch.S index 95e2f1f9e477..1ec1f02c8b7b 100644 --- a/arch/sparc/lib/GENpatch.S +++ b/arch/sparc/lib/GENpatch.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* GENpatch.S: Patch Ultra-I routines with generic variant. * * Copyright (C) 2007 David S. Miller diff --git a/arch/sparc/lib/M7copy_from_user.S b/arch/sparc/lib/M7copy_from_user.S new file mode 100644 index 000000000000..66464b3e3649 --- /dev/null +++ b/arch/sparc/lib/M7copy_from_user.S @@ -0,0 +1,40 @@ +/* + * M7copy_from_user.S: SPARC M7 optimized copy from userspace. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + + +#define EX_LD(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y; \ + .text; \ + .align 4; + +#define EX_LD_FP(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y##_fp; \ + .text; \ + .align 4; + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#define FUNC_NAME M7copy_from_user +#define LOAD(type,addr,dest) type##a [addr] %asi, dest +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, raw_copy_in_user; \ + nop +#endif + +#include "M7memcpy.S" diff --git a/arch/sparc/lib/M7copy_to_user.S b/arch/sparc/lib/M7copy_to_user.S new file mode 100644 index 000000000000..a60ac467f808 --- /dev/null +++ b/arch/sparc/lib/M7copy_to_user.S @@ -0,0 +1,51 @@ +/* + * M7copy_to_user.S: SPARC M7 optimized copy to userspace. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + + +#define EX_ST(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y; \ + .text; \ + .align 4; + +#define EX_ST_FP(x, y) \ +98: x; \ + .section __ex_table,"a"; \ + .align 4; \ + .word 98b, y##_fp; \ + .text; \ + .align 4; + + +#ifndef ASI_AIUS +#define ASI_AIUS 0x11 +#endif + +#ifndef ASI_BLK_INIT_QUAD_LDD_AIUS +#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23 +#endif + +#define FUNC_NAME M7copy_to_user +#define STORE(type,src,addr) type##a src, [addr] %asi +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_AIUS +#define STORE_MRU_ASI ASI_ST_BLKINIT_MRU_S +#define EX_RETVAL(x) 0 + +#ifdef __KERNEL__ + /* Writing to %asi is _expensive_ so we hardcode it. + * Reading %asi to check for KERNEL_DS is comparatively + * cheap. + */ +#define PREAMBLE \ + rd %asi, %g1; \ + cmp %g1, ASI_AIUS; \ + bne,pn %icc, raw_copy_in_user; \ + nop +#endif + +#include "M7memcpy.S" diff --git a/arch/sparc/lib/M7memcpy.S b/arch/sparc/lib/M7memcpy.S new file mode 100644 index 000000000000..cbd42ea7c3f7 --- /dev/null +++ b/arch/sparc/lib/M7memcpy.S @@ -0,0 +1,923 @@ +/* + * M7memcpy: Optimized SPARC M7 memcpy + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + + .file "M7memcpy.S" + +/* + * memcpy(s1, s2, len) + * + * Copy s2 to s1, always copy n bytes. + * Note: this C code does not work for overlapped copies. + * + * Fast assembler language version of the following C-program for memcpy + * which represents the `standard' for the C-library. + * + * void * + * memcpy(void *s, const void *s0, size_t n) + * { + * if (n != 0) { + * char *s1 = s; + * const char *s2 = s0; + * do { + * *s1++ = *s2++; + * } while (--n != 0); + * } + * return (s); + * } + * + * + * SPARC T7/M7 Flow : + * + * if (count < SMALL_MAX) { + * if count < SHORTCOPY (SHORTCOPY=3) + * copy bytes; exit with dst addr + * if src & dst aligned on word boundary but not long word boundary, + * copy with ldw/stw; branch to finish_up + * if src & dst aligned on long word boundary + * copy with ldx/stx; branch to finish_up + * if src & dst not aligned and length <= SHORTCHECK (SHORTCHECK=14) + * copy bytes; exit with dst addr + * move enough bytes to get src to word boundary + * if dst now on word boundary + * move_words: + * copy words; branch to finish_up + * if dst now on half word boundary + * load words, shift half words, store words; branch to finish_up + * if dst on byte 1 + * load words, shift 3 bytes, store words; branch to finish_up + * if dst on byte 3 + * load words, shift 1 byte, store words; branch to finish_up + * finish_up: + * copy bytes; exit with dst addr + * } else { More than SMALL_MAX bytes + * move bytes until dst is on long word boundary + * if( src is on long word boundary ) { + * if (count < MED_MAX) { + * finish_long: src/dst aligned on 8 bytes + * copy with ldx/stx in 8-way unrolled loop; + * copy final 0-63 bytes; exit with dst addr + * } else { src/dst aligned; count > MED_MAX + * align dst on 64 byte boundary; for main data movement: + * prefetch src data to L2 cache; let HW prefetch move data to L1 cache + * Use BIS (block initializing store) to avoid copying store cache + * lines from memory. But pre-store first element of each cache line + * ST_CHUNK lines in advance of the rest of that cache line. That + * gives time for replacement cache lines to be written back without + * excess STQ and Miss Buffer filling. Repeat until near the end, + * then finish up storing before going to finish_long. + * } + * } else { src/dst not aligned on 8 bytes + * if src is word aligned and count < MED_WMAX + * move words in 8-way unrolled loop + * move final 0-31 bytes; exit with dst addr + * if count < MED_UMAX + * use alignaddr/faligndata combined with ldd/std in 8-way + * unrolled loop to move data. + * go to unalign_done + * else + * setup alignaddr for faligndata instructions + * align dst on 64 byte boundary; prefetch src data to L1 cache + * loadx8, falign, block-store, prefetch loop + * (only use block-init-store when src/dst on 8 byte boundaries.) + * unalign_done: + * move remaining bytes for unaligned cases. exit with dst addr. + * } + * + */ + +#include +#include + +#if !defined(EX_LD) && !defined(EX_ST) +#define NON_USER_COPY +#endif + +#ifndef EX_LD +#define EX_LD(x,y) x +#endif +#ifndef EX_LD_FP +#define EX_LD_FP(x,y) x +#endif + +#ifndef EX_ST +#define EX_ST(x,y) x +#endif +#ifndef EX_ST_FP +#define EX_ST_FP(x,y) x +#endif + +#ifndef EX_RETVAL +#define EX_RETVAL(x) x +#endif + +#ifndef LOAD +#define LOAD(type,addr,dest) type [addr], dest +#endif + +#ifndef STORE +#define STORE(type,src,addr) type src, [addr] +#endif + +/* + * ASI_BLK_INIT_QUAD_LDD_P/ASI_BLK_INIT_QUAD_LDD_S marks the cache + * line as "least recently used" which means if many threads are + * active, it has a high probability of being pushed out of the cache + * between the first initializing store and the final stores. + * Thus, we use ASI_ST_BLKINIT_MRU_P/ASI_ST_BLKINIT_MRU_S which + * marks the cache line as "most recently used" for all + * but the last cache line + */ +#ifndef STORE_ASI +#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA +#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P +#else +#define STORE_ASI 0x80 /* ASI_P */ +#endif +#endif + +#ifndef STORE_MRU_ASI +#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA +#define STORE_MRU_ASI ASI_ST_BLKINIT_MRU_P +#else +#define STORE_MRU_ASI 0x80 /* ASI_P */ +#endif +#endif + +#ifndef STORE_INIT +#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI +#endif + +#ifndef STORE_INIT_MRU +#define STORE_INIT_MRU(src,addr) stxa src, [addr] STORE_MRU_ASI +#endif + +#ifndef FUNC_NAME +#define FUNC_NAME M7memcpy +#endif + +#ifndef PREAMBLE +#define PREAMBLE +#endif + +#define BLOCK_SIZE 64 +#define SHORTCOPY 3 +#define SHORTCHECK 14 +#define SHORT_LONG 64 /* max copy for short longword-aligned case */ + /* must be at least 64 */ +#define SMALL_MAX 128 +#define MED_UMAX 1024 /* max copy for medium un-aligned case */ +#define MED_WMAX 1024 /* max copy for medium word-aligned case */ +#define MED_MAX 1024 /* max copy for medium longword-aligned case */ +#define ST_CHUNK 24 /* ST_CHUNK - block of values for BIS Store */ +#define ALIGN_PRE 24 /* distance for aligned prefetch loop */ + + .register %g2,#scratch + + .section ".text" + .global FUNC_NAME + .type FUNC_NAME, #function + .align 16 +FUNC_NAME: + srlx %o2, 31, %g2 + cmp %g2, 0 + tne %xcc, 5 + PREAMBLE + mov %o0, %g1 ! save %o0 + brz,pn %o2, .Lsmallx + cmp %o2, 3 + ble,pn %icc, .Ltiny_cp + cmp %o2, 19 + ble,pn %icc, .Lsmall_cp + or %o0, %o1, %g2 + cmp %o2, SMALL_MAX + bl,pn %icc, .Lmedium_cp + nop + +.Lmedium: + neg %o0, %o5 + andcc %o5, 7, %o5 ! bytes till DST 8 byte aligned + brz,pt %o5, .Ldst_aligned_on_8 + + ! %o5 has the bytes to be written in partial store. + sub %o2, %o5, %o2 + sub %o1, %o0, %o1 ! %o1 gets the difference +7: ! dst aligning loop + add %o1, %o0, %o4 + EX_LD(LOAD(ldub, %o4, %o4), memcpy_retl_o2_plus_o5) ! load one byte + subcc %o5, 1, %o5 + EX_ST(STORE(stb, %o4, %o0), memcpy_retl_o2_plus_o5_plus_1) + bgu,pt %xcc, 7b + add %o0, 1, %o0 ! advance dst + add %o1, %o0, %o1 ! restore %o1 +.Ldst_aligned_on_8: + andcc %o1, 7, %o5 + brnz,pt %o5, .Lsrc_dst_unaligned_on_8 + nop + +.Lsrc_dst_aligned_on_8: + ! check if we are copying MED_MAX or more bytes + set MED_MAX, %o3 + cmp %o2, %o3 ! limit to store buffer size + bgu,pn %xcc, .Llarge_align8_copy + nop + +/* + * Special case for handling when src and dest are both long word aligned + * and total data to move is less than MED_MAX bytes + */ +.Lmedlong: + subcc %o2, 63, %o2 ! adjust length to allow cc test + ble,pn %xcc, .Lmedl63 ! skip big loop if less than 64 bytes + nop +.Lmedl64: + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_63) ! load + subcc %o2, 64, %o2 ! decrement length count + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_63_64) ! and store + EX_LD(LOAD(ldx, %o1+8, %o3), memcpy_retl_o2_plus_63_56) ! a block of 64 + EX_ST(STORE(stx, %o3, %o0+8), memcpy_retl_o2_plus_63_56) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_63_48) + EX_ST(STORE(stx, %o4, %o0+16), memcpy_retl_o2_plus_63_48) + EX_LD(LOAD(ldx, %o1+24, %o3), memcpy_retl_o2_plus_63_40) + EX_ST(STORE(stx, %o3, %o0+24), memcpy_retl_o2_plus_63_40) + EX_LD(LOAD(ldx, %o1+32, %o4), memcpy_retl_o2_plus_63_32)! load and store + EX_ST(STORE(stx, %o4, %o0+32), memcpy_retl_o2_plus_63_32) + EX_LD(LOAD(ldx, %o1+40, %o3), memcpy_retl_o2_plus_63_24)! a block of 64 + add %o1, 64, %o1 ! increase src ptr by 64 + EX_ST(STORE(stx, %o3, %o0+40), memcpy_retl_o2_plus_63_24) + EX_LD(LOAD(ldx, %o1-16, %o4), memcpy_retl_o2_plus_63_16) + add %o0, 64, %o0 ! increase dst ptr by 64 + EX_ST(STORE(stx, %o4, %o0-16), memcpy_retl_o2_plus_63_16) + EX_LD(LOAD(ldx, %o1-8, %o3), memcpy_retl_o2_plus_63_8) + bgu,pt %xcc, .Lmedl64 ! repeat if at least 64 bytes left + EX_ST(STORE(stx, %o3, %o0-8), memcpy_retl_o2_plus_63_8) +.Lmedl63: + addcc %o2, 32, %o2 ! adjust remaining count + ble,pt %xcc, .Lmedl31 ! to skip if 31 or fewer bytes left + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_31) ! load + sub %o2, 32, %o2 ! decrement length count + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_31_32) ! and store + EX_LD(LOAD(ldx, %o1+8, %o3), memcpy_retl_o2_plus_31_24) ! a block of 32 + add %o1, 32, %o1 ! increase src ptr by 32 + EX_ST(STORE(stx, %o3, %o0+8), memcpy_retl_o2_plus_31_24) + EX_LD(LOAD(ldx, %o1-16, %o4), memcpy_retl_o2_plus_31_16) + add %o0, 32, %o0 ! increase dst ptr by 32 + EX_ST(STORE(stx, %o4, %o0-16), memcpy_retl_o2_plus_31_16) + EX_LD(LOAD(ldx, %o1-8, %o3), memcpy_retl_o2_plus_31_8) + EX_ST(STORE(stx, %o3, %o0-8), memcpy_retl_o2_plus_31_8) +.Lmedl31: + addcc %o2, 16, %o2 ! adjust remaining count + ble,pt %xcc, .Lmedl15 ! skip if 15 or fewer bytes left + nop ! + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_15) + add %o1, 16, %o1 ! increase src ptr by 16 + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_15) + sub %o2, 16, %o2 ! decrease count by 16 + EX_LD(LOAD(ldx, %o1-8, %o3), memcpy_retl_o2_plus_15_8) + add %o0, 16, %o0 ! increase dst ptr by 16 + EX_ST(STORE(stx, %o3, %o0-8), memcpy_retl_o2_plus_15_8) +.Lmedl15: + addcc %o2, 15, %o2 ! restore count + bz,pt %xcc, .Lsmallx ! exit if finished + cmp %o2, 8 + blt,pt %xcc, .Lmedw7 ! skip if 7 or fewer bytes left + tst %o2 + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) ! load 8 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + add %o0, 8, %o0 ! increase dst ptr by 8 + subcc %o2, 8, %o2 ! decrease count by 8 + bnz,pn %xcc, .Lmedw7 + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) ! and store 8 + retl + mov EX_RETVAL(%g1), %o0 ! restore %o0 + + .align 16 +.Lsrc_dst_unaligned_on_8: + ! DST is 8-byte aligned, src is not +2: + andcc %o1, 0x3, %o5 ! test word alignment + bnz,pt %xcc, .Lunalignsetup ! branch to skip if not word aligned + nop + +/* + * Handle all cases where src and dest are aligned on word + * boundaries. Use unrolled loops for better performance. + * This option wins over standard large data move when + * source and destination is in cache for.Lmedium + * to short data moves. + */ + set MED_WMAX, %o3 + cmp %o2, %o3 ! limit to store buffer size + bge,pt %xcc, .Lunalignrejoin ! otherwise rejoin main loop + nop + + subcc %o2, 31, %o2 ! adjust length to allow cc test + ! for end of loop + ble,pt %xcc, .Lmedw31 ! skip big loop if less than 16 +.Lmedw32: + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2_plus_31)! move a block of 32 + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1+4, %o4), memcpy_retl_o2_plus_31) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_31) + subcc %o2, 32, %o2 ! decrement length count + EX_LD(LOAD(ld, %o1+8, %o4), memcpy_retl_o2_plus_31_24) + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1+12, %o4), memcpy_retl_o2_plus_31_24) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0+8), memcpy_retl_o2_plus_31_24) + add %o1, 32, %o1 ! increase src ptr by 32 + EX_LD(LOAD(ld, %o1-16, %o4), memcpy_retl_o2_plus_31_16) + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1-12, %o4), memcpy_retl_o2_plus_31_16) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0+16), memcpy_retl_o2_plus_31_16) + add %o0, 32, %o0 ! increase dst ptr by 32 + EX_LD(LOAD(ld, %o1-8, %o4), memcpy_retl_o2_plus_31_8) + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1-4, %o4), memcpy_retl_o2_plus_31_8) + or %o4, %o5, %o5 + bgu,pt %xcc, .Lmedw32 ! repeat if at least 32 bytes left + EX_ST(STORE(stx, %o5, %o0-8), memcpy_retl_o2_plus_31_8) +.Lmedw31: + addcc %o2, 31, %o2 ! restore count + + bz,pt %xcc, .Lsmallx ! exit if finished + nop + cmp %o2, 16 + blt,pt %xcc, .Lmedw15 + nop + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2)! move a block of 16 bytes + sllx %o4, 32, %o5 + subcc %o2, 16, %o2 ! decrement length count + EX_LD(LOAD(ld, %o1+4, %o4), memcpy_retl_o2_plus_16) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_16) + add %o1, 16, %o1 ! increase src ptr by 16 + EX_LD(LOAD(ld, %o1-8, %o4), memcpy_retl_o2_plus_8) + add %o0, 16, %o0 ! increase dst ptr by 16 + sllx %o4, 32, %o5 + EX_LD(LOAD(ld, %o1-4, %o4), memcpy_retl_o2_plus_8) + or %o4, %o5, %o5 + EX_ST(STORE(stx, %o5, %o0-8), memcpy_retl_o2_plus_8) +.Lmedw15: + bz,pt %xcc, .Lsmallx ! exit if finished + cmp %o2, 8 + blt,pn %xcc, .Lmedw7 ! skip if 7 or fewer bytes left + tst %o2 + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2) ! load 4 bytes + subcc %o2, 8, %o2 ! decrease count by 8 + EX_ST(STORE(stw, %o4, %o0), memcpy_retl_o2_plus_8)! and store 4 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + EX_LD(LOAD(ld, %o1-4, %o3), memcpy_retl_o2_plus_4) ! load 4 bytes + add %o0, 8, %o0 ! increase dst ptr by 8 + EX_ST(STORE(stw, %o3, %o0-4), memcpy_retl_o2_plus_4)! and store 4 bytes + bz,pt %xcc, .Lsmallx ! exit if finished +.Lmedw7: ! count is ge 1, less than 8 + cmp %o2, 4 ! check for 4 bytes left + blt,pn %xcc, .Lsmallleft3 ! skip if 3 or fewer bytes left + nop ! + EX_LD(LOAD(ld, %o1, %o4), memcpy_retl_o2) ! load 4 bytes + add %o1, 4, %o1 ! increase src ptr by 4 + add %o0, 4, %o0 ! increase dst ptr by 4 + subcc %o2, 4, %o2 ! decrease count by 4 + bnz .Lsmallleft3 + EX_ST(STORE(stw, %o4, %o0-4), memcpy_retl_o2_plus_4)! and store 4 bytes + retl + mov EX_RETVAL(%g1), %o0 + + .align 16 +.Llarge_align8_copy: ! Src and dst share 8 byte alignment + ! align dst to 64 byte boundary + andcc %o0, 0x3f, %o3 ! %o3 == 0 means dst is 64 byte aligned + brz,pn %o3, .Laligned_to_64 + andcc %o0, 8, %o3 ! odd long words to move? + brz,pt %o3, .Laligned_to_16 + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) + sub %o2, 8, %o2 + add %o1, 8, %o1 ! increment src ptr + add %o0, 8, %o0 ! increment dst ptr + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) +.Laligned_to_16: + andcc %o0, 16, %o3 ! pair of long words to move? + brz,pt %o3, .Laligned_to_32 + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) + sub %o2, 16, %o2 + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_16) + add %o1, 16, %o1 ! increment src ptr + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_8) + add %o0, 16, %o0 ! increment dst ptr + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) +.Laligned_to_32: + andcc %o0, 32, %o3 ! four long words to move? + brz,pt %o3, .Laligned_to_64 + nop + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2) + sub %o2, 32, %o2 + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_32) + EX_LD(LOAD(ldx, %o1+8, %o4), memcpy_retl_o2_plus_24) + EX_ST(STORE(stx, %o4, %o0+8), memcpy_retl_o2_plus_24) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_16) + EX_ST(STORE(stx, %o4, %o0+16), memcpy_retl_o2_plus_16) + add %o1, 32, %o1 ! increment src ptr + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_8) + add %o0, 32, %o0 ! increment dst ptr + EX_ST(STORE(stx, %o4, %o0-8), memcpy_retl_o2_plus_8) +.Laligned_to_64: +! +! Using block init store (BIS) instructions to avoid fetching cache +! lines from memory. Use ST_CHUNK stores to first element of each cache +! line (similar to prefetching) to avoid overfilling STQ or miss buffers. +! Gives existing cache lines time to be moved out of L1/L2/L3 cache. +! Initial stores using MRU version of BIS to keep cache line in +! cache until we are ready to store final element of cache line. +! Then store last element using the LRU version of BIS. +! + andn %o2, 0x3f, %o5 ! %o5 is multiple of block size + and %o2, 0x3f, %o2 ! residue bytes in %o2 +! +! We use STORE_MRU_ASI for the first seven stores to each cache line +! followed by STORE_ASI (mark as LRU) for the last store. That +! mixed approach reduces the probability that the cache line is removed +! before we finish setting it, while minimizing the effects on +! other cached values during a large memcpy +! +! ST_CHUNK batches up initial BIS operations for several cache lines +! to allow multiple requests to not be blocked by overflowing the +! the store miss buffer. Then the matching stores for all those +! BIS operations are executed. +! + + sub %o0, 8, %o0 ! adjust %o0 for ASI alignment +.Lalign_loop: + cmp %o5, ST_CHUNK*64 + blu,pt %xcc, .Lalign_loop_fin + mov ST_CHUNK,%o3 +.Lalign_loop_start: + prefetch [%o1 + (ALIGN_PRE * BLOCK_SIZE)], 21 + subcc %o3, 1, %o3 + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_o5) + add %o1, 64, %o1 + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + bgu %xcc,.Lalign_loop_start + add %o0, 56, %o0 + + mov ST_CHUNK,%o3 + sllx %o3, 6, %o4 ! ST_CHUNK*64 + sub %o1, %o4, %o1 ! reset %o1 + sub %o0, %o4, %o0 ! reset %o0 + +.Lalign_loop_rest: + EX_LD(LOAD(ldx, %o1+8, %o4), memcpy_retl_o2_plus_o5) + add %o0, 16, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + subcc %o3, 1, %o3 + EX_LD(LOAD(ldx, %o1+24, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+32, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+40, %o4), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+48, %o4), memcpy_retl_o2_plus_o5) + add %o1, 64, %o1 + add %o0, 8, %o0 + EX_ST(STORE_INIT_MRU(%o4, %o0), memcpy_retl_o2_plus_o5) + add %o0, 8, %o0 + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_o5) + sub %o5, 64, %o5 + bgu %xcc,.Lalign_loop_rest + ! mark cache line as LRU + EX_ST(STORE_INIT(%o4, %o0), memcpy_retl_o2_plus_o5_plus_64) + + cmp %o5, ST_CHUNK*64 + bgu,pt %xcc, .Lalign_loop_start + mov ST_CHUNK,%o3 + + cmp %o5, 0 + beq .Lalign_done + nop +.Lalign_loop_fin: + EX_LD(LOAD(ldx, %o1, %o4), memcpy_retl_o2_plus_o5) + EX_ST(STORE(stx, %o4, %o0+8), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+8, %o4), memcpy_retl_o2_plus_o5) + EX_ST(STORE(stx, %o4, %o0+8+8), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1+16, %o4), memcpy_retl_o2_plus_o5) + EX_ST(STORE(stx, %o4, %o0+8+16), memcpy_retl_o2_plus_o5) + subcc %o5, 64, %o5 + EX_LD(LOAD(ldx, %o1+24, %o4), memcpy_retl_o2_plus_o5_64) + EX_ST(STORE(stx, %o4, %o0+8+24), memcpy_retl_o2_plus_o5_64) + EX_LD(LOAD(ldx, %o1+32, %o4), memcpy_retl_o2_plus_o5_64) + EX_ST(STORE(stx, %o4, %o0+8+32), memcpy_retl_o2_plus_o5_64) + EX_LD(LOAD(ldx, %o1+40, %o4), memcpy_retl_o2_plus_o5_64) + EX_ST(STORE(stx, %o4, %o0+8+40), memcpy_retl_o2_plus_o5_64) + EX_LD(LOAD(ldx, %o1+48, %o4), memcpy_retl_o2_plus_o5_64) + add %o1, 64, %o1 + EX_ST(STORE(stx, %o4, %o0+8+48), memcpy_retl_o2_plus_o5_64) + add %o0, 64, %o0 + EX_LD(LOAD(ldx, %o1-8, %o4), memcpy_retl_o2_plus_o5_64) + bgu %xcc,.Lalign_loop_fin + EX_ST(STORE(stx, %o4, %o0), memcpy_retl_o2_plus_o5_64) + +.Lalign_done: + add %o0, 8, %o0 ! restore %o0 from ASI alignment + membar #StoreStore + sub %o2, 63, %o2 ! adjust length to allow cc test + ba .Lmedl63 ! in .Lmedl63 + nop + + .align 16 + ! Dst is on 8 byte boundary; src is not; remaining count > SMALL_MAX +.Lunalignsetup: +.Lunalignrejoin: + mov %g1, %o3 ! save %g1 as VISEntryHalf clobbers it +#ifdef NON_USER_COPY + VISEntryHalfFast(.Lmedium_vis_entry_fail_cp) +#else + VISEntryHalf +#endif + mov %o3, %g1 ! restore %g1 + + set MED_UMAX, %o3 + cmp %o2, %o3 ! check for.Lmedium unaligned limit + bge,pt %xcc,.Lunalign_large + prefetch [%o1 + (4 * BLOCK_SIZE)], 20 + andn %o2, 0x3f, %o5 ! %o5 is multiple of block size + and %o2, 0x3f, %o2 ! residue bytes in %o2 + cmp %o2, 8 ! Insure we do not load beyond + bgt .Lunalign_adjust ! end of source buffer + andn %o1, 0x7, %o4 ! %o4 has long word aligned src address + add %o2, 64, %o2 ! adjust to leave loop + sub %o5, 64, %o5 ! early if necessary +.Lunalign_adjust: + alignaddr %o1, %g0, %g0 ! generate %gsr + add %o1, %o5, %o1 ! advance %o1 to after blocks + EX_LD_FP(LOAD(ldd, %o4, %f0), memcpy_retl_o2_plus_o5) +.Lunalign_loop: + EX_LD_FP(LOAD(ldd, %o4+8, %f2), memcpy_retl_o2_plus_o5) + faligndata %f0, %f2, %f16 + EX_LD_FP(LOAD(ldd, %o4+16, %f4), memcpy_retl_o2_plus_o5) + subcc %o5, BLOCK_SIZE, %o5 + EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5_plus_64) + faligndata %f2, %f4, %f18 + EX_LD_FP(LOAD(ldd, %o4+24, %f6), memcpy_retl_o2_plus_o5_plus_56) + EX_ST_FP(STORE(std, %f18, %o0+8), memcpy_retl_o2_plus_o5_plus_56) + faligndata %f4, %f6, %f20 + EX_LD_FP(LOAD(ldd, %o4+32, %f8), memcpy_retl_o2_plus_o5_plus_48) + EX_ST_FP(STORE(std, %f20, %o0+16), memcpy_retl_o2_plus_o5_plus_48) + faligndata %f6, %f8, %f22 + EX_LD_FP(LOAD(ldd, %o4+40, %f10), memcpy_retl_o2_plus_o5_plus_40) + EX_ST_FP(STORE(std, %f22, %o0+24), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f8, %f10, %f24 + EX_LD_FP(LOAD(ldd, %o4+48, %f12), memcpy_retl_o2_plus_o5_plus_32) + EX_ST_FP(STORE(std, %f24, %o0+32), memcpy_retl_o2_plus_o5_plus_32) + faligndata %f10, %f12, %f26 + EX_LD_FP(LOAD(ldd, %o4+56, %f14), memcpy_retl_o2_plus_o5_plus_24) + add %o4, BLOCK_SIZE, %o4 + EX_ST_FP(STORE(std, %f26, %o0+40), memcpy_retl_o2_plus_o5_plus_24) + faligndata %f12, %f14, %f28 + EX_LD_FP(LOAD(ldd, %o4, %f0), memcpy_retl_o2_plus_o5_plus_16) + EX_ST_FP(STORE(std, %f28, %o0+48), memcpy_retl_o2_plus_o5_plus_16) + faligndata %f14, %f0, %f30 + EX_ST_FP(STORE(std, %f30, %o0+56), memcpy_retl_o2_plus_o5_plus_8) + add %o0, BLOCK_SIZE, %o0 + bgu,pt %xcc, .Lunalign_loop + prefetch [%o4 + (5 * BLOCK_SIZE)], 20 + ba .Lunalign_done + nop + +.Lunalign_large: + andcc %o0, 0x3f, %o3 ! is dst 64-byte block aligned? + bz %xcc, .Lunalignsrc + sub %o3, 64, %o3 ! %o3 will be multiple of 8 + neg %o3 ! bytes until dest is 64 byte aligned + sub %o2, %o3, %o2 ! update cnt with bytes to be moved + ! Move bytes according to source alignment + andcc %o1, 0x1, %o5 + bnz %xcc, .Lunalignbyte ! check for byte alignment + nop + andcc %o1, 2, %o5 ! check for half word alignment + bnz %xcc, .Lunalignhalf + nop + ! Src is word aligned +.Lunalignword: + EX_LD_FP(LOAD(ld, %o1, %o4), memcpy_retl_o2_plus_o3) ! load 4 bytes + add %o1, 8, %o1 ! increase src ptr by 8 + EX_ST_FP(STORE(stw, %o4, %o0), memcpy_retl_o2_plus_o3) ! and store 4 + subcc %o3, 8, %o3 ! decrease count by 8 + EX_LD_FP(LOAD(ld, %o1-4, %o4), memcpy_retl_o2_plus_o3_plus_4)! load 4 + add %o0, 8, %o0 ! increase dst ptr by 8 + bnz %xcc, .Lunalignword + EX_ST_FP(STORE(stw, %o4, %o0-4), memcpy_retl_o2_plus_o3_plus_4) + ba .Lunalignsrc + nop + + ! Src is half-word aligned +.Lunalignhalf: + EX_LD_FP(LOAD(lduh, %o1, %o4), memcpy_retl_o2_plus_o3) ! load 2 bytes + sllx %o4, 32, %o5 ! shift left + EX_LD_FP(LOAD(lduw, %o1+2, %o4), memcpy_retl_o2_plus_o3) + or %o4, %o5, %o5 + sllx %o5, 16, %o5 + EX_LD_FP(LOAD(lduh, %o1+6, %o4), memcpy_retl_o2_plus_o3) + or %o4, %o5, %o5 + EX_ST_FP(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_o3) + add %o1, 8, %o1 + subcc %o3, 8, %o3 + bnz %xcc, .Lunalignhalf + add %o0, 8, %o0 + ba .Lunalignsrc + nop + + ! Src is Byte aligned +.Lunalignbyte: + sub %o0, %o1, %o0 ! share pointer advance +.Lunalignbyte_loop: + EX_LD_FP(LOAD(ldub, %o1, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 56, %o5 + EX_LD_FP(LOAD(lduh, %o1+1, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 40, %o4 + or %o4, %o5, %o5 + EX_LD_FP(LOAD(lduh, %o1+3, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 24, %o4 + or %o4, %o5, %o5 + EX_LD_FP(LOAD(lduh, %o1+5, %o4), memcpy_retl_o2_plus_o3) + sllx %o4, 8, %o4 + or %o4, %o5, %o5 + EX_LD_FP(LOAD(ldub, %o1+7, %o4), memcpy_retl_o2_plus_o3) + or %o4, %o5, %o5 + add %o0, %o1, %o0 + EX_ST_FP(STORE(stx, %o5, %o0), memcpy_retl_o2_plus_o3) + sub %o0, %o1, %o0 + subcc %o3, 8, %o3 + bnz %xcc, .Lunalignbyte_loop + add %o1, 8, %o1 + add %o0,%o1, %o0 ! restore pointer + + ! Destination is now block (64 byte aligned) +.Lunalignsrc: + andn %o2, 0x3f, %o5 ! %o5 is multiple of block size + and %o2, 0x3f, %o2 ! residue bytes in %o2 + add %o2, 64, %o2 ! Insure we do not load beyond + sub %o5, 64, %o5 ! end of source buffer + + andn %o1, 0x7, %o4 ! %o4 has long word aligned src address + alignaddr %o1, %g0, %g0 ! generate %gsr + add %o1, %o5, %o1 ! advance %o1 to after blocks + + EX_LD_FP(LOAD(ldd, %o4, %f14), memcpy_retl_o2_plus_o5) + add %o4, 8, %o4 +.Lunalign_sloop: + EX_LD_FP(LOAD(ldd, %o4, %f16), memcpy_retl_o2_plus_o5) + faligndata %f14, %f16, %f0 + EX_LD_FP(LOAD(ldd, %o4+8, %f18), memcpy_retl_o2_plus_o5) + faligndata %f16, %f18, %f2 + EX_LD_FP(LOAD(ldd, %o4+16, %f20), memcpy_retl_o2_plus_o5) + faligndata %f18, %f20, %f4 + EX_ST_FP(STORE(std, %f0, %o0), memcpy_retl_o2_plus_o5) + subcc %o5, 64, %o5 + EX_LD_FP(LOAD(ldd, %o4+24, %f22), memcpy_retl_o2_plus_o5_plus_56) + faligndata %f20, %f22, %f6 + EX_ST_FP(STORE(std, %f2, %o0+8), memcpy_retl_o2_plus_o5_plus_56) + EX_LD_FP(LOAD(ldd, %o4+32, %f24), memcpy_retl_o2_plus_o5_plus_48) + faligndata %f22, %f24, %f8 + EX_ST_FP(STORE(std, %f4, %o0+16), memcpy_retl_o2_plus_o5_plus_48) + EX_LD_FP(LOAD(ldd, %o4+40, %f26), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f24, %f26, %f10 + EX_ST_FP(STORE(std, %f6, %o0+24), memcpy_retl_o2_plus_o5_plus_40) + EX_LD_FP(LOAD(ldd, %o4+48, %f28), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f26, %f28, %f12 + EX_ST_FP(STORE(std, %f8, %o0+32), memcpy_retl_o2_plus_o5_plus_40) + add %o4, 64, %o4 + EX_LD_FP(LOAD(ldd, %o4-8, %f30), memcpy_retl_o2_plus_o5_plus_40) + faligndata %f28, %f30, %f14 + EX_ST_FP(STORE(std, %f10, %o0+40), memcpy_retl_o2_plus_o5_plus_40) + EX_ST_FP(STORE(std, %f12, %o0+48), memcpy_retl_o2_plus_o5_plus_40) + add %o0, 64, %o0 + EX_ST_FP(STORE(std, %f14, %o0-8), memcpy_retl_o2_plus_o5_plus_40) + fsrc2 %f30, %f14 + bgu,pt %xcc, .Lunalign_sloop + prefetch [%o4 + (8 * BLOCK_SIZE)], 20 + +.Lunalign_done: + ! Handle trailing bytes, 64 to 127 + ! Dest long word aligned, Src not long word aligned + cmp %o2, 15 + bleu %xcc, .Lunalign_short + + andn %o2, 0x7, %o5 ! %o5 is multiple of 8 + and %o2, 0x7, %o2 ! residue bytes in %o2 + add %o2, 8, %o2 + sub %o5, 8, %o5 ! insure we do not load past end of src + andn %o1, 0x7, %o4 ! %o4 has long word aligned src address + add %o1, %o5, %o1 ! advance %o1 to after multiple of 8 + EX_LD_FP(LOAD(ldd, %o4, %f0), memcpy_retl_o2_plus_o5)! fetch partialword +.Lunalign_by8: + EX_LD_FP(LOAD(ldd, %o4+8, %f2), memcpy_retl_o2_plus_o5) + add %o4, 8, %o4 + faligndata %f0, %f2, %f16 + subcc %o5, 8, %o5 + EX_ST_FP(STORE(std, %f16, %o0), memcpy_retl_o2_plus_o5) + fsrc2 %f2, %f0 + bgu,pt %xcc, .Lunalign_by8 + add %o0, 8, %o0 + +.Lunalign_short: +#ifdef NON_USER_COPY + VISExitHalfFast +#else + VISExitHalf +#endif + ba .Lsmallrest + nop + +/* + * This is a special case of nested memcpy. This can happen when kernel + * calls unaligned memcpy back to back without saving FP registers. We need + * traps(context switch) to save/restore FP registers. If the kernel calls + * memcpy without this trap sequence we will hit FP corruption. Let's use + * the normal integer load/store method in this case. + */ + +#ifdef NON_USER_COPY +.Lmedium_vis_entry_fail_cp: + or %o0, %o1, %g2 +#endif +.Lmedium_cp: + LOAD(prefetch, %o1 + 0x40, #n_reads_strong) + andcc %g2, 0x7, %g0 + bne,pn %xcc, .Lmedium_unaligned_cp + nop + +.Lmedium_noprefetch_cp: + andncc %o2, 0x20 - 1, %o5 + be,pn %xcc, 2f + sub %o2, %o5, %o2 +1: EX_LD(LOAD(ldx, %o1 + 0x00, %o3), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x08, %g2), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x10, %g7), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x18, %o4), memcpy_retl_o2_plus_o5) + add %o1, 0x20, %o1 + subcc %o5, 0x20, %o5 + EX_ST(STORE(stx, %o3, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) + EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, %g7, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) + bne,pt %xcc, 1b + add %o0, 0x20, %o0 +2: andcc %o2, 0x18, %o5 + be,pt %xcc, 3f + sub %o2, %o5, %o2 +1: EX_LD(LOAD(ldx, %o1 + 0x00, %o3), memcpy_retl_o2_plus_o5) + add %o1, 0x08, %o1 + add %o0, 0x08, %o0 + subcc %o5, 0x08, %o5 + bne,pt %xcc, 1b + EX_ST(STORE(stx, %o3, %o0 - 0x08), memcpy_retl_o2_plus_o5_plus_8) +3: brz,pt %o2, .Lexit_cp + cmp %o2, 0x04 + bl,pn %xcc, .Ltiny_cp + nop + EX_LD(LOAD(lduw, %o1 + 0x00, %o3), memcpy_retl_o2) + add %o1, 0x04, %o1 + add %o0, 0x04, %o0 + subcc %o2, 0x04, %o2 + bne,pn %xcc, .Ltiny_cp + EX_ST(STORE(stw, %o3, %o0 - 0x04), memcpy_retl_o2_plus_4) + ba,a,pt %xcc, .Lexit_cp + +.Lmedium_unaligned_cp: + /* First get dest 8 byte aligned. */ + sub %g0, %o0, %o3 + and %o3, 0x7, %o3 + brz,pt %o3, 2f + sub %o2, %o3, %o2 + +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) + add %o1, 1, %o1 + subcc %o3, 1, %o3 + add %o0, 1, %o0 + bne,pt %xcc, 1b + EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) +2: + and %o1, 0x7, %o3 + brz,pn %o3, .Lmedium_noprefetch_cp + sll %o3, 3, %o3 + mov 64, %g2 + sub %g2, %o3, %g2 + andn %o1, 0x7, %o1 + EX_LD(LOAD(ldx, %o1 + 0x00, %o4), memcpy_retl_o2) + sllx %o4, %o3, %o4 + andn %o2, 0x08 - 1, %o5 + sub %o2, %o5, %o2 + +1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), memcpy_retl_o2_plus_o5) + add %o1, 0x08, %o1 + subcc %o5, 0x08, %o5 + srlx %g3, %g2, %g7 + or %g7, %o4, %g7 + EX_ST(STORE(stx, %g7, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_8) + add %o0, 0x08, %o0 + bne,pt %xcc, 1b + sllx %g3, %o3, %o4 + srl %o3, 3, %o3 + add %o1, %o3, %o1 + brz,pn %o2, .Lexit_cp + nop + ba,pt %xcc, .Lsmall_unaligned_cp + +.Ltiny_cp: + EX_LD(LOAD(ldub, %o1 + 0x00, %o3), memcpy_retl_o2) + subcc %o2, 1, %o2 + be,pn %xcc, .Lexit_cp + EX_ST(STORE(stb, %o3, %o0 + 0x00), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x01, %o3), memcpy_retl_o2) + subcc %o2, 1, %o2 + be,pn %xcc, .Lexit_cp + EX_ST(STORE(stb, %o3, %o0 + 0x01), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x02, %o3), memcpy_retl_o2) + ba,pt %xcc, .Lexit_cp + EX_ST(STORE(stb, %o3, %o0 + 0x02), memcpy_retl_o2) + +.Lsmall_cp: + andcc %g2, 0x3, %g0 + bne,pn %xcc, .Lsmall_unaligned_cp + andn %o2, 0x4 - 1, %o5 + sub %o2, %o5, %o2 +1: + EX_LD(LOAD(lduw, %o1 + 0x00, %o3), memcpy_retl_o2_plus_o5) + add %o1, 0x04, %o1 + subcc %o5, 0x04, %o5 + add %o0, 0x04, %o0 + bne,pt %xcc, 1b + EX_ST(STORE(stw, %o3, %o0 - 0x04), memcpy_retl_o2_plus_o5_plus_4) + brz,pt %o2, .Lexit_cp + nop + ba,a,pt %xcc, .Ltiny_cp + +.Lsmall_unaligned_cp: +1: EX_LD(LOAD(ldub, %o1 + 0x00, %o3), memcpy_retl_o2) + add %o1, 1, %o1 + add %o0, 1, %o0 + subcc %o2, 1, %o2 + bne,pt %xcc, 1b + EX_ST(STORE(stb, %o3, %o0 - 0x01), memcpy_retl_o2_plus_1) + ba,a,pt %xcc, .Lexit_cp + +.Lsmallrest: + tst %o2 + bz,pt %xcc, .Lsmallx + cmp %o2, 4 + blt,pn %xcc, .Lsmallleft3 + nop + sub %o2, 3, %o2 +.Lsmallnotalign4: + EX_LD(LOAD(ldub, %o1, %o3), memcpy_retl_o2_plus_3)! read byte + subcc %o2, 4, %o2 ! reduce count by 4 + EX_ST(STORE(stb, %o3, %o0), memcpy_retl_o2_plus_7)! write byte & repeat + EX_LD(LOAD(ldub, %o1+1, %o3), memcpy_retl_o2_plus_6)! for total of 4 + add %o1, 4, %o1 ! advance SRC by 4 + EX_ST(STORE(stb, %o3, %o0+1), memcpy_retl_o2_plus_6) + EX_LD(LOAD(ldub, %o1-2, %o3), memcpy_retl_o2_plus_5) + add %o0, 4, %o0 ! advance DST by 4 + EX_ST(STORE(stb, %o3, %o0-2), memcpy_retl_o2_plus_5) + EX_LD(LOAD(ldub, %o1-1, %o3), memcpy_retl_o2_plus_4) + bgu,pt %xcc, .Lsmallnotalign4 ! loop til 3 or fewer bytes remain + EX_ST(STORE(stb, %o3, %o0-1), memcpy_retl_o2_plus_4) + addcc %o2, 3, %o2 ! restore count + bz,pt %xcc, .Lsmallx +.Lsmallleft3: ! 1, 2, or 3 bytes remain + subcc %o2, 1, %o2 + EX_LD(LOAD(ldub, %o1, %o3), memcpy_retl_o2_plus_1) ! load one byte + bz,pt %xcc, .Lsmallx + EX_ST(STORE(stb, %o3, %o0), memcpy_retl_o2_plus_1) ! store one byte + EX_LD(LOAD(ldub, %o1+1, %o3), memcpy_retl_o2) ! load second byte + subcc %o2, 1, %o2 + bz,pt %xcc, .Lsmallx + EX_ST(STORE(stb, %o3, %o0+1), memcpy_retl_o2_plus_1)! store second byte + EX_LD(LOAD(ldub, %o1+2, %o3), memcpy_retl_o2) ! load third byte + EX_ST(STORE(stb, %o3, %o0+2), memcpy_retl_o2) ! store third byte +.Lsmallx: + retl + mov EX_RETVAL(%g1), %o0 +.Lsmallfin: + tst %o2 + bnz,pn %xcc, .Lsmallleft3 + nop + retl + mov EX_RETVAL(%g1), %o0 ! restore %o0 +.Lexit_cp: + retl + mov EX_RETVAL(%g1), %o0 + .size FUNC_NAME, .-FUNC_NAME diff --git a/arch/sparc/lib/M7memset.S b/arch/sparc/lib/M7memset.S new file mode 100644 index 000000000000..62ea91b3a6b8 --- /dev/null +++ b/arch/sparc/lib/M7memset.S @@ -0,0 +1,352 @@ +/* + * M7memset.S: SPARC M7 optimized memset. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + +/* + * M7memset.S: M7 optimized memset. + * + * char *memset(sp, c, n) + * + * Set an array of n chars starting at sp to the character c. + * Return sp. + * + * Fast assembler language version of the following C-program for memset + * which represents the `standard' for the C-library. + * + * void * + * memset(void *sp1, int c, size_t n) + * { + * if (n != 0) { + * char *sp = sp1; + * do { + * *sp++ = (char)c; + * } while (--n != 0); + * } + * return (sp1); + * } + * + * The algorithm is as follows : + * + * For small 6 or fewer bytes stores, bytes will be stored. + * + * For less than 32 bytes stores, align the address on 4 byte boundary. + * Then store as many 4-byte chunks, followed by trailing bytes. + * + * For sizes greater than 32 bytes, align the address on 8 byte boundary. + * if (count >= 64) { + * store 8-bytes chunks to align the address on 64 byte boundary + * if (value to be set is zero && count >= MIN_ZERO) { + * Using BIS stores, set the first long word of each + * 64-byte cache line to zero which will also clear the + * other seven long words of the cache line. + * } + * else if (count >= MIN_LOOP) { + * Using BIS stores, set the first long word of each of + * ST_CHUNK cache lines (64 bytes each) before the main + * loop is entered. + * In the main loop, continue pre-setting the first long + * word of each cache line ST_CHUNK lines in advance while + * setting the other seven long words (56 bytes) of each + * cache line until fewer than ST_CHUNK*64 bytes remain. + * Then set the remaining seven long words of each cache + * line that has already had its first long word set. + * } + * store remaining data in 64-byte chunks until less than + * 64 bytes remain. + * } + * Store as many 8-byte chunks, followed by trailing bytes. + * + * BIS = Block Init Store + * Doing the advance store of the first element of the cache line + * initiates the displacement of a cache line while only using a single + * instruction in the pipeline. That avoids various pipeline delays, + * such as filling the miss buffer. The performance effect is + * similar to prefetching for normal stores. + * The special case for zero fills runs faster and uses fewer instruction + * cycles than the normal memset loop. + * + * We only use BIS for memset of greater than MIN_LOOP bytes because a sequence + * BIS stores must be followed by a membar #StoreStore. The benefit of + * the BIS store must be balanced against the cost of the membar operation. + */ + +/* + * ASI_STBI_P marks the cache line as "least recently used" + * which means if many threads are active, it has a high chance + * of being pushed out of the cache between the first initializing + * store and the final stores. + * Thus, we use ASI_STBIMRU_P which marks the cache line as + * "most recently used" for all but the last store to the cache line. + */ + +#include +#include + +#define ASI_STBI_P ASI_BLK_INIT_QUAD_LDD_P +#define ASI_STBIMRU_P ASI_ST_BLKINIT_MRU_P + + +#define ST_CHUNK 24 /* multiple of 4 due to loop unrolling */ +#define MIN_LOOP 16320 +#define MIN_ZERO 512 + + .section ".text" + .align 32 + +/* + * Define clear_page(dest) as memset(dest, 0, PAGE_SIZE) + * (can create a more optimized version later.) + */ + .globl M7clear_page + .globl M7clear_user_page +M7clear_page: /* clear_page(dest) */ +M7clear_user_page: + set PAGE_SIZE, %o1 + /* fall through into bzero code */ + + .size M7clear_page,.-M7clear_page + .size M7clear_user_page,.-M7clear_user_page + +/* + * Define bzero(dest, n) as memset(dest, 0, n) + * (can create a more optimized version later.) + */ + .globl M7bzero +M7bzero: /* bzero(dest, size) */ + mov %o1, %o2 + mov 0, %o1 + /* fall through into memset code */ + + .size M7bzero,.-M7bzero + + .global M7memset + .type M7memset, #function + .register %g3, #scratch +M7memset: + mov %o0, %o5 ! copy sp1 before using it + cmp %o2, 7 ! if small counts, just write bytes + bleu,pn %xcc, .wrchar + and %o1, 0xff, %o1 ! o1 is (char)c + + sll %o1, 8, %o3 + or %o1, %o3, %o1 ! now o1 has 2 bytes of c + sll %o1, 16, %o3 + cmp %o2, 32 + blu,pn %xcc, .wdalign + or %o1, %o3, %o1 ! now o1 has 4 bytes of c + + sllx %o1, 32, %o3 + or %o1, %o3, %o1 ! now o1 has 8 bytes of c + +.dbalign: + andcc %o5, 7, %o3 ! is sp1 aligned on a 8 byte bound? + bz,pt %xcc, .blkalign ! already long word aligned + sub %o3, 8, %o3 ! -(bytes till long word aligned) + + add %o2, %o3, %o2 ! update o2 with new count + ! Set -(%o3) bytes till sp1 long word aligned +1: stb %o1, [%o5] ! there is at least 1 byte to set + inccc %o3 ! byte clearing loop + bl,pt %xcc, 1b + inc %o5 + + ! Now sp1 is long word aligned (sp1 is found in %o5) +.blkalign: + cmp %o2, 64 ! check if there are 64 bytes to set + blu,pn %xcc, .wrshort + mov %o2, %o3 + + andcc %o5, 63, %o3 ! is sp1 block aligned? + bz,pt %xcc, .blkwr ! now block aligned + sub %o3, 64, %o3 ! o3 is -(bytes till block aligned) + add %o2, %o3, %o2 ! o2 is the remainder + + ! Store -(%o3) bytes till dst is block (64 byte) aligned. + ! Use long word stores. + ! Recall that dst is already long word aligned +1: + addcc %o3, 8, %o3 + stx %o1, [%o5] + bl,pt %xcc, 1b + add %o5, 8, %o5 + + ! Now sp1 is block aligned +.blkwr: + andn %o2, 63, %o4 ! calculate size of blocks in bytes + brz,pn %o1, .wrzero ! special case if c == 0 + and %o2, 63, %o3 ! %o3 = bytes left after blk stores. + + set MIN_LOOP, %g1 + cmp %o4, %g1 ! check there are enough bytes to set + blu,pn %xcc, .short_set ! to justify cost of membar + ! must be > pre-cleared lines + nop + + ! initial cache-clearing stores + ! get store pipeline moving + rd %asi, %g3 ! save %asi to be restored later + wr %g0, ASI_STBIMRU_P, %asi + + ! Primary memset loop for large memsets +.wr_loop: + sub %o5, 8, %o5 ! adjust %o5 for ASI store alignment + mov ST_CHUNK, %g1 +.wr_loop_start: + stxa %o1, [%o5+8]%asi + subcc %g1, 4, %g1 + stxa %o1, [%o5+8+64]%asi + add %o5, 256, %o5 + stxa %o1, [%o5+8-128]%asi + bgu %xcc, .wr_loop_start + stxa %o1, [%o5+8-64]%asi + + sub %o5, ST_CHUNK*64, %o5 ! reset %o5 + mov ST_CHUNK, %g1 + +.wr_loop_rest: + stxa %o1, [%o5+8+8]%asi + sub %o4, 64, %o4 + stxa %o1, [%o5+16+8]%asi + subcc %g1, 1, %g1 + stxa %o1, [%o5+24+8]%asi + stxa %o1, [%o5+32+8]%asi + stxa %o1, [%o5+40+8]%asi + add %o5, 64, %o5 + stxa %o1, [%o5-8]%asi + bgu %xcc, .wr_loop_rest + stxa %o1, [%o5]ASI_STBI_P + + ! If more than ST_CHUNK*64 bytes remain to set, continue + ! setting the first long word of each cache line in advance + ! to keep the store pipeline moving. + + cmp %o4, ST_CHUNK*64 + bge,pt %xcc, .wr_loop_start + mov ST_CHUNK, %g1 + + brz,a,pn %o4, .asi_done + add %o5, 8, %o5 ! restore %o5 offset + +.wr_loop_small: + stxa %o1, [%o5+8]%asi + stxa %o1, [%o5+8+8]%asi + stxa %o1, [%o5+16+8]%asi + stxa %o1, [%o5+24+8]%asi + stxa %o1, [%o5+32+8]%asi + subcc %o4, 64, %o4 + stxa %o1, [%o5+40+8]%asi + add %o5, 64, %o5 + stxa %o1, [%o5-8]%asi + bgu,pt %xcc, .wr_loop_small + stxa %o1, [%o5]ASI_STBI_P + + ba .asi_done + add %o5, 8, %o5 ! restore %o5 offset + + ! Special case loop for zero fill memsets + ! For each 64 byte cache line, single STBI to first element + ! clears line +.wrzero: + cmp %o4, MIN_ZERO ! check if enough bytes to set + ! to pay %asi + membar cost + blu %xcc, .short_set + nop + sub %o4, 256, %o4 + +.wrzero_loop: + mov 64, %g3 + stxa %o1, [%o5]ASI_STBI_P + subcc %o4, 256, %o4 + stxa %o1, [%o5+%g3]ASI_STBI_P + add %o5, 256, %o5 + sub %g3, 192, %g3 + stxa %o1, [%o5+%g3]ASI_STBI_P + add %g3, 64, %g3 + bge,pt %xcc, .wrzero_loop + stxa %o1, [%o5+%g3]ASI_STBI_P + add %o4, 256, %o4 + + brz,pn %o4, .bsi_done + nop + +.wrzero_small: + stxa %o1, [%o5]ASI_STBI_P + subcc %o4, 64, %o4 + bgu,pt %xcc, .wrzero_small + add %o5, 64, %o5 + ba,a .bsi_done + +.asi_done: + wr %g3, 0x0, %asi ! restored saved %asi +.bsi_done: + membar #StoreStore ! required by use of Block Store Init + +.short_set: + cmp %o4, 64 ! check if 64 bytes to set + blu %xcc, 5f + nop +4: ! set final blocks of 64 bytes + stx %o1, [%o5] + stx %o1, [%o5+8] + stx %o1, [%o5+16] + stx %o1, [%o5+24] + subcc %o4, 64, %o4 + stx %o1, [%o5+32] + stx %o1, [%o5+40] + add %o5, 64, %o5 + stx %o1, [%o5-16] + bgu,pt %xcc, 4b + stx %o1, [%o5-8] + +5: + ! Set the remaining long words +.wrshort: + subcc %o3, 8, %o3 ! Can we store any long words? + blu,pn %xcc, .wrchars + and %o2, 7, %o2 ! calc bytes left after long words +6: + subcc %o3, 8, %o3 + stx %o1, [%o5] ! store the long words + bgeu,pt %xcc, 6b + add %o5, 8, %o5 + +.wrchars: ! check for extra chars + brnz %o2, .wrfin + nop + retl + nop + +.wdalign: + andcc %o5, 3, %o3 ! is sp1 aligned on a word boundary + bz,pn %xcc, .wrword + andn %o2, 3, %o3 ! create word sized count in %o3 + + dec %o2 ! decrement count + stb %o1, [%o5] ! clear a byte + b .wdalign + inc %o5 ! next byte + +.wrword: + subcc %o3, 4, %o3 + st %o1, [%o5] ! 4-byte writing loop + bnz,pt %xcc, .wrword + add %o5, 4, %o5 + + and %o2, 3, %o2 ! leftover count, if any + +.wrchar: + ! Set the remaining bytes, if any + brz %o2, .exit + nop +.wrfin: + deccc %o2 + stb %o1, [%o5] + bgu,pt %xcc, .wrfin + inc %o5 +.exit: + retl ! %o0 was preserved + nop + + .size M7memset,.-M7memset diff --git a/arch/sparc/lib/M7patch.S b/arch/sparc/lib/M7patch.S new file mode 100644 index 000000000000..9000b7bc5f2b --- /dev/null +++ b/arch/sparc/lib/M7patch.S @@ -0,0 +1,51 @@ +/* + * M7patch.S: Patch generic routines with M7 variant. + * + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + */ + +#include + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + +ENTRY(m7_patch_copyops) + NG_DO_PATCH(memcpy, M7memcpy) + NG_DO_PATCH(raw_copy_from_user, M7copy_from_user) + NG_DO_PATCH(raw_copy_to_user, M7copy_to_user) + retl + nop +ENDPROC(m7_patch_copyops) + +ENTRY(m7_patch_bzero) + NG_DO_PATCH(memset, M7memset) + NG_DO_PATCH(__bzero, M7bzero) + NG_DO_PATCH(__clear_user, NGclear_user) + NG_DO_PATCH(tsb_init, NGtsb_init) + retl + nop +ENDPROC(m7_patch_bzero) + +ENTRY(m7_patch_pageops) + NG_DO_PATCH(copy_user_page, NG4copy_user_page) + NG_DO_PATCH(_clear_page, M7clear_page) + NG_DO_PATCH(clear_user_page, M7clear_user_page) + retl + nop +ENDPROC(m7_patch_pageops) diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 07c03e72d812..44829a8dc458 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for Sparc library files.. # @@ -36,6 +37,11 @@ lib-$(CONFIG_SPARC64) += NG2patch.o lib-$(CONFIG_SPARC64) += NG4memcpy.o NG4copy_from_user.o NG4copy_to_user.o lib-$(CONFIG_SPARC64) += NG4patch.o NG4copy_page.o NG4clear_page.o NG4memset.o +lib-$(CONFIG_SPARC64) += Memcpy_utils.o + +lib-$(CONFIG_SPARC64) += M7memcpy.o M7copy_from_user.o M7copy_to_user.o +lib-$(CONFIG_SPARC64) += M7patch.o M7memset.o + lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o diff --git a/arch/sparc/lib/Memcpy_utils.S b/arch/sparc/lib/Memcpy_utils.S new file mode 100644 index 000000000000..64fbac28b3db --- /dev/null +++ b/arch/sparc/lib/Memcpy_utils.S @@ -0,0 +1,345 @@ +#ifndef __ASM_MEMCPY_UTILS +#define __ASM_MEMCPY_UTILS + +#include +#include +#include + +ENTRY(__restore_asi_fp) + VISExitHalf + retl + wr %g0, ASI_AIUS, %asi +ENDPROC(__restore_asi_fp) + +ENTRY(__restore_asi) + retl + wr %g0, ASI_AIUS, %asi +ENDPROC(__restore_asi) + +ENTRY(memcpy_retl_o2) + ba,pt %xcc, __restore_asi + mov %o2, %o0 +ENDPROC(memcpy_retl_o2) +ENTRY(memcpy_retl_o2_plus_1) + ba,pt %xcc, __restore_asi + add %o2, 1, %o0 +ENDPROC(memcpy_retl_o2_plus_1) +ENTRY(memcpy_retl_o2_plus_3) + ba,pt %xcc, __restore_asi + add %o2, 3, %o0 +ENDPROC(memcpy_retl_o2_plus_3) +ENTRY(memcpy_retl_o2_plus_4) + ba,pt %xcc, __restore_asi + add %o2, 4, %o0 +ENDPROC(memcpy_retl_o2_plus_4) +ENTRY(memcpy_retl_o2_plus_5) + ba,pt %xcc, __restore_asi + add %o2, 5, %o0 +ENDPROC(memcpy_retl_o2_plus_5) +ENTRY(memcpy_retl_o2_plus_6) + ba,pt %xcc, __restore_asi + add %o2, 6, %o0 +ENDPROC(memcpy_retl_o2_plus_6) +ENTRY(memcpy_retl_o2_plus_7) + ba,pt %xcc, __restore_asi + add %o2, 7, %o0 +ENDPROC(memcpy_retl_o2_plus_7) +ENTRY(memcpy_retl_o2_plus_8) + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_8) +ENTRY(memcpy_retl_o2_plus_15) + ba,pt %xcc, __restore_asi + add %o2, 15, %o0 +ENDPROC(memcpy_retl_o2_plus_15) +ENTRY(memcpy_retl_o2_plus_15_8) + add %o2, 15, %o2 + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_15_8) +ENTRY(memcpy_retl_o2_plus_16) + ba,pt %xcc, __restore_asi + add %o2, 16, %o0 +ENDPROC(memcpy_retl_o2_plus_16) +ENTRY(memcpy_retl_o2_plus_24) + ba,pt %xcc, __restore_asi + add %o2, 24, %o0 +ENDPROC(memcpy_retl_o2_plus_24) +ENTRY(memcpy_retl_o2_plus_31) + ba,pt %xcc, __restore_asi + add %o2, 31, %o0 +ENDPROC(memcpy_retl_o2_plus_31) +ENTRY(memcpy_retl_o2_plus_32) + ba,pt %xcc, __restore_asi + add %o2, 32, %o0 +ENDPROC(memcpy_retl_o2_plus_32) +ENTRY(memcpy_retl_o2_plus_31_32) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 32, %o0 +ENDPROC(memcpy_retl_o2_plus_31_32) +ENTRY(memcpy_retl_o2_plus_31_24) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 24, %o0 +ENDPROC(memcpy_retl_o2_plus_31_24) +ENTRY(memcpy_retl_o2_plus_31_16) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 16, %o0 +ENDPROC(memcpy_retl_o2_plus_31_16) +ENTRY(memcpy_retl_o2_plus_31_8) + add %o2, 31, %o2 + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_31_8) +ENTRY(memcpy_retl_o2_plus_63) + ba,pt %xcc, __restore_asi + add %o2, 63, %o0 +ENDPROC(memcpy_retl_o2_plus_63) +ENTRY(memcpy_retl_o2_plus_63_64) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 64, %o0 +ENDPROC(memcpy_retl_o2_plus_63_64) +ENTRY(memcpy_retl_o2_plus_63_56) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 56, %o0 +ENDPROC(memcpy_retl_o2_plus_63_56) +ENTRY(memcpy_retl_o2_plus_63_48) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 48, %o0 +ENDPROC(memcpy_retl_o2_plus_63_48) +ENTRY(memcpy_retl_o2_plus_63_40) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 40, %o0 +ENDPROC(memcpy_retl_o2_plus_63_40) +ENTRY(memcpy_retl_o2_plus_63_32) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 32, %o0 +ENDPROC(memcpy_retl_o2_plus_63_32) +ENTRY(memcpy_retl_o2_plus_63_24) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 24, %o0 +ENDPROC(memcpy_retl_o2_plus_63_24) +ENTRY(memcpy_retl_o2_plus_63_16) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 16, %o0 +ENDPROC(memcpy_retl_o2_plus_63_16) +ENTRY(memcpy_retl_o2_plus_63_8) + add %o2, 63, %o2 + ba,pt %xcc, __restore_asi + add %o2, 8, %o0 +ENDPROC(memcpy_retl_o2_plus_63_8) +ENTRY(memcpy_retl_o2_plus_o5) + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5) +ENTRY(memcpy_retl_o2_plus_o5_plus_1) + add %o5, 1, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_1) +ENTRY(memcpy_retl_o2_plus_o5_plus_4) + add %o5, 4, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_4) +ENTRY(memcpy_retl_o2_plus_o5_plus_8) + add %o5, 8, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_8) +ENTRY(memcpy_retl_o2_plus_o5_plus_16) + add %o5, 16, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_16) +ENTRY(memcpy_retl_o2_plus_o5_plus_24) + add %o5, 24, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_24) +ENTRY(memcpy_retl_o2_plus_o5_plus_32) + add %o5, 32, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_32) +ENTRY(memcpy_retl_o2_plus_o5_64) + add %o5, 32, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_64) +ENTRY(memcpy_retl_o2_plus_g1) + ba,pt %xcc, __restore_asi + add %o2, %g1, %o0 +ENDPROC(memcpy_retl_o2_plus_g1) +ENTRY(memcpy_retl_o2_plus_g1_plus_1) + add %g1, 1, %g1 + ba,pt %xcc, __restore_asi + add %o2, %g1, %o0 +ENDPROC(memcpy_retl_o2_plus_g1_plus_1) +ENTRY(memcpy_retl_o2_plus_g1_plus_8) + add %g1, 8, %g1 + ba,pt %xcc, __restore_asi + add %o2, %g1, %o0 +ENDPROC(memcpy_retl_o2_plus_g1_plus_8) +ENTRY(memcpy_retl_o2_plus_o4) + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4) +ENTRY(memcpy_retl_o2_plus_o4_plus_8) + add %o4, 8, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_8) +ENTRY(memcpy_retl_o2_plus_o4_plus_16) + add %o4, 16, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_16) +ENTRY(memcpy_retl_o2_plus_o4_plus_24) + add %o4, 24, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_24) +ENTRY(memcpy_retl_o2_plus_o4_plus_32) + add %o4, 32, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_32) +ENTRY(memcpy_retl_o2_plus_o4_plus_40) + add %o4, 40, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_40) +ENTRY(memcpy_retl_o2_plus_o4_plus_48) + add %o4, 48, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_48) +ENTRY(memcpy_retl_o2_plus_o4_plus_56) + add %o4, 56, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_56) +ENTRY(memcpy_retl_o2_plus_o4_plus_64) + add %o4, 64, %o4 + ba,pt %xcc, __restore_asi + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_64) +ENTRY(memcpy_retl_o2_plus_o5_plus_64) + add %o5, 64, %o5 + ba,pt %xcc, __restore_asi + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_64) +ENTRY(memcpy_retl_o2_plus_o3_fp) + ba,pt %xcc, __restore_asi_fp + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3_fp) +ENTRY(memcpy_retl_o2_plus_o3_plus_1_fp) + add %o3, 1, %o3 + ba,pt %xcc, __restore_asi_fp + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3_plus_1_fp) +ENTRY(memcpy_retl_o2_plus_o3_plus_4_fp) + add %o3, 4, %o3 + ba,pt %xcc, __restore_asi_fp + add %o2, %o3, %o0 +ENDPROC(memcpy_retl_o2_plus_o3_plus_4_fp) +ENTRY(memcpy_retl_o2_plus_o4_fp) + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_8_fp) + add %o4, 8, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_8_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_16_fp) + add %o4, 16, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_16_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_24_fp) + add %o4, 24, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_24_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_32_fp) + add %o4, 32, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_32_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_40_fp) + add %o4, 40, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_40_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_48_fp) + add %o4, 48, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_48_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_56_fp) + add %o4, 56, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_56_fp) +ENTRY(memcpy_retl_o2_plus_o4_plus_64_fp) + add %o4, 64, %o4 + ba,pt %xcc, __restore_asi_fp + add %o2, %o4, %o0 +ENDPROC(memcpy_retl_o2_plus_o4_plus_64_fp) +ENTRY(memcpy_retl_o2_plus_o5_fp) + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_64_fp) + add %o5, 64, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_64_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_56_fp) + add %o5, 56, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_56_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_48_fp) + add %o5, 48, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_48_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_40_fp) + add %o5, 40, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_40_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_32_fp) + add %o5, 32, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_32_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_24_fp) + add %o5, 24, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_24_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_16_fp) + add %o5, 16, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_16_fp) +ENTRY(memcpy_retl_o2_plus_o5_plus_8_fp) + add %o5, 8, %o5 + ba,pt %xcc, __restore_asi_fp + add %o2, %o5, %o0 +ENDPROC(memcpy_retl_o2_plus_o5_plus_8_fp) + +#endif diff --git a/arch/sparc/lib/NG2copy_from_user.S b/arch/sparc/lib/NG2copy_from_user.S index 0d8a018118c2..e57bc514f538 100644 --- a/arch/sparc/lib/NG2copy_from_user.S +++ b/arch/sparc/lib/NG2copy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG2copy_from_user.S: Niagara-2 optimized copy from userspace. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NG2copy_to_user.S b/arch/sparc/lib/NG2copy_to_user.S index a7a0ea0d8a0b..367c0bf01518 100644 --- a/arch/sparc/lib/NG2copy_to_user.S +++ b/arch/sparc/lib/NG2copy_to_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG2copy_to_user.S: Niagara-2 optimized copy to userspace. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S index 64dcd6cdb606..bcb21b3a82f1 100644 --- a/arch/sparc/lib/NG2memcpy.S +++ b/arch/sparc/lib/NG2memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG2memcpy.S: Niagara-2 optimized memcpy. * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NG2patch.S b/arch/sparc/lib/NG2patch.S index 56ccc19adde8..72431b24491a 100644 --- a/arch/sparc/lib/NG2patch.S +++ b/arch/sparc/lib/NG2patch.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG2patch.S: Patch Ultra-I routines with Niagara-2 variant. * * Copyright (C) 2007 David S. Miller diff --git a/arch/sparc/lib/NG4clear_page.S b/arch/sparc/lib/NG4clear_page.S index e16c88204a42..97e2678d042a 100644 --- a/arch/sparc/lib/NG4clear_page.S +++ b/arch/sparc/lib/NG4clear_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG4copy_page.S: Niagara-4 optimized clear page. * * Copyright (C) 2012 (davem@davemloft.net) diff --git a/arch/sparc/lib/NG4copy_from_user.S b/arch/sparc/lib/NG4copy_from_user.S index 5bb506bd61fa..0cac15a6db3c 100644 --- a/arch/sparc/lib/NG4copy_from_user.S +++ b/arch/sparc/lib/NG4copy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG4copy_from_user.S: Niagara-4 optimized copy from userspace. * * Copyright (C) 2012 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NG4copy_page.S b/arch/sparc/lib/NG4copy_page.S index 28504e88c535..581062f8ba5f 100644 --- a/arch/sparc/lib/NG4copy_page.S +++ b/arch/sparc/lib/NG4copy_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG4copy_page.S: Niagara-4 optimized copy page. * * Copyright (C) 2012 (davem@davemloft.net) diff --git a/arch/sparc/lib/NG4copy_to_user.S b/arch/sparc/lib/NG4copy_to_user.S index a82d4d45fc1c..c5c9abb3cb77 100644 --- a/arch/sparc/lib/NG4copy_to_user.S +++ b/arch/sparc/lib/NG4copy_to_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG4copy_to_user.S: Niagara-4 optimized copy to userspace. * * Copyright (C) 2012 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S index 78ea962edcbe..7ad58ebe0d00 100644 --- a/arch/sparc/lib/NG4memcpy.S +++ b/arch/sparc/lib/NG4memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG4memcpy.S: Niagara-4 optimized memcpy. * * Copyright (C) 2012 David S. Miller (davem@davemloft.net) @@ -94,155 +95,6 @@ .text #ifndef EX_RETVAL #define EX_RETVAL(x) x -__restore_asi_fp: - VISExitHalf -__restore_asi: - retl - wr %g0, ASI_AIUS, %asi - -ENTRY(NG4_retl_o2) - ba,pt %xcc, __restore_asi - mov %o2, %o0 -ENDPROC(NG4_retl_o2) -ENTRY(NG4_retl_o2_plus_1) - ba,pt %xcc, __restore_asi - add %o2, 1, %o0 -ENDPROC(NG4_retl_o2_plus_1) -ENTRY(NG4_retl_o2_plus_4) - ba,pt %xcc, __restore_asi - add %o2, 4, %o0 -ENDPROC(NG4_retl_o2_plus_4) -ENTRY(NG4_retl_o2_plus_o5) - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5) -ENTRY(NG4_retl_o2_plus_o5_plus_4) - add %o5, 4, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_4) -ENTRY(NG4_retl_o2_plus_o5_plus_8) - add %o5, 8, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_8) -ENTRY(NG4_retl_o2_plus_o5_plus_16) - add %o5, 16, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_16) -ENTRY(NG4_retl_o2_plus_o5_plus_24) - add %o5, 24, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_24) -ENTRY(NG4_retl_o2_plus_o5_plus_32) - add %o5, 32, %o5 - ba,pt %xcc, __restore_asi - add %o2, %o5, %o0 -ENDPROC(NG4_retl_o2_plus_o5_plus_32) -ENTRY(NG4_retl_o2_plus_g1) - ba,pt %xcc, __restore_asi - add %o2, %g1, %o0 -ENDPROC(NG4_retl_o2_plus_g1) -ENTRY(NG4_retl_o2_plus_g1_plus_1) - add %g1, 1, %g1 - ba,pt %xcc, __restore_asi - add %o2, %g1, %o0 -ENDPROC(NG4_retl_o2_plus_g1_plus_1) -ENTRY(NG4_retl_o2_plus_g1_plus_8) - add %g1, 8, %g1 - ba,pt %xcc, __restore_asi - add %o2, %g1, %o0 -ENDPROC(NG4_retl_o2_plus_g1_plus_8) -ENTRY(NG4_retl_o2_plus_o4) - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4) -ENTRY(NG4_retl_o2_plus_o4_plus_8) - add %o4, 8, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_8) -ENTRY(NG4_retl_o2_plus_o4_plus_16) - add %o4, 16, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_16) -ENTRY(NG4_retl_o2_plus_o4_plus_24) - add %o4, 24, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_24) -ENTRY(NG4_retl_o2_plus_o4_plus_32) - add %o4, 32, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_32) -ENTRY(NG4_retl_o2_plus_o4_plus_40) - add %o4, 40, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_40) -ENTRY(NG4_retl_o2_plus_o4_plus_48) - add %o4, 48, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_48) -ENTRY(NG4_retl_o2_plus_o4_plus_56) - add %o4, 56, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_56) -ENTRY(NG4_retl_o2_plus_o4_plus_64) - add %o4, 64, %o4 - ba,pt %xcc, __restore_asi - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_64) -ENTRY(NG4_retl_o2_plus_o4_fp) - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_8_fp) - add %o4, 8, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_8_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_16_fp) - add %o4, 16, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_16_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_24_fp) - add %o4, 24, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_24_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_32_fp) - add %o4, 32, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_32_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_40_fp) - add %o4, 40, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_40_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_48_fp) - add %o4, 48, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_48_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_56_fp) - add %o4, 56, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_56_fp) -ENTRY(NG4_retl_o2_plus_o4_plus_64_fp) - add %o4, 64, %o4 - ba,pt %xcc, __restore_asi_fp - add %o2, %o4, %o0 -ENDPROC(NG4_retl_o2_plus_o4_plus_64_fp) #endif .align 64 @@ -275,12 +127,12 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ sub %o2, %g1, %o2 -1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) add %o1, 1, %o1 subcc %g1, 1, %g1 add %o0, 1, %o0 bne,pt %icc, 1b - EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1) + EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) 51: LOAD(prefetch, %o1 + 0x040, #n_reads_strong) LOAD(prefetch, %o1 + 0x080, #n_reads_strong) @@ -305,43 +157,43 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ brz,pt %g1, .Llarge_aligned sub %o2, %g1, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) add %o1, 8, %o1 subcc %g1, 8, %g1 add %o0, 8, %o0 bne,pt %icc, 1b - EX_ST(STORE(stx, %g2, %o0 - 0x08), NG4_retl_o2_plus_g1_plus_8) + EX_ST(STORE(stx, %g2, %o0 - 0x08), memcpy_retl_o2_plus_g1_plus_8) .Llarge_aligned: /* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */ andn %o2, 0x3f, %o4 sub %o2, %o4, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o4) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o4) add %o1, 0x40, %o1 - EX_LD(LOAD(ldx, %o1 - 0x38, %g2), NG4_retl_o2_plus_o4) + EX_LD(LOAD(ldx, %o1 - 0x38, %g2), memcpy_retl_o2_plus_o4) subcc %o4, 0x40, %o4 - EX_LD(LOAD(ldx, %o1 - 0x30, %g3), NG4_retl_o2_plus_o4_plus_64) - EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_64) - EX_LD(LOAD(ldx, %o1 - 0x20, %o5), NG4_retl_o2_plus_o4_plus_64) - EX_ST(STORE_INIT(%g1, %o0), NG4_retl_o2_plus_o4_plus_64) + EX_LD(LOAD(ldx, %o1 - 0x30, %g3), memcpy_retl_o2_plus_o4_plus_64) + EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), memcpy_retl_o2_plus_o4_plus_64) + EX_LD(LOAD(ldx, %o1 - 0x20, %o5), memcpy_retl_o2_plus_o4_plus_64) + EX_ST(STORE_INIT(%g1, %o0), memcpy_retl_o2_plus_o4_plus_64) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_56) + EX_ST(STORE_INIT(%g2, %o0), memcpy_retl_o2_plus_o4_plus_56) add %o0, 0x08, %o0 - EX_LD(LOAD(ldx, %o1 - 0x18, %g2), NG4_retl_o2_plus_o4_plus_48) - EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_48) + EX_LD(LOAD(ldx, %o1 - 0x18, %g2), memcpy_retl_o2_plus_o4_plus_48) + EX_ST(STORE_INIT(%g3, %o0), memcpy_retl_o2_plus_o4_plus_48) add %o0, 0x08, %o0 - EX_LD(LOAD(ldx, %o1 - 0x10, %g3), NG4_retl_o2_plus_o4_plus_40) - EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_40) + EX_LD(LOAD(ldx, %o1 - 0x10, %g3), memcpy_retl_o2_plus_o4_plus_40) + EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), memcpy_retl_o2_plus_o4_plus_40) add %o0, 0x08, %o0 - EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_32) - EX_ST(STORE_INIT(%o5, %o0), NG4_retl_o2_plus_o4_plus_32) + EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), memcpy_retl_o2_plus_o4_plus_32) + EX_ST(STORE_INIT(%o5, %o0), memcpy_retl_o2_plus_o4_plus_32) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_24) + EX_ST(STORE_INIT(%g2, %o0), memcpy_retl_o2_plus_o4_plus_24) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_16) + EX_ST(STORE_INIT(%g3, %o0), memcpy_retl_o2_plus_o4_plus_16) add %o0, 0x08, %o0 - EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_8) + EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), memcpy_retl_o2_plus_o4_plus_8) add %o0, 0x08, %o0 bne,pt %icc, 1b LOAD(prefetch, %o1 + 0x200, #n_reads_strong) @@ -367,17 +219,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ sub %o2, %o4, %o2 alignaddr %o1, %g0, %g1 add %o1, %o4, %o1 - EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), NG4_retl_o2_plus_o4) -1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), NG4_retl_o2_plus_o4) + EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), memcpy_retl_o2_plus_o4) +1: EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), memcpy_retl_o2_plus_o4) subcc %o4, 0x40, %o4 - EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), NG4_retl_o2_plus_o4_plus_64) - EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), NG4_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), memcpy_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), memcpy_retl_o2_plus_o4_plus_64) faligndata %f0, %f2, %f16 - EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), NG4_retl_o2_plus_o4_plus_64) + EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), memcpy_retl_o2_plus_o4_plus_64) faligndata %f2, %f4, %f18 add %g1, 0x40, %g1 faligndata %f4, %f6, %f20 @@ -386,14 +238,14 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ faligndata %f10, %f12, %f26 faligndata %f12, %f14, %f28 faligndata %f14, %f0, %f30 - EX_ST_FP(STORE(std, %f16, %o0 + 0x00), NG4_retl_o2_plus_o4_plus_64) - EX_ST_FP(STORE(std, %f18, %o0 + 0x08), NG4_retl_o2_plus_o4_plus_56) - EX_ST_FP(STORE(std, %f20, %o0 + 0x10), NG4_retl_o2_plus_o4_plus_48) - EX_ST_FP(STORE(std, %f22, %o0 + 0x18), NG4_retl_o2_plus_o4_plus_40) - EX_ST_FP(STORE(std, %f24, %o0 + 0x20), NG4_retl_o2_plus_o4_plus_32) - EX_ST_FP(STORE(std, %f26, %o0 + 0x28), NG4_retl_o2_plus_o4_plus_24) - EX_ST_FP(STORE(std, %f28, %o0 + 0x30), NG4_retl_o2_plus_o4_plus_16) - EX_ST_FP(STORE(std, %f30, %o0 + 0x38), NG4_retl_o2_plus_o4_plus_8) + EX_ST_FP(STORE(std, %f16, %o0 + 0x00), memcpy_retl_o2_plus_o4_plus_64) + EX_ST_FP(STORE(std, %f18, %o0 + 0x08), memcpy_retl_o2_plus_o4_plus_56) + EX_ST_FP(STORE(std, %f20, %o0 + 0x10), memcpy_retl_o2_plus_o4_plus_48) + EX_ST_FP(STORE(std, %f22, %o0 + 0x18), memcpy_retl_o2_plus_o4_plus_40) + EX_ST_FP(STORE(std, %f24, %o0 + 0x20), memcpy_retl_o2_plus_o4_plus_32) + EX_ST_FP(STORE(std, %f26, %o0 + 0x28), memcpy_retl_o2_plus_o4_plus_24) + EX_ST_FP(STORE(std, %f28, %o0 + 0x30), memcpy_retl_o2_plus_o4_plus_16) + EX_ST_FP(STORE(std, %f30, %o0 + 0x38), memcpy_retl_o2_plus_o4_plus_8) add %o0, 0x40, %o0 bne,pt %icc, 1b LOAD(prefetch, %g1 + 0x200, #n_reads_strong) @@ -421,38 +273,38 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ andncc %o2, 0x20 - 1, %o5 be,pn %icc, 2f sub %o2, %o5, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) - EX_LD(LOAD(ldx, %o1 + 0x08, %g2), NG4_retl_o2_plus_o5) - EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), NG4_retl_o2_plus_o5) - EX_LD(LOAD(ldx, %o1 + 0x18, %o4), NG4_retl_o2_plus_o5) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x08, %g2), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), memcpy_retl_o2_plus_o5) + EX_LD(LOAD(ldx, %o1 + 0x18, %o4), memcpy_retl_o2_plus_o5) add %o1, 0x20, %o1 subcc %o5, 0x20, %o5 - EX_ST(STORE(stx, %g1, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_32) - EX_ST(STORE(stx, %g2, %o0 + 0x08), NG4_retl_o2_plus_o5_plus_24) - EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), NG4_retl_o2_plus_o5_plus_24) - EX_ST(STORE(stx, %o4, %o0 + 0x18), NG4_retl_o2_plus_o5_plus_8) + EX_ST(STORE(stx, %g1, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_32) + EX_ST(STORE(stx, %g2, %o0 + 0x08), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), memcpy_retl_o2_plus_o5_plus_24) + EX_ST(STORE(stx, %o4, %o0 + 0x18), memcpy_retl_o2_plus_o5_plus_8) bne,pt %icc, 1b add %o0, 0x20, %o0 2: andcc %o2, 0x18, %o5 be,pt %icc, 3f sub %o2, %o5, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) +1: EX_LD(LOAD(ldx, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o5) add %o1, 0x08, %o1 add %o0, 0x08, %o0 subcc %o5, 0x08, %o5 bne,pt %icc, 1b - EX_ST(STORE(stx, %g1, %o0 - 0x08), NG4_retl_o2_plus_o5_plus_8) + EX_ST(STORE(stx, %g1, %o0 - 0x08), memcpy_retl_o2_plus_o5_plus_8) 3: brz,pt %o2, .Lexit cmp %o2, 0x04 bl,pn %icc, .Ltiny nop - EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2) + EX_LD(LOAD(lduw, %o1 + 0x00, %g1), memcpy_retl_o2) add %o1, 0x04, %o1 add %o0, 0x04, %o0 subcc %o2, 0x04, %o2 bne,pn %icc, .Ltiny - EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_4) + EX_ST(STORE(stw, %g1, %o0 - 0x04), memcpy_retl_o2_plus_4) ba,a,pt %icc, .Lexit .Lmedium_unaligned: /* First get dest 8 byte aligned. */ @@ -461,12 +313,12 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ brz,pt %g1, 2f sub %o2, %g1, %o2 -1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1) +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g2), memcpy_retl_o2_plus_g1) add %o1, 1, %o1 subcc %g1, 1, %g1 add %o0, 1, %o0 bne,pt %icc, 1b - EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1) + EX_ST(STORE(stb, %g2, %o0 - 0x01), memcpy_retl_o2_plus_g1_plus_1) 2: and %o1, 0x7, %g1 brz,pn %g1, .Lmedium_noprefetch @@ -474,16 +326,16 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ mov 64, %g2 sub %g2, %g1, %g2 andn %o1, 0x7, %o1 - EX_LD(LOAD(ldx, %o1 + 0x00, %o4), NG4_retl_o2) + EX_LD(LOAD(ldx, %o1 + 0x00, %o4), memcpy_retl_o2) sllx %o4, %g1, %o4 andn %o2, 0x08 - 1, %o5 sub %o2, %o5, %o2 -1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), NG4_retl_o2_plus_o5) +1: EX_LD(LOAD(ldx, %o1 + 0x08, %g3), memcpy_retl_o2_plus_o5) add %o1, 0x08, %o1 subcc %o5, 0x08, %o5 srlx %g3, %g2, GLOBAL_SPARE or GLOBAL_SPARE, %o4, GLOBAL_SPARE - EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_8) + EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), memcpy_retl_o2_plus_o5_plus_8) add %o0, 0x08, %o0 bne,pt %icc, 1b sllx %g3, %g1, %o4 @@ -494,17 +346,17 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ ba,pt %icc, .Lsmall_unaligned .Ltiny: - EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2) + EX_LD(LOAD(ldub, %o1 + 0x00, %g1), memcpy_retl_o2) subcc %o2, 1, %o2 be,pn %icc, .Lexit - EX_ST(STORE(stb, %g1, %o0 + 0x00), NG4_retl_o2_plus_1) - EX_LD(LOAD(ldub, %o1 + 0x01, %g1), NG4_retl_o2) + EX_ST(STORE(stb, %g1, %o0 + 0x00), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x01, %g1), memcpy_retl_o2) subcc %o2, 1, %o2 be,pn %icc, .Lexit - EX_ST(STORE(stb, %g1, %o0 + 0x01), NG4_retl_o2_plus_1) - EX_LD(LOAD(ldub, %o1 + 0x02, %g1), NG4_retl_o2) + EX_ST(STORE(stb, %g1, %o0 + 0x01), memcpy_retl_o2_plus_1) + EX_LD(LOAD(ldub, %o1 + 0x02, %g1), memcpy_retl_o2) ba,pt %icc, .Lexit - EX_ST(STORE(stb, %g1, %o0 + 0x02), NG4_retl_o2) + EX_ST(STORE(stb, %g1, %o0 + 0x02), memcpy_retl_o2) .Lsmall: andcc %g2, 0x3, %g0 @@ -512,23 +364,23 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ andn %o2, 0x4 - 1, %o5 sub %o2, %o5, %o2 1: - EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5) + EX_LD(LOAD(lduw, %o1 + 0x00, %g1), memcpy_retl_o2_plus_o5) add %o1, 0x04, %o1 subcc %o5, 0x04, %o5 add %o0, 0x04, %o0 bne,pt %icc, 1b - EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_o5_plus_4) + EX_ST(STORE(stw, %g1, %o0 - 0x04), memcpy_retl_o2_plus_o5_plus_4) brz,pt %o2, .Lexit nop ba,a,pt %icc, .Ltiny .Lsmall_unaligned: -1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2) +1: EX_LD(LOAD(ldub, %o1 + 0x00, %g1), memcpy_retl_o2) add %o1, 1, %o1 add %o0, 1, %o0 subcc %o2, 1, %o2 bne,pt %icc, 1b - EX_ST(STORE(stb, %g1, %o0 - 0x01), NG4_retl_o2_plus_1) + EX_ST(STORE(stb, %g1, %o0 - 0x01), memcpy_retl_o2_plus_1) ba,a,pt %icc, .Lexit nop .size FUNC_NAME, .-FUNC_NAME diff --git a/arch/sparc/lib/NG4memset.S b/arch/sparc/lib/NG4memset.S index 7c0c81f18837..f81ee5419e2c 100644 --- a/arch/sparc/lib/NG4memset.S +++ b/arch/sparc/lib/NG4memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG4memset.S: Niagara-4 optimized memset/bzero. * * Copyright (C) 2012 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NG4patch.S b/arch/sparc/lib/NG4patch.S index 3cc0f8cc95df..aa58ab39f9a6 100644 --- a/arch/sparc/lib/NG4patch.S +++ b/arch/sparc/lib/NG4patch.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NG4patch.S: Patch Ultra-I routines with Niagara-4 variant. * * Copyright (C) 2012 David S. Miller diff --git a/arch/sparc/lib/NGbzero.S b/arch/sparc/lib/NGbzero.S index 33053bdf3766..19327614d57d 100644 --- a/arch/sparc/lib/NGbzero.S +++ b/arch/sparc/lib/NGbzero.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NGbzero.S: Niagara optimized memset/clear_user. * * Copyright (C) 2006 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NGcopy_from_user.S b/arch/sparc/lib/NGcopy_from_user.S index 2333b6f3e824..9abc49fcdbbe 100644 --- a/arch/sparc/lib/NGcopy_from_user.S +++ b/arch/sparc/lib/NGcopy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NGcopy_from_user.S: Niagara optimized copy from userspace. * * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NGcopy_to_user.S b/arch/sparc/lib/NGcopy_to_user.S index 07ba20bc4ea4..9cbe2f18e5cc 100644 --- a/arch/sparc/lib/NGcopy_to_user.S +++ b/arch/sparc/lib/NGcopy_to_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NGcopy_to_user.S: Niagara optimized copy to userspace. * * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NGmemcpy.S b/arch/sparc/lib/NGmemcpy.S index cd654a719b27..8e4d22a6ba0b 100644 --- a/arch/sparc/lib/NGmemcpy.S +++ b/arch/sparc/lib/NGmemcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NGmemcpy.S: Niagara optimized memcpy. * * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/NGpage.S b/arch/sparc/lib/NGpage.S index 423d46e2258b..88fec7818065 100644 --- a/arch/sparc/lib/NGpage.S +++ b/arch/sparc/lib/NGpage.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NGpage.S: Niagara optimize clear and copy page. * * Copyright (C) 2006 (davem@davemloft.net) diff --git a/arch/sparc/lib/NGpatch.S b/arch/sparc/lib/NGpatch.S index 62ccda7e7b38..e9f843f1063e 100644 --- a/arch/sparc/lib/NGpatch.S +++ b/arch/sparc/lib/NGpatch.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* NGpatch.S: Patch Ultra-I routines with Niagara variant. * * Copyright (C) 2006 David S. Miller diff --git a/arch/sparc/lib/PeeCeeI.c b/arch/sparc/lib/PeeCeeI.c index e6d183675990..cde4c9a51b2e 100644 --- a/arch/sparc/lib/PeeCeeI.c +++ b/arch/sparc/lib/PeeCeeI.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PeeCeeI.c: The emerging standard... * diff --git a/arch/sparc/lib/U1copy_from_user.S b/arch/sparc/lib/U1copy_from_user.S index 9a6e68a9bf4a..bf08d1c78836 100644 --- a/arch/sparc/lib/U1copy_from_user.S +++ b/arch/sparc/lib/U1copy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* U1copy_from_user.S: UltraSparc-I/II/IIi/IIe optimized copy from userspace. * * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/U1copy_to_user.S b/arch/sparc/lib/U1copy_to_user.S index d7b28491eddf..15169851e7ab 100644 --- a/arch/sparc/lib/U1copy_to_user.S +++ b/arch/sparc/lib/U1copy_to_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* U1copy_to_user.S: UltraSparc-I/II/IIi/IIe optimized copy to userspace. * * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/U1memcpy.S b/arch/sparc/lib/U1memcpy.S index 4f0d50b33a72..a6f4ee391897 100644 --- a/arch/sparc/lib/U1memcpy.S +++ b/arch/sparc/lib/U1memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* U1memcpy.S: UltraSPARC-I/II/IIi/IIe optimized memcpy. * * Copyright (C) 1997, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/U3copy_from_user.S b/arch/sparc/lib/U3copy_from_user.S index db73010a1af8..9c891e9edc7b 100644 --- a/arch/sparc/lib/U3copy_from_user.S +++ b/arch/sparc/lib/U3copy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* U3copy_from_user.S: UltraSparc-III optimized copy from userspace. * * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/U3copy_to_user.S b/arch/sparc/lib/U3copy_to_user.S index f48fb87fe9f2..da424608272c 100644 --- a/arch/sparc/lib/U3copy_to_user.S +++ b/arch/sparc/lib/U3copy_to_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* U3copy_to_user.S: UltraSparc-III optimized copy to userspace. * * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/U3memcpy.S b/arch/sparc/lib/U3memcpy.S index 5a8cb37f0a3b..9248d59c734c 100644 --- a/arch/sparc/lib/U3memcpy.S +++ b/arch/sparc/lib/U3memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* U3memcpy.S: UltraSparc-III optimized memcpy. * * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) @@ -168,18 +169,25 @@ ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8) FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ srlx %o2, 31, %g2 cmp %g2, 0 + + /* software trap 5 "Range Check" if dst >= 0x80000000 */ tne %xcc, 5 PREAMBLE mov %o0, %o4 + + /* if len == 0 */ cmp %o2, 0 - be,pn %XCC, 85f + be,pn %XCC, end_return or %o0, %o1, %o3 + + /* if len < 16 */ cmp %o2, 16 - blu,a,pn %XCC, 80f + blu,a,pn %XCC, less_than_16 or %o3, %o2, %o3 + /* if len < 192 */ cmp %o2, (3 * 64) - blu,pt %XCC, 70f + blu,pt %XCC, less_than_192 andcc %o3, 0x7, %g0 /* Clobbers o5/g1/g2/g3/g7/icc/xcc. We must preserve @@ -362,7 +370,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ cmp %o2, 0 add %o1, %g1, %o1 VISExitHalf - be,pn %XCC, 85f + be,pn %XCC, end_return sub %o0, %o1, %o3 andcc %g1, 0x7, %g0 @@ -392,14 +400,15 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ sub %o2, 2, %o2 1: andcc %o2, 0x1, %g0 - be,pt %icc, 85f + be,pt %icc, end_return nop EX_LD(LOAD(ldub, %o1, %o5), U3_retl_o2) - ba,pt %xcc, 85f + ba,pt %xcc, end_return EX_ST(STORE(stb, %o5, %o1 + %o3), U3_retl_o2) .align 64 -70: /* 16 < len <= 64 */ + /* 16 <= len < 192 */ +less_than_192: bne,pn %XCC, 75f sub %o0, %o1, %o3 @@ -429,7 +438,7 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ EX_ST(STORE(stw, %o5, %o1 + %o3), U3_retl_o2_plus_4) add %o1, 0x4, %o1 1: cmp %o2, 0 - be,pt %XCC, 85f + be,pt %XCC, end_return nop ba,pt %xcc, 90f nop @@ -475,13 +484,14 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ srl %g1, 3, %g1 andcc %o2, 0x7, %o2 - be,pn %icc, 85f + be,pn %icc, end_return add %o1, %g1, %o1 ba,pt %xcc, 90f sub %o0, %o1, %o3 .align 64 -80: /* 0 < len <= 16 */ + /* 0 < len < 16 */ +less_than_16: andcc %o3, 0x3, %g0 bne,pn %XCC, 90f sub %o0, %o1, %o3 @@ -493,7 +503,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */ bgu,pt %XCC, 1b add %o1, 4, %o1 -85: retl +end_return: + retl mov EX_RETVAL(%o4), %o0 .align 32 diff --git a/arch/sparc/lib/U3patch.S b/arch/sparc/lib/U3patch.S index 91cd6539b6e1..9a888088f3c9 100644 --- a/arch/sparc/lib/U3patch.S +++ b/arch/sparc/lib/U3patch.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* U3patch.S: Patch Ultra-I routines with Ultra-III variant. * * Copyright (C) 2004 David S. Miller diff --git a/arch/sparc/lib/VISsave.S b/arch/sparc/lib/VISsave.S index 1c7b6a39b942..9c8eb2017d5b 100644 --- a/arch/sparc/lib/VISsave.S +++ b/arch/sparc/lib/VISsave.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * VISsave.S: Code for saving FPU register state for * VIS routines. One should not call this directly, diff --git a/arch/sparc/lib/ashldi3.S b/arch/sparc/lib/ashldi3.S index c8b1cf71bc73..2d72de88af90 100644 --- a/arch/sparc/lib/ashldi3.S +++ b/arch/sparc/lib/ashldi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ashldi3.S: GCC emits these for certain drivers playing * with long longs. diff --git a/arch/sparc/lib/ashrdi3.S b/arch/sparc/lib/ashrdi3.S index 4310256e7964..05dfda9f5005 100644 --- a/arch/sparc/lib/ashrdi3.S +++ b/arch/sparc/lib/ashrdi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ashrdi3.S: The filesystem code creates all kinds of references to * this little routine on the sparc with gcc. diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c index 2c373329d5cb..5010df497387 100644 --- a/arch/sparc/lib/atomic32.c +++ b/arch/sparc/lib/atomic32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * atomic32.c: 32-bit atomic_t implementation * diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index ce17c3094ba6..456b65a30ecf 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* atomic.S: These things are too big to do inline. * * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c index 8ec4e9c0251a..32a5c1d9459c 100644 --- a/arch/sparc/lib/bitext.c +++ b/arch/sparc/lib/bitext.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * bitext.c: kernel little helper (of bit shuffling variety). * diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S index 7031bf1587cb..9d647f977618 100644 --- a/arch/sparc/lib/bitops.S +++ b/arch/sparc/lib/bitops.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* bitops.S: Sparc64 atomic bit operations. * * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/blockops.S b/arch/sparc/lib/blockops.S index 1f2692d59d18..76ddd1ff6833 100644 --- a/arch/sparc/lib/blockops.S +++ b/arch/sparc/lib/blockops.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * blockops.S: Common block zero optimized routines. * diff --git a/arch/sparc/lib/bzero.S b/arch/sparc/lib/bzero.S index 3bb1914c4fa4..87fec4cbe10c 100644 --- a/arch/sparc/lib/bzero.S +++ b/arch/sparc/lib/bzero.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* bzero.S: Simple prefetching memset, bzero, and clear_user * implementations. * diff --git a/arch/sparc/lib/checksum_32.S b/arch/sparc/lib/checksum_32.S index c9d8b6232111..6a5469c97246 100644 --- a/arch/sparc/lib/checksum_32.S +++ b/arch/sparc/lib/checksum_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* checksum.S: Sparc optimized checksum code. * * Copyright(C) 1995 Linus Torvalds diff --git a/arch/sparc/lib/checksum_64.S b/arch/sparc/lib/checksum_64.S index 6cfa521f444d..9700ef1730df 100644 --- a/arch/sparc/lib/checksum_64.S +++ b/arch/sparc/lib/checksum_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* checksum.S: Sparc V9 optimized checksum code. * * Copyright(C) 1995 Linus Torvalds diff --git a/arch/sparc/lib/clear_page.S b/arch/sparc/lib/clear_page.S index f30d6b78afbd..8a6c783a6301 100644 --- a/arch/sparc/lib/clear_page.S +++ b/arch/sparc/lib/clear_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* clear_page.S: UltraSparc optimized clear page. * * Copyright (C) 1996, 1998, 1999, 2000, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/cmpdi2.c b/arch/sparc/lib/cmpdi2.c index 8c1306437ed1..333367fe7353 100644 --- a/arch/sparc/lib/cmpdi2.c +++ b/arch/sparc/lib/cmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/sparc/lib/copy_in_user.S b/arch/sparc/lib/copy_in_user.S index 1b73bb80aeb0..66e90bf528e2 100644 --- a/arch/sparc/lib/copy_in_user.S +++ b/arch/sparc/lib/copy_in_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* copy_in_user.S: Copy from userspace to userspace. * * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/copy_page.S b/arch/sparc/lib/copy_page.S index 7197b7250895..c088e871e8e3 100644 --- a/arch/sparc/lib/copy_page.S +++ b/arch/sparc/lib/copy_page.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* clear_page.S: UltraSparc optimized copy page. * * Copyright (C) 1996, 1998, 1999, 2000, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/copy_user.S b/arch/sparc/lib/copy_user.S index bc243ee807cc..dc72f2b970b7 100644 --- a/arch/sparc/lib/copy_user.S +++ b/arch/sparc/lib/copy_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* copy_user.S: Sparc optimized copy_from_user and copy_to_user code. * * Copyright(C) 1995 Linus Torvalds diff --git a/arch/sparc/lib/csum_copy.S b/arch/sparc/lib/csum_copy.S index b1051e77c49a..26c644ba3ecb 100644 --- a/arch/sparc/lib/csum_copy.S +++ b/arch/sparc/lib/csum_copy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* csum_copy.S: Checksum+copy code for sparc64 * * Copyright (C) 2005 David S. Miller diff --git a/arch/sparc/lib/csum_copy_from_user.S b/arch/sparc/lib/csum_copy_from_user.S index e0304e6a2242..d20b9594f0c7 100644 --- a/arch/sparc/lib/csum_copy_from_user.S +++ b/arch/sparc/lib/csum_copy_from_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* csum_copy_from_user.S: Checksum+copy from userspace. * * Copyright (C) 2005 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/csum_copy_to_user.S b/arch/sparc/lib/csum_copy_to_user.S index afd01acc587c..d71c0c81e8ab 100644 --- a/arch/sparc/lib/csum_copy_to_user.S +++ b/arch/sparc/lib/csum_copy_to_user.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* csum_copy_to_user.S: Checksum+copy to userspace. * * Copyright (C) 2005 David S. Miller (davem@davemloft.net) diff --git a/arch/sparc/lib/ffs.S b/arch/sparc/lib/ffs.S index 23aab144d28e..5a11d864fa05 100644 --- a/arch/sparc/lib/ffs.S +++ b/arch/sparc/lib/ffs.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/lib/hweight.S b/arch/sparc/lib/hweight.S index d21cf20e5c1e..e5547b22cd18 100644 --- a/arch/sparc/lib/hweight.S +++ b/arch/sparc/lib/hweight.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/lib/iomap.c b/arch/sparc/lib/iomap.c index c4d42a50ebc0..c9da9f139694 100644 --- a/arch/sparc/lib/iomap.c +++ b/arch/sparc/lib/iomap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implement the sparc iomap interfaces */ diff --git a/arch/sparc/lib/ipcsum.S b/arch/sparc/lib/ipcsum.S index 5d61648b53dd..531d89c9d5d9 100644 --- a/arch/sparc/lib/ipcsum.S +++ b/arch/sparc/lib/ipcsum.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/lib/libgcc.h b/arch/sparc/lib/libgcc.h index b84fd797f3ea..79845c941b87 100644 --- a/arch/sparc/lib/libgcc.h +++ b/arch/sparc/lib/libgcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_LIBGCC_H #define __ASM_LIBGCC_H diff --git a/arch/sparc/lib/locks.S b/arch/sparc/lib/locks.S index f38c4e59d078..9a1289a3fb28 100644 --- a/arch/sparc/lib/locks.S +++ b/arch/sparc/lib/locks.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * locks.S: SMP low-level lock primitives on Sparc. * diff --git a/arch/sparc/lib/lshrdi3.S b/arch/sparc/lib/lshrdi3.S index c9b9373f8d81..509ca6682da8 100644 --- a/arch/sparc/lib/lshrdi3.S +++ b/arch/sparc/lib/lshrdi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/lib/mcount.S b/arch/sparc/lib/mcount.S index 194f383611c0..deba6fa0bc78 100644 --- a/arch/sparc/lib/mcount.S +++ b/arch/sparc/lib/mcount.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com) * diff --git a/arch/sparc/lib/memcmp.S b/arch/sparc/lib/memcmp.S index cee7f30dbb61..a18076ef5af1 100644 --- a/arch/sparc/lib/memcmp.S +++ b/arch/sparc/lib/memcmp.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Sparc optimized memcmp code. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/lib/memcpy.S b/arch/sparc/lib/memcpy.S index 8913feaa7ac7..ee823d8c9215 100644 --- a/arch/sparc/lib/memcpy.S +++ b/arch/sparc/lib/memcpy.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* memcpy.S: Sparc optimized memcpy and memmove code * Hand optimized from GNU libc's memcpy and memmove * Copyright (C) 1991,1996 Free Software Foundation diff --git a/arch/sparc/lib/memmove.S b/arch/sparc/lib/memmove.S index 012cdb6ca467..3132b6316144 100644 --- a/arch/sparc/lib/memmove.S +++ b/arch/sparc/lib/memmove.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* memmove.S: Simple memmove implementation. * * Copyright (C) 1997, 2004 David S. Miller (davem@redhat.com) diff --git a/arch/sparc/lib/memscan_32.S b/arch/sparc/lib/memscan_32.S index 51ce690c42a8..c4c2d5b3a2e9 100644 --- a/arch/sparc/lib/memscan_32.S +++ b/arch/sparc/lib/memscan_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * memscan.S: Optimized memscan for the Sparc. * diff --git a/arch/sparc/lib/memscan_64.S b/arch/sparc/lib/memscan_64.S index 5efee1f4be36..36dd638905c3 100644 --- a/arch/sparc/lib/memscan_64.S +++ b/arch/sparc/lib/memscan_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * memscan.S: Optimized memscan for Sparc64. * diff --git a/arch/sparc/lib/memset.S b/arch/sparc/lib/memset.S index e23338dbfc43..b89d42b29e34 100644 --- a/arch/sparc/lib/memset.S +++ b/arch/sparc/lib/memset.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* linux/arch/sparc/lib/memset.S: Sparc optimized memset, bzero and clear_user code * Copyright (C) 1991,1996 Free Software Foundation * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/lib/multi3.S b/arch/sparc/lib/multi3.S index 703127aaf4a5..2f187b299345 100644 --- a/arch/sparc/lib/multi3.S +++ b/arch/sparc/lib/multi3.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/sparc/lib/strlen.S b/arch/sparc/lib/strlen.S index ca0e7077e871..dd111bbad5df 100644 --- a/arch/sparc/lib/strlen.S +++ b/arch/sparc/lib/strlen.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* strlen.S: Sparc optimized strlen code * Hand optimized from GNU libc's strlen * Copyright (C) 1991,1996 Free Software Foundation diff --git a/arch/sparc/lib/strncmp_32.S b/arch/sparc/lib/strncmp_32.S index e3fe014813af..794733f036b6 100644 --- a/arch/sparc/lib/strncmp_32.S +++ b/arch/sparc/lib/strncmp_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * strncmp.S: Hand optimized Sparc assembly of GCC output from GNU libc * generic strncmp routine. diff --git a/arch/sparc/lib/strncmp_64.S b/arch/sparc/lib/strncmp_64.S index efb5f884330d..3d37d65f674c 100644 --- a/arch/sparc/lib/strncmp_64.S +++ b/arch/sparc/lib/strncmp_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Sparc64 optimized strncmp code. * diff --git a/arch/sparc/lib/ucmpdi2.c b/arch/sparc/lib/ucmpdi2.c index 1e06ed500682..82c1cccb1264 100644 --- a/arch/sparc/lib/ucmpdi2.c +++ b/arch/sparc/lib/ucmpdi2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "libgcc.h" diff --git a/arch/sparc/lib/xor.S b/arch/sparc/lib/xor.S index 45a49cb618b5..f6af7c7ee6fc 100644 --- a/arch/sparc/lib/xor.S +++ b/arch/sparc/lib/xor.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/sparc64/lib/xor.S * diff --git a/arch/sparc/math-emu/math_32.c b/arch/sparc/math-emu/math_32.c index 4d7e0fff054f..72e560ef4a09 100644 --- a/arch/sparc/math-emu/math_32.c +++ b/arch/sparc/math-emu/math_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sparc/math-emu/math.c * diff --git a/arch/sparc/math-emu/math_64.c b/arch/sparc/math-emu/math_64.c index 9647051853d3..1379dee26a65 100644 --- a/arch/sparc/math-emu/math_64.c +++ b/arch/sparc/math-emu/math_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sparc64/math-emu/math.c * diff --git a/arch/sparc/math-emu/sfp-util_32.h b/arch/sparc/math-emu/sfp-util_32.h index bb587d5f3d9d..b57375ff28ee 100644 --- a/arch/sparc/math-emu/sfp-util_32.h +++ b/arch/sparc/math-emu/sfp-util_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/sparc/math-emu/sfp-util_64.h b/arch/sparc/math-emu/sfp-util_64.h index 51320a861cc2..8fdb55aae9c8 100644 --- a/arch/sparc/math-emu/sfp-util_64.h +++ b/arch/sparc/math-emu/sfp-util_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * arch/sparc64/math-emu/sfp-util.h * diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 30c3eccfdf5a..d39075b1e3b7 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the linux Sparc-specific parts of the memory manager. # diff --git a/arch/sparc/mm/extable.c b/arch/sparc/mm/extable.c index 2422511dc8c5..241b40641873 100644 --- a/arch/sparc/mm/extable.c +++ b/arch/sparc/mm/extable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sparc/mm/extable.c */ diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index 4714061d6cd3..be3136f142a9 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * fault.c: Page fault handlers for the Sparc. * diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index b84c4dd14954..815c03d7a765 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index f80cfc64c55b..5335ba3c850e 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Lockless get_user_pages_fast for sparc, cribbed from powerpc * @@ -103,6 +104,45 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, return 1; } +static int gup_huge_pud(pud_t *pudp, pud_t pud, unsigned long addr, + unsigned long end, int write, struct page **pages, + int *nr) +{ + struct page *head, *page; + int refs; + + if (!(pud_val(pud) & _PAGE_VALID)) + return 0; + + if (write && !pud_write(pud)) + return 0; + + refs = 0; + page = pud_page(pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT); + head = compound_head(page); + do { + VM_BUG_ON(compound_head(page) != head); + pages[*nr] = page; + (*nr)++; + page++; + refs++; + } while (addr += PAGE_SIZE, addr != end); + + if (!page_cache_add_speculative(head, refs)) { + *nr -= refs; + return 0; + } + + if (unlikely(pud_val(pud) != pud_val(*pudp))) { + *nr -= refs; + while (refs--) + put_page(head); + return 0; + } + + return 1; +} + static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { @@ -141,7 +181,11 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, next = pud_addr_end(addr, end); if (pud_none(pud)) return 0; - if (!gup_pmd_range(pud, addr, next, write, pages, nr)) + if (unlikely(pud_large(pud))) { + if (!gup_huge_pud(pudp, pud, addr, next, + write, pages, nr)) + return 0; + } else if (!gup_pmd_range(pud, addr, next, write, pages, nr)) return 0; } while (pudp++, addr = next, addr != end); diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c index a454ec5ff07a..86bc2a58d26c 100644 --- a/arch/sparc/mm/highmem.c +++ b/arch/sparc/mm/highmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * highmem.c: virtual kernel memory mappings for high memory * diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index 28ee8d8ffa07..5078b7f68890 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SPARC64 Huge TLB page support. * @@ -143,6 +144,10 @@ static pte_t sun4v_hugepage_shift_to_tte(pte_t entry, unsigned int shift) pte_val(entry) = pte_val(entry) & ~_PAGE_SZALL_4V; switch (shift) { + case HPAGE_16GB_SHIFT: + hugepage_size = _PAGE_SZ16GB_4V; + pte_val(entry) |= _PAGE_PUD_HUGE; + break; case HPAGE_2GB_SHIFT: hugepage_size = _PAGE_SZ2GB_4V; pte_val(entry) |= _PAGE_PMD_HUGE; @@ -187,6 +192,9 @@ static unsigned int sun4v_huge_tte_to_shift(pte_t entry) unsigned int shift; switch (tte_szbits) { + case _PAGE_SZ16GB_4V: + shift = HPAGE_16GB_SHIFT; + break; case _PAGE_SZ2GB_4V: shift = HPAGE_2GB_SHIFT; break; @@ -259,22 +267,19 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, pgd_t *pgd; pud_t *pud; pmd_t *pmd; - pte_t *pte = NULL; pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); - if (pud) { - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - return NULL; - - if (sz >= PMD_SIZE) - pte = (pte_t *)pmd; - else - pte = pte_alloc_map(mm, pmd, addr); - } - - return pte; + if (!pud) + return NULL; + if (sz >= PUD_SIZE) + return (pte_t *)pud; + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + return NULL; + if (sz >= PMD_SIZE) + return (pte_t *)pmd; + return pte_alloc_map(mm, pmd, addr); } pte_t *huge_pte_offset(struct mm_struct *mm, @@ -283,34 +288,40 @@ pte_t *huge_pte_offset(struct mm_struct *mm, pgd_t *pgd; pud_t *pud; pmd_t *pmd; - pte_t *pte = NULL; pgd = pgd_offset(mm, addr); - if (!pgd_none(*pgd)) { - pud = pud_offset(pgd, addr); - if (!pud_none(*pud)) { - pmd = pmd_offset(pud, addr); - if (!pmd_none(*pmd)) { - if (is_hugetlb_pmd(*pmd)) - pte = (pte_t *)pmd; - else - pte = pte_offset_map(pmd, addr); - } - } - } - - return pte; + if (pgd_none(*pgd)) + return NULL; + pud = pud_offset(pgd, addr); + if (pud_none(*pud)) + return NULL; + if (is_hugetlb_pud(*pud)) + return (pte_t *)pud; + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) + return NULL; + if (is_hugetlb_pmd(*pmd)) + return (pte_t *)pmd; + return pte_offset_map(pmd, addr); } void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { - unsigned int i, nptes, orig_shift, shift; - unsigned long size; + unsigned int nptes, orig_shift, shift; + unsigned long i, size; pte_t orig; size = huge_tte_to_size(entry); - shift = size >= HPAGE_SIZE ? PMD_SHIFT : PAGE_SHIFT; + + shift = PAGE_SHIFT; + if (size >= PUD_SIZE) + shift = PUD_SHIFT; + else if (size >= PMD_SIZE) + shift = PMD_SHIFT; + else + shift = PAGE_SHIFT; + nptes = size >> shift; if (!pte_present(*ptep) && pte_present(entry)) @@ -333,19 +344,23 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - unsigned int i, nptes, hugepage_shift; + unsigned int i, nptes, orig_shift, shift; unsigned long size; pte_t entry; entry = *ptep; size = huge_tte_to_size(entry); - if (size >= HPAGE_SIZE) - nptes = size >> PMD_SHIFT; - else - nptes = size >> PAGE_SHIFT; - hugepage_shift = pte_none(entry) ? PAGE_SHIFT : - huge_tte_to_shift(entry); + shift = PAGE_SHIFT; + if (size >= PUD_SIZE) + shift = PUD_SHIFT; + else if (size >= PMD_SIZE) + shift = PMD_SHIFT; + else + shift = PAGE_SHIFT; + + nptes = size >> shift; + orig_shift = pte_none(entry) ? PAGE_SHIFT : huge_tte_to_shift(entry); if (pte_present(entry)) mm->context.hugetlb_pte_count -= nptes; @@ -354,11 +369,11 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, for (i = 0; i < nptes; i++) ptep[i] = __pte(0UL); - maybe_tlb_batch_add(mm, addr, ptep, entry, 0, hugepage_shift); + maybe_tlb_batch_add(mm, addr, ptep, entry, 0, orig_shift); /* An HPAGE_SIZE'ed page is composed of two REAL_HPAGE_SIZE'ed pages */ if (size == HPAGE_SIZE) maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, entry, 0, - hugepage_shift); + orig_shift); return entry; } @@ -371,7 +386,8 @@ int pmd_huge(pmd_t pmd) int pud_huge(pud_t pud) { - return 0; + return !pud_none(pud) && + (pud_val(pud) & (_PAGE_VALID|_PAGE_PUD_HUGE)) != _PAGE_VALID; } static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd, @@ -435,8 +451,11 @@ static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, next = pud_addr_end(addr, end); if (pud_none_or_clear_bad(pud)) continue; - hugetlb_free_pmd_range(tlb, pud, addr, next, floor, - ceiling); + if (is_hugetlb_pud(*pud)) + pud_clear(pud); + else + hugetlb_free_pmd_range(tlb, pud, addr, next, floor, + ceiling); } while (pud++, addr = next, addr != end); start &= PGDIR_MASK; diff --git a/arch/sparc/mm/hypersparc.S b/arch/sparc/mm/hypersparc.S index 969f96450f69..66885a8dc50a 100644 --- a/arch/sparc/mm/hypersparc.S +++ b/arch/sparc/mm/hypersparc.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * hypersparc.S: High speed Hypersparc mmu/cache operations. * diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index 3bd0d513bddb..95fe4f081ba3 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sparc/mm/init.c * diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index afa0099f3748..61bdc1270d19 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/sparc64/mm/init.c * @@ -348,6 +349,18 @@ static int __init hugetlbpage_init(void) arch_initcall(hugetlbpage_init); +static void __init pud_huge_patch(void) +{ + struct pud_huge_patch_entry *p; + unsigned long addr; + + p = &__pud_huge_patch; + addr = p->addr; + *(unsigned int *)addr = p->insn; + + __asm__ __volatile__("flush %0" : : "r" (addr)); +} + static int __init setup_hugepagesz(char *string) { unsigned long long hugepage_size; @@ -360,6 +373,11 @@ static int __init setup_hugepagesz(char *string) hugepage_shift = ilog2(hugepage_size); switch (hugepage_shift) { + case HPAGE_16GB_SHIFT: + hv_pgsz_mask = HV_PGSZ_MASK_16GB; + hv_pgsz_idx = HV_PGSZ_IDX_16GB; + pud_huge_patch(); + break; case HPAGE_2GB_SHIFT: hv_pgsz_mask = HV_PGSZ_MASK_2GB; hv_pgsz_idx = HV_PGSZ_IDX_2GB; @@ -400,6 +418,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * { struct mm_struct *mm; unsigned long flags; + bool is_huge_tsb; pte_t pte = *ptep; if (tlb_type != hypervisor) { @@ -417,15 +436,37 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t * spin_lock_irqsave(&mm->context.lock, flags); + is_huge_tsb = false; #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) - if ((mm->context.hugetlb_pte_count || mm->context.thp_pte_count) && - is_hugetlb_pmd(__pmd(pte_val(pte)))) { - /* We are fabricating 8MB pages using 4MB real hw pages. */ - pte_val(pte) |= (address & (1UL << REAL_HPAGE_SHIFT)); - __update_mmu_tsb_insert(mm, MM_TSB_HUGE, REAL_HPAGE_SHIFT, - address, pte_val(pte)); - } else + if (mm->context.hugetlb_pte_count || mm->context.thp_pte_count) { + unsigned long hugepage_size = PAGE_SIZE; + + if (is_vm_hugetlb_page(vma)) + hugepage_size = huge_page_size(hstate_vma(vma)); + + if (hugepage_size >= PUD_SIZE) { + unsigned long mask = 0x1ffc00000UL; + + /* Transfer bits [32:22] from address to resolve + * at 4M granularity. + */ + pte_val(pte) &= ~mask; + pte_val(pte) |= (address & mask); + } else if (hugepage_size >= PMD_SIZE) { + /* We are fabricating 8MB pages using 4MB + * real hw pages. + */ + pte_val(pte) |= (address & (1UL << REAL_HPAGE_SHIFT)); + } + + if (hugepage_size >= PMD_SIZE) { + __update_mmu_tsb_insert(mm, MM_TSB_HUGE, + REAL_HPAGE_SHIFT, address, pte_val(pte)); + is_huge_tsb = true; + } + } #endif + if (!is_huge_tsb) __update_mmu_tsb_insert(mm, MM_TSB_BASE, PAGE_SHIFT, address, pte_val(pte)); diff --git a/arch/sparc/mm/init_64.h b/arch/sparc/mm/init_64.h index a4c09603b05c..d920a75b5f14 100644 --- a/arch/sparc/mm/init_64.h +++ b/arch/sparc/mm/init_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPARC64_MM_INIT_H #define _SPARC64_MM_INIT_H diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 338fb71535de..c8cb27d3ea75 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * io-unit.c: IO-UNIT specific routines for memory management. * diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 491511d37e37..2c5f8a648f8c 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * iommu.c: IOMMU specific routines for memory management. * diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c index 3b17b6f7895a..ec61ff1f96b7 100644 --- a/arch/sparc/mm/leon_mm.c +++ b/arch/sparc/mm/leon_mm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/sparc/mm/leon_m.c * diff --git a/arch/sparc/mm/mm_32.h b/arch/sparc/mm/mm_32.h index a6c27ca9a721..0d0b06e952a5 100644 --- a/arch/sparc/mm/mm_32.h +++ b/arch/sparc/mm/mm_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* fault_32.c - visible as they are called from assembler */ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, unsigned long address); diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index 8e76ebba2986..1d70c3f6d986 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * srmmu.c: SRMMU specific routines for memory management. * diff --git a/arch/sparc/mm/srmmu_access.S b/arch/sparc/mm/srmmu_access.S index d0a67b2c2383..d8d2e644a5ca 100644 --- a/arch/sparc/mm/srmmu_access.S +++ b/arch/sparc/mm/srmmu_access.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Assembler variants of srmmu access functions. * Implemented in assembler to allow run-time patching. * LEON uses a different ASI for MMUREGS than SUN. diff --git a/arch/sparc/mm/swift.S b/arch/sparc/mm/swift.S index 5d2b88d39424..f414bfd8d899 100644 --- a/arch/sparc/mm/swift.S +++ b/arch/sparc/mm/swift.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * swift.S: MicroSparc-II mmu/cache operations. * diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index ee8066c3d96c..4ae86bc0d35c 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* arch/sparc64/mm/tlb.c * * Copyright (C) 2004 David S. Miller diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 0d4b998c7d7b..75a04c1a2383 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* arch/sparc64/mm/tsb.c * * Copyright (C) 2006, 2008 David S. Miller diff --git a/arch/sparc/mm/tsunami.S b/arch/sparc/mm/tsunami.S index bf10a345fa8b..62b742df65dc 100644 --- a/arch/sparc/mm/tsunami.S +++ b/arch/sparc/mm/tsunami.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * tsunami.S: High speed MicroSparc-I mmu/cache operations. * diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index fcf4d27a38fb..d245f89d1395 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ultra.S: Don't expand these all over the place... * diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S index 852257fcc82b..adaef6e7b8cf 100644 --- a/arch/sparc/mm/viking.S +++ b/arch/sparc/mm/viking.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * viking.S: High speed Viking cache/mmu operations * diff --git a/arch/sparc/net/bpf_jit_32.h b/arch/sparc/net/bpf_jit_32.h index d5c069bff5f9..cfd6a8be0eb4 100644 --- a/arch/sparc/net/bpf_jit_32.h +++ b/arch/sparc/net/bpf_jit_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _BPF_JIT_H #define _BPF_JIT_H diff --git a/arch/sparc/net/bpf_jit_64.h b/arch/sparc/net/bpf_jit_64.h index 74abd45796ea..428f7fd19175 100644 --- a/arch/sparc/net/bpf_jit_64.h +++ b/arch/sparc/net/bpf_jit_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _BPF_JIT_H #define _BPF_JIT_H diff --git a/arch/sparc/net/bpf_jit_asm_32.S b/arch/sparc/net/bpf_jit_asm_32.S index dcc402f5738a..a2e28e0464a3 100644 --- a/arch/sparc/net/bpf_jit_asm_32.S +++ b/arch/sparc/net/bpf_jit_asm_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include "bpf_jit_32.h" diff --git a/arch/sparc/net/bpf_jit_asm_64.S b/arch/sparc/net/bpf_jit_asm_64.S index 3b3f14655f81..7177867052a1 100644 --- a/arch/sparc/net/bpf_jit_asm_64.S +++ b/arch/sparc/net/bpf_jit_asm_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include "bpf_jit_64.h" diff --git a/arch/sparc/net/bpf_jit_comp_32.c b/arch/sparc/net/bpf_jit_comp_32.c index d193748548e2..09e318eb34ee 100644 --- a/arch/sparc/net/bpf_jit_comp_32.c +++ b/arch/sparc/net/bpf_jit_comp_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index 8799ae9a8788..5765e7e711f7 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -128,6 +129,8 @@ static u32 WDISP10(u32 off) #define BA (BRANCH | CONDA) #define BG (BRANCH | CONDG) +#define BL (BRANCH | CONDL) +#define BLE (BRANCH | CONDLE) #define BGU (BRANCH | CONDGU) #define BLEU (BRANCH | CONDLEU) #define BGE (BRANCH | CONDGE) @@ -715,9 +718,15 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src, case BPF_JGT: br_opcode = BGU; break; + case BPF_JLT: + br_opcode = BLU; + break; case BPF_JGE: br_opcode = BGEU; break; + case BPF_JLE: + br_opcode = BLEU; + break; case BPF_JSET: case BPF_JNE: br_opcode = BNE; @@ -725,9 +734,15 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src, case BPF_JSGT: br_opcode = BG; break; + case BPF_JSLT: + br_opcode = BL; + break; case BPF_JSGE: br_opcode = BGE; break; + case BPF_JSLE: + br_opcode = BLE; + break; default: /* Make sure we dont leak kernel information to the * user. @@ -746,18 +761,30 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src, case BPF_JGT: cbcond_opcode = CBCONDGU; break; + case BPF_JLT: + cbcond_opcode = CBCONDLU; + break; case BPF_JGE: cbcond_opcode = CBCONDGEU; break; + case BPF_JLE: + cbcond_opcode = CBCONDLEU; + break; case BPF_JNE: cbcond_opcode = CBCONDNE; break; case BPF_JSGT: cbcond_opcode = CBCONDG; break; + case BPF_JSLT: + cbcond_opcode = CBCONDL; + break; case BPF_JSGE: cbcond_opcode = CBCONDGE; break; + case BPF_JSLE: + cbcond_opcode = CBCONDLE; + break; default: /* Make sure we dont leak kernel information to the * user. @@ -1176,10 +1203,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) /* IF (dst COND src) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_X: case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JLT | BPF_X: case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JLE | BPF_X: case BPF_JMP | BPF_JNE | BPF_X: case BPF_JMP | BPF_JSGT | BPF_X: + case BPF_JMP | BPF_JSLT | BPF_X: case BPF_JMP | BPF_JSGE | BPF_X: + case BPF_JMP | BPF_JSLE | BPF_X: case BPF_JMP | BPF_JSET | BPF_X: { int err; @@ -1191,10 +1222,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) /* IF (dst COND imm) JUMP off */ case BPF_JMP | BPF_JEQ | BPF_K: case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JLT | BPF_K: case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JLE | BPF_K: case BPF_JMP | BPF_JNE | BPF_K: case BPF_JMP | BPF_JSGT | BPF_K: + case BPF_JMP | BPF_JSLT | BPF_K: case BPF_JMP | BPF_JSGE | BPF_K: + case BPF_JMP | BPF_JSLE | BPF_K: case BPF_JMP | BPF_JSET | BPF_K: { int err; diff --git a/arch/sparc/power/hibernate.c b/arch/sparc/power/hibernate.c index df707a8ad311..47b06f4af1f9 100644 --- a/arch/sparc/power/hibernate.c +++ b/arch/sparc/power/hibernate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * hibernate.c: Hibernaton support specific for sparc64. * diff --git a/arch/sparc/power/hibernate_asm.S b/arch/sparc/power/hibernate_asm.S index d7d9017dcb15..8cfaf5b6a32e 100644 --- a/arch/sparc/power/hibernate_asm.S +++ b/arch/sparc/power/hibernate_asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * hibernate_asm.S: Hibernaton support specific for sparc64. * diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 020300b18c0b..397b79af77f7 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Sun Boot PROM interface library under # Linux. # diff --git a/arch/sparc/prom/bootstr_32.c b/arch/sparc/prom/bootstr_32.c index d2b49d2365e7..e3b731ff00f0 100644 --- a/arch/sparc/prom/bootstr_32.c +++ b/arch/sparc/prom/bootstr_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * bootstr.c: Boot string/argument acquisition from the PROM. * diff --git a/arch/sparc/prom/bootstr_64.c b/arch/sparc/prom/bootstr_64.c index 7149e77714a4..f1cc34d99eec 100644 --- a/arch/sparc/prom/bootstr_64.c +++ b/arch/sparc/prom/bootstr_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * bootstr.c: Boot string/argument acquisition from the PROM. * diff --git a/arch/sparc/prom/cif.S b/arch/sparc/prom/cif.S index 8050f381f518..dd06bb1fb90c 100644 --- a/arch/sparc/prom/cif.S +++ b/arch/sparc/prom/cif.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* cif.S: PROM entry/exit assembler trampolines. * * Copyright (C) 1996, 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 1cfb50f4cb9c..6404e5bbb7e6 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index f95edcc54fd5..86dace787ae6 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* console.c: Routines that deal with sending and receiving IO * to/from the current console device using the PROM. * diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c index 9ac30c2b7dba..d20470166cb1 100644 --- a/arch/sparc/prom/init_32.c +++ b/arch/sparc/prom/init_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * init.c: Initialize internal variables used by the PROM * library functions. diff --git a/arch/sparc/prom/init_64.c b/arch/sparc/prom/init_64.c index 110b0d78b864..103aa9104318 100644 --- a/arch/sparc/prom/init_64.c +++ b/arch/sparc/prom/init_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * init.c: Initialize internal variables used by the PROM * library functions. diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c index 3f263a64857d..269d6ab5ef5e 100644 --- a/arch/sparc/prom/memory.c +++ b/arch/sparc/prom/memory.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* memory.c: Prom routine for acquiring various bits of information * about RAM on the machine, both virtual and physical. * diff --git a/arch/sparc/prom/misc_32.c b/arch/sparc/prom/misc_32.c index 8dc0b6b271e8..625750924860 100644 --- a/arch/sparc/prom/misc_32.c +++ b/arch/sparc/prom/misc_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * misc.c: Miscellaneous prom functions that don't belong * anywhere else. diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index 53a696d3eb3b..aed94cd4a1e7 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * misc.c: Miscellaneous prom functions that don't belong * anywhere else. diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c index 0da8256cf76f..67cf0e957e38 100644 --- a/arch/sparc/prom/mp.c +++ b/arch/sparc/prom/mp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * mp.c: OpenBoot Prom Multiprocessor support routines. Don't call * these on a UP or else you will halt and catch fire. ;) diff --git a/arch/sparc/prom/p1275.c b/arch/sparc/prom/p1275.c index 545d8bb79b65..889aa602f8d8 100644 --- a/arch/sparc/prom/p1275.c +++ b/arch/sparc/prom/p1275.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * p1275.c: Sun IEEE 1275 PROM low level interface routines * diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index d9682f06b3b0..dcee3dfa6de9 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * printf.c: Internal prom library printf facility. * diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c index 6d8dc2aa94ce..20cb828bc5f4 100644 --- a/arch/sparc/prom/ranges.c +++ b/arch/sparc/prom/ranges.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ranges.c: Handle ranges in newer proms for obio/sbus. * diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c index f30e8d038f01..0fed89375b74 100644 --- a/arch/sparc/prom/tree_32.c +++ b/arch/sparc/prom/tree_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * tree.c: Basic device tree traversal/scanning for the Linux * prom library. diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index bd1b2a3ac34e..989e7992d629 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * tree.c: Basic device tree traversal/scanning for the Linux * prom library. diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 4583c0320059..02f269cfa538 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. diff --git a/arch/tile/Kconfig.debug b/arch/tile/Kconfig.debug index 19734d3ab1e8..9f665d1a805f 100644 --- a/arch/tile/Kconfig.debug +++ b/arch/tile/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/tile/Makefile b/arch/tile/Makefile index 4dc380a519d4..8fa0befba32b 100644 --- a/arch/tile/Makefile +++ b/arch/tile/Makefile @@ -51,6 +51,8 @@ else BITS := 32 endif +CHECKFLAGS += -m$(BITS) + head-y := arch/tile/kernel/head_$(BITS).o libs-y += arch/tile/lib/ diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index 0d925fa0f0c1..9f94435cc44f 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig @@ -409,5 +409,4 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 149d8e8eacb8..1c5bd4f8ffca 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig @@ -189,7 +189,6 @@ CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_TTL=m @@ -521,7 +520,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRC_CCITT=m CONFIG_CRC7=m diff --git a/arch/tile/gxio/Kconfig b/arch/tile/gxio/Kconfig index d4e10d58071b..903c8646bdd7 100644 --- a/arch/tile/gxio/Kconfig +++ b/arch/tile/gxio/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Support direct access to TILE-Gx hardware from user space, via the # gxio library, or from kernel space, via kernel IORPC support. config TILE_GXIO diff --git a/arch/tile/gxio/Makefile b/arch/tile/gxio/Makefile index 26ae2c727467..fcc903c4cf87 100644 --- a/arch/tile/gxio/Makefile +++ b/arch/tile/gxio/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Tile-Gx device access support. # diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h index a93774255136..53a423e7cb92 100644 --- a/arch/tile/include/asm/atomic_32.h +++ b/arch/tile/include/asm/atomic_32.h @@ -101,6 +101,8 @@ static inline void atomic_set(atomic_t *v, int n) _atomic_xchg(&v->counter, n); } +#define atomic_set_release(v, i) atomic_set((v), (i)) + /* A 64bit atomic type */ typedef struct { diff --git a/arch/tile/include/asm/div64.h b/arch/tile/include/asm/div64.h index 9f765cdf09a5..a0a798344d5f 100644 --- a/arch/tile/include/asm/div64.h +++ b/arch/tile/include/asm/div64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_TILE_DIV64_H #define _ASM_TILE_DIV64_H diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h index bbc71a29b2c6..7061dc8af43a 100644 --- a/arch/tile/include/asm/dma-mapping.h +++ b/arch/tile/include/asm/dma-mapping.h @@ -68,8 +68,8 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) int dma_set_mask(struct device *dev, u64 mask); /* - * dma_alloc_noncoherent() is #defined to return coherent memory, - * so there's no need to do any flushing here. + * dma_alloc_attrs() always returns non-cacheable memory, so there's no need to + * do any flushing here. */ static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h index e64a1b75fc38..83c1e639b411 100644 --- a/arch/tile/include/asm/futex.h +++ b/arch/tile/include/asm/futex.h @@ -106,12 +106,9 @@ lock = __atomic_hashed_lock((int __force *)uaddr) #endif -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int uninitialized_var(val), ret; __futex_prolog(); @@ -119,12 +116,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) /* The 32-bit futex code makes this assumption, so validate it here. */ BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int)); - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -148,30 +139,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) } pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (val == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (val != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (val < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (val >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (val <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (val > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = val; + return ret; } diff --git a/arch/tile/include/asm/irq_work.h b/arch/tile/include/asm/irq_work.h index 48af33a61a2c..78d3b6a7b27a 100644 --- a/arch/tile/include/asm/irq_work.h +++ b/arch/tile/include/asm/irq_work.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_IRQ_WORK_H #define __ASM_IRQ_WORK_H diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h index b14b1ba5bf9c..cba8ba9b8da6 100644 --- a/arch/tile/include/asm/spinlock_32.h +++ b/arch/tile/include/asm/spinlock_32.h @@ -64,8 +64,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) lock->current_ticket = old_ticket + TICKET_QUANTUM; } -void arch_spin_unlock_wait(arch_spinlock_t *lock); - /* * Read-write spinlocks, allowing multiple readers * but only one writer. diff --git a/arch/tile/include/asm/spinlock_64.h b/arch/tile/include/asm/spinlock_64.h index b9718fb4e74a..9a2c2d605752 100644 --- a/arch/tile/include/asm/spinlock_64.h +++ b/arch/tile/include/asm/spinlock_64.h @@ -58,8 +58,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock) __insn_fetchadd4(&lock->lock, 1U << __ARCH_SPIN_CURRENT_SHIFT); } -void arch_spin_unlock_wait(arch_spinlock_t *lock); - void arch_spin_lock_slow(arch_spinlock_t *lock, u32 val); /* Grab the "next" ticket number and bump it atomically. diff --git a/arch/tile/include/asm/word-at-a-time.h b/arch/tile/include/asm/word-at-a-time.h index b66a693c2c34..2f2515867760 100644 --- a/arch/tile/include/asm/word-at-a-time.h +++ b/arch/tile/include/asm/word-at-a-time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_WORD_AT_A_TIME_H #define _ASM_WORD_AT_A_TIME_H diff --git a/arch/tile/include/uapi/arch/abi.h b/arch/tile/include/uapi/arch/abi.h index 328e62260272..df161a484730 100644 --- a/arch/tile/include/uapi/arch/abi.h +++ b/arch/tile/include/uapi/arch/abi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/chip.h b/arch/tile/include/uapi/arch/chip.h index 4c91f90b9369..7f55c6856c89 100644 --- a/arch/tile/include/uapi/arch/chip.h +++ b/arch/tile/include/uapi/arch/chip.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/chip_tilegx.h b/arch/tile/include/uapi/arch/chip_tilegx.h index ea8e4f2c9483..c2a71a43b21c 100644 --- a/arch/tile/include/uapi/arch/chip_tilegx.h +++ b/arch/tile/include/uapi/arch/chip_tilegx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2011 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/chip_tilepro.h b/arch/tile/include/uapi/arch/chip_tilepro.h index 70017699a74c..a8a3ed144dfe 100644 --- a/arch/tile/include/uapi/arch/chip_tilepro.h +++ b/arch/tile/include/uapi/arch/chip_tilepro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/icache.h b/arch/tile/include/uapi/arch/icache.h index 762eafa8a11e..ff85a5d77f16 100644 --- a/arch/tile/include/uapi/arch/icache.h +++ b/arch/tile/include/uapi/arch/icache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/interrupts.h b/arch/tile/include/uapi/arch/interrupts.h index 20f8f07d2de9..c288b5d82b4d 100644 --- a/arch/tile/include/uapi/arch/interrupts.h +++ b/arch/tile/include/uapi/arch/interrupts.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/interrupts_32.h b/arch/tile/include/uapi/arch/interrupts_32.h index 2efe3f68b2d6..a748752cec16 100644 --- a/arch/tile/include/uapi/arch/interrupts_32.h +++ b/arch/tile/include/uapi/arch/interrupts_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/interrupts_64.h b/arch/tile/include/uapi/arch/interrupts_64.h index 13c9f9182348..142eaff3c244 100644 --- a/arch/tile/include/uapi/arch/interrupts_64.h +++ b/arch/tile/include/uapi/arch/interrupts_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2011 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/intreg.h b/arch/tile/include/uapi/arch/intreg.h index 1cf2fbf74306..5387fb645bb8 100644 --- a/arch/tile/include/uapi/arch/intreg.h +++ b/arch/tile/include/uapi/arch/intreg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2017 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/opcode.h b/arch/tile/include/uapi/arch/opcode.h index 92d15229ecec..a9ce5961a028 100644 --- a/arch/tile/include/uapi/arch/opcode.h +++ b/arch/tile/include/uapi/arch/opcode.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2011 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/opcode_tilegx.h b/arch/tile/include/uapi/arch/opcode_tilegx.h index 9e46eaa847d4..948ea544567f 100644 --- a/arch/tile/include/uapi/arch/opcode_tilegx.h +++ b/arch/tile/include/uapi/arch/opcode_tilegx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* TILE-Gx opcode information. * * Copyright 2011 Tilera Corporation. All Rights Reserved. diff --git a/arch/tile/include/uapi/arch/opcode_tilepro.h b/arch/tile/include/uapi/arch/opcode_tilepro.h index 4451cff1a861..0d633688de63 100644 --- a/arch/tile/include/uapi/arch/opcode_tilepro.h +++ b/arch/tile/include/uapi/arch/opcode_tilepro.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* TILEPro opcode information. * * Copyright 2011 Tilera Corporation. All Rights Reserved. diff --git a/arch/tile/include/uapi/arch/sim.h b/arch/tile/include/uapi/arch/sim.h index e54b7b0527f3..c4183dcd2ea7 100644 --- a/arch/tile/include/uapi/arch/sim.h +++ b/arch/tile/include/uapi/arch/sim.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/sim_def.h b/arch/tile/include/uapi/arch/sim_def.h index 1c069537ae41..f74f9943770d 100644 --- a/arch/tile/include/uapi/arch/sim_def.h +++ b/arch/tile/include/uapi/arch/sim_def.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/spr_def.h b/arch/tile/include/uapi/arch/spr_def.h index c250c5adb1a6..743428615cda 100644 --- a/arch/tile/include/uapi/arch/spr_def.h +++ b/arch/tile/include/uapi/arch/spr_def.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/spr_def_32.h b/arch/tile/include/uapi/arch/spr_def_32.h index 78daa3146d25..64122d6160e1 100644 --- a/arch/tile/include/uapi/arch/spr_def_32.h +++ b/arch/tile/include/uapi/arch/spr_def_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/arch/spr_def_64.h b/arch/tile/include/uapi/arch/spr_def_64.h index 67a6c1751e3b..d183cbb31aa7 100644 --- a/arch/tile/include/uapi/arch/spr_def_64.h +++ b/arch/tile/include/uapi/arch/spr_def_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2011 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/auxvec.h b/arch/tile/include/uapi/asm/auxvec.h index f497123ed980..922383ce8f4f 100644 --- a/arch/tile/include/uapi/asm/auxvec.h +++ b/arch/tile/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/bitsperlong.h b/arch/tile/include/uapi/asm/bitsperlong.h index 58c771f2af2f..57cca78c0fbb 100644 --- a/arch/tile/include/uapi/asm/bitsperlong.h +++ b/arch/tile/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/byteorder.h b/arch/tile/include/uapi/asm/byteorder.h index 6b8fa2e1cf6e..d508e61c1e56 100644 --- a/arch/tile/include/uapi/asm/byteorder.h +++ b/arch/tile/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2011 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/cachectl.h b/arch/tile/include/uapi/asm/cachectl.h index 572ddcad2090..ed8bac28a1b9 100644 --- a/arch/tile/include/uapi/asm/cachectl.h +++ b/arch/tile/include/uapi/asm/cachectl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2011 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/hardwall.h b/arch/tile/include/uapi/asm/hardwall.h index c2169d4f4010..f02e9132ae71 100644 --- a/arch/tile/include/uapi/asm/hardwall.h +++ b/arch/tile/include/uapi/asm/hardwall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/kvm_para.h b/arch/tile/include/uapi/asm/kvm_para.h index 14fab8f0b957..baacc4996d18 100644 --- a/arch/tile/include/uapi/asm/kvm_para.h +++ b/arch/tile/include/uapi/asm/kvm_para.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/arch/tile/include/uapi/asm/mman.h b/arch/tile/include/uapi/asm/mman.h index 63ee13faf17d..9b7add95926b 100644 --- a/arch/tile/include/uapi/asm/mman.h +++ b/arch/tile/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/ptrace.h b/arch/tile/include/uapi/asm/ptrace.h index d03b829857e8..667ed742f4dd 100644 --- a/arch/tile/include/uapi/asm/ptrace.h +++ b/arch/tile/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/setup.h b/arch/tile/include/uapi/asm/setup.h index e6f7da265ac3..6d1dfdddad6c 100644 --- a/arch/tile/include/uapi/asm/setup.h +++ b/arch/tile/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/sigcontext.h b/arch/tile/include/uapi/asm/sigcontext.h index 39ff5d1a232d..4003d5cc9202 100644 --- a/arch/tile/include/uapi/asm/sigcontext.h +++ b/arch/tile/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/siginfo.h b/arch/tile/include/uapi/asm/siginfo.h index 56d661bb010b..f234d24fff55 100644 --- a/arch/tile/include/uapi/asm/siginfo.h +++ b/arch/tile/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * @@ -26,8 +27,8 @@ /* * Additional Tile-specific SIGILL si_codes */ -#define ILL_DBLFLT (__SI_FAULT|9) /* double fault */ -#define ILL_HARDWALL (__SI_FAULT|10) /* user networks hardwall violation */ +#define ILL_DBLFLT 9 /* double fault */ +#define ILL_HARDWALL 10 /* user networks hardwall violation */ #undef NSIGILL #define NSIGILL 10 diff --git a/arch/tile/include/uapi/asm/signal.h b/arch/tile/include/uapi/asm/signal.h index ef0d32d84a4c..7b3c814e00f0 100644 --- a/arch/tile/include/uapi/asm/signal.h +++ b/arch/tile/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/stat.h b/arch/tile/include/uapi/asm/stat.h index c0db34d56be3..ea03de7d67aa 100644 --- a/arch/tile/include/uapi/asm/stat.h +++ b/arch/tile/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #if defined(__KERNEL__) && defined(CONFIG_COMPAT) #define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */ #endif diff --git a/arch/tile/include/uapi/asm/swab.h b/arch/tile/include/uapi/asm/swab.h index 7c37b38f6c8d..36952353a31d 100644 --- a/arch/tile/include/uapi/asm/swab.h +++ b/arch/tile/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/include/uapi/asm/unistd.h b/arch/tile/include/uapi/asm/unistd.h index 24e9187e85a8..1a169ec92ef8 100644 --- a/arch/tile/include/uapi/asm/unistd.h +++ b/arch/tile/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile index 09936d0bcb42..3e43d78731a8 100644 --- a/arch/tile/kernel/Makefile +++ b/arch/tile/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Linux/TILE kernel. # diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 0e863f1ee08c..971d87a1d8cf 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c @@ -64,7 +64,7 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr 3 ints plus the relevant union member. */ err = __put_user(from->si_signo, &to->si_signo); err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); + err |= __put_user(from->si_code, &to->si_code); if (from->si_code < 0) { err |= __put_user(from->si_pid, &to->si_pid); @@ -77,28 +77,26 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *fr */ err |= __put_user(from->_sifields._pad[0], &to->_sifields._pad[0]); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: + switch (siginfo_layout(from->si_signo, from->si_code)) { + case SIL_FAULT: break; - case __SI_CHLD >> 16: + case SIL_CHLD: err |= __put_user(from->si_utime, &to->si_utime); err |= __put_user(from->si_stime, &to->si_stime); err |= __put_user(from->si_status, &to->si_status); /* FALL THROUGH */ default: - case __SI_KILL >> 16: + case SIL_KILL: err |= __put_user(from->si_uid, &to->si_uid); break; - case __SI_POLL >> 16: + case SIL_POLL: err |= __put_user(from->si_fd, &to->si_fd); break; - case __SI_TIMER >> 16: + case SIL_TIMER: err |= __put_user(from->si_overrun, &to->si_overrun); err |= __put_user(from->si_int, &to->si_int); break; - /* This is not generated by the kernel as of now. */ - case __SI_RT >> 16: - case __SI_MESGQ >> 16: + case SIL_RT: err |= __put_user(from->si_uid, &to->si_uid); err |= __put_user(from->si_int, &to->si_int); break; diff --git a/arch/tile/kernel/hvglue.S b/arch/tile/kernel/hvglue.S index d78ee2ad610c..70c661448638 100644 --- a/arch/tile/kernel/hvglue.S +++ b/arch/tile/kernel/hvglue.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Hypervisor call vector addresses; see */ .macro gensym sym, val, size .org \val diff --git a/arch/tile/kernel/pci.c b/arch/tile/kernel/pci.c index bc6656b5708b..bbf81579b1f8 100644 --- a/arch/tile/kernel/pci.c +++ b/arch/tile/kernel/pci.c @@ -66,16 +66,6 @@ static int pci_scan_flags[TILE_NUM_PCIE]; static struct pci_ops tile_cfg_ops; -/* - * We don't need to worry about the alignment of resources. - */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - /* * Open a FD to the hypervisor PCI device. * @@ -274,6 +264,7 @@ static void fixup_read_and_payload_sizes(void) */ int __init pcibios_init(void) { + struct pci_host_bridge *bridge; int i; pr_info("PCI: Probing PCI hardware\n"); @@ -306,16 +297,26 @@ int __init pcibios_init(void) pci_add_resource(&resources, &ioport_resource); pci_add_resource(&resources, &iomem_resource); - bus = pci_scan_root_bus(NULL, 0, controller->ops, - controller, &resources); + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + break; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = controller; + bridge->busnr = 0; + bridge->ops = controller->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = tile_map_irq; + + pci_scan_root_bus_bridge(bridge); + bus = bridge->bus; controller->root_bus = bus; controller->last_busno = bus->busn_res.end; } } - /* Do machine dependent PCI interrupt routing */ - pci_fixup_irqs(pci_common_swizzle, tile_map_irq); - /* * This comes from the generic Linux PCI driver. * @@ -369,14 +370,6 @@ int __init pcibios_init(void) } subsys_initcall(pcibios_init); -/* - * No bus fixups needed. - */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Nothing needs to be done. */ -} - void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling. */ diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index b554a68eea1b..9aa238ac7b35 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c @@ -108,15 +108,6 @@ static struct pci_ops tile_cfg_ops; /* Mask of CPUs that should receive PCIe interrupts. */ static struct cpumask intr_cpus_map; -/* We don't need to worry about the alignment of resources. */ -resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, - resource_size_t align) -{ - return res->start; -} -EXPORT_SYMBOL(pcibios_align_resource); - /* * Pick a CPU to receive and handle the PCIe interrupts, based on the IRQ #. * For now, we simply send interrupts to non-dataplane CPUs. @@ -669,6 +660,7 @@ int __init pcibios_init(void) resource_size_t offset; LIST_HEAD(resources); int next_busno; + struct pci_host_bridge *bridge; int i; tile_pci_init(); @@ -881,15 +873,25 @@ int __init pcibios_init(void) controller->mem_offset); pci_add_resource(&resources, &controller->io_space); controller->first_busno = next_busno; - bus = pci_scan_root_bus(NULL, next_busno, controller->ops, - controller, &resources); + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + break; + + list_splice_init(&resources, &bridge->windows); + bridge->dev.parent = NULL; + bridge->sysdata = controller; + bridge->busnr = next_busno; + bridge->ops = controller->ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = tile_map_irq; + + pci_scan_root_bus_bridge(bridge); + bus = bridge->bus; controller->root_bus = bus; next_busno = bus->busn_res.end + 1; } - /* Do machine dependent PCI interrupt routing */ - pci_fixup_irqs(pci_common_swizzle, tile_map_irq); - /* * This comes from the generic Linux PCI driver. * @@ -1038,11 +1040,6 @@ alloc_mem_map_failed: } subsys_initcall(pcibios_init); -/* No bus fixups needed. */ -void pcibios_fixup_bus(struct pci_bus *bus) -{ -} - /* Process any "pci=" kernel boot arguments. */ char *__init pcibios_setup(char *str) { diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index 443a70bccc1c..ad83c1e66dbd 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -140,7 +140,7 @@ static int __init setup_maxnodemem(char *str) { char *endp; unsigned long long maxnodemem; - long node; + unsigned long node; node = str ? simple_strtoul(str, &endp, 0) : INT_MAX; if (node >= MAX_NUMNODES || *endp != ':') @@ -1200,7 +1200,7 @@ static void __init validate_hv(void) * We use a struct cpumask for this, so it must be big enough. */ if ((smp_height * smp_width) > nr_cpu_ids) - early_panic("Hypervisor %d x %d grid too big for Linux NR_CPUS %d\n", + early_panic("Hypervisor %d x %d grid too big for Linux NR_CPUS %u\n", smp_height, smp_width, nr_cpu_ids); #endif diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index 6643ffbc0615..f95d65f3162b 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -162,6 +162,7 @@ static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = { .set_next_event = tile_timer_set_next_event, .set_state_shutdown = tile_timer_shutdown, .set_state_oneshot = tile_timer_shutdown, + .set_state_oneshot_stopped = tile_timer_shutdown, .tick_resume = tile_timer_shutdown, }; diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index 54804866f238..9b08c6055f15 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c @@ -188,7 +188,7 @@ static int special_ill(tile_bundle_bits bundle, int *sigp, int *codep) /* Make it the requested signal. */ *sigp = sig; - *codep = code | __SI_FAULT; + *codep = code; return 1; } diff --git a/arch/tile/kernel/vdso/Makefile b/arch/tile/kernel/vdso/Makefile index 71d5f5d71f79..b596a7396382 100644 --- a/arch/tile/kernel/vdso/Makefile +++ b/arch/tile/kernel/vdso/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Symbols present in the vdso vdso-syms = rt_sigreturn gettimeofday diff --git a/arch/tile/kernel/vmlinux.lds.S b/arch/tile/kernel/vmlinux.lds.S index e1baf094fba4..3558d981e336 100644 --- a/arch/tile/kernel/vmlinux.lds.S +++ b/arch/tile/kernel/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/tile/kvm/Kconfig b/arch/tile/kvm/Kconfig index 1e968f7550dc..efce89a8473b 100644 --- a/arch/tile/kvm/Kconfig +++ b/arch/tile/kvm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # KVM configuration # diff --git a/arch/tile/lib/Makefile b/arch/tile/lib/Makefile index c4211cbb2021..815a1fdeb2e4 100644 --- a/arch/tile/lib/Makefile +++ b/arch/tile/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for TILE-specific library files.. # diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c index 076c6cc43113..db9333f2447c 100644 --- a/arch/tile/lib/spinlock_32.c +++ b/arch/tile/lib/spinlock_32.c @@ -62,29 +62,6 @@ int arch_spin_trylock(arch_spinlock_t *lock) } EXPORT_SYMBOL(arch_spin_trylock); -void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - u32 iterations = 0; - int curr = READ_ONCE(lock->current_ticket); - int next = READ_ONCE(lock->next_ticket); - - /* Return immediately if unlocked. */ - if (next == curr) - return; - - /* Wait until the current locker has released the lock. */ - do { - delay_backoff(iterations++); - } while (READ_ONCE(lock->current_ticket) == curr); - - /* - * The TILE architecture doesn't do read speculation; therefore - * a control dependency guarantees a LOAD->{LOAD,STORE} order. - */ - barrier(); -} -EXPORT_SYMBOL(arch_spin_unlock_wait); - /* * The low byte is always reserved to be the marker for a "tns" operation * since the low bit is set to "1" by a tns. The next seven bits are diff --git a/arch/tile/lib/spinlock_64.c b/arch/tile/lib/spinlock_64.c index a4b5b2cbce93..de414c22892f 100644 --- a/arch/tile/lib/spinlock_64.c +++ b/arch/tile/lib/spinlock_64.c @@ -62,28 +62,6 @@ int arch_spin_trylock(arch_spinlock_t *lock) } EXPORT_SYMBOL(arch_spin_trylock); -void arch_spin_unlock_wait(arch_spinlock_t *lock) -{ - u32 iterations = 0; - u32 val = READ_ONCE(lock->lock); - u32 curr = arch_spin_current(val); - - /* Return immediately if unlocked. */ - if (arch_spin_next(val) == curr) - return; - - /* Wait until the current locker has released the lock. */ - do { - delay_backoff(iterations++); - } while (arch_spin_current(READ_ONCE(lock->lock)) == curr); - - /* - * The TILE architecture doesn't do read speculation; therefore - * a control dependency guarantees a LOAD->{LOAD,STORE} order. - */ - barrier(); -} -EXPORT_SYMBOL(arch_spin_unlock_wait); /* * If the read lock fails due to a writer, we retry periodically diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index f10738d68b2d..f184bde7030e 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "UML Character Devices" config STDERR_CONSOLE diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 85f6dd204ab6..d9280482a2f8 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config UML bool default y diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index 68205fd3b08c..967d3109689f 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/um/Kconfig.net b/arch/um/Kconfig.net index 820a56f00332..e871af24d9cd 100644 --- a/arch/um/Kconfig.net +++ b/arch/um/Kconfig.net @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "UML Network Devices" depends on NET diff --git a/arch/um/Kconfig.rest b/arch/um/Kconfig.rest index 567eb5fc21df..08327b9c0cbe 100644 --- a/arch/um/Kconfig.rest +++ b/arch/um/Kconfig.rest @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 source "init/Kconfig" source "kernel/Kconfig.freezer" diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index 4b2ed5858b2e..3e7f228b22e1 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config STATIC_LINK bool "Force a static link" default n @@ -20,6 +21,7 @@ config LD_SCRIPT_DYN bool default y depends on !LD_SCRIPT_STATIC + select MODULE_REL_CRCS if MODVERSIONS source "fs/Kconfig.binfmt" diff --git a/arch/um/Makefile b/arch/um/Makefile index 6ca4f66085c1..b76fcce397a1 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -121,7 +121,7 @@ archheaders: archprepare: include/generated/user_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib +LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie) CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ $(call cc-option, -fno-stack-protector,) \ diff --git a/arch/um/configs/i386_defconfig b/arch/um/configs/i386_defconfig index 5636221b8785..8f114e3b0a7a 100644 --- a/arch/um/configs/i386_defconfig +++ b/arch/um/configs/i386_defconfig @@ -53,7 +53,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UML_NET=y CONFIG_UML_NET_ETHERTAP=y diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig index 7a67b7ac1a7e..5d0875fc0db2 100644 --- a/arch/um/configs/x86_64_defconfig +++ b/arch/um/configs/x86_64_defconfig @@ -51,7 +51,6 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_UML_NET=y CONFIG_UML_NET_ETHERTAP=y diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h index 6673508f3426..760c507dd5b6 100644 --- a/arch/um/drivers/cow.h +++ b/arch/um/drivers/cow.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __COW_H__ #define __COW_H__ diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index 67cbee63e702..916811ef5317 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __COW_SYS_H__ #define __COW_SYS_H__ diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index af326fb6510d..c4d162a94be9 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -148,12 +148,7 @@ void mconsole_proc(struct mc_request *req) } do { - loff_t pos = file->f_pos; - mm_segment_t old_fs = get_fs(); - set_fs(KERNEL_DS); - len = vfs_read(file, buf, PAGE_SIZE - 1, &pos); - set_fs(old_fs); - file->f_pos = pos; + len = kernel_read(file, buf, PAGE_SIZE - 1, &file->f_pos); if (len < 0) { mconsole_reply(req, "Read of file failed", 1, 0); goto out_free; diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h index c64f8c61d274..0f3b7ca99465 100644 --- a/arch/um/drivers/slip.h +++ b/arch/um/drivers/slip.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_SLIP_H #define __UM_SLIP_H diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c index f597fa7c91d3..20fe4f42743d 100644 --- a/arch/um/drivers/slip_common.c +++ b/arch/um/drivers/slip_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "slip_common.h" #include diff --git a/arch/um/drivers/slip_common.h b/arch/um/drivers/slip_common.h index d574e0a9dc13..d3798b5caf7f 100644 --- a/arch/um/drivers/slip_common.h +++ b/arch/um/drivers/slip_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_SLIP_COMMON_H #define __UM_SLIP_COMMON_H diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h index 89ccf83b7577..4aef2b88249a 100644 --- a/arch/um/drivers/slirp.h +++ b/arch/um/drivers/slirp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_SLIRP_H #define __UM_SLIRP_H diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index d07a97f8b994..ecc3a5814932 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/um/include/asm/bugs.h b/arch/um/include/asm/bugs.h index 6a72e240d5fc..4473942a0839 100644 --- a/arch/um/include/asm/bugs.h +++ b/arch/um/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_BUGS_H #define __UM_BUGS_H diff --git a/arch/um/include/asm/cache.h b/arch/um/include/asm/cache.h index 19e1bdd67416..5c156273484b 100644 --- a/arch/um/include/asm/cache.h +++ b/arch/um/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_CACHE_H #define __UM_CACHE_H diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S index 9e6d5997cfc4..b30d73ca29d0 100644 --- a/arch/um/include/asm/common.lds.S +++ b/arch/um/include/asm/common.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include .fini : { *(.fini) } =0x9090 diff --git a/arch/um/include/asm/dma.h b/arch/um/include/asm/dma.h index f88c5860520b..fdc53642c718 100644 --- a/arch/um/include/asm/dma.h +++ b/arch/um/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_DMA_H #define __UM_DMA_H diff --git a/arch/um/include/asm/fixmap.h b/arch/um/include/asm/fixmap.h index 1761fd75bf13..2c697a145ac1 100644 --- a/arch/um/include/asm/fixmap.h +++ b/arch/um/include/asm/fixmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_FIXMAP_H #define __UM_FIXMAP_H diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h index 756f0778e327..b426796d26fd 100644 --- a/arch/um/include/asm/hardirq.h +++ b/arch/um/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_UM_HARDIRQ_H #define __ASM_UM_HARDIRQ_H diff --git a/arch/um/include/asm/io.h b/arch/um/include/asm/io.h index 8f35d574f35b..96f77b5232aa 100644 --- a/arch/um/include/asm/io.h +++ b/arch/um/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_UM_IO_H #define _ASM_UM_IO_H diff --git a/arch/um/include/asm/irq.h b/arch/um/include/asm/irq.h index 4a2037f8204b..b5cdd3f91157 100644 --- a/arch/um/include/asm/irq.h +++ b/arch/um/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_IRQ_H #define __UM_IRQ_H diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h index 3bb221e1d5a4..cbc6c0013a64 100644 --- a/arch/um/include/asm/irqflags.h +++ b/arch/um/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_IRQFLAGS_H #define __UM_IRQFLAGS_H diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index f6d1a3f747a9..86942a492454 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -58,11 +58,6 @@ static inline void release_thread(struct task_struct *task) { } -static inline void mm_copy_segments(struct mm_struct *from_mm, - struct mm_struct *new_mm) -{ -} - #define init_stack (init_thread_union.stack) /* diff --git a/arch/um/include/asm/sections.h b/arch/um/include/asm/sections.h index cafcf684d947..a3c1fb6ed6ad 100644 --- a/arch/um/include/asm/sections.h +++ b/arch/um/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_SECTIONS_H #define __UM_SECTIONS_H diff --git a/arch/um/include/asm/setup.h b/arch/um/include/asm/setup.h index 99f086301f4c..80ada899f254 100644 --- a/arch/um/include/asm/setup.h +++ b/arch/um/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SETUP_H_INCLUDED #define SETUP_H_INCLUDED diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h index 9c3be355ed01..a8cc1d46ddcb 100644 --- a/arch/um/include/asm/smp.h +++ b/arch/um/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_SMP_H #define __UM_SMP_H diff --git a/arch/um/include/asm/stacktrace.h b/arch/um/include/asm/stacktrace.h index 9a864328c67f..436b55952c3a 100644 --- a/arch/um/include/asm/stacktrace.h +++ b/arch/um/include/asm/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_UML_STACKTRACE_H #define _ASM_UML_STACKTRACE_H diff --git a/arch/um/include/asm/sysrq.h b/arch/um/include/asm/sysrq.h index c8d332b56b98..8fc8c65cd357 100644 --- a/arch/um/include/asm/sysrq.h +++ b/arch/um/include/asm/sysrq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_SYSRQ_H #define __UM_SYSRQ_H diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index 053baff03674..9300f7630d2a 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -11,6 +11,7 @@ #include #include #include +#include struct thread_info { struct task_struct *task; /* main task structure */ @@ -22,6 +23,8 @@ struct thread_info { 0-0xBFFFFFFF for user 0-0xFFFFFFFF for kernel */ 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) \ diff --git a/arch/um/include/asm/timex.h b/arch/um/include/asm/timex.h index 0f4ada08f748..e392a9a5bc9b 100644 --- a/arch/um/include/asm/timex.h +++ b/arch/um/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_TIMEX_H #define __UM_TIMEX_H diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h index 344d95619d03..dce6db147f24 100644 --- a/arch/um/include/asm/tlb.h +++ b/arch/um/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UM_TLB_H #define __UM_TLB_H diff --git a/arch/um/include/asm/unwind.h b/arch/um/include/asm/unwind.h new file mode 100644 index 000000000000..7ffa5437b761 --- /dev/null +++ b/arch/um/include/asm/unwind.h @@ -0,0 +1,8 @@ +#ifndef _ASM_UML_UNWIND_H +#define _ASM_UML_UNWIND_H + +static inline void +unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size) {} + +#endif /* _ASM_UML_UNWIND_H */ diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h index c92306809029..4e99fe05576a 100644 --- a/arch/um/include/shared/common-offsets.h +++ b/arch/um/include/shared/common-offsets.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* for use by sys-$SUBARCH/kernel-offsets.c */ DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); diff --git a/arch/um/include/shared/init.h b/arch/um/include/shared/init.h index 233e2593eee0..390572daa40d 100644 --- a/arch/um/include/shared/init.h +++ b/arch/um/include/shared/init.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_UML_INIT_H #define _LINUX_UML_INIT_H diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h index 9bdddf4c405b..b3315c1f198b 100644 --- a/arch/um/include/shared/longjmp.h +++ b/arch/um/include/shared/longjmp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UML_LONGJMP_H #define __UML_LONGJMP_H diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 574e03fc7ba2..d8ddaf9790d2 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -278,7 +278,7 @@ extern int protect(struct mm_id * mm_idp, unsigned long addr, extern int is_skas_winch(int pid, int fd, void *data); extern int start_userspace(unsigned long stub_stack); extern int copy_context_skas0(unsigned long stack, int pid); -extern void userspace(struct uml_pt_regs *regs); +extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs); extern int map_stub_pages(int fd, unsigned long code, unsigned long data, unsigned long stack); extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 4fdbcf958cd5..d417e3899700 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c index 1bf61266da8e..f138a4a0db99 100644 --- a/arch/um/kernel/gmon_syms.c +++ b/arch/um/kernel/gmon_syms.c @@ -7,3 +7,10 @@ extern void __bb_init_func(void *) __attribute__((weak)); EXPORT_SYMBOL(__bb_init_func); + +extern void __gcov_init(void *) __attribute__((weak)); +EXPORT_SYMBOL(__gcov_init); +extern void __gcov_merge_add(void *, unsigned int) __attribute__((weak)); +EXPORT_SYMBOL(__gcov_merge_add); +extern void __gcov_exit(void) __attribute__((weak)); +EXPORT_SYMBOL(__gcov_exit); diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c index 407d49251d6f..98bdf69e4c2e 100644 --- a/arch/um/kernel/kmsg_dump.c +++ b/arch/um/kernel/kmsg_dump.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 2c7f721eccbc..691b83b10649 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -131,7 +131,7 @@ void new_thread_handler(void) * callback returns only if the kernel thread execs a process */ n = fn(arg); - userspace(¤t->thread.regs.regs); + userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); } /* Called magically, see new_thread_handler above */ @@ -150,7 +150,7 @@ void fork_handler(void) current->thread.prev_sched = NULL; - userspace(¤t->thread.regs.regs); + userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); } int copy_thread(unsigned long clone_flags, unsigned long sp, diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index 0b034ebbda2a..7f69d17de354 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c @@ -98,7 +98,7 @@ static struct clocksource timer_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init timer_setup(void) +static void __init um_timer_setup(void) { int err; @@ -132,5 +132,5 @@ void read_persistent_clock(struct timespec *ts) void __init time_init(void) { timer_set_signal_handler(); - late_time_init = timer_setup; + late_time_init = um_timer_setup; } diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 1840f55ed042..3d6ed6ba5b78 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index c2e6e1dad876..db24ce0d09a6 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -80,7 +80,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, pid = run_helper(tuntap_pre_exec, &data, argv); if (pid < 0) - return -pid; + return pid; close(remote); diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 1a365ddc4d02..77a9321379b7 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/um/kernel/elf_aux.c * diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 819d68656673..c94c3bd70ccd 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -88,12 +88,11 @@ bad_wait: extern unsigned long current_stub_stack(void); -static void get_skas_faultinfo(int pid, struct faultinfo *fi) +static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux_fp_regs) { int err; - unsigned long fpregs[FP_SIZE]; - err = get_fp_registers(pid, fpregs); + err = get_fp_registers(pid, aux_fp_regs); if (err < 0) { printk(UM_KERN_ERR "save_fp_registers returned %d\n", err); @@ -113,7 +112,7 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi) */ memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); - err = put_fp_registers(pid, fpregs); + err = put_fp_registers(pid, aux_fp_regs); if (err < 0) { printk(UM_KERN_ERR "put_fp_registers returned %d\n", err); @@ -121,9 +120,9 @@ static void get_skas_faultinfo(int pid, struct faultinfo *fi) } } -static void handle_segv(int pid, struct uml_pt_regs * regs) +static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp_regs) { - get_skas_faultinfo(pid, ®s->faultinfo); + get_skas_faultinfo(pid, ®s->faultinfo, aux_fp_regs); segv(regs->faultinfo, 0, 1, NULL); } @@ -332,7 +331,7 @@ int start_userspace(unsigned long stub_stack) return err; } -void userspace(struct uml_pt_regs *regs) +void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) { int err, status, op, pid = userspace_pid[0]; /* To prevent races if using_sysemu changes under us.*/ @@ -407,11 +406,11 @@ void userspace(struct uml_pt_regs *regs) case SIGSEGV: if (PTRACE_FULL_FAULTINFO) { get_skas_faultinfo(pid, - ®s->faultinfo); + ®s->faultinfo, aux_fp_regs); (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, regs); } - else handle_segv(pid, regs); + else handle_segv(pid, regs, aux_fp_regs); break; case SIGTRAP + 0x80: handle_trap(pid, regs, local_using_sysemu); diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index b1b6b75c5b17..82bf5f8442ba 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c @@ -154,10 +154,10 @@ static int __init nosysemu_cmd_param(char *str, int* add) __uml_setup("nosysemu", nosysemu_cmd_param, "nosysemu\n" -" Turns off syscall emulation patch for ptrace (SYSEMU) on.\n" +" Turns off syscall emulation patch for ptrace (SYSEMU).\n" " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n" -" behaviour of ptrace() and helps reducing host context switch rate.\n" -" To make it working, you need a kernel patch for your host, too.\n" +" behaviour of ptrace() and helps reduce host context switch rates.\n" +" To make it work, you need a kernel patch for your host, too.\n" " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n" " information.\n\n"); diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index db4a034aeee1..715594fe5719 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 15889df9b466..a4dfa7d7636e 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # =========================================================================== # arch/um: Generic definitions # =========================================================================== diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 0769066929c6..d39f0bc6a046 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config UNICORE32 def_bool y select ARCH_HAS_DEVMEM_IS_ALLOWED diff --git a/arch/unicore32/Kconfig.debug b/arch/unicore32/Kconfig.debug index f075bbe1d46f..de8dae3abc0a 100644 --- a/arch/unicore32/Kconfig.debug +++ b/arch/unicore32/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" source "lib/Kconfig.debug" diff --git a/arch/unicore32/include/mach/regs-ac97.h b/arch/unicore32/include/mach/regs-ac97.h index b7563e9d6503..85c601898d02 100644 --- a/arch/unicore32/include/mach/regs-ac97.h +++ b/arch/unicore32/include/mach/regs-ac97.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity AC97 Registers */ diff --git a/arch/unicore32/include/mach/regs-dmac.h b/arch/unicore32/include/mach/regs-dmac.h index 66de9e7d1c8f..bbdc52d06a98 100644 --- a/arch/unicore32/include/mach/regs-dmac.h +++ b/arch/unicore32/include/mach/regs-dmac.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Direct Memory Access Controller (DMAC) */ diff --git a/arch/unicore32/include/mach/regs-gpio.h b/arch/unicore32/include/mach/regs-gpio.h index 0273b861ef96..806350e1ccb6 100644 --- a/arch/unicore32/include/mach/regs-gpio.h +++ b/arch/unicore32/include/mach/regs-gpio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity General-Purpose Input/Output (GPIO) Registers */ diff --git a/arch/unicore32/include/mach/regs-i2c.h b/arch/unicore32/include/mach/regs-i2c.h index 463d108f8bfb..b41aa7c92430 100644 --- a/arch/unicore32/include/mach/regs-i2c.h +++ b/arch/unicore32/include/mach/regs-i2c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Inter-integrated Circuit (I2C) Registers */ diff --git a/arch/unicore32/include/mach/regs-intc.h b/arch/unicore32/include/mach/regs-intc.h index 25648f89cbd3..4eb1b5b571bb 100644 --- a/arch/unicore32/include/mach/regs-intc.h +++ b/arch/unicore32/include/mach/regs-intc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUNITY Interrupt Controller (INTC) Registers */ diff --git a/arch/unicore32/include/mach/regs-nand.h b/arch/unicore32/include/mach/regs-nand.h index a7c5563bb550..7f29939251ef 100644 --- a/arch/unicore32/include/mach/regs-nand.h +++ b/arch/unicore32/include/mach/regs-nand.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity NAND Controller Registers */ diff --git a/arch/unicore32/include/mach/regs-ost.h b/arch/unicore32/include/mach/regs-ost.h index 4a85fb463848..6c63e7b7569e 100644 --- a/arch/unicore32/include/mach/regs-ost.h +++ b/arch/unicore32/include/mach/regs-ost.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Operating System Timer (OST) Registers */ diff --git a/arch/unicore32/include/mach/regs-pci.h b/arch/unicore32/include/mach/regs-pci.h index 6a9341686bf8..25bb307b87c3 100644 --- a/arch/unicore32/include/mach/regs-pci.h +++ b/arch/unicore32/include/mach/regs-pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity AHB-PCI Bridge Registers */ diff --git a/arch/unicore32/include/mach/regs-pm.h b/arch/unicore32/include/mach/regs-pm.h index 854844aa8f4b..777b1ace39b9 100644 --- a/arch/unicore32/include/mach/regs-pm.h +++ b/arch/unicore32/include/mach/regs-pm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUNITY Power Manager (PM) Registers */ diff --git a/arch/unicore32/include/mach/regs-ps2.h b/arch/unicore32/include/mach/regs-ps2.h index 17d4e6dc0069..d539d7482462 100644 --- a/arch/unicore32/include/mach/regs-ps2.h +++ b/arch/unicore32/include/mach/regs-ps2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity PS2 Controller Registers */ diff --git a/arch/unicore32/include/mach/regs-resetc.h b/arch/unicore32/include/mach/regs-resetc.h index 39900cf4c936..5f2b9d77a9ec 100644 --- a/arch/unicore32/include/mach/regs-resetc.h +++ b/arch/unicore32/include/mach/regs-resetc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Reset Controller (RC) Registers */ diff --git a/arch/unicore32/include/mach/regs-rtc.h b/arch/unicore32/include/mach/regs-rtc.h index e94ca193271d..f2f7f47eb65e 100644 --- a/arch/unicore32/include/mach/regs-rtc.h +++ b/arch/unicore32/include/mach/regs-rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Real-Time Clock (RTC) control registers */ diff --git a/arch/unicore32/include/mach/regs-sdc.h b/arch/unicore32/include/mach/regs-sdc.h index 1303ecf660ba..658bfaf4cb3c 100644 --- a/arch/unicore32/include/mach/regs-sdc.h +++ b/arch/unicore32/include/mach/regs-sdc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Multi-Media Card and Security Digital Card (MMC/SD) Registers */ diff --git a/arch/unicore32/include/mach/regs-spi.h b/arch/unicore32/include/mach/regs-spi.h index de16895e2dc0..3460647a9c2a 100644 --- a/arch/unicore32/include/mach/regs-spi.h +++ b/arch/unicore32/include/mach/regs-spi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Serial Peripheral Interface (SPI) Registers */ diff --git a/arch/unicore32/include/mach/regs-umal.h b/arch/unicore32/include/mach/regs-umal.h index aa22df74e11d..7023089c61c6 100644 --- a/arch/unicore32/include/mach/regs-umal.h +++ b/arch/unicore32/include/mach/regs-umal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity Ultra Media Access Layer (UMAL) Ethernet MAC Registers */ diff --git a/arch/unicore32/include/mach/regs-unigfx.h b/arch/unicore32/include/mach/regs-unigfx.h index faf8b287fccf..553d1157c6b2 100644 --- a/arch/unicore32/include/mach/regs-unigfx.h +++ b/arch/unicore32/include/mach/regs-unigfx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PKUnity UNIGFX Registers */ diff --git a/arch/unicore32/include/uapi/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h index ebe1b3fef3e3..864fe4814cf4 100644 --- a/arch/unicore32/include/uapi/asm/byteorder.h +++ b/arch/unicore32/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * linux/arch/unicore32/include/asm/byteorder.h * diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h index 187aa2e98a53..2820de83e37d 100644 --- a/arch/unicore32/include/uapi/asm/ptrace.h +++ b/arch/unicore32/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * linux/arch/unicore32/include/asm/ptrace.h * diff --git a/arch/unicore32/include/uapi/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h index 6a2d7671c052..79e56f28e4b5 100644 --- a/arch/unicore32/include/uapi/asm/sigcontext.h +++ b/arch/unicore32/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * linux/arch/unicore32/include/asm/sigcontext.h * diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 1f63c476528e..65856eaab163 100644 --- a/arch/unicore32/include/uapi/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * linux/arch/unicore32/include/asm/unistd.h * diff --git a/arch/unicore32/kernel/Makefile b/arch/unicore32/kernel/Makefile index 607a72f2ae35..2f79aa56735b 100644 --- a/arch/unicore32/kernel/Makefile +++ b/arch/unicore32/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # diff --git a/arch/unicore32/kernel/ksyms.h b/arch/unicore32/kernel/ksyms.h index 31472ad9467a..5d2d5ba324ac 100644 --- a/arch/unicore32/kernel/ksyms.h +++ b/arch/unicore32/kernel/ksyms.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index 1053bca1f8aa..9f26840e41b1 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c @@ -101,7 +101,7 @@ void pci_puv3_preinit(void) writel(readl(PCIBRI_CMD) | PCIBRI_CMD_IO | PCIBRI_CMD_MEM, PCIBRI_CMD); } -static int __init pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int pci_puv3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->bus->number == 0) { #ifdef CONFIG_ARCH_FPGA /* 4 pci slots */ @@ -252,19 +252,46 @@ void pcibios_fixup_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pcibios_fixup_bus); +static struct resource busn_resource = { + .name = "PCI busn", + .start = 0, + .end = 255, + .flags = IORESOURCE_BUS, +}; + static int __init pci_common_init(void) { struct pci_bus *puv3_bus; + struct pci_host_bridge *bridge; + int ret; + + bridge = pci_alloc_host_bridge(0); + if (!bridge) + return -ENOMEM; pci_puv3_preinit(); - puv3_bus = pci_scan_bus(0, &pci_puv3_ops, NULL); + pci_add_resource(&bridge->windows, &ioport_resource); + pci_add_resource(&bridge->windows, &iomem_resource); + pci_add_resource(&bridge->windows, &busn_resource); + bridge->sysdata = NULL; + bridge->busnr = 0; + bridge->ops = &pci_puv3_ops; + bridge->swizzle_irq = pci_common_swizzle; + bridge->map_irq = pci_puv3_map_irq; + + /* Scan our single hose. */ + ret = pci_scan_root_bus_bridge(bridge); + if (ret) { + pci_free_host_bridge(bridge); + return; + } + + puv3_bus = bridge->bus; if (!puv3_bus) panic("PCI: unable to scan bus!"); - pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); - pci_bus_size_bridges(puv3_bus); pci_bus_assign_resources(puv3_bus); pci_bus_add_devices(puv3_bus); diff --git a/arch/unicore32/lib/Makefile b/arch/unicore32/lib/Makefile index 87229a558b36..098981a01841 100644 --- a/arch/unicore32/lib/Makefile +++ b/arch/unicore32/lib/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/unicore32/lib/Makefile # diff --git a/arch/unicore32/mm/Kconfig b/arch/unicore32/mm/Kconfig index 5f77fb3c63be..c256460cd363 100644 --- a/arch/unicore32/mm/Kconfig +++ b/arch/unicore32/mm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 comment "Processor Type" # Select CPU types depending on the architecture selected. This selects diff --git a/arch/unicore32/mm/Makefile b/arch/unicore32/mm/Makefile index 46c166699319..681c0ef5ec9e 100644 --- a/arch/unicore32/mm/Makefile +++ b/arch/unicore32/mm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux unicore-specific parts of the memory manager. # diff --git a/arch/x86/Kbuild b/arch/x86/Kbuild index 586b786b3edf..0038a2d10a7a 100644 --- a/arch/x86/Kbuild +++ b/arch/x86/Kbuild @@ -8,10 +8,7 @@ obj-$(CONFIG_KVM) += kvm/ obj-$(CONFIG_XEN) += xen/ # Hyper-V paravirtualization support -obj-$(CONFIG_HYPERVISOR_GUEST) += hyperv/ - -# lguest paravirtualization support -obj-$(CONFIG_LGUEST_GUEST) += lguest/ +obj-$(subst m,y,$(CONFIG_HYPERV)) += hyperv/ obj-y += realmode/ obj-y += kernel/ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 323cb065be5e..2fdb23313dd5 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Select 32 or 64 bit config 64BIT bool "64-bit kernel" if ARCH = "x86" @@ -53,8 +54,9 @@ config X86 select ARCH_HAS_FORTIFY_SOURCE select ARCH_HAS_GCOV_PROFILE_ALL select ARCH_HAS_KCOV if X86_64 - select ARCH_HAS_MMIO_FLUSH select ARCH_HAS_PMEM_API if X86_64 + # Causing hangs/crashes, see the commit that added this change for details. + select ARCH_HAS_REFCOUNT if BROKEN select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 select ARCH_HAS_SET_MEMORY select ARCH_HAS_SG_CHAIN @@ -73,7 +75,6 @@ config X86 select ARCH_USE_QUEUED_RWLOCKS select ARCH_USE_QUEUED_SPINLOCKS select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH - select ARCH_WANT_FRAME_POINTERS select ARCH_WANTS_DYNAMIC_TASK_STRUCT select ARCH_WANTS_THP_SWAP if X86_64 select BUILDTIME_EXTABLE_SORT @@ -158,6 +159,7 @@ config X86 select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select HAVE_MIXED_BREAKPOINTS_REGS + select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI select HAVE_OPROFILE select HAVE_OPTPROBES @@ -167,8 +169,9 @@ config X86 select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_RCU_TABLE_FREE select HAVE_REGS_AND_STACK_ACCESS_API - select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER && STACK_VALIDATION + select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER_UNWINDER && STACK_VALIDATION select HAVE_STACK_VALIDATION if X86_64 select HAVE_SYSCALL_TRACEPOINTS select HAVE_UNSTABLE_SCHED_CLOCK @@ -327,6 +330,7 @@ config FIX_EARLYCON_MEM config PGTABLE_LEVELS int + default 5 if X86_5LEVEL default 4 if X86_64 default 3 if X86_PAE default 2 @@ -425,16 +429,16 @@ config GOLDFISH def_bool y depends on X86_GOLDFISH -config INTEL_RDT_A - bool "Intel Resource Director Technology Allocation support" +config INTEL_RDT + bool "Intel Resource Director Technology support" default n depends on X86 && CPU_SUP_INTEL select KERNFS help - Select to enable resource allocation which is a sub-feature of - Intel Resource Director Technology(RDT). More information about - RDT can be found in the Intel x86 Architecture Software - Developer Manual. + Select to enable resource allocation and monitoring which are + sub-features of Intel Resource Director Technology(RDT). More + information about RDT can be found in the Intel x86 + Architecture Software Developer Manual. Say N if unsure. @@ -778,8 +782,6 @@ config KVM_DEBUG_FS Statistics are displayed in debugfs filesystem. Enabling this option may incur significant overhead. -source "arch/x86/lguest/Kconfig" - config PARAVIRT_TIME_ACCOUNTING bool "Paravirtual steal time accounting" depends on PARAVIRT @@ -1399,6 +1401,24 @@ config X86_PAE has the cost of more pagetable lookup overhead, and also consumes more pagetable space per process. +config X86_5LEVEL + bool "Enable 5-level page tables support" + depends on X86_64 + ---help--- + 5-level paging enables access to larger address space: + upto 128 PiB of virtual address space and 4 PiB of + physical address space. + + It will be supported by future Intel CPUs. + + Note: a kernel with this option enabled can only be booted + on machines that support the feature. + + See Documentation/x86/x86_64/5level-paging.txt for more + information. + + Say N if unsure. + config ARCH_PHYS_ADDR_T_64BIT def_bool y depends on X86_64 || X86_PAE @@ -1416,6 +1436,35 @@ config X86_DIRECT_GBPAGES supports them), so don't confuse the user by printing that we have them enabled. +config ARCH_HAS_MEM_ENCRYPT + def_bool y + +config AMD_MEM_ENCRYPT + bool "AMD Secure Memory Encryption (SME) support" + depends on X86_64 && CPU_SUP_AMD + ---help--- + Say yes to enable support for the encryption of system memory. + This requires an AMD processor that supports Secure Memory + Encryption (SME). + +config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT + bool "Activate AMD Secure Memory Encryption (SME) by default" + default y + depends on AMD_MEM_ENCRYPT + ---help--- + Say yes to have system memory encrypted by default if running on + an AMD processor that supports Secure Memory Encryption (SME). + + If set to Y, then the encryption of system memory can be + deactivated with the mem_encrypt=off command line option. + + If set to N, then the encryption of system memory can be + activated with the mem_encrypt=on command line option. + +config ARCH_USE_MEMREMAP_PROT + def_bool y + depends on AMD_MEM_ENCRYPT + # Common NUMA Features config NUMA bool "Numa Memory Allocation and Scheduler Support" @@ -1757,7 +1806,9 @@ config X86_SMAP config X86_INTEL_MPX prompt "Intel MPX (Memory Protection Extensions)" def_bool n - depends on CPU_SUP_INTEL + # Note: only available in 64-bit mode due to VMA flags shortage + depends on CPU_SUP_INTEL && X86_64 + select ARCH_USES_HIGH_VMA_FLAGS ---help--- MPX provides hardware features that can be used in conjunction with compiler-instrumented code to check @@ -2272,6 +2323,10 @@ source "kernel/livepatch/Kconfig" endmenu +config ARCH_HAS_ADD_PAGES + def_bool y + depends on X86_64 && ARCH_ENABLE_MEMORY_HOTPLUG + config ARCH_ENABLE_MEMORY_HOTPLUG def_bool y depends on X86_64 || (X86_32 && HIGHMEM) @@ -2292,6 +2347,10 @@ config ARCH_ENABLE_HUGEPAGE_MIGRATION def_bool y depends on X86_64 && HUGETLB_PAGE && MIGRATION +config ARCH_ENABLE_THP_MIGRATION + def_bool y + depends on X86_64 && TRANSPARENT_HUGEPAGE + menu "Power management and ACPI options" config ARCH_HIBERNATION_HEADER diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index 3ba5ff2f2d08..65a9a4716e34 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Put here option for CPU selection and depending optimization choice prompt "Processor family" diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index cd20ca0b4043..90b123056f4b 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Kernel hacking" config TRACE_IRQFLAGS_SUPPORT @@ -305,8 +306,6 @@ config DEBUG_ENTRY Some of these sanity checks may slow down kernel entries and exits or otherwise impact performance. - This is currently used to help test NMI code. - If unsure, say N. config DEBUG_NMI_SELFTEST @@ -358,4 +357,61 @@ config PUNIT_ATOM_DEBUG The current power state can be read from /sys/kernel/debug/punit_atom/dev_power_state +choice + prompt "Choose kernel unwinder" + default FRAME_POINTER_UNWINDER + ---help--- + This determines which method will be used for unwinding kernel stack + traces for panics, oopses, bugs, warnings, perf, /proc//stack, + livepatch, lockdep, and more. + +config FRAME_POINTER_UNWINDER + bool "Frame pointer unwinder" + select FRAME_POINTER + ---help--- + This option enables the frame pointer unwinder for unwinding kernel + stack traces. + + The unwinder itself is fast and it uses less RAM than the ORC + unwinder, but the kernel text size will grow by ~3% and the kernel's + overall performance will degrade by roughly 5-10%. + + This option is recommended if you want to use the livepatch + consistency model, as this is currently the only way to get a + reliable stack trace (CONFIG_HAVE_RELIABLE_STACKTRACE). + +config ORC_UNWINDER + bool "ORC unwinder" + depends on X86_64 + select STACK_VALIDATION + ---help--- + This option enables the ORC (Oops Rewind Capability) unwinder for + unwinding kernel stack traces. It uses a custom data format which is + a simplified version of the DWARF Call Frame Information standard. + + This unwinder is more accurate across interrupt entry frames than the + frame pointer unwinder. It also enables a 5-10% performance + improvement across the entire kernel compared to frame pointers. + + Enabling this option will increase the kernel's runtime memory usage + by roughly 2-4MB, depending on your kernel config. + +config GUESS_UNWINDER + bool "Guess unwinder" + depends on EXPERT + ---help--- + This option enables the "guess" unwinder for unwinding kernel stack + traces. It scans the stack and reports every kernel text address it + finds. Some of the addresses it reports may be incorrect. + + While this option often produces false positives, it can still be + useful in many cases. Unlike the other unwinders, it has no runtime + overhead. + +endchoice + +config FRAME_POINTER + depends on !ORC_UNWINDER && !GUESS_UNWINDER + bool + endmenu diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 1e902f926be3..a20eacd9c7e9 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Unified Makefile for i386 and x86_64 # select defconfig based on actual architecture @@ -14,9 +15,11 @@ endif # For gcc stack alignment is specified with -mpreferred-stack-boundary, # clang has the option -mstack-alignment for that purpose. ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align_opt := -mpreferred-stack-boundary -else ifneq ($(call cc-option, -mstack-alignment=4),) - cc_stack_align_opt := -mstack-alignment + cc_stack_align4 := -mpreferred-stack-boundary=2 + cc_stack_align8 := -mpreferred-stack-boundary=3 +else ifneq ($(call cc-option, -mstack-alignment=16),) + cc_stack_align4 := -mstack-alignment=4 + cc_stack_align8 := -mstack-alignment=8 endif # How to compile the 16-bit code. Note we always compile for -march=i386; @@ -36,7 +39,7 @@ REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -D__KERNEL__ \ REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector) -REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align_opt)=2) +REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4)) export REALMODE_CFLAGS # BITS is used as extension for files which are available in a 32 bit @@ -76,7 +79,7 @@ ifeq ($(CONFIG_X86_32),y) # Align the stack to the register width instead of using the default # alignment of 16 bytes. This reduces stack usage and the number of # alignment instructions. - KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align_opt)=2) + KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align4)) # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use # a lot more stack due to the lack of sharing of stacklots: @@ -115,7 +118,7 @@ else # default alignment which keep the stack *mis*aligned. # Furthermore an alignment to the register width reduces stack usage # and the number of alignment instructions. - KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align_opt)=3) + KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align8)) # Use -mskip-rax-setup if supported. KBUILD_CFLAGS += $(call cc-option,-mskip-rax-setup) @@ -232,9 +235,6 @@ KBUILD_CFLAGS += -Wno-sign-compare # KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -KBUILD_CFLAGS += $(mflags-y) -KBUILD_AFLAGS += $(mflags-y) - archscripts: scripts_basic $(Q)$(MAKE) $(build)=arch/x86/tools relocs diff --git a/arch/x86/Makefile.um b/arch/x86/Makefile.um index 5b7e898ffd9a..45af19921ebd 100644 --- a/arch/x86/Makefile.um +++ b/arch/x86/Makefile.um @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 core-y += arch/x86/crypto/ ifeq ($(CONFIG_X86_32),y) diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu index f3717d36718a..1f5faf8606b4 100644 --- a/arch/x86/Makefile_32.cpu +++ b/arch/x86/Makefile_32.cpu @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # CPU tuning section - shared with UML. # Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML. diff --git a/arch/x86/boot/code16gcc.h b/arch/x86/boot/code16gcc.h index 5ff426535397..e19fd7536307 100644 --- a/arch/x86/boot/code16gcc.h +++ b/arch/x86/boot/code16gcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ # # code16gcc.h # diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 8a958274b54c..4b7575b00563 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # linux/arch/x86/boot/compressed/Makefile # diff --git a/arch/x86/boot/compressed/cmdline.c b/arch/x86/boot/compressed/cmdline.c index 9dc1ce6ba3c0..0cb325734cfb 100644 --- a/arch/x86/boot/compressed/cmdline.c +++ b/arch/x86/boot/compressed/cmdline.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "misc.h" #if CONFIG_EARLY_PRINTK || CONFIG_RANDOMIZE_BASE diff --git a/arch/x86/boot/compressed/cpuflags.c b/arch/x86/boot/compressed/cpuflags.c index aa313466118b..6448a8196d32 100644 --- a/arch/x86/boot/compressed/cpuflags.c +++ b/arch/x86/boot/compressed/cpuflags.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifdef CONFIG_RANDOMIZE_BASE #include "../cpuflags.c" diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c3e869eaef0c..e56dbc67e837 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -767,7 +767,7 @@ static efi_status_t setup_e820(struct boot_params *params, m |= (u64)efi->efi_memmap_hi << 32; #endif - d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size)); + d = efi_early_memdesc_ptr(m, efi->efi_memdesc_size, i); switch (d->type) { case EFI_RESERVED_TYPE: case EFI_RUNTIME_SERVICES_CODE: @@ -997,6 +997,9 @@ struct boot_params *efi_main(struct efi_config *c, if (boot_params->secure_boot == efi_secureboot_mode_unset) boot_params->secure_boot = efi_get_secureboot(sys_table); + /* Ask the firmware to clear memory on unclean shutdown */ + efi_enable_reset_attack_mitigation(sys_table); + setup_graphics(boot_params); setup_efi_pci(boot_params); @@ -1058,7 +1061,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = DESC_TYPE_CODE_DATA; desc->dpl = 0; desc->p = 1; - desc->limit = 0xf; + desc->limit1 = 0xf; desc->avl = 0; desc->l = 0; desc->d = SEG_OP_SIZE_32BIT; @@ -1078,7 +1081,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = DESC_TYPE_CODE_DATA; desc->dpl = 0; desc->p = 1; - desc->limit = 0xf; + desc->limit1 = 0xf; desc->avl = 0; if (IS_ENABLED(CONFIG_X86_64)) { desc->l = 1; @@ -1099,7 +1102,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = DESC_TYPE_CODE_DATA; desc->dpl = 0; desc->p = 1; - desc->limit = 0xf; + desc->limit1 = 0xf; desc->avl = 0; desc->l = 0; desc->d = SEG_OP_SIZE_32BIT; @@ -1116,7 +1119,7 @@ struct boot_params *efi_main(struct efi_config *c, desc->s = 0; desc->dpl = 0; desc->p = 1; - desc->limit = 0x0; + desc->limit1 = 0x0; desc->avl = 0; desc->l = 0; desc->d = 0; diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index c0223f1a89d7..e799dc5c6448 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BOOT_COMPRESSED_EBOOT_H #define BOOT_COMPRESSED_EBOOT_H diff --git a/arch/x86/boot/compressed/efi_stub_32.S b/arch/x86/boot/compressed/efi_stub_32.S index a53440e81d52..257e341fd2c8 100644 --- a/arch/x86/boot/compressed/efi_stub_32.S +++ b/arch/x86/boot/compressed/efi_stub_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * EFI call stub for IA32. * diff --git a/arch/x86/boot/compressed/efi_thunk_64.S b/arch/x86/boot/compressed/efi_thunk_64.S index 630384a4c14a..bff9ab7c6317 100644 --- a/arch/x86/boot/compressed/efi_thunk_64.S +++ b/arch/x86/boot/compressed/efi_thunk_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2014, 2015 Intel Corporation; author Matt Fleming * diff --git a/arch/x86/boot/compressed/error.c b/arch/x86/boot/compressed/error.c index 31922023de49..c881878e56d3 100644 --- a/arch/x86/boot/compressed/error.c +++ b/arch/x86/boot/compressed/error.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Callers outside of misc.c need access to the error reporting routines, * but the *_putstr() functions need to stay in misc.c because of how diff --git a/arch/x86/boot/compressed/error.h b/arch/x86/boot/compressed/error.h index d732e608e3af..1de5821184f1 100644 --- a/arch/x86/boot/compressed/error.h +++ b/arch/x86/boot/compressed/error.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BOOT_COMPRESSED_ERROR_H #define BOOT_COMPRESSED_ERROR_H diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index d85b9625e836..37380c0d5999 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/boot/head.S * @@ -61,71 +62,6 @@ __HEAD ENTRY(startup_32) -#ifdef CONFIG_EFI_STUB - jmp preferred_addr - - /* - * We don't need the return address, so set up the stack so - * efi_main() can find its arguments. - */ -ENTRY(efi_pe_entry) - add $0x4, %esp - - call 1f -1: popl %esi - subl $1b, %esi - - popl %ecx - movl %ecx, efi32_config(%esi) /* Handle */ - popl %ecx - movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */ - - /* Relocate efi_config->call() */ - leal efi32_config(%esi), %eax - add %esi, 40(%eax) - pushl %eax - - call make_boot_params - cmpl $0, %eax - je fail - movl %esi, BP_code32_start(%eax) - popl %ecx - pushl %eax - pushl %ecx - jmp 2f /* Skip efi_config initialization */ - -ENTRY(efi32_stub_entry) - add $0x4, %esp - popl %ecx - popl %edx - - call 1f -1: popl %esi - subl $1b, %esi - - movl %ecx, efi32_config(%esi) /* Handle */ - movl %edx, efi32_config+8(%esi) /* EFI System table pointer */ - - /* Relocate efi_config->call() */ - leal efi32_config(%esi), %eax - add %esi, 40(%eax) - pushl %eax -2: - call efi_main - cmpl $0, %eax - movl %eax, %esi - jne 2f -fail: - /* EFI init failed, so hang. */ - hlt - jmp fail -2: - movl BP_code32_start(%esi), %eax - leal preferred_addr(%eax), %eax - jmp *%eax - -preferred_addr: -#endif cld /* * Test KEEP_SEGMENTS flag to see if the bootloader is asking @@ -208,6 +144,70 @@ preferred_addr: jmp *%eax ENDPROC(startup_32) +#ifdef CONFIG_EFI_STUB +/* + * We don't need the return address, so set up the stack so efi_main() can find + * its arguments. + */ +ENTRY(efi_pe_entry) + add $0x4, %esp + + call 1f +1: popl %esi + subl $1b, %esi + + popl %ecx + movl %ecx, efi32_config(%esi) /* Handle */ + popl %ecx + movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */ + + /* Relocate efi_config->call() */ + leal efi32_config(%esi), %eax + add %esi, 40(%eax) + pushl %eax + + call make_boot_params + cmpl $0, %eax + je fail + movl %esi, BP_code32_start(%eax) + popl %ecx + pushl %eax + pushl %ecx + jmp 2f /* Skip efi_config initialization */ +ENDPROC(efi_pe_entry) + +ENTRY(efi32_stub_entry) + add $0x4, %esp + popl %ecx + popl %edx + + call 1f +1: popl %esi + subl $1b, %esi + + movl %ecx, efi32_config(%esi) /* Handle */ + movl %edx, efi32_config+8(%esi) /* EFI System table pointer */ + + /* Relocate efi_config->call() */ + leal efi32_config(%esi), %eax + add %esi, 40(%eax) + pushl %eax +2: + call efi_main + cmpl $0, %eax + movl %eax, %esi + jne 2f +fail: + /* EFI init failed, so hang. */ + hlt + jmp fail +2: + movl BP_code32_start(%esi), %eax + leal startup_32(%eax), %eax + jmp *%eax +ENDPROC(efi32_stub_entry) +#endif + .text relocated: diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index fbf4c32d0b62..beb255b66447 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/boot/head.S * @@ -243,65 +244,6 @@ ENTRY(startup_64) * that maps our entire kernel(text+data+bss+brk), zero page * and command line. */ -#ifdef CONFIG_EFI_STUB - /* - * The entry point for the PE/COFF executable is efi_pe_entry, so - * only legacy boot loaders will execute this jmp. - */ - jmp preferred_addr - -ENTRY(efi_pe_entry) - movq %rcx, efi64_config(%rip) /* Handle */ - movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ - - leaq efi64_config(%rip), %rax - movq %rax, efi_config(%rip) - - call 1f -1: popq %rbp - subq $1b, %rbp - - /* - * Relocate efi_config->call(). - */ - addq %rbp, efi64_config+40(%rip) - - movq %rax, %rdi - call make_boot_params - cmpq $0,%rax - je fail - mov %rax, %rsi - leaq startup_32(%rip), %rax - movl %eax, BP_code32_start(%rsi) - jmp 2f /* Skip the relocation */ - -handover_entry: - call 1f -1: popq %rbp - subq $1b, %rbp - - /* - * Relocate efi_config->call(). - */ - movq efi_config(%rip), %rax - addq %rbp, 40(%rax) -2: - movq efi_config(%rip), %rdi - call efi_main - movq %rax,%rsi - cmpq $0,%rax - jne 2f -fail: - /* EFI init failed, so hang. */ - hlt - jmp fail -2: - movl BP_code32_start(%esi), %eax - leaq preferred_addr(%rax), %rax - jmp *%rax - -preferred_addr: -#endif /* Setup data segments. */ xorl %eax, %eax @@ -413,6 +355,59 @@ lvl5: jmp *%rax #ifdef CONFIG_EFI_STUB + +/* The entry point for the PE/COFF executable is efi_pe_entry. */ +ENTRY(efi_pe_entry) + movq %rcx, efi64_config(%rip) /* Handle */ + movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ + + leaq efi64_config(%rip), %rax + movq %rax, efi_config(%rip) + + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + addq %rbp, efi64_config+40(%rip) + + movq %rax, %rdi + call make_boot_params + cmpq $0,%rax + je fail + mov %rax, %rsi + leaq startup_32(%rip), %rax + movl %eax, BP_code32_start(%rsi) + jmp 2f /* Skip the relocation */ + +handover_entry: + call 1f +1: popq %rbp + subq $1b, %rbp + + /* + * Relocate efi_config->call(). + */ + movq efi_config(%rip), %rax + addq %rbp, 40(%rax) +2: + movq efi_config(%rip), %rdi + call efi_main + movq %rax,%rsi + cmpq $0,%rax + jne 2f +fail: + /* EFI init failed, so hang. */ + hlt + jmp fail +2: + movl BP_code32_start(%esi), %eax + leaq startup_64(%rax), %rax + jmp *%rax +ENDPROC(efi_pe_entry) + .org 0x390 ENTRY(efi64_stub_entry) movq %rdi, efi64_config(%rip) /* Handle */ diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index 91f27ab970ef..a63fbc25ce84 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * kaslr.c * @@ -37,7 +38,9 @@ #include #include #include +#include #include +#include /* Macros used by the included decompressor code below. */ #define STATIC @@ -479,35 +482,31 @@ static unsigned long slots_fetch_random(void) return 0; } -static void process_e820_entry(struct boot_e820_entry *entry, +static void process_mem_region(struct mem_vector *entry, unsigned long minimum, unsigned long image_size) { struct mem_vector region, overlap; struct slot_area slot_area; unsigned long start_orig, end; - struct boot_e820_entry cur_entry; - - /* Skip non-RAM entries. */ - if (entry->type != E820_TYPE_RAM) - return; + struct mem_vector cur_entry; /* On 32-bit, ignore entries entirely above our maximum. */ - if (IS_ENABLED(CONFIG_X86_32) && entry->addr >= KERNEL_IMAGE_SIZE) + if (IS_ENABLED(CONFIG_X86_32) && entry->start >= KERNEL_IMAGE_SIZE) return; /* Ignore entries entirely below our minimum. */ - if (entry->addr + entry->size < minimum) + if (entry->start + entry->size < minimum) return; /* Ignore entries above memory limit */ - end = min(entry->size + entry->addr, mem_limit); - if (entry->addr >= end) + end = min(entry->size + entry->start, mem_limit); + if (entry->start >= end) return; - cur_entry.addr = entry->addr; - cur_entry.size = end - entry->addr; + cur_entry.start = entry->start; + cur_entry.size = end - entry->start; - region.start = cur_entry.addr; + region.start = cur_entry.start; region.size = cur_entry.size; /* Give up if slot area array is full. */ @@ -521,8 +520,8 @@ static void process_e820_entry(struct boot_e820_entry *entry, /* Potentially raise address to meet alignment needs. */ region.start = ALIGN(region.start, CONFIG_PHYSICAL_ALIGN); - /* Did we raise the address above this e820 region? */ - if (region.start > cur_entry.addr + cur_entry.size) + /* Did we raise the address above the passed in memory entry? */ + if (region.start > cur_entry.start + cur_entry.size) return; /* Reduce size by any delta from the original address. */ @@ -562,31 +561,126 @@ static void process_e820_entry(struct boot_e820_entry *entry, } } +#ifdef CONFIG_EFI +/* + * Returns true if mirror region found (and must have been processed + * for slots adding) + */ +static bool +process_efi_entries(unsigned long minimum, unsigned long image_size) +{ + struct efi_info *e = &boot_params->efi_info; + bool efi_mirror_found = false; + struct mem_vector region; + efi_memory_desc_t *md; + unsigned long pmap; + char *signature; + u32 nr_desc; + int i; + + signature = (char *)&e->efi_loader_signature; + if (strncmp(signature, EFI32_LOADER_SIGNATURE, 4) && + strncmp(signature, EFI64_LOADER_SIGNATURE, 4)) + return false; + +#ifdef CONFIG_X86_32 + /* Can't handle data above 4GB at this time */ + if (e->efi_memmap_hi) { + warn("EFI memmap is above 4GB, can't be handled now on x86_32. EFI should be disabled.\n"); + return false; + } + pmap = e->efi_memmap; +#else + pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32)); +#endif + + nr_desc = e->efi_memmap_size / e->efi_memdesc_size; + for (i = 0; i < nr_desc; i++) { + md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); + if (md->attribute & EFI_MEMORY_MORE_RELIABLE) { + efi_mirror_found = true; + break; + } + } + + for (i = 0; i < nr_desc; i++) { + md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i); + + /* + * Here we are more conservative in picking free memory than + * the EFI spec allows: + * + * According to the spec, EFI_BOOT_SERVICES_{CODE|DATA} are also + * free memory and thus available to place the kernel image into, + * but in practice there's firmware where using that memory leads + * to crashes. + * + * Only EFI_CONVENTIONAL_MEMORY is guaranteed to be free. + */ + if (md->type != EFI_CONVENTIONAL_MEMORY) + continue; + + if (efi_mirror_found && + !(md->attribute & EFI_MEMORY_MORE_RELIABLE)) + continue; + + region.start = md->phys_addr; + region.size = md->num_pages << EFI_PAGE_SHIFT; + process_mem_region(®ion, minimum, image_size); + if (slot_area_index == MAX_SLOT_AREA) { + debug_putstr("Aborted EFI scan (slot_areas full)!\n"); + break; + } + } + return true; +} +#else +static inline bool +process_efi_entries(unsigned long minimum, unsigned long image_size) +{ + return false; +} +#endif + +static void process_e820_entries(unsigned long minimum, + unsigned long image_size) +{ + int i; + struct mem_vector region; + struct boot_e820_entry *entry; + + /* Verify potential e820 positions, appending to slots list. */ + for (i = 0; i < boot_params->e820_entries; i++) { + entry = &boot_params->e820_table[i]; + /* Skip non-RAM entries. */ + if (entry->type != E820_TYPE_RAM) + continue; + region.start = entry->addr; + region.size = entry->size; + process_mem_region(®ion, minimum, image_size); + if (slot_area_index == MAX_SLOT_AREA) { + debug_putstr("Aborted e820 scan (slot_areas full)!\n"); + break; + } + } +} + static unsigned long find_random_phys_addr(unsigned long minimum, unsigned long image_size) { - int i; - unsigned long addr; - /* Check if we had too many memmaps. */ if (memmap_too_large) { - debug_putstr("Aborted e820 scan (more than 4 memmap= args)!\n"); + debug_putstr("Aborted memory entries scan (more than 4 memmap= args)!\n"); return 0; } /* Make sure minimum is aligned. */ minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN); - /* Verify potential e820 positions, appending to slots list. */ - for (i = 0; i < boot_params->e820_entries; i++) { - process_e820_entry(&boot_params->e820_table[i], minimum, - image_size); - if (slot_area_index == MAX_SLOT_AREA) { - debug_putstr("Aborted e820 scan (slot_areas full)!\n"); - break; - } - } + if (process_efi_entries(minimum, image_size)) + return slots_fetch_random(); + process_e820_entries(minimum, image_size); return slots_fetch_random(); } @@ -645,7 +739,7 @@ void choose_random_location(unsigned long input, */ min_addr = min(*output, 512UL << 20); - /* Walk e820 and find a random address. */ + /* Walk available memory entries to find a random address. */ random_addr = find_random_phys_addr(min_addr, output_size); if (!random_addr) { warn("Physical KASLR disabled: no suitable memory region!"); diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index c14217cd0155..b50c42455e25 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * misc.c * diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h index 766a5211f827..32d4ec2e0243 100644 --- a/arch/x86/boot/compressed/misc.h +++ b/arch/x86/boot/compressed/misc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BOOT_COMPRESSED_MISC_H #define BOOT_COMPRESSED_MISC_H diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c index 28029be47fbb..972319ff5b01 100644 --- a/arch/x86/boot/compressed/pagetable.c +++ b/arch/x86/boot/compressed/pagetable.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This code is used on x86_64 to create page table identity mappings on * demand by building up a new set of page tables (or appending to the @@ -15,6 +16,13 @@ #define __pa(x) ((unsigned long)(x)) #define __va(x) ((void *)((unsigned long)(x))) +/* + * The pgtable.h and mm/ident_map.c includes make use of the SME related + * information which is not used in the compressed image support. Un-define + * the SME support to avoid any compile and link errors. + */ +#undef CONFIG_AMD_MEM_ENCRYPT + #include "misc.h" /* These actually do the work of building the kernel identity maps. */ diff --git a/arch/x86/boot/compressed/string.c b/arch/x86/boot/compressed/string.c index cea140ce6b42..19dbbcdd1a53 100644 --- a/arch/x86/boot/compressed/string.c +++ b/arch/x86/boot/compressed/string.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This provides an optimized implementation of memcpy, and a simplified * implementation of memset and memmove. These are used here because the diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index e24e0a0c90c9..f491bbde8493 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include OUTPUT_FORMAT(CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT, CONFIG_OUTPUT_FORMAT) diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c index 9e77c23c2422..a0b75f73dc63 100644 --- a/arch/x86/boot/cpuflags.c +++ b/arch/x86/boot/cpuflags.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "bitops.h" diff --git a/arch/x86/boot/cpuflags.h b/arch/x86/boot/cpuflags.h index 15ad56a3f905..2e20814d3ce3 100644 --- a/arch/x86/boot/cpuflags.h +++ b/arch/x86/boot/cpuflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BOOT_CPUFLAGS_H #define BOOT_CPUFLAGS_H diff --git a/arch/x86/boot/ctype.h b/arch/x86/boot/ctype.h index 020f137df7a2..8f5ef2994b5e 100644 --- a/arch/x86/boot/ctype.h +++ b/arch/x86/boot/ctype.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BOOT_CTYPE_H #define BOOT_CTYPE_H diff --git a/arch/x86/boot/early_serial_console.c b/arch/x86/boot/early_serial_console.c index f0b8d6d93164..b25c53527a94 100644 --- a/arch/x86/boot/early_serial_console.c +++ b/arch/x86/boot/early_serial_console.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Serial port routines for use during early boot reporting. This code is * included from both the compressed kernel and the regular kernel. diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 1bb08ecffd24..9c7ea597eee6 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * header.S * diff --git a/arch/x86/boot/string.h b/arch/x86/boot/string.h index f274a50db5fa..3d78e27077f4 100644 --- a/arch/x86/boot/string.h +++ b/arch/x86/boot/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BOOT_STRING_H #define BOOT_STRING_H diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index 0702d2531bc7..d4e6cd4577e5 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1997 Martin Mares diff --git a/arch/x86/configs/tiny.config b/arch/x86/configs/tiny.config index 4b429df40d7a..550cd5012b73 100644 --- a/arch/x86/configs/tiny.config +++ b/arch/x86/configs/tiny.config @@ -1,3 +1,5 @@ CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set +CONFIG_GUESS_UNWINDER=y +# CONFIG_FRAME_POINTER_UNWINDER is not set diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index 9e32d40d71bd..5f07333bb224 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 4a55cdcdc008..5c15d6b57329 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -475,8 +475,8 @@ static void ctr_crypt_final(struct crypto_aes_ctx *ctx, unsigned int nbytes = walk->nbytes; aesni_enc(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); + crypto_inc(ctrblk, AES_BLOCK_SIZE); } diff --git a/arch/x86/crypto/blowfish-x86_64-asm_64.S b/arch/x86/crypto/blowfish-x86_64-asm_64.S index 246c67006ed0..8c1fcb6bad21 100644 --- a/arch/x86/crypto/blowfish-x86_64-asm_64.S +++ b/arch/x86/crypto/blowfish-x86_64-asm_64.S @@ -33,7 +33,7 @@ #define s3 ((16 + 2 + (3 * 256)) * 4) /* register macros */ -#define CTX %rdi +#define CTX %r12 #define RIO %rsi #define RX0 %rax @@ -56,12 +56,12 @@ #define RX2bh %ch #define RX3bh %dh -#define RT0 %rbp +#define RT0 %rdi #define RT1 %rsi #define RT2 %r8 #define RT3 %r9 -#define RT0d %ebp +#define RT0d %edi #define RT1d %esi #define RT2d %r8d #define RT3d %r9d @@ -120,13 +120,14 @@ ENTRY(__blowfish_enc_blk) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src * %rcx: bool, if true: xor output */ - movq %rbp, %r11; + movq %r12, %r11; + movq %rdi, CTX; movq %rsi, %r10; movq %rdx, RIO; @@ -142,7 +143,7 @@ ENTRY(__blowfish_enc_blk) round_enc(14); add_roundkey_enc(16); - movq %r11, %rbp; + movq %r11, %r12; movq %r10, RIO; test %cl, %cl; @@ -157,12 +158,13 @@ ENDPROC(__blowfish_enc_blk) ENTRY(blowfish_dec_blk) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ - movq %rbp, %r11; + movq %r12, %r11; + movq %rdi, CTX; movq %rsi, %r10; movq %rdx, RIO; @@ -181,7 +183,7 @@ ENTRY(blowfish_dec_blk) movq %r10, RIO; write_block(); - movq %r11, %rbp; + movq %r11, %r12; ret; ENDPROC(blowfish_dec_blk) @@ -298,20 +300,21 @@ ENDPROC(blowfish_dec_blk) ENTRY(__blowfish_enc_blk_4way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src * %rcx: bool, if true: xor output */ - pushq %rbp; + pushq %r12; pushq %rbx; pushq %rcx; - preload_roundkey_enc(0); - + movq %rdi, CTX movq %rsi, %r11; movq %rdx, RIO; + preload_roundkey_enc(0); + read_block4(); round_enc4(0); @@ -324,39 +327,40 @@ ENTRY(__blowfish_enc_blk_4way) round_enc4(14); add_preloaded_roundkey4(); - popq %rbp; + popq %r12; movq %r11, RIO; - test %bpl, %bpl; + test %r12b, %r12b; jnz .L__enc_xor4; write_block4(); popq %rbx; - popq %rbp; + popq %r12; ret; .L__enc_xor4: xor_block4(); popq %rbx; - popq %rbp; + popq %r12; ret; ENDPROC(__blowfish_enc_blk_4way) ENTRY(blowfish_dec_blk_4way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ - pushq %rbp; + pushq %r12; pushq %rbx; - preload_roundkey_dec(17); - movq %rsi, %r11; + movq %rdi, CTX; + movq %rsi, %r11 movq %rdx, RIO; + preload_roundkey_dec(17); read_block4(); round_dec4(17); @@ -373,7 +377,7 @@ ENTRY(blowfish_dec_blk_4way) write_block4(); popq %rbx; - popq %rbp; + popq %r12; ret; ENDPROC(blowfish_dec_blk_4way) diff --git a/arch/x86/crypto/blowfish_glue.c b/arch/x86/crypto/blowfish_glue.c index 17c05531dfd1..f9eca34301e2 100644 --- a/arch/x86/crypto/blowfish_glue.c +++ b/arch/x86/crypto/blowfish_glue.c @@ -271,8 +271,7 @@ static void ctr_crypt_final(struct bf_ctx *ctx, struct blkcipher_walk *walk) unsigned int nbytes = walk->nbytes; blowfish_enc_blk(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); crypto_inc(ctrblk, BF_BLOCK_SIZE); } diff --git a/arch/x86/crypto/camellia-x86_64-asm_64.S b/arch/x86/crypto/camellia-x86_64-asm_64.S index 310319c601ed..95ba6956a7f6 100644 --- a/arch/x86/crypto/camellia-x86_64-asm_64.S +++ b/arch/x86/crypto/camellia-x86_64-asm_64.S @@ -75,17 +75,17 @@ #define RCD1bh %dh #define RT0 %rsi -#define RT1 %rbp +#define RT1 %r12 #define RT2 %r8 #define RT0d %esi -#define RT1d %ebp +#define RT1d %r12d #define RT2d %r8d #define RT2bl %r8b #define RXOR %r9 -#define RRBP %r10 +#define RR12 %r10 #define RDST %r11 #define RXORd %r9d @@ -197,7 +197,7 @@ ENTRY(__camellia_enc_blk) * %rdx: src * %rcx: bool xor */ - movq %rbp, RRBP; + movq %r12, RR12; movq %rcx, RXOR; movq %rsi, RDST; @@ -227,13 +227,13 @@ ENTRY(__camellia_enc_blk) enc_outunpack(mov, RT1); - movq RRBP, %rbp; + movq RR12, %r12; ret; .L__enc_xor: enc_outunpack(xor, RT1); - movq RRBP, %rbp; + movq RR12, %r12; ret; ENDPROC(__camellia_enc_blk) @@ -248,7 +248,7 @@ ENTRY(camellia_dec_blk) movl $24, RXORd; cmovel RXORd, RT2d; /* max */ - movq %rbp, RRBP; + movq %r12, RR12; movq %rsi, RDST; movq %rdx, RIO; @@ -271,7 +271,7 @@ ENTRY(camellia_dec_blk) dec_outunpack(); - movq RRBP, %rbp; + movq RR12, %r12; ret; ENDPROC(camellia_dec_blk) @@ -433,7 +433,7 @@ ENTRY(__camellia_enc_blk_2way) */ pushq %rbx; - movq %rbp, RRBP; + movq %r12, RR12; movq %rcx, RXOR; movq %rsi, RDST; movq %rdx, RIO; @@ -461,14 +461,14 @@ ENTRY(__camellia_enc_blk_2way) enc_outunpack2(mov, RT2); - movq RRBP, %rbp; + movq RR12, %r12; popq %rbx; ret; .L__enc2_xor: enc_outunpack2(xor, RT2); - movq RRBP, %rbp; + movq RR12, %r12; popq %rbx; ret; ENDPROC(__camellia_enc_blk_2way) @@ -485,7 +485,7 @@ ENTRY(camellia_dec_blk_2way) cmovel RXORd, RT2d; /* max */ movq %rbx, RXOR; - movq %rbp, RRBP; + movq %r12, RR12; movq %rsi, RDST; movq %rdx, RIO; @@ -508,7 +508,7 @@ ENTRY(camellia_dec_blk_2way) dec_outunpack2(); - movq RRBP, %rbp; + movq RR12, %r12; movq RXOR, %rbx; ret; ENDPROC(camellia_dec_blk_2way) diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S index b4a8806234ea..86107c961bb4 100644 --- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S @@ -47,7 +47,7 @@ /********************************************************************** 16-way AVX cast5 **********************************************************************/ -#define CTX %rdi +#define CTX %r15 #define RL1 %xmm0 #define RR1 %xmm1 @@ -70,8 +70,8 @@ #define RTMP %xmm15 -#define RID1 %rbp -#define RID1d %ebp +#define RID1 %rdi +#define RID1d %edi #define RID2 %rsi #define RID2d %esi @@ -226,7 +226,7 @@ .align 16 __cast5_enc_blk16: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RL1: blocks 1 and 2 * RR1: blocks 3 and 4 * RL2: blocks 5 and 6 @@ -246,9 +246,11 @@ __cast5_enc_blk16: * RR4: encrypted blocks 15 and 16 */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -283,7 +285,7 @@ __cast5_enc_blk16: .L__skip_enc: popq %rbx; - popq %rbp; + popq %r15; vmovdqa .Lbswap_mask, RKM; @@ -298,7 +300,7 @@ ENDPROC(__cast5_enc_blk16) .align 16 __cast5_dec_blk16: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RL1: encrypted blocks 1 and 2 * RR1: encrypted blocks 3 and 4 * RL2: encrypted blocks 5 and 6 @@ -318,9 +320,11 @@ __cast5_dec_blk16: * RR4: decrypted blocks 15 and 16 */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -356,7 +360,7 @@ __cast5_dec_blk16: vmovdqa .Lbswap_mask, RKM; popq %rbx; - popq %rbp; + popq %r15; outunpack_blocks(RR1, RL1, RTMP, RX, RKM); outunpack_blocks(RR2, RL2, RTMP, RX, RKM); @@ -372,12 +376,14 @@ ENDPROC(__cast5_dec_blk16) ENTRY(cast5_ecb_enc_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; vmovdqu (0*4*4)(%rdx), RL1; @@ -400,18 +406,22 @@ ENTRY(cast5_ecb_enc_16way) vmovdqu RR4, (6*4*4)(%r11); vmovdqu RL4, (7*4*4)(%r11); + popq %r15; FRAME_END ret; ENDPROC(cast5_ecb_enc_16way) ENTRY(cast5_ecb_dec_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + + movq %rdi, CTX; movq %rsi, %r11; vmovdqu (0*4*4)(%rdx), RL1; @@ -434,20 +444,22 @@ ENTRY(cast5_ecb_dec_16way) vmovdqu RR4, (6*4*4)(%r11); vmovdqu RL4, (7*4*4)(%r11); + popq %r15; FRAME_END ret; ENDPROC(cast5_ecb_dec_16way) ENTRY(cast5_cbc_dec_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN - pushq %r12; + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -483,23 +495,24 @@ ENTRY(cast5_cbc_dec_16way) vmovdqu RR4, (6*16)(%r11); vmovdqu RL4, (7*16)(%r11); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast5_cbc_dec_16way) ENTRY(cast5_ctr_16way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src * %rcx: iv (big endian, 64bit) */ FRAME_BEGIN - pushq %r12; + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -558,8 +571,8 @@ ENTRY(cast5_ctr_16way) vmovdqu RR4, (6*16)(%r11); vmovdqu RL4, (7*16)(%r11); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast5_ctr_16way) diff --git a/arch/x86/crypto/cast5_avx_glue.c b/arch/x86/crypto/cast5_avx_glue.c index 8648158f3916..dbea6020ffe7 100644 --- a/arch/x86/crypto/cast5_avx_glue.c +++ b/arch/x86/crypto/cast5_avx_glue.c @@ -256,8 +256,7 @@ static void ctr_crypt_final(struct blkcipher_desc *desc, unsigned int nbytes = walk->nbytes; __cast5_encrypt(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); crypto_inc(ctrblk, CAST5_BLOCK_SIZE); } diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S index 952d3156a933..7f30b6f0d72c 100644 --- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S @@ -47,7 +47,7 @@ /********************************************************************** 8-way AVX cast6 **********************************************************************/ -#define CTX %rdi +#define CTX %r15 #define RA1 %xmm0 #define RB1 %xmm1 @@ -70,8 +70,8 @@ #define RTMP %xmm15 -#define RID1 %rbp -#define RID1d %ebp +#define RID1 %rdi +#define RID1d %edi #define RID2 %rsi #define RID2d %esi @@ -264,15 +264,17 @@ .align 8 __cast6_enc_blk8: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks * output: * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -297,7 +299,7 @@ __cast6_enc_blk8: QBAR(11); popq %rbx; - popq %rbp; + popq %r15; vmovdqa .Lbswap_mask, RKM; @@ -310,15 +312,17 @@ ENDPROC(__cast6_enc_blk8) .align 8 __cast6_dec_blk8: /* input: - * %rdi: ctx, CTX + * %rdi: ctx * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks * output: * RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: decrypted blocks */ - pushq %rbp; + pushq %r15; pushq %rbx; + movq %rdi, CTX; + vmovdqa .Lbswap_mask, RKM; vmovd .Lfirst_mask, R1ST; vmovd .L32_mask, R32; @@ -343,7 +347,7 @@ __cast6_dec_blk8: QBAR(0); popq %rbx; - popq %rbp; + popq %r15; vmovdqa .Lbswap_mask, RKM; outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM); @@ -354,12 +358,14 @@ ENDPROC(__cast6_dec_blk8) ENTRY(cast6_ecb_enc_8way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); @@ -368,18 +374,21 @@ ENTRY(cast6_ecb_enc_8way) store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_ecb_enc_8way) ENTRY(cast6_ecb_dec_8way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); @@ -388,20 +397,22 @@ ENTRY(cast6_ecb_dec_8way) store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_ecb_dec_8way) ENTRY(cast6_cbc_dec_8way) /* input: - * %rdi: ctx, CTX + * %rdi: ctx * %rsi: dst * %rdx: src */ FRAME_BEGIN - pushq %r12; + pushq %r15; + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -411,8 +422,8 @@ ENTRY(cast6_cbc_dec_8way) store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast6_cbc_dec_8way) @@ -425,9 +436,10 @@ ENTRY(cast6_ctr_8way) * %rcx: iv (little endian, 128bit) */ FRAME_BEGIN - pushq %r12; + pushq %r15 + movq %rdi, CTX; movq %rsi, %r11; movq %rdx, %r12; @@ -438,8 +450,8 @@ ENTRY(cast6_ctr_8way) store_ctr_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; popq %r12; - FRAME_END ret; ENDPROC(cast6_ctr_8way) @@ -452,7 +464,9 @@ ENTRY(cast6_xts_enc_8way) * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX movq %rsi, %r11; /* regs <= src, dst <= IVs, regs <= regs xor IVs */ @@ -464,6 +478,7 @@ ENTRY(cast6_xts_enc_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_xts_enc_8way) @@ -476,7 +491,9 @@ ENTRY(cast6_xts_dec_8way) * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ FRAME_BEGIN + pushq %r15; + movq %rdi, CTX movq %rsi, %r11; /* regs <= src, dst <= IVs, regs <= regs xor IVs */ @@ -488,6 +505,7 @@ ENTRY(cast6_xts_dec_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + popq %r15; FRAME_END ret; ENDPROC(cast6_xts_dec_8way) diff --git a/arch/x86/crypto/chacha20-avx2-x86_64.S b/arch/x86/crypto/chacha20-avx2-x86_64.S index 3a2dc3dc6cac..f3cd26f48332 100644 --- a/arch/x86/crypto/chacha20-avx2-x86_64.S +++ b/arch/x86/crypto/chacha20-avx2-x86_64.S @@ -45,7 +45,7 @@ ENTRY(chacha20_8block_xor_avx2) vzeroupper # 4 * 32 byte stack, 32-byte aligned - mov %rsp, %r8 + lea 8(%rsp),%r10 and $~31, %rsp sub $0x80, %rsp @@ -443,6 +443,6 @@ ENTRY(chacha20_8block_xor_avx2) vmovdqu %ymm15,0x01e0(%rsi) vzeroupper - mov %r8,%rsp + lea -8(%r10),%rsp ret ENDPROC(chacha20_8block_xor_avx2) diff --git a/arch/x86/crypto/chacha20-ssse3-x86_64.S b/arch/x86/crypto/chacha20-ssse3-x86_64.S index 3f511a7d73b8..512a2b500fd1 100644 --- a/arch/x86/crypto/chacha20-ssse3-x86_64.S +++ b/arch/x86/crypto/chacha20-ssse3-x86_64.S @@ -160,7 +160,7 @@ ENTRY(chacha20_4block_xor_ssse3) # done with the slightly better performing SSSE3 byte shuffling, # 7/12-bit word rotation uses traditional shift+OR. - mov %rsp,%r11 + lea 8(%rsp),%r10 sub $0x80,%rsp and $~63,%rsp @@ -625,6 +625,6 @@ ENTRY(chacha20_4block_xor_ssse3) pxor %xmm1,%xmm15 movdqu %xmm15,0xf0(%rsi) - mov %r11,%rsp + lea -8(%r10),%rsp ret ENDPROC(chacha20_4block_xor_ssse3) diff --git a/arch/x86/crypto/des3_ede-asm_64.S b/arch/x86/crypto/des3_ede-asm_64.S index f3e91647ca27..8e49ce117494 100644 --- a/arch/x86/crypto/des3_ede-asm_64.S +++ b/arch/x86/crypto/des3_ede-asm_64.S @@ -64,12 +64,12 @@ #define RW2bh %ch #define RT0 %r15 -#define RT1 %rbp +#define RT1 %rsi #define RT2 %r14 #define RT3 %rdx #define RT0d %r15d -#define RT1d %ebp +#define RT1d %esi #define RT2d %r14d #define RT3d %edx @@ -177,13 +177,14 @@ ENTRY(des3_ede_x86_64_crypt_blk) * %rsi: dst * %rdx: src */ - pushq %rbp; pushq %rbx; pushq %r12; pushq %r13; pushq %r14; pushq %r15; + pushq %rsi; /* dst */ + read_block(%rdx, RL0, RR0); initial_permutation(RL0, RR0); @@ -241,6 +242,8 @@ ENTRY(des3_ede_x86_64_crypt_blk) round1(32+15, RL0, RR0, dummy2); final_permutation(RR0, RL0); + + popq %rsi /* dst */ write_block(%rsi, RR0, RL0); popq %r15; @@ -248,7 +251,6 @@ ENTRY(des3_ede_x86_64_crypt_blk) popq %r13; popq %r12; popq %rbx; - popq %rbp; ret; ENDPROC(des3_ede_x86_64_crypt_blk) @@ -432,13 +434,14 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) * %rdx: src (3 blocks) */ - pushq %rbp; pushq %rbx; pushq %r12; pushq %r13; pushq %r14; pushq %r15; + pushq %rsi /* dst */ + /* load input */ movl 0 * 4(%rdx), RL0d; movl 1 * 4(%rdx), RR0d; @@ -520,6 +523,7 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) bswapl RR2d; bswapl RL2d; + popq %rsi /* dst */ movl RR0d, 0 * 4(%rsi); movl RL0d, 1 * 4(%rsi); movl RR1d, 2 * 4(%rsi); @@ -532,7 +536,6 @@ ENTRY(des3_ede_x86_64_crypt_blk_3way) popq %r13; popq %r12; popq %rbx; - popq %rbp; ret; ENDPROC(des3_ede_x86_64_crypt_blk_3way) diff --git a/arch/x86/crypto/des3_ede_glue.c b/arch/x86/crypto/des3_ede_glue.c index d6fc59aaaadf..30c0a37f4882 100644 --- a/arch/x86/crypto/des3_ede_glue.c +++ b/arch/x86/crypto/des3_ede_glue.c @@ -277,8 +277,7 @@ static void ctr_crypt_final(struct des3_ede_x86_ctx *ctx, unsigned int nbytes = walk->nbytes; des3_ede_enc_blk(ctx, keystream, ctrblk); - crypto_xor(keystream, src, nbytes); - memcpy(dst, keystream, nbytes); + crypto_xor_cpy(dst, keystream, src, nbytes); crypto_inc(ctrblk, DES3_EDE_BLOCK_SIZE); } diff --git a/arch/x86/crypto/salsa20-x86_64-asm_64.S b/arch/x86/crypto/salsa20-x86_64-asm_64.S index 9279e0b2d60e..10db30d58006 100644 --- a/arch/x86/crypto/salsa20-x86_64-asm_64.S +++ b/arch/x86/crypto/salsa20-x86_64-asm_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include # enter salsa20_encrypt_bytes diff --git a/arch/x86/crypto/sha1-mb/Makefile b/arch/x86/crypto/sha1-mb/Makefile index 2e14acc3da25..815ded3ba90e 100644 --- a/arch/x86/crypto/sha1-mb/Makefile +++ b/arch/x86/crypto/sha1-mb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # diff --git a/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S index 93b945597ecf..7cfba738f104 100644 --- a/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S +++ b/arch/x86/crypto/sha1-mb/sha1_mb_mgr_flush_avx2.S @@ -157,8 +157,8 @@ LABEL skip_ %I .endr # Find min length - vmovdqa _lens+0*16(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens+0*16(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} @@ -178,8 +178,8 @@ LABEL skip_ %I vpsubd %xmm2, %xmm0, %xmm0 vpsubd %xmm2, %xmm1, %xmm1 - vmovdqa %xmm0, _lens+0*16(state) - vmovdqa %xmm1, _lens+1*16(state) + vmovdqu %xmm0, _lens+0*16(state) + vmovdqu %xmm1, _lens+1*16(state) # "state" and "args" are the same address, arg1 # len is arg2 @@ -235,8 +235,8 @@ ENTRY(sha1_mb_mgr_get_comp_job_avx2) jc .return_null # Find min length - vmovdqa _lens(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} diff --git a/arch/x86/crypto/sha1_avx2_x86_64_asm.S b/arch/x86/crypto/sha1_avx2_x86_64_asm.S index 1eab79c9ac48..9f712a7dfd79 100644 --- a/arch/x86/crypto/sha1_avx2_x86_64_asm.S +++ b/arch/x86/crypto/sha1_avx2_x86_64_asm.S @@ -89,7 +89,7 @@ #define REG_RE %rdx #define REG_RTA %r12 #define REG_RTB %rbx -#define REG_T1 %ebp +#define REG_T1 %r11d #define xmm_mov vmovups #define avx2_zeroupper vzeroupper #define RND_F1 1 @@ -637,7 +637,6 @@ _loop3: ENTRY(\name) push %rbx - push %rbp push %r12 push %r13 push %r14 @@ -673,7 +672,6 @@ _loop3: pop %r14 pop %r13 pop %r12 - pop %rbp pop %rbx ret diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S index a4109506a5e8..6204bd53528c 100644 --- a/arch/x86/crypto/sha1_ssse3_asm.S +++ b/arch/x86/crypto/sha1_ssse3_asm.S @@ -37,7 +37,7 @@ #define REG_A %ecx #define REG_B %esi #define REG_C %edi -#define REG_D %ebp +#define REG_D %r12d #define REG_E %edx #define REG_T1 %eax @@ -74,10 +74,10 @@ ENTRY(\name) push %rbx - push %rbp push %r12 + push %rbp + mov %rsp, %rbp - mov %rsp, %r12 sub $64, %rsp # allocate workspace and $~15, %rsp # align stack @@ -99,10 +99,9 @@ xor %rax, %rax rep stosq - mov %r12, %rsp # deallocate workspace - - pop %r12 + mov %rbp, %rsp # deallocate workspace pop %rbp + pop %r12 pop %rbx ret diff --git a/arch/x86/crypto/sha256-avx-asm.S b/arch/x86/crypto/sha256-avx-asm.S index e08888a1a5f2..001bbcf93c79 100644 --- a/arch/x86/crypto/sha256-avx-asm.S +++ b/arch/x86/crypto/sha256-avx-asm.S @@ -103,7 +103,7 @@ SRND = %rsi # clobbers INP c = %ecx d = %r8d e = %edx -TBL = %rbp +TBL = %r12 a = %eax b = %ebx @@ -350,13 +350,13 @@ a = TMP_ ENTRY(sha256_transform_avx) .align 32 pushq %rbx - pushq %rbp + pushq %r12 pushq %r13 pushq %r14 pushq %r15 - pushq %r12 + pushq %rbp + movq %rsp, %rbp - mov %rsp, %r12 subq $STACK_SIZE, %rsp # allocate stack space and $~15, %rsp # align stack pointer @@ -452,13 +452,12 @@ loop2: done_hash: - mov %r12, %rsp - - popq %r12 + mov %rbp, %rsp + popq %rbp popq %r15 popq %r14 popq %r13 - popq %rbp + popq %r12 popq %rbx ret ENDPROC(sha256_transform_avx) diff --git a/arch/x86/crypto/sha256-avx2-asm.S b/arch/x86/crypto/sha256-avx2-asm.S index 89c8f09787d2..1420db15dcdd 100644 --- a/arch/x86/crypto/sha256-avx2-asm.S +++ b/arch/x86/crypto/sha256-avx2-asm.S @@ -98,8 +98,6 @@ d = %r8d e = %edx # clobbers NUM_BLKS y3 = %esi # clobbers INP - -TBL = %rbp SRND = CTX # SRND is same register as CTX a = %eax @@ -531,7 +529,6 @@ STACK_SIZE = _RSP + _RSP_SIZE ENTRY(sha256_transform_rorx) .align 32 pushq %rbx - pushq %rbp pushq %r12 pushq %r13 pushq %r14 @@ -568,8 +565,6 @@ ENTRY(sha256_transform_rorx) mov CTX, _CTX(%rsp) loop0: - lea K256(%rip), TBL - ## Load first 16 dwords from two blocks VMOVDQ 0*32(INP),XTMP0 VMOVDQ 1*32(INP),XTMP1 @@ -597,19 +592,19 @@ last_block_enter: .align 16 loop1: - vpaddd 0*32(TBL, SRND), X0, XFER + vpaddd K256+0*32(SRND), X0, XFER vmovdqa XFER, 0*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 0*32 - vpaddd 1*32(TBL, SRND), X0, XFER + vpaddd K256+1*32(SRND), X0, XFER vmovdqa XFER, 1*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 1*32 - vpaddd 2*32(TBL, SRND), X0, XFER + vpaddd K256+2*32(SRND), X0, XFER vmovdqa XFER, 2*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 2*32 - vpaddd 3*32(TBL, SRND), X0, XFER + vpaddd K256+3*32(SRND), X0, XFER vmovdqa XFER, 3*32+_XFER(%rsp, SRND) FOUR_ROUNDS_AND_SCHED _XFER + 3*32 @@ -619,10 +614,11 @@ loop1: loop2: ## Do last 16 rounds with no scheduling - vpaddd 0*32(TBL, SRND), X0, XFER + vpaddd K256+0*32(SRND), X0, XFER vmovdqa XFER, 0*32+_XFER(%rsp, SRND) DO_4ROUNDS _XFER + 0*32 - vpaddd 1*32(TBL, SRND), X1, XFER + + vpaddd K256+1*32(SRND), X1, XFER vmovdqa XFER, 1*32+_XFER(%rsp, SRND) DO_4ROUNDS _XFER + 1*32 add $2*32, SRND @@ -676,9 +672,6 @@ loop3: ja done_hash do_last_block: - #### do last block - lea K256(%rip), TBL - VMOVDQ 0*16(INP),XWORD0 VMOVDQ 1*16(INP),XWORD1 VMOVDQ 2*16(INP),XWORD2 @@ -718,7 +711,6 @@ done_hash: popq %r14 popq %r13 popq %r12 - popq %rbp popq %rbx ret ENDPROC(sha256_transform_rorx) diff --git a/arch/x86/crypto/sha256-mb/Makefile b/arch/x86/crypto/sha256-mb/Makefile index 45b4fca6c4a8..53ad6e7db747 100644 --- a/arch/x86/crypto/sha256-mb/Makefile +++ b/arch/x86/crypto/sha256-mb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # diff --git a/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S index 8fe6338bcc84..16c4ccb1f154 100644 --- a/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S +++ b/arch/x86/crypto/sha256-mb/sha256_mb_mgr_flush_avx2.S @@ -155,8 +155,8 @@ LABEL skip_ %I .endr # Find min length - vmovdqa _lens+0*16(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens+0*16(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} @@ -176,8 +176,8 @@ LABEL skip_ %I vpsubd %xmm2, %xmm0, %xmm0 vpsubd %xmm2, %xmm1, %xmm1 - vmovdqa %xmm0, _lens+0*16(state) - vmovdqa %xmm1, _lens+1*16(state) + vmovdqu %xmm0, _lens+0*16(state) + vmovdqu %xmm1, _lens+1*16(state) # "state" and "args" are the same address, arg1 # len is arg2 @@ -234,8 +234,8 @@ ENTRY(sha256_mb_mgr_get_comp_job_avx2) jc .return_null # Find min length - vmovdqa _lens(state), %xmm0 - vmovdqa _lens+1*16(state), %xmm1 + vmovdqu _lens(state), %xmm0 + vmovdqu _lens+1*16(state), %xmm1 vpminud %xmm1, %xmm0, %xmm2 # xmm2 has {D,C,B,A} vpalignr $8, %xmm2, %xmm3, %xmm3 # xmm3 has {x,x,D,C} diff --git a/arch/x86/crypto/sha256-ssse3-asm.S b/arch/x86/crypto/sha256-ssse3-asm.S index 39b83c93e7fd..c6c05ed2c16a 100644 --- a/arch/x86/crypto/sha256-ssse3-asm.S +++ b/arch/x86/crypto/sha256-ssse3-asm.S @@ -95,7 +95,7 @@ SRND = %rsi # clobbers INP c = %ecx d = %r8d e = %edx -TBL = %rbp +TBL = %r12 a = %eax b = %ebx @@ -356,13 +356,13 @@ a = TMP_ ENTRY(sha256_transform_ssse3) .align 32 pushq %rbx - pushq %rbp + pushq %r12 pushq %r13 pushq %r14 pushq %r15 - pushq %r12 + pushq %rbp + mov %rsp, %rbp - mov %rsp, %r12 subq $STACK_SIZE, %rsp and $~15, %rsp @@ -462,13 +462,12 @@ loop2: done_hash: - mov %r12, %rsp - - popq %r12 + mov %rbp, %rsp + popq %rbp popq %r15 popq %r14 popq %r13 - popq %rbp + popq %r12 popq %rbx ret diff --git a/arch/x86/crypto/sha512-avx2-asm.S b/arch/x86/crypto/sha512-avx2-asm.S index 7f5f6c6ec72e..b16d56005162 100644 --- a/arch/x86/crypto/sha512-avx2-asm.S +++ b/arch/x86/crypto/sha512-avx2-asm.S @@ -69,8 +69,9 @@ XFER = YTMP0 BYTE_FLIP_MASK = %ymm9 -# 1st arg -CTX = %rdi +# 1st arg is %rdi, which is saved to the stack and accessed later via %r12 +CTX1 = %rdi +CTX2 = %r12 # 2nd arg INP = %rsi # 3rd arg @@ -81,7 +82,7 @@ d = %r8 e = %rdx y3 = %rsi -TBL = %rbp +TBL = %rdi # clobbers CTX1 a = %rax b = %rbx @@ -91,26 +92,26 @@ g = %r10 h = %r11 old_h = %r11 -T1 = %r12 +T1 = %r12 # clobbers CTX2 y0 = %r13 y1 = %r14 y2 = %r15 -y4 = %r12 - # Local variables (stack frame) XFER_SIZE = 4*8 SRND_SIZE = 1*8 INP_SIZE = 1*8 INPEND_SIZE = 1*8 +CTX_SIZE = 1*8 RSPSAVE_SIZE = 1*8 -GPRSAVE_SIZE = 6*8 +GPRSAVE_SIZE = 5*8 frame_XFER = 0 frame_SRND = frame_XFER + XFER_SIZE frame_INP = frame_SRND + SRND_SIZE frame_INPEND = frame_INP + INP_SIZE -frame_RSPSAVE = frame_INPEND + INPEND_SIZE +frame_CTX = frame_INPEND + INPEND_SIZE +frame_RSPSAVE = frame_CTX + CTX_SIZE frame_GPRSAVE = frame_RSPSAVE + RSPSAVE_SIZE frame_size = frame_GPRSAVE + GPRSAVE_SIZE @@ -576,12 +577,11 @@ ENTRY(sha512_transform_rorx) mov %rax, frame_RSPSAVE(%rsp) # Save GPRs - mov %rbp, frame_GPRSAVE(%rsp) - mov %rbx, 8*1+frame_GPRSAVE(%rsp) - mov %r12, 8*2+frame_GPRSAVE(%rsp) - mov %r13, 8*3+frame_GPRSAVE(%rsp) - mov %r14, 8*4+frame_GPRSAVE(%rsp) - mov %r15, 8*5+frame_GPRSAVE(%rsp) + mov %rbx, 8*0+frame_GPRSAVE(%rsp) + mov %r12, 8*1+frame_GPRSAVE(%rsp) + mov %r13, 8*2+frame_GPRSAVE(%rsp) + mov %r14, 8*3+frame_GPRSAVE(%rsp) + mov %r15, 8*4+frame_GPRSAVE(%rsp) shl $7, NUM_BLKS # convert to bytes jz done_hash @@ -589,14 +589,17 @@ ENTRY(sha512_transform_rorx) mov NUM_BLKS, frame_INPEND(%rsp) ## load initial digest - mov 8*0(CTX),a - mov 8*1(CTX),b - mov 8*2(CTX),c - mov 8*3(CTX),d - mov 8*4(CTX),e - mov 8*5(CTX),f - mov 8*6(CTX),g - mov 8*7(CTX),h + mov 8*0(CTX1), a + mov 8*1(CTX1), b + mov 8*2(CTX1), c + mov 8*3(CTX1), d + mov 8*4(CTX1), e + mov 8*5(CTX1), f + mov 8*6(CTX1), g + mov 8*7(CTX1), h + + # save %rdi (CTX) before it gets clobbered + mov %rdi, frame_CTX(%rsp) vmovdqa PSHUFFLE_BYTE_FLIP_MASK(%rip), BYTE_FLIP_MASK @@ -652,14 +655,15 @@ loop2: subq $1, frame_SRND(%rsp) jne loop2 - addm 8*0(CTX),a - addm 8*1(CTX),b - addm 8*2(CTX),c - addm 8*3(CTX),d - addm 8*4(CTX),e - addm 8*5(CTX),f - addm 8*6(CTX),g - addm 8*7(CTX),h + mov frame_CTX(%rsp), CTX2 + addm 8*0(CTX2), a + addm 8*1(CTX2), b + addm 8*2(CTX2), c + addm 8*3(CTX2), d + addm 8*4(CTX2), e + addm 8*5(CTX2), f + addm 8*6(CTX2), g + addm 8*7(CTX2), h mov frame_INP(%rsp), INP add $128, INP @@ -669,12 +673,11 @@ loop2: done_hash: # Restore GPRs - mov frame_GPRSAVE(%rsp) ,%rbp - mov 8*1+frame_GPRSAVE(%rsp) ,%rbx - mov 8*2+frame_GPRSAVE(%rsp) ,%r12 - mov 8*3+frame_GPRSAVE(%rsp) ,%r13 - mov 8*4+frame_GPRSAVE(%rsp) ,%r14 - mov 8*5+frame_GPRSAVE(%rsp) ,%r15 + mov 8*0+frame_GPRSAVE(%rsp), %rbx + mov 8*1+frame_GPRSAVE(%rsp), %r12 + mov 8*2+frame_GPRSAVE(%rsp), %r13 + mov 8*3+frame_GPRSAVE(%rsp), %r14 + mov 8*4+frame_GPRSAVE(%rsp), %r15 # Restore Stack Pointer mov frame_RSPSAVE(%rsp), %rsp diff --git a/arch/x86/crypto/sha512-mb/Makefile b/arch/x86/crypto/sha512-mb/Makefile index 0a57e2103980..90f1ef69152e 100644 --- a/arch/x86/crypto/sha512-mb/Makefile +++ b/arch/x86/crypto/sha512-mb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S index b3f49d286348..73b471da3622 100644 --- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S @@ -76,8 +76,8 @@ #define RT %xmm14 #define RR %xmm15 -#define RID1 %rbp -#define RID1d %ebp +#define RID1 %r13 +#define RID1d %r13d #define RID2 %rsi #define RID2d %esi @@ -259,7 +259,7 @@ __twofish_enc_blk8: vmovdqu w(CTX), RK1; - pushq %rbp; + pushq %r13; pushq %rbx; pushq %rcx; @@ -282,7 +282,7 @@ __twofish_enc_blk8: popq %rcx; popq %rbx; - popq %rbp; + popq %r13; outunpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2); outunpack_blocks(RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2); @@ -301,7 +301,7 @@ __twofish_dec_blk8: vmovdqu (w+4*4)(CTX), RK1; - pushq %rbp; + pushq %r13; pushq %rbx; inpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2); @@ -322,7 +322,7 @@ __twofish_dec_blk8: vmovdqu (w)(CTX), RK1; popq %rbx; - popq %rbp; + popq %r13; outunpack_blocks(RA1, RB1, RC1, RD1, RK1, RX0, RY0, RK2); outunpack_blocks(RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2); diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile index 9976fcecd17e..06fc70cf5433 100644 --- a/arch/x86/entry/Makefile +++ b/arch/x86/entry/Makefile @@ -1,8 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the x86 low level entry code # -OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y CFLAGS_syscall_64.o += $(call cc-option,-Wno-override-init,) diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 05ed3d393da7..6e160031cfea 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -1,4 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include +#include /* @@ -112,6 +114,7 @@ For 32-bit we have the following conventions - kernel is built with movq %rdx, 12*8+\offset(%rsp) movq %rsi, 13*8+\offset(%rsp) movq %rdi, 14*8+\offset(%rsp) + UNWIND_HINT_REGS offset=\offset extra=0 .endm .macro SAVE_C_REGS offset=0 SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1 @@ -136,6 +139,7 @@ For 32-bit we have the following conventions - kernel is built with movq %r12, 3*8+\offset(%rsp) movq %rbp, 4*8+\offset(%rsp) movq %rbx, 5*8+\offset(%rsp) + UNWIND_HINT_REGS offset=\offset .endm .macro RESTORE_EXTRA_REGS offset=0 @@ -145,6 +149,7 @@ For 32-bit we have the following conventions - kernel is built with movq 3*8+\offset(%rsp), %r12 movq 4*8+\offset(%rsp), %rbp movq 5*8+\offset(%rsp), %rbx + UNWIND_HINT_REGS offset=\offset extra=0 .endm .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1 @@ -167,6 +172,7 @@ For 32-bit we have the following conventions - kernel is built with .endif movq 13*8(%rsp), %rsi movq 14*8(%rsp), %rdi + UNWIND_HINT_IRET_REGS offset=16*8 .endm .macro RESTORE_C_REGS RESTORE_C_REGS_HELPER 1,1,1,1,1 diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index cdefcfdd9e63..03505ffbe1b6 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -183,6 +184,8 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) struct thread_info *ti = current_thread_info(); u32 cached_flags; + addr_limit_user_check(); + if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled())) local_irq_disable(); diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 48ef7bb32c42..4838037f97f6 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1991,1992 Linus Torvalds * @@ -176,7 +177,7 @@ /* * This is a sneaky trick to help the unwinder find pt_regs on the stack. The * frame pointer is replaced with an encoded pointer to pt_regs. The encoding - * is just setting the LSB, which makes it an invalid stack address and is also + * is just clearing the MSB, which makes it an invalid stack address and is also * a signal to the unwinder that it's a pt_regs pointer in disguise. * * NOTE: This macro must be used *after* SAVE_ALL because it corrupts the @@ -185,7 +186,7 @@ .macro ENCODE_FRAME_POINTER #ifdef CONFIG_FRAME_POINTER mov %esp, %ebp - orl $0x1, %ebp + andl $0x7fffffff, %ebp #endif .endm @@ -673,16 +674,8 @@ ENTRY(name) \ jmp ret_from_intr; \ ENDPROC(name) - -#ifdef CONFIG_TRACING -# define TRACE_BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) -#else -# define TRACE_BUILD_INTERRUPT(name, nr) -#endif - #define BUILD_INTERRUPT(name, nr) \ BUILD_INTERRUPT3(name, nr, smp_##name); \ - TRACE_BUILD_INTERRUPT(name, nr) /* The include is where all of the SMP etc. interrupts come from */ #include @@ -880,25 +873,17 @@ ENTRY(xen_failsafe_callback) ENDPROC(xen_failsafe_callback) BUILD_INTERRUPT3(xen_hvm_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - xen_evtchn_do_upcall) + xen_evtchn_do_upcall) #endif /* CONFIG_XEN */ #if IS_ENABLED(CONFIG_HYPERV) BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, - hyperv_vector_handler) + hyperv_vector_handler) #endif /* CONFIG_HYPERV */ -#ifdef CONFIG_TRACING -ENTRY(trace_page_fault) - ASM_CLAC - pushl $trace_do_page_fault - jmp common_exception -END(trace_page_fault) -#endif - ENTRY(page_fault) ASM_CLAC pushl $do_page_fault diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 6d078b89a5e8..bcfc5668dcb2 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/x86_64/entry.S * @@ -36,6 +37,7 @@ #include #include #include +#include #include .code64 @@ -43,9 +45,10 @@ #ifdef CONFIG_PARAVIRT ENTRY(native_usergs_sysret64) + UNWIND_HINT_EMPTY swapgs sysretq -ENDPROC(native_usergs_sysret64) +END(native_usergs_sysret64) #endif /* CONFIG_PARAVIRT */ .macro TRACE_IRQS_IRETQ @@ -134,19 +137,14 @@ ENDPROC(native_usergs_sysret64) */ ENTRY(entry_SYSCALL_64) + UNWIND_HINT_EMPTY /* * Interrupts are off on entry. * We do not frame this tiny irq-off block with TRACE_IRQS_OFF/ON, * it is too small to ever cause noticeable irq latency. */ - SWAPGS_UNSAFE_STACK - /* - * A hypervisor implementation might want to use a label - * after the swapgs, so that it can do the swapgs - * for the guest and jump here on syscall. - */ -GLOBAL(entry_SYSCALL_64_after_swapgs) + swapgs movq %rsp, PER_CPU_VAR(rsp_scratch) movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp @@ -158,6 +156,7 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) pushq %r11 /* pt_regs->flags */ pushq $__USER_CS /* pt_regs->cs */ pushq %rcx /* pt_regs->ip */ +GLOBAL(entry_SYSCALL_64_after_hwframe) pushq %rax /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ @@ -169,6 +168,7 @@ GLOBAL(entry_SYSCALL_64_after_swapgs) pushq %r10 /* pt_regs->r10 */ pushq %r11 /* pt_regs->r11 */ sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */ + UNWIND_HINT_REGS extra=0 /* * If we need to do entry work or if we guess we'll need to do @@ -223,6 +223,7 @@ entry_SYSCALL_64_fastpath: movq EFLAGS(%rsp), %r11 RESTORE_C_REGS_EXCEPT_RCX_R11 movq RSP(%rsp), %rsp + UNWIND_HINT_EMPTY USERGS_SYSRET64 1: @@ -316,6 +317,7 @@ syscall_return_via_sysret: /* rcx and r11 are already restored (see code above) */ RESTORE_C_REGS_EXCEPT_RCX_R11 movq RSP(%rsp), %rsp + UNWIND_HINT_EMPTY USERGS_SYSRET64 opportunistic_sysret_failed: @@ -343,6 +345,7 @@ ENTRY(stub_ptregs_64) DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF popq %rax + UNWIND_HINT_REGS extra=0 jmp entry_SYSCALL64_slow_path 1: @@ -351,6 +354,7 @@ END(stub_ptregs_64) .macro ptregs_stub func ENTRY(ptregs_\func) + UNWIND_HINT_FUNC leaq \func(%rip), %rax jmp stub_ptregs_64 END(ptregs_\func) @@ -367,6 +371,7 @@ END(ptregs_\func) * %rsi: next task */ ENTRY(__switch_to_asm) + UNWIND_HINT_FUNC /* * Save callee-saved registers * This must match the order in inactive_task_frame @@ -406,6 +411,7 @@ END(__switch_to_asm) * r12: kernel thread arg */ ENTRY(ret_from_fork) + UNWIND_HINT_EMPTY movq %rax, %rdi call schedule_tail /* rdi: 'prev' task parameter */ @@ -413,6 +419,7 @@ ENTRY(ret_from_fork) jnz 1f /* kernel threads are uncommon */ 2: + UNWIND_HINT_REGS movq %rsp, %rdi call syscall_return_slowpath /* returns with IRQs disabled */ TRACE_IRQS_ON /* user mode is traced as IRQS on */ @@ -440,13 +447,102 @@ END(ret_from_fork) ENTRY(irq_entries_start) vector=FIRST_EXTERNAL_VECTOR .rept (FIRST_SYSTEM_VECTOR - FIRST_EXTERNAL_VECTOR) + UNWIND_HINT_IRET_REGS pushq $(~vector+0x80) /* Note: always in signed byte range */ - vector=vector+1 jmp common_interrupt .align 8 + vector=vector+1 .endr END(irq_entries_start) +.macro DEBUG_ENTRY_ASSERT_IRQS_OFF +#ifdef CONFIG_DEBUG_ENTRY + pushfq + testl $X86_EFLAGS_IF, (%rsp) + jz .Lokay_\@ + ud2 +.Lokay_\@: + addq $8, %rsp +#endif +.endm + +/* + * Enters the IRQ stack if we're not already using it. NMI-safe. Clobbers + * flags and puts old RSP into old_rsp, and leaves all other GPRs alone. + * Requires kernel GSBASE. + * + * The invariant is that, if irq_count != -1, then the IRQ stack is in use. + */ +.macro ENTER_IRQ_STACK regs=1 old_rsp + DEBUG_ENTRY_ASSERT_IRQS_OFF + movq %rsp, \old_rsp + + .if \regs + UNWIND_HINT_REGS base=\old_rsp + .endif + + incl PER_CPU_VAR(irq_count) + jnz .Lirq_stack_push_old_rsp_\@ + + /* + * Right now, if we just incremented irq_count to zero, we've + * claimed the IRQ stack but we haven't switched to it yet. + * + * If anything is added that can interrupt us here without using IST, + * it must be *extremely* careful to limit its stack usage. This + * could include kprobes and a hypothetical future IST-less #DB + * handler. + * + * The OOPS unwinder relies on the word at the top of the IRQ + * stack linking back to the previous RSP for the entire time we're + * on the IRQ stack. For this to work reliably, we need to write + * it before we actually move ourselves to the IRQ stack. + */ + + movq \old_rsp, PER_CPU_VAR(irq_stack_union + IRQ_STACK_SIZE - 8) + movq PER_CPU_VAR(irq_stack_ptr), %rsp + +#ifdef CONFIG_DEBUG_ENTRY + /* + * If the first movq above becomes wrong due to IRQ stack layout + * changes, the only way we'll notice is if we try to unwind right + * here. Assert that we set up the stack right to catch this type + * of bug quickly. + */ + cmpq -8(%rsp), \old_rsp + je .Lirq_stack_okay\@ + ud2 + .Lirq_stack_okay\@: +#endif + +.Lirq_stack_push_old_rsp_\@: + pushq \old_rsp + + .if \regs + UNWIND_HINT_REGS indirect=1 + .endif +.endm + +/* + * Undoes ENTER_IRQ_STACK. + */ +.macro LEAVE_IRQ_STACK regs=1 + DEBUG_ENTRY_ASSERT_IRQS_OFF + /* We need to be off the IRQ stack before decrementing irq_count. */ + popq %rsp + + .if \regs + UNWIND_HINT_REGS + .endif + + /* + * As in ENTER_IRQ_STACK, irq_count == 0, we are still claiming + * the irq stack but we're not on it. + */ + + decl PER_CPU_VAR(irq_count) +.endm + /* * Interrupt entry/exit. * @@ -485,17 +581,7 @@ END(irq_entries_start) CALL_enter_from_user_mode 1: - /* - * Save previous stack pointer, optionally switch to interrupt stack. - * irq_count is used to check if a CPU is already on an interrupt stack - * or not. While this is essentially redundant with preempt_count it is - * a little cheaper to use a separate counter in the PDA (short of - * moving irq_enter into assembly, which would be too much work) - */ - movq %rsp, %rdi - incl PER_CPU_VAR(irq_count) - cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp - pushq %rdi + ENTER_IRQ_STACK old_rsp=%rdi /* We entered an interrupt context - irqs are off: */ TRACE_IRQS_OFF @@ -515,10 +601,8 @@ common_interrupt: ret_from_intr: DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF - decl PER_CPU_VAR(irq_count) - /* Restore saved previous stack */ - popq %rsp + LEAVE_IRQ_STACK testb $3, CS(%rsp) jz retint_kernel @@ -561,6 +645,7 @@ restore_c_regs_and_iret: INTERRUPT_RETURN ENTRY(native_iret) + UNWIND_HINT_IRET_REGS /* * Are we returning to a stack segment from the LDT? Note: in * 64-bit mode SS:RSP on the exception stack is always valid. @@ -633,6 +718,7 @@ native_irq_return_ldt: orq PER_CPU_VAR(espfix_stack), %rax SWAPGS movq %rax, %rsp + UNWIND_HINT_IRET_REGS offset=8 /* * At this point, we cannot write to the stack any more, but we can @@ -654,6 +740,7 @@ END(common_interrupt) */ .macro apicinterrupt3 num sym do_sym ENTRY(\sym) + UNWIND_HINT_IRET_REGS ASM_CLAC pushq $~(\num) .Lcommon_\sym: @@ -662,31 +749,13 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -#define trace(sym) trace_##sym -#define smp_trace(sym) smp_trace_##sym - -.macro trace_apicinterrupt num sym -apicinterrupt3 \num trace(\sym) smp_trace(\sym) -.endm -#else -.macro trace_apicinterrupt num sym do_sym -.endm -#endif - /* Make sure APIC interrupt handlers end up in the irqentry section: */ -#if defined(CONFIG_FUNCTION_GRAPH_TRACER) || defined(CONFIG_KASAN) -# define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax" -# define POP_SECTION_IRQENTRY .popsection -#else -# define PUSH_SECTION_IRQENTRY -# define POP_SECTION_IRQENTRY -#endif +#define PUSH_SECTION_IRQENTRY .pushsection .irqentry.text, "ax" +#define POP_SECTION_IRQENTRY .popsection .macro apicinterrupt num sym do_sym PUSH_SECTION_IRQENTRY apicinterrupt3 \num \sym \do_sym -trace_apicinterrupt \num \sym POP_SECTION_IRQENTRY .endm @@ -740,13 +809,14 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 ENTRY(\sym) + UNWIND_HINT_IRET_REGS offset=\has_error_code*8 + /* Sanity check */ .if \shift_ist != -1 && \paranoid == 0 .error "using shift_ist requires paranoid=1" .endif ASM_CLAC - PARAVIRT_ADJUST_EXCEPTION_FRAME .ifeq \has_error_code pushq $-1 /* ORIG_RAX: no syscall to restart */ @@ -763,6 +833,7 @@ ENTRY(\sym) .else call error_entry .endif + UNWIND_HINT_REGS /* returned flag: ebx=0: need swapgs on exit, ebx=1: don't need it */ .if \paranoid @@ -829,17 +900,6 @@ ENTRY(\sym) END(\sym) .endm -#ifdef CONFIG_TRACING -.macro trace_idtentry sym do_sym has_error_code:req -idtentry trace(\sym) trace(\do_sym) has_error_code=\has_error_code -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#else -.macro trace_idtentry sym do_sym has_error_code:req -idtentry \sym \do_sym has_error_code=\has_error_code -.endm -#endif - idtentry divide_error do_divide_error has_error_code=0 idtentry overflow do_overflow has_error_code=0 idtentry bounds do_bounds has_error_code=0 @@ -860,6 +920,7 @@ idtentry simd_coprocessor_error do_simd_coprocessor_error has_error_code=0 * edi: new selector */ ENTRY(native_load_gs_index) + FRAME_BEGIN pushfq DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI) SWAPGS @@ -868,8 +929,9 @@ ENTRY(native_load_gs_index) 2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE SWAPGS popfq + FRAME_END ret -END(native_load_gs_index) +ENDPROC(native_load_gs_index) EXPORT_SYMBOL(native_load_gs_index) _ASM_EXTABLE(.Lgs_change, bad_gs) @@ -892,17 +954,15 @@ bad_gs: ENTRY(do_softirq_own_stack) pushq %rbp mov %rsp, %rbp - incl PER_CPU_VAR(irq_count) - cmove PER_CPU_VAR(irq_stack_ptr), %rsp - push %rbp /* frame pointer backlink */ + ENTER_IRQ_STACK regs=0 old_rsp=%r11 call __do_softirq + LEAVE_IRQ_STACK regs=0 leaveq - decl PER_CPU_VAR(irq_count) ret -END(do_softirq_own_stack) +ENDPROC(do_softirq_own_stack) #ifdef CONFIG_XEN -idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0 +idtentry hypervisor_callback xen_do_hypervisor_callback has_error_code=0 /* * A note on the "critical region" in our callback handler. @@ -923,14 +983,14 @@ ENTRY(xen_do_hypervisor_callback) /* do_hypervisor_callback(struct *pt_regs) */ * Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will * see the correct pointer to the pt_regs */ + UNWIND_HINT_FUNC movq %rdi, %rsp /* we don't return, adjust the stack frame */ -11: incl PER_CPU_VAR(irq_count) - movq %rsp, %rbp - cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp - pushq %rbp /* frame pointer backlink */ + UNWIND_HINT_REGS + + ENTER_IRQ_STACK old_rsp=%r10 call xen_evtchn_do_upcall - popq %rsp - decl PER_CPU_VAR(irq_count) + LEAVE_IRQ_STACK + #ifndef CONFIG_PREEMPT call xen_maybe_preempt_hcall #endif @@ -951,6 +1011,7 @@ END(xen_do_hypervisor_callback) * with its current contents: any discrepancy means we in category 1. */ ENTRY(xen_failsafe_callback) + UNWIND_HINT_EMPTY movl %ds, %ecx cmpw %cx, 0x10(%rsp) jne 1f @@ -968,13 +1029,13 @@ ENTRY(xen_failsafe_callback) movq 8(%rsp), %r11 addq $0x30, %rsp pushq $0 /* RIP */ - pushq %r11 - pushq %rcx + UNWIND_HINT_IRET_REGS offset=8 jmp general_protection 1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */ movq (%rsp), %rcx movq 8(%rsp), %r11 addq $0x30, %rsp + UNWIND_HINT_IRET_REGS pushq $-1 /* orig_ax = -1 => not a system call */ ALLOC_PT_GPREGS_ON_STACK SAVE_C_REGS @@ -998,13 +1059,12 @@ idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK idtentry stack_segment do_stack_segment has_error_code=1 #ifdef CONFIG_XEN -idtentry xen_debug do_debug has_error_code=0 -idtentry xen_int3 do_int3 has_error_code=0 -idtentry xen_stack_segment do_stack_segment has_error_code=1 +idtentry xendebug do_debug has_error_code=0 +idtentry xenint3 do_int3 has_error_code=0 #endif idtentry general_protection do_general_protection has_error_code=1 -trace_idtentry page_fault do_page_fault has_error_code=1 +idtentry page_fault do_page_fault has_error_code=1 #ifdef CONFIG_KVM_GUEST idtentry async_page_fault do_async_page_fault has_error_code=1 @@ -1020,6 +1080,7 @@ idtentry machine_check has_error_code=0 paranoid=1 do_sym=*machine_check_vec * Return: ebx=0: need swapgs on exit, ebx=1: otherwise */ ENTRY(paranoid_entry) + UNWIND_HINT_FUNC cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 @@ -1047,6 +1108,7 @@ END(paranoid_entry) * On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) */ ENTRY(paranoid_exit) + UNWIND_HINT_REGS DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF_DEBUG testl %ebx, %ebx /* swapgs needed? */ @@ -1068,6 +1130,7 @@ END(paranoid_exit) * Return: EBX=0: came from user mode; EBX=1: otherwise */ ENTRY(error_entry) + UNWIND_HINT_FUNC cld SAVE_C_REGS 8 SAVE_EXTRA_REGS 8 @@ -1152,6 +1215,7 @@ END(error_entry) * 0: user gsbase is loaded, we need SWAPGS and standard preparation for return to usermode */ ENTRY(error_exit) + UNWIND_HINT_REGS DISABLE_INTERRUPTS(CLBR_ANY) TRACE_IRQS_OFF testl %ebx, %ebx @@ -1160,19 +1224,9 @@ ENTRY(error_exit) END(error_exit) /* Runs on exception stack */ +/* XXX: broken on Xen PV */ ENTRY(nmi) - /* - * Fix up the exception frame if we're on Xen. - * PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most - * one value to the stack on native, so it may clobber the rdx - * scratch slot, but it won't clobber any of the important - * slots past it. - * - * Xen is a different story, because the Xen frame itself overlaps - * the "NMI executing" variable. - */ - PARAVIRT_ADJUST_EXCEPTION_FRAME - + UNWIND_HINT_IRET_REGS /* * We allow breakpoints in NMIs. If a breakpoint occurs, then * the iretq it performs will take us out of NMI context. @@ -1234,11 +1288,13 @@ ENTRY(nmi) cld movq %rsp, %rdx movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp + UNWIND_HINT_IRET_REGS base=%rdx offset=8 pushq 5*8(%rdx) /* pt_regs->ss */ pushq 4*8(%rdx) /* pt_regs->rsp */ pushq 3*8(%rdx) /* pt_regs->flags */ pushq 2*8(%rdx) /* pt_regs->cs */ pushq 1*8(%rdx) /* pt_regs->rip */ + UNWIND_HINT_IRET_REGS pushq $-1 /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ @@ -1255,6 +1311,7 @@ ENTRY(nmi) pushq %r13 /* pt_regs->r13 */ pushq %r14 /* pt_regs->r14 */ pushq %r15 /* pt_regs->r15 */ + UNWIND_HINT_REGS ENCODE_FRAME_POINTER /* @@ -1409,6 +1466,7 @@ first_nmi: .rept 5 pushq 11*8(%rsp) .endr + UNWIND_HINT_IRET_REGS /* Everything up to here is safe from nested NMIs */ @@ -1424,6 +1482,7 @@ first_nmi: pushq $__KERNEL_CS /* CS */ pushq $1f /* RIP */ INTERRUPT_RETURN /* continues at repeat_nmi below */ + UNWIND_HINT_IRET_REGS 1: #endif @@ -1473,6 +1532,7 @@ end_repeat_nmi: * exceptions might do. */ call paranoid_entry + UNWIND_HINT_REGS /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp, %rdi @@ -1510,17 +1570,19 @@ nmi_restore: END(nmi) ENTRY(ignore_sysret) + UNWIND_HINT_EMPTY mov $-ENOSYS, %eax sysret END(ignore_sysret) ENTRY(rewind_stack_do_exit) + UNWIND_HINT_FUNC /* Prevent any naive code from trying to unwind to our caller. */ xorl %ebp, %ebp movq PER_CPU_VAR(cpu_current_top_of_stack), %rax - leaq -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%rax), %rsp + leaq -PTREGS_SIZE(%rax), %rsp + UNWIND_HINT_FUNC sp_offset=PTREGS_SIZE call do_exit -1: jmp 1b END(rewind_stack_do_exit) diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index e1721dafbcb1..b5c7a56ed256 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Compatibility mode system call entry point for x86-64. * @@ -183,21 +184,20 @@ ENDPROC(entry_SYSENTER_compat) */ ENTRY(entry_SYSCALL_compat) /* Interrupts are off on entry. */ - SWAPGS_UNSAFE_STACK + swapgs /* Stash user ESP and switch to the kernel stack. */ movl %esp, %r8d movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp - /* Zero-extending 32-bit regs, do not remove */ - movl %eax, %eax - /* Construct struct pt_regs on stack */ pushq $__USER32_DS /* pt_regs->ss */ pushq %r8 /* pt_regs->sp */ pushq %r11 /* pt_regs->flags */ pushq $__USER32_CS /* pt_regs->cs */ pushq %rcx /* pt_regs->ip */ +GLOBAL(entry_SYSCALL_compat_after_hwframe) + movl %eax, %eax /* discard orig_ax high bits */ pushq %rax /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ @@ -294,7 +294,6 @@ ENTRY(entry_INT80_compat) /* * Interrupts are off on entry. */ - PARAVIRT_ADJUST_EXCEPTION_FRAME ASM_CLAC /* Do this early to minimize exposure */ SWAPGS @@ -342,8 +341,7 @@ ENTRY(entry_INT80_compat) jmp restore_regs_and_iret END(entry_INT80_compat) - ALIGN -GLOBAL(stub32_clone) +ENTRY(stub32_clone) /* * The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr). * The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val). @@ -353,3 +351,4 @@ GLOBAL(stub32_clone) */ xchg %r8, %rcx jmp sys_clone +ENDPROC(stub32_clone) diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c index 8f895ee13a1c..95c294963612 100644 --- a/arch/x86/entry/syscall_32.c +++ b/arch/x86/entry/syscall_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* System call table for i386. */ #include diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c index 9dbc5abb6162..9c09775e589d 100644 --- a/arch/x86/entry/syscall_64.c +++ b/arch/x86/entry/syscall_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* System call table for x86-64. */ #include diff --git a/arch/x86/entry/syscalls/Makefile b/arch/x86/entry/syscalls/Makefile index 57aa59fd140c..331f1dca5085 100644 --- a/arch/x86/entry/syscalls/Makefile +++ b/arch/x86/entry/syscalls/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 out := $(obj)/../../include/generated/asm uapi := $(obj)/../../include/generated/uapi/asm diff --git a/arch/x86/entry/syscalls/syscallhdr.sh b/arch/x86/entry/syscalls/syscallhdr.sh index 31fd5f1f38f7..12fbbcfe7ef3 100644 --- a/arch/x86/entry/syscalls/syscallhdr.sh +++ b/arch/x86/entry/syscalls/syscallhdr.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 in="$1" out="$2" diff --git a/arch/x86/entry/syscalls/syscalltbl.sh b/arch/x86/entry/syscalls/syscalltbl.sh index 751d1f992630..d71ef4bd3615 100644 --- a/arch/x86/entry/syscalls/syscalltbl.sh +++ b/arch/x86/entry/syscalls/syscalltbl.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 in="$1" out="$2" diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index d5409660f5de..c366c0adeb40 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Building vDSO images for x86. # diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S b/arch/x86/entry/vdso/vdso-layout.lds.S index 8ebb4b6454fe..acfd5ba7d943 100644 --- a/arch/x86/entry/vdso/vdso-layout.lds.S +++ b/arch/x86/entry/vdso/vdso-layout.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/arch/x86/entry/vdso/vdso.lds.S b/arch/x86/entry/vdso/vdso.lds.S index 6807932643c2..d3a2dce4cfa9 100644 --- a/arch/x86/entry/vdso/vdso.lds.S +++ b/arch/x86/entry/vdso/vdso.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Linker script for 64-bit vDSO. * We #include the file to define the layout details. diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h index 3dab75f2a673..fa847a620f40 100644 --- a/arch/x86/entry/vdso/vdso2c.h +++ b/arch/x86/entry/vdso/vdso2c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is included twice from vdso2c.c. It generates code for 32-bit * and 64-bit vDSOs. We need both for 64-bit builds, since 32-bit vDSOs diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c index 3f9d1a83891a..42d4c89f990e 100644 --- a/arch/x86/entry/vdso/vdso32-setup.c +++ b/arch/x86/entry/vdso/vdso32-setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * (C) Copyright 2002 Linus Torvalds * Portions based on the vdso-randomization code from exec-shield: diff --git a/arch/x86/entry/vdso/vdso32/note.S b/arch/x86/entry/vdso/vdso32/note.S index c83f25734696..9fd51f206314 100644 --- a/arch/x86/entry/vdso/vdso32/note.S +++ b/arch/x86/entry/vdso/vdso32/note.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. * Here we can supply some information useful to userland. diff --git a/arch/x86/entry/vdso/vdso32/sigreturn.S b/arch/x86/entry/vdso/vdso32/sigreturn.S index 20633e026e82..c3233ee98a6b 100644 --- a/arch/x86/entry/vdso/vdso32/sigreturn.S +++ b/arch/x86/entry/vdso/vdso32/sigreturn.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S index ed4bc9731cbb..263d7433dea8 100644 --- a/arch/x86/entry/vdso/vdso32/system_call.S +++ b/arch/x86/entry/vdso/vdso32/system_call.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * AT_SYSINFO entry point */ diff --git a/arch/x86/entry/vdso/vdso32/vclock_gettime.c b/arch/x86/entry/vdso/vdso32/vclock_gettime.c index 87a86e017f0e..7780bbfb06ef 100644 --- a/arch/x86/entry/vdso/vdso32/vclock_gettime.c +++ b/arch/x86/entry/vdso/vdso32/vclock_gettime.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define BUILD_VDSO32 #ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE diff --git a/arch/x86/entry/vdso/vdso32/vdso32.lds.S b/arch/x86/entry/vdso/vdso32/vdso32.lds.S index 31056cf294bf..422764a81d32 100644 --- a/arch/x86/entry/vdso/vdso32/vdso32.lds.S +++ b/arch/x86/entry/vdso/vdso32/vdso32.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Linker script for 32-bit vDSO. * We #include the file to define the layout details. diff --git a/arch/x86/entry/vdso/vdsox32.lds.S b/arch/x86/entry/vdso/vdsox32.lds.S index 697c11ece90c..05cd1c5c4a15 100644 --- a/arch/x86/entry/vdso/vdsox32.lds.S +++ b/arch/x86/entry/vdso/vdsox32.lds.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Linker script for x32 vDSO. * We #include the file to define the layout details. diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 726355ce8497..1911310959f8 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -351,7 +351,7 @@ static void vgetcpu_cpu_init(void *arg) * and 8 bits for the node) */ d.limit0 = cpu | ((node & 0xf) << 12); - d.limit = node >> 4; + d.limit1 = node >> 4; d.type = 5; /* RO data, expand down, accessed */ d.dpl = 3; /* Visible to user code */ d.s = 1; /* Not a system segment */ diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c index ce1d7534fa53..f279ba2643dc 100644 --- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2014 Andy Lutomirski * diff --git a/arch/x86/entry/vsyscall/vsyscall_gtod.c b/arch/x86/entry/vsyscall/vsyscall_gtod.c index 0fb3a104ac62..e1216dd95c04 100644 --- a/arch/x86/entry/vsyscall/vsyscall_gtod.c +++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2001 Andrea Arcangeli SuSE * Copyright 2003 Andi Kleen, SuSE Labs. diff --git a/arch/x86/entry/vsyscall/vsyscall_trace.h b/arch/x86/entry/vsyscall/vsyscall_trace.h index 9dd7359a38a8..3c3f9765a85c 100644 --- a/arch/x86/entry/vsyscall/vsyscall_trace.h +++ b/arch/x86/entry/vsyscall/vsyscall_trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM vsyscall diff --git a/arch/x86/events/Kconfig b/arch/x86/events/Kconfig index 98397db5ceae..9a7a1446cb3a 100644 --- a/arch/x86/events/Kconfig +++ b/arch/x86/events/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "Performance monitoring" config PERF_EVENTS_INTEL_UNCORE diff --git a/arch/x86/events/amd/Makefile b/arch/x86/events/amd/Makefile index b1da46f396e0..fe8795a67385 100644 --- a/arch/x86/events/amd/Makefile +++ b/arch/x86/events/amd/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CPU_SUP_AMD) += core.o uncore.o obj-$(CONFIG_PERF_EVENTS_AMD_POWER) += power.o obj-$(CONFIG_X86_LOCAL_APIC) += ibs.o diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index ad44af0dd667..f5cbbba99283 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -400,11 +400,24 @@ static int amd_uncore_cpu_starting(unsigned int cpu) if (amd_uncore_llc) { unsigned int apicid = cpu_data(cpu).apicid; - unsigned int nshared; + unsigned int nshared, subleaf, prev_eax = 0; uncore = *per_cpu_ptr(amd_uncore_llc, cpu); - cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx); - nshared = ((eax >> 14) & 0xfff) + 1; + /* + * Iterate over Cache Topology Definition leaves until no + * more cache descriptions are available. + */ + for (subleaf = 0; subleaf < 5; subleaf++) { + cpuid_count(0x8000001d, subleaf, &eax, &ebx, &ecx, &edx); + + /* EAX[0:4] gives type of cache */ + if (!(eax & 0x1f)) + break; + + prev_eax = eax; + } + nshared = ((prev_eax >> 14) & 0xfff) + 1; + uncore->id = apicid - (apicid % nshared); uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_llc); @@ -555,7 +568,7 @@ static int __init amd_uncore_init(void) ret = 0; } - if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) { + if (boot_cpu_has(X86_FEATURE_PERFCTR_LLC)) { amd_uncore_llc = alloc_percpu(struct amd_uncore *); if (!amd_uncore_llc) { ret = -ENOMEM; diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 939050169d12..80534d3c2480 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -487,22 +487,28 @@ static inline int precise_br_compat(struct perf_event *event) return m == b; } +int x86_pmu_max_precise(void) +{ + int precise = 0; + + /* Support for constant skid */ + if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { + precise++; + + /* Support for IP fixup */ + if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2) + precise++; + + if (x86_pmu.pebs_prec_dist) + precise++; + } + return precise; +} + int x86_pmu_hw_config(struct perf_event *event) { if (event->attr.precise_ip) { - int precise = 0; - - /* Support for constant skid */ - if (x86_pmu.pebs_active && !x86_pmu.pebs_broken) { - precise++; - - /* Support for IP fixup */ - if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2) - precise++; - - if (x86_pmu.pebs_prec_dist) - precise++; - } + int precise = x86_pmu_max_precise(); if (event->attr.precise_ip > precise) return -EOPNOTSUPP; @@ -1751,6 +1757,7 @@ ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event) } static struct attribute_group x86_pmu_attr_group; +static struct attribute_group x86_pmu_caps_group; static int __init init_hw_perf_events(void) { @@ -1799,6 +1806,14 @@ static int __init init_hw_perf_events(void) x86_pmu_format_group.attrs = x86_pmu.format_attrs; + if (x86_pmu.caps_attrs) { + struct attribute **tmp; + + tmp = merge_attr(x86_pmu_caps_group.attrs, x86_pmu.caps_attrs); + if (!WARN_ON(!tmp)) + x86_pmu_caps_group.attrs = tmp; + } + if (x86_pmu.event_attrs) x86_pmu_events_group.attrs = x86_pmu.event_attrs; @@ -2213,10 +2228,30 @@ static struct attribute_group x86_pmu_attr_group = { .attrs = x86_pmu_attrs, }; +static ssize_t max_precise_show(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu_max_precise()); +} + +static DEVICE_ATTR_RO(max_precise); + +static struct attribute *x86_pmu_caps_attrs[] = { + &dev_attr_max_precise.attr, + NULL +}; + +static struct attribute_group x86_pmu_caps_group = { + .name = "caps", + .attrs = x86_pmu_caps_attrs, +}; + static const struct attribute_group *x86_pmu_attr_groups[] = { &x86_pmu_attr_group, &x86_pmu_format_group, &x86_pmu_events_group, + &x86_pmu_caps_group, NULL, }; diff --git a/arch/x86/events/intel/Makefile b/arch/x86/events/intel/Makefile index 06c2baa51814..3468b0c1dc7c 100644 --- a/arch/x86/events/intel/Makefile +++ b/arch/x86/events/intel/Makefile @@ -1,4 +1,5 @@ -obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o cqm.o +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o obj-$(CONFIG_CPU_SUP_INTEL) += ds.o knc.o obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += intel-rapl-perf.o diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c index ddd8d3516bfc..141e07b06216 100644 --- a/arch/x86/events/intel/bts.c +++ b/arch/x86/events/intel/bts.c @@ -268,7 +268,7 @@ static void bts_event_start(struct perf_event *event, int flags) bts->ds_back.bts_absolute_maximum = cpuc->ds->bts_absolute_maximum; bts->ds_back.bts_interrupt_threshold = cpuc->ds->bts_interrupt_threshold; - event->hw.itrace_started = 1; + perf_event_itrace_started(event); event->hw.state = 0; __bts_event_start(event); @@ -546,9 +546,6 @@ static int bts_event_init(struct perf_event *event) if (event->attr.type != bts_pmu.type) return -ENOENT; - if (x86_add_exclusive(x86_lbr_exclusive_bts)) - return -EBUSY; - /* * BTS leaks kernel addresses even when CPL0 tracing is * disabled, so disallow intel_bts driver for unprivileged @@ -562,6 +559,9 @@ static int bts_event_init(struct perf_event *event) !capable(CAP_SYS_ADMIN)) return -EACCES; + if (x86_add_exclusive(x86_lbr_exclusive_bts)) + return -EBUSY; + ret = x86_reserve_hardware(); if (ret) { x86_del_exclusive(x86_lbr_exclusive_bts); diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 98b0f0729527..9fb9a1f1e47b 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -3415,12 +3415,26 @@ static struct attribute *intel_arch3_formats_attr[] = { &format_attr_any.attr, &format_attr_inv.attr, &format_attr_cmask.attr, + NULL, +}; + +static struct attribute *hsw_format_attr[] = { &format_attr_in_tx.attr, &format_attr_in_tx_cp.attr, + &format_attr_offcore_rsp.attr, + &format_attr_ldlat.attr, + NULL +}; - &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */ - &format_attr_ldlat.attr, /* PEBS load latency */ - NULL, +static struct attribute *nhm_format_attr[] = { + &format_attr_offcore_rsp.attr, + &format_attr_ldlat.attr, + NULL +}; + +static struct attribute *slm_format_attr[] = { + &format_attr_offcore_rsp.attr, + NULL }; static struct attribute *skl_format_attr[] = { @@ -3781,6 +3795,36 @@ done: static DEVICE_ATTR_RW(freeze_on_smi); +static ssize_t branches_show(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", x86_pmu.lbr_nr); +} + +static DEVICE_ATTR_RO(branches); + +static struct attribute *lbr_attrs[] = { + &dev_attr_branches.attr, + NULL +}; + +static char pmu_name_str[30]; + +static ssize_t pmu_name_show(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", pmu_name_str); +} + +static DEVICE_ATTR_RO(pmu_name); + +static struct attribute *intel_pmu_caps_attrs[] = { + &dev_attr_pmu_name.attr, + NULL +}; + static struct attribute *intel_pmu_attrs[] = { &dev_attr_freeze_on_smi.attr, NULL, @@ -3795,6 +3839,8 @@ __init int intel_pmu_init(void) unsigned int unused; struct extra_reg *er; int version, i; + struct attribute **extra_attr = NULL; + char *name; if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { switch (boot_cpu_data.x86) { @@ -3862,6 +3908,7 @@ __init int intel_pmu_init(void) switch (boot_cpu_data.x86_model) { case INTEL_FAM6_CORE_YONAH: pr_cont("Core events, "); + name = "core"; break; case INTEL_FAM6_CORE2_MEROM: @@ -3877,6 +3924,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_core2_event_constraints; x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints; pr_cont("Core2 events, "); + name = "core2"; break; case INTEL_FAM6_NEHALEM: @@ -3905,8 +3953,11 @@ __init int intel_pmu_init(void) intel_pmu_pebs_data_source_nhm(); x86_add_quirk(intel_nehalem_quirk); + x86_pmu.pebs_no_tlb = 1; + extra_attr = nhm_format_attr; pr_cont("Nehalem events, "); + name = "nehalem"; break; case INTEL_FAM6_ATOM_PINEVIEW: @@ -3923,6 +3974,7 @@ __init int intel_pmu_init(void) x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints; x86_pmu.pebs_aliases = intel_pebs_aliases_core2; pr_cont("Atom events, "); + name = "bonnell"; break; case INTEL_FAM6_ATOM_SILVERMONT1: @@ -3940,7 +3992,9 @@ __init int intel_pmu_init(void) x86_pmu.extra_regs = intel_slm_extra_regs; x86_pmu.flags |= PMU_FL_HAS_RSP_1; x86_pmu.cpu_events = slm_events_attrs; + extra_attr = slm_format_attr; pr_cont("Silvermont events, "); + name = "silvermont"; break; case INTEL_FAM6_ATOM_GOLDMONT: @@ -3965,7 +4019,9 @@ __init int intel_pmu_init(void) x86_pmu.lbr_pt_coexist = true; x86_pmu.flags |= PMU_FL_HAS_RSP_1; x86_pmu.cpu_events = glm_events_attrs; + extra_attr = slm_format_attr; pr_cont("Goldmont events, "); + name = "goldmont"; break; case INTEL_FAM6_ATOM_GEMINI_LAKE: @@ -3991,7 +4047,9 @@ __init int intel_pmu_init(void) x86_pmu.cpu_events = glm_events_attrs; /* Goldmont Plus has 4-wide pipeline */ event_attr_td_total_slots_scale_glm.event_str = "4"; + extra_attr = slm_format_attr; pr_cont("Goldmont plus events, "); + name = "goldmont_plus"; break; case INTEL_FAM6_WESTMERE: @@ -4020,7 +4078,9 @@ __init int intel_pmu_init(void) X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1); intel_pmu_pebs_data_source_nhm(); + extra_attr = nhm_format_attr; pr_cont("Westmere events, "); + name = "westmere"; break; case INTEL_FAM6_SANDYBRIDGE: @@ -4056,7 +4116,10 @@ __init int intel_pmu_init(void) intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = X86_CONFIG(.event=0xb1, .umask=0x01, .inv=1, .cmask=1); + extra_attr = nhm_format_attr; + pr_cont("SandyBridge events, "); + name = "sandybridge"; break; case INTEL_FAM6_IVYBRIDGE: @@ -4090,7 +4153,10 @@ __init int intel_pmu_init(void) intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); + extra_attr = nhm_format_attr; + pr_cont("IvyBridge events, "); + name = "ivybridge"; break; @@ -4118,7 +4184,10 @@ __init int intel_pmu_init(void) x86_pmu.get_event_constraints = hsw_get_event_constraints; x86_pmu.cpu_events = hsw_events_attrs; x86_pmu.lbr_double_abort = true; + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; pr_cont("Haswell events, "); + name = "haswell"; break; case INTEL_FAM6_BROADWELL_CORE: @@ -4154,7 +4223,10 @@ __init int intel_pmu_init(void) x86_pmu.get_event_constraints = hsw_get_event_constraints; x86_pmu.cpu_events = hsw_events_attrs; x86_pmu.limit_period = bdw_limit_period; + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; pr_cont("Broadwell events, "); + name = "broadwell"; break; case INTEL_FAM6_XEON_PHI_KNL: @@ -4172,8 +4244,9 @@ __init int intel_pmu_init(void) /* all extra regs are per-cpu when HT is on */ x86_pmu.flags |= PMU_FL_HAS_RSP_1; x86_pmu.flags |= PMU_FL_NO_HT_SHARING; - + extra_attr = slm_format_attr; pr_cont("Knights Landing/Mill events, "); + name = "knights-landing"; break; case INTEL_FAM6_SKYLAKE_MOBILE: @@ -4203,11 +4276,14 @@ __init int intel_pmu_init(void) x86_pmu.hw_config = hsw_hw_config; x86_pmu.get_event_constraints = hsw_get_event_constraints; - x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr, - skl_format_attr); - WARN_ON(!x86_pmu.format_attrs); + extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? + hsw_format_attr : nhm_format_attr; + extra_attr = merge_attr(extra_attr, skl_format_attr); x86_pmu.cpu_events = hsw_events_attrs; + intel_pmu_pebs_data_source_skl( + boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X); pr_cont("Skylake events, "); + name = "skylake"; break; default: @@ -4215,6 +4291,7 @@ __init int intel_pmu_init(void) case 1: x86_pmu.event_constraints = intel_v1_event_constraints; pr_cont("generic architected perfmon v1, "); + name = "generic_arch_v1"; break; default: /* @@ -4222,10 +4299,19 @@ __init int intel_pmu_init(void) */ x86_pmu.event_constraints = intel_gen_event_constraints; pr_cont("generic architected perfmon, "); + name = "generic_arch_v2+"; break; } } + snprintf(pmu_name_str, sizeof pmu_name_str, "%s", name); + + if (version >= 2 && extra_attr) { + x86_pmu.format_attrs = merge_attr(intel_arch3_formats_attr, + extra_attr); + WARN_ON(!x86_pmu.format_attrs); + } + if (x86_pmu.num_counters > INTEL_PMC_MAX_GENERIC) { WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!", x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC); @@ -4272,8 +4358,13 @@ __init int intel_pmu_init(void) x86_pmu.lbr_nr = 0; } - if (x86_pmu.lbr_nr) + x86_pmu.caps_attrs = intel_pmu_caps_attrs; + + if (x86_pmu.lbr_nr) { + x86_pmu.caps_attrs = merge_attr(x86_pmu.caps_attrs, lbr_attrs); pr_cont("%d-deep LBR, ", x86_pmu.lbr_nr); + } + /* * Access extra MSR may cause #GP under certain circumstances. * E.g. KVM doesn't support offcore event @@ -4318,10 +4409,9 @@ static __init int fixup_ht_bug(void) return 0; } - if (lockup_detector_suspend() != 0) { - pr_debug("failed to disable PMU erratum BJ122, BV98, HSD29 workaround\n"); - return 0; - } + cpus_read_lock(); + + hardlockup_detector_perf_stop(); x86_pmu.flags &= ~(PMU_FL_EXCL_CNTRS | PMU_FL_EXCL_ENABLED); @@ -4329,9 +4419,7 @@ static __init int fixup_ht_bug(void) x86_pmu.commit_scheduling = NULL; x86_pmu.stop_scheduling = NULL; - lockup_detector_resume(); - - cpus_read_lock(); + hardlockup_detector_perf_restart(); for_each_online_cpu(c) free_excl_cntrs(c); diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c deleted file mode 100644 index 2521f771f2f5..000000000000 --- a/arch/x86/events/intel/cqm.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* - * Intel Cache Quality-of-Service Monitoring (CQM) support. - * - * Based very, very heavily on work by Peter Zijlstra. - */ - -#include -#include -#include -#include -#include "../perf_event.h" - -#define MSR_IA32_QM_CTR 0x0c8e -#define MSR_IA32_QM_EVTSEL 0x0c8d - -#define MBM_CNTR_WIDTH 24 -/* - * Guaranteed time in ms as per SDM where MBM counters will not overflow. - */ -#define MBM_CTR_OVERFLOW_TIME 1000 - -static u32 cqm_max_rmid = -1; -static unsigned int cqm_l3_scale; /* supposedly cacheline size */ -static bool cqm_enabled, mbm_enabled; -unsigned int mbm_socket_max; - -/* - * The cached intel_pqr_state is strictly per CPU and can never be - * updated from a remote CPU. Both functions which modify the state - * (intel_cqm_event_start and intel_cqm_event_stop) are called with - * interrupts disabled, which is sufficient for the protection. - */ -DEFINE_PER_CPU(struct intel_pqr_state, pqr_state); -static struct hrtimer *mbm_timers; -/** - * struct sample - mbm event's (local or total) data - * @total_bytes #bytes since we began monitoring - * @prev_msr previous value of MSR - */ -struct sample { - u64 total_bytes; - u64 prev_msr; -}; - -/* - * samples profiled for total memory bandwidth type events - */ -static struct sample *mbm_total; -/* - * samples profiled for local memory bandwidth type events - */ -static struct sample *mbm_local; - -#define pkg_id topology_physical_package_id(smp_processor_id()) -/* - * rmid_2_index returns the index for the rmid in mbm_local/mbm_total array. - * mbm_total[] and mbm_local[] are linearly indexed by socket# * max number of - * rmids per socket, an example is given below - * RMID1 of Socket0: vrmid = 1 - * RMID1 of Socket1: vrmid = 1 * (cqm_max_rmid + 1) + 1 - * RMID1 of Socket2: vrmid = 2 * (cqm_max_rmid + 1) + 1 - */ -#define rmid_2_index(rmid) ((pkg_id * (cqm_max_rmid + 1)) + rmid) -/* - * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru. - * Also protects event->hw.cqm_rmid - * - * Hold either for stability, both for modification of ->hw.cqm_rmid. - */ -static DEFINE_MUTEX(cache_mutex); -static DEFINE_RAW_SPINLOCK(cache_lock); - -/* - * Groups of events that have the same target(s), one RMID per group. - */ -static LIST_HEAD(cache_groups); - -/* - * Mask of CPUs for reading CQM values. We only need one per-socket. - */ -static cpumask_t cqm_cpumask; - -#define RMID_VAL_ERROR (1ULL << 63) -#define RMID_VAL_UNAVAIL (1ULL << 62) - -/* - * Event IDs are used to program IA32_QM_EVTSEL before reading event - * counter from IA32_QM_CTR - */ -#define QOS_L3_OCCUP_EVENT_ID 0x01 -#define QOS_MBM_TOTAL_EVENT_ID 0x02 -#define QOS_MBM_LOCAL_EVENT_ID 0x03 - -/* - * This is central to the rotation algorithm in __intel_cqm_rmid_rotate(). - * - * This rmid is always free and is guaranteed to have an associated - * near-zero occupancy value, i.e. no cachelines are tagged with this - * RMID, once __intel_cqm_rmid_rotate() returns. - */ -static u32 intel_cqm_rotation_rmid; - -#define INVALID_RMID (-1) - -/* - * Is @rmid valid for programming the hardware? - * - * rmid 0 is reserved by the hardware for all non-monitored tasks, which - * means that we should never come across an rmid with that value. - * Likewise, an rmid value of -1 is used to indicate "no rmid currently - * assigned" and is used as part of the rotation code. - */ -static inline bool __rmid_valid(u32 rmid) -{ - if (!rmid || rmid == INVALID_RMID) - return false; - - return true; -} - -static u64 __rmid_read(u32 rmid) -{ - u64 val; - - /* - * Ignore the SDM, this thing is _NOTHING_ like a regular perfcnt, - * it just says that to increase confusion. - */ - wrmsr(MSR_IA32_QM_EVTSEL, QOS_L3_OCCUP_EVENT_ID, rmid); - rdmsrl(MSR_IA32_QM_CTR, val); - - /* - * Aside from the ERROR and UNAVAIL bits, assume this thing returns - * the number of cachelines tagged with @rmid. - */ - return val; -} - -enum rmid_recycle_state { - RMID_YOUNG = 0, - RMID_AVAILABLE, - RMID_DIRTY, -}; - -struct cqm_rmid_entry { - u32 rmid; - enum rmid_recycle_state state; - struct list_head list; - unsigned long queue_time; -}; - -/* - * cqm_rmid_free_lru - A least recently used list of RMIDs. - * - * Oldest entry at the head, newest (most recently used) entry at the - * tail. This list is never traversed, it's only used to keep track of - * the lru order. That is, we only pick entries of the head or insert - * them on the tail. - * - * All entries on the list are 'free', and their RMIDs are not currently - * in use. To mark an RMID as in use, remove its entry from the lru - * list. - * - * - * cqm_rmid_limbo_lru - list of currently unused but (potentially) dirty RMIDs. - * - * This list is contains RMIDs that no one is currently using but that - * may have a non-zero occupancy value associated with them. The - * rotation worker moves RMIDs from the limbo list to the free list once - * the occupancy value drops below __intel_cqm_threshold. - * - * Both lists are protected by cache_mutex. - */ -static LIST_HEAD(cqm_rmid_free_lru); -static LIST_HEAD(cqm_rmid_limbo_lru); - -/* - * We use a simple array of pointers so that we can lookup a struct - * cqm_rmid_entry in O(1). This alleviates the callers of __get_rmid() - * and __put_rmid() from having to worry about dealing with struct - * cqm_rmid_entry - they just deal with rmids, i.e. integers. - * - * Once this array is initialized it is read-only. No locks are required - * to access it. - * - * All entries for all RMIDs can be looked up in the this array at all - * times. - */ -static struct cqm_rmid_entry **cqm_rmid_ptrs; - -static inline struct cqm_rmid_entry *__rmid_entry(u32 rmid) -{ - struct cqm_rmid_entry *entry; - - entry = cqm_rmid_ptrs[rmid]; - WARN_ON(entry->rmid != rmid); - - return entry; -} - -/* - * Returns < 0 on fail. - * - * We expect to be called with cache_mutex held. - */ -static u32 __get_rmid(void) -{ - struct cqm_rmid_entry *entry; - - lockdep_assert_held(&cache_mutex); - - if (list_empty(&cqm_rmid_free_lru)) - return INVALID_RMID; - - entry = list_first_entry(&cqm_rmid_free_lru, struct cqm_rmid_entry, list); - list_del(&entry->list); - - return entry->rmid; -} - -static void __put_rmid(u32 rmid) -{ - struct cqm_rmid_entry *entry; - - lockdep_assert_held(&cache_mutex); - - WARN_ON(!__rmid_valid(rmid)); - entry = __rmid_entry(rmid); - - entry->queue_time = jiffies; - entry->state = RMID_YOUNG; - - list_add_tail(&entry->list, &cqm_rmid_limbo_lru); -} - -static void cqm_cleanup(void) -{ - int i; - - if (!cqm_rmid_ptrs) - return; - - for (i = 0; i < cqm_max_rmid; i++) - kfree(cqm_rmid_ptrs[i]); - - kfree(cqm_rmid_ptrs); - cqm_rmid_ptrs = NULL; - cqm_enabled = false; -} - -static int intel_cqm_setup_rmid_cache(void) -{ - struct cqm_rmid_entry *entry; - unsigned int nr_rmids; - int r = 0; - - nr_rmids = cqm_max_rmid + 1; - cqm_rmid_ptrs = kzalloc(sizeof(struct cqm_rmid_entry *) * - nr_rmids, GFP_KERNEL); - if (!cqm_rmid_ptrs) - return -ENOMEM; - - for (; r <= cqm_max_rmid; r++) { - struct cqm_rmid_entry *entry; - - entry = kmalloc(sizeof(*entry), GFP_KERNEL); - if (!entry) - goto fail; - - INIT_LIST_HEAD(&entry->list); - entry->rmid = r; - cqm_rmid_ptrs[r] = entry; - - list_add_tail(&entry->list, &cqm_rmid_free_lru); - } - - /* - * RMID 0 is special and is always allocated. It's used for all - * tasks that are not monitored. - */ - entry = __rmid_entry(0); - list_del(&entry->list); - - mutex_lock(&cache_mutex); - intel_cqm_rotation_rmid = __get_rmid(); - mutex_unlock(&cache_mutex); - - return 0; - -fail: - cqm_cleanup(); - return -ENOMEM; -} - -/* - * Determine if @a and @b measure the same set of tasks. - * - * If @a and @b measure the same set of tasks then we want to share a - * single RMID. - */ -static bool __match_event(struct perf_event *a, struct perf_event *b) -{ - /* Per-cpu and task events don't mix */ - if ((a->attach_state & PERF_ATTACH_TASK) != - (b->attach_state & PERF_ATTACH_TASK)) - return false; - -#ifdef CONFIG_CGROUP_PERF - if (a->cgrp != b->cgrp) - return false; -#endif - - /* If not task event, we're machine wide */ - if (!(b->attach_state & PERF_ATTACH_TASK)) - return true; - - /* - * Events that target same task are placed into the same cache group. - * Mark it as a multi event group, so that we update ->count - * for every event rather than just the group leader later. - */ - if (a->hw.target == b->hw.target) { - b->hw.is_group_event = true; - return true; - } - - /* - * Are we an inherited event? - */ - if (b->parent == a) - return true; - - return false; -} - -#ifdef CONFIG_CGROUP_PERF -static inline struct perf_cgroup *event_to_cgroup(struct perf_event *event) -{ - if (event->attach_state & PERF_ATTACH_TASK) - return perf_cgroup_from_task(event->hw.target, event->ctx); - - return event->cgrp; -} -#endif - -/* - * Determine if @a's tasks intersect with @b's tasks - * - * There are combinations of events that we explicitly prohibit, - * - * PROHIBITS - * system-wide -> cgroup and task - * cgroup -> system-wide - * -> task in cgroup - * task -> system-wide - * -> task in cgroup - * - * Call this function before allocating an RMID. - */ -static bool __conflict_event(struct perf_event *a, struct perf_event *b) -{ -#ifdef CONFIG_CGROUP_PERF - /* - * We can have any number of cgroups but only one system-wide - * event at a time. - */ - if (a->cgrp && b->cgrp) { - struct perf_cgroup *ac = a->cgrp; - struct perf_cgroup *bc = b->cgrp; - - /* - * This condition should have been caught in - * __match_event() and we should be sharing an RMID. - */ - WARN_ON_ONCE(ac == bc); - - if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) || - cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup)) - return true; - - return false; - } - - if (a->cgrp || b->cgrp) { - struct perf_cgroup *ac, *bc; - - /* - * cgroup and system-wide events are mutually exclusive - */ - if ((a->cgrp && !(b->attach_state & PERF_ATTACH_TASK)) || - (b->cgrp && !(a->attach_state & PERF_ATTACH_TASK))) - return true; - - /* - * Ensure neither event is part of the other's cgroup - */ - ac = event_to_cgroup(a); - bc = event_to_cgroup(b); - if (ac == bc) - return true; - - /* - * Must have cgroup and non-intersecting task events. - */ - if (!ac || !bc) - return false; - - /* - * We have cgroup and task events, and the task belongs - * to a cgroup. Check for for overlap. - */ - if (cgroup_is_descendant(ac->css.cgroup, bc->css.cgroup) || - cgroup_is_descendant(bc->css.cgroup, ac->css.cgroup)) - return true; - - return false; - } -#endif - /* - * If one of them is not a task, same story as above with cgroups. - */ - if (!(a->attach_state & PERF_ATTACH_TASK) || - !(b->attach_state & PERF_ATTACH_TASK)) - return true; - - /* - * Must be non-overlapping. - */ - return false; -} - -struct rmid_read { - u32 rmid; - u32 evt_type; - atomic64_t value; -}; - -static void __intel_cqm_event_count(void *info); -static void init_mbm_sample(u32 rmid, u32 evt_type); -static void __intel_mbm_event_count(void *info); - -static bool is_cqm_event(int e) -{ - return (e == QOS_L3_OCCUP_EVENT_ID); -} - -static bool is_mbm_event(int e) -{ - return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID); -} - -static void cqm_mask_call(struct rmid_read *rr) -{ - if (is_mbm_event(rr->evt_type)) - on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count, rr, 1); - else - on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, rr, 1); -} - -/* - * Exchange the RMID of a group of events. - */ -static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid) -{ - struct perf_event *event; - struct list_head *head = &group->hw.cqm_group_entry; - u32 old_rmid = group->hw.cqm_rmid; - - lockdep_assert_held(&cache_mutex); - - /* - * If our RMID is being deallocated, perform a read now. - */ - if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) { - struct rmid_read rr = { - .rmid = old_rmid, - .evt_type = group->attr.config, - .value = ATOMIC64_INIT(0), - }; - - cqm_mask_call(&rr); - local64_set(&group->count, atomic64_read(&rr.value)); - } - - raw_spin_lock_irq(&cache_lock); - - group->hw.cqm_rmid = rmid; - list_for_each_entry(event, head, hw.cqm_group_entry) - event->hw.cqm_rmid = rmid; - - raw_spin_unlock_irq(&cache_lock); - - /* - * If the allocation is for mbm, init the mbm stats. - * Need to check if each event in the group is mbm event - * because there could be multiple type of events in the same group. - */ - if (__rmid_valid(rmid)) { - event = group; - if (is_mbm_event(event->attr.config)) - init_mbm_sample(rmid, event->attr.config); - - list_for_each_entry(event, head, hw.cqm_group_entry) { - if (is_mbm_event(event->attr.config)) - init_mbm_sample(rmid, event->attr.config); - } - } - - return old_rmid; -} - -/* - * If we fail to assign a new RMID for intel_cqm_rotation_rmid because - * cachelines are still tagged with RMIDs in limbo, we progressively - * increment the threshold until we find an RMID in limbo with <= - * __intel_cqm_threshold lines tagged. This is designed to mitigate the - * problem where cachelines tagged with an RMID are not steadily being - * evicted. - * - * On successful rotations we decrease the threshold back towards zero. - * - * __intel_cqm_max_threshold provides an upper bound on the threshold, - * and is measured in bytes because it's exposed to userland. - */ -static unsigned int __intel_cqm_threshold; -static unsigned int __intel_cqm_max_threshold; - -/* - * Test whether an RMID has a zero occupancy value on this cpu. - */ -static void intel_cqm_stable(void *arg) -{ - struct cqm_rmid_entry *entry; - - list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) { - if (entry->state != RMID_AVAILABLE) - break; - - if (__rmid_read(entry->rmid) > __intel_cqm_threshold) - entry->state = RMID_DIRTY; - } -} - -/* - * If we have group events waiting for an RMID that don't conflict with - * events already running, assign @rmid. - */ -static bool intel_cqm_sched_in_event(u32 rmid) -{ - struct perf_event *leader, *event; - - lockdep_assert_held(&cache_mutex); - - leader = list_first_entry(&cache_groups, struct perf_event, - hw.cqm_groups_entry); - event = leader; - - list_for_each_entry_continue(event, &cache_groups, - hw.cqm_groups_entry) { - if (__rmid_valid(event->hw.cqm_rmid)) - continue; - - if (__conflict_event(event, leader)) - continue; - - intel_cqm_xchg_rmid(event, rmid); - return true; - } - - return false; -} - -/* - * Initially use this constant for both the limbo queue time and the - * rotation timer interval, pmu::hrtimer_interval_ms. - * - * They don't need to be the same, but the two are related since if you - * rotate faster than you recycle RMIDs, you may run out of available - * RMIDs. - */ -#define RMID_DEFAULT_QUEUE_TIME 250 /* ms */ - -static unsigned int __rmid_queue_time_ms = RMID_DEFAULT_QUEUE_TIME; - -/* - * intel_cqm_rmid_stabilize - move RMIDs from limbo to free list - * @nr_available: number of freeable RMIDs on the limbo list - * - * Quiescent state; wait for all 'freed' RMIDs to become unused, i.e. no - * cachelines are tagged with those RMIDs. After this we can reuse them - * and know that the current set of active RMIDs is stable. - * - * Return %true or %false depending on whether stabilization needs to be - * reattempted. - * - * If we return %true then @nr_available is updated to indicate the - * number of RMIDs on the limbo list that have been queued for the - * minimum queue time (RMID_AVAILABLE), but whose data occupancy values - * are above __intel_cqm_threshold. - */ -static bool intel_cqm_rmid_stabilize(unsigned int *available) -{ - struct cqm_rmid_entry *entry, *tmp; - - lockdep_assert_held(&cache_mutex); - - *available = 0; - list_for_each_entry(entry, &cqm_rmid_limbo_lru, list) { - unsigned long min_queue_time; - unsigned long now = jiffies; - - /* - * We hold RMIDs placed into limbo for a minimum queue - * time. Before the minimum queue time has elapsed we do - * not recycle RMIDs. - * - * The reasoning is that until a sufficient time has - * passed since we stopped using an RMID, any RMID - * placed onto the limbo list will likely still have - * data tagged in the cache, which means we'll probably - * fail to recycle it anyway. - * - * We can save ourselves an expensive IPI by skipping - * any RMIDs that have not been queued for the minimum - * time. - */ - min_queue_time = entry->queue_time + - msecs_to_jiffies(__rmid_queue_time_ms); - - if (time_after(min_queue_time, now)) - break; - - entry->state = RMID_AVAILABLE; - (*available)++; - } - - /* - * Fast return if none of the RMIDs on the limbo list have been - * sitting on the queue for the minimum queue time. - */ - if (!*available) - return false; - - /* - * Test whether an RMID is free for each package. - */ - on_each_cpu_mask(&cqm_cpumask, intel_cqm_stable, NULL, true); - - list_for_each_entry_safe(entry, tmp, &cqm_rmid_limbo_lru, list) { - /* - * Exhausted all RMIDs that have waited min queue time. - */ - if (entry->state == RMID_YOUNG) - break; - - if (entry->state == RMID_DIRTY) - continue; - - list_del(&entry->list); /* remove from limbo */ - - /* - * The rotation RMID gets priority if it's - * currently invalid. In which case, skip adding - * the RMID to the the free lru. - */ - if (!__rmid_valid(intel_cqm_rotation_rmid)) { - intel_cqm_rotation_rmid = entry->rmid; - continue; - } - - /* - * If we have groups waiting for RMIDs, hand - * them one now provided they don't conflict. - */ - if (intel_cqm_sched_in_event(entry->rmid)) - continue; - - /* - * Otherwise place it onto the free list. - */ - list_add_tail(&entry->list, &cqm_rmid_free_lru); - } - - - return __rmid_valid(intel_cqm_rotation_rmid); -} - -/* - * Pick a victim group and move it to the tail of the group list. - * @next: The first group without an RMID - */ -static void __intel_cqm_pick_and_rotate(struct perf_event *next) -{ - struct perf_event *rotor; - u32 rmid; - - lockdep_assert_held(&cache_mutex); - - rotor = list_first_entry(&cache_groups, struct perf_event, - hw.cqm_groups_entry); - - /* - * The group at the front of the list should always have a valid - * RMID. If it doesn't then no groups have RMIDs assigned and we - * don't need to rotate the list. - */ - if (next == rotor) - return; - - rmid = intel_cqm_xchg_rmid(rotor, INVALID_RMID); - __put_rmid(rmid); - - list_rotate_left(&cache_groups); -} - -/* - * Deallocate the RMIDs from any events that conflict with @event, and - * place them on the back of the group list. - */ -static void intel_cqm_sched_out_conflicting_events(struct perf_event *event) -{ - struct perf_event *group, *g; - u32 rmid; - - lockdep_assert_held(&cache_mutex); - - list_for_each_entry_safe(group, g, &cache_groups, hw.cqm_groups_entry) { - if (group == event) - continue; - - rmid = group->hw.cqm_rmid; - - /* - * Skip events that don't have a valid RMID. - */ - if (!__rmid_valid(rmid)) - continue; - - /* - * No conflict? No problem! Leave the event alone. - */ - if (!__conflict_event(group, event)) - continue; - - intel_cqm_xchg_rmid(group, INVALID_RMID); - __put_rmid(rmid); - } -} - -/* - * Attempt to rotate the groups and assign new RMIDs. - * - * We rotate for two reasons, - * 1. To handle the scheduling of conflicting events - * 2. To recycle RMIDs - * - * Rotating RMIDs is complicated because the hardware doesn't give us - * any clues. - * - * There's problems with the hardware interface; when you change the - * task:RMID map cachelines retain their 'old' tags, giving a skewed - * picture. In order to work around this, we must always keep one free - * RMID - intel_cqm_rotation_rmid. - * - * Rotation works by taking away an RMID from a group (the old RMID), - * and assigning the free RMID to another group (the new RMID). We must - * then wait for the old RMID to not be used (no cachelines tagged). - * This ensure that all cachelines are tagged with 'active' RMIDs. At - * this point we can start reading values for the new RMID and treat the - * old RMID as the free RMID for the next rotation. - * - * Return %true or %false depending on whether we did any rotating. - */ -static bool __intel_cqm_rmid_rotate(void) -{ - struct perf_event *group, *start = NULL; - unsigned int threshold_limit; - unsigned int nr_needed = 0; - unsigned int nr_available; - bool rotated = false; - - mutex_lock(&cache_mutex); - -again: - /* - * Fast path through this function if there are no groups and no - * RMIDs that need cleaning. - */ - if (list_empty(&cache_groups) && list_empty(&cqm_rmid_limbo_lru)) - goto out; - - list_for_each_entry(group, &cache_groups, hw.cqm_groups_entry) { - if (!__rmid_valid(group->hw.cqm_rmid)) { - if (!start) - start = group; - nr_needed++; - } - } - - /* - * We have some event groups, but they all have RMIDs assigned - * and no RMIDs need cleaning. - */ - if (!nr_needed && list_empty(&cqm_rmid_limbo_lru)) - goto out; - - if (!nr_needed) - goto stabilize; - - /* - * We have more event groups without RMIDs than available RMIDs, - * or we have event groups that conflict with the ones currently - * scheduled. - * - * We force deallocate the rmid of the group at the head of - * cache_groups. The first event group without an RMID then gets - * assigned intel_cqm_rotation_rmid. This ensures we always make - * forward progress. - * - * Rotate the cache_groups list so the previous head is now the - * tail. - */ - __intel_cqm_pick_and_rotate(start); - - /* - * If the rotation is going to succeed, reduce the threshold so - * that we don't needlessly reuse dirty RMIDs. - */ - if (__rmid_valid(intel_cqm_rotation_rmid)) { - intel_cqm_xchg_rmid(start, intel_cqm_rotation_rmid); - intel_cqm_rotation_rmid = __get_rmid(); - - intel_cqm_sched_out_conflicting_events(start); - - if (__intel_cqm_threshold) - __intel_cqm_threshold--; - } - - rotated = true; - -stabilize: - /* - * We now need to stablize the RMID we freed above (if any) to - * ensure that the next time we rotate we have an RMID with zero - * occupancy value. - * - * Alternatively, if we didn't need to perform any rotation, - * we'll have a bunch of RMIDs in limbo that need stabilizing. - */ - threshold_limit = __intel_cqm_max_threshold / cqm_l3_scale; - - while (intel_cqm_rmid_stabilize(&nr_available) && - __intel_cqm_threshold < threshold_limit) { - unsigned int steal_limit; - - /* - * Don't spin if nobody is actively waiting for an RMID, - * the rotation worker will be kicked as soon as an - * event needs an RMID anyway. - */ - if (!nr_needed) - break; - - /* Allow max 25% of RMIDs to be in limbo. */ - steal_limit = (cqm_max_rmid + 1) / 4; - - /* - * We failed to stabilize any RMIDs so our rotation - * logic is now stuck. In order to make forward progress - * we have a few options: - * - * 1. rotate ("steal") another RMID - * 2. increase the threshold - * 3. do nothing - * - * We do both of 1. and 2. until we hit the steal limit. - * - * The steal limit prevents all RMIDs ending up on the - * limbo list. This can happen if every RMID has a - * non-zero occupancy above threshold_limit, and the - * occupancy values aren't dropping fast enough. - * - * Note that there is prioritisation at work here - we'd - * rather increase the number of RMIDs on the limbo list - * than increase the threshold, because increasing the - * threshold skews the event data (because we reuse - * dirty RMIDs) - threshold bumps are a last resort. - */ - if (nr_available < steal_limit) - goto again; - - __intel_cqm_threshold++; - } - -out: - mutex_unlock(&cache_mutex); - return rotated; -} - -static void intel_cqm_rmid_rotate(struct work_struct *work); - -static DECLARE_DELAYED_WORK(intel_cqm_rmid_work, intel_cqm_rmid_rotate); - -static struct pmu intel_cqm_pmu; - -static void intel_cqm_rmid_rotate(struct work_struct *work) -{ - unsigned long delay; - - __intel_cqm_rmid_rotate(); - - delay = msecs_to_jiffies(intel_cqm_pmu.hrtimer_interval_ms); - schedule_delayed_work(&intel_cqm_rmid_work, delay); -} - -static u64 update_sample(unsigned int rmid, u32 evt_type, int first) -{ - struct sample *mbm_current; - u32 vrmid = rmid_2_index(rmid); - u64 val, bytes, shift; - u32 eventid; - - if (evt_type == QOS_MBM_LOCAL_EVENT_ID) { - mbm_current = &mbm_local[vrmid]; - eventid = QOS_MBM_LOCAL_EVENT_ID; - } else { - mbm_current = &mbm_total[vrmid]; - eventid = QOS_MBM_TOTAL_EVENT_ID; - } - - wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); - rdmsrl(MSR_IA32_QM_CTR, val); - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - return mbm_current->total_bytes; - - if (first) { - mbm_current->prev_msr = val; - mbm_current->total_bytes = 0; - return mbm_current->total_bytes; - } - - /* - * The h/w guarantees that counters will not overflow - * so long as we poll them at least once per second. - */ - shift = 64 - MBM_CNTR_WIDTH; - bytes = (val << shift) - (mbm_current->prev_msr << shift); - bytes >>= shift; - - bytes *= cqm_l3_scale; - - mbm_current->total_bytes += bytes; - mbm_current->prev_msr = val; - - return mbm_current->total_bytes; -} - -static u64 rmid_read_mbm(unsigned int rmid, u32 evt_type) -{ - return update_sample(rmid, evt_type, 0); -} - -static void __intel_mbm_event_init(void *info) -{ - struct rmid_read *rr = info; - - update_sample(rr->rmid, rr->evt_type, 1); -} - -static void init_mbm_sample(u32 rmid, u32 evt_type) -{ - struct rmid_read rr = { - .rmid = rmid, - .evt_type = evt_type, - .value = ATOMIC64_INIT(0), - }; - - /* on each socket, init sample */ - on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_init, &rr, 1); -} - -/* - * Find a group and setup RMID. - * - * If we're part of a group, we use the group's RMID. - */ -static void intel_cqm_setup_event(struct perf_event *event, - struct perf_event **group) -{ - struct perf_event *iter; - bool conflict = false; - u32 rmid; - - event->hw.is_group_event = false; - list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { - rmid = iter->hw.cqm_rmid; - - if (__match_event(iter, event)) { - /* All tasks in a group share an RMID */ - event->hw.cqm_rmid = rmid; - *group = iter; - if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) - init_mbm_sample(rmid, event->attr.config); - return; - } - - /* - * We only care about conflicts for events that are - * actually scheduled in (and hence have a valid RMID). - */ - if (__conflict_event(iter, event) && __rmid_valid(rmid)) - conflict = true; - } - - if (conflict) - rmid = INVALID_RMID; - else - rmid = __get_rmid(); - - if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) - init_mbm_sample(rmid, event->attr.config); - - event->hw.cqm_rmid = rmid; -} - -static void intel_cqm_event_read(struct perf_event *event) -{ - unsigned long flags; - u32 rmid; - u64 val; - - /* - * Task events are handled by intel_cqm_event_count(). - */ - if (event->cpu == -1) - return; - - raw_spin_lock_irqsave(&cache_lock, flags); - rmid = event->hw.cqm_rmid; - - if (!__rmid_valid(rmid)) - goto out; - - if (is_mbm_event(event->attr.config)) - val = rmid_read_mbm(rmid, event->attr.config); - else - val = __rmid_read(rmid); - - /* - * Ignore this reading on error states and do not update the value. - */ - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - goto out; - - local64_set(&event->count, val); -out: - raw_spin_unlock_irqrestore(&cache_lock, flags); -} - -static void __intel_cqm_event_count(void *info) -{ - struct rmid_read *rr = info; - u64 val; - - val = __rmid_read(rr->rmid); - - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - return; - - atomic64_add(val, &rr->value); -} - -static inline bool cqm_group_leader(struct perf_event *event) -{ - return !list_empty(&event->hw.cqm_groups_entry); -} - -static void __intel_mbm_event_count(void *info) -{ - struct rmid_read *rr = info; - u64 val; - - val = rmid_read_mbm(rr->rmid, rr->evt_type); - if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) - return; - atomic64_add(val, &rr->value); -} - -static enum hrtimer_restart mbm_hrtimer_handle(struct hrtimer *hrtimer) -{ - struct perf_event *iter, *iter1; - int ret = HRTIMER_RESTART; - struct list_head *head; - unsigned long flags; - u32 grp_rmid; - - /* - * Need to cache_lock as the timer Event Select MSR reads - * can race with the mbm/cqm count() and mbm_init() reads. - */ - raw_spin_lock_irqsave(&cache_lock, flags); - - if (list_empty(&cache_groups)) { - ret = HRTIMER_NORESTART; - goto out; - } - - list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { - grp_rmid = iter->hw.cqm_rmid; - if (!__rmid_valid(grp_rmid)) - continue; - if (is_mbm_event(iter->attr.config)) - update_sample(grp_rmid, iter->attr.config, 0); - - head = &iter->hw.cqm_group_entry; - if (list_empty(head)) - continue; - list_for_each_entry(iter1, head, hw.cqm_group_entry) { - if (!iter1->hw.is_group_event) - break; - if (is_mbm_event(iter1->attr.config)) - update_sample(iter1->hw.cqm_rmid, - iter1->attr.config, 0); - } - } - - hrtimer_forward_now(hrtimer, ms_to_ktime(MBM_CTR_OVERFLOW_TIME)); -out: - raw_spin_unlock_irqrestore(&cache_lock, flags); - - return ret; -} - -static void __mbm_start_timer(void *info) -{ - hrtimer_start(&mbm_timers[pkg_id], ms_to_ktime(MBM_CTR_OVERFLOW_TIME), - HRTIMER_MODE_REL_PINNED); -} - -static void __mbm_stop_timer(void *info) -{ - hrtimer_cancel(&mbm_timers[pkg_id]); -} - -static void mbm_start_timers(void) -{ - on_each_cpu_mask(&cqm_cpumask, __mbm_start_timer, NULL, 1); -} - -static void mbm_stop_timers(void) -{ - on_each_cpu_mask(&cqm_cpumask, __mbm_stop_timer, NULL, 1); -} - -static void mbm_hrtimer_init(void) -{ - struct hrtimer *hr; - int i; - - for (i = 0; i < mbm_socket_max; i++) { - hr = &mbm_timers[i]; - hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hr->function = mbm_hrtimer_handle; - } -} - -static u64 intel_cqm_event_count(struct perf_event *event) -{ - unsigned long flags; - struct rmid_read rr = { - .evt_type = event->attr.config, - .value = ATOMIC64_INIT(0), - }; - - /* - * We only need to worry about task events. System-wide events - * are handled like usual, i.e. entirely with - * intel_cqm_event_read(). - */ - if (event->cpu != -1) - return __perf_event_count(event); - - /* - * Only the group leader gets to report values except in case of - * multiple events in the same group, we still need to read the - * other events.This stops us - * reporting duplicate values to userspace, and gives us a clear - * rule for which task gets to report the values. - * - * Note that it is impossible to attribute these values to - * specific packages - we forfeit that ability when we create - * task events. - */ - if (!cqm_group_leader(event) && !event->hw.is_group_event) - return 0; - - /* - * Getting up-to-date values requires an SMP IPI which is not - * possible if we're being called in interrupt context. Return - * the cached values instead. - */ - if (unlikely(in_interrupt())) - goto out; - - /* - * Notice that we don't perform the reading of an RMID - * atomically, because we can't hold a spin lock across the - * IPIs. - * - * Speculatively perform the read, since @event might be - * assigned a different (possibly invalid) RMID while we're - * busying performing the IPI calls. It's therefore necessary to - * check @event's RMID afterwards, and if it has changed, - * discard the result of the read. - */ - rr.rmid = ACCESS_ONCE(event->hw.cqm_rmid); - - if (!__rmid_valid(rr.rmid)) - goto out; - - cqm_mask_call(&rr); - - raw_spin_lock_irqsave(&cache_lock, flags); - if (event->hw.cqm_rmid == rr.rmid) - local64_set(&event->count, atomic64_read(&rr.value)); - raw_spin_unlock_irqrestore(&cache_lock, flags); -out: - return __perf_event_count(event); -} - -static void intel_cqm_event_start(struct perf_event *event, int mode) -{ - struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - u32 rmid = event->hw.cqm_rmid; - - if (!(event->hw.cqm_state & PERF_HES_STOPPED)) - return; - - event->hw.cqm_state &= ~PERF_HES_STOPPED; - - if (state->rmid_usecnt++) { - if (!WARN_ON_ONCE(state->rmid != rmid)) - return; - } else { - WARN_ON_ONCE(state->rmid); - } - - state->rmid = rmid; - wrmsr(MSR_IA32_PQR_ASSOC, rmid, state->closid); -} - -static void intel_cqm_event_stop(struct perf_event *event, int mode) -{ - struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - - if (event->hw.cqm_state & PERF_HES_STOPPED) - return; - - event->hw.cqm_state |= PERF_HES_STOPPED; - - intel_cqm_event_read(event); - - if (!--state->rmid_usecnt) { - state->rmid = 0; - wrmsr(MSR_IA32_PQR_ASSOC, 0, state->closid); - } else { - WARN_ON_ONCE(!state->rmid); - } -} - -static int intel_cqm_event_add(struct perf_event *event, int mode) -{ - unsigned long flags; - u32 rmid; - - raw_spin_lock_irqsave(&cache_lock, flags); - - event->hw.cqm_state = PERF_HES_STOPPED; - rmid = event->hw.cqm_rmid; - - if (__rmid_valid(rmid) && (mode & PERF_EF_START)) - intel_cqm_event_start(event, mode); - - raw_spin_unlock_irqrestore(&cache_lock, flags); - - return 0; -} - -static void intel_cqm_event_destroy(struct perf_event *event) -{ - struct perf_event *group_other = NULL; - unsigned long flags; - - mutex_lock(&cache_mutex); - /* - * Hold the cache_lock as mbm timer handlers could be - * scanning the list of events. - */ - raw_spin_lock_irqsave(&cache_lock, flags); - - /* - * If there's another event in this group... - */ - if (!list_empty(&event->hw.cqm_group_entry)) { - group_other = list_first_entry(&event->hw.cqm_group_entry, - struct perf_event, - hw.cqm_group_entry); - list_del(&event->hw.cqm_group_entry); - } - - /* - * And we're the group leader.. - */ - if (cqm_group_leader(event)) { - /* - * If there was a group_other, make that leader, otherwise - * destroy the group and return the RMID. - */ - if (group_other) { - list_replace(&event->hw.cqm_groups_entry, - &group_other->hw.cqm_groups_entry); - } else { - u32 rmid = event->hw.cqm_rmid; - - if (__rmid_valid(rmid)) - __put_rmid(rmid); - list_del(&event->hw.cqm_groups_entry); - } - } - - raw_spin_unlock_irqrestore(&cache_lock, flags); - - /* - * Stop the mbm overflow timers when the last event is destroyed. - */ - if (mbm_enabled && list_empty(&cache_groups)) - mbm_stop_timers(); - - mutex_unlock(&cache_mutex); -} - -static int intel_cqm_event_init(struct perf_event *event) -{ - struct perf_event *group = NULL; - bool rotate = false; - unsigned long flags; - - if (event->attr.type != intel_cqm_pmu.type) - return -ENOENT; - - if ((event->attr.config < QOS_L3_OCCUP_EVENT_ID) || - (event->attr.config > QOS_MBM_LOCAL_EVENT_ID)) - return -EINVAL; - - if ((is_cqm_event(event->attr.config) && !cqm_enabled) || - (is_mbm_event(event->attr.config) && !mbm_enabled)) - return -EINVAL; - - /* unsupported modes and filters */ - if (event->attr.exclude_user || - event->attr.exclude_kernel || - event->attr.exclude_hv || - event->attr.exclude_idle || - event->attr.exclude_host || - event->attr.exclude_guest || - event->attr.sample_period) /* no sampling */ - return -EINVAL; - - INIT_LIST_HEAD(&event->hw.cqm_group_entry); - INIT_LIST_HEAD(&event->hw.cqm_groups_entry); - - event->destroy = intel_cqm_event_destroy; - - mutex_lock(&cache_mutex); - - /* - * Start the mbm overflow timers when the first event is created. - */ - if (mbm_enabled && list_empty(&cache_groups)) - mbm_start_timers(); - - /* Will also set rmid */ - intel_cqm_setup_event(event, &group); - - /* - * Hold the cache_lock as mbm timer handlers be - * scanning the list of events. - */ - raw_spin_lock_irqsave(&cache_lock, flags); - - if (group) { - list_add_tail(&event->hw.cqm_group_entry, - &group->hw.cqm_group_entry); - } else { - list_add_tail(&event->hw.cqm_groups_entry, - &cache_groups); - - /* - * All RMIDs are either in use or have recently been - * used. Kick the rotation worker to clean/free some. - * - * We only do this for the group leader, rather than for - * every event in a group to save on needless work. - */ - if (!__rmid_valid(event->hw.cqm_rmid)) - rotate = true; - } - - raw_spin_unlock_irqrestore(&cache_lock, flags); - mutex_unlock(&cache_mutex); - - if (rotate) - schedule_delayed_work(&intel_cqm_rmid_work, 0); - - return 0; -} - -EVENT_ATTR_STR(llc_occupancy, intel_cqm_llc, "event=0x01"); -EVENT_ATTR_STR(llc_occupancy.per-pkg, intel_cqm_llc_pkg, "1"); -EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes"); -EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL); -EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1"); - -EVENT_ATTR_STR(total_bytes, intel_cqm_total_bytes, "event=0x02"); -EVENT_ATTR_STR(total_bytes.per-pkg, intel_cqm_total_bytes_pkg, "1"); -EVENT_ATTR_STR(total_bytes.unit, intel_cqm_total_bytes_unit, "MB"); -EVENT_ATTR_STR(total_bytes.scale, intel_cqm_total_bytes_scale, "1e-6"); - -EVENT_ATTR_STR(local_bytes, intel_cqm_local_bytes, "event=0x03"); -EVENT_ATTR_STR(local_bytes.per-pkg, intel_cqm_local_bytes_pkg, "1"); -EVENT_ATTR_STR(local_bytes.unit, intel_cqm_local_bytes_unit, "MB"); -EVENT_ATTR_STR(local_bytes.scale, intel_cqm_local_bytes_scale, "1e-6"); - -static struct attribute *intel_cqm_events_attr[] = { - EVENT_PTR(intel_cqm_llc), - EVENT_PTR(intel_cqm_llc_pkg), - EVENT_PTR(intel_cqm_llc_unit), - EVENT_PTR(intel_cqm_llc_scale), - EVENT_PTR(intel_cqm_llc_snapshot), - NULL, -}; - -static struct attribute *intel_mbm_events_attr[] = { - EVENT_PTR(intel_cqm_total_bytes), - EVENT_PTR(intel_cqm_local_bytes), - EVENT_PTR(intel_cqm_total_bytes_pkg), - EVENT_PTR(intel_cqm_local_bytes_pkg), - EVENT_PTR(intel_cqm_total_bytes_unit), - EVENT_PTR(intel_cqm_local_bytes_unit), - EVENT_PTR(intel_cqm_total_bytes_scale), - EVENT_PTR(intel_cqm_local_bytes_scale), - NULL, -}; - -static struct attribute *intel_cmt_mbm_events_attr[] = { - EVENT_PTR(intel_cqm_llc), - EVENT_PTR(intel_cqm_total_bytes), - EVENT_PTR(intel_cqm_local_bytes), - EVENT_PTR(intel_cqm_llc_pkg), - EVENT_PTR(intel_cqm_total_bytes_pkg), - EVENT_PTR(intel_cqm_local_bytes_pkg), - EVENT_PTR(intel_cqm_llc_unit), - EVENT_PTR(intel_cqm_total_bytes_unit), - EVENT_PTR(intel_cqm_local_bytes_unit), - EVENT_PTR(intel_cqm_llc_scale), - EVENT_PTR(intel_cqm_total_bytes_scale), - EVENT_PTR(intel_cqm_local_bytes_scale), - EVENT_PTR(intel_cqm_llc_snapshot), - NULL, -}; - -static struct attribute_group intel_cqm_events_group = { - .name = "events", - .attrs = NULL, -}; - -PMU_FORMAT_ATTR(event, "config:0-7"); -static struct attribute *intel_cqm_formats_attr[] = { - &format_attr_event.attr, - NULL, -}; - -static struct attribute_group intel_cqm_format_group = { - .name = "format", - .attrs = intel_cqm_formats_attr, -}; - -static ssize_t -max_recycle_threshold_show(struct device *dev, struct device_attribute *attr, - char *page) -{ - ssize_t rv; - - mutex_lock(&cache_mutex); - rv = snprintf(page, PAGE_SIZE-1, "%u\n", __intel_cqm_max_threshold); - mutex_unlock(&cache_mutex); - - return rv; -} - -static ssize_t -max_recycle_threshold_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int bytes, cachelines; - int ret; - - ret = kstrtouint(buf, 0, &bytes); - if (ret) - return ret; - - mutex_lock(&cache_mutex); - - __intel_cqm_max_threshold = bytes; - cachelines = bytes / cqm_l3_scale; - - /* - * The new maximum takes effect immediately. - */ - if (__intel_cqm_threshold > cachelines) - __intel_cqm_threshold = cachelines; - - mutex_unlock(&cache_mutex); - - return count; -} - -static DEVICE_ATTR_RW(max_recycle_threshold); - -static struct attribute *intel_cqm_attrs[] = { - &dev_attr_max_recycle_threshold.attr, - NULL, -}; - -static const struct attribute_group intel_cqm_group = { - .attrs = intel_cqm_attrs, -}; - -static const struct attribute_group *intel_cqm_attr_groups[] = { - &intel_cqm_events_group, - &intel_cqm_format_group, - &intel_cqm_group, - NULL, -}; - -static struct pmu intel_cqm_pmu = { - .hrtimer_interval_ms = RMID_DEFAULT_QUEUE_TIME, - .attr_groups = intel_cqm_attr_groups, - .task_ctx_nr = perf_sw_context, - .event_init = intel_cqm_event_init, - .add = intel_cqm_event_add, - .del = intel_cqm_event_stop, - .start = intel_cqm_event_start, - .stop = intel_cqm_event_stop, - .read = intel_cqm_event_read, - .count = intel_cqm_event_count, -}; - -static inline void cqm_pick_event_reader(int cpu) -{ - int reader; - - /* First online cpu in package becomes the reader */ - reader = cpumask_any_and(&cqm_cpumask, topology_core_cpumask(cpu)); - if (reader >= nr_cpu_ids) - cpumask_set_cpu(cpu, &cqm_cpumask); -} - -static int intel_cqm_cpu_starting(unsigned int cpu) -{ - struct intel_pqr_state *state = &per_cpu(pqr_state, cpu); - struct cpuinfo_x86 *c = &cpu_data(cpu); - - state->rmid = 0; - state->closid = 0; - state->rmid_usecnt = 0; - - WARN_ON(c->x86_cache_max_rmid != cqm_max_rmid); - WARN_ON(c->x86_cache_occ_scale != cqm_l3_scale); - - cqm_pick_event_reader(cpu); - return 0; -} - -static int intel_cqm_cpu_exit(unsigned int cpu) -{ - int target; - - /* Is @cpu the current cqm reader for this package ? */ - if (!cpumask_test_and_clear_cpu(cpu, &cqm_cpumask)) - return 0; - - /* Find another online reader in this package */ - target = cpumask_any_but(topology_core_cpumask(cpu), cpu); - - if (target < nr_cpu_ids) - cpumask_set_cpu(target, &cqm_cpumask); - - return 0; -} - -static const struct x86_cpu_id intel_cqm_match[] = { - { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_OCCUP_LLC }, - {} -}; - -static void mbm_cleanup(void) -{ - if (!mbm_enabled) - return; - - kfree(mbm_local); - kfree(mbm_total); - mbm_enabled = false; -} - -static const struct x86_cpu_id intel_mbm_local_match[] = { - { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_LOCAL }, - {} -}; - -static const struct x86_cpu_id intel_mbm_total_match[] = { - { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_TOTAL }, - {} -}; - -static int intel_mbm_init(void) -{ - int ret = 0, array_size, maxid = cqm_max_rmid + 1; - - mbm_socket_max = topology_max_packages(); - array_size = sizeof(struct sample) * maxid * mbm_socket_max; - mbm_local = kmalloc(array_size, GFP_KERNEL); - if (!mbm_local) - return -ENOMEM; - - mbm_total = kmalloc(array_size, GFP_KERNEL); - if (!mbm_total) { - ret = -ENOMEM; - goto out; - } - - array_size = sizeof(struct hrtimer) * mbm_socket_max; - mbm_timers = kmalloc(array_size, GFP_KERNEL); - if (!mbm_timers) { - ret = -ENOMEM; - goto out; - } - mbm_hrtimer_init(); - -out: - if (ret) - mbm_cleanup(); - - return ret; -} - -static int __init intel_cqm_init(void) -{ - char *str = NULL, scale[20]; - int cpu, ret; - - if (x86_match_cpu(intel_cqm_match)) - cqm_enabled = true; - - if (x86_match_cpu(intel_mbm_local_match) && - x86_match_cpu(intel_mbm_total_match)) - mbm_enabled = true; - - if (!cqm_enabled && !mbm_enabled) - return -ENODEV; - - cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale; - - /* - * It's possible that not all resources support the same number - * of RMIDs. Instead of making scheduling much more complicated - * (where we have to match a task's RMID to a cpu that supports - * that many RMIDs) just find the minimum RMIDs supported across - * all cpus. - * - * Also, check that the scales match on all cpus. - */ - cpus_read_lock(); - for_each_online_cpu(cpu) { - struct cpuinfo_x86 *c = &cpu_data(cpu); - - if (c->x86_cache_max_rmid < cqm_max_rmid) - cqm_max_rmid = c->x86_cache_max_rmid; - - if (c->x86_cache_occ_scale != cqm_l3_scale) { - pr_err("Multiple LLC scale values, disabling\n"); - ret = -EINVAL; - goto out; - } - } - - /* - * A reasonable upper limit on the max threshold is the number - * of lines tagged per RMID if all RMIDs have the same number of - * lines tagged in the LLC. - * - * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC. - */ - __intel_cqm_max_threshold = - boot_cpu_data.x86_cache_size * 1024 / (cqm_max_rmid + 1); - - snprintf(scale, sizeof(scale), "%u", cqm_l3_scale); - str = kstrdup(scale, GFP_KERNEL); - if (!str) { - ret = -ENOMEM; - goto out; - } - - event_attr_intel_cqm_llc_scale.event_str = str; - - ret = intel_cqm_setup_rmid_cache(); - if (ret) - goto out; - - if (mbm_enabled) - ret = intel_mbm_init(); - if (ret && !cqm_enabled) - goto out; - - if (cqm_enabled && mbm_enabled) - intel_cqm_events_group.attrs = intel_cmt_mbm_events_attr; - else if (!cqm_enabled && mbm_enabled) - intel_cqm_events_group.attrs = intel_mbm_events_attr; - else if (cqm_enabled && !mbm_enabled) - intel_cqm_events_group.attrs = intel_cqm_events_attr; - - ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1); - if (ret) { - pr_err("Intel CQM perf registration failed: %d\n", ret); - goto out; - } - - if (cqm_enabled) - pr_info("Intel CQM monitoring enabled\n"); - if (mbm_enabled) - pr_info("Intel MBM enabled\n"); - - /* - * Setup the hot cpu notifier once we are sure cqm - * is enabled to avoid notifier leak. - */ - cpuhp_setup_state_cpuslocked(CPUHP_AP_PERF_X86_CQM_STARTING, - "perf/x86/cqm:starting", - intel_cqm_cpu_starting, NULL); - cpuhp_setup_state_cpuslocked(CPUHP_AP_PERF_X86_CQM_ONLINE, - "perf/x86/cqm:online", - NULL, intel_cqm_cpu_exit); -out: - cpus_read_unlock(); - - if (ret) { - kfree(str); - cqm_cleanup(); - mbm_cleanup(); - } - - return ret; -} -device_initcall(intel_cqm_init); diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c index 4cf100ff2a37..72db0664a53d 100644 --- a/arch/x86/events/intel/cstate.c +++ b/arch/x86/events/intel/cstate.c @@ -552,6 +552,7 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_MOBILE, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_DESKTOP, snb_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_SKYLAKE_X, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_MOBILE, snb_cstates), X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_DESKTOP, snb_cstates), @@ -560,6 +561,9 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { X86_CSTATES_MODEL(INTEL_FAM6_XEON_PHI_KNM, knl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_DENVERTON, glm_cstates), + + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GEMINI_LAKE, glm_cstates), { }, }; MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index a322fed5f8ed..3674a4b6f8bd 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -49,34 +50,47 @@ union intel_x86_pebs_dse { */ #define P(a, b) PERF_MEM_S(a, b) #define OP_LH (P(OP, LOAD) | P(LVL, HIT)) +#define LEVEL(x) P(LVLNUM, x) +#define REM P(REMOTE, REMOTE) #define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS)) /* Version for Sandy Bridge and later */ static u64 pebs_data_source[] = { - P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */ - OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */ - OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */ - OP_LH | P(LVL, L2) | P(SNOOP, NONE), /* 0x03: L2 hit */ - OP_LH | P(LVL, L3) | P(SNOOP, NONE), /* 0x04: L3 hit */ - OP_LH | P(LVL, L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */ - OP_LH | P(LVL, L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */ - OP_LH | P(LVL, L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */ - OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */ - OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/ - OP_LH | P(LVL, LOC_RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */ - OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */ - OP_LH | P(LVL, LOC_RAM) | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */ - OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */ - OP_LH | P(LVL, IO) | P(SNOOP, NONE), /* 0x0e: I/O */ - OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */ + P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA),/* 0x00:ukn L3 */ + OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x01: L1 local */ + OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */ + OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* 0x03: L2 hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* 0x04: L3 hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */ + OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */ + OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */ + OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/ + OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */ + OP_LH | P(LVL, REM_RAM1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */ + OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | SNOOP_NONE_MISS, /* 0x0c: L3 miss, excl */ + OP_LH | P(LVL, REM_RAM1) | LEVEL(RAM) | REM | SNOOP_NONE_MISS, /* 0x0d: L3 miss, excl */ + OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0e: I/O */ + OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0f: uncached */ }; /* Patch up minor differences in the bits */ void __init intel_pmu_pebs_data_source_nhm(void) { - pebs_data_source[0x05] = OP_LH | P(LVL, L3) | P(SNOOP, HIT); - pebs_data_source[0x06] = OP_LH | P(LVL, L3) | P(SNOOP, HITM); - pebs_data_source[0x07] = OP_LH | P(LVL, L3) | P(SNOOP, HITM); + pebs_data_source[0x05] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT); + pebs_data_source[0x06] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); + pebs_data_source[0x07] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); +} + +void __init intel_pmu_pebs_data_source_skl(bool pmem) +{ + u64 pmem_or_l4 = pmem ? LEVEL(PMEM) : LEVEL(L4); + + pebs_data_source[0x08] = OP_LH | pmem_or_l4 | P(SNOOP, HIT); + pebs_data_source[0x09] = OP_LH | pmem_or_l4 | REM | P(SNOOP, HIT); + pebs_data_source[0x0b] = OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE); + pebs_data_source[0x0c] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOPX, FWD); + pebs_data_source[0x0d] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOP, HITM); } static u64 precise_store_data(u64 status) @@ -149,8 +163,6 @@ static u64 load_latency_data(u64 status) { union intel_x86_pebs_dse dse; u64 val; - int model = boot_cpu_data.x86_model; - int fam = boot_cpu_data.x86; dse.val = status; @@ -162,8 +174,7 @@ static u64 load_latency_data(u64 status) /* * Nehalem models do not support TLB, Lock infos */ - if (fam == 0x6 && (model == 26 || model == 30 - || model == 31 || model == 46)) { + if (x86_pmu.pebs_no_tlb) { val |= P(TLB, NA) | P(LOCK, NA); return val; } @@ -1175,7 +1186,7 @@ static void setup_pebs_sample_data(struct perf_event *event, else regs->flags &= ~PERF_EFLAGS_EXACT; - if ((sample_type & PERF_SAMPLE_ADDR) && + if ((sample_type & (PERF_SAMPLE_ADDR | PERF_SAMPLE_PHYS_ADDR)) && x86_pmu.intel_cap.pebs_format >= 1) data->addr = pebs->dla; diff --git a/arch/x86/events/intel/knc.c b/arch/x86/events/intel/knc.c index 548d5f774b07..618001c208e8 100644 --- a/arch/x86/events/intel/knc.c +++ b/arch/x86/events/intel/knc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Driver for Intel Xeon Phi "Knights Corner" PMU */ #include diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 955457a30197..ae64d0b69729 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -109,6 +110,9 @@ enum { X86_BR_ZERO_CALL = 1 << 15,/* zero length call */ X86_BR_CALL_STACK = 1 << 16,/* call stack */ X86_BR_IND_JMP = 1 << 17,/* indirect jump */ + + X86_BR_TYPE_SAVE = 1 << 18,/* indicate to save branch type */ + }; #define X86_BR_PLM (X86_BR_USER | X86_BR_KERNEL) @@ -514,6 +518,7 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc) cpuc->lbr_entries[i].in_tx = 0; cpuc->lbr_entries[i].abort = 0; cpuc->lbr_entries[i].cycles = 0; + cpuc->lbr_entries[i].type = 0; cpuc->lbr_entries[i].reserved = 0; } cpuc->lbr_stack.nr = i; @@ -600,6 +605,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) cpuc->lbr_entries[out].in_tx = in_tx; cpuc->lbr_entries[out].abort = abort; cpuc->lbr_entries[out].cycles = cycles; + cpuc->lbr_entries[out].type = 0; cpuc->lbr_entries[out].reserved = 0; out++; } @@ -677,6 +683,10 @@ static int intel_pmu_setup_sw_lbr_filter(struct perf_event *event) if (br_type & PERF_SAMPLE_BRANCH_CALL) mask |= X86_BR_CALL | X86_BR_ZERO_CALL; + + if (br_type & PERF_SAMPLE_BRANCH_TYPE_SAVE) + mask |= X86_BR_TYPE_SAVE; + /* * stash actual user request into reg, it may * be used by fixup code for some CPU @@ -930,6 +940,43 @@ static int branch_type(unsigned long from, unsigned long to, int abort) return ret; } +#define X86_BR_TYPE_MAP_MAX 16 + +static int branch_map[X86_BR_TYPE_MAP_MAX] = { + PERF_BR_CALL, /* X86_BR_CALL */ + PERF_BR_RET, /* X86_BR_RET */ + PERF_BR_SYSCALL, /* X86_BR_SYSCALL */ + PERF_BR_SYSRET, /* X86_BR_SYSRET */ + PERF_BR_UNKNOWN, /* X86_BR_INT */ + PERF_BR_UNKNOWN, /* X86_BR_IRET */ + PERF_BR_COND, /* X86_BR_JCC */ + PERF_BR_UNCOND, /* X86_BR_JMP */ + PERF_BR_UNKNOWN, /* X86_BR_IRQ */ + PERF_BR_IND_CALL, /* X86_BR_IND_CALL */ + PERF_BR_UNKNOWN, /* X86_BR_ABORT */ + PERF_BR_UNKNOWN, /* X86_BR_IN_TX */ + PERF_BR_UNKNOWN, /* X86_BR_NO_TX */ + PERF_BR_CALL, /* X86_BR_ZERO_CALL */ + PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */ + PERF_BR_IND, /* X86_BR_IND_JMP */ +}; + +static int +common_branch_type(int type) +{ + int i; + + type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */ + + if (type) { + i = __ffs(type); + if (i < X86_BR_TYPE_MAP_MAX) + return branch_map[i]; + } + + return PERF_BR_UNKNOWN; +} + /* * implement actual branch filter based on user demand. * Hardware may not exactly satisfy that request, thus @@ -946,7 +993,8 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc) bool compress = false; /* if sampling all branches, then nothing to filter */ - if ((br_sel & X86_BR_ALL) == X86_BR_ALL) + if (((br_sel & X86_BR_ALL) == X86_BR_ALL) && + ((br_sel & X86_BR_TYPE_SAVE) != X86_BR_TYPE_SAVE)) return; for (i = 0; i < cpuc->lbr_stack.nr; i++) { @@ -967,6 +1015,9 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc) cpuc->lbr_entries[i].from = 0; compress = true; } + + if ((br_sel & X86_BR_TYPE_SAVE) == X86_BR_TYPE_SAVE) + cpuc->lbr_entries[i].type = common_branch_type(type); } if (!compress) diff --git a/arch/x86/events/intel/p6.c b/arch/x86/events/intel/p6.c index 1f5c47ab4c65..a5604c352930 100644 --- a/arch/x86/events/intel/p6.c +++ b/arch/x86/events/intel/p6.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index ae8324d65e61..81fd41d5a0d9 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -471,8 +471,9 @@ static void pt_config(struct perf_event *event) struct pt *pt = this_cpu_ptr(&pt_ctx); u64 reg; - if (!event->hw.itrace_started) { - event->hw.itrace_started = 1; + /* First round: clear STATUS, in particular the PSB byte counter. */ + if (!event->hw.config) { + perf_event_itrace_started(event); wrmsrl(MSR_IA32_RTIT_STATUS, 0); } diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index 8e2457cb6b4a..005908ee9333 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -775,6 +775,9 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = { X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_DESKTOP, skl_rapl_init), X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, hsw_rapl_init), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_DENVERTON, hsw_rapl_init), + + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GEMINI_LAKE, hsw_rapl_init), {}, }; diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 1c5390f1cf09..d45e06346f14 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -822,7 +822,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid) pmus[i].type = type; pmus[i].boxes = kzalloc(size, GFP_KERNEL); if (!pmus[i].boxes) - return -ENOMEM; + goto err; } type->pmus = pmus; @@ -836,7 +836,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid) attr_group = kzalloc(sizeof(struct attribute *) * (i + 1) + sizeof(*attr_group), GFP_KERNEL); if (!attr_group) - return -ENOMEM; + goto err; attrs = (struct attribute **)(attr_group + 1); attr_group->name = "events"; @@ -849,7 +849,15 @@ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid) } type->pmu_group = &uncore_pmu_attr_group; + return 0; + +err: + for (i = 0; i < type->num_boxes; i++) + kfree(pmus[i].boxes); + kfree(pmus); + + return -ENOMEM; } static int __init diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h index df5989f27b1b..4364191e7c6b 100644 --- a/arch/x86/events/intel/uncore.h +++ b/arch/x86/events/intel/uncore.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/x86/events/intel/uncore_nhmex.c b/arch/x86/events/intel/uncore_nhmex.c index 6a5cbe90f859..93e7a8397cde 100644 --- a/arch/x86/events/intel/uncore_nhmex.c +++ b/arch/x86/events/intel/uncore_nhmex.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Nehalem-EX/Westmere-EX uncore support */ #include "uncore.h" diff --git a/arch/x86/events/intel/uncore_snb.c b/arch/x86/events/intel/uncore_snb.c index db1127ce685e..aee5e8496be4 100644 --- a/arch/x86/events/intel/uncore_snb.c +++ b/arch/x86/events/intel/uncore_snb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Nehalem/SandBridge/Haswell/Broadwell/Skylake uncore support */ #include "uncore.h" diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index db1fe377e6dd..95cb19f4e06f 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* SandyBridge-EP/IvyTown uncore support */ #include "uncore.h" @@ -3462,7 +3463,7 @@ static struct intel_uncore_ops skx_uncore_iio_ops = { static struct intel_uncore_type skx_uncore_iio = { .name = "iio", .num_counters = 4, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IIO0_MSR_PMON_CTL0, .perf_ctr = SKX_IIO0_MSR_PMON_CTR0, @@ -3492,7 +3493,7 @@ static const struct attribute_group skx_uncore_format_group = { static struct intel_uncore_type skx_uncore_irp = { .name = "irp", .num_counters = 2, - .num_boxes = 5, + .num_boxes = 6, .perf_ctr_bits = 48, .event_ctl = SKX_IRP0_MSR_PMON_CTL0, .perf_ctr = SKX_IRP0_MSR_PMON_CTR0, diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c index 4bb3ec69e8ea..14efaa0e8684 100644 --- a/arch/x86/events/msr.c +++ b/arch/x86/events/msr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -63,6 +64,14 @@ static bool test_intel(int idx) case INTEL_FAM6_ATOM_SILVERMONT1: case INTEL_FAM6_ATOM_SILVERMONT2: case INTEL_FAM6_ATOM_AIRMONT: + + case INTEL_FAM6_ATOM_GOLDMONT: + case INTEL_FAM6_ATOM_DENVERTON: + + case INTEL_FAM6_ATOM_GEMINI_LAKE: + + case INTEL_FAM6_XEON_PHI_KNL: + case INTEL_FAM6_XEON_PHI_KNM: if (idx == PERF_MSR_SMI) return true; break; diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 476aec3a4cab..4196f81ec0e1 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -91,7 +91,7 @@ struct amd_nb { (PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_ADDR | \ PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \ PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \ - PERF_SAMPLE_TRANSACTION) + PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR) /* * A debug store configuration. @@ -558,6 +558,7 @@ struct x86_pmu { int attr_rdpmc; struct attribute **format_attrs; struct attribute **event_attrs; + struct attribute **caps_attrs; ssize_t (*events_sysfs_show)(char *page, u64 config); struct attribute **cpu_events; @@ -591,7 +592,8 @@ struct x86_pmu { pebs :1, pebs_active :1, pebs_broken :1, - pebs_prec_dist :1; + pebs_prec_dist :1, + pebs_no_tlb :1; int pebs_record_size; int pebs_buffer_size; void (*drain_pebs)(struct pt_regs *regs); @@ -741,6 +743,8 @@ int x86_reserve_hardware(void); void x86_release_hardware(void); +int x86_pmu_max_precise(void); + void hw_perf_lbr_event_destroy(struct perf_event *event); int x86_setup_perfctr(struct perf_event *event); @@ -947,6 +951,8 @@ void intel_pmu_lbr_init_knl(void); void intel_pmu_pebs_data_source_nhm(void); +void intel_pmu_pebs_data_source_skl(bool pmem); + int intel_pmu_setup_lbr_filter(struct perf_event *event); void intel_pt_interrupt(void); diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile index 171ae09864d7..367a8203cfcf 100644 --- a/arch/x86/hyperv/Makefile +++ b/arch/x86/hyperv/Makefile @@ -1 +1 @@ -obj-y := hv_init.o +obj-y := hv_init.o mmu.o diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 5b882cc0c0e9..a5db63f728a2 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #ifdef CONFIG_HYPERV_TSCPAGE @@ -75,10 +77,30 @@ static struct clocksource hyperv_cs_msr = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void *hypercall_pg; +void *hv_hypercall_pg; +EXPORT_SYMBOL_GPL(hv_hypercall_pg); struct clocksource *hyperv_cs; EXPORT_SYMBOL_GPL(hyperv_cs); +u32 *hv_vp_index; +EXPORT_SYMBOL_GPL(hv_vp_index); + +u32 hv_max_vp_index; + +static int hv_cpu_init(unsigned int cpu) +{ + u64 msr_vp_index; + + hv_get_vp_index(msr_vp_index); + + hv_vp_index[smp_processor_id()] = msr_vp_index; + + if (msr_vp_index > hv_max_vp_index) + hv_max_vp_index = msr_vp_index; + + return 0; +} + /* * This function is to be invoked early in the boot sequence after the * hypervisor has been detected. @@ -94,6 +116,16 @@ void hyperv_init(void) if (x86_hyper != &x86_hyper_ms_hyperv) return; + /* Allocate percpu VP index */ + hv_vp_index = kmalloc_array(num_possible_cpus(), sizeof(*hv_vp_index), + GFP_KERNEL); + if (!hv_vp_index) + return; + + if (cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv_init:online", + hv_cpu_init, NULL) < 0) + goto free_vp_index; + /* * Setup the hypercall page and enable hypercalls. * 1. Register the guest ID @@ -102,17 +134,19 @@ void hyperv_init(void) guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id); - hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX); - if (hypercall_pg == NULL) { + hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX); + if (hv_hypercall_pg == NULL) { wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0); - return; + goto free_vp_index; } rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); hypercall_msr.enable = 1; - hypercall_msr.guest_physical_address = vmalloc_to_pfn(hypercall_pg); + hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); + hyper_alloc_mmu(); + /* * Register Hyper-V specific clocksource. */ @@ -148,6 +182,12 @@ register_msr_cs: hyperv_cs = &hyperv_cs_msr; if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100); + + return; + +free_vp_index: + kfree(hv_vp_index); + hv_vp_index = NULL; } /* @@ -170,51 +210,6 @@ void hyperv_cleanup(void) } EXPORT_SYMBOL_GPL(hyperv_cleanup); -/* - * hv_do_hypercall- Invoke the specified hypercall - */ -u64 hv_do_hypercall(u64 control, void *input, void *output) -{ - u64 input_address = (input) ? virt_to_phys(input) : 0; - u64 output_address = (output) ? virt_to_phys(output) : 0; -#ifdef CONFIG_X86_64 - u64 hv_status = 0; - - if (!hypercall_pg) - return (u64)ULLONG_MAX; - - __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); - __asm__ __volatile__("call *%3" : "=a" (hv_status) : - "c" (control), "d" (input_address), - "m" (hypercall_pg)); - - return hv_status; - -#else - - u32 control_hi = control >> 32; - u32 control_lo = control & 0xFFFFFFFF; - u32 hv_status_hi = 1; - u32 hv_status_lo = 1; - u32 input_address_hi = input_address >> 32; - u32 input_address_lo = input_address & 0xFFFFFFFF; - u32 output_address_hi = output_address >> 32; - u32 output_address_lo = output_address & 0xFFFFFFFF; - - if (!hypercall_pg) - return (u64)ULLONG_MAX; - - __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), - "=a"(hv_status_lo) : "d" (control_hi), - "a" (control_lo), "b" (input_address_hi), - "c" (input_address_lo), "D"(output_address_hi), - "S"(output_address_lo), "m" (hypercall_pg)); - - return hv_status_lo | ((u64)hv_status_hi << 32); -#endif /* !x86_64 */ -} -EXPORT_SYMBOL_GPL(hv_do_hypercall); - void hyperv_report_panic(struct pt_regs *regs) { static bool panic_reported; diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c new file mode 100644 index 000000000000..9cc9e1c1e2db --- /dev/null +++ b/arch/x86/hyperv/mmu.c @@ -0,0 +1,301 @@ +#define pr_fmt(fmt) "Hyper-V: " fmt + +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CREATE_TRACE_POINTS +#include + +/* HvFlushVirtualAddressSpace, HvFlushVirtualAddressList hypercalls */ +struct hv_flush_pcpu { + u64 address_space; + u64 flags; + u64 processor_mask; + u64 gva_list[]; +}; + +/* HvFlushVirtualAddressSpaceEx, HvFlushVirtualAddressListEx hypercalls */ +struct hv_flush_pcpu_ex { + u64 address_space; + u64 flags; + struct { + u64 format; + u64 valid_bank_mask; + u64 bank_contents[]; + } hv_vp_set; + u64 gva_list[]; +}; + +/* Each gva in gva_list encodes up to 4096 pages to flush */ +#define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE) + +static struct hv_flush_pcpu __percpu **pcpu_flush; + +static struct hv_flush_pcpu_ex __percpu **pcpu_flush_ex; + +/* + * Fills in gva_list starting from offset. Returns the number of items added. + */ +static inline int fill_gva_list(u64 gva_list[], int offset, + unsigned long start, unsigned long end) +{ + int gva_n = offset; + unsigned long cur = start, diff; + + do { + diff = end > cur ? end - cur : 0; + + gva_list[gva_n] = cur & PAGE_MASK; + /* + * Lower 12 bits encode the number of additional + * pages to flush (in addition to the 'cur' page). + */ + if (diff >= HV_TLB_FLUSH_UNIT) + gva_list[gva_n] |= ~PAGE_MASK; + else if (diff) + gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT; + + cur += HV_TLB_FLUSH_UNIT; + gva_n++; + + } while (cur < end); + + return gva_n - offset; +} + +/* Return the number of banks in the resulting vp_set */ +static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush, + const struct cpumask *cpus) +{ + int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1; + + /* valid_bank_mask can represent up to 64 banks */ + if (hv_max_vp_index / 64 >= 64) + return 0; + + /* + * Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex + * structs are not cleared between calls, we risk flushing unneeded + * vCPUs otherwise. + */ + for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++) + flush->hv_vp_set.bank_contents[vcpu_bank] = 0; + + /* + * Some banks may end up being empty but this is acceptable. + */ + for_each_cpu(cpu, cpus) { + vcpu = hv_cpu_number_to_vp_number(cpu); + vcpu_bank = vcpu / 64; + vcpu_offset = vcpu % 64; + __set_bit(vcpu_offset, (unsigned long *) + &flush->hv_vp_set.bank_contents[vcpu_bank]); + if (vcpu_bank >= nr_bank) + nr_bank = vcpu_bank + 1; + } + flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0); + + return nr_bank; +} + +static void hyperv_flush_tlb_others(const struct cpumask *cpus, + const struct flush_tlb_info *info) +{ + int cpu, vcpu, gva_n, max_gvas; + struct hv_flush_pcpu **flush_pcpu; + struct hv_flush_pcpu *flush; + u64 status = U64_MAX; + unsigned long flags; + + trace_hyperv_mmu_flush_tlb_others(cpus, info); + + if (!pcpu_flush || !hv_hypercall_pg) + goto do_native; + + if (cpumask_empty(cpus)) + return; + + local_irq_save(flags); + + flush_pcpu = this_cpu_ptr(pcpu_flush); + + if (unlikely(!*flush_pcpu)) + *flush_pcpu = page_address(alloc_page(GFP_ATOMIC)); + + flush = *flush_pcpu; + + if (unlikely(!flush)) { + local_irq_restore(flags); + goto do_native; + } + + if (info->mm) { + flush->address_space = virt_to_phys(info->mm->pgd); + flush->flags = 0; + } else { + flush->address_space = 0; + flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES; + } + + flush->processor_mask = 0; + if (cpumask_equal(cpus, cpu_present_mask)) { + flush->flags |= HV_FLUSH_ALL_PROCESSORS; + } else { + for_each_cpu(cpu, cpus) { + vcpu = hv_cpu_number_to_vp_number(cpu); + if (vcpu >= 64) + goto do_native; + + __set_bit(vcpu, (unsigned long *) + &flush->processor_mask); + } + } + + /* + * We can flush not more than max_gvas with one hypercall. Flush the + * whole address space if we were asked to do more. + */ + max_gvas = (PAGE_SIZE - sizeof(*flush)) / sizeof(flush->gva_list[0]); + + if (info->end == TLB_FLUSH_ALL) { + flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY; + status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE, + flush, NULL); + } else if (info->end && + ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) { + status = hv_do_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE, + flush, NULL); + } else { + gva_n = fill_gva_list(flush->gva_list, 0, + info->start, info->end); + status = hv_do_rep_hypercall(HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST, + gva_n, 0, flush, NULL); + } + + local_irq_restore(flags); + + if (!(status & HV_HYPERCALL_RESULT_MASK)) + return; +do_native: + native_flush_tlb_others(cpus, info); +} + +static void hyperv_flush_tlb_others_ex(const struct cpumask *cpus, + const struct flush_tlb_info *info) +{ + int nr_bank = 0, max_gvas, gva_n; + struct hv_flush_pcpu_ex **flush_pcpu; + struct hv_flush_pcpu_ex *flush; + u64 status = U64_MAX; + unsigned long flags; + + trace_hyperv_mmu_flush_tlb_others(cpus, info); + + if (!pcpu_flush_ex || !hv_hypercall_pg) + goto do_native; + + if (cpumask_empty(cpus)) + return; + + local_irq_save(flags); + + flush_pcpu = this_cpu_ptr(pcpu_flush_ex); + + if (unlikely(!*flush_pcpu)) + *flush_pcpu = page_address(alloc_page(GFP_ATOMIC)); + + flush = *flush_pcpu; + + if (unlikely(!flush)) { + local_irq_restore(flags); + goto do_native; + } + + if (info->mm) { + flush->address_space = virt_to_phys(info->mm->pgd); + flush->flags = 0; + } else { + flush->address_space = 0; + flush->flags = HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES; + } + + flush->hv_vp_set.valid_bank_mask = 0; + + if (!cpumask_equal(cpus, cpu_present_mask)) { + flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K; + nr_bank = cpumask_to_vp_set(flush, cpus); + } + + if (!nr_bank) { + flush->hv_vp_set.format = HV_GENERIC_SET_ALL; + flush->flags |= HV_FLUSH_ALL_PROCESSORS; + } + + /* + * We can flush not more than max_gvas with one hypercall. Flush the + * whole address space if we were asked to do more. + */ + max_gvas = + (PAGE_SIZE - sizeof(*flush) - nr_bank * + sizeof(flush->hv_vp_set.bank_contents[0])) / + sizeof(flush->gva_list[0]); + + if (info->end == TLB_FLUSH_ALL) { + flush->flags |= HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY; + status = hv_do_rep_hypercall( + HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX, + 0, nr_bank, flush, NULL); + } else if (info->end && + ((info->end - info->start)/HV_TLB_FLUSH_UNIT) > max_gvas) { + status = hv_do_rep_hypercall( + HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX, + 0, nr_bank, flush, NULL); + } else { + gva_n = fill_gva_list(flush->gva_list, nr_bank, + info->start, info->end); + status = hv_do_rep_hypercall( + HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX, + gva_n, nr_bank, flush, NULL); + } + + local_irq_restore(flags); + + if (!(status & HV_HYPERCALL_RESULT_MASK)) + return; +do_native: + native_flush_tlb_others(cpus, info); +} + +void hyperv_setup_mmu_ops(void) +{ + if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)) + return; + + setup_clear_cpu_cap(X86_FEATURE_PCID); + + if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) { + pr_info("Using hypercall for remote TLB flush\n"); + pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others; + } else { + pr_info("Using ext hypercall for remote TLB flush\n"); + pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex; + } +} + +void hyper_alloc_mmu(void) +{ + if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED)) + return; + + if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) + pcpu_flush = alloc_percpu(struct hv_flush_pcpu *); + else + pcpu_flush_ex = alloc_percpu(struct hv_flush_pcpu_ex *); +} diff --git a/arch/x86/ia32/audit.c b/arch/x86/ia32/audit.c index 2eccc8932ae6..3d21eab7aaed 100644 --- a/arch/x86/ia32/audit.c +++ b/arch/x86/ia32/audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include unsigned ia32_dir_class[] = { diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c index 8d0879f1d42c..8e02b30cf08e 100644 --- a/arch/x86/ia32/ia32_aout.c +++ b/arch/x86/ia32/ia32_aout.c @@ -407,10 +407,10 @@ static int load_aout_library(struct file *file) unsigned long bss, start_addr, len, error; int retval; struct exec ex; - + loff_t pos = 0; retval = -ENOEXEC; - error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); + error = kernel_read(file, &ex, sizeof(ex), &pos); if (error != sizeof(ex)) goto out; diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 724153797209..41c671854642 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/x86_64/ia32/ia32_signal.c * @@ -226,12 +227,12 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, if (ksig->ka.sa.sa_flags & SA_ONSTACK) sp = sigsp(sp, ksig); /* This is the legacy signal stack switching. */ - else if ((regs->ss & 0xffff) != __USER32_DS && + else if (regs->ss != __USER32_DS && !(ksig->ka.sa.sa_flags & SA_RESTORER) && ksig->ka.sa.sa_restorer) sp = (unsigned long) ksig->ka.sa.sa_restorer; - if (fpu->fpstate_active) { + if (fpu->initialized) { unsigned long fx_aligned, math_size; sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size); diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c index 47956c6a4fd8..96cd33bbfc85 100644 --- a/arch/x86/ia32/sys_ia32.c +++ b/arch/x86/ia32/sys_ia32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on * sys_sparc32 diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 2efc768e4362..8d0ec9df1cbe 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -162,12 +162,13 @@ static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) * you call efi_mem_attributes() during boot and at runtime, * you could theoretically see different attributes. * - * Since we are yet to see any x86 platforms that require - * anything other than PAGE_KERNEL (some arm64 platforms - * require the equivalent of PAGE_KERNEL_NOCACHE), return that - * until we know differently. + * We are yet to see any x86 platforms that require anything + * other than PAGE_KERNEL (some ARM64 platforms require the + * equivalent of PAGE_KERNEL_NOCACHE). Additionally, if SME + * is active, the ACPI information will not be encrypted, + * so return PAGE_KERNEL_NOENC until we know differently. */ - return PAGE_KERNEL; + return PAGE_KERNEL_NOENC; } #endif diff --git a/arch/x86/include/asm/agp.h b/arch/x86/include/asm/agp.h index eec2a70d4376..8e25bf4f323a 100644 --- a/arch/x86/include/asm/agp.h +++ b/arch/x86/include/asm/agp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_AGP_H #define _ASM_X86_AGP_H diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h index e7636bac7372..31b627b43a8e 100644 --- a/arch/x86/include/asm/alternative-asm.h +++ b/arch/x86/include/asm/alternative-asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ALTERNATIVE_ASM_H #define _ASM_X86_ALTERNATIVE_ASM_H @@ -62,8 +63,10 @@ #define new_len2 145f-144f /* - * max without conditionals. Idea adapted from: + * gas compatible max based on the idea from: * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax + * + * The additional "-" is needed because gas uses a "true" value of -1. */ #define alt_max_short(a, b) ((a) ^ (((a) ^ (b)) & -(-((a) < (b))))) diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 1b020381ab38..dbfd0854651f 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ALTERNATIVE_H #define _ASM_X86_ALTERNATIVE_H @@ -103,12 +104,12 @@ static inline int alternatives_text_reserved(void *start, void *end) alt_end_marker ":\n" /* - * max without conditionals. Idea adapted from: + * gas compatible max based on the idea from: * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax * - * The additional "-" is needed because gas works with s32s. + * The additional "-" is needed because gas uses a "true" value of -1. */ -#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") - (" b ")))))" +#define alt_max_short(a, b) "((" a ") ^ (((" a ") ^ (" b ")) & -(-((" a ") < (" b ")))))" /* * Pad the second replacement alternative with additional NOPs if it is @@ -218,10 +219,9 @@ static inline int alternatives_text_reserved(void *start, void *end) #define alternative_call_2(oldfunc, newfunc1, feature1, newfunc2, feature2, \ output, input...) \ { \ - register void *__sp asm(_ASM_SP); \ asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ "call %P[new2]", feature2) \ - : output, "+r" (__sp) \ + : output, ASM_CALL_CONSTRAINT \ : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ [new2] "i" (newfunc2), ## input); \ } diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index da181ad1d5f8..fddb6d26239f 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_AMD_NB_H #define _ASM_X86_AMD_NB_H diff --git a/arch/x86/include/asm/apic_flat_64.h b/arch/x86/include/asm/apic_flat_64.h index a2d312796440..d3a2b3876ce6 100644 --- a/arch/x86/include/asm/apic_flat_64.h +++ b/arch/x86/include/asm/apic_flat_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_APIC_FLAT_64_H #define _ASM_X86_APIC_FLAT_64_H diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h index c46bb99d5fb2..05e694ed8386 100644 --- a/arch/x86/include/asm/apicdef.h +++ b/arch/x86/include/asm/apicdef.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_APICDEF_H #define _ASM_X86_APICDEF_H diff --git a/arch/x86/include/asm/apm.h b/arch/x86/include/asm/apm.h index 93eebc636c76..4d4015ddcf26 100644 --- a/arch/x86/include/asm/apm.h +++ b/arch/x86/include/asm/apm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine specific APM BIOS functions for generic. * Split out from apm.c by Osamu Tomita diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h index e7cd63175de4..34a10b2d5b73 100644 --- a/arch/x86/include/asm/arch_hweight.h +++ b/arch/x86/include/asm/arch_hweight.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HWEIGHT_H #define _ASM_X86_HWEIGHT_H diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h index 830b19dbfa31..ff700d81e91e 100644 --- a/arch/x86/include/asm/asm-prototypes.h +++ b/arch/x86/include/asm/asm-prototypes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 7a9df3beb89b..219faaec51df 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ASM_H #define _ASM_X86_ASM_H @@ -11,10 +12,12 @@ # define __ASM_FORM_COMMA(x) " " #x "," #endif -#ifdef CONFIG_X86_32 +#ifndef __x86_64__ +/* 32 bit */ # define __ASM_SEL(a,b) __ASM_FORM(a) # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(a) #else +/* 64 bit */ # define __ASM_SEL(a,b) __ASM_FORM(b) # define __ASM_SEL_RAW(a,b) __ASM_FORM_RAW(b) #endif @@ -74,6 +77,9 @@ # define _ASM_EXTABLE_EX(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) +# define _ASM_EXTABLE_REFCOUNT(from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount) + # define _ASM_NOKPROBE(entry) \ .pushsection "_kprobe_blacklist","aw" ; \ _ASM_ALIGN ; \ @@ -123,7 +129,21 @@ # define _ASM_EXTABLE_EX(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) +# define _ASM_EXTABLE_REFCOUNT(from, to) \ + _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount) + /* For C file, we already have NOKPROBE_SYMBOL macro */ #endif +#ifndef __ASSEMBLY__ +/* + * This output constraint should be used for any inline asm which has a "call" + * instruction. Otherwise the asm may be inserted before the frame pointer + * gets set up by the containing function. If you forget to do this, objtool + * may print a "call without frame pointer save/setup" warning. + */ +register unsigned long current_stack_pointer asm(_ASM_SP); +#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) +#endif + #endif /* _ASM_X86_ASM_H */ diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 33380b871463..72759f131cc5 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ATOMIC_H #define _ASM_X86_ATOMIC_H @@ -197,35 +198,56 @@ static inline int atomic_xchg(atomic_t *v, int new) return xchg(&v->counter, new); } -#define ATOMIC_OP(op) \ -static inline void atomic_##op(int i, atomic_t *v) \ -{ \ - asm volatile(LOCK_PREFIX #op"l %1,%0" \ - : "+m" (v->counter) \ - : "ir" (i) \ - : "memory"); \ +static inline void atomic_and(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "andl %1,%0" + : "+m" (v->counter) + : "ir" (i) + : "memory"); } -#define ATOMIC_FETCH_OP(op, c_op) \ -static inline int atomic_fetch_##op(int i, atomic_t *v) \ -{ \ - int val = atomic_read(v); \ - do { \ - } while (!atomic_try_cmpxchg(v, &val, val c_op i)); \ - return val; \ +static inline int atomic_fetch_and(int i, atomic_t *v) +{ + int val = atomic_read(v); + + do { } while (!atomic_try_cmpxchg(v, &val, val & i)); + + return val; } -#define ATOMIC_OPS(op, c_op) \ - ATOMIC_OP(op) \ - ATOMIC_FETCH_OP(op, c_op) +static inline void atomic_or(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "orl %1,%0" + : "+m" (v->counter) + : "ir" (i) + : "memory"); +} -ATOMIC_OPS(and, &) -ATOMIC_OPS(or , |) -ATOMIC_OPS(xor, ^) +static inline int atomic_fetch_or(int i, atomic_t *v) +{ + int val = atomic_read(v); -#undef ATOMIC_OPS -#undef ATOMIC_FETCH_OP -#undef ATOMIC_OP + do { } while (!atomic_try_cmpxchg(v, &val, val | i)); + + return val; +} + +static inline void atomic_xor(int i, atomic_t *v) +{ + asm volatile(LOCK_PREFIX "xorl %1,%0" + : "+m" (v->counter) + : "ir" (i) + : "memory"); +} + +static inline int atomic_fetch_xor(int i, atomic_t *v) +{ + int val = atomic_read(v); + + do { } while (!atomic_try_cmpxchg(v, &val, val ^ i)); + + return val; +} /** * __atomic_add_unless - add unless the number is already a given value @@ -239,10 +261,12 @@ ATOMIC_OPS(xor, ^) static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u) { int c = atomic_read(v); + do { if (unlikely(c == u)) break; } while (!atomic_try_cmpxchg(v, &c, c + a)); + return c; } diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h index 71d7705fb303..97c46b8169b7 100644 --- a/arch/x86/include/asm/atomic64_32.h +++ b/arch/x86/include/asm/atomic64_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ATOMIC64_32_H #define _ASM_X86_ATOMIC64_32_H @@ -312,37 +313,70 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v) #undef alternative_atomic64 #undef __alternative_atomic64 -#define ATOMIC64_OP(op, c_op) \ -static inline void atomic64_##op(long long i, atomic64_t *v) \ -{ \ - long long old, c = 0; \ - while ((old = atomic64_cmpxchg(v, c, c c_op i)) != c) \ - c = old; \ +static inline void atomic64_and(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c & i)) != c) + c = old; } -#define ATOMIC64_FETCH_OP(op, c_op) \ -static inline long long atomic64_fetch_##op(long long i, atomic64_t *v) \ -{ \ - long long old, c = 0; \ - while ((old = atomic64_cmpxchg(v, c, c c_op i)) != c) \ - c = old; \ - return old; \ +static inline long long atomic64_fetch_and(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c & i)) != c) + c = old; + + return old; } -ATOMIC64_FETCH_OP(add, +) +static inline void atomic64_or(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c | i)) != c) + c = old; +} + +static inline long long atomic64_fetch_or(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c | i)) != c) + c = old; + + return old; +} + +static inline void atomic64_xor(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c ^ i)) != c) + c = old; +} + +static inline long long atomic64_fetch_xor(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c ^ i)) != c) + c = old; + + return old; +} + +static inline long long atomic64_fetch_add(long long i, atomic64_t *v) +{ + long long old, c = 0; + + while ((old = atomic64_cmpxchg(v, c, c + i)) != c) + c = old; + + return old; +} #define atomic64_fetch_sub(i, v) atomic64_fetch_add(-(i), (v)) -#define ATOMIC64_OPS(op, c_op) \ - ATOMIC64_OP(op, c_op) \ - ATOMIC64_FETCH_OP(op, c_op) - -ATOMIC64_OPS(and, &) -ATOMIC64_OPS(or, |) -ATOMIC64_OPS(xor, ^) - -#undef ATOMIC64_OPS -#undef ATOMIC64_FETCH_OP -#undef ATOMIC64_OP - #endif /* _ASM_X86_ATOMIC64_32_H */ diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h index 6189a433c9a9..738495caf05f 100644 --- a/arch/x86/include/asm/atomic64_64.h +++ b/arch/x86/include/asm/atomic64_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ATOMIC64_64_H #define _ASM_X86_ATOMIC64_64_H @@ -177,7 +178,7 @@ static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new) } #define atomic64_try_cmpxchg atomic64_try_cmpxchg -static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, long *old, long new) +static __always_inline bool atomic64_try_cmpxchg(atomic64_t *v, s64 *old, long new) { return try_cmpxchg(&v->counter, old, new); } @@ -198,7 +199,7 @@ static inline long atomic64_xchg(atomic64_t *v, long new) */ static inline bool atomic64_add_unless(atomic64_t *v, long a, long u) { - long c = atomic64_read(v); + s64 c = atomic64_read(v); do { if (unlikely(c == u)) return false; @@ -217,7 +218,7 @@ static inline bool atomic64_add_unless(atomic64_t *v, long a, long u) */ static inline long atomic64_dec_if_positive(atomic64_t *v) { - long dec, c = atomic64_read(v); + s64 dec, c = atomic64_read(v); do { dec = c - 1; if (unlikely(dec < 0)) @@ -226,34 +227,55 @@ static inline long atomic64_dec_if_positive(atomic64_t *v) return dec; } -#define ATOMIC64_OP(op) \ -static inline void atomic64_##op(long i, atomic64_t *v) \ -{ \ - asm volatile(LOCK_PREFIX #op"q %1,%0" \ - : "+m" (v->counter) \ - : "er" (i) \ - : "memory"); \ +static inline void atomic64_and(long i, atomic64_t *v) +{ + asm volatile(LOCK_PREFIX "andq %1,%0" + : "+m" (v->counter) + : "er" (i) + : "memory"); } -#define ATOMIC64_FETCH_OP(op, c_op) \ -static inline long atomic64_fetch_##op(long i, atomic64_t *v) \ -{ \ - long val = atomic64_read(v); \ - do { \ - } while (!atomic64_try_cmpxchg(v, &val, val c_op i)); \ - return val; \ +static inline long atomic64_fetch_and(long i, atomic64_t *v) +{ + s64 val = atomic64_read(v); + + do { + } while (!atomic64_try_cmpxchg(v, &val, val & i)); + return val; } -#define ATOMIC64_OPS(op, c_op) \ - ATOMIC64_OP(op) \ - ATOMIC64_FETCH_OP(op, c_op) +static inline void atomic64_or(long i, atomic64_t *v) +{ + asm volatile(LOCK_PREFIX "orq %1,%0" + : "+m" (v->counter) + : "er" (i) + : "memory"); +} -ATOMIC64_OPS(and, &) -ATOMIC64_OPS(or, |) -ATOMIC64_OPS(xor, ^) +static inline long atomic64_fetch_or(long i, atomic64_t *v) +{ + s64 val = atomic64_read(v); -#undef ATOMIC64_OPS -#undef ATOMIC64_FETCH_OP -#undef ATOMIC64_OP + do { + } while (!atomic64_try_cmpxchg(v, &val, val | i)); + return val; +} + +static inline void atomic64_xor(long i, atomic64_t *v) +{ + asm volatile(LOCK_PREFIX "xorq %1,%0" + : "+m" (v->counter) + : "er" (i) + : "memory"); +} + +static inline long atomic64_fetch_xor(long i, atomic64_t *v) +{ + s64 val = atomic64_read(v); + + do { + } while (!atomic64_try_cmpxchg(v, &val, val ^ i)); + return val; +} #endif /* _ASM_X86_ATOMIC64_64_H */ diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index bfb28caf97b1..01727dbc294a 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BARRIER_H #define _ASM_X86_BARRIER_H diff --git a/arch/x86/include/asm/bios_ebda.h b/arch/x86/include/asm/bios_ebda.h index 4b7b8e71607e..4d5a17e2febe 100644 --- a/arch/x86/include/asm/bios_ebda.h +++ b/arch/x86/include/asm/bios_ebda.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BIOS_EBDA_H #define _ASM_X86_BIOS_EBDA_H diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 854022772c5b..2bcf47314959 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BITOPS_H #define _ASM_X86_BITOPS_H diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index abd06b19ddd2..680c320363db 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BOOT_H #define _ASM_X86_BOOT_H diff --git a/arch/x86/include/asm/bootparam_utils.h b/arch/x86/include/asm/bootparam_utils.h index 4a8cb8d7cbd5..a07ffd23e4dd 100644 --- a/arch/x86/include/asm/bootparam_utils.h +++ b/arch/x86/include/asm/bootparam_utils.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BOOTPARAM_UTILS_H #define _ASM_X86_BOOTPARAM_UTILS_H diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index aa6b2023d8f8..34d99af43994 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BUG_H #define _ASM_X86_BUG_H diff --git a/arch/x86/include/asm/bugs.h b/arch/x86/include/asm/bugs.h index 5490bbaf71d5..542509b53e0f 100644 --- a/arch/x86/include/asm/bugs.h +++ b/arch/x86/include/asm/bugs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BUGS_H #define _ASM_X86_BUGS_H diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h index 48f99f15452e..abe08690a887 100644 --- a/arch/x86/include/asm/cache.h +++ b/arch/x86/include/asm/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CACHE_H #define _ASM_X86_CACHE_H diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h index 8b4140f6724f..63feaf2a5f93 100644 --- a/arch/x86/include/asm/cacheflush.h +++ b/arch/x86/include/asm/cacheflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CACHEFLUSH_H #define _ASM_X86_CACHEFLUSH_H @@ -7,6 +8,4 @@ void clflush_cache_range(void *addr, unsigned int size); -#define mmio_flush_range(addr, size) clflush_cache_range(addr, size) - #endif /* _ASM_X86_CACHEFLUSH_H */ diff --git a/arch/x86/include/asm/ce4100.h b/arch/x86/include/asm/ce4100.h index e656ad8c0a2e..2930f560d7f3 100644 --- a/arch/x86/include/asm/ce4100.h +++ b/arch/x86/include/asm/ce4100.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_CE4100_H_ #define _ASM_CE4100_H_ diff --git a/arch/x86/include/asm/checksum.h b/arch/x86/include/asm/checksum.h index 5f5bb0f97361..d79d1e622dcf 100644 --- a/arch/x86/include/asm/checksum.h +++ b/arch/x86/include/asm/checksum.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_X86_32 # include #else diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h index 7b53743ed267..7a659c74cd03 100644 --- a/arch/x86/include/asm/checksum_32.h +++ b/arch/x86/include/asm/checksum_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CHECKSUM_32_H #define _ASM_X86_CHECKSUM_32_H diff --git a/arch/x86/include/asm/checksum_64.h b/arch/x86/include/asm/checksum_64.h index 08e7efb2c140..3ec6d3267cf9 100644 --- a/arch/x86/include/asm/checksum_64.h +++ b/arch/x86/include/asm/checksum_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CHECKSUM_64_H #define _ASM_X86_CHECKSUM_64_H diff --git a/arch/x86/include/asm/clocksource.h b/arch/x86/include/asm/clocksource.h index 47bea8cadbd0..dc4cfc888d6d 100644 --- a/arch/x86/include/asm/clocksource.h +++ b/arch/x86/include/asm/clocksource.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* x86-specific clocksource additions */ #ifndef _ASM_X86_CLOCKSOURCE_H diff --git a/arch/x86/include/asm/cmdline.h b/arch/x86/include/asm/cmdline.h index e01f7f7ccb0c..6faaf27e8899 100644 --- a/arch/x86/include/asm/cmdline.h +++ b/arch/x86/include/asm/cmdline.h @@ -1,6 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CMDLINE_H #define _ASM_X86_CMDLINE_H int cmdline_find_option_bool(const char *cmdline_ptr, const char *option); +int cmdline_find_option(const char *cmdline_ptr, const char *option, + char *buffer, int bufsize); #endif /* _ASM_X86_CMDLINE_H */ diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index d90296d061e8..56bd436ed01b 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_X86_CMPXCHG_H #define ASM_X86_CMPXCHG_H @@ -157,7 +158,7 @@ extern void __add_wrong_size(void) #define __raw_try_cmpxchg(_ptr, _pold, _new, size, lock) \ ({ \ bool success; \ - __typeof__(_ptr) _old = (_pold); \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ __typeof__(*(_ptr)) __old = *_old; \ __typeof__(*(_ptr)) __new = (_new); \ switch (size) { \ diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h index e4959d023af8..1732704f0445 100644 --- a/arch/x86/include/asm/cmpxchg_32.h +++ b/arch/x86/include/asm/cmpxchg_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CMPXCHG_32_H #define _ASM_X86_CMPXCHG_32_H diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h index caa23a34c963..03cad196a301 100644 --- a/arch/x86/include/asm/cmpxchg_64.h +++ b/arch/x86/include/asm/cmpxchg_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CMPXCHG_64_H #define _ASM_X86_CMPXCHG_64_H diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index 5343c19814b3..9eef9cc64c68 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_COMPAT_H #define _ASM_X86_COMPAT_H diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 9b7fa6313f1a..adc6cc86b062 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CPU_H #define _ASM_X86_CPU_H diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h index ff501e511d91..baeba0567126 100644 --- a/arch/x86/include/asm/cpu_device_id.h +++ b/arch/x86/include/asm/cpu_device_id.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CPU_DEVICE_ID #define _CPU_DEVICE_ID 1 diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index d59c15c3defd..0dfa68438e80 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CPUFEATURE_H #define _ASM_X86_CPUFEATURE_H diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 5a28e8e55e36..793690fbda36 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CPUFEATURES_H #define _ASM_X86_CPUFEATURES_H @@ -177,7 +178,7 @@ #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ #define X86_FEATURE_PTSC ( 6*32+27) /* performance time-stamp counter */ -#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ +#define X86_FEATURE_PERFCTR_LLC ( 6*32+28) /* Last Level Cache performance counter extensions */ #define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ /* @@ -196,6 +197,7 @@ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ +#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ @@ -287,6 +289,7 @@ #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ #define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ +#define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h index 61c852fa346b..6722ffcef2e6 100644 --- a/arch/x86/include/asm/cpumask.h +++ b/arch/x86/include/asm/cpumask.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CPUMASK_H #define _ASM_X86_CPUMASK_H #ifndef __ASSEMBLY__ diff --git a/arch/x86/include/asm/crash.h b/arch/x86/include/asm/crash.h index f498411f2500..a7adb2bfbf0b 100644 --- a/arch/x86/include/asm/crash.h +++ b/arch/x86/include/asm/crash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CRASH_H #define _ASM_X86_CRASH_H diff --git a/arch/x86/include/asm/crypto/aes.h b/arch/x86/include/asm/crypto/aes.h index 80545a1cbe39..c508521dd190 100644 --- a/arch/x86/include/asm/crypto/aes.h +++ b/arch/x86/include/asm/crypto/aes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_X86_AES_H #define ASM_X86_AES_H diff --git a/arch/x86/include/asm/crypto/camellia.h b/arch/x86/include/asm/crypto/camellia.h index bb93333d9200..10f8d590bcfe 100644 --- a/arch/x86/include/asm/crypto/camellia.h +++ b/arch/x86/include/asm/crypto/camellia.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_X86_CAMELLIA_H #define ASM_X86_CAMELLIA_H diff --git a/arch/x86/include/asm/crypto/glue_helper.h b/arch/x86/include/asm/crypto/glue_helper.h index ed8b66de541f..553a03de55c3 100644 --- a/arch/x86/include/asm/crypto/glue_helper.h +++ b/arch/x86/include/asm/crypto/glue_helper.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Shared glue code for 128bit block ciphers */ diff --git a/arch/x86/include/asm/crypto/serpent-avx.h b/arch/x86/include/asm/crypto/serpent-avx.h index 33c2b8a435da..c958b7bd0fcb 100644 --- a/arch/x86/include/asm/crypto/serpent-avx.h +++ b/arch/x86/include/asm/crypto/serpent-avx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_X86_SERPENT_AVX_H #define ASM_X86_SERPENT_AVX_H diff --git a/arch/x86/include/asm/crypto/serpent-sse2.h b/arch/x86/include/asm/crypto/serpent-sse2.h index e6e77dffbdab..1a345e8a7496 100644 --- a/arch/x86/include/asm/crypto/serpent-sse2.h +++ b/arch/x86/include/asm/crypto/serpent-sse2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_X86_SERPENT_SSE2_H #define ASM_X86_SERPENT_SSE2_H diff --git a/arch/x86/include/asm/crypto/twofish.h b/arch/x86/include/asm/crypto/twofish.h index 878c51ceebb5..65bb80adba3e 100644 --- a/arch/x86/include/asm/crypto/twofish.h +++ b/arch/x86/include/asm/crypto/twofish.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_X86_TWOFISH_H #define ASM_X86_TWOFISH_H diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h index 9476c04ee635..3e204e6140b5 100644 --- a/arch/x86/include/asm/current.h +++ b/arch/x86/include/asm/current.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CURRENT_H #define _ASM_X86_CURRENT_H diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h index 12cb66f6d3a5..4505ac2735ad 100644 --- a/arch/x86/include/asm/debugreg.h +++ b/arch/x86/include/asm/debugreg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DEBUGREG_H #define _ASM_X86_DEBUGREG_H diff --git a/arch/x86/include/asm/delay.h b/arch/x86/include/asm/delay.h index 36a760bda462..de9e7841f953 100644 --- a/arch/x86/include/asm/delay.h +++ b/arch/x86/include/asm/delay.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DELAY_H #define _ASM_X86_DELAY_H diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index d0a21b12dd58..0a3e808b9123 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DESC_H #define _ASM_X86_DESC_H @@ -5,6 +6,7 @@ #include #include #include +#include #include #include @@ -22,7 +24,7 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in desc->s = 1; desc->dpl = 0x3; desc->p = info->seg_not_present ^ 1; - desc->limit = (info->limit & 0xf0000) >> 16; + desc->limit1 = (info->limit & 0xf0000) >> 16; desc->avl = info->useable; desc->d = info->seg_32bit; desc->g = info->limit_in_pages; @@ -83,33 +85,25 @@ static inline phys_addr_t get_cpu_gdt_paddr(unsigned int cpu) return per_cpu_ptr_to_phys(get_cpu_gdt_rw(cpu)); } -#ifdef CONFIG_X86_64 - static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, unsigned dpl, unsigned ist, unsigned seg) { - gate->offset_low = PTR_LOW(func); + gate->offset_low = (u16) func; + gate->bits.p = 1; + gate->bits.dpl = dpl; + gate->bits.zero = 0; + gate->bits.type = type; + gate->offset_middle = (u16) (func >> 16); +#ifdef CONFIG_X86_64 gate->segment = __KERNEL_CS; - gate->ist = ist; - gate->p = 1; - gate->dpl = dpl; - gate->zero0 = 0; - gate->zero1 = 0; - gate->type = type; - gate->offset_middle = PTR_MIDDLE(func); - gate->offset_high = PTR_HIGH(func); -} - + gate->bits.ist = ist; + gate->reserved = 0; + gate->offset_high = (u32) (func >> 32); #else -static inline void pack_gate(gate_desc *gate, unsigned char type, - unsigned long base, unsigned dpl, unsigned flags, - unsigned short seg) -{ - gate->a = (seg << 16) | (base & 0xffff); - gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8); -} - + gate->segment = seg; + gate->bits.ist = 0; #endif +} static inline int desc_empty(const void *ptr) { @@ -128,7 +122,6 @@ static inline int desc_empty(const void *ptr) #define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt)) #define store_gdt(dtr) native_store_gdt(dtr) -#define store_idt(dtr) native_store_idt(dtr) #define store_tr(tr) (tr = native_store_tr()) #define load_TLS(t, cpu) native_load_tls(t, cpu) @@ -173,35 +166,22 @@ native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, int memcpy(&gdt[entry], desc, size); } -static inline void pack_descriptor(struct desc_struct *desc, unsigned long base, - unsigned long limit, unsigned char type, - unsigned char flags) +static inline void set_tssldt_descriptor(void *d, unsigned long addr, + unsigned type, unsigned size) { - desc->a = ((base & 0xffff) << 16) | (limit & 0xffff); - desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) | - (limit & 0x000f0000) | ((type & 0xff) << 8) | - ((flags & 0xf) << 20); - desc->p = 1; -} - - -static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size) -{ -#ifdef CONFIG_X86_64 - struct ldttss_desc64 *desc = d; + struct ldttss_desc *desc = d; memset(desc, 0, sizeof(*desc)); - desc->limit0 = size & 0xFFFF; - desc->base0 = PTR_LOW(addr); - desc->base1 = PTR_MIDDLE(addr) & 0xFF; + desc->limit0 = (u16) size; + desc->base0 = (u16) addr; + desc->base1 = (addr >> 16) & 0xFF; desc->type = type; desc->p = 1; desc->limit1 = (size >> 16) & 0xF; - desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF; - desc->base3 = PTR_HIGH(addr); -#else - pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0); + desc->base2 = (addr >> 24) & 0xFF; +#ifdef CONFIG_X86_64 + desc->base3 = (u32) (addr >> 32); #endif } @@ -248,7 +228,7 @@ static inline void native_store_gdt(struct desc_ptr *dtr) asm volatile("sgdt %0":"=m" (*dtr)); } -static inline void native_store_idt(struct desc_ptr *dtr) +static inline void store_idt(struct desc_ptr *dtr) { asm volatile("sidt %0":"=m" (*dtr)); } @@ -401,147 +381,20 @@ static inline void set_desc_base(struct desc_struct *desc, unsigned long base) static inline unsigned long get_desc_limit(const struct desc_struct *desc) { - return desc->limit0 | (desc->limit << 16); + return desc->limit0 | (desc->limit1 << 16); } static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit) { desc->limit0 = limit & 0xffff; - desc->limit = (limit >> 16) & 0xf; + desc->limit1 = (limit >> 16) & 0xf; } -#ifdef CONFIG_X86_64 -static inline void set_nmi_gate(int gate, void *addr) -{ - gate_desc s; +void update_intr_gate(unsigned int n, const void *addr); +void alloc_intr_gate(unsigned int n, const void *addr); - pack_gate(&s, GATE_INTERRUPT, (unsigned long)addr, 0, 0, __KERNEL_CS); - write_idt_entry(debug_idt_table, gate, &s); -} -#endif - -#ifdef CONFIG_TRACING -extern struct desc_ptr trace_idt_descr; -extern gate_desc trace_idt_table[]; -static inline void write_trace_idt_entry(int entry, const gate_desc *gate) -{ - write_idt_entry(trace_idt_table, entry, gate); -} - -static inline void _trace_set_gate(int gate, unsigned type, void *addr, - unsigned dpl, unsigned ist, unsigned seg) -{ - gate_desc s; - - pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); - /* - * does not need to be atomic because it is only done once at - * setup time - */ - write_trace_idt_entry(gate, &s); -} -#else -static inline void write_trace_idt_entry(int entry, const gate_desc *gate) -{ -} - -#define _trace_set_gate(gate, type, addr, dpl, ist, seg) -#endif - -static inline void _set_gate(int gate, unsigned type, void *addr, - unsigned dpl, unsigned ist, unsigned seg) -{ - gate_desc s; - - pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg); - /* - * does not need to be atomic because it is only done once at - * setup time - */ - write_idt_entry(idt_table, gate, &s); - write_trace_idt_entry(gate, &s); -} - -/* - * This needs to use 'idt_table' rather than 'idt', and - * thus use the _nonmapped_ version of the IDT, as the - * Pentium F0 0F bugfix can have resulted in the mapped - * IDT being write-protected. - */ -#define set_intr_gate_notrace(n, addr) \ - do { \ - BUG_ON((unsigned)n > 0xFF); \ - _set_gate(n, GATE_INTERRUPT, (void *)addr, 0, 0, \ - __KERNEL_CS); \ - } while (0) - -#define set_intr_gate(n, addr) \ - do { \ - set_intr_gate_notrace(n, addr); \ - _trace_set_gate(n, GATE_INTERRUPT, (void *)trace_##addr,\ - 0, 0, __KERNEL_CS); \ - } while (0) - -extern int first_system_vector; -/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ extern unsigned long used_vectors[]; -static inline void alloc_system_vector(int vector) -{ - if (!test_bit(vector, used_vectors)) { - set_bit(vector, used_vectors); - if (first_system_vector > vector) - first_system_vector = vector; - } else { - BUG(); - } -} - -#define alloc_intr_gate(n, addr) \ - do { \ - alloc_system_vector(n); \ - set_intr_gate(n, addr); \ - } while (0) - -/* - * This routine sets up an interrupt gate at directory privilege level 3. - */ -static inline void set_system_intr_gate(unsigned int n, void *addr) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS); -} - -static inline void set_system_trap_gate(unsigned int n, void *addr) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS); -} - -static inline void set_trap_gate(unsigned int n, void *addr) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS); -} - -static inline void set_task_gate(unsigned int n, unsigned int gdt_entry) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3)); -} - -static inline void set_intr_gate_ist(int n, void *addr, unsigned ist) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS); -} - -static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist) -{ - BUG_ON((unsigned)n > 0xFF); - _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS); -} - #ifdef CONFIG_X86_64 DECLARE_PER_CPU(u32, debug_idt_ctr); static inline bool is_debug_idt_enabled(void) @@ -567,31 +420,6 @@ static inline void load_debug_idt(void) } #endif -#ifdef CONFIG_TRACING -extern atomic_t trace_idt_ctr; -static inline bool is_trace_idt_enabled(void) -{ - if (atomic_read(&trace_idt_ctr)) - return true; - - return false; -} - -static inline void load_trace_idt(void) -{ - load_idt((const struct desc_ptr *)&trace_idt_descr); -} -#else -static inline bool is_trace_idt_enabled(void) -{ - return false; -} - -static inline void load_trace_idt(void) -{ -} -#endif - /* * The load_current_idt() must be called with interrupts disabled * to avoid races. That way the IDT will always be set back to the expected @@ -603,9 +431,25 @@ static inline void load_current_idt(void) { if (is_debug_idt_enabled()) load_debug_idt(); - else if (is_trace_idt_enabled()) - load_trace_idt(); else load_idt((const struct desc_ptr *)&idt_descr); } + +extern void idt_setup_early_handler(void); +extern void idt_setup_early_traps(void); +extern void idt_setup_traps(void); +extern void idt_setup_apic_and_irq_gates(void); + +#ifdef CONFIG_X86_64 +extern void idt_setup_early_pf(void); +extern void idt_setup_ist_traps(void); +extern void idt_setup_debugidt_traps(void); +#else +static inline void idt_setup_early_pf(void) { } +static inline void idt_setup_ist_traps(void) { } +static inline void idt_setup_debugidt_traps(void) { } +#endif + +extern void idt_invalidate(void *addr); + #endif /* _ASM_X86_DESC_H */ diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h index 49265345d4d2..a91f3b6e4f2a 100644 --- a/arch/x86/include/asm/desc_defs.h +++ b/arch/x86/include/asm/desc_defs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Written 2000 by Andi Kleen */ #ifndef _ASM_X86_DESC_DEFS_H #define _ASM_X86_DESC_DEFS_H @@ -11,34 +12,30 @@ #include -/* - * FIXME: Accessing the desc_struct through its fields is more elegant, - * and should be the one valid thing to do. However, a lot of open code - * still touches the a and b accessors, and doing this allow us to do it - * incrementally. We keep the signature as a struct, rather than a union, - * so we can get rid of it transparently in the future -- glommer - */ /* 8 byte segment descriptor */ struct desc_struct { - union { - struct { - unsigned int a; - unsigned int b; - }; - struct { - u16 limit0; - u16 base0; - unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1; - unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; - }; - }; + u16 limit0; + u16 base0; + u16 base1: 8, type: 4, s: 1, dpl: 2, p: 1; + u16 limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8; } __attribute__((packed)); -#define GDT_ENTRY_INIT(flags, base, limit) { { { \ - .a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \ - .b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \ - ((limit) & 0xf0000) | ((base) & 0xff000000), \ - } } } +#define GDT_ENTRY_INIT(flags, base, limit) \ + { \ + .limit0 = (u16) (limit), \ + .limit1 = ((limit) >> 16) & 0x0F, \ + .base0 = (u16) (base), \ + .base1 = ((base) >> 16) & 0xFF, \ + .base2 = ((base) >> 24) & 0xFF, \ + .type = (flags & 0x0f), \ + .s = (flags >> 4) & 0x01, \ + .dpl = (flags >> 5) & 0x03, \ + .p = (flags >> 7) & 0x01, \ + .avl = (flags >> 12) & 0x01, \ + .l = (flags >> 13) & 0x01, \ + .d = (flags >> 14) & 0x01, \ + .g = (flags >> 15) & 0x01, \ + } enum { GATE_INTERRUPT = 0xE, @@ -47,49 +44,63 @@ enum { GATE_TASK = 0x5, }; -/* 16byte gate */ -struct gate_struct64 { - u16 offset_low; - u16 segment; - unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; - u16 offset_middle; - u32 offset_high; - u32 zero1; -} __attribute__((packed)); - -#define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF) -#define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH(x) ((unsigned long long)(x) >> 32) - enum { DESC_TSS = 0x9, DESC_LDT = 0x2, DESCTYPE_S = 0x10, /* !system */ }; -/* LDT or TSS descriptor in the GDT. 16 bytes. */ -struct ldttss_desc64 { - u16 limit0; - u16 base0; - unsigned base1 : 8, type : 5, dpl : 2, p : 1; - unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; - u32 base3; - u32 zero1; +/* LDT or TSS descriptor in the GDT. */ +struct ldttss_desc { + u16 limit0; + u16 base0; + + u16 base1 : 8, type : 5, dpl : 2, p : 1; + u16 limit1 : 4, zero0 : 3, g : 1, base2 : 8; +#ifdef CONFIG_X86_64 + u32 base3; + u32 zero1; +#endif } __attribute__((packed)); +typedef struct ldttss_desc ldt_desc; +typedef struct ldttss_desc tss_desc; + +struct idt_bits { + u16 ist : 3, + zero : 5, + type : 5, + dpl : 2, + p : 1; +} __attribute__((packed)); + +struct gate_struct { + u16 offset_low; + u16 segment; + struct idt_bits bits; + u16 offset_middle; #ifdef CONFIG_X86_64 -typedef struct gate_struct64 gate_desc; -typedef struct ldttss_desc64 ldt_desc; -typedef struct ldttss_desc64 tss_desc; -#define gate_offset(g) ((g).offset_low | ((unsigned long)(g).offset_middle << 16) | ((unsigned long)(g).offset_high << 32)) -#define gate_segment(g) ((g).segment) -#else -typedef struct desc_struct gate_desc; -typedef struct desc_struct ldt_desc; -typedef struct desc_struct tss_desc; -#define gate_offset(g) (((g).b & 0xffff0000) | ((g).a & 0x0000ffff)) -#define gate_segment(g) ((g).a >> 16) + u32 offset_high; + u32 reserved; #endif +} __attribute__((packed)); + +typedef struct gate_struct gate_desc; + +static inline unsigned long gate_offset(const gate_desc *g) +{ +#ifdef CONFIG_X86_64 + return g->offset_low | ((unsigned long)g->offset_middle << 16) | + ((unsigned long) g->offset_high << 32); +#else + return g->offset_low | ((unsigned long)g->offset_middle << 16); +#endif +} + +static inline unsigned long gate_segment(const gate_desc *g) +{ + return g->segment; +} struct desc_ptr { unsigned short size; diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h index 1b3ef26e77df..5e12c63b47aa 100644 --- a/arch/x86/include/asm/device.h +++ b/arch/x86/include/asm/device.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DEVICE_H #define _ASM_X86_DEVICE_H diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index 5dff775af7cd..c10c9128f54e 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -21,11 +21,13 @@ # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31)) # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31)) # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) +# define DISABLE_PCID 0 #else # define DISABLE_VME 0 # define DISABLE_K6_MTRR 0 # define DISABLE_CYRIX_ARR 0 # define DISABLE_CENTAUR_MCR 0 +# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31)) #endif /* CONFIG_X86_64 */ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS @@ -49,7 +51,7 @@ #define DISABLED_MASK1 0 #define DISABLED_MASK2 0 #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) -#define DISABLED_MASK4 0 +#define DISABLED_MASK4 (DISABLE_PCID) #define DISABLED_MASK5 0 #define DISABLED_MASK6 0 #define DISABLED_MASK7 0 diff --git a/arch/x86/include/asm/div64.h b/arch/x86/include/asm/div64.h index af95c47d5c9e..20a46150e0a8 100644 --- a/arch/x86/include/asm/div64.h +++ b/arch/x86/include/asm/div64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DIV64_H #define _ASM_X86_DIV64_H diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 398c79889f5c..836ca1178a6a 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DMA_MAPPING_H #define _ASM_X86_DMA_MAPPING_H @@ -12,6 +13,7 @@ #include #include #include +#include #ifdef CONFIG_ISA # define ISA_DMA_BIT_MASK DMA_BIT_MASK(24) @@ -57,12 +59,12 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { - return paddr; + return __sme_set(paddr); } static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) { - return daddr; + return __sme_clr(daddr); } #endif /* CONFIG_X86_DMA_REMAP */ diff --git a/arch/x86/include/asm/dma.h b/arch/x86/include/asm/dma.h index fe884e18fa6e..00f7cf45e699 100644 --- a/arch/x86/include/asm/dma.h +++ b/arch/x86/include/asm/dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/include/asm/dma.h: Defines for using and allocating dma channels. * Written by Hennus Bergman, 1992. diff --git a/arch/x86/include/asm/dmi.h b/arch/x86/include/asm/dmi.h index 3c69fed215c5..0ab2ab27ad1f 100644 --- a/arch/x86/include/asm/dmi.h +++ b/arch/x86/include/asm/dmi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DMI_H #define _ASM_X86_DMI_H @@ -13,9 +14,9 @@ static __always_inline __init void *dmi_alloc(unsigned len) } /* Use early IO mappings for DMI because it's initialized early */ -#define dmi_early_remap early_ioremap -#define dmi_early_unmap early_iounmap -#define dmi_remap ioremap_cache -#define dmi_unmap iounmap +#define dmi_early_remap early_memremap +#define dmi_early_unmap early_memunmap +#define dmi_remap(_x, _l) memremap(_x, _l, MEMREMAP_WB) +#define dmi_unmap(_x) memunmap(_x) #endif /* _ASM_X86_DMI_H */ diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h index b7a1ab865d68..ae391f609840 100644 --- a/arch/x86/include/asm/dwarf2.h +++ b/arch/x86/include/asm/dwarf2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_DWARF2_H #define _ASM_X86_DWARF2_H diff --git a/arch/x86/include/asm/e820/api.h b/arch/x86/include/asm/e820/api.h index a504adc661a4..62be73b23d5c 100644 --- a/arch/x86/include/asm/e820/api.h +++ b/arch/x86/include/asm/e820/api.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_E820_API_H #define _ASM_E820_API_H @@ -39,6 +40,8 @@ extern void e820__setup_pci_gap(void); extern void e820__reallocate_tables(void); extern void e820__register_nosave_regions(unsigned long limit_pfn); +extern int e820__get_entry_type(u64 start, u64 end); + /* * Returns true iff the specified range [start,end) is completely contained inside * the ISA region. diff --git a/arch/x86/include/asm/e820/types.h b/arch/x86/include/asm/e820/types.h index 4adeed03a9a1..c3aa4b5e49e2 100644 --- a/arch/x86/include/asm/e820/types.h +++ b/arch/x86/include/asm/e820/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_E820_TYPES_H #define _ASM_E820_TYPES_H diff --git a/arch/x86/include/asm/edac.h b/arch/x86/include/asm/edac.h index cf8fdf83b231..426fc53ff803 100644 --- a/arch/x86/include/asm/edac.h +++ b/arch/x86/include/asm/edac.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_EDAC_H #define _ASM_X86_EDAC_H diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 796ff6c1aa53..85f6ccb80b91 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_EFI_H #define _ASM_X86_EFI_H diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h index 9aeb91935ce0..3a091cea36c5 100644 --- a/arch/x86/include/asm/elf.h +++ b/arch/x86/include/asm/elf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ELF_H #define _ASM_X86_ELF_H @@ -126,15 +127,15 @@ do { \ pr_reg[4] = regs->di; \ pr_reg[5] = regs->bp; \ pr_reg[6] = regs->ax; \ - pr_reg[7] = regs->ds & 0xffff; \ - pr_reg[8] = regs->es & 0xffff; \ - pr_reg[9] = regs->fs & 0xffff; \ + pr_reg[7] = regs->ds; \ + pr_reg[8] = regs->es; \ + pr_reg[9] = regs->fs; \ pr_reg[11] = regs->orig_ax; \ pr_reg[12] = regs->ip; \ - pr_reg[13] = regs->cs & 0xffff; \ + pr_reg[13] = regs->cs; \ pr_reg[14] = regs->flags; \ pr_reg[15] = regs->sp; \ - pr_reg[16] = regs->ss & 0xffff; \ + pr_reg[16] = regs->ss; \ } while (0); #define ELF_CORE_COPY_REGS(pr_reg, regs) \ @@ -204,6 +205,7 @@ void set_personality_ia32(bool); #define ELF_CORE_COPY_REGS(pr_reg, regs) \ do { \ + unsigned long base; \ unsigned v; \ (pr_reg)[0] = (regs)->r15; \ (pr_reg)[1] = (regs)->r14; \ @@ -226,8 +228,8 @@ do { \ (pr_reg)[18] = (regs)->flags; \ (pr_reg)[19] = (regs)->sp; \ (pr_reg)[20] = (regs)->ss; \ - (pr_reg)[21] = current->thread.fsbase; \ - (pr_reg)[22] = current->thread.gsbase; \ + rdmsrl(MSR_FS_BASE, base); (pr_reg)[21] = base; \ + rdmsrl(MSR_KERNEL_GS_BASE, base); (pr_reg)[22] = base; \ asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \ asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \ asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \ @@ -251,7 +253,7 @@ extern int force_personality32; * space open for things that want to use the area for 32-bit pointers. */ #define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \ - (TASK_SIZE / 3 * 2)) + (DEFAULT_MAP_WINDOW / 3 * 2)) /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This could be done in user space, @@ -304,8 +306,8 @@ static inline int mmap_is_ia32(void) test_thread_flag(TIF_ADDR32)); } -extern unsigned long tasksize_32bit(void); -extern unsigned long tasksize_64bit(void); +extern unsigned long task_size_32bit(void); +extern unsigned long task_size_64bit(int full_addr_space); extern unsigned long get_mmap_base(int is_legacy); #ifdef CONFIG_X86_32 diff --git a/arch/x86/include/asm/emergency-restart.h b/arch/x86/include/asm/emergency-restart.h index 77a99ac06d00..2abde717db31 100644 --- a/arch/x86/include/asm/emergency-restart.h +++ b/arch/x86/include/asm/emergency-restart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_EMERGENCY_RESTART_H #define _ASM_X86_EMERGENCY_RESTART_H diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index 07b06955a05d..416422762845 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is designed to contain the BUILD_INTERRUPT specifications for * all of the extra named interrupt vectors used by the architecture. @@ -13,20 +14,14 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) -BUILD_INTERRUPT3(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR, - smp_irq_move_cleanup_interrupt) -BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt) +BUILD_INTERRUPT(irq_move_cleanup_interrupt, IRQ_MOVE_CLEANUP_VECTOR) +BUILD_INTERRUPT(reboot_interrupt, REBOOT_VECTOR) #endif -BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) - #ifdef CONFIG_HAVE_KVM -BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR, - smp_kvm_posted_intr_ipi) -BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR, - smp_kvm_posted_intr_wakeup_ipi) -BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR, - smp_kvm_posted_intr_nested_ipi) +BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR) +BUILD_INTERRUPT(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR) #endif /* @@ -41,6 +36,7 @@ BUILD_INTERRUPT3(kvm_posted_intr_nested_ipi, POSTED_INTR_NESTED_VECTOR, BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) +BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) #ifdef CONFIG_IRQ_WORK BUILD_INTERRUPT(irq_work_interrupt, IRQ_WORK_VECTOR) diff --git a/arch/x86/include/asm/espfix.h b/arch/x86/include/asm/espfix.h index ca3ce9ab9385..0211029076ea 100644 --- a/arch/x86/include/asm/espfix.h +++ b/arch/x86/include/asm/espfix.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ESPFIX_H #define _ASM_X86_ESPFIX_H diff --git a/arch/x86/include/asm/export.h b/arch/x86/include/asm/export.h index 138de56b13eb..2a51d66689c5 100644 --- a/arch/x86/include/asm/export.h +++ b/arch/x86/include/asm/export.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_64BIT #define KSYM_ALIGN 16 #endif diff --git a/arch/x86/include/asm/extable.h b/arch/x86/include/asm/extable.h index c66d19e3c23e..f9c3a5d502f4 100644 --- a/arch/x86/include/asm/extable.h +++ b/arch/x86/include/asm/extable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_EXTABLE_H #define _ASM_X86_EXTABLE_H /* diff --git a/arch/x86/include/asm/fb.h b/arch/x86/include/asm/fb.h index c3dd5e71f439..ab4c960146e3 100644 --- a/arch/x86/include/asm/fb.h +++ b/arch/x86/include/asm/fb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_FB_H #define _ASM_X86_FB_H diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index b65155cc3760..dcd9fb55e679 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -157,6 +157,26 @@ static inline void __set_fixmap(enum fixed_addresses idx, } #endif +/* + * FIXMAP_PAGE_NOCACHE is used for MMIO. Memory encryption is not + * supported for MMIO addresses, so make sure that the memory encryption + * mask is not part of the page attributes. + */ +#define FIXMAP_PAGE_NOCACHE PAGE_KERNEL_IO_NOCACHE + +/* + * Early memremap routines used for in-place encryption. The mappings created + * by these routines are intended to be used as temporary mappings. + */ +void __init *early_memremap_encrypted(resource_size_t phys_addr, + unsigned long size); +void __init *early_memremap_encrypted_wp(resource_size_t phys_addr, + unsigned long size); +void __init *early_memremap_decrypted(resource_size_t phys_addr, + unsigned long size); +void __init *early_memremap_decrypted_wp(resource_size_t phys_addr, + unsigned long size); + #include #define __late_set_fixmap(idx, phys, flags) __set_fixmap(idx, phys, flags) diff --git a/arch/x86/include/asm/fpu/api.h b/arch/x86/include/asm/fpu/api.h index 0877ae018fc9..a9caac9d4a72 100644 --- a/arch/x86/include/asm/fpu/api.h +++ b/arch/x86/include/asm/fpu/api.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1994 Linus Torvalds * diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 554cdb205d17..a38bf5a1e37a 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1994 Linus Torvalds * @@ -23,11 +24,9 @@ /* * High level FPU state handling functions: */ -extern void fpu__activate_curr(struct fpu *fpu); -extern void fpu__activate_fpstate_read(struct fpu *fpu); -extern void fpu__activate_fpstate_write(struct fpu *fpu); -extern void fpu__current_fpstate_write_begin(void); -extern void fpu__current_fpstate_write_end(void); +extern void fpu__initialize(struct fpu *fpu); +extern void fpu__prepare_read(struct fpu *fpu); +extern void fpu__prepare_write(struct fpu *fpu); extern void fpu__save(struct fpu *fpu); extern void fpu__restore(struct fpu *fpu); extern int fpu__restore_sig(void __user *buf, int ia32_frame); @@ -120,20 +119,11 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu); err; \ }) -#define check_insn(insn, output, input...) \ -({ \ - int err; \ +#define kernel_insn(insn, output, input...) \ asm volatile("1:" #insn "\n\t" \ "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: movl $-1,%[err]\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err), output \ - : "0"(0), input); \ - err; \ -}) + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_fprestore) \ + : output : input) static inline int copy_fregs_to_user(struct fregs_state __user *fx) { @@ -153,20 +143,16 @@ static inline int copy_fxregs_to_user(struct fxregs_state __user *fx) static inline void copy_kernel_to_fxregs(struct fxregs_state *fx) { - int err; - if (IS_ENABLED(CONFIG_X86_32)) { - err = check_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx)); + kernel_insn(fxrstor %[fx], "=m" (*fx), [fx] "m" (*fx)); } else { if (IS_ENABLED(CONFIG_AS_FXSAVEQ)) { - err = check_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx)); + kernel_insn(fxrstorq %[fx], "=m" (*fx), [fx] "m" (*fx)); } else { /* See comment in copy_fxregs_to_kernel() below. */ - err = check_insn(rex64/fxrstor (%[fx]), "=m" (*fx), [fx] "R" (fx), "m" (*fx)); + kernel_insn(rex64/fxrstor (%[fx]), "=m" (*fx), [fx] "R" (fx), "m" (*fx)); } } - /* Copying from a kernel buffer to FPU registers should never fail: */ - WARN_ON_FPU(err); } static inline int copy_user_to_fxregs(struct fxregs_state __user *fx) @@ -183,9 +169,7 @@ static inline int copy_user_to_fxregs(struct fxregs_state __user *fx) static inline void copy_kernel_to_fregs(struct fregs_state *fx) { - int err = check_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx)); - - WARN_ON_FPU(err); + kernel_insn(frstor %[fx], "=m" (*fx), [fx] "m" (*fx)); } static inline int copy_user_to_fregs(struct fregs_state __user *fx) @@ -281,18 +265,13 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact * XSAVE area format. */ -#define XSTATE_XRESTORE(st, lmask, hmask, err) \ +#define XSTATE_XRESTORE(st, lmask, hmask) \ asm volatile(ALTERNATIVE(XRSTOR, \ XRSTORS, X86_FEATURE_XSAVES) \ "\n" \ - "xor %[err], %[err]\n" \ "3:\n" \ - ".pushsection .fixup,\"ax\"\n" \ - "4: movl $-2, %[err]\n" \ - "jmp 3b\n" \ - ".popsection\n" \ - _ASM_EXTABLE(661b, 4b) \ - : [err] "=r" (err) \ + _ASM_EXTABLE_HANDLE(661b, 3b, ex_handler_fprestore)\ + : \ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ : "memory") @@ -336,7 +315,10 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate) else XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); - /* We should never fault when copying from a kernel buffer: */ + /* + * We should never fault when copying from a kernel buffer, and the FPU + * state we set at boot time should be valid. + */ WARN_ON_FPU(err); } @@ -350,7 +332,7 @@ static inline void copy_xregs_to_kernel(struct xregs_state *xstate) u32 hmask = mask >> 32; int err; - WARN_ON(!alternatives_patched); + WARN_ON_FPU(!alternatives_patched); XSTATE_XSAVE(xstate, lmask, hmask, err); @@ -365,12 +347,8 @@ static inline void copy_kernel_to_xregs(struct xregs_state *xstate, u64 mask) { u32 lmask = mask; u32 hmask = mask >> 32; - int err; - XSTATE_XRESTORE(xstate, lmask, hmask, err); - - /* We should never fault when copying from a kernel buffer: */ - WARN_ON_FPU(err); + XSTATE_XRESTORE(xstate, lmask, hmask); } /* @@ -526,37 +504,16 @@ static inline int fpregs_state_valid(struct fpu *fpu, unsigned int cpu) */ static inline void fpregs_deactivate(struct fpu *fpu) { - WARN_ON_FPU(!fpu->fpregs_active); - - fpu->fpregs_active = 0; this_cpu_write(fpu_fpregs_owner_ctx, NULL); trace_x86_fpu_regs_deactivated(fpu); } static inline void fpregs_activate(struct fpu *fpu) { - WARN_ON_FPU(fpu->fpregs_active); - - fpu->fpregs_active = 1; this_cpu_write(fpu_fpregs_owner_ctx, fpu); trace_x86_fpu_regs_activated(fpu); } -/* - * The question "does this thread have fpu access?" - * is slightly racy, since preemption could come in - * and revoke it immediately after the test. - * - * However, even in that very unlikely scenario, - * we can just assume we have FPU access - typically - * to save the FP state - we'll just take a #NM - * fault and get the FPU access back. - */ -static inline int fpregs_active(void) -{ - return current->thread.fpu.fpregs_active; -} - /* * FPU state switching for scheduling. * @@ -571,14 +528,13 @@ static inline int fpregs_active(void) static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu) { - if (old_fpu->fpregs_active) { + if (old_fpu->initialized) { if (!copy_fpregs_to_fpstate(old_fpu)) old_fpu->last_cpu = -1; else old_fpu->last_cpu = cpu; /* But leave fpu_fpregs_owner_ctx! */ - old_fpu->fpregs_active = 0; trace_x86_fpu_regs_deactivated(old_fpu); } else old_fpu->last_cpu = -1; @@ -595,7 +551,7 @@ switch_fpu_prepare(struct fpu *old_fpu, int cpu) static inline void switch_fpu_finish(struct fpu *new_fpu, int cpu) { bool preload = static_cpu_has(X86_FEATURE_FPU) && - new_fpu->fpstate_active; + new_fpu->initialized; if (preload) { if (!fpregs_state_valid(new_fpu, cpu)) @@ -617,8 +573,7 @@ static inline void user_fpu_begin(void) struct fpu *fpu = ¤t->thread.fpu; preempt_disable(); - if (!fpregs_active()) - fpregs_activate(fpu); + fpregs_activate(fpu); preempt_enable(); } diff --git a/arch/x86/include/asm/fpu/regset.h b/arch/x86/include/asm/fpu/regset.h index 39d3107ac6c7..d5bdffb9d27f 100644 --- a/arch/x86/include/asm/fpu/regset.h +++ b/arch/x86/include/asm/fpu/regset.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * FPU regset handling methods: */ diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/signal.h index 20a1fbf7fe4e..4df2754ef380 100644 --- a/arch/x86/include/asm/fpu/signal.h +++ b/arch/x86/include/asm/fpu/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * x86 FPU signal frame handling methods: */ diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h index 3c80f5b9c09d..202c53918ecf 100644 --- a/arch/x86/include/asm/fpu/types.h +++ b/arch/x86/include/asm/fpu/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * FPU data structures: */ @@ -68,6 +69,9 @@ struct fxregs_state { /* Default value for fxregs_state.mxcsr: */ #define MXCSR_DEFAULT 0x1f80 +/* Copy both mxcsr & mxcsr_flags with a single u64 memcpy: */ +#define MXCSR_AND_FLAGS_SIZE sizeof(u64) + /* * Software based FPU emulation state. This is arbitrary really, * it matches the x87 format to make it easier to understand: @@ -290,36 +294,13 @@ struct fpu { unsigned int last_cpu; /* - * @fpstate_active: + * @initialized: * - * This flag indicates whether this context is active: if the task + * This flag indicates whether this context is initialized: if the task * is not running then we can restore from this context, if the task * is running then we should save into this context. */ - unsigned char fpstate_active; - - /* - * @fpregs_active: - * - * This flag determines whether a given context is actively - * loaded into the FPU's registers and that those registers - * represent the task's current FPU state. - * - * Note the interaction with fpstate_active: - * - * # task does not use the FPU: - * fpstate_active == 0 - * - * # task uses the FPU and regs are active: - * fpstate_active == 1 && fpregs_active == 1 - * - * # the regs are inactive but still match fpstate: - * fpstate_active == 1 && fpregs_active == 0 && fpregs_owner == fpu - * - * The third state is what we use for the lazy restore optimization - * on lazy-switching CPUs. - */ - unsigned char fpregs_active; + unsigned char initialized; /* * @state: diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index 1b2799e0699a..48581988d78c 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_X86_XSAVE_H #define __ASM_X86_XSAVE_H @@ -48,8 +49,12 @@ void fpu__xstate_clear_all_cpu_caps(void); void *get_xsave_addr(struct xregs_state *xsave, int xstate); const void *get_xsave_field_ptr(int xstate_field); int using_compacted_format(void); -int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, - void __user *ubuf, struct xregs_state *xsave); -int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, - struct xregs_state *xsave); +int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset, unsigned int size); +int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset, unsigned int size); +int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf); +int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf); + +/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ +extern int validate_xstate_header(const struct xstate_header *hdr); + #endif diff --git a/arch/x86/include/asm/frame.h b/arch/x86/include/asm/frame.h index 6e4d170726b7..5cbce6fbb534 100644 --- a/arch/x86/include/asm/frame.h +++ b/arch/x86/include/asm/frame.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_FRAME_H #define _ASM_X86_FRAME_H diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index eccd0ac6bc38..09ad88572746 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_FTRACE_H #define _ASM_X86_FTRACE_H diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h index b4c1f5453436..de4d68852d3a 100644 --- a/arch/x86/include/asm/futex.h +++ b/arch/x86/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_FUTEX_H #define _ASM_X86_FUTEX_H @@ -41,20 +42,11 @@ "+m" (*uaddr), "=&r" (tem) \ : "r" (oparg), "i" (-EFAULT), "1" (0)) -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tem; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -80,30 +72,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/x86/include/asm/gart.h b/arch/x86/include/asm/gart.h index 1d268098ac2e..318556574345 100644 --- a/arch/x86/include/asm/gart.h +++ b/arch/x86/include/asm/gart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_GART_H #define _ASM_X86_GART_H diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index ad1ed531febc..51cc979dd364 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HARDIRQ_H #define _ASM_X86_HARDIRQ_H diff --git a/arch/x86/include/asm/highmem.h b/arch/x86/include/asm/highmem.h index 1c0b43724ce3..a8059930056d 100644 --- a/arch/x86/include/asm/highmem.h +++ b/arch/x86/include/asm/highmem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * highmem.h: virtual kernel memory mappings for high memory * diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index cc285ec4b2c1..67385d56d4f4 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HPET_H #define _ASM_X86_HPET_H diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h index 535af0f2d8ac..5ed826da5e07 100644 --- a/arch/x86/include/asm/hugetlb.h +++ b/arch/x86/include/asm/hugetlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HUGETLB_H #define _ASM_X86_HUGETLB_H diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index 6c98be864a75..f59c39835a5a 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _I386_HW_BREAKPOINT_H #define _I386_HW_BREAKPOINT_H diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index d6dbafbd4207..8ec99a55e6b9 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HW_IRQ_H #define _ASM_X86_HW_IRQ_H @@ -46,26 +47,6 @@ extern asmlinkage void deferred_error_interrupt(void); extern asmlinkage void call_function_interrupt(void); extern asmlinkage void call_function_single_interrupt(void); -#ifdef CONFIG_TRACING -/* Interrupt handlers registered during init_IRQ */ -extern void trace_apic_timer_interrupt(void); -extern void trace_x86_platform_ipi(void); -extern void trace_error_interrupt(void); -extern void trace_irq_work_interrupt(void); -extern void trace_spurious_interrupt(void); -extern void trace_thermal_interrupt(void); -extern void trace_reschedule_interrupt(void); -extern void trace_threshold_interrupt(void); -extern void trace_deferred_error_interrupt(void); -extern void trace_call_function_interrupt(void); -extern void trace_call_function_single_interrupt(void); -#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt -#define trace_reboot_interrupt reboot_interrupt -#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi -#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi -#define trace_kvm_posted_intr_nested_ipi kvm_posted_intr_nested_ipi -#endif /* CONFIG_TRACING */ - #ifdef CONFIG_X86_LOCAL_APIC struct irq_data; struct pci_dev; diff --git a/arch/x86/include/asm/hypertransport.h b/arch/x86/include/asm/hypertransport.h index 334b1a885d9c..5d55df352879 100644 --- a/arch/x86/include/asm/hypertransport.h +++ b/arch/x86/include/asm/hypertransport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HYPERTRANSPORT_H #define _ASM_X86_HYPERTRANSPORT_H diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h index 39bcefc20de7..c8376b40e882 100644 --- a/arch/x86/include/asm/i8259.h +++ b/arch/x86/include/asm/i8259.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_I8259_H #define _ASM_X86_I8259_H diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h index a9bdf5569ab3..2c5f7861d373 100644 --- a/arch/x86/include/asm/ia32.h +++ b/arch/x86/include/asm/ia32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IA32_H #define _ASM_X86_IA32_H diff --git a/arch/x86/include/asm/ia32_unistd.h b/arch/x86/include/asm/ia32_unistd.h index b0d5716ca1e4..aa065c94ccf5 100644 --- a/arch/x86/include/asm/ia32_unistd.h +++ b/arch/x86/include/asm/ia32_unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IA32_UNISTD_H #define _ASM_X86_IA32_UNISTD_H diff --git a/arch/x86/include/asm/init.h b/arch/x86/include/asm/init.h index 474eb8c66fee..5f1d3c421f68 100644 --- a/arch/x86/include/asm/init.h +++ b/arch/x86/include/asm/init.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_INIT_H #define _ASM_X86_INIT_H @@ -7,6 +8,7 @@ struct x86_mapping_info { unsigned long page_flag; /* page flag for PMD or PUD entry */ unsigned long offset; /* ident mapping offset */ bool direct_gbpages; /* PUD level 1GB page support */ + unsigned long kernpg_flag; /* kernel pagetable flag override */ }; int kernel_ident_mapping_init(struct x86_mapping_info *info, pgd_t *pgd_page, diff --git a/arch/x86/include/asm/inst.h b/arch/x86/include/asm/inst.h index 3e115273ed88..f5a796da07f8 100644 --- a/arch/x86/include/asm/inst.h +++ b/arch/x86/include/asm/inst.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Generate .byte code for some instructions not supported by old * binutils. diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 75b748a1deb8..35a6bc4da8ad 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_INTEL_FAMILY_H #define _ASM_X86_INTEL_FAMILY_H diff --git a/arch/x86/include/asm/intel_mid_vrtc.h b/arch/x86/include/asm/intel_mid_vrtc.h index 86ff4685c409..35555016b1be 100644 --- a/arch/x86/include/asm/intel_mid_vrtc.h +++ b/arch/x86/include/asm/intel_mid_vrtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _INTEL_MID_VRTC_H #define _INTEL_MID_VRTC_H diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h index fac89eb78a6b..528ed4be4393 100644 --- a/arch/x86/include/asm/intel_pmc_ipc.h +++ b/arch/x86/include/asm/intel_pmc_ipc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_INTEL_PMC_IPC_H_ #define _ASM_X86_INTEL_PMC_IPC_H_ diff --git a/arch/x86/include/asm/intel_pt.h b/arch/x86/include/asm/intel_pt.h index e1a411786bf5..b523f51c5400 100644 --- a/arch/x86/include/asm/intel_pt.h +++ b/arch/x86/include/asm/intel_pt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_INTEL_PT_H #define _ASM_X86_INTEL_PT_H diff --git a/arch/x86/include/asm/intel_punit_ipc.h b/arch/x86/include/asm/intel_punit_ipc.h index 201eb9dce595..ce16da719596 100644 --- a/arch/x86/include/asm/intel_punit_ipc.h +++ b/arch/x86/include/asm/intel_punit_ipc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_INTEL_PUNIT_IPC_H_ #define _ASM_X86_INTEL_PUNIT_IPC_H_ diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h deleted file mode 100644 index 597dc4995678..000000000000 --- a/arch/x86/include/asm/intel_rdt.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef _ASM_X86_INTEL_RDT_H -#define _ASM_X86_INTEL_RDT_H - -#ifdef CONFIG_INTEL_RDT_A - -#include -#include -#include - -#include - -#define IA32_L3_QOS_CFG 0xc81 -#define IA32_L3_CBM_BASE 0xc90 -#define IA32_L2_CBM_BASE 0xd10 -#define IA32_MBA_THRTL_BASE 0xd50 - -#define L3_QOS_CDP_ENABLE 0x01ULL - -/** - * struct rdtgroup - store rdtgroup's data in resctrl file system. - * @kn: kernfs node - * @rdtgroup_list: linked list for all rdtgroups - * @closid: closid for this rdtgroup - * @cpu_mask: CPUs assigned to this rdtgroup - * @flags: status bits - * @waitcount: how many cpus expect to find this - * group when they acquire rdtgroup_mutex - */ -struct rdtgroup { - struct kernfs_node *kn; - struct list_head rdtgroup_list; - int closid; - struct cpumask cpu_mask; - int flags; - atomic_t waitcount; -}; - -/* rdtgroup.flags */ -#define RDT_DELETED 1 - -/* rftype.flags */ -#define RFTYPE_FLAGS_CPUS_LIST 1 - -/* List of all resource groups */ -extern struct list_head rdt_all_groups; - -extern int max_name_width, max_data_width; - -int __init rdtgroup_init(void); - -/** - * struct rftype - describe each file in the resctrl file system - * @name: File name - * @mode: Access mode - * @kf_ops: File operations - * @flags: File specific RFTYPE_FLAGS_* flags - * @seq_show: Show content of the file - * @write: Write to the file - */ -struct rftype { - char *name; - umode_t mode; - struct kernfs_ops *kf_ops; - unsigned long flags; - - int (*seq_show)(struct kernfs_open_file *of, - struct seq_file *sf, void *v); - /* - * write() is the generic write callback which maps directly to - * kernfs write operation and overrides all other operations. - * Maximum write size is determined by ->max_write_len. - */ - ssize_t (*write)(struct kernfs_open_file *of, - char *buf, size_t nbytes, loff_t off); -}; - -/** - * struct rdt_domain - group of cpus sharing an RDT resource - * @list: all instances of this resource - * @id: unique id for this instance - * @cpu_mask: which cpus share this resource - * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) - * @new_ctrl: new ctrl value to be loaded - * @have_new_ctrl: did user provide new_ctrl for this domain - */ -struct rdt_domain { - struct list_head list; - int id; - struct cpumask cpu_mask; - u32 *ctrl_val; - u32 new_ctrl; - bool have_new_ctrl; -}; - -/** - * struct msr_param - set a range of MSRs from a domain - * @res: The resource to use - * @low: Beginning index from base MSR - * @high: End index - */ -struct msr_param { - struct rdt_resource *res; - int low; - int high; -}; - -/** - * struct rdt_cache - Cache allocation related data - * @cbm_len: Length of the cache bit mask - * @min_cbm_bits: Minimum number of consecutive bits to be set - * @cbm_idx_mult: Multiplier of CBM index - * @cbm_idx_offset: Offset of CBM index. CBM index is computed by: - * closid * cbm_idx_multi + cbm_idx_offset - * in a cache bit mask - */ -struct rdt_cache { - unsigned int cbm_len; - unsigned int min_cbm_bits; - unsigned int cbm_idx_mult; - unsigned int cbm_idx_offset; -}; - -/** - * struct rdt_membw - Memory bandwidth allocation related data - * @max_delay: Max throttle delay. Delay is the hardware - * representation for memory bandwidth. - * @min_bw: Minimum memory bandwidth percentage user can request - * @bw_gran: Granularity at which the memory bandwidth is allocated - * @delay_linear: True if memory B/W delay is in linear scale - * @mb_map: Mapping of memory B/W percentage to memory B/W delay - */ -struct rdt_membw { - u32 max_delay; - u32 min_bw; - u32 bw_gran; - u32 delay_linear; - u32 *mb_map; -}; - -/** - * struct rdt_resource - attributes of an RDT resource - * @enabled: Is this feature enabled on this machine - * @capable: Is this feature available on this machine - * @name: Name to use in "schemata" file - * @num_closid: Number of CLOSIDs available - * @cache_level: Which cache level defines scope of this resource - * @default_ctrl: Specifies default cache cbm or memory B/W percent. - * @msr_base: Base MSR address for CBMs - * @msr_update: Function pointer to update QOS MSRs - * @data_width: Character width of data when displaying - * @domains: All domains for this resource - * @cache: Cache allocation related data - * @info_files: resctrl info files for the resource - * @nr_info_files: Number of info files - * @format_str: Per resource format string to show domain value - * @parse_ctrlval: Per resource function pointer to parse control values - */ -struct rdt_resource { - bool enabled; - bool capable; - char *name; - int num_closid; - int cache_level; - u32 default_ctrl; - unsigned int msr_base; - void (*msr_update) (struct rdt_domain *d, struct msr_param *m, - struct rdt_resource *r); - int data_width; - struct list_head domains; - struct rdt_cache cache; - struct rdt_membw membw; - struct rftype *info_files; - int nr_info_files; - const char *format_str; - int (*parse_ctrlval) (char *buf, struct rdt_resource *r, - struct rdt_domain *d); -}; - -void rdt_get_cache_infofile(struct rdt_resource *r); -void rdt_get_mba_infofile(struct rdt_resource *r); -int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d); -int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d); - -extern struct mutex rdtgroup_mutex; - -extern struct rdt_resource rdt_resources_all[]; -extern struct rdtgroup rdtgroup_default; -DECLARE_STATIC_KEY_FALSE(rdt_enable_key); - -int __init rdtgroup_init(void); - -enum { - RDT_RESOURCE_L3, - RDT_RESOURCE_L3DATA, - RDT_RESOURCE_L3CODE, - RDT_RESOURCE_L2, - RDT_RESOURCE_MBA, - - /* Must be the last */ - RDT_NUM_RESOURCES, -}; - -#define for_each_capable_rdt_resource(r) \ - for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ - r++) \ - if (r->capable) - -#define for_each_enabled_rdt_resource(r) \ - for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ - r++) \ - if (r->enabled) - -/* CPUID.(EAX=10H, ECX=ResID=1).EAX */ -union cpuid_0x10_1_eax { - struct { - unsigned int cbm_len:5; - } split; - unsigned int full; -}; - -/* CPUID.(EAX=10H, ECX=ResID=3).EAX */ -union cpuid_0x10_3_eax { - struct { - unsigned int max_delay:12; - } split; - unsigned int full; -}; - -/* CPUID.(EAX=10H, ECX=ResID).EDX */ -union cpuid_0x10_x_edx { - struct { - unsigned int cos_max:16; - } split; - unsigned int full; -}; - -DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid); - -void rdt_ctrl_update(void *arg); -struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); -void rdtgroup_kn_unlock(struct kernfs_node *kn); -ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, - char *buf, size_t nbytes, loff_t off); -int rdtgroup_schemata_show(struct kernfs_open_file *of, - struct seq_file *s, void *v); - -/* - * intel_rdt_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR - * - * Following considerations are made so that this has minimal impact - * on scheduler hot path: - * - This will stay as no-op unless we are running on an Intel SKU - * which supports resource control and we enable by mounting the - * resctrl file system. - * - Caches the per cpu CLOSid values and does the MSR write only - * when a task with a different CLOSid is scheduled in. - * - * Must be called with preemption disabled. - */ -static inline void intel_rdt_sched_in(void) -{ - if (static_branch_likely(&rdt_enable_key)) { - struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - int closid; - - /* - * If this task has a closid assigned, use it. - * Else use the closid assigned to this cpu. - */ - closid = current->closid; - if (closid == 0) - closid = this_cpu_read(cpu_closid); - - if (closid != state->closid) { - state->closid = closid; - wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, closid); - } - } -} - -#else - -static inline void intel_rdt_sched_in(void) {} - -#endif /* CONFIG_INTEL_RDT_A */ -#endif /* _ASM_X86_INTEL_RDT_H */ diff --git a/arch/x86/include/asm/intel_rdt_common.h b/arch/x86/include/asm/intel_rdt_common.h deleted file mode 100644 index b31081b89407..000000000000 --- a/arch/x86/include/asm/intel_rdt_common.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _ASM_X86_INTEL_RDT_COMMON_H -#define _ASM_X86_INTEL_RDT_COMMON_H - -#define MSR_IA32_PQR_ASSOC 0x0c8f - -/** - * struct intel_pqr_state - State cache for the PQR MSR - * @rmid: The cached Resource Monitoring ID - * @closid: The cached Class Of Service ID - * @rmid_usecnt: The usage counter for rmid - * - * The upper 32 bits of MSR_IA32_PQR_ASSOC contain closid and the - * lower 10 bits rmid. The update to MSR_IA32_PQR_ASSOC always - * contains both parts, so we need to cache them. - * - * The cache also helps to avoid pointless updates if the value does - * not change. - */ -struct intel_pqr_state { - u32 rmid; - u32 closid; - int rmid_usecnt; -}; - -DECLARE_PER_CPU(struct intel_pqr_state, pqr_state); - -#endif /* _ASM_X86_INTEL_RDT_COMMON_H */ diff --git a/arch/x86/include/asm/intel_rdt_sched.h b/arch/x86/include/asm/intel_rdt_sched.h new file mode 100644 index 000000000000..9acb06b6f81e --- /dev/null +++ b/arch/x86/include/asm/intel_rdt_sched.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_INTEL_RDT_SCHED_H +#define _ASM_X86_INTEL_RDT_SCHED_H + +#ifdef CONFIG_INTEL_RDT + +#include +#include + +#define IA32_PQR_ASSOC 0x0c8f + +/** + * struct intel_pqr_state - State cache for the PQR MSR + * @cur_rmid: The cached Resource Monitoring ID + * @cur_closid: The cached Class Of Service ID + * @default_rmid: The user assigned Resource Monitoring ID + * @default_closid: The user assigned cached Class Of Service ID + * + * The upper 32 bits of IA32_PQR_ASSOC contain closid and the + * lower 10 bits rmid. The update to IA32_PQR_ASSOC always + * contains both parts, so we need to cache them. This also + * stores the user configured per cpu CLOSID and RMID. + * + * The cache also helps to avoid pointless updates if the value does + * not change. + */ +struct intel_pqr_state { + u32 cur_rmid; + u32 cur_closid; + u32 default_rmid; + u32 default_closid; +}; + +DECLARE_PER_CPU(struct intel_pqr_state, pqr_state); + +DECLARE_STATIC_KEY_FALSE(rdt_enable_key); +DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key); +DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); + +/* + * __intel_rdt_sched_in() - Writes the task's CLOSid/RMID to IA32_PQR_MSR + * + * Following considerations are made so that this has minimal impact + * on scheduler hot path: + * - This will stay as no-op unless we are running on an Intel SKU + * which supports resource control or monitoring and we enable by + * mounting the resctrl file system. + * - Caches the per cpu CLOSid/RMID values and does the MSR write only + * when a task with a different CLOSid/RMID is scheduled in. + * - We allocate RMIDs/CLOSids globally in order to keep this as + * simple as possible. + * Must be called with preemption disabled. + */ +static void __intel_rdt_sched_in(void) +{ + struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); + u32 closid = state->default_closid; + u32 rmid = state->default_rmid; + + /* + * If this task has a closid/rmid assigned, use it. + * Else use the closid/rmid assigned to this cpu. + */ + if (static_branch_likely(&rdt_alloc_enable_key)) { + if (current->closid) + closid = current->closid; + } + + if (static_branch_likely(&rdt_mon_enable_key)) { + if (current->rmid) + rmid = current->rmid; + } + + if (closid != state->cur_closid || rmid != state->cur_rmid) { + state->cur_closid = closid; + state->cur_rmid = rmid; + wrmsr(IA32_PQR_ASSOC, rmid, closid); + } +} + +static inline void intel_rdt_sched_in(void) +{ + if (static_branch_likely(&rdt_enable_key)) + __intel_rdt_sched_in(); +} + +#else + +static inline void intel_rdt_sched_in(void) {} + +#endif /* CONFIG_INTEL_RDT */ + +#endif /* _ASM_X86_INTEL_RDT_SCHED_H */ diff --git a/arch/x86/include/asm/intel_scu_ipc.h b/arch/x86/include/asm/intel_scu_ipc.h index 81d3d8776fd9..4a8c6e817398 100644 --- a/arch/x86/include/asm/intel_scu_ipc.h +++ b/arch/x86/include/asm/intel_scu_ipc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_INTEL_SCU_IPC_H_ #define _ASM_X86_INTEL_SCU_IPC_H_ diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 48febf07e828..11398d55aefa 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IO_H #define _ASM_X86_IO_H @@ -69,6 +70,9 @@ build_mmio_write(__writeb, "b", unsigned char, "q", ) build_mmio_write(__writew, "w", unsigned short, "r", ) build_mmio_write(__writel, "l", unsigned int, "r", ) +#define readb readb +#define readw readw +#define readl readl #define readb_relaxed(a) __readb(a) #define readw_relaxed(a) __readw(a) #define readl_relaxed(a) __readl(a) @@ -76,6 +80,9 @@ build_mmio_write(__writel, "l", unsigned int, "r", ) #define __raw_readw __readw #define __raw_readl __readl +#define writeb writeb +#define writew writew +#define writel writel #define writeb_relaxed(v, a) __writeb(v, a) #define writew_relaxed(v, a) __writew(v, a) #define writel_relaxed(v, a) __writel(v, a) @@ -88,13 +95,15 @@ build_mmio_write(__writel, "l", unsigned int, "r", ) #ifdef CONFIG_X86_64 build_mmio_read(readq, "q", unsigned long, "=r", :"memory") +build_mmio_read(__readq, "q", unsigned long, "=r", ) build_mmio_write(writeq, "q", unsigned long, "r", :"memory") +build_mmio_write(__writeq, "q", unsigned long, "r", ) -#define readq_relaxed(a) readq(a) -#define writeq_relaxed(v, a) writeq(v, a) +#define readq_relaxed(a) __readq(a) +#define writeq_relaxed(v, a) __writeq(v, a) -#define __raw_readq(a) readq(a) -#define __raw_writeq(val, addr) writeq(val, addr) +#define __raw_readq __readq +#define __raw_writeq __writeq /* Let people know that we have them */ #define readq readq @@ -119,6 +128,7 @@ static inline phys_addr_t virt_to_phys(volatile void *address) { return __pa(address); } +#define virt_to_phys virt_to_phys /** * phys_to_virt - map physical address to virtual @@ -137,6 +147,7 @@ static inline void *phys_to_virt(phys_addr_t address) { return __va(address); } +#define phys_to_virt phys_to_virt /* * Change "struct page" to physical address. @@ -169,11 +180,14 @@ static inline unsigned int isa_virt_to_bus(volatile void *address) * else, you probably want one of the following. */ extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size); +#define ioremap_nocache ioremap_nocache extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size); #define ioremap_uc ioremap_uc extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size); +#define ioremap_cache ioremap_cache extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, unsigned long prot_val); +#define ioremap_prot ioremap_prot /** * ioremap - map bus memory into CPU space @@ -193,8 +207,10 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size) { return ioremap_nocache(offset, size); } +#define ioremap ioremap extern void iounmap(volatile void __iomem *addr); +#define iounmap iounmap extern void set_iounmap_nonlazy(void); @@ -202,53 +218,6 @@ extern void set_iounmap_nonlazy(void); #include -/* - * Convert a virtual cached pointer to an uncached pointer - */ -#define xlate_dev_kmem_ptr(p) p - -/** - * memset_io Set a range of I/O memory to a constant value - * @addr: The beginning of the I/O-memory range to set - * @val: The value to set the memory to - * @count: The number of bytes to set - * - * Set a range of I/O memory to a given value. - */ -static inline void -memset_io(volatile void __iomem *addr, unsigned char val, size_t count) -{ - memset((void __force *)addr, val, count); -} - -/** - * memcpy_fromio Copy a block of data from I/O memory - * @dst: The (RAM) destination for the copy - * @src: The (I/O memory) source for the data - * @count: The number of bytes to copy - * - * Copy a block of data from I/O memory. - */ -static inline void -memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count) -{ - memcpy(dst, (const void __force *)src, count); -} - -/** - * memcpy_toio Copy a block of data into I/O memory - * @dst: The (I/O memory) destination for the copy - * @src: The (RAM) source for the data - * @count: The number of bytes to copy - * - * Copy a block of data to I/O memory. - */ -static inline void -memcpy_toio(volatile void __iomem *dst, const void *src, size_t count) -{ - memcpy((void __force *)dst, src, count); -} - /* * ISA space is 'always mapped' on a typical x86 system, no need to * explicitly ioremap() it. The fact that the ISA IO space is mapped @@ -341,13 +310,38 @@ BUILDIO(b, b, char) BUILDIO(w, w, short) BUILDIO(l, , int) +#define inb inb +#define inw inw +#define inl inl +#define inb_p inb_p +#define inw_p inw_p +#define inl_p inl_p +#define insb insb +#define insw insw +#define insl insl + +#define outb outb +#define outw outw +#define outl outl +#define outb_p outb_p +#define outw_p outw_p +#define outl_p outl_p +#define outsb outsb +#define outsw outsw +#define outsl outsl + extern void *xlate_dev_mem_ptr(phys_addr_t phys); extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); +#define xlate_dev_mem_ptr xlate_dev_mem_ptr +#define unxlate_dev_mem_ptr unxlate_dev_mem_ptr + extern int ioremap_change_attr(unsigned long vaddr, unsigned long size, enum page_cache_mode pcm); extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size); +#define ioremap_wc ioremap_wc extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size); +#define ioremap_wt ioremap_wt extern bool is_early_ioremap_ptep(pte_t *ptep); @@ -365,6 +359,9 @@ extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, #define IO_SPACE_LIMIT 0xffff +#include +#undef PCI_IOBASE + #ifdef CONFIG_MTRR extern int __must_check arch_phys_wc_index(int handle); #define arch_phys_wc_index arch_phys_wc_index @@ -381,4 +378,12 @@ extern void arch_io_free_memtype_wc(resource_size_t start, resource_size_t size) #define arch_io_reserve_memtype_wc arch_io_reserve_memtype_wc #endif +extern bool arch_memremap_can_ram_remap(resource_size_t offset, + unsigned long size, + unsigned long flags); +#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap + +extern bool phys_mem_access_encrypted(unsigned long phys_addr, + unsigned long size); + #endif /* _ASM_X86_IO_H */ diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 6cbf2cfb3f8a..5c27e146a166 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IO_APIC_H #define _ASM_X86_IO_APIC_H diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index fca144a104e4..1e5d5d92eb40 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IOMMU_H #define _ASM_X86_IOMMU_H diff --git a/arch/x86/include/asm/iommu_table.h b/arch/x86/include/asm/iommu_table.h index e37d6b3ad983..1fb3fd1a83c2 100644 --- a/arch/x86/include/asm/iommu_table.h +++ b/arch/x86/include/asm/iommu_table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IOMMU_TABLE_H #define _ASM_X86_IOMMU_TABLE_H diff --git a/arch/x86/include/asm/iosf_mbi.h b/arch/x86/include/asm/iosf_mbi.h index c313cac36f56..7d87437bd030 100644 --- a/arch/x86/include/asm/iosf_mbi.h +++ b/arch/x86/include/asm/iosf_mbi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Intel OnChip System Fabric MailBox access support */ diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 668cca540025..d8632f8fa17d 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IRQ_H #define _ASM_X86_IRQ_H /* @@ -42,10 +43,6 @@ extern bool handle_irq(struct irq_desc *desc, struct pt_regs *regs); extern __visible unsigned int do_IRQ(struct pt_regs *regs); -/* Interrupt vector management */ -extern DECLARE_BITMAP(used_vectors, NR_VECTORS); -extern int vector_used_by_percpu_irq(unsigned int vector); - extern void init_ISA_irqs(void); #ifdef CONFIG_X86_LOCAL_APIC diff --git a/arch/x86/include/asm/irq_regs.h b/arch/x86/include/asm/irq_regs.h index d82250b1debb..8f3bee821e6c 100644 --- a/arch/x86/include/asm/irq_regs.h +++ b/arch/x86/include/asm/irq_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Per-cpu current frame pointer - the location of the last exception frame on * the stack, stored in the per-cpu area. diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index aaf8d28b5d00..c20ffca8fef1 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_IRQ_VECTORS_H #define _ASM_X86_IRQ_VECTORS_H diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h index f70604125286..800ffce0db29 100644 --- a/arch/x86/include/asm/irq_work.h +++ b/arch/x86/include/asm/irq_work.h @@ -1,11 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IRQ_WORK_H #define _ASM_IRQ_WORK_H #include +#ifdef CONFIG_X86_LOCAL_APIC static inline bool arch_irq_work_has_interrupt(void) { return boot_cpu_has(X86_FEATURE_APIC); } +extern void arch_irq_work_raise(void); +#else +static inline bool arch_irq_work_has_interrupt(void) +{ + return false; +} +#endif #endif /* _ASM_IRQ_WORK_H */ diff --git a/arch/x86/include/asm/irqdomain.h b/arch/x86/include/asm/irqdomain.h index d26075b52885..423e112c1e8f 100644 --- a/arch/x86/include/asm/irqdomain.h +++ b/arch/x86/include/asm/irqdomain.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_IRQDOMAIN_H #define _ASM_IRQDOMAIN_H diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index ac7692dcfa2e..c8ef23f2c28f 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _X86_IRQFLAGS_H_ #define _X86_IRQFLAGS_H_ diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h index adc54c12cbd1..8c0de4282659 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_JUMP_LABEL_H #define _ASM_X86_JUMP_LABEL_H diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h index f527b02a0ee3..b577dd0916aa 100644 --- a/arch/x86/include/asm/kasan.h +++ b/arch/x86/include/asm/kasan.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KASAN_H #define _ASM_X86_KASAN_H diff --git a/arch/x86/include/asm/kaslr.h b/arch/x86/include/asm/kaslr.h index 1052a797d71d..460991e3b529 100644 --- a/arch/x86/include/asm/kaslr.h +++ b/arch/x86/include/asm/kaslr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KASLR_H_ #define _ASM_KASLR_H_ diff --git a/arch/x86/include/asm/kbdleds.h b/arch/x86/include/asm/kbdleds.h index f27ac5ff597d..197ea4fedd53 100644 --- a/arch/x86/include/asm/kbdleds.h +++ b/arch/x86/include/asm/kbdleds.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KBDLEDS_H #define _ASM_X86_KBDLEDS_H diff --git a/arch/x86/include/asm/kdebug.h b/arch/x86/include/asm/kdebug.h index 29a594a3b82a..f86a8caa561e 100644 --- a/arch/x86/include/asm/kdebug.h +++ b/arch/x86/include/asm/kdebug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KDEBUG_H #define _ASM_X86_KDEBUG_H diff --git a/arch/x86/include/asm/kexec-bzimage64.h b/arch/x86/include/asm/kexec-bzimage64.h index d1b5d194e31d..9f07cff43705 100644 --- a/arch/x86/include/asm/kexec-bzimage64.h +++ b/arch/x86/include/asm/kexec-bzimage64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_KEXEC_BZIMAGE64_H #define _ASM_KEXEC_BZIMAGE64_H diff --git a/arch/x86/include/asm/kexec.h b/arch/x86/include/asm/kexec.h index 70ef205489f0..f327236f0fa7 100644 --- a/arch/x86/include/asm/kexec.h +++ b/arch/x86/include/asm/kexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KEXEC_H #define _ASM_X86_KEXEC_H @@ -147,7 +148,8 @@ unsigned long relocate_kernel(unsigned long indirection_page, unsigned long page_list, unsigned long start_address, - unsigned int preserve_context); + unsigned int preserve_context, + unsigned int sme_active); #endif #define ARCH_HAS_KIMAGE_ARCH @@ -207,6 +209,14 @@ struct kexec_entry64_regs { uint64_t r15; uint64_t rip; }; + +extern int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, + gfp_t gfp); +#define arch_kexec_post_alloc_pages arch_kexec_post_alloc_pages + +extern void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages); +#define arch_kexec_pre_free_pages arch_kexec_pre_free_pages + #endif typedef void crash_vmclear_fn(void); diff --git a/arch/x86/include/asm/kgdb.h b/arch/x86/include/asm/kgdb.h index 22a8537eb780..aacaf2502bd2 100644 --- a/arch/x86/include/asm/kgdb.h +++ b/arch/x86/include/asm/kgdb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KGDB_H #define _ASM_X86_KGDB_H diff --git a/arch/x86/include/asm/kmap_types.h b/arch/x86/include/asm/kmap_types.h index 9e00a731a7fb..04ab8266e347 100644 --- a/arch/x86/include/asm/kmap_types.h +++ b/arch/x86/include/asm/kmap_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KMAP_TYPES_H #define _ASM_X86_KMAP_TYPES_H diff --git a/arch/x86/include/asm/kmemcheck.h b/arch/x86/include/asm/kmemcheck.h index ed01518f297e..945a0337fbcf 100644 --- a/arch/x86/include/asm/kmemcheck.h +++ b/arch/x86/include/asm/kmemcheck.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ASM_X86_KMEMCHECK_H #define ASM_X86_KMEMCHECK_H diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index fde36f189836..ee23a43386a2 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************** * x86_emulate.h * @@ -219,8 +220,8 @@ struct x86_emulate_ops { struct x86_instruction_info *info, enum x86_intercept_stage stage); - void (*get_cpuid)(struct x86_emulate_ctxt *ctxt, - u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); + bool (*get_cpuid)(struct x86_emulate_ctxt *ctxt, u32 *eax, u32 *ebx, + u32 *ecx, u32 *edx, bool check_limit); void (*set_nmi_mask)(struct x86_emulate_ctxt *ctxt, bool masked); unsigned (*get_hflags)(struct x86_emulate_ctxt *ctxt); diff --git a/arch/x86/include/asm/kvm_guest.h b/arch/x86/include/asm/kvm_guest.h index a92b1763c419..46185263d9c2 100644 --- a/arch/x86/include/asm/kvm_guest.h +++ b/arch/x86/include/asm/kvm_guest.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KVM_GUEST_H #define _ASM_X86_KVM_GUEST_H diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 92c9032502d8..c73e493adf07 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -79,15 +79,14 @@ | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \ | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG)) -#define CR3_L_MODE_RESERVED_BITS 0xFFFFFF0000000000ULL #define CR3_PCID_INVD BIT_64(63) #define CR4_RESERVED_BITS \ (~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\ | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \ | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ - | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP \ - | X86_CR4_PKE)) + | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_VMXE \ + | X86_CR4_SMAP | X86_CR4_PKE)) #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) @@ -204,7 +203,6 @@ enum { #define PFERR_GUEST_PAGE_MASK (1ULL << PFERR_GUEST_PAGE_BIT) #define PFERR_NESTED_GUEST_PAGE (PFERR_GUEST_PAGE_MASK | \ - PFERR_USER_MASK | \ PFERR_WRITE_MASK | \ PFERR_PRESENT_MASK) @@ -317,15 +315,17 @@ struct kvm_pio_request { int size; }; +#define PT64_ROOT_MAX_LEVEL 5 + struct rsvd_bits_validate { - u64 rsvd_bits_mask[2][4]; + u64 rsvd_bits_mask[2][PT64_ROOT_MAX_LEVEL]; u64 bad_mt_xwr; }; /* - * x86 supports 3 paging modes (4-level 64-bit, 3-level 64-bit, and 2-level - * 32-bit). The kvm_mmu structure abstracts the details of the current mmu - * mode. + * x86 supports 4 paging modes (5-level 64-bit, 4-level 64-bit, 3-level 32-bit, + * and 2-level 32-bit). The kvm_mmu structure abstracts the details of the + * current mmu mode. */ struct kvm_mmu { void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root); @@ -548,8 +548,8 @@ struct kvm_vcpu_arch { struct kvm_queued_exception { bool pending; + bool injected; bool has_error_code; - bool reinject; u8 nr; u32 error_code; u8 nested_apf; @@ -687,8 +687,12 @@ struct kvm_vcpu_arch { int pending_ioapic_eoi; int pending_external_vector; - /* GPA available (AMD only) */ + /* GPA available */ bool gpa_available; + gpa_t gpa_val; + + /* be preempted when it's in kernel-mode(cpl=0) */ + bool preempted_in_kernel; }; struct kvm_lpage_info { @@ -947,7 +951,6 @@ struct kvm_x86_ops { void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); - u32 (*get_pkru)(struct kvm_vcpu *vcpu); void (*tlb_flush)(struct kvm_vcpu *vcpu); @@ -969,7 +972,7 @@ struct kvm_x86_ops { void (*enable_nmi_window)(struct kvm_vcpu *vcpu); void (*enable_irq_window)(struct kvm_vcpu *vcpu); void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr); - bool (*get_enable_apicv)(void); + bool (*get_enable_apicv)(struct kvm_vcpu *vcpu); void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu); void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr); void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr); @@ -979,7 +982,7 @@ struct kvm_x86_ops { void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu); int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); - int (*get_tdp_level)(void); + int (*get_tdp_level)(struct kvm_vcpu *vcpu); u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); int (*get_lpage_level)(void); bool (*rdtscp_supported)(void); @@ -1079,7 +1082,7 @@ void kvm_mmu_init_vm(struct kvm *kvm); void kvm_mmu_uninit_vm(struct kvm *kvm); void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, u64 dirty_mask, u64 nx_mask, u64 x_mask, u64 p_mask, - u64 acc_track_mask); + u64 acc_track_mask, u64 me_mask); void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); void kvm_mmu_slot_remove_write_access(struct kvm *kvm, @@ -1297,20 +1300,6 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code) kvm_queue_exception_e(vcpu, GP_VECTOR, error_code); } -static inline u64 get_canonical(u64 la) -{ - return ((int64_t)la << 16) >> 16; -} - -static inline bool is_noncanonical_address(u64 la) -{ -#ifdef CONFIG_X86_64 - return get_canonical(la) != la; -#else - return false; -#endif -} - #define TSS_IOPB_BASE_OFFSET 0x66 #define TSS_BASE_SIZE 0x68 #define TSS_IOPB_SIZE (65536 / 8) diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h index c4eda791f877..172f9749dbb2 100644 --- a/arch/x86/include/asm/kvm_page_track.h +++ b/arch/x86/include/asm/kvm_page_track.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KVM_PAGE_TRACK_H #define _ASM_X86_KVM_PAGE_TRACK_H diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index bc62e7cbf1b1..c373e44049b1 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KVM_PARA_H #define _ASM_X86_KVM_PARA_H @@ -88,7 +89,7 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, bool kvm_para_available(void); unsigned int kvm_arch_para_features(void); void __init kvm_guest_init(void); -void kvm_async_pf_task_wait(u32 token); +void kvm_async_pf_task_wait(u32 token, int interrupt_kernel); void kvm_async_pf_task_wake(u32 token); u32 kvm_read_and_reset_pf_reason(void); extern void kvm_disable_steal_time(void); @@ -103,7 +104,7 @@ static inline void kvm_spinlock_init(void) #else /* CONFIG_KVM_GUEST */ #define kvm_guest_init() do {} while (0) -#define kvm_async_pf_task_wait(T) do {} while(0) +#define kvm_async_pf_task_wait(T, I) do {} while(0) #define kvm_async_pf_task_wake(T) do {} while(0) static inline bool kvm_para_available(void) diff --git a/arch/x86/include/asm/kvmclock.h b/arch/x86/include/asm/kvmclock.h index f260bef63591..eceea9299097 100644 --- a/arch/x86/include/asm/kvmclock.h +++ b/arch/x86/include/asm/kvmclock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_KVM_CLOCK_H #define _ASM_X86_KVM_CLOCK_H diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h deleted file mode 100644 index 73d0c9b92087..000000000000 --- a/arch/x86/include/asm/lguest.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef _ASM_X86_LGUEST_H -#define _ASM_X86_LGUEST_H - -#define GDT_ENTRY_LGUEST_CS 10 -#define GDT_ENTRY_LGUEST_DS 11 -#define LGUEST_CS (GDT_ENTRY_LGUEST_CS * 8) -#define LGUEST_DS (GDT_ENTRY_LGUEST_DS * 8) - -#ifndef __ASSEMBLY__ -#include - -#define GUEST_PL 1 - -/* Page for Switcher text itself, then two pages per cpu */ -#define SWITCHER_TEXT_PAGES (1) -#define SWITCHER_STACK_PAGES (2 * nr_cpu_ids) -#define TOTAL_SWITCHER_PAGES (SWITCHER_TEXT_PAGES + SWITCHER_STACK_PAGES) - -/* Where we map the Switcher, in both Host and Guest. */ -extern unsigned long switcher_addr; - -/* Found in switcher.S */ -extern unsigned long default_idt_entries[]; - -/* Declarations for definitions in arch/x86/lguest/head_32.S */ -extern char lguest_noirq_iret[]; -extern const char lgstart_cli[], lgend_cli[]; -extern const char lgstart_pushf[], lgend_pushf[]; - -extern void lguest_iret(void); -extern void lguest_init(void); - -struct lguest_regs { - /* Manually saved part. */ - unsigned long eax, ebx, ecx, edx; - unsigned long esi, edi, ebp; - unsigned long gs; - unsigned long fs, ds, es; - unsigned long trapnum, errcode; - /* Trap pushed part */ - unsigned long eip; - unsigned long cs; - unsigned long eflags; - unsigned long esp; - unsigned long ss; -}; - -/* This is a guest-specific page (mapped ro) into the guest. */ -struct lguest_ro_state { - /* Host information we need to restore when we switch back. */ - u32 host_cr3; - struct desc_ptr host_idt_desc; - struct desc_ptr host_gdt_desc; - u32 host_sp; - - /* Fields which are used when guest is running. */ - struct desc_ptr guest_idt_desc; - struct desc_ptr guest_gdt_desc; - struct x86_hw_tss guest_tss; - struct desc_struct guest_idt[IDT_ENTRIES]; - struct desc_struct guest_gdt[GDT_ENTRIES]; -}; - -struct lg_cpu_arch { - /* The GDT entries copied into lguest_ro_state when running. */ - struct desc_struct gdt[GDT_ENTRIES]; - - /* The IDT entries: some copied into lguest_ro_state when running. */ - struct desc_struct idt[IDT_ENTRIES]; - - /* The address of the last guest-visible pagefault (ie. cr2). */ - unsigned long last_pagefault; -}; - -static inline void lguest_set_ts(void) -{ - u32 cr0; - - cr0 = read_cr0(); - if (!(cr0 & 8)) - write_cr0(cr0 | 8); -} - -/* Full 4G segment descriptors, suitable for CS and DS. */ -#define FULL_EXEC_SEGMENT \ - ((struct desc_struct)GDT_ENTRY_INIT(0xc09b, 0, 0xfffff)) -#define FULL_SEGMENT ((struct desc_struct)GDT_ENTRY_INIT(0xc093, 0, 0xfffff)) - -#endif /* __ASSEMBLY__ */ - -#endif /* _ASM_X86_LGUEST_H */ diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h deleted file mode 100644 index 6c119cfae218..000000000000 --- a/arch/x86/include/asm/lguest_hcall.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Architecture specific portion of the lguest hypercalls */ -#ifndef _ASM_X86_LGUEST_HCALL_H -#define _ASM_X86_LGUEST_HCALL_H - -#define LHCALL_FLUSH_ASYNC 0 -#define LHCALL_LGUEST_INIT 1 -#define LHCALL_SHUTDOWN 2 -#define LHCALL_NEW_PGTABLE 4 -#define LHCALL_FLUSH_TLB 5 -#define LHCALL_LOAD_IDT_ENTRY 6 -#define LHCALL_SET_STACK 7 -#define LHCALL_SET_CLOCKEVENT 9 -#define LHCALL_HALT 10 -#define LHCALL_SET_PMD 13 -#define LHCALL_SET_PTE 14 -#define LHCALL_SET_PGD 15 -#define LHCALL_LOAD_TLS 16 -#define LHCALL_LOAD_GDT_ENTRY 18 -#define LHCALL_SEND_INTERRUPTS 19 - -#define LGUEST_TRAP_ENTRY 0x1F - -/* Argument number 3 to LHCALL_LGUEST_SHUTDOWN */ -#define LGUEST_SHUTDOWN_POWEROFF 1 -#define LGUEST_SHUTDOWN_RESTART 2 - -#ifndef __ASSEMBLY__ -#include - -/*G:030 - * But first, how does our Guest contact the Host to ask for privileged - * operations? There are two ways: the direct way is to make a "hypercall", - * to make requests of the Host Itself. - * - * Our hypercall mechanism uses the highest unused trap code (traps 32 and - * above are used by real hardware interrupts). Seventeen hypercalls are - * available: the hypercall number is put in the %eax register, and the - * arguments (when required) are placed in %ebx, %ecx, %edx and %esi. - * If a return value makes sense, it's returned in %eax. - * - * Grossly invalid calls result in Sudden Death at the hands of the vengeful - * Host, rather than returning failure. This reflects Winston Churchill's - * definition of a gentleman: "someone who is only rude intentionally". - */ -static inline unsigned long -hcall(unsigned long call, - unsigned long arg1, unsigned long arg2, unsigned long arg3, - unsigned long arg4) -{ - /* "int" is the Intel instruction to trigger a trap. */ - asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY) - /* The call in %eax (aka "a") might be overwritten */ - : "=a"(call) - /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */ - : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4) - /* "memory" means this might write somewhere in memory. - * This isn't true for all calls, but it's safe to tell - * gcc that it might happen so it doesn't get clever. */ - : "memory"); - return call; -} -/*:*/ - -/* Can't use our min() macro here: needs to be a constant */ -#define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32) - -#define LHCALL_RING_SIZE 64 -struct hcall_args { - /* These map directly onto eax/ebx/ecx/edx/esi in struct lguest_regs */ - unsigned long arg0, arg1, arg2, arg3, arg4; -}; - -#endif /* !__ASSEMBLY__ */ -#endif /* _ASM_X86_LGUEST_HCALL_H */ diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h index 0ccb26dda126..14caa9d9fb7f 100644 --- a/arch/x86/include/asm/linkage.h +++ b/arch/x86/include/asm/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_LINKAGE_H #define _ASM_X86_LINKAGE_H diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h index 7511978093eb..c91083c59845 100644 --- a/arch/x86/include/asm/local.h +++ b/arch/x86/include/asm/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_LOCAL_H #define _ASM_X86_LOCAL_H diff --git a/arch/x86/include/asm/mach_timer.h b/arch/x86/include/asm/mach_timer.h index 88d0c3c74c13..044daf6fb8f6 100644 --- a/arch/x86/include/asm/mach_timer.h +++ b/arch/x86/include/asm/mach_timer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine specific calibrate_tsc() for generic. * Split out from timer_tsc.c by Osamu Tomita diff --git a/arch/x86/include/asm/mach_traps.h b/arch/x86/include/asm/mach_traps.h index a01e7ec7d237..e39a517467cd 100644 --- a/arch/x86/include/asm/mach_traps.h +++ b/arch/x86/include/asm/mach_traps.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine specific NMI handling for generic. * Split out from traps.c by Osamu Tomita diff --git a/arch/x86/include/asm/math_emu.h b/arch/x86/include/asm/math_emu.h index 0d9b14f60d2c..3c42743083ed 100644 --- a/arch/x86/include/asm/math_emu.h +++ b/arch/x86/include/asm/math_emu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MATH_EMU_H #define _ASM_X86_MATH_EMU_H diff --git a/arch/x86/include/asm/mc146818rtc.h b/arch/x86/include/asm/mc146818rtc.h index 24acd9ba7837..1775a32f7ea6 100644 --- a/arch/x86/include/asm/mc146818rtc.h +++ b/arch/x86/include/asm/mc146818rtc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Machine dependent access functions for RTC registers. */ diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 181264989db5..b1e8d8db921f 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MCE_H #define _ASM_X86_MCE_H @@ -187,7 +188,6 @@ struct mca_msr_regs { extern struct mce_vendor_flags mce_flags; -extern struct mca_config mca_cfg; extern struct mca_msr_regs msr_ops; enum mce_notifier_prios { diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h new file mode 100644 index 000000000000..6a77c63540f7 --- /dev/null +++ b/arch/x86/include/asm/mem_encrypt.h @@ -0,0 +1,80 @@ +/* + * AMD Memory Encryption Support + * + * Copyright (C) 2016 Advanced Micro Devices, Inc. + * + * Author: Tom Lendacky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __X86_MEM_ENCRYPT_H__ +#define __X86_MEM_ENCRYPT_H__ + +#ifndef __ASSEMBLY__ + +#include + +#include + +#ifdef CONFIG_AMD_MEM_ENCRYPT + +extern u64 sme_me_mask; + +void sme_encrypt_execute(unsigned long encrypted_kernel_vaddr, + unsigned long decrypted_kernel_vaddr, + unsigned long kernel_len, + unsigned long encryption_wa, + unsigned long encryption_pgd); + +void __init sme_early_encrypt(resource_size_t paddr, + unsigned long size); +void __init sme_early_decrypt(resource_size_t paddr, + unsigned long size); + +void __init sme_map_bootdata(char *real_mode_data); +void __init sme_unmap_bootdata(char *real_mode_data); + +void __init sme_early_init(void); + +void __init sme_encrypt_kernel(void); +void __init sme_enable(struct boot_params *bp); + +/* Architecture __weak replacement functions */ +void __init mem_encrypt_init(void); + +void swiotlb_set_mem_attributes(void *vaddr, unsigned long size); + +#else /* !CONFIG_AMD_MEM_ENCRYPT */ + +#define sme_me_mask 0ULL + +static inline void __init sme_early_encrypt(resource_size_t paddr, + unsigned long size) { } +static inline void __init sme_early_decrypt(resource_size_t paddr, + unsigned long size) { } + +static inline void __init sme_map_bootdata(char *real_mode_data) { } +static inline void __init sme_unmap_bootdata(char *real_mode_data) { } + +static inline void __init sme_early_init(void) { } + +static inline void __init sme_encrypt_kernel(void) { } +static inline void __init sme_enable(struct boot_params *bp) { } + +#endif /* CONFIG_AMD_MEM_ENCRYPT */ + +/* + * The __sme_pa() and __sme_pa_nodebug() macros are meant for use when + * writing to or comparing values from the cr3 register. Having the + * encryption mask set in cr3 enables the PGD entry to be encrypted and + * avoid special case handling of PGD allocations. + */ +#define __sme_pa(x) (__pa(x) | sme_me_mask) +#define __sme_pa_nodebug(x) (__pa_nodebug(x) | sme_me_mask) + +#endif /* __ASSEMBLY__ */ + +#endif /* __X86_MEM_ENCRYPT_H__ */ diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index daadeeea00b1..55520cec8b27 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MICROCODE_H #define _ASM_X86_MICROCODE_H diff --git a/arch/x86/include/asm/microcode_amd.h b/arch/x86/include/asm/microcode_amd.h index 3d57009e168b..209492849566 100644 --- a/arch/x86/include/asm/microcode_amd.h +++ b/arch/x86/include/asm/microcode_amd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MICROCODE_AMD_H #define _ASM_X86_MICROCODE_AMD_H diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h index e793fc9a9b20..d85a07d7154f 100644 --- a/arch/x86/include/asm/microcode_intel.h +++ b/arch/x86/include/asm/microcode_intel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MICROCODE_INTEL_H #define _ASM_X86_MICROCODE_INTEL_H diff --git a/arch/x86/include/asm/misc.h b/arch/x86/include/asm/misc.h index 475f5bbc7f53..bb049cca3729 100644 --- a/arch/x86/include/asm/misc.h +++ b/arch/x86/include/asm/misc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MISC_H #define _ASM_X86_MISC_H diff --git a/arch/x86/include/asm/mmconfig.h b/arch/x86/include/asm/mmconfig.h index 04a3fed22cfe..976486447e10 100644 --- a/arch/x86/include/asm/mmconfig.h +++ b/arch/x86/include/asm/mmconfig.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MMCONFIG_H #define _ASM_X86_MMCONFIG_H diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 79b647a7ebd0..9ea26f167497 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h @@ -1,14 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MMU_H #define _ASM_X86_MMU_H #include #include +#include /* - * The x86 doesn't have a mmu context, but - * we put the segment information here. + * x86 has arch-specific MMU state beyond what lives in mm_struct. */ typedef struct { + /* + * ctx_id uniquely identifies this mm_struct. A ctx_id will never + * be reused, and zero is not a valid ctx_id. + */ + u64 ctx_id; + + /* + * Any code that needs to do any sort of TLB flushing for this + * mm will first make its changes to the page tables, then + * increment tlb_gen, then flush. This lets the low-level + * flushing code keep track of what needs flushing. + * + * This is not used on Xen PV. + */ + atomic64_t tlb_gen; + #ifdef CONFIG_MODIFY_LDT_SYSCALL struct ldt_struct *ldt; #endif @@ -37,6 +54,11 @@ typedef struct { #endif } mm_context_t; +#define INIT_MM_CONTEXT(mm) \ + .context = { \ + .ctx_id = 1, \ + } + void leave_mm(int cpu); #endif /* _ASM_X86_MMU_H */ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 7a234be7e298..6699fc441644 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MMU_CONTEXT_H #define _ASM_X86_MMU_CONTEXT_H @@ -12,6 +13,9 @@ #include #include #include + +extern atomic64_t last_mm_ctx_id; + #ifndef CONFIG_PARAVIRT static inline void paravirt_activate_mm(struct mm_struct *prev, struct mm_struct *next) @@ -123,15 +127,14 @@ static inline void switch_ldt(struct mm_struct *prev, struct mm_struct *next) DEBUG_LOCKS_WARN_ON(preemptible()); } -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -{ - if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) - this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); -} +void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk); static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { + mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); + atomic64_set(&mm->context.tlb_gen, 0); + #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS if (cpu_feature_enabled(X86_FEATURE_OSPKE)) { /* pkey 0 is the default and always allocated */ @@ -278,6 +281,32 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, return __pkru_allows_pkey(vma_pkey(vma), write); } +/* + * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID + * bits. This serves two purposes. It prevents a nasty situation in + * which PCID-unaware code saves CR3, loads some other value (with PCID + * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if + * the saved ASID was nonzero. It also means that any bugs involving + * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger + * deterministically. + */ + +static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid) +{ + if (static_cpu_has(X86_FEATURE_PCID)) { + VM_WARN_ON_ONCE(asid > 4094); + return __sme_pa(mm->pgd) | (asid + 1); + } else { + VM_WARN_ON_ONCE(asid != 0); + return __sme_pa(mm->pgd); + } +} + +static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid) +{ + VM_WARN_ON_ONCE(asid > 4094); + return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH; +} /* * This can be used from process context to figure out what the value of @@ -288,7 +317,8 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, */ static inline unsigned long __get_current_cr3_fast(void) { - unsigned long cr3 = __pa(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd); + unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm), + this_cpu_read(cpu_tlbstate.loaded_mm_asid)); /* For now, be very restrictive about when this can be called. */ VM_WARN_ON(in_nmi() || preemptible()); diff --git a/arch/x86/include/asm/mmx.h b/arch/x86/include/asm/mmx.h index 5cbf3135b971..f572d0f944bb 100644 --- a/arch/x86/include/asm/mmx.h +++ b/arch/x86/include/asm/mmx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MMX_H #define _ASM_X86_MMX_H diff --git a/arch/x86/include/asm/mmzone.h b/arch/x86/include/asm/mmzone.h index d497bc425cae..c41b41edd691 100644 --- a/arch/x86/include/asm/mmzone.h +++ b/arch/x86/include/asm/mmzone.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_X86_32 # include #else diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index 1ec990bd7dc0..73d8dd14dda2 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Written by Pat Gaughen (gone@us.ibm.com) Mar 2002 * diff --git a/arch/x86/include/asm/mmzone_64.h b/arch/x86/include/asm/mmzone_64.h index 129d9aa3ceb3..0c585046f744 100644 --- a/arch/x86/include/asm/mmzone_64.h +++ b/arch/x86/include/asm/mmzone_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* K8 NUMA support */ /* Copyright 2002,2003 by Andi Kleen, SuSE Labs */ /* 2.5 Version loosely based on the NUMAQ Code by Pat Gaughen. */ diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h index e3b7819caeef..8546fafa21a9 100644 --- a/arch/x86/include/asm/module.h +++ b/arch/x86/include/asm/module.h @@ -1,7 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MODULE_H #define _ASM_X86_MODULE_H #include +#include + +struct mod_arch_specific { +#ifdef CONFIG_ORC_UNWINDER + unsigned int num_orcs; + int *orc_unwind_ip; + struct orc_entry *orc_unwind; +#endif +}; #ifdef CONFIG_X86_64 /* X86_64 does not define MODULE_PROC_FAMILY */ diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 831eb7895535..606cbaebd336 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MPSPEC_H #define _ASM_X86_MPSPEC_H @@ -86,7 +87,6 @@ static inline void e820__memblock_alloc_reserved_mpc_new(void) { } #endif int generic_processor_info(int apicid, int version); -int __generic_processor_info(int apicid, int version, bool enabled); #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_LOCAL_APIC) diff --git a/arch/x86/include/asm/mpspec_def.h b/arch/x86/include/asm/mpspec_def.h index b31f8c098271..9492893aec52 100644 --- a/arch/x86/include/asm/mpspec_def.h +++ b/arch/x86/include/asm/mpspec_def.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MPSPEC_DEF_H #define _ASM_X86_MPSPEC_DEF_H diff --git a/arch/x86/include/asm/mpx.h b/arch/x86/include/asm/mpx.h index a0d662be4c5b..61eb4b63c5ec 100644 --- a/arch/x86/include/asm/mpx.h +++ b/arch/x86/include/asm/mpx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MPX_H #define _ASM_X86_MPX_H @@ -73,6 +74,9 @@ static inline void mpx_mm_init(struct mm_struct *mm) } void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start, unsigned long end); + +unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len, + unsigned long flags); #else static inline siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) { @@ -94,6 +98,12 @@ static inline void mpx_notify_unmap(struct mm_struct *mm, unsigned long start, unsigned long end) { } + +static inline unsigned long mpx_unmapped_area_check(unsigned long addr, + unsigned long len, unsigned long flags) +{ + return addr; +} #endif /* CONFIG_X86_INTEL_MPX */ #endif /* _ASM_X86_MPX_H */ diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 2b58c8c1eeaa..581bb54dd464 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -1,8 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MSHYPER_H #define _ASM_X86_MSHYPER_H #include #include +#include +#include #include /* @@ -28,6 +31,8 @@ struct ms_hyperv_info { u32 features; u32 misc_features; u32 hints; + u32 max_vp_index; + u32 max_lp_index; }; extern struct ms_hyperv_info ms_hyperv; @@ -168,12 +173,154 @@ void hv_remove_crash_handler(void); #if IS_ENABLED(CONFIG_HYPERV) extern struct clocksource *hyperv_cs; +extern void *hv_hypercall_pg; + +static inline u64 hv_do_hypercall(u64 control, void *input, void *output) +{ + u64 input_address = input ? virt_to_phys(input) : 0; + u64 output_address = output ? virt_to_phys(output) : 0; + u64 hv_status; + +#ifdef CONFIG_X86_64 + if (!hv_hypercall_pg) + return U64_MAX; + + __asm__ __volatile__("mov %4, %%r8\n" + "call *%5" + : "=a" (hv_status), ASM_CALL_CONSTRAINT, + "+c" (control), "+d" (input_address) + : "r" (output_address), "m" (hv_hypercall_pg) + : "cc", "memory", "r8", "r9", "r10", "r11"); +#else + u32 input_address_hi = upper_32_bits(input_address); + u32 input_address_lo = lower_32_bits(input_address); + u32 output_address_hi = upper_32_bits(output_address); + u32 output_address_lo = lower_32_bits(output_address); + + if (!hv_hypercall_pg) + return U64_MAX; + + __asm__ __volatile__("call *%7" + : "=A" (hv_status), + "+c" (input_address_lo), ASM_CALL_CONSTRAINT + : "A" (control), + "b" (input_address_hi), + "D"(output_address_hi), "S"(output_address_lo), + "m" (hv_hypercall_pg) + : "cc", "memory"); +#endif /* !x86_64 */ + return hv_status; +} + +#define HV_HYPERCALL_RESULT_MASK GENMASK_ULL(15, 0) +#define HV_HYPERCALL_FAST_BIT BIT(16) +#define HV_HYPERCALL_VARHEAD_OFFSET 17 +#define HV_HYPERCALL_REP_COMP_OFFSET 32 +#define HV_HYPERCALL_REP_COMP_MASK GENMASK_ULL(43, 32) +#define HV_HYPERCALL_REP_START_OFFSET 48 +#define HV_HYPERCALL_REP_START_MASK GENMASK_ULL(59, 48) + +/* Fast hypercall with 8 bytes of input and no output */ +static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) +{ + u64 hv_status, control = (u64)code | HV_HYPERCALL_FAST_BIT; + +#ifdef CONFIG_X86_64 + { + __asm__ __volatile__("call *%4" + : "=a" (hv_status), ASM_CALL_CONSTRAINT, + "+c" (control), "+d" (input1) + : "m" (hv_hypercall_pg) + : "cc", "r8", "r9", "r10", "r11"); + } +#else + { + u32 input1_hi = upper_32_bits(input1); + u32 input1_lo = lower_32_bits(input1); + + __asm__ __volatile__ ("call *%5" + : "=A"(hv_status), + "+c"(input1_lo), + ASM_CALL_CONSTRAINT + : "A" (control), + "b" (input1_hi), + "m" (hv_hypercall_pg) + : "cc", "edi", "esi"); + } +#endif + return hv_status; +} + +/* + * Rep hypercalls. Callers of this functions are supposed to ensure that + * rep_count and varhead_size comply with Hyper-V hypercall definition. + */ +static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, + void *input, void *output) +{ + u64 control = code; + u64 status; + u16 rep_comp; + + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET; + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET; + + do { + status = hv_do_hypercall(control, input, output); + if ((status & HV_HYPERCALL_RESULT_MASK) != HV_STATUS_SUCCESS) + return status; + + /* Bits 32-43 of status have 'Reps completed' data. */ + rep_comp = (status & HV_HYPERCALL_REP_COMP_MASK) >> + HV_HYPERCALL_REP_COMP_OFFSET; + + control &= ~HV_HYPERCALL_REP_START_MASK; + control |= (u64)rep_comp << HV_HYPERCALL_REP_START_OFFSET; + + touch_nmi_watchdog(); + } while (rep_comp < rep_count); + + return status; +} + +/* + * Hypervisor's notion of virtual processor ID is different from + * Linux' notion of CPU ID. This information can only be retrieved + * in the context of the calling CPU. Setup a map for easy access + * to this information. + */ +extern u32 *hv_vp_index; +extern u32 hv_max_vp_index; + +/** + * hv_cpu_number_to_vp_number() - Map CPU to VP. + * @cpu_number: CPU number in Linux terms + * + * This function returns the mapping between the Linux processor + * number and the hypervisor's virtual processor number, useful + * in making hypercalls and such that talk about specific + * processors. + * + * Return: Virtual processor number in Hyper-V terms + */ +static inline int hv_cpu_number_to_vp_number(int cpu_number) +{ + return hv_vp_index[cpu_number]; +} void hyperv_init(void); +void hyperv_setup_mmu_ops(void); +void hyper_alloc_mmu(void); void hyperv_report_panic(struct pt_regs *regs); bool hv_is_hypercall_page_setup(void); void hyperv_cleanup(void); -#endif +#else /* CONFIG_HYPERV */ +static inline void hyperv_init(void) {} +static inline bool hv_is_hypercall_page_setup(void) { return false; } +static inline void hyperv_cleanup(void) {} +static inline void hyperv_setup_mmu_ops(void) {} +#endif /* CONFIG_HYPERV */ + #ifdef CONFIG_HYPERV_TSCPAGE struct ms_hyperv_tsc_page *hv_get_tsc_page(void); static inline u64 hv_read_tsc_page(const struct ms_hyperv_tsc_page *tsc_pg) diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h index eb4b09b41df5..25ddd0916bb2 100644 --- a/arch/x86/include/asm/msi.h +++ b/arch/x86/include/asm/msi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MSI_H #define _ASM_X86_MSI_H #include diff --git a/arch/x86/include/asm/msidef.h b/arch/x86/include/asm/msidef.h index 4cc48af23fef..ee2f8ccc32d0 100644 --- a/arch/x86/include/asm/msidef.h +++ b/arch/x86/include/asm/msidef.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MSIDEF_H #define _ASM_X86_MSIDEF_H diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 5573c75f8e4c..ab022618a50a 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MSR_INDEX_H #define _ASM_X86_MSR_INDEX_H @@ -356,6 +357,8 @@ #define MSR_K8_TOP_MEM1 0xc001001a #define MSR_K8_TOP_MEM2 0xc001001d #define MSR_K8_SYSCFG 0xc0010010 +#define MSR_K8_SYSCFG_MEM_ENCRYPT_BIT 23 +#define MSR_K8_SYSCFG_MEM_ENCRYPT BIT_ULL(MSR_K8_SYSCFG_MEM_ENCRYPT_BIT) #define MSR_K8_INT_PENDING_MSG 0xc0010055 /* C1E active bits in int pending message */ #define K8_INTP_C1E_ACTIVE_MASK 0x18000000 diff --git a/arch/x86/include/asm/msr-trace.h b/arch/x86/include/asm/msr-trace.h index 7567225747d8..f6adbe96856a 100644 --- a/arch/x86/include/asm/msr-trace.h +++ b/arch/x86/include/asm/msr-trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM msr diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 898dba2e2e2c..07962f5f6fba 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MSR_H #define _ASM_X86_MSR_H diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index bda3c27f0da0..39a2fb29378a 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_MWAIT_H #define _ASM_X86_MWAIT_H diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h index 5f2fc4441b11..75ded1d13d98 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_NMI_H #define _ASM_X86_NMI_H diff --git a/arch/x86/include/asm/nops.h b/arch/x86/include/asm/nops.h index aff2b3356101..12f12b5cf2ca 100644 --- a/arch/x86/include/asm/nops.h +++ b/arch/x86/include/asm/nops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_NOPS_H #define _ASM_X86_NOPS_H diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h index 01b493e5a99b..bbfde3d2662f 100644 --- a/arch/x86/include/asm/numa.h +++ b/arch/x86/include/asm/numa.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_NUMA_H #define _ASM_X86_NUMA_H diff --git a/arch/x86/include/asm/numa_32.h b/arch/x86/include/asm/numa_32.h index e7d6b8254742..9c8e9e85be77 100644 --- a/arch/x86/include/asm/numa_32.h +++ b/arch/x86/include/asm/numa_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_NUMA_32_H #define _ASM_X86_NUMA_32_H diff --git a/arch/x86/include/asm/olpc.h b/arch/x86/include/asm/olpc.h index 72f9adf6eca4..c2bf1de5d901 100644 --- a/arch/x86/include/asm/olpc.h +++ b/arch/x86/include/asm/olpc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* OLPC machine specific definitions */ #ifndef _ASM_X86_OLPC_H diff --git a/arch/x86/include/asm/olpc_ofw.h b/arch/x86/include/asm/olpc_ofw.h index 24487712e0b1..8c2a1daf7f72 100644 --- a/arch/x86/include/asm/olpc_ofw.h +++ b/arch/x86/include/asm/olpc_ofw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_OLPC_OFW_H #define _ASM_X86_OLPC_OFW_H diff --git a/arch/x86/include/asm/orc_lookup.h b/arch/x86/include/asm/orc_lookup.h new file mode 100644 index 000000000000..91c8d868424d --- /dev/null +++ b/arch/x86/include/asm/orc_lookup.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +#ifndef _ORC_LOOKUP_H +#define _ORC_LOOKUP_H + +/* + * This is a lookup table for speeding up access to the .orc_unwind table. + * Given an input address offset, the corresponding lookup table entry + * specifies a subset of the .orc_unwind table to search. + * + * Each block represents the end of the previous range and the start of the + * next range. An extra block is added to give the last range an end. + * + * The block size should be a power of 2 to avoid a costly 'div' instruction. + * + * A block size of 256 was chosen because it roughly doubles unwinder + * performance while only adding ~5% to the ORC data footprint. + */ +#define LOOKUP_BLOCK_ORDER 8 +#define LOOKUP_BLOCK_SIZE (1 << LOOKUP_BLOCK_ORDER) + +#ifndef LINKER_SCRIPT + +extern unsigned int orc_lookup[]; +extern unsigned int orc_lookup_end[]; + +#define LOOKUP_START_IP (unsigned long)_stext +#define LOOKUP_STOP_IP (unsigned long)_etext + +#endif /* LINKER_SCRIPT */ + +#endif /* _ORC_LOOKUP_H */ diff --git a/arch/x86/include/asm/orc_types.h b/arch/x86/include/asm/orc_types.h new file mode 100644 index 000000000000..9c9dc579bd7d --- /dev/null +++ b/arch/x86/include/asm/orc_types.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _ORC_TYPES_H +#define _ORC_TYPES_H + +#include +#include + +/* + * The ORC_REG_* registers are base registers which are used to find other + * registers on the stack. + * + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the + * address of the previous frame: the caller's SP before it called the current + * function. + * + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in + * the current frame. + * + * The most commonly used base registers are SP and BP -- which the previous SP + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is + * usually based on. + * + * The rest of the base registers are needed for special cases like entry code + * and GCC realigned stacks. + */ +#define ORC_REG_UNDEFINED 0 +#define ORC_REG_PREV_SP 1 +#define ORC_REG_DX 2 +#define ORC_REG_DI 3 +#define ORC_REG_BP 4 +#define ORC_REG_SP 5 +#define ORC_REG_R10 6 +#define ORC_REG_R13 7 +#define ORC_REG_BP_INDIRECT 8 +#define ORC_REG_SP_INDIRECT 9 +#define ORC_REG_MAX 15 + +/* + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the + * caller's SP right before it made the call). Used for all callable + * functions, i.e. all C code and all callable asm functions. + * + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points + * to a fully populated pt_regs from a syscall, interrupt, or exception. + * + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset + * points to the iret return frame. + * + * The UNWIND_HINT macros are used only for the unwind_hint struct. They + * aren't used in struct orc_entry due to size and complexity constraints. + * Objtool converts them to real types when it converts the hints to orc + * entries. + */ +#define ORC_TYPE_CALL 0 +#define ORC_TYPE_REGS 1 +#define ORC_TYPE_REGS_IRET 2 +#define UNWIND_HINT_TYPE_SAVE 3 +#define UNWIND_HINT_TYPE_RESTORE 4 + +#ifndef __ASSEMBLY__ +/* + * This struct is more or less a vastly simplified version of the DWARF Call + * Frame Information standard. It contains only the necessary parts of DWARF + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the + * unwinder how to find the previous SP and BP (and sometimes entry regs) on + * the stack for a given code address. Each instance of the struct corresponds + * to one or more code locations. + */ +struct orc_entry { + s16 sp_offset; + s16 bp_offset; + unsigned sp_reg:4; + unsigned bp_reg:4; + unsigned type:2; +} __packed; + +/* + * This struct is used by asm and inline asm code to manually annotate the + * location of registers on the stack for the ORC unwinder. + * + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. + */ +struct unwind_hint { + u32 ip; + s16 sp_offset; + u8 sp_reg; + u8 type; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ORC_TYPES_H */ diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index cf8f619b305f..7555b48803a8 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PAGE_H #define _ASM_X86_PAGE_H diff --git a/arch/x86/include/asm/page_32.h b/arch/x86/include/asm/page_32.h index 904f528cc8e8..94dbd51df58f 100644 --- a/arch/x86/include/asm/page_32.h +++ b/arch/x86/include/asm/page_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PAGE_32_H #define _ASM_X86_PAGE_32_H diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index 3bae4969ac65..aa30c3241ea7 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PAGE_32_DEFS_H #define _ASM_X86_PAGE_32_DEFS_H diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index b4a0d43248cf..4baa6bceb232 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PAGE_64_H #define _ASM_X86_PAGE_64_H @@ -51,6 +52,10 @@ static inline void clear_page(void *page) void copy_page(void *to, void *from); +#ifdef CONFIG_X86_MCE +#define arch_unmap_kpfn arch_unmap_kpfn +#endif + #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_X86_VSYSCALL_EMULATION diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 3f5f08b010d0..e1407312c412 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PAGE_64_DEFS_H #define _ASM_X86_PAGE_64_DEFS_H diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 7bd0099384ca..1e53560a84bb 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h @@ -1,8 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PAGE_DEFS_H #define _ASM_X86_PAGE_DEFS_H #include #include +#include /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 @@ -15,7 +17,7 @@ #define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT) #define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1)) -#define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1)) +#define __PHYSICAL_MASK ((phys_addr_t)(__sme_clr((1ULL << __PHYSICAL_MASK_SHIFT) - 1))) #define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1) /* Cast *PAGE_MASK to a signed type so that it is sign-extended if diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 9ccac1926587..fd81228e8037 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PARAVIRT_H #define _ASM_X86_PARAVIRT_H /* Various instructions on x86 need to be replaced for @@ -71,11 +72,6 @@ static inline void write_cr3(unsigned long x) PVOP_VCALL1(pv_mmu_ops.write_cr3, x); } -static inline unsigned long __read_cr4(void) -{ - return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4); -} - static inline void __write_cr4(unsigned long x) { PVOP_VCALL1(pv_cpu_ops.write_cr4, x); @@ -228,10 +224,6 @@ static inline void set_ldt(const void *addr, unsigned entries) { PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); } -static inline void store_idt(struct desc_ptr *dtr) -{ - PVOP_VCALL1(pv_cpu_ops.store_idt, dtr); -} static inline unsigned long paravirt_store_tr(void) { return PVOP_CALL0(unsigned long, pv_cpu_ops.store_tr); @@ -365,12 +357,6 @@ static inline void paravirt_release_p4d(unsigned long pfn) PVOP_VCALL1(pv_mmu_ops.release_p4d, pfn); } -static inline void pte_update(struct mm_struct *mm, unsigned long addr, - pte_t *ptep) -{ - PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep); -} - static inline pte_t __pte(pteval_t val) { pteval_t ret; @@ -472,28 +458,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pte.pte); } -static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmd) -{ - if (sizeof(pmdval_t) > sizeof(long)) - /* 5 arg words */ - pv_mmu_ops.set_pmd_at(mm, addr, pmdp, pmd); - else - PVOP_VCALL4(pv_mmu_ops.set_pmd_at, mm, addr, pmdp, - native_pmd_val(pmd)); -} - -static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, - pud_t *pudp, pud_t pud) -{ - if (sizeof(pudval_t) > sizeof(long)) - /* 5 arg words */ - pv_mmu_ops.set_pud_at(mm, addr, pudp, pud); - else - PVOP_VCALL4(pv_mmu_ops.set_pud_at, mm, addr, pudp, - native_pud_val(pud)); -} - static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) { pmdval_t val = native_pmd_val(pmd); @@ -960,11 +924,6 @@ extern void default_banner(void); #define GET_CR2_INTO_RAX \ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr2) -#define PARAVIRT_ADJUST_EXCEPTION_FRAME \ - PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_adjust_exception_frame), \ - CLBR_NONE, \ - call PARA_INDIRECT(pv_irq_ops+PV_IRQ_adjust_exception_frame)) - #define USERGS_SYSRET64 \ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_usergs_sysret64), \ CLBR_NONE, \ diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 9ffc36bfe4cd..10cc3b9709fe 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PARAVIRT_TYPES_H #define _ASM_X86_PARAVIRT_TYPES_H @@ -107,7 +108,6 @@ struct pv_cpu_ops { unsigned long (*read_cr0)(void); void (*write_cr0)(unsigned long); - unsigned long (*read_cr4)(void); void (*write_cr4)(unsigned long); #ifdef CONFIG_X86_64 @@ -119,8 +119,6 @@ struct pv_cpu_ops { void (*load_tr_desc)(void); void (*load_gdt)(const struct desc_ptr *); void (*load_idt)(const struct desc_ptr *); - /* store_gdt has been removed. */ - void (*store_idt)(struct desc_ptr *); void (*set_ldt)(const void *desc, unsigned entries); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); @@ -196,9 +194,6 @@ struct pv_irq_ops { void (*safe_halt)(void); void (*halt)(void); -#ifdef CONFIG_X86_64 - void (*adjust_exception_frame)(void); -#endif } __no_randomize_layout; struct pv_mmu_ops { @@ -248,12 +243,6 @@ struct pv_mmu_ops { void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval); void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval); - void (*set_pmd_at)(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp, pmd_t pmdval); - void (*set_pud_at)(struct mm_struct *mm, unsigned long addr, - pud_t *pudp, pud_t pudval); - void (*pte_update)(struct mm_struct *mm, unsigned long addr, - pte_t *ptep); pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr, pte_t *ptep); @@ -471,8 +460,8 @@ int paravirt_disable_iospace(void); */ #ifdef CONFIG_X86_32 #define PVOP_VCALL_ARGS \ - unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; \ - register void *__sp asm("esp") + unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; + #define PVOP_CALL_ARGS PVOP_VCALL_ARGS #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) @@ -492,8 +481,8 @@ int paravirt_disable_iospace(void); /* [re]ax isn't an arg, but the return val */ #define PVOP_VCALL_ARGS \ unsigned long __edi = __edi, __esi = __esi, \ - __edx = __edx, __ecx = __ecx, __eax = __eax; \ - register void *__sp asm("rsp") + __edx = __edx, __ecx = __ecx, __eax = __eax; + #define PVOP_CALL_ARGS PVOP_VCALL_ARGS #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) @@ -544,7 +533,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr, "+r" (__sp) \ + : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ @@ -554,7 +543,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr, "+r" (__sp) \ + : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ @@ -581,7 +570,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr, "+r" (__sp) \ + : call_clbr, ASM_CALL_CONSTRAINT \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ diff --git a/arch/x86/include/asm/parport.h b/arch/x86/include/asm/parport.h index 0d2d3b29118f..163f78259a7e 100644 --- a/arch/x86/include/asm/parport.h +++ b/arch/x86/include/asm/parport.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PARPORT_H #define _ASM_X86_PARPORT_H diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h index fffb2794dd89..8a3ee355b422 100644 --- a/arch/x86/include/asm/pat.h +++ b/arch/x86/include/asm/pat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PAT_H #define _ASM_X86_PAT_H diff --git a/arch/x86/include/asm/pci-direct.h b/arch/x86/include/asm/pci-direct.h index b1e7a45d868a..e1084f71a295 100644 --- a/arch/x86/include/asm/pci-direct.h +++ b/arch/x86/include/asm/pci-direct.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PCI_DIRECT_H #define _ASM_X86_PCI_DIRECT_H diff --git a/arch/x86/include/asm/pci-functions.h b/arch/x86/include/asm/pci-functions.h index ed0bab427354..1bbc10812ae1 100644 --- a/arch/x86/include/asm/pci-functions.h +++ b/arch/x86/include/asm/pci-functions.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PCI BIOS function numbering for conventional PCI BIOS * systems diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 473a7295ab10..09c06b0fb964 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PCI_H #define _ASM_X86_PCI_H diff --git a/arch/x86/include/asm/pci_64.h b/arch/x86/include/asm/pci_64.h index fe15cfb21b9b..f5411de0ae11 100644 --- a/arch/x86/include/asm/pci_64.h +++ b/arch/x86/include/asm/pci_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PCI_64_H #define _ASM_X86_PCI_64_H diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 9f1b21f372fe..7a5d6695abd3 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Low-Level PCI Access for i386 machines. * diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 9fa03604b2b3..377f1ffd18be 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PERCPU_H #define _ASM_X86_PERCPU_H diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index f353061bba1d..12f54082f4c8 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PERF_EVENT_H #define _ASM_X86_PERF_EVENT_H diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index d725382c2ae0..94de1a05aeba 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Netburst Performance Events (P4, old Xeon) */ diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index b2d0cd8288aa..4b5e1eafada7 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGALLOC_H #define _ASM_X86_PGALLOC_H diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h index a8b96e708c2b..685ffe8a0eaf 100644 --- a/arch/x86/include/asm/pgtable-2level.h +++ b/arch/x86/include/asm/pgtable-2level.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_2LEVEL_H #define _ASM_X86_PGTABLE_2LEVEL_H diff --git a/arch/x86/include/asm/pgtable-2level_types.h b/arch/x86/include/asm/pgtable-2level_types.h index 373ab1de909f..f982ef808e7e 100644 --- a/arch/x86/include/asm/pgtable-2level_types.h +++ b/arch/x86/include/asm/pgtable-2level_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_2LEVEL_DEFS_H #define _ASM_X86_PGTABLE_2LEVEL_DEFS_H diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index c8821bab938f..bc4af5453802 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_3LEVEL_H #define _ASM_X86_PGTABLE_3LEVEL_H diff --git a/arch/x86/include/asm/pgtable-3level_types.h b/arch/x86/include/asm/pgtable-3level_types.h index b8a4341faafa..876b4c77d983 100644 --- a/arch/x86/include/asm/pgtable-3level_types.h +++ b/arch/x86/include/asm/pgtable-3level_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_3LEVEL_DEFS_H #define _ASM_X86_PGTABLE_3LEVEL_DEFS_H diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 77037b6f1caa..f735c3016325 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1,6 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_H #define _ASM_X86_PGTABLE_H +#include #include #include @@ -13,9 +15,18 @@ cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS))) \ : (prot)) +/* + * Macros to add or remove encryption attribute + */ +#define pgprot_encrypted(prot) __pgprot(__sme_set(pgprot_val(prot))) +#define pgprot_decrypted(prot) __pgprot(__sme_clr(pgprot_val(prot))) + #ifndef __ASSEMBLY__ #include +extern pgd_t early_top_pgt[PTRS_PER_PGD]; +int __init __early_make_pgtable(unsigned long address, pmdval_t pmd); + void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd); void ptdump_walk_pgd_level_checkwx(void); @@ -38,13 +49,13 @@ extern struct list_head pgd_list; extern struct mm_struct *pgd_page_get_mm(struct page *page); +extern pmdval_t early_pmd_flags; + #ifdef CONFIG_PARAVIRT #include #else /* !CONFIG_PARAVIRT */ #define set_pte(ptep, pte) native_set_pte(ptep, pte) #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) -#define set_pmd_at(mm, addr, pmdp, pmd) native_set_pmd_at(mm, addr, pmdp, pmd) -#define set_pud_at(mm, addr, pudp, pud) native_set_pud_at(mm, addr, pudp, pud) #define set_pte_atomic(ptep, pte) \ native_set_pte_atomic(ptep, pte) @@ -75,8 +86,6 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); #define pte_clear(mm, addr, ptep) native_pte_clear(mm, addr, ptep) #define pmd_clear(pmd) native_pmd_clear(pmd) -#define pte_update(mm, addr, ptep) do { } while (0) - #define pgd_val(x) native_pgd_val(x) #define __pgd(x) native_make_pgd(x) @@ -195,6 +204,11 @@ static inline unsigned long p4d_pfn(p4d_t p4d) return (p4d_val(p4d) & p4d_pfn_mask(p4d)) >> PAGE_SHIFT; } +static inline unsigned long pgd_pfn(pgd_t pgd) +{ + return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT; +} + static inline int p4d_large(p4d_t p4d) { /* No 512 GiB pages yet */ @@ -704,8 +718,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pmd_page(pmd) \ - pfn_to_page((pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT) +#define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd)) /* * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] @@ -773,8 +786,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pud_page(pud) \ - pfn_to_page((pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT) +#define pud_page(pud) pfn_to_page(pud_pfn(pud)) /* Find an entry in the second-level page table.. */ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) @@ -824,8 +836,7 @@ static inline unsigned long p4d_page_vaddr(p4d_t p4d) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define p4d_page(p4d) \ - pfn_to_page((p4d_val(p4d) & p4d_pfn_mask(p4d)) >> PAGE_SHIFT) +#define p4d_page(p4d) pfn_to_page(p4d_pfn(p4d)) /* Find an entry in the third-level page table.. */ static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) @@ -859,7 +870,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) +#define pgd_page(pgd) pfn_to_page(pgd_pfn(pgd)) /* to find an entry in a page-table-directory. */ static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) @@ -965,31 +976,18 @@ static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, native_set_pte(ptep, pte); } -static inline void native_set_pmd_at(struct mm_struct *mm, unsigned long addr, - pmd_t *pmdp , pmd_t pmd) +static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, + pmd_t *pmdp, pmd_t pmd) { native_set_pmd(pmdp, pmd); } -static inline void native_set_pud_at(struct mm_struct *mm, unsigned long addr, - pud_t *pudp, pud_t pud) +static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, + pud_t *pudp, pud_t pud) { native_set_pud(pudp, pud); } -#ifndef CONFIG_PARAVIRT -/* - * Rules for using pte_update - it must be called after any PTE update which - * has not been done using the set_pte / clear_pte interfaces. It is used by - * shadow mode hypervisors to resynchronize the shadow page tables. Kernel PTE - * updates should either be sets, clears, or set_pte_atomic for P->P - * transitions, which means this hook should only be called for user PTEs. - * This hook implies a P->P protection or access change has taken place, which - * requires a subsequent TLB flush. - */ -#define pte_update(mm, addr, ptep) do { } while (0) -#endif - /* * We only update the dirty/accessed state if we set * the dirty bit by hand in the kernel, since the hardware @@ -1017,7 +1015,6 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { pte_t pte = native_ptep_get_and_clear(ptep); - pte_update(mm, addr, ptep); return pte; } @@ -1044,7 +1041,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { clear_bit(_PAGE_BIT_RW, (unsigned long *)&ptep->pte); - pte_update(mm, addr, ptep); } #define flush_tlb_fix_spurious_fault(vma, address) do { } while (0) @@ -1158,6 +1154,23 @@ static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) { return pte_clear_flags(pte, _PAGE_SWP_SOFT_DIRTY); } + +#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION +static inline pmd_t pmd_swp_mksoft_dirty(pmd_t pmd) +{ + return pmd_set_flags(pmd, _PAGE_SWP_SOFT_DIRTY); +} + +static inline int pmd_swp_soft_dirty(pmd_t pmd) +{ + return pmd_flags(pmd) & _PAGE_SWP_SOFT_DIRTY; +} + +static inline pmd_t pmd_swp_clear_soft_dirty(pmd_t pmd) +{ + return pmd_clear_flags(pmd, _PAGE_SWP_SOFT_DIRTY); +} +#endif #endif #define PKRU_AD_BIT 0x1 diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h index bfab55675c16..e67c0620aec2 100644 --- a/arch/x86/include/asm/pgtable_32.h +++ b/arch/x86/include/asm/pgtable_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_32_H #define _ASM_X86_PGTABLE_32_H diff --git a/arch/x86/include/asm/pgtable_32_types.h b/arch/x86/include/asm/pgtable_32_types.h index 9fb2f2bc8245..f2ca9b28fd68 100644 --- a/arch/x86/include/asm/pgtable_32_types.h +++ b/arch/x86/include/asm/pgtable_32_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_32_DEFS_H #define _ASM_X86_PGTABLE_32_DEFS_H diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index 2160c1fee920..e9f05331e732 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_64_H #define _ASM_X86_PGTABLE_64_H @@ -180,15 +181,21 @@ static inline int pgd_large(pgd_t pgd) { return 0; } /* * Encode and de-code a swap entry * - * | ... | 11| 10| 9|8|7|6|5| 4| 3|2|1|0| <- bit number - * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U|W|P| <- bit names - * | OFFSET (14->63) | TYPE (9-13) |0|X|X|X| X| X|X|X|0| <- swp entry + * | ... | 11| 10| 9|8|7|6|5| 4| 3|2| 1|0| <- bit number + * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U| W|P| <- bit names + * | OFFSET (14->63) | TYPE (9-13) |0|0|X|X| X| X|X|SD|0| <- swp entry * * G (8) is aliased and used as a PROT_NONE indicator for * !present ptes. We need to start storing swap entries above * there. We also need to avoid using A and D because of an * erratum where they can be incorrectly set by hardware on * non-present PTEs. + * + * SD (1) in swp entry is used to store soft dirty bit, which helps us + * remember soft dirty over page migration + * + * Bit 7 in swp entry should be 0 because pmd_present checks not only P, + * but also L and G. */ #define SWP_TYPE_FIRST_BIT (_PAGE_BIT_PROTNONE + 1) #define SWP_TYPE_BITS 5 @@ -204,7 +211,9 @@ static inline int pgd_large(pgd_t pgd) { return 0; } ((type) << (SWP_TYPE_FIRST_BIT)) \ | ((offset) << SWP_OFFSET_FIRST_BIT) }) #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) +#define __pmd_to_swp_entry(pmd) ((swp_entry_t) { pmd_val((pmd)) }) #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) +#define __swp_entry_to_pmd(x) ((pmd_t) { .pmd = (x).val }) extern int kern_addr_valid(unsigned long addr); extern void cleanup_highmap(void); diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h index 06470da156ba..6d5f45dcd4a1 100644 --- a/arch/x86/include/asm/pgtable_64_types.h +++ b/arch/x86/include/asm/pgtable_64_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_64_DEFS_H #define _ASM_X86_PGTABLE_64_DEFS_H diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index bf9638e1ee42..59df7b47a434 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -1,7 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PGTABLE_DEFS_H #define _ASM_X86_PGTABLE_DEFS_H #include +#include + #include #define FIRST_USER_ADDRESS 0UL @@ -97,15 +100,15 @@ /* * Tracking soft dirty bit when a page goes to a swap is tricky. * We need a bit which can be stored in pte _and_ not conflict - * with swap entry format. On x86 bits 6 and 7 are *not* involved - * into swap entry computation, but bit 6 is used for nonlinear - * file mapping, so we borrow bit 7 for soft dirty tracking. + * with swap entry format. On x86 bits 1-4 are *not* involved + * into swap entry computation, but bit 7 is used for thp migration, + * so we borrow bit 1 for soft dirty tracking. * * Please note that this bit must be treated as swap dirty page - * mark if and only if the PTE has present bit clear! + * mark if and only if the PTE/PMD has present bit clear! */ #ifdef CONFIG_MEM_SOFT_DIRTY -#define _PAGE_SWP_SOFT_DIRTY _PAGE_PSE +#define _PAGE_SWP_SOFT_DIRTY _PAGE_RW #else #define _PAGE_SWP_SOFT_DIRTY (_AT(pteval_t, 0)) #endif @@ -121,10 +124,10 @@ #define _PAGE_PROTNONE (_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE) -#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ - _PAGE_ACCESSED | _PAGE_DIRTY) -#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ - _PAGE_DIRTY) +#define _PAGE_TABLE_NOENC (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |\ + _PAGE_ACCESSED | _PAGE_DIRTY) +#define _KERNPG_TABLE_NOENC (_PAGE_PRESENT | _PAGE_RW | \ + _PAGE_ACCESSED | _PAGE_DIRTY) /* * Set of bits not changed in pte_modify. The pte's @@ -159,6 +162,7 @@ enum page_cache_mode { #define _PAGE_CACHE_MASK (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT) #define _PAGE_NOCACHE (cachemode2protval(_PAGE_CACHE_MODE_UC)) +#define _PAGE_CACHE_WP (cachemode2protval(_PAGE_CACHE_MODE_WP)) #define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ @@ -187,22 +191,42 @@ enum page_cache_mode { #define __PAGE_KERNEL_VVAR (__PAGE_KERNEL_RO | _PAGE_USER) #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) +#define __PAGE_KERNEL_WP (__PAGE_KERNEL | _PAGE_CACHE_WP) #define __PAGE_KERNEL_IO (__PAGE_KERNEL) #define __PAGE_KERNEL_IO_NOCACHE (__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL __pgprot(__PAGE_KERNEL) -#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) -#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) -#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) -#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) -#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) -#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC) -#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL) -#define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR) +#ifndef __ASSEMBLY__ -#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) -#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE) +#define _PAGE_ENC (_AT(pteval_t, sme_me_mask)) + +#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \ + _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_ENC) +#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ + _PAGE_DIRTY | _PAGE_ENC) + +#define __PAGE_KERNEL_ENC (__PAGE_KERNEL | _PAGE_ENC) +#define __PAGE_KERNEL_ENC_WP (__PAGE_KERNEL_WP | _PAGE_ENC) + +#define __PAGE_KERNEL_NOENC (__PAGE_KERNEL) +#define __PAGE_KERNEL_NOENC_WP (__PAGE_KERNEL_WP) + +#define PAGE_KERNEL __pgprot(__PAGE_KERNEL | _PAGE_ENC) +#define PAGE_KERNEL_NOENC __pgprot(__PAGE_KERNEL) +#define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO | _PAGE_ENC) +#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC | _PAGE_ENC) +#define PAGE_KERNEL_EXEC_NOENC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX | _PAGE_ENC) +#define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC) +#define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC) +#define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) +#define PAGE_KERNEL_VSYSCALL __pgprot(__PAGE_KERNEL_VSYSCALL | _PAGE_ENC) +#define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC) + +#define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) +#define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE) + +#endif /* __ASSEMBLY__ */ /* xwr */ #define __P000 PAGE_NONE @@ -287,6 +311,11 @@ static inline p4dval_t native_p4d_val(p4d_t p4d) #else #include +static inline p4d_t native_make_p4d(pudval_t val) +{ + return (p4d_t) { .pgd = native_make_pgd((pgdval_t)val) }; +} + static inline p4dval_t native_p4d_val(p4d_t p4d) { return native_pgd_val(p4d.pgd); diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h index b3b09b98896d..a0ba1ffda0df 100644 --- a/arch/x86/include/asm/pkeys.h +++ b/arch/x86/include/asm/pkeys.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PKEYS_H #define _ASM_X86_PKEYS_H diff --git a/arch/x86/include/asm/pm-trace.h b/arch/x86/include/asm/pm-trace.h index 7b7ac42c3661..bfa32aa428e5 100644 --- a/arch/x86/include/asm/pm-trace.h +++ b/arch/x86/include/asm/pm-trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PM_TRACE_H #define _ASM_X86_PM_TRACE_H diff --git a/arch/x86/include/asm/posix_types.h b/arch/x86/include/asm/posix_types.h index f565f6dd59d4..374336e217ff 100644 --- a/arch/x86/include/asm/posix_types.h +++ b/arch/x86/include/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ # ifdef CONFIG_X86_32 # include # else diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h index ec1f3c651150..7f2dbd91fc74 100644 --- a/arch/x86/include/asm/preempt.h +++ b/arch/x86/include/asm/preempt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_PREEMPT_H #define __ASM_PREEMPT_H @@ -100,19 +101,14 @@ static __always_inline bool should_resched(int preempt_offset) #ifdef CONFIG_PREEMPT extern asmlinkage void ___preempt_schedule(void); -# define __preempt_schedule() \ -({ \ - register void *__sp asm(_ASM_SP); \ - asm volatile ("call ___preempt_schedule" : "+r"(__sp)); \ -}) +# define __preempt_schedule() \ + asm volatile ("call ___preempt_schedule" : ASM_CALL_CONSTRAINT) extern asmlinkage void preempt_schedule(void); extern asmlinkage void ___preempt_schedule_notrace(void); -# define __preempt_schedule_notrace() \ -({ \ - register void *__sp asm(_ASM_SP); \ - asm volatile ("call ___preempt_schedule_notrace" : "+r"(__sp)); \ -}) +# define __preempt_schedule_notrace() \ + asm volatile ("call ___preempt_schedule_notrace" : ASM_CALL_CONSTRAINT) + extern asmlinkage void preempt_schedule_notrace(void); #endif diff --git a/arch/x86/include/asm/probe_roms.h b/arch/x86/include/asm/probe_roms.h index 4950a0b1d09c..1c7f3815bbd6 100644 --- a/arch/x86/include/asm/probe_roms.h +++ b/arch/x86/include/asm/probe_roms.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PROBE_ROMS_H_ #define _PROBE_ROMS_H_ struct pci_dev; diff --git a/arch/x86/include/asm/processor-cyrix.h b/arch/x86/include/asm/processor-cyrix.h index 1198f2a0e42c..aaedd73ea2c6 100644 --- a/arch/x86/include/asm/processor-cyrix.h +++ b/arch/x86/include/asm/processor-cyrix.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * NSC/Cyrix CPU indexed register access. Must be inlined instead of * macros to ensure correct access ordering diff --git a/arch/x86/include/asm/processor-flags.h b/arch/x86/include/asm/processor-flags.h index 79aa2f98398d..43212a43ee69 100644 --- a/arch/x86/include/asm/processor-flags.h +++ b/arch/x86/include/asm/processor-flags.h @@ -1,7 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PROCESSOR_FLAGS_H #define _ASM_X86_PROCESSOR_FLAGS_H #include +#include #ifdef CONFIG_VM86 #define X86_VM_MASK X86_EFLAGS_VM @@ -32,16 +34,18 @@ * CR3_ADDR_MASK is the mask used by read_cr3_pa(). */ #ifdef CONFIG_X86_64 -/* Mask off the address space ID bits. */ -#define CR3_ADDR_MASK 0x7FFFFFFFFFFFF000ull -#define CR3_PCID_MASK 0xFFFull +/* Mask off the address space ID and SME encryption bits. */ +#define CR3_ADDR_MASK __sme_clr(0x7FFFFFFFFFFFF000ull) +#define CR3_PCID_MASK 0xFFFull +#define CR3_NOFLUSH BIT_ULL(63) #else /* * CR3_ADDR_MASK needs at least bits 31:5 set on PAE systems, and we save * a tiny bit of code size by setting all the bits. */ -#define CR3_ADDR_MASK 0xFFFFFFFFull -#define CR3_PCID_MASK 0ull +#define CR3_ADDR_MASK 0xFFFFFFFFull +#define CR3_PCID_MASK 0ull +#define CR3_NOFLUSH 0 #endif #endif /* _ASM_X86_PROCESSOR_FLAGS_H */ diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 028245e1c42b..bdac19ab2488 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PROCESSOR_H #define _ASM_X86_PROCESSOR_H @@ -22,6 +23,7 @@ struct vm86; #include #include #include +#include #include #include @@ -29,6 +31,7 @@ struct vm86; #include #include #include +#include /* * We handle most unaligned accesses in hardware. On the other hand @@ -239,9 +242,14 @@ static inline unsigned long read_cr3_pa(void) return __read_cr3() & CR3_ADDR_MASK; } +static inline unsigned long native_read_cr3_pa(void) +{ + return __native_read_cr3() & CR3_ADDR_MASK; +} + static inline void load_cr3(pgd_t *pgdir) { - write_cr3(__pa(pgdir)); + write_cr3(__sme_pa(pgdir)); } #ifdef CONFIG_X86_32 @@ -661,7 +669,7 @@ static inline void sync_core(void) * In case NMI unmasking or performance ever becomes a problem, * the next best option appears to be MOV-to-CR2 and an * unconditional jump. That sequence also works on all CPUs, - * but it will fault at CPL3 (i.e. Xen PV and lguest). + * but it will fault at CPL3 (i.e. Xen PV). * * CPUID is the conventional way, but it's nasty: it doesn't * exist on some 486-like CPUs, and it usually exits to a @@ -670,8 +678,6 @@ static inline void sync_core(void) * Like all of Linux's memory ordering operations, this is a * compiler barrier as well. */ - register void *__sp asm(_ASM_SP); - #ifdef CONFIG_X86_32 asm volatile ( "pushfl\n\t" @@ -679,11 +685,12 @@ static inline void sync_core(void) "pushl $1f\n\t" "iret\n\t" "1:" - : "+r" (__sp) : : "memory"); + : ASM_CALL_CONSTRAINT : : "memory"); #else unsigned int tmp; asm volatile ( + UNWIND_HINT_SAVE "mov %%ss, %0\n\t" "pushq %q0\n\t" "pushq %%rsp\n\t" @@ -693,8 +700,9 @@ static inline void sync_core(void) "pushq %q0\n\t" "pushq $1f\n\t" "iretq\n\t" + UNWIND_HINT_RESTORE "1:" - : "=&r" (tmp), "+r" (__sp) : : "cc", "memory"); + : "=&r" (tmp), ASM_CALL_CONSTRAINT : : "cc", "memory"); #endif } @@ -802,7 +810,9 @@ static inline void spin_lock_prefetch(const void *x) */ #define IA32_PAGE_OFFSET PAGE_OFFSET #define TASK_SIZE PAGE_OFFSET +#define TASK_SIZE_LOW TASK_SIZE #define TASK_SIZE_MAX TASK_SIZE +#define DEFAULT_MAP_WINDOW TASK_SIZE #define STACK_TOP TASK_SIZE #define STACK_TOP_MAX STACK_TOP @@ -842,7 +852,9 @@ static inline void spin_lock_prefetch(const void *x) * particular problem by preventing anything from being mapped * at the maximum canonical address. */ -#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE) +#define TASK_SIZE_MAX ((1UL << __VIRTUAL_MASK_SHIFT) - PAGE_SIZE) + +#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. @@ -850,12 +862,14 @@ static inline void spin_lock_prefetch(const void *x) #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \ 0xc0000000 : 0xFFFFe000) +#define TASK_SIZE_LOW (test_thread_flag(TIF_ADDR32) ? \ + IA32_PAGE_OFFSET : DEFAULT_MAP_WINDOW) #define TASK_SIZE (test_thread_flag(TIF_ADDR32) ? \ IA32_PAGE_OFFSET : TASK_SIZE_MAX) #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_ADDR32)) ? \ IA32_PAGE_OFFSET : TASK_SIZE_MAX) -#define STACK_TOP TASK_SIZE +#define STACK_TOP TASK_SIZE_LOW #define STACK_TOP_MAX TASK_SIZE_MAX #define INIT_THREAD { \ @@ -876,7 +890,7 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip, * space during mmap's. */ #define __TASK_UNMAPPED_BASE(task_size) (PAGE_ALIGN(task_size / 3)) -#define TASK_UNMAPPED_BASE __TASK_UNMAPPED_BASE(TASK_SIZE) +#define TASK_UNMAPPED_BASE __TASK_UNMAPPED_BASE(TASK_SIZE_LOW) #define KSTK_EIP(task) (task_pt_regs(task)->ip) diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h index 8d3964fc5f91..6e81788a30c1 100644 --- a/arch/x86/include/asm/proto.h +++ b/arch/x86/include/asm/proto.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PROTO_H #define _ASM_X86_PROTO_H @@ -24,6 +25,9 @@ void entry_SYSENTER_compat(void); void __end_entry_SYSENTER_compat(void); void entry_SYSCALL_compat(void); void entry_INT80_compat(void); +#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV) +void xen_entry_INT80_compat(void); +#endif #endif void x86_configure_nx(void); diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 2b5d686ea9f3..c0e3c45cf6ab 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PTRACE_H #define _ASM_X86_PTRACE_H @@ -9,6 +10,20 @@ #ifdef __i386__ struct pt_regs { + /* + * NB: 32-bit x86 CPUs are inconsistent as what happens in the + * following cases (where %seg represents a segment register): + * + * - pushl %seg: some do a 16-bit write and leave the high + * bits alone + * - movl %seg, [mem]: some do a 16-bit write despite the movl + * - IDT entry: some (e.g. 486) will leave the high bits of CS + * and (if applicable) SS undefined. + * + * Fortunately, x86-32 doesn't read the high bits on POP or IRET, + * so we can just treat all of the segment registers as 16-bit + * values. + */ unsigned long bx; unsigned long cx; unsigned long dx; @@ -16,16 +31,22 @@ struct pt_regs { unsigned long di; unsigned long bp; unsigned long ax; - unsigned long ds; - unsigned long es; - unsigned long fs; - unsigned long gs; + unsigned short ds; + unsigned short __dsh; + unsigned short es; + unsigned short __esh; + unsigned short fs; + unsigned short __fsh; + unsigned short gs; + unsigned short __gsh; unsigned long orig_ax; unsigned long ip; - unsigned long cs; + unsigned short cs; + unsigned short __csh; unsigned long flags; unsigned long sp; - unsigned long ss; + unsigned short ss; + unsigned short __ssh; }; #else /* __i386__ */ @@ -176,6 +197,17 @@ static inline unsigned long regs_get_register(struct pt_regs *regs, if (offset == offsetof(struct pt_regs, sp) && regs->cs == __KERNEL_CS) return kernel_stack_pointer(regs); + + /* The selector fields are 16-bit. */ + if (offset == offsetof(struct pt_regs, cs) || + offset == offsetof(struct pt_regs, ss) || + offset == offsetof(struct pt_regs, ds) || + offset == offsetof(struct pt_regs, es) || + offset == offsetof(struct pt_regs, fs) || + offset == offsetof(struct pt_regs, gs)) { + return *(u16 *)((unsigned long)regs + offset); + + } #endif return *(unsigned long *)((unsigned long)regs + offset); } diff --git a/arch/x86/include/asm/purgatory.h b/arch/x86/include/asm/purgatory.h index d7da2729903d..92c34e517da1 100644 --- a/arch/x86/include/asm/purgatory.h +++ b/arch/x86/include/asm/purgatory.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PURGATORY_H #define _ASM_X86_PURGATORY_H diff --git a/arch/x86/include/asm/pvclock-abi.h b/arch/x86/include/asm/pvclock-abi.h index 67f08230103a..1436226efe3e 100644 --- a/arch/x86/include/asm/pvclock-abi.h +++ b/arch/x86/include/asm/pvclock-abi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PVCLOCK_ABI_H #define _ASM_X86_PVCLOCK_ABI_H #ifndef __ASSEMBLY__ diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index 448cfe1b48cf..3e4ed8fb5f91 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PVCLOCK_H #define _ASM_X86_PVCLOCK_H diff --git a/arch/x86/include/asm/qrwlock.h b/arch/x86/include/asm/qrwlock.h index c537cbb038a7..8656b5a6e8e7 100644 --- a/arch/x86/include/asm/qrwlock.h +++ b/arch/x86/include/asm/qrwlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_QRWLOCK_H #define _ASM_X86_QRWLOCK_H diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h index 48a706f641f2..9982dd96f093 100644 --- a/arch/x86/include/asm/qspinlock.h +++ b/arch/x86/include/asm/qspinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_QSPINLOCK_H #define _ASM_X86_QSPINLOCK_H diff --git a/arch/x86/include/asm/qspinlock_paravirt.h b/arch/x86/include/asm/qspinlock_paravirt.h index 9d55f9b6e167..923307ea11c7 100644 --- a/arch/x86/include/asm/qspinlock_paravirt.h +++ b/arch/x86/include/asm/qspinlock_paravirt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_QSPINLOCK_PARAVIRT_H #define __ASM_QSPINLOCK_PARAVIRT_H diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h index 230e1903acf0..63b3393bd98e 100644 --- a/arch/x86/include/asm/realmode.h +++ b/arch/x86/include/asm/realmode.h @@ -1,6 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_X86_REALMODE_H #define _ARCH_X86_REALMODE_H +/* + * Flag bit definitions for use with the flags field of the trampoline header + * in the CONFIG_X86_64 variant. + */ +#define TH_FLAGS_SME_ACTIVE_BIT 0 +#define TH_FLAGS_SME_ACTIVE BIT(TH_FLAGS_SME_ACTIVE_BIT) + +#ifndef __ASSEMBLY__ + #include #include @@ -38,6 +48,7 @@ struct trampoline_header { u64 start; u64 efer; u32 cr4; + u32 flags; #endif }; @@ -69,4 +80,6 @@ static inline size_t real_mode_size_needed(void) void set_real_mode_mem(phys_addr_t mem, size_t size); void reserve_real_mode(void); +#endif /* __ASSEMBLY__ */ + #endif /* _ARCH_X86_REALMODE_H */ diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index fc62ba8dce93..a671a1145906 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_REBOOT_H #define _ASM_X86_REBOOT_H diff --git a/arch/x86/include/asm/reboot_fixups.h b/arch/x86/include/asm/reboot_fixups.h index 765debe4c54c..96515658ce12 100644 --- a/arch/x86/include/asm/reboot_fixups.h +++ b/arch/x86/include/asm/reboot_fixups.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_REBOOT_FIXUPS_H #define _ASM_X86_REBOOT_FIXUPS_H diff --git a/arch/x86/include/asm/refcount.h b/arch/x86/include/asm/refcount.h new file mode 100644 index 000000000000..ff871210b9f2 --- /dev/null +++ b/arch/x86/include/asm/refcount.h @@ -0,0 +1,109 @@ +#ifndef __ASM_X86_REFCOUNT_H +#define __ASM_X86_REFCOUNT_H +/* + * x86-specific implementation of refcount_t. Based on PAX_REFCOUNT from + * PaX/grsecurity. + */ +#include + +/* + * This is the first portion of the refcount error handling, which lives in + * .text.unlikely, and is jumped to from the CPU flag check (in the + * following macros). This saves the refcount value location into CX for + * the exception handler to use (in mm/extable.c), and then triggers the + * central refcount exception. The fixup address for the exception points + * back to the regular execution flow in .text. + */ +#define _REFCOUNT_EXCEPTION \ + ".pushsection .text.unlikely\n" \ + "111:\tlea %[counter], %%" _ASM_CX "\n" \ + "112:\t" ASM_UD0 "\n" \ + ASM_UNREACHABLE \ + ".popsection\n" \ + "113:\n" \ + _ASM_EXTABLE_REFCOUNT(112b, 113b) + +/* Trigger refcount exception if refcount result is negative. */ +#define REFCOUNT_CHECK_LT_ZERO \ + "js 111f\n\t" \ + _REFCOUNT_EXCEPTION + +/* Trigger refcount exception if refcount result is zero or negative. */ +#define REFCOUNT_CHECK_LE_ZERO \ + "jz 111f\n\t" \ + REFCOUNT_CHECK_LT_ZERO + +/* Trigger refcount exception unconditionally. */ +#define REFCOUNT_ERROR \ + "jmp 111f\n\t" \ + _REFCOUNT_EXCEPTION + +static __always_inline void refcount_add(unsigned int i, refcount_t *r) +{ + asm volatile(LOCK_PREFIX "addl %1,%0\n\t" + REFCOUNT_CHECK_LT_ZERO + : [counter] "+m" (r->refs.counter) + : "ir" (i) + : "cc", "cx"); +} + +static __always_inline void refcount_inc(refcount_t *r) +{ + asm volatile(LOCK_PREFIX "incl %0\n\t" + REFCOUNT_CHECK_LT_ZERO + : [counter] "+m" (r->refs.counter) + : : "cc", "cx"); +} + +static __always_inline void refcount_dec(refcount_t *r) +{ + asm volatile(LOCK_PREFIX "decl %0\n\t" + REFCOUNT_CHECK_LE_ZERO + : [counter] "+m" (r->refs.counter) + : : "cc", "cx"); +} + +static __always_inline __must_check +bool refcount_sub_and_test(unsigned int i, refcount_t *r) +{ + GEN_BINARY_SUFFIXED_RMWcc(LOCK_PREFIX "subl", REFCOUNT_CHECK_LT_ZERO, + r->refs.counter, "er", i, "%0", e); +} + +static __always_inline __must_check bool refcount_dec_and_test(refcount_t *r) +{ + GEN_UNARY_SUFFIXED_RMWcc(LOCK_PREFIX "decl", REFCOUNT_CHECK_LT_ZERO, + r->refs.counter, "%0", e); +} + +static __always_inline __must_check +bool refcount_add_not_zero(unsigned int i, refcount_t *r) +{ + int c, result; + + c = atomic_read(&(r->refs)); + do { + if (unlikely(c == 0)) + return false; + + result = c + i; + + /* Did we try to increment from/to an undesirable state? */ + if (unlikely(c < 0 || c == INT_MAX || result < c)) { + asm volatile(REFCOUNT_ERROR + : : [counter] "m" (r->refs.counter) + : "cc", "cx"); + break; + } + + } while (!atomic_try_cmpxchg(&(r->refs), &c, result)); + + return c != 0; +} + +static __always_inline __must_check bool refcount_inc_not_zero(refcount_t *r) +{ + return refcount_add_not_zero(1, r); +} + +#endif diff --git a/arch/x86/include/asm/rio.h b/arch/x86/include/asm/rio.h index 97bab6388a92..0a21986d2238 100644 --- a/arch/x86/include/asm/rio.h +++ b/arch/x86/include/asm/rio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Derived from include/asm-x86/mach-summit/mach_mpparse.h * and include/asm-x86/mach-default/bios_ebda.h diff --git a/arch/x86/include/asm/rmwcc.h b/arch/x86/include/asm/rmwcc.h index 661dd305694a..d8f3a6ae9f6c 100644 --- a/arch/x86/include/asm/rmwcc.h +++ b/arch/x86/include/asm/rmwcc.h @@ -1,45 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_RMWcc #define _ASM_X86_RMWcc +#define __CLOBBERS_MEM "memory" +#define __CLOBBERS_MEM_CC_CX "memory", "cc", "cx" + #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO) /* Use asm goto */ -#define __GEN_RMWcc(fullop, var, cc, ...) \ +#define __GEN_RMWcc(fullop, var, cc, clobbers, ...) \ do { \ asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \ - : : "m" (var), ## __VA_ARGS__ \ - : "memory" : cc_label); \ + : : [counter] "m" (var), ## __VA_ARGS__ \ + : clobbers : cc_label); \ return 0; \ cc_label: \ return 1; \ } while (0) -#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ - __GEN_RMWcc(op " " arg0, var, cc) +#define __BINARY_RMWcc_ARG " %1, " -#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ - __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val)) #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ /* Use flags output or a set instruction */ -#define __GEN_RMWcc(fullop, var, cc, ...) \ +#define __GEN_RMWcc(fullop, var, cc, clobbers, ...) \ do { \ bool c; \ asm volatile (fullop ";" CC_SET(cc) \ - : "+m" (var), CC_OUT(cc) (c) \ - : __VA_ARGS__ : "memory"); \ + : [counter] "+m" (var), CC_OUT(cc) (c) \ + : __VA_ARGS__ : clobbers); \ return c; \ } while (0) -#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ - __GEN_RMWcc(op " " arg0, var, cc) - -#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ - __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val)) +#define __BINARY_RMWcc_ARG " %2, " #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ +#define GEN_UNARY_RMWcc(op, var, arg0, cc) \ + __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM) + +#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc) \ + __GEN_RMWcc(op " " arg0 "\n\t" suffix, var, cc, \ + __CLOBBERS_MEM_CC_CX) + +#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc) \ + __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0, var, cc, \ + __CLOBBERS_MEM, vcon (val)) + +#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc) \ + __GEN_RMWcc(op __BINARY_RMWcc_ARG arg0 "\n\t" suffix, var, cc, \ + __CLOBBERS_MEM_CC_CX, vcon (val)) + #endif /* _ASM_X86_RMWcc */ diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index a34e0d4b957d..4d38d85a16ad 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* rwsem.h: R/W semaphores implemented using XADD/CMPXCHG for i486+ * * Written by David Howells (dhowells@redhat.com). @@ -103,7 +104,6 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) ({ \ long tmp; \ struct rw_semaphore* ret; \ - register void *__sp asm(_ASM_SP); \ \ asm volatile("# beginning down_write\n\t" \ LOCK_PREFIX " xadd %1,(%4)\n\t" \ @@ -114,7 +114,8 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem) " call " slow_path "\n" \ "1:\n" \ "# ending down_write" \ - : "+m" (sem->count), "=d" (tmp), "=a" (ret), "+r" (__sp) \ + : "+m" (sem->count), "=d" (tmp), \ + "=a" (ret), ASM_CALL_CONSTRAINT \ : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \ : "memory", "cc"); \ ret; \ diff --git a/arch/x86/include/asm/seccomp.h b/arch/x86/include/asm/seccomp.h index 0c8c7c8861b4..2bd1338de236 100644 --- a/arch/x86/include/asm/seccomp.h +++ b/arch/x86/include/asm/seccomp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SECCOMP_H #define _ASM_X86_SECCOMP_H diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h index 2f75f30cb2f6..d6baf23782bc 100644 --- a/arch/x86/include/asm/sections.h +++ b/arch/x86/include/asm/sections.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SECTIONS_H #define _ASM_X86_SECTIONS_H diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h index 1549caa098f0..b20f9d623f9c 100644 --- a/arch/x86/include/asm/segment.h +++ b/arch/x86/include/asm/segment.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SEGMENT_H #define _ASM_X86_SEGMENT_H @@ -238,9 +239,7 @@ #ifndef __ASSEMBLY__ extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; -#ifdef CONFIG_TRACING -# define trace_early_idt_handler_array early_idt_handler_array -#endif +extern void early_ignore_irq(void); /* * Load a segment. Fall back on loading the zero segment if something goes diff --git a/arch/x86/include/asm/serial.h b/arch/x86/include/asm/serial.h index bb658211edad..ece8299d2695 100644 --- a/arch/x86/include/asm/serial.h +++ b/arch/x86/include/asm/serial.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SERIAL_H #define _ASM_X86_SERIAL_H diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h index eaec6c364e42..bd090367236c 100644 --- a/arch/x86/include/asm/set_memory.h +++ b/arch/x86/include/asm/set_memory.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SET_MEMORY_H #define _ASM_X86_SET_MEMORY_H @@ -11,6 +12,7 @@ * Executability : eXeutable, NoteXecutable * Read/Write : ReadOnly, ReadWrite * Presence : NotPresent + * Encryption : Encrypted, Decrypted * * Within a category, the attributes are mutually exclusive. * @@ -42,6 +44,8 @@ int set_memory_wt(unsigned long addr, int numpages); int set_memory_wb(unsigned long addr, int numpages); int set_memory_np(unsigned long addr, int numpages); int set_memory_4k(unsigned long addr, int numpages); +int set_memory_encrypted(unsigned long addr, int numpages); +int set_memory_decrypted(unsigned long addr, int numpages); int set_memory_array_uc(unsigned long *addr, int addrinarray); int set_memory_array_wc(unsigned long *addr, int addrinarray); diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h index e4585a393965..ae13bc974416 100644 --- a/arch/x86/include/asm/setup.h +++ b/arch/x86/include/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SETUP_H #define _ASM_X86_SETUP_H @@ -39,6 +40,7 @@ static inline void vsmp_init(void) { } #endif void setup_bios_corruption_check(void); +void early_platform_quirks(void); extern unsigned long saved_video_mode; diff --git a/arch/x86/include/asm/shmparam.h b/arch/x86/include/asm/shmparam.h index 0880cf0917b9..c4041819c3e5 100644 --- a/arch/x86/include/asm/shmparam.h +++ b/arch/x86/include/asm/shmparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SHMPARAM_H #define _ASM_X86_SHMPARAM_H diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h index e6cd2c489dbb..140d890c2c98 100644 --- a/arch/x86/include/asm/sigcontext.h +++ b/arch/x86/include/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SIGCONTEXT_H #define _ASM_X86_SIGCONTEXT_H diff --git a/arch/x86/include/asm/sigframe.h b/arch/x86/include/asm/sigframe.h index 34edd1650bae..f176114c04d4 100644 --- a/arch/x86/include/asm/sigframe.h +++ b/arch/x86/include/asm/sigframe.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SIGFRAME_H #define _ASM_X86_SIGFRAME_H diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sighandling.h index 452c88b8ad06..bd26834724e5 100644 --- a/arch/x86/include/asm/sighandling.h +++ b/arch/x86/include/asm/sighandling.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SIGHANDLING_H #define _ASM_X86_SIGHANDLING_H diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h index 8af22be0fe61..5f9012ff52ed 100644 --- a/arch/x86/include/asm/signal.h +++ b/arch/x86/include/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SIGNAL_H #define _ASM_X86_SIGNAL_H diff --git a/arch/x86/include/asm/simd.h b/arch/x86/include/asm/simd.h index 6c8a7ed13365..a341c878e977 100644 --- a/arch/x86/include/asm/simd.h +++ b/arch/x86/include/asm/simd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 47103eca3775..461f53d27708 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SMP_H #define _ASM_X86_SMP_H #ifndef __ASSEMBLY__ diff --git a/arch/x86/include/asm/sparsemem.h b/arch/x86/include/asm/sparsemem.h index 1f5bee2c202f..4fc1e9d3c43e 100644 --- a/arch/x86/include/asm/sparsemem.h +++ b/arch/x86/include/asm/sparsemem.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SPARSEMEM_H #define _ASM_X86_SPARSEMEM_H diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 9efaabf5b54b..317fc59b512c 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SPECIAL_INSNS_H #define _ASM_X86_SPECIAL_INSNS_H @@ -135,6 +136,11 @@ static inline void native_wbinvd(void) extern asmlinkage void native_load_gs_index(unsigned); +static inline unsigned long __read_cr4(void) +{ + return native_read_cr4(); +} + #ifdef CONFIG_PARAVIRT #include #else @@ -173,11 +179,6 @@ static inline void write_cr3(unsigned long x) native_write_cr3(x); } -static inline unsigned long __read_cr4(void) -{ - return native_read_cr4(); -} - static inline void __write_cr4(unsigned long x) { native_write_cr4(x); diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index 6d391909e864..b34625796eb2 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SPINLOCK_H #define _ASM_X86_SPINLOCK_H diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h index 25311ebb446c..bf3e34b25afc 100644 --- a/arch/x86/include/asm/spinlock_types.h +++ b/arch/x86/include/asm/spinlock_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SPINLOCK_TYPES_H #define _ASM_X86_SPINLOCK_TYPES_H diff --git a/arch/x86/include/asm/sta2x11.h b/arch/x86/include/asm/sta2x11.h index e9d32df89ccc..e0975e9c4f47 100644 --- a/arch/x86/include/asm/sta2x11.h +++ b/arch/x86/include/asm/sta2x11.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Header file for STMicroelectronics ConneXt (STA2X11) IOHub */ diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index 8abedf1d650e..371b3a4af000 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * GCC stack protector support. * diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index 2e41c50ddf47..8da111b3c342 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h index 09224d7a5862..c3c2c1914d65 100644 --- a/arch/x86/include/asm/string.h +++ b/arch/x86/include/asm/string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_X86_32 # include #else diff --git a/arch/x86/include/asm/string_32.h b/arch/x86/include/asm/string_32.h index e9ee84873de5..076502241eae 100644 --- a/arch/x86/include/asm/string_32.h +++ b/arch/x86/include/asm/string_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_STRING_32_H #define _ASM_X86_STRING_32_H @@ -340,6 +341,30 @@ extern void *memset(void *, int, size_t); #endif #endif /* !CONFIG_FORTIFY_SOURCE */ +#define __HAVE_ARCH_MEMSET16 +static inline void *memset16(uint16_t *s, uint16_t v, size_t n) +{ + int d0, d1; + asm volatile("rep\n\t" + "stosw" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + +#define __HAVE_ARCH_MEMSET32 +static inline void *memset32(uint32_t *s, uint32_t v, size_t n) +{ + int d0, d1; + asm volatile("rep\n\t" + "stosl" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + /* * find the first occurrence of byte 'c', or 1 past the area if none */ diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h index 2a8c822de1fc..0b1b4445f4c5 100644 --- a/arch/x86/include/asm/string_64.h +++ b/arch/x86/include/asm/string_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_STRING_64_H #define _ASM_X86_STRING_64_H @@ -58,6 +59,42 @@ extern void *__memcpy(void *to, const void *from, size_t len); void *memset(void *s, int c, size_t n); void *__memset(void *s, int c, size_t n); +#define __HAVE_ARCH_MEMSET16 +static inline void *memset16(uint16_t *s, uint16_t v, size_t n) +{ + long d0, d1; + asm volatile("rep\n\t" + "stosw" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + +#define __HAVE_ARCH_MEMSET32 +static inline void *memset32(uint32_t *s, uint32_t v, size_t n) +{ + long d0, d1; + asm volatile("rep\n\t" + "stosl" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + +#define __HAVE_ARCH_MEMSET64 +static inline void *memset64(uint64_t *s, uint64_t v, size_t n) +{ + long d0, d1; + asm volatile("rep\n\t" + "stosq" + : "=&c" (d0), "=&D" (d1) + : "a" (v), "1" (s), "0" (n) + : "memory"); + return s; +} + #define __HAVE_ARCH_MEMMOVE void *memmove(void *dest, const void *src, size_t count); void *__memmove(void *dest, const void *src, size_t count); diff --git a/arch/x86/include/asm/suspend.h b/arch/x86/include/asm/suspend.h index 2fab6c2c3575..ecffe81ff65c 100644 --- a/arch/x86/include/asm/suspend.h +++ b/arch/x86/include/asm/suspend.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef CONFIG_X86_32 # include #else diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h index 8e9dbe7b73a1..982c325dad33 100644 --- a/arch/x86/include/asm/suspend_32.h +++ b/arch/x86/include/asm/suspend_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2001-2002 Pavel Machek * Based on code diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h index 2bd96b4df140..7306e911faee 100644 --- a/arch/x86/include/asm/suspend_64.h +++ b/arch/x86/include/asm/suspend_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2001-2003 Pavel Machek * Based on code diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 58fffe79e417..78dd9df88157 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SVM_H #define __SVM_H @@ -107,6 +108,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define V_IRQ_SHIFT 8 #define V_IRQ_MASK (1 << V_IRQ_SHIFT) +#define V_GIF_SHIFT 9 +#define V_GIF_MASK (1 << V_GIF_SHIFT) + #define V_INTR_PRIO_SHIFT 16 #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) @@ -116,6 +120,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define V_INTR_MASKING_SHIFT 24 #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) +#define V_GIF_ENABLE_SHIFT 25 +#define V_GIF_ENABLE_MASK (1 << V_GIF_ENABLE_SHIFT) + #define AVIC_ENABLE_SHIFT 31 #define AVIC_ENABLE_MASK (1 << AVIC_ENABLE_SHIFT) diff --git a/arch/x86/include/asm/swiotlb.h b/arch/x86/include/asm/swiotlb.h index d2f69b9ff732..bdf9aed40403 100644 --- a/arch/x86/include/asm/swiotlb.h +++ b/arch/x86/include/asm/swiotlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SWIOTLB_H #define _ASM_X86_SWIOTLB_H diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h index fcc5cd387fd1..899084b70412 100644 --- a/arch/x86/include/asm/switch_to.h +++ b/arch/x86/include/asm/switch_to.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SWITCH_TO_H #define _ASM_X86_SWITCH_TO_H diff --git a/arch/x86/include/asm/sync_bitops.h b/arch/x86/include/asm/sync_bitops.h index cbf8847d02a0..2fe745356fb1 100644 --- a/arch/x86/include/asm/sync_bitops.h +++ b/arch/x86/include/asm/sync_bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SYNC_BITOPS_H #define _ASM_X86_SYNC_BITOPS_H diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h index 90395063383c..2ecd34e2d46c 100644 --- a/arch/x86/include/asm/text-patching.h +++ b/arch/x86/include/asm/text-patching.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TEXT_PATCHING_H #define _ASM_X86_TEXT_PATCHING_H diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index e00e1bd6e7b3..70f425947dc5 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* thread_info.h: low-level thread information * * Copyright (C) 2002 David Howells (dhowells@redhat.com) @@ -98,6 +99,7 @@ struct thread_info { #define TIF_SYSCALL_TRACEPOINT 28 /* syscall tracepoint instrumentation */ #define TIF_ADDR32 29 /* 32-bit address space on 64 bits */ #define TIF_X32 30 /* 32-bit native x86-64 binary */ +#define TIF_FSCHECK 31 /* Check FS is USER_DS on return */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) @@ -122,6 +124,7 @@ struct thread_info { #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_ADDR32 (1 << TIF_ADDR32) #define _TIF_X32 (1 << TIF_X32) +#define _TIF_FSCHECK (1 << TIF_FSCHECK) /* * work to do in syscall_trace_enter(). Also includes TIF_NOHZ for @@ -137,7 +140,8 @@ struct thread_info { (_TIF_SYSCALL_TRACE | _TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \ _TIF_NEED_RESCHED | _TIF_SINGLESTEP | _TIF_SYSCALL_EMU | \ _TIF_SYSCALL_AUDIT | _TIF_USER_RETURN_NOTIFY | _TIF_UPROBE | \ - _TIF_PATCH_PENDING | _TIF_NOHZ | _TIF_SYSCALL_TRACEPOINT) + _TIF_PATCH_PENDING | _TIF_NOHZ | _TIF_SYSCALL_TRACEPOINT | \ + _TIF_FSCHECK) /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ @@ -155,17 +159,6 @@ struct thread_info { */ #ifndef __ASSEMBLY__ -static inline unsigned long current_stack_pointer(void) -{ - unsigned long sp; -#ifdef CONFIG_X86_64 - asm("mov %%rsp,%0" : "=g" (sp)); -#else - asm("mov %%esp,%0" : "=g" (sp)); -#endif - return sp; -} - /* * Walks up the stack frames to make sure that the specified object is * entirely contained by a single stack frame. diff --git a/arch/x86/include/asm/time.h b/arch/x86/include/asm/time.h index 92b8aec06970..cef818b16045 100644 --- a/arch/x86/include/asm/time.h +++ b/arch/x86/include/asm/time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TIME_H #define _ASM_X86_TIME_H diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h index 2016962103df..47457ab975fd 100644 --- a/arch/x86/include/asm/timer.h +++ b/arch/x86/include/asm/timer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TIMER_H #define _ASM_X86_TIMER_H #include diff --git a/arch/x86/include/asm/timex.h b/arch/x86/include/asm/timex.h index 1375cfc93960..a4a8b1b16c0c 100644 --- a/arch/x86/include/asm/timex.h +++ b/arch/x86/include/asm/timex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TIMEX_H #define _ASM_X86_TIMEX_H diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index c7797307fc2b..cb0a1f470980 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TLB_H #define _ASM_X86_TLB_H @@ -15,4 +16,18 @@ #include +/* + * While x86 architecture in general requires an IPI to perform TLB + * shootdown, enablement code for several hypervisors overrides + * .flush_tlb_others hook in pv_mmu_ops and implements it by issuing + * a hypercall. To keep software pagetable walkers safe in this case we + * switch to RCU based table free (HAVE_RCU_TABLE_FREE). See the comment + * below 'ifdef CONFIG_HAVE_RCU_TABLE_FREE' in include/asm-generic/tlb.h + * for more details. + */ +static inline void __tlb_remove_table(void *table) +{ + free_page_and_swap_cache(table); +} + #endif /* _ASM_X86_TLB_H */ diff --git a/arch/x86/include/asm/tlbbatch.h b/arch/x86/include/asm/tlbbatch.h index f4a6ff352a0e..1ad56eb3e8a8 100644 --- a/arch/x86/include/asm/tlbbatch.h +++ b/arch/x86/include/asm/tlbbatch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ARCH_X86_TLBBATCH_H #define _ARCH_X86_TLBBATCH_H diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 50ea3482e1d1..509046cfa5ce 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TLBFLUSH_H #define _ASM_X86_TLBFLUSH_H @@ -57,6 +58,23 @@ static inline void invpcid_flush_all_nonglobals(void) __invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL); } +static inline u64 inc_mm_tlb_gen(struct mm_struct *mm) +{ + u64 new_tlb_gen; + + /* + * Bump the generation count. This also serves as a full barrier + * that synchronizes with switch_mm(): callers are required to order + * their read of mm_cpumask after their writes to the paging + * structures. + */ + smp_mb__before_atomic(); + new_tlb_gen = atomic64_inc_return(&mm->context.tlb_gen); + smp_mb__after_atomic(); + + return new_tlb_gen; +} + #ifdef CONFIG_PARAVIRT #include #else @@ -65,6 +83,33 @@ static inline void invpcid_flush_all_nonglobals(void) #define __flush_tlb_single(addr) __native_flush_tlb_single(addr) #endif +static inline bool tlb_defer_switch_to_init_mm(void) +{ + /* + * If we have PCID, then switching to init_mm is reasonably + * fast. If we don't have PCID, then switching to init_mm is + * quite slow, so we try to defer it in the hopes that we can + * avoid it entirely. The latter approach runs the risk of + * receiving otherwise unnecessary IPIs. + * + * This choice is just a heuristic. The tlb code can handle this + * function returning true or false regardless of whether we have + * PCID. + */ + return !static_cpu_has(X86_FEATURE_PCID); +} + +/* + * 6 because 6 should be plenty and struct tlb_state will fit in + * two cache lines. + */ +#define TLB_NR_DYN_ASIDS 6 + +struct tlb_context { + u64 ctx_id; + u64 tlb_gen; +}; + struct tlb_state { /* * cpu_tlbstate.loaded_mm should match CR3 whenever interrupts @@ -73,13 +118,52 @@ struct tlb_state { * mode even if we've already switched back to swapper_pg_dir. */ struct mm_struct *loaded_mm; - int state; + u16 loaded_mm_asid; + u16 next_asid; + + /* + * We can be in one of several states: + * + * - Actively using an mm. Our CPU's bit will be set in + * mm_cpumask(loaded_mm) and is_lazy == false; + * + * - Not using a real mm. loaded_mm == &init_mm. Our CPU's bit + * will not be set in mm_cpumask(&init_mm) and is_lazy == false. + * + * - Lazily using a real mm. loaded_mm != &init_mm, our bit + * is set in mm_cpumask(loaded_mm), but is_lazy == true. + * We're heuristically guessing that the CR3 load we + * skipped more than makes up for the overhead added by + * lazy mode. + */ + bool is_lazy; /* * Access to this CR4 shadow and to H/W CR4 is protected by * disabling interrupts when modifying either one. */ unsigned long cr4; + + /* + * This is a list of all contexts that might exist in the TLB. + * There is one per ASID that we use, and the ASID (what the + * CPU calls PCID) is the index into ctxts. + * + * For each context, ctx_id indicates which mm the TLB's user + * entries came from. As an invariant, the TLB will never + * contain entries that are out-of-date as when that mm reached + * the tlb_gen in the list. + * + * To be clear, this means that it's legal for the TLB code to + * flush the TLB without updating tlb_gen. This can happen + * (for now, at least) due to paravirt remote flushes. + * + * NB: context 0 is a bit special, since it's also used by + * various bits of init code. This is fine -- code that + * isn't aware of PCID will end up harmlessly flushing + * context 0. + */ + struct tlb_context ctxs[TLB_NR_DYN_ASIDS]; }; DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate); @@ -148,6 +232,8 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask) cr4_set_bits(mask); } +extern void initialize_tlbstate_and_flush(void); + static inline void __native_flush_tlb(void) { /* @@ -207,6 +293,14 @@ static inline void __flush_tlb_all(void) __flush_tlb_global(); else __flush_tlb(); + + /* + * Note: if we somehow had PCID but not PGE, then this wouldn't work -- + * we'd end up flushing kernel translations for the current ASID but + * we might fail to flush kernel translations for other cached ASIDs. + * + * To avoid this issue, we force PCID off if PGE is off. + */ } static inline void __flush_tlb_one(unsigned long addr) @@ -231,9 +325,26 @@ static inline void __flush_tlb_one(unsigned long addr) * and page-granular flushes are available only on i486 and up. */ struct flush_tlb_info { - struct mm_struct *mm; - unsigned long start; - unsigned long end; + /* + * We support several kinds of flushes. + * + * - Fully flush a single mm. .mm will be set, .end will be + * TLB_FLUSH_ALL, and .new_tlb_gen will be the tlb_gen to + * which the IPI sender is trying to catch us up. + * + * - Partially flush a single mm. .mm will be set, .start and + * .end will indicate the range, and .new_tlb_gen will be set + * such that the changes between generation .new_tlb_gen-1 and + * .new_tlb_gen are entirely contained in the indicated range. + * + * - Fully flush all mms whose tlb_gens have been updated. .mm + * will be NULL, .end will be TLB_FLUSH_ALL, and .new_tlb_gen + * will be zero. + */ + struct mm_struct *mm; + unsigned long start; + unsigned long end; + u64 new_tlb_gen; }; #define local_flush_tlb() __flush_tlb() @@ -256,12 +367,10 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a) void native_flush_tlb_others(const struct cpumask *cpumask, const struct flush_tlb_info *info); -#define TLBSTATE_OK 1 -#define TLBSTATE_LAZY 2 - static inline void arch_tlbbatch_add_mm(struct arch_tlbflush_unmap_batch *batch, struct mm_struct *mm) { + inc_mm_tlb_gen(mm); cpumask_or(&batch->cpumask, &batch->cpumask, mm_cpumask(mm)); } diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 6358a85e2270..c1d2a9892352 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -75,12 +75,6 @@ static inline const struct cpumask *cpumask_of_node(int node) extern void setup_node_to_cpumask_map(void); -/* - * Returns the number of the node containing Node 'node'. This - * architecture is flat, so it is a pretty simple function! - */ -#define parent_node(node) (node) - #define pcibus_to_node(bus) __pcibus_to_node(bus) extern int __node_distance(int, int); diff --git a/arch/x86/include/asm/trace/common.h b/arch/x86/include/asm/trace/common.h new file mode 100644 index 000000000000..57c8da027d99 --- /dev/null +++ b/arch/x86/include/asm/trace/common.h @@ -0,0 +1,16 @@ +#ifndef _ASM_TRACE_COMMON_H +#define _ASM_TRACE_COMMON_H + +#ifdef CONFIG_TRACING +DECLARE_STATIC_KEY_FALSE(trace_pagefault_key); +#define trace_pagefault_enabled() \ + static_branch_unlikely(&trace_pagefault_key) +DECLARE_STATIC_KEY_FALSE(trace_resched_ipi_key); +#define trace_resched_ipi_enabled() \ + static_branch_unlikely(&trace_resched_ipi_key) +#else +static inline bool trace_pagefault_enabled(void) { return false; } +static inline bool trace_resched_ipi_enabled(void) { return false; } +#endif + +#endif diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h index 2422b14c50a7..69615e387973 100644 --- a/arch/x86/include/asm/trace/exceptions.h +++ b/arch/x86/include/asm/trace/exceptions.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM exceptions @@ -5,9 +6,10 @@ #define _TRACE_PAGE_FAULT_H #include +#include -extern int trace_irq_vector_regfunc(void); -extern void trace_irq_vector_unregfunc(void); +extern int trace_pagefault_reg(void); +extern void trace_pagefault_unreg(void); DECLARE_EVENT_CLASS(x86_exceptions, @@ -37,8 +39,7 @@ DEFINE_EVENT_FN(x86_exceptions, name, \ TP_PROTO(unsigned long address, struct pt_regs *regs, \ unsigned long error_code), \ TP_ARGS(address, regs, error_code), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); + trace_pagefault_reg, trace_pagefault_unreg); DEFINE_PAGE_FAULT_EVENT(page_fault_user); DEFINE_PAGE_FAULT_EVENT(page_fault_kernel); diff --git a/arch/x86/include/asm/trace/fpu.h b/arch/x86/include/asm/trace/fpu.h index 342e59789fcd..fa60398bbc3a 100644 --- a/arch/x86/include/asm/trace/fpu.h +++ b/arch/x86/include/asm/trace/fpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM x86_fpu @@ -12,25 +13,22 @@ DECLARE_EVENT_CLASS(x86_fpu, TP_STRUCT__entry( __field(struct fpu *, fpu) - __field(bool, fpregs_active) - __field(bool, fpstate_active) + __field(bool, initialized) __field(u64, xfeatures) __field(u64, xcomp_bv) ), TP_fast_assign( __entry->fpu = fpu; - __entry->fpregs_active = fpu->fpregs_active; - __entry->fpstate_active = fpu->fpstate_active; + __entry->initialized = fpu->initialized; if (boot_cpu_has(X86_FEATURE_OSXSAVE)) { __entry->xfeatures = fpu->state.xsave.header.xfeatures; __entry->xcomp_bv = fpu->state.xsave.header.xcomp_bv; } ), - TP_printk("x86/fpu: %p fpregs_active: %d fpstate_active: %d xfeatures: %llx xcomp_bv: %llx", + TP_printk("x86/fpu: %p initialized: %d xfeatures: %llx xcomp_bv: %llx", __entry->fpu, - __entry->fpregs_active, - __entry->fpstate_active, + __entry->initialized, __entry->xfeatures, __entry->xcomp_bv ) diff --git a/arch/x86/include/asm/trace/hyperv.h b/arch/x86/include/asm/trace/hyperv.h new file mode 100644 index 000000000000..4253bca99989 --- /dev/null +++ b/arch/x86/include/asm/trace/hyperv.h @@ -0,0 +1,40 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM hyperv + +#if !defined(_TRACE_HYPERV_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HYPERV_H + +#include + +#if IS_ENABLED(CONFIG_HYPERV) + +TRACE_EVENT(hyperv_mmu_flush_tlb_others, + TP_PROTO(const struct cpumask *cpus, + const struct flush_tlb_info *info), + TP_ARGS(cpus, info), + TP_STRUCT__entry( + __field(unsigned int, ncpus) + __field(struct mm_struct *, mm) + __field(unsigned long, addr) + __field(unsigned long, end) + ), + TP_fast_assign(__entry->ncpus = cpumask_weight(cpus); + __entry->mm = info->mm; + __entry->addr = info->start; + __entry->end = info->end; + ), + TP_printk("ncpus %d mm %p addr %lx, end %lx", + __entry->ncpus, __entry->mm, + __entry->addr, __entry->end) + ); + +#endif /* CONFIG_HYPERV */ + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH asm/trace/ +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE hyperv +#endif /* _TRACE_HYPERV_H */ + +/* This part must be outside protection */ +#include diff --git a/arch/x86/include/asm/trace/irq_vectors.h b/arch/x86/include/asm/trace/irq_vectors.h index 32dd6a9e343c..8eb139ed1a03 100644 --- a/arch/x86/include/asm/trace/irq_vectors.h +++ b/arch/x86/include/asm/trace/irq_vectors.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM irq_vectors @@ -5,9 +6,12 @@ #define _TRACE_IRQ_VECTORS_H #include +#include -extern int trace_irq_vector_regfunc(void); -extern void trace_irq_vector_unregfunc(void); +#ifdef CONFIG_X86_LOCAL_APIC + +extern int trace_resched_ipi_reg(void); +extern void trace_resched_ipi_unreg(void); DECLARE_EVENT_CLASS(x86_irq_vector, @@ -26,17 +30,24 @@ DECLARE_EVENT_CLASS(x86_irq_vector, TP_printk("vector=%d", __entry->vector) ); #define DEFINE_IRQ_VECTOR_EVENT(name) \ +DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ + TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); \ +DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ + TP_PROTO(int vector), \ + TP_ARGS(vector), NULL, NULL); + +#define DEFINE_RESCHED_IPI_EVENT(name) \ DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \ TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); \ + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg); \ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ TP_PROTO(int vector), \ TP_ARGS(vector), \ - trace_irq_vector_regfunc, \ - trace_irq_vector_unregfunc); - + trace_resched_ipi_reg, \ + trace_resched_ipi_unreg); /* * local_timer - called when entering/exiting a local timer interrupt @@ -44,11 +55,6 @@ DEFINE_EVENT_FN(x86_irq_vector, name##_exit, \ */ DEFINE_IRQ_VECTOR_EVENT(local_timer); -/* - * reschedule - called when entering/exiting a reschedule vector handler - */ -DEFINE_IRQ_VECTOR_EVENT(reschedule); - /* * spurious_apic - called when entering/exiting a spurious apic vector handler */ @@ -65,6 +71,7 @@ DEFINE_IRQ_VECTOR_EVENT(error_apic); */ DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi); +#ifdef CONFIG_IRQ_WORK /* * irq_work - called when entering/exiting a irq work interrupt * vector handler @@ -81,6 +88,18 @@ DEFINE_IRQ_VECTOR_EVENT(irq_work); * 4) goto 1 */ TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0); +#endif + +/* + * The ifdef is required because that tracepoint macro hell emits tracepoint + * code in files which include this header even if the tracepoint is not + * enabled. Brilliant stuff that. + */ +#ifdef CONFIG_SMP +/* + * reschedule - called when entering/exiting a reschedule vector handler + */ +DEFINE_RESCHED_IPI_EVENT(reschedule); /* * call_function - called when entering/exiting a call function interrupt @@ -93,24 +112,33 @@ DEFINE_IRQ_VECTOR_EVENT(call_function); * single interrupt vector handler */ DEFINE_IRQ_VECTOR_EVENT(call_function_single); +#endif +#ifdef CONFIG_X86_MCE_THRESHOLD /* * threshold_apic - called when entering/exiting a threshold apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT(threshold_apic); +#endif +#ifdef CONFIG_X86_MCE_AMD /* * deferred_error_apic - called when entering/exiting a deferred apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic); +#endif +#ifdef CONFIG_X86_THERMAL_VECTOR /* * thermal_apic - called when entering/exiting a thermal apic interrupt * vector handler */ DEFINE_IRQ_VECTOR_EVENT(thermal_apic); +#endif + +#endif /* CONFIG_X86_LOCAL_APIC */ #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . diff --git a/arch/x86/include/asm/trace/mpx.h b/arch/x86/include/asm/trace/mpx.h index 0f492fc50bce..7bd92db09e8d 100644 --- a/arch/x86/include/asm/trace/mpx.h +++ b/arch/x86/include/asm/trace/mpx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM mpx diff --git a/arch/x86/include/asm/trace_clock.h b/arch/x86/include/asm/trace_clock.h index beab86cc282d..7061a5650969 100644 --- a/arch/x86/include/asm/trace_clock.h +++ b/arch/x86/include/asm/trace_clock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TRACE_CLOCK_H #define _ASM_X86_TRACE_CLOCK_H diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 01fd0a7f48cd..b0cced97a6ce 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TRAPS_H #define _ASM_X86_TRAPS_H @@ -13,9 +14,6 @@ asmlinkage void divide_error(void); asmlinkage void debug(void); asmlinkage void nmi(void); asmlinkage void int3(void); -asmlinkage void xen_debug(void); -asmlinkage void xen_int3(void); -asmlinkage void xen_stack_segment(void); asmlinkage void overflow(void); asmlinkage void bounds(void); asmlinkage void invalid_op(void); @@ -38,22 +36,29 @@ asmlinkage void machine_check(void); #endif /* CONFIG_X86_MCE */ asmlinkage void simd_coprocessor_error(void); -#ifdef CONFIG_TRACING -asmlinkage void trace_page_fault(void); -#define trace_stack_segment stack_segment -#define trace_divide_error divide_error -#define trace_bounds bounds -#define trace_invalid_op invalid_op -#define trace_device_not_available device_not_available -#define trace_coprocessor_segment_overrun coprocessor_segment_overrun -#define trace_invalid_TSS invalid_TSS -#define trace_segment_not_present segment_not_present -#define trace_general_protection general_protection -#define trace_spurious_interrupt_bug spurious_interrupt_bug -#define trace_coprocessor_error coprocessor_error -#define trace_alignment_check alignment_check -#define trace_simd_coprocessor_error simd_coprocessor_error -#define trace_async_page_fault async_page_fault +#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV) +asmlinkage void xen_divide_error(void); +asmlinkage void xen_xendebug(void); +asmlinkage void xen_xenint3(void); +asmlinkage void xen_nmi(void); +asmlinkage void xen_overflow(void); +asmlinkage void xen_bounds(void); +asmlinkage void xen_invalid_op(void); +asmlinkage void xen_device_not_available(void); +asmlinkage void xen_double_fault(void); +asmlinkage void xen_coprocessor_segment_overrun(void); +asmlinkage void xen_invalid_TSS(void); +asmlinkage void xen_segment_not_present(void); +asmlinkage void xen_stack_segment(void); +asmlinkage void xen_general_protection(void); +asmlinkage void xen_page_fault(void); +asmlinkage void xen_spurious_interrupt_bug(void); +asmlinkage void xen_coprocessor_error(void); +asmlinkage void xen_alignment_check(void); +#ifdef CONFIG_X86_MCE +asmlinkage void xen_machine_check(void); +#endif /* CONFIG_X86_MCE */ +asmlinkage void xen_simd_coprocessor_error(void); #endif dotraplinkage void do_divide_error(struct pt_regs *, long); @@ -74,14 +79,6 @@ asmlinkage struct pt_regs *sync_regs(struct pt_regs *); #endif dotraplinkage void do_general_protection(struct pt_regs *, long); dotraplinkage void do_page_fault(struct pt_regs *, unsigned long); -#ifdef CONFIG_TRACING -dotraplinkage void trace_do_page_fault(struct pt_regs *, unsigned long); -#else -static inline void trace_do_page_fault(struct pt_regs *regs, unsigned long error) -{ - do_page_fault(regs, error); -} -#endif dotraplinkage void do_spurious_interrupt_bug(struct pt_regs *, long); dotraplinkage void do_coprocessor_error(struct pt_regs *, long); dotraplinkage void do_alignment_check(struct pt_regs *, long); diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index f5e6f1c417df..8da0efb13544 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * x86 TSC related functions */ diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 30269dafec47..574dff4d2913 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_UACCESS_H #define _ASM_X86_UACCESS_H /* @@ -26,7 +27,12 @@ #define get_ds() (KERNEL_DS) #define get_fs() (current->thread.addr_limit) -#define set_fs(x) (current->thread.addr_limit = (x)) +static inline void set_fs(mm_segment_t fs) +{ + current->thread.addr_limit = fs; + /* On user-mode return, check fs is correct */ + set_thread_flag(TIF_FSCHECK); +} #define segment_eq(a, b) ((a).seg == (b).seg) @@ -161,11 +167,11 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) ({ \ int __ret_gu; \ register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ - register void *__sp asm(_ASM_SP); \ __chk_user_ptr(ptr); \ might_fault(); \ asm volatile("call __get_user_%P4" \ - : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) \ + : "=a" (__ret_gu), "=r" (__val_gu), \ + ASM_CALL_CONSTRAINT \ : "0" (ptr), "i" (sizeof(*(ptr)))); \ (x) = (__force __typeof__(*(ptr))) __val_gu; \ __builtin_expect(__ret_gu, 0); \ @@ -332,7 +338,7 @@ do { \ _ASM_EXTABLE(1b, 4b) \ _ASM_EXTABLE(2b, 4b) \ : "=r" (retval), "=&A"(x) \ - : "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \ + : "m" (__m(__ptr)), "m" __m(((u32 __user *)(__ptr)) + 1), \ "i" (errret), "0" (retval)); \ }) diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h index aeda9bb8af50..72950401b223 100644 --- a/arch/x86/include/asm/uaccess_32.h +++ b/arch/x86/include/asm/uaccess_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_UACCESS_32_H #define _ASM_X86_UACCESS_32_H diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index b16f6a1d8b26..f07ef3c575db 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_UACCESS_64_H #define _ASM_X86_UACCESS_64_H diff --git a/arch/x86/include/asm/unaligned.h b/arch/x86/include/asm/unaligned.h index a7bd416b4763..9c754a7447aa 100644 --- a/arch/x86/include/asm/unaligned.h +++ b/arch/x86/include/asm/unaligned.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_UNALIGNED_H #define _ASM_X86_UNALIGNED_H diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h index 1ba1536f627e..51c4eee00732 100644 --- a/arch/x86/include/asm/unistd.h +++ b/arch/x86/include/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_UNISTD_H #define _ASM_X86_UNISTD_H 1 diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index e6676495b125..87adc0d38c4a 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_UNWIND_H #define _ASM_X86_UNWIND_H @@ -12,11 +13,14 @@ struct unwind_state { struct task_struct *task; int graph_idx; bool error; -#ifdef CONFIG_FRAME_POINTER +#if defined(CONFIG_ORC_UNWINDER) + bool signal, full_regs; + unsigned long sp, bp, ip; + struct pt_regs *regs; +#elif defined(CONFIG_FRAME_POINTER_UNWINDER) bool got_irq; - unsigned long *bp, *orig_sp; + unsigned long *bp, *orig_sp, ip; struct pt_regs *regs; - unsigned long ip; #else unsigned long *sp; #endif @@ -24,16 +28,20 @@ struct unwind_state { void __unwind_start(struct unwind_state *state, struct task_struct *task, struct pt_regs *regs, unsigned long *first_frame); - bool unwind_next_frame(struct unwind_state *state); - unsigned long unwind_get_return_address(struct unwind_state *state); +unsigned long *unwind_get_return_address_ptr(struct unwind_state *state); static inline bool unwind_done(struct unwind_state *state) { return state->stack_info.type == STACK_TYPE_UNKNOWN; } +static inline bool unwind_error(struct unwind_state *state) +{ + return state->error; +} + static inline void unwind_start(struct unwind_state *state, struct task_struct *task, struct pt_regs *regs, unsigned long *first_frame) @@ -43,22 +51,7 @@ void unwind_start(struct unwind_state *state, struct task_struct *task, __unwind_start(state, task, regs, first_frame); } -static inline bool unwind_error(struct unwind_state *state) -{ - return state->error; -} - -#ifdef CONFIG_FRAME_POINTER - -static inline -unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) -{ - if (unwind_done(state)) - return NULL; - - return state->regs ? &state->regs->ip : state->bp + 1; -} - +#if defined(CONFIG_ORC_UNWINDER) || defined(CONFIG_FRAME_POINTER_UNWINDER) static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) { if (unwind_done(state)) @@ -66,20 +59,46 @@ static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) return state->regs; } - -#else /* !CONFIG_FRAME_POINTER */ - -static inline -unsigned long *unwind_get_return_address_ptr(struct unwind_state *state) -{ - return NULL; -} - +#else static inline struct pt_regs *unwind_get_entry_regs(struct unwind_state *state) { return NULL; } +#endif -#endif /* CONFIG_FRAME_POINTER */ +#ifdef CONFIG_ORC_UNWINDER +void unwind_init(void); +void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size); +#else +static inline void unwind_init(void) {} +static inline +void unwind_module_init(struct module *mod, void *orc_ip, size_t orc_ip_size, + void *orc, size_t orc_size) {} +#endif + +/* + * This disables KASAN checking when reading a value from another task's stack, + * since the other task could be running on another CPU and could have poisoned + * the stack in the meantime. + */ +#define READ_ONCE_TASK_STACK(task, x) \ +({ \ + unsigned long val; \ + if (task == current) \ + val = READ_ONCE(x); \ + else \ + val = READ_ONCE_NOCHECK(x); \ + val; \ +}) + +static inline bool task_on_another_cpu(struct task_struct *task) +{ +#ifdef CONFIG_SMP + return task != current && task->on_cpu; +#else + return false; +#endif +} #endif /* _ASM_X86_UNWIND_H */ diff --git a/arch/x86/include/asm/unwind_hints.h b/arch/x86/include/asm/unwind_hints.h new file mode 100644 index 000000000000..bae46fc6b9de --- /dev/null +++ b/arch/x86/include/asm/unwind_hints.h @@ -0,0 +1,105 @@ +#ifndef _ASM_X86_UNWIND_HINTS_H +#define _ASM_X86_UNWIND_HINTS_H + +#include "orc_types.h" + +#ifdef __ASSEMBLY__ + +/* + * In asm, there are two kinds of code: normal C-type callable functions and + * the rest. The normal callable functions can be called by other code, and + * don't do anything unusual with the stack. Such normal callable functions + * are annotated with the ENTRY/ENDPROC macros. Most asm code falls in this + * category. In this case, no special debugging annotations are needed because + * objtool can automatically generate the ORC data for the ORC unwinder to read + * at runtime. + * + * Anything which doesn't fall into the above category, such as syscall and + * interrupt handlers, tends to not be called directly by other functions, and + * often does unusual non-C-function-type things with the stack pointer. Such + * code needs to be annotated such that objtool can understand it. The + * following CFI hint macros are for this type of code. + * + * These macros provide hints to objtool about the state of the stack at each + * instruction. Objtool starts from the hints and follows the code flow, + * making automatic CFI adjustments when it sees pushes and pops, filling out + * the debuginfo as necessary. It will also warn if it sees any + * inconsistencies. + */ +.macro UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=0 type=ORC_TYPE_CALL +#ifdef CONFIG_STACK_VALIDATION +.Lunwind_hint_ip_\@: + .pushsection .discard.unwind_hints + /* struct unwind_hint */ + .long .Lunwind_hint_ip_\@ - . + .short \sp_offset + .byte \sp_reg + .byte \type + .popsection +#endif +.endm + +.macro UNWIND_HINT_EMPTY + UNWIND_HINT sp_reg=ORC_REG_UNDEFINED +.endm + +.macro UNWIND_HINT_REGS base=%rsp offset=0 indirect=0 extra=1 iret=0 + .if \base == %rsp + .if \indirect + .set sp_reg, ORC_REG_SP_INDIRECT + .else + .set sp_reg, ORC_REG_SP + .endif + .elseif \base == %rbp + .set sp_reg, ORC_REG_BP + .elseif \base == %rdi + .set sp_reg, ORC_REG_DI + .elseif \base == %rdx + .set sp_reg, ORC_REG_DX + .elseif \base == %r10 + .set sp_reg, ORC_REG_R10 + .else + .error "UNWIND_HINT_REGS: bad base register" + .endif + + .set sp_offset, \offset + + .if \iret + .set type, ORC_TYPE_REGS_IRET + .elseif \extra == 0 + .set type, ORC_TYPE_REGS_IRET + .set sp_offset, \offset + (16*8) + .else + .set type, ORC_TYPE_REGS + .endif + + UNWIND_HINT sp_reg=sp_reg sp_offset=sp_offset type=type +.endm + +.macro UNWIND_HINT_IRET_REGS base=%rsp offset=0 + UNWIND_HINT_REGS base=\base offset=\offset iret=1 +.endm + +.macro UNWIND_HINT_FUNC sp_offset=8 + UNWIND_HINT sp_offset=\sp_offset +.endm + +#else /* !__ASSEMBLY__ */ + +#define UNWIND_HINT(sp_reg, sp_offset, type) \ + "987: \n\t" \ + ".pushsection .discard.unwind_hints\n\t" \ + /* struct unwind_hint */ \ + ".long 987b - .\n\t" \ + ".short " __stringify(sp_offset) "\n\t" \ + ".byte " __stringify(sp_reg) "\n\t" \ + ".byte " __stringify(type) "\n\t" \ + ".popsection\n\t" + +#define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE) + +#define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE) + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_X86_UNWIND_HINTS_H */ diff --git a/arch/x86/include/asm/user.h b/arch/x86/include/asm/user.h index 59a54e869f15..413c91746b27 100644 --- a/arch/x86/include/asm/user.h +++ b/arch/x86/include/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_USER_H #define _ASM_X86_USER_H diff --git a/arch/x86/include/asm/user32.h b/arch/x86/include/asm/user32.h index 14cbb73ebcba..fa577312f63a 100644 --- a/arch/x86/include/asm/user32.h +++ b/arch/x86/include/asm/user32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_USER32_H #define _ASM_X86_USER32_H diff --git a/arch/x86/include/asm/user_32.h b/arch/x86/include/asm/user_32.h index bebfd8644016..d72c3d66e94f 100644 --- a/arch/x86/include/asm/user_32.h +++ b/arch/x86/include/asm/user_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_USER_32_H #define _ASM_X86_USER_32_H diff --git a/arch/x86/include/asm/user_64.h b/arch/x86/include/asm/user_64.h index faf2cd3e0d76..db909923611c 100644 --- a/arch/x86/include/asm/user_64.h +++ b/arch/x86/include/asm/user_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_USER_64_H #define _ASM_X86_USER_64_H diff --git a/arch/x86/include/asm/uv/uv.h b/arch/x86/include/asm/uv/uv.h index b5a32231abd8..a80c0673798f 100644 --- a/arch/x86/include/asm/uv/uv.h +++ b/arch/x86/include/asm/uv/uv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_UV_UV_H #define _ASM_X86_UV_UV_H diff --git a/arch/x86/include/asm/vdso.h b/arch/x86/include/asm/vdso.h index bccdf4938ddf..27566e57e87d 100644 --- a/arch/x86/include/asm/vdso.h +++ b/arch/x86/include/asm/vdso.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_VDSO_H #define _ASM_X86_VDSO_H diff --git a/arch/x86/include/asm/vga.h b/arch/x86/include/asm/vga.h index c4b9dc2f67c5..46f9b2deab4d 100644 --- a/arch/x86/include/asm/vga.h +++ b/arch/x86/include/asm/vga.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access to VGA videoram * @@ -7,12 +8,24 @@ #ifndef _ASM_X86_VGA_H #define _ASM_X86_VGA_H +#include + /* * On the PC, we can just recalculate addresses and then * access the videoram directly without any black magic. + * To support memory encryption however, we need to access + * the videoram as decrypted memory. */ -#define VGA_MAP_MEM(x, s) (unsigned long)phys_to_virt(x) +#define VGA_MAP_MEM(x, s) \ +({ \ + unsigned long start = (unsigned long)phys_to_virt(x); \ + \ + if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) \ + set_memory_decrypted(start, (s) >> PAGE_SHIFT); \ + \ + start; \ +}) #define vga_readb(x) (*(x)) #define vga_writeb(x, y) (*(y) = (x)) diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h index 022e59714562..52250681f68c 100644 --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_VGTOD_H #define _ASM_X86_VGTOD_H diff --git a/arch/x86/include/asm/vm86.h b/arch/x86/include/asm/vm86.h index 1e491f3af317..26efbec94448 100644 --- a/arch/x86/include/asm/vm86.h +++ b/arch/x86/include/asm/vm86.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_VM86_H #define _ASM_X86_VM86_H diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 35cd06f636ab..caec8417539f 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -72,6 +72,7 @@ #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 #define SECONDARY_EXEC_RDRAND 0x00000800 #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 +#define SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000 #define SECONDARY_EXEC_SHADOW_VMCS 0x00004000 #define SECONDARY_EXEC_RDSEED 0x00010000 #define SECONDARY_EXEC_ENABLE_PML 0x00020000 @@ -114,6 +115,10 @@ #define VMX_MISC_SAVE_EFER_LMA 0x00000020 #define VMX_MISC_ACTIVITY_HLT 0x00000040 +/* VMFUNC functions */ +#define VMX_VMFUNC_EPTP_SWITCHING 0x00000001 +#define VMFUNC_EPTP_ENTRIES 512 + static inline u32 vmx_basic_vmcs_revision_id(u64 vmx_basic) { return vmx_basic & GENMASK_ULL(30, 0); @@ -187,6 +192,8 @@ enum vmcs_field { APIC_ACCESS_ADDR_HIGH = 0x00002015, POSTED_INTR_DESC_ADDR = 0x00002016, POSTED_INTR_DESC_ADDR_HIGH = 0x00002017, + VM_FUNCTION_CONTROL = 0x00002018, + VM_FUNCTION_CONTROL_HIGH = 0x00002019, EPT_POINTER = 0x0000201a, EPT_POINTER_HIGH = 0x0000201b, EOI_EXIT_BITMAP0 = 0x0000201c, @@ -197,6 +204,8 @@ enum vmcs_field { EOI_EXIT_BITMAP2_HIGH = 0x00002021, EOI_EXIT_BITMAP3 = 0x00002022, EOI_EXIT_BITMAP3_HIGH = 0x00002023, + EPTP_LIST_ADDRESS = 0x00002024, + EPTP_LIST_ADDRESS_HIGH = 0x00002025, VMREAD_BITMAP = 0x00002026, VMWRITE_BITMAP = 0x00002028, XSS_EXIT_BITMAP = 0x0000202C, @@ -444,6 +453,7 @@ enum vmcs_field { #define VMX_EPT_EXECUTE_ONLY_BIT (1ull) #define VMX_EPT_PAGE_WALK_4_BIT (1ull << 6) +#define VMX_EPT_PAGE_WALK_5_BIT (1ull << 7) #define VMX_EPTP_UC_BIT (1ull << 8) #define VMX_EPTP_WB_BIT (1ull << 14) #define VMX_EPT_2MB_PAGE_BIT (1ull << 16) @@ -459,12 +469,14 @@ enum vmcs_field { #define VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT (1ull << 10) /* (42 - 32) */ #define VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT (1ull << 11) /* (43 - 32) */ -#define VMX_EPT_DEFAULT_GAW 3 -#define VMX_EPT_MAX_GAW 0x4 #define VMX_EPT_MT_EPTE_SHIFT 3 -#define VMX_EPT_GAW_EPTP_SHIFT 3 -#define VMX_EPT_AD_ENABLE_BIT (1ull << 6) -#define VMX_EPT_DEFAULT_MT 0x6ull +#define VMX_EPTP_PWL_MASK 0x38ull +#define VMX_EPTP_PWL_4 0x18ull +#define VMX_EPTP_PWL_5 0x20ull +#define VMX_EPTP_AD_ENABLE_BIT (1ull << 6) +#define VMX_EPTP_MT_MASK 0x7ull +#define VMX_EPTP_MT_WB 0x6ull +#define VMX_EPTP_MT_UC 0x0ull #define VMX_EPT_READABLE_MASK 0x1ull #define VMX_EPT_WRITABLE_MASK 0x2ull #define VMX_EPT_EXECUTABLE_MASK 0x4ull diff --git a/arch/x86/include/asm/vsyscall.h b/arch/x86/include/asm/vsyscall.h index 6ba66ee79710..d9a7c659009c 100644 --- a/arch/x86/include/asm/vsyscall.h +++ b/arch/x86/include/asm/vsyscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_VSYSCALL_H #define _ASM_X86_VSYSCALL_H diff --git a/arch/x86/include/asm/word-at-a-time.h b/arch/x86/include/asm/word-at-a-time.h index 5b238981542a..06006b0351f3 100644 --- a/arch/x86/include/asm/word-at-a-time.h +++ b/arch/x86/include/asm/word-at-a-time.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_WORD_AT_A_TIME_H #define _ASM_WORD_AT_A_TIME_H diff --git a/arch/x86/include/asm/x2apic.h b/arch/x86/include/asm/x2apic.h index f90f0a587c66..78ccf28d17db 100644 --- a/arch/x86/include/asm/x2apic.h +++ b/arch/x86/include/asm/x2apic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Common bits for X2APIC cluster/physical modes. */ diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h index 7ba7e90a9ad6..8a1ebf9540dd 100644 --- a/arch/x86/include/asm/x86_init.h +++ b/arch/x86/include/asm/x86_init.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_PLATFORM_H #define _ASM_X86_PLATFORM_H diff --git a/arch/x86/include/asm/xen/events.h b/arch/x86/include/asm/xen/events.h index e6911caf5bbf..d383140e1dc8 100644 --- a/arch/x86/include/asm/xen/events.h +++ b/arch/x86/include/asm/xen/events.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_XEN_EVENTS_H #define _ASM_X86_XEN_EVENTS_H diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 11071fcd630e..7cb282e9e587 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -113,10 +113,9 @@ extern struct { char _entry[32]; } hypercall_page[]; register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ - register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; \ - register void *__sp asm(_ASM_SP); + register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; -#define __HYPERCALL_0PARAM "=r" (__res), "+r" (__sp) +#define __HYPERCALL_0PARAM "=r" (__res), ASM_CALL_CONSTRAINT #define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) #define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) #define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) @@ -557,10 +556,12 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr, mcl->args[0] = maddr; mcl->args[1] = *(unsigned long *)&desc; } else { + u32 *p = (u32 *)&desc; + mcl->args[0] = maddr; mcl->args[1] = maddr >> 32; - mcl->args[2] = desc.a; - mcl->args[3] = desc.b; + mcl->args[2] = *p++; + mcl->args[3] = *p; } trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4); diff --git a/arch/x86/include/asm/xen/interface_32.h b/arch/x86/include/asm/xen/interface_32.h index 8413688b2571..dc40578abded 100644 --- a/arch/x86/include/asm/xen/interface_32.h +++ b/arch/x86/include/asm/xen/interface_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************** * arch-x86_32.h * diff --git a/arch/x86/include/asm/xen/interface_64.h b/arch/x86/include/asm/xen/interface_64.h index 839a4811cf98..c599ec269a25 100644 --- a/arch/x86/include/asm/xen/interface_64.h +++ b/arch/x86/include/asm/xen/interface_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_XEN_INTERFACE_64_H #define _ASM_X86_XEN_INTERFACE_64_H diff --git a/arch/x86/include/asm/xen/page-coherent.h b/arch/x86/include/asm/xen/page-coherent.h index f02f025ff988..116777e7f387 100644 --- a/arch/x86/include/asm/xen/page-coherent.h +++ b/arch/x86/include/asm/xen/page-coherent.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_XEN_PAGE_COHERENT_H #define _ASM_X86_XEN_PAGE_COHERENT_H diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h index 8417ef7c3885..c6b84245e5ab 100644 --- a/arch/x86/include/asm/xen/page.h +++ b/arch/x86/include/asm/xen/page.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_XEN_PAGE_H #define _ASM_X86_XEN_PAGE_H @@ -158,9 +159,6 @@ static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn) unsigned long pfn; int ret; - if (xen_feature(XENFEAT_auto_translated_physmap)) - return mfn; - if (unlikely(mfn >= machine_to_phys_nr)) return ~0; @@ -317,8 +315,6 @@ static inline pte_t __pte_ma(pteval_t x) #define p4d_val_ma(x) ((x).p4d) #endif -void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid); - xmaddr_t arbitrary_virt_to_machine(void *address); unsigned long arbitrary_virt_to_mfn(void *vaddr); void make_lowmem_page_readonly(void *vaddr); diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h index f320ee32d5a1..3506d8c598c1 100644 --- a/arch/x86/include/asm/xen/pci.h +++ b/arch/x86/include/asm/xen/pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_XEN_PCI_H #define _ASM_X86_XEN_PCI_H diff --git a/arch/x86/include/asm/xen/swiotlb-xen.h b/arch/x86/include/asm/xen/swiotlb-xen.h index ee52fcac6f72..6b56d0d45d15 100644 --- a/arch/x86/include/asm/xen/swiotlb-xen.h +++ b/arch/x86/include/asm/xen/swiotlb-xen.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SWIOTLB_XEN_H #define _ASM_X86_SWIOTLB_XEN_H diff --git a/arch/x86/include/asm/xen/trace_types.h b/arch/x86/include/asm/xen/trace_types.h index 21e1874c0a0b..2aad0abd68e2 100644 --- a/arch/x86/include/asm/xen/trace_types.h +++ b/arch/x86/include/asm/xen/trace_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_XEN_TRACE_TYPES_H #define _ASM_XEN_TRACE_TYPES_H diff --git a/arch/x86/include/asm/xor_64.h b/arch/x86/include/asm/xor_64.h index 546f1e3b87cc..0307e4ec5044 100644 --- a/arch/x86/include/asm/xor_64.h +++ b/arch/x86/include/asm/xor_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_XOR_64_H #define _ASM_X86_XOR_64_H diff --git a/arch/x86/include/uapi/asm/a.out.h b/arch/x86/include/uapi/asm/a.out.h index 4684f97a5bbd..094c49d8ea8e 100644 --- a/arch/x86/include/uapi/asm/a.out.h +++ b/arch/x86/include/uapi/asm/a.out.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_A_OUT_H #define _ASM_X86_A_OUT_H diff --git a/arch/x86/include/uapi/asm/auxvec.h b/arch/x86/include/uapi/asm/auxvec.h index 77203ac352de..580e3c567046 100644 --- a/arch/x86/include/uapi/asm/auxvec.h +++ b/arch/x86/include/uapi/asm/auxvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_AUXVEC_H #define _ASM_X86_AUXVEC_H /* diff --git a/arch/x86/include/uapi/asm/bitsperlong.h b/arch/x86/include/uapi/asm/bitsperlong.h index 217909b4d6f5..5d72c8458838 100644 --- a/arch/x86/include/uapi/asm/bitsperlong.h +++ b/arch/x86/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_X86_BITSPERLONG_H #define __ASM_X86_BITSPERLONG_H diff --git a/arch/x86/include/uapi/asm/boot.h b/arch/x86/include/uapi/asm/boot.h index 94292c4c8122..88ffc5aee087 100644 --- a/arch/x86/include/uapi/asm/boot.h +++ b/arch/x86/include/uapi/asm/boot.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_BOOT_H #define _UAPI_ASM_X86_BOOT_H diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index ddef37b16af2..afdd5ae0fcc4 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_BOOTPARAM_H #define _ASM_X86_BOOTPARAM_H @@ -201,7 +202,7 @@ struct boot_params { * * @X86_SUBARCH_PC: Should be used if the hardware is enumerable using standard * PC mechanisms (PCI, ACPI) and doesn't need a special boot flow. - * @X86_SUBARCH_LGUEST: Used for x86 hypervisor demo, lguest + * @X86_SUBARCH_LGUEST: Used for x86 hypervisor demo, lguest, deprecated * @X86_SUBARCH_XEN: Used for Xen guest types which follow the PV boot path, * which start at asm startup_xen() entry point and later jump to the C * xen_start_kernel() entry point. Both domU and dom0 type of guests are diff --git a/arch/x86/include/uapi/asm/byteorder.h b/arch/x86/include/uapi/asm/byteorder.h index b13a7a88f3eb..484e3cfd7ef2 100644 --- a/arch/x86/include/uapi/asm/byteorder.h +++ b/arch/x86/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_BYTEORDER_H #define _ASM_X86_BYTEORDER_H diff --git a/arch/x86/include/uapi/asm/debugreg.h b/arch/x86/include/uapi/asm/debugreg.h index 3c0874dd9861..d95d080b30e3 100644 --- a/arch/x86/include/uapi/asm/debugreg.h +++ b/arch/x86/include/uapi/asm/debugreg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_DEBUGREG_H #define _UAPI_ASM_X86_DEBUGREG_H diff --git a/arch/x86/include/uapi/asm/e820.h b/arch/x86/include/uapi/asm/e820.h index 9dafe59cf6e2..2f491efe3a12 100644 --- a/arch/x86/include/uapi/asm/e820.h +++ b/arch/x86/include/uapi/asm/e820.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_E820_H #define _UAPI_ASM_X86_E820_H #define E820MAP 0x2d0 /* our map */ diff --git a/arch/x86/include/uapi/asm/hw_breakpoint.h b/arch/x86/include/uapi/asm/hw_breakpoint.h index 79a9626b5500..6789884c7701 100644 --- a/arch/x86/include/uapi/asm/hw_breakpoint.h +++ b/arch/x86/include/uapi/asm/hw_breakpoint.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* */ diff --git a/arch/x86/include/uapi/asm/hwcap2.h b/arch/x86/include/uapi/asm/hwcap2.h index 0bd2be5c7617..6ebaae90e207 100644 --- a/arch/x86/include/uapi/asm/hwcap2.h +++ b/arch/x86/include/uapi/asm/hwcap2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_HWCAP2_H #define _ASM_X86_HWCAP2_H diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h index 127ddadee1a5..1a5bfead93b4 100644 --- a/arch/x86/include/uapi/asm/hyperv.h +++ b/arch/x86/include/uapi/asm/hyperv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_HYPERV_H #define _ASM_X86_HYPERV_H @@ -149,12 +150,9 @@ */ #define HV_X64_DEPRECATING_AEOI_RECOMMENDED (1 << 9) -/* - * HV_VP_SET available - */ +/* Recommend using the newer ExProcessorMasks interface */ #define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED (1 << 11) - /* * Crash notification flag. */ @@ -242,7 +240,11 @@ (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1)) /* Declare the various hypercall operations. */ +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE 0x0002 +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST 0x0003 #define HVCALL_NOTIFY_LONG_SPIN_WAIT 0x0008 +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013 +#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014 #define HVCALL_POST_MESSAGE 0x005c #define HVCALL_SIGNAL_EVENT 0x005d @@ -259,6 +261,16 @@ #define HV_PROCESSOR_POWER_STATE_C2 2 #define HV_PROCESSOR_POWER_STATE_C3 3 +#define HV_FLUSH_ALL_PROCESSORS BIT(0) +#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES BIT(1) +#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY BIT(2) +#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3) + +enum HV_GENERIC_SET_FORMAT { + HV_GENERIC_SET_SPARCE_4K, + HV_GENERIC_SET_ALL, +}; + /* hypercall status code */ #define HV_STATUS_SUCCESS 0 #define HV_STATUS_INVALID_HYPERCALL_CODE 2 diff --git a/arch/x86/include/uapi/asm/ist.h b/arch/x86/include/uapi/asm/ist.h index bad9f5ea4070..eac5b207939d 100644 --- a/arch/x86/include/uapi/asm/ist.h +++ b/arch/x86/include/uapi/asm/ist.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ /* * Include file for the interface to IST BIOS * Copyright 2002 Andy Grover diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index c2824d02ba37..f3a960488eae 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_KVM_H #define _ASM_X86_KVM_H diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index a965e5b0d328..554aa8f24f91 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_KVM_PARA_H #define _UAPI_ASM_X86_KVM_PARA_H diff --git a/arch/x86/include/uapi/asm/kvm_perf.h b/arch/x86/include/uapi/asm/kvm_perf.h index 3bb964f88aa1..125cf5cdf6c5 100644 --- a/arch/x86/include/uapi/asm/kvm_perf.h +++ b/arch/x86/include/uapi/asm/kvm_perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_KVM_PERF_H #define _ASM_X86_KVM_PERF_H diff --git a/arch/x86/include/uapi/asm/ldt.h b/arch/x86/include/uapi/asm/ldt.h index 6e1aaf73852a..d62ac5db093b 100644 --- a/arch/x86/include/uapi/asm/ldt.h +++ b/arch/x86/include/uapi/asm/ldt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * ldt.h * diff --git a/arch/x86/include/uapi/asm/mce.h b/arch/x86/include/uapi/asm/mce.h index eb6247a7009b..91723461dc1f 100644 --- a/arch/x86/include/uapi/asm/mce.h +++ b/arch/x86/include/uapi/asm/mce.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_MCE_H #define _UAPI_ASM_X86_MCE_H diff --git a/arch/x86/include/uapi/asm/mman.h b/arch/x86/include/uapi/asm/mman.h index 39bca7fac087..d4a8d0424bfb 100644 --- a/arch/x86/include/uapi/asm/mman.h +++ b/arch/x86/include/uapi/asm/mman.h @@ -1,11 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_MMAN_H #define _ASM_X86_MMAN_H #define MAP_32BIT 0x40 /* only give out 32bit addresses */ -#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) -#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) - #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS /* * Take the 4 protection key bits out of the vma->vm_flags diff --git a/arch/x86/include/uapi/asm/msr.h b/arch/x86/include/uapi/asm/msr.h index c41f4fe25483..e7516b402a00 100644 --- a/arch/x86/include/uapi/asm/msr.h +++ b/arch/x86/include/uapi/asm/msr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_MSR_H #define _UAPI_ASM_X86_MSR_H diff --git a/arch/x86/include/uapi/asm/mtrr.h b/arch/x86/include/uapi/asm/mtrr.h index 7528dcf59691..376563f2bac1 100644 --- a/arch/x86/include/uapi/asm/mtrr.h +++ b/arch/x86/include/uapi/asm/mtrr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.0+ WITH Linux-syscall-note */ /* Generic MTRR (Memory Type Range Register) ioctls. Copyright (C) 1997-1999 Richard Gooch diff --git a/arch/x86/include/uapi/asm/perf_regs.h b/arch/x86/include/uapi/asm/perf_regs.h index 3f2207bfd17b..f3329cabce5c 100644 --- a/arch/x86/include/uapi/asm/perf_regs.h +++ b/arch/x86/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_PERF_REGS_H #define _ASM_X86_PERF_REGS_H diff --git a/arch/x86/include/uapi/asm/posix_types.h b/arch/x86/include/uapi/asm/posix_types.h index 85506b383627..c661e95f0134 100644 --- a/arch/x86/include/uapi/asm/posix_types.h +++ b/arch/x86/include/uapi/asm/posix_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __KERNEL__ # ifdef __i386__ # include diff --git a/arch/x86/include/uapi/asm/posix_types_32.h b/arch/x86/include/uapi/asm/posix_types_32.h index 8e525059e7d8..840659f4b96f 100644 --- a/arch/x86/include/uapi/asm/posix_types_32.h +++ b/arch/x86/include/uapi/asm/posix_types_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_POSIX_TYPES_32_H #define _ASM_X86_POSIX_TYPES_32_H diff --git a/arch/x86/include/uapi/asm/posix_types_64.h b/arch/x86/include/uapi/asm/posix_types_64.h index cba0c1ead162..515afb8059ce 100644 --- a/arch/x86/include/uapi/asm/posix_types_64.h +++ b/arch/x86/include/uapi/asm/posix_types_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_POSIX_TYPES_64_H #define _ASM_X86_POSIX_TYPES_64_H diff --git a/arch/x86/include/uapi/asm/posix_types_x32.h b/arch/x86/include/uapi/asm/posix_types_x32.h index 85f9bdafa93c..f60479b07fc8 100644 --- a/arch/x86/include/uapi/asm/posix_types_x32.h +++ b/arch/x86/include/uapi/asm/posix_types_x32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_POSIX_TYPES_X32_H #define _ASM_X86_POSIX_TYPES_X32_H diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h index c45765517092..5a6aac9fa41f 100644 --- a/arch/x86/include/uapi/asm/prctl.h +++ b/arch/x86/include/uapi/asm/prctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_PRCTL_H #define _ASM_X86_PRCTL_H diff --git a/arch/x86/include/uapi/asm/processor-flags.h b/arch/x86/include/uapi/asm/processor-flags.h index 185f3d10c194..6f3355399665 100644 --- a/arch/x86/include/uapi/asm/processor-flags.h +++ b/arch/x86/include/uapi/asm/processor-flags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_PROCESSOR_FLAGS_H #define _UAPI_ASM_X86_PROCESSOR_FLAGS_H /* Various flags defined: can be included from assembler. */ diff --git a/arch/x86/include/uapi/asm/ptrace-abi.h b/arch/x86/include/uapi/asm/ptrace-abi.h index 580aee3072e0..16074b9c93bb 100644 --- a/arch/x86/include/uapi/asm/ptrace-abi.h +++ b/arch/x86/include/uapi/asm/ptrace-abi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_PTRACE_ABI_H #define _ASM_X86_PTRACE_ABI_H diff --git a/arch/x86/include/uapi/asm/ptrace.h b/arch/x86/include/uapi/asm/ptrace.h index bc16115af39b..85165c0edafc 100644 --- a/arch/x86/include/uapi/asm/ptrace.h +++ b/arch/x86/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_PTRACE_H #define _UAPI_ASM_X86_PTRACE_H diff --git a/arch/x86/include/uapi/asm/sembuf.h b/arch/x86/include/uapi/asm/sembuf.h index cc2d6a3aeae7..cabd7476bd6c 100644 --- a/arch/x86/include/uapi/asm/sembuf.h +++ b/arch/x86/include/uapi/asm/sembuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_SEMBUF_H #define _ASM_X86_SEMBUF_H diff --git a/arch/x86/include/uapi/asm/sigcontext.h b/arch/x86/include/uapi/asm/sigcontext.h index 62d4111c1c54..844d60eb1882 100644 --- a/arch/x86/include/uapi/asm/sigcontext.h +++ b/arch/x86/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_SIGCONTEXT_H #define _UAPI_ASM_X86_SIGCONTEXT_H diff --git a/arch/x86/include/uapi/asm/sigcontext32.h b/arch/x86/include/uapi/asm/sigcontext32.h index a92b0f0dc09e..6b18e88de8a6 100644 --- a/arch/x86/include/uapi/asm/sigcontext32.h +++ b/arch/x86/include/uapi/asm/sigcontext32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_SIGCONTEXT32_H #define _ASM_X86_SIGCONTEXT32_H diff --git a/arch/x86/include/uapi/asm/siginfo.h b/arch/x86/include/uapi/asm/siginfo.h index 34c47b3341c0..b3d157957177 100644 --- a/arch/x86/include/uapi/asm/siginfo.h +++ b/arch/x86/include/uapi/asm/siginfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_SIGINFO_H #define _ASM_X86_SIGINFO_H diff --git a/arch/x86/include/uapi/asm/signal.h b/arch/x86/include/uapi/asm/signal.h index 8264f47cf53e..e5745d593dc7 100644 --- a/arch/x86/include/uapi/asm/signal.h +++ b/arch/x86/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_SIGNAL_H #define _UAPI_ASM_X86_SIGNAL_H diff --git a/arch/x86/include/uapi/asm/stat.h b/arch/x86/include/uapi/asm/stat.h index bc03eb5d6360..9e3982d95d0f 100644 --- a/arch/x86/include/uapi/asm/stat.h +++ b/arch/x86/include/uapi/asm/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_STAT_H #define _ASM_X86_STAT_H diff --git a/arch/x86/include/uapi/asm/statfs.h b/arch/x86/include/uapi/asm/statfs.h index 2d0adbf99a8e..13c2464cd2c4 100644 --- a/arch/x86/include/uapi/asm/statfs.h +++ b/arch/x86/include/uapi/asm/statfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_STATFS_H #define _ASM_X86_STATFS_H diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h index 3725e145aa58..a9731f8a480f 100644 --- a/arch/x86/include/uapi/asm/svm.h +++ b/arch/x86/include/uapi/asm/svm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__SVM_H #define _UAPI__SVM_H diff --git a/arch/x86/include/uapi/asm/swab.h b/arch/x86/include/uapi/asm/swab.h index 7f235c7105c1..cd3fd8ddbe9a 100644 --- a/arch/x86/include/uapi/asm/swab.h +++ b/arch/x86/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_SWAB_H #define _ASM_X86_SWAB_H diff --git a/arch/x86/include/uapi/asm/types.h b/arch/x86/include/uapi/asm/types.h index 8e8c23fef08c..df55e1ddb0c9 100644 --- a/arch/x86/include/uapi/asm/types.h +++ b/arch/x86/include/uapi/asm/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_TYPES_H #define _ASM_X86_TYPES_H diff --git a/arch/x86/include/uapi/asm/ucontext.h b/arch/x86/include/uapi/asm/ucontext.h index e3d1ec90616e..5657b7a49f03 100644 --- a/arch/x86/include/uapi/asm/ucontext.h +++ b/arch/x86/include/uapi/asm/ucontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_UCONTEXT_H #define _ASM_X86_UCONTEXT_H diff --git a/arch/x86/include/uapi/asm/unistd.h b/arch/x86/include/uapi/asm/unistd.h index a26df0d75cd0..30d7d04d72d6 100644 --- a/arch/x86/include/uapi/asm/unistd.h +++ b/arch/x86/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_UNISTD_H #define _UAPI_ASM_X86_UNISTD_H diff --git a/arch/x86/include/uapi/asm/vm86.h b/arch/x86/include/uapi/asm/vm86.h index e0b243e9d859..d2ee4e307ef8 100644 --- a/arch/x86/include/uapi/asm/vm86.h +++ b/arch/x86/include/uapi/asm/vm86.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_VM86_H #define _UAPI_ASM_X86_VM86_H diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index 690a2dcf4078..f0b0c90dd398 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * vmx.h: VMX Architecture related definitions * Copyright (c) 2004, Intel Corporation. diff --git a/arch/x86/include/uapi/asm/vsyscall.h b/arch/x86/include/uapi/asm/vsyscall.h index b97dd6e263d2..75275f547444 100644 --- a/arch/x86/include/uapi/asm/vsyscall.h +++ b/arch/x86/include/uapi/asm/vsyscall.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_X86_VSYSCALL_H #define _UAPI_ASM_X86_VSYSCALL_H diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a01892bdd61a..5f70044340ff 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the linux kernel. # @@ -42,7 +43,7 @@ CFLAGS_irq.o := -I$(src)/../include/asm/trace obj-y := process_$(BITS).o signal.o obj-$(CONFIG_COMPAT) += signal_compat.o -obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o +obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o dumpstack.o nmi.o obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o obj-y += setup.o x86_init.o i8259.o irqinit.o jump_label.o @@ -111,6 +112,7 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o +obj-$(CONFIG_EISA) += eisa.o obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o @@ -126,11 +128,9 @@ obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_TRACING) += tracepoint.o obj-$(CONFIG_SCHED_MC_PRIO) += itmt.o -ifdef CONFIG_FRAME_POINTER -obj-y += unwind_frame.o -else -obj-y += unwind_guess.o -endif +obj-$(CONFIG_ORC_UNWINDER) += unwind_orc.o +obj-$(CONFIG_FRAME_POINTER_UNWINDER) += unwind_frame.o +obj-$(CONFIG_GUESS_UNWINDER) += unwind_guess.o ### # 64 bit specific files diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile index 85a9e17e0dbc..f1bb57b0e41e 100644 --- a/arch/x86/kernel/acpi/Makefile +++ b/arch/x86/kernel/acpi/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 OBJECT_FILES_NON_STANDARD_wakeup_$(BITS).o := y obj-$(CONFIG_ACPI) += boot.o diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 7491e73d9253..079535e53e2a 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -115,24 +115,24 @@ static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = { #define ACPI_INVALID_GSI INT_MIN /* - * This is just a simple wrapper around early_ioremap(), + * This is just a simple wrapper around early_memremap(), * with sanity checks for phys == 0 and size == 0. */ -char *__init __acpi_map_table(unsigned long phys, unsigned long size) +void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) { if (!phys || !size) return NULL; - return early_ioremap(phys, size); + return early_memremap(phys, size); } -void __init __acpi_unmap_table(char *map, unsigned long size) +void __init __acpi_unmap_table(void __iomem *map, unsigned long size) { if (!map || !size) return; - early_iounmap(map, size); + early_memunmap(map, size); } #ifdef CONFIG_X86_LOCAL_APIC @@ -199,8 +199,10 @@ static int __init acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) { struct acpi_madt_local_x2apic *processor = NULL; +#ifdef CONFIG_X86_X2APIC int apic_id; u8 enabled; +#endif processor = (struct acpi_madt_local_x2apic *)header; @@ -209,9 +211,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end) acpi_table_print_madt_entry(header); +#ifdef CONFIG_X86_X2APIC apic_id = processor->local_apic_id; enabled = processor->lapic_flags & ACPI_MADT_ENABLED; -#ifdef CONFIG_X86_X2APIC + /* * We need to register disabled CPU as well to permit * counting disabled CPUs. This allows us to size @@ -1083,7 +1086,7 @@ static void __init mp_config_acpi_legacy_irqs(void) mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; #endif set_bit(MP_ISA_BUS, mp_bus_not_pci); - pr_debug("Bus #%d is ISA\n", MP_ISA_BUS); + pr_debug("Bus #%d is ISA (nIRQs: %d)\n", MP_ISA_BUS, nr_legacy_irqs()); /* * Use the default configuration for the IRQs 0-15. Unless @@ -1370,7 +1373,7 @@ static void __init acpi_reduced_hw_init(void) * If your system is blacklisted here, but you find that acpi=force * works for you, please contact linux-acpi@vger.kernel.org */ -static struct dmi_system_id __initdata acpi_dmi_table[] = { +static const struct dmi_system_id acpi_dmi_table[] __initconst = { /* * Boxes that need ACPI disabled */ @@ -1445,7 +1448,7 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { }; /* second table for DMI checks that should run after early-quirks */ -static struct dmi_system_id __initdata acpi_dmi_table_late[] = { +static const struct dmi_system_id acpi_dmi_table_late[] __initconst = { /* * HP laptops which use a DSDT reporting as HP/SB400/10000, * which includes some code which overrides all temperature diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index ed014814ea35..7188aea91549 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sleep.c - x86-specific ACPI sleep support. * diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h index 65c7b606b606..fbb60ca4255c 100644 --- a/arch/x86/kernel/acpi/sleep.h +++ b/arch/x86/kernel/acpi/sleep.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Variables and functions used by the code in sleep.c */ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 32e14d137416..3344d3382e91 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -742,7 +742,16 @@ static void *bp_int3_handler, *bp_int3_addr; int poke_int3_handler(struct pt_regs *regs) { - /* bp_patching_in_progress */ + /* + * Having observed our INT3 instruction, we now must observe + * bp_patching_in_progress. + * + * in_progress = TRUE INT3 + * WMB RMB + * write INT3 if (in_progress) + * + * Idem for bp_int3_handler. + */ smp_rmb(); if (likely(!bp_patching_in_progress)) @@ -788,9 +797,8 @@ void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler) bp_int3_addr = (u8 *)addr + sizeof(int3); bp_patching_in_progress = true; /* - * Corresponding read barrier in int3 notifier for - * making sure the in_progress flags is correctly ordered wrt. - * patching + * Corresponding read barrier in int3 notifier for making sure the + * in_progress and handler are correctly ordered wrt. patching. */ smp_wmb(); @@ -815,9 +823,11 @@ void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler) text_poke(addr, opcode, sizeof(int3)); on_each_cpu(do_sync_core, NULL, 1); - + /* + * sync_core() implies an smp_mb() and orders this store against + * the writing of the new instruction. + */ bp_patching_in_progress = false; - smp_wmb(); return addr; } diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 458da8509b75..6db28f17ff28 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -27,6 +27,8 @@ static const struct pci_device_id amd_root_ids[] = { {} }; +#define PCI_DEVICE_ID_AMD_CNB17H_F4 0x1704 + const struct pci_device_id amd_nb_misc_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) }, @@ -37,6 +39,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, {} }; EXPORT_SYMBOL_GPL(amd_nb_misc_ids); @@ -48,6 +51,7 @@ static const struct pci_device_id amd_nb_link_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, {} }; @@ -402,11 +406,48 @@ void amd_flush_garts(void) } EXPORT_SYMBOL_GPL(amd_flush_garts); +static void __fix_erratum_688(void *info) +{ +#define MSR_AMD64_IC_CFG 0xC0011021 + + msr_set_bit(MSR_AMD64_IC_CFG, 3); + msr_set_bit(MSR_AMD64_IC_CFG, 14); +} + +/* Apply erratum 688 fix so machines without a BIOS fix work. */ +static __init void fix_erratum_688(void) +{ + struct pci_dev *F4; + u32 val; + + if (boot_cpu_data.x86 != 0x14) + return; + + if (!amd_northbridges.num) + return; + + F4 = node_to_amd_nb(0)->link; + if (!F4) + return; + + if (pci_read_config_dword(F4, 0x164, &val)) + return; + + if (val & BIT(2)) + return; + + on_each_cpu(__fix_erratum_688, NULL, 0); + + pr_info("x86/cpu/AMD: CPU erratum 688 worked around\n"); +} + static __init int init_amd_nbs(void) { amd_cache_northbridges(); amd_cache_gart(); + fix_erratum_688(); + return 0; } diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index ef2859f9fcce..f5d92bc3b884 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Firmware replacement code. * diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile index 8e63ebdcbd0b..2fb7309c6900 100644 --- a/arch/x86/kernel/apic/Makefile +++ b/arch/x86/kernel/apic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for local APIC drivers and for the IO-APIC code # diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 98b3dd8cf2bf..ff891772c9f8 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -177,8 +177,6 @@ static int disable_apic_timer __initdata; int local_apic_timer_c2_ok; EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); -int first_system_vector = FIRST_SYSTEM_VECTOR; - /* * Debug level, exported for io_apic.c */ @@ -575,11 +573,21 @@ static u32 bdx_deadline_rev(void) return ~0U; } +static u32 skx_deadline_rev(void) +{ + switch (boot_cpu_data.x86_mask) { + case 0x03: return 0x01000136; + case 0x04: return 0x02000014; + } + + return ~0U; +} + static const struct x86_cpu_id deadline_match[] = { DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_HASWELL_X, hsx_deadline_rev), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_X, 0x0b000020), DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_XEON_D, bdx_deadline_rev), - DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_SKYLAKE_X, 0x02000014), + DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_SKYLAKE_X, skx_deadline_rev), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_CORE, 0x22), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_HASWELL_ULT, 0x20), @@ -599,9 +607,14 @@ static const struct x86_cpu_id deadline_match[] = { static void apic_check_deadline_errata(void) { - const struct x86_cpu_id *m = x86_match_cpu(deadline_match); + const struct x86_cpu_id *m; u32 rev; + if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER) || + boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return; + + m = x86_match_cpu(deadline_match); if (!m) return; @@ -990,8 +1003,7 @@ void setup_secondary_APIC_clock(void) */ static void local_apic_timer_interrupt(void) { - int cpu = smp_processor_id(); - struct clock_event_device *evt = &per_cpu(lapic_events, cpu); + struct clock_event_device *evt = this_cpu_ptr(&lapic_events); /* * Normally we should not be here till LAPIC has been initialized but @@ -1005,7 +1017,8 @@ static void local_apic_timer_interrupt(void) * spurious. */ if (!evt->event_handler) { - pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", cpu); + pr_warning("Spurious LAPIC timer interrupt on cpu %d\n", + smp_processor_id()); /* Switch it off */ lapic_timer_shutdown(evt); return; @@ -1031,25 +1044,6 @@ __visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - /* - * NOTE! We'd better ACK the irq immediately, - * because timer handling can be slow. - * - * update_process_times() expects us to have done irq_enter(). - * Besides, if we don't timer interrupts ignore the global - * interrupt lock, which is the WrongThing (tm) to do. - */ - entering_ack_irq(); - local_apic_timer_interrupt(); - exiting_irq(); - - set_irq_regs(old_regs); -} - -__visible void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - /* * NOTE! We'd better ACK the irq immediately, * because timer handling can be slow. @@ -1920,10 +1914,14 @@ void __init register_lapic_address(unsigned long address) /* * This interrupt should _never_ happen with our APIC/SMP architecture */ -static void __smp_spurious_interrupt(u8 vector) +__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs) { + u8 vector = ~regs->orig_ax; u32 v; + entering_irq(); + trace_spurious_apic_entry(vector); + /* * Check if this really is a spurious interrupt and ACK it * if it is a vectored one. Just in case... @@ -1938,22 +1936,7 @@ static void __smp_spurious_interrupt(u8 vector) /* see sw-dev-man vol 3, chapter 7.4.13.5 */ pr_info("spurious APIC interrupt through vector %02x on CPU#%d, " "should never happen.\n", vector, smp_processor_id()); -} -__visible void __irq_entry smp_spurious_interrupt(struct pt_regs *regs) -{ - entering_irq(); - __smp_spurious_interrupt(~regs->orig_ax); - exiting_irq(); -} - -__visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs) -{ - u8 vector = ~regs->orig_ax; - - entering_irq(); - trace_spurious_apic_entry(vector); - __smp_spurious_interrupt(vector); trace_spurious_apic_exit(vector); exiting_irq(); } @@ -1961,10 +1944,8 @@ __visible void __irq_entry smp_trace_spurious_interrupt(struct pt_regs *regs) /* * This interrupt should never happen with our APIC/SMP architecture */ -static void __smp_error_interrupt(struct pt_regs *regs) +__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs) { - u32 v; - u32 i = 0; static const char * const error_interrupt_reason[] = { "Send CS error", /* APIC Error Bit 0 */ "Receive CS error", /* APIC Error Bit 1 */ @@ -1975,6 +1956,10 @@ static void __smp_error_interrupt(struct pt_regs *regs) "Received illegal vector", /* APIC Error Bit 6 */ "Illegal register address", /* APIC Error Bit 7 */ }; + u32 v, i = 0; + + entering_irq(); + trace_error_apic_entry(ERROR_APIC_VECTOR); /* First tickle the hardware, only then report what went on. -- REW */ if (lapic_get_maxlvt() > 3) /* Due to the Pentium erratum 3AP. */ @@ -1996,20 +1981,6 @@ static void __smp_error_interrupt(struct pt_regs *regs) apic_printk(APIC_DEBUG, KERN_CONT "\n"); -} - -__visible void __irq_entry smp_error_interrupt(struct pt_regs *regs) -{ - entering_irq(); - __smp_error_interrupt(regs); - exiting_irq(); -} - -__visible void __irq_entry smp_trace_error_interrupt(struct pt_regs *regs) -{ - entering_irq(); - trace_error_apic_entry(ERROR_APIC_VECTOR); - __smp_error_interrupt(regs); trace_error_apic_exit(ERROR_APIC_VECTOR); exiting_irq(); } @@ -2137,7 +2108,7 @@ static int allocate_logical_cpuid(int apicid) /* Allocate a new cpuid. */ if (nr_logical_cpuids >= nr_cpu_ids) { - WARN_ONCE(1, "APIC: NR_CPUS/possible_cpus limit of %i reached. " + WARN_ONCE(1, "APIC: NR_CPUS/possible_cpus limit of %u reached. " "Processor %d/0x%x and the rest are ignored.\n", nr_cpu_ids, nr_logical_cpuids, apicid); return -EINVAL; @@ -2170,7 +2141,7 @@ int generic_processor_info(int apicid, int version) * Since fixing handling of boot_cpu_physical_apicid requires * another discussion and tests on each platform, we leave it * for now and here we use read_apic_id() directly in this - * function, __generic_processor_info(). + * function, generic_processor_info(). */ if (disabled_cpu_apicid != BAD_APICID && disabled_cpu_apicid != read_apic_id() && diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c index 6599f437b4ab..c8d211277315 100644 --- a/arch/x86/kernel/apic/apic_noop.c +++ b/arch/x86/kernel/apic/apic_noop.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NOOP APIC driver. * diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index 456e45e8bf84..e12fbcfc9571 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c +++ b/arch/x86/kernel/apic/bigsmp_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs. * diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index d6f387780849..d1fc62a67320 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * HW NMI watchdog support * diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 237e9c2341c7..3b89b27945ff 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel IO-APIC support for multi-Pentium hosts. * @@ -1243,7 +1244,7 @@ static void io_apic_print_entries(unsigned int apic, unsigned int nr_entries) entry.vector, entry.irr, entry.delivery_status); if (ir_entry->format) printk(KERN_DEBUG "%s, remapped, I(%04X), Z(%X)\n", - buf, (ir_entry->index << 15) | ir_entry->index, + buf, (ir_entry->index2 << 15) | ir_entry->index, ir_entry->zero); else printk(KERN_DEBUG "%s, %s, D(%02X), M(%1d)\n", diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c index 3a205d4a12d0..82f9244fe61f 100644 --- a/arch/x86/kernel/apic/ipi.c +++ b/arch/x86/kernel/apic/ipi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index b3af457ed667..88c214e75a6b 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -166,7 +166,7 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, offset = current_offset; next: vector += 16; - if (vector >= first_system_vector) { + if (vector >= FIRST_SYSTEM_VECTOR) { offset = (offset + 1) % 16; vector = FIRST_EXTERNAL_VECTOR + offset; } diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 481237cb1544..e216cf3d64d2 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c index 3baf0c3dc875..b94d35320f85 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 446b0d3d4932..e4b0d92b3ae0 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -2043,7 +2043,7 @@ static int __init swab_apm_power_in_minutes(const struct dmi_system_id *d) return 0; } -static struct dmi_system_id __initdata apm_dmi_table[] = { +static const struct dmi_system_id apm_dmi_table[] __initconst = { { print_if_true, KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c index de827d6ac8c2..8ea78275480d 100644 --- a/arch/x86/kernel/asm-offsets.c +++ b/arch/x86/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generate definitions needed by assembly language modules. * This code generates raw asm output which is post-processed to extract diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index 880aa093268d..dedf428b20b6 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -1,12 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef __LINUX_KBUILD_H # error "Please do not build this file directly, build asm-offsets.c instead" #endif #include -#include -#include "../../../drivers/lguest/lg.h" - #define __SYSCALL_I386(nr, sym, qual) [nr] = 1, static char syscalls[] = { #include @@ -62,23 +60,6 @@ void foo(void) OFFSET(stack_canary_offset, stack_canary, canary); #endif -#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE) - BLANK(); - OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled); - OFFSET(LGUEST_DATA_irq_pending, lguest_data, irq_pending); - - BLANK(); - OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc); - OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc); - OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3); - OFFSET(LGUEST_PAGES_host_sp, lguest_pages, state.host_sp); - OFFSET(LGUEST_PAGES_guest_gdt_desc, lguest_pages,state.guest_gdt_desc); - OFFSET(LGUEST_PAGES_guest_idt_desc, lguest_pages,state.guest_idt_desc); - OFFSET(LGUEST_PAGES_guest_gdt, lguest_pages, state.guest_gdt); - OFFSET(LGUEST_PAGES_regs_trapnum, lguest_pages, regs.trapnum); - OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode); - OFFSET(LGUEST_PAGES_regs, lguest_pages, regs); -#endif BLANK(); DEFINE(__NR_syscall_max, sizeof(syscalls) - 1); DEFINE(NR_syscalls, sizeof(syscalls)); diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index 99332f550c48..630212fa9b9d 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef __LINUX_KBUILD_H # error "Please do not build this file directly, build asm-offsets.c instead" #endif @@ -20,7 +21,6 @@ static char syscalls_ia32[] = { int main(void) { #ifdef CONFIG_PARAVIRT - OFFSET(PV_IRQ_adjust_exception_frame, pv_irq_ops, adjust_exception_frame); OFFSET(PV_CPU_usergs_sysret64, pv_cpu_ops, usergs_sysret64); OFFSET(PV_CPU_swapgs, pv_cpu_ops, swapgs); BLANK(); diff --git a/arch/x86/kernel/audit_64.c b/arch/x86/kernel/audit_64.c index f3672508b249..e1efe44ebefc 100644 --- a/arch/x86/kernel/audit_64.c +++ b/arch/x86/kernel/audit_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/bootflag.c b/arch/x86/kernel/bootflag.c index 52c8e3c7789d..3fed7ae58b60 100644 --- a/arch/x86/kernel/bootflag.c +++ b/arch/x86/kernel/bootflag.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implement 'Simple Boot Flag Specification 2.0' */ diff --git a/arch/x86/kernel/check.c b/arch/x86/kernel/check.c index 145863d4d343..33399426793e 100644 --- a/arch/x86/kernel/check.c +++ b/arch/x86/kernel/check.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index cdf82492b770..c60922a66385 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for x86-compatible CPU details, features and quirks # @@ -33,7 +34,7 @@ obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o -obj-$(CONFIG_INTEL_RDT_A) += intel_rdt.o intel_rdt_rdtgroup.o intel_rdt_schemata.o +obj-$(CONFIG_INTEL_RDT) += intel_rdt.o intel_rdt_rdtgroup.o intel_rdt_monitor.o intel_rdt_ctrlmondata.o obj-$(CONFIG_X86_MCE) += mcheck/ obj-$(CONFIG_MTRR) += mtrr/ diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 3b9e220621f8..d58184b7cd44 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -297,13 +297,29 @@ static int nearby_node(int apicid) } #endif +#ifdef CONFIG_SMP +/* + * Fix up cpu_core_id for pre-F17h systems to be in the + * [0 .. cores_per_node - 1] range. Not really needed but + * kept so as not to break existing setups. + */ +static void legacy_fixup_core_id(struct cpuinfo_x86 *c) +{ + u32 cus_per_node; + + if (c->x86 >= 0x17) + return; + + cus_per_node = c->x86_max_cores / nodes_per_socket; + c->cpu_core_id %= cus_per_node; +} + /* * Fixup core topology information for * (1) AMD multi-node processors * Assumption: Number of cores in each internal node is the same. * (2) AMD processors supporting compute units */ -#ifdef CONFIG_SMP static void amd_get_topology(struct cpuinfo_x86 *c) { u8 node_id; @@ -354,15 +370,9 @@ static void amd_get_topology(struct cpuinfo_x86 *c) } else return; - /* fixup multi-node processor information */ if (nodes_per_socket > 1) { - u32 cus_per_node; - set_cpu_cap(c, X86_FEATURE_AMD_DCM); - cus_per_node = c->x86_max_cores / nodes_per_socket; - - /* core id has to be in the [0 .. cores_per_node - 1] range */ - c->cpu_core_id %= cus_per_node; + legacy_fixup_core_id(c); } } #endif @@ -548,8 +558,12 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) static void early_init_amd(struct cpuinfo_x86 *c) { + u32 dummy; + early_init_amd_mc(c); + rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); + /* * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate * with P/T states and does not stop in deep C-states @@ -612,6 +626,27 @@ static void early_init_amd(struct cpuinfo_x86 *c) */ if (cpu_has_amd_erratum(c, amd_erratum_400)) set_cpu_bug(c, X86_BUG_AMD_E400); + + /* + * BIOS support is required for SME. If BIOS has enabled SME then + * adjust x86_phys_bits by the SME physical address space reduction + * value. If BIOS has not enabled SME then don't advertise the + * feature (set in scattered.c). Also, since the SME support requires + * long mode, don't advertise the feature under CONFIG_X86_32. + */ + if (cpu_has(c, X86_FEATURE_SME)) { + u64 msr; + + /* Check if SME is enabled */ + rdmsrl(MSR_K8_SYSCFG, msr); + if (msr & MSR_K8_SYSCFG_MEM_ENCRYPT) { + c->x86_phys_bits -= (cpuid_ebx(0x8000001f) >> 6) & 0x3f; + if (IS_ENABLED(CONFIG_X86_32)) + clear_cpu_cap(c, X86_FEATURE_SME); + } else { + clear_cpu_cap(c, X86_FEATURE_SME); + } + } } static void init_amd_k8(struct cpuinfo_x86 *c) @@ -728,10 +763,18 @@ static void init_amd_bd(struct cpuinfo_x86 *c) } } +static void init_amd_zn(struct cpuinfo_x86 *c) +{ + /* + * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects + * all up to and including B1. + */ + if (c->x86_model <= 1 && c->x86_mask <= 1) + set_cpu_cap(c, X86_FEATURE_CPB); +} + static void init_amd(struct cpuinfo_x86 *c) { - u32 dummy; - early_init_amd(c); /* @@ -758,6 +801,7 @@ static void init_amd(struct cpuinfo_x86 *c) case 0x10: init_amd_gh(c); break; case 0x12: init_amd_ln(c); break; case 0x15: init_amd_bd(c); break; + case 0x17: init_amd_zn(c); break; } /* Enable workaround for FXSAVE leak */ @@ -793,8 +837,6 @@ static void init_amd(struct cpuinfo_x86 *c) if (c->x86 > 0x11) set_cpu_cap(c, X86_FEATURE_ARAT); - rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy); - /* 3DNow or LM implies PREFETCHW */ if (!cpu_has(c, X86_FEATURE_3DNOWPREFETCH)) if (cpu_has(c, X86_FEATURE_3DNOW) || cpu_has(c, X86_FEATURE_LM)) diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 0af86d9242da..ba0b2424c9b0 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1994 Linus Torvalds * diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index 44207b71fee1..68bc6d9b3132 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index c8b39870f33e..c9176bae7fd8 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -168,6 +168,24 @@ static int __init x86_mpx_setup(char *s) } __setup("nompx", x86_mpx_setup); +#ifdef CONFIG_X86_64 +static int __init x86_nopcid_setup(char *s) +{ + /* nopcid doesn't accept parameters */ + if (s) + return -EINVAL; + + /* do not emit a message if the feature is not present */ + if (!boot_cpu_has(X86_FEATURE_PCID)) + return 0; + + setup_clear_cpu_cap(X86_FEATURE_PCID); + pr_info("nopcid: PCID feature disabled\n"); + return 0; +} +early_param("nopcid", x86_nopcid_setup); +#endif + static int __init x86_noinvpcid_setup(char *s) { /* noinvpcid doesn't accept parameters */ @@ -886,6 +904,14 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) setup_force_cpu_cap(X86_FEATURE_ALWAYS); fpu__init_system(c); + +#ifdef CONFIG_X86_32 + /* + * Regardless of whether PCID is enumerated, the SDM says + * that it can't be enabled in 32-bit mode. + */ + setup_clear_cpu_cap(X86_FEATURE_PCID); +#endif } void __init early_cpu_init(void) @@ -1289,15 +1315,6 @@ static __init int setup_disablecpuid(char *arg) __setup("clearcpuid=", setup_disablecpuid); #ifdef CONFIG_X86_64 -struct desc_ptr idt_descr __ro_after_init = { - .size = NR_VECTORS * 16 - 1, - .address = (unsigned long) idt_table, -}; -const struct desc_ptr debug_idt_descr = { - .size = NR_VECTORS * 16 - 1, - .address = (unsigned long) debug_idt_table, -}; - DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union) __aligned(PAGE_SIZE) __visible; @@ -1552,6 +1569,7 @@ void cpu_init(void) mmgrab(&init_mm); me->active_mm = &init_mm; BUG_ON(me->mm); + initialize_tlbstate_and_flush(); enter_lazy_tlb(&init_mm, me); load_sp0(t, ¤t->thread); @@ -1606,6 +1624,7 @@ void cpu_init(void) mmgrab(&init_mm); curr->active_mm = &init_mm; BUG_ON(curr->mm); + initialize_tlbstate_and_flush(); enter_lazy_tlb(&init_mm, curr); load_sp0(t, thread); diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 2584265d4745..f52a370b6c00 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_X86_CPU_H #define ARCH_X86_CPU_H diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index 6f077445647a..6b4bb335641f 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index dfa90a3a5145..b720dacac051 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index c55fb2cb2acc..54d04d574148 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Routines to identify caches on Intel CPU. * @@ -811,10 +812,26 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index, struct cacheinfo *this_leaf; int i, sibling; - if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + /* + * For L3, always use the pre-calculated cpu_llc_shared_mask + * to derive shared_cpu_map. + */ + if (index == 3) { + for_each_cpu(i, cpu_llc_shared_mask(cpu)) { + this_cpu_ci = get_cpu_cacheinfo(i); + if (!this_cpu_ci->info_list) + continue; + this_leaf = this_cpu_ci->info_list + index; + for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { + if (!cpu_online(sibling)) + continue; + cpumask_set_cpu(sibling, + &this_leaf->shared_cpu_map); + } + } + } else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { unsigned int apicid, nshared, first, last; - this_leaf = this_cpu_ci->info_list + index; nshared = base->eax.split.num_threads_sharing + 1; apicid = cpu_data(cpu).apicid; first = apicid - (apicid % nshared); @@ -839,19 +856,6 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index, &this_leaf->shared_cpu_map); } } - } else if (index == 3) { - for_each_cpu(i, cpu_llc_shared_mask(cpu)) { - this_cpu_ci = get_cpu_cacheinfo(i); - if (!this_cpu_ci->info_list) - continue; - this_leaf = this_cpu_ci->info_list + index; - for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { - if (!cpu_online(sibling)) - continue; - cpumask_set_cpu(sibling, - &this_leaf->shared_cpu_map); - } - } } else return 0; diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 5b366462f579..cd5fc61ba450 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -30,7 +30,8 @@ #include #include -#include +#include +#include "intel_rdt.h" #define MAX_MBA_BW 100u #define MBA_IS_LINEAR 0x4 @@ -38,7 +39,13 @@ /* Mutex to protect rdtgroup access. */ DEFINE_MUTEX(rdtgroup_mutex); -DEFINE_PER_CPU_READ_MOSTLY(int, cpu_closid); +/* + * The cached intel_pqr_state is strictly per CPU and can never be + * updated from a remote CPU. Functions which modify the state + * are called with interrupts disabled and no preemption, which + * is sufficient for the protection. + */ +DEFINE_PER_CPU(struct intel_pqr_state, pqr_state); /* * Used to store the max resource name width and max resource data width @@ -46,6 +53,12 @@ DEFINE_PER_CPU_READ_MOSTLY(int, cpu_closid); */ int max_name_width, max_data_width; +/* + * Global boolean for rdt_alloc which is true if any + * resource allocation is enabled. + */ +bool rdt_alloc_capable; + static void mba_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r); static void @@ -54,7 +67,9 @@ cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r); #define domain_init(id) LIST_HEAD_INIT(rdt_resources_all[id].domains) struct rdt_resource rdt_resources_all[] = { + [RDT_RESOURCE_L3] = { + .rid = RDT_RESOURCE_L3, .name = "L3", .domains = domain_init(RDT_RESOURCE_L3), .msr_base = IA32_L3_CBM_BASE, @@ -67,8 +82,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_L3DATA] = { + .rid = RDT_RESOURCE_L3DATA, .name = "L3DATA", .domains = domain_init(RDT_RESOURCE_L3DATA), .msr_base = IA32_L3_CBM_BASE, @@ -81,8 +99,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_L3CODE] = { + .rid = RDT_RESOURCE_L3CODE, .name = "L3CODE", .domains = domain_init(RDT_RESOURCE_L3CODE), .msr_base = IA32_L3_CBM_BASE, @@ -95,8 +116,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_L2] = { + .rid = RDT_RESOURCE_L2, .name = "L2", .domains = domain_init(RDT_RESOURCE_L2), .msr_base = IA32_L2_CBM_BASE, @@ -109,8 +133,11 @@ struct rdt_resource rdt_resources_all[] = { }, .parse_ctrlval = parse_cbm, .format_str = "%d=%0*x", + .fflags = RFTYPE_RES_CACHE, }, + [RDT_RESOURCE_MBA] = { + .rid = RDT_RESOURCE_MBA, .name = "MB", .domains = domain_init(RDT_RESOURCE_MBA), .msr_base = IA32_MBA_THRTL_BASE, @@ -118,6 +145,7 @@ struct rdt_resource rdt_resources_all[] = { .cache_level = 3, .parse_ctrlval = parse_bw, .format_str = "%d=%*d", + .fflags = RFTYPE_RES_MB, }, }; @@ -144,33 +172,28 @@ static unsigned int cbm_idx(struct rdt_resource *r, unsigned int closid) * is always 20 on hsw server parts. The minimum cache bitmask length * allowed for HSW server is always 2 bits. Hardcode all of them. */ -static inline bool cache_alloc_hsw_probe(void) +static inline void cache_alloc_hsw_probe(void) { - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && - boot_cpu_data.x86 == 6 && - boot_cpu_data.x86_model == INTEL_FAM6_HASWELL_X) { - struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; - u32 l, h, max_cbm = BIT_MASK(20) - 1; + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; + u32 l, h, max_cbm = BIT_MASK(20) - 1; - if (wrmsr_safe(IA32_L3_CBM_BASE, max_cbm, 0)) - return false; - rdmsr(IA32_L3_CBM_BASE, l, h); + if (wrmsr_safe(IA32_L3_CBM_BASE, max_cbm, 0)) + return; + rdmsr(IA32_L3_CBM_BASE, l, h); - /* If all the bits were set in MSR, return success */ - if (l != max_cbm) - return false; + /* If all the bits were set in MSR, return success */ + if (l != max_cbm) + return; - r->num_closid = 4; - r->default_ctrl = max_cbm; - r->cache.cbm_len = 20; - r->cache.min_cbm_bits = 2; - r->capable = true; - r->enabled = true; + r->num_closid = 4; + r->default_ctrl = max_cbm; + r->cache.cbm_len = 20; + r->cache.shareable_bits = 0xc0000; + r->cache.min_cbm_bits = 2; + r->alloc_capable = true; + r->alloc_enabled = true; - return true; - } - - return false; + rdt_alloc_capable = true; } /* @@ -213,15 +236,14 @@ static bool rdt_get_mem_config(struct rdt_resource *r) return false; } r->data_width = 3; - rdt_get_mba_infofile(r); - r->capable = true; - r->enabled = true; + r->alloc_capable = true; + r->alloc_enabled = true; return true; } -static void rdt_get_cache_config(int idx, struct rdt_resource *r) +static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r) { union cpuid_0x10_1_eax eax; union cpuid_0x10_x_edx edx; @@ -231,10 +253,10 @@ static void rdt_get_cache_config(int idx, struct rdt_resource *r) r->num_closid = edx.split.cos_max + 1; r->cache.cbm_len = eax.split.cbm_len + 1; r->default_ctrl = BIT_MASK(eax.split.cbm_len + 1) - 1; + r->cache.shareable_bits = ebx & r->default_ctrl; r->data_width = (r->cache.cbm_len + 3) / 4; - rdt_get_cache_infofile(r); - r->capable = true; - r->enabled = true; + r->alloc_capable = true; + r->alloc_enabled = true; } static void rdt_get_cdp_l3_config(int type) @@ -246,12 +268,12 @@ static void rdt_get_cdp_l3_config(int type) r->cache.cbm_len = r_l3->cache.cbm_len; r->default_ctrl = r_l3->default_ctrl; r->data_width = (r->cache.cbm_len + 3) / 4; - r->capable = true; + r->alloc_capable = true; /* * By default, CDP is disabled. CDP can be enabled by mount parameter * "cdp" during resctrl file system mount time. */ - r->enabled = false; + r->alloc_enabled = false; } static int get_cache_id(int cpu, int level) @@ -300,6 +322,19 @@ cat_wrmsr(struct rdt_domain *d, struct msr_param *m, struct rdt_resource *r) wrmsrl(r->msr_base + cbm_idx(r, i), d->ctrl_val[i]); } +struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r) +{ + struct rdt_domain *d; + + list_for_each_entry(d, &r->domains, list) { + /* Find the domain that contains this CPU */ + if (cpumask_test_cpu(cpu, &d->cpu_mask)) + return d; + } + + return NULL; +} + void rdt_ctrl_update(void *arg) { struct msr_param *m = arg; @@ -307,12 +342,10 @@ void rdt_ctrl_update(void *arg) int cpu = smp_processor_id(); struct rdt_domain *d; - list_for_each_entry(d, &r->domains, list) { - /* Find the domain that contains this CPU */ - if (cpumask_test_cpu(cpu, &d->cpu_mask)) { - r->msr_update(d, m, r); - return; - } + d = get_domain_from_cpu(cpu, r); + if (d) { + r->msr_update(d, m, r); + return; } pr_warn_once("cpu %d not found in any domain for resource %s\n", cpu, r->name); @@ -326,8 +359,8 @@ void rdt_ctrl_update(void *arg) * caller, return the first domain whose id is bigger than the input id. * The domain list is sorted by id in ascending order. */ -static struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, - struct list_head **pos) +struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, + struct list_head **pos) { struct rdt_domain *d; struct list_head *l; @@ -377,6 +410,44 @@ static int domain_setup_ctrlval(struct rdt_resource *r, struct rdt_domain *d) return 0; } +static int domain_setup_mon_state(struct rdt_resource *r, struct rdt_domain *d) +{ + size_t tsize; + + if (is_llc_occupancy_enabled()) { + d->rmid_busy_llc = kcalloc(BITS_TO_LONGS(r->num_rmid), + sizeof(unsigned long), + GFP_KERNEL); + if (!d->rmid_busy_llc) + return -ENOMEM; + INIT_DELAYED_WORK(&d->cqm_limbo, cqm_handle_limbo); + } + if (is_mbm_total_enabled()) { + tsize = sizeof(*d->mbm_total); + d->mbm_total = kcalloc(r->num_rmid, tsize, GFP_KERNEL); + if (!d->mbm_total) { + kfree(d->rmid_busy_llc); + return -ENOMEM; + } + } + if (is_mbm_local_enabled()) { + tsize = sizeof(*d->mbm_local); + d->mbm_local = kcalloc(r->num_rmid, tsize, GFP_KERNEL); + if (!d->mbm_local) { + kfree(d->rmid_busy_llc); + kfree(d->mbm_total); + return -ENOMEM; + } + } + + if (is_mbm_enabled()) { + INIT_DELAYED_WORK(&d->mbm_over, mbm_handle_overflow); + mbm_setup_overflow_handler(d, MBM_OVERFLOW_INTERVAL); + } + + return 0; +} + /* * domain_add_cpu - Add a cpu to a resource's domain list. * @@ -412,14 +483,26 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r) return; d->id = id; + cpumask_set_cpu(cpu, &d->cpu_mask); - if (domain_setup_ctrlval(r, d)) { + if (r->alloc_capable && domain_setup_ctrlval(r, d)) { + kfree(d); + return; + } + + if (r->mon_capable && domain_setup_mon_state(r, d)) { kfree(d); return; } - cpumask_set_cpu(cpu, &d->cpu_mask); list_add_tail(&d->list, add_pos); + + /* + * If resctrl is mounted, add + * per domain monitor data directories. + */ + if (static_branch_unlikely(&rdt_mon_enable_key)) + mkdir_mondata_subdir_allrdtgrp(r, d); } static void domain_remove_cpu(int cpu, struct rdt_resource *r) @@ -435,19 +518,58 @@ static void domain_remove_cpu(int cpu, struct rdt_resource *r) cpumask_clear_cpu(cpu, &d->cpu_mask); if (cpumask_empty(&d->cpu_mask)) { + /* + * If resctrl is mounted, remove all the + * per domain monitor data directories. + */ + if (static_branch_unlikely(&rdt_mon_enable_key)) + rmdir_mondata_subdir_allrdtgrp(r, d->id); kfree(d->ctrl_val); + kfree(d->rmid_busy_llc); + kfree(d->mbm_total); + kfree(d->mbm_local); list_del(&d->list); + if (is_mbm_enabled()) + cancel_delayed_work(&d->mbm_over); + if (is_llc_occupancy_enabled() && has_busy_rmid(r, d)) { + /* + * When a package is going down, forcefully + * decrement rmid->ebusy. There is no way to know + * that the L3 was flushed and hence may lead to + * incorrect counts in rare scenarios, but leaving + * the RMID as busy creates RMID leaks if the + * package never comes back. + */ + __check_limbo(d, true); + cancel_delayed_work(&d->cqm_limbo); + } + kfree(d); + return; + } + + if (r == &rdt_resources_all[RDT_RESOURCE_L3]) { + if (is_mbm_enabled() && cpu == d->mbm_work_cpu) { + cancel_delayed_work(&d->mbm_over); + mbm_setup_overflow_handler(d, 0); + } + if (is_llc_occupancy_enabled() && cpu == d->cqm_work_cpu && + has_busy_rmid(r, d)) { + cancel_delayed_work(&d->cqm_limbo); + cqm_setup_limbo_handler(d, 0); + } } } -static void clear_closid(int cpu) +static void clear_closid_rmid(int cpu) { struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); - per_cpu(cpu_closid, cpu) = 0; - state->closid = 0; - wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, 0); + state->default_closid = 0; + state->default_rmid = 0; + state->cur_closid = 0; + state->cur_rmid = 0; + wrmsr(IA32_PQR_ASSOC, 0, 0); } static int intel_rdt_online_cpu(unsigned int cpu) @@ -459,12 +581,23 @@ static int intel_rdt_online_cpu(unsigned int cpu) domain_add_cpu(cpu, r); /* The cpu is set in default rdtgroup after online. */ cpumask_set_cpu(cpu, &rdtgroup_default.cpu_mask); - clear_closid(cpu); + clear_closid_rmid(cpu); mutex_unlock(&rdtgroup_mutex); return 0; } +static void clear_childcpus(struct rdtgroup *r, unsigned int cpu) +{ + struct rdtgroup *cr; + + list_for_each_entry(cr, &r->mon.crdtgrp_list, mon.crdtgrp_list) { + if (cpumask_test_and_clear_cpu(cpu, &cr->cpu_mask)) { + break; + } + } +} + static int intel_rdt_offline_cpu(unsigned int cpu) { struct rdtgroup *rdtgrp; @@ -474,10 +607,12 @@ static int intel_rdt_offline_cpu(unsigned int cpu) for_each_capable_rdt_resource(r) domain_remove_cpu(cpu, r); list_for_each_entry(rdtgrp, &rdt_all_groups, rdtgroup_list) { - if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) + if (cpumask_test_and_clear_cpu(cpu, &rdtgrp->cpu_mask)) { + clear_childcpus(rdtgrp, cpu); break; + } } - clear_closid(cpu); + clear_closid_rmid(cpu); mutex_unlock(&rdtgroup_mutex); return 0; @@ -492,7 +627,7 @@ static __init void rdt_init_padding(void) struct rdt_resource *r; int cl; - for_each_capable_rdt_resource(r) { + for_each_alloc_capable_rdt_resource(r) { cl = strlen(r->name); if (cl > max_name_width) max_name_width = cl; @@ -502,38 +637,153 @@ static __init void rdt_init_padding(void) } } -static __init bool get_rdt_resources(void) +enum { + RDT_FLAG_CMT, + RDT_FLAG_MBM_TOTAL, + RDT_FLAG_MBM_LOCAL, + RDT_FLAG_L3_CAT, + RDT_FLAG_L3_CDP, + RDT_FLAG_L2_CAT, + RDT_FLAG_MBA, +}; + +#define RDT_OPT(idx, n, f) \ +[idx] = { \ + .name = n, \ + .flag = f \ +} + +struct rdt_options { + char *name; + int flag; + bool force_off, force_on; +}; + +static struct rdt_options rdt_options[] __initdata = { + RDT_OPT(RDT_FLAG_CMT, "cmt", X86_FEATURE_CQM_OCCUP_LLC), + RDT_OPT(RDT_FLAG_MBM_TOTAL, "mbmtotal", X86_FEATURE_CQM_MBM_TOTAL), + RDT_OPT(RDT_FLAG_MBM_LOCAL, "mbmlocal", X86_FEATURE_CQM_MBM_LOCAL), + RDT_OPT(RDT_FLAG_L3_CAT, "l3cat", X86_FEATURE_CAT_L3), + RDT_OPT(RDT_FLAG_L3_CDP, "l3cdp", X86_FEATURE_CDP_L3), + RDT_OPT(RDT_FLAG_L2_CAT, "l2cat", X86_FEATURE_CAT_L2), + RDT_OPT(RDT_FLAG_MBA, "mba", X86_FEATURE_MBA), +}; +#define NUM_RDT_OPTIONS ARRAY_SIZE(rdt_options) + +static int __init set_rdt_options(char *str) +{ + struct rdt_options *o; + bool force_off; + char *tok; + + if (*str == '=') + str++; + while ((tok = strsep(&str, ",")) != NULL) { + force_off = *tok == '!'; + if (force_off) + tok++; + for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) { + if (strcmp(tok, o->name) == 0) { + if (force_off) + o->force_off = true; + else + o->force_on = true; + break; + } + } + } + return 1; +} +__setup("rdt", set_rdt_options); + +static bool __init rdt_cpu_has(int flag) +{ + bool ret = boot_cpu_has(flag); + struct rdt_options *o; + + if (!ret) + return ret; + + for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) { + if (flag == o->flag) { + if (o->force_off) + ret = false; + if (o->force_on) + ret = true; + break; + } + } + return ret; +} + +static __init bool get_rdt_alloc_resources(void) { bool ret = false; - if (cache_alloc_hsw_probe()) + if (rdt_alloc_capable) return true; if (!boot_cpu_has(X86_FEATURE_RDT_A)) return false; - if (boot_cpu_has(X86_FEATURE_CAT_L3)) { - rdt_get_cache_config(1, &rdt_resources_all[RDT_RESOURCE_L3]); - if (boot_cpu_has(X86_FEATURE_CDP_L3)) { + if (rdt_cpu_has(X86_FEATURE_CAT_L3)) { + rdt_get_cache_alloc_cfg(1, &rdt_resources_all[RDT_RESOURCE_L3]); + if (rdt_cpu_has(X86_FEATURE_CDP_L3)) { rdt_get_cdp_l3_config(RDT_RESOURCE_L3DATA); rdt_get_cdp_l3_config(RDT_RESOURCE_L3CODE); } ret = true; } - if (boot_cpu_has(X86_FEATURE_CAT_L2)) { + if (rdt_cpu_has(X86_FEATURE_CAT_L2)) { /* CPUID 0x10.2 fields are same format at 0x10.1 */ - rdt_get_cache_config(2, &rdt_resources_all[RDT_RESOURCE_L2]); + rdt_get_cache_alloc_cfg(2, &rdt_resources_all[RDT_RESOURCE_L2]); ret = true; } - if (boot_cpu_has(X86_FEATURE_MBA)) { + if (rdt_cpu_has(X86_FEATURE_MBA)) { if (rdt_get_mem_config(&rdt_resources_all[RDT_RESOURCE_MBA])) ret = true; } - return ret; } +static __init bool get_rdt_mon_resources(void) +{ + if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) + rdt_mon_features |= (1 << QOS_L3_OCCUP_EVENT_ID); + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) + rdt_mon_features |= (1 << QOS_L3_MBM_TOTAL_EVENT_ID); + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) + rdt_mon_features |= (1 << QOS_L3_MBM_LOCAL_EVENT_ID); + + if (!rdt_mon_features) + return false; + + return !rdt_get_mon_l3_config(&rdt_resources_all[RDT_RESOURCE_L3]); +} + +static __init void rdt_quirks(void) +{ + switch (boot_cpu_data.x86_model) { + case INTEL_FAM6_HASWELL_X: + if (!rdt_options[RDT_FLAG_L3_CAT].force_off) + cache_alloc_hsw_probe(); + break; + case INTEL_FAM6_SKYLAKE_X: + if (boot_cpu_data.x86_mask <= 4) + set_rdt_options("!cmt,!mbmtotal,!mbmlocal,!l3cat"); + } +} + +static __init bool get_rdt_resources(void) +{ + rdt_quirks(); + rdt_alloc_capable = get_rdt_alloc_resources(); + rdt_mon_capable = get_rdt_mon_resources(); + + return (rdt_mon_capable || rdt_alloc_capable); +} + static int __init intel_rdt_late_init(void) { struct rdt_resource *r; @@ -556,9 +806,12 @@ static int __init intel_rdt_late_init(void) return ret; } - for_each_capable_rdt_resource(r) + for_each_alloc_capable_rdt_resource(r) pr_info("Intel RDT %s allocation detected\n", r->name); + for_each_mon_capable_rdt_resource(r) + pr_info("Intel RDT %s monitoring detected\n", r->name); + return 0; } diff --git a/arch/x86/kernel/cpu/intel_rdt.h b/arch/x86/kernel/cpu/intel_rdt.h new file mode 100644 index 000000000000..a43a72d8e88e --- /dev/null +++ b/arch/x86/kernel/cpu/intel_rdt.h @@ -0,0 +1,441 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_INTEL_RDT_H +#define _ASM_X86_INTEL_RDT_H + +#include +#include +#include + +#define IA32_L3_QOS_CFG 0xc81 +#define IA32_L3_CBM_BASE 0xc90 +#define IA32_L2_CBM_BASE 0xd10 +#define IA32_MBA_THRTL_BASE 0xd50 + +#define L3_QOS_CDP_ENABLE 0x01ULL + +/* + * Event IDs are used to program IA32_QM_EVTSEL before reading event + * counter from IA32_QM_CTR + */ +#define QOS_L3_OCCUP_EVENT_ID 0x01 +#define QOS_L3_MBM_TOTAL_EVENT_ID 0x02 +#define QOS_L3_MBM_LOCAL_EVENT_ID 0x03 + +#define CQM_LIMBOCHECK_INTERVAL 1000 + +#define MBM_CNTR_WIDTH 24 +#define MBM_OVERFLOW_INTERVAL 1000 + +#define RMID_VAL_ERROR BIT_ULL(63) +#define RMID_VAL_UNAVAIL BIT_ULL(62) + +DECLARE_STATIC_KEY_FALSE(rdt_enable_key); + +/** + * struct mon_evt - Entry in the event list of a resource + * @evtid: event id + * @name: name of the event + */ +struct mon_evt { + u32 evtid; + char *name; + struct list_head list; +}; + +/** + * struct mon_data_bits - Monitoring details for each event file + * @rid: Resource id associated with the event file. + * @evtid: Event id associated with the event file + * @domid: The domain to which the event file belongs + */ +union mon_data_bits { + void *priv; + struct { + unsigned int rid : 10; + unsigned int evtid : 8; + unsigned int domid : 14; + } u; +}; + +struct rmid_read { + struct rdtgroup *rgrp; + struct rdt_domain *d; + int evtid; + bool first; + u64 val; +}; + +extern unsigned int intel_cqm_threshold; +extern bool rdt_alloc_capable; +extern bool rdt_mon_capable; +extern unsigned int rdt_mon_features; + +enum rdt_group_type { + RDTCTRL_GROUP = 0, + RDTMON_GROUP, + RDT_NUM_GROUP, +}; + +/** + * struct mongroup - store mon group's data in resctrl fs. + * @mon_data_kn kernlfs node for the mon_data directory + * @parent: parent rdtgrp + * @crdtgrp_list: child rdtgroup node list + * @rmid: rmid for this rdtgroup + */ +struct mongroup { + struct kernfs_node *mon_data_kn; + struct rdtgroup *parent; + struct list_head crdtgrp_list; + u32 rmid; +}; + +/** + * struct rdtgroup - store rdtgroup's data in resctrl file system. + * @kn: kernfs node + * @rdtgroup_list: linked list for all rdtgroups + * @closid: closid for this rdtgroup + * @cpu_mask: CPUs assigned to this rdtgroup + * @flags: status bits + * @waitcount: how many cpus expect to find this + * group when they acquire rdtgroup_mutex + * @type: indicates type of this rdtgroup - either + * monitor only or ctrl_mon group + * @mon: mongroup related data + */ +struct rdtgroup { + struct kernfs_node *kn; + struct list_head rdtgroup_list; + u32 closid; + struct cpumask cpu_mask; + int flags; + atomic_t waitcount; + enum rdt_group_type type; + struct mongroup mon; +}; + +/* rdtgroup.flags */ +#define RDT_DELETED 1 + +/* rftype.flags */ +#define RFTYPE_FLAGS_CPUS_LIST 1 + +/* + * Define the file type flags for base and info directories. + */ +#define RFTYPE_INFO BIT(0) +#define RFTYPE_BASE BIT(1) +#define RF_CTRLSHIFT 4 +#define RF_MONSHIFT 5 +#define RFTYPE_CTRL BIT(RF_CTRLSHIFT) +#define RFTYPE_MON BIT(RF_MONSHIFT) +#define RFTYPE_RES_CACHE BIT(8) +#define RFTYPE_RES_MB BIT(9) +#define RF_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL) +#define RF_MON_INFO (RFTYPE_INFO | RFTYPE_MON) +#define RF_CTRL_BASE (RFTYPE_BASE | RFTYPE_CTRL) + +/* List of all resource groups */ +extern struct list_head rdt_all_groups; + +extern int max_name_width, max_data_width; + +int __init rdtgroup_init(void); + +/** + * struct rftype - describe each file in the resctrl file system + * @name: File name + * @mode: Access mode + * @kf_ops: File operations + * @flags: File specific RFTYPE_FLAGS_* flags + * @fflags: File specific RF_* or RFTYPE_* flags + * @seq_show: Show content of the file + * @write: Write to the file + */ +struct rftype { + char *name; + umode_t mode; + struct kernfs_ops *kf_ops; + unsigned long flags; + unsigned long fflags; + + int (*seq_show)(struct kernfs_open_file *of, + struct seq_file *sf, void *v); + /* + * write() is the generic write callback which maps directly to + * kernfs write operation and overrides all other operations. + * Maximum write size is determined by ->max_write_len. + */ + ssize_t (*write)(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off); +}; + +/** + * struct mbm_state - status for each MBM counter in each domain + * @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes) + * @prev_msr Value of IA32_QM_CTR for this RMID last time we read it + */ +struct mbm_state { + u64 chunks; + u64 prev_msr; +}; + +/** + * struct rdt_domain - group of cpus sharing an RDT resource + * @list: all instances of this resource + * @id: unique id for this instance + * @cpu_mask: which cpus share this resource + * @rmid_busy_llc: + * bitmap of which limbo RMIDs are above threshold + * @mbm_total: saved state for MBM total bandwidth + * @mbm_local: saved state for MBM local bandwidth + * @mbm_over: worker to periodically read MBM h/w counters + * @cqm_limbo: worker to periodically read CQM h/w counters + * @mbm_work_cpu: + * worker cpu for MBM h/w counters + * @cqm_work_cpu: + * worker cpu for CQM h/w counters + * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) + * @new_ctrl: new ctrl value to be loaded + * @have_new_ctrl: did user provide new_ctrl for this domain + */ +struct rdt_domain { + struct list_head list; + int id; + struct cpumask cpu_mask; + unsigned long *rmid_busy_llc; + struct mbm_state *mbm_total; + struct mbm_state *mbm_local; + struct delayed_work mbm_over; + struct delayed_work cqm_limbo; + int mbm_work_cpu; + int cqm_work_cpu; + u32 *ctrl_val; + u32 new_ctrl; + bool have_new_ctrl; +}; + +/** + * struct msr_param - set a range of MSRs from a domain + * @res: The resource to use + * @low: Beginning index from base MSR + * @high: End index + */ +struct msr_param { + struct rdt_resource *res; + int low; + int high; +}; + +/** + * struct rdt_cache - Cache allocation related data + * @cbm_len: Length of the cache bit mask + * @min_cbm_bits: Minimum number of consecutive bits to be set + * @cbm_idx_mult: Multiplier of CBM index + * @cbm_idx_offset: Offset of CBM index. CBM index is computed by: + * closid * cbm_idx_multi + cbm_idx_offset + * in a cache bit mask + * @shareable_bits: Bitmask of shareable resource with other + * executing entities + */ +struct rdt_cache { + unsigned int cbm_len; + unsigned int min_cbm_bits; + unsigned int cbm_idx_mult; + unsigned int cbm_idx_offset; + unsigned int shareable_bits; +}; + +/** + * struct rdt_membw - Memory bandwidth allocation related data + * @max_delay: Max throttle delay. Delay is the hardware + * representation for memory bandwidth. + * @min_bw: Minimum memory bandwidth percentage user can request + * @bw_gran: Granularity at which the memory bandwidth is allocated + * @delay_linear: True if memory B/W delay is in linear scale + * @mb_map: Mapping of memory B/W percentage to memory B/W delay + */ +struct rdt_membw { + u32 max_delay; + u32 min_bw; + u32 bw_gran; + u32 delay_linear; + u32 *mb_map; +}; + +static inline bool is_llc_occupancy_enabled(void) +{ + return (rdt_mon_features & (1 << QOS_L3_OCCUP_EVENT_ID)); +} + +static inline bool is_mbm_total_enabled(void) +{ + return (rdt_mon_features & (1 << QOS_L3_MBM_TOTAL_EVENT_ID)); +} + +static inline bool is_mbm_local_enabled(void) +{ + return (rdt_mon_features & (1 << QOS_L3_MBM_LOCAL_EVENT_ID)); +} + +static inline bool is_mbm_enabled(void) +{ + return (is_mbm_total_enabled() || is_mbm_local_enabled()); +} + +static inline bool is_mbm_event(int e) +{ + return (e >= QOS_L3_MBM_TOTAL_EVENT_ID && + e <= QOS_L3_MBM_LOCAL_EVENT_ID); +} + +/** + * struct rdt_resource - attributes of an RDT resource + * @rid: The index of the resource + * @alloc_enabled: Is allocation enabled on this machine + * @mon_enabled: Is monitoring enabled for this feature + * @alloc_capable: Is allocation available on this machine + * @mon_capable: Is monitor feature available on this machine + * @name: Name to use in "schemata" file + * @num_closid: Number of CLOSIDs available + * @cache_level: Which cache level defines scope of this resource + * @default_ctrl: Specifies default cache cbm or memory B/W percent. + * @msr_base: Base MSR address for CBMs + * @msr_update: Function pointer to update QOS MSRs + * @data_width: Character width of data when displaying + * @domains: All domains for this resource + * @cache: Cache allocation related data + * @format_str: Per resource format string to show domain value + * @parse_ctrlval: Per resource function pointer to parse control values + * @evt_list: List of monitoring events + * @num_rmid: Number of RMIDs available + * @mon_scale: cqm counter * mon_scale = occupancy in bytes + * @fflags: flags to choose base and info files + */ +struct rdt_resource { + int rid; + bool alloc_enabled; + bool mon_enabled; + bool alloc_capable; + bool mon_capable; + char *name; + int num_closid; + int cache_level; + u32 default_ctrl; + unsigned int msr_base; + void (*msr_update) (struct rdt_domain *d, struct msr_param *m, + struct rdt_resource *r); + int data_width; + struct list_head domains; + struct rdt_cache cache; + struct rdt_membw membw; + const char *format_str; + int (*parse_ctrlval) (char *buf, struct rdt_resource *r, + struct rdt_domain *d); + struct list_head evt_list; + int num_rmid; + unsigned int mon_scale; + unsigned long fflags; +}; + +int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d); +int parse_bw(char *buf, struct rdt_resource *r, struct rdt_domain *d); + +extern struct mutex rdtgroup_mutex; + +extern struct rdt_resource rdt_resources_all[]; +extern struct rdtgroup rdtgroup_default; +DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key); + +int __init rdtgroup_init(void); + +enum { + RDT_RESOURCE_L3, + RDT_RESOURCE_L3DATA, + RDT_RESOURCE_L3CODE, + RDT_RESOURCE_L2, + RDT_RESOURCE_MBA, + + /* Must be the last */ + RDT_NUM_RESOURCES, +}; + +#define for_each_capable_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->alloc_capable || r->mon_capable) + +#define for_each_alloc_capable_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->alloc_capable) + +#define for_each_mon_capable_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->mon_capable) + +#define for_each_alloc_enabled_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->alloc_enabled) + +#define for_each_mon_enabled_rdt_resource(r) \ + for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\ + r++) \ + if (r->mon_enabled) + +/* CPUID.(EAX=10H, ECX=ResID=1).EAX */ +union cpuid_0x10_1_eax { + struct { + unsigned int cbm_len:5; + } split; + unsigned int full; +}; + +/* CPUID.(EAX=10H, ECX=ResID=3).EAX */ +union cpuid_0x10_3_eax { + struct { + unsigned int max_delay:12; + } split; + unsigned int full; +}; + +/* CPUID.(EAX=10H, ECX=ResID).EDX */ +union cpuid_0x10_x_edx { + struct { + unsigned int cos_max:16; + } split; + unsigned int full; +}; + +void rdt_ctrl_update(void *arg); +struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn); +void rdtgroup_kn_unlock(struct kernfs_node *kn); +struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id, + struct list_head **pos); +ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off); +int rdtgroup_schemata_show(struct kernfs_open_file *of, + struct seq_file *s, void *v); +struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r); +int alloc_rmid(void); +void free_rmid(u32 rmid); +int rdt_get_mon_l3_config(struct rdt_resource *r); +void mon_event_count(void *info); +int rdtgroup_mondata_show(struct seq_file *m, void *arg); +void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, + unsigned int dom_id); +void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, + struct rdt_domain *d); +void mon_event_read(struct rmid_read *rr, struct rdt_domain *d, + struct rdtgroup *rdtgrp, int evtid, int first); +void mbm_setup_overflow_handler(struct rdt_domain *dom, + unsigned long delay_ms); +void mbm_handle_overflow(struct work_struct *work); +void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms); +void cqm_handle_limbo(struct work_struct *work); +bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d); +void __check_limbo(struct rdt_domain *d, bool force_free); + +#endif /* _ASM_X86_INTEL_RDT_H */ diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c similarity index 82% rename from arch/x86/kernel/cpu/intel_rdt_schemata.c rename to arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c index 406d7a6532f9..f6ea94f8954a 100644 --- a/arch/x86/kernel/cpu/intel_rdt_schemata.c +++ b/arch/x86/kernel/cpu/intel_rdt_ctrlmondata.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "intel_rdt.h" /* * Check whether MBA bandwidth percentage value is correct. The value is @@ -192,7 +192,7 @@ static int rdtgroup_parse_resource(char *resname, char *tok, int closid) { struct rdt_resource *r; - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { if (!strcmp(resname, r->name) && closid < r->num_closid) return parse_line(tok, r); } @@ -221,7 +221,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, closid = rdtgrp->closid; - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { list_for_each_entry(dom, &r->domains, list) dom->have_new_ctrl = false; } @@ -237,7 +237,7 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, goto out; } - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { ret = update_domains(r, closid); if (ret) goto out; @@ -269,12 +269,13 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of, { struct rdtgroup *rdtgrp; struct rdt_resource *r; - int closid, ret = 0; + int ret = 0; + u32 closid; rdtgrp = rdtgroup_kn_lock_live(of->kn); if (rdtgrp) { closid = rdtgrp->closid; - for_each_enabled_rdt_resource(r) { + for_each_alloc_enabled_rdt_resource(r) { if (closid < r->num_closid) show_doms(s, r, closid); } @@ -284,3 +285,57 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of, rdtgroup_kn_unlock(of->kn); return ret; } + +void mon_event_read(struct rmid_read *rr, struct rdt_domain *d, + struct rdtgroup *rdtgrp, int evtid, int first) +{ + /* + * setup the parameters to send to the IPI to read the data. + */ + rr->rgrp = rdtgrp; + rr->evtid = evtid; + rr->d = d; + rr->val = 0; + rr->first = first; + + smp_call_function_any(&d->cpu_mask, mon_event_count, rr, 1); +} + +int rdtgroup_mondata_show(struct seq_file *m, void *arg) +{ + struct kernfs_open_file *of = m->private; + u32 resid, evtid, domid; + struct rdtgroup *rdtgrp; + struct rdt_resource *r; + union mon_data_bits md; + struct rdt_domain *d; + struct rmid_read rr; + int ret = 0; + + rdtgrp = rdtgroup_kn_lock_live(of->kn); + + md.priv = of->kn->priv; + resid = md.u.rid; + domid = md.u.domid; + evtid = md.u.evtid; + + r = &rdt_resources_all[resid]; + d = rdt_find_domain(r, domid, NULL); + if (!d) { + ret = -ENOENT; + goto out; + } + + mon_event_read(&rr, d, rdtgrp, evtid, false); + + if (rr.val & RMID_VAL_ERROR) + seq_puts(m, "Error\n"); + else if (rr.val & RMID_VAL_UNAVAIL) + seq_puts(m, "Unavailable\n"); + else + seq_printf(m, "%llu\n", rr.val * r->mon_scale); + +out: + rdtgroup_kn_unlock(of->kn); + return ret; +} diff --git a/arch/x86/kernel/cpu/intel_rdt_monitor.c b/arch/x86/kernel/cpu/intel_rdt_monitor.c new file mode 100644 index 000000000000..30827510094b --- /dev/null +++ b/arch/x86/kernel/cpu/intel_rdt_monitor.c @@ -0,0 +1,499 @@ +/* + * Resource Director Technology(RDT) + * - Monitoring code + * + * Copyright (C) 2017 Intel Corporation + * + * Author: + * Vikas Shivappa + * + * This replaces the cqm.c based on perf but we reuse a lot of + * code and datastructures originally from Peter Zijlstra and Matt Fleming. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * More information about RDT be found in the Intel (R) x86 Architecture + * Software Developer Manual June 2016, volume 3, section 17.17. + */ + +#include +#include +#include +#include "intel_rdt.h" + +#define MSR_IA32_QM_CTR 0x0c8e +#define MSR_IA32_QM_EVTSEL 0x0c8d + +struct rmid_entry { + u32 rmid; + int busy; + struct list_head list; +}; + +/** + * @rmid_free_lru A least recently used list of free RMIDs + * These RMIDs are guaranteed to have an occupancy less than the + * threshold occupancy + */ +static LIST_HEAD(rmid_free_lru); + +/** + * @rmid_limbo_count count of currently unused but (potentially) + * dirty RMIDs. + * This counts RMIDs that no one is currently using but that + * may have a occupancy value > intel_cqm_threshold. User can change + * the threshold occupancy value. + */ +unsigned int rmid_limbo_count; + +/** + * @rmid_entry - The entry in the limbo and free lists. + */ +static struct rmid_entry *rmid_ptrs; + +/* + * Global boolean for rdt_monitor which is true if any + * resource monitoring is enabled. + */ +bool rdt_mon_capable; + +/* + * Global to indicate which monitoring events are enabled. + */ +unsigned int rdt_mon_features; + +/* + * This is the threshold cache occupancy at which we will consider an + * RMID available for re-allocation. + */ +unsigned int intel_cqm_threshold; + +static inline struct rmid_entry *__rmid_entry(u32 rmid) +{ + struct rmid_entry *entry; + + entry = &rmid_ptrs[rmid]; + WARN_ON(entry->rmid != rmid); + + return entry; +} + +static u64 __rmid_read(u32 rmid, u32 eventid) +{ + u64 val; + + /* + * As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured + * with a valid event code for supported resource type and the bits + * IA32_QM_EVTSEL.RMID (bits 41:32) are configured with valid RMID, + * IA32_QM_CTR.data (bits 61:0) reports the monitored data. + * IA32_QM_CTR.Error (bit 63) and IA32_QM_CTR.Unavailable (bit 62) + * are error bits. + */ + wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); + rdmsrl(MSR_IA32_QM_CTR, val); + + return val; +} + +static bool rmid_dirty(struct rmid_entry *entry) +{ + u64 val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID); + + return val >= intel_cqm_threshold; +} + +/* + * Check the RMIDs that are marked as busy for this domain. If the + * reported LLC occupancy is below the threshold clear the busy bit and + * decrement the count. If the busy count gets to zero on an RMID, we + * free the RMID + */ +void __check_limbo(struct rdt_domain *d, bool force_free) +{ + struct rmid_entry *entry; + struct rdt_resource *r; + u32 crmid = 1, nrmid; + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + + /* + * Skip RMID 0 and start from RMID 1 and check all the RMIDs that + * are marked as busy for occupancy < threshold. If the occupancy + * is less than the threshold decrement the busy counter of the + * RMID and move it to the free list when the counter reaches 0. + */ + for (;;) { + nrmid = find_next_bit(d->rmid_busy_llc, r->num_rmid, crmid); + if (nrmid >= r->num_rmid) + break; + + entry = __rmid_entry(nrmid); + if (force_free || !rmid_dirty(entry)) { + clear_bit(entry->rmid, d->rmid_busy_llc); + if (!--entry->busy) { + rmid_limbo_count--; + list_add_tail(&entry->list, &rmid_free_lru); + } + } + crmid = nrmid + 1; + } +} + +bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d) +{ + return find_first_bit(d->rmid_busy_llc, r->num_rmid) != r->num_rmid; +} + +/* + * As of now the RMIDs allocation is global. + * However we keep track of which packages the RMIDs + * are used to optimize the limbo list management. + */ +int alloc_rmid(void) +{ + struct rmid_entry *entry; + + lockdep_assert_held(&rdtgroup_mutex); + + if (list_empty(&rmid_free_lru)) + return rmid_limbo_count ? -EBUSY : -ENOSPC; + + entry = list_first_entry(&rmid_free_lru, + struct rmid_entry, list); + list_del(&entry->list); + + return entry->rmid; +} + +static void add_rmid_to_limbo(struct rmid_entry *entry) +{ + struct rdt_resource *r; + struct rdt_domain *d; + int cpu; + u64 val; + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + + entry->busy = 0; + cpu = get_cpu(); + list_for_each_entry(d, &r->domains, list) { + if (cpumask_test_cpu(cpu, &d->cpu_mask)) { + val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID); + if (val <= intel_cqm_threshold) + continue; + } + + /* + * For the first limbo RMID in the domain, + * setup up the limbo worker. + */ + if (!has_busy_rmid(r, d)) + cqm_setup_limbo_handler(d, CQM_LIMBOCHECK_INTERVAL); + set_bit(entry->rmid, d->rmid_busy_llc); + entry->busy++; + } + put_cpu(); + + if (entry->busy) + rmid_limbo_count++; + else + list_add_tail(&entry->list, &rmid_free_lru); +} + +void free_rmid(u32 rmid) +{ + struct rmid_entry *entry; + + if (!rmid) + return; + + lockdep_assert_held(&rdtgroup_mutex); + + entry = __rmid_entry(rmid); + + if (is_llc_occupancy_enabled()) + add_rmid_to_limbo(entry); + else + list_add_tail(&entry->list, &rmid_free_lru); +} + +static int __mon_event_count(u32 rmid, struct rmid_read *rr) +{ + u64 chunks, shift, tval; + struct mbm_state *m; + + tval = __rmid_read(rmid, rr->evtid); + if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { + rr->val = tval; + return -EINVAL; + } + switch (rr->evtid) { + case QOS_L3_OCCUP_EVENT_ID: + rr->val += tval; + return 0; + case QOS_L3_MBM_TOTAL_EVENT_ID: + m = &rr->d->mbm_total[rmid]; + break; + case QOS_L3_MBM_LOCAL_EVENT_ID: + m = &rr->d->mbm_local[rmid]; + break; + default: + /* + * Code would never reach here because + * an invalid event id would fail the __rmid_read. + */ + return -EINVAL; + } + + if (rr->first) { + m->prev_msr = tval; + m->chunks = 0; + return 0; + } + + shift = 64 - MBM_CNTR_WIDTH; + chunks = (tval << shift) - (m->prev_msr << shift); + chunks >>= shift; + m->chunks += chunks; + m->prev_msr = tval; + + rr->val += m->chunks; + return 0; +} + +/* + * This is called via IPI to read the CQM/MBM counters + * on a domain. + */ +void mon_event_count(void *info) +{ + struct rdtgroup *rdtgrp, *entry; + struct rmid_read *rr = info; + struct list_head *head; + + rdtgrp = rr->rgrp; + + if (__mon_event_count(rdtgrp->mon.rmid, rr)) + return; + + /* + * For Ctrl groups read data from child monitor groups. + */ + head = &rdtgrp->mon.crdtgrp_list; + + if (rdtgrp->type == RDTCTRL_GROUP) { + list_for_each_entry(entry, head, mon.crdtgrp_list) { + if (__mon_event_count(entry->mon.rmid, rr)) + return; + } + } +} + +static void mbm_update(struct rdt_domain *d, int rmid) +{ + struct rmid_read rr; + + rr.first = false; + rr.d = d; + + /* + * This is protected from concurrent reads from user + * as both the user and we hold the global mutex. + */ + if (is_mbm_total_enabled()) { + rr.evtid = QOS_L3_MBM_TOTAL_EVENT_ID; + __mon_event_count(rmid, &rr); + } + if (is_mbm_local_enabled()) { + rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID; + __mon_event_count(rmid, &rr); + } +} + +/* + * Handler to scan the limbo list and move the RMIDs + * to free list whose occupancy < threshold_occupancy. + */ +void cqm_handle_limbo(struct work_struct *work) +{ + unsigned long delay = msecs_to_jiffies(CQM_LIMBOCHECK_INTERVAL); + int cpu = smp_processor_id(); + struct rdt_resource *r; + struct rdt_domain *d; + + mutex_lock(&rdtgroup_mutex); + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + d = get_domain_from_cpu(cpu, r); + + if (!d) { + pr_warn_once("Failure to get domain for limbo worker\n"); + goto out_unlock; + } + + __check_limbo(d, false); + + if (has_busy_rmid(r, d)) + schedule_delayed_work_on(cpu, &d->cqm_limbo, delay); + +out_unlock: + mutex_unlock(&rdtgroup_mutex); +} + +void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms) +{ + unsigned long delay = msecs_to_jiffies(delay_ms); + struct rdt_resource *r; + int cpu; + + r = &rdt_resources_all[RDT_RESOURCE_L3]; + + cpu = cpumask_any(&dom->cpu_mask); + dom->cqm_work_cpu = cpu; + + schedule_delayed_work_on(cpu, &dom->cqm_limbo, delay); +} + +void mbm_handle_overflow(struct work_struct *work) +{ + unsigned long delay = msecs_to_jiffies(MBM_OVERFLOW_INTERVAL); + struct rdtgroup *prgrp, *crgrp; + int cpu = smp_processor_id(); + struct list_head *head; + struct rdt_domain *d; + + mutex_lock(&rdtgroup_mutex); + + if (!static_branch_likely(&rdt_enable_key)) + goto out_unlock; + + d = get_domain_from_cpu(cpu, &rdt_resources_all[RDT_RESOURCE_L3]); + if (!d) + goto out_unlock; + + list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { + mbm_update(d, prgrp->mon.rmid); + + head = &prgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) + mbm_update(d, crgrp->mon.rmid); + } + + schedule_delayed_work_on(cpu, &d->mbm_over, delay); + +out_unlock: + mutex_unlock(&rdtgroup_mutex); +} + +void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms) +{ + unsigned long delay = msecs_to_jiffies(delay_ms); + int cpu; + + if (!static_branch_likely(&rdt_enable_key)) + return; + cpu = cpumask_any(&dom->cpu_mask); + dom->mbm_work_cpu = cpu; + schedule_delayed_work_on(cpu, &dom->mbm_over, delay); +} + +static int dom_data_init(struct rdt_resource *r) +{ + struct rmid_entry *entry = NULL; + int i, nr_rmids; + + nr_rmids = r->num_rmid; + rmid_ptrs = kcalloc(nr_rmids, sizeof(struct rmid_entry), GFP_KERNEL); + if (!rmid_ptrs) + return -ENOMEM; + + for (i = 0; i < nr_rmids; i++) { + entry = &rmid_ptrs[i]; + INIT_LIST_HEAD(&entry->list); + + entry->rmid = i; + list_add_tail(&entry->list, &rmid_free_lru); + } + + /* + * RMID 0 is special and is always allocated. It's used for all + * tasks that are not monitored. + */ + entry = __rmid_entry(0); + list_del(&entry->list); + + return 0; +} + +static struct mon_evt llc_occupancy_event = { + .name = "llc_occupancy", + .evtid = QOS_L3_OCCUP_EVENT_ID, +}; + +static struct mon_evt mbm_total_event = { + .name = "mbm_total_bytes", + .evtid = QOS_L3_MBM_TOTAL_EVENT_ID, +}; + +static struct mon_evt mbm_local_event = { + .name = "mbm_local_bytes", + .evtid = QOS_L3_MBM_LOCAL_EVENT_ID, +}; + +/* + * Initialize the event list for the resource. + * + * Note that MBM events are also part of RDT_RESOURCE_L3 resource + * because as per the SDM the total and local memory bandwidth + * are enumerated as part of L3 monitoring. + */ +static void l3_mon_evt_init(struct rdt_resource *r) +{ + INIT_LIST_HEAD(&r->evt_list); + + if (is_llc_occupancy_enabled()) + list_add_tail(&llc_occupancy_event.list, &r->evt_list); + if (is_mbm_total_enabled()) + list_add_tail(&mbm_total_event.list, &r->evt_list); + if (is_mbm_local_enabled()) + list_add_tail(&mbm_local_event.list, &r->evt_list); +} + +int rdt_get_mon_l3_config(struct rdt_resource *r) +{ + int ret; + + r->mon_scale = boot_cpu_data.x86_cache_occ_scale; + r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1; + + /* + * A reasonable upper limit on the max threshold is the number + * of lines tagged per RMID if all RMIDs have the same number of + * lines tagged in the LLC. + * + * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC. + */ + intel_cqm_threshold = boot_cpu_data.x86_cache_size * 1024 / r->num_rmid; + + /* h/w works in units of "boot_cpu_data.x86_cache_occ_scale" */ + intel_cqm_threshold /= r->mon_scale; + + ret = dom_data_init(r); + if (ret) + return ret; + + l3_mon_evt_init(r); + + r->mon_capable = true; + r->mon_enabled = true; + + return 0; +} diff --git a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c index 9257bd9dc664..a869d4a073c5 100644 --- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c @@ -32,17 +32,25 @@ #include -#include -#include +#include +#include "intel_rdt.h" DEFINE_STATIC_KEY_FALSE(rdt_enable_key); -struct kernfs_root *rdt_root; +DEFINE_STATIC_KEY_FALSE(rdt_mon_enable_key); +DEFINE_STATIC_KEY_FALSE(rdt_alloc_enable_key); +static struct kernfs_root *rdt_root; struct rdtgroup rdtgroup_default; LIST_HEAD(rdt_all_groups); /* Kernel fs node for "info" directory under root */ static struct kernfs_node *kn_info; +/* Kernel fs node for "mon_groups" directory under root */ +static struct kernfs_node *kn_mongrp; + +/* Kernel fs node for "mon_data" directory under root */ +static struct kernfs_node *kn_mondata; + /* * Trivial allocator for CLOSIDs. Since h/w only supports a small number, * we can keep a bitmap of free CLOSIDs in a single integer. @@ -66,7 +74,7 @@ static void closid_init(void) int rdt_min_closid = 32; /* Compute rdt_min_closid across all resources */ - for_each_enabled_rdt_resource(r) + for_each_alloc_enabled_rdt_resource(r) rdt_min_closid = min(rdt_min_closid, r->num_closid); closid_free_map = BIT_MASK(rdt_min_closid) - 1; @@ -75,9 +83,9 @@ static void closid_init(void) closid_free_map &= ~1; } -int closid_alloc(void) +static int closid_alloc(void) { - int closid = ffs(closid_free_map); + u32 closid = ffs(closid_free_map); if (closid == 0) return -ENOSPC; @@ -125,28 +133,6 @@ static int rdtgroup_add_file(struct kernfs_node *parent_kn, struct rftype *rft) return 0; } -static int rdtgroup_add_files(struct kernfs_node *kn, struct rftype *rfts, - int len) -{ - struct rftype *rft; - int ret; - - lockdep_assert_held(&rdtgroup_mutex); - - for (rft = rfts; rft < rfts + len; rft++) { - ret = rdtgroup_add_file(kn, rft); - if (ret) - goto error; - } - - return 0; -error: - pr_warn("Failed to add %s, err=%d\n", rft->name, ret); - while (--rft >= rfts) - kernfs_remove_by_name(kn, rft->name); - return ret; -} - static int rdtgroup_seqfile_show(struct seq_file *m, void *arg) { struct kernfs_open_file *of = m->private; @@ -174,6 +160,11 @@ static struct kernfs_ops rdtgroup_kf_single_ops = { .seq_show = rdtgroup_seqfile_show, }; +static struct kernfs_ops kf_mondata_ops = { + .atomic_write_len = PAGE_SIZE, + .seq_show = rdtgroup_mondata_show, +}; + static bool is_cpu_list(struct kernfs_open_file *of) { struct rftype *rft = of->kn->priv; @@ -203,13 +194,18 @@ static int rdtgroup_cpus_show(struct kernfs_open_file *of, /* * This is safe against intel_rdt_sched_in() called from __switch_to() * because __switch_to() is executed with interrupts disabled. A local call - * from rdt_update_closid() is proteced against __switch_to() because + * from update_closid_rmid() is proteced against __switch_to() because * preemption is disabled. */ -static void rdt_update_cpu_closid(void *closid) +static void update_cpu_closid_rmid(void *info) { - if (closid) - this_cpu_write(cpu_closid, *(int *)closid); + struct rdtgroup *r = info; + + if (r) { + this_cpu_write(pqr_state.default_closid, r->closid); + this_cpu_write(pqr_state.default_rmid, r->mon.rmid); + } + /* * We cannot unconditionally write the MSR because the current * executing task might have its own closid selected. Just reuse @@ -221,28 +217,128 @@ static void rdt_update_cpu_closid(void *closid) /* * Update the PGR_ASSOC MSR on all cpus in @cpu_mask, * - * Per task closids must have been set up before calling this function. - * - * The per cpu closids are updated with the smp function call, when @closid - * is not NULL. If @closid is NULL then all affected percpu closids must - * have been set up before calling this function. + * Per task closids/rmids must have been set up before calling this function. */ static void -rdt_update_closid(const struct cpumask *cpu_mask, int *closid) +update_closid_rmid(const struct cpumask *cpu_mask, struct rdtgroup *r) { int cpu = get_cpu(); if (cpumask_test_cpu(cpu, cpu_mask)) - rdt_update_cpu_closid(closid); - smp_call_function_many(cpu_mask, rdt_update_cpu_closid, closid, 1); + update_cpu_closid_rmid(r); + smp_call_function_many(cpu_mask, update_cpu_closid_rmid, r, 1); put_cpu(); } +static int cpus_mon_write(struct rdtgroup *rdtgrp, cpumask_var_t newmask, + cpumask_var_t tmpmask) +{ + struct rdtgroup *prgrp = rdtgrp->mon.parent, *crgrp; + struct list_head *head; + + /* Check whether cpus belong to parent ctrl group */ + cpumask_andnot(tmpmask, newmask, &prgrp->cpu_mask); + if (cpumask_weight(tmpmask)) + return -EINVAL; + + /* Check whether cpus are dropped from this group */ + cpumask_andnot(tmpmask, &rdtgrp->cpu_mask, newmask); + if (cpumask_weight(tmpmask)) { + /* Give any dropped cpus to parent rdtgroup */ + cpumask_or(&prgrp->cpu_mask, &prgrp->cpu_mask, tmpmask); + update_closid_rmid(tmpmask, prgrp); + } + + /* + * If we added cpus, remove them from previous group that owned them + * and update per-cpu rmid + */ + cpumask_andnot(tmpmask, newmask, &rdtgrp->cpu_mask); + if (cpumask_weight(tmpmask)) { + head = &prgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) { + if (crgrp == rdtgrp) + continue; + cpumask_andnot(&crgrp->cpu_mask, &crgrp->cpu_mask, + tmpmask); + } + update_closid_rmid(tmpmask, rdtgrp); + } + + /* Done pushing/pulling - update this group with new mask */ + cpumask_copy(&rdtgrp->cpu_mask, newmask); + + return 0; +} + +static void cpumask_rdtgrp_clear(struct rdtgroup *r, struct cpumask *m) +{ + struct rdtgroup *crgrp; + + cpumask_andnot(&r->cpu_mask, &r->cpu_mask, m); + /* update the child mon group masks as well*/ + list_for_each_entry(crgrp, &r->mon.crdtgrp_list, mon.crdtgrp_list) + cpumask_and(&crgrp->cpu_mask, &r->cpu_mask, &crgrp->cpu_mask); +} + +static int cpus_ctrl_write(struct rdtgroup *rdtgrp, cpumask_var_t newmask, + cpumask_var_t tmpmask, cpumask_var_t tmpmask1) +{ + struct rdtgroup *r, *crgrp; + struct list_head *head; + + /* Check whether cpus are dropped from this group */ + cpumask_andnot(tmpmask, &rdtgrp->cpu_mask, newmask); + if (cpumask_weight(tmpmask)) { + /* Can't drop from default group */ + if (rdtgrp == &rdtgroup_default) + return -EINVAL; + + /* Give any dropped cpus to rdtgroup_default */ + cpumask_or(&rdtgroup_default.cpu_mask, + &rdtgroup_default.cpu_mask, tmpmask); + update_closid_rmid(tmpmask, &rdtgroup_default); + } + + /* + * If we added cpus, remove them from previous group and + * the prev group's child groups that owned them + * and update per-cpu closid/rmid. + */ + cpumask_andnot(tmpmask, newmask, &rdtgrp->cpu_mask); + if (cpumask_weight(tmpmask)) { + list_for_each_entry(r, &rdt_all_groups, rdtgroup_list) { + if (r == rdtgrp) + continue; + cpumask_and(tmpmask1, &r->cpu_mask, tmpmask); + if (cpumask_weight(tmpmask1)) + cpumask_rdtgrp_clear(r, tmpmask1); + } + update_closid_rmid(tmpmask, rdtgrp); + } + + /* Done pushing/pulling - update this group with new mask */ + cpumask_copy(&rdtgrp->cpu_mask, newmask); + + /* + * Clear child mon group masks since there is a new parent mask + * now and update the rmid for the cpus the child lost. + */ + head = &rdtgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) { + cpumask_and(tmpmask, &rdtgrp->cpu_mask, &crgrp->cpu_mask); + update_closid_rmid(tmpmask, rdtgrp); + cpumask_clear(&crgrp->cpu_mask); + } + + return 0; +} + static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { - cpumask_var_t tmpmask, newmask; - struct rdtgroup *rdtgrp, *r; + cpumask_var_t tmpmask, newmask, tmpmask1; + struct rdtgroup *rdtgrp; int ret; if (!buf) @@ -254,6 +350,11 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, free_cpumask_var(tmpmask); return -ENOMEM; } + if (!zalloc_cpumask_var(&tmpmask1, GFP_KERNEL)) { + free_cpumask_var(tmpmask); + free_cpumask_var(newmask); + return -ENOMEM; + } rdtgrp = rdtgroup_kn_lock_live(of->kn); if (!rdtgrp) { @@ -276,41 +377,18 @@ static ssize_t rdtgroup_cpus_write(struct kernfs_open_file *of, goto unlock; } - /* Check whether cpus are dropped from this group */ - cpumask_andnot(tmpmask, &rdtgrp->cpu_mask, newmask); - if (cpumask_weight(tmpmask)) { - /* Can't drop from default group */ - if (rdtgrp == &rdtgroup_default) { - ret = -EINVAL; - goto unlock; - } - /* Give any dropped cpus to rdtgroup_default */ - cpumask_or(&rdtgroup_default.cpu_mask, - &rdtgroup_default.cpu_mask, tmpmask); - rdt_update_closid(tmpmask, &rdtgroup_default.closid); - } - - /* - * If we added cpus, remove them from previous group that owned them - * and update per-cpu closid - */ - cpumask_andnot(tmpmask, newmask, &rdtgrp->cpu_mask); - if (cpumask_weight(tmpmask)) { - list_for_each_entry(r, &rdt_all_groups, rdtgroup_list) { - if (r == rdtgrp) - continue; - cpumask_andnot(&r->cpu_mask, &r->cpu_mask, tmpmask); - } - rdt_update_closid(tmpmask, &rdtgrp->closid); - } - - /* Done pushing/pulling - update this group with new mask */ - cpumask_copy(&rdtgrp->cpu_mask, newmask); + if (rdtgrp->type == RDTCTRL_GROUP) + ret = cpus_ctrl_write(rdtgrp, newmask, tmpmask, tmpmask1); + else if (rdtgrp->type == RDTMON_GROUP) + ret = cpus_mon_write(rdtgrp, newmask, tmpmask); + else + ret = -EINVAL; unlock: rdtgroup_kn_unlock(of->kn); free_cpumask_var(tmpmask); free_cpumask_var(newmask); + free_cpumask_var(tmpmask1); return ret ?: nbytes; } @@ -336,6 +414,7 @@ static void move_myself(struct callback_head *head) if (atomic_dec_and_test(&rdtgrp->waitcount) && (rdtgrp->flags & RDT_DELETED)) { current->closid = 0; + current->rmid = 0; kfree(rdtgrp); } @@ -374,7 +453,20 @@ static int __rdtgroup_move_task(struct task_struct *tsk, atomic_dec(&rdtgrp->waitcount); kfree(callback); } else { - tsk->closid = rdtgrp->closid; + /* + * For ctrl_mon groups move both closid and rmid. + * For monitor groups, can move the tasks only from + * their parent CTRL group. + */ + if (rdtgrp->type == RDTCTRL_GROUP) { + tsk->closid = rdtgrp->closid; + tsk->rmid = rdtgrp->mon.rmid; + } else if (rdtgrp->type == RDTMON_GROUP) { + if (rdtgrp->mon.parent->closid == tsk->closid) + tsk->rmid = rdtgrp->mon.rmid; + else + ret = -EINVAL; + } } return ret; } @@ -454,7 +546,8 @@ static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s) rcu_read_lock(); for_each_process_thread(p, t) { - if (t->closid == r->closid) + if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || + (r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) seq_printf(s, "%d\n", t->pid); } rcu_read_unlock(); @@ -476,39 +569,6 @@ static int rdtgroup_tasks_show(struct kernfs_open_file *of, return ret; } -/* Files in each rdtgroup */ -static struct rftype rdtgroup_base_files[] = { - { - .name = "cpus", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_cpus_write, - .seq_show = rdtgroup_cpus_show, - }, - { - .name = "cpus_list", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_cpus_write, - .seq_show = rdtgroup_cpus_show, - .flags = RFTYPE_FLAGS_CPUS_LIST, - }, - { - .name = "tasks", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_tasks_write, - .seq_show = rdtgroup_tasks_show, - }, - { - .name = "schemata", - .mode = 0644, - .kf_ops = &rdtgroup_kf_single_ops, - .write = rdtgroup_schemata_write, - .seq_show = rdtgroup_schemata_show, - }, -}; - static int rdt_num_closids_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { @@ -536,6 +596,15 @@ static int rdt_min_cbm_bits_show(struct kernfs_open_file *of, return 0; } +static int rdt_shareable_bits_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%x\n", r->cache.shareable_bits); + return 0; +} + static int rdt_min_bw_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { @@ -545,6 +614,28 @@ static int rdt_min_bw_show(struct kernfs_open_file *of, return 0; } +static int rdt_num_rmids_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%d\n", r->num_rmid); + + return 0; +} + +static int rdt_mon_features_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + struct mon_evt *mevt; + + list_for_each_entry(mevt, &r->evt_list, list) + seq_printf(seq, "%s\n", mevt->name); + + return 0; +} + static int rdt_bw_gran_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { @@ -563,74 +654,200 @@ static int rdt_delay_linear_show(struct kernfs_open_file *of, return 0; } +static int max_threshold_occ_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct rdt_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%u\n", intel_cqm_threshold * r->mon_scale); + + return 0; +} + +static ssize_t max_threshold_occ_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct rdt_resource *r = of->kn->parent->priv; + unsigned int bytes; + int ret; + + ret = kstrtouint(buf, 0, &bytes); + if (ret) + return ret; + + if (bytes > (boot_cpu_data.x86_cache_size * 1024)) + return -EINVAL; + + intel_cqm_threshold = bytes / r->mon_scale; + + return nbytes; +} + /* rdtgroup information files for one cache resource. */ -static struct rftype res_cache_info_files[] = { +static struct rftype res_common_files[] = { { .name = "num_closids", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_num_closids_show, + .fflags = RF_CTRL_INFO, + }, + { + .name = "mon_features", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_mon_features_show, + .fflags = RF_MON_INFO, + }, + { + .name = "num_rmids", + .mode = 0444, + .kf_ops = &rdtgroup_kf_single_ops, + .seq_show = rdt_num_rmids_show, + .fflags = RF_MON_INFO, }, { .name = "cbm_mask", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_default_ctrl_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, }, { .name = "min_cbm_bits", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_min_cbm_bits_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, }, -}; - -/* rdtgroup information files for memory bandwidth. */ -static struct rftype res_mba_info_files[] = { { - .name = "num_closids", + .name = "shareable_bits", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, - .seq_show = rdt_num_closids_show, + .seq_show = rdt_shareable_bits_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, }, { .name = "min_bandwidth", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_min_bw_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, }, { .name = "bandwidth_gran", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_bw_gran_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, }, { .name = "delay_linear", .mode = 0444, .kf_ops = &rdtgroup_kf_single_ops, .seq_show = rdt_delay_linear_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, + }, + { + .name = "max_threshold_occupancy", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = max_threshold_occ_write, + .seq_show = max_threshold_occ_show, + .fflags = RF_MON_INFO | RFTYPE_RES_CACHE, + }, + { + .name = "cpus", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_cpus_write, + .seq_show = rdtgroup_cpus_show, + .fflags = RFTYPE_BASE, + }, + { + .name = "cpus_list", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_cpus_write, + .seq_show = rdtgroup_cpus_show, + .flags = RFTYPE_FLAGS_CPUS_LIST, + .fflags = RFTYPE_BASE, + }, + { + .name = "tasks", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_tasks_write, + .seq_show = rdtgroup_tasks_show, + .fflags = RFTYPE_BASE, + }, + { + .name = "schemata", + .mode = 0644, + .kf_ops = &rdtgroup_kf_single_ops, + .write = rdtgroup_schemata_write, + .seq_show = rdtgroup_schemata_show, + .fflags = RF_CTRL_BASE, }, }; -void rdt_get_mba_infofile(struct rdt_resource *r) +static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags) { - r->info_files = res_mba_info_files; - r->nr_info_files = ARRAY_SIZE(res_mba_info_files); + struct rftype *rfts, *rft; + int ret, len; + + rfts = res_common_files; + len = ARRAY_SIZE(res_common_files); + + lockdep_assert_held(&rdtgroup_mutex); + + for (rft = rfts; rft < rfts + len; rft++) { + if ((fflags & rft->fflags) == rft->fflags) { + ret = rdtgroup_add_file(kn, rft); + if (ret) + goto error; + } + } + + return 0; +error: + pr_warn("Failed to add %s, err=%d\n", rft->name, ret); + while (--rft >= rfts) { + if ((fflags & rft->fflags) == rft->fflags) + kernfs_remove_by_name(kn, rft->name); + } + return ret; } -void rdt_get_cache_infofile(struct rdt_resource *r) +static int rdtgroup_mkdir_info_resdir(struct rdt_resource *r, char *name, + unsigned long fflags) { - r->info_files = res_cache_info_files; - r->nr_info_files = ARRAY_SIZE(res_cache_info_files); + struct kernfs_node *kn_subdir; + int ret; + + kn_subdir = kernfs_create_dir(kn_info, name, + kn_info->mode, r); + if (IS_ERR(kn_subdir)) + return PTR_ERR(kn_subdir); + + kernfs_get(kn_subdir); + ret = rdtgroup_kn_set_ugid(kn_subdir); + if (ret) + return ret; + + ret = rdtgroup_add_files(kn_subdir, fflags); + if (!ret) + kernfs_activate(kn_subdir); + + return ret; } static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) { - struct kernfs_node *kn_subdir; - struct rftype *res_info_files; struct rdt_resource *r; - int ret, len; + unsigned long fflags; + char name[32]; + int ret; /* create the directory */ kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); @@ -638,25 +855,19 @@ static int rdtgroup_create_info_dir(struct kernfs_node *parent_kn) return PTR_ERR(kn_info); kernfs_get(kn_info); - for_each_enabled_rdt_resource(r) { - kn_subdir = kernfs_create_dir(kn_info, r->name, - kn_info->mode, r); - if (IS_ERR(kn_subdir)) { - ret = PTR_ERR(kn_subdir); - goto out_destroy; - } - kernfs_get(kn_subdir); - ret = rdtgroup_kn_set_ugid(kn_subdir); + for_each_alloc_enabled_rdt_resource(r) { + fflags = r->fflags | RF_CTRL_INFO; + ret = rdtgroup_mkdir_info_resdir(r, r->name, fflags); if (ret) goto out_destroy; + } - res_info_files = r->info_files; - len = r->nr_info_files; - - ret = rdtgroup_add_files(kn_subdir, res_info_files, len); + for_each_mon_enabled_rdt_resource(r) { + fflags = r->fflags | RF_MON_INFO; + sprintf(name, "%s_MON", r->name); + ret = rdtgroup_mkdir_info_resdir(r, name, fflags); if (ret) goto out_destroy; - kernfs_activate(kn_subdir); } /* @@ -678,6 +889,39 @@ out_destroy: return ret; } +static int +mongroup_create_dir(struct kernfs_node *parent_kn, struct rdtgroup *prgrp, + char *name, struct kernfs_node **dest_kn) +{ + struct kernfs_node *kn; + int ret; + + /* create the directory */ + kn = kernfs_create_dir(parent_kn, name, parent_kn->mode, prgrp); + if (IS_ERR(kn)) + return PTR_ERR(kn); + + if (dest_kn) + *dest_kn = kn; + + /* + * This extra ref will be put in kernfs_remove() and guarantees + * that @rdtgrp->kn is always accessible. + */ + kernfs_get(kn); + + ret = rdtgroup_kn_set_ugid(kn); + if (ret) + goto out_destroy; + + kernfs_activate(kn); + + return 0; + +out_destroy: + kernfs_remove(kn); + return ret; +} static void l3_qos_cfg_update(void *arg) { bool *enable = arg; @@ -718,14 +962,15 @@ static int cdp_enable(void) struct rdt_resource *r_l3 = &rdt_resources_all[RDT_RESOURCE_L3]; int ret; - if (!r_l3->capable || !r_l3data->capable || !r_l3code->capable) + if (!r_l3->alloc_capable || !r_l3data->alloc_capable || + !r_l3code->alloc_capable) return -EINVAL; ret = set_l3_qos_cfg(r_l3, true); if (!ret) { - r_l3->enabled = false; - r_l3data->enabled = true; - r_l3code->enabled = true; + r_l3->alloc_enabled = false; + r_l3data->alloc_enabled = true; + r_l3code->alloc_enabled = true; } return ret; } @@ -734,11 +979,11 @@ static void cdp_disable(void) { struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3]; - r->enabled = r->capable; + r->alloc_enabled = r->alloc_capable; - if (rdt_resources_all[RDT_RESOURCE_L3DATA].enabled) { - rdt_resources_all[RDT_RESOURCE_L3DATA].enabled = false; - rdt_resources_all[RDT_RESOURCE_L3CODE].enabled = false; + if (rdt_resources_all[RDT_RESOURCE_L3DATA].alloc_enabled) { + rdt_resources_all[RDT_RESOURCE_L3DATA].alloc_enabled = false; + rdt_resources_all[RDT_RESOURCE_L3CODE].alloc_enabled = false; set_l3_qos_cfg(r, false); } } @@ -823,10 +1068,16 @@ void rdtgroup_kn_unlock(struct kernfs_node *kn) } } +static int mkdir_mondata_all(struct kernfs_node *parent_kn, + struct rdtgroup *prgrp, + struct kernfs_node **mon_data_kn); + static struct dentry *rdt_mount(struct file_system_type *fs_type, int flags, const char *unused_dev_name, void *data) { + struct rdt_domain *dom; + struct rdt_resource *r; struct dentry *dentry; int ret; @@ -853,15 +1104,54 @@ static struct dentry *rdt_mount(struct file_system_type *fs_type, goto out_cdp; } + if (rdt_mon_capable) { + ret = mongroup_create_dir(rdtgroup_default.kn, + NULL, "mon_groups", + &kn_mongrp); + if (ret) { + dentry = ERR_PTR(ret); + goto out_info; + } + kernfs_get(kn_mongrp); + + ret = mkdir_mondata_all(rdtgroup_default.kn, + &rdtgroup_default, &kn_mondata); + if (ret) { + dentry = ERR_PTR(ret); + goto out_mongrp; + } + kernfs_get(kn_mondata); + rdtgroup_default.mon.mon_data_kn = kn_mondata; + } + dentry = kernfs_mount(fs_type, flags, rdt_root, RDTGROUP_SUPER_MAGIC, NULL); if (IS_ERR(dentry)) - goto out_destroy; + goto out_mondata; + + if (rdt_alloc_capable) + static_branch_enable(&rdt_alloc_enable_key); + if (rdt_mon_capable) + static_branch_enable(&rdt_mon_enable_key); + + if (rdt_alloc_capable || rdt_mon_capable) + static_branch_enable(&rdt_enable_key); + + if (is_mbm_enabled()) { + r = &rdt_resources_all[RDT_RESOURCE_L3]; + list_for_each_entry(dom, &r->domains, list) + mbm_setup_overflow_handler(dom, MBM_OVERFLOW_INTERVAL); + } - static_branch_enable(&rdt_enable_key); goto out; -out_destroy: +out_mondata: + if (rdt_mon_capable) + kernfs_remove(kn_mondata); +out_mongrp: + if (rdt_mon_capable) + kernfs_remove(kn_mongrp); +out_info: kernfs_remove(kn_info); out_cdp: cdp_disable(); @@ -909,6 +1199,18 @@ static int reset_all_ctrls(struct rdt_resource *r) return 0; } +static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_alloc_capable && + (r->type == RDTCTRL_GROUP) && (t->closid == r->closid)); +} + +static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_mon_capable && + (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid)); +} + /* * Move tasks from one to the other group. If @from is NULL, then all tasks * in the systems are moved unconditionally (used for teardown). @@ -924,8 +1226,11 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, read_lock(&tasklist_lock); for_each_process_thread(p, t) { - if (!from || t->closid == from->closid) { + if (!from || is_closid_match(t, from) || + is_rmid_match(t, from)) { t->closid = to->closid; + t->rmid = to->mon.rmid; + #ifdef CONFIG_SMP /* * This is safe on x86 w/o barriers as the ordering @@ -944,6 +1249,19 @@ static void rdt_move_group_tasks(struct rdtgroup *from, struct rdtgroup *to, read_unlock(&tasklist_lock); } +static void free_all_child_rdtgrp(struct rdtgroup *rdtgrp) +{ + struct rdtgroup *sentry, *stmp; + struct list_head *head; + + head = &rdtgrp->mon.crdtgrp_list; + list_for_each_entry_safe(sentry, stmp, head, mon.crdtgrp_list) { + free_rmid(sentry->mon.rmid); + list_del(&sentry->mon.crdtgrp_list); + kfree(sentry); + } +} + /* * Forcibly remove all of subdirectories under root. */ @@ -955,6 +1273,9 @@ static void rmdir_all_sub(void) rdt_move_group_tasks(NULL, &rdtgroup_default, NULL); list_for_each_entry_safe(rdtgrp, tmp, &rdt_all_groups, rdtgroup_list) { + /* Free any child rmids */ + free_all_child_rdtgrp(rdtgrp); + /* Remove each rdtgroup other than root */ if (rdtgrp == &rdtgroup_default) continue; @@ -967,16 +1288,20 @@ static void rmdir_all_sub(void) cpumask_or(&rdtgroup_default.cpu_mask, &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask); + free_rmid(rdtgrp->mon.rmid); + kernfs_remove(rdtgrp->kn); list_del(&rdtgrp->rdtgroup_list); kfree(rdtgrp); } /* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */ get_online_cpus(); - rdt_update_closid(cpu_online_mask, &rdtgroup_default.closid); + update_closid_rmid(cpu_online_mask, &rdtgroup_default); put_online_cpus(); kernfs_remove(kn_info); + kernfs_remove(kn_mongrp); + kernfs_remove(kn_mondata); } static void rdt_kill_sb(struct super_block *sb) @@ -986,10 +1311,12 @@ static void rdt_kill_sb(struct super_block *sb) mutex_lock(&rdtgroup_mutex); /*Put everything back to default values. */ - for_each_enabled_rdt_resource(r) + for_each_alloc_enabled_rdt_resource(r) reset_all_ctrls(r); cdp_disable(); rmdir_all_sub(); + static_branch_disable(&rdt_alloc_enable_key); + static_branch_disable(&rdt_mon_enable_key); static_branch_disable(&rdt_enable_key); kernfs_kill_sb(sb); mutex_unlock(&rdtgroup_mutex); @@ -1001,46 +1328,223 @@ static struct file_system_type rdt_fs_type = { .kill_sb = rdt_kill_sb, }; -static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, - umode_t mode) +static int mon_addfile(struct kernfs_node *parent_kn, const char *name, + void *priv) { - struct rdtgroup *parent, *rdtgrp; struct kernfs_node *kn; - int ret, closid; + int ret = 0; - /* Only allow mkdir in the root directory */ - if (parent_kn != rdtgroup_default.kn) - return -EPERM; + kn = __kernfs_create_file(parent_kn, name, 0444, 0, + &kf_mondata_ops, priv, NULL, NULL); + if (IS_ERR(kn)) + return PTR_ERR(kn); - /* Do not accept '\n' to avoid unparsable situation. */ - if (strchr(name, '\n')) - return -EINVAL; + ret = rdtgroup_kn_set_ugid(kn); + if (ret) { + kernfs_remove(kn); + return ret; + } - parent = rdtgroup_kn_lock_live(parent_kn); - if (!parent) { + return ret; +} + +/* + * Remove all subdirectories of mon_data of ctrl_mon groups + * and monitor groups with given domain id. + */ +void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, unsigned int dom_id) +{ + struct rdtgroup *prgrp, *crgrp; + char name[32]; + + if (!r->mon_enabled) + return; + + list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { + sprintf(name, "mon_%s_%02d", r->name, dom_id); + kernfs_remove_by_name(prgrp->mon.mon_data_kn, name); + + list_for_each_entry(crgrp, &prgrp->mon.crdtgrp_list, mon.crdtgrp_list) + kernfs_remove_by_name(crgrp->mon.mon_data_kn, name); + } +} + +static int mkdir_mondata_subdir(struct kernfs_node *parent_kn, + struct rdt_domain *d, + struct rdt_resource *r, struct rdtgroup *prgrp) +{ + union mon_data_bits priv; + struct kernfs_node *kn; + struct mon_evt *mevt; + struct rmid_read rr; + char name[32]; + int ret; + + sprintf(name, "mon_%s_%02d", r->name, d->id); + /* create the directory */ + kn = kernfs_create_dir(parent_kn, name, parent_kn->mode, prgrp); + if (IS_ERR(kn)) + return PTR_ERR(kn); + + /* + * This extra ref will be put in kernfs_remove() and guarantees + * that kn is always accessible. + */ + kernfs_get(kn); + ret = rdtgroup_kn_set_ugid(kn); + if (ret) + goto out_destroy; + + if (WARN_ON(list_empty(&r->evt_list))) { + ret = -EPERM; + goto out_destroy; + } + + priv.u.rid = r->rid; + priv.u.domid = d->id; + list_for_each_entry(mevt, &r->evt_list, list) { + priv.u.evtid = mevt->evtid; + ret = mon_addfile(kn, mevt->name, priv.priv); + if (ret) + goto out_destroy; + + if (is_mbm_event(mevt->evtid)) + mon_event_read(&rr, d, prgrp, mevt->evtid, true); + } + kernfs_activate(kn); + return 0; + +out_destroy: + kernfs_remove(kn); + return ret; +} + +/* + * Add all subdirectories of mon_data for "ctrl_mon" groups + * and "monitor" groups with given domain id. + */ +void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r, + struct rdt_domain *d) +{ + struct kernfs_node *parent_kn; + struct rdtgroup *prgrp, *crgrp; + struct list_head *head; + + if (!r->mon_enabled) + return; + + list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { + parent_kn = prgrp->mon.mon_data_kn; + mkdir_mondata_subdir(parent_kn, d, r, prgrp); + + head = &prgrp->mon.crdtgrp_list; + list_for_each_entry(crgrp, head, mon.crdtgrp_list) { + parent_kn = crgrp->mon.mon_data_kn; + mkdir_mondata_subdir(parent_kn, d, r, crgrp); + } + } +} + +static int mkdir_mondata_subdir_alldom(struct kernfs_node *parent_kn, + struct rdt_resource *r, + struct rdtgroup *prgrp) +{ + struct rdt_domain *dom; + int ret; + + list_for_each_entry(dom, &r->domains, list) { + ret = mkdir_mondata_subdir(parent_kn, dom, r, prgrp); + if (ret) + return ret; + } + + return 0; +} + +/* + * This creates a directory mon_data which contains the monitored data. + * + * mon_data has one directory for each domain whic are named + * in the format mon__. For ex: A mon_data + * with L3 domain looks as below: + * ./mon_data: + * mon_L3_00 + * mon_L3_01 + * mon_L3_02 + * ... + * + * Each domain directory has one file per event: + * ./mon_L3_00/: + * llc_occupancy + * + */ +static int mkdir_mondata_all(struct kernfs_node *parent_kn, + struct rdtgroup *prgrp, + struct kernfs_node **dest_kn) +{ + struct rdt_resource *r; + struct kernfs_node *kn; + int ret; + + /* + * Create the mon_data directory first. + */ + ret = mongroup_create_dir(parent_kn, NULL, "mon_data", &kn); + if (ret) + return ret; + + if (dest_kn) + *dest_kn = kn; + + /* + * Create the subdirectories for each domain. Note that all events + * in a domain like L3 are grouped into a resource whose domain is L3 + */ + for_each_mon_enabled_rdt_resource(r) { + ret = mkdir_mondata_subdir_alldom(kn, r, prgrp); + if (ret) + goto out_destroy; + } + + return 0; + +out_destroy: + kernfs_remove(kn); + return ret; +} + +static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, + struct kernfs_node *prgrp_kn, + const char *name, umode_t mode, + enum rdt_group_type rtype, struct rdtgroup **r) +{ + struct rdtgroup *prdtgrp, *rdtgrp; + struct kernfs_node *kn; + uint files = 0; + int ret; + + prdtgrp = rdtgroup_kn_lock_live(prgrp_kn); + if (!prdtgrp) { ret = -ENODEV; goto out_unlock; } - ret = closid_alloc(); - if (ret < 0) - goto out_unlock; - closid = ret; - /* allocate the rdtgroup. */ rdtgrp = kzalloc(sizeof(*rdtgrp), GFP_KERNEL); if (!rdtgrp) { ret = -ENOSPC; - goto out_closid_free; + goto out_unlock; } - rdtgrp->closid = closid; - list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups); + *r = rdtgrp; + rdtgrp->mon.parent = prdtgrp; + rdtgrp->type = rtype; + INIT_LIST_HEAD(&rdtgrp->mon.crdtgrp_list); /* kernfs creates the directory for rdtgrp */ - kn = kernfs_create_dir(parent->kn, name, mode, rdtgrp); + kn = kernfs_create_dir(parent_kn, name, mode, rdtgrp); if (IS_ERR(kn)) { ret = PTR_ERR(kn); - goto out_cancel_ref; + goto out_free_rgrp; } rdtgrp->kn = kn; @@ -1056,33 +1560,258 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, if (ret) goto out_destroy; - ret = rdtgroup_add_files(kn, rdtgroup_base_files, - ARRAY_SIZE(rdtgroup_base_files)); + files = RFTYPE_BASE | RFTYPE_CTRL; + files = RFTYPE_BASE | BIT(RF_CTRLSHIFT + rtype); + ret = rdtgroup_add_files(kn, files); if (ret) goto out_destroy; + if (rdt_mon_capable) { + ret = alloc_rmid(); + if (ret < 0) + goto out_destroy; + rdtgrp->mon.rmid = ret; + + ret = mkdir_mondata_all(kn, rdtgrp, &rdtgrp->mon.mon_data_kn); + if (ret) + goto out_idfree; + } kernfs_activate(kn); - ret = 0; - goto out_unlock; + /* + * The caller unlocks the prgrp_kn upon success. + */ + return 0; +out_idfree: + free_rmid(rdtgrp->mon.rmid); out_destroy: kernfs_remove(rdtgrp->kn); -out_cancel_ref: - list_del(&rdtgrp->rdtgroup_list); +out_free_rgrp: kfree(rdtgrp); -out_closid_free: - closid_free(closid); out_unlock: - rdtgroup_kn_unlock(parent_kn); + rdtgroup_kn_unlock(prgrp_kn); return ret; } +static void mkdir_rdt_prepare_clean(struct rdtgroup *rgrp) +{ + kernfs_remove(rgrp->kn); + free_rmid(rgrp->mon.rmid); + kfree(rgrp); +} + +/* + * Create a monitor group under "mon_groups" directory of a control + * and monitor group(ctrl_mon). This is a resource group + * to monitor a subset of tasks and cpus in its parent ctrl_mon group. + */ +static int rdtgroup_mkdir_mon(struct kernfs_node *parent_kn, + struct kernfs_node *prgrp_kn, + const char *name, + umode_t mode) +{ + struct rdtgroup *rdtgrp, *prgrp; + int ret; + + ret = mkdir_rdt_prepare(parent_kn, prgrp_kn, name, mode, RDTMON_GROUP, + &rdtgrp); + if (ret) + return ret; + + prgrp = rdtgrp->mon.parent; + rdtgrp->closid = prgrp->closid; + + /* + * Add the rdtgrp to the list of rdtgrps the parent + * ctrl_mon group has to track. + */ + list_add_tail(&rdtgrp->mon.crdtgrp_list, &prgrp->mon.crdtgrp_list); + + rdtgroup_kn_unlock(prgrp_kn); + return ret; +} + +/* + * These are rdtgroups created under the root directory. Can be used + * to allocate and monitor resources. + */ +static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn, + struct kernfs_node *prgrp_kn, + const char *name, umode_t mode) +{ + struct rdtgroup *rdtgrp; + struct kernfs_node *kn; + u32 closid; + int ret; + + ret = mkdir_rdt_prepare(parent_kn, prgrp_kn, name, mode, RDTCTRL_GROUP, + &rdtgrp); + if (ret) + return ret; + + kn = rdtgrp->kn; + ret = closid_alloc(); + if (ret < 0) + goto out_common_fail; + closid = ret; + + rdtgrp->closid = closid; + list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups); + + if (rdt_mon_capable) { + /* + * Create an empty mon_groups directory to hold the subset + * of tasks and cpus to monitor. + */ + ret = mongroup_create_dir(kn, NULL, "mon_groups", NULL); + if (ret) + goto out_id_free; + } + + goto out_unlock; + +out_id_free: + closid_free(closid); + list_del(&rdtgrp->rdtgroup_list); +out_common_fail: + mkdir_rdt_prepare_clean(rdtgrp); +out_unlock: + rdtgroup_kn_unlock(prgrp_kn); + return ret; +} + +/* + * We allow creating mon groups only with in a directory called "mon_groups" + * which is present in every ctrl_mon group. Check if this is a valid + * "mon_groups" directory. + * + * 1. The directory should be named "mon_groups". + * 2. The mon group itself should "not" be named "mon_groups". + * This makes sure "mon_groups" directory always has a ctrl_mon group + * as parent. + */ +static bool is_mon_groups(struct kernfs_node *kn, const char *name) +{ + return (!strcmp(kn->name, "mon_groups") && + strcmp(name, "mon_groups")); +} + +static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name, + umode_t mode) +{ + /* Do not accept '\n' to avoid unparsable situation. */ + if (strchr(name, '\n')) + return -EINVAL; + + /* + * If the parent directory is the root directory and RDT + * allocation is supported, add a control and monitoring + * subdirectory + */ + if (rdt_alloc_capable && parent_kn == rdtgroup_default.kn) + return rdtgroup_mkdir_ctrl_mon(parent_kn, parent_kn, name, mode); + + /* + * If RDT monitoring is supported and the parent directory is a valid + * "mon_groups" directory, add a monitoring subdirectory. + */ + if (rdt_mon_capable && is_mon_groups(parent_kn, name)) + return rdtgroup_mkdir_mon(parent_kn, parent_kn->parent, name, mode); + + return -EPERM; +} + +static int rdtgroup_rmdir_mon(struct kernfs_node *kn, struct rdtgroup *rdtgrp, + cpumask_var_t tmpmask) +{ + struct rdtgroup *prdtgrp = rdtgrp->mon.parent; + int cpu; + + /* Give any tasks back to the parent group */ + rdt_move_group_tasks(rdtgrp, prdtgrp, tmpmask); + + /* Update per cpu rmid of the moved CPUs first */ + for_each_cpu(cpu, &rdtgrp->cpu_mask) + per_cpu(pqr_state.default_rmid, cpu) = prdtgrp->mon.rmid; + /* + * Update the MSR on moved CPUs and CPUs which have moved + * task running on them. + */ + cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask); + update_closid_rmid(tmpmask, NULL); + + rdtgrp->flags = RDT_DELETED; + free_rmid(rdtgrp->mon.rmid); + + /* + * Remove the rdtgrp from the parent ctrl_mon group's list + */ + WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list)); + list_del(&rdtgrp->mon.crdtgrp_list); + + /* + * one extra hold on this, will drop when we kfree(rdtgrp) + * in rdtgroup_kn_unlock() + */ + kernfs_get(kn); + kernfs_remove(rdtgrp->kn); + + return 0; +} + +static int rdtgroup_rmdir_ctrl(struct kernfs_node *kn, struct rdtgroup *rdtgrp, + cpumask_var_t tmpmask) +{ + int cpu; + + /* Give any tasks back to the default group */ + rdt_move_group_tasks(rdtgrp, &rdtgroup_default, tmpmask); + + /* Give any CPUs back to the default group */ + cpumask_or(&rdtgroup_default.cpu_mask, + &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask); + + /* Update per cpu closid and rmid of the moved CPUs first */ + for_each_cpu(cpu, &rdtgrp->cpu_mask) { + per_cpu(pqr_state.default_closid, cpu) = rdtgroup_default.closid; + per_cpu(pqr_state.default_rmid, cpu) = rdtgroup_default.mon.rmid; + } + + /* + * Update the MSR on moved CPUs and CPUs which have moved + * task running on them. + */ + cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask); + update_closid_rmid(tmpmask, NULL); + + rdtgrp->flags = RDT_DELETED; + closid_free(rdtgrp->closid); + free_rmid(rdtgrp->mon.rmid); + + /* + * Free all the child monitor group rmids. + */ + free_all_child_rdtgrp(rdtgrp); + + list_del(&rdtgrp->rdtgroup_list); + + /* + * one extra hold on this, will drop when we kfree(rdtgrp) + * in rdtgroup_kn_unlock() + */ + kernfs_get(kn); + kernfs_remove(rdtgrp->kn); + + return 0; +} + static int rdtgroup_rmdir(struct kernfs_node *kn) { - int ret, cpu, closid = rdtgroup_default.closid; + struct kernfs_node *parent_kn = kn->parent; struct rdtgroup *rdtgrp; cpumask_var_t tmpmask; + int ret = 0; if (!zalloc_cpumask_var(&tmpmask, GFP_KERNEL)) return -ENOMEM; @@ -1093,34 +1822,21 @@ static int rdtgroup_rmdir(struct kernfs_node *kn) goto out; } - /* Give any tasks back to the default group */ - rdt_move_group_tasks(rdtgrp, &rdtgroup_default, tmpmask); - - /* Give any CPUs back to the default group */ - cpumask_or(&rdtgroup_default.cpu_mask, - &rdtgroup_default.cpu_mask, &rdtgrp->cpu_mask); - - /* Update per cpu closid of the moved CPUs first */ - for_each_cpu(cpu, &rdtgrp->cpu_mask) - per_cpu(cpu_closid, cpu) = closid; /* - * Update the MSR on moved CPUs and CPUs which have moved - * task running on them. + * If the rdtgroup is a ctrl_mon group and parent directory + * is the root directory, remove the ctrl_mon group. + * + * If the rdtgroup is a mon group and parent directory + * is a valid "mon_groups" directory, remove the mon group. */ - cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask); - rdt_update_closid(tmpmask, NULL); + if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) + ret = rdtgroup_rmdir_ctrl(kn, rdtgrp, tmpmask); + else if (rdtgrp->type == RDTMON_GROUP && + is_mon_groups(parent_kn, kn->name)) + ret = rdtgroup_rmdir_mon(kn, rdtgrp, tmpmask); + else + ret = -EPERM; - rdtgrp->flags = RDT_DELETED; - closid_free(rdtgrp->closid); - list_del(&rdtgrp->rdtgroup_list); - - /* - * one extra hold on this, will drop when we kfree(rdtgrp) - * in rdtgroup_kn_unlock() - */ - kernfs_get(kn); - kernfs_remove(rdtgrp->kn); - ret = 0; out: rdtgroup_kn_unlock(kn); free_cpumask_var(tmpmask); @@ -1129,7 +1845,7 @@ out: static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf) { - if (rdt_resources_all[RDT_RESOURCE_L3DATA].enabled) + if (rdt_resources_all[RDT_RESOURCE_L3DATA].alloc_enabled) seq_puts(seq, ",cdp"); return 0; } @@ -1153,10 +1869,13 @@ static int __init rdtgroup_setup_root(void) mutex_lock(&rdtgroup_mutex); rdtgroup_default.closid = 0; + rdtgroup_default.mon.rmid = 0; + rdtgroup_default.type = RDTCTRL_GROUP; + INIT_LIST_HEAD(&rdtgroup_default.mon.crdtgrp_list); + list_add(&rdtgroup_default.rdtgroup_list, &rdt_all_groups); - ret = rdtgroup_add_files(rdt_root->kn, rdtgroup_base_files, - ARRAY_SIZE(rdtgroup_base_files)); + ret = rdtgroup_add_files(rdt_root->kn, RF_CTRL_BASE); if (ret) { kernfs_destroy_root(rdt_root); goto out; diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index e42117d5f4d7..3fed38812eea 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile index 43051f0777d4..bcc7c54c7041 100644 --- a/arch/x86/kernel/cpu/mcheck/Makefile +++ b/arch/x86/kernel/cpu/mcheck/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y = mce.o mce-severity.o mce-genpool.o obj-$(CONFIG_X86_ANCIENT_MCE) += winchip.o p5.o diff --git a/arch/x86/kernel/cpu/mcheck/dev-mcelog.c b/arch/x86/kernel/cpu/mcheck/dev-mcelog.c index 10cec43aac38..7f85b76f43bc 100644 --- a/arch/x86/kernel/cpu/mcheck/dev-mcelog.c +++ b/arch/x86/kernel/cpu/mcheck/dev-mcelog.c @@ -24,14 +24,6 @@ static DEFINE_MUTEX(mce_chrdev_read_mutex); static char mce_helper[128]; static char *mce_helper_argv[2] = { mce_helper, NULL }; -#define mce_log_get_idx_check(p) \ -({ \ - RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held() && \ - !lockdep_is_held(&mce_chrdev_read_mutex), \ - "suspicious mce_log_get_idx_check() usage"); \ - smp_load_acquire(&(p)); \ -}) - /* * Lockless MCE logging infrastructure. * This avoids deadlocks on printk locks without having to break locks. Also @@ -53,43 +45,32 @@ static int dev_mce_log(struct notifier_block *nb, unsigned long val, void *data) { struct mce *mce = (struct mce *)data; - unsigned int next, entry; + unsigned int entry; - wmb(); - for (;;) { - entry = mce_log_get_idx_check(mcelog.next); - for (;;) { + mutex_lock(&mce_chrdev_read_mutex); - /* - * When the buffer fills up discard new entries. - * Assume that the earlier errors are the more - * interesting ones: - */ - if (entry >= MCE_LOG_LEN) { - set_bit(MCE_OVERFLOW, - (unsigned long *)&mcelog.flags); - return NOTIFY_OK; - } - /* Old left over entry. Skip: */ - if (mcelog.entry[entry].finished) { - entry++; - continue; - } - break; - } - smp_rmb(); - next = entry + 1; - if (cmpxchg(&mcelog.next, entry, next) == entry) - break; + entry = mcelog.next; + + /* + * When the buffer fills up discard new entries. Assume that the + * earlier errors are the more interesting ones: + */ + if (entry >= MCE_LOG_LEN) { + set_bit(MCE_OVERFLOW, (unsigned long *)&mcelog.flags); + goto unlock; } + + mcelog.next = entry + 1; + memcpy(mcelog.entry + entry, mce, sizeof(struct mce)); - wmb(); mcelog.entry[entry].finished = 1; - wmb(); /* wake processes polling /dev/mcelog */ wake_up_interruptible(&mce_chrdev_wait); +unlock: + mutex_unlock(&mce_chrdev_read_mutex); + return NOTIFY_OK; } @@ -177,13 +158,6 @@ static int mce_chrdev_release(struct inode *inode, struct file *file) return 0; } -static void collect_tscs(void *data) -{ - unsigned long *cpu_tsc = (unsigned long *)data; - - cpu_tsc[smp_processor_id()] = rdtsc(); -} - static int mce_apei_read_done; /* Collect MCE record of previous boot in persistent storage via APEI ERST. */ @@ -231,14 +205,9 @@ static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf, size_t usize, loff_t *off) { char __user *buf = ubuf; - unsigned long *cpu_tsc; - unsigned prev, next; + unsigned next; int i, err; - cpu_tsc = kmalloc(nr_cpu_ids * sizeof(long), GFP_KERNEL); - if (!cpu_tsc) - return -ENOMEM; - mutex_lock(&mce_chrdev_read_mutex); if (!mce_apei_read_done) { @@ -247,65 +216,29 @@ static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf, goto out; } - next = mce_log_get_idx_check(mcelog.next); - /* Only supports full reads right now */ err = -EINVAL; if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) goto out; + next = mcelog.next; err = 0; - prev = 0; - do { - for (i = prev; i < next; i++) { - unsigned long start = jiffies; - struct mce *m = &mcelog.entry[i]; - while (!m->finished) { - if (time_after_eq(jiffies, start + 2)) { - memset(m, 0, sizeof(*m)); - goto timeout; - } - cpu_relax(); - } - smp_rmb(); - err |= copy_to_user(buf, m, sizeof(*m)); - buf += sizeof(*m); -timeout: - ; - } - - memset(mcelog.entry + prev, 0, - (next - prev) * sizeof(struct mce)); - prev = next; - next = cmpxchg(&mcelog.next, prev, 0); - } while (next != prev); - - synchronize_sched(); - - /* - * Collect entries that were still getting written before the - * synchronize. - */ - on_each_cpu(collect_tscs, cpu_tsc, 1); - - for (i = next; i < MCE_LOG_LEN; i++) { + for (i = 0; i < next; i++) { struct mce *m = &mcelog.entry[i]; - if (m->finished && m->tsc < cpu_tsc[m->cpu]) { - err |= copy_to_user(buf, m, sizeof(*m)); - smp_rmb(); - buf += sizeof(*m); - memset(m, 0, sizeof(*m)); - } + err |= copy_to_user(buf, m, sizeof(*m)); + buf += sizeof(*m); } + memset(mcelog.entry, 0, next * sizeof(struct mce)); + mcelog.next = 0; + if (err) err = -EFAULT; out: mutex_unlock(&mce_chrdev_read_mutex); - kfree(cpu_tsc); return err ? err : buf - ubuf; } diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h index 098530a93bb7..aa0d5df9dc60 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-internal.h +++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h @@ -1,3 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __X86_MCE_INTERNAL_H__ +#define __X86_MCE_INTERNAL_H__ + #include #include @@ -108,3 +112,7 @@ static inline void mce_work_trigger(void) { } static inline void mce_register_injector_chain(struct notifier_block *nb) { } static inline void mce_unregister_injector_chain(struct notifier_block *nb) { } #endif + +extern struct mca_config mca_cfg; + +#endif /* __X86_MCE_INTERNAL_H__ */ diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 6dde0497efc7..3b413065c613 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "mce-internal.h" @@ -1051,6 +1052,48 @@ static int do_memory_failure(struct mce *m) return ret; } +#if defined(arch_unmap_kpfn) && defined(CONFIG_MEMORY_FAILURE) + +void arch_unmap_kpfn(unsigned long pfn) +{ + unsigned long decoy_addr; + + /* + * Unmap this page from the kernel 1:1 mappings to make sure + * we don't log more errors because of speculative access to + * the page. + * We would like to just call: + * set_memory_np((unsigned long)pfn_to_kaddr(pfn), 1); + * but doing that would radically increase the odds of a + * speculative access to the posion page because we'd have + * the virtual address of the kernel 1:1 mapping sitting + * around in registers. + * Instead we get tricky. We create a non-canonical address + * that looks just like the one we want, but has bit 63 flipped. + * This relies on set_memory_np() not checking whether we passed + * a legal address. + */ + +/* + * Build time check to see if we have a spare virtual bit. Don't want + * to leave this until run time because most developers don't have a + * system that can exercise this code path. This will only become a + * problem if/when we move beyond 5-level page tables. + * + * Hard code "9" here because cpp doesn't grok ilog2(PTRS_PER_PGD) + */ +#if PGDIR_SHIFT + 9 < 63 + decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63)); +#else +#error "no unused virtual bit available" +#endif + + if (set_memory_np(decoy_addr, 1)) + pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn); + +} +#endif + /* * The actual machine check handler. This only handles real * exceptions when something got corrupted coming in through int 18. diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 9e314bcf67cc..486f640b02ef 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -28,6 +28,8 @@ #include #include +#include "mce-internal.h" + #define NR_BLOCKS 5 #define THRESHOLD_MAX 0xFFF #define INT_TYPE_APIC 0x00020000 @@ -201,8 +203,8 @@ static void smca_configure(unsigned int bank, unsigned int cpu) wrmsr(smca_config, low, high); } - /* Collect bank_info using CPU 0 for now. */ - if (cpu) + /* Return early if this bank was already initialized. */ + if (smca_banks[bank].hwid) return; if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) { @@ -216,11 +218,6 @@ static void smca_configure(unsigned int bank, unsigned int cpu) for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) { s_hwid = &smca_hwid_mcatypes[i]; if (hwid_mcatype == s_hwid->hwid_mcatype) { - - WARN(smca_banks[bank].hwid, - "Bank %s already initialized!\n", - smca_get_name(s_hwid->bank_type)); - smca_banks[bank].hwid = s_hwid; smca_banks[bank].id = low; smca_banks[bank].sysfs_id = s_hwid->count++; @@ -776,24 +773,12 @@ static void __log_error(unsigned int bank, u64 status, u64 addr, u64 misc) mce_log(&m); } -static inline void __smp_deferred_error_interrupt(void) -{ - inc_irq_stat(irq_deferred_error_count); - deferred_error_int_vector(); -} - asmlinkage __visible void __irq_entry smp_deferred_error_interrupt(void) -{ - entering_irq(); - __smp_deferred_error_interrupt(); - exiting_ack_irq(); -} - -asmlinkage __visible void __irq_entry smp_trace_deferred_error_interrupt(void) { entering_irq(); trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR); - __smp_deferred_error_interrupt(); + inc_irq_stat(irq_deferred_error_count); + deferred_error_int_vector(); trace_deferred_error_apic_exit(DEFERRED_ERROR_VECTOR); exiting_ack_irq(); } diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index e84db79ef272..d05be307d081 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel specific MCE features. * Copyright 2004 Zwane Mwaikambo diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c index 2a0717bf8033..5cddf831720f 100644 --- a/arch/x86/kernel/cpu/mcheck/p5.c +++ b/arch/x86/kernel/cpu/mcheck/p5.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * P5 specific Machine Check Exception Reporting * (C) Copyright 2002 Alan Cox diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index f7370abd33c6..2da67b70ba98 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -390,26 +390,12 @@ static void unexpected_thermal_interrupt(void) static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt; -static inline void __smp_thermal_interrupt(void) -{ - inc_irq_stat(irq_thermal_count); - smp_thermal_vector(); -} - -asmlinkage __visible void __irq_entry -smp_thermal_interrupt(struct pt_regs *regs) -{ - entering_irq(); - __smp_thermal_interrupt(); - exiting_ack_irq(); -} - -asmlinkage __visible void __irq_entry -smp_trace_thermal_interrupt(struct pt_regs *regs) +asmlinkage __visible void __irq_entry smp_thermal_interrupt(struct pt_regs *r) { entering_irq(); trace_thermal_apic_entry(THERMAL_APIC_VECTOR); - __smp_thermal_interrupt(); + inc_irq_stat(irq_thermal_count); + smp_thermal_vector(); trace_thermal_apic_exit(THERMAL_APIC_VECTOR); exiting_ack_irq(); } diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c index bb0e75eed10a..2b584b319eff 100644 --- a/arch/x86/kernel/cpu/mcheck/threshold.c +++ b/arch/x86/kernel/cpu/mcheck/threshold.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Common corrected MCE threshold handler code: */ @@ -17,24 +18,12 @@ static void default_threshold_interrupt(void) void (*mce_threshold_vector)(void) = default_threshold_interrupt; -static inline void __smp_threshold_interrupt(void) -{ - inc_irq_stat(irq_threshold_count); - mce_threshold_vector(); -} - asmlinkage __visible void __irq_entry smp_threshold_interrupt(void) -{ - entering_irq(); - __smp_threshold_interrupt(); - exiting_ack_irq(); -} - -asmlinkage __visible void __irq_entry smp_trace_threshold_interrupt(void) { entering_irq(); trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); - __smp_threshold_interrupt(); + inc_irq_stat(irq_threshold_count); + mce_threshold_vector(); trace_threshold_apic_exit(THRESHOLD_APIC_VECTOR); exiting_ack_irq(); } diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c index c6a722e1d011..3b45b270a865 100644 --- a/arch/x86/kernel/cpu/mcheck/winchip.c +++ b/arch/x86/kernel/cpu/mcheck/winchip.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IDT Winchip specific Machine Check Exception Reporting * (C) Copyright 2002 Alan Cox diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index 21b185793c80..c6daec4bdba5 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -400,9 +400,12 @@ static void update_cache(struct ucode_patch *new_patch) list_for_each_entry(p, µcode_cache, plist) { if (p->equiv_cpu == new_patch->equiv_cpu) { - if (p->patch_id >= new_patch->patch_id) + if (p->patch_id >= new_patch->patch_id) { /* we already have the latest patch */ + kfree(new_patch->data); + kfree(new_patch); return; + } list_replace(&p->plist, &new_patch->plist); kfree(p->data); diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index 86e8f0b2537b..c4fa4a85d4cb 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -122,9 +122,6 @@ static bool __init check_loader_disabled_bsp(void) bool *res = &dis_ucode_ldr; #endif - if (!have_cpuid_p()) - return *res; - /* * CPUID(1).ECX[31]: reserved for hypervisor use. This is still not * completely accurate as xen pv guests don't see that CPUID bit set but @@ -166,24 +163,36 @@ bool get_builtin_firmware(struct cpio_data *cd, const char *name) void __init load_ucode_bsp(void) { unsigned int cpuid_1_eax; + bool intel = true; - if (check_loader_disabled_bsp()) + if (!have_cpuid_p()) return; cpuid_1_eax = native_cpuid_eax(1); switch (x86_cpuid_vendor()) { case X86_VENDOR_INTEL: - if (x86_family(cpuid_1_eax) >= 6) - load_ucode_intel_bsp(); + if (x86_family(cpuid_1_eax) < 6) + return; break; + case X86_VENDOR_AMD: - if (x86_family(cpuid_1_eax) >= 0x10) - load_ucode_amd_bsp(cpuid_1_eax); + if (x86_family(cpuid_1_eax) < 0x10) + return; + intel = false; break; + default: - break; + return; } + + if (check_loader_disabled_bsp()) + return; + + if (intel) + load_ucode_intel_bsp(); + else + load_ucode_amd_bsp(cpuid_1_eax); } static bool check_loader_disabled_ap(void) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index 59edbe9d4ccb..7dbcb7adf797 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -146,18 +147,18 @@ static bool microcode_matches(struct microcode_header_intel *mc_header, return false; } -static struct ucode_patch *__alloc_microcode_buf(void *data, unsigned int size) +static struct ucode_patch *memdup_patch(void *data, unsigned int size) { struct ucode_patch *p; p = kzalloc(sizeof(struct ucode_patch), GFP_KERNEL); if (!p) - return ERR_PTR(-ENOMEM); + return NULL; p->data = kmemdup(data, size, GFP_KERNEL); if (!p->data) { kfree(p); - return ERR_PTR(-ENOMEM); + return NULL; } return p; @@ -183,8 +184,8 @@ static void save_microcode_patch(void *data, unsigned int size) if (mc_hdr->rev <= mc_saved_hdr->rev) continue; - p = __alloc_microcode_buf(data, size); - if (IS_ERR(p)) + p = memdup_patch(data, size); + if (!p) pr_err("Error allocating buffer %p\n", data); else list_replace(&iter->plist, &p->plist); @@ -196,24 +197,25 @@ static void save_microcode_patch(void *data, unsigned int size) * newly found. */ if (!prev_found) { - p = __alloc_microcode_buf(data, size); - if (IS_ERR(p)) + p = memdup_patch(data, size); + if (!p) pr_err("Error allocating buffer for %p\n", data); else list_add_tail(&p->plist, µcode_cache); } + if (!p) + return; + /* * Save for early loading. On 32-bit, that needs to be a physical * address as the APs are running from physical addresses, before * paging has been enabled. */ - if (p) { - if (IS_ENABLED(CONFIG_X86_32)) - intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); - else - intel_ucode_patch = p->data; - } + if (IS_ENABLED(CONFIG_X86_32)) + intel_ucode_patch = (struct microcode_intel *)__pa_nodebug(p->data); + else + intel_ucode_patch = p->data; } static int microcode_sanity_check(void *mc, int print_err) @@ -917,6 +919,18 @@ static int get_ucode_fw(void *to, const void *from, size_t n) return 0; } +static bool is_blacklisted(unsigned int cpu) +{ + struct cpuinfo_x86 *c = &cpu_data(cpu); + + if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) { + pr_err_once("late loading on model 79 is disabled.\n"); + return true; + } + + return false; +} + static enum ucode_state request_microcode_fw(int cpu, struct device *device, bool refresh_fw) { @@ -925,6 +939,9 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device, const struct firmware *firmware; enum ucode_state ret; + if (is_blacklisted(cpu)) + return UCODE_NFOUND; + sprintf(name, "intel-ucode/%02x-%02x-%02x", c->x86, c->x86_model, c->x86_mask); @@ -949,6 +966,9 @@ static int get_ucode_user(void *to, const void *from, size_t n) static enum ucode_state request_microcode_user(int cpu, const void __user *buf, size_t size) { + if (is_blacklisted(cpu)) + return UCODE_NFOUND; + return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); } diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh index 6988c74409a8..d0dfb892c72f 100644 --- a/arch/x86/kernel/cpu/mkcapflags.sh +++ b/arch/x86/kernel/cpu/mkcapflags.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # # Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h # diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 70e717fccdd6..236324e83a3a 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -59,13 +59,6 @@ void hyperv_vector_handler(struct pt_regs *regs) void hv_setup_vmbus_irq(void (*handler)(void)) { vmbus_handler = handler; - /* - * Setup the IDT for hypervisor callback. Prevent reallocation - * at module reload. - */ - if (!test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) - alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, - hyperv_callback_vector); } void hv_remove_vmbus_irq(void) @@ -184,9 +177,15 @@ static void __init ms_hyperv_init_platform(void) ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES); ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO); - pr_info("HyperV: features 0x%x, hints 0x%x\n", + pr_info("Hyper-V: features 0x%x, hints 0x%x\n", ms_hyperv.features, ms_hyperv.hints); + ms_hyperv.max_vp_index = cpuid_eax(HVCPUID_IMPLEMENTATION_LIMITS); + ms_hyperv.max_lp_index = cpuid_ebx(HVCPUID_IMPLEMENTATION_LIMITS); + + pr_debug("Hyper-V: max %u virtual processors, %u logical processors\n", + ms_hyperv.max_vp_index, ms_hyperv.max_lp_index); + /* * Extract host information. */ @@ -219,7 +218,7 @@ static void __init ms_hyperv_init_platform(void) rdmsrl(HV_X64_MSR_APIC_FREQUENCY, hv_lapic_frequency); hv_lapic_frequency = div_u64(hv_lapic_frequency, HZ); lapic_timer_frequency = hv_lapic_frequency; - pr_info("HyperV: LAPIC Timer Frequency: %#x\n", + pr_info("Hyper-V: LAPIC Timer Frequency: %#x\n", lapic_timer_frequency); } @@ -249,11 +248,14 @@ static void __init ms_hyperv_init_platform(void) * Setup the hook to get control post apic initialization. */ x86_platform.apic_post_init = hyperv_init; + hyperv_setup_mmu_ops(); + /* Setup the IDT for hypervisor callback */ + alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); #endif } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { - .name = "Microsoft HyperV", + .name = "Microsoft Hyper-V", .detect = ms_hyperv_platform, .init_platform = ms_hyperv_init_platform, }; diff --git a/arch/x86/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c index 92ba9cd31c9a..a65a0272096d 100644 --- a/arch/x86/kernel/cpu/mtrr/amd.c +++ b/arch/x86/kernel/cpu/mtrr/amd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/centaur.c index 3d689937fc1b..f27177816569 100644 --- a/arch/x86/kernel/cpu/mtrr/centaur.c +++ b/arch/x86/kernel/cpu/mtrr/centaur.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c index b1086f79e57e..4296c702a3f7 100644 --- a/arch/x86/kernel/cpu/mtrr/cyrix.c +++ b/arch/x86/kernel/cpu/mtrr/cyrix.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c index 6d9b45549109..558444b23923 100644 --- a/arch/x86/kernel/cpu/mtrr/if.c +++ b/arch/x86/kernel/cpu/mtrr/if.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h index ad8bd763efa5..2ac99e561181 100644 --- a/arch/x86/kernel/cpu/mtrr/mtrr.h +++ b/arch/x86/kernel/cpu/mtrr/mtrr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * local MTRR defines. */ diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index 181eabecae25..d389083330c5 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * local apic based NMI watchdog for various CPUs. * diff --git a/arch/x86/kernel/cpu/powerflags.c b/arch/x86/kernel/cpu/powerflags.c index 1dd8294fd730..fd6ec2aa0303 100644 --- a/arch/x86/kernel/cpu/powerflags.c +++ b/arch/x86/kernel/cpu/powerflags.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Strings for the various x86 power flags * diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c index 218f79825b3c..6b7e17bf0b71 100644 --- a/arch/x86/kernel/cpu/proc.c +++ b/arch/x86/kernel/cpu/proc.c @@ -1,7 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include #include +#include /* * Get CPU information for use by the procfs. @@ -75,9 +77,14 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (c->microcode) seq_printf(m, "microcode\t: 0x%x\n", c->microcode); - if (cpu_has(c, X86_FEATURE_TSC)) + if (cpu_has(c, X86_FEATURE_TSC)) { + unsigned int freq = cpufreq_quick_get(cpu); + + if (!freq) + freq = cpu_khz; seq_printf(m, "cpu MHz\t\t: %u.%03u\n", - cpu_khz / 1000, (cpu_khz % 1000)); + freq / 1000, (freq % 1000)); + } /* Cache size */ if (c->x86_cache_size >= 0) diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 23c23508c012..05459ad3db46 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -31,6 +31,7 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_HW_PSTATE, CPUID_EDX, 7, 0x80000007, 0 }, { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 }, { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, + { X86_FEATURE_SME, CPUID_EAX, 0, 0x8000001f, 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index cd531355e838..b099024d339c 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Check for extended topology enumeration cpuid leaf 0xb and if it * exists, use it for populating initial_apicid and cpu topology diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c index d77d07ab310b..42c939827621 100644 --- a/arch/x86/kernel/cpu/transmeta.c +++ b/arch/x86/kernel/cpu/transmeta.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/cpu/umc.c b/arch/x86/kernel/cpu/umc.c index ef9c2a0078bd..65a58a390fc3 100644 --- a/arch/x86/kernel/cpu/umc.c +++ b/arch/x86/kernel/cpu/umc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "cpu.h" diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c index 538fedea9b3f..33ee47670b99 100644 --- a/arch/x86/kernel/crash_dump_32.c +++ b/arch/x86/kernel/crash_dump_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Memory preserving reboot related code. * diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c index afa64adb75ee..4f2e0778feac 100644 --- a/arch/x86/kernel/crash_dump_64.c +++ b/arch/x86/kernel/crash_dump_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Memory preserving reboot related code. * diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index cbf1f6ba39a8..76e07698e6d1 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Architecture specific OF callbacks. */ diff --git a/arch/x86/kernel/doublefault.c b/arch/x86/kernel/doublefault.c index f9c324e08d85..0e662c55ae90 100644 --- a/arch/x86/kernel/doublefault.c +++ b/arch/x86/kernel/doublefault.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index dbce3cca94cb..f13b4c00a5de 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -94,6 +94,9 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, if (stack_name) printk("%s <%s>\n", log_lvl, stack_name); + if (regs && on_stack(&stack_info, regs, sizeof(*regs))) + __show_regs(regs, 0); + /* * Scan the stack, printing any text addresses we find. At the * same time, follow proper stack frames with the unwinder. @@ -118,10 +121,8 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, * Don't print regs->ip again if it was already printed * by __show_regs() below. */ - if (regs && stack == ®s->ip) { - unwind_next_frame(&state); - continue; - } + if (regs && stack == ®s->ip) + goto next; if (stack == ret_addr_p) reliable = 1; @@ -144,6 +145,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, if (!reliable) continue; +next: /* * Get the next frame from the unwinder. No need to * check for an error: if anything goes wrong, the rest @@ -153,7 +155,7 @@ void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, /* if the frame has entry regs, print them */ regs = unwind_get_entry_regs(&state); - if (regs) + if (regs && on_stack(&stack_info, regs, sizeof(*regs))) __show_regs(regs, 0); } @@ -265,7 +267,7 @@ int __die(const char *str, struct pt_regs *regs, long err) #ifdef CONFIG_X86_32 if (user_mode(regs)) { sp = regs->sp; - ss = regs->ss & 0xffff; + ss = regs->ss; } else { sp = kernel_stack_pointer(regs); savesegment(ss, ss); diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index e5f0b40e66d2..daefae83a3aa 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs @@ -37,7 +38,7 @@ static bool in_hardirq_stack(unsigned long *stack, struct stack_info *info) * This is a software stack, so 'end' can be a valid stack pointer. * It just means the stack is empty. */ - if (stack < begin || stack > end) + if (stack <= begin || stack > end) return false; info->type = STACK_TYPE_IRQ; @@ -62,7 +63,7 @@ static bool in_softirq_stack(unsigned long *stack, struct stack_info *info) * This is a software stack, so 'end' can be a valid stack pointer. * It just means the stack is empty. */ - if (stack < begin || stack > end) + if (stack <= begin || stack > end) return false; info->type = STACK_TYPE_SOFTIRQ; diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 3e1471d57487..88ce2ffdb110 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs @@ -55,7 +56,7 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info) begin = end - (exception_stack_sizes[k] / sizeof(long)); regs = (struct pt_regs *)end - 1; - if (stack < begin || stack >= end) + if (stack <= begin || stack >= end) continue; info->type = STACK_TYPE_EXCEPTION + k; @@ -78,7 +79,7 @@ static bool in_irq_stack(unsigned long *stack, struct stack_info *info) * This is a software stack, so 'end' can be a valid stack pointer. * It just means the stack is empty. */ - if (stack < begin || stack > end) + if (stack <= begin || stack > end) return false; info->type = STACK_TYPE_IRQ; diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 532da61d605c..71c11ad5643e 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -96,7 +96,8 @@ EXPORT_SYMBOL_GPL(e820__mapped_any); * Note: this function only works correctly once the E820 table is sorted and * not-overlapping (at least for the range specified), which is the case normally. */ -bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type) +static struct e820_entry *__e820__mapped_all(u64 start, u64 end, + enum e820_type type) { int i; @@ -122,9 +123,28 @@ bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type) * coverage of the desired range exists: */ if (start >= end) - return 1; + return entry; } - return 0; + + return NULL; +} + +/* + * This function checks if the entire range is mapped with type. + */ +bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type) +{ + return __e820__mapped_all(start, end, type); +} + +/* + * This function returns the type associated with the range . + */ +int e820__get_entry_type(u64 start, u64 end) +{ + struct e820_entry *entry = __e820__mapped_all(start, end, 0); + + return entry ? entry->type : -EINVAL; } /* diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index d907c3d8633f..1e82f787c160 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Various workarounds for chipset bugs. This code runs very early and can't use the regular PCI subsystem The entries are keyed to PCI bridges which usually identify chipsets @@ -12,10 +13,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -527,6 +528,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_BXT_IDS(&gen9_early_ops), INTEL_KBL_IDS(&gen9_early_ops), INTEL_GLK_IDS(&gen9_early_ops), + INTEL_CNL_IDS(&gen9_early_ops), }; static void __init @@ -593,7 +595,7 @@ static void __init apple_airport_reset(int bus, int slot, int func) u64 addr; int i; - if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc.")) + if (!x86_apple_machine) return; /* Card may have been put into PCI_D3hot by grub quirk */ diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 0f0840304452..5e801c8c8ce7 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/ebda.c b/arch/x86/kernel/ebda.c index 4312f8ae71b7..38e7d597b660 100644 --- a/arch/x86/kernel/ebda.c +++ b/arch/x86/kernel/ebda.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/eisa.c b/arch/x86/kernel/eisa.c new file mode 100644 index 000000000000..f260e452e4f8 --- /dev/null +++ b/arch/x86/kernel/eisa.c @@ -0,0 +1,19 @@ +/* + * EISA specific code + * + * This file is licensed under the GPL V2 + */ +#include +#include +#include + +static __init int eisa_bus_probe(void) +{ + void __iomem *p = ioremap(0x0FFFD9, 4); + + if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24)) + EISA_bus = 1; + iounmap(p); + return 0; +} +subsys_initcall(eisa_bus_probe); diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c index 6b91e2eb8d3f..9c4e7ba6870c 100644 --- a/arch/x86/kernel/espfix_64.c +++ b/arch/x86/kernel/espfix_64.c @@ -195,7 +195,7 @@ void init_espfix_ap(int cpu) pte_p = pte_offset_kernel(&pmd, addr); stack_page = page_address(alloc_pages_node(node, GFP_KERNEL, 0)); - pte = __pte(__pa(stack_page) | (__PAGE_KERNEL_RO & ptemask)); + pte = __pte(__pa(stack_page) | ((__PAGE_KERNEL_RO | _PAGE_ENC) & ptemask)); for (n = 0; n < ESPFIX_PTE_CLONES; n++) set_pte(&pte_p[n*PTE_STRIDE], pte); diff --git a/arch/x86/kernel/fpu/bugs.c b/arch/x86/kernel/fpu/bugs.c index d913047f832c..2954fab15e51 100644 --- a/arch/x86/kernel/fpu/bugs.c +++ b/arch/x86/kernel/fpu/bugs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * x86 FPU bug checks: */ diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index e1114f070c2d..f92a6593de1e 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -100,7 +100,7 @@ void __kernel_fpu_begin(void) kernel_fpu_disable(); - if (fpu->fpregs_active) { + if (fpu->initialized) { /* * Ignore return value -- we don't care if reg state * is clobbered. @@ -116,7 +116,7 @@ void __kernel_fpu_end(void) { struct fpu *fpu = ¤t->thread.fpu; - if (fpu->fpregs_active) + if (fpu->initialized) copy_kernel_to_fpregs(&fpu->state); kernel_fpu_enable(); @@ -148,7 +148,7 @@ void fpu__save(struct fpu *fpu) preempt_disable(); trace_x86_fpu_before_save(fpu); - if (fpu->fpregs_active) { + if (fpu->initialized) { if (!copy_fpregs_to_fpstate(fpu)) { copy_kernel_to_fpregs(&fpu->state); } @@ -189,10 +189,9 @@ EXPORT_SYMBOL_GPL(fpstate_init); int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) { - dst_fpu->fpregs_active = 0; dst_fpu->last_cpu = -1; - if (!src_fpu->fpstate_active || !static_cpu_has(X86_FEATURE_FPU)) + if (!src_fpu->initialized || !static_cpu_has(X86_FEATURE_FPU)) return 0; WARN_ON_FPU(src_fpu != ¤t->thread.fpu); @@ -206,26 +205,14 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) /* * Save current FPU registers directly into the child * FPU context, without any memory-to-memory copying. - * In lazy mode, if the FPU context isn't loaded into - * fpregs, CR0.TS will be set and do_device_not_available - * will load the FPU context. * - * We have to do all this with preemption disabled, - * mostly because of the FNSAVE case, because in that - * case we must not allow preemption in the window - * between the FNSAVE and us marking the context lazy. - * - * It shouldn't be an issue as even FNSAVE is plenty - * fast in terms of critical section length. + * ( The function 'fails' in the FNSAVE case, which destroys + * register contents so we have to copy them back. ) */ - preempt_disable(); if (!copy_fpregs_to_fpstate(dst_fpu)) { - memcpy(&src_fpu->state, &dst_fpu->state, - fpu_kernel_xstate_size); - + memcpy(&src_fpu->state, &dst_fpu->state, fpu_kernel_xstate_size); copy_kernel_to_fpregs(&src_fpu->state); } - preempt_enable(); trace_x86_fpu_copy_src(src_fpu); trace_x86_fpu_copy_dst(dst_fpu); @@ -237,45 +224,48 @@ int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu) * Activate the current task's in-memory FPU context, * if it has not been used before: */ -void fpu__activate_curr(struct fpu *fpu) +void fpu__initialize(struct fpu *fpu) { WARN_ON_FPU(fpu != ¤t->thread.fpu); - if (!fpu->fpstate_active) { + if (!fpu->initialized) { fpstate_init(&fpu->state); trace_x86_fpu_init_state(fpu); trace_x86_fpu_activate_state(fpu); /* Safe to do for the current task: */ - fpu->fpstate_active = 1; + fpu->initialized = 1; } } -EXPORT_SYMBOL_GPL(fpu__activate_curr); +EXPORT_SYMBOL_GPL(fpu__initialize); /* * This function must be called before we read a task's fpstate. * - * If the task has not used the FPU before then initialize its - * fpstate. + * There's two cases where this gets called: + * + * - for the current task (when coredumping), in which case we have + * to save the latest FPU registers into the fpstate, + * + * - or it's called for stopped tasks (ptrace), in which case the + * registers were already saved by the context-switch code when + * the task scheduled out - we only have to initialize the registers + * if they've never been initialized. * * If the task has used the FPU before then save it. */ -void fpu__activate_fpstate_read(struct fpu *fpu) +void fpu__prepare_read(struct fpu *fpu) { - /* - * If fpregs are active (in the current CPU), then - * copy them to the fpstate: - */ - if (fpu->fpregs_active) { + if (fpu == ¤t->thread.fpu) { fpu__save(fpu); } else { - if (!fpu->fpstate_active) { + if (!fpu->initialized) { fpstate_init(&fpu->state); trace_x86_fpu_init_state(fpu); trace_x86_fpu_activate_state(fpu); /* Safe to do for current and for stopped child tasks: */ - fpu->fpstate_active = 1; + fpu->initialized = 1; } } } @@ -283,17 +273,17 @@ void fpu__activate_fpstate_read(struct fpu *fpu) /* * This function must be called before we write a task's fpstate. * - * If the task has used the FPU before then unlazy it. + * If the task has used the FPU before then invalidate any cached FPU registers. * If the task has not used the FPU before then initialize its fpstate. * * After this function call, after registers in the fpstate are * modified and the child task has woken up, the child task will * restore the modified FPU state from the modified context. If we - * didn't clear its lazy status here then the lazy in-registers + * didn't clear its cached status here then the cached in-registers * state pending on its former CPU could be restored, corrupting * the modifications. */ -void fpu__activate_fpstate_write(struct fpu *fpu) +void fpu__prepare_write(struct fpu *fpu) { /* * Only stopped child tasks can be used to modify the FPU @@ -301,8 +291,8 @@ void fpu__activate_fpstate_write(struct fpu *fpu) */ WARN_ON_FPU(fpu == ¤t->thread.fpu); - if (fpu->fpstate_active) { - /* Invalidate any lazy state: */ + if (fpu->initialized) { + /* Invalidate any cached state: */ __fpu_invalidate_fpregs_state(fpu); } else { fpstate_init(&fpu->state); @@ -310,73 +300,10 @@ void fpu__activate_fpstate_write(struct fpu *fpu) trace_x86_fpu_activate_state(fpu); /* Safe to do for stopped child tasks: */ - fpu->fpstate_active = 1; + fpu->initialized = 1; } } -/* - * This function must be called before we write the current - * task's fpstate. - * - * This call gets the current FPU register state and moves - * it in to the 'fpstate'. Preemption is disabled so that - * no writes to the 'fpstate' can occur from context - * swiches. - * - * Must be followed by a fpu__current_fpstate_write_end(). - */ -void fpu__current_fpstate_write_begin(void) -{ - struct fpu *fpu = ¤t->thread.fpu; - - /* - * Ensure that the context-switching code does not write - * over the fpstate while we are doing our update. - */ - preempt_disable(); - - /* - * Move the fpregs in to the fpu's 'fpstate'. - */ - fpu__activate_fpstate_read(fpu); - - /* - * The caller is about to write to 'fpu'. Ensure that no - * CPU thinks that its fpregs match the fpstate. This - * ensures we will not be lazy and skip a XRSTOR in the - * future. - */ - __fpu_invalidate_fpregs_state(fpu); -} - -/* - * This function must be paired with fpu__current_fpstate_write_begin() - * - * This will ensure that the modified fpstate gets placed back in - * the fpregs if necessary. - * - * Note: This function may be called whether or not an _actual_ - * write to the fpstate occurred. - */ -void fpu__current_fpstate_write_end(void) -{ - struct fpu *fpu = ¤t->thread.fpu; - - /* - * 'fpu' now has an updated copy of the state, but the - * registers may still be out of date. Update them with - * an XRSTOR if they are active. - */ - if (fpregs_active()) - copy_kernel_to_fpregs(&fpu->state); - - /* - * Our update is done and the fpregs/fpstate are in sync - * if necessary. Context switches can happen again. - */ - preempt_enable(); -} - /* * 'fpu__restore()' is called to copy FPU registers from * the FPU fpstate to the live hw registers and to activate @@ -389,7 +316,7 @@ void fpu__current_fpstate_write_end(void) */ void fpu__restore(struct fpu *fpu) { - fpu__activate_curr(fpu); + fpu__initialize(fpu); /* Avoid __kernel_fpu_begin() right after fpregs_activate() */ kernel_fpu_disable(); @@ -414,15 +341,17 @@ void fpu__drop(struct fpu *fpu) { preempt_disable(); - if (fpu->fpregs_active) { - /* Ignore delayed exceptions from user space */ - asm volatile("1: fwait\n" - "2:\n" - _ASM_EXTABLE(1b, 2b)); - fpregs_deactivate(fpu); + if (fpu == ¤t->thread.fpu) { + if (fpu->initialized) { + /* Ignore delayed exceptions from user space */ + asm volatile("1: fwait\n" + "2:\n" + _ASM_EXTABLE(1b, 2b)); + fpregs_deactivate(fpu); + } } - fpu->fpstate_active = 0; + fpu->initialized = 0; trace_x86_fpu_dropped(fpu); @@ -462,9 +391,11 @@ void fpu__clear(struct fpu *fpu) * Make sure fpstate is cleared and initialized. */ if (static_cpu_has(X86_FEATURE_FPU)) { - fpu__activate_curr(fpu); + preempt_disable(); + fpu__initialize(fpu); user_fpu_begin(); copy_init_fpstate_to_fpregs(); + preempt_enable(); } } diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index d5d44c452624..7affb7e3d9a5 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -240,7 +240,7 @@ static void __init fpu__init_system_ctx_switch(void) WARN_ON_FPU(!on_boot_cpu); on_boot_cpu = 0; - WARN_ON_FPU(current->thread.fpu.fpstate_active); + WARN_ON_FPU(current->thread.fpu.initialized); } /* diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index b188b16841e3..bc02f5144b95 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * FPU register's regset abstraction, for ptrace, core dumps, etc. */ @@ -16,14 +17,14 @@ int regset_fpregs_active(struct task_struct *target, const struct user_regset *r { struct fpu *target_fpu = &target->thread.fpu; - return target_fpu->fpstate_active ? regset->n : 0; + return target_fpu->initialized ? regset->n : 0; } int regset_xregset_fpregs_active(struct task_struct *target, const struct user_regset *regset) { struct fpu *target_fpu = &target->thread.fpu; - if (boot_cpu_has(X86_FEATURE_FXSR) && target_fpu->fpstate_active) + if (boot_cpu_has(X86_FEATURE_FXSR) && target_fpu->initialized) return regset->n; else return 0; @@ -38,7 +39,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, if (!boot_cpu_has(X86_FEATURE_FXSR)) return -ENODEV; - fpu__activate_fpstate_read(fpu); + fpu__prepare_read(fpu); fpstate_sanitize_xstate(fpu); return user_regset_copyout(&pos, &count, &kbuf, &ubuf, @@ -55,7 +56,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, if (!boot_cpu_has(X86_FEATURE_FXSR)) return -ENODEV; - fpu__activate_fpstate_write(fpu); + fpu__prepare_write(fpu); fpstate_sanitize_xstate(fpu); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, @@ -89,10 +90,13 @@ int xstateregs_get(struct task_struct *target, const struct user_regset *regset, xsave = &fpu->state.xsave; - fpu__activate_fpstate_read(fpu); + fpu__prepare_read(fpu); if (using_compacted_format()) { - ret = copyout_from_xsaves(pos, count, kbuf, ubuf, xsave); + if (kbuf) + ret = copy_xstate_to_kernel(kbuf, xsave, pos, count); + else + ret = copy_xstate_to_user(ubuf, xsave, pos, count); } else { fpstate_sanitize_xstate(fpu); /* @@ -129,12 +133,23 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, xsave = &fpu->state.xsave; - fpu__activate_fpstate_write(fpu); + fpu__prepare_write(fpu); - if (boot_cpu_has(X86_FEATURE_XSAVES)) - ret = copyin_to_xsaves(kbuf, ubuf, xsave); - else + if (using_compacted_format()) { + if (kbuf) + ret = copy_kernel_to_xstate(xsave, kbuf); + else + ret = copy_user_to_xstate(xsave, ubuf); + } else { ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1); + if (!ret) + ret = validate_xstate_header(&xsave->header); + } + + /* + * mxcsr reserved bits must be masked to zero for security reasons. + */ + xsave->i387.mxcsr &= mxcsr_feature_mask; /* * In case of failure, mark all states as init: @@ -142,16 +157,6 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, if (ret) fpstate_init(&fpu->state); - /* - * mxcsr reserved bits must be masked to zero for security reasons. - */ - xsave->i387.mxcsr &= mxcsr_feature_mask; - xsave->header.xfeatures &= xfeatures_mask; - /* - * These bits must be zero. - */ - memset(&xsave->header.reserved, 0, 48); - return ret; } @@ -299,7 +304,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, struct fpu *fpu = &target->thread.fpu; struct user_i387_ia32_struct env; - fpu__activate_fpstate_read(fpu); + fpu__prepare_read(fpu); if (!boot_cpu_has(X86_FEATURE_FPU)) return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); @@ -329,7 +334,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, struct user_i387_ia32_struct env; int ret; - fpu__activate_fpstate_write(fpu); + fpu__prepare_write(fpu); fpstate_sanitize_xstate(fpu); if (!boot_cpu_has(X86_FEATURE_FPU)) @@ -369,7 +374,7 @@ int dump_fpu(struct pt_regs *regs, struct user_i387_struct *ufpu) struct fpu *fpu = &tsk->thread.fpu; int fpvalid; - fpvalid = fpu->fpstate_active; + fpvalid = fpu->initialized; if (fpvalid) fpvalid = !fpregs_get(tsk, NULL, 0, sizeof(struct user_i387_ia32_struct), diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index 83c23c230b4c..23f1691670b6 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * FPU signal frame handling routines. */ @@ -155,7 +156,8 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf) */ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) { - struct xregs_state *xsave = ¤t->thread.fpu.state.xsave; + struct fpu *fpu = ¤t->thread.fpu; + struct xregs_state *xsave = &fpu->state.xsave; struct task_struct *tsk = current; int ia32_fxstate = (buf != buf_fx); @@ -170,13 +172,13 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) sizeof(struct user_i387_ia32_struct), NULL, (struct _fpstate_32 __user *) buf) ? -1 : 1; - if (fpregs_active() || using_compacted_format()) { + if (fpu->initialized || using_compacted_format()) { /* Save the live register state to the user directly. */ if (copy_fpregs_to_sigframe(buf_fx)) return -1; /* Update the thread's fxstate to save the fsave header. */ if (ia32_fxstate) - copy_fxregs_to_kernel(&tsk->thread.fpu); + copy_fxregs_to_kernel(fpu); } else { /* * It is a *bug* if kernel uses compacted-format for xsave @@ -189,7 +191,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size) return -1; } - fpstate_sanitize_xstate(&tsk->thread.fpu); + fpstate_sanitize_xstate(fpu); if (__copy_to_user(buf_fx, xsave, fpu_user_xstate_size)) return -1; } @@ -213,8 +215,11 @@ sanitize_restored_xstate(struct task_struct *tsk, struct xstate_header *header = &xsave->header; if (use_xsave()) { - /* These bits must be zero. */ - memset(header->reserved, 0, 48); + /* + * Note: we don't need to zero the reserved bits in the + * xstate_header here because we either didn't copy them at all, + * or we checked earlier that they aren't set. + */ /* * Init the state that is not present in the memory @@ -223,7 +228,7 @@ sanitize_restored_xstate(struct task_struct *tsk, if (fx_only) header->xfeatures = XFEATURE_MASK_FPSSE; else - header->xfeatures &= (xfeatures_mask & xfeatures); + header->xfeatures &= xfeatures; } if (use_fxsr()) { @@ -279,7 +284,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) if (!access_ok(VERIFY_READ, buf, size)) return -EACCES; - fpu__activate_curr(fpu); + fpu__initialize(fpu); if (!static_cpu_has(X86_FEATURE_FPU)) return fpregs_soft_set(current, NULL, @@ -307,28 +312,29 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) /* * For 32-bit frames with fxstate, copy the user state to the * thread's fpu state, reconstruct fxstate from the fsave - * header. Sanitize the copied state etc. + * header. Validate and sanitize the copied state. */ struct fpu *fpu = &tsk->thread.fpu; struct user_i387_ia32_struct env; int err = 0; /* - * Drop the current fpu which clears fpu->fpstate_active. This ensures + * Drop the current fpu which clears fpu->initialized. This ensures * that any context-switch during the copy of the new state, * avoids the intermediate state from getting restored/saved. * Thus avoiding the new restored state from getting corrupted. * We will be ready to restore/save the state only after - * fpu->fpstate_active is again set. + * fpu->initialized is again set. */ fpu__drop(fpu); if (using_compacted_format()) { - err = copyin_to_xsaves(NULL, buf_fx, - &fpu->state.xsave); + err = copy_user_to_xstate(&fpu->state.xsave, buf_fx); } else { - err = __copy_from_user(&fpu->state.xsave, - buf_fx, state_size); + err = __copy_from_user(&fpu->state.xsave, buf_fx, state_size); + + if (!err && state_size > offsetof(struct xregs_state, header)) + err = validate_xstate_header(&fpu->state.xsave.header); } if (err || __copy_from_user(&env, buf, sizeof(env))) { @@ -339,7 +345,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) sanitize_restored_xstate(tsk, &env, xfeatures, fx_only); } - fpu->fpstate_active = 1; + fpu->initialized = 1; preempt_disable(); fpu__restore(fpu); preempt_enable(); diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index c24ac1efb12d..f1d5476c9022 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -483,6 +483,30 @@ int using_compacted_format(void) return boot_cpu_has(X86_FEATURE_XSAVES); } +/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */ +int validate_xstate_header(const struct xstate_header *hdr) +{ + /* No unknown or supervisor features may be set */ + if (hdr->xfeatures & (~xfeatures_mask | XFEATURE_MASK_SUPERVISOR)) + return -EINVAL; + + /* Userspace must use the uncompacted format */ + if (hdr->xcomp_bv) + return -EINVAL; + + /* + * If 'reserved' is shrunken to add a new field, make sure to validate + * that new field here! + */ + BUILD_BUG_ON(sizeof(hdr->reserved) != 48); + + /* No reserved bits may be set */ + if (memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved))) + return -EINVAL; + + return 0; +} + static void __xstate_dump_leaves(void) { int i; @@ -867,7 +891,7 @@ const void *get_xsave_field_ptr(int xsave_state) { struct fpu *fpu = ¤t->thread.fpu; - if (!fpu->fpstate_active) + if (!fpu->initialized) return NULL; /* * fpu__save() takes the CPU's xstate registers @@ -920,48 +944,55 @@ int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, } #endif /* ! CONFIG_ARCH_HAS_PKEYS */ +/* + * Weird legacy quirk: SSE and YMM states store information in the + * MXCSR and MXCSR_FLAGS fields of the FP area. That means if the FP + * area is marked as unused in the xfeatures header, we need to copy + * MXCSR and MXCSR_FLAGS if either SSE or YMM are in use. + */ +static inline bool xfeatures_mxcsr_quirk(u64 xfeatures) +{ + if (!(xfeatures & (XFEATURE_MASK_SSE|XFEATURE_MASK_YMM))) + return false; + + if (xfeatures & XFEATURE_MASK_FP) + return false; + + return true; +} + /* * This is similar to user_regset_copyout(), but will not add offset to * the source data pointer or increment pos, count, kbuf, and ubuf. */ -static inline int xstate_copyout(unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf, - const void *data, const int start_pos, - const int end_pos) +static inline void +__copy_xstate_to_kernel(void *kbuf, const void *data, + unsigned int offset, unsigned int size, unsigned int size_total) { - if ((count == 0) || (pos < start_pos)) - return 0; + if (offset < size_total) { + unsigned int copy = min(size, size_total - offset); - if (end_pos < 0 || pos < end_pos) { - unsigned int copy = (end_pos < 0 ? count : min(count, end_pos - pos)); - - if (kbuf) { - memcpy(kbuf + pos, data, copy); - } else { - if (__copy_to_user(ubuf + pos, data, copy)) - return -EFAULT; - } + memcpy(kbuf + offset, data, copy); } - return 0; } /* * Convert from kernel XSAVES compacted format to standard format and copy - * to a ptrace buffer. It supports partial copy but pos always starts from - * zero. This is called from xstateregs_get() and there we check the CPU - * has XSAVES. + * to a kernel-space ptrace buffer. + * + * It supports partial copy but pos always starts from zero. This is called + * from xstateregs_get() and there we check the CPU has XSAVES. */ -int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, - void __user *ubuf, struct xregs_state *xsave) +int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) { unsigned int offset, size; - int ret, i; struct xstate_header header; + int i; /* * Currently copy_regset_to_user() starts from pos 0: */ - if (unlikely(pos != 0)) + if (unlikely(offset_start != 0)) return -EFAULT; /* @@ -977,8 +1008,91 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, offset = offsetof(struct xregs_state, header); size = sizeof(header); - ret = xstate_copyout(offset, size, kbuf, ubuf, &header, 0, count); + __copy_xstate_to_kernel(kbuf, &header, offset, size, size_total); + for (i = 0; i < XFEATURE_MAX; i++) { + /* + * Copy only in-use xstates: + */ + if ((header.xfeatures >> i) & 1) { + void *src = __raw_xsave_addr(xsave, 1 << i); + + offset = xstate_offsets[i]; + size = xstate_sizes[i]; + + /* The next component has to fit fully into the output buffer: */ + if (offset + size > size_total) + break; + + __copy_xstate_to_kernel(kbuf, src, offset, size, size_total); + } + + } + + if (xfeatures_mxcsr_quirk(header.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + __copy_xstate_to_kernel(kbuf, &xsave->i387.mxcsr, offset, size, size_total); + } + + /* + * Fill xsave->i387.sw_reserved value for ptrace frame: + */ + offset = offsetof(struct fxregs_state, sw_reserved); + size = sizeof(xstate_fx_sw_bytes); + + __copy_xstate_to_kernel(kbuf, xstate_fx_sw_bytes, offset, size, size_total); + + return 0; +} + +static inline int +__copy_xstate_to_user(void __user *ubuf, const void *data, unsigned int offset, unsigned int size, unsigned int size_total) +{ + if (!size) + return 0; + + if (offset < size_total) { + unsigned int copy = min(size, size_total - offset); + + if (__copy_to_user(ubuf + offset, data, copy)) + return -EFAULT; + } + return 0; +} + +/* + * Convert from kernel XSAVES compacted format to standard format and copy + * to a user-space buffer. It supports partial copy but pos always starts from + * zero. This is called from xstateregs_get() and there we check the CPU + * has XSAVES. + */ +int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) +{ + unsigned int offset, size; + int ret, i; + struct xstate_header header; + + /* + * Currently copy_regset_to_user() starts from pos 0: + */ + if (unlikely(offset_start != 0)) + return -EFAULT; + + /* + * The destination is a ptrace buffer; we put in only user xstates: + */ + memset(&header, 0, sizeof(header)); + header.xfeatures = xsave->header.xfeatures; + header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; + + /* + * Copy xregs_state->header: + */ + offset = offsetof(struct xregs_state, header); + size = sizeof(header); + + ret = __copy_xstate_to_user(ubuf, &header, offset, size, size_total); if (ret) return ret; @@ -992,25 +1106,30 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, offset = xstate_offsets[i]; size = xstate_sizes[i]; - ret = xstate_copyout(offset, size, kbuf, ubuf, src, 0, count); + /* The next component has to fit fully into the output buffer: */ + if (offset + size > size_total) + break; + ret = __copy_xstate_to_user(ubuf, src, offset, size, size_total); if (ret) return ret; - - if (offset + size >= count) - break; } } + if (xfeatures_mxcsr_quirk(header.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + __copy_xstate_to_user(ubuf, &xsave->i387.mxcsr, offset, size, size_total); + } + /* * Fill xsave->i387.sw_reserved value for ptrace frame: */ offset = offsetof(struct fxregs_state, sw_reserved); size = sizeof(xstate_fx_sw_bytes); - ret = xstate_copyout(offset, size, kbuf, ubuf, xstate_fx_sw_bytes, 0, count); - + ret = __copy_xstate_to_user(ubuf, xstate_fx_sw_bytes, offset, size, size_total); if (ret) return ret; @@ -1018,55 +1137,42 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf, } /* - * Convert from a ptrace standard-format buffer to kernel XSAVES format - * and copy to the target thread. This is called from xstateregs_set() and - * there we check the CPU has XSAVES and a whole standard-sized buffer - * exists. + * Convert from a ptrace standard-format kernel buffer to kernel XSAVES format + * and copy to the target thread. This is called from xstateregs_set(). */ -int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, - struct xregs_state *xsave) +int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf) { unsigned int offset, size; int i; - u64 xfeatures; - u64 allowed_features; + struct xstate_header hdr; offset = offsetof(struct xregs_state, header); - size = sizeof(xfeatures); + size = sizeof(hdr); - if (kbuf) { - memcpy(&xfeatures, kbuf + offset, size); - } else { - if (__copy_from_user(&xfeatures, ubuf + offset, size)) - return -EFAULT; - } + memcpy(&hdr, kbuf + offset, size); - /* - * Reject if the user sets any disabled or supervisor features: - */ - allowed_features = xfeatures_mask & ~XFEATURE_MASK_SUPERVISOR; - - if (xfeatures & ~allowed_features) + if (validate_xstate_header(&hdr)) return -EINVAL; for (i = 0; i < XFEATURE_MAX; i++) { u64 mask = ((u64)1 << i); - if (xfeatures & mask) { + if (hdr.xfeatures & mask) { void *dst = __raw_xsave_addr(xsave, 1 << i); offset = xstate_offsets[i]; size = xstate_sizes[i]; - if (kbuf) { - memcpy(dst, kbuf + offset, size); - } else { - if (__copy_from_user(dst, ubuf + offset, size)) - return -EFAULT; - } + memcpy(dst, kbuf + offset, size); } } + if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + memcpy(&xsave->i387.mxcsr, kbuf + offset, size); + } + /* * The state that came in from userspace was user-state only. * Mask all the user states out of 'xfeatures': @@ -1076,7 +1182,63 @@ int copyin_to_xsaves(const void *kbuf, const void __user *ubuf, /* * Add back in the features that came in from userspace: */ - xsave->header.xfeatures |= xfeatures; + xsave->header.xfeatures |= hdr.xfeatures; + + return 0; +} + +/* + * Convert from a ptrace or sigreturn standard-format user-space buffer to + * kernel XSAVES format and copy to the target thread. This is called from + * xstateregs_set(), as well as potentially from the sigreturn() and + * rt_sigreturn() system calls. + */ +int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf) +{ + unsigned int offset, size; + int i; + struct xstate_header hdr; + + offset = offsetof(struct xregs_state, header); + size = sizeof(hdr); + + if (__copy_from_user(&hdr, ubuf + offset, size)) + return -EFAULT; + + if (validate_xstate_header(&hdr)) + return -EINVAL; + + for (i = 0; i < XFEATURE_MAX; i++) { + u64 mask = ((u64)1 << i); + + if (hdr.xfeatures & mask) { + void *dst = __raw_xsave_addr(xsave, 1 << i); + + offset = xstate_offsets[i]; + size = xstate_sizes[i]; + + if (__copy_from_user(dst, ubuf + offset, size)) + return -EFAULT; + } + } + + if (xfeatures_mxcsr_quirk(hdr.xfeatures)) { + offset = offsetof(struct fxregs_state, mxcsr); + size = MXCSR_AND_FLAGS_SIZE; + if (__copy_from_user(&xsave->i387.mxcsr, ubuf + offset, size)) + return -EFAULT; + } + + /* + * The state that came in from userspace was user-state only. + * Mask all the user states out of 'xfeatures': + */ + xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR; + + /* + * Add back in the features that came in from userspace: + */ + xsave->header.xfeatures |= hdr.xfeatures; return 0; } diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 9bef1bbeba63..01ebcb6f263e 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Dynamic function tracing support. * diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S index 722a145b4139..b6c6468e10bc 100644 --- a/arch/x86/kernel/ftrace_32.S +++ b/arch/x86/kernel/ftrace_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2017 Steven Rostedt, VMware Inc. */ diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index 1dfac634bbf7..c832291d948a 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2014 Steven Rostedt, Red Hat Inc */ diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 538ec012b371..ec6fefbfd3c0 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/arch/i386/kernel/head32.c -- prepare to run common code * @@ -10,6 +11,7 @@ #include #include +#include #include #include #include @@ -29,7 +31,11 @@ static void __init i386_default_early_setup(void) asmlinkage __visible void __init i386_start_kernel(void) { + /* Make sure IDT is set up before any exception happens */ + idt_setup_early_handler(); + cr4_init_shadow(); + sanitize_boot_params(&boot_params); x86_early_init_platform_quirks(); diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 9ba79543d9ee..6a5d757b9cfd 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * prepare to run common code * @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -33,7 +35,6 @@ /* * Manage page tables very early on. */ -extern pgd_t early_top_pgt[PTRS_PER_PGD]; extern pmd_t early_dynamic_pgts[EARLY_DYNAMIC_PAGE_TABLES][PTRS_PER_PMD]; static unsigned int __initdata next_early_pgt; pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX); @@ -45,9 +46,11 @@ static void __head *fixup_pointer(void *ptr, unsigned long physaddr) return ptr - (void *)_text + (void *)physaddr; } -void __head __startup_64(unsigned long physaddr) +unsigned long __head __startup_64(unsigned long physaddr, + struct boot_params *bp) { unsigned long load_delta, *p; + unsigned long pgtable_flags; pgdval_t *pgd; p4dval_t *p4d; pudval_t *pud; @@ -69,6 +72,12 @@ void __head __startup_64(unsigned long physaddr) if (load_delta & ~PMD_PAGE_MASK) for (;;); + /* Activate Secure Memory Encryption (SME) if supported and enabled */ + sme_enable(bp); + + /* Include the SME encryption mask in the fixup value */ + load_delta += sme_get_me_mask(); + /* Fixup the physical addresses in the page table */ pgd = fixup_pointer(&early_top_pgt, physaddr); @@ -92,31 +101,35 @@ void __head __startup_64(unsigned long physaddr) * creates a bunch of nonsense entries but that is fine -- * it avoids problems around wraparound. */ + next_pgt_ptr = fixup_pointer(&next_early_pgt, physaddr); pud = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr); pmd = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr); + pgtable_flags = _KERNPG_TABLE_NOENC + sme_get_me_mask(); + if (IS_ENABLED(CONFIG_X86_5LEVEL)) { p4d = fixup_pointer(early_dynamic_pgts[next_early_pgt++], physaddr); i = (physaddr >> PGDIR_SHIFT) % PTRS_PER_PGD; - pgd[i + 0] = (pgdval_t)p4d + _KERNPG_TABLE; - pgd[i + 1] = (pgdval_t)p4d + _KERNPG_TABLE; + pgd[i + 0] = (pgdval_t)p4d + pgtable_flags; + pgd[i + 1] = (pgdval_t)p4d + pgtable_flags; i = (physaddr >> P4D_SHIFT) % PTRS_PER_P4D; - p4d[i + 0] = (pgdval_t)pud + _KERNPG_TABLE; - p4d[i + 1] = (pgdval_t)pud + _KERNPG_TABLE; + p4d[i + 0] = (pgdval_t)pud + pgtable_flags; + p4d[i + 1] = (pgdval_t)pud + pgtable_flags; } else { i = (physaddr >> PGDIR_SHIFT) % PTRS_PER_PGD; - pgd[i + 0] = (pgdval_t)pud + _KERNPG_TABLE; - pgd[i + 1] = (pgdval_t)pud + _KERNPG_TABLE; + pgd[i + 0] = (pgdval_t)pud + pgtable_flags; + pgd[i + 1] = (pgdval_t)pud + pgtable_flags; } i = (physaddr >> PUD_SHIFT) % PTRS_PER_PUD; - pud[i + 0] = (pudval_t)pmd + _KERNPG_TABLE; - pud[i + 1] = (pudval_t)pmd + _KERNPG_TABLE; + pud[i + 0] = (pudval_t)pmd + pgtable_flags; + pud[i + 1] = (pudval_t)pmd + pgtable_flags; pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL; + pmd_entry += sme_get_me_mask(); pmd_entry += physaddr; for (i = 0; i < DIV_ROUND_UP(_end - _text, PMD_SIZE); i++) { @@ -137,9 +150,30 @@ void __head __startup_64(unsigned long physaddr) pmd[i] += load_delta; } - /* Fixup phys_base */ + /* + * Fixup phys_base - remove the memory encryption mask to obtain + * the true physical address. + */ p = fixup_pointer(&phys_base, physaddr); - *p += load_delta; + *p += load_delta - sme_get_me_mask(); + + /* Encrypt the kernel (if SME is active) */ + sme_encrypt_kernel(); + + /* + * Return the SME encryption mask (if SME is active) to be used as a + * modifier for the initial pgdir entry programmed into CR3. + */ + return sme_get_me_mask(); +} + +unsigned long __startup_secondary_64(void) +{ + /* + * Return the SME encryption mask (if SME is active) to be used as a + * modifier for the initial pgdir entry programmed into CR3. + */ + return sme_get_me_mask(); } /* Wipe all early page tables except for the kernel symbol map */ @@ -147,17 +181,17 @@ static void __init reset_early_page_tables(void) { memset(early_top_pgt, 0, sizeof(pgd_t)*(PTRS_PER_PGD-1)); next_early_pgt = 0; - write_cr3(__pa_nodebug(early_top_pgt)); + write_cr3(__sme_pa_nodebug(early_top_pgt)); } /* Create a new PMD entry */ -int __init early_make_pgtable(unsigned long address) +int __init __early_make_pgtable(unsigned long address, pmdval_t pmd) { unsigned long physaddr = address - __PAGE_OFFSET; pgdval_t pgd, *pgd_p; p4dval_t p4d, *p4d_p; pudval_t pud, *pud_p; - pmdval_t pmd, *pmd_p; + pmdval_t *pmd_p; /* Invalid address or early pgt is done ? */ if (physaddr >= MAXMEM || read_cr3_pa() != __pa_nodebug(early_top_pgt)) @@ -216,12 +250,21 @@ again: memset(pmd_p, 0, sizeof(*pmd_p) * PTRS_PER_PMD); *pud_p = (pudval_t)pmd_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE; } - pmd = (physaddr & PMD_MASK) + early_pmd_flags; pmd_p[pmd_index(address)] = pmd; return 0; } +int __init early_make_pgtable(unsigned long address) +{ + unsigned long physaddr = address - __PAGE_OFFSET; + pmdval_t pmd; + + pmd = (physaddr & PMD_MASK) + early_pmd_flags; + + return __early_make_pgtable(address, pmd); +} + /* Don't add a printk in there. printk relies on the PDA which is not initialized yet. */ static void __init clear_bss(void) @@ -244,6 +287,12 @@ static void __init copy_bootdata(char *real_mode_data) char * command_line; unsigned long cmd_line_ptr; + /* + * If SME is active, this will create decrypted mappings of the + * boot data in advance of the copy operations. + */ + sme_map_bootdata(real_mode_data); + memcpy(&boot_params, real_mode_data, sizeof boot_params); sanitize_boot_params(&boot_params); cmd_line_ptr = get_cmd_line_ptr(); @@ -251,12 +300,18 @@ static void __init copy_bootdata(char *real_mode_data) command_line = __va(cmd_line_ptr); memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); } + + /* + * The old boot data is no longer needed and won't be reserved, + * freeing up that memory for use by the system. If SME is active, + * we need to remove the mappings that were created so that the + * memory doesn't remain mapped as decrypted. + */ + sme_unmap_bootdata(real_mode_data); } asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) { - int i; - /* * Build-time sanity checks on the kernel image and module * area mappings. (these are purely build-time and produce no code) @@ -280,11 +335,16 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) clear_page(init_top_pgt); + /* + * SME support may update early_pmd_flags to include the memory + * encryption mask, so it needs to be called before anything + * that may generate a page fault. + */ + sme_early_init(); + kasan_early_init(); - for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) - set_intr_gate(i, early_idt_handler_array[i]); - load_idt((const struct desc_ptr *)&idt_descr); + idt_setup_early_handler(); copy_bootdata(__va(real_mode_data)); diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 1f85ee8f9439..f1d528bb66a6 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Copyright (C) 1991, 1992 Linus Torvalds @@ -155,7 +156,6 @@ ENTRY(startup_32) jmp *%eax .Lbad_subarch: -WEAK(lguest_entry) WEAK(xen_entry) /* Unknown implementation; there's really nothing we can do at this point. */ @@ -165,7 +165,6 @@ WEAK(xen_entry) subarch_entries: .long .Ldefault_entry /* normal x86/PC */ - .long lguest_entry /* lguest hypervisor */ .long xen_entry /* Xen hypervisor */ .long .Ldefault_entry /* Moorestown MID */ num_subarch_entries = (. - subarch_entries) / 4 @@ -347,7 +346,6 @@ ENTRY(startup_32_smp) movl %eax,%cr0 lgdt early_gdt_descr - lidt idt_descr ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers movl %eax,%ss # after changing gdt. @@ -380,37 +378,6 @@ ENDPROC(startup_32_smp) */ __INIT setup_once: - /* - * Set up a idt with 256 interrupt gates that push zero if there - * is no error code and then jump to early_idt_handler_common. - * It doesn't actually load the idt - that needs to be done on - * each CPU. Interrupts are enabled elsewhere, when we can be - * relatively sure everything is ok. - */ - - movl $idt_table,%edi - movl $early_idt_handler_array,%eax - movl $NUM_EXCEPTION_VECTORS,%ecx -1: - movl %eax,(%edi) - movl %eax,4(%edi) - /* interrupt gate, dpl=0, present */ - movl $(0x8E000000 + __KERNEL_CS),2(%edi) - addl $EARLY_IDT_HANDLER_SIZE,%eax - addl $8,%edi - loop 1b - - movl $256 - NUM_EXCEPTION_VECTORS,%ecx - movl $ignore_int,%edx - movl $(__KERNEL_CS << 16),%eax - movw %dx,%ax /* selector = 0x0010 = cs */ - movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ -2: - movl %eax,(%edi) - movl %edx,4(%edi) - addl $8,%edi - loop 2b - #ifdef CONFIG_CC_STACKPROTECTOR /* * Configure the stack canary. The linker can't handle this by @@ -457,12 +424,9 @@ early_idt_handler_common: /* The vector number is in pt_regs->gs */ cld - pushl %fs /* pt_regs->fs */ - movw $0, 2(%esp) /* clear high bits (some CPUs leave garbage) */ - pushl %es /* pt_regs->es */ - movw $0, 2(%esp) /* clear high bits (some CPUs leave garbage) */ - pushl %ds /* pt_regs->ds */ - movw $0, 2(%esp) /* clear high bits (some CPUs leave garbage) */ + pushl %fs /* pt_regs->fs (__fsh varies by model) */ + pushl %es /* pt_regs->es (__esh varies by model) */ + pushl %ds /* pt_regs->ds (__dsh varies by model) */ pushl %eax /* pt_regs->ax */ pushl %ebp /* pt_regs->bp */ pushl %edi /* pt_regs->di */ @@ -479,9 +443,8 @@ early_idt_handler_common: /* Load the vector number into EDX */ movl PT_GS(%esp), %edx - /* Load GS into pt_regs->gs and clear high bits */ + /* Load GS into pt_regs->gs (and maybe clobber __gsh) */ movw %gs, PT_GS(%esp) - movw $0, PT_GS+2(%esp) movl %esp, %eax /* args are pt_regs (EAX), trapnr (EDX) */ call early_fixup_exception @@ -493,18 +456,17 @@ early_idt_handler_common: popl %edi /* pt_regs->di */ popl %ebp /* pt_regs->bp */ popl %eax /* pt_regs->ax */ - popl %ds /* pt_regs->ds */ - popl %es /* pt_regs->es */ - popl %fs /* pt_regs->fs */ - popl %gs /* pt_regs->gs */ + popl %ds /* pt_regs->ds (always ignores __dsh) */ + popl %es /* pt_regs->es (always ignores __esh) */ + popl %fs /* pt_regs->fs (always ignores __fsh) */ + popl %gs /* pt_regs->gs (always ignores __gsh) */ decl %ss:early_recursion_flag addl $4, %esp /* pop pt_regs->orig_ax */ iret ENDPROC(early_idt_handler_common) /* This is the default interrupt "handler" :-) */ - ALIGN -ignore_int: +ENTRY(early_ignore_irq) cld #ifdef CONFIG_PRINTK pushl %eax @@ -539,7 +501,8 @@ ignore_int: hlt_loop: hlt jmp hlt_loop -ENDPROC(ignore_int) +ENDPROC(early_ignore_irq) + __INITDATA .align 4 GLOBAL(early_recursion_flag) @@ -628,7 +591,6 @@ int_msg: .data .globl boot_gdt_descr -.globl idt_descr ALIGN # early boot GDT descriptor (must use 1:1 address mapping) @@ -637,11 +599,6 @@ boot_gdt_descr: .word __BOOT_DS+7 .long boot_gdt - __PAGE_OFFSET - .word 0 # 32-bit align idt_desc.address -idt_descr: - .word IDT_ENTRIES*8-1 # idt contains 256 entries - .long idt_table - # boot GDT descriptor (later on used by CPU#0): .word 0 # 32 bit align gdt_desc.address ENTRY(early_gdt_descr) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 6225550883df..6dde3f3fc1f8 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/arch/x86/kernel/head_64.S -- start in 32bit and switch to 64bit * @@ -73,12 +74,19 @@ startup_64: /* Sanitize CPU configuration */ call verify_cpu + /* + * Perform pagetable fixups. Additionally, if SME is active, encrypt + * the kernel and retrieve the modifier (SME encryption mask if SME + * is active) to be added to the initial pgdir entry that will be + * programmed into CR3. + */ leaq _text(%rip), %rdi pushq %rsi call __startup_64 popq %rsi - movq $(early_top_pgt - __START_KERNEL_map), %rax + /* Form the CR3 value being sure to include the CR3 modifier */ + addq $(early_top_pgt - __START_KERNEL_map), %rax jmp 1f ENTRY(secondary_startup_64) /* @@ -98,7 +106,16 @@ ENTRY(secondary_startup_64) /* Sanitize CPU configuration */ call verify_cpu - movq $(init_top_pgt - __START_KERNEL_map), %rax + /* + * Retrieve the modifier (SME encryption mask if SME is active) to be + * added to the initial pgdir entry that will be programmed into CR3. + */ + pushq %rsi + call __startup_secondary_64 + popq %rsi + + /* Form the CR3 value being sure to include the CR3 modifier */ + addq $(init_top_pgt - __START_KERNEL_map), %rax 1: /* Enable PAE mode, PGE and LA57 */ @@ -335,9 +352,9 @@ GLOBAL(name) NEXT_PAGE(early_top_pgt) .fill 511,8,0 #ifdef CONFIG_X86_5LEVEL - .quad level4_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level4_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC #else - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC #endif NEXT_PAGE(early_dynamic_pgts) @@ -350,15 +367,15 @@ NEXT_PAGE(init_top_pgt) .fill 512,8,0 #else NEXT_PAGE(init_top_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC .org init_top_pgt + PGD_PAGE_OFFSET*8, 0 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC .org init_top_pgt + PGD_START_KERNEL*8, 0 /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC NEXT_PAGE(level3_ident_pgt) - .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC .fill 511, 8, 0 NEXT_PAGE(level2_ident_pgt) /* Since I easily can, map the first 1G. @@ -370,14 +387,14 @@ NEXT_PAGE(level2_ident_pgt) #ifdef CONFIG_X86_5LEVEL NEXT_PAGE(level4_kernel_pgt) .fill 511,8,0 - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC #endif NEXT_PAGE(level3_kernel_pgt) .fill L3_START_KERNEL,8,0 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ - .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE - .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC + .quad level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC NEXT_PAGE(level2_kernel_pgt) /* @@ -395,7 +412,7 @@ NEXT_PAGE(level2_kernel_pgt) NEXT_PAGE(level2_fixmap_pgt) .fill 506,8,0 - .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE + .quad level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */ .fill 5,8,0 diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index 6ebe00cb4a3b..0d307a657abb 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * 8253/PIT functions * diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 4e3b8a587c88..8f5cb2c7060c 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/idt.c b/arch/x86/kernel/idt.c new file mode 100644 index 000000000000..014cb2fc47ff --- /dev/null +++ b/arch/x86/kernel/idt.c @@ -0,0 +1,369 @@ +/* + * Interrupt descriptor table related code + * + * This file is licensed under the GPL V2 + */ +#include + +#include +#include +#include + +struct idt_data { + unsigned int vector; + unsigned int segment; + struct idt_bits bits; + const void *addr; +}; + +#define DPL0 0x0 +#define DPL3 0x3 + +#define DEFAULT_STACK 0 + +#define G(_vector, _addr, _ist, _type, _dpl, _segment) \ + { \ + .vector = _vector, \ + .bits.ist = _ist, \ + .bits.type = _type, \ + .bits.dpl = _dpl, \ + .bits.p = 1, \ + .addr = _addr, \ + .segment = _segment, \ + } + +/* Interrupt gate */ +#define INTG(_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* System interrupt gate */ +#define SYSG(_vector, _addr) \ + G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS) + +/* Interrupt gate with interrupt stack */ +#define ISTG(_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) + +/* System interrupt gate with interrupt stack */ +#define SISTG(_vector, _addr, _ist) \ + G(_vector, _addr, _ist, GATE_INTERRUPT, DPL3, __KERNEL_CS) + +/* Task gate */ +#define TSKG(_vector, _gdt) \ + G(_vector, NULL, DEFAULT_STACK, GATE_TASK, DPL0, _gdt << 3) + +/* + * Early traps running on the DEFAULT_STACK because the other interrupt + * stacks work only after cpu_init(). + */ +static const __initdata struct idt_data early_idts[] = { + INTG(X86_TRAP_DB, debug), + SYSG(X86_TRAP_BP, int3), +#ifdef CONFIG_X86_32 + INTG(X86_TRAP_PF, page_fault), +#endif +}; + +/* + * The default IDT entries which are set up in trap_init() before + * cpu_init() is invoked. Interrupt stacks cannot be used at that point and + * the traps which use them are reinitialized with IST after cpu_init() has + * set up TSS. + */ +static const __initdata struct idt_data def_idts[] = { + INTG(X86_TRAP_DE, divide_error), + INTG(X86_TRAP_NMI, nmi), + INTG(X86_TRAP_BR, bounds), + INTG(X86_TRAP_UD, invalid_op), + INTG(X86_TRAP_NM, device_not_available), + INTG(X86_TRAP_OLD_MF, coprocessor_segment_overrun), + INTG(X86_TRAP_TS, invalid_TSS), + INTG(X86_TRAP_NP, segment_not_present), + INTG(X86_TRAP_SS, stack_segment), + INTG(X86_TRAP_GP, general_protection), + INTG(X86_TRAP_SPURIOUS, spurious_interrupt_bug), + INTG(X86_TRAP_MF, coprocessor_error), + INTG(X86_TRAP_AC, alignment_check), + INTG(X86_TRAP_XF, simd_coprocessor_error), + +#ifdef CONFIG_X86_32 + TSKG(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS), +#else + INTG(X86_TRAP_DF, double_fault), +#endif + INTG(X86_TRAP_DB, debug), + +#ifdef CONFIG_X86_MCE + INTG(X86_TRAP_MC, &machine_check), +#endif + + SYSG(X86_TRAP_OF, overflow), +#if defined(CONFIG_IA32_EMULATION) + SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat), +#elif defined(CONFIG_X86_32) + SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), +#endif +}; + +/* + * The APIC and SMP idt entries + */ +static const __initdata struct idt_data apic_idts[] = { +#ifdef CONFIG_SMP + INTG(RESCHEDULE_VECTOR, reschedule_interrupt), + INTG(CALL_FUNCTION_VECTOR, call_function_interrupt), + INTG(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt), + INTG(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt), + INTG(REBOOT_VECTOR, reboot_interrupt), +#endif + +#ifdef CONFIG_X86_THERMAL_VECTOR + INTG(THERMAL_APIC_VECTOR, thermal_interrupt), +#endif + +#ifdef CONFIG_X86_MCE_THRESHOLD + INTG(THRESHOLD_APIC_VECTOR, threshold_interrupt), +#endif + +#ifdef CONFIG_X86_MCE_AMD + INTG(DEFERRED_ERROR_VECTOR, deferred_error_interrupt), +#endif + +#ifdef CONFIG_X86_LOCAL_APIC + INTG(LOCAL_TIMER_VECTOR, apic_timer_interrupt), + INTG(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi), +# ifdef CONFIG_HAVE_KVM + INTG(POSTED_INTR_VECTOR, kvm_posted_intr_ipi), + INTG(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi), + INTG(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi), +# endif +# ifdef CONFIG_IRQ_WORK + INTG(IRQ_WORK_VECTOR, irq_work_interrupt), +# endif + INTG(SPURIOUS_APIC_VECTOR, spurious_interrupt), + INTG(ERROR_APIC_VECTOR, error_interrupt), +#endif +}; + +#ifdef CONFIG_X86_64 +/* + * Early traps running on the DEFAULT_STACK because the other interrupt + * stacks work only after cpu_init(). + */ +static const __initdata struct idt_data early_pf_idts[] = { + INTG(X86_TRAP_PF, page_fault), +}; + +/* + * Override for the debug_idt. Same as the default, but with interrupt + * stack set to DEFAULT_STACK (0). Required for NMI trap handling. + */ +static const __initdata struct idt_data dbg_idts[] = { + INTG(X86_TRAP_DB, debug), + INTG(X86_TRAP_BP, int3), +}; +#endif + +/* Must be page-aligned because the real IDT is used in a fixmap. */ +gate_desc idt_table[IDT_ENTRIES] __page_aligned_bss; + +struct desc_ptr idt_descr __ro_after_init = { + .size = (IDT_ENTRIES * 2 * sizeof(unsigned long)) - 1, + .address = (unsigned long) idt_table, +}; + +#ifdef CONFIG_X86_64 +/* No need to be aligned, but done to keep all IDTs defined the same way. */ +gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; + +/* + * The exceptions which use Interrupt stacks. They are setup after + * cpu_init() when the TSS has been initialized. + */ +static const __initdata struct idt_data ist_idts[] = { + ISTG(X86_TRAP_DB, debug, DEBUG_STACK), + ISTG(X86_TRAP_NMI, nmi, NMI_STACK), + SISTG(X86_TRAP_BP, int3, DEBUG_STACK), + ISTG(X86_TRAP_DF, double_fault, DOUBLEFAULT_STACK), +#ifdef CONFIG_X86_MCE + ISTG(X86_TRAP_MC, &machine_check, MCE_STACK), +#endif +}; + +/* + * Override for the debug_idt. Same as the default, but with interrupt + * stack set to DEFAULT_STACK (0). Required for NMI trap handling. + */ +const struct desc_ptr debug_idt_descr = { + .size = IDT_ENTRIES * 16 - 1, + .address = (unsigned long) debug_idt_table, +}; +#endif + +static inline void idt_init_desc(gate_desc *gate, const struct idt_data *d) +{ + unsigned long addr = (unsigned long) d->addr; + + gate->offset_low = (u16) addr; + gate->segment = (u16) d->segment; + gate->bits = d->bits; + gate->offset_middle = (u16) (addr >> 16); +#ifdef CONFIG_X86_64 + gate->offset_high = (u32) (addr >> 32); + gate->reserved = 0; +#endif +} + +static void +idt_setup_from_table(gate_desc *idt, const struct idt_data *t, int size, bool sys) +{ + gate_desc desc; + + for (; size > 0; t++, size--) { + idt_init_desc(&desc, t); + write_idt_entry(idt, t->vector, &desc); + if (sys) + set_bit(t->vector, used_vectors); + } +} + +static void set_intr_gate(unsigned int n, const void *addr) +{ + struct idt_data data; + + BUG_ON(n > 0xFF); + + memset(&data, 0, sizeof(data)); + data.vector = n; + data.addr = addr; + data.segment = __KERNEL_CS; + data.bits.type = GATE_INTERRUPT; + data.bits.p = 1; + + idt_setup_from_table(idt_table, &data, 1, false); +} + +/** + * idt_setup_early_traps - Initialize the idt table with early traps + * + * On X8664 these traps do not use interrupt stacks as they can't work + * before cpu_init() is invoked and sets up TSS. The IST variants are + * installed after that. + */ +void __init idt_setup_early_traps(void) +{ + idt_setup_from_table(idt_table, early_idts, ARRAY_SIZE(early_idts), + true); + load_idt(&idt_descr); +} + +/** + * idt_setup_traps - Initialize the idt table with default traps + */ +void __init idt_setup_traps(void) +{ + idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true); +} + +#ifdef CONFIG_X86_64 +/** + * idt_setup_early_pf - Initialize the idt table with early pagefault handler + * + * On X8664 this does not use interrupt stacks as they can't work before + * cpu_init() is invoked and sets up TSS. The IST variant is installed + * after that. + * + * FIXME: Why is 32bit and 64bit installing the PF handler at different + * places in the early setup code? + */ +void __init idt_setup_early_pf(void) +{ + idt_setup_from_table(idt_table, early_pf_idts, + ARRAY_SIZE(early_pf_idts), true); +} + +/** + * idt_setup_ist_traps - Initialize the idt table with traps using IST + */ +void __init idt_setup_ist_traps(void) +{ + idt_setup_from_table(idt_table, ist_idts, ARRAY_SIZE(ist_idts), true); +} + +/** + * idt_setup_debugidt_traps - Initialize the debug idt table with debug traps + */ +void __init idt_setup_debugidt_traps(void) +{ + memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16); + + idt_setup_from_table(debug_idt_table, dbg_idts, ARRAY_SIZE(dbg_idts), false); +} +#endif + +/** + * idt_setup_apic_and_irq_gates - Setup APIC/SMP and normal interrupt gates + */ +void __init idt_setup_apic_and_irq_gates(void) +{ + int i = FIRST_EXTERNAL_VECTOR; + void *entry; + + idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts), true); + + for_each_clear_bit_from(i, used_vectors, FIRST_SYSTEM_VECTOR) { + entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR); + set_intr_gate(i, entry); + } + + for_each_clear_bit_from(i, used_vectors, NR_VECTORS) { +#ifdef CONFIG_X86_LOCAL_APIC + set_bit(i, used_vectors); + set_intr_gate(i, spurious_interrupt); +#else + entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR); + set_intr_gate(i, entry); +#endif + } +} + +/** + * idt_setup_early_handler - Initializes the idt table with early handlers + */ +void __init idt_setup_early_handler(void) +{ + int i; + + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) + set_intr_gate(i, early_idt_handler_array[i]); +#ifdef CONFIG_X86_32 + for ( ; i < NR_VECTORS; i++) + set_intr_gate(i, early_ignore_irq); +#endif + load_idt(&idt_descr); +} + +/** + * idt_invalidate - Invalidate interrupt descriptor table + * @addr: The virtual address of the 'invalid' IDT + */ +void idt_invalidate(void *addr) +{ + struct desc_ptr idt = { .address = (unsigned long) addr, .size = 0 }; + + load_idt(&idt); +} + +void __init update_intr_gate(unsigned int n, const void *addr) +{ + if (WARN_ON_ONCE(!test_bit(n, used_vectors))) + return; + set_intr_gate(n, addr); +} + +void alloc_intr_gate(unsigned int n, const void *addr) +{ + BUG_ON(n < FIRST_SYSTEM_VECTOR); + if (!test_and_set_bit(n, used_vectors)) + set_intr_gate(n, addr); +} diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c index 50c89e8a95f2..805b7a341aca 100644 --- a/arch/x86/kernel/io_delay.c +++ b/arch/x86/kernel/io_delay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * I/O delay strategies for inb_p/outb_p * @@ -58,7 +59,7 @@ static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id) * Quirk table for systems that misbehave (lock up, etc.) if port * 0x80 is used: */ -static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = { +static const struct dmi_system_id io_delay_0xed_port_dmi_table[] __initconst = { { .callback = dmi_io_delay_0xed_port, .ident = "Compaq Presario V6000", diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 9c3cf0944bce..3feb648781c4 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This contains the io-permission bitmap code - written by obz, with changes * by Linus. 32/64 bits code unification by Miguel Botón. diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 4ed0aba8dbc8..52089c043160 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -29,9 +29,6 @@ EXPORT_PER_CPU_SYMBOL(irq_regs); atomic_t irq_err_count; -/* Function pointer for generic interrupt vector handling */ -void (*x86_platform_ipi_callback)(void) = NULL; - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -87,13 +84,13 @@ int arch_show_interrupts(struct seq_file *p, int prec) for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->icr_read_retry_count); seq_puts(p, " APIC ICR read retries\n"); -#endif if (x86_platform_ipi_callback) { seq_printf(p, "%*s: ", prec, "PLT"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->x86_platform_ipis); seq_puts(p, " Platform interrupts\n"); } +#endif #ifdef CONFIG_SMP seq_printf(p, "%*s: ", prec, "RES"); for_each_online_cpu(j) @@ -183,9 +180,9 @@ u64 arch_irq_stat_cpu(unsigned int cpu) sum += irq_stats(cpu)->apic_perf_irqs; sum += irq_stats(cpu)->apic_irq_work_irqs; sum += irq_stats(cpu)->icr_read_retry_count; -#endif if (x86_platform_ipi_callback) sum += irq_stats(cpu)->x86_platform_ipis; +#endif #ifdef CONFIG_SMP sum += irq_stats(cpu)->irq_resched_count; sum += irq_stats(cpu)->irq_call_count; @@ -259,26 +256,26 @@ __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs) return 1; } +#ifdef CONFIG_X86_LOCAL_APIC +/* Function pointer for generic interrupt vector handling */ +void (*x86_platform_ipi_callback)(void) = NULL; /* * Handler for X86_PLATFORM_IPI_VECTOR. */ -void __smp_x86_platform_ipi(void) -{ - inc_irq_stat(x86_platform_ipis); - - if (x86_platform_ipi_callback) - x86_platform_ipi_callback(); -} - __visible void __irq_entry smp_x86_platform_ipi(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); entering_ack_irq(); - __smp_x86_platform_ipi(); + trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); + inc_irq_stat(x86_platform_ipis); + if (x86_platform_ipi_callback) + x86_platform_ipi_callback(); + trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); exiting_irq(); set_irq_regs(old_regs); } +#endif #ifdef CONFIG_HAVE_KVM static void dummy_handler(void) {} @@ -334,19 +331,6 @@ __visible void smp_kvm_posted_intr_nested_ipi(struct pt_regs *regs) } #endif -__visible void __irq_entry smp_trace_x86_platform_ipi(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - - entering_ack_irq(); - trace_x86_platform_ipi_entry(X86_PLATFORM_IPI_VECTOR); - __smp_x86_platform_ipi(); - trace_x86_platform_ipi_exit(X86_PLATFORM_IPI_VECTOR); - exiting_irq(); - set_irq_regs(old_regs); -} - -EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); #ifdef CONFIG_HOTPLUG_CPU @@ -431,7 +415,7 @@ int check_irq_vectors_for_cpu_disable(void) * this w/o holding vector_lock. */ for (vector = FIRST_EXTERNAL_VECTOR; - vector < first_system_vector; vector++) { + vector < FIRST_SYSTEM_VECTOR; vector++) { if (!test_bit(vector, used_vectors) && IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) { if (++count == this_count) diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index 1f38d9a4d9de..a83b3346a0e1 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * @@ -64,7 +65,7 @@ static void call_on_stack(void *func, void *stack) static inline void *current_stack(void) { - return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1)); + return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1)); } static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) @@ -88,7 +89,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) /* Save the next esp at the bottom of the stack */ prev_esp = (u32 *)irqstk; - *prev_esp = current_stack_pointer(); + *prev_esp = current_stack_pointer; if (unlikely(overflow)) call_on_stack(print_stack_overflow, isp); @@ -139,7 +140,7 @@ void do_softirq_own_stack(void) /* Push the previous esp onto the stack */ prev_esp = (u32 *)irqstk; - *prev_esp = current_stack_pointer(); + *prev_esp = current_stack_pointer; call_on_stack(__do_softirq, isp); } diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c index 3be74fbdeff2..020efbf5786b 100644 --- a/arch/x86/kernel/irq_64.c +++ b/arch/x86/kernel/irq_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * diff --git a/arch/x86/kernel/irq_work.c b/arch/x86/kernel/irq_work.c index 275487872be2..80bee7695a20 100644 --- a/arch/x86/kernel/irq_work.c +++ b/arch/x86/kernel/irq_work.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * x86 specific code for irq_work * @@ -11,35 +12,23 @@ #include #include -static inline void __smp_irq_work_interrupt(void) -{ - inc_irq_stat(apic_irq_work_irqs); - irq_work_run(); -} - +#ifdef CONFIG_X86_LOCAL_APIC __visible void __irq_entry smp_irq_work_interrupt(struct pt_regs *regs) -{ - ipi_entering_ack_irq(); - __smp_irq_work_interrupt(); - exiting_irq(); -} - -__visible void __irq_entry smp_trace_irq_work_interrupt(struct pt_regs *regs) { ipi_entering_ack_irq(); trace_irq_work_entry(IRQ_WORK_VECTOR); - __smp_irq_work_interrupt(); + inc_irq_stat(apic_irq_work_irqs); + irq_work_run(); trace_irq_work_exit(IRQ_WORK_VECTOR); exiting_irq(); } void arch_irq_work_raise(void) { -#ifdef CONFIG_X86_LOCAL_APIC if (!arch_irq_work_has_interrupt()) return; apic->send_IPI_self(IRQ_WORK_VECTOR); apic_wait_icr_idle(); -#endif } +#endif diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index c7fd18526c3e..1e4094eba15e 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -55,18 +56,6 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = { [0 ... NR_VECTORS - 1] = VECTOR_UNUSED, }; -int vector_used_by_percpu_irq(unsigned int vector) -{ - int cpu; - - for_each_online_cpu(cpu) { - if (!IS_ERR_OR_NULL(per_cpu(vector_irq, cpu)[vector])) - return 1; - } - - return 0; -} - void __init init_ISA_irqs(void) { struct irq_chip *chip = legacy_pic->chip; @@ -99,100 +88,12 @@ void __init init_IRQ(void) x86_init.irqs.intr_init(); } -static void __init smp_intr_init(void) -{ -#ifdef CONFIG_SMP - /* - * The reschedule interrupt is a CPU-to-CPU reschedule-helper - * IPI, driven by wakeup. - */ - alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); - - /* IPI for generic function call */ - alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); - - /* IPI for generic single function call */ - alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, - call_function_single_interrupt); - - /* Low priority IPI to cleanup after moving an irq */ - set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); - set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); - - /* IPI used for rebooting/stopping */ - alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt); -#endif /* CONFIG_SMP */ -} - -static void __init apic_intr_init(void) -{ - smp_intr_init(); - -#ifdef CONFIG_X86_THERMAL_VECTOR - alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); -#endif -#ifdef CONFIG_X86_MCE_THRESHOLD - alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); -#endif - -#ifdef CONFIG_X86_MCE_AMD - alloc_intr_gate(DEFERRED_ERROR_VECTOR, deferred_error_interrupt); -#endif - -#ifdef CONFIG_X86_LOCAL_APIC - /* self generated IPI for local APIC timer */ - alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); - - /* IPI for X86 platform specific use */ - alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi); -#ifdef CONFIG_HAVE_KVM - /* IPI for KVM to deliver posted interrupt */ - alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi); - /* IPI for KVM to deliver interrupt to wake up tasks */ - alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi); - /* IPI for KVM to deliver nested posted interrupt */ - alloc_intr_gate(POSTED_INTR_NESTED_VECTOR, kvm_posted_intr_nested_ipi); -#endif - - /* IPI vectors for APIC spurious and error interrupts */ - alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); - alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); - - /* IRQ work interrupts: */ -# ifdef CONFIG_IRQ_WORK - alloc_intr_gate(IRQ_WORK_VECTOR, irq_work_interrupt); -# endif - -#endif -} - void __init native_init_IRQ(void) { - int i; - /* Execute any quirks before the call gates are initialised: */ x86_init.irqs.pre_vector_init(); - apic_intr_init(); - - /* - * Cover the whole vector space, no vector can escape - * us. (some of these will be overridden and become - * 'special' SMP interrupts) - */ - i = FIRST_EXTERNAL_VECTOR; -#ifndef CONFIG_X86_LOCAL_APIC -#define first_system_vector NR_VECTORS -#endif - for_each_clear_bit_from(i, used_vectors, first_system_vector) { - /* IA32_SYSCALL_VECTOR could be used in trap_init already. */ - set_intr_gate(i, irq_entries_start + - 8 * (i - FIRST_EXTERNAL_VECTOR)); - } -#ifdef CONFIG_X86_LOCAL_APIC - for_each_clear_bit_from(i, used_vectors, NR_VECTORS) - set_intr_gate(i, spurious_interrupt); -#endif + idt_setup_apic_and_irq_gates(); if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) setup_irq(2, &irq2); diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c index ab4f491da2a9..e56c95be2808 100644 --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * jump label x86 support * diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index 38b64587b31b..fd6f8fbbe6f2 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c @@ -33,7 +33,6 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf, struct setup_data_node *node = file->private_data; unsigned long remain; loff_t pos = *ppos; - struct page *pg; void *p; u64 pa; @@ -47,18 +46,13 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf, count = node->len - pos; pa = node->paddr + sizeof(struct setup_data) + pos; - pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT); - if (PageHighMem(pg)) { - p = ioremap_cache(pa, count); - if (!p) - return -ENXIO; - } else - p = __va(pa); + p = memremap(pa, count, MEMREMAP_WB); + if (!p) + return -ENOMEM; remain = copy_to_user(user_buf, p, count); - if (PageHighMem(pg)) - iounmap(p); + memunmap(p); if (remain) return -EFAULT; @@ -109,7 +103,6 @@ static int __init create_setup_data_nodes(struct dentry *parent) struct setup_data *data; int error; struct dentry *d; - struct page *pg; u64 pa_data; int no = 0; @@ -126,16 +119,12 @@ static int __init create_setup_data_nodes(struct dentry *parent) goto err_dir; } - pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT); - if (PageHighMem(pg)) { - data = ioremap_cache(pa_data, sizeof(*data)); - if (!data) { - kfree(node); - error = -ENXIO; - goto err_dir; - } - } else - data = __va(pa_data); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); + if (!data) { + kfree(node); + error = -ENOMEM; + goto err_dir; + } node->paddr = pa_data; node->type = data->type; @@ -143,8 +132,7 @@ static int __init create_setup_data_nodes(struct dentry *parent) error = create_setup_data_node(d, no, node); pa_data = data->next; - if (PageHighMem(pg)) - iounmap(data); + memunmap(data); if (error) goto err_dir; no++; diff --git a/arch/x86/kernel/kprobes/common.h b/arch/x86/kernel/kprobes/common.h index db2182d63ed0..615105cf7d58 100644 --- a/arch/x86/kernel/kprobes/common.h +++ b/arch/x86/kernel/kprobes/common.h @@ -1,8 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __X86_KERNEL_KPROBES_COMMON_H #define __X86_KERNEL_KPROBES_COMMON_H /* Kprobes and Optprobes common header */ +#include + +#ifdef CONFIG_FRAME_POINTER +# define SAVE_RBP_STRING " push %" _ASM_BP "\n" \ + " mov %" _ASM_SP ", %" _ASM_BP "\n" +#else +# define SAVE_RBP_STRING " push %" _ASM_BP "\n" +#endif + #ifdef CONFIG_X86_64 #define SAVE_REGS_STRING \ /* Skip cs, ip, orig_ax. */ \ @@ -17,7 +27,7 @@ " pushq %r10\n" \ " pushq %r11\n" \ " pushq %rbx\n" \ - " pushq %rbp\n" \ + SAVE_RBP_STRING \ " pushq %r12\n" \ " pushq %r13\n" \ " pushq %r14\n" \ @@ -48,7 +58,7 @@ " pushl %es\n" \ " pushl %ds\n" \ " pushl %eax\n" \ - " pushl %ebp\n" \ + SAVE_RBP_STRING \ " pushl %edi\n" \ " pushl %esi\n" \ " pushl %edx\n" \ diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index f0153714ddac..0742491cbb73 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -1080,8 +1080,6 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) * raw stack chunk with redzones: */ __memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, MIN_STACK_SIZE(addr)); - regs->flags &= ~X86_EFLAGS_IF; - trace_hardirqs_off(); regs->ip = (unsigned long)(jp->entry); /* diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 69ea0bc1cfa3..4f98aad38237 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "common.h" @@ -251,10 +252,12 @@ static int can_optimize(unsigned long paddr) /* * Do not optimize in the entry code due to the unstable - * stack handling. + * stack handling and registers setup. */ - if ((paddr >= (unsigned long)__entry_text_start) && - (paddr < (unsigned long)__entry_text_end)) + if (((paddr >= (unsigned long)__entry_text_start) && + (paddr < (unsigned long)__entry_text_end)) || + ((paddr >= (unsigned long)__irqentry_text_start) && + (paddr < (unsigned long)__irqentry_text_end))) return 0; /* Check there is enough space for a relative jump. */ diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c index 06e1ff5562c0..8c1cc08f514f 100644 --- a/arch/x86/kernel/ksysfs.c +++ b/arch/x86/kernel/ksysfs.c @@ -16,8 +16,8 @@ #include #include #include +#include -#include #include static ssize_t version_show(struct kobject *kobj, @@ -79,12 +79,12 @@ static int get_setup_data_paddr(int nr, u64 *paddr) *paddr = pa_data; return 0; } - data = ioremap_cache(pa_data, sizeof(*data)); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; pa_data = data->next; - iounmap(data); + memunmap(data); i++; } return -EINVAL; @@ -97,17 +97,17 @@ static int __init get_setup_data_size(int nr, size_t *size) u64 pa_data = boot_params.hdr.setup_data; while (pa_data) { - data = ioremap_cache(pa_data, sizeof(*data)); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; if (nr == i) { *size = data->len; - iounmap(data); + memunmap(data); return 0; } pa_data = data->next; - iounmap(data); + memunmap(data); i++; } return -EINVAL; @@ -127,12 +127,12 @@ static ssize_t type_show(struct kobject *kobj, ret = get_setup_data_paddr(nr, &paddr); if (ret) return ret; - data = ioremap_cache(paddr, sizeof(*data)); + data = memremap(paddr, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; ret = sprintf(buf, "0x%x\n", data->type); - iounmap(data); + memunmap(data); return ret; } @@ -154,7 +154,7 @@ static ssize_t setup_data_data_read(struct file *fp, ret = get_setup_data_paddr(nr, &paddr); if (ret) return ret; - data = ioremap_cache(paddr, sizeof(*data)); + data = memremap(paddr, sizeof(*data), MEMREMAP_WB); if (!data) return -ENOMEM; @@ -170,15 +170,15 @@ static ssize_t setup_data_data_read(struct file *fp, goto out; ret = count; - p = ioremap_cache(paddr + sizeof(*data), data->len); + p = memremap(paddr + sizeof(*data), data->len, MEMREMAP_WB); if (!p) { ret = -ENOMEM; goto out; } memcpy(buf, p + off, count); - iounmap(p); + memunmap(p); out: - iounmap(data); + memunmap(data); return ret; } @@ -250,13 +250,13 @@ static int __init get_setup_data_total_num(u64 pa_data, int *nr) *nr = 0; while (pa_data) { *nr += 1; - data = ioremap_cache(pa_data, sizeof(*data)); + data = memremap(pa_data, sizeof(*data), MEMREMAP_WB); if (!data) { ret = -ENOMEM; goto out; } pa_data = data->next; - iounmap(data); + memunmap(data); } out: @@ -299,7 +299,7 @@ static int __init create_setup_data_nodes(struct kobject *parent) return 0; out_clean_nodes: - for (j = i - 1; j > 0; j--) + for (j = i - 1; j >= 0; j--) cleanup_setup_data_node(*(kobjp + j)); kfree(kobjp); out_setup_data_kobj: diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index d04e30e3c0ff..8bb9594d0761 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -117,7 +117,11 @@ static struct kvm_task_sleep_node *_find_apf_task(struct kvm_task_sleep_head *b, return NULL; } -void kvm_async_pf_task_wait(u32 token) +/* + * @interrupt_kernel: Is this called from a routine which interrupts the kernel + * (other than user space)? + */ +void kvm_async_pf_task_wait(u32 token, int interrupt_kernel) { u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS); struct kvm_task_sleep_head *b = &async_pf_sleepers[key]; @@ -140,7 +144,10 @@ void kvm_async_pf_task_wait(u32 token) n.token = token; n.cpu = smp_processor_id(); - n.halted = is_idle_task(current) || preempt_count() > 1; + n.halted = is_idle_task(current) || + (IS_ENABLED(CONFIG_PREEMPT_COUNT) + ? preempt_count() > 1 || rcu_preempt_depth() + : interrupt_kernel); init_swait_queue_head(&n.wq); hlist_add_head(&n.link, &b->list); raw_spin_unlock(&b->lock); @@ -180,7 +187,7 @@ static void apf_task_wake_one(struct kvm_task_sleep_node *n) hlist_del_init(&n->link); if (n->halted) smp_send_reschedule(n->cpu); - else if (swait_active(&n->wq)) + else if (swq_has_sleeper(&n->wq)) swake_up(&n->wq); } @@ -263,12 +270,12 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) switch (kvm_read_and_reset_pf_reason()) { default: - trace_do_page_fault(regs, error_code); + do_page_fault(regs, error_code); break; case KVM_PV_REASON_PAGE_NOT_PRESENT: /* page is swapped out by the host. */ prev_state = exception_enter(); - kvm_async_pf_task_wait((u32)read_cr2()); + kvm_async_pf_task_wait((u32)read_cr2(), !user_mode(regs)); exception_exit(prev_state); break; case KVM_PV_REASON_PAGE_READY: @@ -455,7 +462,7 @@ static int kvm_cpu_down_prepare(unsigned int cpu) static void __init kvm_apf_trap_init(void) { - set_intr_gate(14, async_page_fault); + update_intr_gate(X86_TRAP_PF, async_page_fault); } void __init kvm_guest_init(void) diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index d88967659098..5b609e28ce3f 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -79,7 +79,7 @@ static void kvm_get_wallclock(struct timespec *now) static int kvm_set_wallclock(const struct timespec *now) { - return -1; + return -ENODEV; } static u64 kvm_clock_read(void) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index a870910c8565..4d17bacf4030 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds * Copyright (C) 1999 Ingo Molnar @@ -21,6 +22,25 @@ #include #include +static void refresh_ldt_segments(void) +{ +#ifdef CONFIG_X86_64 + unsigned short sel; + + /* + * Make sure that the cached DS and ES descriptors match the updated + * LDT. + */ + savesegment(ds, sel); + if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) + loadsegment(ds, sel); + + savesegment(es, sel); + if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) + loadsegment(es, sel); +#endif +} + /* context.lock is held for us, so we don't need any locking. */ static void flush_ldt(void *__mm) { @@ -32,6 +52,8 @@ static void flush_ldt(void *__mm) pc = &mm->context; set_ldt(pc->ldt->entries, pc->ldt->nr_entries); + + refresh_ldt_segments(); } /* The caller must call finalize_ldt_struct on the result. LDT starts zeroed. */ diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 8c53c5d7a1bc..00bc751c861c 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -26,18 +26,6 @@ #include #include -static void set_idt(void *newidt, __u16 limit) -{ - struct desc_ptr curidt; - - /* ia32 supports unaliged loads & stores */ - curidt.size = limit; - curidt.address = (unsigned long)newidt; - - load_idt(&curidt); -} - - static void set_gdt(void *newgdt, __u16 limit) { struct desc_ptr curgdt; @@ -245,7 +233,7 @@ void machine_kexec(struct kimage *image) * If you want to load them you must set up your own idt & gdt. */ set_gdt(phys_to_virt(0), 0); - set_idt(phys_to_virt(0), 0); + idt_invalidate(phys_to_virt(0)); /* now call it */ image->start = relocate_kernel_ptr((unsigned long)image->head, diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index cb0a30473c23..1f790cf9d38f 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -87,7 +87,7 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE)); } pte = pte_offset_kernel(pmd, vaddr); - set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC)); + set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC)); return 0; err: free_transition_pgtable(image); @@ -115,6 +115,7 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable) .alloc_pgt_page = alloc_pgt_page, .context = image, .page_flag = __PAGE_KERNEL_LARGE_EXEC, + .kernpg_flag = _KERNPG_TABLE_NOENC, }; unsigned long mstart, mend; pgd_t *level4p; @@ -334,7 +335,8 @@ void machine_kexec(struct kimage *image) image->start = relocate_kernel((unsigned long)image->head, (unsigned long)page_list, image->start, - image->preserve_context); + image->preserve_context, + sme_active()); #ifdef CONFIG_KEXEC_JUMP if (image->preserve_context) @@ -602,3 +604,22 @@ void arch_kexec_unprotect_crashkres(void) { kexec_mark_crashkres(false); } + +int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp) +{ + /* + * If SME is active we need to be sure that kexec pages are + * not encrypted because when we boot to the new kernel the + * pages won't be accessed encrypted (initially). + */ + return set_memory_decrypted((unsigned long)vaddr, pages); +} + +void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) +{ + /* + * If SME is active we need to reset the pages back to being + * an encrypted mapping before freeing them. + */ + set_memory_encrypted((unsigned long)vaddr, pages); +} diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c index f4c886d9165c..b5cb49e57df8 100644 --- a/arch/x86/kernel/mmconf-fam10h_64.c +++ b/arch/x86/kernel/mmconf-fam10h_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * AMD Family 10h mmconfig enablement */ diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index f67bd3205df7..da0c160e5589 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -35,6 +35,7 @@ #include #include #include +#include #if 0 #define DEBUGP(fmt, ...) \ @@ -171,19 +172,27 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, case R_X86_64_NONE: break; case R_X86_64_64: + if (*(u64 *)loc != 0) + goto invalid_relocation; *(u64 *)loc = val; break; case R_X86_64_32: + if (*(u32 *)loc != 0) + goto invalid_relocation; *(u32 *)loc = val; if (val != *(u32 *)loc) goto overflow; break; case R_X86_64_32S: + if (*(s32 *)loc != 0) + goto invalid_relocation; *(s32 *)loc = val; if ((s64)val != *(s32 *)loc) goto overflow; break; case R_X86_64_PC32: + if (*(u32 *)loc != 0) + goto invalid_relocation; val -= (u64)loc; *(u32 *)loc = val; #if 0 @@ -199,6 +208,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, } return 0; +invalid_relocation: + pr_err("x86/modules: Skipping invalid relocation target, existing value is nonzero for type %d, loc %p, val %Lx\n", + (int)ELF64_R_TYPE(rel[i].r_info), loc, val); + return -ENOEXEC; + overflow: pr_err("overflow in relocation type %d val %Lx\n", (int)ELF64_R_TYPE(rel[i].r_info), val); @@ -213,7 +227,7 @@ int module_finalize(const Elf_Ehdr *hdr, struct module *me) { const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, - *para = NULL; + *para = NULL, *orc = NULL, *orc_ip = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { @@ -225,6 +239,10 @@ int module_finalize(const Elf_Ehdr *hdr, locks = s; if (!strcmp(".parainstructions", secstrings + s->sh_name)) para = s; + if (!strcmp(".orc_unwind", secstrings + s->sh_name)) + orc = s; + if (!strcmp(".orc_unwind_ip", secstrings + s->sh_name)) + orc_ip = s; } if (alt) { @@ -248,6 +266,10 @@ int module_finalize(const Elf_Ehdr *hdr, /* make jump label nops */ jump_label_apply_nops(me); + if (orc && orc_ip) + unwind_module_init(me, (void *)orc_ip->sh_addr, orc_ip->sh_size, + (void *)orc->sh_addr, orc->sh_size); + return 0; } diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 0d904d759ff1..410c5dadcee3 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel Multiprocessor Specification 1.1 and 1.4 * compliant MP-table parsing routines. @@ -429,16 +430,16 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) } } -static struct mpf_intel *mpf_found; +static unsigned long mpf_base; static unsigned long __init get_mpc_size(unsigned long physptr) { struct mpc_table *mpc; unsigned long size; - mpc = early_ioremap(physptr, PAGE_SIZE); + mpc = early_memremap(physptr, PAGE_SIZE); size = mpc->length; - early_iounmap(mpc, PAGE_SIZE); + early_memunmap(mpc, PAGE_SIZE); apic_printk(APIC_VERBOSE, " mpc: %lx-%lx\n", physptr, physptr + size); return size; @@ -450,7 +451,8 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) unsigned long size; size = get_mpc_size(mpf->physptr); - mpc = early_ioremap(mpf->physptr, size); + mpc = early_memremap(mpf->physptr, size); + /* * Read the physical hardware table. Anything here will * override the defaults. @@ -461,10 +463,10 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) #endif pr_err("BIOS bug, MP table errors detected!...\n"); pr_cont("... disabling SMP support. (tell your hw vendor)\n"); - early_iounmap(mpc, size); + early_memunmap(mpc, size); return -1; } - early_iounmap(mpc, size); + early_memunmap(mpc, size); if (early) return -1; @@ -497,12 +499,12 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early) */ void __init default_get_smp_config(unsigned int early) { - struct mpf_intel *mpf = mpf_found; + struct mpf_intel *mpf; if (!smp_found_config) return; - if (!mpf) + if (!mpf_base) return; if (acpi_lapic && early) @@ -515,6 +517,12 @@ void __init default_get_smp_config(unsigned int early) if (acpi_lapic && acpi_ioapic) return; + mpf = early_memremap(mpf_base, sizeof(*mpf)); + if (!mpf) { + pr_err("MPTABLE: error mapping MP table\n"); + return; + } + pr_info("Intel MultiProcessor Specification v1.%d\n", mpf->specification); #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32) @@ -529,7 +537,7 @@ void __init default_get_smp_config(unsigned int early) /* * Now see if we need to read further. */ - if (mpf->feature1 != 0) { + if (mpf->feature1) { if (early) { /* * local APIC has default address @@ -542,8 +550,10 @@ void __init default_get_smp_config(unsigned int early) construct_default_ISA_mptable(mpf->feature1); } else if (mpf->physptr) { - if (check_physptr(mpf, early)) + if (check_physptr(mpf, early)) { + early_memunmap(mpf, sizeof(*mpf)); return; + } } else BUG(); @@ -552,6 +562,8 @@ void __init default_get_smp_config(unsigned int early) /* * Only use the first configuration found. */ + + early_memunmap(mpf, sizeof(*mpf)); } static void __init smp_reserve_memory(struct mpf_intel *mpf) @@ -561,15 +573,16 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf) static int __init smp_scan_config(unsigned long base, unsigned long length) { - unsigned int *bp = phys_to_virt(base); + unsigned int *bp; struct mpf_intel *mpf; - unsigned long mem; + int ret = 0; apic_printk(APIC_VERBOSE, "Scan for SMP in [mem %#010lx-%#010lx]\n", base, base + length - 1); BUILD_BUG_ON(sizeof(*mpf) != 16); while (length > 0) { + bp = early_memremap(base, length); mpf = (struct mpf_intel *)bp; if ((*bp == SMP_MAGIC_IDENT) && (mpf->length == 1) && @@ -579,24 +592,26 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) #ifdef CONFIG_X86_LOCAL_APIC smp_found_config = 1; #endif - mpf_found = mpf; + mpf_base = base; - pr_info("found SMP MP-table at [mem %#010llx-%#010llx] mapped at [%p]\n", - (unsigned long long) virt_to_phys(mpf), - (unsigned long long) virt_to_phys(mpf) + - sizeof(*mpf) - 1, mpf); + pr_info("found SMP MP-table at [mem %#010lx-%#010lx] mapped at [%p]\n", + base, base + sizeof(*mpf) - 1, mpf); - mem = virt_to_phys(mpf); - memblock_reserve(mem, sizeof(*mpf)); + memblock_reserve(base, sizeof(*mpf)); if (mpf->physptr) smp_reserve_memory(mpf); - return 1; + ret = 1; } - bp += 4; + early_memunmap(bp, length); + + if (ret) + break; + + base += 16; length -= 16; } - return 0; + return ret; } void __init default_find_smp_config(void) @@ -838,29 +853,40 @@ static int __init update_mp_table(void) char oem[10]; struct mpf_intel *mpf; struct mpc_table *mpc, *mpc_new; + unsigned long size; if (!enable_update_mptable) return 0; - mpf = mpf_found; - if (!mpf) + if (!mpf_base) return 0; + mpf = early_memremap(mpf_base, sizeof(*mpf)); + if (!mpf) { + pr_err("MPTABLE: mpf early_memremap() failed\n"); + return 0; + } + /* * Now see if we need to go further. */ - if (mpf->feature1 != 0) - return 0; + if (mpf->feature1) + goto do_unmap_mpf; if (!mpf->physptr) - return 0; + goto do_unmap_mpf; - mpc = phys_to_virt(mpf->physptr); + size = get_mpc_size(mpf->physptr); + mpc = early_memremap(mpf->physptr, size); + if (!mpc) { + pr_err("MPTABLE: mpc early_memremap() failed\n"); + goto do_unmap_mpf; + } if (!smp_check_mpc(mpc, oem, str)) - return 0; + goto do_unmap_mpc; - pr_info("mpf: %llx\n", (u64)virt_to_phys(mpf)); + pr_info("mpf: %llx\n", (u64)mpf_base); pr_info("physptr: %x\n", mpf->physptr); if (mpc_new_phys && mpc->length > mpc_new_length) { @@ -878,21 +904,32 @@ static int __init update_mp_table(void) new = mpf_checksum((unsigned char *)mpc, mpc->length); if (old == new) { pr_info("mpc is readonly, please try alloc_mptable instead\n"); - return 0; + goto do_unmap_mpc; } pr_info("use in-position replacing\n"); } else { + mpc_new = early_memremap(mpc_new_phys, mpc_new_length); + if (!mpc_new) { + pr_err("MPTABLE: new mpc early_memremap() failed\n"); + goto do_unmap_mpc; + } mpf->physptr = mpc_new_phys; - mpc_new = phys_to_virt(mpc_new_phys); memcpy(mpc_new, mpc, mpc->length); + early_memunmap(mpc, size); mpc = mpc_new; + size = mpc_new_length; /* check if we can modify that */ if (mpc_new_phys - mpf->physptr) { struct mpf_intel *mpf_new; /* steal 16 bytes from [0, 1k) */ + mpf_new = early_memremap(0x400 - 16, sizeof(*mpf_new)); + if (!mpf_new) { + pr_err("MPTABLE: new mpf early_memremap() failed\n"); + goto do_unmap_mpc; + } pr_info("mpf new: %x\n", 0x400 - 16); - mpf_new = phys_to_virt(0x400 - 16); memcpy(mpf_new, mpf, 16); + early_memunmap(mpf, sizeof(*mpf)); mpf = mpf_new; mpf->physptr = mpc_new_phys; } @@ -909,6 +946,12 @@ static int __init update_mp_table(void) */ replace_intsrc_all(mpc, mpc_new_phys, mpc_new_length); +do_unmap_mpc: + early_memunmap(mpc, size); + +do_unmap_mpf: + early_memunmap(mpf, sizeof(*mpf)); + return 0; } diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 446c8aa09b9b..35aafc95e4b8 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -39,26 +39,26 @@ #include struct nmi_desc { - spinlock_t lock; + raw_spinlock_t lock; struct list_head head; }; static struct nmi_desc nmi_desc[NMI_MAX] = { { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[0].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[0].lock), .head = LIST_HEAD_INIT(nmi_desc[0].head), }, { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[1].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[1].lock), .head = LIST_HEAD_INIT(nmi_desc[1].head), }, { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[2].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[2].lock), .head = LIST_HEAD_INIT(nmi_desc[2].head), }, { - .lock = __SPIN_LOCK_UNLOCKED(&nmi_desc[3].lock), + .lock = __RAW_SPIN_LOCK_UNLOCKED(&nmi_desc[3].lock), .head = LIST_HEAD_INIT(nmi_desc[3].head), }, @@ -163,7 +163,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) init_irq_work(&action->irq_work, nmi_max_handler); - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); /* * Indicate if there are multiple registrations on the @@ -181,7 +181,7 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) else list_add_tail_rcu(&action->list, &desc->head); - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); return 0; } EXPORT_SYMBOL(__register_nmi_handler); @@ -192,7 +192,7 @@ void unregister_nmi_handler(unsigned int type, const char *name) struct nmiaction *n; unsigned long flags; - spin_lock_irqsave(&desc->lock, flags); + raw_spin_lock_irqsave(&desc->lock, flags); list_for_each_entry_rcu(n, &desc->head, list) { /* @@ -207,7 +207,7 @@ void unregister_nmi_handler(unsigned int type, const char *name) } } - spin_unlock_irqrestore(&desc->lock, flags); + raw_spin_unlock_irqrestore(&desc->lock, flags); synchronize_rcu(); } EXPORT_SYMBOL_GPL(unregister_nmi_handler); diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c index d27f8d84c4ff..a1a96df3dff1 100644 --- a/arch/x86/kernel/nmi_selftest.c +++ b/arch/x86/kernel/nmi_selftest.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * arch/x86/kernel/nmi-selftest.c * diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 8f2d1c9d43a8..71f2d1125ec0 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Split spinlock implementation out into its own file, so it can be * compiled in a FTRACE-compatible way. diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index bc0a849589bb..19a3e8f961c7 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -319,9 +319,6 @@ __visible struct pv_irq_ops pv_irq_ops = { .irq_enable = __PV_IS_CALLEE_SAVE(native_irq_enable), .safe_halt = native_safe_halt, .halt = native_halt, -#ifdef CONFIG_X86_64 - .adjust_exception_frame = paravirt_nop, -#endif }; __visible struct pv_cpu_ops pv_cpu_ops = { @@ -330,7 +327,6 @@ __visible struct pv_cpu_ops pv_cpu_ops = { .set_debugreg = native_set_debugreg, .read_cr0 = native_read_cr0, .write_cr0 = native_write_cr0, - .read_cr4 = native_read_cr4, .write_cr4 = native_write_cr4, #ifdef CONFIG_X86_64 .read_cr8 = native_read_cr8, @@ -346,7 +342,6 @@ __visible struct pv_cpu_ops pv_cpu_ops = { .set_ldt = native_set_ldt, .load_gdt = native_load_gdt, .load_idt = native_load_idt, - .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, #ifdef CONFIG_X86_64 @@ -414,8 +409,6 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = { .set_pte = native_set_pte, .set_pte_at = native_set_pte_at, .set_pmd = native_set_pmd, - .set_pmd_at = native_set_pmd_at, - .pte_update = paravirt_nop, .ptep_modify_prot_start = __ptep_modify_prot_start, .ptep_modify_prot_commit = __ptep_modify_prot_commit, @@ -427,7 +420,6 @@ struct pv_mmu_ops pv_mmu_ops __ro_after_init = { .pmd_clear = native_pmd_clear, #endif .set_pud = native_set_pud, - .set_pud_at = native_set_pud_at, .pmd_val = PTE_IDENT, .make_pmd = PTE_IDENT, diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c index 553acbbb4d32..758e69d72ebf 100644 --- a/arch/x86/kernel/paravirt_patch_32.c +++ b/arch/x86/kernel/paravirt_patch_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include DEF_NATIVE(pv_irq_ops, irq_disable, "cli"); diff --git a/arch/x86/kernel/paravirt_patch_64.c b/arch/x86/kernel/paravirt_patch_64.c index 11aaf1eaa0e4..ac0be8283325 100644 --- a/arch/x86/kernel/paravirt_patch_64.c +++ b/arch/x86/kernel/paravirt_patch_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 5e16d3f29594..599d7462eccc 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -93,9 +94,12 @@ again: if (gfpflags_allow_blocking(flag)) { page = dma_alloc_from_contiguous(dev, count, get_order(size), flag); - if (page && page_to_phys(page) + size > dma_mask) { - dma_release_from_contiguous(dev, page, count); - page = NULL; + if (page) { + addr = phys_to_dma(dev, page_to_phys(page)); + if (addr + size > dma_mask) { + dma_release_from_contiguous(dev, page, count); + page = NULL; + } } } /* fallback */ @@ -104,7 +108,7 @@ again: if (!page) return NULL; - addr = page_to_phys(page); + addr = phys_to_dma(dev, page_to_phys(page)); if (addr + size > dma_mask) { __free_pages(page, get_order(size)); diff --git a/arch/x86/kernel/pci-iommu_table.c b/arch/x86/kernel/pci-iommu_table.c index f712dfdf1357..4dfd90a75e63 100644 --- a/arch/x86/kernel/pci-iommu_table.c +++ b/arch/x86/kernel/pci-iommu_table.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index a6d404087fe3..b0caae27e1b7 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Fallback functions when the main IOMMU code is not compiled in. This code is roughly equivalent to i386. */ #include @@ -32,7 +33,7 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page, enum dma_data_direction dir, unsigned long attrs) { - dma_addr_t bus = page_to_phys(page) + offset; + dma_addr_t bus = phys_to_dma(dev, page_to_phys(page)) + offset; WARN_ON(size == 0); if (!check_addr("map_single", dev, bus, size)) return NOMMU_MAPPING_ERROR; diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 1e23577e17cf..53bd05ea90d8 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Glue code to lib/swiotlb.c */ #include @@ -6,12 +7,14 @@ #include #include #include +#include #include #include #include #include #include + int swiotlb __read_mostly; void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, @@ -79,8 +82,8 @@ IOMMU_INIT_FINISH(pci_swiotlb_detect_override, pci_swiotlb_late_init); /* - * if 4GB or more detected (and iommu=off not set) return 1 - * and set swiotlb to 1. + * If 4GB or more detected (and iommu=off not set) or if SME is active + * then set swiotlb to 1 and return 1. */ int __init pci_swiotlb_detect_4gb(void) { @@ -89,6 +92,15 @@ int __init pci_swiotlb_detect_4gb(void) if (!no_iommu && max_possible_pfn > MAX_DMA32_PFN) swiotlb = 1; #endif + + /* + * If SME is active then swiotlb will be set to 1 so that bounce + * buffers are allocated and used for devices that do not support + * the addressing range required for the encryption mask. + */ + if (sme_active()) + swiotlb = 1; + return swiotlb; } IOMMU_INIT(pci_swiotlb_detect_4gb, diff --git a/arch/x86/kernel/pcspeaker.c b/arch/x86/kernel/pcspeaker.c index a311ffcaad16..da5190a1ea16 100644 --- a/arch/x86/kernel/pcspeaker.c +++ b/arch/x86/kernel/pcspeaker.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c index 587d887f7f17..e47b2dbbdef3 100644 --- a/arch/x86/kernel/perf_regs.c +++ b/arch/x86/kernel/perf_regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/platform-quirks.c b/arch/x86/kernel/platform-quirks.c index 91271122f0df..39a59299bfa0 100644 --- a/arch/x86/kernel/platform-quirks.c +++ b/arch/x86/kernel/platform-quirks.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -16,7 +17,6 @@ void __init x86_early_init_platform_quirks(void) x86_platform.legacy.reserve_bios_regions = 1; break; case X86_SUBARCH_XEN: - case X86_SUBARCH_LGUEST: x86_platform.legacy.devices.pnpbios = 0; x86_platform.legacy.rtc = 0; break; diff --git a/arch/x86/kernel/pmem.c b/arch/x86/kernel/pmem.c index 0c5315d322c8..3fe690067802 100644 --- a/arch/x86/kernel/pmem.c +++ b/arch/x86/kernel/pmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2015, Christoph Hellwig. * Copyright (c) 2015, Intel Corporation. diff --git a/arch/x86/kernel/probe_roms.c b/arch/x86/kernel/probe_roms.c index 963e3fb56437..ee0286390a4c 100644 --- a/arch/x86/kernel/probe_roms.c +++ b/arch/x86/kernel/probe_roms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 3ca198080ea9..c67685337c5a 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include @@ -355,6 +356,7 @@ bool xen_set_default_idle(void) return ret; } #endif + void stop_this_cpu(void *dummy) { local_irq_disable(); @@ -365,8 +367,20 @@ void stop_this_cpu(void *dummy) disable_local_APIC(); mcheck_cpu_clear(this_cpu_ptr(&cpu_info)); - for (;;) - halt(); + for (;;) { + /* + * Use wbinvd followed by hlt to stop the processor. This + * provides support for kexec on a processor that supports + * SME. With kexec, going from SME inactive to SME active + * requires clearing cache entries so that addresses without + * the encryption bit set don't corrupt the same physical + * address that has the encryption bit set when caches are + * flushed. To achieve this a wbinvd is performed followed by + * a hlt. Even if the processor is not in the kexec/SME + * scenario this only adds a wbinvd to a halting processor. + */ + asm volatile("wbinvd; hlt" : : : "memory"); + } } /* diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index c6d6dc5f8bb2..11966251cd42 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include void __show_regs(struct pt_regs *regs, int all) @@ -68,7 +68,7 @@ void __show_regs(struct pt_regs *regs, int all) if (user_mode(regs)) { sp = regs->sp; - ss = regs->ss & 0xffff; + ss = regs->ss; gs = get_user_gs(regs); } else { sp = kernel_stack_pointer(regs); diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index c3169be4c596..302e7b2572d1 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #ifdef CONFIG_IA32_EMULATION /* Not included via unistd.h */ @@ -69,8 +69,7 @@ void __show_regs(struct pt_regs *regs, int all) unsigned int fsindex, gsindex; unsigned int ds, cs, es; - printk(KERN_DEFAULT "RIP: %04lx:%pS\n", regs->cs & 0xffff, - (void *)regs->ip); + printk(KERN_DEFAULT "RIP: %04lx:%pS\n", regs->cs, (void *)regs->ip); printk(KERN_DEFAULT "RSP: %04lx:%016lx EFLAGS: %08lx", regs->ss, regs->sp, regs->flags); if (regs->orig_ax != -1) @@ -149,6 +148,123 @@ void release_thread(struct task_struct *dead_task) } } +enum which_selector { + FS, + GS +}; + +/* + * Saves the FS or GS base for an outgoing thread if FSGSBASE extensions are + * not available. The goal is to be reasonably fast on non-FSGSBASE systems. + * It's forcibly inlined because it'll generate better code and this function + * is hot. + */ +static __always_inline void save_base_legacy(struct task_struct *prev_p, + unsigned short selector, + enum which_selector which) +{ + if (likely(selector == 0)) { + /* + * On Intel (without X86_BUG_NULL_SEG), the segment base could + * be the pre-existing saved base or it could be zero. On AMD + * (with X86_BUG_NULL_SEG), the segment base could be almost + * anything. + * + * This branch is very hot (it's hit twice on almost every + * context switch between 64-bit programs), and avoiding + * the RDMSR helps a lot, so we just assume that whatever + * value is already saved is correct. This matches historical + * Linux behavior, so it won't break existing applications. + * + * To avoid leaking state, on non-X86_BUG_NULL_SEG CPUs, if we + * report that the base is zero, it needs to actually be zero: + * see the corresponding logic in load_seg_legacy. + */ + } else { + /* + * If the selector is 1, 2, or 3, then the base is zero on + * !X86_BUG_NULL_SEG CPUs and could be anything on + * X86_BUG_NULL_SEG CPUs. In the latter case, Linux + * has never attempted to preserve the base across context + * switches. + * + * If selector > 3, then it refers to a real segment, and + * saving the base isn't necessary. + */ + if (which == FS) + prev_p->thread.fsbase = 0; + else + prev_p->thread.gsbase = 0; + } +} + +static __always_inline void save_fsgs(struct task_struct *task) +{ + savesegment(fs, task->thread.fsindex); + savesegment(gs, task->thread.gsindex); + save_base_legacy(task, task->thread.fsindex, FS); + save_base_legacy(task, task->thread.gsindex, GS); +} + +static __always_inline void loadseg(enum which_selector which, + unsigned short sel) +{ + if (which == FS) + loadsegment(fs, sel); + else + load_gs_index(sel); +} + +static __always_inline void load_seg_legacy(unsigned short prev_index, + unsigned long prev_base, + unsigned short next_index, + unsigned long next_base, + enum which_selector which) +{ + if (likely(next_index <= 3)) { + /* + * The next task is using 64-bit TLS, is not using this + * segment at all, or is having fun with arcane CPU features. + */ + if (next_base == 0) { + /* + * Nasty case: on AMD CPUs, we need to forcibly zero + * the base. + */ + if (static_cpu_has_bug(X86_BUG_NULL_SEG)) { + loadseg(which, __USER_DS); + loadseg(which, next_index); + } else { + /* + * We could try to exhaustively detect cases + * under which we can skip the segment load, + * but there's really only one case that matters + * for performance: if both the previous and + * next states are fully zeroed, we can skip + * the load. + * + * (This assumes that prev_base == 0 has no + * false positives. This is the case on + * Intel-style CPUs.) + */ + if (likely(prev_index | next_index | prev_base)) + loadseg(which, next_index); + } + } else { + if (prev_index != next_index) + loadseg(which, next_index); + wrmsrl(which == FS ? MSR_FS_BASE : MSR_KERNEL_GS_BASE, + next_base); + } + } else { + /* + * The next task is using a real segment. Loading the selector + * is sufficient. + */ + loadseg(which, next_index); + } +} + int copy_thread_tls(unsigned long clone_flags, unsigned long sp, unsigned long arg, struct task_struct *p, unsigned long tls) { @@ -229,10 +345,19 @@ start_thread_common(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp, unsigned int _cs, unsigned int _ss, unsigned int _ds) { + WARN_ON_ONCE(regs != current_pt_regs()); + + if (static_cpu_has(X86_BUG_NULL_SEG)) { + /* Loading zero below won't clear the base. */ + loadsegment(fs, __USER_DS); + load_gs_index(__USER_DS); + } + loadsegment(fs, 0); loadsegment(es, _ds); loadsegment(ds, _ds); load_gs_index(0); + regs->ip = new_ip; regs->sp = new_sp; regs->cs = _cs; @@ -277,7 +402,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) struct fpu *next_fpu = &next->fpu; int cpu = smp_processor_id(); struct tss_struct *tss = &per_cpu(cpu_tss, cpu); - unsigned prev_fsindex, prev_gsindex; + + WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) && + this_cpu_read(irq_count) != -1); switch_fpu_prepare(prev_fpu, cpu); @@ -286,8 +413,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) * * (e.g. xen_load_tls()) */ - savesegment(fs, prev_fsindex); - savesegment(gs, prev_gsindex); + save_fsgs(prev_p); /* * Load TLS before restoring any segments so that segment loads @@ -326,108 +452,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) if (unlikely(next->ds | prev->ds)) loadsegment(ds, next->ds); - /* - * Switch FS and GS. - * - * These are even more complicated than DS and ES: they have - * 64-bit bases are that controlled by arch_prctl. The bases - * don't necessarily match the selectors, as user code can do - * any number of things to cause them to be inconsistent. - * - * We don't promise to preserve the bases if the selectors are - * nonzero. We also don't promise to preserve the base if the - * selector is zero and the base doesn't match whatever was - * most recently passed to ARCH_SET_FS/GS. (If/when the - * FSGSBASE instructions are enabled, we'll need to offer - * stronger guarantees.) - * - * As an invariant, - * (fsbase != 0 && fsindex != 0) || (gsbase != 0 && gsindex != 0) is - * impossible. - */ - if (next->fsindex) { - /* Loading a nonzero value into FS sets the index and base. */ - loadsegment(fs, next->fsindex); - } else { - if (next->fsbase) { - /* Next index is zero but next base is nonzero. */ - if (prev_fsindex) - loadsegment(fs, 0); - wrmsrl(MSR_FS_BASE, next->fsbase); - } else { - /* Next base and index are both zero. */ - if (static_cpu_has_bug(X86_BUG_NULL_SEG)) { - /* - * We don't know the previous base and can't - * find out without RDMSR. Forcibly clear it. - */ - loadsegment(fs, __USER_DS); - loadsegment(fs, 0); - } else { - /* - * If the previous index is zero and ARCH_SET_FS - * didn't change the base, then the base is - * also zero and we don't need to do anything. - */ - if (prev->fsbase || prev_fsindex) - loadsegment(fs, 0); - } - } - } - /* - * Save the old state and preserve the invariant. - * NB: if prev_fsindex == 0, then we can't reliably learn the base - * without RDMSR because Intel user code can zero it without telling - * us and AMD user code can program any 32-bit value without telling - * us. - */ - if (prev_fsindex) - prev->fsbase = 0; - prev->fsindex = prev_fsindex; - - if (next->gsindex) { - /* Loading a nonzero value into GS sets the index and base. */ - load_gs_index(next->gsindex); - } else { - if (next->gsbase) { - /* Next index is zero but next base is nonzero. */ - if (prev_gsindex) - load_gs_index(0); - wrmsrl(MSR_KERNEL_GS_BASE, next->gsbase); - } else { - /* Next base and index are both zero. */ - if (static_cpu_has_bug(X86_BUG_NULL_SEG)) { - /* - * We don't know the previous base and can't - * find out without RDMSR. Forcibly clear it. - * - * This contains a pointless SWAPGS pair. - * Fixing it would involve an explicit check - * for Xen or a new pvop. - */ - load_gs_index(__USER_DS); - load_gs_index(0); - } else { - /* - * If the previous index is zero and ARCH_SET_GS - * didn't change the base, then the base is - * also zero and we don't need to do anything. - */ - if (prev->gsbase || prev_gsindex) - load_gs_index(0); - } - } - } - /* - * Save the old state and preserve the invariant. - * NB: if prev_gsindex == 0, then we can't reliably learn the base - * without RDMSR because Intel user code can zero it without telling - * us and AMD user code can program any 32-bit value without telling - * us. - */ - if (prev_gsindex) - prev->gsbase = 0; - prev->gsindex = prev_gsindex; + load_seg_legacy(prev->fsindex, prev->fsbase, + next->fsindex, next->fsbase, FS); + load_seg_legacy(prev->gsindex, prev->gsbase, + next->gsindex, next->gsbase, GS); switch_fpu_finish(next_fpu, cpu); diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index 0bee04d41bed..697a4ce04308 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c @@ -1,6 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file contains work-arounds for x86 and x86_64 platform bugs. */ +#include #include #include @@ -656,3 +658,12 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x6fc0, quirk_intel_brickland_xeon_ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2083, quirk_intel_purley_xeon_ras_cap); #endif #endif + +bool x86_apple_machine; +EXPORT_SYMBOL(x86_apple_machine); + +void __init early_platform_quirks(void) +{ + x86_apple_machine = dmi_match(DMI_SYS_VENDOR, "Apple Inc.") || + dmi_match(DMI_SYS_VENDOR, "Apple Computer, Inc."); +} diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index a56bf6051f4e..2126b9d27c34 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include @@ -38,8 +39,6 @@ void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); -static const struct desc_ptr no_idt = {}; - /* * This is set if we need to go through the 'emergency' path. * When machine_emergency_restart() is called, we may be on @@ -107,6 +106,10 @@ void __noreturn machine_real_restart(unsigned int type) load_cr3(initial_page_table); #else write_cr3(real_mode_header->trampoline_pgd); + + /* Exiting long mode will fail if CR4.PCIDE is set. */ + if (static_cpu_has(X86_FEATURE_PCID)) + cr4_clear_bits(X86_CR4_PCIDE); #endif /* Jump to the identity-mapped low memory code */ @@ -152,7 +155,7 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) /* * This is a single dmi_table handling all reboot quirks. */ -static struct dmi_system_id __initdata reboot_dmi_table[] = { +static const struct dmi_system_id reboot_dmi_table[] __initconst = { /* Acer */ { /* Handle reboot issue on Acer Aspire one */ @@ -638,7 +641,7 @@ static void native_machine_emergency_restart(void) break; case BOOT_TRIPLE: - load_idt(&no_idt); + idt_invalidate(NULL); __asm__ __volatile__("int3"); /* We're probably dead after this, but... */ diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c index c8e41e90f59c..b7c0f142d026 100644 --- a/arch/x86/kernel/reboot_fixups_32.c +++ b/arch/x86/kernel/reboot_fixups_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This is a good place to put board specific reboot fixups. * diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S index 98111b38ebfd..307d3bac5f04 100644 --- a/arch/x86/kernel/relocate_kernel_64.S +++ b/arch/x86/kernel/relocate_kernel_64.S @@ -47,6 +47,7 @@ relocate_kernel: * %rsi page_list * %rdx start address * %rcx preserve_context + * %r8 sme_active */ /* Save the CPU context, used for jumping back */ @@ -71,6 +72,9 @@ relocate_kernel: pushq $0 popfq + /* Save SME active flag */ + movq %r8, %r12 + /* * get physical address of control page now * this is impossible after page table switch @@ -132,6 +136,16 @@ identity_mapped: /* Flush the TLB (needed?) */ movq %r9, %cr3 + /* + * If SME is active, there could be old encrypted cache line + * entries that will conflict with the now unencrypted memory + * used by kexec. Flush the caches before copying the kernel. + */ + testq %r12, %r12 + jz 1f + wbinvd +1: + movq %rcx, %r11 call swap_pages diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c index 5ab3895516ac..9b9fb7882c20 100644 --- a/arch/x86/kernel/resource.c +++ b/arch/x86/kernel/resource.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 5b21cb7d84d6..69ac9cb9cac6 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC related functions */ diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 3486d0498800..0957dd73d127 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include ", short_cfo_a, short_cfo_b); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "Long CFO(Hz) ", long_cfo_a, long_cfo_b); + + /*SCFO*/ + value32 = odm_get_bb_reg(dm, 0xdb8, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xdb4, MASKDWORD); + + scfo_b = (s32)(value32 & 0x7ff); /*S(11,10)*/ + scfo_a = (s32)((value32 & 0x07ff0000) >> 16); + + if (scfo_a > 1023) + scfo_a = scfo_a - 2048; + + if (scfo_b > 1023) + scfo_b = scfo_b - 2048; + + scfo_a = scfo_a * 312500 / 1024; + scfo_b = scfo_b * 312500 / 1024; + + avg_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/ + avg_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16); + + if (avg_cfo_a > 4095) + avg_cfo_a = avg_cfo_a - 8192; + + if (avg_cfo_b > 4095) + avg_cfo_b = avg_cfo_b - 8192; + + avg_cfo_a = avg_cfo_a * 312500 / 4096; + avg_cfo_b = avg_cfo_b * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "value SCFO(Hz) ", scfo_a, scfo_b); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "Avg CFO(Hz) ", avg_cfo_a, avg_cfo_b); + + value32 = odm_get_bb_reg(dm, 0xdbc, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xde0, MASKDWORD); + + cfo_end_b = (s32)(value32 & 0x1fff); /*S(13,12)*/ + cfo_end_a = (s32)((value32 & 0x1fff0000) >> 16); + + if (cfo_end_a > 4095) + cfo_end_a = cfo_end_a - 8192; + + if (cfo_end_b > 4095) + cfo_end_b = cfo_end_b - 8192; + + cfo_end_a = cfo_end_a * 312500 / 4096; + cfo_end_b = cfo_end_b * 312500 / 4096; + + acq_cfo_b = (s32)(value32_1 & 0x1fff); /*S(13,12)*/ + acq_cfo_a = (s32)((value32_1 & 0x1fff0000) >> 16); + + if (acq_cfo_a > 4095) + acq_cfo_a = acq_cfo_a - 8192; + + if (acq_cfo_b > 4095) + acq_cfo_b = acq_cfo_b - 8192; + + acq_cfo_a = acq_cfo_a * 312500 / 4096; + acq_cfo_b = acq_cfo_b * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "End CFO(Hz) ", cfo_end_a, cfo_end_b); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "ACQ CFO(Hz) ", acq_cfo_a, acq_cfo_b); +} + +static void phydm_bb_debug_info(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + + char *tmp_string = NULL; + + u8 rx_ht_bw, rx_vht_bw, rxsc, rx_ht, rx_bw; + static u8 v_rx_bw; + u32 value32, value32_1, value32_2, value32_3; + s32 sfo_a, sfo_b, sfo_c, sfo_d; + s32 lfo_a, lfo_b, lfo_c, lfo_d; + static u8 MCSS, tail, parity, rsv, vrsv, idx, smooth, htsound, agg, + stbc, vstbc, fec, fecext, sgi, sgiext, htltf, vgid, v_nsts, + vtxops, vrsv2, vbrsv, bf, vbcrc; + static u16 h_length, htcrc8, length; + static u16 vpaid; + static u16 v_length, vhtcrc8, v_mcss, v_tail, vb_tail; + static u8 hmcss, hrx_bw; + + u8 pwdb; + s8 rxevm_0, rxevm_1, rxevm_2; + u8 rf_gain_path_a, rf_gain_path_b, rf_gain_path_c, rf_gain_path_d; + u8 rx_snr_path_a, rx_snr_path_b, rx_snr_path_c, rx_snr_path_d; + s32 sig_power; + + const char *L_rate[8] = {"6M", "9M", "12M", "18M", + "24M", "36M", "48M", "54M"}; + + if (dm->support_ic_type & ODM_IC_11N_SERIES) { + phydm_bb_debug_info_n_series(dm, &used, output, &out_len); + return; + } + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s\n", + "BB Report Info"); + + /*BW & mode Detection*/ + + value32 = odm_get_bb_reg(dm, 0xf80, MASKDWORD); + value32_2 = value32; + rx_ht_bw = (u8)(value32 & 0x1); + rx_vht_bw = (u8)((value32 >> 1) & 0x3); + rxsc = (u8)(value32 & 0x78); + value32_1 = (value32 & 0x180) >> 7; + rx_ht = (u8)(value32_1); + + rx_bw = 0; + + if (rx_ht == 2) { + if (rx_vht_bw == 0) + tmp_string = "20M"; + else if (rx_vht_bw == 1) + tmp_string = "40M"; + else + tmp_string = "80M"; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s %s %s", "mode", "VHT", tmp_string); + rx_bw = rx_vht_bw; + } else if (rx_ht == 1) { + if (rx_ht_bw == 0) + tmp_string = "20M"; + else if (rx_ht_bw == 1) + tmp_string = "40M"; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s %s %s", "mode", "HT", tmp_string); + rx_bw = rx_ht_bw; + } else { + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s %s", + "mode", "Legacy"); + } + if (rx_ht != 0) { + if (rxsc == 0) + tmp_string = "duplicate/full bw"; + else if (rxsc == 1) + tmp_string = "usc20-1"; + else if (rxsc == 2) + tmp_string = "lsc20-1"; + else if (rxsc == 3) + tmp_string = "usc20-2"; + else if (rxsc == 4) + tmp_string = "lsc20-2"; + else if (rxsc == 9) + tmp_string = "usc40"; + else if (rxsc == 10) + tmp_string = "lsc40"; + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s", + tmp_string); + } + + /* RX signal power and AGC related info*/ + + value32 = odm_get_bb_reg(dm, 0xF90, MASKDWORD); + pwdb = (u8)((value32 & MASKBYTE1) >> 8); + pwdb = pwdb >> 1; + sig_power = -110 + pwdb; + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "OFDM RX Signal Power(dB)", sig_power); + + value32 = odm_get_bb_reg(dm, 0xd14, MASKDWORD); + rx_snr_path_a = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_a = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_a *= 2; + value32 = odm_get_bb_reg(dm, 0xd54, MASKDWORD); + rx_snr_path_b = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_b = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_b *= 2; + value32 = odm_get_bb_reg(dm, 0xd94, MASKDWORD); + rx_snr_path_c = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_c = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_c *= 2; + value32 = odm_get_bb_reg(dm, 0xdd4, MASKDWORD); + rx_snr_path_d = (u8)(value32 & 0xFF) >> 1; + rf_gain_path_d = (s8)((value32 & MASKBYTE1) >> 8); + rf_gain_path_d *= 2; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d / %d", + "OFDM RX RF Gain(A/B/C/D)", rf_gain_path_a, + rf_gain_path_b, rf_gain_path_c, rf_gain_path_d); + + /* RX counter related info*/ + + value32 = odm_get_bb_reg(dm, 0xF08, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "OFDM CCA counter", ((value32 & 0xFFFF0000) >> 16)); + + value32 = odm_get_bb_reg(dm, 0xFD0, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "OFDM SBD Fail counter", value32 & 0xFFFF); + + value32 = odm_get_bb_reg(dm, 0xFC4, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "VHT SIGA/SIGB CRC8 Fail counter", value32 & 0xFFFF, + ((value32 & 0xFFFF0000) >> 16)); + + value32 = odm_get_bb_reg(dm, 0xFCC, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d", + "CCK CCA counter", value32 & 0xFFFF); + + value32 = odm_get_bb_reg(dm, 0xFBC, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "LSIG (parity Fail/rate Illegal) counter", + value32 & 0xFFFF, ((value32 & 0xFFFF0000) >> 16)); + + value32_1 = odm_get_bb_reg(dm, 0xFC8, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xFC0, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "HT/VHT MCS NOT SUPPORT counter", + ((value32_2 & 0xFFFF0000) >> 16), value32_1 & 0xFFFF); + + /* PostFFT related info*/ + value32 = odm_get_bb_reg(dm, 0xF8c, MASKDWORD); + rxevm_0 = (s8)((value32 & MASKBYTE2) >> 16); + rxevm_0 /= 2; + if (rxevm_0 < -63) + rxevm_0 = 0; + + rxevm_1 = (s8)((value32 & MASKBYTE3) >> 24); + rxevm_1 /= 2; + value32 = odm_get_bb_reg(dm, 0xF88, MASKDWORD); + rxevm_2 = (s8)((value32 & MASKBYTE2) >> 16); + rxevm_2 /= 2; + + if (rxevm_1 < -63) + rxevm_1 = 0; + if (rxevm_2 < -63) + rxevm_2 = 0; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d", "RXEVM (1ss/2ss/3ss)", + rxevm_0, rxevm_1, rxevm_2); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d / %d", "RXSNR(A/B/C/D, dB)", + rx_snr_path_a, rx_snr_path_b, rx_snr_path_c, + rx_snr_path_d); + + value32 = odm_get_bb_reg(dm, 0xF8C, MASKDWORD); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s = %d / %d", + "CSI_1st /CSI_2nd", value32 & 0xFFFF, + ((value32 & 0xFFFF0000) >> 16)); + + /*BW & mode Detection*/ + + /*Reset Page F counter*/ + odm_set_bb_reg(dm, 0xB58, BIT(0), 1); + odm_set_bb_reg(dm, 0xB58, BIT(0), 0); + + /*CFO Report Info*/ + /*Short CFO*/ + value32 = odm_get_bb_reg(dm, 0xd0c, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xd4c, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xd8c, MASKDWORD); + value32_3 = odm_get_bb_reg(dm, 0xdcc, MASKDWORD); + + sfo_a = (s32)(value32 & 0xfff); + sfo_b = (s32)(value32_1 & 0xfff); + sfo_c = (s32)(value32_2 & 0xfff); + sfo_d = (s32)(value32_3 & 0xfff); + + lfo_a = (s32)(value32 >> 16); + lfo_b = (s32)(value32_1 >> 16); + lfo_c = (s32)(value32_2 >> 16); + lfo_d = (s32)(value32_3 >> 16); + + /*SFO 2's to dec*/ + if (sfo_a > 2047) + sfo_a = sfo_a - 4096; + sfo_a = (sfo_a * 312500) / 2048; + if (sfo_b > 2047) + sfo_b = sfo_b - 4096; + sfo_b = (sfo_b * 312500) / 2048; + if (sfo_c > 2047) + sfo_c = sfo_c - 4096; + sfo_c = (sfo_c * 312500) / 2048; + if (sfo_d > 2047) + sfo_d = sfo_d - 4096; + sfo_d = (sfo_d * 312500) / 2048; + + /*LFO 2's to dec*/ + + if (lfo_a > 4095) + lfo_a = lfo_a - 8192; + + if (lfo_b > 4095) + lfo_b = lfo_b - 8192; + + if (lfo_c > 4095) + lfo_c = lfo_c - 8192; + + if (lfo_d > 4095) + lfo_d = lfo_d - 8192; + lfo_a = lfo_a * 312500 / 4096; + lfo_b = lfo_b * 312500 / 4096; + lfo_c = lfo_c * 312500 / 4096; + lfo_d = lfo_d * 312500 / 4096; + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "CFO Report Info"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", + "Short CFO(Hz) ", sfo_a, sfo_b, sfo_c, sfo_d); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", + "Long CFO(Hz) ", lfo_a, lfo_b, lfo_c, lfo_d); + + /*SCFO*/ + value32 = odm_get_bb_reg(dm, 0xd10, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xd50, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xd90, MASKDWORD); + value32_3 = odm_get_bb_reg(dm, 0xdd0, MASKDWORD); + + sfo_a = (s32)(value32 & 0x7ff); + sfo_b = (s32)(value32_1 & 0x7ff); + sfo_c = (s32)(value32_2 & 0x7ff); + sfo_d = (s32)(value32_3 & 0x7ff); + + if (sfo_a > 1023) + sfo_a = sfo_a - 2048; + + if (sfo_b > 2047) + sfo_b = sfo_b - 4096; + + if (sfo_c > 2047) + sfo_c = sfo_c - 4096; + + if (sfo_d > 2047) + sfo_d = sfo_d - 4096; + + sfo_a = sfo_a * 312500 / 1024; + sfo_b = sfo_b * 312500 / 1024; + sfo_c = sfo_c * 312500 / 1024; + sfo_d = sfo_d * 312500 / 1024; + + lfo_a = (s32)(value32 >> 16); + lfo_b = (s32)(value32_1 >> 16); + lfo_c = (s32)(value32_2 >> 16); + lfo_d = (s32)(value32_3 >> 16); + + if (lfo_a > 4095) + lfo_a = lfo_a - 8192; + + if (lfo_b > 4095) + lfo_b = lfo_b - 8192; + + if (lfo_c > 4095) + lfo_c = lfo_c - 8192; + + if (lfo_d > 4095) + lfo_d = lfo_d - 8192; + lfo_a = lfo_a * 312500 / 4096; + lfo_b = lfo_b * 312500 / 4096; + lfo_c = lfo_c * 312500 / 4096; + lfo_d = lfo_d * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", + "value SCFO(Hz) ", sfo_a, sfo_b, sfo_c, sfo_d); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", "ACQ CFO(Hz) ", + lfo_a, lfo_b, lfo_c, lfo_d); + + value32 = odm_get_bb_reg(dm, 0xd14, MASKDWORD); + value32_1 = odm_get_bb_reg(dm, 0xd54, MASKDWORD); + value32_2 = odm_get_bb_reg(dm, 0xd94, MASKDWORD); + value32_3 = odm_get_bb_reg(dm, 0xdd4, MASKDWORD); + + lfo_a = (s32)(value32 >> 16); + lfo_b = (s32)(value32_1 >> 16); + lfo_c = (s32)(value32_2 >> 16); + lfo_d = (s32)(value32_3 >> 16); + + if (lfo_a > 4095) + lfo_a = lfo_a - 8192; + + if (lfo_b > 4095) + lfo_b = lfo_b - 8192; + + if (lfo_c > 4095) + lfo_c = lfo_c - 8192; + + if (lfo_d > 4095) + lfo_d = lfo_d - 8192; + + lfo_a = lfo_a * 312500 / 4096; + lfo_b = lfo_b * 312500 / 4096; + lfo_c = lfo_c * 312500 / 4096; + lfo_d = lfo_d * 312500 / 4096; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d / %d / %d /%d", "End CFO(Hz) ", + lfo_a, lfo_b, lfo_c, lfo_d); + + value32 = odm_get_bb_reg(dm, 0xf20, MASKDWORD); /*L SIG*/ + + tail = (u8)((value32 & 0xfc0000) >> 16); + parity = (u8)((value32 & 0x20000) >> 16); + length = (u16)((value32 & 0x1ffe00) >> 8); + rsv = (u8)(value32 & 0x10); + MCSS = (u8)(value32 & 0x0f); + + switch (MCSS) { + case 0x0b: + idx = 0; + break; + case 0x0f: + idx = 1; + break; + case 0x0a: + idx = 2; + break; + case 0x0e: + idx = 3; + break; + case 0x09: + idx = 4; + break; + case 0x08: + idx = 5; + break; + case 0x0c: + idx = 6; + break; + default: + idx = 6; + break; + } + + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "L-SIG"); + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s : %s", "rate", + L_rate[idx]); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x", "Rsv/length/parity", rsv, + rx_bw, length); + + value32 = odm_get_bb_reg(dm, 0xf2c, MASKDWORD); /*HT SIG*/ + if (rx_ht == 1) { + hmcss = (u8)(value32 & 0x7F); + hrx_bw = (u8)(value32 & 0x80); + h_length = (u16)((value32 >> 8) & 0xffff); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "HT-SIG1"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x", "MCS/BW/length", hmcss, + hrx_bw, h_length); + + value32 = odm_get_bb_reg(dm, 0xf30, MASKDWORD); /*HT SIG*/ + + if (rx_ht == 1) { + smooth = (u8)(value32 & 0x01); + htsound = (u8)(value32 & 0x02); + rsv = (u8)(value32 & 0x04); + agg = (u8)(value32 & 0x08); + stbc = (u8)(value32 & 0x30); + fec = (u8)(value32 & 0x40); + sgi = (u8)(value32 & 0x80); + htltf = (u8)((value32 & 0x300) >> 8); + htcrc8 = (u16)((value32 & 0x3fc00) >> 8); + tail = (u8)((value32 & 0xfc0000) >> 16); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", "HT-SIG2"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x / %x / %x", + "Smooth/NoSound/Rsv/Aggregate/STBC/LDPC", smooth, + htsound, rsv, agg, stbc, fec); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x", + "SGI/E-HT-LTFs/CRC/tail", sgi, htltf, htcrc8, tail); + + value32 = odm_get_bb_reg(dm, 0xf2c, MASKDWORD); /*VHT SIG A1*/ + if (rx_ht == 2) { + /* value32 = odm_get_bb_reg(dm, 0xf2c,MASKDWORD);*/ + v_rx_bw = (u8)(value32 & 0x03); + vrsv = (u8)(value32 & 0x04); + vstbc = (u8)(value32 & 0x08); + vgid = (u8)((value32 & 0x3f0) >> 4); + v_nsts = (u8)(((value32 & 0x1c00) >> 8) + 1); + vpaid = (u16)(value32 & 0x3fe); + vtxops = (u8)((value32 & 0x400000) >> 20); + vrsv2 = (u8)((value32 & 0x800000) >> 20); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "VHT-SIG-A1"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x / %x", + "BW/Rsv1/STBC/GID/Nsts/PAID/TXOPPS/Rsv2", v_rx_bw, vrsv, + vstbc, vgid, v_nsts, vpaid, vtxops, vrsv2); + + value32 = odm_get_bb_reg(dm, 0xf30, MASKDWORD); /*VHT SIG*/ + + if (rx_ht == 2) { + /*value32 = odm_get_bb_reg(dm, 0xf30,MASKDWORD); */ /*VHT SIG*/ + + /* sgi=(u8)(value32&0x01); */ + sgiext = (u8)(value32 & 0x03); + /* fec = (u8)(value32&0x04); */ + fecext = (u8)(value32 & 0x0C); + + v_mcss = (u8)(value32 & 0xf0); + bf = (u8)((value32 & 0x100) >> 8); + vrsv = (u8)((value32 & 0x200) >> 8); + vhtcrc8 = (u16)((value32 & 0x3fc00) >> 8); + v_tail = (u8)((value32 & 0xfc0000) >> 16); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "VHT-SIG-A2"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x / %x / %x / %x", + "SGI/FEC/MCS/BF/Rsv/CRC/tail", sgiext, fecext, v_mcss, + bf, vrsv, vhtcrc8, v_tail); + + value32 = odm_get_bb_reg(dm, 0xf34, MASKDWORD); /*VHT SIG*/ + { + v_length = (u16)(value32 & 0x1fffff); + vbrsv = (u8)((value32 & 0x600000) >> 20); + vb_tail = (u16)((value32 & 0x1f800000) >> 20); + vbcrc = (u8)((value32 & 0x80000000) >> 28); + } + PHYDM_SNPRINTF(output + used, out_len - used, "\r\n %-35s", + "VHT-SIG-B"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %x / %x / %x / %x", "length/Rsv/tail/CRC", + v_length, vbrsv, vb_tail, vbcrc); + + /*for Condition number*/ + if (dm->support_ic_type & ODM_RTL8822B) { + s32 condition_num = 0; + char *factor = NULL; + + /*enable report condition number*/ + odm_set_bb_reg(dm, 0x1988, BIT(22), 0x1); + + condition_num = odm_get_bb_reg(dm, 0xf84, MASKDWORD); + condition_num = (condition_num & 0x3ffff) >> 4; + + if (*dm->band_width == ODM_BW80M) { + factor = "256/234"; + } else if (*dm->band_width == ODM_BW40M) { + factor = "128/108"; + } else if (*dm->band_width == ODM_BW20M) { + if (rx_ht == 2 || rx_ht == 1) + factor = "64/52"; /*HT or VHT*/ + else + factor = "64/48"; /*legacy*/ + } + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n %-35s = %d (factor = %s)", + "Condition number", condition_num, factor); + } +} + +void phydm_basic_dbg_message(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct false_alarm_stat *false_alm_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + struct cfo_tracking *cfo_track = + (struct cfo_tracking *)phydm_get_structure(dm, PHYDM_CFOTRACK); + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct ra_table *ra_tab = &dm->dm_ra_table; + u16 macid, phydm_macid, client_cnt = 0; + struct rtl_sta_info *entry; + s32 tmp_val = 0; + u8 tmp_val_u1 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "[PHYDM Common MSG] System up time: ((%d sec))----->\n", + dm->phydm_sys_up_time); + + if (dm->is_linked) { + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "ID=%d, BW=((%d)), CH=((%d))\n", + dm->curr_station_id, 20 << *dm->band_width, + *dm->channel); + + /*Print RX rate*/ + if (dm->rx_rate <= ODM_RATE11M) + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "[CCK AGC Report] LNA_idx = 0x%x, VGA_idx = 0x%x\n", + dm->cck_lna_idx, dm->cck_vga_idx); + else + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "[OFDM AGC Report] { 0x%x, 0x%x, 0x%x, 0x%x }\n", + dm->ofdm_agc_idx[0], dm->ofdm_agc_idx[1], + dm->ofdm_agc_idx[2], dm->ofdm_agc_idx[3]); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "RSSI: { %d, %d, %d, %d }, rx_rate:", + (dm->rssi_a == 0xff) ? 0 : dm->rssi_a, + (dm->rssi_b == 0xff) ? 0 : dm->rssi_b, + (dm->rssi_c == 0xff) ? 0 : dm->rssi_c, + (dm->rssi_d == 0xff) ? 0 : dm->rssi_d); + + phydm_print_rate(dm, dm->rx_rate, ODM_COMP_COMMON); + + /*Print TX rate*/ + for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) { + entry = dm->odm_sta_info[macid]; + if (!IS_STA_VALID(entry)) + continue; + + phydm_macid = (dm->platform2phydm_macid_table[macid]); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "TXRate [%d]:", + macid); + phydm_print_rate(dm, ra_tab->link_tx_rate[macid], + ODM_COMP_COMMON); + + client_cnt++; + + if (client_cnt == dm->number_linked_client) + break; + } + + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "TP { TX, RX, total} = {%d, %d, %d }Mbps, traffic_load = (%d))\n", + dm->tx_tp, dm->rx_tp, dm->total_tp, dm->traffic_load); + + tmp_val_u1 = + (cfo_track->crystal_cap > cfo_track->def_x_cap) ? + (cfo_track->crystal_cap - + cfo_track->def_x_cap) : + (cfo_track->def_x_cap - cfo_track->crystal_cap); + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "CFO_avg = ((%d kHz)) , CrystalCap_tracking = ((%s%d))\n", + cfo_track->CFO_ave_pre, + ((cfo_track->crystal_cap > cfo_track->def_x_cap) ? "+" : + "-"), + tmp_val_u1); + + /* Condition number */ + if (dm->support_ic_type == ODM_RTL8822B) { + tmp_val = phydm_get_condition_number_8822B(dm); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "Condition number = ((%d))\n", tmp_val); + } + + /*STBC or LDPC pkt*/ + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "LDPC = %s, STBC = %s\n", + (dm->phy_dbg_info.is_ldpc_pkt) ? "Y" : "N", + (dm->phy_dbg_info.is_stbc_pkt) ? "Y" : "N"); + } else { + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "No Link !!!\n"); + } + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca, + false_alm_cnt->cnt_cca_all); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, + false_alm_cnt->cnt_all); + + if (dm->support_ic_type & ODM_IC_11N_SERIES) + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n", + false_alm_cnt->cnt_parity_fail, + false_alm_cnt->cnt_rate_illegal, + false_alm_cnt->cnt_crc8_fail, + false_alm_cnt->cnt_mcs_fail, + false_alm_cnt->cnt_fast_fsync, + false_alm_cnt->cnt_sb_search_fail); + + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "is_linked = %d, Num_client = %d, rssi_min = %d, current_igi = 0x%x, bNoisy=%d\n\n", + dm->is_linked, dm->number_linked_client, dm->rssi_min, + dig_tab->cur_ig_value, dm->noisy_decision); +} + +void phydm_basic_profile(void *dm_void, u32 *_used, char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + char *cut = NULL; + char *ic_type = NULL; + u32 used = *_used; + u32 out_len = *_out_len; + u32 date = 0; + char *commit_by = NULL; + u32 release_ver = 0; + + PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n", + "% Basic Profile %"); + + if (dm->support_ic_type == ODM_RTL8188E) { + } else if (dm->support_ic_type == ODM_RTL8822B) { + ic_type = "RTL8822B"; + date = RELEASE_DATE_8822B; + commit_by = COMMIT_BY_8822B; + release_ver = RELEASE_VERSION_8822B; + } + + /* JJ ADD 20161014 */ + + PHYDM_SNPRINTF(output + used, out_len - used, + " %-35s: %s (MP Chip: %s)\n", "IC type", ic_type, + dm->is_mp_chip ? "Yes" : "No"); + + if (dm->cut_version == ODM_CUT_A) + cut = "A"; + else if (dm->cut_version == ODM_CUT_B) + cut = "B"; + else if (dm->cut_version == ODM_CUT_C) + cut = "C"; + else if (dm->cut_version == ODM_CUT_D) + cut = "D"; + else if (dm->cut_version == ODM_CUT_E) + cut = "E"; + else if (dm->cut_version == ODM_CUT_F) + cut = "F"; + else if (dm->cut_version == ODM_CUT_I) + cut = "I"; + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "cut version", cut); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n", + "PHY Parameter version", odm_get_hw_img_version(dm)); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n", + "PHY Parameter Commit date", date); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "PHY Parameter Commit by", commit_by); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %d\n", + "PHY Parameter Release version", release_ver); + + { + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + PHYDM_SNPRINTF(output + used, out_len - used, + " %-35s: %d (Subversion: %d)\n", "FW version", + rtlhal->fw_version, rtlhal->fw_subversion); + } + /* 1 PHY DM version List */ + PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n", + "% PHYDM version %"); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Code base", PHYDM_CODE_BASE); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Release Date", PHYDM_RELEASE_DATE); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "adaptivity", ADAPTIVITY_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", "DIG", + DIG_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Dynamic BB PowerSaving", DYNAMIC_BBPWRSAV_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "CFO Tracking", CFO_TRACKING_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Antenna Diversity", ANTDIV_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Power Tracking", POWRTRACKING_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Dynamic TxPower", DYNAMIC_TXPWR_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "RA Info", RAINFO_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Auto channel Selection", ACS_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "EDCA Turbo", EDCATURBO_VERSION); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "LA mode", DYNAMIC_LA_MODE); + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "Dynamic RX path", DYNAMIC_RX_PATH_VERSION); + + if (dm->support_ic_type & ODM_RTL8822B) + PHYDM_SNPRINTF(output + used, out_len - used, " %-35s: %s\n", + "PHY config 8822B", PHY_CONFIG_VERSION_8822B); + + *_used = used; + *_out_len = out_len; +} + +void phydm_fw_trace_en_h2c(void *dm_void, bool enable, u32 fw_debug_component, + u32 monitor_mode, u32 macid) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 h2c_parameter[7] = {0}; + u8 cmd_length; + + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + h2c_parameter[0] = enable; + h2c_parameter[1] = (u8)(fw_debug_component & MASKBYTE0); + h2c_parameter[2] = (u8)((fw_debug_component & MASKBYTE1) >> 8); + h2c_parameter[3] = (u8)((fw_debug_component & MASKBYTE2) >> 16); + h2c_parameter[4] = (u8)((fw_debug_component & MASKBYTE3) >> 24); + h2c_parameter[5] = (u8)monitor_mode; + h2c_parameter[6] = (u8)macid; + cmd_length = 7; + + } else { + h2c_parameter[0] = enable; + h2c_parameter[1] = (u8)monitor_mode; + h2c_parameter[2] = (u8)macid; + cmd_length = 3; + } + + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "---->\n"); + if (monitor_mode == 0) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[H2C] FW_debug_en: (( %d ))\n", enable); + else + ODM_RT_TRACE( + dm, ODM_FW_DEBUG_TRACE, + "[H2C] FW_debug_en: (( %d )), mode: (( %d )), macid: (( %d ))\n", + enable, monitor_mode, macid); + odm_fill_h2c_cmd(dm, PHYDM_H2C_FW_TRACE_EN, cmd_length, h2c_parameter); +} + +bool phydm_api_set_txagc(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate, + bool is_single_rate) +{ + bool ret = false; + + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8821C)) { + if (is_single_rate) { + if (dm->support_ic_type == ODM_RTL8822B) + ret = phydm_write_txagc_1byte_8822b( + dm, power_index, path, hw_rate); + + } else { + if (dm->support_ic_type == ODM_RTL8822B) + ret = config_phydm_write_txagc_8822b( + dm, power_index, path, hw_rate); + } + } + + return ret; +} + +static u8 phydm_api_get_txagc(struct phy_dm_struct *dm, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u8 ret = 0; + + if (dm->support_ic_type & ODM_RTL8822B) + ret = config_phydm_read_txagc_8822b(dm, path, hw_rate); + + return ret; +} + +static bool phydm_api_switch_bw_channel(struct phy_dm_struct *dm, u8 central_ch, + u8 primary_ch_idx, + enum odm_bw bandwidth) +{ + bool ret = false; + + if (dm->support_ic_type & ODM_RTL8822B) + ret = config_phydm_switch_channel_bw_8822b( + dm, central_ch, primary_ch_idx, bandwidth); + + return ret; +} + +bool phydm_api_trx_mode(struct phy_dm_struct *dm, enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path) +{ + bool ret = false; + + if (dm->support_ic_type & ODM_RTL8822B) + ret = config_phydm_trx_mode_8822b(dm, tx_path, rx_path, + is_tx2_path); + + return ret; +} + +static void phydm_get_per_path_txagc(void *dm_void, u8 path, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 rate_idx; + u8 txagc; + u32 used = *_used; + u32 out_len = *_out_len; + + if (((dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) && + (path <= ODM_RF_PATH_B)) || + ((dm->support_ic_type & (ODM_RTL8821C)) && + (path <= ODM_RF_PATH_A))) { + for (rate_idx = 0; rate_idx <= 0x53; rate_idx++) { + if (rate_idx == ODM_RATE1M) + PHYDM_SNPRINTF(output + used, out_len - used, + " %-35s\n", "CCK====>"); + else if (rate_idx == ODM_RATE6M) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "OFDM====>"); + else if (rate_idx == ODM_RATEMCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 1ss====>"); + else if (rate_idx == ODM_RATEMCS8) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 2ss====>"); + else if (rate_idx == ODM_RATEMCS16) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 3ss====>"); + else if (rate_idx == ODM_RATEMCS24) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "HT 4ss====>"); + else if (rate_idx == ODM_RATEVHTSS1MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 1ss====>"); + else if (rate_idx == ODM_RATEVHTSS2MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 2ss====>"); + else if (rate_idx == ODM_RATEVHTSS3MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 3ss====>"); + else if (rate_idx == ODM_RATEVHTSS4MCS0) + PHYDM_SNPRINTF(output + used, out_len - used, + "\n %-35s\n", "VHT 4ss====>"); + + txagc = phydm_api_get_txagc( + dm, (enum odm_rf_radio_path)path, rate_idx); + if (config_phydm_read_txagc_check(txagc)) + PHYDM_SNPRINTF(output + used, out_len - used, + " 0x%02x ", txagc); + else + PHYDM_SNPRINTF(output + used, out_len - used, + " 0x%s ", "xx"); + } + } +} + +static void phydm_get_txagc(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + + /* path-A */ + PHYDM_SNPRINTF(output + used, out_len - used, "%-35s\n", + "path-A===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_A, _used, output, _out_len); + + /* path-B */ + PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n", + "path-B===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_B, _used, output, _out_len); + + /* path-C */ + PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n", + "path-C===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_C, _used, output, _out_len); + + /* path-D */ + PHYDM_SNPRINTF(output + used, out_len - used, "\n%-35s\n", + "path-D===================="); + phydm_get_per_path_txagc(dm, ODM_RF_PATH_D, _used, output, _out_len); +} + +static void phydm_set_txagc(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 used = *_used; + u32 out_len = *_out_len; + + /*dm_value[1] = path*/ + /*dm_value[2] = hw_rate*/ + /*dm_value[3] = power_index*/ + + if (dm->support_ic_type & + (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C)) { + if (dm_value[1] <= 1) { + phydm_check_dmval_txagc(dm, used, out_len, dm_value, + output); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, + " %s%d %s%x%s\n", "Write path-", + (dm_value[1] & 0x1), "rate index-0x", + (dm_value[2] & 0x7f), " fail"); + } + } +} + +static void phydm_debug_trace(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 pre_debug_components, one = 1; + u32 used = *_used; + u32 out_len = *_out_len; + + pre_debug_components = dm->debug_components; + + PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n", + "================================"); + if (dm_value[0] == 100) { + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "[Debug Message] PhyDM Selection"); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + PHYDM_SNPRINTF(output + used, out_len - used, + "00. (( %s ))DIG\n", + ((dm->debug_components & ODM_COMP_DIG) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "01. (( %s ))RA_MASK\n", + ((dm->debug_components & ODM_COMP_RA_MASK) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, + "02. (( %s ))DYNAMIC_TXPWR\n", + ((dm->debug_components & ODM_COMP_DYNAMIC_TXPWR) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "03. (( %s ))FA_CNT\n", + ((dm->debug_components & ODM_COMP_FA_CNT) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "04. (( %s ))RSSI_MONITOR\n", + ((dm->debug_components & ODM_COMP_RSSI_MONITOR) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "05. (( %s ))SNIFFER\n", + ((dm->debug_components & ODM_COMP_SNIFFER) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "06. (( %s ))ANT_DIV\n", + ((dm->debug_components & ODM_COMP_ANT_DIV) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "07. (( %s ))DFS\n", + ((dm->debug_components & ODM_COMP_DFS) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "08. (( %s ))NOISY_DETECT\n", + ((dm->debug_components & ODM_COMP_NOISY_DETECT) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, + "09. (( %s ))RATE_ADAPTIVE\n", + ((dm->debug_components & ODM_COMP_RATE_ADAPTIVE) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "10. (( %s ))PATH_DIV\n", + ((dm->debug_components & ODM_COMP_PATH_DIV) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, + "12. (( %s ))DYNAMIC_PRICCA\n", + ((dm->debug_components & ODM_COMP_DYNAMIC_PRICCA) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "14. (( %s ))MP\n", + ((dm->debug_components & ODM_COMP_MP) ? ("V") : ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "15. (( %s ))struct cfo_tracking\n", + ((dm->debug_components & ODM_COMP_CFO_TRACKING) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "16. (( %s ))struct acs_info\n", + ((dm->debug_components & ODM_COMP_ACS) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "17. (( %s ))ADAPTIVITY\n", + ((dm->debug_components & PHYDM_COMP_ADAPTIVITY) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "18. (( %s ))RA_DBG\n", + ((dm->debug_components & PHYDM_COMP_RA_DBG) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "19. (( %s ))TXBF\n", + ((dm->debug_components & PHYDM_COMP_TXBF) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "20. (( %s ))EDCA_TURBO\n", + ((dm->debug_components & ODM_COMP_EDCA_TURBO) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "22. (( %s ))FW_DEBUG_TRACE\n", + ((dm->debug_components & ODM_FW_DEBUG_TRACE) ? + ("V") : + ("."))); + + PHYDM_SNPRINTF(output + used, out_len - used, + "24. (( %s ))TX_PWR_TRACK\n", + ((dm->debug_components & ODM_COMP_TX_PWR_TRACK) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "26. (( %s ))CALIBRATION\n", + ((dm->debug_components & ODM_COMP_CALIBRATION) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "28. (( %s ))PHY_CONFIG\n", + ((dm->debug_components & ODM_PHY_CONFIG) ? + ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "29. (( %s ))INIT\n", + ((dm->debug_components & ODM_COMP_INIT) ? ("V") : + ("."))); + PHYDM_SNPRINTF( + output + used, out_len - used, "30. (( %s ))COMMON\n", + ((dm->debug_components & ODM_COMP_COMMON) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "31. (( %s ))API\n", + ((dm->debug_components & ODM_COMP_API) ? ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + + } else if (dm_value[0] == 101) { + dm->debug_components = 0; + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "Disable all debug components"); + } else { + if (dm_value[1] == 1) /*enable*/ + dm->debug_components |= (one << dm_value[0]); + else if (dm_value[1] == 2) /*disable*/ + dm->debug_components &= ~(one << dm_value[0]); + else + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "[Warning!!!] 1:enable, 2:disable"); + } + PHYDM_SNPRINTF(output + used, out_len - used, + "pre-DbgComponents = 0x%x\n", pre_debug_components); + PHYDM_SNPRINTF(output + used, out_len - used, + "Curr-DbgComponents = 0x%x\n", dm->debug_components); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); +} + +static void phydm_fw_debug_trace(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 pre_fw_debug_components, one = 1; + u32 used = *_used; + u32 out_len = *_out_len; + + pre_fw_debug_components = dm->fw_debug_components; + + PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n", + "================================"); + if (dm_value[0] == 100) { + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "[FW Debug Component]"); + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + PHYDM_SNPRINTF( + output + used, out_len - used, "00. (( %s ))RA\n", + ((dm->fw_debug_components & PHYDM_FW_COMP_RA) ? ("V") : + ("."))); + + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "01. (( %s ))MU\n", + ((dm->fw_debug_components & PHYDM_FW_COMP_MU) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "02. (( %s ))path Div\n", + ((dm->fw_debug_components & + PHYDM_FW_COMP_PHY_CONFIG) ? + ("V") : + ("."))); + PHYDM_SNPRINTF(output + used, out_len - used, + "03. (( %s ))Phy Config\n", + ((dm->fw_debug_components & + PHYDM_FW_COMP_PHY_CONFIG) ? + ("V") : + ("."))); + } + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "================================"); + + } else { + if (dm_value[0] == 101) { + dm->fw_debug_components = 0; + PHYDM_SNPRINTF(output + used, out_len - used, "%s\n", + "Clear all fw debug components"); + } else { + if (dm_value[1] == 1) /*enable*/ + dm->fw_debug_components |= (one << dm_value[0]); + else if (dm_value[1] == 2) /*disable*/ + dm->fw_debug_components &= + ~(one << dm_value[0]); + else + PHYDM_SNPRINTF( + output + used, out_len - used, "%s\n", + "[Warning!!!] 1:enable, 2:disable"); + } + + if (dm->fw_debug_components == 0) { + dm->debug_components &= ~ODM_FW_DEBUG_TRACE; + phydm_fw_trace_en_h2c( + dm, false, dm->fw_debug_components, dm_value[2], + dm_value[3]); /*H2C to enable C2H Msg*/ + } else { + dm->debug_components |= ODM_FW_DEBUG_TRACE; + phydm_fw_trace_en_h2c( + dm, true, dm->fw_debug_components, dm_value[2], + dm_value[3]); /*H2C to enable C2H Msg*/ + } + } +} + +static void phydm_dump_bb_reg(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 addr = 0; + u32 used = *_used; + u32 out_len = *_out_len; + + /* For Nseries IC we only need to dump page8 to pageF using 3 digits*/ + for (addr = 0x800; addr < 0xfff; addr += 4) { + if (dm->support_ic_type & ODM_IC_11N_SERIES) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%03x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + else + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + + if (dm->support_ic_type & + (ODM_RTL8822B | ODM_RTL8814A | ODM_RTL8821C)) { + if (dm->rf_type > ODM_2T2R) { + for (addr = 0x1800; addr < 0x18ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + + if (dm->rf_type > ODM_3T3R) { + for (addr = 0x1a00; addr < 0x1aff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } + + for (addr = 0x1900; addr < 0x19ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + for (addr = 0x1c00; addr < 0x1cff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + for (addr = 0x1f00; addr < 0x1fff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + } +} + +static void phydm_dump_all_reg(void *dm_void, u32 *_used, char *output, + u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 addr = 0; + u32 used = *_used; + u32 out_len = *_out_len; + + /* dump MAC register */ + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "MAC==========\n"); + for (addr = 0; addr < 0x7ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + for (addr = 0x1000; addr < 0x17ff; addr += 4) + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "0x%04x 0x%08x\n", addr, + odm_get_bb_reg(dm, addr, MASKDWORD)); + + /* dump BB register */ + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "BB==========\n"); + phydm_dump_bb_reg(dm, &used, output, &out_len); + + /* dump RF register */ + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-A==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_A, addr, + RFREGOFFSETMASK)); + + if (dm->rf_type > ODM_1T1R) { + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-B==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_B, addr, + RFREGOFFSETMASK)); + } + + if (dm->rf_type > ODM_2T2R) { + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-C==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_C, addr, + RFREGOFFSETMASK)); + } + + if (dm->rf_type > ODM_3T3R) { + PHYDM_VAST_INFO_SNPRINTF(output + used, out_len - used, + "RF-D==========\n"); + for (addr = 0; addr < 0xFF; addr++) + PHYDM_VAST_INFO_SNPRINTF( + output + used, out_len - used, + "0x%02x 0x%05x\n", addr, + odm_get_rf_reg(dm, ODM_RF_PATH_D, addr, + RFREGOFFSETMASK)); + } +} + +static void phydm_enable_big_jump(struct phy_dm_struct *dm, bool state) +{ + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (!state) { + dm->dm_dig_table.enable_adjust_big_jump = false; + odm_set_bb_reg(dm, 0x8c8, 0xfe, + ((dig_tab->big_jump_step3 << 5) | + (dig_tab->big_jump_step2 << 3) | + dig_tab->big_jump_step1)); + } else { + dm->dm_dig_table.enable_adjust_big_jump = true; + } +} + +static void phydm_show_rx_rate(struct phy_dm_struct *dm, u32 *_used, + char *output, u32 *_out_len) +{ + u32 used = *_used; + u32 out_len = *_out_len; + + PHYDM_SNPRINTF(output + used, out_len - used, + "=====Rx SU rate Statistics=====\n"); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS0 = %d, 1SS MCS1 = %d, 1SS MCS2 = %d, 1SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[0], + dm->phy_dbg_info.num_qry_vht_pkt[1], + dm->phy_dbg_info.num_qry_vht_pkt[2], + dm->phy_dbg_info.num_qry_vht_pkt[3]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS4 = %d, 1SS MCS5 = %d, 1SS MCS6 = %d, 1SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[4], + dm->phy_dbg_info.num_qry_vht_pkt[5], + dm->phy_dbg_info.num_qry_vht_pkt[6], + dm->phy_dbg_info.num_qry_vht_pkt[7]); + PHYDM_SNPRINTF(output + used, out_len - used, + "1SS MCS8 = %d, 1SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[8], + dm->phy_dbg_info.num_qry_vht_pkt[9]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS0 = %d, 2SS MCS1 = %d, 2SS MCS2 = %d, 2SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[10], + dm->phy_dbg_info.num_qry_vht_pkt[11], + dm->phy_dbg_info.num_qry_vht_pkt[12], + dm->phy_dbg_info.num_qry_vht_pkt[13]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS4 = %d, 2SS MCS5 = %d, 2SS MCS6 = %d, 2SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[14], + dm->phy_dbg_info.num_qry_vht_pkt[15], + dm->phy_dbg_info.num_qry_vht_pkt[16], + dm->phy_dbg_info.num_qry_vht_pkt[17]); + PHYDM_SNPRINTF(output + used, out_len - used, + "2SS MCS8 = %d, 2SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_vht_pkt[18], + dm->phy_dbg_info.num_qry_vht_pkt[19]); + + PHYDM_SNPRINTF(output + used, out_len - used, + "=====Rx MU rate Statistics=====\n"); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS0 = %d, 1SS MCS1 = %d, 1SS MCS2 = %d, 1SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[0], + dm->phy_dbg_info.num_qry_mu_vht_pkt[1], + dm->phy_dbg_info.num_qry_mu_vht_pkt[2], + dm->phy_dbg_info.num_qry_mu_vht_pkt[3]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "1SS MCS4 = %d, 1SS MCS5 = %d, 1SS MCS6 = %d, 1SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[4], + dm->phy_dbg_info.num_qry_mu_vht_pkt[5], + dm->phy_dbg_info.num_qry_mu_vht_pkt[6], + dm->phy_dbg_info.num_qry_mu_vht_pkt[7]); + PHYDM_SNPRINTF(output + used, out_len - used, + "1SS MCS8 = %d, 1SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[8], + dm->phy_dbg_info.num_qry_mu_vht_pkt[9]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS0 = %d, 2SS MCS1 = %d, 2SS MCS2 = %d, 2SS MCS 3 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[10], + dm->phy_dbg_info.num_qry_mu_vht_pkt[11], + dm->phy_dbg_info.num_qry_mu_vht_pkt[12], + dm->phy_dbg_info.num_qry_mu_vht_pkt[13]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "2SS MCS4 = %d, 2SS MCS5 = %d, 2SS MCS6 = %d, 2SS MCS 7 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[14], + dm->phy_dbg_info.num_qry_mu_vht_pkt[15], + dm->phy_dbg_info.num_qry_mu_vht_pkt[16], + dm->phy_dbg_info.num_qry_mu_vht_pkt[17]); + PHYDM_SNPRINTF(output + used, out_len - used, + "2SS MCS8 = %d, 2SS MCS9 = %d\n", + dm->phy_dbg_info.num_qry_mu_vht_pkt[18], + dm->phy_dbg_info.num_qry_mu_vht_pkt[19]); +} + +struct phydm_command { + char name[16]; + u8 id; +}; + +enum PHYDM_CMD_ID { + PHYDM_HELP, + PHYDM_DEMO, + PHYDM_RA, + PHYDM_PROFILE, + PHYDM_ANTDIV, + PHYDM_PATHDIV, + PHYDM_DEBUG, + PHYDM_FW_DEBUG, + PHYDM_SUPPORT_ABILITY, + PHYDM_GET_TXAGC, + PHYDM_SET_TXAGC, + PHYDM_SMART_ANT, + PHYDM_API, + PHYDM_TRX_PATH, + PHYDM_LA_MODE, + PHYDM_DUMP_REG, + PHYDM_MU_MIMO, + PHYDM_HANG, + PHYDM_BIG_JUMP, + PHYDM_SHOW_RXRATE, + PHYDM_NBI_EN, + PHYDM_CSI_MASK_EN, + PHYDM_DFS, + PHYDM_IQK, + PHYDM_NHM, + PHYDM_CLM, + PHYDM_BB_INFO, + PHYDM_TXBF, + PHYDM_PAUSE_DIG_EN, + PHYDM_H2C, + PHYDM_ANT_SWITCH, + PHYDM_DYNAMIC_RA_PATH, + PHYDM_PSD, + PHYDM_DEBUG_PORT +}; + +static struct phydm_command phy_dm_ary[] = { + {"-h", PHYDM_HELP}, /*do not move this element to other position*/ + {"demo", PHYDM_DEMO}, /*do not move this element to other position*/ + {"ra", PHYDM_RA}, + {"profile", PHYDM_PROFILE}, + {"antdiv", PHYDM_ANTDIV}, + {"pathdiv", PHYDM_PATHDIV}, + {"dbg", PHYDM_DEBUG}, + {"fw_dbg", PHYDM_FW_DEBUG}, + {"ability", PHYDM_SUPPORT_ABILITY}, + {"get_txagc", PHYDM_GET_TXAGC}, + {"set_txagc", PHYDM_SET_TXAGC}, + {"smtant", PHYDM_SMART_ANT}, + {"api", PHYDM_API}, + {"trxpath", PHYDM_TRX_PATH}, + {"lamode", PHYDM_LA_MODE}, + {"dumpreg", PHYDM_DUMP_REG}, + {"mu", PHYDM_MU_MIMO}, + {"hang", PHYDM_HANG}, + {"bigjump", PHYDM_BIG_JUMP}, + {"rxrate", PHYDM_SHOW_RXRATE}, + {"nbi", PHYDM_NBI_EN}, + {"csi_mask", PHYDM_CSI_MASK_EN}, + {"dfs", PHYDM_DFS}, + {"iqk", PHYDM_IQK}, + {"nhm", PHYDM_NHM}, + {"clm", PHYDM_CLM}, + {"bbinfo", PHYDM_BB_INFO}, + {"txbf", PHYDM_TXBF}, + {"pause_dig", PHYDM_PAUSE_DIG_EN}, + {"h2c", PHYDM_H2C}, + {"ant_switch", PHYDM_ANT_SWITCH}, + {"drp", PHYDM_DYNAMIC_RA_PATH}, + {"psd", PHYDM_PSD}, + {"dbgport", PHYDM_DEBUG_PORT}, +}; + +void phydm_cmd_parser(struct phy_dm_struct *dm, char input[][MAX_ARGV], + u32 input_num, u8 flag, char *output, u32 out_len) +{ + u32 used = 0; + u8 id = 0; + int var1[10] = {0}; + int i, input_idx = 0, phydm_ary_size; + char help[] = "-h"; + + bool is_enable_dbg_mode; + u8 central_ch, primary_ch_idx, bandwidth; + + if (flag == 0) { + PHYDM_SNPRINTF(output + used, out_len - used, + "GET, nothing to print\n"); + return; + } + + PHYDM_SNPRINTF(output + used, out_len - used, "\n"); + + /* Parsing Cmd ID */ + if (input_num) { + phydm_ary_size = + sizeof(phy_dm_ary) / sizeof(struct phydm_command); + for (i = 0; i < phydm_ary_size; i++) { + if (strcmp(phy_dm_ary[i].name, input[0]) == 0) { + id = phy_dm_ary[i].id; + break; + } + } + if (i == phydm_ary_size) { + PHYDM_SNPRINTF(output + used, out_len - used, + "SET, command not found!\n"); + return; + } + } + + switch (id) { + case PHYDM_HELP: { + PHYDM_SNPRINTF(output + used, out_len - used, "BB cmd ==>\n"); + for (i = 0; i < phydm_ary_size - 2; i++) { + PHYDM_SNPRINTF(output + used, out_len - used, + " %-5d: %s\n", i, + phy_dm_ary[i + 2].name); + /**/ + } + } break; + + case PHYDM_DEMO: { /*echo demo 10 0x3a z abcde >cmd*/ + u32 directory = 0; + + char char_temp; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &directory); + PHYDM_SNPRINTF(output + used, out_len - used, + "Decimal value = %d\n", directory); + PHYDM_SSCANF(input[2], DCMD_HEX, &directory); + PHYDM_SNPRINTF(output + used, out_len - used, + "Hex value = 0x%x\n", directory); + PHYDM_SSCANF(input[3], DCMD_CHAR, &char_temp); + PHYDM_SNPRINTF(output + used, out_len - used, "Char = %c\n", + char_temp); + PHYDM_SNPRINTF(output + used, out_len - used, "String = %s\n", + input[4]); + } break; + + case PHYDM_RA: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_RA_debug_PCR(dm, (u32 *)var1, &used, output, + &out_len); + } + + break; + + case PHYDM_ANTDIV: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + + input_idx++; + } + } + + break; + + case PHYDM_PATHDIV: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + + input_idx++; + } + } + + break; + + case PHYDM_DEBUG: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_debug_trace(dm, (u32 *)var1, &used, output, + &out_len); + } + + break; + + case PHYDM_FW_DEBUG: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) + phydm_fw_debug_trace(dm, (u32 *)var1, &used, output, + &out_len); + + break; + + case PHYDM_SUPPORT_ABILITY: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_support_ability_debug(dm, (u32 *)var1, &used, + output, &out_len); + } + + break; + + case PHYDM_SMART_ANT: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + break; + + case PHYDM_API: + if (!(dm->support_ic_type & + (ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C))) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "This IC doesn't support PHYDM API function\n"); + } + + for (i = 0; i < 4; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + is_enable_dbg_mode = (bool)var1[0]; + central_ch = (u8)var1[1]; + primary_ch_idx = (u8)var1[2]; + bandwidth = (enum odm_bw)var1[3]; + + if (is_enable_dbg_mode) { + dm->is_disable_phy_api = false; + phydm_api_switch_bw_channel(dm, central_ch, + primary_ch_idx, + (enum odm_bw)bandwidth); + dm->is_disable_phy_api = true; + PHYDM_SNPRINTF( + output + used, out_len - used, + "central_ch = %d, primary_ch_idx = %d, bandwidth = %d\n", + central_ch, primary_ch_idx, bandwidth); + } else { + dm->is_disable_phy_api = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "Disable API debug mode\n"); + } + break; + + case PHYDM_PROFILE: /*echo profile, >cmd*/ + phydm_basic_profile(dm, &used, output, &out_len); + break; + + case PHYDM_GET_TXAGC: + phydm_get_txagc(dm, &used, output, &out_len); + break; + + case PHYDM_SET_TXAGC: { + bool is_enable_dbg_mode; + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + if ((strcmp(input[1], help) == 0)) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "{En} {pathA~D(0~3)} {rate_idx(Hex), All_rate:0xff} {txagc_idx (Hex)}\n"); + /**/ + + } else { + is_enable_dbg_mode = (bool)var1[0]; + if (is_enable_dbg_mode) { + dm->is_disable_phy_api = false; + phydm_set_txagc(dm, (u32 *)var1, &used, output, + &out_len); + dm->is_disable_phy_api = true; + } else { + dm->is_disable_phy_api = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "Disable API debug mode\n"); + } + } + } break; + + case PHYDM_TRX_PATH: + + for (i = 0; i < 4; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) { + u8 tx_path, rx_path; + bool is_enable_dbg_mode, is_tx2_path; + + is_enable_dbg_mode = (bool)var1[0]; + tx_path = (u8)var1[1]; + rx_path = (u8)var1[2]; + is_tx2_path = (bool)var1[3]; + + if (is_enable_dbg_mode) { + dm->is_disable_phy_api = false; + phydm_api_trx_mode( + dm, (enum odm_rf_path)tx_path, + (enum odm_rf_path)rx_path, is_tx2_path); + dm->is_disable_phy_api = true; + PHYDM_SNPRINTF( + output + used, out_len - used, + "tx_path = 0x%x, rx_path = 0x%x, is_tx2_path = %d\n", + tx_path, rx_path, is_tx2_path); + } else { + dm->is_disable_phy_api = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "Disable API debug mode\n"); + } + } else { + phydm_config_trx_path(dm, (u32 *)var1, &used, output, + &out_len); + } + break; + + case PHYDM_LA_MODE: + + dm->support_ability &= ~(ODM_BB_FA_CNT); + phydm_lamode_trigger_setting(dm, &input[0], &used, output, + &out_len, input_num); + dm->support_ability |= ODM_BB_FA_CNT; + + break; + + case PHYDM_DUMP_REG: { + u8 type = 0; + + if (input[1]) { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + type = (u8)var1[0]; + } + + if (type == 0) + phydm_dump_bb_reg(dm, &used, output, &out_len); + else if (type == 1) + phydm_dump_all_reg(dm, &used, output, &out_len); + } break; + + case PHYDM_MU_MIMO: + + if (input[1]) + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + else + var1[0] = 0; + + if (var1[0] == 1) { + PHYDM_SNPRINTF(output + used, out_len - used, + "Get MU BFee CSI\n"); + odm_set_bb_reg(dm, 0x9e8, BIT(17) | BIT(16), + 2); /*Read BFee*/ + odm_set_bb_reg(dm, 0x1910, BIT(15), + 1); /*Select BFee's CSI report*/ + odm_set_bb_reg(dm, 0x19b8, BIT(6), + 1); /*set as CSI report*/ + odm_set_bb_reg(dm, 0x19a8, 0xFFFF, + 0xFFFF); /*disable gated_clk*/ + phydm_print_csi(dm, used, out_len, output); + + } else if (var1[0] == 2) { + PHYDM_SSCANF(input[2], DCMD_DECIMAL, &var1[1]); + PHYDM_SNPRINTF(output + used, out_len - used, + "Get MU BFer's STA%d CSI\n", var1[1]); + odm_set_bb_reg(dm, 0x9e8, BIT(24), 0); /*Read BFer*/ + odm_set_bb_reg(dm, 0x9e8, BIT(25), + 1); /*enable Read/Write RAM*/ + odm_set_bb_reg(dm, 0x9e8, BIT(30) | BIT(29) | BIT(28), + var1[1]); /*read which STA's CSI report*/ + odm_set_bb_reg(dm, 0x1910, BIT(15), + 0); /*select BFer's CSI*/ + odm_set_bb_reg(dm, 0x19e0, 0x00003FC0, + 0xFF); /*disable gated_clk*/ + phydm_print_csi(dm, used, out_len, output); + } + break; + + case PHYDM_BIG_JUMP: { + if (input[1]) { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + phydm_enable_big_jump(dm, (bool)(var1[0])); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, + "unknown command!\n"); + } + break; + } + + case PHYDM_HANG: + phydm_bb_rx_hang_info(dm, &used, output, &out_len); + break; + + case PHYDM_SHOW_RXRATE: { + u8 rate_idx; + + if (input[1]) + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (var1[0] == 1) { + phydm_show_rx_rate(dm, &used, output, &out_len); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, + "Reset Rx rate counter\n"); + + for (rate_idx = 0; rate_idx < 40; rate_idx++) { + dm->phy_dbg_info.num_qry_vht_pkt[rate_idx] = 0; + dm->phy_dbg_info.num_qry_mu_vht_pkt[rate_idx] = + 0; + } + } + } break; + + case PHYDM_NBI_EN: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_api_debug(dm, PHYDM_API_NBI, (u32 *)var1, &used, + output, &out_len); + /**/ + } + + break; + + case PHYDM_CSI_MASK_EN: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + phydm_api_debug(dm, PHYDM_API_CSI_MASK, (u32 *)var1, + &used, output, &out_len); + /**/ + } + + break; + + case PHYDM_DFS: + break; + + case PHYDM_IQK: + break; + + case PHYDM_NHM: { + u8 target_rssi; + u16 nhm_period = 0xC350; /* 200ms */ + u8 IGI; + struct ccx_info *ccx_info = &dm->dm_ccx_info; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (input_num == 1) { + ccx_info->echo_NHM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Trigger NHM: echo nhm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Exclude CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Trigger NHM: echo nhm 2\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Include CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get NHM results: echo nhm 3\n"); + + return; + } + + /* NMH trigger */ + if ((var1[0] <= 2) && (var1[0] != 0)) { + ccx_info->echo_NHM_en = true; + ccx_info->echo_IGI = + (u8)odm_get_bb_reg(dm, 0xC50, MASKBYTE0); + + target_rssi = ccx_info->echo_IGI - 10; + + ccx_info->NHM_th[0] = (target_rssi - 15 + 10) * 2; + + for (i = 1; i <= 10; i++) + ccx_info->NHM_th[i] = + ccx_info->NHM_th[0] + 6 * i; + + /* 4 1. store previous NHM setting */ + phydm_nhm_setting(dm, STORE_NHM_SETTING); + + /* 4 2. Set NHM period, 0x990[31:16]=0xC350, + * Time duration for NHM unit: 4us, 0xC350=200ms + */ + ccx_info->NHM_period = nhm_period; + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Monitor NHM for %d us", + nhm_period * 4); + + /* 4 3. Set NHM inexclude_txon, inexclude_cca, ccx_en */ + + ccx_info->nhm_inexclude_cca = (var1[0] == 1) ? + NHM_EXCLUDE_CCA : + NHM_INCLUDE_CCA; + ccx_info->nhm_inexclude_txon = NHM_EXCLUDE_TXON; + + phydm_nhm_setting(dm, SET_NHM_SETTING); + phydm_print_nhm_trigger(output, used, out_len, + ccx_info); + + /* 4 4. Trigger NHM */ + phydm_nhm_trigger(dm); + } + + /*Get NHM results*/ + else if (var1[0] == 3) { + IGI = (u8)odm_get_bb_reg(dm, 0xC50, MASKBYTE0); + + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Cur_IGI = 0x%x", IGI); + + phydm_get_nhm_result(dm); + + /* 4 Resotre NHM setting */ + phydm_nhm_setting(dm, RESTORE_NHM_SETTING); + phydm_print_nhm_result(output, used, out_len, ccx_info); + + ccx_info->echo_NHM_en = false; + } else { + ccx_info->echo_NHM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Trigger NHM: echo nhm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Exclude CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Trigger NHM: echo nhm 2\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r (Include CCA)\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get NHM results: echo nhm 3\n"); + + return; + } + } break; + + case PHYDM_CLM: { + struct ccx_info *ccx_info = &dm->dm_ccx_info; + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (input_num == 1) { + ccx_info->echo_CLM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Trigger CLM: echo clm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get CLM results: echo clm 2\n"); + return; + } + + /* Set & trigger CLM */ + if (var1[0] == 1) { + ccx_info->echo_CLM_en = true; + ccx_info->CLM_period = 0xC350; /*100ms*/ + phydm_clm_setting(dm); + phydm_clm_trigger(dm); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n Monitor CLM for 200ms\n"); + } + + /* Get CLM results */ + else if (var1[0] == 2) { + ccx_info->echo_CLM_en = false; + phydm_get_cl_mresult(dm); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n CLM_result = %d us\n", + ccx_info->CLM_result * 4); + + } else { + ccx_info->echo_CLM_en = false; + PHYDM_SNPRINTF(output + used, out_len - used, + "\n\r Error command !\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Trigger CLM: echo clm 1\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "\r Get CLM results: echo clm 2\n"); + } + } break; + + case PHYDM_BB_INFO: { + s32 value32 = 0; + + phydm_bb_debug_info(dm, &used, output, &out_len); + + if (dm->support_ic_type & ODM_RTL8822B && input[1]) { + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + odm_set_bb_reg(dm, 0x1988, 0x003fff00, var1[0]); + value32 = odm_get_bb_reg(dm, 0xf84, MASKDWORD); + value32 = (value32 & 0xff000000) >> 24; + PHYDM_SNPRINTF( + output + used, out_len - used, + "\r\n %-35s = condition num = %d, subcarriers = %d\n", + "Over condition num subcarrier", var1[0], + value32); + odm_set_bb_reg(dm, 0x1988, BIT(22), + 0x0); /*disable report condition number*/ + } + } break; + + case PHYDM_TXBF: { + PHYDM_SNPRINTF(output + used, out_len - used, + "\r\n no TxBF !!\n"); + } break; + + case PHYDM_PAUSE_DIG_EN: + + for (i = 0; i < 5; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + if (var1[0] == 0) { + odm_pause_dig(dm, PHYDM_PAUSE, + PHYDM_PAUSE_LEVEL_7, (u8)var1[1]); + PHYDM_SNPRINTF(output + used, out_len - used, + "Set IGI_value = ((%x))\n", + var1[1]); + } else if (var1[0] == 1) { + odm_pause_dig(dm, PHYDM_RESUME, + PHYDM_PAUSE_LEVEL_7, (u8)var1[1]); + PHYDM_SNPRINTF(output + used, out_len - used, + "Resume IGI_value\n"); + } else { + PHYDM_SNPRINTF( + output + used, out_len - used, + "echo (1:pause, 2resume) (IGI_value)\n"); + } + } + break; + case PHYDM_H2C: + + for (i = 0; i < 8; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_HEX, &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) + phydm_h2C_debug(dm, (u32 *)var1, &used, output, + &out_len); + + break; + + case PHYDM_ANT_SWITCH: + + for (i = 0; i < 8; i++) { + if (input[i + 1]) { + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + input_idx++; + } + } + + if (input_idx >= 1) { + PHYDM_SNPRINTF(output + used, out_len - used, + "Not Support IC"); + } + + break; + + case PHYDM_DYNAMIC_RA_PATH: + + PHYDM_SNPRINTF(output + used, out_len - used, "Not Support IC"); + + break; + + case PHYDM_PSD: + + phydm_psd_debug(dm, &input[0], &used, output, &out_len, + input_num); + + break; + + case PHYDM_DEBUG_PORT: { + u32 dbg_port_value; + + PHYDM_SSCANF(input[1], DCMD_HEX, &var1[0]); + + if (phydm_set_bb_dbg_port(dm, BB_DBGPORT_PRIORITY_3, + var1[0])) { /*set debug port to 0x0*/ + + dbg_port_value = phydm_get_bb_dbg_port_value(dm); + phydm_release_bb_dbg_port(dm); + + PHYDM_SNPRINTF(output + used, out_len - used, + "Debug Port[0x%x] = ((0x%x))\n", var1[1], + dbg_port_value); + } + } break; + + default: + PHYDM_SNPRINTF(output + used, out_len - used, + "SET, unknown command!\n"); + break; + } +} + +s32 phydm_cmd(struct phy_dm_struct *dm, char *input, u32 in_len, u8 flag, + char *output, u32 out_len) +{ + char *token; + u32 argc = 0; + char argv[MAX_ARGC][MAX_ARGV]; + + do { + token = strsep(&input, ", "); + if (token) { + strcpy(argv[argc], token); + argc++; + } else { + break; + } + } while (argc < MAX_ARGC); + + if (argc == 1) + argv[0][strlen(argv[0]) - 1] = '\0'; + + phydm_cmd_parser(dm, argv, argc, flag, output, out_len); + + return 0; +} + +void phydm_fw_trace_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /*u8 debug_trace_11byte[60];*/ + u8 freg_num, c2h_seq, buf_0 = 0; + + if (!(dm->support_ic_type & PHYDM_IC_3081_SERIES)) + return; + + if (cmd_len > 12) + return; + + buf_0 = cmd_buf[0]; + freg_num = (buf_0 & 0xf); + c2h_seq = (buf_0 & 0xf0) >> 4; + + if ((c2h_seq != dm->pre_c2h_seq) && !dm->fw_buff_is_enpty) { + dm->fw_debug_trace[dm->c2h_cmd_start] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW Dbg Queue Overflow] %s\n", + dm->fw_debug_trace); + dm->c2h_cmd_start = 0; + } + + if ((cmd_len - 1) > (60 - dm->c2h_cmd_start)) { + dm->fw_debug_trace[dm->c2h_cmd_start] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW Dbg Queue error: wrong C2H length] %s\n", + dm->fw_debug_trace); + dm->c2h_cmd_start = 0; + return; + } + + strncpy((char *)&dm->fw_debug_trace[dm->c2h_cmd_start], + (char *)&cmd_buf[1], (cmd_len - 1)); + dm->c2h_cmd_start += (cmd_len - 1); + dm->fw_buff_is_enpty = false; + + if (freg_num == 0 || dm->c2h_cmd_start >= 60) { + if (dm->c2h_cmd_start < 60) + dm->fw_debug_trace[dm->c2h_cmd_start] = '\0'; + else + dm->fw_debug_trace[59] = '\0'; + + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s\n", + dm->fw_debug_trace); + /*dbg_print("[FW DBG Msg] %s\n", dm->fw_debug_trace);*/ + dm->c2h_cmd_start = 0; + dm->fw_buff_is_enpty = true; + } + + dm->pre_c2h_seq = c2h_seq; +} + +void phydm_fw_trace_handler_code(void *dm_void, u8 *buffer, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 function = buffer[0]; + u8 dbg_num = buffer[1]; + u16 content_0 = (((u16)buffer[3]) << 8) | ((u16)buffer[2]); + u16 content_1 = (((u16)buffer[5]) << 8) | ((u16)buffer[4]); + u16 content_2 = (((u16)buffer[7]) << 8) | ((u16)buffer[6]); + u16 content_3 = (((u16)buffer[9]) << 8) | ((u16)buffer[8]); + u16 content_4 = (((u16)buffer[11]) << 8) | ((u16)buffer[10]); + + if (cmd_len > 12) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW Msg] Invalid cmd length (( %d )) >12\n", + cmd_len); + + /*--------------------------------------------*/ + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "[FW][general][%d, %d, %d] = {%d, %d, %d, %d}\n", function, + dbg_num, content_0, content_1, content_2, content_3, + content_4); + /*--------------------------------------------*/ +} + +void phydm_fw_trace_handler_8051(void *dm_void, u8 *buffer, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + int i = 0; + u8 extend_c2h_sub_id = 0, extend_c2h_dbg_len = 0, + extend_c2h_dbg_seq = 0; + u8 fw_debug_trace[128]; + u8 *extend_c2h_dbg_content = NULL; + + if (cmd_len > 127) + return; + + extend_c2h_sub_id = buffer[0]; + extend_c2h_dbg_len = buffer[1]; + extend_c2h_dbg_content = buffer + 2; /*DbgSeq+DbgContent for show HEX*/ + +go_backfor_aggre_dbg_pkt: + i = 0; + extend_c2h_dbg_seq = buffer[2]; + extend_c2h_dbg_content = buffer + 3; + + for (;; i++) { + fw_debug_trace[i] = extend_c2h_dbg_content[i]; + if (extend_c2h_dbg_content[i + 1] == '\0') { + fw_debug_trace[i + 1] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s", + &fw_debug_trace[0]); + break; + } else if (extend_c2h_dbg_content[i] == '\n') { + fw_debug_trace[i + 1] = '\0'; + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "[FW DBG Msg] %s", + &fw_debug_trace[0]); + buffer = extend_c2h_dbg_content + i + 3; + goto go_backfor_aggre_dbg_pkt; + } + } +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_debug.h b/drivers/staging/rtlwifi/phydm/phydm_debug.h new file mode 100644 index 000000000000..f442f7c19595 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_debug.h @@ -0,0 +1,175 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_DBG_H__ +#define __ODM_DBG_H__ + +/*#define DEBUG_VERSION "1.1"*/ /*2015.07.29 YuChen*/ +/*#define DEBUG_VERSION "1.2"*/ /*2015.08.28 Dino*/ +#define DEBUG_VERSION "1.3" /*2016.04.28 YuChen*/ +#define ODM_DBG_TRACE 5 + +/*FW DBG MSG*/ +#define RATE_DECISION BIT(0) +#define INIT_RA_TABLE BIT(1) +#define RATE_UP BIT(2) +#define RATE_DOWN BIT(3) +#define TRY_DONE BIT(4) +#define RA_H2C BIT(5) +#define F_RATE_AP_RPT BIT(7) + +/* ----------------------------------------------------------------------------- + * Define the tracing components + * + * ----------------------------------------------------------------------------- + */ +/*BB FW Functions*/ +#define PHYDM_FW_COMP_RA BIT(0) +#define PHYDM_FW_COMP_MU BIT(1) +#define PHYDM_FW_COMP_PATH_DIV BIT(2) +#define PHYDM_FW_COMP_PHY_CONFIG BIT(3) + +/*BB Driver Functions*/ +#define ODM_COMP_DIG BIT(0) +#define ODM_COMP_RA_MASK BIT(1) +#define ODM_COMP_DYNAMIC_TXPWR BIT(2) +#define ODM_COMP_FA_CNT BIT(3) +#define ODM_COMP_RSSI_MONITOR BIT(4) +#define ODM_COMP_SNIFFER BIT(5) +#define ODM_COMP_ANT_DIV BIT(6) +#define ODM_COMP_DFS BIT(7) +#define ODM_COMP_NOISY_DETECT BIT(8) +#define ODM_COMP_RATE_ADAPTIVE BIT(9) +#define ODM_COMP_PATH_DIV BIT(10) +#define ODM_COMP_CCX BIT(11) + +#define ODM_COMP_DYNAMIC_PRICCA BIT(12) +/*BIT13 TBD*/ +#define ODM_COMP_MP BIT(14) +#define ODM_COMP_CFO_TRACKING BIT(15) +#define ODM_COMP_ACS BIT(16) +#define PHYDM_COMP_ADAPTIVITY BIT(17) +#define PHYDM_COMP_RA_DBG BIT(18) +#define PHYDM_COMP_TXBF BIT(19) +/* MAC Functions */ +#define ODM_COMP_EDCA_TURBO BIT(20) +#define ODM_COMP_DYNAMIC_RX_PATH BIT(21) +#define ODM_FW_DEBUG_TRACE BIT(22) +/* RF Functions */ +/*BIT23 TBD*/ +#define ODM_COMP_TX_PWR_TRACK BIT(24) +/*BIT25 TBD*/ +#define ODM_COMP_CALIBRATION BIT(26) +/* Common Functions */ +/*BIT27 TBD*/ +#define ODM_PHY_CONFIG BIT(28) +#define ODM_COMP_INIT BIT(29) +#define ODM_COMP_COMMON BIT(30) +#define ODM_COMP_API BIT(31) + +#define ODM_COMP_UNCOND 0xFFFFFFFF + +/*------------------------Export Marco Definition---------------------------*/ + +#define config_phydm_read_txagc_check(data) (data != INVALID_TXAGC_DATA) + +#define ODM_RT_TRACE(dm, comp, fmt, ...) \ + do { \ + if (((comp) & dm->debug_components) || \ + ((comp) == ODM_COMP_UNCOND)) \ + RT_TRACE(dm->adapter, COMP_PHYDM, DBG_DMESG, fmt, \ + ##__VA_ARGS__); \ + } while (0) + +#define BB_DBGPORT_PRIORITY_3 3 /*Debug function (the highest priority)*/ +#define BB_DBGPORT_PRIORITY_2 2 /*Check hang function & Strong function*/ +#define BB_DBGPORT_PRIORITY_1 1 /*Watch dog function*/ +#define BB_DBGPORT_RELEASE 0 /*Init value (the lowest priority)*/ + +void phydm_init_debug_setting(struct phy_dm_struct *dm); + +u8 phydm_set_bb_dbg_port(void *dm_void, u8 curr_dbg_priority, u32 debug_port); + +void phydm_release_bb_dbg_port(void *dm_void); + +u32 phydm_get_bb_dbg_port_value(void *dm_void); + +void phydm_basic_dbg_message(void *dm_void); + +#define PHYDM_DBGPRINT 0 +#define MAX_ARGC 20 +#define MAX_ARGV 16 +#define DCMD_DECIMAL "%d" +#define DCMD_CHAR "%c" +#define DCMD_HEX "%x" + +#define PHYDM_SSCANF(x, y, z) \ + do { \ + if (sscanf(x, y, z) != 1) \ + ODM_RT_TRACE(dm, ODM_COMP_UNCOND, \ + "%s:%d sscanf fail!", __func__, \ + __LINE__); \ + } while (0) + +#define PHYDM_VAST_INFO_SNPRINTF(msg, ...) \ + do { \ + snprintf(msg, ##__VA_ARGS__); \ + ODM_RT_TRACE(dm, ODM_COMP_UNCOND, output); \ + } while (0) + +#if (PHYDM_DBGPRINT == 1) +#define PHYDM_SNPRINTF(msg, ...) \ + do { \ + snprintf(msg, ##__VA_ARGS__); \ + ODM_RT_TRACE(dm, ODM_COMP_UNCOND, output); \ + } while (0) +#else +#define PHYDM_SNPRINTF(msg, ...) \ + do { \ + if (out_len > used) \ + used += snprintf(msg, ##__VA_ARGS__); \ + } while (0) +#endif + +void phydm_basic_profile(void *dm_void, u32 *_used, char *output, + u32 *_out_len); +s32 phydm_cmd(struct phy_dm_struct *dm, char *input, u32 in_len, u8 flag, + char *output, u32 out_len); +void phydm_cmd_parser(struct phy_dm_struct *dm, char input[][16], u32 input_num, + u8 flag, char *output, u32 out_len); + +bool phydm_api_trx_mode(struct phy_dm_struct *dm, enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path); + +void phydm_fw_trace_en_h2c(void *dm_void, bool enable, u32 fw_debug_component, + u32 monitor_mode, u32 macid); + +void phydm_fw_trace_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +void phydm_fw_trace_handler_code(void *dm_void, u8 *buffer, u8 cmd_len); + +void phydm_fw_trace_handler_8051(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +#endif /* __ODM_DBG_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_dfs.h b/drivers/staging/rtlwifi/phydm/phydm_dfs.h new file mode 100644 index 000000000000..59a1d08cf381 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dfs.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDM_DFS_H__ +#define __PHYDM_DFS_H__ + +#define DFS_VERSION "0.0" + +/* ============================================================ + * Definition + * ============================================================ + */ + +/* ============================================================ + * 1 structure + * ============================================================ + */ + +/* ============================================================ + * enumeration + * ============================================================ + */ + +enum phydm_dfs_region_domain { + PHYDM_DFS_DOMAIN_UNKNOWN = 0, + PHYDM_DFS_DOMAIN_FCC = 1, + PHYDM_DFS_DOMAIN_MKK = 2, + PHYDM_DFS_DOMAIN_ETSI = 3, +}; + +/* ============================================================ + * function prototype + * ============================================================ + */ +#define phydm_dfs_master_enabled(dm) false + +#endif /*#ifndef __PHYDM_DFS_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_dig.c b/drivers/staging/rtlwifi/phydm/phydm_dig.c new file mode 100644 index 000000000000..31a4f3fcad19 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dig.c @@ -0,0 +1,1535 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +static int get_igi_for_diff(int); + +static inline void phydm_check_ap_write_dig(struct phy_dm_struct *dm, + u8 current_igi) +{ + switch (*dm->one_path_cca) { + case ODM_CCA_2R: + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + + if (dm->rf_type > ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), + current_igi); + break; + case ODM_CCA_1R_A: + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + if (dm->rf_type != ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), + get_igi_for_diff(current_igi)); + break; + case ODM_CCA_1R_B: + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), + get_igi_for_diff(current_igi)); + if (dm->rf_type != ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + break; + } +} + +static inline u8 phydm_get_current_igi(u8 dig_max_of_min, u8 rssi_min, + u8 current_igi) +{ + if (rssi_min < dig_max_of_min) { + if (current_igi < rssi_min) + return rssi_min; + } else { + if (current_igi < dig_max_of_min) + return dig_max_of_min; + } + return current_igi; +} + +void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type, + u32 dm_value) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (dm_type == DIG_TYPE_THRESH_HIGH) { + dig_tab->rssi_high_thresh = dm_value; + } else if (dm_type == DIG_TYPE_THRESH_LOW) { + dig_tab->rssi_low_thresh = dm_value; + } else if (dm_type == DIG_TYPE_ENABLE) { + dig_tab->dig_enable_flag = true; + } else if (dm_type == DIG_TYPE_DISABLE) { + dig_tab->dig_enable_flag = false; + } else if (dm_type == DIG_TYPE_BACKOFF) { + if (dm_value > 30) + dm_value = 30; + dig_tab->backoff_val = (u8)dm_value; + } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) { + if (dm_value == 0) + dm_value = 0x1; + dig_tab->rx_gain_range_min = (u8)dm_value; + } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) { + if (dm_value > 0x50) + dm_value = 0x50; + dig_tab->rx_gain_range_max = (u8)dm_value; + } +} /* dm_change_dynamic_init_gain_thresh */ + +static int get_igi_for_diff(int value_IGI) +{ +#define ONERCCA_LOW_TH 0x30 +#define ONERCCA_LOW_DIFF 8 + + if (value_IGI < ONERCCA_LOW_TH) { + if ((ONERCCA_LOW_TH - value_IGI) < ONERCCA_LOW_DIFF) + return ONERCCA_LOW_TH; + else + return value_IGI + ONERCCA_LOW_DIFF; + } + + return value_IGI; +} + +static void odm_fa_threshold_check(void *dm_void, bool is_dfs_band, + bool is_performance, u32 rx_tp, u32 tx_tp, + u32 *dm_FA_thres) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->is_linked && (is_performance || is_dfs_band)) { + /*For NIC*/ + dm_FA_thres[0] = DM_DIG_FA_TH0; + dm_FA_thres[1] = DM_DIG_FA_TH1; + dm_FA_thres[2] = DM_DIG_FA_TH2; + } else { + if (is_dfs_band) { + /* For DFS band and no link */ + dm_FA_thres[0] = 250; + dm_FA_thres[1] = 1000; + dm_FA_thres[2] = 2000; + } else { + dm_FA_thres[0] = 2000; + dm_FA_thres[1] = 4000; + dm_FA_thres[2] = 5000; + } + } +} + +static u8 odm_forbidden_igi_check(void *dm_void, u8 dig_dynamic_min, + u8 current_igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct false_alarm_stat *fa_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + u8 rx_gain_range_min = dig_tab->rx_gain_range_min; + + if (dig_tab->large_fa_timeout) { + if (--dig_tab->large_fa_timeout == 0) + dig_tab->large_fa_hit = 0; + } + + if (fa_cnt->cnt_all > 10000) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Abnormally false alarm case.\n", __func__); + + if (dig_tab->large_fa_hit != 3) + dig_tab->large_fa_hit++; + + if (dig_tab->forbidden_igi < current_igi) { + dig_tab->forbidden_igi = current_igi; + dig_tab->large_fa_hit = 1; + dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT; + } + + if (dig_tab->large_fa_hit >= 3) { + if ((dig_tab->forbidden_igi + 2) > + dig_tab->rx_gain_range_max) + rx_gain_range_min = dig_tab->rx_gain_range_max; + else + rx_gain_range_min = + (dig_tab->forbidden_igi + 2); + dig_tab->recover_cnt = 1800; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Abnormally false alarm case: recover_cnt = %d\n", + __func__, dig_tab->recover_cnt); + } + } + + else if (fa_cnt->cnt_all > 2000) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "Abnormally false alarm case.\n"); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "cnt_all=%d, cnt_all_pre=%d, current_igi=0x%x, pre_ig_value=0x%x\n", + fa_cnt->cnt_all, fa_cnt->cnt_all_pre, current_igi, + dig_tab->pre_ig_value); + + /* fa_cnt->cnt_all = 1.1875*fa_cnt->cnt_all_pre */ + if ((fa_cnt->cnt_all > + (fa_cnt->cnt_all_pre + (fa_cnt->cnt_all_pre >> 3) + + (fa_cnt->cnt_all_pre >> 4))) && + (current_igi < dig_tab->pre_ig_value)) { + if (dig_tab->large_fa_hit != 3) + dig_tab->large_fa_hit++; + + if (dig_tab->forbidden_igi < current_igi) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "Updating forbidden_igi by current_igi, forbidden_igi=0x%x, current_igi=0x%x\n", + dig_tab->forbidden_igi, current_igi); + + dig_tab->forbidden_igi = current_igi; + dig_tab->large_fa_hit = 1; + dig_tab->large_fa_timeout = LARGE_FA_TIMEOUT; + } + } + + if (dig_tab->large_fa_hit >= 3) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "FaHit is greater than 3, rx_gain_range_max=0x%x, rx_gain_range_min=0x%x, forbidden_igi=0x%x\n", + dig_tab->rx_gain_range_max, rx_gain_range_min, + dig_tab->forbidden_igi); + + if ((dig_tab->forbidden_igi + 1) > + dig_tab->rx_gain_range_max) + rx_gain_range_min = dig_tab->rx_gain_range_max; + else + rx_gain_range_min = + (dig_tab->forbidden_igi + 1); + + dig_tab->recover_cnt = 1200; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "Abnormally false alarm case: recover_cnt = %d, rx_gain_range_min = 0x%x\n", + dig_tab->recover_cnt, rx_gain_range_min); + } + } else { + if (dig_tab->recover_cnt != 0) { + dig_tab->recover_cnt--; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Normal Case: recover_cnt = %d\n", + __func__, dig_tab->recover_cnt); + return rx_gain_range_min; + } + + if (dig_tab->large_fa_hit >= 3) { + dig_tab->large_fa_hit = 0; + return rx_gain_range_min; + } + + if ((dig_tab->forbidden_igi - 2) < + dig_dynamic_min) { /* DM_DIG_MIN) */ + dig_tab->forbidden_igi = + dig_dynamic_min; /* DM_DIG_MIN; */ + rx_gain_range_min = dig_dynamic_min; /* DM_DIG_MIN; */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Normal Case: At Lower Bound\n", + __func__); + } else { + if (dig_tab->large_fa_hit == 0) { + dig_tab->forbidden_igi -= 2; + rx_gain_range_min = + (dig_tab->forbidden_igi + 2); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Normal Case: Approach Lower Bound\n", + __func__); + } + } + } + + return rx_gain_range_min; +} + +static void phydm_set_big_jump_step(void *dm_void, u8 current_igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + u8 step1[8] = {24, 30, 40, 50, 60, 70, 80, 90}; + u8 i; + + if (dig_tab->enable_adjust_big_jump == 0) + return; + + for (i = 0; i <= dig_tab->big_jump_step1; i++) { + if ((current_igi + step1[i]) > + dig_tab->big_jump_lmt[dig_tab->agc_table_idx]) { + if (i != 0) + i = i - 1; + break; + } else if (i == dig_tab->big_jump_step1) { + break; + } + } + if (dm->support_ic_type & ODM_RTL8822B) + odm_set_bb_reg(dm, 0x8c8, 0xe, i); + else if (dm->support_ic_type & ODM_RTL8197F) + odm_set_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, 0xe, i); + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): bigjump = %d (ori = 0x%x), LMT=0x%x\n", __func__, i, + dig_tab->big_jump_step1, + dig_tab->big_jump_lmt[dig_tab->agc_table_idx]); +} + +void odm_write_dig(void *dm_void, u8 current_igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (dig_tab->is_stop_dig) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Stop Writing IGI\n", + __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): ODM_REG(IGI_A,dm)=0x%x, ODM_BIT(IGI,dm)=0x%x\n", + __func__, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + + /* 1 Check initial gain by upper bound */ + if ((!dig_tab->is_psd_in_progress) && dm->is_linked) { + if (current_igi > dig_tab->rx_gain_range_max) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): current_igi(0x%02x) is larger than upper bound !!\n", + __func__, current_igi); + current_igi = dig_tab->rx_gain_range_max; + } + if (dm->support_ability & ODM_BB_ADAPTIVITY && + dm->adaptivity_flag) { + if (current_igi > dm->adaptivity_igi_upper) + current_igi = dm->adaptivity_igi_upper; + + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): adaptivity case: Force upper bound to 0x%x !!!!!!\n", + __func__, current_igi); + } + } + + if (dig_tab->cur_ig_value != current_igi) { + /* Modify big jump step for 8822B and 8197F */ + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) + phydm_set_big_jump_step(dm, current_igi); + + /* Set IGI value of CCK for new CCK AGC */ + if (dm->cck_new_agc) { + if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) + odm_set_bb_reg(dm, 0xa0c, 0x00003f00, + (current_igi >> 1)); + } + + /*Add by YuChen for USB IO too slow issue*/ + if ((dm->support_ability & ODM_BB_ADAPTIVITY) && + (current_igi > dig_tab->cur_ig_value)) { + dig_tab->cur_ig_value = current_igi; + phydm_adaptivity(dm); + } + + /* 1 Set IGI value */ + if (dm->support_platform & (ODM_WIN | ODM_CE)) { + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), + current_igi); + + if (dm->rf_type > ODM_1T1R) + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), + ODM_BIT(IGI, dm), current_igi); + + } else if (dm->support_platform & (ODM_AP)) { + phydm_check_ap_write_dig(dm, current_igi); + } + + dig_tab->cur_ig_value = current_igi; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi(0x%02x).\n", __func__, + current_igi); +} + +void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, u8 igi_value) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + s8 max_level; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__, + pause_level); + + if ((dig_tab->pause_dig_level == 0) && + (!(dm->support_ability & ODM_BB_DIG) || + !(dm->support_ability & ODM_BB_FA_CNT))) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Return: support_ability DIG or FA is disabled !!\n", + __func__); + return; + } + + if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: Wrong pause level !!\n", __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_dig_level, igi_value); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_dig_value[7], + dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5], + dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3], + dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1], + dig_tab->pause_dig_value[0]); + + switch (pause_type) { + /* Pause DIG */ + case PHYDM_PAUSE: { + /* Disable DIG */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability & (~ODM_BB_DIG)); + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Pause DIG !!\n", + __func__); + + /* Backup IGI value */ + if (dig_tab->pause_dig_level == 0) { + dig_tab->igi_backup = dig_tab->cur_ig_value; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Backup IGI = 0x%x, new IGI = 0x%x\n", + __func__, dig_tab->igi_backup, igi_value); + } + + /* Record IGI value */ + dig_tab->pause_dig_value[pause_level] = igi_value; + + /* Update pause level */ + dig_tab->pause_dig_level = + (dig_tab->pause_dig_level | BIT(pause_level)); + + /* Write new IGI value */ + if (BIT(pause_level + 1) > dig_tab->pause_dig_level) { + odm_write_dig(dm, igi_value); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): IGI of higher level = 0x%x\n", + __func__, igi_value); + } + break; + } + /* Resume DIG */ + case PHYDM_RESUME: { + /* check if the level is illegal or not */ + if ((dig_tab->pause_dig_level & (BIT(pause_level))) != 0) { + dig_tab->pause_dig_level = dig_tab->pause_dig_level & + (~(BIT(pause_level))); + dig_tab->pause_dig_value[pause_level] = 0; + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Resume DIG !!\n", + __func__); + } else { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Wrong resume level !!\n", __func__); + break; + } + + /* Resume DIG */ + if (dig_tab->pause_dig_level == 0) { + /* Write backup IGI value */ + odm_write_dig(dm, dig_tab->igi_backup); + dig_tab->is_ignore_dig = true; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write original IGI = 0x%x\n", + __func__, dig_tab->igi_backup); + + /* Enable DIG */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability | ODM_BB_DIG); + break; + } + + if (BIT(pause_level) <= dig_tab->pause_dig_level) + break; + + /* Calculate the maximum level now */ + for (max_level = (pause_level - 1); max_level >= 0; + max_level--) { + if ((dig_tab->pause_dig_level & BIT(max_level)) > 0) + break; + } + + /* write IGI of lower level */ + odm_write_dig(dm, dig_tab->pause_dig_value[max_level]); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write IGI (0x%x) of level (%d)\n", __func__, + dig_tab->pause_dig_value[max_level], max_level); + break; + } + default: + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n", + __func__); + break; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_dig_level, igi_value); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_dig_value[7], + dig_tab->pause_dig_value[6], dig_tab->pause_dig_value[5], + dig_tab->pause_dig_value[4], dig_tab->pause_dig_value[3], + dig_tab->pause_dig_value[2], dig_tab->pause_dig_value[1], + dig_tab->pause_dig_value[0]); +} + +static bool odm_dig_abort(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + /* support_ability */ + if (!(dm->support_ability & ODM_BB_FA_CNT)) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Return: support_ability ODM_BB_FA_CNT is disabled\n", + __func__); + return true; + } + + /* support_ability */ + if (!(dm->support_ability & ODM_BB_DIG)) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Return: support_ability ODM_BB_DIG is disabled\n", + __func__); + return true; + } + + /* ScanInProcess */ + if (*dm->is_scan_in_process) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: In Scan Progress\n", __func__); + return true; + } + + if (dig_tab->is_ignore_dig) { + dig_tab->is_ignore_dig = false; + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Return: Ignore DIG\n", + __func__); + return true; + } + + /* add by Neil Chen to avoid PSD is processing */ + if (!dm->is_dm_initial_gain_enable) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: PSD is Processing\n", __func__); + return true; + } + + return false; +} + +void odm_dig_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + u32 ret_value; + u8 i; + + dig_tab->is_stop_dig = false; + dig_tab->is_ignore_dig = false; + dig_tab->is_psd_in_progress = false; + dig_tab->cur_ig_value = + (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + dig_tab->pre_ig_value = 0; + dig_tab->rssi_low_thresh = DM_DIG_THRESH_LOW; + dig_tab->rssi_high_thresh = DM_DIG_THRESH_HIGH; + dig_tab->fa_low_thresh = DM_FALSEALARM_THRESH_LOW; + dig_tab->fa_high_thresh = DM_FALSEALARM_THRESH_HIGH; + dig_tab->backoff_val = DM_DIG_BACKOFF_DEFAULT; + dig_tab->backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dig_tab->backoff_val_range_min = DM_DIG_BACKOFF_MIN; + dig_tab->pre_cck_cca_thres = 0xFF; + dig_tab->cur_cck_cca_thres = 0x83; + dig_tab->forbidden_igi = DM_DIG_MIN_NIC; + dig_tab->large_fa_hit = 0; + dig_tab->large_fa_timeout = 0; + dig_tab->recover_cnt = 0; + dig_tab->is_media_connect_0 = false; + dig_tab->is_media_connect_1 = false; + + /*To initialize dm->is_dm_initial_gain_enable==false to avoid DIG err*/ + dm->is_dm_initial_gain_enable = true; + + dig_tab->dig_dynamic_min_0 = DM_DIG_MIN_NIC; + dig_tab->dig_dynamic_min_1 = DM_DIG_MIN_NIC; + + /* To Initi BT30 IGI */ + dig_tab->bt30_cur_igi = 0x32; + + odm_memory_set(dm, dig_tab->pause_dig_value, 0, + (DM_DIG_MAX_PAUSE_TYPE + 1)); + dig_tab->pause_dig_level = 0; + odm_memory_set(dm, dig_tab->pause_cckpd_value, 0, + (DM_DIG_MAX_PAUSE_TYPE + 1)); + dig_tab->pause_cckpd_level = 0; + + if (dm->board_type & (ODM_BOARD_EXT_PA | ODM_BOARD_EXT_LNA)) { + dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC; + dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC; + } else { + dig_tab->rx_gain_range_max = DM_DIG_MAX_NIC; + dig_tab->rx_gain_range_min = DM_DIG_MIN_NIC; + } + + dig_tab->enable_adjust_big_jump = 1; + if (dm->support_ic_type & ODM_RTL8822B) { + ret_value = odm_get_bb_reg(dm, 0x8c8, MASKLWORD); + dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; + dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; + dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; + + } else if (dm->support_ic_type & ODM_RTL8197F) { + ret_value = + odm_get_bb_reg(dm, ODM_REG_BB_AGC_SET_2_11N, MASKLWORD); + dig_tab->big_jump_step1 = (u8)(ret_value & 0xe) >> 1; + dig_tab->big_jump_step2 = (u8)(ret_value & 0x30) >> 4; + dig_tab->big_jump_step3 = (u8)(ret_value & 0xc0) >> 6; + } + if (dm->support_ic_type & (ODM_RTL8822B | ODM_RTL8197F)) { + for (i = 0; i < sizeof(dig_tab->big_jump_lmt); i++) { + if (dig_tab->big_jump_lmt[i] == 0) + dig_tab->big_jump_lmt[i] = + 0x64; /* Set -10dBm as default value */ + } + } +} + +void odm_DIG(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /* Common parameters */ + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct false_alarm_stat *fa_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + bool first_connect, first_dis_connect; + u8 dig_max_of_min, dig_dynamic_min; + u8 dm_dig_max, dm_dig_min; + u8 current_igi = dig_tab->cur_ig_value; + u8 offset; + u32 dm_FA_thres[3]; + u32 tx_tp = 0, rx_tp = 0; + bool is_dfs_band = false; + bool is_performance = true, is_first_tp_target = false, + is_first_coverage = false; + + if (odm_dig_abort(dm)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG Start===>\n"); + + /* 1 Update status */ + { + dig_dynamic_min = dig_tab->dig_dynamic_min_0; + first_connect = (dm->is_linked) && !dig_tab->is_media_connect_0; + first_dis_connect = + (!dm->is_linked) && dig_tab->is_media_connect_0; + } + + /* 1 Boundary Decision */ + { + /* 2 For WIN\CE */ + if (dm->support_ic_type >= ODM_RTL8188E) + dm_dig_max = 0x5A; + else + dm_dig_max = DM_DIG_MAX_NIC; + + if (dm->support_ic_type != ODM_RTL8821) + dm_dig_min = DM_DIG_MIN_NIC; + else + dm_dig_min = 0x1C; + + dig_max_of_min = DM_DIG_MAX_AP; + + /* Modify lower bound for DFS band */ + if ((((*dm->channel >= 52) && (*dm->channel <= 64)) || + ((*dm->channel >= 100) && (*dm->channel <= 140))) && + phydm_dfs_master_enabled(dm)) { + is_dfs_band = true; + if (*dm->band_width == ODM_BW20M) + dm_dig_min = DM_DIG_MIN_AP_DFS + 2; + else + dm_dig_min = DM_DIG_MIN_AP_DFS; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: ====== In DFS band ======\n"); + } + } + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: Absolutly upper bound = 0x%x, lower bound = 0x%x\n", + dm_dig_max, dm_dig_min); + + if (dm->pu1_forced_igi_lb && (*dm->pu1_forced_igi_lb > 0)) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Force IGI lb to: 0x%02x\n", + *dm->pu1_forced_igi_lb); + dm_dig_min = *dm->pu1_forced_igi_lb; + dm_dig_max = (dm_dig_min <= dm_dig_max) ? (dm_dig_max) : + (dm_dig_min + 1); + } + + /* 1 Adjust boundary by RSSI */ + if (dm->is_linked && is_performance) { + /* 2 Modify DIG upper bound */ + /* 4 Modify DIG upper bound for 92E, 8723A\B, 8821 & 8812 BT */ + if ((dm->support_ic_type & (ODM_RTL8192E | ODM_RTL8723B | + ODM_RTL8812 | ODM_RTL8821)) && + (dm->is_bt_limited_dig == 1)) { + offset = 10; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Coex. case: Force upper bound to RSSI + %d\n", + offset); + } else { + offset = 15; + } + + if ((dm->rssi_min + offset) > dm_dig_max) + dig_tab->rx_gain_range_max = dm_dig_max; + else if ((dm->rssi_min + offset) < dm_dig_min) + dig_tab->rx_gain_range_max = dm_dig_min; + else + dig_tab->rx_gain_range_max = dm->rssi_min + offset; + + /* 2 Modify DIG lower bound */ + /* if(dm->is_one_entry_only) */ + { + if (dm->rssi_min < dm_dig_min) + dig_dynamic_min = dm_dig_min; + else if (dm->rssi_min > dig_max_of_min) + dig_dynamic_min = dig_max_of_min; + else + dig_dynamic_min = dm->rssi_min; + + if (is_dfs_band) { + dig_dynamic_min = dm_dig_min; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: DFS band: Force lower bound to 0x%x after link\n", + dm_dig_min); + } + } + } else { + if (is_performance && is_dfs_band) { + dig_tab->rx_gain_range_max = 0x28; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: DFS band: Force upper bound to 0x%x before link\n", + dig_tab->rx_gain_range_max); + } else { + if (is_performance) + dig_tab->rx_gain_range_max = DM_DIG_MAX_OF_MIN; + else + dig_tab->rx_gain_range_max = dm_dig_max; + } + dig_dynamic_min = dm_dig_min; + } + + /* 1 Force Lower Bound for AntDiv */ + if (dm->is_linked && !dm->is_one_entry_only && + (dm->support_ic_type & ODM_ANTDIV_SUPPORT) && + (dm->support_ability & ODM_BB_ANT_DIV)) { + if (dm->ant_div_type == CG_TRX_HW_ANTDIV || + dm->ant_div_type == CG_TRX_SMART_ANTDIV) { + if (dig_tab->ant_div_rssi_max > dig_max_of_min) + dig_dynamic_min = dig_max_of_min; + else + dig_dynamic_min = (u8)dig_tab->ant_div_rssi_max; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: AntDiv case: Force lower bound to 0x%x\n", + dig_dynamic_min); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: AntDiv case: rssi_max = 0x%x\n", + dig_tab->ant_div_rssi_max); + } + } + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Adjust boundary by RSSI Upper bound = 0x%x, Lower bound = 0x%x\n", + dig_tab->rx_gain_range_max, dig_dynamic_min); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Link status: is_linked = %d, RSSI = %d, bFirstConnect = %d, bFirsrDisConnect = %d\n", + dm->is_linked, dm->rssi_min, first_connect, first_dis_connect); + + /* 1 Modify DIG lower bound, deal with abnormal case */ + /* 2 Abnormal false alarm case */ + if (is_dfs_band) { + dig_tab->rx_gain_range_min = dig_dynamic_min; + } else { + if (!dm->is_linked) { + dig_tab->rx_gain_range_min = dig_dynamic_min; + + if (first_dis_connect) + dig_tab->forbidden_igi = dig_dynamic_min; + } else { + dig_tab->rx_gain_range_min = odm_forbidden_igi_check( + dm, dig_dynamic_min, current_igi); + } + } + + /* 2 Abnormal # beacon case */ + if (dm->is_linked && !first_connect) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "Beacon Num (%d)\n", + dm->phy_dbg_info.num_qry_beacon_pkt); + if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) && + (dm->bsta_state)) { + dig_tab->rx_gain_range_min = 0x1c; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Abnrormal #beacon (%d) case in STA mode: Force lower bound to 0x%x\n", + dm->phy_dbg_info.num_qry_beacon_pkt, + dig_tab->rx_gain_range_min); + } + } + + /* 2 Abnormal lower bound case */ + if (dig_tab->rx_gain_range_min > dig_tab->rx_gain_range_max) { + dig_tab->rx_gain_range_min = dig_tab->rx_gain_range_max; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Abnrormal lower bound case: Force lower bound to 0x%x\n", + dig_tab->rx_gain_range_min); + } + + /* 1 False alarm threshold decision */ + odm_fa_threshold_check(dm, is_dfs_band, is_performance, rx_tp, tx_tp, + dm_FA_thres); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "DIG: False alarm threshold = %d, %d, %d\n", + dm_FA_thres[0], dm_FA_thres[1], dm_FA_thres[2]); + + /* 1 Adjust initial gain by false alarm */ + if (dm->is_linked && is_performance) { + /* 2 After link */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI after link\n"); + + if (is_first_tp_target || (first_connect && is_performance)) { + dig_tab->large_fa_hit = 0; + + if (is_dfs_band) { + u8 rssi = dm->rssi_min; + + current_igi = + (dm->rssi_min > 0x28) ? 0x28 : rssi; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: DFS band: One-shot to 0x28 upmost\n"); + } else { + current_igi = phydm_get_current_igi( + dig_max_of_min, dm->rssi_min, + current_igi); + } + + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: First connect case: IGI does on-shot to 0x%x\n", + current_igi); + + } else { + if (fa_cnt->cnt_all > dm_FA_thres[2]) + current_igi = current_igi + 4; + else if (fa_cnt->cnt_all > dm_FA_thres[1]) + current_igi = current_igi + 2; + else if (fa_cnt->cnt_all < dm_FA_thres[0]) + current_igi = current_igi - 2; + + /* 4 Abnormal # beacon case */ + if ((dm->phy_dbg_info.num_qry_beacon_pkt < 5) && + (fa_cnt->cnt_all < DM_DIG_FA_TH1) && + (dm->bsta_state)) { + current_igi = dig_tab->rx_gain_range_min; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: Abnormal #beacon (%d) case: IGI does one-shot to 0x%x\n", + dm->phy_dbg_info.num_qry_beacon_pkt, + current_igi); + } + } + } else { + /* 2 Before link */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: Adjust IGI before link\n"); + + if (first_dis_connect || is_first_coverage) { + current_igi = dm_dig_min; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "DIG: First disconnect case: IGI does on-shot to lower bound\n"); + } else { + if (fa_cnt->cnt_all > dm_FA_thres[2]) + current_igi = current_igi + 4; + else if (fa_cnt->cnt_all > dm_FA_thres[1]) + current_igi = current_igi + 2; + else if (fa_cnt->cnt_all < dm_FA_thres[0]) + current_igi = current_igi - 2; + } + } + + /* 1 Check initial gain by upper/lower bound */ + if (current_igi < dig_tab->rx_gain_range_min) + current_igi = dig_tab->rx_gain_range_min; + + if (current_igi > dig_tab->rx_gain_range_max) + current_igi = dig_tab->rx_gain_range_max; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG: cur_ig_value=0x%x, TotalFA = %d\n", + current_igi, fa_cnt->cnt_all); + + /* 1 Update status */ + if (dm->is_bt_hs_operation) { + if (dm->is_linked) { + if (dig_tab->bt30_cur_igi > (current_igi)) + odm_write_dig(dm, current_igi); + else + odm_write_dig(dm, dig_tab->bt30_cur_igi); + + dig_tab->is_media_connect_0 = dm->is_linked; + dig_tab->dig_dynamic_min_0 = dig_dynamic_min; + } else { + if (dm->is_link_in_process) + odm_write_dig(dm, 0x1c); + else if (dm->is_bt_connect_process) + odm_write_dig(dm, 0x28); + else + odm_write_dig(dm, dig_tab->bt30_cur_igi); + } + } else { /* BT is not using */ + odm_write_dig(dm, current_igi); + dig_tab->is_media_connect_0 = dm->is_linked; + dig_tab->dig_dynamic_min_0 = dig_dynamic_min; + } + ODM_RT_TRACE(dm, ODM_COMP_DIG, "DIG end\n"); +} + +void odm_dig_by_rssi_lps(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct false_alarm_stat *fa_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + + u8 rssi_lower = DM_DIG_MIN_NIC; /* 0x1E or 0x1C */ + u8 current_igi = dm->rssi_min; + + if (odm_dig_abort(dm)) + return; + + current_igi = current_igi + RSSI_OFFSET_DIG; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()==>\n", __func__); + + /* Using FW PS mode to make IGI */ + /* Adjust by FA in LPS MODE */ + if (fa_cnt->cnt_all > DM_DIG_FA_TH2_LPS) + current_igi = current_igi + 4; + else if (fa_cnt->cnt_all > DM_DIG_FA_TH1_LPS) + current_igi = current_igi + 2; + else if (fa_cnt->cnt_all < DM_DIG_FA_TH0_LPS) + current_igi = current_igi - 2; + + /* Lower bound checking */ + + /* RSSI Lower bound check */ + if ((dm->rssi_min - 10) > DM_DIG_MIN_NIC) + rssi_lower = (dm->rssi_min - 10); + else + rssi_lower = DM_DIG_MIN_NIC; + + /* Upper and Lower Bound checking */ + if (current_igi > DM_DIG_MAX_NIC) + current_igi = DM_DIG_MAX_NIC; + else if (current_igi < rssi_lower) + current_igi = rssi_lower; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): fa_cnt->cnt_all = %d\n", __func__, + fa_cnt->cnt_all); + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): dm->rssi_min = %d\n", __func__, + dm->rssi_min); + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): current_igi = 0x%x\n", __func__, + current_igi); + + odm_write_dig( + dm, + current_igi); /* odm_write_dig(dm, dig_tab->cur_ig_value); */ +} + +/* 3============================================================ + * 3 FASLE ALARM CHECK + * 3============================================================ + */ + +void odm_false_alarm_counter_statistics(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct false_alarm_stat *false_alm_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + struct rt_adcsmp *adc_smp = &dm->adcsmp; + u32 ret_value; + + if (!(dm->support_ability & ODM_BB_FA_CNT)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "%s()======>\n", __func__); + + if (dm->support_ic_type & ODM_IC_11N_SERIES) { + /* hold ofdm counter */ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), + 1); /* hold page C counter */ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), + 1); /* hold page D counter */ + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE1_11N, + MASKDWORD); + false_alm_cnt->cnt_fast_fsync = (ret_value & 0xffff); + false_alm_cnt->cnt_sb_search_fail = + ((ret_value & 0xffff0000) >> 16); + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE2_11N, + MASKDWORD); + false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff); + false_alm_cnt->cnt_parity_fail = + ((ret_value & 0xffff0000) >> 16); + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE3_11N, + MASKDWORD); + false_alm_cnt->cnt_rate_illegal = (ret_value & 0xffff); + false_alm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); + + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_FA_TYPE4_11N, + MASKDWORD); + false_alm_cnt->cnt_mcs_fail = (ret_value & 0xffff); + + false_alm_cnt->cnt_ofdm_fail = + false_alm_cnt->cnt_parity_fail + + false_alm_cnt->cnt_rate_illegal + + false_alm_cnt->cnt_crc8_fail + + false_alm_cnt->cnt_mcs_fail + + false_alm_cnt->cnt_fast_fsync + + false_alm_cnt->cnt_sb_search_fail; + + /* read CCK CRC32 counter */ + false_alm_cnt->cnt_cck_crc32_error = odm_get_bb_reg( + dm, ODM_REG_CCK_CRC32_ERROR_CNT_11N, MASKDWORD); + false_alm_cnt->cnt_cck_crc32_ok = odm_get_bb_reg( + dm, ODM_REG_CCK_CRC32_OK_CNT_11N, MASKDWORD); + + /* read OFDM CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11N, + MASKDWORD); + false_alm_cnt->cnt_ofdm_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff; + + /* read HT CRC32 counter */ + ret_value = + odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11N, MASKDWORD); + false_alm_cnt->cnt_ht_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff; + + /* read VHT CRC32 counter */ + false_alm_cnt->cnt_vht_crc32_error = 0; + false_alm_cnt->cnt_vht_crc32_ok = 0; + + { + /* hold cck counter */ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(12), 1); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, BIT(14), 1); + + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_LSB_11N, + MASKBYTE0); + false_alm_cnt->cnt_cck_fail = ret_value; + + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_FA_MSB_11N, + MASKBYTE3); + false_alm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; + + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11N, + MASKDWORD); + false_alm_cnt->cnt_cck_cca = + ((ret_value & 0xFF) << 8) | + ((ret_value & 0xFF00) >> 8); + } + + false_alm_cnt->cnt_all_pre = false_alm_cnt->cnt_all; + + false_alm_cnt->cnt_all = (false_alm_cnt->cnt_fast_fsync + + false_alm_cnt->cnt_sb_search_fail + + false_alm_cnt->cnt_parity_fail + + false_alm_cnt->cnt_rate_illegal + + false_alm_cnt->cnt_crc8_fail + + false_alm_cnt->cnt_mcs_fail + + false_alm_cnt->cnt_cck_fail); + + false_alm_cnt->cnt_cca_all = false_alm_cnt->cnt_ofdm_cca + + false_alm_cnt->cnt_cck_cca; + + if (dm->support_ic_type >= ODM_RTL8188E) { + /*reset false alarm counter registers*/ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), + 1); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTC_11N, BIT(31), + 0); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), + 1); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(27), + 0); + + /*update ofdm counter*/ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), + 0); /*update page C counter*/ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), + 0); /*update page D counter*/ + + /*reset CCK CCA counter*/ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(13) | BIT(12), 0); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(13) | BIT(12), 2); + + /*reset CCK FA counter*/ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(15) | BIT(14), 0); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11N, + BIT(15) | BIT(14), 2); + + /*reset CRC32 counter*/ + odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 1); + odm_set_bb_reg(dm, ODM_REG_PAGE_F_RST_11N, BIT(16), 0); + } + + /* Get debug port 0 */ + odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x0); + false_alm_cnt->dbg_port0 = + odm_get_bb_reg(dm, ODM_REG_RPT_11N, MASKDWORD); + + /* Get EDCCA flag */ + odm_set_bb_reg(dm, ODM_REG_DBG_RPT_11N, MASKDWORD, 0x208); + false_alm_cnt->edcca_flag = + (bool)odm_get_bb_reg(dm, ODM_REG_RPT_11N, BIT(30)); + + ODM_RT_TRACE( + dm, ODM_COMP_FA_CNT, + "[OFDM FA Detail] Parity_Fail = (( %d )), Rate_Illegal = (( %d )), CRC8_fail = (( %d )), Mcs_fail = (( %d )), Fast_Fsync = (( %d )), SB_Search_fail = (( %d ))\n", + false_alm_cnt->cnt_parity_fail, + false_alm_cnt->cnt_rate_illegal, + false_alm_cnt->cnt_crc8_fail, + false_alm_cnt->cnt_mcs_fail, + false_alm_cnt->cnt_fast_fsync, + false_alm_cnt->cnt_sb_search_fail); + } + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + u32 cck_enable; + + /* read OFDM FA counter */ + false_alm_cnt->cnt_ofdm_fail = + odm_get_bb_reg(dm, ODM_REG_OFDM_FA_11AC, MASKLWORD); + + /* Read CCK FA counter */ + false_alm_cnt->cnt_cck_fail = + odm_get_bb_reg(dm, ODM_REG_CCK_FA_11AC, MASKLWORD); + + /* read CCK/OFDM CCA counter */ + ret_value = + odm_get_bb_reg(dm, ODM_REG_CCK_CCA_CNT_11AC, MASKDWORD); + false_alm_cnt->cnt_ofdm_cca = (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_cck_cca = ret_value & 0xffff; + + /* read CCK CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_CCK_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_cck_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_cck_crc32_ok = ret_value & 0xffff; + + /* read OFDM CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_OFDM_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_ofdm_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ofdm_crc32_ok = ret_value & 0xffff; + + /* read HT CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_HT_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_ht_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_ht_crc32_ok = ret_value & 0xffff; + + /* read VHT CRC32 counter */ + ret_value = odm_get_bb_reg(dm, ODM_REG_VHT_CRC32_CNT_11AC, + MASKDWORD); + false_alm_cnt->cnt_vht_crc32_error = + (ret_value & 0xffff0000) >> 16; + false_alm_cnt->cnt_vht_crc32_ok = ret_value & 0xffff; + + /* reset OFDM FA counter */ + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); + odm_set_bb_reg(dm, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); + + /* reset CCK FA counter */ + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); + odm_set_bb_reg(dm, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); + + /* reset CCA counter */ + odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 1); + odm_set_bb_reg(dm, ODM_REG_RST_RPT_11AC, BIT(0), 0); + + cck_enable = + odm_get_bb_reg(dm, ODM_REG_BB_RX_PATH_11AC, BIT(28)); + if (cck_enable) { /* if(*dm->band_type == ODM_BAND_2_4G) */ + false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail + + false_alm_cnt->cnt_cck_fail; + false_alm_cnt->cnt_cca_all = + false_alm_cnt->cnt_cck_cca + + false_alm_cnt->cnt_ofdm_cca; + } else { + false_alm_cnt->cnt_all = false_alm_cnt->cnt_ofdm_fail; + false_alm_cnt->cnt_cca_all = + false_alm_cnt->cnt_ofdm_cca; + } + + if (adc_smp->adc_smp_state == ADCSMP_STATE_IDLE) { + if (phydm_set_bb_dbg_port( + dm, BB_DBGPORT_PRIORITY_1, + 0x0)) { /*set debug port to 0x0*/ + false_alm_cnt->dbg_port0 = + phydm_get_bb_dbg_port_value(dm); + phydm_release_bb_dbg_port(dm); + } + + if (phydm_set_bb_dbg_port( + dm, BB_DBGPORT_PRIORITY_1, + 0x209)) { /*set debug port to 0x0*/ + false_alm_cnt->edcca_flag = + (bool)((phydm_get_bb_dbg_port_value( + dm) & + BIT(30)) >> + 30); + phydm_release_bb_dbg_port(dm); + } + } + } + + false_alm_cnt->cnt_crc32_error_all = + false_alm_cnt->cnt_vht_crc32_error + + false_alm_cnt->cnt_ht_crc32_error + + false_alm_cnt->cnt_ofdm_crc32_error + + false_alm_cnt->cnt_cck_crc32_error; + false_alm_cnt->cnt_crc32_ok_all = false_alm_cnt->cnt_vht_crc32_ok + + false_alm_cnt->cnt_ht_crc32_ok + + false_alm_cnt->cnt_ofdm_crc32_ok + + false_alm_cnt->cnt_cck_crc32_ok; + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[CCA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_cca, false_alm_cnt->cnt_ofdm_cca, + false_alm_cnt->cnt_cca_all); + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[FA Cnt] {CCK, OFDM, Total} = {%d, %d, %d}\n", + false_alm_cnt->cnt_cck_fail, false_alm_cnt->cnt_ofdm_fail, + false_alm_cnt->cnt_all); + + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[CCK] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_cck_crc32_error, + false_alm_cnt->cnt_cck_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, "[OFDM]CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_ofdm_crc32_error, + false_alm_cnt->cnt_ofdm_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[ HT ] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_ht_crc32_error, + false_alm_cnt->cnt_ht_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[VHT] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_vht_crc32_error, + false_alm_cnt->cnt_vht_crc32_ok); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "[VHT] CRC32 {error, ok}= {%d, %d}\n", + false_alm_cnt->cnt_crc32_error_all, + false_alm_cnt->cnt_crc32_ok_all); + ODM_RT_TRACE(dm, ODM_COMP_FA_CNT, + "FA_Cnt: Dbg port 0x0 = 0x%x, EDCCA = %d\n\n", + false_alm_cnt->dbg_port0, false_alm_cnt->edcca_flag); +} + +/* 3============================================================ + * 3 CCK Packet Detect threshold + * 3============================================================ + */ + +void odm_pause_cck_packet_detection(void *dm_void, + enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, + u8 cck_pd_threshold) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + s8 max_level; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s()=========> level = %d\n", __func__, + pause_level); + + if ((dig_tab->pause_cckpd_level == 0) && + (!(dm->support_ability & ODM_BB_CCK_PD) || + !(dm->support_ability & ODM_BB_FA_CNT))) { + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "Return: support_ability ODM_BB_CCK_PD or ODM_BB_FA_CNT is disabled\n"); + return; + } + + if (pause_level > DM_DIG_MAX_PAUSE_TYPE) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Return: Wrong pause level !!\n", __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_cckpd_level, cck_pd_threshold); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_cckpd_value[7], + dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5], + dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3], + dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1], + dig_tab->pause_cckpd_value[0]); + + switch (pause_type) { + /* Pause CCK Packet Detection threshold */ + case PHYDM_PAUSE: { + /* Disable CCK PD */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability & (~ODM_BB_CCK_PD)); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Pause CCK packet detection threshold !!\n", + __func__); + + /*Backup original CCK PD threshold decided by CCK PD mechanism*/ + if (dig_tab->pause_cckpd_level == 0) { + dig_tab->cck_pd_backup = dig_tab->cur_cck_cca_thres; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): Backup CCKPD = 0x%x, new CCKPD = 0x%x\n", + __func__, dig_tab->cck_pd_backup, + cck_pd_threshold); + } + + /* Update pause level */ + dig_tab->pause_cckpd_level = + (dig_tab->pause_cckpd_level | BIT(pause_level)); + + /* Record CCK PD threshold */ + dig_tab->pause_cckpd_value[pause_level] = cck_pd_threshold; + + /* Write new CCK PD threshold */ + if (BIT(pause_level + 1) > dig_tab->pause_cckpd_level) { + odm_write_cck_cca_thres(dm, cck_pd_threshold); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): CCKPD of higher level = 0x%x\n", + __func__, cck_pd_threshold); + } + break; + } + /* Resume CCK Packet Detection threshold */ + case PHYDM_RESUME: { + /* check if the level is illegal or not */ + if ((dig_tab->pause_cckpd_level & (BIT(pause_level))) != 0) { + dig_tab->pause_cckpd_level = + dig_tab->pause_cckpd_level & + (~(BIT(pause_level))); + dig_tab->pause_cckpd_value[pause_level] = 0; + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Resume CCK PD !!\n", __func__); + } else { + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Wrong resume level !!\n", __func__); + break; + } + + /* Resume DIG */ + if (dig_tab->pause_cckpd_level == 0) { + /* Write backup IGI value */ + odm_write_cck_cca_thres(dm, dig_tab->cck_pd_backup); + /* dig_tab->is_ignore_dig = true; */ + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write original CCKPD = 0x%x\n", + __func__, dig_tab->cck_pd_backup); + + /* Enable DIG */ + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, + dm->support_ability | + ODM_BB_CCK_PD); + break; + } + + if (BIT(pause_level) <= dig_tab->pause_cckpd_level) + break; + + /* Calculate the maximum level now */ + for (max_level = (pause_level - 1); max_level >= 0; + max_level--) { + if ((dig_tab->pause_cckpd_level & BIT(max_level)) > 0) + break; + } + + /* write CCKPD of lower level */ + odm_write_cck_cca_thres(dm, + dig_tab->pause_cckpd_value[max_level]); + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): Write CCKPD (0x%x) of level (%d)\n", + __func__, dig_tab->pause_cckpd_value[max_level], + max_level); + break; + } + default: + ODM_RT_TRACE(dm, ODM_COMP_DIG, "%s(): Wrong type !!\n", + __func__); + break; + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, + "%s(): pause level = 0x%x, Current value = 0x%x\n", + __func__, dig_tab->pause_cckpd_level, cck_pd_threshold); + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "%s(): pause value = 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + __func__, dig_tab->pause_cckpd_value[7], + dig_tab->pause_cckpd_value[6], dig_tab->pause_cckpd_value[5], + dig_tab->pause_cckpd_value[4], dig_tab->pause_cckpd_value[3], + dig_tab->pause_cckpd_value[2], dig_tab->pause_cckpd_value[1], + dig_tab->pause_cckpd_value[0]); +} + +void odm_cck_packet_detection_thresh(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + struct false_alarm_stat *false_alm_cnt = + (struct false_alarm_stat *)phydm_get_structure( + dm, PHYDM_FALSEALMCNT); + u8 cur_cck_cca_thres = dig_tab->cur_cck_cca_thres, rssi_thd = 35; + + if ((!(dm->support_ability & ODM_BB_CCK_PD)) || + (!(dm->support_ability & ODM_BB_FA_CNT))) { + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: return==========\n"); + return; + } + + if (dm->ext_lna) + return; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: ==========>\n"); + + if (dig_tab->cck_fa_ma == 0xffffffff) + dig_tab->cck_fa_ma = false_alm_cnt->cnt_cck_fail; + else + dig_tab->cck_fa_ma = + ((dig_tab->cck_fa_ma << 1) + dig_tab->cck_fa_ma + + false_alm_cnt->cnt_cck_fail) >> + 2; + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: CCK FA moving average = %d\n", + dig_tab->cck_fa_ma); + + if (dm->is_linked) { + if (dm->rssi_min > rssi_thd) { + cur_cck_cca_thres = 0xcd; + } else if (dm->rssi_min > 20) { + if (dig_tab->cck_fa_ma > + ((DM_DIG_FA_TH1 >> 1) + (DM_DIG_FA_TH1 >> 3))) + cur_cck_cca_thres = 0xcd; + else if (dig_tab->cck_fa_ma < (DM_DIG_FA_TH0 >> 1)) + cur_cck_cca_thres = 0x83; + } else if (dm->rssi_min > 7) { + cur_cck_cca_thres = 0x83; + } else { + cur_cck_cca_thres = 0x40; + } + + } else { + if (dig_tab->cck_fa_ma > 0x400) + cur_cck_cca_thres = 0x83; + else if (dig_tab->cck_fa_ma < 0x200) + cur_cck_cca_thres = 0x40; + } + + { + odm_write_cck_cca_thres(dm, cur_cck_cca_thres); + } + + ODM_RT_TRACE(dm, ODM_COMP_DIG, "CCK_PD: cck_cca_th=((0x%x))\n\n", + cur_cck_cca_thres); +} + +void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dig_thres *dig_tab = &dm->dm_dig_table; + + if (dig_tab->cur_cck_cca_thres != + cur_cck_cca_thres) { /* modify by Guo.Mingzhi 2012-01-03 */ + odm_write_1byte(dm, ODM_REG(CCK_CCA, dm), cur_cck_cca_thres); + dig_tab->cck_fa_ma = 0xffffffff; + } + dig_tab->pre_cck_cca_thres = dig_tab->cur_cck_cca_thres; + dig_tab->cur_cck_cca_thres = cur_cck_cca_thres; +} + +bool phydm_dig_go_up_check(void *dm_void) +{ + bool ret = true; + + return ret; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_dig.h b/drivers/staging/rtlwifi/phydm/phydm_dig.h new file mode 100644 index 000000000000..af70aaec3b19 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dig.h @@ -0,0 +1,241 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDIG_H__ +#define __PHYDMDIG_H__ + +#define DIG_VERSION "1.32" /* 2016.09.02 YuChen. add CCK PD for 8197F*/ + +/* Pause DIG & CCKPD */ +#define DM_DIG_MAX_PAUSE_TYPE 0x7 + +enum dig_goupcheck_level { + DIG_GOUPCHECK_LEVEL_0, + DIG_GOUPCHECK_LEVEL_1, + DIG_GOUPCHECK_LEVEL_2 + +}; + +struct dig_thres { + bool is_stop_dig; /* for debug */ + bool is_ignore_dig; + bool is_psd_in_progress; + + u8 dig_enable_flag; + u8 dig_ext_port_stage; + + int rssi_low_thresh; + int rssi_high_thresh; + + u32 fa_low_thresh; + u32 fa_high_thresh; + + u8 cur_sta_connect_state; + u8 pre_sta_connect_state; + u8 cur_multi_sta_connect_state; + + u8 pre_ig_value; + u8 cur_ig_value; + u8 backup_ig_value; /* MP DIG */ + u8 bt30_cur_igi; + u8 igi_backup; + + s8 backoff_val; + s8 backoff_val_range_max; + s8 backoff_val_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + u8 rssi_val_min; + + u8 pre_cck_cca_thres; + u8 cur_cck_cca_thres; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 cck_pd_backup; + u8 pause_cckpd_level; + u8 pause_cckpd_value[DM_DIG_MAX_PAUSE_TYPE + 1]; + + u8 large_fa_hit; + u8 large_fa_timeout; /*if (large_fa_hit), monitor "large_fa_timeout" + *sec, if timeout, large_fa_hit=0 + */ + u8 forbidden_igi; + u32 recover_cnt; + + u8 dig_dynamic_min_0; + u8 dig_dynamic_min_1; + bool is_media_connect_0; + bool is_media_connect_1; + + u32 ant_div_rssi_max; + u32 rssi_max; + + u8 *is_p2p_in_process; + + u8 pause_dig_level; + u8 pause_dig_value[DM_DIG_MAX_PAUSE_TYPE + 1]; + + u32 cck_fa_ma; + enum dig_goupcheck_level dig_go_up_check_level; + u8 aaa_default; + + u8 rf_gain_idx; + u8 agc_table_idx; + u8 big_jump_lmt[16]; + u8 enable_adjust_big_jump : 1; + u8 big_jump_step1 : 3; + u8 big_jump_step2 : 2; + u8 big_jump_step3 : 2; +}; + +struct false_alarm_stat { + u32 cnt_parity_fail; + u32 cnt_rate_illegal; + u32 cnt_crc8_fail; + u32 cnt_mcs_fail; + u32 cnt_ofdm_fail; + u32 cnt_ofdm_fail_pre; /* For RTL8881A */ + u32 cnt_cck_fail; + u32 cnt_all; + u32 cnt_all_pre; + u32 cnt_fast_fsync; + u32 cnt_sb_search_fail; + u32 cnt_ofdm_cca; + u32 cnt_cck_cca; + u32 cnt_cca_all; + u32 cnt_bw_usc; /* Gary */ + u32 cnt_bw_lsc; /* Gary */ + u32 cnt_cck_crc32_error; + u32 cnt_cck_crc32_ok; + u32 cnt_ofdm_crc32_error; + u32 cnt_ofdm_crc32_ok; + u32 cnt_ht_crc32_error; + u32 cnt_ht_crc32_ok; + u32 cnt_vht_crc32_error; + u32 cnt_vht_crc32_ok; + u32 cnt_crc32_error_all; + u32 cnt_crc32_ok_all; + bool cck_block_enable; + bool ofdm_block_enable; + u32 dbg_port0; + bool edcca_flag; +}; + +enum dm_dig_op { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}; + +enum phydm_pause_type { PHYDM_PAUSE = BIT(0), PHYDM_RESUME = BIT(1) }; + +enum phydm_pause_level { + /* number of pause level can't exceed DM_DIG_MAX_PAUSE_TYPE */ + PHYDM_PAUSE_LEVEL_0 = 0, + PHYDM_PAUSE_LEVEL_1 = 1, + PHYDM_PAUSE_LEVEL_2 = 2, + PHYDM_PAUSE_LEVEL_3 = 3, + PHYDM_PAUSE_LEVEL_4 = 4, + PHYDM_PAUSE_LEVEL_5 = 5, + PHYDM_PAUSE_LEVEL_6 = 6, + PHYDM_PAUSE_LEVEL_7 = DM_DIG_MAX_PAUSE_TYPE /* maximum level */ +}; + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX_NIC 0x3e +#define DM_DIG_MIN_NIC 0x20 +#define DM_DIG_MAX_OF_MIN_NIC 0x3e + +#define DM_DIG_MAX_AP 0x3e +#define DM_DIG_MIN_AP 0x20 +#define DM_DIG_MAX_OF_MIN 0x2A /* 0x32 */ +#define DM_DIG_MIN_AP_DFS 0x20 + +#define DM_DIG_MAX_NIC_HP 0x46 +#define DM_DIG_MIN_NIC_HP 0x2e + +#define DM_DIG_MAX_AP_HP 0x42 +#define DM_DIG_MIN_AP_HP 0x30 + +/* vivi 92c&92d has different definition, 20110504 + * this is for 92c + */ +#define DM_DIG_FA_TH0 0x200 /* 0x20 */ + +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 +/* this is for 92d */ +#define DM_DIG_FA_TH0_92D 0x100 +#define DM_DIG_FA_TH1_92D 0x400 +#define DM_DIG_FA_TH2_92D 0x600 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define DM_DIG_FA_TH0_LPS 4 /* -> 4 in lps */ +#define DM_DIG_FA_TH1_LPS 15 /* -> 15 lps */ +#define DM_DIG_FA_TH2_LPS 30 /* -> 30 lps */ +#define RSSI_OFFSET_DIG 0x05 +#define LARGE_FA_TIMEOUT 60 + +void odm_change_dynamic_init_gain_thresh(void *dm_void, u32 dm_type, + u32 dm_value); + +void odm_write_dig(void *dm_void, u8 current_igi); + +void odm_pause_dig(void *dm_void, enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, u8 igi_value); + +void odm_dig_init(void *dm_void); + +void odm_DIG(void *dm_void); + +void odm_dig_by_rssi_lps(void *dm_void); + +void odm_false_alarm_counter_statistics(void *dm_void); + +void odm_pause_cck_packet_detection(void *dm_void, + enum phydm_pause_type pause_type, + enum phydm_pause_level pause_level, + u8 cck_pd_threshold); + +void odm_cck_packet_detection_thresh(void *dm_void); + +void odm_write_cck_cca_thres(void *dm_void, u8 cur_cck_cca_thres); + +bool phydm_dig_go_up_check(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h b/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h new file mode 100644 index 000000000000..9f3cb2468c02 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamic_rx_path.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDYMICRXPATH_H__ +#define __PHYDMDYMICRXPATH_H__ + +#define DYNAMIC_RX_PATH_VERSION "1.0" /*2016.07.15 Dino */ + +#define DRP_RSSI_TH 35 + +#define INIT_DRP_TIMMER 0 +#define CANCEL_DRP_TIMMER 1 +#define RELEASE_DRP_TIMMER 2 + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c new file mode 100644 index 000000000000..7661c499aeb1 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.c @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +static inline void phydm_update_rf_state(struct phy_dm_struct *dm, + struct dyn_pwr_saving *dm_ps_table, + int _rssi_up_bound, + int _rssi_low_bound, + int _is_force_in_normal) +{ + if (_is_force_in_normal) { + dm_ps_table->cur_rf_state = rf_normal; + return; + } + + if (dm->rssi_min == 0xFF) { + dm_ps_table->cur_rf_state = RF_MAX; + return; + } + + if (dm_ps_table->pre_rf_state == rf_normal) { + if (dm->rssi_min >= _rssi_up_bound) + dm_ps_table->cur_rf_state = rf_save; + else + dm_ps_table->cur_rf_state = rf_normal; + } else { + if (dm->rssi_min <= _rssi_low_bound) + dm_ps_table->cur_rf_state = rf_normal; + else + dm_ps_table->cur_rf_state = rf_save; + } +} + +void odm_dynamic_bb_power_saving_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dyn_pwr_saving *dm_ps_table = &dm->dm_ps_table; + + dm_ps_table->pre_cca_state = CCA_MAX; + dm_ps_table->cur_cca_state = CCA_MAX; + dm_ps_table->pre_rf_state = RF_MAX; + dm_ps_table->cur_rf_state = RF_MAX; + dm_ps_table->rssi_val_min = 0; + dm_ps_table->initialize = 0; +} + +void odm_rf_saving(void *dm_void, u8 is_force_in_normal) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dyn_pwr_saving *dm_ps_table = &dm->dm_ps_table; + u8 rssi_up_bound = 30; + u8 rssi_low_bound = 25; + + if (dm->patch_id == 40) { /* RT_CID_819x_FUNAI_TV */ + rssi_up_bound = 50; + rssi_low_bound = 45; + } + if (dm_ps_table->initialize == 0) { + dm_ps_table->reg874 = + (odm_get_bb_reg(dm, 0x874, MASKDWORD) & 0x1CC000) >> 14; + dm_ps_table->regc70 = + (odm_get_bb_reg(dm, 0xc70, MASKDWORD) & BIT(3)) >> 3; + dm_ps_table->reg85c = + (odm_get_bb_reg(dm, 0x85c, MASKDWORD) & 0xFF000000) >> + 24; + dm_ps_table->rega74 = + (odm_get_bb_reg(dm, 0xa74, MASKDWORD) & 0xF000) >> 12; + /* Reg818 = phy_query_bb_reg(adapter, 0x818, MASKDWORD); */ + dm_ps_table->initialize = 1; + } + + phydm_update_rf_state(dm, dm_ps_table, rssi_up_bound, rssi_low_bound, + is_force_in_normal); + + if (dm_ps_table->pre_rf_state != dm_ps_table->cur_rf_state) { + if (dm_ps_table->cur_rf_state == rf_save) { + odm_set_bb_reg(dm, 0x874, 0x1C0000, + 0x2); /* reg874[20:18]=3'b010 */ + odm_set_bb_reg(dm, 0xc70, BIT(3), + 0); /* regc70[3]=1'b0 */ + odm_set_bb_reg(dm, 0x85c, 0xFF000000, + 0x63); /* reg85c[31:24]=0x63 */ + odm_set_bb_reg(dm, 0x874, 0xC000, + 0x2); /* reg874[15:14]=2'b10 */ + odm_set_bb_reg(dm, 0xa74, 0xF000, + 0x3); /* RegA75[7:4]=0x3 */ + odm_set_bb_reg(dm, 0x818, BIT(28), + 0x0); /* Reg818[28]=1'b0 */ + odm_set_bb_reg(dm, 0x818, BIT(28), + 0x1); /* Reg818[28]=1'b1 */ + } else { + odm_set_bb_reg(dm, 0x874, 0x1CC000, + dm_ps_table->reg874); + odm_set_bb_reg(dm, 0xc70, BIT(3), dm_ps_table->regc70); + odm_set_bb_reg(dm, 0x85c, 0xFF000000, + dm_ps_table->reg85c); + odm_set_bb_reg(dm, 0xa74, 0xF000, dm_ps_table->rega74); + odm_set_bb_reg(dm, 0x818, BIT(28), 0x0); + } + dm_ps_table->pre_rf_state = dm_ps_table->cur_rf_state; + } +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h new file mode 100644 index 000000000000..e7394c475395 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamicbbpowersaving.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDYNAMICBBPOWERSAVING_H__ +#define __PHYDMDYNAMICBBPOWERSAVING_H__ + +#define DYNAMIC_BBPWRSAV_VERSION "1.1" + +struct dyn_pwr_saving { + u8 pre_cca_state; + u8 cur_cca_state; + + u8 pre_rf_state; + u8 cur_rf_state; + + int rssi_val_min; + + u8 initialize; + u32 reg874, regc70, reg85c, rega74; +}; + +#define dm_rf_saving odm_rf_saving + +void odm_rf_saving(void *dm_void, u8 is_force_in_normal); + +void odm_dynamic_bb_power_saving_init(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c new file mode 100644 index 000000000000..ebb43342b80b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.c @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +void odm_dynamic_tx_power_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + dm->last_dtp_lvl = tx_high_pwr_level_normal; + dm->dynamic_tx_high_power_lvl = tx_high_pwr_level_normal; + dm->tx_agc_ofdm_18_6 = + odm_get_bb_reg(dm, 0xC24, MASKDWORD); /*TXAGC {18M 12M 9M 6M}*/ +} + +void odm_dynamic_tx_power_save_power_index(void *dm_void) {} + +void odm_dynamic_tx_power_restore_power_index(void *dm_void) {} + +void odm_dynamic_tx_power_write_power_index(void *dm_void, u8 value) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 index; + u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a}; + + for (index = 0; index < 6; index++) + odm_write_1byte(dm, power_index_reg[index], value); +} + +static void odm_dynamic_tx_power_nic_ce(void *dm_void) {} + +void odm_dynamic_tx_power(void *dm_void) +{ + /* */ + /* For AP/ADSL use struct rtl8192cd_priv* */ + /* For CE/NIC use struct void* */ + /* */ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR)) + return; + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + switch (dm->support_platform) { + case ODM_WIN: + odm_dynamic_tx_power_nic(dm); + break; + case ODM_CE: + odm_dynamic_tx_power_nic_ce(dm); + break; + case ODM_AP: + odm_dynamic_tx_power_ap(dm); + break; + default: + break; + } +} + +void odm_dynamic_tx_power_nic(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_DYNAMIC_TXPWR)) + return; +} + +void odm_dynamic_tx_power_ap(void *dm_void + + ) +{ +} + +void odm_dynamic_tx_power_8821(void *dm_void, u8 *desc, u8 mac_id) {} diff --git a/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h new file mode 100644 index 000000000000..10bad1209db2 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_dynamictxpower.h @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMDYNAMICTXPOWER_H__ +#define __PHYDMDYNAMICTXPOWER_H__ + +/*#define DYNAMIC_TXPWR_VERSION "1.0"*/ +/*#define DYNAMIC_TXPWR_VERSION "1.3" */ /*2015.08.26, Add 8814 Dynamic TX pwr*/ +#define DYNAMIC_TXPWR_VERSION "1.4" /*2015.11.06,Add CE 8821A Dynamic TX pwr*/ + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 60 + +#define tx_high_pwr_level_normal 0 +#define tx_high_pwr_level_level1 1 +#define tx_high_pwr_level_level2 2 + +#define tx_high_pwr_level_bt1 3 +#define tx_high_pwr_level_bt2 4 +#define tx_high_pwr_level_15 5 +#define tx_high_pwr_level_35 6 +#define tx_high_pwr_level_50 7 +#define tx_high_pwr_level_70 8 +#define tx_high_pwr_level_100 9 + +void odm_dynamic_tx_power_init(void *dm_void); + +void odm_dynamic_tx_power_restore_power_index(void *dm_void); + +void odm_dynamic_tx_power_nic(void *dm_void); + +void odm_dynamic_tx_power_save_power_index(void *dm_void); + +void odm_dynamic_tx_power_write_power_index(void *dm_void, u8 value); + +void odm_dynamic_tx_power_8821(void *dm_void, u8 *desc, u8 mac_id); + +void odm_dynamic_tx_power(void *dm_void); + +void odm_dynamic_tx_power_ap(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c new file mode 100644 index 000000000000..753a9b9834e4 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.c @@ -0,0 +1,139 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +void odm_edca_turbo_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + dm->dm_edca_table.is_current_turbo_edca = false; + dm->dm_edca_table.is_cur_rdl_state = false; + + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial VO PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_VO_PARAM)); + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial VI PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_VI_PARAM)); + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial BE PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_BE_PARAM)); + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, "Orginial BK PARAM: 0x%x\n", + odm_read_4byte(dm, ODM_EDCA_BK_PARAM)); + +} /* ODM_InitEdcaTurbo */ + +void odm_edca_turbo_check(void *dm_void) +{ + /* For AP/ADSL use struct rtl8192cd_priv* */ + /* For CE/NIC use struct void* */ + + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, + "%s========================>\n", __func__); + + if (!(dm->support_ability & ODM_MAC_EDCA_TURBO)) + return; + + switch (dm->support_platform) { + case ODM_WIN: + + break; + + case ODM_CE: + odm_edca_turbo_check_ce(dm); + break; + } + ODM_RT_TRACE(dm, ODM_COMP_EDCA_TURBO, + "<========================%s\n", __func__); + +} /* odm_CheckEdcaTurbo */ + +void odm_edca_turbo_check_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + u64 cur_txok_cnt = 0; + u64 cur_rxok_cnt = 0; + u32 edca_be_ul = 0x5ea42b; + u32 edca_be_dl = 0x5ea42b; + u32 edca_be = 0x5ea42b; + bool is_cur_rdlstate; + bool edca_turbo_on = false; + + if (dm->wifi_test) + return; + + if (!dm->is_linked) { + rtlpriv->dm.is_any_nonbepkts = false; + return; + } + + if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) + rtlpriv->dm.is_any_nonbepkts = true; + rtlpriv->dm.dbginfo.num_non_be_pkt = 0; + + cur_txok_cnt = rtlpriv->stats.txbytesunicast_inperiod; + cur_rxok_cnt = rtlpriv->stats.rxbytesunicast_inperiod; + + /*b_bias_on_rx = false;*/ + edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && + (!rtlpriv->dm.disable_framebursting)) ? + true : + false; + + if (rtlpriv->mac80211.mode == WIRELESS_MODE_B) + goto label_exit; + + if (edca_turbo_on) { + is_cur_rdlstate = + (cur_rxok_cnt > cur_txok_cnt * 4) ? true : false; + + edca_be = is_cur_rdlstate ? edca_be_dl : edca_be_ul; + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM_8822B, edca_be); + rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate; + rtlpriv->dm.current_turbo_edca = true; + } else { + if (rtlpriv->dm.current_turbo_edca) { + u8 tmp = AC0_BE; + + rtlpriv->cfg->ops->set_hw_reg(rtlpriv->hw, + HW_VAR_AC_PARAM, + (u8 *)(&tmp)); + rtlpriv->dm.current_turbo_edca = false; + } + } + +label_exit: + rtlpriv->dm.is_any_nonbepkts = false; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h new file mode 100644 index 000000000000..5845b108a001 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_edcaturbocheck.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMEDCATURBOCHECK_H__ +#define __PHYDMEDCATURBOCHECK_H__ + +/*#define EDCATURBO_VERSION "2.1"*/ +#define EDCATURBO_VERSION "2.3" /*2015.07.29 by YuChen*/ + +struct edca_turbo { + bool is_current_turbo_edca; + bool is_cur_rdl_state; + + u32 prv_traffic_idx; /* edca turbo */ +}; + +void odm_edca_turbo_check(void *dm_void); +void odm_edca_turbo_init(void *dm_void); + +void odm_edca_turbo_check_ce(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_features.h b/drivers/staging/rtlwifi/phydm/phydm_features.h new file mode 100644 index 000000000000..37f6f0cd7235 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_features.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDM_FEATURES_H__ +#define __PHYDM_FEATURES + +/*phydm debyg report & tools*/ + +/*Antenna Diversity*/ + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c new file mode 100644 index 000000000000..0a1f11a926e4 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.c @@ -0,0 +1,1928 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ + +#include "mp_precomp.h" +#include "phydm_precomp.h" + +#define READ_AND_CONFIG_MP(ic, txt) (odm_read_and_config_mp_##ic##txt(dm)) +#define READ_AND_CONFIG_TC(ic, txt) (odm_read_and_config_tc_##ic##txt(dm)) + +#define READ_AND_CONFIG READ_AND_CONFIG_MP + +#define READ_FIRMWARE_MP(ic, txt) \ + (odm_read_firmware_mp_##ic##txt(dm, p_firmware, size)) +#define READ_FIRMWARE_TC(ic, txt) \ + (odm_read_firmware_tc_##ic##txt(dm, p_firmware, size)) + +#define READ_FIRMWARE READ_FIRMWARE_MP + +#define GET_VERSION_MP(ic, txt) (odm_get_version_mp_##ic##txt()) +#define GET_VERSION_TC(ic, txt) (odm_get_version_tc_##ic##txt()) + +#define GET_VERSION(ic, txt) GET_VERSION_MP(ic, txt) + +static u32 phydm_process_rssi_pwdb(struct phy_dm_struct *dm, + struct rtl_sta_info *entry, + struct dm_per_pkt_info *pktinfo, + u32 undecorated_smoothed_ofdm, + u32 undecorated_smoothed_cck) +{ + u32 weighting = 0, undecorated_smoothed_pwdb; + /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */ + + if (entry->rssi_stat.ofdm_pkt == + 64) { /* speed up when all packets are OFDM*/ + undecorated_smoothed_pwdb = undecorated_smoothed_ofdm; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "PWDB_0[%d] = (( %d ))\n", pktinfo->station_id, + undecorated_smoothed_cck); + } else { + if (entry->rssi_stat.valid_bit < 64) + entry->rssi_stat.valid_bit++; + + if (entry->rssi_stat.valid_bit == 64) { + weighting = ((entry->rssi_stat.ofdm_pkt) > 4) ? + 64 : + (entry->rssi_stat.ofdm_pkt << 4); + undecorated_smoothed_pwdb = + (weighting * undecorated_smoothed_ofdm + + (64 - weighting) * undecorated_smoothed_cck) >> + 6; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "PWDB_1[%d] = (( %d )), W = (( %d ))\n", + pktinfo->station_id, + undecorated_smoothed_cck, weighting); + } else { + if (entry->rssi_stat.valid_bit != 0) + undecorated_smoothed_pwdb = + (entry->rssi_stat.ofdm_pkt * + undecorated_smoothed_ofdm + + (entry->rssi_stat.valid_bit - + entry->rssi_stat.ofdm_pkt) * + undecorated_smoothed_cck) / + entry->rssi_stat.valid_bit; + else + undecorated_smoothed_pwdb = 0; + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "PWDB_2[%d] = (( %d )), ofdm_pkt = (( %d )), Valid_Bit = (( %d ))\n", + pktinfo->station_id, undecorated_smoothed_cck, + entry->rssi_stat.ofdm_pkt, + entry->rssi_stat.valid_bit); + } + } + + return undecorated_smoothed_pwdb; +} + +static u32 phydm_process_rssi_cck(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct rtl_sta_info *entry, + u32 undecorated_smoothed_cck) +{ + u32 rssi_ave; + u8 i; + + rssi_ave = phy_info->rx_pwdb_all; + dm->rssi_a = (u8)phy_info->rx_pwdb_all; + dm->rssi_b = 0xFF; + dm->rssi_c = 0xFF; + dm->rssi_d = 0xFF; + + if (entry->rssi_stat.cck_pkt <= 63) + entry->rssi_stat.cck_pkt++; + + /* 1 Process CCK RSSI */ + if (undecorated_smoothed_cck <= 0) { /* initialize */ + undecorated_smoothed_cck = phy_info->rx_pwdb_all; + entry->rssi_stat.cck_sum_power = + (u16)phy_info->rx_pwdb_all; /*reset*/ + entry->rssi_stat.cck_pkt = 1; /*reset*/ + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "CCK_INIT: (( %d ))\n", + undecorated_smoothed_cck); + } else if (entry->rssi_stat.cck_pkt <= CCK_RSSI_INIT_COUNT) { + entry->rssi_stat.cck_sum_power = + entry->rssi_stat.cck_sum_power + + (u16)phy_info->rx_pwdb_all; + undecorated_smoothed_cck = entry->rssi_stat.cck_sum_power / + entry->rssi_stat.cck_pkt; + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "CCK_0: (( %d )), SumPow = (( %d )), cck_pkt = (( %d ))\n", + undecorated_smoothed_cck, + entry->rssi_stat.cck_sum_power, + entry->rssi_stat.cck_pkt); + } else { + if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_cck) { + undecorated_smoothed_cck = + (((undecorated_smoothed_cck) * + (RX_SMOOTH_FACTOR - 1)) + + (phy_info->rx_pwdb_all)) / + (RX_SMOOTH_FACTOR); + undecorated_smoothed_cck = undecorated_smoothed_cck + 1; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "CCK_1: (( %d ))\n", + undecorated_smoothed_cck); + } else { + undecorated_smoothed_cck = + (((undecorated_smoothed_cck) * + (RX_SMOOTH_FACTOR - 1)) + + (phy_info->rx_pwdb_all)) / + (RX_SMOOTH_FACTOR); + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "CCK_2: (( %d ))\n", + undecorated_smoothed_cck); + } + } + + i = 63; + entry->rssi_stat.ofdm_pkt -= + (u8)((entry->rssi_stat.packet_map >> i) & BIT(0)); + entry->rssi_stat.packet_map = entry->rssi_stat.packet_map << 1; + return undecorated_smoothed_cck; +} + +static u32 phydm_process_rssi_ofdm(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct rtl_sta_info *entry, + u32 undecorated_smoothed_ofdm) +{ + u32 rssi_ave; + u8 rssi_max, rssi_min, i; + + if (dm->support_ic_type & (ODM_RTL8814A | ODM_RTL8822B)) { + u8 rx_count = 0; + u32 rssi_linear = 0; + + if (dm->rx_ant_status & ODM_RF_A) { + dm->rssi_a = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]); + } else { + dm->rssi_a = 0; + } + + if (dm->rx_ant_status & ODM_RF_B) { + dm->rssi_b = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]); + } else { + dm->rssi_b = 0; + } + + if (dm->rx_ant_status & ODM_RF_C) { + dm->rssi_c = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_C]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_C]); + } else { + dm->rssi_c = 0; + } + + if (dm->rx_ant_status & ODM_RF_D) { + dm->rssi_d = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_D]; + rx_count++; + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_D]); + } else { + dm->rssi_d = 0; + } + + /* Calculate average RSSI */ + switch (rx_count) { + case 2: + rssi_linear = (rssi_linear >> 1); + break; + case 3: + /* rssi_linear/3 ~ rssi_linear*11/32 */ + rssi_linear = ((rssi_linear) + (rssi_linear << 1) + + (rssi_linear << 3)) >> + 5; + break; + case 4: + rssi_linear = (rssi_linear >> 2); + break; + } + + rssi_ave = odm_convert_to_db(rssi_linear); + } else { + if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B] == 0) { + rssi_ave = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + dm->rssi_a = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + dm->rssi_b = 0; + } else { + dm->rssi_a = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + dm->rssi_b = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + + if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] > + phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) { + rssi_max = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + rssi_min = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + } else { + rssi_max = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_B]; + rssi_min = phy_info->rx_mimo_signal_strength + [ODM_RF_PATH_A]; + } + if ((rssi_max - rssi_min) < 3) + rssi_ave = rssi_max; + else if ((rssi_max - rssi_min) < 6) + rssi_ave = rssi_max - 1; + else if ((rssi_max - rssi_min) < 10) + rssi_ave = rssi_max - 2; + else + rssi_ave = rssi_max - 3; + } + } + + /* 1 Process OFDM RSSI */ + if (undecorated_smoothed_ofdm <= 0) { /* initialize */ + undecorated_smoothed_ofdm = phy_info->rx_pwdb_all; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, "OFDM_INIT: (( %d ))\n", + undecorated_smoothed_ofdm); + } else { + if (phy_info->rx_pwdb_all > (u32)undecorated_smoothed_ofdm) { + undecorated_smoothed_ofdm = + (((undecorated_smoothed_ofdm) * + (RX_SMOOTH_FACTOR - 1)) + + (rssi_ave)) / + (RX_SMOOTH_FACTOR); + undecorated_smoothed_ofdm = + undecorated_smoothed_ofdm + 1; + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "OFDM_1: (( %d ))\n", + undecorated_smoothed_ofdm); + } else { + undecorated_smoothed_ofdm = + (((undecorated_smoothed_ofdm) * + (RX_SMOOTH_FACTOR - 1)) + + (rssi_ave)) / + (RX_SMOOTH_FACTOR); + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "OFDM_2: (( %d ))\n", + undecorated_smoothed_ofdm); + } + } + + if (entry->rssi_stat.ofdm_pkt != 64) { + i = 63; + entry->rssi_stat.ofdm_pkt -= + (u8)(((entry->rssi_stat.packet_map >> i) & BIT(0)) - 1); + } + + entry->rssi_stat.packet_map = + (entry->rssi_stat.packet_map << 1) | BIT(0); + return undecorated_smoothed_ofdm; +} + +static u8 odm_evm_db_to_percentage(s8); +static u8 odm_evm_dbm_jaguar_series(s8); + +static inline u32 phydm_get_rssi_average(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info) +{ + u8 rssi_max = 0, rssi_min = 0; + + dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + + if (phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A] > + phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]) { + rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + } else { + rssi_max = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + rssi_min = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + } + if ((rssi_max - rssi_min) < 3) + return rssi_max; + else if ((rssi_max - rssi_min) < 6) + return rssi_max - 1; + else if ((rssi_max - rssi_min) < 10) + return rssi_max - 2; + else + return rssi_max - 3; +} + +static inline u8 phydm_get_evm_dbm(u8 i, u8 EVM, + struct phy_status_rpt_8812 *phy_sta_rpt, + struct dm_phy_status_info *phy_info) +{ + if (i < ODM_RF_PATH_C) + return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm[i]); + else + return odm_evm_dbm_jaguar_series(phy_sta_rpt->rxevm_cd[i - 2]); + /*RT_DISP(FRX, RX_PHY_SQ, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",*/ + /*pktinfo->data_rate, phy_sta_rpt->rxevm[i], "%", EVM));*/ +} + +static inline u8 phydm_get_odm_evm(u8 i, struct dm_per_pkt_info *pktinfo, + struct phy_status_rpt_8812 *phy_sta_rpt) +{ + u8 evm = 0; + + if (pktinfo->data_rate >= ODM_RATE6M && + pktinfo->data_rate <= ODM_RATE54M) { + if (i == ODM_RF_PATH_A) { + evm = odm_evm_db_to_percentage( + (phy_sta_rpt->sigevm)); /*dbm*/ + evm += 20; + if (evm > 100) + evm = 100; + } + } else { + if (i < ODM_RF_PATH_C) { + if (phy_sta_rpt->rxevm[i] == -128) + phy_sta_rpt->rxevm[i] = -25; + evm = odm_evm_db_to_percentage( + (phy_sta_rpt->rxevm[i])); /*dbm*/ + } else { + if (phy_sta_rpt->rxevm_cd[i - 2] == -128) + phy_sta_rpt->rxevm_cd[i - 2] = -25; + evm = odm_evm_db_to_percentage( + (phy_sta_rpt->rxevm_cd[i - 2])); /*dbm*/ + } + } + + return evm; +} + +static inline s8 phydm_get_rx_pwr(u8 LNA_idx, u8 VGA_idx, u8 cck_highpwr) +{ + switch (LNA_idx) { + case 7: + if (VGA_idx <= 27) + return -100 + 2 * (27 - VGA_idx); /*VGA_idx = 27~2*/ + else + return -100; + break; + case 6: + return -48 + 2 * (2 - VGA_idx); /*VGA_idx = 2~0*/ + case 5: + return -42 + 2 * (7 - VGA_idx); /*VGA_idx = 7~5*/ + case 4: + return -36 + 2 * (7 - VGA_idx); /*VGA_idx = 7~4*/ + case 3: + return -24 + 2 * (7 - VGA_idx); /*VGA_idx = 7~0*/ + case 2: + if (cck_highpwr) + return -12 + 2 * (5 - VGA_idx); /*VGA_idx = 5~0*/ + else + return -6 + 2 * (5 - VGA_idx); + break; + case 1: + return 8 - 2 * VGA_idx; + case 0: + return 14 - 2 * VGA_idx; + default: + break; + } + return 0; +} + +static inline u8 phydm_adjust_pwdb(u8 cck_highpwr, u8 pwdb_all) +{ + if (!cck_highpwr) { + if (pwdb_all >= 80) + return ((pwdb_all - 80) << 1) + ((pwdb_all - 80) >> 1) + + 80; + else if ((pwdb_all <= 78) && (pwdb_all >= 20)) + return pwdb_all + 3; + if (pwdb_all > 100) + return 100; + } + return pwdb_all; +} + +static inline u8 +phydm_get_signal_quality_8812(struct dm_phy_status_info *phy_info, + struct phy_dm_struct *dm, + struct phy_status_rpt_8812 *phy_sta_rpt) +{ + u8 sq_rpt; + + if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test) + return 100; + + sq_rpt = phy_sta_rpt->pwdb_all; + + if (sq_rpt > 64) + return 0; + else if (sq_rpt < 20) + return 100; + else + return ((64 - sq_rpt) * 100) / 44; +} + +static inline u8 +phydm_get_signal_quality_8192(struct dm_phy_status_info *phy_info, + struct phy_dm_struct *dm, + struct phy_status_rpt_8192cd *phy_sta_rpt) +{ + u8 sq_rpt; + + if (phy_info->rx_pwdb_all > 40 && !dm->is_in_hct_test) + return 100; + + sq_rpt = phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all; + + if (sq_rpt > 64) + return 0; + else if (sq_rpt < 20) + return 100; + else + return ((64 - sq_rpt) * 100) / 44; +} + +static u8 odm_query_rx_pwr_percentage(s8 ant_power) +{ + if ((ant_power <= -100) || (ant_power >= 20)) + return 0; + else if (ant_power >= 0) + return 100; + else + return 100 + ant_power; +} + +/* + * 2012/01/12 MH MOve some signal strength smooth method to MP HAL layer. + * IF other SW team do not support the feature, remove this section.?? + */ + +s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig) +{ + { + return curr_sig; + } +} + +static u8 odm_sq_process_patch_rt_cid_819x_lenovo(struct phy_dm_struct *dm, + u8 is_cck_rate, u8 pwdb_all, + u8 path, u8 RSSI) +{ + u8 sq = 0; + return sq; +} + +static u8 odm_evm_db_to_percentage(s8 value) +{ + /* -33dB~0dB to 0%~99% */ + s8 ret_val; + + ret_val = value; + ret_val /= 2; + + if (ret_val >= 0) + ret_val = 0; + + if (ret_val <= -33) + ret_val = -33; + + ret_val = 0 - ret_val; + ret_val *= 3; + + if (ret_val == 99) + ret_val = 100; + + return (u8)ret_val; +} + +static u8 odm_evm_dbm_jaguar_series(s8 value) +{ + s8 ret_val = value; + + /* -33dB~0dB to 33dB ~ 0dB */ + if (ret_val == -128) + ret_val = 127; + else if (ret_val < 0) + ret_val = 0 - ret_val; + + ret_val = ret_val >> 1; + return (u8)ret_val; +} + +static s16 odm_cfo(s8 value) +{ + s16 ret_val; + + if (value < 0) { + ret_val = 0 - value; + ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */ + ret_val = + ret_val | BIT(12); /* set bit12 as 1 for negative cfo */ + } else { + ret_val = value; + ret_val = (ret_val << 1) + (ret_val >> 1); /* *2.5~=312.5/2^7 */ + } + return ret_val; +} + +static u8 phydm_rate_to_num_ss(struct phy_dm_struct *dm, u8 data_rate) +{ + u8 num_ss = 1; + + if (data_rate <= ODM_RATE54M) + num_ss = 1; + else if (data_rate <= ODM_RATEMCS31) + num_ss = ((data_rate - ODM_RATEMCS0) >> 3) + 1; + else if (data_rate <= ODM_RATEVHTSS1MCS9) + num_ss = 1; + else if (data_rate <= ODM_RATEVHTSS2MCS9) + num_ss = 2; + else if (data_rate <= ODM_RATEVHTSS3MCS9) + num_ss = 3; + else if (data_rate <= ODM_RATEVHTSS4MCS9) + num_ss = 4; + + return num_ss; +} + +static void odm_rx_phy_status92c_series_parsing( + struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, + u8 *phy_status, struct dm_per_pkt_info *pktinfo) +{ + u8 i, max_spatial_stream; + s8 rx_pwr[4], rx_pwr_all = 0; + u8 EVM, pwdb_all = 0, pwdb_all_bt; + u8 RSSI, total_rssi = 0; + bool is_cck_rate = false; + u8 rf_rx_num = 0; + u8 LNA_idx = 0; + u8 VGA_idx = 0; + u8 cck_agc_rpt; + u8 num_ss; + struct phy_status_rpt_8192cd *phy_sta_rpt = + (struct phy_status_rpt_8192cd *)phy_status; + + is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false; + + if (pktinfo->is_to_self) + dm->curr_station_id = pktinfo->station_id; + + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; + + if (is_cck_rate) { + dm->phy_dbg_info.num_qry_phy_status_cck++; + cck_agc_rpt = phy_sta_rpt->cck_agc_rpt_ofdm_cfosho_a; + + if (dm->support_ic_type & (ODM_RTL8703B)) { + } else { /*3 bit LNA*/ + + LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); + VGA_idx = (cck_agc_rpt & 0x1F); + } + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "ext_lna_gain (( %d )), LNA_idx: (( 0x%x )), VGA_idx: (( 0x%x )), rx_pwr_all: (( %d ))\n", + dm->ext_lna_gain, LNA_idx, VGA_idx, rx_pwr_all); + + if (dm->board_type & ODM_BOARD_EXT_LNA) + rx_pwr_all -= dm->ext_lna_gain; + + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + + if (pktinfo->is_to_self) { + dm->cck_lna_idx = LNA_idx; + dm->cck_vga_idx = VGA_idx; + } + phy_info->rx_pwdb_all = pwdb_all; + + phy_info->bt_rx_rssi_percentage = pwdb_all; + phy_info->recv_signal_power = rx_pwr_all; + /* (3) Get Signal Quality (EVM) */ + { + u8 sq; + + sq = phydm_get_signal_quality_8192(phy_info, dm, + phy_sta_rpt); + phy_info->signal_quality = sq; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; + } + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) { + if (i == 0) + phy_info->rx_mimo_signal_strength[0] = pwdb_all; + else + phy_info->rx_mimo_signal_strength[1] = 0; + } + } else { /* 2 is OFDM rate */ + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /* */ + /* (1)Get RSSI for HT rate */ + /* */ + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX; i++) { + /* 2008/01/30 MH we will judge RF RX path now. */ + if (dm->rf_path_rx_enable & BIT(i)) + rf_rx_num++; + /* else */ + /* continue; */ + + rx_pwr[i] = + ((phy_sta_rpt->path_agc[i].gain & 0x3F) * 2) - + 110; + + if (pktinfo->is_to_self) { + dm->ofdm_agc_idx[i] = + (phy_sta_rpt->path_agc[i].gain & 0x3F); + /**/ + } + + phy_info->rx_pwr[i] = rx_pwr[i]; + + /* Translate DBM to percentage. */ + RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]); + total_rssi += RSSI; + + phy_info->rx_mimo_signal_strength[i] = (u8)RSSI; + + /* Get Rx snr value in DB */ + dm->phy_dbg_info.rx_snr_db[i] = + (s32)(phy_sta_rpt->path_rxsnr[i] / 2); + phy_info->rx_snr[i] = dm->phy_dbg_info.rx_snr_db[i]; + + /* Record Signal Strength for next packet */ + /* if(pktinfo->is_packet_match_bssid) */ + { + } + } + + /* */ + /* (2)PWDB, Average PWDB calcuated by hardware (for RA) */ + /* */ + rx_pwr_all = (((phy_sta_rpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & + 0x7f) - + 110; + + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + pwdb_all_bt = pwdb_all; + + phy_info->rx_pwdb_all = pwdb_all; + phy_info->bt_rx_rssi_percentage = pwdb_all_bt; + phy_info->rx_power = rx_pwr_all; + phy_info->recv_signal_power = rx_pwr_all; + + if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) { + /* do nothing */ + } else if ((dm->support_platform == ODM_WIN) && + (dm->patch_id == 25)) { + /* do nothing */ + } else { /* mgnt_info->customer_id != RT_CID_819X_LENOVO */ + /* */ + /* (3)EVM of HT rate */ + /* */ + if (pktinfo->data_rate >= ODM_RATEMCS8 && + pktinfo->data_rate <= ODM_RATEMCS15) { + /* 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++) { + /*Don't use shift operation like "rx_evmX >>= 1" + *because the compilor of free build environment + *fill most significant bit to "zero" when doing + *shifting operation which may change a negative + *value to positive one, then the dbm value + *(which is supposed to be negative) is not + *correct anymore. + */ + EVM = odm_evm_db_to_percentage( + (phy_sta_rpt + ->stream_rxevm[i])); /* dbm */ + + /* Fill value in RFD, Get the first spatial + * stream only + */ + if (i == ODM_RF_PATH_A) + phy_info->signal_quality = + (u8)(EVM & 0xff); + phy_info->rx_mimo_signal_quality[i] = + (u8)(EVM & 0xff); + } + } + + num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); + odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->path_cfotail, num_ss); + } + /* UI BSS List signal strength(in percentage), make it good looking, + * from 0~100. + */ + /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */ + if (is_cck_rate) { + phy_info->signal_strength = (u8)( + odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/ + } else { + if (rf_rx_num != 0) { + phy_info->signal_strength = + (u8)(odm_signal_scale_mapping(dm, total_rssi /= + rf_rx_num)); + } + } + + /* For 92C/92D HW (Hybrid) Antenna Diversity */ +} + +static void +odm_rx_phy_bw_jaguar_series_parsing(struct dm_phy_status_info *phy_info, + struct dm_per_pkt_info *pktinfo, + struct phy_status_rpt_8812 *phy_sta_rpt) +{ + if (pktinfo->data_rate <= ODM_RATE54M) { + switch (phy_sta_rpt->r_RFMOD) { + case 1: + if (phy_sta_rpt->sub_chnl == 0) + phy_info->band_width = 1; + else + phy_info->band_width = 0; + break; + + case 2: + if (phy_sta_rpt->sub_chnl == 0) + phy_info->band_width = 2; + else if (phy_sta_rpt->sub_chnl == 9 || + phy_sta_rpt->sub_chnl == 10) + phy_info->band_width = 1; + else + phy_info->band_width = 0; + break; + + default: + case 0: + phy_info->band_width = 0; + break; + } + } +} + +static void odm_rx_phy_status_jaguar_series_parsing( + struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, + u8 *phy_status, struct dm_per_pkt_info *pktinfo) +{ + u8 i, max_spatial_stream; + s8 rx_pwr[4], rx_pwr_all = 0; + u8 EVM = 0, evm_dbm, pwdb_all = 0, pwdb_all_bt; + u8 RSSI, avg_rssi = 0, best_rssi = 0, second_rssi = 0; + u8 is_cck_rate = 0; + u8 rf_rx_num = 0; + u8 cck_highpwr = 0; + u8 LNA_idx, VGA_idx; + struct phy_status_rpt_8812 *phy_sta_rpt = + (struct phy_status_rpt_8812 *)phy_status; + struct fast_antenna_training *fat_tab = &dm->dm_fat_table; + u8 num_ss; + + odm_rx_phy_bw_jaguar_series_parsing(phy_info, pktinfo, phy_sta_rpt); + + if (pktinfo->data_rate <= ODM_RATE11M) + is_cck_rate = true; + else + is_cck_rate = false; + + if (pktinfo->is_to_self) + dm->curr_station_id = pktinfo->station_id; + else + dm->curr_station_id = 0xff; + + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_B] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_C] = -1; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_D] = -1; + + if (is_cck_rate) { + u8 cck_agc_rpt; + + dm->phy_dbg_info.num_qry_phy_status_cck++; + + /*(1)Hardware does not provide RSSI for CCK*/ + /*(2)PWDB, Average PWDB calculated by hardware (for RA)*/ + + cck_highpwr = dm->is_cck_high_power; + + cck_agc_rpt = phy_sta_rpt->cfosho[0]; + LNA_idx = ((cck_agc_rpt & 0xE0) >> 5); + VGA_idx = (cck_agc_rpt & 0x1F); + + if (dm->support_ic_type == ODM_RTL8812) { + rx_pwr_all = + phydm_get_rx_pwr(LNA_idx, VGA_idx, cck_highpwr); + rx_pwr_all += 6; + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + pwdb_all = phydm_adjust_pwdb(cck_highpwr, pwdb_all); + + } else if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) { + s8 pout = -6; + + switch (LNA_idx) { + case 5: + rx_pwr_all = pout - 32 - (2 * VGA_idx); + break; + case 4: + rx_pwr_all = pout - 24 - (2 * VGA_idx); + break; + case 2: + rx_pwr_all = pout - 11 - (2 * VGA_idx); + break; + case 1: + rx_pwr_all = pout + 5 - (2 * VGA_idx); + break; + case 0: + rx_pwr_all = pout + 21 - (2 * VGA_idx); + break; + } + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + } else if (dm->support_ic_type == ODM_RTL8814A || + dm->support_ic_type == ODM_RTL8822B) { + s8 pout = -6; + + switch (LNA_idx) { + /*CCK only use LNA: 2, 3, 5, 7*/ + case 7: + rx_pwr_all = pout - 32 - (2 * VGA_idx); + break; + case 5: + rx_pwr_all = pout - 22 - (2 * VGA_idx); + break; + case 3: + rx_pwr_all = pout - 2 - (2 * VGA_idx); + break; + case 2: + rx_pwr_all = pout + 5 - (2 * VGA_idx); + break; + default: + break; + } + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + } + + dm->cck_lna_idx = LNA_idx; + dm->cck_vga_idx = VGA_idx; + phy_info->rx_pwdb_all = pwdb_all; + phy_info->bt_rx_rssi_percentage = pwdb_all; + phy_info->recv_signal_power = rx_pwr_all; + /*(3) Get Signal Quality (EVM)*/ + { + u8 sq; + + if ((dm->support_platform == ODM_WIN) && + (dm->patch_id == RT_CID_819X_LENOVO)) + sq = odm_sq_process_patch_rt_cid_819x_lenovo( + dm, is_cck_rate, pwdb_all, 0, 0); + else + sq = phydm_get_signal_quality_8812(phy_info, dm, + phy_sta_rpt); + + phy_info->signal_quality = sq; + phy_info->rx_mimo_signal_quality[ODM_RF_PATH_A] = sq; + } + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (i == 0) + phy_info->rx_mimo_signal_strength[0] = pwdb_all; + else + phy_info->rx_mimo_signal_strength[i] = 0; + } + } else { + /*is OFDM rate*/ + fat_tab->hw_antsw_occur = phy_sta_rpt->hw_antsw_occur; + + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /*(1)Get RSSI for OFDM rate*/ + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + /*2008/01/30 MH we will judge RF RX path now.*/ + if (dm->rf_path_rx_enable & BIT(i)) + rf_rx_num++; + /*2012.05.25 LukeLee: Testchip AGC report is wrong, + *it should be restored back to old formula in MP chip + */ + if (i < ODM_RF_PATH_C) + rx_pwr[i] = (phy_sta_rpt->gain_trsw[i] & 0x7F) - + 110; + else + rx_pwr[i] = (phy_sta_rpt->gain_trsw_cd[i - 2] & + 0x7F) - + 110; + + phy_info->rx_pwr[i] = rx_pwr[i]; + + /* Translate DBM to percentage. */ + RSSI = odm_query_rx_pwr_percentage(rx_pwr[i]); + + /*total_rssi += RSSI;*/ + /*Get the best two RSSI*/ + if (RSSI > best_rssi && RSSI > second_rssi) { + second_rssi = best_rssi; + best_rssi = RSSI; + } else if (RSSI > second_rssi && RSSI <= best_rssi) { + second_rssi = RSSI; + } + + phy_info->rx_mimo_signal_strength[i] = (u8)RSSI; + + /*Get Rx snr value in DB*/ + if (i < ODM_RF_PATH_C) + phy_info->rx_snr[i] = + dm->phy_dbg_info.rx_snr_db[i] = + phy_sta_rpt->rxsnr[i] / 2; + else if (dm->support_ic_type & + (ODM_RTL8814A | ODM_RTL8822B)) + phy_info->rx_snr[i] = dm->phy_dbg_info + .rx_snr_db[i] = + phy_sta_rpt->csi_current[i - 2] / 2; + + /*(2) CFO_short & CFO_tail*/ + if (i < ODM_RF_PATH_C) { + phy_info->cfo_short[i] = + odm_cfo((phy_sta_rpt->cfosho[i])); + phy_info->cfo_tail[i] = + odm_cfo((phy_sta_rpt->cfotail[i])); + } + } + + /*(3)PWDB, Average PWDB calculated by hardware (for RA)*/ + + /*2012.05.25 LukeLee: Testchip AGC report is wrong, it should be + *restored back to old formula in MP chip + */ + if ((dm->support_ic_type & + (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A)) && + (!dm->is_mp_chip)) + rx_pwr_all = (phy_sta_rpt->pwdb_all & 0x7f) - 110; + else + rx_pwr_all = (((phy_sta_rpt->pwdb_all) >> 1) & 0x7f) - + 110; /*OLD FORMULA*/ + + pwdb_all = odm_query_rx_pwr_percentage(rx_pwr_all); + pwdb_all_bt = pwdb_all; + + phy_info->rx_pwdb_all = pwdb_all; + phy_info->bt_rx_rssi_percentage = pwdb_all_bt; + phy_info->rx_power = rx_pwr_all; + phy_info->recv_signal_power = rx_pwr_all; + + if ((dm->support_platform == ODM_WIN) && (dm->patch_id == 19)) { + /*do nothing*/ + } else { + /*mgnt_info->customer_id != RT_CID_819X_LENOVO*/ + + /*(4)EVM of OFDM rate*/ + + if ((pktinfo->data_rate >= ODM_RATEMCS8) && + (pktinfo->data_rate <= ODM_RATEMCS15)) + max_spatial_stream = 2; + else if ((pktinfo->data_rate >= ODM_RATEVHTSS2MCS0) && + (pktinfo->data_rate <= ODM_RATEVHTSS2MCS9)) + max_spatial_stream = 2; + else if ((pktinfo->data_rate >= ODM_RATEMCS16) && + (pktinfo->data_rate <= ODM_RATEMCS23)) + max_spatial_stream = 3; + else if ((pktinfo->data_rate >= ODM_RATEVHTSS3MCS0) && + (pktinfo->data_rate <= ODM_RATEVHTSS3MCS9)) + max_spatial_stream = 3; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + /*Don't use shift operation like "rx_evmX >>= 1" + *because the compilor of free build environment + *fill most significant bit to "zero" when doing + *shifting operation which may change a negative + *value to positive one, then the dbm value + *(which is supposed to be negative) is not + *correct anymore. + */ + + EVM = phydm_get_odm_evm(i, pktinfo, + phy_sta_rpt); + evm_dbm = phydm_get_evm_dbm(i, EVM, phy_sta_rpt, + phy_info); + phy_info->rx_mimo_signal_quality[i] = EVM; + phy_info->rx_mimo_evm_dbm[i] = evm_dbm; + } + } + + num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); + odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfotail, num_ss); + } + + /*UI BSS List signal strength(in percentage), make it good looking, + *from 0~100. + */ + /*It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().*/ + if (is_cck_rate) { + phy_info->signal_strength = (u8)( + odm_signal_scale_mapping(dm, pwdb_all)); /*pwdb_all;*/ + } else { + if (rf_rx_num != 0) { + /* 2015/01 Sean, use the best two RSSI only, + * suggested by Ynlin and ChenYu. + */ + if (rf_rx_num == 1) + avg_rssi = best_rssi; + else + avg_rssi = (best_rssi + second_rssi) / 2; + phy_info->signal_strength = + (u8)(odm_signal_scale_mapping(dm, avg_rssi)); + } + } + dm->rx_pwdb_ave = dm->rx_pwdb_ave + phy_info->rx_pwdb_all; + + dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_anta; + dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_antb; + dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_antc; + dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_antd; +} + +void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id) +{ + struct rtl_sta_info *entry; + + entry = dm->odm_sta_info[station_id]; + + if (!IS_STA_VALID(entry)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_RSSI_MONITOR, + "Reset RSSI for macid = (( %d ))\n", station_id); + + entry->rssi_stat.undecorated_smoothed_cck = -1; + entry->rssi_stat.undecorated_smoothed_ofdm = -1; + entry->rssi_stat.undecorated_smoothed_pwdb = -1; + entry->rssi_stat.ofdm_pkt = 0; + entry->rssi_stat.cck_pkt = 0; + entry->rssi_stat.cck_sum_power = 0; + entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_INIT; + entry->rssi_stat.packet_map = 0; + entry->rssi_stat.valid_bit = 0; +} + +void odm_init_rssi_for_dm(struct phy_dm_struct *dm) {} + +static void odm_process_rssi_for_dm(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct dm_per_pkt_info *pktinfo) +{ + s32 undecorated_smoothed_pwdb, undecorated_smoothed_cck, + undecorated_smoothed_ofdm; + u8 is_cck_rate = 0; + u8 send_rssi_2_fw = 0; + struct rtl_sta_info *entry; + + if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM) + return; + + /* 2012/05/30 MH/Luke.Lee Add some description */ + /* In windows driver: AP/IBSS mode STA */ + entry = dm->odm_sta_info[pktinfo->station_id]; + + if (!IS_STA_VALID(entry)) + return; + + { + if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/ + return; + } + + if (pktinfo->is_packet_beacon) + dm->phy_dbg_info.num_qry_beacon_pkt++; + + is_cck_rate = (pktinfo->data_rate <= ODM_RATE11M) ? true : false; + dm->rx_rate = pktinfo->data_rate; + + /* --------------Statistic for antenna/path diversity---------------- */ + + /* -----------------Smart Antenna Debug Message------------------ */ + + undecorated_smoothed_cck = entry->rssi_stat.undecorated_smoothed_cck; + undecorated_smoothed_ofdm = entry->rssi_stat.undecorated_smoothed_ofdm; + undecorated_smoothed_pwdb = entry->rssi_stat.undecorated_smoothed_pwdb; + + if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) { + if (!is_cck_rate) /* ofdm rate */ + undecorated_smoothed_ofdm = phydm_process_rssi_ofdm( + dm, phy_info, entry, undecorated_smoothed_ofdm); + else + undecorated_smoothed_cck = phydm_process_rssi_cck( + dm, phy_info, entry, undecorated_smoothed_cck); + + undecorated_smoothed_pwdb = phydm_process_rssi_pwdb( + dm, entry, pktinfo, undecorated_smoothed_ofdm, + undecorated_smoothed_cck); + + if ((entry->rssi_stat.ofdm_pkt >= 1 || + entry->rssi_stat.cck_pkt >= 5) && + (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_INIT)) { + send_rssi_2_fw = 1; + entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_SEND; + } + + entry->rssi_stat.undecorated_smoothed_cck = + undecorated_smoothed_cck; + entry->rssi_stat.undecorated_smoothed_ofdm = + undecorated_smoothed_ofdm; + entry->rssi_stat.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + + if (send_rssi_2_fw) { /* Trigger init rate by RSSI */ + + if (entry->rssi_stat.ofdm_pkt != 0) + entry->rssi_stat.undecorated_smoothed_pwdb = + undecorated_smoothed_ofdm; + + ODM_RT_TRACE( + dm, ODM_COMP_RSSI_MONITOR, + "[Send to FW] PWDB = (( %d )), ofdm_pkt = (( %d )), cck_pkt = (( %d ))\n", + undecorated_smoothed_pwdb, + entry->rssi_stat.ofdm_pkt, + entry->rssi_stat.cck_pkt); + } + } +} + +/* + * Endianness before calling this API + */ +static void odm_phy_status_query_92c_series(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo) +{ + odm_rx_phy_status92c_series_parsing(dm, phy_info, phy_status, pktinfo); + odm_process_rssi_for_dm(dm, phy_info, pktinfo); +} + +/* + * Endianness before calling this API + */ + +static void odm_phy_status_query_jaguar_series( + struct phy_dm_struct *dm, struct dm_phy_status_info *phy_info, + u8 *phy_status, struct dm_per_pkt_info *pktinfo) +{ + odm_rx_phy_status_jaguar_series_parsing(dm, phy_info, phy_status, + pktinfo); + odm_process_rssi_for_dm(dm, phy_info, pktinfo); +} + +void odm_phy_status_query(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, u8 *phy_status, + struct dm_per_pkt_info *pktinfo) +{ + if (dm->support_ic_type & ODM_IC_PHY_STATUE_NEW_TYPE) { + phydm_rx_phy_status_new_type(dm, phy_status, pktinfo, phy_info); + return; + } + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) + odm_phy_status_query_jaguar_series(dm, phy_info, phy_status, + pktinfo); + + if (dm->support_ic_type & ODM_IC_11N_SERIES) + odm_phy_status_query_92c_series(dm, phy_info, phy_status, + pktinfo); +} + +/* For future use. */ +void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id, + bool is_packet_match_bssid, bool is_packet_to_self, + bool is_packet_beacon) +{ + /* 2011/10/19 Driver team will handle in the future. */ +} + +/* + * If you want to add a new IC, Please follow below template and generate + * a new one. + */ + +enum hal_status +odm_config_rf_with_header_file(struct phy_dm_struct *dm, + enum odm_rf_config_type config_type, + enum odm_rf_radio_path e_rf_path) +{ + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===>%s (%s)\n", __func__, + (dm->is_mp_chip) ? "MPChip" : "TestChip"); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", + dm->support_platform, dm->support_interface, dm->board_type); + + /* 1 AP doesn't use PHYDM power tracking table in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + if (dm->support_ic_type == ODM_RTL8822B) { + if (config_type == CONFIG_RF_RADIO) { + if (e_rf_path == ODM_RF_PATH_A) + READ_AND_CONFIG_MP(8822b, _radioa); + else if (e_rf_path == ODM_RF_PATH_B) + READ_AND_CONFIG_MP(8822b, _radiob); + } else if (config_type == CONFIG_RF_TXPWR_LMT) { + if (dm->rfe_type == 5) + READ_AND_CONFIG_MP(8822b, _txpwr_lmt_type5); + else + READ_AND_CONFIG_MP(8822b, _txpwr_lmt); + } + } + + return HAL_STATUS_SUCCESS; +} + +enum hal_status +odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm) +{ + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===>%s (%s)\n", __func__, + (dm->is_mp_chip) ? "MPChip" : "TestChip"); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", + dm->support_platform, dm->support_interface, dm->board_type); + + /* 1 AP doesn't use PHYDM power tracking table in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + + if (dm->support_ic_type == ODM_RTL8822B) { + if (dm->rfe_type == 0) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type0); + else if (dm->rfe_type == 1) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type1); + else if (dm->rfe_type == 2) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type2); + else if ((dm->rfe_type == 3) || (dm->rfe_type == 5)) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type3_type5); + else if (dm->rfe_type == 4) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type4); + else if (dm->rfe_type == 6) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type6); + else if (dm->rfe_type == 7) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type7); + else if (dm->rfe_type == 8) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type8); + else if (dm->rfe_type == 9) + READ_AND_CONFIG_MP(8822b, _txpowertrack_type9); + else + READ_AND_CONFIG_MP(8822b, _txpowertrack); + } + + return HAL_STATUS_SUCCESS; +} + +enum hal_status +odm_config_bb_with_header_file(struct phy_dm_struct *dm, + enum odm_bb_config_type config_type) +{ + /* 1 AP doesn't use PHYDM initialization in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + if (dm->support_ic_type == ODM_RTL8822B) { + if (config_type == CONFIG_BB_PHY_REG) + READ_AND_CONFIG_MP(8822b, _phy_reg); + else if (config_type == CONFIG_BB_AGC_TAB) + READ_AND_CONFIG_MP(8822b, _agc_tab); + else if (config_type == CONFIG_BB_PHY_REG_PG) + READ_AND_CONFIG_MP(8822b, _phy_reg_pg); + /*else if (config_type == CONFIG_BB_PHY_REG_MP)*/ + /*READ_AND_CONFIG_MP(8822b, _phy_reg_mp);*/ + } + + return HAL_STATUS_SUCCESS; +} + +enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm) +{ + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===>%s (%s)\n", __func__, + (dm->is_mp_chip) ? "MPChip" : "TestChip"); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "dm->support_platform: 0x%X, dm->support_interface: 0x%X, dm->board_type: 0x%X\n", + dm->support_platform, dm->support_interface, dm->board_type); + + /* 1 AP doesn't use PHYDM initialization in these ICs */ + /* JJ ADD 20161014 */ + + /* 1 All platforms support */ + if (dm->support_ic_type == ODM_RTL8822B) + READ_AND_CONFIG_MP(8822b, _mac_reg); + + return HAL_STATUS_SUCCESS; +} + +enum hal_status +odm_config_fw_with_header_file(struct phy_dm_struct *dm, + enum odm_fw_config_type config_type, + u8 *p_firmware, u32 *size) +{ + return HAL_STATUS_SUCCESS; +} + +u32 odm_get_hw_img_version(struct phy_dm_struct *dm) +{ + u32 version = 0; + + /* 1 AP doesn't use PHYDM initialization in these ICs */ + /* JJ ADD 20161014 */ + + /*1 All platforms support*/ + if (dm->support_ic_type == ODM_RTL8822B) + version = GET_VERSION_MP(8822b, _mac_reg); + + return version; +} + +/* For 8822B only!! need to move to FW finally */ +/*==============================================*/ + +bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx, + u8 *p_data_rate, u8 *p_gid) +{ + u8 data_rate = 0, gid = 0; + bool is_mu = false; + + data_rate = phydm->phy_dbg_info.num_of_ppdu[ppdu_idx]; + gid = phydm->phy_dbg_info.gid_num[ppdu_idx]; + + if (data_rate & BIT(7)) { + is_mu = true; + data_rate = data_rate & ~(BIT(7)); + } else { + is_mu = false; + } + + *p_data_rate = data_rate; + *p_gid = gid; + + return is_mu; +} + +static void phydm_rx_statistic_cal(struct phy_dm_struct *phydm, u8 *phy_status, + struct dm_per_pkt_info *pktinfo) +{ + struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type1 *)phy_status; + u8 date_rate = pktinfo->data_rate & ~(BIT(7)); + + if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) { + if (date_rate >= ODM_RATEVHTSS1MCS0) { + phydm->phy_dbg_info + .num_qry_mu_vht_pkt[date_rate - 0x2C]++; + phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] = + date_rate | BIT(7); + phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] = + phy_sta_rpt->gid; + } + + } else { + if (date_rate >= ODM_RATEVHTSS1MCS0) { + phydm->phy_dbg_info.num_qry_vht_pkt[date_rate - 0x2C]++; + phydm->phy_dbg_info.num_of_ppdu[pktinfo->ppdu_cnt] = + date_rate; + phydm->phy_dbg_info.gid_num[pktinfo->ppdu_cnt] = + phy_sta_rpt->gid; + } + } +} + +static void phydm_reset_phy_info(struct phy_dm_struct *phydm, + struct dm_phy_status_info *phy_info) +{ + phy_info->rx_pwdb_all = 0; + phy_info->signal_quality = 0; + phy_info->band_width = 0; + phy_info->rx_count = 0; + odm_memory_set(phydm, phy_info->rx_mimo_signal_quality, 0, 4); + odm_memory_set(phydm, phy_info->rx_mimo_signal_strength, 0, 4); + odm_memory_set(phydm, phy_info->rx_snr, 0, 4); + + phy_info->rx_power = -110; + phy_info->recv_signal_power = -110; + phy_info->bt_rx_rssi_percentage = 0; + phy_info->signal_strength = 0; + phy_info->bt_coex_pwr_adjust = 0; + phy_info->channel = 0; + phy_info->is_mu_packet = 0; + phy_info->is_beamformed = 0; + phy_info->rxsc = 0; + odm_memory_set(phydm, phy_info->rx_pwr, -110, 4); + odm_memory_set(phydm, phy_info->rx_mimo_evm_dbm, 0, 4); + odm_memory_set(phydm, phy_info->cfo_short, 0, 8); + odm_memory_set(phydm, phy_info->cfo_tail, 0, 8); +} + +static void phydm_set_per_path_phy_info(u8 rx_path, s8 rx_pwr, s8 rx_evm, + s8 cfo_tail, s8 rx_snr, + struct dm_phy_status_info *phy_info) +{ + u8 evm_dbm = 0; + u8 evm_percentage = 0; + + /* SNR is S(8,1), EVM is S(8,1), CFO is S(8,7) */ + + if (rx_evm < 0) { + /* Calculate EVM in dBm */ + evm_dbm = ((u8)(0 - rx_evm) >> 1); + + /* Calculate EVM in percentage */ + if (evm_dbm >= 33) + evm_percentage = 100; + else + evm_percentage = (evm_dbm << 1) + (evm_dbm); + } + + phy_info->rx_pwr[rx_path] = rx_pwr; + phy_info->rx_mimo_evm_dbm[rx_path] = evm_dbm; + + /* CFO = CFO_tail * 312.5 / 2^7 ~= CFO tail * 39/512 (kHz)*/ + phy_info->cfo_tail[rx_path] = cfo_tail; + phy_info->cfo_tail[rx_path] = ((phy_info->cfo_tail[rx_path] << 5) + + (phy_info->cfo_tail[rx_path] << 2) + + (phy_info->cfo_tail[rx_path] << 1) + + (phy_info->cfo_tail[rx_path])) >> + 9; + + phy_info->rx_mimo_signal_strength[rx_path] = + odm_query_rx_pwr_percentage(rx_pwr); + phy_info->rx_mimo_signal_quality[rx_path] = evm_percentage; + phy_info->rx_snr[rx_path] = rx_snr >> 1; +} + +static void phydm_set_common_phy_info(s8 rx_power, u8 channel, + bool is_beamformed, bool is_mu_packet, + u8 bandwidth, u8 signal_quality, u8 rxsc, + struct dm_phy_status_info *phy_info) +{ + phy_info->rx_power = rx_power; /* RSSI in dB */ + phy_info->recv_signal_power = rx_power; /* RSSI in dB */ + phy_info->channel = channel; /* channel number */ + phy_info->is_beamformed = is_beamformed; /* apply BF */ + phy_info->is_mu_packet = is_mu_packet; /* MU packet */ + phy_info->rxsc = rxsc; + phy_info->rx_pwdb_all = + odm_query_rx_pwr_percentage(rx_power); /* RSSI in percentage */ + phy_info->signal_quality = signal_quality; /* signal quality */ + phy_info->band_width = bandwidth; /* bandwidth */ +} + +static void phydm_get_rx_phy_status_type0(struct phy_dm_struct *dm, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + /* type 0 is used for cck packet */ + + struct phy_status_rpt_jaguar2_type0 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type0 *)phy_status; + u8 sq = 0; + s8 rx_power = phy_sta_rpt->pwdb - 110; + + /* JJ ADD 20161014 */ + + /* Calculate Signal Quality*/ + if (pktinfo->is_packet_match_bssid) { + if (phy_sta_rpt->signal_quality >= 64) { + sq = 0; + } else if (phy_sta_rpt->signal_quality <= 20) { + sq = 100; + } else { + /* mapping to 2~99% */ + sq = 64 - phy_sta_rpt->signal_quality; + sq = ((sq << 3) + sq) >> 2; + } + } + + /* Modify CCK PWDB if old AGC */ + if (!dm->cck_new_agc) { + u8 lna_idx, vga_idx; + + lna_idx = ((phy_sta_rpt->lna_h << 3) | phy_sta_rpt->lna_l); + vga_idx = phy_sta_rpt->vga; + + /* JJ ADD 20161014 */ + + /* Need to do !! */ + /*if (dm->support_ic_type & ODM_RTL8822B) */ + /*rx_power = odm_CCKRSSI_8822B(LNA_idx, VGA_idx);*/ + } + + /* Update CCK packet counter */ + dm->phy_dbg_info.num_qry_phy_status_cck++; + + /*CCK no STBC and LDPC*/ + dm->phy_dbg_info.is_ldpc_pkt = false; + dm->phy_dbg_info.is_stbc_pkt = false; + + /* Update Common information */ + phydm_set_common_phy_info(rx_power, phy_sta_rpt->channel, false, false, + ODM_BW20M, sq, phy_sta_rpt->rxsc, phy_info); + + /* Update CCK pwdb */ + /* Update per-path information */ + phydm_set_per_path_phy_info(ODM_RF_PATH_A, rx_power, 0, 0, 0, phy_info); + + dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a; + dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b; + dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c; + dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d; +} + +static void phydm_get_rx_phy_status_type1(struct phy_dm_struct *dm, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + /* type 1 is used for ofdm packet */ + + struct phy_status_rpt_jaguar2_type1 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type1 *)phy_status; + s8 rx_pwr_db = -120; + u8 i, rxsc, bw = ODM_BW20M, rx_count = 0; + bool is_mu; + u8 num_ss; + + /* Update OFDM packet counter */ + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /* Update per-path information */ + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (dm->rx_ant_status & BIT(i)) { + s8 rx_path_pwr_db; + + /* RX path counter */ + rx_count++; + + /* Update per-path information + * (RSSI_dB RSSI_percentage EVM SNR CFO sq) + */ + /* EVM report is reported by stream, not path */ + rx_path_pwr_db = phy_sta_rpt->pwdb[i] - + 110; /* per-path pwdb in dB domain */ + phydm_set_per_path_phy_info( + i, rx_path_pwr_db, + phy_sta_rpt->rxevm[rx_count - 1], + phy_sta_rpt->cfo_tail[i], phy_sta_rpt->rxsnr[i], + phy_info); + + /* search maximum pwdb */ + if (rx_path_pwr_db > rx_pwr_db) + rx_pwr_db = rx_path_pwr_db; + } + } + + /* mapping RX counter from 1~4 to 0~3 */ + if (rx_count > 0) + phy_info->rx_count = rx_count - 1; + + /* Check if MU packet or not */ + if ((phy_sta_rpt->gid != 0) && (phy_sta_rpt->gid != 63)) { + is_mu = true; + dm->phy_dbg_info.num_qry_mu_pkt++; + } else { + is_mu = false; + } + + /* count BF packet */ + dm->phy_dbg_info.num_qry_bf_pkt = + dm->phy_dbg_info.num_qry_bf_pkt + phy_sta_rpt->beamformed; + + /*STBC or LDPC pkt*/ + dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc; + dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc; + + /* Check sub-channel */ + if ((pktinfo->data_rate > ODM_RATE11M) && + (pktinfo->data_rate < ODM_RATEMCS0)) + rxsc = phy_sta_rpt->l_rxsc; + else + rxsc = phy_sta_rpt->ht_rxsc; + + /* Check RX bandwidth */ + if (dm->support_ic_type & ODM_RTL8822B) { + if ((rxsc >= 1) && (rxsc <= 8)) + bw = ODM_BW20M; + else if ((rxsc >= 9) && (rxsc <= 12)) + bw = ODM_BW40M; + else if (rxsc >= 13) + bw = ODM_BW80M; + else + bw = phy_sta_rpt->rf_mode; + } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D | + ODM_RTL8710B)) { /* JJ ADD 20161014 */ + if (phy_sta_rpt->rf_mode == 0) + bw = ODM_BW20M; + else if ((rxsc == 1) || (rxsc == 2)) + bw = ODM_BW20M; + else + bw = ODM_BW40M; + } + + /* Update packet information */ + phydm_set_common_phy_info( + rx_pwr_db, phy_sta_rpt->channel, (bool)phy_sta_rpt->beamformed, + is_mu, bw, odm_evm_db_to_percentage(phy_sta_rpt->rxevm[0]), + rxsc, phy_info); + + num_ss = phydm_rate_to_num_ss(dm, pktinfo->data_rate); + + odm_parsing_cfo(dm, pktinfo, phy_sta_rpt->cfo_tail, num_ss); + dm->dm_fat_table.antsel_rx_keep_0 = phy_sta_rpt->antidx_a; + dm->dm_fat_table.antsel_rx_keep_1 = phy_sta_rpt->antidx_b; + dm->dm_fat_table.antsel_rx_keep_2 = phy_sta_rpt->antidx_c; + dm->dm_fat_table.antsel_rx_keep_3 = phy_sta_rpt->antidx_d; + + if (pktinfo->is_packet_match_bssid) { + /* */ + phydm_rx_statistic_cal(dm, phy_status, pktinfo); + } +} + +static void phydm_get_rx_phy_status_type2(struct phy_dm_struct *dm, + u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + struct phy_status_rpt_jaguar2_type2 *phy_sta_rpt = + (struct phy_status_rpt_jaguar2_type2 *)phy_status; + s8 rx_pwr_db = -120; + u8 i, rxsc, bw = ODM_BW20M, rx_count = 0; + + /* Update OFDM packet counter */ + dm->phy_dbg_info.num_qry_phy_status_ofdm++; + + /* Update per-path information */ + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (dm->rx_ant_status & BIT(i)) { + s8 rx_path_pwr_db; + + /* RX path counter */ + rx_count++; + + /* Update per-path information + * (RSSI_dB RSSI_percentage EVM SNR CFO sq) + */ + rx_path_pwr_db = phy_sta_rpt->pwdb[i] - + 110; /* per-path pwdb in dB domain */ + + phydm_set_per_path_phy_info(i, rx_path_pwr_db, 0, 0, 0, + phy_info); + + /* search maximum pwdb */ + if (rx_path_pwr_db > rx_pwr_db) + rx_pwr_db = rx_path_pwr_db; + } + } + + /* mapping RX counter from 1~4 to 0~3 */ + if (rx_count > 0) + phy_info->rx_count = rx_count - 1; + + /* Check RX sub-channel */ + if ((pktinfo->data_rate > ODM_RATE11M) && + (pktinfo->data_rate < ODM_RATEMCS0)) + rxsc = phy_sta_rpt->l_rxsc; + else + rxsc = phy_sta_rpt->ht_rxsc; + + /*STBC or LDPC pkt*/ + dm->phy_dbg_info.is_ldpc_pkt = phy_sta_rpt->ldpc; + dm->phy_dbg_info.is_stbc_pkt = phy_sta_rpt->stbc; + + /* Check RX bandwidth */ + /* the BW information of sc=0 is useless, because there is + * no information of RF mode + */ + + if (dm->support_ic_type & ODM_RTL8822B) { + if ((rxsc >= 1) && (rxsc <= 8)) + bw = ODM_BW20M; + else if ((rxsc >= 9) && (rxsc <= 12)) + bw = ODM_BW40M; + else if (rxsc >= 13) + bw = ODM_BW80M; + else + bw = ODM_BW20M; + } else if (dm->support_ic_type & (ODM_RTL8197F | ODM_RTL8723D | + ODM_RTL8710B)) { /* JJ ADD 20161014 */ + if (rxsc == 3) + bw = ODM_BW40M; + else if ((rxsc == 1) || (rxsc == 2)) + bw = ODM_BW20M; + else + bw = ODM_BW20M; + } + + /* Update packet information */ + phydm_set_common_phy_info(rx_pwr_db, phy_sta_rpt->channel, + (bool)phy_sta_rpt->beamformed, false, bw, 0, + rxsc, phy_info); +} + +static void +phydm_process_rssi_for_dm_new_type(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, + struct dm_per_pkt_info *pktinfo) +{ + s32 undecorated_smoothed_pwdb, accumulate_pwdb; + u32 rssi_ave; + u8 i; + struct rtl_sta_info *entry; + u8 scaling_factor = 4; + + if (pktinfo->station_id >= ODM_ASSOCIATE_ENTRY_NUM) + return; + + entry = dm->odm_sta_info[pktinfo->station_id]; + + if (!IS_STA_VALID(entry)) + return; + + if ((!pktinfo->is_packet_match_bssid)) /*data frame only*/ + return; + + if (pktinfo->is_packet_beacon) + dm->phy_dbg_info.num_qry_beacon_pkt++; + + if (pktinfo->is_packet_to_self || pktinfo->is_packet_beacon) { + u32 rssi_linear = 0; + + dm->rx_rate = pktinfo->data_rate; + undecorated_smoothed_pwdb = + entry->rssi_stat.undecorated_smoothed_pwdb; + accumulate_pwdb = dm->accumulate_pwdb[pktinfo->station_id]; + dm->rssi_a = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_A]; + dm->rssi_b = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_B]; + dm->rssi_c = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_C]; + dm->rssi_d = phy_info->rx_mimo_signal_strength[ODM_RF_PATH_D]; + + for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_MAX_JAGUAR; i++) { + if (phy_info->rx_mimo_signal_strength[i] != 0) + rssi_linear += odm_convert_to_linear( + phy_info->rx_mimo_signal_strength[i]); + } + + switch (phy_info->rx_count + 1) { + case 2: + rssi_linear = (rssi_linear >> 1); + break; + case 3: + /* rssi_linear/3 ~ rssi_linear*11/32 */ + rssi_linear = ((rssi_linear) + (rssi_linear << 1) + + (rssi_linear << 3)) >> + 5; + break; + case 4: + rssi_linear = (rssi_linear >> 2); + break; + } + rssi_ave = odm_convert_to_db(rssi_linear); + + if (undecorated_smoothed_pwdb <= 0) { + accumulate_pwdb = + (phy_info->rx_pwdb_all << scaling_factor); + undecorated_smoothed_pwdb = phy_info->rx_pwdb_all; + } else { + accumulate_pwdb = accumulate_pwdb - + (accumulate_pwdb >> scaling_factor) + + rssi_ave; + undecorated_smoothed_pwdb = + (accumulate_pwdb + + (1 << (scaling_factor - 1))) >> + scaling_factor; + } + + entry->rssi_stat.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; + dm->accumulate_pwdb[pktinfo->station_id] = accumulate_pwdb; + } +} + +void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info) +{ + u8 phy_status_type = (*phy_status & 0xf); + + /* Memory reset */ + phydm_reset_phy_info(phydm, phy_info); + + /* Phy status parsing */ + switch (phy_status_type) { + case 0: { + phydm_get_rx_phy_status_type0(phydm, phy_status, pktinfo, + phy_info); + break; + } + case 1: { + phydm_get_rx_phy_status_type1(phydm, phy_status, pktinfo, + phy_info); + break; + } + case 2: { + phydm_get_rx_phy_status_type2(phydm, phy_status, pktinfo, + phy_info); + break; + } + default: + return; + } + + /* Update signal strength to UI, and phy_info->rx_pwdb_all is the + * maximum RSSI of all path + */ + phy_info->signal_strength = + (u8)(odm_signal_scale_mapping(phydm, phy_info->rx_pwdb_all)); + + /* Calculate average RSSI and smoothed RSSI */ + phydm_process_rssi_for_dm_new_type(phydm, phy_info, pktinfo); +} + +u32 query_phydm_trx_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_stbc_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} + +u32 query_phydm_txbf_capability(struct phy_dm_struct *dm) +{ + u32 value32 = 0xFFFFFFFF; + + return value32; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h new file mode 100644 index 000000000000..ec94c61df2b9 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_hwconfig.h @@ -0,0 +1,510 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __HALHWOUTSRC_H__ +#define __HALHWOUTSRC_H__ + +/*--------------------------Define -------------------------------------------*/ +#define CCK_RSSI_INIT_COUNT 5 + +#define RA_RSSI_STATE_INIT 0 +#define RA_RSSI_STATE_SEND 1 +#define RA_RSSI_STATE_HOLD 2 + +#define CFO_HW_RPT_2_MHZ(val) ((val << 1) + (val >> 1)) +/* ((X* 3125) / 10)>>7 = (X*10)>>2 = X*2.5 = X<<1 + X>>1 */ + +#define AGC_DIFF_CONFIG_MP(ic, band) \ + (odm_read_and_config_mp_##ic##_agc_tab_diff( \ + dm, array_mp_##ic##_agc_tab_diff_##band, \ + sizeof(array_mp_##ic##_agc_tab_diff_##band) / sizeof(u32))) +#define AGC_DIFF_CONFIG_TC(ic, band) \ + (odm_read_and_config_tc_##ic##_agc_tab_diff( \ + dm, array_tc_##ic##_agc_tab_diff_##band, \ + sizeof(array_tc_##ic##_agc_tab_diff_##band) / sizeof(u32))) + +#define AGC_DIFF_CONFIG(ic, band) \ + do { \ + if (dm->is_mp_chip) \ + AGC_DIFF_CONFIG_MP(ic, band); \ + else \ + AGC_DIFF_CONFIG_TC(ic, band); \ + } while (0) + +/* ************************************************************ + * structure and define + * *************************************************************/ + +struct phy_rx_agc_info { +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 gain : 7, trsw : 1; +#else + u8 trsw : 1, gain : 7; +#endif +}; + +struct phy_status_rpt_8192cd { + struct phy_rx_agc_info path_agc[2]; + u8 ch_corr[2]; + u8 cck_sig_qual_ofdm_pwdb_all; + u8 cck_agc_rpt_ofdm_cfosho_a; + u8 cck_rpt_b_ofdm_cfosho_b; + u8 rsvd_1; /*ch_corr_msb;*/ + u8 noise_power_db_msb; + s8 path_cfotail[2]; + u8 pcts_mask[2]; + s8 stream_rxevm[2]; + u8 path_rxsnr[2]; + u8 noise_power_db_lsb; + u8 rsvd_2[3]; + u8 stream_csi[2]; + u8 stream_target_csi[2]; + s8 sig_evm; + u8 rsvd_3; + +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antsel_rx_keep_2 : 1; /*ex_intf_flg:1;*/ + u8 sgi_en : 1; + u8 rxsc : 2; + u8 idle_long : 1; + u8 r_ant_train_en : 1; + u8 ant_sel_b : 1; + u8 ant_sel : 1; +#else /*_BIG_ENDIAN_ */ + u8 ant_sel : 1; + u8 ant_sel_b : 1; + u8 r_ant_train_en : 1; + u8 idle_long : 1; + u8 rxsc : 2; + u8 sgi_en : 1; + u8 antsel_rx_keep_2 : 1; /*ex_intf_flg:1;*/ +#endif +}; + +struct phy_status_rpt_8812 { + /* DWORD 0*/ + u8 gain_trsw[2]; /*path-A and path-B {TRSW, gain[6:0] }*/ + u8 chl_num_LSB; /*channel number[7:0]*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 chl_num_MSB : 2; /*channel number[9:8]*/ + u8 sub_chnl : 4; /*sub-channel location[3:0]*/ + u8 r_RFMOD : 2; /*RF mode[1:0]*/ +#else /*_BIG_ENDIAN_ */ + u8 r_RFMOD : 2; + u8 sub_chnl : 4; + u8 chl_num_MSB : 2; +#endif + + /* DWORD 1*/ + u8 pwdb_all; /*CCK signal quality / OFDM pwdb all*/ + s8 cfosho[2]; /*DW1 byte 1 DW1 byte2 */ +/*CCK AGC report and CCK_BB_Power / OFDM path-A and path-B short CFO*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + /*this should be checked again + *because the definition of 8812 and 8814 is different + */ + u8 resvd_0 : 6; + u8 bt_RF_ch_MSB : 2; /*8812A:2'b0, 8814A: bt rf channel keep[7:6]*/ +#else /*_BIG_ENDIAN_*/ + u8 bt_RF_ch_MSB : 2; + u8 resvd_0 : 6; +#endif + +/* DWORD 2*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 ant_div_sw_a : 1; /*8812A: ant_div_sw_a, 8814A: 1'b0*/ + u8 ant_div_sw_b : 1; /*8812A: ant_div_sw_b, 8814A: 1'b0*/ + u8 bt_RF_ch_LSB : 6; /*8812A: 6'b0, 8814A: bt rf channel keep[5:0]*/ +#else /*_BIG_ENDIAN_ */ + u8 bt_RF_ch_LSB : 6; + u8 ant_div_sw_b : 1; + u8 ant_div_sw_a : 1; +#endif + s8 cfotail[2]; /*DW2 byte 1 DW2 byte 2 path-A and path-B CFO tail*/ + u8 PCTS_MSK_RPT_0; /*PCTS mask report[7:0]*/ + u8 PCTS_MSK_RPT_1; /*PCTS mask report[15:8]*/ + + /* DWORD 3*/ + s8 rxevm[2]; /*DW3 byte 1 DW3 byte 2 stream 1 and stream 2 RX EVM*/ + s8 rxsnr[2]; /*DW3 byte 3 DW4 byte 0 path-A and path-B RX SNR*/ + + /* DWORD 4*/ + u8 PCTS_MSK_RPT_2; /*PCTS mask report[23:16]*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 PCTS_MSK_RPT_3 : 6; /*PCTS mask report[29:24]*/ + u8 pcts_rpt_valid : 1; /*pcts_rpt_valid*/ + u8 resvd_1 : 1; /*1'b0*/ +#else /*_BIG_ENDIAN_*/ + u8 resvd_1 : 1; + u8 pcts_rpt_valid : 1; + u8 PCTS_MSK_RPT_3 : 6; +#endif + s8 rxevm_cd[2]; /*DW 4 byte 3 DW5 byte 0 */ + /* 8812A: 16'b0, 8814A: stream 3 and stream 4 RX EVM*/ + + /* DWORD 5*/ + u8 csi_current[2]; /*DW5 byte 1 DW5 byte 2 */ + /* 8812A: stream 1 and 2 CSI, 8814A: path-C and path-D RX SNR*/ + u8 gain_trsw_cd[2]; /*DW5 byte 3 DW6 byte 0 */ + /* path-C and path-D {TRSW, gain[6:0] }*/ + + /* DWORD 6*/ + s8 sigevm; /*signal field EVM*/ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_antc : 3; /*8812A: 3'b0 8814A: antidx_antc[2:0]*/ + u8 antidx_antd : 3; /*8812A: 3'b0 8814A: antidx_antd[2:0]*/ + u8 dpdt_ctrl_keep : 1; /*8812A: 1'b0 8814A: dpdt_ctrl_keep*/ + u8 GNT_BT_keep : 1; /*8812A: 1'b0 8814A: GNT_BT_keep*/ +#else /*_BIG_ENDIAN_*/ + u8 GNT_BT_keep : 1; + u8 dpdt_ctrl_keep : 1; + u8 antidx_antd : 3; + u8 antidx_antc : 3; +#endif +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_anta : 3; /*antidx_anta[2:0]*/ + u8 antidx_antb : 3; /*antidx_antb[2:0]*/ + u8 hw_antsw_occur : 2; /*1'b0*/ +#else /*_BIG_ENDIAN_*/ + u8 hw_antsw_occur : 2; + u8 antidx_antb : 3; + u8 antidx_anta : 3; +#endif +}; + +void phydm_reset_rssi_for_dm(struct phy_dm_struct *dm, u8 station_id); + +void odm_init_rssi_for_dm(struct phy_dm_struct *dm); + +void odm_phy_status_query(struct phy_dm_struct *dm, + struct dm_phy_status_info *phy_info, u8 *phy_status, + struct dm_per_pkt_info *pktinfo); + +void odm_mac_status_query(struct phy_dm_struct *dm, u8 *mac_status, u8 mac_id, + bool is_packet_match_bssid, bool is_packet_to_self, + bool is_packet_beacon); + +enum hal_status +odm_config_rf_with_tx_pwr_track_header_file(struct phy_dm_struct *dm); + +enum hal_status +odm_config_rf_with_header_file(struct phy_dm_struct *dm, + enum odm_rf_config_type config_type, + enum odm_rf_radio_path e_rf_path); + +enum hal_status +odm_config_bb_with_header_file(struct phy_dm_struct *dm, + enum odm_bb_config_type config_type); + +enum hal_status odm_config_mac_with_header_file(struct phy_dm_struct *dm); + +enum hal_status +odm_config_fw_with_header_file(struct phy_dm_struct *dm, + enum odm_fw_config_type config_type, + u8 *p_firmware, u32 *size); + +u32 odm_get_hw_img_version(struct phy_dm_struct *dm); + +s32 odm_signal_scale_mapping(struct phy_dm_struct *dm, s32 curr_sig); + +/*For 8822B only!! need to move to FW finally */ +/*==============================================*/ +void phydm_rx_phy_status_new_type(struct phy_dm_struct *phydm, u8 *phy_status, + struct dm_per_pkt_info *pktinfo, + struct dm_phy_status_info *phy_info); + +bool phydm_query_is_mu_api(struct phy_dm_struct *phydm, u8 ppdu_idx, + u8 *p_data_rate, u8 *p_gid); + +struct phy_status_rpt_jaguar2_type0 { + /* DW0 */ + u8 page_num; + u8 pwdb; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 gain : 6; + u8 rsvd_0 : 1; + u8 trsw : 1; +#else + u8 trsw : 1; + u8 rsvd_0 : 1; + u8 gain : 6; +#endif + u8 rsvd_1; + + /* DW1 */ + u8 rsvd_2; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 rxsc : 4; + u8 agc_table : 4; +#else + u8 agc_table : 4; + u8 rxsc : 4; +#endif + u8 channel; + u8 band; + + /* DW2 */ + u16 length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_a : 3; + u8 antidx_b : 3; + u8 rsvd_3 : 2; + u8 antidx_c : 3; + u8 antidx_d : 3; + u8 rsvd_4 : 2; +#else + u8 rsvd_3 : 2; + u8 antidx_b : 3; + u8 antidx_a : 3; + u8 rsvd_4 : 2; + u8 antidx_d : 3; + u8 antidx_c : 3; +#endif + + /* DW3 */ + u8 signal_quality; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 vga : 5; + u8 lna_l : 3; + u8 bb_power : 6; + u8 rsvd_9 : 1; + u8 lna_h : 1; +#else + u8 lna_l : 3; + u8 vga : 5; + u8 lna_h : 1; + u8 rsvd_9 : 1; + u8 bb_power : 6; +#endif + u8 rsvd_5; + + /* DW4 */ + u32 rsvd_6; + + /* DW5 */ + u32 rsvd_7; + + /* DW6 */ + u32 rsvd_8; +}; + +struct phy_status_rpt_jaguar2_type1 { + /* DW0 and DW1 */ + u8 page_num; + u8 pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 l_rxsc : 4; + u8 ht_rxsc : 4; +#else + u8 ht_rxsc : 4; + u8 l_rxsc : 4; +#endif + u8 channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 band : 2; + u8 rsvd_0 : 1; + u8 hw_antsw_occu : 1; + u8 gnt_bt : 1; + u8 ldpc : 1; + u8 stbc : 1; + u8 beamformed : 1; +#else + u8 beamformed : 1; + u8 stbc : 1; + u8 ldpc : 1; + u8 gnt_bt : 1; + u8 hw_antsw_occu : 1; + u8 rsvd_0 : 1; + u8 band : 2; +#endif + + /* DW2 */ + u16 lsig_length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 antidx_a : 3; + u8 antidx_b : 3; + u8 rsvd_1 : 2; + u8 antidx_c : 3; + u8 antidx_d : 3; + u8 rsvd_2 : 2; +#else + u8 rsvd_1 : 2; + u8 antidx_b : 3; + u8 antidx_a : 3; + u8 rsvd_2 : 2; + u8 antidx_d : 3; + u8 antidx_c : 3; +#endif + + /* DW3 */ + u8 paid; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 paid_msb : 1; + u8 gid : 6; + u8 rsvd_3 : 1; +#else + u8 rsvd_3 : 1; + u8 gid : 6; + u8 paid_msb : 1; +#endif + u8 intf_pos; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 intf_pos_msb : 1; + u8 rsvd_4 : 2; + u8 nb_intf_flag : 1; + u8 rf_mode : 2; + u8 rsvd_5 : 2; +#else + u8 rsvd_5 : 2; + u8 rf_mode : 2; + u8 nb_intf_flag : 1; + u8 rsvd_4 : 2; + u8 intf_pos_msb : 1; +#endif + + /* DW4 */ + s8 rxevm[4]; /* s(8,1) */ + + /* DW5 */ + s8 cfo_tail[4]; /* s(8,7) */ + + /* DW6 */ + s8 rxsnr[4]; /* s(8,1) */ +}; + +struct phy_status_rpt_jaguar2_type2 { + /* DW0 ane DW1 */ + u8 page_num; + u8 pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 l_rxsc : 4; + u8 ht_rxsc : 4; +#else + u8 ht_rxsc : 4; + u8 l_rxsc : 4; +#endif + u8 channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 band : 2; + u8 rsvd_0 : 1; + u8 hw_antsw_occu : 1; + u8 gnt_bt : 1; + u8 ldpc : 1; + u8 stbc : 1; + u8 beamformed : 1; +#else + u8 beamformed : 1; + u8 stbc : 1; + u8 ldpc : 1; + u8 gnt_bt : 1; + u8 hw_antsw_occu : 1; + u8 rsvd_0 : 1; + u8 band : 2; +#endif + +/* DW2 */ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 shift_l_map : 6; + u8 rsvd_1 : 2; +#else + u8 rsvd_1 : 2; + u8 shift_l_map : 6; +#endif + u8 cnt_pw2cca; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 agc_table_a : 4; + u8 agc_table_b : 4; + u8 agc_table_c : 4; + u8 agc_table_d : 4; +#else + u8 agc_table_b : 4; + u8 agc_table_a : 4; + u8 agc_table_d : 4; + u8 agc_table_c : 4; +#endif + + /* DW3 ~ DW6*/ + u8 cnt_cca2agc_rdy; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 gain_a : 6; + u8 rsvd_2 : 1; + u8 trsw_a : 1; + u8 gain_b : 6; + u8 rsvd_3 : 1; + u8 trsw_b : 1; + u8 gain_c : 6; + u8 rsvd_4 : 1; + u8 trsw_c : 1; + u8 gain_d : 6; + u8 rsvd_5 : 1; + u8 trsw_d : 1; + u8 aagc_step_a : 2; + u8 aagc_step_b : 2; + u8 aagc_step_c : 2; + u8 aagc_step_d : 2; +#else + u8 trsw_a : 1; + u8 rsvd_2 : 1; + u8 gain_a : 6; + u8 trsw_b : 1; + u8 rsvd_3 : 1; + u8 gain_b : 6; + u8 trsw_c : 1; + u8 rsvd_4 : 1; + u8 gain_c : 6; + u8 trsw_d : 1; + u8 rsvd_5 : 1; + u8 gain_d : 6; + u8 aagc_step_d : 2; + u8 aagc_step_c : 2; + u8 aagc_step_b : 2; + u8 aagc_step_a : 2; +#endif + u8 ht_aagc_gain[4]; + u8 dagc_gain[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u8 counter : 6; + u8 rsvd_6 : 2; + u8 syn_count : 5; + u8 rsvd_7 : 3; +#else + u8 rsvd_6 : 2; + u8 counter : 6; + u8 rsvd_7 : 3; + u8 syn_count : 5; +#endif +}; + +u32 query_phydm_trx_capability(struct phy_dm_struct *dm); + +u32 query_phydm_stbc_capability(struct phy_dm_struct *dm); + +u32 query_phydm_ldpc_capability(struct phy_dm_struct *dm); + +u32 query_phydm_txbf_parameters(struct phy_dm_struct *dm); + +u32 query_phydm_txbf_capability(struct phy_dm_struct *dm); + +#endif /*#ifndef __HALHWOUTSRC_H__*/ diff --git a/drivers/staging/rtlwifi/phydm/phydm_interface.c b/drivers/staging/rtlwifi/phydm/phydm_interface.c new file mode 100644 index 000000000000..102576a46c04 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_interface.c @@ -0,0 +1,341 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ + +#include "mp_precomp.h" +#include "phydm_precomp.h" + +/* + * ODM IO Relative API. + */ + +u8 odm_read_1byte(struct phy_dm_struct *dm, u32 reg_addr) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_read_byte(rtlpriv, reg_addr); +} + +u16 odm_read_2byte(struct phy_dm_struct *dm, u32 reg_addr) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_read_word(rtlpriv, reg_addr); +} + +u32 odm_read_4byte(struct phy_dm_struct *dm, u32 reg_addr) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_read_dword(rtlpriv, reg_addr); +} + +void odm_write_1byte(struct phy_dm_struct *dm, u32 reg_addr, u8 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_write_byte(rtlpriv, reg_addr, data); +} + +void odm_write_2byte(struct phy_dm_struct *dm, u32 reg_addr, u16 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_write_word(rtlpriv, reg_addr, data); +} + +void odm_write_4byte(struct phy_dm_struct *dm, u32 reg_addr, u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_write_dword(rtlpriv, reg_addr, data); +} + +void odm_set_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data); +} + +u32 odm_get_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask); +} + +void odm_set_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_set_bbreg(rtlpriv->hw, reg_addr, bit_mask, data); +} + +u32 odm_get_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_get_bbreg(rtlpriv->hw, reg_addr, bit_mask); +} + +void odm_set_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask, u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + rtl_set_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr, + bit_mask, data); +} + +u32 odm_get_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + + return rtl_get_rfreg(rtlpriv->hw, (enum radio_path)e_rf_path, reg_addr, + bit_mask); +} + +/* + * ODM Memory relative API. + */ +void odm_allocate_memory(struct phy_dm_struct *dm, void **ptr, u32 length) +{ + *ptr = kmalloc(length, GFP_ATOMIC); +} + +/* length could be ignored, used to detect memory leakage. */ +void odm_free_memory(struct phy_dm_struct *dm, void *ptr, u32 length) +{ + kfree(ptr); +} + +void odm_move_memory(struct phy_dm_struct *dm, void *p_dest, void *src, + u32 length) +{ + memcpy(p_dest, src, length); +} + +void odm_memory_set(struct phy_dm_struct *dm, void *pbuf, s8 value, u32 length) +{ + memset(pbuf, value, length); +} + +s32 odm_compare_memory(struct phy_dm_struct *dm, void *p_buf1, void *buf2, + u32 length) +{ + return memcmp(p_buf1, buf2, length); +} + +/* + * ODM MISC relative API. + */ +void odm_acquire_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type) +{ +} + +void odm_release_spin_lock(struct phy_dm_struct *dm, enum rt_spinlock_type type) +{ +} + +/* + * ODM Timer relative API. + */ +void odm_stall_execution(u32 us_delay) { udelay(us_delay); } + +void ODM_delay_ms(u32 ms) { mdelay(ms); } + +void ODM_delay_us(u32 us) { udelay(us); } + +void ODM_sleep_ms(u32 ms) { msleep(ms); } + +void ODM_sleep_us(u32 us) { usleep_range(us, us + 1); } + +void odm_set_timer(struct phy_dm_struct *dm, struct timer_list *timer, + u32 ms_delay) +{ + mod_timer(timer, jiffies + msecs_to_jiffies(ms_delay)); +} + +void odm_initialize_timer(struct phy_dm_struct *dm, struct timer_list *timer, + void *call_back_func, void *context, + const char *sz_id) +{ + init_timer(timer); + timer->function = call_back_func; + timer->data = (unsigned long)dm; + /*mod_timer(timer, jiffies+RTL_MILISECONDS_TO_JIFFIES(10)); */ +} + +void odm_cancel_timer(struct phy_dm_struct *dm, struct timer_list *timer) +{ + del_timer(timer); +} + +void odm_release_timer(struct phy_dm_struct *dm, struct timer_list *timer) {} + +static u8 phydm_trans_h2c_id(struct phy_dm_struct *dm, u8 phydm_h2c_id) +{ + u8 platform_h2c_id = phydm_h2c_id; + + switch (phydm_h2c_id) { + /* 1 [0] */ + case ODM_H2C_RSSI_REPORT: + + break; + + /* 1 [3] */ + case ODM_H2C_WIFI_CALIBRATION: + + break; + + /* 1 [4] */ + case ODM_H2C_IQ_CALIBRATION: + + break; + /* 1 [5] */ + case ODM_H2C_RA_PARA_ADJUST: + + break; + + /* 1 [6] */ + case PHYDM_H2C_DYNAMIC_TX_PATH: + + break; + + /* [7]*/ + case PHYDM_H2C_FW_TRACE_EN: + + platform_h2c_id = 0x49; + + break; + + case PHYDM_H2C_TXBF: + break; + + case PHYDM_H2C_MU: + platform_h2c_id = 0x4a; /*H2C_MU*/ + break; + + default: + platform_h2c_id = phydm_h2c_id; + break; + } + + return platform_h2c_id; +} + +/*ODM FW relative API.*/ + +void odm_fill_h2c_cmd(struct phy_dm_struct *dm, u8 phydm_h2c_id, u32 cmd_len, + u8 *cmd_buffer) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + u8 platform_h2c_id; + + platform_h2c_id = phydm_trans_h2c_id(dm, phydm_h2c_id); + + ODM_RT_TRACE(dm, PHYDM_COMP_RA_DBG, + "[H2C] platform_h2c_id = ((0x%x))\n", platform_h2c_id); + + rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->hw, platform_h2c_id, cmd_len, + cmd_buffer); +} + +u8 phydm_c2H_content_parsing(void *dm_void, u8 c2h_cmd_id, u8 c2h_cmd_len, + u8 *tmp_buf) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 extend_c2h_sub_id = 0; + u8 find_c2h_cmd = true; + + switch (c2h_cmd_id) { + case PHYDM_C2H_DBG: + phydm_fw_trace_handler(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_RA_RPT: + phydm_c2h_ra_report_handler(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_RA_PARA_RPT: + odm_c2h_ra_para_report_handler(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_DYNAMIC_TX_PATH_RPT: + break; + + case PHYDM_C2H_IQK_FINISH: + break; + + case PHYDM_C2H_DBG_CODE: + phydm_fw_trace_handler_code(dm, tmp_buf, c2h_cmd_len); + break; + + case PHYDM_C2H_EXTEND: + extend_c2h_sub_id = tmp_buf[0]; + if (extend_c2h_sub_id == PHYDM_EXTEND_C2H_DBG_PRINT) + phydm_fw_trace_handler_8051(dm, tmp_buf, c2h_cmd_len); + + break; + + default: + find_c2h_cmd = false; + break; + } + + return find_c2h_cmd; +} + +u64 odm_get_current_time(struct phy_dm_struct *dm) { return jiffies; } + +u64 odm_get_progressing_time(struct phy_dm_struct *dm, u64 start_time) +{ + return jiffies_to_msecs(jiffies - (u32)start_time); +} + +void odm_set_tx_power_index_by_rate_section(struct phy_dm_struct *dm, + u8 rf_path, u8 channel, + u8 rate_section) +{ + void *adapter = dm->adapter; + + phy_set_tx_power_index_by_rs(adapter, channel, rf_path, rate_section); +} + +u8 odm_get_tx_power_index(struct phy_dm_struct *dm, u8 rf_path, u8 tx_rate, + u8 band_width, u8 channel) +{ + void *adapter = dm->adapter; + + return phy_get_tx_power_index(adapter, (enum odm_rf_radio_path)rf_path, + tx_rate, band_width, channel); +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_interface.h b/drivers/staging/rtlwifi/phydm/phydm_interface.h new file mode 100644 index 000000000000..d315c79c962a --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_interface.h @@ -0,0 +1,205 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_INTERFACE_H__ +#define __ODM_INTERFACE_H__ + +#define INTERFACE_VERSION "1.1" /*2015.07.29 YuChen*/ + +/* + * =========== Constant/Structure/Enum/... Define + */ + +/* + * =========== Macro Define + */ + +#define _reg_all(_name) ODM_##_name +#define _reg_ic(_name, _ic) ODM_##_name##_ic +#define _bit_all(_name) BIT_##_name +#define _bit_ic(_name, _ic) BIT_##_name##_ic + +/* _cat: implemented by Token-Pasting Operator. */ + +/*=================================== + * + * #define ODM_REG_DIG_11N 0xC50 + * #define ODM_REG_DIG_11AC 0xDDD + * + * ODM_REG(DIG,_pdm_odm) + * =================================== + */ + +#define _reg_11N(_name) ODM_REG_##_name##_11N +#define _reg_11AC(_name) ODM_REG_##_name##_11AC +#define _bit_11N(_name) ODM_BIT_##_name##_11N +#define _bit_11AC(_name) ODM_BIT_##_name##_11AC + +#define _cat(_name, _ic_type, _func) \ + (((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \ + _func##_11AC(_name)) + +/* _name: name of register or bit. + * Example: "ODM_REG(R_A_AGC_CORE1, dm)" + * gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", + * depends on support_ic_type. + */ +#define ODM_REG(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _reg) +#define ODM_BIT(_name, _pdm_odm) _cat(_name, _pdm_odm->support_ic_type, _bit) +enum phydm_h2c_cmd { + PHYDM_H2C_TXBF = 0x41, + ODM_H2C_RSSI_REPORT = 0x42, + ODM_H2C_IQ_CALIBRATION = 0x45, + ODM_H2C_RA_PARA_ADJUST = 0x47, + PHYDM_H2C_DYNAMIC_TX_PATH = 0x48, + PHYDM_H2C_FW_TRACE_EN = 0x49, + ODM_H2C_WIFI_CALIBRATION = 0x6d, + PHYDM_H2C_MU = 0x4a, + ODM_MAX_H2CCMD +}; + +enum phydm_c2h_evt { + PHYDM_C2H_DBG = 0, + PHYDM_C2H_LB = 1, + PHYDM_C2H_XBF = 2, + PHYDM_C2H_TX_REPORT = 3, + PHYDM_C2H_INFO = 9, + PHYDM_C2H_BT_MP = 11, + PHYDM_C2H_RA_RPT = 12, + PHYDM_C2H_RA_PARA_RPT = 14, + PHYDM_C2H_DYNAMIC_TX_PATH_RPT = 15, + PHYDM_C2H_IQK_FINISH = 17, /*0x11*/ + PHYDM_C2H_DBG_CODE = 0xFE, + PHYDM_C2H_EXTEND = 0xFF, +}; + +enum phydm_extend_c2h_evt { + PHYDM_EXTEND_C2H_DBG_PRINT = 0 + +}; + +/* + * =========== Extern Variable ??? It should be forbidden. + */ + +/* + * =========== EXtern Function Prototype + */ + +u8 odm_read_1byte(struct phy_dm_struct *dm, u32 reg_addr); + +u16 odm_read_2byte(struct phy_dm_struct *dm, u32 reg_addr); + +u32 odm_read_4byte(struct phy_dm_struct *dm, u32 reg_addr); + +void odm_write_1byte(struct phy_dm_struct *dm, u32 reg_addr, u8 data); + +void odm_write_2byte(struct phy_dm_struct *dm, u32 reg_addr, u16 data); + +void odm_write_4byte(struct phy_dm_struct *dm, u32 reg_addr, u32 data); + +void odm_set_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data); + +u32 odm_get_mac_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask); + +void odm_set_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask, + u32 data); + +u32 odm_get_bb_reg(struct phy_dm_struct *dm, u32 reg_addr, u32 bit_mask); + +void odm_set_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask, u32 data); + +u32 odm_get_rf_reg(struct phy_dm_struct *dm, enum odm_rf_radio_path e_rf_path, + u32 reg_addr, u32 bit_mask); + +/* + * Memory Relative Function. + */ +void odm_allocate_memory(struct phy_dm_struct *dm, void **ptr, u32 length); +void odm_free_memory(struct phy_dm_struct *dm, void *ptr, u32 length); + +void odm_move_memory(struct phy_dm_struct *dm, void *p_dest, void *src, + u32 length); + +s32 odm_compare_memory(struct phy_dm_struct *dm, void *p_buf1, void *buf2, + u32 length); + +void odm_memory_set(struct phy_dm_struct *dm, void *pbuf, s8 value, u32 length); + +/* + * ODM MISC-spin lock relative API. + */ +void odm_acquire_spin_lock(struct phy_dm_struct *dm, + enum rt_spinlock_type type); + +void odm_release_spin_lock(struct phy_dm_struct *dm, + enum rt_spinlock_type type); + +/* + * ODM Timer relative API. + */ +void odm_stall_execution(u32 us_delay); + +void ODM_delay_ms(u32 ms); + +void ODM_delay_us(u32 us); + +void ODM_sleep_ms(u32 ms); + +void ODM_sleep_us(u32 us); + +void odm_set_timer(struct phy_dm_struct *dm, struct timer_list *timer, + u32 ms_delay); + +void odm_initialize_timer(struct phy_dm_struct *dm, struct timer_list *timer, + void *call_back_func, void *context, + const char *sz_id); + +void odm_cancel_timer(struct phy_dm_struct *dm, struct timer_list *timer); + +void odm_release_timer(struct phy_dm_struct *dm, struct timer_list *timer); + +/* + * ODM FW relative API. + */ +void odm_fill_h2c_cmd(struct phy_dm_struct *dm, u8 element_id, u32 cmd_len, + u8 *cmd_buffer); + +u8 phydm_c2H_content_parsing(void *dm_void, u8 c2h_cmd_id, u8 c2h_cmd_len, + u8 *tmp_buf); + +u64 odm_get_current_time(struct phy_dm_struct *dm); +u64 odm_get_progressing_time(struct phy_dm_struct *dm, u64 start_time); + +void odm_set_tx_power_index_by_rate_section(struct phy_dm_struct *dm, + u8 rf_path, u8 channel, + u8 rate_section); + +u8 odm_get_tx_power_index(struct phy_dm_struct *dm, u8 rf_path, u8 tx_rate, + u8 band_width, u8 channel); + +#endif /* __ODM_INTERFACE_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_iqk.h b/drivers/staging/rtlwifi/phydm/phydm_iqk.h new file mode 100644 index 000000000000..0d45bf099aeb --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_iqk.h @@ -0,0 +1,76 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMIQK_H__ +#define __PHYDMIQK_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define LOK_delay 1 +#define WBIQK_delay 10 +#define TX_IQK 0 +#define RX_IQK 1 +#define TXIQK 0 +#define RXIQK1 1 +#define RXIQK2 2 +#define GSRXK1 0 +#define GSRXK2 1 +#define kcount_limit_80m 2 +#define kcount_limit_others 4 +#define rxiqk_gs_limit 4 + +#define NUM 4 +/*----------------------End Define Parameters-------------------------------*/ + +struct dm_iqk_info { + bool lok_fail[NUM]; + bool iqk_fail[2][NUM]; + u32 iqc_matrix[2][NUM]; + u8 iqk_times; + u32 rf_reg18; + u32 lna_idx; + u8 rxiqk_step; + u8 tmp1bcc; + u8 kcount; + + u32 iqk_channel[2]; + bool iqk_fail_report[2][4][2]; /*channel/path/TRX(TX:0, RX:1) */ + u32 iqk_cfir_real[2][4][2] + [8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_real*/ + u32 iqk_cfir_imag[2][4][2] + [8]; /*channel / path / TRX(TX:0, RX:1) / CFIR_imag*/ + u8 retry_count[2][4][3]; /* channel / path / (TXK:0, RXK1:1, RXK2:2) */ + u8 gs_retry_count[2][4][2]; /* channel / path / (GSRXK1:0, GSRXK2:1) */ + u8 rxiqk_fail_code[2][4]; /* channel / path + * 0:SRXK1 fail, 1:RXK1 fail 2:RXK2 fail + */ + u32 lok_idac[2][4]; /*channel / path*/ + u16 rxiqk_agc[2][4]; /*channel / path*/ + u32 bypass_iqk[2][4]; /*channel / 0xc94/0xe94*/ + u32 tmp_gntwl; + bool is_btg; + bool isbnd; +}; + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_kfree.c b/drivers/staging/rtlwifi/phydm/phydm_kfree.c new file mode 100644 index 000000000000..5f3582341806 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_kfree.c @@ -0,0 +1,228 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*============================================================*/ +/*include files*/ +/*============================================================*/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +/* Add for KFree Feature Requested by RF David.*/ +/*This is a phydm API*/ + +static void phydm_set_kfree_to_rf_8814a(void *dm_void, u8 e_rf_path, u8 data) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + bool is_odd; + + if ((data % 2) != 0) { /*odd->positive*/ + data = data - 1; + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), + 1); + is_odd = true; + } else { /*even->negative*/ + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(19), + 0); + is_odd = false; + } + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): RF_0x55[19]= %d\n", __func__, + is_odd); + switch (data) { + case 0: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 0); + cali_info->kfree_offset[e_rf_path] = 0; + break; + case 2: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 0); + cali_info->kfree_offset[e_rf_path] = 0; + break; + case 4: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 1); + cali_info->kfree_offset[e_rf_path] = 1; + break; + case 6: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 1); + cali_info->kfree_offset[e_rf_path] = 1; + break; + case 8: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 2); + cali_info->kfree_offset[e_rf_path] = 2; + break; + case 10: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 2); + cali_info->kfree_offset[e_rf_path] = 2; + break; + case 12: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 3); + cali_info->kfree_offset[e_rf_path] = 3; + break; + case 14: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 3); + cali_info->kfree_offset[e_rf_path] = 3; + break; + case 16: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 4); + cali_info->kfree_offset[e_rf_path] = 4; + break; + case 18: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 1); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 4); + cali_info->kfree_offset[e_rf_path] = 4; + break; + case 20: + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, BIT(14), + 0); + odm_set_rf_reg(dm, e_rf_path, REG_RF_TX_GAIN_OFFSET, + BIT(17) | BIT(16) | BIT(15), 5); + cali_info->kfree_offset[e_rf_path] = 5; + break; + + default: + break; + } + + if (!is_odd) { + /*that means Kfree offset is negative, we need to record it.*/ + cali_info->kfree_offset[e_rf_path] = + (-1) * cali_info->kfree_offset[e_rf_path]; + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n", + __func__, cali_info->kfree_offset[e_rf_path]); + } else { + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): kfree_offset = %d\n", + __func__, cali_info->kfree_offset[e_rf_path]); + } +} + +static void phydm_set_kfree_to_rf(void *dm_void, u8 e_rf_path, u8 data) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->support_ic_type & ODM_RTL8814A) + phydm_set_kfree_to_rf_8814a(dm, e_rf_path, data); +} + +void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + u8 rfpath = 0, max_rf_path = 0; + u8 channel_idx = 0; + + if (dm->support_ic_type & ODM_RTL8814A) + max_rf_path = 4; /*0~3*/ + else if (dm->support_ic_type & + (ODM_RTL8812 | ODM_RTL8192E | ODM_RTL8822B)) + max_rf_path = 2; /*0~1*/ + else + max_rf_path = 1; + + ODM_RT_TRACE(dm, ODM_COMP_MP, "===>%s()\n", __func__); + + if (cali_info->reg_rf_kfree_enable == 2) { + ODM_RT_TRACE(dm, ODM_COMP_MP, + "%s(): reg_rf_kfree_enable == 2, Disable\n", + __func__); + return; + } + + if (cali_info->reg_rf_kfree_enable != 1 && + cali_info->reg_rf_kfree_enable != 0) { + ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): reg_rf_kfree_enable == true\n", + __func__); + /*Make sure the targetval is defined*/ + if (((cali_info->reg_rf_kfree_enable == 1) && + (kfree_table[0] != 0xFF)) || + cali_info->rf_kfree_enable) { + /*if kfree_table[0] == 0xff, means no Kfree*/ + if (*dm->band_type == ODM_BAND_2_4G) { + if (channel_to_sw <= 14 && channel_to_sw >= 1) + channel_idx = PHYDM_2G; + } else if (*dm->band_type == ODM_BAND_5G) { + if (channel_to_sw >= 36 && channel_to_sw <= 48) + channel_idx = PHYDM_5GLB1; + if (channel_to_sw >= 52 && channel_to_sw <= 64) + channel_idx = PHYDM_5GLB2; + if (channel_to_sw >= 100 && channel_to_sw <= 120) + channel_idx = PHYDM_5GMB1; + if (channel_to_sw >= 124 && channel_to_sw <= 144) + channel_idx = PHYDM_5GMB2; + if (channel_to_sw >= 149 && channel_to_sw <= 177) + channel_idx = PHYDM_5GHB; + } + + for (rfpath = ODM_RF_PATH_A; rfpath < max_rf_path; rfpath++) { + ODM_RT_TRACE(dm, ODM_COMP_MP, "%s(): PATH_%d: %#x\n", + __func__, rfpath, + kfree_table[channel_idx * max_rf_path + + rfpath]); + phydm_set_kfree_to_rf( + dm, rfpath, + kfree_table[channel_idx * max_rf_path + + rfpath]); + } + } else { + ODM_RT_TRACE( + dm, ODM_COMP_MP, + "%s(): targetval not defined, Don't execute KFree Process.\n", + __func__); + return; + } + + ODM_RT_TRACE(dm, ODM_COMP_MP, "<===%s()\n", __func__); +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_kfree.h b/drivers/staging/rtlwifi/phydm/phydm_kfree.h new file mode 100644 index 000000000000..1ee60059afc1 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_kfree.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMKFREE_H__ +#define __PHYDKFREE_H__ + +#define KFREE_VERSION "1.0" + +enum phydm_kfree_channeltosw { + PHYDM_2G = 0, + PHYDM_5GLB1 = 1, + PHYDM_5GLB2 = 2, + PHYDM_5GMB1 = 3, + PHYDM_5GMB2 = 4, + PHYDM_5GHB = 5, +}; + +void phydm_config_kfree(void *dm_void, u8 channel_to_sw, u8 *kfree_table); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c new file mode 100644 index 000000000000..8d79a5add1b4 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.c @@ -0,0 +1,330 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" +#include "phydm_noisemonitor.h" + +/* ************************************************* + * This function is for inband noise test utility only + * To obtain the inband noise level(dbm), do the following. + * 1. disable DIG and Power Saving + * 2. Set initial gain = 0x1a + * 3. Stop updating idle time pwer report (for driver read) + * - 0x80c[25] + * + * **************************************************/ + +#define VALID_MIN -35 +#define VALID_MAX 10 +#define VALID_CNT 5 + +static inline void phydm_set_noise_data_sum(struct noise_level *noise_data, + u8 max_rf_path) +{ + u8 rf_path; + + for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; rf_path++) { + if (noise_data->valid_cnt[rf_path]) + noise_data->sum[rf_path] /= + noise_data->valid_cnt[rf_path]; + else + noise_data->sum[rf_path] = 0; + } +} + +static s16 odm_inband_noise_monitor_n_series(struct phy_dm_struct *dm, + u8 is_pause_dig, u8 igi_value, + u32 max_time) +{ + u32 tmp4b; + u8 max_rf_path = 0, rf_path; + u8 reg_c50, reg_c58, valid_done = 0; + struct noise_level noise_data; + u64 start = 0, func_start = 0, func_end = 0; + + func_start = odm_get_current_time(dm); + dm->noise_level.noise_all = 0; + + if ((dm->rf_type == ODM_1T2R) || (dm->rf_type == ODM_2T2R)) + max_rf_path = 2; + else + max_rf_path = 1; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() ==>\n", __func__); + + odm_memory_set(dm, &noise_data, 0, sizeof(struct noise_level)); + + /* */ + /* step 1. Disable DIG && Set initial gain. */ + /* */ + + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value); + /* */ + /* step 2. Disable all power save for read registers */ + /* */ + /* dcmd_DebugControlPowerSave(adapter, PSDisable); */ + + /* */ + /* step 3. Get noise power level */ + /* */ + start = odm_get_current_time(dm); + while (1) { + /* Stop updating idle time pwer report (for driver read) */ + odm_set_bb_reg(dm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 1); + + /* Read Noise Floor Report */ + tmp4b = odm_get_bb_reg(dm, 0x8f8, MASKDWORD); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "Noise Floor Report (0x8f8) = 0x%08x\n", tmp4b); + + /* update idle time pwer report per 5us */ + odm_set_bb_reg(dm, REG_FPGA0_TX_GAIN_STAGE, BIT(25), 0); + + noise_data.value[ODM_RF_PATH_A] = (u8)(tmp4b & 0xff); + noise_data.value[ODM_RF_PATH_B] = (u8)((tmp4b & 0xff00) >> 8); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "value_a = 0x%x(%d), value_b = 0x%x(%d)\n", + noise_data.value[ODM_RF_PATH_A], + noise_data.value[ODM_RF_PATH_A], + noise_data.value[ODM_RF_PATH_B], + noise_data.value[ODM_RF_PATH_B]); + + for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; + rf_path++) { + noise_data.sval[rf_path] = + (s8)noise_data.value[rf_path]; + noise_data.sval[rf_path] /= 2; + } + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "sval_a = %d, sval_b = %d\n", + noise_data.sval[ODM_RF_PATH_A], + noise_data.sval[ODM_RF_PATH_B]); + + for (rf_path = ODM_RF_PATH_A; rf_path < max_rf_path; + rf_path++) { + if (!(noise_data.valid_cnt[rf_path] < VALID_CNT) || + !(noise_data.sval[rf_path] < VALID_MAX && + noise_data.sval[rf_path] >= VALID_MIN)) { + continue; + } + + noise_data.valid_cnt[rf_path]++; + noise_data.sum[rf_path] += noise_data.sval[rf_path]; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "rf_path:%d Valid sval = %d\n", rf_path, + noise_data.sval[rf_path]); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Sum of sval = %d,\n", + noise_data.sum[rf_path]); + if (noise_data.valid_cnt[rf_path] == VALID_CNT) { + valid_done++; + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "After divided, rf_path:%d,sum = %d\n", + rf_path, noise_data.sum[rf_path]); + } + } + + if ((valid_done == max_rf_path) || + (odm_get_progressing_time(dm, start) > max_time)) { + phydm_set_noise_data_sum(&noise_data, max_rf_path); + break; + } + } + reg_c50 = (u8)odm_get_bb_reg(dm, REG_OFDM_0_XA_AGC_CORE1, MASKBYTE0); + reg_c50 &= ~BIT(7); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "0x%x = 0x%02x(%d)\n", + REG_OFDM_0_XA_AGC_CORE1, reg_c50, reg_c50); + dm->noise_level.noise[ODM_RF_PATH_A] = + (u8)(-110 + reg_c50 + noise_data.sum[ODM_RF_PATH_A]); + dm->noise_level.noise_all += dm->noise_level.noise[ODM_RF_PATH_A]; + + if (max_rf_path == 2) { + reg_c58 = (u8)odm_get_bb_reg(dm, REG_OFDM_0_XB_AGC_CORE1, + MASKBYTE0); + reg_c58 &= ~BIT(7); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "0x%x = 0x%02x(%d)\n", + REG_OFDM_0_XB_AGC_CORE1, reg_c58, reg_c58); + dm->noise_level.noise[ODM_RF_PATH_B] = + (u8)(-110 + reg_c58 + noise_data.sum[ODM_RF_PATH_B]); + dm->noise_level.noise_all += + dm->noise_level.noise[ODM_RF_PATH_B]; + } + dm->noise_level.noise_all /= max_rf_path; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "noise_a = %d, noise_b = %d\n", + dm->noise_level.noise[ODM_RF_PATH_A], + dm->noise_level.noise[ODM_RF_PATH_B]); + + /* */ + /* step 4. Recover the Dig */ + /* */ + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value); + func_end = odm_get_progressing_time(dm, func_start); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() <==\n", __func__); + return dm->noise_level.noise_all; +} + +static s16 odm_inband_noise_monitor_ac_series(struct phy_dm_struct *dm, + u8 is_pause_dig, u8 igi_value, + u32 max_time) +{ + s32 rxi_buf_anta, rxq_buf_anta; /*rxi_buf_antb, rxq_buf_antb;*/ + s32 value32, pwdb_A = 0, sval, noise, sum; + bool pd_flag; + u8 valid_cnt; + u64 start = 0, func_start = 0, func_end = 0; + + if (!(dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A))) + return 0; + + func_start = odm_get_current_time(dm); + dm->noise_level.noise_all = 0; + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() ==>\n", __func__); + + /* step 1. Disable DIG && Set initial gain. */ + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_1, igi_value); + + /* step 2. Disable all power save for read registers */ + /*dcmd_DebugControlPowerSave(adapter, PSDisable); */ + + /* step 3. Get noise power level */ + start = odm_get_current_time(dm); + + /* reset counters */ + sum = 0; + valid_cnt = 0; + + /* step 3. Get noise power level */ + while (1) { + /*Set IGI=0x1C */ + odm_write_dig(dm, 0x1C); + /*stop CK320&CK88 */ + odm_set_bb_reg(dm, 0x8B4, BIT(6), 1); + /*Read path-A */ + odm_set_bb_reg(dm, 0x8FC, MASKDWORD, 0x200); /*set debug port*/ + value32 = odm_get_bb_reg(dm, 0xFA0, + MASKDWORD); /*read debug port*/ + + rxi_buf_anta = (value32 & 0xFFC00) >> + 10; /*rxi_buf_anta=RegFA0[19:10]*/ + rxq_buf_anta = value32 & 0x3FF; /*rxq_buf_anta=RegFA0[19:10]*/ + + pd_flag = (bool)((value32 & BIT(31)) >> 31); + + /*Not in packet detection period or Tx state */ + if ((!pd_flag) || (rxi_buf_anta != 0x200)) { + /*sign conversion*/ + rxi_buf_anta = odm_sign_conversion(rxi_buf_anta, 10); + rxq_buf_anta = odm_sign_conversion(rxq_buf_anta, 10); + + pwdb_A = odm_pwdb_conversion( + rxi_buf_anta * rxi_buf_anta + + rxq_buf_anta * rxq_buf_anta, + 20, 18); /*S(10,9)*S(10,9)=S(20,18)*/ + + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "pwdb_A= %d dB, rxi_buf_anta= 0x%x, rxq_buf_anta= 0x%x\n", + pwdb_A, rxi_buf_anta & 0x3FF, + rxq_buf_anta & 0x3FF); + } + /*Start CK320&CK88*/ + odm_set_bb_reg(dm, 0x8B4, BIT(6), 0); + /*BB Reset*/ + odm_write_1byte(dm, 0x02, odm_read_1byte(dm, 0x02) & (~BIT(0))); + odm_write_1byte(dm, 0x02, odm_read_1byte(dm, 0x02) | BIT(0)); + /*PMAC Reset*/ + odm_write_1byte(dm, 0xB03, + odm_read_1byte(dm, 0xB03) & (~BIT(0))); + odm_write_1byte(dm, 0xB03, odm_read_1byte(dm, 0xB03) | BIT(0)); + /*CCK Reset*/ + if (odm_read_1byte(dm, 0x80B) & BIT(4)) { + odm_write_1byte(dm, 0x80B, + odm_read_1byte(dm, 0x80B) & (~BIT(4))); + odm_write_1byte(dm, 0x80B, + odm_read_1byte(dm, 0x80B) | BIT(4)); + } + + sval = pwdb_A; + + if ((sval < 0 && sval >= -27) && (valid_cnt < VALID_CNT)) { + valid_cnt++; + sum += sval; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Valid sval = %d\n", + sval); + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "Sum of sval = %d,\n", + sum); + if ((valid_cnt >= VALID_CNT) || + (odm_get_progressing_time(dm, start) > max_time)) { + sum /= VALID_CNT; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "After divided, sum = %d\n", sum); + break; + } + } + } + + /*ADC backoff is 12dB,*/ + /*Ptarget=0x1C-110=-82dBm*/ + noise = sum + 12 + 0x1C - 110; + + /*Offset*/ + noise = noise - 3; + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "noise = %d\n", noise); + dm->noise_level.noise_all = (s16)noise; + + /* step 4. Recover the Dig*/ + if (is_pause_dig) + odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_1, igi_value); + + func_end = odm_get_progressing_time(dm, func_start); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s() <==\n", __func__); + + return dm->noise_level.noise_all; +} + +s16 odm_inband_noise_monitor(void *dm_void, u8 is_pause_dig, u8 igi_value, + u32 max_time) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) + return odm_inband_noise_monitor_ac_series(dm, is_pause_dig, + igi_value, max_time); + else + return odm_inband_noise_monitor_n_series(dm, is_pause_dig, + igi_value, max_time); +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h new file mode 100644 index 000000000000..a711b7954985 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_noisemonitor.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __ODMNOISEMONITOR_H__ +#define __ODMNOISEMONITOR_H__ + +#define ODM_MAX_CHANNEL_NUM 38 /* 14+24 */ +struct noise_level { + u8 value[MAX_RF_PATH]; + s8 sval[MAX_RF_PATH]; + + s32 sum[MAX_RF_PATH]; + u8 valid[MAX_RF_PATH]; + u8 valid_cnt[MAX_RF_PATH]; +}; + +struct odm_noise_monitor { + s8 noise[MAX_RF_PATH]; + s16 noise_all; +}; + +s16 odm_inband_noise_monitor(void *dm_void, u8 is_pause_dig, u8 igi_value, + u32 max_time); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c new file mode 100644 index 000000000000..48e73eb1622b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.c @@ -0,0 +1,644 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*============================================================ */ +/* include files */ +/*============================================================ */ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +/* ************************************************************ + * Global var + * *************************************************************/ + +u32 ofdm_swing_table[OFDM_TABLE_SIZE] = { + 0x7f8001fe, /* 0, +6.0dB */ + 0x788001e2, /* 1, +5.5dB */ + 0x71c001c7, /* 2, +5.0dB*/ + 0x6b8001ae, /* 3, +4.5dB*/ + 0x65400195, /* 4, +4.0dB*/ + 0x5fc0017f, /* 5, +3.5dB*/ + 0x5a400169, /* 6, +3.0dB*/ + 0x55400155, /* 7, +2.5dB*/ + 0x50800142, /* 8, +2.0dB*/ + 0x4c000130, /* 9, +1.5dB*/ + 0x47c0011f, /* 10, +1.0dB*/ + 0x43c0010f, /* 11, +0.5dB*/ + 0x40000100, /* 12, +0dB*/ + 0x3c8000f2, /* 13, -0.5dB*/ + 0x390000e4, /* 14, -1.0dB*/ + 0x35c000d7, /* 15, -1.5dB*/ + 0x32c000cb, /* 16, -2.0dB*/ + 0x300000c0, /* 17, -2.5dB*/ + 0x2d4000b5, /* 18, -3.0dB*/ + 0x2ac000ab, /* 19, -3.5dB*/ + 0x288000a2, /* 20, -4.0dB*/ + 0x26000098, /* 21, -4.5dB*/ + 0x24000090, /* 22, -5.0dB*/ + 0x22000088, /* 23, -5.5dB*/ + 0x20000080, /* 24, -6.0dB*/ + 0x1e400079, /* 25, -6.5dB*/ + 0x1c800072, /* 26, -7.0dB*/ + 0x1b00006c, /* 27. -7.5dB*/ + 0x19800066, /* 28, -8.0dB*/ + 0x18000060, /* 29, -8.5dB*/ + 0x16c0005b, /* 30, -9.0dB*/ + 0x15800056, /* 31, -9.5dB*/ + 0x14400051, /* 32, -10.0dB*/ + 0x1300004c, /* 33, -10.5dB*/ + 0x12000048, /* 34, -11.0dB*/ + 0x11000044, /* 35, -11.5dB*/ + 0x10000040, /* 36, -12.0dB*/ +}; + +u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 2, -1.0dB*/ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 3, -1.5dB*/ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 4, -2.0dB */ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 5, -2.5dB*/ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 6, -3.0dB*/ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 7, -3.5dB*/ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 9, -4.5dB*/ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 11, -5.5dB*/ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, + 0x02}, /* 12, -6.0dB <== default */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 13, -6.5dB*/ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 15, -7.5dB*/ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 17, -8.5dB*/ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 19, -9.5dB*/ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} /* 32, -16.0dB*/ +}; + +u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 1, -0.5dB */ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 2, -1.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 3, -1.5dB*/ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 4, -2.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 5, -2.5dB*/ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 6, -3.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 7, -3.5dB */ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 8, -4.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 9, -4.5dB*/ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 10, -5.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 11, -5.5dB*/ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, + 0x00}, /* 12, -6.0dB <== default*/ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 13, -6.5dB */ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 14, -7.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 15, -7.5dB*/ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 17, -8.5dB*/ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 18, -9.0dB */ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 19, -9.5dB*/ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 20, -10.0dB*/ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 21, -10.5dB*/ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 22, -11.0dB*/ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 23, -11.5dB*/ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 24, -12.0dB*/ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 25, -12.5dB*/ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 26, -13.0dB*/ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 27, -13.5dB*/ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 28, -14.0dB*/ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 29, -14.5dB*/ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 30, -15.0dB*/ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 31, -15.5dB*/ + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB*/ +}; + +u32 ofdm_swing_table_new[OFDM_TABLE_SIZE] = { + 0x0b40002d, /* 0, -15.0dB */ + 0x0c000030, /* 1, -14.5dB*/ + 0x0cc00033, /* 2, -14.0dB*/ + 0x0d800036, /* 3, -13.5dB*/ + 0x0e400039, /* 4, -13.0dB */ + 0x0f00003c, /* 5, -12.5dB*/ + 0x10000040, /* 6, -12.0dB*/ + 0x11000044, /* 7, -11.5dB*/ + 0x12000048, /* 8, -11.0dB*/ + 0x1300004c, /* 9, -10.5dB*/ + 0x14400051, /* 10, -10.0dB*/ + 0x15800056, /* 11, -9.5dB*/ + 0x16c0005b, /* 12, -9.0dB*/ + 0x18000060, /* 13, -8.5dB*/ + 0x19800066, /* 14, -8.0dB*/ + 0x1b00006c, /* 15, -7.5dB*/ + 0x1c800072, /* 16, -7.0dB*/ + 0x1e400079, /* 17, -6.5dB*/ + 0x20000080, /* 18, -6.0dB*/ + 0x22000088, /* 19, -5.5dB*/ + 0x24000090, /* 20, -5.0dB*/ + 0x26000098, /* 21, -4.5dB*/ + 0x288000a2, /* 22, -4.0dB*/ + 0x2ac000ab, /* 23, -3.5dB*/ + 0x2d4000b5, /* 24, -3.0dB*/ + 0x300000c0, /* 25, -2.5dB*/ + 0x32c000cb, /* 26, -2.0dB*/ + 0x35c000d7, /* 27, -1.5dB*/ + 0x390000e4, /* 28, -1.0dB*/ + 0x3c8000f2, /* 29, -0.5dB*/ + 0x40000100, /* 30, +0dB*/ + 0x43c0010f, /* 31, +0.5dB*/ + 0x47c0011f, /* 32, +1.0dB*/ + 0x4c000130, /* 33, +1.5dB*/ + 0x50800142, /* 34, +2.0dB*/ + 0x55400155, /* 35, +2.5dB*/ + 0x5a400169, /* 36, +3.0dB*/ + 0x5fc0017f, /* 37, +3.5dB*/ + 0x65400195, /* 38, +4.0dB*/ + 0x6b8001ae, /* 39, +4.5dB*/ + 0x71c001c7, /* 40, +5.0dB*/ + 0x788001e2, /* 41, +5.5dB*/ + 0x7f8001fe /* 42, +6.0dB*/ +}; + +u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16] = { + {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ + {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ + {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ + {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ + {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ + {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ + {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ + {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ + {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ + {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ + {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ + {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ + {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ + {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ + {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ + {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ + {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ + {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ + {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ + {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ + {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + +u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16] = { + {0x44, 0x42, 0x3C, 0x33, 0x28, 0x1C, 0x13, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ + {0x48, 0x46, 0x3F, 0x36, 0x2A, 0x1E, 0x14, 0x0B, 0x05, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ + {0x4D, 0x4A, 0x43, 0x39, 0x2C, 0x20, 0x15, 0x0C, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ + {0x51, 0x4F, 0x47, 0x3C, 0x2F, 0x22, 0x16, 0x0D, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ + {0x56, 0x53, 0x4B, 0x40, 0x32, 0x24, 0x17, 0x0E, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ + {0x5B, 0x58, 0x50, 0x43, 0x35, 0x26, 0x19, 0x0E, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ + {0x60, 0x5D, 0x54, 0x47, 0x38, 0x28, 0x1A, 0x0F, 0x07, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ + {0x66, 0x63, 0x59, 0x4C, 0x3B, 0x2B, 0x1C, 0x10, 0x08, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ + {0x6C, 0x69, 0x5F, 0x50, 0x3F, 0x2D, 0x1E, 0x11, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ + {0x73, 0x6F, 0x64, 0x55, 0x42, 0x30, 0x1F, 0x12, 0x08, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ + {0x79, 0x76, 0x6A, 0x5A, 0x46, 0x33, 0x21, 0x13, 0x09, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ + {0x81, 0x7C, 0x71, 0x5F, 0x4A, 0x36, 0x23, 0x14, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ + {0x88, 0x84, 0x77, 0x65, 0x4F, 0x39, 0x25, 0x15, 0x0A, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ + {0x90, 0x8C, 0x7E, 0x6B, 0x54, 0x3C, 0x27, 0x17, 0x0B, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ + {0x99, 0x94, 0x86, 0x71, 0x58, 0x40, 0x2A, 0x18, 0x0B, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ + {0xA2, 0x9D, 0x8E, 0x78, 0x5E, 0x43, 0x2C, 0x19, 0x0C, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ + {0xAC, 0xA6, 0x96, 0x7F, 0x63, 0x47, 0x2F, 0x1B, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ + {0xB6, 0xB0, 0x9F, 0x87, 0x69, 0x4C, 0x32, 0x1D, 0x0D, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ + {0xC1, 0xBA, 0xA8, 0x8F, 0x6F, 0x50, 0x35, 0x1E, 0x0E, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ + {0xCC, 0xC5, 0xB2, 0x97, 0x76, 0x55, 0x38, 0x20, 0x0F, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ + {0xD8, 0xD1, 0xBD, 0xA0, 0x7D, 0x5A, 0x3B, 0x22, 0x10, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + +u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16] = { + {0x44, 0x42, 0x3C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-16dB*/ + {0x48, 0x46, 0x3F, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15.5dB*/ + {0x4D, 0x4A, 0x43, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-15dB*/ + {0x51, 0x4F, 0x47, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14.5dB*/ + {0x56, 0x53, 0x4B, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-14dB*/ + {0x5B, 0x58, 0x50, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13.5dB*/ + {0x60, 0x5D, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-13dB*/ + {0x66, 0x63, 0x59, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12.5dB*/ + {0x6C, 0x69, 0x5F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-12dB*/ + {0x73, 0x6F, 0x64, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11.5dB*/ + {0x79, 0x76, 0x6A, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-11dB*/ + {0x81, 0x7C, 0x71, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10.5dB*/ + {0x88, 0x84, 0x77, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-10dB*/ + {0x90, 0x8C, 0x7E, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9.5dB*/ + {0x99, 0x94, 0x86, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-9dB*/ + {0xA2, 0x9D, 0x8E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8.5dB*/ + {0xAC, 0xA6, 0x96, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-8dB*/ + {0xB6, 0xB0, 0x9F, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7.5dB*/ + {0xC1, 0xBA, 0xA8, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-7dB*/ + {0xCC, 0xC5, 0xB2, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}, /*-6.5dB*/ + {0xD8, 0xD1, 0xBD, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} /*-6dB*/ +}; + +u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8] = { + {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB*/ + {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB*/ + {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB*/ + {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB*/ + {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB*/ + {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB*/ + {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB*/ + {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB*/ + {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB*/ + {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB*/ + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB*/ + {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB*/ + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB*/ + {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB*/ + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */ + {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB*/ + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */ + {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB*/ + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */ + {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB*/ + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /*20, -6.0dB */ + {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB*/ + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */ + {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB*/ + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */ + {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB*/ + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB*/ + {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB*/ + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */ + {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB*/ + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB*/ + {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB*/ + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB*/ +}; + +u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8] = { + {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB*/ + {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB*/ + {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB*/ + {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB*/ + {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB*/ + {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*5, -13.5dB*/ + {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB*/ + {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB*/ + {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB*/ + {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB*/ + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB*/ + {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /*11, -10.5dB*/ + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB*/ + {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB*/ + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /*14, -9.0dB */ + {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB*/ + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */ + {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB*/ + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */ + {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */ + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */ + {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB*/ + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */ + {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /*23, -4.5dB*/ + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */ + {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */ + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */ + {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /*27, -2.5dB*/ + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */ + {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /*29, -1.5dB*/ + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */ + {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */ + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */ +}; + +u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D] = { + 0x0CD, /*0 , -20dB*/ + 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, 0x16C, + 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, 0x287, + 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, 0x47F, + 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, 0x7FF, +}; + +/* JJ ADD 20161014 */ +u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B] = { + 0x0CD, /*0 , -20dB*/ + 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, 0x16C, + 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, 0x287, + 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, 0x47F, + 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, 0x7FF, +}; + +u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE] = { + 0x081, /* 0, -12.0dB*/ + 0x088, /* 1, -11.5dB*/ + 0x090, /* 2, -11.0dB*/ + 0x099, /* 3, -10.5dB*/ + 0x0A2, /* 4, -10.0dB*/ + 0x0AC, /* 5, -9.5dB*/ + 0x0B6, /* 6, -9.0dB*/ + 0x0C0, /*7, -8.5dB*/ + 0x0CC, /* 8, -8.0dB*/ + 0x0D8, /* 9, -7.5dB*/ + 0x0E5, /* 10, -7.0dB*/ + 0x0F2, /* 11, -6.5dB*/ + 0x101, /* 12, -6.0dB*/ + 0x110, /* 13, -5.5dB*/ + 0x120, /* 14, -5.0dB*/ + 0x131, /* 15, -4.5dB*/ + 0x143, /* 16, -4.0dB*/ + 0x156, /* 17, -3.5dB*/ + 0x16A, /* 18, -3.0dB*/ + 0x180, /* 19, -2.5dB*/ + 0x197, /* 20, -2.0dB*/ + 0x1AF, /* 21, -1.5dB*/ + 0x1C8, /* 22, -1.0dB*/ + 0x1E3, /* 23, -0.5dB*/ + 0x200, /* 24, +0 dB*/ + 0x21E, /* 25, +0.5dB*/ + 0x23E, /* 26, +1.0dB*/ + 0x261, /* 27, +1.5dB*/ + 0x285, /* 28, +2.0dB*/ + 0x2AB, /* 29, +2.5dB*/ + 0x2D3, /*30, +3.0dB*/ + 0x2FE, /* 31, +3.5dB*/ + 0x32B, /* 32, +4.0dB*/ + 0x35C, /* 33, +4.5dB*/ + 0x38E, /* 34, +5.0dB*/ + 0x3C4, /* 35, +5.5dB*/ + 0x3FE /* 36, +6.0dB */ +}; + +void odm_txpowertracking_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + odm_txpowertracking_thermal_meter_init(dm); +} + +static u8 get_swing_index(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 i = 0; + u32 bb_swing; + u32 swing_table_size; + u32 *swing_table; + + if (dm->support_ic_type == ODM_RTL8188E || + dm->support_ic_type == ODM_RTL8723B || + dm->support_ic_type == ODM_RTL8192E || + dm->support_ic_type == ODM_RTL8188F || + dm->support_ic_type == ODM_RTL8703B) { + bb_swing = odm_get_bb_reg(dm, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + 0xFFC00000); + + swing_table = ofdm_swing_table_new; + swing_table_size = OFDM_TABLE_SIZE; + } else { + { + bb_swing = 0; + swing_table = ofdm_swing_table; + swing_table_size = OFDM_TABLE_SIZE; + } + } + + for (i = 0; i < swing_table_size; ++i) { + u32 table_value = swing_table[i]; + + if (table_value >= 0x100000) + table_value >>= 22; + if (bb_swing == table_value) + break; + } + return i; +} + +void odm_txpowertracking_thermal_meter_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 default_swing_index = get_swing_index(dm); + u8 p = 0; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_efuse *rtlefu = rtl_efuse(rtlpriv); + + cali_info->is_txpowertracking = true; + cali_info->tx_powercount = 0; + cali_info->is_txpowertracking_init = false; + + if (!dm->mp_mode) + cali_info->txpowertrack_control = true; + else + cali_info->txpowertrack_control = false; + + if (!dm->mp_mode) + cali_info->txpowertrack_control = true; + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "dm txpowertrack_control = %d\n", + cali_info->txpowertrack_control); + + /* dm->rf_calibrate_info.txpowertrack_control = true; */ + cali_info->thermal_value = rtlefu->eeprom_thermalmeter; + cali_info->thermal_value_iqk = rtlefu->eeprom_thermalmeter; + cali_info->thermal_value_lck = rtlefu->eeprom_thermalmeter; + + if (!cali_info->default_bb_swing_index_flag) { + /*The index of "0 dB" in SwingTable.*/ + if (dm->support_ic_type == ODM_RTL8188E || + dm->support_ic_type == ODM_RTL8723B || + dm->support_ic_type == ODM_RTL8192E || + dm->support_ic_type == ODM_RTL8703B) { + cali_info->default_ofdm_index = + (default_swing_index >= OFDM_TABLE_SIZE) ? + 30 : + default_swing_index; + cali_info->default_cck_index = 20; + } else if (dm->support_ic_type == + ODM_RTL8188F) { /*add by Mingzhi.Guo 2015-03-23*/ + cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/ + cali_info->default_cck_index = 20; /*CCK:-6dB*/ + } else if (dm->support_ic_type == + ODM_RTL8723D) { /*add by zhaohe 2015-10-27*/ + cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/ + cali_info->default_cck_index = 28; /*CCK: -6dB*/ + } else if (dm->support_ic_type == + ODM_RTL8710B) { /* JJ ADD 20161014 */ + cali_info->default_ofdm_index = 28; /*OFDM: -1dB*/ + cali_info->default_cck_index = 28; /*CCK: -6dB*/ + } else { + cali_info->default_ofdm_index = + (default_swing_index >= TXSCALE_TABLE_SIZE) ? + 24 : + default_swing_index; + cali_info->default_cck_index = 24; + } + cali_info->default_bb_swing_index_flag = true; + } + + cali_info->bb_swing_idx_cck_base = cali_info->default_cck_index; + cali_info->CCK_index = cali_info->default_cck_index; + + for (p = ODM_RF_PATH_A; p < MAX_RF_PATH; ++p) { + cali_info->bb_swing_idx_ofdm_base[p] = + cali_info->default_ofdm_index; + cali_info->OFDM_index[p] = cali_info->default_ofdm_index; + cali_info->delta_power_index[p] = 0; + cali_info->delta_power_index_last[p] = 0; + cali_info->power_index_offset[p] = 0; + } + cali_info->modify_tx_agc_value_ofdm = 0; + cali_info->modify_tx_agc_value_cck = 0; +} + +void odm_txpowertracking_check(void *dm_void) +{ + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + switch (dm->support_platform) { + case ODM_WIN: + odm_txpowertracking_check_mp(dm); + break; + + case ODM_CE: + odm_txpowertracking_check_ce(dm); + break; + + case ODM_AP: + odm_txpowertracking_check_ap(dm); + break; + + default: + break; + } +} + +void odm_txpowertracking_check_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + void *adapter = dm->adapter; + + if (!(dm->support_ability & ODM_RF_TX_PWR_TRACK)) + return; + + if (!dm->rf_calibrate_info.tm_trigger) { + if (IS_HARDWARE_TYPE_8188E(adapter) || + IS_HARDWARE_TYPE_8188F(adapter) || + IS_HARDWARE_TYPE_8192E(adapter) || + IS_HARDWARE_TYPE_8723B(adapter) || + IS_HARDWARE_TYPE_JAGUAR(adapter) || + IS_HARDWARE_TYPE_8814A(adapter) || + IS_HARDWARE_TYPE_8703B(adapter) || + IS_HARDWARE_TYPE_8723D(adapter) || + IS_HARDWARE_TYPE_8822B(adapter) || + IS_HARDWARE_TYPE_8821C(adapter) || + (dm->support_ic_type == ODM_RTL8710B)) /* JJ ADD 20161014 */ + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_T_METER_NEW, + (BIT(17) | BIT(16)), 0x03); + else + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_T_METER_OLD, + RFREGOFFSETMASK, 0x60); + + dm->rf_calibrate_info.tm_trigger = 1; + return; + } + + odm_txpowertracking_callback_thermal_meter(dm); + dm->rf_calibrate_info.tm_trigger = 0; +} + +void odm_txpowertracking_check_mp(void *dm_void) {} + +void odm_txpowertracking_check_ap(void *dm_void) {} diff --git a/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h new file mode 100644 index 000000000000..757d7720d931 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_powertracking_ce.h @@ -0,0 +1,293 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMPOWERTRACKING_H__ +#define __PHYDMPOWERTRACKING_H__ + +#define POWRTRACKING_VERSION "1.1" + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#define CCK_TABLE_SIZE_88F 21 +#define TXSCALE_TABLE_SIZE 37 +#define CCK_TABLE_SIZE_8723D 41 +/* JJ ADD 20161014 */ +#define CCK_TABLE_SIZE_8710B 41 + +#define TXPWR_TRACK_TABLE_SIZE 30 +#define DELTA_SWINGIDX_SIZE 30 +#define DELTA_SWINTSSI_SIZE 61 +#define BAND_NUM 4 + +#define AVG_THERMAL_NUM 8 +#define HP_THERMAL_NUM 8 +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM_MAX 10 + +#define IQK_BB_REG_NUM 9 + +#define iqk_matrix_reg_num 8 + +extern u32 ofdm_swing_table[OFDM_TABLE_SIZE]; +extern u8 cck_swing_table_ch1_ch13[CCK_TABLE_SIZE][8]; +extern u8 cck_swing_table_ch14[CCK_TABLE_SIZE][8]; + +extern u32 ofdm_swing_table_new[OFDM_TABLE_SIZE]; +extern u8 cck_swing_table_ch1_ch13_new[CCK_TABLE_SIZE][8]; +extern u8 cck_swing_table_ch14_new[CCK_TABLE_SIZE][8]; +extern u8 cck_swing_table_ch1_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern u8 cck_swing_table_ch1_ch13_88f[CCK_TABLE_SIZE_88F][16]; +extern u8 cck_swing_table_ch14_88f[CCK_TABLE_SIZE_88F][16]; +extern u32 cck_swing_table_ch1_ch14_8723d[CCK_TABLE_SIZE_8723D]; +/* JJ ADD 20161014 */ +extern u32 cck_swing_table_ch1_ch14_8710b[CCK_TABLE_SIZE_8710B]; + +extern u32 tx_scaling_table_jaguar[TXSCALE_TABLE_SIZE]; + +/* <20121018, Kordan> In case fail to read TxPowerTrack.txt, + * we use the table of 88E as the default table. + */ + +#define dm_check_txpowertracking odm_txpowertracking_check + +struct iqk_matrix_regs_setting { + bool is_iqk_done; + s32 value[3][iqk_matrix_reg_num]; + bool is_bw_iqk_result_saved[3]; +}; + +struct dm_rf_calibration_struct { + /* for tx power tracking */ + + u32 rega24; /* for TempCCK */ + s32 rege94; + s32 rege9c; + s32 regeb4; + s32 regebc; + + u8 tx_powercount; + bool is_txpowertracking_init; + bool is_txpowertracking; + /* for mp mode, turn off txpwrtracking as default */ + u8 txpowertrack_control; + u8 tm_trigger; + u8 internal_pa_5g[2]; /* pathA / pathB */ + + u8 thermal_meter + [2]; /* thermal_meter, index 0 for RFIC0, and 1 for RFIC1 */ + u8 thermal_value; + u8 thermal_value_lck; + u8 thermal_value_iqk; + s8 thermal_value_delta; /* delta of thermal_value and efuse thermal */ + u8 thermal_value_dpk; + u8 thermal_value_avg[AVG_THERMAL_NUM]; + u8 thermal_value_avg_index; + u8 thermal_value_rx_gain; + u8 thermal_value_crystal; + u8 thermal_value_dpk_store; + u8 thermal_value_dpk_track; + bool txpowertracking_in_progress; + + bool is_reloadtxpowerindex; + u8 is_rf_pi_enable; + u32 txpowertracking_callback_cnt; /* cosa add for debug */ + + /* ---------------------- Tx power Tracking ------------------------- */ + u8 is_cck_in_ch14; + u8 CCK_index; + u8 OFDM_index[MAX_RF_PATH]; + s8 power_index_offset[MAX_RF_PATH]; + s8 delta_power_index[MAX_RF_PATH]; + s8 delta_power_index_last[MAX_RF_PATH]; + bool is_tx_power_changed; + s8 xtal_offset; + s8 xtal_offset_last; + + u8 thermal_value_hp[HP_THERMAL_NUM]; + u8 thermal_value_hp_index; + struct iqk_matrix_regs_setting + iqk_matrix_reg_setting[IQK_MATRIX_SETTINGS_NUM]; + u8 delta_lck; + s8 bb_swing_diff_2g, bb_swing_diff_5g; /* Unit: dB */ + u8 delta_swing_table_idx_2g_cck_a_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_a_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_b_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_b_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_c_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_c_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_d_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2g_cck_d_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gb_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gb_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gc_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gc_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gd_p[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2gd_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5ga_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5ga_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gb_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gb_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gc_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gc_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gd_p[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_5gd_n[BAND_NUM][DELTA_SWINGIDX_SIZE]; + u8 delta_swing_tssi_table_2g_cck_a[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2g_cck_b[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2g_cck_c[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2g_cck_d[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2ga[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2gb[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2gc[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_2gd[DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5ga[BAND_NUM][DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5gb[BAND_NUM][DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5gc[BAND_NUM][DELTA_SWINTSSI_SIZE]; + u8 delta_swing_tssi_table_5gd[BAND_NUM][DELTA_SWINTSSI_SIZE]; + s8 delta_swing_table_xtal_p[DELTA_SWINGIDX_SIZE]; + s8 delta_swing_table_xtal_n[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_p_8188e[DELTA_SWINGIDX_SIZE]; + u8 delta_swing_table_idx_2ga_n_8188e[DELTA_SWINGIDX_SIZE]; + + u8 bb_swing_idx_ofdm[MAX_RF_PATH]; + u8 bb_swing_idx_ofdm_current; + u8 bb_swing_idx_ofdm_base[MAX_RF_PATH]; + bool default_bb_swing_index_flag; + bool bb_swing_flag_ofdm; + u8 bb_swing_idx_cck; + u8 bb_swing_idx_cck_current; + u8 bb_swing_idx_cck_base; + u8 default_ofdm_index; + u8 default_cck_index; + bool bb_swing_flag_cck; + + s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_ofdm_swing_idx[MAX_RF_PATH]; + s8 absolute_cck_swing_idx[MAX_RF_PATH]; + s8 remnant_cck_swing_idx; + s8 modify_tx_agc_value; /*Remnat compensate value at tx_agc */ + bool modify_tx_agc_flag_path_a; + bool modify_tx_agc_flag_path_b; + bool modify_tx_agc_flag_path_c; + bool modify_tx_agc_flag_path_d; + bool modify_tx_agc_flag_path_a_cck; + + s8 kfree_offset[MAX_RF_PATH]; + + /* ------------------------------------------------------------------ */ + + /* for IQK */ + u32 regc04; + u32 reg874; + u32 regc08; + u32 regb68; + u32 regb6c; + u32 reg870; + u32 reg860; + u32 reg864; + + bool is_iqk_initialized; + bool is_lck_in_progress; + bool is_antenna_detected; + bool is_need_iqk; + bool is_iqk_in_progress; + bool is_iqk_pa_off; + u8 delta_iqk; + u32 ADDA_backup[IQK_ADDA_REG_NUM]; + u32 IQK_MAC_backup[IQK_MAC_REG_NUM]; + u32 IQK_BB_backup_recover[9]; + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} */ + u32 IQK_BB_backup[IQK_BB_REG_NUM]; + u32 tx_iqc_8723b[2][3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} */ + u32 rx_iqc_8723b[2][2][2]; + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u32 tx_iqc_8703b[3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + u32 rx_iqc_8703b[2][2]; + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u32 tx_iqc_8723d[2][3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + u32 rx_iqc_8723d[2][2][2]; + /* JJ ADD 20161014 */ + /* { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}}*/ + u32 tx_iqc_8710b[2][3][2]; + /* { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}}*/ + u32 rx_iqc_8710b[2][2][2]; + + u8 iqk_step; + u8 kcount; + u8 retry_count[4][2]; /* [4]: path ABCD, [2] TXK, RXK */ + bool is_mp_mode; + + /* IQK time measurement */ + u64 iqk_start_time; + u64 iqk_progressing_time; + u64 iqk_total_progressing_time; + + u32 lok_result; + + /* for APK */ + u32 ap_koutput[2][2]; /* path A/B; output1_1a/output1_2a */ + u8 is_ap_kdone; + u8 is_apk_thermal_meter_ignore; + + /* DPK */ + bool is_dpk_fail; + u8 is_dp_done; + u8 is_dp_path_aok; + u8 is_dp_path_bok; + + u32 tx_lok[2]; + u32 dpk_tx_agc; + s32 dpk_gain; + u32 dpk_thermal[4]; + s8 modify_tx_agc_value_ofdm; + s8 modify_tx_agc_value_cck; + + /*Add by Yuchen for Kfree Phydm*/ + u8 reg_rf_kfree_enable; /*for registry*/ + u8 rf_kfree_enable; /*for efuse enable check*/ +}; + +void odm_txpowertracking_check(void *dm_void); + +void odm_txpowertracking_init(void *dm_void); + +void odm_txpowertracking_check_ap(void *dm_void); + +void odm_txpowertracking_thermal_meter_init(void *dm_void); + +void odm_txpowertracking_init(void *dm_void); + +void odm_txpowertracking_check_mp(void *dm_void); + +void odm_txpowertracking_check_ce(void *dm_void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_pre_define.h b/drivers/staging/rtlwifi/phydm/phydm_pre_define.h new file mode 100644 index 000000000000..6c301fe87b3d --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_pre_define.h @@ -0,0 +1,613 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMPREDEFINE_H__ +#define __PHYDMPREDEFINE_H__ + +/* 1 ============================================================ + * 1 Definition + * 1 ============================================================ + */ + +#define PHYDM_CODE_BASE "PHYDM_TRUNK" +#define PHYDM_RELEASE_DATE "00000000" + +/* Max path of IC */ +#define MAX_PATH_NUM_8188E 1 +#define MAX_PATH_NUM_8192E 2 +#define MAX_PATH_NUM_8723B 1 +#define MAX_PATH_NUM_8812A 2 +#define MAX_PATH_NUM_8821A 1 +#define MAX_PATH_NUM_8814A 4 +#define MAX_PATH_NUM_8822B 2 +#define MAX_PATH_NUM_8821B 2 +#define MAX_PATH_NUM_8703B 1 +#define MAX_PATH_NUM_8188F 1 +#define MAX_PATH_NUM_8723D 1 +#define MAX_PATH_NUM_8197F 2 +#define MAX_PATH_NUM_8821C 1 +/* JJ ADD 20161014 */ +#define MAX_PATH_NUM_8710B 1 + +/* Max RF path */ +#define ODM_RF_PATH_MAX 2 +#define ODM_RF_PATH_MAX_JAGUAR 4 + +/*Bit define path*/ +#define PHYDM_A BIT(0) +#define PHYDM_B BIT(1) +#define PHYDM_C BIT(2) +#define PHYDM_D BIT(3) +#define PHYDM_AB (BIT(0) | BIT(1)) +#define PHYDM_AC (BIT(0) | BIT(2)) +#define PHYDM_AD (BIT(0) | BIT(3)) +#define PHYDM_BC (BIT(1) | BIT(2)) +#define PHYDM_BD (BIT(1) | BIT(3)) +#define PHYDM_CD (BIT(2) | BIT(3)) +#define PHYDM_ABC (BIT(0) | BIT(1) | BIT(2)) +#define PHYDM_ABD (BIT(0) | BIT(1) | BIT(3)) +#define PHYDM_ACD (BIT(0) | BIT(2) | BIT(3)) +#define PHYDM_BCD (BIT(1) | BIT(2) | BIT(3)) +#define PHYDM_ABCD (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +/* number of entry */ +/* defined in wifi.h (32+1) */ +#define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM + +#define RX_SMOOTH_FACTOR 20 + +/* -----MGN rate--------------------------------- */ + +enum ODM_MGN_RATE { + ODM_MGN_1M = 0x02, + ODM_MGN_2M = 0x04, + ODM_MGN_5_5M = 0x0B, + ODM_MGN_6M = 0x0C, + ODM_MGN_9M = 0x12, + ODM_MGN_11M = 0x16, + ODM_MGN_12M = 0x18, + ODM_MGN_18M = 0x24, + ODM_MGN_24M = 0x30, + ODM_MGN_36M = 0x48, + ODM_MGN_48M = 0x60, + ODM_MGN_54M = 0x6C, + ODM_MGN_MCS32 = 0x7F, + ODM_MGN_MCS0, + ODM_MGN_MCS1, + ODM_MGN_MCS2, + ODM_MGN_MCS3, + ODM_MGN_MCS4, + ODM_MGN_MCS5, + ODM_MGN_MCS6, + ODM_MGN_MCS7, + ODM_MGN_MCS8, + ODM_MGN_MCS9, + ODM_MGN_MCS10, + ODM_MGN_MCS11, + ODM_MGN_MCS12, + ODM_MGN_MCS13, + ODM_MGN_MCS14, + ODM_MGN_MCS15, + ODM_MGN_MCS16, + ODM_MGN_MCS17, + ODM_MGN_MCS18, + ODM_MGN_MCS19, + ODM_MGN_MCS20, + ODM_MGN_MCS21, + ODM_MGN_MCS22, + ODM_MGN_MCS23, + ODM_MGN_MCS24, + ODM_MGN_MCS25, + ODM_MGN_MCS26, + ODM_MGN_MCS27, + ODM_MGN_MCS28, + ODM_MGN_MCS29, + ODM_MGN_MCS30, + ODM_MGN_MCS31, + ODM_MGN_VHT1SS_MCS0, + ODM_MGN_VHT1SS_MCS1, + ODM_MGN_VHT1SS_MCS2, + ODM_MGN_VHT1SS_MCS3, + ODM_MGN_VHT1SS_MCS4, + ODM_MGN_VHT1SS_MCS5, + ODM_MGN_VHT1SS_MCS6, + ODM_MGN_VHT1SS_MCS7, + ODM_MGN_VHT1SS_MCS8, + ODM_MGN_VHT1SS_MCS9, + ODM_MGN_VHT2SS_MCS0, + ODM_MGN_VHT2SS_MCS1, + ODM_MGN_VHT2SS_MCS2, + ODM_MGN_VHT2SS_MCS3, + ODM_MGN_VHT2SS_MCS4, + ODM_MGN_VHT2SS_MCS5, + ODM_MGN_VHT2SS_MCS6, + ODM_MGN_VHT2SS_MCS7, + ODM_MGN_VHT2SS_MCS8, + ODM_MGN_VHT2SS_MCS9, + ODM_MGN_VHT3SS_MCS0, + ODM_MGN_VHT3SS_MCS1, + ODM_MGN_VHT3SS_MCS2, + ODM_MGN_VHT3SS_MCS3, + ODM_MGN_VHT3SS_MCS4, + ODM_MGN_VHT3SS_MCS5, + ODM_MGN_VHT3SS_MCS6, + ODM_MGN_VHT3SS_MCS7, + ODM_MGN_VHT3SS_MCS8, + ODM_MGN_VHT3SS_MCS9, + ODM_MGN_VHT4SS_MCS0, + ODM_MGN_VHT4SS_MCS1, + ODM_MGN_VHT4SS_MCS2, + ODM_MGN_VHT4SS_MCS3, + ODM_MGN_VHT4SS_MCS4, + ODM_MGN_VHT4SS_MCS5, + ODM_MGN_VHT4SS_MCS6, + ODM_MGN_VHT4SS_MCS7, + ODM_MGN_VHT4SS_MCS8, + ODM_MGN_VHT4SS_MCS9, + ODM_MGN_UNKNOWN +}; + +#define ODM_MGN_MCS0_SG 0xc0 +#define ODM_MGN_MCS1_SG 0xc1 +#define ODM_MGN_MCS2_SG 0xc2 +#define ODM_MGN_MCS3_SG 0xc3 +#define ODM_MGN_MCS4_SG 0xc4 +#define ODM_MGN_MCS5_SG 0xc5 +#define ODM_MGN_MCS6_SG 0xc6 +#define ODM_MGN_MCS7_SG 0xc7 +#define ODM_MGN_MCS8_SG 0xc8 +#define ODM_MGN_MCS9_SG 0xc9 +#define ODM_MGN_MCS10_SG 0xca +#define ODM_MGN_MCS11_SG 0xcb +#define ODM_MGN_MCS12_SG 0xcc +#define ODM_MGN_MCS13_SG 0xcd +#define ODM_MGN_MCS14_SG 0xce +#define ODM_MGN_MCS15_SG 0xcf + +/* -----DESC rate--------------------------------- */ + +#define ODM_RATEMCS15_SG 0x1c +#define ODM_RATEMCS32 0x20 + +/* CCK Rates, TxHT = 0 */ +#define ODM_RATE1M 0x00 +#define ODM_RATE2M 0x01 +#define ODM_RATE5_5M 0x02 +#define ODM_RATE11M 0x03 +/* OFDM Rates, TxHT = 0 */ +#define ODM_RATE6M 0x04 +#define ODM_RATE9M 0x05 +#define ODM_RATE12M 0x06 +#define ODM_RATE18M 0x07 +#define ODM_RATE24M 0x08 +#define ODM_RATE36M 0x09 +#define ODM_RATE48M 0x0A +#define ODM_RATE54M 0x0B +/* MCS Rates, TxHT = 1 */ +#define ODM_RATEMCS0 0x0C +#define ODM_RATEMCS1 0x0D +#define ODM_RATEMCS2 0x0E +#define ODM_RATEMCS3 0x0F +#define ODM_RATEMCS4 0x10 +#define ODM_RATEMCS5 0x11 +#define ODM_RATEMCS6 0x12 +#define ODM_RATEMCS7 0x13 +#define ODM_RATEMCS8 0x14 +#define ODM_RATEMCS9 0x15 +#define ODM_RATEMCS10 0x16 +#define ODM_RATEMCS11 0x17 +#define ODM_RATEMCS12 0x18 +#define ODM_RATEMCS13 0x19 +#define ODM_RATEMCS14 0x1A +#define ODM_RATEMCS15 0x1B +#define ODM_RATEMCS16 0x1C +#define ODM_RATEMCS17 0x1D +#define ODM_RATEMCS18 0x1E +#define ODM_RATEMCS19 0x1F +#define ODM_RATEMCS20 0x20 +#define ODM_RATEMCS21 0x21 +#define ODM_RATEMCS22 0x22 +#define ODM_RATEMCS23 0x23 +#define ODM_RATEMCS24 0x24 +#define ODM_RATEMCS25 0x25 +#define ODM_RATEMCS26 0x26 +#define ODM_RATEMCS27 0x27 +#define ODM_RATEMCS28 0x28 +#define ODM_RATEMCS29 0x29 +#define ODM_RATEMCS30 0x2A +#define ODM_RATEMCS31 0x2B +#define ODM_RATEVHTSS1MCS0 0x2C +#define ODM_RATEVHTSS1MCS1 0x2D +#define ODM_RATEVHTSS1MCS2 0x2E +#define ODM_RATEVHTSS1MCS3 0x2F +#define ODM_RATEVHTSS1MCS4 0x30 +#define ODM_RATEVHTSS1MCS5 0x31 +#define ODM_RATEVHTSS1MCS6 0x32 +#define ODM_RATEVHTSS1MCS7 0x33 +#define ODM_RATEVHTSS1MCS8 0x34 +#define ODM_RATEVHTSS1MCS9 0x35 +#define ODM_RATEVHTSS2MCS0 0x36 +#define ODM_RATEVHTSS2MCS1 0x37 +#define ODM_RATEVHTSS2MCS2 0x38 +#define ODM_RATEVHTSS2MCS3 0x39 +#define ODM_RATEVHTSS2MCS4 0x3A +#define ODM_RATEVHTSS2MCS5 0x3B +#define ODM_RATEVHTSS2MCS6 0x3C +#define ODM_RATEVHTSS2MCS7 0x3D +#define ODM_RATEVHTSS2MCS8 0x3E +#define ODM_RATEVHTSS2MCS9 0x3F +#define ODM_RATEVHTSS3MCS0 0x40 +#define ODM_RATEVHTSS3MCS1 0x41 +#define ODM_RATEVHTSS3MCS2 0x42 +#define ODM_RATEVHTSS3MCS3 0x43 +#define ODM_RATEVHTSS3MCS4 0x44 +#define ODM_RATEVHTSS3MCS5 0x45 +#define ODM_RATEVHTSS3MCS6 0x46 +#define ODM_RATEVHTSS3MCS7 0x47 +#define ODM_RATEVHTSS3MCS8 0x48 +#define ODM_RATEVHTSS3MCS9 0x49 +#define ODM_RATEVHTSS4MCS0 0x4A +#define ODM_RATEVHTSS4MCS1 0x4B +#define ODM_RATEVHTSS4MCS2 0x4C +#define ODM_RATEVHTSS4MCS3 0x4D +#define ODM_RATEVHTSS4MCS4 0x4E +#define ODM_RATEVHTSS4MCS5 0x4F +#define ODM_RATEVHTSS4MCS6 0x50 +#define ODM_RATEVHTSS4MCS7 0x51 +#define ODM_RATEVHTSS4MCS8 0x52 +#define ODM_RATEVHTSS4MCS9 0x53 + +#define ODM_NUM_RATE_IDX (ODM_RATEVHTSS4MCS9 + 1) + +/* 1 ============================================================ + * 1 enumeration + * 1 ============================================================ + */ + +/* ODM_CMNINFO_INTERFACE */ +enum odm_interface { + ODM_ITRF_PCIE = 0x1, + ODM_ITRF_USB = 0x2, + ODM_ITRF_SDIO = 0x4, + ODM_ITRF_ALL = 0x7, +}; + +/* ODM_CMNINFO_IC_TYPE */ +enum odm_ic_type { + ODM_RTL8188E = BIT(0), + ODM_RTL8812 = BIT(1), + ODM_RTL8821 = BIT(2), + ODM_RTL8192E = BIT(3), + ODM_RTL8723B = BIT(4), + ODM_RTL8814A = BIT(5), + ODM_RTL8881A = BIT(6), + ODM_RTL8822B = BIT(7), + ODM_RTL8703B = BIT(8), + ODM_RTL8195A = BIT(9), + ODM_RTL8188F = BIT(10), + ODM_RTL8723D = BIT(11), + ODM_RTL8197F = BIT(12), + ODM_RTL8821C = BIT(13), + ODM_RTL8814B = BIT(14), + ODM_RTL8198F = BIT(15), + /* JJ ADD 20161014 */ + ODM_RTL8710B = BIT(16), +}; + +/* JJ ADD 20161014 */ +#define ODM_IC_1SS \ + (ODM_RTL8188E | ODM_RTL8188F | ODM_RTL8723B | ODM_RTL8703B | \ + ODM_RTL8723D | ODM_RTL8881A | ODM_RTL8821 | ODM_RTL8821C | \ + ODM_RTL8195A | ODM_RTL8710B) +#define ODM_IC_2SS (ODM_RTL8192E | ODM_RTL8197F | ODM_RTL8812 | ODM_RTL8822B) +#define ODM_IC_3SS (ODM_RTL8814A) +#define ODM_IC_4SS (ODM_RTL8814B | ODM_RTL8198F) + +/* JJ ADD 20161014 */ +#define ODM_IC_11N_SERIES \ + (ODM_RTL8188E | ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | \ + ODM_RTL8188F | ODM_RTL8723D | ODM_RTL8197F | ODM_RTL8710B) +#define ODM_IC_11AC_SERIES \ + (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | ODM_RTL8881A | \ + ODM_RTL8822B | ODM_RTL8821C) +#define ODM_IC_11AC_1_SERIES (ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8881A) +#define ODM_IC_11AC_2_SERIES (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C) +#define ODM_IC_TXBF_SUPPORT \ + (ODM_RTL8192E | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8814A | \ + ODM_RTL8881A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C) +#define ODM_IC_11N_GAIN_IDX_EDCCA \ + (ODM_RTL8195A | ODM_RTL8703B | ODM_RTL8188F | ODM_RTL8723D | \ + ODM_RTL8197F | ODM_RTL8710B) +#define ODM_IC_11AC_GAIN_IDX_EDCCA (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8821C) +#define ODM_IC_PHY_STATUE_NEW_TYPE \ + (ODM_RTL8197F | ODM_RTL8822B | ODM_RTL8723D | ODM_RTL8821C | \ + ODM_RTL8710B) + +#define PHYDM_IC_8051_SERIES \ + (ODM_RTL8881A | ODM_RTL8812 | ODM_RTL8821 | ODM_RTL8188E | \ + ODM_RTL8192E | ODM_RTL8723B | ODM_RTL8703B | ODM_RTL8188F) +#define PHYDM_IC_3081_SERIES \ + (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C) + +#define PHYDM_IC_SUPPORT_LA_MODE \ + (ODM_RTL8814A | ODM_RTL8822B | ODM_RTL8197F | ODM_RTL8821C) + +/* JJ ADD 20161014 */ + +/* ODM_CMNINFO_CUT_VER */ +enum odm_cut_version { + ODM_CUT_A = 0, + ODM_CUT_B = 1, + ODM_CUT_C = 2, + ODM_CUT_D = 3, + ODM_CUT_E = 4, + ODM_CUT_F = 5, + + ODM_CUT_I = 8, + ODM_CUT_J = 9, + ODM_CUT_K = 10, + ODM_CUT_TEST = 15, +}; + +/* ODM_CMNINFO_FAB_VER */ +enum odm_fab { + ODM_TSMC = 0, + ODM_UMC = 1, +}; + +/* ODM_CMNINFO_RF_TYPE + * + * For example 1T2R (A+AB = BIT(0)|BIT(4)|BIT(5)) + */ +enum odm_rf_path { + ODM_RF_A = BIT(0), + ODM_RF_B = BIT(1), + ODM_RF_C = BIT(2), + ODM_RF_D = BIT(3), +}; + +enum odm_rf_tx_num { + ODM_1T = 1, + ODM_2T = 2, + ODM_3T = 3, + ODM_4T = 4, +}; + +enum odm_rf_type { + ODM_1T1R, + ODM_1T2R, + ODM_2T2R, + ODM_2T2R_GREEN, + ODM_2T3R, + ODM_2T4R, + ODM_3T3R, + ODM_3T4R, + ODM_4T4R, + ODM_XTXR +}; + +enum odm_mac_phy_mode { + ODM_SMSP = 0, + ODM_DMSP = 1, + ODM_DMDP = 2, +}; + +enum odm_bt_coexist { + ODM_BT_BUSY = 1, + ODM_BT_ON = 2, + ODM_BT_OFF = 3, + ODM_BT_NONE = 4, +}; + +/* ODM_CMNINFO_OP_MODE */ +enum odm_operation_mode { + ODM_NO_LINK = BIT(0), + ODM_LINK = BIT(1), + ODM_SCAN = BIT(2), + ODM_POWERSAVE = BIT(3), + ODM_AP_MODE = BIT(4), + ODM_CLIENT_MODE = BIT(5), + ODM_AD_HOC = BIT(6), + ODM_WIFI_DIRECT = BIT(7), + ODM_WIFI_DISPLAY = BIT(8), +}; + +/* ODM_CMNINFO_WM_MODE */ +enum odm_wireless_mode { + ODM_WM_UNKNOWN = 0x0, + ODM_WM_B = BIT(0), + ODM_WM_G = BIT(1), + ODM_WM_A = BIT(2), + ODM_WM_N24G = BIT(3), + ODM_WM_N5G = BIT(4), + ODM_WM_AUTO = BIT(5), + ODM_WM_AC = BIT(6), +}; + +/* ODM_CMNINFO_BAND */ +enum odm_band_type { + ODM_BAND_2_4G = 0, + ODM_BAND_5G, + ODM_BAND_ON_BOTH, + ODM_BANDMAX +}; + +/* ODM_CMNINFO_SEC_CHNL_OFFSET */ +enum phydm_sec_chnl_offset { + PHYDM_DONT_CARE = 0, + PHYDM_BELOW = 1, + PHYDM_ABOVE = 2 +}; + +/* ODM_CMNINFO_SEC_MODE */ +enum odm_security { + ODM_SEC_OPEN = 0, + ODM_SEC_WEP40 = 1, + ODM_SEC_TKIP = 2, + ODM_SEC_RESERVE = 3, + ODM_SEC_AESCCMP = 4, + ODM_SEC_WEP104 = 5, + ODM_WEP_WPA_MIXED = 6, /* WEP + WPA */ + ODM_SEC_SMS4 = 7, +}; + +/* ODM_CMNINFO_BW */ +enum odm_bw { + ODM_BW20M = 0, + ODM_BW40M = 1, + ODM_BW80M = 2, + ODM_BW160M = 3, + ODM_BW5M = 4, + ODM_BW10M = 5, + ODM_BW_MAX = 6 +}; + +/* ODM_CMNINFO_CHNL */ + +/* ODM_CMNINFO_BOARD_TYPE */ +enum odm_board_type { + ODM_BOARD_DEFAULT = 0, /* The DEFAULT case. */ + ODM_BOARD_MINICARD = BIT(0), /* 0 = non-mini card, 1= mini card. */ + ODM_BOARD_SLIM = BIT(1), /* 0 = non-slim card, 1 = slim card */ + ODM_BOARD_BT = BIT(2), /* 0 = without BT card, 1 = with BT */ + ODM_BOARD_EXT_PA = + BIT(3), /* 0 = no 2G ext-PA, 1 = existing 2G ext-PA */ + ODM_BOARD_EXT_LNA = + BIT(4), /* 0 = no 2G ext-LNA, 1 = existing 2G ext-LNA */ + ODM_BOARD_EXT_TRSW = + BIT(5), /* 0 = no ext-TRSW, 1 = existing ext-TRSW */ + ODM_BOARD_EXT_PA_5G = + BIT(6), /* 0 = no 5G ext-PA, 1 = existing 5G ext-PA */ + ODM_BOARD_EXT_LNA_5G = + BIT(7), /* 0 = no 5G ext-LNA, 1 = existing 5G ext-LNA */ +}; + +enum odm_package_type { + ODM_PACKAGE_DEFAULT = 0, + ODM_PACKAGE_QFN68 = BIT(0), + ODM_PACKAGE_TFBGA90 = BIT(1), + ODM_PACKAGE_TFBGA79 = BIT(2), +}; + +enum odm_type_gpa { + TYPE_GPA0 = 0x0000, + TYPE_GPA1 = 0x0055, + TYPE_GPA2 = 0x00AA, + TYPE_GPA3 = 0x00FF, + TYPE_GPA4 = 0x5500, + TYPE_GPA5 = 0x5555, + TYPE_GPA6 = 0x55AA, + TYPE_GPA7 = 0x55FF, + TYPE_GPA8 = 0xAA00, + TYPE_GPA9 = 0xAA55, + TYPE_GPA10 = 0xAAAA, + TYPE_GPA11 = 0xAAFF, + TYPE_GPA12 = 0xFF00, + TYPE_GPA13 = 0xFF55, + TYPE_GPA14 = 0xFFAA, + TYPE_GPA15 = 0xFFFF, +}; + +enum odm_type_apa { + TYPE_APA0 = 0x0000, + TYPE_APA1 = 0x0055, + TYPE_APA2 = 0x00AA, + TYPE_APA3 = 0x00FF, + TYPE_APA4 = 0x5500, + TYPE_APA5 = 0x5555, + TYPE_APA6 = 0x55AA, + TYPE_APA7 = 0x55FF, + TYPE_APA8 = 0xAA00, + TYPE_APA9 = 0xAA55, + TYPE_APA10 = 0xAAAA, + TYPE_APA11 = 0xAAFF, + TYPE_APA12 = 0xFF00, + TYPE_APA13 = 0xFF55, + TYPE_APA14 = 0xFFAA, + TYPE_APA15 = 0xFFFF, +}; + +enum odm_type_glna { + TYPE_GLNA0 = 0x0000, + TYPE_GLNA1 = 0x0055, + TYPE_GLNA2 = 0x00AA, + TYPE_GLNA3 = 0x00FF, + TYPE_GLNA4 = 0x5500, + TYPE_GLNA5 = 0x5555, + TYPE_GLNA6 = 0x55AA, + TYPE_GLNA7 = 0x55FF, + TYPE_GLNA8 = 0xAA00, + TYPE_GLNA9 = 0xAA55, + TYPE_GLNA10 = 0xAAAA, + TYPE_GLNA11 = 0xAAFF, + TYPE_GLNA12 = 0xFF00, + TYPE_GLNA13 = 0xFF55, + TYPE_GLNA14 = 0xFFAA, + TYPE_GLNA15 = 0xFFFF, +}; + +enum odm_type_alna { + TYPE_ALNA0 = 0x0000, + TYPE_ALNA1 = 0x0055, + TYPE_ALNA2 = 0x00AA, + TYPE_ALNA3 = 0x00FF, + TYPE_ALNA4 = 0x5500, + TYPE_ALNA5 = 0x5555, + TYPE_ALNA6 = 0x55AA, + TYPE_ALNA7 = 0x55FF, + TYPE_ALNA8 = 0xAA00, + TYPE_ALNA9 = 0xAA55, + TYPE_ALNA10 = 0xAAAA, + TYPE_ALNA11 = 0xAAFF, + TYPE_ALNA12 = 0xFF00, + TYPE_ALNA13 = 0xFF55, + TYPE_ALNA14 = 0xFFAA, + TYPE_ALNA15 = 0xFFFF, +}; + +enum odm_rf_radio_path { + ODM_RF_PATH_A = 0, /* Radio path A */ + ODM_RF_PATH_B = 1, /* Radio path B */ + ODM_RF_PATH_C = 2, /* Radio path C */ + ODM_RF_PATH_D = 3, /* Radio path D */ + ODM_RF_PATH_AB, + ODM_RF_PATH_AC, + ODM_RF_PATH_AD, + ODM_RF_PATH_BC, + ODM_RF_PATH_BD, + ODM_RF_PATH_CD, + ODM_RF_PATH_ABC, + ODM_RF_PATH_ACD, + ODM_RF_PATH_BCD, + ODM_RF_PATH_ABCD, + /* ODM_RF_PATH_MAX, */ /* Max RF number 90 support */ +}; + +enum odm_parameter_init { + ODM_PRE_SETTING = 0, + ODM_POST_SETTING = 1, +}; + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_precomp.h b/drivers/staging/rtlwifi/phydm/phydm_precomp.h new file mode 100644 index 000000000000..bada15c4d2d8 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_precomp.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_PRECOMP_H__ +#define __ODM_PRECOMP_H__ + +#include "phydm_types.h" + +/* 2 Config Flags and Structs - defined by each ODM type */ + +#include "../wifi.h" +#include "rtl_phydm.h" + +/* 2 OutSrc Header Files */ + +#include "phydm.h" +#include "phydm_hwconfig.h" +#include "phydm_debug.h" +#include "phydm_regdefine11ac.h" +#include "phydm_regdefine11n.h" +#include "phydm_interface.h" +#include "phydm_reg.h" + +#include "phydm_adc_sampling.h" + +/* JJ ADD 20161014 */ + +#include "../halmac/halmac_reg2.h" + +#define LDPC_HT_ENABLE_RX BIT(0) +#define LDPC_HT_ENABLE_TX BIT(1) +#define LDPC_HT_TEST_TX_ENABLE BIT(2) +#define LDPC_HT_CAP_TX BIT(3) + +#define STBC_HT_ENABLE_RX BIT(0) +#define STBC_HT_ENABLE_TX BIT(1) +#define STBC_HT_TEST_TX_ENABLE BIT(2) +#define STBC_HT_CAP_TX BIT(3) + +#define LDPC_VHT_ENABLE_RX BIT(0) +#define LDPC_VHT_ENABLE_TX BIT(1) +#define LDPC_VHT_TEST_TX_ENABLE BIT(2) +#define LDPC_VHT_CAP_TX BIT(3) + +#define STBC_VHT_ENABLE_RX BIT(0) +#define STBC_VHT_ENABLE_TX BIT(1) +#define STBC_VHT_TEST_TX_ENABLE BIT(2) +#define STBC_VHT_CAP_TX BIT(3) + +#include "rtl8822b/halhwimg8822b_mac.h" +#include "rtl8822b/halhwimg8822b_rf.h" +#include "rtl8822b/halhwimg8822b_bb.h" +#include "rtl8822b/phydm_regconfig8822b.h" +#include "rtl8822b/halphyrf_8822b.h" +#include "rtl8822b/phydm_rtl8822b.h" +#include "rtl8822b/phydm_hal_api8822b.h" +#include "rtl8822b/version_rtl8822b.h" + +#include "../halmac/halmac_reg_8822b.h" + +/* JJ ADD 20161014 */ + +#endif /* __ODM_PRECOMP_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/phydm_psd.c b/drivers/staging/rtlwifi/phydm/phydm_psd.c new file mode 100644 index 000000000000..48f8776bc8f9 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_psd.c @@ -0,0 +1,422 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*============================================================ + * include files + *============================================================ + */ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u32 psd_report = 0; + + odm_set_bb_reg(dm, dm_psd_table->psd_reg, 0x3ff, psd_tone_idx); + + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22), + 1); /*PSD trigger start*/ + ODM_delay_us(10); + odm_set_bb_reg(dm, dm_psd_table->psd_reg, BIT(22), + 0); /*PSD trigger stop*/ + + psd_report = odm_get_bb_reg(dm, dm_psd_table->psd_report_reg, 0xffff); + psd_report = odm_convert_to_db(psd_report) + igi; + + return psd_report; +} + +static u8 phydm_psd_stop_trx(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u32 i; + u8 trx_idle_success = false; + u32 dbg_port_value = 0; + + /*[Stop TRX]----------------------------------------------------------*/ + if (!phydm_set_bb_dbg_port(dm, BB_DBGPORT_PRIORITY_3, + 0x0)) /*set debug port to 0x0*/ + return STOP_TRX_FAIL; + + for (i = 0; i < 10000; i++) { + dbg_port_value = phydm_get_bb_dbg_port_value(dm); + if ((dbg_port_value & (BIT(17) | BIT(3))) == + 0) /* PHYTXON && CCA_all */ { + ODM_RT_TRACE(dm, ODM_COMP_API, + "PSD wait for ((%d)) times\n", i); + + trx_idle_success = true; + break; + } + } + + if (trx_idle_success) { + /*pause all TX queue*/ + odm_set_bb_reg(dm, 0x520, 0xff0000, 0xff); + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + /*disable CCK block*/ + odm_set_bb_reg(dm, 0x808, BIT(28), 0); + /*disable OFDM RX CCA*/ + odm_set_bb_reg(dm, 0x838, BIT(1), 1); + } else { + /*TBD*/ + /* disable whole CCK block */ + odm_set_bb_reg(dm, 0x800, BIT(24), 0); + /*[ Set IQK Matrix = 0 ] equivalent to [ Turn off CCA]*/ + odm_set_bb_reg(dm, 0xC14, MASKDWORD, 0x0); + } + + } else { + return STOP_TRX_FAIL; + } + + phydm_release_bb_dbg_port(dm); + + return STOP_TRX_SUCCESS; +} + +static u8 psd_result_cali_tone_8821[7] = {21, 28, 33, 93, 98, 105, 127}; +static u8 psd_result_cali_val_8821[7] = {67, 69, 71, 72, 71, 69, 67}; + +void phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u32 i = 0, mod_tone_idx; + u32 t = 0; + u16 fft_max_half_bw; + u32 psd_igi_a_reg; + u32 psd_igi_b_reg; + u16 psd_fc_channel = dm_psd_table->psd_fc_channel; + u8 ag_rf_mode_reg = 0; + u8 rf_reg18_9_8 = 0; + u32 psd_result_tmp = 0; + u8 psd_result = 0; + u8 psd_result_cali_tone[7] = {0}; + u8 psd_result_cali_val[7] = {0}; + u8 noise_table_idx = 0; + + if (dm->support_ic_type == ODM_RTL8821) { + odm_move_memory(dm, psd_result_cali_tone, + psd_result_cali_tone_8821, 7); + odm_move_memory(dm, psd_result_cali_val, + psd_result_cali_val_8821, 7); + } + + dm_psd_table->psd_in_progress = 1; + + /*[Stop DIG]*/ + dm->support_ability &= ~(ODM_BB_DIG); + dm->support_ability &= ~(ODM_BB_FA_CNT); + + ODM_RT_TRACE(dm, ODM_COMP_API, "PSD Start =>\n"); + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + psd_igi_a_reg = 0xc50; + psd_igi_b_reg = 0xe50; + } else { + psd_igi_a_reg = 0xc50; + psd_igi_b_reg = 0xc58; + } + + /*[back up IGI]*/ + dm_psd_table->initial_gain_backup = + odm_get_bb_reg(dm, psd_igi_a_reg, 0xff); + odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, + 0x6e); /*IGI target at 0dBm & make it can't CCA*/ + odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, + 0x6e); /*IGI target at 0dBm & make it can't CCA*/ + ODM_delay_us(10); + + if (phydm_psd_stop_trx(dm) == STOP_TRX_FAIL) { + ODM_RT_TRACE(dm, ODM_COMP_API, "STOP_TRX_FAIL\n"); + return; + } + + /*[Set IGI]*/ + odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, igi); + odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, igi); + + /*[Backup RF Reg]*/ + dm_psd_table->rf_0x18_bkp = + odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK); + + if (psd_fc_channel > 14) { + rf_reg18_9_8 = 1; + + if (psd_fc_channel >= 36 && psd_fc_channel <= 64) + ag_rf_mode_reg = 0x1; + else if (psd_fc_channel >= 100 && psd_fc_channel <= 140) + ag_rf_mode_reg = 0x3; + else if (psd_fc_channel > 140) + ag_rf_mode_reg = 0x5; + } + + /* Set RF fc*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xff, psd_fc_channel); + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0x300, rf_reg18_9_8); + /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xc00, + dm_psd_table->psd_bw_rf_reg); + /* Set RF ag fc mode*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xf0000, ag_rf_mode_reg); + + ODM_RT_TRACE(dm, ODM_COMP_API, "0xc50=((0x%x))\n", + odm_get_bb_reg(dm, 0xc50, MASKDWORD)); + ODM_RT_TRACE(dm, ODM_COMP_API, "RF0x18=((0x%x))\n", + odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK)); + + /*[Stop 3-wires]*/ + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + odm_set_bb_reg(dm, 0xc00, 0xf, 0x4); /* hardware 3-wire off */ + odm_set_bb_reg(dm, 0xe00, 0xf, 0x4); /* hardware 3-wire off */ + } else { + odm_set_bb_reg(dm, 0x88c, 0xf00000, + 0xf); /* 3 wire Disable 88c[23:20]=0xf */ + } + ODM_delay_us(10); + + if (stop_point > (dm_psd_table->fft_smp_point - 1)) + stop_point = (dm_psd_table->fft_smp_point - 1); + + if (start_point > (dm_psd_table->fft_smp_point - 1)) + start_point = (dm_psd_table->fft_smp_point - 1); + + if (start_point > stop_point) + stop_point = start_point; + + if (stop_point > 127) /* limit of psd_result[128] */ + stop_point = 127; + + for (i = start_point; i <= stop_point; i++) { + fft_max_half_bw = (dm_psd_table->fft_smp_point) >> 1; + + if (i < fft_max_half_bw) + mod_tone_idx = i + fft_max_half_bw; + else + mod_tone_idx = i - fft_max_half_bw; + + psd_result_tmp = 0; + for (t = 0; t < dm_psd_table->sw_avg_time; t++) + psd_result_tmp += + phydm_get_psd_data(dm, mod_tone_idx, igi); + psd_result = + (u8)((psd_result_tmp / dm_psd_table->sw_avg_time)) - + dm_psd_table->psd_pwr_common_offset; + + if (dm_psd_table->fft_smp_point == 128 && + (dm_psd_table->noise_k_en)) { + if (i > psd_result_cali_tone[noise_table_idx]) + noise_table_idx++; + + if (noise_table_idx > 6) + noise_table_idx = 6; + + if (psd_result >= psd_result_cali_val[noise_table_idx]) + psd_result = + psd_result - + psd_result_cali_val[noise_table_idx]; + else + psd_result = 0; + + dm_psd_table->psd_result[i] = psd_result; + } + + ODM_RT_TRACE(dm, ODM_COMP_API, "[%d] N_cali = %d, PSD = %d\n", + mod_tone_idx, psd_result_cali_val[noise_table_idx], + psd_result); + } + + /*[Start 3-wires]*/ + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + odm_set_bb_reg(dm, 0xc00, 0xf, 0x7); /* hardware 3-wire on */ + odm_set_bb_reg(dm, 0xe00, 0xf, 0x7); /* hardware 3-wire on */ + } else { + odm_set_bb_reg(dm, 0x88c, 0xf00000, + 0x0); /* 3 wire enable 88c[23:20]=0x0 */ + } + ODM_delay_us(10); + + /*[Revert Reg]*/ + odm_set_bb_reg(dm, 0x520, 0xff0000, 0x0); /*start all TX queue*/ + odm_set_bb_reg(dm, 0x808, BIT(28), 1); /*enable CCK block*/ + odm_set_bb_reg(dm, 0x838, BIT(1), 0); /*enable OFDM RX CCA*/ + + odm_set_bb_reg(dm, psd_igi_a_reg, 0xff, + dm_psd_table->initial_gain_backup); + odm_set_bb_reg(dm, psd_igi_b_reg, 0xff, + dm_psd_table->initial_gain_backup); + + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, RFREGOFFSETMASK, + dm_psd_table->rf_0x18_bkp); + + ODM_RT_TRACE(dm, ODM_COMP_API, "PSD finished\n\n"); + + dm->support_ability |= ODM_BB_DIG; + dm->support_ability |= ODM_BB_FA_CNT; + dm_psd_table->psd_in_progress = 0; +} + +void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, + u8 i_q_setting, u16 fft_smp_point, u8 ant_sel, + u8 psd_input, u8 channel, u8 noise_k_en) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u8 fft_smp_point_idx = 0; + + dm_psd_table->fft_smp_point = fft_smp_point; + + if (sw_avg_time == 0) + sw_avg_time = 1; + + dm_psd_table->sw_avg_time = sw_avg_time; + dm_psd_table->psd_fc_channel = channel; + dm_psd_table->noise_k_en = noise_k_en; + + if (fft_smp_point == 128) + fft_smp_point_idx = 0; + else if (fft_smp_point == 256) + fft_smp_point_idx = 1; + else if (fft_smp_point == 512) + fft_smp_point_idx = 2; + else if (fft_smp_point == 1024) + fft_smp_point_idx = 3; + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + odm_set_bb_reg(dm, 0x910, BIT(11) | BIT(10), i_q_setting); + odm_set_bb_reg(dm, 0x910, BIT(13) | BIT(12), hw_avg_time); + odm_set_bb_reg(dm, 0x910, BIT(15) | BIT(14), fft_smp_point_idx); + odm_set_bb_reg(dm, 0x910, BIT(17) | BIT(16), ant_sel); + odm_set_bb_reg(dm, 0x910, BIT(23), psd_input); + } + + /*bw = (*dm->band_width); //ODM_BW20M */ + /*channel = *(dm->channel);*/ +} + +void phydm_psd_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + + ODM_RT_TRACE(dm, ODM_COMP_API, "PSD para init\n"); + + dm_psd_table->psd_in_progress = false; + + if (dm->support_ic_type & ODM_IC_11AC_SERIES) { + dm_psd_table->psd_reg = 0x910; + dm_psd_table->psd_report_reg = 0xF44; + + if (ODM_IC_11AC_2_SERIES) + dm_psd_table->psd_bw_rf_reg = + 1; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + else + dm_psd_table->psd_bw_rf_reg = + 2; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + + } else { + dm_psd_table->psd_reg = 0x808; + dm_psd_table->psd_report_reg = 0x8B4; + dm_psd_table->psd_bw_rf_reg = + 2; /*2b'11: 20MHz, 2b'10: 40MHz, 2b'01: 80MHz */ + } + + if (dm->support_ic_type == ODM_RTL8812) + dm_psd_table->psd_pwr_common_offset = 0; + else if (dm->support_ic_type == ODM_RTL8821) + dm_psd_table->psd_pwr_common_offset = 0; + else + dm_psd_table->psd_pwr_common_offset = 0; + + phydm_psd_para_setting(dm, 1, 2, 3, 128, 0, 0, 7, 0); + /*phydm_psd(dm, 0x3c, 0, 127);*/ /* target at -50dBm */ +} + +void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, char *output, + u32 *_out_len, u32 input_num) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + char help[] = "-h"; + u32 var1[10] = {0}; + u32 used = *_used; + u32 out_len = *_out_len; + u8 i; + + if ((strcmp(input[1], help) == 0)) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "{0} {sw_avg} {hw_avg 0:3} {1:I,2:Q,3:IQ} {fft_point: 128*(1:4)} {path_sel 0~3} {0:ADC, 1:RXIQC} {CH} {noise_k}\n"); + PHYDM_SNPRINTF(output + used, out_len - used, + "{1} {IGI(hex)} {start_point} {stop_point}\n"); + return; + } + + PHYDM_SSCANF(input[1], DCMD_DECIMAL, &var1[0]); + + if (var1[0] == 0) { + for (i = 1; i < 10; i++) { + if (input[i + 1]) + PHYDM_SSCANF(input[i + 1], DCMD_DECIMAL, + &var1[i]); + } + + PHYDM_SNPRINTF( + output + used, out_len - used, + "sw_avg_time=((%d)), hw_avg_time=((%d)), IQ=((%d)), fft=((%d)), path=((%d)), input =((%d)) ch=((%d)), noise_k=((%d))\n", + var1[1], var1[2], var1[3], var1[4], var1[5], var1[6], + (u8)var1[7], (u8)var1[8]); + phydm_psd_para_setting(dm, (u8)var1[1], (u8)var1[2], + (u8)var1[3], (u16)var1[4], (u8)var1[5], + (u8)var1[6], (u8)var1[7], (u8)var1[8]); + + } else if (var1[0] == 1) { + PHYDM_SSCANF(input[2], DCMD_HEX, &var1[1]); + PHYDM_SSCANF(input[3], DCMD_DECIMAL, &var1[2]); + PHYDM_SSCANF(input[4], DCMD_DECIMAL, &var1[3]); + PHYDM_SNPRINTF( + output + used, out_len - used, + "IGI=((0x%x)), start_point=((%d)), stop_point=((%d))\n", + var1[1], var1[2], var1[3]); + dm->debug_components |= ODM_COMP_API; + phydm_psd(dm, var1[1], (u16)var1[2], (u16)var1[3]); + dm->debug_components &= (~ODM_COMP_API); + } +} + +u8 phydm_get_psd_result_table(void *dm_void, int index) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct psd_info *dm_psd_table = &dm->dm_psd_table; + u8 temp_result = 0; + + if (index < 128) + temp_result = dm_psd_table->psd_result[index]; + + return temp_result; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_psd.h b/drivers/staging/rtlwifi/phydm/phydm_psd.h new file mode 100644 index 000000000000..aeb70751d80b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_psd.h @@ -0,0 +1,67 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMPSD_H__ +#define __PHYDMPSD_H__ + +/*#define PSD_VERSION "1.0"*/ /*2016.09.22 Dino*/ +#define PSD_VERSION "1.1" /*2016.10.07 Dino, Add Option for PSD Tone index + *Selection + */ + +#define STOP_TRX_SUCCESS 1 +#define STOP_TRX_FAIL 0 + +struct psd_info { + u8 psd_in_progress; + u32 psd_reg; + u32 psd_report_reg; + u8 psd_pwr_common_offset; + u16 sw_avg_time; + u16 fft_smp_point; + u32 initial_gain_backup; + u32 rf_0x18_bkp; + u16 psd_fc_channel; + u32 psd_bw_rf_reg; + u8 psd_result[128]; + u8 noise_k_en; +}; + +u32 phydm_get_psd_data(void *dm_void, u32 psd_tone_idx, u32 igi); + +void phydm_psd_debug(void *dm_void, char input[][16], u32 *_used, char *output, + u32 *_out_len, u32 input_num); + +void phydm_psd(void *dm_void, u32 igi, u16 start_point, u16 stop_point); + +void phydm_psd_para_setting(void *dm_void, u8 sw_avg_time, u8 hw_avg_time, + u8 i_q_setting, u16 fft_smp_point, u8 ant_sel, + u8 psd_input, u8 channel, u8 noise_k_en); + +void phydm_psd_init(void *dm_void); + +u8 phydm_get_psd_result_table(void *dm_void, int index); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.c b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c new file mode 100644 index 000000000000..8c08c76d4eda --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.c @@ -0,0 +1,1208 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/* ************************************************************ + * include files + * *************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" + +void phydm_h2C_debug(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 h2c_parameter[H2C_MAX_LENGTH] = {0}; + u8 phydm_h2c_id = (u8)dm_value[0]; + u8 i; + u32 used = *_used; + u32 out_len = *_out_len; + + PHYDM_SNPRINTF(output + used, out_len - used, + "Phydm Send H2C_ID (( 0x%x))\n", phydm_h2c_id); + for (i = 0; i < H2C_MAX_LENGTH; i++) { + h2c_parameter[i] = (u8)dm_value[i + 1]; + PHYDM_SNPRINTF(output + used, out_len - used, + "H2C: Byte[%d] = ((0x%x))\n", i, + h2c_parameter[i]); + } + + odm_fill_h2c_cmd(dm, phydm_h2c_id, H2C_MAX_LENGTH, h2c_parameter); +} + +void phydm_RA_debug_PCR(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u32 used = *_used; + u32 out_len = *_out_len; + + if (dm_value[0] == 100) { + PHYDM_SNPRINTF( + output + used, out_len - used, + "[Get] PCR RA_threshold_offset = (( %s%d ))\n", + ((ra_tab->RA_threshold_offset == 0) ? + " " : + ((ra_tab->RA_offset_direction) ? "+" : "-")), + ra_tab->RA_threshold_offset); + /**/ + } else if (dm_value[0] == 0) { + ra_tab->RA_offset_direction = 0; + ra_tab->RA_threshold_offset = (u8)dm_value[1]; + PHYDM_SNPRINTF(output + used, out_len - used, + "[Set] PCR RA_threshold_offset = (( -%d ))\n", + ra_tab->RA_threshold_offset); + } else if (dm_value[0] == 1) { + ra_tab->RA_offset_direction = 1; + ra_tab->RA_threshold_offset = (u8)dm_value[1]; + PHYDM_SNPRINTF(output + used, out_len - used, + "[Set] PCR RA_threshold_offset = (( +%d ))\n", + ra_tab->RA_threshold_offset); + } else { + PHYDM_SNPRINTF(output + used, out_len - used, "[Set] Error\n"); + /**/ + } +} + +void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + u8 para_idx = cmd_buf[0]; /*Retry Penalty, NH, NL*/ + u8 i; + + ODM_RT_TRACE(dm, PHYDM_COMP_RA_DBG, + "[ From FW C2H RA Para ] cmd_buf[0]= (( %d ))\n", + cmd_buf[0]); + + if (para_idx == RADBG_DEBUG_MONITOR1) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "RSSI =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "rate =", cmd_buf[2] & 0x7f); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "SGI =", (cmd_buf[2] & 0x80) >> 7); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "BW =", cmd_buf[3]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "BW_max =", cmd_buf[4]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "multi_rate0 =", cmd_buf[5]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "multi_rate1 =", cmd_buf[6]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "DISRA =", cmd_buf[7]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "VHT_EN =", cmd_buf[8]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "SGI_support =", cmd_buf[9]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "try_ness =", cmd_buf[10]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "pre_rate =", cmd_buf[11]); + } else { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "RSSI =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %x\n", + "BW =", cmd_buf[2]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "DISRA =", cmd_buf[3]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "VHT_EN =", cmd_buf[4]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "Hightest rate =", cmd_buf[5]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "Lowest rate =", cmd_buf[6]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "SGI_support =", cmd_buf[7]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "Rate_ID =", cmd_buf[8]); + ; + } + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + } else if (para_idx == RADBG_DEBUG_MONITOR2) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + if (dm->support_ic_type & PHYDM_IC_3081_SERIES) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "rate_id =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "highest_rate =", cmd_buf[2]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "lowest_rate =", cmd_buf[3]); + + for (i = 4; i <= 11; i++) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "RAMASK = 0x%x\n", cmd_buf[i]); + } else { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "%5s %x%x %x%x %x%x %x%x\n", + "RA Mask:", cmd_buf[8], cmd_buf[7], + cmd_buf[6], cmd_buf[5], cmd_buf[4], + cmd_buf[3], cmd_buf[2], cmd_buf[1]); + } + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "-------------------------------\n"); + } else if (para_idx == RADBG_DEBUG_MONITOR3) { + for (i = 0; i < (cmd_len - 1); i++) + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, + "content[%d] = %d\n", i, cmd_buf[1 + i]); + } else if (para_idx == RADBG_DEBUG_MONITOR4) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s {%d.%d}\n", + "RA version =", cmd_buf[1], cmd_buf[2]); + } else if (para_idx == RADBG_DEBUG_MONITOR5) { + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "Current rate =", cmd_buf[1]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "Retry ratio =", cmd_buf[2]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s %d\n", + "rate down ratio =", cmd_buf[3]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x\n", + "highest rate =", cmd_buf[4]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s {0x%x 0x%x}\n", + "Muti-try =", cmd_buf[5], cmd_buf[6]); + ODM_RT_TRACE(dm, ODM_FW_DEBUG_TRACE, "%5s 0x%x%x%x%x%x\n", + "RA mask =", cmd_buf[11], cmd_buf[10], cmd_buf[9], + cmd_buf[8], cmd_buf[7]); + } +} + +void phydm_ra_dynamic_retry_count(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_DYNAMIC_ARFR)) + return; + + if (dm->pre_b_noisy != dm->noisy_decision) { + if (dm->noisy_decision) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "->Noisy Env. RA fallback value\n"); + odm_set_mac_reg(dm, 0x430, MASKDWORD, 0x0); + odm_set_mac_reg(dm, 0x434, MASKDWORD, 0x04030201); + } else { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "->Clean Env. RA fallback value\n"); + odm_set_mac_reg(dm, 0x430, MASKDWORD, 0x01000000); + odm_set_mac_reg(dm, 0x434, MASKDWORD, 0x06050402); + } + dm->pre_b_noisy = dm->noisy_decision; + } +} + +void phydm_ra_dynamic_retry_limit(void *dm_void) {} + +void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 legacy_table[12] = {1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54}; + u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/ + u8 vht_en = (rate_idx >= ODM_RATEVHTSS1MCS0) ? 1 : 0; + u8 b_sgi = (rate & 0x80) >> 7; + + ODM_RT_TRACE(dm, dbg_component, "( %s%s%s%s%d%s%s)\n", + ((rate_idx >= ODM_RATEVHTSS1MCS0) && + (rate_idx <= ODM_RATEVHTSS1MCS9)) ? + "VHT 1ss " : + "", + ((rate_idx >= ODM_RATEVHTSS2MCS0) && + (rate_idx <= ODM_RATEVHTSS2MCS9)) ? + "VHT 2ss " : + "", + ((rate_idx >= ODM_RATEVHTSS3MCS0) && + (rate_idx <= ODM_RATEVHTSS3MCS9)) ? + "VHT 3ss " : + "", + (rate_idx >= ODM_RATEMCS0) ? "MCS " : "", + (vht_en) ? ((rate_idx - ODM_RATEVHTSS1MCS0) % 10) : + ((rate_idx >= ODM_RATEMCS0) ? + (rate_idx - ODM_RATEMCS0) : + ((rate_idx <= ODM_RATE54M) ? + legacy_table[rate_idx] : + 0)), + (b_sgi) ? "-S" : " ", + (rate_idx >= ODM_RATEMCS0) ? "" : "M"); +} + +void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u8 macid = cmd_buf[1]; + u8 rate = cmd_buf[0]; + u8 rate_idx = rate & 0x7f; /*remove bit7 SGI*/ + u8 rate_order; + + if (cmd_len >= 4) { + if (cmd_buf[3] == 0) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "TX Init-rate Update[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 0xff) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "FW Level: Fix rate[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 1) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "Try Success[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 2) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "Try Fail & Try Again[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 3) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "rate Back[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 4) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "start rate by RSSI[%d]:", macid); + /**/ + } else if (cmd_buf[3] == 5) { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, + "Try rate[%d]:", macid); + /**/ + } + } else { + ODM_RT_TRACE(dm, ODM_COMP_RATE_ADAPTIVE, "Tx rate Update[%d]:", + macid); + /**/ + } + + phydm_print_rate(dm, rate, ODM_COMP_RATE_ADAPTIVE); + + ra_tab->link_tx_rate[macid] = rate; + + /*trigger power training*/ + + rate_order = phydm_rate_order_compute(dm, rate_idx); + + if ((dm->is_one_entry_only) || + ((rate_order > ra_tab->highest_client_tx_order) && + (ra_tab->power_tracking_flag == 1))) { + phydm_update_pwr_track(dm, rate_idx); + ra_tab->power_tracking_flag = 0; + } + + /*trigger dynamic rate ID*/ +} + +void odm_rssi_monitor_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + ra_tab->firstconnect = false; +} + +void odm_ra_post_action_on_assoc(void *dm_void) {} + +void phydm_init_ra_info(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (dm->support_ic_type == ODM_RTL8822B) { + u32 ret_value; + + ret_value = odm_get_bb_reg(dm, 0x4c8, MASKBYTE2); + odm_set_bb_reg(dm, 0x4cc, MASKBYTE3, (ret_value - 1)); + } +} + +void phydm_modify_RA_PCR_threshold(void *dm_void, u8 RA_offset_direction, + u8 RA_threshold_offset + + ) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + ra_tab->RA_offset_direction = RA_offset_direction; + ra_tab->RA_threshold_offset = RA_threshold_offset; + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Set RA_threshold_offset = (( %s%d ))\n", + ((RA_threshold_offset == 0) ? + " " : + ((RA_offset_direction) ? "+" : "-")), + RA_threshold_offset); +} + +static void odm_rssi_monitor_check_mp(void *dm_void) {} + +static void odm_rssi_monitor_check_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_sta_info *entry; + int i; + int tmp_entry_min_pwdb = 0xff; + unsigned long cur_tx_ok_cnt = 0, cur_rx_ok_cnt = 0; + u8 UL_DL_STATE = 0, STBC_TX = 0, tx_bf_en = 0; + u8 h2c_parameter[H2C_0X42_LENGTH] = {0}; + u8 cmdlen = H2C_0X42_LENGTH; + u8 macid = 0; + + if (!dm->is_linked) + return; + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + entry = (struct rtl_sta_info *)dm->odm_sta_info[i]; + if (!IS_STA_VALID(entry)) + continue; + + if (is_multicast_ether_addr(entry->mac_addr) || + is_broadcast_ether_addr(entry->mac_addr)) + continue; + + if (entry->rssi_stat.undecorated_smoothed_pwdb == (-1)) + continue; + + /* calculate min_pwdb */ + if (entry->rssi_stat.undecorated_smoothed_pwdb < + tmp_entry_min_pwdb) + tmp_entry_min_pwdb = + entry->rssi_stat.undecorated_smoothed_pwdb; + + /* report RSSI */ + cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast_inperiod; + cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast_inperiod; + + if (cur_rx_ok_cnt > (cur_tx_ok_cnt * 6)) + UL_DL_STATE = 1; + else + UL_DL_STATE = 0; + + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + struct ieee80211_sta *sta = container_of( + (void *)entry, struct ieee80211_sta, drv_priv); + macid = sta->aid + 1; + } + + h2c_parameter[0] = macid; + h2c_parameter[2] = + entry->rssi_stat.undecorated_smoothed_pwdb & 0x7F; + + if (UL_DL_STATE) + h2c_parameter[3] |= RAINFO_BE_RX_STATE; + + if (tx_bf_en) + h2c_parameter[3] |= RAINFO_BF_STATE; + if (STBC_TX) + h2c_parameter[3] |= RAINFO_STBC_STATE; + if (dm->noisy_decision) + h2c_parameter[3] |= RAINFO_NOISY_STATE; + + if (entry->rssi_stat.is_send_rssi == RA_RSSI_STATE_SEND) { + h2c_parameter[3] |= RAINFO_INIT_RSSI_RATE_STATE; + entry->rssi_stat.is_send_rssi = RA_RSSI_STATE_HOLD; + } + + h2c_parameter[4] = (ra_tab->RA_threshold_offset & 0x7f) | + (ra_tab->RA_offset_direction << 7); + + odm_fill_h2c_cmd(dm, ODM_H2C_RSSI_REPORT, cmdlen, + h2c_parameter); + } + + if (tmp_entry_min_pwdb != 0xff) + dm->rssi_min = tmp_entry_min_pwdb; +} + +static void odm_rssi_monitor_check_ap(void *dm_void) {} + +void odm_rssi_monitor_check(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + if (!(dm->support_ability & ODM_BB_RSSI_MONITOR)) + return; + + switch (dm->support_platform) { + case ODM_WIN: + odm_rssi_monitor_check_mp(dm); + break; + + case ODM_CE: + odm_rssi_monitor_check_ce(dm); + break; + + case ODM_AP: + odm_rssi_monitor_check_ap(dm); + break; + + default: + break; + } +} + +void odm_rate_adaptive_mask_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct odm_rate_adaptive *odm_ra = &dm->rate_adaptive; + + odm_ra->type = dm_type_by_driver; + if (odm_ra->type == dm_type_by_driver) + dm->is_use_ra_mask = true; + else + dm->is_use_ra_mask = false; + + odm_ra->ratr_state = DM_RATR_STA_INIT; + + odm_ra->ldpc_thres = 35; + odm_ra->is_use_ldpc = false; + + odm_ra->high_rssi_thresh = 50; + odm_ra->low_rssi_thresh = 20; +} + +/*----------------------------------------------------------------------------- + * Function: odm_refresh_rate_adaptive_mask() + * + * Overview: Update rate table mask according to rssi + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 05/27/2009 hpfan Create version 0. + * + *--------------------------------------------------------------------------- + */ +void odm_refresh_rate_adaptive_mask(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + if (!dm->is_linked) + return; + + if (!(dm->support_ability & ODM_BB_RA_MASK)) { + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "%s(): Return cos not supported\n", __func__); + return; + } + + ra_tab->force_update_ra_mask_count++; + /* 2011/09/29 MH In HW integration first stage, we provide 4 different + * handle to operate at the same time. + * In the stage2/3, we need to prive universal interface and merge all + * HW dynamic mechanism. + */ + switch (dm->support_platform) { + case ODM_WIN: + odm_refresh_rate_adaptive_mask_mp(dm); + break; + + case ODM_CE: + odm_refresh_rate_adaptive_mask_ce(dm); + break; + + case ODM_AP: + odm_refresh_rate_adaptive_mask_apadsl(dm); + break; + } +} + +static u8 phydm_trans_platform_bw(void *dm_void, u8 BW) +{ + if (BW == HT_CHANNEL_WIDTH_20) + BW = PHYDM_BW_20; + + else if (BW == HT_CHANNEL_WIDTH_20_40) + BW = PHYDM_BW_40; + + else if (BW == HT_CHANNEL_WIDTH_80) + BW = PHYDM_BW_80; + + return BW; +} + +static u8 phydm_trans_platform_rf_type(void *dm_void, u8 rf_type) +{ + if (rf_type == RF_1T2R) + rf_type = PHYDM_RF_1T2R; + + else if (rf_type == RF_2T4R) + rf_type = PHYDM_RF_2T4R; + + else if (rf_type == RF_2T2R) + rf_type = PHYDM_RF_2T2R; + + else if (rf_type == RF_1T1R) + rf_type = PHYDM_RF_1T1R; + + else if (rf_type == RF_2T2R_GREEN) + rf_type = PHYDM_RF_2T2R_GREEN; + + else if (rf_type == RF_3T3R) + rf_type = PHYDM_RF_3T3R; + + else if (rf_type == RF_4T4R) + rf_type = PHYDM_RF_4T4R; + + else if (rf_type == RF_2T3R) + rf_type = PHYDM_RF_1T2R; + + else if (rf_type == RF_3T4R) + rf_type = PHYDM_RF_3T4R; + + return rf_type; +} + +static u32 phydm_trans_platform_wireless_mode(void *dm_void, u32 wireless_mode) +{ + return wireless_mode; +} + +u8 phydm_vht_en_mapping(void *dm_void, u32 wireless_mode) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 vht_en_out = 0; + + if ((wireless_mode == PHYDM_WIRELESS_MODE_AC_5G) || + (wireless_mode == PHYDM_WIRELESS_MODE_AC_24G) || + (wireless_mode == PHYDM_WIRELESS_MODE_AC_ONLY)) { + vht_en_out = 1; + /**/ + } + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "wireless_mode= (( 0x%x )), VHT_EN= (( %d ))\n", + wireless_mode, vht_en_out); + return vht_en_out; +} + +u8 phydm_rate_id_mapping(void *dm_void, u32 wireless_mode, u8 rf_type, u8 bw) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 rate_id_idx = 0; + u8 phydm_BW; + u8 phydm_rf_type; + + phydm_BW = phydm_trans_platform_bw(dm, bw); + phydm_rf_type = phydm_trans_platform_rf_type(dm, rf_type); + wireless_mode = phydm_trans_platform_wireless_mode(dm, wireless_mode); + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x ))\n", + wireless_mode, phydm_rf_type, phydm_BW); + + switch (wireless_mode) { + case PHYDM_WIRELESS_MODE_N_24G: { + if (phydm_BW == PHYDM_BW_40) { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_BGN_40M_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_BGN_40M_2SS; + else + rate_id_idx = PHYDM_ARFR5_N_3SS; + + } else { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_BGN_20M_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_BGN_20M_2SS; + else + rate_id_idx = PHYDM_ARFR5_N_3SS; + } + } break; + + case PHYDM_WIRELESS_MODE_N_5G: { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_GN_N1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_GN_N2SS; + else + rate_id_idx = PHYDM_ARFR5_N_3SS; + } + + break; + + case PHYDM_WIRELESS_MODE_G: + rate_id_idx = PHYDM_BG; + break; + + case PHYDM_WIRELESS_MODE_A: + rate_id_idx = PHYDM_G; + break; + + case PHYDM_WIRELESS_MODE_B: + rate_id_idx = PHYDM_B_20M; + break; + + case PHYDM_WIRELESS_MODE_AC_5G: + case PHYDM_WIRELESS_MODE_AC_ONLY: { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_ARFR1_AC_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_ARFR0_AC_2SS; + else + rate_id_idx = PHYDM_ARFR4_AC_3SS; + } break; + + case PHYDM_WIRELESS_MODE_AC_24G: { + /*Becareful to set "Lowest rate" while using PHYDM_ARFR4_AC_3SS + *in 2.4G/5G + */ + if (phydm_BW >= PHYDM_BW_80) { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_ARFR1_AC_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_ARFR0_AC_2SS; + else + rate_id_idx = PHYDM_ARFR4_AC_3SS; + } else { + if (phydm_rf_type == PHYDM_RF_1T1R) + rate_id_idx = PHYDM_ARFR2_AC_2G_1SS; + else if (phydm_rf_type == PHYDM_RF_2T2R) + rate_id_idx = PHYDM_ARFR3_AC_2G_2SS; + else + rate_id_idx = PHYDM_ARFR4_AC_3SS; + } + } break; + + default: + rate_id_idx = 0; + break; + } + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "RA rate ID = (( 0x%x ))\n", + rate_id_idx); + + return rate_id_idx; +} + +void phydm_update_hal_ra_mask(void *dm_void, u32 wireless_mode, u8 rf_type, + u8 BW, u8 mimo_ps_enable, u8 disable_cck_rate, + u32 *ratr_bitmap_msb_in, u32 *ratr_bitmap_lsb_in, + u8 tx_rate_level) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 phydm_rf_type; + u8 phydm_BW; + u32 ratr_bitmap = *ratr_bitmap_lsb_in, + ratr_bitmap_msb = *ratr_bitmap_msb_in; + + wireless_mode = phydm_trans_platform_wireless_mode(dm, wireless_mode); + + phydm_rf_type = phydm_trans_platform_rf_type(dm, rf_type); + phydm_BW = phydm_trans_platform_bw(dm, BW); + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Platfoem original RA Mask = (( 0x %x | %x ))\n", + ratr_bitmap_msb, ratr_bitmap); + + switch (wireless_mode) { + case PHYDM_WIRELESS_MODE_B: { + ratr_bitmap &= 0x0000000f; + } break; + + case PHYDM_WIRELESS_MODE_G: { + ratr_bitmap &= 0x00000ff5; + } break; + + case PHYDM_WIRELESS_MODE_A: { + ratr_bitmap &= 0x00000ff0; + } break; + + case PHYDM_WIRELESS_MODE_N_24G: + case PHYDM_WIRELESS_MODE_N_5G: { + if (mimo_ps_enable) + phydm_rf_type = PHYDM_RF_1T1R; + + if (phydm_rf_type == PHYDM_RF_1T1R) { + if (phydm_BW == PHYDM_BW_40) + ratr_bitmap &= 0x000ff015; + else + ratr_bitmap &= 0x000ff005; + } else if (phydm_rf_type == PHYDM_RF_2T2R || + phydm_rf_type == PHYDM_RF_2T4R || + phydm_rf_type == PHYDM_RF_2T3R) { + if (phydm_BW == PHYDM_BW_40) + ratr_bitmap &= 0x0ffff015; + else + ratr_bitmap &= 0x0ffff005; + } else { /*3T*/ + + ratr_bitmap &= 0xfffff015; + ratr_bitmap_msb &= 0xf; + } + } break; + + case PHYDM_WIRELESS_MODE_AC_24G: { + if (phydm_rf_type == PHYDM_RF_1T1R) { + ratr_bitmap &= 0x003ff015; + } else if (phydm_rf_type == PHYDM_RF_2T2R || + phydm_rf_type == PHYDM_RF_2T4R || + phydm_rf_type == PHYDM_RF_2T3R) { + ratr_bitmap &= 0xfffff015; + } else { /*3T*/ + + ratr_bitmap &= 0xfffff010; + ratr_bitmap_msb &= 0x3ff; + } + + if (phydm_BW == + PHYDM_BW_20) { /* AC 20MHz doesn't support MCS9 */ + ratr_bitmap &= 0x7fdfffff; + ratr_bitmap_msb &= 0x1ff; + } + } break; + + case PHYDM_WIRELESS_MODE_AC_5G: { + if (phydm_rf_type == PHYDM_RF_1T1R) { + ratr_bitmap &= 0x003ff010; + } else if (phydm_rf_type == PHYDM_RF_2T2R || + phydm_rf_type == PHYDM_RF_2T4R || + phydm_rf_type == PHYDM_RF_2T3R) { + ratr_bitmap &= 0xfffff010; + } else { /*3T*/ + + ratr_bitmap &= 0xfffff010; + ratr_bitmap_msb &= 0x3ff; + } + + if (phydm_BW == + PHYDM_BW_20) { /* AC 20MHz doesn't support MCS9 */ + ratr_bitmap &= 0x7fdfffff; + ratr_bitmap_msb &= 0x1ff; + } + } break; + + default: + break; + } + + if (wireless_mode != PHYDM_WIRELESS_MODE_B) { + if (tx_rate_level == 0) + ratr_bitmap &= 0xffffffff; + else if (tx_rate_level == 1) + ratr_bitmap &= 0xfffffff0; + else if (tx_rate_level == 2) + ratr_bitmap &= 0xffffefe0; + else if (tx_rate_level == 3) + ratr_bitmap &= 0xffffcfc0; + else if (tx_rate_level == 4) + ratr_bitmap &= 0xffff8f80; + else if (tx_rate_level >= 5) + ratr_bitmap &= 0xffff0f00; + } + + if (disable_cck_rate) + ratr_bitmap &= 0xfffffff0; + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "wireless_mode= (( 0x%x )), rf_type = (( 0x%x )), BW = (( 0x%x )), MimoPs_en = (( %d )), tx_rate_level= (( 0x%x ))\n", + wireless_mode, phydm_rf_type, phydm_BW, mimo_ps_enable, + tx_rate_level); + + *ratr_bitmap_lsb_in = ratr_bitmap; + *ratr_bitmap_msb_in = ratr_bitmap_msb; + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Phydm modified RA Mask = (( 0x %x | %x ))\n", + *ratr_bitmap_msb_in, *ratr_bitmap_lsb_in); +} + +u8 phydm_RA_level_decision(void *dm_void, u32 rssi, u8 ratr_state) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 ra_rate_floor_table[RA_FLOOR_TABLE_SIZE] = { + 20, 34, 38, 42, + 46, 50, 100}; /*MCS0 ~ MCS4 , VHT1SS MCS0 ~ MCS4 , G 6M~24M*/ + u8 new_ratr_state = 0; + u8 i; + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "curr RA level = ((%d)), Rate_floor_table ori [ %d , %d, %d , %d, %d, %d]\n", + ratr_state, ra_rate_floor_table[0], ra_rate_floor_table[1], + ra_rate_floor_table[2], ra_rate_floor_table[3], + ra_rate_floor_table[4], ra_rate_floor_table[5]); + + for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { + if (i >= (ratr_state)) + ra_rate_floor_table[i] += RA_FLOOR_UP_GAP; + } + + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "RSSI = ((%d)), Rate_floor_table_mod [ %d , %d, %d , %d, %d, %d]\n", + rssi, ra_rate_floor_table[0], ra_rate_floor_table[1], + ra_rate_floor_table[2], ra_rate_floor_table[3], + ra_rate_floor_table[4], ra_rate_floor_table[5]); + + for (i = 0; i < RA_FLOOR_TABLE_SIZE; i++) { + if (rssi < ra_rate_floor_table[i]) { + new_ratr_state = i; + break; + } + } + + return new_ratr_state; +} + +void odm_refresh_rate_adaptive_mask_mp(void *dm_void) {} + +void odm_refresh_rate_adaptive_mask_ce(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + void *adapter = dm->adapter; + u32 i; + struct rtl_sta_info *entry; + u8 ratr_state_new; + + if (!dm->is_use_ra_mask) { + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "<---- %s(): driver does not control rate adaptive mask\n", + __func__); + return; + } + + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) { + entry = dm->odm_sta_info[i]; + + if (!IS_STA_VALID(entry)) + continue; + + if (is_multicast_ether_addr(entry->mac_addr)) + continue; + else if (is_broadcast_ether_addr(entry->mac_addr)) + continue; + + ratr_state_new = phydm_RA_level_decision( + dm, entry->rssi_stat.undecorated_smoothed_pwdb, + entry->rssi_level); + + if ((entry->rssi_level != ratr_state_new) || + (ra_tab->force_update_ra_mask_count >= + FORCED_UPDATE_RAMASK_PERIOD)) { + ra_tab->force_update_ra_mask_count = 0; + ODM_RT_TRACE( + dm, ODM_COMP_RA_MASK, + "Update Tx RA Level: ((%x)) -> ((%x)), RSSI = ((%d))\n", + entry->rssi_level, ratr_state_new, + entry->rssi_stat.undecorated_smoothed_pwdb); + + entry->rssi_level = ratr_state_new; + rtl_hal_update_ra_mask(adapter, entry, + entry->rssi_level); + } else { + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "Stay in RA level = (( %d ))\n\n", + ratr_state_new); + /**/ + } + } +} + +void odm_refresh_rate_adaptive_mask_apadsl(void *dm_void) {} + +void odm_refresh_basic_rate_mask(void *dm_void) {} + +u8 phydm_rate_order_compute(void *dm_void, u8 rate_idx) +{ + u8 rate_order = 0; + + if (rate_idx >= ODM_RATEVHTSS4MCS0) { + rate_idx -= ODM_RATEVHTSS4MCS0; + /**/ + } else if (rate_idx >= ODM_RATEVHTSS3MCS0) { + rate_idx -= ODM_RATEVHTSS3MCS0; + /**/ + } else if (rate_idx >= ODM_RATEVHTSS2MCS0) { + rate_idx -= ODM_RATEVHTSS2MCS0; + /**/ + } else if (rate_idx >= ODM_RATEVHTSS1MCS0) { + rate_idx -= ODM_RATEVHTSS1MCS0; + /**/ + } else if (rate_idx >= ODM_RATEMCS24) { + rate_idx -= ODM_RATEMCS24; + /**/ + } else if (rate_idx >= ODM_RATEMCS16) { + rate_idx -= ODM_RATEMCS16; + /**/ + } else if (rate_idx >= ODM_RATEMCS8) { + rate_idx -= ODM_RATEMCS8; + /**/ + } + rate_order = rate_idx; + + return rate_order; +} + +static void phydm_ra_common_info_update(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + u16 macid; + u8 rate_order_tmp; + u8 cnt = 0; + + ra_tab->highest_client_tx_order = 0; + ra_tab->power_tracking_flag = 1; + + if (dm->number_linked_client != 0) { + for (macid = 0; macid < ODM_ASSOCIATE_ENTRY_NUM; macid++) { + rate_order_tmp = phydm_rate_order_compute( + dm, ((ra_tab->link_tx_rate[macid]) & 0x7f)); + + if (rate_order_tmp >= + (ra_tab->highest_client_tx_order)) { + ra_tab->highest_client_tx_order = + rate_order_tmp; + ra_tab->highest_client_tx_rate_order = macid; + } + + cnt++; + + if (cnt == dm->number_linked_client) + break; + } + ODM_RT_TRACE( + dm, ODM_COMP_RATE_ADAPTIVE, + "MACID[%d], Highest Tx order Update for power traking: %d\n", + (ra_tab->highest_client_tx_rate_order), + (ra_tab->highest_client_tx_order)); + } +} + +void phydm_ra_info_watchdog(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + phydm_ra_common_info_update(dm); + phydm_ra_dynamic_retry_limit(dm); + phydm_ra_dynamic_retry_count(dm); + odm_refresh_rate_adaptive_mask(dm); + odm_refresh_basic_rate_mask(dm); +} + +void phydm_ra_info_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct ra_table *ra_tab = &dm->dm_ra_table; + + ra_tab->highest_client_tx_rate_order = 0; + ra_tab->highest_client_tx_order = 0; + ra_tab->RA_threshold_offset = 0; + ra_tab->RA_offset_direction = 0; +} + +u8 odm_find_rts_rate(void *dm_void, u8 tx_rate, bool is_erp_protect) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + u8 rts_ini_rate = ODM_RATE6M; + + if (is_erp_protect) { /* use CCK rate as RTS*/ + rts_ini_rate = ODM_RATE1M; + } else { + switch (tx_rate) { + case ODM_RATEVHTSS3MCS9: + case ODM_RATEVHTSS3MCS8: + case ODM_RATEVHTSS3MCS7: + case ODM_RATEVHTSS3MCS6: + case ODM_RATEVHTSS3MCS5: + case ODM_RATEVHTSS3MCS4: + case ODM_RATEVHTSS3MCS3: + case ODM_RATEVHTSS2MCS9: + case ODM_RATEVHTSS2MCS8: + case ODM_RATEVHTSS2MCS7: + case ODM_RATEVHTSS2MCS6: + case ODM_RATEVHTSS2MCS5: + case ODM_RATEVHTSS2MCS4: + case ODM_RATEVHTSS2MCS3: + case ODM_RATEVHTSS1MCS9: + case ODM_RATEVHTSS1MCS8: + case ODM_RATEVHTSS1MCS7: + case ODM_RATEVHTSS1MCS6: + case ODM_RATEVHTSS1MCS5: + case ODM_RATEVHTSS1MCS4: + case ODM_RATEVHTSS1MCS3: + case ODM_RATEMCS15: + case ODM_RATEMCS14: + case ODM_RATEMCS13: + case ODM_RATEMCS12: + case ODM_RATEMCS11: + case ODM_RATEMCS7: + case ODM_RATEMCS6: + case ODM_RATEMCS5: + case ODM_RATEMCS4: + case ODM_RATEMCS3: + case ODM_RATE54M: + case ODM_RATE48M: + case ODM_RATE36M: + case ODM_RATE24M: + rts_ini_rate = ODM_RATE24M; + break; + case ODM_RATEVHTSS3MCS2: + case ODM_RATEVHTSS3MCS1: + case ODM_RATEVHTSS2MCS2: + case ODM_RATEVHTSS2MCS1: + case ODM_RATEVHTSS1MCS2: + case ODM_RATEVHTSS1MCS1: + case ODM_RATEMCS10: + case ODM_RATEMCS9: + case ODM_RATEMCS2: + case ODM_RATEMCS1: + case ODM_RATE18M: + case ODM_RATE12M: + rts_ini_rate = ODM_RATE12M; + break; + case ODM_RATEVHTSS3MCS0: + case ODM_RATEVHTSS2MCS0: + case ODM_RATEVHTSS1MCS0: + case ODM_RATEMCS8: + case ODM_RATEMCS0: + case ODM_RATE9M: + case ODM_RATE6M: + rts_ini_rate = ODM_RATE6M; + break; + case ODM_RATE11M: + case ODM_RATE5_5M: + case ODM_RATE2M: + case ODM_RATE1M: + rts_ini_rate = ODM_RATE1M; + break; + default: + rts_ini_rate = ODM_RATE6M; + break; + } + } + + if (*dm->band_type == 1) { + if (rts_ini_rate < ODM_RATE6M) + rts_ini_rate = ODM_RATE6M; + } + return rts_ini_rate; +} + +static void odm_set_ra_dm_arfb_by_noisy(struct phy_dm_struct *dm) {} + +void odm_update_noisy_state(void *dm_void, bool is_noisy_state_from_c2h) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + /* JJ ADD 20161014 */ + if (dm->support_ic_type == ODM_RTL8821 || + dm->support_ic_type == ODM_RTL8812 || + dm->support_ic_type == ODM_RTL8723B || + dm->support_ic_type == ODM_RTL8192E || + dm->support_ic_type == ODM_RTL8188E || + dm->support_ic_type == ODM_RTL8723D || + dm->support_ic_type == ODM_RTL8710B) + dm->is_noisy_state = is_noisy_state_from_c2h; + odm_set_ra_dm_arfb_by_noisy(dm); +}; + +void phydm_update_pwr_track(void *dm_void, u8 rate) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "Pwr Track Get rate=0x%x\n", + rate); + + dm->tx_rate = rate; +} + +/* RA_MASK_PHYDMLIZE, will delete it later*/ + +bool odm_ra_state_check(void *dm_void, s32 rssi, bool is_force_update, + u8 *ra_tr_state) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct odm_rate_adaptive *ra = &dm->rate_adaptive; + const u8 go_up_gap = 5; + u8 high_rssi_thresh_for_ra = ra->high_rssi_thresh; + u8 low_rssi_thresh_for_ra = ra->low_rssi_thresh; + u8 ratr_state; + + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "RSSI= (( %d )), Current_RSSI_level = (( %d ))\n", rssi, + *ra_tr_state); + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "[Ori RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", + high_rssi_thresh_for_ra, low_rssi_thresh_for_ra); + /* threshold Adjustment: + * when RSSI state trends to go up one or two levels, make sure RSSI is + * high enough. Here go_up_gap is added to solve the boundary's level + * alternation issue. + */ + + switch (*ra_tr_state) { + case DM_RATR_STA_INIT: + case DM_RATR_STA_HIGH: + break; + + case DM_RATR_STA_MIDDLE: + high_rssi_thresh_for_ra += go_up_gap; + break; + + case DM_RATR_STA_LOW: + high_rssi_thresh_for_ra += go_up_gap; + low_rssi_thresh_for_ra += go_up_gap; + break; + + default: + WARN_ONCE(true, "wrong rssi level setting %d !", *ra_tr_state); + break; + } + + /* Decide ratr_state by RSSI.*/ + if (rssi > high_rssi_thresh_for_ra) + ratr_state = DM_RATR_STA_HIGH; + else if (rssi > low_rssi_thresh_for_ra) + ratr_state = DM_RATR_STA_MIDDLE; + + else + ratr_state = DM_RATR_STA_LOW; + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "[Mod RA RSSI Thresh] High= (( %d )), Low = (( %d ))\n", + high_rssi_thresh_for_ra, low_rssi_thresh_for_ra); + + if (*ra_tr_state != ratr_state || is_force_update) { + ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, + "[RSSI Level Update] %d->%d\n", *ra_tr_state, + ratr_state); + *ra_tr_state = ratr_state; + return true; + } + + return false; +} diff --git a/drivers/staging/rtlwifi/phydm/phydm_rainfo.h b/drivers/staging/rtlwifi/phydm/phydm_rainfo.h new file mode 100644 index 000000000000..c14ed9bda0af --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_rainfo.h @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __PHYDMRAINFO_H__ +#define __PHYDMRAINFO_H__ + +/*#define RAINFO_VERSION "2.0"*/ /*2014.11.04*/ +/*#define RAINFO_VERSION "3.0"*/ /*2015.01.13 Dino*/ +/*#define RAINFO_VERSION "3.1"*/ /*2015.01.14 Dino*/ +/*#define RAINFO_VERSION "3.3"*/ /*2015.07.29 YuChen*/ +/*#define RAINFO_VERSION "3.4"*/ /*2015.12.15 Stanley*/ +/*#define RAINFO_VERSION "4.0"*/ /*2016.03.24 Dino, Add more RA mask + *state and Phydm-lize partial ra mask + *function + */ +/*#define RAINFO_VERSION "4.1"*/ /*2016.04.20 Dino, Add new function to + *adjust PCR RA threshold + */ +/*#define RAINFO_VERSION "4.2"*/ /*2016.05.17 Dino, Add H2C debug cmd */ +#define RAINFO_VERSION "4.3" /*2016.07.11 Dino, Fix RA hang in CCK 1M problem*/ + +#define FORCED_UPDATE_RAMASK_PERIOD 5 + +#define H2C_0X42_LENGTH 5 +#define H2C_MAX_LENGTH 7 + +#define RA_FLOOR_UP_GAP 3 +#define RA_FLOOR_TABLE_SIZE 7 + +#define ACTIVE_TP_THRESHOLD 150 +#define RA_RETRY_DESCEND_NUM 2 +#define RA_RETRY_LIMIT_LOW 4 +#define RA_RETRY_LIMIT_HIGH 32 + +#define RAINFO_BE_RX_STATE BIT(0) /* 1:RX */ /* ULDL */ +#define RAINFO_STBC_STATE BIT(1) +/* #define RAINFO_LDPC_STATE BIT2 */ +#define RAINFO_NOISY_STATE BIT(2) /* set by Noisy_Detection */ +#define RAINFO_SHURTCUT_STATE BIT(3) +#define RAINFO_SHURTCUT_FLAG BIT(4) +#define RAINFO_INIT_RSSI_RATE_STATE BIT(5) +#define RAINFO_BF_STATE BIT(6) +#define RAINFO_BE_TX_STATE BIT(7) /* 1:TX */ + +#define RA_MASK_CCK 0xf +#define RA_MASK_OFDM 0xff0 +#define RA_MASK_HT1SS 0xff000 +#define RA_MASK_HT2SS 0xff00000 +/*#define RA_MASK_MCS3SS */ +#define RA_MASK_HT4SS 0xff0 +#define RA_MASK_VHT1SS 0x3ff000 +#define RA_MASK_VHT2SS 0xffc00000 + +#define RA_FIRST_MACID 0 + +#define ap_init_rate_adaptive_state odm_rate_adaptive_state_ap_init + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 +#define DM_RATR_STA_ULTRA_LOW 4 + +enum phydm_ra_arfr_num { + ARFR_0_RATE_ID = 0x9, + ARFR_1_RATE_ID = 0xa, + ARFR_2_RATE_ID = 0xb, + ARFR_3_RATE_ID = 0xc, + ARFR_4_RATE_ID = 0xd, + ARFR_5_RATE_ID = 0xe +}; + +enum phydm_ra_dbg_para { + RADBG_PCR_TH_OFFSET = 0, + RADBG_RTY_PENALTY = 1, + RADBG_N_HIGH = 2, + RADBG_N_LOW = 3, + RADBG_TRATE_UP_TABLE = 4, + RADBG_TRATE_DOWN_TABLE = 5, + RADBG_TRYING_NECESSARY = 6, + RADBG_TDROPING_NECESSARY = 7, + RADBG_RATE_UP_RTY_RATIO = 8, + RADBG_RATE_DOWN_RTY_RATIO = 9, /* u8 */ + + RADBG_DEBUG_MONITOR1 = 0xc, + RADBG_DEBUG_MONITOR2 = 0xd, + RADBG_DEBUG_MONITOR3 = 0xe, + RADBG_DEBUG_MONITOR4 = 0xf, + RADBG_DEBUG_MONITOR5 = 0x10, + NUM_RA_PARA +}; + +enum phydm_wireless_mode { + PHYDM_WIRELESS_MODE_UNKNOWN = 0x00, + PHYDM_WIRELESS_MODE_A = 0x01, + PHYDM_WIRELESS_MODE_B = 0x02, + PHYDM_WIRELESS_MODE_G = 0x04, + PHYDM_WIRELESS_MODE_AUTO = 0x08, + PHYDM_WIRELESS_MODE_N_24G = 0x10, + PHYDM_WIRELESS_MODE_N_5G = 0x20, + PHYDM_WIRELESS_MODE_AC_5G = 0x40, + PHYDM_WIRELESS_MODE_AC_24G = 0x80, + PHYDM_WIRELESS_MODE_AC_ONLY = 0x100, + PHYDM_WIRELESS_MODE_MAX = 0x800, + PHYDM_WIRELESS_MODE_ALL = 0xFFFF +}; + +enum phydm_rateid_idx { + PHYDM_BGN_40M_2SS = 0, + PHYDM_BGN_40M_1SS = 1, + PHYDM_BGN_20M_2SS = 2, + PHYDM_BGN_20M_1SS = 3, + PHYDM_GN_N2SS = 4, + PHYDM_GN_N1SS = 5, + PHYDM_BG = 6, + PHYDM_G = 7, + PHYDM_B_20M = 8, + PHYDM_ARFR0_AC_2SS = 9, + PHYDM_ARFR1_AC_1SS = 10, + PHYDM_ARFR2_AC_2G_1SS = 11, + PHYDM_ARFR3_AC_2G_2SS = 12, + PHYDM_ARFR4_AC_3SS = 13, + PHYDM_ARFR5_N_3SS = 14 +}; + +enum phydm_rf_type_def { + PHYDM_RF_1T1R = 0, + PHYDM_RF_1T2R, + PHYDM_RF_2T2R, + PHYDM_RF_2T2R_GREEN, + PHYDM_RF_2T3R, + PHYDM_RF_2T4R, + PHYDM_RF_3T3R, + PHYDM_RF_3T4R, + PHYDM_RF_4T4R, + PHYDM_RF_MAX_TYPE +}; + +enum phydm_bw { + PHYDM_BW_20 = 0, + PHYDM_BW_40, + PHYDM_BW_80, + PHYDM_BW_80_80, + PHYDM_BW_160, + PHYDM_BW_10, + PHYDM_BW_5 +}; + +struct ra_table { + u8 firstconnect; + + u8 link_tx_rate[ODM_ASSOCIATE_ENTRY_NUM]; + u8 highest_client_tx_order; + u16 highest_client_tx_rate_order; + u8 power_tracking_flag; + u8 RA_threshold_offset; + u8 RA_offset_direction; + u8 force_update_ra_mask_count; +}; + +struct odm_rate_adaptive { + /* dm_type_by_fw/dm_type_by_driver */ + u8 type; + /* if RSSI > high_rssi_thresh => ratr_state is DM_RATR_STA_HIGH */ + u8 high_rssi_thresh; + /* if RSSI <= low_rssi_thresh => ratr_state is DM_RATR_STA_LOW */ + u8 low_rssi_thresh; + /* Cur RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW*/ + u8 ratr_state; + + /* if RSSI > ldpc_thres => switch from LPDC to BCC */ + u8 ldpc_thres; + bool is_lower_rts_rate; + + bool is_use_ldpc; +}; + +void phydm_h2C_debug(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len); + +void phydm_RA_debug_PCR(void *dm_void, u32 *const dm_value, u32 *_used, + char *output, u32 *_out_len); + +void odm_c2h_ra_para_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +void odm_ra_para_adjust(void *dm_void); + +void phydm_ra_dynamic_retry_count(void *dm_void); + +void phydm_ra_dynamic_retry_limit(void *dm_void); + +void phydm_ra_dynamic_rate_id_on_assoc(void *dm_void, u8 wireless_mode, + u8 init_rate_id); + +void phydm_print_rate(void *dm_void, u8 rate, u32 dbg_component); + +void phydm_c2h_ra_report_handler(void *dm_void, u8 *cmd_buf, u8 cmd_len); + +u8 phydm_rate_order_compute(void *dm_void, u8 rate_idx); + +void phydm_ra_info_watchdog(void *dm_void); + +void phydm_ra_info_init(void *dm_void); + +void odm_rssi_monitor_init(void *dm_void); + +void phydm_modify_RA_PCR_threshold(void *dm_void, u8 RA_offset_direction, + u8 RA_threshold_offset); + +void odm_rssi_monitor_check(void *dm_void); + +void phydm_init_ra_info(void *dm_void); + +u8 phydm_vht_en_mapping(void *dm_void, u32 wireless_mode); + +u8 phydm_rate_id_mapping(void *dm_void, u32 wireless_mode, u8 rf_type, u8 bw); + +void phydm_update_hal_ra_mask(void *dm_void, u32 wireless_mode, u8 rf_type, + u8 BW, u8 mimo_ps_enable, u8 disable_cck_rate, + u32 *ratr_bitmap_msb_in, u32 *ratr_bitmap_in, + u8 tx_rate_level); + +void odm_rate_adaptive_mask_init(void *dm_void); + +void odm_refresh_rate_adaptive_mask(void *dm_void); + +void odm_refresh_rate_adaptive_mask_mp(void *dm_void); + +void odm_refresh_rate_adaptive_mask_ce(void *dm_void); + +void odm_refresh_rate_adaptive_mask_apadsl(void *dm_void); + +u8 phydm_RA_level_decision(void *dm_void, u32 rssi, u8 ratr_state); + +bool odm_ra_state_check(void *dm_void, s32 RSSI, bool is_force_update, + u8 *ra_tr_state); + +void odm_refresh_basic_rate_mask(void *dm_void); +void odm_ra_post_action_on_assoc(void *dm); + +u8 odm_find_rts_rate(void *dm_void, u8 tx_rate, bool is_erp_protect); + +void odm_update_noisy_state(void *dm_void, bool is_noisy_state_from_c2h); + +void phydm_update_pwr_track(void *dm_void, u8 rate); + +#endif /*#ifndef __ODMRAINFO_H__*/ diff --git a/drivers/staging/rtlwifi/phydm/phydm_reg.h b/drivers/staging/rtlwifi/phydm/phydm_reg.h new file mode 100644 index 000000000000..d9d878e4c925 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_reg.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +/* ************************************************************ + * File Name: odm_reg.h + * + * Description: + * + * This file is for general register definition. + * + * + * *************************************************************/ +#ifndef __HAL_ODM_REG_H__ +#define __HAL_ODM_REG_H__ + +/* + * Register Definition + */ + +/* MAC REG */ +#define ODM_BB_RESET 0x002 +#define ODM_DUMMY 0x4fe +#define RF_T_METER_OLD 0x24 +#define RF_T_METER_NEW 0x42 + +#define ODM_EDCA_VO_PARAM 0x500 +#define ODM_EDCA_VI_PARAM 0x504 +#define ODM_EDCA_BE_PARAM 0x508 +#define ODM_EDCA_BK_PARAM 0x50C +#define ODM_TXPAUSE 0x522 + +/* LTE_COEX */ +#define REG_LTECOEX_CTRL 0x07C0 +#define REG_LTECOEX_WRITE_DATA 0x07C4 +#define REG_LTECOEX_READ_DATA 0x07C8 +#define REG_LTECOEX_PATH_CONTROL 0x70 + +/* BB REG */ +#define ODM_FPGA_PHY0_PAGE8 0x800 +#define ODM_PSD_SETTING 0x808 +#define ODM_AFE_SETTING 0x818 +#define ODM_TXAGC_B_6_18 0x830 +#define ODM_TXAGC_B_24_54 0x834 +#define ODM_TXAGC_B_MCS32_5 0x838 +#define ODM_TXAGC_B_MCS0_MCS3 0x83c +#define ODM_TXAGC_B_MCS4_MCS7 0x848 +#define ODM_TXAGC_B_MCS8_MCS11 0x84c +#define ODM_ANALOG_REGISTER 0x85c +#define ODM_RF_INTERFACE_OUTPUT 0x860 +#define ODM_TXAGC_B_MCS12_MCS15 0x868 +#define ODM_TXAGC_B_11_A_2_11 0x86c +#define ODM_AD_DA_LSB_MASK 0x874 +#define ODM_ENABLE_3_WIRE 0x88c +#define ODM_PSD_REPORT 0x8b4 +#define ODM_R_ANT_SELECT 0x90c +#define ODM_CCK_ANT_SELECT 0xa07 +#define ODM_CCK_PD_THRESH 0xa0a +#define ODM_CCK_RF_REG1 0xa11 +#define ODM_CCK_MATCH_FILTER 0xa20 +#define ODM_CCK_RAKE_MAC 0xa2e +#define ODM_CCK_CNT_RESET 0xa2d +#define ODM_CCK_TX_DIVERSITY 0xa2f +#define ODM_CCK_FA_CNT_MSB 0xa5b +#define ODM_CCK_FA_CNT_LSB 0xa5c +#define ODM_CCK_NEW_FUNCTION 0xa75 +#define ODM_OFDM_PHY0_PAGE_C 0xc00 +#define ODM_OFDM_RX_ANT 0xc04 +#define ODM_R_A_RXIQI 0xc14 +#define ODM_R_A_AGC_CORE1 0xc50 +#define ODM_R_A_AGC_CORE2 0xc54 +#define ODM_R_B_AGC_CORE1 0xc58 +#define ODM_R_AGC_PAR 0xc70 +#define ODM_R_HTSTF_AGC_PAR 0xc7c +#define ODM_TX_PWR_TRAINING_A 0xc90 +#define ODM_TX_PWR_TRAINING_B 0xc98 +#define ODM_OFDM_FA_CNT1 0xcf0 +#define ODM_OFDM_PHY0_PAGE_D 0xd00 +#define ODM_OFDM_FA_CNT2 0xda0 +#define ODM_OFDM_FA_CNT3 0xda4 +#define ODM_OFDM_FA_CNT4 0xda8 +#define ODM_TXAGC_A_6_18 0xe00 +#define ODM_TXAGC_A_24_54 0xe04 +#define ODM_TXAGC_A_1_MCS32 0xe08 +#define ODM_TXAGC_A_MCS0_MCS3 0xe10 +#define ODM_TXAGC_A_MCS4_MCS7 0xe14 +#define ODM_TXAGC_A_MCS8_MCS11 0xe18 +#define ODM_TXAGC_A_MCS12_MCS15 0xe1c + +/* RF REG */ +#define ODM_GAIN_SETTING 0x00 +#define ODM_CHANNEL 0x18 +#define ODM_RF_T_METER 0x24 +#define ODM_RF_T_METER_92D 0x42 +#define ODM_RF_T_METER_88E 0x42 +#define ODM_RF_T_METER_92E 0x42 +#define ODM_RF_T_METER_8812 0x42 +#define REG_RF_TX_GAIN_OFFSET 0x55 + +/* ant Detect Reg */ +#define ODM_DPDT 0x300 + +/* PSD Init */ +#define ODM_PSDREG 0x808 + +/* 92D path Div */ +#define PATHDIV_REG 0xB30 +#define PATHDIV_TRI 0xBA0 + +/* + * Bitmap Definition + */ + +#define BIT_FA_RESET BIT(0) + +#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0xC80 +#define REG_OFDM_0_ECCA_THRESHOLD 0xC4C +#define REG_FPGA0_XB_LSSI_READ_BACK 0x8A4 +#define REG_FPGA0_TX_GAIN_STAGE 0x80C +#define REG_OFDM_0_XA_AGC_CORE1 0xC50 +#define REG_OFDM_0_XB_AGC_CORE1 0xC58 +#define REG_A_TX_SCALE_JAGUAR 0xC1C +#define REG_B_TX_SCALE_JAGUAR 0xE1C + +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_MAC_PHY_CTRL 0x002C + +#define RF_CHNLBW 0x18 + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h b/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h new file mode 100644 index 000000000000..28d48415ac99 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_regdefine11ac.h @@ -0,0 +1,94 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_REGDEFINE11AC_H__ +#define __ODM_REGDEFINE11AC_H__ + +/* 2 RF REG LIST */ + +/* 2 BB REG LIST */ +/* PAGE 8 */ +#define ODM_REG_CCK_RPT_FORMAT_11AC 0x804 +#define ODM_REG_BB_RX_PATH_11AC 0x808 +#define ODM_REG_BB_TX_PATH_11AC 0x80c +#define ODM_REG_BB_ATC_11AC 0x860 +#define ODM_REG_EDCCA_POWER_CAL 0x8dc +#define ODM_REG_DBG_RPT_11AC 0x8fc +/* PAGE 9 */ +#define ODM_REG_EDCCA_DOWN_OPT 0x900 +#define ODM_REG_ACBB_EDCCA_ENHANCE 0x944 +#define odm_adc_trigger_jaguar2 0x95C /*ADC sample mode*/ +#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 +#define ODM_REG_CCX_PERIOD_11AC 0x990 +#define ODM_REG_NHM_TH9_TH10_11AC 0x994 +#define ODM_REG_CLM_11AC 0x994 +#define ODM_REG_NHM_TH3_TO_TH0_11AC 0x998 +#define ODM_REG_NHM_TH7_TO_TH4_11AC 0x99c +#define ODM_REG_NHM_TH8_11AC 0x9a0 +#define ODM_REG_NHM_9E8_11AC 0x9e8 +#define ODM_REG_CSI_CONTENT_VALUE 0x9b4 +/* PAGE A */ +#define ODM_REG_CCK_CCA_11AC 0xA0A +#define ODM_REG_CCK_FA_RST_11AC 0xA2C +#define ODM_REG_CCK_FA_11AC 0xA5C +/* PAGE B */ +#define ODM_REG_RST_RPT_11AC 0xB58 +/* PAGE C */ +#define ODM_REG_TRMUX_11AC 0xC08 +#define ODM_REG_IGI_A_11AC 0xC50 +/* PAGE E */ +#define ODM_REG_IGI_B_11AC 0xE50 +#define ODM_REG_TRMUX_11AC_B 0xE08 +/* PAGE F */ +#define ODM_REG_CCK_CRC32_CNT_11AC 0xF04 +#define ODM_REG_CCK_CCA_CNT_11AC 0xF08 +#define ODM_REG_VHT_CRC32_CNT_11AC 0xF0c +#define ODM_REG_HT_CRC32_CNT_11AC 0xF10 +#define ODM_REG_OFDM_CRC32_CNT_11AC 0xF14 +#define ODM_REG_OFDM_FA_11AC 0xF48 +#define ODM_REG_RPT_11AC 0xfa0 +#define ODM_REG_CLM_RESULT_11AC 0xfa4 +#define ODM_REG_NHM_CNT_11AC 0xfa8 +#define ODM_REG_NHM_DUR_READY_11AC 0xfb4 + +#define ODM_REG_NHM_CNT7_TO_CNT4_11AC 0xfac +#define ODM_REG_NHM_CNT11_TO_CNT8_11AC 0xfb0 +#define ODM_REG_OFDM_FA_TYPE2_11AC 0xFD0 +/* PAGE 18 */ +#define ODM_REG_IGI_C_11AC 0x1850 +/* PAGE 1A */ +#define ODM_REG_IGI_D_11AC 0x1A50 + +/* 2 MAC REG LIST */ +#define ODM_REG_RESP_TX_11AC 0x6D8 + +/* DIG Related */ +#define ODM_BIT_IGI_11AC 0xFFFFFFFF +#define ODM_BIT_CCK_RPT_FORMAT_11AC BIT(16) +#define ODM_BIT_BB_RX_PATH_11AC 0xF +#define ODM_BIT_BB_TX_PATH_11AC 0xF +#define ODM_BIT_BB_ATC_11AC BIT(14) + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h b/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h new file mode 100644 index 000000000000..0b6581c50ab3 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_regdefine11n.h @@ -0,0 +1,213 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __ODM_REGDEFINE11N_H__ +#define __ODM_REGDEFINE11N_H__ + +/* 2 RF REG LIST */ +#define ODM_REG_RF_MODE_11N 0x00 +#define ODM_REG_RF_0B_11N 0x0B +#define ODM_REG_CHNBW_11N 0x18 +#define ODM_REG_T_METER_11N 0x24 +#define ODM_REG_RF_25_11N 0x25 +#define ODM_REG_RF_26_11N 0x26 +#define ODM_REG_RF_27_11N 0x27 +#define ODM_REG_RF_2B_11N 0x2B +#define ODM_REG_RF_2C_11N 0x2C +#define ODM_REG_RXRF_A3_11N 0x3C +#define ODM_REG_T_METER_92D_11N 0x42 +#define ODM_REG_T_METER_88E_11N 0x42 + +/* 2 BB REG LIST */ +/* PAGE 8 */ +#define ODM_REG_BB_CTRL_11N 0x800 +#define ODM_REG_RF_PIN_11N 0x804 +#define ODM_REG_PSD_CTRL_11N 0x808 +#define ODM_REG_TX_ANT_CTRL_11N 0x80C +#define ODM_REG_BB_PWR_SAV5_11N 0x818 +#define ODM_REG_CCK_RPT_FORMAT_11N 0x824 +#define ODM_REG_CCK_RPT_FORMAT_11N_B 0x82C +#define ODM_REG_RX_DEFAULT_A_11N 0x858 +#define ODM_REG_RX_DEFAULT_B_11N 0x85A +#define ODM_REG_BB_PWR_SAV3_11N 0x85C +#define ODM_REG_ANTSEL_CTRL_11N 0x860 +#define ODM_REG_RX_ANT_CTRL_11N 0x864 +#define ODM_REG_PIN_CTRL_11N 0x870 +#define ODM_REG_BB_PWR_SAV1_11N 0x874 +#define ODM_REG_ANTSEL_PATH_11N 0x878 +#define ODM_REG_BB_3WIRE_11N 0x88C +#define ODM_REG_SC_CNT_11N 0x8C4 +#define ODM_REG_PSD_DATA_11N 0x8B4 +#define ODM_REG_CCX_PERIOD_11N 0x894 +#define ODM_REG_NHM_TH9_TH10_11N 0x890 +#define ODM_REG_CLM_11N 0x890 +#define ODM_REG_NHM_TH3_TO_TH0_11N 0x898 +#define ODM_REG_NHM_TH7_TO_TH4_11N 0x89c +#define ODM_REG_NHM_TH8_11N 0xe28 +#define ODM_REG_CLM_READY_11N 0x8b4 +#define ODM_REG_CLM_RESULT_11N 0x8d0 +#define ODM_REG_NHM_CNT_11N 0x8d8 + +/* For struct acs_info, Jeffery, 2014-12-26 */ +#define ODM_REG_NHM_CNT7_TO_CNT4_11N 0x8dc +#define ODM_REG_NHM_CNT9_TO_CNT8_11N 0x8d0 +#define ODM_REG_NHM_CNT10_TO_CNT11_11N 0x8d4 + +/* PAGE 9 */ +#define ODM_REG_BB_CTRL_PAGE9_11N 0x900 +#define ODM_REG_DBG_RPT_11N 0x908 +#define ODM_REG_BB_TX_PATH_11N 0x90c +#define ODM_REG_ANT_MAPPING1_11N 0x914 +#define ODM_REG_ANT_MAPPING2_11N 0x918 +#define ODM_REG_EDCCA_DOWN_OPT_11N 0x948 +#define ODM_REG_RX_DFIR_MOD_97F 0x948 + +/* PAGE A */ +#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define ODM_REG_CCK_ANT_SEL_11N 0xA04 +#define ODM_REG_CCK_CCA_11N 0xA0A +#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define ODM_REG_CCK_FA_RST_11N 0xA2C +#define ODM_REG_CCK_FA_MSB_11N 0xA58 +#define ODM_REG_CCK_FA_LSB_11N 0xA5C +#define ODM_REG_CCK_CCA_CNT_11N 0xA60 +#define ODM_REG_BB_PWR_SAV4_11N 0xA74 +/* PAGE B */ +#define ODM_REG_LNA_SWITCH_11N 0xB2C +#define ODM_REG_PATH_SWITCH_11N 0xB30 +#define ODM_REG_RSSI_CTRL_11N 0xB38 +#define ODM_REG_CONFIG_ANTA_11N 0xB68 +#define ODM_REG_RSSI_BT_11N 0xB9C +#define ODM_REG_RXCK_RFMOD 0xBB0 +#define ODM_REG_EDCCA_DCNF_97F 0xBC0 + +/* PAGE C */ +#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define ODM_REG_BB_RX_PATH_11N 0xC04 +#define ODM_REG_TRMUX_11N 0xC08 +#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C +#define ODM_REG_DOWNSAM_FACTOR_11N 0xC10 +#define ODM_REG_RXIQI_MATRIX_11N 0xC14 +#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define ODM_REG_IGI_A_11N 0xC50 +#define ODM_REG_ANTDIV_PARA2_11N 0xC54 +#define ODM_REG_IGI_B_11N 0xC58 +#define ODM_REG_ANTDIV_PARA3_11N 0xC5C +#define ODM_REG_L1SBD_PD_CH_11N 0XC6C +#define ODM_REG_BB_PWR_SAV2_11N 0xC70 +#define ODM_REG_BB_AGC_SET_2_11N 0xc74 +#define ODM_REG_RX_OFF_11N 0xC7C +#define ODM_REG_TXIQK_MATRIXA_11N 0xC80 +#define ODM_REG_TXIQK_MATRIXB_11N 0xC88 +#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define ODM_REG_ANTDIV_PARA1_11N 0xCA4 +#define ODM_REG_SMALL_BANDWIDTH_11N 0xCE4 +#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0 +/* PAGE D */ +#define ODM_REG_OFDM_FA_RSTD_11N 0xD00 +#define ODM_REG_BB_RX_ANT_11N 0xD04 +#define ODM_REG_BB_ATC_11N 0xD2C +#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8 +#define ODM_REG_RPT_11N 0xDF4 +/* PAGE E */ +#define ODM_REG_TXAGC_A_6_18_11N 0xE00 +#define ODM_REG_TXAGC_A_24_54_11N 0xE04 +#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define ODM_REG_EDCCA_DCNF_11N 0xE24 +#define ODM_REG_TAP_UPD_97F 0xE24 +#define ODM_REG_FPGA0_IQK_11N 0xE28 +#define ODM_REG_PAGE_B1_97F 0xE28 +#define ODM_REG_TXIQK_TONE_A_11N 0xE30 +#define ODM_REG_RXIQK_TONE_A_11N 0xE34 +#define ODM_REG_TXIQK_PI_A_11N 0xE38 +#define ODM_REG_RXIQK_PI_A_11N 0xE3C +#define ODM_REG_TXIQK_11N 0xE40 +#define ODM_REG_RXIQK_11N 0xE44 +#define ODM_REG_IQK_AGC_PTS_11N 0xE48 +#define ODM_REG_IQK_AGC_RSP_11N 0xE4C +#define ODM_REG_BLUETOOTH_11N 0xE6C +#define ODM_REG_RX_WAIT_CCA_11N 0xE70 +#define ODM_REG_TX_CCK_RFON_11N 0xE74 +#define ODM_REG_TX_CCK_BBON_11N 0xE78 +#define ODM_REG_OFDM_RFON_11N 0xE7C +#define ODM_REG_OFDM_BBON_11N 0xE80 +#define ODM_REG_TX2RX_11N 0xE84 +#define ODM_REG_TX2TX_11N 0xE88 +#define ODM_REG_RX_CCK_11N 0xE8C +#define ODM_REG_RX_OFDM_11N 0xED0 +#define ODM_REG_RX_WAIT_RIFS_11N 0xED4 +#define ODM_REG_RX2RX_11N 0xED8 +#define ODM_REG_STANDBY_11N 0xEDC +#define ODM_REG_SLEEP_11N 0xEE0 +#define ODM_REG_PMPD_ANAEN_11N 0xEEC +/* PAGE F */ +#define ODM_REG_PAGE_F_RST_11N 0xF14 +#define ODM_REG_IGI_C_11N 0xF84 +#define ODM_REG_IGI_D_11N 0xF88 +#define ODM_REG_CCK_CRC32_ERROR_CNT_11N 0xF84 +#define ODM_REG_CCK_CRC32_OK_CNT_11N 0xF88 +#define ODM_REG_HT_CRC32_CNT_11N 0xF90 +#define ODM_REG_OFDM_CRC32_CNT_11N 0xF94 + +/* 2 MAC REG LIST */ +#define ODM_REG_BB_RST_11N 0x02 +#define ODM_REG_ANTSEL_PIN_11N 0x4C +#define ODM_REG_EARLY_MODE_11N 0x4D0 +#define ODM_REG_RSSI_MONITOR_11N 0x4FE +#define ODM_REG_EDCA_VO_11N 0x500 +#define ODM_REG_EDCA_VI_11N 0x504 +#define ODM_REG_EDCA_BE_11N 0x508 +#define ODM_REG_EDCA_BK_11N 0x50C +#define ODM_REG_TXPAUSE_11N 0x522 +#define ODM_REG_RESP_TX_11N 0x6D8 +#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + +/* DIG Related */ +#define ODM_BIT_IGI_11N 0x0000007F +#define ODM_BIT_CCK_RPT_FORMAT_11N BIT(9) +#define ODM_BIT_BB_RX_PATH_11N 0xF +#define ODM_BIT_BB_TX_PATH_11N 0xF +#define ODM_BIT_BB_ATC_11N BIT(11) + +#endif diff --git a/drivers/staging/rtlwifi/phydm/phydm_types.h b/drivers/staging/rtlwifi/phydm/phydm_types.h new file mode 100644 index 000000000000..a34ebe876528 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/phydm_types.h @@ -0,0 +1,130 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __ODM_TYPES_H__ +#define __ODM_TYPES_H__ + +/*Define Different SW team support*/ +#define ODM_AP 0x01 /*BIT0*/ +#define ODM_CE 0x04 /*BIT2*/ +#define ODM_WIN 0x08 /*BIT3*/ +#define ODM_ADSL 0x10 /*BIT4*/ +#define ODM_IOT 0x20 /*BIT5*/ + +/*Deifne HW endian support*/ +#define ODM_ENDIAN_BIG 0 +#define ODM_ENDIAN_LITTLE 1 + +#define GET_PDM_ODM(__padapter) \ + ((struct phy_dm_struct *)(&(GET_HAL_DATA(__padapter))->odmpriv)) + +enum hal_status { + HAL_STATUS_SUCCESS, + HAL_STATUS_FAILURE, +}; + +/* + * Declare for ODM spin lock definition temporarily fro compile pass. + */ +enum rt_spinlock_type { + RT_TX_SPINLOCK = 1, + RT_RX_SPINLOCK = 2, + RT_RM_SPINLOCK = 3, + RT_CAM_SPINLOCK = 4, + RT_SCAN_SPINLOCK = 5, + RT_LOG_SPINLOCK = 7, + RT_BW_SPINLOCK = 8, + RT_CHNLOP_SPINLOCK = 9, + RT_RF_OPERATE_SPINLOCK = 10, + RT_INITIAL_SPINLOCK = 11, + RT_RF_STATE_SPINLOCK = + 12, /* For RF state. Added by Bruce, 2007-10-30. */ + /* Shall we define Ndis 6.2 SpinLock Here ? */ + RT_PORT_SPINLOCK = 16, + RT_VNIC_SPINLOCK = 17, + RT_HVL_SPINLOCK = 18, + RT_H2C_SPINLOCK = 20, /* For H2C cmd. Added by tynli. 2009.11.09. */ + + rt_bt_data_spinlock = 25, + + RT_WAPI_OPTION_SPINLOCK = 26, + RT_WAPI_RX_SPINLOCK = 27, + + /* add for 92D CCK control issue */ + RT_CCK_PAGEA_SPINLOCK = 28, + RT_BUFFER_SPINLOCK = 29, + RT_CHANNEL_AND_BANDWIDTH_SPINLOCK = 30, + RT_GEN_TEMP_BUF_SPINLOCK = 31, + RT_AWB_SPINLOCK = 32, + RT_FW_PS_SPINLOCK = 33, + RT_HW_TIMER_SPIN_LOCK = 34, + RT_MPT_WI_SPINLOCK = 35, + RT_P2P_SPIN_LOCK = 36, /* Protect P2P context */ + RT_DBG_SPIN_LOCK = 37, + RT_IQK_SPINLOCK = 38, + RT_PENDED_OID_SPINLOCK = 39, + RT_CHNLLIST_SPINLOCK = 40, + RT_INDIC_SPINLOCK = 41, /* protect indication */ + RT_RFD_SPINLOCK = 42, + RT_SYNC_IO_CNT_SPINLOCK = 43, + RT_LAST_SPINLOCK, +}; + +#include + +#if defined(__LITTLE_ENDIAN) +#define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE +#elif defined(__BIG_ENDIAN) +#define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG +#else +#error +#endif + +#define COND_ELSE 2 +#define COND_ENDIF 3 + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK7BITS 0x7f +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASK20BITS 0xfffff +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f +#define RFREGOFFSETMASK 0xfffff +#define MASKH3BYTES 0xffffff00 +#define MASKL3BYTES 0x00ffffff +#define MASKBYTE2HIGHNIBBLE 0x00f00000 +#define MASKBYTE3LOWNIBBLE 0x0f000000 +#define MASKL3BYTES 0x00ffffff +#define RFREGOFFSETMASK 0xfffff + +#include "phydm_features.h" + +#endif /* __ODM_TYPES_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c new file mode 100644 index 000000000000..4e7946019fcb --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.c @@ -0,0 +1,1969 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool check_positive(struct phy_dm_struct *dm, const u32 condition1, + const u32 condition2, const u32 condition3, + const u32 condition4) +{ + u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/ + ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/ + ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/ + ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/ + + u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, + cond4 = condition4; + + u8 cut_version_for_para = + (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version; + u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type; + + u32 driver1 = cut_version_for_para << 24 | + (dm->support_interface & 0xF0) << 16 | + dm->support_platform << 16 | pkg_type_for_para << 12 | + (dm->support_interface & 0x0F) << 8 | _board_type; + + u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 | + (dm->type_alna & 0xFF) << 16 | + (dm->type_apa & 0xFF) << 24; + + u32 driver3 = 0; + + u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) | + (dm->type_alna & 0xFF00) << 8 | + (dm->type_apa & 0xFF00) << 16; + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, cond1, cond2, cond3, cond4); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, driver1, driver2, driver3, driver4); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Platform, Interface) = (0x%X, 0x%X)\n", + dm->support_platform, dm->support_interface); + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Board, Package) = (0x%X, 0x%X)\n", + dm->board_type, dm->package_type); + + /*============== value Defined Check ===============*/ + /*QFN type [15:12] and cut version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && + ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && + ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 bit_mask = 0; + + if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + bit_mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + bit_mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + bit_mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + bit_mask |= 0xFF000000; + + if (((cond2 & bit_mask) == (driver2 & bit_mask)) && + ((cond4 & bit_mask) == + (driver4 & + bit_mask))) /* board_type of each RF path is matched*/ + return true; + else + return false; + } else { + return false; + } +} + +/****************************************************************************** + * agc_tab.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_agc_tab[] = { + 0x8000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003, + 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003, + 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003, + 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003, + 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003, + 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003, + 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003, + 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003, + 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003, + 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003, + 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003, + 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003, + 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003, + 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, 0x81C, 0xF5000003, 0x81C, 0xF4020003, + 0x81C, 0xF3040003, 0x81C, 0xF2060003, 0x81C, 0xF1080003, + 0x81C, 0xF00A0003, 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, + 0x81C, 0xED100003, 0x81C, 0xEC120003, 0x81C, 0xEB140003, + 0x81C, 0xEA160003, 0x81C, 0xE9180003, 0x81C, 0xE81A0003, + 0x81C, 0xE71C0003, 0x81C, 0xE61E0003, 0x81C, 0xE5200003, + 0x81C, 0xE4220003, 0x81C, 0xE3240003, 0x81C, 0xE2260003, + 0x81C, 0xE1280003, 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, + 0x81C, 0xC22E0003, 0x81C, 0xC1300003, 0x81C, 0xC0320003, + 0x81C, 0xA4340003, 0x81C, 0xA3360003, 0x81C, 0xA2380003, + 0x81C, 0xA13A0003, 0x81C, 0xA03C0003, 0x81C, 0x823E0003, + 0x81C, 0x81400003, 0x81C, 0x80420003, 0x81C, 0x64440003, + 0x81C, 0x63460003, 0x81C, 0x62480003, 0x81C, 0x614A0003, + 0x81C, 0x604C0003, 0x81C, 0x454E0003, 0x81C, 0x44500003, + 0x81C, 0x43520003, 0x81C, 0x42540003, 0x81C, 0x41560003, + 0x81C, 0x40580003, 0x81C, 0x055A0003, 0x81C, 0x045C0003, + 0x81C, 0x035E0003, 0x81C, 0x02600003, 0x81C, 0x01620003, + 0x81C, 0x00640003, 0x81C, 0x00660003, 0x81C, 0x00680003, + 0x81C, 0x006A0003, 0x81C, 0x006C0003, 0x81C, 0x006E0003, + 0x81C, 0x00700003, 0x81C, 0x00720003, 0x81C, 0x00740003, + 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003, + 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xF5000003, + 0x81C, 0xF4020003, 0x81C, 0xF3040003, 0x81C, 0xF2060003, + 0x81C, 0xF1080003, 0x81C, 0xF00A0003, 0x81C, 0xEF0C0003, + 0x81C, 0xEE0E0003, 0x81C, 0xED100003, 0x81C, 0xEC120003, + 0x81C, 0xEB140003, 0x81C, 0xEA160003, 0x81C, 0xE9180003, + 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, 0x81C, 0xE61E0003, + 0x81C, 0xE5200003, 0x81C, 0xE4220003, 0x81C, 0xE3240003, + 0x81C, 0xE2260003, 0x81C, 0xE1280003, 0x81C, 0xE02A0003, + 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, 0x81C, 0xC1300003, + 0x81C, 0xC0320003, 0x81C, 0xA4340003, 0x81C, 0xA3360003, + 0x81C, 0xA2380003, 0x81C, 0xA13A0003, 0x81C, 0xA03C0003, + 0x81C, 0x823E0003, 0x81C, 0x81400003, 0x81C, 0x80420003, + 0x81C, 0x64440003, 0x81C, 0x63460003, 0x81C, 0x62480003, + 0x81C, 0x614A0003, 0x81C, 0x604C0003, 0x81C, 0x454E0003, + 0x81C, 0x44500003, 0x81C, 0x43520003, 0x81C, 0x42540003, + 0x81C, 0x41560003, 0x81C, 0x40580003, 0x81C, 0x055A0003, + 0x81C, 0x045C0003, 0x81C, 0x035E0003, 0x81C, 0x02600003, + 0x81C, 0x01620003, 0x81C, 0x00640003, 0x81C, 0x00660003, + 0x81C, 0x00680003, 0x81C, 0x006A0003, 0x81C, 0x006C0003, + 0x81C, 0x006E0003, 0x81C, 0x00700003, 0x81C, 0x00720003, + 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003, + 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003, + 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003, + 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003, + 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003, + 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003, + 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003, + 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003, + 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003, + 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003, + 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003, + 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003, + 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003, + 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003, + 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, 0x81C, 0xFD000003, 0x81C, 0xFC020003, + 0x81C, 0xFB040003, 0x81C, 0xFA060003, 0x81C, 0xF9080003, + 0x81C, 0xF80A0003, 0x81C, 0xF70C0003, 0x81C, 0xF60E0003, + 0x81C, 0xF5100003, 0x81C, 0xF4120003, 0x81C, 0xF3140003, + 0x81C, 0xF2160003, 0x81C, 0xF1180003, 0x81C, 0xF01A0003, + 0x81C, 0xEF1C0003, 0x81C, 0xEE1E0003, 0x81C, 0xED200003, + 0x81C, 0xEC220003, 0x81C, 0xEB240003, 0x81C, 0xEA260003, + 0x81C, 0xE9280003, 0x81C, 0xE82A0003, 0x81C, 0xE72C0003, + 0x81C, 0xE62E0003, 0x81C, 0xE5300003, 0x81C, 0xC8320003, + 0x81C, 0xC7340003, 0x81C, 0xC6360003, 0x81C, 0xC5380003, + 0x81C, 0xC43A0003, 0x81C, 0xC33C0003, 0x81C, 0xC23E0003, + 0x81C, 0xC1400003, 0x81C, 0xC0420003, 0x81C, 0xA5440003, + 0x81C, 0xA4460003, 0x81C, 0xA3480003, 0x81C, 0xA24A0003, + 0x81C, 0xA14C0003, 0x81C, 0x834E0003, 0x81C, 0x82500003, + 0x81C, 0x81520003, 0x81C, 0x80540003, 0x81C, 0x65560003, + 0x81C, 0x64580003, 0x81C, 0x635A0003, 0x81C, 0x625C0003, + 0x81C, 0x435E0003, 0x81C, 0x42600003, 0x81C, 0x41620003, + 0x81C, 0x40640003, 0x81C, 0x06660003, 0x81C, 0x05680003, + 0x81C, 0x046A0003, 0x81C, 0x036C0003, 0x81C, 0x026E0003, + 0x81C, 0x01700003, 0x81C, 0x00720003, 0x81C, 0x00740003, + 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003, + 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xFE000003, + 0x81C, 0xFD020003, 0x81C, 0xFC040003, 0x81C, 0xFB060003, + 0x81C, 0xFA080003, 0x81C, 0xF90A0003, 0x81C, 0xF80C0003, + 0x81C, 0xF70E0003, 0x81C, 0xF6100003, 0x81C, 0xF5120003, + 0x81C, 0xF4140003, 0x81C, 0xF3160003, 0x81C, 0xF2180003, + 0x81C, 0xF11A0003, 0x81C, 0xF01C0003, 0x81C, 0xEF1E0003, + 0x81C, 0xEE200003, 0x81C, 0xED220003, 0x81C, 0xEC240003, + 0x81C, 0xEB260003, 0x81C, 0xEA280003, 0x81C, 0xE92A0003, + 0x81C, 0xE82C0003, 0x81C, 0xE72E0003, 0x81C, 0xE6300003, + 0x81C, 0xE5320003, 0x81C, 0xC8340003, 0x81C, 0xC7360003, + 0x81C, 0xC6380003, 0x81C, 0xC53A0003, 0x81C, 0xC43C0003, + 0x81C, 0xC33E0003, 0x81C, 0xC2400003, 0x81C, 0xC1420003, + 0x81C, 0xC0440003, 0x81C, 0xA3460003, 0x81C, 0xA2480003, + 0x81C, 0xA14A0003, 0x81C, 0xA04C0003, 0x81C, 0x824E0003, + 0x81C, 0x81500003, 0x81C, 0x80520003, 0x81C, 0x64540003, + 0x81C, 0x63560003, 0x81C, 0x62580003, 0x81C, 0x445A0003, + 0x81C, 0x435C0003, 0x81C, 0x425E0003, 0x81C, 0x41600003, + 0x81C, 0x40620003, 0x81C, 0x05640003, 0x81C, 0x04660003, + 0x81C, 0x03680003, 0x81C, 0x026A0003, 0x81C, 0x016C0003, + 0x81C, 0x006E0003, 0x81C, 0x00700003, 0x81C, 0x00720003, + 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003, + 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xF5000003, 0x81C, 0xF4020003, 0x81C, 0xF3040003, + 0x81C, 0xF2060003, 0x81C, 0xF1080003, 0x81C, 0xF00A0003, + 0x81C, 0xEF0C0003, 0x81C, 0xEE0E0003, 0x81C, 0xED100003, + 0x81C, 0xEC120003, 0x81C, 0xEB140003, 0x81C, 0xEA160003, + 0x81C, 0xE9180003, 0x81C, 0xE81A0003, 0x81C, 0xE71C0003, + 0x81C, 0xE61E0003, 0x81C, 0xE5200003, 0x81C, 0xE4220003, + 0x81C, 0xE3240003, 0x81C, 0xE2260003, 0x81C, 0xE1280003, + 0x81C, 0xE02A0003, 0x81C, 0xC32C0003, 0x81C, 0xC22E0003, + 0x81C, 0xC1300003, 0x81C, 0xC0320003, 0x81C, 0xA4340003, + 0x81C, 0xA3360003, 0x81C, 0xA2380003, 0x81C, 0xA13A0003, + 0x81C, 0xA03C0003, 0x81C, 0x823E0003, 0x81C, 0x81400003, + 0x81C, 0x80420003, 0x81C, 0x64440003, 0x81C, 0x63460003, + 0x81C, 0x62480003, 0x81C, 0x614A0003, 0x81C, 0x604C0003, + 0x81C, 0x454E0003, 0x81C, 0x44500003, 0x81C, 0x43520003, + 0x81C, 0x42540003, 0x81C, 0x41560003, 0x81C, 0x40580003, + 0x81C, 0x055A0003, 0x81C, 0x045C0003, 0x81C, 0x035E0003, + 0x81C, 0x02600003, 0x81C, 0x01620003, 0x81C, 0x00640003, + 0x81C, 0x00660003, 0x81C, 0x00680003, 0x81C, 0x006A0003, + 0x81C, 0x006C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0x90011000, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000003, 0x81C, 0xFE000003, 0x81C, 0xFD020003, + 0x81C, 0xFC040003, 0x81C, 0xFB060003, 0x81C, 0xFA080003, + 0x81C, 0xF90A0003, 0x81C, 0xF80C0003, 0x81C, 0xF70E0003, + 0x81C, 0xF6100003, 0x81C, 0xF5120003, 0x81C, 0xF4140003, + 0x81C, 0xF3160003, 0x81C, 0xF2180003, 0x81C, 0xF11A0003, + 0x81C, 0xF01C0003, 0x81C, 0xEF1E0003, 0x81C, 0xEE200003, + 0x81C, 0xED220003, 0x81C, 0xEC240003, 0x81C, 0xEB260003, + 0x81C, 0xEA280003, 0x81C, 0xE92A0003, 0x81C, 0xE82C0003, + 0x81C, 0xE72E0003, 0x81C, 0xE6300003, 0x81C, 0xE5320003, + 0x81C, 0xC8340003, 0x81C, 0xC7360003, 0x81C, 0xC6380003, + 0x81C, 0xC53A0003, 0x81C, 0xC43C0003, 0x81C, 0xC33E0003, + 0x81C, 0xC2400003, 0x81C, 0xC1420003, 0x81C, 0xC0440003, + 0x81C, 0xA3460003, 0x81C, 0xA2480003, 0x81C, 0xA14A0003, + 0x81C, 0xA04C0003, 0x81C, 0x824E0003, 0x81C, 0x81500003, + 0x81C, 0x80520003, 0x81C, 0x64540003, 0x81C, 0x63560003, + 0x81C, 0x62580003, 0x81C, 0x445A0003, 0x81C, 0x435C0003, + 0x81C, 0x425E0003, 0x81C, 0x41600003, 0x81C, 0x40620003, + 0x81C, 0x05640003, 0x81C, 0x04660003, 0x81C, 0x03680003, + 0x81C, 0x026A0003, 0x81C, 0x016C0003, 0x81C, 0x006E0003, + 0x81C, 0x00700003, 0x81C, 0x00720003, 0x81C, 0x00740003, + 0x81C, 0x00760003, 0x81C, 0x00780003, 0x81C, 0x007A0003, + 0x81C, 0x007C0003, 0x81C, 0x007E0003, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000003, 0x81C, 0xFD000003, + 0x81C, 0xFC020003, 0x81C, 0xFB040003, 0x81C, 0xFA060003, + 0x81C, 0xF9080003, 0x81C, 0xF80A0003, 0x81C, 0xF70C0003, + 0x81C, 0xF60E0003, 0x81C, 0xF5100003, 0x81C, 0xF4120003, + 0x81C, 0xF3140003, 0x81C, 0xF2160003, 0x81C, 0xF1180003, + 0x81C, 0xF01A0003, 0x81C, 0xEF1C0003, 0x81C, 0xEE1E0003, + 0x81C, 0xED200003, 0x81C, 0xEC220003, 0x81C, 0xEB240003, + 0x81C, 0xEA260003, 0x81C, 0xE9280003, 0x81C, 0xE82A0003, + 0x81C, 0xE72C0003, 0x81C, 0xE62E0003, 0x81C, 0xE5300003, + 0x81C, 0xC8320003, 0x81C, 0xC7340003, 0x81C, 0xC6360003, + 0x81C, 0xC5380003, 0x81C, 0xC43A0003, 0x81C, 0xC33C0003, + 0x81C, 0xC23E0003, 0x81C, 0xC1400003, 0x81C, 0xC0420003, + 0x81C, 0xA5440003, 0x81C, 0xA4460003, 0x81C, 0xA3480003, + 0x81C, 0xA24A0003, 0x81C, 0xA14C0003, 0x81C, 0x834E0003, + 0x81C, 0x82500003, 0x81C, 0x81520003, 0x81C, 0x80540003, + 0x81C, 0x65560003, 0x81C, 0x64580003, 0x81C, 0x635A0003, + 0x81C, 0x625C0003, 0x81C, 0x435E0003, 0x81C, 0x42600003, + 0x81C, 0x41620003, 0x81C, 0x40640003, 0x81C, 0x06660003, + 0x81C, 0x05680003, 0x81C, 0x046A0003, 0x81C, 0x036C0003, + 0x81C, 0x026E0003, 0x81C, 0x01700003, 0x81C, 0x00720003, + 0x81C, 0x00740003, 0x81C, 0x00760003, 0x81C, 0x00780003, + 0x81C, 0x007A0003, 0x81C, 0x007C0003, 0x81C, 0x007E0003, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xFD000003, 0x81C, 0xFC020003, 0x81C, 0xFB040003, + 0x81C, 0xFA060003, 0x81C, 0xF9080003, 0x81C, 0xF80A0003, + 0x81C, 0xF70C0003, 0x81C, 0xF60E0003, 0x81C, 0xF5100003, + 0x81C, 0xF4120003, 0x81C, 0xF3140003, 0x81C, 0xF2160003, + 0x81C, 0xF1180003, 0x81C, 0xF01A0003, 0x81C, 0xEF1C0003, + 0x81C, 0xEE1E0003, 0x81C, 0xED200003, 0x81C, 0xEC220003, + 0x81C, 0xEB240003, 0x81C, 0xEA260003, 0x81C, 0xE9280003, + 0x81C, 0xE82A0003, 0x81C, 0xE72C0003, 0x81C, 0xE62E0003, + 0x81C, 0xE5300003, 0x81C, 0xC8320003, 0x81C, 0xC7340003, + 0x81C, 0xC6360003, 0x81C, 0xC5380003, 0x81C, 0xC43A0003, + 0x81C, 0xC33C0003, 0x81C, 0xC23E0003, 0x81C, 0xC1400003, + 0x81C, 0xC0420003, 0x81C, 0xA5440003, 0x81C, 0xA4460003, + 0x81C, 0xA3480003, 0x81C, 0xA24A0003, 0x81C, 0xA14C0003, + 0x81C, 0x834E0003, 0x81C, 0x82500003, 0x81C, 0x81520003, + 0x81C, 0x80540003, 0x81C, 0x65560003, 0x81C, 0x64580003, + 0x81C, 0x635A0003, 0x81C, 0x625C0003, 0x81C, 0x435E0003, + 0x81C, 0x42600003, 0x81C, 0x41620003, 0x81C, 0x40640003, + 0x81C, 0x06660003, 0x81C, 0x05680003, 0x81C, 0x046A0003, + 0x81C, 0x036C0003, 0x81C, 0x026E0003, 0x81C, 0x01700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0xA0000000, 0x00000000, 0x81C, 0xFF000003, + 0x81C, 0xFE000003, 0x81C, 0xFD020003, 0x81C, 0xFC040003, + 0x81C, 0xFB060003, 0x81C, 0xFA080003, 0x81C, 0xF90A0003, + 0x81C, 0xF80C0003, 0x81C, 0xF70E0003, 0x81C, 0xF6100003, + 0x81C, 0xF5120003, 0x81C, 0xF4140003, 0x81C, 0xF3160003, + 0x81C, 0xF2180003, 0x81C, 0xF11A0003, 0x81C, 0xF01C0003, + 0x81C, 0xEF1E0003, 0x81C, 0xEE200003, 0x81C, 0xED220003, + 0x81C, 0xEC240003, 0x81C, 0xEB260003, 0x81C, 0xEA280003, + 0x81C, 0xE92A0003, 0x81C, 0xE82C0003, 0x81C, 0xE72E0003, + 0x81C, 0xE6300003, 0x81C, 0xE5320003, 0x81C, 0xC8340003, + 0x81C, 0xC7360003, 0x81C, 0xC6380003, 0x81C, 0xC53A0003, + 0x81C, 0xC43C0003, 0x81C, 0xC33E0003, 0x81C, 0xC2400003, + 0x81C, 0xC1420003, 0x81C, 0xC0440003, 0x81C, 0xA3460003, + 0x81C, 0xA2480003, 0x81C, 0xA14A0003, 0x81C, 0xA04C0003, + 0x81C, 0x824E0003, 0x81C, 0x81500003, 0x81C, 0x80520003, + 0x81C, 0x64540003, 0x81C, 0x63560003, 0x81C, 0x62580003, + 0x81C, 0x445A0003, 0x81C, 0x435C0003, 0x81C, 0x425E0003, + 0x81C, 0x41600003, 0x81C, 0x40620003, 0x81C, 0x05640003, + 0x81C, 0x04660003, 0x81C, 0x03680003, 0x81C, 0x026A0003, + 0x81C, 0x016C0003, 0x81C, 0x006E0003, 0x81C, 0x00700003, + 0x81C, 0x00720003, 0x81C, 0x00740003, 0x81C, 0x00760003, + 0x81C, 0x00780003, 0x81C, 0x007A0003, 0x81C, 0x007C0003, + 0x81C, 0x007E0003, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xE22C0103, + 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x64420103, 0x81C, 0x63440103, + 0x81C, 0x62460103, 0x81C, 0x61480103, 0x81C, 0x434A0103, + 0x81C, 0x424C0103, 0x81C, 0x414E0103, 0x81C, 0x40500103, + 0x81C, 0x22520103, 0x81C, 0x21540103, 0x81C, 0x20560103, + 0x81C, 0x04580103, 0x81C, 0x035A0103, 0x81C, 0x025C0103, + 0x81C, 0x015E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x81C, 0xFA000103, 0x81C, 0xF9020103, + 0x81C, 0xF8040103, 0x81C, 0xF7060103, 0x81C, 0xF6080103, + 0x81C, 0xF50A0103, 0x81C, 0xF40C0103, 0x81C, 0xF30E0103, + 0x81C, 0xF2100103, 0x81C, 0xF1120103, 0x81C, 0xF0140103, + 0x81C, 0xEF160103, 0x81C, 0xEE180103, 0x81C, 0xED1A0103, + 0x81C, 0xEC1C0103, 0x81C, 0xEB1E0103, 0x81C, 0xEA200103, + 0x81C, 0xE9220103, 0x81C, 0xE8240103, 0x81C, 0xE7260103, + 0x81C, 0xE6280103, 0x81C, 0xE52A0103, 0x81C, 0xC42C0103, + 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103, + 0x81C, 0xA4340103, 0x81C, 0xA3360103, 0x81C, 0xA2380103, + 0x81C, 0xA13A0103, 0x81C, 0x833C0103, 0x81C, 0x823E0103, + 0x81C, 0x81400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103, + 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x06500103, + 0x81C, 0x05520103, 0x81C, 0x04540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103, + 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xC32C0103, + 0x81C, 0xC22E0103, 0x81C, 0xC1300103, 0x81C, 0xC0320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x63420103, 0x81C, 0x62440103, + 0x81C, 0x61460103, 0x81C, 0x60480103, 0x81C, 0x424A0103, + 0x81C, 0x414C0103, 0x81C, 0x404E0103, 0x81C, 0x22500103, + 0x81C, 0x21520103, 0x81C, 0x20540103, 0x81C, 0x03560103, + 0x81C, 0x02580103, 0x81C, 0x015A0103, 0x81C, 0x005C0103, + 0x81C, 0x005E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103, + 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103, + 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, 0x81C, 0xEE1E0103, 0x81C, 0xED200103, + 0x81C, 0xEC220103, 0x81C, 0xEB240103, 0x81C, 0xEA260103, + 0x81C, 0xE9280103, 0x81C, 0xE82A0103, 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, 0x81C, 0xE5300103, 0x81C, 0xE4320103, + 0x81C, 0xE3340103, 0x81C, 0xC6360103, 0x81C, 0xC5380103, + 0x81C, 0xC43A0103, 0x81C, 0xC33C0103, 0x81C, 0xC23E0103, + 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103, + 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0x834A0103, + 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x63500103, + 0x81C, 0x62520103, 0x81C, 0x61540103, 0x81C, 0x43560103, + 0x81C, 0x42580103, 0x81C, 0x245A0103, 0x81C, 0x235C0103, + 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x04620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000103, 0x81C, 0xF7020103, + 0x81C, 0xF6040103, 0x81C, 0xF5060103, 0x81C, 0xF4080103, + 0x81C, 0xF30A0103, 0x81C, 0xF20C0103, 0x81C, 0xF10E0103, + 0x81C, 0xF0100103, 0x81C, 0xEF120103, 0x81C, 0xEE140103, + 0x81C, 0xED160103, 0x81C, 0xEC180103, 0x81C, 0xEB1A0103, + 0x81C, 0xEA1C0103, 0x81C, 0xE91E0103, 0x81C, 0xE8200103, + 0x81C, 0xE7220103, 0x81C, 0xE6240103, 0x81C, 0xE5260103, + 0x81C, 0xE4280103, 0x81C, 0xE32A0103, 0x81C, 0xE22C0103, + 0x81C, 0xC32E0103, 0x81C, 0xC2300103, 0x81C, 0xC1320103, + 0x81C, 0xA3340103, 0x81C, 0xA2360103, 0x81C, 0xA1380103, + 0x81C, 0xA03A0103, 0x81C, 0x823C0103, 0x81C, 0x813E0103, + 0x81C, 0x80400103, 0x81C, 0x64420103, 0x81C, 0x63440103, + 0x81C, 0x62460103, 0x81C, 0x61480103, 0x81C, 0x434A0103, + 0x81C, 0x424C0103, 0x81C, 0x414E0103, 0x81C, 0x40500103, + 0x81C, 0x22520103, 0x81C, 0x21540103, 0x81C, 0x20560103, + 0x81C, 0x04580103, 0x81C, 0x035A0103, 0x81C, 0x025C0103, + 0x81C, 0x015E0103, 0x81C, 0x00600103, 0x81C, 0x00620103, + 0x81C, 0x00640103, 0x81C, 0x00660103, 0x81C, 0x00680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90011000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103, + 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103, + 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103, + 0x81C, 0xEE1C0103, 0x81C, 0xED1E0103, 0x81C, 0xEC200103, + 0x81C, 0xEB220103, 0x81C, 0xEA240103, 0x81C, 0xE9260103, + 0x81C, 0xE8280103, 0x81C, 0xE72A0103, 0x81C, 0xE62C0103, + 0x81C, 0xE52E0103, 0x81C, 0xE4300103, 0x81C, 0xE3320103, + 0x81C, 0xE2340103, 0x81C, 0xC5360103, 0x81C, 0xC4380103, + 0x81C, 0xC33A0103, 0x81C, 0xC23C0103, 0x81C, 0xA53E0103, + 0x81C, 0xA4400103, 0x81C, 0xA3420103, 0x81C, 0xA2440103, + 0x81C, 0xA1460103, 0x81C, 0x83480103, 0x81C, 0x824A0103, + 0x81C, 0x814C0103, 0x81C, 0x804E0103, 0x81C, 0x63500103, + 0x81C, 0x62520103, 0x81C, 0x61540103, 0x81C, 0x43560103, + 0x81C, 0x42580103, 0x81C, 0x415A0103, 0x81C, 0x405C0103, + 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x20620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFD000103, 0x81C, 0xFC020103, + 0x81C, 0xFB040103, 0x81C, 0xFA060103, 0x81C, 0xF9080103, + 0x81C, 0xF80A0103, 0x81C, 0xF70C0103, 0x81C, 0xF60E0103, + 0x81C, 0xF5100103, 0x81C, 0xF4120103, 0x81C, 0xF3140103, + 0x81C, 0xF2160103, 0x81C, 0xF1180103, 0x81C, 0xF01A0103, + 0x81C, 0xEF1C0103, 0x81C, 0xEE1E0103, 0x81C, 0xED200103, + 0x81C, 0xEC220103, 0x81C, 0xEB240103, 0x81C, 0xEA260103, + 0x81C, 0xE9280103, 0x81C, 0xE82A0103, 0x81C, 0xE72C0103, + 0x81C, 0xE62E0103, 0x81C, 0xE5300103, 0x81C, 0xE4320103, + 0x81C, 0xE3340103, 0x81C, 0xE2360103, 0x81C, 0xC5380103, + 0x81C, 0xC43A0103, 0x81C, 0xC33C0103, 0x81C, 0xC23E0103, + 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103, + 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0x834A0103, + 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x64500103, + 0x81C, 0x63520103, 0x81C, 0x62540103, 0x81C, 0x61560103, + 0x81C, 0x42580103, 0x81C, 0x415A0103, 0x81C, 0x405C0103, + 0x81C, 0x065E0103, 0x81C, 0x05600103, 0x81C, 0x04620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFE000103, 0x81C, 0xFD020103, + 0x81C, 0xFC040103, 0x81C, 0xFB060103, 0x81C, 0xFA080103, + 0x81C, 0xF90A0103, 0x81C, 0xF80C0103, 0x81C, 0xF70E0103, + 0x81C, 0xF6100103, 0x81C, 0xF5120103, 0x81C, 0xF4140103, + 0x81C, 0xF3160103, 0x81C, 0xF2180103, 0x81C, 0xF11A0103, + 0x81C, 0xF01C0103, 0x81C, 0xEF1E0103, 0x81C, 0xEE200103, + 0x81C, 0xED220103, 0x81C, 0xEC240103, 0x81C, 0xEB260103, + 0x81C, 0xEA280103, 0x81C, 0xE92A0103, 0x81C, 0xE82C0103, + 0x81C, 0xE72E0103, 0x81C, 0xE6300103, 0x81C, 0xE5320103, + 0x81C, 0xE4340103, 0x81C, 0xE3360103, 0x81C, 0xC6380103, + 0x81C, 0xC53A0103, 0x81C, 0xC43C0103, 0x81C, 0xC33E0103, + 0x81C, 0xA5400103, 0x81C, 0xA4420103, 0x81C, 0xA3440103, + 0x81C, 0xA2460103, 0x81C, 0xA1480103, 0x81C, 0xA04A0103, + 0x81C, 0x824C0103, 0x81C, 0x814E0103, 0x81C, 0x80500103, + 0x81C, 0x64520103, 0x81C, 0x63540103, 0x81C, 0x62560103, + 0x81C, 0x61580103, 0x81C, 0x605A0103, 0x81C, 0x235C0103, + 0x81C, 0x225E0103, 0x81C, 0x21600103, 0x81C, 0x20620103, + 0x81C, 0x03640103, 0x81C, 0x02660103, 0x81C, 0x01680103, + 0x81C, 0x006A0103, 0x81C, 0x006C0103, 0x81C, 0x006E0103, + 0x81C, 0x00700103, 0x81C, 0x00720103, 0x81C, 0x00740103, + 0x81C, 0x00760103, 0x81C, 0x00780103, 0x81C, 0x007A0103, + 0x81C, 0x007C0103, 0x81C, 0x007E0103, 0xA0000000, 0x00000000, + 0x81C, 0xFE000103, 0x81C, 0xFD020103, 0x81C, 0xFC040103, + 0x81C, 0xFB060103, 0x81C, 0xFA080103, 0x81C, 0xF90A0103, + 0x81C, 0xF80C0103, 0x81C, 0xF70E0103, 0x81C, 0xF6100103, + 0x81C, 0xF5120103, 0x81C, 0xF4140103, 0x81C, 0xF3160103, + 0x81C, 0xF2180103, 0x81C, 0xF11A0103, 0x81C, 0xF01C0103, + 0x81C, 0xEF1E0103, 0x81C, 0xEE200103, 0x81C, 0xED220103, + 0x81C, 0xEC240103, 0x81C, 0xEB260103, 0x81C, 0xEA280103, + 0x81C, 0xE92A0103, 0x81C, 0xE82C0103, 0x81C, 0xE72E0103, + 0x81C, 0xE6300103, 0x81C, 0xE5320103, 0x81C, 0xE4340103, + 0x81C, 0xE3360103, 0x81C, 0xC6380103, 0x81C, 0xC53A0103, + 0x81C, 0xC43C0103, 0x81C, 0xC33E0103, 0x81C, 0xA5400103, + 0x81C, 0xA4420103, 0x81C, 0xA3440103, 0x81C, 0xA2460103, + 0x81C, 0xA1480103, 0x81C, 0xA04A0103, 0x81C, 0x824C0103, + 0x81C, 0x814E0103, 0x81C, 0x80500103, 0x81C, 0x64520103, + 0x81C, 0x63540103, 0x81C, 0x62560103, 0x81C, 0x61580103, + 0x81C, 0x605A0103, 0x81C, 0x235C0103, 0x81C, 0x225E0103, + 0x81C, 0x21600103, 0x81C, 0x20620103, 0x81C, 0x03640103, + 0x81C, 0x02660103, 0x81C, 0x01680103, 0x81C, 0x006A0103, + 0x81C, 0x006C0103, 0x81C, 0x006E0103, 0x81C, 0x00700103, + 0x81C, 0x00720103, 0x81C, 0x00740103, 0x81C, 0x00760103, + 0x81C, 0x00780103, 0x81C, 0x007A0103, 0x81C, 0x007C0103, + 0x81C, 0x007E0103, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xF8000203, 0x81C, 0xF7020203, + 0x81C, 0xF6040203, 0x81C, 0xF5060203, 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, 0x81C, 0xF20C0203, 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, 0x81C, 0xEF120203, 0x81C, 0xEE140203, + 0x81C, 0xED160203, 0x81C, 0xEC180203, 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, 0x81C, 0xE91E0203, 0x81C, 0xE8200203, + 0x81C, 0xE7220203, 0x81C, 0xE6240203, 0x81C, 0xE5260203, + 0x81C, 0xE4280203, 0x81C, 0xE32A0203, 0x81C, 0xC42C0203, + 0x81C, 0xC32E0203, 0x81C, 0xC2300203, 0x81C, 0xC1320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x65420203, 0x81C, 0x64440203, + 0x81C, 0x63460203, 0x81C, 0x62480203, 0x81C, 0x614A0203, + 0x81C, 0x424C0203, 0x81C, 0x414E0203, 0x81C, 0x40500203, + 0x81C, 0x22520203, 0x81C, 0x21540203, 0x81C, 0x20560203, + 0x81C, 0x04580203, 0x81C, 0x035A0203, 0x81C, 0x025C0203, + 0x81C, 0x015E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x81C, 0xF9000203, 0x81C, 0xF8020203, + 0x81C, 0xF7040203, 0x81C, 0xF6060203, 0x81C, 0xF5080203, + 0x81C, 0xF40A0203, 0x81C, 0xF30C0203, 0x81C, 0xF20E0203, + 0x81C, 0xF1100203, 0x81C, 0xF0120203, 0x81C, 0xEF140203, + 0x81C, 0xEE160203, 0x81C, 0xED180203, 0x81C, 0xEC1A0203, + 0x81C, 0xEB1C0203, 0x81C, 0xEA1E0203, 0x81C, 0xE9200203, + 0x81C, 0xE8220203, 0x81C, 0xE7240203, 0x81C, 0xE6260203, + 0x81C, 0xE5280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203, + 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203, + 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203, + 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203, + 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203, + 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203, + 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x63420203, 0x81C, 0x62440203, + 0x81C, 0x61460203, 0x81C, 0x60480203, 0x81C, 0x424A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x06500203, + 0x81C, 0x05520203, 0x81C, 0x04540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203, + 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203, + 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203, + 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203, + 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203, + 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203, + 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000203, 0x81C, 0xF6020203, + 0x81C, 0xF5040203, 0x81C, 0xF4060203, 0x81C, 0xF3080203, + 0x81C, 0xF20A0203, 0x81C, 0xF10C0203, 0x81C, 0xF00E0203, + 0x81C, 0xEF100203, 0x81C, 0xEE120203, 0x81C, 0xED140203, + 0x81C, 0xEC160203, 0x81C, 0xEB180203, 0x81C, 0xEA1A0203, + 0x81C, 0xE91C0203, 0x81C, 0xE81E0203, 0x81C, 0xE7200203, + 0x81C, 0xE6220203, 0x81C, 0xE5240203, 0x81C, 0xE4260203, + 0x81C, 0xE3280203, 0x81C, 0xC42A0203, 0x81C, 0xC32C0203, + 0x81C, 0xC22E0203, 0x81C, 0xC1300203, 0x81C, 0xC0320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x64420203, 0x81C, 0x63440203, + 0x81C, 0x62460203, 0x81C, 0x61480203, 0x81C, 0x604A0203, + 0x81C, 0x414C0203, 0x81C, 0x404E0203, 0x81C, 0x22500203, + 0x81C, 0x21520203, 0x81C, 0x20540203, 0x81C, 0x03560203, + 0x81C, 0x02580203, 0x81C, 0x015A0203, 0x81C, 0x005C0203, + 0x81C, 0x005E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000203, 0x81C, 0xFA020203, + 0x81C, 0xF9040203, 0x81C, 0xF8060203, 0x81C, 0xF7080203, + 0x81C, 0xF60A0203, 0x81C, 0xF50C0203, 0x81C, 0xF40E0203, + 0x81C, 0xF3100203, 0x81C, 0xF2120203, 0x81C, 0xF1140203, + 0x81C, 0xF0160203, 0x81C, 0xEF180203, 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, 0x81C, 0xEC1E0203, 0x81C, 0xEB200203, + 0x81C, 0xEA220203, 0x81C, 0xE9240203, 0x81C, 0xE8260203, + 0x81C, 0xE7280203, 0x81C, 0xE62A0203, 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, 0x81C, 0xE3300203, 0x81C, 0xE2320203, + 0x81C, 0xC6340203, 0x81C, 0xC5360203, 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, 0x81C, 0xC23C0203, 0x81C, 0xC13E0203, + 0x81C, 0xC0400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203, + 0x81C, 0xA1460203, 0x81C, 0xA0480203, 0x81C, 0x824A0203, + 0x81C, 0x814C0203, 0x81C, 0x804E0203, 0x81C, 0x63500203, + 0x81C, 0x62520203, 0x81C, 0x61540203, 0x81C, 0x60560203, + 0x81C, 0x24580203, 0x81C, 0x235A0203, 0x81C, 0x225C0203, + 0x81C, 0x215E0203, 0x81C, 0x20600203, 0x81C, 0x03620203, + 0x81C, 0x02640203, 0x81C, 0x01660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000203, 0x81C, 0xF7020203, + 0x81C, 0xF6040203, 0x81C, 0xF5060203, 0x81C, 0xF4080203, + 0x81C, 0xF30A0203, 0x81C, 0xF20C0203, 0x81C, 0xF10E0203, + 0x81C, 0xF0100203, 0x81C, 0xEF120203, 0x81C, 0xEE140203, + 0x81C, 0xED160203, 0x81C, 0xEC180203, 0x81C, 0xEB1A0203, + 0x81C, 0xEA1C0203, 0x81C, 0xE91E0203, 0x81C, 0xE8200203, + 0x81C, 0xE7220203, 0x81C, 0xE6240203, 0x81C, 0xE5260203, + 0x81C, 0xE4280203, 0x81C, 0xE32A0203, 0x81C, 0xC42C0203, + 0x81C, 0xC32E0203, 0x81C, 0xC2300203, 0x81C, 0xC1320203, + 0x81C, 0xA3340203, 0x81C, 0xA2360203, 0x81C, 0xA1380203, + 0x81C, 0xA03A0203, 0x81C, 0x823C0203, 0x81C, 0x813E0203, + 0x81C, 0x80400203, 0x81C, 0x65420203, 0x81C, 0x64440203, + 0x81C, 0x63460203, 0x81C, 0x62480203, 0x81C, 0x614A0203, + 0x81C, 0x424C0203, 0x81C, 0x414E0203, 0x81C, 0x40500203, + 0x81C, 0x22520203, 0x81C, 0x21540203, 0x81C, 0x20560203, + 0x81C, 0x04580203, 0x81C, 0x035A0203, 0x81C, 0x025C0203, + 0x81C, 0x015E0203, 0x81C, 0x00600203, 0x81C, 0x00620203, + 0x81C, 0x00640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90011000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203, + 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203, + 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEE1A0203, + 0x81C, 0xED1C0203, 0x81C, 0xEC1E0203, 0x81C, 0xEB200203, + 0x81C, 0xEA220203, 0x81C, 0xE9240203, 0x81C, 0xE8260203, + 0x81C, 0xE7280203, 0x81C, 0xE62A0203, 0x81C, 0xE52C0203, + 0x81C, 0xE42E0203, 0x81C, 0xE3300203, 0x81C, 0xE2320203, + 0x81C, 0xC6340203, 0x81C, 0xC5360203, 0x81C, 0xC4380203, + 0x81C, 0xC33A0203, 0x81C, 0xA63C0203, 0x81C, 0xA53E0203, + 0x81C, 0xA4400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203, + 0x81C, 0xA1460203, 0x81C, 0x83480203, 0x81C, 0x824A0203, + 0x81C, 0x814C0203, 0x81C, 0x804E0203, 0x81C, 0x63500203, + 0x81C, 0x62520203, 0x81C, 0x61540203, 0x81C, 0x42560203, + 0x81C, 0x41580203, 0x81C, 0x405A0203, 0x81C, 0x225C0203, + 0x81C, 0x215E0203, 0x81C, 0x20600203, 0x81C, 0x04620203, + 0x81C, 0x03640203, 0x81C, 0x02660203, 0x81C, 0x01680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203, + 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203, + 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, 0x81C, 0xED1E0203, 0x81C, 0xEC200203, + 0x81C, 0xEB220203, 0x81C, 0xEA240203, 0x81C, 0xE9260203, + 0x81C, 0xE8280203, 0x81C, 0xE72A0203, 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, 0x81C, 0xE4300203, 0x81C, 0xE3320203, + 0x81C, 0xE2340203, 0x81C, 0xE1360203, 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, 0x81C, 0xC33C0203, 0x81C, 0xC23E0203, + 0x81C, 0xC1400203, 0x81C, 0xA3420203, 0x81C, 0xA2440203, + 0x81C, 0xA1460203, 0x81C, 0xA0480203, 0x81C, 0x834A0203, + 0x81C, 0x824C0203, 0x81C, 0x814E0203, 0x81C, 0x64500203, + 0x81C, 0x63520203, 0x81C, 0x62540203, 0x81C, 0x61560203, + 0x81C, 0x25580203, 0x81C, 0x245A0203, 0x81C, 0x235C0203, + 0x81C, 0x225E0203, 0x81C, 0x21600203, 0x81C, 0x04620203, + 0x81C, 0x03640203, 0x81C, 0x02660203, 0x81C, 0x01680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000203, 0x81C, 0xFB020203, + 0x81C, 0xFA040203, 0x81C, 0xF9060203, 0x81C, 0xF8080203, + 0x81C, 0xF70A0203, 0x81C, 0xF60C0203, 0x81C, 0xF50E0203, + 0x81C, 0xF4100203, 0x81C, 0xF3120203, 0x81C, 0xF2140203, + 0x81C, 0xF1160203, 0x81C, 0xF0180203, 0x81C, 0xEF1A0203, + 0x81C, 0xEE1C0203, 0x81C, 0xED1E0203, 0x81C, 0xEC200203, + 0x81C, 0xEB220203, 0x81C, 0xEA240203, 0x81C, 0xE9260203, + 0x81C, 0xE8280203, 0x81C, 0xE72A0203, 0x81C, 0xE62C0203, + 0x81C, 0xE52E0203, 0x81C, 0xE4300203, 0x81C, 0xE3320203, + 0x81C, 0xE2340203, 0x81C, 0xC6360203, 0x81C, 0xC5380203, + 0x81C, 0xC43A0203, 0x81C, 0xC33C0203, 0x81C, 0xA63E0203, + 0x81C, 0xA5400203, 0x81C, 0xA4420203, 0x81C, 0xA3440203, + 0x81C, 0xA2460203, 0x81C, 0xA1480203, 0x81C, 0x834A0203, + 0x81C, 0x824C0203, 0x81C, 0x814E0203, 0x81C, 0x64500203, + 0x81C, 0x63520203, 0x81C, 0x62540203, 0x81C, 0x61560203, + 0x81C, 0x60580203, 0x81C, 0x405A0203, 0x81C, 0x215C0203, + 0x81C, 0x205E0203, 0x81C, 0x03600203, 0x81C, 0x02620203, + 0x81C, 0x01640203, 0x81C, 0x00660203, 0x81C, 0x00680203, + 0x81C, 0x006A0203, 0x81C, 0x006C0203, 0x81C, 0x006E0203, + 0x81C, 0x00700203, 0x81C, 0x00720203, 0x81C, 0x00740203, + 0x81C, 0x00760203, 0x81C, 0x00780203, 0x81C, 0x007A0203, + 0x81C, 0x007C0203, 0x81C, 0x007E0203, 0xA0000000, 0x00000000, + 0x81C, 0xFD000203, 0x81C, 0xFC020203, 0x81C, 0xFB040203, + 0x81C, 0xFA060203, 0x81C, 0xF9080203, 0x81C, 0xF80A0203, + 0x81C, 0xF70C0203, 0x81C, 0xF60E0203, 0x81C, 0xF5100203, + 0x81C, 0xF4120203, 0x81C, 0xF3140203, 0x81C, 0xF2160203, + 0x81C, 0xF1180203, 0x81C, 0xF01A0203, 0x81C, 0xEF1C0203, + 0x81C, 0xEE1E0203, 0x81C, 0xED200203, 0x81C, 0xEC220203, + 0x81C, 0xEB240203, 0x81C, 0xEA260203, 0x81C, 0xE9280203, + 0x81C, 0xE82A0203, 0x81C, 0xE72C0203, 0x81C, 0xE62E0203, + 0x81C, 0xE5300203, 0x81C, 0xE4320203, 0x81C, 0xE3340203, + 0x81C, 0xC6360203, 0x81C, 0xC5380203, 0x81C, 0xC43A0203, + 0x81C, 0xC33C0203, 0x81C, 0xA63E0203, 0x81C, 0xA5400203, + 0x81C, 0xA4420203, 0x81C, 0xA3440203, 0x81C, 0xA2460203, + 0x81C, 0xA1480203, 0x81C, 0x834A0203, 0x81C, 0x824C0203, + 0x81C, 0x814E0203, 0x81C, 0x64500203, 0x81C, 0x63520203, + 0x81C, 0x62540203, 0x81C, 0x61560203, 0x81C, 0x60580203, + 0x81C, 0x235A0203, 0x81C, 0x225C0203, 0x81C, 0x215E0203, + 0x81C, 0x20600203, 0x81C, 0x03620203, 0x81C, 0x02640203, + 0x81C, 0x01660203, 0x81C, 0x00680203, 0x81C, 0x006A0203, + 0x81C, 0x006C0203, 0x81C, 0x006E0203, 0x81C, 0x00700203, + 0x81C, 0x00720203, 0x81C, 0x00740203, 0x81C, 0x00760203, + 0x81C, 0x00780203, 0x81C, 0x007A0203, 0x81C, 0x007C0203, + 0x81C, 0x007E0203, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xF8000303, 0x81C, 0xF7020303, + 0x81C, 0xF6040303, 0x81C, 0xF5060303, 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, 0x81C, 0xF20C0303, 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, 0x81C, 0xEF120303, 0x81C, 0xEE140303, + 0x81C, 0xED160303, 0x81C, 0xEC180303, 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, 0x81C, 0xE91E0303, 0x81C, 0xCA200303, + 0x81C, 0xC9220303, 0x81C, 0xC8240303, 0x81C, 0xC7260303, + 0x81C, 0xC6280303, 0x81C, 0xC52A0303, 0x81C, 0xC42C0303, + 0x81C, 0xC32E0303, 0x81C, 0xC2300303, 0x81C, 0xC1320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x65420303, 0x81C, 0x64440303, + 0x81C, 0x63460303, 0x81C, 0x62480303, 0x81C, 0x614A0303, + 0x81C, 0x424C0303, 0x81C, 0x414E0303, 0x81C, 0x40500303, + 0x81C, 0x22520303, 0x81C, 0x21540303, 0x81C, 0x20560303, + 0x81C, 0x04580303, 0x81C, 0x035A0303, 0x81C, 0x025C0303, + 0x81C, 0x015E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x81C, 0xF9000303, 0x81C, 0xF8020303, + 0x81C, 0xF7040303, 0x81C, 0xF6060303, 0x81C, 0xF5080303, + 0x81C, 0xF40A0303, 0x81C, 0xF30C0303, 0x81C, 0xF20E0303, + 0x81C, 0xF1100303, 0x81C, 0xF0120303, 0x81C, 0xEF140303, + 0x81C, 0xEE160303, 0x81C, 0xED180303, 0x81C, 0xEC1A0303, + 0x81C, 0xEB1C0303, 0x81C, 0xEA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xC0320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303, + 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303, + 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303, + 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x06500303, + 0x81C, 0x05520303, 0x81C, 0x04540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303, + 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303, + 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303, + 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF7000303, 0x81C, 0xF6020303, + 0x81C, 0xF5040303, 0x81C, 0xF4060303, 0x81C, 0xF3080303, + 0x81C, 0xF20A0303, 0x81C, 0xF10C0303, 0x81C, 0xF00E0303, + 0x81C, 0xEF100303, 0x81C, 0xEE120303, 0x81C, 0xED140303, + 0x81C, 0xEC160303, 0x81C, 0xEB180303, 0x81C, 0xEA1A0303, + 0x81C, 0xE91C0303, 0x81C, 0xCA1E0303, 0x81C, 0xC9200303, + 0x81C, 0xC8220303, 0x81C, 0xC7240303, 0x81C, 0xC6260303, + 0x81C, 0xC5280303, 0x81C, 0xC42A0303, 0x81C, 0xC32C0303, + 0x81C, 0xC22E0303, 0x81C, 0xC1300303, 0x81C, 0xA4320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x64420303, 0x81C, 0x63440303, + 0x81C, 0x62460303, 0x81C, 0x61480303, 0x81C, 0x604A0303, + 0x81C, 0x414C0303, 0x81C, 0x404E0303, 0x81C, 0x22500303, + 0x81C, 0x21520303, 0x81C, 0x20540303, 0x81C, 0x03560303, + 0x81C, 0x02580303, 0x81C, 0x015A0303, 0x81C, 0x005C0303, + 0x81C, 0x005E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90012100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303, + 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303, + 0x81C, 0xF0160303, 0x81C, 0xEF180303, 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, 0x81C, 0xEC1E0303, 0x81C, 0xEB200303, + 0x81C, 0xEA220303, 0x81C, 0xE9240303, 0x81C, 0xE8260303, + 0x81C, 0xE7280303, 0x81C, 0xE62A0303, 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, 0x81C, 0xE3300303, 0x81C, 0xE2320303, + 0x81C, 0xC6340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, 0x81C, 0xC23C0303, 0x81C, 0xC13E0303, + 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303, + 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303, + 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x63500303, + 0x81C, 0x62520303, 0x81C, 0x43540303, 0x81C, 0x42560303, + 0x81C, 0x41580303, 0x81C, 0x235A0303, 0x81C, 0x225C0303, + 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303, + 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xF8000303, 0x81C, 0xF7020303, + 0x81C, 0xF6040303, 0x81C, 0xF5060303, 0x81C, 0xF4080303, + 0x81C, 0xF30A0303, 0x81C, 0xF20C0303, 0x81C, 0xF10E0303, + 0x81C, 0xF0100303, 0x81C, 0xEF120303, 0x81C, 0xEE140303, + 0x81C, 0xED160303, 0x81C, 0xEC180303, 0x81C, 0xEB1A0303, + 0x81C, 0xEA1C0303, 0x81C, 0xE91E0303, 0x81C, 0xCA200303, + 0x81C, 0xC9220303, 0x81C, 0xC8240303, 0x81C, 0xC7260303, + 0x81C, 0xC6280303, 0x81C, 0xC52A0303, 0x81C, 0xC42C0303, + 0x81C, 0xC32E0303, 0x81C, 0xC2300303, 0x81C, 0xC1320303, + 0x81C, 0xA3340303, 0x81C, 0xA2360303, 0x81C, 0xA1380303, + 0x81C, 0xA03A0303, 0x81C, 0x823C0303, 0x81C, 0x813E0303, + 0x81C, 0x80400303, 0x81C, 0x65420303, 0x81C, 0x64440303, + 0x81C, 0x63460303, 0x81C, 0x62480303, 0x81C, 0x614A0303, + 0x81C, 0x424C0303, 0x81C, 0x414E0303, 0x81C, 0x40500303, + 0x81C, 0x22520303, 0x81C, 0x21540303, 0x81C, 0x20560303, + 0x81C, 0x04580303, 0x81C, 0x035A0303, 0x81C, 0x025C0303, + 0x81C, 0x015E0303, 0x81C, 0x00600303, 0x81C, 0x00620303, + 0x81C, 0x00640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90011000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303, + 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303, + 0x81C, 0xF0160303, 0x81C, 0xEE180303, 0x81C, 0xED1A0303, + 0x81C, 0xEC1C0303, 0x81C, 0xEB1E0303, 0x81C, 0xEA200303, + 0x81C, 0xE9220303, 0x81C, 0xE8240303, 0x81C, 0xE7260303, + 0x81C, 0xE6280303, 0x81C, 0xE52A0303, 0x81C, 0xE42C0303, + 0x81C, 0xE32E0303, 0x81C, 0xE2300303, 0x81C, 0xE1320303, + 0x81C, 0xC6340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, 0x81C, 0xA63C0303, 0x81C, 0xA53E0303, + 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303, + 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303, + 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x63500303, + 0x81C, 0x62520303, 0x81C, 0x61540303, 0x81C, 0x42560303, + 0x81C, 0x41580303, 0x81C, 0x405A0303, 0x81C, 0x225C0303, + 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303, + 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFB000303, 0x81C, 0xFA020303, + 0x81C, 0xF9040303, 0x81C, 0xF8060303, 0x81C, 0xF7080303, + 0x81C, 0xF60A0303, 0x81C, 0xF50C0303, 0x81C, 0xF40E0303, + 0x81C, 0xF3100303, 0x81C, 0xF2120303, 0x81C, 0xF1140303, + 0x81C, 0xF0160303, 0x81C, 0xEF180303, 0x81C, 0xEE1A0303, + 0x81C, 0xED1C0303, 0x81C, 0xEC1E0303, 0x81C, 0xEB200303, + 0x81C, 0xEA220303, 0x81C, 0xE9240303, 0x81C, 0xE8260303, + 0x81C, 0xE7280303, 0x81C, 0xE62A0303, 0x81C, 0xE52C0303, + 0x81C, 0xE42E0303, 0x81C, 0xE3300303, 0x81C, 0xE2320303, + 0x81C, 0xE1340303, 0x81C, 0xC5360303, 0x81C, 0xC4380303, + 0x81C, 0xC33A0303, 0x81C, 0xC23C0303, 0x81C, 0xC13E0303, + 0x81C, 0xA4400303, 0x81C, 0xA3420303, 0x81C, 0xA2440303, + 0x81C, 0xA1460303, 0x81C, 0x83480303, 0x81C, 0x824A0303, + 0x81C, 0x814C0303, 0x81C, 0x804E0303, 0x81C, 0x64500303, + 0x81C, 0x63520303, 0x81C, 0x62540303, 0x81C, 0x61560303, + 0x81C, 0x60580303, 0x81C, 0x235A0303, 0x81C, 0x225C0303, + 0x81C, 0x215E0303, 0x81C, 0x20600303, 0x81C, 0x04620303, + 0x81C, 0x03640303, 0x81C, 0x02660303, 0x81C, 0x01680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFC000303, 0x81C, 0xFB020303, + 0x81C, 0xFA040303, 0x81C, 0xF9060303, 0x81C, 0xF8080303, + 0x81C, 0xF70A0303, 0x81C, 0xF60C0303, 0x81C, 0xF50E0303, + 0x81C, 0xF4100303, 0x81C, 0xF3120303, 0x81C, 0xF2140303, + 0x81C, 0xF1160303, 0x81C, 0xF0180303, 0x81C, 0xEF1A0303, + 0x81C, 0xEE1C0303, 0x81C, 0xED1E0303, 0x81C, 0xEC200303, + 0x81C, 0xEB220303, 0x81C, 0xEA240303, 0x81C, 0xE9260303, + 0x81C, 0xE8280303, 0x81C, 0xE72A0303, 0x81C, 0xE62C0303, + 0x81C, 0xE52E0303, 0x81C, 0xE4300303, 0x81C, 0xE3320303, + 0x81C, 0xE2340303, 0x81C, 0xC6360303, 0x81C, 0xC5380303, + 0x81C, 0xC43A0303, 0x81C, 0xC33C0303, 0x81C, 0xA63E0303, + 0x81C, 0xA5400303, 0x81C, 0xA4420303, 0x81C, 0xA3440303, + 0x81C, 0xA2460303, 0x81C, 0x84480303, 0x81C, 0x834A0303, + 0x81C, 0x824C0303, 0x81C, 0x814E0303, 0x81C, 0x80500303, + 0x81C, 0x63520303, 0x81C, 0x62540303, 0x81C, 0x61560303, + 0x81C, 0x60580303, 0x81C, 0x225A0303, 0x81C, 0x055C0303, + 0x81C, 0x045E0303, 0x81C, 0x03600303, 0x81C, 0x02620303, + 0x81C, 0x01640303, 0x81C, 0x00660303, 0x81C, 0x00680303, + 0x81C, 0x006A0303, 0x81C, 0x006C0303, 0x81C, 0x006E0303, + 0x81C, 0x00700303, 0x81C, 0x00720303, 0x81C, 0x00740303, + 0x81C, 0x00760303, 0x81C, 0x00780303, 0x81C, 0x007A0303, + 0x81C, 0x007C0303, 0x81C, 0x007E0303, 0xA0000000, 0x00000000, + 0x81C, 0xFC000303, 0x81C, 0xFB020303, 0x81C, 0xFA040303, + 0x81C, 0xF9060303, 0x81C, 0xF8080303, 0x81C, 0xF70A0303, + 0x81C, 0xF60C0303, 0x81C, 0xF50E0303, 0x81C, 0xF4100303, + 0x81C, 0xF3120303, 0x81C, 0xF2140303, 0x81C, 0xF1160303, + 0x81C, 0xF0180303, 0x81C, 0xEF1A0303, 0x81C, 0xEE1C0303, + 0x81C, 0xED1E0303, 0x81C, 0xEC200303, 0x81C, 0xEB220303, + 0x81C, 0xEA240303, 0x81C, 0xE9260303, 0x81C, 0xE8280303, + 0x81C, 0xE72A0303, 0x81C, 0xE62C0303, 0x81C, 0xE52E0303, + 0x81C, 0xE4300303, 0x81C, 0xE3320303, 0x81C, 0xE2340303, + 0x81C, 0xC6360303, 0x81C, 0xC5380303, 0x81C, 0xC43A0303, + 0x81C, 0xC33C0303, 0x81C, 0xA63E0303, 0x81C, 0xA5400303, + 0x81C, 0xA4420303, 0x81C, 0xA3440303, 0x81C, 0xA2460303, + 0x81C, 0x84480303, 0x81C, 0x834A0303, 0x81C, 0x824C0303, + 0x81C, 0x814E0303, 0x81C, 0x80500303, 0x81C, 0x63520303, + 0x81C, 0x62540303, 0x81C, 0x61560303, 0x81C, 0x60580303, + 0x81C, 0x235A0303, 0x81C, 0x225C0303, 0x81C, 0x215E0303, + 0x81C, 0x20600303, 0x81C, 0x03620303, 0x81C, 0x02640303, + 0x81C, 0x01660303, 0x81C, 0x00680303, 0x81C, 0x006A0303, + 0x81C, 0x006C0303, 0x81C, 0x006E0303, 0x81C, 0x00700303, + 0x81C, 0x00720303, 0x81C, 0x00740303, 0x81C, 0x00760303, + 0x81C, 0x00780303, 0x81C, 0x007A0303, 0x81C, 0x007C0303, + 0x81C, 0x007E0303, 0xB0000000, 0x00000000, 0x8000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403, + 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403, + 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403, + 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403, + 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403, + 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403, + 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403, + 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403, + 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403, + 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403, + 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403, + 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403, + 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403, + 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403, + 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403, + 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x81C, 0xFF000403, + 0x81C, 0xF5000403, 0x81C, 0xF4020403, 0x81C, 0xF3040403, + 0x81C, 0xF2060403, 0x81C, 0xF1080403, 0x81C, 0xF00A0403, + 0x81C, 0xEF0C0403, 0x81C, 0xEE0E0403, 0x81C, 0xED100403, + 0x81C, 0xEC120403, 0x81C, 0xEB140403, 0x81C, 0xEA160403, + 0x81C, 0xE9180403, 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, + 0x81C, 0xE61E0403, 0x81C, 0xE5200403, 0x81C, 0xE4220403, + 0x81C, 0xE3240403, 0x81C, 0xE2260403, 0x81C, 0xE1280403, + 0x81C, 0xE02A0403, 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, + 0x81C, 0xC1300403, 0x81C, 0xC0320403, 0x81C, 0xA4340403, + 0x81C, 0xA3360403, 0x81C, 0xA2380403, 0x81C, 0xA13A0403, + 0x81C, 0xA03C0403, 0x81C, 0x823E0403, 0x81C, 0x81400403, + 0x81C, 0x80420403, 0x81C, 0x64440403, 0x81C, 0x63460403, + 0x81C, 0x62480403, 0x81C, 0x614A0403, 0x81C, 0x604C0403, + 0x81C, 0x454E0403, 0x81C, 0x44500403, 0x81C, 0x43520403, + 0x81C, 0x42540403, 0x81C, 0x41560403, 0x81C, 0x40580403, + 0x81C, 0x055A0403, 0x81C, 0x045C0403, 0x81C, 0x035E0403, + 0x81C, 0x02600403, 0x81C, 0x01620403, 0x81C, 0x00640403, + 0x81C, 0x00660403, 0x81C, 0x00680403, 0x81C, 0x006A0403, + 0x81C, 0x006C0403, 0x81C, 0x006E0403, 0x81C, 0x00700403, + 0x81C, 0x00720403, 0x81C, 0x00740403, 0x81C, 0x00760403, + 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403, + 0x81C, 0x007E0403, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, 0x81C, 0xF5000403, 0x81C, 0xF4020403, + 0x81C, 0xF3040403, 0x81C, 0xF2060403, 0x81C, 0xF1080403, + 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, 0x81C, 0xEE0E0403, + 0x81C, 0xED100403, 0x81C, 0xEC120403, 0x81C, 0xEB140403, + 0x81C, 0xEA160403, 0x81C, 0xE9180403, 0x81C, 0xE81A0403, + 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, 0x81C, 0xE5200403, + 0x81C, 0xE4220403, 0x81C, 0xE3240403, 0x81C, 0xE2260403, + 0x81C, 0xE1280403, 0x81C, 0xE02A0403, 0x81C, 0xC32C0403, + 0x81C, 0xC22E0403, 0x81C, 0xC1300403, 0x81C, 0xC0320403, + 0x81C, 0xA4340403, 0x81C, 0xA3360403, 0x81C, 0xA2380403, + 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, 0x81C, 0x823E0403, + 0x81C, 0x81400403, 0x81C, 0x80420403, 0x81C, 0x64440403, + 0x81C, 0x63460403, 0x81C, 0x62480403, 0x81C, 0x614A0403, + 0x81C, 0x604C0403, 0x81C, 0x454E0403, 0x81C, 0x44500403, + 0x81C, 0x43520403, 0x81C, 0x42540403, 0x81C, 0x41560403, + 0x81C, 0x40580403, 0x81C, 0x055A0403, 0x81C, 0x045C0403, + 0x81C, 0x035E0403, 0x81C, 0x02600403, 0x81C, 0x01620403, + 0x81C, 0x00640403, 0x81C, 0x00660403, 0x81C, 0x00680403, + 0x81C, 0x006A0403, 0x81C, 0x006C0403, 0x81C, 0x006E0403, + 0x81C, 0x00700403, 0x81C, 0x00720403, 0x81C, 0x00740403, + 0x81C, 0x00760403, 0x81C, 0x00780403, 0x81C, 0x007A0403, + 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403, + 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403, + 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403, + 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403, + 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403, + 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403, + 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403, + 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403, + 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403, + 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403, + 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403, + 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403, + 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403, + 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403, + 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403, + 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000403, + 0x81C, 0xFF000403, 0x81C, 0xFF020403, 0x81C, 0xFE040403, + 0x81C, 0xFD060403, 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, 0x81C, 0xF8100403, + 0x81C, 0xF7120403, 0x81C, 0xF6140403, 0x81C, 0xF5160403, + 0x81C, 0xF4180403, 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, 0x81C, 0xD4200403, 0x81C, 0xD3220403, + 0x81C, 0xD2240403, 0x81C, 0xB6260403, 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, 0x81C, 0xB0320403, 0x81C, 0xAF340403, + 0x81C, 0xAE360403, 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, + 0x81C, 0xA8420403, 0x81C, 0xA7440403, 0x81C, 0xA6460403, + 0x81C, 0xA5480403, 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, 0x81C, 0x84500403, 0x81C, 0x83520403, + 0x81C, 0x82540403, 0x81C, 0x81560403, 0x81C, 0x80580403, + 0x81C, 0x485A0403, 0x81C, 0x475C0403, 0x81C, 0x465E0403, + 0x81C, 0x45600403, 0x81C, 0x44620403, 0x81C, 0x0A640403, + 0x81C, 0x09660403, 0x81C, 0x08680403, 0x81C, 0x076A0403, + 0x81C, 0x066C0403, 0x81C, 0x056E0403, 0x81C, 0x04700403, + 0x81C, 0x03720403, 0x81C, 0x02740403, 0x81C, 0x01760403, + 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403, + 0x81C, 0x007E0403, 0x90012100, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, 0x81C, 0xFF000403, 0x81C, 0xFF020403, + 0x81C, 0xFE040403, 0x81C, 0xFD060403, 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, 0x81C, 0xF7120403, 0x81C, 0xF6140403, + 0x81C, 0xF5160403, 0x81C, 0xF4180403, 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, 0x81C, 0xD4200403, + 0x81C, 0xD3220403, 0x81C, 0xD2240403, 0x81C, 0xB6260403, + 0x81C, 0xB5280403, 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, 0x81C, 0xB1300403, 0x81C, 0xB0320403, + 0x81C, 0xAF340403, 0x81C, 0xAE360403, 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, 0x81C, 0xA8420403, 0x81C, 0xA7440403, + 0x81C, 0xA6460403, 0x81C, 0xA5480403, 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, 0x81C, 0x854E0403, 0x81C, 0x84500403, + 0x81C, 0x83520403, 0x81C, 0x82540403, 0x81C, 0x81560403, + 0x81C, 0x80580403, 0x81C, 0x485A0403, 0x81C, 0x475C0403, + 0x81C, 0x465E0403, 0x81C, 0x45600403, 0x81C, 0x44620403, + 0x81C, 0x0A640403, 0x81C, 0x09660403, 0x81C, 0x08680403, + 0x81C, 0x076A0403, 0x81C, 0x066C0403, 0x81C, 0x056E0403, + 0x81C, 0x04700403, 0x81C, 0x03720403, 0x81C, 0x02740403, + 0x81C, 0x01760403, 0x81C, 0x00780403, 0x81C, 0x007A0403, + 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xF5000403, + 0x81C, 0xF4020403, 0x81C, 0xF3040403, 0x81C, 0xF2060403, + 0x81C, 0xF1080403, 0x81C, 0xF00A0403, 0x81C, 0xEF0C0403, + 0x81C, 0xEE0E0403, 0x81C, 0xED100403, 0x81C, 0xEC120403, + 0x81C, 0xEB140403, 0x81C, 0xEA160403, 0x81C, 0xE9180403, + 0x81C, 0xE81A0403, 0x81C, 0xE71C0403, 0x81C, 0xE61E0403, + 0x81C, 0xE5200403, 0x81C, 0xE4220403, 0x81C, 0xE3240403, + 0x81C, 0xE2260403, 0x81C, 0xE1280403, 0x81C, 0xE02A0403, + 0x81C, 0xC32C0403, 0x81C, 0xC22E0403, 0x81C, 0xC1300403, + 0x81C, 0xC0320403, 0x81C, 0xA4340403, 0x81C, 0xA3360403, + 0x81C, 0xA2380403, 0x81C, 0xA13A0403, 0x81C, 0xA03C0403, + 0x81C, 0x823E0403, 0x81C, 0x81400403, 0x81C, 0x80420403, + 0x81C, 0x64440403, 0x81C, 0x63460403, 0x81C, 0x62480403, + 0x81C, 0x614A0403, 0x81C, 0x604C0403, 0x81C, 0x454E0403, + 0x81C, 0x44500403, 0x81C, 0x43520403, 0x81C, 0x42540403, + 0x81C, 0x41560403, 0x81C, 0x40580403, 0x81C, 0x055A0403, + 0x81C, 0x045C0403, 0x81C, 0x035E0403, 0x81C, 0x02600403, + 0x81C, 0x01620403, 0x81C, 0x00640403, 0x81C, 0x00660403, + 0x81C, 0x00680403, 0x81C, 0x006A0403, 0x81C, 0x006C0403, + 0x81C, 0x006E0403, 0x81C, 0x00700403, 0x81C, 0x00720403, + 0x81C, 0x00740403, 0x81C, 0x00760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0x90011000, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFF000403, + 0x81C, 0xFF000403, 0x81C, 0xFF020403, 0x81C, 0xFE040403, + 0x81C, 0xFD060403, 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, + 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, 0x81C, 0xF8100403, + 0x81C, 0xF7120403, 0x81C, 0xF6140403, 0x81C, 0xF5160403, + 0x81C, 0xF4180403, 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, + 0x81C, 0xD51E0403, 0x81C, 0xD4200403, 0x81C, 0xD3220403, + 0x81C, 0xD2240403, 0x81C, 0xB6260403, 0x81C, 0xB5280403, + 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, + 0x81C, 0xB1300403, 0x81C, 0xB0320403, 0x81C, 0xAF340403, + 0x81C, 0xAE360403, 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, + 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, + 0x81C, 0xA8420403, 0x81C, 0xA7440403, 0x81C, 0xA6460403, + 0x81C, 0xA5480403, 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, + 0x81C, 0x854E0403, 0x81C, 0x84500403, 0x81C, 0x83520403, + 0x81C, 0x82540403, 0x81C, 0x81560403, 0x81C, 0x80580403, + 0x81C, 0x485A0403, 0x81C, 0x475C0403, 0x81C, 0x465E0403, + 0x81C, 0x45600403, 0x81C, 0x44620403, 0x81C, 0x0A640403, + 0x81C, 0x09660403, 0x81C, 0x08680403, 0x81C, 0x076A0403, + 0x81C, 0x066C0403, 0x81C, 0x056E0403, 0x81C, 0x04700403, + 0x81C, 0x03720403, 0x81C, 0x02740403, 0x81C, 0x01760403, + 0x81C, 0x00780403, 0x81C, 0x007A0403, 0x81C, 0x007C0403, + 0x81C, 0x007E0403, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFF000403, 0x81C, 0xFF000403, 0x81C, 0xFF020403, + 0x81C, 0xFE040403, 0x81C, 0xFD060403, 0x81C, 0xFC080403, + 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, 0x81C, 0xF90E0403, + 0x81C, 0xF8100403, 0x81C, 0xF7120403, 0x81C, 0xF6140403, + 0x81C, 0xF5160403, 0x81C, 0xF4180403, 0x81C, 0xF31A0403, + 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, 0x81C, 0xD4200403, + 0x81C, 0xD3220403, 0x81C, 0xD2240403, 0x81C, 0xB6260403, + 0x81C, 0xB5280403, 0x81C, 0xB42A0403, 0x81C, 0xB32C0403, + 0x81C, 0xB22E0403, 0x81C, 0xB1300403, 0x81C, 0xB0320403, + 0x81C, 0xAF340403, 0x81C, 0xAE360403, 0x81C, 0xAD380403, + 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, 0x81C, 0xAA3E0403, + 0x81C, 0xA9400403, 0x81C, 0xA8420403, 0x81C, 0xA7440403, + 0x81C, 0xA6460403, 0x81C, 0xA5480403, 0x81C, 0xA44A0403, + 0x81C, 0xA34C0403, 0x81C, 0x854E0403, 0x81C, 0x84500403, + 0x81C, 0x83520403, 0x81C, 0x82540403, 0x81C, 0x81560403, + 0x81C, 0x80580403, 0x81C, 0x485A0403, 0x81C, 0x475C0403, + 0x81C, 0x465E0403, 0x81C, 0x45600403, 0x81C, 0x44620403, + 0x81C, 0x0A640403, 0x81C, 0x09660403, 0x81C, 0x08680403, + 0x81C, 0x076A0403, 0x81C, 0x066C0403, 0x81C, 0x056E0403, + 0x81C, 0x04700403, 0x81C, 0x03720403, 0x81C, 0x02740403, + 0x81C, 0x01760403, 0x81C, 0x00780403, 0x81C, 0x007A0403, + 0x81C, 0x007C0403, 0x81C, 0x007E0403, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xFF000403, + 0x81C, 0xFF020403, 0x81C, 0xFE040403, 0x81C, 0xFD060403, + 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, 0x81C, 0xF8100403, 0x81C, 0xF7120403, + 0x81C, 0xF6140403, 0x81C, 0xF5160403, 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, 0x81C, 0xD3220403, 0x81C, 0xD2240403, + 0x81C, 0xB6260403, 0x81C, 0xB5280403, 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, 0x81C, 0xB1300403, + 0x81C, 0xB0320403, 0x81C, 0xAF340403, 0x81C, 0xAE360403, + 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, 0x81C, 0xA8420403, + 0x81C, 0xA7440403, 0x81C, 0xA6460403, 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, 0x81C, 0x854E0403, + 0x81C, 0x84500403, 0x81C, 0x83520403, 0x81C, 0x82540403, + 0x81C, 0x81560403, 0x81C, 0x80580403, 0x81C, 0x485A0403, + 0x81C, 0x475C0403, 0x81C, 0x465E0403, 0x81C, 0x45600403, + 0x81C, 0x44620403, 0x81C, 0x0A640403, 0x81C, 0x09660403, + 0x81C, 0x08680403, 0x81C, 0x076A0403, 0x81C, 0x066C0403, + 0x81C, 0x056E0403, 0x81C, 0x04700403, 0x81C, 0x03720403, + 0x81C, 0x02740403, 0x81C, 0x01760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0xA0000000, 0x00000000, 0x81C, 0xFF000403, 0x81C, 0xFF000403, + 0x81C, 0xFF020403, 0x81C, 0xFE040403, 0x81C, 0xFD060403, + 0x81C, 0xFC080403, 0x81C, 0xFB0A0403, 0x81C, 0xFA0C0403, + 0x81C, 0xF90E0403, 0x81C, 0xF8100403, 0x81C, 0xF7120403, + 0x81C, 0xF6140403, 0x81C, 0xF5160403, 0x81C, 0xF4180403, + 0x81C, 0xF31A0403, 0x81C, 0xF21C0403, 0x81C, 0xD51E0403, + 0x81C, 0xD4200403, 0x81C, 0xD3220403, 0x81C, 0xD2240403, + 0x81C, 0xB6260403, 0x81C, 0xB5280403, 0x81C, 0xB42A0403, + 0x81C, 0xB32C0403, 0x81C, 0xB22E0403, 0x81C, 0xB1300403, + 0x81C, 0xB0320403, 0x81C, 0xAF340403, 0x81C, 0xAE360403, + 0x81C, 0xAD380403, 0x81C, 0xAC3A0403, 0x81C, 0xAB3C0403, + 0x81C, 0xAA3E0403, 0x81C, 0xA9400403, 0x81C, 0xA8420403, + 0x81C, 0xA7440403, 0x81C, 0xA6460403, 0x81C, 0xA5480403, + 0x81C, 0xA44A0403, 0x81C, 0xA34C0403, 0x81C, 0x854E0403, + 0x81C, 0x84500403, 0x81C, 0x83520403, 0x81C, 0x82540403, + 0x81C, 0x81560403, 0x81C, 0x80580403, 0x81C, 0x485A0403, + 0x81C, 0x475C0403, 0x81C, 0x465E0403, 0x81C, 0x45600403, + 0x81C, 0x44620403, 0x81C, 0x0A640403, 0x81C, 0x09660403, + 0x81C, 0x08680403, 0x81C, 0x076A0403, 0x81C, 0x066C0403, + 0x81C, 0x056E0403, 0x81C, 0x04700403, 0x81C, 0x03720403, + 0x81C, 0x02740403, 0x81C, 0x01760403, 0x81C, 0x00780403, + 0x81C, 0x007A0403, 0x81C, 0x007C0403, 0x81C, 0x007E0403, + 0xB0000000, 0x00000000, 0xC50, 0x00000022, 0xC50, 0x00000020, + 0xE50, 0x00000022, 0xE50, 0x00000020, + +}; + +void odm_read_and_config_mp_8822b_agc_tab(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_agc_tab) / sizeof(u32); + u32 *array = array_mp_8822b_agc_tab; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_bb_agc_8822b(dm, v1, MASKDWORD, v2); + } + } +} + +u32 odm_get_version_mp_8822b_agc_tab(void) { return 67; } + +/****************************************************************************** + * phy_reg.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_phy_reg[] = { + 0x800, 0x9020D010, 0x804, 0x800181A0, 0x808, 0x0E028233, + 0x80C, 0x10000013, 0x810, 0x21101263, 0x814, 0x020C3D10, + 0x818, 0x84A10385, 0x81C, 0x1E1E081F, 0x820, 0x0001AAAA, + 0x824, 0x00030FE0, 0x828, 0x0000CCCC, 0x82C, 0x75CB7010, + 0x830, 0x79A0EA2A, 0x834, 0x072E6986, 0x838, 0x87766441, + 0x83C, 0x9194B2B6, 0x840, 0x171740E0, 0x844, 0x4D3D7CDB, + 0x848, 0x4AD0408B, 0x84C, 0x6AFBF7A5, 0x850, 0x28A74706, + 0x854, 0x0001520C, 0x858, 0x4060C000, 0x85C, 0x74010160, + 0x860, 0x68A7C321, 0x864, 0x79F27432, 0x868, 0x8CA7A314, + 0x86C, 0x778C2878, 0x870, 0x77777777, 0x874, 0x27612C2E, + 0x878, 0xC0003152, 0x87C, 0x5C8FC000, 0x880, 0x00000000, + 0x884, 0x00000000, 0x888, 0x00000000, 0x88C, 0x00000000, + 0x890, 0x00000000, 0x894, 0x00000000, 0x898, 0x00000000, + 0x89C, 0x00000000, 0x8A0, 0x00000013, 0x8A4, 0x7F7F7F7F, + 0x8A8, 0x2202033E, 0x8AC, 0xF00F000A, 0x8B0, 0x00000600, + 0x8B4, 0x000FC080, 0x8B8, 0xEC0057F7, 0x8BC, 0xACB520A3, + 0x8C0, 0xFFE04020, 0x8C4, 0x47C00000, 0x8C8, 0x000251A5, + 0x8CC, 0x08108000, 0x8D0, 0x0000B800, 0x8D4, 0x860308A0, + 0x8D8, 0x21095612, 0x8DC, 0x00000000, 0x8E0, 0x32D16777, + 0x8E4, 0x4C098935, 0x8E8, 0xFFFFC42C, 0x8EC, 0x99999999, + 0x8F0, 0x00009999, 0x8F4, 0x00D80FA1, 0x8F8, 0x40000080, + 0x8FC, 0x00000130, 0x900, 0x00800000, 0x904, 0x00000000, + 0x908, 0x00000000, 0x90C, 0xD3000000, 0x910, 0x0000FC00, + 0x914, 0xC6380000, 0x918, 0x1C1028C0, 0x91C, 0x64B11A1C, + 0x920, 0xE0767233, 0x924, 0x855A2500, 0x928, 0x4AB0E4E4, + 0x92C, 0xFFFEB200, 0x930, 0xFFFFFFFE, 0x934, 0x001FFFFF, + 0x938, 0x00008480, 0x93C, 0xE41C0642, 0x940, 0x0E470430, + 0x944, 0x00000000, 0x948, 0xAC000000, 0x94C, 0x10000083, + 0x950, 0x32010080, 0x954, 0x84510080, 0x958, 0x00000001, + 0x95C, 0x04248000, 0x960, 0x00000000, 0x964, 0x00000000, + 0x968, 0x00000000, 0x96C, 0x00000000, 0x970, 0x00001FFF, + 0x974, 0x44000FFF, 0x978, 0x00000000, 0x97C, 0x00000000, + 0x980, 0x00000000, 0x984, 0x00000000, 0x988, 0x00000000, + 0x98C, 0x23440000, 0x990, 0x27100000, 0x994, 0xFFFF0100, + 0x998, 0xFFFFFF5C, 0x99C, 0xFFFFFFFF, 0x9A0, 0x000000FF, + 0x9A4, 0x80000088, 0x9A8, 0x0C2F0000, 0x9AC, 0x01560000, + 0x9B0, 0x70000000, 0x9B4, 0x00000000, 0x9B8, 0x00000000, + 0x9BC, 0x00000000, 0x9C0, 0x00000000, 0x9C4, 0x00000000, + 0x9C8, 0x00000000, 0x9CC, 0x00000000, 0x9D0, 0x00000000, + 0x9D4, 0x00000000, 0x9D8, 0x00000000, 0x9DC, 0x00000000, + 0x9E0, 0x00000000, 0x9E4, 0x02000402, 0x9E8, 0x000022D4, + 0x9EC, 0x00000000, 0x9F0, 0x00010080, 0x9F4, 0x00000000, + 0x9F8, 0x00000000, 0x9FC, 0xEFFFF7F7, 0xA00, 0x00D047C8, + 0xA04, 0x81FF800C, 0xA08, 0x8C838300, 0xA0C, 0x2E20100F, + 0xA10, 0x9500BB78, 0xA14, 0x1114D028, 0xA18, 0x00881117, + 0xA1C, 0x89140F00, 0xA20, 0x84880000, 0xA24, 0x384F6577, + 0xA28, 0x00001525, 0xA2C, 0x00920000, 0xA70, 0x101FFF00, + 0xA74, 0x00000148, 0xA78, 0x00000900, 0xA7C, 0x225B0606, + 0xA80, 0x218675B2, 0xA84, 0x80208C00, 0xA88, 0x040C0000, + 0xA8C, 0x12345678, 0xA90, 0xABCDEF00, 0xA94, 0x001B1B89, + 0xA98, 0x030A0000, 0xA9C, 0x00060000, 0xAA0, 0x00000000, + 0xAA4, 0x0004000F, 0xAA8, 0x00000200, 0xB00, 0xE1000440, + 0xB04, 0x00800000, 0xB08, 0xFF02030B, 0xB0C, 0x01EAA406, + 0xB10, 0x00030690, 0xB14, 0x006000FA, 0xB18, 0x00000002, + 0xB1C, 0x00000002, 0xB20, 0x4B00001F, 0xB24, 0x4E8E3E40, + 0xB28, 0x03020100, 0xB2C, 0x07060504, 0xB30, 0x0B0A0908, + 0xB34, 0x0F0E0D0C, 0xB38, 0x13121110, 0xB3C, 0x0000003A, + 0xB40, 0x00000000, 0xB44, 0x80000000, 0xB48, 0x3F0000FA, + 0xB4C, 0x88C80020, 0xB50, 0x00000000, 0xB54, 0x00004241, + 0xB58, 0xE0008208, 0xB5C, 0x41EFFFF9, 0xB60, 0x00000000, + 0xB64, 0x00200063, 0xB68, 0x0000003A, 0xB6C, 0x00000102, + 0xB70, 0x4E6D1870, 0xB74, 0x03020100, 0xB78, 0x07060504, + 0xB7C, 0x0B0A0908, 0xB80, 0x0F0E0D0C, 0xB84, 0x13121110, + 0xB88, 0x00000000, 0xB8C, 0x00000000, 0xC00, 0x00000007, + 0xC04, 0x00000020, 0xC08, 0x60403231, 0xC0C, 0x00012345, + 0xC10, 0x00000100, 0xC14, 0x01000000, 0xC18, 0x00000000, + 0xC1C, 0x40040053, 0xC20, 0x40020103, 0xC24, 0x00000000, + 0xC28, 0x00000000, 0xC2C, 0x00000000, 0xC30, 0x00000000, + 0xC34, 0x00000000, 0xC38, 0x00000000, 0xC3C, 0x00000000, + 0xC40, 0x00000000, 0xC44, 0x00000000, 0xC48, 0x00000000, + 0xC4C, 0x00000000, 0xC50, 0x00000020, 0xC54, 0x00000000, + 0xC58, 0xD8020402, 0xC5C, 0xDE000120, 0xC68, 0x5979993F, + 0xC6C, 0x0000122A, 0xC70, 0x99795979, 0xC74, 0x99795979, + 0xC78, 0x99799979, 0xC7C, 0x99791979, 0xC80, 0x19791979, + 0xC84, 0x19791979, 0xC88, 0x00000000, 0xC8C, 0x07000000, + 0xC94, 0x01000100, 0xC98, 0x201C8000, 0xC9C, 0x00000000, + 0xCA0, 0x0000A555, 0xCA4, 0x08040201, 0xCA8, 0x80402010, + 0xCAC, 0x00000000, 0xCB0, 0x77777777, 0xCB4, 0x00007777, + 0xCB8, 0x00000000, 0xCBC, 0x00000000, 0xCC0, 0x00000000, + 0xCC4, 0x00000000, 0xCC8, 0x00000000, 0xCCC, 0x00000000, + 0xCD0, 0x00000000, 0xCD4, 0x00000000, 0xCD8, 0x00000000, + 0xCDC, 0x00000000, 0xCE0, 0x00000000, 0xCE4, 0x00000000, + 0xCE8, 0x00000000, 0xCEC, 0x00000000, 0xE00, 0x00000007, + 0xE04, 0x00000020, 0xE08, 0x60403231, 0xE0C, 0x00012345, + 0xE10, 0x00000100, 0xE14, 0x01000000, 0xE18, 0x00000000, + 0xE1C, 0x40040053, 0xE20, 0x40020103, 0xE24, 0x00000000, + 0xE28, 0x00000000, 0xE2C, 0x00000000, 0xE30, 0x00000000, + 0xE34, 0x00000000, 0xE38, 0x00000000, 0xE3C, 0x00000000, + 0xE40, 0x00000000, 0xE44, 0x00000000, 0xE48, 0x00000000, + 0xE4C, 0x00000000, 0xE50, 0x00000020, 0xE54, 0x00000000, + 0xE58, 0xD8020402, 0xE5C, 0xDE000120, 0xE68, 0x5979993F, + 0xE6C, 0x0000122A, 0xE70, 0x99795979, 0xE74, 0x99795979, + 0xE78, 0x99799979, 0xE7C, 0x99791979, 0xE80, 0x19791979, + 0xE84, 0x19791979, 0xE88, 0x00000000, 0xE8C, 0x07000000, + 0xE94, 0x01000100, 0xE98, 0x201C8000, 0xE9C, 0x00000000, + 0xEA0, 0x0000A555, 0xEA4, 0x08040201, 0xEA8, 0x80402010, + 0xEAC, 0x00000000, 0xEB0, 0x77777777, 0xEB4, 0x00007777, + 0xEB8, 0x00000000, 0xEBC, 0x00000000, 0xEC0, 0x00000000, + 0xEC4, 0x00000000, 0xEC8, 0x00000000, 0xECC, 0x00000000, + 0xED0, 0x00000000, 0xED4, 0x00000000, 0xED8, 0x00000000, + 0xEDC, 0x00000000, 0xEE0, 0x00000000, 0xEE4, 0x00000000, + 0xEE8, 0x00000000, 0xEEC, 0x00000000, 0x1900, 0x00000000, + 0x1904, 0x00238000, 0x1908, 0x00000000, 0x190C, 0x00000000, + 0x1910, 0x00000000, 0x1914, 0x00000000, 0x1918, 0x00000000, + 0x191C, 0x00000000, 0x1920, 0x00000000, 0x1924, 0x00000000, + 0x1928, 0x00000000, 0x192C, 0x00000000, 0x1930, 0x00000000, + 0x1934, 0x00000000, 0x1938, 0x00000000, 0x193C, 0x00000000, + 0x1940, 0x00000000, 0x1944, 0x00000000, 0x1948, 0x00000000, + 0x194C, 0x00000000, 0x1950, 0x00000000, 0x1954, 0x00000000, + 0x1958, 0x00000000, 0x195C, 0x00000000, 0x1960, 0x00000000, + 0x1964, 0x00000000, 0x1968, 0x00000000, 0x196C, 0x00000000, + 0x1970, 0x00000000, 0x1974, 0x00000000, 0x1978, 0x00000000, + 0x197C, 0x00000000, 0x1980, 0x00000000, 0x1984, 0x03000000, + 0x1988, 0x21401E88, 0x198C, 0x00004000, 0x1990, 0x00000000, + 0x1994, 0x00000000, 0x1998, 0x00000053, 0x199C, 0x00000000, + 0x19A0, 0x00000000, 0x19A4, 0x00000000, 0x19A8, 0x00000000, + 0x19AC, 0x0E47E47F, 0x19B0, 0x00000000, 0x19B4, 0x0E47E47F, + 0x19B8, 0x00000000, 0x19BC, 0x00000000, 0x19C0, 0x00000000, + 0x19C4, 0x00000000, 0x19C8, 0x00000000, 0x19CC, 0x00000000, + 0x19D0, 0x00000000, 0x19D4, 0xAAAAAAAA, 0x19D8, 0x00000AAA, + 0x19DC, 0x133E0F37, 0x19E0, 0x00000000, 0x19E4, 0x00000000, + 0x19E8, 0x00000000, 0x19EC, 0x00000000, 0x19F0, 0x00000000, + 0x19F4, 0x00000000, 0x19F8, 0x01A00000, 0x19FC, 0x00000000, + 0x1C00, 0x00000100, 0x1C04, 0x01000000, 0x1C08, 0x00000100, + 0x1C0C, 0x01000000, 0x1C10, 0x00000100, 0x1C14, 0x01000000, + 0x1C18, 0x00000100, 0x1C1C, 0x01000000, 0x1C20, 0x00000100, + 0x1C24, 0x01000000, 0x1C28, 0x00000100, 0x1C2C, 0x01000000, + 0x1C30, 0x00000100, 0x1C34, 0x01000000, 0x1C38, 0x00000000, + 0x1C3C, 0x00000000, 0x1C40, 0x000C0100, 0x1C44, 0x000000F3, + 0x1C48, 0x1A8249A8, 0x1C4C, 0x1461C826, 0x1C50, 0x0001469E, + 0x1C54, 0x58D158D1, 0x1C58, 0x04490088, 0x1C5C, 0x04004400, + 0x1C60, 0x00000000, 0x1C64, 0x04004400, 0x1C68, 0x00000100, + 0x1C6C, 0x01000000, 0x1C70, 0x00000100, 0x1C74, 0x01000000, + 0x1C78, 0x00000000, 0x1C7C, 0x00000010, 0x1C80, 0x5FFF5FFF, + 0x1C84, 0x5FFF5FFF, 0x1C88, 0x5FFF5FFF, 0x1C8C, 0x5FFF5FFF, + 0x1C90, 0x5FFF5FFF, 0x1C94, 0x5FFF5FFF, 0x1C98, 0x5FFF5FFF, + 0x1C9C, 0x5FFF5FFF, 0x1CA0, 0x00000100, 0x1CA4, 0x01000000, + 0x1CA8, 0x00000100, 0x1CAC, 0x5FFF5FFF, 0x1CB0, 0x00000100, + 0x1CB4, 0x01000000, 0x1CB8, 0x00000000, 0x1CBC, 0x00000000, + 0x1CC0, 0x00000100, 0x1CC4, 0x01000000, 0x1CC8, 0x00000100, + 0x1CCC, 0x01000000, 0x1CD0, 0x00000100, 0x1CD4, 0x01000000, + 0x1CD8, 0x00000100, 0x1CDC, 0x01000000, 0x1CE0, 0x00000100, + 0x1CE4, 0x01000000, 0x1CE8, 0x00000100, 0x1CEC, 0x01000000, + 0x1CF0, 0x00000100, 0x1CF4, 0x01000000, 0x1CF8, 0x00000000, + 0x1CFC, 0x00000000, 0xC60, 0x70038040, 0xC60, 0x70038040, + 0xC60, 0x70146040, 0xC60, 0x70246040, 0xC60, 0x70346040, + 0xC60, 0x70446040, 0xC60, 0x70532040, 0xC60, 0x70646040, + 0xC60, 0x70738040, 0xC60, 0x70838040, 0xC60, 0x70938040, + 0xC60, 0x70A38040, 0xC60, 0x70B36040, 0xC60, 0x70C06040, + 0xC60, 0x70D06040, 0xC60, 0x70E76040, 0xC60, 0x70F06040, + 0xE60, 0x70038040, 0xE60, 0x70038040, 0xE60, 0x70146040, + 0xE60, 0x70246040, 0xE60, 0x70346040, 0xE60, 0x70446040, + 0xE60, 0x70532040, 0xE60, 0x70646040, 0xE60, 0x70738040, + 0xE60, 0x70838040, 0xE60, 0x70938040, 0xE60, 0x70A38040, + 0xE60, 0x70B36040, 0xE60, 0x70C06040, 0xE60, 0x70D06040, + 0xE60, 0x70E76040, 0xE60, 0x70F06040, 0xC64, 0x00800000, + 0xC64, 0x08800001, 0xC64, 0x00800002, 0xC64, 0x00800003, + 0xC64, 0x00800004, 0xC64, 0x00800005, 0xC64, 0x00800006, + 0xC64, 0x08800007, 0xC64, 0x00004000, 0xE64, 0x00800000, + 0xE64, 0x08800001, 0xE64, 0x00800002, 0xE64, 0x00800003, + 0xE64, 0x00800004, 0xE64, 0x00800005, 0xE64, 0x00800006, + 0xE64, 0x08800007, 0xE64, 0x00004000, 0x1B00, 0xF8000008, + 0x1B00, 0xF80A7008, 0x1B00, 0xF8015008, 0x1B00, 0xF8000008, + 0x1B04, 0xE24629D2, 0x1B08, 0x00000080, 0x1B0C, 0x00000000, + 0x1B10, 0x00010C00, 0x1B14, 0x00000000, 0x1B18, 0x00292903, + 0x1B1C, 0xA2193C32, 0x1B20, 0x01840008, 0x1B24, 0x01860008, + 0x1B28, 0x80060300, 0x1B2C, 0x00000003, 0x1B30, 0x20000000, + 0x1B34, 0x00000800, 0x1B3C, 0x20000000, 0x1BC0, 0x01000000, + 0x1BCC, 0x00000000, 0x1B00, 0xF800000A, 0x1B1C, 0xA2193C32, + 0x1B20, 0x01840008, 0x1B24, 0x01860008, 0x1B28, 0x80060300, + 0x1B2C, 0x00000003, 0x1B30, 0x20000000, 0x1B34, 0x00000800, + 0x1B3C, 0x20000000, 0x1BC0, 0x01000000, 0x1BCC, 0x00000000, + 0x1B00, 0xF8000000, 0x1B80, 0x00000007, 0x1B80, 0x090A0005, + 0x1B80, 0x090A0007, 0x1B80, 0x0FFE0015, 0x1B80, 0x0FFE0017, + 0x1B80, 0x00220025, 0x1B80, 0x00220027, 0x1B80, 0x00040035, + 0x1B80, 0x00040037, 0x1B80, 0x05C00045, 0x1B80, 0x05C00047, + 0x1B80, 0x00070055, 0x1B80, 0x00070057, 0x1B80, 0x64000065, + 0x1B80, 0x64000067, 0x1B80, 0x00020075, 0x1B80, 0x00020077, + 0x1B80, 0x00080085, 0x1B80, 0x00080087, 0x1B80, 0x80000095, + 0x1B80, 0x80000097, 0x1B80, 0x090800A5, 0x1B80, 0x090800A7, + 0x1B80, 0x0F0200B5, 0x1B80, 0x0F0200B7, 0x1B80, 0x002200C5, + 0x1B80, 0x002200C7, 0x1B80, 0x000400D5, 0x1B80, 0x000400D7, + 0x1B80, 0x05C000E5, 0x1B80, 0x05C000E7, 0x1B80, 0x000700F5, + 0x1B80, 0x000700F7, 0x1B80, 0x64020105, 0x1B80, 0x64020107, + 0x1B80, 0x00020115, 0x1B80, 0x00020117, 0x1B80, 0x00040125, + 0x1B80, 0x00040127, 0x1B80, 0x4A000135, 0x1B80, 0x4A000137, + 0x1B80, 0x4B040145, 0x1B80, 0x4B040147, 0x1B80, 0x85030155, + 0x1B80, 0x85030157, 0x1B80, 0x40090165, 0x1B80, 0x40090167, + 0x1B80, 0xE0210175, 0x1B80, 0xE0210177, 0x1B80, 0x4B050185, + 0x1B80, 0x4B050187, 0x1B80, 0x86030195, 0x1B80, 0x86030197, + 0x1B80, 0x400B01A5, 0x1B80, 0x400B01A7, 0x1B80, 0xE02101B5, + 0x1B80, 0xE02101B7, 0x1B80, 0x4B0001C5, 0x1B80, 0x4B0001C7, + 0x1B80, 0x000701D5, 0x1B80, 0x000701D7, 0x1B80, 0x4C0001E5, + 0x1B80, 0x4C0001E7, 0x1B80, 0x000401F5, 0x1B80, 0x000401F7, + 0x1B80, 0x30000205, 0x1B80, 0x30000207, 0x1B80, 0xFE000215, + 0x1B80, 0xFE000217, 0x1B80, 0xFF000225, 0x1B80, 0xFF000227, + 0x1B80, 0xE1750235, 0x1B80, 0xE1750237, 0x1B80, 0xF00D0245, + 0x1B80, 0xF00D0247, 0x1B80, 0xF10D0255, 0x1B80, 0xF10D0257, + 0x1B80, 0xF20D0265, 0x1B80, 0xF20D0267, 0x1B80, 0xF30D0275, + 0x1B80, 0xF30D0277, 0x1B80, 0xF40D0285, 0x1B80, 0xF40D0287, + 0x1B80, 0xF50D0295, 0x1B80, 0xF50D0297, 0x1B80, 0xF60D02A5, + 0x1B80, 0xF60D02A7, 0x1B80, 0xF70D02B5, 0x1B80, 0xF70D02B7, + 0x1B80, 0xF80D02C5, 0x1B80, 0xF80D02C7, 0x1B80, 0xF90D02D5, + 0x1B80, 0xF90D02D7, 0x1B80, 0xFA0D02E5, 0x1B80, 0xFA0D02E7, + 0x1B80, 0xFB0D02F5, 0x1B80, 0xFB0D02F7, 0x1B80, 0x00010305, + 0x1B80, 0x00010307, 0x1B80, 0x303D0315, 0x1B80, 0x303D0317, + 0x1B80, 0x30550325, 0x1B80, 0x30550327, 0x1B80, 0x30A00335, + 0x1B80, 0x30A00337, 0x1B80, 0x30A30345, 0x1B80, 0x30A30347, + 0x1B80, 0x30570355, 0x1B80, 0x30570357, 0x1B80, 0x30620365, + 0x1B80, 0x30620367, 0x1B80, 0x306D0375, 0x1B80, 0x306D0377, + 0x1B80, 0x30AD0385, 0x1B80, 0x30AD0387, 0x1B80, 0x30A70395, + 0x1B80, 0x30A70397, 0x1B80, 0x30BB03A5, 0x1B80, 0x30BB03A7, + 0x1B80, 0x30C603B5, 0x1B80, 0x30C603B7, 0x1B80, 0x30D103C5, + 0x1B80, 0x30D103C7, 0x1B80, 0xE11403D5, 0x1B80, 0xE11403D7, + 0x1B80, 0x4D0403E5, 0x1B80, 0x4D0403E7, 0x1B80, 0x208003F5, + 0x1B80, 0x208003F7, 0x1B80, 0x00000405, 0x1B80, 0x00000407, + 0x1B80, 0x4D000415, 0x1B80, 0x4D000417, 0x1B80, 0x55070425, + 0x1B80, 0x55070427, 0x1B80, 0xE10C0435, 0x1B80, 0xE10C0437, + 0x1B80, 0xE10C0445, 0x1B80, 0xE10C0447, 0x1B80, 0x4D040455, + 0x1B80, 0x4D040457, 0x1B80, 0x20880465, 0x1B80, 0x20880467, + 0x1B80, 0x02000475, 0x1B80, 0x02000477, 0x1B80, 0x4D000485, + 0x1B80, 0x4D000487, 0x1B80, 0x550F0495, 0x1B80, 0x550F0497, + 0x1B80, 0xE10C04A5, 0x1B80, 0xE10C04A7, 0x1B80, 0x4F0204B5, + 0x1B80, 0x4F0204B7, 0x1B80, 0x4E0004C5, 0x1B80, 0x4E0004C7, + 0x1B80, 0x530204D5, 0x1B80, 0x530204D7, 0x1B80, 0x520104E5, + 0x1B80, 0x520104E7, 0x1B80, 0xE11004F5, 0x1B80, 0xE11004F7, + 0x1B80, 0x4D080505, 0x1B80, 0x4D080507, 0x1B80, 0x57100515, + 0x1B80, 0x57100517, 0x1B80, 0x57000525, 0x1B80, 0x57000527, + 0x1B80, 0x4D000535, 0x1B80, 0x4D000537, 0x1B80, 0x00010545, + 0x1B80, 0x00010547, 0x1B80, 0xE1140555, 0x1B80, 0xE1140557, + 0x1B80, 0x00010565, 0x1B80, 0x00010567, 0x1B80, 0x30770575, + 0x1B80, 0x30770577, 0x1B80, 0x00230585, 0x1B80, 0x00230587, + 0x1B80, 0xE1680595, 0x1B80, 0xE1680597, 0x1B80, 0x000205A5, + 0x1B80, 0x000205A7, 0x1B80, 0x54E905B5, 0x1B80, 0x54E905B7, + 0x1B80, 0x0BA605C5, 0x1B80, 0x0BA605C7, 0x1B80, 0x002305D5, + 0x1B80, 0x002305D7, 0x1B80, 0xE16805E5, 0x1B80, 0xE16805E7, + 0x1B80, 0x000205F5, 0x1B80, 0x000205F7, 0x1B80, 0x4D300605, + 0x1B80, 0x4D300607, 0x1B80, 0x30900615, 0x1B80, 0x30900617, + 0x1B80, 0x30730625, 0x1B80, 0x30730627, 0x1B80, 0x00220635, + 0x1B80, 0x00220637, 0x1B80, 0xE1680645, 0x1B80, 0xE1680647, + 0x1B80, 0x00020655, 0x1B80, 0x00020657, 0x1B80, 0x54E80665, + 0x1B80, 0x54E80667, 0x1B80, 0x0BA60675, 0x1B80, 0x0BA60677, + 0x1B80, 0x00220685, 0x1B80, 0x00220687, 0x1B80, 0xE1680695, + 0x1B80, 0xE1680697, 0x1B80, 0x000206A5, 0x1B80, 0x000206A7, + 0x1B80, 0x4D3006B5, 0x1B80, 0x4D3006B7, 0x1B80, 0x309006C5, + 0x1B80, 0x309006C7, 0x1B80, 0x63F106D5, 0x1B80, 0x63F106D7, + 0x1B80, 0xE11406E5, 0x1B80, 0xE11406E7, 0x1B80, 0xE16806F5, + 0x1B80, 0xE16806F7, 0x1B80, 0x63F40705, 0x1B80, 0x63F40707, + 0x1B80, 0xE1140715, 0x1B80, 0xE1140717, 0x1B80, 0xE1680725, + 0x1B80, 0xE1680727, 0x1B80, 0x0BA80735, 0x1B80, 0x0BA80737, + 0x1B80, 0x63F80745, 0x1B80, 0x63F80747, 0x1B80, 0xE1140755, + 0x1B80, 0xE1140757, 0x1B80, 0xE1680765, 0x1B80, 0xE1680767, + 0x1B80, 0x0BA90775, 0x1B80, 0x0BA90777, 0x1B80, 0x63FC0785, + 0x1B80, 0x63FC0787, 0x1B80, 0xE1140795, 0x1B80, 0xE1140797, + 0x1B80, 0xE16807A5, 0x1B80, 0xE16807A7, 0x1B80, 0x63FF07B5, + 0x1B80, 0x63FF07B7, 0x1B80, 0xE11407C5, 0x1B80, 0xE11407C7, + 0x1B80, 0xE16807D5, 0x1B80, 0xE16807D7, 0x1B80, 0x630007E5, + 0x1B80, 0x630007E7, 0x1B80, 0xE11407F5, 0x1B80, 0xE11407F7, + 0x1B80, 0xE1680805, 0x1B80, 0xE1680807, 0x1B80, 0x63030815, + 0x1B80, 0x63030817, 0x1B80, 0xE1140825, 0x1B80, 0xE1140827, + 0x1B80, 0xE1680835, 0x1B80, 0xE1680837, 0x1B80, 0xF4D40845, + 0x1B80, 0xF4D40847, 0x1B80, 0x63070855, 0x1B80, 0x63070857, + 0x1B80, 0xE1140865, 0x1B80, 0xE1140867, 0x1B80, 0xE1680875, + 0x1B80, 0xE1680877, 0x1B80, 0xF5DB0885, 0x1B80, 0xF5DB0887, + 0x1B80, 0x630B0895, 0x1B80, 0x630B0897, 0x1B80, 0xE11408A5, + 0x1B80, 0xE11408A7, 0x1B80, 0xE16808B5, 0x1B80, 0xE16808B7, + 0x1B80, 0x630E08C5, 0x1B80, 0x630E08C7, 0x1B80, 0xE11408D5, + 0x1B80, 0xE11408D7, 0x1B80, 0xE16808E5, 0x1B80, 0xE16808E7, + 0x1B80, 0x4D3008F5, 0x1B80, 0x4D3008F7, 0x1B80, 0x55010905, + 0x1B80, 0x55010907, 0x1B80, 0x57040915, 0x1B80, 0x57040917, + 0x1B80, 0x57000925, 0x1B80, 0x57000927, 0x1B80, 0x96000935, + 0x1B80, 0x96000937, 0x1B80, 0x57080945, 0x1B80, 0x57080947, + 0x1B80, 0x57000955, 0x1B80, 0x57000957, 0x1B80, 0x95000965, + 0x1B80, 0x95000967, 0x1B80, 0x4D000975, 0x1B80, 0x4D000977, + 0x1B80, 0x6C070985, 0x1B80, 0x6C070987, 0x1B80, 0x7B200995, + 0x1B80, 0x7B200997, 0x1B80, 0x7A0009A5, 0x1B80, 0x7A0009A7, + 0x1B80, 0x790009B5, 0x1B80, 0x790009B7, 0x1B80, 0x7F2009C5, + 0x1B80, 0x7F2009C7, 0x1B80, 0x7E0009D5, 0x1B80, 0x7E0009D7, + 0x1B80, 0x7D0009E5, 0x1B80, 0x7D0009E7, 0x1B80, 0x000109F5, + 0x1B80, 0x000109F7, 0x1B80, 0x62850A05, 0x1B80, 0x62850A07, + 0x1B80, 0xE1140A15, 0x1B80, 0xE1140A17, 0x1B80, 0x00010A25, + 0x1B80, 0x00010A27, 0x1B80, 0x5C320A35, 0x1B80, 0x5C320A37, + 0x1B80, 0xE1640A45, 0x1B80, 0xE1640A47, 0x1B80, 0xE1420A55, + 0x1B80, 0xE1420A57, 0x1B80, 0x00010A65, 0x1B80, 0x00010A67, + 0x1B80, 0x5C320A75, 0x1B80, 0x5C320A77, 0x1B80, 0x63F40A85, + 0x1B80, 0x63F40A87, 0x1B80, 0x62850A95, 0x1B80, 0x62850A97, + 0x1B80, 0x0BB00AA5, 0x1B80, 0x0BB00AA7, 0x1B80, 0xE1140AB5, + 0x1B80, 0xE1140AB7, 0x1B80, 0xE1680AC5, 0x1B80, 0xE1680AC7, + 0x1B80, 0x5C320AD5, 0x1B80, 0x5C320AD7, 0x1B80, 0x63FC0AE5, + 0x1B80, 0x63FC0AE7, 0x1B80, 0x62850AF5, 0x1B80, 0x62850AF7, + 0x1B80, 0x0BB10B05, 0x1B80, 0x0BB10B07, 0x1B80, 0xE1140B15, + 0x1B80, 0xE1140B17, 0x1B80, 0xE1680B25, 0x1B80, 0xE1680B27, + 0x1B80, 0x63030B35, 0x1B80, 0x63030B37, 0x1B80, 0xE1140B45, + 0x1B80, 0xE1140B47, 0x1B80, 0xE1680B55, 0x1B80, 0xE1680B57, + 0x1B80, 0xF7040B65, 0x1B80, 0xF7040B67, 0x1B80, 0x630B0B75, + 0x1B80, 0x630B0B77, 0x1B80, 0xE1140B85, 0x1B80, 0xE1140B87, + 0x1B80, 0xE1680B95, 0x1B80, 0xE1680B97, 0x1B80, 0x00010BA5, + 0x1B80, 0x00010BA7, 0x1B80, 0x30DF0BB5, 0x1B80, 0x30DF0BB7, + 0x1B80, 0x00230BC5, 0x1B80, 0x00230BC7, 0x1B80, 0xE16D0BD5, + 0x1B80, 0xE16D0BD7, 0x1B80, 0x00020BE5, 0x1B80, 0x00020BE7, + 0x1B80, 0x54E90BF5, 0x1B80, 0x54E90BF7, 0x1B80, 0x0BA60C05, + 0x1B80, 0x0BA60C07, 0x1B80, 0x00230C15, 0x1B80, 0x00230C17, + 0x1B80, 0xE16D0C25, 0x1B80, 0xE16D0C27, 0x1B80, 0x00020C35, + 0x1B80, 0x00020C37, 0x1B80, 0x4D100C45, 0x1B80, 0x4D100C47, + 0x1B80, 0x30900C55, 0x1B80, 0x30900C57, 0x1B80, 0x30D90C65, + 0x1B80, 0x30D90C67, 0x1B80, 0x00220C75, 0x1B80, 0x00220C77, + 0x1B80, 0xE16D0C85, 0x1B80, 0xE16D0C87, 0x1B80, 0x00020C95, + 0x1B80, 0x00020C97, 0x1B80, 0x54E80CA5, 0x1B80, 0x54E80CA7, + 0x1B80, 0x0BA60CB5, 0x1B80, 0x0BA60CB7, 0x1B80, 0x00220CC5, + 0x1B80, 0x00220CC7, 0x1B80, 0xE16D0CD5, 0x1B80, 0xE16D0CD7, + 0x1B80, 0x00020CE5, 0x1B80, 0x00020CE7, 0x1B80, 0x4D100CF5, + 0x1B80, 0x4D100CF7, 0x1B80, 0x30900D05, 0x1B80, 0x30900D07, + 0x1B80, 0x5C320D15, 0x1B80, 0x5C320D17, 0x1B80, 0x54F00D25, + 0x1B80, 0x54F00D27, 0x1B80, 0x67F10D35, 0x1B80, 0x67F10D37, + 0x1B80, 0xE1420D45, 0x1B80, 0xE1420D47, 0x1B80, 0xE16D0D55, + 0x1B80, 0xE16D0D57, 0x1B80, 0x67F40D65, 0x1B80, 0x67F40D67, + 0x1B80, 0xE1420D75, 0x1B80, 0xE1420D77, 0x1B80, 0xE16D0D85, + 0x1B80, 0xE16D0D87, 0x1B80, 0x5C320D95, 0x1B80, 0x5C320D97, + 0x1B80, 0x54F10DA5, 0x1B80, 0x54F10DA7, 0x1B80, 0x0BA80DB5, + 0x1B80, 0x0BA80DB7, 0x1B80, 0x67F80DC5, 0x1B80, 0x67F80DC7, + 0x1B80, 0xE1420DD5, 0x1B80, 0xE1420DD7, 0x1B80, 0xE16D0DE5, + 0x1B80, 0xE16D0DE7, 0x1B80, 0x5C320DF5, 0x1B80, 0x5C320DF7, + 0x1B80, 0x54F10E05, 0x1B80, 0x54F10E07, 0x1B80, 0x0BA90E15, + 0x1B80, 0x0BA90E17, 0x1B80, 0x67FC0E25, 0x1B80, 0x67FC0E27, + 0x1B80, 0xE1420E35, 0x1B80, 0xE1420E37, 0x1B80, 0xE16D0E45, + 0x1B80, 0xE16D0E47, 0x1B80, 0x67FF0E55, 0x1B80, 0x67FF0E57, + 0x1B80, 0xE1420E65, 0x1B80, 0xE1420E67, 0x1B80, 0xE16D0E75, + 0x1B80, 0xE16D0E77, 0x1B80, 0x5C320E85, 0x1B80, 0x5C320E87, + 0x1B80, 0x54F20E95, 0x1B80, 0x54F20E97, 0x1B80, 0x67000EA5, + 0x1B80, 0x67000EA7, 0x1B80, 0xE1420EB5, 0x1B80, 0xE1420EB7, + 0x1B80, 0xE16D0EC5, 0x1B80, 0xE16D0EC7, 0x1B80, 0x67030ED5, + 0x1B80, 0x67030ED7, 0x1B80, 0xE1420EE5, 0x1B80, 0xE1420EE7, + 0x1B80, 0xE16D0EF5, 0x1B80, 0xE16D0EF7, 0x1B80, 0xF9CC0F05, + 0x1B80, 0xF9CC0F07, 0x1B80, 0x67070F15, 0x1B80, 0x67070F17, + 0x1B80, 0xE1420F25, 0x1B80, 0xE1420F27, 0x1B80, 0xE16D0F35, + 0x1B80, 0xE16D0F37, 0x1B80, 0xFAD30F45, 0x1B80, 0xFAD30F47, + 0x1B80, 0x5C320F55, 0x1B80, 0x5C320F57, 0x1B80, 0x54F30F65, + 0x1B80, 0x54F30F67, 0x1B80, 0x670B0F75, 0x1B80, 0x670B0F77, + 0x1B80, 0xE1420F85, 0x1B80, 0xE1420F87, 0x1B80, 0xE16D0F95, + 0x1B80, 0xE16D0F97, 0x1B80, 0x670E0FA5, 0x1B80, 0x670E0FA7, + 0x1B80, 0xE1420FB5, 0x1B80, 0xE1420FB7, 0x1B80, 0xE16D0FC5, + 0x1B80, 0xE16D0FC7, 0x1B80, 0x4D100FD5, 0x1B80, 0x4D100FD7, + 0x1B80, 0x30900FE5, 0x1B80, 0x30900FE7, 0x1B80, 0x00010FF5, + 0x1B80, 0x00010FF7, 0x1B80, 0x7B241005, 0x1B80, 0x7B241007, + 0x1B80, 0x7A401015, 0x1B80, 0x7A401017, 0x1B80, 0x79001025, + 0x1B80, 0x79001027, 0x1B80, 0x55031035, 0x1B80, 0x55031037, + 0x1B80, 0x310C1045, 0x1B80, 0x310C1047, 0x1B80, 0x7B1C1055, + 0x1B80, 0x7B1C1057, 0x1B80, 0x7A401065, 0x1B80, 0x7A401067, + 0x1B80, 0x550B1075, 0x1B80, 0x550B1077, 0x1B80, 0x310C1085, + 0x1B80, 0x310C1087, 0x1B80, 0x7B201095, 0x1B80, 0x7B201097, + 0x1B80, 0x7A0010A5, 0x1B80, 0x7A0010A7, 0x1B80, 0x551310B5, + 0x1B80, 0x551310B7, 0x1B80, 0x740110C5, 0x1B80, 0x740110C7, + 0x1B80, 0x740010D5, 0x1B80, 0x740010D7, 0x1B80, 0x8E0010E5, + 0x1B80, 0x8E0010E7, 0x1B80, 0x000110F5, 0x1B80, 0x000110F7, + 0x1B80, 0x57021105, 0x1B80, 0x57021107, 0x1B80, 0x57001115, + 0x1B80, 0x57001117, 0x1B80, 0x97001125, 0x1B80, 0x97001127, + 0x1B80, 0x00011135, 0x1B80, 0x00011137, 0x1B80, 0x4F781145, + 0x1B80, 0x4F781147, 0x1B80, 0x53881155, 0x1B80, 0x53881157, + 0x1B80, 0xE1221165, 0x1B80, 0xE1221167, 0x1B80, 0x54801175, + 0x1B80, 0x54801177, 0x1B80, 0x54001185, 0x1B80, 0x54001187, + 0x1B80, 0xE1221195, 0x1B80, 0xE1221197, 0x1B80, 0x548111A5, + 0x1B80, 0x548111A7, 0x1B80, 0x540011B5, 0x1B80, 0x540011B7, + 0x1B80, 0xE12211C5, 0x1B80, 0xE12211C7, 0x1B80, 0x548211D5, + 0x1B80, 0x548211D7, 0x1B80, 0x540011E5, 0x1B80, 0x540011E7, + 0x1B80, 0xE12D11F5, 0x1B80, 0xE12D11F7, 0x1B80, 0xBF1D1205, + 0x1B80, 0xBF1D1207, 0x1B80, 0x301D1215, 0x1B80, 0x301D1217, + 0x1B80, 0xE1001225, 0x1B80, 0xE1001227, 0x1B80, 0xE1051235, + 0x1B80, 0xE1051237, 0x1B80, 0xE1091245, 0x1B80, 0xE1091247, + 0x1B80, 0xE1101255, 0x1B80, 0xE1101257, 0x1B80, 0xE1641265, + 0x1B80, 0xE1641267, 0x1B80, 0x55131275, 0x1B80, 0x55131277, + 0x1B80, 0xE10C1285, 0x1B80, 0xE10C1287, 0x1B80, 0x55151295, + 0x1B80, 0x55151297, 0x1B80, 0xE11012A5, 0x1B80, 0xE11012A7, + 0x1B80, 0xE16412B5, 0x1B80, 0xE16412B7, 0x1B80, 0x000112C5, + 0x1B80, 0x000112C7, 0x1B80, 0x54BF12D5, 0x1B80, 0x54BF12D7, + 0x1B80, 0x54C012E5, 0x1B80, 0x54C012E7, 0x1B80, 0x54A312F5, + 0x1B80, 0x54A312F7, 0x1B80, 0x54C11305, 0x1B80, 0x54C11307, + 0x1B80, 0x54A41315, 0x1B80, 0x54A41317, 0x1B80, 0x4C181325, + 0x1B80, 0x4C181327, 0x1B80, 0xBF071335, 0x1B80, 0xBF071337, + 0x1B80, 0x54C21345, 0x1B80, 0x54C21347, 0x1B80, 0x54A41355, + 0x1B80, 0x54A41357, 0x1B80, 0xBF041365, 0x1B80, 0xBF041367, + 0x1B80, 0x54C11375, 0x1B80, 0x54C11377, 0x1B80, 0x54A31385, + 0x1B80, 0x54A31387, 0x1B80, 0xBF011395, 0x1B80, 0xBF011397, + 0x1B80, 0xE17213A5, 0x1B80, 0xE17213A7, 0x1B80, 0x54DF13B5, + 0x1B80, 0x54DF13B7, 0x1B80, 0x000113C5, 0x1B80, 0x000113C7, + 0x1B80, 0x54BF13D5, 0x1B80, 0x54BF13D7, 0x1B80, 0x54E513E5, + 0x1B80, 0x54E513E7, 0x1B80, 0x050A13F5, 0x1B80, 0x050A13F7, + 0x1B80, 0x54DF1405, 0x1B80, 0x54DF1407, 0x1B80, 0x00011415, + 0x1B80, 0x00011417, 0x1B80, 0x7F201425, 0x1B80, 0x7F201427, + 0x1B80, 0x7E001435, 0x1B80, 0x7E001437, 0x1B80, 0x7D001445, + 0x1B80, 0x7D001447, 0x1B80, 0x55011455, 0x1B80, 0x55011457, + 0x1B80, 0x5C311465, 0x1B80, 0x5C311467, 0x1B80, 0xE10C1475, + 0x1B80, 0xE10C1477, 0x1B80, 0xE1101485, 0x1B80, 0xE1101487, + 0x1B80, 0x54801495, 0x1B80, 0x54801497, 0x1B80, 0x540014A5, + 0x1B80, 0x540014A7, 0x1B80, 0xE10C14B5, 0x1B80, 0xE10C14B7, + 0x1B80, 0xE11014C5, 0x1B80, 0xE11014C7, 0x1B80, 0x548114D5, + 0x1B80, 0x548114D7, 0x1B80, 0x540014E5, 0x1B80, 0x540014E7, + 0x1B80, 0xE10C14F5, 0x1B80, 0xE10C14F7, 0x1B80, 0xE1101505, + 0x1B80, 0xE1101507, 0x1B80, 0x54821515, 0x1B80, 0x54821517, + 0x1B80, 0x54001525, 0x1B80, 0x54001527, 0x1B80, 0xE12D1535, + 0x1B80, 0xE12D1537, 0x1B80, 0xBFE91545, 0x1B80, 0xBFE91547, + 0x1B80, 0x301D1555, 0x1B80, 0x301D1557, 0x1B80, 0x00231565, + 0x1B80, 0x00231567, 0x1B80, 0x7B201575, 0x1B80, 0x7B201577, + 0x1B80, 0x7A001585, 0x1B80, 0x7A001587, 0x1B80, 0x79001595, + 0x1B80, 0x79001597, 0x1B80, 0xE16815A5, 0x1B80, 0xE16815A7, + 0x1B80, 0x000215B5, 0x1B80, 0x000215B7, 0x1B80, 0x000115C5, + 0x1B80, 0x000115C7, 0x1B80, 0x002215D5, 0x1B80, 0x002215D7, + 0x1B80, 0x7B2015E5, 0x1B80, 0x7B2015E7, 0x1B80, 0x7A0015F5, + 0x1B80, 0x7A0015F7, 0x1B80, 0x79001605, 0x1B80, 0x79001607, + 0x1B80, 0xE1681615, 0x1B80, 0xE1681617, 0x1B80, 0x00021625, + 0x1B80, 0x00021627, 0x1B80, 0x00011635, 0x1B80, 0x00011637, + 0x1B80, 0x549F1645, 0x1B80, 0x549F1647, 0x1B80, 0x54FF1655, + 0x1B80, 0x54FF1657, 0x1B80, 0x54001665, 0x1B80, 0x54001667, + 0x1B80, 0x00011675, 0x1B80, 0x00011677, 0x1B80, 0x5C311685, + 0x1B80, 0x5C311687, 0x1B80, 0x07141695, 0x1B80, 0x07141697, + 0x1B80, 0x540016A5, 0x1B80, 0x540016A7, 0x1B80, 0x5C3216B5, + 0x1B80, 0x5C3216B7, 0x1B80, 0x000116C5, 0x1B80, 0x000116C7, + 0x1B80, 0x5C3216D5, 0x1B80, 0x5C3216D7, 0x1B80, 0x071416E5, + 0x1B80, 0x071416E7, 0x1B80, 0x540016F5, 0x1B80, 0x540016F7, + 0x1B80, 0x5C311705, 0x1B80, 0x5C311707, 0x1B80, 0x00011715, + 0x1B80, 0x00011717, 0x1B80, 0x4C981725, 0x1B80, 0x4C981727, + 0x1B80, 0x4C181735, 0x1B80, 0x4C181737, 0x1B80, 0x00011745, + 0x1B80, 0x00011747, 0x1B80, 0x5C321755, 0x1B80, 0x5C321757, + 0x1B80, 0x62841765, 0x1B80, 0x62841767, 0x1B80, 0x66861775, + 0x1B80, 0x66861777, 0x1B80, 0x6C031785, 0x1B80, 0x6C031787, + 0x1B80, 0x7B201795, 0x1B80, 0x7B201797, 0x1B80, 0x7A0017A5, + 0x1B80, 0x7A0017A7, 0x1B80, 0x790017B5, 0x1B80, 0x790017B7, + 0x1B80, 0x7F2017C5, 0x1B80, 0x7F2017C7, 0x1B80, 0x7E0017D5, + 0x1B80, 0x7E0017D7, 0x1B80, 0x7D0017E5, 0x1B80, 0x7D0017E7, + 0x1B80, 0x090117F5, 0x1B80, 0x090117F7, 0x1B80, 0x0C011805, + 0x1B80, 0x0C011807, 0x1B80, 0x0BA61815, 0x1B80, 0x0BA61817, + 0x1B80, 0x00011825, 0x1B80, 0x00011827, 0x1B80, 0x00000006, + 0x1B80, 0x00000002, + +}; + +void odm_read_and_config_mp_8822b_phy_reg(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_phy_reg) / sizeof(u32); + u32 *array = array_mp_8822b_phy_reg; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_bb_phy_8822b(dm, v1, MASKDWORD, v2); + } + } +} + +u32 odm_get_version_mp_8822b_phy_reg(void) { return 67; } + +/****************************************************************************** + * phy_reg_pg.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_phy_reg_pg[] = { + 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, + 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, + 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, + 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, + 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, + 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, + 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, + 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, + 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, + 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, + 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, + 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, + 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, + 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, + 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, + 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, + 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, + 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, + 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, + 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, + 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, + 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, + 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, + 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, + 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840, + 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, + 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638, + 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, + 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638, + 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, + 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638, + 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, + 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022, + 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234, + 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, + 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840, + 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032, + 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638, + 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, + 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638, + 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, + 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638, + 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, + 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022, + 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234, + 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, +}; + +void odm_read_and_config_mp_8822b_phy_reg_pg(struct phy_dm_struct *dm) +{ + u32 i = 0; + u32 array_len = sizeof(array_mp_8822b_phy_reg_pg) / sizeof(u32); + u32 *array = array_mp_8822b_phy_reg_pg; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + dm->phy_reg_pg_version = 1; + dm->phy_reg_pg_value_type = PHY_REG_PG_EXACT_VALUE; + + for (i = 0; i < array_len; i += 6) { + u32 v1 = array[i]; + u32 v2 = array[i + 1]; + u32 v3 = array[i + 2]; + u32 v4 = array[i + 3]; + u32 v5 = array[i + 4]; + u32 v6 = array[i + 5]; + + odm_config_bb_phy_reg_pg_8822b(dm, v1, v2, v3, v4, v5, v6); + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h new file mode 100644 index 000000000000..53431998b47e --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_bb.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#ifndef __INC_MP_BB_HW_IMG_8822B_H +#define __INC_MP_BB_HW_IMG_8822B_H + +/****************************************************************************** + * agc_tab.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_agc_tab(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_agc_tab(void); + +/****************************************************************************** + * phy_reg.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_phy_reg(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_phy_reg(void); + +/****************************************************************************** + * phy_reg_pg.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_phy_reg_pg(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_phy_reg_pg(void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c new file mode 100644 index 000000000000..1a9daed2e609 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.c @@ -0,0 +1,222 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool check_positive(struct phy_dm_struct *dm, const u32 condition1, + const u32 condition2, const u32 condition3, + const u32 condition4) +{ + u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/ + ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/ + ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/ + ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/ + + u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, + cond4 = condition4; + + u8 cut_version_for_para = + (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version; + u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type; + + u32 driver1 = cut_version_for_para << 24 | + (dm->support_interface & 0xF0) << 16 | + dm->support_platform << 16 | pkg_type_for_para << 12 | + (dm->support_interface & 0x0F) << 8 | _board_type; + + u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 | + (dm->type_alna & 0xFF) << 16 | + (dm->type_apa & 0xFF) << 24; + + u32 driver3 = 0; + + u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) | + (dm->type_alna & 0xFF00) << 8 | + (dm->type_apa & 0xFF00) << 16; + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, cond1, cond2, cond3, cond4); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, driver1, driver2, driver3, driver4); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Platform, Interface) = (0x%X, 0x%X)\n", + dm->support_platform, dm->support_interface); + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Board, Package) = (0x%X, 0x%X)\n", + dm->board_type, dm->package_type); + + /*============== value Defined Check ===============*/ + /*QFN type [15:12] and cut version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && + ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && + ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 bit_mask = 0; + + if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + bit_mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + bit_mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + bit_mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + bit_mask |= 0xFF000000; + + if (((cond2 & bit_mask) == (driver2 & bit_mask)) && + ((cond4 & bit_mask) == + (driver4 & + bit_mask))) /* board_type of each RF path is matched*/ + return true; + else + return false; + } else { + return false; + } +} + +/****************************************************************************** + * mac_reg.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_mac_reg[] = { + 0x029, 0x000000F9, 0x420, 0x00000080, 0x421, 0x0000000F, + 0x428, 0x0000000A, 0x429, 0x00000010, 0x430, 0x00000000, + 0x431, 0x00000000, 0x432, 0x00000000, 0x433, 0x00000001, + 0x434, 0x00000004, 0x435, 0x00000005, 0x436, 0x00000007, + 0x437, 0x00000008, 0x43C, 0x00000004, 0x43D, 0x00000005, + 0x43E, 0x00000007, 0x43F, 0x00000008, 0x440, 0x0000005D, + 0x441, 0x00000001, 0x442, 0x00000000, 0x444, 0x00000010, + 0x445, 0x000000F0, 0x446, 0x00000001, 0x447, 0x000000FE, + 0x448, 0x00000000, 0x449, 0x00000000, 0x44A, 0x00000000, + 0x44B, 0x00000040, 0x44C, 0x00000010, 0x44D, 0x000000F0, + 0x44E, 0x0000003F, 0x44F, 0x00000000, 0x450, 0x00000000, + 0x451, 0x00000000, 0x452, 0x00000000, 0x453, 0x00000040, + 0x455, 0x00000070, 0x45E, 0x00000004, 0x49C, 0x00000010, + 0x49D, 0x000000F0, 0x49E, 0x00000000, 0x49F, 0x00000006, + 0x4A0, 0x000000E0, 0x4A1, 0x00000003, 0x4A2, 0x00000000, + 0x4A3, 0x00000040, 0x4A4, 0x00000015, 0x4A5, 0x000000F0, + 0x4A6, 0x00000000, 0x4A7, 0x00000006, 0x4A8, 0x000000E0, + 0x4A9, 0x00000000, 0x4AA, 0x00000000, 0x4AB, 0x00000000, + 0x7DA, 0x00000008, 0x1448, 0x00000006, 0x144A, 0x00000006, + 0x144C, 0x00000006, 0x144E, 0x00000006, 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, 0x4CA, 0x00000020, 0x4CB, 0x00000020, + 0x4CC, 0x000000FF, 0x4CD, 0x000000FF, 0x4CE, 0x00000001, + 0x4CF, 0x00000008, 0x500, 0x00000026, 0x501, 0x000000A2, + 0x502, 0x0000002F, 0x503, 0x00000000, 0x504, 0x00000028, + 0x505, 0x000000A3, 0x506, 0x0000005E, 0x507, 0x00000000, + 0x508, 0x0000002B, 0x509, 0x000000A4, 0x50A, 0x0000005E, + 0x50B, 0x00000000, 0x50C, 0x0000004F, 0x50D, 0x000000A4, + 0x50E, 0x00000000, 0x50F, 0x00000000, 0x512, 0x0000001C, + 0x514, 0x0000000A, 0x516, 0x0000000A, 0x521, 0x0000002F, + 0x525, 0x0000004F, 0x551, 0x00000010, 0x559, 0x00000002, + 0x55C, 0x00000050, 0x55D, 0x000000FF, 0x577, 0x0000000B, + 0x5BE, 0x00000064, 0x605, 0x00000030, 0x608, 0x0000000E, + 0x609, 0x00000022, 0x60C, 0x00000018, 0x6A0, 0x000000FF, + 0x6A1, 0x000000FF, 0x6A2, 0x000000FF, 0x6A3, 0x000000FF, + 0x6A4, 0x000000FF, 0x6A5, 0x000000FF, 0x6DE, 0x00000084, + 0x620, 0x000000FF, 0x621, 0x000000FF, 0x622, 0x000000FF, + 0x623, 0x000000FF, 0x624, 0x000000FF, 0x625, 0x000000FF, + 0x626, 0x000000FF, 0x627, 0x000000FF, 0x638, 0x00000050, + 0x63C, 0x0000000A, 0x63D, 0x0000000A, 0x63E, 0x0000000E, + 0x63F, 0x0000000E, 0x640, 0x00000040, 0x642, 0x00000040, + 0x643, 0x00000000, 0x652, 0x000000C8, 0x66E, 0x00000005, + 0x718, 0x00000040, 0x7D4, 0x00000098, + +}; + +void odm_read_and_config_mp_8822b_mac_reg(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_mac_reg) / sizeof(u32); + u32 *array = array_mp_8822b_mac_reg; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_mac_8822b(dm, v1, (u8)v2); + } + } +} + +u32 odm_get_version_mp_8822b_mac_reg(void) { return 67; } diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h new file mode 100644 index 000000000000..d02fdd7a4a53 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_mac.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#ifndef __INC_MP_MAC_HW_IMG_8822B_H +#define __INC_MP_MAC_HW_IMG_8822B_H + +/****************************************************************************** + * mac_reg.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_mac_reg(/* tc: Test Chip, mp: mp Chip*/ + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_mac_reg(void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c new file mode 100644 index 000000000000..84cdc0644207 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.c @@ -0,0 +1,4744 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool check_positive(struct phy_dm_struct *dm, const u32 condition1, + const u32 condition2, const u32 condition3, + const u32 condition4) +{ + u8 _board_type = ((dm->board_type & BIT(4)) >> 4) << 0 | /* _GLNA*/ + ((dm->board_type & BIT(3)) >> 3) << 1 | /* _GPA*/ + ((dm->board_type & BIT(7)) >> 7) << 2 | /* _ALNA*/ + ((dm->board_type & BIT(6)) >> 6) << 3 | /* _APA */ + ((dm->board_type & BIT(2)) >> 2) << 4; /* _BT*/ + + u32 cond1 = condition1, cond2 = condition2, cond3 = condition3, + cond4 = condition4; + + u8 cut_version_for_para = + (dm->cut_version == ODM_CUT_A) ? 14 : dm->cut_version; + u8 pkg_type_for_para = (dm->package_type == 0) ? 14 : dm->package_type; + + u32 driver1 = cut_version_for_para << 24 | + (dm->support_interface & 0xF0) << 16 | + dm->support_platform << 16 | pkg_type_for_para << 12 | + (dm->support_interface & 0x0F) << 8 | _board_type; + + u32 driver2 = (dm->type_glna & 0xFF) << 0 | (dm->type_gpa & 0xFF) << 8 | + (dm->type_alna & 0xFF) << 16 | + (dm->type_apa & 0xFF) << 24; + + u32 driver3 = 0; + + u32 driver4 = (dm->type_glna & 0xFF00) >> 8 | (dm->type_gpa & 0xFF00) | + (dm->type_alna & 0xFF00) << 8 | + (dm->type_apa & 0xFF00) << 16; + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (cond1, cond2, cond3, cond4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, cond1, cond2, cond3, cond4); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> %s (driver1, driver2, driver3, driver4) = (0x%X 0x%X 0x%X 0x%X)\n", + __func__, driver1, driver2, driver3, driver4); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Platform, Interface) = (0x%X, 0x%X)\n", + dm->support_platform, dm->support_interface); + ODM_RT_TRACE(dm, ODM_COMP_INIT, + " (Board, Package) = (0x%X, 0x%X)\n", + dm->board_type, dm->package_type); + + /*============== value Defined Check ===============*/ + /*QFN type [15:12] and cut version [27:24] need to do value check*/ + + if (((cond1 & 0x0000F000) != 0) && + ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) + return false; + if (((cond1 & 0x0F000000) != 0) && + ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) + return false; + + /*=============== Bit Defined Check ================*/ + /* We don't care [31:28] */ + + cond1 &= 0x00FF0FFF; + driver1 &= 0x00FF0FFF; + + if ((cond1 & driver1) == cond1) { + u32 bit_mask = 0; + + if ((cond1 & 0x0F) == 0) /* board_type is DONTCARE*/ + return true; + + if ((cond1 & BIT(0)) != 0) /*GLNA*/ + bit_mask |= 0x000000FF; + if ((cond1 & BIT(1)) != 0) /*GPA*/ + bit_mask |= 0x0000FF00; + if ((cond1 & BIT(2)) != 0) /*ALNA*/ + bit_mask |= 0x00FF0000; + if ((cond1 & BIT(3)) != 0) /*APA*/ + bit_mask |= 0xFF000000; + + if (((cond2 & bit_mask) == (driver2 & bit_mask)) && + ((cond4 & bit_mask) == + (driver4 & + bit_mask))) /* board_type of each RF path is matched*/ + return true; + else + return false; + } else { + return false; + } +} + +/****************************************************************************** + * radioa.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_radioa[] = { + 0x000, 0x00030000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0xA0000000, 0x00000000, 0x001, 0x00040029, + 0xB0000000, 0x00000000, 0x018, 0x00010D24, 0x0EF, 0x00080000, + 0x033, 0x00000002, 0x03E, 0x0000003F, 0x03F, 0x000C0F4E, + 0x033, 0x00000001, 0x03E, 0x00000034, 0x03F, 0x0004080E, + 0x0EF, 0x00080000, 0x0DF, 0x00002449, 0x033, 0x00000024, + 0x03E, 0x0000003F, 0x03F, 0x00060FDE, 0x0EF, 0x00000000, + 0x0EF, 0x00080000, 0x033, 0x00000025, 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, 0x0EF, 0x00000000, 0x0EF, 0x00080000, + 0x033, 0x00000026, 0x03E, 0x00000037, 0x03F, 0x000DEFCE, + 0x0EF, 0x00000000, 0x07F, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FF0F8, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x0B0, 0x000FB0F8, 0xA0000000, 0x00000000, + 0x0B0, 0x000FF0F8, 0xB0000000, 0x00000000, 0x0B1, 0x0007DBE4, + 0x0B2, 0x000225D1, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x000FC760, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x0B3, 0x0007C330, 0xA0000000, 0x00000000, 0x0B3, 0x000FC760, + 0xB0000000, 0x00000000, 0x0B4, 0x00099DD0, 0x0B5, 0x000400FC, + 0x0B6, 0x000187F0, 0x0B7, 0x00030018, 0x0B8, 0x00080800, + 0x0B9, 0x00000000, 0x0BA, 0x00008000, 0x0BB, 0x00000000, + 0x0BC, 0x00040030, 0x0BD, 0x00000000, 0x0BE, 0x00000000, + 0x0BF, 0x00000000, 0x0C0, 0x00000000, 0x0C1, 0x00000000, + 0x0C2, 0x00000000, 0x0C3, 0x00000000, 0x0C4, 0x00002402, + 0x0C5, 0x00000009, 0x0C6, 0x00040299, 0x0C7, 0x00055555, + 0x0C8, 0x0000C16C, 0x0C9, 0x0001C140, 0x0CA, 0x00000000, + 0x0CB, 0x00000000, 0x0CC, 0x00000000, 0x0CD, 0x00000000, + 0x0CE, 0x00090C00, 0x0CF, 0x0006D200, 0x0DF, 0x00000009, + 0x018, 0x00010524, 0x089, 0x00000207, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FF186, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x08A, 0x000FE186, 0xA0000000, 0x00000000, + 0x08A, 0x000FF186, 0xB0000000, 0x00000000, 0x08B, 0x00061E3C, + 0x08C, 0x000112C7, 0x08D, 0x000F4988, 0x08E, 0x00064D40, + 0x0EF, 0x00020000, 0x033, 0x00000007, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0xA0000000, 0x00000000, + 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x00000006, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0xA0000000, 0x00000000, 0x03E, 0x00004080, 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, 0x033, 0x00000005, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x000040C8, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004084, 0xA0000000, 0x00000000, + 0x03E, 0x000040C8, 0xB0000000, 0x00000000, 0x03F, 0x000C3186, + 0x033, 0x00000004, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004190, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004108, 0xA0000000, 0x00000000, 0x03E, 0x00004190, + 0xB0000000, 0x00000000, 0x03F, 0x000C3186, 0x033, 0x00000003, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004998, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x0000490C, + 0xA0000000, 0x00000000, 0x03E, 0x00004998, 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, 0x033, 0x00000002, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00005840, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00005E00, 0xA0000000, 0x00000000, + 0x03E, 0x00005840, 0xB0000000, 0x00000000, 0x03F, 0x000C3186, + 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x000058C2, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00005862, 0xA0000000, 0x00000000, 0x03E, 0x000058C2, + 0xB0000000, 0x00000000, 0x03F, 0x000C3186, 0x033, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00005930, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00005948, + 0xA0000000, 0x00000000, 0x03E, 0x00005930, 0xB0000000, 0x00000000, + 0x03F, 0x000C3186, 0x033, 0x0000000F, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0xA0000000, 0x00000000, + 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000DFF86, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x0000000E, + 0x03E, 0x00004080, 0x03F, 0x000C3186, 0x033, 0x0000000D, + 0x03E, 0x000040C8, 0x03F, 0x000C3186, 0x033, 0x0000000C, + 0x03E, 0x00004190, 0x03F, 0x000C3186, 0x033, 0x0000000B, + 0x03E, 0x00004998, 0x03F, 0x000C3186, 0x033, 0x0000000A, + 0x03E, 0x00005840, 0x03F, 0x000C3186, 0x033, 0x00000009, + 0x03E, 0x000058C2, 0x03F, 0x000C3186, 0x033, 0x00000008, + 0x03E, 0x00005930, 0x03F, 0x000C3186, 0x033, 0x00000017, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0xA0000000, 0x00000000, 0x03E, 0x00004000, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C0006, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, 0x03F, 0x000C3186, 0xB0000000, 0x00000000, + 0x033, 0x00000016, 0x03E, 0x00004080, 0x03F, 0x000C3186, + 0x033, 0x00000015, 0x03E, 0x000040C8, 0x03F, 0x000C3186, + 0x033, 0x00000014, 0x03E, 0x00004190, 0x03F, 0x000C3186, + 0x033, 0x00000013, 0x03E, 0x00004998, 0x03F, 0x000C3186, + 0x033, 0x00000012, 0x03E, 0x00005840, 0x03F, 0x000C3186, + 0x033, 0x00000011, 0x03E, 0x000058C2, 0x03F, 0x000C3186, + 0x033, 0x00000010, 0x03E, 0x00005930, 0x03F, 0x000C3186, + 0x0EF, 0x00000000, 0x0EF, 0x00004000, 0x033, 0x00000000, + 0x03F, 0x0000000A, 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000006, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0xA0000000, 0x00000000, + 0x03F, 0x00000005, 0xB0000000, 0x00000000, 0x033, 0x00000002, + 0x03F, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x00000401, + 0x084, 0x00001209, 0x086, 0x000001A0, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0xA0000000, 0x00000000, + 0x087, 0x000E8180, 0xB0000000, 0x00000000, 0x088, 0x00070020, + 0x0DE, 0x00000010, 0x0EF, 0x00008000, 0x033, 0x0000000F, + 0x03F, 0x0000003C, 0x033, 0x0000000E, 0x03F, 0x00000038, + 0x033, 0x0000000D, 0x03F, 0x00000030, 0x033, 0x0000000C, + 0x03F, 0x00000028, 0x033, 0x0000000B, 0x03F, 0x00000020, + 0x033, 0x0000000A, 0x03F, 0x00000018, 0x033, 0x00000009, + 0x03F, 0x00000010, 0x033, 0x00000008, 0x03F, 0x00000008, + 0x033, 0x00000007, 0x03F, 0x0000003C, 0x033, 0x00000006, + 0x03F, 0x00000038, 0x033, 0x00000005, 0x03F, 0x00000030, + 0x033, 0x00000004, 0x03F, 0x00000028, 0x033, 0x00000003, + 0x03F, 0x00000020, 0x033, 0x00000002, 0x03F, 0x00000018, + 0x033, 0x00000001, 0x03F, 0x00000010, 0x033, 0x00000000, + 0x03F, 0x00000008, 0x0EF, 0x00000000, 0x0B8, 0x00080A00, + 0x0B0, 0x000FF0FA, 0x0FE, 0x00000000, 0x0CA, 0x00080000, + 0x0C9, 0x0001C141, 0x0FE, 0x00000000, 0x0B0, 0x000FF0F8, + 0x018, 0x00018D24, 0xFFE, 0x00000000, 0xFFE, 0x00000000, + 0xFFE, 0x00000000, 0xFFE, 0x00000000, 0x018, 0x00010D24, + 0x01B, 0x00075A40, 0x0EE, 0x00000002, 0x033, 0x00000000, + 0x03F, 0x00000004, 0x033, 0x00000001, 0x03F, 0x00000004, + 0x033, 0x00000002, 0x03F, 0x00000004, 0x033, 0x00000003, + 0x03F, 0x00000004, 0x033, 0x00000004, 0x03F, 0x00000004, + 0x033, 0x00000005, 0x03F, 0x00000006, 0x033, 0x00000006, + 0x03F, 0x00000002, 0x033, 0x00000007, 0x03F, 0x00000000, + 0x0EE, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000062, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D301, 0x062, 0x0000D303, 0x063, 0x00000002, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D301, + 0x062, 0x0000D303, 0x063, 0x00000002, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D301, 0x062, 0x0000D303, + 0x063, 0x00000002, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D301, + 0x062, 0x0000D303, 0x063, 0x00000002, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D301, 0x062, 0x0000D303, + 0x063, 0x00000002, 0xA0000000, 0x00000000, 0x061, 0x0005D3D0, + 0x062, 0x0000D303, 0x063, 0x00000002, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000004A3, 0x030, 0x000014A3, 0x030, 0x000024A3, + 0x030, 0x000034A3, 0x030, 0x000044A3, 0x030, 0x000054A3, + 0x030, 0x000064A3, 0x030, 0x000074A3, 0x030, 0x000084A3, + 0x030, 0x000094A3, 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, + 0x0EF, 0x00000000, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000004A3, 0x030, 0x000014A3, + 0x030, 0x000024A3, 0x030, 0x000034A3, 0x030, 0x000044A3, + 0x030, 0x000054A3, 0x030, 0x000064A3, 0x030, 0x000074A3, + 0x030, 0x000084A3, 0x030, 0x000094A3, 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, 0x0EF, 0x00000000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000004A3, + 0x030, 0x000014A3, 0x030, 0x000024A3, 0x030, 0x000034A3, + 0x030, 0x000044A3, 0x030, 0x000054A3, 0x030, 0x000064A3, + 0x030, 0x000074A3, 0x030, 0x000084A3, 0x030, 0x000094A3, + 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, 0x0EF, 0x00000000, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000002A6, 0x030, 0x000012A6, 0x030, 0x000022A6, + 0x030, 0x000032A6, 0x030, 0x000042A6, 0x030, 0x000052A6, + 0x030, 0x000062A6, 0x030, 0x000072A6, 0x030, 0x000082A6, + 0x030, 0x000092A6, 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, + 0x0EF, 0x00000000, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000004A0, 0x030, 0x000014A0, + 0x030, 0x000024A0, 0x030, 0x000034A0, 0x030, 0x000044A0, + 0x030, 0x000054A0, 0x030, 0x000064A0, 0x030, 0x000074A0, + 0x030, 0x000084A0, 0x030, 0x000094A0, 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, 0x0EF, 0x00000000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000004A0, + 0x030, 0x000014A0, 0x030, 0x000024A0, 0x030, 0x000034A0, + 0x030, 0x000044A0, 0x030, 0x000054A0, 0x030, 0x000064A0, + 0x030, 0x000074A0, 0x030, 0x000084A0, 0x030, 0x000094A0, + 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, 0x0EF, 0x00000000, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0, + 0x030, 0x000034A0, 0x030, 0x000044A0, 0x030, 0x000054A0, + 0x030, 0x000064A0, 0x030, 0x000074A0, 0x030, 0x000084A0, + 0x030, 0x000094A0, 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, + 0x0EF, 0x00000000, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000002A1, 0x030, 0x000012A1, + 0x030, 0x000022A1, 0x030, 0x000032A1, 0x030, 0x000042A1, + 0x030, 0x000052A1, 0x030, 0x000062A1, 0x030, 0x000072A1, + 0x030, 0x000082A1, 0x030, 0x000092A1, 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, 0x0EF, 0x00000000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000002A6, + 0x030, 0x000012A6, 0x030, 0x000022A6, 0x030, 0x000032A6, + 0x030, 0x000042A6, 0x030, 0x000052A6, 0x030, 0x000062A6, + 0x030, 0x000072A6, 0x030, 0x000082A6, 0x030, 0x000092A6, + 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, 0x0EF, 0x00000000, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x00000384, 0x030, 0x00001384, 0x030, 0x00002384, + 0x030, 0x00003384, 0x030, 0x00004425, 0x030, 0x00005425, + 0x030, 0x00006425, 0x030, 0x00007425, 0x030, 0x000083A4, + 0x030, 0x000093A4, 0x030, 0x0000A3A4, 0x030, 0x0000B3A4, + 0x0EF, 0x00000000, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000003A3, 0x030, 0x000013A3, + 0x030, 0x000023A3, 0x030, 0x000033A3, 0x030, 0x00004355, + 0x030, 0x00005355, 0x030, 0x00006355, 0x030, 0x00007355, + 0x030, 0x00008314, 0x030, 0x00009314, 0x030, 0x0000A314, + 0x030, 0x0000B314, 0x0EF, 0x00000000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003A1, + 0x030, 0x000013A1, 0x030, 0x000023A1, 0x030, 0x000033A1, + 0x030, 0x000043A3, 0x030, 0x000053A3, 0x030, 0x000063A3, + 0x030, 0x000073A3, 0x030, 0x000083A5, 0x030, 0x000093A5, + 0x030, 0x0000A3A5, 0x030, 0x0000B3A5, 0x0EF, 0x00000000, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000002A1, 0x030, 0x000012A1, 0x030, 0x000022A1, + 0x030, 0x000032A1, 0x030, 0x000042A1, 0x030, 0x000052A1, + 0x030, 0x000062A1, 0x030, 0x000072A1, 0x030, 0x000082A1, + 0x030, 0x000092A1, 0x030, 0x0000A2A1, 0x030, 0x0000B2A1, + 0x0EF, 0x00000000, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x00000463, 0x030, 0x00001463, + 0x030, 0x00002463, 0x030, 0x00003463, 0x030, 0x00004545, + 0x030, 0x00005545, 0x030, 0x00006545, 0x030, 0x00007545, + 0x030, 0x00008565, 0x030, 0x00009565, 0x030, 0x0000A565, + 0x030, 0x0000B565, 0x0EF, 0x00000000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x00000303, + 0x030, 0x00001303, 0x030, 0x00002303, 0x030, 0x00003303, + 0x030, 0x000043A4, 0x030, 0x000053A4, 0x030, 0x000063A4, + 0x030, 0x000073A4, 0x030, 0x00008365, 0x030, 0x00009365, + 0x030, 0x0000A365, 0x030, 0x0000B365, 0x0EF, 0x00000000, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x0EF, 0x00000200, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x00004343, 0x030, 0x00005343, + 0x030, 0x00006343, 0x030, 0x00007343, 0x030, 0x00008364, + 0x030, 0x00009364, 0x030, 0x0000A364, 0x030, 0x0000B364, + 0x0EF, 0x00000000, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000200, 0x030, 0x000003A0, 0x030, 0x000013A0, + 0x030, 0x000023A0, 0x030, 0x000033A0, 0x030, 0x00004430, + 0x030, 0x00005430, 0x030, 0x00006430, 0x030, 0x00007430, + 0x030, 0x00008372, 0x030, 0x00009372, 0x030, 0x0000A372, + 0x030, 0x0000B372, 0x0EF, 0x00000000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003A0, + 0x030, 0x000013A0, 0x030, 0x000023A0, 0x030, 0x000033A0, + 0x030, 0x000043A1, 0x030, 0x000053A1, 0x030, 0x000063A1, + 0x030, 0x000073A1, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x0EF, 0x00000000, + 0xA0000000, 0x00000000, 0x0EF, 0x00000200, 0x030, 0x000003D0, + 0x030, 0x000013D0, 0x030, 0x000023D0, 0x030, 0x000033D0, + 0x030, 0x000043D0, 0x030, 0x000053D0, 0x030, 0x000063D0, + 0x030, 0x000073D0, 0x030, 0x000083D0, 0x030, 0x000093D0, + 0x030, 0x0000A3D0, 0x030, 0x0000B3D0, 0x0EF, 0x00000000, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A3, 0x030, 0x000013A3, + 0x030, 0x000023A3, 0x030, 0x000033A3, 0x030, 0x000043A3, + 0x030, 0x000053A3, 0x030, 0x000063A3, 0x030, 0x000073A3, + 0x030, 0x000083A3, 0x030, 0x000093A3, 0x030, 0x0000A3A3, + 0x030, 0x0000B3A3, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x0EF, 0x00000080, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0xA0000000, 0x00000000, 0x0EF, 0x00000080, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000660, + 0x030, 0x00001443, 0x030, 0x00002221, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000776, + 0x030, 0x00001455, 0x030, 0x00002325, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000777, + 0x030, 0x00001442, 0x030, 0x00002222, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000775, + 0x030, 0x00001343, 0x030, 0x00002210, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x0EF, 0x00000040, 0x030, 0x00000775, + 0x030, 0x00001422, 0x030, 0x00002210, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0xA0000000, 0x00000000, + 0x0EF, 0x00000040, 0x030, 0x00000764, 0x030, 0x00001632, + 0x030, 0x00002421, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000800, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000007, 0x033, 0x00000021, + 0x03F, 0x0000000A, 0x033, 0x00000022, 0x03F, 0x0000000D, + 0x033, 0x00000023, 0x03F, 0x0000002A, 0x033, 0x00000024, + 0x03F, 0x0000002D, 0x033, 0x00000025, 0x03F, 0x00000030, + 0x033, 0x00000026, 0x03F, 0x0000006D, 0x033, 0x00000027, + 0x03F, 0x00000070, 0x033, 0x00000028, 0x03F, 0x000000ED, + 0x033, 0x00000029, 0x03F, 0x000000F0, 0x033, 0x0000002A, + 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C0C, 0x033, 0x00000021, + 0x03F, 0x00000C29, 0x033, 0x00000022, 0x03F, 0x00000C2C, + 0x033, 0x00000023, 0x03F, 0x00000C69, 0x033, 0x00000024, + 0x03F, 0x00000CA8, 0x033, 0x00000025, 0x03F, 0x00000CE8, + 0x033, 0x00000026, 0x03F, 0x00000CEB, 0x033, 0x00000027, + 0x03F, 0x00000CEE, 0x033, 0x00000028, 0x03F, 0x00000CF1, + 0x033, 0x00000029, 0x03F, 0x00000CF4, 0x033, 0x0000002A, + 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021, + 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849, + 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024, + 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000CA9, + 0x033, 0x00000026, 0x03F, 0x00000CEA, 0x033, 0x00000027, + 0x03F, 0x00000CED, 0x033, 0x00000028, 0x03F, 0x00000CF0, + 0x033, 0x00000029, 0x03F, 0x00000CF3, 0x033, 0x0000002A, + 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021, + 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F, + 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024, + 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0, + 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A, + 0x03F, 0x00000CF5, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000005, 0x033, 0x00000021, + 0x03F, 0x00000008, 0x033, 0x00000022, 0x03F, 0x0000000B, + 0x033, 0x00000023, 0x03F, 0x0000000E, 0x033, 0x00000024, + 0x03F, 0x0000002B, 0x033, 0x00000025, 0x03F, 0x00000068, + 0x033, 0x00000026, 0x03F, 0x0000006B, 0x033, 0x00000027, + 0x03F, 0x0000006E, 0x033, 0x00000028, 0x03F, 0x00000071, + 0x033, 0x00000029, 0x03F, 0x00000074, 0x033, 0x0000002A, + 0x03F, 0x00000077, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021, + 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F, + 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024, + 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0, + 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A, + 0x03F, 0x00000CF5, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000429, 0x033, 0x00000021, + 0x03F, 0x00000828, 0x033, 0x00000022, 0x03F, 0x00000847, + 0x033, 0x00000023, 0x03F, 0x0000084A, 0x033, 0x00000024, + 0x03F, 0x00000C4B, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000CEA, 0x033, 0x00000027, + 0x03F, 0x00000CED, 0x033, 0x00000028, 0x03F, 0x00000CF0, + 0x033, 0x00000029, 0x03F, 0x00000CF3, 0x033, 0x0000002A, + 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x00000C09, 0x033, 0x00000021, + 0x03F, 0x00000C0C, 0x033, 0x00000022, 0x03F, 0x00000C0F, + 0x033, 0x00000023, 0x03F, 0x00000C2C, 0x033, 0x00000024, + 0x03F, 0x00000C2F, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000C90, 0x033, 0x00000028, 0x03F, 0x00000CD0, + 0x033, 0x00000029, 0x03F, 0x00000CF2, 0x033, 0x0000002A, + 0x03F, 0x00000CF5, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021, + 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849, + 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024, + 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000CEB, 0x033, 0x00000028, 0x03F, 0x00000CEE, + 0x033, 0x00000029, 0x03F, 0x00000CF1, 0x033, 0x0000002A, + 0x03F, 0x00000CF4, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000020, 0x03F, 0x0000042B, 0x033, 0x00000021, + 0x03F, 0x0000082A, 0x033, 0x00000022, 0x03F, 0x00000849, + 0x033, 0x00000023, 0x03F, 0x0000084C, 0x033, 0x00000024, + 0x03F, 0x00000C4C, 0x033, 0x00000025, 0x03F, 0x00000C8A, + 0x033, 0x00000026, 0x03F, 0x00000C8D, 0x033, 0x00000027, + 0x03F, 0x00000CEB, 0x033, 0x00000028, 0x03F, 0x00000CEE, + 0x033, 0x00000029, 0x03F, 0x00000CF1, 0x033, 0x0000002A, + 0x03F, 0x00000CF4, 0xA0000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000007, 0x033, 0x00000061, + 0x03F, 0x0000000A, 0x033, 0x00000062, 0x03F, 0x0000000D, + 0x033, 0x00000063, 0x03F, 0x0000002A, 0x033, 0x00000064, + 0x03F, 0x0000002D, 0x033, 0x00000065, 0x03F, 0x00000030, + 0x033, 0x00000066, 0x03F, 0x0000006D, 0x033, 0x00000067, + 0x03F, 0x00000070, 0x033, 0x00000068, 0x03F, 0x000000ED, + 0x033, 0x00000069, 0x03F, 0x000000F0, 0x033, 0x0000006A, + 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000080B, 0x033, 0x00000061, + 0x03F, 0x0000080E, 0x033, 0x00000062, 0x03F, 0x00000848, + 0x033, 0x00000063, 0x03F, 0x00000869, 0x033, 0x00000064, + 0x03F, 0x000008A9, 0x033, 0x00000065, 0x03F, 0x00000CE8, + 0x033, 0x00000066, 0x03F, 0x00000CEB, 0x033, 0x00000067, + 0x03F, 0x00000CEE, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000042B, 0x033, 0x00000061, + 0x03F, 0x0000082A, 0x033, 0x00000062, 0x03F, 0x00000849, + 0x033, 0x00000063, 0x03F, 0x0000084C, 0x033, 0x00000064, + 0x03F, 0x00000C4C, 0x033, 0x00000065, 0x03F, 0x00000CA9, + 0x033, 0x00000066, 0x03F, 0x00000CEA, 0x033, 0x00000067, + 0x03F, 0x00000CED, 0x033, 0x00000068, 0x03F, 0x00000CF0, + 0x033, 0x00000069, 0x03F, 0x00000CF3, 0x033, 0x0000006A, + 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061, + 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A, + 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064, + 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA, + 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067, + 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000005, 0x033, 0x00000061, + 0x03F, 0x00000008, 0x033, 0x00000062, 0x03F, 0x0000000B, + 0x033, 0x00000063, 0x03F, 0x0000000E, 0x033, 0x00000064, + 0x03F, 0x0000002B, 0x033, 0x00000065, 0x03F, 0x00000068, + 0x033, 0x00000066, 0x03F, 0x0000006B, 0x033, 0x00000067, + 0x03F, 0x0000006E, 0x033, 0x00000068, 0x03F, 0x00000071, + 0x033, 0x00000069, 0x03F, 0x00000074, 0x033, 0x0000006A, + 0x03F, 0x00000077, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061, + 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A, + 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064, + 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA, + 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067, + 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000429, 0x033, 0x00000061, + 0x03F, 0x00000828, 0x033, 0x00000062, 0x03F, 0x00000847, + 0x033, 0x00000063, 0x03F, 0x0000084A, 0x033, 0x00000064, + 0x03F, 0x00000C4B, 0x033, 0x00000065, 0x03F, 0x00000C8A, + 0x033, 0x00000066, 0x03F, 0x00000CEA, 0x033, 0x00000067, + 0x03F, 0x00000CED, 0x033, 0x00000068, 0x03F, 0x00000CF0, + 0x033, 0x00000069, 0x03F, 0x00000CF3, 0x033, 0x0000006A, + 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x00000C0A, 0x033, 0x00000061, + 0x03F, 0x00000C0D, 0x033, 0x00000062, 0x03F, 0x00000C2A, + 0x033, 0x00000063, 0x03F, 0x00000C2D, 0x033, 0x00000064, + 0x03F, 0x00000C6A, 0x033, 0x00000065, 0x03F, 0x00000CAA, + 0x033, 0x00000066, 0x03F, 0x00000CAD, 0x033, 0x00000067, + 0x03F, 0x00000CB0, 0x033, 0x00000068, 0x03F, 0x00000CF1, + 0x033, 0x00000069, 0x03F, 0x00000CF4, 0x033, 0x0000006A, + 0x03F, 0x00000CF7, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000042C, 0x033, 0x00000061, + 0x03F, 0x0000082B, 0x033, 0x00000062, 0x03F, 0x0000084A, + 0x033, 0x00000063, 0x03F, 0x0000084D, 0x033, 0x00000064, + 0x03F, 0x00000C4D, 0x033, 0x00000065, 0x03F, 0x00000C8B, + 0x033, 0x00000066, 0x03F, 0x00000C8E, 0x033, 0x00000067, + 0x03F, 0x00000CEC, 0x033, 0x00000068, 0x03F, 0x00000CEF, + 0x033, 0x00000069, 0x03F, 0x00000CF2, 0x033, 0x0000006A, + 0x03F, 0x00000CF5, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000060, 0x03F, 0x0000042C, 0x033, 0x00000061, + 0x03F, 0x0000082B, 0x033, 0x00000062, 0x03F, 0x0000084A, + 0x033, 0x00000063, 0x03F, 0x0000084D, 0x033, 0x00000064, + 0x03F, 0x00000C4D, 0x033, 0x00000065, 0x03F, 0x00000C8B, + 0x033, 0x00000066, 0x03F, 0x00000C8E, 0x033, 0x00000067, + 0x03F, 0x00000CEC, 0x033, 0x00000068, 0x03F, 0x00000CEF, + 0x033, 0x00000069, 0x03F, 0x00000CF2, 0x033, 0x0000006A, + 0x03F, 0x00000CF5, 0xA0000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000007, 0x033, 0x000000A1, + 0x03F, 0x0000000A, 0x033, 0x000000A2, 0x03F, 0x0000000D, + 0x033, 0x000000A3, 0x03F, 0x0000002A, 0x033, 0x000000A4, + 0x03F, 0x0000002D, 0x033, 0x000000A5, 0x03F, 0x00000030, + 0x033, 0x000000A6, 0x03F, 0x0000006D, 0x033, 0x000000A7, + 0x03F, 0x00000070, 0x033, 0x000000A8, 0x03F, 0x000000ED, + 0x033, 0x000000A9, 0x03F, 0x000000F0, 0x033, 0x000000AA, + 0x03F, 0x000000F3, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C0A, 0x033, 0x000000A1, + 0x03F, 0x00000C0D, 0x033, 0x000000A2, 0x03F, 0x00000C2A, + 0x033, 0x000000A3, 0x03F, 0x00000C2D, 0x033, 0x000000A4, + 0x03F, 0x00000C6A, 0x033, 0x000000A5, 0x03F, 0x00000CE8, + 0x033, 0x000000A6, 0x03F, 0x00000CEB, 0x033, 0x000000A7, + 0x03F, 0x00000CEE, 0x033, 0x000000A8, 0x03F, 0x00000CF1, + 0x033, 0x000000A9, 0x03F, 0x00000CF4, 0x033, 0x000000AA, + 0x03F, 0x00000CF7, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1, + 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848, + 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4, + 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000CA9, + 0x033, 0x000000A6, 0x03F, 0x00000CEA, 0x033, 0x000000A7, + 0x03F, 0x00000CED, 0x033, 0x000000A8, 0x03F, 0x00000CF0, + 0x033, 0x000000A9, 0x03F, 0x00000CF3, 0x033, 0x000000AA, + 0x03F, 0x00000CF6, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1, + 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F, + 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4, + 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF, + 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA, + 0x03F, 0x00000CF5, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000005, 0x033, 0x000000A1, + 0x03F, 0x00000008, 0x033, 0x000000A2, 0x03F, 0x0000000B, + 0x033, 0x000000A3, 0x03F, 0x0000000E, 0x033, 0x000000A4, + 0x03F, 0x00000047, 0x033, 0x000000A5, 0x03F, 0x0000004A, + 0x033, 0x000000A6, 0x03F, 0x0000004D, 0x033, 0x000000A7, + 0x03F, 0x00000050, 0x033, 0x000000A8, 0x03F, 0x00000053, + 0x033, 0x000000A9, 0x03F, 0x00000056, 0x033, 0x000000AA, + 0x03F, 0x00000094, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1, + 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F, + 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4, + 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF, + 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA, + 0x03F, 0x00000CF5, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000429, 0x033, 0x000000A1, + 0x03F, 0x00000828, 0x033, 0x000000A2, 0x03F, 0x00000847, + 0x033, 0x000000A3, 0x03F, 0x0000084A, 0x033, 0x000000A4, + 0x03F, 0x00000C4B, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000CEA, 0x033, 0x000000A7, + 0x03F, 0x00000CED, 0x033, 0x000000A8, 0x03F, 0x00000CF0, + 0x033, 0x000000A9, 0x03F, 0x00000CF3, 0x033, 0x000000AA, + 0x03F, 0x00000CF6, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x00000C09, 0x033, 0x000000A1, + 0x03F, 0x00000C0C, 0x033, 0x000000A2, 0x03F, 0x00000C0F, + 0x033, 0x000000A3, 0x03F, 0x00000C2C, 0x033, 0x000000A4, + 0x03F, 0x00000C2F, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000C90, 0x033, 0x000000A8, 0x03F, 0x00000CEF, + 0x033, 0x000000A9, 0x03F, 0x00000CF2, 0x033, 0x000000AA, + 0x03F, 0x00000CF5, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1, + 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848, + 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4, + 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000CEB, 0x033, 0x000000A8, 0x03F, 0x00000CEE, + 0x033, 0x000000A9, 0x03F, 0x00000CF1, 0x033, 0x000000AA, + 0x03F, 0x00000CF4, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x000000A0, 0x03F, 0x0000042A, 0x033, 0x000000A1, + 0x03F, 0x00000829, 0x033, 0x000000A2, 0x03F, 0x00000848, + 0x033, 0x000000A3, 0x03F, 0x0000084B, 0x033, 0x000000A4, + 0x03F, 0x00000C4C, 0x033, 0x000000A5, 0x03F, 0x00000C8A, + 0x033, 0x000000A6, 0x03F, 0x00000C8D, 0x033, 0x000000A7, + 0x03F, 0x00000CEB, 0x033, 0x000000A8, 0x03F, 0x00000CEE, + 0x033, 0x000000A9, 0x03F, 0x00000CF1, 0x033, 0x000000AA, + 0x03F, 0x00000CF4, 0xA0000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0EF, 0x00000400, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C, + 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003, + 0x03F, 0x0000047C, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001, + 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C, + 0x033, 0x00000003, 0x03F, 0x0000047C, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000047C, + 0x033, 0x00000001, 0x03F, 0x0000047C, 0x033, 0x00000002, + 0x03F, 0x0000047C, 0x033, 0x00000003, 0x03F, 0x0000047C, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C, + 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003, + 0x03F, 0x0000047C, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001, + 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C, + 0x033, 0x00000003, 0x03F, 0x0000047C, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000047C, + 0x033, 0x00000001, 0x03F, 0x0000047C, 0x033, 0x00000002, + 0x03F, 0x0000047C, 0x033, 0x00000003, 0x03F, 0x0000047C, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000047C, 0x033, 0x00000001, 0x03F, 0x0000047C, + 0x033, 0x00000002, 0x03F, 0x0000047C, 0x033, 0x00000003, + 0x03F, 0x0000047C, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000047C, 0x033, 0x00000001, + 0x03F, 0x0000047C, 0x033, 0x00000002, 0x03F, 0x0000047C, + 0x033, 0x00000003, 0x03F, 0x0000047C, 0xA0000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x000004BB, 0x033, 0x00000001, + 0x03F, 0x000004BB, 0x033, 0x00000002, 0x03F, 0x000004BB, + 0x033, 0x00000003, 0x03F, 0x000004BB, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000100, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726, + 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002, + 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726, + 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003, + 0x03F, 0x00001726, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00001726, 0x033, 0x00000001, + 0x03F, 0x00001726, 0x033, 0x00000002, 0x03F, 0x00001726, + 0x033, 0x00000003, 0x03F, 0x00001726, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726, + 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002, + 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726, + 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003, + 0x03F, 0x00001726, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00001726, 0x033, 0x00000001, + 0x03F, 0x00001726, 0x033, 0x00000002, 0x03F, 0x00001726, + 0x033, 0x00000003, 0x03F, 0x00001726, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00001726, + 0x033, 0x00000001, 0x03F, 0x00001726, 0x033, 0x00000002, + 0x03F, 0x00001726, 0x033, 0x00000003, 0x03F, 0x00001726, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00001726, 0x033, 0x00000001, 0x03F, 0x00001726, + 0x033, 0x00000002, 0x03F, 0x00001726, 0x033, 0x00000003, + 0x03F, 0x00001726, 0xA0000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000F34, 0x033, 0x00000001, 0x03F, 0x00000F34, + 0x033, 0x00000002, 0x03F, 0x00000F34, 0x033, 0x00000003, + 0x03F, 0x00000F34, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0xA0000000, 0x00000000, 0x081, 0x0000F000, + 0x087, 0x00016040, 0x051, 0x00000C00, 0x052, 0x0007C241, + 0x053, 0x0001C069, 0x054, 0x00078032, 0x057, 0x0000CE0A, + 0x058, 0x00058750, 0xB0000000, 0x00000000, 0x0EF, 0x00000800, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000003, 0x033, 0x00000001, 0x03F, 0x00000006, + 0x033, 0x00000002, 0x03F, 0x00000009, 0x033, 0x00000003, + 0x03F, 0x00000026, 0x033, 0x00000004, 0x03F, 0x00000029, + 0x033, 0x00000005, 0x03F, 0x0000002C, 0x033, 0x00000006, + 0x03F, 0x0000002F, 0x033, 0x00000007, 0x03F, 0x00000033, + 0x033, 0x00000008, 0x03F, 0x00000036, 0x033, 0x00000009, + 0x03F, 0x00000039, 0x033, 0x0000000A, 0x03F, 0x0000003C, + 0xA0000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0005142C, + 0x033, 0x00000001, 0x03F, 0x0005144B, 0x033, 0x00000002, + 0x03F, 0x0005144E, 0x033, 0x00000003, 0x03F, 0x00051C69, + 0x033, 0x00000004, 0x03F, 0x00051C6C, 0x033, 0x00000005, + 0x03F, 0x00051C6F, 0x033, 0x00000006, 0x03F, 0x00051CEB, + 0x033, 0x00000007, 0x03F, 0x00051CEE, 0x033, 0x00000008, + 0x03F, 0x00051CF1, 0x033, 0x00000009, 0x03F, 0x00051CF4, + 0x033, 0x0000000A, 0x03F, 0x00051CF7, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000010, 0x033, 0x00000000, + 0x008, 0x0009C060, 0x033, 0x00000001, 0x008, 0x0009C060, + 0x0EF, 0x00000000, 0x033, 0x000000A2, 0x0EF, 0x00080000, + 0x03E, 0x0000593F, 0x03F, 0x000C0F4F, 0x0EF, 0x00000000, + 0x033, 0x000000A3, 0x0EF, 0x00080000, 0x03E, 0x00005934, + 0x03F, 0x0005AFCF, 0x0EF, 0x00000000, + +}; + +void odm_read_and_config_mp_8822b_radioa(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_radioa) / sizeof(u32); + u32 *array = array_mp_8822b_radioa; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_rf_radio_a_8822b(dm, v1, v2); + } + } +} + +u32 odm_get_version_mp_8822b_radioa(void) { return 67; } + +/****************************************************************************** + * radiob.TXT + ******************************************************************************/ + +static u32 array_mp_8822b_radiob[] = { + 0x000, 0x00030000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x0004002D, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x001, 0x00040029, 0xA0000000, 0x00000000, 0x001, 0x00040029, + 0xB0000000, 0x00000000, 0x018, 0x00010D24, 0x0EF, 0x00080000, + 0x033, 0x00000002, 0x03E, 0x0000003F, 0x03F, 0x000C0F4E, + 0x033, 0x00000001, 0x03E, 0x00000034, 0x03F, 0x0004080E, + 0x0EF, 0x00080000, 0x0DF, 0x00002449, 0x033, 0x00000024, + 0x03E, 0x0000003F, 0x03F, 0x00060FDE, 0x0EF, 0x00000000, + 0x0EF, 0x00080000, 0x033, 0x00000025, 0x03E, 0x00000037, + 0x03F, 0x0007EFCE, 0x0EF, 0x00000000, 0x0EF, 0x00080000, + 0x033, 0x00000026, 0x03E, 0x00000037, 0x03F, 0x000DEFCE, + 0x0EF, 0x00000000, 0x0DF, 0x00000009, 0x018, 0x00010524, + 0x089, 0x00000207, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x08A, 0x000FF186, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x08A, 0x000FE186, 0xA0000000, 0x00000000, 0x08A, 0x000FF186, + 0xB0000000, 0x00000000, 0x08B, 0x00061E3C, 0x08C, 0x000112C7, + 0x08D, 0x000F4988, 0x08E, 0x00064D40, 0x0EF, 0x00020000, + 0x033, 0x00000007, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004080, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03E, 0x00004080, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004040, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x03E, 0x00004000, 0xA0000000, 0x00000000, 0x03E, 0x00004000, + 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C0006, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x03F, 0x000C3186, 0xA0000000, 0x00000000, 0x03F, 0x000C3186, + 0xB0000000, 0x00000000, 0x033, 0x00000006, 0x03E, 0x00004080, + 0x03F, 0x000C3186, 0x033, 0x00000005, 0x03E, 0x000040C8, + 0x03F, 0x000C3186, 0x033, 0x00000004, 0x03E, 0x00004190, + 0x03F, 0x000C3186, 0x033, 0x00000003, 0x03E, 0x00004998, + 0x03F, 0x000C3186, 0x033, 0x00000002, 0x03E, 0x00005840, + 0x03F, 0x000C3186, 0x033, 0x00000001, 0x03E, 0x000058C2, + 0x03F, 0x000C3186, 0x033, 0x00000000, 0x03E, 0x00005930, + 0x03F, 0x000C3186, 0x033, 0x0000000F, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03E, 0x00004080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004040, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03E, 0x00004000, 0xA0000000, 0x00000000, + 0x03E, 0x00004000, 0xB0000000, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C0006, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x000C3186, 0xA0000000, 0x00000000, + 0x03F, 0x000C3186, 0xB0000000, 0x00000000, 0x033, 0x0000000E, + 0x03E, 0x00004080, 0x03F, 0x000C3186, 0x033, 0x0000000D, + 0x03E, 0x000040C8, 0x03F, 0x000C3186, 0x033, 0x0000000C, + 0x03E, 0x00004190, 0x03F, 0x000C3186, 0x033, 0x0000000B, + 0x03E, 0x00004998, 0x03F, 0x000C3186, 0x033, 0x0000000A, + 0x03E, 0x00005840, 0x03F, 0x000C3186, 0x033, 0x00000009, + 0x03E, 0x000058C2, 0x03F, 0x000C3186, 0x033, 0x00000008, + 0x03E, 0x00005930, 0x03F, 0x000C3186, 0x033, 0x00000017, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03E, 0x00004080, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004040, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03E, 0x00004000, + 0xA0000000, 0x00000000, 0x03E, 0x00004000, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000DFF86, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C0006, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x03F, 0x000C3186, + 0xA0000000, 0x00000000, 0x03F, 0x000C3186, 0xB0000000, 0x00000000, + 0x033, 0x00000016, 0x03E, 0x00004080, 0x03F, 0x000C3186, + 0x033, 0x00000015, 0x03E, 0x000040C8, 0x03F, 0x000C3186, + 0x033, 0x00000014, 0x03E, 0x00004190, 0x03F, 0x000C3186, + 0x033, 0x00000013, 0x03E, 0x00004998, 0x03F, 0x000C3186, + 0x033, 0x00000012, 0x03E, 0x00005840, 0x03F, 0x000C3186, + 0x033, 0x00000011, 0x03E, 0x000058C2, 0x03F, 0x000C3186, + 0x033, 0x00000010, 0x03E, 0x00005930, 0x03F, 0x000C3186, + 0x0EF, 0x00000000, 0x0EF, 0x00004000, 0x033, 0x00000000, + 0x03F, 0x0000000A, 0x033, 0x00000001, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000002, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000005, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x03F, 0x00000000, 0xA0000000, 0x00000000, + 0x03F, 0x00000005, 0xB0000000, 0x00000000, 0x033, 0x00000002, + 0x03F, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x00000401, + 0x084, 0x00001209, 0x086, 0x000001A0, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x087, 0x00068080, 0xA0000000, 0x00000000, + 0x087, 0x000E8180, 0xB0000000, 0x00000000, 0x088, 0x00070020, + 0x0DE, 0x00000010, 0x0EF, 0x00008000, 0x033, 0x0000000F, + 0x03F, 0x0000003C, 0x033, 0x0000000E, 0x03F, 0x00000038, + 0x033, 0x0000000D, 0x03F, 0x00000030, 0x033, 0x0000000C, + 0x03F, 0x00000028, 0x033, 0x0000000B, 0x03F, 0x00000020, + 0x033, 0x0000000A, 0x03F, 0x00000018, 0x033, 0x00000009, + 0x03F, 0x00000010, 0x033, 0x00000008, 0x03F, 0x00000008, + 0x033, 0x00000007, 0x03F, 0x0000003C, 0x033, 0x00000006, + 0x03F, 0x00000038, 0x033, 0x00000005, 0x03F, 0x00000030, + 0x033, 0x00000004, 0x03F, 0x00000028, 0x033, 0x00000003, + 0x03F, 0x00000020, 0x033, 0x00000002, 0x03F, 0x00000018, + 0x033, 0x00000001, 0x03F, 0x00000010, 0x033, 0x00000000, + 0x03F, 0x00000008, 0x0EF, 0x00000000, 0x018, 0x00018D24, + 0xFFE, 0x00000000, 0xFFE, 0x00000000, 0xFFE, 0x00000000, + 0xFFE, 0x00000000, 0x018, 0x00010D24, 0x01B, 0x00075A40, + 0x0EE, 0x00000002, 0x033, 0x00000000, 0x03F, 0x00000004, + 0x033, 0x00000001, 0x03F, 0x00000004, 0x033, 0x00000002, + 0x03F, 0x00000004, 0x033, 0x00000003, 0x03F, 0x00000004, + 0x033, 0x00000004, 0x03F, 0x00000004, 0x033, 0x00000005, + 0x03F, 0x00000006, 0x033, 0x00000006, 0x03F, 0x00000002, + 0x033, 0x00000007, 0x03F, 0x00000000, 0x0EE, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x061, 0x0005D4A0, 0x062, 0x0000D203, + 0x063, 0x00000062, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x061, 0x0005D4A0, 0x062, 0x0000D203, 0x063, 0x00000062, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D4A0, + 0x062, 0x0000D203, 0x063, 0x00000062, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000062, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000062, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D2A1, + 0x062, 0x0000D3A2, 0x063, 0x00000062, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D3D1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x0005D3D1, + 0x062, 0x0000D3A2, 0x063, 0x00000002, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, + 0x063, 0x00000002, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x0005D2A1, 0x062, 0x0000D3A2, 0x063, 0x00000002, + 0xA0000000, 0x00000000, 0x061, 0x0005D3D0, 0x062, 0x0000D303, + 0x063, 0x00000002, 0xB0000000, 0x00000000, 0x0EF, 0x00000200, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x030, 0x000004A3, + 0x030, 0x000014A3, 0x030, 0x000024A3, 0x030, 0x000034A3, + 0x030, 0x000044A3, 0x030, 0x000054A3, 0x030, 0x000064A3, + 0x030, 0x000074A3, 0x030, 0x000084A3, 0x030, 0x000094A3, + 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x030, 0x000004A3, 0x030, 0x000014A3, + 0x030, 0x000024A3, 0x030, 0x000034A3, 0x030, 0x000044A3, + 0x030, 0x000054A3, 0x030, 0x000064A3, 0x030, 0x000074A3, + 0x030, 0x000084A3, 0x030, 0x000094A3, 0x030, 0x0000A4A3, + 0x030, 0x0000B4A3, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A3, 0x030, 0x000014A3, 0x030, 0x000024A3, + 0x030, 0x000034A3, 0x030, 0x000044A3, 0x030, 0x000054A3, + 0x030, 0x000064A3, 0x030, 0x000074A3, 0x030, 0x000084A3, + 0x030, 0x000094A3, 0x030, 0x0000A4A3, 0x030, 0x0000B4A3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002A6, + 0x030, 0x000012A6, 0x030, 0x000022A6, 0x030, 0x000032A6, + 0x030, 0x000042A6, 0x030, 0x000052A6, 0x030, 0x000062A6, + 0x030, 0x000072A6, 0x030, 0x000082A6, 0x030, 0x000092A6, + 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x030, 0x000004A0, 0x030, 0x000014A0, + 0x030, 0x000024A0, 0x030, 0x000034A0, 0x030, 0x000044A0, + 0x030, 0x000054A0, 0x030, 0x000064A0, 0x030, 0x000074A0, + 0x030, 0x000084A0, 0x030, 0x000094A0, 0x030, 0x0000A4A0, + 0x030, 0x0000B4A0, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0, + 0x030, 0x000034A0, 0x030, 0x000044A0, 0x030, 0x000054A0, + 0x030, 0x000064A0, 0x030, 0x000074A0, 0x030, 0x000084A0, + 0x030, 0x000094A0, 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000004A0, + 0x030, 0x000014A0, 0x030, 0x000024A0, 0x030, 0x000034A0, + 0x030, 0x000044A0, 0x030, 0x000054A0, 0x030, 0x000064A0, + 0x030, 0x000074A0, 0x030, 0x000084A0, 0x030, 0x000094A0, + 0x030, 0x0000A4A0, 0x030, 0x0000B4A0, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000002A1, 0x030, 0x000012A1, + 0x030, 0x000022A1, 0x030, 0x000032A1, 0x030, 0x000042A1, + 0x030, 0x000052A1, 0x030, 0x000062A1, 0x030, 0x000072A1, + 0x030, 0x000082A1, 0x030, 0x000092A1, 0x030, 0x0000A2A1, + 0x030, 0x0000B2A1, 0x9300200c, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000002A6, 0x030, 0x000012A6, 0x030, 0x000022A6, + 0x030, 0x000032A6, 0x030, 0x000042A6, 0x030, 0x000052A6, + 0x030, 0x000062A6, 0x030, 0x000072A6, 0x030, 0x000082A6, + 0x030, 0x000092A6, 0x030, 0x0000A2A6, 0x030, 0x0000B2A6, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002F4, + 0x030, 0x000012F4, 0x030, 0x000022F4, 0x030, 0x000032F4, + 0x030, 0x00004365, 0x030, 0x00005365, 0x030, 0x00006365, + 0x030, 0x00007365, 0x030, 0x000082A4, 0x030, 0x000092A4, + 0x030, 0x0000A2A4, 0x030, 0x0000B2A4, 0x93002100, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000004A4, 0x030, 0x000014A4, + 0x030, 0x000024A4, 0x030, 0x000034A4, 0x030, 0x000043A4, + 0x030, 0x000053A4, 0x030, 0x000063A4, 0x030, 0x000073A4, + 0x030, 0x000083A5, 0x030, 0x000093A5, 0x030, 0x0000A3A5, + 0x030, 0x0000B3A5, 0x93011000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A1, 0x030, 0x000013A1, 0x030, 0x000023A1, + 0x030, 0x000033A1, 0x030, 0x000043A4, 0x030, 0x000053A4, + 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x000083A6, + 0x030, 0x000093A6, 0x030, 0x0000A3A6, 0x030, 0x0000B3A6, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000002A1, + 0x030, 0x000012A1, 0x030, 0x000022A1, 0x030, 0x000032A1, + 0x030, 0x000042A1, 0x030, 0x000052A1, 0x030, 0x000062A1, + 0x030, 0x000072A1, 0x030, 0x000082A1, 0x030, 0x000092A1, + 0x030, 0x0000A2A1, 0x030, 0x0000B2A1, 0x90001004, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000382, 0x030, 0x00001382, + 0x030, 0x00002382, 0x030, 0x00003382, 0x030, 0x00004445, + 0x030, 0x00005445, 0x030, 0x00006445, 0x030, 0x00007445, + 0x030, 0x00008425, 0x030, 0x00009425, 0x030, 0x0000A425, + 0x030, 0x0000B425, 0x93002000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000303, 0x030, 0x00001303, 0x030, 0x00002303, + 0x030, 0x00003303, 0x030, 0x000043A4, 0x030, 0x000053A4, + 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x00008365, + 0x030, 0x00009365, 0x030, 0x0000A365, 0x030, 0x0000B365, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A1, + 0x030, 0x000013A1, 0x030, 0x000023A1, 0x030, 0x000033A1, + 0x030, 0x00004364, 0x030, 0x00005364, 0x030, 0x00006364, + 0x030, 0x00007364, 0x030, 0x00008564, 0x030, 0x00009564, + 0x030, 0x0000A564, 0x030, 0x0000B564, 0x90002100, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000004A1, 0x030, 0x000014A1, + 0x030, 0x000024A1, 0x030, 0x000034A1, 0x030, 0x000043A1, + 0x030, 0x000053A1, 0x030, 0x000063A1, 0x030, 0x000073A1, + 0x030, 0x000083A1, 0x030, 0x000093A1, 0x030, 0x0000A3A1, + 0x030, 0x0000B3A1, 0x90002000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000004A0, 0x030, 0x000014A0, 0x030, 0x000024A0, + 0x030, 0x000034A0, 0x030, 0x000043A1, 0x030, 0x000053A1, + 0x030, 0x000063A1, 0x030, 0x000073A1, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0xA0000000, 0x00000000, 0x030, 0x000002D0, 0x030, 0x000012D0, + 0x030, 0x000022D0, 0x030, 0x000032D0, 0x030, 0x000042D0, + 0x030, 0x000052D0, 0x030, 0x000062D0, 0x030, 0x000072D0, + 0x030, 0x000082D0, 0x030, 0x000092D0, 0x030, 0x0000A2D0, + 0x030, 0x0000B2D0, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000080, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x030, 0x00000203, 0x030, 0x00001203, 0x030, 0x00002203, + 0x030, 0x00003203, 0x030, 0x00004203, 0x030, 0x00005203, + 0x030, 0x00006203, 0x030, 0x00007203, 0x030, 0x00008203, + 0x030, 0x00009203, 0x030, 0x0000A203, 0x030, 0x0000B203, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x030, 0x00000203, + 0x030, 0x00001203, 0x030, 0x00002203, 0x030, 0x00003203, + 0x030, 0x00004203, 0x030, 0x00005203, 0x030, 0x00006203, + 0x030, 0x00007203, 0x030, 0x00008203, 0x030, 0x00009203, + 0x030, 0x0000A203, 0x030, 0x0000B203, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x030, 0x00000203, + 0x030, 0x00001203, 0x030, 0x00002203, 0x030, 0x00003203, + 0x030, 0x00004203, 0x030, 0x00005203, 0x030, 0x00006203, + 0x030, 0x00007203, 0x030, 0x00008203, 0x030, 0x00009203, + 0x030, 0x0000A203, 0x030, 0x0000B203, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x030, 0x00000203, 0x030, 0x00001203, + 0x030, 0x00002203, 0x030, 0x00003203, 0x030, 0x00004203, + 0x030, 0x00005203, 0x030, 0x00006203, 0x030, 0x00007203, + 0x030, 0x00008203, 0x030, 0x00009203, 0x030, 0x0000A203, + 0x030, 0x0000B203, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000203, 0x030, 0x00001203, 0x030, 0x00002203, + 0x030, 0x00003203, 0x030, 0x00004203, 0x030, 0x00005203, + 0x030, 0x00006203, 0x030, 0x00007203, 0x030, 0x00008203, + 0x030, 0x00009203, 0x030, 0x0000A203, 0x030, 0x0000B203, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x9300200c, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93012100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A3, 0x030, 0x000013A3, 0x030, 0x000023A3, + 0x030, 0x000033A3, 0x030, 0x000043A4, 0x030, 0x000053A4, + 0x030, 0x000063A4, 0x030, 0x000073A4, 0x030, 0x000083A3, + 0x030, 0x000093A3, 0x030, 0x0000A3A3, 0x030, 0x0000B3A3, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x93011000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x9000200c, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x93002000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0x93001000, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x000003A2, 0x030, 0x000013A2, 0x030, 0x000023A2, + 0x030, 0x000033A2, 0x030, 0x000043A2, 0x030, 0x000053A2, + 0x030, 0x000063A2, 0x030, 0x000073A2, 0x030, 0x000083A2, + 0x030, 0x000093A2, 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0x90002000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x000003A2, 0x030, 0x000013A2, + 0x030, 0x000023A2, 0x030, 0x000033A2, 0x030, 0x000043A2, + 0x030, 0x000053A2, 0x030, 0x000063A2, 0x030, 0x000073A2, + 0x030, 0x000083A2, 0x030, 0x000093A2, 0x030, 0x0000A3A2, + 0x030, 0x0000B3A2, 0xA0000000, 0x00000000, 0x030, 0x000003A2, + 0x030, 0x000013A2, 0x030, 0x000023A2, 0x030, 0x000033A2, + 0x030, 0x000043A2, 0x030, 0x000053A2, 0x030, 0x000063A2, + 0x030, 0x000073A2, 0x030, 0x000083A2, 0x030, 0x000093A2, + 0x030, 0x0000A3A2, 0x030, 0x0000B3A2, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000040, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004777, 0x030, 0x00005777, + 0x030, 0x00006777, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000645, 0x030, 0x00001333, 0x030, 0x00002011, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000645, + 0x030, 0x00001333, 0x030, 0x00002011, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93012100, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000660, 0x030, 0x00001341, + 0x030, 0x00002220, 0x030, 0x00004777, 0x030, 0x00005777, + 0x030, 0x00006777, 0x93002100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, 0x030, 0x00001452, 0x030, 0x00002220, + 0x030, 0x00004777, 0x030, 0x00005777, 0x030, 0x00006777, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000764, + 0x030, 0x00001632, 0x030, 0x00002421, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0x9000200c, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000645, 0x030, 0x00001333, + 0x030, 0x00002011, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x90001004, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000764, 0x030, 0x00001632, 0x030, 0x00002421, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000777, + 0x030, 0x00001442, 0x030, 0x00002222, 0x030, 0x00004777, + 0x030, 0x00005777, 0x030, 0x00006777, 0x93001000, 0x00000000, + 0x40000000, 0x00000000, 0x030, 0x00000764, 0x030, 0x00001632, + 0x030, 0x00002421, 0x030, 0x00004000, 0x030, 0x00005000, + 0x030, 0x00006000, 0x90002100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x00000775, 0x030, 0x00001222, 0x030, 0x00002210, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x030, 0x00000775, + 0x030, 0x00001422, 0x030, 0x00002210, 0x030, 0x00004000, + 0x030, 0x00005000, 0x030, 0x00006000, 0xA0000000, 0x00000000, + 0x030, 0x00000764, 0x030, 0x00001632, 0x030, 0x00002421, + 0x030, 0x00004000, 0x030, 0x00005000, 0x030, 0x00006000, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0EF, 0x00000800, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000007, 0x033, 0x00000021, 0x03F, 0x0000000A, + 0x033, 0x00000022, 0x03F, 0x0000000D, 0x033, 0x00000023, + 0x03F, 0x0000002A, 0x033, 0x00000024, 0x03F, 0x0000002D, + 0x033, 0x00000025, 0x03F, 0x00000030, 0x033, 0x00000026, + 0x03F, 0x0000006D, 0x033, 0x00000027, 0x03F, 0x00000070, + 0x033, 0x00000028, 0x03F, 0x000000ED, 0x033, 0x00000029, + 0x03F, 0x000000F0, 0x033, 0x0000002A, 0x03F, 0x000000F3, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000828, 0x033, 0x00000021, 0x03F, 0x0000082B, + 0x033, 0x00000022, 0x03F, 0x00000868, 0x033, 0x00000023, + 0x03F, 0x00000889, 0x033, 0x00000024, 0x03F, 0x000008AA, + 0x033, 0x00000025, 0x03F, 0x00000CE8, 0x033, 0x00000026, + 0x03F, 0x00000CEB, 0x033, 0x00000027, 0x03F, 0x00000CEE, + 0x033, 0x00000028, 0x03F, 0x00000CF1, 0x033, 0x00000029, + 0x03F, 0x00000CF4, 0x033, 0x0000002A, 0x03F, 0x00000CF7, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x0000042A, 0x033, 0x00000021, 0x03F, 0x00000829, + 0x033, 0x00000022, 0x03F, 0x00000848, 0x033, 0x00000023, + 0x03F, 0x0000084B, 0x033, 0x00000024, 0x03F, 0x00000C4C, + 0x033, 0x00000025, 0x03F, 0x00000C8B, 0x033, 0x00000026, + 0x03F, 0x00000CEA, 0x033, 0x00000027, 0x03F, 0x00000CED, + 0x033, 0x00000028, 0x03F, 0x00000CF0, 0x033, 0x00000029, + 0x03F, 0x00000CF3, 0x033, 0x0000002A, 0x03F, 0x00000CF6, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000005, 0x033, 0x00000021, 0x03F, 0x00000008, + 0x033, 0x00000022, 0x03F, 0x0000000B, 0x033, 0x00000023, + 0x03F, 0x0000000E, 0x033, 0x00000024, 0x03F, 0x0000002B, + 0x033, 0x00000025, 0x03F, 0x00000068, 0x033, 0x00000026, + 0x03F, 0x0000006B, 0x033, 0x00000027, 0x03F, 0x0000006E, + 0x033, 0x00000028, 0x03F, 0x00000071, 0x033, 0x00000029, + 0x03F, 0x00000074, 0x033, 0x0000002A, 0x03F, 0x00000077, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000429, 0x033, 0x00000021, 0x03F, 0x00000828, + 0x033, 0x00000022, 0x03F, 0x00000847, 0x033, 0x00000023, + 0x03F, 0x0000084A, 0x033, 0x00000024, 0x03F, 0x00000C4B, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000CEA, 0x033, 0x00000027, 0x03F, 0x00000CED, + 0x033, 0x00000028, 0x03F, 0x00000CF0, 0x033, 0x00000029, + 0x03F, 0x00000CF3, 0x033, 0x0000002A, 0x03F, 0x00000CF6, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x00000C09, 0x033, 0x00000021, 0x03F, 0x00000C0C, + 0x033, 0x00000022, 0x03F, 0x00000C0F, 0x033, 0x00000023, + 0x03F, 0x00000C2C, 0x033, 0x00000024, 0x03F, 0x00000C2F, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000C90, + 0x033, 0x00000028, 0x03F, 0x00000CD0, 0x033, 0x00000029, + 0x03F, 0x00000CF2, 0x033, 0x0000002A, 0x03F, 0x00000CF5, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x0000042B, 0x033, 0x00000021, 0x03F, 0x0000082A, + 0x033, 0x00000022, 0x03F, 0x00000849, 0x033, 0x00000023, + 0x03F, 0x0000084C, 0x033, 0x00000024, 0x03F, 0x00000C4C, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000CEB, + 0x033, 0x00000028, 0x03F, 0x00000CEE, 0x033, 0x00000029, + 0x03F, 0x00000CF1, 0x033, 0x0000002A, 0x03F, 0x00000CF4, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000020, + 0x03F, 0x0000042B, 0x033, 0x00000021, 0x03F, 0x0000082A, + 0x033, 0x00000022, 0x03F, 0x00000849, 0x033, 0x00000023, + 0x03F, 0x0000084C, 0x033, 0x00000024, 0x03F, 0x00000C4C, + 0x033, 0x00000025, 0x03F, 0x00000C8A, 0x033, 0x00000026, + 0x03F, 0x00000C8D, 0x033, 0x00000027, 0x03F, 0x00000CEB, + 0x033, 0x00000028, 0x03F, 0x00000CEE, 0x033, 0x00000029, + 0x03F, 0x00000CF1, 0x033, 0x0000002A, 0x03F, 0x00000CF4, + 0xA0000000, 0x00000000, 0x033, 0x00000020, 0x03F, 0x00000C09, + 0x033, 0x00000021, 0x03F, 0x00000C0C, 0x033, 0x00000022, + 0x03F, 0x00000C0F, 0x033, 0x00000023, 0x03F, 0x00000C2C, + 0x033, 0x00000024, 0x03F, 0x00000C2F, 0x033, 0x00000025, + 0x03F, 0x00000C8A, 0x033, 0x00000026, 0x03F, 0x00000C8D, + 0x033, 0x00000027, 0x03F, 0x00000C90, 0x033, 0x00000028, + 0x03F, 0x00000CD0, 0x033, 0x00000029, 0x03F, 0x00000CF2, + 0x033, 0x0000002A, 0x03F, 0x00000CF5, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000007, 0x033, 0x00000061, 0x03F, 0x0000000A, + 0x033, 0x00000062, 0x03F, 0x0000000D, 0x033, 0x00000063, + 0x03F, 0x0000002A, 0x033, 0x00000064, 0x03F, 0x0000002D, + 0x033, 0x00000065, 0x03F, 0x00000030, 0x033, 0x00000066, + 0x03F, 0x0000006D, 0x033, 0x00000067, 0x03F, 0x00000070, + 0x033, 0x00000068, 0x03F, 0x000000ED, 0x033, 0x00000069, + 0x03F, 0x000000F0, 0x033, 0x0000006A, 0x03F, 0x000000F3, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000842, 0x033, 0x00000061, 0x03F, 0x00000845, + 0x033, 0x00000062, 0x03F, 0x00000866, 0x033, 0x00000063, + 0x03F, 0x000008A6, 0x033, 0x00000064, 0x03F, 0x000008C8, + 0x033, 0x00000065, 0x03F, 0x00000CE8, 0x033, 0x00000066, + 0x03F, 0x00000CEB, 0x033, 0x00000067, 0x03F, 0x00000CEE, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x0000042A, 0x033, 0x00000061, 0x03F, 0x00000829, + 0x033, 0x00000062, 0x03F, 0x00000848, 0x033, 0x00000063, + 0x03F, 0x0000084B, 0x033, 0x00000064, 0x03F, 0x00000C69, + 0x033, 0x00000065, 0x03F, 0x00000CA9, 0x033, 0x00000066, + 0x03F, 0x00000CEA, 0x033, 0x00000067, 0x03F, 0x00000CED, + 0x033, 0x00000068, 0x03F, 0x00000CF0, 0x033, 0x00000069, + 0x03F, 0x00000CF3, 0x033, 0x0000006A, 0x03F, 0x00000CF6, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000005, 0x033, 0x00000061, 0x03F, 0x00000008, + 0x033, 0x00000062, 0x03F, 0x0000000B, 0x033, 0x00000063, + 0x03F, 0x0000000E, 0x033, 0x00000064, 0x03F, 0x0000002B, + 0x033, 0x00000065, 0x03F, 0x00000068, 0x033, 0x00000066, + 0x03F, 0x0000006B, 0x033, 0x00000067, 0x03F, 0x0000006E, + 0x033, 0x00000068, 0x03F, 0x00000071, 0x033, 0x00000069, + 0x03F, 0x00000074, 0x033, 0x0000006A, 0x03F, 0x00000077, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000429, 0x033, 0x00000061, 0x03F, 0x00000828, + 0x033, 0x00000062, 0x03F, 0x00000847, 0x033, 0x00000063, + 0x03F, 0x0000084A, 0x033, 0x00000064, 0x03F, 0x00000C4B, + 0x033, 0x00000065, 0x03F, 0x00000C8A, 0x033, 0x00000066, + 0x03F, 0x00000CEA, 0x033, 0x00000067, 0x03F, 0x00000CED, + 0x033, 0x00000068, 0x03F, 0x00000CF0, 0x033, 0x00000069, + 0x03F, 0x00000CF3, 0x033, 0x0000006A, 0x03F, 0x00000CF6, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x00000C0A, 0x033, 0x00000061, 0x03F, 0x00000C0D, + 0x033, 0x00000062, 0x03F, 0x00000C2A, 0x033, 0x00000063, + 0x03F, 0x00000C2D, 0x033, 0x00000064, 0x03F, 0x00000C6A, + 0x033, 0x00000065, 0x03F, 0x00000CAA, 0x033, 0x00000066, + 0x03F, 0x00000CAD, 0x033, 0x00000067, 0x03F, 0x00000CB0, + 0x033, 0x00000068, 0x03F, 0x00000CF1, 0x033, 0x00000069, + 0x03F, 0x00000CF4, 0x033, 0x0000006A, 0x03F, 0x00000CF7, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x0000042C, 0x033, 0x00000061, 0x03F, 0x0000082B, + 0x033, 0x00000062, 0x03F, 0x0000084A, 0x033, 0x00000063, + 0x03F, 0x0000084D, 0x033, 0x00000064, 0x03F, 0x00000C4E, + 0x033, 0x00000065, 0x03F, 0x00000C8C, 0x033, 0x00000066, + 0x03F, 0x00000C8F, 0x033, 0x00000067, 0x03F, 0x00000CEC, + 0x033, 0x00000068, 0x03F, 0x00000CEF, 0x033, 0x00000069, + 0x03F, 0x00000CF2, 0x033, 0x0000006A, 0x03F, 0x00000CF5, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000060, + 0x03F, 0x0000042C, 0x033, 0x00000061, 0x03F, 0x0000082B, + 0x033, 0x00000062, 0x03F, 0x0000084A, 0x033, 0x00000063, + 0x03F, 0x0000084D, 0x033, 0x00000064, 0x03F, 0x00000C4E, + 0x033, 0x00000065, 0x03F, 0x00000C8C, 0x033, 0x00000066, + 0x03F, 0x00000C8F, 0x033, 0x00000067, 0x03F, 0x00000CEC, + 0x033, 0x00000068, 0x03F, 0x00000CEF, 0x033, 0x00000069, + 0x03F, 0x00000CF2, 0x033, 0x0000006A, 0x03F, 0x00000CF5, + 0xA0000000, 0x00000000, 0x033, 0x00000060, 0x03F, 0x00000C0A, + 0x033, 0x00000061, 0x03F, 0x00000C0D, 0x033, 0x00000062, + 0x03F, 0x00000C2A, 0x033, 0x00000063, 0x03F, 0x00000C2D, + 0x033, 0x00000064, 0x03F, 0x00000C6A, 0x033, 0x00000065, + 0x03F, 0x00000CAA, 0x033, 0x00000066, 0x03F, 0x00000CAD, + 0x033, 0x00000067, 0x03F, 0x00000CB0, 0x033, 0x00000068, + 0x03F, 0x00000CF1, 0x033, 0x00000069, 0x03F, 0x00000CF4, + 0x033, 0x0000006A, 0x03F, 0x00000CF7, 0xB0000000, 0x00000000, + 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9300200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9000100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000007, 0x033, 0x000000A1, 0x03F, 0x0000000A, + 0x033, 0x000000A2, 0x03F, 0x0000000D, 0x033, 0x000000A3, + 0x03F, 0x0000002A, 0x033, 0x000000A4, 0x03F, 0x0000002D, + 0x033, 0x000000A5, 0x03F, 0x00000030, 0x033, 0x000000A6, + 0x03F, 0x0000006D, 0x033, 0x000000A7, 0x03F, 0x00000070, + 0x033, 0x000000A8, 0x03F, 0x000000ED, 0x033, 0x000000A9, + 0x03F, 0x000000F0, 0x033, 0x000000AA, 0x03F, 0x000000F3, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x9300200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x93012100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000826, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x0000082C, 0x033, 0x000000A3, + 0x03F, 0x0000082F, 0x033, 0x000000A4, 0x03F, 0x0000086C, + 0x033, 0x000000A5, 0x03F, 0x00000CE8, 0x033, 0x000000A6, + 0x03F, 0x00000CEB, 0x033, 0x000000A7, 0x03F, 0x00000CEE, + 0x033, 0x000000A8, 0x03F, 0x00000CF1, 0x033, 0x000000A9, + 0x03F, 0x00000CF4, 0x033, 0x000000AA, 0x03F, 0x00000CF7, + 0x93002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3, + 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C, + 0x033, 0x000000A5, 0x03F, 0x00000CA9, 0x033, 0x000000A6, + 0x03F, 0x00000CEA, 0x033, 0x000000A7, 0x03F, 0x00000CED, + 0x033, 0x000000A8, 0x03F, 0x00000CF0, 0x033, 0x000000A9, + 0x03F, 0x00000CF3, 0x033, 0x000000AA, 0x03F, 0x00000CF6, + 0x93011000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x9000200c, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000005, 0x033, 0x000000A1, 0x03F, 0x00000008, + 0x033, 0x000000A2, 0x03F, 0x0000000B, 0x033, 0x000000A3, + 0x03F, 0x0000000E, 0x033, 0x000000A4, 0x03F, 0x00000047, + 0x033, 0x000000A5, 0x03F, 0x0000004A, 0x033, 0x000000A6, + 0x03F, 0x0000004D, 0x033, 0x000000A7, 0x03F, 0x00000050, + 0x033, 0x000000A8, 0x03F, 0x00000053, 0x033, 0x000000A9, + 0x03F, 0x00000056, 0x033, 0x000000AA, 0x03F, 0x00000094, + 0x90001004, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x93002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000429, 0x033, 0x000000A1, 0x03F, 0x00000828, + 0x033, 0x000000A2, 0x03F, 0x00000847, 0x033, 0x000000A3, + 0x03F, 0x0000084A, 0x033, 0x000000A4, 0x03F, 0x00000C4B, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000CEA, 0x033, 0x000000A7, 0x03F, 0x00000CED, + 0x033, 0x000000A8, 0x03F, 0x00000CF0, 0x033, 0x000000A9, + 0x03F, 0x00000CF3, 0x033, 0x000000AA, 0x03F, 0x00000CF6, + 0x93001000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x00000C09, 0x033, 0x000000A1, 0x03F, 0x00000C0C, + 0x033, 0x000000A2, 0x03F, 0x00000C0F, 0x033, 0x000000A3, + 0x03F, 0x00000C2C, 0x033, 0x000000A4, 0x03F, 0x00000C2F, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000C90, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x90002100, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3, + 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000CEC, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0x90002000, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x000000A0, + 0x03F, 0x0000042A, 0x033, 0x000000A1, 0x03F, 0x00000829, + 0x033, 0x000000A2, 0x03F, 0x00000848, 0x033, 0x000000A3, + 0x03F, 0x0000084B, 0x033, 0x000000A4, 0x03F, 0x00000C4C, + 0x033, 0x000000A5, 0x03F, 0x00000C8A, 0x033, 0x000000A6, + 0x03F, 0x00000C8D, 0x033, 0x000000A7, 0x03F, 0x00000CEC, + 0x033, 0x000000A8, 0x03F, 0x00000CEF, 0x033, 0x000000A9, + 0x03F, 0x00000CF2, 0x033, 0x000000AA, 0x03F, 0x00000CF5, + 0xA0000000, 0x00000000, 0x033, 0x000000A0, 0x03F, 0x00000C09, + 0x033, 0x000000A1, 0x03F, 0x00000C0C, 0x033, 0x000000A2, + 0x03F, 0x00000C0F, 0x033, 0x000000A3, 0x03F, 0x00000C2C, + 0x033, 0x000000A4, 0x03F, 0x00000C2F, 0x033, 0x000000A5, + 0x03F, 0x00000C8A, 0x033, 0x000000A6, 0x03F, 0x00000C8D, + 0x033, 0x000000A7, 0x03F, 0x00000C90, 0x033, 0x000000A8, + 0x03F, 0x00000CEF, 0x033, 0x000000A9, 0x03F, 0x00000CF2, + 0x033, 0x000000AA, 0x03F, 0x00000CF5, 0xB0000000, 0x00000000, + 0x0EF, 0x00000000, 0x0EF, 0x00000400, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A, + 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002, + 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A, + 0x9300100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A, + 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003, + 0x03F, 0x0000265A, 0x9300100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000265A, 0x033, 0x00000001, + 0x03F, 0x0000265A, 0x033, 0x00000002, 0x03F, 0x0000265A, + 0x033, 0x00000003, 0x03F, 0x0000265A, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A, + 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002, + 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A, + 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A, + 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003, + 0x03F, 0x0000265A, 0x9000100f, 0x05050505, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0000265A, 0x033, 0x00000001, + 0x03F, 0x0000265A, 0x033, 0x00000002, 0x03F, 0x0000265A, + 0x033, 0x00000003, 0x03F, 0x0000265A, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x0000265A, + 0x033, 0x00000001, 0x03F, 0x0000265A, 0x033, 0x00000002, + 0x03F, 0x0000265A, 0x033, 0x00000003, 0x03F, 0x0000265A, + 0x9000200f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x0000265A, 0x033, 0x00000001, 0x03F, 0x0000265A, + 0x033, 0x00000002, 0x03F, 0x0000265A, 0x033, 0x00000003, + 0x03F, 0x0000265A, 0xA0000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x000004BB, 0x033, 0x00000001, 0x03F, 0x000004BB, + 0x033, 0x00000002, 0x03F, 0x000004BB, 0x033, 0x00000003, + 0x03F, 0x000004BB, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000100, 0x8300100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001, + 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745, + 0x033, 0x00000003, 0x03F, 0x00000745, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745, + 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002, + 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000745, 0x033, 0x00000001, 0x03F, 0x00000745, + 0x033, 0x00000002, 0x03F, 0x00000745, 0x033, 0x00000003, + 0x03F, 0x00000745, 0x9300200f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001, + 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745, + 0x033, 0x00000003, 0x03F, 0x00000745, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745, + 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002, + 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x033, 0x00000000, + 0x03F, 0x00000745, 0x033, 0x00000001, 0x03F, 0x00000745, + 0x033, 0x00000002, 0x03F, 0x00000745, 0x033, 0x00000003, + 0x03F, 0x00000745, 0x9000100f, 0x00000000, 0x40000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x00000745, 0x033, 0x00000001, + 0x03F, 0x00000745, 0x033, 0x00000002, 0x03F, 0x00000745, + 0x033, 0x00000003, 0x03F, 0x00000745, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000745, + 0x033, 0x00000001, 0x03F, 0x00000745, 0x033, 0x00000002, + 0x03F, 0x00000745, 0x033, 0x00000003, 0x03F, 0x00000745, + 0xA0000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000F34, + 0x033, 0x00000001, 0x03F, 0x00000F34, 0x033, 0x00000002, + 0x03F, 0x00000F34, 0x033, 0x00000003, 0x03F, 0x00000F34, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9300100f, 0x05050505, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9300100f, 0x00000000, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9000100f, 0x0a0a0a0a, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0x9000100f, 0x05050505, 0x40000000, 0x00000000, 0x081, 0x0000F400, + 0x087, 0x00016040, 0x051, 0x00000808, 0x052, 0x00098002, + 0x053, 0x0000FA47, 0x054, 0x00058032, 0x056, 0x00051000, + 0x057, 0x0000CE0A, 0x058, 0x00082030, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x081, 0x0000F400, 0x087, 0x00016040, + 0x051, 0x00000808, 0x052, 0x00098002, 0x053, 0x0000FA47, + 0x054, 0x00058032, 0x056, 0x00051000, 0x057, 0x0000CE0A, + 0x058, 0x00082030, 0x9000200f, 0x00000000, 0x40000000, 0x00000000, + 0x081, 0x0000F400, 0x087, 0x00016040, 0x051, 0x00000808, + 0x052, 0x00098002, 0x053, 0x0000FA47, 0x054, 0x00058032, + 0x056, 0x00051000, 0x057, 0x0000CE0A, 0x058, 0x00082030, + 0xA0000000, 0x00000000, 0x081, 0x0000F000, 0x087, 0x00016040, + 0x051, 0x00000C00, 0x052, 0x0007C241, 0x053, 0x0001C069, + 0x054, 0x00078032, 0x057, 0x0000CE0A, 0x058, 0x00058750, + 0xB0000000, 0x00000000, 0x0EF, 0x00000800, 0x8300100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9300200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x0a0a0a0a, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x05050505, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000100f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0x9000200f, 0x00000000, + 0x40000000, 0x00000000, 0x033, 0x00000000, 0x03F, 0x00000003, + 0x033, 0x00000001, 0x03F, 0x00000006, 0x033, 0x00000002, + 0x03F, 0x00000009, 0x033, 0x00000003, 0x03F, 0x00000026, + 0x033, 0x00000004, 0x03F, 0x00000029, 0x033, 0x00000005, + 0x03F, 0x0000002C, 0x033, 0x00000006, 0x03F, 0x0000002F, + 0x033, 0x00000007, 0x03F, 0x00000033, 0x033, 0x00000008, + 0x03F, 0x00000036, 0x033, 0x00000009, 0x03F, 0x00000039, + 0x033, 0x0000000A, 0x03F, 0x0000003C, 0xA0000000, 0x00000000, + 0x033, 0x00000000, 0x03F, 0x0005142C, 0x033, 0x00000001, + 0x03F, 0x0005142F, 0x033, 0x00000002, 0x03F, 0x00051432, + 0x033, 0x00000003, 0x03F, 0x00051C87, 0x033, 0x00000004, + 0x03F, 0x00051C8A, 0x033, 0x00000005, 0x03F, 0x00051C8D, + 0x033, 0x00000006, 0x03F, 0x00051CEB, 0x033, 0x00000007, + 0x03F, 0x00051CEE, 0x033, 0x00000008, 0x03F, 0x00051CF1, + 0x033, 0x00000009, 0x03F, 0x00051CF4, 0x033, 0x0000000A, + 0x03F, 0x00051CF7, 0xB0000000, 0x00000000, 0x0EF, 0x00000000, + 0x0EF, 0x00000010, 0x033, 0x00000000, 0x008, 0x0009C060, + 0x033, 0x00000001, 0x008, 0x0009C060, 0x0EF, 0x00000000, + 0x033, 0x000000A2, 0x0EF, 0x00080000, 0x03E, 0x0000593F, + 0x03F, 0x000C0F4F, 0x0EF, 0x00000000, 0x033, 0x000000A3, + 0x0EF, 0x00080000, 0x03E, 0x00005934, 0x03F, 0x0005AFCF, + 0x0EF, 0x00000000, + +}; + +void odm_read_and_config_mp_8822b_radiob(struct phy_dm_struct *dm) +{ + u32 i = 0; + u8 c_cond; + bool is_matched = true, is_skipped = false; + u32 array_len = sizeof(array_mp_8822b_radiob) / sizeof(u32); + u32 *array = array_mp_8822b_radiob; + + u32 v1 = 0, v2 = 0, pre_v1 = 0, pre_v2 = 0; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (; (i + 1) < array_len; i = i + 2) { + v1 = array[i]; + v2 = array[i + 1]; + + if (v1 & BIT(31)) { /* positive condition*/ + c_cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); + if (c_cond == COND_ENDIF) { /*end*/ + is_matched = true; + is_skipped = false; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ENDIF\n"); + } else if (c_cond == COND_ELSE) { /*else*/ + is_matched = is_skipped ? false : true; + ODM_RT_TRACE(dm, ODM_COMP_INIT, "ELSE\n"); + } else { /*if , else if*/ + pre_v1 = v1; + pre_v2 = v2; + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "IF or ELSE IF\n"); + } + } else if (v1 & BIT(30)) { /*negative condition*/ + if (is_skipped) { + is_matched = false; + continue; + } + + if (check_positive(dm, pre_v1, pre_v2, v1, v2)) { + is_matched = true; + is_skipped = true; + } else { + is_matched = false; + is_skipped = false; + } + } else if (is_matched) { + odm_config_rf_radio_b_8822b(dm, v1, v2); + } + } +} + +u32 odm_get_version_mp_8822b_radiob(void) { return 67; } + +/****************************************************************************** + * txpowertrack.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 18, 18, 18}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 10, 11, 12, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_8822b[][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, + 10, 11, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 18, 18, 18}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type0.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type0_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type0_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type0_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type0_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type0_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type0(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type0_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type1.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 15, 16, 17, 17, 18, 18, 18, 18, 18, 18}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 10, 11, 12, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type1_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 20, 20}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, + 10, 11, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18, 18, 18}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 6, 7, 8, 8, 9, 10, + 11, 12, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 18, 18, 18}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type1_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type1_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type1_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type1_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type1(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type1_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type2.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type2_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type2_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type2(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type2_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type3_type5.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type3_type5_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type3_type5_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type3_type5( + struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory( + dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type3_type5_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type4.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, + 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type4_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type4_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type4(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type4_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type6.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 11, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 21, 21, 21}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type6_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, + 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21}, + {0, 1, 2, 2, 3, 4, 4, 5, 7, 7, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 21, 21}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 20, 20, 20, 20}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type6_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type6_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type6_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type6_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type6(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type6_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type7.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, + 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 15, 15, 15}, + {0, 1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, + {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, + 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 19, 19, 19, 19, 19}, + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 9, 11, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21, 21}, + {0, 1, 2, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10, 11, 12, + 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 20, 20, 21, 21, 21}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, + 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 17}, + {0, 1, 2, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 15}, + {0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, + 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type7_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, + 13, 14, 15, 15, 16, 17, 18, 19, 20, 20, 21, 21, 21, 21, 21}, + {0, 1, 2, 2, 3, 4, 4, 5, 7, 7, 8, 9, 10, 11, 11, + 12, 13, 13, 14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 21, 21}, + {0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 14, 15, 16, 17, 17, 18, 19, 19, 20, 20, 20, 20, 20}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type7_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type7_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type7_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type7_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type7(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type7_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type8.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type8_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, + 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16, 17}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type8_8822b[] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; + +void odm_read_and_config_mp_8822b_txpowertrack_type8(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type8_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpowertrack_type9.TXT + ******************************************************************************/ + +static u8 delta_swing_index_mp_5gb_n_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_5gb_p_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 12, 13, 14, 14, 15, 15, 15, 16, 16}, +}; + +static u8 delta_swing_index_mp_5ga_n_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14}, +}; + +static u8 delta_swing_index_mp_5ga_p_txpwrtrack_type9_8822b + [][DELTA_SWINGIDX_SIZE] = { + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 13, 13, 14, 14, 15, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 15, 15}, + {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 15, 15}, +}; + +static u8 delta_swing_index_mp_2gb_n_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2gb_p_txpwrtrack_type9_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2ga_n_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2ga_p_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type9_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17}; + +static u8 delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type9_8822b[] = { + 0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +static u8 delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 13, 14, 15, 16, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; + +static u8 delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type9_8822b[] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, + 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 22, 22}; + +void odm_read_and_config_mp_8822b_txpowertrack_type9(struct phy_dm_struct *dm) +{ + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> ODM_ReadAndConfig_MP_mp_8822b\n"); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_p, + delta_swing_index_mp_2ga_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2ga_n, + delta_swing_index_mp_2ga_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_p, + delta_swing_index_mp_2gb_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2gb_n, + delta_swing_index_mp_2gb_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_p, + delta_swing_index_mp_2g_cck_a_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_a_n, + delta_swing_index_mp_2g_cck_a_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_p, + delta_swing_index_mp_2g_cck_b_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + odm_move_memory(dm, cali_info->delta_swing_table_idx_2g_cck_b_n, + delta_swing_index_mp_2g_cck_b_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE); + + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_p, + delta_swing_index_mp_5ga_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5ga_n, + delta_swing_index_mp_5ga_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_p, + delta_swing_index_mp_5gb_p_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); + odm_move_memory(dm, cali_info->delta_swing_table_idx_5gb_n, + delta_swing_index_mp_5gb_n_txpwrtrack_type9_8822b, + DELTA_SWINGIDX_SIZE * 3); +} + +/****************************************************************************** + * txpwr_lmt.TXT + ******************************************************************************/ + +static const char *const array_mp_8822b_txpwr_lmt[] = { + "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "01", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "01", "30", "FCC", "2.4G", "20M", "CCK", "1T", "02", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "02", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "02", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "03", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "03", "28", "MKK", "2.4G", "20M", "CCK", "1T", "03", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "04", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "04", "30", "FCC", "2.4G", "20M", "CCK", "1T", "05", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "05", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "05", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "06", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "06", "28", "MKK", "2.4G", "20M", "CCK", "1T", "06", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "07", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "07", "30", "FCC", "2.4G", "20M", "CCK", "1T", "08", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "08", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "08", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "09", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "09", "28", "MKK", "2.4G", "20M", "CCK", "1T", "09", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "10", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "10", "30", "FCC", "2.4G", "20M", "CCK", "1T", "11", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "11", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "11", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "12", "26", "ETSI", "2.4G", "20M", "CCK", "1T", + "12", "28", "MKK", "2.4G", "20M", "CCK", "1T", "12", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "13", "20", "ETSI", "2.4G", + "20M", "CCK", "1T", "13", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "13", "28", "FCC", "2.4G", "20M", "CCK", "1T", "14", + "63", "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", "MKK", + "2.4G", "20M", "CCK", "1T", "14", "32", "FCC", "2.4G", "20M", + "OFDM", "1T", "01", "26", "ETSI", "2.4G", "20M", "OFDM", "1T", + "01", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30", "ETSI", "2.4G", + "20M", "OFDM", "1T", "02", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "02", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "03", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "03", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "04", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "04", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "05", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "05", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "06", + "34", "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "06", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "07", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "07", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "08", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "08", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "09", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "09", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "10", "30", "ETSI", "2.4G", "20M", "OFDM", "1T", + "10", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28", "ETSI", "2.4G", + "20M", "OFDM", "1T", "11", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "11", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "12", + "22", "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "12", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "13", "14", "ETSI", "2.4G", "20M", "OFDM", "1T", + "13", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", "ETSI", "2.4G", + "20M", "OFDM", "1T", "14", "63", "MKK", "2.4G", "20M", "OFDM", + "1T", "14", "63", "FCC", "2.4G", "20M", "HT", "1T", "01", + "26", "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", "MKK", + "2.4G", "20M", "HT", "1T", "01", "34", "FCC", "2.4G", "20M", + "HT", "1T", "02", "30", "ETSI", "2.4G", "20M", "HT", "1T", + "02", "30", "MKK", "2.4G", "20M", "HT", "1T", "02", "34", + "FCC", "2.4G", "20M", "HT", "1T", "03", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "03", "30", "MKK", "2.4G", "20M", "HT", + "1T", "03", "34", "FCC", "2.4G", "20M", "HT", "1T", "04", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", "MKK", + "2.4G", "20M", "HT", "1T", "04", "34", "FCC", "2.4G", "20M", + "HT", "1T", "05", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "05", "30", "MKK", "2.4G", "20M", "HT", "1T", "05", "34", + "FCC", "2.4G", "20M", "HT", "1T", "06", "34", "ETSI", "2.4G", + "20M", "HT", "1T", "06", "30", "MKK", "2.4G", "20M", "HT", + "1T", "06", "34", "FCC", "2.4G", "20M", "HT", "1T", "07", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", "MKK", + "2.4G", "20M", "HT", "1T", "07", "34", "FCC", "2.4G", "20M", + "HT", "1T", "08", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "08", "30", "MKK", "2.4G", "20M", "HT", "1T", "08", "34", + "FCC", "2.4G", "20M", "HT", "1T", "09", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "09", "30", "MKK", "2.4G", "20M", "HT", + "1T", "09", "34", "FCC", "2.4G", "20M", "HT", "1T", "10", + "30", "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", "MKK", + "2.4G", "20M", "HT", "1T", "10", "34", "FCC", "2.4G", "20M", + "HT", "1T", "11", "26", "ETSI", "2.4G", "20M", "HT", "1T", + "11", "30", "MKK", "2.4G", "20M", "HT", "1T", "11", "34", + "FCC", "2.4G", "20M", "HT", "1T", "12", "20", "ETSI", "2.4G", + "20M", "HT", "1T", "12", "30", "MKK", "2.4G", "20M", "HT", + "1T", "12", "34", "FCC", "2.4G", "20M", "HT", "1T", "13", + "14", "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", "MKK", + "2.4G", "20M", "HT", "1T", "13", "34", "FCC", "2.4G", "20M", + "HT", "1T", "14", "63", "ETSI", "2.4G", "20M", "HT", "1T", + "14", "63", "MKK", "2.4G", "20M", "HT", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "2T", "01", "26", "ETSI", "2.4G", + "20M", "HT", "2T", "01", "18", "MKK", "2.4G", "20M", "HT", + "2T", "01", "30", "FCC", "2.4G", "20M", "HT", "2T", "02", + "28", "ETSI", "2.4G", "20M", "HT", "2T", "02", "18", "MKK", + "2.4G", "20M", "HT", "2T", "02", "30", "FCC", "2.4G", "20M", + "HT", "2T", "03", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "03", "18", "MKK", "2.4G", "20M", "HT", "2T", "03", "30", + "FCC", "2.4G", "20M", "HT", "2T", "04", "30", "ETSI", "2.4G", + "20M", "HT", "2T", "04", "18", "MKK", "2.4G", "20M", "HT", + "2T", "04", "30", "FCC", "2.4G", "20M", "HT", "2T", "05", + "32", "ETSI", "2.4G", "20M", "HT", "2T", "05", "18", "MKK", + "2.4G", "20M", "HT", "2T", "05", "30", "FCC", "2.4G", "20M", + "HT", "2T", "06", "32", "ETSI", "2.4G", "20M", "HT", "2T", + "06", "18", "MKK", "2.4G", "20M", "HT", "2T", "06", "30", + "FCC", "2.4G", "20M", "HT", "2T", "07", "32", "ETSI", "2.4G", + "20M", "HT", "2T", "07", "18", "MKK", "2.4G", "20M", "HT", + "2T", "07", "30", "FCC", "2.4G", "20M", "HT", "2T", "08", + "30", "ETSI", "2.4G", "20M", "HT", "2T", "08", "18", "MKK", + "2.4G", "20M", "HT", "2T", "08", "30", "FCC", "2.4G", "20M", + "HT", "2T", "09", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "09", "18", "MKK", "2.4G", "20M", "HT", "2T", "09", "30", + "FCC", "2.4G", "20M", "HT", "2T", "10", "28", "ETSI", "2.4G", + "20M", "HT", "2T", "10", "18", "MKK", "2.4G", "20M", "HT", + "2T", "10", "30", "FCC", "2.4G", "20M", "HT", "2T", "11", + "26", "ETSI", "2.4G", "20M", "HT", "2T", "11", "18", "MKK", + "2.4G", "20M", "HT", "2T", "11", "30", "FCC", "2.4G", "20M", + "HT", "2T", "12", "20", "ETSI", "2.4G", "20M", "HT", "2T", + "12", "18", "MKK", "2.4G", "20M", "HT", "2T", "12", "30", + "FCC", "2.4G", "20M", "HT", "2T", "13", "14", "ETSI", "2.4G", + "20M", "HT", "2T", "13", "18", "MKK", "2.4G", "20M", "HT", + "2T", "13", "30", "FCC", "2.4G", "20M", "HT", "2T", "14", + "63", "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", "MKK", + "2.4G", "20M", "HT", "2T", "14", "63", "FCC", "2.4G", "40M", + "HT", "1T", "01", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "01", "63", "MKK", "2.4G", "40M", "HT", "1T", "01", "63", + "FCC", "2.4G", "40M", "HT", "1T", "02", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "02", "63", "MKK", "2.4G", "40M", "HT", + "1T", "02", "63", "FCC", "2.4G", "40M", "HT", "1T", "03", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", "MKK", + "2.4G", "40M", "HT", "1T", "03", "34", "FCC", "2.4G", "40M", + "HT", "1T", "04", "26", "ETSI", "2.4G", "40M", "HT", "1T", + "04", "30", "MKK", "2.4G", "40M", "HT", "1T", "04", "34", + "FCC", "2.4G", "40M", "HT", "1T", "05", "30", "ETSI", "2.4G", + "40M", "HT", "1T", "05", "30", "MKK", "2.4G", "40M", "HT", + "1T", "05", "34", "FCC", "2.4G", "40M", "HT", "1T", "06", + "32", "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", "MKK", + "2.4G", "40M", "HT", "1T", "06", "34", "FCC", "2.4G", "40M", + "HT", "1T", "07", "30", "ETSI", "2.4G", "40M", "HT", "1T", + "07", "30", "MKK", "2.4G", "40M", "HT", "1T", "07", "34", + "FCC", "2.4G", "40M", "HT", "1T", "08", "26", "ETSI", "2.4G", + "40M", "HT", "1T", "08", "30", "MKK", "2.4G", "40M", "HT", + "1T", "08", "34", "FCC", "2.4G", "40M", "HT", "1T", "09", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", "MKK", + "2.4G", "40M", "HT", "1T", "09", "34", "FCC", "2.4G", "40M", + "HT", "1T", "10", "20", "ETSI", "2.4G", "40M", "HT", "1T", + "10", "30", "MKK", "2.4G", "40M", "HT", "1T", "10", "34", + "FCC", "2.4G", "40M", "HT", "1T", "11", "14", "ETSI", "2.4G", + "40M", "HT", "1T", "11", "30", "MKK", "2.4G", "40M", "HT", + "1T", "11", "34", "FCC", "2.4G", "40M", "HT", "1T", "12", + "63", "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", "MKK", + "2.4G", "40M", "HT", "1T", "12", "63", "FCC", "2.4G", "40M", + "HT", "1T", "13", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "13", "63", "MKK", "2.4G", "40M", "HT", "1T", "13", "63", + "FCC", "2.4G", "40M", "HT", "1T", "14", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "14", "63", "MKK", "2.4G", "40M", "HT", + "1T", "14", "63", "FCC", "2.4G", "40M", "HT", "2T", "01", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", "MKK", + "2.4G", "40M", "HT", "2T", "01", "63", "FCC", "2.4G", "40M", + "HT", "2T", "02", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "02", "63", "MKK", "2.4G", "40M", "HT", "2T", "02", "63", + "FCC", "2.4G", "40M", "HT", "2T", "03", "24", "ETSI", "2.4G", + "40M", "HT", "2T", "03", "18", "MKK", "2.4G", "40M", "HT", + "2T", "03", "30", "FCC", "2.4G", "40M", "HT", "2T", "04", + "24", "ETSI", "2.4G", "40M", "HT", "2T", "04", "18", "MKK", + "2.4G", "40M", "HT", "2T", "04", "30", "FCC", "2.4G", "40M", + "HT", "2T", "05", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "05", "18", "MKK", "2.4G", "40M", "HT", "2T", "05", "30", + "FCC", "2.4G", "40M", "HT", "2T", "06", "28", "ETSI", "2.4G", + "40M", "HT", "2T", "06", "18", "MKK", "2.4G", "40M", "HT", + "2T", "06", "30", "FCC", "2.4G", "40M", "HT", "2T", "07", + "26", "ETSI", "2.4G", "40M", "HT", "2T", "07", "18", "MKK", + "2.4G", "40M", "HT", "2T", "07", "30", "FCC", "2.4G", "40M", + "HT", "2T", "08", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "08", "18", "MKK", "2.4G", "40M", "HT", "2T", "08", "30", + "FCC", "2.4G", "40M", "HT", "2T", "09", "26", "ETSI", "2.4G", + "40M", "HT", "2T", "09", "18", "MKK", "2.4G", "40M", "HT", + "2T", "09", "30", "FCC", "2.4G", "40M", "HT", "2T", "10", + "20", "ETSI", "2.4G", "40M", "HT", "2T", "10", "18", "MKK", + "2.4G", "40M", "HT", "2T", "10", "30", "FCC", "2.4G", "40M", + "HT", "2T", "11", "14", "ETSI", "2.4G", "40M", "HT", "2T", + "11", "18", "MKK", "2.4G", "40M", "HT", "2T", "11", "30", + "FCC", "2.4G", "40M", "HT", "2T", "12", "63", "ETSI", "2.4G", + "40M", "HT", "2T", "12", "63", "MKK", "2.4G", "40M", "HT", + "2T", "12", "63", "FCC", "2.4G", "40M", "HT", "2T", "13", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "13", "63", "MKK", + "2.4G", "40M", "HT", "2T", "13", "63", "FCC", "2.4G", "40M", + "HT", "2T", "14", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "14", "63", "MKK", "2.4G", "40M", "HT", "2T", "14", "63", + "FCC", "5G", "20M", "OFDM", "1T", "36", "30", "ETSI", "5G", + "20M", "OFDM", "1T", "36", "32", "MKK", "5G", "20M", "OFDM", + "1T", "36", "30", "FCC", "5G", "20M", "OFDM", "1T", "40", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", "MKK", + "5G", "20M", "OFDM", "1T", "40", "30", "FCC", "5G", "20M", + "OFDM", "1T", "44", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "44", "32", "MKK", "5G", "20M", "OFDM", "1T", "44", "30", + "FCC", "5G", "20M", "OFDM", "1T", "48", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "48", "32", "MKK", "5G", "20M", "OFDM", + "1T", "48", "30", "FCC", "5G", "20M", "OFDM", "1T", "52", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", "MKK", + "5G", "20M", "OFDM", "1T", "52", "28", "FCC", "5G", "20M", + "OFDM", "1T", "56", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "56", "32", "MKK", "5G", "20M", "OFDM", "1T", "56", "28", + "FCC", "5G", "20M", "OFDM", "1T", "60", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "60", "32", "MKK", "5G", "20M", "OFDM", + "1T", "60", "28", "FCC", "5G", "20M", "OFDM", "1T", "64", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", "MKK", + "5G", "20M", "OFDM", "1T", "64", "28", "FCC", "5G", "20M", + "OFDM", "1T", "100", "26", "ETSI", "5G", "20M", "OFDM", "1T", + "100", "32", "MKK", "5G", "20M", "OFDM", "1T", "100", "32", + "FCC", "5G", "20M", "OFDM", "1T", "104", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "104", "32", "MKK", "5G", "20M", "OFDM", + "1T", "104", "32", "FCC", "5G", "20M", "OFDM", "1T", "108", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", "MKK", + "5G", "20M", "OFDM", "1T", "108", "32", "FCC", "5G", "20M", + "OFDM", "1T", "112", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "112", "32", "MKK", "5G", "20M", "OFDM", "1T", "112", "32", + "FCC", "5G", "20M", "OFDM", "1T", "116", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "116", "32", "MKK", "5G", "20M", "OFDM", + "1T", "116", "32", "FCC", "5G", "20M", "OFDM", "1T", "120", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", "MKK", + "5G", "20M", "OFDM", "1T", "120", "32", "FCC", "5G", "20M", + "OFDM", "1T", "124", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "124", "32", "MKK", "5G", "20M", "OFDM", "1T", "124", "32", + "FCC", "5G", "20M", "OFDM", "1T", "128", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "128", "32", "MKK", "5G", "20M", "OFDM", + "1T", "128", "32", "FCC", "5G", "20M", "OFDM", "1T", "132", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", "MKK", + "5G", "20M", "OFDM", "1T", "132", "32", "FCC", "5G", "20M", + "OFDM", "1T", "136", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "136", "32", "MKK", "5G", "20M", "OFDM", "1T", "136", "32", + "FCC", "5G", "20M", "OFDM", "1T", "140", "28", "ETSI", "5G", + "20M", "OFDM", "1T", "140", "32", "MKK", "5G", "20M", "OFDM", + "1T", "140", "32", "FCC", "5G", "20M", "OFDM", "1T", "144", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "144", "32", "MKK", + "5G", "20M", "OFDM", "1T", "144", "63", "FCC", "5G", "20M", + "OFDM", "1T", "149", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "149", "63", "MKK", "5G", "20M", "OFDM", "1T", "149", "63", + "FCC", "5G", "20M", "OFDM", "1T", "153", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "153", "63", "MKK", "5G", "20M", "OFDM", + "1T", "153", "63", "FCC", "5G", "20M", "OFDM", "1T", "157", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "157", "63", "MKK", + "5G", "20M", "OFDM", "1T", "157", "63", "FCC", "5G", "20M", + "OFDM", "1T", "161", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "161", "63", "MKK", "5G", "20M", "OFDM", "1T", "161", "63", + "FCC", "5G", "20M", "OFDM", "1T", "165", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "165", "63", "MKK", "5G", "20M", "OFDM", + "1T", "165", "63", "FCC", "5G", "20M", "HT", "1T", "36", + "30", "ETSI", "5G", "20M", "HT", "1T", "36", "32", "MKK", + "5G", "20M", "HT", "1T", "36", "28", "FCC", "5G", "20M", + "HT", "1T", "40", "32", "ETSI", "5G", "20M", "HT", "1T", + "40", "32", "MKK", "5G", "20M", "HT", "1T", "40", "28", + "FCC", "5G", "20M", "HT", "1T", "44", "32", "ETSI", "5G", + "20M", "HT", "1T", "44", "32", "MKK", "5G", "20M", "HT", + "1T", "44", "28", "FCC", "5G", "20M", "HT", "1T", "48", + "32", "ETSI", "5G", "20M", "HT", "1T", "48", "32", "MKK", + "5G", "20M", "HT", "1T", "48", "28", "FCC", "5G", "20M", + "HT", "1T", "52", "32", "ETSI", "5G", "20M", "HT", "1T", + "52", "32", "MKK", "5G", "20M", "HT", "1T", "52", "28", + "FCC", "5G", "20M", "HT", "1T", "56", "32", "ETSI", "5G", + "20M", "HT", "1T", "56", "32", "MKK", "5G", "20M", "HT", + "1T", "56", "28", "FCC", "5G", "20M", "HT", "1T", "60", + "32", "ETSI", "5G", "20M", "HT", "1T", "60", "32", "MKK", + "5G", "20M", "HT", "1T", "60", "28", "FCC", "5G", "20M", + "HT", "1T", "64", "28", "ETSI", "5G", "20M", "HT", "1T", + "64", "32", "MKK", "5G", "20M", "HT", "1T", "64", "28", + "FCC", "5G", "20M", "HT", "1T", "100", "26", "ETSI", "5G", + "20M", "HT", "1T", "100", "32", "MKK", "5G", "20M", "HT", + "1T", "100", "32", "FCC", "5G", "20M", "HT", "1T", "104", + "32", "ETSI", "5G", "20M", "HT", "1T", "104", "32", "MKK", + "5G", "20M", "HT", "1T", "104", "32", "FCC", "5G", "20M", + "HT", "1T", "108", "32", "ETSI", "5G", "20M", "HT", "1T", + "108", "32", "MKK", "5G", "20M", "HT", "1T", "108", "32", + "FCC", "5G", "20M", "HT", "1T", "112", "32", "ETSI", "5G", + "20M", "HT", "1T", "112", "32", "MKK", "5G", "20M", "HT", + "1T", "112", "32", "FCC", "5G", "20M", "HT", "1T", "116", + "32", "ETSI", "5G", "20M", "HT", "1T", "116", "32", "MKK", + "5G", "20M", "HT", "1T", "116", "32", "FCC", "5G", "20M", + "HT", "1T", "120", "32", "ETSI", "5G", "20M", "HT", "1T", + "120", "32", "MKK", "5G", "20M", "HT", "1T", "120", "32", + "FCC", "5G", "20M", "HT", "1T", "124", "32", "ETSI", "5G", + "20M", "HT", "1T", "124", "32", "MKK", "5G", "20M", "HT", + "1T", "124", "32", "FCC", "5G", "20M", "HT", "1T", "128", + "32", "ETSI", "5G", "20M", "HT", "1T", "128", "32", "MKK", + "5G", "20M", "HT", "1T", "128", "32", "FCC", "5G", "20M", + "HT", "1T", "132", "32", "ETSI", "5G", "20M", "HT", "1T", + "132", "32", "MKK", "5G", "20M", "HT", "1T", "132", "32", + "FCC", "5G", "20M", "HT", "1T", "136", "32", "ETSI", "5G", + "20M", "HT", "1T", "136", "32", "MKK", "5G", "20M", "HT", + "1T", "136", "32", "FCC", "5G", "20M", "HT", "1T", "140", + "26", "ETSI", "5G", "20M", "HT", "1T", "140", "32", "MKK", + "5G", "20M", "HT", "1T", "140", "32", "FCC", "5G", "20M", + "HT", "1T", "144", "26", "ETSI", "5G", "20M", "HT", "1T", + "144", "63", "MKK", "5G", "20M", "HT", "1T", "144", "63", + "FCC", "5G", "20M", "HT", "1T", "149", "32", "ETSI", "5G", + "20M", "HT", "1T", "149", "63", "MKK", "5G", "20M", "HT", + "1T", "149", "63", "FCC", "5G", "20M", "HT", "1T", "153", + "32", "ETSI", "5G", "20M", "HT", "1T", "153", "63", "MKK", + "5G", "20M", "HT", "1T", "153", "63", "FCC", "5G", "20M", + "HT", "1T", "157", "32", "ETSI", "5G", "20M", "HT", "1T", + "157", "63", "MKK", "5G", "20M", "HT", "1T", "157", "63", + "FCC", "5G", "20M", "HT", "1T", "161", "32", "ETSI", "5G", + "20M", "HT", "1T", "161", "63", "MKK", "5G", "20M", "HT", + "1T", "161", "63", "FCC", "5G", "20M", "HT", "1T", "165", + "32", "ETSI", "5G", "20M", "HT", "1T", "165", "63", "MKK", + "5G", "20M", "HT", "1T", "165", "63", "FCC", "5G", "20M", + "HT", "2T", "36", "28", "ETSI", "5G", "20M", "HT", "2T", + "36", "20", "MKK", "5G", "20M", "HT", "2T", "36", "22", + "FCC", "5G", "20M", "HT", "2T", "40", "30", "ETSI", "5G", + "20M", "HT", "2T", "40", "20", "MKK", "5G", "20M", "HT", + "2T", "40", "22", "FCC", "5G", "20M", "HT", "2T", "44", + "30", "ETSI", "5G", "20M", "HT", "2T", "44", "20", "MKK", + "5G", "20M", "HT", "2T", "44", "22", "FCC", "5G", "20M", + "HT", "2T", "48", "30", "ETSI", "5G", "20M", "HT", "2T", + "48", "20", "MKK", "5G", "20M", "HT", "2T", "48", "22", + "FCC", "5G", "20M", "HT", "2T", "52", "30", "ETSI", "5G", + "20M", "HT", "2T", "52", "20", "MKK", "5G", "20M", "HT", + "2T", "52", "22", "FCC", "5G", "20M", "HT", "2T", "56", + "30", "ETSI", "5G", "20M", "HT", "2T", "56", "20", "MKK", + "5G", "20M", "HT", "2T", "56", "22", "FCC", "5G", "20M", + "HT", "2T", "60", "30", "ETSI", "5G", "20M", "HT", "2T", + "60", "20", "MKK", "5G", "20M", "HT", "2T", "60", "22", + "FCC", "5G", "20M", "HT", "2T", "64", "28", "ETSI", "5G", + "20M", "HT", "2T", "64", "20", "MKK", "5G", "20M", "HT", + "2T", "64", "22", "FCC", "5G", "20M", "HT", "2T", "100", + "26", "ETSI", "5G", "20M", "HT", "2T", "100", "20", "MKK", + "5G", "20M", "HT", "2T", "100", "30", "FCC", "5G", "20M", + "HT", "2T", "104", "30", "ETSI", "5G", "20M", "HT", "2T", + "104", "20", "MKK", "5G", "20M", "HT", "2T", "104", "30", + "FCC", "5G", "20M", "HT", "2T", "108", "32", "ETSI", "5G", + "20M", "HT", "2T", "108", "20", "MKK", "5G", "20M", "HT", + "2T", "108", "30", "FCC", "5G", "20M", "HT", "2T", "112", + "32", "ETSI", "5G", "20M", "HT", "2T", "112", "20", "MKK", + "5G", "20M", "HT", "2T", "112", "30", "FCC", "5G", "20M", + "HT", "2T", "116", "32", "ETSI", "5G", "20M", "HT", "2T", + "116", "20", "MKK", "5G", "20M", "HT", "2T", "116", "30", + "FCC", "5G", "20M", "HT", "2T", "120", "32", "ETSI", "5G", + "20M", "HT", "2T", "120", "20", "MKK", "5G", "20M", "HT", + "2T", "120", "30", "FCC", "5G", "20M", "HT", "2T", "124", + "32", "ETSI", "5G", "20M", "HT", "2T", "124", "20", "MKK", + "5G", "20M", "HT", "2T", "124", "30", "FCC", "5G", "20M", + "HT", "2T", "128", "32", "ETSI", "5G", "20M", "HT", "2T", + "128", "20", "MKK", "5G", "20M", "HT", "2T", "128", "30", + "FCC", "5G", "20M", "HT", "2T", "132", "32", "ETSI", "5G", + "20M", "HT", "2T", "132", "20", "MKK", "5G", "20M", "HT", + "2T", "132", "30", "FCC", "5G", "20M", "HT", "2T", "136", + "30", "ETSI", "5G", "20M", "HT", "2T", "136", "20", "MKK", + "5G", "20M", "HT", "2T", "136", "30", "FCC", "5G", "20M", + "HT", "2T", "140", "26", "ETSI", "5G", "20M", "HT", "2T", + "140", "20", "MKK", "5G", "20M", "HT", "2T", "140", "30", + "FCC", "5G", "20M", "HT", "2T", "144", "26", "ETSI", "5G", + "20M", "HT", "2T", "144", "63", "MKK", "5G", "20M", "HT", + "2T", "144", "63", "FCC", "5G", "20M", "HT", "2T", "149", + "32", "ETSI", "5G", "20M", "HT", "2T", "149", "63", "MKK", + "5G", "20M", "HT", "2T", "149", "63", "FCC", "5G", "20M", + "HT", "2T", "153", "32", "ETSI", "5G", "20M", "HT", "2T", + "153", "63", "MKK", "5G", "20M", "HT", "2T", "153", "63", + "FCC", "5G", "20M", "HT", "2T", "157", "32", "ETSI", "5G", + "20M", "HT", "2T", "157", "63", "MKK", "5G", "20M", "HT", + "2T", "157", "63", "FCC", "5G", "20M", "HT", "2T", "161", + "32", "ETSI", "5G", "20M", "HT", "2T", "161", "63", "MKK", + "5G", "20M", "HT", "2T", "161", "63", "FCC", "5G", "20M", + "HT", "2T", "165", "32", "ETSI", "5G", "20M", "HT", "2T", + "165", "63", "MKK", "5G", "20M", "HT", "2T", "165", "63", + "FCC", "5G", "40M", "HT", "1T", "38", "22", "ETSI", "5G", + "40M", "HT", "1T", "38", "30", "MKK", "5G", "40M", "HT", + "1T", "38", "30", "FCC", "5G", "40M", "HT", "1T", "46", + "30", "ETSI", "5G", "40M", "HT", "1T", "46", "30", "MKK", + "5G", "40M", "HT", "1T", "46", "30", "FCC", "5G", "40M", + "HT", "1T", "54", "30", "ETSI", "5G", "40M", "HT", "1T", + "54", "30", "MKK", "5G", "40M", "HT", "1T", "54", "30", + "FCC", "5G", "40M", "HT", "1T", "62", "24", "ETSI", "5G", + "40M", "HT", "1T", "62", "30", "MKK", "5G", "40M", "HT", + "1T", "62", "30", "FCC", "5G", "40M", "HT", "1T", "102", + "24", "ETSI", "5G", "40M", "HT", "1T", "102", "30", "MKK", + "5G", "40M", "HT", "1T", "102", "30", "FCC", "5G", "40M", + "HT", "1T", "110", "30", "ETSI", "5G", "40M", "HT", "1T", + "110", "30", "MKK", "5G", "40M", "HT", "1T", "110", "30", + "FCC", "5G", "40M", "HT", "1T", "118", "30", "ETSI", "5G", + "40M", "HT", "1T", "118", "30", "MKK", "5G", "40M", "HT", + "1T", "118", "30", "FCC", "5G", "40M", "HT", "1T", "126", + "30", "ETSI", "5G", "40M", "HT", "1T", "126", "30", "MKK", + "5G", "40M", "HT", "1T", "126", "30", "FCC", "5G", "40M", + "HT", "1T", "134", "30", "ETSI", "5G", "40M", "HT", "1T", + "134", "30", "MKK", "5G", "40M", "HT", "1T", "134", "30", + "FCC", "5G", "40M", "HT", "1T", "142", "30", "ETSI", "5G", + "40M", "HT", "1T", "142", "63", "MKK", "5G", "40M", "HT", + "1T", "142", "63", "FCC", "5G", "40M", "HT", "1T", "151", + "30", "ETSI", "5G", "40M", "HT", "1T", "151", "63", "MKK", + "5G", "40M", "HT", "1T", "151", "63", "FCC", "5G", "40M", + "HT", "1T", "159", "30", "ETSI", "5G", "40M", "HT", "1T", + "159", "63", "MKK", "5G", "40M", "HT", "1T", "159", "63", + "FCC", "5G", "40M", "HT", "2T", "38", "20", "ETSI", "5G", + "40M", "HT", "2T", "38", "20", "MKK", "5G", "40M", "HT", + "2T", "38", "22", "FCC", "5G", "40M", "HT", "2T", "46", + "30", "ETSI", "5G", "40M", "HT", "2T", "46", "20", "MKK", + "5G", "40M", "HT", "2T", "46", "22", "FCC", "5G", "40M", + "HT", "2T", "54", "30", "ETSI", "5G", "40M", "HT", "2T", + "54", "20", "MKK", "5G", "40M", "HT", "2T", "54", "22", + "FCC", "5G", "40M", "HT", "2T", "62", "22", "ETSI", "5G", + "40M", "HT", "2T", "62", "20", "MKK", "5G", "40M", "HT", + "2T", "62", "22", "FCC", "5G", "40M", "HT", "2T", "102", + "22", "ETSI", "5G", "40M", "HT", "2T", "102", "20", "MKK", + "5G", "40M", "HT", "2T", "102", "30", "FCC", "5G", "40M", + "HT", "2T", "110", "30", "ETSI", "5G", "40M", "HT", "2T", + "110", "20", "MKK", "5G", "40M", "HT", "2T", "110", "30", + "FCC", "5G", "40M", "HT", "2T", "118", "30", "ETSI", "5G", + "40M", "HT", "2T", "118", "20", "MKK", "5G", "40M", "HT", + "2T", "118", "30", "FCC", "5G", "40M", "HT", "2T", "126", + "30", "ETSI", "5G", "40M", "HT", "2T", "126", "20", "MKK", + "5G", "40M", "HT", "2T", "126", "30", "FCC", "5G", "40M", + "HT", "2T", "134", "30", "ETSI", "5G", "40M", "HT", "2T", + "134", "20", "MKK", "5G", "40M", "HT", "2T", "134", "30", + "FCC", "5G", "40M", "HT", "2T", "142", "30", "ETSI", "5G", + "40M", "HT", "2T", "142", "63", "MKK", "5G", "40M", "HT", + "2T", "142", "63", "FCC", "5G", "40M", "HT", "2T", "151", + "30", "ETSI", "5G", "40M", "HT", "2T", "151", "63", "MKK", + "5G", "40M", "HT", "2T", "151", "63", "FCC", "5G", "40M", + "HT", "2T", "159", "30", "ETSI", "5G", "40M", "HT", "2T", + "159", "63", "MKK", "5G", "40M", "HT", "2T", "159", "63", + "FCC", "5G", "80M", "VHT", "1T", "42", "20", "ETSI", "5G", + "80M", "VHT", "1T", "42", "30", "MKK", "5G", "80M", "VHT", + "1T", "42", "28", "FCC", "5G", "80M", "VHT", "1T", "58", + "20", "ETSI", "5G", "80M", "VHT", "1T", "58", "30", "MKK", + "5G", "80M", "VHT", "1T", "58", "28", "FCC", "5G", "80M", + "VHT", "1T", "106", "20", "ETSI", "5G", "80M", "VHT", "1T", + "106", "30", "MKK", "5G", "80M", "VHT", "1T", "106", "30", + "FCC", "5G", "80M", "VHT", "1T", "122", "30", "ETSI", "5G", + "80M", "VHT", "1T", "122", "30", "MKK", "5G", "80M", "VHT", + "1T", "122", "30", "FCC", "5G", "80M", "VHT", "1T", "138", + "30", "ETSI", "5G", "80M", "VHT", "1T", "138", "63", "MKK", + "5G", "80M", "VHT", "1T", "138", "63", "FCC", "5G", "80M", + "VHT", "1T", "155", "30", "ETSI", "5G", "80M", "VHT", "1T", + "155", "63", "MKK", "5G", "80M", "VHT", "1T", "155", "63", + "FCC", "5G", "80M", "VHT", "2T", "42", "18", "ETSI", "5G", + "80M", "VHT", "2T", "42", "20", "MKK", "5G", "80M", "VHT", + "2T", "42", "22", "FCC", "5G", "80M", "VHT", "2T", "58", + "18", "ETSI", "5G", "80M", "VHT", "2T", "58", "20", "MKK", + "5G", "80M", "VHT", "2T", "58", "22", "FCC", "5G", "80M", + "VHT", "2T", "106", "20", "ETSI", "5G", "80M", "VHT", "2T", + "106", "20", "MKK", "5G", "80M", "VHT", "2T", "106", "30", + "FCC", "5G", "80M", "VHT", "2T", "122", "30", "ETSI", "5G", + "80M", "VHT", "2T", "122", "20", "MKK", "5G", "80M", "VHT", + "2T", "122", "30", "FCC", "5G", "80M", "VHT", "2T", "138", + "30", "ETSI", "5G", "80M", "VHT", "2T", "138", "63", "MKK", + "5G", "80M", "VHT", "2T", "138", "63", "FCC", "5G", "80M", + "VHT", "2T", "155", "30", "ETSI", "5G", "80M", "VHT", "2T", + "155", "63", "MKK", "5G", "80M", "VHT", "2T", "155", "63"}; + +void odm_read_and_config_mp_8822b_txpwr_lmt(struct phy_dm_struct *dm) +{ + u32 i = 0; + u32 array_len = sizeof(array_mp_8822b_txpwr_lmt) / sizeof(u8 *); + u8 **array = (u8 **)array_mp_8822b_txpwr_lmt; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> %s\n", __func__); + + for (i = 0; i < array_len; i += 7) { + u8 *regulation = array[i]; + u8 *band = array[i + 1]; + u8 *bandwidth = array[i + 2]; + u8 *rate = array[i + 3]; + u8 *rf_path = array[i + 4]; + u8 *chnl = array[i + 5]; + u8 *val = array[i + 6]; + + odm_config_bb_txpwr_lmt_8822b(dm, regulation, band, bandwidth, + rate, rf_path, chnl, val); + } +} + +/****************************************************************************** +* txpwr_lmt_type5.TXT +******************************************************************************/ + +static const char *const array_mp_8822b_txpwr_lmt_type5[] = { + "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "01", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "01", "30", "FCC", "2.4G", "20M", "CCK", "1T", "02", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "02", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "02", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "03", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "03", "28", "MKK", "2.4G", "20M", "CCK", "1T", "03", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "04", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "04", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "04", "30", "FCC", "2.4G", "20M", "CCK", "1T", "05", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "05", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "05", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "06", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "06", "28", "MKK", "2.4G", "20M", "CCK", "1T", "06", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "07", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "07", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "07", "30", "FCC", "2.4G", "20M", "CCK", "1T", "08", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "08", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "08", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "09", "32", "ETSI", "2.4G", "20M", "CCK", "1T", + "09", "28", "MKK", "2.4G", "20M", "CCK", "1T", "09", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "10", "32", "ETSI", "2.4G", + "20M", "CCK", "1T", "10", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "10", "30", "FCC", "2.4G", "20M", "CCK", "1T", "11", + "32", "ETSI", "2.4G", "20M", "CCK", "1T", "11", "28", "MKK", + "2.4G", "20M", "CCK", "1T", "11", "30", "FCC", "2.4G", "20M", + "CCK", "1T", "12", "26", "ETSI", "2.4G", "20M", "CCK", "1T", + "12", "28", "MKK", "2.4G", "20M", "CCK", "1T", "12", "30", + "FCC", "2.4G", "20M", "CCK", "1T", "13", "20", "ETSI", "2.4G", + "20M", "CCK", "1T", "13", "28", "MKK", "2.4G", "20M", "CCK", + "1T", "13", "28", "FCC", "2.4G", "20M", "CCK", "1T", "14", + "63", "ETSI", "2.4G", "20M", "CCK", "1T", "14", "63", "MKK", + "2.4G", "20M", "CCK", "1T", "14", "32", "FCC", "2.4G", "20M", + "OFDM", "1T", "01", "26", "ETSI", "2.4G", "20M", "OFDM", "1T", + "01", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "01", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "02", "30", "ETSI", "2.4G", + "20M", "OFDM", "1T", "02", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "02", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "03", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "03", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "03", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "04", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "04", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "04", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "05", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "05", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "05", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "06", + "34", "ETSI", "2.4G", "20M", "OFDM", "1T", "06", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "06", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "07", "34", "ETSI", "2.4G", "20M", "OFDM", "1T", + "07", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "07", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "08", "34", "ETSI", "2.4G", + "20M", "OFDM", "1T", "08", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "08", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "09", + "32", "ETSI", "2.4G", "20M", "OFDM", "1T", "09", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "09", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "10", "30", "ETSI", "2.4G", "20M", "OFDM", "1T", + "10", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "10", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "11", "28", "ETSI", "2.4G", + "20M", "OFDM", "1T", "11", "30", "MKK", "2.4G", "20M", "OFDM", + "1T", "11", "34", "FCC", "2.4G", "20M", "OFDM", "1T", "12", + "22", "ETSI", "2.4G", "20M", "OFDM", "1T", "12", "30", "MKK", + "2.4G", "20M", "OFDM", "1T", "12", "34", "FCC", "2.4G", "20M", + "OFDM", "1T", "13", "14", "ETSI", "2.4G", "20M", "OFDM", "1T", + "13", "30", "MKK", "2.4G", "20M", "OFDM", "1T", "13", "34", + "FCC", "2.4G", "20M", "OFDM", "1T", "14", "63", "ETSI", "2.4G", + "20M", "OFDM", "1T", "14", "63", "MKK", "2.4G", "20M", "OFDM", + "1T", "14", "63", "FCC", "2.4G", "20M", "HT", "1T", "01", + "26", "ETSI", "2.4G", "20M", "HT", "1T", "01", "30", "MKK", + "2.4G", "20M", "HT", "1T", "01", "34", "FCC", "2.4G", "20M", + "HT", "1T", "02", "30", "ETSI", "2.4G", "20M", "HT", "1T", + "02", "30", "MKK", "2.4G", "20M", "HT", "1T", "02", "34", + "FCC", "2.4G", "20M", "HT", "1T", "03", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "03", "30", "MKK", "2.4G", "20M", "HT", + "1T", "03", "34", "FCC", "2.4G", "20M", "HT", "1T", "04", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "04", "30", "MKK", + "2.4G", "20M", "HT", "1T", "04", "34", "FCC", "2.4G", "20M", + "HT", "1T", "05", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "05", "30", "MKK", "2.4G", "20M", "HT", "1T", "05", "34", + "FCC", "2.4G", "20M", "HT", "1T", "06", "34", "ETSI", "2.4G", + "20M", "HT", "1T", "06", "30", "MKK", "2.4G", "20M", "HT", + "1T", "06", "34", "FCC", "2.4G", "20M", "HT", "1T", "07", + "34", "ETSI", "2.4G", "20M", "HT", "1T", "07", "30", "MKK", + "2.4G", "20M", "HT", "1T", "07", "34", "FCC", "2.4G", "20M", + "HT", "1T", "08", "34", "ETSI", "2.4G", "20M", "HT", "1T", + "08", "30", "MKK", "2.4G", "20M", "HT", "1T", "08", "34", + "FCC", "2.4G", "20M", "HT", "1T", "09", "32", "ETSI", "2.4G", + "20M", "HT", "1T", "09", "30", "MKK", "2.4G", "20M", "HT", + "1T", "09", "34", "FCC", "2.4G", "20M", "HT", "1T", "10", + "30", "ETSI", "2.4G", "20M", "HT", "1T", "10", "30", "MKK", + "2.4G", "20M", "HT", "1T", "10", "34", "FCC", "2.4G", "20M", + "HT", "1T", "11", "26", "ETSI", "2.4G", "20M", "HT", "1T", + "11", "30", "MKK", "2.4G", "20M", "HT", "1T", "11", "34", + "FCC", "2.4G", "20M", "HT", "1T", "12", "20", "ETSI", "2.4G", + "20M", "HT", "1T", "12", "30", "MKK", "2.4G", "20M", "HT", + "1T", "12", "34", "FCC", "2.4G", "20M", "HT", "1T", "13", + "14", "ETSI", "2.4G", "20M", "HT", "1T", "13", "30", "MKK", + "2.4G", "20M", "HT", "1T", "13", "34", "FCC", "2.4G", "20M", + "HT", "1T", "14", "63", "ETSI", "2.4G", "20M", "HT", "1T", + "14", "63", "MKK", "2.4G", "20M", "HT", "1T", "14", "63", + "FCC", "2.4G", "20M", "HT", "2T", "01", "26", "ETSI", "2.4G", + "20M", "HT", "2T", "01", "18", "MKK", "2.4G", "20M", "HT", + "2T", "01", "30", "FCC", "2.4G", "20M", "HT", "2T", "02", + "28", "ETSI", "2.4G", "20M", "HT", "2T", "02", "18", "MKK", + "2.4G", "20M", "HT", "2T", "02", "30", "FCC", "2.4G", "20M", + "HT", "2T", "03", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "03", "18", "MKK", "2.4G", "20M", "HT", "2T", "03", "30", + "FCC", "2.4G", "20M", "HT", "2T", "04", "30", "ETSI", "2.4G", + "20M", "HT", "2T", "04", "18", "MKK", "2.4G", "20M", "HT", + "2T", "04", "30", "FCC", "2.4G", "20M", "HT", "2T", "05", + "32", "ETSI", "2.4G", "20M", "HT", "2T", "05", "18", "MKK", + "2.4G", "20M", "HT", "2T", "05", "30", "FCC", "2.4G", "20M", + "HT", "2T", "06", "32", "ETSI", "2.4G", "20M", "HT", "2T", + "06", "18", "MKK", "2.4G", "20M", "HT", "2T", "06", "30", + "FCC", "2.4G", "20M", "HT", "2T", "07", "32", "ETSI", "2.4G", + "20M", "HT", "2T", "07", "18", "MKK", "2.4G", "20M", "HT", + "2T", "07", "30", "FCC", "2.4G", "20M", "HT", "2T", "08", + "30", "ETSI", "2.4G", "20M", "HT", "2T", "08", "18", "MKK", + "2.4G", "20M", "HT", "2T", "08", "30", "FCC", "2.4G", "20M", + "HT", "2T", "09", "30", "ETSI", "2.4G", "20M", "HT", "2T", + "09", "18", "MKK", "2.4G", "20M", "HT", "2T", "09", "30", + "FCC", "2.4G", "20M", "HT", "2T", "10", "28", "ETSI", "2.4G", + "20M", "HT", "2T", "10", "18", "MKK", "2.4G", "20M", "HT", + "2T", "10", "30", "FCC", "2.4G", "20M", "HT", "2T", "11", + "26", "ETSI", "2.4G", "20M", "HT", "2T", "11", "18", "MKK", + "2.4G", "20M", "HT", "2T", "11", "30", "FCC", "2.4G", "20M", + "HT", "2T", "12", "20", "ETSI", "2.4G", "20M", "HT", "2T", + "12", "18", "MKK", "2.4G", "20M", "HT", "2T", "12", "30", + "FCC", "2.4G", "20M", "HT", "2T", "13", "14", "ETSI", "2.4G", + "20M", "HT", "2T", "13", "18", "MKK", "2.4G", "20M", "HT", + "2T", "13", "30", "FCC", "2.4G", "20M", "HT", "2T", "14", + "63", "ETSI", "2.4G", "20M", "HT", "2T", "14", "63", "MKK", + "2.4G", "20M", "HT", "2T", "14", "63", "FCC", "2.4G", "40M", + "HT", "1T", "01", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "01", "63", "MKK", "2.4G", "40M", "HT", "1T", "01", "63", + "FCC", "2.4G", "40M", "HT", "1T", "02", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "02", "63", "MKK", "2.4G", "40M", "HT", + "1T", "02", "63", "FCC", "2.4G", "40M", "HT", "1T", "03", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "03", "30", "MKK", + "2.4G", "40M", "HT", "1T", "03", "34", "FCC", "2.4G", "40M", + "HT", "1T", "04", "26", "ETSI", "2.4G", "40M", "HT", "1T", + "04", "30", "MKK", "2.4G", "40M", "HT", "1T", "04", "34", + "FCC", "2.4G", "40M", "HT", "1T", "05", "30", "ETSI", "2.4G", + "40M", "HT", "1T", "05", "30", "MKK", "2.4G", "40M", "HT", + "1T", "05", "34", "FCC", "2.4G", "40M", "HT", "1T", "06", + "32", "ETSI", "2.4G", "40M", "HT", "1T", "06", "30", "MKK", + "2.4G", "40M", "HT", "1T", "06", "34", "FCC", "2.4G", "40M", + "HT", "1T", "07", "30", "ETSI", "2.4G", "40M", "HT", "1T", + "07", "30", "MKK", "2.4G", "40M", "HT", "1T", "07", "34", + "FCC", "2.4G", "40M", "HT", "1T", "08", "26", "ETSI", "2.4G", + "40M", "HT", "1T", "08", "30", "MKK", "2.4G", "40M", "HT", + "1T", "08", "34", "FCC", "2.4G", "40M", "HT", "1T", "09", + "26", "ETSI", "2.4G", "40M", "HT", "1T", "09", "30", "MKK", + "2.4G", "40M", "HT", "1T", "09", "34", "FCC", "2.4G", "40M", + "HT", "1T", "10", "20", "ETSI", "2.4G", "40M", "HT", "1T", + "10", "30", "MKK", "2.4G", "40M", "HT", "1T", "10", "34", + "FCC", "2.4G", "40M", "HT", "1T", "11", "14", "ETSI", "2.4G", + "40M", "HT", "1T", "11", "30", "MKK", "2.4G", "40M", "HT", + "1T", "11", "34", "FCC", "2.4G", "40M", "HT", "1T", "12", + "63", "ETSI", "2.4G", "40M", "HT", "1T", "12", "63", "MKK", + "2.4G", "40M", "HT", "1T", "12", "63", "FCC", "2.4G", "40M", + "HT", "1T", "13", "63", "ETSI", "2.4G", "40M", "HT", "1T", + "13", "63", "MKK", "2.4G", "40M", "HT", "1T", "13", "63", + "FCC", "2.4G", "40M", "HT", "1T", "14", "63", "ETSI", "2.4G", + "40M", "HT", "1T", "14", "63", "MKK", "2.4G", "40M", "HT", + "1T", "14", "63", "FCC", "2.4G", "40M", "HT", "2T", "01", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "01", "63", "MKK", + "2.4G", "40M", "HT", "2T", "01", "63", "FCC", "2.4G", "40M", + "HT", "2T", "02", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "02", "63", "MKK", "2.4G", "40M", "HT", "2T", "02", "63", + "FCC", "2.4G", "40M", "HT", "2T", "03", "24", "ETSI", "2.4G", + "40M", "HT", "2T", "03", "18", "MKK", "2.4G", "40M", "HT", + "2T", "03", "30", "FCC", "2.4G", "40M", "HT", "2T", "04", + "24", "ETSI", "2.4G", "40M", "HT", "2T", "04", "18", "MKK", + "2.4G", "40M", "HT", "2T", "04", "30", "FCC", "2.4G", "40M", + "HT", "2T", "05", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "05", "18", "MKK", "2.4G", "40M", "HT", "2T", "05", "30", + "FCC", "2.4G", "40M", "HT", "2T", "06", "28", "ETSI", "2.4G", + "40M", "HT", "2T", "06", "18", "MKK", "2.4G", "40M", "HT", + "2T", "06", "30", "FCC", "2.4G", "40M", "HT", "2T", "07", + "26", "ETSI", "2.4G", "40M", "HT", "2T", "07", "18", "MKK", + "2.4G", "40M", "HT", "2T", "07", "30", "FCC", "2.4G", "40M", + "HT", "2T", "08", "26", "ETSI", "2.4G", "40M", "HT", "2T", + "08", "18", "MKK", "2.4G", "40M", "HT", "2T", "08", "30", + "FCC", "2.4G", "40M", "HT", "2T", "09", "26", "ETSI", "2.4G", + "40M", "HT", "2T", "09", "18", "MKK", "2.4G", "40M", "HT", + "2T", "09", "30", "FCC", "2.4G", "40M", "HT", "2T", "10", + "20", "ETSI", "2.4G", "40M", "HT", "2T", "10", "18", "MKK", + "2.4G", "40M", "HT", "2T", "10", "30", "FCC", "2.4G", "40M", + "HT", "2T", "11", "14", "ETSI", "2.4G", "40M", "HT", "2T", + "11", "18", "MKK", "2.4G", "40M", "HT", "2T", "11", "30", + "FCC", "2.4G", "40M", "HT", "2T", "12", "63", "ETSI", "2.4G", + "40M", "HT", "2T", "12", "63", "MKK", "2.4G", "40M", "HT", + "2T", "12", "63", "FCC", "2.4G", "40M", "HT", "2T", "13", + "63", "ETSI", "2.4G", "40M", "HT", "2T", "13", "63", "MKK", + "2.4G", "40M", "HT", "2T", "13", "63", "FCC", "2.4G", "40M", + "HT", "2T", "14", "63", "ETSI", "2.4G", "40M", "HT", "2T", + "14", "63", "MKK", "2.4G", "40M", "HT", "2T", "14", "63", + "FCC", "5G", "20M", "OFDM", "1T", "36", "30", "ETSI", "5G", + "20M", "OFDM", "1T", "36", "32", "MKK", "5G", "20M", "OFDM", + "1T", "36", "30", "FCC", "5G", "20M", "OFDM", "1T", "40", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "40", "32", "MKK", + "5G", "20M", "OFDM", "1T", "40", "30", "FCC", "5G", "20M", + "OFDM", "1T", "44", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "44", "32", "MKK", "5G", "20M", "OFDM", "1T", "44", "30", + "FCC", "5G", "20M", "OFDM", "1T", "48", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "48", "32", "MKK", "5G", "20M", "OFDM", + "1T", "48", "30", "FCC", "5G", "20M", "OFDM", "1T", "52", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "52", "32", "MKK", + "5G", "20M", "OFDM", "1T", "52", "28", "FCC", "5G", "20M", + "OFDM", "1T", "56", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "56", "32", "MKK", "5G", "20M", "OFDM", "1T", "56", "28", + "FCC", "5G", "20M", "OFDM", "1T", "60", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "60", "32", "MKK", "5G", "20M", "OFDM", + "1T", "60", "28", "FCC", "5G", "20M", "OFDM", "1T", "64", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "64", "32", "MKK", + "5G", "20M", "OFDM", "1T", "64", "28", "FCC", "5G", "20M", + "OFDM", "1T", "100", "26", "ETSI", "5G", "20M", "OFDM", "1T", + "100", "32", "MKK", "5G", "20M", "OFDM", "1T", "100", "32", + "FCC", "5G", "20M", "OFDM", "1T", "104", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "104", "32", "MKK", "5G", "20M", "OFDM", + "1T", "104", "32", "FCC", "5G", "20M", "OFDM", "1T", "108", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "108", "32", "MKK", + "5G", "20M", "OFDM", "1T", "108", "32", "FCC", "5G", "20M", + "OFDM", "1T", "112", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "112", "32", "MKK", "5G", "20M", "OFDM", "1T", "112", "32", + "FCC", "5G", "20M", "OFDM", "1T", "116", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "116", "32", "MKK", "5G", "20M", "OFDM", + "1T", "116", "32", "FCC", "5G", "20M", "OFDM", "1T", "120", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "120", "32", "MKK", + "5G", "20M", "OFDM", "1T", "120", "32", "FCC", "5G", "20M", + "OFDM", "1T", "124", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "124", "32", "MKK", "5G", "20M", "OFDM", "1T", "124", "32", + "FCC", "5G", "20M", "OFDM", "1T", "128", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "128", "32", "MKK", "5G", "20M", "OFDM", + "1T", "128", "32", "FCC", "5G", "20M", "OFDM", "1T", "132", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "132", "32", "MKK", + "5G", "20M", "OFDM", "1T", "132", "32", "FCC", "5G", "20M", + "OFDM", "1T", "136", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "136", "32", "MKK", "5G", "20M", "OFDM", "1T", "136", "32", + "FCC", "5G", "20M", "OFDM", "1T", "140", "28", "ETSI", "5G", + "20M", "OFDM", "1T", "140", "32", "MKK", "5G", "20M", "OFDM", + "1T", "140", "32", "FCC", "5G", "20M", "OFDM", "1T", "144", + "28", "ETSI", "5G", "20M", "OFDM", "1T", "144", "32", "MKK", + "5G", "20M", "OFDM", "1T", "144", "63", "FCC", "5G", "20M", + "OFDM", "1T", "149", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "149", "63", "MKK", "5G", "20M", "OFDM", "1T", "149", "63", + "FCC", "5G", "20M", "OFDM", "1T", "153", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "153", "63", "MKK", "5G", "20M", "OFDM", + "1T", "153", "63", "FCC", "5G", "20M", "OFDM", "1T", "157", + "32", "ETSI", "5G", "20M", "OFDM", "1T", "157", "63", "MKK", + "5G", "20M", "OFDM", "1T", "157", "63", "FCC", "5G", "20M", + "OFDM", "1T", "161", "32", "ETSI", "5G", "20M", "OFDM", "1T", + "161", "63", "MKK", "5G", "20M", "OFDM", "1T", "161", "63", + "FCC", "5G", "20M", "OFDM", "1T", "165", "32", "ETSI", "5G", + "20M", "OFDM", "1T", "165", "63", "MKK", "5G", "20M", "OFDM", + "1T", "165", "63", "FCC", "5G", "20M", "HT", "1T", "36", + "30", "ETSI", "5G", "20M", "HT", "1T", "36", "32", "MKK", + "5G", "20M", "HT", "1T", "36", "28", "FCC", "5G", "20M", + "HT", "1T", "40", "32", "ETSI", "5G", "20M", "HT", "1T", + "40", "32", "MKK", "5G", "20M", "HT", "1T", "40", "28", + "FCC", "5G", "20M", "HT", "1T", "44", "32", "ETSI", "5G", + "20M", "HT", "1T", "44", "32", "MKK", "5G", "20M", "HT", + "1T", "44", "28", "FCC", "5G", "20M", "HT", "1T", "48", + "32", "ETSI", "5G", "20M", "HT", "1T", "48", "32", "MKK", + "5G", "20M", "HT", "1T", "48", "28", "FCC", "5G", "20M", + "HT", "1T", "52", "32", "ETSI", "5G", "20M", "HT", "1T", + "52", "32", "MKK", "5G", "20M", "HT", "1T", "52", "28", + "FCC", "5G", "20M", "HT", "1T", "56", "32", "ETSI", "5G", + "20M", "HT", "1T", "56", "32", "MKK", "5G", "20M", "HT", + "1T", "56", "28", "FCC", "5G", "20M", "HT", "1T", "60", + "32", "ETSI", "5G", "20M", "HT", "1T", "60", "32", "MKK", + "5G", "20M", "HT", "1T", "60", "28", "FCC", "5G", "20M", + "HT", "1T", "64", "28", "ETSI", "5G", "20M", "HT", "1T", + "64", "32", "MKK", "5G", "20M", "HT", "1T", "64", "28", + "FCC", "5G", "20M", "HT", "1T", "100", "26", "ETSI", "5G", + "20M", "HT", "1T", "100", "32", "MKK", "5G", "20M", "HT", + "1T", "100", "32", "FCC", "5G", "20M", "HT", "1T", "104", + "32", "ETSI", "5G", "20M", "HT", "1T", "104", "32", "MKK", + "5G", "20M", "HT", "1T", "104", "32", "FCC", "5G", "20M", + "HT", "1T", "108", "32", "ETSI", "5G", "20M", "HT", "1T", + "108", "32", "MKK", "5G", "20M", "HT", "1T", "108", "32", + "FCC", "5G", "20M", "HT", "1T", "112", "32", "ETSI", "5G", + "20M", "HT", "1T", "112", "32", "MKK", "5G", "20M", "HT", + "1T", "112", "32", "FCC", "5G", "20M", "HT", "1T", "116", + "32", "ETSI", "5G", "20M", "HT", "1T", "116", "32", "MKK", + "5G", "20M", "HT", "1T", "116", "32", "FCC", "5G", "20M", + "HT", "1T", "120", "32", "ETSI", "5G", "20M", "HT", "1T", + "120", "32", "MKK", "5G", "20M", "HT", "1T", "120", "32", + "FCC", "5G", "20M", "HT", "1T", "124", "32", "ETSI", "5G", + "20M", "HT", "1T", "124", "32", "MKK", "5G", "20M", "HT", + "1T", "124", "32", "FCC", "5G", "20M", "HT", "1T", "128", + "32", "ETSI", "5G", "20M", "HT", "1T", "128", "32", "MKK", + "5G", "20M", "HT", "1T", "128", "32", "FCC", "5G", "20M", + "HT", "1T", "132", "32", "ETSI", "5G", "20M", "HT", "1T", + "132", "32", "MKK", "5G", "20M", "HT", "1T", "132", "32", + "FCC", "5G", "20M", "HT", "1T", "136", "32", "ETSI", "5G", + "20M", "HT", "1T", "136", "32", "MKK", "5G", "20M", "HT", + "1T", "136", "32", "FCC", "5G", "20M", "HT", "1T", "140", + "26", "ETSI", "5G", "20M", "HT", "1T", "140", "32", "MKK", + "5G", "20M", "HT", "1T", "140", "32", "FCC", "5G", "20M", + "HT", "1T", "144", "26", "ETSI", "5G", "20M", "HT", "1T", + "144", "63", "MKK", "5G", "20M", "HT", "1T", "144", "63", + "FCC", "5G", "20M", "HT", "1T", "149", "32", "ETSI", "5G", + "20M", "HT", "1T", "149", "63", "MKK", "5G", "20M", "HT", + "1T", "149", "63", "FCC", "5G", "20M", "HT", "1T", "153", + "32", "ETSI", "5G", "20M", "HT", "1T", "153", "63", "MKK", + "5G", "20M", "HT", "1T", "153", "63", "FCC", "5G", "20M", + "HT", "1T", "157", "32", "ETSI", "5G", "20M", "HT", "1T", + "157", "63", "MKK", "5G", "20M", "HT", "1T", "157", "63", + "FCC", "5G", "20M", "HT", "1T", "161", "32", "ETSI", "5G", + "20M", "HT", "1T", "161", "63", "MKK", "5G", "20M", "HT", + "1T", "161", "63", "FCC", "5G", "20M", "HT", "1T", "165", + "32", "ETSI", "5G", "20M", "HT", "1T", "165", "63", "MKK", + "5G", "20M", "HT", "1T", "165", "63", "FCC", "5G", "20M", + "HT", "2T", "36", "28", "ETSI", "5G", "20M", "HT", "2T", + "36", "20", "MKK", "5G", "20M", "HT", "2T", "36", "22", + "FCC", "5G", "20M", "HT", "2T", "40", "30", "ETSI", "5G", + "20M", "HT", "2T", "40", "20", "MKK", "5G", "20M", "HT", + "2T", "40", "22", "FCC", "5G", "20M", "HT", "2T", "44", + "30", "ETSI", "5G", "20M", "HT", "2T", "44", "20", "MKK", + "5G", "20M", "HT", "2T", "44", "22", "FCC", "5G", "20M", + "HT", "2T", "48", "30", "ETSI", "5G", "20M", "HT", "2T", + "48", "20", "MKK", "5G", "20M", "HT", "2T", "48", "22", + "FCC", "5G", "20M", "HT", "2T", "52", "30", "ETSI", "5G", + "20M", "HT", "2T", "52", "20", "MKK", "5G", "20M", "HT", + "2T", "52", "22", "FCC", "5G", "20M", "HT", "2T", "56", + "30", "ETSI", "5G", "20M", "HT", "2T", "56", "20", "MKK", + "5G", "20M", "HT", "2T", "56", "22", "FCC", "5G", "20M", + "HT", "2T", "60", "30", "ETSI", "5G", "20M", "HT", "2T", + "60", "20", "MKK", "5G", "20M", "HT", "2T", "60", "22", + "FCC", "5G", "20M", "HT", "2T", "64", "28", "ETSI", "5G", + "20M", "HT", "2T", "64", "20", "MKK", "5G", "20M", "HT", + "2T", "64", "22", "FCC", "5G", "20M", "HT", "2T", "100", + "26", "ETSI", "5G", "20M", "HT", "2T", "100", "20", "MKK", + "5G", "20M", "HT", "2T", "100", "30", "FCC", "5G", "20M", + "HT", "2T", "104", "30", "ETSI", "5G", "20M", "HT", "2T", + "104", "20", "MKK", "5G", "20M", "HT", "2T", "104", "30", + "FCC", "5G", "20M", "HT", "2T", "108", "32", "ETSI", "5G", + "20M", "HT", "2T", "108", "20", "MKK", "5G", "20M", "HT", + "2T", "108", "30", "FCC", "5G", "20M", "HT", "2T", "112", + "32", "ETSI", "5G", "20M", "HT", "2T", "112", "20", "MKK", + "5G", "20M", "HT", "2T", "112", "30", "FCC", "5G", "20M", + "HT", "2T", "116", "32", "ETSI", "5G", "20M", "HT", "2T", + "116", "20", "MKK", "5G", "20M", "HT", "2T", "116", "30", + "FCC", "5G", "20M", "HT", "2T", "120", "32", "ETSI", "5G", + "20M", "HT", "2T", "120", "20", "MKK", "5G", "20M", "HT", + "2T", "120", "30", "FCC", "5G", "20M", "HT", "2T", "124", + "32", "ETSI", "5G", "20M", "HT", "2T", "124", "20", "MKK", + "5G", "20M", "HT", "2T", "124", "30", "FCC", "5G", "20M", + "HT", "2T", "128", "32", "ETSI", "5G", "20M", "HT", "2T", + "128", "20", "MKK", "5G", "20M", "HT", "2T", "128", "30", + "FCC", "5G", "20M", "HT", "2T", "132", "32", "ETSI", "5G", + "20M", "HT", "2T", "132", "20", "MKK", "5G", "20M", "HT", + "2T", "132", "30", "FCC", "5G", "20M", "HT", "2T", "136", + "30", "ETSI", "5G", "20M", "HT", "2T", "136", "20", "MKK", + "5G", "20M", "HT", "2T", "136", "30", "FCC", "5G", "20M", + "HT", "2T", "140", "26", "ETSI", "5G", "20M", "HT", "2T", + "140", "20", "MKK", "5G", "20M", "HT", "2T", "140", "30", + "FCC", "5G", "20M", "HT", "2T", "144", "26", "ETSI", "5G", + "20M", "HT", "2T", "144", "63", "MKK", "5G", "20M", "HT", + "2T", "144", "63", "FCC", "5G", "20M", "HT", "2T", "149", + "32", "ETSI", "5G", "20M", "HT", "2T", "149", "63", "MKK", + "5G", "20M", "HT", "2T", "149", "63", "FCC", "5G", "20M", + "HT", "2T", "153", "32", "ETSI", "5G", "20M", "HT", "2T", + "153", "63", "MKK", "5G", "20M", "HT", "2T", "153", "63", + "FCC", "5G", "20M", "HT", "2T", "157", "32", "ETSI", "5G", + "20M", "HT", "2T", "157", "63", "MKK", "5G", "20M", "HT", + "2T", "157", "63", "FCC", "5G", "20M", "HT", "2T", "161", + "32", "ETSI", "5G", "20M", "HT", "2T", "161", "63", "MKK", + "5G", "20M", "HT", "2T", "161", "63", "FCC", "5G", "20M", + "HT", "2T", "165", "32", "ETSI", "5G", "20M", "HT", "2T", + "165", "63", "MKK", "5G", "20M", "HT", "2T", "165", "63", + "FCC", "5G", "40M", "HT", "1T", "38", "22", "ETSI", "5G", + "40M", "HT", "1T", "38", "30", "MKK", "5G", "40M", "HT", + "1T", "38", "30", "FCC", "5G", "40M", "HT", "1T", "46", + "30", "ETSI", "5G", "40M", "HT", "1T", "46", "30", "MKK", + "5G", "40M", "HT", "1T", "46", "30", "FCC", "5G", "40M", + "HT", "1T", "54", "30", "ETSI", "5G", "40M", "HT", "1T", + "54", "30", "MKK", "5G", "40M", "HT", "1T", "54", "30", + "FCC", "5G", "40M", "HT", "1T", "62", "24", "ETSI", "5G", + "40M", "HT", "1T", "62", "30", "MKK", "5G", "40M", "HT", + "1T", "62", "30", "FCC", "5G", "40M", "HT", "1T", "102", + "24", "ETSI", "5G", "40M", "HT", "1T", "102", "30", "MKK", + "5G", "40M", "HT", "1T", "102", "30", "FCC", "5G", "40M", + "HT", "1T", "110", "30", "ETSI", "5G", "40M", "HT", "1T", + "110", "30", "MKK", "5G", "40M", "HT", "1T", "110", "30", + "FCC", "5G", "40M", "HT", "1T", "118", "30", "ETSI", "5G", + "40M", "HT", "1T", "118", "30", "MKK", "5G", "40M", "HT", + "1T", "118", "30", "FCC", "5G", "40M", "HT", "1T", "126", + "30", "ETSI", "5G", "40M", "HT", "1T", "126", "30", "MKK", + "5G", "40M", "HT", "1T", "126", "30", "FCC", "5G", "40M", + "HT", "1T", "134", "30", "ETSI", "5G", "40M", "HT", "1T", + "134", "30", "MKK", "5G", "40M", "HT", "1T", "134", "30", + "FCC", "5G", "40M", "HT", "1T", "142", "30", "ETSI", "5G", + "40M", "HT", "1T", "142", "63", "MKK", "5G", "40M", "HT", + "1T", "142", "63", "FCC", "5G", "40M", "HT", "1T", "151", + "30", "ETSI", "5G", "40M", "HT", "1T", "151", "63", "MKK", + "5G", "40M", "HT", "1T", "151", "63", "FCC", "5G", "40M", + "HT", "1T", "159", "30", "ETSI", "5G", "40M", "HT", "1T", + "159", "63", "MKK", "5G", "40M", "HT", "1T", "159", "63", + "FCC", "5G", "40M", "HT", "2T", "38", "20", "ETSI", "5G", + "40M", "HT", "2T", "38", "20", "MKK", "5G", "40M", "HT", + "2T", "38", "22", "FCC", "5G", "40M", "HT", "2T", "46", + "30", "ETSI", "5G", "40M", "HT", "2T", "46", "20", "MKK", + "5G", "40M", "HT", "2T", "46", "22", "FCC", "5G", "40M", + "HT", "2T", "54", "30", "ETSI", "5G", "40M", "HT", "2T", + "54", "20", "MKK", "5G", "40M", "HT", "2T", "54", "22", + "FCC", "5G", "40M", "HT", "2T", "62", "22", "ETSI", "5G", + "40M", "HT", "2T", "62", "20", "MKK", "5G", "40M", "HT", + "2T", "62", "22", "FCC", "5G", "40M", "HT", "2T", "102", + "22", "ETSI", "5G", "40M", "HT", "2T", "102", "20", "MKK", + "5G", "40M", "HT", "2T", "102", "30", "FCC", "5G", "40M", + "HT", "2T", "110", "30", "ETSI", "5G", "40M", "HT", "2T", + "110", "20", "MKK", "5G", "40M", "HT", "2T", "110", "30", + "FCC", "5G", "40M", "HT", "2T", "118", "30", "ETSI", "5G", + "40M", "HT", "2T", "118", "20", "MKK", "5G", "40M", "HT", + "2T", "118", "30", "FCC", "5G", "40M", "HT", "2T", "126", + "30", "ETSI", "5G", "40M", "HT", "2T", "126", "20", "MKK", + "5G", "40M", "HT", "2T", "126", "30", "FCC", "5G", "40M", + "HT", "2T", "134", "30", "ETSI", "5G", "40M", "HT", "2T", + "134", "20", "MKK", "5G", "40M", "HT", "2T", "134", "30", + "FCC", "5G", "40M", "HT", "2T", "142", "30", "ETSI", "5G", + "40M", "HT", "2T", "142", "63", "MKK", "5G", "40M", "HT", + "2T", "142", "63", "FCC", "5G", "40M", "HT", "2T", "151", + "30", "ETSI", "5G", "40M", "HT", "2T", "151", "63", "MKK", + "5G", "40M", "HT", "2T", "151", "63", "FCC", "5G", "40M", + "HT", "2T", "159", "30", "ETSI", "5G", "40M", "HT", "2T", + "159", "63", "MKK", "5G", "40M", "HT", "2T", "159", "63", + "FCC", "5G", "80M", "VHT", "1T", "42", "20", "ETSI", "5G", + "80M", "VHT", "1T", "42", "30", "MKK", "5G", "80M", "VHT", + "1T", "42", "28", "FCC", "5G", "80M", "VHT", "1T", "58", + "20", "ETSI", "5G", "80M", "VHT", "1T", "58", "30", "MKK", + "5G", "80M", "VHT", "1T", "58", "28", "FCC", "5G", "80M", + "VHT", "1T", "106", "20", "ETSI", "5G", "80M", "VHT", "1T", + "106", "30", "MKK", "5G", "80M", "VHT", "1T", "106", "30", + "FCC", "5G", "80M", "VHT", "1T", "122", "30", "ETSI", "5G", + "80M", "VHT", "1T", "122", "30", "MKK", "5G", "80M", "VHT", + "1T", "122", "30", "FCC", "5G", "80M", "VHT", "1T", "138", + "30", "ETSI", "5G", "80M", "VHT", "1T", "138", "63", "MKK", + "5G", "80M", "VHT", "1T", "138", "63", "FCC", "5G", "80M", + "VHT", "1T", "155", "30", "ETSI", "5G", "80M", "VHT", "1T", + "155", "63", "MKK", "5G", "80M", "VHT", "1T", "155", "63", + "FCC", "5G", "80M", "VHT", "2T", "42", "18", "ETSI", "5G", + "80M", "VHT", "2T", "42", "20", "MKK", "5G", "80M", "VHT", + "2T", "42", "22", "FCC", "5G", "80M", "VHT", "2T", "58", + "18", "ETSI", "5G", "80M", "VHT", "2T", "58", "20", "MKK", + "5G", "80M", "VHT", "2T", "58", "22", "FCC", "5G", "80M", + "VHT", "2T", "106", "20", "ETSI", "5G", "80M", "VHT", "2T", + "106", "20", "MKK", "5G", "80M", "VHT", "2T", "106", "30", + "FCC", "5G", "80M", "VHT", "2T", "122", "30", "ETSI", "5G", + "80M", "VHT", "2T", "122", "20", "MKK", "5G", "80M", "VHT", + "2T", "122", "30", "FCC", "5G", "80M", "VHT", "2T", "138", + "30", "ETSI", "5G", "80M", "VHT", "2T", "138", "63", "MKK", + "5G", "80M", "VHT", "2T", "138", "63", "FCC", "5G", "80M", + "VHT", "2T", "155", "30", "ETSI", "5G", "80M", "VHT", "2T", + "155", "63", "MKK", "5G", "80M", "VHT", "2T", "155", "63"}; + +void odm_read_and_config_mp_8822b_txpwr_lmt_type5(struct phy_dm_struct *dm) +{ + u32 i = 0; + u32 array_len = sizeof(array_mp_8822b_txpwr_lmt_type5) / sizeof(u8 *); + u8 **array = (u8 **)array_mp_8822b_txpwr_lmt_type5; + + ODM_RT_TRACE(dm, ODM_COMP_INIT, + "===> odm_read_and_config_mp_8822b_txpwr_lmt_type5\n"); + + for (i = 0; i < array_len; i += 7) { + u8 *regulation = array[i]; + u8 *band = array[i + 1]; + u8 *bandwidth = array[i + 2]; + u8 *rate = array[i + 3]; + u8 *rf_path = array[i + 4]; + u8 *chnl = array[i + 5]; + u8 *val = array[i + 6]; + + odm_config_bb_txpwr_lmt_8822b(dm, regulation, band, bandwidth, + rate, rf_path, chnl, val); + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h new file mode 100644 index 000000000000..1340fa9f369b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halhwimg8822b_rf.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +/*Image2HeaderVersion: 3.2*/ +#ifndef __INC_MP_RF_HW_IMG_8822B_H +#define __INC_MP_RF_HW_IMG_8822B_H + +/****************************************************************************** + * radioa.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_radioa(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_radioa(void); + +/****************************************************************************** + * radiob.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_radiob(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_radiob(void); + +/****************************************************************************** + * txpowertrack.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack(void); + +/****************************************************************************** + * txpowertrack_type0.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type0(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type0(void); + +/****************************************************************************** + * txpowertrack_type1.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type1(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type1(void); + +/****************************************************************************** + * txpowertrack_type2.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type2(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type2(void); + +/****************************************************************************** + * txpowertrack_type3_type5.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type3_type5( + struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type3_type5(void); + +/****************************************************************************** + * txpowertrack_type4.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type4(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type4(void); + +/****************************************************************************** + * txpowertrack_type6.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type6(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type6(void); + +/****************************************************************************** + * txpowertrack_type7.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type7(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type7(void); + +/****************************************************************************** + * txpowertrack_type8.TXT + *****************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type8(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type8(void); + +/****************************************************************************** + * txpowertrack_type9.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpowertrack_type9(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpowertrack_type9(void); + +/****************************************************************************** + * txpwr_lmt.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpwr_lmt(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpwr_lmt(void); + +/****************************************************************************** + * txpwr_lmt_type5.TXT + ******************************************************************************/ + +void odm_read_and_config_mp_8822b_txpwr_lmt_type5(struct phy_dm_struct *dm); +u32 odm_get_version_mp_8822b_txpwr_lmt_type5(void); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c new file mode 100644 index 000000000000..ae3e2278fefd --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.c @@ -0,0 +1,351 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static bool +get_mix_mode_tx_agc_bb_swing_offset_8822b(void *dm_void, + enum pwrtrack_method method, + u8 rf_path, u8 tx_power_index_offest) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + u8 bb_swing_upper_bound = cali_info->default_ofdm_index + 10; + u8 bb_swing_lower_bound = 0; + + s8 tx_agc_index = 0; + u8 tx_bb_swing_index = cali_info->default_ofdm_index; + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d, tx_power_index_offest=%d\n", + rf_path, cali_info->absolute_ofdm_swing_idx[rf_path], + tx_power_index_offest); + + if (tx_power_index_offest > 0XF) + tx_power_index_offest = 0XF; + + if (cali_info->absolute_ofdm_swing_idx[rf_path] >= 0 && + cali_info->absolute_ofdm_swing_idx[rf_path] <= + tx_power_index_offest) { + tx_agc_index = cali_info->absolute_ofdm_swing_idx[rf_path]; + tx_bb_swing_index = cali_info->default_ofdm_index; + } else if (cali_info->absolute_ofdm_swing_idx[rf_path] > + tx_power_index_offest) { + tx_agc_index = tx_power_index_offest; + cali_info->remnant_ofdm_swing_idx[rf_path] = + cali_info->absolute_ofdm_swing_idx[rf_path] - + tx_power_index_offest; + tx_bb_swing_index = cali_info->default_ofdm_index + + cali_info->remnant_ofdm_swing_idx[rf_path]; + + if (tx_bb_swing_index > bb_swing_upper_bound) + tx_bb_swing_index = bb_swing_upper_bound; + } else { + tx_agc_index = 0; + + if (cali_info->default_ofdm_index > + (cali_info->absolute_ofdm_swing_idx[rf_path] * (-1))) + tx_bb_swing_index = + cali_info->default_ofdm_index + + cali_info->absolute_ofdm_swing_idx[rf_path]; + else + tx_bb_swing_index = bb_swing_lower_bound; + + if (tx_bb_swing_index < bb_swing_lower_bound) + tx_bb_swing_index = bb_swing_lower_bound; + } + + cali_info->absolute_ofdm_swing_idx[rf_path] = tx_agc_index; + cali_info->bb_swing_idx_ofdm[rf_path] = tx_bb_swing_index; + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "MixMode Offset Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d cali_info->bb_swing_idx_ofdm[rf_path]=%d tx_power_index_offest=%d\n", + rf_path, cali_info->absolute_ofdm_swing_idx[rf_path], + cali_info->bb_swing_idx_ofdm[rf_path], tx_power_index_offest); + + return true; +} + +void odm_tx_pwr_track_set_pwr8822b(void *dm_void, enum pwrtrack_method method, + u8 rf_path, u8 channel_mapped_index) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + u8 tx_power_index_offest = 0; + u8 tx_power_index = 0; + + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 channel = rtlphy->current_channel; + u8 band_width = rtlphy->current_chan_bw; + u8 tx_rate = 0xFF; + + if (!dm->mp_mode) { + u16 rate = *dm->forced_data_rate; + + if (!rate) /*auto rate*/ + tx_rate = dm->tx_rate; + else /*force rate*/ + tx_rate = (u8)rate; + } + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "Call:%s tx_rate=0x%X\n", + __func__, tx_rate); + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "pRF->default_ofdm_index=%d pRF->default_cck_index=%d\n", + cali_info->default_ofdm_index, + cali_info->default_cck_index); + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "pRF->absolute_ofdm_swing_idx=%d pRF->remnant_ofdm_swing_idx=%d pRF->absolute_cck_swing_idx=%d pRF->remnant_cck_swing_idx=%d rf_path=%d\n", + cali_info->absolute_ofdm_swing_idx[rf_path], + cali_info->remnant_ofdm_swing_idx[rf_path], + cali_info->absolute_cck_swing_idx[rf_path], + cali_info->remnant_cck_swing_idx, rf_path); + + if (dm->number_linked_client != 0) + tx_power_index = odm_get_tx_power_index( + dm, (enum odm_rf_radio_path)rf_path, tx_rate, + band_width, channel); + + if (tx_power_index >= 63) + tx_power_index = 63; + + tx_power_index_offest = 63 - tx_power_index; + + ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, + "tx_power_index=%d tx_power_index_offest=%d rf_path=%d\n", + tx_power_index, tx_power_index_offest, rf_path); + + if (method == + BBSWING) { /*use for mp driver clean power tracking status*/ + switch (rf_path) { + case ODM_RF_PATH_A: + odm_set_bb_reg( + dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + break; + case ODM_RF_PATH_B: + odm_set_bb_reg( + dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + break; + + default: + break; + } + } else if (method == MIX_MODE) { + switch (rf_path) { + case ODM_RF_PATH_A: + get_mix_mode_tx_agc_bb_swing_offset_8822b( + dm, method, rf_path, tx_power_index_offest); + odm_set_bb_reg( + dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "TXAGC(0xC94)=0x%x BBSwing(0xc1c)=0x%x BBSwingIndex=%d rf_path=%d\n", + odm_get_bb_reg(dm, 0xC94, + (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25))), + odm_get_bb_reg(dm, 0xc1c, 0xFFE00000), + cali_info->bb_swing_idx_ofdm[rf_path], rf_path); + break; + + case ODM_RF_PATH_B: + get_mix_mode_tx_agc_bb_swing_offset_8822b( + dm, method, rf_path, tx_power_index_offest); + odm_set_bb_reg( + dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25)), + cali_info->absolute_ofdm_swing_idx[rf_path]); + odm_set_bb_reg( + dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000, + tx_scaling_table_jaguar + [cali_info + ->bb_swing_idx_ofdm[rf_path]]); + + ODM_RT_TRACE( + dm, ODM_COMP_TX_PWR_TRACK, + "TXAGC(0xE94)=0x%x BBSwing(0xe1c)=0x%x BBSwingIndex=%d rf_path=%d\n", + odm_get_bb_reg(dm, 0xE94, + (BIT(29) | BIT(28) | BIT(27) | + BIT(26) | BIT(25))), + odm_get_bb_reg(dm, 0xe1c, 0xFFE00000), + cali_info->bb_swing_idx_ofdm[rf_path], rf_path); + break; + + default: + break; + } + } +} + +void get_delta_swing_table_8822b(void *dm_void, u8 **temperature_up_a, + u8 **temperature_down_a, u8 **temperature_up_b, + u8 **temperature_down_b) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info; + + struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 channel = rtlphy->current_channel; + + *temperature_up_a = cali_info->delta_swing_table_idx_2ga_p; + *temperature_down_a = cali_info->delta_swing_table_idx_2ga_n; + *temperature_up_b = cali_info->delta_swing_table_idx_2gb_p; + *temperature_down_b = cali_info->delta_swing_table_idx_2gb_n; + + if (channel >= 36 && channel <= 64) { + *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[0]; + *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[0]; + *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[0]; + *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[0]; + } else if (channel >= 100 && channel <= 144) { + *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[1]; + *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[1]; + *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[1]; + *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[1]; + } else if (channel >= 149 && channel <= 177) { + *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[2]; + *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[2]; + *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[2]; + *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[2]; + } +} + +static void _phy_lc_calibrate_8822b(struct phy_dm_struct *dm) +{ + u32 lc_cal = 0, cnt = 0; + + /*backup RF0x18*/ + lc_cal = odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK); + + /*Start LCK*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, + lc_cal | 0x08000); + + ODM_delay_ms(100); + + for (cnt = 0; cnt < 100; cnt++) { + if (odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, 0x8000) != 0x1) + break; + ODM_delay_ms(10); + } + + /*Recover channel number*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, lc_cal); +} + +void phy_lc_calibrate_8822b(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + bool is_start_cont_tx = false, is_single_tone = false, + is_carrier_suppression = false; + u64 start_time; + u64 progressing_time; + + if (is_start_cont_tx || is_single_tone || is_carrier_suppression) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[LCK]continues TX ing !!! LCK return\n"); + return; + } + + start_time = odm_get_current_time(dm); + _phy_lc_calibrate_8822b(dm); + progressing_time = odm_get_progressing_time(dm, start_time); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[LCK]LCK progressing_time = %lld\n", progressing_time); +} + +void configure_txpower_track_8822b(struct txpwrtrack_cfg *config) +{ + config->swing_table_size_cck = TXSCALE_TABLE_SIZE; + config->swing_table_size_ofdm = TXSCALE_TABLE_SIZE; + config->threshold_iqk = IQK_THRESHOLD; + config->threshold_dpk = DPK_THRESHOLD; + config->average_thermal_num = AVG_THERMAL_NUM_8822B; + config->rf_path_count = MAX_PATH_NUM_8822B; + config->thermal_reg_addr = RF_T_METER_8822B; + + config->odm_tx_pwr_track_set_pwr = odm_tx_pwr_track_set_pwr8822b; + config->do_iqk = do_iqk_8822b; + config->phy_lc_calibrate = phy_lc_calibrate_8822b; + + config->get_delta_swing_table = get_delta_swing_table_8822b; +} + +void phy_set_rf_path_switch_8822b(struct phy_dm_struct *dm, bool is_main) +{ + /*BY SY Request */ + odm_set_bb_reg(dm, 0x4C, (BIT(24) | BIT(23)), 0x2); + odm_set_bb_reg(dm, 0x974, 0xff, 0xff); + + /*odm_set_bb_reg(dm, 0x1991, 0x3, 0x0);*/ + odm_set_bb_reg(dm, 0x1990, (BIT(9) | BIT(8)), 0x0); + + /*odm_set_bb_reg(dm, 0xCBE, 0x8, 0x0);*/ + odm_set_bb_reg(dm, 0xCBC, BIT(19), 0x0); + + odm_set_bb_reg(dm, 0xCB4, 0xff, 0x77); + + odm_set_bb_reg(dm, 0x70, MASKBYTE3, 0x0e); + odm_set_bb_reg(dm, 0x1704, MASKDWORD, 0x0000ff00); + odm_set_bb_reg(dm, 0x1700, MASKDWORD, 0xc00f0038); + + if (is_main) { + /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x2); WiFi */ + odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x2); /*WiFi */ + } else { + /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x1); BT*/ + odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x1); /*BT*/ + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h new file mode 100644 index 000000000000..4f3bfe316ee9 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/halphyrf_8822b.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __HAL_PHY_RF_8822B_H__ +#define __HAL_PHY_RF_8822B_H__ + +#define AVG_THERMAL_NUM_8822B 4 +#define RF_T_METER_8822B 0x42 + +void configure_txpower_track_8822b(struct txpwrtrack_cfg *config); + +void odm_tx_pwr_track_set_pwr8822b(void *dm_void, enum pwrtrack_method method, + u8 rf_path, u8 channel_mapped_index); + +void get_delta_swing_table_8822b(void *dm_void, u8 **temperature_up_a, + u8 **temperature_down_a, u8 **temperature_up_b, + u8 **temperature_down_b); + +void phy_lc_calibrate_8822b(void *dm_void); + +void phy_set_rf_path_switch_8822b(struct phy_dm_struct *dm, bool is_main); + +#endif /* #ifndef __HAL_PHY_RF_8822B_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c new file mode 100644 index 000000000000..26d1022e851c --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.c @@ -0,0 +1,1815 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +/* ======================================================================== */ +/* These following functions can be used for PHY DM only*/ + +static u32 reg82c_8822b; +static u32 reg838_8822b; +static u32 reg830_8822b; +static u32 reg83c_8822b; +static u32 rega20_8822b; +static u32 rega24_8822b; +static u32 rega28_8822b; +static enum odm_bw bw_8822b; +static u8 central_ch_8822b; + +static u32 cca_ifem_ccut[12][4] = { + /*20M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*40M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/ + {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x87746641, 0x00000000, 0x87746641}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ +static u32 cca_efem_ccut[12][4] = { + /*20M*/ + {0x75A76010, 0x75A76010, 0x75A76010, 0x75A75010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x87766651, 0x87766431, 0x87766451, 0x87766431}, /*Reg838*/ + {0x9194b2b9, 0x9194b2b9, 0x9194b2b9, 0x9194b2b9}, /*Reg83C*/ + /*40M*/ + {0x75A85010, 0x75A75010, 0x75A85010, 0x75A75010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x87766431, 0x87766431, 0x87766431, 0x87766431}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x76BA7010, 0x75BA7010, 0x76BA7010, 0x75BA7010}, /*Reg82C*/ + {0x79a0ea28, 0x00000000, 0x79a0ea28, 0x00000000}, /*Reg830*/ + {0x87766431, 0x87766431, 0x87766431, 0x87766431}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ +static u32 cca_ifem_ccut_rfetype5[12][4] = { + /*20M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x00000000, 0x87766461, 0x87766461}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*40M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/ + {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x76666641, 0x00000000, 0x76666641}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ +static u32 cca_ifem_ccut_rfetype3[12][4] = { + /*20M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x00000000, 0x87766461, 0x87766461}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*40M*/ + {0x75D97010, 0x75D97010, 0x75D97010, 0x75D97010}, /*Reg82C*/ + {0x00000000, 0x79a0ea2c, 0x00000000, 0x79a0ea28}, /*Reg830*/ + {0x87765541, 0x87766341, 0x87765541, 0x87766341}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg83C*/ + /*80M*/ + {0x75C97010, 0x75C97010, 0x75C97010, 0x75C97010}, /*Reg82C*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, /*Reg830*/ + {0x00000000, 0x76666641, 0x00000000, 0x76666641}, /*Reg838*/ + {0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; /*Reg83C*/ + +static inline u32 phydm_check_bit_mask(u32 bit_mask, u32 data_original, + u32 data) +{ + u8 bit_shift; + + if (bit_mask != 0xfffff) { + for (bit_shift = 0; bit_shift <= 19; bit_shift++) { + if (((bit_mask >> bit_shift) & 0x1) == 1) + break; + } + return ((data_original) & (~bit_mask)) | (data << bit_shift); + } + return data; +} + +static bool phydm_rfe_8822b(struct phy_dm_struct *dm, u8 channel) +{ + if (dm->rfe_type == 4) { + /* Default setting is in PHY parameters */ + + if (channel <= 14) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57); + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x8); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x2); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x8); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x2); + + /* antenna switch table */ + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf050); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf050); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf055); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf055); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xf550); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xf550); + } + + } else if (channel > 35) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75); + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + /* antenna switch table */ + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005); + } + } else { + return false; + } + + } else if ((dm->rfe_type == 1) || (dm->rfe_type == 2) || + (dm->rfe_type == 7) || (dm->rfe_type == 9)) { + /* eFem */ + if (((dm->cut_version == ODM_CUT_A) || + (dm->cut_version == ODM_CUT_B)) && + (dm->rfe_type < 2)) { + if (channel <= 14) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x704570); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x704570); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x45); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x45); + } else if (channel > 35) { + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x174517); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x174517); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x45); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x45); + } else { + return false; + } + + /* delay 400ns for PAPE */ + odm_set_bb_reg(dm, 0x810, + MASKBYTE3 | BIT(20) | BIT(21) | BIT(22) | + BIT(23), + 0x211); + + /* antenna switch table */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa555); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa555); + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s: Using old RFE control pin setting for A-cut and B-cut\n", + __func__); + } else { + if (channel <= 14) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x705770); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x705770); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xcb8, BIT(4), 0); + odm_set_bb_reg(dm, 0xeb8, BIT(4), 0); + } else if (channel > 35) { + /* signal source */ + odm_set_bb_reg(dm, 0xcb0, + (MASKBYTE2 | MASKLWORD), + 0x177517); + odm_set_bb_reg(dm, 0xeb0, + (MASKBYTE2 | MASKLWORD), + 0x177517); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xcb8, BIT(5), 0); + odm_set_bb_reg(dm, 0xeb8, BIT(5), 0); + } else { + return false; + } + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | + BIT(2) | BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + /* antenna switch table */ + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005); + } + } + } else if ((dm->rfe_type == 0) || (dm->rfe_type == 3) || + (dm->rfe_type == 5) || (dm->rfe_type == 6) || + (dm->rfe_type == 8) || (dm->rfe_type == 10)) { + /* iFEM */ + if (channel <= 14) { + /* signal source */ + + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x745774); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x57); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x57); + + } else if (channel > 35) { + /* signal source */ + + odm_set_bb_reg(dm, 0xcb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xeb0, (MASKBYTE2 | MASKLWORD), + 0x477547); + odm_set_bb_reg(dm, 0xcb4, MASKBYTE1, 0x75); + odm_set_bb_reg(dm, 0xeb4, MASKBYTE1, 0x75); + + } else { + return false; + } + + /* inverse or not */ + odm_set_bb_reg(dm, 0xcbc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | + BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xcbc, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(5) | BIT(4) | BIT(3) | BIT(2) | + BIT(1) | BIT(0)), + 0x0); + odm_set_bb_reg(dm, 0xebc, (BIT(11) | BIT(10)), 0x0); + + /* antenna switch table */ + if (channel <= 14) { + if ((dm->rx_ant_status == (ODM_RF_A | ODM_RF_B)) || + (dm->tx_ant_status == (ODM_RF_A | ODM_RF_B))) { + /* 2TX or 2RX */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa501); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa501); + } else if (dm->rx_ant_status == dm->tx_ant_status) { + /* TXA+RXA or TXB+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa500); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa500); + } else { + /* TXB+RXA or TXA+RXB */ + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa005); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa005); + } + } else if (channel > 35) { + odm_set_bb_reg(dm, 0xca0, MASKLWORD, 0xa5a5); + odm_set_bb_reg(dm, 0xea0, MASKLWORD, 0xa5a5); + } + } + + /* chip top mux */ + odm_set_bb_reg(dm, 0x64, BIT(29) | BIT(28), 0x3); + odm_set_bb_reg(dm, 0x4c, BIT(26) | BIT(25), 0x0); + odm_set_bb_reg(dm, 0x40, BIT(2), 0x1); + + /* from s0 or s1 */ + odm_set_bb_reg(dm, 0x1990, + (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), + 0x30); + odm_set_bb_reg(dm, 0x1990, (BIT(11) | BIT(10)), 0x3); + + /* input or output */ + odm_set_bb_reg(dm, 0x974, + (BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)), + 0x3f); + odm_set_bb_reg(dm, 0x974, (BIT(11) | BIT(10)), 0x3); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s: Update RFE control pin setting (ch%d, tx_path 0x%x, rx_path 0x%x)\n", + __func__, channel, dm->tx_ant_status, dm->rx_ant_status); + + return true; +} + +static void phydm_ccapar_by_rfe_8822b(struct phy_dm_struct *dm) +{ + u32 cca_ifem[12][4], cca_efem[12][4]; + u8 row, col; + u32 reg82c, reg830, reg838, reg83c; + + if (dm->cut_version == ODM_CUT_A) + return; + { + odm_move_memory(dm, cca_efem, cca_efem_ccut, 48 * 4); + if (dm->rfe_type == 5) + odm_move_memory(dm, cca_ifem, cca_ifem_ccut_rfetype5, + 48 * 4); + else if (dm->rfe_type == 3) + odm_move_memory(dm, cca_ifem, cca_ifem_ccut_rfetype3, + 48 * 4); + else + odm_move_memory(dm, cca_ifem, cca_ifem_ccut, 48 * 4); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s: Update CCA parameters for Ccut\n", __func__); + } + + if (bw_8822b == ODM_BW20M) + row = 0; + else if (bw_8822b == ODM_BW40M) + row = 4; + else + row = 8; + + if (central_ch_8822b <= 14) { + if ((dm->rx_ant_status == ODM_RF_A) || + (dm->rx_ant_status == ODM_RF_B)) + col = 0; + else + col = 1; + } else { + if ((dm->rx_ant_status == ODM_RF_A) || + (dm->rx_ant_status == ODM_RF_B)) + col = 2; + else + col = 3; + } + + if ((dm->rfe_type == 1) || (dm->rfe_type == 4) || (dm->rfe_type == 6) || + (dm->rfe_type == 7)) { + /*eFEM => RFE type 1 & RFE type 4 & RFE type 6 & RFE type 7*/ + reg82c = (cca_efem[row][col] != 0) ? cca_efem[row][col] : + reg82c_8822b; + reg830 = (cca_efem[row + 1][col] != 0) ? + cca_efem[row + 1][col] : + reg830_8822b; + reg838 = (cca_efem[row + 2][col] != 0) ? + cca_efem[row + 2][col] : + reg838_8822b; + reg83c = (cca_efem[row + 3][col] != 0) ? + cca_efem[row + 3][col] : + reg83c_8822b; + } else if ((dm->rfe_type == 2) || (dm->rfe_type == 9)) { + /*5G eFEM, 2G iFEM => RFE type 2, 5G eFEM => RFE type 9 */ + if (central_ch_8822b <= 14) { + reg82c = (cca_ifem[row][col] != 0) ? + cca_ifem[row][col] : + reg82c_8822b; + reg830 = (cca_ifem[row + 1][col] != 0) ? + cca_ifem[row + 1][col] : + reg830_8822b; + reg838 = (cca_ifem[row + 2][col] != 0) ? + cca_ifem[row + 2][col] : + reg838_8822b; + reg83c = (cca_ifem[row + 3][col] != 0) ? + cca_ifem[row + 3][col] : + reg83c_8822b; + } else { + reg82c = (cca_efem[row][col] != 0) ? + cca_efem[row][col] : + reg82c_8822b; + reg830 = (cca_efem[row + 1][col] != 0) ? + cca_efem[row + 1][col] : + reg830_8822b; + reg838 = (cca_efem[row + 2][col] != 0) ? + cca_efem[row + 2][col] : + reg838_8822b; + reg83c = (cca_efem[row + 3][col] != 0) ? + cca_efem[row + 3][col] : + reg83c_8822b; + } + } else { + /* iFEM =>RFE type 3 & RFE type 5 & RFE type 0 & RFE type 8 & + * RFE type 10 + */ + reg82c = (cca_ifem[row][col] != 0) ? cca_ifem[row][col] : + reg82c_8822b; + reg830 = (cca_ifem[row + 1][col] != 0) ? + cca_ifem[row + 1][col] : + reg830_8822b; + reg838 = (cca_ifem[row + 2][col] != 0) ? + cca_ifem[row + 2][col] : + reg838_8822b; + reg83c = (cca_ifem[row + 3][col] != 0) ? + cca_ifem[row + 3][col] : + reg83c_8822b; + } + + odm_set_bb_reg(dm, 0x82c, MASKDWORD, reg82c); + odm_set_bb_reg(dm, 0x830, MASKDWORD, reg830); + odm_set_bb_reg(dm, 0x838, MASKDWORD, reg838); + odm_set_bb_reg(dm, 0x83c, MASKDWORD, reg83c); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s: (Pkt%d, Intf%d, RFE%d), row = %d, col = %d\n", + __func__, dm->package_type, dm->support_interface, + dm->rfe_type, row, col); +} + +static void phydm_ccapar_by_bw_8822b(struct phy_dm_struct *dm, + enum odm_bw bandwidth) +{ + u32 reg82c; + + if (dm->cut_version != ODM_CUT_A) + return; + + /* A-cut */ + reg82c = odm_get_bb_reg(dm, 0x82c, MASKDWORD); + + if (bandwidth == ODM_BW20M) { + /* 82c[15:12] = 4 */ + /* 82c[27:24] = 6 */ + + reg82c &= (~(0x0f00f000)); + reg82c |= ((0x4) << 12); + reg82c |= ((0x6) << 24); + } else if (bandwidth == ODM_BW40M) { + /* 82c[19:16] = 9 */ + /* 82c[27:24] = 6 */ + + reg82c &= (~(0x0f0f0000)); + reg82c |= ((0x9) << 16); + reg82c |= ((0x6) << 24); + } else if (bandwidth == ODM_BW80M) { + /* 82c[15:12] 7 */ + /* 82c[19:16] b */ + /* 82c[23:20] d */ + /* 82c[27:24] 3 */ + + reg82c &= (~(0x0ffff000)); + reg82c |= ((0xdb7) << 12); + reg82c |= ((0x3) << 24); + } + + odm_set_bb_reg(dm, 0x82c, MASKDWORD, reg82c); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Update CCA parameters for Acut\n", __func__); +} + +static void phydm_ccapar_by_rxpath_8822b(struct phy_dm_struct *dm) +{ + if (dm->cut_version != ODM_CUT_A) + return; + + if ((dm->rx_ant_status == ODM_RF_A) || + (dm->rx_ant_status == ODM_RF_B)) { + /* 838[7:4] = 8 */ + /* 838[11:8] = 7 */ + /* 838[15:12] = 6 */ + /* 838[19:16] = 7 */ + /* 838[23:20] = 7 */ + /* 838[27:24] = 7 */ + odm_set_bb_reg(dm, 0x838, 0x0ffffff0, 0x777678); + } else { + /* 838[7:4] = 3 */ + /* 838[11:8] = 3 */ + /* 838[15:12] = 6 */ + /* 838[19:16] = 6 */ + /* 838[23:20] = 7 */ + /* 838[27:24] = 7 */ + odm_set_bb_reg(dm, 0x838, 0x0ffffff0, 0x776633); + } + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Update CCA parameters for Acut\n", __func__); +} + +static void phydm_rxdfirpar_by_bw_8822b(struct phy_dm_struct *dm, + enum odm_bw bandwidth) +{ + if (bandwidth == ODM_BW40M) { + /* RX DFIR for BW40 */ + odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x1); + odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x0); + odm_set_bb_reg(dm, 0xc20, BIT(31), 0x0); + odm_set_bb_reg(dm, 0xe20, BIT(31), 0x0); + } else if (bandwidth == ODM_BW80M) { + /* RX DFIR for BW80 */ + odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x2); + odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x1); + odm_set_bb_reg(dm, 0xc20, BIT(31), 0x0); + odm_set_bb_reg(dm, 0xe20, BIT(31), 0x0); + } else { + /* RX DFIR for BW20, BW10 and BW5*/ + odm_set_bb_reg(dm, 0x948, BIT(29) | BIT(28), 0x2); + odm_set_bb_reg(dm, 0x94c, BIT(29) | BIT(28), 0x2); + odm_set_bb_reg(dm, 0xc20, BIT(31), 0x1); + odm_set_bb_reg(dm, 0xe20, BIT(31), 0x1); + } +} + +bool phydm_write_txagc_1byte_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u32 offset_txagc[2] = {0x1d00, 0x1d80}; + u8 rate_idx = (hw_rate & 0xfc), i; + u8 rate_offset = (hw_rate & 0x3); + u32 txagc_content = 0x0; + + /* For debug command only!!!! */ + + /* Error handling */ + if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, path); + return false; + } + + /* For HW limitation, We can't write TXAGC once a byte. */ + for (i = 0; i < 4; i++) { + if (i != rate_offset) + txagc_content = + txagc_content | (config_phydm_read_txagc_8822b( + dm, path, rate_idx + i) + << (i << 3)); + else + txagc_content = txagc_content | + ((power_index & 0x3f) << (i << 3)); + } + odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD, + txagc_content); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__, + path, hw_rate, (offset_txagc[path] + hw_rate), + power_index); + return true; +} + +void phydm_init_hw_info_by_rfe_type_8822b(struct phy_dm_struct *dm) +{ + u16 mask_path_a = 0x0303; + u16 mask_path_b = 0x0c0c; + /*u16 mask_path_c = 0x3030;*/ + /*u16 mask_path_d = 0xc0c0;*/ + + dm->is_init_hw_info_by_rfe = false; + + if ((dm->rfe_type == 1) || (dm->rfe_type == 6) || (dm->rfe_type == 7)) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_LNA_5G | + ODM_BOARD_EXT_PA | ODM_BOARD_EXT_PA_5G)); + + if (dm->rfe_type == 6) { + odm_cmn_info_init( + dm, ODM_CMNINFO_GPA, + (TYPE_GPA1 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_APA, + (TYPE_APA1 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA1 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA1 & (mask_path_a | mask_path_b))); + } else if (dm->rfe_type == 7) { + odm_cmn_info_init( + dm, ODM_CMNINFO_GPA, + (TYPE_GPA2 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_APA, + (TYPE_APA2 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA2 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA2 & (mask_path_a | mask_path_b))); + } else { + odm_cmn_info_init( + dm, ODM_CMNINFO_GPA, + (TYPE_GPA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_APA, + (TYPE_APA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init( + dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + } + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true); + } else if (dm->rfe_type == 2) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA_5G | ODM_BOARD_EXT_PA_5G)); + odm_cmn_info_init(dm, ODM_CMNINFO_APA, + (TYPE_APA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true); + } else if (dm->rfe_type == 9) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA_5G)); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } else if ((dm->rfe_type == 3) || (dm->rfe_type == 5)) { + /* RFE type 3: 8822BS\8822BU TFBGA iFEM */ + /* RFE type 5: 8822BE TFBGA iFEM */ + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } else if (dm->rfe_type == 4) { + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, + (ODM_BOARD_EXT_LNA | ODM_BOARD_EXT_LNA_5G | + ODM_BOARD_EXT_PA | ODM_BOARD_EXT_PA_5G)); + odm_cmn_info_init(dm, ODM_CMNINFO_GPA, + (TYPE_GPA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_APA, + (TYPE_APA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_GLNA, + (TYPE_GLNA0 & (mask_path_a | mask_path_b))); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, + (TYPE_ALNA0 & (mask_path_a | mask_path_b))); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, true); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, true); + } else if (dm->rfe_type == 8) { + /* RFE type 8: TFBGA iFEM AP */ + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 2); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } else { + /* RFE Type 0 & 9 & 10: QFN iFEM */ + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_PACKAGE_TYPE, 1); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, false); + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, false); + } + + dm->is_init_hw_info_by_rfe = true; + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): RFE type (%d), Board type (0x%x), Package type (%d)\n", + __func__, dm->rfe_type, dm->board_type, dm->package_type); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): 5G ePA (%d), 5G eLNA (%d), 2G ePA (%d), 2G eLNA (%d)\n", + __func__, dm->ext_pa_5g, dm->ext_lna_5g, dm->ext_pa, + dm->ext_lna); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): 5G PA type (%d), 5G LNA type (%d), 2G PA type (%d), 2G LNA type (%d)\n", + __func__, dm->type_apa, dm->type_alna, dm->type_gpa, + dm->type_glna); +} + +s32 phydm_get_condition_number_8822B(struct phy_dm_struct *dm) +{ + s32 ret_val; + + odm_set_bb_reg(dm, 0x1988, BIT(22), 0x1); + ret_val = + (s32)odm_get_bb_reg(dm, 0xf84, (BIT(17) | BIT(16) | MASKLWORD)); + + if (bw_8822b == 0) { + ret_val = ret_val << (8 - 4); + ret_val = ret_val / 234; + } else if (bw_8822b == 1) { + ret_val = ret_val << (7 - 4); + ret_val = ret_val / 108; + } else if (bw_8822b == 2) { + ret_val = ret_val << (6 - 4); + ret_val = ret_val / 52; + } + + return ret_val; +} + +/* ======================================================================== */ + +/* ======================================================================== */ +/* These following functions can be used by driver*/ + +u32 config_phydm_read_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, u32 reg_addr, + u32 bit_mask) +{ + u32 readback_value, direct_addr; + u32 offset_read_rf[2] = {0x2800, 0x2c00}; + u32 power_RF[2] = {0x1c, 0xec}; + + /* Error handling.*/ + if (rf_path > ODM_RF_PATH_B) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, + rf_path); + return INVALID_RF_DATA; + } + + /* Error handling. Check if RF power is enable or not */ + /* 0xffffffff means RF power is disable */ + if (odm_get_mac_reg(dm, power_RF[rf_path], MASKBYTE3) != 0x7) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Read fail, RF is disabled\n", __func__); + return INVALID_RF_DATA; + } + + /* Calculate offset */ + reg_addr &= 0xff; + direct_addr = offset_read_rf[rf_path] + (reg_addr << 2); + + /* RF register only has 20bits */ + bit_mask &= RFREGOFFSETMASK; + + /* Read RF register directly */ + readback_value = odm_get_bb_reg(dm, direct_addr, bit_mask); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): RF-%d 0x%x = 0x%x, bit mask = 0x%x\n", __func__, + rf_path, reg_addr, readback_value, bit_mask); + return readback_value; +} + +bool config_phydm_write_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, + u32 reg_addr, u32 bit_mask, u32 data) +{ + u32 data_and_addr = 0, data_original = 0; + u32 offset_write_rf[2] = {0xc90, 0xe90}; + u32 power_RF[2] = {0x1c, 0xec}; + + /* Error handling.*/ + if (rf_path > ODM_RF_PATH_B) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, + rf_path); + return false; + } + + /* Read RF register content first */ + reg_addr &= 0xff; + bit_mask = bit_mask & RFREGOFFSETMASK; + + if (bit_mask != RFREGOFFSETMASK) { + data_original = config_phydm_read_rf_reg_8822b( + dm, rf_path, reg_addr, RFREGOFFSETMASK); + + /* Error handling. RF is disabled */ + if (!config_phydm_read_rf_check_8822b(data_original)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Write fail, RF is disable\n", + __func__); + return false; + } + + /* check bit mask */ + data = phydm_check_bit_mask(bit_mask, data_original, data); + } else if (odm_get_mac_reg(dm, power_RF[rf_path], MASKBYTE3) != 0x7) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Write fail, RF is disabled\n", __func__); + return false; + } + + /* Put write addr in [27:20] and write data in [19:00] */ + data_and_addr = ((reg_addr << 20) | (data & 0x000fffff)) & 0x0fffffff; + + /* Write operation */ + odm_set_bb_reg(dm, offset_write_rf[rf_path], MASKDWORD, data_and_addr); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): RF-%d 0x%x = 0x%x (original: 0x%x), bit mask = 0x%x\n", + __func__, rf_path, reg_addr, data, data_original, bit_mask); + return true; +} + +bool config_phydm_write_txagc_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u32 offset_txagc[2] = {0x1d00, 0x1d80}; + u8 rate_idx = (hw_rate & 0xfc); + + /* Input need to be HW rate index, not driver rate index!!!! */ + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + /* Error handling */ + if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, path); + return false; + } + + /* driver need to construct a 4-byte power index */ + odm_set_bb_reg(dm, (offset_txagc[path] + rate_idx), MASKDWORD, + power_index); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): path-%d rate index 0x%x (0x%x) = 0x%x\n", __func__, + path, hw_rate, (offset_txagc[path] + hw_rate), + power_index); + return true; +} + +u8 config_phydm_read_txagc_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path path, u8 hw_rate) +{ + u8 read_back_data; + + /* Input need to be HW rate index, not driver rate index!!!! */ + + /* Error handling */ + if ((path > ODM_RF_PATH_B) || (hw_rate > 0x53)) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): unsupported path (%d)\n", __func__, path); + return INVALID_TXAGC_DATA; + } + + /* Disable TX AGC report */ + odm_set_bb_reg(dm, 0x1998, BIT(16), 0x0); /* need to check */ + + /* Set data rate index (bit0~6) and path index (bit7) */ + odm_set_bb_reg(dm, 0x1998, MASKBYTE0, (hw_rate | (path << 7))); + + /* Enable TXAGC report */ + odm_set_bb_reg(dm, 0x1998, BIT(16), 0x1); + + /* Read TX AGC report */ + read_back_data = (u8)odm_get_bb_reg(dm, 0xd30, 0x7f0000); + + /* Driver have to disable TXAGC report after reading TXAGC + * (ref. user guide v11) + */ + odm_set_bb_reg(dm, 0x1998, BIT(16), 0x0); + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): path-%d rate index 0x%x = 0x%x\n", __func__, path, + hw_rate, read_back_data); + return read_back_data; +} + +bool config_phydm_switch_band_8822b(struct phy_dm_struct *dm, u8 central_ch) +{ + u32 rf_reg18; + bool rf_reg_status = true; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()======================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + rf_reg_status = + rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18); + + if (central_ch <= 14) { + /* 2.4G */ + + /* Enable CCK block */ + odm_set_bb_reg(dm, 0x808, BIT(28), 0x1); + + /* Disable MAC CCK check */ + odm_set_bb_reg(dm, 0x454, BIT(7), 0x0); + + /* Disable BB CCK check */ + odm_set_bb_reg(dm, 0xa80, BIT(18), 0x0); + + /*CCA Mask*/ + odm_set_bb_reg(dm, 0x814, 0x0000FC00, 15); /*default value*/ + + /* RF band */ + rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8)))); + + /* RxHP dynamic control */ + if ((dm->rfe_type == 2) || (dm->rfe_type == 3) || + (dm->rfe_type == 5)) { + odm_set_bb_reg(dm, 0x8cc, MASKDWORD, 0x08108492); + odm_set_bb_reg(dm, 0x8d8, MASKDWORD, 0x29095612); + } + + } else if (central_ch > 35) { + /* 5G */ + + /* Enable BB CCK check */ + odm_set_bb_reg(dm, 0xa80, BIT(18), 0x1); + + /* Enable CCK check */ + odm_set_bb_reg(dm, 0x454, BIT(7), 0x1); + + /* Disable CCK block */ + odm_set_bb_reg(dm, 0x808, BIT(28), 0x0); + + /*CCA Mask*/ + odm_set_bb_reg(dm, 0x814, 0x0000FC00, 15); /*default value*/ + + /* RF band */ + rf_reg18 = (rf_reg18 & (~(BIT(16) | BIT(9) | BIT(8)))); + rf_reg18 = (rf_reg18 | BIT(8) | BIT(16)); + + /* RxHP dynamic control */ + if ((dm->rfe_type == 2) || (dm->rfe_type == 3) || + (dm->rfe_type == 5)) { + odm_set_bb_reg(dm, 0x8cc, MASKDWORD, 0x08100000); + odm_set_bb_reg(dm, 0x8d8, MASKDWORD, 0x21095612); + } + + } else { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Fail to switch band (ch: %d)\n", __func__, + central_ch); + return false; + } + + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->rf_type > ODM_1T1R) + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (!phydm_rfe_8822b(dm, central_ch)) + return false; + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch band (ch: %d), because writing RF register is fail\n", + __func__, central_ch); + return false; + } + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Success to switch band (ch: %d)\n", __func__, + central_ch); + return true; +} + +bool config_phydm_switch_channel_8822b(struct phy_dm_struct *dm, u8 central_ch) +{ + struct dig_thres *dig_tab = &dm->dm_dig_table; + u32 rf_reg18 = 0, rf_reg_b8 = 0, rf_reg_be = 0xff; + bool rf_reg_status = true; + u8 low_band[15] = {0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7, 0xff, + 0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6}; + u8 middle_band[23] = {0x6, 0x5, 0x0, 0x0, 0x7, 0x6, 0x6, 0xff, + 0x0, 0x0, 0x7, 0x6, 0x6, 0x5, 0x0, 0xff, + 0x7, 0x6, 0x6, 0x5, 0x0, 0x0, 0x7}; + u8 high_band[15] = {0x5, 0x5, 0x0, 0x7, 0x7, 0x6, 0x5, 0xff, + 0x0, 0x7, 0x7, 0x6, 0x5, 0x5, 0x0}; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()====================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + central_ch_8822b = central_ch; + rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + rf_reg_status = + rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18); + rf_reg18 = (rf_reg18 & (~(BIT(18) | BIT(17) | MASKBYTE0))); + + if (dm->cut_version == ODM_CUT_A) { + rf_reg_b8 = config_phydm_read_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xb8, RFREGOFFSETMASK); + rf_reg_status = rf_reg_status & + config_phydm_read_rf_check_8822b(rf_reg_b8); + } + + /* Switch band and channel */ + if (central_ch <= 14) { + /* 2.4G */ + + /* 1. RF band and channel*/ + rf_reg18 = (rf_reg18 | central_ch); + + /* 2. AGC table selection */ + odm_set_bb_reg(dm, 0x958, 0x1f, 0x0); + dig_tab->agc_table_idx = 0x0; + + /* 3. Set central frequency for clock offset tracking */ + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x96a); + + /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */ + if (dm->cut_version == ODM_CUT_A) + rf_reg_b8 = rf_reg_b8 | BIT(19); + + /* CCK TX filter parameters */ + if (central_ch == 14) { + odm_set_bb_reg(dm, 0xa20, MASKHWORD, 0x8488); + odm_set_bb_reg(dm, 0xa24, MASKDWORD, 0x00006577); + odm_set_bb_reg(dm, 0xa28, MASKLWORD, 0x0000); + } else { + odm_set_bb_reg(dm, 0xa20, MASKHWORD, + (rega20_8822b >> 16)); + odm_set_bb_reg(dm, 0xa24, MASKDWORD, rega24_8822b); + odm_set_bb_reg(dm, 0xa28, MASKLWORD, + (rega28_8822b & MASKLWORD)); + } + + } else if (central_ch > 35) { + /* 5G */ + + /* 1. RF band and channel*/ + rf_reg18 = (rf_reg18 | central_ch); + + /* 2. AGC table selection */ + if ((central_ch >= 36) && (central_ch <= 64)) { + odm_set_bb_reg(dm, 0x958, 0x1f, 0x1); + dig_tab->agc_table_idx = 0x1; + } else if ((central_ch >= 100) && (central_ch <= 144)) { + odm_set_bb_reg(dm, 0x958, 0x1f, 0x2); + dig_tab->agc_table_idx = 0x2; + } else if (central_ch >= 149) { + odm_set_bb_reg(dm, 0x958, 0x1f, 0x3); + dig_tab->agc_table_idx = 0x3; + } else { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (AGC) (ch: %d)\n", + __func__, central_ch); + return false; + } + + /* 3. Set central frequency for clock offset tracking */ + if ((central_ch >= 36) && (central_ch <= 48)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x494); + } else if ((central_ch >= 52) && (central_ch <= 64)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x453); + } else if ((central_ch >= 100) && (central_ch <= 116)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x452); + } else if ((central_ch >= 118) && (central_ch <= 177)) { + odm_set_bb_reg(dm, 0x860, 0x1ffe0000, 0x412); + } else { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (fc_area) (ch: %d)\n", + __func__, central_ch); + return false; + } + + /* Fix A-cut LCK fail issue @ 5285MHz~5375MHz, 0xb8[19]=0x0 */ + if (dm->cut_version == ODM_CUT_A) { + if ((central_ch >= 57) && (central_ch <= 75)) + rf_reg_b8 = rf_reg_b8 & (~BIT(19)); + else + rf_reg_b8 = rf_reg_b8 | BIT(19); + } + } else { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (ch: %d)\n", + __func__, central_ch); + return false; + } + + /* Modify IGI for MP driver to aviod PCIE interference */ + if (dm->mp_mode && ((dm->rfe_type == 3) || (dm->rfe_type == 5))) { + if (central_ch == 14) + odm_write_dig(dm, 0x26); + else + odm_write_dig(dm, 0x20); + } + + /* Modify the setting of register 0xBE to reduce phase noise */ + if (central_ch <= 14) + rf_reg_be = 0x0; + else if ((central_ch >= 36) && (central_ch <= 64)) + rf_reg_be = low_band[(central_ch - 36) >> 1]; + else if ((central_ch >= 100) && (central_ch <= 144)) + rf_reg_be = middle_band[(central_ch - 100) >> 1]; + else if ((central_ch >= 149) && (central_ch <= 177)) + rf_reg_be = high_band[(central_ch - 149) >> 1]; + else + rf_reg_be = 0xff; + + if (rf_reg_be != 0xff) { + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xbe, + (BIT(17) | BIT(16) | BIT(15)), + rf_reg_be); + } else { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (ch: %d, Phase noise)\n", + __func__, central_ch); + return false; + } + + /* Fix channel 144 issue, ask by RFSI Alvin*/ + /* 00 when freq < 5400; 01 when 5400<=freq<=5720; 10 when freq > 5720; + * 2G don't care + */ + /* need to set 0xdf[18]=1 before writing RF18 when channel 144 */ + if (central_ch == 144) { + rf_reg_status = rf_reg_status & + config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xdf, BIT(18), 0x1); + rf_reg18 = (rf_reg18 | BIT(17)); + } else { + rf_reg_status = rf_reg_status & + config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xdf, BIT(18), 0x0); + + if (central_ch > 144) + rf_reg18 = (rf_reg18 | BIT(18)); + else if (central_ch >= 80) + rf_reg18 = (rf_reg18 | BIT(17)); + } + + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->cut_version == ODM_CUT_A) + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xb8, + RFREGOFFSETMASK, rf_reg_b8); + + if (dm->rf_type > ODM_1T1R) { + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->cut_version == ODM_CUT_A) + rf_reg_status = rf_reg_status & + config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0xb8, + RFREGOFFSETMASK, rf_reg_b8); + } + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch channel (ch: %d), because writing RF register is fail\n", + __func__, central_ch); + return false; + } + + phydm_ccapar_by_rfe_8822b(dm); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Success to switch channel (ch: %d)\n", __func__, + central_ch); + return true; +} + +bool config_phydm_switch_bandwidth_8822b(struct phy_dm_struct *dm, + u8 primary_ch_idx, + enum odm_bw bandwidth) +{ + u32 rf_reg18; + bool rf_reg_status = true; + u8 IGI = 0; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()===================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + /* Error handling */ + if ((bandwidth >= ODM_BW_MAX) || + ((bandwidth == ODM_BW40M) && (primary_ch_idx > 2)) || + ((bandwidth == ODM_BW80M) && (primary_ch_idx > 4))) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d)\n", + __func__, bandwidth, primary_ch_idx); + return false; + } + + bw_8822b = bandwidth; + rf_reg18 = config_phydm_read_rf_reg_8822b(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + rf_reg_status = + rf_reg_status & config_phydm_read_rf_check_8822b(rf_reg18); + + /* Switch bandwidth */ + switch (bandwidth) { + case ODM_BW20M: { + /* Small BW([7:6]) = 0, primary channel ([5:2]) = 0, + * rf mode([1:0]) = 20M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, ODM_BW20M); + + /* ADC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x1); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x1); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 | BIT(11) | BIT(10)); + + break; + } + case ODM_BW40M: { + /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel, + * rf mode([1:0]) = 40M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, + (((primary_ch_idx & 0xf) << 2) | ODM_BW40M)); + + /* CCK primary channel */ + if (primary_ch_idx == 1) + odm_set_bb_reg(dm, 0xa00, BIT(4), primary_ch_idx); + else + odm_set_bb_reg(dm, 0xa00, BIT(4), 0); + + /* ADC clock = 160M clock for BW40 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(11) | BIT(10)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(17), 0x1); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(23) | BIT(22)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(29), 0x1); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10)))); + rf_reg18 = (rf_reg18 | BIT(11)); + + break; + } + case ODM_BW80M: { + /* Small BW([7:6]) = 0, primary channel ([5:2]) = sub-channel, + * rf mode([1:0]) = 80M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, + (((primary_ch_idx & 0xf) << 2) | ODM_BW80M)); + + /* ADC clock = 160M clock for BW80 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(13) | BIT(12)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(18), 0x1); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(25) | BIT(24)), 0x0); + odm_set_bb_reg(dm, 0x8ac, BIT(30), 0x1); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 & (~(BIT(11) | BIT(10)))); + rf_reg18 = (rf_reg18 | BIT(10)); + + break; + } + case ODM_BW5M: { + /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0, + * rf mode([1:0]) = 20M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, (BIT(6) | ODM_BW20M)); + + /* ADC clock = 40M clock */ + odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x2); + odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x0); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x2); + odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x0); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x0); + odm_set_bb_reg(dm, 0x8c8, BIT(31), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 | BIT(11) | BIT(10)); + + break; + } + case ODM_BW10M: { + /* Small BW([7:6]) = 1, primary channel ([5:2]) = 0, + * rf mode([1:0]) = 20M + */ + odm_set_bb_reg(dm, 0x8ac, MASKBYTE0, (BIT(7) | ODM_BW20M)); + + /* ADC clock = 80M clock */ + odm_set_bb_reg(dm, 0x8ac, (BIT(9) | BIT(8)), 0x3); + odm_set_bb_reg(dm, 0x8ac, BIT(16), 0x0); + + /* DAC clock = 160M clock for BW20 */ + odm_set_bb_reg(dm, 0x8ac, (BIT(21) | BIT(20)), 0x3); + odm_set_bb_reg(dm, 0x8ac, BIT(28), 0x0); + + /* ADC buffer clock */ + odm_set_bb_reg(dm, 0x8c4, BIT(30), 0x0); + odm_set_bb_reg(dm, 0x8c8, BIT(31), 0x1); + + /* RF bandwidth */ + rf_reg18 = (rf_reg18 | BIT(11) | BIT(10)); + + break; + } + default: + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d)\n", + __func__, bandwidth, primary_ch_idx); + } + + /* Write RF register */ + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (dm->rf_type > ODM_1T1R) + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_B, 0x18, + RFREGOFFSETMASK, rf_reg18); + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to switch bandwidth (bw: %d, primary ch: %d), because writing RF register is fail\n", + __func__, bandwidth, primary_ch_idx); + return false; + } + + /* Modify RX DFIR parameters */ + phydm_rxdfirpar_by_bw_8822b(dm, bandwidth); + + /* Modify CCA parameters */ + phydm_ccapar_by_bw_8822b(dm, bandwidth); + phydm_ccapar_by_rfe_8822b(dm); + + /* Toggle RX path to avoid RX dead zone issue */ + odm_set_bb_reg(dm, 0x808, MASKBYTE0, 0x0); + odm_set_bb_reg(dm, 0x808, MASKBYTE0, + (dm->rx_ant_status | (dm->rx_ant_status << 4))); + + /* Toggle IGI to let RF enter RX mode */ + IGI = (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), IGI - 2); + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), IGI - 2); + odm_set_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm), IGI); + odm_set_bb_reg(dm, ODM_REG(IGI_B, dm), ODM_BIT(IGI, dm), IGI); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Success to switch bandwidth (bw: %d, primary ch: %d)\n", + __func__, bandwidth, primary_ch_idx); + return true; +} + +bool config_phydm_switch_channel_bw_8822b(struct phy_dm_struct *dm, + u8 central_ch, u8 primary_ch_idx, + enum odm_bw bandwidth) +{ + /* Switch band */ + if (!config_phydm_switch_band_8822b(dm, central_ch)) + return false; + + /* Switch channel */ + if (!config_phydm_switch_channel_8822b(dm, central_ch)) + return false; + + /* Switch bandwidth */ + if (!config_phydm_switch_bandwidth_8822b(dm, primary_ch_idx, bandwidth)) + return false; + + return true; +} + +bool config_phydm_trx_mode_8822b(struct phy_dm_struct *dm, + enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path) +{ + bool rf_reg_status = true; + u8 IGI; + u32 rf_reg33 = 0; + u16 counter = 0; + + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s()=====================>\n", + __func__); + + if (dm->is_disable_phy_api) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): disable PHY API for debug!!\n", __func__); + return true; + } + + if ((tx_path & (~(ODM_RF_A | ODM_RF_B))) != 0) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Wrong TX setting (TX: 0x%x)\n", __func__, + tx_path); + return false; + } + + if ((rx_path & (~(ODM_RF_A | ODM_RF_B))) != 0) { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Wrong RX setting (RX: 0x%x)\n", __func__, + rx_path); + return false; + } + + /* RF mode of path-A and path-B */ + /* Cannot shut down path-A, beacause synthesizer will be shut down when + * path-A is in shut down mode + */ + if ((tx_path | rx_path) & ODM_RF_A) + odm_set_bb_reg(dm, 0xc08, MASKLWORD, 0x3231); + else + odm_set_bb_reg(dm, 0xc08, MASKLWORD, 0x1111); + + if ((tx_path | rx_path) & ODM_RF_B) + odm_set_bb_reg(dm, 0xe08, MASKLWORD, 0x3231); + else + odm_set_bb_reg(dm, 0xe08, MASKLWORD, 0x1111); + + /* Set TX antenna by Nsts */ + odm_set_bb_reg(dm, 0x93c, (BIT(19) | BIT(18)), 0x3); + odm_set_bb_reg(dm, 0x80c, (BIT(29) | BIT(28)), 0x1); + + /* Control CCK TX path by 0xa07[7] */ + odm_set_bb_reg(dm, 0x80c, BIT(30), 0x1); + + /* TX logic map and TX path en for Nsts = 1, and CCK TX path*/ + if (tx_path & ODM_RF_A) { + odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x001); + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x8); + } else if (tx_path & ODM_RF_B) { + odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x002); + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4); + } + + /* TX logic map and TX path en for Nsts = 2*/ + if ((tx_path == ODM_RF_A) || (tx_path == ODM_RF_B)) + odm_set_bb_reg(dm, 0x940, 0xfff0, 0x01); + else + odm_set_bb_reg(dm, 0x940, 0xfff0, 0x43); + + /* TX path enable */ + odm_set_bb_reg(dm, 0x80c, MASKBYTE0, ((tx_path << 4) | tx_path)); + + /* Tx2path for 1ss */ + if (!((tx_path == ODM_RF_A) || (tx_path == ODM_RF_B))) { + if (is_tx2_path || dm->mp_mode) { + /* 2Tx for OFDM */ + odm_set_bb_reg(dm, 0x93c, 0xfff00000, 0x043); + + /* 2Tx for CCK */ + odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc); + } + } + + /* Always disable MRC for CCK CCA */ + odm_set_bb_reg(dm, 0xa2c, BIT(22), 0x0); + + /* Always disable MRC for CCK barker */ + odm_set_bb_reg(dm, 0xa2c, BIT(18), 0x0); + + /* CCK RX 1st and 2nd path setting*/ + if (rx_path & ODM_RF_A) + odm_set_bb_reg(dm, 0xa04, 0x0f000000, 0x0); + else if (rx_path & ODM_RF_B) + odm_set_bb_reg(dm, 0xa04, 0x0f000000, 0x5); + + /* RX path enable */ + odm_set_bb_reg(dm, 0x808, MASKBYTE0, ((rx_path << 4) | rx_path)); + + if ((rx_path == ODM_RF_A) || (rx_path == ODM_RF_B)) { + /* 1R */ + + /* Disable MRC for CCA */ + /* odm_set_bb_reg(dm, 0xa2c, BIT22, 0x0); */ + + /* Disable MRC for barker */ + /* odm_set_bb_reg(dm, 0xa2c, BIT18, 0x0); */ + + /* Disable CCK antenna diversity */ + /* odm_set_bb_reg(dm, 0xa00, BIT15, 0x0); */ + + /* Disable Antenna weighting */ + odm_set_bb_reg(dm, 0x1904, BIT(16), 0x0); + odm_set_bb_reg(dm, 0x800, BIT(28), 0x0); + odm_set_bb_reg(dm, 0x850, BIT(23), 0x0); + } else { + /* 2R */ + + /* Enable MRC for CCA */ + /* odm_set_bb_reg(dm, 0xa2c, BIT22, 0x1); */ + + /* Enable MRC for barker */ + /* odm_set_bb_reg(dm, 0xa2c, BIT18, 0x1); */ + + /* Disable CCK antenna diversity */ + /* odm_set_bb_reg(dm, 0xa00, BIT15, 0x0); */ + + /* Enable Antenna weighting */ + odm_set_bb_reg(dm, 0x1904, BIT(16), 0x1); + odm_set_bb_reg(dm, 0x800, BIT(28), 0x1); + odm_set_bb_reg(dm, 0x850, BIT(23), 0x1); + } + + /* Update TXRX antenna status for PHYDM */ + dm->tx_ant_status = (tx_path & 0x3); + dm->rx_ant_status = (rx_path & 0x3); + + /* MP driver need to support path-B TX\RX */ + + while (1) { + counter++; + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x80000); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, + RFREGOFFSETMASK, 0x00001); + + ODM_delay_us(2); + rf_reg33 = config_phydm_read_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, RFREGOFFSETMASK); + + if ((rf_reg33 == 0x00001) && + (config_phydm_read_rf_check_8822b(rf_reg33))) + break; + else if (counter == 100) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to set TRx mode setting, because writing RF mode table is fail\n", + __func__); + return false; + } + } + + if ((dm->mp_mode) || *dm->antenna_test || (dm->normal_rx_path)) { + /* 0xef 0x80000 0x33 0x00001 0x3e 0x00034 0x3f 0x4080e + * 0xef 0x00000 suggested by Lucas + */ + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x80000); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, + RFREGOFFSETMASK, 0x00001); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3e, + RFREGOFFSETMASK, 0x00034); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3f, + RFREGOFFSETMASK, 0x4080e); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x00000); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): MP mode or Antenna test mode!! support path-B TX and RX\n", + __func__); + } else { + /* 0xef 0x80000 0x33 0x00001 0x3e 0x00034 0x3f 0x4080c + * 0xef 0x00000 + */ + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x80000); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x33, + RFREGOFFSETMASK, 0x00001); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3e, + RFREGOFFSETMASK, 0x00034); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0x3f, + RFREGOFFSETMASK, 0x4080c); + rf_reg_status = + rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x00000); + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Normal mode!! Do not support path-B TX and RX\n", + __func__); + } + + rf_reg_status = rf_reg_status & config_phydm_write_rf_reg_8822b( + dm, ODM_RF_PATH_A, 0xef, + RFREGOFFSETMASK, 0x00000); + + if (!rf_reg_status) { + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Fail to set TRx mode setting (TX: 0x%x, RX: 0x%x), because writing RF register is fail\n", + __func__, tx_path, rx_path); + return false; + } + + /* Toggle IGI to let RF enter RX mode, + * because BB doesn't send 3-wire command when RX path is enable + */ + IGI = (u8)odm_get_bb_reg(dm, ODM_REG(IGI_A, dm), ODM_BIT(IGI, dm)); + odm_write_dig(dm, IGI - 2); + odm_write_dig(dm, IGI); + + /* Modify CCA parameters */ + phydm_ccapar_by_rxpath_8822b(dm); + phydm_ccapar_by_rfe_8822b(dm); + phydm_rfe_8822b(dm, central_ch_8822b); + + ODM_RT_TRACE( + dm, ODM_PHY_CONFIG, + "%s(): Success to set TRx mode setting (TX: 0x%x, RX: 0x%x)\n", + __func__, tx_path, rx_path); + return true; +} + +bool config_phydm_parameter_init(struct phy_dm_struct *dm, + enum odm_parameter_init type) +{ + if (type == ODM_PRE_SETTING) { + odm_set_bb_reg(dm, 0x808, (BIT(28) | BIT(29)), 0x0); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Pre setting: disable OFDM and CCK block\n", + __func__); + } else if (type == ODM_POST_SETTING) { + odm_set_bb_reg(dm, 0x808, (BIT(28) | BIT(29)), 0x3); + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, + "%s(): Post setting: enable OFDM and CCK block\n", + __func__); + reg82c_8822b = odm_get_bb_reg(dm, 0x82c, MASKDWORD); + reg838_8822b = odm_get_bb_reg(dm, 0x838, MASKDWORD); + reg830_8822b = odm_get_bb_reg(dm, 0x830, MASKDWORD); + reg83c_8822b = odm_get_bb_reg(dm, 0x83c, MASKDWORD); + rega20_8822b = odm_get_bb_reg(dm, 0xa20, MASKDWORD); + rega24_8822b = odm_get_bb_reg(dm, 0xa24, MASKDWORD); + rega28_8822b = odm_get_bb_reg(dm, 0xa28, MASKDWORD); + } else { + ODM_RT_TRACE(dm, ODM_PHY_CONFIG, "%s(): Wrong type!!\n", + __func__); + return false; + } + + return true; +} + +/* ======================================================================== */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h new file mode 100644 index 000000000000..279ef06298e2 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_hal_api8822b.h @@ -0,0 +1,84 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __INC_PHYDM_API_H_8822B__ +#define __INC_PHYDM_API_H_8822B__ + +/*2016.08.01 (HW user guide version: R27, SW user guide version: R05, + * Modification: R31) + */ +#define PHY_CONFIG_VERSION_8822B "27.5.31" + +#define INVALID_RF_DATA 0xffffffff +#define INVALID_TXAGC_DATA 0xff + +#define config_phydm_read_rf_check_8822b(data) (data != INVALID_RF_DATA) +#define config_phydm_read_txagc_check_8822b(data) (data != INVALID_TXAGC_DATA) + +u32 config_phydm_read_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, u32 reg_addr, + u32 bit_mask); + +bool config_phydm_write_rf_reg_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path rf_path, + u32 reg_addr, u32 bit_mask, u32 data); + +bool config_phydm_write_txagc_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate); + +u8 config_phydm_read_txagc_8822b(struct phy_dm_struct *dm, + enum odm_rf_radio_path path, u8 hw_rate); + +bool config_phydm_switch_band_8822b(struct phy_dm_struct *dm, u8 central_ch); + +bool config_phydm_switch_channel_8822b(struct phy_dm_struct *dm, u8 central_ch); + +bool config_phydm_switch_bandwidth_8822b(struct phy_dm_struct *dm, + u8 primary_ch_idx, + enum odm_bw bandwidth); + +bool config_phydm_switch_channel_bw_8822b(struct phy_dm_struct *dm, + u8 central_ch, u8 primary_ch_idx, + enum odm_bw bandwidth); + +bool config_phydm_trx_mode_8822b(struct phy_dm_struct *dm, + enum odm_rf_path tx_path, + enum odm_rf_path rx_path, bool is_tx2_path); + +bool config_phydm_parameter_init(struct phy_dm_struct *dm, + enum odm_parameter_init type); + +/* ======================================================================== */ +/* These following functions can be used for PHY DM only*/ + +bool phydm_write_txagc_1byte_8822b(struct phy_dm_struct *dm, u32 power_index, + enum odm_rf_radio_path path, u8 hw_rate); + +void phydm_init_hw_info_by_rfe_type_8822b(struct phy_dm_struct *dm); + +s32 phydm_get_condition_number_8822B(struct phy_dm_struct *dm); + +/* ======================================================================== */ + +#endif /* __INC_PHYDM_API_H_8822B__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c new file mode 100644 index 000000000000..d320311213cc --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.c @@ -0,0 +1,1410 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +/*---------------------------Define Local Constant---------------------------*/ + +static bool _iqk_rx_iqk_by_path_8822b(void *, u8); + +static inline void phydm_set_iqk_info(struct phy_dm_struct *dm, + struct dm_iqk_info *iqk_info, u8 status) +{ + bool KFAIL = true; + + while (1) { + KFAIL = _iqk_rx_iqk_by_path_8822b(dm, ODM_RF_PATH_A); + if (status == 0) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S0RXK KFail = 0x%x\n", KFAIL); + else if (status == 1) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S1RXK KFail = 0x%x\n", KFAIL); + if (iqk_info->rxiqk_step == 5) { + dm->rf_calibrate_info.iqk_step++; + iqk_info->rxiqk_step = 1; + if (KFAIL && status == 0) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S0RXK fail code: %d!!!\n", + iqk_info->rxiqk_fail_code + [0][ODM_RF_PATH_A]); + else if (KFAIL && status == 1) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S1RXK fail code: %d!!!\n", + iqk_info->rxiqk_fail_code + [0][ODM_RF_PATH_A]); + break; + } + } + + iqk_info->kcount++; +} + +static inline void phydm_init_iqk_information(struct dm_iqk_info *iqk_info) +{ + u8 i, j, k, m; + + for (i = 0; i < 2; i++) { + iqk_info->iqk_channel[i] = 0x0; + + for (j = 0; j < SS_8822B; j++) { + iqk_info->lok_idac[i][j] = 0x0; + iqk_info->rxiqk_agc[i][j] = 0x0; + iqk_info->bypass_iqk[i][j] = 0x0; + + for (k = 0; k < 2; k++) { + iqk_info->iqk_fail_report[i][j][k] = true; + for (m = 0; m < 8; m++) { + iqk_info->iqk_cfir_real[i][j][k][m] = + 0x0; + iqk_info->iqk_cfir_imag[i][j][k][m] = + 0x0; + } + } + + for (k = 0; k < 3; k++) + iqk_info->retry_count[i][j][k] = 0x0; + } + } +} + +static inline void phydm_backup_iqk_information(struct dm_iqk_info *iqk_info) +{ + u8 i, j, k; + + iqk_info->iqk_channel[1] = iqk_info->iqk_channel[0]; + for (i = 0; i < 2; i++) { + iqk_info->lok_idac[1][i] = iqk_info->lok_idac[0][i]; + iqk_info->rxiqk_agc[1][i] = iqk_info->rxiqk_agc[0][i]; + iqk_info->bypass_iqk[1][i] = iqk_info->bypass_iqk[0][i]; + iqk_info->rxiqk_fail_code[1][i] = + iqk_info->rxiqk_fail_code[0][i]; + for (j = 0; j < 2; j++) { + iqk_info->iqk_fail_report[1][i][j] = + iqk_info->iqk_fail_report[0][i][j]; + for (k = 0; k < 8; k++) { + iqk_info->iqk_cfir_real[1][i][j][k] = + iqk_info->iqk_cfir_real[0][i][j][k]; + iqk_info->iqk_cfir_imag[1][i][j][k] = + iqk_info->iqk_cfir_imag[0][i][j][k]; + } + } + } + + for (i = 0; i < 4; i++) { + iqk_info->rxiqk_fail_code[0][i] = 0x0; + iqk_info->rxiqk_agc[0][i] = 0x0; + for (j = 0; j < 2; j++) { + iqk_info->iqk_fail_report[0][i][j] = true; + iqk_info->gs_retry_count[0][i][j] = 0x0; + } + for (j = 0; j < 3; j++) + iqk_info->retry_count[0][i][j] = 0x0; + } +} + +static inline void phydm_set_iqk_cfir(struct phy_dm_struct *dm, + struct dm_iqk_info *iqk_info, u8 path) +{ + u8 idx, i; + u32 tmp; + + for (idx = 0; idx < 2; idx++) { + odm_set_bb_reg(dm, 0x1b00, MASKDWORD, 0xf8000008 | path << 1); + + if (idx == 0) + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x3); + else + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x1); + + odm_set_bb_reg(dm, 0x1bd4, + BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16), + 0x10); + + for (i = 0; i < 8; i++) { + odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, + 0xe0000001 + (i * 4)); + tmp = odm_get_bb_reg(dm, 0x1bfc, MASKDWORD); + iqk_info->iqk_cfir_real[0][path][idx][i] = + (tmp & 0x0fff0000) >> 16; + iqk_info->iqk_cfir_imag[0][path][idx][i] = tmp & 0xfff; + } + } +} + +static inline void phydm_get_read_counter(struct phy_dm_struct *dm) +{ + u32 counter = 0x0; + + while (1) { + if (((odm_read_4byte(dm, 0x1bf0) >> 24) == 0x7f) || + (counter > 300)) + break; + + counter++; + ODM_delay_ms(1); + } + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]counter = %d\n", counter); +} + +/*---------------------------Define Local Constant---------------------------*/ + +void do_iqk_8822b(void *dm_void, u8 delta_thermal_index, u8 thermal_value, + u8 threshold) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + odm_reset_iqk_result(dm); + + dm->rf_calibrate_info.thermal_value_iqk = thermal_value; + + phy_iq_calibrate_8822b(dm, true); +} + +static void _iqk_fill_iqk_report_8822b(void *dm_void, u8 channel) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u32 tmp1 = 0x0, tmp2 = 0x0, tmp3 = 0x0; + u8 i; + + for (i = 0; i < SS_8822B; i++) { + tmp1 = tmp1 + + ((iqk_info->iqk_fail_report[channel][i][TX_IQK] & 0x1) + << i); + tmp2 = tmp2 + + ((iqk_info->iqk_fail_report[channel][i][RX_IQK] & 0x1) + << (i + 4)); + tmp3 = tmp3 + ((iqk_info->rxiqk_fail_code[channel][i] & 0x3) + << (i * 2 + 8)); + } + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_set_bb_reg(dm, 0x1bf0, 0x0000ffff, tmp1 | tmp2 | tmp3); + + for (i = 0; i < 2; i++) + odm_write_4byte( + dm, 0x1be8 + (i * 4), + (iqk_info->rxiqk_agc[channel][(i * 2) + 1] << 16) | + iqk_info->rxiqk_agc[channel][i * 2]); +} + +static void _iqk_backup_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup, + u32 *BB_backup, u32 *backup_mac_reg, + u32 *backup_bb_reg) +{ + u32 i; + + for (i = 0; i < MAC_REG_NUM_8822B; i++) + MAC_backup[i] = odm_read_4byte(dm, backup_mac_reg[i]); + + for (i = 0; i < BB_REG_NUM_8822B; i++) + BB_backup[i] = odm_read_4byte(dm, backup_bb_reg[i]); +} + +static void _iqk_backup_rf_8822b(struct phy_dm_struct *dm, u32 RF_backup[][2], + u32 *backup_rf_reg) +{ + u32 i; + + for (i = 0; i < RF_REG_NUM_8822B; i++) { + RF_backup[i][ODM_RF_PATH_A] = odm_get_rf_reg( + dm, ODM_RF_PATH_A, backup_rf_reg[i], RFREGOFFSETMASK); + RF_backup[i][ODM_RF_PATH_B] = odm_get_rf_reg( + dm, ODM_RF_PATH_B, backup_rf_reg[i], RFREGOFFSETMASK); + } +} + +static void _iqk_agc_bnd_int_8822b(struct phy_dm_struct *dm) +{ + /*initialize RX AGC bnd, it must do after bbreset*/ + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_write_4byte(dm, 0x1b00, 0xf80a7008); + odm_write_4byte(dm, 0x1b00, 0xf8015008); + odm_write_4byte(dm, 0x1b00, 0xf8000008); +} + +static void _iqk_bb_reset_8822b(struct phy_dm_struct *dm) +{ + bool cca_ing = false; + u32 count = 0; + + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x0, RFREGOFFSETMASK, 0x10000); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x0, RFREGOFFSETMASK, 0x10000); + + while (1) { + odm_write_4byte(dm, 0x8fc, 0x0); + odm_set_bb_reg(dm, 0x198c, 0x7, 0x7); + cca_ing = (bool)odm_get_bb_reg(dm, 0xfa0, BIT(3)); + + if (count > 30) + cca_ing = false; + + if (cca_ing) { + ODM_delay_ms(1); + count++; + } else { + odm_write_1byte(dm, 0x808, 0x0); /*RX ant off*/ + odm_set_bb_reg(dm, 0xa04, + BIT(27) | BIT(26) | BIT(25) | BIT(24), + 0x0); /*CCK RX path off*/ + + /*BBreset*/ + odm_set_bb_reg(dm, 0x0, BIT(16), 0x0); + odm_set_bb_reg(dm, 0x0, BIT(16), 0x1); + + if (odm_get_bb_reg(dm, 0x660, BIT(16))) + odm_write_4byte(dm, 0x6b4, 0x89000006); + break; + } + } +} + +static void _iqk_afe_setting_8822b(struct phy_dm_struct *dm, bool do_iqk) +{ + if (do_iqk) { + odm_write_4byte(dm, 0xc60, 0x50000000); + odm_write_4byte(dm, 0xc60, 0x70070040); + odm_write_4byte(dm, 0xe60, 0x50000000); + odm_write_4byte(dm, 0xe60, 0x70070040); + + odm_write_4byte(dm, 0xc58, 0xd8000402); + odm_write_4byte(dm, 0xc5c, 0xd1000120); + odm_write_4byte(dm, 0xc6c, 0x00000a15); + odm_write_4byte(dm, 0xe58, 0xd8000402); + odm_write_4byte(dm, 0xe5c, 0xd1000120); + odm_write_4byte(dm, 0xe6c, 0x00000a15); + _iqk_bb_reset_8822b(dm); + } else { + odm_write_4byte(dm, 0xc60, 0x50000000); + odm_write_4byte(dm, 0xc60, 0x70038040); + odm_write_4byte(dm, 0xe60, 0x50000000); + odm_write_4byte(dm, 0xe60, 0x70038040); + + odm_write_4byte(dm, 0xc58, 0xd8020402); + odm_write_4byte(dm, 0xc5c, 0xde000120); + odm_write_4byte(dm, 0xc6c, 0x0000122a); + odm_write_4byte(dm, 0xe58, 0xd8020402); + odm_write_4byte(dm, 0xe5c, 0xde000120); + odm_write_4byte(dm, 0xe6c, 0x0000122a); + } +} + +static void _iqk_restore_mac_bb_8822b(struct phy_dm_struct *dm, u32 *MAC_backup, + u32 *BB_backup, u32 *backup_mac_reg, + u32 *backup_bb_reg) +{ + u32 i; + + for (i = 0; i < MAC_REG_NUM_8822B; i++) + odm_write_4byte(dm, backup_mac_reg[i], MAC_backup[i]); + for (i = 0; i < BB_REG_NUM_8822B; i++) + odm_write_4byte(dm, backup_bb_reg[i], BB_backup[i]); +} + +static void _iqk_restore_rf_8822b(struct phy_dm_struct *dm, u32 *backup_rf_reg, + u32 RF_backup[][2]) +{ + u32 i; + + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xef, RFREGOFFSETMASK, 0x0); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xef, RFREGOFFSETMASK, 0x0); + /*0xdf[4]=0*/ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0xdf, RFREGOFFSETMASK, + RF_backup[0][ODM_RF_PATH_A] & (~BIT(4))); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0xdf, RFREGOFFSETMASK, + RF_backup[0][ODM_RF_PATH_B] & (~BIT(4))); + + for (i = 1; i < RF_REG_NUM_8822B; i++) { + odm_set_rf_reg(dm, ODM_RF_PATH_A, backup_rf_reg[i], + RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_A]); + odm_set_rf_reg(dm, ODM_RF_PATH_B, backup_rf_reg[i], + RFREGOFFSETMASK, RF_backup[i][ODM_RF_PATH_B]); + } +} + +static void _iqk_backup_iqk_8822b(struct phy_dm_struct *dm, u8 step) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 path; + u16 iqk_apply[2] = {0xc94, 0xe94}; + + if (step == 0x0) { + phydm_backup_iqk_information(iqk_info); + } else { + iqk_info->iqk_channel[0] = iqk_info->rf_reg18; + for (path = 0; path < 2; path++) { + iqk_info->lok_idac[0][path] = + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x58, RFREGOFFSETMASK); + iqk_info->bypass_iqk[0][path] = + odm_get_bb_reg(dm, iqk_apply[path], MASKDWORD); + + phydm_set_iqk_cfir(dm, iqk_info, path); + odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0); + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0); + } + } +} + +static void _iqk_reload_iqk_setting_8822b( + struct phy_dm_struct *dm, u8 channel, + u8 reload_idx /*1: reload TX, 2: reload LO, TX, RX*/ + ) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 i, path, idx; + u16 iqk_apply[2] = {0xc94, 0xe94}; + + for (path = 0; path < 2; path++) { + if (reload_idx == 2) { + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf, + BIT(4), 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x58, + RFREGOFFSETMASK, + iqk_info->lok_idac[channel][path]); + } + + for (idx = 0; idx < reload_idx; idx++) { + odm_set_bb_reg(dm, 0x1b00, MASKDWORD, + 0xf8000008 | path << 1); + odm_set_bb_reg(dm, 0x1b2c, MASKDWORD, 0x7); + odm_set_bb_reg(dm, 0x1b38, MASKDWORD, 0x20000000); + odm_set_bb_reg(dm, 0x1b3c, MASKDWORD, 0x20000000); + odm_set_bb_reg(dm, 0x1bcc, MASKDWORD, 0x00000000); + + if (idx == 0) + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), + 0x3); + else + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), + 0x1); + + odm_set_bb_reg(dm, 0x1bd4, BIT(20) | BIT(19) | BIT(18) | + BIT(17) | BIT(16), + 0x10); + + for (i = 0; i < 8; i++) { + odm_write_4byte( + dm, 0x1bd8, + ((0xc0000000 >> idx) + 0x3) + (i * 4) + + (iqk_info->iqk_cfir_real + [channel][path][idx][i] + << 9)); + odm_write_4byte( + dm, 0x1bd8, + ((0xc0000000 >> idx) + 0x1) + (i * 4) + + (iqk_info->iqk_cfir_imag + [channel][path][idx][i] + << 9)); + } + } + odm_set_bb_reg(dm, iqk_apply[path], MASKDWORD, + iqk_info->bypass_iqk[channel][path]); + + odm_set_bb_reg(dm, 0x1bd8, MASKDWORD, 0x0); + odm_set_bb_reg(dm, 0x1b0c, BIT(13) | BIT(12), 0x0); + } +} + +static bool _iqk_reload_iqk_8822b(struct phy_dm_struct *dm, bool reset) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 i; + bool reload = false; + + if (reset) { + for (i = 0; i < 2; i++) + iqk_info->iqk_channel[i] = 0x0; + } else { + iqk_info->rf_reg18 = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, + RFREGOFFSETMASK); + + for (i = 0; i < 2; i++) { + if (iqk_info->rf_reg18 == iqk_info->iqk_channel[i]) { + _iqk_reload_iqk_setting_8822b(dm, i, 2); + _iqk_fill_iqk_report_8822b(dm, i); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]reload IQK result before!!!!\n"); + reload = true; + } + } + } + return reload; +} + +static void _iqk_rfe_setting_8822b(struct phy_dm_struct *dm, bool ext_pa_on) +{ + if (ext_pa_on) { + /*RFE setting*/ + odm_write_4byte(dm, 0xcb0, 0x77777777); + odm_write_4byte(dm, 0xcb4, 0x00007777); + odm_write_4byte(dm, 0xcbc, 0x0000083B); + odm_write_4byte(dm, 0xeb0, 0x77777777); + odm_write_4byte(dm, 0xeb4, 0x00007777); + odm_write_4byte(dm, 0xebc, 0x0000083B); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]external PA on!!!!\n"); + } else { + /*RFE setting*/ + odm_write_4byte(dm, 0xcb0, 0x77777777); + odm_write_4byte(dm, 0xcb4, 0x00007777); + odm_write_4byte(dm, 0xcbc, 0x00000100); + odm_write_4byte(dm, 0xeb0, 0x77777777); + odm_write_4byte(dm, 0xeb4, 0x00007777); + odm_write_4byte(dm, 0xebc, 0x00000100); + } +} + +static void _iqk_rf_setting_8822b(struct phy_dm_struct *dm) +{ + u8 path; + u32 tmp; + + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_write_4byte(dm, 0x1bb8, 0x00000000); + + for (path = 0; path < 2; path++) { + /*0xdf:B11 = 1,B4 = 0, B1 = 1*/ + tmp = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf, + RFREGOFFSETMASK); + tmp = (tmp & (~BIT(4))) | BIT(1) | BIT(11); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xdf, + RFREGOFFSETMASK, tmp); + + /*release 0x56 TXBB*/ + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x65, + RFREGOFFSETMASK, 0x09000); + + if (*dm->band_type == ODM_BAND_5G) { + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + RFREGOFFSETMASK, 0x00026); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e, + RFREGOFFSETMASK, 0x00037); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f, + RFREGOFFSETMASK, 0xdefce); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x0); + } else { + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + RFREGOFFSETMASK, 0x00026); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3e, + RFREGOFFSETMASK, 0x00037); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x3f, + RFREGOFFSETMASK, 0x5efce); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, + BIT(19), 0x0); + } + } +} + +static void _iqk_configure_macbb_8822b(struct phy_dm_struct *dm) +{ + /*MACBB register setting*/ + odm_write_1byte(dm, 0x522, 0x7f); + odm_set_bb_reg(dm, 0x550, BIT(11) | BIT(3), 0x0); + odm_set_bb_reg(dm, 0x90c, BIT(15), + 0x1); /*0x90c[15]=1: dac_buf reset selection*/ + odm_set_bb_reg(dm, 0x9a4, BIT(31), + 0x0); /*0x9a4[31]=0: Select da clock*/ + /*0xc94[0]=1, 0xe94[0]=1: let tx through iqk*/ + odm_set_bb_reg(dm, 0xc94, BIT(0), 0x1); + odm_set_bb_reg(dm, 0xe94, BIT(0), 0x1); + /* 3-wire off*/ + odm_write_4byte(dm, 0xc00, 0x00000004); + odm_write_4byte(dm, 0xe00, 0x00000004); +} + +static void _iqk_lok_setting_8822b(struct phy_dm_struct *dm, u8 path) +{ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1bcc, 0x9); + odm_write_1byte(dm, 0x1b23, 0x00); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + odm_write_1byte(dm, 0x1b2b, 0x00); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x50df2); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xadc00); + /* WE_LUT_TX_LOK*/ + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4), + 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + BIT(1) | BIT(0), 0x0); + break; + case ODM_BAND_5G: + odm_write_1byte(dm, 0x1b2b, 0x80); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x5086c); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + /* WE_LUT_TX_LOK*/ + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0xef, BIT(4), + 0x1); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x33, + BIT(1) | BIT(0), 0x1); + break; + } +} + +static void _iqk_txk_setting_8822b(struct phy_dm_struct *dm, u8 path) +{ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1bcc, 0x9); + odm_write_4byte(dm, 0x1b20, 0x01440008); + + if (path == 0x0) + odm_write_4byte(dm, 0x1b00, 0xf800000a); + else + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_write_4byte(dm, 0x1bcc, 0x3f); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x50df2); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xadc00); + odm_write_1byte(dm, 0x1b2b, 0x00); + break; + case ODM_BAND_5G: + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x500ef); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + odm_write_1byte(dm, 0x1b2b, 0x80); + break; + } +} + +static void _iqk_rxk1_setting_8822b(struct phy_dm_struct *dm, u8 path) +{ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + odm_write_1byte(dm, 0x1bcc, 0x9); + odm_write_1byte(dm, 0x1b2b, 0x00); + odm_write_4byte(dm, 0x1b20, 0x01450008); + odm_write_4byte(dm, 0x1b24, 0x01460c88); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x510e0); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xacc00); + break; + case ODM_BAND_5G: + odm_write_1byte(dm, 0x1bcc, 0x09); + odm_write_1byte(dm, 0x1b2b, 0x80); + odm_write_4byte(dm, 0x1b20, 0x00850008); + odm_write_4byte(dm, 0x1b24, 0x00460048); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x510e0); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xadc00); + break; + } +} + +static void _iqk_rxk2_setting_8822b(struct phy_dm_struct *dm, u8 path, + bool is_gs) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + + switch (*dm->band_type) { + case ODM_BAND_2_4G: + if (is_gs) + iqk_info->tmp1bcc = 0x12; + odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc); + odm_write_1byte(dm, 0x1b2b, 0x00); + odm_write_4byte(dm, 0x1b20, 0x01450008); + odm_write_4byte(dm, 0x1b24, 0x01460848); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x510e0); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + break; + case ODM_BAND_5G: + if (is_gs) { + if (path == ODM_RF_PATH_A) + iqk_info->tmp1bcc = 0x12; + else + iqk_info->tmp1bcc = 0x09; + } + odm_write_1byte(dm, 0x1bcc, iqk_info->tmp1bcc); + odm_write_1byte(dm, 0x1b2b, 0x80); + odm_write_4byte(dm, 0x1b20, 0x00850008); + odm_write_4byte(dm, 0x1b24, 0x00460848); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x56, + RFREGOFFSETMASK, 0x51060); + odm_set_rf_reg(dm, (enum odm_rf_radio_path)path, 0x8f, + RFREGOFFSETMASK, 0xa9c00); + break; + } +} + +static bool _iqk_check_cal_8822b(struct phy_dm_struct *dm, u32 IQK_CMD) +{ + bool notready = true, fail = true; + u32 delay_count = 0x0; + + while (notready) { + if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) { + fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26)); + notready = false; + } else { + ODM_delay_ms(1); + delay_count++; + } + + if (delay_count >= 50) { + fail = true; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]IQK timeout!!!\n"); + break; + } + } + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay count = 0x%x!!!\n", + delay_count); + return fail; +} + +static bool _iqk_rx_iqk_gain_search_fail_8822b(struct phy_dm_struct *dm, + u8 path, u8 step) +{ + struct dm_iqk_info *iqk_info = &dm->IQK_info; + bool fail = true; + u32 IQK_CMD = 0x0, rf_reg0, tmp, bb_idx; + u8 IQMUX[4] = {0x9, 0x12, 0x1b, 0x24}; + u8 idx; + + for (idx = 0; idx < 4; idx++) + if (iqk_info->tmp1bcc == IQMUX[idx]) + break; + + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1bcc, iqk_info->tmp1bcc); + + if (step == RXIQK1) + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d RXIQK GainSearch ============\n", + path); + + if (step == RXIQK1) + IQK_CMD = 0xf8000208 | (1 << (path + 4)); + else + IQK_CMD = 0xf8000308 | (1 << (path + 4)); + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]S%d GS%d_Trigger = 0x%x\n", + path, step, IQK_CMD); + + odm_write_4byte(dm, 0x1b00, IQK_CMD); + odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1); + ODM_delay_ms(GS_delay_8822B); + fail = _iqk_check_cal_8822b(dm, IQK_CMD); + + if (step == RXIQK2) { + rf_reg0 = odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, 0x0, + RFREGOFFSETMASK); + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> RF0x0 = 0x%x, tmp1bcc = 0x%x, idx = %d, 0x1b3c = 0x%x\n", + path, rf_reg0, iqk_info->tmp1bcc, idx, + odm_read_4byte(dm, 0x1b3c)); + tmp = (rf_reg0 & 0x1fe0) >> 5; + iqk_info->lna_idx = tmp >> 5; + bb_idx = tmp & 0x1f; + if (bb_idx == 0x1) { + if (iqk_info->lna_idx != 0x0) + iqk_info->lna_idx--; + else if (idx != 3) + idx++; + else + iqk_info->isbnd = true; + fail = true; + } else if (bb_idx == 0xa) { + if (idx != 0) + idx--; + else if (iqk_info->lna_idx != 0x7) + iqk_info->lna_idx++; + else + iqk_info->isbnd = true; + fail = true; + } else { + fail = false; + } + + if (iqk_info->isbnd) + fail = false; + + iqk_info->tmp1bcc = IQMUX[idx]; + + if (fail) { + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte( + dm, 0x1b24, + (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) | + (iqk_info->lna_idx << 10)); + } + } + + return fail; +} + +static bool _lok_one_shot_8822b(void *dm_void, u8 path) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 delay_count = 0; + bool LOK_notready = false; + u32 LOK_temp = 0; + u32 IQK_CMD = 0x0; + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========S%d LOK ==========\n", path); + + IQK_CMD = 0xf8000008 | (1 << (4 + path)); + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]LOK_Trigger = 0x%x\n", + IQK_CMD); + + odm_write_4byte(dm, 0x1b00, IQK_CMD); + odm_write_4byte(dm, 0x1b00, IQK_CMD + 1); + /*LOK: CMD ID = 0 {0xf8000018, 0xf8000028}*/ + /*LOK: CMD ID = 0 {0xf8000019, 0xf8000029}*/ + ODM_delay_ms(LOK_delay_8822B); + + delay_count = 0; + LOK_notready = true; + + while (LOK_notready) { + if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) + LOK_notready = false; + else + LOK_notready = true; + + if (LOK_notready) { + ODM_delay_ms(1); + delay_count++; + } + + if (delay_count >= 50) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d LOK timeout!!!\n", path); + break; + } + } + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> delay_count = 0x%x\n", path, delay_count); + if (ODM_COMP_CALIBRATION) { + if (!LOK_notready) { + LOK_temp = + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x58, RFREGOFFSETMASK); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]0x58 = 0x%x\n", LOK_temp); + } else { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==>S%d LOK Fail!!!\n", path); + } + } + iqk_info->lok_fail[path] = LOK_notready; + return LOK_notready; +} + +static bool _iqk_one_shot_8822b(void *dm_void, u8 path, u8 idx) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 delay_count = 0; + bool notready = true, fail = true; + u32 IQK_CMD = 0x0; + u16 iqk_apply[2] = {0xc94, 0xe94}; + + if (idx == TXIQK) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d WBTXIQK ============\n", + path); + else if (idx == RXIQK1) + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d WBRXIQK STEP1============\n", + path); + else + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]============ S%d WBRXIQK STEP2============\n", + path); + + if (idx == TXIQK) { + IQK_CMD = 0xf8000008 | ((*dm->band_width + 4) << 8) | + (1 << (path + 4)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]TXK_Trigger = 0x%x\n", IQK_CMD); + /*{0xf8000418, 0xf800042a} ==> 20 WBTXK (CMD = 4)*/ + /*{0xf8000518, 0xf800052a} ==> 40 WBTXK (CMD = 5)*/ + /*{0xf8000618, 0xf800062a} ==> 80 WBTXK (CMD = 6)*/ + } else if (idx == RXIQK1) { + if (*dm->band_width == 2) + IQK_CMD = 0xf8000808 | (1 << (path + 4)); + else + IQK_CMD = 0xf8000708 | (1 << (path + 4)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]RXK1_Trigger = 0x%x\n", IQK_CMD); + /*{0xf8000718, 0xf800072a} ==> 20 WBTXK (CMD = 7)*/ + /*{0xf8000718, 0xf800072a} ==> 40 WBTXK (CMD = 7)*/ + /*{0xf8000818, 0xf800082a} ==> 80 WBTXK (CMD = 8)*/ + } else if (idx == RXIQK2) { + IQK_CMD = 0xf8000008 | ((*dm->band_width + 9) << 8) | + (1 << (path + 4)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]RXK2_Trigger = 0x%x\n", IQK_CMD); + /*{0xf8000918, 0xf800092a} ==> 20 WBRXK (CMD = 9)*/ + /*{0xf8000a18, 0xf8000a2a} ==> 40 WBRXK (CMD = 10)*/ + /*{0xf8000b18, 0xf8000b2a} ==> 80 WBRXK (CMD = 11)*/ + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + odm_write_4byte(dm, 0x1b24, + (odm_read_4byte(dm, 0x1b24) & 0xffffe3ff) | + ((iqk_info->lna_idx & 0x7) << 10)); + } + odm_write_4byte(dm, 0x1b00, IQK_CMD); + odm_write_4byte(dm, 0x1b00, IQK_CMD + 0x1); + ODM_delay_ms(WBIQK_delay_8822B); + + while (notready) { + if (odm_read_4byte(dm, 0x1b00) == (IQK_CMD & 0xffffff0f)) + notready = false; + else + notready = true; + + if (notready) { + ODM_delay_ms(1); + delay_count++; + } else { + fail = (bool)odm_get_bb_reg(dm, 0x1b08, BIT(26)); + break; + } + + if (delay_count >= 50) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d IQK timeout!!!\n", path); + break; + } + } + + if (dm->debug_components & ODM_COMP_CALIBRATION) { + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> 0x1b00 = 0x%x, 0x1b08 = 0x%x\n", + path, odm_read_4byte(dm, 0x1b00), + odm_read_4byte(dm, 0x1b08)); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> delay_count = 0x%x\n", path, + delay_count); + if (idx != TXIQK) + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]S%d ==> RF0x0 = 0x%x, RF0x56 = 0x%x\n", + path, + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x0, RFREGOFFSETMASK), + odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x56, RFREGOFFSETMASK)); + } + + odm_write_4byte(dm, 0x1b00, 0xf8000008 | path << 1); + + if (idx == TXIQK) + if (fail) + odm_set_bb_reg(dm, iqk_apply[path], BIT(0), 0x0); + + if (idx == RXIQK2) { + iqk_info->rxiqk_agc[0][path] = + (u16)(((odm_get_rf_reg(dm, (enum odm_rf_radio_path)path, + 0x0, RFREGOFFSETMASK) >> + 5) & + 0xff) | + (iqk_info->tmp1bcc << 8)); + + odm_write_4byte(dm, 0x1b38, 0x20000000); + + if (!fail) + odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)), + 0x1); + else + odm_set_bb_reg(dm, iqk_apply[path], (BIT(11) | BIT(10)), + 0x0); + } + + if (idx == TXIQK) + iqk_info->iqk_fail_report[0][path][TXIQK] = fail; + else + iqk_info->iqk_fail_report[0][path][RXIQK] = fail; + + return fail; +} + +static bool _iqk_rx_iqk_by_path_8822b(void *dm_void, u8 path) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + bool KFAIL = true, gonext; + + switch (iqk_info->rxiqk_step) { + case 1: /*gain search_RXK1*/ + _iqk_rxk1_setting_8822b(dm, path); + gonext = false; + while (1) { + KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path, + RXIQK1); + if (KFAIL && + (iqk_info->gs_retry_count[0][path][GSRXK1] < 2)) + iqk_info->gs_retry_count[0][path][GSRXK1]++; + else if (KFAIL) { + iqk_info->rxiqk_fail_code[0][path] = 0; + iqk_info->rxiqk_step = 5; + gonext = true; + } else { + iqk_info->rxiqk_step++; + gonext = true; + } + if (gonext) + break; + } + break; + case 2: /*gain search_RXK2*/ + _iqk_rxk2_setting_8822b(dm, path, true); + iqk_info->isbnd = false; + while (1) { + KFAIL = _iqk_rx_iqk_gain_search_fail_8822b(dm, path, + RXIQK2); + if (KFAIL && + (iqk_info->gs_retry_count[0][path][GSRXK2] < + rxiqk_gs_limit)) { + iqk_info->gs_retry_count[0][path][GSRXK2]++; + } else { + iqk_info->rxiqk_step++; + break; + } + } + break; + case 3: /*RXK1*/ + _iqk_rxk1_setting_8822b(dm, path); + gonext = false; + while (1) { + KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK1); + if (KFAIL && + (iqk_info->retry_count[0][path][RXIQK1] < 2)) + iqk_info->retry_count[0][path][RXIQK1]++; + else if (KFAIL) { + iqk_info->rxiqk_fail_code[0][path] = 1; + iqk_info->rxiqk_step = 5; + gonext = true; + } else { + iqk_info->rxiqk_step++; + gonext = true; + } + if (gonext) + break; + } + break; + case 4: /*RXK2*/ + _iqk_rxk2_setting_8822b(dm, path, false); + gonext = false; + while (1) { + KFAIL = _iqk_one_shot_8822b(dm, path, RXIQK2); + if (KFAIL && + (iqk_info->retry_count[0][path][RXIQK2] < 2)) + iqk_info->retry_count[0][path][RXIQK2]++; + else if (KFAIL) { + iqk_info->rxiqk_fail_code[0][path] = 2; + iqk_info->rxiqk_step = 5; + gonext = true; + } else { + iqk_info->rxiqk_step++; + gonext = true; + } + if (gonext) + break; + } + break; + } + return KFAIL; +} + +static void _iqk_iqk_by_path_8822b(void *dm_void, bool segment_iqk) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + bool KFAIL = true; + u8 i, kcount_limit; + + if (*dm->band_width == 2) + kcount_limit = kcount_limit_80m; + else + kcount_limit = kcount_limit_others; + + while (1) { + switch (dm->rf_calibrate_info.iqk_step) { + case 1: /*S0 LOK*/ + _iqk_lok_setting_8822b(dm, ODM_RF_PATH_A); + _lok_one_shot_8822b(dm, ODM_RF_PATH_A); + dm->rf_calibrate_info.iqk_step++; + break; + case 2: /*S1 LOK*/ + _iqk_lok_setting_8822b(dm, ODM_RF_PATH_B); + _lok_one_shot_8822b(dm, ODM_RF_PATH_B); + dm->rf_calibrate_info.iqk_step++; + break; + case 3: /*S0 TXIQK*/ + _iqk_txk_setting_8822b(dm, ODM_RF_PATH_A); + KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_A, TXIQK); + iqk_info->kcount++; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S0TXK KFail = 0x%x\n", KFAIL); + + if (KFAIL && + (iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK] < + 3)) + iqk_info->retry_count[0][ODM_RF_PATH_A] + [TXIQK]++; + else + dm->rf_calibrate_info.iqk_step++; + break; + case 4: /*S1 TXIQK*/ + _iqk_txk_setting_8822b(dm, ODM_RF_PATH_B); + KFAIL = _iqk_one_shot_8822b(dm, ODM_RF_PATH_B, TXIQK); + iqk_info->kcount++; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]S1TXK KFail = 0x%x\n", KFAIL); + if (KFAIL && + iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK] < 3) + iqk_info->retry_count[0][ODM_RF_PATH_B] + [TXIQK]++; + else + dm->rf_calibrate_info.iqk_step++; + break; + case 5: /*S0 RXIQK*/ + phydm_set_iqk_info(dm, iqk_info, 0); + break; + case 6: /*S1 RXIQK*/ + phydm_set_iqk_info(dm, iqk_info, 1); + break; + } + + if (dm->rf_calibrate_info.iqk_step == 7) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========LOK summary ==========\n"); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_LOK_notready = %d, PathB_LOK1_notready = %d\n", + iqk_info->lok_fail[ODM_RF_PATH_A], + iqk_info->lok_fail[ODM_RF_PATH_B]); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========IQK summary ==========\n"); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_TXIQK_fail = %d, PathB_TXIQK_fail = %d\n", + iqk_info->iqk_fail_report[0][ODM_RF_PATH_A] + [TXIQK], + iqk_info->iqk_fail_report[0][ODM_RF_PATH_B] + [TXIQK]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_RXIQK_fail = %d, PathB_RXIQK_fail = %d\n", + iqk_info->iqk_fail_report[0][ODM_RF_PATH_A] + [RXIQK], + iqk_info->iqk_fail_report[0][ODM_RF_PATH_B] + [RXIQK]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_TXIQK_retry = %d, PathB_TXIQK_retry = %d\n", + iqk_info->retry_count[0][ODM_RF_PATH_A][TXIQK], + iqk_info->retry_count[0][ODM_RF_PATH_B][TXIQK]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_RXK1_retry = %d, PathA_RXK2_retry = %d, PathB_RXK1_retry = %d, PathB_RXK2_retry = %d\n", + iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK1], + iqk_info->retry_count[0][ODM_RF_PATH_A][RXIQK2], + iqk_info->retry_count[0][ODM_RF_PATH_B][RXIQK1], + iqk_info->retry_count[0][ODM_RF_PATH_B] + [RXIQK2]); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]PathA_GS1_retry = %d, PathA_GS2_retry = %d, PathB_GS1_retry = %d, PathB_GS2_retry = %d\n", + iqk_info->gs_retry_count[0][ODM_RF_PATH_A] + [GSRXK1], + iqk_info->gs_retry_count[0][ODM_RF_PATH_A] + [GSRXK2], + iqk_info->gs_retry_count[0][ODM_RF_PATH_B] + [GSRXK1], + iqk_info->gs_retry_count[0][ODM_RF_PATH_B] + [GSRXK2]); + for (i = 0; i < 2; i++) { + odm_write_4byte(dm, 0x1b00, + 0xf8000008 | i << 1); + odm_write_4byte(dm, 0x1b2c, 0x7); + odm_write_4byte(dm, 0x1bcc, 0x0); + } + break; + } + + if (segment_iqk && (iqk_info->kcount == kcount_limit)) + break; + } +} + +static void _iqk_start_iqk_8822b(struct phy_dm_struct *dm, bool segment_iqk) +{ + u32 tmp; + + /*GNT_WL = 1*/ + tmp = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK); + tmp = tmp | BIT(5) | BIT(0); + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x1, RFREGOFFSETMASK, tmp); + + tmp = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK); + tmp = tmp | BIT(5) | BIT(0); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x1, RFREGOFFSETMASK, tmp); + + _iqk_iqk_by_path_8822b(dm, segment_iqk); +} + +static void _iq_calibrate_8822b_init(void *dm_void) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + struct dm_iqk_info *iqk_info = &dm->IQK_info; + u8 i, j; + + if (iqk_info->iqk_times == 0) { + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]=====>PHY_IQCalibrate_8822B_Init\n"); + + for (i = 0; i < SS_8822B; i++) { + for (j = 0; j < 2; j++) { + iqk_info->lok_fail[i] = true; + iqk_info->iqk_fail[j][i] = true; + iqk_info->iqc_matrix[j][i] = 0x20000000; + } + } + + phydm_init_iqk_information(iqk_info); + } +} + +static void _phy_iq_calibrate_8822b(struct phy_dm_struct *dm, bool reset) +{ + u32 MAC_backup[MAC_REG_NUM_8822B], BB_backup[BB_REG_NUM_8822B], + RF_backup[RF_REG_NUM_8822B][SS_8822B]; + u32 backup_mac_reg[MAC_REG_NUM_8822B] = {0x520, 0x550}; + u32 backup_bb_reg[BB_REG_NUM_8822B] = { + 0x808, 0x90c, 0xc00, 0xcb0, 0xcb4, 0xcbc, 0xe00, + 0xeb0, 0xeb4, 0xebc, 0x1990, 0x9a4, 0xa04}; + u32 backup_rf_reg[RF_REG_NUM_8822B] = {0xdf, 0x8f, 0x65, 0x0, 0x1}; + bool segment_iqk = false, is_mp = false; + + struct dm_iqk_info *iqk_info = &dm->IQK_info; + + if (dm->mp_mode) + is_mp = true; + else if (dm->is_linked) + segment_iqk = true; + + if (!is_mp) + if (_iqk_reload_iqk_8822b(dm, reset)) + return; + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========IQK strat!!!!!==========\n"); + + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]band_type = %s, band_width = %d, ExtPA2G = %d, ext_pa_5g = %d\n", + (*dm->band_type == ODM_BAND_5G) ? "5G" : "2G", *dm->band_width, + dm->ext_pa, dm->ext_pa_5g); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]Interface = %d, cut_version = %x\n", + dm->support_interface, dm->cut_version); + + iqk_info->iqk_times++; + + iqk_info->kcount = 0; + dm->rf_calibrate_info.iqk_total_progressing_time = 0; + dm->rf_calibrate_info.iqk_step = 1; + iqk_info->rxiqk_step = 1; + + _iqk_backup_iqk_8822b(dm, 0); + _iqk_backup_mac_bb_8822b(dm, MAC_backup, BB_backup, backup_mac_reg, + backup_bb_reg); + _iqk_backup_rf_8822b(dm, RF_backup, backup_rf_reg); + + while (1) { + if (!is_mp) + dm->rf_calibrate_info.iqk_start_time = + odm_get_current_time(dm); + + _iqk_configure_macbb_8822b(dm); + _iqk_afe_setting_8822b(dm, true); + _iqk_rfe_setting_8822b(dm, false); + _iqk_agc_bnd_int_8822b(dm); + _iqk_rf_setting_8822b(dm); + + _iqk_start_iqk_8822b(dm, segment_iqk); + + _iqk_afe_setting_8822b(dm, false); + _iqk_restore_mac_bb_8822b(dm, MAC_backup, BB_backup, + backup_mac_reg, backup_bb_reg); + _iqk_restore_rf_8822b(dm, backup_rf_reg, RF_backup); + + if (!is_mp) { + dm->rf_calibrate_info.iqk_progressing_time = + odm_get_progressing_time( + dm, + dm->rf_calibrate_info.iqk_start_time); + dm->rf_calibrate_info.iqk_total_progressing_time += + odm_get_progressing_time( + dm, + dm->rf_calibrate_info.iqk_start_time); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info.iqk_progressing_time); + } + + if (dm->rf_calibrate_info.iqk_step == 7) + break; + + iqk_info->kcount = 0; + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, "[IQK]delay 50ms!!!\n"); + ODM_delay_ms(50); + }; + + _iqk_backup_iqk_8822b(dm, 1); + _iqk_fill_iqk_report_8822b(dm, 0); + + if (!is_mp) + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]Total IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info.iqk_total_progressing_time); + + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]==========IQK end!!!!!==========\n"); +} + +static void _phy_iq_calibrate_by_fw_8822b(void *dm_void, u8 clear) {} + +/*IQK version:v3.3, NCTL v0.6*/ +/*1.The new gainsearch method for RXIQK*/ +/*2.The new format of IQK report register: 0x1be8/0x1bec*/ +/*3. add the option of segment IQK*/ +void phy_iq_calibrate_8822b(void *dm_void, bool clear) +{ + struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void; + + dm->iqk_fw_offload = 0; + + /*FW IQK*/ + if (dm->iqk_fw_offload) { + if (!dm->rf_calibrate_info.is_iqk_in_progress) { + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = true; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + + dm->rf_calibrate_info.iqk_start_time = + odm_get_current_time(dm); + + odm_write_4byte(dm, 0x1b00, 0xf8000008); + odm_set_bb_reg(dm, 0x1bf0, 0xff000000, 0xff); + ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION, + "[IQK]0x1bf0 = 0x%x\n", + odm_read_4byte(dm, 0x1bf0)); + + _phy_iq_calibrate_by_fw_8822b(dm, clear); + phydm_get_read_counter(dm); + + dm->rf_calibrate_info.iqk_progressing_time = + odm_get_progressing_time( + dm, + dm->rf_calibrate_info.iqk_start_time); + + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info.iqk_progressing_time); + + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = false; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + } else { + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "== Return the IQK CMD, because the IQK in Progress ==\n"); + } + + } else { + _iq_calibrate_8822b_init(dm_void); + + if (!dm->rf_calibrate_info.is_iqk_in_progress) { + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = true; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + if (dm->mp_mode) + dm->rf_calibrate_info.iqk_start_time = + odm_get_current_time(dm); + + _phy_iq_calibrate_8822b(dm, clear); + if (dm->mp_mode) { + dm->rf_calibrate_info.iqk_progressing_time = + odm_get_progressing_time( + dm, dm->rf_calibrate_info + .iqk_start_time); + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]IQK progressing_time = %lld ms\n", + dm->rf_calibrate_info + .iqk_progressing_time); + } + odm_acquire_spin_lock(dm, RT_IQK_SPINLOCK); + dm->rf_calibrate_info.is_iqk_in_progress = false; + odm_release_spin_lock(dm, RT_IQK_SPINLOCK); + } else { + ODM_RT_TRACE( + dm, ODM_COMP_CALIBRATION, + "[IQK]== Return the IQK CMD, because the IQK in Progress ==\n"); + } + } +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h new file mode 100644 index 000000000000..ea19deb512d5 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_iqk_8822b.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __PHYDM_IQK_8822B_H__ +#define __PHYDM_IQK_8822B_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define MAC_REG_NUM_8822B 2 +#define BB_REG_NUM_8822B 13 +#define RF_REG_NUM_8822B 5 + +#define LOK_delay_8822B 2 +#define GS_delay_8822B 2 +#define WBIQK_delay_8822B 2 + +#define TXIQK 0 +#define RXIQK 1 +#define SS_8822B 2 + +/*------------------------End Define Parameters-------------------------------*/ + +void do_iqk_8822b(void *dm_void, u8 delta_thermal_index, u8 thermal_value, + u8 threshold); + +void phy_iq_calibrate_8822b(void *dm_void, bool clear); + +#endif /* #ifndef __PHYDM_IQK_8822B_H__*/ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c new file mode 100644 index 000000000000..644fca822c61 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.c @@ -0,0 +1,168 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +void odm_config_rf_reg_8822b(struct phy_dm_struct *dm, u32 addr, u32 data, + enum odm_rf_radio_path RF_PATH, u32 reg_addr) +{ + if (addr == 0xffe) { + ODM_sleep_ms(50); + } else if (addr == 0xfe) { + ODM_delay_us(100); + } else { + odm_set_rf_reg(dm, RF_PATH, reg_addr, RFREGOFFSETMASK, data); + + /* Add 1us delay between BB/RF register setting. */ + ODM_delay_us(1); + } +} + +void odm_config_rf_radio_a_8822b(struct phy_dm_struct *dm, u32 addr, u32 data) +{ + u32 content = 0x1000; /* RF_Content: radioa_txt */ + u32 maskfor_phy_set = (u32)(content & 0xE000); + + odm_config_rf_reg_8822b(dm, addr, data, ODM_RF_PATH_A, + addr | maskfor_phy_set); + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> odm_config_rf_with_header_file: [RadioA] %08X %08X\n", + addr, data); +} + +void odm_config_rf_radio_b_8822b(struct phy_dm_struct *dm, u32 addr, u32 data) +{ + u32 content = 0x1001; /* RF_Content: radiob_txt */ + u32 maskfor_phy_set = (u32)(content & 0xE000); + + odm_config_rf_reg_8822b(dm, addr, data, ODM_RF_PATH_B, + addr | maskfor_phy_set); + + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> odm_config_rf_with_header_file: [RadioB] %08X %08X\n", + addr, data); +} + +void odm_config_mac_8822b(struct phy_dm_struct *dm, u32 addr, u8 data) +{ + odm_write_1byte(dm, addr, data); + ODM_RT_TRACE( + dm, ODM_COMP_INIT, + "===> odm_config_mac_with_header_file: [MAC_REG] %08X %08X\n", + addr, data); +} + +void odm_update_agc_big_jump_lmt_8822b(struct phy_dm_struct *dm, u32 addr, + u32 data) +{ + struct dig_thres *dig_tab = &dm->dm_dig_table; + u8 rf_gain_idx = (u8)((data & 0xFF000000) >> 24); + u8 bb_gain_idx = (u8)((data & 0x00ff0000) >> 16); + u8 agc_table_idx = (u8)((data & 0x00000f00) >> 8); + static bool is_limit; + + if (addr != 0x81c) + return; + + if (bb_gain_idx > 0x3c) { + if ((rf_gain_idx == dig_tab->rf_gain_idx) && !is_limit) { + is_limit = true; + dig_tab->big_jump_lmt[agc_table_idx] = bb_gain_idx - 2; + ODM_RT_TRACE( + dm, ODM_COMP_DIG, + "===> [AGC_TAB] big_jump_lmt [%d] = 0x%x\n", + agc_table_idx, + dig_tab->big_jump_lmt[agc_table_idx]); + } + } else { + is_limit = false; + } + + dig_tab->rf_gain_idx = rf_gain_idx; +} + +void odm_config_bb_agc_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data) +{ + odm_update_agc_big_jump_lmt_8822b(dm, addr, data); + + odm_set_bb_reg(dm, addr, bitmask, data); + + /* Add 1us delay between BB/RF register setting. */ + ODM_delay_us(1); + + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [AGC_TAB] %08X %08X\n", + __func__, addr, data); +} + +void odm_config_bb_phy_reg_pg_8822b(struct phy_dm_struct *dm, u32 band, + u32 rf_path, u32 tx_num, u32 addr, + u32 bitmask, u32 data) +{ + if (addr == 0xfe || addr == 0xffe) { + ODM_sleep_ms(50); + } else { + phy_store_tx_power_by_rate(dm->adapter, band, rf_path, tx_num, + addr, bitmask, data); + } + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [PHY_REG] %08X %08X %08X\n", + __func__, addr, bitmask, data); +} + +void odm_config_bb_phy_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data) +{ + if (addr == 0xfe) + ODM_sleep_ms(50); + else if (addr == 0xfd) + ODM_delay_ms(5); + else if (addr == 0xfc) + ODM_delay_ms(1); + else if (addr == 0xfb) + ODM_delay_us(50); + else if (addr == 0xfa) + ODM_delay_us(5); + else if (addr == 0xf9) + ODM_delay_us(1); + else + odm_set_bb_reg(dm, addr, bitmask, data); + + /* Add 1us delay between BB/RF register setting. */ + ODM_delay_us(1); + ODM_RT_TRACE(dm, ODM_COMP_INIT, "===> %s: [PHY_REG] %08X %08X\n", + __func__, addr, data); +} + +void odm_config_bb_txpwr_lmt_8822b(struct phy_dm_struct *dm, u8 *regulation, + u8 *band, u8 *bandwidth, u8 *rate_section, + u8 *rf_path, u8 *channel, u8 *power_limit) +{ + phy_set_tx_power_limit(dm, regulation, band, bandwidth, rate_section, + rf_path, channel, power_limit); +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h new file mode 100644 index 000000000000..4817cf6b1ed9 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_regconfig8822b.h @@ -0,0 +1,54 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __INC_ODM_REGCONFIG_H_8822B +#define __INC_ODM_REGCONFIG_H_8822B + +void odm_config_rf_reg_8822b(struct phy_dm_struct *dm, u32 addr, u32 data, + enum odm_rf_radio_path RF_PATH, u32 reg_addr); + +void odm_config_rf_radio_a_8822b(struct phy_dm_struct *dm, u32 addr, u32 data); + +void odm_config_rf_radio_b_8822b(struct phy_dm_struct *dm, u32 addr, u32 data); + +void odm_config_mac_8822b(struct phy_dm_struct *dm, u32 addr, u8 data); + +void odm_update_agc_big_jump_lmt_8822b(struct phy_dm_struct *dm, u32 addr, + u32 data); + +void odm_config_bb_agc_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data); + +void odm_config_bb_phy_reg_pg_8822b(struct phy_dm_struct *dm, u32 band, + u32 rf_path, u32 tx_num, u32 addr, + u32 bitmask, u32 data); + +void odm_config_bb_phy_8822b(struct phy_dm_struct *dm, u32 addr, u32 bitmask, + u32 data); + +void odm_config_bb_txpwr_lmt_8822b(struct phy_dm_struct *dm, u8 *regulation, + u8 *band, u8 *bandwidth, u8 *rate_section, + u8 *rf_path, u8 *channel, u8 *power_limit); + +#endif /* RTL8822B_SUPPORT == 1*/ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c new file mode 100644 index 000000000000..59adabda09de --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.c @@ -0,0 +1,225 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../mp_precomp.h" +#include "../phydm_precomp.h" + +static void phydm_dynamic_switch_htstf_mumimo_8822b(struct phy_dm_struct *dm) +{ + /*if rssi > 40dBm, enable HT-STF gain controller, + *otherwise, if rssi < 40dBm, disable the controller + */ + /*add by Chun-Hung Ho 20160711 */ + if (dm->rssi_min >= 40) + odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x1); + else if (dm->rssi_min < 35) + odm_set_bb_reg(dm, 0x8d8, BIT(17), 0x0); + + ODM_RT_TRACE(dm, ODM_COMP_COMMON, "%s, rssi_min = %d\n", __func__, + dm->rssi_min); +} + +static void _set_tx_a_cali_value(struct phy_dm_struct *dm, u8 rf_path, + u8 offset, u8 tx_a_bias_offset) +{ + u32 modi_tx_a_value = 0; + u8 tmp1_byte = 0; + bool is_minus = false; + u8 comp_value = 0; + + switch (offset) { + case 0x0: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10124); + break; + case 0x1: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10524); + break; + case 0x2: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10924); + break; + case 0x3: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X10D24); + break; + case 0x4: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30164); + break; + case 0x5: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30564); + break; + case 0x6: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30964); + break; + case 0x7: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X30D64); + break; + case 0x8: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50195); + break; + case 0x9: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50595); + break; + case 0xa: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50995); + break; + case 0xb: + odm_set_rf_reg(dm, rf_path, 0x18, 0xFFFFF, 0X50D95); + break; + default: + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "Invalid TxA band offset...\n"); + return; + } + + /* Get TxA value */ + modi_tx_a_value = odm_get_rf_reg(dm, rf_path, 0x61, 0xFFFFF); + tmp1_byte = (u8)modi_tx_a_value & (BIT(3) | BIT(2) | BIT(1) | BIT(0)); + + /* check how much need to calibration */ + switch (tx_a_bias_offset) { + case 0xF6: + is_minus = true; + comp_value = 3; + break; + + case 0xF4: + is_minus = true; + comp_value = 2; + break; + + case 0xF2: + is_minus = true; + comp_value = 1; + break; + + case 0xF3: + is_minus = false; + comp_value = 1; + break; + + case 0xF5: + is_minus = false; + comp_value = 2; + break; + + case 0xF7: + is_minus = false; + comp_value = 3; + break; + + case 0xF9: + is_minus = false; + comp_value = 4; + break; + + /* do nothing case */ + case 0xF0: + default: + ODM_RT_TRACE(dm, ODM_COMP_COMMON, + "No need to do TxA bias current calibration\n"); + return; + } + + /* calc correct value to calibrate */ + if (is_minus) { + if (tmp1_byte >= comp_value) { + tmp1_byte -= comp_value; + /*modi_tx_a_value += tmp1_byte;*/ + } else { + tmp1_byte = 0; + } + } else { + tmp1_byte += comp_value; + if (tmp1_byte >= 7) + tmp1_byte = 7; + } + + /* Write back to RF reg */ + odm_set_rf_reg(dm, rf_path, 0x30, 0xFFFF, + (offset << 12 | (modi_tx_a_value & 0xFF0) | tmp1_byte)); +} + +static void _txa_bias_cali_4_each_path(struct phy_dm_struct *dm, u8 rf_path, + u8 efuse_value) +{ + /* switch on set TxA bias */ + odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x200); + + /* Set 12 sets of TxA value */ + _set_tx_a_cali_value(dm, rf_path, 0x0, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x1, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x2, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x3, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x4, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x5, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x6, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x7, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x8, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0x9, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0xa, efuse_value); + _set_tx_a_cali_value(dm, rf_path, 0xb, efuse_value); + + /* switch off set TxA bias */ + odm_set_rf_reg(dm, rf_path, 0xEF, 0xFFFFF, 0x0); +} + +/* + * for 8822B PCIE D-cut patch only + * Normal driver and MP driver need this patch + */ + +void phydm_txcurrentcalibration(struct phy_dm_struct *dm) +{ + u8 efuse0x3D8, efuse0x3D7; + u32 orig_rf0x18_path_a = 0, orig_rf0x18_path_b = 0; + + /* save original 0x18 value */ + orig_rf0x18_path_a = odm_get_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF); + orig_rf0x18_path_b = odm_get_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF); + + /* define efuse content */ + efuse0x3D8 = dm->efuse0x3d8; + efuse0x3D7 = dm->efuse0x3d7; + + /* check efuse content to judge whether need to calibration or not */ + if (efuse0x3D7 == 0xFF) { + ODM_RT_TRACE( + dm, ODM_COMP_COMMON, + "efuse content 0x3D7 == 0xFF, No need to do TxA cali\n"); + return; + } + + /* write RF register for calibration */ + _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_A, efuse0x3D7); + _txa_bias_cali_4_each_path(dm, ODM_RF_PATH_B, efuse0x3D8); + + /* restore original 0x18 value */ + odm_set_rf_reg(dm, ODM_RF_PATH_A, 0x18, 0xFFFFF, orig_rf0x18_path_a); + odm_set_rf_reg(dm, ODM_RF_PATH_B, 0x18, 0xFFFFF, orig_rf0x18_path_b); +} + +void phydm_hwsetting_8822b(struct phy_dm_struct *dm) +{ + phydm_dynamic_switch_htstf_mumimo_8822b(dm); +} diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h new file mode 100644 index 000000000000..af91a6f958ed --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/phydm_rtl8822b.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __ODM_RTL8822B_H__ +#define __ODM_RTL8822B_H__ + +void phydm_hwsetting_8822b(struct phy_dm_struct *dm); + +#endif /* #define __ODM_RTL8822B_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h b/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h new file mode 100644 index 000000000000..ad0d32fce0a9 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl8822b/version_rtl8822b.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +/*RTL8822B PHY Parameters*/ +/* + * [Caution] + * Since 01/Aug/2015, the commit rules will be simplified. + * You do not need to fill up the version.h anymore, + * only the maintenance supervisor fills it before formal release. + */ +#define RELEASE_DATE_8822B 20161103 +#define COMMIT_BY_8822B "BB_JOE" +#define RELEASE_VERSION_8822B 67 diff --git a/drivers/staging/rtlwifi/phydm/rtl_phydm.c b/drivers/staging/rtlwifi/phydm/rtl_phydm.c new file mode 100644 index 000000000000..85e490d3601f --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl_phydm.c @@ -0,0 +1,874 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#include "mp_precomp.h" +#include "phydm_precomp.h" +#include + +static int _rtl_phydm_init_com_info(struct rtl_priv *rtlpriv, + enum odm_ic_type ic_type, + struct rtl_phydm_params *params) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + u8 odm_board_type = ODM_BOARD_DEFAULT; + u32 support_ability; + int i; + + dm->adapter = (void *)rtlpriv; + + odm_cmn_info_init(dm, ODM_CMNINFO_PLATFORM, ODM_CE); + + odm_cmn_info_init(dm, ODM_CMNINFO_IC_TYPE, ic_type); + + odm_cmn_info_init(dm, ODM_CMNINFO_INTERFACE, ODM_ITRF_PCIE); + + odm_cmn_info_init(dm, ODM_CMNINFO_MP_TEST_CHIP, params->mp_chip); + + odm_cmn_info_init(dm, ODM_CMNINFO_PATCH_ID, rtlhal->oem_id); + + odm_cmn_info_init(dm, ODM_CMNINFO_BWIFI_TEST, 1); + + if (rtlphy->rf_type == RF_1T1R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T1R); + else if (rtlphy->rf_type == RF_1T2R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_1T2R); + else if (rtlphy->rf_type == RF_2T2R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R); + else if (rtlphy->rf_type == RF_2T2R_GREEN) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T2R_GREEN); + else if (rtlphy->rf_type == RF_2T3R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T3R); + else if (rtlphy->rf_type == RF_2T4R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_2T4R); + else if (rtlphy->rf_type == RF_3T3R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T3R); + else if (rtlphy->rf_type == RF_3T4R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_3T4R); + else if (rtlphy->rf_type == RF_4T4R) + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_4T4R); + else + odm_cmn_info_init(dm, ODM_CMNINFO_RF_TYPE, ODM_XTXR); + + /* 1 ======= BoardType: ODM_CMNINFO_BOARD_TYPE ======= */ + if (rtlhal->external_lna_2g != 0) { + odm_board_type |= ODM_BOARD_EXT_LNA; + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_LNA, 1); + } + if (rtlhal->external_lna_5g != 0) { + odm_board_type |= ODM_BOARD_EXT_LNA_5G; + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_LNA, 1); + } + if (rtlhal->external_pa_2g != 0) { + odm_board_type |= ODM_BOARD_EXT_PA; + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_PA, 1); + } + if (rtlhal->external_pa_5g != 0) { + odm_board_type |= ODM_BOARD_EXT_PA_5G; + odm_cmn_info_init(dm, ODM_CMNINFO_5G_EXT_PA, 1); + } + if (rtlpriv->cfg->ops->get_btc_status()) + odm_board_type |= ODM_BOARD_BT; + + odm_cmn_info_init(dm, ODM_CMNINFO_BOARD_TYPE, odm_board_type); + /* 1 ============== End of BoardType ============== */ + + odm_cmn_info_init(dm, ODM_CMNINFO_GPA, rtlhal->type_gpa); + odm_cmn_info_init(dm, ODM_CMNINFO_APA, rtlhal->type_apa); + odm_cmn_info_init(dm, ODM_CMNINFO_GLNA, rtlhal->type_glna); + odm_cmn_info_init(dm, ODM_CMNINFO_ALNA, rtlhal->type_alna); + + odm_cmn_info_init(dm, ODM_CMNINFO_RFE_TYPE, rtlhal->rfe_type); + + odm_cmn_info_init(dm, ODM_CMNINFO_EXT_TRSW, 0); + + /*Add by YuChen for kfree init*/ + odm_cmn_info_init(dm, ODM_CMNINFO_REGRFKFREEENABLE, 2); + odm_cmn_info_init(dm, ODM_CMNINFO_RFKFREEENABLE, 0); + + /*Antenna diversity relative parameters*/ + odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_DIV, + &rtlefuse->antenna_div_cfg); + odm_cmn_info_init(dm, ODM_CMNINFO_RF_ANTENNA_TYPE, + rtlefuse->antenna_div_type); + odm_cmn_info_init(dm, ODM_CMNINFO_BE_FIX_TX_ANT, 0); + odm_cmn_info_init(dm, ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH, 0); + + /* (8822B) efuse 0x3D7 & 0x3D8 for TX PA bias */ + odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D7, params->efuse0x3d7); + odm_cmn_info_init(dm, ODM_CMNINFO_EFUSE0X3D8, params->efuse0x3d8); + + /*Add by YuChen for adaptivity init*/ + odm_cmn_info_hook(dm, ODM_CMNINFO_ADAPTIVITY, + &rtlpriv->phydm.adaptivity_en); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_CARRIER_SENSE_ENABLE, + false); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DCBACKOFF, 0); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_DYNAMICLINKADAPTIVITY, + false); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_L2H_INI, 0); + phydm_adaptivity_info_init(dm, PHYDM_ADAPINFO_TH_EDCCA_HL_DIFF, 0); + + odm_cmn_info_init(dm, ODM_CMNINFO_IQKFWOFFLOAD, 0); + + /* Pointer reference */ + odm_cmn_info_hook(dm, ODM_CMNINFO_TX_UNI, + &rtlpriv->stats.txbytesunicast); + odm_cmn_info_hook(dm, ODM_CMNINFO_RX_UNI, + &rtlpriv->stats.rxbytesunicast); + odm_cmn_info_hook(dm, ODM_CMNINFO_BAND, &rtlhal->current_bandtype); + odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_RATE, + &rtlpriv->phydm.forced_data_rate); + odm_cmn_info_hook(dm, ODM_CMNINFO_FORCED_IGI_LB, + &rtlpriv->phydm.forced_igi_lb); + + odm_cmn_info_hook(dm, ODM_CMNINFO_SEC_CHNL_OFFSET, + &mac->cur_40_prime_sc); + odm_cmn_info_hook(dm, ODM_CMNINFO_BW, &rtlphy->current_chan_bw); + odm_cmn_info_hook(dm, ODM_CMNINFO_CHNL, &rtlphy->current_channel); + + odm_cmn_info_hook(dm, ODM_CMNINFO_SCAN, &mac->act_scanning); + odm_cmn_info_hook(dm, ODM_CMNINFO_POWER_SAVING, + &ppsc->dot11_psmode); /* may add new boolean flag */ + /*Add by Yuchen for phydm beamforming*/ + odm_cmn_info_hook(dm, ODM_CMNINFO_TX_TP, + &rtlpriv->stats.txbytesunicast_inperiod_tp); + odm_cmn_info_hook(dm, ODM_CMNINFO_RX_TP, + &rtlpriv->stats.rxbytesunicast_inperiod_tp); + odm_cmn_info_hook(dm, ODM_CMNINFO_ANT_TEST, + &rtlpriv->phydm.antenna_test); + for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) + odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, i, + NULL); + + phydm_init_debug_setting(dm); + + odm_cmn_info_init(dm, ODM_CMNINFO_FAB_VER, params->fab_ver); + odm_cmn_info_init(dm, ODM_CMNINFO_CUT_VER, params->cut_ver); + + /* after ifup, ability is updated again */ + support_ability = ODM_RF_CALIBRATION | ODM_RF_TX_PWR_TRACK; + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, support_ability); + + return 0; +} + +static int rtl_phydm_init_priv(struct rtl_priv *rtlpriv, + struct rtl_phydm_params *params) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_ic_type ic; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + ic = ODM_RTL8822B; + else + return 0; + + rtlpriv->phydm.internal = + kzalloc(sizeof(struct phy_dm_struct), GFP_KERNEL); + + _rtl_phydm_init_com_info(rtlpriv, ic, params); + + odm_init_all_timers(dm); + + return 1; +} + +static int rtl_phydm_deinit_priv(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + odm_cancel_all_timers(dm); + + kfree(rtlpriv->phydm.internal); + rtlpriv->phydm.internal = NULL; + + return 0; +} + +static bool rtl_phydm_load_txpower_by_rate(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + status = odm_config_bb_with_header_file(dm, CONFIG_BB_PHY_REG_PG); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_load_txpower_limit(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) { + odm_read_and_config_mp_8822b_txpwr_lmt(dm); + } else { + status = odm_config_rf_with_header_file(dm, CONFIG_RF_TXPWR_LMT, + 0); + if (status != HAL_STATUS_SUCCESS) + return false; + } + + return true; +} + +static int rtl_phydm_init_dm(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + u32 support_ability = 0; + + /* clang-format off */ + support_ability = 0 + | ODM_BB_DIG + | ODM_BB_RA_MASK + | ODM_BB_DYNAMIC_TXPWR + | ODM_BB_FA_CNT + | ODM_BB_RSSI_MONITOR + | ODM_BB_CCK_PD + /* | ODM_BB_PWR_SAVE*/ + | ODM_BB_CFO_TRACKING + | ODM_MAC_EDCA_TURBO + | ODM_RF_TX_PWR_TRACK + | ODM_RF_CALIBRATION + | ODM_BB_NHM_CNT + /* | ODM_BB_PWR_TRAIN*/ + ; + /* clang-format on */ + + odm_cmn_info_update(dm, ODM_CMNINFO_ABILITY, support_ability); + + odm_dm_init(dm); + + return 0; +} + +static int rtl_phydm_deinit_dm(struct rtl_priv *rtlpriv) +{ + return 0; +} + +static int rtl_phydm_reset_dm(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + odm_dm_reset(dm); + + return 0; +} + +static bool rtl_phydm_parameter_init(struct rtl_priv *rtlpriv, bool post) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_parameter_init(dm, post ? ODM_POST_SETTING : + ODM_PRE_SETTING); + + return false; +} + +static bool rtl_phydm_phy_bb_config(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + status = odm_config_bb_with_header_file(dm, CONFIG_BB_PHY_REG); + if (status != HAL_STATUS_SUCCESS) + return false; + + status = odm_config_bb_with_header_file(dm, CONFIG_BB_AGC_TAB); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_phy_rf_config(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + enum hal_status status; + enum odm_rf_radio_path rfpath; + + for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { + status = odm_config_rf_with_header_file(dm, CONFIG_RF_RADIO, + rfpath); + if (status != HAL_STATUS_SUCCESS) + return false; + } + + status = odm_config_rf_with_tx_pwr_track_header_file(dm); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_phy_mac_config(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum hal_status status; + + status = odm_config_mac_with_header_file(dm); + if (status != HAL_STATUS_SUCCESS) + return false; + + return true; +} + +static bool rtl_phydm_trx_mode(struct rtl_priv *rtlpriv, + enum radio_mask tx_path, enum radio_mask rx_path, + bool is_tx2_path) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_trx_mode_8822b(dm, + (enum odm_rf_path)tx_path, + (enum odm_rf_path)rx_path, + is_tx2_path); + + return false; +} + +static bool rtl_phydm_watchdog(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); + bool fw_current_inpsmode = false; + bool fw_ps_awake = true; + u8 is_linked = false; + u8 bsta_state = false; + u8 is_bt_enabled = false; + + /* check whether do watchdog */ + rtlpriv->cfg->ops->get_hw_reg(rtlpriv->hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inpsmode)); + rtlpriv->cfg->ops->get_hw_reg(rtlpriv->hw, HW_VAR_FWLPS_RF_ON, + (u8 *)(&fw_ps_awake)); + if (ppsc->p2p_ps_info.p2p_ps_mode) + fw_ps_awake = false; + + if ((ppsc->rfpwr_state == ERFON) && + ((!fw_current_inpsmode) && fw_ps_awake) && + (!ppsc->rfchange_inprogress)) + ; + else + return false; + + /* update common info before doing watchdog */ + if (mac->link_state >= MAC80211_LINKED) { + is_linked = true; + if (mac->vif && mac->vif->type == NL80211_IFTYPE_STATION) + bsta_state = true; + } + + if (rtlpriv->cfg->ops->get_btc_status()) + is_bt_enabled = !rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled( + rtlpriv); + + odm_cmn_info_update(dm, ODM_CMNINFO_LINK, is_linked); + odm_cmn_info_update(dm, ODM_CMNINFO_STATION_STATE, bsta_state); + odm_cmn_info_update(dm, ODM_CMNINFO_BT_ENABLED, is_bt_enabled); + + /* do watchdog */ + odm_dm_watchdog(dm); + + return true; +} + +static bool rtl_phydm_switch_band(struct rtl_priv *rtlpriv, u8 central_ch) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_switch_band_8822b(dm, central_ch); + + return false; +} + +static bool rtl_phydm_switch_channel(struct rtl_priv *rtlpriv, u8 central_ch) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_switch_channel_8822b(dm, central_ch); + + return false; +} + +static bool rtl_phydm_switch_bandwidth(struct rtl_priv *rtlpriv, + u8 primary_ch_idx, + enum ht_channel_width bandwidth) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_bw odm_bw = (enum odm_bw)bandwidth; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_switch_bandwidth_8822b(dm, primary_ch_idx, + odm_bw); + + return false; +} + +static bool rtl_phydm_iq_calibrate(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + phy_iq_calibrate_8822b(dm, false); + else + return false; + + return true; +} + +static bool rtl_phydm_clear_txpowertracking_state(struct rtl_priv *rtlpriv) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + odm_clear_txpowertracking_state(dm); + + return true; +} + +static bool rtl_phydm_pause_dig(struct rtl_priv *rtlpriv, bool pause) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (pause) + odm_pause_dig(dm, PHYDM_PAUSE, PHYDM_PAUSE_LEVEL_0, 0x1e); + else /* resume */ + odm_pause_dig(dm, PHYDM_RESUME, PHYDM_PAUSE_LEVEL_0, 0xff); + + return true; +} + +static u32 rtl_phydm_read_rf_reg(struct rtl_priv *rtlpriv, + enum radio_path rfpath, u32 addr, u32 mask) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_read_rf_reg_8822b(dm, odm_rfpath, addr, + mask); + + return -1; +} + +static bool rtl_phydm_write_rf_reg(struct rtl_priv *rtlpriv, + enum radio_path rfpath, u32 addr, u32 mask, + u32 data) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_write_rf_reg_8822b(dm, odm_rfpath, addr, + mask, data); + + return false; +} + +static u8 rtl_phydm_read_txagc(struct rtl_priv *rtlpriv, enum radio_path rfpath, + u8 hw_rate) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_read_txagc_8822b(dm, odm_rfpath, hw_rate); + + return -1; +} + +static bool rtl_phydm_write_txagc(struct rtl_priv *rtlpriv, u32 power_index, + enum radio_path rfpath, u8 hw_rate) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + enum odm_rf_radio_path odm_rfpath = (enum odm_rf_radio_path)rfpath; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + return config_phydm_write_txagc_8822b(dm, power_index, + odm_rfpath, hw_rate); + + return false; +} + +static bool rtl_phydm_c2h_content_parsing(struct rtl_priv *rtlpriv, u8 cmd_id, + u8 cmd_len, u8 *content) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + if (phydm_c2H_content_parsing(dm, cmd_id, cmd_len, content)) + return true; + + return false; +} + +static bool rtl_phydm_query_phy_status(struct rtl_priv *rtlpriv, u8 *phystrpt, + struct ieee80211_hdr *hdr, + struct rtl_stats *pstatus) +{ + /* NOTE: phystrpt may be NULL, and need to fill default value */ + + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct dm_per_pkt_info pktinfo; /* input of pydm */ + struct dm_phy_status_info phy_info; /* output of phydm */ + __le16 fc = hdr->frame_control; + + /* fill driver pstatus */ + ether_addr_copy(pstatus->psaddr, ieee80211_get_SA(hdr)); + + /* fill pktinfo */ + memset(&pktinfo, 0, sizeof(pktinfo)); + + pktinfo.data_rate = pstatus->rate; + + if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION) { + pktinfo.station_id = 0; + } else { + /* TODO: use rtl_find_sta() to find ID */ + pktinfo.station_id = 0xFF; + } + + pktinfo.is_packet_match_bssid = + (!ieee80211_is_ctl(fc) && + (ether_addr_equal(mac->bssid, + ieee80211_has_tods(fc) ? + hdr->addr1 : + ieee80211_has_fromds(fc) ? + hdr->addr2 : + hdr->addr3)) && + (!pstatus->hwerror) && (!pstatus->crc) && (!pstatus->icv)); + pktinfo.is_packet_to_self = + pktinfo.is_packet_match_bssid && + (ether_addr_equal(hdr->addr1, rtlefuse->dev_addr)); + pktinfo.is_to_self = (!pstatus->icv) && (!pstatus->crc) && + (ether_addr_equal(hdr->addr1, rtlefuse->dev_addr)); + pktinfo.is_packet_beacon = (ieee80211_is_beacon(fc) ? true : false); + + /* query phy status */ + if (phystrpt) + odm_phy_status_query(dm, &phy_info, phystrpt, &pktinfo); + else + memset(&phy_info, 0, sizeof(phy_info)); + + /* copy phy_info from phydm to driver */ + pstatus->rx_pwdb_all = phy_info.rx_pwdb_all; + pstatus->bt_rx_rssi_percentage = phy_info.bt_rx_rssi_percentage; + pstatus->recvsignalpower = phy_info.recv_signal_power; + pstatus->signalquality = phy_info.signal_quality; + pstatus->rx_mimo_signalquality[0] = phy_info.rx_mimo_signal_quality[0]; + pstatus->rx_mimo_signalquality[1] = phy_info.rx_mimo_signal_quality[1]; + pstatus->rx_packet_bw = + phy_info.band_width; /* HT_CHANNEL_WIDTH_20 <- ODM_BW20M */ + + /* fill driver pstatus */ + pstatus->packet_matchbssid = pktinfo.is_packet_match_bssid; + pstatus->packet_toself = pktinfo.is_packet_to_self; + pstatus->packet_beacon = pktinfo.is_packet_beacon; + + return true; +} + +static u8 rtl_phydm_rate_id_mapping(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + return phydm_rate_id_mapping(dm, wireless_mode, rf_type, bw); +} + +static bool rtl_phydm_get_ra_bitmap(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw, + u8 tx_rate_level, /* 0~6 */ + u32 *tx_bitmap_msb, + u32 *tx_bitmap_lsb) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + const u8 mimo_ps_enable = 0; + const u8 disable_cck_rate = 0; + + phydm_update_hal_ra_mask(dm, wireless_mode, rf_type, bw, mimo_ps_enable, + disable_cck_rate, tx_bitmap_msb, tx_bitmap_lsb, + tx_rate_level); + + return true; +} + +static u8 _rtl_phydm_get_macid(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + return 0; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + return sta->aid + 1; + + return 0; +} + +static bool rtl_phydm_add_sta(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + struct rtl_sta_info *sta_entry = (struct rtl_sta_info *)sta->drv_priv; + u8 mac_id = _rtl_phydm_get_macid(rtlpriv, sta); + + odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, mac_id, + sta_entry); + + return true; +} + +static bool rtl_phydm_del_sta(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + u8 mac_id = _rtl_phydm_get_macid(rtlpriv, sta); + + odm_cmn_info_ptr_array_hook(dm, ODM_CMNINFO_STA_STATUS, mac_id, NULL); + + return true; +} + +static u32 rtl_phydm_get_version(struct rtl_priv *rtlpriv) +{ + u32 ver = 0; + + if (IS_HARDWARE_TYPE_8822B(rtlpriv)) + ver = RELEASE_VERSION_8822B; + + return ver; +} + +static bool rtl_phydm_modify_ra_pcr_threshold(struct rtl_priv *rtlpriv, + u8 ra_offset_direction, + u8 ra_threshold_offset) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + phydm_modify_RA_PCR_threshold(dm, ra_offset_direction, + ra_threshold_offset); + + return true; +} + +static u32 rtl_phydm_query_counter(struct rtl_priv *rtlpriv, + const char *info_type) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + static const struct query_entry { + const char *query_name; + enum phydm_info_query query_id; + } query_table[] = { +#define QUERY_ENTRY(name) {#name, name} + QUERY_ENTRY(PHYDM_INFO_FA_OFDM), + QUERY_ENTRY(PHYDM_INFO_FA_CCK), + QUERY_ENTRY(PHYDM_INFO_CCA_OFDM), + QUERY_ENTRY(PHYDM_INFO_CCA_CCK), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_CCK), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_LEGACY), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_HT), + QUERY_ENTRY(PHYDM_INFO_CRC32_OK_VHT), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_CCK), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_LEGACY), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_HT), + QUERY_ENTRY(PHYDM_INFO_CRC32_ERROR_VHT), + }; +#define QUERY_TABLE_SIZE ARRAY_SIZE(query_table) + + int i; + const struct query_entry *entry; + + if (!strcmp(info_type, "IQK_TOTAL")) + return dm->n_iqk_cnt; + + if (!strcmp(info_type, "IQK_OK")) + return dm->n_iqk_ok_cnt; + + if (!strcmp(info_type, "IQK_FAIL")) + return dm->n_iqk_fail_cnt; + + for (i = 0; i < QUERY_TABLE_SIZE; i++) { + entry = &query_table[i]; + + if (!strcmp(info_type, entry->query_name)) + return phydm_cmn_info_query(dm, entry->query_id); + } + + pr_err("Unrecognized info_type:%s!!!!:\n", info_type); + + return 0xDEADDEAD; +} + +static bool rtl_phydm_debug_cmd(struct rtl_priv *rtlpriv, char *in, u32 in_len, + char *out, u32 out_len) +{ + struct phy_dm_struct *dm = rtlpriv_to_phydm(rtlpriv); + + phydm_cmd(dm, in, in_len, 1, out, out_len); + + return true; +} + +static struct rtl_phydm_ops rtl_phydm_operation = { + /* init/deinit priv */ + .phydm_init_priv = rtl_phydm_init_priv, + .phydm_deinit_priv = rtl_phydm_deinit_priv, + .phydm_load_txpower_by_rate = rtl_phydm_load_txpower_by_rate, + .phydm_load_txpower_limit = rtl_phydm_load_txpower_limit, + + /* init hw */ + .phydm_init_dm = rtl_phydm_init_dm, + .phydm_deinit_dm = rtl_phydm_deinit_dm, + .phydm_reset_dm = rtl_phydm_reset_dm, + .phydm_parameter_init = rtl_phydm_parameter_init, + .phydm_phy_bb_config = rtl_phydm_phy_bb_config, + .phydm_phy_rf_config = rtl_phydm_phy_rf_config, + .phydm_phy_mac_config = rtl_phydm_phy_mac_config, + .phydm_trx_mode = rtl_phydm_trx_mode, + + /* watchdog */ + .phydm_watchdog = rtl_phydm_watchdog, + + /* channel */ + .phydm_switch_band = rtl_phydm_switch_band, + .phydm_switch_channel = rtl_phydm_switch_channel, + .phydm_switch_bandwidth = rtl_phydm_switch_bandwidth, + .phydm_iq_calibrate = rtl_phydm_iq_calibrate, + .phydm_clear_txpowertracking_state = + rtl_phydm_clear_txpowertracking_state, + .phydm_pause_dig = rtl_phydm_pause_dig, + + /* read/write reg */ + .phydm_read_rf_reg = rtl_phydm_read_rf_reg, + .phydm_write_rf_reg = rtl_phydm_write_rf_reg, + .phydm_read_txagc = rtl_phydm_read_txagc, + .phydm_write_txagc = rtl_phydm_write_txagc, + + /* RX */ + .phydm_c2h_content_parsing = rtl_phydm_c2h_content_parsing, + .phydm_query_phy_status = rtl_phydm_query_phy_status, + + /* TX */ + .phydm_rate_id_mapping = rtl_phydm_rate_id_mapping, + .phydm_get_ra_bitmap = rtl_phydm_get_ra_bitmap, + + /* STA */ + .phydm_add_sta = rtl_phydm_add_sta, + .phydm_del_sta = rtl_phydm_del_sta, + + /* BTC */ + .phydm_get_version = rtl_phydm_get_version, + .phydm_modify_ra_pcr_threshold = rtl_phydm_modify_ra_pcr_threshold, + .phydm_query_counter = rtl_phydm_query_counter, + + /* debug */ + .phydm_debug_cmd = rtl_phydm_debug_cmd, +}; + +struct rtl_phydm_ops *rtl_phydm_get_ops_pointer(void) +{ + return &rtl_phydm_operation; +} +EXPORT_SYMBOL(rtl_phydm_get_ops_pointer); + +/* ******************************************************** + * Define phydm callout function in below + * ******************************************************** + */ + +u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate, + enum ht_channel_width bandwidth, u8 channel) +{ + /* rate: DESC_RATE1M */ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + + return rtlpriv->cfg->ops->get_txpower_index(rtlpriv->hw, rf_path, rate, + bandwidth, channel); +} + +void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + + return rtlpriv->cfg->ops->set_tx_power_index_by_rs(rtlpriv->hw, ch, + path, rs); +} + +void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + + rtlpriv->cfg->ops->store_tx_power_by_rate( + rtlpriv->hw, band, rfpath, txnum, regaddr, bitmask, data); +} + +void phy_set_tx_power_limit(void *dm, u8 *regulation, u8 *band, u8 *bandwidth, + u8 *rate_section, u8 *rf_path, u8 *channel, + u8 *power_limit) +{ + struct rtl_priv *rtlpriv = + (struct rtl_priv *)((struct phy_dm_struct *)dm)->adapter; + + rtlpriv->cfg->ops->phy_set_txpower_limit(rtlpriv->hw, regulation, band, + bandwidth, rate_section, + rf_path, channel, power_limit); +} + +void rtl_hal_update_ra_mask(void *adapter, struct rtl_sta_info *psta, + u8 rssi_level) +{ + struct rtl_priv *rtlpriv = (struct rtl_priv *)adapter; + struct ieee80211_sta *sta = + container_of((void *)psta, struct ieee80211_sta, drv_priv); + + rtlpriv->cfg->ops->update_rate_tbl(rtlpriv->hw, sta, rssi_level, false); +} + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); diff --git a/drivers/staging/rtlwifi/phydm/rtl_phydm.h b/drivers/staging/rtlwifi/phydm/rtl_phydm.h new file mode 100644 index 000000000000..483d2418699b --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/rtl_phydm.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __RTL_PHYDM_H__ +#define __RTL_PHYDM_H__ + +struct rtl_phydm_ops *rtl_phydm_get_ops_pointer(void); + +#define rtlpriv_to_phydm(priv) \ + ((struct phy_dm_struct *)((priv)->phydm.internal)) + +u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate, + enum ht_channel_width bandwidth, u8 channel); +void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs); +void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum, + u32 regaddr, u32 bitmask, u32 data); +void phy_set_tx_power_limit(void *dm, u8 *regulation, u8 *band, u8 *bandwidth, + u8 *rate_section, u8 *rf_path, u8 *channel, + u8 *power_limit); + +void rtl_hal_update_ra_mask(void *adapter, struct rtl_sta_info *psta, + u8 rssi_level); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h b/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h new file mode 100644 index 000000000000..6cacca12d792 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/halcomtxbf.h @@ -0,0 +1,67 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_COM_TXBF_H__ +#define __HAL_COM_TXBF_H__ + +enum txbf_set_type { + TXBF_SET_SOUNDING_ENTER, + TXBF_SET_SOUNDING_LEAVE, + TXBF_SET_SOUNDING_RATE, + TXBF_SET_SOUNDING_STATUS, + TXBF_SET_SOUNDING_FW_NDPA, + TXBF_SET_SOUNDING_CLK, + TXBF_SET_TX_PATH_RESET, + TXBF_SET_GET_TX_RATE +}; + +enum txbf_get_type { + TXBF_GET_EXPLICIT_BEAMFORMEE, + TXBF_GET_EXPLICIT_BEAMFORMER, + TXBF_GET_MU_MIMO_STA, + TXBF_GET_MU_MIMO_AP +}; + +/* 2 HAL TXBF related */ +struct _HAL_TXBF_INFO { + u8 txbf_idx; + u8 ndpa_idx; + u8 BW; + u8 rate; + + struct timer_list txbf_fw_ndpa_timer; +}; + +#define hal_com_txbf_beamform_init(dm_void) NULL +#define hal_com_txbf_config_gtab(dm_void) NULL +#define hal_com_txbf_enter_work_item_callback(_adapter) NULL +#define hal_com_txbf_leave_work_item_callback(_adapter) NULL +#define hal_com_txbf_fw_ndpa_work_item_callback(_adapter) NULL +#define hal_com_txbf_clk_work_item_callback(_adapter) NULL +#define hal_com_txbf_rate_work_item_callback(_adapter) NULL +#define hal_com_txbf_fw_ndpa_timer_callback(_adapter) NULL +#define hal_com_txbf_status_work_item_callback(_adapter) NULL +#define hal_com_txbf_get(_adapter, _get_type, _pout_buf) + +#endif /* #ifndef __HAL_COM_TXBF_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h new file mode 100644 index 000000000000..5c92c4326f7e --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbf8822b.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_TXBF_8822B_H__ +#define __HAL_TXBF_8822B_H__ + +#define hal_txbf_8822b_enter(dm_void, idx) +#define hal_txbf_8822b_leave(dm_void, idx) +#define hal_txbf_8822b_status(dm_void, idx) +#define hal_txbf_8822b_fw_txbf(dm_void, idx) +#define hal_txbf_8822b_config_gtab(dm_void) + +void phydm_8822btxbf_rfmode(void *dm_void, u8 su_bfee_cnt, u8 mu_bfee_cnt); + +void phydm_8822b_sutxbfer_workaroud(void *dm_void, bool enable_su_bfer, u8 nc, + u8 nr, u8 ng, u8 CB, u8 BW, bool is_vht); + +#endif diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h new file mode 100644 index 000000000000..82aeac1ff3e0 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbfinterface.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_TXBF_INTERFACE_H__ +#define __HAL_TXBF_INTERFACE_H__ + +#define beamforming_get_ndpa_frame(dm, _pdu_os) +#define beamforming_get_report_frame(adapter, precv_frame) RT_STATUS_FAILURE +#define send_fw_ht_ndpa_packet(dm_void, RA, BW) +#define send_sw_ht_ndpa_packet(dm_void, RA, BW) +#define send_fw_vht_ndpa_packet(dm_void, RA, AID, BW) +#define send_sw_vht_ndpa_packet(dm_void, RA, AID, BW) +#define send_sw_vht_gid_mgnt_frame(dm_void, RA, idx) +#define send_sw_vht_bf_report_poll(dm_void, RA, is_final_poll) +#define send_sw_vht_mu_ndpa_packet(dm_void, BW) + +#endif diff --git a/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h b/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h new file mode 100644 index 000000000000..c5ddd9cb9cd5 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/haltxbfjaguar.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __HAL_TXBF_JAGUAR_H__ +#define __HAL_TXBF_JAGUAR_H__ + +#define hal_txbf_8812a_set_ndpa_rate(dm_void, BW, rate) +#define hal_txbf_jaguar_enter(dm_void, idx) +#define hal_txbf_jaguar_leave(dm_void, idx) +#define hal_txbf_jaguar_status(dm_void, idx) +#define hal_txbf_jaguar_fw_txbf(dm_void, idx) +#define hal_txbf_jaguar_patch(dm_void, operation) +#define hal_txbf_jaguar_clk_8812a(dm_void) + +#endif /* #ifndef __HAL_TXBF_JAGUAR_H__ */ diff --git a/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h b/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h new file mode 100644 index 000000000000..41358fce2875 --- /dev/null +++ b/drivers/staging/rtlwifi/phydm/txbf/phydm_hal_txbf_api.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#ifndef __PHYDM_HAL_TXBF_API_H__ +#define __PHYDM_HAL_TXBF_API_H__ + +#define tx_bf_nr(a, b) ((a > b) ? (b) : (a)) + +u8 beamforming_get_htndp_tx_rate(void *dm_void, u8 comp_steering_num_of_bfer); + +u8 beamforming_get_vht_ndp_tx_rate(void *dm_void, u8 comp_steering_num_of_bfer); + +u8 phydm_get_beamforming_sounding_info(void *dm_void, u16 *troughput, + u8 total_bfee_num, u8 *tx_rate); + +u8 phydm_get_ndpa_rate(void *dm_void); + +u8 phydm_get_mu_bfee_snding_decision(void *dm_void, u16 throughput); + +#endif diff --git a/drivers/staging/rtlwifi/ps.c b/drivers/staging/rtlwifi/ps.c new file mode 100644 index 000000000000..9172cee45f74 --- /dev/null +++ b/drivers/staging/rtlwifi/ps.c @@ -0,0 +1,1007 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "base.h" +#include "ps.h" +#include +#include "btcoexist/rtl_btc.h" + +bool rtl_ps_enable_nic(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); + + /*<1> reset trx ring */ + if (rtlhal->interface == INTF_PCI) + rtlpriv->intf_ops->reset_trx_ring(hw); + + if (is_hal_stop(rtlhal)) + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Driver is already down!\n"); + + /*<2> Enable Adapter */ + if (rtlpriv->cfg->ops->hw_init(hw)) + return false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, + &rtlmac->retry_long); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + /*<2.1> Switch Channel & Bandwidth to last rtl_op_config setting*/ + rtlpriv->cfg->ops->switch_channel(hw); + rtlpriv->cfg->ops->set_channel_access(hw); + rtlpriv->cfg->ops->set_bw_mode(hw, + cfg80211_get_chandef_type(&hw->conf.chandef)); + + /*<3> Enable Interrupt */ + rtlpriv->cfg->ops->enable_interrupt(hw); + + /* */ + rtl_watch_dog_timer_callback((unsigned long)hw); + + return true; +} + +bool rtl_ps_disable_nic(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /*<1> Stop all timer */ + rtl_deinit_deferred_work(hw); + + /*<2> Disable Interrupt */ + rtlpriv->cfg->ops->disable_interrupt(hw); + tasklet_kill(&rtlpriv->works.irq_tasklet); + + /*<3> Disable Adapter */ + rtlpriv->cfg->ops->hw_disable(hw); + + return true; +} + +static bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, + enum rf_pwrstate state_toset, + u32 changesource) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + bool actionallowed = false; + u16 rfwait_cnt = 0; + + /*Only one thread can change + *the RF state at one time, and others + *should wait to be executed. + */ + while (true) { + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (ppsc->rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "RF Change in progress! Wait to set..state_toset(%d).\n", + state_toset); + + /* Set RF after the previous action is done. */ + while (ppsc->rfchange_inprogress) { + rfwait_cnt++; + mdelay(1); + /*Wait too long, return false to avoid + *to be stuck here. + */ + if (rfwait_cnt > 100) + return false; + } + } else { + ppsc->rfchange_inprogress = true; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + break; + } + } + + rtstate = ppsc->rfpwr_state; + + switch (state_toset) { + case ERFON: + ppsc->rfoff_reason &= (~changesource); + + if ((changesource == RF_CHANGE_BY_HW) && + (ppsc->hwradiooff)) { + ppsc->hwradiooff = false; + } + + if (!ppsc->rfoff_reason) { + ppsc->rfoff_reason = 0; + actionallowed = true; + } + break; + case ERFOFF: + if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff) + ppsc->hwradiooff = true; + + ppsc->rfoff_reason |= changesource; + actionallowed = true; + break; + case ERFSLEEP: + ppsc->rfoff_reason |= changesource; + actionallowed = true; + break; + default: + pr_err("switch case %#x not processed\n", state_toset); + break; + } + + if (actionallowed) + rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); + + spin_lock(&rtlpriv->locks.rf_ps_lock); + ppsc->rfchange_inprogress = false; + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + return actionallowed; +} + +static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + ppsc->swrf_processing = true; + + if (ppsc->inactive_pwrstate == ERFON && + rtlhal->interface == INTF_PCI) { + if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && + rtlhal->interface == INTF_PCI) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + } + + rtl_ps_set_rf_state(hw, ppsc->inactive_pwrstate, + RF_CHANGE_BY_IPS); + + if (ppsc->inactive_pwrstate == ERFOFF && + rtlhal->interface == INTF_PCI) { + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && + !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + } + + ppsc->swrf_processing = false; +} + +void rtl_ips_nic_off_wq_callback(void *data) +{ + struct rtl_works *rtlworks = + container_of_dwork_rtl(data, struct rtl_works, ips_nic_off_wq); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + if (mac->opmode != NL80211_IFTYPE_STATION) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "not station return\n"); + return; + } + + if (mac->p2p_in_use) + return; + + if (mac->link_state > MAC80211_NOLINK) + return; + + if (is_hal_stop(rtlhal)) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (rtlpriv->cfg->ops->bt_coex_off_before_lps) + rtlpriv->cfg->ops->bt_coex_off_before_lps(hw); + + if (ppsc->inactiveps) { + rtstate = ppsc->rfpwr_state; + + /* + *Do not enter IPS in the following conditions: + *(1) RF is already OFF or Sleep + *(2) swrf_processing (indicates the IPS is still under going) + *(3) Connectted (only disconnected can trigger IPS) + *(4) IBSS (send Beacon) + *(5) AP mode (send Beacon) + *(6) monitor mode (rcv packet) + */ + + if (rtstate == ERFON && + !ppsc->swrf_processing && + (mac->link_state == MAC80211_NOLINK) && + !mac->act_scanning) { + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "IPSEnter(): Turn off RF\n"); + + ppsc->inactive_pwrstate = ERFOFF; + ppsc->in_powersavemode = true; + + /* call before RF off */ + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, + ppsc->inactive_pwrstate); + + /*rtl_pci_reset_trx_ring(hw); */ + _rtl_ps_inactive_ps(hw); + } + } +} + +void rtl_ips_nic_off(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* because when link with ap, mac80211 will ask us + * to disable nic quickly after scan before linking, + * this will cause link failed, so we delay 100ms here + */ + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ips_nic_off_wq, MSECS(100)); +} + +/* NOTICE: any opmode should exc nic_on, or disable without + * nic_on may something wrong, like adhoc TP + */ +void rtl_ips_nic_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + enum rf_pwrstate rtstate; + + cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq); + + mutex_lock(&rtlpriv->locks.ips_mutex); + if (ppsc->inactiveps) { + rtstate = ppsc->rfpwr_state; + + if (rtstate != ERFON && + !ppsc->swrf_processing && + ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { + ppsc->inactive_pwrstate = ERFON; + ppsc->in_powersavemode = false; + _rtl_ps_inactive_ps(hw); + /* call after RF on */ + if (rtlpriv->phydm.ops) + rtlpriv->phydm.ops->phydm_reset_dm(rtlpriv); + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_ips_notify(rtlpriv, + ppsc->inactive_pwrstate); + } + } + mutex_unlock(&rtlpriv->locks.ips_mutex); +} + +/*for FW LPS*/ + +/* + *Determine if we can set Fw into PS mode + *in current condition.Return TRUE if it + *can enter PS mode. + */ +static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u32 ps_timediff; + + ps_timediff = jiffies_to_msecs(jiffies - + ppsc->last_delaylps_stamp_jiffies); + + if (ps_timediff < 2000) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); + return false; + } + + if (mac->link_state != MAC80211_LINKED) + return false; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return false; + + return true; +} + +/* Change current and default preamble mode.*/ +void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool enter_fwlps; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + if (ppsc->dot11_psmode == rt_psmode && rt_psmode == EACTIVE) + return; + + /* Update power save mode configured. */ + ppsc->dot11_psmode = rt_psmode; + + /* + * + *1. Enter PS mode + * Set RPWM to Fw to turn RF off and send H2C fw_pwrmode + * cmd to set Fw into PS mode. + *2. Leave PS mode + * Send H2C fw_pwrmode cmd to Fw to set Fw into Active + * mode and set RPWM to turn RF on. + */ + + if ((ppsc->fwctrl_lps) && ppsc->report_linked) { + if (ppsc->dot11_psmode == EACTIVE) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); + enter_fwlps = false; + ppsc->pwr_mode = FW_PS_ACTIVE_MODE; + ppsc->smart_ps = 0; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_LPS_ACTION, + (u8 *)(&enter_fwlps)); + if (ppsc->p2p_ps_info.opp_ps) + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); + } else { + if (rtl_get_fwlps_doze(hw)) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); + enter_fwlps = true; + ppsc->pwr_mode = ppsc->fwctrl_psmode; + ppsc->smart_ps = 2; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_FW_LPS_ACTION, + (u8 *)(&enter_fwlps)); + + } else { + /* Reset the power save related parameters. */ + ppsc->dot11_psmode = EACTIVE; + } + } + } +} + +/* Interrupt safe routine to enter the leisure power save mode.*/ +static void rtl_lps_enter_core(struct ieee80211_hw *hw) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!ppsc->fwctrl_lps) + return; + + if (rtlpriv->sec.being_setkey) + return; + + if (rtlpriv->link_info.busytraffic) + return; + + /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ + if (mac->cnt_after_linked < 5) + return; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + return; + + if (mac->link_state != MAC80211_LINKED) + return; + + mutex_lock(&rtlpriv->locks.lps_mutex); + + /* Don't need to check (ppsc->dot11_psmode == EACTIVE), because + * bt_ccoexist may ask to enter lps. + * In normal case, this constraint move to rtl_lps_set_psmode(). + */ + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Enter 802.11 power save mode...\n"); + rtl_lps_set_psmode(hw, EAUTOPS); + + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +/* Interrupt safe routine to leave the leisure power save mode.*/ +static void rtl_lps_leave_core(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + mutex_lock(&rtlpriv->locks.lps_mutex); + + if (ppsc->fwctrl_lps) { + if (ppsc->dot11_psmode != EACTIVE) { + /*FIX ME */ + /*rtlpriv->cfg->ops->enable_interrupt(hw); */ + + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && + rtlhal->interface == INTF_PCI) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Busy Traffic,Leave 802.11 power save..\n"); + + rtl_lps_set_psmode(hw, EACTIVE); + } + } + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +/* For sw LPS*/ +void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = data; + struct ieee80211_tim_ie *tim_ie; + u8 *tim; + u8 tim_len; + bool u_buffed; + bool m_buffed; + + if (mac->opmode != NL80211_IFTYPE_STATION) + return; + + if (!rtlpriv->psc.swctrl_lps) + return; + + if (rtlpriv->mac80211.link_state != MAC80211_LINKED) + return; + + if (!rtlpriv->psc.sw_ps_enabled) + return; + + if (rtlpriv->psc.fwctrl_lps) + return; + + if (likely(!(hw->conf.flags & IEEE80211_CONF_PS))) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control)) + return; + + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + rtlpriv->psc.last_beacon = jiffies; + + tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); + if (!tim) + return; + + if (tim[1] < sizeof(*tim_ie)) + return; + + tim_len = tim[1]; + tim_ie = (struct ieee80211_tim_ie *)&tim[2]; + + if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period)) + rtlpriv->psc.dtim_counter = tim_ie->dtim_count; + + /* Check whenever the PHY can be turned off again. */ + + /* 1. What about buffered unicast traffic for our AID? */ + u_buffed = ieee80211_check_tim(tim_ie, tim_len, + rtlpriv->mac80211.assoc_id); + + /* 2. Maybe the AP wants to send multicast/broadcast data? */ + m_buffed = tim_ie->bitmap_ctrl & 0x01; + rtlpriv->psc.multi_buffered = m_buffed; + + /* unicast will process by mac80211 through + * set ~IEEE80211_CONF_PS, So we just check + * multicast frames here + */ + if (!m_buffed) { + /* back to low-power land. and delay is + * prevent null power save frame tx fail + */ + queue_delayed_work(rtlpriv->works.rtl_wq, + &rtlpriv->works.ps_work, MSECS(5)); + } else { + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); + } +} + +void rtl_swlps_rf_awake(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + if (!rtlpriv->psc.swctrl_lps) + return; + if (mac->link_state != MAC80211_LINKED) + return; + + if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM && + RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->disable_aspm(hw); + RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + mutex_lock(&rtlpriv->locks.lps_mutex); + rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); + mutex_unlock(&rtlpriv->locks.lps_mutex); +} + +void rtl_swlps_rfon_wq_callback(void *data) +{ + struct rtl_works *rtlworks = + container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq); + struct ieee80211_hw *hw = rtlworks->hw; + + rtl_swlps_rf_awake(hw); +} + +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 sleep_intv; + + if (!rtlpriv->psc.sw_ps_enabled) + return; + + if ((rtlpriv->sec.being_setkey) || + (mac->opmode == NL80211_IFTYPE_ADHOC)) + return; + + /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ + if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5)) + return; + + if (rtlpriv->link_info.busytraffic) + return; + + spin_lock(&rtlpriv->locks.rf_ps_lock); + if (rtlpriv->psc.rfchange_inprogress) { + spin_unlock(&rtlpriv->locks.rf_ps_lock); + return; + } + spin_unlock(&rtlpriv->locks.rf_ps_lock); + + mutex_lock(&rtlpriv->locks.lps_mutex); + rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); + mutex_unlock(&rtlpriv->locks.lps_mutex); + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && + !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { + rtlpriv->intf_ops->enable_aspm(hw); + RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); + } + + /* here is power save alg, when this beacon is DTIM + * we will set sleep time to dtim_period * n; + * when this beacon is not DTIM, we will set sleep + * time to sleep_intv = rtlpriv->psc.dtim_counter or + * MAX_SW_LPS_SLEEP_INTV(default set to 5) + */ + + if (rtlpriv->psc.dtim_counter == 0) { + if (hw->conf.ps_dtim_period == 1) + sleep_intv = hw->conf.ps_dtim_period * 2; + else + sleep_intv = hw->conf.ps_dtim_period; + } else { + sleep_intv = rtlpriv->psc.dtim_counter; + } + + if (sleep_intv > MAX_SW_LPS_SLEEP_INTV) + sleep_intv = MAX_SW_LPS_SLEEP_INTV; + + /* this print should always be dtim_conter = 0 & + * sleep = dtim_period, that meaons, we should + * awake before every dtim + */ + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); + + /* we tested that 40ms is enough for sw & hw sw delay */ + queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, + MSECS(sleep_intv * + mac->vif->bss_conf.beacon_int - 40)); +} + +void rtl_lps_change_work_callback(struct work_struct *work) +{ + struct rtl_works *rtlworks = + container_of(work, struct rtl_works, lps_change_work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->enter_ps) + rtl_lps_enter_core(hw); + else + rtl_lps_leave_core(hw); +} + +void rtl_lps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!in_interrupt()) + return rtl_lps_enter_core(hw); + rtlpriv->enter_ps = true; + schedule_work(&rtlpriv->works.lps_change_work); +} + +void rtl_lps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (!in_interrupt()) + return rtl_lps_leave_core(hw); + rtlpriv->enter_ps = false; + schedule_work(&rtlpriv->works.lps_change_work); +} + +void rtl_swlps_wq_callback(void *data) +{ + struct rtl_works *rtlworks = container_of_dwork_rtl(data, + struct rtl_works, + ps_work); + struct ieee80211_hw *hw = rtlworks->hw; + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool ps = false; + + ps = (hw->conf.flags & IEEE80211_CONF_PS); + + /* we can sleep after ps null send ok */ + if (rtlpriv->psc.state_inap) { + rtl_swlps_rf_sleep(hw); + + if (rtlpriv->psc.state && !ps) { + rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies - + rtlpriv->psc.last_action); + } + + if (ps) + rtlpriv->psc.last_slept = jiffies; + + rtlpriv->psc.last_action = jiffies; + rtlpriv->psc.state = ps; + } +} + +static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, + unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt = data; + struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info; + u8 *pos, *end, *ie; + u16 noa_len; + static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; + u8 noa_num, index, i, noa_index = 0; + bool find_p2p_ie = false, find_p2p_ps_ie = false; + + pos = (u8 *)mgmt->u.beacon.variable; + end = data + len; + ie = NULL; + + while (pos + 1 < end) { + if (pos + 2 + pos[1] > end) + return; + + if (pos[0] == 221 && pos[1] > 4) { + if (memcmp(&pos[2], p2p_oui_ie_type, 4) == 0) { + ie = pos + 2 + 4; + break; + } + } + pos += 2 + pos[1]; + } + + if (!ie) + return; + find_p2p_ie = true; + /*to find noa ie*/ + while (ie + 1 < end) { + noa_len = READEF2BYTE((__le16 *)&ie[1]); + if (ie + 3 + ie[1] > end) + return; + + if (ie[0] == 12) { + find_p2p_ps_ie = true; + if ((noa_len - 2) % 13 != 0) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); + return; + } + noa_num = (noa_len - 2) / 13; + noa_index = ie[3]; + if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == + P2P_PS_NONE || noa_index != p2pinfo->noa_index) { + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "update NOA ie.\n"); + p2pinfo->noa_index = noa_index; + p2pinfo->opp_ps = (ie[4] >> 7); + p2pinfo->ctwindow = ie[4] & 0x7F; + p2pinfo->noa_num = noa_num; + index = 5; + for (i = 0; i < noa_num; i++) { + p2pinfo->noa_count_type[i] = + READEF1BYTE(ie + index); + index += 1; + p2pinfo->noa_duration[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_interval[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_start_time[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + } + + if (p2pinfo->opp_ps == 1) { + p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + /* Driver should wait LPS entering + * CTWindow + */ + if (rtlpriv->psc.fw_current_inpsmode) + rtl_p2p_ps_cmd(hw, + P2P_PS_ENABLE); + } else if (p2pinfo->noa_num > 0) { + p2pinfo->p2p_ps_mode = P2P_PS_NOA; + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } + } + break; + } + ie += 3 + noa_len; + } + + if (find_p2p_ie) { + if ((p2pinfo->p2p_ps_mode > P2P_PS_NONE) && + (!find_p2p_ps_ie)) + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } +} + +static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, + unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt = data; + struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info; + u8 noa_num, index, i, noa_index = 0; + u8 *pos, *end, *ie; + u16 noa_len; + static u8 p2p_oui_ie_type[4] = {0x50, 0x6f, 0x9a, 0x09}; + + pos = (u8 *)&mgmt->u.action.category; + end = data + len; + ie = NULL; + + if (pos[0] == 0x7f) { + if (memcmp(&pos[1], p2p_oui_ie_type, 4) == 0) + ie = pos + 3 + 4; + } + + if (!ie) + return; + + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); + /*to find noa ie*/ + while (ie + 1 < end) { + noa_len = READEF2BYTE((__le16 *)&ie[1]); + if (ie + 3 + ie[1] > end) + return; + + if (ie[0] == 12) { + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); + RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ", + ie, noa_len); + if ((noa_len - 2) % 13 != 0) { + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); + return; + } + noa_num = (noa_len - 2) / 13; + noa_index = ie[3]; + if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == + P2P_PS_NONE || noa_index != p2pinfo->noa_index) { + p2pinfo->noa_index = noa_index; + p2pinfo->opp_ps = (ie[4] >> 7); + p2pinfo->ctwindow = ie[4] & 0x7F; + p2pinfo->noa_num = noa_num; + index = 5; + for (i = 0; i < noa_num; i++) { + p2pinfo->noa_count_type[i] = + READEF1BYTE(ie + index); + index += 1; + p2pinfo->noa_duration[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_interval[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + p2pinfo->noa_start_time[i] = + READEF4BYTE((__le32 *)ie + index); + index += 4; + } + + if (p2pinfo->opp_ps == 1) { + p2pinfo->p2p_ps_mode = P2P_PS_CTWINDOW; + /* Driver should wait LPS entering + * CTWindow + */ + if (rtlpriv->psc.fw_current_inpsmode) + rtl_p2p_ps_cmd(hw, + P2P_PS_ENABLE); + } else if (p2pinfo->noa_num > 0) { + p2pinfo->p2p_ps_mode = P2P_PS_NOA; + rtl_p2p_ps_cmd(hw, P2P_PS_ENABLE); + } else if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); + } + } + break; + } + ie += 3 + noa_len; + } +} + +void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &rtlpriv->psc.p2p_ps_info; + + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "p2p state %x\n", p2p_ps_state); + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + p2pinfo->p2p_ps_state = p2p_ps_state; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + p2pinfo->noa_index = 0; + p2pinfo->ctwindow = 0; + p2pinfo->opp_ps = 0; + p2pinfo->noa_num = 0; + p2pinfo->p2p_ps_mode = P2P_PS_NONE; + if (rtlps->fw_current_inpsmode) { + if (rtlps->smart_ps == 0) { + rtlps->smart_ps = 2; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &rtlps->pwr_mode); + } + } + break; + case P2P_PS_ENABLE: + if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + p2pinfo->p2p_ps_state = p2p_ps_state; + + if (p2pinfo->ctwindow > 0) { + if (rtlps->smart_ps != 0) { + rtlps->smart_ps = 0; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_PWRMODE, + &rtlps->pwr_mode); + } + } + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + } + break; + case P2P_PS_SCAN: + case P2P_PS_SCAN_DONE: + case P2P_PS_ALLSTASLEEP: + if (p2pinfo->p2p_ps_mode > P2P_PS_NONE) { + p2pinfo->p2p_ps_state = p2p_ps_state; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD, + &p2p_ps_state); + } + break; + default: + break; + } + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "ctwindow %x oppps %x\n", + p2pinfo->ctwindow, p2pinfo->opp_ps); + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, + "count %x duration %x index %x interval %x start time %x noa num %x\n", + p2pinfo->noa_count_type[0], + p2pinfo->noa_duration[0], + p2pinfo->noa_index, + p2pinfo->noa_interval[0], + p2pinfo->noa_start_time[0], + p2pinfo->noa_num); + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); +} + +void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct ieee80211_hdr *hdr = data; + + if (!mac->p2p) + return; + if (mac->link_state != MAC80211_LINKED) + return; + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (!ether_addr_equal_64bits(hdr->addr3, rtlpriv->mac80211.bssid)) + return; + + /* check if this really is a beacon */ + if (!(ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control) || + ieee80211_is_action(hdr->frame_control))) + return; + + if (ieee80211_is_action(hdr->frame_control)) + rtl_p2p_action_ie(hw, data, len - FCS_LEN); + else + rtl_p2p_noa_ie(hw, data, len - FCS_LEN); +} diff --git a/drivers/staging/rtlwifi/ps.h b/drivers/staging/rtlwifi/ps.h new file mode 100644 index 000000000000..6c187daced4a --- /dev/null +++ b/drivers/staging/rtlwifi/ps.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __REALTEK_RTL_PCI_PS_H__ +#define __REALTEK_RTL_PCI_PS_H__ + +#define MAX_SW_LPS_SLEEP_INTV 5 + +bool rtl_ps_enable_nic(struct ieee80211_hw *hw); +bool rtl_ps_disable_nic(struct ieee80211_hw *hw); +void rtl_ips_nic_off(struct ieee80211_hw *hw); +void rtl_ips_nic_on(struct ieee80211_hw *hw); +void rtl_ips_nic_off_wq_callback(void *data); +void rtl_lps_enter(struct ieee80211_hw *hw); +void rtl_lps_leave(struct ieee80211_hw *hw); + +void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode); + +void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len); +void rtl_swlps_wq_callback(void *data); +void rtl_swlps_rfon_wq_callback(void *data); +void rtl_swlps_rf_awake(struct ieee80211_hw *hw); +void rtl_swlps_rf_sleep(struct ieee80211_hw *hw); +void rtl_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len); +void rtl_lps_change_work_callback(struct work_struct *work); + +#endif diff --git a/drivers/staging/rtlwifi/pwrseqcmd.h b/drivers/staging/rtlwifi/pwrseqcmd.h new file mode 100644 index 000000000000..f411b7ebb08f --- /dev/null +++ b/drivers/staging/rtlwifi/pwrseqcmd.h @@ -0,0 +1,94 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8723E_PWRSEQCMD_H__ +#define __RTL8723E_PWRSEQCMD_H__ + +#include "wifi.h" +/*--------------------------------------------- + * 3 The value of cmd: 4 bits + *--------------------------------------------- + */ +#define PWR_CMD_READ 0x00 +#define PWR_CMD_WRITE 0x01 +#define PWR_CMD_POLLING 0x02 +#define PWR_CMD_DELAY 0x03 +#define PWR_CMD_END 0x04 + +/* define the base address of each block */ +#define PWR_BASEADDR_MAC 0x00 +#define PWR_BASEADDR_USB 0x01 +#define PWR_BASEADDR_PCIE 0x02 +#define PWR_BASEADDR_SDIO 0x03 + +#define PWR_INTF_SDIO_MSK BIT(0) +#define PWR_INTF_USB_MSK BIT(1) +#define PWR_INTF_PCI_MSK BIT(2) +#define PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define PWR_FAB_TSMC_MSK BIT(0) +#define PWR_FAB_UMC_MSK BIT(1) +#define PWR_FAB_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define PWR_CUT_TESTCHIP_MSK BIT(0) +#define PWR_CUT_A_MSK BIT(1) +#define PWR_CUT_B_MSK BIT(2) +#define PWR_CUT_C_MSK BIT(3) +#define PWR_CUT_D_MSK BIT(4) +#define PWR_CUT_E_MSK BIT(5) +#define PWR_CUT_F_MSK BIT(6) +#define PWR_CUT_G_MSK BIT(7) +#define PWR_CUT_ALL_MSK 0xFF + +enum pwrseq_delay_unit { + PWRSEQ_DELAY_US, + PWRSEQ_DELAY_MS, +}; + +struct wlan_pwr_cfg { + u16 offset; + u8 cut_msk; + u8 fab_msk:4; + u8 interface_msk:4; + u8 base:4; + u8 cmd:4; + u8 msk; + u8 value; +}; + +#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset) +#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk) +#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk) +#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk) +#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base) +#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd) +#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk) +#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value) + +bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, + u8 fab_version, u8 interface_type, + struct wlan_pwr_cfg pwrcfgcmd[]); + +#endif diff --git a/drivers/staging/rtlwifi/rc.c b/drivers/staging/rtlwifi/rc.c new file mode 100644 index 000000000000..65de0c7b5a67 --- /dev/null +++ b/drivers/staging/rtlwifi/rc.c @@ -0,0 +1,322 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "base.h" +#include "rc.h" + +/* + *Finds the highest rate index we can use + *if skb is special data like DHCP/EAPOL, we set should + *it to lowest rate CCK_1M, otherwise we set rate to + *highest rate based on wireless mode used for iwconfig + *show Tx rate. + */ +static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta, + struct sk_buff *skb, bool not_data) +{ + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_sta_info *sta_entry = NULL; + u16 wireless_mode = 0; + u8 nss; /* NSS -1 */ + + if (get_rf_type(rtlphy) >= RF_4T4R) + nss = 3; + else if (get_rf_type(rtlphy) >= RF_3T3R) + nss = 2; + else if (get_rf_type(rtlphy) >= RF_2T2R) + nss = 1; + else + nss = 0; + + /* + *this rate is no use for true rate, firmware + *will control rate at all it just used for + *1.show in iwconfig in B/G mode + *2.in rtl_get_tcb_desc when we check rate is + * 1M we will not use FW rate but user rate. + */ + + if (sta) { + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wireless_mode = sta_entry->wireless_mode; + } + + if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true, false) || + not_data) { + return 0; + } + if (rtlhal->current_bandtype == BAND_ON_2_4G) { + if (wireless_mode == WIRELESS_MODE_B) { + return B_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_G) { + return G_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_N_24G) { + if (nss == 0) + return N_MODE_MCS7_RIX; + else + return N_MODE_MCS15_RIX; + } else if (wireless_mode == WIRELESS_MODE_AC_24G) { + if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + return AC_MODE_MCS8_RIX | (nss << 4); + else + return AC_MODE_MCS9_RIX | (nss << 4); + } + return 0; + } + if (wireless_mode == WIRELESS_MODE_A) { + return A_MODE_MAX_RIX; + } else if (wireless_mode == WIRELESS_MODE_N_5G) { + if (nss == 0) + return N_MODE_MCS7_RIX; + else + return N_MODE_MCS15_RIX; + } else if (wireless_mode == WIRELESS_MODE_AC_5G) { + if (sta->bandwidth == IEEE80211_STA_RX_BW_20) + return AC_MODE_MCS8_RIX | (nss << 4); + else + return AC_MODE_MCS9_RIX | (nss << 4); + } + return 0; +} + +static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta, + struct ieee80211_tx_rate *rate, + struct ieee80211_tx_rate_control *txrc, + u8 tries, s8 rix, int rtsctsenable, + bool not_data) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct rtl_sta_info *sta_entry = NULL; + u16 wireless_mode = 0; + u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0; + + if (sta) { + sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20; + sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40; + sgi_80 = sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80; + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wireless_mode = sta_entry->wireless_mode; + } + rate->count = tries; + rate->idx = rix >= 0x00 ? rix : 0x00; + if (((rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) || + (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8822BE)) && + wireless_mode == WIRELESS_MODE_AC_5G) + rate->idx |= 0x10;/*2NSS for 8812AE, 8822BE*/ + + if (!not_data) { + if (txrc->short_preamble) + rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE; + if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) { + if (sta && (sta->ht_cap.cap & + IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (sta && (sta->vht_cap.vht_supported)) + rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + } else { + if (mac->bw_80) + rate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH; + else if (mac->bw_40) + rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + } + + if (sgi_20 || sgi_40 || sgi_80) + rate->flags |= IEEE80211_TX_RC_SHORT_GI; + if (sta && sta->ht_cap.ht_supported && + ((wireless_mode == WIRELESS_MODE_N_5G) || + (wireless_mode == WIRELESS_MODE_N_24G))) + rate->flags |= IEEE80211_TX_RC_MCS; + if (sta && sta->vht_cap.vht_supported && + (wireless_mode == WIRELESS_MODE_AC_5G || + wireless_mode == WIRELESS_MODE_AC_24G || + wireless_mode == WIRELESS_MODE_AC_ONLY)) + rate->flags |= IEEE80211_TX_RC_VHT_MCS; + } +} + +static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta, + void *priv_sta, + struct ieee80211_tx_rate_control *txrc) +{ + struct rtl_priv *rtlpriv = ppriv; + struct sk_buff *skb = txrc->skb; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_rate *rates = tx_info->control.rates; + __le16 fc = rtl_get_fc(skb); + u8 try_per_rate, i, rix; + bool not_data = !ieee80211_is_data(fc); + + if (rate_control_send_low(sta, priv_sta, txrc)) + return; + + rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data); + try_per_rate = 1; + _rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc, + try_per_rate, rix, 1, not_data); + + if (!not_data) { + for (i = 1; i < 4; i++) + _rtl_rc_rate_set_series(rtlpriv, sta, &rates[i], + txrc, i, (rix - i), 1, + not_data); + } +} + +static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, + struct rtl_sta_info *sta_entry, u16 tid) +{ + struct rtl_mac *mac = rtl_mac(rtlpriv); + + if (mac->act_scanning) + return false; + + if (mac->opmode == NL80211_IFTYPE_STATION && + mac->cnt_after_linked < 3) + return false; + + if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP) + return true; + + return false; +} + +/*mac80211 Rate Control callbacks*/ +static void rtl_tx_status(void *ppriv, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_mac *mac = rtl_mac(rtlpriv); + struct ieee80211_hdr *hdr = rtl_get_hdr(skb); + __le16 fc = rtl_get_fc(skb); + struct rtl_sta_info *sta_entry; + + if (!priv_sta || !ieee80211_is_data(fc)) + return; + + if (rtl_is_special_data(mac->hw, skb, true, true)) + return; + + if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) + return; + + if (sta) { + /* Check if aggregation has to be enabled for this tid */ + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + if ((sta->ht_cap.ht_supported) && + !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { + if (ieee80211_is_data_qos(fc)) { + u8 tid = rtl_get_tid(skb); + + if (_rtl_tx_aggr_check(rtlpriv, sta_entry, + tid)) { + sta_entry->tids[tid].agg.agg_state = + RTL_AGG_PROGRESS; + ieee80211_start_tx_ba_session(sta, tid, + 5000); + } + } + } + } +} + +static void rtl_rate_init(void *ppriv, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, void *priv_sta) +{ +} + +static void rtl_rate_update(void *ppriv, + struct ieee80211_supported_band *sband, + struct cfg80211_chan_def *chandef, + struct ieee80211_sta *sta, void *priv_sta, + u32 changed) +{ +} + +static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + return rtlpriv; +} + +static void rtl_rate_free(void *rtlpriv) +{ +} + +static void *rtl_rate_alloc_sta(void *ppriv, + struct ieee80211_sta *sta, gfp_t gfp) +{ + struct rtl_priv *rtlpriv = ppriv; + struct rtl_rate_priv *rate_priv; + + rate_priv = kzalloc(sizeof(*rate_priv), gfp); + if (!rate_priv) { + pr_err("Unable to allocate private rc structure\n"); + return NULL; + } + + rtlpriv->rate_priv = rate_priv; + + return rate_priv; +} + +static void rtl_rate_free_sta(void *rtlpriv, + struct ieee80211_sta *sta, void *priv_sta) +{ + struct rtl_rate_priv *rate_priv = priv_sta; + + kfree(rate_priv); +} + +static const struct rate_control_ops rtl_rate_ops = { + .name = "rtl_rc", + .alloc = rtl_rate_alloc, + .free = rtl_rate_free, + .alloc_sta = rtl_rate_alloc_sta, + .free_sta = rtl_rate_free_sta, + .rate_init = rtl_rate_init, + .rate_update = rtl_rate_update, + .tx_status = rtl_tx_status, + .get_rate = rtl_get_rate, +}; + +int rtl_rate_control_register(void) +{ + return ieee80211_rate_control_register(&rtl_rate_ops); +} + +void rtl_rate_control_unregister(void) +{ + ieee80211_rate_control_unregister(&rtl_rate_ops); +} diff --git a/drivers/staging/rtlwifi/rc.h b/drivers/staging/rtlwifi/rc.h new file mode 100644 index 000000000000..dcc8520866b7 --- /dev/null +++ b/drivers/staging/rtlwifi/rc.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_RC_H__ +#define __RTL_RC_H__ + +#define B_MODE_MAX_RIX 3 +#define G_MODE_MAX_RIX 11 +#define A_MODE_MAX_RIX 7 + +/* in mac80211 mcs0-mcs15 is idx0-idx15*/ +#define N_MODE_MCS7_RIX 7 +#define N_MODE_MCS15_RIX 15 + +/* in mac80211 vht mcs0-9 is in [3:0], nss is in [:4] */ +#define AC_MODE_MCS7_RIX 7 +#define AC_MODE_MCS8_RIX 8 +#define AC_MODE_MCS9_RIX 9 + +struct rtl_rate_priv { + u8 ht_cap; +}; + +int rtl_rate_control_register(void); +void rtl_rate_control_unregister(void); + +#endif diff --git a/drivers/staging/rtlwifi/regd.c b/drivers/staging/rtlwifi/regd.c new file mode 100644 index 000000000000..e0a3ff85edb6 --- /dev/null +++ b/drivers/staging/rtlwifi/regd.c @@ -0,0 +1,469 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "wifi.h" +#include "regd.h" + +static struct country_code_to_enum_rd allcountries[] = { + {COUNTRY_CODE_FCC, "US"}, + {COUNTRY_CODE_IC, "US"}, + {COUNTRY_CODE_ETSI, "EC"}, + {COUNTRY_CODE_SPAIN, "EC"}, + {COUNTRY_CODE_FRANCE, "EC"}, + {COUNTRY_CODE_MKK, "JP"}, + {COUNTRY_CODE_MKK1, "JP"}, + {COUNTRY_CODE_ISRAEL, "EC"}, + {COUNTRY_CODE_TELEC, "JP"}, + {COUNTRY_CODE_MIC, "JP"}, + {COUNTRY_CODE_GLOBAL_DOMAIN, "JP"}, + {COUNTRY_CODE_WORLD_WIDE_13, "EC"}, + {COUNTRY_CODE_TELEC_NETGEAR, "EC"}, + {COUNTRY_CODE_WORLD_WIDE_13_5G_ALL, "US"}, +}; + +/*Only these channels all allow active + *scan on all world regulatory domains + */ +#define RTL819x_2GHZ_CH01_11 \ + REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0) + +/*We enable active scan on these a case + *by case basis by regulatory domain + */ +#define RTL819x_2GHZ_CH12_13 \ + REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN) + +#define RTL819x_2GHZ_CH14 \ + REG_RULE(2484 - 10, 2484 + 10, 40, 0, 20, \ + NL80211_RRF_PASSIVE_SCAN | \ + NL80211_RRF_NO_OFDM) + +/* 5G chan 36 - chan 64*/ +#define RTL819x_5GHZ_5150_5350 \ + REG_RULE(5150 - 10, 5350 + 10, 80, 0, 30, 0) +/* 5G chan 100 - chan 165*/ +#define RTL819x_5GHZ_5470_5850 \ + REG_RULE(5470 - 10, 5850 + 10, 80, 0, 30, 0) +/* 5G chan 149 - chan 165*/ +#define RTL819x_5GHZ_5725_5850 \ + REG_RULE(5725 - 10, 5850 + 10, 80, 0, 30, 0) + +#define RTL819x_5GHZ_ALL \ + (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) + +static const struct ieee80211_regdomain rtl_regdom_11 = { + .n_reg_rules = 1, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_12_13 = { + .n_reg_rules = 2, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_no_midband = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_5GHZ_5150_5350, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_60_64 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_14_60_64 = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_2GHZ_CH14, + RTL819x_5GHZ_5725_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_12_13_5g_all = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_5GHZ_5150_5350, + RTL819x_5GHZ_5470_5850, + } +}; + +static const struct ieee80211_regdomain rtl_regdom_14 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + RTL819x_2GHZ_CH01_11, + RTL819x_2GHZ_CH12_13, + RTL819x_2GHZ_CH14, + } +}; + +static bool _rtl_is_radar_freq(u16 center_freq) +{ + return center_freq >= 5260 && center_freq <= 5700; +} + +static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum nl80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (_rtl_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { + reg_rule = freq_reg_info(wiphy, + ch->center_freq); + if (IS_ERR(reg_rule)) + continue; + /* + *If 11d had a rule for this channel ensure + *we enable adhoc/beaconing if it allows us to + *use it. Note that we would have disabled it + *by applying our static world regdomain by + *default during init, prior to calling our + *regulatory_hint(). + */ + + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; + if (!(reg_rule->flags & + NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } + } +} + +/* Allows active scan scan on Ch 12 and 13 */ +static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator + initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + + if (!wiphy->bands[NL80211_BAND_2GHZ]) + return; + sband = wiphy->bands[NL80211_BAND_2GHZ]; + + /* + *If no country IE has been received always enable active scan + *on these channels. This is only done for specific regulatory SKUs + */ + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /*If a country IE has been received check its rule for this + *channel first before enabling active scan. The passive scan + *would have been enforced by the initial processing of our + *custom regulatory domain. + */ + + ch = &sband->channels[11]; /* CH 12 */ + reg_rule = freq_reg_info(wiphy, ch->center_freq); + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } + + ch = &sband->channels[12]; /* CH 13 */ + reg_rule = freq_reg_info(wiphy, ch->center_freq); + if (!IS_ERR(reg_rule)) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +/* + *Always apply Radar/DFS rules on + *freq range 5260 MHz - 5700 MHz + */ +static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + if (!wiphy->bands[NL80211_BAND_5GHZ]) + return; + + sband = wiphy->bands[NL80211_BAND_5GHZ]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!_rtl_is_radar_freq(ch->center_freq)) + continue; + + /* + *We always enable radar detection/DFS on this + *frequency range. Additionally we also apply on + *this frequency range: + *- If STA mode does not yet have DFS supports disable + * active scanning + *- If adhoc mode does not support DFS yet then disable + * adhoc in the frequency. + *- If AP mode does not yet support radar detection/DFS + *do not allow AP mode + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + } +} + +static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct rtl_regulatory *reg) +{ + _rtl_reg_apply_beaconing_flags(wiphy, initiator); + _rtl_reg_apply_active_scan_flags(wiphy, initiator); +} + +static void _rtl_dump_channel_map(struct wiphy *wiphy) +{ + enum nl80211_band band; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!wiphy->bands[band]) + continue; + sband = wiphy->bands[band]; + for (i = 0; i < sband->n_channels; i++) + ch = &sband->channels[i]; + } +} + +static int _rtl_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, + struct rtl_regulatory *reg) +{ + /* We always apply this */ + _rtl_reg_apply_radar_flags(wiphy); + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + _rtl_reg_apply_world_flags(wiphy, request->initiator, reg); + break; + } + + _rtl_dump_channel_map(wiphy); + + return 0; +} + +static const struct ieee80211_regdomain *_rtl_regdomain_select( + struct rtl_regulatory *reg) +{ + switch (reg->country_code) { + case COUNTRY_CODE_FCC: + return &rtl_regdom_no_midband; + case COUNTRY_CODE_IC: + return &rtl_regdom_11; + case COUNTRY_CODE_TELEC_NETGEAR: + return &rtl_regdom_60_64; + case COUNTRY_CODE_ETSI: + case COUNTRY_CODE_SPAIN: + case COUNTRY_CODE_FRANCE: + case COUNTRY_CODE_ISRAEL: + return &rtl_regdom_12_13; + case COUNTRY_CODE_MKK: + case COUNTRY_CODE_MKK1: + case COUNTRY_CODE_TELEC: + case COUNTRY_CODE_MIC: + return &rtl_regdom_14_60_64; + case COUNTRY_CODE_GLOBAL_DOMAIN: + return &rtl_regdom_14; + case COUNTRY_CODE_WORLD_WIDE_13: + case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL: + return &rtl_regdom_12_13_5g_all; + default: + return &rtl_regdom_no_midband; + } +} + +static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg, + struct wiphy *wiphy, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request * + request)) +{ + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; + + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; + wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; + wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; + regd = _rtl_regdomain_select(reg); + wiphy_apply_custom_regulatory(wiphy, regd); + _rtl_reg_apply_radar_flags(wiphy); + _rtl_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); + return 0; +} + +static struct country_code_to_enum_rd *_rtl_regd_find_country(u16 countrycode) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(allcountries); i++) { + if (allcountries[i].countrycode == countrycode) + return &allcountries[i]; + } + return NULL; +} + +static u8 channel_plan_to_country_code(u8 channelplan) +{ + switch (channelplan) { + case 0x20: + case 0x21: + return COUNTRY_CODE_WORLD_WIDE_13; + case 0x22: + return COUNTRY_CODE_IC; + case 0x25: + return COUNTRY_CODE_ETSI; + case 0x32: + return COUNTRY_CODE_TELEC_NETGEAR; + case 0x41: + return COUNTRY_CODE_GLOBAL_DOMAIN; + case 0x7f: + return COUNTRY_CODE_WORLD_WIDE_13_5G_ALL; + default: + return COUNTRY_CODE_MAX; /*Error*/ + } +} + +int rtl_regd_init(struct ieee80211_hw *hw, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct wiphy *wiphy = hw->wiphy; + struct country_code_to_enum_rd *country = NULL; + + if (!wiphy || !&rtlpriv->regd) + return -EINVAL; + + /* init country_code from efuse channel plan */ + rtlpriv->regd.country_code = + channel_plan_to_country_code(rtlpriv->efuse.channel_plan); + + RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM regdomain: 0x%0x country code: %d\n", + rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); + + if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { + RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); + + rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; + } + + country = _rtl_regd_find_country(rtlpriv->regd.country_code); + + if (country) { + rtlpriv->regd.alpha2[0] = country->iso_name[0]; + rtlpriv->regd.alpha2[1] = country->iso_name[1]; + } else { + rtlpriv->regd.alpha2[0] = '0'; + rtlpriv->regd.alpha2[1] = '0'; + } + + RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); + + _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); + + return 0; +} + +void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); + + _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); +} diff --git a/drivers/staging/rtlwifi/regd.h b/drivers/staging/rtlwifi/regd.h new file mode 100644 index 000000000000..5626015a6d0d --- /dev/null +++ b/drivers/staging/rtlwifi/regd.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_REGD_H__ +#define __RTL_REGD_H__ + +/* for kernel 3.14 , both value are changed to IEEE80211_CHAN_NO_IR*/ +#define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR +#define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR + +struct country_code_to_enum_rd { + u16 countrycode; + const char *iso_name; +}; + +enum country_code_type_t { + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC = 8, + COUNTRY_CODE_MIC = 9, + COUNTRY_CODE_GLOBAL_DOMAIN = 10, + COUNTRY_CODE_WORLD_WIDE_13 = 11, + COUNTRY_CODE_TELEC_NETGEAR = 12, + COUNTRY_CODE_WORLD_WIDE_13_5G_ALL = 13, + + /*add new channel plan above this line */ + COUNTRY_CODE_MAX +}; + +int rtl_regd_init(struct ieee80211_hw *hw, + void (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)); +void rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request); + +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/Makefile b/drivers/staging/rtlwifi/rtl8822be/Makefile new file mode 100644 index 000000000000..d535ff8febf1 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/Makefile @@ -0,0 +1,7 @@ +rtl8822be-objs := \ + fw.o \ + hw.o \ + led.o \ + phy.o \ + sw.o \ + trx.o diff --git a/drivers/staging/rtlwifi/rtl8822be/def.h b/drivers/staging/rtlwifi/rtl8822be/def.h new file mode 100644 index 000000000000..7942ddfdcf43 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/def.h @@ -0,0 +1,82 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_DEF_H__ +#define __RTL8822B_DEF_H__ + +#define RX_DESC_NUM_8822BE 512 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +#define RX_MPDU_QUEUE 0 + +#define IS_HT_RATE(_rate) (_rate >= DESC_RATEMCS0) +#define IS_CCK_RATE(_rate) (_rate >= DESC_RATE1M && _rate <= DESC_RATE11M) +#define IS_OFDM_RATE(_rate) (_rate >= DESC_RATE6M && _rate <= DESC_RATE54M) +#define IS_1T_RATE(_rate) \ + ((_rate >= DESC_RATE1M && _rate <= DESC_RATEMCS7) || \ + (_rate >= DESC_RATEVHT1SS_MCS0 && _rate <= DESC_RATEVHT1SS_MCS9)) +#define IS_2T_RATE(_rate) \ + ((_rate >= DESC_RATEMCS8 && _rate <= DESC_RATEMCS15) || \ + (_rate >= DESC_RATEVHT2SS_MCS0 && _rate <= DESC_RATEVHT2SS_MCS9)) + +#define IS_1T_RATESEC(_rs) \ + ((_rs == CCK) || (_rs == OFDM) || (_rs == HT_MCS0_MCS7) || \ + (_rs == VHT_1SSMCS0_1SSMCS9)) +#define IS_2T_RATESEC(_rs) \ + ((_rs == HT_MCS8_MCS15) || (_rs == VHT_2SSMCS0_2SSMCS9)) + +enum rx_packet_type { + NORMAL_RX, + C2H_PACKET, +}; + +enum rtl_desc_qsel { + QSLT_BK = 0x2, + QSLT_BE = 0x0, + QSLT_VI = 0x5, + QSLT_VO = 0x7, + QSLT_BEACON = 0x10, + QSLT_HIGH = 0x11, + QSLT_MGNT = 0x12, + QSLT_CMD = 0x13, +}; + +enum vht_data_sc { + VHT_DATA_SC_DONOT_CARE = 0, + VHT_DATA_SC_20_UPPER_OF_80MHZ = 1, + VHT_DATA_SC_20_LOWER_OF_80MHZ = 2, + VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3, + VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4, + VHT_DATA_SC_20_RECV1 = 5, + VHT_DATA_SC_20_RECV2 = 6, + VHT_DATA_SC_20_RECV3 = 7, + VHT_DATA_SC_20_RECV4 = 8, + VHT_DATA_SC_40_UPPER_OF_80MHZ = 9, + VHT_DATA_SC_40_LOWER_OF_80MHZ = 10, +}; +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.c b/drivers/staging/rtlwifi/rtl8822be/fw.c new file mode 100644 index 000000000000..8e24da16752c --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/fw.c @@ -0,0 +1,968 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "fw.h" + +static bool _rtl8822be_check_fw_read_last_h2c(struct ieee80211_hw *hw, + u8 boxnum) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 val_hmetfr; + bool result = false; + + val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR_8822B); + if (((val_hmetfr >> boxnum) & BIT(0)) == 0) + result = true; + return result; +} + +static void _rtl8822be_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *cmdbuffer) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 boxnum; + u16 box_reg = 0, box_extreg = 0; + u8 u1b_tmp; + bool isfw_read; + u8 buf_index = 0; + bool bwrite_success = false; + u8 wait_h2c_limmit = 100; + u8 boxcontent[4], boxextcontent[4]; + u32 h2c_waitcounter = 0; + unsigned long flag; + u8 idx; + + /* 1. Prevent race condition in setting H2C cmd. + * (copy from MgntActSet_RF_State().) + */ + while (true) { + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + if (rtlhal->h2c_setinprogress) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "H2C set in progress! wait..H2C_ID=%d.\n", + element_id); + + while (rtlhal->h2c_setinprogress) { + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, + flag); + h2c_waitcounter++; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); + udelay(100); + + if (h2c_waitcounter > 1000) + return; + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, + flag); + } + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + } else { + rtlhal->h2c_setinprogress = true; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + break; + } + } + + while (!bwrite_success) { + /* 2. Find the last BOX number which has been writen. */ + boxnum = rtlhal->last_hmeboxnum; + switch (boxnum) { + case 0: + box_reg = REG_HMEBOX0_8822B; + box_extreg = REG_HMEBOX_E0_8822B; + break; + case 1: + box_reg = REG_HMEBOX1_8822B; + box_extreg = REG_HMEBOX_E1_8822B; + break; + case 2: + box_reg = REG_HMEBOX2_8822B; + box_extreg = REG_HMEBOX_E2_8822B; + break; + case 3: + box_reg = REG_HMEBOX3_8822B; + box_extreg = REG_HMEBOX_E3_8822B; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + + /* 3. Check if the box content is empty. */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_CR_8822B); + + if (u1b_tmp == 0xea) { + if (rtl_read_byte(rtlpriv, REG_TXDMA_STATUS_8822B) == + 0xea || + rtl_read_byte(rtlpriv, REG_TXPKT_EMPTY_8822B) == + 0xea) + rtl_write_byte(rtlpriv, REG_SYS_CFG1_8822B + 3, + 0xff); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "REG_CR is unavaliable\n"); + break; + } + + wait_h2c_limmit = 100; + isfw_read = _rtl8822be_check_fw_read_last_h2c(hw, boxnum); + while (!isfw_read) { + wait_h2c_limmit--; + if (wait_h2c_limmit == 0) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_WARNING, + "Wait too long for FW clear MB%d!!!\n", + boxnum); + break; + } + udelay(10); + isfw_read = + _rtl8822be_check_fw_read_last_h2c(hw, boxnum); + u1b_tmp = rtl_read_byte(rtlpriv, 0x130); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Waiting for FW clear MB%d!!! 0x130 = %2x\n", + boxnum, u1b_tmp); + } + + /* If Fw has not read the last H2C cmd, + * break and give up this H2C. + */ + if (!isfw_read) { + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Write H2C reg BOX[%d] fail,Fw don't read.\n", + boxnum); + break; + } + /* 4. Fill the H2C cmd into box */ + memset(boxcontent, 0, sizeof(boxcontent)); + memset(boxextcontent, 0, sizeof(boxextcontent)); + boxcontent[0] = element_id; + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", box_reg, + element_id); + + switch (cmd_len) { + case 1: + case 2: + case 3: + /*boxcontent[0] &= ~(BIT(7));*/ + memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index, + cmd_len); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + case 4: + case 5: + case 6: + case 7: + /*boxcontent[0] |= (BIT(7));*/ + memcpy((u8 *)(boxextcontent), cmdbuffer + buf_index + 3, + cmd_len - 3); + memcpy((u8 *)(boxcontent) + 1, cmdbuffer + buf_index, + 3); + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_extreg + idx, + boxextcontent[idx]); + } + + for (idx = 0; idx < 4; idx++) { + rtl_write_byte(rtlpriv, box_reg + idx, + boxcontent[idx]); + } + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + + bwrite_success = true; + + rtlhal->last_hmeboxnum = boxnum + 1; + if (rtlhal->last_hmeboxnum == 4) + rtlhal->last_hmeboxnum = 0; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); + } + + spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); + rtlhal->h2c_setinprogress = false; + spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); +} + +void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, + u8 *cmdbuffer) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_cmdbuf[8]; + + if (!rtlhal->fw_ready) { + WARN_ONCE(true, + "return H2C cmd because of Fw download fail!!!\n"); + return; + } + + memset(tmp_cmdbuf, 0, 8); + memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); + + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, + "h2c cmd: len=%d %02X%02X%02X%02X %02X%02X%02X%02X\n", cmd_len, + tmp_cmdbuf[2], tmp_cmdbuf[1], tmp_cmdbuf[0], element_id, + tmp_cmdbuf[6], tmp_cmdbuf[5], tmp_cmdbuf[4], tmp_cmdbuf[3]); + + _rtl8822be_fill_h2c_command(hw, element_id, cmd_len, tmp_cmdbuf); +} + +void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw) +{ + u8 h2c_set_default_port_id[H2C_DEFAULT_PORT_ID_LEN]; + + SET_H2CCMD_DFTPID_PORT_ID(h2c_set_default_port_id, 0); + SET_H2CCMD_DFTPID_MAC_ID(h2c_set_default_port_id, 0); + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_DEFAULT_PORT_ID, + H2C_DEFAULT_PORT_ID_LEN, + h2c_set_default_port_id); +} + +void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 u1_h2c_set_pwrmode[H2C_8822B_PWEMODE_LENGTH] = {0}; + static u8 prev_h2c[H2C_8822B_PWEMODE_LENGTH] = {0}; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + u8 rlbm, power_state = 0, byte5 = 0; + u8 awake_intvl; /* DTIM = (awake_intvl - 1) */ + u8 smart_ps = 0; + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + bool bt_ctrl_lps = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_ctrl_lps(rtlpriv) : false); + bool bt_lps_on = (rtlpriv->cfg->ops->get_btc_status() ? + btc_ops->btc_is_bt_lps_on(rtlpriv) : false); + + memset(u1_h2c_set_pwrmode, 0, H2C_8822B_PWEMODE_LENGTH); + + if (bt_ctrl_lps) + mode = (bt_lps_on ? FW_PS_MIN_MODE : FW_PS_ACTIVE_MODE); + + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "FW LPS mode = %d (coex:%d)\n", + mode, bt_ctrl_lps); + + switch (mode) { + case FW_PS_MIN_MODE: + rlbm = 0; + awake_intvl = 2; + smart_ps = ppsc->smart_ps; + break; + case FW_PS_MAX_MODE: + rlbm = 1; + awake_intvl = 2; + smart_ps = ppsc->smart_ps; + break; + case FW_PS_DTIM_MODE: + rlbm = 2; + awake_intvl = ppsc->reg_max_lps_awakeintvl; + /* + * hw->conf.ps_dtim_period or mac->vif->bss_conf.dtim_period + * is only used in swlps. + */ + smart_ps = ppsc->smart_ps; + break; + case FW_PS_ACTIVE_MODE: + rlbm = 0; + awake_intvl = 1; + break; + default: + rlbm = 2; + awake_intvl = 4; + smart_ps = ppsc->smart_ps; + break; + } + + if (rtlpriv->mac80211.p2p) { + awake_intvl = 2; + rlbm = 1; + } + + if (mode == FW_PS_ACTIVE_MODE) { + byte5 = 0x40; + power_state = FW_PWR_STATE_ACTIVE; + } else { + if (bt_ctrl_lps) { + byte5 = btc_ops->btc_get_lps_val(rtlpriv); + power_state = btc_ops->btc_get_rpwm_val(rtlpriv); + + if ((rlbm == 2) && (byte5 & BIT(4))) { + /* Keep awake interval to 1 to prevent from + * decreasing coex performance + */ + awake_intvl = 2; + rlbm = 2; + } + smart_ps = 0; + } else { + byte5 = 0x40; + power_state = FW_PWR_STATE_RF_OFF; + } + } + + SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); + SET_H2CCMD_PWRMODE_PARM_RLBM(u1_h2c_set_pwrmode, rlbm); + SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, smart_ps); + SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(u1_h2c_set_pwrmode, awake_intvl); + SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1_h2c_set_pwrmode, 0); + SET_H2CCMD_PWRMODE_PARM_PWR_STATE(u1_h2c_set_pwrmode, power_state); + SET_H2CCMD_PWRMODE_PARM_BYTE5(u1_h2c_set_pwrmode, byte5); + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, + "rtl8822be_set_fw_pwrmode(): u1_h2c_set_pwrmode\n", + u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_record_pwr_mode(rtlpriv, u1_h2c_set_pwrmode, + H2C_8822B_PWEMODE_LENGTH); + + if (!memcmp(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH)) + return; + memcpy(prev_h2c, u1_h2c_set_pwrmode, H2C_8822B_PWEMODE_LENGTH); + + rtl8822be_set_default_port_id_cmd(hw); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_SETPWRMODE, + H2C_8822B_PWEMODE_LENGTH, u1_h2c_set_pwrmode); +} + +void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus) +{ + u8 parm[4] = {0, 0, 0, 0}; + /* parm[0]: bit0=0-->Disconnect, bit0=1-->Connect + * bit1=0-->update Media Status to MACID + * bit1=1-->update Media Status from MACID to MACID_End + * parm[1]: MACID, if this is INFRA_STA, MacID = 0 + * parm[2]: MACID_End + * parm[3]: bit2-0: port ID + */ + + SET_H2CCMD_MSRRPT_PARM_OPMODE(parm, mstatus); + SET_H2CCMD_MSRRPT_PARM_MACID_IND(parm, 0); + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MSRRPT, 4, parm); +} + +static bool _rtl8822be_send_bcn_or_cmd_packet(struct ieee80211_hw *hw, + struct sk_buff *skb, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + struct rtl_tx_desc *pdesc; + struct rtl_tx_buffer_desc *pbd_desc; + unsigned long flags; + struct sk_buff *pskb = NULL; + u8 *pdesc_or_bddesc; + dma_addr_t dma_addr; + + if (hw_queue != BEACON_QUEUE && hw_queue != H2C_QUEUE) + return false; + + ring = &rtlpci->tx_ring[hw_queue]; + + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); + + if (hw_queue == BEACON_QUEUE) { + pdesc = &ring->desc[0]; + pbd_desc = &ring->buffer_desc[0]; + pdesc_or_bddesc = (u8 *)pbd_desc; + + /* free previous beacon queue */ + pskb = __skb_dequeue(&ring->queue); + + if (!pskb) + goto free_prev_skb_done; + + dma_addr = rtlpriv->cfg->ops->get_desc( + hw, (u8 *)pbd_desc, true, HW_DESC_TXBUFF_ADDR); + + pci_unmap_single(rtlpci->pdev, dma_addr, skb->len, + PCI_DMA_TODEVICE); + kfree_skb(pskb); + +free_prev_skb_done: + ; + + } else { /* hw_queue == TXCMD_QUEUE */ + if (rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "get_available_desc fail hw_queue=%d\n", + hw_queue); + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, + flags); + return false; + } + + pdesc = &ring->desc[ring->cur_tx_wp]; + pbd_desc = &ring->buffer_desc[ring->cur_tx_wp]; + pdesc_or_bddesc = (u8 *)pdesc; + } + + rtlpriv->cfg->ops->fill_tx_special_desc(hw, (u8 *)pdesc, (u8 *)pbd_desc, + skb, hw_queue); + + __skb_queue_tail(&ring->queue, skb); + + rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc_or_bddesc, true, + HW_DESC_OWN, (u8 *)&hw_queue); + + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + rtlpriv->cfg->ops->tx_polling(hw, hw_queue); + + return true; +} + +bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf, + u32 size) +{ + struct sk_buff *skb = NULL; + u8 u1b_tmp; + int count; + + skb = dev_alloc_skb(size); + memcpy((u8 *)skb_put(skb, size), buf, size); + + if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE)) + return false; + + /* These code isn't actually need, because halmac will check + * BCN_VALID + */ + + /* Polling Beacon Queue to send Beacon */ + u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1); + count = 0; + while ((count < 20) && (u1b_tmp & BIT(4))) { + count++; + udelay(10); + u1b_tmp = rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1); + } + + if (count >= 20) + pr_err("%s polling beacon fail\n", __func__); + + return true; +} + +bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf, + u32 size) +{ + struct sk_buff *skb = NULL; + + /* without GFP_DMA, pci_map_single() may not work */ + skb = __netdev_alloc_skb(NULL, size, GFP_ATOMIC | GFP_DMA); + memcpy((u8 *)skb_put(skb, size), buf, size); + + return _rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, H2C_QUEUE); +} + +/* Rsvd page HALMAC_RSVD_DRV_PGNUM_8822B occupies 16 page (2048 byte) */ +#define BEACON_PG 0 /* ->1 */ +#define PSPOLL_PG 2 +#define NULL_PG 3 +#define PROBERSP_PG 4 /* ->5 */ +#define QOS_NULL_PG 6 +#define BT_QOS_NULL_PG 7 + +#define TOTAL_RESERVED_PKT_LEN 1024 + +static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = {/* page size = 128 */ + /* page 0 beacon */ + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x10, 0x04, 0x00, 0x05, 0x54, 0x65, + 0x73, 0x74, 0x32, 0x01, 0x08, 0x82, 0x84, 0x0B, + 0x16, 0x24, 0x30, 0x48, 0x6C, 0x03, 0x01, 0x06, + 0x06, 0x02, 0x00, 0x00, 0x2A, 0x01, 0x02, 0x32, + 0x04, 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, + 0x09, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3D, 0x00, 0xDD, 0x07, 0x00, 0xE0, 0x4C, + 0x02, 0x02, 0x00, 0x00, 0xDD, 0x18, 0x00, 0x50, + 0xF2, 0x01, 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, + 0x01, 0x00, 0x00, 0x50, 0xF2, 0x04, 0x01, 0x00, + + /* page 1 beacon */ + 0x00, 0x50, 0xF2, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 2 ps-poll */ + 0xA4, 0x10, 0x01, 0xC0, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 3 null */ + 0x48, 0x01, 0x00, 0x00, 0xEC, 0x1A, 0x59, 0x0B, + 0xAD, 0xD4, 0x00, 0xE0, 0x4C, 0x02, 0xB1, 0x78, + 0xEC, 0x1A, 0x59, 0x0B, 0xAD, 0xD4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 4 probe_resp */ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, + 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, + 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, + 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, + 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, + 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, + 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, + 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, + 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, + 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 5 probe_resp */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 6 qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x00, 0x30, 0x84, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* page 7 BT-qos null data */ + 0xC8, 0x01, 0x00, 0x00, 0x84, 0xC9, 0xB2, 0xA7, + 0xB3, 0x6E, 0x00, 0xE0, 0x4C, 0x02, 0x51, 0x02, + 0x84, 0xC9, 0xB2, 0xA7, 0xB3, 0x6E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct sk_buff *skb = NULL; + + u32 totalpacketlen; + bool rtstatus; + u8 u1_rsvd_page_loc[7] = {0}; + bool b_dlok = false; + + u8 *beacon; + u8 *p_pspoll; + u8 *nullfunc; + u8 *p_probersp; + u8 *qosnull; + u8 *btqosnull; + + memset(u1_rsvd_page_loc, 0, sizeof(u1_rsvd_page_loc)); + + /*--------------------------------------------------------- + * (1) beacon + *--------------------------------------------------------- + */ + beacon = &reserved_page_packet[BEACON_PG * 128]; + SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); + SET_80211_HDR_ADDRESS3(beacon, mac->bssid); + + /*------------------------------------------------------- + * (2) ps-poll + *-------------------------------------------------------- + */ + p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; + SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); + SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); + SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); + + SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1_rsvd_page_loc, PSPOLL_PG); + + /*-------------------------------------------------------- + * (3) null data + *--------------------------------------------------------- + */ + nullfunc = &reserved_page_packet[NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); + SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); + SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1_rsvd_page_loc, NULL_PG); + + /*--------------------------------------------------------- + * (4) probe response + *---------------------------------------------------------- + */ + p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; + SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); + SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); + SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1_rsvd_page_loc, PROBERSP_PG); + + /*--------------------------------------------------------- + * (5) QoS null data + *---------------------------------------------------------- + */ + qosnull = &reserved_page_packet[QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(qosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(qosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(qosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1_rsvd_page_loc, QOS_NULL_PG); + + /*--------------------------------------------------------- + * (6) BT QoS null data + *---------------------------------------------------------- + */ + btqosnull = &reserved_page_packet[BT_QOS_NULL_PG * 128]; + SET_80211_HDR_ADDRESS1(btqosnull, mac->bssid); + SET_80211_HDR_ADDRESS2(btqosnull, mac->mac_addr); + SET_80211_HDR_ADDRESS3(btqosnull, mac->bssid); + + SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1_rsvd_page_loc, + BT_QOS_NULL_PG); + + totalpacketlen = TOTAL_RESERVED_PKT_LEN; + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + &reserved_page_packet[0], totalpacketlen); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, + "rtl8822be_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + u1_rsvd_page_loc, 3); + + skb = dev_alloc_skb(totalpacketlen); + memcpy((u8 *)skb_put(skb, totalpacketlen), &reserved_page_packet, + totalpacketlen); + + rtstatus = _rtl8822be_send_bcn_or_cmd_packet(hw, skb, BEACON_QUEUE); + + if (rtstatus) + b_dlok = true; + + if (b_dlok) { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw.\n"); + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C_RSVDPAGE:\n", + u1_rsvd_page_loc, 3); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_RSVDPAGE, + sizeof(u1_rsvd_page_loc), + u1_rsvd_page_loc); + } else + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Set RSVD page location to Fw FAIL!!!!!!.\n"); +} + +/* Should check FW support p2p or not. */ +static void rtl8822be_set_p2p_ctw_period_cmd(struct ieee80211_hw *hw, + u8 ctwindow) +{ + u8 u1_ctwindow_period[1] = {ctwindow}; + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_CTW_CMD, 1, + u1_ctwindow_period); +} + +void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_p2p_ps_info *p2pinfo = &rtlps->p2p_ps_info; + struct p2p_ps_offload_t *p2p_ps_offload = &rtlhal->p2p_ps_offload; + u8 i; + u16 ctwindow; + u32 start_time, tsf_low; + + switch (p2p_ps_state) { + case P2P_PS_DISABLE: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); + memset(p2p_ps_offload, 0, sizeof(*p2p_ps_offload)); + break; + case P2P_PS_ENABLE: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); + /* update CTWindow value. */ + if (p2pinfo->ctwindow > 0) { + p2p_ps_offload->ctwindow_en = 1; + ctwindow = p2pinfo->ctwindow; + rtl8822be_set_p2p_ctw_period_cmd(hw, ctwindow); + } + /* hw only support 2 set of NoA */ + for (i = 0; i < p2pinfo->noa_num; i++) { + /* To control the register setting for which NOA*/ + rtl_write_byte(rtlpriv, 0x5cf, (i << 4)); + if (i == 0) + p2p_ps_offload->noa0_en = 1; + else + p2p_ps_offload->noa1_en = 1; + /* config P2P NoA Descriptor Register */ + rtl_write_dword(rtlpriv, 0x5E0, + p2pinfo->noa_duration[i]); + rtl_write_dword(rtlpriv, 0x5E4, + p2pinfo->noa_interval[i]); + + /*Get Current TSF value */ + tsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B); + + start_time = p2pinfo->noa_start_time[i]; + if (p2pinfo->noa_count_type[i] != 1) { + while (start_time <= (tsf_low + (50 * 1024))) { + start_time += p2pinfo->noa_interval[i]; + if (p2pinfo->noa_count_type[i] != 255) + p2pinfo->noa_count_type[i]--; + } + } + rtl_write_dword(rtlpriv, 0x5E8, start_time); + rtl_write_dword(rtlpriv, 0x5EC, + p2pinfo->noa_count_type[i]); + } + if ((p2pinfo->opp_ps == 1) || (p2pinfo->noa_num > 0)) { + /* rst p2p circuit */ + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, BIT(4)); + p2p_ps_offload->offload_en = 1; + + if (rtlpriv->mac80211.p2p == P2P_ROLE_GO) { + p2p_ps_offload->role = 1; + p2p_ps_offload->allstasleep = 0; + } else { + p2p_ps_offload->role = 0; + } + p2p_ps_offload->discovery = 0; + } + break; + case P2P_PS_SCAN: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); + p2p_ps_offload->discovery = 1; + break; + case P2P_PS_SCAN_DONE: + RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); + p2p_ps_offload->discovery = 0; + p2pinfo->p2p_ps_state = P2P_PS_ENABLE; + break; + default: + break; + } + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_P2P_PS_OFFLOAD, 1, + (u8 *)p2p_ps_offload); +} + +static +void rtl8822be_c2h_content_parsing_ext(struct ieee80211_hw *hw, + u8 c2h_sub_cmd_id, + u8 c2h_cmd_len, + u8 *c2h_content_buf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_halmac_ops *halmac_ops; + + switch (c2h_sub_cmd_id) { + case 0x0F: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_TX_REPORT!\n"); + rtl_tx_report_handler(hw, c2h_content_buf, c2h_cmd_len); + break; + default: + /* indicate c2h pkt + rx desc to halmac */ + halmac_ops = rtlpriv->halmac.ops; + halmac_ops->halmac_c2h_handle(rtlpriv, + c2h_content_buf - 24 - 2 - 2, + c2h_cmd_len + 24 + 2 + 2); + break; + } +} + +void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id, + u8 c2h_cmd_len, u8 *tmp_buf) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_btc_ops *btc_ops = rtlpriv->btcoexist.btc_ops; + + if (c2h_cmd_id == 0xFF) { + rtl8822be_c2h_content_parsing_ext(hw, tmp_buf[0], + c2h_cmd_len - 2, + tmp_buf + 2); + return; + } + + switch (c2h_cmd_id) { + case C2H_8822B_DBG: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_DBG!!\n"); + break; + case C2H_8822B_TXBF: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822B_TXBF!!\n"); + break; + case C2H_8822B_BT_INFO: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_BT_INFO!!\n"); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf, + c2h_cmd_len); + break; + case C2H_8822B_BT_MP: + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_8822BE_BT_MP!!\n"); + if (rtlpriv->cfg->ops->get_btc_status()) + btc_ops->btc_btmpinfo_notify(rtlpriv, tmp_buf, + c2h_cmd_len); + break; + default: + if (!rtlpriv->phydm.ops->phydm_c2h_content_parsing( + rtlpriv, c2h_cmd_id, c2h_cmd_len, tmp_buf)) + break; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], Unknown packet!! CmdId(%#X)!\n", c2h_cmd_id); + break; + } +} + +void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 c2h_cmd_id = 0, c2h_cmd_seq = 0, c2h_cmd_len = 0; + u8 *tmp_buf = NULL; + + c2h_cmd_id = buffer[0]; + c2h_cmd_seq = buffer[1]; + c2h_cmd_len = len - 2; + tmp_buf = buffer + 2; + + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H packet], c2hCmdId=0x%x, c2hCmdSeq=0x%x, c2hCmdLen=%d\n", + c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len); + + RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len); + + switch (c2h_cmd_id) { + case C2H_8822B_BT_INFO: + case C2H_8822B_BT_MP: + rtl_c2hcmd_enqueue(hw, c2h_cmd_id, c2h_cmd_len, tmp_buf); + break; + default: + rtl8822be_c2h_content_parsing(hw, c2h_cmd_id, c2h_cmd_len, + tmp_buf); + break; + } +} diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.h b/drivers/staging/rtlwifi/rtl8822be/fw.h new file mode 100644 index 000000000000..3ad7a66e80a3 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/fw.h @@ -0,0 +1,198 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B__FW__H__ +#define __RTL8822B__FW__H__ + +#define USE_OLD_WOWLAN_DEBUG_FW 0 + +#define H2C_8822B_RSVDPAGE_LOC_LEN 5 +#define H2C_8822B_PWEMODE_LENGTH 7 +#define H2C_8822B_JOINBSSRPT_LENGTH 1 +#define H2C_8822B_AP_OFFLOAD_LENGTH 3 +#define H2C_8822B_WOWLAN_LENGTH 3 +#define H2C_8822B_KEEP_ALIVE_CTRL_LENGTH 3 +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) +#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 1 +#else +#define H2C_8822B_REMOTE_WAKE_CTRL_LEN 3 +#endif +#define H2C_8822B_AOAC_GLOBAL_INFO_LEN 2 +#define H2C_8822B_AOAC_RSVDPAGE_LOC_LEN 7 +#define H2C_DEFAULT_PORT_ID_LEN 2 + +/* Fw PS state for RPWM. + *BIT[2:0] = HW state + *BIT[3] = Protocol PS state, 1: register active state, 0: register sleep state + *BIT[4] = sub-state + */ +#define FW_PS_RF_ON BIT(2) +#define FW_PS_REGISTER_ACTIVE BIT(3) + +#define FW_PS_ACK BIT(6) +#define FW_PS_TOGGLE BIT(7) + +/* 8822B RPWM value*/ +/* BIT[0] = 1: 32k, 0: 40M*/ +#define FW_PS_CLOCK_OFF BIT(0) /* 32k */ +#define FW_PS_CLOCK_ON 0 /* 40M */ + +#define FW_PS_STATE_MASK (0x0F) +#define FW_PS_STATE_HW_MASK (0x07) +#define FW_PS_STATE_INT_MASK (0x3F) + +#define FW_PS_STATE(x) (FW_PS_STATE_MASK & (x)) + +#define FW_PS_STATE_ALL_ON_8822B (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_ON_8822B (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_OFF_8822B (FW_PS_CLOCK_ON) +#define FW_PS_STATE_RF_OFF_LOW_PWR (FW_PS_CLOCK_OFF) + +/* For 8822B H2C PwrMode Cmd ID 5.*/ +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +#define FW_PS_IS_ACK(x) ((x) & FW_PS_ACK) + +#define IS_IN_LOW_POWER_STATE_8822B(fw_ps_state) \ + (FW_PS_STATE(fw_ps_state) == FW_PS_CLOCK_OFF) + +#define FW_PWR_STATE_ACTIVE ((FW_PS_RF_ON) | (FW_PS_REGISTER_ACTIVE)) +#define FW_PWR_STATE_RF_OFF 0 + +enum rtl8822b_h2c_cmd { + H2C_8822B_RSVDPAGE = 0, + H2C_8822B_MSRRPT = 1, + H2C_8822B_SCAN = 2, + H2C_8822B_KEEP_ALIVE_CTRL = 3, + H2C_8822B_DISCONNECT_DECISION = 4, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_8822B_WO_WLAN = 5, +#endif + H2C_8822B_INIT_OFFLOAD = 6, +#if (USE_OLD_WOWLAN_DEBUG_FW == 1) + H2C_8822B_REMOTE_WAKE_CTRL = 7, +#endif + H2C_8822B_AP_OFFLOAD = 8, + H2C_8822B_BCN_RSVDPAGE = 9, + H2C_8822B_PROBERSP_RSVDPAGE = 10, + + H2C_8822B_SETPWRMODE = 0x20, + H2C_8822B_PS_TUNING_PARA = 0x21, + H2C_8822B_PS_TUNING_PARA2 = 0x22, + H2C_8822B_PS_LPS_PARA = 0x23, + H2C_8822B_P2P_PS_OFFLOAD = 024, + H2C_8822B_DEFAULT_PORT_ID = 0x2C, + +#if (USE_OLD_WOWLAN_DEBUG_FW == 0) + H2C_8822B_WO_WLAN = 0x80, + H2C_8822B_REMOTE_WAKE_CTRL = 0x81, + H2C_8822B_AOAC_GLOBAL_INFO = 0x82, + H2C_8822B_AOAC_RSVDPAGE = 0x83, +#endif + H2C_8822B_MACID_CFG = 0x40, + H2C_8822B_RSSI_REPORT = 0x42, + H2C_8822B_MACID_CFG_3SS = 0x46, + /*Not defined CTW CMD for P2P yet*/ + H2C_8822B_P2P_PS_CTW_CMD = 0x99, + MAX_8822B_H2CCMD +}; + +enum rtl8822b_c2h_evt { + C2H_8822B_DBG = 0x00, + C2H_8822B_LB = 0x01, + C2H_8822B_TXBF = 0x02, + C2H_8822B_TX_REPORT = 0x03, + C2H_8822B_BT_INFO = 0x09, + C2H_8822B_BT_MP = 0x0B, + C2H_8822B_RA_RPT = 0x0C, + MAX_8822B_C2HEVENT +}; + +/* H2C: 0x20 */ +#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 7, __val) +#define SET_H2CCMD_PWRMODE_PARM_CLK_REQ(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 7, 1, __val) +#define SET_H2CCMD_PWRMODE_PARM_RLBM(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 4, __val) +#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 4, 4, __val) +#define SET_H2CCMD_PWRMODE_PARM_AWAKE_INTERVAL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 1, __val) +#define SET_H2CCMD_PWRMODE_PARM_BCN_EARLY_RPT(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 2, 1, __val) +#define SET_H2CCMD_PWRMODE_PARM_PORT_ID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 5, 3, __val) +#define SET_H2CCMD_PWRMODE_PARM_PWR_STATE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val) +#define SET_H2CCMD_PWRMODE_PARM_BYTE5(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 5, 0, 8, __val) + +/* H2C: 0x00 */ +#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 1, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 2, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 3, 0, 8, __val) +#define SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE((__ph2ccmd) + 4, 0, 8, __val) + +/* H2C: 0x01 */ +#define SET_H2CCMD_MSRRPT_PARM_OPMODE(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 1, __val) +#define SET_H2CCMD_MSRRPT_PARM_MACID_IND(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd, 1, 1, __val) +#define SET_H2CCMD_MSRRPT_PARM_MACID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd + 1, 0, 8, __val) +#define SET_H2CCMD_MSRRPT_PARM_MACID_END(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(__ph2ccmd + 2, 0, 8, __val) + +/* H2C: 0x2C */ +#define SET_H2CCMD_DFTPID_PORT_ID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)), 0, 8, (__val)) +#define SET_H2CCMD_DFTPID_MAC_ID(__ph2ccmd, __val) \ + SET_BITS_TO_LE_1BYTE(((u8 *)(__ph2ccmd)) + 1, 0, 8, (__val)) + +void rtl8822be_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, + u8 *cmdbuffer); +void rtl8822be_set_default_port_id_cmd(struct ieee80211_hw *hw); +void rtl8822be_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); +void rtl8822be_set_fw_media_status_rpt_cmd(struct ieee80211_hw *hw, u8 mstatus); +void rtl8822be_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); +void rtl8822be_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state); +void rtl8822be_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len); +void rtl8822be_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id, + u8 c2h_cmd_len, u8 *tmp_buf); +bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf, + u32 size); +bool rtl8822b_halmac_cb_write_data_h2c(struct rtl_priv *rtlpriv, u8 *buf, + u32 size); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/hw.c b/drivers/staging/rtlwifi/rtl8822be/hw.c new file mode 100644 index 000000000000..74386003044f --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/hw.c @@ -0,0 +1,2441 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../efuse.h" +#include "../base.h" +#include "../regd.h" +#include "../cam.h" +#include "../ps.h" +#include "../pci.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "fw.h" +#include "led.h" +#include "hw.h" + +#define LLT_CONFIG 5 + +u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ +u8 rtl_channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, + 138, 155, 171}; + +static void _rtl8822be_set_bcn_ctrl_reg(struct ieee80211_hw *hw, u8 set_bits, + u8 clear_bits) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpci->reg_bcn_ctrl_val |= set_bits; + rtlpci->reg_bcn_ctrl_val &= ~clear_bits; + + rtl_write_byte(rtlpriv, REG_BCN_CTRL_8822B, + (u8)rtlpci->reg_bcn_ctrl_val); +} + +static void _rtl8822be_stop_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, tmp & (~BIT(6))); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 1, 0x64); + tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2, tmp); +} + +static void _rtl8822be_resume_tx_beacon(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp; + + tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, tmp | BIT(6)); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 1, 0xff); + tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT_8822B + 2, tmp); +} + +static void _rtl8822be_enable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(1)); +} + +static void _rtl8822be_disable_bcn_sub_func(struct ieee80211_hw *hw) +{ + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(1), 0); +} + +static void _rtl8822be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val, + bool b_need_turn_off_ckk) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 count = 0, isr_regaddr, content; + bool b_schedule_timer = b_need_turn_off_ckk; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + + while (1) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (rtlhal->fw_clk_change_in_progress) { + while (rtlhal->fw_clk_change_in_progress) { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + count++; + udelay(100); + if (count > 1000) + return; + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + } + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + break; + } + } + + if (IS_IN_LOW_POWER_STATE_8822B(rtlhal->fw_ps_state)) { + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + if (FW_PS_IS_ACK(rpwm_val)) { + isr_regaddr = REG_HISR0_8822B; + content = rtl_read_dword(rtlpriv, isr_regaddr); + while (!(content & IMR_CPWM) && (count < 500)) { + udelay(50); + count++; + content = rtl_read_dword(rtlpriv, isr_regaddr); + } + + if (content & IMR_CPWM) { + rtl_write_word(rtlpriv, isr_regaddr, 0x0100); + rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_8822B; + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Receive CPWM INT!!! PSState = %X\n", + rtlhal->fw_ps_state); + } + } + + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + + } else { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } +} + +static void _rtl8822be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring; + enum rf_pwrstate rtstate; + bool b_schedule_timer = false; + u8 queue; + + if (!rtlhal->fw_ready) + return; + if (!rtlpriv->psc.fw_current_inpsmode) + return; + if (!rtlhal->allow_sw_to_change_hwclc) + return; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); + if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) + return; + + for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { + ring = &rtlpci->tx_ring[queue]; + if (skb_queue_len(&ring->queue)) { + b_schedule_timer = true; + break; + } + } + + if (b_schedule_timer) { + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + return; + } + + if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) { + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + if (!rtlhal->fw_clk_change_in_progress) { + rtlhal->fw_clk_change_in_progress = true; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); + rtl_write_word(rtlpriv, REG_HISR0_8822B, 0x0100); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + spin_lock_bh(&rtlpriv->locks.fw_ps_lock); + rtlhal->fw_clk_change_in_progress = false; + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + } else { + spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); + mod_timer(&rtlpriv->works.fw_clockoff_timer, + jiffies + MSECS(10)); + } + } +} + +static void _rtl8822be_set_fw_ps_rf_on(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= (FW_PS_STATE_RF_OFF_8822B | FW_PS_ACK); + _rtl8822be_set_fw_clock_on(hw, rpwm_val, true); +} + +static void _rtl8822be_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw) +{ + u8 rpwm_val = 0; + + rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR; + _rtl8822be_set_fw_clock_off(hw, rpwm_val); +} + +void rtl8822be_fw_clk_off_timer_callback(unsigned long data) +{ + struct ieee80211_hw *hw = (struct ieee80211_hw *)data; + + _rtl8822be_set_fw_ps_rf_off_low_power(hw); +} + +static void _rtl8822be_fwlps_leave(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = false; + u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; + + if (ppsc->low_power_enable) { + rpwm_val = (FW_PS_STATE_ALL_ON_8822B | FW_PS_ACK); /* RF on */ + _rtl8822be_set_fw_clock_on(hw, rpwm_val, false); + rtlhal->allow_sw_to_change_hwclc = false; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } else { + rpwm_val = FW_PS_STATE_ALL_ON_8822B; /* RF on */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&fw_pwrmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + } +} + +static void _rtl8822be_fwlps_enter(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + bool fw_current_inps = true; + u8 rpwm_val; + + if (ppsc->low_power_enable) { + rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlhal->allow_sw_to_change_hwclc = true; + _rtl8822be_set_fw_clock_off(hw, rpwm_val); + } else { + rpwm_val = FW_PS_STATE_RF_OFF_8822B; /* RF off */ + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, + (u8 *)(&fw_current_inps)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, + (u8 *)(&ppsc->fwctrl_psmode)); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, + (u8 *)(&rpwm_val)); + } +} + +void rtl8822be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + switch (variable) { + case HW_VAR_RCR: + *((u32 *)(val)) = rtlpci->receive_config; + break; + case HW_VAR_RF_STATE: + *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; + break; + case HW_VAR_FWLPS_RF_ON: { + enum rf_pwrstate rf_state; + u32 val_rcr; + + rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, + (u8 *)(&rf_state)); + if (rf_state == ERFOFF) { + *((bool *)(val)) = true; + } else { + val_rcr = rtl_read_dword(rtlpriv, REG_RCR_8822B); + val_rcr &= 0x00070000; + if (val_rcr) + *((bool *)(val)) = false; + else + *((bool *)(val)) = true; + } + } break; + case HW_VAR_FW_PSMODE_STATUS: + *((bool *)(val)) = ppsc->fw_current_inpsmode; + break; + case HW_VAR_CORRECT_TSF: { + u64 tsf; + u32 *ptsf_low = (u32 *)&tsf; + u32 *ptsf_high = ((u32 *)&tsf) + 1; + + *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR_8822B + 4)); + *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR_8822B); + + *((u64 *)(val)) = tsf; + + } break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case not process %x\n", variable); + break; + } +} + +static void _rtl8822be_download_rsvd_page(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 tmp_regcr, tmp_reg422; + u8 bcnvalid_reg /*, txbc_reg*/; + u8 count = 0, dlbcn_count = 0; + bool b_recover = false; + + /*Set REG_CR_8822B bit 8. DMA beacon by SW.*/ + tmp_regcr = rtl_read_byte(rtlpriv, REG_CR_8822B + 1); + rtl_write_byte(rtlpriv, REG_CR_8822B + 1, tmp_regcr | BIT(0)); + + /* Disable Hw protection for a time which revserd for Hw sending beacon. + * Fix download reserved page packet fail + * that access collision with the protection time. + * 2010.05.11. Added by tynli. + */ + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(3)); + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(4), 0); + + /* Set FWHW_TXQ_CTRL 0x422[6]=0 to + * tell Hw the packet is not a real beacon frame. + */ + tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, + tmp_reg422 & (~BIT(6))); + + if (tmp_reg422 & BIT(6)) + b_recover = true; + + do { + /* Clear beacon valid check bit */ + bcnvalid_reg = + rtl_read_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1); + bcnvalid_reg = bcnvalid_reg | BIT(7); + rtl_write_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1, + bcnvalid_reg); + + /* download rsvd page */ + rtl8822be_set_fw_rsvdpagepkt(hw, false); + + /* check rsvd page download OK. */ + bcnvalid_reg = + rtl_read_byte(rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1); + + count = 0; + while (!(BIT(7) & bcnvalid_reg) && count < 20) { + count++; + udelay(50); + bcnvalid_reg = rtl_read_byte( + rtlpriv, REG_FIFOPAGE_CTRL_2_8822B + 1); + } + + dlbcn_count++; + } while (!(BIT(7) & bcnvalid_reg) && dlbcn_count < 5); + + if (!(BIT(7) & bcnvalid_reg)) + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, + "Download RSVD page failed!\n"); + + /* Enable Bcn */ + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0); + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(4)); + + if (b_recover) + rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL_8822B + 2, + tmp_reg422); +} + +void rtl8822be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *efuse = rtl_efuse(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + switch (variable) { + case HW_VAR_ETHER_ADDR: + rtlpriv->halmac.ops->halmac_set_mac_address(rtlpriv, 0, val); + break; + case HW_VAR_BASIC_RATE: { + u16 b_rate_cfg = ((u16 *)val)[0]; + + b_rate_cfg = b_rate_cfg & 0x15f; + b_rate_cfg |= 0x01; + b_rate_cfg = (b_rate_cfg | 0xd) & (~BIT(1)); + rtl_write_byte(rtlpriv, REG_RRSR_8822B, b_rate_cfg & 0xff); + rtl_write_byte(rtlpriv, REG_RRSR_8822B + 1, + (b_rate_cfg >> 8) & 0xff); + } break; + case HW_VAR_BSSID: + rtlpriv->halmac.ops->halmac_set_bssid(rtlpriv, 0, val); + break; + case HW_VAR_SIFS: + rtl_write_byte(rtlpriv, REG_SIFS_8822B + 1, val[0]); + rtl_write_byte(rtlpriv, REG_SIFS_TRX_8822B + 1, val[1]); + + rtl_write_byte(rtlpriv, REG_SPEC_SIFS_8822B + 1, val[0]); + rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS_8822B + 1, val[0]); + + if (!mac->ht_enable) + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM_8822B, + 0x0e0e); + else + rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM_8822B, + *((u16 *)val)); + break; + case HW_VAR_SLOT_TIME: { + u8 e_aci; + + RT_TRACE(rtlpriv, COMP_MLME, DBG_TRACE, "HW_VAR_SLOT_TIME %x\n", + val[0]); + + rtl_write_byte(rtlpriv, REG_SLOT_8822B, val[0]); + + for (e_aci = 0; e_aci < AC_MAX; e_aci++) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, + (u8 *)(&e_aci)); + } + } break; + case HW_VAR_ACK_PREAMBLE: { + u8 reg_tmp; + u8 short_preamble = (bool)(*(u8 *)val); + + reg_tmp = (rtlpriv->mac80211.cur_40_prime_sc) << 5; + if (short_preamble) + reg_tmp |= 0x80; + rtl_write_byte(rtlpriv, REG_RRSR_8822B + 2, reg_tmp); + rtlpriv->mac80211.short_preamble = short_preamble; + } break; + case HW_VAR_WPA_CONFIG: + rtl_write_byte(rtlpriv, REG_SECCFG_8822B, *((u8 *)val)); + break; + case HW_VAR_AMPDU_FACTOR: { + u32 ampdu_len = (*((u8 *)val)); + + ampdu_len = (0x2000 << ampdu_len) - 1; + rtl_write_dword(rtlpriv, REG_AMPDU_MAX_LENGTH_8822B, ampdu_len); + } break; + case HW_VAR_AC_PARAM: { + u8 e_aci = *((u8 *)val); + + if (mac->vif && mac->vif->bss_conf.assoc && !mac->act_scanning) + rtl8822be_set_qos(hw, e_aci); + + if (rtlpci->acm_method != EACMWAY2_SW) + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, + (u8 *)(&e_aci)); + } break; + case HW_VAR_ACM_CTRL: { + u8 e_aci = *((u8 *)val); + union aci_aifsn *aifs = (union aci_aifsn *)&mac->ac[0].aifs; + + u8 acm = aifs->f.acm; + u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL_8822B); + + acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); + + if (acm) { + switch (e_aci) { + case AC0_BE: + acm_ctrl |= ACMHW_BEQ_EN; + break; + case AC2_VI: + acm_ctrl |= ACMHW_VIQ_EN; + break; + case AC3_VO: + acm_ctrl |= ACMHW_VOQ_EN; + break; + default: + RT_TRACE( + rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); + break; + } + } else { + switch (e_aci) { + case AC0_BE: + acm_ctrl &= (~ACMHW_BEQ_EN); + break; + case AC2_VI: + acm_ctrl &= (~ACMHW_VIQ_EN); + break; + case AC3_VO: + acm_ctrl &= (~ACMHW_VOQ_EN); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case not process\n"); + break; + } + } + + RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); + rtl_write_byte(rtlpriv, REG_ACMHWCTRL_8822B, acm_ctrl); + } break; + case HW_VAR_RCR: { + rtl_write_dword(rtlpriv, REG_RCR_8822B, ((u32 *)(val))[0]); + rtlpci->receive_config = ((u32 *)(val))[0]; + } break; + case HW_VAR_RETRY_LIMIT: { + u8 retry_limit = ((u8 *)(val))[0]; + + rtl_write_word(rtlpriv, REG_RETRY_LIMIT_8822B, + retry_limit << RETRY_LIMIT_SHORT_SHIFT | + retry_limit << RETRY_LIMIT_LONG_SHIFT); + } break; + case HW_VAR_DUAL_TSF_RST: + rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST_8822B, + (BIT(0) | BIT(1))); + break; + case HW_VAR_EFUSE_BYTES: + efuse->efuse_usedbytes = *((u16 *)val); + break; + case HW_VAR_EFUSE_USAGE: + efuse->efuse_usedpercentage = *((u8 *)val); + break; + case HW_VAR_IO_CMD: + rtl8822be_phy_set_io_cmd(hw, (*(enum io_type *)val)); + break; + case HW_VAR_SET_RPWM: + break; + case HW_VAR_H2C_FW_PWRMODE: + rtl8822be_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_FW_PSMODE_STATUS: + ppsc->fw_current_inpsmode = *((bool *)val); + break; + case HW_VAR_RESUME_CLK_ON: + _rtl8822be_set_fw_ps_rf_on(hw); + break; + case HW_VAR_FW_LPS_ACTION: { + bool b_enter_fwlps = *((bool *)val); + + if (b_enter_fwlps) + _rtl8822be_fwlps_enter(hw); + else + _rtl8822be_fwlps_leave(hw); + } break; + case HW_VAR_H2C_FW_JOINBSSRPT: { + u8 mstatus = (*(u8 *)val); + + if (mstatus == RT_MEDIA_CONNECT) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); + _rtl8822be_download_rsvd_page(hw); + } + rtl8822be_set_default_port_id_cmd(hw); + rtl8822be_set_fw_media_status_rpt_cmd(hw, mstatus); + } break; + case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: + rtl8822be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); + break; + case HW_VAR_AID: { + u16 u2btmp; + + u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT_8822B); + u2btmp &= 0xC000; + rtl_write_word(rtlpriv, REG_BCN_PSR_RPT_8822B, + (u2btmp | mac->assoc_id)); + } break; + case HW_VAR_CORRECT_TSF: { + u8 btype_ibss = ((u8 *)(val))[0]; + + if (btype_ibss) + _rtl8822be_stop_tx_beacon(hw); + + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(3)); + + rtl_write_dword(rtlpriv, REG_TSFTR_8822B, + (u32)(mac->tsf & 0xffffffff)); + rtl_write_dword(rtlpriv, REG_TSFTR_8822B + 4, + (u32)((mac->tsf >> 32) & 0xffffffff)); + + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0); + + if (btype_ibss) + _rtl8822be_resume_tx_beacon(hw); + } break; + case HW_VAR_KEEP_ALIVE: { + u8 array[2]; + + array[0] = 0xff; + array[1] = *((u8 *)val); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_KEEP_ALIVE_CTRL, 2, array); + } break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, + "switch case not process %x\n", variable); + break; + } +} + +static void _rtl8822be_gen_refresh_led_state(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_led *led0 = &pcipriv->ledctl.sw_led0; + + if (rtlpriv->rtlhal.up_first_time) + return; + + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) + rtl8822be_sw_led_on(hw, led0); + else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) + rtl8822be_sw_led_on(hw, led0); + else + rtl8822be_sw_led_off(hw, led0); +} + +static bool _rtl8822be_init_trxbd(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + /*struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));*/ + + u8 bytetmp; + /*u16 wordtmp;*/ + u32 dwordtmp; + + /* Set TX/RX descriptor physical address -- HI part */ + if (!rtlpriv->cfg->mod_params->dma64) + goto dma64_end; + + rtl_write_dword(rtlpriv, REG_H2CQ_TXBD_DESA_8822B + 4, + ((u64)rtlpci->tx_ring[H2C_QUEUE].buffer_desc_dma) >> + 32); + rtl_write_dword(rtlpriv, REG_BCNQ_TXBD_DESA_8822B + 4, + ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) >> + 32); + rtl_write_dword(rtlpriv, REG_MGQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_VOQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_VIQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_BKQ_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma >> 32); + rtl_write_dword(rtlpriv, REG_HI0Q_TXBD_DESA_8822B + 4, + (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma >> 32); + + rtl_write_dword(rtlpriv, REG_RXQ_RXBD_DESA_8822B + 4, + (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma >> 32); + +dma64_end: + /* Set TX/RX descriptor physical address(from OS API). */ + rtl_write_dword(rtlpriv, REG_H2CQ_TXBD_DESA_8822B, + ((u64)rtlpci->tx_ring[H2C_QUEUE].buffer_desc_dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BCNQ_TXBD_DESA_8822B, + ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_MGQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VOQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_VIQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + dwordtmp = rtl_read_dword(rtlpriv, REG_BEQ_TXBD_DESA_8822B); /* need? */ + rtl_write_dword(rtlpriv, REG_BKQ_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + rtl_write_dword(rtlpriv, REG_HI0Q_TXBD_DESA_8822B, + (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma & + DMA_BIT_MASK(32)); + + rtl_write_dword(rtlpriv, REG_RXQ_RXBD_DESA_8822B, + (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma & + DMA_BIT_MASK(32)); + + /* Reset R/W point */ + rtl_write_dword(rtlpriv, REG_BD_RWPTR_CLR_8822B, 0x3fffffff); + + /* Reset the H2CQ R/W point index to 0 */ + dwordtmp = rtl_read_dword(rtlpriv, REG_H2CQ_CSR_8822B); + rtl_write_dword(rtlpriv, REG_H2CQ_CSR_8822B, + (dwordtmp | BIT(8) | BIT(16))); + + bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 3); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 3, bytetmp | 0xF7); + + rtl_write_dword(rtlpriv, REG_INT_MIG_8822B, 0); + + rtl_write_dword(rtlpriv, REG_MCUTST_I_8822B, 0x0); + + rtl_write_word(rtlpriv, REG_H2CQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_MGQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VIQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_BEQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_BKQ_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI0Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI1Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI2Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI3Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI4Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI5Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI6Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + rtl_write_word(rtlpriv, REG_HI7Q_TXBD_NUM_8822B, + TX_DESC_NUM_8822B | + ((RTL8822BE_SEG_NUM << 12) & 0x3000)); + /*Rx*/ + rtl_write_word(rtlpriv, REG_RX_RXBD_NUM_8822B, + RX_DESC_NUM_8822BE | + ((RTL8822BE_SEG_NUM << 13) & 0x6000) | 0x8000); + + rtl_write_dword(rtlpriv, REG_BD_RWPTR_CLR_8822B, 0XFFFFFFFF); + + _rtl8822be_gen_refresh_led_state(hw); + + return true; +} + +static void _rtl8822be_enable_aspm_back_door(struct ieee80211_hw *hw) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 tmp; + + if (!ppsc->support_backdoor) + return; + + pci_read_config_byte(rtlpci->pdev, 0x70f, &tmp); + pci_write_config_byte(rtlpci->pdev, 0x70f, tmp | BIT(7)); + + pci_read_config_byte(rtlpci->pdev, 0x719, &tmp); + pci_write_config_byte(rtlpci->pdev, 0x719, tmp | BIT(3) | BIT(4)); +} + +void rtl8822be_enable_hw_security_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 sec_reg_value; + u8 tmp; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); + + if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); + return; + } + + sec_reg_value = SCR_TX_ENC_ENABLE | SRC_RX_DEC_ENABLE; + + if (rtlpriv->sec.use_defaultkey) { + sec_reg_value |= SCR_TX_USE_DK; + sec_reg_value |= SCR_RX_USE_DK; + } + + sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); + + tmp = rtl_read_byte(rtlpriv, REG_CR_8822B + 1); + rtl_write_byte(rtlpriv, REG_CR_8822B + 1, tmp | BIT(1)); + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "The SECR-value %x\n", + sec_reg_value); + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); +} + +static bool _rtl8822be_check_pcie_dma_hang(struct rtl_priv *rtlpriv) +{ + u8 tmp; + + /* write reg 0x350 Bit[26]=1. Enable debug port. */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3); + if (!(tmp & BIT(2))) { + rtl_write_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3, + (tmp | BIT(2))); + mdelay(100); /* Suggested by DD Justin_tsai. */ + } + + /* read reg 0x350 Bit[25] if 1 : RX hang + * read reg 0x350 Bit[24] if 1 : TX hang + */ + tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG_V1_8822B + 3); + if ((tmp & BIT(0)) || (tmp & BIT(1))) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "CheckPcieDMAHang8822BE(): true!!\n"); + return true; + } else { + return false; + } +} + +static void _rtl8822be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv, + bool mac_power_on) +{ + u8 tmp; + bool release_mac_rx_pause; + u8 backup_pcie_dma_pause; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "ResetPcieInterfaceDMA8822BE()\n"); + + /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03" + * released by SD1 Alan. + * 2013.05.07, by tynli. + */ + + /* 1. disable register write lock + * write 0x1C bit[1:0] = 2'h0 + * write 0xCC bit[2] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL_8822B); + tmp &= ~(BIT(1) | BIT(0)); + rtl_write_byte(rtlpriv, REG_RSV_CTRL_8822B, tmp); + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B); + tmp |= BIT(2); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B, tmp); + + /* 2. Check and pause TRX DMA + * write 0x284 bit[18] = 1'b1 + * write 0x301 = 0xFF + */ + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL_8822B); + if (tmp & BIT(2)) { + /* Already pause before the function for another purpose. */ + release_mac_rx_pause = false; + } else { + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL_8822B, + (tmp | BIT(2))); + release_mac_rx_pause = true; + } + + backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1); + if (backup_pcie_dma_pause != 0xFF) + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1, 0xFF); + + if (mac_power_on) { + /* 3. reset TRX function + * write 0x100 = 0x00 + */ + rtl_write_byte(rtlpriv, REG_CR_8822B, 0); + } + + /* 4. Reset PCIe DMA + * write 0x003 bit[0] = 0 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1); + tmp &= ~(BIT(0)); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1, tmp); + + /* 5. Enable PCIe DMA + * write 0x003 bit[0] = 1 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1); + tmp |= BIT(0); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B + 1, tmp); + + if (mac_power_on) { + /* 6. enable TRX function + * write 0x100 = 0xFF + */ + rtl_write_byte(rtlpriv, REG_CR_8822B, 0xFF); + + /* We should init LLT & RQPN and + * prepare Tx/Rx descrptor address later + * because MAC function is reset. + */ + } + + /* 7. Restore PCIe autoload down bit + * write 0xF8 bit[17] = 1'b1 + */ + tmp = rtl_read_byte(rtlpriv, REG_SYS_STATUS2_8822B + 2); + tmp |= BIT(1); + rtl_write_byte(rtlpriv, REG_SYS_STATUS2_8822B + 2, tmp); + + /* In MAC power on state, BB and RF maybe in ON state, + * if we release TRx DMA here + * it will cause packets to be started to Tx/Rx, + * so we release Tx/Rx DMA later. + */ + if (!mac_power_on) { + /* 8. release TRX DMA + * write 0x284 bit[18] = 1'b0 + * write 0x301 = 0x00 + */ + if (release_mac_rx_pause) { + tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL_8822B); + rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL_8822B, + (tmp & (~BIT(2)))); + } + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 1, + backup_pcie_dma_pause); + } + + /* 9. lock system register + * write 0xCC bit[2] = 1'b0 + */ + tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B); + tmp &= ~(BIT(2)); + rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2_8822B, tmp); +} + +int rtl8822be_hw_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + int err = 0; + u8 tmp_u1b; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, " Rtl8822BE hw init\n"); + rtlpriv->rtlhal.being_init_adapter = true; + rtlpriv->intf_ops->disable_aspm(hw); + + if (_rtl8822be_check_pcie_dma_hang(rtlpriv)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "8822be dma hang!\n"); + _rtl8822be_reset_pcie_interface_dma(rtlpriv, + rtlhal->mac_func_enable); + rtlhal->mac_func_enable = false; + } + + /* init TRX BD */ + _rtl8822be_init_trxbd(hw); + + /* use halmac to init */ + err = rtlpriv->halmac.ops->halmac_init_hal(rtlpriv); + if (err) { + pr_err("halmac_init_hal failed\n"); + rtlhal->fw_ready = false; + return err; + } + + rtlhal->fw_ready = true; + + /* have to init after halmac init */ + tmp_u1b = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_8822B + 2); + rtl_write_byte(rtlpriv, REG_PCIE_CTRL_8822B + 2, (tmp_u1b | BIT(4))); + + /*rtl_write_word(rtlpriv, REG_PCIE_CTRL_8822B, 0x8000);*/ + rtlhal->rx_tag = 0; + + rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ_8822B, 0x4); + + /*fw related variable initialize */ + ppsc->fw_current_inpsmode = false; + rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_8822B; + rtlhal->fw_clk_change_in_progress = false; + rtlhal->allow_sw_to_change_hwclc = false; + rtlhal->last_hmeboxnum = 0; + + rtlphy->rfreg_chnlval[0] = + rtl_get_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[1] = + rtl_get_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK); + rtlphy->backup_rf_0x1a = (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1, + RFREG_OFFSET_MASK); + rtlphy->rfreg_chnlval[0] = + (rtlphy->rfreg_chnlval[0] & 0xfffff3ff) | BIT(10) | BIT(11); + + rtlhal->mac_func_enable = true; + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv); + + /* reset cam / set security */ + rtl_cam_reset_all_entry(hw); + rtl8822be_enable_hw_security_config(hw); + + /* check RCR/ICV bit */ + rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); + rtl_write_dword(rtlpriv, REG_RCR_8822B, rtlpci->receive_config); + + /* clear rx ctrl frame */ + rtl_write_word(rtlpriv, REG_RXFLTMAP1_8822B, 0); + + ppsc->rfpwr_state = ERFON; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); + _rtl8822be_enable_aspm_back_door(hw); + rtlpriv->intf_ops->enable_aspm(hw); + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); + else + rtlpriv->btcoexist.btc_ops->btc_init_hw_config_wifi_only( + rtlpriv); + + rtlpriv->rtlhal.being_init_adapter = false; + + rtlpriv->phydm.ops->phydm_init_dm(rtlpriv); + + /* clear ISR, and IMR will be on later */ + rtl_write_dword(rtlpriv, REG_HISR0_8822B, + rtl_read_dword(rtlpriv, REG_HISR0_8822B)); + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "end of Rtl8822BE hw init %x\n", + err); + return 0; +} + +static u32 _rtl8822be_read_chip_version(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + /*enum version_8822b version = VERSION_UNKNOWN;*/ + u32 version; + u32 value32; + + rtlphy->rf_type = RF_2T2R; + + value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1_8822B); + + version = value32; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R"); + + return version; +} + +static int _rtl8822be_set_media_status(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 bt_msr = rtl_read_byte(rtlpriv, MSR); + enum led_ctl_mode ledaction = LED_CTL_NO_LINK; + u8 mode = MSR_NOLINK; + + bt_msr &= 0xfc; + + switch (type) { + case NL80211_IFTYPE_UNSPECIFIED: + mode = MSR_NOLINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); + break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + mode = MSR_ADHOC; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); + break; + case NL80211_IFTYPE_STATION: + mode = MSR_INFRA; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); + break; + case NL80211_IFTYPE_AP: + mode = MSR_AP; + ledaction = LED_CTL_LINK; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); + break; + default: + pr_err("Network type %d not support!\n", type); + return 1; + } + + /* MSR_INFRA == Link in infrastructure network; + * MSR_ADHOC == Link in ad hoc network; + * Therefore, check link state is necessary. + * + * MSR_AP == AP mode; link state is not cared here. + */ + if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) { + mode = MSR_NOLINK; + ledaction = LED_CTL_NO_LINK; + } + + if (mode == MSR_NOLINK || mode == MSR_INFRA) { + _rtl8822be_stop_tx_beacon(hw); + _rtl8822be_enable_bcn_sub_func(hw); + } else if (mode == MSR_ADHOC || mode == MSR_AP) { + _rtl8822be_resume_tx_beacon(hw); + _rtl8822be_disable_bcn_sub_func(hw); + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", + mode); + } + + rtl_write_byte(rtlpriv, (MSR), bt_msr | mode); + rtlpriv->cfg->ops->led_control(hw, ledaction); + if (mode == MSR_AP) + rtl_write_byte(rtlpriv, REG_BCNTCFG_8822B + 1, 0x00); + else + rtl_write_byte(rtlpriv, REG_BCNTCFG_8822B + 1, 0x66); + return 0; +} + +void rtl8822be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 reg_rcr = rtlpci->receive_config; + + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + _rtl8822be_set_bcn_ctrl_reg(hw, 0, BIT(4)); + } else if (!check_bssid) { + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(4), 0); + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); + } +} + +int rtl8822be_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (_rtl8822be_set_media_status(hw, type)) + return -EOPNOTSUPP; + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP && + type != NL80211_IFTYPE_MESH_POINT) + rtl8822be_set_check_bssid(hw, true); + } else { + rtl8822be_set_check_bssid(hw, false); + } + + return 0; +} + +void rtl8822be_set_qos(struct ieee80211_hw *hw, int aci) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtlpriv); + u32 ac_param; + + ac_param = rtl_get_hal_edca_param(hw, mac->vif, mac->mode, + &mac->edca_param[aci]); + + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM_8822B, ac_param); + break; + case AC0_BE: + rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM_8822B, ac_param); + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM_8822B, ac_param); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM_8822B, ac_param); + break; + default: + WARN_ONCE(true, "invalid aci: %d !\n", aci); + break; + } +} + +void rtl8822be_enable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR0_8822B, + rtlpci->irq_mask[0] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMR1_8822B, + rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtl_write_dword(rtlpriv, REG_HIMR3_8822B, + rtlpci->irq_mask[3] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; +} + +void rtl8822be_disable_interrupt(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + rtl_write_dword(rtlpriv, REG_HIMR0_8822B, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMR1_8822B, IMR_DISABLED); + rtl_write_dword(rtlpriv, REG_HIMR3_8822B, IMR_DISABLED); + rtlpci->irq_enabled = false; + /*synchronize_irq(rtlpci->pdev->irq);*/ +} + +void rtl8822be_card_disable(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + enum nl80211_iftype opmode; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8822be card disable\n"); + + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + + mac->link_state = MAC80211_NOLINK; + opmode = NL80211_IFTYPE_UNSPECIFIED; + + _rtl8822be_set_media_status(hw, opmode); + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + ppsc->rfoff_reason > RF_CHANGE_BY_PS) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); + + rtlpriv->phydm.ops->phydm_deinit_dm(rtlpriv); + + rtlpriv->halmac.ops->halmac_deinit_hal(rtlpriv); + + /* after power off we should do iqk again */ + if (!rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->phy.iqk_initialized = false; +} + +void rtl8822be_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta, + u32 *p_intb, u32 *p_intc, u32 *p_intd) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + *p_inta = + rtl_read_dword(rtlpriv, REG_HISR0_8822B) & rtlpci->irq_mask[0]; + rtl_write_dword(rtlpriv, REG_HISR0_8822B, *p_inta); + + *p_intb = + rtl_read_dword(rtlpriv, REG_HISR1_8822B) & rtlpci->irq_mask[1]; + rtl_write_dword(rtlpriv, REG_HISR1_8822B, *p_intb); + + *p_intd = + rtl_read_dword(rtlpriv, REG_HISR3_8822B) & rtlpci->irq_mask[3]; + rtl_write_dword(rtlpriv, REG_HISR3_8822B, *p_intd); +} + +void rtl8822be_set_beacon_related_registers(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u16 bcn_interval, atim_window; + + bcn_interval = mac->beacon_interval; + atim_window = 2; /*FIX MERGE */ + rtl8822be_disable_interrupt(hw); + rtl_write_word(rtlpriv, REG_ATIMWND_8822B, atim_window); + rtl_write_word(rtlpriv, REG_MBSSID_BCN_SPACE_8822B, bcn_interval); + rtl_write_word(rtlpriv, REG_BCNTCFG_8822B, 0x660f); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK_8822B, 0x18); + rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM_8822B, 0x18); + rtl_write_byte(rtlpriv, 0x606, 0x30); + rtlpci->reg_bcn_ctrl_val |= BIT(3); + rtl_write_byte(rtlpriv, REG_BCN_CTRL_8822B, + (u8)rtlpci->reg_bcn_ctrl_val); +} + +void rtl8822be_set_beacon_interval(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 bcn_interval = mac->beacon_interval; + + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", + bcn_interval); + rtl_write_word(rtlpriv, REG_MBSSID_BCN_SPACE_8822B, bcn_interval); +} + +void rtl8822be_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr, + u32 rm_msr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); + + if (add_msr) + rtlpci->irq_mask[0] |= add_msr; + if (rm_msr) + rtlpci->irq_mask[0] &= (~rm_msr); + rtl8822be_disable_interrupt(hw); + rtl8822be_enable_interrupt(hw); +} + +static bool _rtl8822be_get_chnl_group(u8 chnl, u8 *group) +{ + bool in_24g; + + if (chnl <= 14) { + in_24g = true; + + if (chnl >= 1 && chnl <= 2) + *group = 0; + else if (chnl >= 3 && chnl <= 5) + *group = 1; + else if (chnl >= 6 && chnl <= 8) + *group = 2; + else if (chnl >= 9 && chnl <= 11) + *group = 3; + else if (chnl >= 12 && chnl <= 14) + *group = 4; + } else { + in_24g = false; + + if (chnl >= 36 && chnl <= 42) + *group = 0; + else if (chnl >= 44 && chnl <= 48) + *group = 1; + else if (chnl >= 50 && chnl <= 58) + *group = 2; + else if (chnl >= 60 && chnl <= 64) + *group = 3; + else if (chnl >= 100 && chnl <= 106) + *group = 4; + else if (chnl >= 108 && chnl <= 114) + *group = 5; + else if (chnl >= 116 && chnl <= 122) + *group = 6; + else if (chnl >= 124 && chnl <= 130) + *group = 7; + else if (chnl >= 132 && chnl <= 138) + *group = 8; + else if (chnl >= 140 && chnl <= 144) + *group = 9; + else if (chnl >= 149 && chnl <= 155) + *group = 10; + else if (chnl >= 157 && chnl <= 161) + *group = 11; + else if (chnl >= 165 && chnl <= 171) + *group = 12; + else if (chnl >= 173 && chnl <= 177) + *group = 13; + } + return in_24g; +} + +static inline bool power_valid(u8 power) +{ + if (power <= 63) + return true; + + return false; +} + +static inline s8 power_diff(s8 diff) +{ + /* bit sign number to 8 bit sign number */ + if (diff & BIT(3)) + diff |= 0xF0; + + return diff; +} + +static void _rtl8822be_read_power_value_fromprom(struct ieee80211_hw *hw, + struct txpower_info_2g *pwr2g, + struct txpower_info_5g *pwr5g, + bool autoload_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 rf, addr = EEPROM_TX_PWR_INX_8822B, group, i = 0; + u8 power; + s8 diff; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "hal_ReadPowerValueFromPROM8822B(): PROMContent[0x%x]=0x%x\n", + (addr + 1), hwinfo[addr + 1]); + if (hwinfo[addr + 1] == 0xFF) /*YJ,add,120316*/ + autoload_fail = true; + + memset(pwr2g, 0, sizeof(struct txpower_info_2g)); + memset(pwr5g, 0, sizeof(struct txpower_info_5g)); + + if (autoload_fail) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "auto load fail : Use Default value!\n"); + for (rf = 0; rf < MAX_RF_PATH; rf++) { + /* 2.4G default value */ + for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { + pwr2g->index_cck_base[rf][group] = 0x2D; + pwr2g->index_bw40_base[rf][group] = 0x2D; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr2g->bw20_diff[rf][0] = 0x02; + pwr2g->ofdm_diff[rf][0] = 0x04; + } else { + pwr2g->bw20_diff[rf][i] = 0xFE; + pwr2g->bw40_diff[rf][i] = 0xFE; + pwr2g->cck_diff[rf][i] = 0xFE; + pwr2g->ofdm_diff[rf][i] = 0xFE; + } + } + + /*5G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_5G; group++) + pwr5g->index_bw40_base[rf][group] = 0x2A; + + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr5g->ofdm_diff[rf][0] = 0x04; + pwr5g->bw20_diff[rf][0] = 0x00; + pwr5g->bw80_diff[rf][0] = 0xFE; + pwr5g->bw160_diff[rf][0] = 0xFE; + } else { + pwr5g->ofdm_diff[rf][i] = 0xFE; + pwr5g->bw20_diff[rf][i] = 0xFE; + pwr5g->bw40_diff[rf][i] = 0xFE; + pwr5g->bw80_diff[rf][i] = 0xFE; + pwr5g->bw160_diff[rf][i] = 0xFE; + } + } + } + return; + } + + rtl_priv(hw)->efuse.txpwr_fromeprom = true; + + for (rf = 0; rf < 2 /*MAX_RF_PATH*/; rf++) { + /*2.4G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_24G; group++) { + power = hwinfo[addr++]; + if (power_valid(power)) + pwr2g->index_cck_base[rf][group] = power; + } + for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) { + power = hwinfo[addr++]; + if (power_valid(power)) + pwr2g->index_bw40_base[rf][group] = power; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr2g->bw40_diff[rf][i] = 0; + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr2g->bw20_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr2g->ofdm_diff[rf][i] = power_diff(diff); + + pwr2g->cck_diff[rf][i] = 0; + + addr++; + } else { + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr2g->bw40_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr2g->bw20_diff[rf][i] = power_diff(diff); + + addr++; + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr2g->ofdm_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr2g->cck_diff[rf][i] = power_diff(diff); + + addr++; + } + } + + /*5G default value*/ + for (group = 0; group < MAX_CHNL_GROUP_5G; group++) { + power = hwinfo[addr++]; + if (power_valid(power)) + pwr5g->index_bw40_base[rf][group] = power; + } + + for (i = 0; i < MAX_TX_COUNT; i++) { + if (i == 0) { + pwr5g->bw40_diff[rf][i] = 0; + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->bw20_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->ofdm_diff[rf][i] = power_diff(diff); + + addr++; + } else { + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->bw40_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->bw20_diff[rf][i] = power_diff(diff); + + addr++; + } + } + + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->ofdm_diff[rf][1] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->ofdm_diff[rf][2] = power_diff(diff); + + addr++; + + diff = hwinfo[addr] & 0x0F; + pwr5g->ofdm_diff[rf][3] = power_diff(diff); + + addr++; + + for (i = 0; i < MAX_TX_COUNT; i++) { + diff = (hwinfo[addr] & 0xF0) >> 4; + pwr5g->bw80_diff[rf][i] = power_diff(diff); + + diff = hwinfo[addr] & 0x0F; + pwr5g->bw160_diff[rf][i] = power_diff(diff); + + addr++; + } + } +} + +static void _rtl8822be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, + u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw)); + struct txpower_info_2g pwr2g; + struct txpower_info_5g pwr5g; + u8 channel5g[CHANNEL_MAX_NUMBER_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ + u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, + 138, 155, 171}; + u8 rf, group; + u8 i; + + _rtl8822be_read_power_value_fromprom(hw, &pwr2g, &pwr5g, autoload_fail, + hwinfo); + + for (rf = 0; rf < MAX_RF_PATH; rf++) { + for (i = 0; i < CHANNEL_MAX_NUMBER_2G; i++) { + _rtl8822be_get_chnl_group(i + 1, &group); + + if (i == CHANNEL_MAX_NUMBER_2G - 1) { + efu->txpwrlevel_cck[rf][i] = + pwr2g.index_cck_base[rf][5]; + efu->txpwrlevel_ht40_1s[rf][i] = + pwr2g.index_bw40_base[rf][group]; + } else { + efu->txpwrlevel_cck[rf][i] = + pwr2g.index_cck_base[rf][group]; + efu->txpwrlevel_ht40_1s[rf][i] = + pwr2g.index_bw40_base[rf][group]; + } + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) { + _rtl8822be_get_chnl_group(channel5g[i], &group); + efu->txpwr_5g_bw40base[rf][i] = + pwr5g.index_bw40_base[rf][group]; + } + for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) { + u8 upper, lower; + + _rtl8822be_get_chnl_group(channel5g_80m[i], &group); + upper = pwr5g.index_bw40_base[rf][group]; + lower = pwr5g.index_bw40_base[rf][group + 1]; + + efu->txpwr_5g_bw80base[rf][i] = (upper + lower) / 2; + } + for (i = 0; i < MAX_TX_COUNT; i++) { + efu->txpwr_cckdiff[rf][i] = pwr2g.cck_diff[rf][i]; + efu->txpwr_legacyhtdiff[rf][i] = pwr2g.ofdm_diff[rf][i]; + efu->txpwr_ht20diff[rf][i] = pwr2g.bw20_diff[rf][i]; + efu->txpwr_ht40diff[rf][i] = pwr2g.bw40_diff[rf][i]; + + efu->txpwr_5g_ofdmdiff[rf][i] = pwr5g.ofdm_diff[rf][i]; + efu->txpwr_5g_bw20diff[rf][i] = pwr5g.bw20_diff[rf][i]; + efu->txpwr_5g_bw40diff[rf][i] = pwr5g.bw40_diff[rf][i]; + efu->txpwr_5g_bw80diff[rf][i] = pwr5g.bw80_diff[rf][i]; + } + } + + if (!autoload_fail) + efu->eeprom_thermalmeter = hwinfo[EEPROM_THERMAL_METER_8822B]; + else + efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + + if (efu->eeprom_thermalmeter == 0xff || autoload_fail) { + efu->apk_thermalmeterignore = true; + efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; + } + + efu->thermalmeter[0] = efu->eeprom_thermalmeter; + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "thermalmeter = 0x%x\n", + efu->eeprom_thermalmeter); + + if (!autoload_fail) { + efu->eeprom_regulatory = + hwinfo[EEPROM_RF_BOARD_OPTION_8822B] & 0x07; + if (hwinfo[EEPROM_RF_BOARD_OPTION_8822B] == 0xFF) + efu->eeprom_regulatory = 0; + } else { + efu->eeprom_regulatory = 0; + } + RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "eeprom_regulatory = 0x%x\n", + efu->eeprom_regulatory); +} + +static void _rtl8822be_read_pa_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!autoload_fail) { + rtlhal->pa_type_2g = hwinfo[EEPROM_2G_5G_PA_TYPE_8822B]; + rtlhal->lna_type_2g = + hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B]; + if (rtlhal->pa_type_2g == 0xFF) + rtlhal->pa_type_2g = 0; + if (rtlhal->lna_type_2g == 0xFF) + rtlhal->lna_type_2g = 0; + + rtlhal->external_pa_2g = (rtlhal->pa_type_2g & BIT(4)) ? 1 : 0; + rtlhal->external_lna_2g = + (rtlhal->lna_type_2g & BIT(3)) ? 1 : 0; + + rtlhal->pa_type_5g = hwinfo[EEPROM_2G_5G_PA_TYPE_8822B]; + rtlhal->lna_type_5g = + hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B]; + if (rtlhal->pa_type_5g == 0xFF) + rtlhal->pa_type_5g = 0; + if (rtlhal->lna_type_5g == 0xFF) + rtlhal->lna_type_5g = 0; + + rtlhal->external_pa_5g = (rtlhal->pa_type_5g & BIT(0)) ? 1 : 0; + rtlhal->external_lna_5g = + (rtlhal->lna_type_5g & BIT(3)) ? 1 : 0; + } else { + rtlhal->external_pa_2g = 0; + rtlhal->external_lna_2g = 0; + rtlhal->external_pa_5g = 0; + rtlhal->external_lna_5g = 0; + } +} + +static void _rtl8822be_read_amplifier_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + u8 ext_type_pa_2g_a = + (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(2)) >> + 2; /* 0xBD[2] */ + u8 ext_type_pa_2g_b = + (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(6)) >> + 6; /* 0xBD[6] */ + u8 ext_type_pa_5g_a = + (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(2)) >> + 2; /* 0xBF[2] */ + u8 ext_type_pa_5g_b = + (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & BIT(6)) >> + 6; /* 0xBF[6] */ + u8 ext_type_lna_2g_a = (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(1) | BIT(0))) >> + 0; /* 0xBD[1:0] */ + u8 ext_type_lna_2g_b = (hwinfo[EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(5) | BIT(4))) >> + 4; /* 0xBD[5:4] */ + u8 ext_type_lna_5g_a = (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(1) | BIT(0))) >> + 0; /* 0xBF[1:0] */ + u8 ext_type_lna_5g_b = (hwinfo[EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B] & + (BIT(5) | BIT(4))) >> + 4; /* 0xBF[5:4] */ + + _rtl8822be_read_pa_type(hw, hwinfo, autoload_fail); + + /* [2.4G] Path A and B are both extPA */ + if ((rtlhal->pa_type_2g & (BIT(5) | BIT(4))) == (BIT(5) | BIT(4))) + rtlhal->type_gpa = ext_type_pa_2g_b << 2 | ext_type_pa_2g_a; + + /* [5G] Path A and B are both extPA */ + if ((rtlhal->pa_type_5g & (BIT(1) | BIT(0))) == (BIT(1) | BIT(0))) + rtlhal->type_apa = ext_type_pa_5g_b << 2 | ext_type_pa_5g_a; + + /* [2.4G] Path A and B are both extLNA */ + if ((rtlhal->lna_type_2g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3))) + rtlhal->type_glna = ext_type_lna_2g_b << 2 | ext_type_lna_2g_a; + + /* [5G] Path A and B are both extLNA */ + if ((rtlhal->lna_type_5g & (BIT(7) | BIT(3))) == (BIT(7) | BIT(3))) + rtlhal->type_alna = ext_type_lna_5g_b << 2 | ext_type_lna_5g_a; +} + +static void _rtl8822be_read_rfe_type(struct ieee80211_hw *hw, u8 *hwinfo, + bool autoload_fail) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + + if (!autoload_fail) + rtlhal->rfe_type = hwinfo[EEPROM_RFE_OPTION_8822B]; + else + rtlhal->rfe_type = 0; + + if (rtlhal->rfe_type == 0xFF) + rtlhal->rfe_type = 0; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "RFE Type: 0x%2x\n", + rtlhal->rfe_type); +} + +static void _rtl8822be_read_adapter_info(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_halmac_ops *halmac_ops = rtlpriv->halmac.ops; + u16 i, usvalue; + u8 *hwinfo; + u16 eeprom_id; + u32 efuse_size; + int err; + + if (rtlefuse->epromtype != EEPROM_BOOT_EFUSE) { + pr_err("RTL8822B Not boot from efuse!!"); + return; + } + + /* read logical efuse size (normalely, 0x0300) */ + err = halmac_ops->halmac_get_logical_efuse_size(rtlpriv, &efuse_size); + + if (err || !efuse_size) { + pr_err("halmac_get_logical_efuse_size err=%d efuse_size=0x%X", + err, efuse_size); + efuse_size = HWSET_MAX_SIZE; + } + + if (efuse_size > HWSET_MAX_SIZE) { + pr_err("halmac_get_logical_efuse_size efuse_size=0x%X > 0x%X", + efuse_size, HWSET_MAX_SIZE); + efuse_size = HWSET_MAX_SIZE; + } + + /* read efuse */ + hwinfo = kzalloc(efuse_size, GFP_KERNEL); + + err = halmac_ops->halmac_read_logical_efuse_map(rtlpriv, hwinfo, + efuse_size); + if (err) { + pr_err("%s: fail to get efuse map!\n", __func__); + goto label_end; + } + + /* copy to efuse_map (need?) */ + memcpy(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], hwinfo, + EFUSE_MAX_LOGICAL_SIZE); + memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0], hwinfo, + EFUSE_MAX_LOGICAL_SIZE); + + /* parse content */ + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP\n", hwinfo, + HWSET_MAX_SIZE); + + eeprom_id = *((u16 *)&hwinfo[0]); + if (eeprom_id != RTL8822B_EEPROM_ID) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); + rtlefuse->autoload_failflag = true; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + } + + if (rtlefuse->autoload_failflag) + goto label_end; + + /*VID DID SVID SDID*/ + rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; + rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; + rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; + rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM VID = 0x%4x\n", + rtlefuse->eeprom_vid); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM DID = 0x%4x\n", + rtlefuse->eeprom_did); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SVID = 0x%4x\n", + rtlefuse->eeprom_svid); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM SMID = 0x%4x\n", + rtlefuse->eeprom_smid); + /*customer ID*/ + rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOM_ID_8822B]; + if (rtlefuse->eeprom_oemid == 0xFF) + rtlefuse->eeprom_oemid = 0; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); + /*EEPROM version*/ + rtlefuse->eeprom_version = *(u8 *)&hwinfo[EEPROM_VERSION_8822B]; + /*mac address*/ + for (i = 0; i < 6; i += 2) { + usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_8822BE + i]; + *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n", + rtlefuse->dev_addr); + + /* channel plan */ + rtlefuse->eeprom_channelplan = + *(u8 *)&hwinfo[EEPROM_CHANNEL_PLAN_8822B]; + + /* set channel plan from efuse */ + rtlefuse->channel_plan = rtlefuse->eeprom_channelplan; + if (rtlefuse->channel_plan == 0xFF) + rtlefuse->channel_plan = 0x7f; /* use 2G + 5G as default */ + + /*tx power*/ + _rtl8822be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, + hwinfo); + + rtl8822be_read_bt_coexist_info_from_hwpg( + hw, rtlefuse->autoload_failflag, hwinfo); + + /*amplifier type*/ + _rtl8822be_read_amplifier_type(hw, hwinfo, rtlefuse->autoload_failflag); + + /*rfe type*/ + _rtl8822be_read_rfe_type(hw, hwinfo, rtlefuse->autoload_failflag); + + /*board type*/ + rtlefuse->board_type = + (((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_8822B]) & 0xE0) >> 5); + if ((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_8822B]) == 0xFF) + rtlefuse->board_type = 0; + + if (rtlpriv->btcoexist.btc_info.btcoexist == 1) + rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */ + + /* phydm maintain rtlhal->board_type and rtlhal->package_type */ + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "board_type = 0x%x\n", + rtlefuse->board_type); + /*parse xtal*/ + rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8822B]; + if (hwinfo[EEPROM_XTAL_8822B] == 0xFF) + rtlefuse->crystalcap = 0; /*0x20;*/ + + /*antenna diversity*/ + rtlefuse->antenna_div_type = 0; + rtlefuse->antenna_div_cfg = 0; + +label_end: + kfree(hwinfo); +} + +static void _rtl8822be_hal_customized_behavior(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + pcipriv->ledctl.led_opendrain = true; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", + rtlhal->oem_id); +} + +static void _rtl8822be_read_pa_bias(struct ieee80211_hw *hw, + struct rtl_phydm_params *params) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_halmac_ops *halmac_ops = rtlpriv->halmac.ops; + u32 size; + u8 *map = NULL; + + /* fill default values */ + params->efuse0x3d7 = 0xFF; + params->efuse0x3d8 = 0xFF; + + if (halmac_ops->halmac_get_physical_efuse_size(rtlpriv, &size)) + goto err; + + map = kmalloc(size, GFP_KERNEL); + if (!map) + goto err; + + if (halmac_ops->halmac_read_physical_efuse_map(rtlpriv, map, size)) + goto err; + + params->efuse0x3d7 = map[0x3d7]; + params->efuse0x3d8 = map[0x3d8]; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "efuse0x3d7 = 0x%2x, efuse0x3d8 = 0x%2x\n", + params->efuse0x3d7, params->efuse0x3d8); + +err: + kfree(map); +} + +void rtl8822be_read_eeprom_info(struct ieee80211_hw *hw, + struct rtl_phydm_params *params) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u8 tmp_u1b; + + rtlhal->version = _rtl8822be_read_chip_version(hw); + + params->mp_chip = (rtlhal->version & BIT_RTL_ID_8822B) ? 0 : 1; + params->fab_ver = BIT_GET_VENDOR_ID_8822B(rtlhal->version) >> 2; + params->cut_ver = BIT_GET_CHIP_VER_8822B(rtlhal->version); + + /* fab_ver mapping */ + if (params->fab_ver == 2) + params->fab_ver = 1; + else if (params->fab_ver == 1) + params->fab_ver = 2; + + /* read PA bias: params->efuse0x3d7/efuse0x3d8 */ + _rtl8822be_read_pa_bias(hw, params); + + if (get_rf_type(rtlphy) == RF_1T1R) + rtlpriv->dm.rfpath_rxenable[0] = true; + else + rtlpriv->dm.rfpath_rxenable[0] = + rtlpriv->dm.rfpath_rxenable[1] = true; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); + tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_EEPROM_CTRL_8822B); + if (tmp_u1b & BIT(4)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtlefuse->epromtype = EEPROM_93C46; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtlefuse->epromtype = EEPROM_BOOT_EFUSE; + } + if (tmp_u1b & BIT(5)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtlefuse->autoload_failflag = false; + _rtl8822be_read_adapter_info(hw); + } else { + pr_err("Autoload ERR!!\n"); + } + _rtl8822be_hal_customized_behavior(hw); + + rtlphy->rfpath_rx_enable[0] = true; + if (rtlphy->rf_type == RF_2T2R) + rtlphy->rfpath_rx_enable[1] = true; +} + +void rtl8822be_read_eeprom_info_dummy(struct ieee80211_hw *hw) +{ + /* + * 8822b use halmac, so + * move rtl8822be_read_eeprom_info() to rtl8822be_init_sw_vars() + * after halmac_init_adapter(). + */ +} + +static u32 _rtl8822be_rate_to_bitmap_2ssvht(__le16 vht_rate) +{ + u8 i, j, tmp_rate; + u32 rate_bitmap = 0; + + for (i = j = 0; i < 4; i += 2, j += 10) { + tmp_rate = (le16_to_cpu(vht_rate) >> i) & 3; + + switch (tmp_rate) { + case 2: + rate_bitmap = rate_bitmap | (0x03ff << j); + break; + + case 1: + rate_bitmap = rate_bitmap | (0x01ff << j); + break; + + case 0: + rate_bitmap = rate_bitmap | (0x00ff << j); + break; + + default: + break; + } + } + + return rate_bitmap; +} + +static u8 _rtl8822be_get_vht_en(enum wireless_mode wirelessmode, + u32 ratr_bitmap) +{ + u8 ret = 0; + + if (wirelessmode < WIRELESS_MODE_N_24G) { + ret = 0; + } else if (wirelessmode == WIRELESS_MODE_AC_24G) { + if (ratr_bitmap & 0xfff00000) /* Mix , 2SS */ + ret = 3; + else /* Mix, 1SS */ + ret = 2; + } else if (wirelessmode == WIRELESS_MODE_AC_5G) { + ret = 1; + } /* VHT */ + + return ret << 4; +} + +static u8 _rtl8822be_get_ra_ldpc(struct ieee80211_hw *hw, u8 mac_id, + struct rtl_sta_info *sta_entry, + enum wireless_mode wirelessmode) +{ + u8 b_ldpc = 0; + /*not support ldpc, do not open*/ + return b_ldpc << 2; +} + +static u8 _rtl8822be_get_ra_rftype(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u32 ratr_bitmap) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rf_type = RF_1T1R; + + if (rtlphy->rf_type == RF_1T1R) { + rf_type = RF_1T1R; + } else if (wirelessmode == WIRELESS_MODE_AC_5G || + wirelessmode == WIRELESS_MODE_AC_24G || + wirelessmode == WIRELESS_MODE_AC_ONLY) { + if (ratr_bitmap & 0xffc00000) + rf_type = RF_2T2R; + } else if (wirelessmode == WIRELESS_MODE_N_5G || + wirelessmode == WIRELESS_MODE_N_24G) { + if (ratr_bitmap & 0xfff00000) + rf_type = RF_2T2R; + } + + return rf_type; +} + +static bool _rtl8822be_get_ra_shortgi(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 mac_id) +{ + bool b_short_gi = false; + u8 b_curshortgi_40mhz = + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1 : 0; + u8 b_curshortgi_20mhz = + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1 : 0; + u8 b_curshortgi_80mhz = 0; + + b_curshortgi_80mhz = + (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) ? 1 : 0; + + if (mac_id == 99 /*MAC_ID_STATIC_FOR_BROADCAST_MULTICAST*/) + b_short_gi = false; + + if (b_curshortgi_40mhz || b_curshortgi_80mhz || b_curshortgi_20mhz) + b_short_gi = true; + + return b_short_gi; +} + +static void rtl8822be_update_hal_rate_mask(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + u8 rssi_level, bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_sta_info *sta_entry = NULL; + u32 ratr_bitmap, ratr_bitmap_msb = 0; + u8 ratr_index; + enum wireless_mode wirelessmode = 0; + u8 curtxbw_40mhz = + (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0; + bool b_shortgi = false; + u8 rate_mask[7]; + u8 macid = 0; + u8 rf_type; + + sta_entry = (struct rtl_sta_info *)sta->drv_priv; + wirelessmode = sta_entry->wireless_mode; + + RT_TRACE(rtlpriv, COMP_RATR, DBG_LOUD, "wireless mode = 0x%x\n", + wirelessmode); + if (mac->opmode == NL80211_IFTYPE_STATION || + mac->opmode == NL80211_IFTYPE_MESH_POINT) { + curtxbw_40mhz = mac->bw_40; + } else if (mac->opmode == NL80211_IFTYPE_AP || + mac->opmode == NL80211_IFTYPE_ADHOC) + macid = sta->aid + 1; + if (wirelessmode == WIRELESS_MODE_N_5G || + wirelessmode == WIRELESS_MODE_AC_5G || + wirelessmode == WIRELESS_MODE_A) + ratr_bitmap = (sta->supp_rates[NL80211_BAND_5GHZ]) << 4; + else + ratr_bitmap = sta->supp_rates[NL80211_BAND_2GHZ]; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) + ratr_bitmap = 0xfff; + + if (wirelessmode == WIRELESS_MODE_N_24G || + wirelessmode == WIRELESS_MODE_N_5G) + ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | + sta->ht_cap.mcs.rx_mask[0] << 12); + else if (wirelessmode == WIRELESS_MODE_AC_24G || + wirelessmode == WIRELESS_MODE_AC_5G || + wirelessmode == WIRELESS_MODE_AC_ONLY) + ratr_bitmap |= _rtl8822be_rate_to_bitmap_2ssvht( + sta->vht_cap.vht_mcs.rx_mcs_map) + << 12; + + b_shortgi = _rtl8822be_get_ra_shortgi(hw, sta, macid); + rf_type = _rtl8822be_get_ra_rftype(hw, wirelessmode, ratr_bitmap); + + ratr_index = rtlpriv->phydm.ops->phydm_rate_id_mapping( + rtlpriv, wirelessmode, rf_type, rtlphy->current_chan_bw); + sta_entry->ratr_index = ratr_index; + + rtlpriv->phydm.ops->phydm_get_ra_bitmap( + rtlpriv, wirelessmode, rf_type, rtlphy->current_chan_bw, + rssi_level, &ratr_bitmap_msb, &ratr_bitmap); + + RT_TRACE(rtlpriv, COMP_RATR, DBG_LOUD, "ratr_bitmap :%x\n", + ratr_bitmap); + + rate_mask[0] = macid; + rate_mask[1] = ratr_index | (b_shortgi ? 0x80 : 0x00); + rate_mask[2] = + rtlphy->current_chan_bw | ((!update_bw) << 3) | + _rtl8822be_get_vht_en(wirelessmode, ratr_bitmap) | + _rtl8822be_get_ra_ldpc(hw, macid, sta_entry, wirelessmode); + + rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff); + rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8); + rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); + rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); + + RT_TRACE( + rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%08x, %02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], rate_mask[4], rate_mask[5], + rate_mask[6]); + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MACID_CFG, 7, rate_mask); + + /* for h2c cmd 0x46, only modify cmd id & ra mask */ + /* Keep rate_mask0~2 of cmd 0x40, but clear byte3 and later */ + /* 8822B has no 3SS, so keep it zeros. */ + memset(rate_mask + 3, 0, 4); + + rtl8822be_fill_h2c_cmd(hw, H2C_8822B_MACID_CFG_3SS, 7, rate_mask); + + _rtl8822be_set_bcn_ctrl_reg(hw, BIT(3), 0); +} + +void rtl8822be_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (rtlpriv->dm.useramask) + rtl8822be_update_hal_rate_mask(hw, sta, rssi_level, update_bw); +} + +void rtl8822be_update_channel_access_setting(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u16 sifs_timer; + + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, + (u8 *)&mac->slot_time); + if (!mac->ht_enable) + sifs_timer = 0x0a0a; + else + sifs_timer = 0x0e0e; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); +} + +bool rtl8822be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) +{ + *valid = 1; + return true; +} + +void rtl8822be_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, + bool is_group, u8 enc_algo, bool is_wepkey, + bool clear_all) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 *macaddr = p_macaddr; + u32 entry_id = 0; + bool is_pairwise = false; + + static u8 cam_const_addr[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}, + }; + static u8 cam_const_broad[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + if (clear_all) { + u8 idx = 0; + u8 cam_offset = 0; + u8 clear_number = 5; + + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + + for (idx = 0; idx < clear_number; idx++) { + rtl_cam_mark_invalid(hw, cam_offset + idx); + rtl_cam_empty_entry(hw, cam_offset + idx); + + if (idx < 5) { + memset(rtlpriv->sec.key_buf[idx], 0, + MAX_KEY_LEN); + rtlpriv->sec.key_len[idx] = 0; + } + } + + return; + } + + switch (enc_algo) { + case WEP40_ENCRYPTION: + enc_algo = CAM_WEP40; + break; + case WEP104_ENCRYPTION: + enc_algo = CAM_WEP104; + break; + case TKIP_ENCRYPTION: + enc_algo = CAM_TKIP; + break; + case AESCCMP_ENCRYPTION: + enc_algo = CAM_AES; + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case %#x not processed\n", enc_algo); + enc_algo = CAM_TKIP; + break; + } + + if (is_wepkey || rtlpriv->sec.use_defaultkey) { + macaddr = cam_const_addr[key_index]; + entry_id = key_index; + } else { + if (is_group) { + macaddr = cam_const_broad; + entry_id = key_index; + } else { + if (mac->opmode == NL80211_IFTYPE_AP) { + entry_id = + rtl_cam_get_free_entry(hw, p_macaddr); + if (entry_id >= TOTAL_CAM_ENTRY) { + pr_err("Can not find free hwsecurity cam entry\n"); + return; + } + } else { + entry_id = CAM_PAIRWISE_KEY_POSITION; + } + + key_index = PAIRWISE_KEYIDX; + is_pairwise = true; + } + } + + if (rtlpriv->sec.key_len[key_index] == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", entry_id); + if (mac->opmode == NL80211_IFTYPE_AP) + rtl_cam_del_entry(hw, p_macaddr); + rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "add one entry\n"); + if (is_pairwise) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); + + rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[key_index]); + } else { + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + rtl_cam_add_one_entry( + hw, rtlefuse->dev_addr, PAIRWISE_KEYIDX, + CAM_PAIRWISE_KEY_POSITION, enc_algo, + CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + + rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, + enc_algo, CAM_CONFIG_NO_USEDK, + rtlpriv->sec.key_buf[entry_id]); + } + } +} + +void rtl8822be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool auto_load_fail, u8 *hwinfo) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value; + u32 val32; + + val32 = rtl_read_dword(rtlpriv, REG_WL_BT_PWR_CTRL_8822B); + if (val32 & BIT_BT_FUNC_EN_8822B) + rtlpriv->btcoexist.btc_info.btcoexist = 1; + else + rtlpriv->btcoexist.btc_info.btcoexist = 0; + + if (!auto_load_fail) { + value = hwinfo[EEPROM_RF_BT_SETTING_8822B]; + + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8822B; + rtlpriv->btcoexist.btc_info.ant_num = + (value & BIT(0) ? ANT_TOTAL_X1 : ANT_TOTAL_X2); + } else { + rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8822B; + rtlpriv->btcoexist.btc_info.ant_num = ANT_TOTAL_X2; + } +} + +void rtl8822be_bt_reg_init(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + /* 0:Low, 1:High, 2:From Efuse. */ + rtlpriv->btcoexist.reg_bt_iso = 2; + /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ + rtlpriv->btcoexist.reg_bt_sco = 3; + /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ + rtlpriv->btcoexist.reg_bt_sco = 0; +} + +void rtl8822be_suspend(struct ieee80211_hw *hw) {} + +void rtl8822be_resume(struct ieee80211_hw *hw) {} diff --git a/drivers/staging/rtlwifi/rtl8822be/hw.h b/drivers/staging/rtlwifi/rtl8822be/hw.h new file mode 100644 index 000000000000..a91c276c5794 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/hw.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_HW_H__ +#define __RTL8822B_HW_H__ + +extern u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G]; +extern u8 rtl_channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M]; + +void rtl8822be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8822be_read_eeprom_info(struct ieee80211_hw *hw, + struct rtl_phydm_params *params); +void rtl8822be_read_eeprom_info_dummy(struct ieee80211_hw *hw); +void rtl8822be_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta, + u32 *p_intb, u32 *p_intc, u32 *p_intd); +int rtl8822be_hw_init(struct ieee80211_hw *hw); +void rtl8822be_card_disable(struct ieee80211_hw *hw); +void rtl8822be_enable_interrupt(struct ieee80211_hw *hw); +void rtl8822be_disable_interrupt(struct ieee80211_hw *hw); +int rtl8822be_set_network_type(struct ieee80211_hw *hw, + enum nl80211_iftype type); +void rtl8822be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); +void rtl8822be_set_qos(struct ieee80211_hw *hw, int aci); +void rtl8822be_set_beacon_related_registers(struct ieee80211_hw *hw); +void rtl8822be_set_beacon_interval(struct ieee80211_hw *hw); +void rtl8822be_update_interrupt_mask(struct ieee80211_hw *hw, u32 add_msr, + u32 rm_msr); +void rtl8822be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); +void rtl8822be_update_hal_rate_tbl(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_level, + bool update_bw); +void rtl8822be_update_channel_access_setting(struct ieee80211_hw *hw); +bool rtl8822be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); +void rtl8822be_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, + bool is_group, u8 enc_algo, bool is_wepkey, + bool clear_all); +void rtl8822be_enable_hw_security_config(struct ieee80211_hw *hw); +void rtl8822be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, + bool autoload_fail, u8 *hwinfo); +void rtl8822be_bt_reg_init(struct ieee80211_hw *hw); +void rtl8822be_suspend(struct ieee80211_hw *hw); +void rtl8822be_resume(struct ieee80211_hw *hw); +void rtl8822be_fw_clk_off_timer_callback(unsigned long data); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/led.c b/drivers/staging/rtlwifi/rtl8822be/led.c new file mode 100644 index 000000000000..f4b5af8ab116 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/led.c @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "reg.h" +#include "led.h" + +static void _rtl8822be_init_led(struct ieee80211_hw *hw, struct rtl_led *pled, + enum rtl_led_pin ledpin) +{ + pled->hw = hw; + pled->ledpin = ledpin; + pled->ledon = false; +} + +void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2_8822B, pled->ledpin); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + break; + case LED_PIN_LED1: + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + pled->ledon = true; +} + +void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2_8822B, pled->ledpin); + + switch (pled->ledpin) { + case LED_PIN_GPIO0: + break; + case LED_PIN_LED0: + break; + case LED_PIN_LED1: + + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + pled->ledon = false; +} + +void rtl8822be_init_sw_leds(struct ieee80211_hw *hw) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + + _rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led0, LED_PIN_LED0); + _rtl8822be_init_led(hw, &pcipriv->ledctl.sw_led1, LED_PIN_LED1); +} + +static void _rtl8822be_sw_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction) +{ + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_led *led0 = &pcipriv->ledctl.sw_led0; + + switch (ledaction) { + case LED_CTL_POWER_ON: + case LED_CTL_LINK: + case LED_CTL_NO_LINK: + rtl8822be_sw_led_on(hw, led0); + break; + case LED_CTL_POWER_OFF: + rtl8822be_sw_led_off(hw, led0); + break; + default: + break; + } +} + +void rtl8822be_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && + (ledaction == LED_CTL_TX || ledaction == LED_CTL_RX || + ledaction == LED_CTL_SITE_SURVEY || ledaction == LED_CTL_LINK || + ledaction == LED_CTL_NO_LINK || + ledaction == LED_CTL_START_TO_LINK || + ledaction == LED_CTL_POWER_ON)) { + return; + } + RT_TRACE(rtlpriv, COMP_LED, DBG_TRACE, "ledaction %d,\n", ledaction); + _rtl8822be_sw_led_control(hw, ledaction); +} diff --git a/drivers/staging/rtlwifi/rtl8822be/led.h b/drivers/staging/rtlwifi/rtl8822be/led.h new file mode 100644 index 000000000000..9c0a2290df7d --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/led.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_LED_H__ +#define __RTL8822B_LED_H__ + +void rtl8822be_init_sw_leds(struct ieee80211_hw *hw); +void rtl8822be_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl8822be_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); +void rtl8822be_led_control(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/phy.c b/drivers/staging/rtlwifi/rtl8822be/phy.c new file mode 100644 index 000000000000..4cba2adc3165 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/phy.c @@ -0,0 +1,2233 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../ps.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "../btcoexist/halbt_precomp.h" +#include "hw.h" +#include "../efuse.h" + +static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask); +static void +_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); + +static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx); +static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl8822be_phy_set_io(struct ieee80211_hw *hw); + +static u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M}; +static u8 sizes_of_cck_retes = 4; +static u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, + DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, + DESC_RATE48M, DESC_RATE54M}; +static u8 sizes_of_ofdm_retes = 8; +static u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, + DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, + DESC_RATEMCS6, DESC_RATEMCS7}; +static u8 sizes_of_ht_retes_1t = 8; +static u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, + DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13, + DESC_RATEMCS14, DESC_RATEMCS15}; +static u8 sizes_of_ht_retes_2t = 8; +static u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, + DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, + DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, + DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, + DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9}; +static u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, + DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, + DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, + DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, + DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9}; +static u8 sizes_of_vht_retes = 10; + +u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 returnvalue, originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask); + returnvalue = (originalvalue & bitmask) >> bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); + + return returnvalue; +} + +void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 originalvalue, bitshift; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask, + data); + + if (bitmask != MASKDWORD) { + originalvalue = rtl_read_dword(rtlpriv, regaddr); + bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask); + data = ((originalvalue & (~bitmask)) | + ((data << bitshift) & bitmask)); + } + + rtl_write_dword(rtlpriv, regaddr, data); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask, + data); +} + +u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 /*original_value,*/ readback_value /*, bitshift*/; + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath, + bitmask); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + readback_value = rtlpriv->phydm.ops->phydm_read_rf_reg( + rtlpriv, rfpath, regaddr, bitmask); + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + return readback_value; +} + +void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + unsigned long flags; + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); + + spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); + + rtlpriv->phydm.ops->phydm_write_rf_reg(rtlpriv, rfpath, regaddr, + bitmask, data); + + spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); + + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); +} + +static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) { + if (((bitmask >> i) & 0x1) == 1) + break; + } + return i; +} + +bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv) +{ + return rtlpriv->phydm.ops->phydm_phy_mac_config(rtlpriv); +} + +bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw) +{ + bool rtstatus = true; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 crystal_cap; + /* u32 tmp; */ + + rtstatus = rtlpriv->phydm.ops->phydm_phy_bb_config(rtlpriv); + + /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */ + crystal_cap = rtlefuse->crystalcap & 0x3F; + rtl_set_bbreg(hw, REG_AFE_XTAL_CTRL_8822B, 0x7E000000, crystal_cap); + rtl_set_bbreg(hw, REG_AFE_PLL_CTRL_8822B, 0x7E, crystal_cap); + + /*rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);*/ /*unused*/ + + return rtstatus; +} + +bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (rtlphy->rf_type == RF_1T1R) + rtlphy->num_total_rfpath = 1; + else + rtlphy->num_total_rfpath = 2; + + return rtlpriv->phydm.ops->phydm_phy_rf_config(rtlpriv); +} + +bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv) +{ + struct ieee80211_hw *hw = rtlpriv->hw; + enum radio_mask txpath, rxpath; + bool tx2path; + bool ret = false; + + _rtl8822be_phy_init_bb_rf_register_definition(hw); + + rtlpriv->halmac.ops->halmac_phy_power_switch(rtlpriv, 1); + + /* beofre bb/rf config */ + rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 0); + + /* do bb/rf config */ + if (rtl8822be_phy_bb_config(hw) && rtl8822be_phy_rf_config(hw)) + ret = true; + + /* after bb/rf config */ + rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 1); + + /* set trx mode (keep it to be last, r17376) */ + txpath = RF_MASK_A | RF_MASK_B; + rxpath = RF_MASK_A | RF_MASK_B; + tx2path = false; + ret = rtlpriv->phydm.ops->phydm_trx_mode(rtlpriv, txpath, rxpath, + tx2path); + + return ret; +} + +static void _rtl8822be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 band, rfpath, txnum, rate; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) + for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath) + for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) + for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE; + ++rate) + rtlphy->tx_power_by_rate_offset + [band][rfpath][txnum][rate] = 0; +} + +static void _rtl8822be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, + u8 rate_section, u8 txnum, + u8 value) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + if (path > RF90_PATH_D) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", + path); + return; + } + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid band %d in phy_SetTxPowerByRatBase()\n", + band); + return; + } + + if (rate_section >= MAX_RATE_SECTION || + (band == BAND_ON_5G && rate_section == CCK)) { + RT_TRACE( + rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid rate_section %d in phy_SetTxPowerByRatBase()\n", + rate_section); + return; + } + + if (band == BAND_ON_2_4G) + rtlphy->txpwr_by_rate_base_24g[path][txnum][rate_section] = + value; + else /* BAND_ON_5G */ + rtlphy->txpwr_by_rate_base_5g[path][txnum][rate_section - 1] = + value; +} + +static u8 _rtl8822be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, u8 txnum, + u8 rate_section) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 value; + + if (path > RF90_PATH_D) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid Rf Path %d in phy_GetTxPowerByRatBase()\n", + path); + return 0; + } + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid band %d in phy_GetTxPowerByRatBase()\n", + band); + return 0; + } + + if (rate_section >= MAX_RATE_SECTION || + (band == BAND_ON_5G && rate_section == CCK)) { + RT_TRACE( + rtlpriv, COMP_INIT, DBG_LOUD, + "Invalid rate_section %d in phy_GetTxPowerByRatBase()\n", + rate_section); + return 0; + } + + if (band == BAND_ON_2_4G) + value = rtlphy->txpwr_by_rate_base_24g[path][txnum] + [rate_section]; + else /* BAND_ON_5G */ + value = rtlphy->txpwr_by_rate_base_5g[path][txnum] + [rate_section - 1]; + + return value; +} + +static void _rtl8822be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + struct { + enum rtl_desc_rate rate; + enum rate_section section; + } rate_sec_base[] = { + {DESC_RATE11M, CCK}, + {DESC_RATE54M, OFDM}, + {DESC_RATEMCS7, HT_MCS0_MCS7}, + {DESC_RATEMCS15, HT_MCS8_MCS15}, + {DESC_RATEVHT1SS_MCS7, VHT_1SSMCS0_1SSMCS9}, + {DESC_RATEVHT2SS_MCS7, VHT_2SSMCS0_2SSMCS9}, + }; + + u8 band, path, rs, tx_num, base; + u8 rate, section; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) { + for (path = RF90_PATH_A; path <= RF90_PATH_B; path++) { + for (rs = 0; rs < MAX_RATE_SECTION; rs++) { + rate = rate_sec_base[rs].rate; + section = rate_sec_base[rs].section; + + if (IS_1T_RATE(rate)) + tx_num = RF_1TX; + else + tx_num = RF_2TX; + + if (band == BAND_ON_5G && + RX_HAL_IS_CCK_RATE(rate)) + continue; + + base = rtlphy->tx_power_by_rate_offset + [band][path][tx_num][rate]; + _rtl8822be_phy_set_txpower_by_rate_base( + hw, band, path, section, tx_num, base); + } + } + } +} + +static void __rtl8822be_phy_cross_reference_core(struct ieee80211_hw *hw, + u8 regulation, u8 bw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rs, ref_rs; + s8 pwrlmt, ref_pwrlmt; + + for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) { + /*5G 20M 40M VHT and HT can cross reference*/ + if (bw != HT_CHANNEL_WIDTH_20 && bw != HT_CHANNEL_WIDTH_20_40) + continue; + + if (rs == HT_MCS0_MCS7) + ref_rs = VHT_1SSMCS0_1SSMCS9; + else if (rs == HT_MCS8_MCS15) + ref_rs = VHT_2SSMCS0_2SSMCS9; + else if (rs == VHT_1SSMCS0_1SSMCS9) + ref_rs = HT_MCS0_MCS7; + else if (rs == VHT_2SSMCS0_2SSMCS9) + ref_rs = HT_MCS8_MCS15; + else + continue; + + ref_pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][ref_rs] + [channel][RF90_PATH_A]; + if (ref_pwrlmt == MAX_POWER_INDEX) + continue; + + pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][rs][channel] + [RF90_PATH_A]; + if (pwrlmt != MAX_POWER_INDEX) + continue; + + rtlphy->txpwr_limit_5g[regulation][bw][rs][channel] + [RF90_PATH_A] = ref_pwrlmt; + } +} + +static void +_rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw) +{ + u8 regulation, bw, channel; + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; + ++channel) { + __rtl8822be_phy_cross_reference_core( + hw, regulation, bw, channel); + } + } + } +} + +static void __rtl8822be_txpwr_limit_to_index_2g(struct ieee80211_hw *hw, + u8 regulation, u8 bw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw40_pwr_base_dbm2_4G; + u8 rate_section; + s8 temp_pwrlmt; + enum rf_tx_num txnum; + s8 temp_value; + u8 rf_path; + + for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; + ++rate_section) { + /* obtain the base dBm values in 2.4G band + * CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15 + */ + + temp_pwrlmt = + rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section] + [channel][RF90_PATH_A]; + txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX; + + if (temp_pwrlmt == MAX_POWER_INDEX) + continue; + + for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM; + ++rf_path) { + bw40_pwr_base_dbm2_4G = + _rtl8822be_phy_get_txpower_by_rate_base( + hw, BAND_ON_2_4G, rf_path, txnum, + rate_section); + + temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G; + rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section] + [channel][rf_path] = temp_value; + + RT_TRACE( + rtlpriv, COMP_INIT, DBG_TRACE, + "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n", + regulation, bw, rate_section, channel, + rtlphy->txpwr_limit_2_4g[regulation][bw] + [rate_section][channel] + [rf_path], + (temp_pwrlmt == 63) ? 0 : temp_pwrlmt / 2, + channel, rf_path, bw40_pwr_base_dbm2_4G); + } + } +} + +static void __rtl8822be_txpwr_limit_to_index_5g(struct ieee80211_hw *hw, + u8 regulation, u8 bw, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw40_pwr_base_dbm5G; + u8 rate_section; + s8 temp_pwrlmt; + enum rf_tx_num txnum; + s8 temp_value; + u8 rf_path; + + for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; + ++rate_section) { + /* obtain the base dBm values in 5G band + * OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15, + * VHT => 1SSMCS7, VHT 2T => 2SSMCS7 + */ + + temp_pwrlmt = + rtlphy->txpwr_limit_5g[regulation][bw][rate_section] + [channel][RF90_PATH_A]; + txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX; + + if (temp_pwrlmt == MAX_POWER_INDEX) + continue; + + for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM; + ++rf_path) { + bw40_pwr_base_dbm5G = + _rtl8822be_phy_get_txpower_by_rate_base( + hw, BAND_ON_5G, rf_path, txnum, + rate_section); + + temp_value = temp_pwrlmt - bw40_pwr_base_dbm5G; + rtlphy->txpwr_limit_5g[regulation][bw][rate_section] + [channel][rf_path] = temp_value; + + RT_TRACE( + rtlpriv, COMP_INIT, DBG_TRACE, + "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n", + regulation, bw, rate_section, channel, + rtlphy->txpwr_limit_5g[regulation][bw] + [rate_section][channel] + [rf_path], + temp_pwrlmt, channel, rf_path, + bw40_pwr_base_dbm5G); + } + } +} + +static void +_rtl8822be_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 regulation, bw, channel; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "=====> %s()\n", __func__); + + _rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(hw); + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; + ++channel) { + __rtl8822be_txpwr_limit_to_index_2g( + hw, regulation, bw, channel); + } + } + } + + for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { + for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) { + for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; + ++channel) { + __rtl8822be_txpwr_limit_to_index_5g( + hw, regulation, bw, channel); + } + } + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<===== %s()\n", __func__); +} + +static void _rtl8822be_phy_init_txpower_limit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i, j, k, l, m; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "=====> %s()!\n", __func__); + + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m) + for (l = 0; l < MAX_RF_PATH_NUM; ++l) + rtlphy->txpwr_limit_2_4g[i][j] + [k][m] + [l] = + MAX_POWER_INDEX; + } + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j) + for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) + for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m) + for (l = 0; l < MAX_RF_PATH_NUM; ++l) + rtlphy->txpwr_limit_5g[i][j][k] + [m][l] = + MAX_POWER_INDEX; + } + + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<===== %s()!\n", __func__); +} + +static void +_rtl8822be_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + u8 base = 0, i = 0, value = 0, band = 0, path = 0, txnum = 0; + + for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) { + for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { + for (txnum = RF_1TX; txnum <= RF_2TX; ++txnum) { + /* CCK */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATE11M]; + for (i = 0; i < sizeof(cck_rates); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [cck_rates[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [cck_rates[i]] = value - base; + } + + /* OFDM */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATE54M]; + for (i = 0; i < sizeof(ofdm_rates); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ofdm_rates[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ofdm_rates[i]] = value - base; + } + + /* HT MCS0~7 */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEMCS7]; + for (i = 0; i < sizeof(ht_rates_1t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_1t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_1t[i]] = value - base; + } + + /* HT MCS8~15 */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEMCS15]; + for (i = 0; i < sizeof(ht_rates_2t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_2t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [ht_rates_2t[i]] = value - base; + } + + /* VHT 1SS */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEVHT1SS_MCS7]; + for (i = 0; i < sizeof(vht_rates_1t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_1t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_1t[i]] = + value - base; + } + + /* VHT 2SS */ + base = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [DESC_RATEVHT2SS_MCS7]; + for (i = 0; i < sizeof(vht_rates_2t); ++i) { + value = rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_2t[i]]; + rtlphy->tx_power_by_rate_offset + [band][path][txnum] + [vht_rates_2t[i]] = + value - base; + } + } + } + } + + RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "<===%s()\n", __func__); +} + +static void +_rtl8822be_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw) +{ + /* copy rate_section from + * tx_power_by_rate_offset[][rate] to txpwr_by_rate_base_24g/_5g[][rs] + */ + _rtl8822be_phy_store_txpower_by_rate_base(hw); + + /* convert tx_power_by_rate_offset[] to relative value */ + _rtl8822be_phy_convert_txpower_dbm_to_relative_value(hw); +} + +/* string is in decimal */ +static bool _rtl8822be_get_integer_from_string(char *str, u8 *pint) +{ + u16 i = 0; + *pint = 0; + + while (str[i] != '\0') { + if (str[i] >= '0' && str[i] <= '9') { + *pint *= 10; + *pint += (str[i] - '0'); + } else { + return false; + } + ++i; + } + + return true; +} + +static bool _rtl8822be_eq_n_byte(u8 *str1, u8 *str2, u32 num) +{ + if (num == 0) + return false; + while (num > 0) { + num--; + if (str1[num] != str2[num]) + return false; + } + return true; +} + +static char _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw, + u8 band, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + char channel_index = -1; + u8 i = 0; + + if (band == BAND_ON_2_4G) { + channel_index = channel - 1; + } else if (band == BAND_ON_5G) { + for (i = 0; i < sizeof(rtl_channel5g) / sizeof(u8); ++i) { + if (rtl_channel5g[i] == channel) + channel_index = i; + } + } else { + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s", + band, __func__); + } + + if (channel_index == -1) + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Invalid Channel %d of Band %d in %s", channel, band, + __func__); + + return channel_index; +} + +void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation, + u8 *pband, u8 *pbandwidth, + u8 *prate_section, u8 *prf_path, + u8 *pchannel, u8 *ppower_limit) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 regulation = 0, bandwidth = 0, rate_section = 0, channel; + u8 channel_index; + char power_limit = 0, prev_power_limit, ret; + + if (!_rtl8822be_get_integer_from_string((char *)pchannel, &channel) || + !_rtl8822be_get_integer_from_string((char *)ppower_limit, + &power_limit)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Illegal index of pwr_lmt table [chnl %d][val %d]\n", + channel, power_limit); + } + + power_limit = + power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit; + + if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("FCC"), 3)) + regulation = 0; + else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("MKK"), 3)) + regulation = 1; + else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("ETSI"), 4)) + regulation = 2; + else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("WW13"), 4)) + regulation = 3; + + if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("CCK"), 3)) + rate_section = CCK; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("OFDM"), 4)) + rate_section = OFDM; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + rate_section = HT_MCS0_MCS7; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + rate_section = HT_MCS8_MCS15; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + rate_section = VHT_1SSMCS0_1SSMCS9; + else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && + _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + rate_section = VHT_2SSMCS0_2SSMCS9; + + if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("20M"), 3)) + bandwidth = HT_CHANNEL_WIDTH_20; + else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("40M"), 3)) + bandwidth = HT_CHANNEL_WIDTH_20_40; + else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("80M"), 3)) + bandwidth = HT_CHANNEL_WIDTH_80; + else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("160M"), 4)) + bandwidth = 3; + + if (_rtl8822be_eq_n_byte(pband, (u8 *)("2.4G"), 4)) { + ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G, + channel); + + if (ret == -1) + return; + + channel_index = ret; + + prev_power_limit = + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]; + + if (power_limit < prev_power_limit) + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A] = power_limit; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n", + regulation, bandwidth, rate_section, channel_index, + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]); + } else if (_rtl8822be_eq_n_byte(pband, (u8 *)("5G"), 2)) { + ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G, + channel); + + if (ret == -1) + return; + + channel_index = ret; + + prev_power_limit = + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]; + + if (power_limit < prev_power_limit) + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A] = power_limit; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n", + regulation, bandwidth, rate_section, channel, + rtlphy->txpwr_limit_5g[regulation][bandwidth] + [rate_section][channel_index] + [RF90_PATH_A]); + + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Cannot recognize the band info in %s\n", pband); + return; + } +} + +bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool rtstatus = true; + + _rtl8822be_phy_init_tx_power_by_rate(hw); + + rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_by_rate(rtlpriv); + + if (!rtstatus) { + pr_err("BB_PG Reg Fail!!"); + return false; + } + + _rtl8822be_phy_txpower_by_rate_configuration(hw); + + return true; +} + +bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + bool rtstatus = true; + + _rtl8822be_phy_init_txpower_limit(hw); + + if (rtlefuse->eeprom_regulatory == 1) + ; + else + return true; + + rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_limit(rtlpriv); + + if (!rtstatus) { + pr_err("RF TxPwr Limit Fail!!"); + return false; + } + + _rtl8822be_phy_convert_txpower_limit_to_power_index(hw); + + return true; +} + +static void _rtl8822be_get_rate_values_of_tx_power_by_rate( + struct ieee80211_hw *hw, u32 reg_addr, u32 bit_mask, u32 value, + u8 *rate, s8 *pwr_by_rate_val, u8 *rate_num) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 /*index = 0,*/ i = 0; + + switch (reg_addr) { + case 0xE00: /*rTxAGC_A_Rate18_06:*/ + case 0x830: /*rTxAGC_B_Rate18_06:*/ + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE04: /*rTxAGC_A_Rate54_24:*/ + case 0x834: /*rTxAGC_B_Rate54_24:*/ + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE08: /*rTxAGC_A_CCK1_Mcs32:*/ + rate[0] = DESC_RATE1M; + pwr_by_rate_val[0] = (s8)((((value >> (8 + 4)) & 0xF)) * 10 + + ((value >> 8) & 0xF)); + *rate_num = 1; + break; + + case 0x86C: /*rTxAGC_B_CCK11_A_CCK2_11:*/ + if (bit_mask == 0xffffff00) { + rate[0] = DESC_RATE2M; + rate[1] = DESC_RATE5_5M; + rate[2] = DESC_RATE11M; + for (i = 1; i < 4; ++i) { + pwr_by_rate_val[i - 1] = (s8)( + (((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 3; + } else if (bit_mask == 0x000000ff) { + rate[0] = DESC_RATE11M; + pwr_by_rate_val[0] = (s8)((((value >> 4) & 0xF)) * 10 + + (value & 0xF)); + *rate_num = 1; + } + break; + + case 0xE10: /*rTxAGC_A_Mcs03_Mcs00:*/ + case 0x83C: /*rTxAGC_B_Mcs03_Mcs00:*/ + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE14: /*rTxAGC_A_Mcs07_Mcs04:*/ + case 0x848: /*rTxAGC_B_Mcs07_Mcs04:*/ + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE18: /*rTxAGC_A_Mcs11_Mcs08:*/ + case 0x84C: /*rTxAGC_B_Mcs11_Mcs08:*/ + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xE1C: /*rTxAGC_A_Mcs15_Mcs12:*/ + case 0x868: /*rTxAGC_B_Mcs15_Mcs12:*/ + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + + break; + + case 0x838: /*rTxAGC_B_CCK1_55_Mcs32:*/ + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + for (i = 1; i < 4; ++i) { + pwr_by_rate_val[i - 1] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 3; + break; + + case 0xC20: + case 0xE20: + case 0x1820: + case 0x1a20: + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + rate[3] = DESC_RATE11M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC24: + case 0xE24: + case 0x1824: + case 0x1a24: + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC28: + case 0xE28: + case 0x1828: + case 0x1a28: + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC2C: + case 0xE2C: + case 0x182C: + case 0x1a2C: + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC30: + case 0xE30: + case 0x1830: + case 0x1a30: + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC34: + case 0xE34: + case 0x1834: + case 0x1a34: + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC38: + case 0xE38: + case 0x1838: + case 0x1a38: + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC3C: + case 0xE3C: + case 0x183C: + case 0x1a3C: + rate[0] = DESC_RATEVHT1SS_MCS0; + rate[1] = DESC_RATEVHT1SS_MCS1; + rate[2] = DESC_RATEVHT1SS_MCS2; + rate[3] = DESC_RATEVHT1SS_MCS3; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC40: + case 0xE40: + case 0x1840: + case 0x1a40: + rate[0] = DESC_RATEVHT1SS_MCS4; + rate[1] = DESC_RATEVHT1SS_MCS5; + rate[2] = DESC_RATEVHT1SS_MCS6; + rate[3] = DESC_RATEVHT1SS_MCS7; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC44: + case 0xE44: + case 0x1844: + case 0x1a44: + rate[0] = DESC_RATEVHT1SS_MCS8; + rate[1] = DESC_RATEVHT1SS_MCS9; + rate[2] = DESC_RATEVHT2SS_MCS0; + rate[3] = DESC_RATEVHT2SS_MCS1; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC48: + case 0xE48: + case 0x1848: + case 0x1a48: + rate[0] = DESC_RATEVHT2SS_MCS2; + rate[1] = DESC_RATEVHT2SS_MCS3; + rate[2] = DESC_RATEVHT2SS_MCS4; + rate[3] = DESC_RATEVHT2SS_MCS5; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + case 0xC4C: + case 0xE4C: + case 0x184C: + case 0x1a4C: + rate[0] = DESC_RATEVHT2SS_MCS6; + rate[1] = DESC_RATEVHT2SS_MCS7; + rate[2] = DESC_RATEVHT2SS_MCS8; + rate[3] = DESC_RATEVHT2SS_MCS9; + for (i = 0; i < 4; ++i) { + pwr_by_rate_val[i] = + (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 + + ((value >> (i * 8)) & 0xF)); + } + *rate_num = 4; + break; + + default: + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + "Invalid reg_addr 0x%x in %s()\n", reg_addr, __func__); + break; + }; +} + +void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band, + u32 rfpath, u32 txnum, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 i = 0, rates[4] = {0}, rate_num = 0; + s8 pwr_by_rate_val[4] = {0}; + + _rtl8822be_get_rate_values_of_tx_power_by_rate( + hw, regaddr, bitmask, data, rates, pwr_by_rate_val, &rate_num); + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", + band); + band = BAND_ON_2_4G; + } + if (rfpath >= MAX_RF_PATH) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", + rfpath); + rfpath = MAX_RF_PATH - 1; + } + if (txnum >= MAX_RF_PATH) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", + txnum); + txnum = MAX_RF_PATH - 1; + } + + for (i = 0; i < rate_num; ++i) { + u8 rate_idx = rates[i]; + + if (IS_1T_RATE(rates[i])) + txnum = RF_1TX; + else if (IS_2T_RATE(rates[i])) + txnum = RF_2TX; + else + WARN_ON(1); + + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_idx] = + pwr_by_rate_val[i]; + + RT_TRACE( + rtlpriv, COMP_INIT, DBG_LOUD, + "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][rate_idx %d] = 0x%x\n", + band, rfpath, txnum, rate_idx, + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum] + [rate_idx]); + } +} + +static void +_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; + rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; + rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; + + rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8822B; + rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8822B; + + rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8822BE; + rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8822BE; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8822B; + rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8822B; + + rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8822B; + rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8822B; +} + +void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 txpwr_level; + long txpwr_dbm; + + txpwr_level = rtlphy->cur_cck_txpwridx; + txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > + txpwr_dbm) + txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, + txpwr_level); + txpwr_level = rtlphy->cur_ofdm24g_txpwridx; + if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, + txpwr_level) > txpwr_dbm) + txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm( + hw, WIRELESS_MODE_N_24G, txpwr_level); + *powerlevel = txpwr_dbm; +} + +static bool _rtl8822be_phy_get_chnl_index(u8 channel, u8 *chnl_index) +{ + u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ + u8 i = 0; + bool in_24g = true; + + if (channel <= 14) { + in_24g = true; + *chnl_index = channel - 1; + } else { + in_24g = false; + + for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) { + if (rtl_channel5g[i] == channel) { + *chnl_index = i; + return in_24g; + } + } + } + return in_24g; +} + +static char _rtl8822be_phy_get_world_wide_limit(char *limit_table) +{ + char min = limit_table[0]; + u8 i = 0; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) { + if (limit_table[i] < min) + min = limit_table[i]; + } + return min; +} + +static char _rtl8822be_phy_get_txpower_limit(struct ieee80211_hw *hw, u8 band, + enum ht_channel_width bandwidth, + enum radio_path rf_path, u8 rate, + u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + short regulation = -1, rate_section = -1, channel_index = -1; + char power_limit = MAX_POWER_INDEX; + + if (rtlefuse->eeprom_regulatory == 2) + return MAX_POWER_INDEX; + + regulation = TXPWR_LMT_WW; + + switch (rate) { + case DESC_RATE1M: + case DESC_RATE2M: + case DESC_RATE5_5M: + case DESC_RATE11M: + rate_section = CCK; + break; + + case DESC_RATE6M: + case DESC_RATE9M: + case DESC_RATE12M: + case DESC_RATE18M: + case DESC_RATE24M: + case DESC_RATE36M: + case DESC_RATE48M: + case DESC_RATE54M: + rate_section = OFDM; + break; + + case DESC_RATEMCS0: + case DESC_RATEMCS1: + case DESC_RATEMCS2: + case DESC_RATEMCS3: + case DESC_RATEMCS4: + case DESC_RATEMCS5: + case DESC_RATEMCS6: + case DESC_RATEMCS7: + rate_section = HT_MCS0_MCS7; + break; + + case DESC_RATEMCS8: + case DESC_RATEMCS9: + case DESC_RATEMCS10: + case DESC_RATEMCS11: + case DESC_RATEMCS12: + case DESC_RATEMCS13: + case DESC_RATEMCS14: + case DESC_RATEMCS15: + rate_section = HT_MCS8_MCS15; + break; + + case DESC_RATEVHT1SS_MCS0: + case DESC_RATEVHT1SS_MCS1: + case DESC_RATEVHT1SS_MCS2: + case DESC_RATEVHT1SS_MCS3: + case DESC_RATEVHT1SS_MCS4: + case DESC_RATEVHT1SS_MCS5: + case DESC_RATEVHT1SS_MCS6: + case DESC_RATEVHT1SS_MCS7: + case DESC_RATEVHT1SS_MCS8: + case DESC_RATEVHT1SS_MCS9: + rate_section = VHT_1SSMCS0_1SSMCS9; + break; + + case DESC_RATEVHT2SS_MCS0: + case DESC_RATEVHT2SS_MCS1: + case DESC_RATEVHT2SS_MCS2: + case DESC_RATEVHT2SS_MCS3: + case DESC_RATEVHT2SS_MCS4: + case DESC_RATEVHT2SS_MCS5: + case DESC_RATEVHT2SS_MCS6: + case DESC_RATEVHT2SS_MCS7: + case DESC_RATEVHT2SS_MCS8: + case DESC_RATEVHT2SS_MCS9: + rate_section = VHT_2SSMCS0_2SSMCS9; + break; + + default: + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Wrong rate 0x%x\n", + rate); + break; + } + + if (band == BAND_ON_5G && rate_section == 0) + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "Wrong rate 0x%x: No CCK in 5G Band\n", rate); + + /* workaround for wrong index combination to obtain tx power limit, + * OFDM only exists in BW 20M + */ + if (rate_section == 1) + bandwidth = 0; + + /* workaround for wrong index combination to obtain tx power limit, + * CCK table will only be given in BW 20M + */ + if (rate_section == 0) + bandwidth = 0; + + /* workaround for wrong indxe combination to obtain tx power limit, + * HT on 80M will reference to HT on 40M + */ + if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G && + bandwidth == 2) + bandwidth = 1; + + if (band == BAND_ON_2_4G) + channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt( + hw, BAND_ON_2_4G, channel); + else if (band == BAND_ON_5G) + channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt( + hw, BAND_ON_5G, channel); + else if (band == BAND_ON_BOTH) + ; /* BAND_ON_BOTH don't care temporarily */ + + if (band >= BANDMAX || regulation == -1 || bandwidth == -1 || + rate_section == -1 || channel_index == -1) { + RT_TRACE( + rtlpriv, COMP_POWER, DBG_LOUD, + "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n", + band, regulation, bandwidth, rf_path, rate_section, + channel_index); + return MAX_POWER_INDEX; + } + + if (band == BAND_ON_2_4G) { + char limits[10] = {0}; + u8 i = 0; + + for (i = 0; i < 4; ++i) + limits[i] = rtlphy->txpwr_limit_2_4g[i][bandwidth] + [rate_section] + [channel_index] + [rf_path]; + + power_limit = + (regulation == TXPWR_LMT_WW) ? + _rtl8822be_phy_get_world_wide_limit(limits) : + rtlphy->txpwr_limit_2_4g[regulation][bandwidth] + [rate_section] + [channel_index] + [rf_path]; + + } else if (band == BAND_ON_5G) { + char limits[10] = {0}; + u8 i = 0; + + for (i = 0; i < MAX_REGULATION_NUM; ++i) + limits[i] = + rtlphy->txpwr_limit_5g[i][bandwidth] + [rate_section] + [channel_index][rf_path]; + + power_limit = + (regulation == TXPWR_LMT_WW) ? + _rtl8822be_phy_get_world_wide_limit(limits) : + rtlphy->txpwr_limit_5g[regulation] + [channel_index] + [rate_section] + [channel_index][rf_path]; + } else + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "No power limit table of the specified band\n"); + + return power_limit; +} + +static char +_rtl8822be_phy_get_txpower_by_rate(struct ieee80211_hw *hw, u8 band, u8 path, + u8 rate /* enum rtl_desc8822b_rate */) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 tx_num; + char tx_pwr_diff = 0; + + if (band != BAND_ON_2_4G && band != BAND_ON_5G) + return tx_pwr_diff; + + if (path > RF90_PATH_B) + return tx_pwr_diff; + + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9)) + tx_num = RF_2TX; + else + tx_num = RF_1TX; + + tx_pwr_diff = (char)(rtlphy->tx_power_by_rate_offset[band][path][tx_num] + [rate] & + 0xff); + + return tx_pwr_diff; +} + +u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate, + u8 bandwidth, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u8 index = (channel - 1); + u8 txpower = 0; + bool in_24g = false; + char limit; + char powerdiff_byrate = 0; + + if (((rtlhal->current_bandtype == BAND_ON_2_4G) && + (channel > 14 || channel < 1)) || + ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) { + index = 0; + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Illegal channel!!\n"); + } + + /* 1. base tx power */ + in_24g = _rtl8822be_phy_get_chnl_index(channel, &index); + if (in_24g) { + if (RX_HAL_IS_CCK_RATE(rate)) + txpower = rtlefuse->txpwrlevel_cck[path][index]; + else if (rate >= DESC_RATE6M) + txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; + else + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "invalid rate\n"); + + if (rate >= DESC_RATE6M && rate <= DESC_RATE54M && + !RX_HAL_IS_CCK_RATE(rate)) + txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S]; + + if (bandwidth == HT_CHANNEL_WIDTH_20) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht20diff[path][TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht20diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_80) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += + rtlefuse->txpwr_ht40diff[path][TX_2S]; + } + + } else { + if (rate >= DESC_RATE6M) + txpower = rtlefuse->txpwr_5g_bw40base[path][index]; + else + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING, + "INVALID Rate.\n"); + + if (rate >= DESC_RATE6M && rate <= DESC_RATE54M && + !RX_HAL_IS_CCK_RATE(rate)) + txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S]; + + if (bandwidth == HT_CHANNEL_WIDTH_20) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw20diff[path] + [TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw20diff[path] + [TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw40diff[path] + [TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw40diff[path] + [TX_2S]; + } else if (bandwidth == HT_CHANNEL_WIDTH_80) { + u8 i = 0; + + for (i = 0; i < sizeof(rtl_channel5g_80m) / sizeof(u8); + ++i) + if (rtl_channel5g_80m[i] == channel) + index = i; + + txpower = rtlefuse->txpwr_5g_bw80base[path][index]; + + if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw80diff[path] + [TX_1S]; + if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || + (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9)) + txpower += rtlefuse->txpwr_5g_bw80diff[path] + [TX_2S]; + } + } + + /* 2. tx power by rate */ + if (rtlefuse->eeprom_regulatory != 2) + powerdiff_byrate = _rtl8822be_phy_get_txpower_by_rate( + hw, (u8)(!in_24g), path, rate); + + /* 3. tx power limit */ + if (rtlefuse->eeprom_regulatory == 1) + limit = _rtl8822be_phy_get_txpower_limit( + hw, (u8)(!in_24g), bandwidth, path, rate, + channel); + else + limit = MAX_POWER_INDEX; + + /* ----- */ + powerdiff_byrate = powerdiff_byrate > limit ? limit : powerdiff_byrate; + + txpower += powerdiff_byrate; + + if (txpower > MAX_POWER_INDEX) + txpower = MAX_POWER_INDEX; + + return txpower; +} + +static void _rtl8822be_phy_set_txpower_index(struct ieee80211_hw *hw, + u8 power_index, u8 path, u8 rate) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 shift = 0; + static u32 index; + + /* + * For 8822B, phydm api use 4 bytes txagc value + * driver must combine every four 1 byte to one 4 byte and send to phydm + */ + shift = rate & 0x03; + index |= ((u32)power_index << (shift * 8)); + + if (shift == 3) { + rate = rate - 3; + + if (!rtlpriv->phydm.ops->phydm_write_txagc(rtlpriv, index, path, + rate)) { + RT_TRACE(rtlpriv, COMP_TXAGC, DBG_LOUD, + "%s(index:%d, rfpath:%d, rate:0x%02x) fail\n", + __func__, index, path, rate); + + WARN_ON(1); + } + index = 0; + } +} + +static void _rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 *array, u8 path, + u8 channel, u8 size) +{ + struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy); + u8 i; + u8 power_index; + + for (i = 0; i < size; i++) { + power_index = rtl8822be_get_txpower_index( + hw, path, array[i], rtlphy->current_chan_bw, channel); + _rtl8822be_phy_set_txpower_index(hw, power_index, path, + array[i]); + } +} + +void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 channel, u8 path) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + + /* + * Below order is *VERY* important! + * Because _rtl8822be_phy_set_txpower_index() do actually writing + * every four power values. + */ + if (rtlhal->current_bandtype == BAND_ON_2_4G) + _rtl8822be_phy_set_txpower_level_by_path( + hw, cck_rates, path, channel, sizes_of_cck_retes); + _rtl8822be_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel, + sizes_of_ofdm_retes); + _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel, + sizes_of_ht_retes_1t); + _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, channel, + sizes_of_ht_retes_2t); + _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, + channel, sizes_of_vht_retes); + _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_2t, path, + channel, sizes_of_vht_retes); +} + +void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel, + u8 path, enum rate_section rs) +{ + struct { + u8 *array; + u8 size; + } rs_ref[MAX_RATE_SECTION] = { + {cck_rates, sizes_of_cck_retes}, + {ofdm_rates, sizes_of_ofdm_retes}, + {ht_rates_1t, sizes_of_ht_retes_1t}, + {ht_rates_2t, sizes_of_ht_retes_2t}, + {vht_rates_1t, sizes_of_vht_retes}, + {vht_rates_2t, sizes_of_vht_retes}, + }; + + if (rs >= MAX_RATE_SECTION) + return; + + _rtl8822be_phy_set_txpower_level_by_path(hw, rs_ref[rs].array, path, + channel, rs_ref[rs].size); +} + +void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 path = 0; + + for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path) + rtl8822be_phy_set_txpower_level_by_path(hw, channel, path); +} + +static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, + enum wireless_mode wirelessmode, + u8 txpwridx) +{ + long offset; + long pwrout_dbm; + + switch (wirelessmode) { + case WIRELESS_MODE_B: + offset = -7; + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + offset = -8; + break; + default: + offset = -8; + break; + } + pwrout_dbm = txpwridx / 2 + offset; + return pwrout_dbm; +} + +void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_BACKUP_BAND1: + iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + pr_err("Unknown Scan Backup operation.\n"); + break; + } + } +} + +static u8 _rtl8822be_phy_get_pri_ch_id(struct rtl_priv *rtlpriv) +{ + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 pri_ch_idx = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + /* primary channel is at lower subband of 80MHz & 40MHz */ + if ((mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)) { + pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ; + /* primary channel is at + * lower subband of 80MHz & upper subband of 40MHz + */ + } else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) { + pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ; + /* primary channel is at + * upper subband of 80MHz & lower subband of 40MHz + */ + } else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) { + pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ; + /* primary channel is at + * upper subband of 80MHz & upper subband of 40MHz + */ + } else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) { + pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ; + } else { + if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) + pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) + pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ; + } + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + /* primary channel is at upper subband of 40MHz */ + if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER) + pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ; + /* primary channel is at lower subband of 40MHz */ + else if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) + pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ; + else + ; + } + + return pri_ch_idx; +} + +void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u8 tmp_bw = rtlphy->current_chan_bw; + + if (rtlphy->set_bwmode_inprogress) + return; + rtlphy->set_bwmode_inprogress = true; + if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { + /* get primary channel index */ + u8 pri_ch_idx = _rtl8822be_phy_get_pri_ch_id(rtlpriv); + + /* 3.1 set MAC register */ + rtlpriv->halmac.ops->halmac_set_bandwidth( + rtlpriv, rtlphy->current_channel, pri_ch_idx, + rtlphy->current_chan_bw); + + /* 3.2 set BB/RF registet */ + rtlpriv->phydm.ops->phydm_switch_bandwidth( + rtlpriv, pri_ch_idx, rtlphy->current_chan_bw); + + if (!mac->act_scanning) + rtlpriv->phydm.ops->phydm_iq_calibrate(rtlpriv); + + rtlphy->set_bwmode_inprogress = false; + } else { + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "FALSE driver sleep or unload\n"); + rtlphy->set_bwmode_inprogress = false; + rtlphy->current_chan_bw = tmp_bw; + } +} + +u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + u32 timeout = 1000, timecount = 0; + u8 channel = rtlphy->current_channel; + + if (rtlphy->sw_chnl_inprogress) + return 0; + if (rtlphy->set_bwmode_inprogress) + return 0; + + if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { + RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, + "sw_chnl_inprogress false driver sleep or unload\n"); + return 0; + } + while (rtlphy->lck_inprogress && timecount < timeout) { + mdelay(50); + timecount += 50; + } + + if (rtlphy->current_channel > 14) + rtlhal->current_bandtype = BAND_ON_5G; + else if (rtlphy->current_channel <= 14) + rtlhal->current_bandtype = BAND_ON_2_4G; + + if (rtlpriv->cfg->ops->get_btc_status()) + rtlpriv->btcoexist.btc_ops->btc_switch_band_notify( + rtlpriv, rtlhal->current_bandtype, mac->act_scanning); + else + rtlpriv->btcoexist.btc_ops->btc_switch_band_notify_wifi_only( + rtlpriv, rtlhal->current_bandtype, mac->act_scanning); + + rtlpriv->phydm.ops->phydm_switch_band(rtlpriv, rtlphy->current_channel); + + rtlphy->sw_chnl_inprogress = true; + if (channel == 0) + channel = 1; + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, + "switch to channel%d, band type is %d\n", + rtlphy->current_channel, rtlhal->current_bandtype); + + rtlpriv->phydm.ops->phydm_switch_channel(rtlpriv, + rtlphy->current_channel); + + rtlpriv->phydm.ops->phydm_clear_txpowertracking_state(rtlpriv); + + rtl8822be_phy_set_txpower_level(hw, rtlphy->current_channel); + + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); + rtlphy->sw_chnl_inprogress = false; + return 1; +} + +bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool postprocessing = false; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", iotype, + rtlphy->set_io_inprogress); + do { + switch (iotype) { + case IO_CMD_RESUME_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Resume DM after scan.\n"); + postprocessing = true; + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "[IO CMD] Pause DM before scan.\n"); + postprocessing = true; + break; + default: + pr_err("switch case not process\n"); + break; + } + } while (false); + if (postprocessing && !rtlphy->set_io_inprogress) { + rtlphy->set_io_inprogress = true; + rtlphy->current_io_type = iotype; + } else { + return false; + } + rtl8822be_phy_set_io(hw); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); + return true; +} + +static void rtl8822be_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + break; + case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: + break; + default: + pr_err("switch case not process\n"); + break; + } + rtlphy->set_io_inprogress = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "(%#x)\n", + rtlphy->current_io_type); +} + +static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, REG_SPS0_CTRL_8822B, 0x2b); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE2); + rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3); + rtl_write_byte(rtlpriv, REG_TXPAUSE_8822B, 0x00); +} + +static bool _rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + bool bresult = true; + u8 i, queue_id; + struct rtl8192_tx_ring *ring = NULL; + + switch (rfpwr_state) { + case ERFON: + if ((ppsc->rfpwr_state == ERFOFF) && + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus = false; + u32 initialize_count = 0; + + do { + initialize_count++; + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); + rtstatus = rtl_ps_enable_nic(hw); + } while ((!rtstatus) && (initialize_count < 10)); + RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "Set ERFON slept:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); + ppsc->last_awake_jiffies = jiffies; + rtl8822be_phy_set_rf_on(hw); + } + if (mac->link_state == MAC80211_LINKED) + rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); + else + rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); + break; + case ERFOFF: + for (queue_id = 0, i = 0; + queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { + ring = &pcipriv->dev.tx_ring[queue_id]; + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { + queue_id++; + continue; + } else { + RT_TRACE( + rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); + + udelay(10); + i++; + } + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE( + rtlpriv, COMP_ERR, DBG_WARNING, + "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, queue_id, + skb_queue_len(&ring->queue)); + break; + } + } + + if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); + rtl_ps_disable_nic(hw); + RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); + } else { + if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { + rtlpriv->cfg->ops->led_control(hw, + LED_CTL_NO_LINK); + } else { + rtlpriv->cfg->ops->led_control( + hw, LED_CTL_POWER_OFF); + } + } + break; + default: + pr_err("switch case not process\n"); + bresult = false; + break; + } + if (bresult) + ppsc->rfpwr_state = rfpwr_state; + return bresult; +} + +bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state) +{ + struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + + bool bresult = false; + + if (rfpwr_state == ppsc->rfpwr_state) + return bresult; + bresult = _rtl8822be_phy_set_rf_power_state(hw, rfpwr_state); + return bresult; +} diff --git a/drivers/staging/rtlwifi/rtl8822be/phy.h b/drivers/staging/rtlwifi/rtl8822be/phy.h new file mode 100644 index 000000000000..5c33f16bcaa4 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/phy.h @@ -0,0 +1,145 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822BE_PHY_H__ +#define __RTL8822BE_PHY_H__ + +/* It must always set to 4, otherwise read + * efuse table sequence will be wrong. + */ +#define MAX_TX_COUNT 4 +#define TX_1S 0 +#define TX_2S 1 +#define TX_3S 2 +#define TX_4S 3 + +#define MAX_POWER_INDEX 0x3F + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define RT_CANNOT_IO(hw) false +#define HIGHPOWER_RADIOA_ARRAYLEN 22 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM 9 +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 10 +#define index_mapping_NUM 15 + +#define APK_BB_REG_NUM 5 +#define APK_AFE_REG_NUM 16 +#define APK_CURVE_REG_NUM 4 +#define PATH_NUM 2 + +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 +#define ANTENNA_DIVERSITY_VALUE 0x80 +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define RESET_CNT_LIMIT 3 + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 + +#define RF6052_MAX_PATH 2 + +#define CT_OFFSET_MAC_ADDR 0X16 + +#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A +#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 +#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 +#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 +#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C + +#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F +#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 + +#define CT_OFFSET_CHANNEL_PLAH 0x75 +#define CT_OFFSET_THERMAL_METER 0x78 +#define CT_OFFSET_RF_OPTION 0x79 +#define CT_OFFSET_VERSION 0x7E +#define CT_OFFSET_CUSTOMER_ID 0x7F + +#define RTL8822BE_MAX_PATH_NUM 2 + +#define TARGET_CHNL_NUM_2G_5G_8822B 59 + +u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask); +void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); +u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); +void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); +bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw); +bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw); +bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv); +bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv); +void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel); +void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); +void rtl8822be_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw); +void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl8822be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +void rtl8822be_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); +void rtl8822be_phy_lc_calibrate(struct ieee80211_hw *hw); +void rtl8822be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); +bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8822be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); +bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); +void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, + u8 channel, u8 path); +void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold); +void rtl8822be_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, + u8 thermal_value, u8 threshold); +void rtl8822be_reset_iqk_result(struct ieee80211_hw *hw); + +u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate, + u8 bandwidth, u8 channel); +void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel, + u8 path, enum rate_section rs); +void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band, + u32 rfpath, u32 txnum, u32 regaddr, + u32 bitmask, u32 data); +void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation, + u8 *pband, u8 *pbandwidth, + u8 *prate_section, u8 *prf_path, + u8 *pchannel, u8 *ppower_limit); +bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw); +bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw); + +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/reg.h b/drivers/staging/rtlwifi/rtl8822be/reg.h new file mode 100644 index 000000000000..0dca5dccf49a --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/reg.h @@ -0,0 +1,1653 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_REG_H__ +#define __RTL8822B_REG_H__ + +#include "../halmac/halmac_reg_8822b.h" +#include "../halmac/halmac_bit_8822b.h" + +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +/* Page 0 */ +#define REG_LEDCFG2_8822B 0x004E /* need review */ +#define REG_SPS0_CTRL_8822B 0x0011 /* need review: swlps */ + +#define REG_EFUSE_ACCESS_8822B (REG_PMC_DBG_CTRL2_8822B + 3) /*0x00CF*/ +#define REG_AFE_XTAL_CTRL_8822B REG_AFE_CTRL1_8822B +#define REG_AFE_PLL_CTRL_8822B REG_AFE_CTRL2_8822B + +/* Page 1 */ + +#define MSR (REG_CR_8822B + 2) + +/* for MSR 0x102 */ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +/*----------------------------------------------------- + * + * 0x0200h ~ 0x027Fh TXDMA Configuration + * + *----------------------------------------------------- + */ + +/*----------------------------------------------------- + * + * 0x0280h ~ 0x02FFh RXDMA Configuration + * + *----------------------------------------------------- + */ +#define REG_RXDMA_CONTROL_8822B (REG_RXPKT_NUM_8822B + 2) /* 0x0286 */ + +/*----------------------------------------------------- + * + * 0x0300h ~ 0x03FFh PCIe + * + *----------------------------------------------------- + */ + +/* REG_HIMR3_8822B */ +#define IMR_H2CDOK BIT_SETH2CDOK_MASK_8822B + +/* spec version 11 + *----------------------------------------------------- + * + * 0x0400h ~ 0x047Fh Protocol Configuration + * + *----------------------------------------------------- + */ + +#define REG_MAX_AGGR_NUM_8822B (REG_PROT_MODE_CTRL_8822B + 2) /*0x04CA*/ + +/* for RRSR 0x440 */ +#define RRSR_RSC_OFFSET 21 +#define RRSR_SHORT_OFFSET 23 +#define RRSR_RSC_BW_40M 0x600000 +#define RRSR_RSC_UPSUBCHNL 0x400000 +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_1M BIT(0) +#define RRSR_2M BIT(1) +#define RRSR_5_5M BIT(2) +#define RRSR_11M BIT(3) +#define RRSR_6M BIT(4) +#define RRSR_9M BIT(5) +#define RRSR_12M BIT(6) +#define RRSR_18M BIT(7) +#define RRSR_24M BIT(8) +#define RRSR_36M BIT(9) +#define RRSR_48M BIT(10) +#define RRSR_54M BIT(11) +#define RRSR_MCS0 BIT(12) +#define RRSR_MCS1 BIT(13) +#define RRSR_MCS2 BIT(14) +#define RRSR_MCS3 BIT(15) +#define RRSR_MCS4 BIT(16) +#define RRSR_MCS5 BIT(17) +#define RRSR_MCS6 BIT(18) +#define RRSR_MCS7 BIT(19) + +#define RRSR_ALL_CCK (RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M) +#define RRSR_ALL_OFDM_AG \ + (RRSR_6M | RRSR_9M | RRSR_12M | RRSR_18M | RRSR_24M | RRSR_36M | \ + RRSR_48M | RRSR_54M) + +/*----------------------------------------------------- + * + * 0x0500h ~ 0x05FFh EDCA Configuration + * + *----------------------------------------------------- + */ + +#define REG_SIFS_TRX_8822B (REG_SIFS_8822B + 2) /*0x0516*/ + +/*----------------------------------------------------- + * + * 0x0600h ~ 0x07FFh WMAC Configuration + * + *----------------------------------------------------- + */ + +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +/* CAM definition */ + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 + +/*#define TOTAL_CAM_ENTRY 64*/ +/*#define HALF_CAM_ENTRY 32*/ + +#define CAM_WRITE BIT(16) +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT(31) + +/********************************************* + * 8822BE IMR/ISR bits + ********************************************* + */ +#define IMR_DISABLED 0x0 +/* IMR DW0(0x0060-0063) Bit 0-31 */ +#define IMR_TIMER2 BIT(31) +#define IMR_TIMER1 BIT(30) +#define IMR_PSTIMEOUT BIT(29) +#define IMR_GTINT4 BIT(28) +#define IMR_GTINT3 BIT(27) +#define IMR_TBDER BIT(26) +#define IMR_TBDOK BIT(25) +#define IMR_TSF_BIT32_TOGGLE BIT(24) +#define IMR_BCNDMAINT0 BIT(20) +#define IMR_BCNDOK0 BIT(16) +#define IMR_HSISR_IND_ON_INT BIT(15) +#define IMR_BCNDMAINT_E BIT(14) +#define IMR_ATIMEND BIT(12) +#define IMR_HISR1_IND_INT BIT(11) +#define IMR_C2HCMD BIT(10) +#define IMR_CPWM2 BIT(9) +#define IMR_CPWM BIT(8) +#define IMR_HIGHDOK BIT(7) +#define IMR_MGNTDOK BIT(6) +#define IMR_BKDOK BIT(5) +#define IMR_BEDOK BIT(4) +#define IMR_VIDOK BIT(3) +#define IMR_VODOK BIT(2) +#define IMR_RDU BIT(1) +#define IMR_ROK BIT(0) + +/* IMR DW1(0x00B4-00B7) Bit 0-31 */ +#define IMR_TXFIFO_TH_INT_8822B BIT_TXFIFO_TH_INT_8822B +#define IMR_BTON_STS_UPDATE_MASK_8822B BIT_BTON_STS_UPDATE_MASK_8822B +#define IMR_MCUERR BIT(28) +#define IMR_BCNDMAINT7 BIT(27) +#define IMR_BCNDMAINT6 BIT(26) +#define IMR_BCNDMAINT5 BIT(25) +#define IMR_BCNDMAINT4 BIT(24) +#define IMR_BCNDMAINT3 BIT(23) +#define IMR_BCNDMAINT2 BIT(22) +#define IMR_BCNDMAINT1 BIT(21) +#define IMR_BCNDOK7 BIT(20) +#define IMR_BCNDOK6 BIT(19) +#define IMR_BCNDOK5 BIT(18) +#define IMR_BCNDOK4 BIT(17) +#define IMR_BCNDOK3 BIT(16) +#define IMR_BCNDOK2 BIT(15) +#define IMR_BCNDOK1 BIT(14) +#define IMR_ATIMEND_E BIT(13) +#define IMR_ATIMEND BIT(12) +#define IMR_TXERR BIT(11) +#define IMR_RXERR BIT(10) +#define IMR_TXFOVW BIT(9) +#define IMR_RXFOVW BIT(8) +#define IMR_CPU_MGQ_TXDONE_MSK_8822B BIT_CPU_MGQ_TXDONE_MSK_8822B +#define IMR_PS_TIMER_C_MSK_8822B BIT_PS_TIMER_C_MSK_8822B +#define IMR_PS_TIMER_B_MSK_8822B BIT_PS_TIMER_B_MSK_8822B +#define IMR_PS_TIMER_A_MSK_8822B BIT_PS_TIMER_A_MSK_8822B +#define IMR_CPUMGQ_TX_TIMER_MSK_8822B BIT_CPUMGQ_TX_TIMER_MSK_8822B + +/********************************************* + * 8822BE EFUSE definition + ********************************************* + */ +#define HWSET_MAX_SIZE 1024 +#define EFUSE_MAX_SECTION 64 +#define EFUSE_REAL_CONTENT_LEN 1024 +#define EFUSE_OOB_PROTECT_BYTES 18 + +#define EEPROM_DEFAULT_THERMALMETER 0x12 + +#define RTL8822B_EEPROM_ID 0x8129 + +#define PPG_BB_GAIN_2G_TXA_OFFSET_8822B 0xEE +#define PPG_THERMAL_OFFSET_8822B 0xEF + +#define EEPROM_TX_PWR_INX_8822B 0x10 + +#define EEPROM_CHANNEL_PLAN_8822B 0xB8 +#define EEPROM_XTAL_8822B 0xB9 +#define EEPROM_THERMAL_METER_8822B 0xBA +#define EEPROM_IQK_LCK_8822B 0xBB +#define EEPROM_2G_5G_PA_TYPE_8822B 0xBC +/* PATH A & PATH B */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_AB_8822B 0xBD +/* PATH C & PATH D */ +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_CD_8822B 0xBE +/* PATH A & PATH B */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_AB_8822B 0xBF +/* PATH C & PATH D */ +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_CD_8822B 0xC0 + +#define EEPROM_RF_BOARD_OPTION_8822B 0xC1 +#define EEPROM_FEATURE_OPTION_8822B 0xC2 +#define EEPROM_RF_BT_SETTING_8822B 0xC3 +#define EEPROM_VERSION_8822B 0xC4 +#define EEPROM_CUSTOM_ID_8822B 0xC5 +#define EEPROM_TX_BBSWING_2G_8822B 0xC6 +#define EEPROM_TX_PWR_CALIBRATE_RATE_8822B 0xC8 +#define EEPROM_RF_ANTENNA_OPT_8822B 0xC9 +#define EEPROM_RFE_OPTION_8822B 0xCA +#define EEPROM_COUNTRY_CODE_8822B 0xCB + +#define EEPROM_VID 0xD6 +#define EEPROM_DID 0xD8 +#define EEPROM_SVID 0xDA +#define EEPROM_SMID 0xDC + +/* RTL8822BU */ +#define EEPROM_MAC_ADDR_8822BU 0x107 +#define EEPROM_VID_8822BU 0x100 +#define EEPROM_PID_8822BU 0x102 +#define EEPROM_USB_OPTIONAL_FUNCTION0_8822BU 0x104 +#define EEPROM_USB_MODE_8822BU 0x06 + +/* RTL8822BS */ +#define EEPROM_MAC_ADDR_8822BS 0x11A + +/* RTL8822BE */ +#define EEPROM_MAC_ADDR_8822BE 0xD0 + +/* ------------------------- */ + +#define STOPBECON BIT(6) +#define STOPHIGHT BIT(5) +#define STOPMGT BIT(4) +#define STOPVO BIT(3) +#define STOPVI BIT(2) +#define STOPBE BIT(1) +#define STOPBK BIT(0) + +#define RCR_APPFCS BIT(31) +#define RCR_APP_MIC BIT(30) +#define RCR_APP_ICV BIT(29) +#define RCR_APP_PHYST_RXFF BIT(28) +#define RCR_APP_BA_SSN BIT(27) +#define RCR_VHT_DACK BIT(26) +#define RCR_ENMBID BIT(24) +#define RCR_LSIGEN BIT(23) +#define RCR_MFBEN BIT(22) +#define RCR_HTC_LOC_CTRL BIT(14) +#define RCR_AMF BIT(13) +#define RCR_ACF BIT(12) +#define RCR_ADF BIT(11) +#define RCR_AICV BIT(9) +#define RCR_ACRC32 BIT(8) +#define RCR_CBSSID_BCN BIT(7) +#define RCR_CBSSID_DATA BIT(6) +#define RCR_CBSSID RCR_CBSSID_DATA +#define RCR_APWRMGT BIT(5) +#define RCR_ADD3 BIT(4) +#define RCR_AB BIT(3) +#define RCR_AM BIT(2) +#define RCR_APM BIT(1) +#define RCR_AAP BIT(0) +#define RCR_MXDMA_OFFSET 8 +#define RCR_FIFO_OFFSET 13 + +#define RSV_CTRL 0x001C +#define RD_CTRL 0x0524 + +#define REG_USB_INFO_8822B 0xFE17 +#define REG_USB_SPECIAL_OPTION_8822B 0xFE55 +#define REG_USB_DMA_AGG_TO_8822B 0xFE5B +#define REG_USB_AGG_TO_8822B 0xFE5C +#define REG_USB_AGG_TH_8822B 0xFE5D + +#define REG_USB_VID_8822B 0xFE60 +#define REG_USB_PID_8822B 0xFE62 +#define REG_USB_OPTIONAL_8822B 0xFE64 +#define REG_USB_CHIRP_K_8822B 0xFE65 +#define REG_USB_PHY_8822B 0xFE66 +#define REG_USB_MAC_ADDR_8822B 0xFE70 +#define REG_USB_HRPWM_8822B 0xFE58 +#define REG_USB_HCPWM_8822B 0xFE57 + +#define SW18_FPWM BIT(3) + +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) + +#define PWC_EV25V BIT(14) +#define PWC_EV12V BIT(15) + +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTN BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EN_PDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) +#define _80M_SSC_DIS BIT(7) +#define _80M_SSC_EN_HO BIT(8) +#define PHY_SSC_RSTB BIT(9) +#define SEC_CLK_EN BIT(10) +#define MAC_CLK_EN BIT(11) +#define SYS_CLK_EN BIT(12) +#define RING_CLK_EN BIT(13) + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + +#define AFE_BGEN BIT(0) +#define AFE_MBEN BIT(1) +#define MAC_ID_EN BIT(7) + +#define WLOCK_ALL BIT(0) +#define WLOCK_00 BIT(1) +#define WLOCK_04 BIT(2) +#define WLOCK_08 BIT(3) +#define WLOCK_40 BIT(4) +#define R_DIS_PRST_0 BIT(5) +#define R_DIS_PRST_1 BIT(6) +#define LOCK_ALL_EN BIT(7) + +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +#define LDA15_EN BIT(0) +#define LDA15_STBY BIT(1) +#define LDA15_OBUF BIT(2) +#define LDA15_REG_VOS BIT(3) +#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) + +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + +#define XTAL_EN BIT(0) +#define XTAL_BSEL BIT(1) +#define _XTAL_BOSC(x) (((x) & 0x3) << 2) +#define _XTAL_CADJ(x) (((x) & 0xF) << 4) +#define XTAL_GATE_USB BIT(8) +#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) +#define XTAL_GATE_AFE BIT(11) +#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) +#define XTAL_RF_GATE BIT(14) +#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) +#define XTAL_GATE_DIG BIT(17) +#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) +#define XTAL_BT_GATE BIT(20) +#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) +#define _XTAL_GPIO(x) (((x) & 0x7) << 23) + +#define CKDLY_AFE BIT(26) +#define CKDLY_USB BIT(27) +#define CKDLY_DIG BIT(28) +#define CKDLY_BT BIT(29) + +#define APLL_EN BIT(0) +#define APLL_320_EN BIT(1) +#define APLL_FREF_SEL BIT(2) +#define APLL_EDGE_SEL BIT(3) +#define APLL_WDOGB BIT(4) +#define APLL_LPFEN BIT(5) + +#define APLL_REF_CLK_13MHZ 0x1 +#define APLL_REF_CLK_19_2MHZ 0x2 +#define APLL_REF_CLK_20MHZ 0x3 +#define APLL_REF_CLK_25MHZ 0x4 +#define APLL_REF_CLK_26MHZ 0x5 +#define APLL_REF_CLK_38_4MHZ 0x6 +#define APLL_REF_CLK_40MHZ 0x7 + +#define APLL_320EN BIT(14) +#define APLL_80EN BIT(15) +#define APLL_1MEN BIT(24) + +#define ALD_EN BIT(18) +#define EF_PD BIT(19) +#define EF_FLAG BIT(31) + +#define EF_TRPT BIT(7) +#define LDOE25_EN BIT(31) + +#define RSM_EN BIT(0) +#define TIMER_EN BIT(4) + +#define TRSW0EN BIT(2) +#define TRSW1EN BIT(3) +#define EROM_EN BIT(4) +#define EN_BT BIT(5) +#define EN_UART BIT(8) +#define UART_910 BIT(9) +#define EN_PMAC BIT(10) +#define SIC_SWRST BIT(11) +#define EN_SIC BIT(12) +#define SIC_23 BIT(13) +#define EN_HDP BIT(14) +#define SIC_LBK BIT(15) + +#define LED0PL BIT(4) +#define LED1PL BIT(12) +#define LED0DIS BIT(7) + +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_CHKSUM_RPT BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define CPRST BIT(23) + +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 +#define CHIP_VER_RTL_SHIFT 12 + +#define REG_LBMODE_8822B (REG_CR_8822B + 3) + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) + +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +#define _LBMODE(x) (((x) & 0xF) << 24) +#define MASK_LBMODE 0xF000000 +#define LOOPBACK_NORMAL 0x0 +#define LOOPBACK_IMMEDIATELY 0xB +#define LOOPBACK_MAC_DELAY 0x3 +#define LOOPBACK_PHY 0x1 +#define LOOPBACK_DMA 0x7 + +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +#define _TXDMA_HIQ_MAP(x) (((x) & 0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x) & 0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x) & 0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x) & 0x3) << 8) +#define _TXDMA_VIQ_MAP(x) (((x) & 0x3) << 6) +#define _TXDMA_VOQ_MAP(x) (((x) & 0x3) << 4) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) +#define BB_WRITE_EN BIT(30) +#define BB_READ_EN BIT(31) + +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + +#define BCN_VALID BIT(16) +#define BCN_HEAD(x) (((x) & 0xFF) << 8) +#define BCN_HEAD_MASK 0xFF00 + +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + +#define DROP_DATA_EN BIT(9) + +#define EN_AMPDU_RTY_NEW BIT(7) + +#define _INIRTSMCS_SEL(x) ((x) & 0x3F) + +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +#define RATE_REG_BITMAP_ALL 0xFFFFF + +#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) + +#define _RRSR_RSC(x) (((x) & 0x3) << 21) +#define RRSR_RSC_RESERVED 0x0 +#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 +#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 +#define RRSR_RSC_DUPLICATE_MODE 0x3 + +#define USE_SHORT_G1 BIT(20) + +#define _AGGLMT_MCS0(x) ((x) & 0xF) +#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) +#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) +#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) +#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) +#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) +#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) +#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) + +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _DARF_RC1(x) ((x) & 0x1F) +#define _DARF_RC2(x) (((x) & 0x1F) << 8) +#define _DARF_RC3(x) (((x) & 0x1F) << 16) +#define _DARF_RC4(x) (((x) & 0x1F) << 24) +#define _DARF_RC5(x) ((x) & 0x1F) +#define _DARF_RC6(x) (((x) & 0x1F) << 8) +#define _DARF_RC7(x) (((x) & 0x1F) << 16) +#define _DARF_RC8(x) (((x) & 0x1F) << 24) + +#define _RARF_RC1(x) ((x) & 0x1F) +#define _RARF_RC2(x) (((x) & 0x1F) << 8) +#define _RARF_RC3(x) (((x) & 0x1F) << 16) +#define _RARF_RC4(x) (((x) & 0x1F) << 24) +#define _RARF_RC5(x) ((x) & 0x1F) +#define _RARF_RC6(x) (((x) & 0x1F) << 8) +#define _RARF_RC7(x) (((x) & 0x1F) << 16) +#define _RARF_RC8(x) (((x) & 0x1F) << 24) + +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + +#define _AIFS(x) (x) +#define _ECW_MAX_MIN(x) ((x) << 8) +#define _TXOP_LIMIT(x) ((x) << 16) + +#define _BCNIFS(x) ((x) & 0xFF) +#define _BCNECW(x) ((((x) & 0xF)) << 8) + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + +#define _SIFS_CCK_CTX(x) ((x) & 0xFF) +#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8) + +#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) +#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8) + +#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) + +#define DIS_EDCA_CNT_DWN BIT(11) + +#define EN_MBSSID BIT(1) +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +#define TSFTR_RST BIT(0) +#define TSFTR1_RST BIT(1) + +#define STOP_BCNQ BIT(6) + +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + +#define ACMHW_HW_EN BIT(0) +#define ACMHW_BEQ_EN BIT(1) +#define ACMHW_VIQ_EN BIT(2) +#define ACMHW_VOQ_EN BIT(3) +#define ACMHW_BEQ_STATUS BIT(4) +#define ACMHW_VIQ_STATUS BIT(5) +#define ACMHW_VOQ_STATUS BIT(6) + +#define APSDOFF BIT(6) +#define APSDOFF_STATUS BIT(7) + +#define BW_20MHZ BIT(2) + +#define RATE_BITMAP_ALL 0xFFFFF + +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 + +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EN_MBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + +#define _MIN_SPACE(x) ((x) & 0x7) +#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) + +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +#define SCR_TX_USE_DK BIT(0) +#define SCR_RX_USE_DK BIT(1) +#define SCR_TX_ENC_ENABLE BIT(2) +#define SRC_RX_DEC_ENABLE BIT(3) +#define SCR_SK_BY_A2 BIT(4) +#define SCR_NO_SKMC BIT(5) +#define SCR_TXBCUSEDK BIT(6) +#define SCR_RXBCUSEDK BIT(7) + +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +#define USB_TEST_EP_MASK 0x30 +#define USB_TEST_EP_SHIFT 4 + +#define USB_AGG_EN BIT(3) + +#define MAC_ADDR_LEN 6 +#define LAST_ENTRY_OF_TX_PKT_BUFFER 175 + +#define POLLING_LLT_THRESHOLD 20 +#define POLLING_READY_TIMEOUT_COUNT 3000 + +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +#define EPROM_CMD_OPERATING_MODE_MASK ((1 << 7) | (1 << 6)) +#define EPROM_CMD_CONFIG 0x3 +#define EPROM_CMD_LOAD 1 + +#define HAL_8822B_HW_GPIO_WPS_BIT BIT(2) + +/*----------------------------------------------------- + * BB / RF register + *----------------------------------------------------- + */ + +#define RFPGA0_XA_HSSIPARAMETER1 0x820 +#define RFPGA0_XA_HSSIPARAMETER2 0x824 +#define RFPGA0_XB_HSSIPARAMETER1 0x828 +#define RFPGA0_XB_HSSIPARAMETER2 0x82c +#define RCCAONSEC 0x838 + +#define RFPGA0_XA_LSSIPARAMETER 0x840 +#define RFPGA0_XB_LSSIPARAMETER 0x844 +#define RL1PEAKTH 0x848 + +#define RFPGA0_RFWAKEUPPARAMETER 0x850 +#define RFPGA0_RFSLEEPUPPARAMETER 0x854 + +#define RFPGA0_XAB_SWITCHCONTROL 0x858 +#define RFPGA0_XCD_SWITCHCONTROL 0x85c + +#define RFPGA0_XA_RFINTERFACEOE 0x860 +#define RFC_AREA 0x860 +#define RFPGA0_XB_RFINTERFACEOE 0x864 + +#define RFPGA0_XAB_RFINTERFACESW 0x870 +#define RFPGA0_XCD_RFINTERFACESW 0x874 + +#define RFPGA0_XAB_RF_PARA_METER 0x878 +#define RFPGA0_XCD_RF_PARA_METER 0x87c + +#define RFPGA0_ANALOGPARAMETER1 0x880 +#define RFPGA0_ANALOGPARAMETER2 0x884 +#define RFPGA0_ANALOGPARAMETER3 0x888 +#define RFPGA0_ANALOGPARAMETER4 0x88c + +#define RFPGA0_XA_LSSIREADBACK 0x8a0 +#define RFPGA0_XB_LSSIREADBACK 0x8a4 +#define RFPGA0_XC_LSSIREADBACK 0x8a8 +/*#define RFPGA0_XD_LSSIREADBACK 0x8ac*/ +#define RRFMOD 0x8ac +#define RHSSIREAD_8822BE 0x8b0 + +#define RFPGA0_PSDREPORT 0x8b4 +#define TRANSCEIVEA_HSPI_READBACK 0x8b8 +#define TRANSCEIVEB_HSPI_READBACK 0x8bc +/*#define REG_SC_CNT_8822B 0x8c4*/ +#define RADC_BUF_CLK 0x8c4 +#define RFPGA0_XAB_RFINTERFACERB 0x8e0 +#define RFPGA0_XCD_RFINTERFACERB 0x8e4 + +/* PageB(0xB00) */ + +/*Page C*/ + +#define RA_TXPWRTRAING 0xc54 +#define RB_TXPWRTRAING 0xe54 + +#define RA_LSSIWRITE_8822B 0xc90 +#define RB_LSSIWRITE_8822B 0xe90 + +#define RA_PIREAD_8822B 0xd04 +#define RB_PIREAD_8822B 0xd44 +#define RA_SIREAD_8822B 0xd08 +#define RB_SIREAD_8822B 0xd48 + +#define RZEBRA1_HSSIENABLE 0x0 +#define RZEBRA1_TRXENABLE1 0x1 +#define RZEBRA1_TRXENABLE2 0x2 +#define RZEBRA1_AGC 0x4 +#define RZEBRA1_CHARGEPUMP 0x5 +#define RZEBRA1_CHANNEL 0x7 + +#define RZEBRA1_TXGAIN 0x8 +#define RZEBRA1_TXLPF 0x9 +#define RZEBRA1_RXLPF 0xb +#define RZEBRA1_RXHPFCORNER 0xc + +#define RGLOBALCTRL 0 +#define RRTL8256_TXLPF 19 +#define RRTL8256_RXLPF 11 +#define RRTL8258_TXLPF 0x11 +#define RRTL8258_RXLPF 0x13 +#define RRTL8258_RSSILPF 0xa + +#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 +#define RF_CHNLBW 0x18 +#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 0x42 + +#define RF_SYN_G1 0x25 +#define RF_SYN_G2 0x26 +#define RF_SYN_G3 0x27 +#define RF_SYN_G4 0x28 +#define RF_SYN_G5 0x29 +#define RF_SYN_G6 0x2A +#define RF_SYN_G7 0x2B +#define RF_SYN_G8 0x2C + +#define RF_RCK_OS 0x30 +#define RF_TXPA_G1 0x31 +#define RF_TXPA_G2 0x32 +#define RF_TXPA_G3 0x33 + +#define RF_TX_BIAS_A 0x35 +#define RF_TX_BIAS_D 0x36 +#define RF_LOBF_9 0x38 +#define RF_RXRF_A3 0x3C +#define RF_TRSW 0x3F + +#define RF_TXRF_A2 0x41 +#define RF_TXPA_G4 0x46 +#define RF_TXPA_A4 0x4B + +#define RF_APK 0x63 + +#define RF_WE_LUT 0xEF + +#define BBBRESETB 0x100 +#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 BCCKTXLENGHT 0xffff0000 +#define BCCKTXCRC16 0xffff +#define BCCKTXSTATUS 0x1 +#define BOFDMTXSTATUS 0x2 +#define IS_BB_REG_OFFSET_92S(_offset) ((_offset >= 0x800) && (_offset <= 0xfff)) + +#define BRFMOD 0x1 +#define BJAPANMODE 0x2 +#define BCCKTXSC 0x30 +/* Block & Path enable*/ +#define ROFDMCCKEN 0x808 +#define BCCKEN 0x10000000 +#define BOFDMEN 0x20000000 +/* Rx antenna*/ +#define RRXPATH 0x808 +#define BRXPATH 0xff +/* Tx antenna*/ +#define RTXPATH 0x80c +#define BTXPATH 0x0fffffff +/* for cck rx path selection*/ +#define RCCK_RX 0xa04 +#define BCCK_RX 0x0c000000 +/* Use LSIG for VHT length*/ +#define RVHTLEN_USE_LSIG 0x8c3 + +#define BOFDMRXADCPHASE 0x10000 +#define BOFDMTXDACPHASE 0x40000 +#define BXATXAGC 0x3f + +#define BXBTXAGC 0xf00 +#define BXCTXAGC 0xf000 +#define BXDTXAGC 0xf0000 + +#define BPASTART 0xf0000000 +#define BTRSTART 0x00f00000 +#define BRFSTART 0x0000f000 +#define BBBSTART 0x000000f0 +#define BBBCCKSTART 0x0000000f +#define BPAEND 0xf +#define BTREND 0x0f000000 +#define BRFEND 0x000f0000 +#define BCCAMASK 0x000000f0 +#define BR2RCCAMASK 0x00000f00 +#define BHSSI_R2TDELAY 0xf8000000 +#define BHSSI_T2RDELAY 0xf80000 +#define BCONTXHSSI 0x400 +#define BIGFROMCCK 0x200 +#define BAGCADDRESS 0x3f +#define BRXHPTX 0x7000 +#define BRXHP2RX 0x38000 +#define BRXHPCCKINI 0xc0000 +#define BAGCTXCODE 0xc00000 +#define BAGCRXCODE 0x300000 + +#define B3WIREDATALENGTH 0x800 +#define B3WIREADDREAALENGTH 0x400 + +#define B3WIRERFPOWERDOWN 0x1 +#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 + +#define BRFSI_TRSW 0x20 +#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 +#define BLSSIREADEDGE 0x80000000 + +#define BLSSIREADBACKDATA 0xfffff + +#define BLSSIREADOKFLAG 0x1000 +#define BCCKSAMPLERATE 0x8 +#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 + +#define BADCLKPHASE 0x4000000 +#define B80MCLKDELAY 0x18000000 +#define BAFEWATCHDOGENABLE 0x20000000 + +#define BXTALCAP01 0xc0000000 +#define BXTALCAP23 0x3 +#define BXTALCAP92X 0x0f000000 +#define BXTALCAP 0x0f000000 + +#define BINTDIFCLKENABLE 0x400 +#define BEXTSIGCLKENABLE 0x800 +#define BBANDGAP_MBIAS_POWERUP 0x10000 +#define BAD11SH_GAIN 0xc0000 +#define BAD11NPUT_RANGE 0x700000 +#define BAD110P_CURRENT 0x3800000 +#define BLPATH_LOOPBACK 0x4000000 +#define BQPATH_LOOPBACK 0x8000000 +#define BAFE_LOOPBACK 0x10000000 +#define BDA10_SWING 0x7e0 +#define BDA10_REVERSE 0x800 +#define BDA_CLK_SOURCE 0x1000 +#define BDA7INPUT_RANGE 0x6000 +#define BDA7_GAIN 0x38000 +#define BDA7OUTPUT_CM_MODE 0x40000 +#define BDA7INPUT_CM_MODE 0x380000 +#define BDA7CURRENT 0xc00000 +#define BREGULATOR_ADJUST 0x7000000 +#define BAD11POWERUP_ATTX 0x1 +#define BDA10PS_ATTX 0x10 +#define BAD11POWERUP_ATRX 0x100 +#define BDA10PS_ATRX 0x1000 +#define BCCKRX_AGC_FORMAT 0x200 +#define BPSDFFT_SAMPLE_POINT 0xc000 +#define BPSD_AVERAGE_NUM 0x3000 +#define BIQPATH_CONTROL 0xc00 +#define BPSD_FREQ 0x3ff +#define BPSD_ANTENNA_PATH 0x30 +#define BPSD_IQ_SWITCH 0x40 +#define BPSD_RX_TRIGGER 0x400000 +#define BPSD_TX_TRIGGER 0x80000000 +#define BPSD_SINE_TONE_SCALE 0x7f000000 +#define BPSD_REPORT 0xffff + +#define BOFDM_TXSC 0x30000000 +#define BCCK_TXON 0x1 +#define BOFDM_TXON 0x2 +#define BDEBUG_PAGE 0xfff +#define BDEBUG_ITEM 0xff +#define BANTL 0x10 +#define BANT_NONHT 0x100 +#define BANT_HT1 0x1000 +#define BANT_HT2 0x10000 +#define BANT_HT1S1 0x100000 +#define BANT_NONHTS1 0x1000000 + +#define BCCK_BBMODE 0x3 +#define BCCK_TXPOWERSAVING 0x80 +#define BCCK_RXPOWERSAVING 0x40 + +#define BCCK_SIDEBAND 0x10 + +#define BCCK_SCRAMBLE 0x8 +#define BCCK_ANTDIVERSITY 0x8000 +#define BCCK_CARRIER_RECOVERY 0x4000 +#define BCCK_TXRATE 0x3000 +#define BCCK_DCCANCEL 0x0800 +#define BCCK_ISICANCEL 0x0400 +#define BCCK_MATCH_FILTER 0x0200 +#define BCCK_EQUALIZER 0x0100 +#define BCCK_PREAMBLE_DETECT 0x800000 +#define BCCK_FAST_FALSECCA 0x400000 +#define BCCK_CH_ESTSTART 0x300000 +#define BCCK_CCA_COUNT 0x080000 +#define BCCK_CS_LIM 0x070000 +#define BCCK_BIST_MODE 0x80000000 +#define BCCK_CCAMASK 0x40000000 +#define BCCK_TX_DAC_PHASE 0x4 +#define BCCK_RX_ADC_PHASE 0x20000000 +#define BCCKR_CP_MODE 0x0100 +#define BCCK_TXDC_OFFSET 0xf0 +#define BCCK_RXDC_OFFSET 0xf +#define BCCK_CCA_MODE 0xc000 +#define BCCK_FALSECS_LIM 0x3f00 +#define BCCK_CS_RATIO 0xc00000 +#define BCCK_CORGBIT_SEL 0x300000 +#define BCCK_PD_LIM 0x0f0000 +#define BCCK_NEWCCA 0x80000000 +#define BCCK_RXHP_OF_IG 0x8000 +#define BCCK_RXIG 0x7f00 +#define BCCK_LNA_POLARITY 0x800000 +#define BCCK_RX1ST_BAIN 0x7f0000 +#define BCCK_RF_EXTEND 0x20000000 +#define BCCK_RXAGC_SATLEVEL 0x1f000000 +#define BCCK_RXAGC_SATCOUNT 0xe0 +#define BCCK_RX_RF_SETTLE 0x1f +#define BCCK_FIXED_RXAGC 0x8000 +#define BCCK_ANTENNA_POLARITY 0x2000 +#define BCCK_TXFILTER_TYPE 0x0c00 +#define BCCK_RXAGC_REPORTTYPE 0x0300 +#define BCCK_RXDAGC_EN 0x80000000 +#define BCCK_RXDAGC_PERIOD 0x20000000 +#define BCCK_RXDAGC_SATLEVEL 0x1f000000 +#define BCCK_TIMING_RECOVERY 0x800000 +#define BCCK_TXC0 0x3f0000 +#define BCCK_TXC1 0x3f000000 +#define BCCK_TXC2 0x3f +#define BCCK_TXC3 0x3f00 +#define BCCK_TXC4 0x3f0000 +#define BCCK_TXC5 0x3f000000 +#define BCCK_TXC6 0x3f +#define BCCK_TXC7 0x3f00 +#define BCCK_DEBUGPORT 0xff0000 +#define BCCK_DAC_DEBUG 0x0f000000 +#define BCCK_FALSEALARM_ENABLE 0x8000 +#define BCCK_FALSEALARM_READ 0x4000 +#define BCCK_TRSSI 0x7f +#define BCCK_RXAGC_REPORT 0xfe +#define BCCK_RXREPORT_ANTSEL 0x80000000 +#define BCCK_RXREPORT_MFOFF 0x40000000 +#define BCCK_RXREPORT_SQLOSS 0x20000000 +#define BCCK_RXREPORT_PKTLOSS 0x10000000 +#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 +#define BCCK_RXREPORT_RATEERROR 0x04000000 +#define BCCK_RXREPORT_RXRATE 0x03000000 +#define BCCK_RXFA_COUNTER_LOWER 0xff +#define BCCK_RXFA_COUNTER_UPPER 0xff000000 +#define BCCK_RXHPAGC_START 0xe000 +#define BCCK_RXHPAGC_FINAL 0x1c00 +#define BCCK_RXFALSEALARM_ENABLE 0x8000 +#define BCCK_FACOUNTER_FREEZE 0x4000 +#define BCCK_TXPATH_SEL 0x10000000 +#define BCCK_DEFAULT_RXPATH 0xc000000 +#define BCCK_OPTION_RXPATH 0x3000000 + +#define BNUM_OFSTF 0x3 +#define BSHIFT_L 0xc0 +#define BGI_TH 0xc +#define BRXPATH_A 0x1 +#define BRXPATH_B 0x2 +#define BRXPATH_C 0x4 +#define BRXPATH_D 0x8 +#define BTXPATH_A 0x1 +#define BTXPATH_B 0x2 +#define BTXPATH_C 0x4 +#define BTXPATH_D 0x8 +#define BTRSSI_FREQ 0x200 +#define BADC_BACKOFF 0x3000 +#define BDFIR_BACKOFF 0xc000 +#define BTRSSI_LATCH_PHASE 0x10000 +#define BRX_LDC_OFFSET 0xff +#define BRX_QDC_OFFSET 0xff00 +#define BRX_DFIR_MODE 0x1800000 +#define BRX_DCNF_TYPE 0xe000000 +#define BRXIQIMB_A 0x3ff +#define BRXIQIMB_B 0xfc00 +#define BRXIQIMB_C 0x3f0000 +#define BRXIQIMB_D 0xffc00000 +#define BDC_DC_NOTCH 0x60000 +#define BRXNB_NOTCH 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 BRADIO_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 BCFOLOOPBACK 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 BTXIQDCOFFSET 0xff00 +#define BTXDFIRMODE 0x10000 +#define BTXPESUDO_NOISEON 0x4000000 +#define BTXPESUDO_NOISE_A 0xff +#define BTXPESUDO_NOISE_B 0xff00 +#define BTXPESUDO_NOISE_C 0xff0000 +#define BTXPESUDO_NOISE_D 0xff000000 +#define BCCA_DROPOPTION 0x20000 +#define BCCA_DROPTHRES 0xfff00000 +#define BEDCCA_H 0xf +#define BEDCCA_L 0xf0 +#define BLAMBDA_ED 0x300 +#define BRX_INITIALGAIN 0x7f +#define BRX_ANTDIV_EN 0x80 +#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 +#define BRX_HIGHPOWER_FLOW 0x8000 +#define BRX_AGC_FREEZE_THRES 0xc0000 +#define BRX_FREEZESTEP_AGC1 0x300000 +#define BRX_FREEZESTEP_AGC2 0xc00000 +#define BRX_FREEZESTEP_AGC3 0x3000000 +#define BRX_FREEZESTEP_AGC0 0xc000000 +#define BRXRSSI_CMP_EN 0x10000000 +#define BRXQUICK_AGCEN 0x20000000 +#define BRXAGC_FREEZE_THRES_MODE 0x40000000 +#define BRX_OVERFLOW_CHECKTYPE 0x80000000 +#define BRX_AGCSHIFT 0x7f +#define BTRSW_TRI_ONLY 0x80 +#define BPOWER_THRES 0x300 +#define BRXAGC_EN 0x1 +#define BRXAGC_TOGETHER_EN 0x2 +#define BRXAGC_MIN 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 +#define BRSSI_GEN 0x7f000000 +#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 BRXPROCESS_TIME_DAGC 0x300000 +#define BRXSETTLE_HSSI 0x400000 +#define BRXPROCESS_TIME_BBPPW 0x800000 +#define BRXANTENNA_POWER_SHIFT 0x3000000 +#define BRSSI_TABLE_SELECT 0xc000000 +#define BRXHP_FINAL 0x7000000 +#define BRXHPSETTLE_BBP 0x7 +#define BRXHTSETTLE_HSSI 0x8 +#define BRXHTSETTLE_RXHP 0x70 +#define BRXHTSETTLE_BBPPW 0x80 +#define BRXHTSETTLE_IDLE 0x300 +#define BRXHTSETTLE_RESERVED 0x1c00 +#define BRXHT_RXHP_EN 0x8000 +#define BRXAGC_FREEZE_THRES 0x30000 +#define BRXAGC_TOGETHEREN 0x40000 +#define BRXHTAGC_MIN 0x80000 +#define BRXHTAGC_EN 0x100000 +#define BRXHTDAGC_EN 0x200000 +#define BRXHT_RXHP_BBP 0x1c00000 +#define BRXHT_RXHP_FINAL 0xe0000000 +#define BRXPW_RADIO_TH 0x3 +#define BRXPW_RADIO_EN 0x4 +#define BRXMF_HOLD 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_FUARD_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 BMF_WEIGHT_SUM 0x300000 +#define BMINIDX_TH 0x7f000000 +#define BDAFORMAT 0x40000 +#define BTXCH_EMU_ENABLE 0x01000000 +#define BTRSW_ISOLATION_A 0x7f +#define BTRSW_ISOLATION_B 0x7f00 +#define BTRSW_ISOLATION_C 0x7f0000 +#define BTRSW_ISOLATION_D 0x7f000000 +#define BEXT_LNA_GAIN 0x7c00 + +#define BSTBC_EN 0x4 +#define BANTENNA_MAPPING 0x10 +#define BNSS 0x20 +#define BCFO_ANTSUM_ID 0x200 +#define BPHY_COUNTER_RESET 0x8000000 +#define BCFO_REPORT_GET 0x4000000 +#define BOFDM_CONTINUE_TX 0x10000000 +#define BOFDM_SINGLE_CARRIER 0x20000000 +#define BOFDM_SINGLE_TONE 0x40000000 +#define BHT_DETECT 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 BSHORTCFOT_LENGTH 12 +#define BSHORTCFOF_LENGTH 11 +#define BLONGCFO 0x7ff +#define BLONGCFOT_LENGTH 11 +#define BLONGCFOF_LENGTH 11 +#define BTAILCFO 0x1fff +#define BTAILCFOT_LENGTH 13 +#define BTAILCFOF_LENGTH 12 +#define BNOISE_EN_PWDB 0xffff +#define BCC_POWER_DB 0xffff0000 +#define BMOISE_PWDB 0xffff +#define BPOWERMEAST_LENGTH 10 +#define BPOWERMEASF_LENGTH 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 BSNR_EVMT_LENGTH 8 +#define BSNR_EVMF_LENGTH 1 +#define BCSI1ST 0xff +#define BCSI2ND 0xff00 +#define BRXEVM1ST 0xff0000 +#define BRXEVM2ND 0xff000000 +#define BSIGEVM 0xff +#define BPWDB 0xff00 +#define BSGIEN 0x10000 + +#define BSFACTOR_QMA1 0xf +#define BSFACTOR_QMA2 0xf0 +#define BSFACTOR_QMA3 0xf00 +#define BSFACTOR_QMA4 0xf000 +#define BSFACTOR_QMA5 0xf0000 +#define BSFACTOR_QMA6 0xf0000 +#define BSFACTOR_QMA7 0xf00000 +#define BSFACTOR_QMA8 0xf000000 +#define BSFACTOR_QMA9 0xf0000000 +#define BCSI_SCHEME 0x100000 + +#define BNOISE_LVL_TOP_SET 0x3 +#define BCHSMOOTH 0x4 +#define BCHSMOOTH_CFG1 0x38 +#define BCHSMOOTH_CFG2 0x1c0 +#define BCHSMOOTH_CFG3 0xe00 +#define BCHSMOOTH_CFG4 0x7000 +#define BMRCMODE 0x800000 +#define BTHEVMCFG 0x7000000 + +#define BLOOP_FIT_TYPE 0x1 +#define BUPD_CFO 0x40 +#define BUPD_CFO_OFFDATA 0x80 +#define BADV_UPD_CFO 0x100 +#define BADV_TIME_CTRL 0x800 +#define BUPD_CLKO 0x1000 +#define BFC 0x6000 +#define BTRACKING_MODE 0x8000 +#define BPHCMP_ENABLE 0x10000 +#define BUPD_CLKO_LTF 0x20000 +#define BCOM_CH_CFO 0x40000 +#define BCSI_ESTI_MODE 0x80000 +#define BADV_UPD_EQZ 0x100000 +#define BUCHCFG 0x7000000 +#define BUPDEQZ 0x8000000 + +#define BRX_PESUDO_NOISE_ON 0x20000000 +#define BRX_PESUDO_NOISE_A 0xff +#define BRX_PESUDO_NOISE_B 0xff00 +#define BRX_PESUDO_NOISE_C 0xff0000 +#define BRX_PESUDO_NOISE_D 0xff000000 +#define BRX_PESUDO_NOISESTATE_A 0xffff +#define BRX_PESUDO_NOISESTATE_B 0xffff0000 +#define BRX_PESUDO_NOISESTATE_C 0xffff +#define BRX_PESUDO_NOISESTATE_D 0xffff0000 + +#define BZEBRA1_HSSIENABLE 0x8 +#define BZEBRA1_TRXCONTROL 0xc00 +#define BZEBRA1_TRXGAINSETTING 0x07f +#define BZEBRA1_RXCOUNTER 0xc00 +#define BZEBRA1_TXCHANGEPUMP 0x38 +#define BZEBRA1_RXCHANGEPUMP 0x7 +#define BZEBRA1_CHANNEL_NUM 0xf80 +#define BZEBRA1_TXLPFBW 0x400 +#define BZEBRA1_RXLPFBW 0x600 + +#define BRTL8256REG_MODE_CTRL1 0x100 +#define BRTL8256REG_MODE_CTRL0 0x40 +#define BRTL8256REG_TXLPFBW 0x18 +#define BRTL8256REG_RXLPFBW 0x600 + +#define BRTL8258_TXLPFBW 0xc +#define BRTL8258_RXLPFBW 0xc00 +#define BRTL8258_RSSILPFBW 0xc0 + +#define BBYTE0 0x1 +#define BBYTE1 0x2 +#define BBYTE2 0x4 +#define BBYTE3 0x8 +#define BWORD0 0x3 +#define BWORD1 0xc +#define BWORD 0xf + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define BMASKBYTE0 0xff +#define BMASKBYTE1 0xff00 +#define BMASKBYTE2 0xff0000 +#define BMASKBYTE3 0xff000000 +#define BMASKHWORD 0xffff0000 +#define BMASKLWORD 0x0000ffff +#define BMASKDWORD 0xffffffff +#define BMASK12BITS 0xfff +#define BMASKH4BITS 0xf0000000 +#define BMASKOFDM_D 0xffc00000 +#define BMASKCCK 0x3f3f3f3f + +#define BRFREGOFFSETMASK 0xfffff + +/* WOL bit information */ +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_FW_DISCONNECT BIT(4) + +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/sw.c b/drivers/staging/rtlwifi/rtl8822be/sw.c new file mode 100644 index 000000000000..91b784b6d1c5 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/sw.c @@ -0,0 +1,481 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../core.h" +#include "../pci.h" +#include "../base.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "hw.h" +#include "sw.h" +#include "fw.h" +#include "trx.h" +#include "led.h" +#include "../btcoexist/rtl_btc.h" +#include "../halmac/rtl_halmac.h" +#include "../phydm/rtl_phydm.h" +#include +#include + +static void rtl8822be_init_aspm_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + + /*close ASPM for AMD defaultly */ + rtlpci->const_amdpci_aspm = 0; + + /* + * ASPM PS mode. + * 0 - Disable ASPM, + * 1 - Enable ASPM without Clock Req, + * 2 - Enable ASPM with Clock Req, + * 3 - Alwyas Enable ASPM with Clock Req, + * 4 - Always Enable ASPM without Clock Req. + * set default to RTL8822BE:3 RTL8822B:2 + * + */ + rtlpci->const_pci_aspm = 3; + + /*Setting for PCI-E device */ + rtlpci->const_devicepci_aspm_setting = 0x03; + + /*Setting for PCI-E bridge */ + rtlpci->const_hostpci_aspm_setting = 0x02; + + /* + * In Hw/Sw Radio Off situation. + * 0 - Default, + * 1 - From ASPM setting without low Mac Pwr, + * 2 - From ASPM setting with low Mac Pwr, + * 3 - Bus D3 + * set default to RTL8822BE:0 RTL8192SE:2 + */ + rtlpci->const_hwsw_rfoff_d3 = 0; + + /* + * This setting works for those device with + * backdoor ASPM setting such as EPHY setting. + * 0 - Not support ASPM, + * 1 - Support ASPM, + * 2 - According to chipset. + */ + rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support; +} + +int rtl8822be_init_sw_vars(struct ieee80211_hw *hw) +{ + int err = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + const char *fw_name; + struct rtl_phydm_params params; + + rtl8822be_bt_reg_init(hw); + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); + rtlpriv->halmac.ops = rtl_halmac_get_ops_pointer(); + rtlpriv->halmac.ops->halmac_init_adapter(rtlpriv); + + /* should after halmac_init_adapter() */ + rtl8822be_read_eeprom_info(hw, ¶ms); + + /* need eeprom info */ + rtlpriv->phydm.ops = rtl_phydm_get_ops_pointer(); + rtlpriv->phydm.ops->phydm_init_priv(rtlpriv, ¶ms); + + rtlpriv->dm.dm_initialgain_enable = 1; + rtlpriv->dm.dm_flag = 0; + rtlpriv->dm.disable_framebursting = 0; + /*rtlpriv->dm.thermalvalue = 0;*/ + rtlpriv->dm.useramask = 1; /* turn on RA */ + rtlpci->transmit_config = CFENDFORM | BIT(15); + + rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; + /*following 2 is for register 5G band, refer to _rtl_init_mac80211()*/ + rtlpriv->rtlhal.bandset = BAND_ON_BOTH; + rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; + + rtlpci->receive_config = (RCR_APPFCS | + RCR_APP_MIC | + RCR_APP_ICV | + RCR_APP_PHYST_RXFF | + RCR_VHT_DACK | + RCR_HTC_LOC_CTRL | + /*RCR_AMF |*/ + RCR_CBSSID_BCN | + RCR_CBSSID_DATA | + /*RCR_ACF |*/ + /*RCR_ADF |*/ + /*RCR_AICV |*/ + /*RCR_ACRC32 |*/ + RCR_AB | + RCR_AM | + RCR_APM | + 0); + + rtlpci->irq_mask[0] = (u32)(IMR_PSTIMEOUT | + /*IMR_TBDER |*/ + /*IMR_TBDOK |*/ + /*IMR_BCNDMAINT0 |*/ + IMR_GTINT3 | + IMR_HSISR_IND_ON_INT | + IMR_C2HCMD | + IMR_HIGHDOK | + IMR_MGNTDOK | + IMR_BKDOK | + IMR_BEDOK | + IMR_VIDOK | + IMR_VODOK | + IMR_RDU | + IMR_ROK | + 0); + + rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | IMR_TXFOVW | 0); + rtlpci->irq_mask[3] = (u32)(BIT_SETH2CDOK_MASK | 0); + + /* for LPS & IPS */ + rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; + rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; + rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; + rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support; + if (rtlpriv->cfg->mod_params->disable_watchdog) + pr_info("watchdog disabled\n"); + rtlpriv->psc.reg_fwctrl_lps = 2; + rtlpriv->psc.reg_max_lps_awakeintvl = 2; + /* for ASPM, you can close aspm through + * set const_support_pciaspm = 0 + */ + rtl8822be_init_aspm_vars(hw); + + if (rtlpriv->psc.reg_fwctrl_lps == 1) + rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 2) + rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; + else if (rtlpriv->psc.reg_fwctrl_lps == 3) + rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = false; + + /*low power */ + rtlpriv->psc.low_power_enable = false; + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x40000); + if (!rtlpriv->rtlhal.pfirmware) { + /*pr_err("Can't alloc buffer for fw\n");*/ + return 1; + } + + /* request fw */ + fw_name = "rtlwifi/rtl8822befw.bin"; + + rtlpriv->max_fw_size = 0x40000; + pr_info("Using firmware %s\n", fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + if (err) { + pr_err("Failed to request firmware!\n"); + return 1; + } + + /* init table of tx power by rate & limit */ + rtl8822be_load_txpower_by_rate(hw); + rtl8822be_load_txpower_limit(hw); + + return 0; +} + +void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->halmac.ops->halmac_deinit_adapter(rtlpriv); + rtlpriv->phydm.ops->phydm_deinit_priv(rtlpriv); + + if (rtlpriv->rtlhal.pfirmware) { + vfree(rtlpriv->rtlhal.pfirmware); + rtlpriv->rtlhal.pfirmware = NULL; + } +} + +/* get bt coexist status */ +bool rtl8822be_get_btc_status(void) +{ + return true; +} + +static void rtl8822be_phydm_watchdog(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 tmp; + + tmp = rtl_read_dword(rtlpriv, 0xc00); + if (tmp & 0xFF000000) { /* Recover 0xC00: 0xF800000C --> 0x0000000C */ + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "found regaddr_c00=%08X\n", tmp); + tmp &= ~0xFF000000; + rtl_write_dword(rtlpriv, 0xc00, tmp); + RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, + "apply regaddr_c00=%08X\n", tmp); + } + + rtlpriv->phydm.ops->phydm_watchdog(rtlpriv); +} + +static struct rtl_hal_ops rtl8822be_hal_ops = { + .init_sw_vars = rtl8822be_init_sw_vars, + .deinit_sw_vars = rtl8822be_deinit_sw_vars, + .read_eeprom_info = rtl8822be_read_eeprom_info_dummy, + .interrupt_recognized = rtl8822be_interrupt_recognized, + .hw_init = rtl8822be_hw_init, + .hw_disable = rtl8822be_card_disable, + .hw_suspend = rtl8822be_suspend, + .hw_resume = rtl8822be_resume, + .enable_interrupt = rtl8822be_enable_interrupt, + .disable_interrupt = rtl8822be_disable_interrupt, + .set_network_type = rtl8822be_set_network_type, + .set_chk_bssid = rtl8822be_set_check_bssid, + .set_qos = rtl8822be_set_qos, + .set_bcn_reg = rtl8822be_set_beacon_related_registers, + .set_bcn_intv = rtl8822be_set_beacon_interval, + .update_interrupt_mask = rtl8822be_update_interrupt_mask, + .get_hw_reg = rtl8822be_get_hw_reg, + .set_hw_reg = rtl8822be_set_hw_reg, + .update_rate_tbl = rtl8822be_update_hal_rate_tbl, + .pre_fill_tx_bd_desc = rtl8822be_pre_fill_tx_bd_desc, + .rx_desc_buff_remained_cnt = rtl8822be_rx_desc_buff_remained_cnt, + .rx_check_dma_ok = rtl8822be_rx_check_dma_ok, + .fill_tx_desc = rtl8822be_tx_fill_desc, + .fill_tx_special_desc = rtl8822be_tx_fill_special_desc, + .query_rx_desc = rtl8822be_rx_query_desc, + .radio_onoff_checking = rtl8822be_gpio_radio_on_off_checking, + .switch_channel = rtl8822be_phy_sw_chnl, + .set_channel_access = rtl8822be_update_channel_access_setting, + .set_bw_mode = rtl8822be_phy_set_bw_mode, + .dm_watchdog = rtl8822be_phydm_watchdog, + .scan_operation_backup = rtl8822be_phy_scan_operation_backup, + .set_rf_power_state = rtl8822be_phy_set_rf_power_state, + .led_control = rtl8822be_led_control, + .set_desc = rtl8822be_set_desc, + .get_desc = rtl8822be_get_desc, + .is_tx_desc_closed = rtl8822be_is_tx_desc_closed, + .get_available_desc = rtl8822be_get_available_desc, + .tx_polling = rtl8822be_tx_polling, + .enable_hw_sec = rtl8822be_enable_hw_security_config, + .set_key = rtl8822be_set_key, + .init_sw_leds = rtl8822be_init_sw_leds, + .get_bbreg = rtl8822be_phy_query_bb_reg, + .set_bbreg = rtl8822be_phy_set_bb_reg, + .get_rfreg = rtl8822be_phy_query_rf_reg, + .set_rfreg = rtl8822be_phy_set_rf_reg, + .fill_h2c_cmd = rtl8822be_fill_h2c_cmd, + .set_default_port_id_cmd = rtl8822be_set_default_port_id_cmd, + .get_btc_status = rtl8822be_get_btc_status, + .rx_command_packet = rtl8822be_rx_command_packet, + .c2h_content_parsing = rtl8822be_c2h_content_parsing, + /* ops for halmac cb */ + .halmac_cb_init_mac_register = rtl8822be_halmac_cb_init_mac_register, + .halmac_cb_init_bb_rf_register = + rtl8822be_halmac_cb_init_bb_rf_register, + .halmac_cb_write_data_rsvd_page = + rtl8822b_halmac_cb_write_data_rsvd_page, + .halmac_cb_write_data_h2c = rtl8822b_halmac_cb_write_data_h2c, + /* ops for phydm cb */ + .get_txpower_index = rtl8822be_get_txpower_index, + .set_tx_power_index_by_rs = rtl8822be_phy_set_tx_power_index_by_rs, + .store_tx_power_by_rate = rtl8822be_store_tx_power_by_rate, + .phy_set_txpower_limit = rtl8822be_phy_set_txpower_limit, +}; + +static struct rtl_mod_params rtl8822be_mod_params = { + .sw_crypto = false, + .inactiveps = true, + .swctrl_lps = false, + .fwctrl_lps = true, + .msi_support = true, + .dma64 = false, + .aspm_support = 1, + .disable_watchdog = false, + .debug_level = 0, + .debug_mask = 0, +}; + +static struct rtl_hal_cfg rtl8822be_hal_cfg = { + .bar_id = 2, + .write_readback = false, + .name = "rtl8822be_pci", + .ops = &rtl8822be_hal_ops, + .mod_params = &rtl8822be_mod_params, + .spec_ver = RTL_SPEC_NEW_RATEID | RTL_SPEC_SUPPORT_VHT | + RTL_SPEC_NEW_FW_C2H, + .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL_8822B, + .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN_8822B, + .maps[SYS_CLK] = REG_SYS_CLK_CTRL_8822B, + .maps[MAC_RCR_AM] = AM, + .maps[MAC_RCR_AB] = AB, + .maps[MAC_RCR_ACRC32] = ACRC32, + .maps[MAC_RCR_ACF] = ACF, + .maps[MAC_RCR_AAP] = AAP, + .maps[MAC_HIMR] = REG_HIMR0_8822B, + .maps[MAC_HIMRE] = REG_HIMR1_8822B, + + .maps[EFUSE_ACCESS] = REG_EFUSE_ACCESS_8822B, + + .maps[EFUSE_TEST] = REG_LDO_EFUSE_CTRL_8822B, + .maps[EFUSE_CTRL] = REG_EFUSE_CTRL_8822B, + .maps[EFUSE_CLK] = 0, + .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL_8822B, + .maps[EFUSE_PWC_EV12V] = PWC_EV12V, + .maps[EFUSE_FEN_ELDR] = FEN_ELDR, + .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, + .maps[EFUSE_ANA8M] = ANA8M, + .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, + .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, + .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, + .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, + + .maps[RWCAM] = REG_CAMCMD_8822B, + .maps[WCAMI] = REG_CAMWRITE_8822B, + .maps[RCAMO] = REG_CAMREAD_8822B, + .maps[CAMDBG] = REG_CAMDBG_8822B, + .maps[SECR] = REG_SECCFG_8822B, + .maps[SEC_CAM_NONE] = CAM_NONE, + .maps[SEC_CAM_WEP40] = CAM_WEP40, + .maps[SEC_CAM_TKIP] = CAM_TKIP, + .maps[SEC_CAM_AES] = CAM_AES, + .maps[SEC_CAM_WEP104] = CAM_WEP104, + + .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, + .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, + .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, + .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, + .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, + .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, + /* .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, */ /*need check*/ + .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, + .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, + .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, + .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, + .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, + .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, + .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, + /* .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,*/ + /* .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,*/ + + .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, + .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, + .maps[RTL_IMR_BCNINT] = IMR_BCNDMAINT0, + .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, + .maps[RTL_IMR_RDU] = IMR_RDU, + .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, + .maps[RTL_IMR_H2CDOK] = IMR_H2CDOK, + .maps[RTL_IMR_BDOK] = IMR_BCNDOK0, + .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, + .maps[RTL_IMR_TBDER] = IMR_TBDER, + .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, + .maps[RTL_IMR_TBDOK] = IMR_TBDOK, + .maps[RTL_IMR_BKDOK] = IMR_BKDOK, + .maps[RTL_IMR_BEDOK] = IMR_BEDOK, + .maps[RTL_IMR_VIDOK] = IMR_VIDOK, + .maps[RTL_IMR_VODOK] = IMR_VODOK, + .maps[RTL_IMR_ROK] = IMR_ROK, + .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNDMAINT0 | IMR_TBDOK | IMR_TBDER), + + .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M, + .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M, + .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M, + .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M, + .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M, + .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M, + .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M, + .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M, + .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M, + .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M, + .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M, + .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M, + + .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7, + .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15, + + /*VHT hightest rate*/ + .maps[RTL_RC_VHT_RATE_1SS_MCS7] = DESC_RATEVHT1SS_MCS7, + .maps[RTL_RC_VHT_RATE_1SS_MCS8] = DESC_RATEVHT1SS_MCS8, + .maps[RTL_RC_VHT_RATE_1SS_MCS9] = DESC_RATEVHT1SS_MCS9, + .maps[RTL_RC_VHT_RATE_2SS_MCS7] = DESC_RATEVHT2SS_MCS7, + .maps[RTL_RC_VHT_RATE_2SS_MCS8] = DESC_RATEVHT2SS_MCS8, + .maps[RTL_RC_VHT_RATE_2SS_MCS9] = DESC_RATEVHT2SS_MCS9, +}; + +static const struct pci_device_id rtl8822be_pci_ids[] = { + {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB822, rtl8822be_hal_cfg)}, + {}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8822be_pci_ids); + +MODULE_AUTHOR("Realtek WlanFAE "); +MODULE_AUTHOR("Larry Finger "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Realtek 8822BE 802.11n PCI wireless"); +MODULE_FIRMWARE("rtlwifi/rtl8822befw.bin"); + +module_param_named(swenc, rtl8822be_mod_params.sw_crypto, bool, 0444); +module_param_named(debug_level, rtl8822be_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8822be_mod_params.debug_mask, ullong, 0644); +module_param_named(ips, rtl8822be_mod_params.inactiveps, bool, 0444); +module_param_named(swlps, rtl8822be_mod_params.swctrl_lps, bool, 0444); +module_param_named(fwlps, rtl8822be_mod_params.fwctrl_lps, bool, 0444); +module_param_named(msi, rtl8822be_mod_params.msi_support, bool, 0444); +module_param_named(dma64, rtl8822be_mod_params.dma64, bool, 0444); +module_param_named(aspm, rtl8822be_mod_params.aspm_support, int, 0444); +module_param_named(disable_watchdog, rtl8822be_mod_params.disable_watchdog, + bool, 0444); +MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); +MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); +MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); +MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); +MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); +MODULE_PARM_DESC(dma64, "Set to 1 to use DMA 64 (default 0)\n"); +MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n"); +MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); +MODULE_PARM_DESC(disable_watchdog, + "Set to 1 to disable the watchdog (default 0)\n"); + +static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); + +static struct pci_driver rtl8822be_driver = { + .name = KBUILD_MODNAME, + .id_table = rtl8822be_pci_ids, + .probe = rtl_pci_probe, + .remove = rtl_pci_disconnect, + .driver.pm = &rtlwifi_pm_ops, +}; + +module_pci_driver(rtl8822be_driver); diff --git a/drivers/staging/rtlwifi/rtl8822be/sw.h b/drivers/staging/rtlwifi/rtl8822be/sw.h new file mode 100644 index 000000000000..931eba98bd80 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/sw.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_SW_H__ +#define __RTL8822B_SW_H__ + +int rtl8822be_init_sw_vars(struct ieee80211_hw *hw); +void rtl8822be_deinit_sw_vars(struct ieee80211_hw *hw); +bool rtl8822be_get_btc_status(void); +#endif diff --git a/drivers/staging/rtlwifi/rtl8822be/trx.c b/drivers/staging/rtlwifi/rtl8822be/trx.c new file mode 100644 index 000000000000..38f80e48a399 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/trx.c @@ -0,0 +1,1015 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "../wifi.h" +#include "../pci.h" +#include "../base.h" +#include "../stats.h" +#include "reg.h" +#include "def.h" +#include "phy.h" +#include "trx.h" +#include "led.h" +#include "fw.h" + +#include + +static u8 _rtl8822be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) +{ + switch (hw_queue) { + case BEACON_QUEUE: + return QSLT_BEACON; + case H2C_QUEUE: + return QSLT_CMD; + case MGNT_QUEUE: + return QSLT_MGNT; + case HIGH_QUEUE: + return QSLT_HIGH; + default: + return skb->priority; + } +} + +static void _rtl8822be_query_rxphystatus(struct ieee80211_hw *hw, u8 *phystrpt, + struct ieee80211_hdr *hdr, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtlpriv->phydm.ops->phydm_query_phy_status(rtlpriv, phystrpt, hdr, + pstatus); + + /* UI BSS List signal strength(in percentage), + * make it good looking, from 0~100. + */ + pstatus->signalstrength = + (u8)(rtl_signal_scale_mapping(hw, pstatus->rx_pwdb_all)); +} + +static void _rtl8822be_translate_rx_signal_stuff(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct rtl_stats *pstatus, + u8 *p_phystrpt) +{ + struct ieee80211_hdr *hdr; + u8 *tmp_buf; + + tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift + + 24; + + hdr = (struct ieee80211_hdr *)tmp_buf; + + /* query phy status */ + _rtl8822be_query_rxphystatus(hw, p_phystrpt, hdr, pstatus); + + /* packet statistics */ + if (pstatus->packet_beacon && pstatus->packet_matchbssid) + rtl_priv(hw)->dm.dbginfo.num_qry_beacon_pkt++; + + if (pstatus->packet_matchbssid && + ieee80211_is_data_qos(hdr->frame_control) && + !is_multicast_ether_addr(ieee80211_get_DA(hdr))) { + struct ieee80211_qos_hdr *hdr_qos = + (struct ieee80211_qos_hdr *)tmp_buf; + u16 tid = le16_to_cpu(hdr_qos->qos_ctrl) & 0xf; + + if (tid != 0 && tid != 3) + rtl_priv(hw)->dm.dbginfo.num_non_be_pkt++; + } + + /* signal statistics */ + if (p_phystrpt) + rtl_process_phyinfo(hw, tmp_buf, pstatus); +} + +static void _rtl8822be_insert_emcontent(struct rtl_tcb_desc *ptcb_desc, + u8 *virtualaddress) +{ + u32 dwtmp = 0; + + memset(virtualaddress, 0, 8); + + SET_EARLYMODE_PKTNUM(virtualaddress, ptcb_desc->empkt_num); + if (ptcb_desc->empkt_num == 1) { + dwtmp = ptcb_desc->empkt_len[0]; + } else { + dwtmp = ptcb_desc->empkt_len[0]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[1]; + } + SET_EARLYMODE_LEN0(virtualaddress, dwtmp); + + if (ptcb_desc->empkt_num <= 3) { + dwtmp = ptcb_desc->empkt_len[2]; + } else { + dwtmp = ptcb_desc->empkt_len[2]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[3]; + } + SET_EARLYMODE_LEN1(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 5) { + dwtmp = ptcb_desc->empkt_len[4]; + } else { + dwtmp = ptcb_desc->empkt_len[4]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[5]; + } + SET_EARLYMODE_LEN2_1(virtualaddress, dwtmp & 0xF); + SET_EARLYMODE_LEN2_2(virtualaddress, dwtmp >> 4); + if (ptcb_desc->empkt_num <= 7) { + dwtmp = ptcb_desc->empkt_len[6]; + } else { + dwtmp = ptcb_desc->empkt_len[6]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[7]; + } + SET_EARLYMODE_LEN3(virtualaddress, dwtmp); + if (ptcb_desc->empkt_num <= 9) { + dwtmp = ptcb_desc->empkt_len[8]; + } else { + dwtmp = ptcb_desc->empkt_len[8]; + dwtmp += ((dwtmp % 4) ? (4 - dwtmp % 4) : 0) + 4; + dwtmp += ptcb_desc->empkt_len[9]; + } + SET_EARLYMODE_LEN4(virtualaddress, dwtmp); +} + +static bool rtl8822be_get_rxdesc_is_ht(struct ieee80211_hw *hw, u8 *pdesc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rx_rate = 0; + + rx_rate = GET_RX_DESC_RX_RATE(pdesc); + + RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate); + + if ((rx_rate >= DESC_RATEMCS0) && (rx_rate <= DESC_RATEMCS15)) + return true; + else + return false; +} + +static bool rtl8822be_get_rxdesc_is_vht(struct ieee80211_hw *hw, u8 *pdesc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 rx_rate = 0; + + rx_rate = GET_RX_DESC_RX_RATE(pdesc); + + RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, "rx_rate=0x%02x.\n", rx_rate); + + if (rx_rate >= DESC_RATEVHT1SS_MCS0) + return true; + else + return false; +} + +static u8 rtl8822be_get_rx_vht_nss(struct ieee80211_hw *hw, u8 *pdesc) +{ + u8 rx_rate = 0; + u8 vht_nss = 0; + + rx_rate = GET_RX_DESC_RX_RATE(pdesc); + + if ((rx_rate >= DESC_RATEVHT1SS_MCS0) && + (rx_rate <= DESC_RATEVHT1SS_MCS9)) + vht_nss = 1; + else if ((rx_rate >= DESC_RATEVHT2SS_MCS0) && + (rx_rate <= DESC_RATEVHT2SS_MCS9)) + vht_nss = 2; + + return vht_nss; +} + +bool rtl8822be_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, u8 *pdesc, + struct sk_buff *skb) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *p_phystrpt = NULL; + struct ieee80211_hdr *hdr; + + u32 phystatus = GET_RX_DESC_PHYST(pdesc); + + if (GET_RX_DESC_C2H(pdesc) == 0) + status->packet_report_type = NORMAL_RX; + else + status->packet_report_type = C2H_PACKET; + + status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc); + status->rx_drvinfo_size = + (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) * RX_DRV_INFO_SIZE_UNIT; + status->rx_bufshift = (u8)(GET_RX_DESC_SHIFT(pdesc) & 0x03); + status->icv = (u16)GET_RX_DESC_ICV_ERR(pdesc); + status->crc = (u16)GET_RX_DESC_CRC32(pdesc); + status->hwerror = (status->crc | status->icv); + status->decrypted = !GET_RX_DESC_SWDEC(pdesc); + status->rate = (u8)GET_RX_DESC_RX_RATE(pdesc); + status->isampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1); + status->isfirst_ampdu = (bool)(GET_RX_DESC_PAGGR(pdesc) == 1); + status->timestamp_low = GET_RX_DESC_TSFL(pdesc); + status->is_ht = rtl8822be_get_rxdesc_is_ht(hw, pdesc); + status->is_vht = rtl8822be_get_rxdesc_is_vht(hw, pdesc); + status->vht_nss = rtl8822be_get_rx_vht_nss(hw, pdesc); + status->is_cck = RX_HAL_IS_CCK_RATE(status->rate); + + status->macid = GET_RX_DESC_MACID(pdesc); + if (GET_RX_DESC_PATTERN_MATCH(pdesc)) + status->wake_match = BIT(2); + else if (GET_RX_DESC_MAGIC_WAKE(pdesc)) + status->wake_match = BIT(1); + else if (GET_RX_DESC_UNICAST_WAKE(pdesc)) + status->wake_match = BIT(0); + else + status->wake_match = 0; + if (status->wake_match) + RT_TRACE(rtlpriv, COMP_RXDESC, DBG_LOUD, + "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch=%d\n", + status->wake_match); + rx_status->freq = hw->conf.chandef.chan->center_freq; + rx_status->band = hw->conf.chandef.chan->band; + + if (phystatus) + p_phystrpt = (skb->data + status->rx_bufshift + 24); + + hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size + + status->rx_bufshift + 24); + + if (status->crc) + rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; + + if (status->is_ht) + rx_status->encoding = RX_ENC_HT; + if (status->is_vht) + rx_status->encoding = RX_ENC_VHT; + + rx_status->nss = status->vht_nss; + + rx_status->flag |= RX_FLAG_MACTIME_START; + + /* hw will set status->decrypted true, if it finds the + * frame is open data frame or mgmt frame. + */ + /* So hw will not decryption robust management frame + * for IEEE80211w but still set status->decrypted + * true, so here we should set it back to undecrypted + * for IEEE80211w frame, and mac80211 sw will help + * to decrypt it + */ + if (status->decrypted) { + if ((!_ieee80211_is_robust_mgmt_frame(hdr)) && + (ieee80211_has_protected(hdr->frame_control))) + rx_status->flag |= RX_FLAG_DECRYPTED; + else + rx_status->flag &= ~RX_FLAG_DECRYPTED; + } + + /* rate_idx: index of data rate into band's + * supported rates or MCS index if HT rates + * are use (RX_FLAG_HT) + */ + /* Notice: this is diff with windows define */ + rx_status->rate_idx = rtlwifi_rate_mapping( + hw, status->is_ht, status->is_vht, status->rate); + + rx_status->mactime = status->timestamp_low; + + _rtl8822be_translate_rx_signal_stuff(hw, skb, status, p_phystrpt); + + /* below info. are filled by _rtl8822be_translate_rx_signal_stuff() */ + if (!p_phystrpt) + goto label_no_physt; + + rx_status->signal = status->recvsignalpower; + + if (status->rx_packet_bw == HT_CHANNEL_WIDTH_20_40) + rx_status->bw = RATE_INFO_BW_40; + else if (status->rx_packet_bw == HT_CHANNEL_WIDTH_80) + rx_status->bw = RATE_INFO_BW_80; + +label_no_physt: + + return true; +} + +void rtl8822be_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 first_seg; + u8 last_seg; + u16 total_len; + u16 read_cnt = 0; + + if (!header_desc) + return; + + do { + total_len = (u16)GET_RX_BUFFER_DESC_TOTAL_LENGTH(header_desc); + first_seg = (u8)GET_RX_BUFFER_DESC_FS(header_desc); + last_seg = (u8)GET_RX_BUFFER_DESC_LS(header_desc); + + if (read_cnt++ > 20) { + RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, + "RX chk DMA over %d times\n", read_cnt); + break; + } + + } while (total_len == 0 && first_seg == 0 && last_seg == 0); +} + +u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, u8 queue_index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + u16 desc_idx_hw = 0, desc_idx_host = 0, remind_cnt = 0; + u32 tmp_4byte = 0; + + u32 rw_mask = 0x1ff; + + tmp_4byte = rtl_read_dword(rtlpriv, REG_RXQ_RXBD_IDX_8822B); + desc_idx_hw = (u16)((tmp_4byte >> 16) & rw_mask); + desc_idx_host = (u16)(tmp_4byte & rw_mask); + + /* may be no data, donot rx */ + if (desc_idx_hw == desc_idx_host) + return 0; + + remind_cnt = + (desc_idx_hw > desc_idx_host) ? + (desc_idx_hw - desc_idx_host) : + (RX_DESC_NUM_8822BE - (desc_idx_host - desc_idx_hw)); + + rtlpci->rx_ring[queue_index].next_rx_rp = desc_idx_host; + + return remind_cnt; +} + +static u16 get_desc_address_from_queue_index(u16 queue_index) +{ + /* + * Note: Access these registers will take a lot of cost. + */ + u16 desc_address = REG_BEQ_TXBD_IDX_8822B; + + switch (queue_index) { + case BK_QUEUE: + desc_address = REG_BKQ_TXBD_IDX_8822B; + break; + case BE_QUEUE: + desc_address = REG_BEQ_TXBD_IDX_8822B; + break; + case VI_QUEUE: + desc_address = REG_VIQ_TXBD_IDX_8822B; + break; + case VO_QUEUE: + desc_address = REG_VOQ_TXBD_IDX_8822B; + break; + case BEACON_QUEUE: + desc_address = REG_BEQ_TXBD_IDX_8822B; + break; + case H2C_QUEUE: + desc_address = REG_H2CQ_TXBD_IDX_8822B; + break; + case MGNT_QUEUE: + desc_address = REG_MGQ_TXBD_IDX_8822B; + break; + case HIGH_QUEUE: + desc_address = REG_HI0Q_TXBD_IDX_8822B; + break; + case HCCA_QUEUE: + desc_address = REG_BEQ_TXBD_IDX_8822B; + break; + default: + break; + } + return desc_address; +} + +/*free desc that can be used */ +u16 rtl8822be_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[q_idx]; + + return calc_fifo_space(ring->cur_tx_rp, ring->cur_tx_wp, + TX_DESC_NUM_8822B); +} + +void rtl8822be_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc, + u8 *desc, u8 queue_index, + struct sk_buff *skb, dma_addr_t data_addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u32 pkt_len = skb->len; + u16 desc_size = 48; /*tx desc size*/ + u32 psblen = 0; + u32 total_packet_size = 0; + u16 current_bd_desc; + u8 i = 0; + /*u16 real_desc_size = 0x28;*/ + u16 append_early_mode_size = 0; + u8 segmentnum = 1 << (RTL8822BE_SEG_NUM + 1); + dma_addr_t desc_dma_addr; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + + current_bd_desc = rtlpci->tx_ring[queue_index].cur_tx_wp; + + total_packet_size = desc_size + pkt_len; + + if (rtlpriv->rtlhal.earlymode_enable) { + if (queue_index < BEACON_QUEUE) { + append_early_mode_size = 8; + total_packet_size += append_early_mode_size; + } + } + + /* page number (round up) */ + psblen = (total_packet_size - 1) / 128 + 1; + + /* tx desc addr */ + desc_dma_addr = rtlpci->tx_ring[queue_index].dma + + (current_bd_desc * TX_DESC_SIZE); + + /* Reset */ + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, 0); + SET_TX_BUFF_DESC_PSB(tx_bd_desc, 0); + SET_TX_BUFF_DESC_OWN(tx_bd_desc, 0); + + for (i = 1; i < segmentnum; i++) { + SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, i, 0); + SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, i, 0); + SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, i, 0); + SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, i, 0, dma64); + } + + /* Clear all status */ + CLEAR_PCI_TX_DESC_CONTENT(desc, TX_DESC_SIZE); + + if (rtlpriv->rtlhal.earlymode_enable) { + if (queue_index < BEACON_QUEUE) + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size + 8); + else + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size); + } else { + SET_TX_BUFF_DESC_LEN_0(tx_bd_desc, desc_size); + } + SET_TX_BUFF_DESC_PSB(tx_bd_desc, psblen); + SET_TX_BUFF_DESC_ADDR_LOW_0(tx_bd_desc, desc_dma_addr); + SET_TX_BUFF_DESC_ADDR_HIGH_0(tx_bd_desc, ((u64)desc_dma_addr >> 32), + dma64); + + SET_TXBUFFER_DESC_LEN_WITH_OFFSET(tx_bd_desc, 1, pkt_len); + SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(tx_bd_desc, 1, 0); + SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(tx_bd_desc, 1, data_addr); + SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(tx_bd_desc, 1, + ((u64)data_addr >> 32), dma64); + + SET_TX_DESC_TXPKTSIZE(desc, (u16)(pkt_len)); +} + +static u8 rtl8822be_bw_mapping(struct ieee80211_hw *hw, + struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 bw_setting_of_desc = 0; + + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + "%s, current_chan_bw %d, packet_bw %d\n", __func__, + rtlphy->current_chan_bw, ptcb_desc->packet_bw); + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) + bw_setting_of_desc = 2; + else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) + bw_setting_of_desc = 1; + else + bw_setting_of_desc = 0; + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + if ((ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) || + (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80)) + bw_setting_of_desc = 1; + else + bw_setting_of_desc = 0; + } else { + bw_setting_of_desc = 0; + } + + return bw_setting_of_desc; +} + +static u8 rtl8822be_sc_mapping(struct ieee80211_hw *hw, + struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_mac *mac = rtl_mac(rtlpriv); + u8 sc_setting_of_desc = 0; + + if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_80) { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) + sc_setting_of_desc = + VHT_DATA_SC_40_LOWER_OF_80MHZ; + else if (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) + sc_setting_of_desc = + VHT_DATA_SC_40_UPPER_OF_80MHZ; + else + RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD, + "%s: Not Correct Primary40MHz Setting\n", + __func__); + } else { + if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_setting_of_desc = + VHT_DATA_SC_20_LOWEST_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER)) + sc_setting_of_desc = + VHT_DATA_SC_20_LOWER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_setting_of_desc = + VHT_DATA_SC_20_UPPER_OF_80MHZ; + else if ((mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) && + (mac->cur_80_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER)) + sc_setting_of_desc = + VHT_DATA_SC_20_UPPERST_OF_80MHZ; + else + RT_TRACE( + rtlpriv, COMP_SEND, DBG_LOUD, + "rtl8822be_sc_mapping: Not Correct Primary40MHz Setting\n"); + } + } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { + if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20_40) { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } else if (ptcb_desc->packet_bw == HT_CHANNEL_WIDTH_20) { + if (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_UPPER) { + sc_setting_of_desc = + VHT_DATA_SC_20_UPPER_OF_80MHZ; + } else if (mac->cur_40_prime_sc == + HAL_PRIME_CHNL_OFFSET_LOWER) { + sc_setting_of_desc = + VHT_DATA_SC_20_LOWER_OF_80MHZ; + } else { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } + } + } else { + sc_setting_of_desc = VHT_DATA_SC_DONOT_CARE; + } + + return sc_setting_of_desc; +} + +void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + u8 *pdesc_tx, u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_hal *rtlhal = rtl_hal(rtlpriv); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 *pdesc = (u8 *)pdesc_tx; + u16 seq_number; + __le16 fc = hdr->frame_control; + u8 fw_qsel = _rtl8822be_map_hwqueue_to_fwqueue(skb, hw_queue); + bool firstseg = + ((hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); + bool lastseg = ((hdr->frame_control & + cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); + dma_addr_t mapping; + u8 short_gi = 0; + + seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc); + /* reserve 8 byte for AMPDU early mode */ + if (rtlhal->earlymode_enable) { + skb_push(skb, EM_HDR_LEN); + memset(skb->data, 0, EM_HDR_LEN); + } + mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error"); + return; + } + + if (pbd_desc_tx) + rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc_tx, pdesc, hw_queue, + skb, mapping); + + if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { + firstseg = true; + lastseg = true; + } + if (firstseg) { + if (rtlhal->earlymode_enable) { + SET_TX_DESC_PKT_OFFSET(pdesc, 1); + SET_TX_DESC_OFFSET(pdesc, + USB_HWDESC_HEADER_LEN + EM_HDR_LEN); + if (ptcb_desc->empkt_num) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); + _rtl8822be_insert_emcontent(ptcb_desc, + (u8 *)(skb->data)); + } + } else { + SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); + } + + /* tx report */ + rtl_get_tx_report(ptcb_desc, pdesc, hw); + + if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G && + ptcb_desc->hw_rate < DESC_RATE6M) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_WARNING, + "hw_rate=0x%X is invalid in 5G\n", + ptcb_desc->hw_rate); + ptcb_desc->hw_rate = DESC_RATE6M; + } + SET_TX_DESC_DATARATE(pdesc, ptcb_desc->hw_rate); + + if (ptcb_desc->hw_rate > DESC_RATEMCS0) + short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; + else + short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + SET_TX_DESC_AGG_EN(pdesc, 1); + SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x1F); + } + SET_TX_DESC_SW_SEQ(pdesc, seq_number); + SET_TX_DESC_RTSEN(pdesc, ((ptcb_desc->rts_enable && + !ptcb_desc->cts_enable) ? + 1 : + 0)); + SET_TX_DESC_HW_RTS_EN(pdesc, 0); + SET_TX_DESC_CTS2SELF(pdesc, ((ptcb_desc->cts_enable) ? 1 : 0)); + + SET_TX_DESC_RTSRATE(pdesc, ptcb_desc->rts_rate); + SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); + SET_TX_DESC_RTS_SHORT( + pdesc, + ((ptcb_desc->rts_rate <= DESC_RATE54M) ? + (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : + (ptcb_desc->rts_use_shortgi ? 1 : 0))); + + if (ptcb_desc->tx_enable_sw_calc_duration) + SET_TX_DESC_NAVUSEHDR(pdesc, 1); + + SET_TX_DESC_DATA_BW(pdesc, rtl8822be_bw_mapping(hw, ptcb_desc)); + SET_TX_DESC_DATA_SC(pdesc, rtl8822be_sc_mapping(hw, ptcb_desc)); + + if (sta) { + u8 ampdu_density = sta->ht_cap.ampdu_density; + + SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); + } + if (info->control.hw_key) { + struct ieee80211_key_conf *key = info->control.hw_key; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x1); + break; + case WLAN_CIPHER_SUITE_CCMP: + SET_TX_DESC_SEC_TYPE(pdesc, 0x3); + break; + default: + SET_TX_DESC_SEC_TYPE(pdesc, 0x0); + break; + } + } + + SET_TX_DESC_QSEL(pdesc, fw_qsel); + + if (rtlphy->current_channel > 14) { + /* OFDM 6M */ + SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 4); + SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 4); + } else { + /* CCK 1M */ + SET_TX_DESC_DATA_RTY_LOWEST_RATE(pdesc, 0); + SET_TX_DESC_RTS_RTY_LOWEST_RATE(pdesc, 0); + } + SET_TX_DESC_DISDATAFB(pdesc, + ptcb_desc->disable_ratefallback ? 1 : 0); + SET_TX_DESC_USE_RATE(pdesc, ptcb_desc->use_driver_rate ? 1 : 0); + + /*SET_TX_DESC_PWR_STATUS(pdesc, pwr_status);*/ + /* Set TxRate and RTSRate in TxDesc */ + /* This prevent Tx initial rate of new-coming packets */ + /* from being overwritten by retried packet rate.*/ + if (!ptcb_desc->use_driver_rate) { + /*SET_TX_DESC_RTS_RATE(pdesc, 0x08); */ + /* SET_TX_DESC_TX_RATE(pdesc, 0x0b); */ + } + if (ieee80211_is_data_qos(fc)) { + if (mac->rdg_en) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, + "Enable RDG function.\n"); + SET_TX_DESC_RDG_EN(pdesc, 1); + SET_TX_DESC_HTC(pdesc, 1); + } + } + + SET_TX_DESC_PORT_ID(pdesc, 0); + SET_TX_DESC_MULTIPLE_PORT(pdesc, 0); + } + + SET_TX_DESC_LS(pdesc, (lastseg ? 1 : 0)); + if (rtlpriv->dm.useramask) { + SET_TX_DESC_RATE_ID(pdesc, ptcb_desc->ratr_index); + SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id); + } else { + SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcb_desc->ratr_index); + SET_TX_DESC_MACID(pdesc, ptcb_desc->ratr_index); + } + + SET_TX_DESC_MOREFRAG(pdesc, (lastseg ? 0 : 1)); + if (ptcb_desc->multicast || ptcb_desc->broadcast) { + SET_TX_DESC_BMC(pdesc, 1); + /* BMC must be not AGG */ + SET_TX_DESC_AGG_EN(pdesc, 0); + } + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); + + /* debug purpose: used to check tx desc is correct or not */ + /*rtlpriv->halmac.ops->halmac_chk_txdesc(rtlpriv, pdesc, + * skb->len + USB_HWDESC_HEADER_LEN); + */ +} + +void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc, + u8 *pbd_desc, struct sk_buff *skb, + u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + u8 fw_queue; + u8 txdesc_len = 48; + + dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + + if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "DMA mapping error"); + return; + } + + rtl8822be_pre_fill_tx_bd_desc(hw, pbd_desc, pdesc, hw_queue, skb, + mapping); + + /* it should be BEACON_QUEUE or H2C_QUEUE, + * so skb=NULL is safe to assert + */ + fw_queue = _rtl8822be_map_hwqueue_to_fwqueue(NULL, hw_queue); + + CLEAR_PCI_TX_DESC_CONTENT(pdesc, txdesc_len); + + /* common part for BEACON and H2C */ + SET_TX_DESC_TXPKTSIZE((u8 *)pdesc, (u16)(skb->len)); + + SET_TX_DESC_QSEL(pdesc, fw_queue); + + if (hw_queue == H2C_QUEUE) { + /* fill H2C */ + SET_TX_DESC_OFFSET(pdesc, 0); + + } else { + /* fill beacon */ + SET_TX_DESC_OFFSET(pdesc, txdesc_len); + + SET_TX_DESC_DATARATE(pdesc, DESC_RATE1M); + + SET_TX_DESC_SW_SEQ(pdesc, 0); + + SET_TX_DESC_RATE_ID(pdesc, 7); + SET_TX_DESC_MACID(pdesc, 0); + + SET_TX_DESC_LS(pdesc, 1); + + SET_TX_DESC_OFFSET(pdesc, 48); + + SET_TX_DESC_USE_RATE(pdesc, 1); + } + + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", + pdesc, txdesc_len); +} + +void rtl8822be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 q_idx = *val; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + + if (istx) { + switch (desc_name) { + case HW_DESC_OWN: { + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[q_idx]; + u16 max_tx_desc = ring->entries; + + if (q_idx == BEACON_QUEUE) { + /* in case of beacon, pdesc is BD desc. */ + u8 *pbd_desc = pdesc; + + ring->cur_tx_wp = 0; + ring->cur_tx_rp = 0; + SET_TX_BUFF_DESC_OWN(pbd_desc, 1); + return; + } + + /* make sure tx desc is available by caller */ + ring->cur_tx_wp = ((ring->cur_tx_wp + 1) % max_tx_desc); + + rtl_write_word( + rtlpriv, + get_desc_address_from_queue_index( + q_idx), + ring->cur_tx_wp); + } break; + } + } else { + switch (desc_name) { + case HW_DESC_RX_PREPARE: + SET_RX_BUFFER_DESC_LS(pdesc, 0); + SET_RX_BUFFER_DESC_FS(pdesc, 0); + SET_RX_BUFFER_DESC_TOTAL_LENGTH(pdesc, 0); + + SET_RX_BUFFER_DESC_DATA_LENGTH( + pdesc, MAX_RECEIVE_BUFFER_SIZE + RX_DESC_SIZE); + + SET_RX_BUFFER_PHYSICAL_LOW( + pdesc, (*(dma_addr_t *)val) & DMA_BIT_MASK(32)); + SET_RX_BUFFER_PHYSICAL_HIGH( + pdesc, ((u64)(*(dma_addr_t *)val) >> 32), + dma64); + break; + default: + WARN_ONCE(true, "ERR rxdesc :%d not process\n", + desc_name); + break; + } + } +} + +u64 rtl8822be_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u64 ret = 0; + u8 *pbd_desc = pdesc; + bool dma64 = rtlpriv->cfg->mod_params->dma64; + + if (istx) { + switch (desc_name) { + case HW_DESC_TXBUFF_ADDR: + ret = GET_TXBUFFER_DESC_ADDR_LOW(pbd_desc, 1); + ret |= (u64)GET_TXBUFFER_DESC_ADDR_HIGH(pbd_desc, 1, + dma64) << 32; + break; + default: + WARN_ONCE(true, "ERR txdesc :%d not process\n", + desc_name); + break; + } + } else { + switch (desc_name) { + case HW_DESC_RXPKT_LEN: + ret = GET_RX_DESC_PKT_LEN(pdesc); + break; + default: + WARN_ONCE(true, "ERR rxdesc :%d not process\n", + desc_name); + break; + } + } + return ret; +} + +bool rtl8822be_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, + u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv = rtl_priv(hw); + bool ret = false; + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u16 cur_tx_rp, cur_tx_wp; + u16 tmp16; + + /* + * design rule: + * idx <= cur_tx_rp <= hw_rp <= cur_tx_wp = hw_wp + */ + + if (index == ring->cur_tx_rp) { + /* update only if sw_rp reach hw_rp */ + tmp16 = rtl_read_word( + rtlpriv, + get_desc_address_from_queue_index(hw_queue) + 2); + + cur_tx_rp = tmp16 & 0x01ff; + cur_tx_wp = ring->cur_tx_wp; + + /* don't need to update ring->cur_tx_wp */ + ring->cur_tx_rp = cur_tx_rp; + } + + if (index == ring->cur_tx_rp) + ret = false; /* no more */ + else + ret = true; /* more */ + + if (hw_queue == BEACON_QUEUE) + ret = true; + + if (rtlpriv->rtlhal.driver_is_goingto_unload || + rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) + ret = true; + + return ret; +} + +void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + if (hw_queue == BEACON_QUEUE) { + /* kick start */ + rtl_write_byte( + rtlpriv, REG_RX_RXBD_NUM_8822B + 1, + rtl_read_byte(rtlpriv, REG_RX_RXBD_NUM_8822B + 1) | + BIT(4)); + } +} + +u32 rtl8822be_rx_command_packet(struct ieee80211_hw *hw, + const struct rtl_stats *status, + struct sk_buff *skb) +{ + u32 result = 0; + struct rtl_priv *rtlpriv = rtl_priv(hw); + + switch (status->packet_report_type) { + case NORMAL_RX: + result = 0; + break; + case C2H_PACKET: + rtl8822be_c2h_packet_handler(hw, skb->data, (u8)skb->len); + result = 1; + break; + default: + RT_TRACE(rtlpriv, COMP_RECV, DBG_TRACE, + "Unknown packet type %d\n", + status->packet_report_type); + break; + } + + return result; +} diff --git a/drivers/staging/rtlwifi/rtl8822be/trx.h b/drivers/staging/rtlwifi/rtl8822be/trx.h new file mode 100644 index 000000000000..db769f3c4cd6 --- /dev/null +++ b/drivers/staging/rtlwifi/rtl8822be/trx.h @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * Copyright(c) 2016 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL8822B_TRX_H__ +#define __RTL8822B_TRX_H__ + +#include "../halmac/halmac_tx_desc_nic.h" +#include "../halmac/halmac_rx_desc_nic.h" + +#define TX_DESC_SIZE 64 + +#define RX_DRV_INFO_SIZE_UNIT 8 + +#define TX_DESC_NEXT_DESC_OFFSET 48 +#define USB_HWDESC_HEADER_LEN 48 + +#define RX_DESC_SIZE 24 +#define MAX_RECEIVE_BUFFER_SIZE 8192 + +#define SET_EARLYMODE_PKTNUM(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 0, 4, __val) +#define SET_EARLYMODE_LEN0(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 4, 15, __val) +#define SET_EARLYMODE_LEN1(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 16, 2, __val) +#define SET_EARLYMODE_LEN1_1(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 19, 13, __val) +#define SET_EARLYMODE_LEN1_2(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 2, __val) +#define SET_EARLYMODE_LEN2(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 2, 15, __val) +#define SET_EARLYMODE_LEN2_1(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr, 2, 4, __val) +#define SET_EARLYMODE_LEN2_2(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 0, 8, __val) +#define SET_EARLYMODE_LEN3(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 17, 15, __val) +#define SET_EARLYMODE_LEN4(__paddr, __val) \ + SET_BITS_TO_LE_4BYTE(__paddr + 4, 20, 12, __val) + +/* TX/RX buffer descriptor */ + +/* for Txfilldescroptor8822be, fill the desc content. */ +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pdesc, __offset, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 0, 16, __val) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pdesc, __offset, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16), 31, 1, __val) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pdesc, __offset, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32, __val) +#define SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(pbd, off, val, dma64) \ + (dma64 ? SET_BITS_TO_LE_4BYTE((pbd) + ((off) * 16) + 8, 0, 32, val) : 0) +#define GET_TXBUFFER_DESC_ADDR_LOW(__pdesc, __offset) \ + LE_BITS_TO_4BYTE((__pdesc) + ((__offset) * 16) + 4, 0, 32) +#define GET_TXBUFFER_DESC_ADDR_HIGH(pbd, off, dma64) \ + (dma64 ? LE_BITS_TO_4BYTE((pbd) + ((off) * 16) + 8, 0, 32) : 0) + +/* Dword 0 */ +#define SET_TX_BUFF_DESC_LEN_0(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) +#define SET_TX_BUFF_DESC_PSB(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 16, 15, __val) +#define SET_TX_BUFF_DESC_OWN(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) + +/* Dword 1 */ +#define SET_TX_BUFF_DESC_ADDR_LOW_0(__pdesc, __val) \ + SET_BITS_TO_LE_4BYTE((__pdesc) + 4, 0, 32, __val) +/* Dword 2 */ +#define SET_TX_BUFF_DESC_ADDR_HIGH_0(bdesc, val, dma64) \ + SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(bdesc, 0, val, dma64) +/* Dword 3 / RESERVED 0 */ + +/* RX buffer */ + +/* DWORD 0 */ +#define SET_RX_BUFFER_DESC_DATA_LENGTH(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 0, 14, __val) +#define SET_RX_BUFFER_DESC_LS(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 15, 1, __val) +#define SET_RX_BUFFER_DESC_FS(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 1, __val) +#define SET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc, 16, 15, __val) + +#define GET_RX_BUFFER_DESC_OWN(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 31, 1) +#define GET_RX_BUFFER_DESC_LS(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 15, 1) +#define GET_RX_BUFFER_DESC_FS(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 16, 1) +#define GET_RX_BUFFER_DESC_TOTAL_LENGTH(__rx_status_desc) \ + LE_BITS_TO_4BYTE(__rx_status_desc, 16, 15) + +/* DWORD 1 */ +#define SET_RX_BUFFER_PHYSICAL_LOW(__rx_status_desc, __val) \ + SET_BITS_TO_LE_4BYTE(__rx_status_desc + 4, 0, 32, __val) + +/* DWORD 2 */ +#define SET_RX_BUFFER_PHYSICAL_HIGH(__rx_status_desc, __val, dma64) \ + (dma64 ? SET_BITS_TO_LE_4BYTE((__rx_status_desc) + 8, 0, 32, __val) : 0) + +#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ + do { \ + if (_size > TX_DESC_NEXT_DESC_OFFSET) \ + memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ + else \ + memset(__pdesc, 0, _size); \ + } while (0) + +void rtl8822be_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index); +u16 rtl8822be_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, + u8 queue_index); +u16 rtl8822be_get_available_desc(struct ieee80211_hw *hw, u8 queue_index); +void rtl8822be_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, u8 *tx_bd_desc, + u8 *desc, u8 queue_index, + struct sk_buff *skb, dma_addr_t addr); + +void rtl8822be_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, + u8 *pdesc_tx, u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, struct sk_buff *skb, + u8 hw_queue, struct rtl_tcb_desc *ptcb_desc); +void rtl8822be_tx_fill_special_desc(struct ieee80211_hw *hw, u8 *pdesc, + u8 *pbd_desc, struct sk_buff *skb, + u8 hw_queue); +bool rtl8822be_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *status, + struct ieee80211_rx_status *rx_status, u8 *pdesc, + struct sk_buff *skb); +void rtl8822be_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); +u64 rtl8822be_get_desc(struct ieee80211_hw *hw, + u8 *pdesc, bool istx, u8 desc_name); +bool rtl8822be_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, + u16 index); +void rtl8822be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); +void rtl8822be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, + bool firstseg, bool lastseg, + struct sk_buff *skb); +u32 rtl8822be_rx_command_packet(struct ieee80211_hw *hw, + const struct rtl_stats *status, + struct sk_buff *skb); +#endif diff --git a/drivers/staging/rtlwifi/stats.c b/drivers/staging/rtlwifi/stats.c new file mode 100644 index 000000000000..96eb14c92c01 --- /dev/null +++ b/drivers/staging/rtlwifi/stats.c @@ -0,0 +1,260 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ +#include "wifi.h" +#include "stats.h" +#include + +u8 rtl_query_rxpwrpercentage(s8 antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; +} + +u8 rtl_evm_db_to_percentage(s8 value) +{ + s8 ret_val = clamp(-value, 0, 33) * 3; + + if (ret_val == 99) + ret_val = 100; + + return ret_val; +} + +static long rtl_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + +long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + + return retsig; +} + +static void rtl_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &rtlpriv->phy; + u8 rfpath; + u32 last_rssi, tmpval; + + if (!pstatus->packet_toself && !pstatus->packet_beacon) + return; + + rtlpriv->stats.pwdb_all_cnt += pstatus->rx_pwdb_all; + rtlpriv->stats.rssi_calculate_cnt++; + + if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX; + last_rssi = rtlpriv->stats.ui_rssi.elements[ + rtlpriv->stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength; + rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] = + pstatus->signalstrength; + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, (u8)tmpval); + pstatus->rssi = rtlpriv->stats.signal_strength; + + if (pstatus->is_cck) + return; + + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstatus->rx_mimo_signalstrength[rfpath]; + } + if (pstatus->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + rtlpriv->stats.rx_snr_db[rfpath] = pstatus->rx_snr[rfpath]; + rtlpriv->stats.rx_evm_dbm[rfpath] = + pstatus->rx_mimo_evm_dbm[rfpath]; + rtlpriv->stats.rx_cfo_short[rfpath] = + pstatus->cfo_short[rfpath]; + rtlpriv->stats.rx_cfo_tail[rfpath] = pstatus->cfo_tail[rfpath]; + } +} + +static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting = 0; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower; + if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * + 5 + pstatus->recvsignalpower + weighting) / 6; +} + +static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_sta_info *drv_priv = NULL; + struct ieee80211_sta *sta = NULL; + long undec_sm_pwdb; + + rcu_read_lock(); + if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) + sta = rtl_find_sta(hw, pstatus->psaddr); + + /* adhoc or ap mode */ + if (sta) { + drv_priv = (struct rtl_sta_info *)sta->drv_priv; + undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + } + + if (undec_sm_pwdb < 0) + undec_sm_pwdb = pstatus->rx_pwdb_all; + if (pstatus->rx_pwdb_all > (u32)undec_sm_pwdb) { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + undec_sm_pwdb = undec_sm_pwdb + 1; + } else { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + + if (sta) + drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; + else + rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rcu_read_unlock(); + + rtl_update_rxsignalstatistics(hw, pstatus); +} + +static void rtl_process_ui_link_quality(struct ieee80211_hw *hw, + struct rtl_stats *pstatus) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm, n_stream, tmpval; + + if (pstatus->signalquality == 0) + return; + + if (rtlpriv->stats.ui_link_quality.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.ui_link_quality.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index]; + rtlpriv->stats.ui_link_quality.total_val -= last_evm; + } + rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality; + rtlpriv->stats.ui_link_quality.elements[ + rtlpriv->stats.ui_link_quality.index++] = + pstatus->signalquality; + if (rtlpriv->stats.ui_link_quality.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.ui_link_quality.index = 0; + tmpval = rtlpriv->stats.ui_link_quality.total_val / + rtlpriv->stats.ui_link_quality.total_num; + rtlpriv->stats.signal_quality = tmpval; + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + for (n_stream = 0; n_stream < 2; n_stream++) { + if (pstatus->rx_mimo_sig_qual[n_stream] != -1) { + if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) { + rtlpriv->stats.rx_evm_percentage[n_stream] = + pstatus->rx_mimo_sig_qual[n_stream]; + } + rtlpriv->stats.rx_evm_percentage[n_stream] = + ((rtlpriv->stats.rx_evm_percentage[n_stream] + * (RX_SMOOTH_FACTOR - 1)) + + (pstatus->rx_mimo_sig_qual[n_stream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } +} + +void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, + struct rtl_stats *pstatus) +{ + if (!pstatus->packet_matchbssid) + return; + + rtl_process_ui_rssi(hw, pstatus); + rtl_process_pwdb(hw, pstatus); + rtl_process_ui_link_quality(hw, pstatus); +} diff --git a/drivers/staging/rtlwifi/stats.h b/drivers/staging/rtlwifi/stats.h new file mode 100644 index 000000000000..bd0108f93182 --- /dev/null +++ b/drivers/staging/rtlwifi/stats.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_STATS_H__ +#define __RTL_STATS_H__ + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 +#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 + +/* Rx smooth factor */ +#define RX_SMOOTH_FACTOR 20 + +u8 rtl_query_rxpwrpercentage(s8 antpower); +u8 rtl_evm_db_to_percentage(s8 value); +long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig); +void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, + struct rtl_stats *pstatus); + +#endif diff --git a/drivers/staging/rtlwifi/wifi.h b/drivers/staging/rtlwifi/wifi.h new file mode 100644 index 000000000000..eb91c130b245 --- /dev/null +++ b/drivers/staging/rtlwifi/wifi.h @@ -0,0 +1,3375 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2012 Realtek Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#ifndef __RTL_WIFI_H__ +#define __RTL_WIFI_H__ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define MASKBYTE0 0xff +#define MASKBYTE1 0xff00 +#define MASKBYTE2 0xff0000 +#define MASKBYTE3 0xff000000 +#define MASKHWORD 0xffff0000 +#define MASKLWORD 0x0000ffff +#define MASKDWORD 0xffffffff +#define MASK12BITS 0xfff +#define MASKH4BITS 0xf0000000 +#define MASKOFDM_D 0xffc00000 +#define MASKCCK 0x3f3f3f3f + +#define MASK4BITS 0x0f +#define MASK20BITS 0xfffff +#define RFREG_OFFSET_MASK 0xfffff + +#define RF_CHANGE_BY_INIT 0 +#define RF_CHANGE_BY_IPS BIT(28) +#define RF_CHANGE_BY_PS BIT(29) +#define RF_CHANGE_BY_HW BIT(30) +#define RF_CHANGE_BY_SW BIT(31) + +#define IQK_ADDA_REG_NUM 16 +#define IQK_MAC_REG_NUM 4 +#define IQK_THRESHOLD 8 + +#define MAX_KEY_LEN 61 +#define KEY_BUF_SIZE 5 + +/* QoS related. */ +/*aci: 0x00 Best Effort*/ +/*aci: 0x01 Background*/ +/*aci: 0x10 Video*/ +/*aci: 0x11 Voice*/ +/*Max: define total number.*/ +#define AC0_BE 0 +#define AC1_BK 1 +#define AC2_VI 2 +#define AC3_VO 3 +#define AC_MAX 4 +#define QOS_QUEUE_NUM 4 +#define RTL_MAC80211_NUM_QUEUE 5 +#define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 +#define RTL_USB_MAX_RX_COUNT 100 +#define QBSS_LOAD_SIZE 5 +#define MAX_WMMELE_LENGTH 64 + +#define TOTAL_CAM_ENTRY 32 + +/*slot time for 11g. */ +#define RTL_SLOT_TIME_9 9 +#define RTL_SLOT_TIME_20 20 + +/*related to tcp/ip. */ +#define SNAP_SIZE 6 +#define PROTOC_TYPE_SIZE 2 + +/*related with 802.11 frame*/ +#define MAC80211_3ADDR_LEN 24 +#define MAC80211_4ADDR_LEN 30 + +#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */ +#define CHANNEL_MAX_NUMBER_2G 14 +#define CHANNEL_MAX_NUMBER_5G 49 /* Please refer to + *"phy_GetChnlGroup8812A" and + * "Hal_ReadTxPowerInfo8812A" + */ +#define CHANNEL_MAX_NUMBER_5G_80M 7 +#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */ +#define MAX_PG_GROUP 13 +#define CHANNEL_GROUP_MAX_2G 3 +#define CHANNEL_GROUP_IDX_5GL 3 +#define CHANNEL_GROUP_IDX_5GM 6 +#define CHANNEL_GROUP_IDX_5GH 9 +#define CHANNEL_GROUP_MAX_5G 9 +#define CHANNEL_MAX_NUMBER_2G 14 +#define AVG_THERMAL_NUM 8 +#define AVG_THERMAL_NUM_88E 4 +#define AVG_THERMAL_NUM_8723BE 4 +#define MAX_TID_COUNT 9 + +/* for early mode */ +#define FCS_LEN 4 +#define EM_HDR_LEN 8 + +enum rtl8192c_h2c_cmd { + H2C_AP_OFFLOAD = 0, + H2C_SETPWRMODE = 1, + H2C_JOINBSSRPT = 2, + H2C_RSVDPAGE = 3, + H2C_RSSI_REPORT = 5, + H2C_RA_MASK = 6, + H2C_MACID_PS_MODE = 7, + H2C_P2P_PS_OFFLOAD = 8, + H2C_MAC_MODE_SEL = 9, + H2C_PWRM = 15, + H2C_P2P_PS_CTW_CMD = 24, + MAX_H2CCMD +}; + +#define MAX_TX_COUNT 4 +#define MAX_REGULATION_NUM 4 +#define MAX_RF_PATH_NUM 4 +#define MAX_RATE_SECTION_NUM 6 /* = MAX_RATE_SECTION */ +#define MAX_2_4G_BANDWIDTH_NUM 4 +#define MAX_5G_BANDWIDTH_NUM 4 +#define MAX_RF_PATH 4 +#define MAX_CHNL_GROUP_24G 6 +#define MAX_CHNL_GROUP_5G 14 + +#define TX_PWR_BY_RATE_NUM_BAND 2 +#define TX_PWR_BY_RATE_NUM_RF 4 +#define TX_PWR_BY_RATE_NUM_SECTION 12 +/* compatible with TX_PWR_BY_RATE_NUM_SECTION */ +#define TX_PWR_BY_RATE_NUM_RATE 84 +#define MAX_BASE_NUM_IN_PHY_REG_PG_24G 6 /* MAX_RATE_SECTION */ +#define MAX_BASE_NUM_IN_PHY_REG_PG_5G 5 /* MAX_RATE_SECTION -1 */ + +#define BUFDESC_SEG_NUM 1 /* 0:2 seg, 1: 4 seg, 2: 8 seg */ + +#define DEL_SW_IDX_SZ 30 + +/* For now, it's just for 8192ee + * but not OK yet, keep it 0 + */ +#define RTL8192EE_SEG_NUM BUFDESC_SEG_NUM +#define RTL8822BE_SEG_NUM BUFDESC_SEG_NUM + +enum rf_tx_num { + RF_1TX = 0, + RF_2TX, + RF_MAX_TX_NUM, + RF_TX_NUM_NONIMPLEMENT, +}; + +#define PACKET_NORMAL 0 +#define PACKET_DHCP 1 +#define PACKET_ARP 2 +#define PACKET_EAPOL 3 + +#define MAX_SUPPORT_WOL_PATTERN_NUM 16 +#define RSVD_WOL_PATTERN_NUM 1 +#define WKFMCAM_ADDR_NUM 6 +#define WKFMCAM_SIZE 24 + +#define MAX_WOL_BIT_MASK_SIZE 16 +/* MIN LEN keeps 13 here */ +#define MIN_WOL_PATTERN_SIZE 13 +#define MAX_WOL_PATTERN_SIZE 128 + +#define WAKE_ON_MAGIC_PACKET BIT(0) +#define WAKE_ON_PATTERN_MATCH BIT(1) + +#define WOL_REASON_PTK_UPDATE BIT(0) +#define WOL_REASON_GTK_UPDATE BIT(1) +#define WOL_REASON_DISASSOC BIT(2) +#define WOL_REASON_DEAUTH BIT(3) +#define WOL_REASON_AP_LOST BIT(4) +#define WOL_REASON_MAGIC_PKT BIT(5) +#define WOL_REASON_UNICAST_PKT BIT(6) +#define WOL_REASON_PATTERN_PKT BIT(7) +#define WOL_REASON_RTD3_SSID_MATCH BIT(8) +#define WOL_REASON_REALWOW_V2_WAKEUPPKT BIT(9) +#define WOL_REASON_REALWOW_V2_ACKLOST BIT(10) + +struct rtlwifi_firmware_header { + __le16 signature; + u8 category; + u8 function; + __le16 version; + u8 subversion; + u8 rsvd1; + u8 month; + u8 date; + u8 hour; + u8 minute; + __le16 ramcodesize; + __le16 rsvd2; + __le32 svnindex; + __le32 rsvd3; + __le32 rsvd4; + __le32 rsvd5; +}; + +struct txpower_info_2g { + u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + /*If only one tx, only BW20 and OFDM are used.*/ + u8 cck_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT]; +}; + +struct txpower_info_5g { + u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_5G]; + /*If only one tx, only BW20, OFDM, BW80 and BW160 are used.*/ + u8 ofdm_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw20_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw40_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw80_diff[MAX_RF_PATH][MAX_TX_COUNT]; + u8 bw160_diff[MAX_RF_PATH][MAX_TX_COUNT]; +}; + +enum rate_section { + CCK = 0, + OFDM, + HT_MCS0_MCS7, + HT_MCS8_MCS15, + VHT_1SSMCS0_1SSMCS9, + VHT_2SSMCS0_2SSMCS9, + MAX_RATE_SECTION, +}; + +enum intf_type { + INTF_PCI = 0, + INTF_USB = 1, +}; + +enum radio_path { + RF90_PATH_A = 0, + RF90_PATH_B = 1, + RF90_PATH_C = 2, + RF90_PATH_D = 3, +}; + +enum radio_mask { + RF_MASK_A = BIT(0), + RF_MASK_B = BIT(1), + RF_MASK_C = BIT(2), + RF_MASK_D = BIT(3), +}; + +enum regulation_txpwr_lmt { + TXPWR_LMT_FCC = 0, + TXPWR_LMT_MKK = 1, + TXPWR_LMT_ETSI = 2, + TXPWR_LMT_WW = 3, + + TXPWR_LMT_MAX_REGULATION_NUM = 4 +}; + +enum rt_eeprom_type { + EEPROM_93C46, + EEPROM_93C56, + EEPROM_BOOT_EFUSE, +}; + +enum ttl_status { + RTL_STATUS_INTERFACE_START = 0, +}; + +enum hardware_type { + HARDWARE_TYPE_RTL8192E, + HARDWARE_TYPE_RTL8192U, + HARDWARE_TYPE_RTL8192SE, + HARDWARE_TYPE_RTL8192SU, + HARDWARE_TYPE_RTL8192CE, + HARDWARE_TYPE_RTL8192CU, + HARDWARE_TYPE_RTL8192DE, + HARDWARE_TYPE_RTL8192DU, + HARDWARE_TYPE_RTL8723AE, + HARDWARE_TYPE_RTL8723U, + HARDWARE_TYPE_RTL8188EE, + HARDWARE_TYPE_RTL8723BE, + HARDWARE_TYPE_RTL8192EE, + HARDWARE_TYPE_RTL8821AE, + HARDWARE_TYPE_RTL8812AE, + HARDWARE_TYPE_RTL8822BE, + + /* keep it last */ + HARDWARE_TYPE_NUM +}; + +#define RTL_HW_TYPE(rtlpriv) (rtl_hal((struct rtl_priv *)rtlpriv)->hw_type) +#define IS_NEW_GENERATION_IC(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) >= HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8192CE(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192CE) +#define IS_HARDWARE_TYPE_8812(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8812AE) +#define IS_HARDWARE_TYPE_8821(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8821AE) +#define IS_HARDWARE_TYPE_8723A(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723AE) +#define IS_HARDWARE_TYPE_8723B(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8723BE) +#define IS_HARDWARE_TYPE_8192E(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8822B(rtlpriv) \ + (RTL_HW_TYPE(rtlpriv) == HARDWARE_TYPE_RTL8822BE) + +#define RX_HAL_IS_CCK_RATE(rxmcs) \ + ((rxmcs) == DESC_RATE1M || \ + (rxmcs) == DESC_RATE2M || \ + (rxmcs) == DESC_RATE5_5M || \ + (rxmcs) == DESC_RATE11M) + +enum scan_operation_backup_opt { + SCAN_OPT_BACKUP = 0, + SCAN_OPT_BACKUP_BAND0 = 0, + SCAN_OPT_BACKUP_BAND1, + SCAN_OPT_RESTORE, + SCAN_OPT_MAX +}; + +/*RF state.*/ +enum rf_pwrstate { + ERFON, + ERFSLEEP, + ERFOFF +}; + +struct bb_reg_def { + u32 rfintfs; + u32 rfintfi; + u32 rfintfo; + u32 rfintfe; + u32 rf3wire_offset; + u32 rflssi_select; + u32 rftxgain_stage; + u32 rfhssi_para1; + u32 rfhssi_para2; + u32 rfsw_ctrl; + u32 rfagc_control1; + u32 rfagc_control2; + u32 rfrxiq_imbal; + u32 rfrx_afe; + u32 rftxiq_imbal; + u32 rftx_afe; + u32 rf_rb; /* rflssi_readback */ + u32 rf_rbpi; /* rflssi_readbackpi */ +}; + +enum io_type { + IO_CMD_PAUSE_DM_BY_SCAN = 0, + IO_CMD_PAUSE_BAND0_DM_BY_SCAN = 0, + IO_CMD_PAUSE_BAND1_DM_BY_SCAN = 1, + IO_CMD_RESUME_DM_BY_SCAN = 2, +}; + +enum hw_variables { + HW_VAR_ETHER_ADDR = 0x0, + HW_VAR_MULTICAST_REG = 0x1, + HW_VAR_BASIC_RATE = 0x2, + HW_VAR_BSSID = 0x3, + HW_VAR_MEDIA_STATUS = 0x4, + HW_VAR_SECURITY_CONF = 0x5, + HW_VAR_BEACON_INTERVAL = 0x6, + HW_VAR_ATIM_WINDOW = 0x7, + HW_VAR_LISTEN_INTERVAL = 0x8, + HW_VAR_CS_COUNTER = 0x9, + HW_VAR_DEFAULTKEY0 = 0xa, + HW_VAR_DEFAULTKEY1 = 0xb, + HW_VAR_DEFAULTKEY2 = 0xc, + HW_VAR_DEFAULTKEY3 = 0xd, + HW_VAR_SIFS = 0xe, + HW_VAR_R2T_SIFS = 0xf, + HW_VAR_DIFS = 0x10, + HW_VAR_EIFS = 0x11, + HW_VAR_SLOT_TIME = 0x12, + HW_VAR_ACK_PREAMBLE = 0x13, + HW_VAR_CW_CONFIG = 0x14, + HW_VAR_CW_VALUES = 0x15, + HW_VAR_RATE_FALLBACK_CONTROL = 0x16, + HW_VAR_CONTENTION_WINDOW = 0x17, + HW_VAR_RETRY_COUNT = 0x18, + HW_VAR_TR_SWITCH = 0x19, + HW_VAR_COMMAND = 0x1a, + HW_VAR_WPA_CONFIG = 0x1b, + HW_VAR_AMPDU_MIN_SPACE = 0x1c, + HW_VAR_SHORTGI_DENSITY = 0x1d, + HW_VAR_AMPDU_FACTOR = 0x1e, + HW_VAR_MCS_RATE_AVAILABLE = 0x1f, + HW_VAR_AC_PARAM = 0x20, + HW_VAR_ACM_CTRL = 0x21, + HW_VAR_DIS_REQ_QSIZE = 0x22, + HW_VAR_CCX_CHNL_LOAD = 0x23, + HW_VAR_CCX_NOISE_HISTOGRAM = 0x24, + HW_VAR_CCX_CLM_NHM = 0x25, + HW_VAR_TXOPLIMIT = 0x26, + HW_VAR_TURBO_MODE = 0x27, + HW_VAR_RF_STATE = 0x28, + HW_VAR_RF_OFF_BY_HW = 0x29, + HW_VAR_BUS_SPEED = 0x2a, + HW_VAR_SET_DEV_POWER = 0x2b, + + HW_VAR_RCR = 0x2c, + HW_VAR_RATR_0 = 0x2d, + HW_VAR_RRSR = 0x2e, + HW_VAR_CPU_RST = 0x2f, + HW_VAR_CHECK_BSSID = 0x30, + HW_VAR_LBK_MODE = 0x31, + HW_VAR_AES_11N_FIX = 0x32, + HW_VAR_USB_RX_AGGR = 0x33, + HW_VAR_USER_CONTROL_TURBO_MODE = 0x34, + HW_VAR_RETRY_LIMIT = 0x35, + HW_VAR_INIT_TX_RATE = 0x36, + HW_VAR_TX_RATE_REG = 0x37, + HW_VAR_EFUSE_USAGE = 0x38, + HW_VAR_EFUSE_BYTES = 0x39, + HW_VAR_AUTOLOAD_STATUS = 0x3a, + HW_VAR_RF_2R_DISABLE = 0x3b, + HW_VAR_SET_RPWM = 0x3c, + HW_VAR_H2C_FW_PWRMODE = 0x3d, + HW_VAR_H2C_FW_JOINBSSRPT = 0x3e, + HW_VAR_H2C_FW_MEDIASTATUSRPT = 0x3f, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD = 0x40, + HW_VAR_FW_PSMODE_STATUS = 0x41, + HW_VAR_INIT_RTS_RATE = 0x42, + HW_VAR_RESUME_CLK_ON = 0x43, + HW_VAR_FW_LPS_ACTION = 0x44, + HW_VAR_1X1_RECV_COMBINE = 0x45, + HW_VAR_STOP_SEND_BEACON = 0x46, + HW_VAR_TSF_TIMER = 0x47, + HW_VAR_IO_CMD = 0x48, + + HW_VAR_RF_RECOVERY = 0x49, + HW_VAR_H2C_FW_UPDATE_GTK = 0x4a, + HW_VAR_WF_MASK = 0x4b, + HW_VAR_WF_CRC = 0x4c, + HW_VAR_WF_IS_MAC_ADDR = 0x4d, + HW_VAR_H2C_FW_OFFLOAD = 0x4e, + HW_VAR_RESET_WFCRC = 0x4f, + + HW_VAR_HANDLE_FW_C2H = 0x50, + HW_VAR_DL_FW_RSVD_PAGE = 0x51, + HW_VAR_AID = 0x52, + HW_VAR_HW_SEQ_ENABLE = 0x53, + HW_VAR_CORRECT_TSF = 0x54, + HW_VAR_BCN_VALID = 0x55, + HW_VAR_FWLPS_RF_ON = 0x56, + HW_VAR_DUAL_TSF_RST = 0x57, + HW_VAR_SWITCH_EPHY_WOWLAN = 0x58, + HW_VAR_INT_MIGRATION = 0x59, + HW_VAR_INT_AC = 0x5a, + HW_VAR_RF_TIMING = 0x5b, + + HAL_DEF_WOWLAN = 0x5c, + HW_VAR_MRC = 0x5d, + HW_VAR_KEEP_ALIVE = 0x5e, + HW_VAR_NAV_UPPER = 0x5f, + + HW_VAR_MGT_FILTER = 0x60, + HW_VAR_CTRL_FILTER = 0x61, + HW_VAR_DATA_FILTER = 0x62, +}; + +enum rt_media_status { + RT_MEDIA_DISCONNECT = 0, + RT_MEDIA_CONNECT = 1 +}; + +enum rt_oem_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_HP = 27, + RT_CID_819X_CLEVO = 28, + RT_CID_819X_ARCADYAN_BELKIN = 29, + RT_CID_819X_SAMSUNG = 30, + RT_CID_819X_WNC_COREGA = 31, + RT_CID_819X_FOXCOON = 32, + RT_CID_819X_DELL = 33, + RT_CID_819X_PRONETS = 34, + RT_CID_819X_EDIMAX_ASUS = 35, + RT_CID_NETGEAR = 36, + RT_CID_PLANEX = 37, + RT_CID_CC_C = 38, +}; + +enum hw_descs { + HW_DESC_OWN, + HW_DESC_RXOWN, + HW_DESC_TX_NEXTDESC_ADDR, + HW_DESC_TXBUFF_ADDR, + HW_DESC_RXBUFF_ADDR, + HW_DESC_RXPKT_LEN, + HW_DESC_RXERO, + HW_DESC_RX_PREPARE, +}; + +enum prime_sc { + PRIME_CHNL_OFFSET_DONT_CARE = 0, + PRIME_CHNL_OFFSET_LOWER = 1, + PRIME_CHNL_OFFSET_UPPER = 2, +}; + +enum rf_type { + RF_1T1R = 0, + RF_1T2R = 1, + RF_2T2R = 2, + RF_2T2R_GREEN = 3, + RF_2T3R = 4, + RF_2T4R = 5, + RF_3T3R = 6, + RF_3T4R = 7, + RF_4T4R = 8, +}; + +enum ht_channel_width { + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_20_40 = 1, + HT_CHANNEL_WIDTH_80 = 2, + HT_CHANNEL_WIDTH_MAX, +}; + +/* Ref: 802.11i spec D10.0 7.3.2.25.1 + * Cipher Suites Encryption Algorithms + */ +enum rt_enc_alg { + NO_ENCRYPTION = 0, + WEP40_ENCRYPTION = 1, + TKIP_ENCRYPTION = 2, + RSERVED_ENCRYPTION = 3, + AESCCMP_ENCRYPTION = 4, + WEP104_ENCRYPTION = 5, + AESCMAC_ENCRYPTION = 6, /*IEEE802.11w */ +}; + +enum rtl_hal_state { + _HAL_STATE_STOP = 0, + _HAL_STATE_START = 1, +}; + +enum rtl_desc_rate { + DESC_RATE1M = 0x00, + DESC_RATE2M = 0x01, + DESC_RATE5_5M = 0x02, + DESC_RATE11M = 0x03, + + DESC_RATE6M = 0x04, + DESC_RATE9M = 0x05, + DESC_RATE12M = 0x06, + DESC_RATE18M = 0x07, + DESC_RATE24M = 0x08, + DESC_RATE36M = 0x09, + DESC_RATE48M = 0x0a, + DESC_RATE54M = 0x0b, + + DESC_RATEMCS0 = 0x0c, + DESC_RATEMCS1 = 0x0d, + DESC_RATEMCS2 = 0x0e, + DESC_RATEMCS3 = 0x0f, + DESC_RATEMCS4 = 0x10, + DESC_RATEMCS5 = 0x11, + DESC_RATEMCS6 = 0x12, + DESC_RATEMCS7 = 0x13, + DESC_RATEMCS8 = 0x14, + DESC_RATEMCS9 = 0x15, + DESC_RATEMCS10 = 0x16, + DESC_RATEMCS11 = 0x17, + DESC_RATEMCS12 = 0x18, + DESC_RATEMCS13 = 0x19, + DESC_RATEMCS14 = 0x1a, + DESC_RATEMCS15 = 0x1b, + DESC_RATEMCS15_SG = 0x1c, + DESC_RATEMCS32 = 0x20, + + DESC_RATEVHT1SS_MCS0 = 0x2c, + DESC_RATEVHT1SS_MCS1 = 0x2d, + DESC_RATEVHT1SS_MCS2 = 0x2e, + DESC_RATEVHT1SS_MCS3 = 0x2f, + DESC_RATEVHT1SS_MCS4 = 0x30, + DESC_RATEVHT1SS_MCS5 = 0x31, + DESC_RATEVHT1SS_MCS6 = 0x32, + DESC_RATEVHT1SS_MCS7 = 0x33, + DESC_RATEVHT1SS_MCS8 = 0x34, + DESC_RATEVHT1SS_MCS9 = 0x35, + DESC_RATEVHT2SS_MCS0 = 0x36, + DESC_RATEVHT2SS_MCS1 = 0x37, + DESC_RATEVHT2SS_MCS2 = 0x38, + DESC_RATEVHT2SS_MCS3 = 0x39, + DESC_RATEVHT2SS_MCS4 = 0x3a, + DESC_RATEVHT2SS_MCS5 = 0x3b, + DESC_RATEVHT2SS_MCS6 = 0x3c, + DESC_RATEVHT2SS_MCS7 = 0x3d, + DESC_RATEVHT2SS_MCS8 = 0x3e, + DESC_RATEVHT2SS_MCS9 = 0x3f, +}; + +enum rtl_var_map { + /*reg map */ + SYS_ISO_CTRL = 0, + SYS_FUNC_EN, + SYS_CLK, + MAC_RCR_AM, + MAC_RCR_AB, + MAC_RCR_ACRC32, + MAC_RCR_ACF, + MAC_RCR_AAP, + MAC_HIMR, + MAC_HIMRE, + MAC_HSISR, + + /*efuse map */ + EFUSE_TEST, + EFUSE_CTRL, + EFUSE_CLK, + EFUSE_CLK_CTRL, + EFUSE_PWC_EV12V, + EFUSE_FEN_ELDR, + EFUSE_LOADER_CLK_EN, + EFUSE_ANA8M, + EFUSE_HWSET_MAX_SIZE, + EFUSE_MAX_SECTION_MAP, + EFUSE_REAL_CONTENT_SIZE, + EFUSE_OOB_PROTECT_BYTES_LEN, + EFUSE_ACCESS, + + /*CAM map */ + RWCAM, + WCAMI, + RCAMO, + CAMDBG, + SECR, + SEC_CAM_NONE, + SEC_CAM_WEP40, + SEC_CAM_TKIP, + SEC_CAM_AES, + SEC_CAM_WEP104, + + /*IMR map */ + RTL_IMR_BCNDMAINT6, /*Beacon DMA Interrupt 6 */ + RTL_IMR_BCNDMAINT5, /*Beacon DMA Interrupt 5 */ + RTL_IMR_BCNDMAINT4, /*Beacon DMA Interrupt 4 */ + RTL_IMR_BCNDMAINT3, /*Beacon DMA Interrupt 3 */ + RTL_IMR_BCNDMAINT2, /*Beacon DMA Interrupt 2 */ + RTL_IMR_BCNDMAINT1, /*Beacon DMA Interrupt 1 */ + RTL_IMR_BCNDOK8, /*Beacon Queue DMA OK Interrupt 8 */ + RTL_IMR_BCNDOK7, /*Beacon Queue DMA OK Interrupt 7 */ + RTL_IMR_BCNDOK6, /*Beacon Queue DMA OK Interrupt 6 */ + RTL_IMR_BCNDOK5, /*Beacon Queue DMA OK Interrupt 5 */ + RTL_IMR_BCNDOK4, /*Beacon Queue DMA OK Interrupt 4 */ + RTL_IMR_BCNDOK3, /*Beacon Queue DMA OK Interrupt 3 */ + RTL_IMR_BCNDOK2, /*Beacon Queue DMA OK Interrupt 2 */ + RTL_IMR_BCNDOK1, /*Beacon Queue DMA OK Interrupt 1 */ + RTL_IMR_TIMEOUT2, /*Timeout interrupt 2 */ + RTL_IMR_TIMEOUT1, /*Timeout interrupt 1 */ + RTL_IMR_TXFOVW, /*Transmit FIFO Overflow */ + RTL_IMR_PSTIMEOUT, /*Power save time out interrupt */ + RTL_IMR_BCNINT, /*Beacon DMA Interrupt 0 */ + RTL_IMR_RXFOVW, /*Receive FIFO Overflow */ + RTL_IMR_RDU, /*Receive Descriptor Unavailable */ + RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ + RTL_IMR_H2CDOK, /*H2C Queue DMA OK Interrupt */ + RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrupt */ + RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ + RTL_IMR_COMDOK, /*Command Queue DMA OK Interrupt*/ + RTL_IMR_TBDOK, /*Transmit Beacon OK interrupt */ + RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */ + RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */ + RTL_IMR_BKDOK, /*AC_BK DMA OK Interrupt */ + RTL_IMR_BEDOK, /*AC_BE DMA OK Interrupt */ + RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ + RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ + RTL_IMR_ROK, /*Receive DMA OK Interrupt */ + RTL_IMR_HSISR_IND, /*HSISR Interrupt*/ + RTL_IBSS_INT_MASKS, /*(RTL_IMR_BCNINT | RTL_IMR_TBDOK | + * RTL_IMR_TBDER) + */ + RTL_IMR_C2HCMD, /*fw interrupt*/ + + /*CCK Rates, TxHT = 0 */ + RTL_RC_CCK_RATE1M, + RTL_RC_CCK_RATE2M, + RTL_RC_CCK_RATE5_5M, + RTL_RC_CCK_RATE11M, + + /*OFDM Rates, TxHT = 0 */ + RTL_RC_OFDM_RATE6M, + RTL_RC_OFDM_RATE9M, + RTL_RC_OFDM_RATE12M, + RTL_RC_OFDM_RATE18M, + RTL_RC_OFDM_RATE24M, + RTL_RC_OFDM_RATE36M, + RTL_RC_OFDM_RATE48M, + RTL_RC_OFDM_RATE54M, + + RTL_RC_HT_RATEMCS7, + RTL_RC_HT_RATEMCS15, + + RTL_RC_VHT_RATE_1SS_MCS7, + RTL_RC_VHT_RATE_1SS_MCS8, + RTL_RC_VHT_RATE_1SS_MCS9, + RTL_RC_VHT_RATE_2SS_MCS7, + RTL_RC_VHT_RATE_2SS_MCS8, + RTL_RC_VHT_RATE_2SS_MCS9, + + /*keep it last */ + RTL_VAR_MAP_MAX, +}; + +/*Firmware PS mode for control LPS.*/ +enum _fw_ps_mode { + FW_PS_ACTIVE_MODE = 0, + FW_PS_MIN_MODE = 1, + FW_PS_MAX_MODE = 2, + FW_PS_DTIM_MODE = 3, + FW_PS_VOIP_MODE = 4, + FW_PS_UAPSD_WMM_MODE = 5, + FW_PS_UAPSD_MODE = 6, + FW_PS_IBSS_MODE = 7, + FW_PS_WWLAN_MODE = 8, + FW_PS_PM_RADIO_OFF = 9, + FW_PS_PM_CARD_DISABLE = 10, +}; + +enum rt_psmode { + EACTIVE, /*Active/Continuous access. */ + EMAXPS, /*Max power save mode. */ + EFASTPS, /*Fast power save mode. */ + EAUTOPS, /*Auto power save mode. */ +}; + +/*LED related.*/ +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, +}; + +enum rtl_led_pin { + LED_PIN_GPIO0, + LED_PIN_LED0, + LED_PIN_LED1, + LED_PIN_LED2 +}; + +/* QoS related.*/ +/* acm implementation method.*/ +enum acm_method { + EACMWAY0_SWANDHW = 0, + EACMWAY1_HW = 1, + EACMWAY2_SW = 2, +}; + +enum macphy_mode { + SINGLEMAC_SINGLEPHY = 0, + DUALMAC_DUALPHY, + DUALMAC_SINGLEPHY, +}; + +enum band_type { + BAND_ON_2_4G = 0, + BAND_ON_5G, + BAND_ON_BOTH, + BANDMAX +}; + +/* aci/aifsn Field. + * Ref: WMM spec 2.2.2: WME Parameter Element, p.12. + */ +union aci_aifsn { + u8 char_data; + + struct { + u8 aifsn:4; + u8 acm:1; + u8 aci:2; + u8 reserved:1; + } f; /* Field */ +}; + +/*mlme related.*/ +enum wireless_mode { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20, + WIRELESS_MODE_AC_5G = 0x40, + WIRELESS_MODE_AC_24G = 0x80, + WIRELESS_MODE_AC_ONLY = 0x100, + WIRELESS_MODE_MAX = 0x800 +}; + +#define IS_WIRELESS_MODE_A(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_A) +#define IS_WIRELESS_MODE_B(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_B) +#define IS_WIRELESS_MODE_G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_G) +#define IS_WIRELESS_MODE_N_24G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_24G) +#define IS_WIRELESS_MODE_N_5G(wirelessmode) \ + (wirelessmode == WIRELESS_MODE_N_5G) + +enum ratr_table_mode { + RATR_INX_WIRELESS_NGB = 0, + RATR_INX_WIRELESS_NG = 1, + RATR_INX_WIRELESS_NB = 2, + RATR_INX_WIRELESS_N = 3, + RATR_INX_WIRELESS_GB = 4, + RATR_INX_WIRELESS_G = 5, + RATR_INX_WIRELESS_B = 6, + RATR_INX_WIRELESS_MC = 7, + RATR_INX_WIRELESS_A = 8, + RATR_INX_WIRELESS_AC_5N = 8, + RATR_INX_WIRELESS_AC_24N = 9, +}; + +enum ratr_table_mode_new { + RATEID_IDX_BGN_40M_2SS = 0, + RATEID_IDX_BGN_40M_1SS = 1, + RATEID_IDX_BGN_20M_2SS_BN = 2, + RATEID_IDX_BGN_20M_1SS_BN = 3, + RATEID_IDX_GN_N2SS = 4, + RATEID_IDX_GN_N1SS = 5, + RATEID_IDX_BG = 6, + RATEID_IDX_G = 7, + RATEID_IDX_B = 8, + RATEID_IDX_VHT_2SS = 9, + RATEID_IDX_VHT_1SS = 10, + RATEID_IDX_MIX1 = 11, + RATEID_IDX_MIX2 = 12, + RATEID_IDX_VHT_3SS = 13, + RATEID_IDX_BGN_3SS = 14, +}; + +enum rtl_link_state { + MAC80211_NOLINK = 0, + MAC80211_LINKING = 1, + MAC80211_LINKED = 2, + MAC80211_LINKED_SCANNING = 3, +}; + +enum act_category { + ACT_CAT_QOS = 1, + ACT_CAT_DLS = 2, + ACT_CAT_BA = 3, + ACT_CAT_HT = 7, + ACT_CAT_WMM = 17, +}; + +enum ba_action { + ACT_ADDBAREQ = 0, + ACT_ADDBARSP = 1, + ACT_DELBA = 2, +}; + +enum rt_polarity_ctl { + RT_POLARITY_LOW_ACT = 0, + RT_POLARITY_HIGH_ACT = 1, +}; + +/* After 8188E, we use V2 reason define. 88C/8723A use V1 reason. */ +enum fw_wow_reason_v2 { + FW_WOW_V2_PTK_UPDATE_EVENT = 0x01, + FW_WOW_V2_GTK_UPDATE_EVENT = 0x02, + FW_WOW_V2_DISASSOC_EVENT = 0x04, + FW_WOW_V2_DEAUTH_EVENT = 0x08, + FW_WOW_V2_FW_DISCONNECT_EVENT = 0x10, + FW_WOW_V2_MAGIC_PKT_EVENT = 0x21, + FW_WOW_V2_UNICAST_PKT_EVENT = 0x22, + FW_WOW_V2_PATTERN_PKT_EVENT = 0x23, + FW_WOW_V2_RTD3_SSID_MATCH_EVENT = 0x24, + FW_WOW_V2_REALWOW_V2_WAKEUPPKT = 0x30, + FW_WOW_V2_REALWOW_V2_ACKLOST = 0x31, + FW_WOW_V2_REASON_MAX = 0xff, +}; + +enum wolpattern_type { + UNICAST_PATTERN = 0, + MULTICAST_PATTERN = 1, + BROADCAST_PATTERN = 2, + DONT_CARE_DA = 3, + UNKNOWN_TYPE = 4, +}; + +enum package_type { + PACKAGE_DEFAULT, + PACKAGE_QFN68, + PACKAGE_TFBGA90, + PACKAGE_TFBGA80, + PACKAGE_TFBGA79 +}; + +enum rtl_spec_ver { + RTL_SPEC_NEW_RATEID = BIT(0), /* use ratr_table_mode_new */ + RTL_SPEC_SUPPORT_VHT = BIT(1), /* support VHT */ + RTL_SPEC_NEW_FW_C2H = BIT(2), /* new FW C2H (e.g. TX REPORT) */ +}; + +struct octet_string { + u8 *octet; + u16 length; +}; + +struct rtl_hdr_3addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __packed; + +struct rtl_info_element { + u8 id; + u8 len; + u8 data[0]; +} __packed; + +struct rtl_probe_rsp { + struct rtl_hdr_3addr header; + u32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + /* SSID, supported rates, FH params, DS params, + * CF params, IBSS params, TIM (if beacon), RSN + */ + struct rtl_info_element info_element[0]; +} __packed; + +struct rtl_beacon_keys { + /*u8 ssid[32];*/ + /*u32 ssid_len;*/ + u8 bcn_channel; + __le16 ht_cap_info; + u8 ht_info_infos_0_sco; /* bit0 & bit1 in infos[0] is 2nd ch offset */ + bool valid; +}; + +/*LED related.*/ +/*ledpin Identify how to implement this SW led.*/ +struct rtl_led { + void *hw; + enum rtl_led_pin ledpin; + bool ledon; +}; + +struct rtl_led_ctl { + bool led_opendrain; + struct rtl_led sw_led0; + struct rtl_led sw_led1; +}; + +struct rtl_qos_parameters { + __le16 cw_min; + __le16 cw_max; + u8 aifs; + u8 flag; + __le16 tx_op; +} __packed; + +struct rt_smooth_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 false_alarm_statistics { + u32 cnt_parity_fail; + u32 cnt_rate_illegal; + u32 cnt_crc8_fail; + u32 cnt_mcs_fail; + u32 cnt_fast_fsync_fail; + u32 cnt_sb_search_fail; + u32 cnt_ofdm_fail; + u32 cnt_cck_fail; + u32 cnt_all; + u32 cnt_ofdm_cca; + u32 cnt_cck_cca; + u32 cnt_cca_all; + u32 cnt_bw_usc; + u32 cnt_bw_lsc; +}; + +struct init_gain { + u8 xaagccore1; + u8 xbagccore1; + u8 xcagccore1; + u8 xdagccore1; + u8 cca; + +}; + +struct wireless_stats { + u64 txbytesunicast; + u64 txbytesmulticast; + u64 txbytesbroadcast; + u64 rxbytesunicast; + + u64 txbytesunicast_inperiod; + u64 rxbytesunicast_inperiod; + u32 txbytesunicast_inperiod_tp; + u32 rxbytesunicast_inperiod_tp; + u64 txbytesunicast_last; + u64 rxbytesunicast_last; + + long rx_snr_db[4]; + /* Correct smoothed ss in Dbm, only used + * in driver to report real power now. + */ + long recv_signal_power; + long signal_quality; + long last_sigstrength_inpercent; + + u32 rssi_calculate_cnt; + u32 pwdb_all_cnt; + + /* Transformed, in dbm. Beautified signal + * strength for UI, not correct. + */ + long signal_strength; + + u8 rx_rssi_percentage[4]; + u8 rx_evm_dbm[4]; + u8 rx_evm_percentage[2]; + + u16 rx_cfo_short[4]; + u16 rx_cfo_tail[4]; + + struct rt_smooth_data ui_rssi; + struct rt_smooth_data ui_link_quality; +}; + +struct rate_adaptive { + u8 rate_adaptive_disabled; + u8 ratr_state; + u16 reserve; + + u32 high_rssi_thresh_for_ra; + u32 high2low_rssi_thresh_for_ra; + u8 low2high_rssi_thresh_for_ra40m; + u32 low_rssi_thresh_for_ra40m; + u8 low2high_rssi_thresh_for_ra20m; + u32 low_rssi_thresh_for_ra20m; + u32 upper_rssi_threshold_ratr; + u32 middleupper_rssi_threshold_ratr; + u32 middle_rssi_threshold_ratr; + u32 middlelow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr; + u32 ultralow_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr_40m; + u32 low_rssi_threshold_ratr_20m; + u8 ping_rssi_enable; + u32 ping_rssi_ratr; + u32 ping_rssi_thresh_for_ra; + u32 last_ratr; + u8 pre_ratr_state; + u8 ldpc_thres; + bool use_ldpc; + bool lower_rts_rate; + bool is_special_data; +}; + +struct regd_pair_mapping { + u16 reg_dmnenum; + u16 reg_5ghz_ctl; + u16 reg_2ghz_ctl; +}; + +struct dynamic_primary_cca { + u8 pricca_flag; + u8 intf_flag; + u8 intf_type; + u8 dup_rts_flag; + u8 monitor_flag; + u8 ch_offset; + u8 mf_state; +}; + +struct rtl_regulatory { + s8 alpha2[2]; + u16 country_code; + u16 max_power_level; + u32 tp_scale; + u16 current_rd; + u16 current_rd_ext; + s16 power_limit; + struct regd_pair_mapping *regpair; +}; + +struct rtl_rfkill { + bool rfkill_state; /*0 is off, 1 is on */ +}; + +/*for P2P PS**/ +#define P2P_MAX_NOA_NUM 2 + +enum p2p_role { + P2P_ROLE_DISABLE = 0, + P2P_ROLE_DEVICE = 1, + P2P_ROLE_CLIENT = 2, + P2P_ROLE_GO = 3 +}; + +enum p2p_ps_state { + P2P_PS_DISABLE = 0, + P2P_PS_ENABLE = 1, + P2P_PS_SCAN = 2, + P2P_PS_SCAN_DONE = 3, + P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */ +}; + +enum p2p_ps_mode { + P2P_PS_NONE = 0, + P2P_PS_CTWINDOW = 1, + P2P_PS_NOA = 2, + P2P_PS_MIX = 3, /* CTWindow and NoA */ +}; + +struct rtl_p2p_ps_info { + enum p2p_ps_mode p2p_ps_mode; /* indicate p2p ps mode */ + enum p2p_ps_state p2p_ps_state; /* indicate p2p ps state */ + u8 noa_index; /* Identifies instance of Notice of Absence timing. */ + /* Client traffic window. A period of time in TU after TBTT. */ + u8 ctwindow; + u8 opp_ps; /* opportunistic power save. */ + u8 noa_num; /* number of NoA descriptor in P2P IE. */ + /* Count for owner, Type of client. */ + u8 noa_count_type[P2P_MAX_NOA_NUM]; + /* Max duration for owner, preferred or min acceptable duration + * for client. + */ + u32 noa_duration[P2P_MAX_NOA_NUM]; + /* Length of interval for owner, preferred or max acceptable intervali + * of client. + */ + u32 noa_interval[P2P_MAX_NOA_NUM]; + /* schedule in terms of the lower 4 bytes of the TSF timer. */ + u32 noa_start_time[P2P_MAX_NOA_NUM]; +}; + +struct p2p_ps_offload_t { + u8 offload_en:1; + u8 role:1; /* 1: Owner, 0: Client */ + u8 ctwindow_en:1; + u8 noa0_en:1; + u8 noa1_en:1; + u8 allstasleep:1; + u8 discovery:1; + u8 reserved:1; +}; + +#define IQK_MATRIX_REG_NUM 8 +#define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) + +struct iqk_matrix_regs { + bool iqk_done; + long value[1][IQK_MATRIX_REG_NUM]; +}; + +struct phy_parameters { + u16 length; + u32 *pdata; +}; + +enum hw_param_tab_index { + PHY_REG_2T, + PHY_REG_1T, + PHY_REG_PG, + RADIOA_2T, + RADIOB_2T, + RADIOA_1T, + RADIOB_1T, + MAC_REG, + AGCTAB_2T, + AGCTAB_1T, + MAX_TAB +}; + +struct rtl_phy { + struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */ + struct init_gain initgain_backup; + enum io_type current_io_type; + + u8 rf_mode; + u8 rf_type; + u8 current_chan_bw; + u8 max_ht_chan_bw; + u8 max_vht_chan_bw; + u8 set_bwmode_inprogress; + u8 sw_chnl_inprogress; + u8 sw_chnl_stage; + u8 sw_chnl_step; + u8 current_channel; + u8 h2c_box_num; + u8 set_io_inprogress; + u8 lck_inprogress; + + /* record for power tracking */ + s32 reg_e94; + s32 reg_e9c; + s32 reg_ea4; + s32 reg_eac; + s32 reg_eb4; + s32 reg_ebc; + s32 reg_ec4; + s32 reg_ecc; + u8 rfpienable; + u8 reserve_0; + u16 reserve_1; + u32 reg_c04, reg_c08, reg_874; + u32 adda_backup[16]; + u32 iqk_mac_backup[IQK_MAC_REG_NUM]; + u32 iqk_bb_backup[10]; + bool iqk_initialized; + + bool rfpath_rx_enable[MAX_RF_PATH]; + u8 reg_837; + /* Dual mac */ + bool need_iqk; + struct iqk_matrix_regs iqk_matrix[IQK_MATRIX_SETTINGS_NUM]; + + bool rfpi_enable; + bool iqk_in_progress; + + u8 pwrgroup_cnt; + u8 cck_high_power; + /* this is for 88E & 8723A */ + u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; + /* MAX_PG_GROUP groups of pwr diff by rates */ + u32 mcs_offset[MAX_PG_GROUP][16]; + u32 tx_power_by_rate_offset[TX_PWR_BY_RATE_NUM_BAND] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RATE]; + /* compatible with TX_PWR_BY_RATE_NUM_SECTION*/ + u8 txpwr_by_rate_base_24g[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_24G]; + u8 txpwr_by_rate_base_5g[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_5G]; + u8 default_initialgain[4]; + + /* the current Tx power level */ + u8 cur_cck_txpwridx; + u8 cur_ofdm24g_txpwridx; + u8 cur_bw20_txpwridx; + u8 cur_bw40_txpwridx; + + s8 txpwr_limit_2_4g[MAX_REGULATION_NUM] + [MAX_2_4G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_2G] + [MAX_RF_PATH_NUM]; + s8 txpwr_limit_5g[MAX_REGULATION_NUM] + [MAX_5G_BANDWIDTH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_5G] + [MAX_RF_PATH_NUM]; + + u32 rfreg_chnlval[2]; + bool apk_done; + u32 reg_rf3c[2]; /* pathA / pathB */ + + u32 backup_rf_0x1a;/*92ee*/ + /* bfsync */ + u8 framesync; + u32 framesync_c34; + + u8 num_total_rfpath; + struct phy_parameters hwparam_tables[MAX_TAB]; + u16 rf_pathmap; + + u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/ + enum rt_polarity_ctl polarity_ctl; +}; + +#define MAX_TID_COUNT 9 +#define RTL_AGG_STOP 0 +#define RTL_AGG_PROGRESS 1 +#define RTL_AGG_START 2 +#define RTL_AGG_OPERATIONAL 3 +#define RTL_AGG_OFF 0 +#define RTL_AGG_ON 1 +#define RTL_RX_AGG_START 1 +#define RTL_RX_AGG_STOP 0 +#define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA 2 +#define RTL_AGG_EMPTYING_HW_QUEUE_DELBA 3 + +struct rtl_ht_agg { + u16 txq_id; + u16 wait_for_ba; + u16 start_idx; + u64 bitmap; + u32 rate_n_flags; + u8 agg_state; + u8 rx_agg_state; +}; + +struct rssi_sta { + /* for old dm */ + long undec_sm_pwdb; + long undec_sm_cck; + + /* for new phydm_mod */ + s32 undecorated_smoothed_pwdb; + s32 undecorated_smoothed_cck; + s32 undecorated_smoothed_ofdm; + u8 ofdm_pkt; + u8 cck_pkt; + u16 cck_sum_power; + u8 is_send_rssi; + u64 packet_map; + u8 valid_bit; +}; + +struct rtl_tid_data { + u16 seq_number; + struct rtl_ht_agg agg; +}; + +struct rtl_sta_info { + struct list_head list; + struct rtl_tid_data tids[MAX_TID_COUNT]; + /* just used for ap adhoc or mesh*/ + struct rssi_sta rssi_stat; + u8 rssi_level; + u16 wireless_mode; + u8 ratr_index; + u8 mimo_ps; + u8 mac_addr[ETH_ALEN]; +} __packed; + +struct rtl_priv; +struct rtl_io { + struct device *dev; + struct mutex bb_mutex; + + /*PCI MEM map */ + unsigned long pci_mem_end; /*shared mem end */ + unsigned long pci_mem_start; /*shared mem start */ + + /*PCI IO map */ + unsigned long pci_base_addr; /*device I/O address */ + + void (*write8_async)(struct rtl_priv *rtlpriv, u32 addr, u8 val); + void (*write16_async)(struct rtl_priv *rtlpriv, u32 addr, u16 val); + void (*write32_async)(struct rtl_priv *rtlpriv, u32 addr, u32 val); + void (*writeN_sync)(struct rtl_priv *rtlpriv, u32 addr, void *buf, + u16 len); + + u8 (*read8_sync)(struct rtl_priv *rtlpriv, u32 addr); + u16 (*read16_sync)(struct rtl_priv *rtlpriv, u32 addr); + u32 (*read32_sync)(struct rtl_priv *rtlpriv, u32 addr); + +}; + +struct rtl_mac { + u8 mac_addr[ETH_ALEN]; + u8 mac80211_registered; + u8 beacon_enabled; + + u32 tx_ss_num; + u32 rx_ss_num; + + struct ieee80211_supported_band bands[NUM_NL80211_BANDS]; + struct ieee80211_hw *hw; + struct ieee80211_vif *vif; + enum nl80211_iftype opmode; + + /*Probe Beacon management */ + struct rtl_tid_data tids[MAX_TID_COUNT]; + enum rtl_link_state link_state; + struct rtl_beacon_keys cur_beacon_keys; + u8 new_beacon_cnt; + + int n_channels; + int n_bitrates; + + bool offchan_delay; + u8 p2p; /*using p2p role*/ + bool p2p_in_use; + + /*filters */ + u32 rx_conf; + u16 rx_mgt_filter; + u16 rx_ctrl_filter; + u16 rx_data_filter; + + bool act_scanning; + u8 cnt_after_linked; + bool skip_scan; + + /* early mode */ + /* skb wait queue */ + struct sk_buff_head skb_waitq[MAX_TID_COUNT]; + + u8 ht_stbc_cap; + u8 ht_cur_stbc; + + /*vht support*/ + u8 vht_enable; + u8 bw_80; + u8 vht_cur_ldpc; + u8 vht_cur_stbc; + u8 vht_stbc_cap; + u8 vht_ldpc_cap; + + /*RDG*/ + bool rdg_en; + + /*AP*/ + u8 bssid[ETH_ALEN] __aligned(2); + u32 vendor; + u8 mcs[16]; /* 16 bytes mcs for HT rates. */ + u32 basic_rates; /* b/g rates */ + u8 ht_enable; + u8 sgi_40; + u8 sgi_20; + u8 bw_40; + u16 mode; /* wireless mode */ + u8 slot_time; + u8 short_preamble; + u8 use_cts_protect; + u8 cur_40_prime_sc; + u8 cur_40_prime_sc_bk; + u8 cur_80_prime_sc; + u64 tsf; + u8 retry_short; + u8 retry_long; + u16 assoc_id; + bool hiddenssid; + + /*IBSS*/ + int beacon_interval; + + /*AMPDU*/ + u8 min_space_cfg; /*For Min spacing configurations */ + u8 max_mss_density; + u8 current_ampdu_factor; + u8 current_ampdu_density; + + /*QOS & EDCA */ + struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; + struct rtl_qos_parameters ac[AC_MAX]; + + /* counters */ + u64 last_txok_cnt; + u64 last_rxok_cnt; + u32 last_bt_edca_ul; + u32 last_bt_edca_dl; +}; + +struct btdm_8723 { + bool all_off; + bool agc_table_en; + bool adc_back_off_on; + bool b2_ant_hid_en; + bool low_penalty_rate_adaptive; + bool rf_rx_lpf_shrink; + bool reject_aggre_pkt; + bool tra_tdma_on; + u8 tra_tdma_nav; + u8 tra_tdma_ant; + bool tdma_on; + u8 tdma_ant; + u8 tdma_nav; + u8 tdma_dac_swing; + u8 fw_dac_swing_lvl; + bool ps_tdma_on; + u8 ps_tdma_byte[5]; + bool pta_on; + u32 val_0x6c0; + u32 val_0x6c8; + u32 val_0x6cc; + bool sw_dac_swing_on; + u32 sw_dac_swing_lvl; + u32 wlan_act_hi; + u32 wlan_act_lo; + u32 bt_retry_index; + bool dec_bt_pwr; + bool ignore_wlan_act; +}; + +struct bt_coexist_8723 { + u32 high_priority_tx; + u32 high_priority_rx; + u32 low_priority_tx; + u32 low_priority_rx; + u8 c2h_bt_info; + bool c2h_bt_info_req_sent; + bool c2h_bt_inquiry_page; + u32 bt_inq_page_start_time; + u8 bt_retry_cnt; + u8 c2h_bt_info_original; + u8 bt_inquiry_page_cnt; + struct btdm_8723 btdm; +}; + +struct rtl_hal { + struct ieee80211_hw *hw; + bool driver_is_goingto_unload; + bool up_first_time; + bool first_init; + bool being_init_adapter; + bool bbrf_ready; + bool mac_func_enable; + bool pre_edcca_enable; + struct bt_coexist_8723 hal_coex_8723; + + enum intf_type interface; + u16 hw_type; /*92c or 92d or 92s and so on */ + u8 ic_class; + u8 oem_id; + u32 version; /*version of chip */ + u8 state; /*stop 0, start 1 */ + u8 board_type; + u8 package_type; + u8 external_pa; + + u8 pa_mode; + u8 pa_type_2g; + u8 pa_type_5g; + u8 lna_type_2g; + u8 lna_type_5g; + u8 external_pa_2g; + u8 external_lna_2g; + u8 external_pa_5g; + u8 external_lna_5g; + u8 type_glna; + u8 type_gpa; + u8 type_alna; + u8 type_apa; + u8 rfe_type; + + /*firmware */ + u32 fwsize; + u8 *pfirmware; + u16 fw_version; + u16 fw_subversion; + bool h2c_setinprogress; + u8 last_hmeboxnum; + bool fw_ready; + /*Reserve page start offset except beacon in TxQ. */ + u8 fw_rsvdpage_startoffset; + u8 h2c_txcmd_seq; + u8 current_ra_rate; + + /* FW Cmd IO related */ + u16 fwcmd_iomap; + u32 fwcmd_ioparam; + bool set_fwcmd_inprogress; + u8 current_fwcmd_io; + + struct p2p_ps_offload_t p2p_ps_offload; + bool fw_clk_change_in_progress; + bool allow_sw_to_change_hwclc; + u8 fw_ps_state; + /**/ + bool driver_going2unload; + + /*AMPDU init min space*/ + u8 minspace_cfg; /*For Min spacing configurations */ + + /* Dual mac */ + enum macphy_mode macphymode; + enum band_type current_bandtype; /* 0:2.4G, 1:5G */ + enum band_type current_bandtypebackup; + enum band_type bandset; + /* dual MAC 0--Mac0 1--Mac1 */ + u32 interfaceindex; + /* just for DualMac S3S4 */ + u8 macphyctl_reg; + bool earlymode_enable; + u8 max_earlymode_num; + /* Dual mac*/ + bool during_mac0init_radiob; + bool during_mac1init_radioa; + bool reloadtxpowerindex; + /* True if IMR or IQK have done + * for 2.4G in scan progress + */ + bool load_imrandiqk_setting_for2g; + + bool disable_amsdu_8k; + bool master_of_dmsp; + bool slave_of_dmsp; + + u16 rx_tag;/*for 92ee*/ + u8 rts_en; + + /*for wowlan*/ + bool wow_enable; + bool enter_pnp_sleep; + bool wake_from_pnp_sleep; + bool wow_enabled; + __kernel_time_t last_suspend_sec; + u32 wowlan_fwsize; + u8 *wowlan_firmware; + + u8 hw_rof_enable; /*Enable GPIO[9] as WL RF HW PDn source*/ + + bool real_wow_v2_enable; + bool re_init_llt_table; +}; + +struct rtl_security { + /*default 0 */ + bool use_sw_sec; + + bool being_setkey; + bool use_defaultkey; + /*Encryption Algorithm for Unicast Packet */ + enum rt_enc_alg pairwise_enc_algorithm; + /*Encryption Algorithm for Brocast/Multicast */ + enum rt_enc_alg group_enc_algorithm; + /*Cam Entry Bitmap */ + u32 hwsec_cam_bitmap; + u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN]; + /* local Key buffer, indx 0 is for + * pairwise key 1-4 is for agoup key. + */ + u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN]; + u8 key_len[KEY_BUF_SIZE]; + + /* The pointer of Pairwise Key, + * it always points to KeyBuf[4] + */ + u8 *pairwise_key; +}; + +#define ASSOCIATE_ENTRY_NUM 33 + +struct fast_ant_training { + u8 bssid[6]; + u8 antsel_rx_keep_0; + u8 antsel_rx_keep_1; + u8 antsel_rx_keep_2; + u32 ant_sum[7]; + u32 ant_cnt[7]; + u32 ant_ave[7]; + u8 fat_state; + u32 train_idx; + u8 antsel_a[ASSOCIATE_ENTRY_NUM]; + u8 antsel_b[ASSOCIATE_ENTRY_NUM]; + u8 antsel_c[ASSOCIATE_ENTRY_NUM]; + u32 main_ant_sum[ASSOCIATE_ENTRY_NUM]; + u32 aux_ant_sum[ASSOCIATE_ENTRY_NUM]; + u32 main_ant_cnt[ASSOCIATE_ENTRY_NUM]; + u32 aux_ant_cnt[ASSOCIATE_ENTRY_NUM]; + u8 rx_idle_ant; + bool becomelinked; +}; + +struct dm_phy_dbg_info { + s8 rx_snrdb[4]; + u64 num_qry_phy_status; + u64 num_qry_phy_status_cck; + u64 num_qry_phy_status_ofdm; + u16 num_qry_beacon_pkt; + u16 num_non_be_pkt; + s32 rx_evm[4]; +}; + +struct rtl_dm { + /*PHY status for Dynamic Management */ + long entry_min_undec_sm_pwdb; + long undec_sm_cck; + long undec_sm_pwdb; /*out dm */ + long entry_max_undec_sm_pwdb; + s32 ofdm_pkt_cnt; + bool dm_initialgain_enable; + bool dynamic_txpower_enable; + bool current_turbo_edca; + bool is_any_nonbepkts; /*out dm */ + bool is_cur_rdlstate; + bool txpower_trackinginit; + bool disable_framebursting; + bool cck_inch14; + bool txpower_tracking; + bool useramask; + bool rfpath_rxenable[4]; + bool inform_fw_driverctrldm; + bool current_mrc_switch; + u8 txpowercount; + u8 powerindex_backup[6]; + + u8 thermalvalue_rxgain; + u8 thermalvalue_iqk; + u8 thermalvalue_lck; + u8 thermalvalue; + u8 last_dtp_lvl; + u8 thermalvalue_avg[AVG_THERMAL_NUM]; + u8 thermalvalue_avg_index; + u8 tm_trigger; + bool done_txpower; + u8 dynamic_txhighpower_lvl; /*Tx high power level */ + u8 dm_flag; /*Indicate each dynamic mechanism's status. */ + u8 dm_flag_tmp; + u8 dm_type; + u8 dm_rssi_sel; + u8 txpower_track_control; + bool interrupt_migration; + bool disable_tx_int; + s8 ofdm_index[MAX_RF_PATH]; + u8 default_ofdm_index; + u8 default_cck_index; + s8 cck_index; + s8 delta_power_index[MAX_RF_PATH]; + s8 delta_power_index_last[MAX_RF_PATH]; + s8 power_index_offset[MAX_RF_PATH]; + s8 absolute_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_ofdm_swing_idx[MAX_RF_PATH]; + s8 remnant_cck_idx; + bool modify_txagc_flag_path_a; + bool modify_txagc_flag_path_b; + + bool one_entry_only; + struct dm_phy_dbg_info dbginfo; + + /* Dynamic ATC switch */ + bool atc_status; + bool large_cfo_hit; + bool is_freeze; + int cfo_tail[2]; + int cfo_ave_pre; + int crystal_cap; + u8 cfo_threshold; + u32 packet_count; + u32 packet_count_pre; + u8 tx_rate; + + /*88e tx power tracking*/ + u8 swing_idx_ofdm[MAX_RF_PATH]; + u8 swing_idx_ofdm_cur; + u8 swing_idx_ofdm_base[MAX_RF_PATH]; + bool swing_flag_ofdm; + u8 swing_idx_cck; + u8 swing_idx_cck_cur; + u8 swing_idx_cck_base; + bool swing_flag_cck; + + s8 swing_diff_2g; + s8 swing_diff_5g; + + /* DMSP */ + bool supp_phymode_switch; + + /* DulMac */ + struct fast_ant_training fat_table; + + u8 resp_tx_path; + u8 path_sel; + u32 patha_sum; + u32 pathb_sum; + u32 patha_cnt; + u32 pathb_cnt; + + u8 pre_channel; + u8 *p_channel; + u8 linked_interval; + + u64 last_tx_ok_cnt; + u64 last_rx_ok_cnt; +}; + +#define EFUSE_MAX_LOGICAL_SIZE 512 + +struct rtl_efuse { + bool autoload_ok; + bool bootfromefuse; + u16 max_physical_size; + + u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE]; + u16 efuse_usedbytes; + u8 efuse_usedpercentage; +#ifdef EFUSE_REPG_WORKAROUND + bool efuse_re_pg_sec1flag; + u8 efuse_re_pg_data[8]; +#endif + + u8 autoload_failflag; + u8 autoload_status; + + short epromtype; + u16 eeprom_vid; + u16 eeprom_did; + u16 eeprom_svid; + u16 eeprom_smid; + u8 eeprom_oemid; + u16 eeprom_channelplan; + u8 eeprom_version; + u8 board_type; + u8 external_pa; + + u8 dev_addr[6]; + u8 wowlan_enable; + u8 antenna_div_cfg; + u8 antenna_div_type; + + bool txpwr_fromeprom; + u8 eeprom_crystalcap; + u8 eeprom_tssi[2]; + u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */ + u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX]; + u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; + u8 eeprom_chnlarea_txpwr_cck[MAX_RF_PATH][CHANNEL_GROUP_MAX_2G]; + u8 eeprom_chnlarea_txpwr_ht40_1s[MAX_RF_PATH][CHANNEL_GROUP_MAX]; + u8 eprom_chnl_txpwr_ht40_2sdf[MAX_RF_PATH][CHANNEL_GROUP_MAX]; + + u8 internal_pa_5g[2]; /* pathA / pathB */ + u8 eeprom_c9; + u8 eeprom_cc; + + /*For power group */ + u8 eeprom_pwrgroup[2][3]; + u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER]; + u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER]; + + u8 txpwrlevel_cck[MAX_RF_PATH][CHANNEL_MAX_NUMBER_2G]; + /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_1s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + /*For HT 40MHZ pwr */ + u8 txpwrlevel_ht40_2s[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + + /*--------------------------------------------------------* + * 8192CE\8192SE\8192DE\8723AE use the following 4 arrays, + * other ICs (8188EE\8723BE\8192EE\8812AE...) + * define new arrays in Windows code. + * BUT, in linux code, we use the same array for all ICs. + * + * The Correspondance relation between two arrays is: + * txpwr_cckdiff[][] == CCK_24G_Diff[][] + * txpwr_ht20diff[][] == BW20_24G_Diff[][] + * txpwr_ht40diff[][] == BW40_24G_Diff[][] + * txpwr_legacyhtdiff[][] == OFDM_24G_Diff[][] + * + * Sizes of these arrays are decided by the larger ones. + */ + s8 txpwr_cckdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_ht20diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_ht40diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + s8 txpwr_legacyhtdiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + + u8 txpwr_5g_bw40base[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + u8 txpwr_5g_bw80base[MAX_RF_PATH][CHANNEL_MAX_NUMBER_5G_80M]; + s8 txpwr_5g_ofdmdiff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw20diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw40diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 txpwr_5g_bw80diff[MAX_RF_PATH][MAX_TX_COUNT]; + + u8 txpwr_safetyflag; /* Band edge enable flag */ + u16 eeprom_txpowerdiff; + u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */ + u8 antenna_txpwdiff[3]; + + u8 eeprom_regulatory; + u8 eeprom_thermalmeter; + u8 thermalmeter[2]; /*ThermalMeter, index 0 for RFIC0, 1 for RFIC1 */ + u16 tssi_13dbm; + u8 crystalcap; /* CrystalCap. */ + u8 delta_iqk; + u8 delta_lck; + + u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ + bool apk_thermalmeterignore; + + bool b1x1_recvcombine; + bool b1ss_support; + + /*channel plan */ + u8 channel_plan; +}; + +struct rtl_tx_report { + atomic_t sn; + u16 last_sent_sn; + unsigned long last_sent_time; + u16 last_recv_sn; +}; + +struct rtl_ps_ctl { + bool pwrdomain_protect; + bool in_powersavemode; + bool rfchange_inprogress; + bool swrf_processing; + bool hwradiooff; + /* just for PCIE ASPM + * If it supports ASPM, Offset[560h] = 0x40, + * otherwise Offset[560h] = 0x00. + */ + bool support_aspm; + bool support_backdoor; + + /*for LPS */ + enum rt_psmode dot11_psmode; /*Power save mode configured. */ + bool swctrl_lps; + bool leisure_ps; + bool fwctrl_lps; + u8 fwctrl_psmode; + /*For Fw control LPS mode */ + u8 reg_fwctrl_lps; + /*Record Fw PS mode status. */ + bool fw_current_inpsmode; + u8 reg_max_lps_awakeintvl; + bool report_linked; + bool low_power_enable;/*for 32k*/ + + /*for IPS */ + bool inactiveps; + + u32 rfoff_reason; + + /*RF OFF Level */ + u32 cur_ps_level; + u32 reg_rfps_level; + + /*just for PCIE ASPM */ + u8 const_amdpci_aspm; + bool pwrdown_mode; + + enum rf_pwrstate inactive_pwrstate; + enum rf_pwrstate rfpwr_state; /*cur power state */ + + /* for SW LPS*/ + bool sw_ps_enabled; + bool state; + bool state_inap; + bool multi_buffered; + u16 nullfunc_seq; + unsigned int dtim_counter; + unsigned int sleep_ms; + unsigned long last_sleep_jiffies; + unsigned long last_awake_jiffies; + unsigned long last_delaylps_stamp_jiffies; + unsigned long last_dtim; + unsigned long last_beacon; + unsigned long last_action; + unsigned long last_slept; + + /*For P2P PS */ + struct rtl_p2p_ps_info p2p_ps_info; + u8 pwr_mode; + u8 smart_ps; + + /* wake up on line */ + u8 wo_wlan_mode; + u8 arp_offload_enable; + u8 gtk_offload_enable; + /* Used for WOL, indicates the reason for waking event.*/ + u32 wakeup_reason; + /* Record the last waking time for comparison with setting key. */ + u64 last_wakeup_time; +}; + +struct rtl_stats { + u8 psaddr[ETH_ALEN]; + u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u8 rate; /* hw desc rate */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u64 tsf; + u32 beacon_time; + u8 nic_type; + u16 length; + u8 signalquality; /*in 0-100 index. */ + /* + * Real power in dBm for this packet, + * no beautification and aggregation. + */ + s32 recvsignalpower; + s8 rxpower; /*in dBm Translate from PWdB */ + u8 signalstrength; /*in 0-100 index. */ + u16 hwerror:1; + u16 crc:1; + u16 icv:1; + u16 shortpreamble:1; + u16 antenna:1; + u16 decrypted:1; + u16 wakeup:1; + u32 timestamp_low; + u32 timestamp_high; + bool shift; + + u8 rx_drvinfo_size; + u8 rx_bufshift; + bool isampdu; + bool isfirst_ampdu; + bool rx_is40mhzpacket; + u8 rx_packet_bw; + u32 rx_pwdb_all; + u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ + s8 rx_mimo_signalquality[4]; + u8 rx_mimo_evm_dbm[4]; + u16 cfo_short[4]; /* per-path's Cfo_short */ + u16 cfo_tail[4]; + + s8 rx_mimo_sig_qual[4]; + u8 rx_pwr[4]; /* per-path's pwdb */ + u8 rx_snr[4]; /* per-path's SNR */ + u8 bandwidth; + u8 bt_coex_pwr_adjust; + bool packet_matchbssid; + bool is_cck; + bool is_ht; + bool packet_toself; + bool packet_beacon; /*for rssi */ + s8 cck_adc_pwdb[4]; /*for rx path selection */ + + bool is_vht; + bool is_short_gi; + u8 vht_nss; + + u8 packet_report_type; + + u32 macid; + u8 wake_match; + u32 bt_rx_rssi_percentage; + u32 macid_valid_entry[2]; +}; + +struct rt_link_detect { + /* count for roaming */ + u32 bcn_rx_inperiod; + u32 roam_times; + + u32 num_tx_in4period[4]; + u32 num_rx_in4period[4]; + + u32 num_tx_inperiod; + u32 num_rx_inperiod; + + bool busytraffic; + bool tx_busy_traffic; + bool rx_busy_traffic; + bool higher_busytraffic; + bool higher_busyrxtraffic; + + u32 tidtx_in4period[MAX_TID_COUNT][4]; + u32 tidtx_inperiod[MAX_TID_COUNT]; + bool higher_busytxtraffic[MAX_TID_COUNT]; +}; + +struct rtl_tcb_desc { + u8 packet_bw:2; + u8 multicast:1; + u8 broadcast:1; + + u8 rts_stbc:1; + u8 rts_enable:1; + u8 cts_enable:1; + u8 rts_use_shortpreamble:1; + u8 rts_use_shortgi:1; + u8 rts_sc:1; + u8 rts_bw:1; + u8 rts_rate; + + u8 use_shortgi:1; + u8 use_shortpreamble:1; + u8 use_driver_rate:1; + u8 disable_ratefallback:1; + + u8 use_spe_rpt:1; + + u8 ratr_index; + u8 mac_id; + u8 hw_rate; + + u8 last_inipkt:1; + u8 cmd_or_init:1; + u8 queue_index; + + /* early mode */ + u8 empkt_num; + /* The max value by HW */ + u32 empkt_len[10]; + bool tx_enable_sw_calc_duration; +}; + +struct rtl_wow_pattern { + u8 type; + u16 crc; + u32 mask[4]; +}; + +struct rtl_hal_ops { + int (*init_sw_vars)(struct ieee80211_hw *hw); + void (*deinit_sw_vars)(struct ieee80211_hw *hw); + void (*read_chip_version)(struct ieee80211_hw *hw); + void (*read_eeprom_info)(struct ieee80211_hw *hw); + void (*interrupt_recognized)(struct ieee80211_hw *hw, + u32 *p_inta, u32 *p_intb, + u32 *p_intc, u32 *p_intd); + int (*hw_init)(struct ieee80211_hw *hw); + void (*hw_disable)(struct ieee80211_hw *hw); + void (*hw_suspend)(struct ieee80211_hw *hw); + void (*hw_resume)(struct ieee80211_hw *hw); + void (*enable_interrupt)(struct ieee80211_hw *hw); + void (*disable_interrupt)(struct ieee80211_hw *hw); + int (*set_network_type)(struct ieee80211_hw *hw, + enum nl80211_iftype type); + void (*set_chk_bssid)(struct ieee80211_hw *hw, + bool check_bssid); + void (*set_bw_mode)(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); + u8 (*switch_channel)(struct ieee80211_hw *hw); + void (*set_qos)(struct ieee80211_hw *hw, int aci); + void (*set_bcn_reg)(struct ieee80211_hw *hw); + void (*set_bcn_intv)(struct ieee80211_hw *hw); + void (*update_interrupt_mask)(struct ieee80211_hw *hw, + u32 add_msr, u32 rm_msr); + void (*get_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*set_hw_reg)(struct ieee80211_hw *hw, u8 variable, u8 *val); + void (*update_rate_tbl)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, u8 rssi_leve, + bool update_bw); + void (*pre_fill_tx_bd_desc)(struct ieee80211_hw *hw, u8 *tx_bd_desc, + u8 *desc, u8 queue_index, + struct sk_buff *skb, dma_addr_t addr); + void (*update_rate_mask)(struct ieee80211_hw *hw, u8 rssi_level); + u16 (*rx_desc_buff_remained_cnt)(struct ieee80211_hw *hw, + u8 queue_index); + void (*rx_check_dma_ok)(struct ieee80211_hw *hw, u8 *header_desc, + u8 queue_index); + void (*fill_tx_desc)(struct ieee80211_hw *hw, + struct ieee80211_hdr *hdr, u8 *pdesc_tx, + u8 *pbd_desc_tx, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta, + struct sk_buff *skb, u8 hw_queue, + struct rtl_tcb_desc *ptcb_desc); + void (*fill_fake_txdesc)(struct ieee80211_hw *hw, u8 *pdesc, + u32 buffer_len, bool bispspoll); + void (*fill_tx_cmddesc)(struct ieee80211_hw *hw, u8 *pdesc, + bool firstseg, bool lastseg, + struct sk_buff *skb); + void (*fill_tx_special_desc)(struct ieee80211_hw *hw, + u8 *pdesc, u8 *pbd_desc, + struct sk_buff *skb, u8 hw_queue); + bool (*query_rx_desc)(struct ieee80211_hw *hw, + struct rtl_stats *stats, + struct ieee80211_rx_status *rx_status, + u8 *pdesc, struct sk_buff *skb); + void (*set_channel_access)(struct ieee80211_hw *hw); + bool (*radio_onoff_checking)(struct ieee80211_hw *hw, u8 *valid); + void (*dm_watchdog)(struct ieee80211_hw *hw); + void (*scan_operation_backup)(struct ieee80211_hw *hw, u8 operation); + bool (*set_rf_power_state)(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); + void (*led_control)(struct ieee80211_hw *hw, + enum led_ctl_mode ledaction); + void (*set_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name, u8 *val); + u64 (*get_desc)(struct ieee80211_hw *hw, u8 *pdesc, bool istx, + u8 desc_name); + bool (*is_tx_desc_closed)(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); + void (*tx_polling)(struct ieee80211_hw *hw, u8 hw_queue); + void (*enable_hw_sec)(struct ieee80211_hw *hw); + void (*set_key)(struct ieee80211_hw *hw, u32 key_index, + u8 *macaddr, bool is_group, u8 enc_algo, + bool is_wepkey, bool clear_all); + void (*init_sw_leds)(struct ieee80211_hw *hw); + void (*deinit_sw_leds)(struct ieee80211_hw *hw); + u32 (*get_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); + void (*set_bbreg)(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, + u32 data); + u32 (*get_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask); + void (*set_rfreg)(struct ieee80211_hw *hw, enum radio_path rfpath, + u32 regaddr, u32 bitmask, u32 data); + void (*linked_set_reg)(struct ieee80211_hw *hw); + void (*chk_switch_dmdp)(struct ieee80211_hw *hw); + void (*dualmac_easy_concurrent)(struct ieee80211_hw *hw); + void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw); + bool (*phy_rf6052_config)(struct ieee80211_hw *hw); + void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw, + u8 *powerlevel); + void (*phy_rf6052_set_ofdm_txpower)(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); + bool (*config_bb_with_headerfile)(struct ieee80211_hw *hw, + u8 configtype); + bool (*config_bb_with_pgheaderfile)(struct ieee80211_hw *hw, + u8 configtype); + void (*phy_lc_calibrate)(struct ieee80211_hw *hw, bool is2t); + void (*phy_set_bw_mode_callback)(struct ieee80211_hw *hw); + void (*dm_dynamic_txpower)(struct ieee80211_hw *hw); + void (*c2h_command_handle)(struct ieee80211_hw *hw); + void (*bt_wifi_media_status_notify)(struct ieee80211_hw *hw, + bool mstate); + void (*bt_coex_off_before_lps)(struct ieee80211_hw *hw); + void (*fill_h2c_cmd)(struct ieee80211_hw *hw, u8 element_id, + u32 cmd_len, u8 *p_cmdbuffer); + void (*set_default_port_id_cmd)(struct ieee80211_hw *hw); + bool (*get_btc_status)(void); + bool (*is_fw_header)(struct rtlwifi_firmware_header *hdr); + u32 (*rx_command_packet)(struct ieee80211_hw *hw, + const struct rtl_stats *status, + struct sk_buff *skb); + void (*add_wowlan_pattern)(struct ieee80211_hw *hw, + struct rtl_wow_pattern *rtl_pattern, + u8 index); + u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx); + void (*c2h_content_parsing)(struct ieee80211_hw *hw, u8 tag, u8 len, + u8 *val); + /* ops for halmac cb */ + bool (*halmac_cb_init_mac_register)(struct rtl_priv *rtlpriv); + bool (*halmac_cb_init_bb_rf_register)(struct rtl_priv *rtlpriv); + bool (*halmac_cb_write_data_rsvd_page)(struct rtl_priv *rtlpriv, + u8 *buf, u32 size); + bool (*halmac_cb_write_data_h2c)(struct rtl_priv *rtlpriv, u8 *buf, + u32 size); + /* ops for phydm cb */ + u8 (*get_txpower_index)(struct ieee80211_hw *hw, u8 path, + u8 rate, u8 bandwidth, u8 channel); + void (*set_tx_power_index_by_rs)(struct ieee80211_hw *hw, + u8 channel, u8 path, + enum rate_section rs); + void (*store_tx_power_by_rate)(struct ieee80211_hw *hw, + u32 band, u32 rfpath, + u32 txnum, u32 regaddr, + u32 bitmask, u32 data); + void (*phy_set_txpower_limit)(struct ieee80211_hw *hw, u8 *pregulation, + u8 *pband, u8 *pbandwidth, + u8 *prate_section, u8 *prf_path, + u8 *pchannel, u8 *ppower_limit); +}; + +struct rtl_intf_ops { + /*com */ + void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); + int (*adapter_start)(struct ieee80211_hw *hw); + void (*adapter_stop)(struct ieee80211_hw *hw); + bool (*check_buddy_priv)(struct ieee80211_hw *hw, + struct rtl_priv **buddy_priv); + + int (*adapter_tx)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb, + struct rtl_tcb_desc *ptcb_desc); + void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); + int (*reset_trx_ring)(struct ieee80211_hw *hw); + bool (*waitq_insert)(struct ieee80211_hw *hw, + struct ieee80211_sta *sta, + struct sk_buff *skb); + + /*pci */ + void (*disable_aspm)(struct ieee80211_hw *hw); + void (*enable_aspm)(struct ieee80211_hw *hw); + + /*usb */ +}; + +struct rtl_mod_params { + /* default: 0,0 */ + u64 debug_mask; + /* default: 0 = using hardware encryption */ + bool sw_crypto; + + /* default: 0 = DBG_EMERG (0)*/ + int debug_level; + + /* default: 1 = using no linked power save */ + bool inactiveps; + + /* default: 1 = using linked sw power save */ + bool swctrl_lps; + + /* default: 1 = using linked fw power save */ + bool fwctrl_lps; + + /* default: 0 = not using MSI interrupts mode + * submodules should set their own default value + */ + bool msi_support; + + /* default: 0 = dma 32 */ + bool dma64; + + /* default: 1 = enable aspm */ + int aspm_support; + + /* default 0: 1 means disable */ + bool disable_watchdog; + + /* default 0: 1 means do not disable interrupts */ + bool int_clear; + + /* select antenna */ + int ant_sel; +}; + +struct rtl_hal_usbint_cfg { + /* data - rx */ + u32 in_ep_num; + u32 rx_urb_num; + u32 rx_max_size; + + /* op - rx */ + void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); + void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, + struct sk_buff_head *); + + /* tx */ + void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); + int (*usb_tx_post_hdl)(struct ieee80211_hw *, struct urb *, + struct sk_buff *); + struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, + struct sk_buff_head *); + + /* endpoint mapping */ + int (*usb_endpoint_mapping)(struct ieee80211_hw *hw); + u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); +}; + +struct rtl_hal_cfg { + u8 bar_id; + bool write_readback; + char *name; + char *alt_fw_name; + struct rtl_hal_ops *ops; + struct rtl_mod_params *mod_params; + struct rtl_hal_usbint_cfg *usb_interface_cfg; + enum rtl_spec_ver spec_ver; + + /* this map used for some registers or vars + * defined int HAL but used in MAIN + */ + u32 maps[RTL_VAR_MAP_MAX]; + +}; + +struct rtl_locks { + /* mutex */ + struct mutex conf_mutex; + struct mutex ips_mutex; /* mutex for enter/leave IPS */ + struct mutex lps_mutex; /* mutex for enter/leave LPS */ + + /*spin lock */ + spinlock_t irq_th_lock; + spinlock_t h2c_lock; + spinlock_t rf_ps_lock; + spinlock_t rf_lock; + spinlock_t waitq_lock; + spinlock_t entry_list_lock; + spinlock_t usb_lock; + spinlock_t c2hcmd_lock; + spinlock_t scan_list_lock; /* lock for the scan list */ + + /*FW clock change */ + spinlock_t fw_ps_lock; + + /*Dual mac*/ + spinlock_t cck_and_rw_pagea_lock; + + spinlock_t iqk_lock; +}; + +struct rtl_works { + struct ieee80211_hw *hw; + + /*timer */ + struct timer_list watchdog_timer; + struct timer_list dualmac_easyconcurrent_retrytimer; + struct timer_list fw_clockoff_timer; + struct timer_list fast_antenna_training_timer; + /*task */ + struct tasklet_struct irq_tasklet; + struct tasklet_struct irq_prepare_bcn_tasklet; + + /*work queue */ + struct workqueue_struct *rtl_wq; + struct delayed_work watchdog_wq; + struct delayed_work ips_nic_off_wq; + struct delayed_work c2hcmd_wq; + + /* For SW LPS */ + struct delayed_work ps_work; + struct delayed_work ps_rfon_wq; + struct delayed_work fwevt_wq; + + struct work_struct lps_change_work; + struct work_struct fill_h2c_cmd; +}; + +struct rtl_debug { + /* add for debug */ + struct dentry *debugfs_dir; + char debugfs_name[20]; + + char *msg_buf; +}; + +#define MIMO_PS_STATIC 0 +#define MIMO_PS_DYNAMIC 1 +#define MIMO_PS_NOLIMIT 3 + +struct rtl_dualmac_easy_concurrent_ctl { + enum band_type currentbandtype_backfordmdp; + bool close_bbandrf_for_dmsp; + bool change_to_dmdp; + bool change_to_dmsp; + bool switch_in_process; +}; + +struct rtl_dmsp_ctl { + bool activescan_for_slaveofdmsp; + bool scan_for_anothermac_fordmsp; + bool scan_for_itself_fordmsp; + bool writedig_for_anothermacofdmsp; + u32 curdigvalue_for_anothermacofdmsp; + bool changecckpdstate_for_anothermacofdmsp; + u8 curcckpdstate_for_anothermacofdmsp; + bool changetxhighpowerlvl_for_anothermacofdmsp; + u8 curtxhighlvl_for_anothermacofdmsp; + long rssivalmin_for_anothermacofdmsp; +}; + +struct ps_t { + u8 pre_ccastate; + u8 cur_ccasate; + u8 pre_rfstate; + u8 cur_rfstate; + u8 initialize; + long rssi_val_min; +}; + +struct dig_t { + u32 rssi_lowthresh; + u32 rssi_highthresh; + u32 fa_lowthresh; + u32 fa_highthresh; + long last_min_undec_pwdb_for_dm; + long rssi_highpower_lowthresh; + long rssi_highpower_highthresh; + u32 recover_cnt; + u32 pre_igvalue; + u32 cur_igvalue; + long rssi_val; + u8 dig_enable_flag; + u8 dig_ext_port_stage; + u8 dig_algorithm; + u8 dig_twoport_algorithm; + u8 dig_dbgmode; + u8 dig_slgorithm_switch; + u8 cursta_cstate; + u8 presta_cstate; + u8 curmultista_cstate; + u8 stop_dig; + s8 back_val; + s8 back_range_max; + s8 back_range_min; + u8 rx_gain_max; + u8 rx_gain_min; + u8 min_undec_pwdb_for_dm; + u8 rssi_val_min; + u8 pre_cck_cca_thres; + u8 cur_cck_cca_thres; + u8 pre_cck_pd_state; + u8 cur_cck_pd_state; + u8 pre_cck_fa_state; + u8 cur_cck_fa_state; + u8 pre_ccastate; + u8 cur_ccasate; + u8 large_fa_hit; + u8 forbidden_igi; + u8 dig_state; + u8 dig_highpwrstate; + u8 cur_sta_cstate; + u8 pre_sta_cstate; + u8 cur_ap_cstate; + u8 pre_ap_cstate; + u8 cur_pd_thstate; + u8 pre_pd_thstate; + u8 cur_cs_ratiostate; + u8 pre_cs_ratiostate; + u8 backoff_enable_flag; + s8 backoffval_range_max; + s8 backoffval_range_min; + u8 dig_min_0; + u8 dig_min_1; + u8 bt30_cur_igi; + bool media_connect_0; + bool media_connect_1; + + u32 antdiv_rssi_max; + u32 rssi_max; +}; + +struct rtl_global_var { + /* from this list we can get + * other adapter's rtl_priv + */ + struct list_head glb_priv_list; + spinlock_t glb_list_lock; +}; + +#define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */ + +struct rtl_btc_info { + u8 bt_type; + u8 btcoexist; + u8 ant_num; + u8 single_ant_path; + + u8 ap_num; + bool in_4way; + unsigned long in_4way_ts; +}; + +struct bt_coexist_info { + struct rtl_btc_ops *btc_ops; + struct rtl_btc_info btc_info; + /* btc context */ + void *btc_context; + void *wifi_only_context; + /* EEPROM BT info. */ + u8 eeprom_bt_coexist; + u8 eeprom_bt_type; + u8 eeprom_bt_ant_num; + u8 eeprom_bt_ant_isol; + u8 eeprom_bt_radio_shared; + + u8 bt_coexistence; + u8 bt_ant_num; + u8 bt_coexist_type; + u8 bt_state; + u8 bt_cur_state; /* 0:on, 1:off */ + u8 bt_ant_isolation; /* 0:good, 1:bad */ + u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */ + u8 bt_service; + u8 bt_radio_shared_type; + u8 bt_rfreg_origin_1e; + u8 bt_rfreg_origin_1f; + u8 bt_rssi_state; + u32 ratio_tx; + u32 ratio_pri; + u32 bt_edca_ul; + u32 bt_edca_dl; + + bool init_set; + bool bt_busy_traffic; + bool bt_traffic_mode_set; + bool bt_non_traffic_mode_set; + + bool fw_coexist_all_off; + bool sw_coexist_all_off; + bool hw_coexist_all_off; + u32 cstate; + u32 previous_state; + u32 cstate_h; + u32 previous_state_h; + + u8 bt_pre_rssi_state; + u8 bt_pre_rssi_state1; + + u8 reg_bt_iso; + u8 reg_bt_sco; + bool balance_on; + u8 bt_active_zero_cnt; + bool cur_bt_disabled; + bool pre_bt_disabled; + + u8 bt_profile_case; + u8 bt_profile_action; + bool bt_busy; + bool hold_for_bt_operation; + u8 lps_counter; +}; + +struct rtl_btc_ops { + void (*btc_init_variables)(struct rtl_priv *rtlpriv); + void (*btc_init_variables_wifi_only)(struct rtl_priv *rtlpriv); + void (*btc_deinit_variables)(struct rtl_priv *rtlpriv); + void (*btc_init_hal_vars)(struct rtl_priv *rtlpriv); + void (*btc_power_on_setting)(struct rtl_priv *rtlpriv); + void (*btc_init_hw_config)(struct rtl_priv *rtlpriv); + void (*btc_init_hw_config_wifi_only)(struct rtl_priv *rtlpriv); + void (*btc_ips_notify)(struct rtl_priv *rtlpriv, u8 type); + void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type); + void (*btc_scan_notify)(struct rtl_priv *rtlpriv, u8 scantype); + void (*btc_scan_notify_wifi_only)(struct rtl_priv *rtlpriv, + u8 scantype); + void (*btc_connect_notify)(struct rtl_priv *rtlpriv, u8 action); + void (*btc_mediastatus_notify)(struct rtl_priv *rtlpriv, + enum rt_media_status mstatus); + void (*btc_periodical)(struct rtl_priv *rtlpriv); + void (*btc_halt_notify)(struct rtl_priv *rtlpriv); + void (*btc_btinfo_notify)(struct rtl_priv *rtlpriv, + u8 *tmp_buf, u8 length); + void (*btc_btmpinfo_notify)(struct rtl_priv *rtlpriv, + u8 *tmp_buf, u8 length); + bool (*btc_is_limited_dig)(struct rtl_priv *rtlpriv); + bool (*btc_is_disable_edca_turbo)(struct rtl_priv *rtlpriv); + bool (*btc_is_bt_disabled)(struct rtl_priv *rtlpriv); + void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv, + u8 pkt_type); + void (*btc_switch_band_notify)(struct rtl_priv *rtlpriv, u8 type, + bool scanning); + void (*btc_switch_band_notify_wifi_only)(struct rtl_priv *rtlpriv, + u8 type, bool scanning); + void (*btc_display_bt_coex_info)(struct rtl_priv *rtlpriv, + struct seq_file *m); + void (*btc_record_pwr_mode)(struct rtl_priv *rtlpriv, u8 *buf, u8 len); + u8 (*btc_get_lps_val)(struct rtl_priv *rtlpriv); + u8 (*btc_get_rpwm_val)(struct rtl_priv *rtlpriv); + bool (*btc_is_bt_ctrl_lps)(struct rtl_priv *rtlpriv); + void (*btc_get_ampdu_cfg)(struct rtl_priv *rtlpriv, u8 *reject_agg, + u8 *ctrl_agg_size, u8 *agg_size); + bool (*btc_is_bt_lps_on)(struct rtl_priv *rtlpriv); +}; + +struct rtl_halmac_ops { + int (*halmac_init_adapter)(struct rtl_priv *); + int (*halmac_deinit_adapter)(struct rtl_priv *); + int (*halmac_init_hal)(struct rtl_priv *); + int (*halmac_deinit_hal)(struct rtl_priv *); + int (*halmac_poweron)(struct rtl_priv *); + int (*halmac_poweroff)(struct rtl_priv *); + + int (*halmac_phy_power_switch)(struct rtl_priv *rtlpriv, u8 enable); + int (*halmac_set_mac_address)(struct rtl_priv *rtlpriv, u8 hwport, + u8 *addr); + int (*halmac_set_bssid)(struct rtl_priv *rtlpriv, u8 hwport, u8 *addr); + + int (*halmac_get_physical_efuse_size)(struct rtl_priv *rtlpriv, + u32 *size); + int (*halmac_read_physical_efuse_map)(struct rtl_priv *rtlpriv, + u8 *map, u32 size); + int (*halmac_get_logical_efuse_size)(struct rtl_priv *rtlpriv, + u32 *size); + int (*halmac_read_logical_efuse_map)(struct rtl_priv *rtlpriv, u8 *map, + u32 size); + + int (*halmac_set_bandwidth)(struct rtl_priv *rtlpriv, u8 channel, + u8 pri_ch_idx, u8 bw); + + int (*halmac_c2h_handle)(struct rtl_priv *rtlpriv, u8 *c2h, u32 size); + + int (*halmac_chk_txdesc)(struct rtl_priv *rtlpriv, u8 *txdesc, + u32 size); +}; + +struct rtl_halmac_indicator { + struct completion *comp; + u32 wait_ms; + + u8 *buffer; + u32 buf_size; + u32 ret_size; + u32 status; +}; + +struct rtl_halmac { + struct rtl_halmac_ops *ops; /* halmac ops (halmac.ko own this object) */ + void *internal; /* internal context of halmac, i.e. PHALMAC_ADAPTER */ + struct rtl_halmac_indicator *indicator; /* size=10 */ + + /* flags */ + /* + * send_general_info + * 0: no need to call halmac_send_general_info() + * 1: need to call halmac_send_general_info() + */ + u8 send_general_info; +}; + +struct rtl_phydm_params { + u8 mp_chip; /* 1: MP chip, 0: test chip */ + u8 fab_ver; /* 0: TSMC, 1: UMC, ...*/ + u8 cut_ver; /* 0: A, 1: B, ..., 10: K */ + u8 efuse0x3d7; /* default: 0xff */ + u8 efuse0x3d8; /* default: 0xff */ +}; + +struct rtl_phydm_ops { + /* init/deinit priv */ + int (*phydm_init_priv)(struct rtl_priv *rtlpriv, + struct rtl_phydm_params *params); + int (*phydm_deinit_priv)(struct rtl_priv *rtlpriv); + bool (*phydm_load_txpower_by_rate)(struct rtl_priv *rtlpriv); + bool (*phydm_load_txpower_limit)(struct rtl_priv *rtlpriv); + + /* init hw */ + int (*phydm_init_dm)(struct rtl_priv *rtlpriv); + int (*phydm_deinit_dm)(struct rtl_priv *rtlpriv); + int (*phydm_reset_dm)(struct rtl_priv *rtlpriv); + bool (*phydm_parameter_init)(struct rtl_priv *rtlpriv, bool post); + bool (*phydm_phy_bb_config)(struct rtl_priv *rtlpriv); + bool (*phydm_phy_rf_config)(struct rtl_priv *rtlpriv); + bool (*phydm_phy_mac_config)(struct rtl_priv *rtlpriv); + bool (*phydm_trx_mode)(struct rtl_priv *rtlpriv, + enum radio_mask tx_path, enum radio_mask rx_path, + bool is_tx2_path); + /* watchdog */ + bool (*phydm_watchdog)(struct rtl_priv *rtlpriv); + + /* channel */ + bool (*phydm_switch_band)(struct rtl_priv *rtlpriv, u8 central_ch); + bool (*phydm_switch_channel)(struct rtl_priv *rtlpriv, u8 central_ch); + bool (*phydm_switch_bandwidth)(struct rtl_priv *rtlpriv, + u8 primary_ch_idx, + enum ht_channel_width width); + bool (*phydm_iq_calibrate)(struct rtl_priv *rtlpriv); + bool (*phydm_clear_txpowertracking_state)(struct rtl_priv *rtlpriv); + bool (*phydm_pause_dig)(struct rtl_priv *rtlpriv, bool pause); + + /* read/write reg */ + u32 (*phydm_read_rf_reg)(struct rtl_priv *rtlpriv, + enum radio_path rfpath, + u32 addr, u32 mask); + bool (*phydm_write_rf_reg)(struct rtl_priv *rtlpriv, + enum radio_path rfpath, + u32 addr, u32 mask, u32 data); + u8 (*phydm_read_txagc)(struct rtl_priv *rtlpriv, + enum radio_path rfpath, u8 hw_rate); + bool (*phydm_write_txagc)(struct rtl_priv *rtlpriv, u32 power_index, + enum radio_path rfpath, u8 hw_rate); + + /* RX */ + bool (*phydm_c2h_content_parsing)(struct rtl_priv *rtlpriv, u8 cmd_id, + u8 cmd_len, u8 *content); + bool (*phydm_query_phy_status)(struct rtl_priv *rtlpriv, u8 *phystrpt, + struct ieee80211_hdr *hdr, + struct rtl_stats *pstatus); + + /* TX */ + u8 (*phydm_rate_id_mapping)(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw); + bool (*phydm_get_ra_bitmap)(struct rtl_priv *rtlpriv, + enum wireless_mode wireless_mode, + enum rf_type rf_type, + enum ht_channel_width bw, + u8 tx_rate_level, /* 0~6 */ + u32 *tx_bitmap_msb, + u32 *tx_bitmap_lsb); + + /* STA */ + bool (*phydm_add_sta)(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta); + bool (*phydm_del_sta)(struct rtl_priv *rtlpriv, + struct ieee80211_sta *sta); + + /* BTC */ + u32 (*phydm_get_version)(struct rtl_priv *rtlpriv); + bool (*phydm_modify_ra_pcr_threshold)(struct rtl_priv *rtlpriv, + u8 ra_offset_direction, + u8 ra_threshold_offset); + u32 (*phydm_query_counter)(struct rtl_priv *rtlpriv, + const char *info_type); + + /* debug */ + bool (*phydm_debug_cmd)(struct rtl_priv *rtlpriv, char *in, u32 in_len, + char *out, u32 out_len); + +}; + +struct rtl_phydm { + struct rtl_phydm_ops *ops;/* phydm ops (phydm_mod.ko own this object) */ + void *internal; /* internal context of phydm, i.e. PHY_DM_STRUCT */ + + u8 adaptivity_en; + /* debug */ + u16 forced_data_rate; + u8 forced_igi_lb; + u8 antenna_test; +}; + +struct proxim { + bool proxim_on; + + void *proximity_priv; + int (*proxim_rx)(struct ieee80211_hw *hw, struct rtl_stats *status, + struct sk_buff *skb); + u8 (*proxim_get_var)(struct ieee80211_hw *hw, u8 type); +}; + +struct rtl_c2hcmd { + struct list_head list; + u8 tag; + u8 len; + u8 *val; +}; + +struct rtl_bssid_entry { + struct list_head list; + u8 bssid[ETH_ALEN]; + u32 age; +}; + +struct rtl_scan_list { + int num; + struct list_head list; /* sort by age */ +}; + +struct rtl_priv { + struct ieee80211_hw *hw; + struct completion firmware_loading_complete; + struct list_head list; + struct rtl_priv *buddy_priv; + struct rtl_global_var *glb_var; + struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl; + struct rtl_dmsp_ctl dmsp_ctl; + struct rtl_locks locks; + struct rtl_works works; + struct rtl_mac mac80211; + struct rtl_hal rtlhal; + struct rtl_regulatory regd; + struct rtl_rfkill rfkill; + struct rtl_io io; + struct rtl_phy phy; + struct rtl_dm dm; + struct rtl_security sec; + struct rtl_efuse efuse; + struct rtl_led_ctl ledctl; + struct rtl_tx_report tx_report; + struct rtl_scan_list scan_list; + struct rtl_ps_ctl psc; + struct rate_adaptive ra; + struct dynamic_primary_cca primarycca; + struct wireless_stats stats; + struct rt_link_detect link_info; + struct false_alarm_statistics falsealm_cnt; + struct rtl_rate_priv *rate_priv; + /* sta entry list for ap adhoc or mesh */ + struct list_head entry_list; + /* c2hcmd list for kthread level access */ + struct list_head c2hcmd_list; + struct rtl_debug dbg; + int max_fw_size; + + /*hal_cfg : for diff cards + *intf_ops : for diff interface usb/pcie + */ + struct rtl_hal_cfg *cfg; + const struct rtl_intf_ops *intf_ops; + + /* this var will be set by set_bit, + * and was used to indicate status of + * interface or hardware + */ + unsigned long status; + + /* tables for dm */ + struct dig_t dm_digtable; + struct ps_t dm_pstable; + + u32 reg_874; + u32 reg_c70; + u32 reg_85c; + u32 reg_a74; + bool reg_init; /* true if regs saved */ + bool bt_operation_on; + __le32 *usb_data; + int usb_data_index; + bool initialized; + bool enter_ps; /* true when entering PS */ + u8 rate_mask[5]; + + /* intel Proximity, should be alloc mem + * in intel Proximity module and can only + * be used in intel Proximity mode + */ + struct proxim proximity; + + /*for bt coexist use*/ + struct bt_coexist_info btcoexist; + + /* halmac for newer IC. (e.g. 8822B) */ + struct rtl_halmac halmac; + + /* phydm for newer IC. (e.g. 8822B) */ + struct rtl_phydm phydm; + + /* separate 92ee from other ICs, + * 92ee use new trx flow. + */ + bool use_new_trx_flow; + +#ifdef CONFIG_PM + struct wiphy_wowlan_support wowlan; +#endif + /* This must be the last item so + * that it points to the data allocated + * beyond this structure like: + * rtl_pci_priv or rtl_usb_priv + */ + u8 priv[0] __aligned(sizeof(void *)); +}; + +#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) +#define rtl_mac(rtlpriv) (&((rtlpriv)->mac80211)) +#define rtl_hal(rtlpriv) (&((rtlpriv)->rtlhal)) +#define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) +#define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) + +/*************************************** + * Bluetooth Co-existence Related + ***************************************/ + +enum bt_ant_num { + ANT_X2 = 0, + ANT_X1 = 1, +}; + +enum bt_co_type { + BT_2WIRE = 0, + BT_ISSC_3WIRE = 1, + BT_ACCEL = 2, + BT_CSR_BC4 = 3, + BT_CSR_BC8 = 4, + BT_RTL8756 = 5, + BT_RTL8723A = 6, + BT_RTL8821A = 7, + BT_RTL8723B = 8, + BT_RTL8192E = 9, + BT_RTL8812A = 11, + BT_RTL8822B = 12, +}; + +enum bt_total_ant_num { + ANT_TOTAL_X2 = 0, + ANT_TOTAL_X1 = 1 +}; + +enum bt_cur_state { + BT_OFF = 0, + BT_ON = 1, +}; + +enum bt_service_type { + BT_SCO = 0, + BT_A2DP = 1, + BT_HID = 2, + BT_HID_IDLE = 3, + BT_SCAN = 4, + BT_IDLE = 5, + BT_OTHER_ACTION = 6, + BT_BUSY = 7, + BT_OTHERBUSY = 8, + BT_PAN = 9, +}; + +enum bt_radio_shared { + BT_RADIO_SHARED = 0, + BT_RADIO_INDIVIDUAL = 1, +}; + +/**************************************** + * mem access macro define start + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. + ***************************************/ +/* Convert little data endian to host ordering */ +#define EF1BYTE(_val) \ + ((u8)(_val)) +#define EF2BYTE(_val) \ + (le16_to_cpu(_val)) +#define EF4BYTE(_val) \ + (le32_to_cpu(_val)) + +/* Read data from memory */ +#define READEF1BYTE(_ptr) \ + EF1BYTE(*((u8 *)(_ptr))) +/* Read le16 data from memory and convert to host ordering */ +#define READEF2BYTE(_ptr) \ + EF2BYTE(*(_ptr)) +#define READEF4BYTE(_ptr) \ + EF4BYTE(*(_ptr)) + +/* Create a bit mask + * Examples: + * BIT_LEN_MASK_32(0) => 0x00000000 + * BIT_LEN_MASK_32(1) => 0x00000001 + * BIT_LEN_MASK_32(2) => 0x00000003 + * BIT_LEN_MASK_32(32) => 0xFFFFFFFF + */ +#define BIT_LEN_MASK_32(__bitlen) \ + (0xFFFFFFFF >> (32 - (__bitlen))) +#define BIT_LEN_MASK_16(__bitlen) \ + (0xFFFF >> (16 - (__bitlen))) +#define BIT_LEN_MASK_8(__bitlen) \ + (0xFF >> (8 - (__bitlen))) + +/* Create an offset bit mask + * Examples: + * BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 + * BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 + */ +#define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) +#define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_16(__bitlen) << (__bitoffset)) +#define BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen) \ + (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) + +/*Description: + * Return 4-byte value in host byte ordering from + * 4-byte pointer in little-endian system. + */ +#define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ + (EF4BYTE(*((__le32 *)(__pstart)))) +#define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ + (EF2BYTE(*((__le16 *)(__pstart)))) +#define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ + (EF1BYTE(*((u8 *)(__pstart)))) + +/* Description: + * Translate subfield (continuous bits in little-endian) of 4-byte + * value to host byte ordering. + */ +#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_32(__bitlen) \ + ) +#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_16(__bitlen) \ + ) +#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ + BIT_LEN_MASK_8(__bitlen) \ + ) + +/* Description: + * Mask subfield (continuous bits in little-endian) of 4-byte value + * and return the result in 4-byte value in host byte ordering. + */ +#define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen)) \ + ) +#define LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen)) \ + ) +#define LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pstart) & \ + (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \ + ) + +/* Description: + * Set subfield of little-endian 4-byte value to specified value. + */ +#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ + (*((__le32 *)(__pstart)) = \ + cpu_to_le32( \ + LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ + )) +#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ + (*((__le16 *)(__pstart)) = \ + cpu_to_le16( \ + LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ + )) +#define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ + (*((u8 *)(__pstart)) = EF1BYTE \ + ( \ + LE_BITS_CLEARED_TO_1BYTE(__pstart, __bitoffset, __bitlen) | \ + ((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \ + )) + +#define N_BYTE_ALIGNMENT(__value, __alignment) ((__alignment == 1) ? \ + (__value) : (((__value + __alignment - 1) / \ + __alignment) * __alignment)) + +/**************************************** + * mem access macro define end + ****************************************/ + +#define byte(x, n) ((x >> (8 * n)) & 0xff) + +#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) +#define RTL_WATCH_DOG_TIME 2000 +#define MSECS(t) msecs_to_jiffies(t) +#define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA) +#define rtl_dm(rtlpriv) (&((rtlpriv)->dm)) + +#define RT_RF_OFF_LEVL_ASPM BIT(0) /*PCI ASPM */ +#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) /*PCI clock request */ +#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) /*PCI D3 mode */ +/*NIC halt, re-initialize hw parameters*/ +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) +#define RT_RF_OFF_LEVL_FREE_FW BIT(4) /*FW free, re-download the FW */ +#define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */ +/*Always enable ASPM and Clock Req in initialization.*/ +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) +/* no matter RFOFF or SLEEP we set PS_ASPM_LEVL*/ +#define RT_PS_LEVEL_ASPM BIT(7) +/*When LPS is on, disable 2R if no packet is received or transmitted.*/ +#define RT_RF_LPS_DISALBE_2R BIT(30) +#define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */ +#define RT_IN_PS_LEVEL(ppsc, _ps_flg) \ + ((ppsc->cur_ps_level & _ps_flg) ? true : false) +#define RT_CLEAR_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level &= (~(_ps_flg))) +#define RT_SET_PS_LEVEL(ppsc, _ps_flg) \ + (ppsc->cur_ps_level |= _ps_flg) + +#define container_of_dwork_rtl(x, y, z) \ + container_of(to_delayed_work(x), y, z) + +#define FILL_OCTET_STRING(_os, _octet, _len) \ + (_os).octet = (u8 *)(_octet); \ + (_os).length = (_len) + +#define CP_MACADDR(des, src) \ + ((des)[0] = (src)[0], (des)[1] = (src)[1],\ + (des)[2] = (src)[2], (des)[3] = (src)[3],\ + (des)[4] = (src)[4], (des)[5] = (src)[5]) + +#define LDPC_HT_ENABLE_RX BIT(0) +#define LDPC_HT_ENABLE_TX BIT(1) +#define LDPC_HT_TEST_TX_ENABLE BIT(2) +#define LDPC_HT_CAP_TX BIT(3) + +#define STBC_HT_ENABLE_RX BIT(0) +#define STBC_HT_ENABLE_TX BIT(1) +#define STBC_HT_TEST_TX_ENABLE BIT(2) +#define STBC_HT_CAP_TX BIT(3) + +#define LDPC_VHT_ENABLE_RX BIT(0) +#define LDPC_VHT_ENABLE_TX BIT(1) +#define LDPC_VHT_TEST_TX_ENABLE BIT(2) +#define LDPC_VHT_CAP_TX BIT(3) + +#define STBC_VHT_ENABLE_RX BIT(0) +#define STBC_VHT_ENABLE_TX BIT(1) +#define STBC_VHT_TEST_TX_ENABLE BIT(2) +#define STBC_VHT_CAP_TX BIT(3) + +extern u8 channel5g[CHANNEL_MAX_NUMBER_5G]; + +extern u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M]; + +static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read8_sync(rtlpriv, addr); +} + +static inline u16 rtl_read_word(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read16_sync(rtlpriv, addr); +} + +static inline u32 rtl_read_dword(struct rtl_priv *rtlpriv, u32 addr) +{ + return rtlpriv->io.read32_sync(rtlpriv, addr); +} + +static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8) +{ + rtlpriv->io.write8_async(rtlpriv, addr, val8); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read8_sync(rtlpriv, addr); +} + +static inline void rtl_write_byte_with_val32(struct ieee80211_hw *hw, + u32 addr, u32 val8) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + + rtl_write_byte(rtlpriv, addr, (u8)val8); +} + +static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16) +{ + rtlpriv->io.write16_async(rtlpriv, addr, val16); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read16_sync(rtlpriv, addr); +} + +static inline void rtl_write_dword(struct rtl_priv *rtlpriv, + u32 addr, u32 val32) +{ + rtlpriv->io.write32_async(rtlpriv, addr, val32); + + if (rtlpriv->cfg->write_readback) + rtlpriv->io.read32_sync(rtlpriv, addr); +} + +static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask) +{ + struct rtl_priv *rtlpriv = hw->priv; + + return rtlpriv->cfg->ops->get_bbreg(hw, regaddr, bitmask); +} + +static inline void rtl_set_bbreg(struct ieee80211_hw *hw, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = hw->priv; + + rtlpriv->cfg->ops->set_bbreg(hw, regaddr, bitmask, data); +} + +static inline void rtl_set_bbreg_with_dwmask(struct ieee80211_hw *hw, + u32 regaddr, u32 data) +{ + rtl_set_bbreg(hw, regaddr, 0xffffffff, data); +} + +static inline u32 rtl_get_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask) +{ + struct rtl_priv *rtlpriv = hw->priv; + + return rtlpriv->cfg->ops->get_rfreg(hw, rfpath, regaddr, bitmask); +} + +static inline void rtl_set_rfreg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data) +{ + struct rtl_priv *rtlpriv = hw->priv; + + rtlpriv->cfg->ops->set_rfreg(hw, rfpath, regaddr, bitmask, data); +} + +static inline bool is_hal_stop(struct rtl_hal *rtlhal) +{ + return (rtlhal->state == _HAL_STATE_STOP); +} + +static inline void set_hal_start(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_START; +} + +static inline void set_hal_stop(struct rtl_hal *rtlhal) +{ + rtlhal->state = _HAL_STATE_STOP; +} + +static inline u8 get_rf_type(struct rtl_phy *rtlphy) +{ + return rtlphy->rf_type; +} + +static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb) +{ + return (struct ieee80211_hdr *)(skb->data); +} + +static inline __le16 rtl_get_fc(struct sk_buff *skb) +{ + return rtl_get_hdr(skb)->frame_control; +} + +static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr) +{ + return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; +} + +static inline u16 rtl_get_tid(struct sk_buff *skb) +{ + return rtl_get_tid_h(rtl_get_hdr(skb)); +} + +static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const u8 *bssid) +{ + return ieee80211_find_sta(vif, bssid); +} + +static inline struct ieee80211_sta *rtl_find_sta(struct ieee80211_hw *hw, + u8 *mac_addr) +{ + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + + return ieee80211_find_sta(mac->vif, mac_addr); +} + +#endif diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 482a29dd06f8..7cdce87f3051 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -3064,7 +3064,8 @@ static int mspro_rw_multi_sector(struct scsi_cmnd *srb, if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit mspro_rw_multi_sector\n"); + dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", + __func__); rtsx_trace(chip); return STATUS_FAIL; } @@ -3101,7 +3102,7 @@ static int mspro_read_format_progress(struct rtsx_chip *chip, u8 cnt, tmp; u8 data[8]; - dev_dbg(rtsx_dev(chip), "mspro_read_format_progress, short_data_len = %d\n", + dev_dbg(rtsx_dev(chip), "%s, short_data_len = %d\n", __func__, short_data_len); retval = ms_switch_clock(chip); diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index b8177f50fabc..89e2cfe7d1cc 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -205,16 +205,6 @@ static int device_reset(struct scsi_cmnd *srb) return SUCCESS; } -/* Simulate a SCSI bus reset by resetting the device's USB port. */ -static int bus_reset(struct scsi_cmnd *srb) -{ - struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - - dev_info(&dev->pci->dev, "%s called\n", __func__); - - return SUCCESS; -} - /* * this defines our host template, with which we'll allocate hosts */ @@ -231,7 +221,6 @@ static struct scsi_host_template rtsx_host_template = { /* error and abort handlers */ .eh_abort_handler = command_abort, .eh_device_reset_handler = device_reset, - .eh_bus_reset_handler = bus_reset, /* queue commands only, only one command per LUN */ .can_queue = 1, @@ -999,7 +988,7 @@ static int rtsx_probe(struct pci_dev *pci, /* We come here if there are any problems */ errout: - dev_err(&pci->dev, "rtsx_probe() failed\n"); + dev_err(&pci->dev, "%s failed\n", __func__); release_everything(dev); return err; @@ -1009,7 +998,7 @@ static void rtsx_remove(struct pci_dev *pci) { struct rtsx_dev *dev = pci_get_drvdata(pci); - dev_info(&pci->dev, "rtsx_remove() called\n"); + dev_info(&pci->dev, "%s called\n", __func__); quiesce_and_remove_host(dev); release_everything(dev); diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index 7f4107bffe31..4ad472dd9daf 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -616,8 +616,8 @@ int rtsx_reset_chip(struct rtsx_chip *chip) else retval = rtsx_pre_handle_sdio_new(chip); - dev_dbg(rtsx_dev(chip), "chip->need_reset = 0x%x (rtsx_reset_chip)\n", - (unsigned int)(chip->need_reset)); + 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 */ diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index 36b5a11f21d2..a401b13f5f5e 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -414,7 +414,7 @@ void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, 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) >> 8; + sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 4; sense->sns_key_info[2] = sns_key_info1 & 0x0f; } } diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index c2eb072cbe1d..4033a2cf7ac9 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -910,8 +910,8 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) int retval; bool ddr_rx = false; - dev_dbg(rtsx_dev(chip), "sd_change_phase (sample_point = %d, tune_dir = %d)\n", - sample_point, tune_dir); + 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; @@ -1225,8 +1225,8 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, u8 func_group, int retval; u8 cmd[5], buf[64]; - dev_dbg(rtsx_dev(chip), "sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n", - mode, func_group, func_to_switch); + 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; @@ -1654,7 +1654,7 @@ static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) return STATUS_SUCCESS; } -static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) +static int mmc_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) { struct sd_info *sd_card = &chip->sd_card; int retval; @@ -1933,7 +1933,7 @@ static int sd_tuning_rx(struct rtsx_chip *chip) } else { if (CHK_MMC_DDR52(sd_card)) { - tuning_cmd = mmc_ddr_tunning_rx_cmd; + tuning_cmd = mmc_ddr_tuning_rx_cmd; } else { rtsx_trace(chip); return STATUS_FAIL; @@ -3575,8 +3575,8 @@ static int reset_mmc_only(struct rtsx_chip *chip) return STATUS_FAIL; } - dev_dbg(rtsx_dev(chip), "In reset_mmc_only, sd_card->sd_type = 0x%x\n", - sd_card->sd_type); + dev_dbg(rtsx_dev(chip), "In %s, sd_card->sd_type = 0x%x\n", + __func__, sd_card->sd_type); return STATUS_SUCCESS; } @@ -3699,11 +3699,11 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, int retval; if (srb->sc_data_direction == DMA_FROM_DEVICE) { - dev_dbg(rtsx_dev(chip), "sd_rw: Read %d %s from 0x%x\n", + 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), "sd_rw: Write %d %s to 0x%x\n", + dev_dbg(rtsx_dev(chip), "%s: Write %d %s to 0x%x\n", __func__, sector_cnt, (sector_cnt > 1) ? "sectors" : "sector", start_sector); } @@ -3921,7 +3921,8 @@ int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, 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 sd_rw\n"); + dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", + __func__); rtsx_trace(chip); return STATUS_FAIL; } @@ -3964,7 +3965,7 @@ RW_FAIL: if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { chip->rw_need_retry = 0; - dev_dbg(rtsx_dev(chip), "No card exist, exit sd_rw\n"); + dev_dbg(rtsx_dev(chip), "No card exist, exit %s\n", __func__); rtsx_trace(chip); return STATUS_FAIL; } diff --git a/drivers/staging/rts5208/spi.c b/drivers/staging/rts5208/spi.c index 8b8cd955dfeb..b5646b62ec9e 100644 --- a/drivers/staging/rts5208/spi.c +++ b/drivers/staging/rts5208/spi.c @@ -520,7 +520,7 @@ int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) { struct spi_info *spi = &chip->spi; - dev_dbg(rtsx_dev(chip), "spi_get_status: err_code = 0x%x\n", + 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); @@ -543,8 +543,10 @@ int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; spi->write_en = srb->cmnd[6]; - dev_dbg(rtsx_dev(chip), "spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n", - spi->spi_clock, spi->clk_div, spi->write_en); + dev_dbg(rtsx_dev(chip), "%s: ", __func__); + dev_dbg(rtsx_dev(chip), "spi_clock = %d, ", spi->spi_clock); + dev_dbg(rtsx_dev(chip), "clk_div = %d, ", spi->clk_div); + dev_dbg(rtsx_dev(chip), "write_en = %d\n", spi->write_en); return STATUS_SUCCESS; } diff --git a/drivers/staging/rts5208/trace.c b/drivers/staging/rts5208/trace.c index 1bddbdf3454b..c878e75293f7 100644 --- a/drivers/staging/rts5208/trace.c +++ b/drivers/staging/rts5208/trace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/drivers/staging/rts5208/xd.c b/drivers/staging/rts5208/xd.c index 74d36f9a4c1d..11ea0c658e28 100644 --- a/drivers/staging/rts5208/xd.c +++ b/drivers/staging/rts5208/xd.c @@ -885,7 +885,7 @@ 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), "xd_init_l2p_tbl: zone_cnt = %d\n", + dev_dbg(rtsx_dev(chip), "%s: zone_cnt = %d\n", __func__, xd_card->zone_cnt); if (xd_card->zone_cnt < 1) { @@ -1026,7 +1026,8 @@ static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off) #ifdef XD_DELAY_WRITE retval = xd_delay_write(chip); if (retval != STATUS_SUCCESS) { - dev_dbg(rtsx_dev(chip), "In xd_get_l2p_tbl, delay write fail!\n"); + dev_dbg(rtsx_dev(chip), "In %s, delay write fail!\n", + __func__); return BLK_NOT_FOUND; } #endif @@ -1434,7 +1435,7 @@ static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) u16 cur_lst_page_logoff, ent_lst_page_logoff; u8 redunt[11]; - dev_dbg(rtsx_dev(chip), "xd_build_l2p_tbl: %d\n", zone_no); + dev_dbg(rtsx_dev(chip), "%s: %d\n", __func__, zone_no); if (!xd_card->zone) { retval = xd_init_l2p_tbl(chip); @@ -1774,8 +1775,10 @@ static int xd_finish_write(struct rtsx_chip *chip, int retval, zone_no; u16 log_off; - dev_dbg(rtsx_dev(chip), "xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", - old_blk, new_blk, log_blk); + dev_dbg(rtsx_dev(chip), "%s ", __func__); + 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) { rtsx_trace(chip); @@ -1960,7 +1963,7 @@ int xd_delay_write(struct rtsx_chip *chip) int retval; if (delay_write->delay_write_flag) { - dev_dbg(rtsx_dev(chip), "xd_delay_write\n"); + dev_dbg(rtsx_dev(chip), "%s\n", __func__); retval = xd_switch_clock(chip); if (retval != STATUS_SUCCESS) { rtsx_trace(chip); @@ -2002,7 +2005,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, xd_card->cleanup_counter = 0; - dev_dbg(rtsx_dev(chip), "xd_rw: scsi_sg_count = %d\n", + dev_dbg(rtsx_dev(chip), "%s: scsi_sg_count = %d\n", __func__, scsi_sg_count(srb)); ptr = (u8 *)scsi_sglist(srb); diff --git a/drivers/staging/skein/Makefile b/drivers/staging/skein/Makefile index b7f947fb98f0..86b7966d694e 100644 --- a/drivers/staging/skein/Makefile +++ b/drivers/staging/skein/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the skein secure hash algorithm # diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c index 256657077a46..3bc25e149034 100644 --- a/drivers/staging/skein/skein_block.c +++ b/drivers/staging/skein/skein_block.c @@ -21,329 +21,6 @@ #include "skein_base.h" #include "skein_block.h" -#ifndef SKEIN_USE_ASM -#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */ -#endif - -#ifndef SKEIN_LOOP -#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ -#endif - -#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */ -#define KW_TWK_BASE (0) -#define KW_KEY_BASE (3) -#define ks (kw + KW_KEY_BASE) -#define ts (kw + KW_TWK_BASE) - -#ifdef SKEIN_DEBUG -#define debug_save_tweak(ctx) \ -{ \ - ctx->h.tweak[0] = ts[0]; \ - ctx->h.tweak[1] = ts[1]; \ -} -#else -#define debug_save_tweak(ctx) -#endif - -#if !(SKEIN_USE_ASM & 256) -#undef RCNT -#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8) -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10) -#else -#define SKEIN_UNROLL_256 (0) -#endif - -#if SKEIN_UNROLL_256 -#if (RCNT % SKEIN_UNROLL_256) -#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ -#endif -#endif -#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ - do { \ - X##p0 += X##p1; \ - X##p1 = rol64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rol64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - } while (0) - -#if SKEIN_UNROLL_256 == 0 -#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ - ROUND256(p0, p1, p2, p3, ROT, r_num) - -#define I256(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[((R) + 1) % 5]; \ - X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \ - X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \ - X3 += ks[((R) + 4) % 5] + (R) + 1; \ - } while (0) -#else -/* looping version */ -#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num) - -#define I256(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[r + (R) + 0]; \ - X1 += ks[r + (R) + 1] + ts[r + (R) + 0];\ - X2 += ks[r + (R) + 2] + ts[r + (R) + 1];\ - X3 += ks[r + (R) + 3] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 4] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - } while (0) -#endif -#define R256_8_ROUNDS(R) \ - do { \ - R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ - R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \ - R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \ - R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \ - I256(2 * (R)); \ - R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \ - R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \ - R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \ - R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \ - I256(2 * (R) + 1); \ - } while (0) - -#define R256_UNROLL_R(NN) \ - ((SKEIN_UNROLL_256 == 0 && \ - SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ - (SKEIN_UNROLL_256 > (NN))) - -#if (SKEIN_UNROLL_256 > 14) -#error "need more unrolling in skein_256_process_block" -#endif -#endif - -#if !(SKEIN_USE_ASM & 512) -#undef RCNT -#define RCNT (SKEIN_512_ROUNDS_TOTAL / 8) - -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_512 (((SKEIN_LOOP) / 10) % 10) -#else -#define SKEIN_UNROLL_512 (0) -#endif - -#if SKEIN_UNROLL_512 -#if (RCNT % SKEIN_UNROLL_512) -#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ -#endif -#endif -#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - do { \ - X##p0 += X##p1; \ - X##p1 = rol64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rol64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - X##p4 += X##p5; \ - X##p5 = rol64(X##p5, ROT##_2); \ - X##p5 ^= X##p4; \ - X##p6 += X##p7; \ - X##p7 = rol64(X##p7, ROT##_3); \ - X##p7 ^= X##p6; \ - } while (0) - -#if SKEIN_UNROLL_512 == 0 -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) - -#define I512(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[((R) + 1) % 9]; \ - X1 += ks[((R) + 2) % 9]; \ - X2 += ks[((R) + 3) % 9]; \ - X3 += ks[((R) + 4) % 9]; \ - X4 += ks[((R) + 5) % 9]; \ - X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ - X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ - X7 += ks[((R) + 8) % 9] + (R) + 1; \ - } while (0) - -#else /* looping version */ -#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ - -#define I512(R) \ - do { \ - /* inject the key schedule value */ \ - X0 += ks[r + (R) + 0]; \ - X1 += ks[r + (R) + 1]; \ - X2 += ks[r + (R) + 2]; \ - X3 += ks[r + (R) + 3]; \ - X4 += ks[r + (R) + 4]; \ - X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ - X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ - X7 += ks[r + (R) + 7] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 8] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - } while (0) -#endif /* end of looped code definitions */ -#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ - do { \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ - I512(2 * (R)); \ - R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ - R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ - R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ - R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ - I512(2 * (R) + 1); /* and key injection */ \ - } while (0) -#define R512_UNROLL_R(NN) \ - ((SKEIN_UNROLL_512 == 0 && \ - SKEIN_512_ROUNDS_TOTAL / 8 > (NN)) || \ - (SKEIN_UNROLL_512 > (NN))) - -#if (SKEIN_UNROLL_512 > 14) -#error "need more unrolling in skein_512_process_block" -#endif -#endif - -#if !(SKEIN_USE_ASM & 1024) -#undef RCNT -#define RCNT (SKEIN_1024_ROUNDS_TOTAL / 8) -#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ -#define SKEIN_UNROLL_1024 ((SKEIN_LOOP) % 10) -#else -#define SKEIN_UNROLL_1024 (0) -#endif - -#if (SKEIN_UNROLL_1024 != 0) -#if (RCNT % SKEIN_UNROLL_1024) -#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ -#endif -#endif -#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, r_num) \ - do { \ - X##p0 += X##p1; \ - X##p1 = rol64(X##p1, ROT##_0); \ - X##p1 ^= X##p0; \ - X##p2 += X##p3; \ - X##p3 = rol64(X##p3, ROT##_1); \ - X##p3 ^= X##p2; \ - X##p4 += X##p5; \ - X##p5 = rol64(X##p5, ROT##_2); \ - X##p5 ^= X##p4; \ - X##p6 += X##p7; \ - X##p7 = rol64(X##p7, ROT##_3); \ - X##p7 ^= X##p6; \ - X##p8 += X##p9; \ - X##p9 = rol64(X##p9, ROT##_4); \ - X##p9 ^= X##p8; \ - X##pA += X##pB; \ - X##pB = rol64(X##pB, ROT##_5); \ - X##pB ^= X##pA; \ - X##pC += X##pD; \ - X##pD = rol64(X##pD, ROT##_6); \ - X##pD ^= X##pC; \ - X##pE += X##pF; \ - X##pF = rol64(X##pF, ROT##_7); \ - X##pF ^= X##pE; \ - } while (0) - -#if SKEIN_UNROLL_1024 == 0 -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn) \ - -#define I1024(R) \ - do { \ - /* inject the key schedule value */ \ - X00 += ks[((R) + 1) % 17]; \ - X01 += ks[((R) + 2) % 17]; \ - X02 += ks[((R) + 3) % 17]; \ - X03 += ks[((R) + 4) % 17]; \ - X04 += ks[((R) + 5) % 17]; \ - X05 += ks[((R) + 6) % 17]; \ - X06 += ks[((R) + 7) % 17]; \ - X07 += ks[((R) + 8) % 17]; \ - X08 += ks[((R) + 9) % 17]; \ - X09 += ks[((R) + 10) % 17]; \ - X10 += ks[((R) + 11) % 17]; \ - X11 += ks[((R) + 12) % 17]; \ - X12 += ks[((R) + 13) % 17]; \ - X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ - X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ - X15 += ks[((R) + 16) % 17] + (R) + 1; \ - } while (0) -#else /* looping version */ -#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ - ROT, rn) \ - ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ - pF, ROT, rn) \ - -#define I1024(R) \ - do { \ - /* inject the key schedule value */ \ - X00 += ks[r + (R) + 0]; \ - X01 += ks[r + (R) + 1]; \ - X02 += ks[r + (R) + 2]; \ - X03 += ks[r + (R) + 3]; \ - X04 += ks[r + (R) + 4]; \ - X05 += ks[r + (R) + 5]; \ - X06 += ks[r + (R) + 6]; \ - X07 += ks[r + (R) + 7]; \ - X08 += ks[r + (R) + 8]; \ - X09 += ks[r + (R) + 9]; \ - X10 += ks[r + (R) + 10]; \ - X11 += ks[r + (R) + 11]; \ - X12 += ks[r + (R) + 12]; \ - X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ - X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ - X15 += ks[r + (R) + 15] + r + (R); \ - /* rotate key schedule */ \ - ks[r + (R) + 16] = ks[r + (R) - 1]; \ - ts[r + (R) + 2] = ts[r + (R) - 1]; \ - } while (0) - -#endif -#define R1024_8_ROUNDS(R) \ - do { \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ - 13, 14, 15, R1024_0, 8 * (R) + 1); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ - 05, 08, 01, R1024_1, 8 * (R) + 2); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ - 11, 10, 09, R1024_2, 8 * (R) + 3); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ - 03, 12, 07, R1024_3, 8 * (R) + 4); \ - I1024(2 * (R)); \ - R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ - 13, 14, 15, R1024_4, 8 * (R) + 5); \ - R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ - 05, 08, 01, R1024_5, 8 * (R) + 6); \ - R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ - 11, 10, 09, R1024_6, 8 * (R) + 7); \ - R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ - 03, 12, 07, R1024_7, 8 * (R) + 8); \ - I1024(2 * (R) + 1); \ - } while (0) - -#define R1024_UNROLL_R(NN) \ - ((SKEIN_UNROLL_1024 == 0 && \ - SKEIN_1024_ROUNDS_TOTAL / 8 > (NN)) || \ - (SKEIN_UNROLL_1024 > (NN))) - -#if (SKEIN_UNROLL_1024 > 14) -#error "need more unrolling in Skein_1024_Process_Block" -#endif -#endif - /***************************** SKEIN_256 ******************************/ #if !(SKEIN_USE_ASM & 256) void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h index ec1baea25c9e..b3bb3d24273b 100644 --- a/drivers/staging/skein/skein_block.h +++ b/drivers/staging/skein/skein_block.h @@ -14,6 +14,329 @@ #include "skein_base.h" /* get the Skein API definitions */ +#ifndef SKEIN_USE_ASM +#define SKEIN_USE_ASM (0) /* default is all C code (no ASM) */ +#endif + +#ifndef SKEIN_LOOP +#define SKEIN_LOOP 001 /* default: unroll 256 and 512, but not 1024 */ +#endif + +#define BLK_BITS (WCNT * 64) /* some useful definitions for code here */ +#define KW_TWK_BASE (0) +#define KW_KEY_BASE (3) +#define ks (kw + KW_KEY_BASE) +#define ts (kw + KW_TWK_BASE) + +#ifdef SKEIN_DEBUG +#define debug_save_tweak(ctx) \ +{ \ + ctx->h.tweak[0] = ts[0]; \ + ctx->h.tweak[1] = ts[1]; \ +} +#else +#define debug_save_tweak(ctx) +#endif + +#if !(SKEIN_USE_ASM & 256) +#undef RCNT +#define RCNT (SKEIN_256_ROUNDS_TOTAL / 8) +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_256 (((SKEIN_LOOP) / 100) % 10) +#else +#define SKEIN_UNROLL_256 (0) +#endif + +#if SKEIN_UNROLL_256 +#if (RCNT % SKEIN_UNROLL_256) +#error "Invalid SKEIN_UNROLL_256" /* sanity check on unroll count */ +#endif +#endif +#define ROUND256(p0, p1, p2, p3, ROT, r_num) \ + do { \ + X##p0 += X##p1; \ + X##p1 = rol64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rol64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + } while (0) + +#if SKEIN_UNROLL_256 == 0 +#define R256(p0, p1, p2, p3, ROT, r_num) /* fully unrolled */ \ + ROUND256(p0, p1, p2, p3, ROT, r_num) + +#define I256(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 5]; \ + X1 += ks[((R) + 2) % 5] + ts[((R) + 1) % 3]; \ + X2 += ks[((R) + 3) % 5] + ts[((R) + 2) % 3]; \ + X3 += ks[((R) + 4) % 5] + (R) + 1; \ + } while (0) +#else +/* looping version */ +#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num) + +#define I256(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1] + ts[r + (R) + 0];\ + X2 += ks[r + (R) + 2] + ts[r + (R) + 1];\ + X3 += ks[r + (R) + 3] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 4] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + } while (0) +#endif +#define R256_8_ROUNDS(R) \ + do { \ + R256(0, 1, 2, 3, R_256_0, 8 * (R) + 1); \ + R256(0, 3, 2, 1, R_256_1, 8 * (R) + 2); \ + R256(0, 1, 2, 3, R_256_2, 8 * (R) + 3); \ + R256(0, 3, 2, 1, R_256_3, 8 * (R) + 4); \ + I256(2 * (R)); \ + R256(0, 1, 2, 3, R_256_4, 8 * (R) + 5); \ + R256(0, 3, 2, 1, R_256_5, 8 * (R) + 6); \ + R256(0, 1, 2, 3, R_256_6, 8 * (R) + 7); \ + R256(0, 3, 2, 1, R_256_7, 8 * (R) + 8); \ + I256(2 * (R) + 1); \ + } while (0) + +#define R256_UNROLL_R(NN) \ + ((SKEIN_UNROLL_256 == 0 && \ + SKEIN_256_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_256 > (NN))) + +#if (SKEIN_UNROLL_256 > 14) +#error "need more unrolling in skein_256_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 512) +#undef RCNT +#define RCNT (SKEIN_512_ROUNDS_TOTAL / 8) + +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_512 (((SKEIN_LOOP) / 10) % 10) +#else +#define SKEIN_UNROLL_512 (0) +#endif + +#if SKEIN_UNROLL_512 +#if (RCNT % SKEIN_UNROLL_512) +#error "Invalid SKEIN_UNROLL_512" /* sanity check on unroll count */ +#endif +#endif +#define ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + do { \ + X##p0 += X##p1; \ + X##p1 = rol64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rol64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rol64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; \ + X##p7 = rol64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ + } while (0) + +#if SKEIN_UNROLL_512 == 0 +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) /* unrolled */ \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) + +#define I512(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[((R) + 1) % 9]; \ + X1 += ks[((R) + 2) % 9]; \ + X2 += ks[((R) + 3) % 9]; \ + X3 += ks[((R) + 4) % 9]; \ + X4 += ks[((R) + 5) % 9]; \ + X5 += ks[((R) + 6) % 9] + ts[((R) + 1) % 3]; \ + X6 += ks[((R) + 7) % 9] + ts[((R) + 2) % 3]; \ + X7 += ks[((R) + 8) % 9] + (R) + 1; \ + } while (0) + +#else /* looping version */ +#define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num) \ + +#define I512(R) \ + do { \ + /* inject the key schedule value */ \ + X0 += ks[r + (R) + 0]; \ + X1 += ks[r + (R) + 1]; \ + X2 += ks[r + (R) + 2]; \ + X3 += ks[r + (R) + 3]; \ + X4 += ks[r + (R) + 4]; \ + X5 += ks[r + (R) + 5] + ts[r + (R) + 0]; \ + X6 += ks[r + (R) + 6] + ts[r + (R) + 1]; \ + X7 += ks[r + (R) + 7] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 8] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + } while (0) +#endif /* end of looped code definitions */ +#define R512_8_ROUNDS(R) /* do 8 full rounds */ \ + do { \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_0, 8 * (R) + 1); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_1, 8 * (R) + 2); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_2, 8 * (R) + 3); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_3, 8 * (R) + 4); \ + I512(2 * (R)); \ + R512(0, 1, 2, 3, 4, 5, 6, 7, R_512_4, 8 * (R) + 5); \ + R512(2, 1, 4, 7, 6, 5, 0, 3, R_512_5, 8 * (R) + 6); \ + R512(4, 1, 6, 3, 0, 5, 2, 7, R_512_6, 8 * (R) + 7); \ + R512(6, 1, 0, 7, 2, 5, 4, 3, R_512_7, 8 * (R) + 8); \ + I512(2 * (R) + 1); /* and key injection */ \ + } while (0) +#define R512_UNROLL_R(NN) \ + ((SKEIN_UNROLL_512 == 0 && \ + SKEIN_512_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_512 > (NN))) + +#if (SKEIN_UNROLL_512 > 14) +#error "need more unrolling in skein_512_process_block" +#endif +#endif + +#if !(SKEIN_USE_ASM & 1024) +#undef RCNT +#define RCNT (SKEIN_1024_ROUNDS_TOTAL / 8) +#ifdef SKEIN_LOOP /* configure how much to unroll the loop */ +#define SKEIN_UNROLL_1024 ((SKEIN_LOOP) % 10) +#else +#define SKEIN_UNROLL_1024 (0) +#endif + +#if (SKEIN_UNROLL_1024 != 0) +#if (RCNT % SKEIN_UNROLL_1024) +#error "Invalid SKEIN_UNROLL_1024" /* sanity check on unroll count */ +#endif +#endif +#define ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, r_num) \ + do { \ + X##p0 += X##p1; \ + X##p1 = rol64(X##p1, ROT##_0); \ + X##p1 ^= X##p0; \ + X##p2 += X##p3; \ + X##p3 = rol64(X##p3, ROT##_1); \ + X##p3 ^= X##p2; \ + X##p4 += X##p5; \ + X##p5 = rol64(X##p5, ROT##_2); \ + X##p5 ^= X##p4; \ + X##p6 += X##p7; \ + X##p7 = rol64(X##p7, ROT##_3); \ + X##p7 ^= X##p6; \ + X##p8 += X##p9; \ + X##p9 = rol64(X##p9, ROT##_4); \ + X##p9 ^= X##p8; \ + X##pA += X##pB; \ + X##pB = rol64(X##pB, ROT##_5); \ + X##pB ^= X##pA; \ + X##pC += X##pD; \ + X##pD = rol64(X##pD, ROT##_6); \ + X##pD ^= X##pC; \ + X##pE += X##pF; \ + X##pF = rol64(X##pF, ROT##_7); \ + X##pF ^= X##pE; \ + } while (0) + +#if SKEIN_UNROLL_1024 == 0 +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn) \ + +#define I1024(R) \ + do { \ + /* inject the key schedule value */ \ + X00 += ks[((R) + 1) % 17]; \ + X01 += ks[((R) + 2) % 17]; \ + X02 += ks[((R) + 3) % 17]; \ + X03 += ks[((R) + 4) % 17]; \ + X04 += ks[((R) + 5) % 17]; \ + X05 += ks[((R) + 6) % 17]; \ + X06 += ks[((R) + 7) % 17]; \ + X07 += ks[((R) + 8) % 17]; \ + X08 += ks[((R) + 9) % 17]; \ + X09 += ks[((R) + 10) % 17]; \ + X10 += ks[((R) + 11) % 17]; \ + X11 += ks[((R) + 12) % 17]; \ + X12 += ks[((R) + 13) % 17]; \ + X13 += ks[((R) + 14) % 17] + ts[((R) + 1) % 3]; \ + X14 += ks[((R) + 15) % 17] + ts[((R) + 2) % 3]; \ + X15 += ks[((R) + 16) % 17] + (R) + 1; \ + } while (0) +#else /* looping version */ +#define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \ + ROT, rn) \ + ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \ + pF, ROT, rn) \ + +#define I1024(R) \ + do { \ + /* inject the key schedule value */ \ + X00 += ks[r + (R) + 0]; \ + X01 += ks[r + (R) + 1]; \ + X02 += ks[r + (R) + 2]; \ + X03 += ks[r + (R) + 3]; \ + X04 += ks[r + (R) + 4]; \ + X05 += ks[r + (R) + 5]; \ + X06 += ks[r + (R) + 6]; \ + X07 += ks[r + (R) + 7]; \ + X08 += ks[r + (R) + 8]; \ + X09 += ks[r + (R) + 9]; \ + X10 += ks[r + (R) + 10]; \ + X11 += ks[r + (R) + 11]; \ + X12 += ks[r + (R) + 12]; \ + X13 += ks[r + (R) + 13] + ts[r + (R) + 0]; \ + X14 += ks[r + (R) + 14] + ts[r + (R) + 1]; \ + X15 += ks[r + (R) + 15] + r + (R); \ + /* rotate key schedule */ \ + ks[r + (R) + 16] = ks[r + (R) - 1]; \ + ts[r + (R) + 2] = ts[r + (R) - 1]; \ + } while (0) + +#endif +#define R1024_8_ROUNDS(R) \ + do { \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ + 13, 14, 15, R1024_0, 8 * (R) + 1); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ + 05, 08, 01, R1024_1, 8 * (R) + 2); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ + 11, 10, 09, R1024_2, 8 * (R) + 3); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ + 03, 12, 07, R1024_3, 8 * (R) + 4); \ + I1024(2 * (R)); \ + R1024(00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, \ + 13, 14, 15, R1024_4, 8 * (R) + 5); \ + R1024(00, 09, 02, 13, 06, 11, 04, 15, 10, 07, 12, 03, 14, \ + 05, 08, 01, R1024_5, 8 * (R) + 6); \ + R1024(00, 07, 02, 05, 04, 03, 06, 01, 12, 15, 14, 13, 08, \ + 11, 10, 09, R1024_6, 8 * (R) + 7); \ + R1024(00, 15, 02, 11, 06, 13, 04, 09, 14, 01, 08, 05, 10, \ + 03, 12, 07, R1024_7, 8 * (R) + 8); \ + I1024(2 * (R) + 1); \ + } while (0) + +#define R1024_UNROLL_R(NN) \ + ((SKEIN_UNROLL_1024 == 0 && \ + SKEIN_1024_ROUNDS_TOTAL / 8 > (NN)) || \ + (SKEIN_UNROLL_1024 > (NN))) + +#if (SKEIN_UNROLL_1024 > 14) +#error "need more unrolling in Skein_1024_Process_Block" +#endif +#endif + void skein_256_process_block(struct skein_256_ctx *ctx, const u8 *blk_ptr, size_t blk_cnt, size_t byte_cnt_add); void skein_512_process_block(struct skein_512_ctx *ctx, const u8 *blk_ptr, diff --git a/drivers/staging/skein/skein_iv.h b/drivers/staging/skein/skein_iv.h index 509d464c65a3..916f029da726 100644 --- a/drivers/staging/skein/skein_iv.h +++ b/drivers/staging/skein/skein_iv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SKEIN_IV_H_ #define _SKEIN_IV_H_ diff --git a/drivers/staging/skein/threefish_api.c b/drivers/staging/skein/threefish_api.c index 2b649abb78c7..e69cefa6b16a 100644 --- a/drivers/staging/skein/threefish_api.c +++ b/drivers/staging/skein/threefish_api.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "threefish_api.h" diff --git a/drivers/staging/skein/threefish_api.h b/drivers/staging/skein/threefish_api.h index 615e467579ee..21539c3cc7a0 100644 --- a/drivers/staging/skein/threefish_api.h +++ b/drivers/staging/skein/threefish_api.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef THREEFISHAPI_H #define THREEFISHAPI_H diff --git a/drivers/staging/skein/threefish_block.c b/drivers/staging/skein/threefish_block.c index 50640656c10d..87f055890544 100644 --- a/drivers/staging/skein/threefish_block.c +++ b/drivers/staging/skein/threefish_block.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "threefish_api.h" diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c index 4754f7a20684..313b99104398 100644 --- a/drivers/staging/sm750fb/ddk750_chip.c +++ b/drivers/staging/sm750fb/ddk750_chip.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/drivers/staging/sm750fb/ddk750_chip.h b/drivers/staging/sm750fb/ddk750_chip.h index 2c7a9b9a7c8a..09c223f815de 100644 --- a/drivers/staging/sm750fb/ddk750_chip.h +++ b/drivers/staging/sm750fb/ddk750_chip.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_CHIP_H__ #define DDK750_CHIP_H__ #define DEFAULT_INPUT_CLOCK 14318181 /* Default reference clock */ diff --git a/drivers/staging/sm750fb/ddk750_display.c b/drivers/staging/sm750fb/ddk750_display.c index 9b116ed6ecc7..c6fd90191530 100644 --- a/drivers/staging/sm750fb/ddk750_display.c +++ b/drivers/staging/sm750fb/ddk750_display.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "ddk750_reg.h" #include "ddk750_chip.h" #include "ddk750_display.h" diff --git a/drivers/staging/sm750fb/ddk750_display.h b/drivers/staging/sm750fb/ddk750_display.h index 609bf742efff..523bbf33521c 100644 --- a/drivers/staging/sm750fb/ddk750_display.h +++ b/drivers/staging/sm750fb/ddk750_display.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_DISPLAY_H__ #define DDK750_DISPLAY_H__ diff --git a/drivers/staging/sm750fb/ddk750_dvi.c b/drivers/staging/sm750fb/ddk750_dvi.c index 87a199d6cdaf..f41bd9181757 100644 --- a/drivers/staging/sm750fb/ddk750_dvi.c +++ b/drivers/staging/sm750fb/ddk750_dvi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define USE_DVICHIP #ifdef USE_DVICHIP #include "ddk750_chip.h" diff --git a/drivers/staging/sm750fb/ddk750_dvi.h b/drivers/staging/sm750fb/ddk750_dvi.h index 4a8394561f76..9529cb9cfd69 100644 --- a/drivers/staging/sm750fb/ddk750_dvi.h +++ b/drivers/staging/sm750fb/ddk750_dvi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_DVI_H__ #define DDK750_DVI_H__ diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.c b/drivers/staging/sm750fb/ddk750_hwi2c.c index ec556a978a98..8482689b665b 100644 --- a/drivers/staging/sm750fb/ddk750_hwi2c.c +++ b/drivers/staging/sm750fb/ddk750_hwi2c.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define USE_HW_I2C #ifdef USE_HW_I2C #include "ddk750_chip.h" diff --git a/drivers/staging/sm750fb/ddk750_hwi2c.h b/drivers/staging/sm750fb/ddk750_hwi2c.h index 46e22dce2570..337c6493ca61 100644 --- a/drivers/staging/sm750fb/ddk750_hwi2c.h +++ b/drivers/staging/sm750fb/ddk750_hwi2c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_HWI2C_H__ #define DDK750_HWI2C_H__ diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c index bb673e18999b..2cdd87b78e58 100644 --- a/drivers/staging/sm750fb/ddk750_mode.c +++ b/drivers/staging/sm750fb/ddk750_mode.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "ddk750_reg.h" #include "ddk750_mode.h" diff --git a/drivers/staging/sm750fb/ddk750_mode.h b/drivers/staging/sm750fb/ddk750_mode.h index d5eae36d85cb..259a9d6a4eb2 100644 --- a/drivers/staging/sm750fb/ddk750_mode.h +++ b/drivers/staging/sm750fb/ddk750_mode.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_MODE_H__ #define DDK750_MODE_H__ diff --git a/drivers/staging/sm750fb/ddk750_power.c b/drivers/staging/sm750fb/ddk750_power.c index 222ae1a06feb..73aeaeb89a64 100644 --- a/drivers/staging/sm750fb/ddk750_power.c +++ b/drivers/staging/sm750fb/ddk750_power.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "ddk750_chip.h" #include "ddk750_reg.h" #include "ddk750_power.h" diff --git a/drivers/staging/sm750fb/ddk750_power.h b/drivers/staging/sm750fb/ddk750_power.h index 44c4fc587e96..651d05247edf 100644 --- a/drivers/staging/sm750fb/ddk750_power.h +++ b/drivers/staging/sm750fb/ddk750_power.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_POWER_H__ #define DDK750_POWER_H__ diff --git a/drivers/staging/sm750fb/ddk750_reg.h b/drivers/staging/sm750fb/ddk750_reg.h index f9b989b7a152..fe412ead72e5 100644 --- a/drivers/staging/sm750fb/ddk750_reg.h +++ b/drivers/staging/sm750fb/ddk750_reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_REG_H__ #define DDK750_REG_H__ diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c index 0431833de781..1eeaf087e891 100644 --- a/drivers/staging/sm750fb/ddk750_sii164.c +++ b/drivers/staging/sm750fb/ddk750_sii164.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define USE_DVICHIP #ifdef USE_DVICHIP diff --git a/drivers/staging/sm750fb/ddk750_sii164.h b/drivers/staging/sm750fb/ddk750_sii164.h index 6968cf532f16..af52a3121067 100644 --- a/drivers/staging/sm750fb/ddk750_sii164.h +++ b/drivers/staging/sm750fb/ddk750_sii164.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef DDK750_SII164_H__ #define DDK750_SII164_H__ diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index 4386122799b2..ce90adcb449d 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LYNXDRV_H_ #define LYNXDRV_H_ diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c index 4b720cfa05de..1035e91e7cd3 100644 --- a/drivers/staging/sm750fb/sm750_accel.c +++ b/drivers/staging/sm750fb/sm750_accel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/staging/sm750fb/sm750_accel.h b/drivers/staging/sm750fb/sm750_accel.h index 4b0ff8feb9a0..c4f42002a50f 100644 --- a/drivers/staging/sm750fb/sm750_accel.h +++ b/drivers/staging/sm750fb/sm750_accel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ACCEL_H__ #define ACCEL_H__ diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c index aa47a16ac75c..9d24159226d1 100644 --- a/drivers/staging/sm750fb/sm750_cursor.c +++ b/drivers/staging/sm750fb/sm750_cursor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/staging/sm750fb/sm750_cursor.h b/drivers/staging/sm750fb/sm750_cursor.h index c7b86ae235b4..16ac07eb58d6 100644 --- a/drivers/staging/sm750fb/sm750_cursor.h +++ b/drivers/staging/sm750fb/sm750_cursor.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LYNX_CURSOR_H__ #define LYNX_CURSOR_H__ diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index baf1bbdc92ff..ffd114a6d09b 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/staging/speakup/Makefile b/drivers/staging/speakup/Makefile index c864ea69c40d..5befb4933b85 100644 --- a/drivers/staging/speakup/Makefile +++ b/drivers/staging/speakup/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SPEAKUP_SYNTH_ACNTSA) += speakup_acntsa.o obj-$(CONFIG_SPEAKUP_SYNTH_ACNTPC) += speakup_acntpc.o obj-$(CONFIG_SPEAKUP_SYNTH_APOLLO) += speakup_apollo.o diff --git a/drivers/staging/speakup/devsynth.c b/drivers/staging/speakup/devsynth.c index 58abd1d85105..d920256328c3 100644 --- a/drivers/staging/speakup/devsynth.c +++ b/drivers/staging/speakup/devsynth.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include /* for misc_register, and SYNTH_MINOR */ #include diff --git a/drivers/staging/speakup/i18n.c b/drivers/staging/speakup/i18n.c index 7809867f5d28..cea8707653f5 100644 --- a/drivers/staging/speakup/i18n.c +++ b/drivers/staging/speakup/i18n.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Internationalization implementation. Includes definitions of English * string arrays, and the i18n pointer. */ diff --git a/drivers/staging/speakup/i18n.h b/drivers/staging/speakup/i18n.h index 8fcce566653f..2ec6e659d02b 100644 --- a/drivers/staging/speakup/i18n.h +++ b/drivers/staging/speakup/i18n.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef I18N_H #define I18N_H /* Internationalization declarations */ diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index 67956e24779c..56f7be6af1f6 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1376,6 +1376,8 @@ static void reset_highlight_buffers(struct vc_data *); static int read_all_key; +static int in_keyboard_notifier; + static void start_read_all_timer(struct vc_data *vc, int command); enum { @@ -1408,7 +1410,10 @@ static void read_all_doc(struct vc_data *vc) cursor_track = read_all_mode; spk_reset_index_count(0); if (get_sentence_buf(vc, 0) == -1) { - kbd_fakekey2(vc, RA_DOWN_ARROW); + del_timer(&cursor_timer); + if (!in_keyboard_notifier) + speakup_fake_down_arrow(); + start_read_all_timer(vc, RA_DOWN_ARROW); } else { say_sentence_num(0, 0); synth_insert_next_index(0); @@ -2212,8 +2217,10 @@ static int keyboard_notifier_call(struct notifier_block *nb, int ret = NOTIFY_OK; static int keycode; /* to hold the current keycode */ + in_keyboard_notifier = 1; + if (vc->vc_mode == KD_GRAPHICS) - return ret; + goto out; /* * First, determine whether we are handling a fake keypress on @@ -2225,7 +2232,7 @@ static int keyboard_notifier_call(struct notifier_block *nb, */ if (speakup_fake_key_pressed()) - return ret; + goto out; switch (code) { case KBD_KEYCODE: @@ -2266,6 +2273,8 @@ static int keyboard_notifier_call(struct notifier_block *nb, break; } } +out: + in_keyboard_notifier = 0; return ret; } diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index 08f68fc2864e..66061b5c3427 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include /* for kmalloc */ #include #include diff --git a/drivers/staging/speakup/serialio.h b/drivers/staging/speakup/serialio.h index 89de6fff9cb2..aa691e4a6916 100644 --- a/drivers/staging/speakup/serialio.h +++ b/drivers/staging/speakup/serialio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPEAKUP_SERIAL_H #define _SPEAKUP_SERIAL_H diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h index a654334c98b9..3d8bda8b9620 100644 --- a/drivers/staging/speakup/speakup.h +++ b/drivers/staging/speakup/speakup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SPEAKUP_H #define _SPEAKUP_H diff --git a/drivers/staging/speakup/speakup_acnt.h b/drivers/staging/speakup/speakup_acnt.h index 107ec1155f51..cffa938ae580 100644 --- a/drivers/staging/speakup/speakup_acnt.h +++ b/drivers/staging/speakup/speakup_acnt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* speakup_acntpc.h - header file for speakups Accent-PC driver. */ #define SYNTH_IO_EXTENT 0x02 diff --git a/drivers/staging/speakup/speakup_dtlk.h b/drivers/staging/speakup/speakup_dtlk.h index 51ac0f2fcded..9c378b58066e 100644 --- a/drivers/staging/speakup/speakup_dtlk.h +++ b/drivers/staging/speakup/speakup_dtlk.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* speakup_dtlk.h - header file for speakups DoubleTalk driver. */ #define SYNTH_IO_EXTENT 0x02 diff --git a/drivers/staging/speakup/speakupmap.h b/drivers/staging/speakup/speakupmap.h index f1c0dd3b2c3a..c60d7339b89a 100644 --- a/drivers/staging/speakup/speakupmap.h +++ b/drivers/staging/speakup/speakupmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ 119, 62, 6, 0, 16, 20, 17, 32, 48, 0, 2, 0, 78, 0, 0, 0, 0, diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c index fe340b07c482..4d7d8f2f66ea 100644 --- a/drivers/staging/speakup/spk_ttyio.c +++ b/drivers/staging/speakup/spk_ttyio.c @@ -7,11 +7,6 @@ #include "spk_types.h" #include "spk_priv.h" -#define DEV_PREFIX_LP "lp" - -static const char * const lp_supported[] = { "acntsa", "bns", "dummy", - "txprt" }; - struct spk_ldisc_data { char buf; struct semaphore sem; @@ -20,6 +15,11 @@ struct spk_ldisc_data { static struct spk_synth *spk_ttyio_synth; static struct tty_struct *speakup_tty; +/* mutex to protect against speakup_tty disappearing from underneath us while + * we are using it. this can happen when the device physically unplugged, + * while in use. it also serialises access to speakup_tty. + */ +static DEFINE_MUTEX(speakup_tty_mutex); static int ser_to_dev(int ser, dev_t *dev_no) { @@ -36,24 +36,8 @@ static int get_dev_to_use(struct spk_synth *synth, dev_t *dev_no) { /* use ser only when dev is not specified */ if (strcmp(synth->dev_name, SYNTH_DEFAULT_DEV) || - synth->ser == SYNTH_DEFAULT_SER) { - /* for /dev/lp* check if synth is supported */ - if (strncmp(synth->dev_name, DEV_PREFIX_LP, - strlen(DEV_PREFIX_LP)) == 0) - if (match_string(lp_supported, ARRAY_SIZE(lp_supported), - synth->name) < 0) { - int i; - - pr_err("speakup: lp* is only supported on:"); - for (i = 0; i < ARRAY_SIZE(lp_supported); i++) - pr_cont(" %s", lp_supported[i]); - pr_cont("\n"); - - return -ENOTSUPP; - } - + synth->ser == SYNTH_DEFAULT_SER) return tty_dev_name_to_number(synth->dev_name, dev_no); - } return ser_to_dev(synth->ser, dev_no); } @@ -81,8 +65,10 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty) static void spk_ttyio_ldisc_close(struct tty_struct *tty) { + mutex_lock(&speakup_tty_mutex); kfree(speakup_tty->disc_data); speakup_tty = NULL; + mutex_unlock(&speakup_tty_mutex); } static int spk_ttyio_receive_buf2(struct tty_struct *tty, @@ -158,7 +144,7 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) if (ret) return ret; - tty = tty_open_by_driver(dev, NULL, NULL); + tty = tty_kopen(dev); if (IS_ERR(tty)) return PTR_ERR(tty); @@ -210,9 +196,11 @@ void spk_ttyio_unregister_ldisc(void) static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) { + mutex_lock(&speakup_tty_mutex); if (in_synth->alive && speakup_tty && speakup_tty->ops->write) { int ret = speakup_tty->ops->write(speakup_tty, &ch, 1); + mutex_unlock(&speakup_tty_mutex); if (ret == 0) /* No room */ return 0; @@ -228,17 +216,50 @@ static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) } return 1; } + + mutex_unlock(&speakup_tty_mutex); + return 0; +} + +static int check_tty(struct tty_struct *tty) +{ + if (!tty) { + pr_warn("%s: I/O error, deactivating speakup\n", + spk_ttyio_synth->long_name); + /* No synth any more, so nobody will restart TTYs, and we thus + * need to do it ourselves. Now that there is no synth we can + * let application flood anyway + */ + spk_ttyio_synth->alive = 0; + speakup_start_ttys(); + return 1; + } + return 0; } static void spk_ttyio_send_xchar(char ch) { + mutex_lock(&speakup_tty_mutex); + if (check_tty(speakup_tty)) { + mutex_unlock(&speakup_tty_mutex); + return; + } + speakup_tty->ops->send_xchar(speakup_tty, ch); + mutex_unlock(&speakup_tty_mutex); } static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear) { + mutex_lock(&speakup_tty_mutex); + if (check_tty(speakup_tty)) { + mutex_unlock(&speakup_tty_mutex); + return; + } + speakup_tty->ops->tiocmset(speakup_tty, set, clear); + mutex_unlock(&speakup_tty_mutex); } static unsigned char ttyio_in(int timeout) @@ -278,8 +299,16 @@ static unsigned char spk_ttyio_in_nowait(void) static void spk_ttyio_flush_buffer(void) { + mutex_lock(&speakup_tty_mutex); + if (check_tty(speakup_tty)) { + mutex_unlock(&speakup_tty_mutex); + return; + } + if (speakup_tty->ops->flush_buffer) speakup_tty->ops->flush_buffer(speakup_tty); + + mutex_unlock(&speakup_tty_mutex); } int spk_ttyio_synth_probe(struct spk_synth *synth) @@ -308,7 +337,7 @@ void spk_ttyio_release(void) tty_ldisc_flush(speakup_tty); tty_unlock(speakup_tty); - tty_release_struct(speakup_tty, speakup_tty->index); + tty_kclose(speakup_tty); } EXPORT_SYMBOL_GPL(spk_ttyio_release); diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h index 22f657d45e46..c50de6035a9a 100644 --- a/drivers/staging/speakup/spk_types.h +++ b/drivers/staging/speakup/spk_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SPEAKUP_TYPES_H #define SPEAKUP_TYPES_H diff --git a/drivers/staging/typec/fusb302/Kconfig b/drivers/staging/typec/fusb302/Kconfig index fce099ff39fe..48a4f2fcee03 100644 --- a/drivers/staging/typec/fusb302/Kconfig +++ b/drivers/staging/typec/fusb302/Kconfig @@ -1,6 +1,6 @@ config TYPEC_FUSB302 tristate "Fairchild FUSB302 Type-C chip driver" - depends on I2C + depends on I2C && POWER_SUPPLY help The Fairchild FUSB302 Type-C chip driver that works with Type-C Port Controller Manager to provide USB PD and USB diff --git a/drivers/staging/typec/fusb302/TODO b/drivers/staging/typec/fusb302/TODO index 4933a1d92c32..19b466eb585d 100644 --- a/drivers/staging/typec/fusb302/TODO +++ b/drivers/staging/typec/fusb302/TODO @@ -4,3 +4,7 @@ fusb302: - Find a non-hacky way to coordinate between PM and I2C access - Documentation? The FUSB302 datasheet provides information on the chip to help understand the code. But it may still be helpful to have a documentation. +- We may want to replace the "fcs,max-snk-microvolt", "fcs,max-snk-microamp", + "fcs,max-snk-microwatt" and "fcs,operating-snk-microwatt" device(tree) + properties with properties which are part of a generic type-c controller + devicetree binding. diff --git a/drivers/staging/typec/fusb302/fusb302.c b/drivers/staging/typec/fusb302/fusb302.c index 03a3809d18f0..fc6a3cf74eb3 100644 --- a/drivers/staging/typec/fusb302/fusb302.c +++ b/drivers/staging/typec/fusb302/fusb302.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -90,11 +92,13 @@ struct fusb302_chip { struct i2c_client *i2c_client; struct tcpm_port *tcpm_port; struct tcpc_dev tcpc_dev; + struct tcpc_config tcpc_config; struct regulator *vbus; int gpio_int_n; int gpio_int_n_irq; + struct extcon_dev *extcon; struct workqueue_struct *wq; struct delayed_work bc_lvl_handler; @@ -105,6 +109,11 @@ struct fusb302_chip { /* lock for sharing chip states */ struct mutex lock; + /* psy + psy status */ + struct power_supply *psy; + u32 current_limit; + u32 supply_voltage; + /* chip status */ enum toggling_mode toggling_mode; enum src_current_status src_current_status; @@ -515,6 +524,38 @@ static int tcpm_get_vbus(struct tcpc_dev *dev) return ret; } +static int tcpm_get_current_limit(struct tcpc_dev *dev) +{ + struct fusb302_chip *chip = container_of(dev, struct fusb302_chip, + tcpc_dev); + int current_limit = 0; + unsigned long timeout; + + if (!chip->extcon) + return 0; + + /* + * USB2 Charger detection may still be in progress when we get here, + * this can take upto 600ms, wait 800ms max. + */ + timeout = jiffies + msecs_to_jiffies(800); + do { + if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_SDP) == 1) + current_limit = 500; + + if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_CDP) == 1 || + extcon_get_state(chip->extcon, EXTCON_CHG_USB_ACA) == 1) + current_limit = 1500; + + if (extcon_get_state(chip->extcon, EXTCON_CHG_USB_DCP) == 1) + current_limit = 2000; + + msleep(50); + } while (current_limit == 0 && time_before(jiffies, timeout)); + + return current_limit; +} + static int fusb302_set_cc_pull(struct fusb302_chip *chip, bool pull_up, bool pull_down) { @@ -841,11 +882,13 @@ static int tcpm_set_vbus(struct tcpc_dev *dev, bool on, bool charge) chip->vbus_on = on; fusb302_log(chip, "vbus := %s", on ? "On" : "Off"); } - if (chip->charge_on == charge) + if (chip->charge_on == charge) { fusb302_log(chip, "charge is already %s", charge ? "On" : "Off"); - else + } else { chip->charge_on = charge; + power_supply_changed(chip->psy); + } done: mutex_unlock(&chip->lock); @@ -861,6 +904,11 @@ static int tcpm_set_current_limit(struct tcpc_dev *dev, u32 max_ma, u32 mv) fusb302_log(chip, "current limit: %d ma, %d mv (not implemented)", max_ma, mv); + chip->supply_voltage = mv; + chip->current_limit = max_ma; + + power_supply_changed(chip->psy); + return 0; } @@ -1187,9 +1235,9 @@ static const struct tcpc_config fusb302_tcpc_config = { .nr_src_pdo = ARRAY_SIZE(src_pdo), .snk_pdo = snk_pdo, .nr_snk_pdo = ARRAY_SIZE(snk_pdo), - .max_snk_mv = 9000, + .max_snk_mv = 5000, .max_snk_ma = 3000, - .max_snk_mw = 27000, + .max_snk_mw = 15000, .operating_snk_mw = 2500, .type = TYPEC_PORT_DRP, .default_role = TYPEC_SINK, @@ -1198,9 +1246,9 @@ static const struct tcpc_config fusb302_tcpc_config = { static void init_tcpc_dev(struct tcpc_dev *fusb302_tcpc_dev) { - fusb302_tcpc_dev->config = &fusb302_tcpc_config; fusb302_tcpc_dev->init = tcpm_init; fusb302_tcpc_dev->get_vbus = tcpm_get_vbus; + fusb302_tcpc_dev->get_current_limit = tcpm_get_current_limit; fusb302_tcpc_dev->set_cc = tcpm_set_cc; fusb302_tcpc_dev->get_cc = tcpm_get_cc; fusb302_tcpc_dev->set_polarity = tcpm_set_polarity; @@ -1646,6 +1694,43 @@ done: return IRQ_HANDLED; } +static int fusb302_psy_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct fusb302_chip *chip = power_supply_get_drvdata(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = chip->charge_on; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = chip->supply_voltage * 1000; /* mV -> µV */ + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + val->intval = chip->current_limit * 1000; /* mA -> µA */ + break; + default: + return -ENODATA; + } + + return 0; +} + +static enum power_supply_property fusb302_psy_properties[] = { + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_MAX, +}; + +static const struct power_supply_desc fusb302_psy_desc = { + .name = "fusb302-typec-source", + .type = POWER_SUPPLY_TYPE_USB_TYPE_C, + .properties = fusb302_psy_properties, + .num_properties = ARRAY_SIZE(fusb302_psy_properties), + .get_property = fusb302_psy_get_property, +}; + static int init_gpio(struct fusb302_chip *chip) { struct device_node *node; @@ -1684,7 +1769,11 @@ static int fusb302_probe(struct i2c_client *client, { struct fusb302_chip *chip; struct i2c_adapter *adapter; + struct device *dev = &client->dev; + struct power_supply_config cfg = {}; + const char *name; int ret = 0; + u32 v; adapter = to_i2c_adapter(client->dev.parent); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { @@ -1699,8 +1788,43 @@ static int fusb302_probe(struct i2c_client *client, chip->i2c_client = client; i2c_set_clientdata(client, chip); chip->dev = &client->dev; + chip->tcpc_config = fusb302_tcpc_config; + chip->tcpc_dev.config = &chip->tcpc_config; mutex_init(&chip->lock); + if (!device_property_read_u32(dev, "fcs,max-sink-microvolt", &v)) + chip->tcpc_config.max_snk_mv = v / 1000; + + if (!device_property_read_u32(dev, "fcs,max-sink-microamp", &v)) + chip->tcpc_config.max_snk_ma = v / 1000; + + if (!device_property_read_u32(dev, "fcs,max-sink-microwatt", &v)) + chip->tcpc_config.max_snk_mw = v / 1000; + + if (!device_property_read_u32(dev, "fcs,operating-sink-microwatt", &v)) + chip->tcpc_config.operating_snk_mw = v / 1000; + + /* + * Devicetree platforms should get extcon via phandle (not yet + * supported). On ACPI platforms, we get the name from a device prop. + * This device prop is for kernel internal use only and is expected + * to be set by the platform code which also registers the i2c client + * for the fusb302. + */ + if (device_property_read_string(dev, "fcs,extcon-name", &name) == 0) { + chip->extcon = extcon_get_extcon_dev(name); + if (!chip->extcon) + return -EPROBE_DEFER; + } + + cfg.drv_data = chip; + chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg); + if (IS_ERR(chip->psy)) { + ret = PTR_ERR(chip->psy); + dev_err(chip->dev, "Error registering power-supply: %d\n", ret); + return ret; + } + ret = fusb302_debugfs_init(chip); if (ret < 0) return ret; @@ -1719,9 +1843,13 @@ static int fusb302_probe(struct i2c_client *client, goto destroy_workqueue; } - ret = init_gpio(chip); - if (ret < 0) - goto destroy_workqueue; + if (client->irq) { + chip->gpio_int_n_irq = client->irq; + } else { + ret = init_gpio(chip); + if (ret < 0) + goto destroy_workqueue; + } chip->tcpm_port = tcpm_register_port(&client->dev, &chip->tcpc_dev); if (IS_ERR(chip->tcpm_port)) { diff --git a/drivers/staging/typec/pd.h b/drivers/staging/typec/pd.h index 510ef7279900..30b32ad72acd 100644 --- a/drivers/staging/typec/pd.h +++ b/drivers/staging/typec/pd.h @@ -278,6 +278,8 @@ static inline unsigned int rdo_max_power(u32 rdo) #define PD_T_VCONN_SOURCE_ON 100 #define PD_T_SINK_REQUEST 100 /* 100 ms minimum */ #define PD_T_ERROR_RECOVERY 100 /* minimum 25 is insufficient */ +#define PD_T_SRCSWAPSTDBY 625 /* Maximum of 650ms */ +#define PD_T_NEWSRC 250 /* Maximum of 275ms */ #define PD_T_DRP_TRY 100 /* 75 - 150 ms */ #define PD_T_DRP_TRYWAIT 600 /* 400 - 800 ms */ diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c index 20eb4ebcf8c3..8af62e74d54c 100644 --- a/drivers/staging/typec/tcpm.c +++ b/drivers/staging/typec/tcpm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -89,9 +90,11 @@ S(PR_SWAP_START), \ S(PR_SWAP_SRC_SNK_TRANSITION_OFF), \ S(PR_SWAP_SRC_SNK_SOURCE_OFF), \ + S(PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED), \ S(PR_SWAP_SRC_SNK_SINK_ON), \ S(PR_SWAP_SNK_SRC_SINK_OFF), \ S(PR_SWAP_SNK_SRC_SOURCE_ON), \ + S(PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP), \ \ S(VCONN_SWAP_ACCEPT), \ S(VCONN_SWAP_SEND), \ @@ -104,10 +107,14 @@ \ S(SNK_TRY), \ S(SNK_TRY_WAIT), \ + S(SNK_TRY_WAIT_DEBOUNCE), \ + S(SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS), \ S(SRC_TRYWAIT), \ + S(SRC_TRYWAIT_DEBOUNCE), \ S(SRC_TRYWAIT_UNATTACHED), \ \ S(SRC_TRY), \ + S(SRC_TRY_WAIT), \ S(SRC_TRY_DEBOUNCE), \ S(SNK_TRYWAIT), \ S(SNK_TRYWAIT_DEBOUNCE), \ @@ -115,7 +122,8 @@ S(BIST_RX), \ \ S(ERROR_RECOVERY), \ - S(ERROR_RECOVERY_WAIT_OFF) + S(PORT_RESET), \ + S(PORT_RESET_WAIT_OFF) #define GENERATE_ENUM(e) e #define GENERATE_STRING(s) #s @@ -196,6 +204,7 @@ struct tcpm_port { bool attached; bool connected; + enum typec_port_type port_type; bool vbus_present; bool vbus_never_low; bool vbus_source; @@ -230,6 +239,7 @@ struct tcpm_port { struct mutex swap_lock; /* swap command lock */ bool swap_pending; + bool non_pd_role_swap; struct completion swap_complete; int swap_status; @@ -281,6 +291,9 @@ struct tcpm_port { struct typec_altmode *partner_altmode[SVID_DISCOVERY_MAX]; struct typec_altmode *port_altmode[SVID_DISCOVERY_MAX]; + /* Deadline in jiffies to exit src_try_wait state */ + unsigned long max_wait; + #ifdef CONFIG_DEBUG_FS struct dentry *dentry; struct mutex logbuffer_lock; /* log buffer access lock */ @@ -325,19 +338,26 @@ struct pd_rx_event { (tcpm_cc_is_audio((port)->cc2) && tcpm_cc_is_open((port)->cc1))) #define tcpm_try_snk(port) \ - ((port)->try_snk_count == 0 && (port)->try_role == TYPEC_SINK) + ((port)->try_snk_count == 0 && (port)->try_role == TYPEC_SINK && \ + (port)->port_type == TYPEC_PORT_DRP) #define tcpm_try_src(port) \ - ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE) + ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE && \ + (port)->port_type == TYPEC_PORT_DRP) static enum tcpm_state tcpm_default_state(struct tcpm_port *port) { - if (port->try_role == TYPEC_SINK) - return SNK_UNATTACHED; - else if (port->try_role == TYPEC_SOURCE) - return SRC_UNATTACHED; - else if (port->tcpc->config->default_role == TYPEC_SINK) + if (port->port_type == TYPEC_PORT_DRP) { + if (port->try_role == TYPEC_SINK) + return SNK_UNATTACHED; + else if (port->try_role == TYPEC_SOURCE) + return SRC_UNATTACHED; + else if (port->tcpc->config->default_role == TYPEC_SINK) + return SNK_UNATTACHED; + /* Fall through to return SRC_UNATTACHED */ + } else if (port->port_type == TYPEC_PORT_UFP) { return SNK_UNATTACHED; + } return SRC_UNATTACHED; } @@ -369,6 +389,7 @@ static bool tcpm_log_full(struct tcpm_port *port) (port->logbuffer_head + 1) % LOG_BUFFER_ENTRIES; } +__printf(2, 0) static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args) { char tmpbuffer[LOG_BUFFER_ENTRY_SIZE]; @@ -415,6 +436,7 @@ abort: mutex_unlock(&port->logbuffer_lock); } +__printf(2, 3) static void tcpm_log(struct tcpm_port *port, const char *fmt, ...) { va_list args; @@ -430,6 +452,7 @@ static void tcpm_log(struct tcpm_port *port, const char *fmt, ...) va_end(args); } +__printf(2, 3) static void tcpm_log_force(struct tcpm_port *port, const char *fmt, ...) { va_list args; @@ -546,7 +569,9 @@ static void tcpm_debugfs_exit(struct tcpm_port *port) #else +__printf(2, 3) static void tcpm_log(const struct tcpm_port *port, const char *fmt, ...) { } +__printf(2, 3) static void tcpm_log_force(struct tcpm_port *port, const char *fmt, ...) { } static void tcpm_log_source_caps(struct tcpm_port *port) { } static int tcpm_debugfs_init(const struct tcpm_port *port) { return 0; } @@ -660,7 +685,10 @@ static u32 tcpm_get_current_limit(struct tcpm_port *port) break; case TYPEC_CC_RP_DEF: default: - limit = 0; + if (port->tcpc->get_current_limit) + limit = port->tcpc->get_current_limit(port->tcpc); + else + limit = 0; break; } @@ -1015,8 +1043,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt, if (port->data_role == TYPEC_DEVICE && port->nr_snk_vdo) { for (i = 0; i < port->nr_snk_vdo; i++) - response[i + 1] - = cpu_to_le32(port->snk_vdo[i]); + response[i + 1] = port->snk_vdo[i]; rlen = port->nr_snk_vdo + 1; } break; @@ -1367,6 +1394,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, tcpm_set_current_limit(port, port->current_limit, port->supply_voltage); + port->explicit_contract = true; tcpm_set_state(port, SNK_READY, 0); } else { /* @@ -1377,7 +1405,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, SNK_TRANSITION_SINK_VBUS, 0); } break; - case PR_SWAP_SRC_SNK_SOURCE_OFF: + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: tcpm_set_state(port, PR_SWAP_SRC_SNK_SINK_ON, 0); break; case PR_SWAP_SNK_SRC_SINK_OFF: @@ -1451,7 +1479,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, tcpm_set_state(port, SOFT_RESET, 0); break; case PD_CTRL_DR_SWAP: - if (port->typec_caps.type != TYPEC_PORT_DRP) { + if (port->port_type != TYPEC_PORT_DRP) { tcpm_queue_message(port, PD_MSG_CTRL_REJECT); break; } @@ -1471,7 +1499,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, } break; case PD_CTRL_PR_SWAP: - if (port->typec_caps.type != TYPEC_PORT_DRP) { + if (port->port_type != TYPEC_PORT_DRP) { tcpm_queue_message(port, PD_MSG_CTRL_REJECT); break; } @@ -1846,7 +1874,7 @@ static bool tcpm_start_drp_toggling(struct tcpm_port *port) int ret; if (port->tcpc->start_drp_toggling && - port->typec_caps.type == TYPEC_PORT_DRP) { + port->port_type == TYPEC_PORT_DRP) { tcpm_log_force(port, "Start DRP toggling"); ret = port->tcpc->start_drp_toggling(port->tcpc, tcpm_rp_cc(port)); @@ -2099,10 +2127,16 @@ static inline enum tcpm_state ready_state(struct tcpm_port *port) static inline enum tcpm_state unattached_state(struct tcpm_port *port) { - if (port->pwr_role == TYPEC_SOURCE) + if (port->port_type == TYPEC_PORT_DRP) { + if (port->pwr_role == TYPEC_SOURCE) + return SRC_UNATTACHED; + else + return SNK_UNATTACHED; + } else if (port->port_type == TYPEC_PORT_DFP) { return SRC_UNATTACHED; - else - return SNK_UNATTACHED; + } + + return SNK_UNATTACHED; } static void tcpm_check_send_discover(struct tcpm_port *port) @@ -2119,13 +2153,29 @@ static void tcpm_swap_complete(struct tcpm_port *port, int result) if (port->swap_pending) { port->swap_status = result; port->swap_pending = false; + port->non_pd_role_swap = false; complete(&port->swap_complete); } } +static enum typec_pwr_opmode tcpm_get_pwr_opmode(enum typec_cc_status cc) +{ + switch (cc) { + case TYPEC_CC_RP_1_5: + return TYPEC_PWR_MODE_1_5A; + case TYPEC_CC_RP_3_0: + return TYPEC_PWR_MODE_3_0A; + case TYPEC_CC_RP_DEF: + default: + return TYPEC_PWR_MODE_USB; + } +} + static void run_state_machine(struct tcpm_port *port) { int ret; + enum typec_pwr_opmode opmode; + unsigned int msecs; port->enter_state = port->state; switch (port->state) { @@ -2133,14 +2183,15 @@ static void run_state_machine(struct tcpm_port *port) break; /* SRC states */ case SRC_UNATTACHED: - tcpm_swap_complete(port, -ENOTCONN); + if (!port->non_pd_role_swap) + tcpm_swap_complete(port, -ENOTCONN); tcpm_src_detach(port); if (tcpm_start_drp_toggling(port)) { tcpm_set_state(port, DRP_TOGGLING, 0); break; } tcpm_set_cc(port, tcpm_rp_cc(port)); - if (port->typec_caps.type == TYPEC_PORT_DRP) + if (port->port_type == TYPEC_PORT_DRP) tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK); break; case SRC_ATTACH_WAIT: @@ -2171,25 +2222,43 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, SNK_TRY_WAIT, PD_T_DRP_TRY); break; case SNK_TRY_WAIT: + if (tcpm_port_is_sink(port)) { + tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE, 0); + } else { + tcpm_set_state(port, SRC_TRYWAIT, 0); + port->max_wait = 0; + } + break; + case SNK_TRY_WAIT_DEBOUNCE: + tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS, + PD_T_PD_DEBOUNCE); + break; + case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS: if (port->vbus_present && tcpm_port_is_sink(port)) { tcpm_set_state(port, SNK_ATTACHED, 0); - break; + } else { + tcpm_set_state(port, SRC_TRYWAIT, 0); + port->max_wait = 0; } - if (!tcpm_port_is_sink(port)) { - tcpm_set_state(port, SRC_TRYWAIT, - PD_T_PD_DEBOUNCE); - break; - } - /* No vbus, cc state is sink or open */ - tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED, PD_T_DRP_TRYWAIT); break; case SRC_TRYWAIT: tcpm_set_cc(port, tcpm_rp_cc(port)); - if (!port->vbus_present && tcpm_port_is_source(port)) - tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE); - else + if (port->max_wait == 0) { + port->max_wait = jiffies + + msecs_to_jiffies(PD_T_DRP_TRY); tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED, PD_T_DRP_TRY); + } else { + if (time_is_after_jiffies(port->max_wait)) + tcpm_set_state(port, SRC_TRYWAIT_UNATTACHED, + jiffies_to_msecs(port->max_wait - + jiffies)); + else + tcpm_set_state(port, SNK_UNATTACHED, 0); + } + break; + case SRC_TRYWAIT_DEBOUNCE: + tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE); break; case SRC_TRYWAIT_UNATTACHED: tcpm_set_state(port, SNK_UNATTACHED, 0); @@ -2201,7 +2270,8 @@ static void run_state_machine(struct tcpm_port *port) ret < 0 ? 0 : PD_T_PS_SOURCE_ON); break; case SRC_STARTUP: - typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_USB); + opmode = tcpm_get_pwr_opmode(tcpm_rp_cc(port)); + typec_set_pwr_opmode(port->typec_port, opmode); port->pwr_opmode = TYPEC_PWR_MODE_USB; port->caps_count = 0; port->message_id = 0; @@ -2262,8 +2332,8 @@ static void run_state_machine(struct tcpm_port *port) #endif port->try_src_count = 0; + tcpm_swap_complete(port, 0); tcpm_typec_connect(port); - tcpm_check_send_discover(port); /* * 6.3.5 @@ -2273,14 +2343,11 @@ static void run_state_machine(struct tcpm_port *port) * - The system is not operating in PD mode * or * - Both partners are connected using a Type-C connector - * XXX How do we know that ? + * + * There is no actual need to send PD messages since the local + * port type-c and the spec does not clearly say whether PD is + * possible when type-c is connected to Type-A/B */ - if (port->pwr_opmode == TYPEC_PWR_MODE_PD && - !port->op_vsafe5v) { - tcpm_pd_send_control(port, PD_CTRL_PING); - tcpm_set_state_cond(port, SRC_READY, - PD_T_SOURCE_ACTIVITY); - } break; case SRC_WAIT_NEW_CAPABILITIES: /* Nothing to do... */ @@ -2288,14 +2355,15 @@ static void run_state_machine(struct tcpm_port *port) /* SNK states */ case SNK_UNATTACHED: - tcpm_swap_complete(port, -ENOTCONN); + if (!port->non_pd_role_swap) + tcpm_swap_complete(port, -ENOTCONN); tcpm_snk_detach(port); if (tcpm_start_drp_toggling(port)) { tcpm_set_state(port, DRP_TOGGLING, 0); break; } tcpm_set_cc(port, TYPEC_CC_RD); - if (port->typec_caps.type == TYPEC_PORT_DRP) + if (port->port_type == TYPEC_PORT_DRP) tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC); break; case SNK_ATTACH_WAIT: @@ -2320,39 +2388,52 @@ static void run_state_machine(struct tcpm_port *port) 0); else /* Wait for VBUS, but not forever */ - tcpm_set_state(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON); + tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON); break; case SRC_TRY: port->try_src_count++; tcpm_set_cc(port, tcpm_rp_cc(port)); - tcpm_set_state(port, SNK_TRYWAIT, PD_T_DRP_TRY); + port->max_wait = 0; + tcpm_set_state(port, SRC_TRY_WAIT, 0); + break; + case SRC_TRY_WAIT: + if (port->max_wait == 0) { + port->max_wait = jiffies + + msecs_to_jiffies(PD_T_DRP_TRY); + msecs = PD_T_DRP_TRY; + } else { + if (time_is_after_jiffies(port->max_wait)) + msecs = jiffies_to_msecs(port->max_wait - + jiffies); + else + msecs = 0; + } + tcpm_set_state(port, SNK_TRYWAIT, msecs); break; case SRC_TRY_DEBOUNCE: tcpm_set_state(port, SRC_ATTACHED, PD_T_PD_DEBOUNCE); break; case SNK_TRYWAIT: tcpm_set_cc(port, TYPEC_CC_RD); - tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, PD_T_CC_DEBOUNCE); + tcpm_set_state(port, SNK_TRYWAIT_VBUS, PD_T_CC_DEBOUNCE); break; - case SNK_TRYWAIT_DEBOUNCE: - if (port->vbus_present) { + case SNK_TRYWAIT_VBUS: + /* + * TCPM stays in this state indefinitely until VBUS + * is detected as long as Rp is not detected for + * more than a time period of tPDDebounce. + */ + if (port->vbus_present && tcpm_port_is_sink(port)) { tcpm_set_state(port, SNK_ATTACHED, 0); break; } - if (tcpm_port_is_disconnected(port)) { - tcpm_set_state(port, SNK_UNATTACHED, - PD_T_PD_DEBOUNCE); - break; - } - if (tcpm_port_is_source(port)) - tcpm_set_state(port, SRC_ATTACHED, 0); - /* XXX Are we supposed to stay in this state ? */ + if (!tcpm_port_is_sink(port)) + tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0); break; - case SNK_TRYWAIT_VBUS: - tcpm_set_state(port, SNK_ATTACHED, PD_T_CC_DEBOUNCE); + case SNK_TRYWAIT_DEBOUNCE: + tcpm_set_state(port, SNK_UNATTACHED, PD_T_PD_DEBOUNCE); break; - case SNK_ATTACHED: ret = tcpm_snk_attach(port); if (ret < 0) @@ -2362,7 +2443,9 @@ static void run_state_machine(struct tcpm_port *port) break; case SNK_STARTUP: /* XXX: callback into infrastructure */ - typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_USB); + opmode = tcpm_get_pwr_opmode(port->polarity ? + port->cc2 : port->cc1); + typec_set_pwr_opmode(port->typec_port, opmode); port->pwr_opmode = TYPEC_PWR_MODE_USB; port->message_id = 0; port->rx_msgid = -1; @@ -2384,7 +2467,7 @@ static void run_state_machine(struct tcpm_port *port) * see USB power delivery specification, section 8.3.3.6.1.5.1). */ tcpm_set_state(port, hard_reset_state(port), - port->typec_caps.type == TYPEC_PORT_DRP ? + port->port_type == TYPEC_PORT_DRP ? PD_T_DB_DETECT : PD_T_NO_RESPONSE); break; case SNK_DISCOVERY_DEBOUNCE: @@ -2441,12 +2524,14 @@ static void run_state_machine(struct tcpm_port *port) break; case SNK_READY: port->try_snk_count = 0; - port->explicit_contract = true; - typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_PD); - port->pwr_opmode = TYPEC_PWR_MODE_PD; + if (port->explicit_contract) { + typec_set_pwr_opmode(port->typec_port, + TYPEC_PWR_MODE_PD); + port->pwr_opmode = TYPEC_PWR_MODE_PD; + } + tcpm_swap_complete(port, 0); tcpm_typec_connect(port); - tcpm_check_send_discover(port); break; @@ -2574,7 +2659,6 @@ static void run_state_machine(struct tcpm_port *port) TYPEC_HOST); port->send_discover = true; } - tcpm_swap_complete(port, 0); tcpm_set_state(port, ready_state(port), 0); break; @@ -2602,11 +2686,17 @@ static void run_state_machine(struct tcpm_port *port) case PR_SWAP_SRC_SNK_TRANSITION_OFF: tcpm_set_vbus(port, false); port->explicit_contract = false; + /* allow time for Vbus discharge, must be < tSrcSwapStdby */ tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, - PD_T_PS_SOURCE_OFF); + PD_T_SRCSWAPSTDBY); break; case PR_SWAP_SRC_SNK_SOURCE_OFF: 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); + break; + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: /* * USB-PD standard, 6.2.1.4, Port Power Role: * "During the Power Role Swap Sequence, for the initial Source @@ -2622,7 +2712,6 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON); break; case PR_SWAP_SRC_SNK_SINK_ON: - tcpm_swap_complete(port, 0); tcpm_set_state(port, SNK_STARTUP, 0); break; case PR_SWAP_SNK_SRC_SINK_OFF: @@ -2633,6 +2722,15 @@ static void run_state_machine(struct tcpm_port *port) case PR_SWAP_SNK_SRC_SOURCE_ON: tcpm_set_cc(port, tcpm_rp_cc(port)); tcpm_set_vbus(port, true); + /* + * allow time VBUS ramp-up, must be < tNewSrc + * Also, this window overlaps with CC debounce as well. + * So, Wait for the max of two which is PD_T_NEWSRC + */ + tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP, + PD_T_NEWSRC); + break; + case PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP: /* * USB PD standard, 6.2.1.4: * "Subsequent Messages initiated by the Policy Engine, @@ -2642,7 +2740,6 @@ static void run_state_machine(struct tcpm_port *port) */ tcpm_set_pwr_role(port, TYPEC_SOURCE); tcpm_pd_send_control(port, PD_CTRL_PS_RDY); - tcpm_swap_complete(port, 0); tcpm_set_state(port, SRC_STARTUP, 0); break; @@ -2672,12 +2769,10 @@ static void run_state_machine(struct tcpm_port *port) case VCONN_SWAP_TURN_ON_VCONN: tcpm_set_vconn(port, true); tcpm_pd_send_control(port, PD_CTRL_PS_RDY); - tcpm_swap_complete(port, 0); tcpm_set_state(port, ready_state(port), 0); break; case VCONN_SWAP_TURN_OFF_VCONN: tcpm_set_vconn(port, false); - tcpm_swap_complete(port, 0); tcpm_set_state(port, ready_state(port), 0); break; @@ -2704,13 +2799,15 @@ static void run_state_machine(struct tcpm_port *port) break; case ERROR_RECOVERY: tcpm_swap_complete(port, -EPROTO); + tcpm_set_state(port, PORT_RESET, 0); + break; + case PORT_RESET: tcpm_reset_port(port); - tcpm_set_cc(port, TYPEC_CC_OPEN); - tcpm_set_state(port, ERROR_RECOVERY_WAIT_OFF, + tcpm_set_state(port, PORT_RESET_WAIT_OFF, PD_T_ERROR_RECOVERY); break; - case ERROR_RECOVERY_WAIT_OFF: + case PORT_RESET_WAIT_OFF: tcpm_set_state(port, tcpm_default_state(port), port->vbus_present ? PD_T_PS_SOURCE_OFF : 0); @@ -2799,10 +2896,12 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, tcpm_set_state(port, SRC_ATTACH_WAIT, 0); break; case SRC_ATTACHED: - if (tcpm_port_is_disconnected(port)) + case SRC_SEND_CAPABILITIES: + case SRC_READY: + if (tcpm_port_is_disconnected(port) || + !tcpm_port_is_source(port)) tcpm_set_state(port, SRC_UNATTACHED, 0); break; - case SNK_UNATTACHED: if (tcpm_port_is_sink(port)) tcpm_set_state(port, SNK_ATTACH_WAIT, 0); @@ -2869,52 +2968,43 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, case SRC_TRYWAIT: /* Hand over to state machine if needed */ if (!port->vbus_present && tcpm_port_is_source(port)) - new_state = SRC_ATTACHED; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) + tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0); + break; + case SRC_TRYWAIT_DEBOUNCE: + if (port->vbus_present || !tcpm_port_is_source(port)) tcpm_set_state(port, SRC_TRYWAIT, 0); break; - case SNK_TRY_WAIT: - if (port->vbus_present && tcpm_port_is_sink(port)) { - tcpm_set_state(port, SNK_ATTACHED, 0); - break; + case SNK_TRY_WAIT_DEBOUNCE: + if (!tcpm_port_is_sink(port)) { + port->max_wait = 0; + tcpm_set_state(port, SRC_TRYWAIT, 0); } - if (!tcpm_port_is_sink(port)) - new_state = SRC_TRYWAIT; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) - tcpm_set_state(port, SNK_TRY_WAIT, 0); break; - - case SRC_TRY: - tcpm_set_state(port, SRC_TRY_DEBOUNCE, 0); + case SRC_TRY_WAIT: + if (tcpm_port_is_source(port)) + tcpm_set_state(port, SRC_TRY_DEBOUNCE, 0); break; case SRC_TRY_DEBOUNCE: - tcpm_set_state(port, SRC_TRY, 0); + tcpm_set_state(port, SRC_TRY_WAIT, 0); break; case SNK_TRYWAIT_DEBOUNCE: - if (port->vbus_present) { - tcpm_set_state(port, SNK_ATTACHED, 0); - break; - } - if (tcpm_port_is_source(port)) { - tcpm_set_state(port, SRC_ATTACHED, 0); - break; - } - if (tcpm_port_is_disconnected(port) && - port->delayed_state != SNK_UNATTACHED) + if (tcpm_port_is_sink(port)) + tcpm_set_state(port, SNK_TRYWAIT_VBUS, 0); + break; + case SNK_TRYWAIT_VBUS: + if (!tcpm_port_is_sink(port)) tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0); break; - + case SNK_TRYWAIT: + /* Do nothing, waiting for tCCDebounce */ + break; case PR_SWAP_SNK_SRC_SINK_OFF: case PR_SWAP_SRC_SNK_TRANSITION_OFF: case PR_SWAP_SRC_SNK_SOURCE_OFF: + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: + case PR_SWAP_SNK_SRC_SOURCE_ON: /* - * CC state change is expected here; we just turned off power. + * CC state change is expected in PR_SWAP * Ignore it. */ break; @@ -2928,12 +3018,11 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, static void _tcpm_pd_vbus_on(struct tcpm_port *port) { - enum tcpm_state new_state; - tcpm_log_force(port, "VBUS on"); port->vbus_present = true; switch (port->state) { case SNK_TRANSITION_SINK_VBUS: + port->explicit_contract = true; tcpm_set_state(port, SNK_READY, 0); break; case SNK_DISCOVERY: @@ -2959,27 +3048,28 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) /* Do nothing, waiting for timeout */ break; case SRC_TRYWAIT: - /* Hand over to state machine if needed */ - if (port->delayed_state != SRC_TRYWAIT_UNATTACHED) - tcpm_set_state(port, SRC_TRYWAIT, 0); + /* Do nothing, Waiting for Rd to be detected */ break; - case SNK_TRY_WAIT: - if (tcpm_port_is_sink(port)) { - tcpm_set_state(port, SNK_ATTACHED, 0); - break; - } - if (!tcpm_port_is_sink(port)) - new_state = SRC_TRYWAIT; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) - tcpm_set_state(port, SNK_TRY_WAIT, 0); + case SRC_TRYWAIT_DEBOUNCE: + tcpm_set_state(port, SRC_TRYWAIT, 0); + break; + case SNK_TRY_WAIT_DEBOUNCE: + /* Do nothing, waiting for PD_DEBOUNCE to do be done */ break; case SNK_TRYWAIT: - tcpm_set_state(port, SNK_TRYWAIT_VBUS, 0); + /* Do nothing, waiting for tCCDebounce */ + break; + case SNK_TRYWAIT_VBUS: + if (tcpm_port_is_sink(port)) + tcpm_set_state(port, SNK_ATTACHED, 0); + break; + case SNK_TRYWAIT_DEBOUNCE: + /* Do nothing, waiting for Rp */ + break; + case SRC_TRY_WAIT: + case SRC_TRY_DEBOUNCE: + /* Do nothing, waiting for sink detection */ break; - default: break; } @@ -2987,8 +3077,6 @@ static void _tcpm_pd_vbus_on(struct tcpm_port *port) static void _tcpm_pd_vbus_off(struct tcpm_port *port) { - enum tcpm_state new_state; - tcpm_log_force(port, "VBUS off"); port->vbus_present = false; port->vbus_never_low = false; @@ -3008,25 +3096,15 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) case SRC_TRYWAIT: /* Hand over to state machine if needed */ if (tcpm_port_is_source(port)) - new_state = SRC_ATTACHED; - else - new_state = SRC_TRYWAIT_UNATTACHED; - if (new_state != port->delayed_state) - tcpm_set_state(port, SRC_TRYWAIT, 0); + tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0); break; - case SNK_TRY_WAIT: - if (!tcpm_port_is_sink(port)) - new_state = SRC_TRYWAIT; - else - new_state = SRC_TRYWAIT_UNATTACHED; - - if (new_state != port->delayed_state) - tcpm_set_state(port, SNK_TRY_WAIT, 0); + case SNK_TRY_WAIT_DEBOUNCE: + /* Do nothing, waiting for PD_DEBOUNCE to do be done */ break; + case SNK_TRYWAIT: case SNK_TRYWAIT_VBUS: - tcpm_set_state(port, SNK_TRYWAIT, 0); + case SNK_TRYWAIT_DEBOUNCE: break; - case SNK_ATTACH_WAIT: tcpm_set_state(port, SNK_UNATTACHED, 0); break; @@ -3042,13 +3120,13 @@ static void _tcpm_pd_vbus_off(struct tcpm_port *port) /* Do nothing, expected */ break; - case ERROR_RECOVERY_WAIT_OFF: - tcpm_set_state(port, - port->pwr_role == TYPEC_SOURCE ? - SRC_UNATTACHED : SNK_UNATTACHED, - 0); + case PORT_RESET_WAIT_OFF: + tcpm_set_state(port, tcpm_default_state(port), 0); + break; + case SRC_TRY_WAIT: + case SRC_TRY_DEBOUNCE: + /* Do nothing, waiting for sink detection */ break; - default: if (port->pwr_role == TYPEC_SINK && port->attached) @@ -3142,7 +3220,7 @@ static int tcpm_dr_set(const struct typec_capability *cap, mutex_lock(&port->swap_lock); mutex_lock(&port->lock); - if (port->typec_caps.type != TYPEC_PORT_DRP || !port->pd_capable) { + if (port->port_type != TYPEC_PORT_DRP) { ret = -EINVAL; goto port_unlock; } @@ -3163,15 +3241,35 @@ static int tcpm_dr_set(const struct typec_capability *cap, * Reject data role swap request in this case. */ + if (!port->pd_capable) { + /* + * If the partner is not PD capable, reset the port to + * trigger a role change. This can only work if a preferred + * role is configured, and if it matches the requested role. + */ + if (port->try_role == TYPEC_NO_PREFERRED_ROLE || + port->try_role == port->pwr_role) { + ret = -EINVAL; + goto port_unlock; + } + port->non_pd_role_swap = true; + tcpm_set_state(port, PORT_RESET, 0); + } else { + tcpm_set_state(port, DR_SWAP_SEND, 0); + } + port->swap_status = 0; port->swap_pending = true; reinit_completion(&port->swap_complete); - tcpm_set_state(port, DR_SWAP_SEND, 0); mutex_unlock(&port->lock); - wait_for_completion(&port->swap_complete); + if (!wait_for_completion_timeout(&port->swap_complete, + msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT))) + ret = -ETIMEDOUT; + else + ret = port->swap_status; - ret = port->swap_status; + port->non_pd_role_swap = false; goto swap_unlock; port_unlock: @@ -3190,7 +3288,7 @@ static int tcpm_pr_set(const struct typec_capability *cap, mutex_lock(&port->swap_lock); mutex_lock(&port->lock); - if (port->typec_caps.type != TYPEC_PORT_DRP) { + if (port->port_type != TYPEC_PORT_DRP) { ret = -EINVAL; goto port_unlock; } @@ -3204,31 +3302,18 @@ static int tcpm_pr_set(const struct typec_capability *cap, goto port_unlock; } - if (!port->pd_capable) { - /* - * If the partner is not PD capable, reset the port to - * trigger a role change. This can only work if a preferred - * role is configured, and if it matches the requested role. - */ - if (port->try_role == TYPEC_NO_PREFERRED_ROLE || - port->try_role == port->pwr_role) { - ret = -EINVAL; - goto port_unlock; - } - tcpm_set_state(port, HARD_RESET_SEND, 0); - ret = 0; - goto port_unlock; - } - port->swap_status = 0; port->swap_pending = true; reinit_completion(&port->swap_complete); tcpm_set_state(port, PR_SWAP_SEND, 0); mutex_unlock(&port->lock); - wait_for_completion(&port->swap_complete); + if (!wait_for_completion_timeout(&port->swap_complete, + msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT))) + ret = -ETIMEDOUT; + else + ret = port->swap_status; - ret = port->swap_status; goto swap_unlock; port_unlock: @@ -3263,9 +3348,12 @@ static int tcpm_vconn_set(const struct typec_capability *cap, tcpm_set_state(port, VCONN_SWAP_SEND, 0); mutex_unlock(&port->lock); - wait_for_completion(&port->swap_complete); + if (!wait_for_completion_timeout(&port->swap_complete, + msecs_to_jiffies(PD_ROLE_SWAP_TIMEOUT))) + ret = -ETIMEDOUT; + else + ret = port->swap_status; - ret = port->swap_status; goto swap_unlock; port_unlock: @@ -3319,7 +3407,35 @@ static void tcpm_init(struct tcpm_port *port) * Some adapters need a clean slate at startup, and won't recover * otherwise. So do not try to be fancy and force a clean disconnect. */ - tcpm_set_state(port, ERROR_RECOVERY, 0); + tcpm_set_state(port, PORT_RESET, 0); +} + +static int tcpm_port_type_set(const struct typec_capability *cap, + enum typec_port_type type) +{ + struct tcpm_port *port = typec_cap_to_tcpm(cap); + + mutex_lock(&port->lock); + if (type == port->port_type) + goto port_unlock; + + port->port_type = type; + + if (!port->connected) { + tcpm_set_state(port, PORT_RESET, 0); + } else if (type == TYPEC_PORT_UFP) { + if (!(port->pwr_role == TYPEC_SINK && + port->data_role == TYPEC_DEVICE)) + tcpm_set_state(port, PORT_RESET, 0); + } else if (type == TYPEC_PORT_DFP) { + if (!(port->pwr_role == TYPEC_SOURCE && + port->data_role == TYPEC_HOST)) + tcpm_set_state(port, PORT_RESET, 0); + } + +port_unlock: + mutex_unlock(&port->lock); + return 0; } void tcpm_tcpc_reset(struct tcpm_port *port) @@ -3469,9 +3585,10 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) port->typec_caps.pr_set = tcpm_pr_set; port->typec_caps.vconn_set = tcpm_vconn_set; port->typec_caps.try_role = tcpm_try_role; + port->typec_caps.port_type_set = tcpm_port_type_set; port->partner_desc.identity = &port->partner_ident; - + port->port_type = tcpc->config->type; /* * TODO: * - alt_modes, set_alt_mode @@ -3485,7 +3602,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) } if (tcpc->config->alt_modes) { - struct typec_altmode_desc *paltmode = tcpc->config->alt_modes; + const struct typec_altmode_desc *paltmode = tcpc->config->alt_modes; i = 0; while (paltmode->svid && i < ARRAY_SIZE(port->port_altmode)) { diff --git a/drivers/staging/typec/tcpm.h b/drivers/staging/typec/tcpm.h index 19c307d31a5a..7e9a6b7b5cd6 100644 --- a/drivers/staging/typec/tcpm.h +++ b/drivers/staging/typec/tcpm.h @@ -34,7 +34,8 @@ enum typec_cc_polarity { }; /* Time to wait for TCPC to complete transmit */ -#define PD_T_TCPC_TX_TIMEOUT 100 +#define PD_T_TCPC_TX_TIMEOUT 100 /* in ms */ +#define PD_ROLE_SWAP_TIMEOUT (MSEC_PER_SEC * 10) enum tcpm_transmit_status { TCPC_TX_SUCCESS = 0, @@ -72,7 +73,7 @@ struct tcpc_config { enum typec_role default_role; bool try_role_hw; /* try.{src,snk} implemented in hardware */ - struct typec_altmode_desc *alt_modes; + const struct typec_altmode_desc *alt_modes; }; enum tcpc_usb_switch { @@ -108,6 +109,13 @@ struct tcpc_dev { int (*init)(struct tcpc_dev *dev); int (*get_vbus)(struct tcpc_dev *dev); + /* + * This optional callback gets called by the tcpm core when configured + * as a snk and cc=Rp-def. This allows the tcpm to provide a fallback + * current-limit detection method for the cc=Rp-def case. E.g. some + * tcpcs may include BC1.2 charger detection and use that in this case. + */ + int (*get_current_limit)(struct tcpc_dev *dev); int (*set_cc)(struct tcpc_dev *dev, enum typec_cc_status cc); int (*get_cc)(struct tcpc_dev *dev, enum typec_cc_status *cc1, enum typec_cc_status *cc2); diff --git a/drivers/staging/unisys/Documentation/overview.txt b/drivers/staging/unisys/Documentation/overview.txt index e0466bfada2f..9ab30af265a5 100644 --- a/drivers/staging/unisys/Documentation/overview.txt +++ b/drivers/staging/unisys/Documentation/overview.txt @@ -221,7 +221,7 @@ The following files exist under /sys/devices/visorbus/vbus:dev: The visorhba driver registers with visorbus as the function driver to handle virtual scsi disk devices, specified using the -VISOR_VHBA_CHANNEL_UUID type in the visorbus_register_visor_driver() +VISOR_VHBA_CHANNEL_GUID type in the visorbus_register_visor_driver() call. visorhba uses scsi_add_host() to expose a Linux block device (e.g., /sys/block/) in the guest environment for each s-Par virtual device. @@ -240,7 +240,7 @@ When compiled as a module, visorhba can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_VHBA_CHANNEL_UUID_STR + "visorbus:"+VISOR_VHBA_CHANNEL_GUID_STR i.e.: @@ -252,7 +252,7 @@ i.e.: The visornic driver registers with visorbus as the function driver to handle virtual network devices, specified using the -VISOR_VNIC_CHANNEL_UUID type in the visorbus_register_visor_driver() +VISOR_VNIC_CHANNEL_GUID type in the visorbus_register_visor_driver() call. visornic uses register_netdev() to expose a Linux device of class net (e.g., /sys/class/net/) in the guest environment for each s-Par virtual device. @@ -270,7 +270,7 @@ When compiled as a module, visornic can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_VNIC_CHANNEL_UUID_STR + "visorbus:"+VISOR_VNIC_CHANNEL_GUID_STR i.e.: @@ -282,7 +282,7 @@ i.e.: The visorinput driver registers with visorbus as the function driver to handle human input devices, specified using the -VISOR_KEYBOARD_CHANNEL_UUID and VISOR_MOUSE_CHANNEL_UUID +VISOR_KEYBOARD_CHANNEL_GUID and VISOR_MOUSE_CHANNEL_GUID types in the visorbus_register_visor_driver() call. visorinput uses input_register_device() to expose devices of class input (e.g., /sys/class/input/) for virtual keyboard and virtual mouse devices. @@ -307,8 +307,8 @@ When compiled as a module, visorinput can be autoloaded by visorbus in standard udev/systemd environments, as it includes the modules.alias definition: - "visorbus:"+VISOR_MOUSE_CHANNEL_UUID_STR - "visorbus:"+VISOR_KEYBOARD_CHANNEL_UUID_STR + "visorbus:"+VISOR_MOUSE_CHANNEL_GUID_STR + "visorbus:"+VISOR_KEYBOARD_CHANNEL_GUID_STR i.e.: diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h index 692efcb38245..2babe93631f3 100644 --- a/drivers/staging/unisys/include/channel.h +++ b/drivers/staging/unisys/include/channel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2013 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -20,87 +21,48 @@ #include #include -#define __SUPERVISOR_CHANNEL_H__ - #define SIGNATURE_16(A, B) ((A) | ((B) << 8)) #define SIGNATURE_32(A, B, C, D) \ (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) -#define SIGNATURE_64(A, B, C, D, E, F, G, H) \ - (SIGNATURE_32(A, B, C, D) | ((u64)(SIGNATURE_32(E, F, G, H)) << 32)) - -#ifndef COVER -#define COVER(v, d) ((d) * DIV_ROUND_UP(v, d)) -#endif - #define VISOR_CHANNEL_SIGNATURE SIGNATURE_32('E', 'C', 'N', 'L') +/* + * enum channel_serverstate + * @CHANNELSRV_UNINITIALIZED: Channel is in an undefined state. + * @CHANNELSRV_READY: Channel has been initialized by server. + */ enum channel_serverstate { - CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */ - CHANNELSRV_READY = 1 /* channel has been initialized by server */ + CHANNELSRV_UNINITIALIZED = 0, + CHANNELSRV_READY = 1 }; +/* + * enum channel_clientstate + * @CHANNELCLI_DETACHED: + * @CHANNELCLI_DISABLED: Client can see channel but is NOT allowed to use it + * unless given TBD* explicit request + * (should actually be < DETACHED). + * @CHANNELCLI_ATTACHING: Legacy EFI client request for EFI server to attach. + * @CHANNELCLI_ATTACHED: Idle, but client may want to use channel any time. + * @CHANNELCLI_BUSY: Client either wants to use or is using channel. + * @CHANNELCLI_OWNED: "No worries" state - client can access channel + * anytime. + */ enum channel_clientstate { CHANNELCLI_DETACHED = 0, - CHANNELCLI_DISABLED = 1, /* client can see channel but is NOT - * allowed to use it unless given TBD - * explicit request (should actually be - * < DETACHED) - */ - CHANNELCLI_ATTACHING = 2, /* legacy EFI client request - * for EFI server to attach - */ - CHANNELCLI_ATTACHED = 3, /* idle, but client may want - * to use channel any time - */ - CHANNELCLI_BUSY = 4, /* client either wants to use or is - * using channel - */ - CHANNELCLI_OWNED = 5 /* "no worries" state - client can */ - /* access channel anytime */ + CHANNELCLI_DISABLED = 1, + CHANNELCLI_ATTACHING = 2, + CHANNELCLI_ATTACHED = 3, + CHANNELCLI_BUSY = 4, + CHANNELCLI_OWNED = 5 }; -#define VISOR_CHANNEL_SERVER_READY(ch) \ - (readl(&(ch)->srv_state) == CHANNELSRV_READY) - -#define VISOR_VALID_CHANNELCLI_TRANSITION(o, n) \ - (((((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DISABLED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_DETACHED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_DETACHED)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHING)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_ATTACHED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_BUSY)) || \ - (((o) == CHANNELCLI_DETACHED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_DISABLED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_ATTACHING) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_ATTACHED) && ((n) == CHANNELCLI_OWNED)) || \ - (((o) == CHANNELCLI_BUSY) && ((n) == CHANNELCLI_OWNED)) || (0)) \ - ? (1) : (0)) - -/* Values for VISORA_CHANNEL_PROTOCOL.CliErrorBoot: */ -/* throttling invalid boot channel statetransition error due to client - * disabled - */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_DISABLED 0x01 - -/* throttling invalid boot channel statetransition error due to client - * not attached - */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_NOTATTACHED 0x02 - -/* throttling invalid boot channel statetransition error due to busy channel */ -#define VISOR_CLIERRORBOOT_THROTTLEMSG_BUSY 0x04 - -/* Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so - * that windows guest can look at the FeatureFlags in the io channel, - * and configure the windows driver to use interrupts or not based on - * this setting. This flag is set in uislib after the - * VISOR_VHBA_init_channel is called. All feature bits for all - * channels should be defined here. The io channel feature bits are - * defined right here +/* + * Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so that + * a guest can look at the FeatureFlags in the io channel, and configure the + * driver to use interrupts or not based on this setting. All feature bits for + * all channels should be defined here. The io channel feature bits are defined + * below. */ #define VISOR_DRIVER_ENABLES_INTS (0x1ULL << 1) #define VISOR_CHANNEL_IS_POLLING (0x1ULL << 3) @@ -108,171 +70,124 @@ enum channel_clientstate { #define VISOR_DRIVER_DISABLES_INTS (0x1ULL << 5) #define VISOR_DRIVER_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6) -/* Common Channel Header */ +/* + * struct channel_header - Common Channel Header + * @signature: Signature. + * @legacy_state: DEPRECATED - being replaced by. + * @header_size: sizeof(struct channel_header). + * @size: Total size of this channel in bytes. + * @features: Flags to modify behavior. + * @chtype: Channel type: data, bus, control, etc.. + * @partition_handle: ID of guest partition. + * @handle: Device number of this channel in client. + * @ch_space_offset: Offset in bytes to channel specific area. + * @version_id: Struct channel_header Version ID. + * @partition_index: Index of guest partition. + * @zone_uuid: Guid of Channel's zone. + * @cli_str_offset: Offset from channel header to null-terminated + * ClientString (0 if ClientString not present). + * @cli_state_boot: CHANNEL_CLIENTSTATE of pre-boot EFI client of this + * channel. + * @cmd_state_cli: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @cli_state_os: CHANNEL_CLIENTSTATE of Guest OS client of this channel. + * @ch_characteristic: CHANNEL_CHARACTERISTIC_. + * @cmd_state_srv: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see + * ServerStateUp, ServerStateDown, etc). + * @srv_state: CHANNEL_SERVERSTATE. + * @cli_error_boot: Bits to indicate err states for boot clients, so err + * messages can be throttled. + * @cli_error_os: Bits to indicate err states for OS clients, so err + * messages can be throttled. + * @filler: Pad out to 128 byte cacheline. + * @recover_channel: Please add all new single-byte values below here. + */ struct channel_header { - u64 signature; /* Signature */ - u32 legacy_state; /* DEPRECATED - being replaced by */ - /* SrvState, CliStateBoot, and CliStateOS below */ - u32 header_size; /* sizeof(struct channel_header) */ - u64 size; /* Total size of this channel in bytes */ - u64 features; /* Flags to modify behavior */ - uuid_le chtype; /* Channel type: data, bus, control, etc. */ - u64 partition_handle; /* ID of guest partition */ - u64 handle; /* Device number of this channel in client */ - u64 ch_space_offset; /* Offset in bytes to channel specific area */ - u32 version_id; /* struct channel_header Version ID */ - u32 partition_index; /* Index of guest partition */ - uuid_le zone_uuid; /* Guid of Channel's zone */ - u32 cli_str_offset; /* offset from channel header to - * nul-terminated ClientString (0 if - * ClientString not present) - */ - u32 cli_state_boot; /* CHANNEL_CLIENTSTATE of pre-boot - * EFI client of this channel - */ - u32 cmd_state_cli; /* CHANNEL_COMMANDSTATE (overloaded in - * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) - */ - u32 cli_state_os; /* CHANNEL_CLIENTSTATE of Guest OS - * client of this channel - */ - u32 ch_characteristic; /* CHANNEL_CHARACTERISTIC_ */ - u32 cmd_state_srv; /* CHANNEL_COMMANDSTATE (overloaded in - * Windows drivers, see ServerStateUp, - * ServerStateDown, etc) - */ - u32 srv_state; /* CHANNEL_SERVERSTATE */ - u8 cli_error_boot; /* bits to indicate err states for - * boot clients, so err messages can - * be throttled - */ - u8 cli_error_os; /* bits to indicate err states for OS - * clients, so err messages can be - * throttled - */ - u8 filler[1]; /* Pad out to 128 byte cacheline */ - /* Please add all new single-byte values below here */ + u64 signature; + u32 legacy_state; + /* SrvState, CliStateBoot, and CliStateOS below */ + u32 header_size; + u64 size; + u64 features; + guid_t chtype; + u64 partition_handle; + u64 handle; + u64 ch_space_offset; + u32 version_id; + u32 partition_index; + guid_t zone_guid; + u32 cli_str_offset; + u32 cli_state_boot; + u32 cmd_state_cli; + u32 cli_state_os; + u32 ch_characteristic; + u32 cmd_state_srv; + u32 srv_state; + u8 cli_error_boot; + u8 cli_error_os; + u8 filler[1]; u8 recover_channel; } __packed; #define VISOR_CHANNEL_ENABLE_INTS (0x1ULL << 0) -/* Subheader for the Signal Type variation of the Common Channel */ +/* + * struct signal_queue_header - Subheader for the Signal Type variation of the + * Common Channel. + * @version: SIGNAL_QUEUE_HEADER Version ID. + * @chtype: Queue type: storage, network. + * @size: Total size of this queue in bytes. + * @sig_base_offset: Offset to signal queue area. + * @features: Flags to modify behavior. + * @num_sent: Total # of signals placed in this queue. + * @num_overflows: Total # of inserts failed due to full queue. + * @signal_size: Total size of a signal for this queue. + * @max_slots: Max # of slots in queue, 1 slot is always empty. + * @max_signals: Max # of signals in queue (MaxSignalSlots-1). + * @head: Queue head signal #. + * @num_received: Total # of signals removed from this queue. + * @tail: Queue tail signal. + * @reserved1: Reserved field. + * @reserved2: Reserved field. + * @client_queue: + * @num_irq_received: Total # of Interrupts received. This is incremented by the + * ISR in the guest windows driver. + * @num_empty: Number of times that visor_signal_remove is called and + * returned Empty Status. + * @errorflags: Error bits set during SignalReinit to denote trouble with + * client's fields. + * @filler: Pad out to 64 byte cacheline. + */ struct signal_queue_header { /* 1st cache line */ - u32 version; /* SIGNAL_QUEUE_HEADER Version ID */ - u32 chtype; /* Queue type: storage, network */ - u64 size; /* Total size of this queue in bytes */ - u64 sig_base_offset; /* Offset to signal queue area */ - u64 features; /* Flags to modify behavior */ - u64 num_sent; /* Total # of signals placed in this queue */ - u64 num_overflows; /* Total # of inserts failed due to - * full queue - */ - u32 signal_size; /* Total size of a signal for this queue */ - u32 max_slots; /* Max # of slots in queue, 1 slot is - * always empty - */ - u32 max_signals; /* Max # of signals in queue - * (MaxSignalSlots-1) - */ - u32 head; /* Queue head signal # */ + u32 version; + u32 chtype; + u64 size; + u64 sig_base_offset; + u64 features; + u64 num_sent; + u64 num_overflows; + u32 signal_size; + u32 max_slots; + u32 max_signals; + u32 head; /* 2nd cache line */ - u64 num_received; /* Total # of signals removed from this queue */ - u32 tail; /* Queue tail signal */ - u32 reserved1; /* Reserved field */ - u64 reserved2; /* Reserved field */ + u64 num_received; + u32 tail; + u32 reserved1; + u64 reserved2; u64 client_queue; - u64 num_irq_received; /* Total # of Interrupts received. This - * is incremented by the ISR in the - * guest windows driver - */ - u64 num_empty; /* Number of times that visor_signal_remove - * is called and returned Empty Status. - */ - u32 errorflags; /* Error bits set during SignalReinit - * to denote trouble with client's - * fields - */ - u8 filler[12]; /* Pad out to 64 byte cacheline */ + u64 num_irq_received; + u64 num_empty; + u32 errorflags; + u8 filler[12]; } __packed; -/* Generic function useful for validating any type of channel when it is - * received by the client that will be accessing the channel. - * Note that is only needed for callers in the EFI environment, and - * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. - */ -static inline int -visor_check_channel(struct channel_header *ch, - uuid_le expected_uuid, - char *chname, - u64 expected_min_bytes, - u32 expected_version, - u64 expected_signature) -{ - if (uuid_le_cmp(expected_uuid, NULL_UUID_LE) != 0) { - /* caller wants us to verify type GUID */ - if (uuid_le_cmp(ch->chtype, expected_uuid) != 0) { - pr_err("Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", - chname, &expected_uuid, - &expected_uuid, &ch->chtype); - return 0; - } - } - if (expected_min_bytes > 0) { /* verify channel size */ - if (ch->size < expected_min_bytes) { - pr_err("Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, &expected_uuid, - (unsigned long long)expected_min_bytes, - ch->size); - return 0; - } - } - if (expected_version > 0) { /* verify channel version */ - if (ch->version_id != expected_version) { - pr_err("Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n", - chname, &expected_uuid, - (unsigned long)expected_version, - ch->version_id); - return 0; - } - } - if (expected_signature > 0) { /* verify channel signature */ - if (ch->signature != expected_signature) { - pr_err("Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, &expected_uuid, - expected_signature, ch->signature); - return 0; - } - } - return 1; -} - -/* - * CHANNEL Guids - */ - +/* CHANNEL Guids */ /* {414815ed-c58c-11da-95a9-00e08161165f} */ -#define VISOR_VHBA_CHANNEL_UUID \ - UUID_LE(0x414815ed, 0xc58c, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vhba_channel_uuid = VISOR_VHBA_CHANNEL_UUID; -#define VISOR_VHBA_CHANNEL_UUID_STR \ +#define VISOR_VHBA_CHANNEL_GUID \ + GUID_INIT(0x414815ed, 0xc58c, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) +#define VISOR_VHBA_CHANNEL_GUID_STR \ "414815ed-c58c-11da-95a9-00e08161165f" - -/* {8cd5994d-c58e-11da-95a9-00e08161165f} */ -#define VISOR_VNIC_CHANNEL_UUID \ - UUID_LE(0x8cd5994d, 0xc58e, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vnic_channel_uuid = VISOR_VNIC_CHANNEL_UUID; -#define VISOR_VNIC_CHANNEL_UUID_STR \ - "8cd5994d-c58e-11da-95a9-00e08161165f" - -/* {72120008-4AAB-11DC-8530-444553544200} */ -#define VISOR_SIOVM_UUID \ - UUID_LE(0x72120008, 0x4AAB, 0x11DC, \ - 0x85, 0x30, 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) -static const uuid_le visor_siovm_uuid = VISOR_SIOVM_UUID; - #endif diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index c7cb3fbde7b2..a70760f48566 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -1,5 +1,19 @@ -/* Copyright (C) 2010 - 2016 UNISYS CORPORATION */ -/* All rights reserved. */ +/* + * Copyright (C) 2010 - 2016 UNISYS CORPORATION + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + */ + #ifndef __IOCHANNEL_H__ #define __IOCHANNEL_H__ @@ -7,9 +21,7 @@ * Everything needed for IOPart-GuestPart communication is define in * this file. Note: Everything is OS-independent because this file is * used by Windows, Linux and possible EFI drivers. - */ - -/* + * * Communication flow between the IOPart and GuestPart uses the channel headers * channel state. The following states are currently being used: * UNINIT(All Zeroes), CHANNEL_ATTACHING, CHANNEL_ATTACHED, CHANNEL_OPENED @@ -30,14 +42,10 @@ */ #include +#include -#include #include "channel.h" -#define VISOR_VHBA_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE -#define VISOR_VNIC_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE -#define VISOR_VSWITCH_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE - /* * Must increment these whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this @@ -47,82 +55,73 @@ */ #define VISOR_VHBA_CHANNEL_VERSIONID 2 #define VISOR_VNIC_CHANNEL_VERSIONID 2 -#define VISOR_VSWITCH_CHANNEL_VERSIONID 1 - -#define VISOR_VHBA_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, visor_vhba_channel_uuid, \ - "vhba", MIN_IO_CHANNEL_SIZE, \ - VISOR_VHBA_CHANNEL_VERSIONID, \ - VISOR_VHBA_CHANNEL_SIGNATURE)) - -#define VISOR_VNIC_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, visor_vnic_channel_uuid, \ - "vnic", MIN_IO_CHANNEL_SIZE, \ - VISOR_VNIC_CHANNEL_VERSIONID, \ - VISOR_VNIC_CHANNEL_SIGNATURE)) /* * Everything necessary to handle SCSI & NIC traffic between Guest Partition and * IO Partition is defined below. */ -/* Defines and enums. */ -#define MINNUM(a, b) (((a) < (b)) ? (a) : (b)) -#define MAXNUM(a, b) (((a) > (b)) ? (a) : (b)) - -/* Define the two queues per data channel between iopart and ioguestparts. */ -/* Used by ioguestpart to 'insert' signals to iopart. */ +/* + * Define the two queues per data channel between iopart and ioguestparts. + * IOCHAN_TO_IOPART -- used by guest to 'insert' signals to iopart. + * IOCHAN_FROM_IOPART -- used by guest to 'remove' signals from IO part. + */ #define IOCHAN_TO_IOPART 0 -/* Used by ioguestpart to 'remove' signals from iopart, same previous queue. */ #define IOCHAN_FROM_IOPART 1 /* Size of cdb - i.e., SCSI cmnd */ #define MAX_CMND_SIZE 16 -#define MAX_SENSE_SIZE 64 - -#define MAX_PHYS_INFO 64 - -/* Various types of network packets that can be sent in cmdrsp. */ -enum net_types { - NET_RCV_POST = 0, /* - * Submit buffer to hold receiving - * incoming packet - */ - /* visornic -> uisnic */ - NET_RCV, /* incoming packet received */ - /* uisnic -> visornic */ - NET_XMIT, /* for outgoing net packets */ - /* visornic -> uisnic */ - NET_XMIT_DONE, /* outgoing packet xmitted */ - /* uisnic -> visornic */ - NET_RCV_ENBDIS, /* enable/disable packet reception */ - /* visornic -> uisnic */ - NET_RCV_ENBDIS_ACK, /* acknowledge enable/disable packet */ - /* reception */ - /* uisnic -> visornic */ - NET_RCV_PROMISC, /* enable/disable promiscuous mode */ - /* visornic -> uisnic */ - NET_CONNECT_STATUS, /* - * indicate the loss or restoration of a network - * connection - */ - /* uisnic -> visornic */ - NET_MACADDR, /* - * Indicates the client has requested to update - * it's MAC address - */ - NET_MACADDR_ACK, /* MAC address acknowledge */ - +/* Unisys-specific DMA direction values */ +enum uis_dma_data_direction { + UIS_DMA_BIDIRECTIONAL = 0, + UIS_DMA_TO_DEVICE = 1, + UIS_DMA_FROM_DEVICE = 2, + UIS_DMA_NONE = 3 }; -#define ETH_MIN_DATA_SIZE 46 /* minimum eth data size */ +#define MAX_SENSE_SIZE 64 +#define MAX_PHYS_INFO 64 + +/* + * enum net_types - Various types of network packets that can be sent in cmdrsp. + * @NET_RCV_POST: Submit buffer to hold receiving incoming packet. + * @NET_RCV: visornic -> uisnic. Incoming packet received. + * @NET_XMIT: uisnic -> visornic. For outgoing packet. + * @NET_XMIT_DONE: visornic -> uisnic. Outgoing packet xmitted. + * @NET_RCV_ENBDIS: uisnic -> visornic. Enable/Disable packet reception. + * @NET_RCV_ENBDIS_ACK: visornic -> uisnic. Acknowledge enable/disable packet. + * @NET_RCV_PROMISC: uisnic -> visornic. Enable/Disable promiscuous mode. + * @NET_CONNECT_STATUS: visornic -> uisnic. Indicate the loss or restoration of + * a network connection. + * @NET_MACADDR: uisnic -> visornic. Indicates the client has requested + * to update it's MAC address. + * @NET_MACADDR_ACK: MAC address acknowledge. + */ +enum net_types { + NET_RCV_POST = 0, + NET_RCV, + NET_XMIT, + NET_XMIT_DONE, + NET_RCV_ENBDIS, + NET_RCV_ENBDIS_ACK, + /* Reception */ + NET_RCV_PROMISC, + NET_CONNECT_STATUS, + NET_MACADDR, + NET_MACADDR_ACK, +}; + +/* Minimum eth data size */ +#define ETH_MIN_DATA_SIZE 46 #define ETH_MIN_PACKET_SIZE (ETH_HLEN + ETH_MIN_DATA_SIZE) -#define VISOR_ETH_MAX_MTU 16384 /* maximum data size */ +/* Maximum data size */ +#define VISOR_ETH_MAX_MTU 16384 #ifndef MAX_MACADDR_LEN -#define MAX_MACADDR_LEN 6 /* number of bytes in MAC address */ +/* Number of bytes in MAC address */ +#define MAX_MACADDR_LEN 6 #endif /* Various types of scsi task mgmt commands. */ @@ -154,12 +153,16 @@ struct guest_phys_info { u64 length; } __packed; -#define GPI_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct guest_phys_info)) - +/* + * struct uisscsi_dest + * @channel: Bus number. + * @id: Target number. + * @lun: Logical unit number. + */ struct uisscsi_dest { - u32 channel; /* channel == bus number */ - u32 id; /* id == target number */ - u32 lun; /* lun == logical unit number */ + u32 channel; + u32 id; + u32 lun; } __packed; struct vhba_wwnn { @@ -168,61 +171,77 @@ struct vhba_wwnn { } __packed; /* - * WARNING: Values stired in this structure must contain maximum counts (not + * struct vhba_config_max + * @max_channel: Maximum channel for devices attached to this bus. + * @max_id: Maximum SCSI ID for devices attached to bus. + * @max_lun: Maximum SCSI LUN for devices attached to bus. + * @cmd_per_lun: Maximum number of outstanding commands per LUN. + * @max_io_size: Maximum io size for devices attached to this bus. Max io size + * is often determined by the resource of the hba. + * e.g Max scatter gather list length * page size / sector size. + * + * WARNING: Values stored in this structure must contain maximum counts (not * maximum values). + * + * 20 bytes */ -struct vhba_config_max {/* 20 bytes */ - u32 max_channel;/* maximum channel for devices attached to this bus */ - u32 max_id; /* maximum SCSI ID for devices attached to bus */ - u32 max_lun; /* maximum SCSI LUN for devices attached to bus */ - u32 cmd_per_lun;/* maximum number of outstanding commands per LUN */ - u32 max_io_size;/* maximum io size for devices attached to this bus */ - /* max io size is often determined by the resource of the hba. e.g */ - /* max scatter gather list length * page size / sector size */ +struct vhba_config_max { + u32 max_channel; + u32 max_id; + u32 max_lun; + u32 cmd_per_lun; + u32 max_io_size; } __packed; +/* + * struct uiscmdrsp_scsi + * + * @handle: The handle to the cmd that was received. Send it back as + * is in the rsp packet. + * @cmnd: The cdb for the command. + * @bufflen: Length of data to be transferred out or in. + * @guest_phys_entries: Number of entries in scatter-gather list. + * @struct gpi_list: Physical address information for each fragment. + * @data_dir: Direction of the data, if any. + * @struct vdest: Identifies the virtual hba, id, channel, lun to which + * cmd was sent. + * @linuxstat: Original Linux status used by Linux vdisk. + * @scsistat: The scsi status. + * @addlstat: Non-scsi status. + * @sensebuf: Sense info in case cmd failed. sensebuf holds the + * sense_data struct. See sense_data struct for more + * details. + * @*vdisk: Pointer to the vdisk to clean up when IO completes. + * @no_disk_result: Used to return no disk inquiry result when + * no_disk_result is set to 1 + * scsi.scsistat is SAM_STAT_GOOD + * scsi.addlstat is 0 + * scsi.linuxstat is SAM_STAT_GOOD + * That is, there is NO error. + */ struct uiscmdrsp_scsi { - u64 handle; /* the handle to the cmd that was received */ - /* send it back as is in the rsp packet. */ - u8 cmnd[MAX_CMND_SIZE]; /* the cdb for the command */ - u32 bufflen; /* length of data to be transferred out or in */ - u16 guest_phys_entries; /* Number of entries in scatter-gather list */ - struct guest_phys_info gpi_list[MAX_PHYS_INFO]; /* physical address - * information for each - * fragment - */ - enum dma_data_direction data_dir; /* direction of the data, if any */ - struct uisscsi_dest vdest; /* identifies the virtual hba, id, */ - /* channel, lun to which cmd was sent */ - + u64 handle; + u8 cmnd[MAX_CMND_SIZE]; + u32 bufflen; + u16 guest_phys_entries; + struct guest_phys_info gpi_list[MAX_PHYS_INFO]; + u32 data_dir; + struct uisscsi_dest vdest; /* Needed to queue the rsp back to cmd originator. */ - int linuxstat; /* original Linux status used by Linux vdisk */ - u8 scsistat; /* the scsi status */ - u8 addlstat; /* non-scsi status */ + int linuxstat; + u8 scsistat; + u8 addlstat; #define ADDL_SEL_TIMEOUT 4 - /* The following fields are need to determine the result of command. */ - u8 sensebuf[MAX_SENSE_SIZE]; /* sense info in case cmd failed; */ - /* sensebuf holds the sense_data struct; */ - /* See sense_data struct for more details. */ - void *vdisk; /* Pointer to the vdisk to clean up when IO completes. */ + u8 sensebuf[MAX_SENSE_SIZE]; + void *vdisk; int no_disk_result; - /* - * Used to return no disk inquiry result - * when no_disk_result is set to 1, - * scsi.scsistat is SAM_STAT_GOOD - * scsi.addlstat is 0 - * scsi.linuxstat is SAM_STAT_GOOD - * That is, there is NO error. - */ } __packed; /* * Defines to support sending correct inquiry result when no disk is * configured. - */ - -/* + * * From SCSI SPC2 - * * If the target is not capable of supporting a device on this logical unit, the @@ -234,22 +253,35 @@ struct uiscmdrsp_scsi { * connected to this logical unit. */ -#define DEV_NOT_CAPABLE 0x7f /* - * peripheral qualifier of 0x3 - * peripheral type of 0x1f - * specifies no device but target present - */ +/* + * Peripheral qualifier of 0x3 + * Peripheral type of 0x1f + * Specifies no device but target present + */ +#define DEV_NOT_CAPABLE 0x7f +/* + * Peripheral qualifier of 0x1 + * Peripheral type of 0 - disk + * Specifies device capable, but not present + */ +#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 +/* HiSup = 1; shows support for report luns must be returned for lun 0. */ +#define DEV_HISUPPORT 0x10 -#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 /* peripheral qualifier of 0x1 - * peripheral type of 0 - disk - * Specifies device capable, but - * not present - */ - -#define DEV_HISUPPORT 0x10 /* - * HiSup = 1; shows support for report luns - * must be returned for lun 0. - */ +/* + * Peripheral qualifier of 0x3 + * Peripheral type of 0x1f + * Specifies no device but target present + */ +#define DEV_NOT_CAPABLE 0x7f +/* + * Peripheral qualifier of 0x1 + * Peripheral type of 0 - disk + * Specifies device capable, but not present + */ +#define DEV_DISK_CAPABLE_NOT_PRESENT 0x20 +/* HiSup = 1; shows support for report luns must be returned for lun 0. */ +#define DEV_HISUPPORT 0x10 /* * NOTE: Linux code assumes inquiry contains 36 bytes. Without checking length @@ -258,11 +290,12 @@ struct uiscmdrsp_scsi { * inquiry result. */ #define NO_DISK_INQUIRY_RESULT_LEN 36 - -#define MIN_INQUIRY_RESULT_LEN 5 /* 5 bytes minimum for inquiry result */ +/* 5 bytes minimum for inquiry result */ +#define MIN_INQUIRY_RESULT_LEN 5 /* SCSI device version for no disk inquiry result */ -#define SCSI_SPC2_VER 4 /* indicates SCSI SPC2 (SPC3 is 5) */ +/* indicates SCSI SPC2 (SPC3 is 5) */ +#define SCSI_SPC2_VER 4 /* Struct and Defines to support sense information. */ @@ -297,35 +330,48 @@ struct sense_data { u8 sense_key_specific[3]; } __packed; +/* + * struct net_pkt_xmt + * @len: Full length of data in the packet. + * @num_frags: Number of fragments in frags containing data. + * @struct phys_info frags: Physical page information. + * @ethhdr: The ethernet header. + * @struct lincsum: These are needed for csum at uisnic end. + * @valid: 1 = struct is valid - else ignore. + * @hrawoffv: 1 = hwrafoff is valid. + * @nhrawoffv: 1 = nhwrafoff is valid. + * @protocol: Specifies packet protocol. + * @csum: Value used to set skb->csum at IOPart. + * @hrawoff: Value used to set skb->h.raw at IOPart. hrawoff points to + * the start of the TRANSPORT LAYER HEADER. + * @nhrawoff: Value used to set skb->nh.raw at IOPart. nhrawoff points to + * the start of the NETWORK LAYER HEADER. + * + * NOTE: + * The full packet is described in frags but the ethernet header is + * separately kept in ethhdr so that uisnic doesn't have "MAP" the + * guest memory to get to the header. uisnic needs ethhdr to + * determine how to route the packet. + */ struct net_pkt_xmt { - int len; /* full length of data in the packet */ - int num_frags; /* number of fragments in frags containing data */ - struct phys_info frags[MAX_PHYS_INFO]; /* physical page information */ - char ethhdr[ETH_HLEN]; /* the ethernet header */ + int len; + int num_frags; + struct phys_info frags[MAX_PHYS_INFO]; + char ethhdr[ETH_HLEN]; struct { - /* These are needed for csum at uisnic end */ - u8 valid; /* 1 = struct is valid - else ignore */ - u8 hrawoffv; /* 1 = hwrafoff is valid */ - u8 nhrawoffv; /* 1 = nhwrafoff is valid */ - __be16 protocol; /* specifies packet protocol */ - __wsum csum; /* value used to set skb->csum at IOPart */ - u32 hrawoff; /* value used to set skb->h.raw at IOPart */ - /* hrawoff points to the start of the TRANSPORT LAYER HEADER */ - u32 nhrawoff; /* value used to set skb->nh.raw at IOPart */ - /* nhrawoff points to the start of the NETWORK LAYER HEADER */ + u8 valid; + u8 hrawoffv; + u8 nhrawoffv; + __be16 protocol; + __wsum csum; + u32 hrawoff; + u32 nhrawoff; } lincsum; - - /* - * NOTE: - * The full packet is described in frags but the ethernet header is - * separately kept in ethhdr so that uisnic doesn't have "MAP" the - * guest memory to get to the header. uisnic needs ethhdr to - * determine how to route the packet. - */ } __packed; struct net_pkt_xmtdone { - u32 xmt_done_result; /* result of NET_XMIT */ + /* Result of NET_XMIT */ + u32 xmt_done_result; } __packed; /* @@ -341,14 +387,12 @@ struct net_pkt_xmtdone { ((VISOR_ETH_MAX_MTU + ETH_HLEN + RCVPOST_BUF_SIZE - 1) \ / RCVPOST_BUF_SIZE) -/* - * rcv buf size must be large enough to include ethernet data len + ethernet +/* rcv buf size must be large enough to include ethernet data len + ethernet * header len - we are choosing 2K because it is guaranteed to be describable. */ struct net_pkt_rcvpost { /* Physical page information for the single fragment 2K rcv buf */ struct phys_info frag; - /* * Ensures that receive posts are returned to the adapter which we sent * them from originally. @@ -358,172 +402,157 @@ struct net_pkt_rcvpost { } __packed; /* + * struct net_pkt_rcv + * @rcv_done_len: Length of the received data. + * @numrcvbufs: Contains the incoming data. Guest side MUST chain these + * together. + * @*rcvbuf: List of chained rcvbufa. Each entry is a receive buffer + * provided by NET_RCV_POST. NOTE: First rcvbuf in the + * chain will also be provided in net.buf. + * @unique_num: + * @rcvs_dropped_delta: + * * The number of rcvbuf that can be chained is based on max mtu and size of each * rcvbuf. */ struct net_pkt_rcv { - u32 rcv_done_len; /* length of received data */ - - /* - * numrcvbufs: contain the incoming data; guest side MUST chain these - * together. - */ + u32 rcv_done_len; u8 numrcvbufs; - - void *rcvbuf[MAX_NET_RCV_CHAIN]; /* list of chained rcvbufs */ - - /* Each entry is a receive buffer provided by NET_RCV_POST. */ - /* NOTE: first rcvbuf in the chain will also be provided in net.buf. */ + void *rcvbuf[MAX_NET_RCV_CHAIN]; u64 unique_num; u32 rcvs_dropped_delta; } __packed; struct net_pkt_enbdis { void *context; - u16 enable; /* 1 = enable, 0 = disable */ + /* 1 = enable, 0 = disable */ + u16 enable; } __packed; struct net_pkt_macaddr { void *context; - u8 macaddr[MAX_MACADDR_LEN]; /* 6 bytes */ + /* 6 bytes */ + u8 macaddr[MAX_MACADDR_LEN]; } __packed; -/* cmd rsp packet used for VNIC network traffic */ +/* + * struct uiscmdrsp_net - cmd rsp packet used for VNIC network traffic. + * @enum type: + * @*buf: + * @union: + * @struct xmt: Used for NET_XMIT. + * @struct xmtdone: Used for NET_XMIT_DONE. + * @struct rcvpost: Used for NET_RCV_POST. + * @struct rcv: Used for NET_RCV. + * @struct enbdis: Used for NET_RCV_ENBDIS, NET_RCV_ENBDIS_ACK, + * NET_RCV_PROMSIC, and NET_CONNECT_STATUS. + * @struct macaddr: + */ struct uiscmdrsp_net { enum net_types type; void *buf; union { - struct net_pkt_xmt xmt; /* used for NET_XMIT */ - struct net_pkt_xmtdone xmtdone; /* used for NET_XMIT_DONE */ - struct net_pkt_rcvpost rcvpost; /* used for NET_RCV_POST */ - struct net_pkt_rcv rcv; /* used for NET_RCV */ - struct net_pkt_enbdis enbdis; /* used for NET_RCV_ENBDIS, */ - /* NET_RCV_ENBDIS_ACK, */ - /* NET_RCV_PROMSIC, */ - /* and NET_CONNECT_STATUS */ + struct net_pkt_xmt xmt; + struct net_pkt_xmtdone xmtdone; + struct net_pkt_rcvpost rcvpost; + struct net_pkt_rcv rcv; + struct net_pkt_enbdis enbdis; struct net_pkt_macaddr macaddr; }; } __packed; +/* + * struct uiscmdrsp_scsitaskmgmt + * @enum tasktype: The type of task. + * @struct vdest: The vdisk for which this task mgmt is generated. + * @handle: This is a handle that the guest has saved off for its + * own use. The handle value is preserved by iopart and + * returned as in task mgmt rsp. + * @notify_handle: For Linux guests, this is a pointer to wait_queue_head + * that a thread is waiting on to see if the taskmgmt + * command has completed. When the rsp is received by + * guest, the thread receiving the response uses this to + * notify the thread waiting for taskmgmt command + * completion. It's value is preserved by iopart and + * returned as in the task mgmt rsp. + * @notifyresult_handle: This is a handle to the location in the guest where + * the result of the taskmgmt command (result field) is + * saved to when the response is handled. It's value is + * preserved by iopart and returned as is in the task mgmt + * rsp. + * @result: Result of taskmgmt command - set by IOPart. + */ struct uiscmdrsp_scsitaskmgmt { - /* The type of task. */ enum task_mgmt_types tasktype; - - /* The vdisk for which this task mgmt is generated. */ struct uisscsi_dest vdest; - - /* - * This is a handle that the guest has saved off for its own use. - * The handle value is preserved by iopart and returned as in task - * mgmt rsp. - */ u64 handle; - - /* - * For Linux guests, this is a pointer to wait_queue_head that a - * thread is waiting on to see if the taskmgmt command has completed. - * When the rsp is received by guest, the thread receiving the - * response uses this to notify the thread waiting for taskmgmt - * command completion. It's value is preserved by iopart and returned - * as in the task mgmt rsp. - */ u64 notify_handle; - - /* - * This is a handle to the location in the guest where the result of - * the taskmgmt command (result field) is saved to when the response - * is handled. It's value is preserved by iopart and returned as in - * the task mgmt rsp. - */ u64 notifyresult_handle; - - /* Result of taskmgmt command - set by IOPart - values are: */ char result; #define TASK_MGMT_FAILED 0 } __packed; -/* Used by uissd to send disk add/remove notifications to Guest. */ -/* Note that the vHba pointer is not used by the Client/Guest side. */ -struct uiscmdrsp_disknotify { - u8 add; /* 0-remove, 1-add */ - void *v_hba; /* channel info to route msg */ - u32 channel, id, lun; /* SCSI Path of Disk to added or removed */ -} __packed; - /* - * The following is used by virthba/vSCSI to send the Acquire/Release commands - * to the IOVM. + * struct uiscmdrsp_disknotify - Used by uissd to send disk add/remove + * notifications to Guest. + * @add: 0-remove, 1-add. + * @*v_hba: Channel info to route msg. + * @channel: SCSI Path of Disk to added or removed. + * @id: SCSI Path of Disk to added or removed. + * @lun: SCSI Path of Disk to added or removed. + * + * Note that the vHba pointer is not used by the Client/Guest side. */ -struct uiscmdrsp_vdiskmgmt { - /* The type of task */ - enum vdisk_mgmt_types vdisktype; - - /* The vdisk for which this task mgmt is generated */ - struct uisscsi_dest vdest; - - /* - * This is a handle that the guest has saved off for its own use. It's - * value is preserved by iopart and returned as in the task mgmt rsp. - */ - u64 handle; - - /* - * For Linux guests, this is a pointer to wait_queue_head that a - * thread is waiting on to see if the tskmgmt command has completed. - * When the rsp is received by guest, the thread receiving the - * response uses this to notify the thread waiting for taskmgmt - * command completion. It's value is preserved by iopart and returned - * as in the task mgmt rsp. - */ - u64 notify_handle; - - /* - * Handle to the location in guest where the result of the - * taskmgmt command (result field) is saved to when the response - * is handled. It's value is preserved by iopart and returned as in - * the task mgmt rsp. - */ - u64 notifyresult_handle; - - /* Result of taskmgmt command - set by IOPart - values are: */ - char result; +struct uiscmdrsp_disknotify { + u8 add; + void *v_hba; + u32 channel, id, lun; } __packed; /* Keeping cmd and rsp info in one structure for now cmd rsp packet for SCSI */ struct uiscmdrsp { char cmdtype; - -/* Describes what type of information is in the struct */ + /* Describes what type of information is in the struct */ #define CMD_SCSI_TYPE 1 #define CMD_NET_TYPE 2 #define CMD_SCSITASKMGMT_TYPE 3 #define CMD_NOTIFYGUEST_TYPE 4 -#define CMD_VDISKMGMT_TYPE 5 union { struct uiscmdrsp_scsi scsi; struct uiscmdrsp_net net; struct uiscmdrsp_scsitaskmgmt scsitaskmgmt; struct uiscmdrsp_disknotify disknotify; - struct uiscmdrsp_vdiskmgmt vdiskmgmt; }; /* Send the response when the cmd is done (scsi and scsittaskmgmt). */ void *private_data; - struct uiscmdrsp *next; /* General Purpose Queue Link */ - struct uiscmdrsp *activeQ_next; /* Pointer to the nextactive commands */ - struct uiscmdrsp *activeQ_prev; /* Pointer to the prevactive commands */ + /* General Purpose Queue Link */ + struct uiscmdrsp *next; + /* Pointer to the nextactive commands */ + struct uiscmdrsp *activeQ_next; + /* Pointer to the prevactive commands */ + struct uiscmdrsp *activeQ_prev; } __packed; +/* total = 28 bytes */ struct iochannel_vhba { - struct vhba_wwnn wwnn; /* 8 bytes */ - struct vhba_config_max max; /* 20 bytes */ -} __packed; /* total = 28 bytes */ -struct iochannel_vnic { - u8 macaddr[6]; /* 6 bytes */ - u32 num_rcv_bufs; /* 4 bytes */ - u32 mtu; /* 4 bytes */ - uuid_le zone_uuid; /* 16 bytes */ + /* 8 bytes */ + struct vhba_wwnn wwnn; + /* 20 bytes */ + struct vhba_config_max max; } __packed; + +struct iochannel_vnic { + /* 6 bytes */ + u8 macaddr[6]; + /* 4 bytes */ + u32 num_rcv_bufs; + /* 4 bytes */ + u32 mtu; + /* 16 bytes */ + guid_t zone_guid; +} __packed; + /* * This is just the header of the IO channel. It is assumed that directly after * this header there is a large region of memory which contains the command and @@ -544,10 +573,11 @@ struct visor_io_channel { } __packed; /* INLINE functions for initializing and accessing I/O data channels. */ -#define SIZEOF_CMDRSP (COVER(sizeof(struct uiscmdrsp), 64)) +#define SIZEOF_CMDRSP (64 * DIV_ROUND_UP(sizeof(struct uiscmdrsp), 64)) /* Use 4K page sizes when passing page info between Guest and IOPartition. */ #define PI_PAGE_SIZE 0x1000 #define PI_PAGE_MASK 0x0FFF -#endif /* __IOCHANNEL_H__ */ +/* __IOCHANNEL_H__ */ +#endif diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h index de0635542fbd..e4ee38c3dbe4 100644 --- a/drivers/staging/unisys/include/visorbus.h +++ b/drivers/staging/unisys/include/visorbus.h @@ -1,5 +1,4 @@ -/* visorbus.h - * +/* * Copyright (C) 2010 - 2013 UNISYS CORPORATION * All rights reserved. * @@ -23,7 +22,6 @@ * * There should be nothing in this file that is private to the visorbus * bus implementation itself. - * */ #ifndef __VISORBUS_H__ @@ -31,20 +29,16 @@ #include #include -#include -#include -#include -#include #include #include "channel.h" -struct visor_driver; struct visor_device; extern struct bus_type visorbus_type; typedef void (*visorbus_state_complete_func) (struct visor_device *dev, int status); + struct visorchipset_state { u32 created:1; u32 attached:1; @@ -54,11 +48,12 @@ struct visorchipset_state { /* Remaining bits in this 32-bit word are unused. */ }; -/** This struct describes a specific Supervisor channel, by providing its - * GUID, name, and sizes. +/* + * This struct describes a specific Supervisor channel, by providing its + * GUID, name, and sizes. */ struct visor_channeltype_descriptor { - const uuid_le guid; + const guid_t guid; const char *name; }; @@ -109,8 +104,7 @@ struct visor_driver { struct device_driver driver; }; -#define to_visor_driver(x) ((x) ? \ - (container_of(x, struct visor_driver, driver)) : (NULL)) +#define to_visor_driver(x) (container_of(x, struct visor_driver, driver)) /** * struct visor_device - A device type for things "plugged" into the visorbus @@ -125,8 +119,8 @@ struct visor_driver { * activity. * @being_removed: Indicates that the device is being removed from * the bus. Private bus driver use only. - * @visordriver_callback_lock: Used by the bus driver to lock when handling - * channel events. + * @visordriver_callback_lock: Used by the bus driver to lock when adding and + * removing devices. * @pausing: Indicates that a change towards a paused state. * is in progress. Only modified by the bus driver. * @resuming: Indicates that a change towards a running state @@ -141,37 +135,42 @@ struct visor_driver { * hypervisor requests. * @vbus_hdr_info: A pointer to header info. Private use by bus * driver. - * @partition_uuid: Indicates client partion id. This should be the + * @partition_guid: Indicates client partion id. This should be the * same across all visor_devices in the current * guest. Private use by bus driver only. */ struct visor_device { struct visorchannel *visorchannel; - uuid_le channel_type_guid; + guid_t channel_type_guid; /* These fields are for private use by the bus driver only. */ struct device device; struct list_head list_all; struct timer_list timer; bool timer_active; bool being_removed; - struct mutex visordriver_callback_lock; + struct mutex visordriver_callback_lock; /* synchronize probe/remove */ bool pausing; bool resuming; u32 chipset_bus_no; u32 chipset_dev_no; struct visorchipset_state state; - uuid_le inst; + guid_t inst; u8 *name; struct controlvm_message_header *pending_msg_hdr; void *vbus_hdr_info; - uuid_le partition_uuid; + guid_t partition_guid; struct dentry *debugfs_dir; struct dentry *debugfs_client_bus_info; }; #define to_visor_device(x) container_of(x, struct visor_device, device) +int visor_check_channel(struct channel_header *ch, struct device *dev, + const guid_t *expected_uuid, char *chname, + u64 expected_min_bytes, u32 expected_version, + u64 expected_signature); + int visorbus_register_visor_driver(struct visor_driver *drv); void visorbus_unregister_visor_driver(struct visor_driver *drv); int visorbus_read_channel(struct visor_device *dev, @@ -183,7 +182,8 @@ int visorbus_write_channel(struct visor_device *dev, int visorbus_enable_channel_interrupts(struct visor_device *dev); void visorbus_disable_channel_interrupts(struct visor_device *dev); -/* Levels of severity for diagnostic events, in order from lowest severity to +/* + * Levels of severity for diagnostic events, in order from lowest severity to * highest (i.e. fatal errors are the most severe, and should always be logged, * but info events rarely need to be logged except during debugging). The * values DIAG_SEVERITY_ENUM_BEGIN and DIAG_SEVERITY_ENUM_END are not valid @@ -207,7 +207,7 @@ int visorchannel_signalremove(struct visorchannel *channel, u32 queue, int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg); bool visorchannel_signalempty(struct visorchannel *channel, u32 queue); -uuid_le visorchannel_get_uuid(struct visorchannel *channel); +const guid_t *visorchannel_get_guid(struct visorchannel *channel); #define BUS_ROOT_DEVICE UINT_MAX struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, diff --git a/drivers/staging/unisys/visorbus/Makefile b/drivers/staging/unisys/visorbus/Makefile index f3730d8c953e..784cdc1f9d6a 100644 --- a/drivers/staging/unisys/visorbus/Makefile +++ b/drivers/staging/unisys/visorbus/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for Unisys visorbus # diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h index ed045eff0e33..32ff5c1bb6ba 100644 --- a/drivers/staging/unisys/visorbus/controlvmchannel.h +++ b/drivers/staging/unisys/visorbus/controlvmchannel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -19,60 +20,55 @@ #include "channel.h" /* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ -#define VISOR_CONTROLVM_CHANNEL_UUID \ - UUID_LE(0x2b3c2d10, 0x7ef5, 0x4ad8, \ - 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) +#define VISOR_CONTROLVM_CHANNEL_GUID \ + GUID_INIT(0x2b3c2d10, 0x7ef5, 0x4ad8, \ + 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) -#define VISOR_CONTROLVM_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE #define CONTROLVM_MESSAGE_MAX 64 -/* Must increment this whenever you insert or delete fields within - * this channel struct. Also increment whenever you change the meaning - * of fields within this channel struct so as to break pre-existing - * software. Note that you can usually add fields to the END of the - * channel struct withOUT needing to increment this. +/* + * Must increment this whenever you insert or delete fields within this channel + * struct. Also increment whenever you change the meaning of fields within this + * channel struct so as to break pre-existing software. Note that you can + * usually add fields to the END of the channel struct withOUT needing to + * increment this. */ #define VISOR_CONTROLVM_CHANNEL_VERSIONID 1 -#define VISOR_CONTROLVM_CHANNEL_OK_CLIENT(ch) \ - (visor_check_channel(ch, \ - VISOR_CONTROLVM_CHANNEL_UUID, \ - "controlvm", \ - sizeof(struct visor_controlvm_channel), \ - VISOR_CONTROLVM_CHANNEL_VERSIONID, \ - VISOR_CONTROLVM_CHANNEL_SIGNATURE)) - /* Defines for various channel queues */ -#define CONTROLVM_QUEUE_REQUEST 0 -#define CONTROLVM_QUEUE_RESPONSE 1 -#define CONTROLVM_QUEUE_EVENT 2 -#define CONTROLVM_QUEUE_ACK 3 +#define CONTROLVM_QUEUE_REQUEST 0 +#define CONTROLVM_QUEUE_RESPONSE 1 +#define CONTROLVM_QUEUE_EVENT 2 +#define CONTROLVM_QUEUE_ACK 3 /* Max num of messages stored during IOVM creation to be reused after crash */ #define CONTROLVM_CRASHMSG_MAX 2 -struct visor_segment_state { - /* Bit 0: May enter other states */ - u16 enabled:1; - /* Bit 1: Assigned to active partition */ - u16 active:1; - /* Bit 2: Configure message sent to service/server */ - u16 alive:1; - /* Bit 3: similar to partition state ShuttingDown */ - u16 revoked:1; - /* Bit 4: memory (device/port number) has been selected by Command */ - u16 allocated:1; - /* Bit 5: has been introduced to the service/guest partition */ - u16 known:1; - /* Bit 6: service/Guest partition has responded to introduction */ - u16 ready:1; - /* Bit 7: resource is configured and operating */ - u16 operating:1; - /* Natural alignment*/ - u16 reserved:8; -/* Note: don't use high bit unless we need to switch to ushort - * which is non-compliant +/* + * struct visor_segment_state + * @enabled: May enter other states. + * @active: Assigned to active partition. + * @alive: Configure message sent to service/server. + * @revoked: Similar to partition state ShuttingDown. + * @allocated: Memory (device/port number) has been selected by Command. + * @known: Has been introduced to the service/guest partition. + * @ready: Service/Guest partition has responded to introduction. + * @operating: Resource is configured and operating. + * @reserved: Natural alignment. + * + * Note: Don't use high bit unless we need to switch to ushort which is + * non-compliant. */ +struct visor_segment_state { + u16 enabled:1; + u16 active:1; + u16 alive:1; + u16 revoked:1; + u16 allocated:1; + u16 known:1; + u16 ready:1; + u16 operating:1; + u16 reserved:8; } __packed; static const struct visor_segment_state segment_state_running = { @@ -87,74 +83,101 @@ static const struct visor_segment_state segment_state_standby = { 1, 1, 0, 0, 1, 1, 1, 0 }; -/* Ids for commands that may appear in either queue of a ControlVm channel. +/* + * enum controlvm_id + * @CONTROLVM_INVALID: + * @CONTROLVM_BUS_CREATE: CP --> SP, GP. + * @CONTROLVM_BUS_DESTROY: CP --> SP, GP. + * @CONTROLVM_BUS_CONFIGURE: CP --> SP. + * @CONTROLVM_BUS_CHANGESTATE: CP --> SP, GP. + * @CONTROLVM_BUS_CHANGESTATE_EVENT: SP, GP --> CP. + * @CONTROLVM_DEVICE_CREATE: CP --> SP, GP. + * @CONTROLVM_DEVICE_DESTROY: CP --> SP, GP. + * @CONTROLVM_DEVICE_CONFIGURE: CP --> SP. + * @CONTROLVM_DEVICE_CHANGESTATE: CP --> SP, GP. + * @CONTROLVM_DEVICE_CHANGESTATE_EVENT: SP, GP --> CP. + * @CONTROLVM_DEVICE_RECONFIGURE: CP --> Boot. + * @CONTROLVM_CHIPSET_INIT: CP --> SP, GP. + * @CONTROLVM_CHIPSET_STOP: CP --> SP, GP. + * @CONTROLVM_CHIPSET_READY: CP --> SP. + * @CONTROLVM_CHIPSET_SELFTEST: CP --> SP. * - * Commands that are initiated by the command partition (CP), by an IO or - * console service partition (SP), or by a guest partition (GP)are: - * - issued on the RequestQueue queue (q #0) in the ControlVm channel - * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel + * Ids for commands that may appear in either queue of a ControlVm channel. * - * Events that are initiated by an IO or console service partition (SP) or - * by a guest partition (GP) are: - * - issued on the EventQueue queue (q #2) in the ControlVm channel - * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel + * Commands that are initiated by the command partition (CP), by an IO or + * console service partition (SP), or by a guest partition (GP) are: + * - issued on the RequestQueue queue (q #0) in the ControlVm channel + * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel + * + * Events that are initiated by an IO or console service partition (SP) or + * by a guest partition (GP) are: + * - issued on the EventQueue queue (q #2) in the ControlVm channel + * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel */ enum controlvm_id { CONTROLVM_INVALID = 0, - /* SWITCH commands required Parameter: SwitchNumber */ - /* BUS commands required Parameter: BusNumber */ - CONTROLVM_BUS_CREATE = 0x101, /* CP --> SP, GP */ - CONTROLVM_BUS_DESTROY = 0x102, /* CP --> SP, GP */ - CONTROLVM_BUS_CONFIGURE = 0x104, /* CP --> SP */ - CONTROLVM_BUS_CHANGESTATE = 0x105, /* CP --> SP, GP */ - CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, /* SP, GP --> CP */ -/* DEVICE commands required Parameter: BusNumber, DeviceNumber */ - - CONTROLVM_DEVICE_CREATE = 0x201, /* CP --> SP, GP */ - CONTROLVM_DEVICE_DESTROY = 0x202, /* CP --> SP, GP */ - CONTROLVM_DEVICE_CONFIGURE = 0x203, /* CP --> SP */ - CONTROLVM_DEVICE_CHANGESTATE = 0x204, /* CP --> SP, GP */ - CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, /* SP, GP --> CP */ - CONTROLVM_DEVICE_RECONFIGURE = 0x206, /* CP --> Boot */ -/* CHIPSET commands */ - CONTROLVM_CHIPSET_INIT = 0x301, /* CP --> SP, GP */ - CONTROLVM_CHIPSET_STOP = 0x302, /* CP --> SP, GP */ - CONTROLVM_CHIPSET_READY = 0x304, /* CP --> SP */ - CONTROLVM_CHIPSET_SELFTEST = 0x305, /* CP --> SP */ - + /* + * SWITCH commands required Parameter: SwitchNumber. + * BUS commands required Parameter: BusNumber + */ + CONTROLVM_BUS_CREATE = 0x101, + CONTROLVM_BUS_DESTROY = 0x102, + CONTROLVM_BUS_CONFIGURE = 0x104, + CONTROLVM_BUS_CHANGESTATE = 0x105, + CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, + /* DEVICE commands required Parameter: BusNumber, DeviceNumber */ + CONTROLVM_DEVICE_CREATE = 0x201, + CONTROLVM_DEVICE_DESTROY = 0x202, + CONTROLVM_DEVICE_CONFIGURE = 0x203, + CONTROLVM_DEVICE_CHANGESTATE = 0x204, + CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, + CONTROLVM_DEVICE_RECONFIGURE = 0x206, + /* CHIPSET commands */ + CONTROLVM_CHIPSET_INIT = 0x301, + CONTROLVM_CHIPSET_STOP = 0x302, + CONTROLVM_CHIPSET_READY = 0x304, + CONTROLVM_CHIPSET_SELFTEST = 0x305, }; +/* + * struct irq_info + * @reserved1: Natural alignment purposes + * @recv_irq_handle: Specifies interrupt handle. It is used to retrieve the + * corresponding interrupt pin from Monitor; and the interrupt + * pin is used to connect to the corresponding interrupt. + * Used by IOPart-GP only. + * @recv_irq_vector: Specifies interrupt vector. It, interrupt pin, and shared + * are used to connect to the corresponding interrupt. + * Used by IOPart-GP only. + * @recv_irq_shared: Specifies if the recvInterrupt is shared. It, interrupt + * pin and vector are used to connect to 0 = not shared; + * 1 = shared the corresponding interrupt. + * Used by IOPart-GP only. + * @reserved: Natural alignment purposes + */ struct irq_info { u64 reserved1; - - /* specifies interrupt handle. It is used to retrieve the - * corresponding interrupt pin from Monitor; and the - * interrupt pin is used to connect to the corresponding - * interrupt. Used by IOPart-GP only. - */ u64 recv_irq_handle; - - /* specifies interrupt vector. It, interrupt pin, and shared are - * used to connect to the corresponding interrupt. Used by - * IOPart-GP only. - */ u32 recv_irq_vector; - - /* specifies if the recvInterrupt is shared. It, interrupt pin - * and vector are used to connect to 0 = not shared; 1 = shared. - * the corresponding interrupt. Used by IOPart-GP only. - */ u8 recv_irq_shared; - u8 reserved[3]; /* Natural alignment purposes */ + u8 reserved[3]; } __packed; +/* + * struct efi_visor_indication + * @boot_to_fw_ui: Stop in UEFI UI + * @clear_nvram: Clear NVRAM + * @clear_cmos: Clear CMOS + * @boot_to_tool: Run install tool + * @reserved: Natural alignment + */ struct efi_visor_indication { - u64 boot_to_fw_ui:1; /* Bit 0: Stop in uefi ui */ - u64 clear_nvram:1; /* Bit 1: Clear NVRAM */ - u64 clear_cmos:1; /* Bit 2: Clear CMOS */ - u64 boot_to_tool:1; /* Bit 3: Run install tool */ - /* remaining bits are available */ - u64 reserved:60; /* Natural alignment */ + u64 boot_to_fw_ui:1; + u64 clear_nvram:1; + u64 clear_cmos:1; + u64 boot_to_tool:1; + /* Remaining bits are available */ + u64 reserved:60; } __packed; enum visor_chipset_feature { @@ -162,182 +185,248 @@ enum visor_chipset_feature { VISOR_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002, }; -/* This is the common structure that is at the beginning of every - * ControlVm message (both commands and responses) in any ControlVm - * queue. Commands are easily distinguished from responses by - * looking at the flags.response field. +/* + * struct controlvm_message_header + * @id: See CONTROLVM_ID. + * @message_size: Includes size of this struct + size of message. + * @segment_index: Index of segment containing Vm message/information. + * @completion_status: Error status code or result of message completion. + * @struct flags: + * @failed: =1 in a response to signify failure. + * @response_expected: =1 in all messages that expect a response. + * @server: =1 in all bus & device-related messages where the + * message receiver is to act as the bus or device + * server. + * @test_message: =1 for testing use only (Control and Command + * ignore this). + * @partial_completion: =1 if there are forthcoming responses/acks + * associated with this message. + * @preserve: =1 this is to let us know to preserve channel + * contents. + * @writer_in_diag: =1 the DiagWriter is active in the Diagnostic + * Partition. + * @reserve: Natural alignment. + * @reserved: Natural alignment. + * @message_handle: Identifies the particular message instance. + * @payload_vm_offset: Offset of payload area from start of this instance. + * @payload_max_bytes: Maximum bytes allocated in payload area of ControlVm + * segment. + * @payload_bytes: Actual number of bytes of payload area to copy between + * IO/Command. If non-zero, there is a payload to copy. + * + * This is the common structure that is at the beginning of every + * ControlVm message (both commands and responses) in any ControlVm + * queue. Commands are easily distinguished from responses by + * looking at the flags.response field. */ struct controlvm_message_header { - u32 id; /* See CONTROLVM_ID. */ - /* For requests, indicates the message type. */ - /* For responses, indicates the type of message we are responding to. */ - - /* Includes size of this struct + size of message */ + u32 id; + /* + * For requests, indicates the message type. For responses, indicates + * the type of message we are responding to. + */ u32 message_size; - /* Index of segment containing Vm message/information */ u32 segment_index; - /* Error status code or result of message completion */ u32 completion_status; struct { - /* =1 in a response to signify failure */ u32 failed:1; - /* =1 in all messages that expect a response */ u32 response_expected:1; - /* =1 in all bus & device-related messages where the message - * receiver is to act as the bus or device server - */ u32 server:1; - /* =1 for testing use only (Control and Command ignore this */ u32 test_message:1; - /* =1 if there are forthcoming responses/acks associated - * with this message - */ u32 partial_completion:1; - /* =1 this is to let us know to preserve channel contents */ u32 preserve:1; - /* =1 the DiagWriter is active in the Diagnostic Partition */ u32 writer_in_diag:1; - /* Natural alignment */ u32 reserve:25; } __packed flags; - /* Natural alignment */ u32 reserved; - /* Identifies the particular message instance */ u64 message_handle; - /* request instances with the corresponding response instance. */ - /* Offset of payload area from start of this instance */ u64 payload_vm_offset; - /* Maximum bytes allocated in payload area of ControlVm segment */ u32 payload_max_bytes; - /* Actual number of bytes of payload area to copy between IO/Command */ u32 payload_bytes; - /* if non-zero, there is a payload to copy. */ } __packed; +/* + * struct controlvm_packet_device_create - For CONTROLVM_DEVICE_CREATE + * @bus_no: Bus # (0..n-1) from the msg receiver's end. + * @dev_no: Bus-relative (0..n-1) device number. + * @channel_addr: Guest physical address of the channel, which can be + * dereferenced by the receiver of this ControlVm command. + * @channel_bytes: Specifies size of the channel in bytes. + * @data_type_uuid: Specifies format of data in channel. + * @dev_inst_uuid: Instance guid for the device. + * @irq_info intr: Specifies interrupt information. + */ struct controlvm_packet_device_create { - u32 bus_no; /* bus # (0..n-1) from the msg receiver's end */ - u32 dev_no; /* bus-relative (0..n-1) device number */ - /* Guest physical address of the channel, which can be dereferenced by - * the receiver of this ControlVm command - */ - u64 channel_addr; - u64 channel_bytes; /* specifies size of the channel in bytes */ - uuid_le data_type_uuid; /* specifies format of data in channel */ - uuid_le dev_inst_uuid; /* instance guid for the device */ - struct irq_info intr; /* specifies interrupt information */ -} __packed; /* for CONTROLVM_DEVICE_CREATE */ - -struct controlvm_packet_device_configure { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - /* Control uses header SegmentIndex field to access bus number... */ - u32 dev_no; /* bus-relative (0..n-1) device number */ -} __packed; /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; + u64 channel_addr; + u64 channel_bytes; + guid_t data_type_guid; + guid_t dev_inst_guid; + struct irq_info intr; +} __packed; +/* + * struct controlvm_packet_device_configure - For CONTROLVM_DEVICE_CONFIGURE + * @bus_no: Bus number (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + */ +struct controlvm_packet_device_configure { + u32 bus_no; + u32 dev_no; +} __packed; + +/* Total 128 bytes */ struct controlvm_message_device_create { struct controlvm_message_header header; struct controlvm_packet_device_create packet; -} __packed; /* total 128 bytes */ +} __packed; +/* Total 56 bytes */ struct controlvm_message_device_configure { struct controlvm_message_header header; struct controlvm_packet_device_configure packet; -} __packed; /* total 56 bytes */ +} __packed; -/* This is the format for a message in any ControlVm queue. */ +/* + * struct controlvm_message_packet - This is the format for a message in any + * ControlVm queue. + * @struct create_bus: For CONTROLVM_BUS_CREATE. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_count: Indicates the max number of devices on this bus. + * @channel_addr: Guest physical address of the channel, which can be + * dereferenced by the receiver of this ControlVM + * command. + * @channel_bytes: Size of the channel. + * @bus_data_type_uuid: Indicates format of data in bus channel. + * @bus_inst_uuid: Instance uuid for the bus. + * + * @struct destroy_bus: For CONTROLVM_BUS_DESTROY. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @reserved: Natural alignment purposes. + * + * @struct configure_bus: For CONTROLVM_BUS_CONFIGURE. + * @bus_no: Bus # (0..n-1) from the receiver's perspective. + * @reserved1: For alignment purposes. + * @guest_handle: This is used to convert guest physical address to + * physical address. + * @recv_bus_irq_handle: Specifies interrupt info. It is used by SP to + * register to receive interrupts from the CP. This + * interrupt is used for bus level notifications. + * The corresponding sendBusInterruptHandle is kept + * in CP. + * + * @struct create_device: For CONTROLVM_DEVICE_CREATE. + * + * @struct destroy_device: For CONTROLVM_DEVICE_DESTROY. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + * + * @struct configure_device: For CONTROLVM_DEVICE_CONFIGURE. + * + * @struct reconfigure_device: For CONTROLVM_DEVICE_RECONFIGURE. + * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. + * @dev_no: Bus-relative (0..n-1) device number. + * + * @struct bus_change_state: For CONTROLVM_BUS_CHANGESTATE. + * @bus_no: + * @struct state: + * @reserved: Natural alignment purposes. + * + * @struct device_change_state: For CONTROLVM_DEVICE_CHANGESTATE. + * @bus_no: + * @dev_no: + * @struct state: + * @struct flags: + * @phys_device: =1 if message is for a physical device. + * @reserved: Natural alignment. + * @reserved1: Natural alignment. + * @reserved: Natural alignment purposes. + * + * @struct device_change_state_event: For CONTROLVM_DEVICE_CHANGESTATE_EVENT. + * @bus_no: + * @dev_no: + * @struct state: + * @reserved: Natural alignment purposes. + * + * @struct init_chipset: For CONTROLVM_CHIPSET_INIT. + * @bus_count: Indicates the max number of busses. + * @switch_count: Indicates the max number of switches. + * @enum features: + * @platform_number: + * + * @struct chipset_selftest: For CONTROLVM_CHIPSET_SELFTEST. + * @options: Reserved. + * @test: Bit 0 set to run embedded selftest. + * + * @addr: A physical address of something, that can be dereferenced by the + * receiver of this ControlVm command. + * + * @handle: A handle of something (depends on command id). + */ struct controlvm_message_packet { union { struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - /* indicates the max number of devices on this bus */ u32 dev_count; - /* Guest physical address of the channel, which can be - * dereferenced by the receiver of this ControlVm command - */ u64 channel_addr; - u64 channel_bytes; /* size of the channel */ - /* indicates format of data in bus channel*/ - uuid_le bus_data_type_uuid; - uuid_le bus_inst_uuid; /* instance uuid for the bus */ - } __packed create_bus; /* for CONTROLVM_BUS_CREATE */ + u64 channel_bytes; + guid_t bus_data_type_guid; + guid_t bus_inst_guid; + } __packed create_bus; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 reserved; /* Natural alignment purposes */ - } __packed destroy_bus; /* for CONTROLVM_BUS_DESTROY */ + u32 reserved; + } __packed destroy_bus; struct { - /* bus # (0..n-1) from the receiver's perspective */ u32 bus_no; - u32 reserved1; /* for alignment purposes */ - /* This is used to convert guest physical address to physical address */ + u32 reserved1; u64 guest_handle; u64 recv_bus_irq_handle; - /* specifies interrupt info. It is used by SP - * to register to receive interrupts from the - * CP. This interrupt is used for bus level - * notifications. The corresponding - * sendBusInterruptHandle is kept in CP. - */ - } __packed configure_bus; /* for CONTROLVM_BUS_CONFIGURE */ - /* for CONTROLVM_DEVICE_CREATE */ + } __packed configure_bus; struct controlvm_packet_device_create create_device; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 dev_no; /* bus-relative (0..n-1) device # */ - } __packed destroy_device; /* for CONTROLVM_DEVICE_DESTROY */ - /* for CONTROLVM_DEVICE_CONFIGURE */ + u32 dev_no; + } __packed destroy_device; struct controlvm_packet_device_configure configure_device; struct { - /* bus # (0..n-1) from the msg receiver's perspective */ u32 bus_no; - u32 dev_no; /* bus-relative (0..n-1) device # */ + u32 dev_no; } __packed reconfigure_device; - /* for CONTROLVM_DEVICE_RECONFIGURE */ struct { u32 bus_no; struct visor_segment_state state; - u8 reserved[2]; /* Natural alignment purposes */ - } __packed bus_change_state; /* for CONTROLVM_BUS_CHANGESTATE */ + u8 reserved[2]; + } __packed bus_change_state; struct { u32 bus_no; u32 dev_no; struct visor_segment_state state; struct { - /* =1 if message is for a physical device */ u32 phys_device:1; - u32 reserved:31; /* Natural alignment */ - u32 reserved1; /* Natural alignment */ + u32 reserved:31; + u32 reserved1; } __packed flags; - u8 reserved[2]; /* Natural alignment purposes */ + u8 reserved[2]; } __packed device_change_state; - /* for CONTROLVM_DEVICE_CHANGESTATE */ struct { u32 bus_no; u32 dev_no; struct visor_segment_state state; - u8 reserved[6]; /* Natural alignment purposes */ + u8 reserved[6]; } __packed device_change_state_event; - /* for CONTROLVM_DEVICE_CHANGESTATE_EVENT */ struct { - /* indicates the max number of busses */ u32 bus_count; - /* indicates the max number of switches */ u32 switch_count; enum visor_chipset_feature features; - u32 platform_number; /* Platform Number */ - } __packed init_chipset; /* for CONTROLVM_CHIPSET_INIT */ + u32 platform_number; + } __packed init_chipset; struct { - u32 options; /* reserved */ - u32 test; /* bit 0 set to run embedded selftest */ + u32 options; + u32 test; } __packed chipset_selftest; - /* for CONTROLVM_CHIPSET_SELFTEST */ - /* a physical address of something, that can be dereferenced - * by the receiver of this ControlVm command - */ u64 addr; - /* a handle of something (depends on command id) */ u64 handle; }; } __packed; @@ -348,93 +437,139 @@ struct controlvm_message { struct controlvm_message_packet cmd; } __packed; +/* + * struct visor_controlvm_channel + * @struct header: + * @gp_controlvm: Guest phys addr of this channel. + * @gp_partition_tables: Guest phys addr of partition tables. + * @gp_diag_guest: Guest phys addr of diagnostic channel. + * @gp_boot_romdisk: Guest phys addr of (read* only) Boot + * ROM disk. + * @gp_boot_ramdisk: Guest phys addr of writable Boot RAM + * disk. + * @gp_acpi_table: Guest phys addr of acpi table. + * @gp_control_channel: Guest phys addr of control channel. + * @gp_diag_romdisk: Guest phys addr of diagnostic ROM disk. + * @gp_nvram: Guest phys addr of NVRAM channel. + * @request_payload_offset: Offset to request payload area. + * @event_payload_offset: Offset to event payload area. + * @request_payload_bytes: Bytes available in request payload area. + * @event_payload_bytes: Bytes available in event payload area. + * @control_channel_bytes: + * @nvram_channel_bytes: Bytes in PartitionNvram segment. + * @message_bytes: sizeof(CONTROLVM_MESSAGE). + * @message_count: CONTROLVM_MESSAGE_MAX. + * @gp_smbios_table: Guest phys addr of SMBIOS tables. + * @gp_physical_smbios_table: Guest phys addr of SMBIOS table. + * @gp_reserved: VISOR_MAX_GUESTS_PER_SERVICE. + * @virtual_guest_firmware_image_base: Guest physical address of EFI firmware + * image base. + * @virtual_guest_firmware_entry_point: Guest physical address of EFI firmware + * entry point. + * @virtual_guest_firmware_image_size: Guest EFI firmware image size. + * @virtual_guest_firmware_boot_base: GPA = 1MB where EFI firmware image is + * copied to. + * @virtual_guest_image_base: + * @virtual_guest_image_size: + * @prototype_control_channel_offset: + * @virtual_guest_partition_handle: + * @restore_action: Restore Action field to restore the + * guest partition. + * @dump_action: For Windows guests it shows if the + * visordisk is in dump mode. + * @nvram_fail_count: + * @saved_crash_message_count: = CONTROLVM_CRASHMSG_MAX. + * @saved_crash_message_offset: Offset to request payload area needed + * for crash dump. + * @installation_error: Type of error encountered during + * installation. + * @installation_text_id: Id of string to display. + * @installation_remaining_steps: Number of remaining installation steps + * (for progress bars). + * @tool_action: VISOR_TOOL_ACTIONS Installation Action + * field. + * @reserved: Alignment. + * @struct efi_visor_ind: + * @sp_reserved: + * @reserved2: Force signals to begin on 128-byte + * cache line. + * @struct request_queue: Guest partition uses this queue to send + * requests to Control. + * @struct response_queue: Control uses this queue to respond to + * service or guest partition request. + * @struct event_queue: Control uses this queue to send events + * to guest partition. + * @struct event_ack_queue: Service or guest partition uses this + * queue to ack Control events. + * @struct request_msg: Request fixed-size message pool - + * does not include payload. + * @struct response_msg: Response fixed-size message pool - + * does not include payload. + * @struct event_msg: Event fixed-size message pool - + * does not include payload. + * @struct event_ack_msg: Ack fixed-size message pool - + * does not include payload. + * @struct saved_crash_msg: Message stored during IOVM creation to + * be reused after crash. + */ struct visor_controlvm_channel { struct channel_header header; - u64 gp_controlvm; /* guest phys addr of this channel */ - u64 gp_partition_tables;/* guest phys addr of partition tables */ - u64 gp_diag_guest; /* guest phys addr of diagnostic channel */ - u64 gp_boot_romdisk;/* guest phys addr of (read* only) Boot ROM disk */ - u64 gp_boot_ramdisk;/* guest phys addr of writable Boot RAM disk */ - u64 gp_acpi_table; /* guest phys addr of acpi table */ - u64 gp_control_channel;/* guest phys addr of control channel */ - u64 gp_diag_romdisk;/* guest phys addr of diagnostic ROM disk */ - u64 gp_nvram; /* guest phys addr of NVRAM channel */ - u64 request_payload_offset; /* Offset to request payload area */ - u64 event_payload_offset; /* Offset to event payload area */ - /* Bytes available in request payload area */ + u64 gp_controlvm; + u64 gp_partition_tables; + u64 gp_diag_guest; + u64 gp_boot_romdisk; + u64 gp_boot_ramdisk; + u64 gp_acpi_table; + u64 gp_control_channel; + u64 gp_diag_romdisk; + u64 gp_nvram; + u64 request_payload_offset; + u64 event_payload_offset; u32 request_payload_bytes; - u32 event_payload_bytes;/* Bytes available in event payload area */ + u32 event_payload_bytes; u32 control_channel_bytes; - u32 nvram_channel_bytes; /* Bytes in PartitionNvram segment */ - u32 message_bytes; /* sizeof(CONTROLVM_MESSAGE) */ - u32 message_count; /* CONTROLVM_MESSAGE_MAX */ - u64 gp_smbios_table; /* guest phys addr of SMBIOS tables */ - u64 gp_physical_smbios_table; /* guest phys addr of SMBIOS table */ - /* VISOR_MAX_GUESTS_PER_SERVICE */ + u32 nvram_channel_bytes; + u32 message_bytes; + u32 message_count; + u64 gp_smbios_table; + u64 gp_physical_smbios_table; char gp_reserved[2688]; - - /* guest physical address of EFI firmware image base */ u64 virtual_guest_firmware_image_base; - - /* guest physical address of EFI firmware entry point */ u64 virtual_guest_firmware_entry_point; - - /* guest EFI firmware image size */ u64 virtual_guest_firmware_image_size; - - /* GPA = 1MB where EFI firmware image is copied to */ u64 virtual_guest_firmware_boot_base; u64 virtual_guest_image_base; u64 virtual_guest_image_size; u64 prototype_control_channel_offset; u64 virtual_guest_partition_handle; - /* Restore Action field to restore the guest partition */ u16 restore_action; - /* For Windows guests it shows if the visordisk is in dump mode */ u16 dump_action; u16 nvram_fail_count; - u16 saved_crash_message_count; /* = CONTROLVM_CRASHMSG_MAX */ - /* Offset to request payload area needed for crash dump */ + u16 saved_crash_message_count; u32 saved_crash_message_offset; - /* Type of error encountered during installation */ u32 installation_error; - u32 installation_text_id; /* Id of string to display */ - /* Number of remaining installation steps (for progress bars) */ + u32 installation_text_id; u16 installation_remaining_steps; - /* VISOR_TOOL_ACTIONS Installation Action field */ u8 tool_action; - u8 reserved; /* alignment */ + u8 reserved; struct efi_visor_indication efi_visor_ind; u32 sp_reserved; - /* Force signals to begin on 128-byte cache line */ u8 reserved2[28]; - /* guest partition uses this queue to send requests to Control */ struct signal_queue_header request_queue; - /* Control uses this queue to respond to service or guest - * partition requests - */ struct signal_queue_header response_queue; - /* Control uses this queue to send events to guest partition */ struct signal_queue_header event_queue; - /* Service or guest partition uses this queue to ack Control events */ struct signal_queue_header event_ack_queue; - /* Request fixed-size message pool - does not include payload */ - struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; - - /* Response fixed-size message pool - does not include payload */ - struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; - - /* Event fixed-size message pool - does not include payload */ - struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; - - /* Ack fixed-size message pool - does not include payload */ - struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; - - /* Message stored during IOVM creation to be reused after crash */ - struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; + struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; + struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; } __packed; -/* The following header will be located at the beginning of PayloadVmOffset for +/* + * struct visor_controlvm_parameters_header + * + * The following header will be located at the beginning of PayloadVmOffset for * various ControlVm commands. The receiver of a ControlVm command with a * PayloadVmOffset will dereference this address and then use connection_offset, * initiator_offset, and target_offset to get the location of UTF-8 formatted @@ -455,9 +590,10 @@ struct visor_controlvm_parameters_header { u32 client_length; u32 name_offset; u32 name_length; - uuid_le id; + guid_t id; u32 revision; - u32 reserved; /* Natural alignment */ + /* Natural alignment */ + u32 reserved; } __packed; /* General Errors------------------------------------------------------[0-99] */ @@ -467,72 +603,57 @@ struct visor_controlvm_parameters_header { #define CONTROLVM_RESP_KMALLOC_FAILED 3 #define CONTROLVM_RESP_ID_UNKNOWN 4 #define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5 - /* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */ #define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100 #define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101 - /* Maximum Limit----------------------------------------------------[200-299] */ -#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */ -#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */ +/* BUS_CREATE */ +#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 +/* DEVICE_CREATE */ +#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* Payload and Parameter Related------------------------------------[400-499] */ -#define CONTROLVM_RESP_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT, - * DEVICE_CONFIGURE - */ -#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 /* Multiple */ -#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */ -/* Specified[Packet Structure] Value-------------------------------[500-599] */ -#define CONTROLVM_RESP_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT, - * BUS_CONFIGURE, - * DEVICE_CREATE, - * DEVICE_CONFIG - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT*/ - /* DEVICE_CREATE, - * DEVICE_CONFIGURE, - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_CHANNEL_INVALID 502 /* DEVICE_CREATE, - * DEVICE_CONFIGURE - */ -/* Partition Driver Callback Interface----------------------[600-699] */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ -/* Unable to invoke VIRTPCI callback */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY - */ -/* VIRTPCI Callback returned error */ +/* SWITCH_ATTACHEXTPORT, DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_PAYLOAD_INVALID 400 +/* Multiple */ +#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 +/* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 +/* DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 +/* Specified[Packet Structure] Value--------------------------------[500-599] */ +/* SWITCH_ATTACHINTPORT */ +/* BUS_CONFIGURE, DEVICE_CREATE, DEVICE_CONFIG, DEVICE_DESTROY */ +#define CONTROLVM_RESP_BUS_INVALID 500 +/* SWITCH_ATTACHINTPORT*/ +/* DEVICE_CREATE, DEVICE_CONFIGURE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_DEVICE_INVALID 501 +/* DEVICE_CREATE, DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_CHANNEL_INVALID 502 +/* Partition Driver Callback Interface------------------------------[600-699] */ +/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 +/* Unable to invoke VIRTPCI callback. VIRTPCI Callback returned error. */ +/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ +#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 +/* Generic device callback returned error. */ +/* SWITCH_ATTACHEXTPORT, SWITCH_DETACHEXTPORT, DEVICE_CONFIGURE */ #define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606 - /* SWITCH_ATTACHEXTPORT, - * SWITCH_DETACHEXTPORT - * DEVICE_CONFIGURE - */ - -/* generic device callback returned error */ /* Bus Related------------------------------------------------------[700-799] */ -#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */ +/* BUS_DESTROY */ +#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* Channel Related--------------------------------------------------[800-899] */ -#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO, - * DEVICE_DESTROY - */ -#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */ +/* GET_CHANNELINFO, DEVICE_DESTROY */ +#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 +/* DEVICE_CREATE */ +#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* Chipset Shutdown Related---------------------------------------[1000-1099] */ #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000 #define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001 - /* Chipset Stop Related-------------------------------------------[1100-1199] */ #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100 #define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101 - /* Device Related-------------------------------------------------[1400-1499] */ #define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400 -#endif /* __CONTROLVMCHANNEL_H__ */ +/* __CONTROLVMCHANNEL_H__ */ +#endif diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h index 01d7d517dba7..27e04de14818 100644 --- a/drivers/staging/unisys/visorbus/vbuschannel.h +++ b/drivers/staging/unisys/visorbus/vbuschannel.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -15,26 +16,26 @@ #ifndef __VBUSCHANNEL_H__ #define __VBUSCHANNEL_H__ -/* The vbus channel is the channel area provided via the BUS_CREATE controlvm - * message for each virtual bus. This channel area is provided to both server - * and client ends of the bus. The channel header area is initialized by - * the server, and the remaining information is filled in by the client. - * We currently use this for the client to provide various information about - * the client devices and client drivers for the server end to see. +/* + * The vbus channel is the channel area provided via the BUS_CREATE controlvm + * message for each virtual bus. This channel area is provided to both server + * and client ends of the bus. The channel header area is initialized by + * the server, and the remaining information is filled in by the client. + * We currently use this for the client to provide various information about + * the client devices and client drivers for the server end to see. */ + #include #include #include "channel.h" /* {193b331b-c58f-11da-95a9-00e08161165f} */ -#define VISOR_VBUS_CHANNEL_UUID \ - UUID_LE(0x193b331b, 0xc58f, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID; +#define VISOR_VBUS_CHANNEL_GUID \ + GUID_INIT(0x193b331b, 0xc58f, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -#define VISOR_VBUS_CHANNEL_SIGNATURE VISOR_CHANNEL_SIGNATURE - -/* Must increment this whenever you insert or delete fields within this channel +/* + * Must increment this whenever you insert or delete fields within this channel * struct. Also increment whenever you change the meaning of fields within this * channel struct so as to break pre-existing software. Note that you can * usually add fields to the END of the channel struct withOUT needing to @@ -43,42 +44,63 @@ static const uuid_le visor_vbus_channel_uuid = VISOR_VBUS_CHANNEL_UUID; #define VISOR_VBUS_CHANNEL_VERSIONID 1 /* + * struct visor_vbus_deviceinfo + * @devtype: Short string identifying the device type. + * @drvname: Driver .sys file name. + * @infostrs: Kernel vversion. + * @reserved: Pad size to 256 bytes. + * * An array of this struct is present in the channel area for each vbus. - * (See vbuschannel.h.) - * It is filled in by the client side to provide info about the device - * and driver from the client's perspective. + * (See vbuschannel.h.). It is filled in by the client side to provide info + * about the device and driver from the client's perspective. */ struct visor_vbus_deviceinfo { - u8 devtype[16]; /* short string identifying the device type */ - u8 drvname[16]; /* driver .sys file name */ - u8 infostrs[96]; /* kernel version */ - u8 reserved[128]; /* pad size to 256 bytes */ + u8 devtype[16]; + u8 drvname[16]; + u8 infostrs[96]; + u8 reserved[128]; } __packed; +/* + * struct visor_vbus_headerinfo + * @struct_bytes: Size of this struct in bytes. + * @device_info_struct_bytes: Size of VISOR_VBUS_DEVICEINFO. + * @dev_info_count: Num of items in DevInfo member. This is the + * allocated size. + * @chp_info_offset: Byte offset from beginning of this struct to the + * ChpInfo struct. + * @bus_info_offset: Byte offset from beginning of this struct to the + * BusInfo struct. + * @dev_info_offset: Byte offset from beginning of this struct to the + * DevInfo array. + * @reserved: Natural Alignment + */ struct visor_vbus_headerinfo { - u32 struct_bytes; /* size of this struct in bytes */ - u32 device_info_struct_bytes; /* sizeof(VISOR_VBUS_DEVICEINFO) */ - u32 dev_info_count; /* num of items in DevInfo member */ - /* (this is the allocated size) */ - u32 chp_info_offset; /* byte offset from beginning of this struct */ - /* to the ChpInfo struct (below) */ - u32 bus_info_offset; /* byte offset from beginning of this struct */ - /* to the BusInfo struct (below) */ - u32 dev_info_offset; /* byte offset from beginning of this struct */ - /* to the DevInfo array (below) */ + u32 struct_bytes; + u32 device_info_struct_bytes; + u32 dev_info_count; + u32 chp_info_offset; + u32 bus_info_offset; + u32 dev_info_offset; u8 reserved[104]; } __packed; +/* + * struct visor_vbus_channel + * @channel_header: Initialized by server. + * @hdr_info: Initialized by server. + * @chp_info: Describes client chipset device and driver. + * @bus_info: Describes client bus device and driver. + * @dev_info: Describes client device and driver for each device on the + * bus. + */ struct visor_vbus_channel { - struct channel_header channel_header; /* initialized by server */ - struct visor_vbus_headerinfo hdr_info; /* initialized by server */ - /* the remainder of this channel is filled in by the client */ + struct channel_header channel_header; + struct visor_vbus_headerinfo hdr_info; + /* The remainder of this channel is filled in by the client */ struct visor_vbus_deviceinfo chp_info; - /* describes client chipset device and driver */ struct visor_vbus_deviceinfo bus_info; - /* describes client bus device and driver */ struct visor_vbus_deviceinfo dev_info[0]; - /* describes client device and driver for each device on the bus */ } __packed; #endif diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 1c785dd19ddd..2bc7ff7bb96a 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -1,5 +1,4 @@ -/* visorbus_main.c - * +/* * Copyright � 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -20,15 +19,14 @@ #include "visorbus.h" #include "visorbus_private.h" -#define MYDRVNAME "visorbus" +static const guid_t visor_vbus_channel_guid = VISOR_VBUS_CHANNEL_GUID; -/* Display string that is guaranteed to be no longer the 99 characters*/ +/* Display string that is guaranteed to be no longer the 99 characters */ #define LINESIZE 99 - -#define CURRENT_FILE_PC VISOR_BUS_PC_visorbus_main_c #define POLLJIFFIES_NORMALCHANNEL 10 -static bool initialized; /* stores whether bus_registration was successful */ +/* stores whether bus_registration was successful */ +static bool initialized; static struct dentry *visorbus_debugfs_dir; /* @@ -40,11 +38,11 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct visor_device *vdev; - uuid_le guid; + const guid_t *guid; vdev = to_visor_device(dev); - guid = visorchannel_get_uuid(vdev->visorchannel); - return sprintf(buf, "visorbus:%pUl\n", &guid); + guid = visorchannel_get_guid(vdev->visorchannel); + return sprintf(buf, "visorbus:%pUl\n", guid); } static DEVICE_ATTR_RO(modalias); @@ -53,15 +51,7 @@ static struct attribute *visorbus_dev_attrs[] = { NULL, }; -/* sysfs example for bridge-only sysfs files using device_type's */ -static const struct attribute_group visorbus_dev_group = { - .attrs = visorbus_dev_attrs, -}; - -static const struct attribute_group *visorbus_dev_groups[] = { - &visorbus_dev_group, - NULL, -}; +ATTRIBUTE_GROUPS(visorbus_dev); /* filled in with info about parent chipset driver when we register with it */ static struct visor_vbus_deviceinfo chipset_driverinfo; @@ -73,16 +63,70 @@ static LIST_HEAD(list_all_bus_instances); /* list of visor_device structs, linked via .list_all */ static LIST_HEAD(list_all_device_instances); -static int -visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) +/* + * Generic function useful for validating any type of channel when it is + * received by the client that will be accessing the channel. + * Note that is only needed for callers in the EFI environment, and + * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. + */ +int visor_check_channel(struct channel_header *ch, + struct device *dev, + const guid_t *expected_guid, + char *chname, + u64 expected_min_bytes, + u32 expected_version, + u64 expected_signature) +{ + if (!guid_is_null(expected_guid)) { + /* caller wants us to verify type GUID */ + if (!guid_equal(&ch->chtype, expected_guid)) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", + chname, expected_guid, expected_guid, + &ch->chtype); + return 0; + } + } + /* verify channel size */ + if (expected_min_bytes > 0) { + if (ch->size < expected_min_bytes) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + chname, expected_guid, + (unsigned long long)expected_min_bytes, + ch->size); + return 0; + } + } + /* verify channel version */ + if (expected_version > 0) { + if (ch->version_id != expected_version) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n", + chname, expected_guid, + (unsigned long)expected_version, + ch->version_id); + return 0; + } + } + /* verify channel signature */ + if (expected_signature > 0) { + if (ch->signature != expected_signature) { + dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n", + chname, expected_guid, expected_signature, + ch->signature); + return 0; + } + } + return 1; +} + +static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) { struct visor_device *dev; - uuid_le guid; + const guid_t *guid; dev = to_visor_device(xdev); - guid = visorchannel_get_uuid(dev->visorchannel); + guid = visorchannel_get_guid(dev->visorchannel); - return add_uevent_var(env, "MODALIAS=visorbus:%pUl", &guid); + return add_uevent_var(env, "MODALIAS=visorbus:%pUl", guid); } /* @@ -94,27 +138,21 @@ visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) * * Return: 1 iff the provided driver can control the specified device */ -static int -visorbus_match(struct device *xdev, struct device_driver *xdrv) +static int visorbus_match(struct device *xdev, struct device_driver *xdrv) { - uuid_le channel_type; + const guid_t *channel_type; int i; struct visor_device *dev; struct visor_driver *drv; dev = to_visor_device(xdev); + channel_type = visorchannel_get_guid(dev->visorchannel); drv = to_visor_driver(xdrv); - channel_type = visorchannel_get_uuid(dev->visorchannel); - if (!drv->channel_types) return 0; - for (i = 0; - (uuid_le_cmp(drv->channel_types[i].guid, NULL_UUID_LE) != 0) || - (drv->channel_types[i].name); - i++) - if (uuid_le_cmp(drv->channel_types[i].guid, - channel_type) == 0) + for (i = 0; !guid_is_null(&drv->channel_types[i].guid); i++) + if (guid_equal(&drv->channel_types[i].guid, channel_type)) return i + 1; return 0; @@ -122,7 +160,7 @@ visorbus_match(struct device *xdev, struct device_driver *xdrv) /* * This describes the TYPE of bus. - * (Don't confuse this with an INSTANCE of the bus.) + * (Don't confuse this with an INSTANCE of the bus.) */ struct bus_type visorbus_type = { .name = "visorbus", @@ -137,8 +175,7 @@ struct bus_type visorbus_type = { * involved with destroying the dev are complete * @xdev: struct device for the bus being released */ -static void -visorbus_release_busdevice(struct device *xdev) +static void visorbus_release_busdevice(struct device *xdev) { struct visor_device *dev = dev_get_drvdata(xdev); @@ -152,15 +189,11 @@ visorbus_release_busdevice(struct device *xdev) * each child device instance * @xdev: struct device for the visor device being released */ -static void -visorbus_release_device(struct device *xdev) +static void visorbus_release_device(struct device *xdev) { struct visor_device *dev = to_visor_device(xdev); - if (dev->visorchannel) { - visorchannel_destroy(dev->visorchannel); - dev->visorchannel = NULL; - } + visorchannel_destroy(dev->visorchannel); kfree(dev); } @@ -229,7 +262,7 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, struct device_driver *xdrv = dev->driver; struct visor_driver *drv = NULL; - if (!xbus || !xdrv) + if (!xdrv) return 0; i = xbus->match(dev, xdrv); if (!i) @@ -240,24 +273,16 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(typename); static struct attribute *channel_attrs[] = { - &dev_attr_physaddr.attr, - &dev_attr_nbytes.attr, - &dev_attr_clientpartition.attr, - &dev_attr_typeguid.attr, - &dev_attr_zoneguid.attr, - &dev_attr_typename.attr, - NULL + &dev_attr_physaddr.attr, + &dev_attr_nbytes.attr, + &dev_attr_clientpartition.attr, + &dev_attr_typeguid.attr, + &dev_attr_zoneguid.attr, + &dev_attr_typename.attr, + NULL }; -static struct attribute_group channel_attr_grp = { - .name = "channel", - .attrs = channel_attrs, -}; - -static const struct attribute_group *visorbus_channel_groups[] = { - &channel_attr_grp, - NULL -}; +ATTRIBUTE_GROUPS(channel); /* end implementation of specific channel attributes */ @@ -270,7 +295,8 @@ static const struct attribute_group *visorbus_channel_groups[] = { static ssize_t partition_handle_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 handle = visorchannel_get_clientpartition(vdev->visorchannel); @@ -280,16 +306,18 @@ static DEVICE_ATTR_RO(partition_handle); static ssize_t partition_guid_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); - return sprintf(buf, "{%pUb}\n", &vdev->partition_uuid); + return sprintf(buf, "{%pUb}\n", &vdev->partition_guid); } static DEVICE_ATTR_RO(partition_guid); static ssize_t partition_name_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); return sprintf(buf, "%s\n", vdev->name); @@ -298,7 +326,8 @@ static DEVICE_ATTR_RO(partition_name); static ssize_t channel_addr_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 addr = visorchannel_get_physaddr(vdev->visorchannel); @@ -308,7 +337,8 @@ static DEVICE_ATTR_RO(channel_addr); static ssize_t channel_bytes_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel); @@ -318,7 +348,8 @@ static DEVICE_ATTR_RO(channel_bytes); static ssize_t channel_id_show(struct device *dev, struct device_attribute *attr, - char *buf) { + char *buf) +{ struct visor_device *vdev = to_visor_device(dev); int len = 0; @@ -330,24 +361,17 @@ static ssize_t channel_id_show(struct device *dev, } static DEVICE_ATTR_RO(channel_id); -static struct attribute *dev_attrs[] = { - &dev_attr_partition_handle.attr, - &dev_attr_partition_guid.attr, - &dev_attr_partition_name.attr, - &dev_attr_channel_addr.attr, - &dev_attr_channel_bytes.attr, - &dev_attr_channel_id.attr, - NULL +static struct attribute *visorbus_attrs[] = { + &dev_attr_partition_handle.attr, + &dev_attr_partition_guid.attr, + &dev_attr_partition_name.attr, + &dev_attr_channel_addr.attr, + &dev_attr_channel_bytes.attr, + &dev_attr_channel_id.attr, + NULL }; -static struct attribute_group dev_attr_grp = { - .attrs = dev_attrs, -}; - -static const struct attribute_group *visorbus_groups[] = { - &dev_attr_grp, - NULL -}; +ATTRIBUTE_GROUPS(visorbus); /* * BUS debugfs entries @@ -355,6 +379,7 @@ static const struct attribute_group *visorbus_groups[] = { * define & implement display of debugfs attributes under * /sys/kernel/debug/visorbus/visorbus. */ + /* * vbuschannel_print_devinfo() - format a struct visor_vbus_deviceinfo * and write it to a seq_file @@ -365,12 +390,12 @@ static const struct attribute_group *visorbus_groups[] = { * * Reads @devInfo, and writes it in human-readable notation to @seq. */ -static void -vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, - struct seq_file *seq, int devix) +static void vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, + struct seq_file *seq, int devix) { + /* uninitialized vbus device entry */ if (!isprint(devinfo->devtype[0])) - return; /* uninitialized vbus device entry */ + return; if (devix >= 0) seq_printf(seq, "[%d]", devix); @@ -392,12 +417,11 @@ vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) { - struct visor_device *vdev = seq->private; - struct visorchannel *channel = vdev->visorchannel; - - int i; + int i = 0; unsigned long off; struct visor_vbus_deviceinfo dev_info; + struct visor_device *vdev = seq->private; + struct visorchannel *channel = vdev->visorchannel; if (!channel) return 0; @@ -406,6 +430,7 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) "Client device / client driver info for %s partition (vbus #%u):\n", ((vdev->name) ? (char *)(vdev->name) : ""), vdev->chipset_bus_no); + if (visorchannel_read(channel, offsetof(struct visor_vbus_channel, chp_info), &dev_info, sizeof(dev_info)) >= 0) @@ -414,8 +439,8 @@ static int client_bus_info_debugfs_show(struct seq_file *seq, void *v) offsetof(struct visor_vbus_channel, bus_info), &dev_info, sizeof(dev_info)) >= 0) vbuschannel_print_devinfo(&dev_info, seq, -1); + off = offsetof(struct visor_vbus_channel, dev_info); - i = 0; while (off + sizeof(dev_info) <= visorchannel_get_nbytes(channel)) { if (visorchannel_read(channel, off, &dev_info, sizeof(dev_info)) >= 0) @@ -441,8 +466,7 @@ static const struct file_operations client_bus_info_debugfs_fops = { .release = single_release, }; -static void -dev_periodic_work(unsigned long __opaque) +static void dev_periodic_work(unsigned long __opaque) { struct visor_device *dev = (struct visor_device *)__opaque; struct visor_driver *drv = to_visor_driver(dev->device.driver); @@ -451,8 +475,7 @@ dev_periodic_work(unsigned long __opaque) mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL); } -static int -dev_start_periodic_work(struct visor_device *dev) +static int dev_start_periodic_work(struct visor_device *dev) { if (dev->being_removed || dev->timer_active) return -EINVAL; @@ -464,8 +487,7 @@ dev_start_periodic_work(struct visor_device *dev) return 0; } -static void -dev_stop_periodic_work(struct visor_device *dev) +static void dev_stop_periodic_work(struct visor_device *dev) { if (!dev->timer_active) return; @@ -484,40 +506,39 @@ dev_stop_periodic_work(struct visor_device *dev) * * Return: 0 iff successful */ -static int -visordriver_remove_device(struct device *xdev) +static int visordriver_remove_device(struct device *xdev) { struct visor_device *dev; struct visor_driver *drv; dev = to_visor_device(xdev); drv = to_visor_driver(xdev->driver); + mutex_lock(&dev->visordriver_callback_lock); dev->being_removed = true; - if (drv->remove) - drv->remove(dev); + drv->remove(dev); mutex_unlock(&dev->visordriver_callback_lock); - dev_stop_periodic_work(dev); + dev_stop_periodic_work(dev); put_device(&dev->device); + return 0; } -/** +/* * visorbus_unregister_visor_driver() - unregisters the provided driver * @drv: the driver to unregister * * A visor function driver calls this function to unregister the driver, * i.e., within its module_exit function. */ -void -visorbus_unregister_visor_driver(struct visor_driver *drv) +void visorbus_unregister_visor_driver(struct visor_driver *drv) { driver_unregister(&drv->driver); } EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver); -/** +/* * visorbus_read_channel() - reads from the designated channel into * the provided buffer * @dev: the device whose channel is read from @@ -530,15 +551,14 @@ EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver); * * Return: integer indicating success (zero) or failure (non-zero) */ -int -visorbus_read_channel(struct visor_device *dev, unsigned long offset, - void *dest, unsigned long nbytes) +int visorbus_read_channel(struct visor_device *dev, unsigned long offset, + void *dest, unsigned long nbytes) { return visorchannel_read(dev->visorchannel, offset, dest, nbytes); } EXPORT_SYMBOL_GPL(visorbus_read_channel); -/** +/* * visorbus_write_channel() - writes the provided buffer into the designated * channel * @dev: the device whose channel is written to @@ -551,15 +571,14 @@ EXPORT_SYMBOL_GPL(visorbus_read_channel); * * Return: integer indicating success (zero) or failure (non-zero) */ -int -visorbus_write_channel(struct visor_device *dev, unsigned long offset, - void *src, unsigned long nbytes) +int visorbus_write_channel(struct visor_device *dev, unsigned long offset, + void *src, unsigned long nbytes) { return visorchannel_write(dev->visorchannel, offset, src, nbytes); } EXPORT_SYMBOL_GPL(visorbus_write_channel); -/** +/* * visorbus_enable_channel_interrupts() - enables interrupts on the * designated device * @dev: the device on which to enable interrupts @@ -567,8 +586,7 @@ EXPORT_SYMBOL_GPL(visorbus_write_channel); * Currently we don't yet have a real interrupt, so for now we just call the * interrupt function periodically via a timer. */ -int -visorbus_enable_channel_interrupts(struct visor_device *dev) +int visorbus_enable_channel_interrupts(struct visor_device *dev) { struct visor_driver *drv = to_visor_driver(dev->device.driver); @@ -581,13 +599,12 @@ visorbus_enable_channel_interrupts(struct visor_device *dev) } EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts); -/** +/* * visorbus_disable_channel_interrupts() - disables interrupts on the * designated device * @dev: the device on which to disable interrupts */ -void -visorbus_disable_channel_interrupts(struct visor_device *dev) +void visorbus_disable_channel_interrupts(struct visor_device *dev) { dev_stop_periodic_work(dev); } @@ -616,8 +633,7 @@ EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts); * Return: 0 if successful, otherwise the negative value returned by * device_add() indicating the reason for failure */ -static int -create_visor_device(struct visor_device *dev) +int create_visor_device(struct visor_device *dev) { int err; u32 chipset_bus_no = dev->chipset_bus_no; @@ -625,7 +641,7 @@ create_visor_device(struct visor_device *dev) mutex_init(&dev->visordriver_callback_lock); dev->device.bus = &visorbus_type; - dev->device.groups = visorbus_channel_groups; + dev->device.groups = channel_groups; device_initialize(&dev->device); dev->device.release = visorbus_release_device; /* keep a reference just for us (now 2) */ @@ -664,7 +680,10 @@ create_visor_device(struct visor_device *dev) goto err_put; list_add_tail(&dev->list_all, &list_all_device_instances); - return 0; /* success: reference kept via unmatched get_device() */ + dev->state.created = 1; + visorbus_response(dev, err, CONTROLVM_DEVICE_CREATE); + /* success: reference kept via unmatched get_device() */ + return 0; err_put: put_device(&dev->device); @@ -672,26 +691,27 @@ err_put: return err; } -static void -remove_visor_device(struct visor_device *dev) +void remove_visor_device(struct visor_device *dev) { list_del(&dev->list_all); put_device(&dev->device); device_unregister(&dev->device); + visorbus_response(dev, 0, CONTROLVM_DEVICE_DESTROY); } -static int -get_vbus_header_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info) +static int get_vbus_header_info(struct visorchannel *chan, + struct device *dev, + struct visor_vbus_headerinfo *hdr_info) { int err; if (!visor_check_channel(visorchannel_get_header(chan), - visor_vbus_channel_uuid, + dev, + &visor_vbus_channel_guid, "vbus", sizeof(struct visor_vbus_channel), VISOR_VBUS_CHANNEL_VERSIONID, - VISOR_VBUS_CHANNEL_SIGNATURE)) + VISOR_CHANNEL_SIGNATURE)) return -EINVAL; err = visorchannel_read(chan, sizeof(struct channel_header), hdr_info, @@ -722,10 +742,9 @@ get_vbus_header_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_chp_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) +static void write_vbus_chp_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info) { int off = sizeof(struct channel_header) + hdr_info->chp_info_offset; @@ -748,10 +767,9 @@ write_vbus_chp_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_bus_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) +static void write_vbus_bus_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info) { int off = sizeof(struct channel_header) + hdr_info->bus_info_offset; @@ -775,10 +793,10 @@ write_vbus_bus_info(struct visorchannel *chan, * Returns no value since this is debug information and not needed for * device functionality. */ -static void -write_vbus_dev_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info, unsigned int devix) +static void write_vbus_dev_info(struct visorchannel *chan, + struct visor_vbus_headerinfo *hdr_info, + struct visor_vbus_deviceinfo *info, + unsigned int devix) { int off = (sizeof(struct channel_header) + hdr_info->dev_info_offset) + @@ -807,14 +825,13 @@ static void bus_device_info_init( } /* - * fix_vbus_dev_info() - for a child device just created on a client bus, fill - * in information about the driver that is controlling - * this device into the appropriate slot within the - * vbus channel of the bus instance + * publish_vbus_dev_info() - for a child device just created on a client bus, + * fill in information about the driver that is + * controlling this device into the appropriate slot + * within the vbus channel of the bus instance * @visordev: struct visor_device for the desired device */ -static void -fix_vbus_dev_info(struct visor_device *visordev) +static void publish_vbus_dev_info(struct visor_device *visordev) { int i; struct visor_device *bdev; @@ -853,7 +870,6 @@ fix_vbus_dev_info(struct visor_device *visordev) bus_device_info_init(&dev_info, chan_type_name, visordrv->name); write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no); - write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo); write_vbus_bus_info(bdev->visorchannel, hdr_info, &clientbus_driverinfo); @@ -874,18 +890,14 @@ fix_vbus_dev_info(struct visor_device *visordev) * was successful with this device, otherwise a negative errno * value indicating failure reason */ -static int -visordriver_probe_device(struct device *xdev) +static int visordriver_probe_device(struct device *xdev) { int res; struct visor_driver *drv; struct visor_device *dev; - drv = to_visor_driver(xdev->driver); dev = to_visor_device(xdev); - - if (!drv->probe) - return -ENODEV; + drv = to_visor_driver(xdev->driver); mutex_lock(&dev->visordriver_callback_lock); dev->being_removed = false; @@ -894,14 +906,14 @@ visordriver_probe_device(struct device *xdev) if (res >= 0) { /* success: reference kept via unmatched get_device() */ get_device(&dev->device); - fix_vbus_dev_info(dev); + publish_vbus_dev_info(dev); } mutex_unlock(&dev->visordriver_callback_lock); return res; } -/** +/* * visorbus_register_visor_driver() - registers the provided visor driver * for handling one or more visor device * types (channel_types) @@ -952,8 +964,21 @@ visordriver_probe_device(struct device *xdev) */ int visorbus_register_visor_driver(struct visor_driver *drv) { + /* can't register on a nonexistent bus */ if (!initialized) - return -ENODEV; /* can't register on a nonexistent bus */ + return -ENODEV; + + if (!drv->probe) + return -EINVAL; + + if (!drv->remove) + return -EINVAL; + + if (!drv->pause) + return -EINVAL; + + if (!drv->resume) + return -EINVAL; drv->driver.name = drv->name; drv->driver.bus = &visorbus_type; @@ -985,8 +1010,7 @@ EXPORT_SYMBOL_GPL(visorbus_register_visor_driver); * Return: 0 for success, otherwise negative errno value indicating reason for * failure */ -static int -visorbus_create_instance(struct visor_device *dev) +int visorbus_create_instance(struct visor_device *dev) { int id = dev->chipset_bus_no; int err; @@ -1009,7 +1033,7 @@ visorbus_create_instance(struct visor_device *dev) &client_bus_info_debugfs_fops); dev_set_drvdata(&dev->device, dev); - err = get_vbus_header_info(dev->visorchannel, hdr_info); + err = get_vbus_header_info(dev->visorchannel, &dev->device, hdr_info); if (err < 0) goto err_debugfs_dir; @@ -1019,18 +1043,21 @@ visorbus_create_instance(struct visor_device *dev) list_add_tail(&dev->list_all, &list_all_bus_instances); + dev->state.created = 1; dev->vbus_hdr_info = (void *)hdr_info; write_vbus_chp_info(dev->visorchannel, hdr_info, &chipset_driverinfo); write_vbus_bus_info(dev->visorchannel, hdr_info, &clientbus_driverinfo); + visorbus_response(dev, err, CONTROLVM_BUS_CREATE); + return 0; err_debugfs_dir: debugfs_remove_recursive(dev->debugfs_dir); kfree(hdr_info); - dev_err(&dev->device, "visorbus_create_instance failed: %d\n", err); + dev_err(&dev->device, "%s failed: %d\n", __func__, err); return err; } @@ -1038,8 +1065,7 @@ err_debugfs_dir: * visorbus_remove_instance() - remove a device instance for the visorbus itself * @dev: struct visor_device indentifying the bus to remove */ -static void -visorbus_remove_instance(struct visor_device *dev) +void visorbus_remove_instance(struct visor_device *dev) { /* * Note that this will result in the release method for @@ -1049,20 +1075,17 @@ visorbus_remove_instance(struct visor_device *dev) * successfully been able to trace thru the code to see where/how * release() gets called. But I know it does. */ - if (dev->visorchannel) { - visorchannel_destroy(dev->visorchannel); - dev->visorchannel = NULL; - } + visorchannel_destroy(dev->visorchannel); kfree(dev->vbus_hdr_info); list_del(&dev->list_all); device_unregister(&dev->device); + visorbus_response(dev, 0, CONTROLVM_BUS_DESTROY); } /* * remove_all_visor_devices() - remove all child visorbus device instances */ -static void -remove_all_visor_devices(void) +static void remove_all_visor_devices(void) { struct list_head *listentry, *listtmp; @@ -1074,50 +1097,6 @@ remove_all_visor_devices(void) } } -int -visorchipset_bus_create(struct visor_device *dev) -{ - int err; - - err = visorbus_create_instance(dev); - - if (err < 0) - return err; - - visorbus_create_response(dev, err); - - return 0; -} - -void -visorchipset_bus_destroy(struct visor_device *dev) -{ - visorbus_remove_instance(dev); - visorbus_destroy_response(dev, 0); -} - -int -visorchipset_device_create(struct visor_device *dev_info) -{ - int err; - - err = create_visor_device(dev_info); - if (err < 0) - return err; - - visorbus_device_create_response(dev_info, err); - - return 0; -} - -void -visorchipset_device_destroy(struct visor_device *dev_info) -{ - remove_visor_device(dev_info); - - visorbus_device_destroy_response(dev_info, 0); -} - /* * pause_state_change_complete() - the callback function to be called by a * visorbus function driver when a @@ -1127,15 +1106,14 @@ visorchipset_device_destroy(struct visor_device *dev_info) * @status: 0 iff the pause state change completed successfully, otherwise * a negative errno value indicating the reason for failure */ -static void -pause_state_change_complete(struct visor_device *dev, int status) +static void pause_state_change_complete(struct visor_device *dev, int status) { if (!dev->pausing) return; dev->pausing = false; - - visorbus_device_pause_response(dev, status); + visorbus_device_changestate_response(dev, status, + segment_state_standby); } /* @@ -1147,8 +1125,7 @@ pause_state_change_complete(struct visor_device *dev, int status) * @status: 0 iff the resume state change completed successfully, otherwise * a negative errno value indicating the reason for failure */ -static void -resume_state_change_complete(struct visor_device *dev, int status) +static void resume_state_change_complete(struct visor_device *dev, int status) { if (!dev->resuming) return; @@ -1160,7 +1137,8 @@ resume_state_change_complete(struct visor_device *dev, int status) * which will presumably want to send some sort of response to * the initiator. */ - visorbus_device_resume_response(dev, status); + visorbus_device_changestate_response(dev, status, + segment_state_running); } /* @@ -1174,34 +1152,28 @@ resume_state_change_complete(struct visor_device *dev, int status) * via a callback function; see pause_state_change_complete() and * resume_state_change_complete(). */ -static int -visorchipset_initiate_device_pause_resume(struct visor_device *dev, - bool is_pause) +static int visorchipset_initiate_device_pause_resume(struct visor_device *dev, + bool is_pause) { int err; struct visor_driver *drv = NULL; - drv = to_visor_driver(dev->device.driver); - if (!drv) - return -ENODEV; - + /* If no driver associated with the device nothing to pause/resume */ + if (!dev->device.driver) + return 0; if (dev->pausing || dev->resuming) return -EBUSY; + drv = to_visor_driver(dev->device.driver); if (is_pause) { - if (!drv->pause) - return -EINVAL; - dev->pausing = true; err = drv->pause(dev, pause_state_change_complete); } else { - /* The vbus_dev_info structure in the channel was been - * cleared, make sure it is valid. + /* + * The vbus_dev_info structure in the channel was been cleared, + * make sure it is valid. */ - fix_vbus_dev_info(dev); - if (!drv->resume) - return -EINVAL; - + publish_vbus_dev_info(dev); dev->resuming = true; err = drv->resume(dev, resume_state_change_complete); } @@ -1209,7 +1181,7 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev, return err; } -/** +/* * visorchipset_device_pause() - start a pause operation for a visor device * @dev_info: struct visor_device identifying the device being paused * @@ -1217,13 +1189,11 @@ visorchipset_initiate_device_pause_resume(struct visor_device *dev, * that device. Success/failure result is returned asynchronously * via a callback function; see pause_state_change_complete(). */ -int -visorchipset_device_pause(struct visor_device *dev_info) +int visorchipset_device_pause(struct visor_device *dev_info) { int err; err = visorchipset_initiate_device_pause_resume(dev_info, true); - if (err < 0) { dev_info->pausing = false; return err; @@ -1232,7 +1202,7 @@ visorchipset_device_pause(struct visor_device *dev_info) return 0; } -/** +/* * visorchipset_device_resume() - start a resume operation for a visor device * @dev_info: struct visor_device identifying the device being resumed * @@ -1240,13 +1210,11 @@ visorchipset_device_pause(struct visor_device *dev_info) * that device. Success/failure result is returned asynchronously * via a callback function; see resume_state_change_complete(). */ -int -visorchipset_device_resume(struct visor_device *dev_info) +int visorchipset_device_resume(struct visor_device *dev_info) { int err; err = visorchipset_initiate_device_pause_resume(dev_info, false); - if (err < 0) { dev_info->resuming = false; return err; @@ -1255,8 +1223,7 @@ visorchipset_device_resume(struct visor_device *dev_info) return 0; } -int -visorbus_init(void) +int visorbus_init(void) { int err; @@ -1271,14 +1238,12 @@ visorbus_init(void) return err; initialized = true; - bus_device_info_init(&chipset_driverinfo, "chipset", "visorchipset"); return 0; } -void -visorbus_exit(void) +void visorbus_exit(void) { struct list_head *listentry, *listtmp; diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h index 98a5af19189d..e878d65ab668 100644 --- a/drivers/staging/unisys/visorbus/visorbus_private.h +++ b/drivers/staging/unisys/visorbus/visorbus_private.h @@ -1,5 +1,4 @@ -/* visorbus_private.h - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -22,36 +21,27 @@ #include "controlvmchannel.h" #include "vbuschannel.h" +#include "visorbus.h" -/* TARGET_HOSTNAME specified as -DTARGET_HOSTNAME=\"thename\" on the - * command line - */ - -int visorchipset_bus_create(struct visor_device *bus_info); -void visorchipset_bus_destroy(struct visor_device *bus_info); -int visorchipset_device_create(struct visor_device *dev_info); -void visorchipset_device_destroy(struct visor_device *dev_info); +int visorbus_create_instance(struct visor_device *dev); +void visorbus_remove_instance(struct visor_device *bus_info); +int create_visor_device(struct visor_device *dev_info); +void remove_visor_device(struct visor_device *dev_info); int visorchipset_device_pause(struct visor_device *dev_info); int visorchipset_device_resume(struct visor_device *dev_info); -void visorbus_create_response(struct visor_device *p, int response); -void visorbus_destroy_response(struct visor_device *p, int response); -void visorbus_device_create_response(struct visor_device *p, int response); -void visorbus_device_destroy_response(struct visor_device *p, int response); -void visorbus_device_resume_response(struct visor_device *p, int response); -void visorbus_device_pause_response(struct visor_device *p, int response); +void visorbus_response(struct visor_device *p, int response, int controlvm_id); +void visorbus_device_changestate_response(struct visor_device *p, int response, + struct visor_segment_state state); int visorbus_init(void); void visorbus_exit(void); /* visorchannel access functions */ - -struct visorchannel *visorchannel_create(u64 physaddr, - unsigned long channel_bytes, - gfp_t gfp, uuid_le guid); -struct visorchannel *visorchannel_create_with_lock(u64 physaddr, - unsigned long channel_bytes, - gfp_t gfp, uuid_le guid); +struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, + const guid_t *guid); +struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp, + const guid_t *guid); void visorchannel_destroy(struct visorchannel *channel); int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest, ulong nbytes); @@ -64,6 +54,6 @@ char *visorchannel_zoneid(struct visorchannel *channel, char *s); u64 visorchannel_get_clientpartition(struct visorchannel *channel); int visorchannel_set_clientpartition(struct visorchannel *channel, u64 partition_handle); -char *visorchannel_uuid_id(uuid_le *guid, char *s); +char *visorchannel_guid_id(const guid_t *guid, char *s); void *visorchannel_get_header(struct visorchannel *channel); #endif diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c index 6885c2cb7135..2a000fee3119 100644 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ b/drivers/staging/unisys/visorbus/visorchannel.c @@ -1,5 +1,4 @@ -/* visorchannel_funcs.c - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -26,13 +25,13 @@ #include "visorbus_private.h" #include "controlvmchannel.h" -#define MYDRVNAME "visorchannel" +#define VISOR_DRV_NAME "visorchannel" #define VISOR_CONSOLEVIDEO_CHANNEL_GUID \ - UUID_LE(0x3cd6e705, 0xd6a2, 0x4aa5, \ - 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2) + GUID_INIT(0x3cd6e705, 0xd6a2, 0x4aa5, \ + 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2) -static const uuid_le visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID; +static const guid_t visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID; struct visorchannel { u64 physaddr; @@ -40,18 +39,21 @@ struct visorchannel { void *mapped; bool requested; struct channel_header chan_hdr; - uuid_le guid; - bool needs_lock; /* channel creator knows if more than one */ - /* thread will be inserting or removing */ - spinlock_t insert_lock; /* protect head writes in chan_hdr */ - spinlock_t remove_lock; /* protect tail writes in chan_hdr */ - - uuid_le type; - uuid_le inst; + guid_t guid; + /* + * channel creator knows if more than one + * thread will be inserting or removing + */ + bool needs_lock; + /* protect head writes in chan_hdr */ + spinlock_t insert_lock; + /* protect tail writes in chan_hdr */ + spinlock_t remove_lock; + guid_t type; + guid_t inst; }; -void -visorchannel_destroy(struct visorchannel *channel) +void visorchannel_destroy(struct visorchannel *channel) { if (!channel) return; @@ -63,67 +65,58 @@ visorchannel_destroy(struct visorchannel *channel) kfree(channel); } -u64 -visorchannel_get_physaddr(struct visorchannel *channel) +u64 visorchannel_get_physaddr(struct visorchannel *channel) { return channel->physaddr; } -ulong -visorchannel_get_nbytes(struct visorchannel *channel) +ulong visorchannel_get_nbytes(struct visorchannel *channel) { return channel->nbytes; } -char * -visorchannel_uuid_id(uuid_le *guid, char *s) +char *visorchannel_guid_id(const guid_t *guid, char *s) { sprintf(s, "%pUL", guid); return s; } -char * -visorchannel_id(struct visorchannel *channel, char *s) +char *visorchannel_id(struct visorchannel *channel, char *s) { - return visorchannel_uuid_id(&channel->guid, s); + return visorchannel_guid_id(&channel->guid, s); } -char * -visorchannel_zoneid(struct visorchannel *channel, char *s) +char *visorchannel_zoneid(struct visorchannel *channel, char *s) { - return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s); + return visorchannel_guid_id(&channel->chan_hdr.zone_guid, s); } -u64 -visorchannel_get_clientpartition(struct visorchannel *channel) +u64 visorchannel_get_clientpartition(struct visorchannel *channel) { return channel->chan_hdr.partition_handle; } -int -visorchannel_set_clientpartition(struct visorchannel *channel, - u64 partition_handle) +int visorchannel_set_clientpartition(struct visorchannel *channel, + u64 partition_handle) { channel->chan_hdr.partition_handle = partition_handle; return 0; } /** - * visorchannel_get_uuid() - queries the UUID of the designated channel + * visorchannel_get_guid() - queries the GUID of the designated channel * @channel: the channel to query * - * Return: the UUID of the provided channel + * Return: the GUID of the provided channel */ -uuid_le -visorchannel_get_uuid(struct visorchannel *channel) +const guid_t *visorchannel_get_guid(struct visorchannel *channel) { - return channel->guid; + return &channel->guid; } -EXPORT_SYMBOL_GPL(visorchannel_get_uuid); +EXPORT_SYMBOL_GPL(visorchannel_get_guid); -int -visorchannel_read(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes) +int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest, + ulong nbytes) { if (offset + nbytes > channel->nbytes) return -EIO; @@ -133,9 +126,8 @@ visorchannel_read(struct visorchannel *channel, ulong offset, return 0; } -int -visorchannel_write(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes) +int visorchannel_write(struct visorchannel *channel, ulong offset, void *dest, + ulong nbytes) { size_t chdr_size = sizeof(struct channel_header); size_t copy_size; @@ -154,8 +146,7 @@ visorchannel_write(struct visorchannel *channel, ulong offset, return 0; } -void * -visorchannel_get_header(struct visorchannel *channel) +void *visorchannel_get_header(struct visorchannel *channel) { return &channel->chan_hdr; } @@ -164,17 +155,22 @@ visorchannel_get_header(struct visorchannel *channel) * Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a * channel header */ -#define SIG_QUEUE_OFFSET(chan_hdr, q) \ - ((chan_hdr)->ch_space_offset + \ - ((q) * sizeof(struct signal_queue_header))) +static int sig_queue_offset(struct channel_header *chan_hdr, int q) +{ + return ((chan_hdr)->ch_space_offset + + ((q) * sizeof(struct signal_queue_header))); +} /* * Return offset of a specific queue entry (data) from the beginning of a * channel header */ -#define SIG_DATA_OFFSET(chan_hdr, q, sig_hdr, slot) \ - (SIG_QUEUE_OFFSET(chan_hdr, q) + (sig_hdr)->sig_base_offset + \ - ((slot) * (sig_hdr)->signal_size)) +static int sig_data_offset(struct channel_header *chan_hdr, int q, + struct signal_queue_header *sig_hdr, int slot) +{ + return (sig_queue_offset(chan_hdr, q) + sig_hdr->sig_base_offset + + (slot * sig_hdr->signal_size)); +} /* * Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back @@ -182,48 +178,47 @@ visorchannel_get_header(struct visorchannel *channel) */ #define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \ visorchannel_write(channel, \ - SIG_QUEUE_OFFSET(&channel->chan_hdr, queue) + \ + sig_queue_offset(&channel->chan_hdr, queue) + \ offsetof(struct signal_queue_header, FIELD), \ &((sig_hdr)->FIELD), \ sizeof((sig_hdr)->FIELD)) -static int -sig_read_header(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr) +static int sig_read_header(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr) { if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) return -EINVAL; /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */ return visorchannel_read(channel, - SIG_QUEUE_OFFSET(&channel->chan_hdr, queue), + sig_queue_offset(&channel->chan_hdr, queue), sig_hdr, sizeof(struct signal_queue_header)); } -static int -sig_read_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, void *data) +static int sig_read_data(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr, u32 slot, + void *data) { - int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, + int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, sig_hdr, slot); return visorchannel_read(channel, signal_data_offset, data, sig_hdr->signal_size); } -static int -sig_write_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, void *data) +static int sig_write_data(struct visorchannel *channel, u32 queue, + struct signal_queue_header *sig_hdr, u32 slot, + void *data) { - int signal_data_offset = SIG_DATA_OFFSET(&channel->chan_hdr, queue, + int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, sig_hdr, slot); return visorchannel_write(channel, signal_data_offset, data, sig_hdr->signal_size); } -static int -signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) +static int signalremove_inner(struct visorchannel *channel, u32 queue, + void *msg) { struct signal_queue_header sig_hdr; int error; @@ -246,9 +241,9 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, - * update host memory. + * update host memory. Required for channel sync. */ - mb(); /* required for channel synch */ + mb(); error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail); if (error) @@ -269,8 +264,8 @@ signalremove_inner(struct visorchannel *channel, u32 queue, void *msg) * * Return: integer error code indicating the status of the removal */ -int -visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) +int visorchannel_signalremove(struct visorchannel *channel, u32 queue, + void *msg) { int rc; unsigned long flags; @@ -287,8 +282,7 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg) } EXPORT_SYMBOL_GPL(visorchannel_signalremove); -static bool -queue_empty(struct visorchannel *channel, u32 queue) +static bool queue_empty(struct visorchannel *channel, u32 queue) { struct signal_queue_header sig_hdr; @@ -307,8 +301,7 @@ queue_empty(struct visorchannel *channel, u32 queue) * Return: boolean indicating whether any messages in the designated * channel/queue are present */ -bool -visorchannel_signalempty(struct visorchannel *channel, u32 queue) +bool visorchannel_signalempty(struct visorchannel *channel, u32 queue) { bool rc; unsigned long flags; @@ -324,8 +317,8 @@ visorchannel_signalempty(struct visorchannel *channel, u32 queue) } EXPORT_SYMBOL_GPL(visorchannel_signalempty); -static int -signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) +static int signalinsert_inner(struct visorchannel *channel, u32 queue, + void *msg) { struct signal_queue_header sig_hdr; int err; @@ -351,9 +344,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) /* * For each data field in SIGNAL_QUEUE_HEADER that was modified, - * update host memory. + * update host memory. Required for channel sync. */ - mb(); /* required for channel synch */ + mb(); err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head); if (err) @@ -370,17 +363,8 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) * for a data area in memory, but does NOT modify * this data area * @physaddr: physical address of start of channel - * @channel_bytes: size of the channel in bytes; this may 0 if the channel has - * already been initialized in memory (which is true for all - * channels provided to guest environments by the s-Par - * back-end), in which case the actual channel size will be - * read from the channel header in memory * @gfp: gfp_t to use when allocating memory for the data struct - * @guid: uuid that identifies channel type; this may 0 if the channel - * has already been initialized in memory (which is true for all - * channels provided to guest environments by the s-Par - * back-end), in which case the actual channel guid will be - * read from the channel header in memory + * @guid: GUID that identifies channel type; * @needs_lock: must specify true if you have multiple threads of execution * that will be calling visorchannel methods of this * visorchannel at the same time @@ -388,9 +372,9 @@ signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg) * Return: pointer to visorchannel that was created if successful, * otherwise NULL */ -static struct visorchannel * -visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid, bool needs_lock) +static struct visorchannel *visorchannel_create_guts(u64 physaddr, gfp_t gfp, + const guid_t *guid, + bool needs_lock) { struct visorchannel *channel; int err; @@ -414,8 +398,8 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, * this. Remember that we haven't requested it so we don't try to * release later on. */ - channel->requested = request_mem_region(physaddr, size, MYDRVNAME); - if (!channel->requested && uuid_le_cmp(guid, visor_video_guid)) + channel->requested = request_mem_region(physaddr, size, VISOR_DRV_NAME); + if (!channel->requested && !guid_equal(guid, &visor_video_guid)) /* we only care about errors if this is not the video channel */ goto err_destroy_channel; @@ -428,36 +412,29 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes, channel->physaddr = physaddr; channel->nbytes = size; - err = visorchannel_read(channel, 0, &channel->chan_hdr, - sizeof(struct channel_header)); + err = visorchannel_read(channel, 0, &channel->chan_hdr, size); if (err) goto err_destroy_channel; - - /* we had better be a CLIENT of this channel */ - if (channel_bytes == 0) - channel_bytes = (ulong)channel->chan_hdr.size; - if (uuid_le_cmp(guid, NULL_UUID_LE) == 0) - guid = channel->chan_hdr.chtype; + size = (ulong)channel->chan_hdr.size; memunmap(channel->mapped); if (channel->requested) release_mem_region(channel->physaddr, channel->nbytes); channel->mapped = NULL; - channel->requested = request_mem_region(channel->physaddr, - channel_bytes, MYDRVNAME); - if (!channel->requested && uuid_le_cmp(guid, visor_video_guid)) + channel->requested = request_mem_region(channel->physaddr, size, + VISOR_DRV_NAME); + if (!channel->requested && !guid_equal(guid, &visor_video_guid)) /* we only care about errors if this is not the video channel */ goto err_destroy_channel; - channel->mapped = memremap(channel->physaddr, channel_bytes, - MEMREMAP_WB); + channel->mapped = memremap(channel->physaddr, size, MEMREMAP_WB); if (!channel->mapped) { - release_mem_region(channel->physaddr, channel_bytes); + release_mem_region(channel->physaddr, size); goto err_destroy_channel; } - channel->nbytes = channel_bytes; - channel->guid = guid; + channel->nbytes = size; + guid_copy(&channel->guid, guid); return channel; err_destroy_channel: @@ -465,20 +442,16 @@ err_destroy_channel: return NULL; } -struct visorchannel * -visorchannel_create(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid) +struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, + const guid_t *guid) { - return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid, - false); + return visorchannel_create_guts(physaddr, gfp, guid, false); } -struct visorchannel * -visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes, - gfp_t gfp, uuid_le guid) +struct visorchannel *visorchannel_create_with_lock(u64 physaddr, gfp_t gfp, + const guid_t *guid) { - return visorchannel_create_guts(physaddr, channel_bytes, gfp, guid, - true); + return visorchannel_create_guts(physaddr, gfp, guid, true); } /** @@ -490,8 +463,8 @@ visorchannel_create_with_lock(u64 physaddr, unsigned long channel_bytes, * * Return: integer error code indicating the status of the insertion */ -int -visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg) +int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, + void *msg) { int rc; unsigned long flags; diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c index 22150564b4fb..27ecf6fb49fd 100644 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ b/drivers/staging/unisys/visorbus/visorchipset.c @@ -1,5 +1,4 @@ -/* visorchipset_main.c - * +/* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -15,19 +14,18 @@ */ #include -#include -#include -#include -#include -#include -#include #include #include "visorbus.h" #include "visorbus_private.h" -#include "vmcallinterface.h" -#define CURRENT_FILE_PC VISOR_BUS_PC_visorchipset_c +/* {72120008-4AAB-11DC-8530-444553544200} */ +#define VISOR_SIOVM_GUID GUID_INIT(0x72120008, 0x4AAB, 0x11DC, 0x85, 0x30, \ + 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) + +static const guid_t visor_vhba_channel_guid = VISOR_VHBA_CHANNEL_GUID; +static const guid_t visor_siovm_guid = VISOR_SIOVM_GUID; +static const guid_t visor_controlvm_channel_guid = VISOR_CONTROLVM_CHANNEL_GUID; #define POLLJIFFIES_CONTROLVMCHANNEL_FAST 1 #define POLLJIFFIES_CONTROLVMCHANNEL_SLOW 100 @@ -42,9 +40,9 @@ #define UNISYS_VISOR_ID_EDX 0x34367261 /* - * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, - * we switch to slow polling mode. As soon as we get a controlvm - * message, we switch back to fast polling mode. + * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, we switch + * to slow polling mode. As soon as we get a controlvm message, we switch back + * to fast polling mode. */ #define MIN_IDLE_SECONDS 10 @@ -54,15 +52,39 @@ struct parser_context { u8 *curr; unsigned long bytes_remaining; bool byte_stream; - char data[0]; + struct visor_controlvm_parameters_header data; }; -struct vmcall_controlvm_addr { - struct vmcall_io_controlvm_addr_params params; - int err; - u64 physaddr; +/* VMCALL_CONTROLVM_ADDR: Used by all guests, not just IO. */ +#define VMCALL_CONTROLVM_ADDR 0x0501 + +enum vmcall_result { + VMCALL_RESULT_SUCCESS = 0, + VMCALL_RESULT_INVALID_PARAM = 1, + VMCALL_RESULT_DATA_UNAVAILABLE = 2, + VMCALL_RESULT_FAILURE_UNAVAILABLE = 3, + VMCALL_RESULT_DEVICE_ERROR = 4, + VMCALL_RESULT_DEVICE_NOT_READY = 5 }; +/* + * struct vmcall_io_controlvm_addr_params - Structure for IO VMCALLS. Has + * parameters to VMCALL_CONTROLVM_ADDR + * interface. + * @address: The Guest-relative physical address of the ControlVm channel. + * This VMCall fills this in with the appropriate address. + * Contents provided by this VMCALL (OUT). + * @channel_bytes: The size of the ControlVm channel in bytes This VMCall fills + * this in with the appropriate address. Contents provided by + * this VMCALL (OUT). + * @unused: Unused Bytes in the 64-Bit Aligned Struct. + */ +struct vmcall_io_controlvm_addr_params { + u64 address; + u32 channel_bytes; + u8 unused[4]; +} __packed; + struct visorchipset_device { struct acpi_device *acpi_device; unsigned long poll_jiffies; @@ -80,7 +102,7 @@ struct visorchipset_device { */ struct controlvm_message controlvm_pending_msg; bool controlvm_pending_msg_valid; - struct vmcall_controlvm_addr controlvm_addr; + struct vmcall_io_controlvm_addr_params controlvm_params; }; static struct visorchipset_device *chipset_dev; @@ -124,7 +146,6 @@ static ssize_t toolaction_store(struct device *dev, offsetof(struct visor_controlvm_channel, tool_action), &tool_action, sizeof(u8)); - if (err) return err; return count; @@ -143,7 +164,6 @@ static ssize_t boottotool_show(struct device *dev, efi_visor_ind), &efi_visor_indication, sizeof(struct efi_visor_indication)); - if (err) return err; return sprintf(buf, "%u\n", efi_visor_indication.boot_to_tool); @@ -165,7 +185,6 @@ static ssize_t boottotool_store(struct device *dev, efi_visor_ind), &(efi_visor_indication), sizeof(struct efi_visor_indication)); - if (err) return err; return count; @@ -184,7 +203,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr, &error, sizeof(u32)); if (err) return err; - return sprintf(buf, "%i\n", error); + return sprintf(buf, "%u\n", error); } static ssize_t error_store(struct device *dev, struct device_attribute *attr, @@ -219,7 +238,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr, if (err) return err; - return sprintf(buf, "%i\n", text_id); + return sprintf(buf, "%u\n", text_id); } static ssize_t textid_store(struct device *dev, struct device_attribute *attr, @@ -277,67 +296,6 @@ static ssize_t remaining_steps_store(struct device *dev, } static DEVICE_ATTR_RW(remaining_steps); -static uuid_le -parser_id_get(struct parser_context *ctx) -{ - struct visor_controlvm_parameters_header *phdr = NULL; - - phdr = (struct visor_controlvm_parameters_header *)(ctx->data); - return phdr->id; -} - -static void parser_done(struct parser_context *ctx) -{ - chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes; - kfree(ctx); -} - -static void * -parser_string_get(struct parser_context *ctx) -{ - u8 *pscan; - unsigned long nscan; - int value_length = -1; - void *value = NULL; - int i; - - pscan = ctx->curr; - nscan = ctx->bytes_remaining; - if (nscan == 0) - return NULL; - if (!pscan) - return NULL; - for (i = 0, value_length = -1; i < nscan; i++) - if (pscan[i] == '\0') { - value_length = i; - break; - } - if (value_length < 0) /* '\0' was not included in the length */ - value_length = nscan; - value = kmalloc(value_length + 1, GFP_KERNEL); - if (!value) - return NULL; - if (value_length > 0) - memcpy(value, pscan, value_length); - ((u8 *)(value))[value_length] = '\0'; - return value; -} - -static void * -parser_name_get(struct parser_context *ctx) -{ - struct visor_controlvm_parameters_header *phdr = NULL; - - phdr = (struct visor_controlvm_parameters_header *)(ctx->data); - - if (phdr->name_offset + phdr->name_length > ctx->param_bytes) - return NULL; - - ctx->curr = ctx->data + phdr->name_offset; - ctx->bytes_remaining = phdr->name_length; - return parser_string_get(ctx); -} - struct visor_busdev { u32 bus_no; u32 dev_no; @@ -347,11 +305,9 @@ static int match_visorbus_dev_by_id(struct device *dev, void *data) { struct visor_device *vdev = to_visor_device(dev); struct visor_busdev *id = data; - u32 bus_no = id->bus_no; - u32 dev_no = id->dev_no; - if ((vdev->chipset_bus_no == bus_no) && - (vdev->chipset_dev_no == dev_no)) + if ((vdev->chipset_bus_no == id->bus_no) && + (vdev->chipset_dev_no == id->dev_no)) return 1; return 0; @@ -364,9 +320,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, struct device *dev_start = NULL; struct visor_device *vdev = NULL; struct visor_busdev id = { - .bus_no = bus_no, - .dev_no = dev_no - }; + .bus_no = bus_no, + .dev_no = dev_no + }; if (from) dev_start = &from->device; @@ -377,9 +333,9 @@ struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, return vdev; } -static void -controlvm_init_response(struct controlvm_message *msg, - struct controlvm_message_header *msg_hdr, int response) +static void controlvm_init_response(struct controlvm_message *msg, + struct controlvm_message_header *msg_hdr, + int response) { memset(msg, 0, sizeof(struct controlvm_message)); memcpy(&msg->hdr, msg_hdr, sizeof(struct controlvm_message_header)); @@ -392,10 +348,10 @@ controlvm_init_response(struct controlvm_message *msg, } } -static int -controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, - int response, - enum visor_chipset_feature features) +static int controlvm_respond_chipset_init( + struct controlvm_message_header *msg_hdr, + int response, + enum visor_chipset_feature features) { struct controlvm_message outmsg; @@ -405,8 +361,7 @@ controlvm_respond_chipset_init(struct controlvm_message_header *msg_hdr, CONTROLVM_QUEUE_REQUEST, &outmsg); } -static int -chipset_init(struct controlvm_message *inmsg) +static int chipset_init(struct controlvm_message *inmsg) { static int chipset_inited; enum visor_chipset_feature features = 0; @@ -421,15 +376,15 @@ chipset_init(struct controlvm_message *inmsg) chipset_inited = 1; /* - * Set features to indicate we support parahotplug (if Command - * also supports it). + * Set features to indicate we support parahotplug (if Command also + * supports it). */ features = inmsg->cmd.init_chipset.features & VISOR_CHIPSET_FEATURE_PARA_HOTPLUG; /* - * Set the "reply" bit so Command knows this is a - * features-aware driver. + * Set the "reply" bit so Command knows this is a features-aware + * driver. */ features |= VISOR_CHIPSET_FEATURE_REPLY; @@ -440,9 +395,9 @@ out_respond: return res; } -static int -controlvm_respond(struct controlvm_message_header *msg_hdr, int response, - struct visor_segment_state *state) +static int controlvm_respond(struct controlvm_message_header *msg_hdr, + int response, + struct visor_segment_state *state) { struct controlvm_message outmsg; @@ -464,8 +419,8 @@ enum crash_obj_type { CRASH_BUS, }; -static int -save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type) +static int save_crash_message(struct controlvm_message *msg, + enum crash_obj_type cr_type) { u32 local_crash_msg_offset; u16 local_crash_msg_count; @@ -529,10 +484,9 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type cr_type) return 0; } -static int -controlvm_responder(enum controlvm_id cmd_id, - struct controlvm_message_header *pending_msg_hdr, - int response) +static int controlvm_responder(enum controlvm_id cmd_id, + struct controlvm_message_header *pending_msg_hdr, + int response) { if (!pending_msg_hdr) return -EIO; @@ -543,14 +497,12 @@ controlvm_responder(enum controlvm_id cmd_id, return controlvm_respond(pending_msg_hdr, response, NULL); } -static int -device_changestate_responder(enum controlvm_id cmd_id, - struct visor_device *p, int response, - struct visor_segment_state response_state) +static int device_changestate_responder( + enum controlvm_id cmd_id, + struct visor_device *p, int response, + struct visor_segment_state response_state) { struct controlvm_message outmsg; - u32 bus_no = p->chipset_bus_no; - u32 dev_no = p->chipset_dev_no; if (!p->pending_msg_hdr) return -EIO; @@ -559,16 +511,15 @@ device_changestate_responder(enum controlvm_id cmd_id, controlvm_init_response(&outmsg, p->pending_msg_hdr, response); - outmsg.cmd.device_change_state.bus_no = bus_no; - outmsg.cmd.device_change_state.dev_no = dev_no; + outmsg.cmd.device_change_state.bus_no = p->chipset_bus_no; + outmsg.cmd.device_change_state.dev_no = p->chipset_dev_no; outmsg.cmd.device_change_state.state = response_state; return visorchannel_signalinsert(chipset_dev->controlvm_channel, CONTROLVM_QUEUE_REQUEST, &outmsg); } -static int -visorbus_create(struct controlvm_message *inmsg) +static int visorbus_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -580,7 +531,7 @@ visorbus_create(struct controlvm_message *inmsg) bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); if (bus_info && (bus_info->state.created == 1)) { dev_err(&chipset_dev->acpi_device->dev, - "failed visorbus_create: already exists\n"); + "failed %s: already exists\n", __func__); err = -EEXIST; goto err_respond; } @@ -595,7 +546,7 @@ visorbus_create(struct controlvm_message *inmsg) bus_info->chipset_bus_no = bus_no; bus_info->chipset_dev_no = BUS_ROOT_DEVICE; - if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, visor_siovm_uuid) == 0) { + if (guid_equal(&cmd->create_bus.bus_inst_guid, &visor_siovm_guid)) { err = save_crash_message(inmsg, CRASH_BUS); if (err) goto err_free_bus_info; @@ -615,19 +566,17 @@ visorbus_create(struct controlvm_message *inmsg) } visorchannel = visorchannel_create(cmd->create_bus.channel_addr, - cmd->create_bus.channel_bytes, GFP_KERNEL, - cmd->create_bus.bus_data_type_uuid); - + &cmd->create_bus.bus_data_type_guid); if (!visorchannel) { err = -ENOMEM; goto err_free_pending_msg; } + bus_info->visorchannel = visorchannel; - /* Response will be handled by visorchipset_bus_create */ - err = visorchipset_bus_create(bus_info); - /* If visorchipset_bus_create didn't respond, need to respond here */ + /* Response will be handled by visorbus_create_instance on success */ + err = visorbus_create_instance(bus_info); if (err) goto err_destroy_channel; @@ -648,8 +597,7 @@ err_respond: return err; } -static int -visorbus_destroy(struct controlvm_message *inmsg) +static int visorbus_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -683,8 +631,8 @@ visorbus_destroy(struct controlvm_message *inmsg) bus_info->pending_msg_hdr = pmsg_hdr; } - /* Response will be handled by visorchipset_bus_destroy */ - visorchipset_bus_destroy(bus_info); + /* Response will be handled by visorbus_remove_instance */ + visorbus_remove_instance(bus_info); return 0; err_respond: @@ -693,9 +641,60 @@ err_respond: return err; } -static int -visorbus_configure(struct controlvm_message *inmsg, - struct parser_context *parser_ctx) +static const guid_t *parser_id_get(struct parser_context *ctx) +{ + return &ctx->data.id; +} + +static void *parser_string_get(struct parser_context *ctx) +{ + u8 *pscan; + unsigned long nscan; + int value_length; + void *value; + int i; + + pscan = ctx->curr; + if (!pscan) + return NULL; + nscan = ctx->bytes_remaining; + if (nscan == 0) + return NULL; + + for (i = 0, value_length = -1; i < nscan; i++) + if (pscan[i] == '\0') { + value_length = i; + break; + } + /* '\0' was not included in the length */ + if (value_length < 0) + value_length = nscan; + + value = kmalloc(value_length + 1, GFP_KERNEL); + if (!value) + return NULL; + if (value_length > 0) + memcpy(value, pscan, value_length); + ((u8 *)(value))[value_length] = '\0'; + return value; +} + +static void *parser_name_get(struct parser_context *ctx) +{ + struct visor_controlvm_parameters_header *phdr = NULL; + + phdr = &ctx->data; + + if (phdr->name_offset + phdr->name_length > ctx->param_bytes) + return NULL; + + ctx->curr = (char *)&phdr + phdr->name_offset; + ctx->bytes_remaining = phdr->name_length; + return parser_string_get(ctx); +} + +static int visorbus_configure(struct controlvm_message *inmsg, + struct parser_context *parser_ctx) { struct controlvm_message_packet *cmd = &inmsg->cmd; u32 bus_no; @@ -707,10 +706,12 @@ visorbus_configure(struct controlvm_message *inmsg, if (!bus_info) { err = -EINVAL; goto err_respond; - } else if (bus_info->state.created == 0) { + } + if (bus_info->state.created == 0) { err = -EINVAL; goto err_respond; - } else if (bus_info->pending_msg_hdr) { + } + if (bus_info->pending_msg_hdr) { err = -EIO; goto err_respond; } @@ -722,7 +723,9 @@ visorbus_configure(struct controlvm_message *inmsg, goto err_respond; if (parser_ctx) { - bus_info->partition_uuid = parser_id_get(parser_ctx); + const guid_t *partition_guid = parser_id_get(parser_ctx); + + guid_copy(&bus_info->partition_guid, partition_guid); bus_info->name = parser_name_get(parser_ctx); } @@ -732,14 +735,13 @@ visorbus_configure(struct controlvm_message *inmsg, err_respond: dev_err(&chipset_dev->acpi_device->dev, - "visorbus_configure exited with err: %d\n", err); + "%s exited with err: %d\n", __func__, err); if (inmsg->hdr.flags.response_expected == 1) controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); return err; } -static int -visorbus_device_create(struct controlvm_message *inmsg) +static int visorbus_device_create(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -757,7 +759,6 @@ visorbus_device_create(struct controlvm_message *inmsg) err = -ENODEV; goto err_respond; } - if (bus_info->state.created == 0) { dev_err(&chipset_dev->acpi_device->dev, "bus not created, id: %d\n", bus_no); @@ -781,17 +782,13 @@ visorbus_device_create(struct controlvm_message *inmsg) dev_info->chipset_bus_no = bus_no; dev_info->chipset_dev_no = dev_no; - dev_info->inst = cmd->create_device.dev_inst_uuid; - - /* not sure where the best place to set the 'parent' */ + guid_copy(&dev_info->inst, &cmd->create_device.dev_inst_guid); dev_info->device.parent = &bus_info->device; visorchannel = visorchannel_create_with_lock(cmd->create_device.channel_addr, - cmd->create_device.channel_bytes, GFP_KERNEL, - cmd->create_device.data_type_uuid); - + &cmd->create_device.data_type_guid); if (!visorchannel) { dev_err(&chipset_dev->acpi_device->dev, "failed to create visorchannel: %d/%d\n", @@ -800,9 +797,8 @@ visorbus_device_create(struct controlvm_message *inmsg) goto err_free_dev_info; } dev_info->visorchannel = visorchannel; - dev_info->channel_type_guid = cmd->create_device.data_type_uuid; - if (uuid_le_cmp(cmd->create_device.data_type_uuid, - visor_vhba_channel_uuid) == 0) { + guid_copy(&dev_info->channel_type_guid, &cmd->create_device.data_type_guid); + if (guid_equal(&cmd->create_device.data_type_guid, &visor_vhba_channel_guid)) { err = save_crash_message(inmsg, CRASH_DEV); if (err) goto err_destroy_visorchannel; @@ -819,8 +815,8 @@ visorbus_device_create(struct controlvm_message *inmsg) sizeof(struct controlvm_message_header)); dev_info->pending_msg_hdr = pmsg_hdr; } - /* visorchipset_device_create will send response */ - err = visorchipset_device_create(dev_info); + /* create_visor_device will send response */ + err = create_visor_device(dev_info); if (err) goto err_destroy_visorchannel; @@ -838,8 +834,7 @@ err_respond: return err; } -static int -visorbus_device_changestate(struct controlvm_message *inmsg) +static int visorbus_device_changestate(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -899,8 +894,7 @@ err_respond: return err; } -static int -visorbus_device_destroy(struct controlvm_message *inmsg) +static int visorbus_device_destroy(struct controlvm_message *inmsg) { struct controlvm_message_packet *cmd = &inmsg->cmd; struct controlvm_message_header *pmsg_hdr = NULL; @@ -918,7 +912,6 @@ visorbus_device_destroy(struct controlvm_message *inmsg) err = -EINVAL; goto err_respond; } - if (dev_info->pending_msg_hdr) { /* only non-NULL if dev is still waiting on a response */ err = -EIO; @@ -936,7 +929,8 @@ visorbus_device_destroy(struct controlvm_message *inmsg) dev_info->pending_msg_hdr = pmsg_hdr; } - visorchipset_device_destroy(dev_info); + kfree(dev_info->name); + remove_visor_device(dev_info); return 0; err_respond: @@ -954,8 +948,7 @@ err_respond: * disable the specified device. The udev script then writes to * /sys/devices/platform/visorchipset/parahotplug, which causes the * parahotplug store functions to get called, at which point the - * appropriate CONTROLVM message is retrieved from the list and responded - * to. + * appropriate CONTROLVM message is retrieved from the list and responded to. */ #define PARAHOTPLUG_TIMEOUT_MS 2000 @@ -967,8 +960,7 @@ err_respond: * * Return: a unique integer value */ -static int -parahotplug_next_id(void) +static int parahotplug_next_id(void) { static atomic_t id = ATOMIC_INIT(0); @@ -982,8 +974,7 @@ parahotplug_next_id(void) * * Return: expected expiration time (in jiffies) */ -static unsigned long -parahotplug_next_expiration(void) +static unsigned long parahotplug_next_expiration(void) { return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS); } @@ -996,8 +987,8 @@ parahotplug_next_expiration(void) * * Return: the request containing the provided message */ -static struct parahotplug_request * -parahotplug_request_create(struct controlvm_message *msg) +static struct parahotplug_request *parahotplug_request_create( + struct controlvm_message *msg) { struct parahotplug_request *req; @@ -1016,14 +1007,14 @@ parahotplug_request_create(struct controlvm_message *msg) * parahotplug_request_destroy() - free a parahotplug_request * @req: the request to deallocate */ -static void -parahotplug_request_destroy(struct parahotplug_request *req) +static void parahotplug_request_destroy(struct parahotplug_request *req) { kfree(req); } static LIST_HEAD(parahotplug_request_list); -static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ +/* lock for above */ +static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* * parahotplug_request_complete() - mark request as complete @@ -1036,8 +1027,7 @@ static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */ * * Return: 0 on success or -EINVAL on failure */ -static int -parahotplug_request_complete(int id, u16 active) +static int parahotplug_request_complete(int id, u16 active) { struct list_head *pos; struct list_head *tmp; @@ -1146,7 +1136,7 @@ static struct attribute *visorchipset_parahotplug_attrs[] = { NULL }; -static struct attribute_group visorchipset_parahotplug_group = { +static const struct attribute_group visorchipset_parahotplug_group = { .name = "parahotplug", .attrs = visorchipset_parahotplug_attrs }; @@ -1164,8 +1154,7 @@ static const struct attribute_group *visorchipset_dev_groups[] = { * Cause uevent to run the user level script to do the disable/enable specified * in the parahotplug_request. */ -static int -parahotplug_request_kickoff(struct parahotplug_request *req) +static int parahotplug_request_kickoff(struct parahotplug_request *req) { struct controlvm_message_packet *cmd = &req->msg.cmd; char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40], @@ -1194,14 +1183,12 @@ parahotplug_request_kickoff(struct parahotplug_request *req) * off a udev script * @inmsg: the message indicating whether to enable or disable */ -static int -parahotplug_process_message(struct controlvm_message *inmsg) +static int parahotplug_process_message(struct controlvm_message *inmsg) { struct parahotplug_request *req; int err; req = parahotplug_request_create(inmsg); - if (!req) return -ENOMEM; @@ -1220,10 +1207,9 @@ parahotplug_process_message(struct controlvm_message *inmsg) } /* - * For disable messages, add the request to the - * request list before kicking off the udev script. It - * won't get responded to until the script has - * indicated it's done. + * For disable messages, add the request to the request list before + * kicking off the udev script. It won't get responded to until the + * script has indicated it's done. */ spin_lock(¶hotplug_request_list_lock); list_add_tail(&req->list, ¶hotplug_request_list); @@ -1247,8 +1233,7 @@ err_respond: * * Return: 0 on success, negative on failure */ -static int -chipset_ready_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_ready_uevent(struct controlvm_message_header *msg_hdr) { int res; @@ -1268,8 +1253,7 @@ chipset_ready_uevent(struct controlvm_message_header *msg_hdr) * * Return: 0 on success, negative on failure */ -static int -chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) { char env_selftest[20]; char *envp[] = { env_selftest, NULL }; @@ -1292,13 +1276,11 @@ chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) * * Return: 0 on success, negative on failure */ -static int -chipset_notready_uevent(struct controlvm_message_header *msg_hdr) +static int chipset_notready_uevent(struct controlvm_message_header *msg_hdr) { - int res; - - res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, + int res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, KOBJ_OFFLINE); + if (msg_hdr->flags.response_expected) controlvm_respond(msg_hdr, res, NULL); @@ -1321,13 +1303,12 @@ static int unisys_vmcall(unsigned long tuple, unsigned long param) __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : "a"(tuple), "b"(reg_ebx), "c"(reg_ecx)); - if (result) goto error; return 0; - -error: /* Need to convert from VMCALL error codes to Linux */ +/* Need to convert from VMCALL error codes to Linux */ +error: switch (result) { case VMCALL_RESULT_INVALID_PARAM: return -EINVAL; @@ -1337,35 +1318,27 @@ error: /* Need to convert from VMCALL error codes to Linux */ return -EFAULT; } } -static unsigned int -issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes) + +static int controlvm_channel_create(struct visorchipset_device *dev) { - chipset_dev->controlvm_addr.physaddr = virt_to_phys( - &chipset_dev->controlvm_addr.params); - chipset_dev->controlvm_addr.err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, - chipset_dev->controlvm_addr.physaddr); - if (chipset_dev->controlvm_addr.err) - return chipset_dev->controlvm_addr.err; - - *control_addr = chipset_dev->controlvm_addr.params.address; - *control_bytes = chipset_dev->controlvm_addr.params.channel_bytes; + struct visorchannel *chan; + u64 addr; + int err; + err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, + virt_to_phys(&dev->controlvm_params)); + if (err) + return err; + addr = dev->controlvm_params.address; + chan = visorchannel_create_with_lock(addr, GFP_KERNEL, + &visor_controlvm_channel_guid); + if (!chan) + return -ENOMEM; + dev->controlvm_channel = chan; return 0; } -static u64 controlvm_get_channel_address(void) -{ - u64 addr = 0; - u32 size = 0; - - if (issue_vmcall_io_controlvm_addr(&addr, &size)) - return 0; - - return addr; -} - -static void -setup_crash_devices_work_queue(struct work_struct *work) +static void setup_crash_devices_work_queue(struct work_struct *work) { struct controlvm_message local_crash_bus_msg; struct controlvm_message local_crash_dev_msg; @@ -1444,87 +1417,44 @@ setup_crash_devices_work_queue(struct work_struct *work) visorbus_device_create(&local_crash_dev_msg); } -void -visorbus_create_response(struct visor_device *bus_info, int response) +void visorbus_response(struct visor_device *bus_info, int response, + int controlvm_id) { - if (response >= 0) - bus_info->state.created = 1; - - controlvm_responder(CONTROLVM_BUS_CREATE, bus_info->pending_msg_hdr, - response); + controlvm_responder(controlvm_id, bus_info->pending_msg_hdr, response); kfree(bus_info->pending_msg_hdr); bus_info->pending_msg_hdr = NULL; } -void -visorbus_destroy_response(struct visor_device *bus_info, int response) -{ - controlvm_responder(CONTROLVM_BUS_DESTROY, bus_info->pending_msg_hdr, - response); - - kfree(bus_info->pending_msg_hdr); - bus_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_create_response(struct visor_device *dev_info, int response) -{ - if (response >= 0) - dev_info->state.created = 1; - - controlvm_responder(CONTROLVM_DEVICE_CREATE, dev_info->pending_msg_hdr, - response); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_destroy_response(struct visor_device *dev_info, int response) -{ - controlvm_responder(CONTROLVM_DEVICE_DESTROY, dev_info->pending_msg_hdr, - response); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; -} - -void -visorbus_device_pause_response(struct visor_device *dev_info, int response) +void visorbus_device_changestate_response(struct visor_device *dev_info, + int response, + struct visor_segment_state state) { device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - dev_info, response, - segment_state_standby); + dev_info, response, state); kfree(dev_info->pending_msg_hdr); dev_info->pending_msg_hdr = NULL; } -void -visorbus_device_resume_response(struct visor_device *dev_info, int response) +static void parser_done(struct parser_context *ctx) { - device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, - dev_info, response, - segment_state_running); - - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; + chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes; + kfree(ctx); } -static struct parser_context * -parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) +static struct parser_context *parser_init_stream(u64 addr, u32 bytes, + bool *retry) { - int allocbytes = sizeof(struct parser_context) + bytes; + int allocbytes; struct parser_context *ctx; + void *mapping; *retry = false; - /* - * alloc an 0 extra byte to ensure payload is - * '\0'-terminated - */ - allocbytes++; + /* alloc an extra byte to ensure payload is \0 terminated */ + allocbytes = bytes + 1 + (sizeof(struct parser_context) - + sizeof(struct visor_controlvm_parameters_header)); if ((chipset_dev->controlvm_payload_bytes_buffered + bytes) > MAX_CONTROLVM_PAYLOAD_BYTES) { *retry = true; @@ -1538,32 +1468,18 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry) ctx->allocbytes = allocbytes; ctx->param_bytes = bytes; - ctx->curr = NULL; - ctx->bytes_remaining = 0; - ctx->byte_stream = false; - if (local) { - void *p; - - if (addr > virt_to_phys(high_memory - 1)) - goto err_finish_ctx; - p = __va((unsigned long)(addr)); - memcpy(ctx->data, p, bytes); - } else { - void *mapping = memremap(addr, bytes, MEMREMAP_WB); - - if (!mapping) - goto err_finish_ctx; - memcpy(ctx->data, mapping, bytes); - memunmap(mapping); - } - + mapping = memremap(addr, bytes, MEMREMAP_WB); + if (!mapping) + goto err_finish_ctx; + memcpy(&ctx->data, mapping, bytes); + memunmap(mapping); ctx->byte_stream = true; chipset_dev->controlvm_payload_bytes_buffered += ctx->param_bytes; return ctx; err_finish_ctx: - parser_done(ctx); + kfree(ctx); return NULL; } @@ -1580,19 +1496,16 @@ err_finish_ctx: * which to copy out controlvm payload data. * < 0 - error: ControlVM message was processed but an error occurred. */ -static int -handle_command(struct controlvm_message inmsg, u64 channel_addr) +static int handle_command(struct controlvm_message inmsg, u64 channel_addr) { struct controlvm_message_packet *cmd = &inmsg.cmd; u64 parm_addr; u32 parm_bytes; struct parser_context *parser_ctx = NULL; - bool local_addr; struct controlvm_message ackmsg; int err = 0; /* create parsing context if necessary */ - local_addr = (inmsg.hdr.flags.test_message == 1); parm_addr = channel_addr + inmsg.hdr.payload_vm_offset; parm_bytes = inmsg.hdr.payload_bytes; @@ -1601,25 +1514,19 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) * within our OS-controlled memory. We need to know that, because it * makes a difference in how we compute the virtual address. */ - if (parm_addr && parm_bytes) { + if (parm_bytes) { bool retry = false; - parser_ctx = - parser_init_byte_stream(parm_addr, parm_bytes, - local_addr, &retry); + parser_ctx = parser_init_stream(parm_addr, parm_bytes, &retry); if (!parser_ctx && retry) return -EAGAIN; } + controlvm_init_response(&ackmsg, &inmsg.hdr, CONTROLVM_RESP_SUCCESS); + err = visorchannel_signalinsert(chipset_dev->controlvm_channel, + CONTROLVM_QUEUE_ACK, &ackmsg); + if (err) + return err; - if (!local_addr) { - controlvm_init_response(&ackmsg, &inmsg.hdr, - CONTROLVM_RESP_SUCCESS); - err = visorchannel_signalinsert(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_ACK, - &ackmsg); - if (err) - return err; - } switch (inmsg.hdr.id) { case CONTROLVM_CHIPSET_INIT: err = chipset_init(&inmsg); @@ -1641,8 +1548,8 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) err = parahotplug_process_message(&inmsg); } else { /* - * save the hdr and cmd structures for later use - * when sending back the response to Command + * save the hdr and cmd structures for later use when + * sending back the response to Command */ err = visorbus_device_changestate(&inmsg); break; @@ -1689,12 +1596,9 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr) * * Return: 0 if valid message was retrieved or -error */ -static int -read_controlvm_event(struct controlvm_message *msg) +static int read_controlvm_event(struct controlvm_message *msg) { - int err; - - err = visorchannel_signalremove(chipset_dev->controlvm_channel, + int err = visorchannel_signalremove(chipset_dev->controlvm_channel, CONTROLVM_QUEUE_EVENT, msg); if (err) return err; @@ -1710,8 +1614,7 @@ read_controlvm_event(struct controlvm_message *msg) * parahotplug_process_list() - remove any request from the list that's been on * there too long and respond with an error */ -static void -parahotplug_process_list(void) +static void parahotplug_process_list(void) { struct list_head *pos; struct list_head *tmp; @@ -1737,8 +1640,7 @@ parahotplug_process_list(void) spin_unlock(¶hotplug_request_list_lock); } -static void -controlvm_periodic_work(struct work_struct *work) +static void controlvm_periodic_work(struct work_struct *work) { struct controlvm_message inmsg; int count = 0; @@ -1756,9 +1658,8 @@ controlvm_periodic_work(struct work_struct *work) if (chipset_dev->controlvm_pending_msg_valid) { /* - * we throttled processing of a prior - * msg, so try to process it again - * rather than reading a new one + * we throttled processing of a prior msg, so try to process + * it again rather than reading a new one */ inmsg = chipset_dev->controlvm_pending_msg; chipset_dev->controlvm_pending_msg_valid = false; @@ -1793,9 +1694,8 @@ schedule_out: if (time_after(jiffies, chipset_dev->most_recent_message_jiffies + (HZ * MIN_IDLE_SECONDS))) { /* - * it's been longer than MIN_IDLE_SECONDS since we - * processed our last controlvm message; slow down the - * polling + * it's been longer than MIN_IDLE_SECONDS since we processed + * our last controlvm message; slow down the polling */ if (chipset_dev->poll_jiffies != POLLJIFFIES_CONTROLVMCHANNEL_SLOW) @@ -1812,41 +1712,36 @@ schedule_out: chipset_dev->poll_jiffies); } -static int -visorchipset_init(struct acpi_device *acpi_device) +static int visorchipset_init(struct acpi_device *acpi_device) { int err = -ENODEV; - u64 addr; - uuid_le uuid = VISOR_CONTROLVM_CHANNEL_UUID; struct visorchannel *controlvm_channel; chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL); if (!chipset_dev) goto error; - addr = controlvm_get_channel_address(); - if (!addr) - goto error; - - acpi_device->driver_data = chipset_dev; - - chipset_dev->acpi_device = acpi_device; - chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST; - controlvm_channel = visorchannel_create_with_lock(addr, - 0, GFP_KERNEL, uuid); - - if (!controlvm_channel) + err = controlvm_channel_create(chipset_dev); + if (err) goto error_free_chipset_dev; - chipset_dev->controlvm_channel = controlvm_channel; + acpi_device->driver_data = chipset_dev; + chipset_dev->acpi_device = acpi_device; + chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVMCHANNEL_FAST; err = sysfs_create_groups(&chipset_dev->acpi_device->dev.kobj, visorchipset_dev_groups); if (err < 0) goto error_destroy_channel; - if (!VISOR_CONTROLVM_CHANNEL_OK_CLIENT( - visorchannel_get_header(controlvm_channel))) + controlvm_channel = chipset_dev->controlvm_channel; + if (!visor_check_channel(visorchannel_get_header(controlvm_channel), + &chipset_dev->acpi_device->dev, + &visor_controlvm_channel_guid, + "controlvm", + sizeof(struct visor_controlvm_channel), + VISOR_CONTROLVM_CHANNEL_VERSIONID, + VISOR_CHANNEL_SIGNATURE)) goto error_delete_groups; /* if booting in a crash kernel */ @@ -1886,8 +1781,7 @@ error: return err; } -static int -visorchipset_exit(struct acpi_device *acpi_device) +static int visorchipset_exit(struct acpi_device *acpi_device) { visorbus_exit(); cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work); @@ -1928,12 +1822,11 @@ static __init int visorutil_spar_detect(void) return (ebx == UNISYS_VISOR_ID_EBX) && (ecx == UNISYS_VISOR_ID_ECX) && (edx == UNISYS_VISOR_ID_EDX); - } else { - return 0; } + return 0; } -static int init_unisys(void) +static int __init init_unisys(void) { int result; @@ -1948,7 +1841,7 @@ static int init_unisys(void) return 0; }; -static void exit_unisys(void) +static void __exit exit_unisys(void) { acpi_bus_unregister_driver(&unisys_acpi_driver); } diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h deleted file mode 100644 index cc70e1b16bda..000000000000 --- a/drivers/staging/unisys/visorbus/vmcallinterface.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __VMCALLINTERFACE_H__ -#define __VMCALLINTERFACE_H__ - -enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */ - /* Note: when a new VMCALL is added: - * - the 1st 2 hex digits correspond to one of the - * VMCALL_MONITOR_INTERFACE types and - * - the next 2 hex digits are the nth relative instance of within a - * type - * E.G. for VMCALL_VIRTPART_RECYCLE_PART, - * - the 0x02 identifies it as a VMCALL_VIRTPART type and - * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART - * type of VMCALL - */ - /* used by all Guests, not just IO */ - VMCALL_CONTROLVM_ADDR = 0x0501, -}; - -enum vmcall_result { - VMCALL_RESULT_SUCCESS = 0, - VMCALL_RESULT_INVALID_PARAM = 1, - VMCALL_RESULT_DATA_UNAVAILABLE = 2, - VMCALL_RESULT_FAILURE_UNAVAILABLE = 3, - VMCALL_RESULT_DEVICE_ERROR = 4, - VMCALL_RESULT_DEVICE_NOT_READY = 5 -}; - -/* Structures for IO VMCALLs */ -/* Parameters to VMCALL_CONTROLVM_ADDR interface */ -struct vmcall_io_controlvm_addr_params { - /* The Guest-relative physical address of the ControlVm channel. */ - /* This VMCall fills this in with the appropriate address. */ - u64 address; /* contents provided by this VMCALL (OUT) */ - /* the size of the ControlVm channel in bytes This VMCall fills this */ - /* in with the appropriate address. */ - u32 channel_bytes; /* contents provided by this VMCALL (OUT) */ - u8 unused[4]; /* Unused Bytes in the 64-Bit Aligned Struct */ -} __packed; - -#endif /* __VMCALLINTERFACE_H__ */ diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index a6e7a6bbc428..419dba89af06 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2012 - 2015 UNISYS CORPORATION +/* + * Copyright (c) 2012 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify @@ -14,7 +15,6 @@ */ #include -#include #include #include #include @@ -39,16 +39,16 @@ static struct visor_channeltype_descriptor visorhba_channel_types[] = { /* Note that the only channel type we expect to be reported by the * bus driver is the VISOR_VHBA channel. */ - { VISOR_VHBA_CHANNEL_UUID, "sparvhba" }, - { NULL_UUID_LE, NULL } + { VISOR_VHBA_CHANNEL_GUID, "sparvhba" }, + {} }; MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types); -MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_GUID_STR); struct visordisk_info { + struct scsi_device *sdev; u32 valid; - u32 channel, id, lun; /* Disk Path */ atomic_t ios_threshold; atomic_t error_count; struct visordisk_info *next; @@ -56,8 +56,10 @@ struct visordisk_info { struct scsipending { struct uiscmdrsp cmdrsp; - void *sent; /* The Data being tracked */ - char cmdtype; /* Type of pointer that is being stored */ + /* The Data being tracked */ + void *sent; + /* Type of pointer that is being stored */ + char cmdtype; }; /* Each scsi_host has a host_data area that contains this struct. */ @@ -71,7 +73,8 @@ struct visorhba_devdata { struct scsipending pending[MAX_PENDING_REQUESTS]; /* Start search for next pending free slot here */ unsigned int nextinsert; - spinlock_t privlock; /* lock to protect data in devdata */ + /* lock to protect data in devdata */ + spinlock_t privlock; bool serverdown; bool serverchangingstate; unsigned long long acquire_failed_cnt; @@ -101,25 +104,19 @@ struct visorhba_devices_open { struct visorhba_devdata *devdata; }; -#define for_each_vdisk_match(iter, list, match) \ - for (iter = &list->head; iter->next; iter = iter->next) \ - if ((iter->channel == match->channel) && \ - (iter->id == match->id) && \ - (iter->lun == match->lun)) - /* - * visor_thread_start - starts a thread for the device - * @threadfn: Function the thread starts - * @thrcontext: Context to pass to the thread, i.e. devdata - * @name: string describing name of thread + * visor_thread_start - Starts a thread for the device + * @threadfn: Function the thread starts + * @thrcontext: Context to pass to the thread, i.e. devdata + * @name: String describing name of thread * - * Starts a thread for the device. + * Starts a thread for the device. * - * Return the task_struct * denoting the thread on success, - * or NULL on failure + * Return: The task_struct * denoting the thread on success, + * or NULL on failure */ -static struct task_struct *visor_thread_start -(int (*threadfn)(void *), void *thrcontext, char *name) +static struct task_struct *visor_thread_start(int (*threadfn)(void *), + void *thrcontext, char *name) { struct task_struct *task; @@ -132,27 +129,27 @@ static struct task_struct *visor_thread_start } /* - * visor_thread_stop - stops the thread if it is running + * visor_thread_stop - Stops the thread if it is running + * @task: Description of process to stop */ static void visor_thread_stop(struct task_struct *task) { - if (!task) - return; /* no thread running */ kthread_stop(task); } /* - * add_scsipending_entry - save off io command that is pending in - * Service Partition - * @devdata: Pointer to devdata - * @cmdtype: Specifies the type of command pending - * @new: The command to be saved + * add_scsipending_entry - Save off io command that is pending in + * Service Partition + * @devdata: Pointer to devdata + * @cmdtype: Specifies the type of command pending + * @new: The command to be saved * - * Saves off the io command that is being handled by the Service - * Partition so that it can be handled when it completes. If new is - * NULL it is assumed the entry refers only to the cmdrsp. - * Returns insert_location where entry was added, - * -EBUSY if it can't + * Saves off the io command that is being handled by the Service + * Partition so that it can be handled when it completes. If new is + * NULL it is assumed the entry refers only to the cmdrsp. + * + * Return: Insert_location where entry was added on success, + * -EBUSY if it can't */ static int add_scsipending_entry(struct visorhba_devdata *devdata, char cmdtype, void *new) @@ -176,7 +173,8 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata, entry->cmdtype = cmdtype; if (new) entry->sent = new; - else /* wants to send cmdrsp */ + /* wants to send cmdrsp */ + else entry->sent = &entry->cmdrsp; devdata->nextinsert = (insert_location + 1) % MAX_PENDING_REQUESTS; spin_unlock_irqrestore(&devdata->privlock, flags); @@ -185,15 +183,15 @@ static int add_scsipending_entry(struct visorhba_devdata *devdata, } /* - * del_scsipending_ent - removes an entry from the pending array - * @devdata: Device holding the pending array - * @del: Entry to remove + * del_scsipending_ent - Removes an entry from the pending array + * @devdata: Device holding the pending array + * @del: Entry to remove * - * Removes the entry pointed at by del and returns it. - * Returns the scsipending entry pointed at + * Removes the entry pointed at by del and returns it. + * + * Return: The scsipending entry pointed to on success, NULL on failure */ -static void *del_scsipending_ent(struct visorhba_devdata *devdata, - int del) +static void *del_scsipending_ent(struct visorhba_devdata *devdata, int del) { unsigned long flags; void *sent; @@ -203,7 +201,6 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata, spin_lock_irqsave(&devdata->privlock, flags); sent = devdata->pending[del].sent; - devdata->pending[del].cmdtype = 0; devdata->pending[del].sent = NULL; spin_unlock_irqrestore(&devdata->privlock, flags); @@ -212,13 +209,14 @@ static void *del_scsipending_ent(struct visorhba_devdata *devdata, } /* - * get_scsipending_cmdrsp - return the cmdrsp stored in a pending entry - * @ddata: Device holding the pending array - * @ent: Entry that stores the cmdrsp + * get_scsipending_cmdrsp - Return the cmdrsp stored in a pending entry + * @ddata: Device holding the pending array + * @ent: Entry that stores the cmdrsp * - * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid - * if the "sent" field is not NULL - * Returns a pointer to the cmdrsp. + * Each scsipending entry has a cmdrsp in it. The cmdrsp is only valid + * if the "sent" field is not NULL. + * + * Return: A pointer to the cmdrsp, NULL on failure */ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata, int ent) @@ -230,13 +228,15 @@ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata, } /* - * simple_idr_get - associate a provided pointer with an int value - * 1 <= value <= INT_MAX, and return this int value; - * the pointer value can be obtained later by passing - * this int value to idr_find() - * @idrtable: the data object maintaining the pointer<-->int mappings - * @p: the pointer value to be remembered - * @lock: a spinlock used when exclusive access to idrtable is needed + * simple_idr_get - Associate a provided pointer with an int value + * 1 <= value <= INT_MAX, and return this int value; + * the pointer value can be obtained later by passing + * this int value to idr_find() + * @idrtable: The data object maintaining the pointer<-->int mappings + * @p: The pointer value to be remembered + * @lock: A spinlock used when exclusive access to idrtable is needed + * + * Return: The id number mapped to pointer 'p', 0 on failure */ static unsigned int simple_idr_get(struct idr *idrtable, void *p, spinlock_t *lock) @@ -249,16 +249,23 @@ static unsigned int simple_idr_get(struct idr *idrtable, void *p, id = idr_alloc(idrtable, p, 1, INT_MAX, GFP_NOWAIT); spin_unlock_irqrestore(lock, flags); idr_preload_end(); + /* failure */ if (id < 0) - return 0; /* failure */ - return (unsigned int)(id); /* idr_alloc() guarantees > 0 */ + return 0; + /* idr_alloc() guarantees > 0 */ + return (unsigned int)(id); } /* - * setup_scsitaskmgmt_handles - stash the necessary handles so that the - * completion processing logic for a taskmgmt - * cmd will be able to find who to wake up - * and where to stash the result + * setup_scsitaskmgmt_handles - Stash the necessary handles so that the + * completion processing logic for a taskmgmt + * cmd will be able to find who to wake up + * and where to stash the result + * @idrtable: The data object maintaining the pointer<-->int mappings + * @lock: A spinlock used when exclusive access to idrtable is needed + * @cmdrsp: Response from the IOVM + * @event: The event handle to associate with an id + * @result: The location to place the result of the event handle into */ static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock, struct uiscmdrsp *cmdrsp, @@ -273,8 +280,10 @@ static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock, } /* - * cleanup_scsitaskmgmt_handles - forget handles created by - * setup_scsitaskmgmt_handles() + * cleanup_scsitaskmgmt_handles - Forget handles created by + * setup_scsitaskmgmt_handles() + * @idrtable: The data object maintaining the pointer<-->int mappings + * @cmdrsp: Response from the IOVM */ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, struct uiscmdrsp *cmdrsp) @@ -286,20 +295,20 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, } /* - * forward_taskmgmt_command - send taskmegmt command to the Service - * Partition - * @tasktype: Type of taskmgmt command - * @scsidev: Scsidev that issued command + * forward_taskmgmt_command - Send taskmegmt command to the Service + * Partition + * @tasktype: Type of taskmgmt command + * @scsidev: Scsidev that issued command * - * Create a cmdrsp packet and send it to the Serivce Partition - * that will service this request. - * Returns whether the command was queued successfully or not. + * Create a cmdrsp packet and send it to the Serivce Partition + * that will service this request. + * + * Return: Int representing whether command was queued successfully or not */ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, - struct scsi_cmnd *scsicmd) + struct scsi_device *scsidev) { struct uiscmdrsp *cmdrsp; - struct scsi_device *scsidev = scsicmd->device; struct visorhba_devdata *devdata = (struct visorhba_devdata *)scsidev->host->hostdata; int notifyresult = 0xffff; @@ -347,12 +356,6 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, dev_dbg(&scsidev->sdev_gendev, "visorhba: taskmgmt type=%d success; result=0x%x\n", tasktype, notifyresult); - if (tasktype == TASK_MGMT_ABORT_TASK) - scsicmd->result = DID_ABORT << 16; - else - scsicmd->result = DID_RESET << 16; - - scsicmd->scsi_done(scsicmd); cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp); return SUCCESS; @@ -365,97 +368,105 @@ err_del_scsipending_ent: } /* - * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK - * @scsicmd: The scsicmd that needs aborted - * - * Returns SUCCESS if inserted, failure otherwise + * visorhba_abort_handler - Send TASK_MGMT_ABORT_TASK + * @scsicmd: The scsicmd that needs aborted * + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_ABORT_TASK */ struct scsi_device *scsidev; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; + int rtn; scsidev = scsicmd->device; - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) - atomic_inc(&vdisk->error_count); - else - atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) + atomic_inc(&vdisk->error_count); + else + atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + rtn = forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsidev); + if (rtn == SUCCESS) { + scsicmd->result = DID_ABORT << 16; + scsicmd->scsi_done(scsicmd); } - return forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsicmd); + return rtn; } /* - * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET - * @scsicmd: The scsicmd that needs aborted + * visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET + * @scsicmd: The scsicmd that needs aborted * - * Returns SUCCESS if inserted, failure otherwise + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_LUN_RESET */ struct scsi_device *scsidev; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; + int rtn; scsidev = scsicmd->device; - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) - atomic_inc(&vdisk->error_count); - else - atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) + atomic_inc(&vdisk->error_count); + else + atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); + rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev); + if (rtn == SUCCESS) { + scsicmd->result = DID_RESET << 16; + scsicmd->scsi_done(scsicmd); } - return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsicmd); + return rtn; } /* - * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each - * target on the bus - * @scsicmd: The scsicmd that needs aborted + * visorhba_bus_reset_handler - Send TASK_MGMT_TARGET_RESET for each + * target on the bus + * @scsicmd: The scsicmd that needs aborted * - * Returns SUCCESS + * Return: SUCCESS if inserted, FAILED otherwise */ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd) { struct scsi_device *scsidev; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; + int rtn; scsidev = scsicmd->device; - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { + shost_for_each_device(scsidev, scsidev->host) { + vdisk = scsidev->hostdata; if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) atomic_inc(&vdisk->error_count); else atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); } - return forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsicmd); + rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev); + if (rtn == SUCCESS) { + scsicmd->result = DID_RESET << 16; + scsicmd->scsi_done(scsicmd); + } + return rtn; } /* - * visorhba_host_reset_handler - Not supported - * @scsicmd: The scsicmd that needs aborted + * visorhba_host_reset_handler - Not supported + * @scsicmd: The scsicmd that needs to be aborted * - * Not supported, return SUCCESS - * Returns SUCCESS + * Return: Not supported, return SUCCESS */ -static int -visorhba_host_reset_handler(struct scsi_cmnd *scsicmd) +static int visorhba_host_reset_handler(struct scsi_cmnd *scsicmd) { /* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */ return SUCCESS; } /* - * visorhba_get_info - * @shp: Scsi host that is requesting information + * visorhba_get_info - Get information about SCSI device + * @shp: Scsi host that is requesting information * - * Returns string with info + * Return: String with visorhba information */ static const char *visorhba_get_info(struct Scsi_Host *shp) { @@ -464,19 +475,42 @@ static const char *visorhba_get_info(struct Scsi_Host *shp) } /* - * visorhba_queue_command_lck -- queues command to the Service Partition - * @scsicmd: Command to be queued - * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned + * dma_data_dir_linux_to_spar - convert dma_data_direction value to + * Unisys-specific equivalent + * @d: dma direction value to convert * - * Queues to scsicmd to the ServicePartition after converting it to a - * uiscmdrsp structure. - * - * Returns success if queued to the Service Partition, otherwise - * failure. + * Returns the Unisys-specific dma direction value corresponding to @d */ -static int -visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, - void (*visorhba_cmnd_done)(struct scsi_cmnd *)) +static u32 dma_data_dir_linux_to_spar(enum dma_data_direction d) +{ + switch (d) { + case DMA_BIDIRECTIONAL: + return UIS_DMA_BIDIRECTIONAL; + case DMA_TO_DEVICE: + return UIS_DMA_TO_DEVICE; + case DMA_FROM_DEVICE: + return UIS_DMA_FROM_DEVICE; + case DMA_NONE: + return UIS_DMA_NONE; + default: + return UIS_DMA_NONE; + } +} + +/* + * visorhba_queue_command_lck - Queues command to the Service Partition + * @scsicmd: Command to be queued + * @vsiorhba_cmnd_done: Done command to call when scsicmd is returned + * + * Queues to scsicmd to the ServicePartition after converting it to a + * uiscmdrsp structure. + * + * Return: 0 if successfully queued to the Service Partition, otherwise + * error code + */ +static int visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, + void (*visorhba_cmnd_done) + (struct scsi_cmnd *)) { struct uiscmdrsp *cmdrsp; struct scsi_device *scsidev = scsicmd->device; @@ -494,12 +528,10 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, insert_location = add_scsipending_entry(devdata, CMD_SCSI_TYPE, (void *)scsicmd); - if (insert_location < 0) return SCSI_MLQUEUE_DEVICE_BUSY; cmdrsp = get_scsipending_cmdrsp(devdata, insert_location); - cmdrsp->cmdtype = CMD_SCSI_TYPE; /* save the pending insertion location. Deletion from pending * will return the scsicmd pointer for completion @@ -513,9 +545,9 @@ visorhba_queue_command_lck(struct scsi_cmnd *scsicmd, cmdrsp->scsi.vdest.id = scsidev->id; cmdrsp->scsi.vdest.lun = scsidev->lun; /* save datadir */ - cmdrsp->scsi.data_dir = scsicmd->sc_data_direction; + cmdrsp->scsi.data_dir = + dma_data_dir_linux_to_spar(scsicmd->sc_data_direction); memcpy(cmdrsp->scsi.cmnd, cdb, MAX_CMND_SIZE); - cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd); /* keep track of the max buffer length so far. */ @@ -555,13 +587,13 @@ static DEF_SCSI_QCMD(visorhba_queue_command) #endif /* - * visorhba_slave_alloc - called when new disk is discovered - * @scsidev: New disk + * visorhba_slave_alloc - Called when new disk is discovered + * @scsidev: New disk * - * Create a new visordisk_info structure and add it to our - * list of vdisks. + * Create a new visordisk_info structure and add it to our + * list of vdisks. * - * Returns success when created, otherwise error. + * Return: 0 on success, -ENOMEM on failure. */ static int visorhba_slave_alloc(struct scsi_device *scsidev) { @@ -569,51 +601,41 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev) * LLD can alloc any struct & do init if needed. */ struct visordisk_info *vdisk; - struct visordisk_info *tmpvdisk; struct visorhba_devdata *devdata; struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; + /* already allocated return success */ + if (scsidev->hostdata) + return 0; + + /* even though we errored, treat as success */ devdata = (struct visorhba_devdata *)scsihost->hostdata; if (!devdata) - return 0; /* even though we errored, treat as success */ + return 0; - for_each_vdisk_match(vdisk, devdata, scsidev) - return 0; /* already allocated return success */ - - tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC); - if (!tmpvdisk) + vdisk = kzalloc(sizeof(*vdisk), GFP_ATOMIC); + if (!vdisk) return -ENOMEM; - tmpvdisk->channel = scsidev->channel; - tmpvdisk->id = scsidev->id; - tmpvdisk->lun = scsidev->lun; - vdisk->next = tmpvdisk; + vdisk->sdev = scsidev; + scsidev->hostdata = vdisk; return 0; } /* - * visorhba_slave_destroy - disk is going away - * @scsidev: scsi device going away - * - * Disk is going away, clean up resources. - * Returns void. + * visorhba_slave_destroy - Disk is going away, clean up resources. + * @scsidev: Scsi device to destroy */ static void visorhba_slave_destroy(struct scsi_device *scsidev) { /* midlevel calls this after device has been quiesced and * before it is to be deleted. */ - struct visordisk_info *vdisk, *delvdisk; - struct visorhba_devdata *devdata; - struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; + struct visordisk_info *vdisk; - devdata = (struct visorhba_devdata *)scsihost->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - delvdisk = vdisk->next; - vdisk->next = delvdisk->next; - kfree(delvdisk); - return; - } + vdisk = scsidev->hostdata; + scsidev->hostdata = NULL; + kfree(vdisk); } static struct scsi_host_template visorhba_driver_template = { @@ -635,10 +657,13 @@ static struct scsi_host_template visorhba_driver_template = { }; /* - * info_debugfs_show - debugfs interface to dump visorhba states + * info_debugfs_show - Debugfs interface to dump visorhba states + * @seq: The sequence file to write information to + * @v: Unused, but needed for use with seq file single_open invocation * - * This presents a file in the debugfs tree named: - * /visorhba/vbus:dev/info + * Presents a file in the debugfs tree named: /visorhba/vbus:dev/info. + * + * Return: SUCCESS */ static int info_debugfs_show(struct seq_file *seq, void *v) { @@ -679,12 +704,13 @@ static const struct file_operations info_debugfs_fops = { }; /* - * complete_taskmgmt_command - complete task management - * @cmdrsp: Response from the IOVM + * complete_taskmgmt_command - Complete task management + * @idrtable: The data object maintaining the pointer<-->int mappings + * @cmdrsp: Response from the IOVM + * @result: The result of the task management command * - * Service Partition returned the result of the task management - * command. Wake up anyone waiting for it. - * Returns void + * Service Partition returned the result of the task management + * command. Wake up anyone waiting for it. */ static void complete_taskmgmt_command(struct idr *idrtable, struct uiscmdrsp *cmdrsp, int result) @@ -693,7 +719,6 @@ static void complete_taskmgmt_command(struct idr *idrtable, idr_find(idrtable, cmdrsp->scsitaskmgmt.notify_handle); int *scsi_result_ptr = idr_find(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle); - if (unlikely(!(wq && scsi_result_ptr))) { pr_err("visorhba: no completion context; cmd will time out\n"); return; @@ -708,13 +733,12 @@ static void complete_taskmgmt_command(struct idr *idrtable, } /* - * visorhba_serverdown_complete - Called when we are done cleaning up - * from serverdown - * @work: work structure for this serverdown request + * visorhba_serverdown_complete - Called when we are done cleaning up + * from serverdown + * @devdata: Visorhba instance on which to complete serverdown * - * Called when we are done cleanning up from serverdown, stop processing - * queue, fail pending IOs. - * Returns void when finished cleaning up + * Called when we are done cleanning up from serverdown, stop processing + * queue, fail pending IOs. */ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) { @@ -758,12 +782,13 @@ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) } /* - * visorhba_serverdown - Got notified that the IOVM is down - * @devdata: visorhba that is being serviced by downed IOVM. + * visorhba_serverdown - Got notified that the IOVM is down + * @devdata: Visorhba that is being serviced by downed IOVM * - * Something happened to the IOVM, return immediately and - * schedule work cleanup work. - * Return SUCCESS or EINVAL + * Something happened to the IOVM, return immediately and + * schedule cleanup work. + * + * Return: 0 on success, -EINVAL on failure */ static int visorhba_serverdown(struct visorhba_devdata *devdata) { @@ -777,17 +802,15 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata) } /* - * do_scsi_linuxstat - scsi command returned linuxstat - * @cmdrsp: response from IOVM - * @scsicmd: Command issued. + * do_scsi_linuxstat - Scsi command returned linuxstat + * @cmdrsp: Response from IOVM + * @scsicmd: Command issued * - * Don't log errors for disk-not-present inquiries - * Returns void + * Don't log errors for disk-not-present inquiries. */ -static void -do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { - struct visorhba_devdata *devdata; struct visordisk_info *vdisk; struct scsi_device *scsidev; @@ -800,19 +823,17 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT)) return; /* Okay see what our error_count is here.... */ - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) { - atomic_inc(&vdisk->error_count); - atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); - } + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) { + atomic_inc(&vdisk->error_count); + atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); } } -static int set_no_disk_inquiry_result(unsigned char *buf, - size_t len, bool is_lun0) +static int set_no_disk_inquiry_result(unsigned char *buf, size_t len, + bool is_lun0) { - if (!buf || len < NO_DISK_INQUIRY_RESULT_LEN) + if (len < NO_DISK_INQUIRY_RESULT_LEN) return -EINVAL; memset(buf, 0, NO_DISK_INQUIRY_RESULT_LEN); buf[2] = SCSI_SPC2_VER; @@ -828,15 +849,14 @@ static int set_no_disk_inquiry_result(unsigned char *buf, } /* - * do_scsi_nolinuxstat - scsi command didn't have linuxstat - * @cmdrsp: response from IOVM - * @scsicmd: Command issued. + * do_scsi_nolinuxstat - Scsi command didn't have linuxstat + * @cmdrsp: Response from IOVM + * @scsicmd: Command issued * - * Handle response when no linuxstat was returned - * Returns void + * Handle response when no linuxstat was returned. */ -static void -do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { struct scsi_device *scsidev; unsigned char *buf; @@ -846,7 +866,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) char *this_page_orig; int bufind = 0; struct visordisk_info *vdisk; - struct visorhba_devdata *devdata; scsidev = scsicmd->device; if ((cmdrsp->scsi.cmnd[0] == INQUIRY) && @@ -883,28 +902,25 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) } kfree(buf); } else { - devdata = (struct visorhba_devdata *)scsidev->host->hostdata; - for_each_vdisk_match(vdisk, devdata, scsidev) { - if (atomic_read(&vdisk->ios_threshold) > 0) { - atomic_dec(&vdisk->ios_threshold); - if (atomic_read(&vdisk->ios_threshold) == 0) - atomic_set(&vdisk->error_count, 0); - } + vdisk = scsidev->hostdata; + if (atomic_read(&vdisk->ios_threshold) > 0) { + atomic_dec(&vdisk->ios_threshold); + if (atomic_read(&vdisk->ios_threshold) == 0) + atomic_set(&vdisk->error_count, 0); } } } /* - * complete_scsi_command - complete a scsi command - * @uiscmdrsp: Response from Service Partition - * @scsicmd: The scsi command + * complete_scsi_command - Complete a scsi command + * @uiscmdrsp: Response from Service Partition + * @scsicmd: The scsi command * - * Response returned by the Service Partition, finish it and send - * completion to the scsi midlayer. - * Returns void. + * Response was returned by the Service Partition. Finish it and send + * completion to the scsi midlayer. */ -static void -complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) +static void complete_scsi_command(struct uiscmdrsp *cmdrsp, + struct scsi_cmnd *scsicmd) { /* take what we need out of cmdrsp and complete the scsicmd */ scsicmd->result = cmdrsp->scsi.linuxstat; @@ -917,24 +933,23 @@ complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) } /* - * drain_queue - pull responses out of iochannel - * @cmdrsp: Response from the IOSP - * @devdata: device that owns this iochannel + * drain_queue - Pull responses out of iochannel + * @cmdrsp: Response from the IOSP + * @devdata: Device that owns this iochannel * - * Pulls responses out of the iochannel and process the responses. - * Restuns void + * Pulls responses out of the iochannel and process the responses. */ -static void -drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata) +static void drain_queue(struct uiscmdrsp *cmdrsp, + struct visorhba_devdata *devdata) { struct scsi_cmnd *scsicmd; while (1) { + /* queue empty */ if (visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, cmdrsp)) - break; /* queue empty */ - + break; if (cmdrsp->cmdtype == CMD_SCSI_TYPE) { /* scsicmd location is returned by the * deletion @@ -959,12 +974,14 @@ drain_queue(struct uiscmdrsp *cmdrsp, struct visorhba_devdata *devdata) } /* - * process_incoming_rsps - Process responses from IOSP - * @v: void pointer to visorhba_devdata + * process_incoming_rsps - Process responses from IOSP + * @v: Void pointer to visorhba_devdata * - * Main function for the thread that processes the responses - * from the IO Service Partition. When the queue is empty, wait - * to check to see if it is full again. + * Main function for the thread that processes the responses + * from the IO Service Partition. When the queue is empty, wait + * to check to see if it is full again. + * + * Return: 0 on success, -ENOMEM on failure */ static int process_incoming_rsps(void *v) { @@ -991,14 +1008,15 @@ static int process_incoming_rsps(void *v) } /* - * visorhba_pause - function to handle visorbus pause messages - * @dev: device that is pausing. - * @complete_func: function to call when finished + * visorhba_pause - Function to handle visorbus pause messages + * @dev: Device that is pausing + * @complete_func: Function to call when finished * - * Something has happened to the IO Service Partition that is - * handling this device. Quiet this device and reset commands - * so that the Service Partition can be corrected. - * Returns SUCCESS + * Something has happened to the IO Service Partition that is + * handling this device. Quiet this device and reset commands + * so that the Service Partition can be corrected. + * + * Return: SUCCESS */ static int visorhba_pause(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -1011,13 +1029,14 @@ static int visorhba_pause(struct visor_device *dev, } /* - * visorhba_resume - function called when the IO Service Partition is back - * @dev: device that is pausing. - * @complete_func: function to call when finished + * visorhba_resume - Function called when the IO Service Partition is back + * @dev: Device that is pausing + * @complete_func: Function to call when finished * - * Yay! The IO Service Partition is back, the channel has been wiped - * so lets re-establish connection and start processing responses. - * Returns 0 on success, error on failure. + * Yay! The IO Service Partition is back, the channel has been wiped + * so lets re-establish connection and start processing responses. + * + * Return: 0 on success, -EINVAL on failure */ static int visorhba_resume(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -1033,7 +1052,6 @@ static int visorhba_resume(struct visor_device *dev, devdata->thread = visor_thread_start(process_incoming_rsps, devdata, "vhba_incming"); - devdata->serverdown = false; devdata->serverchangingstate = false; @@ -1041,11 +1059,12 @@ static int visorhba_resume(struct visor_device *dev, } /* - * visorhba_probe - device has been discovered, do acquire - * @dev: visor_device that was discovered + * visorhba_probe - Device has been discovered; do acquire + * @dev: visor_device that was discovered * - * A new HBA was discovered, do the initial connections of it. - * Return 0 on success, otherwise error. + * A new HBA was discovered; do the initial connections of it. + * + * Return: 0 on success, otherwise error code */ static int visorhba_probe(struct visor_device *dev) { @@ -1139,11 +1158,10 @@ err_scsi_host_put: } /* - * visorhba_remove - remove a visorhba device - * @dev: Device to remove + * visorhba_remove - Remove a visorhba device + * @dev: Device to remove * - * Removes the visorhba device. - * Returns void. + * Removes the visorhba device. */ static void visorhba_remove(struct visor_device *dev) { @@ -1181,10 +1199,12 @@ static struct visor_driver visorhba_driver = { }; /* - * visorhba_init - driver init routine + * visorhba_init - Driver init routine * - * Initialize the visorhba driver and register it with visorbus - * to handle s-Par virtual host bus adapter. + * Initialize the visorhba driver and register it with visorbus + * to handle s-Par virtual host bus adapter. + * + * Return: 0 on success, error code otherwise */ static int visorhba_init(void) { @@ -1207,9 +1227,9 @@ cleanup_debugfs: } /* - * visorhba_exit - driver exit routine + * visorhba_exit - Driver exit routine * - * Unregister driver from the bus and free up memory. + * Unregister driver from the bus and free up memory. */ static void visorhba_exit(void) { diff --git a/drivers/staging/unisys/visorinput/ultrainputreport.h b/drivers/staging/unisys/visorinput/ultrainputreport.h index a4baea53c518..53975a09535f 100644 --- a/drivers/staging/unisys/visorinput/ultrainputreport.h +++ b/drivers/staging/unisys/visorinput/ultrainputreport.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2010 - 2015 UNISYS CORPORATION +/* + * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. * * This program is free software; you can redistribute it and/or modify it @@ -20,44 +21,35 @@ /* These defines identify mouse and keyboard activity which is specified by the * firmware to the host using the cmsimpleinput protocol. @ingroup coretypes */ -#define INPUTACTION_XY_MOTION 1 /* only motion; arg1=x, arg2=y */ -#define INPUTACTION_MOUSE_BUTTON_DOWN 2 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_UP 3 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_CLICK 4 /* arg1: 1=left,2=center,3=right */ -#define INPUTACTION_MOUSE_BUTTON_DCLICK 5 /* arg1: 1=left,2=center, - * 3=right - */ -#define INPUTACTION_WHEEL_ROTATE_AWAY 6 /* arg1: wheel rotation away from - * user - */ -#define INPUTACTION_WHEEL_ROTATE_TOWARD 7 /* arg1: wheel rotation toward - * user - */ -#define INPUTACTION_KEY_DOWN 64 /* arg1: scancode, as follows: - * If arg1 <= 0xff, it's a 1-byte - * scancode and arg1 is that scancode. - * If arg1 > 0xff, it's a 2-byte - * scanecode, with the 1st byte in the - * low 8 bits, and the 2nd byte in the - * high 8 bits. E.g., the right ALT key - * would appear as x'38e0'. - */ -#define INPUTACTION_KEY_UP 65 /* arg1: scancode (in same format as - * inputaction_keyDown) - */ + /* only motion; arg1=x, arg2=y */ +#define INPUTACTION_XY_MOTION 1 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_DOWN 2 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_UP 3 +/* arg1: 1=left,2=center,3=right */ +#define INPUTACTION_MOUSE_BUTTON_CLICK 4 +/* arg1: 1=left,2=center 3=right */ +#define INPUTACTION_MOUSE_BUTTON_DCLICK 5 +/* arg1: wheel rotation away from user */ +#define INPUTACTION_WHEEL_ROTATE_AWAY 6 +/* arg1: wheel rotation toward user */ +#define INPUTACTION_WHEEL_ROTATE_TOWARD 7 +/* arg1: scancode, as follows: If arg1 <= 0xff, it's a 1-byte scancode and arg1 + * is that scancode. If arg1 > 0xff, it's a 2-byte scanecode, with the 1st + * byte in the low 8 bits, and the 2nd byte in the high 8 bits. + * E.g., the right ALT key would appear as x'38e0'. + */ +#define INPUTACTION_KEY_DOWN 64 +/* arg1: scancode (in same format as inputaction_keyDown) */ +#define INPUTACTION_KEY_UP 65 +/* arg1: scancode (in same format as inputaction_keyDown); MUST refer to one of + * the locking keys, like capslock, numlock, or scrolllock. + * arg2: 1 iff locking key should be in the LOCKED position (e.g., light is ON) + */ #define INPUTACTION_SET_LOCKING_KEY_STATE 66 - /* arg1: scancode (in same format - * as inputaction_keyDown); - * MUST refer to one of the - * locking keys, like capslock, - * numlock, or scrolllock - * arg2: 1 iff locking key should be - * in the LOCKED position - * (e.g., light is ON) - */ -#define INPUTACTION_KEY_DOWN_UP 67 /* arg1: scancode (in same format - * as inputaction_keyDown) - */ +/* arg1: scancode (in same format as inputaction_keyDown */ +#define INPUTACTION_KEY_DOWN_UP 67 struct visor_inputactivity { u16 action; diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 45bc340d4e9d..9d8cbc52de8b 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -1,5 +1,4 @@ -/* visorinput.c - * +/* * Copyright (C) 2011 - 2015 UNISYS CORPORATION * All rights reserved. * @@ -21,11 +20,8 @@ * standard way the Linux expects for input drivers. */ -#include #include -#include #include -#include #include #include @@ -33,16 +29,16 @@ #include "ultrainputreport.h" /* Keyboard channel {c73416d0-b0b8-44af-b304-9d2ae99f1b3d} */ -#define VISOR_KEYBOARD_CHANNEL_UUID \ - UUID_LE(0xc73416d0, 0xb0b8, 0x44af, \ - 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d) -#define VISOR_KEYBOARD_CHANNEL_UUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d" +#define VISOR_KEYBOARD_CHANNEL_GUID \ + GUID_INIT(0xc73416d0, 0xb0b8, 0x44af, \ + 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d) +#define VISOR_KEYBOARD_CHANNEL_GUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d" /* Mouse channel {addf07d4-94a9-46e2-81c3-61abcdbdbd87} */ -#define VISOR_MOUSE_CHANNEL_UUID \ - UUID_LE(0xaddf07d4, 0x94a9, 0x46e2, \ - 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87) -#define VISOR_MOUSE_CHANNEL_UUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87" +#define VISOR_MOUSE_CHANNEL_GUID \ + GUID_INIT(0xaddf07d4, 0x94a9, 0x46e2, \ + 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87) +#define VISOR_MOUSE_CHANNEL_GUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87" #define PIXELS_ACROSS_DEFAULT 800 #define PIXELS_DOWN_DEFAULT 600 @@ -60,17 +56,19 @@ enum visorinput_device_type { */ struct visorinput_devdata { struct visor_device *dev; - struct mutex lock_visor_dev; /* lock for dev */ + /* lock for dev */ + struct mutex lock_visor_dev; struct input_dev *visorinput_dev; bool paused; bool interrupts_enabled; - unsigned int keycode_table_bytes; /* size of following array */ + /* size of following array */ + unsigned int keycode_table_bytes; /* for keyboard devices: visorkbd_keycode[] + visorkbd_ext_keycode[] */ unsigned char keycode_table[0]; }; -static const uuid_le visor_keyboard_channel_uuid = VISOR_KEYBOARD_CHANNEL_UUID; -static const uuid_le visor_mouse_channel_uuid = VISOR_MOUSE_CHANNEL_UUID; +static const guid_t visor_keyboard_channel_guid = VISOR_KEYBOARD_CHANNEL_GUID; +static const guid_t visor_mouse_channel_guid = VISOR_MOUSE_CHANNEL_GUID; /* * Borrowed from drivers/input/keyboard/atakbd.c @@ -162,9 +160,8 @@ static const unsigned char visorkbd_keycode[KEYCODE_TABLE_BYTES] = { [81] = KEY_KP3, [82] = KEY_KP0, [83] = KEY_KPDOT, - [86] = KEY_102ND, /* enables UK backslash+pipe key, - * and FR lessthan+greaterthan key - */ + /* enables UK backslash+pipe key and FR lessthan+greaterthan key */ + [86] = KEY_102ND, [87] = KEY_F11, [88] = KEY_F12, [90] = KEY_KPLEFTPAREN, @@ -260,7 +257,6 @@ static void visorinput_close(struct input_dev *visorinput_dev) * interrupts should be disabled so when we resume we will * not re-enable them. */ - mutex_lock(&devdata->lock_visor_dev); devdata->interrupts_enabled = false; if (devdata->paused) @@ -276,15 +272,13 @@ out_unlock: * we can use to deliver keyboard inputs to Linux. We of course do this when * we see keyboard inputs coming in on a keyboard channel. */ -static struct input_dev * -setup_client_keyboard(void *devdata, /* opaque on purpose */ - unsigned char *keycode_table) +static struct input_dev *setup_client_keyboard(void *devdata, + unsigned char *keycode_table) { int i; - struct input_dev *visorinput_dev; + struct input_dev *visorinput_dev = input_allocate_device(); - visorinput_dev = input_allocate_device(); if (!visorinput_dev) return NULL; @@ -302,7 +296,8 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */ BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML); visorinput_dev->keycode = keycode_table; - visorinput_dev->keycodesize = 1; /* sizeof(unsigned char) */ + /* sizeof(unsigned char) */ + visorinput_dev->keycodesize = 1; visorinput_dev->keycodemax = KEYCODE_TABLE_BYTES; for (i = 1; i < visorinput_dev->keycodemax; i++) @@ -313,19 +308,18 @@ setup_client_keyboard(void *devdata, /* opaque on purpose */ visorinput_dev->open = visorinput_open; visorinput_dev->close = visorinput_close; - input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */ + /* pre input_register! */ + input_set_drvdata(visorinput_dev, devdata); return visorinput_dev; } -static struct input_dev * -setup_client_mouse(void *devdata /* opaque on purpose */) +static struct input_dev *setup_client_mouse(void *devdata) { - struct input_dev *visorinput_dev = NULL; int xres, yres; struct fb_info *fb0; + struct input_dev *visorinput_dev = input_allocate_device(); - visorinput_dev = input_allocate_device(); if (!visorinput_dev) return NULL; @@ -354,14 +348,16 @@ setup_client_mouse(void *devdata /* opaque on purpose */) visorinput_dev->open = visorinput_open; visorinput_dev->close = visorinput_close; - input_set_drvdata(visorinput_dev, devdata); /* pre input_register! */ + /* pre input_register! */ + input_set_drvdata(visorinput_dev, devdata); input_set_capability(visorinput_dev, EV_REL, REL_WHEEL); return visorinput_dev; } -static struct visorinput_devdata * -devdata_create(struct visor_device *dev, enum visorinput_device_type devtype) +static struct visorinput_devdata *devdata_create( + struct visor_device *dev, + enum visorinput_device_type devtype) { struct visorinput_devdata *devdata = NULL; unsigned int extra_bytes = 0; @@ -446,16 +442,15 @@ err_kfree_devdata: return NULL; } -static int -visorinput_probe(struct visor_device *dev) +static int visorinput_probe(struct visor_device *dev) { - uuid_le guid; + const guid_t *guid; enum visorinput_device_type devtype; - guid = visorchannel_get_uuid(dev->visorchannel); - if (uuid_le_cmp(guid, visor_mouse_channel_uuid) == 0) + guid = visorchannel_get_guid(dev->visorchannel); + if (guid_equal(guid, &visor_mouse_channel_guid)) devtype = visorinput_mouse; - else if (uuid_le_cmp(guid, visor_keyboard_channel_uuid) == 0) + else if (guid_equal(guid, &visor_keyboard_channel_guid)) devtype = visorinput_keyboard; else return -ENODEV; @@ -465,15 +460,13 @@ visorinput_probe(struct visor_device *dev) return 0; } -static void -unregister_client_input(struct input_dev *visorinput_dev) +static void unregister_client_input(struct input_dev *visorinput_dev) { if (visorinput_dev) input_unregister_device(visorinput_dev); } -static void -visorinput_remove(struct visor_device *dev) +static void visorinput_remove(struct visor_device *dev) { struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -499,9 +492,8 @@ visorinput_remove(struct visor_device *dev) * Make it so the current locking state of the locking key indicated by * is as indicated by (1=locked, 0=unlocked). */ -static void -handle_locking_key(struct input_dev *visorinput_dev, - int keycode, int desired_state) +static void handle_locking_key(struct input_dev *visorinput_dev, int keycode, + int desired_state) { int led; @@ -533,17 +525,15 @@ handle_locking_key(struct input_dev *visorinput_dev, * with 0xE0 in the low byte and the extended scancode value in the next * higher byte. */ -static int -scancode_to_keycode(int scancode) +static int scancode_to_keycode(int scancode) { if (scancode > 0xff) return visorkbd_ext_keycode[(scancode >> 8) & 0xff]; - return visorkbd_keycode[scancode]; + return visorkbd_keycode[scancode]; } -static int -calc_button(int x) +static int calc_button(int x) { switch (x) { case 1: @@ -562,15 +552,13 @@ calc_button(int x) * client guest partition. It is called periodically so we can obtain inputs * from the channel, and deliver them to the guest OS. */ -static void -visorinput_channel_interrupt(struct visor_device *dev) +static void visorinput_channel_interrupt(struct visor_device *dev) { struct visor_inputreport r; int scancode, keycode; struct input_dev *visorinput_dev; int xmotion, ymotion, button; int i; - struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); if (!devdata) @@ -626,7 +614,6 @@ visorinput_channel_interrupt(struct visor_device *dev) if (button < 0) break; input_report_key(visorinput_dev, button, 1); - input_sync(visorinput_dev); input_report_key(visorinput_dev, button, 0); input_sync(visorinput_dev); @@ -657,9 +644,8 @@ visorinput_channel_interrupt(struct visor_device *dev) } } -static int -visorinput_pause(struct visor_device *dev, - visorbus_state_complete_func complete_func) +static int visorinput_pause(struct visor_device *dev, + visorbus_state_complete_func complete_func) { int rc; struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -681,7 +667,6 @@ visorinput_pause(struct visor_device *dev, * due to above, at this time no thread of execution will be * in visorinput_channel_interrupt() */ - devdata->paused = true; complete_func(dev, 0); rc = 0; @@ -691,9 +676,8 @@ out: return rc; } -static int -visorinput_resume(struct visor_device *dev, - visorbus_state_complete_func complete_func) +static int visorinput_resume(struct visor_device *dev, + visorbus_state_complete_func complete_func) { int rc; struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device); @@ -727,9 +711,9 @@ out: /* GUIDS for all channel types supported by this driver. */ static struct visor_channeltype_descriptor visorinput_channel_types[] = { - { VISOR_KEYBOARD_CHANNEL_UUID, "keyboard"}, - { VISOR_MOUSE_CHANNEL_UUID, "mouse"}, - { NULL_UUID_LE, NULL } + { VISOR_KEYBOARD_CHANNEL_GUID, "keyboard"}, + { VISOR_MOUSE_CHANNEL_GUID, "mouse"}, + {} }; static struct visor_driver visorinput_driver = { @@ -743,20 +727,8 @@ static struct visor_driver visorinput_driver = { .resume = visorinput_resume, }; -static int -visorinput_init(void) -{ - return visorbus_register_visor_driver(&visorinput_driver); -} - -static void -visorinput_cleanup(void) -{ - visorbus_unregister_visor_driver(&visorinput_driver); -} - -module_init(visorinput_init); -module_exit(visorinput_cleanup); +module_driver(visorinput_driver, visorbus_register_visor_driver, + visorbus_unregister_visor_driver); MODULE_DEVICE_TABLE(visorbus, visorinput_channel_types); @@ -764,5 +736,5 @@ MODULE_AUTHOR("Unisys"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("s-Par human input driver for virtual keyboard/mouse"); -MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_UUID_STR); -MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_GUID_STR); +MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_GUID_STR); diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 2891622eef18..dc390eae2960 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -37,22 +37,28 @@ #define NAPI_WEIGHT 64 /* GUIDS for director channel type supported by this driver. */ +/* {8cd5994d-c58e-11da-95a9-00e08161165f} */ +#define VISOR_VNIC_CHANNEL_GUID \ + GUID_INIT(0x8cd5994d, 0xc58e, 0x11da, \ + 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) +#define VISOR_VNIC_CHANNEL_GUID_STR \ + "8cd5994d-c58e-11da-95a9-00e08161165f" + static struct visor_channeltype_descriptor visornic_channel_types[] = { /* Note that the only channel type we expect to be reported by the * bus driver is the VISOR_VNIC channel. */ - { VISOR_VNIC_CHANNEL_UUID, "ultravnic" }, - { NULL_UUID_LE, NULL } + { VISOR_VNIC_CHANNEL_GUID, "ultravnic" }, + {} }; MODULE_DEVICE_TABLE(visorbus, visornic_channel_types); -/* - * FIXME XXX: This next line of code must be fixed and removed before +/* FIXME XXX: This next line of code must be fixed and removed before * acceptance into the 'normal' part of the kernel. It is only here as a place * holder to get module autoloading functionality working for visorbus. Code * must be added to scripts/mode/file2alias.c, etc., to get this working * properly. */ -MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_UUID_STR); +MODULE_ALIAS("visorbus:" VISOR_VNIC_CHANNEL_GUID_STR); struct chanstat { unsigned long got_rcv; @@ -68,10 +74,67 @@ struct chanstat { unsigned long extra_rcvbufs_sent; }; +/* struct visornic_devdata + * @enabled: 0 disabled 1 enabled to receive. + * @enab_dis_acked: NET_RCV_ENABLE/DISABLE acked by IOPART. + * @struct *dev: + * @struct *netdev: + * @struct net_stats: + * @interrupt_rcvd: + * @rsp_queue: + * @struct **rcvbuf: + * @incarnation_id: incarnation_id lets IOPART know about + * re-birth. + * @old_flags: flags as they were prior to + * set_multicast_list. + * @usage: count of users. + * @num_rcv_bufs: number of rcv buffers the vnic will post. + * @num_rcv_bufs_could_not_alloc: + * @num_rcvbuf_in_iovm: + * @alloc_failed_in_if_needed_cnt: + * @alloc_failed_in_repost_rtn_cnt: + * @max_outstanding_net_xmits: absolute max number of outstanding xmits + * - should never hit this. + * @upper_threshold_net_xmits: high water mark for calling + * netif_stop_queue(). + * @lower_threshold_net_xmits: high water mark for calling + * netif_wake_queue(). + * @struct xmitbufhead: xmitbufhead - head of the xmit buffer list + * sent to the IOPART end. + * @server_down_complete_func: + * @struct timeout_reset: + * @struct *cmdrsp_rcv: cmdrsp_rcv is used for posting/unposting rcv + * buffers. + * @struct *xmit_cmdrsp: xmit_cmdrsp - issues NET_XMIT - only one + * active xmit at a time. + * @server_down: IOPART is down. + * @server_change_state: Processing SERVER_CHANGESTATE msg. + * @going_away: device is being torn down. + * @struct *eth_debugfs_dir: + * @interrupts_rcvd: + * @interrupts_notme: + * @interrupts_disabled: + * @busy_cnt: + * @priv_lock: spinlock to access devdata structures. + * @flow_control_upper_hits: + * @flow_control_lower_hits: + * @n_rcv0: # rcvs of 0 buffers. + * @n_rcv1: # rcvs of 1 buffers. + * @n_rcv2: # rcvs of 2 buffers. + * @n_rcvx: # rcvs of >2 buffers. + * @found_repost_rcvbuf_cnt: # repost_rcvbuf_cnt. + * @repost_found_skb_cnt: # of found the skb. + * @n_repost_deficit: # of lost rcv buffers. + * @bad_rcv_buf: # of unknown rcv skb not freed. + * @n_rcv_packets_not_accepted: # bogs rcv packets. + * @queuefullmsg_logged: + * @struct chstat: + * @struct irq_poll_timer: + * @struct napi: + * @struct cmdrsp: + */ struct visornic_devdata { - /* 0 disabled 1 enabled to receive */ unsigned short enabled; - /* NET_RCV_ENABLE/DISABLE acked by IOPART */ unsigned short enab_dis_acked; struct visor_device *dev; @@ -80,59 +143,50 @@ struct visornic_devdata { atomic_t interrupt_rcvd; wait_queue_head_t rsp_queue; struct sk_buff **rcvbuf; - /* incarnation_id lets IOPART know about re-birth */ u64 incarnation_id; - /* flags as they were prior to set_multicast_list */ unsigned short old_flags; - atomic_t usage; /* count of users */ + atomic_t usage; - /* number of rcv buffers the vnic will post */ int num_rcv_bufs; int num_rcv_bufs_could_not_alloc; atomic_t num_rcvbuf_in_iovm; unsigned long alloc_failed_in_if_needed_cnt; unsigned long alloc_failed_in_repost_rtn_cnt; - /* absolute max number of outstanding xmits - should never hit this */ unsigned long max_outstanding_net_xmits; - /* high water mark for calling netif_stop_queue() */ unsigned long upper_threshold_net_xmits; - /* high water mark for calling netif_wake_queue() */ unsigned long lower_threshold_net_xmits; - /* xmitbufhead - head of the xmit buffer list sent to the IOPART end */ struct sk_buff_head xmitbufhead; visorbus_state_complete_func server_down_complete_func; struct work_struct timeout_reset; - /* cmdrsp_rcv is used for posting/unposting rcv buffers */ struct uiscmdrsp *cmdrsp_rcv; - /* xmit_cmdrsp - issues NET_XMIT - only one active xmit at a time */ struct uiscmdrsp *xmit_cmdrsp; - - bool server_down; /* IOPART is down */ - bool server_change_state; /* Processing SERVER_CHANGESTATE msg */ - bool going_away; /* device is being torn down */ + bool server_down; + bool server_change_state; + bool going_away; struct dentry *eth_debugfs_dir; u64 interrupts_rcvd; u64 interrupts_notme; u64 interrupts_disabled; u64 busy_cnt; - spinlock_t priv_lock; /* spinlock to access devdata structures */ + /* spinlock to access devdata structures. */ + spinlock_t priv_lock; /* flow control counter */ u64 flow_control_upper_hits; u64 flow_control_lower_hits; /* debug counters */ - unsigned long n_rcv0; /* # rcvs of 0 buffers */ - unsigned long n_rcv1; /* # rcvs of 1 buffers */ - unsigned long n_rcv2; /* # rcvs of 2 buffers */ - unsigned long n_rcvx; /* # rcvs of >2 buffers */ - unsigned long found_repost_rcvbuf_cnt; /* # repost_rcvbuf_cnt */ - unsigned long repost_found_skb_cnt; /* # of found the skb */ - unsigned long n_repost_deficit; /* # of lost rcv buffers */ - unsigned long bad_rcv_buf; /* # of unknown rcv skb not freed */ - unsigned long n_rcv_packets_not_accepted;/* # bogs rcv packets */ + unsigned long n_rcv0; + unsigned long n_rcv1; + unsigned long n_rcv2; + unsigned long n_rcvx; + unsigned long found_repost_rcvbuf_cnt; + unsigned long repost_found_skb_cnt; + unsigned long n_repost_deficit; + unsigned long bad_rcv_buf; + unsigned long n_rcv_packets_not_accepted; int queuefullmsg_logged; struct chanstat chstat; @@ -142,12 +196,11 @@ struct visornic_devdata { }; /* Returns next non-zero index on success or 0 on failure (i.e. out of room). */ -static u16 -add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, - u16 max_pi_arr_entries, struct phys_info pi_arr[]) +static u16 add_physinfo_entries(u64 inp_pfn, u16 inp_off, u16 inp_len, + u16 index, u16 max_pi_arr_entries, + struct phys_info pi_arr[]) { - u32 len; - u16 i, firstlen; + u16 i, len, firstlen; firstlen = PI_PAGE_SIZE - inp_off; if (inp_len <= firstlen) { @@ -171,29 +224,27 @@ add_physinfo_entries(u64 inp_pfn, u16 inp_off, u32 inp_len, u16 index, pi_arr[index].pi_len = firstlen; } else { pi_arr[index + i].pi_off = 0; - pi_arr[index + i].pi_len = - (u16)MINNUM(len, (u32)PI_PAGE_SIZE); + pi_arr[index + i].pi_len = min_t(u16, len, + PI_PAGE_SIZE); } } return index + i; } -/* - * visor_copy_fragsinfo_from_skb( - * @skb_in: skbuff that we are pulling the frags from - * @firstfraglen: length of first fragment in skb - * @frags_max: max len of frags array - * @frags: frags array filled in on output +/* visor_copy_fragsinfo_from_skb - copy fragment list in the SKB to a phys_info + * array that the IOPART understands + * @skb: Skbuff that we are pulling the frags from. + * @firstfraglen: Length of first fragment in skb. + * @frags_max: Max len of frags array. + * @frags: Frags array filled in on output. * - * Copy the fragment list in the SKB to a phys_info - * array that the IOPART understands. - * Return value indicates number of entries filled in frags - * Negative values indicate an error. + * Return: Positive integer indicating number of entries filled in frags on + * success, negative integer on error. */ -static int -visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen, - unsigned int frags_max, - struct phys_info frags[]) +static int visor_copy_fragsinfo_from_skb(struct sk_buff *skb, + unsigned int firstfraglen, + unsigned int frags_max, + struct phys_info frags[]) { unsigned int count = 0, frag, size, offset = 0, numfrags; unsigned int total_count; @@ -239,11 +290,10 @@ visor_copy_fragsinfo_from_skb(struct sk_buff *skb, unsigned int firstfraglen, for (frag = 0; frag < numfrags; frag++) { count = add_physinfo_entries(page_to_pfn( - skb_frag_page(&skb_shinfo(skb)->frags[frag])), - skb_shinfo(skb)->frags[frag]. - page_offset, - skb_shinfo(skb)->frags[frag]. - size, count, frags_max, frags); + skb_frag_page(&skb_shinfo(skb)->frags[frag])), + skb_shinfo(skb)->frags[frag].page_offset, + skb_shinfo(skb)->frags[frag].size, count, + frags_max, frags); /* add_physinfo_entries only returns * zero if the frags array is out of room * That should never happen because we @@ -287,21 +337,15 @@ static const struct file_operations debugfs_enable_ints_fops = { .write = enable_ints_write, }; -/* - * visornic_serverdown_complete - IOPART went down, pause device - * @work: Work queue it was scheduled on +/* visornic_serverdown_complete - pause device following IOPART going down + * @devdata: Device managed by IOPART. * - * The IO partition has gone down and we need to do some cleanup - * for when it comes back. Treat the IO partition as the link - * being down. - * Returns void. + * The IO partition has gone down, and we need to do some cleanup for when it + * comes back. Treat the IO partition as the link being down. */ -static void -visornic_serverdown_complete(struct visornic_devdata *devdata) +static void visornic_serverdown_complete(struct visornic_devdata *devdata) { - struct net_device *netdev; - - netdev = devdata->netdev; + struct net_device *netdev = devdata->netdev; /* Stop polling for interrupts */ del_timer_sync(&devdata->irq_poll_timer); @@ -322,17 +366,17 @@ visornic_serverdown_complete(struct visornic_devdata *devdata) devdata->server_down_complete_func = NULL; } -/* - * visornic_serverdown - Command has notified us that IOPART is down - * @devdata: device that is being managed by IOPART +/* visornic_serverdown - Command has notified us that IOPART is down + * @devdata: Device managed by IOPART. + * @complete_func: Function to call when finished. * - * Schedule the work needed to handle the server down request. Make - * sure we haven't already handled the server change state event. - * Returns 0 if we scheduled the work, -EINVAL on error. + * Schedule the work needed to handle the server down request. Make sure we + * haven't already handled the server change state event. + * + * Return: 0 if we scheduled the work, negative integer on error. */ -static int -visornic_serverdown(struct visornic_devdata *devdata, - visorbus_state_complete_func complete_func) +static int visornic_serverdown(struct visornic_devdata *devdata, + visorbus_state_complete_func complete_func) { unsigned long flags; int err; @@ -369,16 +413,15 @@ err_unlock: return err; } -/* - * alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition. - * @netdev: network adapter the rcv bufs are attached too. +/* alloc_rcv_buf - alloc rcv buffer to be given to the IO Partition + * @netdev: Network adapter the rcv bufs are attached too. * - * Create an sk_buff (rcv_buf) that will be passed to the IO Partition - * so that it can write rcv data into our memory space. - * Return pointer to sk_buff + * Create an sk_buff (rcv_buf) that will be passed to the IO Partition + * so that it can write rcv data into our memory space. + * + * Return: Pointer to sk_buff. */ -static struct sk_buff * -alloc_rcv_buf(struct net_device *netdev) +static struct sk_buff *alloc_rcv_buf(struct net_device *netdev) { struct sk_buff *skb; @@ -400,18 +443,15 @@ alloc_rcv_buf(struct net_device *netdev) return skb; } -/* - * post_skb - post a skb to the IO Partition. - * @cmdrsp: cmdrsp packet to be send to the IO Partition - * @devdata: visornic_devdata to post the skb too - * @skb: skb to give to the IO partition +/* post_skb - post a skb to the IO Partition + * @cmdrsp: Cmdrsp packet to be send to the IO Partition. + * @devdata: visornic_devdata to post the skb to. + * @skb: Skb to give to the IO partition. * - * Send the skb to the IO Partition. - * Returns 0 or error + * Return: 0 on success, negative integer on error. */ -static int -post_skb(struct uiscmdrsp *cmdrsp, - struct visornic_devdata *devdata, struct sk_buff *skb) +static int post_skb(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, + struct sk_buff *skb) { int err; @@ -437,23 +477,20 @@ post_skb(struct uiscmdrsp *cmdrsp, atomic_inc(&devdata->num_rcvbuf_in_iovm); devdata->chstat.sent_post++; - return 0; } -/* - * send_enbdis - send NET_RCV_ENBDIS to IO Partition - * @netdev: netdevice we are enable/disable, used as context - * return value - * @state: enable = 1/disable = 0 - * @devdata: visornic device we are enabling/disabling +/* send_enbdis - Send NET_RCV_ENBDIS to IO Partition + * @netdev: Netdevice we are enabling/disabling, used as context return value. + * @state: Enable = 1/disable = 0. + * @devdata: Visornic device we are enabling/disabling. * - * Send the enable/disable message to the IO Partition. - * Returns 0 or error + * Send the enable/disable message to the IO Partition. + * + * Return: 0 on success, negative integer on error. */ -static int -send_enbdis(struct net_device *netdev, int state, - struct visornic_devdata *devdata) +static int send_enbdis(struct net_device *netdev, int state, + struct visornic_devdata *devdata) { int err; @@ -470,19 +507,17 @@ send_enbdis(struct net_device *netdev, int state, return 0; } -/* - * visornic_disable_with_timeout - Disable network adapter - * @netdev: netdevice to disable - * @timeout: timeout to wait for disable +/* visornic_disable_with_timeout - disable network adapter + * @netdev: netdevice to disable. + * @timeout: Timeout to wait for disable. * - * Disable the network adapter and inform the IO Partition that we - * are disabled, reclaim memory from rcv bufs. - * Returns 0 on success, negative for failure of IO Partition - * responding. + * Disable the network adapter and inform the IO Partition that we are disabled. + * Reclaim memory from rcv bufs. * + * Return: 0 on success, negative integer on failure of IO Partition responding. */ -static int -visornic_disable_with_timeout(struct net_device *netdev, const int timeout) +static int visornic_disable_with_timeout(struct net_device *netdev, + const int timeout) { struct visornic_devdata *devdata = netdev_priv(netdev); int i; @@ -493,7 +528,8 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) /* send a msg telling the other end we are stopping incoming pkts */ spin_lock_irqsave(&devdata->priv_lock, flags); devdata->enabled = 0; - devdata->enab_dis_acked = 0; /* must wait for ack */ + /* must wait for ack */ + devdata->enab_dis_acked = 0; spin_unlock_irqrestore(&devdata->priv_lock, flags); /* send disable and wait for ack -- don't hold lock when sending @@ -560,16 +596,16 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout) return 0; } -/* - * init_rcv_bufs -- initialize receive bufs and send them to the IO Part - * @netdev: struct netdevice - * @devdata: visornic_devdata +/* init_rcv_bufs - initialize receive buffs and send them to the IO Partition + * @netdev: struct netdevice. + * @devdata: visornic_devdata. * - * Allocate rcv buffers and post them to the IO Partition. - * Return 0 for success, and negative for failure. + * Allocate rcv buffers and post them to the IO Partition. + * + * Return: 0 on success, negative integer on failure. */ -static int -init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) +static int init_rcv_bufs(struct net_device *netdev, + struct visornic_devdata *devdata) { int i, j, count, err; @@ -578,10 +614,12 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) */ for (i = 0; i < devdata->num_rcv_bufs; i++) { devdata->rcvbuf[i] = alloc_rcv_buf(netdev); + /* if we failed to allocate one let us stop */ if (!devdata->rcvbuf[i]) - break; /* if we failed to allocate one let us stop */ + break; } - if (i == 0) /* couldn't even allocate one -- bail out */ + /* couldn't even allocate one -- bail out */ + if (i == 0) return -ENOMEM; count = i; @@ -624,17 +662,17 @@ init_rcv_bufs(struct net_device *netdev, struct visornic_devdata *devdata) return 0; } -/* - * visornic_enable_with_timeout - send enable to IO Part - * @netdev: struct net_device - * @timeout: Time to wait for the ACK from the enable +/* visornic_enable_with_timeout - send enable to IO Partition + * @netdev: struct net_device. + * @timeout: Time to wait for the ACK from the enable. * - * Sends enable to IOVM, inits, and posts receive buffers to IOVM - * timeout is defined in msecs (timeout of 0 specifies infinite wait) - * Return 0 for success, negative for failure. + * Sends enable to IOVM and inits, and posts receive buffers to IOVM. Timeout is + * defined in msecs (timeout of 0 specifies infinite wait). + * + * Return: 0 on success, negative integer on failure. */ -static int -visornic_enable_with_timeout(struct net_device *netdev, const int timeout) +static int visornic_enable_with_timeout(struct net_device *netdev, + const int timeout) { int err = 0; struct visornic_devdata *devdata = netdev_priv(netdev); @@ -695,20 +733,17 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout) } netif_start_queue(netdev); - return 0; } -/* - * visornic_timeout_reset - handle xmit timeout resets - * @work work item that scheduled the work +/* visornic_timeout_reset - handle xmit timeout resets + * @work: Work item that scheduled the work. * - * Transmit Timeouts are typically handled by resetting the - * device for our virtual NIC we will send a Disable and Enable - * to the IOVM. If it doesn't respond we will trigger a serverdown. + * Transmit timeouts are typically handled by resetting the device for our + * virtual NIC; we will send a disable and enable to the IOVM. If it doesn't + * respond, we will trigger a serverdown. */ -static void -visornic_timeout_reset(struct work_struct *work) +static void visornic_timeout_reset(struct work_struct *work) { struct visornic_devdata *devdata; struct net_device *netdev; @@ -742,41 +777,36 @@ call_serverdown: rtnl_unlock(); } -/* - * visornic_open - Enable the visornic device and mark the queue started - * @netdev: netdevice to start +/* visornic_open - enable the visornic device and mark the queue started + * @netdev: netdevice to start. * - * Enable the device and start the transmit queue. - * Return 0 for success + * Enable the device and start the transmit queue. + * + * Return: 0 on success. */ -static int -visornic_open(struct net_device *netdev) +static int visornic_open(struct net_device *netdev) { visornic_enable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT); - return 0; } -/* - * visornic_close - Disables the visornic device and stops the queues - * @netdev: netdevice to start +/* visornic_close - disables the visornic device and stops the queues + * @netdev: netdevice to stop. * - * Disable the device and stop the transmit queue. - * Return 0 for success + * Disable the device and stop the transmit queue. + * + * Return 0 on success. */ -static int -visornic_close(struct net_device *netdev) +static int visornic_close(struct net_device *netdev) { visornic_disable_with_timeout(netdev, VISORNIC_INFINITE_RSP_WAIT); - return 0; } -/* - * devdata_xmits_outstanding - compute outstanding xmits - * @devdata: visornic_devdata for device +/* devdata_xmits_outstanding - compute outstanding xmits + * @devdata: visornic_devdata for device * - * Return value is the number of outstanding xmits. + * Return: Long integer representing the number of outstanding xmits. */ static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata) { @@ -787,14 +817,13 @@ static unsigned long devdata_xmits_outstanding(struct visornic_devdata *devdata) + devdata->chstat.sent_xmit + 1); } -/* - * vnic_hit_high_watermark - * @devdata: indicates visornic device we are checking - * @high_watermark: max num of unacked xmits we will tolerate, - * before we will start throttling +/* vnic_hit_high_watermark + * @devdata: Indicates visornic device we are checking. + * @high_watermark: Max num of unacked xmits we will tolerate before we will + * start throttling. * - * Returns true iff the number of unacked xmits sent to - * the IO partition is >= high_watermark. + * Return: True iff the number of unacked xmits sent to the IO Partition is >= + * high_watermark. False otherwise. */ static bool vnic_hit_high_watermark(struct visornic_devdata *devdata, ulong high_watermark) @@ -802,15 +831,13 @@ static bool vnic_hit_high_watermark(struct visornic_devdata *devdata, return (devdata_xmits_outstanding(devdata) >= high_watermark); } -/* - * vnic_hit_low_watermark - * @devdata: indicates visornic device we are checking - * @low_watermark: we will wait until the num of unacked xmits - * drops to this value or lower before we start - * transmitting again +/* vnic_hit_low_watermark + * @devdata: Indicates visornic device we are checking. + * @low_watermark: We will wait until the num of unacked xmits drops to this + * value or lower before we start transmitting again. * - * Returns true iff the number of unacked xmits sent to - * the IO partition is <= low_watermark. + * Return: True iff the number of unacked xmits sent to the IO Partition is <= + * low_watermark. */ static bool vnic_hit_low_watermark(struct visornic_devdata *devdata, ulong low_watermark) @@ -818,20 +845,18 @@ static bool vnic_hit_low_watermark(struct visornic_devdata *devdata, return (devdata_xmits_outstanding(devdata) <= low_watermark); } -/* - * visornic_xmit - send a packet to the IO Partition - * @skb: Packet to be sent - * @netdev: net device the packet is being sent from +/* visornic_xmit - send a packet to the IO Partition + * @skb: Packet to be sent. + * @netdev: Net device the packet is being sent from. * - * Convert the skb to a cmdrsp so the IO Partition can understand it. - * Send the XMIT command to the IO Partition for processing. This - * function is protected from concurrent calls by a spinlock xmit_lock - * in the net_device struct, but as soon as the function returns it - * can be called again. - * Returns NETDEV_TX_OK. + * Convert the skb to a cmdrsp so the IO Partition can understand it, and send + * the XMIT command to the IO Partition for processing. This function is + * protected from concurrent calls by a spinlock xmit_lock in the net_device + * struct. As soon as the function returns, it can be called again. + * + * Return: NETDEV_TX_OK. */ -static int -visornic_xmit(struct sk_buff *skb, struct net_device *netdev) +static int visornic_xmit(struct sk_buff *skb, struct net_device *netdev) { struct visornic_devdata *devdata; int len, firstfraglen, padlen; @@ -938,6 +963,7 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) * - everything else will be pass in frags & DMA'ed */ memcpy(cmdrsp->net.xmt.ethhdr, skb->data, ETH_HLEN); + /* copy frags info - from skb->data we need to only provide access * beyond eth header */ @@ -991,46 +1017,39 @@ visornic_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } -/* - * visornic_get_stats - returns net_stats of the visornic device - * @netdev: netdevice +/* visornic_get_stats - returns net_stats of the visornic device + * @netdev: netdevice. * - * Returns the net_device_stats for the device + * Return: Pointer to the net_device_stats struct for the device. */ -static struct net_device_stats * -visornic_get_stats(struct net_device *netdev) +static struct net_device_stats *visornic_get_stats(struct net_device *netdev) { struct visornic_devdata *devdata = netdev_priv(netdev); return &devdata->net_stats; } -/* - * visornic_change_mtu - changes mtu of device. - * @netdev: netdevice - * @new_mtu: value of new mtu +/* visornic_change_mtu - changes mtu of device + * @netdev: netdevice. + * @new_mtu: Value of new mtu. * - * MTU cannot be changed by system, must be changed via - * CONTROLVM message. All vnics and pnics in a switch have - * to have the same MTU for everything to work. - * Currently not supported. - * Returns EINVAL + * The device's MTU cannot be changed by system; it must be changed via a + * CONTROLVM message. All vnics and pnics in a switch have to have the same MTU + * for everything to work. Currently not supported. + * + * Return: -EINVAL. */ -static int -visornic_change_mtu(struct net_device *netdev, int new_mtu) +static int visornic_change_mtu(struct net_device *netdev, int new_mtu) { return -EINVAL; } -/* - * visornic_set_multi - changes mtu of device. - * @netdev: netdevice +/* visornic_set_multi - set visornic device flags + * @netdev: netdevice. * - * Only flag we support currently is IFF_PROMISC - * Returns void + * The only flag we currently support is IFF_PROMISC. */ -static void -visornic_set_multi(struct net_device *netdev) +static void visornic_set_multi(struct net_device *netdev) { struct uiscmdrsp *cmdrsp; struct visornic_devdata *devdata = netdev_priv(netdev); @@ -1062,16 +1081,13 @@ out_save_flags: devdata->old_flags = netdev->flags; } -/* - * visornic_xmit_timeout - request to timeout the xmit - * @netdev +/* visornic_xmit_timeout - request to timeout the xmit + * @netdev: netdevice. * - * Queue the work and return. Make sure we have not already - * been informed the IO Partition is gone, if it is gone - * we will already timeout the xmits. + * Queue the work and return. Make sure we have not already been informed that + * the IO Partition is gone; if so, we will have already timed-out the xmits. */ -static void -visornic_xmit_timeout(struct net_device *netdev) +static void visornic_xmit_timeout(struct net_device *netdev) { struct visornic_devdata *devdata = netdev_priv(netdev); unsigned long flags; @@ -1097,20 +1113,20 @@ visornic_xmit_timeout(struct net_device *netdev) spin_unlock_irqrestore(&devdata->priv_lock, flags); } -/* - * repost_return - repost rcv bufs that have come back - * @cmdrsp: io channel command struct to post - * @devdata: visornic devdata for the device - * @skb: skb - * @netdev: netdevice +/* repost_return - repost rcv bufs that have come back + * @cmdrsp: IO channel command struct to post. + * @devdata: Visornic devdata for the device. + * @skb: Socket buffer. + * @netdev: netdevice. * - * Repost rcv buffers that have been returned to us when - * we are finished with them. - * Returns 0 for success, -1 for error. + * Repost rcv buffers that have been returned to us when we are finished + * with them. + * + * Return: 0 for success, negative integer on error. */ -static int -repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, - struct sk_buff *skb, struct net_device *netdev) +static int repost_return(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata, + struct sk_buff *skb, struct net_device *netdev) { struct net_pkt_rcv copy; int i = 0, cc, numreposted; @@ -1174,16 +1190,15 @@ repost_return(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, return status; } -/* - * visornic_rx - Handle receive packets coming back from IO Part - * @cmdrsp: Receive packet returned from IO Part +/* visornic_rx - handle receive packets coming back from IO Partition + * @cmdrsp: Receive packet returned from IO Partition. * - * Got a receive packet back from the IO Part, handle it and send - * it up the stack. - * Returns 1 iff an skb was received, otherwise 0 + * Got a receive packet back from the IO Partition; handle it and send it up + * the stack. + + * Return: 1 iff an skb was received, otherwise 0. */ -static int -visornic_rx(struct uiscmdrsp *cmdrsp) +static int visornic_rx(struct uiscmdrsp *cmdrsp) { struct visornic_devdata *devdata; struct sk_buff *skb, *prev, *curr; @@ -1236,7 +1251,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp) * firstfrag & set data_len to show rest see if we have to chain * frag_list. */ - if (skb->len > RCVPOST_BUF_SIZE) { /* do PRECAUTIONARY check */ + /* do PRECAUTIONARY check */ + if (skb->len > RCVPOST_BUF_SIZE) { if (cmdrsp->net.rcv.numrcvbufs < 2) { if (repost_return(cmdrsp, devdata, skb, netdev) < 0) dev_err(&devdata->netdev->dev, @@ -1244,23 +1260,24 @@ visornic_rx(struct uiscmdrsp *cmdrsp) return 0; } /* length rcvd is greater than firstfrag in this skb rcv buf */ - skb->tail += RCVPOST_BUF_SIZE; /* amount in skb->data */ - skb->data_len = skb->len - RCVPOST_BUF_SIZE; /* amount that - * will be in - * frag_list - */ + /* amount in skb->data */ + skb->tail += RCVPOST_BUF_SIZE; + /* amount that will be in frag_list */ + skb->data_len = skb->len - RCVPOST_BUF_SIZE; } else { /* data fits in this skb - no chaining - do * PRECAUTIONARY check */ - if (cmdrsp->net.rcv.numrcvbufs != 1) { /* should be 1 */ + /* should be 1 */ + if (cmdrsp->net.rcv.numrcvbufs != 1) { if (repost_return(cmdrsp, devdata, skb, netdev) < 0) dev_err(&devdata->netdev->dev, "repost_return failed"); return 0; } skb->tail += skb->len; - skb->data_len = 0; /* nothing rcvd in frag_list */ + /* nothing rcvd in frag_list */ + skb->data_len = 0; } off = skb_tail_pointer(skb) - skb->data; @@ -1286,7 +1303,8 @@ visornic_rx(struct uiscmdrsp *cmdrsp) cc < cmdrsp->net.rcv.numrcvbufs; cc++) { curr = (struct sk_buff *)cmdrsp->net.rcv.rcvbuf[cc]; curr->next = NULL; - if (!prev) /* start of list- set head */ + /* start of list- set head */ + if (!prev) skb_shinfo(skb)->frag_list = curr; else prev->next = curr; @@ -1314,18 +1332,18 @@ visornic_rx(struct uiscmdrsp *cmdrsp) * sets up skb->pkt_type & it also PULLS out the eth header */ skb->protocol = eth_type_trans(skb, netdev); - eth = eth_hdr(skb); - skb->csum = 0; skb->ip_summed = CHECKSUM_NONE; do { + /* accept all packets */ if (netdev->flags & IFF_PROMISC) - break; /* accept all packets */ + break; if (skb->pkt_type == PACKET_BROADCAST) { + /* accept all broadcast packets */ if (netdev->flags & IFF_BROADCAST) - break; /* accept all broadcast packets */ + break; } else if (skb->pkt_type == PACKET_MULTICAST) { if ((netdev->flags & IFF_MULTICAST) && (netdev_mc_count(netdev))) { @@ -1367,8 +1385,7 @@ visornic_rx(struct uiscmdrsp *cmdrsp) */ skb = NULL; - /* - * whether the packet got dropped or handled, the skb is freed by + /* whether the packet got dropped or handled, the skb is freed by * kernel code, so we shouldn't free it. but we should repost a * new rcv buffer. */ @@ -1376,29 +1393,25 @@ visornic_rx(struct uiscmdrsp *cmdrsp) return 1; } -/* - * devdata_initialize - Initialize devdata structure - * @devdata: visornic_devdata structure to initialize - * #dev: visorbus_deviced it belongs to +/* devdata_initialize - initialize devdata structure + * @devdata: visornic_devdata structure to initialize. + * @dev: visorbus_device it belongs to. * - * Setup initial values for the visornic based on channel and default - * values. - * Returns a pointer to the devdata structure + * Setup initial values for the visornic, based on channel and default values. + * + * Return: A pointer to the devdata structure. */ -static struct visornic_devdata * -devdata_initialize(struct visornic_devdata *devdata, struct visor_device *dev) +static struct visornic_devdata *devdata_initialize( + struct visornic_devdata *devdata, + struct visor_device *dev) { devdata->dev = dev; devdata->incarnation_id = get_jiffies_64(); return devdata; } -/* - * devdata_release - Frees up references in devdata - * @devdata: struct to clean up - * - * Frees up references in devdata. - * Returns void +/* devdata_release - free up references in devdata + * @devdata: Struct to clean up. */ static void devdata_release(struct visornic_devdata *devdata) { @@ -1570,15 +1583,10 @@ static const struct file_operations debugfs_info_fops = { .read = info_debugfs_read, }; -/* - * send_rcv_posts_if_needed - * @devdata: visornic device - * - * Send receive buffers to the IO Partition. - * Returns void +/* send_rcv_posts_if_needed - send receive buffers to the IO Partition. + * @devdata: Visornic device. */ -static int -send_rcv_posts_if_needed(struct visornic_devdata *devdata) +static void send_rcv_posts_if_needed(struct visornic_devdata *devdata) { int i; struct net_device *netdev; @@ -1588,7 +1596,7 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata) /* don't do this until vnic is marked ready */ if (!(devdata->enabled && devdata->enab_dis_acked)) - return 0; + return; netdev = devdata->netdev; rcv_bufs_allocated = 0; @@ -1617,16 +1625,14 @@ send_rcv_posts_if_needed(struct visornic_devdata *devdata) } } devdata->num_rcv_bufs_could_not_alloc -= rcv_bufs_allocated; - return 0; } -/* - * drain_resp_queue - drains and ignores all messages from the resp queue - * @cmdrsp: io channel command response message - * @devdata: visornic device to drain +/* drain_resp_queue - drains and ignores all messages from the resp queue + * @cmdrsp: IO channel command response message. + * @devdata: Visornic device to drain. */ -static void -drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) +static void drain_resp_queue(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata) { while (!visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, @@ -1634,30 +1640,31 @@ drain_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata) ; } -/* - * service_resp_queue - drains the response queue - * @cmdrsp: io channel command response message - * @devdata: visornic device to drain +/* service_resp_queue - drain the response queue + * @cmdrsp: IO channel command response message. + * @devdata: Visornic device to drain. + * @rx_work_done: + * @budget: * - * Drain the response queue of any responses from the IO partition. - * Process the responses as we get them. - * Returns when response queue is empty or when the thread stops. + * Drain the response queue of any responses from the IO Partition. Process the + * responses as we get them. */ -static void -service_resp_queue(struct uiscmdrsp *cmdrsp, struct visornic_devdata *devdata, - int *rx_work_done, int budget) +static void service_resp_queue(struct uiscmdrsp *cmdrsp, + struct visornic_devdata *devdata, + int *rx_work_done, int budget) { unsigned long flags; struct net_device *netdev; while (*rx_work_done < budget) { - /* TODO: CLIENT ACQUIRE -- Don't really need this at the - * moment - */ + /* TODO: CLIENT ACQUIRE -- Don't really need this at the + * moment + */ + /* queue empty */ if (visorchannel_signalremove(devdata->dev->visorchannel, IOCHAN_FROM_IOPART, cmdrsp)) - break; /* queue empty */ + break; switch (cmdrsp->net.type) { case NET_RCV: @@ -1740,12 +1747,8 @@ static int visornic_poll(struct napi_struct *napi, int budget) struct visornic_devdata, napi); int rx_count = 0; - int err; - - err = send_rcv_posts_if_needed(devdata); - if (err) - return err; + send_rcv_posts_if_needed(devdata); service_resp_queue(devdata->cmdrsp, devdata, &rx_count, budget); /* If there aren't any more packets to receive stop the poll */ @@ -1755,16 +1758,13 @@ static int visornic_poll(struct napi_struct *napi, int budget) return rx_count; } -/* - * poll_for_irq - Checks the status of the response queue. - * @v: void pointer to the visronic devdata +/* poll_for_irq - checks the status of the response queue + * @v: Void pointer to the visronic devdata struct. * - * Main function of the vnic_incoming thread. Periodically check the - * response queue and drain it if needed. - * Returns when thread has stopped. + * Main function of the vnic_incoming thread. Periodically check the response + * queue and drain it if needed. */ -static void -poll_for_irq(unsigned long v) +static void poll_for_irq(unsigned long v) { struct visornic_devdata *devdata = (struct visornic_devdata *)v; @@ -1778,13 +1778,13 @@ poll_for_irq(unsigned long v) mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2)); } -/* - * visornic_probe - probe function for visornic devices - * @dev: The visor device discovered +/* visornic_probe - probe function for visornic devices + * @dev: The visor device discovered. * - * Called when visorbus discovers a visornic device on its - * bus. It creates a new visornic ethernet adapter. - * Returns 0 or negative for error. + * Called when visorbus discovers a visornic device on its bus. It creates a new + * visornic ethernet adapter. + * + * Return: 0 on success, or negative integer on error. */ static int visornic_probe(struct visor_device *dev) { @@ -1831,7 +1831,8 @@ static int visornic_probe(struct visor_device *dev) dev_set_drvdata(&dev->device, devdata); init_waitqueue_head(&devdata->rsp_queue); spin_lock_init(&devdata->priv_lock); - devdata->enabled = 0; /* not yet */ + /* not yet */ + devdata->enabled = 0; atomic_set(&devdata->usage, 1); /* Setup rcv bufs */ @@ -1852,9 +1853,10 @@ static int visornic_probe(struct visor_device *dev) goto cleanup_netdev; } - /* set the net_xmit outstanding threshold */ - /* always leave two slots open but you should have 3 at a minimum */ - /* note that max_outstanding_net_xmits must be > 0 */ + /* set the net_xmit outstanding threshold + * always leave two slots open but you should have 3 at a minimum + * note that max_outstanding_net_xmits must be > 0 + */ devdata->max_outstanding_net_xmits = max_t(unsigned long, 3, ((devdata->num_rcv_bufs / 3) - 2)); devdata->upper_threshold_net_xmits = @@ -1972,28 +1974,25 @@ cleanup_netdev: return err; } -/* - * host_side_disappeared - IO part is gone. - * @devdata: device object +/* host_side_disappeared - IO Partition is gone + * @devdata: Device object. * - * IO partition servicing this device is gone, do cleanup - * Returns void. + * IO partition servicing this device is gone; do cleanup. */ static void host_side_disappeared(struct visornic_devdata *devdata) { unsigned long flags; spin_lock_irqsave(&devdata->priv_lock, flags); - devdata->dev = NULL; /* indicate device destroyed */ + /* indicate device destroyed */ + devdata->dev = NULL; spin_unlock_irqrestore(&devdata->priv_lock, flags); } -/* - * visornic_remove - Called when visornic dev goes away - * @dev: visornic device that is being removed +/* visornic_remove - called when visornic dev goes away + * @dev: Visornic device that is being removed. * - * Called when DEVICE_DESTROY gets called to remove device. - * Returns void + * Called when DEVICE_DESTROY gets called to remove device. */ static void visornic_remove(struct visor_device *dev) { @@ -2023,8 +2022,8 @@ static void visornic_remove(struct visor_device *dev) cancel_work_sync(&devdata->timeout_reset); debugfs_remove_recursive(devdata->eth_debugfs_dir); - - unregister_netdev(netdev); /* this will call visornic_close() */ + /* this will call visornic_close() */ + unregister_netdev(netdev); del_timer_sync(&devdata->irq_poll_timer); netif_napi_del(&devdata->napi); @@ -2035,18 +2034,17 @@ static void visornic_remove(struct visor_device *dev) free_netdev(netdev); } -/* - * visornic_pause - Called when IO Part disappears - * @dev: visornic device that is being serviced - * @complete_func: call when finished. +/* visornic_pause - called when IO Part disappears + * @dev: Visornic device that is being serviced. + * @complete_func: Call when finished. * - * Called when the IO Partition has gone down. Need to free - * up resources and wait for IO partition to come back. Mark - * link as down and don't attempt any DMA. When we have freed - * memory call the complete_func so that Command knows we are - * done. If we don't call complete_func, IO part will never - * come back. - * Returns 0 for success. + * Called when the IO Partition has gone down. Need to free up resources and + * wait for IO partition to come back. Mark link as down and don't attempt any + * DMA. When we have freed memory, call the complete_func so that Command knows + * we are done. If we don't call complete_func, the IO Partition will never + * come back. + * + * Return: 0 on success. */ static int visornic_pause(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -2057,15 +2055,14 @@ static int visornic_pause(struct visor_device *dev, return 0; } -/* - * visornic_resume - Called when IO part has recovered - * @dev: visornic device that is being serviced - * @compelte_func: call when finished +/* visornic_resume - called when IO Partition has recovered + * @dev: Visornic device that is being serviced. + * @compelte_func: Call when finished. * - * Called when the IO partition has recovered. Reestablish - * connection to the IO part and set the link up. Okay to do - * DMA again. - * Returns 0 for success. + * Called when the IO partition has recovered. Re-establish connection to the IO + * Partition and set the link up. Okay to do DMA again. + * + * Returns 0 for success, negative integer on error. */ static int visornic_resume(struct visor_device *dev, visorbus_state_complete_func complete_func) @@ -2127,12 +2124,12 @@ static struct visor_driver visornic_driver = { .channel_interrupt = NULL, }; -/* - * visornic_init - Init function +/* visornic_init - init function * - * Init function for the visornic driver. Do initial driver setup - * and wait for devices. - * Returns 0 for success, negative for error. + * Init function for the visornic driver. Do initial driver setup and wait + * for devices. + * + * Return: 0 on success, negative integer on error. */ static int visornic_init(void) { @@ -2160,19 +2157,16 @@ static int visornic_init(void) cleanup_debugfs: debugfs_remove_recursive(visornic_debugfs_dir); - return err; } -/* - * visornic_cleanup - driver exit routine +/* visornic_cleanup - driver exit routine * - * Unregister driver from the bus and free up memory. + * Unregister driver from the bus and free up memory. */ static void visornic_cleanup(void) { visorbus_unregister_visor_driver(&visornic_driver); - debugfs_remove_recursive(visornic_debugfs_dir); } diff --git a/drivers/staging/vboxvideo/Kconfig b/drivers/staging/vboxvideo/Kconfig index a52746f9a670..1f4182e2e980 100644 --- a/drivers/staging/vboxvideo/Kconfig +++ b/drivers/staging/vboxvideo/Kconfig @@ -2,11 +2,14 @@ config DRM_VBOXVIDEO tristate "Virtual Box Graphics Card" depends on DRM && X86 && PCI select DRM_KMS_HELPER + select DRM_TTM + select GENERIC_ALLOCATOR help This is a KMS driver for the virtual Graphics Card used in Virtual Box virtual machines. - Although it is possible to builtin this module, it is advised - to build this driver as a module, so that it can be updated - independently of the kernel. Select M to built this driver as a - module and add support for these devices via drm/kms interfaces. + Although it is possible to build this driver built-in to the + kernel, it is advised to build it as a module, so that it can + be updated independently of the kernel. Select M to build this + driver as a module and add support for these devices via drm/kms + interfaces. diff --git a/drivers/staging/vboxvideo/Makefile b/drivers/staging/vboxvideo/Makefile index 2d0b3bc7ad73..3f6094aa9cdf 100644 --- a/drivers/staging/vboxvideo/Makefile +++ b/drivers/staging/vboxvideo/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-y := -Iinclude/drm vboxvideo-y := hgsmi_base.o modesetting.o vbva_base.o \ diff --git a/drivers/staging/vboxvideo/TODO b/drivers/staging/vboxvideo/TODO index ce764309b079..bd381d861ab3 100644 --- a/drivers/staging/vboxvideo/TODO +++ b/drivers/staging/vboxvideo/TODO @@ -5,5 +5,5 @@ TODO: -Extend this TODO with the results of that review Please send any patches to Greg Kroah-Hartman , -Hans de Goede and -Michael Thayer . +Hans de Goede , Michael Thayer +and dri-devel@lists.freedesktop.org . diff --git a/drivers/staging/vboxvideo/vbox_drv.c b/drivers/staging/vboxvideo/vbox_drv.c index 92ae1560a16d..e18642e5027e 100644 --- a/drivers/staging/vboxvideo/vbox_drv.c +++ b/drivers/staging/vboxvideo/vbox_drv.c @@ -36,7 +36,7 @@ #include "vbox_drv.h" -int vbox_modeset = -1; +static int vbox_modeset = -1; MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, vbox_modeset, int, 0400); @@ -232,7 +232,6 @@ static struct drm_driver driver = { .lastclose = vbox_driver_lastclose, .master_set = vbox_master_set, .master_drop = vbox_master_drop, - .set_busid = drm_pci_set_busid, .fops = &vbox_fops, .irq_handler = vbox_irq_handler, @@ -270,12 +269,12 @@ static int __init vbox_init(void) if (vbox_modeset == 0) return -EINVAL; - return drm_pci_init(&driver, &vbox_pci_driver); + return pci_register_driver(&vbox_pci_driver); } static void __exit vbox_exit(void) { - drm_pci_exit(&driver, &vbox_pci_driver); + pci_unregister_driver(&vbox_pci_driver); } module_init(vbox_init); diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index 35f6d9f8c203..8aed248db6e2 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -45,144 +45,20 @@ #include "vbox_drv.h" #include "vboxvideo.h" -#define VBOX_DIRTY_DELAY (HZ / 30) -/** - * Tell the host about dirty rectangles to update. - */ -static void vbox_dirty_update(struct vbox_fbdev *fbdev, - int x, int y, int width, int height) -{ - struct drm_gem_object *obj; - struct vbox_bo *bo; - int ret = -EBUSY; - bool store_for_later = false; - int x2, y2; - unsigned long flags; - struct drm_clip_rect rect; - - obj = fbdev->afb.obj; - bo = gem_to_vbox_bo(obj); - - /* - * try and reserve the BO, if we fail with busy - * then the BO is being moved and we should - * store up the damage until later. - */ - if (drm_can_sleep()) - ret = vbox_bo_reserve(bo, true); - if (ret) { - if (ret != -EBUSY) - return; - - store_for_later = true; - } - - x2 = x + width - 1; - y2 = y + height - 1; - spin_lock_irqsave(&fbdev->dirty_lock, flags); - - if (fbdev->y1 < y) - y = fbdev->y1; - if (fbdev->y2 > y2) - y2 = fbdev->y2; - if (fbdev->x1 < x) - x = fbdev->x1; - if (fbdev->x2 > x2) - x2 = fbdev->x2; - - if (store_for_later) { - fbdev->x1 = x; - fbdev->x2 = x2; - fbdev->y1 = y; - fbdev->y2 = y2; - spin_unlock_irqrestore(&fbdev->dirty_lock, flags); - return; - } - - fbdev->x1 = INT_MAX; - fbdev->y1 = INT_MAX; - fbdev->x2 = 0; - fbdev->y2 = 0; - - spin_unlock_irqrestore(&fbdev->dirty_lock, flags); - - /* - * Not sure why the original code subtracted 1 here, but I will keep - * it that way to avoid unnecessary differences. - */ - rect.x1 = x; - rect.x2 = x2 + 1; - rect.y1 = y; - rect.y2 = y2 + 1; - vbox_framebuffer_dirty_rectangles(&fbdev->afb.base, &rect, 1); - - vbox_bo_unreserve(bo); -} - -#ifdef CONFIG_FB_DEFERRED_IO -static void vbox_deferred_io(struct fb_info *info, struct list_head *pagelist) -{ - struct vbox_fbdev *fbdev = info->par; - unsigned long start, end, min, max; - struct page *page; - int y1, y2; - - min = ULONG_MAX; - max = 0; - list_for_each_entry(page, pagelist, lru) { - start = page->index << PAGE_SHIFT; - end = start + PAGE_SIZE - 1; - min = min(min, start); - max = max(max, end); - } - - if (min < max) { - y1 = min / info->fix.line_length; - y2 = (max / info->fix.line_length) + 1; - DRM_INFO("%s: Calling dirty update: 0, %d, %d, %d\n", - __func__, y1, info->var.xres, y2 - y1 - 1); - vbox_dirty_update(fbdev, 0, y1, info->var.xres, y2 - y1 - 1); - } -} - +#ifdef CONFIG_DRM_KMS_FB_HELPER static struct fb_deferred_io vbox_defio = { - .delay = VBOX_DIRTY_DELAY, - .deferred_io = vbox_deferred_io, + .delay = HZ / 30, + .deferred_io = drm_fb_helper_deferred_io, }; #endif -static void vbox_fillrect(struct fb_info *info, const struct fb_fillrect *rect) -{ - struct vbox_fbdev *fbdev = info->par; - - sys_fillrect(info, rect); - vbox_dirty_update(fbdev, rect->dx, rect->dy, rect->width, rect->height); -} - -static void vbox_copyarea(struct fb_info *info, const struct fb_copyarea *area) -{ - struct vbox_fbdev *fbdev = info->par; - - sys_copyarea(info, area); - vbox_dirty_update(fbdev, area->dx, area->dy, area->width, area->height); -} - -static void vbox_imageblit(struct fb_info *info, const struct fb_image *image) -{ - struct vbox_fbdev *fbdev = info->par; - - sys_imageblit(info, image); - vbox_dirty_update(fbdev, image->dx, image->dy, image->width, - image->height); -} - static struct fb_ops vboxfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = vbox_fillrect, - .fb_copyarea = vbox_copyarea, - .fb_imageblit = vbox_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -219,7 +95,6 @@ static int vboxfb_create(struct drm_fb_helper *helper, struct DRM_MODE_FB_CMD mode_cmd; struct drm_framebuffer *fb; struct fb_info *info; - struct device *device = &dev->pdev->dev; struct drm_gem_object *gobj; struct vbox_bo *bo; int size, ret; @@ -263,16 +138,16 @@ static int vboxfb_create(struct drm_fb_helper *helper, return ret; } - info = framebuffer_alloc(0, device); - if (!info) - return -ENOMEM; + info = drm_fb_helper_alloc_fbi(helper); + if (IS_ERR(info)) + return -PTR_ERR(info); + info->par = fbdev; fbdev->size = size; fb = &fbdev->afb.base; fbdev->helper.fb = fb; - fbdev->helper.fbdev = info; strcpy(info->fix.id, "vboxdrmfb"); @@ -284,17 +159,10 @@ static int vboxfb_create(struct drm_fb_helper *helper, FBINFO_MISC_ALWAYS_SETPAR; info->fbops = &vboxfb_ops; - ret = fb_alloc_cmap(&info->cmap, 256, 0); - if (ret) - return -ENOMEM; - /* * This seems to be done for safety checking that the framebuffer * is not registered twice by different drivers. */ - info->apertures = alloc_apertures(1); - if (!info->apertures) - return -ENOMEM; info->apertures->ranges[0].base = pci_resource_start(dev->pdev, 0); info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); @@ -305,7 +173,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, info->screen_base = bo->kmap.virtual; info->screen_size = size; -#ifdef CONFIG_FB_DEFERRED_IO +#ifdef CONFIG_DRM_KMS_FB_HELPER info->fbdefio = &vbox_defio; fb_deferred_io_init(info); #endif @@ -317,22 +185,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, return 0; } -static void vbox_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, - u16 blue, int regno) -{ -} - -static void vbox_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, int regno) -{ - *red = regno; - *green = regno; - *blue = regno; -} - static struct drm_fb_helper_funcs vbox_fb_helper_funcs = { - .gamma_set = vbox_fb_gamma_set, - .gamma_get = vbox_fb_gamma_get, .fb_probe = vboxfb_create, }; @@ -342,6 +195,11 @@ void vbox_fbdev_fini(struct drm_device *dev) struct vbox_fbdev *fbdev = vbox->fbdev; struct vbox_framebuffer *afb = &fbdev->afb; +#ifdef CONFIG_DRM_KMS_FB_HELPER + if (fbdev->helper.fbdev && fbdev->helper.fbdev->fbdefio) + fb_deferred_io_cleanup(fbdev->helper.fbdev); +#endif + drm_fb_helper_unregister_fbi(&fbdev->helper); if (afb->obj) { @@ -358,7 +216,7 @@ void vbox_fbdev_fini(struct drm_device *dev) vbox_bo_unpin(bo); vbox_bo_unreserve(bo); } - drm_gem_object_unreference_unlocked(afb->obj); + drm_gem_object_put_unlocked(afb->obj); afb->obj = NULL; } drm_fb_helper_fini(&fbdev->helper); diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c index d0c6ec75a3c7..80bd039fa08e 100644 --- a/drivers/staging/vboxvideo/vbox_main.c +++ b/drivers/staging/vboxvideo/vbox_main.c @@ -40,7 +40,7 @@ static void vbox_user_framebuffer_destroy(struct drm_framebuffer *fb) struct vbox_framebuffer *vbox_fb = to_vbox_framebuffer(fb); if (vbox_fb->obj) - drm_gem_object_unreference_unlocked(vbox_fb->obj); + drm_gem_object_put_unlocked(vbox_fb->obj); drm_framebuffer_cleanup(fb); kfree(fb); @@ -198,7 +198,7 @@ static struct drm_framebuffer *vbox_user_framebuffer_create( err_free_vbox_fb: kfree(vbox_fb); err_unref_obj: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ERR_PTR(ret); } @@ -472,7 +472,7 @@ int vbox_dumb_create(struct drm_file *file, return ret; ret = drm_gem_handle_create(file, gobj, &handle); - drm_gem_object_unreference_unlocked(gobj); + drm_gem_object_put_unlocked(gobj); if (ret) return ret; @@ -525,7 +525,7 @@ vbox_dumb_mmap_offset(struct drm_file *file, bo = gem_to_vbox_bo(obj); *offset = vbox_bo_mmap_offset(bo); - drm_gem_object_unreference(obj); + drm_gem_object_put(obj); ret = 0; out_unlock: diff --git a/drivers/staging/vboxvideo/vbox_mode.c b/drivers/staging/vboxvideo/vbox_mode.c index f2b85f3256fa..257a77830410 100644 --- a/drivers/staging/vboxvideo/vbox_mode.c +++ b/drivers/staging/vboxvideo/vbox_mode.c @@ -54,14 +54,12 @@ static void vbox_do_modeset(struct drm_crtc *crtc, struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); struct vbox_private *vbox; int width, height, bpp, pitch; - unsigned int crtc_id; u16 flags; s32 x_offset, y_offset; vbox = crtc->dev->dev_private; width = mode->hdisplay ? mode->hdisplay : 640; height = mode->vdisplay ? mode->vdisplay : 480; - crtc_id = vbox_crtc->crtc_id; bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32; pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8; x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint; @@ -134,10 +132,6 @@ static int vbox_set_view(struct drm_crtc *crtc) return 0; } -static void vbox_crtc_load_lut(struct drm_crtc *crtc) -{ -} - static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode) { struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc); @@ -330,7 +324,6 @@ static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = { .mode_set = vbox_crtc_mode_set, /* .mode_set_base = vbox_crtc_mode_set_base, */ .disable = vbox_crtc_disable, - .load_lut = vbox_crtc_load_lut, .prepare = vbox_crtc_prepare, .commit = vbox_crtc_commit, }; @@ -578,9 +571,6 @@ static int vbox_mode_valid(struct drm_connector *connector, static void vbox_connector_destroy(struct drm_connector *connector) { - struct vbox_connector *vbox_connector; - - vbox_connector = to_vbox_connector(connector); drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); @@ -817,7 +807,7 @@ out_unmap_bo: out_unreserve_bo: vbox_bo_unreserve(bo); out_unref_obj: - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_put_unlocked(obj); return ret; } diff --git a/drivers/staging/vboxvideo/vbox_ttm.c b/drivers/staging/vboxvideo/vbox_ttm.c index 34a905d40735..4eb410a2a1a8 100644 --- a/drivers/staging/vboxvideo/vbox_ttm.c +++ b/drivers/staging/vboxvideo/vbox_ttm.c @@ -230,7 +230,7 @@ static void vbox_ttm_tt_unpopulate(struct ttm_tt *ttm) ttm_pool_unpopulate(ttm); } -struct ttm_bo_driver vbox_bo_driver = { +static struct ttm_bo_driver vbox_bo_driver = { .ttm_tt_create = vbox_ttm_tt_create, .ttm_tt_populate = vbox_ttm_tt_populate, .ttm_tt_unpopulate = vbox_ttm_tt_unpopulate, diff --git a/drivers/staging/vc04_services/Makefile b/drivers/staging/vc04_services/Makefile index e9a8e1343cbb..1ecb261e04ae 100644 --- a/drivers/staging/vc04_services/Makefile +++ b/drivers/staging/vc04_services/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_BCM2835_VCHIQ) += vchiq.o vchiq-objs := \ diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c index 3637ddf909a4..94654c0c7bba 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c @@ -20,7 +20,7 @@ #include "bcm2835.h" /* hardware definition */ -static struct snd_pcm_hardware snd_bcm2835_playback_hw = { +static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, @@ -36,7 +36,7 @@ static struct snd_pcm_hardware snd_bcm2835_playback_hw = { .periods_max = 128, }; -static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { +static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), .formats = SNDRV_PCM_FMTBIT_S16_LE, @@ -438,7 +438,7 @@ static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream, } /* operators */ -static struct snd_pcm_ops snd_bcm2835_playback_ops = { +static const struct snd_pcm_ops snd_bcm2835_playback_ops = { .open = snd_bcm2835_playback_open, .close = snd_bcm2835_playback_close, .ioctl = snd_bcm2835_pcm_lib_ioctl, @@ -450,7 +450,7 @@ static struct snd_pcm_ops snd_bcm2835_playback_ops = { .ack = snd_bcm2835_pcm_ack, }; -static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { +static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { .open = snd_bcm2835_playback_spdif_open, .close = snd_bcm2835_playback_close, .ioctl = snd_bcm2835_pcm_lib_ioctl, diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 5f3d8f2339e3..4be864dbd41c 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream __func__, instance); instance->alsa_stream = alsa_stream; alsa_stream->instance = instance; - ret = 0; // xxx todo -1; - goto err_free_mem; + return 0; } /* Initialize and create a VCHI connection */ @@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", __func__, ret); - ret = -EIO; - goto err_free_mem; + return -EIO; } ret = vchi_connect(NULL, 0, vchi_instance); if (ret) { LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", __func__, ret); - ret = -EIO; - goto err_free_mem; + kfree(vchi_instance); + return -EIO; } initted = 1; } @@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream if (IS_ERR(instance)) { LOG_ERR("%s: failed to initialize audio service\n", __func__); - ret = PTR_ERR(instance); - goto err_free_mem; + /* vchi_instance is retained for use the next time. */ + return PTR_ERR(instance); } instance->alsa_stream = alsa_stream; alsa_stream->instance = instance; LOG_DBG(" success !\n"); - ret = 0; -err_free_mem: - kfree(vchi_instance); - return ret; + return 0; } int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) diff --git a/drivers/staging/vc04_services/bcm2835-camera/Makefile b/drivers/staging/vc04_services/bcm2835-camera/Makefile index 8307f30517d5..2a4565e682d8 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/Makefile +++ b/drivers/staging/vc04_services/bcm2835-camera/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 bcm2835-v4l2-$(CONFIG_VIDEO_BCM2835) := \ bcm2835-camera.o \ controls.o \ diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index a11e047734f9..be936b8fe317 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -642,7 +642,7 @@ static void bm2835_mmal_unlock(struct vb2_queue *vq) mutex_unlock(&dev->mutex); } -static struct vb2_ops bm2835_mmal_video_qops = { +static const struct vb2_ops bm2835_mmal_video_qops = { .queue_setup = queue_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, @@ -1456,7 +1456,7 @@ static const struct v4l2_file_operations camera0_fops = { .mmap = vb2_fop_mmap, }; -static struct video_device vdev_template = { +static const struct video_device vdev_template = { .name = "camera0", .fops = &camera0_fops, .ioctl_ops = &camera0_ioctl_ops, diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 0159ca4407d8..be08849175ea 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -612,18 +612,20 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, if (head_bytes > actual) head_bytes = actual; - memcpy((char *)page_address(pages[0]) + + memcpy((char *)kmap(pages[0]) + pagelist->offset, fragments, head_bytes); + kunmap(pages[0]); } if ((actual >= 0) && (head_bytes < actual) && (tail_bytes != 0)) { - memcpy((char *)page_address(pages[num_pages - 1]) + + memcpy((char *)kmap(pages[num_pages - 1]) + ((pagelist->offset + actual) & (PAGE_SIZE - 1) & ~(g_cache_line_size - 1)), fragments + g_cache_line_size, tail_bytes); + kunmap(pages[num_pages - 1]); } down(&g_free_fragments_mutex); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion index 9f5b6344b9b7..dd1f324a8654 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_genversion @@ -1,4 +1,5 @@ #!/usr/bin/perl -w +# SPDX-License-Identifier: GPL-2.0 use strict; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c index 7fa0310e7b9e..2e52f07bbaa9 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c @@ -51,7 +51,7 @@ int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size) sema_init(&queue->pop, 0); sema_init(&queue->push, 0); - queue->storage = kzalloc(size * sizeof(VCHIQ_HEADER_T *), GFP_KERNEL); + queue->storage = kcalloc(size, sizeof(VCHIQ_HEADER_T *), GFP_KERNEL); if (!queue->storage) { vchiu_queue_delete(queue); return 0; diff --git a/drivers/staging/vme/devices/vme_pio2.h b/drivers/staging/vme/devices/vme_pio2.h index ac4a4bad4091..65f834cdeab2 100644 --- a/drivers/staging/vme/devices/vme_pio2.h +++ b/drivers/staging/vme/devices/vme_pio2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VME_PIO2_H_ #define _VME_PIO2_H_ diff --git a/drivers/staging/vme/devices/vme_user.h b/drivers/staging/vme/devices/vme_user.h index a6cb75686fa4..19ecb05781cc 100644 --- a/drivers/staging/vme/devices/vme_user.h +++ b/drivers/staging/vme/devices/vme_user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VME_USER_H_ #define _VME_USER_H_ diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile index d55c3baade53..a151f30fc46f 100644 --- a/drivers/staging/vt6655/Makefile +++ b/drivers/staging/vt6655/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # TODO: all of these should be removed ccflags-y := -DLINUX -D__KERNEL__ -D__NO_VERSION__ ccflags-y += -DHOSTAP diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index f5db2b3d9045..14034e342aa6 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -649,19 +649,19 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *priv, pr_debug("BASIC RATE: %X\n", priv->basic_rates); if (!CARDbIsOFDMinBasicRate((void *)priv)) { - pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); + 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("CARDwGetOFDMControlRate : %d\n", ui); + pr_debug("%s : %d\n", __func__, ui); return (unsigned short)ui; } ui--; } - pr_debug("CARDwGetOFDMControlRate: 6M\n"); + pr_debug("%s: 6M\n", __func__); return (unsigned short)RATE_24M; } diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index 4aaa99bafcda..f7550b215f72 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -809,7 +809,7 @@ void MACvSetKeyEntry(struct vnt_private *priv, unsigned short wKeyCtl, if (byLocalID <= 1) return; - pr_debug("MACvSetKeyEntry\n"); + pr_debug("%s\n", __func__); offset = MISCFIFO_KEYETRY0; offset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile index 3dbe1f89dd25..b64c0d87f612 100644 --- a/drivers/staging/vt6656/Makefile +++ b/drivers/staging/vt6656/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # TODO: all of these should be removed ccflags-y := -DLINUX -D__KERNEL__ -DEXPORT_SYMTAB -D__NO_VERSION__ ccflags-y += -DHOSTAP diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 4832666cc580..74715c854856 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -83,7 +83,7 @@ #define CONFIG_PATH "/etc/vntconfiguration.dat" #define MAX_UINTS 8 -#define OPTION_DEFAULT { [0 ... MAX_UINTS-1] = -1} +#define OPTION_DEFAULT { [0 ... MAX_UINTS - 1] = -1} #define DUPLICATE_RX_CACHE_LENGTH 5 diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 282f665aacfa..093a6048bd22 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -65,7 +65,7 @@ int vnt_download_firmware(struct vnt_private *priv) status = vnt_control_out(priv, 0, - 0x1200+ii, + 0x1200 + ii, 0x0000, length, buffer); diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index 906d3454591d..cfc6c2131536 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -46,6 +46,6 @@ 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); + struct ieee80211_vif *vif, struct ieee80211_key_conf *key); #endif /* __KEY_H__ */ diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 095b85567306..cc6d8778fe5b 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -419,8 +419,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) int ii; for (ii = 0; ii < priv->num_tx_context; ii++) { - tx_context = kmalloc(sizeof(struct vnt_usb_send_context), - GFP_KERNEL); + tx_context = kmalloc(sizeof(*tx_context), GFP_KERNEL); if (!tx_context) goto free_tx; @@ -437,7 +436,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) } for (ii = 0; ii < priv->num_rcb; ii++) { - priv->rcb[ii] = kzalloc(sizeof(struct vnt_rcb), GFP_KERNEL); + priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL); if (!priv->rcb[ii]) { dev_err(&priv->usb->dev, "failed to allocate rcb no %d\n", ii); diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index e322b7d8c617..c466e0614bc4 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -74,16 +74,15 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval) vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_GO2DOZE); if (listen_interval >= 2) { - /* clear always listen beacon */ vnt_mac_reg_bits_off(priv, MAC_REG_PSCTL, PSCTL_ALBCN); /* first time set listen next beacon */ vnt_mac_reg_bits_on(priv, MAC_REG_PSCTL, PSCTL_LNBCN); - } else - + } else { /* 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"); } @@ -100,7 +99,6 @@ void vnt_enable_power_saving(struct vnt_private *priv, u16 listen_interval) void vnt_disable_power_saving(struct vnt_private *priv) { - /* disable power saving hw function */ vnt_control_out(priv, MESSAGE_TYPE_DISABLE_PS, 0, 0, 0, NULL); diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 23581afb4211..3a9d19a0b842 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -611,7 +611,7 @@ int vnt_rf_write_embedded(struct vnt_private *priv, u32 data) reg_data[3] = (u8)(data >> 24); vnt_control_out(priv, MESSAGE_TYPE_WRITE_IFRF, - 0, 0, ARRAY_SIZE(reg_data), reg_data); + 0, 0, ARRAY_SIZE(reg_data), reg_data); return true; } @@ -643,9 +643,9 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel) case RATE_48M: case RATE_54M: if (channel > CB_MAX_CHANNEL_24G) - power = priv->ofdm_a_pwr_tbl[channel-15]; + power = priv->ofdm_a_pwr_tbl[channel - 15]; else - power = priv->ofdm_pwr_tbl[channel-1]; + power = priv->ofdm_pwr_tbl[channel - 1]; break; } diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index dc11a05be8c4..23eaef458556 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -44,7 +44,7 @@ #define USB_CTL_WAIT 500 /* ms */ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer) + u16 index, u16 length, u8 *buffer) { int status = 0; u8 *usb_buffer; @@ -82,7 +82,7 @@ void vnt_control_out_u8(struct vnt_private *priv, u8 reg, u8 reg_off, u8 data) } int vnt_control_in(struct vnt_private *priv, u8 request, u16 value, - u16 index, u16 length, u8 *buffer) + u16 index, u16 length, u8 *buffer) { int status; u8 *usb_buffer; diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index d22628314305..ee7e26b886a5 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_WILC1000) += wilc1000.o ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \ diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index 622994795222..8cf886d32afb 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "coreconfigurator.h" #include "wilc_wlan_if.h" #include "wilc_wlan.h" diff --git a/drivers/staging/wilc1000/coreconfigurator.h b/drivers/staging/wilc1000/coreconfigurator.h index 5256f40524bf..3f5da8c58815 100644 --- a/drivers/staging/wilc1000/coreconfigurator.h +++ b/drivers/staging/wilc1000/coreconfigurator.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*! * @file coreconfigurator.h diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 2568dfc15181..421168b9a9ca 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -1963,7 +1964,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, wilc_get_vif_idx(vif)); if (result) { - netdev_err(vif->ndev, "Failed to SET incative time\n"); + netdev_err(vif->ndev, "Failed to SET inactive time\n"); return -EFAULT; } @@ -1976,7 +1977,7 @@ static s32 Handle_Get_InActiveTime(struct wilc_vif *vif, wilc_get_vif_idx(vif)); if (result) { - netdev_err(vif->ndev, "Failed to get incative time\n"); + netdev_err(vif->ndev, "Failed to get inactive time\n"); return -EFAULT; } diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 1ce5ead318c7..44a2f4b595c5 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef HOST_INT_H #define HOST_INT_H #include diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 01efa80b4f88..91d49c4738dc 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /*! * @file linux_mon.c * @brief File Operations OS wrapper functionality diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index dbb3e24615be..119f3459b5bb 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -283,7 +283,8 @@ int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) static int linux_wlan_txq_task(void *vp) { - int ret, txq_count; + int ret; + u32 txq_count; struct wilc_vif *vif; struct wilc *wl; struct net_device *dev = vp; @@ -812,7 +813,7 @@ _fail_wilc_wlan_: wilc_wlan_cleanup(dev); _fail_locks_: wlan_deinit_locks(dev); - netdev_err(dev, "WLAN Iinitialization FAILED\n"); + netdev_err(dev, "WLAN initialization FAILED\n"); } else { netdev_dbg(dev, "wilc1000 already initialized\n"); } diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 68fd5b3b8b2d..af12925a9d2b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "wilc_wfi_cfgoperations.h" #include "host_interface.h" #include @@ -214,48 +215,39 @@ static u32 get_rssi_avg(struct network_info *network_info) return rssi_v; } -static void refresh_scan(void *user_void, u8 all, bool direct_scan) +static void refresh_scan(struct wilc_priv *priv, bool direct_scan) { - struct wilc_priv *priv; - struct wiphy *wiphy; - struct cfg80211_bss *bss = NULL; + struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy; int i; - int rssi = 0; - - priv = user_void; - wiphy = priv->dev->ieee80211_ptr->wiphy; for (i = 0; i < last_scanned_cnt; i++) { struct network_info *network_info; + s32 freq; + struct ieee80211_channel *channel; + int rssi; + struct cfg80211_bss *bss; network_info = &last_scanned_shadow[i]; - if (!network_info->found || all) { - s32 freq; - struct ieee80211_channel *channel; + if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan) + continue; - if (network_info) { - freq = ieee80211_channel_to_frequency((s32)network_info->ch, NL80211_BAND_2GHZ); - channel = ieee80211_get_channel(wiphy, freq); - - rssi = get_rssi_avg(network_info); - if (memcmp("DIRECT-", network_info->ssid, 7) || - direct_scan) { - bss = cfg80211_inform_bss(wiphy, - channel, - CFG80211_BSS_FTYPE_UNKNOWN, - network_info->bssid, - network_info->tsf_hi, - network_info->cap_info, - network_info->beacon_period, - (const u8 *)network_info->ies, - (size_t)network_info->ies_len, - (s32)rssi * 100, - GFP_KERNEL); - cfg80211_put_bss(wiphy, bss); - } - } - } + freq = ieee80211_channel_to_frequency((s32)network_info->ch, + NL80211_BAND_2GHZ); + channel = ieee80211_get_channel(wiphy, freq); + rssi = get_rssi_avg(network_info); + bss = cfg80211_inform_bss(wiphy, + channel, + CFG80211_BSS_FTYPE_UNKNOWN, + network_info->bssid, + network_info->tsf_hi, + network_info->cap_info, + network_info->beacon_period, + (const u8 *)network_info->ies, + (size_t)network_info->ies_len, + (s32)rssi * 100, + GFP_KERNEL); + cfg80211_put_bss(wiphy, bss); } } @@ -442,7 +434,7 @@ static void CfgScanResult(enum scan_event scan_event, } } } else if (scan_event == SCAN_EVENT_DONE) { - refresh_scan(priv, 1, false); + refresh_scan(priv, false); mutex_lock(&priv->scan_req_lock); @@ -466,7 +458,7 @@ static void CfgScanResult(enum scan_event scan_event, }; update_scan_time(); - refresh_scan(priv, 1, false); + refresh_scan(priv, false); cfg80211_scan_done(priv->pstrScanReq, &info); priv->bCfgScanning = false; @@ -540,7 +532,7 @@ static void CfgConnectResult(enum conn_event enuConnDisconnEvent, } if (bNeedScanRefresh) - refresh_scan(priv, 1, true); + refresh_scan(priv, true); } cfg80211_connect_result(dev, pstrConnectInfo->bssid, diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index 85a3810d7bb5..dfb7ec272935 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*! * @file wilc_wfi_cfgoperations.h * @brief Definitions for the network module diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index c89bf4301096..e6f4d84971c3 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*! * @file wilc_wfi_netdevice.h * @brief Definitions for the network module @@ -227,8 +228,8 @@ int wilc1000_wlan_init(struct net_device *dev, struct wilc_vif *vif); void wilc_frmw_to_linux(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_mac_indicate(struct wilc *wilc, int flag); void wilc_netdev_cleanup(struct wilc *wilc); -int wilc_netdev_init(struct wilc **wilc, struct device *, int io_type, int gpio, - const struct wilc_hif_func *ops); +int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, + int gpio, const struct wilc_hif_func *ops); void wilc1000_wlan_deinit(struct net_device *dev); void WILC_WFI_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); int wilc_wlan_get_firmware(struct net_device *dev); diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 7a5eba9b5f47..da7173105497 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef WILC_WLAN_H #define WILC_WLAN_H diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index d3e5b1b302f4..19e4f85fdd27 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* ////////////////////////////////////////////////////////////////////////// */ /* */ /* Copyright (c) Atmel Corporation. All rights reserved. */ diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.h b/drivers/staging/wilc1000/wilc_wlan_cfg.h index b8641a273547..08092a551840 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.h +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ////////////////////////////////////////////////////////////////////////// */ /* */ /* Copyright (c) Atmel Corporation. All rights reserved. */ diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index f4d60057a06e..c1693cfc076d 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* ///////////////////////////////////////////////////////////////////////// */ /* */ /* Copyright (c) Atmel Corporation. All rights reserved. */ diff --git a/drivers/staging/wlan-ng/Makefile b/drivers/staging/wlan-ng/Makefile index 32b69f238c69..1d24b0f86eee 100644 --- a/drivers/staging/wlan-ng/Makefile +++ b/drivers/staging/wlan-ng/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PRISM2_USB) += prism2_usb.o prism2_usb-y := prism2usb.o \ diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 178f6f5d4613..42912257e2b9 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* cfg80211 Interface for prism2_usb module */ #include "hfa384x.h" #include "prism2mgmt.h" diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index 018db2299d0c..f5a3a1ce21ce 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -413,8 +413,8 @@ struct hfa384x_join_request_data { /*-- Configuration Record: authenticateStation (data portion only) --*/ struct hfa384x_authenticate_station_data { u8 address[ETH_ALEN]; - u16 status; - u16 algorithm; + __le16 status; + __le16 algorithm; } __packed; /*-- Configuration Record: WPAData (data portion only) --*/ @@ -445,9 +445,9 @@ struct hfa384x_downloadbuffer { /*-- Information Record: commsquality --*/ struct hfa384x_commsquality { - u16 cq_curr_bss; - u16 asl_curr_bss; - u16 anl_curr_fc; + __le16 cq_curr_bss; + __le16 asl_curr_bss; + __le16 anl_curr_fc; } __packed; /*-- Information Record: dmbcommsquality --*/ @@ -598,51 +598,51 @@ struct hfa384x_rx_frame { /*-- Inquiry Frame, Diagnose: Communication Tallies --*/ struct hfa384x_comm_tallies_16 { - u16 txunicastframes; - u16 txmulticastframes; - u16 txfragments; - u16 txunicastoctets; - u16 txmulticastoctets; - u16 txdeferredtrans; - u16 txsingleretryframes; - u16 txmultipleretryframes; - u16 txretrylimitexceeded; - u16 txdiscards; - u16 rxunicastframes; - u16 rxmulticastframes; - u16 rxfragments; - u16 rxunicastoctets; - u16 rxmulticastoctets; - u16 rxfcserrors; - u16 rxdiscardsnobuffer; - u16 txdiscardswrongsa; - u16 rxdiscardswepundecr; - u16 rxmsginmsgfrag; - u16 rxmsginbadmsgfrag; + __le16 txunicastframes; + __le16 txmulticastframes; + __le16 txfragments; + __le16 txunicastoctets; + __le16 txmulticastoctets; + __le16 txdeferredtrans; + __le16 txsingleretryframes; + __le16 txmultipleretryframes; + __le16 txretrylimitexceeded; + __le16 txdiscards; + __le16 rxunicastframes; + __le16 rxmulticastframes; + __le16 rxfragments; + __le16 rxunicastoctets; + __le16 rxmulticastoctets; + __le16 rxfcserrors; + __le16 rxdiscardsnobuffer; + __le16 txdiscardswrongsa; + __le16 rxdiscardswepundecr; + __le16 rxmsginmsgfrag; + __le16 rxmsginbadmsgfrag; } __packed; struct hfa384x_comm_tallies_32 { - u32 txunicastframes; - u32 txmulticastframes; - u32 txfragments; - u32 txunicastoctets; - u32 txmulticastoctets; - u32 txdeferredtrans; - u32 txsingleretryframes; - u32 txmultipleretryframes; - u32 txretrylimitexceeded; - u32 txdiscards; - u32 rxunicastframes; - u32 rxmulticastframes; - u32 rxfragments; - u32 rxunicastoctets; - u32 rxmulticastoctets; - u32 rxfcserrors; - u32 rxdiscardsnobuffer; - u32 txdiscardswrongsa; - u32 rxdiscardswepundecr; - u32 rxmsginmsgfrag; - u32 rxmsginbadmsgfrag; + __le32 txunicastframes; + __le32 txmulticastframes; + __le32 txfragments; + __le32 txunicastoctets; + __le32 txmulticastoctets; + __le32 txdeferredtrans; + __le32 txsingleretryframes; + __le32 txmultipleretryframes; + __le32 txretrylimitexceeded; + __le32 txdiscards; + __le32 rxunicastframes; + __le32 rxmulticastframes; + __le32 rxfragments; + __le32 rxunicastoctets; + __le32 rxmulticastoctets; + __le32 rxfcserrors; + __le32 rxdiscardsnobuffer; + __le32 txdiscardswrongsa; + __le32 rxdiscardswepundecr; + __le32 rxmsginmsgfrag; + __le32 rxmsginbadmsgfrag; } __packed; /*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/ @@ -711,7 +711,7 @@ struct hfa384x_hscan_result { #define HFA384x_LINK_ASSOCFAIL ((u16)6) struct hfa384x_link_status { - u16 linkstatus; + __le16 linkstatus; } __packed; /*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/ @@ -733,13 +733,13 @@ struct hfa384x_assoc_status { struct hfa384x_auth_request { u8 sta_addr[ETH_ALEN]; - u16 algorithm; + __le16 algorithm; } __packed; /*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/ struct hfa384x_ps_user_count { - u16 usercnt; + __le16 usercnt; } __packed; struct hfa384x_key_id_changed { diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index ee5fa86e941d..d1e8218f96fb 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -1344,16 +1344,14 @@ hfa384x_docmd(struct hfa384x *hw, if (result != 0) { kfree(ctlx); } else if (mode == DOWAIT) { - struct usbctlx_cmd_completor completor; + struct usbctlx_cmd_completor cmd_completor; + struct usbctlx_completor *completor; - result = - hfa384x_usbctlx_complete_sync(hw, ctlx, - init_cmd_completor(&completor, - &ctlx-> - inbuf. - cmdresp, - &cmd-> - result)); + completor = init_cmd_completor(&cmd_completor, + &ctlx->inbuf.cmdresp, + &cmd->result); + + result = hfa384x_usbctlx_complete_sync(hw, ctlx, completor); } done: diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index fc8ad33ade9f..c1b6d426bcad 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -213,6 +213,7 @@ int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv, netdev_warn(wlandev->netdev, "Host en-WEP failed, dropping frame (%d).\n", foo); + kfree(p80211_wep->data); return 2; } fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 021fb23ae9ba..0f503652740f 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -258,7 +258,7 @@ static int p80211_convert_to_ether(struct wlandevice *wlandev, return 0; } - netdev_dbg(wlandev->netdev, "p80211_convert_to_ether failed.\n"); + netdev_dbg(wlandev->netdev, "%s failed.\n", __func__); return CONV_TO_ETHER_FAILED; } diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 1a0c786c7616..344bec8cc31b 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -1016,7 +1016,8 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, kfree(rstmsg); kfree(rwrmsg); netdev_err(wlandev->netdev, - "writeimage: no memory for firmware download, aborting download\n"); + "%s: no memory for firmware download, aborting download\n", + __func__); return -ENOMEM; } @@ -1058,15 +1059,15 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { netdev_err(wlandev->netdev, - "writeimage state enable failed w/ result=%d, aborting download\n", - result); + "%s state enable failed w/ result=%d, aborting download\n", + __func__, result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { netdev_err(wlandev->netdev, - "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", - resultcode); + "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", + __func__, resultcode); result = 1; goto free_result; } @@ -1102,14 +1103,14 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, /* Check the results */ if (result) { netdev_err(wlandev->netdev, - "writeimage chunk write failed w/ result=%d, aborting download\n", - result); + "%s chunk write failed w/ result=%d, aborting download\n", + __func__, result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { - pr_err("writeimage()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n", - resultcode); + pr_err("%s()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n", + __func__, resultcode); result = 1; goto free_result; } @@ -1124,15 +1125,15 @@ static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { netdev_err(wlandev->netdev, - "writeimage state disable failed w/ result=%d, aborting download\n", - result); + "%s state disable failed w/ result=%d, aborting download\n", + __func__, result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { netdev_err(wlandev->netdev, - "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", - resultcode); + "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", + __func__, resultcode); result = 1; goto free_result; } diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index e16da34389cd..c9df45063ab3 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -991,9 +991,9 @@ static void prism2sta_inf_tallies(struct wlandevice *wlandev, struct hfa384x_inf_frame *inf) { struct hfa384x *hw = wlandev->priv; - u16 *src16; + __le16 *src16; u32 *dst; - u32 *src32; + __le32 *src32; int i; int cnt; @@ -1005,12 +1005,12 @@ static void prism2sta_inf_tallies(struct wlandevice *wlandev, cnt = sizeof(struct hfa384x_comm_tallies_32) / sizeof(u32); if (inf->framelen > 22) { dst = (u32 *)&hw->tallies; - src32 = (u32 *)&inf->info.commtallies32; + src32 = (__le32 *)&inf->info.commtallies32; for (i = 0; i < cnt; i++, dst++, src32++) *dst += le32_to_cpu(*src32); } else { dst = (u32 *)&hw->tallies; - src16 = (u16 *)&inf->info.commtallies16; + src16 = (__le16 *)&inf->info.commtallies16; for (i = 0; i < cnt; i++, dst++, src16++) *dst += le16_to_cpu(*src16); } @@ -1136,7 +1136,7 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, unsigned int i, n; hw->channel_info.results.scanchannels = - le16_to_cpu(inf->info.chinforesult.scanchannels); + inf->info.chinforesult.scanchannels; for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) { struct hfa384x_ch_info_result_sub *result; @@ -1147,16 +1147,16 @@ static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, continue; result = &inf->info.chinforesult.result[n]; - chan = le16_to_cpu(result->chid) - 1; + chan = result->chid - 1; if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX) continue; chinforesult = &hw->channel_info.results.result[chan]; chinforesult->chid = chan; - chinforesult->anl = le16_to_cpu(result->anl); - chinforesult->pnl = le16_to_cpu(result->pnl); - chinforesult->active = le16_to_cpu(result->active); + chinforesult->anl = result->anl; + chinforesult->pnl = result->pnl; + chinforesult->active = result->active; pr_debug("chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", chan + 1, @@ -1447,7 +1447,7 @@ static void prism2sta_inf_linkstatus(struct wlandevice *wlandev, { struct hfa384x *hw = wlandev->priv; - hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus); + hw->link_status_new = inf->info.linkstatus.linkstatus; schedule_work(&hw->link_bh); } @@ -1561,7 +1561,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, */ ether_addr_copy(rec.address, inf->info.authreq.sta_addr); - rec.status = P80211ENUM_status_unspec_failure; + rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); /* * Authenticate based on the access mode. @@ -1578,7 +1578,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, for (i = 0; i < hw->authlist.cnt; i++) if (ether_addr_equal(rec.address, hw->authlist.addr[i])) { - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); break; } @@ -1590,7 +1590,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, * Allow all authentications. */ - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); break; case WLAN_ACCESS_ALLOW: @@ -1615,7 +1615,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, for (i = 0; i < cnt; i++, addr += ETH_ALEN) if (ether_addr_equal(rec.address, addr)) { - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); break; } @@ -1641,11 +1641,11 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, addr = hw->deny.addr1[0]; } - rec.status = P80211ENUM_status_successful; + rec.status = cpu_to_le16(P80211ENUM_status_successful); for (i = 0; i < cnt; i++, addr += ETH_ALEN) if (ether_addr_equal(rec.address, addr)) { - rec.status = P80211ENUM_status_unspec_failure; + rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); break; } @@ -1663,7 +1663,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, added = 0; - if (rec.status == P80211ENUM_status_successful) { + if (rec.status == cpu_to_le16(P80211ENUM_status_successful)) { for (i = 0; i < hw->authlist.cnt; i++) if (ether_addr_equal(rec.address, hw->authlist.addr[i])) @@ -1671,7 +1671,7 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, if (i >= hw->authlist.cnt) { if (hw->authlist.cnt >= WLAN_AUTH_MAX) { - rec.status = P80211ENUM_status_ap_full; + rec.status = cpu_to_le16(P80211ENUM_status_ap_full); } else { ether_addr_copy( hw->authlist.addr[hw->authlist.cnt], @@ -1688,7 +1688,6 @@ static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, * it was added. */ - rec.status = cpu_to_le16(rec.status); rec.algorithm = inf->info.authreq.algorithm; result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA, diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c index bfb6b0a6528d..b5ba176004c1 100644 --- a/drivers/staging/wlan-ng/prism2usb.c +++ b/drivers/staging/wlan-ng/prism2usb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "hfa384x_usb.c" #include "prism2mgmt.c" #include "prism2mib.c" diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index 7a80a90f229f..a3af1cbbf8ee 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _XGIFB_MAIN #define _XGIFB_MAIN /* ------------------- Constant Definitions ------------------------- */ diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index af50362395d5..982c676c16c6 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_XGIFB #define _LINUX_XGIFB #include "vgatypes.h" diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 94e2e3c7c264..0311e2682d27 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VB_DEF_ #define _VB_DEF_ #include "../../video/fbdev/sis/initdef.h" diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 591a3c9babf5..ac1c815a3c5e 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/drivers/staging/xgifb/vb_init.h b/drivers/staging/xgifb/vb_init.h index e835054b87bf..2f8a70133ebd 100644 --- a/drivers/staging/xgifb/vb_init.h +++ b/drivers/staging/xgifb/vb_init.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VBINIT_ #define _VBINIT_ unsigned char XGIInitNew(struct pci_dev *pdev); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index cea128bede52..da07ca57bb40 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "XGIfb.h" diff --git a/drivers/staging/xgifb/vb_setmode.h b/drivers/staging/xgifb/vb_setmode.h index c6317ab00474..5904ed1f2686 100644 --- a/drivers/staging/xgifb/vb_setmode.h +++ b/drivers/staging/xgifb/vb_setmode.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VBSETMODE_ #define _VBSETMODE_ diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 2fd1a5935e1d..e256f72f6d8a 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VB_STRUCT_ #define _VB_STRUCT_ #include "../../video/fbdev/sis/vstruct.h" diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 31dd52c513df..0da63e1da32f 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VB_TABLE_ #define _VB_TABLE_ static const struct SiS_MCLKData XGI340New_MCLKData[] = { diff --git a/drivers/staging/xgifb/vb_util.h b/drivers/staging/xgifb/vb_util.h index 052694e75053..0f6d5aac04f6 100644 --- a/drivers/staging/xgifb/vb_util.h +++ b/drivers/staging/xgifb/vb_util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VBUTIL_ #define _VBUTIL_ static inline void xgifb_reg_set(unsigned long port, u8 index, u8 data) diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index de80e5c108dc..22919f2368d5 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VGATYPES_ #define _VGATYPES_ diff --git a/drivers/target/Makefile b/drivers/target/Makefile index e619c0266a79..45634747377e 100644 --- a/drivers/target/Makefile +++ b/drivers/target/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 target_core_mod-y := target_core_configfs.o \ target_core_device.o \ diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile index 0f18295e05bc..8c9ae96b760d 100644 --- a/drivers/target/iscsi/Makefile +++ b/drivers/target/iscsi/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 iscsi_target_mod-y += iscsi_target_parameters.o \ iscsi_target_seq_pdu_list.o \ iscsi_target_auth.o \ diff --git a/drivers/target/iscsi/cxgbit/Makefile b/drivers/target/iscsi/cxgbit/Makefile index 4893ec29b6b3..d16aaae7ba2a 100644 --- a/drivers/target/iscsi/cxgbit/Makefile +++ b/drivers/target/iscsi/cxgbit/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4 ccflags-y += -Idrivers/net/ethernet/chelsio/libcxgb ccflags-y += -Idrivers/target/iscsi diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index e0db2ceb0f87..42de1843aa40 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_H #define ISCSI_TARGET_H diff --git a/drivers/target/iscsi/iscsi_target_auth.h b/drivers/target/iscsi/iscsi_target_auth.h index 1b91c13cc965..d5600ac30b53 100644 --- a/drivers/target/iscsi/iscsi_target_auth.h +++ b/drivers/target/iscsi/iscsi_target_auth.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ISCSI_CHAP_H_ #define _ISCSI_CHAP_H_ diff --git a/drivers/target/iscsi/iscsi_target_datain_values.h b/drivers/target/iscsi/iscsi_target_datain_values.h index 16edeeeb7777..a420fbd37969 100644 --- a/drivers/target/iscsi/iscsi_target_datain_values.h +++ b/drivers/target/iscsi/iscsi_target_datain_values.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_DATAIN_VALUES_H #define ISCSI_TARGET_DATAIN_VALUES_H diff --git a/drivers/target/iscsi/iscsi_target_device.h b/drivers/target/iscsi/iscsi_target_device.h index 06dbff5cd520..ab2166f17785 100644 --- a/drivers/target/iscsi/iscsi_target_device.h +++ b/drivers/target/iscsi/iscsi_target_device.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_DEVICE_H #define ISCSI_TARGET_DEVICE_H diff --git a/drivers/target/iscsi/iscsi_target_erl0.h b/drivers/target/iscsi/iscsi_target_erl0.h index 3822d9cd1230..3393407bc4e4 100644 --- a/drivers/target/iscsi/iscsi_target_erl0.h +++ b/drivers/target/iscsi/iscsi_target_erl0.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_ERL0_H #define ISCSI_TARGET_ERL0_H diff --git a/drivers/target/iscsi/iscsi_target_erl1.h b/drivers/target/iscsi/iscsi_target_erl1.h index 54d36bd25bea..5f66b265b25b 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.h +++ b/drivers/target/iscsi/iscsi_target_erl1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_ERL1_H #define ISCSI_TARGET_ERL1_H diff --git a/drivers/target/iscsi/iscsi_target_erl2.h b/drivers/target/iscsi/iscsi_target_erl2.h index 634d01e13652..93e180d68d07 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.h +++ b/drivers/target/iscsi/iscsi_target_erl2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_ERL2_H #define ISCSI_TARGET_ERL2_H diff --git a/drivers/target/iscsi/iscsi_target_login.h b/drivers/target/iscsi/iscsi_target_login.h index 0e1fd6cedd54..c2495e03625c 100644 --- a/drivers/target/iscsi/iscsi_target_login.h +++ b/drivers/target/iscsi/iscsi_target_login.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_LOGIN_H #define ISCSI_TARGET_LOGIN_H diff --git a/drivers/target/iscsi/iscsi_target_nego.h b/drivers/target/iscsi/iscsi_target_nego.h index 53438bfca4c6..835e1b769b3f 100644 --- a/drivers/target/iscsi/iscsi_target_nego.h +++ b/drivers/target/iscsi/iscsi_target_nego.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_NEGO_H #define ISCSI_TARGET_NEGO_H diff --git a/drivers/target/iscsi/iscsi_target_nodeattrib.h b/drivers/target/iscsi/iscsi_target_nodeattrib.h index 79cdf06ade48..ce074cb54579 100644 --- a/drivers/target/iscsi/iscsi_target_nodeattrib.h +++ b/drivers/target/iscsi/iscsi_target_nodeattrib.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_NODEATTRIB_H #define ISCSI_TARGET_NODEATTRIB_H diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h index c47b73f57528..daf47f38e081 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.h +++ b/drivers/target/iscsi/iscsi_target_parameters.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_PARAMETERS_H #define ISCSI_PARAMETERS_H diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.h b/drivers/target/iscsi/iscsi_target_seq_pdu_list.h index be1234362271..5a0907027973 100644 --- a/drivers/target/iscsi/iscsi_target_seq_pdu_list.h +++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_SEQ_AND_PDU_LIST_H #define ISCSI_SEQ_AND_PDU_LIST_H diff --git a/drivers/target/iscsi/iscsi_target_tmr.h b/drivers/target/iscsi/iscsi_target_tmr.h index 64cc5c07e47c..301f0936bd8e 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.h +++ b/drivers/target/iscsi/iscsi_target_tmr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_TMR_H #define ISCSI_TARGET_TMR_H diff --git a/drivers/target/iscsi/iscsi_target_tpg.h b/drivers/target/iscsi/iscsi_target_tpg.h index 59fd3cabe89d..88576f5d0ca4 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.h +++ b/drivers/target/iscsi/iscsi_target_tpg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_TPG_H #define ISCSI_TARGET_TPG_H diff --git a/drivers/target/iscsi/iscsi_target_transport.c b/drivers/target/iscsi/iscsi_target_transport.c index c4eb141c6435..036940518bfe 100644 --- a/drivers/target/iscsi/iscsi_target_transport.c +++ b/drivers/target/iscsi/iscsi_target_transport.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 425160565d0c..5e053d61c0c5 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ISCSI_TARGET_UTIL_H #define ISCSI_TARGET_UTIL_H diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h index 3acc43c05117..d3110909a213 100644 --- a/drivers/target/loopback/tcm_loop.h +++ b/drivers/target/loopback/tcm_loop.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include /* struct se_cmd */ diff --git a/drivers/target/sbp/sbp_target.h b/drivers/target/sbp/sbp_target.h index 73bcb1208832..1d101ac86527 100644 --- a/drivers/target/sbp/sbp_target.h +++ b/drivers/target/sbp/sbp_target.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SBP_BASE_H #define _SBP_BASE_H diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index a91b7c25ffd4..928127642574 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -896,13 +896,14 @@ static int core_alua_write_tpg_metadata( u32 md_buf_len) { struct file *file = filp_open(path, O_RDWR | O_CREAT | O_TRUNC, 0600); + loff_t pos = 0; int ret; if (IS_ERR(file)) { pr_err("filp_open(%s) for ALUA metadata failed\n", path); return -ENODEV; } - ret = kernel_write(file, md_buf, md_buf_len, 0); + ret = kernel_write(file, md_buf, md_buf_len, &pos); if (ret < 0) pr_err("Error writing ALUA metadata file: %s\n", path); fput(file); diff --git a/drivers/target/target_core_alua.h b/drivers/target/target_core_alua.h index c69c11baf07f..1902cb5c3b52 100644 --- a/drivers/target/target_core_alua.h +++ b/drivers/target/target_core_alua.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_ALUA_H #define TARGET_CORE_ALUA_H diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 24cf11d9e50a..c629817a8854 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -443,7 +443,7 @@ fd_do_prot_fill(struct se_device *se_dev, sector_t lba, sector_t nolb, for (prot = 0; prot < prot_length;) { sector_t len = min_t(sector_t, bufsize, prot_length - prot); - ssize_t ret = kernel_write(prot_fd, buf, len, pos + prot); + ssize_t ret = kernel_write(prot_fd, buf, len, &pos); if (ret != len) { pr_err("vfs_write to prot file failed: %zd\n", ret); diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h index 526595a072de..53be5ffd3261 100644 --- a/drivers/target/target_core_file.h +++ b/drivers/target/target_core_file.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_FILE_H #define TARGET_CORE_FILE_H diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index ee7c7fa55dad..07c814c42648 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -338,7 +338,7 @@ iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num, int op, return NULL; } - bio->bi_bdev = ib_dev->ibd_bd; + bio_set_dev(bio, ib_dev->ibd_bd); bio->bi_private = cmd; bio->bi_end_io = &iblock_bio_done; bio->bi_iter.bi_sector = lba; @@ -395,7 +395,7 @@ iblock_execute_sync_cache(struct se_cmd *cmd) bio = bio_alloc(GFP_KERNEL, 0); bio->bi_end_io = iblock_end_io_flush; - bio->bi_bdev = ib_dev->ibd_bd; + bio_set_dev(bio, ib_dev->ibd_bd); bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; if (!immed) bio->bi_private = cmd; diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h index f2a5797217d4..b4aeb2584ad4 100644 --- a/drivers/target/target_core_iblock.h +++ b/drivers/target/target_core_iblock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_IBLOCK_H #define TARGET_CORE_IBLOCK_H diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index f30e8ac13386..18e3eb16e756 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_INTERNAL_H #define TARGET_CORE_INTERNAL_H diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 6d5def64db61..dd2cd8048582 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1974,6 +1974,7 @@ static int __core_scsi3_write_aptpl_to_file( char path[512]; u32 pr_aptpl_buf_len; int ret; + loff_t pos = 0; memset(path, 0, 512); @@ -1993,7 +1994,7 @@ static int __core_scsi3_write_aptpl_to_file( pr_aptpl_buf_len = (strlen(buf) + 1); /* Add extra for NULL */ - ret = kernel_write(file, buf, pr_aptpl_buf_len, 0); + ret = kernel_write(file, buf, pr_aptpl_buf_len, &pos); if (ret < 0) pr_debug("Error writing APTPL metadata file: %s\n", path); diff --git a/drivers/target/target_core_pr.h b/drivers/target/target_core_pr.h index 772f9148e75c..198fad5c89dc 100644 --- a/drivers/target/target_core_pr.h +++ b/drivers/target/target_core_pr.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_PR_H #define TARGET_CORE_PR_H diff --git a/drivers/target/target_core_pscsi.h b/drivers/target/target_core_pscsi.h index b86fb0e1b783..e8458b5e85c9 100644 --- a/drivers/target/target_core_pscsi.h +++ b/drivers/target/target_core_pscsi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_PSCSI_H #define TARGET_CORE_PSCSI_H diff --git a/drivers/target/target_core_rd.h b/drivers/target/target_core_rd.h index 91fc1a34791d..8b88f9b14c3f 100644 --- a/drivers/target/target_core_rd.h +++ b/drivers/target/target_core_rd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_RD_H #define TARGET_CORE_RD_H diff --git a/drivers/target/target_core_ua.h b/drivers/target/target_core_ua.h index 97402856a8f0..b0f4205a96cd 100644 --- a/drivers/target/target_core_ua.h +++ b/drivers/target/target_core_ua.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TARGET_CORE_UA_H #define TARGET_CORE_UA_H diff --git a/drivers/target/target_core_xcopy.h b/drivers/target/target_core_xcopy.h index 7c0b105cbe1b..26ba4c3c9cff 100644 --- a/drivers/target/target_core_xcopy.h +++ b/drivers/target/target_core_xcopy.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #define XCOPY_HDR_LEN 16 diff --git a/drivers/target/tcm_fc/Makefile b/drivers/target/tcm_fc/Makefile index 20b14bb087c9..a7d1593ab5af 100644 --- a/drivers/target/tcm_fc/Makefile +++ b/drivers/target/tcm_fc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 tcm_fc-y += tfc_cmd.o \ tfc_conf.o \ tfc_io.o \ diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile index 7a4e4a1ac39c..21f51fd88b07 100644 --- a/drivers/tee/Makefile +++ b/drivers/tee/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEE) += tee.o tee-objs += tee_core.o tee-objs += tee_shm.o diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile index 92fe5789bcce..d526fb88d9c5 100644 --- a/drivers/tee/optee/Makefile +++ b/drivers/tee/optee/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OPTEE) += optee.o optee-objs += core.o optee-objs += call.o diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index 58169e519422..7952357df9c8 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -224,13 +224,14 @@ static void optee_release(struct tee_context *ctx) if (!IS_ERR(shm)) { arg = tee_shm_get_va(shm, 0); /* - * If va2pa fails for some reason, we can't call - * optee_close_session(), only free the memory. Secure OS - * will leak sessions and finally refuse more sessions, but - * we will at least let normal world reclaim its memory. + * If va2pa fails for some reason, we can't call into + * secure world, only free the memory. Secure OS will leak + * sessions and finally refuse more sessions, but we will + * at least let normal world reclaim its memory. */ if (!IS_ERR(arg)) - tee_shm_va2pa(shm, arg, &parg); + if (tee_shm_va2pa(shm, arg, &parg)) + arg = NULL; /* prevent usage of parg below */ } list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list, @@ -258,7 +259,7 @@ static void optee_release(struct tee_context *ctx) } } -static struct tee_driver_ops optee_ops = { +static const struct tee_driver_ops optee_ops = { .get_version = optee_get_version, .open = optee_open, .release = optee_release, @@ -268,13 +269,13 @@ static struct tee_driver_ops optee_ops = { .cancel_req = optee_cancel_req, }; -static struct tee_desc optee_desc = { +static const struct tee_desc optee_desc = { .name = DRIVER_NAME "-clnt", .ops = &optee_ops, .owner = THIS_MODULE, }; -static struct tee_driver_ops optee_supp_ops = { +static const struct tee_driver_ops optee_supp_ops = { .get_version = optee_get_version, .open = optee_open, .release = optee_release, @@ -282,7 +283,7 @@ static struct tee_driver_ops optee_supp_ops = { .supp_send = optee_supp_send, }; -static struct tee_desc optee_supp_desc = { +static const struct tee_desc optee_supp_desc = { .name = DRIVER_NAME "-supp", .ops = &optee_supp_ops, .owner = THIS_MODULE, diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h index 13b7c98cdf25..069c8e1429de 100644 --- a/drivers/tee/optee/optee_smc.h +++ b/drivers/tee/optee/optee_smc.h @@ -298,7 +298,7 @@ struct optee_smc_disable_shm_cache_result { OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE) /* - * Resume from RPC (for example after processing an IRQ) + * Resume from RPC (for example after processing a foreign interrupt) * * Call register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC @@ -383,19 +383,19 @@ struct optee_smc_disable_shm_cache_result { OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE) /* - * Deliver an IRQ in normal world. + * Deliver foreign interrupt to normal world. * * "Call" register usage: - * a0 OPTEE_SMC_RETURN_RPC_IRQ + * a0 OPTEE_SMC_RETURN_RPC_FOREIGN_INTR * a1-7 Resume information, must be preserved * * "Return" register usage: * a0 SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC. * a1-7 Preserved */ -#define OPTEE_SMC_RPC_FUNC_IRQ 4 -#define OPTEE_SMC_RETURN_RPC_IRQ \ - OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_IRQ) +#define OPTEE_SMC_RPC_FUNC_FOREIGN_INTR 4 +#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR \ + OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FOREIGN_INTR) /* * Do an RPC request. The supplied struct optee_msg_arg tells which diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c index 8814eca06021..cef417f4f4d2 100644 --- a/drivers/tee/optee/rpc.c +++ b/drivers/tee/optee/rpc.c @@ -140,11 +140,8 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg) msec_to_wait = arg->params[0].u.value.a; - /* set task's state to interruptible sleep */ - set_current_state(TASK_INTERRUPTIBLE); - - /* take a nap */ - msleep(msec_to_wait); + /* Go to interruptible sleep */ + msleep_interruptible(msec_to_wait); arg->ret = TEEC_SUCCESS; return; @@ -374,11 +371,11 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param) shm = reg_pair_to_ptr(param->a1, param->a2); tee_shm_free(shm); break; - case OPTEE_SMC_RPC_FUNC_IRQ: + case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR: /* - * An IRQ was raised while secure world was executing, - * since all IRQs are handled in Linux a dummy RPC is - * performed to let Linux take the IRQ through the normal + * A foreign interrupt was raised while secure world was + * executing, since they are handled in Linux a dummy RPC is + * performed to let Linux take the interrupt through the normal * vector. */ break; diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 5c60bf4423e6..58a5009eacc3 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -90,8 +90,13 @@ static int tee_ioctl_version(struct tee_context *ctx, struct tee_ioctl_version_data vers; ctx->teedev->desc->ops->get_version(ctx->teedev, &vers); + + if (ctx->teedev->desc->flags & TEE_DESC_PRIVILEGED) + vers.gen_caps |= TEE_GEN_CAP_PRIVILEGED; + if (copy_to_user(uvers, &vers, sizeof(vers))) return -EFAULT; + return 0; } diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index d356d7f025eb..4bc7956cefc4 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -80,7 +80,7 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) size, vma->vm_page_prot); } -static struct dma_buf_ops tee_shm_dma_buf_ops = { +static const struct dma_buf_ops tee_shm_dma_buf_ops = { .map_dma_buf = tee_shm_op_map_dma_buf, .unmap_dma_buf = tee_shm_op_unmap_dma_buf, .release = tee_shm_op_release, diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index b5b5facb8747..07002df4f83a 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -342,7 +342,7 @@ config X86_PKG_TEMP_THERMAL config INTEL_SOC_DTS_IOSF_CORE tristate - depends on X86 + depends on X86 && PCI select IOSF_MBI help This is becoming a common feature for Intel SoCs to expose the additional @@ -352,7 +352,7 @@ config INTEL_SOC_DTS_IOSF_CORE config INTEL_SOC_DTS_THERMAL tristate "Intel SoCs DTS thermal driver" - depends on X86 + depends on X86 && PCI select INTEL_SOC_DTS_IOSF_CORE select THERMAL_WRITABLE_TRIPS help @@ -473,4 +473,12 @@ config ZX2967_THERMAL the primitive temperature sensor embedded in zx2967 SoCs. This sensor generates the real time die temperature. +config UNIPHIER_THERMAL + tristate "Socionext UniPhier thermal driver" + depends on ARCH_UNIPHIER || COMPILE_TEST + depends on THERMAL_OF && MFD_SYSCON + help + Enable this to plug in UniPhier on-chip PVT thermal driver into the + thermal framework. The driver supports CPU thermal zone temperature + reporting and a couple of trip points. endif diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 094d7039981c..195cd08fbc30 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for sensor chip drivers. # @@ -59,3 +60,4 @@ obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o +obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o diff --git a/drivers/thermal/broadcom/bcm2835_thermal.c b/drivers/thermal/broadcom/bcm2835_thermal.c index e6863c841662..a4d6a0e2e993 100644 --- a/drivers/thermal/broadcom/bcm2835_thermal.c +++ b/drivers/thermal/broadcom/bcm2835_thermal.c @@ -145,7 +145,7 @@ static void bcm2835_thermal_debugfs(struct platform_device *pdev) debugfs_create_regset32("regset", 0444, data->debugfsdir, regset); } -static struct thermal_zone_of_device_ops bcm2835_thermal_ops = { +static const struct thermal_zone_of_device_ops bcm2835_thermal_ops = { .get_temp = bcm2835_thermal_get_temp, }; diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c index 9c3ce341eb97..bd3572c41585 100644 --- a/drivers/thermal/hisi_thermal.c +++ b/drivers/thermal/hisi_thermal.c @@ -206,7 +206,7 @@ static int hisi_thermal_get_temp(void *_sensor, int *temp) return 0; } -static struct thermal_zone_of_device_ops hisi_of_thermal_ops = { +static const struct thermal_zone_of_device_ops hisi_of_thermal_ops = { .get_temp = hisi_thermal_get_temp, }; diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile index df0df055e7ff..287eb0a1476d 100644 --- a/drivers/thermal/int340x_thermal/Makefile +++ b/drivers/thermal/int340x_thermal/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal_zone.o obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index 51ceb80212a7..c719167e9f28 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c @@ -228,7 +228,7 @@ static void get_single_name(acpi_handle handle, char *name) struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER}; if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer))) - pr_warn("Failed get name from handle\n"); + pr_warn("Failed to get device name from acpi handle\n"); else { memcpy(name, buffer.pointer, ACPI_NAME_SIZE); kfree(buffer.pointer); diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.h b/drivers/thermal/int340x_thermal/acpi_thermal_rel.h index f00700bc9d79..58822575fd54 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.h +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ACPI_ACPI_THERMAL_H #define __ACPI_ACPI_THERMAL_H @@ -34,10 +35,10 @@ struct trt { acpi_handle target; u64 influence; u64 sample_period; - u64 reverved1; - u64 reverved2; - u64 reverved3; - u64 reverved4; + u64 reserved1; + u64 reserved2; + u64 reserved3; + u64 reserved4; } __packed; #define ACPI_NR_ART_ELEMENTS 13 diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index a9ec94ed7a42..8ee38f55c7f3 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c @@ -16,6 +16,8 @@ #include #include "acpi_thermal_rel.h" +#define INT3400_THERMAL_TABLE_CHANGED 0x83 + enum int3400_thermal_uuid { INT3400_THERMAL_PASSIVE_1, INT3400_THERMAL_ACTIVE, @@ -104,7 +106,7 @@ static struct attribute *uuid_attrs[] = { NULL }; -static struct attribute_group uuid_attribute_group = { +static const struct attribute_group uuid_attribute_group = { .attrs = uuid_attrs, .name = "uuids" }; @@ -185,6 +187,35 @@ static int int3400_thermal_run_osc(acpi_handle handle, return result; } +static void int3400_notify(acpi_handle handle, + u32 event, + void *data) +{ + struct int3400_thermal_priv *priv = data; + char *thermal_prop[5]; + + if (!priv) + return; + + switch (event) { + case INT3400_THERMAL_TABLE_CHANGED: + thermal_prop[0] = kasprintf(GFP_KERNEL, "NAME=%s", + priv->thermal->type); + thermal_prop[1] = kasprintf(GFP_KERNEL, "TEMP=%d", + priv->thermal->temperature); + thermal_prop[2] = kasprintf(GFP_KERNEL, "TRIP="); + thermal_prop[3] = kasprintf(GFP_KERNEL, "EVENT=%d", + THERMAL_TABLE_CHANGED); + thermal_prop[4] = NULL; + kobject_uevent_env(&priv->thermal->device.kobj, KOBJ_CHANGE, + thermal_prop); + break; + default: + dev_err(&priv->adev->dev, "Unsupported event [0x%x]\n", event); + break; + } +} + static int int3400_thermal_get_temp(struct thermal_zone_device *thermal, int *temp) { @@ -290,6 +321,12 @@ static int int3400_thermal_probe(struct platform_device *pdev) if (result) goto free_zone; + result = acpi_install_notify_handler( + priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify, + (void *)priv); + if (result) + goto free_zone; + return 0; free_zone: @@ -306,6 +343,10 @@ static int int3400_thermal_remove(struct platform_device *pdev) { struct int3400_thermal_priv *priv = platform_get_drvdata(pdev); + acpi_remove_notify_handler( + priv->adev->handle, ACPI_DEVICE_NOTIFY, + int3400_notify); + if (!priv->rel_misc_dev_res) acpi_thermal_rel_misc_device_remove(priv->adev->handle); diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c b/drivers/thermal/int340x_thermal/int3406_thermal.c index 1891f34ab7fc..f69ab026ba24 100644 --- a/drivers/thermal/int340x_thermal/int3406_thermal.c +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c @@ -21,39 +21,33 @@ struct int3406_thermal_data { int upper_limit; - int upper_limit_index; int lower_limit; - int lower_limit_index; acpi_handle handle; struct acpi_video_device_brightness *br; struct backlight_device *raw_bd; struct thermal_cooling_device *cooling_dev; }; -static int int3406_thermal_to_raw(int level, struct int3406_thermal_data *d) -{ - int max_level = d->br->levels[d->br->count - 1]; - int raw_max = d->raw_bd->props.max_brightness; - - return level * raw_max / max_level; -} - -static int int3406_thermal_to_acpi(int level, struct int3406_thermal_data *d) -{ - int raw_max = d->raw_bd->props.max_brightness; - int max_level = d->br->levels[d->br->count - 1]; - - return level * max_level / raw_max; -} +/* + * According to the ACPI spec, + * "Each brightness level is represented by a number between 0 and 100, + * and can be thought of as a percentage. For example, 50 can be 50% + * power consumption or 50% brightness, as defined by the OEM." + * + * As int3406 device uses this value to communicate with the native + * graphics driver, we make the assumption that it represents + * the percentage of brightness only + */ +#define ACPI_TO_RAW(v, d) (d->raw_bd->props.max_brightness * v / 100) +#define RAW_TO_ACPI(v, d) (v * 100 / d->raw_bd->props.max_brightness) static int int3406_thermal_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct int3406_thermal_data *d = cooling_dev->devdata; - int index = d->lower_limit_index ? d->lower_limit_index : 2; - *state = d->br->count - 1 - index; + *state = d->upper_limit - d->lower_limit; return 0; } @@ -62,19 +56,15 @@ int3406_thermal_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) { struct int3406_thermal_data *d = cooling_dev->devdata; - int level, raw_level; + int acpi_level, raw_level; - if (state > d->br->count - 3) + if (state > d->upper_limit - d->lower_limit) return -EINVAL; - state = d->br->count - 1 - state; - level = d->br->levels[state]; + acpi_level = d->br->levels[d->upper_limit - state]; - if ((d->upper_limit && level > d->upper_limit) || - (d->lower_limit && level < d->lower_limit)) - return -EINVAL; + raw_level = ACPI_TO_RAW(acpi_level, d); - raw_level = int3406_thermal_to_raw(level, d); return backlight_device_set_brightness(d->raw_bd, raw_level); } @@ -83,27 +73,22 @@ int3406_thermal_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) { struct int3406_thermal_data *d = cooling_dev->devdata; - int raw_level, level, i; - int *levels = d->br->levels; + int acpi_level; + int index; - raw_level = d->raw_bd->props.brightness; - level = int3406_thermal_to_acpi(raw_level, d); + acpi_level = RAW_TO_ACPI(d->raw_bd->props.brightness, d); /* - * There is no 1:1 mapping between the firmware interface level with the - * raw interface level, we will have to find one that is close enough. + * There is no 1:1 mapping between the firmware interface level + * with the raw interface level, we will have to find one that is + * right above it. */ - for (i = 2; i < d->br->count; i++) { - if (level < levels[i]) { - if (i == 2) - break; - if ((level - levels[i - 1]) < (levels[i] - level)) - i--; + for (index = d->lower_limit; index < d->upper_limit; index++) { + if (acpi_level <= d->br->levels[index]) break; - } } - *state = d->br->count - 1 - i; + *state = d->upper_limit - index; return 0; } @@ -117,7 +102,7 @@ static int int3406_thermal_get_index(int *array, int nr, int value) { int i; - for (i = 0; i < nr; i++) { + for (i = 2; i < nr; i++) { if (array[i] == value) break; } @@ -128,27 +113,20 @@ static void int3406_thermal_get_limit(struct int3406_thermal_data *d) { acpi_status status; unsigned long long lower_limit, upper_limit; - int index; status = acpi_evaluate_integer(d->handle, "DDDL", NULL, &lower_limit); - if (ACPI_SUCCESS(status)) { - index = int3406_thermal_get_index(d->br->levels, d->br->count, - lower_limit); - if (index > 0) { - d->lower_limit = (int)lower_limit; - d->lower_limit_index = index; - } - } + if (ACPI_SUCCESS(status)) + d->lower_limit = int3406_thermal_get_index(d->br->levels, + d->br->count, lower_limit); status = acpi_evaluate_integer(d->handle, "DDPC", NULL, &upper_limit); - if (ACPI_SUCCESS(status)) { - index = int3406_thermal_get_index(d->br->levels, d->br->count, - upper_limit); - if (index > 0) { - d->upper_limit = (int)upper_limit; - d->upper_limit_index = index; - } - } + if (ACPI_SUCCESS(status)) + d->upper_limit = int3406_thermal_get_index(d->br->levels, + d->br->count, upper_limit); + + /* lower_limit and upper_limit should be always set */ + d->lower_limit = d->lower_limit > 0 ? d->lower_limit : 2; + d->upper_limit = d->upper_limit > 0 ? d->upper_limit : d->br->count - 1; } static void int3406_notify(acpi_handle handle, u32 event, void *data) diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c index ff3b36f339e3..f02341f7134d 100644 --- a/drivers/thermal/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c @@ -127,7 +127,7 @@ static struct attribute *power_limit_attrs[] = { NULL }; -static struct attribute_group power_limit_attribute_group = { +static const struct attribute_group power_limit_attribute_group = { .attrs = power_limit_attrs, .name = "power_limits" }; diff --git a/drivers/thermal/intel_pch_thermal.c b/drivers/thermal/intel_pch_thermal.c index 2b49e8d0fe9e..c60b1cfcc64e 100644 --- a/drivers/thermal/intel_pch_thermal.c +++ b/drivers/thermal/intel_pch_thermal.c @@ -49,7 +49,7 @@ #define WPT_TSGPEN 0x84 /* General Purpose Event Enables */ /* Wildcat Point-LP PCH Thermal Register bit definitions */ -#define WPT_TEMP_TSR 0x00ff /* Temp TS Reading */ +#define WPT_TEMP_TSR 0x01ff /* Temp TS Reading */ #define WPT_TSC_CPDE 0x01 /* Catastrophic Power-Down Enable */ #define WPT_TSS_TSDSS 0x10 /* Thermal Sensor Dynamic Shutdown Status */ #define WPT_TSS_GPES 0x08 /* GPE status */ @@ -125,7 +125,7 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) *nr_trips = 0; /* Check if BIOS has already enabled thermal sensor */ - if (WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS)) { + if (WPT_TSEL_ETS & readb(ptd->hw_base + WPT_TSEL)) { ptd->bios_enabled = true; goto read_trips; } @@ -141,7 +141,7 @@ static int pch_wpt_init(struct pch_thermal_device *ptd, int *nr_trips) } writeb(tsel|WPT_TSEL_ETS, ptd->hw_base + WPT_TSEL); - if (!(WPT_TSS_TSDSS & readb(ptd->hw_base + WPT_TSS))) { + if (!(WPT_TSEL_ETS & readb(ptd->hw_base + WPT_TSEL))) { dev_err(&ptd->pdev->dev, "Sensor can't be enabled\n"); return -ENODEV; } @@ -174,9 +174,9 @@ read_trips: static int pch_wpt_get_temp(struct pch_thermal_device *ptd, int *temp) { - u8 wpt_temp; + u16 wpt_temp; - wpt_temp = WPT_TEMP_TSR & readl(ptd->hw_base + WPT_TEMP); + wpt_temp = WPT_TEMP_TSR & readw(ptd->hw_base + WPT_TEMP); /* Resolution of 1/2 degree C and an offset of -50C */ *temp = (wpt_temp * 1000 / 2 - 50000); @@ -387,7 +387,7 @@ static int intel_pch_thermal_resume(struct device *device) return ptd->ops->resume(ptd); } -static struct pci_device_id intel_pch_thermal_id[] = { +static const struct pci_device_id intel_pch_thermal_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_1), .driver_data = board_hsw, }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCH_THERMAL_DID_HSW_2), diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c index 7737f14846f9..1e61c09153c9 100644 --- a/drivers/thermal/mtk_thermal.c +++ b/drivers/thermal/mtk_thermal.c @@ -3,6 +3,7 @@ * Author: Hanyi Wu * Sascha Hauer * Dawei Chien + * Louis Yu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -111,9 +112,10 @@ /* * Layout of the fuses providing the calibration data - * These macros could be used for both MT8173 and MT2701. - * MT8173 has five sensors and need five VTS calibration data, - * and MT2701 has three sensors and need three VTS calibration data. + * These macros could be used for MT8173, MT2701, and MT2712. + * MT8173 has 5 sensors and needs 5 VTS calibration data. + * MT2701 has 3 sensors and needs 3 VTS calibration data. + * MT2712 has 4 sensors and needs 4 VTS calibration data. */ #define MT8173_CALIB_BUF0_VALID BIT(0) #define MT8173_CALIB_BUF1_ADC_GE(x) (((x) >> 22) & 0x3ff) @@ -124,6 +126,8 @@ #define MT8173_CALIB_BUF2_VTS_TSABB(x) (((x) >> 14) & 0x1ff) #define MT8173_CALIB_BUF0_DEGC_CALI(x) (((x) >> 1) & 0x3f) #define MT8173_CALIB_BUF0_O_SLOPE(x) (((x) >> 26) & 0x3f) +#define MT8173_CALIB_BUF0_O_SLOPE_SIGN(x) (((x) >> 7) & 0x1) +#define MT8173_CALIB_BUF1_ID(x) (((x) >> 9) & 0x1) /* MT2701 thermal sensors */ #define MT2701_TS1 0 @@ -136,11 +140,26 @@ /* The total number of temperature sensors in the MT2701 */ #define MT2701_NUM_SENSORS 3 -#define THERMAL_NAME "mtk-thermal" - /* The number of sensing points per bank */ #define MT2701_NUM_SENSORS_PER_ZONE 3 +/* MT2712 thermal sensors */ +#define MT2712_TS1 0 +#define MT2712_TS2 1 +#define MT2712_TS3 2 +#define MT2712_TS4 3 + +/* AUXADC channel 11 is used for the temperature sensors */ +#define MT2712_TEMP_AUXADC_CHANNEL 11 + +/* The total number of temperature sensors in the MT2712 */ +#define MT2712_NUM_SENSORS 4 + +/* The number of sensing points per bank */ +#define MT2712_NUM_SENSORS_PER_ZONE 4 + +#define THERMAL_NAME "mtk-thermal" + struct mtk_thermal; struct thermal_bank_cfg { @@ -215,6 +234,21 @@ static const int mt2701_adcpnp[MT2701_NUM_SENSORS_PER_ZONE] = { static const int mt2701_mux_values[MT2701_NUM_SENSORS] = { 0, 1, 16 }; +/* MT2712 thermal sensor data */ +static const int mt2712_bank_data[MT2712_NUM_SENSORS] = { + MT2712_TS1, MT2712_TS2, MT2712_TS3, MT2712_TS4 +}; + +static const int mt2712_msr[MT2712_NUM_SENSORS_PER_ZONE] = { + TEMP_MSR0, TEMP_MSR1, TEMP_MSR2, TEMP_MSR3 +}; + +static const int mt2712_adcpnp[MT2712_NUM_SENSORS_PER_ZONE] = { + TEMP_ADCPNP0, TEMP_ADCPNP1, TEMP_ADCPNP2, TEMP_ADCPNP3 +}; + +static const int mt2712_mux_values[MT2712_NUM_SENSORS] = { 0, 1, 2, 3 }; + /** * The MT8173 thermal controller has four banks. Each bank can read up to * four temperature sensors simultaneously. The MT8173 has a total of 5 @@ -277,6 +311,31 @@ static const struct mtk_thermal_data mt2701_thermal_data = { .sensor_mux_values = mt2701_mux_values, }; +/** + * The MT2712 thermal controller has one bank, which can read up to + * four temperature sensors simultaneously. The MT2712 has a total of 4 + * temperature sensors. + * + * The thermal core only gets the maximum temperature of this one bank, + * so the bank concept wouldn't be necessary here. However, the SVS (Smart + * Voltage Scaling) unit makes its decisions based on the same bank + * data. + */ +static const struct mtk_thermal_data mt2712_thermal_data = { + .auxadc_channel = MT2712_TEMP_AUXADC_CHANNEL, + .num_banks = 1, + .num_sensors = MT2712_NUM_SENSORS, + .bank_data = { + { + .num_sensors = 4, + .sensors = mt2712_bank_data, + }, + }, + .msr = mt2712_msr, + .adcpnp = mt2712_adcpnp, + .sensor_mux_values = mt2712_mux_values, +}; + /** * raw_to_mcelsius - convert a raw ADC value to mcelsius * @mt: The thermal controller @@ -552,7 +611,11 @@ static int mtk_thermal_get_calibration_data(struct device *dev, mt->vts[MT8173_TS4] = MT8173_CALIB_BUF2_VTS_TS4(buf[2]); mt->vts[MT8173_TSABB] = MT8173_CALIB_BUF2_VTS_TSABB(buf[2]); mt->degc_cali = MT8173_CALIB_BUF0_DEGC_CALI(buf[0]); - mt->o_slope = MT8173_CALIB_BUF0_O_SLOPE(buf[0]); + if (MT8173_CALIB_BUF1_ID(buf[1]) & + MT8173_CALIB_BUF0_O_SLOPE_SIGN(buf[0])) + mt->o_slope = -MT8173_CALIB_BUF0_O_SLOPE(buf[0]); + else + mt->o_slope = MT8173_CALIB_BUF0_O_SLOPE(buf[0]); } else { dev_info(dev, "Device not calibrated, using default calibration values\n"); } @@ -571,6 +634,10 @@ static const struct of_device_id mtk_thermal_of_match[] = { { .compatible = "mediatek,mt2701-thermal", .data = (void *)&mt2701_thermal_data, + }, + { + .compatible = "mediatek,mt2712-thermal", + .data = (void *)&mt2712_thermal_data, }, { }, }; @@ -645,16 +712,16 @@ static int mtk_thermal_probe(struct platform_device *pdev) return -EINVAL; } + ret = device_reset(&pdev->dev); + if (ret) + return ret; + ret = clk_prepare_enable(mt->clk_auxadc); if (ret) { dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret); return ret; } - ret = device_reset(&pdev->dev); - if (ret) - goto err_disable_clk_auxadc; - ret = clk_prepare_enable(mt->clk_peri_therm); if (ret) { dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret); @@ -705,6 +772,7 @@ static struct platform_driver mtk_thermal_driver = { module_platform_driver(mtk_thermal_driver); +MODULE_AUTHOR("Louis Yu "); MODULE_AUTHOR("Dawei Chien "); MODULE_AUTHOR("Sascha Hauer "); MODULE_AUTHOR("Hanyi Wu "); diff --git a/drivers/thermal/qoriq_thermal.c b/drivers/thermal/qoriq_thermal.c index 4362a69ac88d..c866cc165960 100644 --- a/drivers/thermal/qoriq_thermal.c +++ b/drivers/thermal/qoriq_thermal.c @@ -188,7 +188,7 @@ static void qoriq_tmu_init_device(struct qoriq_tmu_data *data) tmu_write(data, TMR_DISABLE, &data->regs->tmr); } -static struct thermal_zone_of_device_ops tmu_tz_ops = { +static const struct thermal_zone_of_device_ops tmu_tz_ops = { .get_temp = tmu_get_temp, }; diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c index 37fcefd06d9f..203aca44a2bb 100644 --- a/drivers/thermal/rcar_gen3_thermal.c +++ b/drivers/thermal/rcar_gen3_thermal.c @@ -225,7 +225,7 @@ static int rcar_gen3_thermal_set_trips(void *devdata, int low, int high) return 0; } -static struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = { +static const struct thermal_zone_of_device_ops rcar_gen3_tz_of_ops = { .get_temp = rcar_gen3_thermal_get_temp, .set_trips = rcar_gen3_thermal_set_trips, }; diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 4c7796512453..206035139110 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -320,6 +320,44 @@ static const struct tsadc_table rk3288_code_table[] = { {0, 125000}, }; +static const struct tsadc_table rk3328_code_table[] = { + {0, -40000}, + {296, -40000}, + {304, -35000}, + {313, -30000}, + {331, -20000}, + {340, -15000}, + {349, -10000}, + {359, -5000}, + {368, 0}, + {378, 5000}, + {388, 10000}, + {398, 15000}, + {408, 20000}, + {418, 25000}, + {429, 30000}, + {440, 35000}, + {451, 40000}, + {462, 45000}, + {473, 50000}, + {485, 55000}, + {496, 60000}, + {508, 65000}, + {521, 70000}, + {533, 75000}, + {546, 80000}, + {559, 85000}, + {572, 90000}, + {586, 95000}, + {600, 100000}, + {614, 105000}, + {629, 110000}, + {644, 115000}, + {659, 120000}, + {675, 125000}, + {TSADCV2_DATA_MASK, 125000}, +}; + static const struct tsadc_table rk3368_code_table[] = { {0, -40000}, {106, -40000}, @@ -790,6 +828,29 @@ static const struct rockchip_tsadc_chip rk3288_tsadc_data = { }, }; +static const struct rockchip_tsadc_chip rk3328_tsadc_data = { + .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + .chn_num = 1, /* one channels for tsadc */ + + .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = { + .id = rk3328_code_table, + .length = ARRAY_SIZE(rk3328_code_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + static const struct rockchip_tsadc_chip rk3366_tsadc_data = { .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ @@ -874,6 +935,10 @@ static const struct of_device_id of_rockchip_thermal_match[] = { .compatible = "rockchip,rk3288-tsadc", .data = (void *)&rk3288_tsadc_data, }, + { + .compatible = "rockchip,rk3328-tsadc", + .data = (void *)&rk3328_tsadc_data, + }, { .compatible = "rockchip,rk3366-tsadc", .data = (void *)&rk3366_tsadc_data, diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 7b8ef09d2b3c..ed805c7c5ace 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -1286,7 +1286,7 @@ static int exynos_map_dt_data(struct platform_device *pdev) return 0; } -static struct thermal_zone_of_device_ops exynos_sensor_ops = { +static const struct thermal_zone_of_device_ops exynos_sensor_ops = { .get_temp = exynos_get_temp, .set_emul_temp = exynos_tmu_set_emulation, }; diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile index 1ce1af2cf0f5..8a3f221f17c1 100644 --- a/drivers/thermal/tegra/Makefile +++ b/drivers/thermal/tegra/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TEGRA_SOCTHERM) += tegra-soctherm.o tegra-soctherm-y := soctherm.o soctherm-fuse.o diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 5a51c740e372..2b1b0ba393a4 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -390,7 +390,7 @@ static void handle_critical_trips(struct thermal_zone_device *tz, if (trip_type == THERMAL_TRIP_CRITICAL) { dev_emerg(&tz->device, - "critical temperature reached(%d C),shutting down\n", + "critical temperature reached (%d C), shutting down\n", tz->temperature / 1000); mutex_lock(&poweroff_lock); if (!power_off_triggered) { @@ -836,11 +836,7 @@ static void thermal_release(struct device *dev) if (!strncmp(dev_name(dev), "thermal_zone", sizeof("thermal_zone") - 1)) { tz = to_thermal_zone(dev); - kfree(tz->trip_type_attrs); - kfree(tz->trip_temp_attrs); - kfree(tz->trip_hyst_attrs); - kfree(tz->trips_attribute_group.attrs); - kfree(tz->device.groups); + thermal_zone_destroy_device_groups(tz); kfree(tz); } else if (!strncmp(dev_name(dev), "cooling_device", sizeof("cooling_device") - 1)) { @@ -1213,10 +1209,8 @@ thermal_zone_device_register(const char *type, int trips, int mask, ida_init(&tz->ida); mutex_init(&tz->lock); result = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL); - if (result < 0) { - kfree(tz); - return ERR_PTR(result); - } + if (result < 0) + goto free_tz; tz->id = result; strlcpy(tz->type, type, sizeof(tz->type)); @@ -1232,18 +1226,15 @@ thermal_zone_device_register(const char *type, int trips, int mask, /* Add nodes that are always present via .groups */ result = thermal_zone_create_device_groups(tz, mask); if (result) - goto unregister; + goto remove_id; /* A new thermal zone needs to be updated anyway. */ atomic_set(&tz->need_update, 1); dev_set_name(&tz->device, "thermal_zone%d", tz->id); result = device_register(&tz->device); - if (result) { - ida_simple_remove(&thermal_tz_ida, tz->id); - kfree(tz); - return ERR_PTR(result); - } + if (result) + goto remove_device_groups; for (count = 0; count < trips; count++) { if (tz->ops->get_trip_type(tz, count, &trip_type)) @@ -1297,6 +1288,14 @@ unregister: ida_simple_remove(&thermal_tz_ida, tz->id); device_unregister(&tz->device); return ERR_PTR(result); + +remove_device_groups: + thermal_zone_destroy_device_groups(tz); +remove_id: + ida_simple_remove(&thermal_tz_ida, tz->id); +free_tz: + kfree(tz); + return ERR_PTR(result); } EXPORT_SYMBOL_GPL(thermal_zone_device_register); diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 2412b3759e16..27e3b1df7360 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h @@ -71,6 +71,7 @@ int thermal_build_list_of_policies(char *buf); /* sysfs I/F */ int thermal_zone_create_device_groups(struct thermal_zone_device *, int); +void thermal_zone_destroy_device_groups(struct thermal_zone_device *); void thermal_cooling_device_setup_sysfs(struct thermal_cooling_device *); /* used only at binding time */ ssize_t diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index a694de907a26..fb80c96d8f73 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -605,6 +605,24 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask) return 0; } +/** + * destroy_trip_attrs() - destroy attributes for trip points + * @tz: the thermal zone device + * + * helper function to free resources allocated by create_trip_attrs() + */ +static void destroy_trip_attrs(struct thermal_zone_device *tz) +{ + if (!tz) + return; + + kfree(tz->trip_type_attrs); + kfree(tz->trip_temp_attrs); + if (tz->ops->get_trip_hyst) + kfree(tz->trip_hyst_attrs); + kfree(tz->trips_attribute_group.attrs); +} + int thermal_zone_create_device_groups(struct thermal_zone_device *tz, int mask) { @@ -637,6 +655,17 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *tz, return 0; } +void thermal_zone_destroy_device_groups(struct thermal_zone_device *tz) +{ + if (!tz) + return; + + if (tz->trips) + destroy_trip_attrs(tz); + + kfree(tz->device.groups); +} + /* sys I/F for cooling device */ static ssize_t thermal_cooling_device_type_show(struct device *dev, diff --git a/drivers/thermal/ti-soc-thermal/Makefile b/drivers/thermal/ti-soc-thermal/Makefile index 0f89bdf03790..f180ebead858 100644 --- a/drivers/thermal/ti-soc-thermal/Makefile +++ b/drivers/thermal/ti-soc-thermal/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal.o ti-soc-thermal-y := ti-bandgap.o ti-soc-thermal-$(CONFIG_TI_THERMAL) += ti-thermal-common.o diff --git a/drivers/thermal/uniphier_thermal.c b/drivers/thermal/uniphier_thermal.c new file mode 100644 index 000000000000..95704732f760 --- /dev/null +++ b/drivers/thermal/uniphier_thermal.c @@ -0,0 +1,384 @@ +/** + * uniphier_thermal.c - Socionext UniPhier thermal driver + * + * Copyright 2014 Panasonic Corporation + * Copyright 2016-2017 Socionext Inc. + * All rights reserved. + * + * Author: + * Kunihiko Hayashi + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "thermal_core.h" + +/* + * block registers + * addresses are the offset from .block_base + */ +#define PVTCTLEN 0x0000 +#define PVTCTLEN_EN BIT(0) + +#define PVTCTLMODE 0x0004 +#define PVTCTLMODE_MASK 0xf +#define PVTCTLMODE_TEMPMON 0x5 + +#define EMONREPEAT 0x0040 +#define EMONREPEAT_ENDLESS BIT(24) +#define EMONREPEAT_PERIOD GENMASK(3, 0) +#define EMONREPEAT_PERIOD_1000000 0x9 + +/* + * common registers + * addresses are the offset from .map_base + */ +#define PVTCTLSEL 0x0900 +#define PVTCTLSEL_MASK GENMASK(2, 0) +#define PVTCTLSEL_MONITOR 0 + +#define SETALERT0 0x0910 +#define SETALERT1 0x0914 +#define SETALERT2 0x0918 +#define SETALERT_TEMP_OVF (GENMASK(7, 0) << 16) +#define SETALERT_TEMP_OVF_VALUE(val) (((val) & GENMASK(7, 0)) << 16) +#define SETALERT_EN BIT(0) + +#define PMALERTINTCTL 0x0920 +#define PMALERTINTCTL_CLR(ch) BIT(4 * (ch) + 2) +#define PMALERTINTCTL_SET(ch) BIT(4 * (ch) + 1) +#define PMALERTINTCTL_EN(ch) BIT(4 * (ch) + 0) +#define PMALERTINTCTL_MASK (GENMASK(10, 8) | GENMASK(6, 4) | \ + GENMASK(2, 0)) + +#define TMOD 0x0928 +#define TMOD_WIDTH 9 + +#define TMODCOEF 0x0e5c + +#define TMODSETUP0_EN BIT(30) +#define TMODSETUP0_VAL(val) (((val) & GENMASK(13, 0)) << 16) +#define TMODSETUP1_EN BIT(15) +#define TMODSETUP1_VAL(val) ((val) & GENMASK(14, 0)) + +/* SoC critical temperature */ +#define CRITICAL_TEMP_LIMIT (120 * 1000) + +/* Max # of alert channels */ +#define ALERT_CH_NUM 3 + +/* SoC specific thermal sensor data */ +struct uniphier_tm_soc_data { + u32 map_base; + u32 block_base; + u32 tmod_setup_addr; +}; + +struct uniphier_tm_dev { + struct regmap *regmap; + struct device *dev; + bool alert_en[ALERT_CH_NUM]; + struct thermal_zone_device *tz_dev; + const struct uniphier_tm_soc_data *data; +}; + +static int uniphier_tm_initialize_sensor(struct uniphier_tm_dev *tdev) +{ + struct regmap *map = tdev->regmap; + u32 val; + u32 tmod_calib[2]; + int ret; + + /* stop PVT */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLEN, + PVTCTLEN_EN, 0); + + /* + * Since SoC has a calibrated value that was set in advance, + * TMODCOEF shows non-zero and PVT refers the value internally. + * + * If TMODCOEF shows zero, the boards don't have the calibrated + * value, and the driver has to set default value from DT. + */ + ret = regmap_read(map, tdev->data->map_base + TMODCOEF, &val); + if (ret) + return ret; + if (!val) { + /* look for the default values in DT */ + ret = of_property_read_u32_array(tdev->dev->of_node, + "socionext,tmod-calibration", + tmod_calib, + ARRAY_SIZE(tmod_calib)); + if (ret) + return ret; + + regmap_write(map, tdev->data->tmod_setup_addr, + TMODSETUP0_EN | TMODSETUP0_VAL(tmod_calib[0]) | + TMODSETUP1_EN | TMODSETUP1_VAL(tmod_calib[1])); + } + + /* select temperature mode */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLMODE, + PVTCTLMODE_MASK, PVTCTLMODE_TEMPMON); + + /* set monitoring period */ + regmap_write_bits(map, tdev->data->block_base + EMONREPEAT, + EMONREPEAT_ENDLESS | EMONREPEAT_PERIOD, + EMONREPEAT_ENDLESS | EMONREPEAT_PERIOD_1000000); + + /* set monitor mode */ + regmap_write_bits(map, tdev->data->map_base + PVTCTLSEL, + PVTCTLSEL_MASK, PVTCTLSEL_MONITOR); + + return 0; +} + +static void uniphier_tm_set_alert(struct uniphier_tm_dev *tdev, u32 ch, + u32 temp) +{ + struct regmap *map = tdev->regmap; + + /* set alert temperature */ + regmap_write_bits(map, tdev->data->map_base + SETALERT0 + (ch << 2), + SETALERT_EN | SETALERT_TEMP_OVF, + SETALERT_EN | + SETALERT_TEMP_OVF_VALUE(temp / 1000)); +} + +static void uniphier_tm_enable_sensor(struct uniphier_tm_dev *tdev) +{ + struct regmap *map = tdev->regmap; + int i; + u32 bits = 0; + + for (i = 0; i < ALERT_CH_NUM; i++) + if (tdev->alert_en[i]) + bits |= PMALERTINTCTL_EN(i); + + /* enable alert interrupt */ + regmap_write_bits(map, tdev->data->map_base + PMALERTINTCTL, + PMALERTINTCTL_MASK, bits); + + /* start PVT */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLEN, + PVTCTLEN_EN, PVTCTLEN_EN); + + usleep_range(700, 1500); /* The spec note says at least 700us */ +} + +static void uniphier_tm_disable_sensor(struct uniphier_tm_dev *tdev) +{ + struct regmap *map = tdev->regmap; + + /* disable alert interrupt */ + regmap_write_bits(map, tdev->data->map_base + PMALERTINTCTL, + PMALERTINTCTL_MASK, 0); + + /* stop PVT */ + regmap_write_bits(map, tdev->data->block_base + PVTCTLEN, + PVTCTLEN_EN, 0); + + usleep_range(1000, 2000); /* The spec note says at least 1ms */ +} + +static int uniphier_tm_get_temp(void *data, int *out_temp) +{ + struct uniphier_tm_dev *tdev = data; + struct regmap *map = tdev->regmap; + int ret; + u32 temp; + + ret = regmap_read(map, tdev->data->map_base + TMOD, &temp); + if (ret) + return ret; + + /* MSB of the TMOD field is a sign bit */ + *out_temp = sign_extend32(temp, TMOD_WIDTH - 1) * 1000; + + return 0; +} + +static const struct thermal_zone_of_device_ops uniphier_of_thermal_ops = { + .get_temp = uniphier_tm_get_temp, +}; + +static void uniphier_tm_irq_clear(struct uniphier_tm_dev *tdev) +{ + u32 mask = 0, bits = 0; + int i; + + for (i = 0; i < ALERT_CH_NUM; i++) { + mask |= (PMALERTINTCTL_CLR(i) | PMALERTINTCTL_SET(i)); + bits |= PMALERTINTCTL_CLR(i); + } + + /* clear alert interrupt */ + regmap_write_bits(tdev->regmap, + tdev->data->map_base + PMALERTINTCTL, mask, bits); +} + +static irqreturn_t uniphier_tm_alarm_irq(int irq, void *_tdev) +{ + struct uniphier_tm_dev *tdev = _tdev; + + disable_irq_nosync(irq); + uniphier_tm_irq_clear(tdev); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t uniphier_tm_alarm_irq_thread(int irq, void *_tdev) +{ + struct uniphier_tm_dev *tdev = _tdev; + + thermal_zone_device_update(tdev->tz_dev, THERMAL_EVENT_UNSPECIFIED); + + return IRQ_HANDLED; +} + +static int uniphier_tm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regmap *regmap; + struct device_node *parent; + struct uniphier_tm_dev *tdev; + const struct thermal_trip *trips; + int i, ret, irq, ntrips, crit_temp = INT_MAX; + + tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL); + if (!tdev) + return -ENOMEM; + tdev->dev = dev; + + tdev->data = of_device_get_match_data(dev); + if (WARN_ON(!tdev->data)) + return -EINVAL; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + /* get regmap from syscon node */ + parent = of_get_parent(dev->of_node); /* parent should be syscon node */ + regmap = syscon_node_to_regmap(parent); + of_node_put(parent); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to get regmap (error %ld)\n", + PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + tdev->regmap = regmap; + + ret = uniphier_tm_initialize_sensor(tdev); + if (ret) { + dev_err(dev, "failed to initialize sensor\n"); + return ret; + } + + ret = devm_request_threaded_irq(dev, irq, uniphier_tm_alarm_irq, + uniphier_tm_alarm_irq_thread, + 0, "thermal", tdev); + if (ret) + return ret; + + platform_set_drvdata(pdev, tdev); + + tdev->tz_dev = devm_thermal_zone_of_sensor_register(dev, 0, tdev, + &uniphier_of_thermal_ops); + if (IS_ERR(tdev->tz_dev)) { + dev_err(dev, "failed to register sensor device\n"); + return PTR_ERR(tdev->tz_dev); + } + + /* get trip points */ + trips = of_thermal_get_trip_points(tdev->tz_dev); + ntrips = of_thermal_get_ntrips(tdev->tz_dev); + if (ntrips > ALERT_CH_NUM) { + dev_err(dev, "thermal zone has too many trips\n"); + return -E2BIG; + } + + /* set alert temperatures */ + for (i = 0; i < ntrips; i++) { + if (trips[i].type == THERMAL_TRIP_CRITICAL && + trips[i].temperature < crit_temp) + crit_temp = trips[i].temperature; + uniphier_tm_set_alert(tdev, i, trips[i].temperature); + tdev->alert_en[i] = true; + } + if (crit_temp > CRITICAL_TEMP_LIMIT) { + dev_err(dev, "critical trip is over limit(>%d), or not set\n", + CRITICAL_TEMP_LIMIT); + return -EINVAL; + } + + uniphier_tm_enable_sensor(tdev); + + return 0; +} + +static int uniphier_tm_remove(struct platform_device *pdev) +{ + struct uniphier_tm_dev *tdev = platform_get_drvdata(pdev); + + /* disable sensor */ + uniphier_tm_disable_sensor(tdev); + + return 0; +} + +static const struct uniphier_tm_soc_data uniphier_pxs2_tm_data = { + .map_base = 0xe000, + .block_base = 0xe000, + .tmod_setup_addr = 0xe904, +}; + +static const struct uniphier_tm_soc_data uniphier_ld20_tm_data = { + .map_base = 0xe000, + .block_base = 0xe800, + .tmod_setup_addr = 0xe938, +}; + +static const struct of_device_id uniphier_tm_dt_ids[] = { + { + .compatible = "socionext,uniphier-pxs2-thermal", + .data = &uniphier_pxs2_tm_data, + }, + { + .compatible = "socionext,uniphier-ld20-thermal", + .data = &uniphier_ld20_tm_data, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, uniphier_tm_dt_ids); + +static struct platform_driver uniphier_tm_driver = { + .probe = uniphier_tm_probe, + .remove = uniphier_tm_remove, + .driver = { + .name = "uniphier-thermal", + .of_match_table = uniphier_tm_dt_ids, + }, +}; +module_platform_driver(uniphier_tm_driver); + +MODULE_AUTHOR("Kunihiko Hayashi "); +MODULE_DESCRIPTION("UniPhier thermal driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/thermal/zx2967_thermal.c b/drivers/thermal/zx2967_thermal.c index a5670ad2cfc8..6acce0bce7c0 100644 --- a/drivers/thermal/zx2967_thermal.c +++ b/drivers/thermal/zx2967_thermal.c @@ -111,7 +111,7 @@ unlock: return ret; } -static struct thermal_zone_of_device_ops zx2967_of_thermal_ops = { +static const struct thermal_zone_of_device_ops zx2967_of_thermal_ops = { .get_temp = zx2967_thermal_get_temp, }; diff --git a/drivers/thunderbolt/cap.c b/drivers/thunderbolt/cap.c index 38bc27a5ce4f..c2277b8ee88d 100644 --- a/drivers/thunderbolt/cap.c +++ b/drivers/thunderbolt/cap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt Cactus Ridge driver - capabilities lookup * diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c index 69c0232a22f8..423ae231fc6c 100644 --- a/drivers/thunderbolt/ctl.c +++ b/drivers/thunderbolt/ctl.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt Cactus Ridge driver - control channel and configuration commands * @@ -804,7 +805,7 @@ struct tb_cfg_result tb_cfg_reset(struct tb_ctl *ctl, u64 route, req->request_type = TB_CFG_PKG_RESET; req->response = &reply; req->response_size = sizeof(reply); - req->response_type = sizeof(TB_CFG_PKG_RESET); + req->response_type = TB_CFG_PKG_RESET; res = tb_cfg_request_sync(ctl, req, timeout_msec); diff --git a/drivers/thunderbolt/ctl.h b/drivers/thunderbolt/ctl.h index 36fd28b1c1c5..dd34f627ce49 100644 --- a/drivers/thunderbolt/ctl.h +++ b/drivers/thunderbolt/ctl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Thunderbolt Cactus Ridge driver - control channel and configuration commands * diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c index fe2f00ceafc5..3e8caf22c294 100644 --- a/drivers/thunderbolt/eeprom.c +++ b/drivers/thunderbolt/eeprom.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt Cactus Ridge driver - eeprom access * diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c index bdaac1ff00a5..53250fc057e1 100644 --- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -13,9 +13,9 @@ */ #include -#include #include #include +#include #include #include #include @@ -102,11 +102,6 @@ static inline u64 get_route(u32 route_hi, u32 route_lo) return (u64)route_hi << 32 | route_lo; } -static inline bool is_apple(void) -{ - return dmi_match(DMI_BOARD_VENDOR, "Apple Inc."); -} - static bool icm_match(const struct tb_cfg_request *req, const struct ctl_pkg *pkg) { @@ -176,7 +171,7 @@ static int icm_request(struct tb *tb, const void *request, size_t request_size, static bool icm_fr_is_supported(struct tb *tb) { - return !is_apple(); + return !x86_apple_machine; } static inline int icm_fr_get_switch_index(u32 port) @@ -517,7 +512,7 @@ static bool icm_ar_is_supported(struct tb *tb) * Starting from Alpine Ridge we can use ICM on Apple machines * as well. We just need to reset and re-enable it first. */ - if (!is_apple()) + if (!x86_apple_machine) return true; /* @@ -1011,7 +1006,7 @@ static int icm_start(struct tb *tb) * don't provide images publicly either. To be on the safe side * prevent root switch NVM upgrade on Macs for now. */ - tb->root_switch->no_nvm_upgrade = is_apple(); + tb->root_switch->no_nvm_upgrade = x86_apple_machine; ret = tb_switch_add(tb->root_switch); if (ret) diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h index 5b5bb2c436be..1c7e6b92e235 100644 --- a/drivers/thunderbolt/nhi.h +++ b/drivers/thunderbolt/nhi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Thunderbolt Cactus Ridge driver - NHI driver * diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h index 09ed574e92ff..752ec04305f3 100644 --- a/drivers/thunderbolt/nhi_regs.h +++ b/drivers/thunderbolt/nhi_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Thunderbolt driver - NHI registers * diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index 9562cd026dc0..ff49ad880bfd 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt Cactus Ridge driver - path/tunnel functionality * diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index e9391bbd4036..3953d17202a8 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt Cactus Ridge driver - switch/port utility functions * @@ -807,11 +808,11 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr, struct tb_switch *sw = tb_to_switch(dev); u8 key[TB_SWITCH_KEY_SIZE]; ssize_t ret = count; + bool clear = false; - if (count < 64) - return -EINVAL; - - if (hex2bin(key, buf, sizeof(key))) + if (!strcmp(buf, "\n")) + clear = true; + else if (hex2bin(key, buf, sizeof(key))) return -EINVAL; if (mutex_lock_interruptible(&switch_lock)) @@ -821,15 +822,19 @@ static ssize_t key_store(struct device *dev, struct device_attribute *attr, ret = -EBUSY; } else { kfree(sw->key); - sw->key = kmemdup(key, sizeof(key), GFP_KERNEL); - if (!sw->key) - ret = -ENOMEM; + if (clear) { + sw->key = NULL; + } else { + sw->key = kmemdup(key, sizeof(key), GFP_KERNEL); + if (!sw->key) + ret = -ENOMEM; + } } mutex_unlock(&switch_lock); return ret; } -static DEVICE_ATTR_RW(key); +static DEVICE_ATTR(key, 0600, key_show, key_store); static ssize_t nvm_authenticate_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 1b02ca0b6129..d674e06767a5 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt Cactus Ridge driver - bus logic (NHI independent) * @@ -7,7 +8,7 @@ #include #include #include -#include +#include #include "tb.h" #include "tb_regs.h" @@ -453,7 +454,7 @@ struct tb *tb_probe(struct tb_nhi *nhi) struct tb_cm *tcm; struct tb *tb; - if (!dmi_match(DMI_BOARD_VENDOR, "Apple Inc.")) + if (!x86_apple_machine) return NULL; tb = tb_domain_alloc(nhi, sizeof(*tcm)); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index e0deee4f1eb0..d7ffc159bcf7 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Thunderbolt Cactus Ridge driver - bus logic (NHI independent) * diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h index 582bd1f156dc..5d94142afda6 100644 --- a/drivers/thunderbolt/tb_regs.h +++ b/drivers/thunderbolt/tb_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Thunderbolt Cactus Ridge driver - Port/Switch config area registers * diff --git a/drivers/thunderbolt/tunnel_pci.c b/drivers/thunderbolt/tunnel_pci.c index ca4475907d7a..0637537ea53f 100644 --- a/drivers/thunderbolt/tunnel_pci.c +++ b/drivers/thunderbolt/tunnel_pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Thunderbolt Cactus Ridge driver - PCIe tunnel * diff --git a/drivers/thunderbolt/tunnel_pci.h b/drivers/thunderbolt/tunnel_pci.h index a67f93c140fa..f9b65fa1fd4d 100644 --- a/drivers/thunderbolt/tunnel_pci.h +++ b/drivers/thunderbolt/tunnel_pci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Thunderbolt Cactus Ridge driver - PCIe tunnel * diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index 95103054c0e4..cc2b4d9433ed 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -392,6 +392,9 @@ config PPC_EARLY_DEBUG_EHV_BC_HANDLE config GOLDFISH_TTY tristate "Goldfish TTY Driver" depends on GOLDFISH + select SERIAL_CORE + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON help Console and system TTY driver for the Goldfish virtual platform. @@ -455,4 +458,9 @@ config MIPS_EJTAG_FDC_KGDB_CHAN help FDC channel number to use for KGDB. +config VCC + tristate "Sun Virtual Console Concentrator" + depends on SUN_LDOMS + help + Support for Sun logical domain consoles. endif # TTY diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 8689279afdf1..8ce3a8661b31 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TTY) += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \ tty_buffer.o tty_port.o tty_mutex.o \ tty_ldsem.o tty_baudrate.o tty_jobctrl.o \ @@ -33,5 +34,6 @@ obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o obj-$(CONFIG_DA_TTY) += metag_da.o obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o +obj-$(CONFIG_VCC) += vcc.o obj-y += ipwireless/ diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 61fe8d6fd24e..a1c7125cb968 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -122,7 +122,7 @@ static int find_console_handle(void) stdout_irq = irq_of_parse_and_map(np, 0); if (stdout_irq == NO_IRQ) { - pr_err("ehv-bc: no 'interrupts' property in %s node\n", np->full_name); + pr_err("ehv-bc: no 'interrupts' property in %pOF node\n", np); return 0; } diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 996bd473dd03..381e981dee06 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2007 Google, Inc. * Copyright (C) 2012 Intel, Inc. + * Copyright (C) 2017 Imagination Technologies Ltd. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -22,21 +23,23 @@ #include #include #include +#include +#include +#include -enum { - GOLDFISH_TTY_PUT_CHAR = 0x00, - GOLDFISH_TTY_BYTES_READY = 0x04, - GOLDFISH_TTY_CMD = 0x08, +/* Goldfish tty register's offsets */ +#define GOLDFISH_TTY_REG_BYTES_READY 0x04 +#define GOLDFISH_TTY_REG_CMD 0x08 +#define GOLDFISH_TTY_REG_DATA_PTR 0x10 +#define GOLDFISH_TTY_REG_DATA_LEN 0x14 +#define GOLDFISH_TTY_REG_DATA_PTR_HIGH 0x18 +#define GOLDFISH_TTY_REG_VERSION 0x20 - GOLDFISH_TTY_DATA_PTR = 0x10, - GOLDFISH_TTY_DATA_LEN = 0x14, - GOLDFISH_TTY_DATA_PTR_HIGH = 0x18, - - GOLDFISH_TTY_CMD_INT_DISABLE = 0, - GOLDFISH_TTY_CMD_INT_ENABLE = 1, - GOLDFISH_TTY_CMD_WRITE_BUFFER = 2, - GOLDFISH_TTY_CMD_READ_BUFFER = 3, -}; +/* Goldfish tty commands */ +#define GOLDFISH_TTY_CMD_INT_DISABLE 0 +#define GOLDFISH_TTY_CMD_INT_ENABLE 1 +#define GOLDFISH_TTY_CMD_WRITE_BUFFER 2 +#define GOLDFISH_TTY_CMD_READ_BUFFER 3 struct goldfish_tty { struct tty_port port; @@ -45,6 +48,8 @@ struct goldfish_tty { u32 irq; int opencount; struct console console; + u32 version; + struct device *dev; }; static DEFINE_MUTEX(goldfish_tty_lock); @@ -53,38 +58,107 @@ static u32 goldfish_tty_line_count = 8; static u32 goldfish_tty_current_line_count; static struct goldfish_tty *goldfish_ttys; -static void goldfish_tty_do_write(int line, const char *buf, unsigned count) +static void do_rw_io(struct goldfish_tty *qtty, + unsigned long address, + unsigned int count, + int is_write) { unsigned long irq_flags; - struct goldfish_tty *qtty = &goldfish_ttys[line]; void __iomem *base = qtty->base; + spin_lock_irqsave(&qtty->lock, irq_flags); - gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR, - base + GOLDFISH_TTY_DATA_PTR_HIGH); - writel(count, base + GOLDFISH_TTY_DATA_LEN); - writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, base + GOLDFISH_TTY_CMD); + gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR, + base + GOLDFISH_TTY_REG_DATA_PTR_HIGH); + writel(count, base + GOLDFISH_TTY_REG_DATA_LEN); + + if (is_write) + writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, + base + GOLDFISH_TTY_REG_CMD); + else + writel(GOLDFISH_TTY_CMD_READ_BUFFER, + base + GOLDFISH_TTY_REG_CMD); + spin_unlock_irqrestore(&qtty->lock, irq_flags); } +static void goldfish_tty_rw(struct goldfish_tty *qtty, + unsigned long addr, + unsigned int count, + int is_write) +{ + dma_addr_t dma_handle; + enum dma_data_direction dma_dir; + + dma_dir = (is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + if (qtty->version > 0) { + /* + * Goldfish TTY for Ranchu platform uses + * physical addresses and DMA for read/write operations + */ + unsigned long addr_end = addr + count; + + while (addr < addr_end) { + unsigned long pg_end = (addr & PAGE_MASK) + PAGE_SIZE; + unsigned long next = + pg_end < addr_end ? pg_end : addr_end; + unsigned long avail = next - addr; + + /* + * Map the buffer's virtual address to the DMA address + * so the buffer can be accessed by the device. + */ + dma_handle = dma_map_single(qtty->dev, (void *)addr, + avail, dma_dir); + + if (dma_mapping_error(qtty->dev, dma_handle)) { + dev_err(qtty->dev, "tty: DMA mapping error.\n"); + return; + } + do_rw_io(qtty, dma_handle, avail, is_write); + + /* + * Unmap the previously mapped region after + * the completion of the read/write operation. + */ + dma_unmap_single(qtty->dev, dma_handle, avail, dma_dir); + + addr += avail; + } + } else { + /* + * Old style Goldfish TTY used on the Goldfish platform + * uses virtual addresses. + */ + do_rw_io(qtty, addr, count, is_write); + } +} + +static void goldfish_tty_do_write(int line, const char *buf, + unsigned int count) +{ + struct goldfish_tty *qtty = &goldfish_ttys[line]; + unsigned long address = (unsigned long)(void *)buf; + + goldfish_tty_rw(qtty, address, count, 1); +} + static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) { struct goldfish_tty *qtty = dev_id; void __iomem *base = qtty->base; - unsigned long irq_flags; + unsigned long address; unsigned char *buf; u32 count; - count = readl(base + GOLDFISH_TTY_BYTES_READY); + count = readl(base + GOLDFISH_TTY_REG_BYTES_READY); if (count == 0) return IRQ_NONE; count = tty_prepare_flip_string(&qtty->port, &buf, count); - spin_lock_irqsave(&qtty->lock, irq_flags); - gf_write_ptr(buf, base + GOLDFISH_TTY_DATA_PTR, - base + GOLDFISH_TTY_DATA_PTR_HIGH); - writel(count, base + GOLDFISH_TTY_DATA_LEN); - writel(GOLDFISH_TTY_CMD_READ_BUFFER, base + GOLDFISH_TTY_CMD); - spin_unlock_irqrestore(&qtty->lock, irq_flags); + + address = (unsigned long)(void *)buf; + goldfish_tty_rw(qtty, address, count, 0); + tty_schedule_flip(&qtty->port); return IRQ_HANDLED; } @@ -93,7 +167,7 @@ static int goldfish_tty_activate(struct tty_port *port, struct tty_struct *tty) { struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); - writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_CMD); + writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD); return 0; } @@ -101,7 +175,7 @@ static void goldfish_tty_shutdown(struct tty_port *port) { struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); - writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_CMD); + writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD); } static int goldfish_tty_open(struct tty_struct *tty, struct file *filp) @@ -136,7 +210,7 @@ static int goldfish_tty_chars_in_buffer(struct tty_struct *tty) { struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; void __iomem *base = qtty->base; - return readl(base + GOLDFISH_TTY_BYTES_READY); + return readl(base + GOLDFISH_TTY_REG_BYTES_READY); } static void goldfish_tty_console_write(struct console *co, const char *b, @@ -227,7 +301,7 @@ static void goldfish_tty_delete_driver(void) static int goldfish_tty_probe(struct platform_device *pdev) { struct goldfish_tty *qtty; - int ret = -EINVAL; + int ret = -ENODEV; struct resource *r; struct device *ttydev; void __iomem *base; @@ -235,16 +309,22 @@ static int goldfish_tty_probe(struct platform_device *pdev) unsigned int line; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (r == NULL) - return -EINVAL; + if (!r) { + pr_err("goldfish_tty: No MEM resource available!\n"); + return -ENOMEM; + } base = ioremap(r->start, 0x1000); - if (base == NULL) - pr_err("goldfish_tty: unable to remap base\n"); + if (!base) { + pr_err("goldfish_tty: Unable to ioremap base!\n"); + return -ENOMEM; + } r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (r == NULL) + if (!r) { + pr_err("goldfish_tty: No IRQ resource available!\n"); goto err_unmap; + } irq = r->start; @@ -255,13 +335,17 @@ static int goldfish_tty_probe(struct platform_device *pdev) else line = pdev->id; - if (line >= goldfish_tty_line_count) - goto err_create_driver_failed; + if (line >= goldfish_tty_line_count) { + pr_err("goldfish_tty: Reached maximum tty number of %d.\n", + goldfish_tty_current_line_count); + ret = -ENOMEM; + goto err_unlock; + } if (goldfish_tty_current_line_count == 0) { ret = goldfish_tty_create_driver(); if (ret) - goto err_create_driver_failed; + goto err_unlock; } goldfish_tty_current_line_count++; @@ -271,17 +355,45 @@ static int goldfish_tty_probe(struct platform_device *pdev) qtty->port.ops = &goldfish_port_ops; qtty->base = base; qtty->irq = irq; + qtty->dev = &pdev->dev; - writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_CMD); + /* + * Goldfish TTY device used by the Goldfish emulator + * should identify itself with 0, forcing the driver + * to use virtual addresses. Goldfish TTY device + * on Ranchu emulator (qemu2) returns 1 here and + * driver will use physical addresses. + */ + qtty->version = readl(base + GOLDFISH_TTY_REG_VERSION); + + /* + * Goldfish TTY device on Ranchu emulator (qemu2) + * will use DMA for read/write IO operations. + */ + if (qtty->version > 0) { + /* + * Initialize dma_mask to 32-bits. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "No suitable DMA available.\n"); + goto err_dec_line_count; + } + } + + writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD); ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, - "goldfish_tty", qtty); - if (ret) - goto err_request_irq_failed; - + "goldfish_tty", qtty); + if (ret) { + pr_err("goldfish_tty: No IRQ available!\n"); + goto err_dec_line_count; + } ttydev = tty_port_register_device(&qtty->port, goldfish_tty_driver, - line, &pdev->dev); + line, &pdev->dev); if (IS_ERR(ttydev)) { ret = PTR_ERR(ttydev); goto err_tty_register_device_failed; @@ -301,11 +413,11 @@ static int goldfish_tty_probe(struct platform_device *pdev) err_tty_register_device_failed: free_irq(irq, qtty); -err_request_irq_failed: +err_dec_line_count: goldfish_tty_current_line_count--; if (goldfish_tty_current_line_count == 0) goldfish_tty_delete_driver(); -err_create_driver_failed: +err_unlock: mutex_unlock(&goldfish_tty_lock); err_unmap: iounmap(base); @@ -330,6 +442,30 @@ static int goldfish_tty_remove(struct platform_device *pdev) return 0; } +static void gf_early_console_putchar(struct uart_port *port, int ch) +{ + __raw_writel(ch, port->membase); +} + +static void gf_early_write(struct console *con, const char *s, unsigned int n) +{ + struct earlycon_device *dev = con->data; + + uart_console_write(&dev->port, s, n, gf_early_console_putchar); +} + +static int __init gf_earlycon_setup(struct earlycon_device *device, + const char *opt) +{ + if (!device->port.membase) + return -ENODEV; + + device->con->write = gf_early_write; + return 0; +} + +OF_EARLYCON_DECLARE(early_gf_tty, "google,goldfish-tty", gf_earlycon_setup); + static const struct of_device_id goldfish_tty_of_match[] = { { .compatible = "google,goldfish-tty", }, {}, diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index b8d5ea0ae26b..fec457edad14 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig @@ -4,7 +4,7 @@ config HVC_DRIVER bool help Generic "hypervisor virtual console" infrastructure for various - hypervisors (pSeries, iSeries, Xen, lguest). + hypervisors (pSeries, iSeries, Xen). It will automatically be selected if one of the back-end console drivers is selected. diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile index 6a2702be76d1..0b02ec7f1dfd 100644 --- a/drivers/tty/hvc/Makefile +++ b/drivers/tty/hvc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi_lib.o obj-$(CONFIG_HVC_OPAL) += hvc_opal.o hvsi_lib.o obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o diff --git a/drivers/tty/hvc/hvc_irq.c b/drivers/tty/hvc/hvc_irq.c index bc7a96874637..4b255dfef2cc 100644 --- a/drivers/tty/hvc/hvc_irq.c +++ b/drivers/tty/hvc/hvc_irq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2001,2008 * diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c index 8b70a1627356..a74680729825 100644 --- a/drivers/tty/hvc/hvc_iucv.c +++ b/drivers/tty/hvc/hvc_iucv.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * z/VM IUCV hypervisor console (HVC) device driver * diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 510799311099..16331a90c1e8 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -179,8 +179,8 @@ static int hvc_opal_probe(struct platform_device *dev) proto = HV_PROTOCOL_HVSI; ops = &hvc_opal_hvsi_ops; } else { - pr_err("hvc_opal: Unknown protocol for %s\n", - dev->dev.of_node->full_name); + pr_err("hvc_opal: Unknown protocol for %pOF\n", + dev->dev.of_node); return -ENXIO; } @@ -204,14 +204,14 @@ static int hvc_opal_probe(struct platform_device *dev) /* Instanciate now to establish a mapping index==vtermno */ hvc_instantiate(termno, termno, ops); } else { - pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n", - dev->dev.of_node->full_name, termno); + pr_err("hvc_opal: Device %pOF has duplicate terminal number #%d\n", + dev->dev.of_node, termno); return -ENXIO; } - pr_info("hvc%d: %s protocol on %s%s\n", termno, + pr_info("hvc%d: %s protocol on %pOF%s\n", termno, proto == HV_PROTOCOL_RAW ? "raw" : "hvsi", - dev->dev.of_node->full_name, + dev->dev.of_node, boot ? " (boot console)" : ""); irq = irq_of_parse_and_map(dev->dev.of_node, 0); @@ -222,8 +222,8 @@ static int hvc_opal_probe(struct platform_device *dev) } if (!irq) { - pr_err("hvc_opal: Unable to map interrupt for device %s\n", - dev->dev.of_node->full_name); + pr_err("hvc_opal: Unable to map interrupt for device %pOF\n", + dev->dev.of_node); return irq; } diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index b05dc5086627..a1d272ac82bb 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -53,7 +53,7 @@ static const char hvc_driver_name[] = "hvc_console"; -static struct vio_device_id hvc_driver_table[] = { +static const struct vio_device_id hvc_driver_table[] = { {"serial", "hvterm1"}, #ifndef HVC_OLD_HVSI {"serial", "hvterm-protocol"}, @@ -312,12 +312,12 @@ static int hvc_vio_probe(struct vio_dev *vdev, proto = HV_PROTOCOL_HVSI; ops = &hvterm_hvsi_ops; } else { - pr_err("hvc_vio: Unknown protocol for %s\n", vdev->dev.of_node->full_name); + pr_err("hvc_vio: Unknown protocol for %pOF\n", vdev->dev.of_node); return -ENXIO; } - pr_devel("hvc_vio_probe() device %s, using %s protocol\n", - vdev->dev.of_node->full_name, + pr_devel("hvc_vio_probe() device %pOF, using %s protocol\n", + vdev->dev.of_node, proto == HV_PROTOCOL_RAW ? "raw" : "hvsi"); /* Is it our boot one ? */ @@ -442,6 +442,14 @@ void __init hvc_vio_init_early(void) #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR void __init udbg_init_debug_lpar(void) { + /* + * If we're running as a hypervisor then we definitely can't call the + * hypervisor to print debug output (we *are* the hypervisor), so don't + * register if we detect that MSR_HV=1. + */ + if (mfmsr() & MSR_HV) + return; + hvterm_privs[0] = &hvterm_priv0; hvterm_priv0.termno = 0; hvterm_priv0.proto = HV_PROTOCOL_RAW; @@ -455,6 +463,10 @@ void __init udbg_init_debug_lpar(void) #ifdef CONFIG_PPC_EARLY_DEBUG_LPAR_HVSI void __init udbg_init_debug_lpar_hvsi(void) { + /* See comment above in udbg_init_debug_lpar() */ + if (mfmsr() & MSR_HV) + return; + hvterm_privs[0] = &hvterm_priv0; hvterm_priv0.termno = CONFIG_PPC_EARLY_DEBUG_HVSI_VTERMNO; hvterm_priv0.proto = HV_PROTOCOL_HVSI; diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 79cc5beea2da..63c29fe9d21f 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -189,7 +189,7 @@ MODULE_VERSION(HVCS_DRIVER_VERSION); * that will cause echoing or we'll go into recursive loop echoing chars back * and forth with the console drivers. */ -static struct ktermios hvcs_tty_termios = { +static const struct ktermios hvcs_tty_termios = { .c_iflag = IGNBRK | IGNPAR, .c_oflag = OPOST, .c_cflag = B38400 | CS8 | CREAD | HUPCL, @@ -675,7 +675,7 @@ static int khvcsd(void *unused) return 0; } -static struct vio_device_id hvcs_driver_table[] = { +static const struct vio_device_id hvcs_driver_table[] = { {"serial-server", "hvterm2"}, { "", "" } }; diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c index a270f04588d7..09289c8154ae 100644 --- a/drivers/tty/hvc/hvsi_lib.c +++ b/drivers/tty/hvc/hvsi_lib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index df0204b6148f..a6b8240af6cd 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/ipwireless/hardware.h b/drivers/tty/ipwireless/hardware.h index 90a8590e43b0..e524a8fcc2ad 100644 --- a/drivers/tty/ipwireless/hardware.h +++ b/drivers/tty/ipwireless/hardware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/ipwireless/main.h b/drivers/tty/ipwireless/main.h index f2cbb116bccb..73818bb64416 100644 --- a/drivers/tty/ipwireless/main.h +++ b/drivers/tty/ipwireless/main.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c index c2f9a3263b37..695439c03147 100644 --- a/drivers/tty/ipwireless/network.c +++ b/drivers/tty/ipwireless/network.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/ipwireless/network.h b/drivers/tty/ipwireless/network.h index 561f765b3334..784932a59a73 100644 --- a/drivers/tty/ipwireless/network.h +++ b/drivers/tty/ipwireless/network.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/ipwireless/setup_protocol.h b/drivers/tty/ipwireless/setup_protocol.h index 002c34e72521..d4a7ae257ca5 100644 --- a/drivers/tty/ipwireless/setup_protocol.h +++ b/drivers/tty/ipwireless/setup_protocol.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 2685d59d2724..1ef751c27ac6 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/ipwireless/tty.h b/drivers/tty/ipwireless/tty.h index 747b2d637860..ec698d9f338b 100644 --- a/drivers/tty/ipwireless/tty.h +++ b/drivers/tty/ipwireless/tty.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * IPWireless 3G PCMCIA Network Driver * diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index b70187b46d9d..61ecdd6b2fc2 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -150,7 +150,7 @@ static int isicom_probe(struct pci_dev *, const struct pci_device_id *); static void isicom_remove(struct pci_dev *); -static struct pci_device_id isicom_pci_tbl[] = { +static const struct pci_device_id isicom_pci_tbl[] = { { PCI_DEVICE(VENDOR_ID, 0x2028) }, { PCI_DEVICE(VENDOR_ID, 0x2051) }, { PCI_DEVICE(VENDOR_ID, 0x2052) }, diff --git a/drivers/tty/mips_ejtag_fdc.c b/drivers/tty/mips_ejtag_fdc.c index 234123b0c642..a2dab3fb8751 100644 --- a/drivers/tty/mips_ejtag_fdc.c +++ b/drivers/tty/mips_ejtag_fdc.c @@ -1110,7 +1110,7 @@ out: return ret; } -static struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = { +static const struct mips_cdmm_device_id mips_ejtag_fdc_tty_ids[] = { { .type = 0xfd }, { } }; diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 3b251f4e5df0..7f3d4cb0341b 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -88,7 +88,7 @@ static char *moxa_brdname[] = }; #ifdef CONFIG_PCI -static struct pci_device_id moxa_pcibrds[] = { +static const struct pci_device_id moxa_pcibrds[] = { { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218), .driver_data = MOXA_BOARD_C218_PCI }, { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320), diff --git a/drivers/tty/moxa.h b/drivers/tty/moxa.h index 87d16ce57be7..8ce89fd36c7b 100644 --- a/drivers/tty/moxa.h +++ b/drivers/tty/moxa.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef MOXA_H_FILE #define MOXA_H_FILE diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 8bd6fb6d9391..7dd38047ba23 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -145,7 +145,7 @@ static const struct mxser_cardinfo mxser_cards[] = { /* driver_data correspond to the lines in the structure above see also ISA probe function before you change something */ -static struct pci_device_id mxser_pcibrds[] = { +static const struct pci_device_id mxser_pcibrds[] = { { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, @@ -246,11 +246,11 @@ struct mxser_port { unsigned char err_shadow; struct async_icount icount; /* kernel counters for 4 input interrupts */ - int timeout; + unsigned int timeout; int read_status_mask; int ignore_status_mask; - int xmit_fifo_size; + unsigned int xmit_fifo_size; int xmit_head; int xmit_tail; int xmit_cnt; @@ -572,8 +572,9 @@ static void mxser_dtr_rts(struct tty_port *port, int on) static int mxser_set_baud(struct tty_struct *tty, long newspd) { struct mxser_port *info = tty->driver_data; - int quot = 0, baud; + unsigned int quot = 0, baud; unsigned char cval; + u64 timeout; if (!info->ioaddr) return -1; @@ -594,8 +595,13 @@ static int mxser_set_baud(struct tty_struct *tty, long newspd) quot = 0; } - info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); - info->timeout += HZ / 50; /* Add .02 seconds of slop */ + /* + * worst case (128 * 1000 * 10 * 18432) needs 35 bits, so divide in the + * u64 domain + */ + timeout = (u64)info->xmit_fifo_size * HZ * 10 * quot; + do_div(timeout, info->baud_base); + info->timeout = timeout + HZ / 50; /* Add .02 seconds of slop */ if (quot) { info->MCR |= UART_MCR_DTR; diff --git a/drivers/tty/mxser.h b/drivers/tty/mxser.h index 0bf794313ffd..e6cb15626567 100644 --- a/drivers/tty/mxser.h +++ b/drivers/tty/mxser.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _MXSER_H #define _MXSER_H diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 2afe5fce68e3..0a3c9665e015 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2607,6 +2607,14 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file, } } +#ifdef CONFIG_COMPAT +static long gsmld_compat_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return gsmld_ioctl(tty, file, cmd, arg); +} +#endif + /* * Network interface * @@ -2818,6 +2826,9 @@ static struct tty_ldisc_ops tty_ldisc_packet = { .flush_buffer = gsmld_flush_buffer, .read = gsmld_read, .write = gsmld_write, +#ifdef CONFIG_COMPAT + .compat_ioctl = gsmld_compat_ioctl, +#endif .ioctl = gsmld_ioctl, .poll = gsmld_poll, .receive_buf = gsmld_receive_buf, diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index a6d5164c33a9..64338442050e 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1991, 1992 Linus Torvalds * @@ -742,6 +743,11 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) } } +static void pty_show_fdinfo(struct tty_struct *tty, struct seq_file *m) +{ + seq_printf(m, "tty-index:\t%d\n", tty->index); +} + static const struct tty_operations ptm_unix98_ops = { .lookup = ptm_unix98_lookup, .install = pty_unix98_install, @@ -756,7 +762,8 @@ static const struct tty_operations ptm_unix98_ops = { .ioctl = pty_unix98_ioctl, .compat_ioctl = pty_unix98_compat_ioctl, .resize = pty_resize, - .cleanup = pty_cleanup + .cleanup = pty_cleanup, + .show_fdinfo = pty_show_fdinfo, }; static const struct tty_operations pty_unix98_ops = { diff --git a/drivers/tty/rocket.h b/drivers/tty/rocket.h index c11a9392f219..d0560203f215 100644 --- a/drivers/tty/rocket.h +++ b/drivers/tty/rocket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * rocket.h --- the exported interface of the rocket driver to its configuration program. * diff --git a/drivers/tty/rocket_int.h b/drivers/tty/rocket_int.h index ef1e1be6b26d..727e50dbb92f 100644 --- a/drivers/tty/rocket_int.h +++ b/drivers/tty/rocket_int.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * rocket_int.h --- internal header file for rocket.c * diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index ae1aaa0075d1..c68fb3a8ea1c 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -363,7 +363,7 @@ static int of_serdev_register_devices(struct serdev_controller *ctrl) if (!of_get_property(node, "compatible", NULL)) continue; - dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name); + dev_dbg(&ctrl->dev, "adding child %pOF\n", node); serdev = serdev_device_alloc(ctrl); if (!serdev) diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 9b208bd686e6..804632b4a929 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -334,7 +334,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct return ret; } -static struct uart_ops serial21285_ops = { +static const struct uart_ops serial21285_ops = { .tx_empty = serial21285_tx_empty, .get_mctrl = serial21285_get_mctrl, .set_mctrl = serial21285_set_mctrl, diff --git a/drivers/tty/serial/8250/8250_aspeed_vuart.c b/drivers/tty/serial/8250/8250_aspeed_vuart.c index 822be4906763..33a801353114 100644 --- a/drivers/tty/serial/8250/8250_aspeed_vuart.c +++ b/drivers/tty/serial/8250/8250_aspeed_vuart.c @@ -223,12 +223,13 @@ static int aspeed_vuart_probe(struct platform_device *pdev) if (IS_ERR(vuart->clk)) { dev_warn(&pdev->dev, "clk or clock-frequency not defined\n"); - return PTR_ERR(vuart->clk); + rc = PTR_ERR(vuart->clk); + goto err_sysfs_remove; } rc = clk_prepare_enable(vuart->clk); if (rc < 0) - return rc; + goto err_sysfs_remove; clk = clk_get_rate(vuart->clk); } @@ -286,6 +287,8 @@ static int aspeed_vuart_probe(struct platform_device *pdev) err_clk_disable: clk_disable_unprepare(vuart->clk); irq_dispose_mapping(port.port.irq); +err_sysfs_remove: + sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group); return rc; } diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 1aab3010fbfa..d29b512a7d9f 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -497,6 +497,11 @@ static void univ8250_rsa_support(struct uart_ops *ops) #define univ8250_rsa_support(x) do { } while (0) #endif /* CONFIG_SERIAL_8250_RSA */ +static inline void serial8250_apply_quirks(struct uart_8250_port *up) +{ + up->port.quirks |= skip_txen_test ? UPQ_NO_TXEN_TEST : 0; +} + static void __init serial8250_isa_init_ports(void) { struct uart_8250_port *up; @@ -577,9 +582,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) up->port.dev = dev; - if (skip_txen_test) - up->port.flags |= UPF_NO_TXEN_TEST; - + serial8250_apply_quirks(up); uart_add_one_port(drv, &up->port); } } @@ -1006,9 +1009,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) if (up->port.dev) uart->port.dev = up->port.dev; - if (skip_txen_test) - uart->port.flags |= UPF_NO_TXEN_TEST; - if (up->port.flags & UPF_FIXED_TYPE) uart->port.type = up->port.type; @@ -1048,6 +1048,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up) serial8250_isa_config(0, &uart->port, &uart->capabilities); + serial8250_apply_quirks(uart); ret = uart_add_one_port(&serial8250_reg, &uart->port); if (ret == 0) @@ -1092,11 +1093,10 @@ void serial8250_unregister_port(int line) uart_remove_one_port(&serial8250_reg, &uart->port); if (serial8250_isa_devs) { uart->port.flags &= ~UPF_BOOT_AUTOCONF; - if (skip_txen_test) - uart->port.flags |= UPF_NO_TXEN_TEST; uart->port.type = PORT_UNKNOWN; uart->port.dev = &serial8250_isa_devs->dev; uart->capabilities = 0; + serial8250_apply_quirks(uart); uart_add_one_port(&serial8250_reg, &uart->port); } else { uart->port.dev = NULL; diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 787b1160d3a5..7e638997bfc2 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -529,7 +529,7 @@ static int dw8250_probe(struct platform_device *pdev) } } - data->rst = devm_reset_control_get_optional(dev, NULL); + data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); if (IS_ERR(data->rst)) { err = PTR_ERR(data->rst); goto err_pclk; diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 82fc48eca1df..af72ec32e404 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -37,7 +37,7 @@ #include #include -static unsigned int __init serial8250_early_in(struct uart_port *port, int offset) +static unsigned int serial8250_early_in(struct uart_port *port, int offset) { int reg_offset = offset; offset <<= port->regshift; @@ -60,7 +60,7 @@ static unsigned int __init serial8250_early_in(struct uart_port *port, int offse } } -static void __init serial8250_early_out(struct uart_port *port, int offset, int value) +static void serial8250_early_out(struct uart_port *port, int offset, int value) { int reg_offset = offset; offset <<= port->regshift; @@ -89,7 +89,7 @@ static void __init serial8250_early_out(struct uart_port *port, int offset, int #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) -static void __init serial_putc(struct uart_port *port, int c) +static void serial_putc(struct uart_port *port, int c) { unsigned int status; @@ -103,7 +103,7 @@ static void __init serial_putc(struct uart_port *port, int c) } } -static void __init early_serial8250_write(struct console *console, +static void early_serial8250_write(struct console *console, const char *s, unsigned int count) { struct earlycon_device *device = console->data; diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index c6360fbdf808..c55624703fdf 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -601,7 +601,7 @@ static const struct exar8250_board pbn_exar_XR17V8358 = { (kernel_ulong_t)&bd \ } -static struct pci_device_id exar_pci_tbl[] = { +static const struct pci_device_id exar_pci_tbl[] = { CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect), CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect), CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect), diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index 63306de4390d..df2931e1e086 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c @@ -80,7 +80,7 @@ static int __init serial_init_chip(struct parisc_device *dev) return 0; } -static struct parisc_device_id serial_tbl[] = { +static const struct parisc_device_id serial_tbl[] __initconst = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00075 }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008c }, { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0008d }, @@ -94,7 +94,7 @@ static struct parisc_device_id serial_tbl[] = { * which only knows about Lasi and then a second which will find all the * other serial ports. HPUX ignores this problem. */ -static struct parisc_device_id lasi_tbl[] = { +static const struct parisc_device_id lasi_tbl[] __initconst = { { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03B, 0x0008C }, /* C1xx/C1xxL */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03C, 0x0008C }, /* B132L */ { HPHW_FIO, HVERSION_REV_ANY_ID, 0x03D, 0x0008C }, /* B160L */ @@ -110,13 +110,13 @@ static struct parisc_device_id lasi_tbl[] = { MODULE_DEVICE_TABLE(parisc, serial_tbl); -static struct parisc_driver lasi_driver = { +static struct parisc_driver lasi_driver __refdata = { .name = "serial_1", .id_table = lasi_tbl, .probe = serial_init_chip, }; -static struct parisc_driver serial_driver = { +static struct parisc_driver serial_driver __refdata = { .name = "serial", .id_table = serial_tbl, .probe = serial_init_chip, diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c index 4d9dc10e265c..464389b28900 100644 --- a/drivers/tty/serial/8250/8250_ingenic.c +++ b/drivers/tty/serial/8250/8250_ingenic.c @@ -50,17 +50,17 @@ static const struct of_device_id of_match[]; static struct earlycon_device *early_device; -static uint8_t __init early_in(struct uart_port *port, int offset) +static uint8_t early_in(struct uart_port *port, int offset) { return readl(port->membase + (offset << 2)); } -static void __init early_out(struct uart_port *port, int offset, uint8_t value) +static void early_out(struct uart_port *port, int offset, uint8_t value) { writel(value, port->membase + (offset << 2)); } -static void __init ingenic_early_console_putc(struct uart_port *port, int c) +static void ingenic_early_console_putc(struct uart_port *port, int c) { uint8_t lsr; @@ -71,7 +71,7 @@ static void __init ingenic_early_console_putc(struct uart_port *port, int c) early_out(port, UART_TX, c); } -static void __init ingenic_early_console_write(struct console *console, +static void ingenic_early_console_write(struct console *console, const char *s, unsigned int count) { uart_console_write(&early_device->port, s, count, diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c new file mode 100644 index 000000000000..308977807994 --- /dev/null +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct serial_8250_men_mcb_data { + struct uart_8250_port uart; + int line; +}; + +/* + * The Z125 16550-compatible UART has no fixed base clock assigned + * So, depending on the board we're on, we need to adjust the + * parameter in order to really set the correct baudrate, and + * do so if possible without user interaction + */ +static u32 men_z125_lookup_uartclk(struct mcb_device *mdev) +{ + /* use default value if board is not available below */ + u32 clkval = 1041666; + + dev_info(&mdev->dev, "%s on board %s\n", + dev_name(&mdev->dev), + mdev->bus->name); + if (strncmp(mdev->bus->name, "F075", 4) == 0) + clkval = 1041666; + else if (strncmp(mdev->bus->name, "F216", 4) == 0) + clkval = 1843200; + else if (strncmp(mdev->bus->name, "G215", 4) == 0) + clkval = 1843200; + else + dev_info(&mdev->dev, + "board not detected, using default uartclk\n"); + + clkval = clkval << 4; + + return clkval; +} + +static int serial_8250_men_mcb_probe(struct mcb_device *mdev, + const struct mcb_device_id *id) +{ + struct serial_8250_men_mcb_data *data; + struct resource *mem; + + data = devm_kzalloc(&mdev->dev, + sizeof(struct serial_8250_men_mcb_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + mcb_set_drvdata(mdev, data); + data->uart.port.dev = mdev->dma_dev; + spin_lock_init(&data->uart.port.lock); + + data->uart.port.type = PORT_16550; + data->uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE; + data->uart.port.iotype = UPIO_MEM; + data->uart.port.uartclk = men_z125_lookup_uartclk(mdev); + data->uart.port.regshift = 0; + data->uart.port.fifosize = 60; + + mem = mcb_get_resource(mdev, IORESOURCE_MEM); + if (mem == NULL) + return -ENXIO; + + data->uart.port.irq = mcb_get_irq(mdev); + + data->uart.port.membase = devm_ioremap_resource(&mdev->dev, mem); + if (IS_ERR(data->uart.port.membase)) + return PTR_ERR_OR_ZERO(data->uart.port.membase); + + data->uart.port.mapbase = (unsigned long) mem->start; + data->uart.port.iobase = data->uart.port.mapbase; + + /* ok, register the port */ + data->line = serial8250_register_8250_port(&data->uart); + if (data->line < 0) + return data->line; + + dev_info(&mdev->dev, "found 16Z125 UART: ttyS%d\n", data->line); + + return 0; +} + +static void serial_8250_men_mcb_remove(struct mcb_device *mdev) +{ + struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev); + + if (data) + serial8250_unregister_port(data->line); +} + +static const struct mcb_device_id serial_8250_men_mcb_ids[] = { + { .device = 0x7d }, + { } +}; +MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids); + +static struct mcb_driver mcb_driver = { + .driver = { + .name = "8250_men_mcb", + .owner = THIS_MODULE, + }, + .probe = serial_8250_men_mcb_probe, + .remove = serial_8250_men_mcb_remove, + .id_table = serial_8250_men_mcb_ids, +}; +module_mcb_driver(mcb_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("MEN 16z125 8250 UART driver"); +MODULE_AUTHOR("Michael Moese bus_clk = devm_clk_get(&pdev->dev, "bus"); - if (IS_ERR(data->bus_clk)) - return PTR_ERR(data->bus_clk); - - return 0; + return PTR_ERR_OR_ZERO(data->bus_clk); } static int mtk8250_probe(struct platform_device *pdev) diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c index 0cf95fddccfc..1222c005fb98 100644 --- a/drivers/tty/serial/8250/8250_of.c +++ b/drivers/tty/serial/8250/8250_of.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,10 @@ static int of_platform_serial_setup(struct platform_device *ofdev, int ret; memset(port, 0, sizeof *port); + + pm_runtime_enable(&ofdev->dev); + pm_runtime_get_sync(&ofdev->dev); + if (of_property_read_u32(np, "clock-frequency", &clk)) { /* Get clk rate through clk driver if present */ @@ -72,12 +77,13 @@ static int of_platform_serial_setup(struct platform_device *ofdev, if (IS_ERR(info->clk)) { dev_warn(&ofdev->dev, "clk or clock-frequency not defined\n"); - return PTR_ERR(info->clk); + ret = PTR_ERR(info->clk); + goto err_pmruntime; } ret = clk_prepare_enable(info->clk); if (ret < 0) - return ret; + goto err_pmruntime; clk = clk_get_rate(info->clk); } @@ -88,7 +94,7 @@ static int of_platform_serial_setup(struct platform_device *ofdev, ret = of_address_to_resource(np, 0, &resource); if (ret) { dev_warn(&ofdev->dev, "invalid address\n"); - goto out; + goto err_unprepare; } spin_lock_init(&port->lock); @@ -130,23 +136,23 @@ static int of_platform_serial_setup(struct platform_device *ofdev, dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", prop); ret = -EINVAL; - goto out; + goto err_dispose; } } info->rst = devm_reset_control_get_optional_shared(&ofdev->dev, NULL); if (IS_ERR(info->rst)) - goto out; + goto err_dispose; ret = reset_control_deassert(info->rst); if (ret) - goto out; + goto err_dispose; port->type = type; port->uartclk = clk; port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_FIXED_PORT | UPF_FIXED_TYPE; - if (of_find_property(np, "no-loopback-test", NULL)) + if (of_property_read_bool(np, "no-loopback-test")) port->flags |= UPF_SKIP_TEST; port->dev = &ofdev->dev; @@ -167,9 +173,13 @@ static int of_platform_serial_setup(struct platform_device *ofdev, port->handle_irq = fsl8250_handle_irq; return 0; -out: - if (info->clk) - clk_disable_unprepare(info->clk); +err_dispose: + irq_dispose_mapping(port->irq); +err_unprepare: + clk_disable_unprepare(info->clk); +err_pmruntime: + pm_runtime_put_sync(&ofdev->dev); + pm_runtime_disable(&ofdev->dev); return ret; } @@ -190,7 +200,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) if (!match) return -EINVAL; - if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) + if (of_property_read_bool(ofdev->dev.of_node, "used-by-rtas")) return -EBUSY; info = kzalloc(sizeof(*info), GFP_KERNEL); @@ -201,7 +211,7 @@ static int of_platform_serial_probe(struct platform_device *ofdev) memset(&port8250, 0, sizeof(port8250)); ret = of_platform_serial_setup(ofdev, port_type, &port8250.port, info); if (ret) - goto out; + goto err_free; if (port8250.port.fifosize) port8250.capabilities = UART_CAP_FIFO; @@ -217,15 +227,19 @@ static int of_platform_serial_probe(struct platform_device *ofdev) ret = serial8250_register_8250_port(&port8250); if (ret < 0) - goto out; + goto err_dispose; info->type = port_type; info->line = ret; platform_set_drvdata(ofdev, info); return 0; -out: - kfree(info); +err_dispose: irq_dispose_mapping(port8250.port.irq); + pm_runtime_put_sync(&ofdev->dev); + pm_runtime_disable(&ofdev->dev); + clk_disable_unprepare(info->clk); +err_free: + kfree(info); return ret; } @@ -239,8 +253,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev) serial8250_unregister_port(info->line); reset_control_assert(info->rst); - if (info->clk) - clk_disable_unprepare(info->clk); + pm_runtime_put_sync(&ofdev->dev); + pm_runtime_disable(&ofdev->dev); + clk_disable_unprepare(info->clk); kfree(info); return 0; } @@ -254,9 +269,10 @@ static int of_serial_suspend(struct device *dev) serial8250_suspend_port(info->line); - if (info->clk && (!uart_console(port) || console_suspend_enabled)) + if (!uart_console(port) || console_suspend_enabled) { + pm_runtime_put_sync(dev); clk_disable_unprepare(info->clk); - + } return 0; } @@ -266,8 +282,10 @@ static int of_serial_resume(struct device *dev) struct uart_8250_port *port8250 = serial8250_get_port(info->line); struct uart_port *port = &port8250->port; - if (info->clk && (!uart_console(port) || console_suspend_enabled)) + if (!uart_console(port) || console_suspend_enabled) { + pm_runtime_get_sync(dev); clk_prepare_enable(info->clk); + } serial8250_resume_port(info->line); @@ -295,6 +313,8 @@ static const struct of_device_id of_platform_serial_table[] = { .data = (void *)PORT_ALTR_16550_F64, }, { .compatible = "altr,16550-FIFO128", .data = (void *)PORT_ALTR_16550_F128, }, + { .compatible = "mediatek,mtk-btif", + .data = (void *)PORT_MTK_BTIF, }, { .compatible = "mrvl,mmp-uart", .data = (void *)PORT_XSCALE, }, { .compatible = "ti,da830-uart", .data = (void *)PORT_DA830, }, diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 00e51a064388..0c101a7470b0 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1548,7 +1548,7 @@ static int skip_tx_en_setup(struct serial_private *priv, const struct pciserial_board *board, struct uart_8250_port *port, int idx) { - port->port.flags |= UPF_NO_TXEN_TEST; + port->port.quirks |= UPQ_NO_TXEN_TEST; dev_dbg(&priv->dev->dev, "serial8250: skipping TxEn test for device [%04x:%04x] subsystem [%04x:%04x]\n", priv->dev->vendor, priv->dev->device, @@ -3384,17 +3384,8 @@ static const struct pci_device_id blacklist[] = { { PCI_VDEVICE(COMMTECH, PCI_ANY_ID), }, }; -/* - * Given a complete unknown PCI device, try to use some heuristics to - * guess what the configuration might be, based on the pitiful PCI - * serial specs. Returns 0 on success, 1 on failure. - */ -static int -serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) +static int serial_pci_is_class_communication(struct pci_dev *dev) { - const struct pci_device_id *bldev; - int num_iomem, num_port, first_port = -1, i; - /* * If it is not a communications device or the programming * interface is greater than 6, give up. @@ -3407,6 +3398,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) (dev->class & 0xff) > 6) return -ENODEV; + return 0; +} + +static int serial_pci_is_blacklisted(struct pci_dev *dev) +{ + const struct pci_device_id *bldev; + /* * Do not access blacklisted devices that are known not to * feature serial ports or are handled by other modules. @@ -3419,6 +3417,19 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) return -ENODEV; } + return 0; +} + +/* + * Given a complete unknown PCI device, try to use some heuristics to + * guess what the configuration might be, based on the pitiful PCI + * serial specs. Returns 0 on success, -ENODEV on failure. + */ +static int +serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) +{ + int num_iomem, num_port, first_port = -1, i; + num_iomem = num_port = 0; for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) { @@ -3639,6 +3650,14 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) board = &pci_boards[ent->driver_data]; + rc = serial_pci_is_class_communication(dev); + if (rc) + return rc; + + rc = serial_pci_is_blacklisted(dev); + if (rc) + return rc; + rc = pcim_enable_device(dev); pci_save_state(dev); if (rc) @@ -3723,7 +3742,7 @@ static int pciserial_resume_one(struct device *dev) static SIMPLE_DEV_PM_OPS(pciserial_pm_ops, pciserial_suspend_one, pciserial_resume_one); -static struct pci_device_id serial_pci_tbl[] = { +static const struct pci_device_id serial_pci_tbl[] = { /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620, PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0, diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index a5fe0e66c607..f0cc04f62b67 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include @@ -289,6 +289,14 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, + [PORT_MTK_BTIF] = { + .name = "MediaTek BTIF", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, + .flags = UART_CAP_FIFO, + }, }; /* Uart divisor latch read */ @@ -553,8 +561,8 @@ static inline void serial8250_em485_rts_after_send(struct uart_8250_port *p) serial8250_out_MCR(p, mcr); } -static void serial8250_em485_handle_start_tx(unsigned long arg); -static void serial8250_em485_handle_stop_tx(unsigned long arg); +static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t); +static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t); void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p) { @@ -609,12 +617,14 @@ int serial8250_em485_init(struct uart_8250_port *p) if (!p->em485) return -ENOMEM; - setup_timer(&p->em485->stop_tx_timer, - serial8250_em485_handle_stop_tx, (unsigned long)p); - setup_timer(&p->em485->start_tx_timer, - serial8250_em485_handle_start_tx, (unsigned long)p); + hrtimer_init(&p->em485->stop_tx_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + p->em485->stop_tx_timer.function = &serial8250_em485_handle_stop_tx; + p->em485->start_tx_timer.function = &serial8250_em485_handle_start_tx; + p->em485->port = p; p->em485->active_timer = NULL; - serial8250_em485_rts_after_send(p); return 0; @@ -639,8 +649,8 @@ void serial8250_em485_destroy(struct uart_8250_port *p) if (!p->em485) return; - del_timer(&p->em485->start_tx_timer); - del_timer(&p->em485->stop_tx_timer); + hrtimer_cancel(&p->em485->start_tx_timer); + hrtimer_cancel(&p->em485->stop_tx_timer); kfree(p->em485); p->em485 = NULL; @@ -1435,22 +1445,33 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p) serial_port_out(&p->port, UART_IER, p->ier); } } - -static void serial8250_em485_handle_stop_tx(unsigned long arg) +static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t) { - struct uart_8250_port *p = (struct uart_8250_port *)arg; - struct uart_8250_em485 *em485 = p->em485; + struct uart_8250_em485 *em485; + struct uart_8250_port *p; unsigned long flags; + em485 = container_of(t, struct uart_8250_em485, stop_tx_timer); + p = em485->port; + serial8250_rpm_get(p); spin_lock_irqsave(&p->port.lock, flags); - if (em485 && - em485->active_timer == &em485->stop_tx_timer) { + if (em485->active_timer == &em485->stop_tx_timer) { __do_stop_tx_rs485(p); em485->active_timer = NULL; } spin_unlock_irqrestore(&p->port.lock, flags); serial8250_rpm_put(p); + return HRTIMER_NORESTART; +} + +static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec) +{ + long sec = msec / 1000; + long nsec = (msec % 1000) * 1000000; + ktime_t t = ktime_set(sec, nsec); + + hrtimer_start(hrt, t, HRTIMER_MODE_REL); } static void __stop_tx_rs485(struct uart_8250_port *p) @@ -1463,8 +1484,8 @@ static void __stop_tx_rs485(struct uart_8250_port *p) */ if (p->port.rs485.delay_rts_after_send > 0) { em485->active_timer = &em485->stop_tx_timer; - mod_timer(&em485->stop_tx_timer, jiffies + - p->port.rs485.delay_rts_after_send * HZ / 1000); + start_hrtimer_ms(&em485->stop_tx_timer, + p->port.rs485.delay_rts_after_send); } else { __do_stop_tx_rs485(p); } @@ -1494,8 +1515,8 @@ static inline void __stop_tx(struct uart_8250_port *p) if ((lsr & BOTH_EMPTY) != BOTH_EMPTY) return; - del_timer(&em485->start_tx_timer); em485->active_timer = NULL; + hrtimer_cancel(&em485->start_tx_timer); __stop_tx_rs485(p); } @@ -1558,8 +1579,9 @@ static inline void start_tx_rs485(struct uart_port *port) if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) serial8250_stop_rx(&up->port); - del_timer(&em485->stop_tx_timer); em485->active_timer = NULL; + if (hrtimer_is_queued(&em485->stop_tx_timer)) + hrtimer_cancel(&em485->stop_tx_timer); mcr = serial8250_in_MCR(up); if (!!(up->port.rs485.flags & SER_RS485_RTS_ON_SEND) != @@ -1572,8 +1594,8 @@ static inline void start_tx_rs485(struct uart_port *port) if (up->port.rs485.delay_rts_before_send > 0) { em485->active_timer = &em485->start_tx_timer; - mod_timer(&em485->start_tx_timer, jiffies + - up->port.rs485.delay_rts_before_send * HZ / 1000); + start_hrtimer_ms(&em485->start_tx_timer, + up->port.rs485.delay_rts_before_send); return; } } @@ -1581,19 +1603,22 @@ static inline void start_tx_rs485(struct uart_port *port) __start_tx(port); } -static void serial8250_em485_handle_start_tx(unsigned long arg) +static enum hrtimer_restart serial8250_em485_handle_start_tx(struct hrtimer *t) { - struct uart_8250_port *p = (struct uart_8250_port *)arg; - struct uart_8250_em485 *em485 = p->em485; + struct uart_8250_em485 *em485; + struct uart_8250_port *p; unsigned long flags; + em485 = container_of(t, struct uart_8250_em485, start_tx_timer); + p = em485->port; + spin_lock_irqsave(&p->port.lock, flags); - if (em485 && - em485->active_timer == &em485->start_tx_timer) { + if (em485->active_timer == &em485->start_tx_timer) { __start_tx(&p->port); em485->active_timer = NULL; } spin_unlock_irqrestore(&p->port.lock, flags); + return HRTIMER_NORESTART; } static void serial8250_start_tx(struct uart_port *port) @@ -2304,7 +2329,7 @@ int serial8250_do_startup(struct uart_port *port) * test if we receive TX irq. This way, we'll never enable * UART_BUG_TXEN. */ - if (up->port.flags & UPF_NO_TXEN_TEST) + if (up->port.quirks & UPQ_NO_TXEN_TEST) goto dont_test_tx_en; /* diff --git a/drivers/tty/serial/8250/8250_uniphier.c b/drivers/tty/serial/8250/8250_uniphier.c index 746680ebf90c..8a10b10e27aa 100644 --- a/drivers/tty/serial/8250/8250_uniphier.c +++ b/drivers/tty/serial/8250/8250_uniphier.c @@ -29,12 +29,13 @@ * - MMIO32 (regshift = 2) * - FCR is not at 2, but 3 * - LCR and MCR are not at 3 and 4, they share 4 + * - No SCR (Instead, CHAR can be used as a scratch register) * - Divisor latch at 9, no divisor latch access bit */ #define UNIPHIER_UART_REGSHIFT 2 -/* bit[15:8] = CHAR (not used), bit[7:0] = FCR */ +/* bit[15:8] = CHAR, bit[7:0] = FCR */ #define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT)) /* bit[15:8] = LCR, bit[7:0] = MCR */ #define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT)) @@ -72,13 +73,18 @@ OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart", /* * The register map is slightly different from that of 8250. - * IO callbacks must be overridden for correct access to FCR, LCR, and MCR. + * IO callbacks must be overridden for correct access to FCR, LCR, MCR and SCR. */ static unsigned int uniphier_serial_in(struct uart_port *p, int offset) { unsigned int valshift = 0; switch (offset) { + case UART_SCR: + /* No SCR for this hardware. Use CHAR as a scratch register */ + valshift = 8; + offset = UNIPHIER_UART_CHAR_FCR; + break; case UART_LCR: valshift = 8; /* fall through */ @@ -91,8 +97,8 @@ static unsigned int uniphier_serial_in(struct uart_port *p, int offset) } /* - * The return value must be masked with 0xff because LCR and MCR reside - * in the same register that must be accessed by 32-bit write/read. + * The return value must be masked with 0xff because some registers + * share the same offset that must be accessed by 32-bit write/read. * 8 or 16 bit access to this hardware result in unexpected behavior. */ return (readl(p->membase + offset) >> valshift) & 0xff; @@ -101,9 +107,13 @@ static unsigned int uniphier_serial_in(struct uart_port *p, int offset) static void uniphier_serial_out(struct uart_port *p, int offset, int value) { unsigned int valshift = 0; - bool normal = true; + bool normal = false; switch (offset) { + case UART_SCR: + /* No SCR for this hardware. Use CHAR as a scratch register */ + valshift = 8; + /* fall through */ case UART_FCR: offset = UNIPHIER_UART_CHAR_FCR; break; @@ -114,10 +124,10 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value) /* fall through */ case UART_MCR: offset = UNIPHIER_UART_LCR_MCR; - normal = false; break; default: offset <<= UNIPHIER_UART_REGSHIFT; + normal = true; break; } @@ -169,7 +179,7 @@ static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port, dev_err(dev, "failed to get alias id\n"); return ret; } - port->line = priv->line = ret; + port->line = ret; /* Get clk rate through clk driver */ priv->clk = devm_clk_get(dev, NULL); @@ -249,8 +259,8 @@ static int uniphier_uart_probe(struct platform_device *pdev) up.dl_read = uniphier_serial_dl_read; up.dl_write = uniphier_serial_dl_write; - ret = serial8250_register_8250_port(&up); - if (ret < 0) { + priv->line = serial8250_register_8250_port(&up); + if (priv->line < 0) { dev_err(dev, "failed to register 8250 port\n"); clk_disable_unprepare(priv->clk); return ret; @@ -271,6 +281,40 @@ static int uniphier_uart_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused uniphier_uart_suspend(struct device *dev) +{ + struct uniphier8250_priv *priv = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(priv->line); + + serial8250_suspend_port(priv->line); + + if (!uart_console(&up->port) || console_suspend_enabled) + clk_disable_unprepare(priv->clk); + + return 0; +} + +static int __maybe_unused uniphier_uart_resume(struct device *dev) +{ + struct uniphier8250_priv *priv = dev_get_drvdata(dev); + struct uart_8250_port *up = serial8250_get_port(priv->line); + int ret; + + if (!uart_console(&up->port) || console_suspend_enabled) { + ret = clk_prepare_enable(priv->clk); + if (ret) + return ret; + } + + serial8250_resume_port(priv->line); + + return 0; +} + +static const struct dev_pm_ops uniphier_uart_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume) +}; + static const struct of_device_id uniphier_uart_match[] = { { .compatible = "socionext,uniphier-uart" }, { /* sentinel */ } @@ -283,6 +327,7 @@ static struct platform_driver uniphier_uart_platform_driver = { .driver = { .name = "uniphier-uart", .of_match_table = uniphier_uart_match, + .pm = &uniphier_uart_pm_ops, }, }; module_platform_driver(uniphier_uart_platform_driver); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index a1161ec0256f..a5c0ef1e7695 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -155,6 +155,17 @@ config SERIAL_8250_CS If unsure, say N. +config SERIAL_8250_MEN_MCB + tristate "MEN Z125 UART device support" + depends on MCB && SERIAL_8250 + help + This enables support for FPGA based UARTs found on many MEN + boards. This driver enables support for the Z125 UARTs. + + To compile this driver as a module, chose M here: the + module will be called 8250_men_mcb. + + config SERIAL_8250_NR_UARTS int "Maximum number of 8250/16550 serial ports" depends on SERIAL_8250 diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index a44a99a3e623..18751bc63a84 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the 8250 serial device drivers. # @@ -23,6 +24,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o +obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o obj-$(CONFIG_SERIAL_8250_OMAP) += 8250_omap.o diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 1f096e2bb398..b788fee54249 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1689,7 +1689,7 @@ config SERIAL_MVEBU_CONSOLE Otherwise, say 'N'. config SERIAL_OWL - bool "Actions Semi Owl serial port support" + tristate "Actions Semi Owl serial port support" depends on ARCH_ACTIONS || COMPILE_TEST select SERIAL_CORE help @@ -1705,7 +1705,7 @@ config SERIAL_OWL_CONSOLE default y help Say 'Y' here if you wish to use Actions Semiconductor S500/S900 UART - as the system console. Only earlycon is implemented currently. + as the system console. endmenu diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index fe88a75d9a59..842d185d697e 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the kernel serial device drivers. # diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 24180adb1cbb..9ec4b8d2879f 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -814,7 +814,7 @@ static int pl010_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pl010_dev_pm_ops, pl010_suspend, pl010_resume); -static struct amba_id pl010_ids[] = { +static const struct amba_id pl010_ids[] = { { .id = 0x00041010, .mask = 0x000fffff, diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 1888d168a41c..111e6a950779 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -128,7 +128,7 @@ static struct vendor_data vendor_arm = { .get_fifosize = get_fifosize_arm, }; -static struct vendor_data vendor_sbsa = { +static const struct vendor_data vendor_sbsa = { .reg_offset = pl011_std_offsets, .fr_busy = UART01x_FR_BUSY, .fr_dsr = UART01x_FR_DSR, @@ -143,7 +143,7 @@ static struct vendor_data vendor_sbsa = { }; #ifdef CONFIG_ACPI_SPCR_TABLE -static struct vendor_data vendor_qdt_qdf2400_e44 = { +static const struct vendor_data vendor_qdt_qdf2400_e44 = { .reg_offset = pl011_std_offsets, .fr_busy = UART011_FR_TXFE, .fr_dsr = UART01x_FR_DSR, @@ -2787,7 +2787,7 @@ static struct platform_driver arm_sbsa_uart_platform_driver = { }, }; -static struct amba_id pl011_ids[] = { +static const struct amba_id pl011_ids[] = { { .id = 0x00041011, .mask = 0x000fffff, diff --git a/drivers/tty/serial/amba-pl011.h b/drivers/tty/serial/amba-pl011.h index 411c60e1f9a4..077eb12a3472 100644 --- a/drivers/tty/serial/amba-pl011.h +++ b/drivers/tty/serial/amba-pl011.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef AMBA_PL011_H #define AMBA_PL011_H diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 75eb083b3361..dd60ed96a0ad 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -325,7 +325,7 @@ static int apbuart_verify_port(struct uart_port *port, return ret; } -static struct uart_ops grlib_apbuart_ops = { +static const struct uart_ops grlib_apbuart_ops = { .tx_empty = apbuart_tx_empty, .set_mctrl = apbuart_set_mctrl, .get_mctrl = apbuart_get_mctrl, diff --git a/drivers/tty/serial/apbuart.h b/drivers/tty/serial/apbuart.h index 5faf87c8d2bc..81baf007694f 100644 --- a/drivers/tty/serial/apbuart.h +++ b/drivers/tty/serial/apbuart.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __GRLIB_APBUART_H__ #define __GRLIB_APBUART_H__ diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c index 5ac06fcaa9c6..77fe306690c4 100644 --- a/drivers/tty/serial/arc_uart.c +++ b/drivers/tty/serial/arc_uart.c @@ -549,8 +549,8 @@ static struct console arc_console = { .data = &arc_uart_driver }; -static __init void arc_early_serial_write(struct console *con, const char *s, - unsigned int n) +static void arc_early_serial_write(struct console *con, const char *s, + unsigned int n) { struct earlycon_device *dev = con->data; diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 583c9a0c7ecc..8c48c3784831 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -507,9 +507,14 @@ static void bcm_uart_set_termios(struct uart_port *port, { unsigned int ctl, baud, quot, ier; unsigned long flags; + int tries; spin_lock_irqsave(&port->lock, flags); + /* Drain the hot tub fully before we power it off for the winter. */ + for (tries = 3; !bcm_uart_tx_empty(port) && tries; tries--) + mdelay(10); + /* disable uart while changing speed */ bcm_uart_disable(port); bcm_uart_flush(port); diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index f6bcc19c99d5..9ac142cfc1f1 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1123,7 +1123,7 @@ static void cpm_put_poll_char(struct uart_port *port, } #endif /* CONFIG_CONSOLE_POLL */ -static struct uart_ops cpm_uart_pops = { +static const struct uart_ops cpm_uart_pops = { .tx_empty = cpm_uart_tx_empty, .set_mctrl = cpm_uart_set_mctrl, .get_mctrl = cpm_uart_get_mctrl, diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h index 60c7e94cde1e..18ec0849918a 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Driver for CPM (SCC/SMC) serial ports * diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h index 51e651a69938..051a8509c3e5 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Driver for CPM (SCC/SMC) serial ports * diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 59a2a7e18b5a..1421804975e0 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Serial port driver for the ETRAX 100LX chip * diff --git a/drivers/tty/serial/crisv10.h b/drivers/tty/serial/crisv10.h index 15a52ee58251..79ba2bc95d3d 100644 --- a/drivers/tty/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * serial.h: Arch-dep definitions for the Etrax100 serial driver. * diff --git a/drivers/tty/serial/dz.h b/drivers/tty/serial/dz.h index faf169ed27b3..3b3e31954f24 100644 --- a/drivers/tty/serial/dz.h +++ b/drivers/tty/serial/dz.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * dz.h: Serial port driver for DECstations equipped * with the DZ chipset. diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c index c3651540e1ba..98928f082d87 100644 --- a/drivers/tty/serial/earlycon.c +++ b/drivers/tty/serial/earlycon.c @@ -220,7 +220,7 @@ static int __init param_setup_earlycon(char *buf) if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) { earlycon_init_is_deferred = true; return 0; - } else { + } else if (!buf) { return early_init_dt_scan_chosen_stdout(); } } @@ -282,7 +282,12 @@ int __init of_setup_earlycon(const struct earlycon_id *match, } } + val = of_get_flat_dt_prop(node, "current-speed", NULL); + if (val) + early_console_dev.baud = be32_to_cpu(*val); + if (options) { + early_console_dev.baud = simple_strtoul(options, NULL, 0); strlcpy(early_console_dev.options, options, sizeof(early_console_dev.options)); } diff --git a/drivers/tty/serial/etraxfs-uart.c b/drivers/tty/serial/etraxfs-uart.c index 2f80bc7e44fb..24bf6bfb29b4 100644 --- a/drivers/tty/serial/etraxfs-uart.c +++ b/drivers/tty/serial/etraxfs-uart.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index 898dcb091a27..f0252184291e 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -117,7 +117,7 @@ #define UARTSFIFO_TXOF 0x02 #define UARTSFIFO_RXUF 0x01 -/* 32-bit register defination */ +/* 32-bit register definition */ #define UARTBAUD 0x00 #define UARTSTAT 0x04 #define UARTCTRL 0x08 @@ -521,6 +521,57 @@ static int lpuart_poll_get_char(struct uart_port *port) return readb(port->membase + UARTDR); } +static int lpuart32_poll_init(struct uart_port *port) +{ + unsigned long flags; + struct lpuart_port *sport = container_of(port, struct lpuart_port, port); + u32 temp; + + sport->port.fifosize = 0; + + spin_lock_irqsave(&sport->port.lock, flags); + + /* Disable Rx & Tx */ + writel(0, sport->port.membase + UARTCTRL); + + temp = readl(sport->port.membase + UARTFIFO); + + /* Enable Rx and Tx FIFO */ + writel(temp | UARTFIFO_RXFE | UARTFIFO_TXFE, + sport->port.membase + UARTFIFO); + + /* flush Tx and Rx FIFO */ + writel(UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH, + sport->port.membase + UARTFIFO); + + /* explicitly clear RDRF */ + if (readl(sport->port.membase + UARTSTAT) & UARTSTAT_RDRF) { + readl(sport->port.membase + UARTDATA); + writel(UARTFIFO_RXUF, sport->port.membase + UARTFIFO); + } + + /* Enable Rx and Tx */ + writel(UARTCTRL_RE | UARTCTRL_TE, sport->port.membase + UARTCTRL); + spin_unlock_irqrestore(&sport->port.lock, flags); + + return 0; +} + +static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c) +{ + while (!(readl(port->membase + UARTSTAT) & UARTSTAT_TDRE)) + barrier(); + + writel(c, port->membase + UARTDATA); +} + +static int lpuart32_poll_get_char(struct uart_port *port) +{ + if (!(readl(port->membase + UARTSTAT) & UARTSTAT_RDRF)) + return NO_POLL_CHAR; + + return readl(port->membase + UARTDATA); +} #endif static inline void lpuart_transmit_buffer(struct lpuart_port *sport) @@ -1025,6 +1076,11 @@ static int lpuart_config_rs485(struct uart_port *port, ~(UARTMODEM_TXRTSPOL | UARTMODEM_TXRTSE); writeb(modem, sport->port.membase + UARTMODEM); + /* clear unsupported configurations */ + rs485->delay_rts_before_send = 0; + rs485->delay_rts_after_send = 0; + rs485->flags &= ~SER_RS485_RX_DURING_TX; + if (rs485->flags & SER_RS485_ENABLED) { /* Enable auto RS-485 RTS mode */ modem |= UARTMODEM_TXRTSE; @@ -1220,7 +1276,6 @@ static void rx_dma_timer_init(struct lpuart_port *sport) static int lpuart_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - int ret; unsigned long flags; unsigned char temp; @@ -1235,11 +1290,6 @@ static int lpuart_startup(struct uart_port *port) sport->rxfifo_size = 0x1 << (((temp >> UARTPFIFO_RXSIZE_OFF) & UARTPFIFO_FIFOSIZE_MASK) + 1); - ret = devm_request_irq(port->dev, port->irq, lpuart_int, 0, - DRIVER_NAME, sport); - if (ret) - return ret; - spin_lock_irqsave(&sport->port.lock, flags); lpuart_setup_watermark(sport); @@ -1277,7 +1327,6 @@ static int lpuart_startup(struct uart_port *port) static int lpuart32_startup(struct uart_port *port) { struct lpuart_port *sport = container_of(port, struct lpuart_port, port); - int ret; unsigned long flags; unsigned long temp; @@ -1290,11 +1339,6 @@ static int lpuart32_startup(struct uart_port *port) sport->rxfifo_size = 0x1 << (((temp >> UARTFIFO_RXSIZE_OFF) & UARTFIFO_FIFOSIZE_MASK) - 1); - ret = devm_request_irq(port->dev, port->irq, lpuart32_int, 0, - DRIVER_NAME, sport); - if (ret) - return ret; - spin_lock_irqsave(&sport->port.lock, flags); lpuart32_setup_watermark(sport); @@ -1324,8 +1368,6 @@ static void lpuart_shutdown(struct uart_port *port) spin_unlock_irqrestore(&port->lock, flags); - devm_free_irq(port->dev, port->irq, sport); - if (sport->lpuart_dma_rx_use) { del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); @@ -1344,7 +1386,6 @@ static void lpuart_shutdown(struct uart_port *port) static void lpuart32_shutdown(struct uart_port *port) { - struct lpuart_port *sport = container_of(port, struct lpuart_port, port); unsigned long temp; unsigned long flags; @@ -1357,8 +1398,6 @@ static void lpuart32_shutdown(struct uart_port *port) lpuart32_write(port, temp, UARTCTRL); spin_unlock_irqrestore(&port->lock, flags); - - devm_free_irq(port->dev, port->irq, sport); } static void @@ -1782,6 +1821,11 @@ static const struct uart_ops lpuart32_pops = { .config_port = lpuart_config_port, .verify_port = lpuart_verify_port, .flush_buffer = lpuart_flush_buffer, +#if defined(CONFIG_CONSOLE_POLL) + .poll_init = lpuart32_poll_init, + .poll_get_char = lpuart32_poll_get_char, + .poll_put_char = lpuart32_poll_put_char, +#endif }; static struct lpuart_port *lpuart_ports[UART_NR]; @@ -2151,16 +2195,22 @@ static int lpuart_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &sport->port); - if (lpuart_is_32(sport)) + if (lpuart_is_32(sport)) { lpuart_reg.cons = LPUART32_CONSOLE; - else + ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0, + DRIVER_NAME, sport); + } else { lpuart_reg.cons = LPUART_CONSOLE; + ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0, + DRIVER_NAME, sport); + } + + if (ret) + goto failed_irq_request; ret = uart_add_one_port(&lpuart_reg, &sport->port); - if (ret) { - clk_disable_unprepare(sport->clk); - return ret; - } + if (ret) + goto failed_attach_port; sport->dma_tx_chan = dma_request_slave_channel(sport->port.dev, "tx"); if (!sport->dma_tx_chan) @@ -2179,6 +2229,11 @@ static int lpuart_probe(struct platform_device *pdev) } return 0; + +failed_attach_port: +failed_irq_request: + clk_disable_unprepare(sport->clk); + return ret; } static int lpuart_remove(struct platform_device *pdev) @@ -2203,6 +2258,7 @@ static int lpuart_suspend(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); unsigned long temp; + bool irq_wake; if (lpuart_is_32(sport)) { /* disable Rx/Tx and interrupts */ @@ -2218,6 +2274,9 @@ static int lpuart_suspend(struct device *dev) uart_suspend_port(&lpuart_reg, &sport->port); + /* uart_suspend_port() might set wakeup flag */ + irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); + if (sport->lpuart_dma_rx_use) { /* * EDMA driver during suspend will forcefully release any @@ -2226,7 +2285,7 @@ static int lpuart_suspend(struct device *dev) * cannot resume as as expected, hence gracefully release the * Rx DMA path before suspend and start Rx DMA path on resume. */ - if (sport->port.irq_wake) { + if (irq_wake) { del_timer_sync(&sport->lpuart_timer); lpuart_dma_rx_free(&sport->port); } @@ -2241,7 +2300,7 @@ static int lpuart_suspend(struct device *dev) dmaengine_terminate_all(sport->dma_tx_chan); } - if (sport->port.suspended && !sport->port.irq_wake) + if (sport->port.suspended && !irq_wake) clk_disable_unprepare(sport->clk); return 0; @@ -2250,9 +2309,10 @@ static int lpuart_suspend(struct device *dev) static int lpuart_resume(struct device *dev) { struct lpuart_port *sport = dev_get_drvdata(dev); + bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq)); unsigned long temp; - if (sport->port.suspended && !sport->port.irq_wake) + if (sport->port.suspended && !irq_wake) clk_prepare_enable(sport->clk); if (lpuart_is_32(sport)) { @@ -2269,7 +2329,7 @@ static int lpuart_resume(struct device *dev) } if (sport->lpuart_dma_rx_use) { - if (sport->port.irq_wake) { + if (irq_wake) { if (!lpuart_start_rx_dma(sport)) rx_dma_timer_init(sport); else diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 80934e7bd67f..dfeff3951f93 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -226,7 +226,6 @@ struct imx_port { dma_cookie_t rx_cookie; unsigned int tx_bytes; unsigned int dma_tx_nents; - wait_queue_head_t dma_wait; unsigned int saved_reg[10]; bool context_saved; }; @@ -458,7 +457,10 @@ static inline void imx_transmit_buffer(struct imx_port *sport) } } - while (!uart_circ_empty(xmit) && !sport->dma_is_txing && + if (sport->dma_is_txing) + return; + + while (!uart_circ_empty(xmit) && !(readl(sport->port.membase + uts_reg(sport)) & UTS_TXFULL)) { /* send xmit->buf[xmit->tail] * out the port here */ @@ -498,20 +500,12 @@ static void dma_tx_callback(void *data) sport->dma_is_txing = 0; - spin_unlock_irqrestore(&sport->port.lock, flags); - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); - if (waitqueue_active(&sport->dma_wait)) { - wake_up(&sport->dma_wait); - dev_dbg(sport->port.dev, "exit in %s.\n", __func__); - return; - } - - spin_lock_irqsave(&sport->port.lock, flags); if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port)) imx_dma_tx(sport); + spin_unlock_irqrestore(&sport->port.lock, flags); } @@ -1208,8 +1202,6 @@ static void imx_enable_dma(struct imx_port *sport) { unsigned long temp; - init_waitqueue_head(&sport->dma_wait); - /* set UCR1 */ temp = readl(sport->port.membase + UCR1); temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN; @@ -2332,6 +2324,7 @@ static int imx_serial_port_suspend(struct device *dev) serial_imx_enable_wakeup(sport, true); uart_suspend_port(&imx_reg, &sport->port); + disable_irq(sport->port.irq); /* Needed to enable clock in suspend_noirq */ return clk_prepare(sport->clk_ipg); @@ -2346,6 +2339,7 @@ static int imx_serial_port_resume(struct device *dev) serial_imx_enable_wakeup(sport, false); uart_resume_port(&imx_reg, &sport->port); + enable_irq(sport->port.irq); clk_unprepare(sport->clk_ipg); diff --git a/drivers/tty/serial/ip22zilog.h b/drivers/tty/serial/ip22zilog.h index a59a9a8341d2..b52801fe2d0d 100644 --- a/drivers/tty/serial/ip22zilog.h +++ b/drivers/tty/serial/ip22zilog.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _IP22_ZILOG_H #define _IP22_ZILOG_H diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index a119f11bf2f4..102d499814ac 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -304,7 +304,7 @@ static void jsm_remove_one(struct pci_dev *pdev) kfree(brd); } -static struct pci_device_id jsm_pci_tbl[] = { +static const struct pci_device_id jsm_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9), 0, 0, 0 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2DB9PRI), 0, 0, 1 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 }, diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 218b7118e85d..5b3bd9511993 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c @@ -854,7 +854,7 @@ m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } -static struct uart_ops m32r_sio_pops = { +static const struct uart_ops m32r_sio_pops = { .tx_empty = m32r_sio_tx_empty, .set_mctrl = m32r_sio_set_mctrl, .get_mctrl = m32r_sio_get_mctrl, diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c index 42e4a4c7597f..07c0f98be3ac 100644 --- a/drivers/tty/serial/meson_uart.c +++ b/drivers/tty/serial/meson_uart.c @@ -424,7 +424,7 @@ static void meson_uart_config_port(struct uart_port *port, int flags) } } -static struct uart_ops meson_uart_ops = { +static const struct uart_ops meson_uart_ops = { .set_mctrl = meson_uart_set_mctrl, .get_mctrl = meson_uart_get_mctrl, .tx_empty = meson_uart_tx_empty, diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 3970d6a9aaca..791c4c74f6d6 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1347,7 +1347,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) } -static struct uart_ops mpc52xx_uart_ops = { +static const struct uart_ops mpc52xx_uart_ops = { .tx_empty = mpc52xx_uart_tx_empty, .set_mctrl = mpc52xx_uart_set_mctrl, .get_mctrl = mpc52xx_uart_get_mctrl, @@ -1634,8 +1634,8 @@ mpc52xx_console_setup(struct console *co, char *options) return -EINVAL; } - pr_debug("Console on ttyPSC%x is %s\n", - co->index, mpc52xx_uart_nodes[co->index]->full_name); + pr_debug("Console on ttyPSC%x is %pOF\n", + co->index, mpc52xx_uart_nodes[co->index]); /* Fetch register locations */ ret = of_address_to_resource(np, 0, &res); @@ -1755,8 +1755,8 @@ static int mpc52xx_uart_of_probe(struct platform_device *op) break; if (idx >= MPC52xx_PSC_MAXNUM) return -EINVAL; - pr_debug("Found %s assigned to ttyPSC%x\n", - mpc52xx_uart_nodes[idx]->full_name, idx); + pr_debug("Found %pOF assigned to ttyPSC%x\n", + mpc52xx_uart_nodes[idx], idx); /* set the uart clock to the input clock of the psc, the different * prescalers are taken into account in the set_baudrate() methods @@ -1881,8 +1881,8 @@ mpc52xx_uart_of_enumerate(void) for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { if (mpc52xx_uart_nodes[i]) - pr_debug("%s assigned to ttyPSC%x\n", - mpc52xx_uart_nodes[i]->full_name, i); + pr_debug("%pOF assigned to ttyPSC%x\n", + mpc52xx_uart_nodes[i], i); } } diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 6788e7532dff..1db79ee8a886 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1175,11 +1175,6 @@ static int msm_startup(struct uart_port *port) snprintf(msm_port->name, sizeof(msm_port->name), "msm_serial%d", port->line); - ret = request_irq(port->irq, msm_uart_irq, IRQF_TRIGGER_HIGH, - msm_port->name, port); - if (unlikely(ret)) - return ret; - msm_init_clock(port); if (likely(port->fifosize > 12)) @@ -1206,7 +1201,21 @@ static int msm_startup(struct uart_port *port) msm_request_rx_dma(msm_port, msm_port->uart.mapbase); } + ret = request_irq(port->irq, msm_uart_irq, IRQF_TRIGGER_HIGH, + msm_port->name, port); + if (unlikely(ret)) + goto err_irq; + return 0; + +err_irq: + if (msm_port->is_uartdm) + msm_release_dma(msm_port); + + clk_disable_unprepare(msm_port->pclk); + clk_disable_unprepare(msm_port->clk); + + return ret; } static void msm_shutdown(struct uart_port *port) diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index 8a4be4b73723..2bff69e70e4b 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c @@ -427,7 +427,7 @@ static struct console mux_console = { #define MUX_CONSOLE NULL #endif -static struct uart_ops mux_pops = { +static const struct uart_ops mux_pops = { .tx_empty = mux_tx_empty, .set_mctrl = mux_set_mctrl, .get_mctrl = mux_get_mctrl, @@ -503,7 +503,7 @@ static int __init mux_probe(struct parisc_device *dev) return 0; } -static int mux_remove(struct parisc_device *dev) +static int __exit mux_remove(struct parisc_device *dev) { int i, j; int port_count = (long)dev_get_drvdata(&dev->dev); @@ -536,13 +536,13 @@ static int mux_remove(struct parisc_device *dev) * This table only contains the parisc_device_id of known builtin mux * devices. All other mux cards will be detected by the generic mux_tbl. */ -static struct parisc_device_id builtin_mux_tbl[] = { +static const struct parisc_device_id builtin_mux_tbl[] __initconst = { { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */ { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */ { 0, } }; -static struct parisc_device_id mux_tbl[] = { +static const struct parisc_device_id mux_tbl[] __initconst = { { HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D }, { 0, } }; @@ -550,18 +550,18 @@ static struct parisc_device_id mux_tbl[] = { MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl); MODULE_DEVICE_TABLE(parisc, mux_tbl); -static struct parisc_driver builtin_serial_mux_driver = { +static struct parisc_driver builtin_serial_mux_driver __refdata = { .name = "builtin_serial_mux", .id_table = builtin_mux_tbl, .probe = mux_probe, - .remove = mux_remove, + .remove = __exit_p(mux_remove), }; -static struct parisc_driver serial_mux_driver = { +static struct parisc_driver serial_mux_driver __refdata = { .name = "serial_mux", .id_table = mux_tbl, .probe = mux_probe, - .remove = mux_remove, + .remove = __exit_p(mux_remove), }; /** diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 1ea05ac57aa7..7754053deeda 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1235,21 +1235,20 @@ out: #ifdef CONFIG_SERIAL_OMAP_CONSOLE #ifdef CONFIG_SERIAL_EARLYCON -static unsigned int __init omap_serial_early_in(struct uart_port *port, - int offset) +static unsigned int omap_serial_early_in(struct uart_port *port, int offset) { offset <<= port->regshift; return readw(port->membase + offset); } -static void __init omap_serial_early_out(struct uart_port *port, int offset, - int value) +static void omap_serial_early_out(struct uart_port *port, int offset, + int value) { offset <<= port->regshift; writew(value, port->membase + offset); } -static void __init omap_serial_early_putc(struct uart_port *port, int c) +static void omap_serial_early_putc(struct uart_port *port, int c) { unsigned int status; @@ -1262,8 +1261,8 @@ static void __init omap_serial_early_putc(struct uart_port *port, int c) omap_serial_early_out(port, UART_TX, c); } -static void __init early_omap_serial_write(struct console *console, - const char *s, unsigned int count) +static void early_omap_serial_write(struct console *console, const char *s, + unsigned int count) { struct earlycon_device *device = console->data; struct uart_port *port = &device->port; diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index 1b8008797a1b..b9c859365334 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -20,6 +20,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -28,22 +29,66 @@ #include #include #include +#include +#include + +#define OWL_UART_PORT_NUM 7 +#define OWL_UART_DEV_NAME "ttyOWL" #define OWL_UART_CTL 0x000 +#define OWL_UART_RXDAT 0x004 #define OWL_UART_TXDAT 0x008 #define OWL_UART_STAT 0x00c +#define OWL_UART_CTL_DWLS_MASK GENMASK(1, 0) +#define OWL_UART_CTL_DWLS_5BITS (0x0 << 0) +#define OWL_UART_CTL_DWLS_6BITS (0x1 << 0) +#define OWL_UART_CTL_DWLS_7BITS (0x2 << 0) +#define OWL_UART_CTL_DWLS_8BITS (0x3 << 0) +#define OWL_UART_CTL_STPS_2BITS BIT(2) +#define OWL_UART_CTL_PRS_MASK GENMASK(6, 4) +#define OWL_UART_CTL_PRS_NONE (0x0 << 4) +#define OWL_UART_CTL_PRS_ODD (0x4 << 4) +#define OWL_UART_CTL_PRS_MARK (0x5 << 4) +#define OWL_UART_CTL_PRS_EVEN (0x6 << 4) +#define OWL_UART_CTL_PRS_SPACE (0x7 << 4) +#define OWL_UART_CTL_AFE BIT(12) #define OWL_UART_CTL_TRFS_TX BIT(14) #define OWL_UART_CTL_EN BIT(15) +#define OWL_UART_CTL_RXDE BIT(16) +#define OWL_UART_CTL_TXDE BIT(17) #define OWL_UART_CTL_RXIE BIT(18) #define OWL_UART_CTL_TXIE BIT(19) +#define OWL_UART_CTL_LBEN BIT(20) #define OWL_UART_STAT_RIP BIT(0) #define OWL_UART_STAT_TIP BIT(1) +#define OWL_UART_STAT_RXER BIT(2) +#define OWL_UART_STAT_TFER BIT(3) +#define OWL_UART_STAT_RXST BIT(4) +#define OWL_UART_STAT_RFEM BIT(5) #define OWL_UART_STAT_TFFU BIT(6) -#define OWL_UART_STAT_TRFL_MASK (0x1f << 11) +#define OWL_UART_STAT_CTSS BIT(7) +#define OWL_UART_STAT_RTSS BIT(8) +#define OWL_UART_STAT_TFES BIT(10) +#define OWL_UART_STAT_TRFL_MASK GENMASK(16, 11) #define OWL_UART_STAT_UTBB BIT(17) +static struct uart_driver owl_uart_driver; + +struct owl_uart_info { + unsigned int tx_fifosize; +}; + +struct owl_uart_port { + struct uart_port port; + struct clk *clk; +}; + +#define to_owl_uart_port(prt) container_of(prt, struct owl_uart_port, prt) + +static struct owl_uart_port *owl_uart_ports[OWL_UART_PORT_NUM]; + static inline void owl_uart_write(struct uart_port *port, u32 val, unsigned int off) { writel(val, port->membase + off); @@ -54,6 +99,397 @@ static inline u32 owl_uart_read(struct uart_port *port, unsigned int off) return readl(port->membase + off); } +static void owl_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + u32 ctl; + + ctl = owl_uart_read(port, OWL_UART_CTL); + + if (mctrl & TIOCM_LOOP) + ctl |= OWL_UART_CTL_LBEN; + else + ctl &= ~OWL_UART_CTL_LBEN; + + owl_uart_write(port, ctl, OWL_UART_CTL); +} + +static unsigned int owl_uart_get_mctrl(struct uart_port *port) +{ + unsigned int mctrl = TIOCM_CAR | TIOCM_DSR; + u32 stat, ctl; + + ctl = owl_uart_read(port, OWL_UART_CTL); + stat = owl_uart_read(port, OWL_UART_STAT); + if (stat & OWL_UART_STAT_RTSS) + mctrl |= TIOCM_RTS; + if ((stat & OWL_UART_STAT_CTSS) || !(ctl & OWL_UART_CTL_AFE)) + mctrl |= TIOCM_CTS; + return mctrl; +} + +static unsigned int owl_uart_tx_empty(struct uart_port *port) +{ + unsigned long flags; + u32 val; + unsigned int ret; + + spin_lock_irqsave(&port->lock, flags); + + val = owl_uart_read(port, OWL_UART_STAT); + ret = (val & OWL_UART_STAT_TFES) ? TIOCSER_TEMT : 0; + + spin_unlock_irqrestore(&port->lock, flags); + + return ret; +} + +static void owl_uart_stop_rx(struct uart_port *port) +{ + u32 val; + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~(OWL_UART_CTL_RXIE | OWL_UART_CTL_RXDE); + owl_uart_write(port, val, OWL_UART_CTL); + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_RIP; + owl_uart_write(port, val, OWL_UART_STAT); +} + +static void owl_uart_stop_tx(struct uart_port *port) +{ + u32 val; + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_TXDE); + owl_uart_write(port, val, OWL_UART_CTL); + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_TIP; + owl_uart_write(port, val, OWL_UART_STAT); +} + +static void owl_uart_start_tx(struct uart_port *port) +{ + u32 val; + + if (uart_tx_stopped(port)) { + owl_uart_stop_tx(port); + return; + } + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_TIP; + owl_uart_write(port, val, OWL_UART_STAT); + + val = owl_uart_read(port, OWL_UART_CTL); + val |= OWL_UART_CTL_TXIE; + owl_uart_write(port, val, OWL_UART_CTL); +} + +static void owl_uart_send_chars(struct uart_port *port) +{ + struct circ_buf *xmit = &port->state->xmit; + unsigned int ch; + + if (uart_tx_stopped(port)) + return; + + if (port->x_char) { + while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) + cpu_relax(); + owl_uart_write(port, port->x_char, OWL_UART_TXDAT); + port->icount.tx++; + port->x_char = 0; + } + + while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) { + if (uart_circ_empty(xmit)) + break; + + ch = xmit->buf[xmit->tail]; + owl_uart_write(port, ch, OWL_UART_TXDAT); + xmit->tail = (xmit->tail + 1) & (SERIAL_XMIT_SIZE - 1); + port->icount.tx++; + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (uart_circ_empty(xmit)) + owl_uart_stop_tx(port); +} + +static void owl_uart_receive_chars(struct uart_port *port) +{ + u32 stat, val; + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~OWL_UART_CTL_TRFS_TX; + owl_uart_write(port, val, OWL_UART_CTL); + + stat = owl_uart_read(port, OWL_UART_STAT); + while (!(stat & OWL_UART_STAT_RFEM)) { + char flag = TTY_NORMAL; + + if (stat & OWL_UART_STAT_RXER) + port->icount.overrun++; + + if (stat & OWL_UART_STAT_RXST) { + /* We are not able to distinguish the error type. */ + port->icount.brk++; + port->icount.frame++; + + stat &= port->read_status_mask; + if (stat & OWL_UART_STAT_RXST) + flag = TTY_PARITY; + } else + port->icount.rx++; + + val = owl_uart_read(port, OWL_UART_RXDAT); + val &= 0xff; + + if ((stat & port->ignore_status_mask) == 0) + tty_insert_flip_char(&port->state->port, val, flag); + + stat = owl_uart_read(port, OWL_UART_STAT); + } + + spin_unlock(&port->lock); + tty_flip_buffer_push(&port->state->port); + spin_lock(&port->lock); +} + +static irqreturn_t owl_uart_irq(int irq, void *dev_id) +{ + struct uart_port *port = dev_id; + unsigned long flags; + u32 stat; + + spin_lock_irqsave(&port->lock, flags); + + stat = owl_uart_read(port, OWL_UART_STAT); + + if (stat & OWL_UART_STAT_RIP) + owl_uart_receive_chars(port); + + if (stat & OWL_UART_STAT_TIP) + owl_uart_send_chars(port); + + stat = owl_uart_read(port, OWL_UART_STAT); + stat |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP; + owl_uart_write(port, stat, OWL_UART_STAT); + + spin_unlock_irqrestore(&port->lock, flags); + + return IRQ_HANDLED; +} + +static void owl_uart_shutdown(struct uart_port *port) +{ + u32 val; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + val = owl_uart_read(port, OWL_UART_CTL); + val &= ~(OWL_UART_CTL_TXIE | OWL_UART_CTL_RXIE + | OWL_UART_CTL_TXDE | OWL_UART_CTL_RXDE | OWL_UART_CTL_EN); + owl_uart_write(port, val, OWL_UART_CTL); + + spin_unlock_irqrestore(&port->lock, flags); + + free_irq(port->irq, port); +} + +static int owl_uart_startup(struct uart_port *port) +{ + u32 val; + unsigned long flags; + int ret; + + ret = request_irq(port->irq, owl_uart_irq, IRQF_TRIGGER_HIGH, + "owl-uart", port); + if (ret) + return ret; + + spin_lock_irqsave(&port->lock, flags); + + val = owl_uart_read(port, OWL_UART_STAT); + val |= OWL_UART_STAT_RIP | OWL_UART_STAT_TIP + | OWL_UART_STAT_RXER | OWL_UART_STAT_TFER | OWL_UART_STAT_RXST; + owl_uart_write(port, val, OWL_UART_STAT); + + val = owl_uart_read(port, OWL_UART_CTL); + val |= OWL_UART_CTL_RXIE | OWL_UART_CTL_TXIE; + val |= OWL_UART_CTL_EN; + owl_uart_write(port, val, OWL_UART_CTL); + + spin_unlock_irqrestore(&port->lock, flags); + + return 0; +} + +static void owl_uart_change_baudrate(struct owl_uart_port *owl_port, + unsigned long baud) +{ + clk_set_rate(owl_port->clk, baud * 8); +} + +static void owl_uart_set_termios(struct uart_port *port, + struct ktermios *termios, + struct ktermios *old) +{ + struct owl_uart_port *owl_port = to_owl_uart_port(port); + unsigned int baud; + u32 ctl; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + ctl = owl_uart_read(port, OWL_UART_CTL); + + ctl &= ~OWL_UART_CTL_DWLS_MASK; + switch (termios->c_cflag & CSIZE) { + case CS5: + ctl |= OWL_UART_CTL_DWLS_5BITS; + break; + case CS6: + ctl |= OWL_UART_CTL_DWLS_6BITS; + break; + case CS7: + ctl |= OWL_UART_CTL_DWLS_7BITS; + break; + case CS8: + default: + ctl |= OWL_UART_CTL_DWLS_8BITS; + break; + } + + if (termios->c_cflag & CSTOPB) + ctl |= OWL_UART_CTL_STPS_2BITS; + else + ctl &= ~OWL_UART_CTL_STPS_2BITS; + + ctl &= ~OWL_UART_CTL_PRS_MASK; + if (termios->c_cflag & PARENB) { + if (termios->c_cflag & CMSPAR) { + if (termios->c_cflag & PARODD) + ctl |= OWL_UART_CTL_PRS_MARK; + else + ctl |= OWL_UART_CTL_PRS_SPACE; + } else if (termios->c_cflag & PARODD) + ctl |= OWL_UART_CTL_PRS_ODD; + else + ctl |= OWL_UART_CTL_PRS_EVEN; + } else + ctl |= OWL_UART_CTL_PRS_NONE; + + if (termios->c_cflag & CRTSCTS) + ctl |= OWL_UART_CTL_AFE; + else + ctl &= ~OWL_UART_CTL_AFE; + + owl_uart_write(port, ctl, OWL_UART_CTL); + + baud = uart_get_baud_rate(port, termios, old, 9600, 3200000); + owl_uart_change_baudrate(owl_port, baud); + + /* Don't rewrite B0 */ + if (tty_termios_baud_rate(termios)) + tty_termios_encode_baud_rate(termios, baud, baud); + + port->read_status_mask |= OWL_UART_STAT_RXER; + if (termios->c_iflag & INPCK) + port->read_status_mask |= OWL_UART_STAT_RXST; + + uart_update_timeout(port, termios->c_cflag, baud); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static void owl_uart_release_port(struct uart_port *port) +{ + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return; + + if (port->flags & UPF_IOREMAP) { + devm_release_mem_region(port->dev, port->mapbase, + resource_size(res)); + devm_iounmap(port->dev, port->membase); + port->membase = NULL; + } +} + +static int owl_uart_request_port(struct uart_port *port) +{ + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENXIO; + + if (!devm_request_mem_region(port->dev, port->mapbase, + resource_size(res), dev_name(port->dev))) + return -EBUSY; + + if (port->flags & UPF_IOREMAP) { + port->membase = devm_ioremap_nocache(port->dev, port->mapbase, + resource_size(res)); + if (!port->membase) + return -EBUSY; + } + + return 0; +} + +static const char *owl_uart_type(struct uart_port *port) +{ + return (port->type == PORT_OWL) ? "owl-uart" : NULL; +} + +static int owl_uart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + if (port->type != PORT_OWL) + return -EINVAL; + + if (port->irq != ser->irq) + return -EINVAL; + + return 0; +} + +static void owl_uart_config_port(struct uart_port *port, int flags) +{ + if (flags & UART_CONFIG_TYPE) { + port->type = PORT_OWL; + owl_uart_request_port(port); + } +} + +static const struct uart_ops owl_uart_ops = { + .set_mctrl = owl_uart_set_mctrl, + .get_mctrl = owl_uart_get_mctrl, + .tx_empty = owl_uart_tx_empty, + .start_tx = owl_uart_start_tx, + .stop_rx = owl_uart_stop_rx, + .stop_tx = owl_uart_stop_tx, + .startup = owl_uart_startup, + .shutdown = owl_uart_shutdown, + .set_termios = owl_uart_set_termios, + .type = owl_uart_type, + .config_port = owl_uart_config_port, + .request_port = owl_uart_request_port, + .release_port = owl_uart_release_port, + .verify_port = owl_uart_verify_port, +}; + #ifdef CONFIG_SERIAL_OWL_CONSOLE static void owl_console_putchar(struct uart_port *port, int ch) @@ -110,6 +546,57 @@ static void owl_uart_port_write(struct uart_port *port, const char *s, local_irq_restore(flags); } +static void owl_uart_console_write(struct console *co, const char *s, + u_int count) +{ + struct owl_uart_port *owl_port; + + owl_port = owl_uart_ports[co->index]; + if (!owl_port) + return; + + owl_uart_port_write(&owl_port->port, s, count); +} + +static int owl_uart_console_setup(struct console *co, char *options) +{ + struct owl_uart_port *owl_port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= OWL_UART_PORT_NUM) + return -EINVAL; + + owl_port = owl_uart_ports[co->index]; + if (!owl_port || !owl_port->port.membase) + return -ENODEV; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + return uart_set_options(&owl_port->port, co, baud, parity, bits, flow); +} + +static struct console owl_uart_console = { + .name = OWL_UART_DEV_NAME, + .write = owl_uart_console_write, + .device = uart_console_device, + .setup = owl_uart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &owl_uart_driver, +}; + +static int __init owl_uart_console_init(void) +{ + register_console(&owl_uart_console); + + return 0; +} +console_initcall(owl_uart_console_init); + static void owl_uart_early_console_write(struct console *co, const char *s, u_int count) @@ -132,4 +619,148 @@ owl_uart_early_console_setup(struct earlycon_device *device, const char *opt) OF_EARLYCON_DECLARE(owl, "actions,owl-uart", owl_uart_early_console_setup); -#endif /* CONFIG_SERIAL_OWL_CONSOLE */ +#define OWL_UART_CONSOLE (&owl_uart_console) +#else +#define OWL_UART_CONSOLE NULL +#endif + +static struct uart_driver owl_uart_driver = { + .owner = THIS_MODULE, + .driver_name = "owl-uart", + .dev_name = OWL_UART_DEV_NAME, + .nr = OWL_UART_PORT_NUM, + .cons = OWL_UART_CONSOLE, +}; + +static const struct owl_uart_info owl_s500_info = { + .tx_fifosize = 16, +}; + +static const struct owl_uart_info owl_s900_info = { + .tx_fifosize = 32, +}; + +static const struct of_device_id owl_uart_dt_matches[] = { + { .compatible = "actions,s500-uart", .data = &owl_s500_info }, + { .compatible = "actions,s900-uart", .data = &owl_s900_info }, + { } +}; +MODULE_DEVICE_TABLE(of, owl_uart_dt_matches); + +static int owl_uart_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct owl_uart_info *info = NULL; + struct resource *res_mem; + struct owl_uart_port *owl_port; + int ret, irq; + + if (pdev->dev.of_node) { + pdev->id = of_alias_get_id(pdev->dev.of_node, "serial"); + match = of_match_node(owl_uart_dt_matches, pdev->dev.of_node); + if (match) + info = match->data; + } + + if (pdev->id < 0 || pdev->id >= OWL_UART_PORT_NUM) { + dev_err(&pdev->dev, "id %d out of range\n", pdev->id); + return -EINVAL; + } + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_mem) { + dev_err(&pdev->dev, "could not get mem\n"); + return -ENODEV; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "could not get irq\n"); + return irq; + } + + if (owl_uart_ports[pdev->id]) { + dev_err(&pdev->dev, "port %d already allocated\n", pdev->id); + return -EBUSY; + } + + owl_port = devm_kzalloc(&pdev->dev, sizeof(*owl_port), GFP_KERNEL); + if (!owl_port) + return -ENOMEM; + + owl_port->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(owl_port->clk)) { + dev_err(&pdev->dev, "could not get clk\n"); + return PTR_ERR(owl_port->clk); + } + + owl_port->port.dev = &pdev->dev; + owl_port->port.line = pdev->id; + owl_port->port.type = PORT_OWL; + owl_port->port.iotype = UPIO_MEM; + owl_port->port.mapbase = res_mem->start; + owl_port->port.irq = irq; + owl_port->port.uartclk = clk_get_rate(owl_port->clk); + if (owl_port->port.uartclk == 0) { + dev_err(&pdev->dev, "clock rate is zero\n"); + return -EINVAL; + } + owl_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_LOW_LATENCY; + owl_port->port.x_char = 0; + owl_port->port.fifosize = (info) ? info->tx_fifosize : 16; + owl_port->port.ops = &owl_uart_ops; + + owl_uart_ports[pdev->id] = owl_port; + platform_set_drvdata(pdev, owl_port); + + ret = uart_add_one_port(&owl_uart_driver, &owl_port->port); + if (ret) + owl_uart_ports[pdev->id] = NULL; + + return ret; +} + +static int owl_uart_remove(struct platform_device *pdev) +{ + struct owl_uart_port *owl_port = platform_get_drvdata(pdev); + + uart_remove_one_port(&owl_uart_driver, &owl_port->port); + owl_uart_ports[pdev->id] = NULL; + + return 0; +} + +static struct platform_driver owl_uart_platform_driver = { + .probe = owl_uart_probe, + .remove = owl_uart_remove, + .driver = { + .name = "owl-uart", + .of_match_table = owl_uart_dt_matches, + }, +}; + +static int __init owl_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&owl_uart_driver); + if (ret) + return ret; + + ret = platform_driver_register(&owl_uart_platform_driver); + if (ret) + uart_unregister_driver(&owl_uart_driver); + + return ret; +} + +static void __init owl_uart_exit(void) +{ + platform_driver_unregister(&owl_uart_platform_driver); + uart_unregister_driver(&owl_uart_driver); +} + +module_init(owl_uart_init); +module_exit(owl_uart_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index d3796dc26fa9..d9123f995705 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -46,11 +46,6 @@ enum { PCH_UART_HANDLED_LS_INT_SHIFT, }; -enum { - PCH_UART_8LINE, - PCH_UART_2LINE, -}; - #define PCH_UART_DRIVER_DEVICE "ttyPCH" /* Set the max number of UART port @@ -267,7 +262,7 @@ struct eg20t_port { /** * struct pch_uart_driver_data - private data structure for UART-DMA - * @port_type: The number of DMA channel + * @port_type: The type of UART port * @line_no: UART port line number (0, 1, 2...) */ struct pch_uart_driver_data { @@ -290,17 +285,17 @@ enum pch_uart_num_t { }; static struct pch_uart_driver_data drv_dat[] = { - [pch_et20t_uart0] = {PCH_UART_8LINE, 0}, - [pch_et20t_uart1] = {PCH_UART_2LINE, 1}, - [pch_et20t_uart2] = {PCH_UART_2LINE, 2}, - [pch_et20t_uart3] = {PCH_UART_2LINE, 3}, - [pch_ml7213_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7213_uart1] = {PCH_UART_2LINE, 1}, - [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, - [pch_ml7223_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, - [pch_ml7831_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, + [pch_et20t_uart0] = {PORT_PCH_8LINE, 0}, + [pch_et20t_uart1] = {PORT_PCH_2LINE, 1}, + [pch_et20t_uart2] = {PORT_PCH_2LINE, 2}, + [pch_et20t_uart3] = {PORT_PCH_2LINE, 3}, + [pch_ml7213_uart0] = {PORT_PCH_8LINE, 0}, + [pch_ml7213_uart1] = {PORT_PCH_2LINE, 1}, + [pch_ml7213_uart2] = {PORT_PCH_2LINE, 2}, + [pch_ml7223_uart0] = {PORT_PCH_8LINE, 0}, + [pch_ml7223_uart1] = {PORT_PCH_2LINE, 1}, + [pch_ml7831_uart0] = {PORT_PCH_8LINE, 0}, + [pch_ml7831_uart1] = {PORT_PCH_2LINE, 1}, }; #ifdef CONFIG_SERIAL_PCH_UART_CONSOLE @@ -376,7 +371,7 @@ static const struct file_operations port_regs_ops = { }; #endif /* CONFIG_DEBUG_FS */ -static struct dmi_system_id pch_uart_dmi_table[] = { +static const struct dmi_system_id pch_uart_dmi_table[] = { { .ident = "CM-iTC", { @@ -1777,10 +1772,10 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, goto init_port_free_txbuf; switch (port_type) { - case PORT_UNKNOWN: + case PORT_PCH_8LINE: fifosize = 256; /* EG20T/ML7213: UART0 */ break; - case PORT_8250: + case PORT_PCH_2LINE: fifosize = 64; /* EG20T:UART1~3 ML7213: UART1~2*/ break; default: @@ -1804,7 +1799,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, priv->fifo_size = fifosize; priv->uartclk = pch_uart_get_uartclk(); - priv->port_type = PORT_MAX_8250 + port_type + 1; + priv->port_type = port_type; priv->port.dev = &pdev->dev; priv->port.iobase = iobase; priv->port.membase = NULL; @@ -1862,8 +1857,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv) { #ifdef CONFIG_DEBUG_FS - if (priv->debugfs) - debugfs_remove(priv->debugfs); + debugfs_remove(priv->debugfs); #endif uart_remove_one_port(&pch_uart_driver, &priv->port); free_page((unsigned long)priv->rxbuf.buf); diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 0da52947e59e..6ccdd018fb45 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1671,8 +1671,8 @@ static int __init pmz_probe(void) if (!node_a && !node_b) { of_node_put(node_a); of_node_put(node_b); - printk(KERN_ERR "pmac_zilog: missing node %c for escc %s\n", - (!node_a) ? 'a' : 'b', node_p->full_name); + printk(KERN_ERR "pmac_zilog: missing node %c for escc %pOF\n", + (!node_a) ? 'a' : 'b', node_p); continue; } diff --git a/drivers/tty/serial/pmac_zilog.h b/drivers/tty/serial/pmac_zilog.h index 3483242ee3e0..bb874e76810e 100644 --- a/drivers/tty/serial/pmac_zilog.h +++ b/drivers/tty/serial/pmac_zilog.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PMAC_ZILOG_H__ #define __PMAC_ZILOG_H__ diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index cdd2f942317c..b9c7a904c1ea 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -889,7 +889,16 @@ static int sccnxp_probe(struct platform_device *pdev) goto err_out; uartclk = 0; } else { - clk_prepare_enable(clk); + ret = clk_prepare_enable(clk); + if (ret) + goto err_out; + + ret = devm_add_action_or_reset(&pdev->dev, + (void(*)(void *))clk_disable_unprepare, + clk); + if (ret) + goto err_out; + uartclk = clk_get_rate(clk); } @@ -988,7 +997,7 @@ static int sccnxp_probe(struct platform_device *pdev) uart_unregister_driver(&s->uart); err_out: if (!IS_ERR(s->regulator)) - return regulator_disable(s->regulator); + regulator_disable(s->regulator); return ret; } diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index d92a150c8733..cf9b736f26f8 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -1310,7 +1310,7 @@ static int tegra_uart_probe(struct platform_device *pdev) return PTR_ERR(tup->uart_clk); } - tup->rst = devm_reset_control_get(&pdev->dev, "serial"); + tup->rst = devm_reset_control_get_exclusive(&pdev->dev, "serial"); if (IS_ERR(tup->rst)) { dev_err(&pdev->dev, "Couldn't get the reset\n"); return PTR_ERR(tup->rst); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index f534a40aebde..3a14cccbd7ff 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -36,7 +36,7 @@ #include #include -#include +#include #include /* @@ -165,6 +165,27 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear) #define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0) #define uart_clear_mctrl(port, clear) uart_update_mctrl(port, 0, clear) +static void uart_port_dtr_rts(struct uart_port *uport, int raise) +{ + int rs485_on = uport->rs485_config && + (uport->rs485.flags & SER_RS485_ENABLED); + int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND); + + if (raise) { + if (rs485_on && !RTS_after_send) { + uart_set_mctrl(uport, TIOCM_DTR); + uart_clear_mctrl(uport, TIOCM_RTS); + } else { + uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + } + } else { + unsigned int clear = TIOCM_DTR; + + clear |= (!rs485_on || !RTS_after_send) ? TIOCM_RTS : 0; + uart_clear_mctrl(uport, clear); + } +} + /* * Startup the port. This will be called once per open. All calls * will be serialised by the per-port mutex. @@ -214,7 +235,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, * port is open and ready to respond. */ if (init_hw && C_BAUD(tty)) - uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); + uart_port_dtr_rts(uport, 1); } /* @@ -272,7 +293,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) uport->cons->cflag = tty->termios.c_cflag; if (!tty || C_HUPCL(tty)) - uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); + uart_port_dtr_rts(uport, 0); uart_port_shutdown(port); } @@ -744,7 +765,7 @@ static int uart_get_info(struct tty_port *port, struct serial_struct *retinfo) if (HIGH_BITS_OFFSET) retinfo->port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; retinfo->irq = uport->irq; - retinfo->flags = uport->flags; + retinfo->flags = (__force int)uport->flags; retinfo->xmit_fifo_size = uport->fifosize; retinfo->baud_base = uport->uartclk / 16; retinfo->close_delay = jiffies_to_msecs(port->close_delay) / 10; @@ -818,7 +839,7 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, new_info->type != uport->type); old_flags = uport->flags; - new_flags = new_info->flags; + new_flags = (__force upf_t)new_info->flags; old_custom_divisor = uport->custom_divisor; if (!capable(CAP_SYS_ADMIN)) { @@ -1658,7 +1679,7 @@ static int uart_carrier_raised(struct tty_port *port) return 0; } -static void uart_dtr_rts(struct tty_port *port, int onoff) +static void uart_dtr_rts(struct tty_port *port, int raise) { struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport; @@ -1666,12 +1687,7 @@ static void uart_dtr_rts(struct tty_port *port, int onoff) uport = uart_port_ref(state); if (!uport) return; - - if (onoff) - uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS); - else - uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); - + uart_port_dtr_rts(uport, raise); uart_port_deref(uport); } @@ -2083,8 +2099,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (tty_dev && device_may_wakeup(tty_dev)) { - if (!enable_irq_wake(uport->irq)) - uport->irq_wake = 1; + enable_irq_wake(uport->irq); put_device(tty_dev); mutex_unlock(&port->mutex); return 0; @@ -2147,10 +2162,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (!uport->suspended && device_may_wakeup(tty_dev)) { - if (uport->irq_wake) { + if (irqd_is_wakeup_set(irq_get_irq_data((uport->irq)))) disable_irq_wake(uport->irq); - uport->irq_wake = 0; - } put_device(tty_dev); mutex_unlock(&port->mutex); return 0; diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index e08b16b070c0..784dd42002ea 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -3073,8 +3073,7 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev, p->type = SCI_OF_TYPE(match->data); p->regtype = SCI_OF_REGTYPE(match->data); - if (of_find_property(np, "uart-has-rtscts", NULL)) - sp->has_rtscts = true; + sp->has_rtscts = of_property_read_bool(np, "uart-has-rtscts"); return p; } diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index 971b2ab088d8..938e23a2d166 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 90996ad97b37..e902494ebbd5 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -63,6 +63,7 @@ /* interrupt clear register */ #define SPRD_ICLR 0x0014 +#define SPRD_ICLR_TIMEOUT BIT(13) /* line control register */ #define SPRD_LCR 0x0018 @@ -298,7 +299,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) return IRQ_NONE; } - serial_out(port, SPRD_ICLR, ~0); + if (ims & SPRD_IMSR_TIMEOUT) + serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT); if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) @@ -729,8 +731,8 @@ static int sprd_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(&pdev->dev, "not provide irq resource\n"); - return -ENODEV; + dev_err(&pdev->dev, "not provide irq resource: %d\n", irq); + return irq; } up->irq = irq; diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 6b0ca65027d0..b313a792b149 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -310,7 +310,7 @@ static void asc_receive_chars(struct uart_port *port) if (mode == ASC_CTL_MODE_8BIT || mode == ASC_CTL_MODE_8BIT_PAR) ignore_pe = true; - if (port->irq_wake) + if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) pm_wakeup_event(tport->tty->dev, 0); while ((status = asc_in(port, ASC_STA)) & ASC_STA_RBF) { diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 033856287ca2..03a583264d9e 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1,5 +1,6 @@ /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics SA 2017 * Authors: Maxime Coquelin * Gerald Baeza * License terms: GNU General Public License (GPL), version 2 @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -110,14 +112,13 @@ static void stm32_receive_chars(struct uart_port *port, bool threaded) unsigned long c; u32 sr; char flag; - static int last_res = RX_BUF_L; - if (port->irq_wake) + if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) pm_wakeup_event(tport->tty->dev, 0); - while (stm32_pending_rx(port, &sr, &last_res, threaded)) { + while (stm32_pending_rx(port, &sr, &stm32_port->last_res, threaded)) { sr |= USART_SR_DUMMY_RX; - c = stm32_get_char(port, &sr, &last_res); + c = stm32_get_char(port, &sr, &stm32_port->last_res); flag = TTY_NORMAL; port->icount.rx++; @@ -202,7 +203,7 @@ static void stm32_transmit_chars_pio(struct uart_port *port) ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, isr, (isr & USART_SR_TXE), - 10, 100); + 10, 100000); if (ret) dev_err(port->dev, "tx empty not set\n"); @@ -326,6 +327,10 @@ static irqreturn_t stm32_interrupt(int irq, void *ptr) sr = readl_relaxed(port->membase + ofs->isr); + if ((sr & USART_SR_WUF) && (ofs->icr != UNDEF_REG)) + writel_relaxed(USART_ICR_WUCF, + port->membase + ofs->icr); + if ((sr & USART_SR_RXNE) && !(stm32_port->rx_ch)) stm32_receive_chars(port, false); @@ -442,6 +447,7 @@ static int stm32_startup(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + struct stm32_usart_config *cfg = &stm32_port->info->cfg; const char *name = to_platform_device(port->dev)->name; u32 val; int ret; @@ -452,7 +458,18 @@ static int stm32_startup(struct uart_port *port) if (ret) return ret; + if (cfg->has_wakeup && stm32_port->wakeirq >= 0) { + ret = dev_pm_set_dedicated_wake_irq(port->dev, + stm32_port->wakeirq); + if (ret) { + free_irq(port->irq, port); + return ret; + } + } + val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; + if (stm32_port->fifoen) + val |= USART_CR1_FIFOEN; stm32_set_bits(port, ofs->cr1, val); return 0; @@ -467,8 +484,11 @@ static void stm32_shutdown(struct uart_port *port) val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; val |= BIT(cfg->uart_enable_bit); + if (stm32_port->fifoen) + val |= USART_CR1_FIFOEN; stm32_clr_bits(port, ofs->cr1, val); + dev_pm_clear_wake_irq(port->dev); free_irq(port->irq, port); } @@ -496,6 +516,8 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; cr1 |= BIT(cfg->uart_enable_bit); + if (stm32_port->fifoen) + cr1 |= USART_CR1_FIFOEN; cr2 = 0; cr3 = 0; @@ -518,7 +540,7 @@ static void stm32_set_termios(struct uart_port *port, struct ktermios *termios, port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS); if (cflag & CRTSCTS) { port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; - cr3 |= USART_CR3_CTSE; + cr3 |= USART_CR3_CTSE | USART_CR3_RTSE; } usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud); @@ -659,6 +681,8 @@ static int stm32_init_port(struct stm32_port *stm32port, port->ops = &stm32_uart_ops; port->dev = &pdev->dev; port->irq = platform_get_irq(pdev, 0); + stm32port->wakeirq = platform_get_irq(pdev, 1); + stm32port->fifoen = stm32port->info->cfg.has_fifo; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); port->membase = devm_ioremap_resource(&pdev->dev, res); @@ -678,8 +702,10 @@ static int stm32_init_port(struct stm32_port *stm32port, return ret; stm32port->port.uartclk = clk_get_rate(stm32port->clk); - if (!stm32port->port.uartclk) + if (!stm32port->port.uartclk) { + clk_disable_unprepare(stm32port->clk); ret = -EINVAL; + } return ret; } @@ -693,8 +719,10 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) return NULL; id = of_alias_get_id(np, "serial"); - if (id < 0) - id = 0; + if (id < 0) { + dev_err(&pdev->dev, "failed to get alias id, errno %d\n", id); + return NULL; + } if (WARN_ON(id >= STM32_MAX_PORTS)) return NULL; @@ -702,6 +730,7 @@ static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev) stm32_ports[id].hw_flow_control = of_property_read_bool(np, "st,hw-flow-ctrl"); stm32_ports[id].port.line = id; + stm32_ports[id].last_res = RX_BUF_L; return &stm32_ports[id]; } @@ -711,6 +740,8 @@ static const struct of_device_id stm32_match[] = { { .compatible = "st,stm32-uart", .data = &stm32f4_info}, { .compatible = "st,stm32f7-usart", .data = &stm32f7_info}, { .compatible = "st,stm32f7-uart", .data = &stm32f7_info}, + { .compatible = "st,stm32h7-usart", .data = &stm32h7_info}, + { .compatible = "st,stm32h7-uart", .data = &stm32h7_info}, {}, }; @@ -860,9 +891,15 @@ static int stm32_serial_probe(struct platform_device *pdev) if (ret) return ret; + if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0) { + ret = device_init_wakeup(&pdev->dev, true); + if (ret) + goto err_uninit; + } + ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port); if (ret) - return ret; + goto err_nowup; ret = stm32_of_dma_rx_probe(stm32port, pdev); if (ret) @@ -875,6 +912,15 @@ static int stm32_serial_probe(struct platform_device *pdev) platform_set_drvdata(pdev, &stm32port->port); return 0; + +err_nowup: + if (stm32port->info->cfg.has_wakeup && stm32port->wakeirq >= 0) + device_init_wakeup(&pdev->dev, false); + +err_uninit: + clk_disable_unprepare(stm32port->clk); + + return ret; } static int stm32_serial_remove(struct platform_device *pdev) @@ -882,6 +928,7 @@ static int stm32_serial_remove(struct platform_device *pdev) struct uart_port *port = platform_get_drvdata(pdev); struct stm32_port *stm32_port = to_stm32_port(port); struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + struct stm32_usart_config *cfg = &stm32_port->info->cfg; stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAR); @@ -903,6 +950,9 @@ static int stm32_serial_remove(struct platform_device *pdev) TX_BUF_L, stm32_port->tx_buf, stm32_port->tx_dma_buf); + if (cfg->has_wakeup && stm32_port->wakeirq >= 0) + device_init_wakeup(&pdev->dev, false); + clk_disable_unprepare(stm32_port->clk); return uart_remove_one_port(&stm32_usart_driver, port); @@ -1008,11 +1058,66 @@ static struct uart_driver stm32_usart_driver = { .cons = STM32_SERIAL_CONSOLE, }; +#ifdef CONFIG_PM_SLEEP +static void stm32_serial_enable_wakeup(struct uart_port *port, bool enable) +{ + struct stm32_port *stm32_port = to_stm32_port(port); + struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + struct stm32_usart_config *cfg = &stm32_port->info->cfg; + u32 val; + + if (!cfg->has_wakeup || stm32_port->wakeirq < 0) + return; + + if (enable) { + stm32_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); + stm32_set_bits(port, ofs->cr1, USART_CR1_UESM); + val = readl_relaxed(port->membase + ofs->cr3); + val &= ~USART_CR3_WUS_MASK; + /* Enable Wake up interrupt from low power on start bit */ + val |= USART_CR3_WUS_START_BIT | USART_CR3_WUFIE; + writel_relaxed(val, port->membase + ofs->cr3); + stm32_set_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); + } else { + stm32_clr_bits(port, ofs->cr1, USART_CR1_UESM); + } +} + +static int stm32_serial_suspend(struct device *dev) +{ + struct uart_port *port = dev_get_drvdata(dev); + + uart_suspend_port(&stm32_usart_driver, port); + + if (device_may_wakeup(dev)) + stm32_serial_enable_wakeup(port, true); + else + stm32_serial_enable_wakeup(port, false); + + return 0; +} + +static int stm32_serial_resume(struct device *dev) +{ + struct uart_port *port = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + stm32_serial_enable_wakeup(port, false); + + return uart_resume_port(&stm32_usart_driver, port); +} +#endif /* CONFIG_PM_SLEEP */ + +static const struct dev_pm_ops stm32_serial_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(stm32_serial_suspend, stm32_serial_resume) +}; + static struct platform_driver stm32_serial_driver = { .probe = stm32_serial_probe, .remove = stm32_serial_remove, .driver = { .name = DRIVER_NAME, + .pm = &stm32_serial_pm_ops, .of_match_table = of_match_ptr(stm32_match), }, }; diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index cd97ceb76e4f..ffc0c5285e51 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -1,5 +1,6 @@ /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics SA 2017 * Authors: Maxime Coquelin * Gerald Baeza * License terms: GNU General Public License (GPL), version 2 @@ -24,6 +25,8 @@ struct stm32_usart_offsets { struct stm32_usart_config { u8 uart_enable_bit; /* USART_CR1_UE */ bool has_7bits_data; + bool has_wakeup; + bool has_fifo; }; struct stm32_usart_info { @@ -74,6 +77,28 @@ struct stm32_usart_info stm32f7_info = { } }; +struct stm32_usart_info stm32h7_info = { + .ofs = { + .cr1 = 0x00, + .cr2 = 0x04, + .cr3 = 0x08, + .brr = 0x0c, + .gtpr = 0x10, + .rtor = 0x14, + .rqr = 0x18, + .isr = 0x1c, + .icr = 0x20, + .rdr = 0x24, + .tdr = 0x28, + }, + .cfg = { + .uart_enable_bit = 0, + .has_7bits_data = true, + .has_wakeup = true, + .has_fifo = true, + } +}; + /* USART_SR (F4) / USART_ISR (F7) */ #define USART_SR_PE BIT(0) #define USART_SR_FE BIT(1) @@ -93,6 +118,7 @@ struct stm32_usart_info stm32f7_info = { #define USART_SR_BUSY BIT(16) /* F7 */ #define USART_SR_CMF BIT(17) /* F7 */ #define USART_SR_SBKF BIT(18) /* F7 */ +#define USART_SR_WUF BIT(20) /* H7 */ #define USART_SR_TEACK BIT(21) /* F7 */ #define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \ USART_SR_FE | USART_SR_PE) @@ -113,6 +139,7 @@ struct stm32_usart_info stm32f7_info = { /* USART_CR1 */ #define USART_CR1_SBK BIT(0) #define USART_CR1_RWU BIT(1) /* F4 */ +#define USART_CR1_UESM BIT(1) /* H7 */ #define USART_CR1_RE BIT(2) #define USART_CR1_TE BIT(3) #define USART_CR1_IDLEIE BIT(4) @@ -134,6 +161,7 @@ struct stm32_usart_info stm32f7_info = { #define USART_CR1_EOBIE BIT(27) /* F7 */ #define USART_CR1_M1 BIT(28) /* F7 */ #define USART_CR1_IE_MASK (GENMASK(8, 4) | BIT(14) | BIT(26) | BIT(27)) +#define USART_CR1_FIFOEN BIT(29) /* H7 */ /* USART_CR2 */ #define USART_CR2_ADD_MASK GENMASK(3, 0) /* F4 */ @@ -175,6 +203,9 @@ struct stm32_usart_info stm32f7_info = { #define USART_CR3_DEM BIT(14) /* F7 */ #define USART_CR3_DEP BIT(15) /* F7 */ #define USART_CR3_SCARCNT_MASK GENMASK(19, 17) /* F7 */ +#define USART_CR3_WUS_MASK GENMASK(21, 20) /* H7 */ +#define USART_CR3_WUS_START_BIT BIT(21) /* H7 */ +#define USART_CR3_WUFIE BIT(22) /* H7 */ /* USART_GTPR */ #define USART_GTPR_PSC_MASK GENMASK(7, 0) @@ -203,9 +234,10 @@ struct stm32_usart_info stm32f7_info = { #define USART_ICR_RTOCF BIT(11) /* F7 */ #define USART_ICR_EOBCF BIT(12) /* F7 */ #define USART_ICR_CMCF BIT(17) /* F7 */ +#define USART_ICR_WUCF BIT(20) /* H7 */ #define STM32_SERIAL_NAME "ttyS" -#define STM32_MAX_PORTS 6 +#define STM32_MAX_PORTS 8 #define RX_BUF_L 200 /* dma rx buffer length */ #define RX_BUF_P RX_BUF_L /* dma rx buffer period */ @@ -221,8 +253,11 @@ struct stm32_port { struct dma_chan *tx_ch; /* dma tx channel */ dma_addr_t tx_dma_buf; /* dma tx buffer bus address */ unsigned char *tx_buf; /* dma tx buffer cpu address */ + int last_res; bool tx_dma_busy; /* dma tx busy */ bool hw_flow_control; + bool fifoen; + int wakeirq; }; static struct stm32_port stm32_ports[STM32_MAX_PORTS]; diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index b5e3195b3697..653a076d89d3 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -819,7 +819,7 @@ static int sunsab_verify_port(struct uart_port *port, struct serial_struct *ser) return -EINVAL; } -static struct uart_ops sunsab_pops = { +static const struct uart_ops sunsab_pops = { .tx_empty = sunsab_tx_empty, .set_mctrl = sunsab_set_mctrl, .get_mctrl = sunsab_get_mctrl, diff --git a/drivers/tty/serial/sunsab.h b/drivers/tty/serial/sunsab.h index b78e1f7b8050..1644031aacda 100644 --- a/drivers/tty/serial/sunsab.h +++ b/drivers/tty/serial/sunsab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* sunsab.h: Register Definitions for the Siemens SAB82532 DUSCC * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 72df2e1b88af..95d34d7565c9 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -958,7 +958,7 @@ sunsu_type(struct uart_port *port) return uart_config[type].name; } -static struct uart_ops sunsu_pops = { +static const struct uart_ops sunsu_pops = { .tx_empty = sunsu_tx_empty, .set_mctrl = sunsu_set_mctrl, .get_mctrl = sunsu_get_mctrl, @@ -1212,8 +1212,8 @@ static int sunsu_kbd_ms_init(struct uart_sunsu_port *up) if (up->port.type == PORT_UNKNOWN) return -ENODEV; - printk("%s: %s port at %llx, irq %u\n", - up->port.dev->of_node->full_name, + printk("%pOF: %s port at %llx, irq %u\n", + up->port.dev->of_node, (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", (unsigned long long) up->port.mapbase, up->port.irq); diff --git a/drivers/tty/serial/sunzilog.h b/drivers/tty/serial/sunzilog.h index 5dec7b47cc38..6d6764f0ac98 100644 --- a/drivers/tty/serial/sunzilog.h +++ b/drivers/tty/serial/sunzilog.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SUNZILOG_H #define _SUNZILOG_H diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 481eb2989a1e..55b702775786 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1085,7 +1085,7 @@ static int qe_uart_verify_port(struct uart_port *port, * * Details on these functions can be found in Documentation/serial/driver */ -static struct uart_ops qe_uart_pops = { +static const struct uart_ops qe_uart_pops = { .tx_empty = qe_uart_tx_empty, .set_mctrl = qe_uart_set_mctrl, .get_mctrl = qe_uart_get_mctrl, diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index fde55dcdea5a..31a630ae0870 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1163,7 +1163,7 @@ static void cdns_uart_console_putchar(struct uart_port *port, int ch) writel(ch, port->membase + CDNS_UART_FIFO); } -static void __init cdns_early_write(struct console *con, const char *s, +static void cdns_early_write(struct console *con, const char *s, unsigned n) { struct earlycon_device *dev = con->data; diff --git a/drivers/tty/serial/zs.h b/drivers/tty/serial/zs.h index aa921b57d827..26ef8eafa1c1 100644 --- a/drivers/tty/serial/zs.h +++ b/drivers/tty/serial/zs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * zs.h: Definitions for the DECstation Z85C30 serial driver. * diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 3fafc5a1b2e0..3be981101297 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -884,7 +884,7 @@ static int synclink_init_one (struct pci_dev *dev, const struct pci_device_id *ent); static void synclink_remove_one (struct pci_dev *dev); -static struct pci_device_id synclink_pci_tbl[] = { +static const struct pci_device_id synclink_pci_tbl[] = { { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_MICROGATE, 0x0210, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, /* terminate list */ diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 529c6e3cd537..636b8ae29b46 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -95,7 +95,7 @@ MODULE_LICENSE("GPL"); #define MGSL_MAGIC 0x5401 #define MAX_DEVICES 32 -static struct pci_device_id pci_table[] = { +static const struct pci_device_id pci_table[] = { {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 9b4fb0251c1a..4fed9e7b281f 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -479,7 +479,7 @@ static char *driver_version = "$Revision: 4.38 $"; static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent); static void synclinkmp_remove_one(struct pci_dev *dev); -static struct pci_device_id synclinkmp_pci_tbl[] = { +static const struct pci_device_id synclinkmp_pci_tbl[] = { { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_SCA, PCI_ANY_ID, PCI_ANY_ID, }, { 0, }, /* terminate list */ }; diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 3ffc1ce29023..d008f5a75197 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Linux Magic System Request Key Hacks * diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 4e7a4e9dcf4d..f8eba1c5412f 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -361,6 +361,32 @@ int tty_insert_flip_string_flags(struct tty_port *port, } EXPORT_SYMBOL(tty_insert_flip_string_flags); +/** + * __tty_insert_flip_char - Add one character to the tty buffer + * @port: tty port + * @ch: character + * @flag: flag byte + * + * Queue a single byte to the tty buffering, with an optional flag. + * This is the slow path of tty_insert_flip_char. + */ +int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) +{ + struct tty_buffer *tb; + int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; + + if (!__tty_buffer_request_room(port, 1, flags)) + return 0; + + tb = port->buf.tail; + if (~tb->flags & TTYB_NORMAL) + *flag_buf_ptr(tb, tb->used) = flag; + *char_buf_ptr(tb, tb->used++) = ch; + + return 1; +} +EXPORT_SYMBOL(__tty_insert_flip_char); + /** * tty_schedule_flip - push characters to ldisc * @port: tty port to push from diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 10c4038c0e8d..94cccb6efa32 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -280,7 +280,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) { #ifdef CHECK_TTY_COUNT struct list_head *p; - int count = 0; + int count = 0, kopen_count = 0; spin_lock(&tty->files_lock); list_for_each(p, &tty->tty_files) { @@ -291,10 +291,12 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) tty->driver->subtype == PTY_TYPE_SLAVE && tty->link && tty->link->count) count++; - if (tty->count != count) { - tty_warn(tty, "%s: tty->count(%d) != #fd's(%d)\n", - routine, tty->count, count); - return count; + if (tty_port_kopened(tty->port)) + kopen_count++; + if (tty->count != (count + kopen_count)) { + tty_warn(tty, "%s: tty->count(%d) != (#fd's(%d) + #kopen's(%d))\n", + routine, tty->count, count, kopen_count); + return (count + kopen_count); } #endif return 0; @@ -462,6 +464,14 @@ static int hung_up_tty_fasync(int fd, struct file *file, int on) return -ENOTTY; } +static void tty_show_fdinfo(struct seq_file *m, struct file *file) +{ + struct tty_struct *tty = file_tty(file); + + if (tty && tty->ops && tty->ops->show_fdinfo) + tty->ops->show_fdinfo(tty, m); +} + static const struct file_operations tty_fops = { .llseek = no_llseek, .read = tty_read, @@ -472,6 +482,7 @@ static const struct file_operations tty_fops = { .open = tty_open, .release = tty_release, .fasync = tty_fasync, + .show_fdinfo = tty_show_fdinfo, }; static const struct file_operations console_fops = { @@ -1512,6 +1523,38 @@ static int tty_release_checks(struct tty_struct *tty, int idx) return 0; } +/** + * tty_kclose - closes tty opened by tty_kopen + * @tty: tty device + * + * Performs the final steps to release and free a tty device. It is the + * same as tty_release_struct except that it also resets TTY_PORT_KOPENED + * flag on tty->port. + */ +void tty_kclose(struct tty_struct *tty) +{ + /* + * Ask the line discipline code to release its structures + */ + tty_ldisc_release(tty); + + /* Wait for pending work before tty destruction commmences */ + tty_flush_works(tty); + + tty_debug_hangup(tty, "freeing structure\n"); + /* + * The release_tty function takes care of the details of clearing + * the slots and preserving the termios structure. The tty_unlock_pair + * should be safe as we keep a kref while the tty is locked (so the + * unlock never unlocks a freed tty). + */ + mutex_lock(&tty_mutex); + tty_port_set_kopened(tty->port, 0); + release_tty(tty, tty->index); + mutex_unlock(&tty_mutex); +} +EXPORT_SYMBOL_GPL(tty_kclose); + /** * tty_release_struct - release a tty struct * @tty: tty device @@ -1785,6 +1828,56 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, return driver; } +/** + * tty_kopen - open a tty device for kernel + * @device: dev_t of device to open + * + * Opens tty exclusively for kernel. Performs the driver lookup, + * makes sure it's not already opened and performs the first-time + * tty initialization. + * + * Returns the locked initialized &tty_struct + * + * Claims the global tty_mutex to serialize: + * - concurrent first-time tty initialization + * - concurrent tty driver removal w/ lookup + * - concurrent tty removal from driver table + */ +struct tty_struct *tty_kopen(dev_t device) +{ + struct tty_struct *tty; + struct tty_driver *driver = NULL; + int index = -1; + + mutex_lock(&tty_mutex); + driver = tty_lookup_driver(device, NULL, &index); + if (IS_ERR(driver)) { + mutex_unlock(&tty_mutex); + return ERR_CAST(driver); + } + + /* check whether we're reopening an existing tty */ + tty = tty_driver_lookup_tty(driver, NULL, index); + if (IS_ERR(tty)) + goto out; + + if (tty) { + /* drop kref from tty_driver_lookup_tty() */ + tty_kref_put(tty); + tty = ERR_PTR(-EBUSY); + } else { /* tty_init_dev returns tty with the tty_lock held */ + tty = tty_init_dev(driver, index); + if (IS_ERR(tty)) + goto out; + tty_port_set_kopened(tty->port, 1); + } +out: + mutex_unlock(&tty_mutex); + tty_driver_kref_put(driver); + return tty; +} +EXPORT_SYMBOL_GPL(tty_kopen); + /** * tty_open_by_driver - open a tty device * @device: dev_t of device to open @@ -1801,7 +1894,7 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, * - concurrent tty driver removal w/ lookup * - concurrent tty removal from driver table */ -struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, +static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, struct file *filp) { struct tty_struct *tty; @@ -1824,6 +1917,12 @@ struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, } if (tty) { + if (tty_port_kopened(tty->port)) { + tty_kref_put(tty); + mutex_unlock(&tty_mutex); + tty = ERR_PTR(-EBUSY); + goto out; + } mutex_unlock(&tty_mutex); retval = tty_lock_interruptible(tty); tty_kref_put(tty); /* drop kref from tty_driver_lookup_tty() */ @@ -1846,7 +1945,6 @@ out: tty_driver_kref_put(driver); return tty; } -EXPORT_SYMBOL_GPL(tty_open_by_driver); /** * tty_open - open a tty device diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 2fe216b276e2..84a8ac2a779f 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -694,10 +694,8 @@ int tty_ldisc_reinit(struct tty_struct *tty, int disc) tty_set_termios_ldisc(tty, disc); retval = tty_ldisc_open(tty, tty->ldisc); if (retval) { - if (!WARN_ON(disc == N_TTY)) { - tty_ldisc_put(tty->ldisc); - tty->ldisc = NULL; - } + tty_ldisc_put(tty->ldisc); + tty->ldisc = NULL; } return retval; } @@ -752,8 +750,9 @@ void tty_ldisc_hangup(struct tty_struct *tty, bool reinit) if (tty->ldisc) { if (reinit) { - if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0) - tty_ldisc_reinit(tty, N_TTY); + if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0 && + tty_ldisc_reinit(tty, N_TTY) < 0) + WARN_ON(tty_ldisc_reinit(tty, N_NULL) < 0); } else tty_ldisc_kill(tty); } diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index d8bae67a6174..2640635ee177 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c new file mode 100644 index 000000000000..ef01d24858cd --- /dev/null +++ b/drivers/tty/vcc.c @@ -0,0 +1,1155 @@ +/* vcc.c: sun4v virtual channel concentrator + * + * Copyright (C) 2017 Oracle. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_MODULE_NAME "vcc" +#define DRV_MODULE_VERSION "1.1" +#define DRV_MODULE_RELDATE "July 1, 2017" + +static char version[] = + DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")"; + +MODULE_DESCRIPTION("Sun LDOM virtual console concentrator driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +struct vcc_port { + struct vio_driver_state vio; + + spinlock_t lock; + char *domain; + struct tty_struct *tty; /* only populated while dev is open */ + unsigned long index; /* index into the vcc_table */ + + u64 refcnt; + bool excl_locked; + + bool removed; + + /* This buffer is required to support the tty write_room interface + * and guarantee that any characters that the driver accepts will + * be eventually sent, either immediately or later. + */ + int chars_in_buffer; + struct vio_vcc buffer; + + struct timer_list rx_timer; + struct timer_list tx_timer; +}; + +/* Microseconds that thread will delay waiting for a vcc port ref */ +#define VCC_REF_DELAY 100 + +#define VCC_MAX_PORTS 1024 +#define VCC_MINOR_START 0 /* must be zero */ +#define VCC_BUFF_LEN VIO_VCC_MTU_SIZE + +#define VCC_CTL_BREAK -1 +#define VCC_CTL_HUP -2 + +static const char vcc_driver_name[] = "vcc"; +static const char vcc_device_node[] = "vcc"; +static struct tty_driver *vcc_tty_driver; + +static struct vcc_port *vcc_table[VCC_MAX_PORTS]; +static DEFINE_SPINLOCK(vcc_table_lock); + +int vcc_dbg; +int vcc_dbg_ldc; +int vcc_dbg_vio; + +module_param(vcc_dbg, uint, 0664); +module_param(vcc_dbg_ldc, uint, 0664); +module_param(vcc_dbg_vio, uint, 0664); + +#define VCC_DBG_DRV 0x1 +#define VCC_DBG_LDC 0x2 +#define VCC_DBG_PKT 0x4 + +#define vccdbg(f, a...) \ + do { \ + if (vcc_dbg & VCC_DBG_DRV) \ + pr_info(f, ## a); \ + } while (0) \ + +#define vccdbgl(l) \ + do { \ + if (vcc_dbg & VCC_DBG_LDC) \ + ldc_print(l); \ + } while (0) \ + +#define vccdbgp(pkt) \ + do { \ + if (vcc_dbg & VCC_DBG_PKT) { \ + int i; \ + for (i = 0; i < pkt.tag.stype; i++) \ + pr_info("[%c]", pkt.data[i]); \ + } \ + } while (0) \ + +/* Note: Be careful when adding flags to this line discipline. Don't + * add anything that will cause echoing or we'll go into recursive + * loop echoing chars back and forth with the console drivers. + */ +static const struct ktermios vcc_tty_termios = { + .c_iflag = IGNBRK | IGNPAR, + .c_oflag = OPOST, + .c_cflag = B38400 | CS8 | CREAD | HUPCL, + .c_cc = INIT_C_CC, + .c_ispeed = 38400, + .c_ospeed = 38400 +}; + +/** + * vcc_table_add() - Add VCC port to the VCC table + * @port: pointer to the VCC port + * + * Return: index of the port in the VCC table on success, + * -1 on failure + */ +static int vcc_table_add(struct vcc_port *port) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&vcc_table_lock, flags); + for (i = VCC_MINOR_START; i < VCC_MAX_PORTS; i++) { + if (!vcc_table[i]) { + vcc_table[i] = port; + break; + } + } + spin_unlock_irqrestore(&vcc_table_lock, flags); + + if (i < VCC_MAX_PORTS) + return i; + else + return -1; +} + +/** + * vcc_table_remove() - Removes a VCC port from the VCC table + * @index: Index into the VCC table + */ +static void vcc_table_remove(unsigned long index) +{ + unsigned long flags; + + if (WARN_ON(index >= VCC_MAX_PORTS)) + return; + + spin_lock_irqsave(&vcc_table_lock, flags); + vcc_table[index] = NULL; + spin_unlock_irqrestore(&vcc_table_lock, flags); +} + +/** + * vcc_get() - Gets a reference to VCC port + * @index: Index into the VCC table + * @excl: Indicates if an exclusive access is requested + * + * Return: reference to the VCC port, if found + * NULL, if port not found + */ +static struct vcc_port *vcc_get(unsigned long index, bool excl) +{ + struct vcc_port *port; + unsigned long flags; + +try_again: + spin_lock_irqsave(&vcc_table_lock, flags); + + port = vcc_table[index]; + if (!port) { + spin_unlock_irqrestore(&vcc_table_lock, flags); + return NULL; + } + + if (!excl) { + if (port->excl_locked) { + spin_unlock_irqrestore(&vcc_table_lock, flags); + udelay(VCC_REF_DELAY); + goto try_again; + } + port->refcnt++; + spin_unlock_irqrestore(&vcc_table_lock, flags); + return port; + } + + if (port->refcnt) { + spin_unlock_irqrestore(&vcc_table_lock, flags); + /* Threads wanting exclusive access will wait half the time, + * probably giving them higher priority in the case of + * multiple waiters. + */ + udelay(VCC_REF_DELAY/2); + goto try_again; + } + + port->refcnt++; + port->excl_locked = true; + spin_unlock_irqrestore(&vcc_table_lock, flags); + + return port; +} + +/** + * vcc_put() - Returns a reference to VCC port + * @port: pointer to VCC port + * @excl: Indicates if the returned reference is an exclusive reference + * + * Note: It's the caller's responsibility to ensure the correct value + * for the excl flag + */ +static void vcc_put(struct vcc_port *port, bool excl) +{ + unsigned long flags; + + if (!port) + return; + + spin_lock_irqsave(&vcc_table_lock, flags); + + /* check if caller attempted to put with the wrong flags */ + if (WARN_ON((excl && !port->excl_locked) || + (!excl && port->excl_locked))) + goto done; + + port->refcnt--; + + if (excl) + port->excl_locked = false; + +done: + spin_unlock_irqrestore(&vcc_table_lock, flags); +} + +/** + * vcc_get_ne() - Get a non-exclusive reference to VCC port + * @index: Index into the VCC table + * + * Gets a non-exclusive reference to VCC port, if it's not removed + * + * Return: pointer to the VCC port, if found + * NULL, if port not found + */ +static struct vcc_port *vcc_get_ne(unsigned long index) +{ + struct vcc_port *port; + + port = vcc_get(index, false); + + if (port && port->removed) { + vcc_put(port, false); + return NULL; + } + + return port; +} + +static void vcc_kick_rx(struct vcc_port *port) +{ + struct vio_driver_state *vio = &port->vio; + + assert_spin_locked(&port->lock); + + if (!timer_pending(&port->rx_timer) && !port->removed) { + disable_irq_nosync(vio->vdev->rx_irq); + port->rx_timer.expires = (jiffies + 1); + add_timer(&port->rx_timer); + } +} + +static void vcc_kick_tx(struct vcc_port *port) +{ + assert_spin_locked(&port->lock); + + if (!timer_pending(&port->tx_timer) && !port->removed) { + port->tx_timer.expires = (jiffies + 1); + add_timer(&port->tx_timer); + } +} + +static int vcc_rx_check(struct tty_struct *tty, int size) +{ + if (WARN_ON(!tty || !tty->port)) + return 1; + + /* tty_buffer_request_room won't sleep because it uses + * GFP_ATOMIC flag to allocate buffer + */ + if (test_bit(TTY_THROTTLED, &tty->flags) || + (tty_buffer_request_room(tty->port, VCC_BUFF_LEN) < VCC_BUFF_LEN)) + return 0; + + return 1; +} + +static int vcc_rx(struct tty_struct *tty, char *buf, int size) +{ + int len = 0; + + if (WARN_ON(!tty || !tty->port)) + return len; + + len = tty_insert_flip_string(tty->port, buf, size); + if (len) + tty_flip_buffer_push(tty->port); + + return len; +} + +static int vcc_ldc_read(struct vcc_port *port) +{ + struct vio_driver_state *vio = &port->vio; + struct tty_struct *tty; + struct vio_vcc pkt; + int rv = 0; + + tty = port->tty; + if (!tty) { + rv = ldc_rx_reset(vio->lp); + vccdbg("VCC: reset rx q: rv=%d\n", rv); + goto done; + } + + /* Read as long as LDC has incoming data. */ + while (1) { + if (!vcc_rx_check(tty, VIO_VCC_MTU_SIZE)) { + vcc_kick_rx(port); + break; + } + + vccdbgl(vio->lp); + + rv = ldc_read(vio->lp, &pkt, sizeof(pkt)); + if (rv <= 0) + break; + + vccdbg("VCC: ldc_read()=%d\n", rv); + vccdbg("TAG [%02x:%02x:%04x:%08x]\n", + pkt.tag.type, pkt.tag.stype, + pkt.tag.stype_env, pkt.tag.sid); + + if (pkt.tag.type == VIO_TYPE_DATA) { + vccdbgp(pkt); + /* vcc_rx_check ensures memory availability */ + vcc_rx(tty, pkt.data, pkt.tag.stype); + } else { + pr_err("VCC: unknown msg [%02x:%02x:%04x:%08x]\n", + pkt.tag.type, pkt.tag.stype, + pkt.tag.stype_env, pkt.tag.sid); + rv = -ECONNRESET; + break; + } + + WARN_ON(rv != LDC_PACKET_SIZE); + } + +done: + return rv; +} + +static void vcc_rx_timer(unsigned long index) +{ + struct vio_driver_state *vio; + struct vcc_port *port; + unsigned long flags; + int rv; + + port = vcc_get_ne(index); + if (!port) + return; + + spin_lock_irqsave(&port->lock, flags); + port->rx_timer.expires = 0; + + vio = &port->vio; + + enable_irq(vio->vdev->rx_irq); + + if (!port->tty || port->removed) + goto done; + + rv = vcc_ldc_read(port); + if (rv == -ECONNRESET) + vio_conn_reset(vio); + +done: + spin_unlock_irqrestore(&port->lock, flags); + vcc_put(port, false); +} + +static void vcc_tx_timer(unsigned long index) +{ + struct vcc_port *port; + struct vio_vcc *pkt; + unsigned long flags; + int tosend = 0; + int rv; + + port = vcc_get_ne(index); + if (!port) + return; + + spin_lock_irqsave(&port->lock, flags); + port->tx_timer.expires = 0; + + if (!port->tty || port->removed) + goto done; + + tosend = min(VCC_BUFF_LEN, port->chars_in_buffer); + if (!tosend) + goto done; + + pkt = &port->buffer; + pkt->tag.type = VIO_TYPE_DATA; + pkt->tag.stype = tosend; + vccdbgl(port->vio.lp); + + rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend)); + WARN_ON(!rv); + + if (rv < 0) { + vccdbg("VCC: ldc_write()=%d\n", rv); + vcc_kick_tx(port); + } else { + struct tty_struct *tty = port->tty; + + port->chars_in_buffer = 0; + if (tty) + tty_wakeup(tty); + } + +done: + spin_unlock_irqrestore(&port->lock, flags); + vcc_put(port, false); +} + +/** + * vcc_event() - LDC event processing engine + * @arg: VCC private data + * @event: LDC event + * + * Handles LDC events for VCC + */ +static void vcc_event(void *arg, int event) +{ + struct vio_driver_state *vio; + struct vcc_port *port; + unsigned long flags; + int rv; + + port = arg; + vio = &port->vio; + + spin_lock_irqsave(&port->lock, flags); + + switch (event) { + case LDC_EVENT_RESET: + case LDC_EVENT_UP: + vio_link_state_change(vio, event); + break; + + case LDC_EVENT_DATA_READY: + rv = vcc_ldc_read(port); + if (rv == -ECONNRESET) + vio_conn_reset(vio); + break; + + default: + pr_err("VCC: unexpected LDC event(%d)\n", event); + } + + spin_unlock_irqrestore(&port->lock, flags); +} + +static struct ldc_channel_config vcc_ldc_cfg = { + .event = vcc_event, + .mtu = VIO_VCC_MTU_SIZE, + .mode = LDC_MODE_RAW, + .debug = 0, +}; + +/* Ordered from largest major to lowest */ +static struct vio_version vcc_versions[] = { + { .major = 1, .minor = 0 }, +}; + +static struct tty_port_operations vcc_port_ops = { 0 }; + +static ssize_t vcc_sysfs_domain_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct vcc_port *port; + int rv; + + port = dev_get_drvdata(dev); + if (!port) + return -ENODEV; + + rv = scnprintf(buf, PAGE_SIZE, "%s\n", port->domain); + + return rv; +} + +static int vcc_send_ctl(struct vcc_port *port, int ctl) +{ + struct vio_vcc pkt; + int rv; + + pkt.tag.type = VIO_TYPE_CTRL; + pkt.tag.sid = ctl; + pkt.tag.stype = 0; + + rv = ldc_write(port->vio.lp, &pkt, sizeof(pkt.tag)); + WARN_ON(!rv); + vccdbg("VCC: ldc_write(%ld)=%d\n", sizeof(pkt.tag), rv); + + return rv; +} + +static ssize_t vcc_sysfs_break_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct vcc_port *port; + unsigned long flags; + int rv = count; + int brk; + + port = dev_get_drvdata(dev); + if (!port) + return -ENODEV; + + spin_lock_irqsave(&port->lock, flags); + + if (sscanf(buf, "%ud", &brk) != 1 || brk != 1) + rv = -EINVAL; + else if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0) + vcc_kick_tx(port); + + spin_unlock_irqrestore(&port->lock, flags); + + return rv; +} + +static DEVICE_ATTR(domain, 0400, vcc_sysfs_domain_show, NULL); +static DEVICE_ATTR(break, 0200, NULL, vcc_sysfs_break_store); + +static struct attribute *vcc_sysfs_entries[] = { + &dev_attr_domain.attr, + &dev_attr_break.attr, + NULL +}; + +static struct attribute_group vcc_attribute_group = { + .name = NULL, + .attrs = vcc_sysfs_entries, +}; + +/** + * vcc_probe() - Initialize VCC port + * @vdev: Pointer to VIO device of the new VCC port + * @id: VIO device ID + * + * Initializes a VCC port to receive serial console data from + * the guest domain. Sets up a TTY end point on the control + * domain. Sets up VIO/LDC link between the guest & control + * domain endpoints. + * + * Return: status of the probe + */ +static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) +{ + struct mdesc_handle *hp; + struct vcc_port *port; + struct device *dev; + const char *domain; + char *name; + u64 node; + int rv; + + vccdbg("VCC: name=%s\n", dev_name(&vdev->dev)); + + if (!vcc_tty_driver) { + pr_err("VCC: TTY driver not registered\n"); + return -ENODEV; + } + + port = kzalloc(sizeof(struct vcc_port), GFP_KERNEL); + if (!port) + return -ENOMEM; + + name = kstrdup(dev_name(&vdev->dev), GFP_KERNEL); + + rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions, + ARRAY_SIZE(vcc_versions), NULL, name); + if (rv) + goto free_port; + + port->vio.debug = vcc_dbg_vio; + vcc_ldc_cfg.debug = vcc_dbg_ldc; + + rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port); + if (rv) + goto free_port; + + spin_lock_init(&port->lock); + + port->index = vcc_table_add(port); + if (port->index == -1) { + pr_err("VCC: no more TTY indices left for allocation\n"); + goto free_ldc; + } + + /* Register the device using VCC table index as TTY index */ + dev = tty_register_device(vcc_tty_driver, port->index, &vdev->dev); + if (IS_ERR(dev)) { + rv = PTR_ERR(dev); + goto free_table; + } + + hp = mdesc_grab(); + + node = vio_vdev_node(hp, vdev); + if (node == MDESC_NODE_NULL) { + rv = -ENXIO; + mdesc_release(hp); + goto unreg_tty; + } + + domain = mdesc_get_property(hp, node, "vcc-domain-name", NULL); + if (!domain) { + rv = -ENXIO; + mdesc_release(hp); + goto unreg_tty; + } + port->domain = kstrdup(domain, GFP_KERNEL); + + mdesc_release(hp); + + rv = sysfs_create_group(&vdev->dev.kobj, &vcc_attribute_group); + if (rv) + goto free_domain; + + init_timer(&port->rx_timer); + port->rx_timer.function = vcc_rx_timer; + port->rx_timer.data = port->index; + + init_timer(&port->tx_timer); + port->tx_timer.function = vcc_tx_timer; + port->tx_timer.data = port->index; + + dev_set_drvdata(&vdev->dev, port); + + /* It's possible to receive IRQs in the middle of vio_port_up. Disable + * IRQs until the port is up. + */ + disable_irq_nosync(vdev->rx_irq); + vio_port_up(&port->vio); + enable_irq(vdev->rx_irq); + + return 0; + +free_domain: + kfree(port->domain); +unreg_tty: + tty_unregister_device(vcc_tty_driver, port->index); +free_table: + vcc_table_remove(port->index); +free_ldc: + vio_ldc_free(&port->vio); +free_port: + kfree(name); + kfree(port); + + return rv; +} + +/** + * vcc_remove() - Terminate a VCC port + * @vdev: Pointer to VIO device of the VCC port + * + * Terminates a VCC port. Sets up the teardown of TTY and + * VIO/LDC link between guest and primary domains. + * + * Return: status of removal + */ +static int vcc_remove(struct vio_dev *vdev) +{ + struct vcc_port *port = dev_get_drvdata(&vdev->dev); + + if (!port) + return -ENODEV; + + del_timer_sync(&port->rx_timer); + del_timer_sync(&port->tx_timer); + + /* If there's a process with the device open, do a synchronous + * hangup of the TTY. This *may* cause the process to call close + * asynchronously, but it's not guaranteed. + */ + if (port->tty) + tty_vhangup(port->tty); + + /* Get exclusive reference to VCC, ensures that there are no other + * clients to this port + */ + port = vcc_get(port->index, true); + + if (WARN_ON(!port)) + return -ENODEV; + + tty_unregister_device(vcc_tty_driver, port->index); + + del_timer_sync(&port->vio.timer); + vio_ldc_free(&port->vio); + sysfs_remove_group(&vdev->dev.kobj, &vcc_attribute_group); + dev_set_drvdata(&vdev->dev, NULL); + if (port->tty) { + port->removed = true; + vcc_put(port, true); + } else { + vcc_table_remove(port->index); + + kfree(port->vio.name); + kfree(port->domain); + kfree(port); + } + + return 0; +} + +static const struct vio_device_id vcc_match[] = { + { + .type = "vcc-port", + }, + {}, +}; +MODULE_DEVICE_TABLE(vio, vcc_match); + +static struct vio_driver vcc_driver = { + .id_table = vcc_match, + .probe = vcc_probe, + .remove = vcc_remove, + .name = "vcc", +}; + +static int vcc_open(struct tty_struct *tty, struct file *vcc_file) +{ + struct vcc_port *port; + + if (unlikely(!tty)) { + pr_err("VCC: open: Invalid TTY handle\n"); + return -ENXIO; + } + + if (tty->count > 1) + return -EBUSY; + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: open: Failed to find VCC port\n"); + return -ENODEV; + } + + if (unlikely(!port->vio.lp)) { + pr_err("VCC: open: LDC channel not configured\n"); + vcc_put(port, false); + return -EPIPE; + } + vccdbgl(port->vio.lp); + + vcc_put(port, false); + + if (unlikely(!tty->port)) { + pr_err("VCC: open: TTY port not found\n"); + return -ENXIO; + } + + if (unlikely(!tty->port->ops)) { + pr_err("VCC: open: TTY ops not defined\n"); + return -ENXIO; + } + + return tty_port_open(tty->port, tty, vcc_file); +} + +static void vcc_close(struct tty_struct *tty, struct file *vcc_file) +{ + if (unlikely(!tty)) { + pr_err("VCC: close: Invalid TTY handle\n"); + return; + } + + if (unlikely(tty->count > 1)) + return; + + if (unlikely(!tty->port)) { + pr_err("VCC: close: TTY port not found\n"); + return; + } + + tty_port_close(tty->port, tty, vcc_file); +} + +static void vcc_ldc_hup(struct vcc_port *port) +{ + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + + if (vcc_send_ctl(port, VCC_CTL_HUP) < 0) + vcc_kick_tx(port); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static void vcc_hangup(struct tty_struct *tty) +{ + struct vcc_port *port; + + if (unlikely(!tty)) { + pr_err("VCC: hangup: Invalid TTY handle\n"); + return; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: hangup: Failed to find VCC port\n"); + return; + } + + if (unlikely(!tty->port)) { + pr_err("VCC: hangup: TTY port not found\n"); + vcc_put(port, false); + return; + } + + vcc_ldc_hup(port); + + vcc_put(port, false); + + tty_port_hangup(tty->port); +} + +static int vcc_write(struct tty_struct *tty, const unsigned char *buf, + int count) +{ + struct vcc_port *port; + struct vio_vcc *pkt; + unsigned long flags; + int total_sent = 0; + int tosend = 0; + int rv = -EINVAL; + + if (unlikely(!tty)) { + pr_err("VCC: write: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: write: Failed to find VCC port"); + return -ENODEV; + } + + spin_lock_irqsave(&port->lock, flags); + + pkt = &port->buffer; + pkt->tag.type = VIO_TYPE_DATA; + + while (count > 0) { + /* Minimum of data to write and space available */ + tosend = min(count, (VCC_BUFF_LEN - port->chars_in_buffer)); + + if (!tosend) + break; + + memcpy(&pkt->data[port->chars_in_buffer], &buf[total_sent], + tosend); + port->chars_in_buffer += tosend; + pkt->tag.stype = tosend; + + vccdbg("TAG [%02x:%02x:%04x:%08x]\n", pkt->tag.type, + pkt->tag.stype, pkt->tag.stype_env, pkt->tag.sid); + vccdbg("DATA [%s]\n", pkt->data); + vccdbgl(port->vio.lp); + + /* Since we know we have enough room in VCC buffer for tosend + * we record that it was sent regardless of whether the + * hypervisor actually took it because we have it buffered. + */ + rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend)); + vccdbg("VCC: write: ldc_write(%d)=%d\n", + (VIO_TAG_SIZE + tosend), rv); + + total_sent += tosend; + count -= tosend; + if (rv < 0) { + vcc_kick_tx(port); + break; + } + + port->chars_in_buffer = 0; + } + + spin_unlock_irqrestore(&port->lock, flags); + + vcc_put(port, false); + + vccdbg("VCC: write: total=%d rv=%d", total_sent, rv); + + return total_sent ? total_sent : rv; +} + +static int vcc_write_room(struct tty_struct *tty) +{ + struct vcc_port *port; + u64 num; + + if (unlikely(!tty)) { + pr_err("VCC: write_room: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: write_room: Failed to find VCC port\n"); + return -ENODEV; + } + + num = VCC_BUFF_LEN - port->chars_in_buffer; + + vcc_put(port, false); + + return num; +} + +static int vcc_chars_in_buffer(struct tty_struct *tty) +{ + struct vcc_port *port; + u64 num; + + if (unlikely(!tty)) { + pr_err("VCC: chars_in_buffer: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: chars_in_buffer: Failed to find VCC port\n"); + return -ENODEV; + } + + num = port->chars_in_buffer; + + vcc_put(port, false); + + return num; +} + +static int vcc_break_ctl(struct tty_struct *tty, int state) +{ + struct vcc_port *port; + unsigned long flags; + + if (unlikely(!tty)) { + pr_err("VCC: break_ctl: Invalid TTY handle\n"); + return -ENXIO; + } + + port = vcc_get_ne(tty->index); + if (unlikely(!port)) { + pr_err("VCC: break_ctl: Failed to find VCC port\n"); + return -ENODEV; + } + + /* Turn off break */ + if (state == 0) { + vcc_put(port, false); + return 0; + } + + spin_lock_irqsave(&port->lock, flags); + + if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0) + vcc_kick_tx(port); + + spin_unlock_irqrestore(&port->lock, flags); + + vcc_put(port, false); + + return 0; +} + +static int vcc_install(struct tty_driver *driver, struct tty_struct *tty) +{ + struct vcc_port *port_vcc; + struct tty_port *port_tty; + int ret; + + if (unlikely(!tty)) { + pr_err("VCC: install: Invalid TTY handle\n"); + return -ENXIO; + } + + if (tty->index >= VCC_MAX_PORTS) + return -EINVAL; + + ret = tty_standard_install(driver, tty); + if (ret) + return ret; + + port_tty = kzalloc(sizeof(struct tty_port), GFP_KERNEL); + if (!port_tty) + return -ENOMEM; + + port_vcc = vcc_get(tty->index, true); + if (!port_vcc) { + pr_err("VCC: install: Failed to find VCC port\n"); + tty->port = NULL; + kfree(port_tty); + return -ENODEV; + } + + tty_port_init(port_tty); + port_tty->ops = &vcc_port_ops; + tty->port = port_tty; + + port_vcc->tty = tty; + + vcc_put(port_vcc, true); + + return 0; +} + +static void vcc_cleanup(struct tty_struct *tty) +{ + struct vcc_port *port; + + if (unlikely(!tty)) { + pr_err("VCC: cleanup: Invalid TTY handle\n"); + return; + } + + port = vcc_get(tty->index, true); + if (port) { + port->tty = NULL; + + if (port->removed) { + vcc_table_remove(tty->index); + kfree(port->vio.name); + kfree(port->domain); + kfree(port); + } else { + vcc_put(port, true); + } + } + + tty_port_destroy(tty->port); + kfree(tty->port); + tty->port = NULL; +} + +static const struct tty_operations vcc_ops = { + .open = vcc_open, + .close = vcc_close, + .hangup = vcc_hangup, + .write = vcc_write, + .write_room = vcc_write_room, + .chars_in_buffer = vcc_chars_in_buffer, + .break_ctl = vcc_break_ctl, + .install = vcc_install, + .cleanup = vcc_cleanup, +}; + +#define VCC_TTY_FLAGS (TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_REAL_RAW) + +static int vcc_tty_init(void) +{ + int rv; + + pr_info("VCC: %s\n", version); + + vcc_tty_driver = tty_alloc_driver(VCC_MAX_PORTS, VCC_TTY_FLAGS); + if (IS_ERR(vcc_tty_driver)) { + pr_err("VCC: TTY driver alloc failed\n"); + return PTR_ERR(vcc_tty_driver); + } + + vcc_tty_driver->driver_name = vcc_driver_name; + vcc_tty_driver->name = vcc_device_node; + + vcc_tty_driver->minor_start = VCC_MINOR_START; + vcc_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; + vcc_tty_driver->init_termios = vcc_tty_termios; + + tty_set_operations(vcc_tty_driver, &vcc_ops); + + rv = tty_register_driver(vcc_tty_driver); + if (rv) { + pr_err("VCC: TTY driver registration failed\n"); + put_tty_driver(vcc_tty_driver); + vcc_tty_driver = NULL; + return rv; + } + + vccdbg("VCC: TTY driver registered\n"); + + return 0; +} + +static void vcc_tty_exit(void) +{ + tty_unregister_driver(vcc_tty_driver); + put_tty_driver(vcc_tty_driver); + vccdbg("VCC: TTY driver unregistered\n"); + + vcc_tty_driver = NULL; +} + +static int __init vcc_init(void) +{ + int rv; + + rv = vcc_tty_init(); + if (rv) { + pr_err("VCC: TTY init failed\n"); + return rv; + } + + rv = vio_register_driver(&vcc_driver); + if (rv) { + pr_err("VCC: VIO driver registration failed\n"); + vcc_tty_exit(); + } else { + vccdbg("VCC: VIO driver registered successfully\n"); + } + + return rv; +} + +static void __exit vcc_exit(void) +{ + vio_unregister_driver(&vcc_driver); + vccdbg("VCC: VIO driver unregistered\n"); + vcc_tty_exit(); + vccdbg("VCC: TTY driver unregistered\n"); +} + +module_init(vcc_init); +module_exit(vcc_exit); diff --git a/drivers/tty/vt/Makefile b/drivers/tty/vt/Makefile index 17ae94cb29f8..edbbe0ccdb83 100644 --- a/drivers/tty/vt/Makefile +++ b/drivers/tty/vt/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # This file contains the font map for the default (hardware) font # diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index accbd1257bc4..7a4c8022c023 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This module exports the functions: * diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 56dcff6059d3..85b6634f518a 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Provide access to virtual console memory. * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled) diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 96d389cb506c..2d2b420598b2 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 1992 obz under the linux copyright * diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile index e9663bb8a4c7..c285dd2a4539 100644 --- a/drivers/uio/Makefile +++ b/drivers/uio/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_UIO) += uio.o obj-$(CONFIG_UIO_CIF) += uio_cif.o obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 9650b351c26c..060643a1b5c8 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the kernel USB device drivers. # diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile index ac278946b06c..7ac65ce1aa8a 100644 --- a/drivers/usb/atm/Makefile +++ b/drivers/usb/atm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for USB ATM/xDSL drivers # diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index d65a64c29b85..5160a4a966b3 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -43,7 +43,6 @@ #include "usbatm.h" #define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott" -#define DRIVER_VERSION "0.4" #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" static const char cxacru_driver_name[] = "cxacru"; @@ -1380,4 +1379,3 @@ module_usb_driver(cxacru_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 5083eb5b0d5e..3676adb40d89 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -40,8 +40,7 @@ #include "usbatm.h" #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands " -#define DRIVER_VERSION "1.10" -#define DRIVER_DESC "Alcatel SpeedTouch USB driver version " DRIVER_VERSION +#define DRIVER_DESC "Alcatel SpeedTouch USB driver" static const char speedtch_driver_name[] = "speedtch"; @@ -738,7 +737,7 @@ static int speedtch_post_reset(struct usb_interface *intf) ** USB ** **********/ -static struct usb_device_id speedtch_usb_ids[] = { +static const struct usb_device_id speedtch_usb_ids[] = { {USB_DEVICE(0x06b9, 0x4061)}, {} }; @@ -962,4 +961,3 @@ module_usb_driver(speedtch_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index df67815f74e6..ba7616395db2 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2212,7 +2212,7 @@ static int uea_boot(struct uea_softc *sc) ret = usb_submit_urb(sc->urb_int, GFP_KERNEL); if (ret < 0) { uea_err(INS_TO_USBDEV(sc), - "urb submition failed with error %d\n", ret); + "urb submission failed with error %d\n", ret); goto err1; } @@ -2522,7 +2522,7 @@ static struct attribute *attrs[] = { &dev_attr_stat_firmid.attr, NULL, }; -static struct attribute_group attr_grp = { +static const struct attribute_group attr_grp = { .attrs = attrs, }; diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 3e80aa3b917a..8607af758bbd 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -93,8 +93,7 @@ static int usbatm_print_packet(struct usbatm_data *instance, const unsigned char #endif #define DRIVER_AUTHOR "Johan Verrept, Duncan Sands " -#define DRIVER_VERSION "1.10" -#define DRIVER_DESC "Generic USB ATM/DSL I/O, version " DRIVER_VERSION +#define DRIVER_DESC "Generic USB ATM/DSL I/O" static const char usbatm_driver_name[] = "usbatm"; @@ -174,7 +173,7 @@ static int usbatm_atm_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __us static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb); static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t *pos, char *page); -static struct atmdev_ops usbatm_atm_devops = { +static const struct atmdev_ops usbatm_atm_devops = { .dev_close = usbatm_atm_dev_close, .open = usbatm_atm_open, .close = usbatm_atm_close, @@ -1315,7 +1314,6 @@ module_exit(usbatm_usb_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); /************ ** debug ** diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c index a87597f88a84..c73c1ec3005e 100644 --- a/drivers/usb/atm/xusbatm.c +++ b/drivers/usb/atm/xusbatm.c @@ -228,4 +228,3 @@ module_exit(xusbatm_exit); MODULE_AUTHOR("Roman Kagan, Duncan Sands"); MODULE_DESCRIPTION("Driver for USB ADSL modems initialized in userspace"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c index c2d13968da82..30d3f346686e 100644 --- a/drivers/usb/c67x00/c67x00-hcd.c +++ b/drivers/usb/c67x00/c67x00-hcd.c @@ -305,7 +305,7 @@ static int c67x00_hcd_get_frame(struct usb_hcd *hcd) return temp_val ? (temp_val - 1) : HOST_FRAME_MASK; } -static struct hc_driver c67x00_hc_driver = { +static const struct hc_driver c67x00_hc_driver = { .description = "c67x00-hcd", .product_desc = "Cypress C67X00 Host Controller", .hcd_priv_size = sizeof(struct c67x00_hcd), diff --git a/drivers/usb/chipidea/Makefile b/drivers/usb/chipidea/Makefile index 39fca5715ed3..e3d5e728fa53 100644 --- a/drivers/usb/chipidea/Makefile +++ b/drivers/usb/chipidea/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc.o ci_hdrc-y := core.o otg.o debug.o @@ -15,3 +16,4 @@ obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc_zevio.o obj-$(CONFIG_USB_CHIPIDEA_PCI) += ci_hdrc_pci.o obj-$(CONFIG_USB_CHIPIDEA_OF) += usbmisc_imx.o ci_hdrc_imx.o +obj-$(CONFIG_USB_CHIPIDEA_OF) += ci_hdrc_tegra.o diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 0bdfcdcbf7a5..bb626120296f 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -251,7 +251,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) if (ret) goto err_mux; - ulpi_node = of_find_node_by_name(pdev->dev.of_node, "ulpi"); + ulpi_node = of_find_node_by_name(of_node_get(pdev->dev.of_node), "ulpi"); if (ulpi_node) { phy_node = of_get_next_available_child(ulpi_node, NULL); ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy"); diff --git a/drivers/usb/chipidea/ci_hdrc_pci.c b/drivers/usb/chipidea/ci_hdrc_pci.c index b635ab67490d..39414e4b2d81 100644 --- a/drivers/usb/chipidea/ci_hdrc_pci.c +++ b/drivers/usb/chipidea/ci_hdrc_pci.c @@ -170,5 +170,4 @@ module_pci_driver(ci_hdrc_pci_driver); MODULE_AUTHOR("MIPS - David Lopo "); MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller"); MODULE_LICENSE("GPL"); -MODULE_VERSION("June 2008"); MODULE_ALIAS("platform:ci13xxx_pci"); diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c new file mode 100644 index 000000000000..bfcee2702d50 --- /dev/null +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016, NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include + +#include "ci.h" + +struct tegra_udc { + struct ci_hdrc_platform_data data; + struct platform_device *dev; + + struct usb_phy *phy; + struct clk *clk; +}; + +struct tegra_udc_soc_info { + unsigned long flags; +}; + +static const struct tegra_udc_soc_info tegra20_udc_soc_info = { + .flags = CI_HDRC_REQUIRES_ALIGNED_DMA, +}; + +static const struct tegra_udc_soc_info tegra30_udc_soc_info = { + .flags = 0, +}; + +static const struct tegra_udc_soc_info tegra114_udc_soc_info = { + .flags = 0, +}; + +static const struct tegra_udc_soc_info tegra124_udc_soc_info = { + .flags = 0, +}; + +static const struct of_device_id tegra_udc_of_match[] = { + { + .compatible = "nvidia,tegra20-udc", + .data = &tegra20_udc_soc_info, + }, { + .compatible = "nvidia,tegra30-udc", + .data = &tegra30_udc_soc_info, + }, { + .compatible = "nvidia,tegra114-udc", + .data = &tegra114_udc_soc_info, + }, { + .compatible = "nvidia,tegra124-udc", + .data = &tegra124_udc_soc_info, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, tegra_udc_of_match); + +static int tegra_udc_probe(struct platform_device *pdev) +{ + const struct tegra_udc_soc_info *soc; + struct tegra_udc *udc; + int err; + + udc = devm_kzalloc(&pdev->dev, sizeof(*udc), GFP_KERNEL); + if (!udc) + return -ENOMEM; + + soc = of_device_get_match_data(&pdev->dev); + if (!soc) { + dev_err(&pdev->dev, "failed to match OF data\n"); + return -EINVAL; + } + + udc->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); + if (IS_ERR(udc->phy)) { + err = PTR_ERR(udc->phy); + dev_err(&pdev->dev, "failed to get PHY: %d\n", err); + return err; + } + + udc->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(udc->clk)) { + err = PTR_ERR(udc->clk); + dev_err(&pdev->dev, "failed to get clock: %d\n", err); + return err; + } + + err = clk_prepare_enable(udc->clk); + if (err < 0) { + dev_err(&pdev->dev, "failed to enable clock: %d\n", err); + return err; + } + + /* + * Tegra's USB PHY driver doesn't implement optional phy_init() + * hook, so we have to power on UDC controller before ChipIdea + * driver initialization kicks in. + */ + usb_phy_set_suspend(udc->phy, 0); + + /* setup and register ChipIdea HDRC device */ + udc->data.name = "tegra-udc"; + udc->data.flags = soc->flags; + udc->data.usb_phy = udc->phy; + udc->data.capoffset = DEF_CAPOFFSET; + + udc->dev = ci_hdrc_add_device(&pdev->dev, pdev->resource, + pdev->num_resources, &udc->data); + if (IS_ERR(udc->dev)) { + err = PTR_ERR(udc->dev); + dev_err(&pdev->dev, "failed to add HDRC device: %d\n", err); + goto fail_power_off; + } + + platform_set_drvdata(pdev, udc); + + return 0; + +fail_power_off: + usb_phy_set_suspend(udc->phy, 1); + clk_disable_unprepare(udc->clk); + return err; +} + +static int tegra_udc_remove(struct platform_device *pdev) +{ + struct tegra_udc *udc = platform_get_drvdata(pdev); + + usb_phy_set_suspend(udc->phy, 1); + clk_disable_unprepare(udc->clk); + + return 0; +} + +static struct platform_driver tegra_udc_driver = { + .driver = { + .name = "tegra-udc", + .of_match_table = tegra_udc_of_match, + }, + .probe = tegra_udc_probe, + .remove = tegra_udc_remove, +}; +module_platform_driver(tegra_udc_driver); + +MODULE_DESCRIPTION("NVIDIA Tegra USB device mode driver"); +MODULE_AUTHOR("Thierry Reding "); +MODULE_ALIAS("platform:tegra-udc"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c index d162cc0bb8ce..99425db9ba62 100644 --- a/drivers/usb/chipidea/ci_hdrc_usb2.c +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -52,6 +52,8 @@ static int ci_hdrc_usb2_probe(struct platform_device *pdev) if (!ci_pdata) { ci_pdata = devm_kmalloc(dev, sizeof(*ci_pdata), GFP_KERNEL); + if (!ci_pdata) + return -ENOMEM; *ci_pdata = ci_default_pdata; /* struct copy */ } diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index b17ed3a9a304..43ea5fb87b9a 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -736,7 +736,7 @@ static int ci_extcon_register(struct ci_hdrc *ci) id = &ci->platdata->id_extcon; id->ci = ci; - if (!IS_ERR(id->edev)) { + if (!IS_ERR_OR_NULL(id->edev)) { ret = devm_extcon_register_notifier(ci->dev, id->edev, EXTCON_USB_HOST, &id->nb); if (ret < 0) { @@ -747,7 +747,7 @@ static int ci_extcon_register(struct ci_hdrc *ci) vbus = &ci->platdata->vbus_extcon; vbus->ci = ci; - if (!IS_ERR(vbus->edev)) { + if (!IS_ERR_OR_NULL(vbus->edev)) { ret = devm_extcon_register_notifier(ci->dev, vbus->edev, EXTCON_USB, &vbus->nb); if (ret < 0) { @@ -887,7 +887,7 @@ static struct attribute *ci_attrs[] = { NULL, }; -static struct attribute_group ci_attr_group = { +static const struct attribute_group ci_attr_group = { .attrs = ci_attrs, }; diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index 1c31e8a08810..c9e1a165ed82 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/usb/chipidea/host.h b/drivers/usb/chipidea/host.h index 0f12f131bdd3..70112cf0f195 100644 --- a/drivers/usb/chipidea/host.h +++ b/drivers/usb/chipidea/host.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __DRIVERS_USB_CHIPIDEA_HOST_H #define __DRIVERS_USB_CHIPIDEA_HOST_H diff --git a/drivers/usb/chipidea/otg_fsm.c b/drivers/usb/chipidea/otg_fsm.c index 949183ede16f..5ea0246f650d 100644 --- a/drivers/usb/chipidea/otg_fsm.c +++ b/drivers/usb/chipidea/otg_fsm.c @@ -193,7 +193,7 @@ static struct attribute *inputs_attrs[] = { NULL, }; -static struct attribute_group inputs_attr_group = { +static const struct attribute_group inputs_attr_group = { .name = "inputs", .attrs = inputs_attrs, }; diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index d68b125796f9..fe8a90543ea3 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -944,7 +944,6 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) */ static int isr_setup_status_phase(struct ci_hdrc *ci) { - int retval; struct ci_hw_ep *hwep; /* @@ -960,9 +959,7 @@ static int isr_setup_status_phase(struct ci_hdrc *ci) ci->status->context = ci; ci->status->complete = isr_setup_status_complete; - retval = _ep_queue(&hwep->ep, ci->status, GFP_ATOMIC); - - return retval; + return _ep_queue(&hwep->ep, ci->status, GFP_ATOMIC); } /** @@ -1899,6 +1896,9 @@ static int udc_start(struct ci_hdrc *ci) ci->gadget.name = ci->platdata->name; ci->gadget.otg_caps = otg_caps; + if (ci->platdata->flags & CI_HDRC_REQUIRES_ALIGNED_DMA) + ci->gadget.quirk_avoids_skb_reserve = 1; + if (ci->is_otg && (otg_caps->hnp_support || otg_caps->srp_support || otg_caps->adp_support)) ci->gadget.is_otg = 1; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 5e056064259c..18c923a4c16e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1832,6 +1832,9 @@ static const struct usb_device_id acm_ids[] = { { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ }, + { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ + .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ + }, { USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */ .driver_info = CLEAR_HALT_CONDITIONS, diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 7a2b3deafc90..eacc116e83da 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Includes for cdc-acm.c diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8f972247b1c1..3e865dbf878c 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -26,10 +26,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v0.03" #define DRIVER_AUTHOR "Oliver Neukum" #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" @@ -194,8 +190,10 @@ static void wdm_in_callback(struct urb *urb) /* * only set a new error if there is no previous error. * Errors are only cleared during read/open + * Avoid propagating -EPIPE (stall) to userspace since it is + * better handled as an empty read */ - if (desc->rerr == 0) + if (desc->rerr == 0 && status != -EPIPE) desc->rerr = status; if (length + desc->length > desc->wMaxCommand) { diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 578f424decc2..6ebfabfa0dc7 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -1085,7 +1085,7 @@ static struct attribute *capability_attrs[] = { NULL, }; -static struct attribute_group capability_attr_grp = { +static const struct attribute_group capability_attr_grp = { .attrs = capability_attrs, }; @@ -1151,7 +1151,7 @@ static struct attribute *data_attrs[] = { NULL, }; -static struct attribute_group data_attr_grp = { +static const struct attribute_group data_attr_grp = { .attrs = data_attrs, }; diff --git a/drivers/usb/common/Makefile b/drivers/usb/common/Makefile index 6bbb3ec17018..0a7c45e85481 100644 --- a/drivers/usb/common/Makefile +++ b/drivers/usb/common/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the usb common parts. # diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index 5ef8da6e67c3..552ff7ac5a6b 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -190,10 +190,7 @@ EXPORT_SYMBOL_GPL(of_usb_get_dr_mode_by_phy); */ bool of_usb_host_tpl_support(struct device_node *np) { - if (of_find_property(np, "tpl-support", NULL)) - return true; - - return false; + return of_property_read_bool(np, "tpl-support"); } EXPORT_SYMBOL_GPL(of_usb_host_tpl_support); @@ -227,8 +224,8 @@ int of_usb_update_otg_caps(struct device_node *np, otg_caps->otg_rev = otg_rev; break; default: - pr_err("%s: unsupported otg-rev: 0x%x\n", - np->full_name, otg_rev); + pr_err("%pOF: unsupported otg-rev: 0x%x\n", + np, otg_rev); return -EINVAL; } } else { @@ -240,11 +237,11 @@ int of_usb_update_otg_caps(struct device_node *np, otg_caps->otg_rev = 0; } - if (of_find_property(np, "hnp-disable", NULL)) + if (of_property_read_bool(np, "hnp-disable")) otg_caps->hnp_support = false; - if (of_find_property(np, "srp-disable", NULL)) + if (of_property_read_bool(np, "srp-disable")) otg_caps->srp_support = false; - if (of_find_property(np, "adp-disable", NULL) || + if (of_property_read_bool(np, "adp-disable") || (otg_caps->otg_rev < 0x0200)) otg_caps->adp_support = false; diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 930e8f35f8df..4aa5195db8ea 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -135,7 +135,7 @@ static void ulpi_dev_release(struct device *dev) kfree(to_ulpi_dev(dev)); } -static struct device_type ulpi_dev_type = { +static const struct device_type ulpi_dev_type = { .name = "ulpi_device", .groups = ulpi_dev_attr_groups, .release = ulpi_dev_release, diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index 250ec1d662d9..92c9cefb4317 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for USB Core files and filesystem # diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 4be52c602e9b..883549ee946c 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -643,15 +643,23 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, } else if (header->bDescriptorType == USB_DT_INTERFACE_ASSOCIATION) { + struct usb_interface_assoc_descriptor *d; + + d = (struct usb_interface_assoc_descriptor *)header; + if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) { + dev_warn(ddev, + "config %d has an invalid interface association descriptor of length %d, skipping\n", + cfgno, d->bLength); + continue; + } + if (iad_num == USB_MAXIADS) { dev_warn(ddev, "found more Interface " "Association Descriptors " "than allocated for in " "configuration %d\n", cfgno); } else { - config->intf_assoc[iad_num] = - (struct usb_interface_assoc_descriptor - *)header; + config->intf_assoc[iad_num] = d; iad_num++; } @@ -852,7 +860,7 @@ int usb_get_configuration(struct usb_device *dev) } if (dev->quirks & USB_QUIRK_DELAY_INIT) - msleep(100); + msleep(200); result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); @@ -952,10 +960,12 @@ int usb_get_bos_descriptor(struct usb_device *dev) for (i = 0; i < num; i++) { buffer += length; cap = (struct usb_dev_cap_header *)buffer; - length = cap->bLength; - if (total_len < length) + if (total_len < sizeof(*cap) || total_len < cap->bLength) { + dev->bos->desc->bNumDeviceCaps = i; break; + } + length = cap->bLength; total_len -= length; if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) { diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ebe27595c4af..e9326f31db8d 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -140,6 +140,9 @@ module_param(usbfs_memory_mb, uint, 0644); MODULE_PARM_DESC(usbfs_memory_mb, "maximum MB allowed for usbfs buffers (0 = no limit)"); +/* Hard limit, necessary to avoid arithmetic overflow */ +#define USBFS_XFER_MAX (UINT_MAX / 2 - 1000000) + static atomic64_t usbfs_memory_usage; /* Total memory currently allocated */ /* Check whether it's okay to allocate more memory for a transfer */ @@ -210,7 +213,7 @@ static void usbdev_vm_close(struct vm_area_struct *vma) dec_usb_memory_use_count(usbm, &usbm->vma_use_count); } -static struct vm_operations_struct usbdev_vm_ops = { +static const struct vm_operations_struct usbdev_vm_ops = { .open = usbdev_vm_open, .close = usbdev_vm_close }; @@ -623,6 +626,8 @@ static void async_completed(struct urb *urb) if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET && as->status != -ENOENT) cancel_bulk_urbs(ps, as->bulk_addr); + + wake_up(&ps->wait); spin_unlock(&ps->lock); if (signr) { @@ -630,8 +635,6 @@ static void async_completed(struct urb *urb) put_pid(pid); put_cred(cred); } - - wake_up(&ps->wait); } static void destroy_async(struct usb_dev_state *ps, struct list_head *list) @@ -1460,6 +1463,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb USBDEVFS_URB_ZERO_PACKET | USBDEVFS_URB_NO_INTERRUPT)) return -EINVAL; + if ((unsigned int)uurb->buffer_length >= USBFS_XFER_MAX) + return -EINVAL; if (uurb->buffer_length > 0 && !uurb->buffer) return -EINVAL; if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 7f277b092b5b..75ad6718858c 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -972,7 +972,7 @@ static struct attribute *usb_bus_attrs[] = { NULL, }; -static struct attribute_group usb_bus_attr_group = { +static const struct attribute_group usb_bus_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = usb_bus_attrs, }; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 822f8c50e423..e9ce6bb0b22d 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2614,7 +2614,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub) #define SET_CONFIG_TRIES (2 * (use_both_schemes + 1)) #define USE_NEW_SCHEME(i) ((i) / 2 == (int)old_scheme_first) -#define HUB_ROOT_RESET_TIME 50 /* times are in msec */ +#define HUB_ROOT_RESET_TIME 60 /* times are in msec */ #define HUB_SHORT_RESET_TIME 10 #define HUB_BH_RESET_TIME 50 #define HUB_LONG_RESET_TIME 200 @@ -2710,13 +2710,16 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, if (!(portstatus & USB_PORT_STAT_CONNECTION)) return -ENOTCONN; - /* bomb out completely if the connection bounced. A USB 3.0 - * connection may bounce if multiple warm resets were issued, + /* Retry if connect change is set but status is still connected. + * A USB 3.0 connection may bounce if multiple warm resets were issued, * but the device may have successfully re-connected. Ignore it. */ if (!hub_is_superspeed(hub->hdev) && - (portchange & USB_PORT_STAT_C_CONNECTION)) - return -ENOTCONN; + (portchange & USB_PORT_STAT_C_CONNECTION)) { + usb_clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_CONNECTION); + return -EAGAIN; + } if (!(portstatus & USB_PORT_STAT_ENABLE)) return -EBUSY; @@ -4342,6 +4345,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, enum usb_device_speed oldspeed = udev->speed; const char *speed; int devnum = udev->devnum; + const char *driver_name; /* root hub ports have a slightly longer reset period * (from USB 2.0 spec, section 7.1.7.5) @@ -4409,11 +4413,23 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, else speed = usb_speed_string(udev->speed); + /* + * The controller driver may be NULL if the controller device + * is the middle device between platform device and roothub. + * This middle device may not need a device driver due to + * all hardware control can be at platform device driver, this + * platform device is usually a dual-role USB controller device. + */ + if (udev->bus->controller->driver) + driver_name = udev->bus->controller->driver->name; + else + driver_name = udev->bus->sysdev->driver->name; + if (udev->speed < USB_SPEED_SUPER) dev_info(&udev->dev, "%s %s USB device number %d using %s\n", (udev->config) ? "reset" : "new", speed, - devnum, udev->bus->controller->driver->name); + devnum, driver_name); /* Set up TT records, if needed */ if (hdev->tt) { @@ -4545,7 +4561,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, "%s SuperSpeed%s USB device number %d using %s\n", (udev->config) ? "reset" : "new", (udev->speed == USB_SPEED_SUPER_PLUS) ? "Plus" : "", - devnum, udev->bus->controller->driver->name); + devnum, driver_name); } /* cope with hardware quirkiness: @@ -4825,7 +4841,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, goto loop; if (udev->quirks & USB_QUIRK_DELAY_INIT) - msleep(1000); + msleep(2000); /* consecutive bus-powered hubs aren't reliable; they can * violate the voltage drop budget. if the new child has diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index 16c19a31dad1..1af877942110 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c @@ -149,8 +149,8 @@ static bool usbport_trig_port_observed(struct usbport_trig_data *usbport_data, count = of_count_phandle_with_args(led_np, "trigger-sources", "#trigger-source-cells"); if (count < 0) { - dev_warn(dev, "Failed to get trigger sources for %s\n", - led_np->full_name); + dev_warn(dev, "Failed to get trigger sources for %pOF\n", + led_np); return false; } @@ -205,6 +205,7 @@ static int usbport_trig_add_port(struct usbport_trig_data *usbport_data, } snprintf(port->port_name, len, "%s-port%d", hub_name, portnum); + sysfs_attr_init(&port->attr.attr); port->attr.attr.name = port->port_name; port->attr.attr.mode = S_IRUSR | S_IWUSR; port->attr.show = usbport_trig_port_show; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 4c38ea41ae96..371a07d874a3 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -2069,6 +2069,10 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, elength = 1; goto next_desc; } + if ((buflen < elength) || (elength < 3)) { + dev_err(&intf->dev, "invalid descriptor buffer length\n"); + break; + } if (buffer[1] != USB_DT_CS_INTERFACE) { dev_err(&intf->dev, "skipping garbage\n"); goto next_desc; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 574da2b4529c..a6aaf2f193a4 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -57,8 +57,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* Microsoft LifeCam-VX700 v2.0 */ { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech HD Pro Webcams C920 and C930e */ + /* Logitech HD Pro Webcams C920, C920-C and C930e */ { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, + { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, /* Logitech ConferenceCam CC3000e */ @@ -217,6 +218,13 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x1a0a, 0x0200), .driver_info = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + /* Corsair Strafe RGB */ + { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT }, + + /* MIDI keyboard WORLDE MINI */ + { USB_DEVICE(0x1c75, 0x0204), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Acer C120 LED Projector */ { USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM }, diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index dfc68ed24db1..d930bfda4010 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -113,7 +113,7 @@ static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, { struct device_node *of_node = dev->of_node; - return sprintf(buf, "%s\n", of_node_full_name(of_node)); + return sprintf(buf, "%pOF\n", of_node); } static DEVICE_ATTR_RO(devspec); #endif diff --git a/drivers/usb/dwc2/Makefile b/drivers/usb/dwc2/Makefile index b9237e1e45d0..440320cc20a4 100644 --- a/drivers/usb/dwc2/Makefile +++ b/drivers/usb/dwc2/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_USB_DWC2_DEBUG) += -DDEBUG ccflags-$(CONFIG_USB_DWC2_VERBOSE) += -DVERBOSE_DEBUG diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index c4066cd77e47..0d8e09ccb59c 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -4179,7 +4179,7 @@ static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) return ret; } -static struct usb_ep_ops dwc2_hsotg_ep_ops = { +static const struct usb_ep_ops dwc2_hsotg_ep_ops = { .enable = dwc2_hsotg_ep_enable, .disable = dwc2_hsotg_ep_disable, .alloc_request = dwc2_hsotg_ep_alloc_request, diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 740c7e86d31b..c2631145f404 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4388,6 +4388,9 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); + if (dwc2_is_device_mode(hsotg)) + goto unlock; + if (hsotg->lx_state != DWC2_L0) goto unlock; @@ -4446,6 +4449,9 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); + if (dwc2_is_device_mode(hsotg)) + goto unlock; + if (hsotg->lx_state != DWC2_L2) goto unlock; diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index f15fabbd1e59..7ac725038f8d 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # define_trace.h needs to know how to find our header CFLAGS_trace.o := -I$(src) diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 12ee23f53cdd..d2ed9523e77c 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include /* USBSS register offsets */ #define USBSS_REVISION 0x0000 @@ -41,7 +41,6 @@ struct dwc3_keystone { struct device *dev; - struct clk *clk; void __iomem *usbss; }; @@ -106,17 +105,13 @@ static int kdwc3_probe(struct platform_device *pdev) if (IS_ERR(kdwc->usbss)) return PTR_ERR(kdwc->usbss); - kdwc->clk = devm_clk_get(kdwc->dev, "usb"); - if (IS_ERR(kdwc->clk)) { - dev_err(kdwc->dev, "unable to get usb clock\n"); - return PTR_ERR(kdwc->clk); - } + pm_runtime_enable(kdwc->dev); - error = clk_prepare_enable(kdwc->clk); + error = pm_runtime_get_sync(kdwc->dev); if (error < 0) { - dev_err(kdwc->dev, "unable to enable usb clock, error %d\n", + dev_err(kdwc->dev, "pm_runtime_get_sync failed, error %d\n", error); - return error; + goto err_irq; } irq = platform_get_irq(pdev, 0); @@ -147,7 +142,8 @@ static int kdwc3_probe(struct platform_device *pdev) err_core: kdwc3_disable_irqs(kdwc); err_irq: - clk_disable_unprepare(kdwc->clk); + pm_runtime_put_sync(kdwc->dev); + pm_runtime_disable(kdwc->dev); return error; } @@ -167,7 +163,9 @@ static int kdwc3_remove(struct platform_device *pdev) kdwc3_disable_irqs(kdwc); device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core); - clk_disable_unprepare(kdwc->clk); + pm_runtime_put_sync(kdwc->dev); + pm_runtime_disable(kdwc->dev); + platform_set_drvdata(pdev, NULL); return 0; diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index fe414e7a9c78..a26d1fde0f5e 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -96,7 +95,8 @@ static int dwc3_of_simple_probe(struct platform_device *pdev) platform_set_drvdata(pdev, simple); simple->dev = dev; - ret = dwc3_of_simple_clk_init(simple, of_clk_get_parent_count(np)); + ret = dwc3_of_simple_clk_init(simple, of_count_phandle_with_args(np, + "clocks", "#clock-cells")); if (ret) return ret; @@ -177,6 +177,7 @@ static const struct of_device_id of_dwc3_simple_match[] = { { .compatible = "rockchip,rk3399-dwc3" }, { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, + { .compatible = "sprd,sc9860-dwc3" }, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, of_dwc3_simple_match); diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index f5aaa0cf3873..3530795bbb8f 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -478,8 +478,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(dev, "missing IRQ resource\n"); - return -EINVAL; + dev_err(dev, "missing IRQ resource: %d\n", irq); + return irq; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 7e995df7a797..54343fbd85ee 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -345,7 +345,7 @@ static int dwc3_pci_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -static struct dev_pm_ops dwc3_pci_dev_pm_ops = { +static const struct dev_pm_ops dwc3_pci_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_suspend, dwc3_pci_resume) SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume, NULL) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 827e376bfa97..75e6cb044eb2 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -990,6 +990,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA, true); + req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; + /* Now prepare one extra TRB to align transfer size */ dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, maxpacket - rem, @@ -1015,6 +1017,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA, true); + req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; + /* Now prepare one extra TRB to align transfer size */ dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, 0, DWC3_TRBCTL_CONTROL_DATA, @@ -1029,6 +1033,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, dwc3_ep0_prepare_one_trb(dep, req->request.dma, req->request.length, DWC3_TRBCTL_CONTROL_DATA, false); + + req->trb = &dwc->ep0_trb[dep->trb_enqueue]; + ret = dwc3_ep0_start_trans(dep); } diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 35cc641d9f31..31cce7805eb2 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -130,7 +130,7 @@ config USB_GADGET_STORAGE_NUM_BUFFERS config U_SERIAL_CONSOLE bool "Serial gadget console support" - depends on USB_G_SERIAL + depends on USB_U_SERIAL help It supports the serial gadget can be used as a console. diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 598a67d6ba05..130dad7130b6 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB peripheral controller drivers # diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index dd74c99d6ce1..5d061b3d8224 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2026,6 +2026,8 @@ static DEVICE_ATTR_RO(suspended); static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) { struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_gadget_strings *gstr = cdev->driver->strings[0]; + struct usb_string *dev_str = gstr->strings; /* composite_disconnect() must already have been called * by the underlying peripheral controller driver! @@ -2045,6 +2047,9 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) composite_dev_cleanup(cdev); + if (dev_str[USB_GADGET_MANUFACTURER_IDX].s == cdev->def_manufacturer) + dev_str[USB_GADGET_MANUFACTURER_IDX].s = ""; + kfree(cdev->def_manufacturer); kfree(cdev); set_gadget_data(gadget, NULL); diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index a22a892de7b7..aeb9f3c40521 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1143,11 +1143,12 @@ static struct configfs_attribute *interf_grp_attrs[] = { NULL }; -int usb_os_desc_prepare_interf_dir(struct config_group *parent, - int n_interf, - struct usb_os_desc **desc, - char **names, - struct module *owner) +struct config_group *usb_os_desc_prepare_interf_dir( + struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + char **names, + struct module *owner) { struct config_group *os_desc_group; struct config_item_type *os_desc_type, *interface_type; @@ -1159,7 +1160,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, char *vlabuf = kzalloc(vla_group_size(data_chunk), GFP_KERNEL); if (!vlabuf) - return -ENOMEM; + return ERR_PTR(-ENOMEM); os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group); os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type); @@ -1184,7 +1185,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, configfs_add_default_group(&d->group, os_desc_group); } - return 0; + return os_desc_group; } EXPORT_SYMBOL(usb_os_desc_prepare_interf_dir); diff --git a/drivers/usb/gadget/configfs.h b/drivers/usb/gadget/configfs.h index 36c468c4f5e9..3b6f5298b2e8 100644 --- a/drivers/usb/gadget/configfs.h +++ b/drivers/usb/gadget/configfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USB__GADGET__CONFIGFS__H #define USB__GADGET__CONFIGFS__H @@ -5,11 +6,12 @@ void unregister_gadget_item(struct config_item *item); -int usb_os_desc_prepare_interf_dir(struct config_group *parent, - int n_interf, - struct usb_os_desc **desc, - char **names, - struct module *owner); +struct config_group *usb_os_desc_prepare_interf_dir( + struct config_group *parent, + int n_interf, + struct usb_os_desc **desc, + char **names, + struct module *owner); static inline struct usb_os_desc *to_usb_os_desc(struct config_item *item) { diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 86e825269947..5d3a6cf02218 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB peripheral controller drivers # diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index d21874b35cf6..8b342587f8ad 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -46,7 +46,8 @@ static void ffs_data_get(struct ffs_data *ffs); static void ffs_data_put(struct ffs_data *ffs); /* Creates new ffs_data object. */ -static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc)); +static struct ffs_data *__must_check ffs_data_new(const char *dev_name) + __attribute__((malloc)); /* Opened counter handling. */ static void ffs_data_opened(struct ffs_data *ffs); @@ -780,11 +781,12 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, struct usb_request *req) { struct ffs_io_data *io_data = req->context; + struct ffs_data *ffs = io_data->ffs; ENTER(); INIT_WORK(&io_data->work, ffs_user_copy_worker); - schedule_work(&io_data->work); + queue_work(ffs->io_completion_wq, &io_data->work); } static void __ffs_epfile_read_buffer_free(struct ffs_epfile *epfile) @@ -961,10 +963,9 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) /* In the meantime, endpoint got disabled or changed. */ ret = -ESHUTDOWN; } else if (halt) { - /* Halt */ - if (likely(epfile->ep == ep) && !WARN_ON(!ep->ep)) - usb_ep_set_halt(ep->ep); - ret = -EBADMSG; + ret = usb_ep_set_halt(ep->ep); + if (!ret) + ret = -EBADMSG; } else if (unlikely(data_len == -EINVAL)) { /* * Sanity Check: even though data_len can't be used @@ -1501,7 +1502,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, if (unlikely(ret < 0)) return ERR_PTR(ret); - ffs = ffs_data_new(); + ffs = ffs_data_new(dev_name); if (unlikely(!ffs)) return ERR_PTR(-ENOMEM); ffs->file_perms = data.perms; @@ -1611,6 +1612,7 @@ static void ffs_data_put(struct ffs_data *ffs) BUG_ON(waitqueue_active(&ffs->ev.waitq) || waitqueue_active(&ffs->ep0req_completion.wait) || waitqueue_active(&ffs->wait)); + destroy_workqueue(ffs->io_completion_wq); kfree(ffs->dev_name); kfree(ffs); } @@ -1643,7 +1645,7 @@ static void ffs_data_closed(struct ffs_data *ffs) ffs_data_put(ffs); } -static struct ffs_data *ffs_data_new(void) +static struct ffs_data *ffs_data_new(const char *dev_name) { struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); if (unlikely(!ffs)) @@ -1651,6 +1653,12 @@ static struct ffs_data *ffs_data_new(void) ENTER(); + ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name); + if (!ffs->io_completion_wq) { + kfree(ffs); + return NULL; + } + refcount_set(&ffs->ref, 1); atomic_set(&ffs->opened, 0); ffs->state = FFS_READ_DESCRIPTORS; diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 5eea44823ca0..d8e359ef6eb1 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -44,6 +44,7 @@ struct f_hidg { /* configuration */ unsigned char bInterfaceSubClass; unsigned char bInterfaceProtocol; + unsigned char protocol; unsigned short report_desc_length; char *report_desc; unsigned short report_length; @@ -527,7 +528,9 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_GET_PROTOCOL): VDBG(cdev, "get_protocol\n"); - goto stall; + length = min_t(unsigned int, length, 1); + ((u8 *) req->buf)[0] = hidg->protocol; + goto respond; break; case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 @@ -539,6 +542,17 @@ static int hidg_setup(struct usb_function *f, case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | HID_REQ_SET_PROTOCOL): VDBG(cdev, "set_protocol\n"); + if (value > HID_REPORT_PROTOCOL) + goto stall; + length = 0; + /* + * We assume that programs implementing the Boot protocol + * are also compatible with the Report Protocol + */ + if (hidg->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) { + hidg->protocol = value; + goto respond; + } goto stall; break; @@ -768,6 +782,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) /* set descriptor dynamic values */ hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; + hidg->protocol = HID_REPORT_PROTOCOL; hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_ss_in_comp_desc.wBytesPerInterval = cpu_to_le16(hidg->report_length); diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index f95bddd6513f..5153e29870c3 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -307,8 +307,6 @@ struct fsg_common { struct completion thread_notifier; struct task_struct *thread_task; - /* Callback functions. */ - const struct fsg_operations *ops; /* Gadget's private data. */ void *private_data; @@ -686,9 +684,8 @@ static int do_read(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *)bh->buf, - amount, &file_offset_tmp); + nread = kernel_read(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nread); if (signal_pending(current)) @@ -883,8 +880,8 @@ static int do_write(struct fsg_common *common) /* Perform the write */ file_offset_tmp = file_offset; - nwritten = vfs_write(curlun->filp, (char __user *)bh->buf, - amount, &file_offset_tmp); + nwritten = kernel_write(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, (unsigned long long)file_offset, (int)nwritten); if (signal_pending(current)) @@ -1021,9 +1018,8 @@ static int do_verify(struct fsg_common *common) /* Perform the read */ file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *) bh->buf, - amount, &file_offset_tmp); + nread = kernel_read(curlun->filp, bh->buf, amount, + &file_offset_tmp); VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, (unsigned long long) file_offset, (int) nread); @@ -2440,6 +2436,7 @@ static void handle_exception(struct fsg_common *common) static int fsg_main_thread(void *common_) { struct fsg_common *common = common_; + int i; /* * Allow the thread to be killed by a signal, but set the signal mask @@ -2453,13 +2450,6 @@ static int fsg_main_thread(void *common_) /* Allow the thread to be frozen */ set_freezable(); - /* - * Arrange for userspace references to be interpreted as kernel - * pointers. That way we can pass a kernel pointer to a routine - * that expects a __user pointer and it will work okay. - */ - set_fs(get_ds()); - /* The main loop */ while (common->state != FSG_STATE_TERMINATED) { if (exception_in_progress(common) || signal_pending(current)) { @@ -2485,21 +2475,16 @@ static int fsg_main_thread(void *common_) common->thread_task = NULL; spin_unlock_irq(&common->lock); - if (!common->ops || !common->ops->thread_exits - || common->ops->thread_exits(common) < 0) { - int i; + /* Eject media from all LUNs */ - down_write(&common->filesem); - for (i = 0; i < ARRAY_SIZE(common->luns); i++) { - struct fsg_lun *curlun = common->luns[i]; - if (!curlun || !fsg_lun_is_open(curlun)) - continue; + down_write(&common->filesem); + for (i = 0; i < ARRAY_SIZE(common->luns); i++) { + struct fsg_lun *curlun = common->luns[i]; + if (curlun && fsg_lun_is_open(curlun)) fsg_lun_close(curlun); - curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT; - } - up_write(&common->filesem); } + up_write(&common->filesem); /* Let fsg_unbind() know the thread has exited */ complete_and_exit(&common->thread_notifier, 0); @@ -2690,13 +2675,6 @@ void fsg_common_remove_luns(struct fsg_common *common) } EXPORT_SYMBOL_GPL(fsg_common_remove_luns); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops) -{ - common->ops = ops; -} -EXPORT_SYMBOL_GPL(fsg_common_set_ops); - void fsg_common_free_buffers(struct fsg_common *common) { _fsg_common_free_buffers(common->buffhds, common->fsg_num_buffers); diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h index d3902313b8ac..58857fcf199f 100644 --- a/drivers/usb/gadget/function/f_mass_storage.h +++ b/drivers/usb/gadget/function/f_mass_storage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USB_F_MASS_STORAGE_H #define USB_F_MASS_STORAGE_H @@ -60,17 +61,6 @@ struct fsg_module_parameters { struct fsg_common; /* FSF callback functions */ -struct fsg_operations { - /* - * Callback function to call when thread exits. If no - * callback is set or it returns value lower then zero MSF - * will force eject all LUNs it operates on (including those - * marked as non-removable or with prevent_medium_removal flag - * set). - */ - int (*thread_exits)(struct fsg_common *common); -}; - struct fsg_lun_opts { struct config_group group; struct fsg_lun *lun; @@ -142,9 +132,6 @@ void fsg_common_remove_lun(struct fsg_lun *lun); void fsg_common_remove_luns(struct fsg_common *common); -void fsg_common_set_ops(struct fsg_common *common, - const struct fsg_operations *ops); - int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, unsigned int id, const char *name, const char **name_pfx); diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a5719f271bf0..5d3d7941d2c2 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -98,6 +98,7 @@ struct f_midi { DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *); spinlock_t transmit_lock; unsigned int in_last_port; + unsigned char free_ref; struct gmidi_in_port in_ports_array[/* in_ports */]; }; @@ -108,6 +109,7 @@ static inline struct f_midi *func_to_midi(struct usb_function *f) } static void f_midi_transmit(struct f_midi *midi); +static void f_midi_rmidi_free(struct snd_rawmidi *rmidi); DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); @@ -163,6 +165,13 @@ static struct usb_endpoint_descriptor bulk_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; +static struct usb_ss_ep_comp_descriptor bulk_out_ss_comp_desc = { + .bLength = sizeof(bulk_out_ss_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + /* B.5.2 Class-specific MS Bulk OUT Endpoint Descriptor */ static struct usb_ms_endpoint_descriptor_16 ms_out_desc = { /* .bLength = DYNAMIC */ @@ -180,6 +189,13 @@ static struct usb_endpoint_descriptor bulk_in_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; +static struct usb_ss_ep_comp_descriptor bulk_in_ss_comp_desc = { + .bLength = sizeof(bulk_in_ss_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + /* .bMaxBurst = 0, */ + /* .bmAttributes = 0, */ +}; + /* B.6.2 Class-specific MS Bulk IN Endpoint Descriptor */ static struct usb_ms_endpoint_descriptor_16 ms_in_desc = { /* .bLength = DYNAMIC */ @@ -755,13 +771,13 @@ static void f_midi_out_trigger(struct snd_rawmidi_substream *substream, int up) clear_bit(substream->number, &midi->out_triggered); } -static struct snd_rawmidi_ops gmidi_in_ops = { +static const struct snd_rawmidi_ops gmidi_in_ops = { .open = f_midi_in_open, .close = f_midi_in_close, .trigger = f_midi_in_trigger, }; -static struct snd_rawmidi_ops gmidi_out_ops = { +static const struct snd_rawmidi_ops gmidi_out_ops = { .open = f_midi_out_open, .close = f_midi_out_close, .trigger = f_midi_out_trigger @@ -818,6 +834,8 @@ static int f_midi_register_card(struct f_midi *midi) SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX; rmidi->private_data = midi; + rmidi->private_free = f_midi_rmidi_free; + midi->free_ref++; /* * Yes, rawmidi OUTPUT = USB IN, and rawmidi INPUT = USB OUT. @@ -853,7 +871,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_midi *midi = func_to_midi(f); struct usb_string *us; - int status, n, jack = 1, i = 0; + int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0; midi->gadget = cdev->gadget; tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi); @@ -895,7 +913,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail; /* allocate temporary function list */ - midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function), + midi_function = kcalloc((MAX_PORTS * 4) + 11, sizeof(*midi_function), GFP_KERNEL); if (!midi_function) { status = -ENOMEM; @@ -985,6 +1003,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) ms_in_desc.bNumEmbMIDIJack = midi->out_ports; /* ... and add them to the list */ + endpoint_descriptor_index = i; midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; midi_function[i++] = (struct usb_descriptor_header *) &ms_out_desc; midi_function[i++] = (struct usb_descriptor_header *) &bulk_in_desc; @@ -1009,13 +1028,34 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail_f_midi; } + if (gadget_is_superspeed(c->cdev->gadget)) { + bulk_in_desc.wMaxPacketSize = cpu_to_le16(1024); + bulk_out_desc.wMaxPacketSize = cpu_to_le16(1024); + i = endpoint_descriptor_index; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_out_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_out_ss_comp_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &ms_out_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_in_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &bulk_in_ss_comp_desc; + midi_function[i++] = (struct usb_descriptor_header *) + &ms_in_desc; + f->ss_descriptors = usb_copy_descriptors(midi_function); + if (!f->ss_descriptors) + goto fail_f_midi; + } + kfree(midi_function); return 0; fail_f_midi: kfree(midi_function); - usb_free_descriptors(f->hs_descriptors); + usb_free_all_descriptors(f); fail: f_midi_unregister_card(midi); fail_register: @@ -1197,14 +1237,21 @@ static void f_midi_free(struct usb_function *f) midi = func_to_midi(f); opts = container_of(f->fi, struct f_midi_opts, func_inst); - kfree(midi->id); mutex_lock(&opts->lock); - kfifo_free(&midi->in_req_fifo); - kfree(midi); - --opts->refcnt; + if (!--midi->free_ref) { + kfree(midi->id); + kfifo_free(&midi->in_req_fifo); + kfree(midi); + --opts->refcnt; + } mutex_unlock(&opts->lock); } +static void f_midi_rmidi_free(struct snd_rawmidi *rmidi) +{ + f_midi_free(rmidi->private_data); +} + static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = f->config->cdev; @@ -1219,7 +1266,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) card = midi->card; midi->card = NULL; if (card) - snd_card_free(card); + snd_card_free_when_closed(card); usb_free_all_descriptors(f); } @@ -1263,6 +1310,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) midi->buflen = opts->buflen; midi->qlen = opts->qlen; midi->in_last_port = 0; + midi->free_ref = 1; status = kfifo_alloc(&midi->in_req_fifo, midi->qlen, GFP_KERNEL); if (status) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 24e34cfcb4bd..45b334ceaf2e 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -925,8 +925,6 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) */ ncm->port.is_zlp_ok = gadget_is_zlp_supported(cdev->gadget); - ncm->port.no_skb_reserve = - gadget_avoids_skb_reserve(cdev->gadget); ncm->port.cdc_filter = DEFAULT_FILTER; DBG(cdev, "activate ncm\n"); net = gether_connect(&ncm->port); diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 8df244fc9d80..ea0da35a44e2 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -555,6 +555,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) size_t size; /* Amount of data in a TX request. */ size_t bytes_copied = 0; struct usb_request *req; + int value; DBG(dev, "printer_write trying to send %d bytes\n", (int)len); @@ -634,7 +635,11 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) return -EAGAIN; } - if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { + /* here, we unlock, and only unlock, to avoid deadlock. */ + spin_unlock(&dev->lock); + value = usb_ep_queue(dev->in_ep, req, GFP_ATOMIC); + spin_lock(&dev->lock); + if (value) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); mutex_unlock(&dev->lock_printer_io); diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 16562e461121..c7c5b3ce1d98 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -691,6 +691,10 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) f->os_desc_table[0].os_desc = &rndis_opts->rndis_os_desc; } + rndis_iad_descriptor.bFunctionClass = rndis_opts->class; + rndis_iad_descriptor.bFunctionSubClass = rndis_opts->subclass; + rndis_iad_descriptor.bFunctionProtocol = rndis_opts->protocol; + /* * in drivers/usb/gadget/configfs.c:configfs_composite_bind() * configurations are bound in sequence with list_for_each_entry, @@ -866,11 +870,23 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis); /* f_rndis_opts_ifname */ USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); +/* f_rndis_opts_class */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, class); + +/* f_rndis_opts_subclass */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, subclass); + +/* f_rndis_opts_protocol */ +USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(rndis, protocol); + static struct configfs_attribute *rndis_attrs[] = { &rndis_opts_attr_dev_addr, &rndis_opts_attr_host_addr, &rndis_opts_attr_qmult, &rndis_opts_attr_ifname, + &rndis_opts_attr_class, + &rndis_opts_attr_subclass, + &rndis_opts_attr_protocol, NULL, }; @@ -892,6 +908,7 @@ static void rndis_free_inst(struct usb_function_instance *f) free_netdev(opts->net); } + kfree(opts->rndis_interf_group); /* single VLA chunk */ kfree(opts); } @@ -900,6 +917,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) struct f_rndis_opts *opts; struct usb_os_desc *descs[1]; char *names[1]; + struct config_group *rndis_interf_group; opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) @@ -916,12 +934,22 @@ static struct usb_function_instance *rndis_alloc_inst(void) } INIT_LIST_HEAD(&opts->rndis_os_desc.ext_prop); + opts->class = rndis_iad_descriptor.bFunctionClass; + opts->subclass = rndis_iad_descriptor.bFunctionSubClass; + opts->protocol = rndis_iad_descriptor.bFunctionProtocol; + descs[0] = &opts->rndis_os_desc; names[0] = "rndis"; config_group_init_type_name(&opts->func_inst.group, "", &rndis_func_type); - usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, - names, THIS_MODULE); + rndis_interf_group = + usb_os_desc_prepare_interf_dir(&opts->func_inst.group, 1, descs, + names, THIS_MODULE); + if (IS_ERR(rndis_interf_group)) { + rndis_free_inst(&opts->func_inst); + return ERR_CAST(rndis_interf_group); + } + opts->rndis_interf_group = rndis_interf_group; return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h index 492924d0d599..98b8462ad538 100644 --- a/drivers/usb/gadget/function/g_zero.h +++ b/drivers/usb/gadget/function/g_zero.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This header declares the utility functions used by "Gadget Zero", plus * interfaces to its two single-configuration function drivers. diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h index e0814a960132..e5e3a2553aaa 100644 --- a/drivers/usb/gadget/function/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USB_STORAGE_COMMON_H #define USB_STORAGE_COMMON_H diff --git a/drivers/usb/gadget/function/tcm.h b/drivers/usb/gadget/function/tcm.h index a27e6e34db0b..3cd565794ad7 100644 --- a/drivers/usb/gadget/function/tcm.h +++ b/drivers/usb/gadget/function/tcm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TARGET_USB_GADGET_H__ #define __TARGET_USB_GADGET_H__ diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 5dd73b9e5172..3971bbab88bd 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -79,7 +79,7 @@ struct snd_uac_chip { unsigned int p_framesize; }; -static struct snd_pcm_hardware uac_pcm_hardware = { +static const struct snd_pcm_hardware uac_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, @@ -354,7 +354,7 @@ static int uac_pcm_null(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops uac_pcm_ops = { +static const struct snd_pcm_ops uac_pcm_ops = { .open = uac_pcm_open, .close = uac_pcm_null, .ioctl = snd_pcm_lib_ioctl, diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index a8b40d07e927..bdbc3fdc7c4f 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -1073,7 +1073,7 @@ struct net_device *gether_connect(struct gether *link) if (result == 0) { dev->zlp = link->is_zlp_ok; - dev->no_skb_reserve = link->no_skb_reserve; + dev->no_skb_reserve = gadget_avoids_skb_reserve(dev->gadget); DBG(dev, "qlen %d\n", qlen(dev->gadget, dev->qmult)); dev->header_len = link->header_len; diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h index 81d94a7ae4b4..c77145bd6b5b 100644 --- a/drivers/usb/gadget/function/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h @@ -64,7 +64,6 @@ struct gether { struct usb_ep *out_ep; bool is_zlp_ok; - bool no_skb_reserve; u16 cdc_filter; diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index c71133de17e7..e4c3f84af4c3 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -153,4 +153,39 @@ out: \ \ CONFIGFS_ATTR_RO(_f_##_opts_, ifname) +#define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \ + static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\ + char *page) \ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ + int ret; \ + \ + mutex_lock(&opts->lock); \ + ret = sprintf(page, "%02x\n", opts->_n_); \ + mutex_unlock(&opts->lock); \ + \ + return ret; \ + } \ + \ + static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\ + const char *page, \ + size_t len) \ + { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ + int ret; \ + u8 val; \ + \ + mutex_lock(&opts->lock); \ + ret = sscanf(page, "%02hhx", &val); \ + if (ret > 0) { \ + opts->_n_ = val; \ + ret = len; \ + } \ + mutex_unlock(&opts->lock); \ + \ + return ret; \ + } \ + \ + CONFIGFS_ATTR(_f_##_opts_, _n_) + #endif /* __U_ETHER_CONFIGFS_H */ diff --git a/drivers/usb/gadget/function/u_fs.h b/drivers/usb/gadget/function/u_fs.h index 540f1c48c1a8..79f70ebf85dc 100644 --- a/drivers/usb/gadget/function/u_fs.h +++ b/drivers/usb/gadget/function/u_fs.h @@ -279,6 +279,7 @@ struct ffs_data { } file_perms; struct eventfd_ctx *ffs_eventfd; + struct workqueue_struct *io_completion_wq; bool no_disconnect; struct work_struct reset_work; diff --git a/drivers/usb/gadget/function/u_rndis.h b/drivers/usb/gadget/function/u_rndis.h index 4eafd5050545..efdb7ac381d9 100644 --- a/drivers/usb/gadget/function/u_rndis.h +++ b/drivers/usb/gadget/function/u_rndis.h @@ -26,9 +26,14 @@ struct f_rndis_opts { bool bound; bool borrowed_net; + struct config_group *rndis_interf_group; struct usb_os_desc rndis_os_desc; char rndis_ext_compat_id[16]; + u8 class; + u8 subclass; + u8 protocol; + /* * Read/write access to configfs attributes is handled by configfs. * diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 9b0805f55ad7..4176216d54be 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -537,7 +537,7 @@ static void gs_rx_push(unsigned long _port) } /* push data to (open) tty */ - if (req->actual) { + if (req->actual && tty) { char *packet = req->buf; unsigned size = req->actual; unsigned n; diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index ac461a9a1a70..51ee94e5cf2b 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _UVC_QUEUE_H_ #define _UVC_QUEUE_H_ diff --git a/drivers/usb/gadget/legacy/Makefile b/drivers/usb/gadget/legacy/Makefile index 7f485f25705e..abd0c3e66a05 100644 --- a/drivers/usb/gadget/legacy/Makefile +++ b/drivers/usb/gadget/legacy/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB gadget drivers # diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 684900fcfe24..5c28bee327e1 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -28,7 +28,7 @@ #include #include #include - +#include #include #include @@ -116,6 +116,7 @@ enum ep0_state { struct dev_data { spinlock_t lock; refcount_t count; + int udc_usage; enum ep0_state state; /* P: lock */ struct usb_gadgetfs_event event [N_EVENT]; unsigned ev_next; @@ -513,9 +514,9 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) INIT_WORK(&priv->work, ep_user_copy_worker); schedule_work(&priv->work); } - spin_unlock(&epdata->dev->lock); usb_ep_free_request(ep, req); + spin_unlock(&epdata->dev->lock); put_ep(epdata); } @@ -939,9 +940,11 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) struct usb_request *req = dev->req; if ((retval = setup_req (ep, req, 0)) == 0) { + ++dev->udc_usage; spin_unlock_irq (&dev->lock); retval = usb_ep_queue (ep, req, GFP_KERNEL); spin_lock_irq (&dev->lock); + --dev->udc_usage; } dev->state = STATE_DEV_CONNECTED; @@ -983,11 +986,14 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) retval = -EIO; else { len = min (len, (size_t)dev->req->actual); -// FIXME don't call this with the spinlock held ... + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); if (copy_to_user (buf, dev->req->buf, len)) retval = -EFAULT; else retval = len; + spin_lock_irq(&dev->lock); + --dev->udc_usage; clean_req (dev->gadget->ep0, dev->req); /* NOTE userspace can't yet choose to stall */ } @@ -1131,6 +1137,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) retval = setup_req (dev->gadget->ep0, dev->req, len); if (retval == 0) { dev->state = STATE_DEV_CONNECTED; + ++dev->udc_usage; spin_unlock_irq (&dev->lock); if (copy_from_user (dev->req->buf, buf, len)) retval = -EFAULT; @@ -1142,6 +1149,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) GFP_KERNEL); } spin_lock_irq(&dev->lock); + --dev->udc_usage; if (retval < 0) { clean_req (dev->gadget->ep0, dev->req); } else @@ -1243,9 +1251,21 @@ static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) struct usb_gadget *gadget = dev->gadget; long ret = -ENOTTY; - if (gadget->ops->ioctl) + spin_lock_irq(&dev->lock); + if (dev->state == STATE_DEV_OPENED || + dev->state == STATE_DEV_UNBOUND) { + /* Not bound to a UDC */ + } else if (gadget->ops->ioctl) { + ++dev->udc_usage; + spin_unlock_irq(&dev->lock); + ret = gadget->ops->ioctl (gadget, code, value); + spin_lock_irq(&dev->lock); + --dev->udc_usage; + } + spin_unlock_irq(&dev->lock); + return ret; } @@ -1463,10 +1483,12 @@ delegate: if (value < 0) break; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, dev->req, GFP_KERNEL); spin_lock (&dev->lock); + --dev->udc_usage; if (value < 0) { clean_req (gadget->ep0, dev->req); break; @@ -1490,8 +1512,12 @@ delegate: req->length = value; req->zero = value < w_length; + ++dev->udc_usage; spin_unlock (&dev->lock); value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL); + spin_lock(&dev->lock); + --dev->udc_usage; + spin_unlock(&dev->lock); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); req->status = 0; @@ -1518,21 +1544,24 @@ static void destroy_ep_files (struct dev_data *dev) /* break link to FS */ ep = list_first_entry (&dev->epfiles, struct ep_data, epfiles); list_del_init (&ep->epfiles); + spin_unlock_irq (&dev->lock); + dentry = ep->dentry; ep->dentry = NULL; parent = d_inode(dentry->d_parent); /* break link to controller */ + mutex_lock(&ep->lock); if (ep->state == STATE_EP_ENABLED) (void) usb_ep_disable (ep->ep); ep->state = STATE_EP_UNBOUND; usb_ep_free_request (ep->ep, ep->req); ep->ep = NULL; + mutex_unlock(&ep->lock); + wake_up (&ep->wait); put_ep (ep); - spin_unlock_irq (&dev->lock); - /* break link to dcache */ inode_lock(parent); d_delete (dentry); @@ -1603,6 +1632,11 @@ gadgetfs_unbind (struct usb_gadget *gadget) spin_lock_irq (&dev->lock); dev->state = STATE_DEV_UNBOUND; + while (dev->udc_usage > 0) { + spin_unlock_irq(&dev->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dev->lock); + } spin_unlock_irq (&dev->lock); destroy_ep_files (dev); diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c index e99ab57ee3e5..fcba59782f26 100644 --- a/drivers/usb/gadget/legacy/mass_storage.c +++ b/drivers/usb/gadget/legacy/mass_storage.c @@ -107,15 +107,6 @@ static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS; FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); -static unsigned long msg_registered; -static void msg_cleanup(void); - -static int msg_thread_exits(struct fsg_common *common) -{ - msg_cleanup(); - return 0; -} - static int msg_do_config(struct usb_configuration *c) { struct fsg_opts *opts; @@ -154,9 +145,6 @@ static struct usb_configuration msg_config_driver = { static int msg_bind(struct usb_composite_dev *cdev) { - static const struct fsg_operations ops = { - .thread_exits = msg_thread_exits, - }; struct fsg_opts *opts; struct fsg_config config; int status; @@ -173,8 +161,6 @@ static int msg_bind(struct usb_composite_dev *cdev) if (status) goto fail; - fsg_common_set_ops(opts->common, &ops); - status = fsg_common_set_cdev(opts->common, cdev, config.can_stall); if (status) goto fail_set_cdev; @@ -256,18 +242,12 @@ MODULE_LICENSE("GPL"); static int __init msg_init(void) { - int ret; - - ret = usb_composite_probe(&msg_driver); - set_bit(0, &msg_registered); - - return ret; + return usb_composite_probe(&msg_driver); } module_init(msg_init); -static void msg_cleanup(void) +static void __exit msg_cleanup(void) { - if (test_and_clear_bit(0, &msg_registered)) - usb_composite_unregister(&msg_driver); + usb_composite_unregister(&msg_driver); } module_exit(msg_cleanup); diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index f9661cd627c8..82c13fce9232 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -436,5 +436,4 @@ module_usb_composite_driver(webcam_driver); MODULE_AUTHOR("Laurent Pinchart"); MODULE_DESCRIPTION("Webcam Video Gadget"); MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1.0"); diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 7cd5c969fcbe..1e9567091d86 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -273,6 +273,7 @@ config USB_SNP_CORE config USB_SNP_UDC_PLAT tristate "Synopsys USB 2.0 Device controller" depends on USB_GADGET && OF && HAS_DMA + depends on EXTCON || EXTCON=n select USB_GADGET_DUALSPEED select USB_SNP_CORE default ARCH_BCM_IPROC diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile index ea9e1c7f1923..ce865b129fd6 100644 --- a/drivers/usb/gadget/udc/Makefile +++ b/drivers/usb/gadget/udc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # define_trace.h needs to know how to find our header CFLAGS_trace.o := -I$(src) diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 98d71400f8a1..a884c022df7a 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -29,6 +29,8 @@ #include #include "atmel_usba_udc.h" +#define USBA_VBUS_IRQFLAGS (IRQF_ONESHOT \ + | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING) #ifdef CONFIG_USB_GADGET_DEBUG_FS #include @@ -2361,7 +2363,7 @@ static int usba_udc_probe(struct platform_device *pdev) IRQ_NOAUTOEN); ret = devm_request_threaded_irq(&pdev->dev, gpio_to_irq(udc->vbus_pin), NULL, - usba_vbus_irq_thread, IRQF_ONESHOT, + usba_vbus_irq_thread, USBA_VBUS_IRQFLAGS, "atmel_usba_udc", udc); if (ret) { udc->vbus_pin = -ENODEV; diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig index eb8b55392360..c74ac25dddcd 100644 --- a/drivers/usb/gadget/udc/bdc/Kconfig +++ b/drivers/usb/gadget/udc/bdc/Kconfig @@ -1,6 +1,7 @@ config USB_BDC_UDC tristate "Broadcom USB3.0 device controller IP driver(BDC)" depends on USB_GADGET && HAS_DMA + default ARCH_BRCMSTB help BDC is Broadcom's USB3.0 device controller IP. If your SOC has a BDC IP diff --git a/drivers/usb/gadget/udc/bdc/Makefile b/drivers/usb/gadget/udc/bdc/Makefile index 5cf6a3bcdf0f..52cb5ea48bbe 100644 --- a/drivers/usb/gadget/udc/bdc/Makefile +++ b/drivers/usb/gadget/udc/bdc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_USB_BDC_UDC) += bdc.o bdc-y := bdc_core.o bdc_cmd.o bdc_ep.o bdc_udc.o diff --git a/drivers/usb/gadget/udc/bdc/bdc.h b/drivers/usb/gadget/udc/bdc/bdc.h index 916d47135cac..6df0352cdc50 100644 --- a/drivers/usb/gadget/udc/bdc/bdc.h +++ b/drivers/usb/gadget/udc/bdc/bdc.h @@ -27,8 +27,8 @@ #include #include -#define BRCM_BDC_NAME "bdc_usb3" -#define BRCM_BDC_DESC "BDC device controller driver" +#define BRCM_BDC_NAME "bdc" +#define BRCM_BDC_DESC "Broadcom USB Device Controller driver" #define DMA_ADDR_INVALID (~(dma_addr_t)0) @@ -83,14 +83,14 @@ #define BDC_DVCSA 0x50 #define BDC_DVCSB 0x54 -#define BDC_EPSTS0(n) (0x60 + (n * 0x10)) -#define BDC_EPSTS1(n) (0x64 + (n * 0x10)) -#define BDC_EPSTS2(n) (0x68 + (n * 0x10)) -#define BDC_EPSTS3(n) (0x6c + (n * 0x10)) -#define BDC_EPSTS4(n) (0x70 + (n * 0x10)) -#define BDC_EPSTS5(n) (0x74 + (n * 0x10)) -#define BDC_EPSTS6(n) (0x78 + (n * 0x10)) -#define BDC_EPSTS7(n) (0x7c + (n * 0x10)) +#define BDC_EPSTS0 0x60 +#define BDC_EPSTS1 0x64 +#define BDC_EPSTS2 0x68 +#define BDC_EPSTS3 0x6c +#define BDC_EPSTS4 0x70 +#define BDC_EPSTS5 0x74 +#define BDC_EPSTS6 0x78 +#define BDC_EPSTS7 0x7c #define BDC_SRRBAL(n) (0x200 + (n * 0x10)) #define BDC_SRRBAH(n) (0x204 + (n * 0x10)) #define BDC_SRRINT(n) (0x208 + (n * 0x10)) @@ -413,6 +413,9 @@ struct bdc { /* device lock */ spinlock_t lock; + /* generic phy */ + struct phy **phys; + int num_phys; /* num of endpoints for a particular instantiation of IP */ unsigned int num_eps; /* @@ -454,6 +457,7 @@ struct bdc { * Func Wake packet every 2.5 secs. Refer to USB3 spec section 8.5.6.4 */ struct delayed_work func_wake_notify; + struct clk *clk; }; static inline u32 bdc_readl(void __iomem *base, u32 offset) diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index e9bd8d4abca0..7a8af4b916cf 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -24,9 +24,11 @@ #include #include #include +#include #include #include #include +#include #include "bdc.h" #include "bdc_dbg.h" @@ -444,6 +446,43 @@ static int bdc_hw_init(struct bdc *bdc) return 0; } +static int bdc_phy_init(struct bdc *bdc) +{ + int phy_num; + int ret; + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + ret = phy_init(bdc->phys[phy_num]); + if (ret) + goto err_exit_phy; + ret = phy_power_on(bdc->phys[phy_num]); + if (ret) { + phy_exit(bdc->phys[phy_num]); + goto err_exit_phy; + } + } + + return 0; + +err_exit_phy: + while (--phy_num >= 0) { + phy_power_off(bdc->phys[phy_num]); + phy_exit(bdc->phys[phy_num]); + } + + return ret; +} + +static void bdc_phy_exit(struct bdc *bdc) +{ + int phy_num; + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + phy_power_off(bdc->phys[phy_num]); + phy_exit(bdc->phys[phy_num]); + } +} + static int bdc_probe(struct platform_device *pdev) { struct bdc *bdc; @@ -452,12 +491,29 @@ static int bdc_probe(struct platform_device *pdev) int irq; u32 temp; struct device *dev = &pdev->dev; + struct clk *clk; + int phy_num; dev_dbg(dev, "%s()\n", __func__); + + clk = devm_clk_get(dev, "sw_usbd"); + if (IS_ERR(clk)) { + dev_info(dev, "Clock not found in Device Tree\n"); + clk = NULL; + } + + ret = clk_prepare_enable(clk); + if (ret) { + dev_err(dev, "could not enable clock\n"); + return ret; + } + bdc = devm_kzalloc(dev, sizeof(*bdc), GFP_KERNEL); if (!bdc) return -ENOMEM; + bdc->clk = clk; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bdc->regs = devm_ioremap_resource(dev, res); if (IS_ERR(bdc->regs)) { @@ -473,35 +529,66 @@ static int bdc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, bdc); bdc->irq = irq; bdc->dev = dev; - dev_dbg(bdc->dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); + dev_dbg(dev, "bdc->regs: %p irq=%d\n", bdc->regs, bdc->irq); + + bdc->num_phys = of_count_phandle_with_args(dev->of_node, + "phys", "#phy-cells"); + if (bdc->num_phys > 0) { + bdc->phys = devm_kcalloc(dev, bdc->num_phys, + sizeof(struct phy *), GFP_KERNEL); + if (!bdc->phys) + return -ENOMEM; + } else { + bdc->num_phys = 0; + } + dev_info(dev, "Using %d phy(s)\n", bdc->num_phys); + + for (phy_num = 0; phy_num < bdc->num_phys; phy_num++) { + bdc->phys[phy_num] = devm_of_phy_get_by_index( + dev, dev->of_node, phy_num); + if (IS_ERR(bdc->phys[phy_num])) { + ret = PTR_ERR(bdc->phys[phy_num]); + dev_err(bdc->dev, + "BDC phy specified but not found:%d\n", ret); + return ret; + } + } + + ret = bdc_phy_init(bdc); + if (ret) { + dev_err(bdc->dev, "BDC phy init failure:%d\n", ret); + return ret; + } temp = bdc_readl(bdc->regs, BDC_BDCCAP1); if ((temp & BDC_P64) && !dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { - dev_dbg(bdc->dev, "Using 64-bit address\n"); + dev_dbg(dev, "Using 64-bit address\n"); } else { - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(bdc->dev, "No suitable DMA config available, abort\n"); + dev_err(dev, + "No suitable DMA config available, abort\n"); return -ENOTSUPP; } - dev_dbg(bdc->dev, "Using 32-bit address\n"); + dev_dbg(dev, "Using 32-bit address\n"); } ret = bdc_hw_init(bdc); if (ret) { - dev_err(bdc->dev, "BDC init failure:%d\n", ret); - return ret; + dev_err(dev, "BDC init failure:%d\n", ret); + goto phycleanup; } ret = bdc_udc_init(bdc); if (ret) { - dev_err(bdc->dev, "BDC Gadget init failure:%d\n", ret); + dev_err(dev, "BDC Gadget init failure:%d\n", ret); goto cleanup; } return 0; cleanup: bdc_hw_exit(bdc); - +phycleanup: + bdc_phy_exit(bdc); return ret; } @@ -513,13 +600,56 @@ static int bdc_remove(struct platform_device *pdev) dev_dbg(bdc->dev, "%s ()\n", __func__); bdc_udc_exit(bdc); bdc_hw_exit(bdc); + bdc_phy_exit(bdc); + clk_disable_unprepare(bdc->clk); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int bdc_suspend(struct device *dev) +{ + struct bdc *bdc = dev_get_drvdata(dev); + + clk_disable_unprepare(bdc->clk); + return 0; +} + +static int bdc_resume(struct device *dev) +{ + struct bdc *bdc = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(bdc->clk); + if (ret) { + dev_err(bdc->dev, "err enabling the clock\n"); + return ret; + } + ret = bdc_reinit(bdc); + if (ret) { + dev_err(bdc->dev, "err in bdc reinit\n"); + return ret; + } return 0; } +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(bdc_pm_ops, bdc_suspend, + bdc_resume); + +static const struct of_device_id bdc_of_match[] = { + { .compatible = "brcm,bdc-v0.16" }, + { .compatible = "brcm,bdc" }, + { /* sentinel */ } +}; + static struct platform_driver bdc_driver = { .driver = { .name = BRCM_BDC_NAME, + .owner = THIS_MODULE, + .pm = &bdc_pm_ops, + .of_match_table = bdc_of_match, }, .probe = bdc_probe, .remove = bdc_remove, diff --git a/drivers/usb/gadget/udc/bdc/bdc_dbg.c b/drivers/usb/gadget/udc/bdc/bdc_dbg.c index 5945dbc47825..ac98f6f681b7 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_dbg.c +++ b/drivers/usb/gadget/udc/bdc/bdc_dbg.c @@ -40,28 +40,28 @@ void bdc_dump_epsts(struct bdc *bdc) { u32 temp; - temp = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS0); dev_vdbg(bdc->dev, "BDC_EPSTS0:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS1(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS1); dev_vdbg(bdc->dev, "BDC_EPSTS1:0x%x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS2(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS2); dev_vdbg(bdc->dev, "BDC_EPSTS2:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS3(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS3); dev_vdbg(bdc->dev, "BDC_EPSTS3:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS4(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS4); dev_vdbg(bdc->dev, "BDC_EPSTS4:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS5(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS5); dev_vdbg(bdc->dev, "BDC_EPSTS5:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS6(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS6); dev_vdbg(bdc->dev, "BDC_EPSTS6:0x%08x\n", temp); - temp = bdc_readl(bdc->regs, BDC_EPSTS7(0)); + temp = bdc_readl(bdc->regs, BDC_EPSTS7); dev_vdbg(bdc->dev, "BDC_EPSTS7:0x%08x\n", temp); } diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index ff1ef24d1777..bfd8f7ade935 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -777,9 +777,9 @@ static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req) */ /* The current hw dequeue pointer */ - tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(0)); + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0); deq_ptr_64 = tmp_32; - tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1(0)); + tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS1); deq_ptr_64 |= ((u64)tmp_32 << 32); /* we have the dma addr of next bd that will be fetched by hardware */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c index aae7458d8986..c84346146456 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_udc.c +++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c @@ -249,6 +249,7 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) disconn = true; else if ((uspc & BDC_PCS) && !BDC_PST(uspc)) connected = true; + clear_flags |= BDC_PCC; } /* Change in VBus and VBus is present */ @@ -259,16 +260,16 @@ void bdc_sr_uspc(struct bdc *bdc, struct bdc_sr *sreport) bdc_softconn(bdc); usb_gadget_set_state(&bdc->gadget, USB_STATE_POWERED); } - clear_flags = BDC_VBC; + clear_flags |= BDC_VBC; } else if ((uspc & BDC_PRS) || (uspc & BDC_PRC) || disconn) { /* Hot reset, warm reset, 2.0 bus reset or disconn */ dev_dbg(bdc->dev, "Port reset or disconn\n"); bdc_uspc_disconnected(bdc, disconn); - clear_flags = BDC_PCC|BDC_PCS|BDC_PRS|BDC_PRC; + clear_flags |= BDC_PRC; } else if ((uspc & BDC_PSC) && (uspc & BDC_PCS)) { /* Change in Link state */ handle_link_state_change(bdc, uspc); - clear_flags = BDC_PSC|BDC_PCS; + clear_flags |= BDC_PSC; } /* diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index e6f04eee95c4..d41d07aae0ce 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -812,6 +812,8 @@ int usb_gadget_map_request_by_dev(struct device *dev, dev_err(dev, "failed to map buffer\n"); return -EFAULT; } + + req->dma_mapped = 1; } return 0; @@ -836,9 +838,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev, is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); req->num_mapped_sgs = 0; - } else { + } else if (req->dma_mapped) { dma_unmap_single(dev, req->dma, req->length, is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + req->dma_mapped = 0; } } EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev); @@ -1130,6 +1133,7 @@ static int check_pending_gadget_drivers(struct usb_udc *udc) * @release: a gadget release function. * * Returns zero on success, negative errno otherwise. + * Calls the gadget release function in the latter case. */ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)) @@ -1137,10 +1141,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, struct usb_udc *udc; int ret = -ENOMEM; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); - if (!udc) - goto err1; - dev_set_name(&gadget->dev, "gadget"); INIT_WORK(&gadget->work, usb_gadget_state_work); gadget->dev.parent = parent; @@ -1150,7 +1150,13 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, else gadget->dev.release = usb_udc_nop_release; - ret = device_register(&gadget->dev); + device_initialize(&gadget->dev); + + udc = kzalloc(sizeof(*udc), GFP_KERNEL); + if (!udc) + goto err1; + + ret = device_add(&gadget->dev); if (ret) goto err2; @@ -1197,10 +1203,10 @@ err3: device_del(&gadget->dev); err2: - put_device(&gadget->dev); kfree(udc); err1: + put_device(&gadget->dev); return ret; } EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release); @@ -1314,8 +1320,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri udc->dev.driver = &driver->driver; udc->gadget->dev.driver = &driver->driver; - if (driver->max_speed < udc->gadget->max_speed) - usb_gadget_udc_set_speed(udc, driver->max_speed); + usb_gadget_udc_set_speed(udc, driver->max_speed); ret = driver->bind(udc->gadget, driver); if (ret) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 3c3760315910..f04e91ef9e7c 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -237,6 +237,8 @@ struct dummy_hcd { struct usb_device *udev; struct list_head urbp_list; + struct urbp *next_frame_urbp; + u32 stream_en_ep; u8 num_stream[30 / 2]; @@ -253,11 +255,13 @@ struct dummy { */ struct dummy_ep ep[DUMMY_ENDPOINTS]; int address; + int callback_usage; struct usb_gadget gadget; struct usb_gadget_driver *driver; struct dummy_request fifo_req; u8 fifo_buf[FIFO_SIZE]; u16 devstatus; + unsigned ints_enabled:1; unsigned udc_suspended:1; unsigned pullup:1; @@ -375,11 +379,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) USB_PORT_STAT_CONNECTION) == 0) dum_hcd->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); - if ((dum_hcd->port_status & - USB_PORT_STAT_ENABLE) == 1 && - (dum_hcd->port_status & - USB_SS_PORT_LS_U0) == 1 && - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) && + (dum_hcd->port_status & + USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) dum_hcd->active = 1; } } else { @@ -416,6 +419,7 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) static void set_link_state(struct dummy_hcd *dum_hcd) { struct dummy *dum = dum_hcd->dum; + unsigned int power_bit; dum_hcd->active = 0; if (dum->pullup) @@ -426,32 +430,43 @@ static void set_link_state(struct dummy_hcd *dum_hcd) return; set_link_state_by_speed(dum_hcd); + power_bit = (dummy_hcd_to_hcd(dum_hcd)->speed == HCD_USB3 ? + USB_SS_PORT_STAT_POWER : USB_PORT_STAT_POWER); if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) == 0 || dum_hcd->active) dum_hcd->resuming = 0; /* Currently !connected or in reset */ - if ((dum_hcd->port_status & USB_PORT_STAT_CONNECTION) == 0 || + if ((dum_hcd->port_status & power_bit) == 0 || (dum_hcd->port_status & USB_PORT_STAT_RESET) != 0) { - unsigned disconnect = USB_PORT_STAT_CONNECTION & + unsigned int disconnect = power_bit & dum_hcd->old_status & (~dum_hcd->port_status); - unsigned reset = USB_PORT_STAT_RESET & + unsigned int reset = USB_PORT_STAT_RESET & (~dum_hcd->old_status) & dum_hcd->port_status; /* Report reset and disconnect events to the driver */ - if (dum->driver && (disconnect || reset)) { + if (dum->ints_enabled && (disconnect || reset)) { stop_activity(dum); + ++dum->callback_usage; + spin_unlock(&dum->lock); if (reset) usb_gadget_udc_reset(&dum->gadget, dum->driver); else dum->driver->disconnect(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } - } else if (dum_hcd->active != dum_hcd->old_active) { + } else if (dum_hcd->active != dum_hcd->old_active && + dum->ints_enabled) { + ++dum->callback_usage; + spin_unlock(&dum->lock); if (dum_hcd->old_active && dum->driver->suspend) dum->driver->suspend(&dum->gadget); else if (!dum_hcd->old_active && dum->driver->resume) dum->driver->resume(&dum->gadget); + spin_lock(&dum->lock); + --dum->callback_usage; } dum_hcd->old_status = dum_hcd->port_status; @@ -972,8 +987,11 @@ static int dummy_udc_start(struct usb_gadget *g, * can't enumerate without help from the driver we're binding. */ + spin_lock_irq(&dum->lock); dum->devstatus = 0; dum->driver = driver; + dum->ints_enabled = 1; + spin_unlock_irq(&dum->lock); return 0; } @@ -984,6 +1002,16 @@ static int dummy_udc_stop(struct usb_gadget *g) struct dummy *dum = dum_hcd->dum; spin_lock_irq(&dum->lock); + dum->ints_enabled = 0; + stop_activity(dum); + + /* emulate synchronize_irq(): wait for callbacks to finish */ + while (dum->callback_usage > 0) { + spin_unlock_irq(&dum->lock); + usleep_range(1000, 2000); + spin_lock_irq(&dum->lock); + } + dum->driver = NULL; spin_unlock_irq(&dum->lock); @@ -1037,7 +1065,12 @@ static int dummy_udc_probe(struct platform_device *pdev) memzero_explicit(&dum->gadget, sizeof(struct usb_gadget)); dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; - dum->gadget.max_speed = USB_SPEED_SUPER; + if (mod_data.is_super_speed) + dum->gadget.max_speed = USB_SPEED_SUPER; + else if (mod_data.is_high_speed) + dum->gadget.max_speed = USB_SPEED_HIGH; + else + dum->gadget.max_speed = USB_SPEED_FULL; dum->gadget.dev.parent = &pdev->dev; init_dummy_udc_hw(dum); @@ -1246,6 +1279,8 @@ static int dummy_urb_enqueue( list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); urb->hcpriv = urbp; + if (!dum_hcd->next_frame_urbp) + dum_hcd->next_frame_urbp = urbp; if (usb_pipetype(urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ @@ -1521,6 +1556,8 @@ static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address) if (!is_active((dum->gadget.speed == USB_SPEED_SUPER ? dum->ss_hcd : dum->hs_hcd))) return NULL; + if (!dum->ints_enabled) + return NULL; if ((address & ~USB_DIR_IN) == 0) return &dum->ep[0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { @@ -1762,6 +1799,7 @@ static void dummy_timer(unsigned long _dum_hcd) spin_unlock_irqrestore(&dum->lock, flags); return; } + dum_hcd->next_frame_urbp = NULL; for (i = 0; i < DUMMY_ENDPOINTS; i++) { if (!ep_info[i].name) @@ -1778,6 +1816,10 @@ restart: int type; int status = -EINPROGRESS; + /* stop when we reach URBs queued after the timer interrupt */ + if (urbp == dum_hcd->next_frame_urbp) + break; + urb = urbp->urb; if (urb->unlinked) goto return_urb; @@ -1857,10 +1899,12 @@ restart: * until setup() returns; no reentrancy issues etc. */ if (value > 0) { + ++dum->callback_usage; spin_unlock(&dum->lock); value = dum->driver->setup(&dum->gadget, &setup); spin_lock(&dum->lock); + --dum->callback_usage; if (value >= 0) { /* no delays (max 64KB data stage) */ @@ -2561,8 +2605,6 @@ static struct hc_driver dummy_hcd = { .product_desc = "Dummy host controller", .hcd_priv_size = sizeof(struct dummy_hcd), - .flags = HCD_USB3 | HCD_SHARED, - .reset = dummy_setup, .start = dummy_start, .stop = dummy_stop, @@ -2591,8 +2633,12 @@ static int dummy_hcd_probe(struct platform_device *pdev) dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); dum = *((void **)dev_get_platdata(&pdev->dev)); - if (!mod_data.is_super_speed) + if (mod_data.is_super_speed) + dummy_hcd.flags = HCD_USB3 | HCD_SHARED; + else if (mod_data.is_high_speed) dummy_hcd.flags = HCD_USB2; + else + dummy_hcd.flags = HCD_USB11; hs_hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, dev_name(&pdev->dev)); if (!hs_hcd) return -ENOMEM; @@ -2776,7 +2822,7 @@ static int __init init(void) if (retval < 0) { i--; while (i >= 0) - platform_device_del(the_udc_pdev[i]); + platform_device_del(the_udc_pdev[i--]); goto err_add_udc; } } diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index 303328ce59ee..a3e72d690eef 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -62,7 +62,7 @@ static const char *const ep_name[] = { "ep3", }; -static struct usb_endpoint_descriptor qe_ep0_desc = { +static const struct usb_endpoint_descriptor qe_ep0_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, diff --git a/drivers/usb/gadget/udc/mv_udc_core.c b/drivers/usb/gadget/udc/mv_udc_core.c index 8a708d0a1042..4103bf7cf52a 100644 --- a/drivers/usb/gadget/udc/mv_udc_core.c +++ b/drivers/usb/gadget/udc/mv_udc_core.c @@ -39,7 +39,6 @@ #include "mv_udc.h" #define DRIVER_DESC "Marvell PXA USB Device Controller driver" -#define DRIVER_VERSION "8 Nov 2010" #define ep_dir(ep) (((ep)->ep_num == 0) ? \ ((ep)->udc->ep0_dir) : ((ep)->direction)) @@ -2427,5 +2426,4 @@ module_platform_driver(udc_driver); MODULE_ALIAS("platform:mv-udc"); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Chao Xie "); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/udc/omap_udc.h b/drivers/usb/gadget/udc/omap_udc.h index 26974196cf44..00f9e608e755 100644 --- a/drivers/usb/gadget/udc/omap_udc.h +++ b/drivers/usb/gadget/udc/omap_udc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * omap_udc.h -- for omap 3.2 udc, with OTG support * diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index e1de8fe599a3..63a206122058 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -8,6 +8,7 @@ * the Free Software Foundation; version 2 of the License. */ +#include #include #include #include @@ -20,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -347,6 +350,7 @@ struct renesas_usb3 { bool workaround_for_vbus; bool extcon_host; /* check id and set EXTCON_USB_HOST */ bool extcon_usb; /* check vbus and set EXTCON_USB */ + bool forced_b_device; }; #define gadget_to_renesas_usb3(_gadget) \ @@ -663,7 +667,9 @@ static void usb3_mode_config(struct renesas_usb3 *usb3, bool host, bool a_dev) spin_lock_irqsave(&usb3->lock, flags); usb3_set_mode(usb3, host); usb3_vbus_out(usb3, a_dev); - if (!host && a_dev) /* for A-Peripheral */ + /* for A-Peripheral or forced B-device mode */ + if ((!host && a_dev) || + (usb3->workaround_for_vbus && usb3->forced_b_device)) usb3_connect(usb3); spin_unlock_irqrestore(&usb3->lock, flags); } @@ -677,7 +683,7 @@ static void usb3_check_id(struct renesas_usb3 *usb3) { usb3->extcon_host = usb3_is_a_device(usb3); - if (usb3->extcon_host) + if (usb3->extcon_host && !usb3->forced_b_device) usb3_mode_config(usb3, true, true); else usb3_mode_config(usb3, false, false); @@ -1032,7 +1038,7 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_ep->ep.maxpacket); u8 *buf = usb3_req->req.buf + usb3_req->req.actual; u32 tmp = 0; - bool is_last; + bool is_last = !len ? true : false; if (usb3_wait_pipe_status(usb3_ep, PX_STA_BUFSTS) < 0) return -EBUSY; @@ -1053,7 +1059,8 @@ static int usb3_write_pipe(struct renesas_usb3_ep *usb3_ep, usb3_write(usb3, tmp, fifo_reg); } - is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); + if (!is_last) + is_last = usb3_is_transfer_complete(usb3_ep, usb3_req); /* Send the data */ usb3_set_px_con_send(usb3_ep, len, is_last); @@ -1144,7 +1151,8 @@ static void usb3_start_pipe0(struct renesas_usb3_ep *usb3_ep, usb3_set_p0_con_for_ctrl_read_data(usb3); } else { usb3_clear_bit(usb3, P0_MOD_DIR, USB3_P0_MOD); - usb3_set_p0_con_for_ctrl_write_data(usb3); + if (usb3_req->req.length) + usb3_set_p0_con_for_ctrl_write_data(usb3); } usb3_p0_xfer(usb3_ep, usb3_req); @@ -2047,7 +2055,16 @@ static u32 usb3_calc_ramarea(int ram_size) static u32 usb3_calc_rammap_val(struct renesas_usb3_ep *usb3_ep, const struct usb_endpoint_descriptor *desc) { - return usb3_ep->rammap_val | PN_RAMMAP_MPKT(usb_endpoint_maxp(desc)); + int i; + const u32 max_packet_array[] = {8, 16, 32, 64, 512}; + u32 mpkt = PN_RAMMAP_MPKT(1024); + + for (i = 0; i < ARRAY_SIZE(max_packet_array); i++) { + if (usb_endpoint_maxp(desc) <= max_packet_array[i]) + mpkt = PN_RAMMAP_MPKT(max_packet_array[i]); + } + + return usb3_ep->rammap_val | mpkt; } static int usb3_enable_pipe_n(struct renesas_usb3_ep *usb3_ep, @@ -2192,7 +2209,7 @@ static void renesas_usb3_ep_fifo_flush(struct usb_ep *_ep) } } -static struct usb_ep_ops renesas_usb3_ep_ops = { +static const struct usb_ep_ops renesas_usb3_ep_ops = { .enable = renesas_usb3_ep_enable, .disable = renesas_usb3_ep_disable, @@ -2283,6 +2300,9 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr, if (!usb3->driver) return -ENODEV; + if (usb3->forced_b_device) + return -EBUSY; + if (!strncmp(buf, "host", strlen("host"))) new_mode_is_host = true; else if (!strncmp(buf, "peripheral", strlen("peripheral"))) @@ -2310,6 +2330,70 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(role); +static int renesas_usb3_b_device_show(struct seq_file *s, void *unused) +{ + struct renesas_usb3 *usb3 = s->private; + + seq_printf(s, "%d\n", usb3->forced_b_device); + + return 0; +} + +static int renesas_usb3_b_device_open(struct inode *inode, struct file *file) +{ + return single_open(file, renesas_usb3_b_device_show, inode->i_private); +} + +static ssize_t renesas_usb3_b_device_write(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct renesas_usb3 *usb3 = s->private; + char buf[32]; + + if (!usb3->driver) + return -ENODEV; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "1", 1)) + usb3->forced_b_device = true; + else + usb3->forced_b_device = false; + + /* Let this driver call usb3_connect() anyway */ + usb3_check_id(usb3); + + return count; +} + +static const struct file_operations renesas_usb3_b_device_fops = { + .open = renesas_usb3_b_device_open, + .write = renesas_usb3_b_device_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void renesas_usb3_debugfs_init(struct renesas_usb3 *usb3, + struct device *dev) +{ + struct dentry *root, *file; + + root = debugfs_create_dir(dev_name(dev), NULL); + if (IS_ERR_OR_NULL(root)) { + dev_info(dev, "%s: Can't create the root\n", __func__); + return; + } + + file = debugfs_create_file("b_device", 0644, root, usb3, + &renesas_usb3_b_device_fops); + if (!file) + dev_info(dev, "%s: Can't create debugfs mode\n", __func__); +} + /*------- platform_driver ------------------------------------------------*/ static int renesas_usb3_remove(struct platform_device *pdev) { @@ -2432,22 +2516,40 @@ static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev, } } -static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795 = { +static const struct renesas_usb3_priv renesas_usb3_priv_r8a7795_es1 = { .ramsize_per_ramif = SZ_16K, .num_ramif = 2, .ramsize_per_pipe = SZ_4K, .workaround_for_vbus = true, }; +static const struct renesas_usb3_priv renesas_usb3_priv_gen3 = { + .ramsize_per_ramif = SZ_16K, + .num_ramif = 4, + .ramsize_per_pipe = SZ_4K, +}; + static const struct of_device_id usb3_of_match[] = { { .compatible = "renesas,r8a7795-usb3-peri", - .data = &renesas_usb3_priv_r8a7795, + .data = &renesas_usb3_priv_gen3, + }, + { + .compatible = "renesas,rcar-gen3-usb3-peri", + .data = &renesas_usb3_priv_gen3, }, { }, }; MODULE_DEVICE_TABLE(of, usb3_of_match); +static const struct soc_device_attribute renesas_usb3_quirks_match[] = { + { + .soc_id = "r8a7795", .revision = "ES1.*", + .data = &renesas_usb3_priv_r8a7795_es1, + }, + { /* sentinel */ }, +}; + static const unsigned int renesas_usb3_cable[] = { EXTCON_USB, EXTCON_USB_HOST, @@ -2461,15 +2563,23 @@ static int renesas_usb3_probe(struct platform_device *pdev) const struct of_device_id *match; int irq, ret; const struct renesas_usb3_priv *priv; + const struct soc_device_attribute *attr; match = of_match_node(usb3_of_match, pdev->dev.of_node); if (!match) return -ENODEV; - priv = match->data; + + attr = soc_device_match(renesas_usb3_quirks_match); + if (attr) + priv = attr->data; + else + priv = match->data; irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -ENODEV; + if (irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq); + return irq; + } usb3 = devm_kzalloc(&pdev->dev, sizeof(*usb3), GFP_KERNEL); if (!usb3) @@ -2527,6 +2637,8 @@ static int renesas_usb3_probe(struct platform_device *pdev) usb3->workaround_for_vbus = priv->workaround_for_vbus; + renesas_usb3_debugfs_init(usb3, &pdev->dev); + dev_info(&pdev->dev, "probed\n"); return 0; diff --git a/drivers/usb/gadget/udc/s3c2410_udc.c b/drivers/usb/gadget/udc/s3c2410_udc.c index 4643a01262b4..394abd5d65c0 100644 --- a/drivers/usb/gadget/udc/s3c2410_udc.c +++ b/drivers/usb/gadget/udc/s3c2410_udc.c @@ -51,7 +51,6 @@ #include "s3c2410_udc.h" #define DRIVER_DESC "S3C2410 USB Device Controller Gadget" -#define DRIVER_VERSION "29 Apr 2007" #define DRIVER_AUTHOR "Herbert Pötzl , " \ "Arnaud Patard " @@ -1996,7 +1995,7 @@ static int __init udc_init(void) { int retval; - dprintk(DEBUG_NORMAL, "%s: version %s\n", gadget_name, DRIVER_VERSION); + dprintk(DEBUG_NORMAL, "%s\n", gadget_name); s3c2410_udc_debugfs_root = debugfs_create_dir(gadget_name, NULL); if (IS_ERR(s3c2410_udc_debugfs_root)) { @@ -2027,5 +2026,4 @@ module_exit(udc_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/gadget/udc/snps_udc_plat.c b/drivers/usb/gadget/udc/snps_udc_plat.c index f7b4d0f159e4..e8a5fdaee37d 100644 --- a/drivers/usb/gadget/udc/snps_udc_plat.c +++ b/drivers/usb/gadget/udc/snps_udc_plat.c @@ -184,7 +184,7 @@ static int udc_plat_probe(struct platform_device *pdev) goto exit_phy; } - ret = extcon_get_cable_state_(udc->edev, EXTCON_USB); + ret = extcon_get_state(udc->edev, EXTCON_USB); if (ret < 0) { dev_err(dev, "Can't get cable state\n"); goto exit_extcon; @@ -273,7 +273,7 @@ static int udc_plat_suspend(struct device *dev) udc = dev_get_drvdata(dev); stop_udc(udc); - if (extcon_get_cable_state_(udc->edev, EXTCON_USB) > 0) { + if (extcon_get_state(udc->edev, EXTCON_USB) > 0) { dev_dbg(udc->dev, "device -> idle\n"); stop_udc(udc); } @@ -303,7 +303,7 @@ static int udc_plat_resume(struct device *dev) return ret; } - if (extcon_get_cable_state_(udc->edev, EXTCON_USB) > 0) { + if (extcon_get_state(udc->edev, EXTCON_USB) > 0) { dev_dbg(udc->dev, "idle -> device\n"); start_udc(udc); } diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index cf2691fffcc0..4ab2689c8952 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for USB Host Controller Drivers # diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 4a08b70c81aa..d025cc06dda7 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -642,7 +642,7 @@ static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) #define ehci_start_port_reset NULL #endif /* CONFIG_USB_OTG */ -static struct ehci_driver_overrides ehci_fsl_overrides __initdata = { +static const struct ehci_driver_overrides ehci_fsl_overrides __initconst = { .extra_priv_size = sizeof(struct ehci_fsl), .reset = ehci_fsl_setup, }; diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 94ea9fff13e6..4d308533bc83 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -130,8 +130,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(dev, "EHCI irq failed\n"); - return -ENODEV; + dev_err(dev, "EHCI irq failed: %d\n", irq); + return irq; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index b5cfa7aeb277..7fcd785c7bc8 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_FOTG210_H #define __LINUX_FOTG210_H diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index e90ddb530765..ba557cdba8ef 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -55,8 +55,8 @@ static struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np) return &dr_mode_data[i]; } } - pr_warn("%s: Invalid 'dr_mode' property, fallback to host mode\n", - np->full_name); + pr_warn("%pOF: Invalid 'dr_mode' property, fallback to host mode\n", + np); return &dr_mode_data[0]; /* mode not specified, use host */ } diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 1db0626c8bf4..da3b18038d23 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -614,7 +614,7 @@ error: return result; } -static struct hc_driver hwahc_hc_driver = { +static const struct hc_driver hwahc_hc_driver = { .description = "hwa-hcd", .product_desc = "Wireless USB HWA host controller", .hcd_priv_size = sizeof(struct hwahc) - sizeof(struct usb_hcd), @@ -860,7 +860,7 @@ static void hwahc_disconnect(struct usb_interface *usb_iface) usb_put_hcd(usb_hcd); } -static struct usb_device_id hwahc_id_table[] = { +static const struct usb_device_id hwahc_id_table[] = { /* Alereon 5310 */ { USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01), .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC | diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index f542045dc2a6..39ae7fb64b6f 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1779,7 +1779,7 @@ static void imx21_hc_stop(struct usb_hcd *hcd) /* Driver glue */ /* =========================================== */ -static struct hc_driver imx21_hc_driver = { +static const struct hc_driver imx21_hc_driver = { .description = hcd_name, .product_desc = "IMX21 USB Host Controller", .hcd_priv_size = sizeof(struct imx21), @@ -1849,8 +1849,10 @@ static int imx21_probe(struct platform_device *pdev) if (!res) return -ENODEV; irq = platform_get_irq(pdev, 0); - if (irq < 0) - return -ENXIO; + if (irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", irq); + return irq; + } hcd = usb_create_hcd(&imx21_hc_driver, &pdev->dev, dev_name(&pdev->dev)); diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index d089b3fb7a13..73fec38754f9 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1511,7 +1511,7 @@ static int isp116x_bus_resume(struct usb_hcd *hcd) #endif -static struct hc_driver isp116x_hc_driver = { +static const struct hc_driver isp116x_hc_driver = { .description = hcd_name, .product_desc = "ISP116x Host Controller", .hcd_priv_size = sizeof(struct isp116x), diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index dd34b7a33965..a5e929c10d53 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ISP116x register declarations and HCD data structures * diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 0f2b4b358e1a..9b7e307e2d54 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2591,7 +2591,7 @@ static int isp1362_hc_start(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static struct hc_driver isp1362_hc_driver = { +static const struct hc_driver isp1362_hc_driver = { .description = hcd_name, .product_desc = "ISP1362 Host Controller", .hcd_priv_size = sizeof(struct isp1362_hcd), diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h index 3b0b4847c3a9..da79e36ced89 100644 --- a/drivers/usb/host/isp1362.h +++ b/drivers/usb/host/isp1362.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ISP1362 HCD (Host Controller Driver) for USB. * diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 369869a29ebd..0ece9a9341e5 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -1811,7 +1811,7 @@ max3421_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) { } -static struct hc_driver max3421_hcd_desc = { +static const struct hc_driver max3421_hcd_desc = { .description = "max3421", .product_desc = DRIVER_DESC, .hcd_priv_size = sizeof(struct max3421_hcd), diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index a4d814b7f380..91393ec7d850 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -53,7 +53,7 @@ #define DRIVER_DESC "OHCI OMAP driver" #ifdef CONFIG_TPS65010 -#include +#include #else #define LOW 0 diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index a8b8d8b8d9f3..d4e0f7cd96fa 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -123,13 +123,12 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev) * regular memory. The HCD_LOCAL_MEM flag does just that. */ - if (!dma_declare_coherent_memory(dev, mem->start, + retval = dma_declare_coherent_memory(dev, mem->start, mem->start - mem->parent->start, resource_size(mem), - DMA_MEMORY_MAP | - DMA_MEMORY_EXCLUSIVE)) { + DMA_MEMORY_EXCLUSIVE); + if (retval) { dev_err(dev, "cannot declare coherent memory\n"); - retval = -ENXIO; goto err1; } diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index cfcfadfc94fc..16d081a093bb 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -227,13 +227,10 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) goto err_ioremap_regs; } - if (!dma_declare_coherent_memory(&dev->dev, sram->start, - sram->start, - resource_size(sram), - DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE)) { - ret = -EBUSY; + ret = dma_declare_coherent_memory(&dev->dev, sram->start, sram->start, + resource_size(sram), DMA_MEMORY_EXCLUSIVE); + if (ret) goto err_dma_declare; - } if (cell->enable) { ret = cell->enable(dev); diff --git a/drivers/usb/host/oxu210hp.h b/drivers/usb/host/oxu210hp.h index 1c216ad9aad2..437044147862 100644 --- a/drivers/usb/host/oxu210hp.h +++ b/drivers/usb/host/oxu210hp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Host interface registers */ diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index c8f38649f749..6dda3623a276 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -142,29 +142,30 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo) pinfo->sb_type.gen = AMD_CHIPSET_SB700; else if (rev >= 0x40 && rev <= 0x4f) pinfo->sb_type.gen = AMD_CHIPSET_SB800; - } - pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, - 0x145c, NULL); - if (pinfo->smbus_dev) { - pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN; } else { pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL); - if (!pinfo->smbus_dev) { - pinfo->sb_type.gen = NOT_AMD_CHIPSET; - return 0; + if (pinfo->smbus_dev) { + rev = pinfo->smbus_dev->revision; + if (rev >= 0x11 && rev <= 0x14) + pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2; + else if (rev >= 0x15 && rev <= 0x18) + pinfo->sb_type.gen = AMD_CHIPSET_BOLTON; + else if (rev >= 0x39 && rev <= 0x3a) + pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE; + } else { + pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, + 0x145c, NULL); + if (pinfo->smbus_dev) { + rev = pinfo->smbus_dev->revision; + pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN; + } else { + pinfo->sb_type.gen = NOT_AMD_CHIPSET; + return 0; + } } - - rev = pinfo->smbus_dev->revision; - if (rev >= 0x11 && rev <= 0x14) - pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2; - else if (rev >= 0x15 && rev <= 0x18) - pinfo->sb_type.gen = AMD_CHIPSET_BOLTON; - else if (rev >= 0x39 && rev <= 0x3a) - pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE; } - pinfo->sb_type.rev = rev; return 1; } @@ -446,7 +447,7 @@ static int usb_asmedia_wait_write(struct pci_dev *pdev) if ((value & ASMT_CONTROL_WRITE_BIT) == 0) return 0; - usleep_range(40, 60); + udelay(50); } dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__); @@ -1021,7 +1022,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); * * Takes care of the handoff between the Pre-OS (i.e. BIOS) and the OS. * It signals to the BIOS that the OS wants control of the host controller, - * and then waits 5 seconds for the BIOS to hand over control. + * and then waits 1 second for the BIOS to hand over control. * If we timeout, assume the BIOS is broken and take control anyway. */ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) @@ -1068,9 +1069,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) if (val & XHCI_HC_BIOS_OWNED) { writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); - /* Wait for 5 seconds with 10 microsecond polling interval */ + /* Wait for 1 second with 10 microsecond polling interval */ timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, - 0, 5000, 10); + 0, 1000000, 10); /* Assume a buggy BIOS and take HC ownership anyway */ if (timeout) { @@ -1099,7 +1100,7 @@ hc_init: * operational or runtime registers. Wait 5 seconds and no more. */ timeout = handshake(op_reg_base + XHCI_STS_OFFSET, XHCI_STS_CNR, 0, - 5000, 10); + 5000000, 10); /* Assume a buggy HC and start HC initialization anyway */ if (timeout) { val = readl(op_reg_base + XHCI_STS_OFFSET); diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index 5582cbafecd4..b68dcb5dd0fd 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_USB_PCI_QUIRKS_H #define __LINUX_USB_PCI_QUIRKS_H diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 7bf78be1fd32..5e5fc9d7d533 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2312,7 +2312,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd) #define r8a66597_bus_resume NULL #endif -static struct hc_driver r8a66597_hc_driver = { +static const struct hc_driver r8a66597_hc_driver = { .description = hcd_name, .hcd_priv_size = sizeof(struct r8a66597), .irq = r8a66597_irq, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index fd2a11473be7..24ad1d6cec25 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1554,7 +1554,7 @@ sl811h_start(struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static struct hc_driver sl811h_hc_driver = { +static const struct hc_driver sl811h_hc_driver = { .description = hcd_name, .hcd_priv_size = sizeof(struct sl811), diff --git a/drivers/usb/host/sl811.h b/drivers/usb/host/sl811.h index 1e23ef49bec1..2abe51a5db44 100644 --- a/drivers/usb/host/sl811.h +++ b/drivers/usb/host/sl811.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * SL811HS register declarations and HCD data structures * diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 43d52931b5bf..c38855aed62c 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2941,7 +2941,7 @@ static int u132_bus_resume(struct usb_hcd *hcd) #define u132_bus_suspend NULL #define u132_bus_resume NULL #endif -static struct hc_driver u132_hc_driver = { +static const struct hc_driver u132_hc_driver = { .description = hcd_name, .hcd_priv_size = sizeof(struct u132), .irq = NULL, diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 9c6635d43db0..c4e67c4b51f6 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * UHCI-specific debugging code. Invaluable when something * goes wrong, but don't get in my face. diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index 0342991c9507..2103b1ed0f8f 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * UHCI HCD (Host Controller Driver) for GRLIB GRUSBHC * diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 91b22b2ea3aa..d97f0d9b3ce6 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_UHCI_HCD_H #define __LINUX_UHCI_HCD_H diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index ece9e37e89fe..47106dd8ca7c 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Universal Host Controller Interface driver for USB. * diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 49effdc0d857..0dd944277c99 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * UHCI HCD (Host Controller Driver) PCI Bus Glue. * diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index 1b4e086c33a0..6cb16d4b2257 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generic UHCI HCD (Host Controller Driver) for Platform Devices * diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index c17ea1589b83..49d4edc03cc2 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Universal Host Controller Interface driver for USB. * diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index 5b3603c360ab..cf84269c3e6d 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c @@ -213,7 +213,7 @@ static void whc_endpoint_reset(struct usb_hcd *usb_hcd, } -static struct hc_driver whc_hc_driver = { +static const struct hc_driver whc_hc_driver = { .description = "whci-hcd", .product_desc = "Wireless host controller", .hcd_priv_size = sizeof(struct whc) - sizeof(struct usb_hcd), diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 00721e8807ab..a2336deb5e36 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -112,7 +112,7 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, /* If PSI table exists, add the custom speed attributes from it */ if (usb3_1 && xhci->usb3_rhub.psi_count) { - u32 ssp_cap_base, bm_attrib, psi; + u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp; int offset; ssp_cap_base = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE; @@ -139,6 +139,15 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, for (i = 0; i < xhci->usb3_rhub.psi_count; i++) { psi = xhci->usb3_rhub.psi[i]; psi &= ~USB_SSP_SUBLINK_SPEED_RSVD; + psi_exp = XHCI_EXT_PORT_PSIE(psi); + psi_mant = XHCI_EXT_PORT_PSIM(psi); + + /* Shift to Gbps and set SSP Link BIT(14) if 10Gpbs */ + for (; psi_exp < 3; psi_exp++) + psi_mant /= 1000; + if (psi_mant >= 10) + psi |= BIT(14); + if ((psi & PLT_MASK) == PLT_SYM) { /* Symmetric, create SSA RX and TX from one PSI entry */ put_unaligned_le32(psi, &buf[offset]); @@ -411,14 +420,25 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) GFP_NOWAIT); if (!command) { spin_unlock_irqrestore(&xhci->lock, flags); - xhci_free_command(xhci, cmd); - return -ENOMEM; + ret = -ENOMEM; + goto cmd_cleanup; + } + + ret = xhci_queue_stop_endpoint(xhci, command, slot_id, + i, suspend); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_free_command(xhci, command); + goto cmd_cleanup; } - xhci_queue_stop_endpoint(xhci, command, slot_id, i, - suspend); } } - xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); + ret = xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); + goto cmd_cleanup; + } + xhci_ring_cmd_db(xhci); spin_unlock_irqrestore(&xhci->lock, flags); @@ -430,6 +450,8 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n"); ret = -ETIME; } + +cmd_cleanup: xhci_free_command(xhci, cmd); return ret; } @@ -1179,6 +1201,39 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, break; } + /* + * For xHCI 1.1 according to section 4.19.1.2.4.1 a + * root hub port's transition to compliance mode upon + * detecting LFPS timeout may be controlled by an + * Compliance Transition Enabled (CTE) flag (not + * software visible). This flag is set by writing 0xA + * to PORTSC PLS field which will allow transition to + * compliance mode the next time LFPS timeout is + * encountered. A warm reset will clear it. + * + * The CTE flag is only supported if the HCCPARAMS2 CTC + * flag is set, otherwise, the compliance substate is + * automatically entered as on 1.0 and prior. + */ + if (link_state == USB_SS_PORT_LS_COMP_MOD) { + if (!HCC2_CTC(xhci->hcc_params2)) { + xhci_dbg(xhci, "CTC flag is 0, port already supports entering compliance mode\n"); + break; + } + + if ((temp & PORT_CONNECT)) { + xhci_warn(xhci, "Can't set compliance mode when port is connected\n"); + goto error; + } + + xhci_dbg(xhci, "Enable compliance mode transition for port %d\n", + wIndex); + xhci_set_link_state(xhci, port_array, wIndex, + link_state); + temp = readl(port_array[wIndex]); + break; + } + /* Software should not attempt to set * port link state above '3' (U3) and the port * must be enabled. @@ -1473,9 +1528,6 @@ int xhci_bus_suspend(struct usb_hcd *hcd) t2 |= PORT_WKOC_E | PORT_WKCONN_E; t2 &= ~PORT_WKDISC_E; } - if ((xhci->quirks & XHCI_U2_DISABLE_WAKE) && - (hcd->speed < HCD_USB3)) - t2 &= ~PORT_WAKE_BITS; } else t2 &= ~PORT_WAKE_BITS; @@ -1521,15 +1573,14 @@ static bool xhci_port_missing_cas_quirk(int port_index, int xhci_bus_resume(struct usb_hcd *hcd) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int max_ports, port_index; - __le32 __iomem **port_array; struct xhci_bus_state *bus_state; - u32 temp; + __le32 __iomem **port_array; unsigned long flags; - unsigned long port_was_suspended = 0; - bool need_usb2_u3_exit = false; + int max_ports, port_index; int slot_id; int sret; + u32 next_state; + u32 temp, portsc; max_ports = xhci_get_ports(hcd, &port_array); bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -1548,68 +1599,77 @@ int xhci_bus_resume(struct usb_hcd *hcd) temp &= ~CMD_EIE; writel(temp, &xhci->op_regs->command); + /* bus specific resume for ports we suspended at bus_suspend */ + if (hcd->speed >= HCD_USB3) + next_state = XDEV_U0; + else + next_state = XDEV_RESUME; + port_index = max_ports; while (port_index--) { - /* Check whether need resume ports. If needed - resume port and disable remote wakeup */ - u32 temp; - - temp = readl(port_array[port_index]); + portsc = readl(port_array[port_index]); /* warm reset CAS limited ports stuck in polling/compliance */ if ((xhci->quirks & XHCI_MISSING_CAS) && (hcd->speed >= HCD_USB3) && xhci_port_missing_cas_quirk(port_index, port_array)) { xhci_dbg(xhci, "reset stuck port %d\n", port_index); + clear_bit(port_index, &bus_state->bus_suspended); continue; } - if (DEV_SUPERSPEED_ANY(temp)) - temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); - else - temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); - if (test_bit(port_index, &bus_state->bus_suspended) && - (temp & PORT_PLS_MASK)) { - set_bit(port_index, &port_was_suspended); - if (!DEV_SUPERSPEED_ANY(temp)) { - xhci_set_link_state(xhci, port_array, - port_index, XDEV_RESUME); - need_usb2_u3_exit = true; + /* resume if we suspended the link, and it is still suspended */ + if (test_bit(port_index, &bus_state->bus_suspended)) + switch (portsc & PORT_PLS_MASK) { + case XDEV_U3: + portsc = xhci_port_state_to_neutral(portsc); + portsc &= ~PORT_PLS_MASK; + portsc |= PORT_LINK_STROBE | next_state; + break; + case XDEV_RESUME: + /* resume already initiated */ + break; + default: + /* not in a resumeable state, ignore it */ + clear_bit(port_index, + &bus_state->bus_suspended); + break; } - } else - writel(temp, port_array[port_index]); + /* disable wake for all ports, write new link state if needed */ + portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS); + writel(portsc, port_array[port_index]); } - if (need_usb2_u3_exit) { - spin_unlock_irqrestore(&xhci->lock, flags); - msleep(USB_RESUME_TIMEOUT); - spin_lock_irqsave(&xhci->lock, flags); + /* USB2 specific resume signaling delay and U0 link state transition */ + if (hcd->speed < HCD_USB3) { + if (bus_state->bus_suspended) { + spin_unlock_irqrestore(&xhci->lock, flags); + msleep(USB_RESUME_TIMEOUT); + spin_lock_irqsave(&xhci->lock, flags); + } + for_each_set_bit(port_index, &bus_state->bus_suspended, + BITS_PER_LONG) { + /* Clear PLC to poll it later for U0 transition */ + xhci_test_and_clear_bit(xhci, port_array, port_index, + PORT_PLC); + xhci_set_link_state(xhci, port_array, port_index, + XDEV_U0); + } } - port_index = max_ports; - while (port_index--) { - if (!(port_was_suspended & BIT(port_index))) - continue; - /* Clear PLC to poll it later after XDEV_U0 */ - xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC); - xhci_set_link_state(xhci, port_array, port_index, XDEV_U0); - } - - port_index = max_ports; - while (port_index--) { - if (!(port_was_suspended & BIT(port_index))) - continue; - /* Poll and Clear PLC */ + /* poll for U0 link state complete, both USB2 and USB3 */ + for_each_set_bit(port_index, &bus_state->bus_suspended, BITS_PER_LONG) { sret = xhci_handshake(port_array[port_index], PORT_PLC, PORT_PLC, 10 * 1000); - if (sret) + if (sret) { xhci_warn(xhci, "port %d resume PLC timeout\n", port_index); + continue; + } xhci_test_and_clear_bit(xhci, port_array, port_index, PORT_PLC); slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1); if (slot_id) xhci_ring_device(xhci, slot_id); } - (void) readl(&xhci->op_regs->command); bus_state->next_statechange = jiffies + msecs_to_jiffies(5); diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 67d5dc79b6b5..8fb60657ed4f 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -795,6 +795,7 @@ static const struct dev_pm_ops xhci_mtk_pm_ops = { #ifdef CONFIG_OF static const struct of_device_id mtk_xhci_of_match[] = { { .compatible = "mediatek,mt8173-xhci"}, + { .compatible = "mediatek,mtk-xhci"}, { }, }; MODULE_DEVICE_TABLE(of, mtk_xhci_of_match); diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 8071c8fdd15e..76f392954733 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -54,11 +54,6 @@ #define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8 #define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0 -#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 -#define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba -#define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb -#define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc - #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 static const char hcd_name[] = "xhci_hcd"; @@ -142,13 +137,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_AMD) xhci->quirks |= XHCI_TRUST_TX_LENGTH; - if ((pdev->vendor == PCI_VENDOR_ID_AMD) && - ((pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_3) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_2) || - (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) - xhci->quirks |= XHCI_U2_DISABLE_WAKE; - if (pdev->vendor == PCI_VENDOR_ID_INTEL) { xhci->quirks |= XHCI_LPM_SUPPORT; xhci->quirks |= XHCI_INTEL_HOST; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c04144b25a67..1cb6eaef4ae1 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -107,14 +107,6 @@ static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = { }; static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen3 = { - .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2, - .init_quirk = xhci_rcar_init_quirk, - .plat_start = xhci_rcar_start, - .resume_quirk = xhci_rcar_resume_quirk, -}; - -static const struct xhci_plat_priv xhci_plat_renesas_rcar_r8a7796 = { - .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3, .init_quirk = xhci_rcar_init_quirk, .plat_start = xhci_rcar_start, .resume_quirk = xhci_rcar_resume_quirk, @@ -145,7 +137,7 @@ static const struct of_device_id usb_xhci_of_match[] = { .data = &xhci_plat_renesas_rcar_gen3, }, { .compatible = "renesas,xhci-r8a7796", - .data = &xhci_plat_renesas_rcar_r8a7796, + .data = &xhci_plat_renesas_rcar_gen3, }, { .compatible = "renesas,rcar-gen2-xhci", .data = &xhci_plat_renesas_rcar_gen2, @@ -186,14 +178,18 @@ static int xhci_plat_probe(struct platform_device *pdev) * 2. xhci_plat is child of a device from firmware (dwc3-plat) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; #ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && - sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; + else if (sysdev->bus == &pci_bus_type) + break; #endif + } + + if (!sysdev) + sysdev = &pdev->dev; /* Try to set 64-bit DMA first */ if (WARN_ON(!sysdev->dma_mask)) diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 07278228214b..198bc188ab25 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -13,13 +13,15 @@ #include #include #include +#include #include "xhci.h" #include "xhci-plat.h" #include "xhci-rcar.h" /* -* - The V3 firmware is for r8a7796 (with good performance). +* - The V3 firmware is for r8a7796 (with good performance) and r8a7795 es2.0 +* or later. * - The V2 firmware can be used on both r8a7795 (es1.x) and r8a7796. * - The V2 firmware is possible to use on R-Car Gen2. However, the V2 causes * performance degradation. So, this driver continues to use the V1 if R-Car @@ -67,6 +69,26 @@ MODULE_FIRMWARE(XHCI_RCAR_FIRMWARE_NAME_V3); #define RCAR_USB3_RX_POL_VAL BIT(21) #define RCAR_USB3_TX_POL_VAL BIT(4) +/* For soc_device_attribute */ +#define RCAR_XHCI_FIRMWARE_V2 BIT(0) /* FIRMWARE V2 */ +#define RCAR_XHCI_FIRMWARE_V3 BIT(1) /* FIRMWARE V3 */ + +static const struct soc_device_attribute rcar_quirks_match[] = { + { + .soc_id = "r8a7795", .revision = "ES1.*", + .data = (void *)RCAR_XHCI_FIRMWARE_V2, + }, + { + .soc_id = "r8a7795", + .data = (void *)RCAR_XHCI_FIRMWARE_V3, + }, + { + .soc_id = "r8a7796", + .data = (void *)RCAR_XHCI_FIRMWARE_V3, + }, + { /* sentinel */ }, +}; + static void xhci_rcar_start_gen2(struct usb_hcd *hcd) { /* LCLK Select */ @@ -122,9 +144,23 @@ static int xhci_rcar_download_firmware(struct usb_hcd *hcd) int retval, index, j, time; int timeout = 10000; u32 data, val, temp; + u32 quirks = 0; + const struct soc_device_attribute *attr; + const char *firmware_name; + + attr = soc_device_match(rcar_quirks_match); + if (attr) + quirks = (uintptr_t)attr->data; + + if (quirks & RCAR_XHCI_FIRMWARE_V2) + firmware_name = XHCI_RCAR_FIRMWARE_NAME_V2; + else if (quirks & RCAR_XHCI_FIRMWARE_V3) + firmware_name = XHCI_RCAR_FIRMWARE_NAME_V3; + else + firmware_name = priv->firmware_name; /* request R-Car USB3.0 firmware */ - retval = request_firmware(&fw, priv->firmware_name, dev); + retval = request_firmware(&fw, firmware_name, dev); if (retval) return retval; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index cc368ad2b51e..82c746e2d85c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1309,6 +1309,7 @@ static void xhci_complete_del_and_free_cmd(struct xhci_command *cmd, u32 status) void xhci_cleanup_command_queue(struct xhci_hcd *xhci) { struct xhci_command *cur_cmd, *tmp_cmd; + xhci->current_cmd = NULL; list_for_each_entry_safe(cur_cmd, tmp_cmd, &xhci->cmd_list, cmd_list) xhci_complete_del_and_free_cmd(cur_cmd, COMP_COMMAND_ABORTED); } @@ -1572,7 +1573,7 @@ static void handle_port_status(struct xhci_hcd *xhci, { struct usb_hcd *hcd; u32 port_id; - u32 temp, temp1; + u32 portsc, cmd_reg; int max_ports; int slot_id; unsigned int faked_port_index; @@ -1636,26 +1637,28 @@ static void handle_port_status(struct xhci_hcd *xhci, /* Find the faked port hub number */ faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci, port_id); + portsc = readl(port_array[faked_port_index]); + + trace_xhci_handle_port_status(faked_port_index, portsc); - temp = readl(port_array[faked_port_index]); if (hcd->state == HC_STATE_SUSPENDED) { xhci_dbg(xhci, "resume root hub\n"); usb_hcd_resume_root_hub(hcd); } - if (hcd->speed >= HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE) + if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) bus_state->port_remote_wakeup &= ~(1 << faked_port_index); - if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) { + if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) { xhci_dbg(xhci, "port resume event for port %d\n", port_id); - temp1 = readl(&xhci->op_regs->command); - if (!(temp1 & CMD_RUN)) { + cmd_reg = readl(&xhci->op_regs->command); + if (!(cmd_reg & CMD_RUN)) { xhci_warn(xhci, "xHC is not running.\n"); goto cleanup; } - if (DEV_SUPERSPEED_ANY(temp)) { + if (DEV_SUPERSPEED_ANY(portsc)) { xhci_dbg(xhci, "remote wake SS port %d\n", port_id); /* Set a flag to say the port signaled remote wakeup, * so we can tell the difference between the end of @@ -1683,8 +1686,8 @@ static void handle_port_status(struct xhci_hcd *xhci, } } - if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 && - DEV_SUPERSPEED_ANY(temp)) { + if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_U0 && + DEV_SUPERSPEED_ANY(portsc)) { xhci_dbg(xhci, "resume SS port %d finished\n", port_id); /* We've just brought the device into U0 through either the * Resume state after a device remote wakeup, or through the @@ -1714,7 +1717,7 @@ static void handle_port_status(struct xhci_hcd *xhci, * RExit to a disconnect state). If so, let the the driver know it's * out of the RExit state. */ - if (!DEV_SUPERSPEED_ANY(temp) && + if (!DEV_SUPERSPEED_ANY(portsc) && test_and_clear_bit(faked_port_index, &bus_state->rexit_ports)) { complete(&bus_state->rexit_done[faked_port_index]); @@ -2577,15 +2580,21 @@ static int handle_tx_event(struct xhci_hcd *xhci, (struct xhci_generic_trb *) ep_trb); /* - * No-op TRB should not trigger interrupts. - * If ep_trb is a no-op TRB, it means the - * corresponding TD has been cancelled. Just ignore - * the TD. + * No-op TRB could trigger interrupts in a case where + * a URB was killed and a STALL_ERROR happens right + * after the endpoint ring stopped. Reset the halted + * endpoint. Otherwise, the endpoint remains stalled + * indefinitely. */ if (trb_is_noop(ep_trb)) { - xhci_dbg(xhci, - "ep_trb is a no-op TRB. Skip it for slot %u ep %u\n", - slot_id, ep_index); + if (trb_comp_code == COMP_STALL_ERROR || + xhci_requires_manual_halt_cleanup(xhci, ep_ctx, + trb_comp_code)) + xhci_cleanup_halted_endpoint(xhci, slot_id, + ep_index, + ep_ring->stream_id, + td, ep_trb, + EP_HARD_RESET); goto cleanup; } diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index 8ce96de10e8a..f20753b99624 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -453,6 +453,29 @@ DEFINE_EVENT(xhci_log_ring, xhci_inc_deq, TP_PROTO(struct xhci_ring *ring), TP_ARGS(ring) ); + +DECLARE_EVENT_CLASS(xhci_log_portsc, + TP_PROTO(u32 portnum, u32 portsc), + TP_ARGS(portnum, portsc), + TP_STRUCT__entry( + __field(u32, portnum) + __field(u32, portsc) + ), + TP_fast_assign( + __entry->portnum = portnum; + __entry->portsc = portsc; + ), + TP_printk("port-%d: %s", + __entry->portnum, + xhci_decode_portsc(__entry->portsc) + ) +); + +DEFINE_EVENT(xhci_log_portsc, xhci_handle_port_status, + TP_PROTO(u32 portnum, u32 portsc), + TP_ARGS(portnum, portsc) +); + #endif /* __XHCI_TRACE_H */ /* this part must be outside header guard */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b2ff1ff1a02f..51535ba2bcd4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1703,7 +1703,8 @@ static int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, if (xhci->quirks & XHCI_MTK_HOST) { ret = xhci_mtk_add_ep_quirk(hcd, udev, ep); if (ret < 0) { - xhci_free_endpoint_ring(xhci, virt_dev, ep_index); + xhci_ring_free(xhci, virt_dev->eps[ep_index].new_ring); + virt_dev->eps[ep_index].new_ring = NULL; return ret; } } @@ -4804,7 +4805,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) */ hcd->has_tt = 1; } else { - if (xhci->sbrn == 0x31) { + /* Some 3.1 hosts return sbrn 0x30, can't rely on sbrn alone */ + if (xhci->sbrn == 0x31 || xhci->usb3_rhub.min_rev >= 1) { xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n"); hcd->speed = HCD_USB31; hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e3e935291ed6..2b48aa4f6b76 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -311,12 +311,19 @@ struct xhci_op_regs { */ #define PORT_PLS_MASK (0xf << 5) #define XDEV_U0 (0x0 << 5) +#define XDEV_U1 (0x1 << 5) #define XDEV_U2 (0x2 << 5) #define XDEV_U3 (0x3 << 5) +#define XDEV_DISABLED (0x4 << 5) +#define XDEV_RXDETECT (0x5 << 5) #define XDEV_INACTIVE (0x6 << 5) #define XDEV_POLLING (0x7 << 5) -#define XDEV_COMP_MODE (0xa << 5) +#define XDEV_RECOVERY (0x8 << 5) +#define XDEV_HOT_RESET (0x9 << 5) +#define XDEV_COMP_MODE (0xa << 5) +#define XDEV_TEST_MODE (0xb << 5) #define XDEV_RESUME (0xf << 5) + /* true: port has power (see HCC_PPC) */ #define PORT_POWER (1 << 9) /* bits 10:13 indicate device speed: @@ -728,6 +735,8 @@ struct xhci_ep_ctx { #define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK) /* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */ #define EP_HAS_LSA (1 << 15) +/* hosts with LEC=1 use bits 31:24 as ESIT high bits. */ +#define CTX_TO_MAX_ESIT_PAYLOAD_HI(p) (((p) >> 24) & 0xff) /* ep_info2 bitmasks */ /* @@ -1674,7 +1683,7 @@ struct xhci_bus_state { static inline unsigned int hcd_index(struct usb_hcd *hcd) { - if (hcd->speed == HCD_USB3) + if (hcd->speed >= HCD_USB3) return 0; else return 1; @@ -1819,7 +1828,7 @@ struct xhci_hcd { /* For controller with a broken Port Disable implementation */ #define XHCI_BROKEN_PORT_PED (1 << 25) #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) -#define XHCI_U2_DISABLE_WAKE (1 << 27) +/* Reserved. It was XHCI_U2_DISABLE_WAKE */ #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) unsigned int num_active_eps; @@ -2392,6 +2401,87 @@ static inline const char *xhci_decode_slot_context(u32 info, u32 info2, return str; } + +static inline const char *xhci_portsc_link_state_string(u32 portsc) +{ + switch (portsc & PORT_PLS_MASK) { + case XDEV_U0: + return "U0"; + case XDEV_U1: + return "U1"; + case XDEV_U2: + return "U2"; + case XDEV_U3: + return "U3"; + case XDEV_DISABLED: + return "Disabled"; + case XDEV_RXDETECT: + return "RxDetect"; + case XDEV_INACTIVE: + return "Inactive"; + case XDEV_POLLING: + return "Polling"; + case XDEV_RECOVERY: + return "Recovery"; + case XDEV_HOT_RESET: + return "Hot Reset"; + case XDEV_COMP_MODE: + return "Compliance mode"; + case XDEV_TEST_MODE: + return "Test mode"; + case XDEV_RESUME: + return "Resume"; + default: + break; + } + return "Unknown"; +} + +static inline const char *xhci_decode_portsc(u32 portsc) +{ + static char str[256]; + int ret; + + ret = sprintf(str, "%s %s %s Link:%s ", + portsc & PORT_POWER ? "Powered" : "Powered-off", + portsc & PORT_CONNECT ? "Connected" : "Not-connected", + portsc & PORT_PE ? "Enabled" : "Disabled", + xhci_portsc_link_state_string(portsc)); + + if (portsc & PORT_OC) + ret += sprintf(str + ret, "OverCurrent "); + if (portsc & PORT_RESET) + ret += sprintf(str + ret, "In-Reset "); + + ret += sprintf(str + ret, "Change: "); + if (portsc & PORT_CSC) + ret += sprintf(str + ret, "CSC "); + if (portsc & PORT_PEC) + ret += sprintf(str + ret, "PEC "); + if (portsc & PORT_WRC) + ret += sprintf(str + ret, "WRC "); + if (portsc & PORT_OCC) + ret += sprintf(str + ret, "OCC "); + if (portsc & PORT_RC) + ret += sprintf(str + ret, "PRC "); + if (portsc & PORT_PLC) + ret += sprintf(str + ret, "PLC "); + if (portsc & PORT_CEC) + ret += sprintf(str + ret, "CEC "); + if (portsc & PORT_CAS) + ret += sprintf(str + ret, "CAS "); + + ret += sprintf(str + ret, "Wake: "); + if (portsc & PORT_WKCONN_E) + ret += sprintf(str + ret, "WCE "); + if (portsc & PORT_WKDISC_E) + ret += sprintf(str + ret, "WDE "); + if (portsc & PORT_WKOC_E) + ret += sprintf(str + ret, "WOE "); + + return str; +} + static inline const char *xhci_ep_state_string(u8 state) { switch (state) { @@ -2452,8 +2542,8 @@ static inline const char *xhci_decode_ep_context(u32 info, u32 info2, u64 deq, u8 lsa; u8 hid; - esit = EP_MAX_ESIT_PAYLOAD_HI(info) << 16 | - EP_MAX_ESIT_PAYLOAD_LO(tx_info); + esit = CTX_TO_MAX_ESIT_PAYLOAD_HI(info) << 16 | + CTX_TO_MAX_ESIT_PAYLOAD(tx_info); ep_state = info & EP_STATE_MASK; max_pstr = info & EP_MAXPSTREAMS_MASK; diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index a4dbb0cd80da..0b21ba757bba 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -137,10 +137,6 @@ #include "microtek.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v0.4.3" #define DRIVER_AUTHOR "John Fremlin , Oliver Neukum " #define DRIVER_DESC "Microtek Scanmaker X6 USB scanner driver" diff --git a/drivers/usb/image/microtek.h b/drivers/usb/image/microtek.h index 7e32ae787136..66685e59241a 100644 --- a/drivers/usb/image/microtek.h +++ b/drivers/usb/image/microtek.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Driver for Microtek Scanmaker X6 USB scanner and possibly others. * diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index ac31d19cc54b..bb4d6d959871 100644 --- a/drivers/usb/isp1760/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the NXP ISP1760 chip * @@ -396,7 +397,6 @@ static int handshake(struct usb_hcd *hcd, u32 reg, /* reset a non-running (STS_HALT == 1) controller */ static int ehci_reset(struct usb_hcd *hcd) { - int retval; struct isp1760_hcd *priv = hcd_to_priv(hcd); u32 command = reg_read32(hcd->regs, HC_USBCMD); @@ -405,9 +405,8 @@ static int ehci_reset(struct usb_hcd *hcd) reg_write32(hcd->regs, HC_USBCMD, command); hcd->state = HC_STATE_HALT; priv->next_statechange = jiffies; - retval = handshake(hcd, HC_USBCMD, - CMD_RESET, 0, 250 * 1000); - return retval; + + return handshake(hcd, HC_USBCMD, CMD_RESET, 0, 250 * 1000); } static struct isp1760_qh *qh_alloc(gfp_t flags) diff --git a/drivers/usb/isp1760/isp1760-hcd.h b/drivers/usb/isp1760/isp1760-hcd.h index 0c1c98d6ea08..f1bb2deb1ccf 100644 --- a/drivers/usb/isp1760/isp1760-hcd.h +++ b/drivers/usb/isp1760/isp1760-hcd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ISP1760_HCD_H_ #define _ISP1760_HCD_H_ diff --git a/drivers/usb/isp1760/isp1760-if.c b/drivers/usb/isp1760/isp1760-if.c index bc68bbab7fa1..241a00d75027 100644 --- a/drivers/usb/isp1760/isp1760-if.c +++ b/drivers/usb/isp1760/isp1760-if.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Glue code for the ISP1760 driver and bus * Currently there is support for diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 7fdb45fc976f..109f54f5b9aa 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the rest of the USB drivers # (the ones that don't fit into any other categories) diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index dfd54ea4808f..1c0ada75c35d 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -29,8 +29,6 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v0.0.13" #define DRIVER_AUTHOR "John Homppi" #define DRIVER_DESC "adutux (see www.ontrak.net)" diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c index 15d4e64d3b65..abec6e604a62 100644 --- a/drivers/usb/misc/chaoskey.c +++ b/drivers/usb/misc/chaoskey.c @@ -42,12 +42,10 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data, dev_err(&(usb_if)->dev, format, ## arg) /* Version Information */ -#define DRIVER_VERSION "v0.1" #define DRIVER_AUTHOR "Keith Packard, keithp@keithp.com" #define DRIVER_DESC "Altus Metrum ChaosKey driver" #define DRIVER_SHORT "chaoskey" -MODULE_VERSION(DRIVER_VERSION); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 9d8bb8dacdcd..63207c42acf6 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -20,7 +20,6 @@ #include #include -#define DRIVER_VERSION "v1.0" #define DRIVER_AUTHOR "Erik Rigtorp" #define DRIVER_DESC "Cypress USB Thermometer driver" diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 8291499d0581..424ff12f3b51 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -305,9 +305,9 @@ static int ftdi_elan_command_engine(struct usb_ftdi *ftdi); static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi); static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi) { - int result; if (ftdi->platform_dev.dev.parent) return -EBUSY; + ftdi_elan_get_kref(ftdi); ftdi->platform_data.potpg = 100; ftdi->platform_data.reset = NULL; @@ -324,8 +324,8 @@ static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi) request_module("u132_hcd"); dev_info(&ftdi->udev->dev, "registering '%s'\n", ftdi->platform_dev.name); - result = platform_device_register(&ftdi->platform_dev); - return result; + + return platform_device_register(&ftdi->platform_dev); } static void ftdi_elan_abandon_completions(struct usb_ftdi *ftdi) @@ -857,7 +857,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, target->actual = 0; target->non_null = (ed_length >> 15) & 0x0001; target->repeat_number = (ed_length >> 11) & 0x000F; - if (ed_type == 0x02) { + if (ed_type == 0x02 || ed_type == 0x03) { if (payload == 0 || target->abandoning > 0) { target->abandoning = 0; mutex_unlock(&ftdi->u132_lock); @@ -873,31 +873,6 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi, mutex_unlock(&ftdi->u132_lock); return b; } - } else if (ed_type == 0x03) { - if (payload == 0 || target->abandoning > 0) { - target->abandoning = 0; - mutex_unlock(&ftdi->u132_lock); - ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, - payload); - ftdi->received = 0; - ftdi->expected = 4; - ftdi->ed_found = 0; - return ftdi->response; - } else { - ftdi->expected = 4 + payload; - ftdi->ed_found = 1; - mutex_unlock(&ftdi->u132_lock); - return b; - } - } else if (ed_type == 0x01) { - target->abandoning = 0; - mutex_unlock(&ftdi->u132_lock); - ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response, - payload); - ftdi->received = 0; - ftdi->expected = 4; - ftdi->ed_found = 0; - return ftdi->response; } else { target->abandoning = 0; mutex_unlock(&ftdi->u132_lock); diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index 81fcbf024c65..39d8fedfaf3b 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -33,8 +33,6 @@ #define HEADER "P5 225 289 255 " #define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1) -/* version information */ -#define DRIVER_VERSION "0.6" #define DRIVER_SHORT "idmouse" #define DRIVER_AUTHOR "Florian 'Floe' Echtler " #define DRIVER_DESC "Siemens ID Mouse FingerTIP Sensor Driver" diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 7ca4c7e0ea0d..be5881303681 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -21,10 +21,8 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v0.4.0" #define DRIVER_AUTHOR "Christian Lucht " -#define DRIVER_DESC "USB IO-Warrior driver (Linux 2.6.x)" +#define DRIVER_DESC "USB IO-Warrior driver" #define USB_VENDOR_ID_CODEMERCS 1984 /* low speed iowarrior */ diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 9d9487c66f87..680bddb3ce05 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -112,7 +112,6 @@ static const struct usb_device_id ld_usb_table[] = { { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, ld_usb_table); -MODULE_VERSION("V0.14"); MODULE_AUTHOR("Michael Hund "); MODULE_DESCRIPTION("LD USB Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 0782ac6f5edf..5628f678ab59 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -88,8 +88,6 @@ #include -/* Version Information */ -#define DRIVER_VERSION "v0.96" #define DRIVER_AUTHOR "Juergen Stuber " #define DRIVER_DESC "LEGO USB Tower Driver" diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index 2142132a1f82..ddddd6387f66 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c @@ -178,6 +178,25 @@ static ssize_t hot_reset_store(struct device *dev, } static DEVICE_ATTR_WO(hot_reset); +static ssize_t warm_reset_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_device *hdev = interface_to_usbdev(intf); + struct lvs_rh *lvs = usb_get_intfdata(intf); + int ret; + + ret = lvs_rh_set_port_feature(hdev, lvs->portnum, + USB_PORT_FEAT_BH_PORT_RESET); + if (ret < 0) { + dev_err(dev, "can't issue warm reset %d\n", ret); + return ret; + } + + return count; +} +static DEVICE_ATTR_WO(warm_reset); + static ssize_t u2_timeout_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -274,13 +293,35 @@ free_desc: } static DEVICE_ATTR_WO(get_dev_desc); +static ssize_t enable_compliance_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct usb_interface *intf = to_usb_interface(dev); + struct usb_device *hdev = interface_to_usbdev(intf); + struct lvs_rh *lvs = usb_get_intfdata(intf); + int ret; + + ret = lvs_rh_set_port_feature(hdev, + lvs->portnum | USB_SS_PORT_LS_COMP_MOD << 3, + USB_PORT_FEAT_LINK_STATE); + if (ret < 0) { + dev_err(dev, "can't enable compliance mode %d\n", ret); + return ret; + } + + return count; +} +static DEVICE_ATTR_WO(enable_compliance); + static struct attribute *lvs_attributes[] = { &dev_attr_get_dev_desc.attr, &dev_attr_u1_timeout.attr, &dev_attr_u2_timeout.attr, &dev_attr_hot_reset.attr, + &dev_attr_warm_reset.attr, &dev_attr_u3_entry.attr, &dev_attr_u3_exit.attr, + &dev_attr_enable_compliance.attr, NULL }; diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index b106ce76997b..ddfebb144aaa 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c @@ -43,10 +43,6 @@ #include "rio500_usb.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v1.1" #define DRIVER_AUTHOR "Cesar Miquel " #define DRIVER_DESC "USB Rio 500 driver" diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 440d7fef58cc..30774e0aeadd 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -610,13 +610,11 @@ static int sisusb_write_memio_byte(struct sisusb_usb_data *sisusb, int type, u32 addr, u8 data) { struct sisusb_packet packet; - int ret; packet.header = (1 << (addr & 3)) | (type << 6); packet.address = addr & ~3; packet.data = data << ((addr & 3) << 3); - ret = sisusb_send_packet(sisusb, 10, &packet); - return ret; + return sisusb_send_packet(sisusb, 10, &packet); } static int sisusb_write_memio_word(struct sisusb_usb_data *sisusb, int type, @@ -1333,13 +1331,11 @@ static int sisusb_write_pci_config(struct sisusb_usb_data *sisusb, int regnum, u32 data) { struct sisusb_packet packet; - int ret; packet.header = 0x008f; packet.address = regnum | 0x10000; packet.data = data; - ret = sisusb_send_packet(sisusb, 10, &packet); - return ret; + return sisusb_send_packet(sisusb, 10, &packet); } static int sisusb_read_pci_config(struct sisusb_usb_data *sisusb, @@ -2982,14 +2978,11 @@ err_out: static long sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { - long retval; - switch (cmd) { case SISUSB_GET_CONFIG_SIZE: case SISUSB_GET_CONFIG: case SISUSB_COMMAND: - retval = sisusb_ioctl(f, cmd, arg); - return retval; + return sisusb_ioctl(f, cmd, arg); default: return -ENOIOCTLCMD; diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 9795457723d8..1862ed15ce28 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -25,8 +25,6 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v1.1" #define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org" #define DRIVER_DESC "PlayStation 2 Trance Vibrator driver" diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index 91f66d68bcb7..135c91c434bf 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -114,7 +114,6 @@ #define DRIVER_NAME "usb251xb" #define DRIVER_DESC "Microchip USB 2.0 Hi-Speed Hub Controller" -#define DRIVER_VERSION "1.0" struct usb251xb { struct device *dev; diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 388fae6373db..3f6a28045b53 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -330,7 +330,7 @@ static struct attribute *dev_attrs[] = { NULL }; -static struct attribute_group dev_attr_grp = { +static const struct attribute_group dev_attr_grp = { .attrs = dev_attrs, }; diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index eee82ca55b7b..b3fc602b2e24 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -202,12 +202,13 @@ found: return tmp; } - if (in) { + if (in) dev->in_pipe = usb_rcvbulkpipe(udev, in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + if (out) dev->out_pipe = usb_sndbulkpipe(udev, out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); - } + if (iso_in) { dev->iso_in = &iso_in->desc; dev->in_iso_pipe = usb_rcvisocpipe(udev, @@ -1964,6 +1965,9 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param, int status = 0; struct urb *urbs[param->sglen]; + if (!param->sglen || param->iterations > UINT_MAX / param->sglen) + return -EINVAL; + memset(&context, 0, sizeof(context)); context.count = param->iterations * param->sglen; context.dev = dev; @@ -2087,6 +2091,8 @@ usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param) if (param->iterations <= 0) return -EINVAL; + if (param->sglen > MAX_SGLEN) + return -EINVAL; /* * Just a bunch of test cases that every HCD is expected to handle. * diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 5947373700a1..8a13b2fcf3e1 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -52,10 +52,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v0.6" #define DRIVER_AUTHOR "Thomas M. Sailer, t.sailer@alumni.ethz.ch" #define DRIVER_DESC "USB Parport Cable driver for Cables using the Lucent Technologies USS720 Chip" @@ -816,8 +812,7 @@ static int __init uss720_init(void) if (retval) goto out; - printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" - DRIVER_DESC "\n"); + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n"); printk(KERN_INFO KBUILD_MODNAME ": NOTE: this is a special purpose " "driver to allow nonstandard\n"); printk(KERN_INFO KBUILD_MODNAME ": protocols (eg. bitbang) over " diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index b6d8bf475c92..f6ae753ab99b 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * The USB Monitor, inspired by Dave Harding's USBMon. * diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index 5bdf73a57498..98ab0cc473d6 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * The USB Monitor, inspired by Dave Harding's USBMon. * diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 19c416d69eb9..f5e1bb5e5217 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * The USB Monitor, inspired by Dave Harding's USBMon. * diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index df9a4df342c7..aa64efaba366 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * The USB Monitor, inspired by Dave Harding's USBMon. * diff --git a/drivers/usb/mtu3/Makefile b/drivers/usb/mtu3/Makefile index 60e0fff7a847..4a9715812bf9 100644 --- a/drivers/usb/mtu3/Makefile +++ b/drivers/usb/mtu3/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_USB_MTU3_DEBUG) += -DDEBUG diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 7b6dc23d77e9..b26fffc58446 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -288,6 +288,7 @@ static inline struct ssusb_mtk *dev_to_ssusb(struct device *dev) * MTU3_U3_IP_SLOT_DEFAULT for U3 IP * @may_wakeup: means device's remote wakeup is enabled * @is_self_powered: is reported in device status and the config descriptor + * @delayed_status: true when function drivers ask for delayed status * @ep0_req: dummy request used while handling standard USB requests * for GET_STATUS and SET_SEL * @setup_buf: ep0 response buffer for GET_STATUS and SET_SEL requests @@ -327,6 +328,7 @@ struct mtu3 { unsigned u1_enable:1; unsigned u2_enable:1; unsigned is_u3_ip:1; + unsigned delayed_status:1; u8 address; u8 test_mode_nr; diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 11a0d3b84c5e..560256115b23 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -322,23 +322,65 @@ static const struct file_operations ssusb_mode_fops = { .release = single_release, }; +static int ssusb_vbus_show(struct seq_file *sf, void *unused) +{ + struct ssusb_mtk *ssusb = sf->private; + struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; + + seq_printf(sf, "vbus state: %s\n(echo on/off)\n", + regulator_is_enabled(otg_sx->vbus) ? "on" : "off"); + + return 0; +} + +static int ssusb_vbus_open(struct inode *inode, struct file *file) +{ + return single_open(file, ssusb_vbus_show, inode->i_private); +} + +static ssize_t ssusb_vbus_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *sf = file->private_data; + struct ssusb_mtk *ssusb = sf->private; + struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; + char buf[16]; + bool enable; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (kstrtobool(buf, &enable)) { + dev_err(ssusb->dev, "wrong setting\n"); + return -EINVAL; + } + + ssusb_set_vbus(otg_sx, enable); + + return count; +} + +static const struct file_operations ssusb_vbus_fops = { + .open = ssusb_vbus_open, + .write = ssusb_vbus_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static void ssusb_debugfs_init(struct ssusb_mtk *ssusb) { struct dentry *root; - struct dentry *file; root = debugfs_create_dir(dev_name(ssusb->dev), usb_debug_root); - if (IS_ERR_OR_NULL(root)) { - if (!root) - dev_err(ssusb->dev, "create debugfs root failed\n"); + if (!root) { + dev_err(ssusb->dev, "create debugfs root failed\n"); return; } ssusb->dbgfs_root = root; - file = debugfs_create_file("mode", S_IRUGO | S_IWUSR, root, - ssusb, &ssusb_mode_fops); - if (!file) - dev_dbg(ssusb->dev, "create debugfs mode failed\n"); + debugfs_create_file("mode", 0644, root, ssusb, &ssusb_mode_fops); + debugfs_create_file("vbus", 0644, root, ssusb, &ssusb_vbus_fops); } static void ssusb_debugfs_exit(struct ssusb_mtk *ssusb) diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c index 9dd2441b4fa1..434fca58143c 100644 --- a/drivers/usb/mtu3/mtu3_gadget.c +++ b/drivers/usb/mtu3/mtu3_gadget.c @@ -663,6 +663,7 @@ int mtu3_gadget_setup(struct mtu3 *mtu) mtu->g.sg_supported = 0; mtu->g.name = MTU3_DRIVER_NAME; mtu->is_active = 0; + mtu->delayed_status = false; mtu3_gadget_init_eps(mtu); @@ -727,4 +728,7 @@ void mtu3_gadget_reset(struct mtu3 *mtu) mtu->address = 0; mtu->ep0_state = MU3D_EP0_STATE_SETUP; mtu->may_wakeup = 0; + mtu->u1_enable = 0; + mtu->u2_enable = 0; + mtu->delayed_status = false; } diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c b/drivers/usb/mtu3/mtu3_gadget_ep0.c index 2d7427b48775..958d74dd2b78 100644 --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c @@ -16,6 +16,8 @@ * */ +#include + #include "mtu3.h" /* ep0 is always mtu3->in_eps[0] */ @@ -150,6 +152,7 @@ static void ep0_stall_set(struct mtu3_ep *mep0, bool set, u32 pktrdy) csr = (csr & ~EP0_SENDSTALL) | EP0_SENTSTALL; mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr); + mtu->delayed_status = false; mtu->ep0_state = MU3D_EP0_STATE_SETUP; dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n", @@ -656,6 +659,9 @@ stall: finish: if (mtu->test_mode) { ; /* nothing to do */ + } else if (handled == USB_GADGET_DELAYED_STATUS) { + /* handle the delay STATUS phase till receive ep_queue on ep0 */ + mtu->delayed_status = true; } else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */ mtu3_writel(mbase, U3D_EP0CSR, @@ -775,9 +781,6 @@ static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq) dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__, mep->name, decode_ep0_state(mtu), mreq->request.length); - if (!list_empty(&mep->req_list)) - return -EBUSY; - switch (mtu->ep0_state) { case MU3D_EP0_STATE_SETUP: case MU3D_EP0_STATE_RX: /* control-OUT data */ @@ -789,6 +792,20 @@ static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq) return -EINVAL; } + if (mtu->delayed_status) { + u32 csr; + + mtu->delayed_status = false; + csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS; + csr |= EP0_SETUPPKTRDY | EP0_DATAEND; + mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr); + /* needn't giveback the request for handling delay STATUS */ + return 0; + } + + if (!list_empty(&mep->req_list)) + return -EBUSY; + list_add_tail(&mreq->list, &mep->req_list); /* sequence #1, IN ... start writing the data */ diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c index cd4d01087855..e42d308b8dc2 100644 --- a/drivers/usb/mtu3/mtu3_host.c +++ b/drivers/usb/mtu3/mtu3_host.c @@ -258,8 +258,8 @@ int ssusb_host_init(struct ssusb_mtk *ssusb, struct device_node *parent_dn) ret = of_platform_populate(parent_dn, NULL, NULL, parent_dev); if (ret) { - dev_dbg(parent_dev, "failed to create child devices at %s\n", - parent_dn->full_name); + dev_dbg(parent_dev, "failed to create child devices at %pOF\n", + parent_dn); return ret; } diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h index 212367295276..06b29664470f 100644 --- a/drivers/usb/mtu3/mtu3_hw_regs.h +++ b/drivers/usb/mtu3/mtu3_hw_regs.h @@ -462,10 +462,12 @@ #define SSUSB_U3_PORT_DIS BIT(0) /* U3D_SSUSB_U2_CTRL_0P */ +#define SSUSB_U2_PORT_VBUSVALID BIT(9) #define SSUSB_U2_PORT_OTG_SEL BIT(7) -#define SSUSB_U2_PORT_HOST_SEL BIT(2) +#define SSUSB_U2_PORT_HOST BIT(2) #define SSUSB_U2_PORT_PDN BIT(1) #define SSUSB_U2_PORT_DIS BIT(0) +#define SSUSB_U2_PORT_HOST_SEL (SSUSB_U2_PORT_VBUSVALID | SSUSB_U2_PORT_HOST) /* U3D_SSUSB_DEV_RST_CTRL */ #define SSUSB_DEV_SW_RST BIT(0) diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index 0d3ebb353e08..088e3e685c4f 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -500,6 +500,7 @@ static const struct dev_pm_ops mtu3_pm_ops = { static const struct of_device_id mtu3_of_match[] = { {.compatible = "mediatek,mt8173-mtu3",}, + {.compatible = "mediatek,mtu3",}, {}, }; diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index 689d42aba8a9..79d4d5439164 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # for USB OTG silicon based on Mentor Graphics INVENTRA designs # diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h index 9bb7c5e45c85..16dd1ed44bb5 100644 --- a/drivers/usb/musb/cppi_dma.h +++ b/drivers/usb/musb/cppi_dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2005-2006 by Texas Instruments */ #ifndef _CPPI_DMA_H_ diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 87cbd56cc761..ff5a1a8989d5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -906,7 +906,7 @@ b_host: */ if (int_usb & MUSB_INTR_RESET) { handled = IRQ_HANDLED; - if (devctl & MUSB_DEVCTL_HM) { + if (is_host_active(musb)) { /* * When BABBLE happens what we can depends on which * platform MUSB is running, because some platforms @@ -916,9 +916,7 @@ b_host: * drop the session. */ dev_err(musb->controller, "Babble\n"); - - if (is_host_active(musb)) - musb_recover_from_babble(musb); + musb_recover_from_babble(musb); } else { musb_dbg(musb, "BUS RESET as %s", usb_otg_state_string(musb->xceiv->otg->state)); @@ -1156,8 +1154,8 @@ static struct musb_fifo_cfg mode_2_cfg[] = { { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, }, -{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256, }, -{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256, }, +{ .hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 960, }, +{ .hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 1024, }, }; /* mode 3 - fits in 4KB */ @@ -1861,22 +1859,22 @@ static void musb_pm_runtime_check_session(struct musb *musb) MUSB_DEVCTL_HR; switch (devctl & ~s) { case MUSB_QUIRK_B_INVALID_VBUS_91: - if (musb->quirk_retries--) { + if (musb->quirk_retries && !musb->flush_irq_work) { musb_dbg(musb, "Poll devctl on invalid vbus, assume no session"); schedule_delayed_work(&musb->irq_work, msecs_to_jiffies(1000)); - + musb->quirk_retries--; return; } /* fall through */ case MUSB_QUIRK_A_DISCONNECT_19: - if (musb->quirk_retries--) { + if (musb->quirk_retries && !musb->flush_irq_work) { musb_dbg(musb, "Poll devctl on possible host mode disconnect"); schedule_delayed_work(&musb->irq_work, msecs_to_jiffies(1000)); - + musb->quirk_retries--; return; } if (!musb->session) @@ -2671,11 +2669,25 @@ static int musb_suspend(struct device *dev) { struct musb *musb = dev_to_musb(dev); unsigned long flags; + int ret; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } musb_platform_disable(musb); musb_disable_interrupts(musb); + + musb->flush_irq_work = true; + while (flush_delayed_work(&musb->irq_work)) + ; + musb->flush_irq_work = false; + if (!(musb->io.quirks & MUSB_PRESERVE_SESSION)) musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + WARN_ON(!list_empty(&musb->pending_list)); spin_lock_irqsave(&musb->lock, flags); @@ -2721,14 +2733,6 @@ static int musb_resume(struct device *dev) if ((devctl & mask) != (musb->context.devctl & mask)) musb->port1_status = 0; - /* - * The USB HUB code expects the device to be in RPM_ACTIVE once it came - * out of suspend - */ - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - musb_start(musb); spin_lock_irqsave(&musb->lock, flags); @@ -2738,6 +2742,9 @@ static int musb_resume(struct device *dev) error); spin_unlock_irqrestore(&musb->lock, flags); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return 0; } diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 9f22c5b8ce37..20f4614178d9 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -428,6 +428,8 @@ struct musb { unsigned test_mode:1; unsigned softconnect:1; + unsigned flush_irq_work:1; + u8 address; u8 test_mode_nr; u16 ackpend; /* ep0 */ @@ -465,6 +467,30 @@ static inline struct musb *gadget_to_musb(struct usb_gadget *g) return container_of(g, struct musb, g); } +static inline char *musb_ep_xfertype_string(u8 type) +{ + char *s; + + switch (type) { + case USB_ENDPOINT_XFER_CONTROL: + s = "ctrl"; + break; + case USB_ENDPOINT_XFER_ISOC: + s = "iso"; + break; + case USB_ENDPOINT_XFER_BULK: + s = "bulk"; + break; + case USB_ENDPOINT_XFER_INT: + s = "int"; + break; + default: + s = ""; + break; + } + return s; +} + #ifdef CONFIG_BLACKFIN static inline int musb_read_fifosize(struct musb *musb, struct musb_hw_ep *hw_ep, u8 epnum) diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index ba255280a624..1ec0a4947b6b 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -26,15 +26,28 @@ #define MUSB_DMA_NUM_CHANNELS 15 +#define DA8XX_USB_MODE 0x10 +#define DA8XX_USB_AUTOREQ 0x14 +#define DA8XX_USB_TEARDOWN 0x1c + +#define DA8XX_DMA_NUM_CHANNELS 4 + struct cppi41_dma_controller { struct dma_controller controller; - struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS]; - struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS]; + struct cppi41_dma_channel *rx_channel; + struct cppi41_dma_channel *tx_channel; struct hrtimer early_tx; struct list_head early_tx_list; u32 rx_mode; u32 tx_mode; u32 auto_req; + + u32 tdown_reg; + u32 autoreq_reg; + + void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel, + unsigned int mode); + u8 num_channels; }; static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel) @@ -349,6 +362,32 @@ static void cppi41_set_dma_mode(struct cppi41_dma_channel *cppi41_channel, } } +static void da8xx_set_dma_mode(struct cppi41_dma_channel *cppi41_channel, + unsigned int mode) +{ + struct cppi41_dma_controller *controller = cppi41_channel->controller; + struct musb *musb = controller->controller.musb; + unsigned int shift; + u32 port; + u32 new_mode; + u32 old_mode; + + old_mode = controller->tx_mode; + port = cppi41_channel->port_num; + + shift = (port - 1) * 4; + if (!cppi41_channel->is_tx) + shift += 16; + new_mode = old_mode & ~(3 << shift); + new_mode |= mode << shift; + + if (new_mode == old_mode) + return; + controller->tx_mode = new_mode; + musb_writel(musb->ctrl_base, DA8XX_USB_MODE, new_mode); +} + + static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel, unsigned mode) { @@ -364,8 +403,8 @@ static void cppi41_set_autoreq_mode(struct cppi41_dma_channel *cppi41_channel, if (new_mode == old_mode) return; controller->auto_req = new_mode; - musb_writel(controller->controller.musb->ctrl_base, USB_CTRL_AUTOREQ, - new_mode); + musb_writel(controller->controller.musb->ctrl_base, + controller->autoreq_reg, new_mode); } static bool cppi41_configure_channel(struct dma_channel *channel, @@ -373,6 +412,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, dma_addr_t dma_addr, u32 len) { struct cppi41_dma_channel *cppi41_channel = channel->private_data; + struct cppi41_dma_controller *controller = cppi41_channel->controller; struct dma_chan *dc = cppi41_channel->dc; struct dma_async_tx_descriptor *dma_desc; enum dma_transfer_direction direction; @@ -398,7 +438,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, musb_writel(musb->ctrl_base, RNDIS_REG(cppi41_channel->port_num), len); /* gen rndis */ - cppi41_set_dma_mode(cppi41_channel, + controller->set_dma_mode(cppi41_channel, EP_MODE_DMA_GEN_RNDIS); /* auto req */ @@ -407,14 +447,15 @@ static bool cppi41_configure_channel(struct dma_channel *channel, } else { musb_writel(musb->ctrl_base, RNDIS_REG(cppi41_channel->port_num), 0); - cppi41_set_dma_mode(cppi41_channel, + controller->set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); } } else { /* fallback mode */ - cppi41_set_dma_mode(cppi41_channel, EP_MODE_DMA_TRANSPARENT); + controller->set_dma_mode(cppi41_channel, + EP_MODE_DMA_TRANSPARENT); cppi41_set_autoreq_mode(cppi41_channel, EP_MODE_AUTOREQ_NONE); len = min_t(u32, packet_sz, len); } @@ -445,7 +486,7 @@ static struct dma_channel *cppi41_dma_channel_allocate(struct dma_controller *c, struct cppi41_dma_channel *cppi41_channel = NULL; u8 ch_num = hw_ep->epnum - 1; - if (ch_num >= MUSB_DMA_NUM_CHANNELS) + if (ch_num >= controller->num_channels) return NULL; if (is_tx) @@ -581,12 +622,13 @@ static int cppi41_dma_channel_abort(struct dma_channel *channel) do { if (is_tx) - musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); + musb_writel(musb->ctrl_base, controller->tdown_reg, + tdbit); ret = dmaengine_terminate_all(cppi41_channel->dc); } while (ret == -EAGAIN); if (is_tx) { - musb_writel(musb->ctrl_base, USB_TDOWN, tdbit); + musb_writel(musb->ctrl_base, controller->tdown_reg, tdbit); csr = musb_readw(epio, MUSB_TXCSR); if (csr & MUSB_TXCSR_TXPKTRDY) { @@ -604,7 +646,7 @@ static void cppi41_release_all_dma_chans(struct cppi41_dma_controller *ctrl) struct dma_chan *dc; int i; - for (i = 0; i < MUSB_DMA_NUM_CHANNELS; i++) { + for (i = 0; i < ctrl->num_channels; i++) { dc = ctrl->tx_channel[i].dc; if (dc) dma_release_channel(dc); @@ -656,7 +698,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) goto err; ret = -EINVAL; - if (port > MUSB_DMA_NUM_CHANNELS || !port) + if (port > controller->num_channels || !port) goto err; if (is_tx) cppi41_channel = &controller->tx_channel[port - 1]; @@ -697,6 +739,8 @@ void cppi41_dma_controller_destroy(struct dma_controller *c) hrtimer_cancel(&controller->early_tx); cppi41_dma_controller_stop(controller); + kfree(controller->rx_channel); + kfree(controller->tx_channel); kfree(controller); } EXPORT_SYMBOL_GPL(cppi41_dma_controller_destroy); @@ -705,6 +749,7 @@ struct dma_controller * cppi41_dma_controller_create(struct musb *musb, void __iomem *base) { struct cppi41_dma_controller *controller; + int channel_size; int ret = 0; if (!musb->controller->parent->of_node) { @@ -727,12 +772,37 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base) controller->controller.is_compatible = cppi41_is_compatible; controller->controller.musb = musb; + if (musb->io.quirks & MUSB_DA8XX) { + controller->tdown_reg = DA8XX_USB_TEARDOWN; + controller->autoreq_reg = DA8XX_USB_AUTOREQ; + controller->set_dma_mode = da8xx_set_dma_mode; + controller->num_channels = DA8XX_DMA_NUM_CHANNELS; + } else { + controller->tdown_reg = USB_TDOWN; + controller->autoreq_reg = USB_CTRL_AUTOREQ; + controller->set_dma_mode = cppi41_set_dma_mode; + controller->num_channels = MUSB_DMA_NUM_CHANNELS; + } + + channel_size = controller->num_channels * + sizeof(struct cppi41_dma_channel); + controller->rx_channel = kzalloc(channel_size, GFP_KERNEL); + if (!controller->rx_channel) + goto rx_channel_alloc_fail; + controller->tx_channel = kzalloc(channel_size, GFP_KERNEL); + if (!controller->tx_channel) + goto tx_channel_alloc_fail; + ret = cppi41_dma_controller_start(controller); if (ret) goto plat_get_fail; return &controller->controller; plat_get_fail: + kfree(controller->tx_channel); +tx_channel_alloc_fail: + kfree(controller->rx_channel); +rx_channel_alloc_fail: kfree(controller); kzalloc_fail: if (ret == -EPROBE_DEFER) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index bc6a9be2ccc5..f6b526606ad1 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -1015,13 +1015,20 @@ static int dsps_suspend(struct device *dev) const struct dsps_musb_wrapper *wrp = glue->wrp; struct musb *musb = platform_get_drvdata(glue->musb); void __iomem *mbase; - - del_timer_sync(&glue->timer); + int ret; if (!musb) /* This can happen if the musb device is in -EPROBE_DEFER */ return 0; + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + return ret; + } + + del_timer_sync(&glue->timer); + mbase = musb->ctrl_base; glue->context.control = musb_readl(mbase, wrp->control); glue->context.epintr = musb_readl(mbase, wrp->epintr_set); @@ -1060,6 +1067,8 @@ static int dsps_resume(struct device *dev) musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) dsps_mod_timer(glue, -1); + pm_runtime_put(dev); + return 0; } #endif diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 1acc4864f9f6..bc6d1717c9ec 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1105,11 +1105,7 @@ static int musb_gadget_enable(struct usb_ep *ep, pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n", musb_driver_name, musb_ep->end_point.name, - ({ char *s; switch (musb_ep->type) { - case USB_ENDPOINT_XFER_BULK: s = "bulk"; break; - case USB_ENDPOINT_XFER_INT: s = "int"; break; - default: s = "iso"; break; - } s; }), + musb_ep_xfertype_string(musb_ep->type), musb_ep->is_in ? "IN" : "OUT", musb_ep->dma ? "dma, " : "", musb_ep->packet_sz); diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3344ffd5bb13..b17450a59882 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2152,6 +2152,10 @@ static int musb_schedule( (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4; goto success; } else if (best_end < 0) { + dev_err(musb->controller, + "%s hwep alloc failed for %dx%d\n", + musb_ep_xfertype_string(qh->type), + qh->hb_mult, qh->maxpacket); return -ENOSPC; } @@ -2244,6 +2248,10 @@ static int musb_urb_enqueue( ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx) || (usb_pipeout(urb->pipe) && musb->hb_iso_tx); if (!ok) { + dev_err(musb->controller, + "high bandwidth %s (%dx%d) not supported\n", + musb_ep_xfertype_string(qh->type), + qh->hb_mult, qh->maxpacket & 0x7ff); ret = -EMSGSIZE; goto done; } diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index c9a09b5bb6e5..dc353e24d53c 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -297,6 +297,8 @@ static int sunxi_musb_exit(struct musb *musb) if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags)) sunxi_sram_release(musb->controller->parent); + devm_usb_put_phy(glue->dev, glue->xceiv); + return 0; } diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index e7c9ca8cafb0..0c40ccc90631 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for physical layer USB drivers # diff --git a/drivers/usb/phy/phy-am335x-control.h b/drivers/usb/phy/phy-am335x-control.h index e86b3165d69d..cd4acfc6e360 100644 --- a/drivers/usb/phy/phy-am335x-control.h +++ b/drivers/usb/phy/phy-am335x-control.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _AM335x_PHY_CONTROL_H_ #define _AM335x_PHY_CONTROL_H_ diff --git a/drivers/usb/phy/phy-generic.h b/drivers/usb/phy/phy-generic.h index 0d0eadd54ed9..97289627561d 100644 --- a/drivers/usb/phy/phy-generic.h +++ b/drivers/usb/phy/phy-generic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PHY_GENERIC_H_ #define _PHY_GENERIC_H_ diff --git a/drivers/usb/phy/phy-isp1301-omap.c b/drivers/usb/phy/phy-isp1301-omap.c index 042c5a8fd423..c6052c814bcc 100644 --- a/drivers/usb/phy/phy-isp1301-omap.c +++ b/drivers/usb/phy/phy-isp1301-omap.c @@ -96,7 +96,7 @@ struct isp1301 { #if IS_REACHABLE(CONFIG_TPS65010) -#include +#include #else diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 697a741a0cb1..0e315694adc9 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c @@ -29,10 +29,8 @@ #include "phy-mv-usb.h" #define DRIVER_DESC "Marvell USB OTG transceiver driver" -#define DRIVER_VERSION "Jan 20, 2010" MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); static const char driver_name[] = "mv-otg"; @@ -650,7 +648,7 @@ static struct attribute *inputs_attrs[] = { NULL, }; -static struct attribute_group inputs_attr_group = { +static const struct attribute_group inputs_attr_group = { .name = "inputs", .attrs = inputs_attrs, }; diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c index b6a83a5cbad3..679afeaaa9a8 100644 --- a/drivers/usb/phy/phy-qcom-8x16-usb.c +++ b/drivers/usb/phy/phy-qcom-8x16-usb.c @@ -270,12 +270,9 @@ static int phy_8x16_probe(struct platform_device *pdev) platform_set_drvdata(pdev, qphy); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EINVAL; - - qphy->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!qphy->regs) - return -ENOMEM; + qphy->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(qphy->regs)) + return PTR_ERR(qphy->regs); phy = &qphy->phy; phy->dev = &pdev->dev; diff --git a/drivers/usb/phy/phy-tahvo.c b/drivers/usb/phy/phy-tahvo.c index a31c8682e998..8babd318c0ed 100644 --- a/drivers/usb/phy/phy-tahvo.c +++ b/drivers/usb/phy/phy-tahvo.c @@ -326,7 +326,7 @@ static struct attribute *tahvo_attributes[] = { NULL }; -static struct attribute_group tahvo_attr_group = { +static const struct attribute_group tahvo_attr_group = { .attrs = tahvo_attributes, }; diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index 5fe4a5704bde..ccc2bf5274b4 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -329,6 +329,14 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) unsigned long val; void __iomem *base = phy->regs; + /* + * The USB driver may have already initiated the phy clock + * disable so wait to see if the clock turns off and if not + * then proceed with gating the clock. + */ + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) == 0) + return; + if (phy->is_legacy_phy) { val = readl(base + USB_SUSP_CTRL); val |= USB_SUSP_SET; @@ -351,6 +359,15 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) unsigned long val; void __iomem *base = phy->regs; + /* + * The USB driver may have already initiated the phy clock + * enable so wait to see if the clock turns on and if not + * then proceed with ungating the clock. + */ + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID) == 0) + return; + if (phy->is_legacy_phy) { val = readl(base + USB_SUSP_CTRL); val |= USB_SUSP_CLR; diff --git a/drivers/usb/phy/phy-twl6030-usb.c b/drivers/usb/phy/phy-twl6030-usb.c index 628b600b02b1..b5dc077ed7d3 100644 --- a/drivers/usb/phy/phy-twl6030-usb.c +++ b/drivers/usb/phy/phy-twl6030-usb.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 032f5afaad4b..89f4ac4cd93e 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -18,6 +18,18 @@ #include +/* Default current range by charger type. */ +#define DEFAULT_SDP_CUR_MIN 2 +#define DEFAULT_SDP_CUR_MAX 500 +#define DEFAULT_SDP_CUR_MIN_SS 150 +#define DEFAULT_SDP_CUR_MAX_SS 900 +#define DEFAULT_DCP_CUR_MIN 500 +#define DEFAULT_DCP_CUR_MAX 5000 +#define DEFAULT_CDP_CUR_MIN 1500 +#define DEFAULT_CDP_CUR_MAX 5000 +#define DEFAULT_ACA_CUR_MIN 1500 +#define DEFAULT_ACA_CUR_MAX 5000 + static LIST_HEAD(phy_list); static LIST_HEAD(phy_bind_list); static DEFINE_SPINLOCK(phy_lock); @@ -77,6 +89,221 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) return ERR_PTR(-EPROBE_DEFER); } +static void usb_phy_set_default_current(struct usb_phy *usb_phy) +{ + usb_phy->chg_cur.sdp_min = DEFAULT_SDP_CUR_MIN; + usb_phy->chg_cur.sdp_max = DEFAULT_SDP_CUR_MAX; + usb_phy->chg_cur.dcp_min = DEFAULT_DCP_CUR_MIN; + usb_phy->chg_cur.dcp_max = DEFAULT_DCP_CUR_MAX; + usb_phy->chg_cur.cdp_min = DEFAULT_CDP_CUR_MIN; + usb_phy->chg_cur.cdp_max = DEFAULT_CDP_CUR_MAX; + usb_phy->chg_cur.aca_min = DEFAULT_ACA_CUR_MIN; + usb_phy->chg_cur.aca_max = DEFAULT_ACA_CUR_MAX; +} + +/** + * usb_phy_notify_charger_work - notify the USB charger state + * @work - the charger work to notify the USB charger state + * + * This work can be issued when USB charger state has been changed or + * USB charger current has been changed, then we can notify the current + * what can be drawn to power user and the charger state to userspace. + * + * If we get the charger type from extcon subsystem, we can notify the + * charger state to power user automatically by usb_phy_get_charger_type() + * issuing from extcon subsystem. + * + * If we get the charger type from ->charger_detect() instead of extcon + * subsystem, the usb phy driver should issue usb_phy_set_charger_state() + * to set charger state when the charger state has been changed. + */ +static void usb_phy_notify_charger_work(struct work_struct *work) +{ + struct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work); + char uchger_state[50] = { 0 }; + char *envp[] = { uchger_state, NULL }; + unsigned int min, max; + + switch (usb_phy->chg_state) { + case USB_CHARGER_PRESENT: + usb_phy_get_charger_current(usb_phy, &min, &max); + + atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy); + snprintf(uchger_state, ARRAY_SIZE(uchger_state), + "USB_CHARGER_STATE=%s", "USB_CHARGER_PRESENT"); + break; + case USB_CHARGER_ABSENT: + usb_phy_set_default_current(usb_phy); + + atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy); + snprintf(uchger_state, ARRAY_SIZE(uchger_state), + "USB_CHARGER_STATE=%s", "USB_CHARGER_ABSENT"); + break; + default: + dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n", + usb_phy->chg_state); + return; + } + + kobject_uevent_env(&usb_phy->dev->kobj, KOBJ_CHANGE, envp); +} + +static void __usb_phy_get_charger_type(struct usb_phy *usb_phy) +{ + if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_SDP) > 0) { + usb_phy->chg_type = SDP_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_CDP) > 0) { + usb_phy->chg_type = CDP_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_DCP) > 0) { + usb_phy->chg_type = DCP_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else if (extcon_get_state(usb_phy->edev, EXTCON_CHG_USB_ACA) > 0) { + usb_phy->chg_type = ACA_TYPE; + usb_phy->chg_state = USB_CHARGER_PRESENT; + } else { + usb_phy->chg_type = UNKNOWN_TYPE; + usb_phy->chg_state = USB_CHARGER_ABSENT; + } + + schedule_work(&usb_phy->chg_work); +} + +/** + * usb_phy_get_charger_type - get charger type from extcon subsystem + * @nb -the notifier block to determine charger type + * @state - the cable state + * @data - private data + * + * Determin the charger type from extcon subsystem which also means the + * charger state has been chaned, then we should notify this event. + */ +static int usb_phy_get_charger_type(struct notifier_block *nb, + unsigned long state, void *data) +{ + struct usb_phy *usb_phy = container_of(nb, struct usb_phy, type_nb); + + __usb_phy_get_charger_type(usb_phy); + return NOTIFY_OK; +} + +/** + * usb_phy_set_charger_current - set the USB charger current + * @usb_phy - the USB phy to be used + * @mA - the current need to be set + * + * Usually we only change the charger default current when USB finished the + * enumeration as one SDP charger. As one SDP charger, usb_phy_set_power() + * will issue this function to change charger current when after setting USB + * configuration, or suspend/resume USB. For other type charger, we should + * use the default charger current and we do not suggest to issue this function + * to change the charger current. + * + * When USB charger current has been changed, we need to notify the power users. + */ +void usb_phy_set_charger_current(struct usb_phy *usb_phy, unsigned int mA) +{ + switch (usb_phy->chg_type) { + case SDP_TYPE: + if (usb_phy->chg_cur.sdp_max == mA) + return; + + usb_phy->chg_cur.sdp_max = (mA > DEFAULT_SDP_CUR_MAX_SS) ? + DEFAULT_SDP_CUR_MAX_SS : mA; + break; + case DCP_TYPE: + if (usb_phy->chg_cur.dcp_max == mA) + return; + + usb_phy->chg_cur.dcp_max = (mA > DEFAULT_DCP_CUR_MAX) ? + DEFAULT_DCP_CUR_MAX : mA; + break; + case CDP_TYPE: + if (usb_phy->chg_cur.cdp_max == mA) + return; + + usb_phy->chg_cur.cdp_max = (mA > DEFAULT_CDP_CUR_MAX) ? + DEFAULT_CDP_CUR_MAX : mA; + break; + case ACA_TYPE: + if (usb_phy->chg_cur.aca_max == mA) + return; + + usb_phy->chg_cur.aca_max = (mA > DEFAULT_ACA_CUR_MAX) ? + DEFAULT_ACA_CUR_MAX : mA; + break; + default: + return; + } + + schedule_work(&usb_phy->chg_work); +} +EXPORT_SYMBOL_GPL(usb_phy_set_charger_current); + +/** + * usb_phy_get_charger_current - get the USB charger current + * @usb_phy - the USB phy to be used + * @min - the minimum current + * @max - the maximum current + * + * Usually we will notify the maximum current to power user, but for some + * special case, power user also need the minimum current value. Then the + * power user can issue this function to get the suitable current. + */ +void usb_phy_get_charger_current(struct usb_phy *usb_phy, + unsigned int *min, unsigned int *max) +{ + switch (usb_phy->chg_type) { + case SDP_TYPE: + *min = usb_phy->chg_cur.sdp_min; + *max = usb_phy->chg_cur.sdp_max; + break; + case DCP_TYPE: + *min = usb_phy->chg_cur.dcp_min; + *max = usb_phy->chg_cur.dcp_max; + break; + case CDP_TYPE: + *min = usb_phy->chg_cur.cdp_min; + *max = usb_phy->chg_cur.cdp_max; + break; + case ACA_TYPE: + *min = usb_phy->chg_cur.aca_min; + *max = usb_phy->chg_cur.aca_max; + break; + default: + *min = 0; + *max = 0; + break; + } +} +EXPORT_SYMBOL_GPL(usb_phy_get_charger_current); + +/** + * usb_phy_set_charger_state - set the USB charger state + * @usb_phy - the USB phy to be used + * @state - the new state need to be set for charger + * + * The usb phy driver can issue this function when the usb phy driver + * detected the charger state has been changed, in this case the charger + * type should be get from ->charger_detect(). + */ +void usb_phy_set_charger_state(struct usb_phy *usb_phy, + enum usb_charger_state state) +{ + if (usb_phy->chg_state == state || !usb_phy->charger_detect) + return; + + usb_phy->chg_state = state; + if (usb_phy->chg_state == USB_CHARGER_PRESENT) + usb_phy->chg_type = usb_phy->charger_detect(usb_phy); + else + usb_phy->chg_type = UNKNOWN_TYPE; + + schedule_work(&usb_phy->chg_work); +} +EXPORT_SYMBOL_GPL(usb_phy_set_charger_state); + static void devm_usb_phy_release(struct device *dev, void *res) { struct usb_phy *phy = *(struct usb_phy **)res; @@ -124,6 +351,44 @@ static int usb_add_extcon(struct usb_phy *x) "register VBUS notifier failed\n"); return ret; } + } else { + x->type_nb.notifier_call = usb_phy_get_charger_type; + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_SDP, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB SDP failed.\n"); + return ret; + } + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_CDP, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB CDP failed.\n"); + return ret; + } + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_DCP, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB DCP failed.\n"); + return ret; + } + + ret = devm_extcon_register_notifier(x->dev, x->edev, + EXTCON_CHG_USB_ACA, + &x->type_nb); + if (ret) { + dev_err(x->dev, + "register extcon USB ACA failed.\n"); + return ret; + } } if (x->id_nb.notifier_call) { @@ -145,6 +410,13 @@ static int usb_add_extcon(struct usb_phy *x) } } + usb_phy_set_default_current(x); + INIT_WORK(&x->chg_work, usb_phy_notify_charger_work); + x->chg_type = UNKNOWN_TYPE; + x->chg_state = USB_CHARGER_DEFAULT; + if (x->type_nb.notifier_call) + __usb_phy_get_charger_type(x); + return 0; } @@ -302,8 +574,8 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, node = of_parse_phandle(dev->of_node, phandle, index); if (!node) { - dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle, - dev->of_node->full_name); + dev_dbg(dev, "failed to get %s phandle in %pOF node\n", phandle, + dev->of_node); return ERR_PTR(-ENODEV); } phy = devm_usb_get_phy_by_node(dev, node, NULL); diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile index d787d05f6546..fac147a3ad23 100644 --- a/drivers/usb/renesas_usbhs/Makefile +++ b/drivers/usb/renesas_usbhs/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # for Renesas USB # diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index d1af831f43eb..50285b01da92 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -282,11 +282,26 @@ static void usbhsf_fifo_clear(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo) { struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + int ret = 0; - if (!usbhs_pipe_is_dcp(pipe)) - usbhsf_fifo_barrier(priv, fifo); + if (!usbhs_pipe_is_dcp(pipe)) { + /* + * This driver checks the pipe condition first to avoid -EBUSY + * from usbhsf_fifo_barrier() with about 10 msec delay in + * the interrupt handler if the pipe is RX direction and empty. + */ + if (usbhs_pipe_is_dir_in(pipe)) + ret = usbhs_pipe_is_accessible(pipe); + if (!ret) + ret = usbhsf_fifo_barrier(priv, fifo); + } - usbhs_write(priv, fifo->ctr, BCLR); + /* + * if non-DCP pipe, this driver should set BCLR when + * usbhsf_fifo_barrier() returns 0. + */ + if (!ret) + usbhs_write(priv, fifo->ctr, BCLR); } static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv, @@ -842,9 +857,9 @@ static void xfer_work(struct work_struct *work) fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); usbhs_pipe_running(pipe, 1); - usbhsf_dma_start(pipe, fifo); usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); dma_async_issue_pending(chan); + usbhsf_dma_start(pipe, fifo); usbhs_pipe_enable(pipe); xfer_work_end: diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 2c8161bcf5b5..c068b673420b 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -764,7 +764,7 @@ static int usbhsg_ep_set_wedge(struct usb_ep *ep) return __usbhsg_ep_set_halt_wedge(ep, 1, 1); } -static struct usb_ep_ops usbhsg_ep_ops = { +static const struct usb_ep_ops usbhsg_ep_ops = { .enable = usbhsg_ep_enable, .disable = usbhsg_ep_disable, @@ -1082,7 +1082,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) ret = -ENOMEM; goto usbhs_mod_gadget_probe_err_gpriv; } - spin_lock_init(&uep->lock); gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED); dev_info(dev, "%stransceiver found\n", @@ -1132,6 +1131,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) uep->ep.name = uep->ep_name; uep->ep.ops = &usbhsg_ep_ops; INIT_LIST_HEAD(&uep->ep.ep_list); + spin_lock_init(&uep->lock); /* init DCP */ if (usbhsg_is_dcp(uep)) { diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index dfb346e9bd0c..e256351cb72d 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -1285,7 +1285,7 @@ static int usbhsh_bus_nop(struct usb_hcd *hcd) return 0; } -static struct hc_driver usbhsh_driver = { +static const struct hc_driver usbhsh_driver = { .description = usbhsh_hcd_name, .hcd_priv_size = sizeof(struct usbhsh_hpriv), diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 9396a8c14af8..d811f0550c04 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -401,7 +401,7 @@ static int usbhsp_setup_pipecfg(struct usbhs_pipe *pipe, int is_host, u16 dir = 0; u16 epnum = 0; u16 shtnak = 0; - u16 type_array[] = { + static const u16 type_array[] = { [USB_ENDPOINT_XFER_BULK] = TYPE_BULK, [USB_ENDPOINT_XFER_INT] = TYPE_INT, [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO, diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 5a21a82390e1..2d491e434f11 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the USB serial device drivers. # diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index fdf89800ebc3..43a862a90a77 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -186,6 +186,7 @@ static int usb_console_setup(struct console *co, char *options) tty_kref_put(tty); reset_open_count: port->port.count = 0; + info->port = NULL; usb_autopm_put_interface(serial->interface); error_get_interface: usb_serial_put(serial); @@ -265,7 +266,7 @@ static struct console usbcons = { void usb_serial_console_disconnect(struct usb_serial *serial) { - if (serial->port[0] == usbcons_info.port) { + if (serial->port[0] && serial->port[0] == usbcons_info.port) { usb_serial_console_exit(); usb_serial_put(serial); } diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2d945c9f975c..412f812522ee 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -177,6 +177,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ + { USB_DEVICE(0x18EF, 0xE032) }, /* ELV TFD500 Data Logger */ { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ @@ -352,6 +353,7 @@ static struct usb_serial_driver * const serial_drivers[] = { #define CP210X_PARTNUM_CP2104 0x04 #define CP210X_PARTNUM_CP2105 0x05 #define CP210X_PARTNUM_CP2108 0x08 +#define CP210X_PARTNUM_UNKNOWN 0xFF /* CP210X_GET_COMM_STATUS returns these 0x13 bytes */ struct cp210x_comm_status { @@ -1491,8 +1493,11 @@ static int cp210x_attach(struct usb_serial *serial) result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, CP210X_GET_PARTNUM, &priv->partnum, sizeof(priv->partnum)); - if (result < 0) - goto err_free_priv; + if (result < 0) { + dev_warn(&serial->interface->dev, + "querying part number failed\n"); + priv->partnum = CP210X_PARTNUM_UNKNOWN; + } usb_set_serial_data(serial, priv); @@ -1505,10 +1510,6 @@ static int cp210x_attach(struct usb_serial *serial) } return 0; -err_free_priv: - kfree(priv); - - return result; } static void cp210x_disconnect(struct usb_serial *serial) diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index 119d2e17077b..35e223751c0e 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CYPRESS_M8_H #define CYPRESS_M8_H diff --git a/drivers/usb/serial/ezusb_convert.pl b/drivers/usb/serial/ezusb_convert.pl index 13f11469116e..40d23f21ec74 100644 --- a/drivers/usb/serial/ezusb_convert.pl +++ b/drivers/usb/serial/ezusb_convert.pl @@ -1,4 +1,5 @@ #! /usr/bin/perl -w +# SPDX-License-Identifier: GPL-2.0 # convert an Intel HEX file into a set of C records usable by the firmware diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1cec03799cdf..49d1b2d4606d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1015,6 +1015,8 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) }, { USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_BT_USB_PID) }, + { USB_DEVICE(CYPRESS_VID, CYPRESS_WICED_WL_USB_PID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index bbcc13df11ac..dcd0b6e05baf 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Driver definitions for the FTDI USB Single Port Serial Converter - * known as FTDI_SIO (Serial Input/Output application of the chipset) diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 4fcf1cecb6d7..4faa09fe308c 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * vendor/product IDs (VID/PID) of devices using FTDI USB serial converters. * Please keep numerically sorted within individual areas, thanks! @@ -609,6 +610,13 @@ #define ADI_GNICE_PID 0xF000 #define ADI_GNICEPLUS_PID 0xF001 +/* + * Cypress WICED USB UART + */ +#define CYPRESS_VID 0x04B4 +#define CYPRESS_WICED_BT_USB_PID 0x009B +#define CYPRESS_WICED_WL_USB_PID 0xF900 + /* * Microchip Technology, Inc. * diff --git a/drivers/usb/serial/kl5kusb105.h b/drivers/usb/serial/kl5kusb105.h index 22a90badc86b..41c9bf60fbf0 100644 --- a/drivers/usb/serial/kl5kusb105.h +++ b/drivers/usb/serial/kl5kusb105.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for the KLSI KL5KUSB105 serial port adapter */ diff --git a/drivers/usb/serial/kobil_sct.h b/drivers/usb/serial/kobil_sct.h index be207f7156fe..030c1b426611 100644 --- a/drivers/usb/serial/kobil_sct.h +++ b/drivers/usb/serial/kobil_sct.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define SUSBCRequest_SetBaudRateParityAndStopBits 1 #define SUSBCR_SBR_MASK 0xFF00 #define SUSBCR_SBR_1200 0x0100 diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index cc84da8dbb84..14511d6a7d44 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -45,6 +45,7 @@ struct metrousb_private { static const struct usb_device_id id_table[] = { { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) }, { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, + { USB_DEVICE_INTERFACE_CLASS(0x0c2e, 0x0730, 0xff) }, /* MS7820 */ { }, /* Terminating entry. */ }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index fe123153b1a5..ba672cf4e888 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -522,6 +522,7 @@ static void option_instat_callback(struct urb *urb); /* TP-LINK Incorporated products */ #define TPLINK_VENDOR_ID 0x2357 +#define TPLINK_PRODUCT_LTE 0x000D #define TPLINK_PRODUCT_MA180 0x0201 /* Changhong products */ @@ -2011,18 +2012,17 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, + { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */ - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, - { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d03, 0xff) }, { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */ diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index ebc0beea69d6..eb9928963a53 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -174,6 +174,10 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ {DEVICE_SWI(0x413c, 0x81b5)}, /* Dell Wireless 5811e QDL */ {DEVICE_SWI(0x413c, 0x81b6)}, /* Dell Wireless 5811e QDL */ + {DEVICE_SWI(0x413c, 0x81cf)}, /* Dell Wireless 5819 */ + {DEVICE_SWI(0x413c, 0x81d0)}, /* Dell Wireless 5819 */ + {DEVICE_SWI(0x413c, 0x81d1)}, /* Dell Wireless 5818 */ + {DEVICE_SWI(0x413c, 0x81d2)}, /* Dell Wireless 5818 */ /* Huawei devices */ {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */ diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index 44b25c08c68a..d28dab4b9eff 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Definitions for USB serial mobile broadband cards */ diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index 4cd55481b309..c5126a4cd954 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the USB Mass Storage device drivers. # diff --git a/drivers/usb/storage/option_ms.h b/drivers/usb/storage/option_ms.h index b6e448cab039..6439992184fa 100644 --- a/drivers/usb/storage/option_ms.h +++ b/drivers/usb/storage/option_ms.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _OPTION_MS_H_ #define _OPTION_MS_H_ extern int option_ms_init(struct us_data *us); diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 4176d1af9bf2..ec83b3b5efa9 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -47,7 +47,6 @@ MODULE_DESCRIPTION("Driver for Realtek USB Card Reader"); MODULE_AUTHOR("wwang "); MODULE_LICENSE("GPL"); -MODULE_VERSION("1.03"); static int auto_delink_en = 1; module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index 9a51019ac7b2..daf62448483f 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/drivers/usb/storage/sierra_ms.h b/drivers/usb/storage/sierra_ms.h index bb48634ac1fc..3e9da537d54a 100644 --- a/drivers/usb/storage/sierra_ms.h +++ b/drivers/usb/storage/sierra_ms.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _SIERRA_MS_H_ #define _SIERRA_MS_H_ extern int sierra_ms_init(struct us_data *us); diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 1a59f335b063..a3ccb899df60 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -834,13 +834,25 @@ Retry_Sense: if (result == USB_STOR_TRANSPORT_GOOD) { srb->result = SAM_STAT_GOOD; srb->sense_buffer[0] = 0x0; + } + + /* + * ATA-passthru commands use sense data to report + * the command completion status, and often devices + * return Check Condition status when nothing is + * wrong. + */ + else if (srb->cmnd[0] == ATA_16 || + srb->cmnd[0] == ATA_12) { + /* leave the data alone */ + } /* * If there was a problem, report an unspecified * hardware error to prevent the higher layers from * entering an infinite retry loop. */ - } else { + else { srb->result = DID_ERROR << 16; if ((sshdr.response_code & 0x72) == 0x72) srb->sense_buffer[1] = HARDWARE_ERROR; diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index f58caa9e6a27..1fcd758a961f 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include "usb.h" @@ -9,7 +10,8 @@ static int uas_is_interface(struct usb_host_interface *intf) intf->desc.bInterfaceProtocol == USB_PR_UAS); } -static int uas_find_uas_alt_setting(struct usb_interface *intf) +static struct usb_host_interface *uas_find_uas_alt_setting( + struct usb_interface *intf) { int i; @@ -17,10 +19,10 @@ static int uas_find_uas_alt_setting(struct usb_interface *intf) struct usb_host_interface *alt = &intf->altsetting[i]; if (uas_is_interface(alt)) - return alt->desc.bAlternateSetting; + return alt; } - return -ENODEV; + return NULL; } static int uas_find_endpoints(struct usb_host_interface *alt, @@ -58,14 +60,14 @@ static int uas_use_uas_driver(struct usb_interface *intf, struct usb_device *udev = interface_to_usbdev(intf); struct usb_hcd *hcd = bus_to_hcd(udev->bus); unsigned long flags = id->driver_info; - int r, alt; - + struct usb_host_interface *alt; + int r; alt = uas_find_uas_alt_setting(intf); - if (alt < 0) + if (!alt) return 0; - r = uas_find_endpoints(&intf->altsetting[alt], eps); + r = uas_find_endpoints(alt, eps); if (r < 0) return 0; diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 5ef014ba6ae8..63cf981ed81c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -737,7 +737,7 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd) return FAILED; } -static int uas_eh_bus_reset_handler(struct scsi_cmnd *cmnd) +static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd) { struct scsi_device *sdev = cmnd->device; struct uas_dev_info *devinfo = sdev->hostdata; @@ -848,7 +848,7 @@ static struct scsi_host_template uas_host_template = { .slave_alloc = uas_slave_alloc, .slave_configure = uas_slave_configure, .eh_abort_handler = uas_eh_abort_handler, - .eh_bus_reset_handler = uas_eh_bus_reset_handler, + .eh_device_reset_handler = uas_eh_device_reset_handler, .this_id = -1, .sg_tablesize = SG_NONE, .skip_settle_delay = 1, @@ -873,14 +873,14 @@ MODULE_DEVICE_TABLE(usb, uas_usb_ids); static int uas_switch_interface(struct usb_device *udev, struct usb_interface *intf) { - int alt; + struct usb_host_interface *alt; alt = uas_find_uas_alt_setting(intf); - if (alt < 0) - return alt; + if (!alt) + return -ENODEV; - return usb_set_interface(udev, - intf->altsetting[0].desc.bInterfaceNumber, alt); + return usb_set_interface(udev, alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); } static int uas_configure_endpoints(struct uas_dev_info *devinfo) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 5a70c33ef0e0..eb06d88b41d6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1459,6 +1459,13 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Reported by Kris Lindgren */ +UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9999, + "Seagate", + "External", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT ), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA", diff --git a/drivers/usb/typec/ucsi/Makefile b/drivers/usb/typec/ucsi/Makefile index 8372fc22f9b3..b57891c1fd31 100644 --- a/drivers/usb/typec/ucsi/Makefile +++ b/drivers/usb/typec/ucsi/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 CFLAGS_trace.o := -I$(src) obj-$(CONFIG_TYPEC_UCSI) += typec_ucsi.o diff --git a/drivers/usb/typec/ucsi/debug.h b/drivers/usb/typec/ucsi/debug.h index e4d8fc763e6c..fdeff39df120 100644 --- a/drivers/usb/typec/ucsi/debug.h +++ b/drivers/usb/typec/ucsi/debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UCSI_DEBUG_H #define __UCSI_DEBUG_H diff --git a/drivers/usb/typec/ucsi/trace.h b/drivers/usb/typec/ucsi/trace.h index 98b404404834..d5092446ecc6 100644 --- a/drivers/usb/typec/ucsi/trace.h +++ b/drivers/usb/typec/ucsi/trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM ucsi diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 8a88f45822e3..53b80f40a908 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __DRIVER_USB_TYPEC_UCSI_H #define __DRIVER_USB_TYPEC_UCSI_H diff --git a/drivers/usb/usbip/Makefile b/drivers/usb/usbip/Makefile index d843a9e68852..f4c8f3840262 100644 --- a/drivers/usb/usbip/Makefile +++ b/drivers/usb/usbip/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_USBIP_DEBUG) := -DDEBUG obj-$(CONFIG_USBIP_CORE) += usbip-core.o diff --git a/drivers/usb/usbip/stub_main.c b/drivers/usb/usbip/stub_main.c index 660180a5d5c4..7170404e8979 100644 --- a/drivers/usb/usbip/stub_main.c +++ b/drivers/usb/usbip/stub_main.c @@ -302,7 +302,6 @@ static int __init usbip_host_init(void) goto err_create_file; } - pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; err_create_file: @@ -335,4 +334,3 @@ module_exit(usbip_host_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(USBIP_VERSION); diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index cab2b71a80d0..2281f3562870 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -763,7 +763,6 @@ static int __init usbip_core_init(void) { int ret; - pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); ret = usbip_init_eh(); if (ret) return ret; @@ -783,4 +782,3 @@ module_exit(usbip_core_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(USBIP_VERSION); diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index f8573a52e41a..3050fc99a417 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -34,8 +34,6 @@ #include #include -#define USBIP_VERSION "1.0.0" - #undef pr_fmt #ifdef DEBUG diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 2c4b2fd40406..11b9a22799cc 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -1274,7 +1274,7 @@ static int vhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev, return 0; } -static struct hc_driver vhci_hc_driver = { +static const struct hc_driver vhci_hc_driver = { .description = driver_name, .product_desc = driver_desc, .hcd_priv_size = sizeof(struct vhci_hcd), @@ -1516,7 +1516,6 @@ static int __init vhci_hcd_init(void) } } - pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; err_add_hcd: @@ -1542,4 +1541,3 @@ module_exit(vhci_hcd_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(USBIP_VERSION); diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 5778b640ba9c..1b9f60a22e0b 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -366,7 +366,11 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, sockfd_put(socket); dev_err(dev, "port %d already used\n", rhport); - return -EINVAL; + /* + * Will be retried from userspace + * if there's another free port. + */ + return -EBUSY; } dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", diff --git a/drivers/usb/wusbcore/Makefile b/drivers/usb/wusbcore/Makefile index b3bd313032b1..d604ccdd916f 100644 --- a/drivers/usb/wusbcore/Makefile +++ b/drivers/usb/wusbcore/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ccflags-$(CONFIG_USB_WUSB_CBAF_DEBUG) := -DDEBUG obj-$(CONFIG_USB_WUSB) += wusbcore.o diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index fb70cbef0671..aa4e440e9975 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c @@ -586,7 +586,7 @@ static struct attribute *cbaf_dev_attrs[] = { NULL, }; -static struct attribute_group cbaf_dev_attr_group = { +static const struct attribute_group cbaf_dev_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = cbaf_dev_attrs, }; diff --git a/drivers/usb/wusbcore/dev-sysfs.c b/drivers/usb/wusbcore/dev-sysfs.c index d4de56b93d68..78212f8180ce 100644 --- a/drivers/usb/wusbcore/dev-sysfs.c +++ b/drivers/usb/wusbcore/dev-sysfs.c @@ -114,7 +114,7 @@ static struct attribute *wusb_dev_attrs[] = { NULL, }; -static struct attribute_group wusb_dev_attr_group = { +static const struct attribute_group wusb_dev_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = wusb_dev_attrs, }; diff --git a/drivers/usb/wusbcore/wusbhc.c b/drivers/usb/wusbcore/wusbhc.c index a273a91cf667..5338e42533c8 100644 --- a/drivers/usb/wusbcore/wusbhc.c +++ b/drivers/usb/wusbcore/wusbhc.c @@ -244,7 +244,7 @@ static struct attribute *wusbhc_attrs[] = { NULL, }; -static struct attribute_group wusbhc_attr_group = { +static const struct attribute_group wusbhc_attr_group = { .name = NULL, /* we want them in the same directory */ .attrs = wusbhc_attrs, }; diff --git a/drivers/uwb/Makefile b/drivers/uwb/Makefile index d47dd6e2942c..32f4de7afbd6 100644 --- a/drivers/uwb/Makefile +++ b/drivers/uwb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_UWB) += uwb.o obj-$(CONFIG_UWB_WHCI) += umc.o whci.o whc-rc.o obj-$(CONFIG_UWB_HWA) += hwa-rc.o diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c index 35a1e777b449..9a53912bdfe9 100644 --- a/drivers/uwb/hwa-rc.c +++ b/drivers/uwb/hwa-rc.c @@ -825,6 +825,8 @@ static int hwarc_probe(struct usb_interface *iface, if (iface->cur_altsetting->desc.bNumEndpoints < 1) return -ENODEV; + if (!usb_endpoint_xfer_int(&iface->cur_altsetting->endpoint[0].desc)) + return -ENODEV; result = -ENOMEM; uwb_rc = uwb_rc_alloc(); diff --git a/drivers/uwb/i1480/dfu/Makefile b/drivers/uwb/i1480/dfu/Makefile index bd1b9f25424c..4739fdac5922 100644 --- a/drivers/uwb/i1480/dfu/Makefile +++ b/drivers/uwb/i1480/dfu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_UWB_I1480U) += i1480-dfu-usb.o i1480-dfu-usb-objs := \ diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c index 97ee1b46db69..b0816c753a63 100644 --- a/drivers/uwb/lc-rc.c +++ b/drivers/uwb/lc-rc.c @@ -228,7 +228,7 @@ static struct attribute *rc_attrs[] = { NULL, }; -static struct attribute_group rc_attr_group = { +static const struct attribute_group rc_attr_group = { .attrs = rc_attrs, }; diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c index 01c20a260a8b..39dd4ef53c77 100644 --- a/drivers/uwb/uwbd.c +++ b/drivers/uwb/uwbd.c @@ -302,18 +302,22 @@ static int uwbd(void *param) /** Start the UWB daemon */ void uwbd_start(struct uwb_rc *rc) { - rc->uwbd.task = kthread_run(uwbd, rc, "uwbd"); - if (rc->uwbd.task == NULL) + struct task_struct *task = kthread_run(uwbd, rc, "uwbd"); + if (IS_ERR(task)) { + rc->uwbd.task = NULL; printk(KERN_ERR "UWB: Cannot start management daemon; " "UWB won't work\n"); - else + } else { + rc->uwbd.task = task; rc->uwbd.pid = rc->uwbd.task->pid; + } } /* Stop the UWB daemon and free any unprocessed events */ void uwbd_stop(struct uwb_rc *rc) { - kthread_stop(rc->uwbd.task); + if (rc->uwbd.task) + kthread_stop(rc->uwbd.task); uwbd_flush(rc); } diff --git a/drivers/vfio/Makefile b/drivers/vfio/Makefile index 4a23c13b6be4..de67c4725cce 100644 --- a/drivers/vfio/Makefile +++ b/drivers/vfio/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 vfio_virqfd-y := virqfd.o obj-$(CONFIG_VFIO) += vfio.o diff --git a/drivers/vfio/platform/Makefile b/drivers/vfio/platform/Makefile index 41a6224f5e6b..3f3a24e7c4ef 100644 --- a/drivers/vfio/platform/Makefile +++ b/drivers/vfio/platform/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 vfio-platform-base-y := vfio_platform_common.o vfio_platform_irq.o vfio-platform-y := vfio_platform.o diff --git a/drivers/vfio/platform/reset/Makefile b/drivers/vfio/platform/reset/Makefile index 93f4e232697b..90ba20b646da 100644 --- a/drivers/vfio/platform/reset/Makefile +++ b/drivers/vfio/platform/reset/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 vfio-platform-calxedaxgmac-y := vfio_platform_calxedaxgmac.o vfio-platform-amdxgbe-y := vfio_platform_amdxgbe.o diff --git a/drivers/vfio/platform/vfio_amba.c b/drivers/vfio/platform/vfio_amba.c index 31372fbf6c5b..62dfbfeaabfc 100644 --- a/drivers/vfio/platform/vfio_amba.c +++ b/drivers/vfio/platform/vfio_amba.c @@ -93,7 +93,7 @@ static int vfio_amba_remove(struct amba_device *adev) return -EINVAL; } -static struct amba_id pl330_ids[] = { +static const struct amba_id pl330_ids[] = { { 0, 0 }, }; diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 330d50582f40..f5a86f651f38 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -85,6 +85,7 @@ struct vfio_group { struct list_head unbound_list; struct mutex unbound_lock; atomic_t opened; + wait_queue_head_t container_q; bool noiommu; struct kvm *kvm; struct blocking_notifier_head notifier; @@ -138,9 +139,10 @@ struct iommu_group *vfio_iommu_group_get(struct device *dev) iommu_group_set_name(group, "vfio-noiommu"); iommu_group_set_iommudata(group, &noiommu, NULL); ret = iommu_group_add_device(group, dev); - iommu_group_put(group); - if (ret) + if (ret) { + iommu_group_put(group); return NULL; + } /* * Where to taint? At this point we've added an IOMMU group for a @@ -337,6 +339,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) mutex_init(&group->unbound_lock); atomic_set(&group->container_users, 0); atomic_set(&group->opened, 0); + init_waitqueue_head(&group->container_q); group->iommu_group = iommu_group; #ifdef CONFIG_VFIO_NOIOMMU group->noiommu = (iommu_group_get_iommudata(iommu_group) == &noiommu); @@ -993,6 +996,23 @@ void *vfio_del_group_dev(struct device *dev) } } while (ret <= 0); + /* + * In order to support multiple devices per group, devices can be + * plucked from the group while other devices in the group are still + * in use. The container persists with this group and those remaining + * devices still attached. If the user creates an isolation violation + * by binding this device to another driver while the group is still in + * use, that's their fault. However, in the case of removing the last, + * or potentially the only, device in the group there can be no other + * in-use devices in the group. The user has done their due diligence + * and we should lay no claims to those devices. In order to do that, + * we need to make sure the group is detached from the container. + * Without this stall, we're potentially racing with a user process + * that may attempt to immediately bind this device to another driver. + */ + if (list_empty(&group->device_list)) + wait_event(group->container_q, !group->container); + vfio_group_put(group); return device_data; @@ -1298,6 +1318,7 @@ static void __vfio_group_unset_container(struct vfio_group *group) group->iommu_group); group->container = NULL; + wake_up(&group->container_q); list_del(&group->container_next); /* Detaching the last group deprivileges a container, remove iommu */ diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 8549cb111627..92155cce926d 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1169,13 +1169,21 @@ static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base) INIT_LIST_HEAD(&group_resv_regions); iommu_get_group_resv_regions(group, &group_resv_regions); list_for_each_entry(region, &group_resv_regions, list) { + /* + * The presence of any 'real' MSI regions should take + * precedence over the software-managed one if the + * IOMMU driver happens to advertise both types. + */ + if (region->type == IOMMU_RESV_MSI) { + ret = false; + break; + } + if (region->type == IOMMU_RESV_SW_MSI) { *base = region->start; ret = true; - goto out; } } -out: list_for_each_entry_safe(region, next, &group_resv_regions, list) kfree(region); return ret; @@ -1265,8 +1273,8 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, INIT_LIST_HEAD(&domain->group_list); list_add(&group->next, &domain->group_list); - msi_remap = resv_msi ? irq_domain_check_msi_remap() : - iommu_capable(bus, IOMMU_CAP_INTR_REMAP); + msi_remap = irq_domain_check_msi_remap() || + iommu_capable(bus, IOMMU_CAP_INTR_REMAP); if (!allow_unsafe_interrupts && !msi_remap) { pr_warn("%s: No interrupt remapping support. Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n", diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile index 6b012b986b57..6c6df24f770c 100644 --- a/drivers/vhost/Makefile +++ b/drivers/vhost/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_VHOST_NET) += vhost_net.o vhost_net-y := net.o diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 06d044862e58..58585ec8699e 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -533,6 +533,7 @@ static void handle_tx(struct vhost_net *net) ubuf->callback = vhost_zerocopy_callback; ubuf->ctx = nvq->ubufs; ubuf->desc = nvq->upend_idx; + refcount_set(&ubuf->refcnt, 1); msg.msg_control = ubuf; msg.msg_controllen = sizeof(ubuf); ubufs = nvq->ubufs; @@ -634,8 +635,13 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk) preempt_enable(); - if (vhost_enable_notify(&net->dev, vq)) + if (!vhost_vq_avail_empty(&net->dev, vq)) vhost_poll_queue(&vq->poll); + else if (unlikely(vhost_enable_notify(&net->dev, vq))) { + vhost_disable_notify(&net->dev, vq); + vhost_poll_queue(&vq->poll); + } + mutex_unlock(&vq->mutex); len = peek_head_len(rvq, sk); diff --git a/drivers/vhost/test.h b/drivers/vhost/test.h index 1fef5df82153..7dd265bfdf81 100644 --- a/drivers/vhost/test.h +++ b/drivers/vhost/test.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LINUX_VHOST_TEST_H #define LINUX_VHOST_TEST_H diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 9cb3f722dce1..d6dbb28245e6 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1271,7 +1271,7 @@ static struct vhost_umem *vhost_umem_alloc(void) if (!umem) return NULL; - umem->umem_tree = RB_ROOT; + umem->umem_tree = RB_ROOT_CACHED; umem->numem = 0; INIT_LIST_HEAD(&umem->umem_list); diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index bb7c29b8b9fc..79c6e7a60a5e 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VHOST_H #define _VHOST_H @@ -71,7 +72,7 @@ struct vhost_umem_node { }; struct vhost_umem { - struct rb_root umem_tree; + struct rb_root_cached umem_tree; struct list_head umem_list; int numem; }; diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 445b2c230b56..df7650adede9 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_HDMI) += hdmi.o diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 8905129691e8..5e28f01c8391 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Backlight & LCD drivers obj-$(CONFIG_LCD_AMS369FG06) += ams369fg06.o diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c index 18134416b154..e470da95d806 100644 --- a/drivers/video/backlight/gpio_backlight.c +++ b/drivers/video/backlight/gpio_backlight.c @@ -9,7 +9,8 @@ #include #include #include -#include +#include /* Only for legacy support */ +#include #include #include #include @@ -23,8 +24,7 @@ struct gpio_backlight { struct device *dev; struct device *fbdev; - int gpio; - int active; + struct gpio_desc *gpiod; int def_value; }; @@ -38,8 +38,7 @@ static int gpio_backlight_update_status(struct backlight_device *bl) bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) brightness = 0; - gpio_set_value_cansleep(gbl->gpio, - brightness ? gbl->active : !gbl->active); + gpiod_set_value_cansleep(gbl->gpiod, brightness); return 0; } @@ -61,22 +60,24 @@ static const struct backlight_ops gpio_backlight_ops = { static int gpio_backlight_probe_dt(struct platform_device *pdev, struct gpio_backlight *gbl) { - struct device_node *np = pdev->dev.of_node; - enum of_gpio_flags gpio_flags; - - gbl->gpio = of_get_gpio_flags(np, 0, &gpio_flags); - - if (!gpio_is_valid(gbl->gpio)) { - if (gbl->gpio != -EPROBE_DEFER) { - dev_err(&pdev->dev, - "Error: The gpios parameter is missing or invalid.\n"); - } - return gbl->gpio; - } - - gbl->active = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + enum gpiod_flags flags; + int ret; gbl->def_value = of_property_read_bool(np, "default-on"); + flags = gbl->def_value ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + + gbl->gpiod = devm_gpiod_get(dev, NULL, flags); + if (IS_ERR(gbl->gpiod)) { + ret = PTR_ERR(gbl->gpiod); + + if (ret != -EPROBE_DEFER) { + dev_err(dev, + "Error: The gpios parameter is missing or invalid.\n"); + } + return ret; + } return 0; } @@ -89,7 +90,6 @@ static int gpio_backlight_probe(struct platform_device *pdev) struct backlight_device *bl; struct gpio_backlight *gbl; struct device_node *np = pdev->dev.of_node; - unsigned long flags = GPIOF_DIR_OUT; int ret; if (!pdata && !np) { @@ -109,22 +109,26 @@ static int gpio_backlight_probe(struct platform_device *pdev) if (ret) return ret; } else { + /* + * Legacy platform data GPIO retrieveal. Do not expand + * the use of this code path, currently only used by one + * SH board. + */ + unsigned long flags = GPIOF_DIR_OUT; + gbl->fbdev = pdata->fbdev; - gbl->gpio = pdata->gpio; - gbl->active = pdata->active_low ? 0 : 1; gbl->def_value = pdata->def_value; - } - - if (gbl->active) flags |= gbl->def_value ? GPIOF_INIT_HIGH : GPIOF_INIT_LOW; - else - flags |= gbl->def_value ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH; - ret = devm_gpio_request_one(gbl->dev, gbl->gpio, flags, - pdata ? pdata->name : "backlight"); - if (ret < 0) { - dev_err(&pdev->dev, "unable to request GPIO\n"); - return ret; + ret = devm_gpio_request_one(gbl->dev, pdata->gpio, flags, + pdata ? pdata->name : "backlight"); + if (ret < 0) { + dev_err(&pdev->dev, "unable to request GPIO\n"); + return ret; + } + gbl->gpiod = gpio_to_desc(pdata->gpio); + if (!gbl->gpiod) + return -EINVAL; } memset(&props, 0, sizeof(props)); diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index 84a110a719cb..96312c3afc07 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -78,7 +78,7 @@ static struct kb3886bl_machinfo *bl_machinfo; static unsigned long kb3886bl_flags; #define KB3886BL_SUSPENDED 0x01 -static struct dmi_system_id kb3886bl_device_table[] __initdata = { +static const struct dmi_system_id kb3886bl_device_table[] __initconst = { { .ident = "Sahara Touch-iT", .matches = { diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c index 60d6c2ac87aa..2030a6b77a09 100644 --- a/drivers/video/backlight/lm3630a_bl.c +++ b/drivers/video/backlight/lm3630a_bl.c @@ -31,7 +31,8 @@ #define REG_FAULT 0x0B #define REG_PWM_OUTLOW 0x12 #define REG_PWM_OUTHIGH 0x13 -#define REG_MAX 0x1F +#define REG_FILTER_STRENGTH 0x50 +#define REG_MAX 0x50 #define INT_DEBOUNCE_MSEC 10 struct lm3630a_chip { @@ -80,7 +81,7 @@ static int lm3630a_chip_init(struct lm3630a_chip *pchip) usleep_range(1000, 2000); /* set Filter Strength Register */ - rval = lm3630a_write(pchip, 0x50, 0x03); + rval = lm3630a_write(pchip, REG_FILTER_STRENGTH, 0x03); /* set Cofig. register */ rval |= lm3630a_update(pchip, REG_CONFIG, 0x07, pdata->pwm_ctrl); /* set boost control */ diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c index 5d8bb8b20183..a186bc677c7d 100644 --- a/drivers/video/backlight/pandora_bl.c +++ b/drivers/video/backlight/pandora_bl.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #define TWL_PWM0_ON 0x00 diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 002f1ce22bd0..9bd17682655a 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -178,7 +178,7 @@ static int pwm_backlight_parse_dt(struct device *dev, return 0; } -static struct of_device_id pwm_backlight_of_match[] = { +static const struct of_device_id pwm_backlight_of_match[] = { { .compatible = "pwm-backlight" }, { } }; diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 2111d06f8c81..7f1f1fbcef9e 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -117,7 +117,7 @@ config DUMMY_CONSOLE_ROWS Select 25 if you use a 640x480 resolution by default. config FRAMEBUFFER_CONSOLE - tristate "Framebuffer Console support" + bool "Framebuffer Console support" depends on FB && !UML select VT_HW_CONSOLE_BINDING select CRC32 diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index 43bfa485db96..db07b784bd2c 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Linux graphics to console drivers. # 5 Aug 1999, James Simmons, # Rewritten to use lists instead of if-statements. @@ -7,13 +8,5 @@ obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o obj-$(CONFIG_VGA_CONSOLE) += vgacon.o obj-$(CONFIG_MDA_CONSOLE) += mdacon.o -obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o softcursor.o -ifeq ($(CONFIG_FB_TILEBLITTING),y) -obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o -endif -ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y) -obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ - fbcon_ccw.o -endif obj-$(CONFIG_FB_STI) += sticore.o diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 7da1ad03acb5..d1d3796773aa 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -281,7 +281,7 @@ static void sti_rom_copy(unsigned long base, unsigned long count, void *dest) static char default_sti_path[21] __read_mostly; #ifndef MODULE -static int sti_setup(char *str) +static int __init sti_setup(char *str) { if (str) strlcpy (default_sti_path, str, sizeof (default_sti_path)); @@ -941,7 +941,7 @@ static void sticore_check_for_default_sti(struct sti_struct *sti, char *path) * in the additional address field addr[1] while on * older Systems the PDC stores it in page0->proc_sti */ -static int sticore_pa_init(struct parisc_device *dev) +static int __init sticore_pa_init(struct parisc_device *dev) { char pa_path[21]; struct sti_struct *sti = NULL; @@ -1009,7 +1009,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent) } -static void sticore_pci_remove(struct pci_dev *pd) +static void __exit sticore_pci_remove(struct pci_dev *pd) { BUG(); } @@ -1029,7 +1029,7 @@ static struct pci_driver pci_sti_driver = { .name = "sti", .id_table = sti_pci_tbl, .probe = sticore_pci_init, - .remove = sticore_pci_remove, + .remove = __exit_p(sticore_pci_remove), }; static struct parisc_device_id sti_pa_tbl[] = { @@ -1037,8 +1037,9 @@ static struct parisc_device_id sti_pa_tbl[] = { { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00085 }, { 0, } }; +MODULE_DEVICE_TABLE(parisc, sti_pa_tbl); -static struct parisc_driver pa_sti_driver = { +static struct parisc_driver pa_sti_driver __refdata = { .name = "sti", .id_table = sti_pa_tbl, .probe = sticore_pa_init, diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index dc06cb6a15dc..445b1dc5d441 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -398,9 +398,8 @@ static const char *vgacon_startup(void) #endif } - /* boot_params.screen_info initialized? */ - if ((screen_info.orig_video_mode == 0) && - (screen_info.orig_video_lines == 0) && + /* boot_params.screen_info reasonably initialized? */ + if ((screen_info.orig_video_lines == 0) || (screen_info.orig_video_cols == 0)) goto no_vga; diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c index c0c6b88d3839..d48e96088f76 100644 --- a/drivers/video/fbdev/68328fb.c +++ b/drivers/video/fbdev/68328fb.c @@ -72,7 +72,7 @@ static struct fb_var_screeninfo mc68x328fb_default __initdata = { .vmode = FB_VMODE_NONINTERLACED, }; -static struct fb_fix_screeninfo mc68x328fb_fix __initdata = { +static const struct fb_fix_screeninfo mc68x328fb_fix __initconst = { .id = "68328fb", .type = FB_TYPE_PACKED_PIXELS, .xpanstep = 1, diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 5c6696bb56da..5e58f5ec0a28 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2173,7 +2173,7 @@ config FB_PS3_DEFAULT_SIZE_M config FB_XILINX tristate "Xilinx frame buffer support" - depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ) + depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index ee8c81405a7f..8895536a20d6 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Linux video drivers. # 5 Aug 1999, James Simmons, # Rewritten to use lists instead of if-statements. diff --git a/drivers/video/fbdev/amba-clcd-nomadik.h b/drivers/video/fbdev/amba-clcd-nomadik.h index a24032c8156e..462c31381fa1 100644 --- a/drivers/video/fbdev/amba-clcd-nomadik.h +++ b/drivers/video/fbdev/amba-clcd-nomadik.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _AMBA_CLCD_NOMADIK_H #define _AMBA_CLCD_NOMADIK_H diff --git a/drivers/video/fbdev/amba-clcd-versatile.h b/drivers/video/fbdev/amba-clcd-versatile.h index 4692c3092823..b20baa47e6ad 100644 --- a/drivers/video/fbdev/amba-clcd-versatile.h +++ b/drivers/video/fbdev/amba-clcd-versatile.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Special local versatile callbacks */ diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index ffc2c33c6cef..36d25190b48c 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -1035,7 +1035,7 @@ static struct clcd_vendor_data vendor_nomadik = { .init_panel = nomadik_clcd_init_panel, }; -static struct amba_id clcdfb_id_table[] = { +static const struct amba_id clcdfb_id_table[] = { { .id = 0x00041110, .mask = 0x000ffffe, diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c index 6a317de7082c..13ba371e70aa 100644 --- a/drivers/video/fbdev/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -1157,7 +1157,7 @@ fail: /* List of boards that we are trying to support */ -static struct pci_device_id ark_devices[] = { +static const struct pci_device_id ark_devices[] = { {PCI_DEVICE(0xEDD8, 0xA099)}, {0, 0, 0, 0, 0, 0, 0} }; diff --git a/drivers/video/fbdev/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c index 91eea4583382..ea31054a28ca 100644 --- a/drivers/video/fbdev/asiliantfb.c +++ b/drivers/video/fbdev/asiliantfb.c @@ -592,7 +592,7 @@ static void asiliantfb_remove(struct pci_dev *dp) framebuffer_release(p); } -static struct pci_device_id asiliantfb_pci_tbl[] = { +static const struct pci_device_id asiliantfb_pci_tbl[] = { { PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000, PCI_ANY_ID, PCI_ANY_ID }, { 0 } }; diff --git a/drivers/video/fbdev/atafb.h b/drivers/video/fbdev/atafb.h index 014e05906cb1..2b2675980087 100644 --- a/drivers/video/fbdev/atafb.h +++ b/drivers/video/fbdev/atafb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VIDEO_ATAFB_H #define _VIDEO_ATAFB_H diff --git a/drivers/video/fbdev/atafb_utils.h b/drivers/video/fbdev/atafb_utils.h index ac9e19dc5057..8f3396ea8ae5 100644 --- a/drivers/video/fbdev/atafb_utils.h +++ b/drivers/video/fbdev/atafb_utils.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _VIDEO_ATAFB_UTILS_H #define _VIDEO_ATAFB_UTILS_H diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 669ecc755fa9..e06358da4b99 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -320,7 +320,7 @@ static inline void atmel_lcdfb_power_control(struct atmel_lcdfb_info *sinfo, int } } -static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { +static const struct fb_fix_screeninfo atmel_lcdfb_fix __initconst = { .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, .xpanstep = 0, diff --git a/drivers/video/fbdev/aty/Makefile b/drivers/video/fbdev/aty/Makefile index a6cc0e9ec790..069465c82d6d 100644 --- a/drivers/video/fbdev/aty/Makefile +++ b/drivers/video/fbdev/aty/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_FB_ATY) += atyfb.o obj-$(CONFIG_FB_ATY128) += aty128fb.o obj-$(CONFIG_FB_RADEON) += radeonfb.o diff --git a/drivers/video/fbdev/aty/ati_ids.h b/drivers/video/fbdev/aty/ati_ids.h index 3e9d28bcd9f8..2b589d687b4c 100644 --- a/drivers/video/fbdev/aty/ati_ids.h +++ b/drivers/video/fbdev/aty/ati_ids.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ATI PCI IDs from XFree86, kept here to make sync'ing with * XFree much simpler. Currently, this list is only used by diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index fa07242a78d2..db18474607c9 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -116,7 +116,7 @@ static const struct fb_var_screeninfo default_var = { /* default modedb mode */ /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */ -static struct fb_videomode defaultmode = { +static const struct fb_videomode defaultmode = { .refresh = 60, .xres = 640, .yres = 480, @@ -166,7 +166,7 @@ static int aty128_pci_resume(struct pci_dev *pdev); static int aty128_do_resume(struct pci_dev *pdev); /* supported Rage128 chipsets */ -static struct pci_device_id aty128_pci_tbl[] = { +static const struct pci_device_id aty128_pci_tbl[] = { { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3_pci }, { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF, diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h index 63c4842eb224..8235b285dbb2 100644 --- a/drivers/video/fbdev/aty/atyfb.h +++ b/drivers/video/fbdev/aty/atyfb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * ATI Frame Buffer Device Driver Core Definitions */ diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index b55fdac9c9f5..3ec72f19114b 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -274,7 +274,7 @@ static struct fb_var_screeninfo default_var = { 0, FB_VMODE_NONINTERLACED }; -static struct fb_videomode defmode = { +static const struct fb_videomode defmode = { /* 640x480 @ 60 Hz, 31.5 kHz hsync */ NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED @@ -1855,7 +1855,7 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT) case ATYIO_CLKR: if (M64_HAS(INTEGRATED)) { - struct atyclk clk; + struct atyclk clk = { 0 }; union aty_pll *pll = &par->pll; u32 dsp_config = pll->ct.dsp_config; u32 dsp_on_off = pll->ct.dsp_on_off; @@ -3756,7 +3756,7 @@ static void atyfb_pci_remove(struct pci_dev *pdev) atyfb_remove(info); } -static struct pci_device_id atyfb_pci_tbl[] = { +static const struct pci_device_id atyfb_pci_tbl[] = { #ifdef CONFIG_FB_ATY_GX { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GX) }, { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CX) }, diff --git a/drivers/video/fbdev/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c index 182bd680141f..2541a0e0de76 100644 --- a/drivers/video/fbdev/aty/mach64_accel.c +++ b/drivers/video/fbdev/aty/mach64_accel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ATI Mach64 Hardware Acceleration diff --git a/drivers/video/fbdev/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c index 51f29d627ceb..7d3bd723d3d5 100644 --- a/drivers/video/fbdev/aty/mach64_ct.c +++ b/drivers/video/fbdev/aty/mach64_ct.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ATI Mach64 CT/VT/GT/LT Support diff --git a/drivers/video/fbdev/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c index 2fa0317ab3c7..4cde25eab8e8 100644 --- a/drivers/video/fbdev/aty/mach64_cursor.c +++ b/drivers/video/fbdev/aty/mach64_cursor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ATI Mach64 CT/VT/GT/LT Cursor Support */ diff --git a/drivers/video/fbdev/aty/mach64_gx.c b/drivers/video/fbdev/aty/mach64_gx.c index 10c988aef58e..27cb65fa2ba2 100644 --- a/drivers/video/fbdev/aty/mach64_gx.c +++ b/drivers/video/fbdev/aty/mach64_gx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ATI Mach64 GX Support diff --git a/drivers/video/fbdev/aty/radeon_accel.c b/drivers/video/fbdev/aty/radeon_accel.c index a469a3d6edcb..bb147d8bf82d 100644 --- a/drivers/video/fbdev/aty/radeon_accel.c +++ b/drivers/video/fbdev/aty/radeon_accel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "radeonfb.h" /* the accelerated functions here are patterned after the diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c index 6b4c7872b375..1e2ec360f8c1 100644 --- a/drivers/video/fbdev/aty/radeon_base.c +++ b/drivers/video/fbdev/aty/radeon_base.c @@ -96,7 +96,7 @@ #define CHIP_DEF(id, family, flags) \ { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) } -static struct pci_device_id radeonfb_pci_table[] = { +static const struct pci_device_id radeonfb_pci_table[] = { /* Radeon Xpress 200m */ CHIP_DEF(PCI_CHIP_RS480_5955, RS480, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), CHIP_DEF(PCI_CHIP_RS482_5975, RS480, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), @@ -2241,7 +2241,7 @@ static ssize_t radeon_show_edid2(struct file *filp, struct kobject *kobj, return radeon_show_one_edid(buf, off, count, rinfo->mon2_EDID); } -static struct bin_attribute edid1_attr = { +static const struct bin_attribute edid1_attr = { .attr = { .name = "edid1", .mode = 0444, @@ -2250,7 +2250,7 @@ static struct bin_attribute edid1_attr = { .read = radeon_show_edid1, }; -static struct bin_attribute edid2_attr = { +static const struct bin_attribute edid2_attr = { .attr = { .name = "edid2", .mode = 0444, diff --git a/drivers/video/fbdev/aty/radeon_i2c.c b/drivers/video/fbdev/aty/radeon_i2c.c index ab1d0fd76316..269b12ebb673 100644 --- a/drivers/video/fbdev/aty/radeon_i2c.c +++ b/drivers/video/fbdev/aty/radeon_i2c.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "radeonfb.h" #include diff --git a/drivers/video/fbdev/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c index dd823f5fe4c9..9966c58aa26c 100644 --- a/drivers/video/fbdev/aty/radeon_monitor.c +++ b/drivers/video/fbdev/aty/radeon_monitor.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "radeonfb.h" #include diff --git a/drivers/video/fbdev/aty/radeon_pm.c b/drivers/video/fbdev/aty/radeon_pm.c index 1417542738fc..f7c253dd5899 100644 --- a/drivers/video/fbdev/aty/radeon_pm.c +++ b/drivers/video/fbdev/aty/radeon_pm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/video/aty/radeon_pm.c * diff --git a/drivers/video/fbdev/aty/radeonfb.h b/drivers/video/fbdev/aty/radeonfb.h index 962e31263225..131b34dd65af 100644 --- a/drivers/video/fbdev/aty/radeonfb.h +++ b/drivers/video/fbdev/aty/radeonfb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __RADEONFB_H__ #define __RADEONFB_H__ diff --git a/drivers/video/fbdev/bfin-lq035q1-fb.c b/drivers/video/fbdev/bfin-lq035q1-fb.c index b594a58ff21d..b459354ad940 100644 --- a/drivers/video/fbdev/bfin-lq035q1-fb.c +++ b/drivers/video/fbdev/bfin-lq035q1-fb.c @@ -841,7 +841,7 @@ static int bfin_lq035q1_resume(struct device *dev) return 0; } -static struct dev_pm_ops bfin_lq035q1_dev_pm_ops = { +static const struct dev_pm_ops bfin_lq035q1_dev_pm_ops = { .suspend = bfin_lq035q1_suspend, .resume = bfin_lq035q1_resume, }; diff --git a/drivers/video/fbdev/bw2.c b/drivers/video/fbdev/bw2.c index 8c5b281f0b29..7aa972072357 100644 --- a/drivers/video/fbdev/bw2.c +++ b/drivers/video/fbdev/bw2.c @@ -333,8 +333,8 @@ static int bw2_probe(struct platform_device *op) dev_set_drvdata(&op->dev, info); - printk(KERN_INFO "%s: bwtwo at %lx:%lx\n", - dp->full_name, par->which_io, info->fix.smem_start); + printk(KERN_INFO "%pOF: bwtwo at %lx:%lx\n", + dp, par->which_io, info->fix.smem_start); return 0; diff --git a/drivers/video/fbdev/carminefb.h b/drivers/video/fbdev/carminefb.h index 05306de0c6b6..297688eba469 100644 --- a/drivers/video/fbdev/carminefb.h +++ b/drivers/video/fbdev/carminefb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CARMINE_CARMINE_H #define CARMINE_CARMINE_H diff --git a/drivers/video/fbdev/carminefb_regs.h b/drivers/video/fbdev/carminefb_regs.h index 045215600b73..ae18318d2fc2 100644 --- a/drivers/video/fbdev/carminefb_regs.h +++ b/drivers/video/fbdev/carminefb_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CARMINEFB_REGS_H #define _CARMINEFB_REGS_H diff --git a/drivers/video/fbdev/cg14.c b/drivers/video/fbdev/cg14.c index 43e915eaf606..8de88b129b62 100644 --- a/drivers/video/fbdev/cg14.c +++ b/drivers/video/fbdev/cg14.c @@ -553,8 +553,8 @@ static int cg14_probe(struct platform_device *op) dev_set_drvdata(&op->dev, info); - printk(KERN_INFO "%s: cgfourteen at %lx:%lx, %dMB\n", - dp->full_name, + printk(KERN_INFO "%pOF: cgfourteen at %lx:%lx, %dMB\n", + dp, par->iospace, info->fix.smem_start, par->ramsize >> 20); diff --git a/drivers/video/fbdev/cg3.c b/drivers/video/fbdev/cg3.c index 716391f22e75..6c334260cf53 100644 --- a/drivers/video/fbdev/cg3.c +++ b/drivers/video/fbdev/cg3.c @@ -412,8 +412,8 @@ static int cg3_probe(struct platform_device *op) dev_set_drvdata(&op->dev, info); - printk(KERN_INFO "%s: cg3 at %lx:%lx\n", - dp->full_name, par->which_io, info->fix.smem_start); + printk(KERN_INFO "%pOF: cg3 at %lx:%lx\n", + dp, par->which_io, info->fix.smem_start); return 0; diff --git a/drivers/video/fbdev/cg6.c b/drivers/video/fbdev/cg6.c index bdf901ed5291..0296c21acc78 100644 --- a/drivers/video/fbdev/cg6.c +++ b/drivers/video/fbdev/cg6.c @@ -810,8 +810,8 @@ static int cg6_probe(struct platform_device *op) dev_set_drvdata(&op->dev, info); - printk(KERN_INFO "%s: CGsix [%s] at %lx:%lx\n", - dp->full_name, info->fix.id, + printk(KERN_INFO "%pOF: CGsix [%s] at %lx:%lx\n", + dp, info->fix.id, par->which_io, info->fix.smem_start); return 0; diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c index 59abdc6a97f6..f103665cad43 100644 --- a/drivers/video/fbdev/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c @@ -292,7 +292,7 @@ static void chips_hw_init(void) write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); } -static struct fb_fix_screeninfo chipsfb_fix = { +static const struct fb_fix_screeninfo chipsfb_fix = { .id = "C&T 65550", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -309,7 +309,7 @@ static struct fb_fix_screeninfo chipsfb_fix = { .smem_len = 0x100000, /* 1MB */ }; -static struct fb_var_screeninfo chipsfb_var = { +static const struct fb_var_screeninfo chipsfb_var = { .xres = 800, .yres = 600, .xres_virtual = 800, diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index 9da90bd242f4..0ef633e278a1 100644 --- a/drivers/video/fbdev/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -126,7 +126,7 @@ static void lcd_clear(struct fb_info *info) lcd_write_control(info, LCD_RESET); } -static struct fb_fix_screeninfo cobalt_lcdfb_fix = { +static const struct fb_fix_screeninfo cobalt_lcdfb_fix = { .id = "cobalt-lcd", .type = FB_TYPE_TEXT, .type_aux = FB_AUX_TEXT_MDA, diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index 9e3ddf225393..d34fd182ca68 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -1,9 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o obj-$(CONFIG_FB_NOTIFY) += fb_notify.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o + +ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE),y) +fb-y += fbcon.o bitblit.o softcursor.o +ifeq ($(CONFIG_FB_TILEBLITTING),y) +fb-y += tileblit.o +endif +ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y) +fb-y += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ + fbcon_ccw.o +endif +ifeq ($(CONFIG_DMI),y) +fb-y += fbcon_dmi_quirks.o +endif +endif fb-objs := $(fb-y) obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o diff --git a/drivers/video/console/bitblit.c b/drivers/video/fbdev/core/bitblit.c similarity index 98% rename from drivers/video/console/bitblit.c rename to drivers/video/fbdev/core/bitblit.c index dbfe4eecf12e..790900d646c0 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -203,7 +203,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, } static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, - int bottom_only) + int color, int bottom_only) { unsigned int cw = vc->vc_font.width; unsigned int ch = vc->vc_font.height; @@ -213,7 +213,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int bs = info->var.yres - bh; struct fb_fillrect region; - region.color = 0; + region.color = color; region.rop = ROP_COPY; if (rw && !bottom_only) { @@ -416,7 +416,3 @@ void fbcon_set_bitops(struct fbcon_ops *ops) EXPORT_SYMBOL(fbcon_set_bitops); -MODULE_AUTHOR("Antonino Daplas "); -MODULE_DESCRIPTION("Bit Blitting Operation"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 37f69c061210..487d5e336e1b 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -69,7 +69,7 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy { struct fb_info *info = file->private_data; struct inode *inode = file_inode(file); - int err = filemap_write_and_wait_range(inode->i_mapping, start, end); + int err = file_write_and_wait_range(file, start, end); if (err) return err; diff --git a/drivers/video/fbdev/core/fb_draw.h b/drivers/video/fbdev/core/fb_draw.h index 624ee115f129..e0d829873930 100644 --- a/drivers/video/fbdev/core/fb_draw.h +++ b/drivers/video/fbdev/core/fb_draw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _FB_DRAW_H #define _FB_DRAW_H diff --git a/drivers/video/console/fbcon.c b/drivers/video/fbdev/core/fbcon.c similarity index 99% rename from drivers/video/console/fbcon.c rename to drivers/video/fbdev/core/fbcon.c index 12ded23f1aaf..04612f938bab 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -135,8 +136,9 @@ static char fontname[40]; static int info_idx = -1; /* console rotation */ -static int initial_rotation; +static int initial_rotation = -1; static int fbcon_has_sysfs; +static int margin_color; static const struct consw fb_con; @@ -491,6 +493,13 @@ static int __init fb_console_setup(char *this_opt) initial_rotation = 0; continue; } + + if (!strncmp(options, "margin:", 7)) { + options += 7; + if (*options) + margin_color = simple_strtoul(options, &options, 0); + continue; + } } return 1; } @@ -563,7 +572,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, unsigned short *save = NULL, *r, *q; int logo_height; - if (info->flags & FBINFO_MODULE) { + if (info->fbops->owner) { logo_shown = FBCON_LOGO_DONTSHOW; return; } @@ -954,7 +963,10 @@ static const char *fbcon_startup(void) ops->cur_rotate = -1; ops->cur_blink_jiffies = HZ / 5; info->fbcon_par = ops; - p->con_rotate = initial_rotation; + if (initial_rotation != -1) + p->con_rotate = initial_rotation; + else + p->con_rotate = fbcon_platform_get_rotate(info); set_blitting_type(vc, info); if (info->fix.type != FB_TYPE_TEXT) { @@ -1091,7 +1103,10 @@ static void fbcon_init(struct vc_data *vc, int init) ops = info->fbcon_par; ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms); - p->con_rotate = initial_rotation; + if (initial_rotation != -1) + p->con_rotate = initial_rotation; + else + p->con_rotate = fbcon_platform_get_rotate(info); set_blitting_type(vc, info); cols = vc->vc_cols; @@ -1299,7 +1314,7 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) struct fbcon_ops *ops = info->fbcon_par; if (!fbcon_is_inactive(vc, info)) - ops->clear_margins(vc, info, bottom_only); + ops->clear_margins(vc, info, margin_color, bottom_only); } static void fbcon_cursor(struct vc_data *vc, int mode) @@ -3606,7 +3621,7 @@ static void fbcon_exit(void) fbcon_has_exited = 1; } -static int __init fb_console_init(void) +void __init fb_console_init(void) { int i; @@ -3628,11 +3643,8 @@ static int __init fb_console_init(void) console_unlock(); fbcon_start(); - return 0; } -fs_initcall(fb_console_init); - #ifdef MODULE static void __exit fbcon_deinit_device(void) @@ -3647,7 +3659,7 @@ static void __exit fbcon_deinit_device(void) } } -static void __exit fb_console_exit(void) +void __exit fb_console_exit(void) { console_lock(); fb_unregister_client(&fbcon_event_notifier); @@ -3657,9 +3669,4 @@ static void __exit fb_console_exit(void) do_unregister_con_driver(&fb_con); console_unlock(); } - -module_exit(fb_console_exit); - #endif - -MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/fbcon.h b/drivers/video/fbdev/core/fbcon.h similarity index 97% rename from drivers/video/console/fbcon.h rename to drivers/video/fbdev/core/fbcon.h index 7aaa4eabbba0..18f3ac144237 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/fbdev/core/fbcon.h @@ -60,7 +60,7 @@ struct fbcon_ops { const unsigned short *s, int count, int yy, int xx, int fg, int bg); void (*clear_margins)(struct vc_data *vc, struct fb_info *info, - int bottom_only); + int color, int bottom_only); void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode, int softback_lines, int fg, int bg); int (*update_start)(struct fb_info *info); @@ -261,5 +261,10 @@ extern void fbcon_set_rotate(struct fbcon_ops *ops); #define fbcon_set_rotate(x) do {} while(0) #endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */ -#endif /* _VIDEO_FBCON_H */ +#ifdef CONFIG_DMI +int fbcon_platform_get_rotate(struct fb_info *info); +#else +#define fbcon_platform_get_rotate(i) FB_ROTATE_UR +#endif /* CONFIG_DMI */ +#endif /* _VIDEO_FBCON_H */ diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c similarity index 98% rename from drivers/video/console/fbcon_ccw.c rename to drivers/video/fbdev/core/fbcon_ccw.c index 5a3cbf6dff4d..37a8b0b22566 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/fbdev/core/fbcon_ccw.c @@ -189,7 +189,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info, } static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, - int bottom_only) + int color, int bottom_only) { unsigned int cw = vc->vc_font.width; unsigned int ch = vc->vc_font.height; @@ -198,7 +198,7 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int bs = vc->vc_rows*ch; struct fb_fillrect region; - region.color = 0; + region.color = color; region.rop = ROP_COPY; if (rw && !bottom_only) { @@ -418,7 +418,3 @@ void fbcon_rotate_ccw(struct fbcon_ops *ops) ops->update_start = ccw_update_start; } EXPORT_SYMBOL(fbcon_rotate_ccw); - -MODULE_AUTHOR("Antonino Daplas "); -MODULE_DESCRIPTION("Console Rotation (270 degrees) Support"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c similarity index 98% rename from drivers/video/console/fbcon_cw.c rename to drivers/video/fbdev/core/fbcon_cw.c index e7ee44db4e98..1888f8c866e8 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/fbdev/core/fbcon_cw.c @@ -172,7 +172,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info, } static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, - int bottom_only) + int color, int bottom_only) { unsigned int cw = vc->vc_font.width; unsigned int ch = vc->vc_font.height; @@ -181,7 +181,7 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int rs = info->var.yres - rw; struct fb_fillrect region; - region.color = 0; + region.color = color; region.rop = ROP_COPY; if (rw && !bottom_only) { @@ -401,7 +401,3 @@ void fbcon_rotate_cw(struct fbcon_ops *ops) ops->update_start = cw_update_start; } EXPORT_SYMBOL(fbcon_rotate_cw); - -MODULE_AUTHOR("Antonino Daplas "); -MODULE_DESCRIPTION("Console Rotation (90 degrees) Support"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/core/fbcon_dmi_quirks.c b/drivers/video/fbdev/core/fbcon_dmi_quirks.c new file mode 100644 index 000000000000..6904e47d1e51 --- /dev/null +++ b/drivers/video/fbdev/core/fbcon_dmi_quirks.c @@ -0,0 +1,145 @@ +/* + * fbcon_dmi_quirks.c -- DMI based quirk detection for fbcon + * + * Copyright (C) 2017 Hans de Goede + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include +#include +#include "fbcon.h" + +/* + * Some x86 clamshell design devices use portrait tablet screens and a display + * engine which cannot rotate in hardware, so we need to rotate the fbcon to + * compensate. Unfortunately these (cheap) devices also typically have quite + * generic DMI data, so we match on a combination of DMI data, screen resolution + * and a list of known BIOS dates to avoid false positives. + */ + +struct fbcon_dmi_rotate_data { + int width; + int height; + const char * const *bios_dates; + int rotate; +}; + +static const struct fbcon_dmi_rotate_data rotate_data_asus_t100ha = { + .width = 800, + .height = 1280, + .rotate = FB_ROTATE_CCW, +}; + +static const struct fbcon_dmi_rotate_data rotate_data_gpd_pocket = { + .width = 1200, + .height = 1920, + .bios_dates = (const char * const []){ "05/26/2017", "06/28/2017", + "07/05/2017", "08/07/2017", NULL }, + .rotate = FB_ROTATE_CW, +}; + +static const struct fbcon_dmi_rotate_data rotate_data_gpd_win = { + .width = 720, + .height = 1280, + .bios_dates = (const char * const []){ + "10/25/2016", "11/18/2016", "12/23/2016", "12/26/2016", + "02/21/2017", "03/20/2017", "05/25/2017", NULL }, + .rotate = FB_ROTATE_CW, +}; + +static const struct fbcon_dmi_rotate_data rotate_data_itworks_tw891 = { + .width = 800, + .height = 1280, + .bios_dates = (const char * const []){ "10/16/2015", NULL }, + .rotate = FB_ROTATE_CW, +}; + +static const struct fbcon_dmi_rotate_data rotate_data_vios_lth17 = { + .width = 800, + .height = 1280, + .rotate = FB_ROTATE_CW, +}; + +static const struct dmi_system_id rotate_data[] = { + { /* Asus T100HA */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"), + }, + .driver_data = (void *)&rotate_data_asus_t100ha, + }, { /* + * GPD Pocket, note that the the DMI data is less generic then + * it seems, devices with a board-vendor of "AMI Corporation" + * are quite rare, as are devices which have both board- *and* + * product-id set to "Default String" + */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), + }, + .driver_data = (void *)&rotate_data_gpd_pocket, + }, { /* GPD Win (same note on DMI match as GPD Pocket) */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), + }, + .driver_data = (void *)&rotate_data_gpd_win, + }, { /* I.T.Works TW891 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"), + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"), + }, + .driver_data = (void *)&rotate_data_itworks_tw891, + }, { /* VIOS LTH17 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "VIOS"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "LTH17"), + }, + .driver_data = (void *)&rotate_data_vios_lth17, + }, + {} +}; + +int fbcon_platform_get_rotate(struct fb_info *info) +{ + const struct dmi_system_id *match; + const struct fbcon_dmi_rotate_data *data; + const char *bios_date; + int i; + + for (match = dmi_first_match(rotate_data); + match; + match = dmi_first_match(match + 1)) { + data = match->driver_data; + + if (data->width != info->var.xres || + data->height != info->var.yres) + continue; + + if (!data->bios_dates) + return data->rotate; + + bios_date = dmi_get_system_info(DMI_BIOS_DATE); + if (!bios_date) + continue; + + for (i = 0; data->bios_dates[i]; i++) { + if (!strcmp(data->bios_dates[i], bios_date)) + return data->rotate; + } + } + + return FB_ROTATE_UR; +} diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c similarity index 95% rename from drivers/video/console/fbcon_rotate.c rename to drivers/video/fbdev/core/fbcon_rotate.c index db6528f2d3f2..8a51e4d95cc5 100644 --- a/drivers/video/console/fbcon_rotate.c +++ b/drivers/video/fbdev/core/fbcon_rotate.c @@ -110,7 +110,3 @@ void fbcon_set_rotate(struct fbcon_ops *ops) } } EXPORT_SYMBOL(fbcon_set_rotate); - -MODULE_AUTHOR("Antonino Daplas "); -MODULE_DESCRIPTION("Console Rotation Support"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/fbdev/core/fbcon_rotate.h similarity index 100% rename from drivers/video/console/fbcon_rotate.h rename to drivers/video/fbdev/core/fbcon_rotate.h diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c similarity index 98% rename from drivers/video/console/fbcon_ud.c rename to drivers/video/fbdev/core/fbcon_ud.c index 19e3714abfe8..f98eee263597 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/fbdev/core/fbcon_ud.c @@ -220,7 +220,7 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info, } static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, - int bottom_only) + int color, int bottom_only) { unsigned int cw = vc->vc_font.width; unsigned int ch = vc->vc_font.height; @@ -228,7 +228,7 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, unsigned int bh = info->var.yres - (vc->vc_rows*ch); struct fb_fillrect region; - region.color = 0; + region.color = color; region.rop = ROP_COPY; if (rw && !bottom_only) { @@ -446,7 +446,3 @@ void fbcon_rotate_ud(struct fbcon_ops *ops) ops->update_start = ud_update_start; } EXPORT_SYMBOL(fbcon_rotate_ud); - -MODULE_AUTHOR("Antonino Daplas "); -MODULE_DESCRIPTION("Console Rotation (180 degrees) Support"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 7a42238db446..f741ba8df01b 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include @@ -315,7 +317,7 @@ static void fb_set_logo(struct fb_info *info, for (i = 0; i < logo->height; i++) { for (j = 0; j < logo->width; src++) { d = *src ^ xor; - for (k = 7; k >= 0; k--) { + for (k = 7; k >= 0 && j < logo->width; k--) { *dst++ = ((d >> k) & 1) ? fg : 0; j++; } @@ -462,7 +464,7 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, /* Return if the frame buffer is not mapped or suspended */ if (logo == NULL || info->state != FBINFO_STATE_RUNNING || - info->flags & FBINFO_MODULE) + info->fbops->owner) return 0; image.depth = 8; @@ -600,7 +602,7 @@ int fb_prepare_logo(struct fb_info *info, int rotate) memset(&fb_logo, 0, sizeof(struct logo_data)); if (info->flags & FBINFO_MISC_TILEBLITTING || - info->flags & FBINFO_MODULE) + info->fbops->owner) return 0; if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { @@ -1396,6 +1398,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) mutex_lock(&info->mm_lock); if (fb->fb_mmap) { int res; + + /* + * The framebuffer needs to be accessed decrypted, be sure + * SME protection is removed ahead of the call + */ + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); res = fb->fb_mmap(info, vma); mutex_unlock(&info->mm_lock); return res; @@ -1421,6 +1429,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) mutex_unlock(&info->mm_lock); vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + /* + * The framebuffer needs to be accessed decrypted, be sure + * SME protection is removed + */ + vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); fb_pgprotect(file, vma, start); return vm_iomap_memory(vma, start, len); @@ -1880,6 +1893,9 @@ fbmem_init(void) fb_class = NULL; goto err_class; } + + fb_console_init(); + return 0; err_class: @@ -1894,6 +1910,8 @@ module_init(fbmem_init); static void __exit fbmem_exit(void) { + fb_console_exit(); + remove_proc_entry("fb", NULL); class_destroy(fb_class); unregister_chrdev(FB_MAJOR, "fb"); diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c index 41d7979d81c5..2b2d67328514 100644 --- a/drivers/video/fbdev/core/fbmon.c +++ b/drivers/video/fbdev/core/fbmon.c @@ -1479,8 +1479,8 @@ int of_get_fb_videomode(struct device_node *np, struct fb_videomode *fb, if (ret) return ret; - pr_debug("%s: got %dx%d display mode from %s\n", - of_node_full_name(np), vm.hactive, vm.vactive, np->name); + pr_debug("%pOF: got %dx%d display mode from %s\n", + np, vm.hactive, vm.vactive, np->name); dump_fb_videomode(fb); return 0; diff --git a/drivers/video/console/softcursor.c b/drivers/video/fbdev/core/softcursor.c similarity index 93% rename from drivers/video/console/softcursor.c rename to drivers/video/fbdev/core/softcursor.c index 46dd8f5d2e9e..fc93f254498e 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/fbdev/core/softcursor.c @@ -76,7 +76,3 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) } EXPORT_SYMBOL(soft_cursor); - -MODULE_AUTHOR("James Simmons "); -MODULE_DESCRIPTION("Generic software cursor"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/console/tileblit.c b/drivers/video/fbdev/core/tileblit.c similarity index 96% rename from drivers/video/console/tileblit.c rename to drivers/video/fbdev/core/tileblit.c index 15e8e1a89c45..93390312957f 100644 --- a/drivers/video/console/tileblit.c +++ b/drivers/video/fbdev/core/tileblit.c @@ -74,7 +74,7 @@ static void tile_putcs(struct vc_data *vc, struct fb_info *info, } static void tile_clear_margins(struct vc_data *vc, struct fb_info *info, - int bottom_only) + int color, int bottom_only) { return; } @@ -152,8 +152,3 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info) } EXPORT_SYMBOL(fbcon_set_tileops); - -MODULE_AUTHOR("Antonino Daplas "); -MODULE_DESCRIPTION("Tile Blitting Operation"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index 99acf538a8b8..9a5751cb4e16 100644 --- a/drivers/video/fbdev/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -1336,7 +1336,7 @@ static void cyber2000fb_i2c_unregister(struct cfb_info *cfb) * These parameters give * 640x480, hsync 31.5kHz, vsync 60Hz */ -static struct fb_videomode cyber2000fb_default_mode = { +static const struct fb_videomode cyber2000fb_default_mode = { .refresh = 60, .xres = 640, .yres = 480, diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c index c229b1a0d13b..a74096c53cb5 100644 --- a/drivers/video/fbdev/da8xx-fb.c +++ b/drivers/video/fbdev/da8xx-fb.c @@ -1341,7 +1341,7 @@ static int fb_probe(struct platform_device *device) { struct da8xx_lcdc_platform_data *fb_pdata = dev_get_platdata(&device->dev); - static struct resource *lcdc_regs; + struct resource *lcdc_regs; struct lcd_ctrl_config *lcd_cfg; struct fb_videomode *lcdc_info; struct fb_info *da8xx_fb_info; diff --git a/drivers/video/fbdev/dnfb.c b/drivers/video/fbdev/dnfb.c index 3526899da61b..7b1492d34e98 100644 --- a/drivers/video/fbdev/dnfb.c +++ b/drivers/video/fbdev/dnfb.c @@ -126,7 +126,7 @@ struct fb_var_screeninfo dnfb_var = { .vmode = FB_VMODE_NONINTERLACED, }; -static struct fb_fix_screeninfo dnfb_fix = { +static const struct fb_fix_screeninfo dnfb_fix = { .id = "Apollo Mono", .smem_start = (FRAME_BUFFER_START + IO_BASE), .smem_len = FRAME_BUFFER_LEN, diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 1e784adb89b1..d1bf9c2a78a7 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Framebuffer driver for EFI/UEFI based system * @@ -149,6 +150,10 @@ ATTRIBUTE_GROUPS(efifb); static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ +static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ +static struct resource *bar_resource; +static u64 bar_offset; + static int efifb_probe(struct platform_device *dev) { struct fb_info *info; @@ -203,6 +208,13 @@ static int efifb_probe(struct platform_device *dev) efifb_fix.smem_start |= ext_lfb_base; } + if (bar_resource && + bar_resource->start + bar_offset != efifb_fix.smem_start) { + dev_info(&efifb_pci_dev->dev, + "BAR has moved, updating efifb address\n"); + efifb_fix.smem_start = bar_resource->start + bar_offset; + } + efifb_defined.bits_per_pixel = screen_info.lfb_depth; efifb_defined.xres = screen_info.lfb_width; efifb_defined.yres = screen_info.lfb_height; @@ -370,15 +382,13 @@ static struct platform_driver efifb_driver = { builtin_platform_driver(efifb_driver); -#if defined(CONFIG_PCI) && !defined(CONFIG_X86) +#if defined(CONFIG_PCI) -static bool pci_bar_found; /* did we find a BAR matching the efifb base? */ - -static void claim_efifb_bar(struct pci_dev *dev, int idx) +static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset) { u16 word; - pci_bar_found = true; + efifb_pci_dev = dev; pci_read_config_word(dev, PCI_COMMAND, &word); if (!(word & PCI_COMMAND_MEMORY)) { @@ -389,12 +399,8 @@ static void claim_efifb_bar(struct pci_dev *dev, int idx) return; } - if (pci_claim_resource(dev, idx)) { - pci_dev_disabled = true; - dev_err(&dev->dev, - "BAR %d: failed to claim resource for efifb!\n", idx); - return; - } + bar_resource = &dev->resource[idx]; + bar_offset = offset; dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx); } @@ -405,7 +411,7 @@ static void efifb_fixup_resources(struct pci_dev *dev) u64 size = screen_info.lfb_size; int i; - if (pci_bar_found || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) + if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) return; if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) @@ -421,7 +427,7 @@ static void efifb_fixup_resources(struct pci_dev *dev) continue; if (res->start <= base && res->end >= base + size - 1) { - claim_efifb_bar(dev, i); + record_efifb_bar_resource(dev, i, base - res->start); break; } } diff --git a/drivers/video/fbdev/fb-puv3.c b/drivers/video/fbdev/fb-puv3.c index 88fa2e70a0bb..d9e816d53531 100644 --- a/drivers/video/fbdev/fb-puv3.c +++ b/drivers/video/fbdev/fb-puv3.c @@ -69,7 +69,7 @@ static const struct fb_videomode unifb_modes[] = { 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, }; -static struct fb_var_screeninfo unifb_default = { +static const struct fb_var_screeninfo unifb_default = { .xres = 640, .yres = 480, .xres_virtual = 640, diff --git a/drivers/video/fbdev/ffb.c b/drivers/video/fbdev/ffb.c index dda31e0a45af..6b1915872af1 100644 --- a/drivers/video/fbdev/ffb.c +++ b/drivers/video/fbdev/ffb.c @@ -997,9 +997,9 @@ static int ffb_probe(struct platform_device *op) dev_set_drvdata(&op->dev, info); - printk(KERN_INFO "%s: %s at %016lx, type %d, " + printk(KERN_INFO "%pOF: %s at %016lx, type %d, " "DAC pnum[%x] rev[%d] manuf_rev[%d]\n", - dp->full_name, + dp, ((par->flags & FFB_FLAG_AFB) ? "AFB" : "FFB"), par->physbase, par->board_type, dac_pnum, dac_rev, dac_mrev); diff --git a/drivers/video/fbdev/fm2fb.c b/drivers/video/fbdev/fm2fb.c index e69d47af9932..ac7a4ebfd390 100644 --- a/drivers/video/fbdev/fm2fb.c +++ b/drivers/video/fbdev/fm2fb.c @@ -213,7 +213,7 @@ static int fm2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id); -static struct zorro_device_id fm2fb_devices[] = { +static const struct zorro_device_id fm2fb_devices[] = { { ZORRO_PROD_BSC_FRAMEMASTER_II }, { ZORRO_PROD_HELFRICH_RAINBOW_II }, { 0 } diff --git a/drivers/video/fbdev/geode/Makefile b/drivers/video/fbdev/geode/Makefile index 5c98da126883..16ba8a71dc52 100644 --- a/drivers/video/fbdev/geode/Makefile +++ b/drivers/video/fbdev/geode/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Geode family framebuffer drivers obj-$(CONFIG_FB_GEODE_GX1) += gx1fb.o diff --git a/drivers/video/fbdev/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c index ec9fc9ac23de..f4f76373b2a8 100644 --- a/drivers/video/fbdev/geode/gxfb_core.c +++ b/drivers/video/fbdev/geode/gxfb_core.c @@ -474,7 +474,7 @@ static void gxfb_remove(struct pci_dev *pdev) framebuffer_release(info); } -static struct pci_device_id gxfb_id_table[] = { +static const struct pci_device_id gxfb_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_GX_VIDEO) }, { 0, } }; diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c index b471f92969b1..8fc8f46dadeb 100644 --- a/drivers/video/fbdev/grvga.c +++ b/drivers/video/fbdev/grvga.c @@ -70,7 +70,7 @@ static const struct fb_videomode grvga_modedb[] = { } }; -static struct fb_fix_screeninfo grvga_fix = { +static const struct fb_fix_screeninfo grvga_fix = { .id = "AG SVGACTRL", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, diff --git a/drivers/video/fbdev/i810/Makefile b/drivers/video/fbdev/i810/Makefile index 96e08c8ded97..3e466510fe05 100644 --- a/drivers/video/fbdev/i810/Makefile +++ b/drivers/video/fbdev/i810/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the Intel 810/815 framebuffer driver # diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c index 2488baab7c89..d18f7b31932c 100644 --- a/drivers/video/fbdev/i810/i810_main.c +++ b/drivers/video/fbdev/i810/i810_main.c @@ -107,7 +107,7 @@ static const char * const i810_pci_list[] = { "Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device" }; -static struct pci_device_id i810fb_pci_tbl[] = { +static const struct pci_device_id i810fb_pci_tbl[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, @@ -1542,7 +1542,7 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor) return 0; } -static struct fb_ops i810fb_ops = { +static const struct fb_ops i810fb_ops = { .owner = THIS_MODULE, .fb_open = i810fb_open, .fb_release = i810fb_release, diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c index 4363c64d74e8..ecdcf358ad5e 100644 --- a/drivers/video/fbdev/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -1318,7 +1318,7 @@ imsttfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) } } -static struct pci_device_id imsttfb_pci_tbl[] = { +static const struct pci_device_id imsttfb_pci_tbl[] = { { PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, IBM }, { PCI_VENDOR_ID_IMS, PCI_DEVICE_ID_IMS_TT3D, diff --git a/drivers/video/fbdev/intelfb/Makefile b/drivers/video/fbdev/intelfb/Makefile index f7d631ebee8e..7ff2debb31af 100644 --- a/drivers/video/fbdev/intelfb/Makefile +++ b/drivers/video/fbdev/intelfb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_FB_INTEL) += intelfb.o intelfb-y := intelfbdrv.o intelfbhw.o diff --git a/drivers/video/fbdev/intelfb/intelfb.h b/drivers/video/fbdev/intelfb/intelfb.h index 37f8339ea88c..b54db05f028d 100644 --- a/drivers/video/fbdev/intelfb/intelfb.h +++ b/drivers/video/fbdev/intelfb/intelfb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _INTELFB_H #define _INTELFB_H diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c index ffc391208b27..d7463a2a5d83 100644 --- a/drivers/video/fbdev/intelfb/intelfbdrv.c +++ b/drivers/video/fbdev/intelfb/intelfbdrv.c @@ -173,7 +173,7 @@ static int intelfb_set_fbinfo(struct intelfb_info *dinfo); #define INTELFB_CLASS_MASK 0 #endif -static struct pci_device_id intelfb_pci_table[] = { +static const struct pci_device_id intelfb_pci_table[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830M, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_830M }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c index f77478fb3d14..a7bd9f25911b 100644 --- a/drivers/video/fbdev/kyro/fbdev.c +++ b/drivers/video/fbdev/kyro/fbdev.c @@ -633,7 +633,7 @@ static int kyrofb_ioctl(struct fb_info *info, return 0; } -static struct pci_device_id kyrofb_pci_tbl[] = { +static const struct pci_device_id kyrofb_pci_tbl[] = { { PCI_VENDOR_ID_ST, PCI_DEVICE_ID_STG4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } diff --git a/drivers/video/fbdev/leo.c b/drivers/video/fbdev/leo.c index 62e59dc90ee6..71862188f528 100644 --- a/drivers/video/fbdev/leo.c +++ b/drivers/video/fbdev/leo.c @@ -619,8 +619,8 @@ static int leo_probe(struct platform_device *op) dev_set_drvdata(&op->dev, info); - printk(KERN_INFO "%s: leo at %lx:%lx\n", - dp->full_name, + printk(KERN_INFO "%pOF: leo at %lx:%lx\n", + dp, par->which_io, info->fix.smem_start); return 0; diff --git a/drivers/video/fbdev/matrox/g450_pll.h b/drivers/video/fbdev/matrox/g450_pll.h index aac615d18440..5303336c6547 100644 --- a/drivers/video/fbdev/matrox/g450_pll.h +++ b/drivers/video/fbdev/matrox/g450_pll.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __G450_PLL_H__ #define __G450_PLL_H__ diff --git a/drivers/video/fbdev/matrox/matroxfb_DAC1064.h b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h index 1e6e45b57b78..3b2a6fd35fff 100644 --- a/drivers/video/fbdev/matrox/matroxfb_DAC1064.h +++ b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MATROXFB_DAC1064_H__ #define __MATROXFB_DAC1064_H__ diff --git a/drivers/video/fbdev/matrox/matroxfb_Ti3026.h b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h index 27872aaa0a17..faee149d0ba0 100644 --- a/drivers/video/fbdev/matrox/matroxfb_Ti3026.h +++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MATROXFB_TI3026_H__ #define __MATROXFB_TI3026_H__ diff --git a/drivers/video/fbdev/matrox/matroxfb_accel.h b/drivers/video/fbdev/matrox/matroxfb_accel.h index 1e418e62c22d..a7aa9a1d26c0 100644 --- a/drivers/video/fbdev/matrox/matroxfb_accel.h +++ b/drivers/video/fbdev/matrox/matroxfb_accel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MATROXFB_ACCEL_H__ #define __MATROXFB_ACCEL_H__ diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c index f6a0b9af97a9..b9b284d79631 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.c +++ b/drivers/video/fbdev/matrox/matroxfb_base.c @@ -1198,7 +1198,7 @@ static int matroxfb_blank(int blank, struct fb_info *info) return 0; } -static struct fb_ops matroxfb_ops = { +static const struct fb_ops matroxfb_ops = { .owner = THIS_MODULE, .fb_open = matroxfb_open, .fb_release = matroxfb_release, @@ -1573,14 +1573,14 @@ static struct board { NULL}}; #ifndef MODULE -static struct fb_videomode defaultmode = { +static const struct fb_videomode defaultmode = { /* 640x480 @ 60Hz, 31.5 kHz */ NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED }; -#endif /* !MODULE */ static int hotplug = 0; +#endif /* !MODULE */ static void setDefaultOutputs(struct matrox_fb_info *minfo) { @@ -1623,7 +1623,7 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b) unsigned int memsize; int err; - static struct pci_device_id intel_82437[] = { + static const struct pci_device_id intel_82437[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437) }, { }, }; @@ -1794,9 +1794,7 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b) minfo->fbops = matroxfb_ops; minfo->fbcon.fbops = &minfo->fbops; minfo->fbcon.pseudo_palette = minfo->cmap; - /* after __init time we are like module... no logo */ - minfo->fbcon.flags = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT; - minfo->fbcon.flags |= FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */ + minfo->fbcon.flags = FBINFO_PARTIAL_PAN_OK | /* Prefer panning for scroll under MC viewer/edit */ FBINFO_HWACCEL_COPYAREA | /* We have hw-assisted bmove */ FBINFO_HWACCEL_FILLRECT | /* And fillrect */ FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */ @@ -2116,7 +2114,7 @@ static void pci_remove_matrox(struct pci_dev* pdev) { matroxfb_remove(minfo, 1); } -static struct pci_device_id matroxfb_devices[] = { +static const struct pci_device_id matroxfb_devices[] = { #ifdef CONFIG_FB_MATROX_MILLENIUM {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, diff --git a/drivers/video/fbdev/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h index 7a90ea2c4613..f85ad25659e5 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.h +++ b/drivers/video/fbdev/matrox/matroxfb_base.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450 diff --git a/drivers/video/fbdev/matrox/matroxfb_crtc2.h b/drivers/video/fbdev/matrox/matroxfb_crtc2.h index 1005582e843e..23e90e210905 100644 --- a/drivers/video/fbdev/matrox/matroxfb_crtc2.h +++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MATROXFB_CRTC2_H__ #define __MATROXFB_CRTC2_H__ diff --git a/drivers/video/fbdev/matrox/matroxfb_g450.h b/drivers/video/fbdev/matrox/matroxfb_g450.h index 3a3e654444b8..b5f17b86eae5 100644 --- a/drivers/video/fbdev/matrox/matroxfb_g450.h +++ b/drivers/video/fbdev/matrox/matroxfb_g450.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MATROXFB_G450_H__ #define __MATROXFB_G450_H__ diff --git a/drivers/video/fbdev/matrox/matroxfb_maven.h b/drivers/video/fbdev/matrox/matroxfb_maven.h index 99eddec9f30c..f896b78836b1 100644 --- a/drivers/video/fbdev/matrox/matroxfb_maven.h +++ b/drivers/video/fbdev/matrox/matroxfb_maven.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MATROXFB_MAVEN_H__ #define __MATROXFB_MAVEN_H__ diff --git a/drivers/video/fbdev/matrox/matroxfb_misc.h b/drivers/video/fbdev/matrox/matroxfb_misc.h index 351c823f1f74..9cb6686d309e 100644 --- a/drivers/video/fbdev/matrox/matroxfb_misc.h +++ b/drivers/video/fbdev/matrox/matroxfb_misc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MATROXFB_MISC_H__ #define __MATROXFB_MISC_H__ diff --git a/drivers/video/fbdev/maxinefb.c b/drivers/video/fbdev/maxinefb.c index cab7333208ea..5bb1b5c308a7 100644 --- a/drivers/video/fbdev/maxinefb.c +++ b/drivers/video/fbdev/maxinefb.c @@ -39,7 +39,7 @@ static struct fb_info fb_info; -static struct fb_var_screeninfo maxinefb_defined = { +static const struct fb_var_screeninfo maxinefb_defined = { .xres = 1024, .yres = 768, .xres_virtual = 1024, diff --git a/drivers/video/fbdev/mb862xx/mb862xx_reg.h b/drivers/video/fbdev/mb862xx/mb862xx_reg.h index 9df48b8edc94..e6d0513958c2 100644 --- a/drivers/video/fbdev/mb862xx/mb862xx_reg.h +++ b/drivers/video/fbdev/mb862xx/mb862xx_reg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Fujitsu MB862xx Graphics Controller Registers/Bits */ diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb.h b/drivers/video/fbdev/mb862xx/mb862xxfb.h index 8550630c1e01..50bc9b584ca1 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfb.h +++ b/drivers/video/fbdev/mb862xx/mb862xxfb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MB862XX_H__ #define __MB862XX_H__ diff --git a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h index 96a2dfef0f60..3a2549f9a48f 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h +++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __MB826XXFB_ACCEL_H__ #define __MB826XXFB_ACCEL_H__ diff --git a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c index f9ec5c0484fa..cd372527c9e4 100644 --- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c @@ -982,7 +982,7 @@ static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par) #define CHIP_ID(id) \ { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) } -static struct pci_device_id mb862xx_pci_tbl[] = { +static const struct pci_device_id mb862xx_pci_tbl[] = { /* MB86295/MB86296 */ CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP), CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA), diff --git a/drivers/video/fbdev/mbx/mbxdebugfs.c b/drivers/video/fbdev/mbx/mbxdebugfs.c index 2528d3e609a4..2bd328883178 100644 --- a/drivers/video/fbdev/mbx/mbxdebugfs.c +++ b/drivers/video/fbdev/mbx/mbxdebugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/drivers/video/fbdev/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c index 698df9543e30..539b85da0897 100644 --- a/drivers/video/fbdev/mbx/mbxfb.c +++ b/drivers/video/fbdev/mbx/mbxfb.c @@ -79,7 +79,7 @@ struct mbxfb_info { }; -static struct fb_var_screeninfo mbxfb_default = { +static const struct fb_var_screeninfo mbxfb_default = { .xres = 640, .yres = 480, .xres_virtual = 640, @@ -102,7 +102,7 @@ static struct fb_var_screeninfo mbxfb_default = { .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, }; -static struct fb_fix_screeninfo mbxfb_fix = { +static const struct fb_fix_screeninfo mbxfb_fix = { .id = "MBX", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, diff --git a/drivers/video/fbdev/mbx/reg_bits.h b/drivers/video/fbdev/mbx/reg_bits.h index 5f14b4befd71..6607f353639b 100644 --- a/drivers/video/fbdev/mbx/reg_bits.h +++ b/drivers/video/fbdev/mbx/reg_bits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __REG_BITS_2700G_ #define __REG_BITS_2700G_ diff --git a/drivers/video/fbdev/mbx/regs.h b/drivers/video/fbdev/mbx/regs.h index 063099d48839..591fc9d26084 100644 --- a/drivers/video/fbdev/mbx/regs.h +++ b/drivers/video/fbdev/mbx/regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __REGS_2700G_ #define __REGS_2700G_ diff --git a/drivers/video/fbdev/mmp/panel/Kconfig b/drivers/video/fbdev/mmp/panel/Kconfig index 4b2c4f457b11..808890f7064b 100644 --- a/drivers/video/fbdev/mmp/panel/Kconfig +++ b/drivers/video/fbdev/mmp/panel/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config MMP_PANEL_TPOHVGA bool "tpohvga panel TJ032MD01BW support" depends on SPI_MASTER diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c index db023a97d1ea..5d3a444083f7 100644 --- a/drivers/video/fbdev/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -2138,7 +2138,7 @@ static void neofb_remove(struct pci_dev *dev) } } -static struct pci_device_id neofb_devices[] = { +static const struct pci_device_id neofb_devices[] = { {PCI_VENDOR_ID_NEOMAGIC, PCI_CHIP_NM2070, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_NEOMAGIC_NM2070}, diff --git a/drivers/video/fbdev/nvidia/Makefile b/drivers/video/fbdev/nvidia/Makefile index 917d3eb05feb..cdd6e8ac454a 100644 --- a/drivers/video/fbdev/nvidia/Makefile +++ b/drivers/video/fbdev/nvidia/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the nVidia framebuffer driver # diff --git a/drivers/video/fbdev/nvidia/nv_proto.h b/drivers/video/fbdev/nvidia/nv_proto.h index 878a5ce02299..fb9c5ebf2958 100644 --- a/drivers/video/fbdev/nvidia/nv_proto.h +++ b/drivers/video/fbdev/nvidia/nv_proto.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h,v 1.10 2003/07/31 20:24:29 mvojkovi Exp $ */ #ifndef __NV_PROTO_H__ diff --git a/drivers/video/fbdev/nvidia/nv_type.h b/drivers/video/fbdev/nvidia/nv_type.h index 6ff321a36813..d7a1d4363d5f 100644 --- a/drivers/video/fbdev/nvidia/nv_type.h +++ b/drivers/video/fbdev/nvidia/nv_type.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __NV_TYPE_H__ #define __NV_TYPE_H__ diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index ce7dab7299fe..418a2d0d06a9 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -55,7 +55,7 @@ /* HW cursor parameters */ #define MAX_CURS 32 -static struct pci_device_id nvidiafb_pci_tbl[] = { +static const struct pci_device_id nvidiafb_pci_tbl[] = { {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0}, { 0, } diff --git a/drivers/video/fbdev/offb.c b/drivers/video/fbdev/offb.c index 9be884b0c778..90d38de34479 100644 --- a/drivers/video/fbdev/offb.c +++ b/drivers/video/fbdev/offb.c @@ -383,7 +383,7 @@ static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dp FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR; } -static void __init offb_init_fb(const char *name, const char *full_name, +static void __init offb_init_fb(const char *name, int width, int height, int depth, int pitch, unsigned long address, int foreign_endian, struct device_node *dp) @@ -402,14 +402,13 @@ static void __init offb_init_fb(const char *name, const char *full_name, "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", width, height, name, address, depth, pitch); if (depth != 8 && depth != 15 && depth != 16 && depth != 32) { - printk(KERN_ERR "%s: can't use depth = %d\n", full_name, - depth); + printk(KERN_ERR "%pOF: can't use depth = %d\n", dp, depth); release_mem_region(res_start, res_size); return; } info = framebuffer_alloc(sizeof(u32) * 16, NULL); - + if (info == 0) { release_mem_region(res_start, res_size); return; @@ -515,7 +514,7 @@ static void __init offb_init_fb(const char *name, const char *full_name, if (register_framebuffer(info) < 0) goto out_err; - fb_info(info, "Open Firmware frame buffer device on %s\n", full_name); + fb_info(info, "Open Firmware frame buffer device on %pOF\n", dp); return; out_err: @@ -644,7 +643,6 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) if (strcmp(dp->name, "valkyrie") == 0) address += 0x1000; offb_init_fb(no_real_node ? "bootx" : dp->name, - no_real_node ? "display" : dp->full_name, width, height, depth, pitch, address, foreign_endian, no_real_node ? NULL : dp); } diff --git a/drivers/video/fbdev/omap/Makefile b/drivers/video/fbdev/omap/Makefile index 732e0718be53..daaa73a94e7f 100644 --- a/drivers/video/fbdev/omap/Makefile +++ b/drivers/video/fbdev/omap/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the OMAP1 framebuffer device driver # diff --git a/drivers/video/fbdev/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c index 9d2da146813e..796f4634c4c6 100644 --- a/drivers/video/fbdev/omap/lcd_h3.c +++ b/drivers/video/fbdev/omap/lcd_h3.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include "omapfb.h" diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c index df9e6ebcfad5..e3a85432f926 100644 --- a/drivers/video/fbdev/omap/lcd_mipid.c +++ b/drivers/video/fbdev/omap/lcd_mipid.c @@ -496,7 +496,7 @@ static void mipid_cleanup(struct lcd_panel *panel) mipid_esd_stop_check(md); } -static struct lcd_panel mipid_panel = { +static const struct lcd_panel mipid_panel = { .config = OMAP_LCDC_PANEL_TFT, .bpp = 16, diff --git a/drivers/video/fbdev/omap/lcdc.h b/drivers/video/fbdev/omap/lcdc.h index 845222270db3..8a7607d861c1 100644 --- a/drivers/video/fbdev/omap/lcdc.h +++ b/drivers/video/fbdev/omap/lcdc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LCDC_H #define LCDC_H diff --git a/drivers/video/fbdev/omap2/omapfb/Makefile b/drivers/video/fbdev/omap2/omapfb/Makefile index ad68ecf141af..602edfed09df 100644 --- a/drivers/video/fbdev/omap2/omapfb/Makefile +++ b/drivers/video/fbdev/omap2/omapfb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_OMAP2_VRFB) += vrfb.o obj-y += dss/ obj-y += displays/ diff --git a/drivers/video/fbdev/omap2/omapfb/displays/Makefile b/drivers/video/fbdev/omap2/omapfb/displays/Makefile index 4f7459272256..f801762ce455 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/Makefile +++ b/drivers/video/fbdev/omap2/omapfb/displays/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_FB_OMAP2_ENCODER_OPA362) += encoder-opa362.o obj-$(CONFIG_FB_OMAP2_ENCODER_TFP410) += encoder-tfp410.o obj-$(CONFIG_FB_OMAP2_ENCODER_TPD12S015) += encoder-tpd12s015.o diff --git a/drivers/video/fbdev/omap2/omapfb/displays/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/omapfb/displays/panel-lgphilips-lb035q02.c index f14691ce8d02..6cd759c01037 100644 --- a/drivers/video/fbdev/omap2/omapfb/displays/panel-lgphilips-lb035q02.c +++ b/drivers/video/fbdev/omap2/omapfb/displays/panel-lgphilips-lb035q02.c @@ -18,7 +18,7 @@ #include

    Don't walk tree starting at . + --dont-parse= Don't parse . + -d, --debug Display debugging output. + -h, --help, --version Display this help and exit. + +If an absolute path is passed to --dont_XXX then this path is skipped. If a +single filename is passed then this file/directory will be skipped when +appearing under any subdirectory. + +Example: + + # Just scan dmesg output. + scripts/leaking_addresses.pl --dont_walk_abs /proc --dont_walk_abs /sys + +Scans the running (64 bit) kernel for potential leaking addresses. + +EOM + exit($exitcode); +} + +GetOptions( + 'dont-walk=s' => \@dont_walk, + 'dont-parse=s' => \@dont_parse, + 'd|debug' => \$debug, + 'h|help' => \$help, + 'version' => \$help +) or help(1); + +help(0) if ($help); + +push_to_global(); + +parse_dmesg(); +walk(@DIRS); + +exit 0; + +sub debug_arrays +{ + print 'dirs_any: ' . join(", ", @skip_walk_dirs_any) . "\n"; + print 'dirs_abs: ' . join(", ", @skip_walk_dirs_abs) . "\n"; + print 'parse_any: ' . join(", ", @skip_parse_files_any) . "\n"; + print 'parse_abs: ' . join(", ", @skip_parse_files_abs) . "\n"; +} + +sub dprint +{ + printf(STDERR @_) if $debug; +} + +sub push_in_abs_any +{ + my ($in, $abs, $any) = @_; + + foreach my $path (@$in) { + if (File::Spec->file_name_is_absolute($path)) { + push @$abs, $path; + } elsif (index($path,'/') == -1) { + push @$any, $path; + } else { + print 'path error: ' . $path; + } + } +} + +# Push command line options to global arrays. +sub push_to_global +{ + push_in_abs_any(\@dont_walk, \@skip_walk_dirs_abs, \@skip_walk_dirs_any); + push_in_abs_any(\@dont_parse, \@skip_parse_files_abs, \@skip_parse_files_any); +} + +sub is_false_positive +{ + my ($match) = @_; + + if ($match =~ '\b(0x)?(f|F){16}\b' or + $match =~ '\b(0x)?0{16}\b') { + return 1; + } + + # vsyscall memory region, we should probably check against a range here. + if ($match =~ '\bf{10}600000\b' or + $match =~ '\bf{10}601000\b') { + return 1; + } + + return 0; +} + +# True if argument potentially contains a kernel address. +sub may_leak_address +{ + my ($line) = @_; + my $address = '\b(0x)?ffff[[:xdigit:]]{12}\b'; + + # Signal masks. + if ($line =~ '^SigBlk:' or + $line =~ '^SigCgt:') { + return 0; + } + + if ($line =~ '\bKEY=[[:xdigit:]]{14} [[:xdigit:]]{16} [[:xdigit:]]{16}\b' or + $line =~ '\b[[:xdigit:]]{14} [[:xdigit:]]{16} [[:xdigit:]]{16}\b') { + return 0; + } + + while (/($address)/g) { + if (!is_false_positive($1)) { + return 1; + } + } + + return 0; +} + +sub parse_dmesg +{ + open my $cmd, '-|', 'dmesg'; + while (<$cmd>) { + if (may_leak_address($_)) { + print 'dmesg: ' . $_; + } + } + close $cmd; +} + +# True if we should skip this path. +sub skip +{ + my ($path, $paths_abs, $paths_any) = @_; + + foreach (@$paths_abs) { + return 1 if (/^$path$/); + } + + my($filename, $dirs, $suffix) = fileparse($path); + foreach (@$paths_any) { + return 1 if (/^$filename$/); + } + + return 0; +} + +sub skip_parse +{ + my ($path) = @_; + return skip($path, \@skip_parse_files_abs, \@skip_parse_files_any); +} + +sub parse_file +{ + my ($file) = @_; + + if (! -R $file) { + return; + } + + if (skip_parse($file)) { + dprint "skipping file: $file\n"; + return; + } + dprint "parsing: $file\n"; + + open my $fh, "<", $file or return; + while ( <$fh> ) { + if (may_leak_address($_)) { + print $file . ': ' . $_; + } + } + close $fh; +} + + +# True if we should skip walking this directory. +sub skip_walk +{ + my ($path) = @_; + return skip($path, \@skip_walk_dirs_abs, \@skip_walk_dirs_any) +} + +# Recursively walk directory tree. +sub walk +{ + my @dirs = @_; + my %seen; + + while (my $pwd = shift @dirs) { + next if (skip_walk($pwd)); + next if (!opendir(DIR, $pwd)); + my @files = readdir(DIR); + closedir(DIR); + + foreach my $file (@files) { + next if ($file eq '.' or $file eq '..'); + + my $path = "$pwd/$file"; + next if (-l $path); + + if (-d $path) { + push @dirs, $path; + } else { + parse_file($path); + } + } + } +} diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index e7b7eee31538..e6818b8e7141 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # # link vmlinux # diff --git a/scripts/makelst b/scripts/makelst index e6581496d820..e432af073a65 100755 --- a/scripts/makelst +++ b/scripts/makelst @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # A script to dump mixed source code & assembly # with correct relocations from System.map # Requires the following lines in makefile: diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index fd8fdb91581d..959199c3147e 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 TARGET=$1 ARCH=$2 diff --git a/scripts/mkmakefile b/scripts/mkmakefile index 84af27bf0f99..e19d6565f245 100755 --- a/scripts/mkmakefile +++ b/scripts/mkmakefile @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # Generates a small Makefile used in the root of the output # directory, to allow make to be started from there. # The Makefile also allow for more convinient build of external modules diff --git a/scripts/mkuboot.sh b/scripts/mkuboot.sh index 446739c7843a..4b1fe09e9042 100755 --- a/scripts/mkuboot.sh +++ b/scripts/mkuboot.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 # # Build U-Boot image when `mkimage' tool is available. diff --git a/scripts/mkversion b/scripts/mkversion deleted file mode 100644 index c12addc9c7ef..000000000000 --- a/scripts/mkversion +++ /dev/null @@ -1,6 +0,0 @@ -if [ ! -f .version ] -then - echo 1 -else - expr 0`cat .version` + 1 -fi diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index b497d9764dcf..42c5d50f2bcc 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 OBJECT_FILES_NON_STANDARD := y hostprogs-y := modpost mk_elfconfig diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index e4d90e50f6fe..6d0193a3c591 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index a4fd71d71d65..680eade89be1 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 48397feb08fb..98314b400a95 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -47,6 +47,12 @@ enum export { export_unused_gpl, export_gpl_future, export_unknown }; +/* In kernel, this size is defined in linux/module.h; + * here we use Elf_Addr instead of long for covering cross-compile + */ + +#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr)) + #define PRINTF __attribute__ ((format (printf, 1, 2))) PRINTF void fatal(const char *fmt, ...) @@ -261,7 +267,17 @@ static enum export export_no(const char *s) return export_unknown; } -static const char *sec_name(struct elf_info *elf, int secindex); +static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) +{ + return (void *)elf->hdr + + elf->sechdrs[elf->secindex_strings].sh_offset + + sechdr->sh_name; +} + +static const char *sec_name(struct elf_info *elf, int secindex) +{ + return sech_name(elf, &elf->sechdrs[secindex]); +} #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) @@ -775,21 +791,6 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) return "(unknown)"; } -static const char *sec_name(struct elf_info *elf, int secindex) -{ - Elf_Shdr *sechdrs = elf->sechdrs; - return (void *)elf->hdr + - elf->sechdrs[elf->secindex_strings].sh_offset + - sechdrs[secindex].sh_name; -} - -static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr) -{ - return (void *)elf->hdr + - elf->sechdrs[elf->secindex_strings].sh_offset + - sechdr->sh_name; -} - /* The pattern is an array of simple patterns. * "foo" will match an exact string equal to "foo" * "*foo" will match a string that ends with "foo" @@ -2116,6 +2117,23 @@ static void check_exports(struct module *mod) } } +static int check_modname_len(struct module *mod) +{ + const char *mod_name; + + mod_name = strrchr(mod->name, '/'); + if (mod_name == NULL) + mod_name = mod->name; + else + mod_name++; + if (strlen(mod_name) >= MODULE_NAME_LEN) { + merror("module name is too long [%s.ko]\n", mod->name); + return 1; + } + + return 0; +} + /** * Header for the generated file **/ @@ -2155,11 +2173,6 @@ static void add_staging_flag(struct buffer *b, const char *name) buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); } -/* In kernel, this size is defined in linux/module.h; - * here we use Elf_Addr instead of long for covering cross-compile - */ -#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr)) - /** * Record CRCs for unresolved symbols **/ @@ -2490,6 +2503,7 @@ int main(int argc, char **argv) buf.pos = 0; + err |= check_modname_len(mod); add_header(&buf, mod); add_intree_flag(&buf, !external_module); add_staging_flag(&buf, mod->name); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 6a5e1515123b..8453d6ac2f77 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #include #include diff --git a/scripts/package/Makefile b/scripts/package/Makefile index 71b4a8af9d4d..73f9f3192b9f 100644 --- a/scripts/package/Makefile +++ b/scripts/package/Makefile @@ -50,8 +50,6 @@ rpm-pkg rpm: FORCE $(MAKE) clean $(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec $(call cmd,src_tar,$(KERNELPATH),kernel.spec) - $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version - mv -f $(objtree)/.tmp_version $(objtree)/.version rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz rm $(KERNELPATH).tar.gz kernel.spec @@ -60,9 +58,6 @@ rpm-pkg rpm: FORCE binrpm-pkg: FORCE $(MAKE) KBUILD_SRC= $(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec - $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version - mv -f $(objtree)/.tmp_version $(objtree)/.version - rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \ $(UTS_MACHINE) -bb $(objtree)/binkernel.spec rm binkernel.spec diff --git a/scripts/package/builddeb b/scripts/package/builddeb index aad67000e4dd..0bc87473f68f 100755 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -92,12 +92,10 @@ else fi sourcename=$KDEB_SOURCENAME tmpdir="$objtree/debian/tmp" -fwdir="$objtree/debian/fwtmp" kernel_headers_dir="$objtree/debian/hdrtmp" libc_headers_dir="$objtree/debian/headertmp" dbg_dir="$objtree/debian/dbgtmp" packagename=linux-image-$version -fwpackagename=linux-firmware-image-$version kernel_headers_packagename=linux-headers-$version libc_headers_packagename=linux-libc-dev dbg_packagename=$packagename-dbg @@ -126,10 +124,9 @@ esac BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)" # Setup the directory structure -rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files +rm -rf "$tmpdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files mkdir -m 755 -p "$tmpdir/DEBIAN" mkdir -p "$tmpdir/lib" "$tmpdir/boot" -mkdir -p "$fwdir/lib/firmware/$version/" mkdir -p "$kernel_headers_dir/lib/modules/$version/" # Build and install the kernel @@ -306,7 +303,6 @@ else cat <> debian/control Package: $packagename -Suggests: $fwpackagename Architecture: any Description: Linux kernel, version $version This package contains the Linux kernel, modules and corresponding other @@ -345,22 +341,6 @@ Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch} This is useful for people who need to build external modules EOF -# Do we have firmware? Move it out of the way and build it into a package. -if [ -e "$tmpdir/lib/firmware" ]; then - mv "$tmpdir/lib/firmware"/* "$fwdir/lib/firmware/$version/" - rmdir "$tmpdir/lib/firmware" - - cat <> debian/control - -Package: $fwpackagename -Architecture: all -Description: Linux kernel firmware, version $version - This package contains firmware from the Linux kernel, version $version. -EOF - - create_package "$fwpackagename" "$fwdir" -fi - cat <> debian/control Package: $libc_headers_packagename diff --git a/scripts/package/buildtar b/scripts/package/buildtar index e046bff33589..e8cc72a51b32 100755 --- a/scripts/package/buildtar +++ b/scripts/package/buildtar @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # # buildtar 0.0.4 @@ -24,20 +25,19 @@ tarball="${objtree}/linux-${KERNELRELEASE}-${ARCH}.tar" # case "${1}" in tar-pkg) - compress="cat" - file_ext="" + opts= ;; targz-pkg) - compress="gzip" - file_ext=".gz" + opts=--gzip + tarball=${tarball}.gz ;; tarbz2-pkg) - compress="bzip2" - file_ext=".bz2" + opts=--bzip2 + tarball=${tarball}.bz2 ;; tarxz-pkg) - compress="xz" - file_ext=".xz" + opts=--xz + tarball=${tarball}.xz ;; *) echo "Unknown tarball target \"${1}\" requested, please add it to ${0}." >&2 @@ -51,13 +51,14 @@ esac # rm -rf -- "${tmpdir}" mkdir -p -- "${tmpdir}/boot" - +dirs=boot # # Try to install modules # -if grep -q '^CONFIG_MODULES=y' "${objtree}/.config"; then +if grep -q '^CONFIG_MODULES=y' "${KCONFIG_CONFIG}"; then make ARCH="${ARCH}" O="${objtree}" KBUILD_SRC= INSTALL_MOD_PATH="${tmpdir}" modules_install + dirs="$dirs lib" fi @@ -65,7 +66,7 @@ fi # Install basic kernel files # cp -v -- "${objtree}/System.map" "${tmpdir}/boot/System.map-${KERNELRELEASE}" -cp -v -- "${objtree}/.config" "${tmpdir}/boot/config-${KERNELRELEASE}" +cp -v -- "${KCONFIG_CONFIG}" "${tmpdir}/boot/config-${KERNELRELEASE}" cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}" @@ -124,14 +125,12 @@ esac # # Create the tarball # -( - opts= - if tar --owner=root --group=root --help >/dev/null 2>&1; then - opts="--owner=root --group=root" - fi - tar cf - -C "$tmpdir" boot/ lib/ $opts | ${compress} > "${tarball}${file_ext}" -) +if tar --owner=root --group=root --help >/dev/null 2>&1; then + opts="$opts --owner=root --group=root" +fi -echo "Tarball successfully created in ${tarball}${file_ext}" +tar cf $tarball -C $tmpdir $opts $dirs + +echo "Tarball successfully created in $tarball" exit 0 diff --git a/scripts/package/mkspec b/scripts/package/mkspec index bb43f153fd8e..f47f17aae135 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -27,9 +27,7 @@ __KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-/_/g"` echo "Name: kernel" echo "Summary: The Linux Kernel" echo "Version: $__KERNELRELEASE" -# we need to determine the NEXT version number so that uname and -# rpm -q will agree -echo "Release: `. $srctree/scripts/mkversion`" +echo "Release: $(cat .version 2>/dev/null || echo 1)" echo "License: GPL" echo "Group: System Environment/Kernel" echo "Vendor: The Linux Community" @@ -77,7 +75,7 @@ fi echo "%build" if ! $PREBUILT; then -echo "make clean && make %{?_smp_mflags}" +echo "make clean && make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}" echo "" fi @@ -88,11 +86,8 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules' echo "%else" echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules' echo "%endif" -echo 'mkdir -p $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE" -echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= mod-fw= modules_install' -echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE" -echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install +echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install' echo "%ifarch ia64" echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" @@ -119,7 +114,7 @@ if ! $PREBUILT; then echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/build" echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/source" echo "mkdir -p "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE" -echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude=firmware --exclude .config.old --exclude .missing-syscalls.d\"" +echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude .config.old --exclude .missing-syscalls.d\"" echo "tar "'$EXCLUDES'" -cf- . | (cd "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE;tar xvf -)" echo 'cd $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE" echo "ln -sf /usr/src/kernels/$KERNELRELEASE build" @@ -154,7 +149,6 @@ echo '%defattr (-, root, root)' echo "/lib/modules/$KERNELRELEASE" echo "%exclude /lib/modules/$KERNELRELEASE/build" echo "%exclude /lib/modules/$KERNELRELEASE/source" -echo "/lib/firmware/$KERNELRELEASE" echo "/boot/*" echo "" echo "%files headers" diff --git a/scripts/parse-maintainers.pl b/scripts/parse-maintainers.pl index e40b53db7f9f..5dbd2faa2449 100644 --- a/scripts/parse-maintainers.pl +++ b/scripts/parse-maintainers.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl -w +# SPDX-License-Identifier: GPL-2.0 use strict; diff --git a/scripts/patch-kernel b/scripts/patch-kernel index 49b4241e814a..033d5916797d 100755 --- a/scripts/patch-kernel +++ b/scripts/patch-kernel @@ -1,4 +1,5 @@ #! /bin/sh +# SPDX-License-Identifier: GPL-2.0 # Script to apply kernel patches. # usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] # The source directory defaults to /usr/src/linux, and the patch diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl index f23d7be94394..316e71918ac8 100755 --- a/scripts/profile2linkerlist.pl +++ b/scripts/profile2linkerlist.pl @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 # # Takes a (sorted) output of readprofile and turns it into a list suitable for diff --git a/scripts/prune-kernel b/scripts/prune-kernel index ab5034e1d081..e8aa940bc0a9 100755 --- a/scripts/prune-kernel +++ b/scripts/prune-kernel @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 # because I use CONFIG_LOCALVERSION_AUTO, not the same version again and # again, /boot and /lib/modules/ eventually fill up. diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile index 6fc2b8789a0b..e8c533140981 100644 --- a/scripts/selinux/genheaders/Makefile +++ b/scripts/selinux/genheaders/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 hostprogs-y := genheaders HOST_EXTRACFLAGS += \ -I$(srctree)/include/uapi -I$(srctree)/include \ diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c index 6a24569c3578..fa48fabcb330 100644 --- a/scripts/selinux/genheaders/genheaders.c +++ b/scripts/selinux/genheaders/genheaders.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* NOTE: we really do want to use the kernel headers here */ #define __EXPORTED_HEADERS__ @@ -129,11 +130,16 @@ int main(int argc, char *argv[]) for (i = 0; secclass_map[i].name; i++) { struct security_class_mapping *map = &secclass_map[i]; for (j = 0; map->perms[j]; j++) { + if (j >= 32) { + fprintf(stderr, "Too many permissions to fit into an access vector at (%s, %s).\n", + map->name, map->perms[j]); + exit(5); + } fprintf(fout, "#define %s__%s", map->name, map->perms[j]); for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++) fprintf(fout, " "); - fprintf(fout, "0x%08xUL\n", (1< +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +my $virtenv_dir = "sphinx_1.4"; +my $requirement_file = "Documentation/sphinx/requirements.txt"; + +# +# Static vars +# + +my %missing; +my $system_release; +my $need = 0; +my $optional = 0; +my $need_symlink = 0; +my $need_sphinx = 0; +my $install = ""; + +# +# Command line arguments +# + +my $pdf = 1; +my $virtualenv = 1; + +# +# List of required texlive packages on Fedora and OpenSuse +# + +my %texlive = ( + 'amsfonts.sty' => 'texlive-amsfonts', + 'amsmath.sty' => 'texlive-amsmath', + 'amssymb.sty' => 'texlive-amsfonts', + 'amsthm.sty' => 'texlive-amscls', + 'anyfontsize.sty' => 'texlive-anyfontsize', + 'atbegshi.sty' => 'texlive-oberdiek', + 'bm.sty' => 'texlive-tools', + 'capt-of.sty' => 'texlive-capt-of', + 'cmap.sty' => 'texlive-cmap', + 'ecrm1000.tfm' => 'texlive-ec', + 'eqparbox.sty' => 'texlive-eqparbox', + 'eu1enc.def' => 'texlive-euenc', + 'fancybox.sty' => 'texlive-fancybox', + 'fancyvrb.sty' => 'texlive-fancyvrb', + 'float.sty' => 'texlive-float', + 'fncychap.sty' => 'texlive-fncychap', + 'footnote.sty' => 'texlive-mdwtools', + 'framed.sty' => 'texlive-framed', + 'luatex85.sty' => 'texlive-luatex85', + 'multirow.sty' => 'texlive-multirow', + 'needspace.sty' => 'texlive-needspace', + 'palatino.sty' => 'texlive-psnfss', + 'parskip.sty' => 'texlive-parskip', + 'polyglossia.sty' => 'texlive-polyglossia', + 'tabulary.sty' => 'texlive-tabulary', + 'threeparttable.sty' => 'texlive-threeparttable', + 'titlesec.sty' => 'texlive-titlesec', + 'ucs.sty' => 'texlive-ucs', + 'upquote.sty' => 'texlive-upquote', + 'wrapfig.sty' => 'texlive-wrapfig', +); + +# +# Subroutines that checks if a feature exists +# + +sub check_missing(%) +{ + my %map = %{$_[0]}; + + foreach my $prog (sort keys %missing) { + my $is_optional = $missing{$prog}; + + if ($is_optional) { + print "Warning: better to also install \"$prog\".\n"; + } else { + print "ERROR: please install \"$prog\", otherwise, build won't work.\n"; + } + if (defined($map{$prog})) { + $install .= " " . $map{$prog}; + } else { + $install .= " " . $prog; + } + } + + $install =~ s/^\s//; +} + +sub add_package($$) +{ + my $package = shift; + my $is_optional = shift; + + $missing{$package} = $is_optional; + if ($is_optional) { + $optional++; + } else { + $need++; + } +} + +sub check_missing_file($$$) +{ + my $file = shift; + my $package = shift; + my $is_optional = shift; + + return if(-e $file); + + add_package($package, $is_optional); +} + +sub findprog($) +{ + foreach(split(/:/, $ENV{PATH})) { + return "$_/$_[0]" if(-x "$_/$_[0]"); + } +} + +sub check_program($$) +{ + my $prog = shift; + my $is_optional = shift; + + return if findprog($prog); + + add_package($prog, $is_optional); +} + +sub check_perl_module($$) +{ + my $prog = shift; + my $is_optional = shift; + + my $err = system("perl -M$prog -e 1 2>/dev/null /dev/null"); + return if ($err == 0); + + add_package($prog, $is_optional); +} + +sub check_python_module($$) +{ + my $prog = shift; + my $is_optional = shift; + + my $err = system("python3 -c 'import $prog' 2>/dev/null /dev/null"); + return if ($err == 0); + my $err = system("python -c 'import $prog' 2>/dev/null /dev/null"); + return if ($err == 0); + + add_package($prog, $is_optional); +} + +sub check_rpm_missing($$) +{ + my @pkgs = @{$_[0]}; + my $is_optional = $_[1]; + + foreach my $prog(@pkgs) { + my $err = system("rpm -q '$prog' 2>/dev/null >/dev/null"); + add_package($prog, $is_optional) if ($err); + } +} + +sub check_pacman_missing($$) +{ + my @pkgs = @{$_[0]}; + my $is_optional = $_[1]; + + foreach my $prog(@pkgs) { + my $err = system("pacman -Q '$prog' 2>/dev/null >/dev/null"); + add_package($prog, $is_optional) if ($err); + } +} + +sub check_missing_tex($) +{ + my $is_optional = shift; + my $kpsewhich = findprog("kpsewhich"); + + foreach my $prog(keys %texlive) { + my $package = $texlive{$prog}; + if (!$kpsewhich) { + add_package($package, $is_optional); + next; + } + my $file = qx($kpsewhich $prog); + add_package($package, $is_optional) if ($file =~ /^\s*$/); + } +} + +sub check_sphinx() +{ + return if findprog("sphinx-build"); + + if (findprog("sphinx-build-3")) { + $need_symlink = 1; + return; + } + + if ($virtualenv) { + my $prog = findprog("virtualenv-3"); + $prog = findprog("virtualenv-3.5") if (!$prog); + + check_program("virtualenv", 0) if (!$prog); + $need_sphinx = 1; + } else { + add_package("python-sphinx", 0); + } +} + +# +# Ancillary subroutines +# + +sub catcheck($) +{ + my $res = ""; + $res = qx(cat $_[0]) if (-r $_[0]); + return $res; +} + +sub which($) +{ + my $file = shift; + my @path = split ":", $ENV{PATH}; + + foreach my $dir(@path) { + my $name = $dir.'/'.$file; + return $name if (-x $name ); + } + return undef; +} + +# +# Subroutines that check distro-specific hints +# + +sub give_debian_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx-rtd-theme", + "virtualenv" => "virtualenv", + "dot" => "graphviz", + "convert" => "imagemagick", + "Pod::Usage" => "perl-modules", + "xelatex" => "texlive-xetex", + "rsvg-convert" => "librsvg2-bin", + ); + + if ($pdf) { + check_missing_file("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", + "fonts-dejavu", 1); + } + + check_program("dvipng", 1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo apt-get install $install\n"); +} + +sub give_redhat_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx_rtd_theme", + "virtualenv" => "python3-virtualenv", + "dot" => "graphviz", + "convert" => "ImageMagick", + "Pod::Usage" => "perl-Pod-Usage", + "xelatex" => "texlive-xetex-bin", + "rsvg-convert" => "librsvg2-tools", + ); + + my @fedora26_opt_pkgs = ( + "graphviz-gd", # Fedora 26: needed for PDF support + ); + + my @fedora_tex_pkgs = ( + "texlive-collection-fontsrecommended", + "texlive-collection-latex", + "dejavu-sans-fonts", + "dejavu-serif-fonts", + "dejavu-sans-mono-fonts", + ); + + # + # Checks valid for RHEL/CentOS version 7.x. + # + if (! $system_release =~ /Fedora/) { + $map{"virtualenv"} = "python-virtualenv"; + } + + my $release; + + $release = $1 if ($system_release =~ /Fedora\s+release\s+(\d+)/); + + check_rpm_missing(\@fedora26_opt_pkgs, 1) if ($pdf && $release >= 26); + check_rpm_missing(\@fedora_tex_pkgs, 1) if ($pdf); + check_missing_tex(1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + + if ($release >= 18) { + # dnf, for Fedora 18+ + printf("You should run:\n\n\tsudo dnf install -y $install\n"); + } else { + # yum, for RHEL (and clones) or Fedora version < 18 + printf("You should run:\n\n\tsudo yum install -y $install\n"); + } +} + +sub give_opensuse_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx_rtd_theme", + "virtualenv" => "python3-virtualenv", + "dot" => "graphviz", + "convert" => "ImageMagick", + "Pod::Usage" => "perl-Pod-Usage", + "xelatex" => "texlive-xetex-bin", + "rsvg-convert" => "rsvg-view", + ); + + my @suse_tex_pkgs = ( + "texlive-babel-english", + "texlive-caption", + "texlive-colortbl", + "texlive-courier", + "texlive-dvips", + "texlive-helvetic", + "texlive-makeindex", + "texlive-metafont", + "texlive-metapost", + "texlive-palatino", + "texlive-preview", + "texlive-times", + "texlive-zapfchan", + "texlive-zapfding", + ); + + check_rpm_missing(\@suse_tex_pkgs, 1) if ($pdf); + check_missing_tex(1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo zypper install --no-recommends $install\n"); +} + +sub give_mageia_hints() +{ + my %map = ( + "python-sphinx" => "python3-sphinx", + "sphinx_rtd_theme" => "python3-sphinx_rtd_theme", + "virtualenv" => "python3-virtualenv", + "dot" => "graphviz", + "convert" => "ImageMagick", + "Pod::Usage" => "perl-Pod-Usage", + "xelatex" => "texlive", + "rsvg-convert" => "librsvg2-tools", + ); + + my @tex_pkgs = ( + "texlive-fontsextra", + ); + + check_rpm_missing(\@tex_pkgs, 1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo urpmi $install\n"); +} + +sub give_arch_linux_hints() +{ + my %map = ( + "sphinx_rtd_theme" => "python-sphinx_rtd_theme", + "virtualenv" => "python-virtualenv", + "dot" => "graphviz", + "convert" => "imagemagick", + "xelatex" => "texlive-bin", + "rsvg-convert" => "extra/librsvg", + ); + + my @archlinux_tex_pkgs = ( + "texlive-core", + "texlive-latexextra", + "ttf-dejavu", + ); + check_pacman_missing(\@archlinux_tex_pkgs, 1) if ($pdf); + check_missing(\%map); + + return if (!$need && !$optional); + printf("You should run:\n\n\tsudo pacman -S $install\n"); +} + +sub give_gentoo_hints() +{ + my %map = ( + "sphinx_rtd_theme" => "dev-python/sphinx_rtd_theme", + "virtualenv" => "dev-python/virtualenv", + "dot" => "media-gfx/graphviz", + "convert" => "media-gfx/imagemagick", + "xelatex" => "dev-texlive/texlive-xetex media-fonts/dejavu", + "rsvg-convert" => "gnome-base/librsvg", + ); + + check_missing_file("/usr/share/fonts/dejavu/DejaVuSans.ttf", + "media-fonts/dejavu", 1) if ($pdf); + + check_missing(\%map); + + return if (!$need && !$optional); + + printf("You should run:\n\n"); + printf("\tsudo su -c 'echo \"media-gfx/imagemagick svg png\" > /etc/portage/package.use/imagemagick'\n"); + printf("\tsudo su -c 'echo \"media-gfx/graphviz cairo pdf\" > /etc/portage/package.use/graphviz'\n"); + printf("\tsudo emerge --ask $install\n"); + +} + +sub check_distros() +{ + # Distro-specific hints + if ($system_release =~ /Red Hat Enterprise Linux/) { + give_redhat_hints; + return; + } + if ($system_release =~ /CentOS/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Scientific Linux/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Oracle Linux Server/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Fedora/) { + give_redhat_hints; + return; + } + if ($system_release =~ /Ubuntu/) { + give_debian_hints; + return; + } + if ($system_release =~ /Debian/) { + give_debian_hints; + return; + } + if ($system_release =~ /openSUSE/) { + give_opensuse_hints; + return; + } + if ($system_release =~ /Mageia/) { + give_mageia_hints; + return; + } + if ($system_release =~ /Arch Linux/) { + give_arch_linux_hints; + return; + } + if ($system_release =~ /Gentoo/) { + give_gentoo_hints; + return; + } + + # + # Fall-back to generic hint code for other distros + # That's far from ideal, specially for LaTeX dependencies. + # + my %map = ( + "sphinx-build" => "sphinx" + ); + check_missing_tex(1) if ($pdf); + check_missing(\%map); + print "I don't know distro $system_release.\n"; + print "So, I can't provide you a hint with the install procedure.\n"; + print "There are likely missing dependencies.\n"; +} + +# +# Common dependencies +# + +sub check_needs() +{ + if ($system_release) { + print "Detected OS: $system_release.\n"; + } else { + print "Unknown OS\n"; + } + + # RHEL 7.x and clones have Sphinx version 1.1.x and incomplete texlive + if (($system_release =~ /Red Hat Enterprise Linux/) || + ($system_release =~ /CentOS/) || + ($system_release =~ /Scientific Linux/) || + ($system_release =~ /Oracle Linux Server/)) { + $virtualenv = 1; + $pdf = 0; + + printf("NOTE: On this distro, Sphinx and TexLive shipped versions are incompatible\n"); + printf("with doc build. So, use Sphinx via a Python virtual environment.\n\n"); + printf("This script can't install a TexLive version that would provide PDF.\n"); + } + + # Check for needed programs/tools + check_sphinx(); + check_perl_module("Pod::Usage", 0); + check_program("make", 0); + check_program("gcc", 0); + check_python_module("sphinx_rtd_theme", 1) if (!$virtualenv); + check_program("xelatex", 1) if ($pdf); + check_program("dot", 1); + check_program("convert", 1); + check_program("rsvg-convert", 1) if ($pdf); + + check_distros(); + + if ($need_symlink) { + printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n", + which("sphinx-build-3"); + } + if ($need_sphinx) { + my $activate = "$virtenv_dir/bin/activate"; + if (-e "$ENV{'PWD'}/$activate") { + printf "\nNeed to activate virtualenv with:\n"; + printf "\t. $activate\n"; + } else { + my $virtualenv = findprog("virtualenv-3"); + $virtualenv = findprog("virtualenv-3.5") if (!$virtualenv); + $virtualenv = findprog("virtualenv") if (!$virtualenv); + $virtualenv = "virtualenv" if (!$virtualenv); + + printf "\t$virtualenv $virtenv_dir\n"; + printf "\t. $activate\n"; + printf "\tpip install -r $requirement_file\n"; + $need++; + } + } + printf "\n"; + + print "All optional dependenties are met.\n" if (!$optional); + + if ($need == 1) { + die "Can't build as $need mandatory dependency is missing"; + } elsif ($need) { + die "Can't build as $need mandatory dependencies are missing"; + } + + print "Needed package dependencies are met.\n"; +} + +# +# Main +# + +while (@ARGV) { + my $arg = shift(@ARGV); + + if ($arg eq "--no-virtualenv") { + $virtualenv = 0; + } elsif ($arg eq "--no-pdf"){ + $pdf = 0; + } else { + print "Usage:\n\t$0 <--no-virtualenv> <--no-pdf>\n\n"; + exit -1; + } +} + +# +# Determine the system type. There's no standard unique way that would +# work with all distros with a minimal package install. So, several +# methods are used here. +# +# By default, it will use lsb_release function. If not available, it will +# fail back to reading the known different places where the distro name +# is stored +# + +$system_release = qx(lsb_release -d) if which("lsb_release"); +$system_release =~ s/Description:\s*// if ($system_release); +$system_release = catcheck("/etc/system-release") if !$system_release; +$system_release = catcheck("/etc/redhat-release") if !$system_release; +$system_release = catcheck("/etc/lsb-release") if !$system_release; +$system_release = catcheck("/etc/gentoo-release") if !$system_release; +$system_release = catcheck("/etc/issue") if !$system_release; +$system_release =~ s/\s+$//; + +check_needs; diff --git a/scripts/stackdelta b/scripts/stackdelta index 20a79f19a111..44d2dfd6216f 100755 --- a/scripts/stackdelta +++ b/scripts/stackdelta @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 # Read two files produced by the stackusage script, and show the # delta between them. diff --git a/scripts/stackusage b/scripts/stackusage index 8cf26640ef8a..56ef1ab670ac 100755 --- a/scripts/stackusage +++ b/scripts/stackusage @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 outfile="" now=`date +%s` diff --git a/scripts/tracing/ftrace-bisect.sh b/scripts/tracing/ftrace-bisect.sh index 9ff8ac5fc53c..926701162bc8 100755 --- a/scripts/tracing/ftrace-bisect.sh +++ b/scripts/tracing/ftrace-bisect.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 # # Here's how to use this: # diff --git a/scripts/ver_linux b/scripts/ver_linux index b51de8a7e2a3..545ec7388eb7 100755 --- a/scripts/ver_linux +++ b/scripts/ver_linux @@ -1,4 +1,5 @@ #!/usr/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 # Before running this script please ensure that your PATH is # typical as you use for compilation/installation. I use # /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may diff --git a/scripts/xen-hypercalls.sh b/scripts/xen-hypercalls.sh index 676d9226814f..f18b00843df3 100644 --- a/scripts/xen-hypercalls.sh +++ b/scripts/xen-hypercalls.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 out="$1" shift in="$@" diff --git a/security/Makefile b/security/Makefile index f2d71cdb8e19..4d2d3782ddef 100644 --- a/security/Makefile +++ b/security/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for the kernel security code # diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile index a16b195274de..9a6b4033d52b 100644 --- a/security/apparmor/Makefile +++ b/security/apparmor/Makefile @@ -1,10 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for AppArmor Linux Security Module # obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o apparmor-y := apparmorfs.o audit.o capability.o context.o ipc.o lib.o match.o \ path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \ - resource.o secid.o file.o policy_ns.o label.o + resource.o secid.o file.o policy_ns.o label.o mount.o apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o clean-files := capability_names.h rlim_names.h diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 853c2ec8e0c9..caaf51dda648 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -32,6 +32,7 @@ #include "include/audit.h" #include "include/context.h" #include "include/crypto.h" +#include "include/ipc.h" #include "include/policy_ns.h" #include "include/label.h" #include "include/policy.h" @@ -248,8 +249,10 @@ static struct dentry *aafs_create(const char *name, umode_t mode, inode_lock(dir); dentry = lookup_one_len(name, parent, strlen(name)); - if (IS_ERR(dentry)) + if (IS_ERR(dentry)) { + error = PTR_ERR(dentry); goto fail_lock; + } if (d_really_is_positive(dentry)) { error = -EEXIST; @@ -1443,6 +1446,10 @@ void __aafs_profile_migrate_dents(struct aa_profile *old, { int i; + AA_BUG(!old); + AA_BUG(!new); + AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock)); + for (i = 0; i < AAFS_PROF_SIZEOF; i++) { new->dents[i] = old->dents[i]; if (new->dents[i]) @@ -1506,6 +1513,9 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent) struct dentry *dent = NULL, *dir; int error; + AA_BUG(!profile); + AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock)); + if (!parent) { struct aa_profile *p; p = aa_deref_parent(profile); @@ -1731,6 +1741,7 @@ void __aafs_ns_rmdir(struct aa_ns *ns) if (!ns) return; + AA_BUG(!mutex_is_locked(&ns->lock)); list_for_each_entry(child, &ns->base.profiles, base.list) __aafs_profile_rmdir(child); @@ -1903,6 +1914,10 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns) { struct aa_ns *parent, *next; + AA_BUG(!root); + AA_BUG(!ns); + AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock)); + /* is next namespace a child */ if (!list_empty(&ns->sub_ns)) { next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list); @@ -1937,6 +1952,9 @@ static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns) static struct aa_profile *__first_profile(struct aa_ns *root, struct aa_ns *ns) { + AA_BUG(!root); + AA_BUG(ns && !mutex_is_locked(&ns->lock)); + for (; ns; ns = __next_ns(root, ns)) { if (!list_empty(&ns->base.profiles)) return list_first_entry(&ns->base.profiles, @@ -1959,6 +1977,8 @@ static struct aa_profile *__next_profile(struct aa_profile *p) struct aa_profile *parent; struct aa_ns *ns = p->ns; + AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock)); + /* is next profile a child */ if (!list_empty(&p->base.profiles)) return list_first_entry(&p->base.profiles, typeof(*p), @@ -2127,6 +2147,11 @@ static struct aa_sfs_entry aa_sfs_entry_ptrace[] = { { } }; +static struct aa_sfs_entry aa_sfs_entry_signal[] = { + AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK), + { } +}; + static struct aa_sfs_entry aa_sfs_entry_domain[] = { AA_SFS_FILE_BOOLEAN("change_hat", 1), AA_SFS_FILE_BOOLEAN("change_hatv", 1), @@ -2151,9 +2176,14 @@ static struct aa_sfs_entry aa_sfs_entry_policy[] = { { } }; +static struct aa_sfs_entry aa_sfs_entry_mount[] = { + AA_SFS_FILE_STRING("mask", "mount umount pivot_root"), + { } +}; + static struct aa_sfs_entry aa_sfs_entry_ns[] = { AA_SFS_FILE_BOOLEAN("profile", 1), - AA_SFS_FILE_BOOLEAN("pivot_root", 1), + AA_SFS_FILE_BOOLEAN("pivot_root", 0), { } }; @@ -2172,22 +2202,24 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = { AA_SFS_DIR("policy", aa_sfs_entry_policy), AA_SFS_DIR("domain", aa_sfs_entry_domain), AA_SFS_DIR("file", aa_sfs_entry_file), + AA_SFS_DIR("mount", aa_sfs_entry_mount), AA_SFS_DIR("namespaces", aa_sfs_entry_ns), AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK), AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit), AA_SFS_DIR("caps", aa_sfs_entry_caps), AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace), + AA_SFS_DIR("signal", aa_sfs_entry_signal), AA_SFS_DIR("query", aa_sfs_entry_query), { } }; static struct aa_sfs_entry aa_sfs_entry_apparmor[] = { - AA_SFS_FILE_FOPS(".access", 0640, &aa_sfs_access), + AA_SFS_FILE_FOPS(".access", 0666, &aa_sfs_access), AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops), AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops), - AA_SFS_FILE_FOPS(".ns_level", 0666, &seq_ns_level_fops), - AA_SFS_FILE_FOPS(".ns_name", 0640, &seq_ns_name_fops), - AA_SFS_FILE_FOPS("profiles", 0440, &aa_sfs_profiles_fops), + AA_SFS_FILE_FOPS(".ns_level", 0444, &seq_ns_level_fops), + AA_SFS_FILE_FOPS(".ns_name", 0444, &seq_ns_name_fops), + AA_SFS_FILE_FOPS("profiles", 0444, &aa_sfs_profiles_fops), AA_SFS_DIR("features", aa_sfs_entry_features), { } }; diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index d0594446ae3f..dd754b7850a8 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -374,8 +374,8 @@ static const char *next_name(int xtype, const char *name) * * Returns: refcounted label, or NULL on failure (MAYBE NULL) */ -static struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, - const char **name) +struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, + const char **name) { struct aa_label *label = NULL; u32 xtype = xindex & AA_X_TYPE_MASK; @@ -758,7 +758,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) file_inode(bprm->file)->i_mode }; - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; ctx = cred_ctx(bprm->cred); @@ -807,7 +807,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) aa_label_printk(new, GFP_ATOMIC); dbg_printk("\n"); } - bprm->unsafe |= AA_SECURE_X_NEEDED; + bprm->secureexec = 1; } if (label->proxy != new->proxy) { @@ -843,23 +843,6 @@ audit: goto done; } -/** - * apparmor_bprm_secureexec - determine if secureexec is needed - * @bprm: binprm for exec (NOT NULL) - * - * Returns: %1 if secureexec is needed else %0 - */ -int apparmor_bprm_secureexec(struct linux_binprm *bprm) -{ - /* the decision to use secure exec is computed in set_creds - * and stored in bprm->unsafe. - */ - if (bprm->unsafe & AA_SECURE_X_NEEDED) - return 1; - - return 0; -} - /* * Functions for self directed profile change */ diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h index aaf893f4e4f5..829082c35faa 100644 --- a/security/apparmor/include/apparmor.h +++ b/security/apparmor/include/apparmor.h @@ -27,7 +27,9 @@ #define AA_CLASS_NET 4 #define AA_CLASS_RLIMITS 5 #define AA_CLASS_DOMAIN 6 +#define AA_CLASS_MOUNT 7 #define AA_CLASS_PTRACE 9 +#define AA_CLASS_SIGNAL 10 #define AA_CLASS_LABEL 16 #define AA_CLASS_LAST AA_CLASS_LABEL diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index c68839a44351..620e81169659 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h @@ -71,6 +71,10 @@ enum audit_type { #define OP_FMPROT "file_mprotect" #define OP_INHERIT "file_inherit" +#define OP_PIVOTROOT "pivotroot" +#define OP_MOUNT "mount" +#define OP_UMOUNT "umount" + #define OP_CREATE "create" #define OP_POST_CREATE "post_create" #define OP_BIND "bind" @@ -86,6 +90,7 @@ enum audit_type { #define OP_SHUTDOWN "socket_shutdown" #define OP_PTRACE "ptrace" +#define OP_SIGNAL "signal" #define OP_EXEC "exec" @@ -122,14 +127,22 @@ struct apparmor_audit_data { } fs; }; struct { - const char *name; - long pos; + struct aa_profile *profile; const char *ns; + long pos; } iface; + int signal; struct { int rlim; unsigned long max; } rlim; + struct { + const char *src_name; + const char *type; + const char *trans; + const char *data; + unsigned long flags; + } mnt; }; }; diff --git a/security/apparmor/include/domain.h b/security/apparmor/include/domain.h index bab5810b6e9a..ac9862ff7cdf 100644 --- a/security/apparmor/include/domain.h +++ b/security/apparmor/include/domain.h @@ -15,6 +15,8 @@ #include #include +#include "label.h" + #ifndef __AA_DOMAIN_H #define __AA_DOMAIN_H @@ -29,8 +31,10 @@ struct aa_domain { #define AA_CHANGE_ONEXEC 4 #define AA_CHANGE_STACK 8 +struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, + const char **name); + int apparmor_bprm_set_creds(struct linux_binprm *bprm); -int apparmor_bprm_secureexec(struct linux_binprm *bprm); void aa_free_domain_entries(struct aa_domain *domain); int aa_change_hat(const char *hats[], int count, u64 token, int flags); diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h index 001e40073ff9..4c2c8ac8842f 100644 --- a/security/apparmor/include/file.h +++ b/security/apparmor/include/file.h @@ -101,9 +101,6 @@ static inline struct aa_label *aa_get_file_label(struct aa_file_ctx *ctx) #define AA_X_INHERIT 0x4000 #define AA_X_UNCONFINED 0x8000 -/* AA_SECURE_X_NEEDED - is passed in the bprm->unsafe field */ -#define AA_SECURE_X_NEEDED 0x8000 - /* need to make conditional which ones are being set */ struct path_cond { kuid_t uid; diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h index 656fdb81c8a0..5ffc218d1e74 100644 --- a/security/apparmor/include/ipc.h +++ b/security/apparmor/include/ipc.h @@ -27,8 +27,14 @@ struct aa_profile; #define AA_PTRACE_PERM_MASK (AA_PTRACE_READ | AA_PTRACE_TRACE | \ AA_MAY_BE_READ | AA_MAY_BE_TRACED) +#define AA_SIGNAL_PERM_MASK (MAY_READ | MAY_WRITE) + +#define AA_SFS_SIG_MASK "hup int quit ill trap abrt bus fpe kill usr1 " \ + "segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \ + "xcpu xfsz vtalrm prof winch io pwr sys emt lost" int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, u32 request); +int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig); #endif /* __AA_IPC_H */ diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h index 9a283b722755..af22dcbbcb8a 100644 --- a/security/apparmor/include/label.h +++ b/security/apparmor/include/label.h @@ -310,6 +310,7 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp); #define FLAG_SHOW_MODE 1 #define FLAG_VIEW_SUBNS 2 #define FLAG_HIDDEN_UNCONFINED 4 +#define FLAG_ABS_ROOT 8 int aa_label_snxprint(char *str, size_t size, struct aa_ns *view, struct aa_label *label, int flags); int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label, diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h new file mode 100644 index 000000000000..25d6067fa6ef --- /dev/null +++ b/security/apparmor/include/mount.h @@ -0,0 +1,54 @@ +/* + * AppArmor security module + * + * This file contains AppArmor file mediation function definitions. + * + * Copyright 2017 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#ifndef __AA_MOUNT_H +#define __AA_MOUNT_H + +#include +#include + +#include "domain.h" +#include "policy.h" + +/* mount perms */ +#define AA_MAY_PIVOTROOT 0x01 +#define AA_MAY_MOUNT 0x02 +#define AA_MAY_UMOUNT 0x04 +#define AA_AUDIT_DATA 0x40 +#define AA_MNT_CONT_MATCH 0x40 + +#define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN) + +int aa_remount(struct aa_label *label, const struct path *path, + unsigned long flags, void *data); + +int aa_bind_mount(struct aa_label *label, const struct path *path, + const char *old_name, unsigned long flags); + + +int aa_mount_change_type(struct aa_label *label, const struct path *path, + unsigned long flags); + +int aa_move_mount(struct aa_label *label, const struct path *path, + const char *old_name); + +int aa_new_mount(struct aa_label *label, const char *dev_name, + const struct path *path, const char *type, unsigned long flags, + void *data); + +int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags); + +int aa_pivotroot(struct aa_label *label, const struct path *old_path, + const struct path *new_path); + +#endif /* __AA_MOUNT_H */ diff --git a/security/apparmor/include/sig_names.h b/security/apparmor/include/sig_names.h new file mode 100644 index 000000000000..92e62fe95292 --- /dev/null +++ b/security/apparmor/include/sig_names.h @@ -0,0 +1,98 @@ +#include + +#define SIGUNKNOWN 0 +#define MAXMAPPED_SIG 35 +/* provide a mapping of arch signal to internal signal # for mediation + * those that are always an alias SIGCLD for SIGCLHD and SIGPOLL for SIGIO + * map to the same entry those that may/or may not get a separate entry + */ +static const int sig_map[MAXMAPPED_SIG] = { + [0] = MAXMAPPED_SIG, /* existence test */ + [SIGHUP] = 1, + [SIGINT] = 2, + [SIGQUIT] = 3, + [SIGILL] = 4, + [SIGTRAP] = 5, /* -, 5, - */ + [SIGABRT] = 6, /* SIGIOT: -, 6, - */ + [SIGBUS] = 7, /* 10, 7, 10 */ + [SIGFPE] = 8, + [SIGKILL] = 9, + [SIGUSR1] = 10, /* 30, 10, 16 */ + [SIGSEGV] = 11, + [SIGUSR2] = 12, /* 31, 12, 17 */ + [SIGPIPE] = 13, + [SIGALRM] = 14, + [SIGTERM] = 15, +#ifdef SIGSTKFLT + [SIGSTKFLT] = 16, /* -, 16, - */ +#endif + [SIGCHLD] = 17, /* 20, 17, 18. SIGCHLD -, -, 18 */ + [SIGCONT] = 18, /* 19, 18, 25 */ + [SIGSTOP] = 19, /* 17, 19, 23 */ + [SIGTSTP] = 20, /* 18, 20, 24 */ + [SIGTTIN] = 21, /* 21, 21, 26 */ + [SIGTTOU] = 22, /* 22, 22, 27 */ + [SIGURG] = 23, /* 16, 23, 21 */ + [SIGXCPU] = 24, /* 24, 24, 30 */ + [SIGXFSZ] = 25, /* 25, 25, 31 */ + [SIGVTALRM] = 26, /* 26, 26, 28 */ + [SIGPROF] = 27, /* 27, 27, 29 */ + [SIGWINCH] = 28, /* 28, 28, 20 */ + [SIGIO] = 29, /* SIGPOLL: 23, 29, 22 */ + [SIGPWR] = 30, /* 29, 30, 19. SIGINFO 29, -, - */ +#ifdef SIGSYS + [SIGSYS] = 31, /* 12, 31, 12. often SIG LOST/UNUSED */ +#endif +#ifdef SIGEMT + [SIGEMT] = 32, /* 7, - , 7 */ +#endif +#if defined(SIGLOST) && SIGPWR != SIGLOST /* sparc */ + [SIGLOST] = 33, /* unused on Linux */ +#endif +#if defined(SIGUNUSED) && \ + defined(SIGLOST) && defined(SIGSYS) && SIGLOST != SIGSYS + [SIGUNUSED] = 34, /* -, 31, - */ +#endif +}; + +/* this table is ordered post sig_map[sig] mapping */ +static const char *const sig_names[MAXMAPPED_SIG + 1] = { + "unknown", + "hup", + "int", + "quit", + "ill", + "trap", + "abrt", + "bus", + "fpe", + "kill", + "usr1", + "segv", + "usr2", + "pipe", + "alrm", + "term", + "stkflt", + "chld", + "cont", + "stop", + "stp", + "ttin", + "ttou", + "urg", + "xcpu", + "xfsz", + "vtalrm", + "prof", + "winch", + "io", + "pwr", + "sys", + "emt", + "lost", + "unused", + + "exists", /* always last existence test mapped to MAXMAPPED_SIG */ +}; + diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c index 11e66b5bbc42..7ca0032e7ba9 100644 --- a/security/apparmor/ipc.c +++ b/security/apparmor/ipc.c @@ -20,6 +20,7 @@ #include "include/context.h" #include "include/policy.h" #include "include/ipc.h" +#include "include/sig_names.h" /** * audit_ptrace_mask - convert mask to permission string @@ -121,3 +122,101 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, } +static inline int map_signal_num(int sig) +{ + if (sig > SIGRTMAX) + return SIGUNKNOWN; + else if (sig >= SIGRTMIN) + return sig - SIGRTMIN + 128; /* rt sigs mapped to 128 */ + else if (sig < MAXMAPPED_SIG) + return sig_map[sig]; + return SIGUNKNOWN; +} + +/** + * audit_file_mask - convert mask to permission string + * @buffer: buffer to write string to (NOT NULL) + * @mask: permission mask to convert + */ +static void audit_signal_mask(struct audit_buffer *ab, u32 mask) +{ + if (mask & MAY_READ) + audit_log_string(ab, "receive"); + if (mask & MAY_WRITE) + audit_log_string(ab, "send"); +} + +/** + * audit_cb - call back for signal specific audit fields + * @ab: audit_buffer (NOT NULL) + * @va: audit struct to audit values of (NOT NULL) + */ +static void audit_signal_cb(struct audit_buffer *ab, void *va) +{ + struct common_audit_data *sa = va; + + if (aad(sa)->request & AA_SIGNAL_PERM_MASK) { + audit_log_format(ab, " requested_mask="); + audit_signal_mask(ab, aad(sa)->request); + if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) { + audit_log_format(ab, " denied_mask="); + audit_signal_mask(ab, aad(sa)->denied); + } + } + if (aad(sa)->signal < MAXMAPPED_SIG) + audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]); + else + audit_log_format(ab, " signal=rtmin+%d", + aad(sa)->signal - 128); + audit_log_format(ab, " peer="); + aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, + FLAGS_NONE, GFP_ATOMIC); +} + +/* TODO: update to handle compound name&name2, conditionals */ +static void profile_match_signal(struct aa_profile *profile, const char *label, + int signal, struct aa_perms *perms) +{ + unsigned int state; + + /* TODO: secondary cache check */ + state = aa_dfa_next(profile->policy.dfa, + profile->policy.start[AA_CLASS_SIGNAL], + signal); + state = aa_dfa_match(profile->policy.dfa, state, label); + aa_compute_perms(profile->policy.dfa, state, perms); +} + +static int profile_signal_perm(struct aa_profile *profile, + struct aa_profile *peer, u32 request, + struct common_audit_data *sa) +{ + struct aa_perms perms; + + if (profile_unconfined(profile) || + !PROFILE_MEDIATES(profile, AA_CLASS_SIGNAL)) + return 0; + + aad(sa)->peer = &peer->label; + profile_match_signal(profile, peer->base.hname, aad(sa)->signal, + &perms); + aa_apply_modes_to_perms(profile, &perms); + return aa_check_perms(profile, &perms, request, sa, audit_signal_cb); +} + +static int aa_signal_cross_perm(struct aa_profile *sender, + struct aa_profile *target, + struct common_audit_data *sa) +{ + return xcheck(profile_signal_perm(sender, target, MAY_WRITE, sa), + profile_signal_perm(target, sender, MAY_READ, sa)); +} + +int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig) +{ + DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_SIGNAL); + + aad(&sa)->signal = map_signal_num(sig); + return xcheck_labels_profiles(sender, target, aa_signal_cross_perm, + &sa); +} diff --git a/security/apparmor/label.c b/security/apparmor/label.c index e052eaba1cf6..c5b99b954580 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c @@ -49,7 +49,7 @@ static void free_proxy(struct aa_proxy *proxy) /* p->label will not updated any more as p is dead */ aa_put_label(rcu_dereference_protected(proxy->label, true)); memset(proxy, 0, sizeof(*proxy)); - proxy->label = (struct aa_label *) PROXY_POISON; + RCU_INIT_POINTER(proxy->label, (struct aa_label *)PROXY_POISON); kfree(proxy); } } @@ -1450,9 +1450,11 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp) * cached label name is present and visible * @label->hname only exists if label is namespace hierachical */ -static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label) +static inline bool use_label_hname(struct aa_ns *ns, struct aa_label *label, + int flags) { - if (label->hname && labels_ns(label) == ns) + if (label->hname && (!ns || labels_ns(label) == ns) && + !(flags & ~FLAG_SHOW_MODE)) return true; return false; @@ -1495,7 +1497,7 @@ static int aa_profile_snxprint(char *str, size_t size, struct aa_ns *view, view = profiles_ns(profile); if (view != profile->ns && - (!prev_ns || (prev_ns && *prev_ns != profile->ns))) { + (!prev_ns || (*prev_ns != profile->ns))) { if (prev_ns) *prev_ns = profile->ns; ns_name = aa_ns_name(view, profile->ns, @@ -1605,8 +1607,13 @@ int aa_label_snxprint(char *str, size_t size, struct aa_ns *ns, AA_BUG(!str && size != 0); AA_BUG(!label); - if (!ns) + if (flags & FLAG_ABS_ROOT) { + ns = root_ns; + len = snprintf(str, size, "="); + update_for_len(total, len, size, str); + } else if (!ns) { ns = labels_ns(label); + } label_for_each(i, label, profile) { if (aa_ns_visible(ns, profile->ns, flags & FLAG_VIEW_SUBNS)) { @@ -1710,10 +1717,8 @@ void aa_label_xaudit(struct audit_buffer *ab, struct aa_ns *ns, AA_BUG(!ab); AA_BUG(!label); - if (!ns) - ns = labels_ns(label); - - if (!use_label_hname(ns, label) || display_mode(ns, label, flags)) { + if (!use_label_hname(ns, label, flags) || + display_mode(ns, label, flags)) { len = aa_label_asxprint(&name, ns, label, flags, gfp); if (len == -1) { AA_DEBUG("label print error"); @@ -1738,10 +1743,7 @@ void aa_label_seq_xprint(struct seq_file *f, struct aa_ns *ns, AA_BUG(!f); AA_BUG(!label); - if (!ns) - ns = labels_ns(label); - - if (!use_label_hname(ns, label)) { + if (!use_label_hname(ns, label, flags)) { char *str; int len; @@ -1764,10 +1766,7 @@ void aa_label_xprintk(struct aa_ns *ns, struct aa_label *label, int flags, { AA_BUG(!label); - if (!ns) - ns = labels_ns(label); - - if (!use_label_hname(ns, label)) { + if (!use_label_hname(ns, label, flags)) { char *str; int len; @@ -1874,6 +1873,9 @@ struct aa_label *aa_label_parse(struct aa_label *base, const char *str, if (*str == '&') str++; } + if (*str == '=') + base = &root_ns->unconfined->label; + error = vec_setup(profile, vec, len, gfp); if (error) return ERR_PTR(error); diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 867bcd154c7e..1346ee5be04f 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -38,6 +38,7 @@ #include "include/policy.h" #include "include/policy_ns.h" #include "include/procattr.h" +#include "include/mount.h" /* Flag indicating whether initialization completed */ int apparmor_initialized; @@ -511,6 +512,65 @@ static int apparmor_file_mprotect(struct vm_area_struct *vma, !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); } +static int apparmor_sb_mount(const char *dev_name, const struct path *path, + const char *type, unsigned long flags, void *data) +{ + struct aa_label *label; + int error = 0; + + /* Discard magic */ + if ((flags & MS_MGC_MSK) == MS_MGC_VAL) + flags &= ~MS_MGC_MSK; + + flags &= ~AA_MS_IGNORE_MASK; + + label = __begin_current_label_crit_section(); + if (!unconfined(label)) { + if (flags & MS_REMOUNT) + error = aa_remount(label, path, flags, data); + else if (flags & MS_BIND) + error = aa_bind_mount(label, path, dev_name, flags); + else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | + MS_UNBINDABLE)) + error = aa_mount_change_type(label, path, flags); + else if (flags & MS_MOVE) + error = aa_move_mount(label, path, dev_name); + else + error = aa_new_mount(label, dev_name, path, type, + flags, data); + } + __end_current_label_crit_section(label); + + return error; +} + +static int apparmor_sb_umount(struct vfsmount *mnt, int flags) +{ + struct aa_label *label; + int error = 0; + + label = __begin_current_label_crit_section(); + if (!unconfined(label)) + error = aa_umount(label, mnt, flags); + __end_current_label_crit_section(label); + + return error; +} + +static int apparmor_sb_pivotroot(const struct path *old_path, + const struct path *new_path) +{ + struct aa_label *label; + int error = 0; + + label = aa_get_current_label(); + if (!unconfined(label)) + error = aa_pivotroot(label, old_path, new_path); + aa_put_label(label); + + return error; +} + static int apparmor_getprocattr(struct task_struct *task, char *name, char **value) { @@ -656,12 +716,36 @@ static int apparmor_task_setrlimit(struct task_struct *task, return error; } +static int apparmor_task_kill(struct task_struct *target, struct siginfo *info, + int sig, u32 secid) +{ + struct aa_label *cl, *tl; + int error; + + if (secid) + /* TODO: after secid to label mapping is done. + * Dealing with USB IO specific behavior + */ + return 0; + cl = __begin_current_label_crit_section(); + tl = aa_get_task_label(target); + error = aa_may_signal(cl, tl, sig); + aa_put_label(tl); + __end_current_label_crit_section(cl); + + return error; +} + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), LSM_HOOK_INIT(capget, apparmor_capget), LSM_HOOK_INIT(capable, apparmor_capable), + LSM_HOOK_INIT(sb_mount, apparmor_sb_mount), + LSM_HOOK_INIT(sb_umount, apparmor_sb_umount), + LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot), + LSM_HOOK_INIT(path_link, apparmor_path_link), LSM_HOOK_INIT(path_unlink, apparmor_path_unlink), LSM_HOOK_INIT(path_symlink, apparmor_path_symlink), @@ -694,9 +778,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_set_creds, apparmor_bprm_set_creds), LSM_HOOK_INIT(bprm_committing_creds, apparmor_bprm_committing_creds), LSM_HOOK_INIT(bprm_committed_creds, apparmor_bprm_committed_creds), - LSM_HOOK_INIT(bprm_secureexec, apparmor_bprm_secureexec), LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), + LSM_HOOK_INIT(task_kill, apparmor_task_kill), }; /* diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c new file mode 100644 index 000000000000..82a64b58041d --- /dev/null +++ b/security/apparmor/mount.c @@ -0,0 +1,696 @@ +/* + * AppArmor security module + * + * This file contains AppArmor mediation of files + * + * Copyright (C) 1998-2008 Novell/SUSE + * Copyright 2009-2017 Canonical Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#include +#include +#include + +#include "include/apparmor.h" +#include "include/audit.h" +#include "include/context.h" +#include "include/domain.h" +#include "include/file.h" +#include "include/match.h" +#include "include/mount.h" +#include "include/path.h" +#include "include/policy.h" + + +static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags) +{ + if (flags & MS_RDONLY) + audit_log_format(ab, "ro"); + else + audit_log_format(ab, "rw"); + if (flags & MS_NOSUID) + audit_log_format(ab, ", nosuid"); + if (flags & MS_NODEV) + audit_log_format(ab, ", nodev"); + if (flags & MS_NOEXEC) + audit_log_format(ab, ", noexec"); + if (flags & MS_SYNCHRONOUS) + audit_log_format(ab, ", sync"); + if (flags & MS_REMOUNT) + audit_log_format(ab, ", remount"); + if (flags & MS_MANDLOCK) + audit_log_format(ab, ", mand"); + if (flags & MS_DIRSYNC) + audit_log_format(ab, ", dirsync"); + if (flags & MS_NOATIME) + audit_log_format(ab, ", noatime"); + if (flags & MS_NODIRATIME) + audit_log_format(ab, ", nodiratime"); + if (flags & MS_BIND) + audit_log_format(ab, flags & MS_REC ? ", rbind" : ", bind"); + if (flags & MS_MOVE) + audit_log_format(ab, ", move"); + if (flags & MS_SILENT) + audit_log_format(ab, ", silent"); + if (flags & MS_POSIXACL) + audit_log_format(ab, ", acl"); + if (flags & MS_UNBINDABLE) + audit_log_format(ab, flags & MS_REC ? ", runbindable" : + ", unbindable"); + if (flags & MS_PRIVATE) + audit_log_format(ab, flags & MS_REC ? ", rprivate" : + ", private"); + if (flags & MS_SLAVE) + audit_log_format(ab, flags & MS_REC ? ", rslave" : + ", slave"); + if (flags & MS_SHARED) + audit_log_format(ab, flags & MS_REC ? ", rshared" : + ", shared"); + if (flags & MS_RELATIME) + audit_log_format(ab, ", relatime"); + if (flags & MS_I_VERSION) + audit_log_format(ab, ", iversion"); + if (flags & MS_STRICTATIME) + audit_log_format(ab, ", strictatime"); + if (flags & MS_NOUSER) + audit_log_format(ab, ", nouser"); +} + +/** + * audit_cb - call back for mount specific audit fields + * @ab: audit_buffer (NOT NULL) + * @va: audit struct to audit values of (NOT NULL) + */ +static void audit_cb(struct audit_buffer *ab, void *va) +{ + struct common_audit_data *sa = va; + + if (aad(sa)->mnt.type) { + audit_log_format(ab, " fstype="); + audit_log_untrustedstring(ab, aad(sa)->mnt.type); + } + if (aad(sa)->mnt.src_name) { + audit_log_format(ab, " srcname="); + audit_log_untrustedstring(ab, aad(sa)->mnt.src_name); + } + if (aad(sa)->mnt.trans) { + audit_log_format(ab, " trans="); + audit_log_untrustedstring(ab, aad(sa)->mnt.trans); + } + if (aad(sa)->mnt.flags) { + audit_log_format(ab, " flags=\""); + audit_mnt_flags(ab, aad(sa)->mnt.flags); + audit_log_format(ab, "\""); + } + if (aad(sa)->mnt.data) { + audit_log_format(ab, " options="); + audit_log_untrustedstring(ab, aad(sa)->mnt.data); + } +} + +/** + * audit_mount - handle the auditing of mount operations + * @profile: the profile being enforced (NOT NULL) + * @op: operation being mediated (NOT NULL) + * @name: name of object being mediated (MAYBE NULL) + * @src_name: src_name of object being mediated (MAYBE_NULL) + * @type: type of filesystem (MAYBE_NULL) + * @trans: name of trans (MAYBE NULL) + * @flags: filesystem idependent mount flags + * @data: filesystem mount flags + * @request: permissions requested + * @perms: the permissions computed for the request (NOT NULL) + * @info: extra information message (MAYBE NULL) + * @error: 0 if operation allowed else failure error code + * + * Returns: %0 or error on failure + */ +static int audit_mount(struct aa_profile *profile, const char *op, + const char *name, const char *src_name, + const char *type, const char *trans, + unsigned long flags, const void *data, u32 request, + struct aa_perms *perms, const char *info, int error) +{ + int audit_type = AUDIT_APPARMOR_AUTO; + DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, op); + + if (likely(!error)) { + u32 mask = perms->audit; + + if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) + mask = 0xffff; + + /* mask off perms that are not being force audited */ + request &= mask; + + if (likely(!request)) + return 0; + audit_type = AUDIT_APPARMOR_AUDIT; + } else { + /* only report permissions that were denied */ + request = request & ~perms->allow; + + if (request & perms->kill) + audit_type = AUDIT_APPARMOR_KILL; + + /* quiet known rejects, assumes quiet and kill do not overlap */ + if ((request & perms->quiet) && + AUDIT_MODE(profile) != AUDIT_NOQUIET && + AUDIT_MODE(profile) != AUDIT_ALL) + request &= ~perms->quiet; + + if (!request) + return error; + } + + aad(&sa)->name = name; + aad(&sa)->mnt.src_name = src_name; + aad(&sa)->mnt.type = type; + aad(&sa)->mnt.trans = trans; + aad(&sa)->mnt.flags = flags; + if (data && (perms->audit & AA_AUDIT_DATA)) + aad(&sa)->mnt.data = data; + aad(&sa)->info = info; + aad(&sa)->error = error; + + return aa_audit(audit_type, profile, &sa, audit_cb); +} + +/** + * match_mnt_flags - Do an ordered match on mount flags + * @dfa: dfa to match against + * @state: state to start in + * @flags: mount flags to match against + * + * Mount flags are encoded as an ordered match. This is done instead of + * checking against a simple bitmask, to allow for logical operations + * on the flags. + * + * Returns: next state after flags match + */ +static unsigned int match_mnt_flags(struct aa_dfa *dfa, unsigned int state, + unsigned long flags) +{ + unsigned int i; + + for (i = 0; i <= 31 ; ++i) { + if ((1 << i) & flags) + state = aa_dfa_next(dfa, state, i + 1); + } + + return state; +} + +/** + * compute_mnt_perms - compute mount permission associated with @state + * @dfa: dfa to match against (NOT NULL) + * @state: state match finished in + * + * Returns: mount permissions + */ +static struct aa_perms compute_mnt_perms(struct aa_dfa *dfa, + unsigned int state) +{ + struct aa_perms perms; + + perms.kill = 0; + perms.allow = dfa_user_allow(dfa, state); + perms.audit = dfa_user_audit(dfa, state); + perms.quiet = dfa_user_quiet(dfa, state); + perms.xindex = dfa_user_xindex(dfa, state); + + return perms; +} + +static const char * const mnt_info_table[] = { + "match succeeded", + "failed mntpnt match", + "failed srcname match", + "failed type match", + "failed flags match", + "failed data match" +}; + +/* + * Returns 0 on success else element that match failed in, this is the + * index into the mnt_info_table above + */ +static int do_match_mnt(struct aa_dfa *dfa, unsigned int start, + const char *mntpnt, const char *devname, + const char *type, unsigned long flags, + void *data, bool binary, struct aa_perms *perms) +{ + unsigned int state; + + AA_BUG(!dfa); + AA_BUG(!perms); + + state = aa_dfa_match(dfa, start, mntpnt); + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 1; + + if (devname) + state = aa_dfa_match(dfa, state, devname); + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 2; + + if (type) + state = aa_dfa_match(dfa, state, type); + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 3; + + state = match_mnt_flags(dfa, state, flags); + if (!state) + return 4; + *perms = compute_mnt_perms(dfa, state); + if (perms->allow & AA_MAY_MOUNT) + return 0; + + /* only match data if not binary and the DFA flags data is expected */ + if (data && !binary && (perms->allow & AA_MNT_CONT_MATCH)) { + state = aa_dfa_null_transition(dfa, state); + if (!state) + return 4; + + state = aa_dfa_match(dfa, state, data); + if (!state) + return 5; + *perms = compute_mnt_perms(dfa, state); + if (perms->allow & AA_MAY_MOUNT) + return 0; + } + + /* failed at end of flags match */ + return 4; +} + + +static int path_flags(struct aa_profile *profile, const struct path *path) +{ + AA_BUG(!profile); + AA_BUG(!path); + + return profile->path_flags | + (S_ISDIR(path->dentry->d_inode->i_mode) ? PATH_IS_DIR : 0); +} + +/** + * match_mnt_path_str - handle path matching for mount + * @profile: the confining profile + * @mntpath: for the mntpnt (NOT NULL) + * @buffer: buffer to be used to lookup mntpath + * @devnme: string for the devname/src_name (MAY BE NULL OR ERRPTR) + * @type: string for the dev type (MAYBE NULL) + * @flags: mount flags to match + * @data: fs mount data (MAYBE NULL) + * @binary: whether @data is binary + * @devinfo: error str if (IS_ERR(@devname)) + * + * Returns: 0 on success else error + */ +static int match_mnt_path_str(struct aa_profile *profile, + const struct path *mntpath, char *buffer, + const char *devname, const char *type, + unsigned long flags, void *data, bool binary, + const char *devinfo) +{ + struct aa_perms perms = { }; + const char *mntpnt = NULL, *info = NULL; + int pos, error; + + AA_BUG(!profile); + AA_BUG(!mntpath); + AA_BUG(!buffer); + + error = aa_path_name(mntpath, path_flags(profile, mntpath), buffer, + &mntpnt, &info, profile->disconnected); + if (error) + goto audit; + if (IS_ERR(devname)) { + error = PTR_ERR(devname); + devname = NULL; + info = devinfo; + goto audit; + } + + error = -EACCES; + pos = do_match_mnt(profile->policy.dfa, + profile->policy.start[AA_CLASS_MOUNT], + mntpnt, devname, type, flags, data, binary, &perms); + if (pos) { + info = mnt_info_table[pos]; + goto audit; + } + error = 0; + +audit: + return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL, + flags, data, AA_MAY_MOUNT, &perms, info, error); +} + +/** + * match_mnt - handle path matching for mount + * @profile: the confining profile + * @mntpath: for the mntpnt (NOT NULL) + * @buffer: buffer to be used to lookup mntpath + * @devpath: path devname/src_name (MAYBE NULL) + * @devbuffer: buffer to be used to lookup devname/src_name + * @type: string for the dev type (MAYBE NULL) + * @flags: mount flags to match + * @data: fs mount data (MAYBE NULL) + * @binary: whether @data is binary + * + * Returns: 0 on success else error + */ +static int match_mnt(struct aa_profile *profile, const struct path *path, + char *buffer, struct path *devpath, char *devbuffer, + const char *type, unsigned long flags, void *data, + bool binary) +{ + const char *devname = NULL, *info = NULL; + int error = -EACCES; + + AA_BUG(!profile); + AA_BUG(devpath && !devbuffer); + + if (devpath) { + error = aa_path_name(devpath, path_flags(profile, devpath), + devbuffer, &devname, &info, + profile->disconnected); + if (error) + devname = ERR_PTR(error); + } + + return match_mnt_path_str(profile, path, buffer, devname, type, flags, + data, binary, info); +} + +int aa_remount(struct aa_label *label, const struct path *path, + unsigned long flags, void *data) +{ + struct aa_profile *profile; + char *buffer = NULL; + bool binary; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + binary = path->dentry->d_sb->s_type->fs_flags & FS_BINARY_MOUNTDATA; + + get_buffers(buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, NULL, NULL, NULL, + flags, data, binary)); + put_buffers(buffer); + + return error; +} + +int aa_bind_mount(struct aa_label *label, const struct path *path, + const char *dev_name, unsigned long flags) +{ + struct aa_profile *profile; + char *buffer = NULL, *old_buffer = NULL; + struct path old_path; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + if (!dev_name || !*dev_name) + return -EINVAL; + + flags &= MS_REC | MS_BIND; + + error = kern_path(dev_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path); + if (error) + return error; + + get_buffers(buffer, old_buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, &old_path, old_buffer, + NULL, flags, NULL, false)); + put_buffers(buffer, old_buffer); + path_put(&old_path); + + return error; +} + +int aa_mount_change_type(struct aa_label *label, const struct path *path, + unsigned long flags) +{ + struct aa_profile *profile; + char *buffer = NULL; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + /* These are the flags allowed by do_change_type() */ + flags &= (MS_REC | MS_SILENT | MS_SHARED | MS_PRIVATE | MS_SLAVE | + MS_UNBINDABLE); + + get_buffers(buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, NULL, NULL, NULL, + flags, NULL, false)); + put_buffers(buffer); + + return error; +} + +int aa_move_mount(struct aa_label *label, const struct path *path, + const char *orig_name) +{ + struct aa_profile *profile; + char *buffer = NULL, *old_buffer = NULL; + struct path old_path; + int error; + + AA_BUG(!label); + AA_BUG(!path); + + if (!orig_name || !*orig_name) + return -EINVAL; + + error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path); + if (error) + return error; + + get_buffers(buffer, old_buffer); + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, &old_path, old_buffer, + NULL, MS_MOVE, NULL, false)); + put_buffers(buffer, old_buffer); + path_put(&old_path); + + return error; +} + +int aa_new_mount(struct aa_label *label, const char *dev_name, + const struct path *path, const char *type, unsigned long flags, + void *data) +{ + struct aa_profile *profile; + char *buffer = NULL, *dev_buffer = NULL; + bool binary = true; + int error; + int requires_dev = 0; + struct path tmp_path, *dev_path = NULL; + + AA_BUG(!label); + AA_BUG(!path); + + if (type) { + struct file_system_type *fstype; + + fstype = get_fs_type(type); + if (!fstype) + return -ENODEV; + binary = fstype->fs_flags & FS_BINARY_MOUNTDATA; + requires_dev = fstype->fs_flags & FS_REQUIRES_DEV; + put_filesystem(fstype); + + if (requires_dev) { + if (!dev_name || !*dev_name) + return -ENOENT; + + error = kern_path(dev_name, LOOKUP_FOLLOW, &tmp_path); + if (error) + return error; + dev_path = &tmp_path; + } + } + + get_buffers(buffer, dev_buffer); + if (dev_path) { + error = fn_for_each_confined(label, profile, + match_mnt(profile, path, buffer, dev_path, dev_buffer, + type, flags, data, binary)); + } else { + error = fn_for_each_confined(label, profile, + match_mnt_path_str(profile, path, buffer, dev_name, + type, flags, data, binary, NULL)); + } + put_buffers(buffer, dev_buffer); + if (dev_path) + path_put(dev_path); + + return error; +} + +static int profile_umount(struct aa_profile *profile, struct path *path, + char *buffer) +{ + struct aa_perms perms = { }; + const char *name = NULL, *info = NULL; + unsigned int state; + int error; + + AA_BUG(!profile); + AA_BUG(!path); + + error = aa_path_name(path, path_flags(profile, path), buffer, &name, + &info, profile->disconnected); + if (error) + goto audit; + + state = aa_dfa_match(profile->policy.dfa, + profile->policy.start[AA_CLASS_MOUNT], + name); + perms = compute_mnt_perms(profile->policy.dfa, state); + if (AA_MAY_UMOUNT & ~perms.allow) + error = -EACCES; + +audit: + return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL, + AA_MAY_UMOUNT, &perms, info, error); +} + +int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags) +{ + struct aa_profile *profile; + char *buffer = NULL; + int error; + struct path path = { .mnt = mnt, .dentry = mnt->mnt_root }; + + AA_BUG(!label); + AA_BUG(!mnt); + + get_buffers(buffer); + error = fn_for_each_confined(label, profile, + profile_umount(profile, &path, buffer)); + put_buffers(buffer); + + return error; +} + +/* helper fn for transition on pivotroot + * + * Returns: label for transition or ERR_PTR. Does not return NULL + */ +static struct aa_label *build_pivotroot(struct aa_profile *profile, + const struct path *new_path, + char *new_buffer, + const struct path *old_path, + char *old_buffer) +{ + const char *old_name, *new_name = NULL, *info = NULL; + const char *trans_name = NULL; + struct aa_perms perms = { }; + unsigned int state; + int error; + + AA_BUG(!profile); + AA_BUG(!new_path); + AA_BUG(!old_path); + + if (profile_unconfined(profile)) + return aa_get_newest_label(&profile->label); + + error = aa_path_name(old_path, path_flags(profile, old_path), + old_buffer, &old_name, &info, + profile->disconnected); + if (error) + goto audit; + error = aa_path_name(new_path, path_flags(profile, new_path), + new_buffer, &new_name, &info, + profile->disconnected); + if (error) + goto audit; + + error = -EACCES; + state = aa_dfa_match(profile->policy.dfa, + profile->policy.start[AA_CLASS_MOUNT], + new_name); + state = aa_dfa_null_transition(profile->policy.dfa, state); + state = aa_dfa_match(profile->policy.dfa, state, old_name); + perms = compute_mnt_perms(profile->policy.dfa, state); + + if (AA_MAY_PIVOTROOT & perms.allow) + error = 0; + +audit: + error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name, + NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT, + &perms, info, error); + if (error) + return ERR_PTR(error); + + return aa_get_newest_label(&profile->label); +} + +int aa_pivotroot(struct aa_label *label, const struct path *old_path, + const struct path *new_path) +{ + struct aa_profile *profile; + struct aa_label *target = NULL; + char *old_buffer = NULL, *new_buffer = NULL, *info = NULL; + int error; + + AA_BUG(!label); + AA_BUG(!old_path); + AA_BUG(!new_path); + + get_buffers(old_buffer, new_buffer); + target = fn_label_build(label, profile, GFP_ATOMIC, + build_pivotroot(profile, new_path, new_buffer, + old_path, old_buffer)); + if (!target) { + info = "label build failed"; + error = -ENOMEM; + goto fail; + } else if (!IS_ERR(target)) { + error = aa_replace_current_label(target); + if (error) { + /* TODO: audit target */ + aa_put_label(target); + goto out; + } + } else + /* already audited error */ + error = PTR_ERR(target); +out: + put_buffers(old_buffer, new_buffer); + + return error; + +fail: + /* TODO: add back in auditing of new_name and old_name */ + error = fn_for_each(label, profile, + audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */, + NULL /* old_name */, + NULL, NULL, + 0, NULL, AA_MAY_PIVOTROOT, &nullperms, info, + error)); + goto out; +} diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 244ea4a4a8f0..4243b0c3f0e4 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -289,85 +289,6 @@ fail: return NULL; } -/** - * aa_new_null_profile - create or find a null-X learning profile - * @parent: profile that caused this profile to be created (NOT NULL) - * @hat: true if the null- learning profile is a hat - * @base: name to base the null profile off of - * @gfp: type of allocation - * - * Find/Create a null- complain mode profile used in learning mode. The - * name of the profile is unique and follows the format of parent//null-XXX. - * where XXX is based on the @name or if that fails or is not supplied - * a unique number - * - * null profiles are added to the profile list but the list does not - * hold a count on them so that they are automatically released when - * not in use. - * - * Returns: new refcounted profile else NULL on failure - */ -struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, - const char *base, gfp_t gfp) -{ - struct aa_profile *profile; - char *name; - - AA_BUG(!parent); - - if (base) { - name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base), - gfp); - if (name) { - sprintf(name, "%s//null-%s", parent->base.hname, base); - goto name; - } - /* fall through to try shorter uniq */ - } - - name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp); - if (!name) - return NULL; - sprintf(name, "%s//null-%x", parent->base.hname, - atomic_inc_return(&parent->ns->uniq_null)); - -name: - /* lookup to see if this is a dup creation */ - profile = aa_find_child(parent, basename(name)); - if (profile) - goto out; - - profile = aa_alloc_profile(name, NULL, gfp); - if (!profile) - goto fail; - - profile->mode = APPARMOR_COMPLAIN; - profile->label.flags |= FLAG_NULL; - if (hat) - profile->label.flags |= FLAG_HAT; - profile->path_flags = parent->path_flags; - - /* released on free_profile */ - rcu_assign_pointer(profile->parent, aa_get_profile(parent)); - profile->ns = aa_get_ns(parent->ns); - profile->file.dfa = aa_get_dfa(nulldfa); - profile->policy.dfa = aa_get_dfa(nulldfa); - - mutex_lock(&profile->ns->lock); - __add_profile(&parent->base.profiles, profile); - mutex_unlock(&profile->ns->lock); - - /* refcount released by caller */ -out: - kfree(name); - - return profile; - -fail: - aa_free_profile(profile); - return NULL; -} - /* TODO: profile accounting - setup in remove */ /** @@ -558,6 +479,93 @@ struct aa_profile *aa_fqlookupn_profile(struct aa_label *base, return profile; } +/** + * aa_new_null_profile - create or find a null-X learning profile + * @parent: profile that caused this profile to be created (NOT NULL) + * @hat: true if the null- learning profile is a hat + * @base: name to base the null profile off of + * @gfp: type of allocation + * + * Find/Create a null- complain mode profile used in learning mode. The + * name of the profile is unique and follows the format of parent//null-XXX. + * where XXX is based on the @name or if that fails or is not supplied + * a unique number + * + * null profiles are added to the profile list but the list does not + * hold a count on them so that they are automatically released when + * not in use. + * + * Returns: new refcounted profile else NULL on failure + */ +struct aa_profile *aa_new_null_profile(struct aa_profile *parent, bool hat, + const char *base, gfp_t gfp) +{ + struct aa_profile *p, *profile; + const char *bname; + char *name; + + AA_BUG(!parent); + + if (base) { + name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base), + gfp); + if (name) { + sprintf(name, "%s//null-%s", parent->base.hname, base); + goto name; + } + /* fall through to try shorter uniq */ + } + + name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp); + if (!name) + return NULL; + sprintf(name, "%s//null-%x", parent->base.hname, + atomic_inc_return(&parent->ns->uniq_null)); + +name: + /* lookup to see if this is a dup creation */ + bname = basename(name); + profile = aa_find_child(parent, bname); + if (profile) + goto out; + + profile = aa_alloc_profile(name, NULL, gfp); + if (!profile) + goto fail; + + profile->mode = APPARMOR_COMPLAIN; + profile->label.flags |= FLAG_NULL; + if (hat) + profile->label.flags |= FLAG_HAT; + profile->path_flags = parent->path_flags; + + /* released on free_profile */ + rcu_assign_pointer(profile->parent, aa_get_profile(parent)); + profile->ns = aa_get_ns(parent->ns); + profile->file.dfa = aa_get_dfa(nulldfa); + profile->policy.dfa = aa_get_dfa(nulldfa); + + mutex_lock(&profile->ns->lock); + p = __find_child(&parent->base.profiles, bname); + if (p) { + aa_free_profile(profile); + profile = aa_get_profile(p); + } else { + __add_profile(&parent->base.profiles, profile); + } + mutex_unlock(&profile->ns->lock); + + /* refcount released by caller */ +out: + kfree(name); + + return profile; + +fail: + aa_free_profile(profile); + return NULL; +} + /** * replacement_allowed - test to see if replacement is allowed * @profile: profile to test if it can be replaced (MAYBE NULL) diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c index 351d3bab3a3d..62a3589c62ab 100644 --- a/security/apparmor/policy_ns.c +++ b/security/apparmor/policy_ns.c @@ -112,6 +112,8 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name) ns->unconfined->label.flags |= FLAG_IX_ON_NAME_ERROR | FLAG_IMMUTIBLE | FLAG_NS_COUNT | FLAG_UNCONFINED; ns->unconfined->mode = APPARMOR_UNCONFINED; + ns->unconfined->file.dfa = aa_get_dfa(nulldfa); + ns->unconfined->policy.dfa = aa_get_dfa(nulldfa); /* ns and ns->unconfined share ns->unconfined refcount */ ns->unconfined->ns = ns; diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index c600f4dd1783..4ede87c30f8b 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va) audit_log_format(ab, " ns="); audit_log_untrustedstring(ab, aad(sa)->iface.ns); } - if (aad(sa)->iface.name) { + if (aad(sa)->name) { audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, aad(sa)->iface.name); + audit_log_untrustedstring(ab, aad(sa)->name); } if (aad(sa)->iface.pos) audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); @@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name, aad(&sa)->iface.pos = e->pos - e->start; aad(&sa)->iface.ns = ns_name; if (new) - aad(&sa)->iface.name = new->base.hname; + aad(&sa)->name = new->base.hname; else - aad(&sa)->iface.name = name; + aad(&sa)->name = name; aad(&sa)->info = info; aad(&sa)->error = error; @@ -448,7 +448,7 @@ fail: */ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) { - void *pos = e->pos; + void *saved_pos = e->pos; /* exec table is optional */ if (unpack_nameX(e, AA_STRUCT, "xtable")) { @@ -511,7 +511,7 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile) fail: aa_free_domain_entries(&profile->file.trans); - e->pos = pos; + e->pos = saved_pos; return 0; } @@ -583,6 +583,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) { struct aa_profile *profile = NULL; const char *tmpname, *tmpns = NULL, *name = NULL; + const char *info = "failed to unpack profile"; size_t ns_len; struct rhashtable_params params = { 0 }; char *key = NULL; @@ -604,8 +605,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); if (tmpns) { *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); - if (!*ns_name) + if (!*ns_name) { + info = "out of memory"; goto fail; + } name = tmpname; } @@ -624,12 +627,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) if (IS_ERR(profile->xmatch)) { error = PTR_ERR(profile->xmatch); profile->xmatch = NULL; + info = "bad xmatch"; goto fail; } /* xmatch_len is not optional if xmatch is set */ if (profile->xmatch) { - if (!unpack_u32(e, &tmp, NULL)) + if (!unpack_u32(e, &tmp, NULL)) { + info = "missing xmatch len"; goto fail; + } profile->xmatch_len = tmp; } @@ -637,8 +643,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) (void) unpack_str(e, &profile->disconnected, "disconnected"); /* per profile debug flags (complain, audit) */ - if (!unpack_nameX(e, AA_STRUCT, "flags")) + if (!unpack_nameX(e, AA_STRUCT, "flags")) { + info = "profile missing flags"; goto fail; + } + info = "failed to unpack profile flags"; if (!unpack_u32(e, &tmp, NULL)) goto fail; if (tmp & PACKED_FLAG_HAT) @@ -667,6 +676,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) /* set a default value if path_flags field is not present */ profile->path_flags = PATH_MEDIATE_DELETED; + info = "failed to unpack profile capabilities"; if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) goto fail; if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) @@ -676,6 +686,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) if (!unpack_u32(e, &tmpcap.cap[0], NULL)) goto fail; + info = "failed to unpack upper profile capabilities"; if (unpack_nameX(e, AA_STRUCT, "caps64")) { /* optional upper half of 64 bit caps */ if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) @@ -690,6 +701,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; } + info = "failed to unpack extended profile capabilities"; if (unpack_nameX(e, AA_STRUCT, "capsx")) { /* optional extended caps mediation mask */ if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) @@ -700,11 +712,14 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; } - if (!unpack_rlimits(e, profile)) + if (!unpack_rlimits(e, profile)) { + info = "failed to unpack profile rlimits"; goto fail; + } if (unpack_nameX(e, AA_STRUCT, "policydb")) { /* generic policy dfa - optional and may be NULL */ + info = "failed to unpack policydb"; profile->policy.dfa = unpack_dfa(e); if (IS_ERR(profile->policy.dfa)) { error = PTR_ERR(profile->policy.dfa); @@ -734,6 +749,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) if (IS_ERR(profile->file.dfa)) { error = PTR_ERR(profile->file.dfa); profile->file.dfa = NULL; + info = "failed to unpack profile file rules"; goto fail; } else if (profile->file.dfa) { if (!unpack_u32(e, &profile->file.start, "dfa_start")) @@ -746,10 +762,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) } else profile->file.dfa = aa_get_dfa(nulldfa); - if (!unpack_trans_table(e, profile)) + if (!unpack_trans_table(e, profile)) { + info = "failed to unpack profile transition table"; goto fail; + } if (unpack_nameX(e, AA_STRUCT, "data")) { + info = "out of memory"; profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); if (!profile->data) goto fail; @@ -761,8 +780,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) params.hashfn = strhash; params.obj_cmpfn = datacmp; - if (rhashtable_init(profile->data, ¶ms)) + if (rhashtable_init(profile->data, ¶ms)) { + info = "failed to init key, value hash table"; goto fail; + } while (unpack_strdup(e, &key, NULL)) { data = kzalloc(sizeof(*data), GFP_KERNEL); @@ -784,12 +805,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) profile->data->p); } - if (!unpack_nameX(e, AA_STRUCTEND, NULL)) + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { + info = "failed to unpack end of key, value data table"; goto fail; + } } - if (!unpack_nameX(e, AA_STRUCTEND, NULL)) + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { + info = "failed to unpack end of profile"; goto fail; + } return profile; @@ -798,8 +823,7 @@ fail: name = NULL; else if (!name) name = "unknown"; - audit_iface(profile, NULL, name, "failed to unpack profile", e, - error); + audit_iface(profile, NULL, name, info, e, error); aa_free_profile(profile); return ERR_PTR(error); @@ -832,7 +856,7 @@ static int verify_header(struct aa_ext *e, int required, const char **ns) * if not specified use previous version * Mask off everything that is not kernel abi version */ - if (VERSION_LT(e->version, v5) && VERSION_GT(e->version, v7)) { + if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) { audit_iface(NULL, NULL, NULL, "unsupported interface version", e, error); return error; diff --git a/security/commoncap.c b/security/commoncap.c index 7abebd782d5e..fc46f5b85251 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -82,8 +82,11 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, if (ns == cred->user_ns) return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; - /* Have we tried all of the parent namespaces? */ - if (ns == &init_user_ns) + /* + * If we're already at a lower level than we're looking for, + * we're done searching. + */ + if (ns->level <= cred->user_ns->level) return -EPERM; /* @@ -285,25 +288,16 @@ int cap_capset(struct cred *new, return 0; } -/* - * Clear proposed capability sets for execve(). - */ -static inline void bprm_clear_caps(struct linux_binprm *bprm) -{ - cap_clear(bprm->cred->cap_permitted); - bprm->cap_effective = false; -} - /** * cap_inode_need_killpriv - Determine if inode change affects privileges * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV * * Determine if an inode having a change applied that's marked ATTR_KILL_PRIV * affects the security markings on that inode, and if it is, should - * inode_killpriv() be invoked or the change rejected? + * inode_killpriv() be invoked or the change rejected. * - * Returns 0 if granted; +ve if granted, but inode_killpriv() is required; and - * -ve to deny the change. + * Returns 1 if security.capability has a value, meaning inode_killpriv() + * is required, 0 otherwise, meaning inode_killpriv() is not required. */ int cap_inode_need_killpriv(struct dentry *dentry) { @@ -332,6 +326,209 @@ int cap_inode_killpriv(struct dentry *dentry) return error; } +static bool rootid_owns_currentns(kuid_t kroot) +{ + struct user_namespace *ns; + + if (!uid_valid(kroot)) + return false; + + for (ns = current_user_ns(); ; ns = ns->parent) { + if (from_kuid(ns, kroot) == 0) + return true; + if (ns == &init_user_ns) + break; + } + + return false; +} + +static __u32 sansflags(__u32 m) +{ + return m & ~VFS_CAP_FLAGS_EFFECTIVE; +} + +static bool is_v2header(size_t size, __le32 magic) +{ + __u32 m = le32_to_cpu(magic); + if (size != XATTR_CAPS_SZ_2) + return false; + return sansflags(m) == VFS_CAP_REVISION_2; +} + +static bool is_v3header(size_t size, __le32 magic) +{ + __u32 m = le32_to_cpu(magic); + + if (size != XATTR_CAPS_SZ_3) + return false; + return sansflags(m) == VFS_CAP_REVISION_3; +} + +/* + * getsecurity: We are called for security.* before any attempt to read the + * xattr from the inode itself. + * + * This gives us a chance to read the on-disk value and convert it. If we + * return -EOPNOTSUPP, then vfs_getxattr() will call the i_op handler. + * + * Note we are not called by vfs_getxattr_alloc(), but that is only called + * by the integrity subsystem, which really wants the unconverted values - + * so that's good. + */ +int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer, + bool alloc) +{ + int size, ret; + kuid_t kroot; + uid_t root, mappedroot; + char *tmpbuf = NULL; + struct vfs_cap_data *cap; + struct vfs_ns_cap_data *nscap; + struct dentry *dentry; + struct user_namespace *fs_ns; + + if (strcmp(name, "capability") != 0) + return -EOPNOTSUPP; + + dentry = d_find_alias(inode); + if (!dentry) + return -EINVAL; + + size = sizeof(struct vfs_ns_cap_data); + ret = (int) vfs_getxattr_alloc(dentry, XATTR_NAME_CAPS, + &tmpbuf, size, GFP_NOFS); + dput(dentry); + + if (ret < 0) + return ret; + + fs_ns = inode->i_sb->s_user_ns; + cap = (struct vfs_cap_data *) tmpbuf; + if (is_v2header((size_t) ret, cap->magic_etc)) { + /* If this is sizeof(vfs_cap_data) then we're ok with the + * on-disk value, so return that. */ + if (alloc) + *buffer = tmpbuf; + else + kfree(tmpbuf); + return ret; + } else if (!is_v3header((size_t) ret, cap->magic_etc)) { + kfree(tmpbuf); + return -EINVAL; + } + + nscap = (struct vfs_ns_cap_data *) tmpbuf; + root = le32_to_cpu(nscap->rootid); + kroot = make_kuid(fs_ns, root); + + /* If the root kuid maps to a valid uid in current ns, then return + * this as a nscap. */ + mappedroot = from_kuid(current_user_ns(), kroot); + if (mappedroot != (uid_t)-1 && mappedroot != (uid_t)0) { + if (alloc) { + *buffer = tmpbuf; + nscap->rootid = cpu_to_le32(mappedroot); + } else + kfree(tmpbuf); + return size; + } + + if (!rootid_owns_currentns(kroot)) { + kfree(tmpbuf); + return -EOPNOTSUPP; + } + + /* This comes from a parent namespace. Return as a v2 capability */ + size = sizeof(struct vfs_cap_data); + if (alloc) { + *buffer = kmalloc(size, GFP_ATOMIC); + if (*buffer) { + struct vfs_cap_data *cap = *buffer; + __le32 nsmagic, magic; + magic = VFS_CAP_REVISION_2; + nsmagic = le32_to_cpu(nscap->magic_etc); + if (nsmagic & VFS_CAP_FLAGS_EFFECTIVE) + magic |= VFS_CAP_FLAGS_EFFECTIVE; + memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * VFS_CAP_U32); + cap->magic_etc = cpu_to_le32(magic); + } + } + kfree(tmpbuf); + return size; +} + +static kuid_t rootid_from_xattr(const void *value, size_t size, + struct user_namespace *task_ns) +{ + const struct vfs_ns_cap_data *nscap = value; + uid_t rootid = 0; + + if (size == XATTR_CAPS_SZ_3) + rootid = le32_to_cpu(nscap->rootid); + + return make_kuid(task_ns, rootid); +} + +static bool validheader(size_t size, __le32 magic) +{ + return is_v2header(size, magic) || is_v3header(size, magic); +} + +/* + * User requested a write of security.capability. If needed, update the + * xattr to change from v2 to v3, or to fixup the v3 rootid. + * + * If all is ok, we return the new size, on error return < 0. + */ +int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size) +{ + struct vfs_ns_cap_data *nscap; + uid_t nsrootid; + const struct vfs_cap_data *cap = *ivalue; + __u32 magic, nsmagic; + struct inode *inode = d_backing_inode(dentry); + struct user_namespace *task_ns = current_user_ns(), + *fs_ns = inode->i_sb->s_user_ns; + kuid_t rootid; + size_t newsize; + + if (!*ivalue) + return -EINVAL; + if (!validheader(size, cap->magic_etc)) + return -EINVAL; + if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP)) + return -EPERM; + if (size == XATTR_CAPS_SZ_2) + if (ns_capable(inode->i_sb->s_user_ns, CAP_SETFCAP)) + /* user is privileged, just write the v2 */ + return size; + + rootid = rootid_from_xattr(*ivalue, size, task_ns); + if (!uid_valid(rootid)) + return -EINVAL; + + nsrootid = from_kuid(fs_ns, rootid); + if (nsrootid == -1) + return -EINVAL; + + newsize = sizeof(struct vfs_ns_cap_data); + nscap = kmalloc(newsize, GFP_ATOMIC); + if (!nscap) + return -ENOMEM; + nscap->rootid = cpu_to_le32(nsrootid); + nsmagic = VFS_CAP_REVISION_3; + magic = le32_to_cpu(cap->magic_etc); + if (magic & VFS_CAP_FLAGS_EFFECTIVE) + nsmagic |= VFS_CAP_FLAGS_EFFECTIVE; + nscap->magic_etc = cpu_to_le32(nsmagic); + memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32); + + kvfree(*ivalue); + *ivalue = nscap; + return newsize; +} + /* * Calculate the new process capability sets from the capability sets attached * to a file. @@ -385,26 +582,32 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data __u32 magic_etc; unsigned tocopy, i; int size; - struct vfs_cap_data caps; + struct vfs_ns_cap_data data, *nscaps = &data; + struct vfs_cap_data *caps = (struct vfs_cap_data *) &data; + kuid_t rootkuid; + struct user_namespace *fs_ns; memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data)); if (!inode) return -ENODATA; + fs_ns = inode->i_sb->s_user_ns; size = __vfs_getxattr((struct dentry *)dentry, inode, - XATTR_NAME_CAPS, &caps, XATTR_CAPS_SZ); + XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ); if (size == -ENODATA || size == -EOPNOTSUPP) /* no data, that's ok */ return -ENODATA; + if (size < 0) return size; if (size < sizeof(magic_etc)) return -EINVAL; - cpu_caps->magic_etc = magic_etc = le32_to_cpu(caps.magic_etc); + cpu_caps->magic_etc = magic_etc = le32_to_cpu(caps->magic_etc); + rootkuid = make_kuid(fs_ns, 0); switch (magic_etc & VFS_CAP_REVISION_MASK) { case VFS_CAP_REVISION_1: if (size != XATTR_CAPS_SZ_1) @@ -416,15 +619,27 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data return -EINVAL; tocopy = VFS_CAP_U32_2; break; + case VFS_CAP_REVISION_3: + if (size != XATTR_CAPS_SZ_3) + return -EINVAL; + tocopy = VFS_CAP_U32_3; + rootkuid = make_kuid(fs_ns, le32_to_cpu(nscaps->rootid)); + break; + default: return -EINVAL; } + /* Limit the caps to the mounter of the filesystem + * or the more limited uid specified in the xattr. + */ + if (!rootid_owns_currentns(rootkuid)) + return -ENODATA; CAP_FOR_EACH_U32(i) { if (i >= tocopy) break; - cpu_caps->permitted.cap[i] = le32_to_cpu(caps.data[i].permitted); - cpu_caps->inheritable.cap[i] = le32_to_cpu(caps.data[i].inheritable); + cpu_caps->permitted.cap[i] = le32_to_cpu(caps->data[i].permitted); + cpu_caps->inheritable.cap[i] = le32_to_cpu(caps->data[i].inheritable); } cpu_caps->permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; @@ -443,7 +658,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c int rc = 0; struct cpu_vfs_cap_data vcaps; - bprm_clear_caps(bprm); + cap_clear(bprm->cred->cap_permitted); if (!file_caps_enabled) return 0; @@ -462,8 +677,8 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps); if (rc < 0) { if (rc == -EINVAL) - printk(KERN_NOTICE "%s: get_vfs_caps_from_disk returned %d for %s\n", - __func__, rc, bprm->filename); + printk(KERN_NOTICE "Invalid argument reading file caps for %s\n", + bprm->filename); else if (rc == -ENODATA) rc = 0; goto out; @@ -476,7 +691,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c out: if (rc) - bprm_clear_caps(bprm); + cap_clear(bprm->cred->cap_permitted); return rc; } @@ -585,8 +800,6 @@ skip: if (WARN_ON(!cap_ambient_invariant_ok(new))) return -EPERM; - bprm->cap_effective = effective; - /* * Audit candidate if current->cap_effective is set * @@ -614,33 +827,17 @@ skip: if (WARN_ON(!cap_ambient_invariant_ok(new))) return -EPERM; - return 0; -} - -/** - * cap_bprm_secureexec - Determine whether a secure execution is required - * @bprm: The execution parameters - * - * Determine whether a secure execution is required, return 1 if it is, and 0 - * if it is not. - * - * The credentials have been committed by this point, and so are no longer - * available through @bprm->cred. - */ -int cap_bprm_secureexec(struct linux_binprm *bprm) -{ - const struct cred *cred = current_cred(); - kuid_t root_uid = make_kuid(cred->user_ns, 0); - - if (!uid_eq(cred->uid, root_uid)) { - if (bprm->cap_effective) - return 1; - if (!cap_issubset(cred->cap_permitted, cred->cap_ambient)) - return 1; + /* Check for privilege-elevated exec. */ + bprm->cap_elevated = 0; + if (is_setid) { + bprm->cap_elevated = 1; + } else if (!uid_eq(new->uid, root_uid)) { + if (effective || + !cap_issubset(new->cap_permitted, new->cap_ambient)) + bprm->cap_elevated = 1; } - return (!uid_eq(cred->euid, cred->uid) || - !gid_eq(cred->egid, cred->gid)); + return 0; } /** @@ -660,15 +857,19 @@ int cap_bprm_secureexec(struct linux_binprm *bprm) int cap_inode_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) - return -EPERM; + /* Ignore non-security xattrs */ + if (strncmp(name, XATTR_SECURITY_PREFIX, + sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) return 0; - } - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) + /* + * For XATTR_NAME_CAPS the check will be done in + * cap_convert_nscap(), called by setxattr() + */ + if (strcmp(name, XATTR_NAME_CAPS) == 0) + return 0; + + if (!capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -686,15 +887,22 @@ int cap_inode_setxattr(struct dentry *dentry, const char *name, */ int cap_inode_removexattr(struct dentry *dentry, const char *name) { - if (!strcmp(name, XATTR_NAME_CAPS)) { - if (!capable(CAP_SETFCAP)) + /* Ignore non-security xattrs */ + if (strncmp(name, XATTR_SECURITY_PREFIX, + sizeof(XATTR_SECURITY_PREFIX) - 1) != 0) + return 0; + + if (strcmp(name, XATTR_NAME_CAPS) == 0) { + /* security.capability gets namespaced */ + struct inode *inode = d_backing_inode(dentry); + if (!inode) + return -EINVAL; + if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP)) return -EPERM; return 0; } - if (!strncmp(name, XATTR_SECURITY_PREFIX, - sizeof(XATTR_SECURITY_PREFIX) - 1) && - !capable(CAP_SYS_ADMIN)) + if (!capable(CAP_SYS_ADMIN)) return -EPERM; return 0; } @@ -1079,9 +1287,9 @@ struct security_hook_list capability_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(capget, cap_capget), LSM_HOOK_INIT(capset, cap_capset), LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), - LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec), LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), + LSM_HOOK_INIT(inode_getsecurity, cap_inode_getsecurity), LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), LSM_HOOK_INIT(mmap_file, cap_mmap_file), LSM_HOOK_INIT(task_fix_setuid, cap_task_fix_setuid), diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 03c1652c9a1f..5ef7e5240563 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * device_cgroup.c - device cgroup subsystem * diff --git a/security/integrity/Makefile b/security/integrity/Makefile index 8d1f4bf51087..04d6e462b079 100644 --- a/security/integrity/Makefile +++ b/security/integrity/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for caching inode integrity data (iint) # diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile index 29f198bde02b..d921dc4f9eb0 100644 --- a/security/integrity/ima/Makefile +++ b/security/integrity/ima/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for building Trusted Computing Group's(TCG) runtime Integrity # Measurement Architecture(IMA). diff --git a/security/keys/Kconfig b/security/keys/Kconfig index a7a23b5541f8..6462e6654ccf 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig @@ -45,10 +45,9 @@ config BIG_KEYS bool "Large payload keys" depends on KEYS depends on TMPFS - depends on (CRYPTO_ANSI_CPRNG = y || CRYPTO_DRBG = y) + select CRYPTO select CRYPTO_AES - select CRYPTO_ECB - select CRYPTO_RNG + select CRYPTO_GCM help This option provides support for holding large keys within the kernel (for example Kerberos ticket caches). The data may be stored out to diff --git a/security/keys/Makefile b/security/keys/Makefile index 57dff0c15809..ef1581b337a3 100644 --- a/security/keys/Makefile +++ b/security/keys/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for key management # diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 835c1ab30d01..929e14978c42 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -1,5 +1,6 @@ /* Large capacity key type * + * Copyright (C) 2017 Jason A. Donenfeld . All Rights Reserved. * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * @@ -16,10 +17,10 @@ #include #include #include +#include #include #include -#include -#include +#include /* * Layout of key payload words. @@ -49,7 +50,12 @@ enum big_key_op { /* * Key size for big_key data encryption */ -#define ENC_KEY_SIZE 16 +#define ENC_KEY_SIZE 32 + +/* + * Authentication tag length + */ +#define ENC_AUTHTAG_SIZE 16 /* * big_key defined keys take an arbitrary string as the description and an @@ -64,57 +70,62 @@ struct key_type key_type_big_key = { .destroy = big_key_destroy, .describe = big_key_describe, .read = big_key_read, + /* no ->update(); don't add it without changing big_key_crypt() nonce */ }; /* - * Crypto names for big_key data encryption + * Crypto names for big_key data authenticated encryption */ -static const char big_key_rng_name[] = "stdrng"; -static const char big_key_alg_name[] = "ecb(aes)"; +static const char big_key_alg_name[] = "gcm(aes)"; /* - * Crypto algorithms for big_key data encryption + * Crypto algorithms for big_key data authenticated encryption */ -static struct crypto_rng *big_key_rng; -static struct crypto_skcipher *big_key_skcipher; +static struct crypto_aead *big_key_aead; /* - * Generate random key to encrypt big_key data + * Since changing the key affects the entire object, we need a mutex. */ -static inline int big_key_gen_enckey(u8 *key) -{ - return crypto_rng_get_bytes(big_key_rng, key, ENC_KEY_SIZE); -} +static DEFINE_MUTEX(big_key_aead_lock); /* * Encrypt/decrypt big_key data */ static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key) { - int ret = -EINVAL; + int ret; struct scatterlist sgio; - SKCIPHER_REQUEST_ON_STACK(req, big_key_skcipher); + struct aead_request *aead_req; + /* We always use a zero nonce. The reason we can get away with this is + * because we're using a different randomly generated key for every + * different encryption. Notably, too, key_type_big_key doesn't define + * an .update function, so there's no chance we'll wind up reusing the + * key to encrypt updated data. Simply put: one key, one encryption. + */ + u8 zero_nonce[crypto_aead_ivsize(big_key_aead)]; - if (crypto_skcipher_setkey(big_key_skcipher, key, ENC_KEY_SIZE)) { + aead_req = aead_request_alloc(big_key_aead, GFP_KERNEL); + if (!aead_req) + return -ENOMEM; + + memset(zero_nonce, 0, sizeof(zero_nonce)); + sg_init_one(&sgio, data, datalen + (op == BIG_KEY_ENC ? ENC_AUTHTAG_SIZE : 0)); + aead_request_set_crypt(aead_req, &sgio, &sgio, datalen, zero_nonce); + aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); + aead_request_set_ad(aead_req, 0); + + mutex_lock(&big_key_aead_lock); + if (crypto_aead_setkey(big_key_aead, key, ENC_KEY_SIZE)) { ret = -EAGAIN; goto error; } - - skcipher_request_set_tfm(req, big_key_skcipher); - skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, - NULL, NULL); - - sg_init_one(&sgio, data, datalen); - skcipher_request_set_crypt(req, &sgio, &sgio, datalen, NULL); - if (op == BIG_KEY_ENC) - ret = crypto_skcipher_encrypt(req); + ret = crypto_aead_encrypt(aead_req); else - ret = crypto_skcipher_decrypt(req); - - skcipher_request_zero(req); - + ret = crypto_aead_decrypt(aead_req); error: + mutex_unlock(&big_key_aead_lock); + aead_request_free(aead_req); return ret; } @@ -146,15 +157,13 @@ int big_key_preparse(struct key_preparsed_payload *prep) * * File content is stored encrypted with randomly generated key. */ - size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); + size_t enclen = datalen + ENC_AUTHTAG_SIZE; + loff_t pos = 0; - /* prepare aligned data to encrypt */ data = kmalloc(enclen, GFP_KERNEL); if (!data) return -ENOMEM; - memcpy(data, prep->data, datalen); - memset(data + datalen, 0x00, enclen - datalen); /* generate random key */ enckey = kmalloc(ENC_KEY_SIZE, GFP_KERNEL); @@ -162,13 +171,12 @@ int big_key_preparse(struct key_preparsed_payload *prep) ret = -ENOMEM; goto error; } - - ret = big_key_gen_enckey(enckey); - if (ret) + ret = get_random_bytes_wait(enckey, ENC_KEY_SIZE); + if (unlikely(ret)) goto err_enckey; /* encrypt aligned data */ - ret = big_key_crypt(BIG_KEY_ENC, data, enclen, enckey); + ret = big_key_crypt(BIG_KEY_ENC, data, datalen, enckey); if (ret) goto err_enckey; @@ -179,7 +187,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) goto err_enckey; } - written = kernel_write(file, data, enclen, 0); + written = kernel_write(file, data, enclen, &pos); if (written != enclen) { ret = written; if (written >= 0) @@ -194,7 +202,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) *path = file->f_path; path_get(path); fput(file); - kfree(data); + kzfree(data); } else { /* Just store the data in a buffer */ void *data = kmalloc(datalen, GFP_KERNEL); @@ -210,9 +218,9 @@ int big_key_preparse(struct key_preparsed_payload *prep) err_fput: fput(file); err_enckey: - kfree(enckey); + kzfree(enckey); error: - kfree(data); + kzfree(data); return ret; } @@ -226,7 +234,7 @@ void big_key_free_preparse(struct key_preparsed_payload *prep) path_put(path); } - kfree(prep->payload.data[big_key_data]); + kzfree(prep->payload.data[big_key_data]); } /* @@ -239,7 +247,7 @@ void big_key_revoke(struct key *key) /* clear the quota */ key_payload_reserve(key, 0); - if (key_is_instantiated(key) && + if (key_is_positive(key) && (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) vfs_truncate(path, 0); } @@ -258,7 +266,7 @@ void big_key_destroy(struct key *key) path->mnt = NULL; path->dentry = NULL; } - kfree(key->payload.data[big_key_data]); + kzfree(key->payload.data[big_key_data]); key->payload.data[big_key_data] = NULL; } @@ -271,7 +279,7 @@ void big_key_describe(const struct key *key, struct seq_file *m) seq_puts(m, key->description); - if (key_is_instantiated(key)) + if (key_is_positive(key)) seq_printf(m, ": %zu [%s]", datalen, datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); @@ -294,7 +302,8 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) struct file *file; u8 *data; u8 *enckey = (u8 *)key->payload.data[big_key_data]; - size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); + size_t enclen = datalen + ENC_AUTHTAG_SIZE; + loff_t pos = 0; data = kmalloc(enclen, GFP_KERNEL); if (!data) @@ -307,7 +316,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) } /* read file to kernel and decrypt */ - ret = kernel_read(file, 0, data, enclen); + ret = kernel_read(file, data, enclen, &pos); if (ret >= 0 && ret != enclen) { ret = -EIO; goto err_fput; @@ -326,7 +335,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) err_fput: fput(file); error: - kfree(data); + kzfree(data); } else { ret = datalen; if (copy_to_user(buffer, key->payload.data[big_key_data], @@ -342,47 +351,31 @@ error: */ static int __init big_key_init(void) { - struct crypto_skcipher *cipher; - struct crypto_rng *rng; int ret; - rng = crypto_alloc_rng(big_key_rng_name, 0, 0); - if (IS_ERR(rng)) { - pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng)); - return PTR_ERR(rng); - } - - big_key_rng = rng; - - /* seed RNG */ - ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng)); - if (ret) { - pr_err("Can't reset rng: %d\n", ret); - goto error_rng; - } - /* init block cipher */ - cipher = crypto_alloc_skcipher(big_key_alg_name, 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(cipher)) { - ret = PTR_ERR(cipher); + big_key_aead = crypto_alloc_aead(big_key_alg_name, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(big_key_aead)) { + ret = PTR_ERR(big_key_aead); pr_err("Can't alloc crypto: %d\n", ret); - goto error_rng; + return ret; + } + ret = crypto_aead_setauthsize(big_key_aead, ENC_AUTHTAG_SIZE); + if (ret < 0) { + pr_err("Can't set crypto auth tag len: %d\n", ret); + goto free_aead; } - - big_key_skcipher = cipher; ret = register_key_type(&key_type_big_key); if (ret < 0) { pr_err("Can't register type: %d\n", ret); - goto error_cipher; + goto free_aead; } return 0; -error_cipher: - crypto_free_skcipher(big_key_skcipher); -error_rng: - crypto_free_rng(big_key_rng); +free_aead: + crypto_free_aead(big_key_aead); return ret; } diff --git a/security/keys/encrypted-keys/Makefile b/security/keys/encrypted-keys/Makefile index d6f8433250a5..7a44dce6f69d 100644 --- a/security/keys/encrypted-keys/Makefile +++ b/security/keys/encrypted-keys/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for encrypted keys # diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 69855ba0d3b3..d92cbf9687c3 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c @@ -309,6 +309,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k down_read(&ukey->sem); upayload = user_key_payload_locked(ukey); + if (!upayload) { + /* key was revoked before we acquired its semaphore */ + up_read(&ukey->sem); + key_put(ukey); + ukey = ERR_PTR(-EKEYREVOKED); + goto error; + } *master_key = upayload->data; *master_keylen = upayload->datalen; error: @@ -847,7 +854,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) size_t datalen = prep->datalen; int ret = 0; - if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) + if (key_is_negative(key)) return -ENOKEY; if (datalen <= 0 || datalen > 32767 || !prep->data) return -EINVAL; diff --git a/security/keys/encrypted-keys/encrypted.h b/security/keys/encrypted-keys/encrypted.h index 47802c0de735..1809995db452 100644 --- a/security/keys/encrypted-keys/encrypted.h +++ b/security/keys/encrypted-keys/encrypted.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ENCRYPTED_KEY_H #define __ENCRYPTED_KEY_H diff --git a/security/keys/gc.c b/security/keys/gc.c index 87cb260e4890..f01d48cb3de1 100644 --- a/security/keys/gc.c +++ b/security/keys/gc.c @@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys) while (!list_empty(keys)) { struct key *key = list_entry(keys->next, struct key, graveyard_link); + short state = key->state; + list_del(&key->graveyard_link); kdebug("- %u", key->serial); key_check(key); /* Throw away the key data if the key is instantiated */ - if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && - !test_bit(KEY_FLAG_NEGATIVE, &key->flags) && - key->type->destroy) + if (state == KEY_IS_POSITIVE && key->type->destroy) key->type->destroy(key); security_key_free(key); @@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys) } atomic_dec(&key->user->nkeys); - if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) + if (state != KEY_IS_UNINSTANTIATED) atomic_dec(&key->user->nikeys); key_user_put(key->user); diff --git a/security/keys/internal.h b/security/keys/internal.h index 1c02c6547038..503adbae7b0d 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -141,7 +141,7 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref, extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); -extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); +extern struct key *find_keyring_by_name(const char *name, bool uid_keyring); extern int install_user_keyrings(void); extern int install_thread_keyring_to_cred(struct cred *); diff --git a/security/keys/key.c b/security/keys/key.c index 83da68d98b40..83bf4b4afd49 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -54,10 +54,10 @@ void __key_check(const struct key *key) struct key_user *key_user_lookup(kuid_t uid) { struct key_user *candidate = NULL, *user; - struct rb_node *parent = NULL; - struct rb_node **p; + struct rb_node *parent, **p; try_again: + parent = NULL; p = &key_user_tree.rb_node; spin_lock(&key_user_lock); @@ -302,6 +302,8 @@ struct key *key_alloc(struct key_type *type, const char *desc, key->flags |= 1 << KEY_FLAG_IN_QUOTA; if (flags & KEY_ALLOC_BUILT_IN) key->flags |= 1 << KEY_FLAG_BUILTIN; + if (flags & KEY_ALLOC_UID_KEYRING) + key->flags |= 1 << KEY_FLAG_UID_KEYRING; #ifdef KEY_DEBUGGING key->magic = KEY_DEBUG_MAGIC; @@ -399,6 +401,18 @@ int key_payload_reserve(struct key *key, size_t datalen) } EXPORT_SYMBOL(key_payload_reserve); +/* + * Change the key state to being instantiated. + */ +static void mark_key_instantiated(struct key *key, int reject_error) +{ + /* Commit the payload before setting the state; barrier versus + * key_read_state(). + */ + smp_store_release(&key->state, + (reject_error < 0) ? reject_error : KEY_IS_POSITIVE); +} + /* * Instantiate a key and link it into the target keyring atomically. Must be * called with the target keyring's semaphore writelocked. The target key's @@ -422,14 +436,14 @@ static int __key_instantiate_and_link(struct key *key, mutex_lock(&key_construction_mutex); /* can't instantiate twice */ - if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { + if (key->state == KEY_IS_UNINSTANTIATED) { /* instantiate the key */ ret = key->type->instantiate(key, prep); if (ret == 0) { /* mark the key as being instantiated */ atomic_inc(&key->user->nikeys); - set_bit(KEY_FLAG_INSTANTIATED, &key->flags); + mark_key_instantiated(key, 0); if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) awaken = 1; @@ -575,13 +589,10 @@ int key_reject_and_link(struct key *key, mutex_lock(&key_construction_mutex); /* can't instantiate twice */ - if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { + if (key->state == KEY_IS_UNINSTANTIATED) { /* mark the key as being negatively instantiated */ atomic_inc(&key->user->nikeys); - key->reject_error = -error; - smp_wmb(); - set_bit(KEY_FLAG_NEGATIVE, &key->flags); - set_bit(KEY_FLAG_INSTANTIATED, &key->flags); + mark_key_instantiated(key, -error); now = current_kernel_time(); key->expiry = now.tv_sec + timeout; key_schedule_gc(key->expiry + key_gc_delay); @@ -750,8 +761,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref, ret = key->type->update(key, prep); if (ret == 0) - /* updating a negative key instantiates it */ - clear_bit(KEY_FLAG_NEGATIVE, &key->flags); + /* Updating a negative key positively instantiates it */ + mark_key_instantiated(key, 0); up_write(&key->sem); @@ -934,6 +945,16 @@ error: */ __key_link_end(keyring, &index_key, edit); + key = key_ref_to_ptr(key_ref); + if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) { + ret = wait_for_key_construction(key, true); + if (ret < 0) { + key_ref_put(key_ref); + key_ref = ERR_PTR(ret); + goto error_free_prep; + } + } + key_ref = __key_update(key_ref, &prep); goto error_free_prep; } @@ -984,8 +1005,8 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) ret = key->type->update(key, &prep); if (ret == 0) - /* updating a negative key instantiates it */ - clear_bit(KEY_FLAG_NEGATIVE, &key->flags); + /* Updating a negative key positively instantiates it */ + mark_key_instantiated(key, 0); up_write(&key->sem); diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index ab0b337c84b4..76d22f726ae4 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -766,12 +766,16 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) key = key_ref_to_ptr(key_ref); + ret = key_read_state(key); + if (ret < 0) + goto error2; /* Negatively instantiated */ + /* see if we can read it directly */ ret = key_permission(key_ref, KEY_NEED_READ); if (ret == 0) goto can_read_key; if (ret != -EACCES) - goto error; + goto error2; /* we can't; see if it's searchable from this process's keyrings * - we automatically take account of the fact that it may be @@ -896,7 +900,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) atomic_dec(&key->user->nkeys); atomic_inc(&newowner->nkeys); - if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { + if (key->state != KEY_IS_UNINSTANTIATED) { atomic_dec(&key->user->nikeys); atomic_inc(&newowner->nikeys); } @@ -1406,11 +1410,9 @@ long keyctl_assume_authority(key_serial_t id) } ret = keyctl_change_reqkey_auth(authkey); - if (ret < 0) - goto error; + if (ret == 0) + ret = authkey->serial; key_put(authkey); - - ret = authkey->serial; error: return ret; } diff --git a/security/keys/keyring.c b/security/keys/keyring.c index de81793f9920..36f842ec87f0 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -414,7 +414,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) else seq_puts(m, "[anon]"); - if (key_is_instantiated(keyring)) { + if (key_is_positive(keyring)) { if (keyring->keys.nr_leaves_on_tree != 0) seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree); else @@ -423,7 +423,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) } struct keyring_read_iterator_context { - size_t qty; + size_t buflen; size_t count; key_serial_t __user *buffer; }; @@ -435,9 +435,9 @@ static int keyring_read_iterator(const void *object, void *data) int ret; kenter("{%s,%d},,{%zu/%zu}", - key->type->name, key->serial, ctx->count, ctx->qty); + key->type->name, key->serial, ctx->count, ctx->buflen); - if (ctx->count >= ctx->qty) + if (ctx->count >= ctx->buflen) return 1; ret = put_user(key->serial, ctx->buffer); @@ -459,38 +459,33 @@ static long keyring_read(const struct key *keyring, char __user *buffer, size_t buflen) { struct keyring_read_iterator_context ctx; - unsigned long nr_keys; - int ret; + long ret; kenter("{%d},,%zu", key_serial(keyring), buflen); if (buflen & (sizeof(key_serial_t) - 1)) return -EINVAL; - nr_keys = keyring->keys.nr_leaves_on_tree; - if (nr_keys == 0) - return 0; - - /* Calculate how much data we could return */ - ctx.qty = nr_keys * sizeof(key_serial_t); - - if (!buffer || !buflen) - return ctx.qty; - - if (buflen > ctx.qty) - ctx.qty = buflen; - - /* Copy the IDs of the subscribed keys into the buffer */ - ctx.buffer = (key_serial_t __user *)buffer; - ctx.count = 0; - ret = assoc_array_iterate(&keyring->keys, keyring_read_iterator, &ctx); - if (ret < 0) { - kleave(" = %d [iterate]", ret); - return ret; + /* Copy as many key IDs as fit into the buffer */ + if (buffer && buflen) { + ctx.buffer = (key_serial_t __user *)buffer; + ctx.buflen = buflen; + ctx.count = 0; + ret = assoc_array_iterate(&keyring->keys, + keyring_read_iterator, &ctx); + if (ret < 0) { + kleave(" = %ld [iterate]", ret); + return ret; + } } - kleave(" = %zu [ok]", ctx.count); - return ctx.count; + /* Return the size of the buffer needed */ + ret = keyring->keys.nr_leaves_on_tree * sizeof(key_serial_t); + if (ret <= buflen) + kleave("= %ld [ok]", ret); + else + kleave("= %ld [buffer too small]", ret); + return ret; } /* @@ -557,7 +552,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) { struct keyring_search_context *ctx = iterator_data; const struct key *key = keyring_ptr_to_key(object); - unsigned long kflags = key->flags; + unsigned long kflags = READ_ONCE(key->flags); + short state = READ_ONCE(key->state); kenter("{%d}", key->serial); @@ -569,6 +565,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) /* skip invalidated, revoked and expired keys */ if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) { + time_t expiry = READ_ONCE(key->expiry); + if (kflags & ((1 << KEY_FLAG_INVALIDATED) | (1 << KEY_FLAG_REVOKED))) { ctx->result = ERR_PTR(-EKEYREVOKED); @@ -576,7 +574,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) goto skipped; } - if (key->expiry && ctx->now.tv_sec >= key->expiry) { + if (expiry && ctx->now.tv_sec >= expiry) { if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED)) ctx->result = ERR_PTR(-EKEYEXPIRED); kleave(" = %d [expire]", ctx->skipped_ret); @@ -601,9 +599,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) { /* we set a different error code if we pass a negative key */ - if (kflags & (1 << KEY_FLAG_NEGATIVE)) { - smp_rmb(); - ctx->result = ERR_PTR(key->reject_error); + if (state < 0) { + ctx->result = ERR_PTR(state); kleave(" = %d [neg]", ctx->skipped_ret); goto skipped; } @@ -1101,15 +1098,15 @@ found: /* * Find a keyring with the specified name. * - * All named keyrings in the current user namespace are searched, provided they - * grant Search permission directly to the caller (unless this check is - * skipped). Keyrings whose usage points have reached zero or who have been - * revoked are skipped. + * Only keyrings that have nonzero refcount, are not revoked, and are owned by a + * user in the current user namespace are considered. If @uid_keyring is %true, + * the keyring additionally must have been allocated as a user or user session + * keyring; otherwise, it must grant Search permission directly to the caller. * * Returns a pointer to the keyring with the keyring's refcount having being * incremented on success. -ENOKEY is returned if a key could not be found. */ -struct key *find_keyring_by_name(const char *name, bool skip_perm_check) +struct key *find_keyring_by_name(const char *name, bool uid_keyring) { struct key *keyring; int bucket; @@ -1137,10 +1134,15 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check) if (strcmp(keyring->description, name) != 0) continue; - if (!skip_perm_check && - key_permission(make_key_ref(keyring, 0), - KEY_NEED_SEARCH) < 0) - continue; + if (uid_keyring) { + if (!test_bit(KEY_FLAG_UID_KEYRING, + &keyring->flags)) + continue; + } else { + if (key_permission(make_key_ref(keyring, 0), + KEY_NEED_SEARCH) < 0) + continue; + } /* we've got a match but we might end up racing with * key_cleanup() if the keyring is currently 'dead' diff --git a/security/keys/permission.c b/security/keys/permission.c index 732cc0beffdf..a72b4dd70c8a 100644 --- a/security/keys/permission.c +++ b/security/keys/permission.c @@ -88,7 +88,8 @@ EXPORT_SYMBOL(key_task_permission); */ int key_validate(const struct key *key) { - unsigned long flags = key->flags; + unsigned long flags = READ_ONCE(key->flags); + time_t expiry = READ_ONCE(key->expiry); if (flags & (1 << KEY_FLAG_INVALIDATED)) return -ENOKEY; @@ -99,9 +100,9 @@ int key_validate(const struct key *key) return -EKEYREVOKED; /* check it hasn't expired */ - if (key->expiry) { + if (expiry) { struct timespec now = current_kernel_time(); - if (now.tv_sec >= key->expiry) + if (now.tv_sec >= expiry) return -EKEYEXPIRED; } diff --git a/security/keys/proc.c b/security/keys/proc.c index bf08d02b6646..6d1fcbba1e09 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -179,15 +179,18 @@ static int proc_keys_show(struct seq_file *m, void *v) struct rb_node *_p = v; struct key *key = rb_entry(_p, struct key, serial_node); struct timespec now; + time_t expiry; unsigned long timo; + unsigned long flags; key_ref_t key_ref, skey_ref; char xbuf[16]; + short state; int rc; struct keyring_search_context ctx = { .index_key.type = key->type, .index_key.description = key->description, - .cred = current_cred(), + .cred = m->file->f_cred, .match_data.cmp = lookup_user_key_possessed, .match_data.raw_data = key, .match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT, @@ -207,11 +210,7 @@ static int proc_keys_show(struct seq_file *m, void *v) } } - /* check whether the current task is allowed to view the key (assuming - * non-possession) - * - the caller holds a spinlock, and thus the RCU read lock, making our - * access to __current_cred() safe - */ + /* check whether the current task is allowed to view the key */ rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW); if (rc < 0) return 0; @@ -221,12 +220,13 @@ static int proc_keys_show(struct seq_file *m, void *v) rcu_read_lock(); /* come up with a suitable timeout value */ - if (key->expiry == 0) { + expiry = READ_ONCE(key->expiry); + if (expiry == 0) { memcpy(xbuf, "perm", 5); - } else if (now.tv_sec >= key->expiry) { + } else if (now.tv_sec >= expiry) { memcpy(xbuf, "expd", 5); } else { - timo = key->expiry - now.tv_sec; + timo = expiry - now.tv_sec; if (timo < 60) sprintf(xbuf, "%lus", timo); @@ -240,18 +240,21 @@ static int proc_keys_show(struct seq_file *m, void *v) sprintf(xbuf, "%luw", timo / (60*60*24*7)); } -#define showflag(KEY, LETTER, FLAG) \ - (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-') + state = key_read_state(key); +#define showflag(FLAGS, LETTER, FLAG) \ + ((FLAGS & (1 << FLAG)) ? LETTER : '-') + + flags = READ_ONCE(key->flags); seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", key->serial, - showflag(key, 'I', KEY_FLAG_INSTANTIATED), - showflag(key, 'R', KEY_FLAG_REVOKED), - showflag(key, 'D', KEY_FLAG_DEAD), - showflag(key, 'Q', KEY_FLAG_IN_QUOTA), - showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), - showflag(key, 'N', KEY_FLAG_NEGATIVE), - showflag(key, 'i', KEY_FLAG_INVALIDATED), + state != KEY_IS_UNINSTANTIATED ? 'I' : '-', + showflag(flags, 'R', KEY_FLAG_REVOKED), + showflag(flags, 'D', KEY_FLAG_DEAD), + showflag(flags, 'Q', KEY_FLAG_IN_QUOTA), + showflag(flags, 'U', KEY_FLAG_USER_CONSTRUCT), + state < 0 ? 'N' : '-', + showflag(flags, 'i', KEY_FLAG_INVALIDATED), refcount_read(&key->usage), xbuf, key->perm, diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 86bced9fdbdf..740affd65ee9 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -77,7 +77,8 @@ int install_user_keyrings(void) if (IS_ERR(uid_keyring)) { uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, cred, user_keyring_perm, - KEY_ALLOC_IN_QUOTA, + KEY_ALLOC_UID_KEYRING | + KEY_ALLOC_IN_QUOTA, NULL, NULL); if (IS_ERR(uid_keyring)) { ret = PTR_ERR(uid_keyring); @@ -94,7 +95,8 @@ int install_user_keyrings(void) session_keyring = keyring_alloc(buf, user->uid, INVALID_GID, cred, user_keyring_perm, - KEY_ALLOC_IN_QUOTA, + KEY_ALLOC_UID_KEYRING | + KEY_ALLOC_IN_QUOTA, NULL, NULL); if (IS_ERR(session_keyring)) { ret = PTR_ERR(session_keyring); @@ -728,7 +730,7 @@ try_again: ret = -EIO; if (!(lflags & KEY_LOOKUP_PARTIAL) && - !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) + key_read_state(key) == KEY_IS_UNINSTANTIATED) goto invalid_key; /* check the permissions */ diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 63e63a42db3c..e8036cd0ad54 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -595,10 +595,9 @@ int wait_for_key_construction(struct key *key, bool intr) intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); if (ret) return -ERESTARTSYS; - if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { - smp_rmb(); - return key->reject_error; - } + ret = key_read_state(key); + if (ret < 0) + return ret; return key_validate(key); } EXPORT_SYMBOL(wait_for_key_construction); diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index afe9d22ab361..424e1d90412e 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key, seq_puts(m, "key:"); seq_puts(m, key->description); - if (key_is_instantiated(key)) + if (key_is_positive(key)) seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); } @@ -120,6 +120,18 @@ static void request_key_auth_revoke(struct key *key) } } +static void free_request_key_auth(struct request_key_auth *rka) +{ + if (!rka) + return; + key_put(rka->target_key); + key_put(rka->dest_keyring); + if (rka->cred) + put_cred(rka->cred); + kfree(rka->callout_info); + kfree(rka); +} + /* * Destroy an instantiation authorisation token key. */ @@ -129,15 +141,7 @@ static void request_key_auth_destroy(struct key *key) kenter("{%d}", key->serial); - if (rka->cred) { - put_cred(rka->cred); - rka->cred = NULL; - } - - key_put(rka->target_key); - key_put(rka->dest_keyring); - kfree(rka->callout_info); - kfree(rka); + free_request_key_auth(rka); } /* @@ -151,22 +155,18 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, const struct cred *cred = current->cred; struct key *authkey = NULL; char desc[20]; - int ret; + int ret = -ENOMEM; kenter("%d,", target->serial); /* allocate a auth record */ - rka = kmalloc(sizeof(*rka), GFP_KERNEL); - if (!rka) { - kleave(" = -ENOMEM"); - return ERR_PTR(-ENOMEM); - } - rka->callout_info = kmalloc(callout_len, GFP_KERNEL); - if (!rka->callout_info) { - kleave(" = -ENOMEM"); - kfree(rka); - return ERR_PTR(-ENOMEM); - } + rka = kzalloc(sizeof(*rka), GFP_KERNEL); + if (!rka) + goto error; + rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL); + if (!rka->callout_info) + goto error_free_rka; + rka->callout_len = callout_len; /* see if the calling process is already servicing the key request of * another process */ @@ -176,8 +176,12 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, /* if the auth key has been revoked, then the key we're * servicing is already instantiated */ - if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags)) - goto auth_key_revoked; + if (test_bit(KEY_FLAG_REVOKED, + &cred->request_key_auth->flags)) { + up_read(&cred->request_key_auth->sem); + ret = -EKEYREVOKED; + goto error_free_rka; + } irka = cred->request_key_auth->payload.data[0]; rka->cred = get_cred(irka->cred); @@ -193,8 +197,6 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, rka->target_key = key_get(target); rka->dest_keyring = key_get(dest_keyring); - memcpy(rka->callout_info, callout_info, callout_len); - rka->callout_len = callout_len; /* allocate the auth key */ sprintf(desc, "%x", target->serial); @@ -205,32 +207,22 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info, KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL); if (IS_ERR(authkey)) { ret = PTR_ERR(authkey); - goto error_alloc; + goto error_free_rka; } /* construct the auth key */ ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); if (ret < 0) - goto error_inst; + goto error_put_authkey; kleave(" = {%d,%d}", authkey->serial, refcount_read(&authkey->usage)); return authkey; -auth_key_revoked: - up_read(&cred->request_key_auth->sem); - kfree(rka->callout_info); - kfree(rka); - kleave("= -EKEYREVOKED"); - return ERR_PTR(-EKEYREVOKED); - -error_inst: - key_revoke(authkey); +error_put_authkey: key_put(authkey); -error_alloc: - key_put(rka->target_key); - key_put(rka->dest_keyring); - kfree(rka->callout_info); - kfree(rka); +error_free_rka: + free_request_key_auth(rka); +error: kleave("= %d", ret); return ERR_PTR(ret); } diff --git a/security/keys/trusted.c b/security/keys/trusted.c index ddfaebf60fc8..98aa89ff7bfd 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c @@ -1066,7 +1066,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) char *datablob; int ret = 0; - if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) + if (key_is_negative(key)) return -ENOKEY; p = key->payload.data[0]; if (!p->migratable) @@ -1147,20 +1147,21 @@ static long trusted_read(const struct key *key, char __user *buffer, p = dereference_key_locked(key); if (!p) return -EINVAL; - if (!buffer || buflen <= 0) - return 2 * p->blob_len; - ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL); - if (!ascii_buf) - return -ENOMEM; - bufp = ascii_buf; - for (i = 0; i < p->blob_len; i++) - bufp = hex_byte_pack(bufp, p->blob[i]); - if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) { + if (buffer && buflen >= 2 * p->blob_len) { + ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL); + if (!ascii_buf) + return -ENOMEM; + + bufp = ascii_buf; + for (i = 0; i < p->blob_len; i++) + bufp = hex_byte_pack(bufp, p->blob[i]); + if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) { + kzfree(ascii_buf); + return -EFAULT; + } kzfree(ascii_buf); - return -EFAULT; } - kzfree(ascii_buf); return 2 * p->blob_len; } diff --git a/security/keys/trusted.h b/security/keys/trusted.h index ff001a5dcb24..8d5fe9eafb22 100644 --- a/security/keys/trusted.h +++ b/security/keys/trusted.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TRUSTED_KEY_H #define __TRUSTED_KEY_H diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index 3d8c68eba516..9f558bedba23 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@ -114,7 +114,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) /* attach the new data, displacing the old */ key->expiry = prep->expiry; - if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags)) + if (key_is_positive(key)) zap = dereference_key_locked(key); rcu_assign_keypointer(key, prep->payload.data[0]); prep->payload.data[0] = NULL; @@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(user_destroy); void user_describe(const struct key *key, struct seq_file *m) { seq_puts(m, key->description); - if (key_is_instantiated(key)) + if (key_is_positive(key)) seq_printf(m, ": %u", key->datalen); } diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 28d4c3a528ab..67703dbe29ea 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c @@ -2,7 +2,7 @@ * common LSM auditing functions * * Based on code written for SELinux by : - * Stephen Smalley, + * Stephen Smalley, * James Morris * Author : Etienne Basset, * diff --git a/security/min_addr.c b/security/min_addr.c index f728728f193b..94d2b0cf0e7b 100644 --- a/security/min_addr.c +++ b/security/min_addr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/security/security.c b/security/security.c index 30132378d103..4bf0f571b4ef 100644 --- a/security/security.c +++ b/security/security.c @@ -351,11 +351,6 @@ void security_bprm_committed_creds(struct linux_binprm *bprm) call_void_hook(bprm_committed_creds, bprm); } -int security_bprm_secureexec(struct linux_binprm *bprm) -{ - return call_int_hook(bprm_secureexec, 0, bprm); -} - int security_sb_alloc(struct super_block *sb) { return call_int_hook(sb_alloc_security, 0, sb); @@ -979,11 +974,6 @@ int security_file_open(struct file *file, const struct cred *cred) return fsnotify_perm(file, MAY_OPEN); } -int security_task_create(unsigned long clone_flags) -{ - return call_int_hook(task_create, 0, clone_flags); -} - int security_task_alloc(struct task_struct *task, unsigned long clone_flags) { return call_int_hook(task_alloc, 0, task, clone_flags); diff --git a/security/selinux/Makefile b/security/selinux/Makefile index ff5895ede96f..c7161f8792b2 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for building the SELinux module as part of the kernel tree. # diff --git a/security/selinux/avc.c b/security/selinux/avc.c index e60c79de13e1..2380b8d72cec 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -1,7 +1,7 @@ /* * Implementation of the kernel access vector cache (AVC). * - * Authors: Stephen Smalley, + * Authors: Stephen Smalley, * James Morris * * Update: KaiGai, Kohei @@ -197,8 +197,6 @@ void __init avc_init(void) avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data", sizeof(struct extended_perms_data), 0, SLAB_PANIC, NULL); - - audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n"); } int avc_get_hash_stats(char *page) @@ -348,27 +346,26 @@ static struct avc_xperms_decision_node struct avc_xperms_decision_node *xpd_node; struct extended_perms_decision *xpd; - xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT); if (!xpd_node) return NULL; xpd = &xpd_node->xpd; if (which & XPERMS_ALLOWED) { xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + GFP_NOWAIT); if (!xpd->allowed) goto error; } if (which & XPERMS_AUDITALLOW) { xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + GFP_NOWAIT); if (!xpd->auditallow) goto error; } if (which & XPERMS_DONTAUDIT) { xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_ATOMIC | __GFP_NOMEMALLOC); + GFP_NOWAIT); if (!xpd->dontaudit) goto error; } @@ -396,8 +393,7 @@ static struct avc_xperms_node *avc_xperms_alloc(void) { struct avc_xperms_node *xp_node; - xp_node = kmem_cache_zalloc(avc_xperms_cachep, - GFP_ATOMIC|__GFP_NOMEMALLOC); + xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT); if (!xp_node) return xp_node; INIT_LIST_HEAD(&xp_node->xpd_head); @@ -550,7 +546,7 @@ static struct avc_node *avc_alloc_node(void) { struct avc_node *node; - node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC|__GFP_NOMEMALLOC); + node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT); if (!node) goto out; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 33fd061305c4..f5d304736852 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3,7 +3,7 @@ * * This file contains the SELinux hook function implementations. * - * Authors: Stephen Smalley, + * Authors: Stephen Smalley, * Chris Vance, * Wayne Salamon, * James Morris @@ -815,7 +815,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, if (!strcmp(sb->s_type->name, "debugfs") || !strcmp(sb->s_type->name, "tracefs") || !strcmp(sb->s_type->name, "sysfs") || - !strcmp(sb->s_type->name, "pstore")) + !strcmp(sb->s_type->name, "pstore") || + !strcmp(sb->s_type->name, "cgroup") || + !strcmp(sb->s_type->name, "cgroup2")) sbsec->flags |= SE_SBGENFS; if (!sbsec->behavior) { @@ -1303,6 +1305,7 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc case SOCK_SEQPACKET: return SECCLASS_UNIX_STREAM_SOCKET; case SOCK_DGRAM: + case SOCK_RAW: return SECCLASS_UNIX_DGRAM_SOCKET; } break; @@ -2317,6 +2320,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS); int nosuid = !mnt_may_suid(bprm->file->f_path.mnt); int rc; + u32 av; if (!nnp && !nosuid) return 0; /* neither NNP nor nosuid */ @@ -2325,24 +2329,40 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, return 0; /* No change in credentials */ /* - * The only transitions we permit under NNP or nosuid - * are transitions to bounded SIDs, i.e. SIDs that are - * guaranteed to only be allowed a subset of the permissions - * of the current SID. + * If the policy enables the nnp_nosuid_transition policy capability, + * then we permit transitions under NNP or nosuid if the + * policy allows the corresponding permission between + * the old and new contexts. + */ + if (selinux_policycap_nnp_nosuid_transition) { + av = 0; + if (nnp) + av |= PROCESS2__NNP_TRANSITION; + if (nosuid) + av |= PROCESS2__NOSUID_TRANSITION; + rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + SECCLASS_PROCESS2, av, NULL); + if (!rc) + return 0; + } + + /* + * We also permit NNP or nosuid transitions to bounded SIDs, + * i.e. SIDs that are guaranteed to only be allowed a subset + * of the permissions of the current SID. */ rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); - if (rc) { - /* - * On failure, preserve the errno values for NNP vs nosuid. - * NNP: Operation not permitted for caller. - * nosuid: Permission denied to file. - */ - if (nnp) - return -EPERM; - else - return -EACCES; - } - return 0; + if (!rc) + return 0; + + /* + * On failure, preserve the errno values for NNP vs nosuid. + * NNP: Operation not permitted for caller. + * nosuid: Permission denied to file. + */ + if (nnp) + return -EPERM; + return -EACCES; } static int selinux_bprm_set_creds(struct linux_binprm *bprm) @@ -2356,7 +2376,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) /* SELinux context only depends on initial program or script and not * the script interpreter */ - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; old_tsec = current_security(); @@ -2442,30 +2462,17 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) /* Clear any possibly unsafe personality bits on exec: */ bprm->per_clear |= PER_CLEAR_ON_SETID; - } - return 0; -} - -static int selinux_bprm_secureexec(struct linux_binprm *bprm) -{ - const struct task_security_struct *tsec = current_security(); - u32 sid, osid; - int atsecure = 0; - - sid = tsec->sid; - osid = tsec->osid; - - if (osid != sid) { /* Enable secure mode for SIDs transitions unless the noatsecure permission is granted between the two SIDs, i.e. ahp returns 0. */ - atsecure = avc_has_perm(osid, sid, - SECCLASS_PROCESS, - PROCESS__NOATSECURE, NULL); + rc = avc_has_perm(old_tsec->sid, new_tsec->sid, + SECCLASS_PROCESS, PROCESS__NOATSECURE, + NULL); + bprm->secureexec |= !!rc; } - return !!atsecure; + return 0; } static int match_file(const void *p, struct file *file, unsigned fd) @@ -6266,7 +6273,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_set_creds, selinux_bprm_set_creds), LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), - LSM_HOOK_INIT(bprm_secureexec, selinux_bprm_secureexec), LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), @@ -6530,7 +6536,7 @@ security_initcall(selinux_init); #if defined(CONFIG_NETFILTER) -static struct nf_hook_ops selinux_nf_ops[] = { +static const struct nf_hook_ops selinux_nf_ops[] = { { .hook = selinux_ipv4_postroute, .pf = NFPROTO_IPV4, diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 0999df03af8b..57d61cf36500 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access vector cache interface for object managers. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SELINUX_AVC_H_ #define _SELINUX_AVC_H_ diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index d5c328452df0..3bcc72769b87 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Access vector cache interface for the security server. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SELINUX_AVC_SS_H_ #define _SELINUX_AVC_SS_H_ diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index b9fe3434b036..cc35695d97b4 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ @@ -48,6 +49,8 @@ struct security_class_mapping secclass_map[] = { "setrlimit", "rlimitinh", "dyntransition", "setcurrent", "execmem", "execstack", "execheap", "setkeycreate", "setsockcreate", "getrlimit", NULL } }, + { "process2", + { "nnp_transition", "nosuid_transition", NULL } }, { "system", { "ipc_info", "syslog_read", "syslog_mod", "syslog_console", "module_request", "module_load", NULL } }, diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h index a59b64e3fd02..4f93f697f71c 100644 --- a/security/selinux/include/initial_sid_to_string.h +++ b/security/selinux/include/initial_sid_to_string.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* This file is automatically generated. Do not edit. */ static const char *initial_sid_to_string[] = { diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 6ebc61e370ff..1649cd18eb0b 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -3,7 +3,7 @@ * * This file contains the SELinux security data structures for kernel objects. * - * Author(s): Stephen Smalley, + * Author(s): Stephen Smalley, * Chris Vance, * Wayne Salamon, * James Morris diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index e91f08c16c0b..02f0412d42f2 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Security server interface. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, * */ @@ -73,6 +74,7 @@ enum { POLICYDB_CAPABILITY_EXTSOCKCLASS, POLICYDB_CAPABILITY_ALWAYSNETWORK, POLICYDB_CAPABILITY_CGROUPSECLABEL, + POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) @@ -84,6 +86,7 @@ extern int selinux_policycap_openperm; extern int selinux_policycap_extsockclass; extern int selinux_policycap_alwaysnetwork; extern int selinux_policycap_cgroupseclabel; +extern int selinux_policycap_nnp_nosuid_transition; /* * type_datum properties diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 1450f85b946d..1f173a7a4daa 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * SELinux support for the XFRM LSM hooks * @@ -47,10 +48,8 @@ static inline void selinux_xfrm_notify_policyload(void) struct net *net; rtnl_lock(); - for_each_net(net) { - atomic_inc(&net->xfrm.flow_cache_genid); + for_each_net(net) rt_genid_bump_all(net); - } rtnl_unlock(); } #else diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index 3628d3a868b6..2c3c7d010d8a 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -1,7 +1,7 @@ /* * Implementation of the access vector table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* Updated: Frank Mayer and Karl MacMillan diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index d946c9dc3c9c..725853cadc42 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -5,7 +5,7 @@ * table is used to represent the type enforcement * tables. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* Updated: Frank Mayer and Karl MacMillan diff --git a/security/selinux/ss/constraint.h b/security/selinux/ss/constraint.h index 96fd947c494b..4e563be9ef5f 100644 --- a/security/selinux/ss/constraint.h +++ b/security/selinux/ss/constraint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A constraint is a condition that must be satisfied in * order for one or more permissions to be granted. @@ -10,7 +11,7 @@ * process from labeling an object with a different user * identity. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_CONSTRAINT_H_ #define _SS_CONSTRAINT_H_ diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h index 212e3479a0d9..2260c44a568c 100644 --- a/security/selinux/ss/context.h +++ b/security/selinux/ss/context.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A security context is a set of security attributes * associated with each subject and object controlled @@ -10,7 +11,7 @@ * security server and can be changed without affecting * clients of the security server. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_CONTEXT_H_ #define _SS_CONTEXT_H_ diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index ad38299164c3..b6a78b09235c 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implementation of the extensible bitmap type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Hewlett-Packard diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h index 6d5a9ac4251f..edf4fa39c60a 100644 --- a/security/selinux/ss/ebitmap.h +++ b/security/selinux/ss/ebitmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * An extensible bitmap is a bitmap that supports an * arbitrary number of bits. Extensible bitmaps are @@ -9,7 +10,7 @@ * an explicitly specified starting bit position within * the total bitmap. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_EBITMAP_H_ #define _SS_EBITMAP_H_ diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index 3858706a29fb..6bd6dcd954fa 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implementation of the hash table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #include #include diff --git a/security/selinux/ss/hashtab.h b/security/selinux/ss/hashtab.h index 953872cd84ab..3e3e42bfd150 100644 --- a/security/selinux/ss/hashtab.h +++ b/security/selinux/ss/hashtab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A hash table (hashtab) maintains associations between * key values and datum values. The type of the key values @@ -5,7 +6,7 @@ * functions for hash computation and key comparison are * provided by the creator of the table. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_HASHTAB_H_ #define _SS_HASHTAB_H_ diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index e1088842232c..ad982ce8bfa4 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implementation of the multi-level security (MLS) policy. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Trusted Computer Solutions, Inc. diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index e4369e3e6366..131d76266ea5 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Multi-level security (MLS) policy operations. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Trusted Computer Solutions, Inc. diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h index e93648774137..068e0d7809db 100644 --- a/security/selinux/ss/mls_types.h +++ b/security/selinux/ss/mls_types.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Type definitions for the multi-level security (MLS) policy. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* * Updated: Trusted Computer Solutions, Inc. diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index aa6500abb178..6e8c8056d7ad 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -1,7 +1,7 @@ /* * Implementation of the policy database. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 5d23eed35fa7..215f8f30ac5a 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -2,7 +2,7 @@ * A policy database (policydb) specifies the * configuration data for the security policy. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ /* diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 2f02fa67ec2e..e4a1c0dc561a 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1,7 +1,7 @@ /* * Implementation of the security services. * - * Authors : Stephen Smalley, + * Authors : Stephen Smalley, * James Morris * * Updated: Trusted Computer Solutions, Inc. @@ -76,7 +76,8 @@ char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { "open_perms", "extended_socket_class", "always_check_network", - "cgroup_seclabel" + "cgroup_seclabel", + "nnp_nosuid_transition" }; int selinux_policycap_netpeer; @@ -84,6 +85,7 @@ int selinux_policycap_openperm; int selinux_policycap_extsockclass; int selinux_policycap_alwaysnetwork; int selinux_policycap_cgroupseclabel; +int selinux_policycap_nnp_nosuid_transition; static DEFINE_RWLOCK(policy_rwlock); @@ -2009,6 +2011,9 @@ static void security_load_policycaps(void) selinux_policycap_cgroupseclabel = ebitmap_get_bit(&policydb.policycaps, POLICYDB_CAPABILITY_CGROUPSECLABEL); + selinux_policycap_nnp_nosuid_transition = + ebitmap_get_bit(&policydb.policycaps, + POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION); for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++) pr_info("SELinux: policy capability %s=%d\n", diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index 6abcd8729ec3..356bdd36cf6d 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Implementation of the security services. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_SERVICES_H_ #define _SS_SERVICES_H_ diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index c5f436b15d19..5be31b7af225 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implementation of the SID table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #include #include diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 84dc154d9389..a1a1d2617b6f 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -1,8 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A security identifier table (sidtab) is a hash table * of security context structures indexed by SID value. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_SIDTAB_H_ #define _SS_SIDTAB_H_ diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c index 160326ee99e5..dc2ce94165d3 100644 --- a/security/selinux/ss/symtab.c +++ b/security/selinux/ss/symtab.c @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Implementation of the symbol table type. * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #include #include diff --git a/security/selinux/ss/symtab.h b/security/selinux/ss/symtab.h index ca422b42fbc0..d75fcafe7281 100644 --- a/security/selinux/ss/symtab.h +++ b/security/selinux/ss/symtab.h @@ -1,10 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * A symbol table (symtab) maintains associations between symbol * strings and datum values. The type of the datum values * is arbitrary. The symbol table type is implemented * using the hash table type (hashtab). * - * Author : Stephen Smalley, + * Author : Stephen Smalley, */ #ifndef _SS_SYMTAB_H_ #define _SS_SYMTAB_H_ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 463af86812c7..286171a16ed2 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -917,7 +917,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) struct superblock_smack *sbsp; int rc; - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; isp = inode->i_security; @@ -950,35 +950,9 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) bsp->smk_task = isp->smk_task; bprm->per_clear |= PER_CLEAR_ON_SETID; - return 0; -} - -/** - * smack_bprm_committing_creds - Prepare to install the new credentials - * from bprm. - * - * @bprm: binprm for exec - */ -static void smack_bprm_committing_creds(struct linux_binprm *bprm) -{ - struct task_smack *bsp = bprm->cred->security; - + /* Decide if this is a secure exec. */ if (bsp->smk_task != bsp->smk_forked) - current->pdeath_signal = 0; -} - -/** - * smack_bprm_secureexec - Return the decision to use secureexec. - * @bprm: binprm for exec - * - * Returns 0 on success. - */ -static int smack_bprm_secureexec(struct linux_binprm *bprm) -{ - struct task_smack *tsp = current_security(); - - if (tsp->smk_task != tsp->smk_forked) - return 1; + bprm->secureexec = 1; return 0; } @@ -1499,7 +1473,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) * @inode: the object * @name: attribute name * @buffer: where to put the result - * @alloc: unused + * @alloc: duplicate memory * * Returns the size of the attribute or an error code */ @@ -1512,43 +1486,38 @@ static int smack_inode_getsecurity(struct inode *inode, struct super_block *sbp; struct inode *ip = (struct inode *)inode; struct smack_known *isp; - int ilen; - int rc = 0; - if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) isp = smk_of_inode(inode); - ilen = strlen(isp->smk_known); - *buffer = isp->smk_known; - return ilen; + else { + /* + * The rest of the Smack xattrs are only on sockets. + */ + sbp = ip->i_sb; + if (sbp->s_magic != SOCKFS_MAGIC) + return -EOPNOTSUPP; + + sock = SOCKET_I(ip); + if (sock == NULL || sock->sk == NULL) + return -EOPNOTSUPP; + + ssp = sock->sk->sk_security; + + if (strcmp(name, XATTR_SMACK_IPIN) == 0) + isp = ssp->smk_in; + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) + isp = ssp->smk_out; + else + return -EOPNOTSUPP; } - /* - * The rest of the Smack xattrs are only on sockets. - */ - sbp = ip->i_sb; - if (sbp->s_magic != SOCKFS_MAGIC) - return -EOPNOTSUPP; - - sock = SOCKET_I(ip); - if (sock == NULL || sock->sk == NULL) - return -EOPNOTSUPP; - - ssp = sock->sk->sk_security; - - if (strcmp(name, XATTR_SMACK_IPIN) == 0) - isp = ssp->smk_in; - else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) - isp = ssp->smk_out; - else - return -EOPNOTSUPP; - - ilen = strlen(isp->smk_known); - if (rc == 0) { - *buffer = isp->smk_known; - rc = ilen; + if (alloc) { + *buffer = kstrdup(isp->smk_known, GFP_KERNEL); + if (*buffer == NULL) + return -ENOMEM; } - return rc; + return strlen(isp->smk_known); } @@ -4645,8 +4614,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sb_parse_opts_str, smack_parse_opts_str), LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), - LSM_HOOK_INIT(bprm_committing_creds, smack_bprm_committing_creds), - LSM_HOOK_INIT(bprm_secureexec, smack_bprm_secureexec), LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security), LSM_HOOK_INIT(inode_free_security, smack_inode_free_security), diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index cdeb0f3243dd..e36d17835d4f 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -58,7 +58,7 @@ static unsigned int smack_ipv4_output(void *priv, return NF_ACCEPT; } -static struct nf_hook_ops smack_nf_ops[] = { +static const struct nf_hook_ops smack_nf_ops[] = { { .hook = smack_ipv4_output, .pf = NFPROTO_IPV4, diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile index 65dbcb2fd850..b7c6a7ffc058 100644 --- a/security/tomoyo/Makefile +++ b/security/tomoyo/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o targets += builtin-policy.h diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c index 3ffa4f5509d8..d330b060dcff 100644 --- a/security/tomoyo/audit.c +++ b/security/tomoyo/audit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/audit.c * diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index e0fb75052550..21691b99e61f 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/common.c * diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 361e7a284699..e4097d7994b1 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * security/tomoyo/common.h * diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c index 6c4528d4b48f..8d0e1b9c9c57 100644 --- a/security/tomoyo/condition.c +++ b/security/tomoyo/condition.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/condition.c * diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 00d223e9fb37..f6758dad981f 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/domain.c * diff --git a/security/tomoyo/environ.c b/security/tomoyo/environ.c index ad4c6e18a437..7f0a471f19b2 100644 --- a/security/tomoyo/environ.c +++ b/security/tomoyo/environ.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/environ.c * diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 223f21ffa632..2a374b4da8f5 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/file.c * diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c index 540bc29e1b5a..e22bea811c57 100644 --- a/security/tomoyo/gc.c +++ b/security/tomoyo/gc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/gc.c * diff --git a/security/tomoyo/group.c b/security/tomoyo/group.c index 944ad77d8fba..21b0cc3a7e1a 100644 --- a/security/tomoyo/group.c +++ b/security/tomoyo/group.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/group.c * diff --git a/security/tomoyo/load_policy.c b/security/tomoyo/load_policy.c index 078fac0bb4c5..81b951652051 100644 --- a/security/tomoyo/load_policy.c +++ b/security/tomoyo/load_policy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/load_policy.c * diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c index 1598b559ac42..12477e0b0a11 100644 --- a/security/tomoyo/memory.c +++ b/security/tomoyo/memory.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/memory.c * diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c index 14b53fb2a0cf..807fd91dbb54 100644 --- a/security/tomoyo/mount.c +++ b/security/tomoyo/mount.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/mount.c * diff --git a/security/tomoyo/network.c b/security/tomoyo/network.c index 6c02ac478247..cd6932e5225c 100644 --- a/security/tomoyo/network.c +++ b/security/tomoyo/network.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/network.c * diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index a97b275ca3af..6ff8c21e4fff 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/realpath.c * diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c index 06ab41b1ff28..49393c2a3f8b 100644 --- a/security/tomoyo/securityfs_if.c +++ b/security/tomoyo/securityfs_if.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/securityfs_if.c * diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 130b4fa4f65f..213b8c593668 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/tomoyo.c * @@ -76,7 +77,7 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) * Do only if this function is called for the first time of an execve * operation. */ - if (bprm->cred_prepared) + if (bprm->called_set_creds) return 0; #ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER /* diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c index 848317fea704..580b318910f1 100644 --- a/security/tomoyo/util.c +++ b/security/tomoyo/util.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * security/tomoyo/util.c * diff --git a/sound/Makefile b/sound/Makefile index 6de45d2c32f7..f2d1d093bcdc 100644 --- a/sound/Makefile +++ b/sound/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Linux sound card driver # diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile index c3ee77fc4b2d..95f4c3849d55 100644 --- a/sound/aoa/codecs/Makefile +++ b/sound/aoa/codecs/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-aoa-codec-onyx-objs := onyx.o snd-aoa-codec-tas-objs := tas.o snd-aoa-codec-toonie-objs := toonie.o diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index a04edff8b729..d2d96ca082b7 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -167,7 +167,7 @@ static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new volume_control = { +static const struct snd_kcontrol_new volume_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -229,7 +229,7 @@ static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol, return n != v; } -static struct snd_kcontrol_new inputgain_control = { +static const struct snd_kcontrol_new inputgain_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Capture Volume", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -284,7 +284,7 @@ static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new capture_source_control = { +static const struct snd_kcontrol_new capture_source_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* If we name this 'Input Source', it properly shows up in * alsamixer as a selection, * but it's shown under the @@ -348,7 +348,7 @@ static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol, return !err ? (v != c) : err; } -static struct snd_kcontrol_new mute_control = { +static const struct snd_kcontrol_new mute_control = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -476,7 +476,7 @@ static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new onyx_spdif_mask = { +static const struct snd_kcontrol_new onyx_spdif_mask = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), @@ -533,7 +533,7 @@ static int onyx_spdif_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new onyx_spdif_ctrl = { +static const struct snd_kcontrol_new onyx_spdif_ctrl = { .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), diff --git a/sound/aoa/codecs/tas-basstreble.h b/sound/aoa/codecs/tas-basstreble.h index 69b61136fd54..770935af66af 100644 --- a/sound/aoa/codecs/tas-basstreble.h +++ b/sound/aoa/codecs/tas-basstreble.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is only included exactly once! * diff --git a/sound/aoa/codecs/tas-gain-table.h b/sound/aoa/codecs/tas-gain-table.h index 4cfa6757715e..77b8e7dc55fd 100644 --- a/sound/aoa/codecs/tas-gain-table.h +++ b/sound/aoa/codecs/tas-gain-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* This is the program used to generate below table. diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 733b6365dad6..15c05755d270 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -905,8 +905,8 @@ static int tas_i2c_probe(struct i2c_client *client, goto fail; } printk(KERN_DEBUG - "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n", - (unsigned int)client->addr, node->full_name); + "snd-aoa-codec-tas: tas found, addr 0x%02x on %pOF\n", + (unsigned int)client->addr, node); return 0; fail: mutex_destroy(&tas->mtx); diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile index a1596e88c718..056d69683b1e 100644 --- a/sound/aoa/core/Makefile +++ b/sound/aoa/core/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SND_AOA) += snd-aoa.o snd-aoa-objs := core.o \ alsa.o \ diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c index 053b09c79053..e618531757e0 100644 --- a/sound/aoa/soundbus/i2sbus/pcm.c +++ b/sound/aoa/soundbus/i2sbus/pcm.c @@ -778,7 +778,7 @@ static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream return i2sbus_pcm_pointer(i2sdev, 0); } -static struct snd_pcm_ops i2sbus_playback_ops = { +static const struct snd_pcm_ops i2sbus_playback_ops = { .open = i2sbus_playback_open, .close = i2sbus_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -848,7 +848,7 @@ static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream return i2sbus_pcm_pointer(i2sdev, 1); } -static struct snd_pcm_ops i2sbus_record_ops = { +static const struct snd_pcm_ops i2sbus_record_ops = { .open = i2sbus_record_open, .close = i2sbus_record_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/aoa/soundbus/sysfs.c b/sound/aoa/soundbus/sysfs.c index 5b2d51d99768..81da020bddef 100644 --- a/sound/aoa/soundbus/sysfs.c +++ b/sound/aoa/soundbus/sysfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include /* FIX UP */ diff --git a/sound/arm/Makefile b/sound/arm/Makefile index 8c0c851d4641..e10d5b169565 100644 --- a/sound/arm/Makefile +++ b/sound/arm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 4140b1b95054..0114ffed56dd 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -348,7 +348,7 @@ static irqreturn_t aaci_irq(int irq, void *devid) /* * ALSA support. */ -static struct snd_pcm_hardware aaci_hw_info = { +static const struct snd_pcm_hardware aaci_hw_info = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -635,7 +635,7 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm return ret; } -static struct snd_pcm_ops aaci_playback_ops = { +static const struct snd_pcm_ops aaci_playback_ops = { .open = aaci_pcm_open, .close = aaci_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -738,7 +738,7 @@ static int aaci_pcm_capture_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops aaci_capture_ops = { +static const struct snd_pcm_ops aaci_capture_ops = { .open = aaci_pcm_open, .close = aaci_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -786,7 +786,7 @@ static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume); #endif -static struct ac97_pcm ac97_defs[] = { +static const struct ac97_pcm ac97_defs[] = { [0] = { /* Front PCM */ .exclusive = 1, .r = { diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c index 83fcfac97739..1c6f4b436de3 100644 --- a/sound/arm/pxa2xx-pcm.c +++ b/sound/arm/pxa2xx-pcm.c @@ -68,7 +68,7 @@ static int pxa2xx_pcm_close(struct snd_pcm_substream *substream) return __pxa2xx_pcm_close(substream); } -static struct snd_pcm_ops pxa2xx_pcm_ops = { +static const struct snd_pcm_ops pxa2xx_pcm_ops = { .open = pxa2xx_pcm_open, .close = pxa2xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 9d2c9d9af688..380025887aef 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -12,16 +12,15 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include -#include #include #include @@ -29,7 +28,6 @@ #include #include #include -#include #include #include "ac97c.h" @@ -56,7 +54,7 @@ struct atmel_ac97c { void __iomem *regs; int irq; int opened; - int reset_pin; + struct gpio_desc *reset_pin; }; #define get_chip(card) ((struct atmel_ac97c *)(card)->private_data) @@ -66,7 +64,7 @@ struct atmel_ac97c { #define ac97c_readl(chip, reg) \ __raw_readl((chip)->regs + AC97C_##reg) -static struct snd_pcm_hardware atmel_ac97c_hw = { +static const struct snd_pcm_hardware atmel_ac97c_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED @@ -461,7 +459,7 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream) return frames; } -static struct snd_pcm_ops atmel_ac97_playback_ops = { +static const struct snd_pcm_ops atmel_ac97_playback_ops = { .open = atmel_ac97c_playback_open, .close = atmel_ac97c_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -472,7 +470,7 @@ static struct snd_pcm_ops atmel_ac97_playback_ops = { .pointer = atmel_ac97c_playback_pointer, }; -static struct snd_pcm_ops atmel_ac97_capture_ops = { +static const struct snd_pcm_ops atmel_ac97_capture_ops = { .open = atmel_ac97c_capture_open, .close = atmel_ac97c_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -558,7 +556,7 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) return retval; } -static struct ac97_pcm at91_ac97_pcm_defs[] = { +static const struct ac97_pcm at91_ac97_pcm_defs[] = { /* Playback */ { .exclusive = 1, @@ -700,11 +698,11 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip) ac97c_writel(chip, CAMR, 0); ac97c_writel(chip, COMR, 0); - if (gpio_is_valid(chip->reset_pin)) { - gpio_set_value(chip->reset_pin, 0); + if (!IS_ERR(chip->reset_pin)) { + gpiod_set_value(chip->reset_pin, 0); /* AC97 v2.2 specifications says minimum 1 us. */ udelay(2); - gpio_set_value(chip->reset_pin, 1); + gpiod_set_value(chip->reset_pin, 1); } else { ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA); udelay(2); @@ -712,45 +710,18 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip) } } -#ifdef CONFIG_OF static const struct of_device_id atmel_ac97c_dt_ids[] = { { .compatible = "atmel,at91sam9263-ac97c", }, { } }; MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids); -static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev) -{ - struct ac97c_platform_data *pdata; - struct device_node *node = dev->of_node; - - if (!node) { - dev_err(dev, "Device does not have associated DT data\n"); - return ERR_PTR(-EINVAL); - } - - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - - pdata->reset_pin = of_get_named_gpio(dev->of_node, "ac97-gpios", 2); - - return pdata; -} -#else -static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev) -{ - dev_err(dev, "no platform data defined\n"); - return ERR_PTR(-ENXIO); -} -#endif - static int atmel_ac97c_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct snd_card *card; struct atmel_ac97c *chip; struct resource *regs; - struct ac97c_platform_data *pdata; struct clk *pclk; static struct snd_ac97_bus_ops ops = { .write = atmel_ac97c_write, @@ -765,13 +736,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev) return -ENXIO; } - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - pdata = atmel_ac97c_probe_dt(&pdev->dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - } - irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_dbg(&pdev->dev, "could not get irq: %d\n", irq); @@ -783,7 +747,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "no peripheral clock\n"); return PTR_ERR(pclk); } - clk_prepare_enable(pclk); + retval = clk_prepare_enable(pclk); + if (retval) + goto err_prepare_enable; retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, THIS_MODULE, @@ -819,17 +785,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev) goto err_ioremap; } - if (gpio_is_valid(pdata->reset_pin)) { - if (gpio_request(pdata->reset_pin, "reset_pin")) { - dev_dbg(&pdev->dev, "reset pin not available\n"); - chip->reset_pin = -ENODEV; - } else { - gpio_direction_output(pdata->reset_pin, 1); - chip->reset_pin = pdata->reset_pin; - } - } else { - chip->reset_pin = -EINVAL; - } + chip->reset_pin = devm_gpiod_get_index(dev, "ac97", 2, GPIOD_OUT_HIGH); + if (IS_ERR(chip->reset_pin)) + dev_dbg(dev, "reset pin not available\n"); atmel_ac97c_reset(chip); @@ -869,9 +827,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev) return 0; err_ac97_bus: - if (gpio_is_valid(chip->reset_pin)) - gpio_free(chip->reset_pin); - iounmap(chip->regs); err_ioremap: free_irq(irq, chip); @@ -879,6 +834,7 @@ err_request_irq: snd_card_free(card); err_snd_card_new: clk_disable_unprepare(pclk); +err_prepare_enable: clk_put(pclk); return retval; } @@ -897,9 +853,9 @@ static int atmel_ac97c_resume(struct device *pdev) { struct snd_card *card = dev_get_drvdata(pdev); struct atmel_ac97c *chip = card->private_data; + int ret = clk_prepare_enable(chip->pclk); - clk_prepare_enable(chip->pclk); - return 0; + return ret; } static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume); @@ -913,9 +869,6 @@ static int atmel_ac97c_remove(struct platform_device *pdev) struct snd_card *card = platform_get_drvdata(pdev); struct atmel_ac97c *chip = get_chip(card); - if (gpio_is_valid(chip->reset_pin)) - gpio_free(chip->reset_pin); - ac97c_writel(chip, CAMR, 0); ac97c_writel(chip, COMR, 0); ac97c_writel(chip, MR, 0); @@ -936,7 +889,7 @@ static struct platform_driver atmel_ac97c_driver = { .driver = { .name = "atmel_ac97c", .pm = ATMEL_AC97C_PM_OPS, - .of_match_table = of_match_ptr(atmel_ac97c_dt_ids), + .of_match_table = atmel_ac97c_dt_ids, }, }; module_platform_driver(atmel_ac97c_driver); diff --git a/sound/core/Makefile b/sound/core/Makefile index e2066e2ef9f8..ee4a4a6b99ba 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 1999,2001 by Jaroslav Kysela diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index fec1dfdb14ad..4490a699030b 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -948,14 +948,13 @@ static const struct file_operations snd_compr_file_ops = { static int snd_compress_dev_register(struct snd_device *device) { int ret = -EINVAL; - char str[16]; struct snd_compr *compr; if (snd_BUG_ON(!device || !device->device_data)) return -EBADFD; compr = device->device_data; - pr_debug("reg %s for device %s, direction %d\n", str, compr->name, + pr_debug("reg device %s, direction %d\n", compr->name, compr->direction); /* register compressed device */ ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS, diff --git a/sound/core/control.c b/sound/core/control.c index 4525e127afd9..56b3e2d49c82 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -864,14 +864,14 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl, if (copy_from_user(&info, _info, sizeof(info))) return -EFAULT; - snd_power_lock(ctl->card); result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_info(ctl, &info); - snd_power_unlock(ctl->card); - if (result >= 0) - if (copy_to_user(_info, &info, sizeof(info))) - return -EFAULT; + if (result < 0) + return result; + result = snd_ctl_elem_info(ctl, &info); + if (result < 0) + return result; + if (copy_to_user(_info, &info, sizeof(info))) + return -EFAULT; return result; } @@ -881,24 +881,18 @@ static int snd_ctl_elem_read(struct snd_card *card, struct snd_kcontrol *kctl; struct snd_kcontrol_volatile *vd; unsigned int index_offset; - int result; - down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); - if (kctl == NULL) { - result = -ENOENT; - } else { - index_offset = snd_ctl_get_ioff(kctl, &control->id); - vd = &kctl->vd[index_offset]; - if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && - kctl->get != NULL) { - snd_ctl_build_ioff(&control->id, kctl, index_offset); - result = kctl->get(kctl, control); - } else - result = -EPERM; - } - up_read(&card->controls_rwsem); - return result; + if (kctl == NULL) + return -ENOENT; + + index_offset = snd_ctl_get_ioff(kctl, &control->id); + vd = &kctl->vd[index_offset]; + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get == NULL) + return -EPERM; + + snd_ctl_build_ioff(&control->id, kctl, index_offset); + return kctl->get(kctl, control); } static int snd_ctl_elem_read_user(struct snd_card *card, @@ -911,14 +905,19 @@ static int snd_ctl_elem_read_user(struct snd_card *card, if (IS_ERR(control)) return PTR_ERR(control); - snd_power_lock(card); result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_read(card, control); - snd_power_unlock(card); - if (result >= 0) - if (copy_to_user(_control, control, sizeof(*control))) - result = -EFAULT; + if (result < 0) + goto error; + + down_read(&card->controls_rwsem); + result = snd_ctl_elem_read(card, control); + up_read(&card->controls_rwsem); + if (result < 0) + goto error; + + if (copy_to_user(_control, control, sizeof(*control))) + result = -EFAULT; + error: kfree(control); return result; } @@ -931,30 +930,28 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, unsigned int index_offset; int result; - down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); - if (kctl == NULL) { - result = -ENOENT; - } else { - index_offset = snd_ctl_get_ioff(kctl, &control->id); - vd = &kctl->vd[index_offset]; - if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || - kctl->put == NULL || - (file && vd->owner && vd->owner != file)) { - result = -EPERM; - } else { - snd_ctl_build_ioff(&control->id, kctl, index_offset); - result = kctl->put(kctl, control); - } - if (result > 0) { - struct snd_ctl_elem_id id = control->id; - up_read(&card->controls_rwsem); - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); - return 0; - } + if (kctl == NULL) + return -ENOENT; + + index_offset = snd_ctl_get_ioff(kctl, &control->id); + vd = &kctl->vd[index_offset]; + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kctl->put == NULL || + (file && vd->owner && vd->owner != file)) { + return -EPERM; } - up_read(&card->controls_rwsem); - return result; + + snd_ctl_build_ioff(&control->id, kctl, index_offset); + result = kctl->put(kctl, control); + if (result < 0) + return result; + + if (result > 0) { + struct snd_ctl_elem_id id = control->id; + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id); + } + + return 0; } static int snd_ctl_elem_write_user(struct snd_ctl_file *file, @@ -969,14 +966,19 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file, return PTR_ERR(control); card = file->card; - snd_power_lock(card); result = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (result >= 0) - result = snd_ctl_elem_write(card, file, control); - snd_power_unlock(card); - if (result >= 0) - if (copy_to_user(_control, control, sizeof(*control))) - result = -EFAULT; + if (result < 0) + goto error; + + down_write(&card->controls_rwsem); + result = snd_ctl_elem_write(card, file, control); + up_write(&card->controls_rwsem); + if (result < 0) + goto error; + + if (copy_to_user(_control, control, sizeof(*control))) + result = -EFAULT; + error: kfree(control); return result; } @@ -1095,9 +1097,7 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, char *src = ue->elem_data + snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size; - mutex_lock(&ue->card->user_ctl_lock); memcpy(&ucontrol->value, src, size); - mutex_unlock(&ue->card->user_ctl_lock); return 0; } @@ -1110,60 +1110,83 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol, char *dst = ue->elem_data + snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size; - mutex_lock(&ue->card->user_ctl_lock); change = memcmp(&ucontrol->value, dst, size) != 0; if (change) memcpy(dst, &ucontrol->value, size); - mutex_unlock(&ue->card->user_ctl_lock); return change; } -static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, - int op_flag, - unsigned int size, - unsigned int __user *tlv) +static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf, + unsigned int size) { - struct user_element *ue = kcontrol->private_data; - int change = 0; - void *new_data; + struct user_element *ue = kctl->private_data; + unsigned int *container; + struct snd_ctl_elem_id id; + unsigned int mask = 0; + int i; + int change; - if (op_flag == SNDRV_CTL_TLV_OP_WRITE) { - if (size > 1024 * 128) /* sane value */ - return -EINVAL; + if (size > 1024 * 128) /* sane value */ + return -EINVAL; - new_data = memdup_user(tlv, size); - if (IS_ERR(new_data)) - return PTR_ERR(new_data); - mutex_lock(&ue->card->user_ctl_lock); - change = ue->tlv_data_size != size; - if (!change) - change = memcmp(ue->tlv_data, new_data, size) != 0; - kfree(ue->tlv_data); - ue->tlv_data = new_data; - ue->tlv_data_size = size; - mutex_unlock(&ue->card->user_ctl_lock); - } else { - int ret = 0; + container = memdup_user(buf, size); + if (IS_ERR(container)) + return PTR_ERR(container); - mutex_lock(&ue->card->user_ctl_lock); - if (!ue->tlv_data_size || !ue->tlv_data) { - ret = -ENXIO; - goto err_unlock; - } - if (size < ue->tlv_data_size) { - ret = -ENOSPC; - goto err_unlock; - } - if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size)) - ret = -EFAULT; -err_unlock: - mutex_unlock(&ue->card->user_ctl_lock); - if (ret) - return ret; + change = ue->tlv_data_size != size; + if (!change) + change = memcmp(ue->tlv_data, container, size) != 0; + if (!change) { + kfree(container); + return 0; } + + if (ue->tlv_data == NULL) { + /* Now TLV data is available. */ + for (i = 0; i < kctl->count; ++i) + kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; + mask = SNDRV_CTL_EVENT_MASK_INFO; + } + + kfree(ue->tlv_data); + ue->tlv_data = container; + ue->tlv_data_size = size; + + mask |= SNDRV_CTL_EVENT_MASK_TLV; + for (i = 0; i < kctl->count; ++i) { + snd_ctl_build_ioff(&id, kctl, i); + snd_ctl_notify(ue->card, mask, &id); + } + return change; } +static int read_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf, + unsigned int size) +{ + struct user_element *ue = kctl->private_data; + + if (ue->tlv_data_size == 0 || ue->tlv_data == NULL) + return -ENXIO; + + if (size < ue->tlv_data_size) + return -ENOSPC; + + if (copy_to_user(buf, ue->tlv_data, ue->tlv_data_size)) + return -EFAULT; + + return 0; +} + +static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kctl, int op_flag, + unsigned int size, unsigned int __user *buf) +{ + if (op_flag == SNDRV_CTL_TLV_OP_WRITE) + return replace_user_tlv(kctl, buf, size); + else + return read_user_tlv(kctl, buf, size); +} + static int snd_ctl_elem_init_enum_names(struct user_element *ue) { char *names, *p; @@ -1267,8 +1290,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, access = SNDRV_CTL_ELEM_ACCESS_READWRITE; access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE | - SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE); - if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) + SNDRV_CTL_ELEM_ACCESS_TLV_WRITE); + + /* In initial state, nothing is available as TLV container. */ + if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; access |= SNDRV_CTL_ELEM_ACCESS_USER; @@ -1331,7 +1356,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl->get = snd_ctl_elem_user_get; if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) kctl->put = snd_ctl_elem_user_put; - if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) + if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) kctl->tlv.c = snd_ctl_elem_user_tlv; /* This function manage to free the instance on failure. */ @@ -1405,71 +1430,107 @@ static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) return 0; } +static int call_tlv_handler(struct snd_ctl_file *file, int op_flag, + struct snd_kcontrol *kctl, + struct snd_ctl_elem_id *id, + unsigned int __user *buf, unsigned int size) +{ + static const struct { + int op; + int perm; + } pairs[] = { + {SNDRV_CTL_TLV_OP_READ, SNDRV_CTL_ELEM_ACCESS_TLV_READ}, + {SNDRV_CTL_TLV_OP_WRITE, SNDRV_CTL_ELEM_ACCESS_TLV_WRITE}, + {SNDRV_CTL_TLV_OP_CMD, SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND}, + }; + struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)]; + int i; + + /* Check support of the request for this element. */ + for (i = 0; i < ARRAY_SIZE(pairs); ++i) { + if (op_flag == pairs[i].op && (vd->access & pairs[i].perm)) + break; + } + if (i == ARRAY_SIZE(pairs)) + return -ENXIO; + + if (kctl->tlv.c == NULL) + return -ENXIO; + + /* When locked, this is unavailable. */ + if (vd->owner != NULL && vd->owner != file) + return -EPERM; + + return kctl->tlv.c(kctl, op_flag, size, buf); +} + +static int read_tlv_buf(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id, + unsigned int __user *buf, unsigned int size) +{ + struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)]; + unsigned int len; + + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)) + return -ENXIO; + + if (kctl->tlv.p == NULL) + return -ENXIO; + + len = sizeof(unsigned int) * 2 + kctl->tlv.p[1]; + if (size < len) + return -ENOMEM; + + if (copy_to_user(buf, kctl->tlv.p, len)) + return -EFAULT; + + return 0; +} + static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, - struct snd_ctl_tlv __user *_tlv, + struct snd_ctl_tlv __user *buf, int op_flag) { - struct snd_card *card = file->card; - struct snd_ctl_tlv tlv; + struct snd_ctl_tlv header; + unsigned int *container; + unsigned int container_size; struct snd_kcontrol *kctl; + struct snd_ctl_elem_id id; struct snd_kcontrol_volatile *vd; - unsigned int len; - int err = 0; - if (copy_from_user(&tlv, _tlv, sizeof(tlv))) + if (copy_from_user(&header, buf, sizeof(header))) return -EFAULT; - if (tlv.length < sizeof(unsigned int) * 2) + + /* In design of control core, numerical ID starts at 1. */ + if (header.numid == 0) return -EINVAL; - if (!tlv.numid) + + /* At least, container should include type and length fields. */ + if (header.length < sizeof(unsigned int) * 2) return -EINVAL; - down_read(&card->controls_rwsem); - kctl = snd_ctl_find_numid(card, tlv.numid); - if (kctl == NULL) { - err = -ENOENT; - goto __kctl_end; - } - if (kctl->tlv.p == NULL) { - err = -ENXIO; - goto __kctl_end; - } - vd = &kctl->vd[tlv.numid - kctl->id.numid]; - if ((op_flag == SNDRV_CTL_TLV_OP_READ && - (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) || - (op_flag == SNDRV_CTL_TLV_OP_WRITE && - (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) == 0) || - (op_flag == SNDRV_CTL_TLV_OP_CMD && - (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) == 0)) { - err = -ENXIO; - goto __kctl_end; - } + container_size = header.length; + container = buf->tlv; + + kctl = snd_ctl_find_numid(file->card, header.numid); + if (kctl == NULL) + return -ENOENT; + + /* Calculate index of the element in this set. */ + id = kctl->id; + snd_ctl_build_ioff(&id, kctl, header.numid - id.numid); + vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)]; + if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { - if (vd->owner != NULL && vd->owner != file) { - err = -EPERM; - goto __kctl_end; - } - err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); - if (err > 0) { - struct snd_ctl_elem_id id = kctl->id; - up_read(&card->controls_rwsem); - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id); - return 0; - } + return call_tlv_handler(file, op_flag, kctl, &id, container, + container_size); } else { - if (op_flag != SNDRV_CTL_TLV_OP_READ) { - err = -ENXIO; - goto __kctl_end; + if (op_flag == SNDRV_CTL_TLV_OP_READ) { + return read_tlv_buf(kctl, &id, container, + container_size); } - len = kctl->tlv.p[1] + 2 * sizeof(unsigned int); - if (tlv.length < len) { - err = -ENOMEM; - goto __kctl_end; - } - if (copy_to_user(_tlv->tlv, kctl->tlv.p, len)) - err = -EFAULT; } - __kctl_end: - up_read(&card->controls_rwsem); - return err; + + /* Not supported. */ + return -ENXIO; } static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -1511,11 +1572,20 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS: return snd_ctl_subscribe_events(ctl, ip); case SNDRV_CTL_IOCTL_TLV_READ: - return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ); + down_read(&ctl->card->controls_rwsem); + err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ); + up_read(&ctl->card->controls_rwsem); + return err; case SNDRV_CTL_IOCTL_TLV_WRITE: - return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE); + down_write(&ctl->card->controls_rwsem); + err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE); + up_write(&ctl->card->controls_rwsem); + return err; case SNDRV_CTL_IOCTL_TLV_COMMAND: - return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD); + down_write(&ctl->card->controls_rwsem); + err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD); + up_write(&ctl->card->controls_rwsem); + return err; case SNDRV_CTL_IOCTL_POWER: return -ENOPROTOOPT; case SNDRV_CTL_IOCTL_POWER_STATE: diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 1fa70766ffab..a848836a5de0 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -111,12 +111,10 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) goto error; - snd_power_lock(ctl->card); err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0); - if (err >= 0) - err = snd_ctl_elem_info(ctl, data); - snd_power_unlock(ctl->card); - + if (err < 0) + goto error; + err = snd_ctl_elem_info(ctl, data); if (err < 0) goto error; /* restore info to 32bit */ @@ -315,14 +313,13 @@ static int ctl_elem_read_user(struct snd_card *card, if (err < 0) goto error; - snd_power_lock(card); err = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (err >= 0) - err = snd_ctl_elem_read(card, data); - snd_power_unlock(card); - if (err >= 0) - err = copy_ctl_value_to_user(userdata, valuep, data, - type, count); + if (err < 0) + goto error; + err = snd_ctl_elem_read(card, data); + if (err < 0) + goto error; + err = copy_ctl_value_to_user(userdata, valuep, data, type, count); error: kfree(data); return err; @@ -344,14 +341,13 @@ static int ctl_elem_write_user(struct snd_ctl_file *file, if (err < 0) goto error; - snd_power_lock(card); err = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (err >= 0) - err = snd_ctl_elem_write(card, file, data); - snd_power_unlock(card); - if (err >= 0) - err = copy_ctl_value_to_user(userdata, valuep, data, - type, count); + if (err < 0) + goto error; + err = snd_ctl_elem_write(card, file, data); + if (err < 0) + goto error; + err = copy_ctl_value_to_user(userdata, valuep, data, type, count); error: kfree(data); return err; diff --git a/sound/core/device.c b/sound/core/device.c index 8918838b1999..cb0e46f66cc9 100644 --- a/sound/core/device.c +++ b/sound/core/device.c @@ -128,7 +128,7 @@ void snd_device_disconnect(struct snd_card *card, void *device_data) if (dev) __snd_device_disconnect(dev); else - dev_dbg(card->dev, "device disconnect %p (from %pF), not found\n", + dev_dbg(card->dev, "device disconnect %p (from %pS), not found\n", device_data, __builtin_return_address(0)); } EXPORT_SYMBOL_GPL(snd_device_disconnect); @@ -152,7 +152,7 @@ void snd_device_free(struct snd_card *card, void *device_data) if (dev) __snd_device_free(dev); else - dev_dbg(card->dev, "device free %p (from %pF), not found\n", + dev_dbg(card->dev, "device free %p (from %pS), not found\n", device_data, __builtin_return_address(0)); } EXPORT_SYMBOL(snd_device_free); diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c index 1ac0c423903e..6e47b823bcaa 100644 --- a/sound/core/hrtimer.c +++ b/sound/core/hrtimer.c @@ -159,6 +159,7 @@ static int __init snd_hrtimer_init(void) timer->hw = hrtimer_hw; timer->hw.resolution = resolution; timer->hw.ticks = NANO_SEC / resolution; + timer->max_instances = 100; /* lower the limit */ err = snd_timer_global_register(timer); if (err < 0) { diff --git a/sound/core/init.c b/sound/core/init.c index b4365bcf28a7..32ebe2f6bc59 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -248,13 +248,11 @@ int snd_card_new(struct device *parent, int idx, const char *xid, INIT_LIST_HEAD(&card->devices); init_rwsem(&card->controls_rwsem); rwlock_init(&card->ctl_files_rwlock); - mutex_init(&card->user_ctl_lock); INIT_LIST_HEAD(&card->controls); INIT_LIST_HEAD(&card->ctl_files); spin_lock_init(&card->files_lock); INIT_LIST_HEAD(&card->files_list); #ifdef CONFIG_PM - mutex_init(&card->power_lock); init_waitqueue_head(&card->power_sleep); #endif @@ -979,8 +977,6 @@ EXPORT_SYMBOL(snd_card_file_remove); * Waits until the power-state is changed. * * Return: Zero if successful, or a negative error code. - * - * Note: the power lock must be active before call. */ int snd_power_wait(struct snd_card *card, unsigned int power_state) { @@ -1000,9 +996,7 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state) if (snd_power_get_state(card) == power_state) break; set_current_state(TASK_UNINTERRUPTIBLE); - snd_power_unlock(card); schedule_timeout(30 * HZ); - snd_power_lock(card); } remove_wait_queue(&card->power_sleep, &wait); return result; diff --git a/sound/core/oss/Makefile b/sound/core/oss/Makefile index 10a79453245f..ae25edcc3b42 100644 --- a/sound/core/oss/Makefile +++ b/sound/core/oss/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 1999 by Jaroslav Kysela diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 89c7485519cb..7eadb7fd8074 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -523,7 +523,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) sprintf(name, "pcm%i%c", pcm->device, pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c'); - if ((entry = snd_info_create_card_entry(pcm->card, name, pcm->card->proc_root)) == NULL) + entry = snd_info_create_card_entry(pcm->card, name, + pcm->card->proc_root); + if (!entry) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { @@ -531,8 +533,8 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) return -ENOMEM; } pstr->proc_root = entry; - - if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { + entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root); + if (entry) { snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); @@ -542,8 +544,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) pstr->proc_info_entry = entry; #ifdef CONFIG_SND_PCM_XRUN_DEBUG - if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", - pstr->proc_root)) != NULL) { + entry = snd_info_create_card_entry(pcm->card, "xrun_debug", + pstr->proc_root); + if (entry) { entry->c.text.read = snd_pcm_xrun_debug_read; entry->c.text.write = snd_pcm_xrun_debug_write; entry->mode |= S_IWUSR; @@ -580,7 +583,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) card = substream->pcm->card; sprintf(name, "sub%i", substream->number); - if ((entry = snd_info_create_card_entry(card, name, substream->pstr->proc_root)) == NULL) + entry = snd_info_create_card_entry(card, name, + substream->pstr->proc_root); + if (!entry) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { @@ -588,8 +593,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) return -ENOMEM; } substream->proc_root = entry; - - if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "info", substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_info_read); if (snd_info_register(entry) < 0) { @@ -598,8 +603,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) } } substream->proc_info_entry = entry; - - if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "hw_params", + substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_hw_params_read); if (snd_info_register(entry) < 0) { @@ -608,8 +614,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) } } substream->proc_hw_params_entry = entry; - - if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "sw_params", + substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_sw_params_read); if (snd_info_register(entry) < 0) { @@ -618,8 +625,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) } } substream->proc_sw_params_entry = entry; - - if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { + entry = snd_info_create_card_entry(card, "status", + substream->proc_root); + if (entry) { snd_info_set_text_ops(entry, substream, snd_pcm_substream_proc_status_read); if (snd_info_register(entry) < 0) { @@ -783,21 +791,27 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, INIT_LIST_HEAD(&pcm->list); if (id) strlcpy(pcm->id, id, sizeof(pcm->id)); - if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { - snd_pcm_free(pcm); - return err; - } - if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)) < 0) { - snd_pcm_free(pcm); - return err; - } - if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { - snd_pcm_free(pcm); - return err; - } + + err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, + playback_count); + if (err < 0) + goto free_pcm; + + err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count); + if (err < 0) + goto free_pcm; + + err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops); + if (err < 0) + goto free_pcm; + if (rpcm) *rpcm = pcm; return 0; + +free_pcm: + snd_pcm_free(pcm); + return err; } /** @@ -1224,7 +1238,8 @@ static void snd_pcm_proc_init(void) { struct snd_info_entry *entry; - if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) { + entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL); + if (entry) { snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 10f537f4d735..b719d0bd833e 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c @@ -547,6 +547,7 @@ struct snd_pcm_mmap_status_x32 { u32 pad2; /* alignment */ struct timespec tstamp; s32 suspended_state; + s32 pad3; struct timespec audio_tstamp; } __packed; @@ -689,10 +690,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l case SNDRV_PCM_IOCTL_XRUN: case SNDRV_PCM_IOCTL_LINK: case SNDRV_PCM_IOCTL_UNLINK: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return snd_pcm_playback_ioctl1(file, substream, cmd, argp); - else - return snd_pcm_capture_ioctl1(file, substream, cmd, argp); + return snd_pcm_common_ioctl(file, substream, cmd, argp); case SNDRV_PCM_IOCTL_HW_REFINE32: return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); case SNDRV_PCM_IOCTL_HW_PARAMS32: diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index cf0433f80067..2fec2feac387 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1830,7 +1830,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, add_wait_queue(&to_check->sleep, &wait); snd_pcm_stream_unlock_irq(substream); up_read(&snd_pcm_link_rwsem); - snd_power_unlock(card); if (runtime->no_period_wakeup) tout = MAX_SCHEDULE_TIMEOUT; else { @@ -1842,7 +1841,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, tout = msecs_to_jiffies(tout * 1000); } tout = schedule_timeout_interruptible(tout); - snd_power_lock(card); down_read(&snd_pcm_link_rwsem); snd_pcm_stream_lock_irq(substream); remove_wait_queue(&to_check->sleep, &wait); @@ -2763,12 +2761,106 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg) runtime->tstamp_type = arg; return 0; } - + +static int snd_pcm_xferi_frames_ioctl(struct snd_pcm_substream *substream, + struct snd_xferi __user *_xferi) +{ + struct snd_xferi xferi; + struct snd_pcm_runtime *runtime = substream->runtime; + snd_pcm_sframes_t result; + + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; + if (put_user(0, &_xferi->result)) + return -EFAULT; + if (copy_from_user(&xferi, _xferi, sizeof(xferi))) + return -EFAULT; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames); + else + result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames); + __put_user(result, &_xferi->result); + return result < 0 ? result : 0; +} + +static int snd_pcm_xfern_frames_ioctl(struct snd_pcm_substream *substream, + struct snd_xfern __user *_xfern) +{ + struct snd_xfern xfern; + struct snd_pcm_runtime *runtime = substream->runtime; + void *bufs; + snd_pcm_sframes_t result; + + if (runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD; + if (runtime->channels > 128) + return -EINVAL; + if (put_user(0, &_xfern->result)) + return -EFAULT; + if (copy_from_user(&xfern, _xfern, sizeof(xfern))) + return -EFAULT; + + bufs = memdup_user(xfern.bufs, sizeof(void *) * runtime->channels); + if (IS_ERR(bufs)) + return PTR_ERR(bufs); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_lib_writev(substream, bufs, xfern.frames); + else + result = snd_pcm_lib_readv(substream, bufs, xfern.frames); + kfree(bufs); + __put_user(result, &_xfern->result); + return result < 0 ? result : 0; +} + +static int snd_pcm_rewind_ioctl(struct snd_pcm_substream *substream, + snd_pcm_uframes_t __user *_frames) +{ + snd_pcm_uframes_t frames; + snd_pcm_sframes_t result; + + if (get_user(frames, _frames)) + return -EFAULT; + if (put_user(0, _frames)) + return -EFAULT; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_playback_rewind(substream, frames); + else + result = snd_pcm_capture_rewind(substream, frames); + __put_user(result, _frames); + return result < 0 ? result : 0; +} + +static int snd_pcm_forward_ioctl(struct snd_pcm_substream *substream, + snd_pcm_uframes_t __user *_frames) +{ + snd_pcm_uframes_t frames; + snd_pcm_sframes_t result; + + if (get_user(frames, _frames)) + return -EFAULT; + if (put_user(0, _frames)) + return -EFAULT; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + result = snd_pcm_playback_forward(substream, frames); + else + result = snd_pcm_capture_forward(substream, frames); + __put_user(result, _frames); + return result < 0 ? result : 0; +} + static int snd_pcm_common_ioctl(struct file *file, struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { struct snd_pcm_file *pcm_file = file->private_data; + int res; + + if (PCM_RUNTIME_CHECK(substream)) + return -ENXIO; + + res = snd_power_wait(substream->pcm->card, SNDRV_CTL_POWER_D0); + if (res < 0) + return res; switch (cmd) { case SNDRV_PCM_IOCTL_PVERSION: @@ -2841,188 +2933,23 @@ static int snd_pcm_common_ioctl(struct file *file, return snd_pcm_action_lock_irq(&snd_pcm_action_pause, substream, (int)(unsigned long)arg); + case SNDRV_PCM_IOCTL_WRITEI_FRAMES: + case SNDRV_PCM_IOCTL_READI_FRAMES: + return snd_pcm_xferi_frames_ioctl(substream, arg); + case SNDRV_PCM_IOCTL_WRITEN_FRAMES: + case SNDRV_PCM_IOCTL_READN_FRAMES: + return snd_pcm_xfern_frames_ioctl(substream, arg); + case SNDRV_PCM_IOCTL_REWIND: + return snd_pcm_rewind_ioctl(substream, arg); + case SNDRV_PCM_IOCTL_FORWARD: + return snd_pcm_forward_ioctl(substream, arg); } pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd); return -ENOTTY; } -static int snd_pcm_common_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - struct snd_card *card = substream->pcm->card; - int res; - - snd_power_lock(card); - res = snd_power_wait(card, SNDRV_CTL_POWER_D0); - if (res >= 0) - res = snd_pcm_common_ioctl(file, substream, cmd, arg); - snd_power_unlock(card); - return res; -} - -static int snd_pcm_playback_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK)) - return -EINVAL; - switch (cmd) { - case SNDRV_PCM_IOCTL_WRITEI_FRAMES: - { - struct snd_xferi xferi; - struct snd_xferi __user *_xferi = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (put_user(0, &_xferi->result)) - return -EFAULT; - if (copy_from_user(&xferi, _xferi, sizeof(xferi))) - return -EFAULT; - result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames); - __put_user(result, &_xferi->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_WRITEN_FRAMES: - { - struct snd_xfern xfern; - struct snd_xfern __user *_xfern = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - void __user **bufs; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (runtime->channels > 128) - return -EINVAL; - if (put_user(0, &_xfern->result)) - return -EFAULT; - if (copy_from_user(&xfern, _xfern, sizeof(xfern))) - return -EFAULT; - - bufs = memdup_user(xfern.bufs, - sizeof(void *) * runtime->channels); - if (IS_ERR(bufs)) - return PTR_ERR(bufs); - result = snd_pcm_lib_writev(substream, bufs, xfern.frames); - kfree(bufs); - __put_user(result, &_xfern->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_REWIND: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_playback_rewind(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_FORWARD: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_playback_forward(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - } - return snd_pcm_common_ioctl1(file, substream, cmd, arg); -} - -static int snd_pcm_capture_ioctl1(struct file *file, - struct snd_pcm_substream *substream, - unsigned int cmd, void __user *arg) -{ - if (PCM_RUNTIME_CHECK(substream)) - return -ENXIO; - if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE)) - return -EINVAL; - switch (cmd) { - case SNDRV_PCM_IOCTL_READI_FRAMES: - { - struct snd_xferi xferi; - struct snd_xferi __user *_xferi = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (put_user(0, &_xferi->result)) - return -EFAULT; - if (copy_from_user(&xferi, _xferi, sizeof(xferi))) - return -EFAULT; - result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames); - __put_user(result, &_xferi->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_READN_FRAMES: - { - struct snd_xfern xfern; - struct snd_xfern __user *_xfern = arg; - struct snd_pcm_runtime *runtime = substream->runtime; - void *bufs; - snd_pcm_sframes_t result; - if (runtime->status->state == SNDRV_PCM_STATE_OPEN) - return -EBADFD; - if (runtime->channels > 128) - return -EINVAL; - if (put_user(0, &_xfern->result)) - return -EFAULT; - if (copy_from_user(&xfern, _xfern, sizeof(xfern))) - return -EFAULT; - - bufs = memdup_user(xfern.bufs, - sizeof(void *) * runtime->channels); - if (IS_ERR(bufs)) - return PTR_ERR(bufs); - result = snd_pcm_lib_readv(substream, bufs, xfern.frames); - kfree(bufs); - __put_user(result, &_xfern->result); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_REWIND: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_capture_rewind(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - case SNDRV_PCM_IOCTL_FORWARD: - { - snd_pcm_uframes_t frames; - snd_pcm_uframes_t __user *_frames = arg; - snd_pcm_sframes_t result; - if (get_user(frames, _frames)) - return -EFAULT; - if (put_user(0, _frames)) - return -EFAULT; - result = snd_pcm_capture_forward(substream, frames); - __put_user(result, _frames); - return result < 0 ? result : 0; - } - } - return snd_pcm_common_ioctl1(file, substream, cmd, arg); -} - -static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) +static long snd_pcm_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { struct snd_pcm_file *pcm_file; @@ -3031,22 +2958,8 @@ static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, if (((cmd >> 8) & 0xff) != 'A') return -ENOTTY; - return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd, - (void __user *)arg); -} - -static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct snd_pcm_file *pcm_file; - - pcm_file = file->private_data; - - if (((cmd >> 8) & 0xff) != 'A') - return -ENOTTY; - - return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd, - (void __user *)arg); + return snd_pcm_common_ioctl(file, pcm_file->substream, cmd, + (void __user *)arg); } /** @@ -3064,7 +2977,6 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, { snd_pcm_uframes_t *frames = arg; snd_pcm_sframes_t result; - int err; switch (cmd) { case SNDRV_PCM_IOCTL_FORWARD: @@ -3084,10 +2996,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, case SNDRV_PCM_IOCTL_START: return snd_pcm_start_lock_irq(substream); case SNDRV_PCM_IOCTL_DRAIN: - snd_power_lock(substream->pcm->card); - err = snd_pcm_drain(substream, NULL); - snd_power_unlock(substream->pcm->card); - return err; + return snd_pcm_drain(substream, NULL); case SNDRV_PCM_IOCTL_DROP: return snd_pcm_drop(substream); case SNDRV_PCM_IOCTL_DELAY: @@ -3791,7 +3700,7 @@ const struct file_operations snd_pcm_f_ops[2] = { .release = snd_pcm_release, .llseek = no_llseek, .poll = snd_pcm_playback_poll, - .unlocked_ioctl = snd_pcm_playback_ioctl, + .unlocked_ioctl = snd_pcm_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, @@ -3805,7 +3714,7 @@ const struct file_operations snd_pcm_f_ops[2] = { .release = snd_pcm_release, .llseek = no_llseek, .poll = snd_pcm_capture_poll, - .unlocked_ioctl = snd_pcm_capture_ioctl, + .unlocked_ioctl = snd_pcm_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, diff --git a/sound/core/pcm_param_trace.h b/sound/core/pcm_param_trace.h index 86c8d658a25c..08abba3133ab 100644 --- a/sound/core/pcm_param_trace.h +++ b/sound/core/pcm_param_trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM snd_pcm diff --git a/sound/core/pcm_trace.h b/sound/core/pcm_trace.h index 3ddec1b8ae46..f18da2050772 100644 --- a/sound/core/pcm_trace.h +++ b/sound/core/pcm_trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM snd_pcm #define TRACE_INCLUDE_FILE pcm_trace diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index 68fd367ac39c..3a2177a7e50c 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 1999 by Jaroslav Kysela diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index aaff9ee32695..b30b2139e3f0 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -612,9 +612,7 @@ send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq if (!dp->timer->running) len = snd_seq_oss_timer_start(dp->timer); if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { - if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE) - snd_seq_oss_readq_puts(dp->readq, mdev->seq_device, - ev->data.ext.ptr, ev->data.ext.len); + snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev); } else { len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); if (len > 0) diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c index 046cb586fb2f..06b21226b4e7 100644 --- a/sound/core/seq/oss/seq_oss_readq.c +++ b/sound/core/seq/oss/seq_oss_readq.c @@ -117,6 +117,35 @@ snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, in return 0; } +/* + * put MIDI sysex bytes; the event buffer may be chained, thus it has + * to be expanded via snd_seq_dump_var_event(). + */ +struct readq_sysex_ctx { + struct seq_oss_readq *readq; + int dev; +}; + +static int readq_dump_sysex(void *ptr, void *buf, int count) +{ + struct readq_sysex_ctx *ctx = ptr; + + return snd_seq_oss_readq_puts(ctx->readq, ctx->dev, buf, count); +} + +int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev, + struct snd_seq_event *ev) +{ + struct readq_sysex_ctx ctx = { + .readq = q, + .dev = dev + }; + + if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) + return 0; + return snd_seq_dump_var_event(ev, readq_dump_sysex, &ctx); +} + /* * copy an event to input queue: * return zero if enqueued diff --git a/sound/core/seq/oss/seq_oss_readq.h b/sound/core/seq/oss/seq_oss_readq.h index f1463f1f449e..8d033ca2d23f 100644 --- a/sound/core/seq/oss/seq_oss_readq.h +++ b/sound/core/seq/oss/seq_oss_readq.h @@ -44,6 +44,8 @@ void snd_seq_oss_readq_delete(struct seq_oss_readq *q); void snd_seq_oss_readq_clear(struct seq_oss_readq *readq); unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait); int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len); +int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev, + struct snd_seq_event *ev); int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev); int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode); int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec); diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index ea2d0ae85bd3..d10c780dfd54 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -663,7 +663,7 @@ static int deliver_to_subscribers(struct snd_seq_client *client, if (atomic) read_lock(&grp->list_lock); else - down_read(&grp->list_mutex); + down_read_nested(&grp->list_mutex, hop); list_for_each_entry(subs, &grp->list_head, src_list) { /* both ports ready? */ if (atomic_read(&subs->ref_count) != 2) @@ -1259,6 +1259,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) struct snd_seq_port_info *info = arg; struct snd_seq_client_port *port; struct snd_seq_port_callback *callback; + int port_idx; /* it is not allowed to create the port for an another client */ if (info->addr.client != client->number) @@ -1269,7 +1270,9 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) return -ENOMEM; if (client->type == USER_CLIENT && info->kernel) { - snd_seq_delete_port(client, port->addr.port); + port_idx = port->addr.port; + snd_seq_port_unlock(port); + snd_seq_delete_port(client, port_idx); return -EINVAL; } if (client->type == KERNEL_CLIENT) { @@ -1290,6 +1293,7 @@ static int snd_seq_ioctl_create_port(struct snd_seq_client *client, void *arg) snd_seq_set_port_info(port, info); snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port); + snd_seq_port_unlock(port); return 0; } diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c index 0ff7926a5a69..cda64b489e42 100644 --- a/sound/core/seq/seq_lock.c +++ b/sound/core/seq/seq_lock.c @@ -23,8 +23,6 @@ #include #include "seq_lock.h" -#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) - /* wait until all locks are released */ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) { @@ -41,5 +39,3 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line) } } EXPORT_SYMBOL(snd_use_lock_sync_helper); - -#endif diff --git a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h index 54044bc2c9ef..a973860ebcd0 100644 --- a/sound/core/seq/seq_lock.h +++ b/sound/core/seq/seq_lock.h @@ -1,10 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SND_SEQ_LOCK_H #define __SND_SEQ_LOCK_H #include -#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG) - typedef atomic_t snd_use_lock_t; /* initialize lock */ @@ -20,14 +19,4 @@ typedef atomic_t snd_use_lock_t; void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line); #define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__) -#else /* SMP || CONFIG_SND_DEBUG */ - -typedef spinlock_t snd_use_lock_t; /* dummy */ -#define snd_use_lock_init(lockp) /**/ -#define snd_use_lock_use(lockp) /**/ -#define snd_use_lock_free(lockp) /**/ -#define snd_use_lock_sync(lockp) /**/ - -#endif /* SMP || CONFIG_SND_DEBUG */ - #endif /* __SND_SEQ_LOCK_H */ diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index 0a7020c82bfc..d21ece9f8d73 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -122,7 +122,9 @@ static void port_subs_info_init(struct snd_seq_port_subs_info *grp) } -/* create a port, port number is returned (-1 on failure) */ +/* create a port, port number is returned (-1 on failure); + * the caller needs to unref the port via snd_seq_port_unlock() appropriately + */ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port) { @@ -151,6 +153,7 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, snd_use_lock_init(&new_port->use_lock); port_subs_info_init(&new_port->c_src); port_subs_info_init(&new_port->c_dest); + snd_use_lock_use(&new_port->use_lock); num = port >= 0 ? port : 0; mutex_lock(&client->ports_mutex); @@ -165,9 +168,9 @@ struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, list_add_tail(&new_port->list, &p->list); client->num_ports++; new_port->addr.port = num; /* store the port number in the port */ + sprintf(new_port->name, "port-%d", num); write_unlock_irqrestore(&client->ports_lock, flags); mutex_unlock(&client->ports_mutex); - sprintf(new_port->name, "port-%d", num); return new_port; } diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 8d93a4021c78..f48a4cd24ffc 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -77,13 +77,17 @@ static void snd_virmidi_init_event(struct snd_virmidi *vmidi, * decode input event and put to read buffer of each opened file */ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, - struct snd_seq_event *ev) + struct snd_seq_event *ev, + bool atomic) { struct snd_virmidi *vmidi; unsigned char msg[4]; int len; - read_lock(&rdev->filelist_lock); + if (atomic) + read_lock(&rdev->filelist_lock); + else + down_read(&rdev->filelist_sem); list_for_each_entry(vmidi, &rdev->filelist, list) { if (!vmidi->trigger) continue; @@ -97,7 +101,10 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, snd_rawmidi_receive(vmidi->substream, msg, len); } } - read_unlock(&rdev->filelist_lock); + if (atomic) + read_unlock(&rdev->filelist_lock); + else + up_read(&rdev->filelist_sem); return 0; } @@ -115,7 +122,7 @@ int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev) struct snd_virmidi_dev *rdev; rdev = rmidi->private_data; - return snd_virmidi_dev_receive_event(rdev, ev); + return snd_virmidi_dev_receive_event(rdev, ev, true); } #endif /* 0 */ @@ -130,7 +137,7 @@ static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct, rdev = private_data; if (!(rdev->flags & SNDRV_VIRMIDI_USE)) return 0; /* ignored */ - return snd_virmidi_dev_receive_event(rdev, ev); + return snd_virmidi_dev_receive_event(rdev, ev, atomic); } /* @@ -209,7 +216,6 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) struct snd_virmidi_dev *rdev = substream->rmidi->private_data; struct snd_rawmidi_runtime *runtime = substream->runtime; struct snd_virmidi *vmidi; - unsigned long flags; vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL); if (vmidi == NULL) @@ -223,9 +229,11 @@ static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream) vmidi->client = rdev->client; vmidi->port = rdev->port; runtime->private_data = vmidi; - write_lock_irqsave(&rdev->filelist_lock, flags); + down_write(&rdev->filelist_sem); + write_lock_irq(&rdev->filelist_lock); list_add_tail(&vmidi->list, &rdev->filelist); - write_unlock_irqrestore(&rdev->filelist_lock, flags); + write_unlock_irq(&rdev->filelist_lock); + up_write(&rdev->filelist_sem); vmidi->rdev = rdev; return 0; } @@ -264,9 +272,11 @@ static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream) struct snd_virmidi_dev *rdev = substream->rmidi->private_data; struct snd_virmidi *vmidi = substream->runtime->private_data; + down_write(&rdev->filelist_sem); write_lock_irq(&rdev->filelist_lock); list_del(&vmidi->list); write_unlock_irq(&rdev->filelist_lock); + up_write(&rdev->filelist_sem); snd_midi_event_free(vmidi->parser); substream->runtime->private_data = NULL; kfree(vmidi); @@ -520,6 +530,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi rdev->rmidi = rmidi; rdev->device = device; rdev->client = -1; + init_rwsem(&rdev->filelist_sem); rwlock_init(&rdev->filelist_lock); INIT_LIST_HEAD(&rdev->filelist); rdev->seq_mode = SNDRV_VIRMIDI_SEQ_DISPATCH; diff --git a/sound/core/seq_device.c b/sound/core/seq_device.c index c4acf17e9f5e..e40a2cba5002 100644 --- a/sound/core/seq_device.c +++ b/sound/core/seq_device.c @@ -148,8 +148,10 @@ void snd_seq_device_load_drivers(void) flush_work(&autoload_work); } EXPORT_SYMBOL(snd_seq_device_load_drivers); +#define cancel_autoload_drivers() cancel_work_sync(&autoload_work) #else #define queue_autoload_drivers() /* NOP */ +#define cancel_autoload_drivers() /* NOP */ #endif /* @@ -159,6 +161,7 @@ static int snd_seq_device_dev_free(struct snd_device *device) { struct snd_seq_device *dev = device->device_data; + cancel_autoload_drivers(); put_device(&dev->dev); return 0; } diff --git a/sound/core/timer.c b/sound/core/timer.c index a9b9a277e00c..15e82a656d96 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -180,7 +180,7 @@ static void snd_timer_request(struct snd_timer_id *tid) * * call this with register_mutex down. */ -static void snd_timer_check_slave(struct snd_timer_instance *slave) +static int snd_timer_check_slave(struct snd_timer_instance *slave) { struct snd_timer *timer; struct snd_timer_instance *master; @@ -190,16 +190,21 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave) list_for_each_entry(master, &timer->open_list_head, open_list) { if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { + if (master->timer->num_instances >= + master->timer->max_instances) + return -EBUSY; list_move_tail(&slave->open_list, &master->slave_list_head); + master->timer->num_instances++; spin_lock_irq(&slave_active_lock); slave->master = master; slave->timer = master->timer; spin_unlock_irq(&slave_active_lock); - return; + return 0; } } } + return 0; } /* @@ -208,7 +213,7 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave) * * call this with register_mutex down. */ -static void snd_timer_check_master(struct snd_timer_instance *master) +static int snd_timer_check_master(struct snd_timer_instance *master) { struct snd_timer_instance *slave, *tmp; @@ -216,7 +221,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master) list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) { if (slave->slave_class == master->slave_class && slave->slave_id == master->slave_id) { + if (master->timer->num_instances >= + master->timer->max_instances) + return -EBUSY; list_move_tail(&slave->open_list, &master->slave_list_head); + master->timer->num_instances++; spin_lock_irq(&slave_active_lock); spin_lock(&master->timer->lock); slave->master = master; @@ -228,8 +237,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master) spin_unlock_irq(&slave_active_lock); } } + return 0; } +static int snd_timer_close_locked(struct snd_timer_instance *timeri); + /* * open a timer instance * when opening a master, the slave id must be here given. @@ -240,6 +252,7 @@ int snd_timer_open(struct snd_timer_instance **ti, { struct snd_timer *timer; struct snd_timer_instance *timeri = NULL; + int err; if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { /* open a slave instance */ @@ -259,10 +272,14 @@ int snd_timer_open(struct snd_timer_instance **ti, timeri->slave_id = tid->device; timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; list_add_tail(&timeri->open_list, &snd_timer_slave_list); - snd_timer_check_slave(timeri); + err = snd_timer_check_slave(timeri); + if (err < 0) { + snd_timer_close_locked(timeri); + timeri = NULL; + } mutex_unlock(®ister_mutex); *ti = timeri; - return 0; + return err; } /* open a master instance */ @@ -288,6 +305,10 @@ int snd_timer_open(struct snd_timer_instance **ti, return -EBUSY; } } + if (timer->num_instances >= timer->max_instances) { + mutex_unlock(®ister_mutex); + return -EBUSY; + } timeri = snd_timer_instance_new(owner, timer); if (!timeri) { mutex_unlock(®ister_mutex); @@ -314,25 +335,27 @@ int snd_timer_open(struct snd_timer_instance **ti, } list_add_tail(&timeri->open_list, &timer->open_list_head); - snd_timer_check_master(timeri); + timer->num_instances++; + err = snd_timer_check_master(timeri); + if (err < 0) { + snd_timer_close_locked(timeri); + timeri = NULL; + } mutex_unlock(®ister_mutex); *ti = timeri; - return 0; + return err; } EXPORT_SYMBOL(snd_timer_open); /* * close a timer instance + * call this with register_mutex down. */ -int snd_timer_close(struct snd_timer_instance *timeri) +static int snd_timer_close_locked(struct snd_timer_instance *timeri) { struct snd_timer *timer = NULL; struct snd_timer_instance *slave, *tmp; - if (snd_BUG_ON(!timeri)) - return -ENXIO; - - mutex_lock(®ister_mutex); list_del(&timeri->open_list); /* force to stop the timer */ @@ -340,6 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) timer = timeri->timer; if (timer) { + timer->num_instances--; /* wait, until the active callback is finished */ spin_lock_irq(&timer->lock); while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { @@ -355,6 +379,7 @@ int snd_timer_close(struct snd_timer_instance *timeri) list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, open_list) { list_move_tail(&slave->open_list, &snd_timer_slave_list); + timer->num_instances--; slave->master = NULL; slave->timer = NULL; list_del_init(&slave->ack_list); @@ -382,9 +407,24 @@ int snd_timer_close(struct snd_timer_instance *timeri) module_put(timer->module); } - mutex_unlock(®ister_mutex); return 0; } + +/* + * close a timer instance + */ +int snd_timer_close(struct snd_timer_instance *timeri) +{ + int err; + + if (snd_BUG_ON(!timeri)) + return -ENXIO; + + mutex_lock(®ister_mutex); + err = snd_timer_close_locked(timeri); + mutex_unlock(®ister_mutex); + return err; +} EXPORT_SYMBOL(snd_timer_close); unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) @@ -393,7 +433,8 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) if (timeri == NULL) return 0; - if ((timer = timeri->timer) != NULL) { + timer = timeri->timer; + if (timer) { if (timer->hw.c_resolution) return timer->hw.c_resolution(timer); return timer->hw.resolution; @@ -855,6 +896,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, spin_lock_init(&timer->lock); tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); + timer->max_instances = 1000; /* default limit per timer */ if (card != NULL) { timer->module = card->module; err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); @@ -2096,8 +2138,7 @@ static int __init alsa_timer_init(void) err = snd_timer_register_system(); if (err < 0) { pr_err("ALSA: unable to register system timer (%i)\n", err); - put_device(&timer_dev); - return err; + goto put_timer; } err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0, @@ -2105,12 +2146,15 @@ static int __init alsa_timer_init(void) if (err < 0) { pr_err("ALSA: unable to register timer device (%i)\n", err); snd_timer_free_all(); - put_device(&timer_dev); - return err; + goto put_timer; } snd_timer_proc_init(); return 0; + +put_timer: + put_device(&timer_dev); + return err; } static void __exit alsa_timer_exit(void) diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c index 6a437eb66115..59127b6ef39e 100644 --- a/sound/core/timer_compat.c +++ b/sound/core/timer_compat.c @@ -133,7 +133,8 @@ enum { #endif /* CONFIG_X86_X32 */ }; -static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) +static long __snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = compat_ptr(arg); @@ -153,7 +154,7 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns case SNDRV_TIMER_IOCTL_PAUSE: case SNDRV_TIMER_IOCTL_PAUSE_OLD: case SNDRV_TIMER_IOCTL_NEXT_DEVICE: - return snd_timer_user_ioctl(file, cmd, (unsigned long)argp); + return __snd_timer_user_ioctl(file, cmd, (unsigned long)argp); case SNDRV_TIMER_IOCTL_GPARAMS32: return snd_timer_user_gparams_compat(file, argp); case SNDRV_TIMER_IOCTL_INFO32: @@ -167,3 +168,15 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns } return -ENOIOCTLCMD; } + +static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct snd_timer_user *tu = file->private_data; + long ret; + + mutex_lock(&tu->ioctl_lock); + ret = __snd_timer_user_ioctl_compat(file, cmd, arg); + mutex_unlock(&tu->ioctl_lock); + return ret; +} diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 6c58e6f73a01..e43af18d4383 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -484,3 +484,34 @@ void snd_ctl_sync_vmaster(struct snd_kcontrol *kcontrol, bool hook_only) master->hook(master->hook_private_data, master->val); } EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster); + +/** + * snd_ctl_apply_vmaster_slaves - Apply function to each vmaster slave + * @kctl: vmaster kctl element + * @func: function to apply + * @arg: optional function argument + * + * Apply the function @func to each slave kctl of the given vmaster kctl. + * Returns 0 if successful, or a negative error code. + */ +int snd_ctl_apply_vmaster_slaves(struct snd_kcontrol *kctl, + int (*func)(struct snd_kcontrol *, void *), + void *arg) +{ + struct link_master *master; + struct link_slave *slave; + int err; + + master = snd_kcontrol_chip(kctl); + err = master_init(master); + if (err < 0) + return err; + list_for_each_entry(slave, &master->slaves, list) { + err = func(&slave->slave, arg); + if (err < 0) + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_ctl_apply_vmaster_slaves); diff --git a/sound/drivers/Makefile b/sound/drivers/Makefile index 1a8440c8b138..615558a281c8 100644 --- a/sound/drivers/Makefile +++ b/sound/drivers/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 54f348a4fb78..135adb17703c 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -561,7 +561,7 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream) return bytes_to_frames(runtime, pos); } -static struct snd_pcm_hardware loopback_pcm_hardware = +static const struct snd_pcm_hardware loopback_pcm_hardware = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | @@ -750,7 +750,7 @@ static int loopback_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops loopback_playback_ops = { +static const struct snd_pcm_ops loopback_playback_ops = { .open = loopback_open, .close = loopback_close, .ioctl = snd_pcm_lib_ioctl, @@ -763,7 +763,7 @@ static struct snd_pcm_ops loopback_playback_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops loopback_capture_ops = { +static const struct snd_pcm_ops loopback_capture_ops = { .open = loopback_open, .close = loopback_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index dd5ed037adf2..c0939a0164a6 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -520,7 +520,7 @@ static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream) return get_dummy_ops(substream)->pointer(substream); } -static struct snd_pcm_hardware dummy_pcm_hardware = { +static const struct snd_pcm_hardware dummy_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index bdcb5721393b..18fd12996cf7 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c @@ -373,7 +373,7 @@ struct snd_ml403_ac97cr { struct snd_pcm_indirect2 capture_ind2_rec; }; -static struct snd_pcm_hardware snd_ml403_ac97cr_playback = { +static const struct snd_pcm_hardware snd_ml403_ac97cr_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -392,7 +392,7 @@ static struct snd_pcm_hardware snd_ml403_ac97cr_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ml403_ac97cr_capture = { +static const struct snd_pcm_hardware snd_ml403_ac97cr_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -759,7 +759,7 @@ static int snd_ml403_ac97cr_capture_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = { +static const struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = { .open = snd_ml403_ac97cr_playback_open, .close = snd_ml403_ac97cr_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -770,7 +770,7 @@ static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = { .pointer = snd_ml403_ac97cr_pcm_pointer, }; -static struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = { +static const struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = { .open = snd_ml403_ac97cr_capture_open, .close = snd_ml403_ac97cr_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 9b86e00d7d95..b6715764cd1c 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c @@ -148,7 +148,7 @@ static struct platform_driver snd_mpu401_driver = { #define IO_EXTENT 2 -static struct pnp_device_id snd_mpu401_pnpids[] = { +static const struct pnp_device_id snd_mpu401_pnpids[] = { { .id = "PNPb006" }, { .id = "" } }; diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 3a7c317ae012..b997222274bd 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c @@ -136,7 +136,7 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id) { struct snd_mpu401 *mpu = dev_id; - if (mpu == NULL) + if (!mpu) return IRQ_NONE; _snd_mpu401_uart_interrupt(mpu); return IRQ_HANDLED; @@ -157,7 +157,7 @@ irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id) { struct snd_mpu401 *mpu = dev_id; - if (mpu == NULL) + if (!mpu) return IRQ_NONE; uart_interrupt_tx(mpu); return IRQ_HANDLED; @@ -544,10 +544,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, out_enable, in_enable, &rmidi)) < 0) return err; mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); - if (mpu == NULL) { - snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n"); - snd_device_free(card, rmidi); - return -ENOMEM; + if (!mpu) { + err = -ENOMEM; + goto free_device; } rmidi->private_data = mpu; rmidi->private_free = snd_mpu401_uart_free; @@ -559,12 +558,12 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, if (! (info_flags & MPU401_INFO_INTEGRATED)) { int res_size = hardware == MPU401_HW_PC98II ? 4 : 2; mpu->res = request_region(port, res_size, "MPU401 UART"); - if (mpu->res == NULL) { + if (!mpu->res) { snd_printk(KERN_ERR "mpu401_uart: " "unable to grab port 0x%lx size %d\n", port, res_size); - snd_device_free(card, rmidi); - return -EBUSY; + err = -EBUSY; + goto free_device; } } if (info_flags & MPU401_INFO_MMIO) { @@ -584,8 +583,8 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, "MPU401 UART", (void *) mpu)) { snd_printk(KERN_ERR "mpu401_uart: " "unable to grab IRQ %d\n", irq); - snd_device_free(card, rmidi); - return -EBUSY; + err = -EBUSY; + goto free_device; } } if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK)) @@ -613,6 +612,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, if (rrawmidi) *rrawmidi = rmidi; return 0; +free_device: + snd_device_free(card, rmidi); + return err; } EXPORT_SYMBOL(snd_mpu401_uart_new); diff --git a/sound/drivers/opl3/Makefile b/sound/drivers/opl3/Makefile index d72b1e7b51c4..83bca9f1fbdf 100644 --- a/sound/drivers/opl3/Makefile +++ b/sound/drivers/opl3/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index d5e5b4657b4b..588963d6be28 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c @@ -355,10 +355,8 @@ int snd_opl3_new(struct snd_card *card, *ropl3 = NULL; opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL); - if (opl3 == NULL) { - snd_printk(KERN_ERR "opl3: cannot allocate\n"); + if (!opl3) return -ENOMEM; - } opl3->card = card; opl3->hardware = hardware; diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index 7821b07415a7..13c0a7e1bc2b 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c @@ -131,8 +131,8 @@ static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) { printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice); for (i = 0; i < opl3->max_voices; i++) - printk("%c", *(str + opl3->voices[i].state + 1)); - printk("\n"); + printk(KERN_CONT "%c", *(str + opl3->voices[i].state + 1)); + printk(KERN_CONT "\n"); } #endif diff --git a/sound/drivers/opl4/Makefile b/sound/drivers/opl4/Makefile index c8eaa433d71a..6e86a4092b4c 100644 --- a/sound/drivers/opl4/Makefile +++ b/sound/drivers/opl4/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 72e2d0012084..0dd3f46eb03e 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c @@ -108,22 +108,17 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev) return err; err = snd_pcsp_create(card); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; + if (!nopcm) { err = snd_pcsp_new_pcm(&pcsp_chip); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; } err = snd_pcsp_new_mixer(&pcsp_chip, nopcm); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; strcpy(card->driver, "PC-Speaker"); strcpy(card->shortname, "pcsp"); @@ -131,12 +126,14 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev) pcsp_chip.port); err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; return 0; + +free_card: + snd_card_free(card); + return err; } static int alsa_card_pcsp_init(struct device *dev) diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h index fc7a2dc410a1..036ad3c99a43 100644 --- a/sound/drivers/pcsp/pcsp.h +++ b/sound/drivers/pcsp/pcsp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PC-Speaker driver for Linux * diff --git a/sound/drivers/pcsp/pcsp_input.h b/sound/drivers/pcsp/pcsp_input.h index d692749b8c9b..e80079b38a56 100644 --- a/sound/drivers/pcsp/pcsp_input.h +++ b/sound/drivers/pcsp/pcsp_input.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * PC-Speaker driver for Linux * diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index 44b3632f6940..8f0f05bbc081 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PC-Speaker driver for Linux * @@ -285,7 +286,7 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream return bytes_to_frames(substream->runtime, pos); } -static struct snd_pcm_hardware snd_pcsp_playback = { +static const struct snd_pcm_hardware snd_pcsp_playback = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_HALF_DUPLEX | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c index f1e1defc09b1..be2990451bcd 100644 --- a/sound/drivers/pcsp/pcsp_mixer.c +++ b/sound/drivers/pcsp/pcsp_mixer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PC-Speaker driver for Linux * diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c index f684fffd1397..121357397a6d 100644 --- a/sound/drivers/vx/vx_core.c +++ b/sound/drivers/vx/vx_core.c @@ -256,8 +256,8 @@ int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh) if (rmh->LgCmd > 1) { printk(KERN_DEBUG " "); for (i = 1; i < rmh->LgCmd; i++) - printk("0x%06x ", rmh->Cmd[i]); - printk("\n"); + printk(KERN_CONT "0x%06x ", rmh->Cmd[i]); + printk(KERN_CONT "\n"); } #endif /* Check bit M is set according to length of the command */ diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index d318a33b6cfb..380a028469c4 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -500,7 +500,7 @@ static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe) * playback hw information */ -static struct snd_pcm_hardware vx_pcm_playback_hw = { +static const struct snd_pcm_hardware vx_pcm_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/ /*SNDRV_PCM_INFO_RESUME*/), @@ -891,7 +891,7 @@ static const struct snd_pcm_ops vx_pcm_playback_ops = { * playback hw information */ -static struct snd_pcm_hardware vx_pcm_capture_hw = { +static const struct snd_pcm_hardware vx_pcm_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/ /*SNDRV_PCM_INFO_RESUME*/), diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile index 1b98fa3fa3d4..44a7b510b75b 100644 --- a/sound/firewire/Makefile +++ b/sound/firewire/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # To find a header included by define_trace.h. CFLAGS_amdtp-stream.o := -I$(src) diff --git a/sound/firewire/amdtp-am824.h b/sound/firewire/amdtp-am824.h index b56e61fc997d..06d280783581 100644 --- a/sound/firewire/amdtp-am824.h +++ b/sound/firewire/amdtp-am824.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED #define SOUND_FIREWIRE_AMDTP_AM824_H_INCLUDED diff --git a/sound/firewire/amdtp-stream.h b/sound/firewire/amdtp-stream.h index ed6eafd10992..a608dae83348 100644 --- a/sound/firewire/amdtp-stream.h +++ b/sound/firewire/amdtp-stream.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_AMDTP_H_INCLUDED #define SOUND_FIREWIRE_AMDTP_H_INCLUDED diff --git a/sound/firewire/bebob/Makefile b/sound/firewire/bebob/Makefile index dd454867240d..14bc84c51ef5 100644 --- a/sound/firewire/bebob/Makefile +++ b/sound/firewire/bebob/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-bebob-objs := bebob_command.o bebob_stream.o bebob_proc.o bebob_midi.o \ bebob_pcm.o bebob_hwdep.o bebob_terratec.o \ bebob_yamaha_terratec.o bebob_focusrite.o bebob_maudio.o \ diff --git a/sound/firewire/bebob/bebob.h b/sound/firewire/bebob/bebob.h index 17678d6ab5a2..df1b1e94c43c 100644 --- a/sound/firewire/bebob/bebob.h +++ b/sound/firewire/bebob/bebob.h @@ -58,7 +58,7 @@ enum snd_bebob_clock_type { struct snd_bebob_clock_spec { unsigned int num; const char *const *labels; - enum snd_bebob_clock_type *types; + const enum snd_bebob_clock_type *types; int (*get)(struct snd_bebob *bebob, unsigned int *id); }; struct snd_bebob_rate_spec { diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c index f11090057949..52b8b61ecddd 100644 --- a/sound/firewire/bebob/bebob_focusrite.c +++ b/sound/firewire/bebob/bebob_focusrite.c @@ -103,12 +103,12 @@ saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value) &data, sizeof(__be32), 0); } -static enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = { +static const enum snd_bebob_clock_type saffirepro_10_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */ }; -static enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = { +static const enum snd_bebob_clock_type saffirepro_26_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* ADAT1 */ @@ -201,7 +201,7 @@ end: } const struct snd_bebob_spec saffire_le_spec; -static enum snd_bebob_clock_type saffire_both_clk_src_types[] = { +static const enum snd_bebob_clock_type saffire_both_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, }; diff --git a/sound/firewire/bebob/bebob_maudio.c b/sound/firewire/bebob/bebob_maudio.c index d10208f92edf..bd55620c6a47 100644 --- a/sound/firewire/bebob/bebob_maudio.c +++ b/sound/firewire/bebob/bebob_maudio.c @@ -340,7 +340,7 @@ end: } /* Clock source control for special firmware */ -static enum snd_bebob_clock_type special_clk_types[] = { +static const enum snd_bebob_clock_type special_clk_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, /* With digital mute */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* SPDIF/ADAT */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */ diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c index 2fdaf93e7a8d..9770c2127a7a 100644 --- a/sound/firewire/bebob/bebob_terratec.c +++ b/sound/firewire/bebob/bebob_terratec.c @@ -8,7 +8,7 @@ #include "./bebob.h" -static enum snd_bebob_clock_type phase88_rack_clk_src_types[] = { +static const enum snd_bebob_clock_type phase88_rack_clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* Word Clock */ diff --git a/sound/firewire/bebob/bebob_yamaha_terratec.c b/sound/firewire/bebob/bebob_yamaha_terratec.c index a6be3e7138e0..8bd78fef3516 100644 --- a/sound/firewire/bebob/bebob_yamaha_terratec.c +++ b/sound/firewire/bebob/bebob_yamaha_terratec.c @@ -31,7 +31,7 @@ * Yamaha GO 44 and GO 46. Yamaha and Terratec had cooperated for these models. */ -static enum snd_bebob_clock_type clk_src_types[] = { +static const enum snd_bebob_clock_type clk_src_types[] = { SND_BEBOB_CLOCK_TYPE_INTERNAL, SND_BEBOB_CLOCK_TYPE_EXTERNAL, /* S/PDIF */ }; diff --git a/sound/firewire/cmp.h b/sound/firewire/cmp.h index ebcb48484fca..b60b415caa8f 100644 --- a/sound/firewire/cmp.h +++ b/sound/firewire/cmp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_CMP_H_INCLUDED #define SOUND_FIREWIRE_CMP_H_INCLUDED diff --git a/sound/firewire/dice/dice-interface.h b/sound/firewire/dice/dice-interface.h index 47f2c0a6f5d9..15a484b05298 100644 --- a/sound/firewire/dice/dice-interface.h +++ b/sound/firewire/dice/dice-interface.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_DICE_INTERFACE_H_INCLUDED #define SOUND_FIREWIRE_DICE_INTERFACE_H_INCLUDED diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 25e9f77275c4..4ddb4cdd054b 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c @@ -26,7 +26,7 @@ MODULE_LICENSE("GPL v2"); */ static bool force_two_pcm_support(struct fw_unit *unit) { - const char *const models[] = { + static const char *const models[] = { /* TC Electronic models. */ "StudioKonnekt48", /* Focusrite models. */ diff --git a/sound/firewire/fcp.h b/sound/firewire/fcp.h index 63ae4f7ce3af..512f7c40903a 100644 --- a/sound/firewire/fcp.h +++ b/sound/firewire/fcp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_FCP_H_INCLUDED #define SOUND_FIREWIRE_FCP_H_INCLUDED diff --git a/sound/firewire/fireface/ff-pcm.c b/sound/firewire/fireface/ff-pcm.c index d12a0e3a4219..e3c16308363d 100644 --- a/sound/firewire/fireface/ff-pcm.c +++ b/sound/firewire/fireface/ff-pcm.c @@ -138,16 +138,12 @@ static int pcm_open(struct snd_pcm_substream *substream) return err; err = pcm_init_hw_params(ff, substream); - if (err < 0) { - snd_ff_stream_lock_release(ff); - return err; - } + if (err < 0) + goto release_lock; err = ff->spec->protocol->get_clock(ff, &rate, &src); - if (err < 0) { - snd_ff_stream_lock_release(ff); - return err; - } + if (err < 0) + goto release_lock; if (src != SND_FF_CLOCK_SRC_INTERNAL) { for (i = 0; i < CIP_SFC_COUNT; ++i) { @@ -159,8 +155,8 @@ static int pcm_open(struct snd_pcm_substream *substream) * streaming engine can't support. */ if (i >= CIP_SFC_COUNT) { - snd_ff_stream_lock_release(ff); - return -EIO; + err = -EIO; + goto release_lock; } substream->runtime->hw.rate_min = rate; @@ -177,6 +173,10 @@ static int pcm_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); return 0; + +release_lock: + snd_ff_stream_lock_release(ff); + return err; } static int pcm_close(struct snd_pcm_substream *substream) diff --git a/sound/firewire/fireface/ff-protocol-ff400.c b/sound/firewire/fireface/ff-protocol-ff400.c index fcec6de80eeb..12aa15df435d 100644 --- a/sound/firewire/fireface/ff-protocol-ff400.c +++ b/sound/firewire/fireface/ff-protocol-ff400.c @@ -356,7 +356,7 @@ static void ff400_dump_clock_config(struct snd_ff *ff, snd_iprintf(buffer, "Sync to clock source: %s\n", src); } -struct snd_ff_protocol snd_ff_protocol_ff400 = { +const struct snd_ff_protocol snd_ff_protocol_ff400 = { .get_clock = ff400_get_clock, .begin_session = ff400_begin_session, .finish_session = ff400_finish_session, diff --git a/sound/firewire/fireface/ff.c b/sound/firewire/fireface/ff.c index eee7c8eac7a6..4974bc7980e9 100644 --- a/sound/firewire/fireface/ff.c +++ b/sound/firewire/fireface/ff.c @@ -157,7 +157,7 @@ static void snd_ff_remove(struct fw_unit *unit) } } -static struct snd_ff_spec spec_ff400 = { +static const struct snd_ff_spec spec_ff400 = { .name = "Fireface400", .pcm_capture_channels = {18, 14, 10}, .pcm_playback_channels = {18, 14, 10}, diff --git a/sound/firewire/fireface/ff.h b/sound/firewire/fireface/ff.h index 3cb812a50030..64df44beb950 100644 --- a/sound/firewire/fireface/ff.h +++ b/sound/firewire/fireface/ff.h @@ -47,7 +47,7 @@ struct snd_ff_spec { unsigned int midi_in_ports; unsigned int midi_out_ports; - struct snd_ff_protocol *protocol; + const struct snd_ff_protocol *protocol; }; struct snd_ff { @@ -112,7 +112,7 @@ struct snd_ff_protocol { u64 midi_rx_port_1_reg; }; -extern struct snd_ff_protocol snd_ff_protocol_ff400; +extern const struct snd_ff_protocol snd_ff_protocol_ff400; int snd_ff_transaction_register(struct snd_ff *ff); int snd_ff_transaction_reregister(struct snd_ff *ff); diff --git a/sound/firewire/fireworks/fireworks_proc.c b/sound/firewire/fireworks/fireworks_proc.c index beb0a0ffee57..9c21f31b8b21 100644 --- a/sound/firewire/fireworks/fireworks_proc.c +++ b/sound/firewire/fireworks/fireworks_proc.c @@ -12,7 +12,7 @@ static inline const char* get_phys_name(struct snd_efw_phys_grp *grp, bool input) { - const char *const ch_type[] = { + static const char *const ch_type[] = { "Analog", "S/PDIF", "ADAT", "S/PDIF or ADAT", "Mirroring", "Headphones", "I2S", "Guitar", "Pirzo Guitar", "Guitar String", }; diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 48d6dca471c6..5826aa8362f1 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c @@ -444,7 +444,7 @@ static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream) static int isight_create_pcm(struct isight *isight) { - static struct snd_pcm_ops ops = { + static const struct snd_pcm_ops ops = { .open = isight_open, .close = isight_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/firewire/iso-resources.h b/sound/firewire/iso-resources.h index 5a9af7c61657..34f85e9e8830 100644 --- a/sound/firewire/iso-resources.h +++ b/sound/firewire/iso-resources.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED #define SOUND_FIREWIRE_ISO_RESOURCES_H_INCLUDED diff --git a/sound/firewire/lib.h b/sound/firewire/lib.h index eef70922ed89..dc815dc3933e 100644 --- a/sound/firewire/lib.h +++ b/sound/firewire/lib.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_LIB_H_INCLUDED #define SOUND_FIREWIRE_LIB_H_INCLUDED diff --git a/sound/firewire/motu/Makefile b/sound/firewire/motu/Makefile index 728f586e754b..7c502d35103c 100644 --- a/sound/firewire/motu/Makefile +++ b/sound/firewire/motu/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 CFLAGS_amdtp-motu.o := -I$(src) snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o motu-stream.o \ diff --git a/sound/firewire/motu/motu-midi.c b/sound/firewire/motu/motu-midi.c index e3acfcc53f4e..e55cab6d79c7 100644 --- a/sound/firewire/motu/motu-midi.c +++ b/sound/firewire/motu/motu-midi.c @@ -128,12 +128,12 @@ static void set_midi_substream_names(struct snd_motu *motu, int snd_motu_create_midi_devices(struct snd_motu *motu) { - static struct snd_rawmidi_ops capture_ops = { + static const struct snd_rawmidi_ops capture_ops = { .open = midi_capture_open, .close = midi_capture_close, .trigger = midi_capture_trigger, }; - static struct snd_rawmidi_ops playback_ops = { + static const struct snd_rawmidi_ops playback_ops = { .open = midi_playback_open, .close = midi_playback_close, .trigger = midi_playback_trigger, diff --git a/sound/firewire/motu/motu-pcm.c b/sound/firewire/motu/motu-pcm.c index a2b50df70874..4330220890e8 100644 --- a/sound/firewire/motu/motu-pcm.c +++ b/sound/firewire/motu/motu-pcm.c @@ -145,7 +145,7 @@ static int pcm_open(struct snd_pcm_substream *substream) mutex_lock(&motu->mutex); - err = protocol->cache_packet_formats(motu); + err = snd_motu_stream_cache_packet_formats(motu); if (err < 0) goto err_locked; @@ -352,7 +352,7 @@ static int playback_ack(struct snd_pcm_substream *substream) int snd_motu_create_pcm_devices(struct snd_motu *motu) { - static struct snd_pcm_ops capture_ops = { + static const struct snd_pcm_ops capture_ops = { .open = pcm_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -365,7 +365,7 @@ int snd_motu_create_pcm_devices(struct snd_motu *motu) .page = snd_pcm_lib_get_vmalloc_page, .mmap = snd_pcm_lib_mmap_vmalloc, }; - static struct snd_pcm_ops playback_ops = { + static const struct snd_pcm_ops playback_ops = { .open = pcm_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/firewire/motu/motu-protocol-v2.c b/sound/firewire/motu/motu-protocol-v2.c index 05b5d287c2f3..525b746330be 100644 --- a/sound/firewire/motu/motu-protocol-v2.c +++ b/sound/firewire/motu/motu-protocol-v2.c @@ -217,12 +217,7 @@ static int v2_cache_packet_formats(struct snd_motu *motu) calculate_differed_part(&motu->rx_packet_formats, motu->spec->flags, data, V2_OPT_OUT_IFACE_MASK, V2_OPT_OUT_IFACE_SHIFT); - motu->tx_packet_formats.midi_flag_offset = 4; - motu->tx_packet_formats.midi_byte_offset = 6; motu->tx_packet_formats.pcm_byte_offset = 10; - - motu->rx_packet_formats.midi_flag_offset = 4; - motu->rx_packet_formats.midi_byte_offset = 6; motu->rx_packet_formats.pcm_byte_offset = 10; return 0; diff --git a/sound/firewire/motu/motu-protocol-v3.c b/sound/firewire/motu/motu-protocol-v3.c index ddb647254ed2..c7cd9864dc4d 100644 --- a/sound/firewire/motu/motu-protocol-v3.c +++ b/sound/firewire/motu/motu-protocol-v3.c @@ -291,12 +291,7 @@ static int v3_cache_packet_formats(struct snd_motu *motu) V3_ENABLE_OPT_OUT_IFACE_A, V3_NO_ADAT_OPT_OUT_IFACE_A, V3_ENABLE_OPT_OUT_IFACE_B, V3_NO_ADAT_OPT_OUT_IFACE_B); - motu->tx_packet_formats.midi_flag_offset = 8; - motu->tx_packet_formats.midi_byte_offset = 7; motu->tx_packet_formats.pcm_byte_offset = 10; - - motu->rx_packet_formats.midi_flag_offset = 8; - motu->rx_packet_formats.midi_byte_offset = 7; motu->rx_packet_formats.pcm_byte_offset = 10; return 0; diff --git a/sound/firewire/motu/motu-stream.c b/sound/firewire/motu/motu-stream.c index bd458029099e..73e7a5e527fc 100644 --- a/sound/firewire/motu/motu-stream.c +++ b/sound/firewire/motu/motu-stream.c @@ -33,7 +33,8 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate) u32 data; int err; - if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) + if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q)) midi_ports = 1; /* Set packet formation to our packet streaming engine. */ @@ -42,6 +43,12 @@ static int start_both_streams(struct snd_motu *motu, unsigned int rate) if (err < 0) return err; + if ((motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) + midi_ports = 1; + else + midi_ports = 0; + err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports, &motu->tx_packet_formats); if (err < 0) @@ -141,6 +148,33 @@ static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream) fw_iso_resources_free(resources); } +int snd_motu_stream_cache_packet_formats(struct snd_motu *motu) +{ + int err; + + err = motu->spec->protocol->cache_packet_formats(motu); + if (err < 0) + return err; + + if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) { + motu->tx_packet_formats.midi_flag_offset = 4; + motu->tx_packet_formats.midi_byte_offset = 6; + } else if (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q) { + motu->tx_packet_formats.midi_flag_offset = 8; + motu->tx_packet_formats.midi_byte_offset = 7; + } + + if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) { + motu->rx_packet_formats.midi_flag_offset = 4; + motu->rx_packet_formats.midi_byte_offset = 6; + } else if (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) { + motu->rx_packet_formats.midi_flag_offset = 8; + motu->rx_packet_formats.midi_byte_offset = 7; + } + + return 0; +} + static int ensure_packet_formats(struct snd_motu *motu) { __be32 reg; @@ -184,7 +218,7 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) stop_both_streams(motu); } - err = protocol->cache_packet_formats(motu); + err = snd_motu_stream_cache_packet_formats(motu); if (err < 0) return err; @@ -219,24 +253,21 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) if (err < 0) { dev_err(&motu->unit->device, "fail to start isochronous comm: %d\n", err); - stop_both_streams(motu); - return err; + goto stop_streams; } err = start_isoc_ctx(motu, &motu->rx_stream); if (err < 0) { dev_err(&motu->unit->device, "fail to start IT context: %d\n", err); - stop_both_streams(motu); - return err; + goto stop_streams; } err = protocol->switch_fetching_mode(motu, true); if (err < 0) { dev_err(&motu->unit->device, "fail to enable frame fetching: %d\n", err); - stop_both_streams(motu); - return err; + goto stop_streams; } } @@ -247,12 +278,15 @@ int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) dev_err(&motu->unit->device, "fail to start IR context: %d", err); amdtp_stream_stop(&motu->rx_stream); - stop_both_streams(motu); - return err; + goto stop_streams; } } return 0; + +stop_streams: + stop_both_streams(motu); + return err; } void snd_motu_stream_stop_duplex(struct snd_motu *motu) diff --git a/sound/firewire/motu/motu.c b/sound/firewire/motu/motu.c index 59a270406353..0d6b526105ab 100644 --- a/sound/firewire/motu/motu.c +++ b/sound/firewire/motu/motu.c @@ -103,7 +103,10 @@ static void do_registration(struct work_struct *work) if (err < 0) goto error; - if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) { + if ((motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_RX_MIDI_3RD_Q) || + (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_2ND_Q) || + (motu->spec->flags & SND_MOTU_SPEC_TX_MIDI_3RD_Q)) { err = snd_motu_create_midi_devices(motu); if (err < 0) goto error; @@ -191,20 +194,21 @@ static void motu_bus_update(struct fw_unit *unit) snd_motu_transaction_reregister(motu); } -static struct snd_motu_spec motu_828mk2 = { +static const struct snd_motu_spec motu_828mk2 = { .name = "828mk2", .protocol = &snd_motu_protocol_v2, .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | SND_MOTU_SPEC_TX_MICINST_CHUNK | SND_MOTU_SPEC_TX_RETURN_CHUNK | SND_MOTU_SPEC_HAS_OPT_IFACE_A | - SND_MOTU_SPEC_HAS_MIDI, + SND_MOTU_SPEC_RX_MIDI_2ND_Q | + SND_MOTU_SPEC_TX_MIDI_2ND_Q, .analog_in_ports = 8, .analog_out_ports = 8, }; -static struct snd_motu_spec motu_828mk3 = { +static const struct snd_motu_spec motu_828mk3 = { .name = "828mk3", .protocol = &snd_motu_protocol_v3, .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | @@ -214,12 +218,25 @@ static struct snd_motu_spec motu_828mk3 = { SND_MOTU_SPEC_TX_REVERB_CHUNK | SND_MOTU_SPEC_HAS_OPT_IFACE_A | SND_MOTU_SPEC_HAS_OPT_IFACE_B | - SND_MOTU_SPEC_HAS_MIDI, + SND_MOTU_SPEC_RX_MIDI_3RD_Q | + SND_MOTU_SPEC_TX_MIDI_3RD_Q, .analog_in_ports = 8, .analog_out_ports = 8, }; +static const struct snd_motu_spec motu_audio_express = { + .name = "AudioExpress", + .protocol = &snd_motu_protocol_v3, + .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | + SND_MOTU_SPEC_TX_MICINST_CHUNK | + SND_MOTU_SPEC_TX_RETURN_CHUNK | + SND_MOTU_SPEC_RX_MIDI_2ND_Q | + SND_MOTU_SPEC_TX_MIDI_3RD_Q, + .analog_in_ports = 2, + .analog_out_ports = 4, +}; + #define SND_MOTU_DEV_ENTRY(model, data) \ { \ .match_flags = IEEE1394_MATCH_VENDOR_ID | \ @@ -235,6 +252,7 @@ static const struct ieee1394_device_id motu_id_table[] = { SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2), SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */ SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */ + SND_MOTU_DEV_ENTRY(0x104800, &motu_audio_express), { } }; MODULE_DEVICE_TABLE(ieee1394, motu_id_table); diff --git a/sound/firewire/motu/motu.h b/sound/firewire/motu/motu.h index 8d6a4a3af9cc..4b23cf337c4b 100644 --- a/sound/firewire/motu/motu.h +++ b/sound/firewire/motu/motu.h @@ -82,7 +82,10 @@ enum snd_motu_spec_flags { SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020, SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040, SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080, - SND_MOTU_SPEC_HAS_MIDI = 0x0100, + SND_MOTU_SPEC_RX_MIDI_2ND_Q = 0x0100, + SND_MOTU_SPEC_RX_MIDI_3RD_Q = 0x0200, + SND_MOTU_SPEC_TX_MIDI_2ND_Q = 0x0400, + SND_MOTU_SPEC_TX_MIDI_3RD_Q = 0x0800, }; #define SND_MOTU_CLOCK_RATE_COUNT 6 @@ -146,6 +149,7 @@ void snd_motu_transaction_unregister(struct snd_motu *motu); int snd_motu_stream_init_duplex(struct snd_motu *motu); void snd_motu_stream_destroy_duplex(struct snd_motu *motu); +int snd_motu_stream_cache_packet_formats(struct snd_motu *motu); int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate); void snd_motu_stream_stop_duplex(struct snd_motu *motu); int snd_motu_stream_lock_try(struct snd_motu *motu); diff --git a/sound/firewire/oxfw/oxfw-scs1x.c b/sound/firewire/oxfw/oxfw-scs1x.c index 93209ebd9121..02d595665898 100644 --- a/sound/firewire/oxfw/oxfw-scs1x.c +++ b/sound/firewire/oxfw/oxfw-scs1x.c @@ -297,12 +297,6 @@ static void midi_capture_trigger(struct snd_rawmidi_substream *stream, int up) } } -static const struct snd_rawmidi_ops midi_capture_ops = { - .open = midi_capture_open, - .close = midi_capture_close, - .trigger = midi_capture_trigger, -}; - static int midi_playback_open(struct snd_rawmidi_substream *stream) { return 0; @@ -363,6 +357,11 @@ void snd_oxfw_scs1x_update(struct snd_oxfw *oxfw) int snd_oxfw_scs1x_add(struct snd_oxfw *oxfw) { + static const struct snd_rawmidi_ops midi_capture_ops = { + .open = midi_capture_open, + .close = midi_capture_close, + .trigger = midi_capture_trigger, + }; static const struct snd_rawmidi_ops midi_playback_ops = { .open = midi_playback_open, .close = midi_playback_close, diff --git a/sound/firewire/packets-buffer.h b/sound/firewire/packets-buffer.h index 6513c5cb6ea9..99e963c271e1 100644 --- a/sound/firewire/packets-buffer.h +++ b/sound/firewire/packets-buffer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED #define SOUND_FIREWIRE_PACKETS_BUFFER_H_INCLUDED diff --git a/sound/firewire/tascam/tascam.c b/sound/firewire/tascam/tascam.c index 9dc93a7eb9da..44ad41fb7374 100644 --- a/sound/firewire/tascam/tascam.c +++ b/sound/firewire/tascam/tascam.c @@ -12,7 +12,7 @@ MODULE_DESCRIPTION("TASCAM FireWire series Driver"); MODULE_AUTHOR("Takashi Sakamoto "); MODULE_LICENSE("GPL v2"); -static struct snd_tscm_spec model_specs[] = { +static const struct snd_tscm_spec model_specs[] = { { .name = "FW-1884", .has_adat = true, diff --git a/sound/hda/Makefile b/sound/hda/Makefile index 3b9bedee2fa4..e4e726f2ce98 100644 --- a/sound/hda/Makefile +++ b/sound/hda/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-hda-core-objs := hda_bus_type.o hdac_bus.o hdac_device.o hdac_sysfs.o \ hdac_regmap.o hdac_controller.o hdac_stream.o array.o hdmi_chmap.o diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index 978dc1801b3a..f6d2985b2520 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c @@ -284,6 +284,11 @@ int snd_hdac_bus_parse_capabilities(struct hdac_bus *bus) dev_dbg(bus->dev, "HDA capability ID: 0x%x\n", (cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF); + if (cur_cap == -1) { + dev_dbg(bus->dev, "Invalid capability reg read\n"); + break; + } + switch ((cur_cap & AZX_CAP_HDR_ID_MASK) >> AZX_CAP_HDR_ID_OFF) { case AZX_ML_CAP_ID: dev_dbg(bus->dev, "Found ML capability\n"); diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 0659bf389489..038a180d3f81 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -336,7 +336,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_i915_register_notifier); /* check whether intel graphics is present */ static bool i915_gfx_present(void) { - static struct pci_device_id ids[] = { + static const struct pci_device_id ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), .class = PCI_BASE_CLASS_DISPLAY << 16, .class_mask = 0xff << 16 }, diff --git a/sound/hda/hdac_sysfs.c b/sound/hda/hdac_sysfs.c index 42d61bf41969..3c2d45ee6ab8 100644 --- a/sound/hda/hdac_sysfs.c +++ b/sound/hda/hdac_sysfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sysfs support for HD-audio core device */ diff --git a/sound/hda/local.h b/sound/hda/local.h index 0d5bb159d538..7258fa8ce268 100644 --- a/sound/hda/local.h +++ b/sound/hda/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Local helper macros and functions for HD-audio core drivers */ diff --git a/sound/hda/trace.h b/sound/hda/trace.h index e27e2c0b7b17..70af6c815089 100644 --- a/sound/hda/trace.h +++ b/sound/hda/trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM hda diff --git a/sound/i2c/Makefile b/sound/i2c/Makefile index 36879bf88700..09978855e08e 100644 --- a/sound/i2c/Makefile +++ b/sound/i2c/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile index 5526b03b95a2..1a4ce1236146 100644 --- a/sound/i2c/other/Makefile +++ b/sound/i2c/other/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2003 by Jaroslav Kysela diff --git a/sound/isa/Makefile b/sound/isa/Makefile index 9a15f1497b10..5eaddbf4a712 100644 --- a/sound/isa/Makefile +++ b/sound/isa/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 769226515f0d..4be6c1245820 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c @@ -63,7 +63,7 @@ MODULE_PARM_DESC(enable, "Enable ad1816a based soundcard."); module_param_array(clockfreq, int, NULL, 0444); MODULE_PARM_DESC(clockfreq, "Clock frequency for ad1816a driver (default = 0)."); -static struct pnp_card_device_id snd_ad1816a_pnpids[] = { +static const struct pnp_card_device_id snd_ad1816a_pnpids[] = { /* Analog Devices AD1815 */ { .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } }, /* Analog Device AD1816? */ diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 5c815f5fb044..923201414469 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c @@ -339,7 +339,7 @@ static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id) } -static struct snd_pcm_hardware snd_ad1816a_playback = { +static const struct snd_pcm_hardware snd_ad1816a_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | @@ -358,7 +358,7 @@ static struct snd_pcm_hardware snd_ad1816a_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ad1816a_capture = { +static const struct snd_pcm_hardware snd_ad1816a_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | @@ -653,7 +653,7 @@ int snd_ad1816a_create(struct snd_card *card, return 0; } -static struct snd_pcm_ops snd_ad1816a_playback_ops = { +static const struct snd_pcm_ops snd_ad1816a_playback_ops = { .open = snd_ad1816a_playback_open, .close = snd_ad1816a_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -664,7 +664,7 @@ static struct snd_pcm_ops snd_ad1816a_playback_ops = { .pointer = snd_ad1816a_playback_pointer, }; -static struct snd_pcm_ops snd_ad1816a_capture_ops = { +static const struct snd_pcm_ops snd_ad1816a_capture_ops = { .open = snd_ad1816a_capture_open, .close = snd_ad1816a_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index e739b1c85c25..7c8e92f62f3b 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -110,13 +110,17 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n) if (error < 0) goto out; - strcpy(card->driver, "AD1848"); - strcpy(card->shortname, chip->pcm->name); + strlcpy(card->driver, "AD1848", sizeof(card->driver)); + strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); - sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - chip->pcm->name, chip->port, irq[n], dma1[n]); - if (thinkpad[n]) - strcat(card->longname, " [Thinkpad]"); + if (!thinkpad[n]) + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d", + chip->pcm->name, chip->port, irq[n], dma1[n]); + else + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d [Thinkpad]", + chip->pcm->name, chip->port, irq[n], dma1[n]); error = snd_card_register(card); if (error < 0) diff --git a/sound/isa/als100.c b/sound/isa/als100.c index bc9ea306ee02..f63142ec287e 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c @@ -79,7 +79,7 @@ struct snd_card_als100 { struct snd_sb *chip; }; -static struct pnp_card_device_id snd_als100_pnpids[] = { +static const struct pnp_card_device_id snd_als100_pnpids[] = { /* DT197A30 */ { .id = "RWB1688", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } }, @@ -222,15 +222,16 @@ static int snd_card_als100_probe(int dev, if (pid->driver_data == SB_HW_DT019X) { strcpy(card->driver, "DT-019X"); strcpy(card->shortname, "Diamond Tech. DT-019X"); - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", - card->shortname, chip->name, chip->port, - irq[dev], dma8[dev]); + snprintf(card->longname, sizeof(card->longname), + "Diamond Tech. DT-019X, %s at 0x%lx, irq %d, dma %d", + chip->name, chip->port, irq[dev], dma8[dev]); } else { strcpy(card->driver, "ALS100"); strcpy(card->shortname, "Avance Logic ALS100"); - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, chip->name, chip->port, - irq[dev], dma8[dev], dma16[dev]); + snprintf(card->longname, sizeof(card->longname), + "Avance Logic ALS100, %s at 0x%lx, irq %d, dma %d&%d", + chip->name, chip->port, irq[dev], dma8[dev], + dma16[dev]); } if ((error = snd_sb16dsp_pcm(chip, 0)) < 0) { diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index fff186fa621e..4e6fad4f94d9 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -79,7 +79,7 @@ struct snd_card_azt2320 { struct snd_wss *chip; }; -static struct pnp_card_device_id snd_azt2320_pnpids[] = { +static const struct pnp_card_device_id snd_azt2320_pnpids[] = { /* PRO16V */ { .id = "AZT1008", .devs = { { "AZT1008" }, { "AZT2001" }, } }, /* Aztech Sound Galaxy 16 */ diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index f64b29ab5cc7..6b8c46942efb 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -182,7 +182,7 @@ struct snd_cmi8330 { #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_cmi8330_pnpids[] = { +static const struct pnp_card_device_id snd_cmi8330_pnpids[] = { { .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } }, { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, { .id = "" } diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index e8edd9017a2f..d90ab9558f7f 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c @@ -109,13 +109,17 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n) if (error < 0) goto out; - strcpy(card->driver, "CS4231"); - strcpy(card->shortname, chip->pcm->name); + strlcpy(card->driver, "CS4231", sizeof(card->driver)); + strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); - sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - chip->pcm->name, chip->port, irq[n], dma1[n]); - if (dma2[n] >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); + if (dma2[n] < 0) + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d", + chip->pcm->name, chip->port, irq[n], dma1[n]); + else + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d, dma %d&%d", + chip->pcm->name, chip->port, irq[n], dma1[n], dma2[n]); error = snd_wss_mixer(chip); if (error < 0) diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 1f9a3b2be7a1..70559e59d18f 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -149,7 +149,7 @@ static const struct pnp_device_id snd_cs423x_pnpbiosids[] = { MODULE_DEVICE_TABLE(pnp, snd_cs423x_pnpbiosids); #define CS423X_ISAPNP_DRIVER "cs4232_isapnp" -static struct pnp_card_device_id snd_cs423x_pnpids[] = { +static const struct pnp_card_device_id snd_cs423x_pnpids[] = { /* Philips PCA70PS */ { .id = "CSC0d32", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } }, /* TerraTec Maestro 32/96 (CS4232) */ @@ -419,15 +419,17 @@ static int snd_cs423x_probe(struct snd_card *card, int dev) if (err < 0) return err; } - strcpy(card->driver, chip->pcm->name); - strcpy(card->shortname, chip->pcm->name); - sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", - chip->pcm->name, - chip->port, - irq[dev], - dma1[dev]); - if (dma2[dev] >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); + strlcpy(card->driver, chip->pcm->name, sizeof(card->driver)); + strlcpy(card->shortname, chip->pcm->name, sizeof(card->shortname)); + if (dma2[dev] < 0) + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %i, dma %i", + chip->pcm->name, chip->port, irq[dev], dma1[dev]); + else + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %i, dma %i&%d", + chip->pcm->name, chip->port, irq[dev], dma1[dev], + dma2[dev]); err = snd_wss_timer(chip, 0); if (err < 0) diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 36320e7f2789..a826c138e7f5 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -321,7 +321,7 @@ static int snd_es968_pnp_resume(struct pnp_card_link *pcard) } #endif -static struct pnp_card_device_id snd_es968_pnpids[] = { +static const struct pnp_card_device_id snd_es968_pnpids[] = { { .id = "ESS0968", .devs = { { "@@@0968" }, } }, { .id = "ESS0968", .devs = { { "ESS0968" }, } }, { .id = "", } /* end */ diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index 5d3df96c5e5b..f9c0662e9a22 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c @@ -526,7 +526,7 @@ static snd_pcm_uframes_t snd_es1688_capture_pointer(struct snd_pcm_substream *su */ -static struct snd_pcm_hardware snd_es1688_playback = +static const struct snd_pcm_hardware snd_es1688_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -544,7 +544,7 @@ static struct snd_pcm_hardware snd_es1688_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_es1688_capture = +static const struct snd_pcm_hardware snd_es1688_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -706,7 +706,7 @@ exit: return err; } -static struct snd_pcm_ops snd_es1688_playback_ops = { +static const struct snd_pcm_ops snd_es1688_playback_ops = { .open = snd_es1688_playback_open, .close = snd_es1688_playback_close, .ioctl = snd_es1688_ioctl, @@ -717,7 +717,7 @@ static struct snd_pcm_ops snd_es1688_playback_ops = { .pointer = snd_es1688_playback_pointer, }; -static struct snd_pcm_ops snd_es1688_capture_ops = { +static const struct snd_pcm_ops snd_es1688_capture_ops = { .open = snd_es1688_capture_open, .close = snd_es1688_capture_close, .ioctl = snd_es1688_ioctl, diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index ae17a6584061..2a6960c3e2a4 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -838,7 +838,7 @@ static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *su return pos >> chip->dma1_shift; } -static struct snd_pcm_hardware snd_es18xx_playback = +static const struct snd_pcm_hardware snd_es18xx_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | @@ -858,7 +858,7 @@ static struct snd_pcm_hardware snd_es18xx_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_es18xx_capture = +static const struct snd_pcm_hardware snd_es18xx_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | @@ -1665,7 +1665,7 @@ static int snd_es18xx_probe(struct snd_es18xx *chip, return snd_es18xx_initialize(chip, mpu_port, fm_port); } -static struct snd_pcm_ops snd_es18xx_playback_ops = { +static const struct snd_pcm_ops snd_es18xx_playback_ops = { .open = snd_es18xx_playback_open, .close = snd_es18xx_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1676,7 +1676,7 @@ static struct snd_pcm_ops snd_es18xx_playback_ops = { .pointer = snd_es18xx_playback_pointer, }; -static struct snd_pcm_ops snd_es18xx_capture_ops = { +static const struct snd_pcm_ops snd_es18xx_capture_ops = { .open = snd_es18xx_capture_open, .close = snd_es18xx_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -2017,7 +2017,7 @@ static int isa_registered; static int pnp_registered; static int pnpc_registered; -static struct pnp_device_id snd_audiodrive_pnpbiosids[] = { +static const struct pnp_device_id snd_audiodrive_pnpbiosids[] = { { .id = "ESS1869" }, { .id = "ESS1879" }, { .id = "" } /* end */ @@ -2062,7 +2062,7 @@ static int snd_audiodrive_pnp(int dev, struct snd_es18xx *chip, return 0; } -static struct pnp_card_device_id snd_audiodrive_pnpids[] = { +static const struct pnp_card_device_id snd_audiodrive_pnpids[] = { /* ESS 1868 (integrated on Compaq dual P-Pro motherboard and Genius 18PnP 3D) */ { .id = "ESS1868", .devs = { { "ESS1868" }, { "ESS0000" } } }, /* ESS 1868 (integrated on Maxisound Cards) */ diff --git a/sound/isa/gus/Makefile b/sound/isa/gus/Makefile index 6cd4ee03754a..c6f32ffd3420 100644 --- a/sound/isa/gus/Makefile +++ b/sound/isa/gus/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 6b3da01a93b7..131b28997e1d 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -650,7 +650,7 @@ static void snd_gf1_pcm_interrupt_dma_read(struct snd_gus_card * gus) } } -static struct snd_pcm_hardware snd_gf1_pcm_playback = +static const struct snd_pcm_hardware snd_gf1_pcm_playback = { .info = SNDRV_PCM_INFO_NONINTERLEAVED, .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | @@ -668,7 +668,7 @@ static struct snd_pcm_hardware snd_gf1_pcm_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_gf1_pcm_capture = +static const struct snd_pcm_hardware snd_gf1_pcm_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -842,7 +842,7 @@ static const struct snd_kcontrol_new snd_gf1_pcm_volume_control1 = .put = snd_gf1_pcm_volume_put }; -static struct snd_pcm_ops snd_gf1_pcm_playback_ops = { +static const struct snd_pcm_ops snd_gf1_pcm_playback_ops = { .open = snd_gf1_pcm_playback_open, .close = snd_gf1_pcm_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -856,7 +856,7 @@ static struct snd_pcm_ops snd_gf1_pcm_playback_ops = { .fill_silence = snd_gf1_pcm_playback_silence, }; -static struct snd_pcm_ops snd_gf1_pcm_capture_ops = { +static const struct snd_pcm_ops snd_gf1_pcm_capture_ops = { .open = snd_gf1_pcm_capture_open, .close = snd_gf1_pcm_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 0687b7ef3e53..a6fc26bf0af2 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -136,7 +136,7 @@ struct snd_interwave { static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id snd_interwave_pnpids[] = { +static const struct pnp_card_device_id snd_interwave_pnpids[] = { #ifndef SNDRV_STB /* Gravis UltraSound Plug & Play */ { .id = "GRV0001", .devs = { { .id = "GRV0000" } } }, diff --git a/sound/isa/msnd/Makefile b/sound/isa/msnd/Makefile index 2171c0aa2f62..ec231a7b1d5e 100644 --- a/sound/isa/msnd/Makefile +++ b/sound/isa/msnd/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-msnd-lib-objs := msnd.o msnd_midi.o msnd_pinnacle_mixer.o snd-msnd-pinnacle-objs := msnd_pinnacle.o diff --git a/sound/isa/msnd/msnd.c b/sound/isa/msnd/msnd.c index 8109ab3d29d1..569897f64fda 100644 --- a/sound/isa/msnd/msnd.c +++ b/sound/isa/msnd/msnd.c @@ -437,7 +437,7 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip, } } -static struct snd_pcm_hardware snd_msnd_playback = { +static const struct snd_pcm_hardware snd_msnd_playback = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -456,7 +456,7 @@ static struct snd_pcm_hardware snd_msnd_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_msnd_capture = { +static const struct snd_pcm_hardware snd_msnd_capture = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -572,7 +572,7 @@ snd_msnd_playback_pointer(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_msnd_playback_ops = { +static const struct snd_pcm_ops snd_msnd_playback_ops = { .open = snd_msnd_playback_open, .close = snd_msnd_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -669,7 +669,7 @@ static int snd_msnd_capture_hw_params(struct snd_pcm_substream *substream, } -static struct snd_pcm_ops snd_msnd_capture_ops = { +static const struct snd_pcm_ops snd_msnd_capture_ops = { .open = snd_msnd_capture_open, .close = snd_msnd_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index fc4fb1904aef..45e561c425bf 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c @@ -1192,7 +1192,7 @@ static void snd_msnd_pnp_remove(struct pnp_card_link *pcard) static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id msnd_pnpids[] = { +static const struct pnp_card_device_id msnd_pnpids[] = { /* Pinnacle PnP */ { .id = "BVJ0440", .devs = { { "TBS0000" }, { "TBS0001" } } }, { .id = "" } /* end */ diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 4098e3e0353d..7cce4cd4a23b 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -141,7 +141,7 @@ struct snd_opl3sa2 { #ifdef CONFIG_PNP -static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { +static const struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { { .id = "YMH0021" }, { .id = "NMX2210" }, /* Gateway Solo 2500 */ { .id = "" } /* end */ @@ -149,7 +149,7 @@ static struct pnp_device_id snd_opl3sa2_pnpbiosids[] = { MODULE_DEVICE_TABLE(pnp, snd_opl3sa2_pnpbiosids); -static struct pnp_card_device_id snd_opl3sa2_pnpids[] = { +static const struct pnp_card_device_id snd_opl3sa2_pnpids[] = { /* Yamaha YMF719E-S (Genius Sound Maker 3DX) */ { .id = "YMH0020", .devs = { { "YMH0021" } } }, /* Yamaha OPL3-SA3 (integrated on Intel's Pentium II AL440LX motherboard) */ diff --git a/sound/isa/opti9xx/Makefile b/sound/isa/opti9xx/Makefile index b4d894db257a..a9dcdeb502bd 100644 --- a/sound/isa/opti9xx/Makefile +++ b/sound/isa/opti9xx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index bcbff56f060d..8894c7c18ad6 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -143,7 +143,7 @@ static int snd_miro_pnp_is_probed; #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_miro_pnpids[] = { +static const struct pnp_card_device_id snd_miro_pnpids[] = { /* PCM20 and PCM12 in PnP mode */ { .id = "MIR0924", .devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, }, @@ -1353,9 +1353,10 @@ static int snd_miro_probe(struct snd_card *card) } strcpy(card->driver, "miro"); - sprintf(card->longname, "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, miro->name, codec->pcm->name, - miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2); + snprintf(card->longname, sizeof(card->longname), + "%s: OPTi%s, %s at 0x%lx, irq %d, dma %d&%d", + card->shortname, miro->name, codec->pcm->name, + miro->wss_base + 4, miro->irq, miro->dma1, miro->dma2); if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) rmidi = NULL; diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index ceddb392b1e3..505cd81e19fa 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -151,7 +151,7 @@ static int snd_opti9xx_pnp_is_probed; #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_opti9xx_pnpids[] = { +static const struct pnp_card_device_id snd_opti9xx_pnpids[] = { #ifndef OPTi93X /* OPTi 82C924 */ { .id = "OPT0924", @@ -879,13 +879,15 @@ static int snd_opti9xx_probe(struct snd_card *card) strcpy(card->driver, chip->name); sprintf(card->shortname, "OPTi %s", card->driver); #if defined(CS4231) || defined(OPTi93X) - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", - card->shortname, codec->pcm->name, - chip->wss_base + 4, irq, dma1, xdma2); + snprintf(card->longname, sizeof(card->longname), + "%s, %s at 0x%lx, irq %d, dma %d&%d", + card->shortname, codec->pcm->name, + chip->wss_base + 4, irq, dma1, xdma2); #else - sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", - card->shortname, codec->pcm->name, chip->wss_base + 4, irq, - dma1); + snprintf(card->longname, sizeof(card->longname), + "%s, %s at 0x%lx, irq %d, dma %d", + card->shortname, codec->pcm->name, chip->wss_base + 4, irq, + dma1); #endif /* CS4231 || OPTi93X */ if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT) diff --git a/sound/isa/sb/Makefile b/sound/isa/sb/Makefile index 08b9fb974658..f174a5b3c8e4 100644 --- a/sound/isa/sb/Makefile +++ b/sound/isa/sb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c index d28d712f99f4..5a485504f607 100644 --- a/sound/isa/sb/emu8000_callback.c +++ b/sound/isa/sb/emu8000_callback.c @@ -62,7 +62,7 @@ static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch); /* * set up operators */ -static struct snd_emux_operators emu8000_ops = { +static const struct snd_emux_operators emu8000_ops = { .owner = THIS_MODULE, .get_voice = get_voice, .prepare = start_voice, diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index 2ee8d67871ec..8f34551abd8d 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c @@ -157,7 +157,7 @@ static int calc_rate_offset(int hz) /* */ -static struct snd_pcm_hardware emu8k_pcm_hw = { +static const struct snd_pcm_hardware emu8k_pcm_hw = { #ifdef USE_NONINTERLEAVE .info = SNDRV_PCM_INFO_NONINTERLEAVED, #else @@ -670,7 +670,7 @@ static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs) } -static struct snd_pcm_ops emu8k_pcm_ops = { +static const struct snd_pcm_ops emu8k_pcm_ops = { .open = emu8k_pcm_open, .close = emu8k_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 917a93d696c3..8f9ebeb998f6 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -145,7 +145,7 @@ struct snd_card_sb16 { #ifdef CONFIG_PNP -static struct pnp_card_device_id snd_sb16_pnpids[] = { +static const struct pnp_card_device_id snd_sb16_pnpids[] = { #ifndef SNDRV_SBAWE /* Sound Blaster 16 PnP */ { .id = "CTL0024", .devs = { { "CTL0031" } } }, diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c index 4be1350f6649..3e39ba220c39 100644 --- a/sound/isa/sb/sb16_main.c +++ b/sound/isa/sb/sb16_main.c @@ -473,7 +473,7 @@ static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *subs */ -static struct snd_pcm_hardware snd_sb16_playback = +static const struct snd_pcm_hardware snd_sb16_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -491,7 +491,7 @@ static struct snd_pcm_hardware snd_sb16_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_sb16_capture = +static const struct snd_pcm_hardware snd_sb16_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -838,7 +838,7 @@ int snd_sb16dsp_configure(struct snd_sb * chip) return 0; } -static struct snd_pcm_ops snd_sb16_playback_ops = { +static const struct snd_pcm_ops snd_sb16_playback_ops = { .open = snd_sb16_playback_open, .close = snd_sb16_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -849,7 +849,7 @@ static struct snd_pcm_ops snd_sb16_playback_ops = { .pointer = snd_sb16_playback_pointer, }; -static struct snd_pcm_ops snd_sb16_capture_ops = { +static const struct snd_pcm_ops snd_sb16_capture_ops = { .open = snd_sb16_capture_open, .close = snd_sb16_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 0f302be4fb6d..d45df5c54423 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -447,7 +447,7 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst */ -static struct snd_pcm_hardware snd_sb8_playback = +static const struct snd_pcm_hardware snd_sb8_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -466,7 +466,7 @@ static struct snd_pcm_hardware snd_sb8_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_sb8_capture = +static const struct snd_pcm_hardware snd_sb8_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -572,7 +572,7 @@ static int snd_sb8_close(struct snd_pcm_substream *substream) * Initialization part */ -static struct snd_pcm_ops snd_sb8_playback_ops = { +static const struct snd_pcm_ops snd_sb8_playback_ops = { .open = snd_sb8_open, .close = snd_sb8_close, .ioctl = snd_pcm_lib_ioctl, @@ -583,7 +583,7 @@ static struct snd_pcm_ops snd_sb8_playback_ops = { .pointer = snd_sb8_playback_pointer, }; -static struct snd_pcm_ops snd_sb8_capture_ops = { +static const struct snd_pcm_ops snd_sb8_capture_ops = { .open = snd_sb8_open, .close = snd_sb8_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 1cd2908e4f12..733adee5afbf 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -88,7 +88,7 @@ MODULE_PARM_DESC(joystick, "Enable gameport."); static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id sscape_pnpids[] = { +static const struct pnp_card_device_id sscape_pnpids[] = { { .id = "ENS3081", .devs = { { "ENS0000" } } }, /* Soundscape PnP */ { .id = "ENS4081", .devs = { { "ENS1011" } } }, /* VIVO90 */ { .id = "" } /* end */ diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index da4e9a85f0af..b1989facd732 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -88,7 +88,7 @@ MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly lo static int isa_registered; static int pnp_registered; -static struct pnp_card_device_id snd_wavefront_pnpids[] = { +static const struct pnp_card_device_id snd_wavefront_pnpids[] = { /* Tropez */ { .id = "CSC7532", .devs = { { "CSC0000" }, { "CSC0010" }, { "PnPb006" }, { "CSC0004" } } }, /* Tropez+ */ diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 9f4e2e34cbe1..8a852042a066 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1452,7 +1452,7 @@ static int snd_wss_probe(struct snd_wss *chip) */ -static struct snd_pcm_hardware snd_wss_playback = +static const struct snd_pcm_hardware snd_wss_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1472,7 +1472,7 @@ static struct snd_pcm_hardware snd_wss_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_wss_capture = +static const struct snd_pcm_hardware snd_wss_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1901,7 +1901,7 @@ int snd_wss_create(struct snd_card *card, } EXPORT_SYMBOL(snd_wss_create); -static struct snd_pcm_ops snd_wss_playback_ops = { +static const struct snd_pcm_ops snd_wss_playback_ops = { .open = snd_wss_playback_open, .close = snd_wss_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1912,7 +1912,7 @@ static struct snd_pcm_ops snd_wss_playback_ops = { .pointer = snd_wss_playback_pointer, }; -static struct snd_pcm_ops snd_wss_capture_ops = { +static const struct snd_pcm_ops snd_wss_capture_ops = { .open = snd_wss_capture_open, .close = snd_wss_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 3318c15e324a..37d378a26a50 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c @@ -496,7 +496,7 @@ static void hal2_free_dmabuf(struct hal2_codec *codec) DMA_ATTR_NON_CONSISTENT); } -static struct snd_pcm_hardware hal2_pcm_hw = { +static const struct snd_pcm_hardware hal2_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -711,7 +711,7 @@ static int hal2_capture_ack(struct snd_pcm_substream *substream) hal2_capture_transfer); } -static struct snd_pcm_ops hal2_playback_ops = { +static const struct snd_pcm_ops hal2_playback_ops = { .open = hal2_playback_open, .close = hal2_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -723,7 +723,7 @@ static struct snd_pcm_ops hal2_playback_ops = { .ack = hal2_playback_ack, }; -static struct snd_pcm_ops hal2_capture_ops = { +static const struct snd_pcm_ops hal2_capture_ops = { .open = hal2_capture_open, .close = hal2_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 0ebc1c3727df..71c942162c25 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -532,7 +532,7 @@ static irqreturn_t snd_sgio2audio_error_isr(int irq, void *dev_id) /* PCM part */ /* PCM hardware definition */ -static struct snd_pcm_hardware snd_sgio2audio_pcm_hw = { +static const struct snd_pcm_hardware snd_sgio2audio_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -675,7 +675,7 @@ snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream) } /* operators */ -static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { +static const struct snd_pcm_ops snd_sgio2audio_playback1_ops = { .open = snd_sgio2audio_playback1_open, .close = snd_sgio2audio_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -688,7 +688,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback1_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { +static const struct snd_pcm_ops snd_sgio2audio_playback2_ops = { .open = snd_sgio2audio_playback2_open, .close = snd_sgio2audio_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -701,7 +701,7 @@ static struct snd_pcm_ops snd_sgio2audio_playback2_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops snd_sgio2audio_capture_ops = { +static const struct snd_pcm_ops snd_sgio2audio_capture_ops = { .open = snd_sgio2audio_capture_open, .close = snd_sgio2audio_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/oss/Makefile b/sound/oss/Makefile index 9bdbbde2173e..6564eace4749 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Linux sound card driver # # 18 Apr 1998, Michael Elizabeth Chastain, diff --git a/sound/oss/ad1848.h b/sound/oss/ad1848.h index b95ebe28d426..390f03e13d09 100644 --- a/sound/oss/ad1848.h +++ b/sound/oss/ad1848.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include diff --git a/sound/oss/bin2hex.c b/sound/oss/bin2hex.c index b59109eb0db4..26c04ce04d71 100644 --- a/sound/oss/bin2hex.c +++ b/sound/oss/bin2hex.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h index 01019f06fa91..c1c52b479da2 100644 --- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _dmasound_h_ /* * linux/sound/oss/dmasound/dmasound.h diff --git a/sound/oss/hex2hex.c b/sound/oss/hex2hex.c index 041ef5c52bc2..f76d729b0196 100644 --- a/sound/oss/hex2hex.c +++ b/sound/oss/hex2hex.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * hex2hex reads stdin in Intel HEX format and produces an * (unsigned char) array which contains the bytes and writes it diff --git a/sound/oss/midi_ctrl.h b/sound/oss/midi_ctrl.h index 3353e5a67c24..240d0c719f1e 100644 --- a/sound/oss/midi_ctrl.h +++ b/sound/oss/midi_ctrl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ static unsigned char ctrl_def_values[128] = { 0x40,0x00,0x40,0x40, 0x40,0x40,0x40,0x7f, /* 0 to 7 */ diff --git a/sound/oss/midi_synth.h b/sound/oss/midi_synth.h index b64ddd6c4abc..1cf676c7510e 100644 --- a/sound/oss/midi_synth.h +++ b/sound/oss/midi_synth.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ int midi_synth_ioctl (int dev, unsigned int cmd, void __user * arg); int midi_synth_kill_note (int dev, int channel, int note, int velocity); diff --git a/sound/oss/mpu401.h b/sound/oss/mpu401.h index 0ad1e9ee74f7..6beb8c2ae405 100644 --- a/sound/oss/mpu401.h +++ b/sound/oss/mpu401.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* From uart401.c */ int probe_uart401 (struct address_info *hw_config, struct module *owner); diff --git a/sound/oss/os.h b/sound/oss/os.h index 0bf89e1d679c..16f3a069b85c 100644 --- a/sound/oss/os.h +++ b/sound/oss/os.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define ALLOW_SELECT #undef NO_INLINE_ASM #define SHORT_BANNERS diff --git a/sound/oss/pas2.h b/sound/oss/pas2.h index d19f757dbd79..57f476238309 100644 --- a/sound/oss/pas2.h +++ b/sound/oss/pas2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* From pas_card.c */ int pas_set_intr(int mask); diff --git a/sound/oss/sb.h b/sound/oss/sb.h index 77e8891ce333..bb1d18709b36 100644 --- a/sound/oss/sb.h +++ b/sound/oss/sb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define DSP_RESET (devc->base + 0x6) #define DSP_READ (devc->base + 0xA) #define DSP_WRITE (devc->base + 0xC) diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c index 57f7d25a2cd3..17e3f14318cd 100644 --- a/sound/oss/sb_ess.c +++ b/sound/oss/sb_ess.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #undef FKS_LOGGING #undef FKS_TEST diff --git a/sound/oss/sb_ess.h b/sound/oss/sb_ess.h index 38aa072e01f2..1c741212bcfc 100644 --- a/sound/oss/sb_ess.h +++ b/sound/oss/sb_ess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Created: 9-Jan-1999 Rolf Fokkens */ diff --git a/sound/oss/sleep.h b/sound/oss/sleep.h index a20fc925a5ce..fd17d44d13dd 100644 --- a/sound/oss/sleep.h +++ b/sound/oss/sleep.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* diff --git a/sound/oss/sound_calls.h b/sound/oss/sound_calls.h index 87d8ad4a0340..bcd3f7340ef7 100644 --- a/sound/oss/sound_calls.h +++ b/sound/oss/sound_calls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * DMA buffer calls */ diff --git a/sound/oss/sound_firmware.h b/sound/oss/sound_firmware.h index da4c67e005ed..ebcbded0e8c2 100644 --- a/sound/oss/sound_firmware.h +++ b/sound/oss/sound_firmware.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /** @@ -21,7 +22,7 @@ static inline int mod_firmware_load(const char *fn, char **fp) loff_t size; int err; - err = kernel_read_file_from_path((char *)fn, (void **)fp, &size, + err = kernel_read_file_from_path(fn, (void **)fp, &size, 131072, READING_FIRMWARE); if (err < 0) return 0; diff --git a/sound/oss/tuning.h b/sound/oss/tuning.h index a73e3dd39f9a..953539931237 100644 --- a/sound/oss/tuning.h +++ b/sound/oss/tuning.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ static unsigned short semitone_tuning[24] = { /* 0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, diff --git a/sound/oss/ulaw.h b/sound/oss/ulaw.h index 0ff8c0a3bda0..ee898a0f78ce 100644 --- a/sound/oss/ulaw.h +++ b/sound/oss/ulaw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ static unsigned char ulaw_dsp[] = { 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, diff --git a/sound/oss/v_midi.h b/sound/oss/v_midi.h index 08e2185ee816..f4fc2bed07f8 100644 --- a/sound/oss/v_midi.h +++ b/sound/oss/v_midi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ typedef struct vmidi_devc { int dev; diff --git a/sound/oss/waveartist.h b/sound/oss/waveartist.h index dac4ca910d95..f18d74b26483 100644 --- a/sound/oss/waveartist.h +++ b/sound/oss/waveartist.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * linux/sound/oss/waveartist.h * diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 5911eb35c2a3..f36e7006e00c 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -66,7 +66,7 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for Harmony driver."); -static struct parisc_device_id snd_harmony_devtable[] = { +static const struct parisc_device_id snd_harmony_devtable[] __initconst = { /* bushmaster / flounder */ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, /* 712 / 715 */ @@ -260,7 +260,7 @@ snd_harmony_rate_bits(int rate) return HARMONY_SR_44KHZ; } -static struct snd_pcm_hardware snd_harmony_playback = +static const struct snd_pcm_hardware snd_harmony_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | @@ -281,7 +281,7 @@ static struct snd_pcm_hardware snd_harmony_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_harmony_capture = +static const struct snd_pcm_hardware snd_harmony_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID | @@ -596,7 +596,7 @@ snd_harmony_hw_free(struct snd_pcm_substream *ss) return snd_pcm_lib_free_pages(ss); } -static struct snd_pcm_ops snd_harmony_playback_ops = { +static const struct snd_pcm_ops snd_harmony_playback_ops = { .open = snd_harmony_playback_open, .close = snd_harmony_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -607,7 +607,7 @@ static struct snd_pcm_ops snd_harmony_playback_ops = { .pointer = snd_harmony_playback_pointer, }; -static struct snd_pcm_ops snd_harmony_capture_ops = { +static const struct snd_pcm_ops snd_harmony_capture_ops = { .open = snd_harmony_capture_open, .close = snd_harmony_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -960,7 +960,7 @@ free_and_ret: return err; } -static int +static int __init snd_harmony_probe(struct parisc_device *padev) { int err; @@ -1000,18 +1000,18 @@ free_and_ret: return err; } -static int +static int __exit snd_harmony_remove(struct parisc_device *padev) { snd_card_free(parisc_get_drvdata(padev)); return 0; } -static struct parisc_driver snd_harmony_driver = { +static struct parisc_driver snd_harmony_driver __refdata = { .name = "harmony", .id_table = snd_harmony_devtable, .probe = snd_harmony_probe, - .remove = snd_harmony_remove, + .remove = __exit_p(snd_harmony_remove), }; static int __init diff --git a/sound/parisc/harmony.h b/sound/parisc/harmony.h index 2e434523fedf..f4c29a2e32e8 100644 --- a/sound/parisc/harmony.h +++ b/sound/parisc/harmony.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Hewlett-Packard Harmony audio driver * Copyright (C) 2004, Kyle McMartin */ diff --git a/sound/pci/Makefile b/sound/pci/Makefile index 54fe325e3aa5..04cac7469139 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 8c36990e26f6..0bf2c04eeada 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -283,7 +283,7 @@ snd_ad1889_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); } -static struct snd_pcm_hardware snd_ad1889_playback_hw = { +static const struct snd_pcm_hardware snd_ad1889_playback_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, .formats = SNDRV_PCM_FMTBIT_S16_LE, @@ -300,7 +300,7 @@ static struct snd_pcm_hardware snd_ad1889_playback_hw = { /*.fifo_size = 0,*/ }; -static struct snd_pcm_hardware snd_ad1889_capture_hw = { +static const struct snd_pcm_hardware snd_ad1889_capture_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER, .formats = SNDRV_PCM_FMTBIT_S16_LE, diff --git a/sound/pci/ad1889.h b/sound/pci/ad1889.h index 5e6dad5341a1..d6e8d6c19adc 100644 --- a/sound/pci/ad1889.h +++ b/sound/pci/ad1889.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Analog Devices 1889 audio driver * Copyright (C) 2004, Kyle McMartin */ diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 8567f1e5b9cf..39547e32e584 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1540,7 +1540,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops snd_ali_playback_ops = { +static const struct snd_pcm_ops snd_ali_playback_ops = { .open = snd_ali_playback_open, .close = snd_ali_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1551,7 +1551,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = { .pointer = snd_ali_playback_pointer, }; -static struct snd_pcm_ops snd_ali_capture_ops = { +static const struct snd_pcm_ops snd_ali_capture_ops = { .open = snd_ali_capture_open, .close = snd_ali_close, .ioctl = snd_pcm_lib_ioctl, @@ -1626,7 +1626,7 @@ static int snd_ali_modem_capture_open(struct snd_pcm_substream *substream) return snd_ali_modem_open(substream, 1, ALI_MODEM_IN_CHANNEL); } -static struct snd_pcm_ops snd_ali_modem_playback_ops = { +static const struct snd_pcm_ops snd_ali_modem_playback_ops = { .open = snd_ali_modem_playback_open, .close = snd_ali_close, .ioctl = snd_pcm_lib_ioctl, @@ -1637,7 +1637,7 @@ static struct snd_pcm_ops snd_ali_modem_playback_ops = { .pointer = snd_ali_pointer, }; -static struct snd_pcm_ops snd_ali_modem_capture_ops = { +static const struct snd_pcm_ops snd_ali_modem_capture_ops = { .open = snd_ali_modem_capture_open, .close = snd_ali_close, .ioctl = snd_pcm_lib_ioctl, @@ -1653,8 +1653,8 @@ struct ali_pcm_description { char *name; unsigned int playback_num; unsigned int capture_num; - struct snd_pcm_ops *playback_ops; - struct snd_pcm_ops *capture_ops; + const struct snd_pcm_ops *playback_ops; + const struct snd_pcm_ops *capture_ops; unsigned short class; }; diff --git a/sound/pci/als300.c b/sound/pci/als300.c index ab75601d7c2c..eaa2d853d922 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c @@ -328,7 +328,7 @@ static int snd_als300_ac97(struct snd_als300 *chip) * the card when it is running outside of legacy * mode. */ -static struct snd_pcm_hardware snd_als300_playback_hw = +static const struct snd_pcm_hardware snd_als300_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -347,7 +347,7 @@ static struct snd_pcm_hardware snd_als300_playback_hw = .periods_max = 2, }; -static struct snd_pcm_hardware snd_als300_capture_hw = +static const struct snd_pcm_hardware snd_als300_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 7844a75d8ed9..26b097edec8c 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -592,7 +592,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) /*****************************************************************/ -static struct snd_pcm_hardware snd_als4000_playback = +static const struct snd_pcm_hardware snd_als4000_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), @@ -611,7 +611,7 @@ static struct snd_pcm_hardware snd_als4000_playback = .fifo_size = 0 }; -static struct snd_pcm_hardware snd_als4000_capture = +static const struct snd_pcm_hardware snd_als4000_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index 976a3d23557e..70d023a85bf5 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -558,12 +558,10 @@ static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream) struct snd_card_asihpi_pcm *dpcm; struct snd_card_asihpi *card; - BUG_ON(!substream); - dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; card = snd_pcm_substream_chip(substream); - BUG_ON(in_interrupt()); + WARN_ON(in_interrupt()); tasklet_disable(&card->t); card->llmode_streampriv = dpcm; tasklet_enable(&card->t); @@ -578,8 +576,6 @@ static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream) struct snd_card_asihpi_pcm *dpcm; struct snd_card_asihpi *card; - BUG_ON(!substream); - dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data; card = snd_pcm_substream_chip(substream); diff --git a/sound/pci/asihpi/hpi_version.h b/sound/pci/asihpi/hpi_version.h index 6623ab110038..016bc55457e3 100644 --- a/sound/pci/asihpi/hpi_version.h +++ b/sound/pci/asihpi/hpi_version.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /** HPI Version Definitions Development releases have odd minor version. Production releases have even minor version. diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c index ac86a1f1d3bf..9e122327dc05 100644 --- a/sound/pci/asihpi/hpidebug.c +++ b/sound/pci/asihpi/hpidebug.c @@ -71,8 +71,8 @@ void hpi_debug_data(u16 *pdata, u32 len) printk(KERN_DEBUG "%p:", (pdata + i)); for (k = 0; k < cols && i < len; i++, k++) - printk("%s%04x", k == 0 ? "" : " ", pdata[i]); + printk(KERN_CONT "%s%04x", k == 0 ? "" : " ", pdata[i]); - printk("\n"); + printk(KERN_CONT "\n"); } } diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index f9b57647b319..1de05383126a 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "hpi_internal.h" #include "hpimsginit.h" diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 7e3aa50b21f9..5badd08e1d69 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -103,6 +103,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) void __user *puhr; union hpi_message_buffer_v1 *hm; union hpi_response_buffer_v1 *hr; + u16 msg_size; u16 res_max_size; u32 uncopied_bytes; int err = 0; @@ -127,22 +128,25 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } /* Now read the message size and data from user space. */ - if (get_user(hm->h.size, (u16 __user *)puhm)) { + if (get_user(msg_size, (u16 __user *)puhm)) { err = -EFAULT; goto out; } - if (hm->h.size > sizeof(*hm)) - hm->h.size = sizeof(*hm); + if (msg_size > sizeof(*hm)) + msg_size = sizeof(*hm); /* printk(KERN_INFO "message size %d\n", hm->h.wSize); */ - uncopied_bytes = copy_from_user(hm, puhm, hm->h.size); + uncopied_bytes = copy_from_user(hm, puhm, msg_size); if (uncopied_bytes) { HPI_DEBUG_LOG(ERROR, "uncopied bytes %d\n", uncopied_bytes); err = -EFAULT; goto out; } + /* Override h.size in case it is changed between two userspace fetches */ + hm->h.size = msg_size; + if (get_user(res_max_size, (u16 __user *)puhr)) { err = -EFAULT; goto out; diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index a40c918c8dff..7ae63d452bba 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -1009,7 +1009,7 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for all DMA types */ -static struct snd_pcm_hardware snd_atiixp_pcm_hw = +static const struct snd_pcm_hardware snd_atiixp_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1183,7 +1183,7 @@ static const struct snd_pcm_ops snd_atiixp_spdif_ops = { .pointer = snd_atiixp_pcm_pointer, }; -static struct ac97_pcm atiixp_pcm_defs[] = { +static const struct ac97_pcm atiixp_pcm_defs[] = { /* front PCM */ { .exclusive = 1, diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 52e0ea7b9b80..a586635664e0 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -834,7 +834,7 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for all DMA types */ -static struct snd_pcm_hardware snd_atiixp_pcm_hw = +static const struct snd_pcm_hardware snd_atiixp_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/au88x0/Makefile b/sound/pci/au88x0/Makefile index d0a66bc5d4a7..78ab11562f4d 100644 --- a/sound/pci/au88x0/Makefile +++ b/sound/pci/au88x0/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-au8810-objs := au8810.o snd-au8820-objs := au8820.o snd-au8830-objs := au8830.o diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c index 1b2e34069eb3..b2bfa50bfe30 100644 --- a/sound/pci/au88x0/au8810.c +++ b/sound/pci/au88x0/au8810.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "au8810.h" #include "au88x0.h" static const struct pci_device_id snd_vortex_ids[] = { diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h index 79fbee3845eb..94f11032067e 100644 --- a/sound/pci/au88x0/au8810.h +++ b/sound/pci/au88x0/au8810.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Aureal Advantage Soundcard driver. */ diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c index 74c53fa5f06b..dbc2263b49c6 100644 --- a/sound/pci/au88x0/au8820.c +++ b/sound/pci/au88x0/au8820.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "au8820.h" #include "au88x0.h" static const struct pci_device_id snd_vortex_ids[] = { diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h index cafdb9668a34..8a128e8febbb 100644 --- a/sound/pci/au88x0/au8820.h +++ b/sound/pci/au88x0/au8820.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Aureal Vortex Soundcard driver. diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c index 56f675aad3ad..e963c4e2f026 100644 --- a/sound/pci/au88x0/au8830.c +++ b/sound/pci/au88x0/au8830.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "au8830.h" #include "au88x0.h" static const struct pci_device_id snd_vortex_ids[] = { diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h index 999b29ab34ad..40f671ffd45a 100644 --- a/sound/pci/au88x0/au8830.h +++ b/sound/pci/au88x0/au8830.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Aureal Vortex Soundcard driver. diff --git a/sound/pci/au88x0/au88x0_eq.h b/sound/pci/au88x0/au88x0_eq.h index 474cd0046294..797cdae1db98 100644 --- a/sound/pci/au88x0/au88x0_eq.h +++ b/sound/pci/au88x0/au88x0_eq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef AU88X0_EQ_H #define AU88X0_EQ_H diff --git a/sound/pci/au88x0/au88x0_eqdata.c b/sound/pci/au88x0/au88x0_eqdata.c index ce8dca8ce1e2..49a52d298b1a 100644 --- a/sound/pci/au88x0/au88x0_eqdata.c +++ b/sound/pci/au88x0/au88x0_eqdata.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Data structs */ static u16 asEqCoefsZeros[50] = { diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c index a58298cfe7e0..60dd8a091bc3 100644 --- a/sound/pci/au88x0/au88x0_mixer.c +++ b/sound/pci/au88x0/au88x0_mixer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Vortex Mixer support. * diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 1aa97012451d..53714e0bf598 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -30,7 +30,7 @@ #define VORTEX_PCM_TYPE(x) (x->name[40]) /* hardware definition */ -static struct snd_pcm_hardware snd_vortex_playback_hw_adb = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_adb = { .info = (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | @@ -51,7 +51,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = { }; #ifndef CHIP_AU8820 -static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_a3d = { .info = (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | @@ -71,7 +71,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = { .periods_max = 64, }; #endif -static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_spdif = { .info = (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED | @@ -94,7 +94,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = { }; #ifndef CHIP_AU8810 -static struct snd_pcm_hardware snd_vortex_playback_hw_wt = { +static const struct snd_pcm_hardware snd_vortex_playback_hw_wt = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), @@ -439,7 +439,7 @@ static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substr } /* operators */ -static struct snd_pcm_ops snd_vortex_playback_ops = { +static const struct snd_pcm_ops snd_vortex_playback_ops = { .open = snd_vortex_pcm_open, .close = snd_vortex_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/pci/au88x0/au88x0_wt.h b/sound/pci/au88x0/au88x0_wt.h index 38d98f88a95c..7b2cffad8643 100644 --- a/sound/pci/au88x0/au88x0_wt.h +++ b/sound/pci/au88x0/au88x0_wt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /*************************************************************************** * WT register offsets. * diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 8356180bfe0e..9a49e4243a9c 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c @@ -52,7 +52,7 @@ MODULE_LICENSE("GPL"); * TYPEDEFS ********************************/ /* hardware definition */ -static struct snd_pcm_hardware snd_aw2_playback_hw = { +static const struct snd_pcm_hardware snd_aw2_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), @@ -69,7 +69,7 @@ static struct snd_pcm_hardware snd_aw2_playback_hw = { .periods_max = 1024, }; -static struct snd_pcm_hardware snd_aw2_capture_hw = { +static const struct snd_pcm_hardware snd_aw2_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h index 6f46b97650cc..6f9022784499 100644 --- a/sound/pci/azt3328.h +++ b/sound/pci/azt3328.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_AZT3328_H #define __SOUND_AZT3328_H diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index de0234294c25..d8ade8771a32 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -353,7 +353,7 @@ static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_bt87x_digital_hw = { +static const struct snd_pcm_hardware snd_bt87x_digital_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -370,7 +370,7 @@ static struct snd_pcm_hardware snd_bt87x_digital_hw = { .periods_max = 255, }; -static struct snd_pcm_hardware snd_bt87x_analog_hw = { +static const struct snd_pcm_hardware snd_bt87x_analog_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 6165a57a94ae..cd27b5536654 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -296,7 +296,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = { }; /* hardware definition */ -static struct snd_pcm_hardware snd_ca0106_playback_hw = { +static const struct snd_pcm_hardware snd_ca0106_playback_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -317,7 +317,7 @@ static struct snd_pcm_hardware snd_ca0106_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ca0106_capture_hw = { +static const struct snd_pcm_hardware snd_ca0106_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -660,11 +660,9 @@ static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substre int err; epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); - if (epcm == NULL) { - dev_err(chip->card->dev, - "open_capture_channel: failed epcm alloc\n"); + if (!epcm) return -ENOMEM; - } + epcm->emu = chip; epcm->substream = substream; epcm->channel_id=channel_id; diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index a460cb63e971..26a657870664 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -1477,7 +1477,7 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id) */ /* playback on channel A */ -static struct snd_pcm_hardware snd_cmipci_playback = +static const struct snd_pcm_hardware snd_cmipci_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1497,7 +1497,7 @@ static struct snd_pcm_hardware snd_cmipci_playback = }; /* capture on channel B */ -static struct snd_pcm_hardware snd_cmipci_capture = +static const struct snd_pcm_hardware snd_cmipci_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1517,7 +1517,7 @@ static struct snd_pcm_hardware snd_cmipci_capture = }; /* playback on channel B - stereo 16bit only? */ -static struct snd_pcm_hardware snd_cmipci_playback2 = +static const struct snd_pcm_hardware snd_cmipci_playback2 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1537,7 +1537,7 @@ static struct snd_pcm_hardware snd_cmipci_playback2 = }; /* spdif playback on channel A */ -static struct snd_pcm_hardware snd_cmipci_playback_spdif = +static const struct snd_pcm_hardware snd_cmipci_playback_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1557,7 +1557,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_spdif = }; /* spdif playback on channel A (32bit, IEC958 subframes) */ -static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe = +static const struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -1577,7 +1577,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe = }; /* spdif capture on channel B */ -static struct snd_pcm_hardware snd_cmipci_capture_spdif = +static const struct snd_pcm_hardware snd_cmipci_capture_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | @@ -3295,20 +3295,23 @@ static int snd_cmipci_probe(struct pci_dev *pci, break; } - if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) { - snd_card_free(card); - return err; - } + err = snd_cmipci_create(card, pci, dev, &cm); + if (err < 0) + goto free_card; + card->private_data = cm; - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto free_card; + pci_set_drvdata(pci, card); dev++; return 0; +free_card: + snd_card_free(card); + return err; } static void snd_cmipci_remove(struct pci_dev *pci) diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index ee7ba4b0b47b..ec4247638fa1 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -847,7 +847,7 @@ static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream) snd_cs4281_peekBA0(chip, dma->regDCC) - 1; } -static struct snd_pcm_hardware snd_cs4281_playback = +static const struct snd_pcm_hardware snd_cs4281_playback = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -872,7 +872,7 @@ static struct snd_pcm_hardware snd_cs4281_playback = .fifo_size = CS4281_FIFO_SIZE, }; -static struct snd_pcm_hardware snd_cs4281_capture = +static const struct snd_pcm_hardware snd_cs4281_capture = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 709fb1a503b7..0020fd0efc46 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -1438,7 +1438,7 @@ static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_cs46xx_playback = +static const struct snd_pcm_hardware snd_cs46xx_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -1460,7 +1460,7 @@ static struct snd_pcm_hardware snd_cs46xx_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_cs46xx_capture = +static const struct snd_pcm_hardware snd_cs46xx_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h index 0579daa62215..f4fcdf93f3c8 100644 --- a/sound/pci/cs5535audio/cs5535audio.h +++ b/sound/pci/cs5535audio/cs5535audio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_CS5535AUDIO_H #define __SOUND_CS5535AUDIO_H diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index c208c1d8dbb2..ee7065f6e162 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -33,7 +33,7 @@ #include #include "cs5535audio.h" -static struct snd_pcm_hardware snd_cs5535audio_playback = +static const struct snd_pcm_hardware snd_cs5535audio_playback = { .info = ( SNDRV_PCM_INFO_MMAP | @@ -62,7 +62,7 @@ static struct snd_pcm_hardware snd_cs5535audio_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_cs5535audio_capture = +static const struct snd_pcm_hardware snd_cs5535audio_capture = { .info = ( SNDRV_PCM_INFO_MMAP | diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index 79edd88d5cd0..8e6eb9d7984b 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -2154,7 +2154,7 @@ static void hw_write_pci(struct hw *hw, u32 reg, u32 data) &container_of(hw, struct hw20k1, hw)->reg_pci_lock, flags); } -static struct hw ct20k1_preset = { +static const struct hw ct20k1_preset = { .irq = -1, .card_init = hw_card_init, diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index 18ee7768b7c4..b866d6b2c923 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -2220,7 +2220,7 @@ static void hw_write_20kx(struct hw *hw, u32 reg, u32 data) writel(data, hw->mem_base + reg); } -static struct hw ct20k2_preset = { +static const struct hw ct20k2_preset = { .irq = -1, .card_init = hw_card_init, diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 974978041558..b36e37ae2b51 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -21,7 +21,7 @@ #include /* Hardware descriptions for playback */ -static struct snd_pcm_hardware ct_pcm_playback_hw = { +static const struct snd_pcm_hardware ct_pcm_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -46,7 +46,7 @@ static struct snd_pcm_hardware ct_pcm_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { +static const struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -69,7 +69,7 @@ static struct snd_pcm_hardware ct_spdif_passthru_playback_hw = { }; /* Hardware descriptions for capture */ -static struct snd_pcm_hardware ct_pcm_capture_hw = { +static const struct snd_pcm_hardware ct_pcm_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -140,27 +140,28 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; + err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1024, UINT_MAX); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; apcm->timer = ct_timer_instance_new(atc->timer, apcm); if (!apcm->timer) { - kfree(apcm); - return -ENOMEM; + err = -ENOMEM; + goto free_pcm; } runtime->private_data = apcm; runtime->private_free = ct_atc_pcm_free_substream; return 0; + +free_pcm: + kfree(apcm); + return err; } static int ct_pcm_playback_close(struct snd_pcm_substream *substream) @@ -286,27 +287,28 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; + err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 1024, UINT_MAX); - if (err < 0) { - kfree(apcm); - return err; - } + if (err < 0) + goto free_pcm; apcm->timer = ct_timer_instance_new(atc->timer, apcm); if (!apcm->timer) { - kfree(apcm); - return -ENOMEM; + err = -ENOMEM; + goto free_pcm; } runtime->private_data = apcm; runtime->private_free = ct_atc_pcm_free_substream; return 0; + +free_pcm: + kfree(apcm); + return err; } static int ct_pcm_capture_close(struct snd_pcm_substream *substream) diff --git a/sound/pci/ctxfi/ctresource.c b/sound/pci/ctxfi/ctresource.c index c5124c3c0fd1..80c4d84f9667 100644 --- a/sound/pci/ctxfi/ctresource.c +++ b/sound/pci/ctxfi/ctresource.c @@ -258,10 +258,8 @@ error: int rsc_mgr_uninit(struct rsc_mgr *mgr) { - if (NULL != mgr->rscs) { - kfree(mgr->rscs); - mgr->rscs = NULL; - } + kfree(mgr->rscs); + mgr->rscs = NULL; if ((NULL != mgr->hw) && (NULL != mgr->ctrl_blk)) { switch (mgr->type) { diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index a5a72df29801..bb4c9c3c89ae 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c @@ -702,10 +702,8 @@ error1: static int srcimp_rsc_uninit(struct srcimp *srcimp) { - if (NULL != srcimp->imappers) { - kfree(srcimp->imappers); - srcimp->imappers = NULL; - } + kfree(srcimp->imappers); + srcimp->imappers = NULL; srcimp->ops = NULL; srcimp->mgr = NULL; rsc_uninit(&srcimp->rsc); diff --git a/sound/pci/ctxfi/cttimer.h b/sound/pci/ctxfi/cttimer.h index 979348229291..9c5cb403b646 100644 --- a/sound/pci/ctxfi/cttimer.h +++ b/sound/pci/ctxfi/cttimer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Timer handling */ diff --git a/sound/pci/echoaudio/Makefile b/sound/pci/echoaudio/Makefile index 1361de77e0cd..4865b8fe7434 100644 --- a/sound/pci/echoaudio/Makefile +++ b/sound/pci/echoaudio/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA Echoaudio soundcard drivers # Copyright (c) 2003 by Giuliano Pochini diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index d15ecf9febbf..d68f99e076a8 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -826,7 +826,7 @@ static snd_pcm_uframes_t pcm_pointer(struct snd_pcm_substream *substream) /* pcm *_ops structures */ -static struct snd_pcm_ops analog_playback_ops = { +static const struct snd_pcm_ops analog_playback_ops = { .open = pcm_analog_out_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -837,7 +837,7 @@ static struct snd_pcm_ops analog_playback_ops = { .pointer = pcm_pointer, .page = snd_pcm_sgbuf_ops_page, }; -static struct snd_pcm_ops analog_capture_ops = { +static const struct snd_pcm_ops analog_capture_ops = { .open = pcm_analog_in_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -850,7 +850,7 @@ static struct snd_pcm_ops analog_capture_ops = { }; #ifdef ECHOCARD_HAS_DIGITAL_IO #ifndef ECHOCARD_HAS_VMIXER -static struct snd_pcm_ops digital_playback_ops = { +static const struct snd_pcm_ops digital_playback_ops = { .open = pcm_digital_out_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -862,7 +862,7 @@ static struct snd_pcm_ops digital_playback_ops = { .page = snd_pcm_sgbuf_ops_page, }; #endif /* !ECHOCARD_HAS_VMIXER */ -static struct snd_pcm_ops digital_capture_ops = { +static const struct snd_pcm_ops digital_capture_ops = { .open = pcm_digital_in_open, .close = pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -1272,11 +1272,11 @@ static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, chip = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; uinfo->value.integer.min = ECHOGAIN_MINOUT; uinfo->value.integer.max = ECHOGAIN_MAXOUT; uinfo->dimen.d[0] = num_busses_out(chip); uinfo->dimen.d[1] = num_busses_in(chip); - uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1]; return 0; } @@ -1344,11 +1344,11 @@ static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, chip = snd_kcontrol_chip(kcontrol); uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; uinfo->value.integer.min = ECHOGAIN_MINOUT; uinfo->value.integer.max = ECHOGAIN_MAXOUT; uinfo->dimen.d[0] = num_busses_out(chip); uinfo->dimen.d[1] = num_pipes_out(chip); - uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1]; return 0; } @@ -1728,6 +1728,7 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 96; uinfo->value.integer.min = ECHOGAIN_MINOUT; uinfo->value.integer.max = 0; #ifdef ECHOCARD_HAS_VMIXER @@ -1737,7 +1738,6 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol, #endif uinfo->dimen.d[1] = 16; /* 16 channels */ uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ - uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1] * uinfo->dimen.d[2]; return 0; } diff --git a/sound/pci/emu10k1/Makefile b/sound/pci/emu10k1/Makefile index 29b44ca27010..17d5527be319 100644 --- a/sound/pci/emu10k1/Makefile +++ b/sound/pci/emu10k1/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 77a4413f4564..2c2b12a06177 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -254,7 +254,7 @@ struct emu10k1x { }; /* hardware definition */ -static struct snd_pcm_hardware snd_emu10k1x_playback_hw = { +static const struct snd_pcm_hardware snd_emu10k1x_playback_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -273,7 +273,7 @@ static struct snd_pcm_hardware snd_emu10k1x_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_emu10k1x_capture_hw = { +static const struct snd_pcm_hardware snd_emu10k1x_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 5c9054a9f69e..2683b9717215 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -556,7 +556,7 @@ static int snd_emu10k1_efx_playback_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_hardware snd_emu10k1_efx_playback = +static const struct snd_pcm_hardware snd_emu10k1_efx_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_NONINTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -975,7 +975,7 @@ static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *s * Playback support device description */ -static struct snd_pcm_hardware snd_emu10k1_playback = +static const struct snd_pcm_hardware snd_emu10k1_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -999,7 +999,7 @@ static struct snd_pcm_hardware snd_emu10k1_playback = * Capture support device description */ -static struct snd_pcm_hardware snd_emu10k1_capture = +static const struct snd_pcm_hardware snd_emu10k1_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1019,7 +1019,7 @@ static struct snd_pcm_hardware snd_emu10k1_capture = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_emu10k1_capture_efx = +static const struct snd_pcm_hardware snd_emu10k1_capture_efx = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1742,7 +1742,7 @@ static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(struct snd_pcm_subs return snd_pcm_indirect_playback_pointer(substream, &pcm->pcm_rec, ptr); } -static struct snd_pcm_hardware snd_emu10k1_fx8010_playback = +static const struct snd_pcm_hardware snd_emu10k1_fx8010_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index c11f1a29f35d..a30da78a95b7 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -122,7 +122,7 @@ */ /* hardware definition */ -static struct snd_pcm_hardware snd_p16v_playback_hw = { +static const struct snd_pcm_hardware snd_p16v_playback_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -143,7 +143,7 @@ static struct snd_pcm_hardware snd_p16v_playback_hw = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_p16v_capture_hw = { +static const struct snd_pcm_hardware snd_p16v_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index f0d978e3b274..d4cd6451fdca 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -1059,7 +1059,7 @@ static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *s return ptr; } -static struct snd_pcm_hardware snd_ensoniq_playback1 = +static const struct snd_pcm_hardware snd_ensoniq_playback1 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1086,7 +1086,7 @@ static struct snd_pcm_hardware snd_ensoniq_playback1 = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ensoniq_playback2 = +static const struct snd_pcm_hardware snd_ensoniq_playback2 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1106,7 +1106,7 @@ static struct snd_pcm_hardware snd_ensoniq_playback2 = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ensoniq_capture = +static const struct snd_pcm_hardware snd_ensoniq_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 069902a06f00..9d248eb2e26c 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -900,7 +900,7 @@ static int snd_es1938_pcm_hw_free(struct snd_pcm_substream *substream) /* ---------------------------------------------------------------------- * Audio1 Capture (ADC) * ----------------------------------------------------------------------*/ -static struct snd_pcm_hardware snd_es1938_capture = +static const struct snd_pcm_hardware snd_es1938_capture = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER), @@ -922,7 +922,7 @@ static struct snd_pcm_hardware snd_es1938_capture = /* ----------------------------------------------------------------------- * Audio2 Playback (DAC) * -----------------------------------------------------------------------*/ -static struct snd_pcm_hardware snd_es1938_playback = +static const struct snd_pcm_hardware snd_es1938_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 2ec2b1ce0af6..0b1845ca6005 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1290,7 +1290,7 @@ static snd_pcm_uframes_t snd_es1968_pcm_pointer(struct snd_pcm_substream *substr return bytes_to_frames(substream->runtime, ptr % es->dma_size); } -static struct snd_pcm_hardware snd_es1968_playback = { +static const struct snd_pcm_hardware snd_es1968_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -1311,7 +1311,7 @@ static struct snd_pcm_hardware snd_es1968_playback = { .fifo_size = 0, }; -static struct snd_pcm_hardware snd_es1968_capture = { +static const struct snd_pcm_hardware snd_es1968_capture = { .info = (SNDRV_PCM_INFO_NONINTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 8e6b04b39dcc..73a67bc3586b 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -599,7 +599,7 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_fm801_playback = +static const struct snd_pcm_hardware snd_fm801_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -619,7 +619,7 @@ static struct snd_pcm_hardware snd_fm801_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_fm801_capture = +static const struct snd_pcm_hardware snd_fm801_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 6d83c6e0396a..b57432f00056 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-hda-intel-objs := hda_intel.o snd-hda-tegra-objs := hda_tegra.o diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c index 7efa7bd7acb2..1b48a8c19d28 100644 --- a/sound/pci/hda/dell_wmi_helper.c +++ b/sound/pci/hda/dell_wmi_helper.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Helper functions for Dell Mic Mute LED control; * to be included from codec driver */ @@ -5,12 +6,47 @@ #if IS_ENABLED(CONFIG_DELL_LAPTOP) #include +enum { + MICMUTE_LED_ON, + MICMUTE_LED_OFF, + MICMUTE_LED_FOLLOW_CAPTURE, + MICMUTE_LED_FOLLOW_MUTE, +}; + +static int dell_led_mode = MICMUTE_LED_FOLLOW_MUTE; +static int dell_capture; static int dell_led_value; static int (*dell_micmute_led_set_func)(int); static void (*dell_old_cap_hook)(struct hda_codec *, struct snd_kcontrol *, struct snd_ctl_elem_value *); +static void call_micmute_led_update(void) +{ + int val; + + switch (dell_led_mode) { + case MICMUTE_LED_ON: + val = 1; + break; + case MICMUTE_LED_OFF: + val = 0; + break; + case MICMUTE_LED_FOLLOW_CAPTURE: + val = dell_capture; + break; + case MICMUTE_LED_FOLLOW_MUTE: + default: + val = !dell_capture; + break; + } + + if (val == dell_led_value) + return; + dell_led_value = val; + dell_micmute_led_set_func(dell_led_value); +} + static void update_dell_wmi_micmute_led(struct hda_codec *codec, struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -22,15 +58,54 @@ static void update_dell_wmi_micmute_led(struct hda_codec *codec, return; if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) { /* TODO: How do I verify if it's a mono or stereo here? */ - int val = (ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1]) ? 0 : 1; - if (val == dell_led_value) - return; - dell_led_value = val; - if (dell_micmute_led_set_func) - dell_micmute_led_set_func(dell_led_value); + dell_capture = (ucontrol->value.integer.value[0] || + ucontrol->value.integer.value[1]); + call_micmute_led_update(); } } +static int dell_mic_mute_led_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char * const texts[] = { + "On", "Off", "Follow Capture", "Follow Mute", + }; + + return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); +} + +static int dell_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = dell_led_mode; + return 0; +} + +static int dell_mic_mute_led_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int mode; + + mode = ucontrol->value.enumerated.item[0]; + if (mode > MICMUTE_LED_FOLLOW_MUTE) + mode = MICMUTE_LED_FOLLOW_MUTE; + if (mode == dell_led_mode) + return 0; + dell_led_mode = mode; + call_micmute_led_update(); + return 1; +} + +static const struct snd_kcontrol_new dell_mic_mute_mode_ctls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Mute-LED Mode", + .info = dell_mic_mute_led_mode_info, + .get = dell_mic_mute_led_mode_get, + .put = dell_mic_mute_led_mode_put, + }, + {} +}; static void alc_fixup_dell_wmi(struct hda_codec *codec, const struct hda_fixup *fix, int action) @@ -55,6 +130,7 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec, dell_old_cap_hook = spec->gen.cap_sync_hook; spec->gen.cap_sync_hook = update_dell_wmi_micmute_led; removefunc = false; + add_mixer(spec, dell_mic_mute_mode_ctls); } } diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index 6efadbfb3fe3..d361bb77ca00 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -100,7 +100,7 @@ static int hda_codec_driver_probe(struct device *dev) if (patch) { err = patch(codec); if (err < 0) - goto error_module; + goto error_module_put; } err = snd_hda_codec_build_pcms(codec); @@ -120,6 +120,9 @@ static int hda_codec_driver_probe(struct device *dev) return 0; error_module: + if (codec->patch_ops.free) + codec->patch_ops.free(codec); + error_module_put: module_put(owner); error: diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 821aad374a06..a0989d231fd0 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1803,36 +1803,6 @@ static int check_slave_present(struct hda_codec *codec, return 1; } -/* guess the value corresponding to 0dB */ -static int get_kctl_0dB_offset(struct hda_codec *codec, - struct snd_kcontrol *kctl, int *step_to_check) -{ - int _tlv[4]; - const int *tlv = NULL; - int val = -1; - - if ((kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) && - kctl->tlv.c == snd_hda_mixer_amp_tlv) { - get_ctl_amp_tlv(kctl, _tlv); - tlv = _tlv; - } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) - tlv = kctl->tlv.p; - if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { - int step = tlv[3]; - step &= ~TLV_DB_SCALE_MUTE; - if (!step) - return -1; - if (*step_to_check && *step_to_check != step) { - codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n", -- *step_to_check, step); - return -1; - } - *step_to_check = step; - val = -tlv[2] / step; - } - return val; -} - /* call kctl->put with the given value(s) */ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val) { @@ -1847,19 +1817,58 @@ static int put_kctl_with_value(struct snd_kcontrol *kctl, int val) return 0; } -/* initialize the slave volume with 0dB */ -static int init_slave_0dB(struct hda_codec *codec, - void *data, struct snd_kcontrol *slave) +struct slave_init_arg { + struct hda_codec *codec; + int step; +}; + +/* initialize the slave volume with 0dB via snd_ctl_apply_vmaster_slaves() */ +static int init_slave_0dB(struct snd_kcontrol *kctl, void *_arg) { - int offset = get_kctl_0dB_offset(codec, slave, data); - if (offset > 0) - put_kctl_with_value(slave, offset); + struct slave_init_arg *arg = _arg; + int _tlv[4]; + const int *tlv = NULL; + int step; + int val; + + if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { + if (kctl->tlv.c != snd_hda_mixer_amp_tlv) { + codec_err(arg->codec, + "Unexpected TLV callback for slave %s:%d\n", + kctl->id.name, kctl->id.index); + return 0; /* ignore */ + } + get_ctl_amp_tlv(kctl, _tlv); + tlv = _tlv; + } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) + tlv = kctl->tlv.p; + + if (!tlv || tlv[0] != SNDRV_CTL_TLVT_DB_SCALE) + return 0; + + step = tlv[3]; + step &= ~TLV_DB_SCALE_MUTE; + if (!step) + return 0; + if (arg->step && arg->step != step) { + codec_err(arg->codec, + "Mismatching dB step for vmaster slave (%d!=%d)\n", + arg->step, step); + return 0; + } + + arg->step = step; + val = -tlv[2] / step; + if (val > 0) { + put_kctl_with_value(kctl, val); + return val; + } + return 0; } -/* unmute the slave */ -static int init_slave_unmute(struct hda_codec *codec, - void *data, struct snd_kcontrol *slave) +/* unmute the slave via snd_ctl_apply_vmaster_slaves() */ +static int init_slave_unmute(struct snd_kcontrol *slave, void *_arg) { return put_kctl_with_value(slave, 1); } @@ -1919,9 +1928,13 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, /* init with master mute & zero volume */ put_kctl_with_value(kctl, 0); if (init_slave_vol) { - int step = 0; - map_slaves(codec, slaves, suffix, - tlv ? init_slave_0dB : init_slave_unmute, &step); + struct slave_init_arg arg = { + .codec = codec, + .step = 0, + }; + snd_ctl_apply_vmaster_slaves(kctl, + tlv ? init_slave_0dB : init_slave_unmute, + &arg); } if (ctl_ret) @@ -3213,8 +3226,10 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec) continue; /* no substreams assigned */ dev = get_empty_pcm_device(bus, cpcm->pcm_type); - if (dev < 0) + if (dev < 0) { + cpcm->device = SNDRV_PCM_INVALID_DEVICE; continue; /* no fatal error */ + } cpcm->device = dev; err = snd_hda_attach_pcm_stream(bus, codec, cpcm); if (err < 0) { diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 60ce1cfc300f..681c360f29f9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -164,6 +164,7 @@ enum { HDA_PCM_NTYPES }; +#define SNDRV_PCM_INVALID_DEVICE (-1) /* for PCM creation */ struct hda_pcm { char *name; diff --git a/sound/pci/hda/hda_controller_trace.h b/sound/pci/hda/hda_controller_trace.h index 3e18d99bfb70..bf48304e230a 100644 --- a/sound/pci/hda/hda_controller_trace.h +++ b/sound/pci/hda/hda_controller_trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM hda_controller #define TRACE_INCLUDE_FILE hda_controller_trace diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5ae8ddab6412..f958d8d54d15 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2389,6 +2389,9 @@ static const struct pci_device_id azx_ids[] = { /* Coffelake */ { PCI_DEVICE(0x8086, 0xa348), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, + /* Cannonlake */ + { PCI_DEVICE(0x8086, 0x9dc8), + .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, /* Broxton-P(Apollolake) */ { PCI_DEVICE(0x8086, 0x5a98), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON }, diff --git a/sound/pci/hda/hda_intel_trace.h b/sound/pci/hda/hda_intel_trace.h index 0922d8b1b17d..73a7adfa192d 100644 --- a/sound/pci/hda/hda_intel_trace.h +++ b/sound/pci/hda/hda_intel_trace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #undef TRACE_SYSTEM #define TRACE_SYSTEM hda_intel #define TRACE_INCLUDE_FILE hda_intel_trace diff --git a/sound/pci/hda/local.h b/sound/pci/hda/local.h index 28cb7f98982e..3b8b7d78f9e0 100644 --- a/sound/pci/hda/local.h +++ b/sound/pci/hda/local.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* */ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index e0fb8c6d1bc2..757857313426 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -505,7 +505,7 @@ static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new ad1983_auto_smux_mixer = { +static const struct snd_kcontrol_new ad1983_auto_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Playback Source", .info = ad1983_auto_smux_enum_info, @@ -788,7 +788,7 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new ad1988_auto_smux_mixer = { +static const struct snd_kcontrol_new ad1988_auto_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Playback Source", .info = ad1988_auto_smux_enum_info, diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index a148176c16a9..3e73d5c6ccfc 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4774,13 +4774,17 @@ static int patch_ca0132(struct hda_codec *codec) err = ca0132_prepare_verbs(codec); if (err < 0) - return err; + goto error; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); if (err < 0) - return err; + goto error; return 0; + + error: + ca0132_free(codec); + return err; } /* diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 53f9311370de..c19c81d230bd 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -906,6 +906,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, hda_nid_t pin_nid, u32 stream_tag, int format) { struct hdmi_spec *spec = codec->spec; + unsigned int param; int err; err = spec->ops.pin_hbr_setup(codec, pin_nid, is_hbr_format(format)); @@ -915,6 +916,26 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid, return err; } + if (is_haswell_plus(codec)) { + + /* + * on recent platforms IEC Coding Type is required for HBR + * support, read current Digital Converter settings and set + * ICT bitfield if needed. + */ + param = snd_hda_codec_read(codec, cvt_nid, 0, + AC_VERB_GET_DIGI_CONVERT_1, 0); + + param = (param >> 16) & ~(AC_DIG3_ICT); + + /* on recent platforms ICT mode is required for HBR support */ + if (is_hbr_format(format)) + param |= 0x1; + + snd_hda_codec_write(codec, cvt_nid, 0, + AC_VERB_SET_DIGI_CONVERT_3, param); + } + snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format); return 0; } @@ -2126,7 +2147,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pcm_idx) static int generic_hdmi_build_controls(struct hda_codec *codec) { struct hdmi_spec *spec = codec->spec; - int err; + int dev, err; int pin_idx, pcm_idx; @@ -2154,11 +2175,13 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) return err; snd_hda_spdif_ctls_unassign(codec, pcm_idx); - /* add control for ELD Bytes */ - err = hdmi_create_eld_ctl(codec, pcm_idx, - get_pcm_rec(spec, pcm_idx)->device); - if (err < 0) - return err; + dev = get_pcm_rec(spec, pcm_idx)->device; + if (dev != SNDRV_PCM_INVALID_DEVICE) { + /* add control for ELD Bytes */ + err = hdmi_create_eld_ctl(codec, pcm_idx, dev); + if (err < 0) + return err; + } } for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 217bb582aff1..dce0682c5001 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -327,6 +327,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec) case 0x10ec0215: case 0x10ec0225: case 0x10ec0233: + case 0x10ec0236: case 0x10ec0255: case 0x10ec0256: case 0x10ec0282: @@ -911,6 +912,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = { { 0x10ec0275, 0x1028, 0, "ALC3260" }, { 0x10ec0899, 0x1028, 0, "ALC3861" }, { 0x10ec0298, 0x1028, 0, "ALC3266" }, + { 0x10ec0236, 0x1028, 0, "ALC3204" }, { 0x10ec0256, 0x1028, 0, "ALC3246" }, { 0x10ec0225, 0x1028, 0, "ALC3253" }, { 0x10ec0295, 0x1028, 0, "ALC3254" }, @@ -3930,6 +3932,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) alc_process_coef_fw(codec, coef0255_1); alc_process_coef_fw(codec, coef0255); break; + case 0x10ec0236: case 0x10ec0256: alc_process_coef_fw(codec, coef0256); alc_process_coef_fw(codec, coef0255); @@ -4028,6 +4031,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, }; switch (codec->core.vendor_id) { + case 0x10ec0236: case 0x10ec0255: case 0x10ec0256: alc_write_coef_idx(codec, 0x45, 0xc489); @@ -4160,6 +4164,7 @@ static void alc_headset_mode_default(struct hda_codec *codec) alc_process_coef_fw(codec, alc225_pre_hsmode); alc_process_coef_fw(codec, coef0225); break; + case 0x10ec0236: case 0x10ec0255: case 0x10ec0256: alc_process_coef_fw(codec, coef0255); @@ -4256,6 +4261,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) case 0x10ec0255: alc_process_coef_fw(codec, coef0255); break; + case 0x10ec0236: case 0x10ec0256: alc_process_coef_fw(codec, coef0256); break; @@ -4366,6 +4372,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) case 0x10ec0255: alc_process_coef_fw(codec, coef0255); break; + case 0x10ec0236: case 0x10ec0256: alc_process_coef_fw(codec, coef0256); break; @@ -4451,6 +4458,7 @@ static void alc_determine_headset_type(struct hda_codec *codec) }; switch (codec->core.vendor_id) { + case 0x10ec0236: case 0x10ec0255: case 0x10ec0256: alc_process_coef_fw(codec, coef0255); @@ -4705,6 +4713,7 @@ static void alc255_set_default_jack_type(struct hda_codec *codec) case 0x10ec0255: alc_process_coef_fw(codec, alc255fw); break; + case 0x10ec0236: case 0x10ec0256: alc_process_coef_fw(codec, alc256fw); break; @@ -5263,6 +5272,7 @@ enum { ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, ALC233_FIXUP_LENOVO_MULTI_CODECS, ALC294_FIXUP_LENOVO_MIC_LOCATION, + ALC700_FIXUP_INTEL_REFERENCE, }; static const struct hda_fixup alc269_fixups[] = { @@ -6058,6 +6068,21 @@ static const struct hda_fixup alc269_fixups[] = { { } }, }, + [ALC700_FIXUP_INTEL_REFERENCE] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* Enables internal speaker */ + {0x20, AC_VERB_SET_COEF_INDEX, 0x45}, + {0x20, AC_VERB_SET_PROC_COEF, 0x5289}, + {0x20, AC_VERB_SET_COEF_INDEX, 0x4A}, + {0x20, AC_VERB_SET_PROC_COEF, 0x001b}, + {0x58, AC_VERB_SET_COEF_INDEX, 0x00}, + {0x58, AC_VERB_SET_PROC_COEF, 0x3888}, + {0x20, AC_VERB_SET_COEF_INDEX, 0x6f}, + {0x20, AC_VERB_SET_PROC_COEF, 0x2c0b}, + {} + } + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -6209,6 +6234,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), + SND_PCI_QUIRK(0x10ec, 0x10f2, "Intel Reference board", ALC700_FIXUP_INTEL_REFERENCE), SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), @@ -6402,6 +6428,14 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { ALC225_STANDARD_PINS, {0x12, 0xb7a60130}, {0x1b, 0x90170110}), + SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60140}, + {0x14, 0x90170110}, + {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0x90a60140}, + {0x14, 0x90170150}, + {0x21, 0x02211020}), SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, {0x14, 0x90170110}, {0x21, 0x02211020}), @@ -6510,6 +6544,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { {0x14, 0x90170110}, {0x1b, 0x90a70130}, {0x21, 0x03211020}), + SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, + {0x12, 0xb7a60130}, + {0x13, 0xb8a61140}, + {0x16, 0x90170110}, + {0x21, 0x04211020}), SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, {0x12, 0x90a60130}, {0x14, 0x90170110}, @@ -6789,6 +6828,7 @@ static int patch_alc269(struct hda_codec *codec) case 0x10ec0255: spec->codec_variant = ALC269_TYPE_ALC255; break; + case 0x10ec0236: case 0x10ec0256: spec->codec_variant = ALC269_TYPE_ALC256; spec->shutup = alc256_shutup; @@ -7840,6 +7880,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = { HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269), HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269), HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269), + HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269), HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269), HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269), HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6cefdf6c0b75..63d15b545b33 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -961,7 +961,7 @@ static int stac_smux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_smux[smux_idx]); } -static struct snd_kcontrol_new stac_smux_mixer = { +static const struct snd_kcontrol_new stac_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "IEC958 Playback Source", /* count set later */ diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c index 4d9d320a7971..65bb3ac6af4c 100644 --- a/sound/pci/hda/thinkpad_helper.c +++ b/sound/pci/hda/thinkpad_helper.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Helper functions for Thinkpad LED control; * to be included from codec driver */ diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile index 7e50c1324556..1196f22a9b45 100644 --- a/sound/pci/ice1712/Makefile +++ b/sound/pci/ice1712/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index da5f37b7fdd0..6808bed0105e 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -445,7 +445,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status = * initialize the chips on M-Audio cards */ -static struct snd_akm4xxx akm_audiophile = { +static const struct snd_akm4xxx akm_audiophile = { .type = SND_AK4528, .num_adcs = 2, .num_dacs = 2, @@ -454,7 +454,7 @@ static struct snd_akm4xxx akm_audiophile = { } }; -static struct snd_ak4xxx_private akm_audiophile_priv = { +static const struct snd_ak4xxx_private akm_audiophile_priv = { .caddr = 2, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -466,7 +466,7 @@ static struct snd_ak4xxx_private akm_audiophile_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_delta410 = { +static const struct snd_akm4xxx akm_delta410 = { .type = SND_AK4529, .num_adcs = 2, .num_dacs = 8, @@ -475,7 +475,7 @@ static struct snd_akm4xxx akm_delta410 = { } }; -static struct snd_ak4xxx_private akm_delta410_priv = { +static const struct snd_ak4xxx_private akm_delta410_priv = { .caddr = 0, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -487,7 +487,7 @@ static struct snd_ak4xxx_private akm_delta410_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_delta1010lt = { +static const struct snd_akm4xxx akm_delta1010lt = { .type = SND_AK4524, .num_adcs = 8, .num_dacs = 8, @@ -497,7 +497,7 @@ static struct snd_akm4xxx akm_delta1010lt = { } }; -static struct snd_ak4xxx_private akm_delta1010lt_priv = { +static const struct snd_ak4xxx_private akm_delta1010lt_priv = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_1010LT_DOUT, @@ -509,7 +509,7 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_delta66e = { +static const struct snd_akm4xxx akm_delta66e = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -519,7 +519,7 @@ static struct snd_akm4xxx akm_delta66e = { } }; -static struct snd_ak4xxx_private akm_delta66e_priv = { +static const struct snd_ak4xxx_private akm_delta66e_priv = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_66E_DOUT, @@ -532,7 +532,7 @@ static struct snd_ak4xxx_private akm_delta66e_priv = { }; -static struct snd_akm4xxx akm_delta44 = { +static const struct snd_akm4xxx akm_delta44 = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -542,7 +542,7 @@ static struct snd_akm4xxx akm_delta44 = { } }; -static struct snd_ak4xxx_private akm_delta44_priv = { +static const struct snd_ak4xxx_private akm_delta44_priv = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, @@ -554,7 +554,7 @@ static struct snd_ak4xxx_private akm_delta44_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_vx442 = { +static const struct snd_akm4xxx akm_vx442 = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -564,7 +564,7 @@ static struct snd_akm4xxx akm_vx442 = { } }; -static struct snd_ak4xxx_private akm_vx442_priv = { +static const struct snd_ak4xxx_private akm_vx442_priv = { .caddr = 2, .cif = 0, .data_mask = ICE1712_VX442_DOUT, diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index ec07136fc288..b8af747ecb43 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -344,7 +344,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate) /* */ -static struct snd_akm4xxx akm_ews88mt = { +static const struct snd_akm4xxx akm_ews88mt = { .num_adcs = 8, .num_dacs = 8, .type = SND_AK4524, @@ -354,7 +354,7 @@ static struct snd_akm4xxx akm_ews88mt = { } }; -static struct snd_ak4xxx_private akm_ews88mt_priv = { +static const struct snd_ak4xxx_private akm_ews88mt_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -366,7 +366,7 @@ static struct snd_ak4xxx_private akm_ews88mt_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_ewx2496 = { +static const struct snd_akm4xxx akm_ewx2496 = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -375,7 +375,7 @@ static struct snd_akm4xxx akm_ewx2496 = { } }; -static struct snd_ak4xxx_private akm_ewx2496_priv = { +static const struct snd_ak4xxx_private akm_ewx2496_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -387,7 +387,7 @@ static struct snd_ak4xxx_private akm_ewx2496_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_6fire = { +static const struct snd_akm4xxx akm_6fire = { .num_adcs = 6, .num_dacs = 6, .type = SND_AK4524, @@ -396,7 +396,7 @@ static struct snd_akm4xxx akm_6fire = { } }; -static struct snd_ak4xxx_private akm_6fire_priv = { +static const struct snd_ak4xxx_private akm_6fire_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_6FIRE_SERIAL_DATA, diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index a40001c1d9e8..fa301d31745b 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -166,7 +166,7 @@ static void snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) mutex_unlock(&ice->gpio_mutex); } -static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) +static int hoontech_init(struct snd_ice1712 *ice, bool staudio) { struct hoontech_spec *spec; int box, chn; @@ -203,7 +203,10 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) ICE1712_STDSP24_3_INSEL(spec->boxbits, 0); /* let's go - activate only functions in first box */ - spec->config = 0; + if (staudio) + spec->config = ICE1712_STDSP24_MUTE; + else + spec->config = 0; /* ICE1712_STDSP24_MUTE | ICE1712_STDSP24_INSEL | ICE1712_STDSP24_DAREAR; */ @@ -226,9 +229,16 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) ICE1712_STDSP24_BOX_CHN4 | ICE1712_STDSP24_BOX_MIDI1 | ICE1712_STDSP24_BOX_MIDI2; - spec->boxconfig[1] = - spec->boxconfig[2] = - spec->boxconfig[3] = 0; + if (staudio) { + spec->boxconfig[1] = + spec->boxconfig[2] = + spec->boxconfig[3] = spec->boxconfig[0]; + } else { + spec->boxconfig[1] = + spec->boxconfig[2] = + spec->boxconfig[3] = 0; + } + snd_ice1712_stdsp24_darear(ice, (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0); snd_ice1712_stdsp24_mute(ice, @@ -248,6 +258,16 @@ static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) return 0; } +static int snd_ice1712_hoontech_init(struct snd_ice1712 *ice) +{ + return hoontech_init(ice, false); +} + +static int snd_ice1712_staudio_init(struct snd_ice1712 *ice) +{ + return hoontech_init(ice, true); +} + /* * AK4524 access */ @@ -269,7 +289,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) static int snd_ice1712_value_init(struct snd_ice1712 *ice) { /* Hoontech STDSP24 with modified hardware */ - static struct snd_akm4xxx akm_stdsp24_mv = { + static const struct snd_akm4xxx akm_stdsp24_mv = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -278,7 +298,7 @@ static int snd_ice1712_value_init(struct snd_ice1712 *ice) } }; - static struct snd_ak4xxx_private akm_stdsp24_mv_priv = { + static const struct snd_ak4xxx_private akm_stdsp24_mv_priv = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_STDSP24_SERIAL_DATA, @@ -351,5 +371,14 @@ struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] = { .model = "ez8", .chip_init = snd_ice1712_ez8_init, }, + { + /* STAudio ADCIII has the same SSID as Hoontech StA DSP24, + * thus identified only via the explicit model option + */ + .subvendor = ICE1712_SUBDEVICE_STAUDIO_ADCIII, /* a dummy id */ + .name = "STAudio ADCIII", + .model = "staudio", + .chip_init = snd_ice1712_staudio_init, + }, { } /* terminator */ }; diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h index cc1da1e69ad1..7f94943392ce 100644 --- a/sound/pci/ice1712/hoontech.h +++ b/sound/pci/ice1712/hoontech.h @@ -34,6 +34,7 @@ #define ICE1712_SUBDEVICE_STDSP24_VALUE 0x00010010 /* A dummy id for Hoontech SoundTrack Audio DSP 24 Value */ #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ #define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ +#define ICE1712_SUBDEVICE_STAUDIO_ADCIII 0x00010002 /* A dummy id for STAudio ADCIII */ extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 5bb146703738..0dbaccf61f33 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -282,7 +282,7 @@ static const struct snd_akm4xxx_dac_channel juli_dac[] = { }; -static struct snd_akm4xxx akm_juli_dac = { +static const struct snd_akm4xxx akm_juli_dac = { .type = SND_AK4358, .num_dacs = 8, /* DAC1 - analog out DAC2 - analog in monitor diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h index d9f8534fd92e..9c22d4e73ee3 100644 --- a/sound/pci/ice1712/juli.h +++ b/sound/pci/ice1712/juli.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_JULI_H #define __SOUND_JULI_H diff --git a/sound/pci/ice1712/maya44.h b/sound/pci/ice1712/maya44.h index eafd03a8f4b5..f5a97d987a6f 100644 --- a/sound/pci/ice1712/maya44.h +++ b/sound/pci/ice1712/maya44.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_MAYA44_H #define __SOUND_MAYA44_H diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index e9ca89c9174b..67fbb28bf033 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -102,13 +102,13 @@ static const unsigned char wm_vol[256] = { #define WM_VOL_MAX (sizeof(wm_vol) - 1) #define WM_VOL_MUTE 0x8000 -static struct snd_akm4xxx akm_phase22 = { +static const struct snd_akm4xxx akm_phase22 = { .type = SND_AK4524, .num_dacs = 2, .num_adcs = 2, }; -static struct snd_ak4xxx_private akm_phase22_priv = { +static const struct snd_ak4xxx_private akm_phase22_priv = { .caddr = 2, .cif = 1, .data_mask = 1 << 4, diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h index 16a53b459c72..7bfd769ba982 100644 --- a/sound/pci/ice1712/prodigy192.h +++ b/sound/pci/ice1712/prodigy192.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_PRODIGY192_H #define __SOUND_PRODIGY192_H diff --git a/sound/pci/ice1712/psc724.h b/sound/pci/ice1712/psc724.h index 858e5fd0eebb..e6ce335ae87e 100644 --- a/sound/pci/ice1712/psc724.h +++ b/sound/pci/ice1712/psc724.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_PSC724_H #define __SOUND_PSC724_H diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index f1b3732cc6d2..d145b5eb7ff8 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c @@ -386,7 +386,7 @@ static const struct snd_akm4xxx_adc_channel qtet_adc[] = { AK_CONTROL(PCM_34_CAPTURE_VOLUME, 2), }; -static struct snd_akm4xxx akm_qtet_dac = { +static const struct snd_akm4xxx akm_qtet_dac = { .type = SND_AK4620, .num_dacs = 4, /* DAC1 - Output 12 */ diff --git a/sound/pci/ice1712/quartet.h b/sound/pci/ice1712/quartet.h index 80809b72439a..a1c2fe27185d 100644 --- a/sound/pci/ice1712/quartet.h +++ b/sound/pci/ice1712/quartet.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_QTET_H #define __SOUND_QTET_H diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 1d81ae677573..6669c389f336 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -235,7 +235,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = { }, }; -static struct snd_akm4xxx akm_revo_front = { +static const struct snd_akm4xxx akm_revo_front = { .type = SND_AK4381, .num_dacs = 2, .ops = { @@ -244,7 +244,7 @@ static struct snd_akm4xxx akm_revo_front = { .dac_info = revo71_front, }; -static struct snd_ak4xxx_private akm_revo_front_priv = { +static const struct snd_ak4xxx_private akm_revo_front_priv = { .caddr = 1, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -256,7 +256,7 @@ static struct snd_ak4xxx_private akm_revo_front_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo_surround = { +static const struct snd_akm4xxx akm_revo_surround = { .type = SND_AK4355, .idx_offset = 1, .num_dacs = 6, @@ -266,7 +266,7 @@ static struct snd_akm4xxx akm_revo_surround = { .dac_info = revo71_surround, }; -static struct snd_ak4xxx_private akm_revo_surround_priv = { +static const struct snd_ak4xxx_private akm_revo_surround_priv = { .caddr = 3, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -278,7 +278,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo51 = { +static const struct snd_akm4xxx akm_revo51 = { .type = SND_AK4358, .num_dacs = 8, .ops = { @@ -287,7 +287,7 @@ static struct snd_akm4xxx akm_revo51 = { .dac_info = revo51_dac, }; -static struct snd_ak4xxx_private akm_revo51_priv = { +static const struct snd_ak4xxx_private akm_revo51_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -299,13 +299,13 @@ static struct snd_ak4xxx_private akm_revo51_priv = { .mask_flags = 0, }; -static struct snd_akm4xxx akm_revo51_adc = { +static const struct snd_akm4xxx akm_revo51_adc = { .type = SND_AK5365, .num_adcs = 2, .adc_info = revo51_adc, }; -static struct snd_ak4xxx_private akm_revo51_adc_priv = { +static const struct snd_ak4xxx_private akm_revo51_adc_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -346,7 +346,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = { AK_DAC("PCM Playback Volume", 2) }; -static struct snd_akm4xxx akm_ap192 = { +static const struct snd_akm4xxx akm_ap192 = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -355,7 +355,7 @@ static struct snd_akm4xxx akm_ap192 = { .dac_info = ap192_dac, }; -static struct snd_ak4xxx_private akm_ap192_priv = { +static const struct snd_ak4xxx_private akm_ap192_priv = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, diff --git a/sound/pci/ice1712/se.h b/sound/pci/ice1712/se.h index 0b0a9dabdcfb..61348ecef1e0 100644 --- a/sound/pci/ice1712/se.h +++ b/sound/pci/ice1712/se.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_SE_H #define __SOUND_SE_H diff --git a/sound/pci/ice1712/stac946x.h b/sound/pci/ice1712/stac946x.h index 5b390952d0e4..58f9f17a258a 100644 --- a/sound/pci/ice1712/stac946x.h +++ b/sound/pci/ice1712/stac946x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_STAC946X_H #define __SOUND_STAC946X_H diff --git a/sound/pci/ice1712/wtm.h b/sound/pci/ice1712/wtm.h index 423c1a204c0b..1cfcbde15f42 100644 --- a/sound/pci/ice1712/wtm.h +++ b/sound/pci/ice1712/wtm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SOUND_WTM_H #define __SOUND_WTM_H diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index a8d7092e93dd..4c24346340f4 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1115,7 +1115,7 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs return bytes_to_frames(substream->runtime, ptr); } -static struct snd_pcm_hardware snd_intel8x0_stream = +static const struct snd_pcm_hardware snd_intel8x0_stream = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1367,7 +1367,7 @@ static int snd_intel8x0_ali_spdifout_close(struct snd_pcm_substream *substream) } #endif -static struct snd_pcm_ops snd_intel8x0_playback_ops = { +static const struct snd_pcm_ops snd_intel8x0_playback_ops = { .open = snd_intel8x0_playback_open, .close = snd_intel8x0_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1378,7 +1378,7 @@ static struct snd_pcm_ops snd_intel8x0_playback_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture_ops = { .open = snd_intel8x0_capture_open, .close = snd_intel8x0_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -1389,7 +1389,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture_mic_ops = { .open = snd_intel8x0_mic_open, .close = snd_intel8x0_mic_close, .ioctl = snd_pcm_lib_ioctl, @@ -1400,7 +1400,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = { .open = snd_intel8x0_mic2_open, .close = snd_intel8x0_mic2_close, .ioctl = snd_pcm_lib_ioctl, @@ -1411,7 +1411,7 @@ static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_capture2_ops = { +static const struct snd_pcm_ops snd_intel8x0_capture2_ops = { .open = snd_intel8x0_capture2_open, .close = snd_intel8x0_capture2_close, .ioctl = snd_pcm_lib_ioctl, @@ -1422,7 +1422,7 @@ static struct snd_pcm_ops snd_intel8x0_capture2_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_spdif_ops = { +static const struct snd_pcm_ops snd_intel8x0_spdif_ops = { .open = snd_intel8x0_spdif_open, .close = snd_intel8x0_spdif_close, .ioctl = snd_pcm_lib_ioctl, @@ -1433,7 +1433,7 @@ static struct snd_pcm_ops snd_intel8x0_spdif_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_playback_ops = { .open = snd_intel8x0_playback_open, .close = snd_intel8x0_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1444,7 +1444,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_capture_ops = { .open = snd_intel8x0_capture_open, .close = snd_intel8x0_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -1455,7 +1455,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = { .open = snd_intel8x0_mic_open, .close = snd_intel8x0_mic_close, .ioctl = snd_pcm_lib_ioctl, @@ -1466,7 +1466,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = { .pointer = snd_intel8x0_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = { +static const struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = { .open = snd_intel8x0_ali_ac97spdifout_open, .close = snd_intel8x0_ali_ac97spdifout_close, .ioctl = snd_pcm_lib_ioctl, @@ -1503,8 +1503,8 @@ static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = { struct ich_pcm_table { char *suffix; - struct snd_pcm_ops *playback_ops; - struct snd_pcm_ops *capture_ops; + const struct snd_pcm_ops *playback_ops; + const struct snd_pcm_ops *capture_ops; size_t prealloc_size; size_t prealloc_max_size; int ac97_idx; @@ -1721,7 +1721,7 @@ static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97) chip->ac97[ac97->num] = NULL; } -static struct ac97_pcm ac97_pcm_defs[] = { +static const struct ac97_pcm ac97_pcm_defs[] = { /* front PCM */ { .exclusive = 1, diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 18ff668ce7a5..3a4769a97d29 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -611,7 +611,7 @@ static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_hardware snd_intel8x0m_stream = +static const struct snd_pcm_hardware snd_intel8x0m_stream = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -685,7 +685,7 @@ static int snd_intel8x0m_capture_close(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_intel8x0m_playback_ops = { +static const struct snd_pcm_ops snd_intel8x0m_playback_ops = { .open = snd_intel8x0m_playback_open, .close = snd_intel8x0m_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -696,7 +696,7 @@ static struct snd_pcm_ops snd_intel8x0m_playback_ops = { .pointer = snd_intel8x0m_pcm_pointer, }; -static struct snd_pcm_ops snd_intel8x0m_capture_ops = { +static const struct snd_pcm_ops snd_intel8x0m_capture_ops = { .open = snd_intel8x0m_capture_open, .close = snd_intel8x0m_capture_close, .ioctl = snd_pcm_lib_ioctl, @@ -710,8 +710,8 @@ static struct snd_pcm_ops snd_intel8x0m_capture_ops = { struct ich_pcm_table { char *suffix; - struct snd_pcm_ops *playback_ops; - struct snd_pcm_ops *capture_ops; + const struct snd_pcm_ops *playback_ops; + const struct snd_pcm_ops *capture_ops; size_t prealloc_size; size_t prealloc_max_size; int ac97_idx; diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index b28fe4914d6b..04cd71c74e5c 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -1231,7 +1231,7 @@ static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212) return 0; } -static struct snd_pcm_hardware snd_korg1212_playback_info = +static const struct snd_pcm_hardware snd_korg1212_playback_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -1252,7 +1252,7 @@ static struct snd_pcm_hardware snd_korg1212_playback_info = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_korg1212_capture_info = +static const struct snd_pcm_hardware snd_korg1212_capture_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c index 1268ba329016..310b26a756c9 100644 --- a/sound/pci/lola/lola_pcm.c +++ b/sound/pci/lola/lola_pcm.c @@ -197,7 +197,7 @@ static void lola_stream_reset(struct lola *chip, struct lola_stream *str) } } -static struct snd_pcm_hardware lola_pcm_hw = { +static const struct snd_pcm_hardware lola_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index f9c3e86d55d5..9655b08a1c52 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c @@ -77,7 +77,7 @@ MODULE_DEVICE_TABLE(pci, snd_lx6464es_ids); /* alsa callbacks */ -static struct snd_pcm_hardware lx_caps = { +static const struct snd_pcm_hardware lx_caps = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index cafea6dc5c01..8f20dec97843 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -1681,7 +1681,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id) /* */ -static struct snd_pcm_hardware snd_m3_playback = +static const struct snd_pcm_hardware snd_m3_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -1702,7 +1702,7 @@ static struct snd_pcm_hardware snd_m3_playback = .periods_max = 1024, }; -static struct snd_pcm_hardware snd_m3_capture = +static const struct snd_pcm_hardware snd_m3_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -2622,22 +2622,18 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, err = request_firmware(&chip->assp_kernel_image, "ess/maestro3_assp_kernel.fw", &pci->dev); - if (err < 0) { - snd_m3_free(chip); - return err; - } + if (err < 0) + goto free_chip; err = request_firmware(&chip->assp_minisrc_image, "ess/maestro3_assp_minisrc.fw", &pci->dev); - if (err < 0) { - snd_m3_free(chip); - return err; - } + if (err < 0) + goto free_chip; + + err = pci_request_regions(pci, card->driver); + if (err < 0) + goto free_chip; - if ((err = pci_request_regions(pci, card->driver)) < 0) { - snd_m3_free(chip); - return err; - } chip->iobase = pci_resource_start(pci, 0); /* just to be sure */ @@ -2655,8 +2651,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); - snd_m3_free(chip); - return -ENOMEM; + err = -ENOMEM; + goto free_chip; } chip->irq = pci->irq; @@ -2666,10 +2662,9 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, dev_warn(card->dev, "can't allocate apm buffer\n"); #endif - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_m3_free(chip); - return err; - } + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) + goto free_chip; if ((err = snd_m3_mixer(chip)) < 0) return err; @@ -2699,6 +2694,10 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, *chip_ret = chip; return 0; + +free_chip: + snd_m3_free(chip); + return err; } /* @@ -2741,23 +2740,19 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) break; } - if ((err = snd_m3_create(card, pci, - external_amp[dev], - amp_gpio[dev], - &chip)) < 0) { - snd_card_free(card); - return err; - } + err = snd_m3_create(card, pci, external_amp[dev], amp_gpio[dev], &chip); + if (err < 0) + goto free_card; + card->private_data = chip; sprintf(card->shortname, "ESS %s PCI", card->driver); sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, chip->iobase, chip->irq); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto free_card; #if 0 /* TODO: not supported yet */ /* TODO enable MIDI IRQ and I/O */ @@ -2772,6 +2767,10 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) pci_set_drvdata(pci, card); dev++; return 0; + +free_card: + snd_card_free(card); + return err; } static void snd_m3_remove(struct pci_dev *pci) diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 80d439944cb5..a74f1ad7e7b8 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -675,7 +675,7 @@ static int snd_mixart_hw_free(struct snd_pcm_substream *subs) /* * TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max */ -static struct snd_pcm_hardware snd_mixart_analog_caps = +static const struct snd_pcm_hardware snd_mixart_analog_caps = { .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -696,7 +696,7 @@ static struct snd_pcm_hardware snd_mixart_analog_caps = .periods_max = (32*1024/256), }; -static struct snd_pcm_hardware snd_mixart_digital_caps = +static const struct snd_pcm_hardware snd_mixart_digital_caps = { .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1052,10 +1052,8 @@ static int snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int }; chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (! chip) { - dev_err(card->dev, "cannot allocate chip\n"); + if (!chip) return -ENOMEM; - } chip->card = card; chip->chip_idx = idx; @@ -1313,9 +1311,6 @@ static int snd_mixart_probe(struct pci_dev *pci, } mgr->irq = pci->irq; - sprintf(mgr->shortname, "Digigram miXart"); - sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, irq %i", mgr->shortname, mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq); - /* init mailbox */ mgr->msg_fifo_readptr = 0; mgr->msg_fifo_writeptr = 0; @@ -1350,8 +1345,11 @@ static int snd_mixart_probe(struct pci_dev *pci, } strcpy(card->driver, CARD_NAME); - sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i); - sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); + snprintf(card->shortname, sizeof(card->shortname), + "Digigram miXart [PCM #%d]", i); + snprintf(card->longname, sizeof(card->longname), + "Digigram miXart at 0x%lx & 0x%lx, irq %i [PCM #%d]", + mgr->mem[0].phys, mgr->mem[1].phys, mgr->irq, i); if ((err = snd_mixart_create(mgr, card, i)) < 0) { snd_card_free(card); diff --git a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h index 426743871540..69b3ece099ad 100644 --- a/sound/pci/mixart/mixart.h +++ b/sound/pci/mixart/mixart.h @@ -74,10 +74,6 @@ struct mixart_mgr { /* memory-maps */ struct mem_area mem[2]; - /* share the name */ - char shortname[32]; /* short name of this soundcard */ - char longname[80]; /* name of this soundcard */ - /* one and only blocking message or notification may be pending */ u32 pending_event; wait_queue_head_t msg_sleep; diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 0ef8054c3936..b97f4ea6b56c 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -1271,7 +1271,7 @@ snd_nm256_ac97_write(struct snd_ac97 *ac97, } /* static resolution table */ -static struct snd_ac97_res_table nm256_res_table[] = { +static const struct snd_ac97_res_table nm256_res_table[] = { { AC97_MASTER, 0x1f1f }, { AC97_HEADPHONE, 0x1f1f }, { AC97_MASTER_MONO, 0x001f }, diff --git a/sound/pci/nm256/nm256_coef.c b/sound/pci/nm256/nm256_coef.c index 747d5d6ccfa0..c757252119b1 100644 --- a/sound/pci/nm256/nm256_coef.c +++ b/sound/pci/nm256/nm256_coef.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define NM_TOTAL_COEFF_COUNT 0x3158 static char coefficients[NM_TOTAL_COEFF_COUNT * 4] = { diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile index ab085d753661..0dfc4f840992 100644 --- a/sound/pci/oxygen/Makefile +++ b/sound/pci/oxygen/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o snd-oxygen-objs := oxygen.o xonar_dg_mixer.o xonar_dg.o snd-se6x-objs := se6x.o diff --git a/sound/pci/oxygen/ak4396.h b/sound/pci/oxygen/ak4396.h index 551c1cf8e2e0..a51223461b11 100644 --- a/sound/pci/oxygen/ak4396.h +++ b/sound/pci/oxygen/ak4396.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef AK4396_H_INCLUDED #define AK4396_H_INCLUDED diff --git a/sound/pci/oxygen/cm9780.h b/sound/pci/oxygen/cm9780.h index 144596799676..7efb119d1763 100644 --- a/sound/pci/oxygen/cm9780.h +++ b/sound/pci/oxygen/cm9780.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CM9780_H_INCLUDED #define CM9780_H_INCLUDED diff --git a/sound/pci/oxygen/cs2000.h b/sound/pci/oxygen/cs2000.h index c3501bdb5edc..aca04794ce28 100644 --- a/sound/pci/oxygen/cs2000.h +++ b/sound/pci/oxygen/cs2000.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CS2000_H_INCLUDED #define CS2000_H_INCLUDED diff --git a/sound/pci/oxygen/cs4245.h b/sound/pci/oxygen/cs4245.h index 99098657695a..bb9f2c5b5819 100644 --- a/sound/pci/oxygen/cs4245.h +++ b/sound/pci/oxygen/cs4245.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define CS4245_CHIP_ID 0x01 #define CS4245_POWER_CTRL 0x02 #define CS4245_DAC_CTRL_1 0x03 diff --git a/sound/pci/oxygen/cs4362a.h b/sound/pci/oxygen/cs4362a.h index 6a4fedf5e1ec..1aef15e04dfb 100644 --- a/sound/pci/oxygen/cs4362a.h +++ b/sound/pci/oxygen/cs4362a.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* register 01h */ #define CS4362A_PDN 0x01 #define CS4362A_DAC1_DIS 0x02 diff --git a/sound/pci/oxygen/cs4398.h b/sound/pci/oxygen/cs4398.h index 5faf5efc8826..76cb9d7af0d7 100644 --- a/sound/pci/oxygen/cs4398.h +++ b/sound/pci/oxygen/cs4398.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* register 1 */ #define CS4398_REV_MASK 0x07 #define CS4398_PART_MASK 0xf8 diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 293d0b9a50c3..06bf7e5744d0 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef OXYGEN_H_INCLUDED #define OXYGEN_H_INCLUDED diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h index 8c191badaae8..eca9d943f5c7 100644 --- a/sound/pci/oxygen/oxygen_regs.h +++ b/sound/pci/oxygen/oxygen_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef OXYGEN_REGS_H_INCLUDED #define OXYGEN_REGS_H_INCLUDED diff --git a/sound/pci/oxygen/pcm1796.h b/sound/pci/oxygen/pcm1796.h index 698bf46c710c..34d07dd2d22e 100644 --- a/sound/pci/oxygen/pcm1796.h +++ b/sound/pci/oxygen/pcm1796.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PCM1796_H_INCLUDED #define PCM1796_H_INCLUDED diff --git a/sound/pci/oxygen/wm8766.h b/sound/pci/oxygen/wm8766.h index e0e849a7eaeb..be83ad49dbb1 100644 --- a/sound/pci/oxygen/wm8766.h +++ b/sound/pci/oxygen/wm8766.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef WM8766_H_INCLUDED #define WM8766_H_INCLUDED diff --git a/sound/pci/oxygen/wm8785.h b/sound/pci/oxygen/wm8785.h index 8c23e315ae66..21b932566598 100644 --- a/sound/pci/oxygen/wm8785.h +++ b/sound/pci/oxygen/wm8785.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef WM8785_H_INCLUDED #define WM8785_H_INCLUDED diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h index 0434c207e811..3e373880c187 100644 --- a/sound/pci/oxygen/xonar.h +++ b/sound/pci/oxygen/xonar.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef XONAR_H_INCLUDED #define XONAR_H_INCLUDED diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h index d461df357aa1..7a1e8f9c48e7 100644 --- a/sound/pci/oxygen/xonar_dg.h +++ b/sound/pci/oxygen/xonar_dg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef XONAR_DG_H_INCLUDED #define XONAR_DG_H_INCLUDED diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index bb7eee9d0c2b..f9ae72f28ddc 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -986,7 +986,7 @@ static int pcxhr_hw_free(struct snd_pcm_substream *subs) /* * CONFIGURATION SPACE for all pcms, mono pcm must update channels_max */ -static struct snd_pcm_hardware pcxhr_caps = +static const struct snd_pcm_hardware pcxhr_caps = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | @@ -1165,7 +1165,7 @@ int pcxhr_create_pcm(struct snd_pcxhr *chip) struct snd_pcm *pcm; char name[32]; - sprintf(name, "pcxhr %d", chip->chip_idx); + snprintf(name, sizeof(name), "pcxhr %d", chip->chip_idx); if ((err = snd_pcm_new(chip->card, name, 0, chip->nb_streams_play, chip->nb_streams_capt, &pcm)) < 0) { @@ -1215,10 +1215,8 @@ static int pcxhr_create(struct pcxhr_mgr *mgr, }; chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (! chip) { - dev_err(card->dev, "cannot allocate chip\n"); + if (!chip) return -ENOMEM; - } chip->card = card; chip->chip_idx = idx; @@ -1252,7 +1250,7 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_pcxhr *chip = entry->private_data; struct pcxhr_mgr *mgr = chip->mgr; - snd_iprintf(buffer, "\n%s\n", mgr->longname); + snd_iprintf(buffer, "\n%s\n", mgr->name); /* stats available when embedded DSP is running */ if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { @@ -1339,7 +1337,7 @@ static void pcxhr_proc_sync(struct snd_info_entry *entry, max_clock = PCXHR_CLOCK_TYPE_MAX; } - snd_iprintf(buffer, "\n%s\n", mgr->longname); + snd_iprintf(buffer, "\n%s\n", mgr->name); snd_iprintf(buffer, "Current Sample Clock\t: %s\n", texts[mgr->cur_clock_type]); snd_iprintf(buffer, "Current Sample Rate\t= %d\n", @@ -1597,10 +1595,9 @@ static int pcxhr_probe(struct pci_dev *pci, } mgr->irq = pci->irq; - sprintf(mgr->shortname, "Digigram %s", card_name); - sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i", - mgr->shortname, - mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq); + snprintf(mgr->name, sizeof(mgr->name), + "Digigram at 0x%lx & 0x%lx, 0x%lx irq %i", + mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq); /* ISR lock */ mutex_init(&mgr->lock); @@ -1644,8 +1641,10 @@ static int pcxhr_probe(struct pci_dev *pci, } strcpy(card->driver, DRIVER_NAME); - sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i); - sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); + snprintf(card->shortname, sizeof(card->shortname), + "Digigram [PCM #%d]", i); + snprintf(card->longname, sizeof(card->longname), + "%s [PCM #%d]", mgr->name, i); if ((err = pcxhr_create(mgr, card, i)) < 0) { snd_card_free(card); diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index 9e39e509a3ef..d799cbd37301 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h @@ -75,8 +75,7 @@ struct pcxhr_mgr { unsigned long port[3]; /* share the name */ - char shortname[32]; /* short name of this soundcard */ - char longname[96]; /* name of this soundcard */ + char name[40]; /* name of this soundcard */ struct pcxhr_rmh *prmh; diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c index 36875df30dbf..d9a1c6c50a87 100644 --- a/sound/pci/pcxhr/pcxhr_mixer.c +++ b/sound/pci/pcxhr/pcxhr_mixer.c @@ -185,7 +185,7 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol, return changed; } -static struct snd_kcontrol_new pcxhr_control_analog_level = { +static const struct snd_kcontrol_new pcxhr_control_analog_level = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), @@ -409,7 +409,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol, return changed; } -static struct snd_kcontrol_new snd_pcxhr_pcm_vol = +static const struct snd_kcontrol_new snd_pcxhr_pcm_vol = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index f067c76d77f8..44f3b48d47b1 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -1315,7 +1315,7 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip) return 0; } -static struct snd_pcm_hardware snd_riptide_playback = { +static const struct snd_pcm_hardware snd_riptide_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), @@ -1334,7 +1334,7 @@ static struct snd_pcm_hardware snd_riptide_playback = { .periods_max = 64, .fifo_size = 0, }; -static struct snd_pcm_hardware snd_riptide_capture = { +static const struct snd_pcm_hardware snd_riptide_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID), diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index e4cdef94e4a2..f0906ba416d4 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -314,7 +314,7 @@ static int snd_rme32_capture_copy_kernel(struct snd_pcm_substream *substream, /* * SPDIF I/O capabilities (half-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_spdif_info = { +static const struct snd_pcm_hardware snd_rme32_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -340,7 +340,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_info = { /* * ADAT I/O capabilities (half-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_adat_info = +static const struct snd_pcm_hardware snd_rme32_adat_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -365,7 +365,7 @@ static struct snd_pcm_hardware snd_rme32_adat_info = /* * SPDIF I/O capabilities (full-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { +static const struct snd_pcm_hardware snd_rme32_spdif_fd_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -391,7 +391,7 @@ static struct snd_pcm_hardware snd_rme32_spdif_fd_info = { /* * ADAT I/O capabilities (full-duplex mode) */ -static struct snd_pcm_hardware snd_rme32_adat_fd_info = +static const struct snd_pcm_hardware snd_rme32_adat_fd_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 2e19ba55e754..dcfa4d7a73e2 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -384,7 +384,7 @@ snd_rme96_capture_copy_kernel(struct snd_pcm_substream *substream, /* * Digital output capabilities (S/PDIF) */ -static struct snd_pcm_hardware snd_rme96_playback_spdif_info = +static const struct snd_pcm_hardware snd_rme96_playback_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -415,7 +415,7 @@ static struct snd_pcm_hardware snd_rme96_playback_spdif_info = /* * Digital input capabilities (S/PDIF) */ -static struct snd_pcm_hardware snd_rme96_capture_spdif_info = +static const struct snd_pcm_hardware snd_rme96_capture_spdif_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -446,7 +446,7 @@ static struct snd_pcm_hardware snd_rme96_capture_spdif_info = /* * Digital output capabilities (ADAT) */ -static struct snd_pcm_hardware snd_rme96_playback_adat_info = +static const struct snd_pcm_hardware snd_rme96_playback_adat_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -473,7 +473,7 @@ static struct snd_pcm_hardware snd_rme96_playback_adat_info = /* * Digital input capabilities (ADAT) */ -static struct snd_pcm_hardware snd_rme96_capture_adat_info = +static const struct snd_pcm_hardware snd_rme96_capture_adat_info = { .info = (SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID | @@ -1199,7 +1199,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); spin_lock_irq(&rme96->lock); - if (rme96->playback_substream != NULL) { + if (rme96->playback_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1248,7 +1248,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream) } spin_lock_irq(&rme96->lock); - if (rme96->capture_substream != NULL) { + if (rme96->capture_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1268,7 +1268,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); spin_lock_irq(&rme96->lock); - if (rme96->playback_substream != NULL) { + if (rme96->playback_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1315,7 +1315,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream) } spin_lock_irq(&rme96->lock); - if (rme96->capture_substream != NULL) { + if (rme96->capture_substream) { spin_unlock_irq(&rme96->lock); return -EBUSY; } @@ -1578,9 +1578,9 @@ snd_rme96_free(void *private_data) { struct rme96 *rme96 = (struct rme96 *)private_data; - if (rme96 == NULL) { + if (!rme96) return; - } + if (rme96->irq >= 0) { snd_rme96_trigger(rme96, RME96_STOP_BOTH); rme96->areg &= ~RME96_AR_DAC_EN; @@ -2481,25 +2481,20 @@ snd_rme96_probe(struct pci_dev *pci, rme96 = card->private_data; rme96->card = card; rme96->pci = pci; - if ((err = snd_rme96_create(rme96)) < 0) { - snd_card_free(card); - return err; - } + err = snd_rme96_create(rme96); + if (err) + goto free_card; #ifdef CONFIG_PM_SLEEP rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); if (!rme96->playback_suspend_buffer) { - dev_err(card->dev, - "Failed to allocate playback suspend buffer!\n"); - snd_card_free(card); - return -ENOMEM; + err = -ENOMEM; + goto free_card; } rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); if (!rme96->capture_suspend_buffer) { - dev_err(card->dev, - "Failed to allocate capture suspend buffer!\n"); - snd_card_free(card); - return -ENOMEM; + err = -ENOMEM; + goto free_card; } #endif @@ -2525,14 +2520,16 @@ snd_rme96_probe(struct pci_dev *pci, } sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, rme96->port, rme96->irq); - - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err) + goto free_card; + pci_set_drvdata(pci, card); dev++; return 0; +free_card: + snd_card_free(card); + return err; } static void snd_rme96_remove(struct pci_dev *pci) diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile index dcba56040205..a3351447ddc0 100644 --- a/sound/pci/rme9652/Makefile +++ b/sound/pci/rme9652/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index fe36d44d16c6..9f0f73875f01 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -793,11 +793,8 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp_write(hdsp, HDSP_control2Reg, HDSP_S200 | HDSP_PROGRAM); hdsp_write (hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { - hdsp->io_type = Multiface; - dev_info(hdsp->card->dev, "Multiface found\n"); - return 0; - } + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) + goto set_multi; hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write(hdsp, HDSP_fifoData, 0); @@ -810,20 +807,14 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write(hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) { - hdsp->io_type = Multiface; - dev_info(hdsp->card->dev, "Multiface found\n"); - return 0; - } + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) == 0) + goto set_multi; hdsp_write(hdsp, HDSP_control2Reg, HDSP_S300); hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write(hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) { - hdsp->io_type = Multiface; - dev_info(hdsp->card->dev, "Multiface found\n"); - return 0; - } + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT) < 0) + goto set_multi; hdsp->io_type = RPM; dev_info(hdsp->card->dev, "RPM found\n"); @@ -838,6 +829,11 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp->io_type = Digiface; } return 0; + +set_multi: + hdsp->io_type = Multiface; + dev_info(hdsp->card->dev, "Multiface found\n"); + return 0; } @@ -4211,7 +4207,7 @@ static int snd_hdsp_prepare(struct snd_pcm_substream *substream) return result; } -static struct snd_pcm_hardware snd_hdsp_playback_subinfo = +static const struct snd_pcm_hardware snd_hdsp_playback_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -4241,7 +4237,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo = .fifo_size = 0 }; -static struct snd_pcm_hardware snd_hdsp_capture_subinfo = +static const struct snd_pcm_hardware snd_hdsp_capture_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -5381,17 +5377,16 @@ static int snd_hdsp_probe(struct pci_dev *pci, card->private_free = snd_hdsp_card_free; hdsp->dev = dev; hdsp->pci = pci; - - if ((err = snd_hdsp_create(card, hdsp)) < 0) { - snd_card_free(card); - return err; - } + err = snd_hdsp_create(card, hdsp); + if (err) + goto free_card; strcpy(card->shortname, "Hammerfall DSP"); sprintf(card->longname, "%s at 0x%lx, irq %d", hdsp->card_name, hdsp->port, hdsp->irq); - - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err) { +free_card: snd_card_free(card); return err; } diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 254c3d040118..f20d42714e4d 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -1521,7 +1521,7 @@ static void hdspm_silence_playback(struct hdspm *hdspm) int n = hdspm->period_bytes; void *buf = hdspm->playback_buffer; - if (buf == NULL) + if (!buf) return; for (i = 0; i < HDSPM_MAX_CHANNELS; i++) { @@ -2061,7 +2061,7 @@ static int snd_hdspm_create_midi(struct snd_card *card, struct hdspm *hdspm, int id) { int err; - char buf[32]; + char buf[64]; hdspm->midi[id].id = id; hdspm->midi[id].hdspm = hdspm; @@ -2120,19 +2120,23 @@ static int snd_hdspm_create_midi(struct snd_card *card, if ((id < 2) || ((2 == id) && ((MADI == hdspm->io_type) || (MADIface == hdspm->io_type)))) { if ((id == 0) && (MADIface == hdspm->io_type)) { - sprintf(buf, "%s MIDIoverMADI", card->shortname); + snprintf(buf, sizeof(buf), "%s MIDIoverMADI", + card->shortname); } else if ((id == 2) && (MADI == hdspm->io_type)) { - sprintf(buf, "%s MIDIoverMADI", card->shortname); + snprintf(buf, sizeof(buf), "%s MIDIoverMADI", + card->shortname); } else { - sprintf(buf, "%s MIDI %d", card->shortname, id+1); + snprintf(buf, sizeof(buf), "%s MIDI %d", + card->shortname, id+1); } err = snd_rawmidi_new(card, buf, id, 1, 1, &hdspm->midi[id].rmidi); if (err < 0) return err; - sprintf(hdspm->midi[id].rmidi->name, "%s MIDI %d", - card->id, id+1); + snprintf(hdspm->midi[id].rmidi->name, + sizeof(hdspm->midi[id].rmidi->name), + "%s MIDI %d", card->id, id+1); hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; snd_rawmidi_set_ops(hdspm->midi[id].rmidi, @@ -2148,14 +2152,16 @@ static int snd_hdspm_create_midi(struct snd_card *card, SNDRV_RAWMIDI_INFO_DUPLEX; } else { /* TCO MTC, read only */ - sprintf(buf, "%s MTC %d", card->shortname, id+1); + snprintf(buf, sizeof(buf), "%s MTC %d", + card->shortname, id+1); err = snd_rawmidi_new(card, buf, id, 1, 1, &hdspm->midi[id].rmidi); if (err < 0) return err; - sprintf(hdspm->midi[id].rmidi->name, - "%s MTC %d", card->id, id+1); + snprintf(hdspm->midi[id].rmidi->name, + sizeof(hdspm->midi[id].rmidi->name), + "%s MTC %d", card->id, id+1); hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; snd_rawmidi_set_ops(hdspm->midi[id].rmidi, @@ -4700,7 +4706,7 @@ static int snd_hdspm_create_controls(struct snd_card *card, break; } - if (NULL != list) { + if (list) { for (idx = 0; idx < limit; idx++) { err = snd_ctl_add(card, snd_ctl_new1(&list[idx], hdspm)); @@ -6063,13 +6069,13 @@ static int snd_hdspm_open(struct snd_pcm_substream *substream) snd_hdspm_capture_subinfo; if (playback) { - if (hdspm->capture_substream == NULL) + if (!hdspm->capture_substream) hdspm_stop_audio(hdspm); hdspm->playback_pid = current->pid; hdspm->playback_substream = substream; } else { - if (hdspm->playback_substream == NULL) + if (!hdspm->playback_substream) hdspm_stop_audio(hdspm); hdspm->capture_pid = current->pid; @@ -6215,7 +6221,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, } levels->status2 = hdspm_read(hdspm, HDSPM_statusRegister2); - s = copy_to_user(argp, levels, sizeof(struct hdspm_peak_rms)); + s = copy_to_user(argp, levels, sizeof(*levels)); if (0 != s) { /* dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu [Levels]\n", sizeof(struct hdspm_peak_rms), s); @@ -6260,7 +6266,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, ltc.input_format = no_video; } - s = copy_to_user(argp, <c, sizeof(struct hdspm_ltc)); + s = copy_to_user(argp, <c, sizeof(ltc)); if (0 != s) { /* dev_err(hdspm->card->dev, "copy_to_user(.., .., %lu): %lu [LTC]\n", sizeof(struct hdspm_ltc), s); */ @@ -6351,7 +6357,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, if (copy_from_user(&mixer, argp, sizeof(mixer))) return -EFAULT; if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, - sizeof(struct hdspm_mixer))) + sizeof(*mixer.mixer))) return -EFAULT; break; @@ -6630,14 +6636,10 @@ static int snd_hdspm_create(struct snd_card *card, hdspm->irq = pci->irq; dev_dbg(card->dev, "kmalloc Mixer memory of %zd Bytes\n", - sizeof(struct hdspm_mixer)); - hdspm->mixer = kzalloc(sizeof(struct hdspm_mixer), GFP_KERNEL); - if (!hdspm->mixer) { - dev_err(card->dev, - "unable to kmalloc Mixer memory of %d Bytes\n", - (int)sizeof(struct hdspm_mixer)); + sizeof(*hdspm->mixer)); + hdspm->mixer = kzalloc(sizeof(*hdspm->mixer), GFP_KERNEL); + if (!hdspm->mixer) return -ENOMEM; - } hdspm->port_names_in = NULL; hdspm->port_names_out = NULL; @@ -6772,11 +6774,10 @@ static int snd_hdspm_create(struct snd_card *card, if (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_tco_detect) { hdspm->midiPorts++; - hdspm->tco = kzalloc(sizeof(struct hdspm_tco), - GFP_KERNEL); - if (NULL != hdspm->tco) { + hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL); + if (hdspm->tco) hdspm_tco_write(hdspm); - } + dev_info(card->dev, "AIO/RayDAT TCO module found\n"); } else { hdspm->tco = NULL; @@ -6787,11 +6788,10 @@ static int snd_hdspm_create(struct snd_card *card, case AES32: if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) { hdspm->midiPorts++; - hdspm->tco = kzalloc(sizeof(struct hdspm_tco), - GFP_KERNEL); - if (NULL != hdspm->tco) { + hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL); + if (hdspm->tco) hdspm_tco_write(hdspm); - } + dev_info(card->dev, "MADI/AES TCO module found\n"); } else { hdspm->tco = NULL; @@ -6868,8 +6868,9 @@ static int snd_hdspm_create(struct snd_card *card, * this case, we don't set card->id to avoid collisions * when running with multiple cards. */ - if (NULL == id[hdspm->dev] && hdspm->serial != 0xFFFFFF) { - sprintf(card->id, "HDSPMx%06x", hdspm->serial); + if (!id[hdspm->dev] && hdspm->serial != 0xFFFFFF) { + snprintf(card->id, sizeof(card->id), + "HDSPMx%06x", hdspm->serial); snd_card_set_id(card, card->id); } } @@ -6938,7 +6939,7 @@ static int snd_hdspm_probe(struct pci_dev *pci, } err = snd_card_new(&pci->dev, index[dev], id[dev], - THIS_MODULE, sizeof(struct hdspm), &card); + THIS_MODULE, sizeof(*hdspm), &card); if (err < 0) return err; @@ -6948,35 +6949,36 @@ static int snd_hdspm_probe(struct pci_dev *pci, hdspm->pci = pci; err = snd_hdspm_create(card, hdspm); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; if (hdspm->io_type != MADIface) { - sprintf(card->shortname, "%s_%x", - hdspm->card_name, - hdspm->serial); - sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d", - hdspm->card_name, - hdspm->serial, - hdspm->port, hdspm->irq); + snprintf(card->shortname, sizeof(card->shortname), "%s_%x", + hdspm->card_name, hdspm->serial); + snprintf(card->longname, sizeof(card->longname), + "%s S/N 0x%x at 0x%lx, irq %d", + hdspm->card_name, hdspm->serial, + hdspm->port, hdspm->irq); } else { - sprintf(card->shortname, "%s", hdspm->card_name); - sprintf(card->longname, "%s at 0x%lx, irq %d", - hdspm->card_name, hdspm->port, hdspm->irq); + snprintf(card->shortname, sizeof(card->shortname), "%s", + hdspm->card_name); + snprintf(card->longname, sizeof(card->longname), + "%s at 0x%lx, irq %d", + hdspm->card_name, hdspm->port, hdspm->irq); } err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; pci_set_drvdata(pci, card); dev++; return 0; + +free_card: + snd_card_free(card); + return err; } static void snd_hdspm_remove(struct pci_dev *pci) diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 150d08898db8..df648b1d9217 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -2181,7 +2181,7 @@ static int snd_rme9652_prepare(struct snd_pcm_substream *substream) return result; } -static struct snd_pcm_hardware snd_rme9652_playback_subinfo = +static const struct snd_pcm_hardware snd_rme9652_playback_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -2205,7 +2205,7 @@ static struct snd_pcm_hardware snd_rme9652_playback_subinfo = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_rme9652_capture_subinfo = +static const struct snd_pcm_hardware snd_rme9652_capture_subinfo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -2618,19 +2618,17 @@ static int snd_rme9652_probe(struct pci_dev *pci, card->private_free = snd_rme9652_card_free; rme9652->dev = dev; rme9652->pci = pci; - - if ((err = snd_rme9652_create(card, rme9652, precise_ptr[dev])) < 0) { - snd_card_free(card); - return err; - } + err = snd_rme9652_create(card, rme9652, precise_ptr[dev]); + if (err) + goto free_card; strcpy(card->shortname, rme9652->card_name); sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, rme9652->port, rme9652->irq); - - - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err) { +free_card: snd_card_free(card); return err; } diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index f3860b850210..964acf302479 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -159,7 +159,7 @@ struct sis7019 { * We'll add a constraint upon open that limits the period and buffer sample * size to values that are legal for the hardware. */ -static struct snd_pcm_hardware sis_playback_hw_info = { +static const struct snd_pcm_hardware sis_playback_hw_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -180,7 +180,7 @@ static struct snd_pcm_hardware sis_playback_hw_info = { .periods_max = (0xfff9 / 9), }; -static struct snd_pcm_hardware sis_capture_hw_info = { +static const struct snd_pcm_hardware sis_capture_hw_info = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -872,7 +872,7 @@ static int sis_pcm_capture_prepare(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops sis_playback_ops = { +static const struct snd_pcm_ops sis_playback_ops = { .open = sis_playback_open, .close = sis_substream_close, .ioctl = snd_pcm_lib_ioctl, @@ -883,7 +883,7 @@ static struct snd_pcm_ops sis_playback_ops = { .pointer = sis_pcm_pointer, }; -static struct snd_pcm_ops sis_capture_ops = { +static const struct snd_pcm_ops sis_capture_ops = { .open = sis_capture_open, .close = sis_substream_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 784d762f18a7..a8abb15e3c3a 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -776,7 +776,7 @@ static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(struct snd_pcm_substream return bytes_to_frames(substream->runtime, ptr); } -static struct snd_pcm_hardware snd_sonicvibes_playback = +static const struct snd_pcm_hardware snd_sonicvibes_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -795,7 +795,7 @@ static struct snd_pcm_hardware snd_sonicvibes_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_sonicvibes_capture = +static const struct snd_pcm_hardware snd_sonicvibes_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 64d3b8eba4bb..eabd84d9ffee 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -1727,7 +1727,7 @@ static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *sub * Playback support device description */ -static struct snd_pcm_hardware snd_trident_playback = +static const struct snd_pcm_hardware snd_trident_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1752,7 +1752,7 @@ static struct snd_pcm_hardware snd_trident_playback = * Capture support device description */ -static struct snd_pcm_hardware snd_trident_capture = +static const struct snd_pcm_hardware snd_trident_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1777,7 +1777,7 @@ static struct snd_pcm_hardware snd_trident_capture = * Foldback capture support device description */ -static struct snd_pcm_hardware snd_trident_foldback = +static const struct snd_pcm_hardware snd_trident_foldback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1801,7 +1801,7 @@ static struct snd_pcm_hardware snd_trident_foldback = * SPDIF playback support device description */ -static struct snd_pcm_hardware snd_trident_spdif = +static const struct snd_pcm_hardware snd_trident_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1822,7 +1822,7 @@ static struct snd_pcm_hardware snd_trident_spdif = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_trident_spdif_7018 = +static const struct snd_pcm_hardware snd_trident_spdif_7018 = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -2093,7 +2093,7 @@ static const struct snd_pcm_ops snd_trident_nx_playback_ops = { .page = snd_pcm_sgbuf_ops_page, }; -static struct snd_pcm_ops snd_trident_capture_ops = { +static const struct snd_pcm_ops snd_trident_capture_ops = { .open = snd_trident_capture_open, .close = snd_trident_capture_close, .ioctl = snd_trident_ioctl, @@ -2104,7 +2104,7 @@ static struct snd_pcm_ops snd_trident_capture_ops = { .pointer = snd_trident_capture_pointer, }; -static struct snd_pcm_ops snd_trident_si7018_capture_ops = { +static const struct snd_pcm_ops snd_trident_si7018_capture_ops = { .open = snd_trident_capture_open, .close = snd_trident_capture_close, .ioctl = snd_trident_ioctl, @@ -3363,11 +3363,9 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident) trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4); /* allocate shadow TLB page table (virtual addresses) */ trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long)); - if (trident->tlb.shadow_entries == NULL) { - dev_err(trident->card->dev, - "unable to allocate shadow TLB entries\n"); + if (!trident->tlb.shadow_entries) return -ENOMEM; - } + /* allocate and setup silent page and initialise TLB entries */ if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(trident->pci), SNDRV_TRIDENT_PAGE_SIZE, &trident->tlb.silent_page) < 0) { diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index c767b8664359..3a1c0b8b4ea2 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -1150,7 +1150,7 @@ static int snd_via8233_capture_prepare(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for both playback and capture */ -static struct snd_pcm_hardware snd_via82xx_hw = +static const struct snd_pcm_hardware snd_via82xx_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 55f79b2599e7..8a69221c1b86 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -714,7 +714,7 @@ static int snd_via82xx_pcm_prepare(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for both playback and capture */ -static struct snd_pcm_hardware snd_via82xx_hw = +static const struct snd_pcm_hardware snd_via82xx_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 4faf3e1ed06a..eafdee384059 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -268,10 +268,9 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, if ((err = snd_ymfpci_create(card, pci, old_legacy_ctrl, &chip)) < 0) { - snd_card_free(card); release_and_free_resource(mpu_res); release_and_free_resource(fm_res); - return err; + goto free_card; } chip->fm_res = fm_res; chip->mpu_res = mpu_res; @@ -283,35 +282,31 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, card->shortname, chip->reg_area_phys, chip->irq); - if ((err = snd_ymfpci_pcm(chip, 0)) < 0) { - snd_card_free(card); - return err; - } - if ((err = snd_ymfpci_pcm_spdif(chip, 1)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ymfpci_pcm(chip, 0); + if (err < 0) + goto free_card; + + err = snd_ymfpci_pcm_spdif(chip, 1); + if (err < 0) + goto free_card; + err = snd_ymfpci_mixer(chip, rear_switch[dev]); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; + if (chip->ac97->ext_id & AC97_EI_SDAC) { err = snd_ymfpci_pcm_4ch(chip, 2); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto free_card; + err = snd_ymfpci_pcm2(chip, 3); - if (err < 0) { - snd_card_free(card); - return err; - } - } - if ((err = snd_ymfpci_timer(chip, 0)) < 0) { - snd_card_free(card); - return err; + if (err < 0) + goto free_card; } + err = snd_ymfpci_timer(chip, 0); + if (err < 0) + goto free_card; + if (chip->mpu_res) { if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, mpu_port[dev], @@ -336,21 +331,24 @@ static int snd_card_ymfpci_probe(struct pci_dev *pci, legacy_ctrl &= ~YMFPCI_LEGACY_FMEN; pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); } else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { - snd_card_free(card); dev_err(card->dev, "cannot create opl3 hwdep\n"); - return err; + goto free_card; } } snd_ymfpci_create_gameport(chip, dev, legacy_ctrl, legacy_ctrl2); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto free_card; + pci_set_drvdata(pci, card); dev++; return 0; + +free_card: + snd_card_free(card); + return err; } static void snd_card_ymfpci_remove(struct pci_dev *pci) diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 1114166c685c..8ca2e41e5827 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -845,7 +845,7 @@ static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static struct snd_pcm_hardware snd_ymfpci_playback = +static const struct snd_pcm_hardware snd_ymfpci_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -867,7 +867,7 @@ static struct snd_pcm_hardware snd_ymfpci_playback = .fifo_size = 0, }; -static struct snd_pcm_hardware snd_ymfpci_capture = +static const struct snd_pcm_hardware snd_ymfpci_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -2399,59 +2399,60 @@ int snd_ymfpci_create(struct snd_card *card, dev_err(chip->card->dev, "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); - snd_ymfpci_free(chip); - return -EBUSY; + err = -EBUSY; + goto free_chip; } if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq); - snd_ymfpci_free(chip); - return -EBUSY; + err = -EBUSY; + goto free_chip; } chip->irq = pci->irq; snd_ymfpci_aclink_reset(pci); if (snd_ymfpci_codec_ready(chip, 0) < 0) { - snd_ymfpci_free(chip); - return -EIO; + err = -EIO; + goto free_chip; } err = snd_ymfpci_request_firmware(chip); if (err < 0) { dev_err(chip->card->dev, "firmware request failed: %d\n", err); - snd_ymfpci_free(chip); - return err; + goto free_chip; } snd_ymfpci_download_image(chip); udelay(100); /* seems we need a delay after downloading image.. */ if (snd_ymfpci_memalloc(chip) < 0) { - snd_ymfpci_free(chip); - return -EIO; + err = -EIO; + goto free_chip; } - if ((err = snd_ymfpci_ac3_init(chip)) < 0) { - snd_ymfpci_free(chip); - return err; - } + err = snd_ymfpci_ac3_init(chip); + if (err < 0) + goto free_chip; #ifdef CONFIG_PM_SLEEP chip->saved_regs = kmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32), GFP_KERNEL); if (chip->saved_regs == NULL) { - snd_ymfpci_free(chip); - return -ENOMEM; + err = -ENOMEM; + goto free_chip; } #endif - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_ymfpci_free(chip); - return err; - } + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); + if (err < 0) + goto free_chip; snd_ymfpci_proc_init(card, chip); *rchip = chip; return 0; + +free_chip: + snd_ymfpci_free(chip); + return err; } diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index b48aa0a78c19..4a2354b5ae00 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -193,7 +193,7 @@ static int pdacf_pcm_prepare(struct snd_pcm_substream *subs) * capture hw information */ -static struct snd_pcm_hardware pdacf_pcm_capture_hw = { +static const struct snd_pcm_hardware pdacf_pcm_capture_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID | @@ -266,7 +266,7 @@ static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *sub /* * operators for PCM capture */ -static struct snd_pcm_ops pdacf_pcm_capture_ops = { +static const struct snd_pcm_ops pdacf_pcm_capture_ops = { .open = pdacf_pcm_capture_open, .close = pdacf_pcm_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index a5843fc5ff20..48dd44f8e914 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -509,7 +509,7 @@ static void snd_pmac_pcm_update(struct snd_pmac *chip, struct pmac_stream *rec) * hw info */ -static struct snd_pcm_hardware snd_pmac_playback = +static const struct snd_pcm_hardware snd_pmac_playback = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | @@ -528,7 +528,7 @@ static struct snd_pcm_hardware snd_pmac_playback = .periods_max = PMAC_MAX_FRAGS, }; -static struct snd_pcm_hardware snd_pmac_capture = +static const struct snd_pcm_hardware snd_pmac_capture = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | @@ -681,7 +681,7 @@ static int snd_pmac_capture_close(struct snd_pcm_substream *subs) /* */ -static struct snd_pcm_ops snd_pmac_playback_ops = { +static const struct snd_pcm_ops snd_pmac_playback_ops = { .open = snd_pmac_playback_open, .close = snd_pmac_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -692,7 +692,7 @@ static struct snd_pcm_ops snd_pmac_playback_ops = { .pointer = snd_pmac_playback_pointer, }; -static struct snd_pcm_ops snd_pmac_capture_ops = { +static const struct snd_pcm_ops snd_pmac_capture_ops = { .open = snd_pmac_capture_open, .close = snd_pmac_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index cdd44abfc9e0..36f34f434ecb 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -772,7 +772,7 @@ static struct snd_kcontrol_new spdif_ctls[] = { }, }; -static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = { +static const struct snd_pcm_ops snd_ps3_pcm_spdif_ops = { .open = snd_ps3_pcm_open, .close = snd_ps3_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/ppc/tumbler_volume.h b/sound/ppc/tumbler_volume.h index ef8d85d58b02..549ec6a31a98 100644 --- a/sound/ppc/tumbler_volume.h +++ b/sound/ppc/tumbler_volume.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* volume tables, taken from TAS3001c data manual */ /* volume gain values */ /* 0 = -70 dB, 175 = 18.0 dB in 0.5 dB step */ diff --git a/sound/sh/aica.c b/sound/sh/aica.c index ab4802df62e1..fdc680ae8aa0 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -211,7 +211,7 @@ static void aica_chn_halt(void) } /* ALSA code below */ -static struct snd_pcm_hardware snd_pcm_aica_playback_hw = { +static const struct snd_pcm_hardware snd_pcm_aica_playback_hw = { .info = (SNDRV_PCM_INFO_NONINTERLEAVED), .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | @@ -436,7 +436,7 @@ static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER); } -static struct snd_pcm_ops snd_aicapcm_playback_ops = { +static const struct snd_pcm_ops snd_aicapcm_playback_ops = { .open = snd_aicapcm_pcm_open, .close = snd_aicapcm_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index c1e00ed715ee..834b2574786f 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -93,7 +93,7 @@ static void dac_audio_set_rate(struct snd_sh_dac *chip) /* PCM INTERFACE */ -static struct snd_pcm_hardware snd_sh_dac_pcm_hw = { +static const struct snd_pcm_hardware snd_sh_dac_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -252,7 +252,7 @@ snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream) } /* pcm ops */ -static struct snd_pcm_ops snd_sh_dac_pcm_ops = { +static const struct snd_pcm_ops snd_sh_dac_pcm_ops = { .open = snd_sh_dac_pcm_open, .close = snd_sh_dac_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -424,7 +424,7 @@ static int snd_sh_dac_probe(struct platform_device *devptr) if (err < 0) goto probe_error; - snd_printk("ALSA driver for SuperH DAC audio"); + snd_printk(KERN_INFO "ALSA driver for SuperH DAC audio"); platform_set_drvdata(devptr, card); return 0; diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 39c27a58158d..bf8c1e2ce0bf 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index 330832ef4e5e..9d338216c5ae 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ACP_HW_H #define __ACP_HW_H diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index 67e10cbd4ed7..4440646416e8 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # AT91 Platform Support snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index b7ef8c59b49a..8445edd06737 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c @@ -32,7 +32,6 @@ struct atmel_classd { struct regmap *regmap; struct clk *pclk; struct clk *gclk; - struct clk *aclk; int irq; const struct atmel_classd_pdata *pdata; }; @@ -330,11 +329,6 @@ static int atmel_classd_codec_dai_startup(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); - int ret; - - ret = clk_prepare_enable(dd->aclk); - if (ret) - return ret; return clk_prepare_enable(dd->gclk); } @@ -357,31 +351,31 @@ static int atmel_classd_codec_dai_digital_mute(struct snd_soc_dai *codec_dai, return 0; } -#define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) -#define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) +#define CLASSD_GCLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) +#define CLASSD_GCLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) static struct { int rate; int sample_rate; int dsp_clk; - unsigned long aclk_rate; + unsigned long gclk_rate; } const sample_rates[] = { { 8000, CLASSD_INTPMR_FRAME_8K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 16000, CLASSD_INTPMR_FRAME_16K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 32000, CLASSD_INTPMR_FRAME_32K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 48000, CLASSD_INTPMR_FRAME_48K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 96000, CLASSD_INTPMR_FRAME_96K, - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, { 22050, CLASSD_INTPMR_FRAME_22K, - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, { 44100, CLASSD_INTPMR_FRAME_44K, - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, { 88200, CLASSD_INTPMR_FRAME_88K, - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, }; static int @@ -410,13 +404,12 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, } dev_dbg(codec->dev, - "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n", - sample_rates[best].rate, sample_rates[best].aclk_rate); + "Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n", + sample_rates[best].rate, sample_rates[best].gclk_rate); clk_disable_unprepare(dd->gclk); - clk_disable_unprepare(dd->aclk); - ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate); + ret = clk_set_rate(dd->gclk, sample_rates[best].gclk_rate); if (ret) return ret; @@ -426,10 +419,6 @@ atmel_classd_codec_dai_hw_params(struct snd_pcm_substream *substream, snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val); - ret = clk_prepare_enable(dd->aclk); - if (ret) - return ret; - return clk_prepare_enable(dd->gclk); } @@ -441,7 +430,6 @@ atmel_classd_codec_dai_shutdown(struct snd_pcm_substream *substream, struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); clk_disable_unprepare(dd->gclk); - clk_disable_unprepare(dd->aclk); } static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, @@ -596,13 +584,6 @@ static int atmel_classd_probe(struct platform_device *pdev) return ret; } - dd->aclk = devm_clk_get(dev, "aclk"); - if (IS_ERR(dd->aclk)) { - ret = PTR_ERR(dd->aclk); - dev_err(dev, "failed to get audio clock: %d\n", ret); - return ret; - } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); io_base = devm_ioremap_resource(dev, res); if (IS_ERR(io_base)) { @@ -652,7 +633,6 @@ static int atmel_classd_probe(struct platform_device *pdev) } snd_soc_card_set_drvdata(card, dd); - platform_set_drvdata(pdev, card); ret = atmel_classd_asoc_card_init(dev, card); if (ret) { diff --git a/sound/soc/atmel/atmel-classd.h b/sound/soc/atmel/atmel-classd.h index 73f8fdd1ca83..0f2e25aeb458 100644 --- a/sound/soc/atmel/atmel-classd.h +++ b/sound/soc/atmel/atmel-classd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ATMEL_CLASSD_H_ #define __ATMEL_CLASSD_H_ diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c index c917df7715d1..8e3d34be9e69 100644 --- a/sound/soc/atmel/atmel-pdmic.c +++ b/sound/soc/atmel/atmel-pdmic.c @@ -694,7 +694,6 @@ static int atmel_pdmic_probe(struct platform_device *pdev) } snd_soc_card_set_drvdata(card, dd); - platform_set_drvdata(pdev, card); ret = atmel_pdmic_asoc_card_init(dev, card); if (ret) { diff --git a/sound/soc/atmel/atmel-pdmic.h b/sound/soc/atmel/atmel-pdmic.h index 4527ac741919..1dd35187102c 100644 --- a/sound/soc/atmel/atmel-pdmic.h +++ b/sound/soc/atmel/atmel-pdmic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ATMEL_PDMIC_H_ #define __ATMEL_PDMIC_H_ diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile index 920710514ea0..33183d7fe057 100644 --- a/sound/soc/au1x/Makefile +++ b/sound/soc/au1x/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Au1200/Au1550 PSC audio snd-soc-au1xpsc-dbdma-objs := dbdma2.o snd-soc-au1xpsc-i2s-objs := psc-i2s.o diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index 5c73061d912a..301e1fc9a377 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -99,7 +99,7 @@ static int db1200_i2s_startup(struct snd_pcm_substream *substream) return 0; } -static struct snd_soc_ops db1200_i2s_wm8731_ops = { +static const struct snd_soc_ops db1200_i2s_wm8731_ops = { .startup = db1200_i2s_startup, }; diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index b5d1caa04d8e..6a035ca0f521 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -304,7 +304,7 @@ static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops au1xpsc_pcm_ops = { +static const struct snd_pcm_ops au1xpsc_pcm_ops = { .open = au1xpsc_pcm_open, .close = au1xpsc_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index fcf5a9adde81..19457e2b351e 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -277,7 +277,7 @@ static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss) return bytes_to_frames(ss->runtime, location); } -static struct snd_pcm_ops alchemy_pcm_ops = { +static const struct snd_pcm_ops alchemy_pcm_ops = { .open = alchemy_pcm_open, .close = alchemy_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index bb53c7059005..a2050ae5a3fe 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -474,7 +474,7 @@ static int au1xpsc_ac97_drvresume(struct device *dev) return 0; } -static struct dev_pm_ops au1xpscac97_pmops = { +static const struct dev_pm_ops au1xpscac97_pmops = { .suspend = au1xpsc_ac97_drvsuspend, .resume = au1xpsc_ac97_drvresume, }; diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 0bf9d62b91a0..e6eec081eaae 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -392,7 +392,7 @@ static int au1xpsc_i2s_drvresume(struct device *dev) return 0; } -static struct dev_pm_ops au1xpsci2s_pmops = { +static const struct dev_pm_ops au1xpsci2s_pmops = { .suspend = au1xpsc_i2s_drvsuspend, .resume = au1xpsc_i2s_drvresume, }; diff --git a/sound/soc/bcm/cygnus-ssp.c b/sound/soc/bcm/cygnus-ssp.c index e710bb0c5637..15c438f0f22d 100644 --- a/sound/soc/bcm/cygnus-ssp.c +++ b/sound/soc/bcm/cygnus-ssp.c @@ -27,12 +27,6 @@ #define DEFAULT_VCO 1354750204 -#define CYGNUS_TDM_RATE \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000) - #define CAPTURE_FCI_ID_BASE 0x180 #define CYGNUS_SSP_TRISTATE_MASK 0x001fff #define CYGNUS_PLLCLKSEL_MASK 0xf @@ -234,152 +228,20 @@ static const struct pll_macro_entry pll_predef_mclk[] = { {98304000, 2}, }; +#define CYGNUS_RATE_MIN 8000 +#define CYGNUS_RATE_MAX 384000 + /* List of valid frame sizes for tdm mode */ static const int ssp_valid_tdm_framesize[] = {32, 64, 128, 256, 512}; -/* - * Use this relationship to derive the sampling rate (lrclk) - * lrclk = (mclk) / ((2*mclk_to_sclk_ratio) * (32 * SCLK))). - * - * Use mclk and pll_ch from the table above - * - * Valid SCLK = 0/1/2/4/8/12 - * - * mclk_to_sclk_ratio = number of MCLK per SCLK. Division is twice the - * value programmed in this field. - * Valid mclk_to_sclk_ratio = 1 through to 15 - * - * eg: To set lrclk = 48khz, set mclk = 12288000, mclk_to_sclk_ratio = 2, - * SCLK = 64 - */ -struct _ssp_clk_coeff { - u32 mclk; - u32 sclk_rate; - u32 rate; - u32 mclk_rate; +static const unsigned int cygnus_rates[] = { + 8000, 11025, 16000, 22050, 32000, 44100, 48000, + 88200, 96000, 176400, 192000, 352800, 384000 }; -static const struct _ssp_clk_coeff ssp_clk_coeff[] = { - { 4096000, 32, 16000, 4}, - { 4096000, 32, 32000, 2}, - { 4096000, 64, 8000, 4}, - { 4096000, 64, 16000, 2}, - { 4096000, 64, 32000, 1}, - { 4096000, 128, 8000, 2}, - { 4096000, 128, 16000, 1}, - { 4096000, 256, 8000, 1}, - - { 6144000, 32, 16000, 6}, - { 6144000, 32, 32000, 3}, - { 6144000, 32, 48000, 2}, - { 6144000, 32, 96000, 1}, - { 6144000, 64, 8000, 6}, - { 6144000, 64, 16000, 3}, - { 6144000, 64, 48000, 1}, - { 6144000, 128, 8000, 3}, - - { 8192000, 32, 32000, 4}, - { 8192000, 64, 16000, 4}, - { 8192000, 64, 32000, 2}, - { 8192000, 128, 8000, 4}, - { 8192000, 128, 16000, 2}, - { 8192000, 128, 32000, 1}, - { 8192000, 256, 8000, 2}, - { 8192000, 256, 16000, 1}, - { 8192000, 512, 8000, 1}, - - {12288000, 32, 32000, 6}, - {12288000, 32, 48000, 4}, - {12288000, 32, 96000, 2}, - {12288000, 32, 192000, 1}, - {12288000, 64, 16000, 6}, - {12288000, 64, 32000, 3}, - {12288000, 64, 48000, 2}, - {12288000, 64, 96000, 1}, - {12288000, 128, 8000, 6}, - {12288000, 128, 16000, 3}, - {12288000, 128, 48000, 1}, - {12288000, 256, 8000, 3}, - - {16384000, 64, 32000, 4}, - {16384000, 128, 16000, 4}, - {16384000, 128, 32000, 2}, - {16384000, 256, 8000, 4}, - {16384000, 256, 16000, 2}, - {16384000, 256, 32000, 1}, - {16384000, 512, 8000, 2}, - {16384000, 512, 16000, 1}, - - {24576000, 32, 96000, 4}, - {24576000, 32, 192000, 2}, - {24576000, 64, 32000, 6}, - {24576000, 64, 48000, 4}, - {24576000, 64, 96000, 2}, - {24576000, 64, 192000, 1}, - {24576000, 128, 16000, 6}, - {24576000, 128, 32000, 3}, - {24576000, 128, 48000, 2}, - {24576000, 256, 8000, 6}, - {24576000, 256, 16000, 3}, - {24576000, 256, 48000, 1}, - {24576000, 512, 8000, 3}, - - {49152000, 32, 192000, 4}, - {49152000, 64, 96000, 4}, - {49152000, 64, 192000, 2}, - {49152000, 128, 32000, 6}, - {49152000, 128, 48000, 4}, - {49152000, 128, 96000, 2}, - {49152000, 128, 192000, 1}, - {49152000, 256, 16000, 6}, - {49152000, 256, 32000, 3}, - {49152000, 256, 48000, 2}, - {49152000, 256, 96000, 1}, - {49152000, 512, 8000, 6}, - {49152000, 512, 16000, 3}, - {49152000, 512, 48000, 1}, - - { 5644800, 32, 22050, 4}, - { 5644800, 32, 44100, 2}, - { 5644800, 32, 88200, 1}, - { 5644800, 64, 11025, 4}, - { 5644800, 64, 22050, 2}, - { 5644800, 64, 44100, 1}, - - {11289600, 32, 44100, 4}, - {11289600, 32, 88200, 2}, - {11289600, 32, 176400, 1}, - {11289600, 64, 22050, 4}, - {11289600, 64, 44100, 2}, - {11289600, 64, 88200, 1}, - {11289600, 128, 11025, 4}, - {11289600, 128, 22050, 2}, - {11289600, 128, 44100, 1}, - - {22579200, 32, 88200, 4}, - {22579200, 32, 176400, 2}, - {22579200, 64, 44100, 4}, - {22579200, 64, 88200, 2}, - {22579200, 64, 176400, 1}, - {22579200, 128, 22050, 4}, - {22579200, 128, 44100, 2}, - {22579200, 128, 88200, 1}, - {22579200, 256, 11025, 4}, - {22579200, 256, 22050, 2}, - {22579200, 256, 44100, 1}, - - {45158400, 32, 176400, 4}, - {45158400, 64, 88200, 4}, - {45158400, 64, 176400, 2}, - {45158400, 128, 44100, 4}, - {45158400, 128, 88200, 2}, - {45158400, 128, 176400, 1}, - {45158400, 256, 22050, 4}, - {45158400, 256, 44100, 2}, - {45158400, 256, 88200, 1}, - {45158400, 512, 11025, 4}, - {45158400, 512, 22050, 2}, - {45158400, 512, 44100, 1}, +static const struct snd_pcm_hw_constraint_list cygnus_rate_constraint = { + .count = ARRAY_SIZE(cygnus_rates), + .list = cygnus_rates, }; static struct cygnus_aio_port *cygnus_dai_get_portinfo(struct snd_soc_dai *dai) @@ -679,40 +541,55 @@ static int pll_configure_mclk(struct cygnus_audio *cygaud, u32 mclk, return p_entry->pll_ch_num; } -static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio, - struct cygnus_audio *cygaud) +static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio) { - u32 value, i = 0; + u32 value; u32 mask = 0xf; u32 sclk; - bool found = false; - const struct _ssp_clk_coeff *p_entry = NULL; + u32 mclk_rate; + unsigned int bit_rate; + unsigned int ratio; - for (i = 0; i < ARRAY_SIZE(ssp_clk_coeff); i++) { - p_entry = &ssp_clk_coeff[i]; - if ((p_entry->rate == aio->lrclk) && - (p_entry->sclk_rate == aio->bit_per_frame) && - (p_entry->mclk == aio->mclk)) { - found = true; - break; - } - } - if (!found) { + bit_rate = aio->bit_per_frame * aio->lrclk; + + /* + * Check if the bit clock can be generated from the given MCLK. + * MCLK must be a perfect multiple of bit clock and must be one of the + * following values... (2,4,6,8,10,12,14) + */ + if ((aio->mclk % bit_rate) != 0) + return -EINVAL; + + ratio = aio->mclk / bit_rate; + switch (ratio) { + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + mclk_rate = ratio / 2; + break; + + default: dev_err(aio->cygaud->dev, - "No valid match found in ssp_clk_coeff array\n"); + "Invalid combination of MCLK and BCLK\n"); dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n", aio->lrclk, aio->bit_per_frame, aio->mclk); return -EINVAL; } - sclk = aio->bit_per_frame; - if (sclk == 512) - sclk = 0; - /* sclks_per_1fs_div = sclk cycles/32 */ - sclk /= 32; /* Set sclk rate */ switch (aio->port_type) { case PORT_TDM: + sclk = aio->bit_per_frame; + if (sclk == 512) + sclk = 0; + + /* sclks_per_1fs_div = sclk cycles/32 */ + sclk /= 32; + /* Set number of bitclks per frame */ value = readl(aio->cygaud->audio + aio->regs.i2s_cfg); value &= ~(mask << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32); @@ -731,7 +608,7 @@ static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio, /* Set MCLK_RATE ssp port (spdif and ssp are the same) */ value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg); value &= ~(0xf << I2S_OUT_MCLKRATE_SHIFT); - value |= (p_entry->mclk_rate << I2S_OUT_MCLKRATE_SHIFT); + value |= (mclk_rate << I2S_OUT_MCLKRATE_SHIFT); writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg); dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value); @@ -745,7 +622,6 @@ static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai); - struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai); int rate, bitres; u32 value; u32 mask = 0x1f; @@ -841,7 +717,7 @@ static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream, aio->lrclk = rate; if (!aio->is_slave) - ret = cygnus_ssp_set_clocks(aio, cygaud); + ret = cygnus_ssp_set_clocks(aio); return ret; } @@ -888,6 +764,11 @@ static int cygnus_ssp_startup(struct snd_pcm_substream *substream, else aio->clk_trace.cap_en = true; + substream->runtime->hw.rate_min = CYGNUS_RATE_MIN; + substream->runtime->hw.rate_max = CYGNUS_RATE_MAX; + + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, &cygnus_rate_constraint); return 0; } @@ -1261,9 +1142,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = { .playback = { \ .channels_min = 1, \ .channels_max = 16, \ - .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \ - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \ - SNDRV_PCM_RATE_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ @@ -1271,9 +1150,7 @@ static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = { .capture = { \ .channels_min = 2, \ .channels_max = 16, \ - .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | \ - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \ - SNDRV_PCM_RATE_192000, \ + .rates = SNDRV_PCM_RATE_KNOT, \ .formats = SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S32_LE, \ }, \ @@ -1288,14 +1165,12 @@ static const struct snd_soc_dai_driver cygnus_ssp_dai_info[] = { INIT_CPU_DAI(2), }; -static struct snd_soc_dai_driver cygnus_spdif_dai_info = { +static const struct snd_soc_dai_driver cygnus_spdif_dai_info = { .name = "cygnus-spdif", .playback = { .channels_min = 2, .channels_max = 2, - .rates = CYGNUS_TDM_RATE | SNDRV_PCM_RATE_88200 | - SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | - SNDRV_PCM_RATE_192000, + .rates = SNDRV_PCM_RATE_KNOT, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, }, diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile index f21e948b2e9b..ebeb6a9cedd2 100644 --- a/sound/soc/blackfin/Makefile +++ b/sound/soc/blackfin/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Blackfin Platform Support snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 913e29275f4e..8c1d1983b8f9 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -308,7 +308,7 @@ static int bf5xx_pcm_copy_user(struct snd_pcm_substream *substream, } #endif -static struct snd_pcm_ops bf5xx_pcm_ac97_ops = { +static const struct snd_pcm_ops bf5xx_pcm_ac97_ops = { .open = bf5xx_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = bf5xx_pcm_hw_params, diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 470d99abf6f6..51cae76f14e6 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -318,7 +318,7 @@ static int bf5xx_pcm_silence(struct snd_pcm_substream *substream, return 0; } -static struct snd_pcm_ops bf5xx_pcm_i2s_ops = { +static const struct snd_pcm_ops bf5xx_pcm_i2s_ops = { .open = bf5xx_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = bf5xx_pcm_hw_params, diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c index bd3b4d464145..819cff149a25 100644 --- a/sound/soc/blackfin/bf6xx-i2s.c +++ b/sound/soc/blackfin/bf6xx-i2s.c @@ -164,7 +164,7 @@ static int bfin_i2s_resume(struct snd_soc_dai *dai) #define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops bfin_i2s_dai_ops = { +static const struct snd_soc_dai_ops bfin_i2s_dai_ops = { .hw_params = bfin_i2s_hw_params, .set_fmt = bfin_i2s_set_dai_fmt, }; diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c index dfb744381c42..d2caadfe7b6d 100644 --- a/sound/soc/blackfin/bf6xx-sport.c +++ b/sound/soc/blackfin/bf6xx-sport.c @@ -129,7 +129,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, for (i = 0; i < fragcount; ++i) { desc[i].next_desc_addr = &(desc[i + 1]); - desc[i].start_addr = (unsigned long)buf + i*fragsize; + desc[i].start_addr = (unsigned long)buf + i * fragsize; desc[i].cfg = cfg; desc[i].x_count = count; desc[i].x_modify = wdsize; @@ -138,7 +138,7 @@ static void setup_desc(struct dmasg *desc, void *buf, int fragcount, } /* make circular */ - desc[fragcount-1].next_desc_addr = desc; + desc[fragcount - 1].next_desc_addr = desc; } int sport_config_tx_dma(struct sport_device *sport, void *buf, @@ -148,7 +148,7 @@ int sport_config_tx_dma(struct sport_device *sport, void *buf, unsigned int cfg; dma_addr_t addr; - count = fragsize/sport->wdsize; + count = fragsize / sport->wdsize; if (sport->tx_desc) dma_free_coherent(NULL, sport->tx_desc_size, @@ -166,8 +166,7 @@ int sport_config_tx_dma(struct sport_device *sport, void *buf, cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6; setup_desc(sport->tx_desc, buf, fragcount, fragsize, - cfg|DMAEN, count, sport->wdsize); - + cfg | DMAEN, count, sport->wdsize); return 0; } EXPORT_SYMBOL(sport_config_tx_dma); @@ -179,7 +178,7 @@ int sport_config_rx_dma(struct sport_device *sport, void *buf, unsigned int cfg; dma_addr_t addr; - count = fragsize/sport->wdsize; + count = fragsize / sport->wdsize; if (sport->rx_desc) dma_free_coherent(NULL, sport->rx_desc_size, @@ -198,8 +197,7 @@ int sport_config_rx_dma(struct sport_device *sport, void *buf, | WNR | NDSIZE_6; setup_desc(sport->rx_desc, buf, fragcount, fragsize, - cfg|DMAEN, count, sport->wdsize); - + cfg | DMAEN, count, sport->wdsize); return 0; } EXPORT_SYMBOL(sport_config_rx_dma); @@ -226,7 +224,7 @@ static irqreturn_t sport_tx_irq(int irq, void *dev_id) static unsigned long status; status = get_dma_curr_irqstat(sport->tx_dma_chan); - if (status & (DMA_DONE|DMA_ERR)) { + if (status & (DMA_DONE | DMA_ERR)) { clear_dma_irqstat(sport->tx_dma_chan); SSYNC(); } @@ -241,7 +239,7 @@ static irqreturn_t sport_rx_irq(int irq, void *dev_id) unsigned long status; status = get_dma_curr_irqstat(sport->rx_dma_chan); - if (status & (DMA_DONE|DMA_ERR)) { + if (status & (DMA_DONE | DMA_ERR)) { clear_dma_irqstat(sport->rx_dma_chan); SSYNC(); } @@ -388,26 +386,24 @@ struct sport_device *sport_create(struct platform_device *pdev) int ret; sport = kzalloc(sizeof(*sport), GFP_KERNEL); - if (!sport) { - dev_err(dev, "Unable to allocate memory for sport device\n"); + if (!sport) return NULL; - } + sport->pdev = pdev; ret = sport_get_resource(sport); - if (ret) { - kfree(sport); - return NULL; - } + if (ret) + goto free_data; ret = sport_request_resource(sport); - if (ret) { - kfree(sport); - return NULL; - } + if (ret) + goto free_data; dev_dbg(dev, "SPORT create success\n"); return sport; +free_data: + kfree(sport); + return NULL; } EXPORT_SYMBOL(sport_create); diff --git a/sound/soc/cirrus/Makefile b/sound/soc/cirrus/Makefile index 5514146cbdf0..bfb8dc409f53 100644 --- a/sound/soc/cirrus/Makefile +++ b/sound/soc/cirrus/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # EP93xx Platform Support snd-soc-ep93xx-objs := ep93xx-pcm.o snd-soc-ep93xx-i2s-objs := ep93xx-i2s.o diff --git a/sound/soc/cirrus/edb93xx.c b/sound/soc/cirrus/edb93xx.c index 85962657aabe..c53bd6f2c2d7 100644 --- a/sound/soc/cirrus/edb93xx.c +++ b/sound/soc/cirrus/edb93xx.c @@ -56,7 +56,7 @@ static int edb93xx_hw_params(struct snd_pcm_substream *substream, SND_SOC_CLOCK_OUT); } -static struct snd_soc_ops edb93xx_ops = { +static const struct snd_soc_ops edb93xx_ops = { .hw_params = edb93xx_hw_params, }; diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c index 98089df08df6..2334ec19e7eb 100644 --- a/sound/soc/cirrus/snappercl15.c +++ b/sound/soc/cirrus/snappercl15.c @@ -45,7 +45,7 @@ static int snappercl15_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops snappercl15_ops = { +static const struct snd_soc_ops snappercl15_ops = { .hw_params = snappercl15_hw_params, }; diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index b013a4c62b63..848c5fe49bc7 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1355,7 +1355,7 @@ static struct regmap *pm860x_get_regmap(struct device *dev) return pm860x->regmap; } -static struct snd_soc_codec_driver soc_codec_dev_pm860x = { +static const struct snd_soc_codec_driver soc_codec_dev_pm860x = { .probe = pm860x_probe, .remove = pm860x_remove, .set_bias_level = pm860x_set_bias_level, diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6c78b0b49b81..c367d11079bc 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -60,6 +60,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_CS4271_I2C if I2C select SND_SOC_CS4271_SPI if SPI_MASTER select SND_SOC_CS42XX8_I2C if I2C + select SND_SOC_CS43130 if I2C select SND_SOC_CS4349 if I2C select SND_SOC_CS47L24 if MFD_CS47L24 select SND_SOC_CS53L30 if I2C @@ -71,7 +72,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_DA732X if I2C select SND_SOC_DA9055 if I2C select SND_SOC_DIO2125 - select SND_SOC_DMIC + select SND_SOC_DMIC if GPIOLIB select SND_SOC_ES8316 if I2C select SND_SOC_ES8328_SPI if SPI_MASTER select SND_SOC_ES8328_I2C if I2C @@ -114,6 +115,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_PCM5102A select SND_SOC_PCM512x_I2C if I2C select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RT274 if I2C select SND_SOC_RT286 if I2C select SND_SOC_RT298 if I2C select SND_SOC_RT5514 if I2C @@ -173,6 +175,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8400 if MFD_WM8400 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8523 if I2C + select SND_SOC_WM8524 if GPIOLIB select SND_SOC_WM8580 if I2C select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8727 @@ -486,6 +489,11 @@ config SND_SOC_CS42XX8_I2C select SND_SOC_CS42XX8 select REGMAP_I2C +# Cirrus Logic CS43130 HiFi DAC +config SND_SOC_CS43130 + tristate "Cirrus Logic CS43130 CODEC" + depends on I2C + # Cirrus Logic CS4349 HiFi DAC config SND_SOC_CS4349 tristate "Cirrus Logic CS4349 CODEC" @@ -716,11 +724,17 @@ config SND_SOC_RL6231 config SND_SOC_RL6347A tristate + default y if SND_SOC_RT274=y default y if SND_SOC_RT286=y default y if SND_SOC_RT298=y + default m if SND_SOC_RT274=m default m if SND_SOC_RT286=m default m if SND_SOC_RT298=m +config SND_SOC_RT274 + tristate + depends on I2C + config SND_SOC_RT286 tristate depends on I2C @@ -967,6 +981,10 @@ config SND_SOC_WM8523 tristate "Wolfson Microelectronics WM8523 DAC" depends on I2C +config SND_SOC_WM8524 + tristate "Wolfson Microelectronics WM8524 DAC" + depends on GPIOLIB + config SND_SOC_WM8580 tristate "Wolfson Microelectronics WM8580 and WM8581 CODECs" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 1755a54e3dc9..05018b7ca72b 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-88pm860x-objs := 88pm860x-codec.o snd-soc-ab8500-codec-objs := ab8500-codec.o snd-soc-ac97-objs := ac97.o @@ -53,6 +54,7 @@ snd-soc-cs4271-i2c-objs := cs4271-i2c.o snd-soc-cs4271-spi-objs := cs4271-spi.o snd-soc-cs42xx8-objs := cs42xx8.o snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o +snd-soc-cs43130-objs := cs43130.o snd-soc-cs4349-objs := cs4349.o snd-soc-cs47l24-objs := cs47l24.o snd-soc-cs53l30-objs := cs53l30.o @@ -113,6 +115,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o snd-soc-pcm512x-spi-objs := pcm512x-spi.o snd-soc-rl6231-objs := rl6231.o snd-soc-rl6347a-objs := rl6347a.o +snd-soc-rt274-objs := rt274.o snd-soc-rt286-objs := rt286.o snd-soc-rt298-objs := rt298.o snd-soc-rt5514-objs := rt5514.o @@ -182,6 +185,7 @@ snd-soc-wm8350-objs := wm8350.o snd-soc-wm8400-objs := wm8400.o snd-soc-wm8510-objs := wm8510.o snd-soc-wm8523-objs := wm8523.o +snd-soc-wm8524-objs := wm8524.o snd-soc-wm8580-objs := wm8580.o snd-soc-wm8711-objs := wm8711.o snd-soc-wm8727-objs := wm8727.o @@ -290,6 +294,7 @@ obj-$(CONFIG_SND_SOC_CS4271_I2C) += snd-soc-cs4271-i2c.o obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o +obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o @@ -320,6 +325,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_MAX98090) += snd-soc-max98090.o obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o +obj-$(CONFIG_SND_SOC_MAX98371) += snd-soc-max98371.o obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o @@ -349,6 +355,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o +obj-$(CONFIG_SND_SOC_RT274) += snd-soc-rt274.o obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o @@ -372,6 +379,7 @@ obj-$(CONFIG_SND_SOC_SIGMADSP_REGMAP) += snd-soc-sigmadsp-regmap.o obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o +obj-$(CONFIG_SND_SOC_SIRF_AUDIO_CODEC) += sirf-audio-codec.o obj-$(CONFIG_SND_SOC_SSM2518) += snd-soc-ssm2518.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o @@ -414,6 +422,7 @@ obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o +obj-$(CONFIG_SND_SOC_WM8524) += snd-soc-wm8524.o obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 312b2a11abb6..006627b8c3a8 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -2523,7 +2523,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) return status; } -static struct snd_soc_codec_driver ab8500_codec_driver = { +static const struct snd_soc_codec_driver ab8500_codec_driver = { .probe = ab8500_codec_probe, .component_driver = { .controls = ab8500_ctrls, diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index f7f04c6be01e..440b4ce54376 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -112,7 +112,7 @@ static int ac97_soc_resume(struct snd_soc_codec *codec) #define ac97_soc_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_ac97 = { +static const struct snd_soc_codec_driver soc_codec_dev_ac97 = { .probe = ac97_soc_probe, .suspend = ac97_soc_suspend, .resume = ac97_soc_resume, diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index a478239aadac..d0361caad09e 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -321,7 +321,7 @@ static int ad1836_remove(struct snd_soc_codec *codec) AD1836_ADC_SERFMT_MASK, 0); } -static struct snd_soc_codec_driver soc_codec_dev_ad1836 = { +static const struct snd_soc_codec_driver soc_codec_dev_ad1836 = { .probe = ad1836_probe, .remove = ad1836_remove, .suspend = ad1836_suspend, diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index d643557d89a7..d10988eec0c1 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -408,7 +408,7 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ad193x = { +static const struct snd_soc_codec_driver soc_codec_dev_ad193x = { .probe = ad193x_codec_probe, .component_driver = { .controls = ad193x_snd_controls, diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index b7c1b9f4bf5f..ce89bfb42094 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -295,7 +295,7 @@ static int ad1980_soc_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ad1980 = { +static const struct snd_soc_codec_driver soc_codec_dev_ad1980 = { .probe = ad1980_soc_probe, .remove = ad1980_soc_remove, diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index 3e358a49442d..d8d86a0fea60 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -54,7 +54,7 @@ static struct snd_soc_dai_driver ad73311_dai = { .formats = SNDRV_PCM_FMTBIT_S16_LE, }, }; -static struct snd_soc_codec_driver soc_codec_dev_ad73311 = { +static const struct snd_soc_codec_driver soc_codec_dev_ad73311 = { .component_driver = { .dapm_widgets = ad73311_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ad73311_dapm_widgets), diff --git a/sound/soc/codecs/adau-utils.h b/sound/soc/codecs/adau-utils.h index 939b5f37762f..bf5947b35390 100644 --- a/sound/soc/codecs/adau-utils.h +++ b/sound/soc/codecs/adau-utils.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SOUND_SOC_CODECS_ADAU_PLL_H #define SOUND_SOC_CODECS_ADAU_PLL_H diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 8fa9045571ff..a865945d776a 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -1458,7 +1458,7 @@ static const struct regmap_config adau1373_regmap_config = { .num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults), }; -static struct snd_soc_codec_driver adau1373_codec_driver = { +static const struct snd_soc_codec_driver adau1373_codec_driver = { .probe = adau1373_probe, .resume = adau1373_resume, .set_bias_level = adau1373_set_bias_level, diff --git a/sound/soc/codecs/adau1373.h b/sound/soc/codecs/adau1373.h index c6ab5530760c..56320d5e32d8 100644 --- a/sound/soc/codecs/adau1373.h +++ b/sound/soc/codecs/adau1373.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ADAU1373_H__ #define __ADAU1373_H__ diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 3bad1bc8c00a..805afac8146b 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -757,7 +757,7 @@ static int adau1701_resume(struct snd_soc_codec *codec) #define adau1701_suspend NULL #endif /* CONFIG_PM */ -static struct snd_soc_codec_driver adau1701_codec_drv = { +static const struct snd_soc_codec_driver adau1701_codec_drv = { .probe = adau1701_probe, .remove = adau1701_remove, .resume = adau1701_resume, diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c index 2c1bd2763864..6758f789b712 100644 --- a/sound/soc/codecs/adau17x1.c +++ b/sound/soc/codecs/adau17x1.c @@ -90,6 +90,27 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w, return 0; } +static int adau17x1_adc_fixup(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct adau *adau = snd_soc_codec_get_drvdata(codec); + + /* + * If we are capturing, toggle the ADOSR bit in Converter Control 0 to + * avoid losing SNR (workaround from ADI). This must be done after + * the ADC(s) have been enabled. According to the data sheet, it is + * normally illegal to set this bit when the sampling rate is 96 kHz, + * but according to ADI it is acceptable for this workaround. + */ + regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0, + ADAU17X1_CONVERTER0_ADOSR, ADAU17X1_CONVERTER0_ADOSR); + regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0, + ADAU17X1_CONVERTER0_ADOSR, 0); + + return 0; +} + static const char * const adau17x1_mono_stereo_text[] = { "Stereo", "Mono Left Channel (L+R)", @@ -121,7 +142,8 @@ static const struct snd_soc_dapm_widget adau17x1_dapm_widgets[] = { SND_SOC_DAPM_MUX("Right DAC Mode Mux", SND_SOC_NOPM, 0, 0, &adau17x1_dac_mode_mux), - SND_SOC_DAPM_ADC("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0), + SND_SOC_DAPM_ADC_E("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0, + adau17x1_adc_fixup, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_ADC("Right Decimator", NULL, ADAU17X1_ADC_CONTROL, 1, 0), SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0), SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0), diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h index bf04b7efee40..eaf8f933bab8 100644 --- a/sound/soc/codecs/adau17x1.h +++ b/sound/soc/codecs/adau17x1.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ADAU17X1_H__ #define __ADAU17X1_H__ @@ -129,5 +130,7 @@ bool adau17x1_has_dsp(struct adau *adau); #define ADAU17X1_CONVERTER0_CONVSR_MASK 0x7 +#define ADAU17X1_CONVERTER0_ADOSR BIT(3) + #endif diff --git a/sound/soc/codecs/adau1977.c b/sound/soc/codecs/adau1977.c index b319db6a69f8..e384f212beb2 100644 --- a/sound/soc/codecs/adau1977.c +++ b/sound/soc/codecs/adau1977.c @@ -388,8 +388,7 @@ static int adau1977_power_disable(struct adau1977 *adau1977) regcache_mark_dirty(adau1977->regmap); - if (adau1977->reset_gpio) - gpiod_set_value_cansleep(adau1977->reset_gpio, 0); + gpiod_set_value_cansleep(adau1977->reset_gpio, 0); regcache_cache_only(adau1977->regmap, true); @@ -420,8 +419,7 @@ static int adau1977_power_enable(struct adau1977 *adau1977) goto err_disable_avdd; } - if (adau1977->reset_gpio) - gpiod_set_value_cansleep(adau1977->reset_gpio, 1); + gpiod_set_value_cansleep(adau1977->reset_gpio, 1); regcache_cache_only(adau1977->regmap, false); @@ -867,7 +865,7 @@ static int adau1977_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver adau1977_codec_driver = { +static const struct snd_soc_codec_driver adau1977_codec_driver = { .probe = adau1977_codec_probe, .set_bias_level = adau1977_set_bias_level, .set_sysclk = adau1977_set_sysclk, diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 6e793ebb5883..da7ca81f47cf 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -825,7 +825,7 @@ static int adav80x_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver adav80x_codec_driver = { +static const struct snd_soc_codec_driver adav80x_codec_driver = { .probe = adav80x_probe, .resume = adav80x_resume, .set_bias_level = adav80x_set_bias_level, diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index 90c756d183b4..b7f0057c0239 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -58,7 +58,7 @@ static struct snd_soc_dai_driver ads117x_dai = { .formats = ADS117X_FORMATS,}, }; -static struct snd_soc_codec_driver soc_codec_dev_ads117x = { +static const struct snd_soc_codec_driver soc_codec_dev_ads117x = { .component_driver = { .dapm_widgets = ads117x_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ads117x_dapm_widgets), diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 1a9d233c94d0..dbb184118f2e 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -242,7 +242,7 @@ static int ak4104_soc_resume(struct snd_soc_codec *codec) #define ak4104_soc_resume NULL #endif /* CONFIG_PM */ -static struct snd_soc_codec_driver soc_codec_device_ak4104 = { +static const struct snd_soc_codec_driver soc_codec_device_ak4104 = { .probe = ak4104_probe, .remove = ak4104_remove, .suspend = ak4104_soc_suspend, diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 66cfffde9a12..e3c157dc88db 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -390,7 +390,7 @@ static const struct regmap_config ak4535_regmap = { .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults), }; -static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4535 = { .resume = ak4535_resume, .set_bias_level = ak4535_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/ak4554.c b/sound/soc/codecs/ak4554.c index b92c548b9d29..0bb4fe5c122a 100644 --- a/sound/soc/codecs/ak4554.c +++ b/sound/soc/codecs/ak4554.c @@ -64,7 +64,7 @@ static struct snd_soc_dai_driver ak4554_dai = { .symmetric_rates = 1, }; -static struct snd_soc_codec_driver soc_codec_dev_ak4554 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4554 = { .component_driver = { .dapm_widgets = ak4554_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(ak4554_dapm_widgets), diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 690edebf029e..b95bb8b52e51 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -522,7 +522,7 @@ static int ak4613_resume(struct snd_soc_codec *codec) return regcache_sync(regmap); } -static struct snd_soc_codec_driver soc_codec_dev_ak4613 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4613 = { .suspend = ak4613_suspend, .resume = ak4613_resume, .set_bias_level = ak4613_set_bias_level, diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index ebdaf56c1d61..60142ff32d4f 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -524,7 +524,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_ak4641 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4641 = { .component_driver = { .controls = ak4641_snd_controls, .num_controls = ARRAY_SIZE(ak4641_snd_controls), diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 66de8a2013a6..29530c567bd9 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -550,7 +550,7 @@ static int ak4642_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4642 = { .probe = ak4642_probe, .suspend = ak4642_suspend, .resume = ak4642_resume, diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 6088afaabf62..dcfdff56fc5a 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -610,7 +610,7 @@ static struct snd_soc_dai_driver ak4671_dai = { .ops = &ak4671_dai_ops, }; -static struct snd_soc_codec_driver soc_codec_dev_ak4671 = { +static const struct snd_soc_codec_driver soc_codec_dev_ak4671 = { .set_bias_level = ak4671_set_bias_level, .component_driver = { .controls = ak4671_snd_controls, diff --git a/sound/soc/codecs/ak5386.c b/sound/soc/codecs/ak5386.c index 0ef2df223336..d0e16c03815c 100644 --- a/sound/soc/codecs/ak5386.c +++ b/sound/soc/codecs/ak5386.c @@ -69,7 +69,7 @@ static int ak5386_soc_resume(struct snd_soc_codec *codec) #define ak5386_soc_resume NULL #endif /* CONFIG_PM */ -static struct snd_soc_codec_driver soc_codec_ak5386 = { +static const struct snd_soc_codec_driver soc_codec_ak5386 = { .probe = ak5386_soc_probe, .remove = ak5386_soc_remove, .suspend = ak5386_soc_suspend, diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index d2e3a3ef7499..1db965a93632 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -951,7 +951,7 @@ static int alc5623_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_device_alc5623 = { +static const struct snd_soc_codec_driver soc_codec_device_alc5623 = { .probe = alc5623_probe, .suspend = alc5623_suspend, .resume = alc5623_resume, diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index 0a734d910850..a1149f6a8450 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -710,7 +710,7 @@ const struct soc_enum arizona_anc_input_src[] = { ARRAY_SIZE(arizona_anc_input_src_text), arizona_anc_input_src_text), SOC_ENUM_SINGLE(ARIZONA_FCL_ADC_REFORMATTER_CONTROL, - ARIZONA_FCL_MIC_MODE_SEL, + ARIZONA_FCL_MIC_MODE_SEL_SHIFT, ARRAY_SIZE(arizona_anc_channel_src_text), arizona_anc_channel_src_text), SOC_ENUM_SINGLE(ARIZONA_ANC_SRC, @@ -718,7 +718,7 @@ const struct soc_enum arizona_anc_input_src[] = { ARRAY_SIZE(arizona_anc_input_src_text), arizona_anc_input_src_text), SOC_ENUM_SINGLE(ARIZONA_FCR_ADC_REFORMATTER_CONTROL, - ARIZONA_FCR_MIC_MODE_SEL, + ARIZONA_FCR_MIC_MODE_SEL_SHIFT, ARRAY_SIZE(arizona_anc_channel_src_text), arizona_anc_channel_src_text), }; diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c index 8014e697d540..806191addb44 100644 --- a/sound/soc/codecs/bt-sco.c +++ b/sound/soc/codecs/bt-sco.c @@ -62,7 +62,7 @@ static struct snd_soc_dai_driver bt_sco_dai[] = { } }; -static struct snd_soc_codec_driver soc_codec_dev_bt_sco = { +static const struct snd_soc_codec_driver soc_codec_dev_bt_sco = { .component_driver = { .dapm_widgets = bt_sco_widgets, .num_dapm_widgets = ARRAY_SIZE(bt_sco_widgets), diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 7a2d9a2ee427..6ed2cc374768 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -128,7 +128,7 @@ static struct regmap *cq93vc_get_regmap(struct device *dev) return davinci_vc->regmap; } -static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { +static const struct snd_soc_codec_driver soc_codec_dev_cq93vc = { .set_bias_level = cq93vc_set_bias_level, .get_regmap = cq93vc_get_regmap, .component_driver = { diff --git a/sound/soc/codecs/cs35l33.c b/sound/soc/codecs/cs35l33.c index 6df29fa30fb9..854cf8f27605 100644 --- a/sound/soc/codecs/cs35l33.c +++ b/sound/soc/codecs/cs35l33.c @@ -831,7 +831,7 @@ static int cs35l33_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_cs35l33 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs35l33 = { .probe = cs35l33_probe, .set_bias_level = cs35l33_set_bias_level, @@ -869,8 +869,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev) dev_dbg(dev, "%s\n", __func__); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); ret = regulator_bulk_enable(cs35l33->num_core_supplies, cs35l33->core_supplies); @@ -881,8 +880,7 @@ static int __maybe_unused cs35l33_runtime_resume(struct device *dev) regcache_cache_only(cs35l33->regmap, false); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); msleep(CS35L33_BOOT_DELAY); @@ -1191,8 +1189,7 @@ static int cs35l33_i2c_probe(struct i2c_client *i2c_client, return ret; } - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 1); msleep(CS35L33_BOOT_DELAY); regcache_cache_only(cs35l33->regmap, false); @@ -1262,8 +1259,7 @@ static int cs35l33_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); - if (cs35l33->reset_gpio) - gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l33->reset_gpio, 0); pm_runtime_disable(&client->dev); regulator_bulk_disable(cs35l33->num_core_supplies, diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 0a747c66cc6c..1e05026bedca 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c @@ -779,7 +779,7 @@ static int cs35l34_probe(struct snd_soc_codec *codec) } -static struct snd_soc_codec_driver soc_codec_dev_cs35l34 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs35l34 = { .probe = cs35l34_probe, .component_driver = { @@ -1138,8 +1138,7 @@ static int cs35l34_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); - if (cs35l34->reset_gpio) - gpiod_set_value_cansleep(cs35l34->reset_gpio, 0); + gpiod_set_value_cansleep(cs35l34->reset_gpio, 0); pm_runtime_disable(&client->dev); regulator_bulk_disable(cs35l34->num_core_supplies, diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index f1ee184ecab2..129978d1243e 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -1079,7 +1079,7 @@ static int cs35l35_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_cs35l35 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs35l35 = { .probe = cs35l35_codec_probe, .set_sysclk = cs35l35_codec_set_sysclk, .component_driver = { diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index d8824773dc29..49a80627af12 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -639,7 +639,7 @@ static int cs4271_codec_remove(struct snd_soc_codec *codec) return 0; }; -static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs4271 = { .probe = cs4271_codec_probe, .remove = cs4271_codec_remove, .suspend = cs4271_soc_suspend, diff --git a/sound/soc/codecs/cs4271.h b/sound/soc/codecs/cs4271.h index 9adad8eefdc9..290283a9149e 100644 --- a/sound/soc/codecs/cs4271.h +++ b/sound/soc/codecs/cs4271.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _CS4271_PRIV_H #define _CS4271_PRIV_H diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 55e4520cdcaf..a2324a0e72ee 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -911,7 +911,7 @@ static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute) SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops cs42l42_ops = { +static const struct snd_soc_dai_ops cs42l42_ops = { .hw_params = cs42l42_pcm_hw_params, .set_fmt = cs42l42_set_dai_fmt, .set_sysclk = cs42l42_set_sysclk, @@ -1898,8 +1898,7 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) snd_soc_unregister_codec(&i2c_client->dev); /* Hold down reset */ - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); return 0; } @@ -1913,8 +1912,7 @@ static int cs42l42_runtime_suspend(struct device *dev) regcache_mark_dirty(cs42l42->regmap); /* Hold down reset */ - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); /* remove power */ regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), @@ -1937,8 +1935,7 @@ static int cs42l42_runtime_resume(struct device *dev) return ret; } - if (cs42l42->reset_gpio) - gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); regcache_cache_only(cs42l42->regmap, false); regcache_sync(cs42l42->regmap); diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 96cfe38943cd..f8072f1897d4 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -504,7 +504,7 @@ static int cs42l51_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { +static const struct snd_soc_codec_driver soc_codec_device_cs42l51 = { .probe = cs42l51_codec_probe, .component_driver = { diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c new file mode 100644 index 000000000000..643e37fc218e --- /dev/null +++ b/sound/soc/codecs/cs43130.c @@ -0,0 +1,2694 @@ +/* + * cs43130.c -- CS43130 ALSA Soc Audio driver + * + * Copyright 2017 Cirrus Logic, Inc. + * + * Authors: Li Xu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cs43130.h" + +static const struct reg_default cs43130_reg_defaults[] = { + {CS43130_SYS_CLK_CTL_1, 0x06}, + {CS43130_SP_SRATE, 0x01}, + {CS43130_SP_BITSIZE, 0x05}, + {CS43130_PAD_INT_CFG, 0x03}, + {CS43130_PWDN_CTL, 0xFE}, + {CS43130_CRYSTAL_SET, 0x04}, + {CS43130_PLL_SET_1, 0x00}, + {CS43130_PLL_SET_2, 0x00}, + {CS43130_PLL_SET_3, 0x00}, + {CS43130_PLL_SET_4, 0x00}, + {CS43130_PLL_SET_5, 0x40}, + {CS43130_PLL_SET_6, 0x10}, + {CS43130_PLL_SET_7, 0x80}, + {CS43130_PLL_SET_8, 0x03}, + {CS43130_PLL_SET_9, 0x02}, + {CS43130_PLL_SET_10, 0x02}, + {CS43130_CLKOUT_CTL, 0x00}, + {CS43130_ASP_NUM_1, 0x01}, + {CS43130_ASP_NUM_2, 0x00}, + {CS43130_ASP_DEN_1, 0x08}, + {CS43130_ASP_DEN_2, 0x00}, + {CS43130_ASP_LRCK_HI_TIME_1, 0x1F}, + {CS43130_ASP_LRCK_HI_TIME_2, 0x00}, + {CS43130_ASP_LRCK_PERIOD_1, 0x3F}, + {CS43130_ASP_LRCK_PERIOD_2, 0x00}, + {CS43130_ASP_CLOCK_CONF, 0x0C}, + {CS43130_ASP_FRAME_CONF, 0x0A}, + {CS43130_XSP_NUM_1, 0x01}, + {CS43130_XSP_NUM_2, 0x00}, + {CS43130_XSP_DEN_1, 0x02}, + {CS43130_XSP_DEN_2, 0x00}, + {CS43130_XSP_LRCK_HI_TIME_1, 0x1F}, + {CS43130_XSP_LRCK_HI_TIME_2, 0x00}, + {CS43130_XSP_LRCK_PERIOD_1, 0x3F}, + {CS43130_XSP_LRCK_PERIOD_2, 0x00}, + {CS43130_XSP_CLOCK_CONF, 0x0C}, + {CS43130_XSP_FRAME_CONF, 0x0A}, + {CS43130_ASP_CH_1_LOC, 0x00}, + {CS43130_ASP_CH_2_LOC, 0x00}, + {CS43130_ASP_CH_1_SZ_EN, 0x06}, + {CS43130_ASP_CH_2_SZ_EN, 0x0E}, + {CS43130_XSP_CH_1_LOC, 0x00}, + {CS43130_XSP_CH_2_LOC, 0x00}, + {CS43130_XSP_CH_1_SZ_EN, 0x06}, + {CS43130_XSP_CH_2_SZ_EN, 0x0E}, + {CS43130_DSD_VOL_B, 0x78}, + {CS43130_DSD_VOL_A, 0x78}, + {CS43130_DSD_PATH_CTL_1, 0xA8}, + {CS43130_DSD_INT_CFG, 0x00}, + {CS43130_DSD_PATH_CTL_2, 0x02}, + {CS43130_DSD_PCM_MIX_CTL, 0x00}, + {CS43130_DSD_PATH_CTL_3, 0x40}, + {CS43130_HP_OUT_CTL_1, 0x30}, + {CS43130_PCM_FILT_OPT, 0x02}, + {CS43130_PCM_VOL_B, 0x78}, + {CS43130_PCM_VOL_A, 0x78}, + {CS43130_PCM_PATH_CTL_1, 0xA8}, + {CS43130_PCM_PATH_CTL_2, 0x00}, + {CS43130_CLASS_H_CTL, 0x1E}, + {CS43130_HP_DETECT, 0x04}, + {CS43130_HP_LOAD_1, 0x00}, + {CS43130_HP_MEAS_LOAD_1, 0x00}, + {CS43130_HP_MEAS_LOAD_2, 0x00}, + {CS43130_INT_MASK_1, 0xFF}, + {CS43130_INT_MASK_2, 0xFF}, + {CS43130_INT_MASK_3, 0xFF}, + {CS43130_INT_MASK_4, 0xFF}, + {CS43130_INT_MASK_5, 0xFF}, +}; + +static bool cs43130_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: + case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2: + case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2: + return true; + default: + return false; + } +} + +static bool cs43130_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1: + case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG: + case CS43130_PWDN_CTL: + case CS43130_CRYSTAL_SET: + case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5: + case CS43130_PLL_SET_6: + case CS43130_PLL_SET_7: + case CS43130_PLL_SET_8: + case CS43130_PLL_SET_9: + case CS43130_PLL_SET_10: + case CS43130_CLKOUT_CTL: + case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF: + case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF: + case CS43130_ASP_CH_1_LOC: + case CS43130_ASP_CH_2_LOC: + case CS43130_ASP_CH_1_SZ_EN: + case CS43130_ASP_CH_2_SZ_EN: + case CS43130_XSP_CH_1_LOC: + case CS43130_XSP_CH_2_LOC: + case CS43130_XSP_CH_1_SZ_EN: + case CS43130_XSP_CH_2_SZ_EN: + case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3: + case CS43130_HP_OUT_CTL_1: + case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2: + case CS43130_CLASS_H_CTL: + case CS43130_HP_DETECT: + case CS43130_HP_STATUS: + case CS43130_HP_LOAD_1: + case CS43130_HP_MEAS_LOAD_1: + case CS43130_HP_MEAS_LOAD_2: + case CS43130_HP_DC_STAT_1: + case CS43130_HP_DC_STAT_2: + case CS43130_HP_AC_STAT_1: + case CS43130_HP_AC_STAT_2: + case CS43130_HP_LOAD_STAT: + case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: + case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5: + return true; + default: + return false; + } +} + +static bool cs43130_precious_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5: + return true; + default: + return false; + } +} + +struct cs43130_pll_params { + unsigned int pll_in; + u8 sclk_prediv; + u8 pll_div_int; + u32 pll_div_frac; + u8 pll_mode; + u8 pll_divout; + unsigned int pll_out; + u8 pll_cal_ratio; +}; + +static const struct cs43130_pll_params pll_ratio_table[] = { + {9600000, 0x02, 0x49, 0x800000, 0x00, 0x08, 22579200, 151}, + {9600000, 0x02, 0x50, 0x000000, 0x00, 0x08, 24576000, 164}, + + {11289600, 0x02, 0X40, 0, 0x01, 0x08, 22579200, 128}, + {11289600, 0x02, 0x44, 0x06F700, 0x0, 0x08, 24576000, 139}, + + {12000000, 0x02, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120}, + {12000000, 0x02, 0x40, 0x000000, 0x00, 0x08, 24576000, 131}, + + {12288000, 0x02, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118}, + {12288000, 0x02, 0x40, 0x000000, 0x01, 0x08, 24576000, 128}, + + {13000000, 0x02, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111}, + {13000000, 0x02, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121}, + + {19200000, 0x03, 0x49, 0x800000, 0x00, 0x08, 22579200, 151}, + {19200000, 0x03, 0x50, 0x000000, 0x00, 0x08, 24576000, 164}, + + {22579200, 0, 0, 0, 0, 0, 22579200, 0}, + {22579200, 0x03, 0x44, 0x06F700, 0x00, 0x08, 24576000, 139}, + + {24000000, 0x03, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120}, + {24000000, 0x03, 0x40, 0x000000, 0x00, 0x08, 24576000, 131}, + + {24576000, 0x03, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118}, + {24576000, 0, 0, 0, 0, 0, 24576000, 0}, + + {26000000, 0x03, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111}, + {26000000, 0x03, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121}, +}; + +static const struct cs43130_pll_params *cs43130_get_pll_table( + unsigned int freq_in, unsigned int freq_out) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) { + if (pll_ratio_table[i].pll_in == freq_in && + pll_ratio_table[i].pll_out == freq_out) + return &pll_ratio_table[i]; + } + + return NULL; +} + +static int cs43130_pll_config(struct snd_soc_codec *codec) +{ + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + const struct cs43130_pll_params *pll_entry; + + dev_dbg(codec->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n", + cs43130->mclk, cs43130->mclk_int); + + pll_entry = cs43130_get_pll_table(cs43130->mclk, cs43130->mclk_int); + if (!pll_entry) + return -EINVAL; + + if (pll_entry->pll_cal_ratio == 0) { + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1, + CS43130_PLL_START_MASK, 0); + + cs43130->pll_bypass = true; + return 0; + } + + cs43130->pll_bypass = false; + + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_2, + CS43130_PLL_DIV_DATA_MASK, + pll_entry->pll_div_frac >> + CS43130_PLL_DIV_FRAC_0_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_3, + CS43130_PLL_DIV_DATA_MASK, + pll_entry->pll_div_frac >> + CS43130_PLL_DIV_FRAC_1_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_4, + CS43130_PLL_DIV_DATA_MASK, + pll_entry->pll_div_frac >> + CS43130_PLL_DIV_FRAC_2_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_PLL_SET_5, + pll_entry->pll_div_int); + regmap_write(cs43130->regmap, CS43130_PLL_SET_6, pll_entry->pll_divout); + regmap_write(cs43130->regmap, CS43130_PLL_SET_7, + pll_entry->pll_cal_ratio); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_8, + CS43130_PLL_MODE_MASK, + pll_entry->pll_mode << CS43130_PLL_MODE_SHIFT); + regmap_write(cs43130->regmap, CS43130_PLL_SET_9, + pll_entry->sclk_prediv); + regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1, + CS43130_PLL_START_MASK, 1); + + return 0; +} + +static int cs43130_set_pll(struct snd_soc_codec *codec, int pll_id, int source, + unsigned int freq_in, unsigned int freq_out) +{ + int ret = 0; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (freq_in) { + case 9600000: + case 11289600: + case 12000000: + case 12288000: + case 13000000: + case 19200000: + case 22579200: + case 24000000: + case 24576000: + case 26000000: + cs43130->mclk = freq_in; + break; + default: + dev_err(codec->dev, + "unsupported pll input reference clock:%d\n", freq_in); + return -EINVAL; + } + + switch (freq_out) { + case 22579200: + cs43130->mclk_int = freq_out; + break; + case 24576000: + cs43130->mclk_int = freq_out; + break; + default: + dev_err(codec->dev, + "unsupported pll output ref clock: %u\n", freq_out); + return -EINVAL; + } + + ret = cs43130_pll_config(codec); + dev_dbg(codec->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass); + return ret; +} + +static int cs43130_change_clksrc(struct snd_soc_codec *codec, + enum cs43130_mclk_src_sel src) +{ + int ret; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + int mclk_int_decoded; + + if (src == cs43130->mclk_int_src) { + /* clk source has not changed */ + return 0; + } + + switch (cs43130->mclk_int) { + case CS43130_MCLK_22M: + mclk_int_decoded = CS43130_MCLK_22P5; + break; + case CS43130_MCLK_24M: + mclk_int_decoded = CS43130_MCLK_24P5; + break; + default: + dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int); + return -EINVAL; + } + + switch (src) { + case CS43130_MCLK_SRC_EXT: + cs43130->pll_bypass = true; + cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT; + if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) { + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, + 1 << CS43130_PDN_XTAL_SHIFT); + } else { + reinit_completion(&cs43130->xtal_rdy); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, 0); + ret = wait_for_completion_timeout(&cs43130->xtal_rdy, + msecs_to_jiffies(100)); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, + 1 << CS43130_XTAL_RDY_INT_SHIFT); + if (ret == 0) { + dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n"); + return -ETIMEDOUT; + } + } + + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_SRC_SEL_MASK, + src << CS43130_MCLK_SRC_SEL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_INT_MASK, + mclk_int_decoded << CS43130_MCLK_INT_SHIFT); + usleep_range(150, 200); + + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_PLL_MASK, + 1 << CS43130_PDN_PLL_SHIFT); + break; + case CS43130_MCLK_SRC_PLL: + cs43130->pll_bypass = false; + cs43130->mclk_int_src = CS43130_MCLK_SRC_PLL; + if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) { + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, + 1 << CS43130_PDN_XTAL_SHIFT); + } else { + reinit_completion(&cs43130->xtal_rdy); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, 0); + ret = wait_for_completion_timeout(&cs43130->xtal_rdy, + msecs_to_jiffies(100)); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_RDY_INT_MASK, + 1 << CS43130_XTAL_RDY_INT_SHIFT); + if (ret == 0) { + dev_err(codec->dev, "Timeout waiting for XTAL_READY interrupt\n"); + return -ETIMEDOUT; + } + } + + reinit_completion(&cs43130->pll_rdy); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_PLL_RDY_INT_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_PLL_MASK, 0); + ret = wait_for_completion_timeout(&cs43130->pll_rdy, + msecs_to_jiffies(100)); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_PLL_RDY_INT_MASK, + 1 << CS43130_PLL_RDY_INT_SHIFT); + if (ret == 0) { + dev_err(codec->dev, "Timeout waiting for PLL_READY interrupt\n"); + return -ETIMEDOUT; + } + + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_SRC_SEL_MASK, + src << CS43130_MCLK_SRC_SEL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_INT_MASK, + mclk_int_decoded << CS43130_MCLK_INT_SHIFT); + usleep_range(150, 200); + break; + case CS43130_MCLK_SRC_RCO: + cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; + + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_SRC_SEL_MASK, + src << CS43130_MCLK_SRC_SEL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1, + CS43130_MCLK_INT_MASK, + CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT); + usleep_range(150, 200); + + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_XTAL_MASK, + 1 << CS43130_PDN_XTAL_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, + CS43130_PDN_PLL_MASK, + 1 << CS43130_PDN_PLL_SHIFT); + break; + default: + dev_err(codec->dev, "Invalid MCLK source value\n"); + return -EINVAL; + } + + return 0; +} + +static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = { + {8, CS43130_SP_BIT_SIZE_8, CS43130_CH_BIT_SIZE_8}, + {16, CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16}, + {24, CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24}, + {32, CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32}, +}; + +static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table( + unsigned int bitwidth) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) { + if (cs43130_bitwidth_table[i].bitwidth == bitwidth) + return &cs43130_bitwidth_table[i]; + } + + return NULL; +} + +static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai, + struct regmap *regmap) +{ + const struct cs43130_bitwidth_map *bw_map; + + bw_map = cs43130_get_bitwidth_table(bitwidth_dai); + if (!bw_map) + return -EINVAL; + + switch (dai_id) { + case CS43130_ASP_PCM_DAI: + case CS43130_ASP_DOP_DAI: + regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_SP_BITSIZE, + CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit); + break; + case CS43130_XSP_DOP_DAI: + regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN, + CS43130_CH_BITSIZE_MASK, bw_map->ch_bit); + regmap_update_bits(regmap, CS43130_SP_BITSIZE, + CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit << + CS43130_XSP_BITSIZE_SHIFT); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct cs43130_rate_map cs43130_rate_table[] = { + {32000, CS43130_ASP_SPRATE_32K}, + {44100, CS43130_ASP_SPRATE_44_1K}, + {48000, CS43130_ASP_SPRATE_48K}, + {88200, CS43130_ASP_SPRATE_88_2K}, + {96000, CS43130_ASP_SPRATE_96K}, + {176400, CS43130_ASP_SPRATE_176_4K}, + {192000, CS43130_ASP_SPRATE_192K}, + {352800, CS43130_ASP_SPRATE_352_8K}, + {384000, CS43130_ASP_SPRATE_384K}, +}; + +static const struct cs43130_rate_map *cs43130_get_rate_table(int fs) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) { + if (cs43130_rate_table[i].fs == fs) + return &cs43130_rate_table[i]; + } + + return NULL; +} + +static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs, + const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table) +{ + int i; + + for (i = 0; i < len_clk_gen_table; i++) { + if (clk_gen_table[i].mclk_int == mclk_int && + clk_gen_table[i].fs == fs) + return &clk_gen_table[i]; + } + + return NULL; +} + +static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk, + struct snd_pcm_hw_params *params, + struct cs43130_private *cs43130) +{ + u16 frm_size; + u16 hi_size; + u8 frm_delay; + u8 frm_phase; + u8 frm_data; + u8 sclk_edge; + u8 lrck_edge; + u8 clk_data; + u8 loc_ch1; + u8 loc_ch2; + u8 dai_mode_val; + const struct cs43130_clk_gen *clk_gen; + + switch (cs43130->dais[dai_id].dai_format) { + case SND_SOC_DAIFMT_I2S: + hi_size = bitwidth_sclk; + frm_delay = 2; + frm_phase = 0; + break; + case SND_SOC_DAIFMT_LEFT_J: + hi_size = bitwidth_sclk; + frm_delay = 2; + frm_phase = 1; + break; + case SND_SOC_DAIFMT_DSP_A: + hi_size = 1; + frm_delay = 2; + frm_phase = 1; + break; + case SND_SOC_DAIFMT_DSP_B: + hi_size = 1; + frm_delay = 0; + frm_phase = 1; + break; + default: + return -EINVAL; + } + + switch (cs43130->dais[dai_id].dai_mode) { + case SND_SOC_DAIFMT_CBS_CFS: + dai_mode_val = 0; + break; + case SND_SOC_DAIFMT_CBM_CFM: + dai_mode_val = 1; + break; + default: + return -EINVAL; + } + + frm_size = bitwidth_sclk * params_channels(params); + sclk_edge = 1; + lrck_edge = 0; + loc_ch1 = 0; + loc_ch2 = bitwidth_sclk * (params_channels(params) - 1); + + frm_data = frm_delay & CS43130_SP_FSD_MASK; + frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK; + + clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK; + clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) & + CS43130_SP_LCPOL_OUT_MASK; + clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) & + CS43130_SP_SCPOL_IN_MASK; + clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) & + CS43130_SP_SCPOL_OUT_MASK; + clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) & + CS43130_SP_MODE_MASK; + + switch (dai_id) { + case CS43130_ASP_PCM_DAI: + case CS43130_ASP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_MSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data); + regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1); + regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2); + regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data); + break; + case CS43130_XSP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2, + CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >> + CS43130_SP_LCPR_MSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_LSB_DATA_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2, + CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >> + CS43130_SP_LCHI_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data); + regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1); + regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2); + regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN, + CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data); + break; + default: + return -EINVAL; + } + + switch (frm_size) { + case 16: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_16_clk_gen, + ARRAY_SIZE(cs43130_16_clk_gen)); + break; + case 32: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_32_clk_gen, + ARRAY_SIZE(cs43130_32_clk_gen)); + break; + case 48: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_48_clk_gen, + ARRAY_SIZE(cs43130_48_clk_gen)); + break; + case 64: + clk_gen = cs43130_get_clk_gen(cs43130->mclk_int, + params_rate(params), + cs43130_64_clk_gen, + ARRAY_SIZE(cs43130_64_clk_gen)); + break; + default: + return -EINVAL; + } + + if (!clk_gen) + return -EINVAL; + + switch (dai_id) { + case CS43130_ASP_PCM_DAI: + case CS43130_ASP_DOP_DAI: + regmap_write(cs43130->regmap, CS43130_ASP_DEN_1, + (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> + CS43130_SP_M_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_DEN_2, + (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> + CS43130_SP_M_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_NUM_1, + (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> + CS43130_SP_N_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_ASP_NUM_2, + (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> + CS43130_SP_N_MSB_DATA_SHIFT); + break; + case CS43130_XSP_DOP_DAI: + regmap_write(cs43130->regmap, CS43130_XSP_DEN_1, + (clk_gen->den & CS43130_SP_M_LSB_DATA_MASK) >> + CS43130_SP_M_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_DEN_2, + (clk_gen->den & CS43130_SP_M_MSB_DATA_MASK) >> + CS43130_SP_M_MSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_NUM_1, + (clk_gen->num & CS43130_SP_N_LSB_DATA_MASK) >> + CS43130_SP_N_LSB_DATA_SHIFT); + regmap_write(cs43130->regmap, CS43130_XSP_NUM_2, + (clk_gen->num & CS43130_SP_N_MSB_DATA_MASK) >> + CS43130_SP_N_MSB_DATA_SHIFT); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int cs43130_pcm_dsd_mix(bool en, struct regmap *regmap) +{ + if (en) { + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_PREP_MASK, + 1 << CS43130_MIX_PCM_PREP_SHIFT); + usleep_range(6000, 6050); + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_DSD_MASK, + 1 << CS43130_MIX_PCM_DSD_SHIFT); + } else { + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_DSD_MASK, + 0 << CS43130_MIX_PCM_DSD_SHIFT); + usleep_range(1600, 1650); + regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL, + CS43130_MIX_PCM_PREP_MASK, + 0 << CS43130_MIX_PCM_PREP_SHIFT); + } + + return 0; +} + +static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + unsigned int required_clk; + u8 dsd_speed; + + mutex_lock(&cs43130->clk_mutex); + if (!cs43130->clk_req) { + /* no DAI is currently using clk */ + if (!(CS43130_MCLK_22M % params_rate(params))) + required_clk = CS43130_MCLK_22M; + else + required_clk = CS43130_MCLK_24M; + + cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk); + if (cs43130->pll_bypass) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT); + else + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL); + } + + cs43130->clk_req++; + if (cs43130->clk_req == 2) + cs43130_pcm_dsd_mix(true, cs43130->regmap); + mutex_unlock(&cs43130->clk_mutex); + + switch (params_rate(params)) { + case 176400: + dsd_speed = 0; + break; + case 352800: + dsd_speed = 1; + break; + default: + dev_err(codec->dev, "Rate(%u) not supported\n", + params_rate(params)); + return -EINVAL; + } + + if (cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM) + regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG, + CS43130_DSD_MASTER, CS43130_DSD_MASTER); + else + regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG, + CS43130_DSD_MASTER, 0); + + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SPEED_MASK, + dsd_speed << CS43130_DSD_SPEED_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_DSD << + CS43130_DSD_SRC_SHIFT); + + return 0; +} + +static int cs43130_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + const struct cs43130_rate_map *rate_map; + unsigned int sclk = cs43130->dais[dai->id].sclk; + unsigned int bitwidth_sclk; + unsigned int bitwidth_dai = (unsigned int)(params_width(params)); + unsigned int required_clk; + u8 dsd_speed; + + mutex_lock(&cs43130->clk_mutex); + if (!cs43130->clk_req) { + /* no DAI is currently using clk */ + if (!(CS43130_MCLK_22M % params_rate(params))) + required_clk = CS43130_MCLK_22M; + else + required_clk = CS43130_MCLK_24M; + + cs43130_set_pll(codec, 0, 0, cs43130->mclk, required_clk); + if (cs43130->pll_bypass) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT); + else + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL); + } + + cs43130->clk_req++; + if (cs43130->clk_req == 2) + cs43130_pcm_dsd_mix(true, cs43130->regmap); + mutex_unlock(&cs43130->clk_mutex); + + switch (dai->id) { + case CS43130_ASP_DOP_DAI: + case CS43130_XSP_DOP_DAI: + /* DoP bitwidth is always 24-bit */ + bitwidth_dai = 24; + sclk = params_rate(params) * bitwidth_dai * + params_channels(params); + + switch (params_rate(params)) { + case 176400: + dsd_speed = 0; + break; + case 352800: + dsd_speed = 1; + break; + default: + dev_err(codec->dev, "Rate(%u) not supported\n", + params_rate(params)); + return -EINVAL; + } + + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SPEED_MASK, + dsd_speed << CS43130_DSD_SPEED_SHIFT); + break; + case CS43130_ASP_PCM_DAI: + rate_map = cs43130_get_rate_table(params_rate(params)); + if (!rate_map) + return -EINVAL; + + regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val); + break; + default: + dev_err(codec->dev, "Invalid DAI (%d)\n", dai->id); + return -EINVAL; + } + + switch (dai->id) { + case CS43130_ASP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP << + CS43130_DSD_SRC_SHIFT); + break; + case CS43130_XSP_DOP_DAI: + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP << + CS43130_DSD_SRC_SHIFT); + } + + if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM) + /* Calculate SCLK in master mode if unassigned */ + sclk = params_rate(params) * bitwidth_dai * + params_channels(params); + + if (!sclk) { + /* at this point, SCLK must be set */ + dev_err(codec->dev, "SCLK freq is not set\n"); + return -EINVAL; + } + + bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params); + if (bitwidth_sclk < bitwidth_dai) { + dev_err(codec->dev, "Format not supported: SCLK freq is too low\n"); + return -EINVAL; + } + + dev_dbg(codec->dev, + "sclk = %u, fs = %d, bitwidth_dai = %u\n", + sclk, params_rate(params), bitwidth_dai); + + dev_dbg(codec->dev, + "bitwidth_sclk = %u, num_ch = %u\n", + bitwidth_sclk, params_channels(params)); + + cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap); + cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130); + + return 0; +} + +static int cs43130_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&cs43130->clk_mutex); + cs43130->clk_req--; + if (!cs43130->clk_req) { + /* no DAI is currently using clk */ + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO); + cs43130_pcm_dsd_mix(false, cs43130->regmap); + } + mutex_unlock(&cs43130->clk_mutex); + + return 0; +} + +static const DECLARE_TLV_DB_SCALE(pcm_vol_tlv, -12750, 50, 1); + +static const char * const pcm_ch_text[] = { + "Left-Right Ch", + "Left-Left Ch", + "Right-Left Ch", + "Right-Right Ch", +}; + +static const struct reg_sequence pcm_ch_en_seq[] = { + {CS43130_DXD1, 0x99}, + {0x180005, 0x8C}, + {0x180007, 0xAB}, + {0x180015, 0x31}, + {0x180017, 0xB2}, + {0x180025, 0x30}, + {0x180027, 0x84}, + {0x180035, 0x9C}, + {0x180037, 0xAE}, + {0x18000D, 0x24}, + {0x18000F, 0xA3}, + {0x18001D, 0x05}, + {0x18001F, 0xD4}, + {0x18002D, 0x0B}, + {0x18002F, 0xC7}, + {0x18003D, 0x71}, + {0x18003F, 0xE7}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence pcm_ch_dis_seq[] = { + {CS43130_DXD1, 0x99}, + {0x180005, 0x24}, + {0x180007, 0xA3}, + {0x180015, 0x05}, + {0x180017, 0xD4}, + {0x180025, 0x0B}, + {0x180027, 0xC7}, + {0x180035, 0x71}, + {0x180037, 0xE7}, + {0x18000D, 0x8C}, + {0x18000F, 0xAB}, + {0x18001D, 0x31}, + {0x18001F, 0xB2}, + {0x18002D, 0x30}, + {0x18002F, 0x84}, + {0x18003D, 0x9C}, + {0x18003F, 0xAE}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_pcm_ch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return snd_soc_get_enum_double(kcontrol, ucontrol); +} + +static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; + unsigned int *item = ucontrol->value.enumerated.item; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + + if (item[0] >= e->items) + return -EINVAL; + val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; + + switch (cs43130->dev_id) { + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + if (val >= 2) + regmap_multi_reg_write(cs43130->regmap, pcm_ch_en_seq, + ARRAY_SIZE(pcm_ch_en_seq)); + else + regmap_multi_reg_write(cs43130->regmap, pcm_ch_dis_seq, + ARRAY_SIZE(pcm_ch_dis_seq)); + } + + return snd_soc_put_enum_double(kcontrol, ucontrol); +} + +static SOC_ENUM_SINGLE_DECL(pcm_ch_enum, CS43130_PCM_PATH_CTL_2, 0, + pcm_ch_text); + +static const char * const pcm_spd_texts[] = { + "Fast", + "Slow", +}; + +static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7, + pcm_spd_texts); + +static const char * const dsd_texts[] = { + "Off", + "BCKA Mode", + "BCKD Mode", +}; + +static const unsigned int dsd_values[] = { + CS43130_DSD_SRC_DSD, + CS43130_DSD_SRC_ASP, + CS43130_DSD_SRC_XSP, +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(dsd_enum, CS43130_DSD_INT_CFG, 0, 0x03, + dsd_texts, dsd_values); + +static const struct snd_kcontrol_new cs43130_snd_controls[] = { + SOC_DOUBLE_R_TLV("Master Playback Volume", + CS43130_PCM_VOL_A, CS43130_PCM_VOL_B, 0, 0xFF, 1, + pcm_vol_tlv), + SOC_DOUBLE_R_TLV("Master DSD Playback Volume", + CS43130_DSD_VOL_A, CS43130_DSD_VOL_B, 0, 0xFF, 1, + pcm_vol_tlv), + SOC_ENUM_EXT("PCM Ch Select", pcm_ch_enum, cs43130_pcm_ch_get, + cs43130_pcm_ch_put), + SOC_ENUM("PCM Filter Speed", pcm_spd_enum), + SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0), + SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0), + SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0), + SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0), + SOC_ENUM("DSD Phase Modulation", dsd_enum), +}; + +static const struct reg_sequence pcm_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD7, 0x01}, + {CS43130_DXD8, 0}, + {CS43130_DXD9, 0x01}, + {CS43130_DXD3, 0x12}, + {CS43130_DXD4, 0}, + {CS43130_DXD10, 0x28}, + {CS43130_DXD11, 0x28}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence dsd_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD7, 0x01}, + {CS43130_DXD8, 0}, + {CS43130_DXD9, 0x01}, + {CS43130_DXD3, 0x12}, + {CS43130_DXD4, 0}, + {CS43130_DXD10, 0x1E}, + {CS43130_DXD11, 0x20}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence pop_free_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD12, 0x0A}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence pop_free_seq2[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD13, 0x20}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence mute_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD3, 0x12}, + {CS43130_DXD5, 0x02}, + {CS43130_DXD4, 0x12}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence unmute_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD3, 0x10}, + {CS43130_DXD5, 0}, + {CS43130_DXD4, 0x16}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_dsd_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, dsd_seq, + ARRAY_SIZE(dsd_seq)); + } + break; + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_1, + CS43130_MUTE_MASK, 0); + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, unmute_seq, + ARRAY_SIZE(unmute_seq)); + } + break; + case SND_SOC_DAPM_PRE_PMD: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, mute_seq, + ARRAY_SIZE(mute_seq)); + regmap_update_bits(cs43130->regmap, + CS43130_DSD_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + /* + * DSD Power Down Sequence + * According to Design, 130ms is preferred. + */ + msleep(130); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + regmap_update_bits(cs43130->regmap, + CS43130_DSD_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + } + break; + default: + dev_err(codec->dev, "Invalid event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static int cs43130_pcm_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, pcm_seq, + ARRAY_SIZE(pcm_seq)); + } + break; + case SND_SOC_DAPM_POST_PMU: + regmap_update_bits(cs43130->regmap, CS43130_PCM_PATH_CTL_1, + CS43130_MUTE_MASK, 0); + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, unmute_seq, + ARRAY_SIZE(unmute_seq)); + } + break; + case SND_SOC_DAPM_PRE_PMD: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, mute_seq, + ARRAY_SIZE(mute_seq)); + regmap_update_bits(cs43130->regmap, + CS43130_PCM_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + /* + * PCM Power Down Sequence + * According to Design, 130ms is preferred. + */ + msleep(130); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + regmap_update_bits(cs43130->regmap, + CS43130_PCM_PATH_CTL_1, + CS43130_MUTE_MASK, CS43130_MUTE_EN); + } + break; + default: + dev_err(codec->dev, "Invalid event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static const struct reg_sequence dac_postpmu_seq[] = { + {CS43130_DXD9, 0x0C}, + {CS43130_DXD3, 0x10}, + {CS43130_DXD4, 0x20}, +}; + +static const struct reg_sequence dac_postpmd_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD6, 0x01}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, pop_free_seq, + ARRAY_SIZE(pop_free_seq)); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, pop_free_seq2, + ARRAY_SIZE(pop_free_seq2)); + } + break; + case SND_SOC_DAPM_POST_PMU: + usleep_range(10000, 10050); + + regmap_write(cs43130->regmap, CS43130_DXD1, 0x99); + + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, dac_postpmu_seq, + ARRAY_SIZE(dac_postpmu_seq)); + /* + * Per datasheet, Sec. PCM Power-Up Sequence. + * According to Design, CS43130_DXD12 must be 0 to meet + * THDN and Dynamic Range spec. + */ + msleep(1000); + regmap_write(cs43130->regmap, CS43130_DXD12, 0); + break; + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + usleep_range(12000, 12010); + regmap_write(cs43130->regmap, CS43130_DXD13, 0); + } + + regmap_write(cs43130->regmap, CS43130_DXD1, 0); + break; + case SND_SOC_DAPM_POST_PMD: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + regmap_multi_reg_write(cs43130->regmap, dac_postpmd_seq, + ARRAY_SIZE(dac_postpmd_seq)); + } + break; + default: + dev_err(codec->dev, "Invalid DAC event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static const struct reg_sequence hpin_prepmd_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD15, 0x64}, + {CS43130_DXD14, 0}, + {CS43130_DXD2, 0}, + {CS43130_DXD1, 0}, +}; + +static const struct reg_sequence hpin_postpmu_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD2, 1}, + {CS43130_DXD14, 0xDC}, + {CS43130_DXD15, 0xE4}, + {CS43130_DXD1, 0}, +}; + +static int cs43130_hpin_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMD: + regmap_multi_reg_write(cs43130->regmap, hpin_prepmd_seq, + ARRAY_SIZE(hpin_prepmd_seq)); + break; + case SND_SOC_DAPM_PRE_PMU: + regmap_multi_reg_write(cs43130->regmap, hpin_postpmu_seq, + ARRAY_SIZE(hpin_postpmu_seq)); + break; + default: + dev_err(codec->dev, "Invalid HPIN event = 0x%x\n", event); + return -EINVAL; + } + return 0; +} + +static const struct snd_soc_dapm_widget digital_hp_widgets[] = { + SND_SOC_DAPM_OUTPUT("HPOUTA"), + SND_SOC_DAPM_OUTPUT("HPOUTB"), + + SND_SOC_DAPM_AIF_IN_E("ASPIN PCM", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_ASP_SHIFT, 1, cs43130_pcm_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_AIF_IN_E("ASPIN DoP", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_ASP_SHIFT, 1, cs43130_dsd_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_AIF_IN_E("XSPIN DoP", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_XSP_SHIFT, 1, cs43130_dsd_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_AIF_IN_E("XSPIN DSD", NULL, 0, CS43130_PWDN_CTL, + CS43130_PDN_DSDIF_SHIFT, 1, cs43130_dsd_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_PRE_PMD)), + + SND_SOC_DAPM_DAC("DSD", NULL, CS43130_DSD_PATH_CTL_2, + CS43130_DSD_EN_SHIFT, 0), + + SND_SOC_DAPM_DAC_E("HiFi DAC", NULL, CS43130_PWDN_CTL, + CS43130_PDN_HP_SHIFT, 1, cs43130_dac_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | + SND_SOC_DAPM_POST_PMD)), +}; + +static const struct snd_soc_dapm_widget analog_hp_widgets[] = { + SND_SOC_DAPM_DAC_E("Analog Playback", NULL, CS43130_HP_OUT_CTL_1, + CS43130_HP_IN_EN_SHIFT, 0, cs43130_hpin_event, + (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)), +}; + +static struct snd_soc_dapm_widget all_hp_widgets[ + ARRAY_SIZE(digital_hp_widgets) + + ARRAY_SIZE(analog_hp_widgets)]; + +static const struct snd_soc_dapm_route digital_hp_routes[] = { + {"ASPIN PCM", NULL, "ASP PCM Playback"}, + {"ASPIN DoP", NULL, "ASP DoP Playback"}, + {"XSPIN DoP", NULL, "XSP DoP Playback"}, + {"XSPIN DSD", NULL, "XSP DSD Playback"}, + {"DSD", NULL, "ASPIN DoP"}, + {"DSD", NULL, "XSPIN DoP"}, + {"DSD", NULL, "XSPIN DSD"}, + {"HiFi DAC", NULL, "ASPIN PCM"}, + {"HiFi DAC", NULL, "DSD"}, + {"HPOUTA", NULL, "HiFi DAC"}, + {"HPOUTB", NULL, "HiFi DAC"}, +}; + +static const struct snd_soc_dapm_route analog_hp_routes[] = { + {"HPOUTA", NULL, "Analog Playback"}, + {"HPOUTB", NULL, "Analog Playback"}, +}; + +static struct snd_soc_dapm_route all_hp_routes[ + ARRAY_SIZE(digital_hp_routes) + + ARRAY_SIZE(analog_hp_routes)]; + +static const unsigned int cs43130_asp_src_rates[] = { + 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000 +}; + +static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = { + .count = ARRAY_SIZE(cs43130_asp_src_rates), + .list = cs43130_asp_src_rates, +}; + +static int cs43130_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &cs43130_asp_constraints); +} + +static const unsigned int cs43130_dop_src_rates[] = { + 176400, 352800, +}; + +static const struct snd_pcm_hw_constraint_list cs43130_dop_constraints = { + .count = ARRAY_SIZE(cs43130_dop_src_rates), + .list = cs43130_dop_src_rates, +}; + +static int cs43130_dop_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &cs43130_dop_constraints); +} + +static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS; + break; + case SND_SOC_DAIFMT_CBM_CFM: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM; + break; + default: + dev_err(codec->dev, "unsupported mode\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S; + break; + case SND_SOC_DAIFMT_LEFT_J: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J; + break; + case SND_SOC_DAIFMT_DSP_A: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_A; + break; + case SND_SOC_DAIFMT_DSP_B: + cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_B; + break; + default: + dev_err(codec->dev, + "unsupported audio format\n"); + return -EINVAL; + } + + dev_dbg(codec->dev, "dai_id = %d, dai_mode = %u, dai_format = %u\n", + codec_dai->id, + cs43130->dais[codec_dai->id].dai_mode, + cs43130->dais[codec_dai->id].dai_format); + + return 0; +} + +static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS; + break; + case SND_SOC_DAIFMT_CBM_CFM: + cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM; + break; + default: + dev_err(codec->dev, "Unsupported DAI format.\n"); + return -EINVAL; + } + + dev_dbg(codec->dev, "dai_mode = 0x%x\n", + cs43130->dais[codec_dai->id].dai_mode); + + return 0; +} + +static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + cs43130->dais[codec_dai->id].sclk = freq; + dev_dbg(codec->dev, "dai_id = %d, sclk = %u\n", codec_dai->id, + cs43130->dais[codec_dai->id].sclk); + + return 0; +} + +static const struct snd_soc_dai_ops cs43130_pcm_ops = { + .startup = cs43130_pcm_startup, + .hw_params = cs43130_hw_params, + .hw_free = cs43130_hw_free, + .set_sysclk = cs43130_set_sysclk, + .set_fmt = cs43130_pcm_set_fmt, +}; + +static const struct snd_soc_dai_ops cs43130_dop_ops = { + .startup = cs43130_dop_startup, + .hw_params = cs43130_hw_params, + .hw_free = cs43130_hw_free, + .set_sysclk = cs43130_set_sysclk, + .set_fmt = cs43130_pcm_set_fmt, +}; + +static const struct snd_soc_dai_ops cs43130_dsd_ops = { + .startup = cs43130_dop_startup, + .hw_params = cs43130_dsd_hw_params, + .hw_free = cs43130_hw_free, + .set_fmt = cs43130_dsd_set_fmt, +}; + +static struct snd_soc_dai_driver cs43130_dai[] = { + { + .name = "cs43130-asp-pcm", + .id = CS43130_ASP_PCM_DAI, + .playback = { + .stream_name = "ASP PCM Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_PCM_FORMATS, + }, + .ops = &cs43130_pcm_ops, + .symmetric_rates = 1, + }, + { + .name = "cs43130-asp-dop", + .id = CS43130_ASP_DOP_DAI, + .playback = { + .stream_name = "ASP DoP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_DOP_FORMATS, + }, + .ops = &cs43130_dop_ops, + .symmetric_rates = 1, + }, + { + .name = "cs43130-xsp-dop", + .id = CS43130_XSP_DOP_DAI, + .playback = { + .stream_name = "XSP DoP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_DOP_FORMATS, + }, + .ops = &cs43130_dop_ops, + .symmetric_rates = 1, + }, + { + .name = "cs43130-xsp-dsd", + .id = CS43130_XSP_DSD_DAI, + .playback = { + .stream_name = "XSP DSD Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_KNOT, + .formats = CS43130_DOP_FORMATS, + }, + .ops = &cs43130_dsd_ops, + }, + +}; + +static int cs43130_codec_set_sysclk(struct snd_soc_codec *codec, + int clk_id, int source, unsigned int freq, + int dir) +{ + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n", + clk_id, source, freq, dir); + + switch (freq) { + case CS43130_MCLK_22M: + case CS43130_MCLK_24M: + cs43130->mclk = freq; + break; + default: + dev_err(codec->dev, "Invalid MCLK INT freq: %u\n", freq); + return -EINVAL; + } + + if (source == CS43130_MCLK_SRC_EXT) { + cs43130->pll_bypass = true; + } else { + dev_err(codec->dev, "Invalid MCLK source\n"); + return -EINVAL; + } + + return 0; +} + +static inline u16 cs43130_get_ac_reg_val(u16 ac_freq) +{ + /* AC freq is counted in 5.94Hz step. */ + return ac_freq / 6; +} + +static int cs43130_show_dc(struct device *dev, char *buf, u8 ch) +{ + struct i2c_client *client = to_i2c_client(dev); + struct cs43130_private *cs43130 = i2c_get_clientdata(client); + + if (!cs43130->hpload_done) + return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n"); + else + return scnprintf(buf, PAGE_SIZE, "%u\n", + cs43130->hpload_dc[ch]); +} + +static ssize_t cs43130_show_dc_l(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_dc(dev, buf, HP_LEFT); +} + +static ssize_t cs43130_show_dc_r(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_dc(dev, buf, HP_RIGHT); +} + +static u16 const cs43130_ac_freq[CS43130_AC_FREQ] = { + 24, + 43, + 93, + 200, + 431, + 928, + 2000, + 4309, + 9283, + 20000, +}; + +static int cs43130_show_ac(struct device *dev, char *buf, u8 ch) +{ + int i, j = 0, tmp; + struct i2c_client *client = to_i2c_client(dev); + struct cs43130_private *cs43130 = i2c_get_clientdata(client); + + if (cs43130->hpload_done && cs43130->ac_meas) { + for (i = 0; i < ARRAY_SIZE(cs43130_ac_freq); i++) { + tmp = scnprintf(buf + j, PAGE_SIZE - j, "%u\n", + cs43130->hpload_ac[i][ch]); + if (!tmp) + break; + + j += tmp; + } + + return j; + } else { + return scnprintf(buf, PAGE_SIZE, "NO_HPLOAD\n"); + } +} + +static ssize_t cs43130_show_ac_l(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_ac(dev, buf, HP_LEFT); +} + +static ssize_t cs43130_show_ac_r(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cs43130_show_ac(dev, buf, HP_RIGHT); +} + +static DEVICE_ATTR(hpload_dc_l, S_IRUGO, cs43130_show_dc_l, NULL); +static DEVICE_ATTR(hpload_dc_r, S_IRUGO, cs43130_show_dc_r, NULL); +static DEVICE_ATTR(hpload_ac_l, S_IRUGO, cs43130_show_ac_l, NULL); +static DEVICE_ATTR(hpload_ac_r, S_IRUGO, cs43130_show_ac_r, NULL); + +static struct reg_sequence hp_en_cal_seq[] = { + {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL}, + {CS43130_HP_MEAS_LOAD_1, 0}, + {CS43130_HP_MEAS_LOAD_2, 0}, + {CS43130_INT_MASK_4, 0}, + {CS43130_DXD1, 0x99}, + {CS43130_DXD16, 0xBB}, + {CS43130_DXD12, 0x01}, + {CS43130_DXD19, 0xCB}, + {CS43130_DXD17, 0x95}, + {CS43130_DXD18, 0x0B}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x80}, +}; + +static struct reg_sequence hp_en_cal_seq2[] = { + {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL}, + {CS43130_HP_MEAS_LOAD_1, 0}, + {CS43130_HP_MEAS_LOAD_2, 0}, + {CS43130_INT_MASK_4, 0}, + {CS43130_HP_LOAD_1, 0x80}, +}; + +static struct reg_sequence hp_dis_cal_seq[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_DXD1, 0x99}, + {CS43130_DXD12, 0}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0}, +}; + +static struct reg_sequence hp_dis_cal_seq2[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0}, +}; + +static struct reg_sequence hp_dc_ch_l_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x0A}, + {CS43130_DXD17, 0x93}, + {CS43130_DXD18, 0x0A}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x81}, +}; + +static struct reg_sequence hp_dc_ch_l_seq2[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x81}, +}; + +static struct reg_sequence hp_dc_ch_r_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x8A}, + {CS43130_DXD17, 0x15}, + {CS43130_DXD18, 0x06}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x91}, +}; + +static struct reg_sequence hp_dc_ch_r_seq2[] = { + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x91}, +}; + +static struct reg_sequence hp_ac_ch_l_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x0A}, + {CS43130_DXD17, 0x93}, + {CS43130_DXD18, 0x0A}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x82}, +}; + +static struct reg_sequence hp_ac_ch_l_seq2[] = { + {CS43130_HP_LOAD_1, 0x80}, + {CS43130_HP_LOAD_1, 0x82}, +}; + +static struct reg_sequence hp_ac_ch_r_seq[] = { + {CS43130_DXD1, 0x99}, + {CS43130_DXD19, 0x8A}, + {CS43130_DXD17, 0x15}, + {CS43130_DXD18, 0x06}, + {CS43130_DXD1, 0}, + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x92}, +}; + +static struct reg_sequence hp_ac_ch_r_seq2[] = { + {CS43130_HP_LOAD_1, 0x90}, + {CS43130_HP_LOAD_1, 0x92}, +}; + +static struct reg_sequence hp_cln_seq[] = { + {CS43130_INT_MASK_4, CS43130_INT_MASK_ALL}, + {CS43130_HP_MEAS_LOAD_1, 0}, + {CS43130_HP_MEAS_LOAD_2, 0}, +}; + +struct reg_sequences { + struct reg_sequence *seq; + int size; + unsigned int msk; +}; + +static struct reg_sequences hpload_seq1[] = { + { + .seq = hp_en_cal_seq, + .size = ARRAY_SIZE(hp_en_cal_seq), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_l_seq, + .size = ARRAY_SIZE(hp_dc_ch_l_seq), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_l_seq, + .size = ARRAY_SIZE(hp_ac_ch_l_seq), + .msk = CS43130_HPLOAD_AC_INT, + }, + { + .seq = hp_dis_cal_seq, + .size = ARRAY_SIZE(hp_dis_cal_seq), + .msk = CS43130_HPLOAD_OFF_INT, + }, + { + .seq = hp_en_cal_seq, + .size = ARRAY_SIZE(hp_en_cal_seq), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_r_seq, + .size = ARRAY_SIZE(hp_dc_ch_r_seq), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_r_seq, + .size = ARRAY_SIZE(hp_ac_ch_r_seq), + .msk = CS43130_HPLOAD_AC_INT, + }, +}; + +static struct reg_sequences hpload_seq2[] = { + { + .seq = hp_en_cal_seq2, + .size = ARRAY_SIZE(hp_en_cal_seq2), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_l_seq2, + .size = ARRAY_SIZE(hp_dc_ch_l_seq2), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_l_seq2, + .size = ARRAY_SIZE(hp_ac_ch_l_seq2), + .msk = CS43130_HPLOAD_AC_INT, + }, + { + .seq = hp_dis_cal_seq2, + .size = ARRAY_SIZE(hp_dis_cal_seq2), + .msk = CS43130_HPLOAD_OFF_INT, + }, + { + .seq = hp_en_cal_seq2, + .size = ARRAY_SIZE(hp_en_cal_seq2), + .msk = CS43130_HPLOAD_ON_INT, + }, + { + .seq = hp_dc_ch_r_seq2, + .size = ARRAY_SIZE(hp_dc_ch_r_seq2), + .msk = CS43130_HPLOAD_DC_INT, + }, + { + .seq = hp_ac_ch_r_seq2, + .size = ARRAY_SIZE(hp_ac_ch_r_seq2), + .msk = CS43130_HPLOAD_AC_INT, + }, +}; + +static int cs43130_update_hpload(unsigned int msk, int ac_idx, + struct cs43130_private *cs43130) +{ + bool left_ch = true; + unsigned int reg; + u32 addr; + u16 impedance; + struct snd_soc_codec *codec = cs43130->codec; + + switch (msk) { + case CS43130_HPLOAD_DC_INT: + case CS43130_HPLOAD_AC_INT: + break; + default: + return 0; + } + + regmap_read(cs43130->regmap, CS43130_HP_LOAD_1, ®); + if (reg & CS43130_HPLOAD_CHN_SEL) + left_ch = false; + + if (msk == CS43130_HPLOAD_DC_INT) + addr = CS43130_HP_DC_STAT_1; + else + addr = CS43130_HP_AC_STAT_1; + + regmap_read(cs43130->regmap, addr, ®); + impedance = reg >> 3; + regmap_read(cs43130->regmap, addr + 1, ®); + impedance |= reg << 5; + + if (msk == CS43130_HPLOAD_DC_INT) { + if (left_ch) + cs43130->hpload_dc[HP_LEFT] = impedance; + else + cs43130->hpload_dc[HP_RIGHT] = impedance; + + dev_dbg(codec->dev, "HP DC impedance (Ch %u): %u\n", !left_ch, + impedance); + } else { + if (left_ch) + cs43130->hpload_ac[ac_idx][HP_LEFT] = impedance; + else + cs43130->hpload_ac[ac_idx][HP_RIGHT] = impedance; + + dev_dbg(codec->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n", + cs43130->ac_freq[ac_idx], !left_ch, impedance); + } + + return 0; +} + +static int cs43130_hpload_proc(struct cs43130_private *cs43130, + struct reg_sequence *seq, int seq_size, + unsigned int rslt_msk, int ac_idx) +{ + int ret; + unsigned int msk; + u16 ac_reg_val; + struct snd_soc_codec *codec = cs43130->codec; + + reinit_completion(&cs43130->hpload_evt); + + if (rslt_msk == CS43130_HPLOAD_AC_INT) { + ac_reg_val = cs43130_get_ac_reg_val(cs43130->ac_freq[ac_idx]); + regmap_update_bits(cs43130->regmap, CS43130_HP_LOAD_1, + CS43130_HPLOAD_AC_START, 0); + regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_1, + CS43130_HP_MEAS_LOAD_MASK, + ac_reg_val >> CS43130_HP_MEAS_LOAD_1_SHIFT); + regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_2, + CS43130_HP_MEAS_LOAD_MASK, + ac_reg_val >> CS43130_HP_MEAS_LOAD_2_SHIFT); + } + + regmap_multi_reg_write(cs43130->regmap, seq, + seq_size); + + ret = wait_for_completion_timeout(&cs43130->hpload_evt, + msecs_to_jiffies(1000)); + regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk); + if (!ret) { + dev_err(codec->dev, "Timeout waiting for HPLOAD interrupt\n"); + return -1; + } + + dev_dbg(codec->dev, "HP load stat: %x, INT_MASK_4: %x\n", + cs43130->hpload_stat, msk); + if ((cs43130->hpload_stat & (CS43130_HPLOAD_NO_DC_INT | + CS43130_HPLOAD_UNPLUG_INT | + CS43130_HPLOAD_OOR_INT)) || + !(cs43130->hpload_stat & rslt_msk)) { + dev_dbg(codec->dev, "HP load measure failed\n"); + return -1; + } + + return 0; +} + +static const struct reg_sequence hv_seq[][2] = { + { + {CS43130_CLASS_H_CTL, 0x1C}, + {CS43130_HP_OUT_CTL_1, 0x10}, + }, + { + {CS43130_CLASS_H_CTL, 0x1E}, + {CS43130_HP_OUT_CTL_1, 0x20}, + }, + { + {CS43130_CLASS_H_CTL, 0x1E}, + {CS43130_HP_OUT_CTL_1, 0x30}, + }, +}; + +static int cs43130_set_hv(struct regmap *regmap, u16 hpload_dc, + const u16 *dc_threshold) +{ + int i; + + for (i = 0; i < CS43130_DC_THRESHOLD; i++) { + if (hpload_dc <= dc_threshold[i]) + break; + } + + regmap_multi_reg_write(regmap, hv_seq[i], ARRAY_SIZE(hv_seq[i])); + + return 0; +} + +static void cs43130_imp_meas(struct work_struct *wk) +{ + unsigned int reg, seq_size; + int i, ret, ac_idx; + struct cs43130_private *cs43130; + struct snd_soc_codec *codec; + struct reg_sequences *hpload_seq; + + cs43130 = container_of(wk, struct cs43130_private, work); + codec = cs43130->codec; + + if (!cs43130->mclk) + return; + + cs43130->hpload_done = false; + + mutex_lock(&cs43130->clk_mutex); + if (!cs43130->clk_req) { + /* clk not in use */ + cs43130_set_pll(codec, 0, 0, cs43130->mclk, CS43130_MCLK_22M); + if (cs43130->pll_bypass) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_EXT); + else + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_PLL); + } + + cs43130->clk_req++; + mutex_unlock(&cs43130->clk_mutex); + + regmap_read(cs43130->regmap, CS43130_INT_STATUS_4, ®); + + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + hpload_seq = hpload_seq1; + seq_size = ARRAY_SIZE(hpload_seq1); + break; + case CS43131_CHIP_ID: + hpload_seq = hpload_seq2; + seq_size = ARRAY_SIZE(hpload_seq2); + break; + default: + WARN(1, "Invalid dev_id for meas: %d", cs43130->dev_id); + return; + } + + i = 0; + ac_idx = 0; + while (i < seq_size) { + ret = cs43130_hpload_proc(cs43130, hpload_seq[i].seq, + hpload_seq[i].size, + hpload_seq[i].msk, ac_idx); + if (ret < 0) + goto exit; + + cs43130_update_hpload(hpload_seq[i].msk, ac_idx, cs43130); + + if (cs43130->ac_meas && + hpload_seq[i].msk == CS43130_HPLOAD_AC_INT && + ac_idx < CS43130_AC_FREQ - 1) { + ac_idx++; + } else { + ac_idx = 0; + i++; + } + } + cs43130->hpload_done = true; + + if (cs43130->hpload_dc[HP_LEFT] >= CS43130_LINEOUT_LOAD) + snd_soc_jack_report(&cs43130->jack, CS43130_JACK_LINEOUT, + CS43130_JACK_MASK); + else + snd_soc_jack_report(&cs43130->jack, CS43130_JACK_HEADPHONE, + CS43130_JACK_MASK); + + dev_dbg(codec->dev, "Set HP output control. DC threshold\n"); + for (i = 0; i < CS43130_DC_THRESHOLD; i++) + dev_dbg(codec->dev, "DC threshold[%d]: %u.\n", i, + cs43130->dc_threshold[i]); + + cs43130_set_hv(cs43130->regmap, cs43130->hpload_dc[HP_LEFT], + cs43130->dc_threshold); + +exit: + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + cs43130_hpload_proc(cs43130, hp_dis_cal_seq, + ARRAY_SIZE(hp_dis_cal_seq), + CS43130_HPLOAD_OFF_INT, ac_idx); + break; + case CS43131_CHIP_ID: + cs43130_hpload_proc(cs43130, hp_dis_cal_seq2, + ARRAY_SIZE(hp_dis_cal_seq2), + CS43130_HPLOAD_OFF_INT, ac_idx); + } + + regmap_multi_reg_write(cs43130->regmap, hp_cln_seq, + ARRAY_SIZE(hp_cln_seq)); + + mutex_lock(&cs43130->clk_mutex); + cs43130->clk_req--; + /* clk not in use */ + if (!cs43130->clk_req) + cs43130_change_clksrc(codec, CS43130_MCLK_SRC_RCO); + mutex_unlock(&cs43130->clk_mutex); +} + +static irqreturn_t cs43130_irq_thread(int irq, void *data) +{ + struct cs43130_private *cs43130 = (struct cs43130_private *)data; + struct snd_soc_codec *codec = cs43130->codec; + unsigned int stickies[CS43130_NUM_INT]; + unsigned int irq_occurrence = 0; + unsigned int masks[CS43130_NUM_INT]; + int i, j; + + for (i = 0; i < ARRAY_SIZE(stickies); i++) { + regmap_read(cs43130->regmap, CS43130_INT_STATUS_1 + i, + &stickies[i]); + regmap_read(cs43130->regmap, CS43130_INT_MASK_1 + i, + &masks[i]); + } + + for (i = 0; i < ARRAY_SIZE(stickies); i++) { + stickies[i] = stickies[i] & (~masks[i]); + for (j = 0; j < 8; j++) + irq_occurrence += (stickies[i] >> j) & 1; + } + dev_dbg(codec->dev, "number of interrupts occurred (%u)\n", + irq_occurrence); + + if (!irq_occurrence) + return IRQ_NONE; + + if (stickies[0] & CS43130_XTAL_RDY_INT) { + complete(&cs43130->xtal_rdy); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_PLL_RDY_INT) { + complete(&cs43130->pll_rdy); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_NO_DC_INT) { + cs43130->hpload_stat = stickies[3]; + dev_err(codec->dev, + "DC load has not completed before AC load (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_UNPLUG_INT) { + cs43130->hpload_stat = stickies[3]; + dev_err(codec->dev, "HP unplugged during measurement (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_OOR_INT) { + cs43130->hpload_stat = stickies[3]; + dev_err(codec->dev, "HP load out of range (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_AC_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP AC load measurement done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_DC_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP DC load measurement done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_ON_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP load state machine on done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[3] & CS43130_HPLOAD_OFF_INT) { + cs43130->hpload_stat = stickies[3]; + dev_dbg(codec->dev, "HP load state machine off done (%x)\n", + cs43130->hpload_stat); + complete(&cs43130->hpload_evt); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_XTAL_ERR_INT) { + dev_err(codec->dev, "Crystal err: clock is not running\n"); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_HP_UNPLUG_INT) { + dev_dbg(codec->dev, "HP unplugged\n"); + cs43130->hpload_done = false; + snd_soc_jack_report(&cs43130->jack, 0, CS43130_JACK_MASK); + return IRQ_HANDLED; + } + + if (stickies[0] & CS43130_HP_PLUG_INT) { + if (cs43130->dc_meas && !cs43130->hpload_done && + !work_busy(&cs43130->work)) { + dev_dbg(codec->dev, "HP load queue work\n"); + queue_work(cs43130->wq, &cs43130->work); + } + + snd_soc_jack_report(&cs43130->jack, SND_JACK_MECHANICAL, + CS43130_JACK_MASK); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int cs43130_probe(struct snd_soc_codec *codec) +{ + int ret; + struct cs43130_private *cs43130 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_card *card = codec->component.card; + unsigned int reg; + + cs43130->codec = codec; + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) { + regmap_update_bits(cs43130->regmap, CS43130_CRYSTAL_SET, + CS43130_XTAL_IBIAS_MASK, + cs43130->xtal_ibias); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, 0); + } + + ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK, + &cs43130->jack, NULL, 0); + if (ret < 0) { + dev_err(codec->dev, "Cannot create jack\n"); + return ret; + } + + cs43130->hpload_done = false; + if (cs43130->dc_meas) { + ret = device_create_file(codec->dev, &dev_attr_hpload_dc_l); + if (ret < 0) + return ret; + + ret = device_create_file(codec->dev, &dev_attr_hpload_dc_r); + if (ret < 0) + return ret; + + ret = device_create_file(codec->dev, &dev_attr_hpload_ac_l); + if (ret < 0) + return ret; + + ret = device_create_file(codec->dev, &dev_attr_hpload_ac_r); + if (ret < 0) + return ret; + + cs43130->wq = create_singlethread_workqueue("cs43130_hp"); + INIT_WORK(&cs43130->work, cs43130_imp_meas); + } + + regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, ®); + regmap_read(cs43130->regmap, CS43130_HP_STATUS, ®); + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT, 0); + regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT, + CS43130_HP_DETECT_CTRL_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT, + CS43130_HP_DETECT_CTRL_MASK, + CS43130_HP_DETECT_CTRL_MASK); + + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_cs43130 = { + .probe = cs43130_probe, + .component_driver = { + .controls = cs43130_snd_controls, + .num_controls = ARRAY_SIZE(cs43130_snd_controls), + }, + .set_sysclk = cs43130_codec_set_sysclk, + .set_pll = cs43130_set_pll, +}; + +static const struct regmap_config cs43130_regmap = { + .reg_bits = 24, + .pad_bits = 8, + .val_bits = 8, + + .max_register = CS43130_LASTREG, + .reg_defaults = cs43130_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cs43130_reg_defaults), + .readable_reg = cs43130_readable_register, + .precious_reg = cs43130_precious_register, + .volatile_reg = cs43130_volatile_register, + .cache_type = REGCACHE_RBTREE, + .use_single_rw = true, /* needed for regcache_sync */ +}; + +static u16 const cs43130_dc_threshold[CS43130_DC_THRESHOLD] = { + 50, + 120, +}; + +static int cs43130_handle_device_data(struct i2c_client *i2c_client, + struct cs43130_private *cs43130) +{ + struct device_node *np = i2c_client->dev.of_node; + unsigned int val; + int i; + + if (of_property_read_u32(np, "cirrus,xtal-ibias", &val) < 0) { + /* Crystal is unused. System clock is used for external MCLK */ + cs43130->xtal_ibias = CS43130_XTAL_UNUSED; + return 0; + } + + switch (val) { + case 1: + cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA; + break; + case 2: + cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA; + break; + case 3: + cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA; + break; + default: + dev_err(&i2c_client->dev, + "Invalid cirrus,xtal-ibias value: %d\n", val); + return -EINVAL; + } + + cs43130->dc_meas = of_property_read_bool(np, "cirrus,dc-measure"); + cs43130->ac_meas = of_property_read_bool(np, "cirrus,ac-measure"); + + if (of_property_read_u16_array(np, "cirrus,ac-freq", cs43130->ac_freq, + CS43130_AC_FREQ) < 0) { + for (i = 0; i < CS43130_AC_FREQ; i++) + cs43130->ac_freq[i] = cs43130_ac_freq[i]; + } + + if (of_property_read_u16_array(np, "cirrus,dc-threshold", + cs43130->dc_threshold, + CS43130_DC_THRESHOLD) < 0) { + for (i = 0; i < CS43130_DC_THRESHOLD; i++) + cs43130->dc_threshold[i] = cs43130_dc_threshold[i]; + } + + return 0; +} + +static int cs43130_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cs43130_private *cs43130; + int ret; + unsigned int devid = 0; + unsigned int reg; + int i; + + cs43130 = devm_kzalloc(&client->dev, sizeof(*cs43130), GFP_KERNEL); + if (!cs43130) + return -ENOMEM; + + i2c_set_clientdata(client, cs43130); + + cs43130->regmap = devm_regmap_init_i2c(client, &cs43130_regmap); + if (IS_ERR(cs43130->regmap)) { + ret = PTR_ERR(cs43130->regmap); + return ret; + } + + if (client->dev.of_node) { + ret = cs43130_handle_device_data(client, cs43130); + if (ret != 0) + return ret; + } + for (i = 0; i < ARRAY_SIZE(cs43130->supplies); i++) + cs43130->supplies[i].supply = cs43130_supply_names[i]; + + ret = devm_regulator_bulk_get(&client->dev, + ARRAY_SIZE(cs43130->supplies), + cs43130->supplies); + if (ret != 0) { + dev_err(&client->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + ret = regulator_bulk_enable(ARRAY_SIZE(cs43130->supplies), + cs43130->supplies); + if (ret != 0) { + dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + cs43130->reset_gpio = devm_gpiod_get_optional(&client->dev, + "reset", GPIOD_OUT_LOW); + if (IS_ERR(cs43130->reset_gpio)) + return PTR_ERR(cs43130->reset_gpio); + + gpiod_set_value_cansleep(cs43130->reset_gpio, 1); + + usleep_range(2000, 2050); + + ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, ®); + + devid = (reg & 0xFF) << 12; + ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, ®); + devid |= (reg & 0xFF) << 4; + ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, ®); + devid |= (reg & 0xF0) >> 4; + + switch (devid) { + case CS43130_CHIP_ID: + case CS4399_CHIP_ID: + case CS43131_CHIP_ID: + case CS43198_CHIP_ID: + break; + default: + dev_err(&client->dev, + "CS43130 Device ID %X. Expected ID %X, %X, %X or %X\n", + devid, CS43130_CHIP_ID, CS4399_CHIP_ID, + CS43131_CHIP_ID, CS43198_CHIP_ID); + ret = -ENODEV; + goto err; + } + + cs43130->dev_id = devid; + ret = regmap_read(cs43130->regmap, CS43130_REV_ID, ®); + if (ret < 0) { + dev_err(&client->dev, "Get Revision ID failed\n"); + goto err; + } + + dev_info(&client->dev, + "Cirrus Logic CS43130 (%x), Revision: %02X\n", devid, + reg & 0xFF); + + mutex_init(&cs43130->clk_mutex); + + init_completion(&cs43130->xtal_rdy); + init_completion(&cs43130->pll_rdy); + init_completion(&cs43130->hpload_evt); + + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, cs43130_irq_thread, + IRQF_ONESHOT | IRQF_TRIGGER_LOW, + "cs43130", cs43130); + if (ret != 0) { + dev_err(&client->dev, "Failed to request IRQ: %d\n", ret); + return ret; + } + + cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; + + pm_runtime_set_autosuspend_delay(&client->dev, 100); + pm_runtime_use_autosuspend(&client->dev); + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + + switch (cs43130->dev_id) { + case CS43130_CHIP_ID: + case CS43131_CHIP_ID: + memcpy(all_hp_widgets, digital_hp_widgets, + sizeof(digital_hp_widgets)); + memcpy(all_hp_widgets + ARRAY_SIZE(digital_hp_widgets), + analog_hp_widgets, sizeof(analog_hp_widgets)); + memcpy(all_hp_routes, digital_hp_routes, + sizeof(digital_hp_routes)); + memcpy(all_hp_routes + ARRAY_SIZE(digital_hp_routes), + analog_hp_routes, sizeof(analog_hp_routes)); + + soc_codec_dev_cs43130.component_driver.dapm_widgets = + all_hp_widgets; + soc_codec_dev_cs43130.component_driver.num_dapm_widgets = + ARRAY_SIZE(all_hp_widgets); + soc_codec_dev_cs43130.component_driver.dapm_routes = + all_hp_routes; + soc_codec_dev_cs43130.component_driver.num_dapm_routes = + ARRAY_SIZE(all_hp_routes); + break; + case CS43198_CHIP_ID: + case CS4399_CHIP_ID: + soc_codec_dev_cs43130.component_driver.dapm_widgets = + digital_hp_widgets; + soc_codec_dev_cs43130.component_driver.num_dapm_widgets = + ARRAY_SIZE(digital_hp_widgets); + soc_codec_dev_cs43130.component_driver.dapm_routes = + digital_hp_routes; + soc_codec_dev_cs43130.component_driver.num_dapm_routes = + ARRAY_SIZE(digital_hp_routes); + } + + ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_cs43130, + cs43130_dai, ARRAY_SIZE(cs43130_dai)); + if (ret < 0) { + dev_err(&client->dev, + "snd_soc_register_codec failed with ret = %d\n", ret); + goto err; + } + + regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG, + CS43130_ASP_3ST_MASK, 0); + regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG, + CS43130_XSP_3ST_MASK, 0); + + return 0; +err: + return ret; +} + +static int cs43130_i2c_remove(struct i2c_client *client) +{ + struct cs43130_private *cs43130 = i2c_get_clientdata(client); + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, + 1 << CS43130_XTAL_ERR_INT_SHIFT); + + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT, + CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT); + + if (cs43130->dc_meas) { + cancel_work_sync(&cs43130->work); + flush_workqueue(cs43130->wq); + + device_remove_file(&client->dev, &dev_attr_hpload_dc_l); + device_remove_file(&client->dev, &dev_attr_hpload_dc_r); + device_remove_file(&client->dev, &dev_attr_hpload_ac_l); + device_remove_file(&client->dev, &dev_attr_hpload_ac_r); + } + + if (cs43130->reset_gpio) + gpiod_set_value_cansleep(cs43130->reset_gpio, 0); + + pm_runtime_disable(&client->dev); + regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies); + + snd_soc_unregister_codec(&client->dev); + + return 0; +} + +static int __maybe_unused cs43130_runtime_suspend(struct device *dev) +{ + struct cs43130_private *cs43130 = dev_get_drvdata(dev); + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, + 1 << CS43130_XTAL_ERR_INT_SHIFT); + + regcache_cache_only(cs43130->regmap, true); + regcache_mark_dirty(cs43130->regmap); + + gpiod_set_value_cansleep(cs43130->reset_gpio, 0); + + regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies); + + return 0; +} + +static int __maybe_unused cs43130_runtime_resume(struct device *dev) +{ + struct cs43130_private *cs43130 = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(CS43130_NUM_SUPPLIES, cs43130->supplies); + if (ret != 0) { + dev_err(dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + regcache_cache_only(cs43130->regmap, false); + + gpiod_set_value_cansleep(cs43130->reset_gpio, 1); + + usleep_range(2000, 2050); + + ret = regcache_sync(cs43130->regmap); + if (ret != 0) { + dev_err(dev, "Failed to restore register cache\n"); + goto err; + } + + if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) + regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, + CS43130_XTAL_ERR_INT, 0); + + return 0; +err: + regcache_cache_only(cs43130->regmap, true); + regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies); + + return ret; +} + +static const struct dev_pm_ops cs43130_runtime_pm = { + SET_RUNTIME_PM_OPS(cs43130_runtime_suspend, cs43130_runtime_resume, + NULL) +}; + +static const struct of_device_id cs43130_of_match[] = { + {.compatible = "cirrus,cs43130",}, + {.compatible = "cirrus,cs4399",}, + {.compatible = "cirrus,cs43131",}, + {.compatible = "cirrus,cs43198",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, cs43130_of_match); + +static const struct i2c_device_id cs43130_i2c_id[] = { + {"cs43130", 0}, + {"cs4399", 0}, + {"cs43131", 0}, + {"cs43198", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs43130_i2c_id); + +static struct i2c_driver cs43130_i2c_driver = { + .driver = { + .name = "cs43130", + .of_match_table = cs43130_of_match, + .pm = &cs43130_runtime_pm, + }, + .id_table = cs43130_i2c_id, + .probe = cs43130_i2c_probe, + .remove = cs43130_i2c_remove, +}; + +module_i2c_driver(cs43130_i2c_driver); + +MODULE_AUTHOR("Li Xu "); +MODULE_DESCRIPTION("Cirrus Logic CS43130 ALSA SoC Codec Driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h new file mode 100644 index 000000000000..781258418d89 --- /dev/null +++ b/sound/soc/codecs/cs43130.h @@ -0,0 +1,546 @@ +/* + * ALSA SoC CS43130 codec driver + * + * Copyright 2017 Cirrus Logic, Inc. + * + * Author: Li Xu + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + */ + +#ifndef __CS43130_H__ +#define __CS43130_H__ + +/* CS43130 registers addresses */ +/* all reg address is shifted by a byte for control byte to be LSB */ +#define CS43130_FIRSTREG 0x010000 +#define CS43130_LASTREG 0x190000 +#define CS43130_CHIP_ID 0x00043130 +#define CS4399_CHIP_ID 0x00043990 +#define CS43131_CHIP_ID 0x00043131 +#define CS43198_CHIP_ID 0x00043198 +#define CS43130_DEVID_AB 0x010000 /* Device ID A & B [RO] */ +#define CS43130_DEVID_CD 0x010001 /* Device ID C & D [RO] */ +#define CS43130_DEVID_E 0x010002 /* Device ID E [RO] */ +#define CS43130_FAB_ID 0x010003 /* Fab ID [RO] */ +#define CS43130_REV_ID 0x010004 /* Revision ID [RO] */ +#define CS43130_SUBREV_ID 0x010005 /* Subrevision ID */ +#define CS43130_SYS_CLK_CTL_1 0x010006 /* System Clocking Ctl 1 */ +#define CS43130_SP_SRATE 0x01000B /* Serial Port Sample Rate */ +#define CS43130_SP_BITSIZE 0x01000C /* Serial Port Bit Size */ +#define CS43130_PAD_INT_CFG 0x01000D /* Pad Interface Config */ +#define CS43130_DXD1 0x010010 /* DXD1 */ +#define CS43130_DXD7 0x010025 /* DXD7 */ +#define CS43130_DXD19 0x010026 /* DXD19 */ +#define CS43130_DXD17 0x010027 /* DXD17 */ +#define CS43130_DXD18 0x010028 /* DXD18 */ +#define CS43130_DXD12 0x01002C /* DXD12 */ +#define CS43130_DXD8 0x01002E /* DXD8 */ +#define CS43130_PWDN_CTL 0x020000 /* Power Down Ctl */ +#define CS43130_DXD2 0x020019 /* DXD2 */ +#define CS43130_CRYSTAL_SET 0x020052 /* Crystal Setting */ +#define CS43130_PLL_SET_1 0x030001 /* PLL Setting 1 */ +#define CS43130_PLL_SET_2 0x030002 /* PLL Setting 2 */ +#define CS43130_PLL_SET_3 0x030003 /* PLL Setting 3 */ +#define CS43130_PLL_SET_4 0x030004 /* PLL Setting 4 */ +#define CS43130_PLL_SET_5 0x030005 /* PLL Setting 5 */ +#define CS43130_PLL_SET_6 0x030008 /* PLL Setting 6 */ +#define CS43130_PLL_SET_7 0x03000A /* PLL Setting 7 */ +#define CS43130_PLL_SET_8 0x03001B /* PLL Setting 8 */ +#define CS43130_PLL_SET_9 0x040002 /* PLL Setting 9 */ +#define CS43130_PLL_SET_10 0x040003 /* PLL Setting 10 */ +#define CS43130_CLKOUT_CTL 0x040004 /* CLKOUT Ctl */ +#define CS43130_ASP_NUM_1 0x040010 /* ASP Numerator 1 */ +#define CS43130_ASP_NUM_2 0x040011 /* ASP Numerator 2 */ +#define CS43130_ASP_DEN_1 0x040012 /* ASP Denominator 1 */ +#define CS43130_ASP_DEN_2 0x040013 /* ASP Denominator 2 */ +#define CS43130_ASP_LRCK_HI_TIME_1 0x040014 /* ASP LRCK High Time 1 */ +#define CS43130_ASP_LRCK_HI_TIME_2 0x040015 /* ASP LRCK High Time 2 */ +#define CS43130_ASP_LRCK_PERIOD_1 0x040016 /* ASP LRCK Period 1 */ +#define CS43130_ASP_LRCK_PERIOD_2 0x040017 /* ASP LRCK Period 2 */ +#define CS43130_ASP_CLOCK_CONF 0x040018 /* ASP Clock Config */ +#define CS43130_ASP_FRAME_CONF 0x040019 /* ASP Frame Config */ +#define CS43130_XSP_NUM_1 0x040020 /* XSP Numerator 1 */ +#define CS43130_XSP_NUM_2 0x040021 /* XSP Numerator 2 */ +#define CS43130_XSP_DEN_1 0x040022 /* XSP Denominator 1 */ +#define CS43130_XSP_DEN_2 0x040023 /* XSP Denominator 2 */ +#define CS43130_XSP_LRCK_HI_TIME_1 0x040024 /* XSP LRCK High Time 1 */ +#define CS43130_XSP_LRCK_HI_TIME_2 0x040025 /* XSP LRCK High Time 2 */ +#define CS43130_XSP_LRCK_PERIOD_1 0x040026 /* XSP LRCK Period 1 */ +#define CS43130_XSP_LRCK_PERIOD_2 0x040027 /* XSP LRCK Period 2 */ +#define CS43130_XSP_CLOCK_CONF 0x040028 /* XSP Clock Config */ +#define CS43130_XSP_FRAME_CONF 0x040029 /* XSP Frame Config */ +#define CS43130_ASP_CH_1_LOC 0x050000 /* ASP Chan 1 Location */ +#define CS43130_ASP_CH_2_LOC 0x050001 /* ASP Chan 2 Location */ +#define CS43130_ASP_CH_1_SZ_EN 0x05000A /* ASP Chan 1 Size, Enable */ +#define CS43130_ASP_CH_2_SZ_EN 0x05000B /* ASP Chan 2 Size, Enable */ +#define CS43130_XSP_CH_1_LOC 0x060000 /* XSP Chan 1 Location */ +#define CS43130_XSP_CH_2_LOC 0x060001 /* XSP Chan 2 Location */ +#define CS43130_XSP_CH_1_SZ_EN 0x06000A /* XSP Chan 1 Size, Enable */ +#define CS43130_XSP_CH_2_SZ_EN 0x06000B /* XSP Chan 2 Size, Enable */ +#define CS43130_DSD_VOL_B 0x070000 /* DSD Volume B */ +#define CS43130_DSD_VOL_A 0x070001 /* DSD Volume A */ +#define CS43130_DSD_PATH_CTL_1 0x070002 /* DSD Proc Path Sig Ctl 1 */ +#define CS43130_DSD_INT_CFG 0x070003 /* DSD Interface Config */ +#define CS43130_DSD_PATH_CTL_2 0x070004 /* DSD Proc Path Sig Ctl 2 */ +#define CS43130_DSD_PCM_MIX_CTL 0x070005 /* DSD and PCM Mixing Ctl */ +#define CS43130_DSD_PATH_CTL_3 0x070006 /* DSD Proc Path Sig Ctl 3 */ +#define CS43130_HP_OUT_CTL_1 0x080000 /* HP Output Ctl 1 */ +#define CS43130_DXD16 0x080024 /* DXD16 */ +#define CS43130_DXD13 0x080032 /* DXD13 */ +#define CS43130_PCM_FILT_OPT 0x090000 /* PCM Filter Option */ +#define CS43130_PCM_VOL_B 0x090001 /* PCM Volume B */ +#define CS43130_PCM_VOL_A 0x090002 /* PCM Volume A */ +#define CS43130_PCM_PATH_CTL_1 0x090003 /* PCM Path Signal Ctl 1 */ +#define CS43130_PCM_PATH_CTL_2 0x090004 /* PCM Path Signal Ctl 2 */ +#define CS43130_DXD6 0x090097 /* DXD6 */ +#define CS43130_CLASS_H_CTL 0x0B0000 /* Class H Ctl */ +#define CS43130_DXD15 0x0B0005 /* DXD15 */ +#define CS43130_DXD14 0x0B0006 /* DXD14 */ +#define CS43130_DXD3 0x0C0002 /* DXD3 */ +#define CS43130_DXD10 0x0C0003 /* DXD10 */ +#define CS43130_DXD11 0x0C0005 /* DXD11 */ +#define CS43130_DXD9 0x0C0006 /* DXD9 */ +#define CS43130_DXD4 0x0C0009 /* DXD4 */ +#define CS43130_DXD5 0x0C000E /* DXD5 */ +#define CS43130_HP_DETECT 0x0D0000 /* HP Detect */ +#define CS43130_HP_STATUS 0x0D0001 /* HP Status [RO] */ +#define CS43130_HP_LOAD_1 0x0E0000 /* HP Load 1 */ +#define CS43130_HP_MEAS_LOAD_1 0x0E0003 /* HP Load Measurement 1 */ +#define CS43130_HP_MEAS_LOAD_2 0x0E0004 /* HP Load Measurement 2 */ +#define CS43130_HP_DC_STAT_1 0x0E000D /* HP DC Load Status 0 [RO] */ +#define CS43130_HP_DC_STAT_2 0x0E000E /* HP DC Load Status 1 [RO] */ +#define CS43130_HP_AC_STAT_1 0x0E0010 /* HP AC Load Status 0 [RO] */ +#define CS43130_HP_AC_STAT_2 0x0E0011 /* HP AC Load Status 1 [RO] */ +#define CS43130_HP_LOAD_STAT 0x0E001A /* HP Load Status [RO] */ +#define CS43130_INT_STATUS_1 0x0F0000 /* Interrupt Status 1 */ +#define CS43130_INT_STATUS_2 0x0F0001 /* Interrupt Status 2 */ +#define CS43130_INT_STATUS_3 0x0F0002 /* Interrupt Status 3 */ +#define CS43130_INT_STATUS_4 0x0F0003 /* Interrupt Status 4 */ +#define CS43130_INT_STATUS_5 0x0F0004 /* Interrupt Status 5 */ +#define CS43130_INT_MASK_1 0x0F0010 /* Interrupt Mask 1 */ +#define CS43130_INT_MASK_2 0x0F0011 /* Interrupt Mask 2 */ +#define CS43130_INT_MASK_3 0x0F0012 /* Interrupt Mask 3 */ +#define CS43130_INT_MASK_4 0x0F0013 /* Interrupt Mask 4 */ +#define CS43130_INT_MASK_5 0x0F0014 /* Interrupt Mask 5 */ + +#define CS43130_MCLK_SRC_SEL_MASK 0x03 +#define CS43130_MCLK_SRC_SEL_SHIFT 0 +#define CS43130_MCLK_INT_MASK 0x04 +#define CS43130_MCLK_INT_SHIFT 2 +#define CS43130_CH_BITSIZE_MASK 0x03 +#define CS43130_CH_EN_MASK 0x04 +#define CS43130_CH_EN_SHIFT 2 +#define CS43130_ASP_BITSIZE_MASK 0x03 +#define CS43130_XSP_BITSIZE_MASK 0x0C +#define CS43130_XSP_BITSIZE_SHIFT 2 +#define CS43130_SP_BITSIZE_ASP_SHIFT 0 +#define CS43130_HP_DETECT_CTRL_SHIFT 6 +#define CS43130_HP_DETECT_CTRL_MASK (0x03 << CS43130_HP_DETECT_CTRL_SHIFT) +#define CS43130_HP_DETECT_INV_SHIFT 5 +#define CS43130_HP_DETECT_INV_MASK (1 << CS43130_HP_DETECT_INV_SHIFT) + +/* CS43130_INT_MASK_1 */ +#define CS43130_HP_PLUG_INT_SHIFT 6 +#define CS43130_HP_PLUG_INT (1 << CS43130_HP_PLUG_INT_SHIFT) +#define CS43130_HP_UNPLUG_INT_SHIFT 5 +#define CS43130_HP_UNPLUG_INT (1 << CS43130_HP_UNPLUG_INT_SHIFT) +#define CS43130_XTAL_RDY_INT_SHIFT 4 +#define CS43130_XTAL_RDY_INT_MASK 0x10 +#define CS43130_XTAL_RDY_INT (1 << CS43130_XTAL_RDY_INT_SHIFT) +#define CS43130_XTAL_ERR_INT_SHIFT 3 +#define CS43130_XTAL_ERR_INT (1 << CS43130_XTAL_ERR_INT_SHIFT) +#define CS43130_PLL_RDY_INT_MASK 0x04 +#define CS43130_PLL_RDY_INT_SHIFT 2 +#define CS43130_PLL_RDY_INT (1 << CS43130_PLL_RDY_INT_SHIFT) + +/* CS43130_INT_MASK_4 */ +#define CS43130_INT_MASK_ALL 0xFF +#define CS43130_HPLOAD_NO_DC_INT_SHIFT 7 +#define CS43130_HPLOAD_NO_DC_INT (1 << CS43130_HPLOAD_NO_DC_INT_SHIFT) +#define CS43130_HPLOAD_UNPLUG_INT_SHIFT 6 +#define CS43130_HPLOAD_UNPLUG_INT (1 << CS43130_HPLOAD_UNPLUG_INT_SHIFT) +#define CS43130_HPLOAD_OOR_INT_SHIFT 4 +#define CS43130_HPLOAD_OOR_INT (1 << CS43130_HPLOAD_OOR_INT_SHIFT) +#define CS43130_HPLOAD_AC_INT_SHIFT 3 +#define CS43130_HPLOAD_AC_INT (1 << CS43130_HPLOAD_AC_INT_SHIFT) +#define CS43130_HPLOAD_DC_INT_SHIFT 2 +#define CS43130_HPLOAD_DC_INT (1 << CS43130_HPLOAD_DC_INT_SHIFT) +#define CS43130_HPLOAD_OFF_INT_SHIFT 1 +#define CS43130_HPLOAD_OFF_INT (1 << CS43130_HPLOAD_OFF_INT_SHIFT) +#define CS43130_HPLOAD_ON_INT 1 + +/* CS43130_HP_LOAD_1 */ +#define CS43130_HPLOAD_EN_SHIFT 7 +#define CS43130_HPLOAD_EN (1 << CS43130_HPLOAD_EN_SHIFT) +#define CS43130_HPLOAD_CHN_SEL_SHIFT 4 +#define CS43130_HPLOAD_CHN_SEL (1 << CS43130_HPLOAD_CHN_SEL_SHIFT) +#define CS43130_HPLOAD_AC_START_SHIFT 1 +#define CS43130_HPLOAD_AC_START (1 << CS43130_HPLOAD_AC_START_SHIFT) +#define CS43130_HPLOAD_DC_START 1 + +/* Reg CS43130_SP_BITSIZE */ +#define CS43130_SP_BIT_SIZE_8 0x03 +#define CS43130_SP_BIT_SIZE_16 0x02 +#define CS43130_SP_BIT_SIZE_24 0x01 +#define CS43130_SP_BIT_SIZE_32 0x00 + +/* Reg CS43130_SP_CH_SZ_EN */ +#define CS43130_CH_BIT_SIZE_8 0x00 +#define CS43130_CH_BIT_SIZE_16 0x01 +#define CS43130_CH_BIT_SIZE_24 0x02 +#define CS43130_CH_BIT_SIZE_32 0x03 + +/* PLL */ +#define CS43130_PLL_START_MASK 0x01 +#define CS43130_PLL_MODE_MASK 0x02 +#define CS43130_PLL_MODE_SHIFT 1 + +#define CS43130_PLL_REF_PREDIV_MASK 0x3 + +#define CS43130_SP_STP_MASK 0x10 +#define CS43130_SP_STP_SHIFT 4 +#define CS43130_SP_5050_MASK 0x08 +#define CS43130_SP_5050_SHIFT 3 +#define CS43130_SP_FSD_MASK 0x07 + +#define CS43130_SP_MODE_MASK 0x10 +#define CS43130_SP_MODE_SHIFT 4 +#define CS43130_SP_SCPOL_OUT_MASK 0x08 +#define CS43130_SP_SCPOL_OUT_SHIFT 3 +#define CS43130_SP_SCPOL_IN_MASK 0x04 +#define CS43130_SP_SCPOL_IN_SHIFT 2 +#define CS43130_SP_LCPOL_OUT_MASK 0x02 +#define CS43130_SP_LCPOL_OUT_SHIFT 1 +#define CS43130_SP_LCPOL_IN_MASK 0x01 +#define CS43130_SP_LCPOL_IN_SHIFT 0 + +/* Reg CS43130_PWDN_CTL */ +#define CS43130_PDN_XSP_MASK 0x80 +#define CS43130_PDN_XSP_SHIFT 7 +#define CS43130_PDN_ASP_MASK 0x40 +#define CS43130_PDN_ASP_SHIFT 6 +#define CS43130_PDN_DSPIF_MASK 0x20 +#define CS43130_PDN_DSDIF_SHIFT 5 +#define CS43130_PDN_HP_MASK 0x10 +#define CS43130_PDN_HP_SHIFT 4 +#define CS43130_PDN_XTAL_MASK 0x08 +#define CS43130_PDN_XTAL_SHIFT 3 +#define CS43130_PDN_PLL_MASK 0x04 +#define CS43130_PDN_PLL_SHIFT 2 +#define CS43130_PDN_CLKOUT_MASK 0x02 +#define CS43130_PDN_CLKOUT_SHIFT 1 + +/* Reg CS43130_HP_OUT_CTL_1 */ +#define CS43130_HP_IN_EN_SHIFT 3 +#define CS43130_HP_IN_EN_MASK 0x08 + +/* Reg CS43130_PAD_INT_CFG */ +#define CS43130_ASP_3ST_MASK 0x01 +#define CS43130_XSP_3ST_MASK 0x02 + +/* Reg CS43130_PLL_SET_2 */ +#define CS43130_PLL_DIV_DATA_MASK 0x000000FF +#define CS43130_PLL_DIV_FRAC_0_DATA_SHIFT 0 + +/* Reg CS43130_PLL_SET_3 */ +#define CS43130_PLL_DIV_FRAC_1_DATA_SHIFT 8 + +/* Reg CS43130_PLL_SET_4 */ +#define CS43130_PLL_DIV_FRAC_2_DATA_SHIFT 16 + +/* Reg CS43130_SP_DEN_1 */ +#define CS43130_SP_M_LSB_DATA_MASK 0x00FF +#define CS43130_SP_M_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_DEN_2 */ +#define CS43130_SP_M_MSB_DATA_MASK 0xFF00 +#define CS43130_SP_M_MSB_DATA_SHIFT 8 + +/* Reg CS43130_SP_NUM_1 */ +#define CS43130_SP_N_LSB_DATA_MASK 0x00FF +#define CS43130_SP_N_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_NUM_2 */ +#define CS43130_SP_N_MSB_DATA_MASK 0xFF00 +#define CS43130_SP_N_MSB_DATA_SHIFT 8 + +/* Reg CS43130_SP_LRCK_HI_TIME_1 */ +#define CS43130_SP_LCHI_DATA_MASK 0x00FF +#define CS43130_SP_LCHI_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_LRCK_HI_TIME_2 */ +#define CS43130_SP_LCHI_MSB_DATA_SHIFT 8 + +/* Reg CS43130_SP_LRCK_PERIOD_1 */ +#define CS43130_SP_LCPR_DATA_MASK 0x00FF +#define CS43130_SP_LCPR_LSB_DATA_SHIFT 0 + +/* Reg CS43130_SP_LRCK_PERIOD_2 */ +#define CS43130_SP_LCPR_MSB_DATA_SHIFT 8 + +#define CS43130_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define CS43130_DOP_FORMATS (SNDRV_PCM_FMTBIT_DSD_U16_LE | \ + SNDRV_PCM_FMTBIT_DSD_U16_BE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +/* Reg CS43130_CRYSTAL_SET */ +#define CS43130_XTAL_IBIAS_MASK 0x07 + +/* Reg CS43130_PATH_CTL_1 */ +#define CS43130_MUTE_MASK 0x03 +#define CS43130_MUTE_EN 0x03 + +/* Reg CS43130_DSD_INT_CFG */ +#define CS43130_DSD_MASTER 0x04 + +/* Reg CS43130_DSD_PATH_CTL_2 */ +#define CS43130_DSD_SRC_MASK 0x60 +#define CS43130_DSD_SRC_SHIFT 5 +#define CS43130_DSD_EN_SHIFT 4 +#define CS43130_DSD_SPEED_MASK 0x04 +#define CS43130_DSD_SPEED_SHIFT 2 + +/* Reg CS43130_DSD_PCM_MIX_CTL */ +#define CS43130_MIX_PCM_PREP_SHIFT 1 +#define CS43130_MIX_PCM_PREP_MASK 0x02 + +#define CS43130_MIX_PCM_DSD_SHIFT 0 +#define CS43130_MIX_PCM_DSD_MASK 0x01 + +/* Reg CS43130_HP_MEAS_LOAD */ +#define CS43130_HP_MEAS_LOAD_MASK 0x000000FF +#define CS43130_HP_MEAS_LOAD_1_SHIFT 0 +#define CS43130_HP_MEAS_LOAD_2_SHIFT 8 + +#define CS43130_MCLK_22M 22579200 +#define CS43130_MCLK_24M 24576000 + +#define CS43130_LINEOUT_LOAD 5000 +#define CS43130_JACK_LINEOUT (SND_JACK_MECHANICAL | SND_JACK_LINEOUT) +#define CS43130_JACK_HEADPHONE (SND_JACK_MECHANICAL | \ + SND_JACK_HEADPHONE) +#define CS43130_JACK_MASK (SND_JACK_MECHANICAL | \ + SND_JACK_LINEOUT | \ + SND_JACK_HEADPHONE) + +enum cs43130_dsd_src { + CS43130_DSD_SRC_DSD = 0, + CS43130_DSD_SRC_ASP = 2, + CS43130_DSD_SRC_XSP = 3, +}; + +enum cs43130_asp_rate { + CS43130_ASP_SPRATE_32K = 0, + CS43130_ASP_SPRATE_44_1K, + CS43130_ASP_SPRATE_48K, + CS43130_ASP_SPRATE_88_2K, + CS43130_ASP_SPRATE_96K, + CS43130_ASP_SPRATE_176_4K, + CS43130_ASP_SPRATE_192K, + CS43130_ASP_SPRATE_352_8K, + CS43130_ASP_SPRATE_384K, +}; + +enum cs43130_mclk_src_sel { + CS43130_MCLK_SRC_EXT = 0, + CS43130_MCLK_SRC_PLL, + CS43130_MCLK_SRC_RCO +}; + +enum cs43130_mclk_int_freq { + CS43130_MCLK_24P5 = 0, + CS43130_MCLK_22P5, +}; + +enum cs43130_xtal_ibias { + CS43130_XTAL_UNUSED = -1, + CS43130_XTAL_IBIAS_15UA = 2, + CS43130_XTAL_IBIAS_12_5UA = 4, + CS43130_XTAL_IBIAS_7_5UA = 6, +}; + +enum cs43130_dai_id { + CS43130_ASP_PCM_DAI = 0, + CS43130_ASP_DOP_DAI, + CS43130_XSP_DOP_DAI, + CS43130_XSP_DSD_DAI, + CS43130_DAI_ID_MAX, +}; + +struct cs43130_clk_gen { + unsigned int mclk_int; + int fs; + u16 den; + u16 num; +}; + +/* frm_size = 16 */ +static const struct cs43130_clk_gen cs43130_16_clk_gen[] = { + {22579200, 32000, 441, 10,}, + {22579200, 44100, 32, 1,}, + {22579200, 48000, 147, 5,}, + {22579200, 88200, 16, 1,}, + {22579200, 96000, 147, 10,}, + {22579200, 176400, 8, 1,}, + {22579200, 192000, 147, 20,}, + {22579200, 352800, 4, 1,}, + {22579200, 384000, 147, 40,}, + {24576000, 32000, 48, 1,}, + {24576000, 44100, 5120, 147,}, + {24576000, 48000, 32, 1,}, + {24576000, 88200, 2560, 147,}, + {24576000, 96000, 16, 1,}, + {24576000, 176400, 1280, 147,}, + {24576000, 192000, 8, 1,}, + {24576000, 352800, 640, 147,}, + {24576000, 384000, 4, 1,}, +}; + +/* frm_size = 32 */ +static const struct cs43130_clk_gen cs43130_32_clk_gen[] = { + {22579200, 32000, 441, 20,}, + {22579200, 44100, 16, 1,}, + {22579200, 48000, 147, 10,}, + {22579200, 88200, 8, 1,}, + {22579200, 96000, 147, 20,}, + {22579200, 176400, 4, 1,}, + {22579200, 192000, 147, 40,}, + {22579200, 352800, 2, 1,}, + {22579200, 384000, 147, 80,}, + {24576000, 32000, 24, 1,}, + {24576000, 44100, 2560, 147,}, + {24576000, 48000, 16, 1,}, + {24576000, 88200, 1280, 147,}, + {24576000, 96000, 8, 1,}, + {24576000, 176400, 640, 147,}, + {24576000, 192000, 4, 1,}, + {24576000, 352800, 320, 147,}, + {24576000, 384000, 2, 1,}, +}; + +/* frm_size = 48 */ +static const struct cs43130_clk_gen cs43130_48_clk_gen[] = { + {22579200, 32000, 147, 100,}, + {22579200, 44100, 32, 3,}, + {22579200, 48000, 49, 5,}, + {22579200, 88200, 16, 3,}, + {22579200, 96000, 49, 10,}, + {22579200, 176400, 8, 3,}, + {22579200, 192000, 49, 20,}, + {22579200, 352800, 4, 3,}, + {22579200, 384000, 49, 40,}, + {24576000, 32000, 16, 1,}, + {24576000, 44100, 5120, 441,}, + {24576000, 48000, 32, 3,}, + {24576000, 88200, 2560, 441,}, + {24576000, 96000, 16, 3,}, + {24576000, 176400, 1280, 441,}, + {24576000, 192000, 8, 3,}, + {24576000, 352800, 640, 441,}, + {24576000, 384000, 4, 3,}, +}; + +/* frm_size = 64 */ +static const struct cs43130_clk_gen cs43130_64_clk_gen[] = { + {22579200, 32000, 441, 40,}, + {22579200, 44100, 8, 1,}, + {22579200, 48000, 147, 20,}, + {22579200, 88200, 4, 1,}, + {22579200, 96000, 147, 40,}, + {22579200, 176400, 2, 1,}, + {22579200, 192000, 147, 80,}, + {22579200, 352800, 1, 1,}, + {24576000, 32000, 12, 1,}, + {24576000, 44100, 1280, 147,}, + {24576000, 48000, 8, 1,}, + {24576000, 88200, 640, 147,}, + {24576000, 96000, 4, 1,}, + {24576000, 176400, 320, 147,}, + {24576000, 192000, 2, 1,}, + {24576000, 352800, 160, 147,}, + {24576000, 384000, 1, 1,}, +}; + +struct cs43130_bitwidth_map { + unsigned int bitwidth; + u8 sp_bit; + u8 ch_bit; +}; + +struct cs43130_rate_map { + int fs; + int val; +}; + +#define HP_LEFT 0 +#define HP_RIGHT 1 +#define CS43130_AC_FREQ 10 +#define CS43130_DC_THRESHOLD 2 + +#define CS43130_NUM_SUPPLIES 5 +static const char *const cs43130_supply_names[CS43130_NUM_SUPPLIES] = { + "VA", + "VP", + "VCP", + "VD", + "VL", +}; + +#define CS43130_NUM_INT 5 /* number of interrupt status reg */ + +struct cs43130_dai { + unsigned int sclk; + unsigned int dai_format; + unsigned int dai_mode; +}; + +struct cs43130_private { + struct snd_soc_codec *codec; + struct regmap *regmap; + struct regulator_bulk_data supplies[CS43130_NUM_SUPPLIES]; + struct gpio_desc *reset_gpio; + unsigned int dev_id; /* codec device ID */ + int xtal_ibias; + + /* shared by both DAIs */ + struct mutex clk_mutex; + int clk_req; + bool pll_bypass; + struct completion xtal_rdy; + struct completion pll_rdy; + unsigned int mclk; + unsigned int mclk_int; + int mclk_int_src; + + /* DAI specific */ + struct cs43130_dai dais[CS43130_DAI_ID_MAX]; + + /* HP load specific */ + bool dc_meas; + bool ac_meas; + bool hpload_done; + struct completion hpload_evt; + unsigned int hpload_stat; + u16 hpload_dc[2]; + u16 dc_threshold[CS43130_DC_THRESHOLD]; + u16 ac_freq[CS43130_AC_FREQ]; + u16 hpload_ac[CS43130_AC_FREQ][2]; + struct workqueue_struct *wq; + struct work_struct work; + struct snd_soc_jack jack; +}; + +#endif /* __CS43130_H__ */ diff --git a/sound/soc/codecs/cs4349.c b/sound/soc/codecs/cs4349.c index 231ca935cdf3..0a749c79ef57 100644 --- a/sound/soc/codecs/cs4349.c +++ b/sound/soc/codecs/cs4349.c @@ -255,7 +255,7 @@ static struct snd_soc_dai_driver cs4349_dai = { .symmetric_rates = 1, }; -static struct snd_soc_codec_driver soc_codec_dev_cs4349 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs4349 = { .component_driver = { .controls = cs4349_snd_controls, .num_controls = ARRAY_SIZE(cs4349_snd_controls), diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 47e6fddef92b..e09fc8f037f1 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c @@ -1183,7 +1183,7 @@ static struct regmap *cs47l24_get_regmap(struct device *dev) return priv->core.arizona->regmap; } -static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { +static const struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { .probe = cs47l24_codec_probe, .remove = cs47l24_codec_remove, .get_regmap = cs47l24_get_regmap, @@ -1203,7 +1203,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { }, }; -static struct snd_compr_ops cs47l24_compr_ops = { +static const struct snd_compr_ops cs47l24_compr_ops = { .open = cs47l24_open, .free = wm_adsp_compr_free, .set_params = wm_adsp_compr_set_params, @@ -1213,7 +1213,7 @@ static struct snd_compr_ops cs47l24_compr_ops = { .copy = wm_adsp_compr_copy, }; -static struct snd_soc_platform_driver cs47l24_compr_platform = { +static const struct snd_soc_platform_driver cs47l24_compr_platform = { .compr_ops = &cs47l24_compr_ops, }; diff --git a/sound/soc/codecs/cs53l30.c b/sound/soc/codecs/cs53l30.c index 06933a5d0a75..c7edf2df5e36 100644 --- a/sound/soc/codecs/cs53l30.c +++ b/sound/soc/codecs/cs53l30.c @@ -842,8 +842,7 @@ static int cs53l30_mute_stream(struct snd_soc_dai *dai, int mute, int stream) { struct cs53l30_private *priv = snd_soc_codec_get_drvdata(dai->codec); - if (priv->mute_gpio) - gpiod_set_value_cansleep(priv->mute_gpio, mute); + gpiod_set_value_cansleep(priv->mute_gpio, mute); return 0; } @@ -892,7 +891,7 @@ static int cs53l30_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver cs53l30_driver = { +static const struct snd_soc_codec_driver cs53l30_driver = { .probe = cs53l30_codec_probe, .set_bias_level = cs53l30_set_bias_level, .idle_bias_off = true, @@ -960,8 +959,7 @@ static int cs53l30_i2c_probe(struct i2c_client *client, goto error; } - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); i2c_set_clientdata(client, cs53l30); @@ -1056,8 +1054,7 @@ static int cs53l30_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); /* Hold down reset */ - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), cs53l30->supplies); @@ -1073,8 +1070,7 @@ static int cs53l30_runtime_suspend(struct device *dev) regcache_cache_only(cs53l30->regmap, true); /* Hold down reset */ - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs53l30->supplies), cs53l30->supplies); @@ -1094,8 +1090,7 @@ static int cs53l30_runtime_resume(struct device *dev) return ret; } - if (cs53l30->reset_gpio) - gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); + gpiod_set_value_cansleep(cs53l30->reset_gpio, 1); regcache_cache_only(cs53l30->regmap, false); ret = regcache_sync(cs53l30->regmap); diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 2c12471e42a6..46b1fbb66eba 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -398,7 +398,7 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) static const u8 cx20442_reg; -static struct snd_soc_codec_driver cx20442_codec_dev = { +static const struct snd_soc_codec_driver cx20442_codec_dev = { .probe = cx20442_codec_probe, .remove = cx20442_codec_remove, .set_bias_level = cx20442_set_bias_level, diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 17053dfc94cf..1af443ccbc51 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -1164,7 +1164,7 @@ static int da7210_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da7210 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7210 = { .probe = da7210_probe, .component_driver = { diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index c3e11897f8ae..cc0b2d2eaf15 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -1787,7 +1787,7 @@ static int da7213_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da7213 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7213 = { .probe = da7213_probe, .set_bias_level = da7213_set_bias_level, diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 6e1940eb0653..b2d42ec1dcd9 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -3035,7 +3035,7 @@ static int da7218_resume(struct snd_soc_codec *codec) #define da7218_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_da7218 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7218 = { .probe = da7218_probe, .remove = da7218_remove, .suspend = da7218_suspend, diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index f71d72c22bfc..6f088536df32 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -1891,7 +1891,7 @@ static int da7219_resume(struct snd_soc_codec *codec) #define da7219_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_da7219 = { +static const struct snd_soc_codec_driver soc_codec_dev_da7219 = { .probe = da7219_probe, .remove = da7219_remove, .suspend = da7219_suspend, diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index c1cc1c1c28f2..83db4d23c90b 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -1499,7 +1499,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da732x = { +static const struct snd_soc_codec_driver soc_codec_dev_da732x = { .set_bias_level = da732x_set_bias_level, .component_driver = { .controls = da732x_snd_controls, diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 4efb5f897a0c..bd7faaee5802 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -1451,7 +1451,7 @@ static int da9055_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_da9055 = { +static const struct snd_soc_codec_driver soc_codec_dev_da9055 = { .probe = da9055_probe, .set_bias_level = da9055_set_bias_level, diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index c82b9dc41e9a..b88a1ee66f80 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -19,6 +19,8 @@ * */ +#include +#include #include #include #include @@ -27,6 +29,34 @@ #include #include +static int dmic_daiops_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai); + + if (!dmic_en) + return 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + gpiod_set_value(dmic_en, 1); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + gpiod_set_value(dmic_en, 0); + break; + } + + return 0; +} + +static const struct snd_soc_dai_ops dmic_dai_ops = { + .trigger = dmic_daiops_trigger, +}; + static struct snd_soc_dai_driver dmic_dai = { .name = "dmic-hifi", .capture = { @@ -38,8 +68,23 @@ static struct snd_soc_dai_driver dmic_dai = { | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, }, + .ops = &dmic_dai_ops, }; +static int dmic_codec_probe(struct snd_soc_codec *codec) +{ + struct gpio_desc *dmic_en; + + dmic_en = devm_gpiod_get_optional(codec->dev, + "dmicen", GPIOD_OUT_LOW); + if (IS_ERR(dmic_en)) + return PTR_ERR(dmic_en); + + snd_soc_codec_set_drvdata(codec, dmic_en); + + return 0; +} + static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0, SND_SOC_NOPM, 0, 0), @@ -50,7 +95,8 @@ static const struct snd_soc_dapm_route intercon[] = { {"DMIC AIF", NULL, "DMic"}, }; -static struct snd_soc_codec_driver soc_dmic = { +static const struct snd_soc_codec_driver soc_dmic = { + .probe = dmic_codec_probe, .component_driver = { .dapm_widgets = dmic_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets), @@ -73,9 +119,15 @@ static int dmic_dev_remove(struct platform_device *pdev) MODULE_ALIAS("platform:dmic-codec"); +static const struct of_device_id dmic_dev_match[] = { + {.compatible = "dmic-codec"}, + {} +}; + static struct platform_driver dmic_driver = { .driver = { .name = "dmic-codec", + .of_match_table = dmic_dev_match, }, .probe = dmic_dev_probe, .remove = dmic_dev_remove, diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c index 25ede825d349..3869025754d8 100644 --- a/sound/soc/codecs/es7134.c +++ b/sound/soc/codecs/es7134.c @@ -69,7 +69,7 @@ static const struct snd_soc_dapm_route es7134_dapm_routes[] = { { "AOUTR", NULL, "DAC" }, }; -static struct snd_soc_codec_driver es7134_codec_driver = { +static const struct snd_soc_codec_driver es7134_codec_driver = { .component_driver = { .dapm_widgets = es7134_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(es7134_dapm_widgets), diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index ecc02449c569..da2d353af5ba 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -502,7 +502,7 @@ static int es8316_mute(struct snd_soc_dai *dai, int mute) #define ES8316_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops es8316_ops = { +static const struct snd_soc_dai_ops es8316_ops = { .startup = es8316_pcm_startup, .hw_params = es8316_pcm_hw_params, .set_fmt = es8316_set_dai_fmt, @@ -554,7 +554,7 @@ static int es8316_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_es8316 = { +static const struct snd_soc_codec_driver soc_codec_dev_es8316 = { .probe = es8316_probe, .idle_bias_off = true, diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index ed7cc42d1ee2..bcdb8914ec16 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -830,7 +830,7 @@ const struct regmap_config es8328_regmap_config = { }; EXPORT_SYMBOL_GPL(es8328_regmap_config); -static struct snd_soc_codec_driver es8328_codec_driver = { +static const struct snd_soc_codec_driver es8328_codec_driver = { .probe = es8328_codec_probe, .suspend = es8328_suspend, .resume = es8328_resume, diff --git a/sound/soc/codecs/es8328.h b/sound/soc/codecs/es8328.h index 8930322d712b..9109f6b5b045 100644 --- a/sound/soc/codecs/es8328.h +++ b/sound/soc/codecs/es8328.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * es8328.h -- ES8328 ALSA SoC Audio driver */ diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index bc2e74ff3b2d..e824d47cc22b 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -121,6 +121,10 @@ struct hdac_hdmi_dai_port_map { struct hdac_hdmi_cvt *cvt; }; +struct hdac_hdmi_drv_data { + unsigned int vendor_nid; +}; + struct hdac_hdmi_priv { struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS]; struct list_head pin_list; @@ -131,6 +135,7 @@ struct hdac_hdmi_priv { int num_ports; struct mutex pin_mutex; struct hdac_chmap chmap; + struct hdac_hdmi_drv_data *drv_data; }; static struct hdac_hdmi_pcm * @@ -1321,6 +1326,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) } #define INTEL_VENDOR_NID 0x08 +#define INTEL_GLK_VENDOR_NID 0x0b #define INTEL_GET_VENDOR_VERB 0xf81 #define INTEL_SET_VENDOR_VERB 0x781 #define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ @@ -1329,14 +1335,17 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac) { unsigned int vendor_param; + struct hdac_ext_device *edev = to_ehdac_device(hdac); + struct hdac_hdmi_priv *hdmi = edev->private_data; + unsigned int vendor_nid = hdmi->drv_data->vendor_nid; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_GET_VENDOR_VERB, 0); if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) return; vendor_param |= INTEL_EN_ALL_PIN_CVTS; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_SET_VENDOR_VERB, vendor_param); if (vendor_param == -1) return; @@ -1345,22 +1354,25 @@ static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac) static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac) { unsigned int vendor_param; + struct hdac_ext_device *edev = to_ehdac_device(hdac); + struct hdac_hdmi_priv *hdmi = edev->private_data; + unsigned int vendor_nid = hdmi->drv_data->vendor_nid; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_GET_VENDOR_VERB, 0); if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) return; /* enable DP1.2 mode */ vendor_param |= INTEL_EN_DP12; - vendor_param = snd_hdac_codec_read(hdac, INTEL_VENDOR_NID, 0, + vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, INTEL_SET_VENDOR_VERB, vendor_param); if (vendor_param == -1) return; } -static struct snd_soc_dai_ops hdmi_dai_ops = { +static const struct snd_soc_dai_ops hdmi_dai_ops = { .startup = hdac_hdmi_pcm_open, .shutdown = hdac_hdmi_pcm_close, .hw_params = hdac_hdmi_set_hw_params, @@ -1858,7 +1870,7 @@ static void hdmi_codec_complete(struct device *dev) #define hdmi_codec_complete NULL #endif -static struct snd_soc_codec_driver hdmi_hda_codec = { +static const struct snd_soc_codec_driver hdmi_hda_codec = { .probe = hdmi_codec_probe, .remove = hdmi_codec_remove, .idle_bias_off = true, @@ -1927,6 +1939,14 @@ static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx) return port->eld.info.spk_alloc; } +static struct hdac_hdmi_drv_data intel_glk_drv_data = { + .vendor_nid = INTEL_GLK_VENDOR_NID, +}; + +static struct hdac_hdmi_drv_data intel_drv_data = { + .vendor_nid = INTEL_VENDOR_NID, +}; + static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) { struct hdac_device *codec = &edev->hdac; @@ -1935,6 +1955,8 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) struct hdac_ext_link *hlink = NULL; int num_dais = 0; int ret = 0; + struct hdac_driver *hdrv = drv_to_hdac_driver(codec->dev.driver); + const struct hda_device_id *hdac_id = hdac_get_device_id(codec, hdrv); /* hold the ref while we probe */ hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev)); @@ -1956,6 +1978,12 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached; hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc; + if (hdac_id->driver_data) + hdmi_priv->drv_data = + (struct hdac_hdmi_drv_data *)hdac_id->driver_data; + else + hdmi_priv->drv_data = &intel_drv_data; + dev_set_drvdata(&codec->dev, edev); INIT_LIST_HEAD(&hdmi_priv->pin_list); @@ -2127,7 +2155,8 @@ static const struct hda_device_id hdmi_list[] = { HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0), HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0), HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0), - HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", 0), + HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", + &intel_glk_drv_data), {} }; diff --git a/sound/soc/codecs/hdac_hdmi.h b/sound/soc/codecs/hdac_hdmi.h index dfc3a9cf7199..b5b57a5cbbfd 100644 --- a/sound/soc/codecs/hdac_hdmi.h +++ b/sound/soc/codecs/hdac_hdmi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __HDAC_HDMI_H__ #define __HDAC_HDMI_H__ diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 22ed0dc88f0a..3abf82563408 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -67,14 +67,14 @@ struct hdmi_codec_cea_spk_alloc { }; /* Channel maps stereo HDMI */ -const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = { +static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = { { .channels = 2, .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, { } }; /* Channel maps for multi-channel playbacks, up to 8 n_ch */ -const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { +static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = { { .channels = 2, /* CA_ID 0x00 */ .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, { .channels = 4, /* CA_ID 0x01 */ @@ -326,7 +326,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) { int i; - const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { + static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = { [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR, [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC, }; @@ -340,7 +340,7 @@ static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc) return spk_mask; } -void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp) +static void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp) { u8 spk_alloc; unsigned long spk_mask; @@ -399,18 +399,6 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol, return 0; } - -static const struct snd_kcontrol_new hdmi_controls[] = { - { - .access = SNDRV_CTL_ELEM_ACCESS_READ | - SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "ELD", - .info = hdmi_eld_ctl_info, - .get = hdmi_eld_ctl_get, - }, -}; - static int hdmi_codec_new_stream(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -668,6 +656,16 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, { struct snd_soc_dai_driver *drv = dai->driver; struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + struct snd_kcontrol *kctl; + struct snd_kcontrol_new hdmi_eld_ctl = { + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "ELD", + .info = hdmi_eld_ctl_info, + .get = hdmi_eld_ctl_get, + .device = rtd->pcm->device, + }; int ret; dev_dbg(dai->dev, "%s()\n", __func__); @@ -686,14 +684,19 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; - return 0; + /* add ELD ctl with the device number corresponding to the PCM stream */ + kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component); + if (!kctl) + return -ENOMEM; + + return snd_ctl_add(rtd->card->snd_card, kctl); } -static struct snd_soc_dai_driver hdmi_i2s_dai = { +static const struct snd_soc_dai_driver hdmi_i2s_dai = { .name = "i2s-hifi", .id = DAI_ID_I2S, .playback = { - .stream_name = "Playback", + .stream_name = "I2S Playback", .channels_min = 2, .channels_max = 8, .rates = HDMI_RATES, @@ -708,7 +711,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { .name = "spdif-hifi", .id = DAI_ID_SPDIF, .playback = { - .stream_name = "Playback", + .stream_name = "SPDIF Playback", .channels_min = 2, .channels_max = 2, .rates = HDMI_RATES, @@ -730,10 +733,8 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component, return ret; } -static struct snd_soc_codec_driver hdmi_codec = { +static const struct snd_soc_codec_driver hdmi_codec = { .component_driver = { - .controls = hdmi_controls, - .num_controls = ARRAY_SIZE(hdmi_controls), .dapm_widgets = hdmi_widgets, .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), .dapm_routes = hdmi_routes, diff --git a/sound/soc/codecs/ics43432.c b/sound/soc/codecs/ics43432.c index dd850b93938d..651206273f36 100644 --- a/sound/soc/codecs/ics43432.c +++ b/sound/soc/codecs/ics43432.c @@ -37,7 +37,7 @@ static struct snd_soc_dai_driver ics43432_dai = { }, }; -static struct snd_soc_codec_driver ics43432_codec_driver = { +static const struct snd_soc_codec_driver ics43432_codec_driver = { }; static int ics43432_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/inno_rk3036.c b/sound/soc/codecs/inno_rk3036.c index b918ba5c8ce5..6b59b6f08298 100644 --- a/sound/soc/codecs/inno_rk3036.c +++ b/sound/soc/codecs/inno_rk3036.c @@ -310,7 +310,7 @@ static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream, SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops rk3036_codec_dai_ops = { +static const struct snd_soc_dai_ops rk3036_codec_dai_ops = { .set_fmt = rk3036_codec_dai_set_fmt, .hw_params = rk3036_codec_dai_hw_params, }; @@ -376,7 +376,7 @@ static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_codec_driver rk3036_codec_driver = { +static const struct snd_soc_codec_driver rk3036_codec_driver = { .probe = rk3036_codec_probe, .remove = rk3036_codec_remove, .set_bias_level = rk3036_codec_set_bias_level, diff --git a/sound/soc/codecs/inno_rk3036.h b/sound/soc/codecs/inno_rk3036.h index da759c6c7501..44bb2404198d 100644 --- a/sound/soc/codecs/inno_rk3036.h +++ b/sound/soc/codecs/inno_rk3036.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Driver of Inno Codec for rk3036 by Rockchip Inc. * diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c index a4b0eded984a..5ca99280ae00 100644 --- a/sound/soc/codecs/isabelle.c +++ b/sound/soc/codecs/isabelle.c @@ -1087,7 +1087,7 @@ static struct snd_soc_dai_driver isabelle_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_isabelle = { +static const struct snd_soc_codec_driver soc_codec_dev_isabelle = { .set_bias_level = isabelle_set_bias_level, .component_driver = { .controls = isabelle_snd_controls, diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 0290fab383da..6324ccdc8a5c 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -293,7 +293,7 @@ static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { +static const struct snd_soc_codec_driver soc_codec_dev_jz4740_codec = { .probe = jz4740_codec_dev_probe, .set_bias_level = jz4740_codec_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 558de1053f73..1e964079642a 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -100,7 +100,7 @@ static const struct snd_soc_dapm_route lm4857_routes[] = { { "EP", "Earpiece", "Mode" }, }; -static struct snd_soc_component_driver lm4857_component_driver = { +static const struct snd_soc_component_driver lm4857_component_driver = { .controls = lm4857_controls, .num_controls = ARRAY_SIZE(lm4857_controls), .dapm_widgets = lm4857_dapm_widgets, diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c index 8d413c2677cc..41e09d1287b8 100644 --- a/sound/soc/codecs/lm49453.c +++ b/sound/soc/codecs/lm49453.c @@ -1389,7 +1389,7 @@ static struct snd_soc_dai_driver lm49453_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { +static const struct snd_soc_codec_driver soc_codec_dev_lm49453 = { .set_bias_level = lm49453_set_bias_level, .component_driver = { .controls = lm49453_snd_controls, diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index 5b82e26cd5d1..7017c0389e73 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c @@ -151,7 +151,7 @@ static int max9768_probe(struct snd_soc_component *component) return 0; } -static struct snd_soc_component_driver max9768_component_driver = { +static const struct snd_soc_component_driver max9768_component_driver = { .probe = max9768_probe, .controls = max9768_volume, .num_controls = ARRAY_SIZE(max9768_volume), diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 72f77455582e..f0bb830874e5 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1698,7 +1698,7 @@ static int max98088_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max98088 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98088 = { .probe = max98088_probe, .remove = max98088_remove, .set_bias_level = max98088_set_bias_level, diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 66828480d484..13bcfb1ef9b4 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -2499,7 +2499,7 @@ static void max98090_seq_notifier(struct snd_soc_dapm_context *dapm, } } -static struct snd_soc_codec_driver soc_codec_dev_max98090 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98090 = { .probe = max98090_probe, .remove = max98090_remove, .seq_notifier = max98090_seq_notifier, diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 6f8a757876ed..5ead87d2ab1d 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -2102,7 +2102,7 @@ static int max98095_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max98095 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98095 = { .probe = max98095_probe, .remove = max98095_remove, .suspend = max98095_suspend, diff --git a/sound/soc/codecs/max98357a.c b/sound/soc/codecs/max98357a.c index 6a6b68a4cb52..426ed2dae6ca 100644 --- a/sound/soc/codecs/max98357a.c +++ b/sound/soc/codecs/max98357a.c @@ -72,7 +72,7 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver max98357a_codec_driver = { +static const struct snd_soc_codec_driver max98357a_codec_driver = { .probe = max98357a_codec_probe, .component_driver = { .dapm_widgets = max98357a_dapm_widgets, diff --git a/sound/soc/codecs/max98371.c b/sound/soc/codecs/max98371.c index 781be9ba8dba..7bc2a17c1e94 100644 --- a/sound/soc/codecs/max98371.c +++ b/sound/soc/codecs/max98371.c @@ -349,12 +349,14 @@ static struct snd_soc_dai_driver max98371_dai[] = { }; static const struct snd_soc_codec_driver max98371_codec = { - .controls = max98371_snd_controls, - .num_controls = ARRAY_SIZE(max98371_snd_controls), - .dapm_routes = max98371_audio_map, - .num_dapm_routes = ARRAY_SIZE(max98371_audio_map), - .dapm_widgets = max98371_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets), + .component_driver = { + .controls = max98371_snd_controls, + .num_controls = ARRAY_SIZE(max98371_snd_controls), + .dapm_routes = max98371_audio_map, + .num_dapm_routes = ARRAY_SIZE(max98371_audio_map), + .dapm_widgets = max98371_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets), + }, }; static const struct regmap_config max98371_regmap = { diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index 0610840733d1..a3dfc918c278 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -301,7 +301,7 @@ static int max9850_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max9850 = { +static const struct snd_soc_codec_driver soc_codec_dev_max9850 = { .probe = max9850_probe, .set_bias_level = max9850_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/max9860.c b/sound/soc/codecs/max9860.c index 499bdbfd0a2d..a2dc6a47f466 100644 --- a/sound/soc/codecs/max9860.c +++ b/sound/soc/codecs/max9860.c @@ -534,7 +534,7 @@ static int max9860_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_codec_driver max9860_codec_driver = { +static const struct snd_soc_codec_driver max9860_codec_driver = { .set_bias_level = max9860_set_bias_level, .idle_bias_off = true, diff --git a/sound/soc/codecs/max9867.c b/sound/soc/codecs/max9867.c index 2a40a69a7513..2f60924fe919 100644 --- a/sound/soc/codecs/max9867.c +++ b/sound/soc/codecs/max9867.c @@ -350,7 +350,7 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai, return 0; } -static struct snd_soc_dai_ops max9867_dai_ops = { +static const struct snd_soc_dai_ops max9867_dai_ops = { .set_fmt = max9867_dai_set_fmt, .set_sysclk = max9867_set_dai_sysclk, .prepare = max9867_prepare, @@ -413,7 +413,7 @@ static int max9867_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver max9867_codec = { +static const struct snd_soc_codec_driver max9867_codec = { .probe = max9867_probe, .component_driver = { .controls = max9867_snd_controls, diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 1eff7e0b092e..03d07bf4d942 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c @@ -213,8 +213,8 @@ static bool max98926_readable_register(struct device *dev, unsigned int reg) } }; -DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0); -DECLARE_TLV_DB_RANGE(max98926_current_tlv, +static DECLARE_TLV_DB_SCALE(max98926_spk_tlv, -600, 100, 0); +static DECLARE_TLV_DB_RANGE(max98926_current_tlv, 0, 11, TLV_DB_SCALE_ITEM(20, 20, 0), 12, 15, TLV_DB_SCALE_ITEM(320, 40, 0), ); @@ -459,7 +459,7 @@ static int max98926_dai_hw_params(struct snd_pcm_substream *substream, #define MAX98926_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops max98926_dai_ops = { +static const struct snd_soc_dai_ops max98926_dai_ops = { .set_fmt = max98926_dai_set_fmt, .hw_params = max98926_dai_hw_params, }; @@ -496,7 +496,7 @@ static int max98926_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_max98926 = { +static const struct snd_soc_codec_driver soc_codec_dev_max98926 = { .probe = max98926_probe, .component_driver = { .controls = max98926_snd_controls, diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index b5ee29499e16..d9dbbe72f8ad 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -44,9 +44,9 @@ static struct reg_default max98927_reg[] = { {MAX98927_R0011_CLK_MON, 0x00}, {MAX98927_R0012_WDOG_CTRL, 0x00}, {MAX98927_R0013_WDOG_RST, 0x00}, - {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x00}, - {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x00}, - {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x00}, + {MAX98927_R0014_MEAS_ADC_THERM_WARN_THRESH, 0x75}, + {MAX98927_R0015_MEAS_ADC_THERM_SHDN_THRESH, 0x8c}, + {MAX98927_R0016_MEAS_ADC_THERM_HYSTERESIS, 0x08}, {MAX98927_R0017_PIN_CFG, 0x55}, {MAX98927_R0018_PCM_RX_EN_A, 0x00}, {MAX98927_R0019_PCM_RX_EN_B, 0x00}, @@ -82,14 +82,14 @@ static struct reg_default max98927_reg[] = { {MAX98927_R003A_AMP_EN, 0x00}, {MAX98927_R003B_SPK_SRC_SEL, 0x00}, {MAX98927_R003C_SPK_GAIN, 0x00}, - {MAX98927_R003D_SSM_CFG, 0x01}, + {MAX98927_R003D_SSM_CFG, 0x04}, {MAX98927_R003E_MEAS_EN, 0x00}, {MAX98927_R003F_MEAS_DSP_CFG, 0x04}, {MAX98927_R0040_BOOST_CTRL0, 0x00}, {MAX98927_R0041_BOOST_CTRL3, 0x00}, {MAX98927_R0042_BOOST_CTRL1, 0x00}, {MAX98927_R0043_MEAS_ADC_CFG, 0x00}, - {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x00}, + {MAX98927_R0044_MEAS_ADC_BASE_MSB, 0x01}, {MAX98927_R0045_MEAS_ADC_BASE_LSB, 0x00}, {MAX98927_R0046_ADC_CH0_DIVIDE, 0x00}, {MAX98927_R0047_ADC_CH1_DIVIDE, 0x00}, @@ -159,7 +159,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) mode = MAX98927_PCM_MASTER_MODE_MASTER; break; default: - dev_err(codec->dev, "DAI clock mode unsupported"); + dev_err(codec->dev, "DAI clock mode unsupported\n"); return -EINVAL; } @@ -175,7 +175,7 @@ static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) invert = MAX98927_PCM_MODE_CFG_PCM_BCLKEDGE; break; default: - dev_err(codec->dev, "DAI invert mode unsupported"); + dev_err(codec->dev, "DAI invert mode unsupported\n"); return -EINVAL; } @@ -311,7 +311,7 @@ static int max98927_dai_hw_params(struct snd_pcm_substream *substream, chan_sz = MAX98927_PCM_MODE_CFG_CHANSZ_32; break; default: - dev_err(codec->dev, "format unsupported %d", + dev_err(codec->dev, "format unsupported %d\n", params_format(params)); goto err; } @@ -418,11 +418,6 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w, regmap_update_bits(max98927->regmap, MAX98927_R003A_AMP_EN, MAX98927_AMP_EN_MASK, 1); - /* enable VMON and IMON */ - regmap_update_bits(max98927->regmap, - MAX98927_R003E_MEAS_EN, - MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, - MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN); regmap_update_bits(max98927->regmap, MAX98927_R00FF_GLOBAL_SHDN, MAX98927_GLOBAL_EN_MASK, 1); @@ -434,10 +429,6 @@ static int max98927_dac_event(struct snd_soc_dapm_widget *w, regmap_update_bits(max98927->regmap, MAX98927_R003A_AMP_EN, MAX98927_AMP_EN_MASK, 0); - /* disable VMON and IMON */ - regmap_update_bits(max98927->regmap, - MAX98927_R003E_MEAS_EN, - MAX98927_MEAS_V_EN | MAX98927_MEAS_I_EN, 0); break; default: return 0; @@ -456,14 +447,24 @@ static const struct soc_enum dai_sel_enum = static const struct snd_kcontrol_new max98927_dai_controls = SOC_DAPM_ENUM("DAI Sel", dai_sel_enum); +static const struct snd_kcontrol_new max98927_vi_control = + SOC_DAPM_SINGLE("Switch", MAX98927_R003F_MEAS_DSP_CFG, 2, 1, 0); + static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = { - SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_R003A_AMP_EN, 0, 0, max98927_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0, &max98927_dai_controls), SND_SOC_DAPM_OUTPUT("BE_OUT"), + SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0, + MAX98927_R003E_MEAS_EN, 0, 0), + SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0, + MAX98927_R003E_MEAS_EN, 1, 0), + SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0, + &max98927_vi_control), + SND_SOC_DAPM_SIGGEN("VMON"), + SND_SOC_DAPM_SIGGEN("IMON"), }; static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0); @@ -495,6 +496,13 @@ static bool max98927_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case MAX98927_R0001_INT_RAW1 ... MAX98927_R0009_INT_FLAG3: + case MAX98927_R004C_MEAS_ADC_CH0_READ: + case MAX98927_R004D_MEAS_ADC_CH1_READ: + case MAX98927_R004E_MEAS_ADC_CH2_READ: + case MAX98927_R0051_BROWNOUT_STATUS: + case MAX98927_R0087_ENV_TRACK_BOOST_VOUT_READ: + case MAX98927_R01FF_REV_ID: + case MAX98927_R0100_SOFT_RESET: return true; default: return false; @@ -543,11 +551,16 @@ static const struct snd_kcontrol_new max98927_snd_controls[] = { }; static const struct snd_soc_dapm_route max98927_audio_map[] = { - {"Amp Enable", NULL, "DAI_OUT"}, + /* Plabyack */ {"DAI Sel Mux", "Left", "Amp Enable"}, {"DAI Sel Mux", "Right", "Amp Enable"}, {"DAI Sel Mux", "LeftRight", "Amp Enable"}, {"BE_OUT", NULL, "DAI Sel Mux"}, + /* Capture */ + { "VI Sense", "Switch", "VMON" }, + { "VI Sense", "Switch", "IMON" }, + { "Voltage Sense", NULL, "VI Sense" }, + { "Current Sense", NULL, "VI Sense" }, }; static struct snd_soc_dai_driver max98927_dai[] = { @@ -577,7 +590,6 @@ static int max98927_probe(struct snd_soc_codec *codec) max98927->codec = codec; codec->control_data = max98927->regmap; - codec->cache_bypass = 1; /* Software Reset */ regmap_write(max98927->regmap, @@ -694,6 +706,31 @@ static int max98927_probe(struct snd_soc_codec *codec) return 0; } +#ifdef CONFIG_PM_SLEEP +static int max98927_suspend(struct device *dev) +{ + struct max98927_priv *max98927 = dev_get_drvdata(dev); + + regcache_cache_only(max98927->regmap, true); + regcache_mark_dirty(max98927->regmap); + return 0; +} +static int max98927_resume(struct device *dev) +{ + struct max98927_priv *max98927 = dev_get_drvdata(dev); + + regmap_write(max98927->regmap, + MAX98927_R0100_SOFT_RESET, MAX98927_SOFT_RESET); + regcache_cache_only(max98927->regmap, false); + regcache_sync(max98927->regmap); + return 0; +} +#endif + +static const struct dev_pm_ops max98927_pm = { + SET_SYSTEM_SLEEP_PM_OPS(max98927_suspend, max98927_resume) +}; + static const struct snd_soc_codec_driver soc_codec_dev_max98927 = { .probe = max98927_probe, .component_driver = { @@ -721,14 +758,14 @@ static void max98927_slot_config(struct i2c_client *i2c, struct max98927_priv *max98927) { int value; + struct device *dev = &i2c->dev; - if (!of_property_read_u32(i2c->dev.of_node, - "vmon-slot-no", &value)) + if (!device_property_read_u32(dev, "vmon-slot-no", &value)) max98927->v_l_slot = value & 0xF; else max98927->v_l_slot = 0; - if (!of_property_read_u32(i2c->dev.of_node, - "imon-slot-no", &value)) + + if (!device_property_read_u32(dev, "imon-slot-no", &value)) max98927->i_l_slot = value & 0xF; else max98927->i_l_slot = 1; @@ -827,7 +864,7 @@ static struct i2c_driver max98927_i2c_driver = { .name = "max98927", .of_match_table = of_match_ptr(max98927_of_match), .acpi_match_table = ACPI_PTR(max98927_acpi_match), - .pm = NULL, + .pm = &max98927_pm, }, .probe = max98927_i2c_probe, .remove = max98927_i2c_remove, diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 90562703dcfd..4fd8d1dc4eef 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -733,7 +733,7 @@ static struct regmap *mc13783_get_regmap(struct device *dev) return dev_get_regmap(dev->parent, NULL); } -static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { +static const struct snd_soc_codec_driver soc_codec_dev_mc13783 = { .probe = mc13783_probe, .remove = mc13783_remove, .get_regmap = mc13783_get_regmap, diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c index 69e5e18880c5..5cc960d8211e 100644 --- a/sound/soc/codecs/ml26124.c +++ b/sound/soc/codecs/ml26124.c @@ -537,7 +537,7 @@ static int ml26124_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_ml26124 = { +static const struct snd_soc_codec_driver soc_codec_dev_ml26124 = { .probe = ml26124_probe, .set_bias_level = ml26124_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index 5710fd440bcd..549c269acc7d 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -12,9 +12,16 @@ #include #include #include +#include #define CDC_D_REVISION1 (0xf000) #define CDC_D_PERPH_SUBTYPE (0xf005) +#define CDC_D_INT_EN_SET (0x015) +#define CDC_D_INT_EN_CLR (0x016) +#define MBHC_SWITCH_INT BIT(7) +#define MBHC_MIC_ELECTRICAL_INS_REM_DET BIT(6) +#define MBHC_BUTTON_PRESS_DET BIT(5) +#define MBHC_BUTTON_RELEASE_DET BIT(4) #define CDC_D_CDC_RST_CTL (0xf046) #define RST_CTL_DIG_SW_RST_N_MASK BIT(7) #define RST_CTL_DIG_SW_RST_N_RESET 0 @@ -37,6 +44,8 @@ #define DIG_CLK_CTL_RXD1_CLK_EN BIT(0) #define DIG_CLK_CTL_RXD2_CLK_EN BIT(1) #define DIG_CLK_CTL_RXD3_CLK_EN BIT(2) +#define DIG_CLK_CTL_D_MBHC_CLK_EN_MASK BIT(3) +#define DIG_CLK_CTL_D_MBHC_CLK_EN BIT(3) #define DIG_CLK_CTL_TXD_CLK_EN BIT(4) #define DIG_CLK_CTL_NCP_CLK_EN_MASK BIT(6) #define DIG_CLK_CTL_NCP_CLK_EN BIT(6) @@ -93,8 +102,12 @@ #define MICB_1_EN_TX3_GND_SEL_TX_GND 0 #define CDC_A_MICB_1_VAL (0xf141) +#define MICB_MIN_VAL 1600 +#define MICB_STEP_SIZE 50 +#define MICB_VOLTAGE_REGVAL(v) ((v - MICB_MIN_VAL)/MICB_STEP_SIZE) #define MICB_1_VAL_MICB_OUT_VAL_MASK GENMASK(7, 3) #define MICB_1_VAL_MICB_OUT_VAL_V2P70V ((0x16) << 3) +#define MICB_1_VAL_MICB_OUT_VAL_V1P80V ((0x4) << 3) #define CDC_A_MICB_1_CTL (0xf142) #define MICB_1_CTL_CFILT_REF_SEL_MASK BIT(1) @@ -128,8 +141,51 @@ #define MICB_1_INT_TX3_INT_PULLUP_EN_TX1N_TO_GND 0 #define CDC_A_MICB_2_EN (0xf144) +#define CDC_A_MICB_2_EN_ENABLE BIT(7) +#define CDC_A_MICB_2_PULL_DOWN_EN_MASK BIT(5) +#define CDC_A_MICB_2_PULL_DOWN_EN BIT(5) #define CDC_A_TX_1_2_ATEST_CTL_2 (0xf145) #define CDC_A_MASTER_BIAS_CTL (0xf146) +#define CDC_A_MBHC_DET_CTL_1 (0xf147) +#define CDC_A_MBHC_DET_CTL_L_DET_EN BIT(7) +#define CDC_A_MBHC_DET_CTL_GND_DET_EN BIT(6) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION BIT(5) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_REMOVAL (0) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK BIT(5) +#define CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT (5) +#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO BIT(4) +#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MANUAL BIT(3) +#define CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_MASK GENMASK(4, 3) +#define CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN BIT(2) +#define CDC_A_MBHC_DET_CTL_2 (0xf150) +#define CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 (BIT(7) | BIT(6)) +#define CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD BIT(5) +#define CDC_A_PLUG_TYPE_MASK GENMASK(4, 3) +#define CDC_A_HPHL_PLUG_TYPE_NO BIT(4) +#define CDC_A_GND_PLUG_TYPE_NO BIT(3) +#define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN_MASK BIT(0) +#define CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN BIT(0) +#define CDC_A_MBHC_FSM_CTL (0xf151) +#define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN BIT(7) +#define CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK BIT(7) +#define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA (0x3 << 4) +#define CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK GENMASK(6, 4) +#define CDC_A_MBHC_DBNC_TIMER (0xf152) +#define CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS BIT(3) +#define CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS (0x9 << 4) +#define CDC_A_MBHC_BTN0_ZDET_CTL_0 (0xf153) +#define CDC_A_MBHC_BTN1_ZDET_CTL_1 (0xf154) +#define CDC_A_MBHC_BTN2_ZDET_CTL_2 (0xf155) +#define CDC_A_MBHC_BTN3_CTL (0xf156) +#define CDC_A_MBHC_BTN4_CTL (0xf157) +#define CDC_A_MBHC_BTN_VREF_FINE_SHIFT (2) +#define CDC_A_MBHC_BTN_VREF_FINE_MASK GENMASK(4, 2) +#define CDC_A_MBHC_BTN_VREF_COARSE_MASK GENMASK(7, 5) +#define CDC_A_MBHC_BTN_VREF_COARSE_SHIFT (5) +#define CDC_A_MBHC_BTN_VREF_MASK (CDC_A_MBHC_BTN_VREF_COARSE_MASK | \ + CDC_A_MBHC_BTN_VREF_FINE_MASK) +#define CDC_A_MBHC_RESULT_1 (0xf158) +#define CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK GENMASK(4, 0) #define CDC_A_TX_1_EN (0xf160) #define CDC_A_TX_2_EN (0xf161) #define CDC_A_TX_1_2_TEST_CTL_1 (0xf162) @@ -213,18 +269,37 @@ #define MSM8916_WCD_ANALOG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE) +static int btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4; +static int hs_jack_mask = SND_JACK_HEADPHONE | SND_JACK_HEADSET; + static const char * const supply_names[] = { "vdd-cdc-io", "vdd-cdc-tx-rx-cx", }; +#define MBHC_MAX_BUTTONS (5) + struct pm8916_wcd_analog_priv { u16 pmic_rev; u16 codec_version; + bool mbhc_btn_enabled; + /* special event to detect accessory type */ + bool mbhc_btn0_pressed; + bool detect_accessory_type; struct clk *mclk; + struct snd_soc_codec *codec; struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; + struct snd_soc_jack *jack; + bool hphl_jack_type_normally_open; + bool gnd_jack_type_normally_open; + /* Voltage threshold when internal current source of 100uA is used */ + u32 vref_btn_cs[MBHC_MAX_BUTTONS]; + /* Voltage threshold when microphone bias is ON */ + u32 vref_btn_micb[MBHC_MAX_BUTTONS]; unsigned int micbias1_cap_mode; unsigned int micbias2_cap_mode; + unsigned int micbias_mv; }; static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" }; @@ -265,18 +340,25 @@ static const struct snd_kcontrol_new pm8916_wcd_analog_snd_controls[] = { static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec) { + struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec); + snd_soc_update_bits(codec, CDC_A_MICB_1_CTL, MICB_1_CTL_EXT_PRECHARG_EN_MASK | MICB_1_CTL_INT_PRECHARG_BYP_MASK, MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL | MICB_1_CTL_EXT_PRECHARG_EN_ENABLE); - snd_soc_write(codec, CDC_A_MICB_1_VAL, MICB_1_VAL_MICB_OUT_VAL_V2P70V); - /* - * Special headset needs MICBIAS as 2.7V so wait for - * 50 msec for the MICBIAS to reach 2.7 volts. - */ - msleep(50); + if (wcd->micbias_mv) { + snd_soc_write(codec, CDC_A_MICB_1_VAL, + MICB_VOLTAGE_REGVAL(wcd->micbias_mv)); + /* + * Special headset needs MICBIAS as 2.7V so wait for + * 50 msec for the MICBIAS to reach 2.7 volts. + */ + if (wcd->micbias_mv >= 2700) + msleep(50); + } + snd_soc_update_bits(codec, CDC_A_MICB_1_CTL, MICB_1_CTL_EXT_PRECHARG_EN_MASK | MICB_1_CTL_INT_PRECHARG_BYP_MASK, 0); @@ -361,6 +443,97 @@ static int pm8916_wcd_analog_enable_micbias_int1(struct wcd->micbias1_cap_mode); } +static void pm8916_wcd_setup_mbhc(struct pm8916_wcd_analog_priv *wcd) +{ + struct snd_soc_codec *codec = wcd->codec; + u32 plug_type = 0; + u32 int_en_mask; + + snd_soc_write(codec, CDC_A_MBHC_DET_CTL_1, + CDC_A_MBHC_DET_CTL_L_DET_EN | + CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_INSERTION | + CDC_A_MBHC_DET_CTL_MIC_CLAMP_CTL_AUTO | + CDC_A_MBHC_DET_CTL_MBHC_BIAS_EN); + + if (wcd->hphl_jack_type_normally_open) + plug_type |= CDC_A_HPHL_PLUG_TYPE_NO; + + if (wcd->gnd_jack_type_normally_open) + plug_type |= CDC_A_GND_PLUG_TYPE_NO; + + snd_soc_write(codec, CDC_A_MBHC_DET_CTL_2, + CDC_A_MBHC_DET_CTL_HS_L_DET_PULL_UP_CTRL_I_3P0 | + CDC_A_MBHC_DET_CTL_HS_L_DET_COMPA_CTRL_V0P9_VDD | + plug_type | + CDC_A_MBHC_DET_CTL_HPHL_100K_TO_GND_EN); + + + snd_soc_write(codec, CDC_A_MBHC_DBNC_TIMER, + CDC_A_MBHC_DBNC_TIMER_INSREM_DBNC_T_256_MS | + CDC_A_MBHC_DBNC_TIMER_BTN_DBNC_T_16MS); + + /* enable MBHC clock */ + snd_soc_update_bits(codec, CDC_D_CDC_DIG_CLK_CTL, + DIG_CLK_CTL_D_MBHC_CLK_EN_MASK, + DIG_CLK_CTL_D_MBHC_CLK_EN); + + int_en_mask = MBHC_SWITCH_INT; + if (wcd->mbhc_btn_enabled) + int_en_mask |= MBHC_BUTTON_PRESS_DET | MBHC_BUTTON_RELEASE_DET; + + snd_soc_update_bits(codec, CDC_D_INT_EN_CLR, int_en_mask, 0); + snd_soc_update_bits(codec, CDC_D_INT_EN_SET, int_en_mask, int_en_mask); + wcd->mbhc_btn0_pressed = false; + wcd->detect_accessory_type = true; +} + +static int pm8916_mbhc_configure_bias(struct pm8916_wcd_analog_priv *priv, + bool micbias2_enabled) +{ + struct snd_soc_codec *codec = priv->codec; + u32 coarse, fine, reg_val, reg_addr; + int *vrefs, i; + + if (!micbias2_enabled) { /* use internal 100uA Current source */ + /* Enable internal 2.2k Internal Rbias Resistor */ + snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS, + MICB_1_INT_TX2_INT_RBIAS_EN_MASK, + MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE); + /* Remove pull down on MIC BIAS2 */ + snd_soc_update_bits(codec, CDC_A_MICB_2_EN, + CDC_A_MICB_2_PULL_DOWN_EN_MASK, + 0); + /* enable 100uA internal current source */ + snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL, + CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_MASK, + CDC_A_MBHC_FSM_CTL_BTN_ISRC_CTRL_I_100UA); + } + snd_soc_update_bits(codec, CDC_A_MBHC_FSM_CTL, + CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN_MASK, + CDC_A_MBHC_FSM_CTL_MBHC_FSM_EN); + + if (micbias2_enabled) + vrefs = &priv->vref_btn_micb[0]; + else + vrefs = &priv->vref_btn_cs[0]; + + /* program vref ranges for all the buttons */ + reg_addr = CDC_A_MBHC_BTN0_ZDET_CTL_0; + for (i = 0; i < MBHC_MAX_BUTTONS; i++) { + /* split mv in to coarse parts of 100mv & fine parts of 12mv */ + coarse = (vrefs[i] / 100); + fine = ((vrefs[i] % 100) / 12); + reg_val = (coarse << CDC_A_MBHC_BTN_VREF_COARSE_SHIFT) | + (fine << CDC_A_MBHC_BTN_VREF_FINE_SHIFT); + snd_soc_update_bits(codec, reg_addr, + CDC_A_MBHC_BTN_VREF_MASK, + reg_val); + reg_addr++; + } + + return 0; +} + static int pm8916_wcd_analog_enable_micbias_int2(struct snd_soc_dapm_widget *w, struct snd_kcontrol @@ -369,6 +542,15 @@ static int pm8916_wcd_analog_enable_micbias_int2(struct struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec); + switch (event) { + case SND_SOC_DAPM_POST_PMU: + pm8916_mbhc_configure_bias(wcd, true); + break; + case SND_SOC_DAPM_POST_PMD: + pm8916_mbhc_configure_bias(wcd, false); + break; + } + return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg, wcd->micbias2_cap_mode); } @@ -536,6 +718,14 @@ static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec) snd_soc_write(codec, wcd_reg_defaults_2_0[reg].reg, wcd_reg_defaults_2_0[reg].def); + priv->codec = codec; + + snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL, + RST_CTL_DIG_SW_RST_N_MASK, + RST_CTL_DIG_SW_RST_N_REMOVE_RESET); + + pm8916_wcd_setup_mbhc(priv); + return 0; } @@ -543,6 +733,9 @@ static int pm8916_wcd_analog_remove(struct snd_soc_codec *codec) { struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev); + snd_soc_update_bits(codec, CDC_D_CDC_RST_CTL, + RST_CTL_DIG_SW_RST_N_MASK, 0); + return regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); } @@ -731,32 +924,128 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("A_MCLK2", CDC_D_CDC_TOP_CLK_CTL, 3, 0, NULL, 0), }; +static int pm8916_wcd_analog_set_jack(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, + void *data) +{ + struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec); + + wcd->jack = jack; + + return 0; +} + static struct regmap *pm8916_get_regmap(struct device *dev) { return dev_get_regmap(dev->parent, NULL); } -static int pm8916_wcd_analog_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) +static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg) { - snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL, - RST_CTL_DIG_SW_RST_N_MASK, - RST_CTL_DIG_SW_RST_N_REMOVE_RESET); + struct pm8916_wcd_analog_priv *priv = arg; - return 0; + if (priv->detect_accessory_type) { + struct snd_soc_codec *codec = priv->codec; + u32 val = snd_soc_read(codec, CDC_A_MBHC_RESULT_1); + + /* check if its BTN0 thats released */ + if ((val != -1) && !(val & CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK)) + priv->mbhc_btn0_pressed = false; + + } else { + snd_soc_jack_report(priv->jack, 0, btn_mask); + } + + return IRQ_HANDLED; } -static void pm8916_wcd_analog_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) +static irqreturn_t mbhc_btn_press_irq_handler(int irq, void *arg) { - snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL, - RST_CTL_DIG_SW_RST_N_MASK, 0); + struct pm8916_wcd_analog_priv *priv = arg; + struct snd_soc_codec *codec = priv->codec; + u32 btn_result; + + btn_result = snd_soc_read(codec, CDC_A_MBHC_RESULT_1) & + CDC_A_MBHC_RESULT_1_BTN_RESULT_MASK; + + switch (btn_result) { + case 0xf: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_4, btn_mask); + break; + case 0x7: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_3, btn_mask); + break; + case 0x3: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_2, btn_mask); + break; + case 0x1: + snd_soc_jack_report(priv->jack, SND_JACK_BTN_1, btn_mask); + break; + case 0x0: + /* handle BTN_0 specially for type detection */ + if (priv->detect_accessory_type) + priv->mbhc_btn0_pressed = true; + else + snd_soc_jack_report(priv->jack, + SND_JACK_BTN_0, btn_mask); + break; + default: + dev_err(codec->dev, + "Unexpected button press result (%x)", btn_result); + break; + } + + return IRQ_HANDLED; } -static struct snd_soc_dai_ops pm8916_wcd_analog_dai_ops = { - .startup = pm8916_wcd_analog_startup, - .shutdown = pm8916_wcd_analog_shutdown, -}; +static irqreturn_t pm8916_mbhc_switch_irq_handler(int irq, void *arg) +{ + struct pm8916_wcd_analog_priv *priv = arg; + struct snd_soc_codec *codec = priv->codec; + bool ins = false; + + if (snd_soc_read(codec, CDC_A_MBHC_DET_CTL_1) & + CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK) + ins = true; + + /* Set the detection type appropriately */ + snd_soc_update_bits(codec, CDC_A_MBHC_DET_CTL_1, + CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_MASK, + (!ins << CDC_A_MBHC_DET_CTL_MECH_DET_TYPE_SHIFT)); + + + if (ins) { /* hs insertion */ + bool micbias_enabled = false; + + if (snd_soc_read(codec, CDC_A_MICB_2_EN) & + CDC_A_MICB_2_EN_ENABLE) + micbias_enabled = true; + + pm8916_mbhc_configure_bias(priv, micbias_enabled); + + /* + * if only a btn0 press event is receive just before + * insert event then its a 3 pole headphone else if + * both press and release event received then its + * a headset. + */ + if (priv->mbhc_btn0_pressed) + snd_soc_jack_report(priv->jack, + SND_JACK_HEADPHONE, hs_jack_mask); + else + snd_soc_jack_report(priv->jack, + SND_JACK_HEADSET, hs_jack_mask); + + priv->detect_accessory_type = false; + + } else { /* removal */ + snd_soc_jack_report(priv->jack, 0, hs_jack_mask); + priv->detect_accessory_type = true; + priv->mbhc_btn0_pressed = false; + } + + return IRQ_HANDLED; +} static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = { [0] = { @@ -769,7 +1058,6 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = { .channels_min = 1, .channels_max = 3, }, - .ops = &pm8916_wcd_analog_dai_ops, }, [1] = { .name = "pm8916_wcd_analog_pdm_tx", @@ -781,13 +1069,13 @@ static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = { .channels_min = 1, .channels_max = 4, }, - .ops = &pm8916_wcd_analog_dai_ops, }, }; -static struct snd_soc_codec_driver pm8916_wcd_analog = { +static const struct snd_soc_codec_driver pm8916_wcd_analog = { .probe = pm8916_wcd_analog_probe, .remove = pm8916_wcd_analog_remove, + .set_jack = pm8916_wcd_analog_set_jack, .get_regmap = pm8916_get_regmap, .component_driver = { .controls = pm8916_wcd_analog_snd_controls, @@ -802,6 +1090,7 @@ static struct snd_soc_codec_driver pm8916_wcd_analog = { static int pm8916_wcd_analog_parse_dt(struct device *dev, struct pm8916_wcd_analog_priv *priv) { + int rval; if (of_property_read_bool(dev->of_node, "qcom,micbias1-ext-cap")) priv->micbias1_cap_mode = MICB_1_EN_EXT_BYP_CAP; @@ -813,6 +1102,42 @@ static int pm8916_wcd_analog_parse_dt(struct device *dev, else priv->micbias2_cap_mode = MICB_1_EN_NO_EXT_BYP_CAP; + of_property_read_u32(dev->of_node, "qcom,micbias-lvl", + &priv->micbias_mv); + + if (of_property_read_bool(dev->of_node, + "qcom,hphl-jack-type-normally-open")) + priv->hphl_jack_type_normally_open = true; + else + priv->hphl_jack_type_normally_open = false; + + if (of_property_read_bool(dev->of_node, + "qcom,gnd-jack-type-normally-open")) + priv->gnd_jack_type_normally_open = true; + else + priv->gnd_jack_type_normally_open = false; + + priv->mbhc_btn_enabled = true; + rval = of_property_read_u32_array(dev->of_node, + "qcom,mbhc-vthreshold-low", + &priv->vref_btn_cs[0], + MBHC_MAX_BUTTONS); + if (rval < 0) { + priv->mbhc_btn_enabled = false; + } else { + rval = of_property_read_u32_array(dev->of_node, + "qcom,mbhc-vthreshold-high", + &priv->vref_btn_micb[0], + MBHC_MAX_BUTTONS); + if (rval < 0) + priv->mbhc_btn_enabled = false; + } + + if (!priv->mbhc_btn_enabled) + dev_err(dev, + "DT property missing, MBHC btn detection disabled\n"); + + return 0; } @@ -820,7 +1145,7 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) { struct pm8916_wcd_analog_priv *priv; struct device *dev = &pdev->dev; - int ret, i; + int ret, i, irq; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -852,6 +1177,48 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev) return ret; } + irq = platform_get_irq_byname(pdev, "mbhc_switch_int"); + if (irq < 0) { + dev_err(dev, "failed to get mbhc switch irq\n"); + return irq; + } + + ret = devm_request_irq(dev, irq, pm8916_mbhc_switch_irq_handler, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + "mbhc switch irq", priv); + if (ret) + dev_err(dev, "cannot request mbhc switch irq\n"); + + if (priv->mbhc_btn_enabled) { + irq = platform_get_irq_byname(pdev, "mbhc_but_press_det"); + if (irq < 0) { + dev_err(dev, "failed to get button press irq\n"); + return irq; + } + + ret = devm_request_irq(dev, irq, mbhc_btn_press_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "mbhc btn press irq", priv); + if (ret) + dev_err(dev, "cannot request mbhc button press irq\n"); + + irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det"); + if (irq < 0) { + dev_err(dev, "failed to get button release irq\n"); + return irq; + } + + ret = devm_request_irq(dev, irq, mbhc_btn_release_irq_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "mbhc btn release irq", priv); + if (ret) + dev_err(dev, "cannot request mbhc button release irq\n"); + + } + dev_set_drvdata(dev, priv); return snd_soc_register_codec(dev, &pm8916_wcd_analog, diff --git a/sound/soc/codecs/msm8916-wcd-digital.c b/sound/soc/codecs/msm8916-wcd-digital.c index f690442af8c9..66df8f810f0d 100644 --- a/sound/soc/codecs/msm8916-wcd-digital.c +++ b/sound/soc/codecs/msm8916-wcd-digital.c @@ -218,6 +218,8 @@ static const char *const rx_mix1_text[] = { static const char *const dec_mux_text[] = { "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2" }; + +static const char *const cic_mux_text[] = { "AMIC", "DMIC" }; static const char *const rx_mix2_text[] = { "ZERO", "IIR1", "IIR2" }; static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" }; @@ -256,11 +258,21 @@ static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE( static const struct soc_enum dec2_mux_enum = SOC_ENUM_SINGLE( LPASS_CDC_CONN_TX_B1_CTL, 3, 6, dec_mux_text); +/* CIC */ +static const struct soc_enum cic1_mux_enum = SOC_ENUM_SINGLE( + LPASS_CDC_TX1_MUX_CTL, 0, 2, cic_mux_text); +static const struct soc_enum cic2_mux_enum = SOC_ENUM_SINGLE( + LPASS_CDC_TX2_MUX_CTL, 0, 2, cic_mux_text); + /* RDAC2 MUX */ static const struct snd_kcontrol_new dec1_mux = SOC_DAPM_ENUM( "DEC1 MUX Mux", dec1_mux_enum); static const struct snd_kcontrol_new dec2_mux = SOC_DAPM_ENUM( "DEC2 MUX Mux", dec2_mux_enum); +static const struct snd_kcontrol_new cic1_mux = SOC_DAPM_ENUM( + "CIC1 MUX Mux", cic1_mux_enum); +static const struct snd_kcontrol_new cic2_mux = SOC_DAPM_ENUM( + "CIC2 MUX Mux", cic2_mux_enum); static const struct snd_kcontrol_new rx_mix1_inp1_mux = SOC_DAPM_ENUM( "RX1 MIX1 INP1 Mux", rx_mix1_inp_enum[0]); static const struct snd_kcontrol_new rx_mix1_inp2_mux = SOC_DAPM_ENUM( @@ -500,6 +512,8 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = { SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, &rx3_mix1_inp3_mux), + SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux), + SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux), /* TX */ SND_SOC_DAPM_MIXER("ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), @@ -536,6 +550,8 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = { /* Connectivity Clock */ SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, LPASS_CDC_CLK_OTHR_CTL, 2, 0, NULL, 0), + SND_SOC_DAPM_MIC("Digital Mic1", NULL), + SND_SOC_DAPM_MIC("Digital Mic2", NULL), }; @@ -568,6 +584,15 @@ static int msm8916_wcd_digital_codec_probe(struct snd_soc_codec *codec) return 0; } +static int msm8916_wcd_digital_codec_set_sysclk(struct snd_soc_codec *codec, + int clk_id, int source, + unsigned int freq, int dir) +{ + struct msm8916_wcd_digital_priv *p = dev_get_drvdata(codec->dev); + + return clk_set_rate(p->mclk, freq); +} + static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -646,6 +671,11 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = { {"AIF1 Capture", NULL, "I2S TX2"}, {"AIF1 Capture", NULL, "I2S TX3"}, + {"CIC1 MUX", "DMIC", "DEC1 MUX"}, + {"CIC1 MUX", "AMIC", "DEC1 MUX"}, + {"CIC2 MUX", "DMIC", "DEC2 MUX"}, + {"CIC2 MUX", "AMIC", "DEC2 MUX"}, + /* Decimator Inputs */ {"DEC1 MUX", "DMIC1", "DMIC1"}, {"DEC1 MUX", "DMIC2", "DMIC2"}, @@ -664,8 +694,8 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = { {"DMIC1", NULL, "DMIC_CLK"}, {"DMIC2", NULL, "DMIC_CLK"}, - {"I2S TX1", NULL, "DEC1 MUX"}, - {"I2S TX2", NULL, "DEC2 MUX"}, + {"I2S TX1", NULL, "CIC1 MUX"}, + {"I2S TX2", NULL, "CIC2 MUX"}, {"I2S TX1", NULL, "TX_I2S_CLK"}, {"I2S TX2", NULL, "TX_I2S_CLK"}, @@ -788,7 +818,7 @@ static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream, LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0); } -static struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = { +static const struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = { .startup = msm8916_wcd_digital_startup, .shutdown = msm8916_wcd_digital_shutdown, .hw_params = msm8916_wcd_digital_hw_params, @@ -821,8 +851,9 @@ static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = { }, }; -static struct snd_soc_codec_driver msm8916_wcd_digital = { +static const struct snd_soc_codec_driver msm8916_wcd_digital = { .probe = msm8916_wcd_digital_codec_probe, + .set_sysclk = msm8916_wcd_digital_codec_set_sysclk, .component_driver = { .controls = msm8916_wcd_digital_snd_controls, .num_controls = ARRAY_SIZE(msm8916_wcd_digital_snd_controls), diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index c8bcb1db966d..f9c9933acffb 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c @@ -735,7 +735,7 @@ static int __maybe_unused nau8540_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver nau8540_codec_driver = { +static const struct snd_soc_codec_driver nau8540_codec_driver = { .set_sysclk = nau8540_set_sysclk, .set_pll = nau8540_set_pll, .suspend = nau8540_suspend, diff --git a/sound/soc/codecs/nau8810.c b/sound/soc/codecs/nau8810.c index e45518629968..c8e2451ae0a3 100644 --- a/sound/soc/codecs/nau8810.c +++ b/sound/soc/codecs/nau8810.c @@ -808,7 +808,7 @@ static const struct regmap_config nau8810_regmap_config = { .num_reg_defaults = ARRAY_SIZE(nau8810_reg_defaults), }; -static struct snd_soc_codec_driver nau8810_codec_driver = { +static const struct snd_soc_codec_driver nau8810_codec_driver = { .set_bias_level = nau8810_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 3a309b18035e..0240759f951c 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -1469,7 +1469,7 @@ static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver nau8824_codec_driver = { +static const struct snd_soc_codec_driver nau8824_codec_driver = { .probe = nau8824_codec_probe, .set_sysclk = nau8824_set_sysclk, .set_pll = nau8824_set_pll, diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index 46a30eaa7ace..714ce17da717 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c @@ -260,11 +260,11 @@ static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout) if (timeout) { ret = down_timeout(&nau8825->xtalk_sem, timeout); if (ret < 0) - dev_warn(nau8825->dev, "Acquire semaphone timeout\n"); + dev_warn(nau8825->dev, "Acquire semaphore timeout\n"); } else { ret = down_interruptible(&nau8825->xtalk_sem); if (ret < 0) - dev_warn(nau8825->dev, "Acquire semaphone fail\n"); + dev_warn(nau8825->dev, "Acquire semaphore fail\n"); } return ret; @@ -1299,7 +1299,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1, NAU8825_I2S_DL_MASK, val_len); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); return 0; @@ -1361,7 +1361,7 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, NAU8825_I2S_MS_MASK, ctrl2_val); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); return 0; @@ -2140,7 +2140,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_MCLK: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2150,7 +2150,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, /* MCLK not changed by clock tree */ regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER, NAU8825_CLK_MCLK_SRC_MASK, 0); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); ret = nau8825_mclk_prepare(nau8825, freq); @@ -2188,7 +2188,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_FLL_MCLK: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2201,7 +2201,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, regmap_update_bits(regmap, NAU8825_REG_FLL3, NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK, NAU8825_FLL_CLK_SRC_MCLK | 0); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); ret = nau8825_mclk_prepare(nau8825, freq); @@ -2210,7 +2210,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_FLL_BLK: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2226,7 +2226,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK, NAU8825_FLL_CLK_SRC_BLK | (0xf << NAU8825_GAIN_ERR_SFT)); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); if (nau8825->mclk_freq) { @@ -2236,7 +2236,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, break; case NAU8825_CLK_FLL_FS: - /* Acquire the semaphone to synchronize the playback and + /* Acquire the semaphore to synchronize the playback and * interrupt handler. In order to avoid the playback inter- * fered by cross talk process, the driver make the playback * preparation halted until cross talk process finish. @@ -2252,7 +2252,7 @@ static int nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK, NAU8825_FLL_CLK_SRC_FS | (0xf << NAU8825_GAIN_ERR_SFT)); - /* Release the semaphone. */ + /* Release the semaphore. */ nau8825_sema_release(nau8825); if (nau8825->mclk_freq) { @@ -2388,7 +2388,7 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver nau8825_codec_driver = { +static const struct snd_soc_codec_driver nau8825_codec_driver = { .probe = nau8825_codec_probe, .remove = nau8825_codec_remove, .set_sysclk = nau8825_set_sysclk, @@ -2563,7 +2563,7 @@ static int nau8825_i2c_probe(struct i2c_client *i2c, return PTR_ERR(nau8825->regmap); nau8825->dev = dev; nau8825->irq = i2c->irq; - /* Initiate parameters, semaphone and work queue which are needed in + /* Initiate parameters, semaphore and work queue which are needed in * cross talk suppression measurment function. */ nau8825->xtalk_state = NAU8825_XTALK_DONE; diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index 0b14efab6280..c7e28dd2e815 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -288,7 +288,7 @@ static const struct regmap_config pcm1681_regmap = { .readable_reg = pcm1681_accessible_reg, }; -static struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { +static const struct snd_soc_codec_driver soc_codec_dev_pcm1681 = { .component_driver = { .controls = pcm1681_controls, .num_controls = ARRAY_SIZE(pcm1681_controls), diff --git a/sound/soc/codecs/pcm179x.c b/sound/soc/codecs/pcm179x.c index b813a154ddd9..82a3d9db32cb 100644 --- a/sound/soc/codecs/pcm179x.c +++ b/sound/soc/codecs/pcm179x.c @@ -205,7 +205,7 @@ const struct regmap_config pcm179x_regmap_config = { }; EXPORT_SYMBOL_GPL(pcm179x_regmap_config); -static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { +static const struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .component_driver = { .controls = pcm179x_controls, .num_controls = ARRAY_SIZE(pcm179x_controls), diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 708af05486f6..e59d8ffb93bd 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -98,7 +98,7 @@ static struct snd_soc_dai_driver pcm3008_dai = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { +static const struct snd_soc_codec_driver soc_codec_dev_pcm3008 = { .component_driver = { .dapm_widgets = pcm3008_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(pcm3008_dapm_widgets), diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 72b19e62f626..68feae262476 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -30,9 +30,6 @@ #include "pcm512x.h" -#define DIV_ROUND_DOWN_ULL(ll, d) \ - ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) - #define PCM512x_NUM_SUPPLIES 3 static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = { "AVDD", @@ -1344,7 +1341,7 @@ static struct snd_soc_dai_driver pcm512x_dai = { .ops = &pcm512x_dai_ops, }; -static struct snd_soc_codec_driver pcm512x_codec_driver = { +static const struct snd_soc_codec_driver pcm512x_codec_driver = { .set_bias_level = pcm512x_set_bias_level, .idle_bias_off = true, diff --git a/sound/soc/codecs/rt274.c b/sound/soc/codecs/rt274.c new file mode 100644 index 000000000000..8f92e5c4dd9d --- /dev/null +++ b/sound/soc/codecs/rt274.c @@ -0,0 +1,1229 @@ +/* + * rt274.c -- RT274 ALSA SoC audio codec driver + * + * Copyright 2017 Realtek Semiconductor Corp. + * Author: Bard Liao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rl6347a.h" +#include "rt274.h" + +#define RT274_VENDOR_ID 0x10ec0274 + +struct rt274_priv { + struct reg_default *index_cache; + int index_cache_size; + struct regmap *regmap; + struct snd_soc_codec *codec; + struct i2c_client *i2c; + struct snd_soc_jack *jack; + struct delayed_work jack_detect_work; + int sys_clk; + int clk_id; + int fs; + bool master; +}; + +static const struct reg_default rt274_index_def[] = { + { 0x00, 0x1004 }, + { 0x01, 0xaaaa }, + { 0x02, 0x88aa }, + { 0x03, 0x0002 }, + { 0x04, 0xaa09 }, + { 0x05, 0x0700 }, + { 0x06, 0x6110 }, + { 0x07, 0x0200 }, + { 0x08, 0xa807 }, + { 0x09, 0x0021 }, + { 0x0a, 0x7770 }, + { 0x0b, 0x7770 }, + { 0x0c, 0x002b }, + { 0x0d, 0x2420 }, + { 0x0e, 0x65c0 }, + { 0x0f, 0x7770 }, + { 0x10, 0x0420 }, + { 0x11, 0x7418 }, + { 0x12, 0x6bd0 }, + { 0x13, 0x645f }, + { 0x14, 0x0400 }, + { 0x15, 0x8ccc }, + { 0x16, 0x4c50 }, + { 0x17, 0xff00 }, + { 0x18, 0x0003 }, + { 0x19, 0x2c11 }, + { 0x1a, 0x830b }, + { 0x1b, 0x4e4b }, + { 0x1c, 0x0000 }, + { 0x1d, 0x0000 }, + { 0x1e, 0x0000 }, + { 0x1f, 0x0000 }, + { 0x20, 0x51ff }, + { 0x21, 0x8000 }, + { 0x22, 0x8f00 }, + { 0x23, 0x88f4 }, + { 0x24, 0x0000 }, + { 0x25, 0x0000 }, + { 0x26, 0x0000 }, + { 0x27, 0x0000 }, + { 0x28, 0x0000 }, + { 0x29, 0x3000 }, + { 0x2a, 0x0000 }, + { 0x2b, 0x0000 }, + { 0x2c, 0x0f00 }, + { 0x2d, 0x100f }, + { 0x2e, 0x2902 }, + { 0x2f, 0xe280 }, + { 0x30, 0x1000 }, + { 0x31, 0x8400 }, + { 0x32, 0x5aaa }, + { 0x33, 0x8420 }, + { 0x34, 0xa20c }, + { 0x35, 0x096a }, + { 0x36, 0x5757 }, + { 0x37, 0xfe05 }, + { 0x38, 0x4901 }, + { 0x39, 0x110a }, + { 0x3a, 0x0010 }, + { 0x3b, 0x60d9 }, + { 0x3c, 0xf214 }, + { 0x3d, 0xc2ba }, + { 0x3e, 0xa928 }, + { 0x3f, 0x0000 }, + { 0x40, 0x9800 }, + { 0x41, 0x0000 }, + { 0x42, 0x2000 }, + { 0x43, 0x3d90 }, + { 0x44, 0x4900 }, + { 0x45, 0x5289 }, + { 0x46, 0x0004 }, + { 0x47, 0xa47a }, + { 0x48, 0xd049 }, + { 0x49, 0x0049 }, + { 0x4a, 0xa83b }, + { 0x4b, 0x0777 }, + { 0x4c, 0x065c }, + { 0x4d, 0x7fff }, + { 0x4e, 0x7fff }, + { 0x4f, 0x0000 }, + { 0x50, 0x0000 }, + { 0x51, 0x0000 }, + { 0x52, 0xbf5f }, + { 0x53, 0x3320 }, + { 0x54, 0xcc00 }, + { 0x55, 0x0000 }, + { 0x56, 0x3f00 }, + { 0x57, 0x0000 }, + { 0x58, 0x0000 }, + { 0x59, 0x0000 }, + { 0x5a, 0x1300 }, + { 0x5b, 0x005f }, + { 0x5c, 0x0000 }, + { 0x5d, 0x1001 }, + { 0x5e, 0x1000 }, + { 0x5f, 0x0000 }, + { 0x60, 0x5554 }, + { 0x61, 0xffc0 }, + { 0x62, 0xa000 }, + { 0x63, 0xd010 }, + { 0x64, 0x0000 }, + { 0x65, 0x3fb1 }, + { 0x66, 0x1881 }, + { 0x67, 0xc810 }, + { 0x68, 0x2000 }, + { 0x69, 0xfff0 }, + { 0x6a, 0x0300 }, + { 0x6b, 0x5060 }, + { 0x6c, 0x0000 }, + { 0x6d, 0x0000 }, + { 0x6e, 0x0c25 }, + { 0x6f, 0x0c0b }, + { 0x70, 0x8000 }, + { 0x71, 0x4008 }, + { 0x72, 0x0000 }, + { 0x73, 0x0800 }, + { 0x74, 0xa28f }, + { 0x75, 0xa050 }, + { 0x76, 0x7fe8 }, + { 0x77, 0xdb8c }, + { 0x78, 0x0000 }, + { 0x79, 0x0000 }, + { 0x7a, 0x2a96 }, + { 0x7b, 0x800f }, + { 0x7c, 0x0200 }, + { 0x7d, 0x1600 }, + { 0x7e, 0x0000 }, + { 0x7f, 0x0000 }, +}; +#define INDEX_CACHE_SIZE ARRAY_SIZE(rt274_index_def) + +static const struct reg_default rt274_reg[] = { + { 0x00170500, 0x00000400 }, + { 0x00220000, 0x00000031 }, + { 0x00239000, 0x00000057 }, + { 0x0023a000, 0x00000057 }, + { 0x00270500, 0x00000400 }, + { 0x00370500, 0x00000400 }, + { 0x00870500, 0x00000400 }, + { 0x00920000, 0x00000031 }, + { 0x00935000, 0x00000097 }, + { 0x00936000, 0x00000097 }, + { 0x00970500, 0x00000400 }, + { 0x00b37000, 0x00000400 }, + { 0x00b37200, 0x00000400 }, + { 0x00b37300, 0x00000400 }, + { 0x00c37000, 0x00000400 }, + { 0x00c37100, 0x00000400 }, + { 0x01270500, 0x00000400 }, + { 0x01370500, 0x00000400 }, + { 0x01371f00, 0x411111f0 }, + { 0x01937000, 0x00000000 }, + { 0x01970500, 0x00000400 }, + { 0x02050000, 0x0000001b }, + { 0x02139000, 0x00000080 }, + { 0x0213a000, 0x00000080 }, + { 0x02170100, 0x00000001 }, + { 0x02170500, 0x00000400 }, + { 0x02170700, 0x00000000 }, + { 0x02270100, 0x00000000 }, + { 0x02370100, 0x00000000 }, + { 0x01970700, 0x00000020 }, + { 0x00830000, 0x00000097 }, + { 0x00930000, 0x00000097 }, + { 0x01270700, 0x00000000 }, +}; + +static bool rt274_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0 ... 0xff: + case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): + case RT274_GET_HP_SENSE: + case RT274_GET_MIC_SENSE: + case RT274_PROC_COEF: + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0): + return true; + default: + return false; + } + + +} + +static bool rt274_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0 ... 0xff: + case RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): + case RT274_GET_HP_SENSE: + case RT274_GET_MIC_SENSE: + case RT274_SET_AUDIO_POWER: + case RT274_SET_HPO_POWER: + case RT274_SET_DMIC1_POWER: + case RT274_LOUT_MUX: + case RT274_HPO_MUX: + case RT274_ADC0_MUX: + case RT274_ADC1_MUX: + case RT274_SET_MIC: + case RT274_SET_PIN_HPO: + case RT274_SET_PIN_LOUT3: + case RT274_SET_PIN_DMIC1: + case RT274_SET_AMP_GAIN_HPO: + case RT274_SET_DMIC2_DEFAULT: + case RT274_DAC0L_GAIN: + case RT274_DAC0R_GAIN: + case RT274_DAC1L_GAIN: + case RT274_DAC1R_GAIN: + case RT274_ADCL_GAIN: + case RT274_ADCR_GAIN: + case RT274_MIC_GAIN: + case RT274_HPOL_GAIN: + case RT274_HPOR_GAIN: + case RT274_LOUTL_GAIN: + case RT274_LOUTR_GAIN: + case RT274_DAC_FORMAT: + case RT274_ADC_FORMAT: + case RT274_COEF_INDEX: + case RT274_PROC_COEF: + case RT274_SET_AMP_GAIN_ADC_IN1: + case RT274_SET_AMP_GAIN_ADC_IN2: + case RT274_SET_POWER(RT274_DAC_OUT0): + case RT274_SET_POWER(RT274_DAC_OUT1): + case RT274_SET_POWER(RT274_ADC_IN1): + case RT274_SET_POWER(RT274_ADC_IN2): + case RT274_SET_POWER(RT274_DMIC2): + case RT274_SET_POWER(RT274_MIC): + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_STREAM_FORMAT, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_AMP_GAIN_MUTE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN1, 0): + case VERB_CMD(AC_VERB_GET_CONNECT_SEL, RT274_MIXER_IN2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_DMIC2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE1, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_LINE2, 0): + case VERB_CMD(AC_VERB_GET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_HP_OUT, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_MIC, 0): + case VERB_CMD(AC_VERB_GET_UNSOLICITED_RESPONSE, RT274_INLINE_CMD, 0): + return true; + default: + return false; + } +} + +#ifdef CONFIG_PM +static void rt274_index_sync(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + int i; + + for (i = 0; i < INDEX_CACHE_SIZE; i++) { + snd_soc_write(codec, rt274->index_cache[i].reg, + rt274->index_cache[i].def); + } +} +#endif + +static int rt274_jack_detect(struct rt274_priv *rt274, bool *hp, bool *mic) +{ + unsigned int buf; + + *hp = false; + *mic = false; + + if (!rt274->codec) + return -EINVAL; + + regmap_read(rt274->regmap, RT274_GET_HP_SENSE, &buf); + *hp = buf & 0x80000000; + regmap_read(rt274->regmap, RT274_GET_MIC_SENSE, &buf); + *mic = buf & 0x80000000; + + pr_debug("*hp = %d *mic = %d\n", *hp, *mic); + + return 0; +} + +static void rt274_jack_detect_work(struct work_struct *work) +{ + struct rt274_priv *rt274 = + container_of(work, struct rt274_priv, jack_detect_work.work); + int status = 0; + bool hp = false; + bool mic = false; + + if (rt274_jack_detect(rt274, &hp, &mic) < 0) + return; + + if (hp == true) + status |= SND_JACK_HEADPHONE; + + if (mic == true) + status |= SND_JACK_MICROPHONE; + + snd_soc_jack_report(rt274->jack, status, + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); +} + +static irqreturn_t rt274_irq(int irq, void *data); + +static int rt274_mic_detect(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, void *data) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + if (jack == NULL) { + /* Disable jack detection */ + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_IRQ_EN, RT274_IRQ_DIS); + + return 0; + } + rt274->jack = jack; + + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_IRQ_EN, RT274_IRQ_EN); + + /* Send an initial report */ + rt274_irq(0, rt274); + + return 0; +} + +static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); +static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); + +static const struct snd_kcontrol_new rt274_snd_controls[] = { + SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT274_DAC0L_GAIN, + RT274_DAC0R_GAIN, 0, 0x7f, 0, out_vol_tlv), + SOC_DOUBLE_R_TLV("DAC1 Playback Volume", RT274_DAC1L_GAIN, + RT274_DAC1R_GAIN, 0, 0x7f, 0, out_vol_tlv), + SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT274_ADCL_GAIN, + RT274_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), + SOC_DOUBLE_R("ADC0 Capture Switch", RT274_ADCL_GAIN, + RT274_ADCR_GAIN, RT274_MUTE_SFT, 1, 1), + SOC_SINGLE_TLV("AMIC Volume", RT274_MIC_GAIN, + 0, 0x3, 0, mic_vol_tlv), +}; + +static const struct snd_kcontrol_new hpol_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOL_GAIN, + RT274_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new hpor_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_HPOR_GAIN, + RT274_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new loutl_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTL_GAIN, + RT274_MUTE_SFT, 1, 1); + +static const struct snd_kcontrol_new loutr_enable_control = + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT274_LOUTR_GAIN, + RT274_MUTE_SFT, 1, 1); + +/* ADC0 source */ +static const char * const rt274_adc_src[] = { + "Mic", "Line1", "Line2", "Dmic" +}; + +static SOC_ENUM_SINGLE_DECL( + rt274_adc0_enum, RT274_ADC0_MUX, RT274_ADC_SEL_SFT, + rt274_adc_src); + +static const struct snd_kcontrol_new rt274_adc0_mux = + SOC_DAPM_ENUM("ADC 0 source", rt274_adc0_enum); + +static SOC_ENUM_SINGLE_DECL( + rt274_adc1_enum, RT274_ADC1_MUX, RT274_ADC_SEL_SFT, + rt274_adc_src); + +static const struct snd_kcontrol_new rt274_adc1_mux = + SOC_DAPM_ENUM("ADC 1 source", rt274_adc1_enum); + +static const char * const rt274_dac_src[] = { + "DAC OUT0", "DAC OUT1" +}; +/* HP-OUT source */ +static SOC_ENUM_SINGLE_DECL(rt274_hpo_enum, RT274_HPO_MUX, + 0, rt274_dac_src); + +static const struct snd_kcontrol_new rt274_hpo_mux = +SOC_DAPM_ENUM("HPO source", rt274_hpo_enum); + +/* Line out source */ +static SOC_ENUM_SINGLE_DECL(rt274_lout_enum, RT274_LOUT_MUX, + 0, rt274_dac_src); + +static const struct snd_kcontrol_new rt274_lout_mux = +SOC_DAPM_ENUM("LOUT source", rt274_lout_enum); + +static const struct snd_soc_dapm_widget rt274_dapm_widgets[] = { + /* Input Lines */ + SND_SOC_DAPM_INPUT("DMIC1 Pin"), + SND_SOC_DAPM_INPUT("DMIC2 Pin"), + SND_SOC_DAPM_INPUT("MIC"), + SND_SOC_DAPM_INPUT("LINE1"), + SND_SOC_DAPM_INPUT("LINE2"), + + /* DMIC */ + SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* ADCs */ + SND_SOC_DAPM_ADC("ADC 0", NULL, RT274_SET_STREAMID_ADC1, 4, 0), + SND_SOC_DAPM_ADC("ADC 1", NULL, RT274_SET_STREAMID_ADC2, 4, 0), + + /* ADC Mux */ + SND_SOC_DAPM_MUX("ADC 0 Mux", SND_SOC_NOPM, 0, 0, + &rt274_adc0_mux), + SND_SOC_DAPM_MUX("ADC 1 Mux", SND_SOC_NOPM, 0, 0, + &rt274_adc1_mux), + + /* Audio Interface */ + SND_SOC_DAPM_AIF_IN("AIF1RXL", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF1RXR", "AIF1 Playback", 1, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF1TXL", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF1TXR", "AIF1 Capture", 1, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF2RXL", "AIF1 Playback", 2, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("AIF2RXR", "AIF1 Playback", 3, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF2TXL", "AIF1 Capture", 2, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF2TXR", "AIF1 Capture", 3, SND_SOC_NOPM, 0, 0), + + /* Output Side */ + /* DACs */ + SND_SOC_DAPM_DAC("DAC 0", NULL, RT274_SET_STREAMID_DAC0, 4, 0), + SND_SOC_DAPM_DAC("DAC 1", NULL, RT274_SET_STREAMID_DAC1, 4, 0), + + /* Output Mux */ + SND_SOC_DAPM_MUX("HPO Mux", SND_SOC_NOPM, 0, 0, &rt274_hpo_mux), + SND_SOC_DAPM_MUX("LOUT Mux", SND_SOC_NOPM, 0, 0, &rt274_lout_mux), + + SND_SOC_DAPM_SUPPLY("HP Power", RT274_SET_PIN_HPO, + RT274_SET_PIN_SFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("LOUT Power", RT274_SET_PIN_LOUT3, + RT274_SET_PIN_SFT, 0, NULL, 0), + + /* Output Mixer */ + SND_SOC_DAPM_PGA("DAC OUT0", SND_SOC_NOPM, 0, 0, + NULL, 0), + SND_SOC_DAPM_PGA("DAC OUT1", SND_SOC_NOPM, 0, 0, + NULL, 0), + + /* Output Pga */ + SND_SOC_DAPM_SWITCH("LOUT L", SND_SOC_NOPM, 0, 0, + &loutl_enable_control), + SND_SOC_DAPM_SWITCH("LOUT R", SND_SOC_NOPM, 0, 0, + &loutr_enable_control), + SND_SOC_DAPM_SWITCH("HPO L", SND_SOC_NOPM, 0, 0, + &hpol_enable_control), + SND_SOC_DAPM_SWITCH("HPO R", SND_SOC_NOPM, 0, 0, + &hpor_enable_control), + + /* Output Lines */ + SND_SOC_DAPM_OUTPUT("HPO Pin"), + SND_SOC_DAPM_OUTPUT("SPDIF"), + SND_SOC_DAPM_OUTPUT("LINE3"), +}; + +static const struct snd_soc_dapm_route rt274_dapm_routes[] = { + {"DMIC1", NULL, "DMIC1 Pin"}, + {"DMIC2", NULL, "DMIC2 Pin"}, + + {"ADC 0 Mux", "Mic", "MIC"}, + {"ADC 0 Mux", "Dmic", "DMIC1"}, + {"ADC 0 Mux", "Line1", "LINE1"}, + {"ADC 0 Mux", "Line2", "LINE2"}, + {"ADC 1 Mux", "Mic", "MIC"}, + {"ADC 1 Mux", "Dmic", "DMIC2"}, + {"ADC 1 Mux", "Line1", "LINE1"}, + {"ADC 1 Mux", "Line2", "LINE2"}, + + {"ADC 0", NULL, "ADC 0 Mux"}, + {"ADC 1", NULL, "ADC 1 Mux"}, + + {"AIF1TXL", NULL, "ADC 0"}, + {"AIF1TXR", NULL, "ADC 0"}, + {"AIF2TXL", NULL, "ADC 1"}, + {"AIF2TXR", NULL, "ADC 1"}, + + {"DAC 0", NULL, "AIF1RXL"}, + {"DAC 0", NULL, "AIF1RXR"}, + {"DAC 1", NULL, "AIF2RXL"}, + {"DAC 1", NULL, "AIF2RXR"}, + + {"DAC OUT0", NULL, "DAC 0"}, + + {"DAC OUT1", NULL, "DAC 1"}, + + {"LOUT Mux", "DAC OUT0", "DAC OUT0"}, + {"LOUT Mux", "DAC OUT1", "DAC OUT1"}, + + {"LOUT L", "Switch", "LOUT Mux"}, + {"LOUT R", "Switch", "LOUT Mux"}, + {"LOUT L", NULL, "LOUT Power"}, + {"LOUT R", NULL, "LOUT Power"}, + + {"LINE3", NULL, "LOUT L"}, + {"LINE3", NULL, "LOUT R"}, + + {"HPO Mux", "DAC OUT0", "DAC OUT0"}, + {"HPO Mux", "DAC OUT1", "DAC OUT1"}, + + {"HPO L", "Switch", "HPO Mux"}, + {"HPO R", "Switch", "HPO Mux"}, + {"HPO L", NULL, "HP Power"}, + {"HPO R", NULL, "HP Power"}, + + {"HPO Pin", NULL, "HPO L"}, + {"HPO Pin", NULL, "HPO R"}, +}; + +static int rt274_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + unsigned int val = 0; + int d_len_code = 0, c_len_code = 0; + + switch (params_rate(params)) { + /* bit 14 0:48K 1:44.1K */ + case 44100: + case 48000: + break; + default: + dev_err(codec->dev, "Unsupported sample rate %d\n", + params_rate(params)); + return -EINVAL; + } + switch (rt274->sys_clk) { + case 12288000: + case 24576000: + if (params_rate(params) != 48000) { + dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n", + params_rate(params), rt274->sys_clk); + return -EINVAL; + } + break; + case 11289600: + case 22579200: + if (params_rate(params) != 44100) { + dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n", + params_rate(params), rt274->sys_clk); + return -EINVAL; + } + break; + } + + if (params_channels(params) <= 16) { + /* bit 3:0 Number of Channel */ + val |= (params_channels(params) - 1); + } else { + dev_err(codec->dev, "Unsupported channels %d\n", + params_channels(params)); + return -EINVAL; + } + + switch (params_width(params)) { + /* bit 6:4 Bits per Sample */ + case 16: + d_len_code = 0; + c_len_code = 0; + val |= (0x1 << 4); + break; + case 32: + d_len_code = 2; + c_len_code = 3; + val |= (0x4 << 4); + break; + case 20: + d_len_code = 1; + c_len_code = 1; + val |= (0x2 << 4); + break; + case 24: + d_len_code = 2; + c_len_code = 2; + val |= (0x3 << 4); + break; + case 8: + d_len_code = 3; + c_len_code = 0; + break; + default: + return -EINVAL; + } + + if (rt274->master) + c_len_code = 0x3; + + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, 0xc018, d_len_code << 3 | c_len_code << 14); + dev_dbg(codec->dev, "format val = 0x%x\n", val); + + snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x407f, val); + snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x407f, val); + + return 0; +} + +static int rt274_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_M); + rt274->master = true; + break; + case SND_SOC_DAIFMT_CBS_CFS: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_I2S_MODE_MASK, RT274_I2S_MODE_S); + rt274->master = false; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_I2S); + break; + case SND_SOC_DAIFMT_LEFT_J: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_LJ); + break; + case SND_SOC_DAIFMT_DSP_A: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMA); + break; + case SND_SOC_DAIFMT_DSP_B: + snd_soc_update_bits(codec, RT274_I2S_CTRL1, + RT274_I2S_FMT_MASK, RT274_I2S_FMT_PCMB); + break; + default: + return -EINVAL; + } + /* bit 15 Stream Type 0:PCM 1:Non-PCM */ + snd_soc_update_bits(codec, RT274_DAC_FORMAT, 0x8000, 0); + snd_soc_update_bits(codec, RT274_ADC_FORMAT, 0x8000, 0); + + return 0; +} + +static int rt274_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, + unsigned int freq_in, unsigned int freq_out) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + switch (source) { + case RT274_PLL2_S_MCLK: + snd_soc_update_bits(codec, RT274_PLL2_CTRL, + RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_MCLK); + break; + default: + dev_warn(codec->dev, "invalid pll source, use BCLK\n"); + case RT274_PLL2_S_BCLK: + snd_soc_update_bits(codec, RT274_PLL2_CTRL, + RT274_PLL2_SRC_MASK, RT274_PLL2_SRC_BCLK); + break; + } + + if (source == RT274_PLL2_S_BCLK) { + snd_soc_update_bits(codec, RT274_MCLK_CTRL, + (0x3 << 12), (0x3 << 12)); + switch (rt274->fs) { + case 50: + snd_soc_write(codec, 0x7a, 0xaab6); + snd_soc_write(codec, 0x7b, 0x0301); + snd_soc_write(codec, 0x7c, 0x04fe); + break; + case 64: + snd_soc_write(codec, 0x7a, 0xaa96); + snd_soc_write(codec, 0x7b, 0x8003); + snd_soc_write(codec, 0x7c, 0x081e); + break; + case 128: + snd_soc_write(codec, 0x7a, 0xaa96); + snd_soc_write(codec, 0x7b, 0x8003); + snd_soc_write(codec, 0x7c, 0x080e); + break; + default: + dev_warn(codec->dev, "invalid freq_in, assume 4.8M\n"); + case 100: + snd_soc_write(codec, 0x7a, 0xaab6); + snd_soc_write(codec, 0x7b, 0x0301); + snd_soc_write(codec, 0x7c, 0x047e); + break; + } + } + + return 0; +} + +static int rt274_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + unsigned int clk_src, mclk_en; + + dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq); + + switch (clk_id) { + case RT274_SCLK_S_MCLK: + mclk_en = RT274_MCLK_MODE_EN; + clk_src = RT274_CLK_SRC_MCLK; + break; + case RT274_SCLK_S_PLL1: + mclk_en = RT274_MCLK_MODE_DIS; + clk_src = RT274_CLK_SRC_MCLK; + break; + case RT274_SCLK_S_PLL2: + mclk_en = RT274_MCLK_MODE_EN; + clk_src = RT274_CLK_SRC_PLL2; + break; + default: + mclk_en = RT274_MCLK_MODE_DIS; + clk_src = RT274_CLK_SRC_MCLK; + dev_warn(codec->dev, "invalid sysclk source, use PLL1\n"); + break; + } + snd_soc_update_bits(codec, RT274_MCLK_CTRL, + RT274_MCLK_MODE_MASK, mclk_en); + snd_soc_update_bits(codec, RT274_CLK_CTRL, + RT274_CLK_SRC_MASK, clk_src); + + switch (freq) { + case 19200000: + if (clk_id == RT274_SCLK_S_MCLK) { + dev_err(codec->dev, "Should not use MCLK\n"); + return -EINVAL; + } + snd_soc_update_bits(codec, + RT274_I2S_CTRL2, 0x40, 0x40); + break; + case 24000000: + if (clk_id == RT274_SCLK_S_MCLK) { + dev_err(codec->dev, "Should not use MCLK\n"); + return -EINVAL; + } + snd_soc_update_bits(codec, + RT274_I2S_CTRL2, 0x40, 0x0); + break; + case 12288000: + case 11289600: + snd_soc_update_bits(codec, + RT274_MCLK_CTRL, 0x1fcf, 0x0008); + break; + case 24576000: + case 22579200: + snd_soc_update_bits(codec, + RT274_MCLK_CTRL, 0x1fcf, 0x1543); + break; + default: + dev_err(codec->dev, "Unsupported system clock\n"); + return -EINVAL; + } + + rt274->sys_clk = freq; + rt274->clk_id = clk_id; + + return 0; +} + +static int rt274_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) +{ + struct snd_soc_codec *codec = dai->codec; + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio); + rt274->fs = ratio; + if ((ratio / 50) == 0) + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, 0x1000, 0x1000); + else + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, 0x1000, 0x0); + + + return 0; +} + +static int rt274_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, + unsigned int rx_mask, int slots, int slot_width) + +{ + struct snd_soc_codec *codec = dai->codec; + + if (rx_mask || tx_mask) { + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_EN); + } else { + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_EN, RT274_TDM_DIS); + return 0; + } + + switch (slots) { + case 4: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_4CH); + break; + case 2: + snd_soc_update_bits(codec, + RT274_I2S_CTRL1, RT274_TDM_CH_NUM, RT274_TDM_2CH); + break; + default: + dev_err(codec->dev, + "Support 2 or 4 slots TDM only\n"); + return -EINVAL; + } + + return 0; +} + +static int rt274_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_PREPARE: + if (SND_SOC_BIAS_STANDBY == + snd_soc_codec_get_bias_level(codec)) { + snd_soc_write(codec, + RT274_SET_AUDIO_POWER, AC_PWRST_D0); + } + break; + + case SND_SOC_BIAS_STANDBY: + snd_soc_write(codec, + RT274_SET_AUDIO_POWER, AC_PWRST_D3); + break; + + default: + break; + } + + return 0; +} + +static irqreturn_t rt274_irq(int irq, void *data) +{ + struct rt274_priv *rt274 = data; + bool hp = false; + bool mic = false; + int ret, status = 0; + + /* Clear IRQ */ + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_IRQ_CLR, RT274_IRQ_CLR); + + ret = rt274_jack_detect(rt274, &hp, &mic); + + if (ret == 0) { + if (hp == true) + status |= SND_JACK_HEADPHONE; + + if (mic == true) + status |= SND_JACK_MICROPHONE; + + snd_soc_jack_report(rt274->jack, status, + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + + pm_wakeup_event(&rt274->i2c->dev, 300); + } + + return IRQ_HANDLED; +} + +static int rt274_probe(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + rt274->codec = codec; + + if (rt274->i2c->irq) { + INIT_DELAYED_WORK(&rt274->jack_detect_work, + rt274_jack_detect_work); + schedule_delayed_work(&rt274->jack_detect_work, + msecs_to_jiffies(1250)); + } + + return 0; +} + +static int rt274_remove(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + cancel_delayed_work_sync(&rt274->jack_detect_work); + + return 0; +} + +#ifdef CONFIG_PM +static int rt274_suspend(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + regcache_cache_only(rt274->regmap, true); + regcache_mark_dirty(rt274->regmap); + + return 0; +} + +static int rt274_resume(struct snd_soc_codec *codec) +{ + struct rt274_priv *rt274 = snd_soc_codec_get_drvdata(codec); + + regcache_cache_only(rt274->regmap, false); + rt274_index_sync(codec); + regcache_sync(rt274->regmap); + + return 0; +} +#else +#define rt274_suspend NULL +#define rt274_resume NULL +#endif + +#define RT274_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) +#define RT274_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) + +static const struct snd_soc_dai_ops rt274_aif_dai_ops = { + .hw_params = rt274_hw_params, + .set_fmt = rt274_set_dai_fmt, + .set_sysclk = rt274_set_dai_sysclk, + .set_pll = rt274_set_dai_pll, + .set_bclk_ratio = rt274_set_bclk_ratio, + .set_tdm_slot = rt274_set_tdm_slot, +}; + +static struct snd_soc_dai_driver rt274_dai[] = { + { + .name = "rt274-aif1", + .id = RT274_AIF1, + .playback = { + .stream_name = "AIF1 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = RT274_STEREO_RATES, + .formats = RT274_FORMATS, + }, + .capture = { + .stream_name = "AIF1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = RT274_STEREO_RATES, + .formats = RT274_FORMATS, + }, + .ops = &rt274_aif_dai_ops, + .symmetric_rates = 1, + }, +}; + +static const struct snd_soc_codec_driver soc_codec_dev_rt274 = { + .probe = rt274_probe, + .remove = rt274_remove, + .suspend = rt274_suspend, + .resume = rt274_resume, + .set_bias_level = rt274_set_bias_level, + .idle_bias_off = true, + .component_driver = { + .controls = rt274_snd_controls, + .num_controls = ARRAY_SIZE(rt274_snd_controls), + .dapm_widgets = rt274_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rt274_dapm_widgets), + .dapm_routes = rt274_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(rt274_dapm_routes), + }, + .set_jack = rt274_mic_detect, +}; + +static const struct regmap_config rt274_regmap = { + .reg_bits = 32, + .val_bits = 32, + .max_register = 0x05bfffff, + .volatile_reg = rt274_volatile_register, + .readable_reg = rt274_readable_register, + .reg_write = rl6347a_hw_write, + .reg_read = rl6347a_hw_read, + .cache_type = REGCACHE_RBTREE, + .reg_defaults = rt274_reg, + .num_reg_defaults = ARRAY_SIZE(rt274_reg), +}; + +#ifdef CONFIG_OF +static const struct of_device_id rt274_of_match[] = { + {.compatible = "realtek,rt274"}, + {}, +}; +MODULE_DEVICE_TABLE(of, rt274_of_match); +#endif + +static const struct i2c_device_id rt274_i2c_id[] = { + {"rt274", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, rt274_i2c_id); + +static const struct acpi_device_id rt274_acpi_match[] = { + { "10EC0274", 0 }, + { "INT34C2", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, rt274_acpi_match); + +static int rt274_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct rt274_priv *rt274; + + int ret; + unsigned int val; + + rt274 = devm_kzalloc(&i2c->dev, sizeof(*rt274), + GFP_KERNEL); + if (rt274 == NULL) + return -ENOMEM; + + rt274->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt274_regmap); + if (IS_ERR(rt274->regmap)) { + ret = PTR_ERR(rt274->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + + regmap_read(rt274->regmap, + RT274_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val); + if (val != RT274_VENDOR_ID) { + dev_err(&i2c->dev, + "Device with ID register %#x is not rt274\n", val); + return -ENODEV; + } + + rt274->index_cache = devm_kmemdup(&i2c->dev, rt274_index_def, + sizeof(rt274_index_def), GFP_KERNEL); + if (!rt274->index_cache) + return -ENOMEM; + + rt274->index_cache_size = INDEX_CACHE_SIZE; + rt274->i2c = i2c; + i2c_set_clientdata(i2c, rt274); + + /* reset codec */ + regmap_write(rt274->regmap, RT274_RESET, 0); + regmap_update_bits(rt274->regmap, 0x1a, 0x4000, 0x4000); + + /* Set Pad PDB is floating */ + regmap_update_bits(rt274->regmap, RT274_PAD_CTRL12, 0x3, 0x0); + regmap_write(rt274->regmap, RT274_COEF5b_INDEX, 0x01); + regmap_write(rt274->regmap, RT274_COEF5b_COEF, 0x8540); + regmap_update_bits(rt274->regmap, 0x6f, 0x0100, 0x0100); + /* Combo jack auto detect */ + regmap_write(rt274->regmap, 0x4a, 0x201b); + /* Aux mode off */ + regmap_update_bits(rt274->regmap, 0x6f, 0x3000, 0x2000); + /* HP DC Calibration */ + regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0x0); + /* Set NID=58h.Index 00h [15]= 1b; */ + regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00); + regmap_write(rt274->regmap, RT274_COEF58_COEF, 0xb888); + msleep(500); + regmap_update_bits(rt274->regmap, 0x6f, 0xf, 0xb); + regmap_write(rt274->regmap, RT274_COEF58_INDEX, 0x00); + regmap_write(rt274->regmap, RT274_COEF58_COEF, 0x3888); + /* Set pin widget */ + regmap_write(rt274->regmap, RT274_SET_PIN_HPO, 0x40); + regmap_write(rt274->regmap, RT274_SET_PIN_LOUT3, 0x40); + regmap_write(rt274->regmap, RT274_SET_MIC, 0x20); + regmap_write(rt274->regmap, RT274_SET_PIN_DMIC1, 0x20); + + regmap_update_bits(rt274->regmap, RT274_I2S_CTRL2, 0xc004, 0x4004); + regmap_update_bits(rt274->regmap, RT274_EAPD_GPIO_IRQ_CTRL, + RT274_GPI2_SEL_MASK, RT274_GPI2_SEL_DMIC_CLK); + + /* jack detection */ + regmap_write(rt274->regmap, RT274_UNSOLICITED_HP_OUT, 0x81); + regmap_write(rt274->regmap, RT274_UNSOLICITED_MIC, 0x82); + + if (rt274->i2c->irq) { + ret = request_threaded_irq(rt274->i2c->irq, NULL, rt274_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt274", rt274); + if (ret != 0) { + dev_err(&i2c->dev, + "Failed to reguest IRQ: %d\n", ret); + return ret; + } + } + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt274, + rt274_dai, ARRAY_SIZE(rt274_dai)); + + return ret; +} + +static int rt274_i2c_remove(struct i2c_client *i2c) +{ + struct rt274_priv *rt274 = i2c_get_clientdata(i2c); + + if (i2c->irq) + free_irq(i2c->irq, rt274); + snd_soc_unregister_codec(&i2c->dev); + + return 0; +} + + +static struct i2c_driver rt274_i2c_driver = { + .driver = { + .name = "rt274", + .acpi_match_table = ACPI_PTR(rt274_acpi_match), +#ifdef CONFIG_OF + .of_match_table = of_match_ptr(rt274_of_match), +#endif + }, + .probe = rt274_i2c_probe, + .remove = rt274_i2c_remove, + .id_table = rt274_i2c_id, +}; + +module_i2c_driver(rt274_i2c_driver); + +MODULE_DESCRIPTION("ASoC RT274 driver"); +MODULE_AUTHOR("Bard Liao "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/rt274.h b/sound/soc/codecs/rt274.h new file mode 100644 index 000000000000..4fd1bcb73dba --- /dev/null +++ b/sound/soc/codecs/rt274.h @@ -0,0 +1,217 @@ +/* + * rt274.h -- RT274 ALSA SoC audio driver + * + * Copyright 2016 Realtek Microelectronics + * Author: Bard Liao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __RT274_H__ +#define __RT274_H__ + +#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D) + +#define RT274_AUDIO_FUNCTION_GROUP 0x01 +#define RT274_DAC_OUT0 0x02 +#define RT274_DAC_OUT1 0x03 +#define RT274_ADC_IN2 0x08 +#define RT274_ADC_IN1 0x09 +#define RT274_DIG_CVT 0x0a +#define RT274_DMIC1 0x12 +#define RT274_DMIC2 0x13 +#define RT274_MIC 0x19 +#define RT274_LINE1 0x1a +#define RT274_LINE2 0x1b +#define RT274_LINE3 0x16 +#define RT274_SPDIF 0x1e +#define RT274_VENDOR_REGISTERS 0x20 +#define RT274_HP_OUT 0x21 +#define RT274_MIXER_IN1 0x22 +#define RT274_MIXER_IN2 0x23 +#define RT274_INLINE_CMD 0x55 + +#define RT274_SET_PIN_SFT 6 +#define RT274_SET_PIN_ENABLE 0x40 +#define RT274_SET_PIN_DISABLE 0 +#define RT274_SET_EAPD_HIGH 0x2 +#define RT274_SET_EAPD_LOW 0 + +#define RT274_MUTE_SFT 7 + +/* Verb commands */ +#define RT274_RESET\ + VERB_CMD(AC_VERB_SET_CODEC_RESET, RT274_AUDIO_FUNCTION_GROUP, 0) +#define RT274_GET_PARAM(NID, PARAM) VERB_CMD(AC_VERB_PARAMETERS, NID, PARAM) +#define RT274_SET_POWER(NID) VERB_CMD(AC_VERB_SET_POWER_STATE, NID, 0) +#define RT274_SET_AUDIO_POWER RT274_SET_POWER(RT274_AUDIO_FUNCTION_GROUP) +#define RT274_SET_HPO_POWER RT274_SET_POWER(RT274_HP_OUT) +#define RT274_SET_DMIC1_POWER RT274_SET_POWER(RT274_DMIC1) +#define RT274_LOUT_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_LINE3, 0) +#define RT274_HPO_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_HP_OUT, 0) +#define RT274_ADC0_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_MIXER_IN1, 0) +#define RT274_ADC1_MUX\ + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT274_MIXER_IN2, 0) +#define RT274_SET_MIC\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_MIC, 0) +#define RT274_SET_PIN_LOUT3\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_LINE3, 0) +#define RT274_SET_PIN_HPO\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_HP_OUT, 0) +#define RT274_SET_PIN_DMIC1\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_DMIC1, 0) +#define RT274_SET_PIN_SPDIF\ + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT274_SPDIF, 0) +#define RT274_SET_PIN_DIG_CVT\ + VERB_CMD(AC_VERB_SET_DIGI_CONVERT_1, RT274_DIG_CVT, 0) +#define RT274_SET_AMP_GAIN_HPO\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0) +#define RT274_SET_AMP_GAIN_ADC_IN1\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0) +#define RT274_SET_AMP_GAIN_ADC_IN2\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN2, 0) +#define RT274_GET_HP_SENSE\ + VERB_CMD(AC_VERB_GET_PIN_SENSE, RT274_HP_OUT, 0) +#define RT274_GET_MIC_SENSE\ + VERB_CMD(AC_VERB_GET_PIN_SENSE, RT274_MIC, 0) +#define RT274_SET_DMIC2_DEFAULT\ + VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT274_DMIC2, 0) +#define RT274_SET_SPDIF_DEFAULT\ + VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT274_SPDIF, 0) +#define RT274_DAC0L_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0xa000) +#define RT274_DAC0R_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT0, 0x9000) +#define RT274_DAC1L_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0xa000) +#define RT274_DAC1R_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_DAC_OUT1, 0x9000) +#define RT274_ADCL_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0x6000) +#define RT274_ADCR_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_ADC_IN1, 0x5000) +#define RT274_MIC_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_MIC, 0x7000) +#define RT274_LOUTL_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_LINE3, 0xa000) +#define RT274_LOUTR_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_LINE3, 0x9000) +#define RT274_HPOL_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0xa000) +#define RT274_HPOR_GAIN\ + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT274_HP_OUT, 0x9000) +#define RT274_DAC_FORMAT\ + VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT274_DAC_OUT0, 0) +#define RT274_ADC_FORMAT\ + VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT274_ADC_IN1, 0) +#define RT274_COEF_INDEX\ + VERB_CMD(AC_VERB_SET_COEF_INDEX, RT274_VENDOR_REGISTERS, 0) +#define RT274_PROC_COEF\ + VERB_CMD(AC_VERB_SET_PROC_COEF, RT274_VENDOR_REGISTERS, 0) +#define RT274_UNSOLICITED_INLINE_CMD\ + VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_INLINE_CMD, 0) +#define RT274_UNSOLICITED_HP_OUT\ + VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_HP_OUT, 0) +#define RT274_UNSOLICITED_MIC\ + VERB_CMD(AC_VERB_SET_UNSOLICITED_ENABLE, RT274_MIC, 0) +#define RT274_COEF58_INDEX\ + VERB_CMD(AC_VERB_SET_COEF_INDEX, 0x58, 0) +#define RT274_COEF58_COEF\ + VERB_CMD(AC_VERB_SET_PROC_COEF, 0x58, 0) +#define RT274_COEF5b_INDEX\ + VERB_CMD(AC_VERB_SET_COEF_INDEX, 0x5b, 0) +#define RT274_COEF5b_COEF\ + VERB_CMD(AC_VERB_SET_PROC_COEF, 0x5b, 0) +#define RT274_SET_STREAMID_DAC0\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_DAC_OUT0, 0) +#define RT274_SET_STREAMID_DAC1\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_DAC_OUT1, 0) +#define RT274_SET_STREAMID_ADC1\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_ADC_IN1, 0) +#define RT274_SET_STREAMID_ADC2\ + VERB_CMD(AC_VERB_SET_CHANNEL_STREAMID, RT274_ADC_IN2, 0) + +/* Index registers */ +#define RT274_EAPD_GPIO_IRQ_CTRL 0x10 +#define RT274_PAD_CTRL12 0x35 +#define RT274_I2S_CTRL1 0x63 +#define RT274_I2S_CTRL2 0x64 +#define RT274_MCLK_CTRL 0x71 +#define RT274_CLK_CTRL 0x72 +#define RT274_PLL2_CTRL 0x7b + + +/* EAPD GPIO IRQ control (Index 0x10) */ +#define RT274_IRQ_DIS (0x0 << 13) +#define RT274_IRQ_EN (0x1 << 13) +#define RT274_IRQ_CLR (0x1 << 12) +#define RT274_GPI2_SEL_MASK (0x3 << 7) +#define RT274_GPI2_SEL_GPIO2 (0x0 << 7) +#define RT274_GPI2_SEL_I2S (0x1 << 7) +#define RT274_GPI2_SEL_DMIC_CLK (0x2 << 7) +#define RT274_GPI2_SEL_CBJ (0x3 << 7) + +/* Front I2S_Interface control 1 (Index 0x63) */ +#define RT274_I2S_MODE_MASK (0x1 << 11) +#define RT274_I2S_MODE_S (0x0 << 11) +#define RT274_I2S_MODE_M (0x1 << 11) +#define RT274_TDM_DIS (0x0 << 10) +#define RT274_TDM_EN (0x1 << 10) +#define RT274_TDM_CH_NUM (0x1 << 7) +#define RT274_TDM_2CH (0x0 << 7) +#define RT274_TDM_4CH (0x1 << 7) +#define RT274_I2S_FMT_MASK (0x3 << 8) +#define RT274_I2S_FMT_I2S (0x0 << 8) +#define RT274_I2S_FMT_LJ (0x1 << 8) +#define RT274_I2S_FMT_PCMA (0x2 << 8) +#define RT274_I2S_FMT_PCMB (0x3 << 8) + +/* MCLK clock domain control (Index 0x71) */ +#define RT274_MCLK_MODE_MASK (0x1 << 14) +#define RT274_MCLK_MODE_DIS (0x0 << 14) +#define RT274_MCLK_MODE_EN (0x1 << 14) + +/* Clock control (Index 0x72) */ +#define RT274_CLK_SRC_MASK (0x7 << 3) +#define RT274_CLK_SRC_MCLK (0x0 << 3) +#define RT274_CLK_SRC_PLL2 (0x3 << 3) + +/* PLL2 control (Index 0x7b) */ +#define RT274_PLL2_SRC_MASK (0x1 << 13) +#define RT274_PLL2_SRC_MCLK (0x0 << 13) +#define RT274_PLL2_SRC_BCLK (0x1 << 13) + +/* HP-OUT (0x21) */ +#define RT274_M_HP_MUX_SFT 14 +#define RT274_HP_SEL_MASK 0x1 +#define RT274_HP_SEL_SFT 0 +#define RT274_HP_SEL_F 0 +#define RT274_HP_SEL_S 1 + +/* ADC (0x22) (0x23) */ +#define RT274_ADC_SEL_MASK 0x7 +#define RT274_ADC_SEL_SFT 0 +#define RT274_ADC_SEL_MIC 0 +#define RT274_ADC_SEL_LINE1 1 +#define RT274_ADC_SEL_LINE2 2 +#define RT274_ADC_SEL_DMIC 3 + +#define RT274_SCLK_S_MCLK 0 +#define RT274_SCLK_S_PLL1 1 +#define RT274_SCLK_S_PLL2 2 + +#define RT274_PLL2_S_MCLK 0 +#define RT274_PLL2_S_BCLK 1 + +enum { + RT274_AIF1, + RT274_AIFS, +}; + +#endif /* __RT274_H__ */ + diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index 7899a2cdeb42..af6325c78292 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c @@ -1046,7 +1046,7 @@ static struct snd_soc_dai_driver rt286_dai[] = { }; -static struct snd_soc_codec_driver soc_codec_dev_rt286 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt286 = { .probe = rt286_probe, .remove = rt286_remove, .suspend = rt286_suspend, diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index d9e96e65e1c4..ce963768449f 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -1113,7 +1113,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { }; -static struct snd_soc_codec_driver soc_codec_dev_rt298 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt298 = { .probe = rt298_probe, .remove = rt298_remove, .suspend = rt298_suspend, diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 7ed62e8c80b4..12f2ecf3a4fe 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c @@ -43,9 +43,7 @@ struct rt5514_dsp { struct mutex dma_lock; struct snd_pcm_substream *substream; unsigned int buf_base, buf_limit, buf_rp; - size_t buf_size; - size_t dma_offset; - size_t dsp_offset; + size_t buf_size, get_size, dma_offset; }; static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = { @@ -80,6 +78,8 @@ static void rt5514_spi_copy_work(struct work_struct *work) container_of(work, struct rt5514_dsp, copy_work.work); struct snd_pcm_runtime *runtime; size_t period_bytes, truncated_bytes = 0; + unsigned int cur_wp, remain_data; + u8 buf[8]; mutex_lock(&rt5514_dsp->dma_lock); if (!rt5514_dsp->substream) { @@ -90,8 +90,24 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime = rt5514_dsp->substream->runtime; period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream); - if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset < period_bytes) - period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset; + if (rt5514_dsp->get_size >= rt5514_dsp->buf_size) { + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + cur_wp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + if (cur_wp >= rt5514_dsp->buf_rp) + remain_data = (cur_wp - rt5514_dsp->buf_rp); + else + remain_data = + (rt5514_dsp->buf_limit - rt5514_dsp->buf_rp) + + (cur_wp - rt5514_dsp->buf_base); + + if (remain_data < period_bytes) { + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + goto done; + } + } if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) { rt5514_spi_burst_read(rt5514_dsp->buf_rp, @@ -112,24 +128,68 @@ static void rt5514_spi_copy_work(struct work_struct *work) runtime->dma_area + rt5514_dsp->dma_offset + truncated_bytes, period_bytes - truncated_bytes); - rt5514_dsp->buf_rp = rt5514_dsp->buf_base + - period_bytes - truncated_bytes; + rt5514_dsp->buf_rp = rt5514_dsp->buf_base + period_bytes - + truncated_bytes; } + rt5514_dsp->get_size += period_bytes; rt5514_dsp->dma_offset += period_bytes; if (rt5514_dsp->dma_offset >= runtime->dma_bytes) rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset += period_bytes; - snd_pcm_period_elapsed(rt5514_dsp->substream); - if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size) - schedule_delayed_work(&rt5514_dsp->copy_work, 5); + schedule_delayed_work(&rt5514_dsp->copy_work, 5); + done: mutex_unlock(&rt5514_dsp->dma_lock); } +static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp) +{ + u8 buf[8]; + + rt5514_dsp->get_size = 0; + + /** + * The address area x1800XXXX is the register address, and it cannot + * support spi burst read perfectly. So we use the spi burst read + * individually to make sure the data correctly. + */ + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf, + sizeof(buf)); + rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 | + buf[3] << 24; + + if (rt5514_dsp->buf_rp % 8) + rt5514_dsp->buf_rp = (rt5514_dsp->buf_rp / 8) * 8; + + rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base; + + if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit && + rt5514_dsp->buf_rp && rt5514_dsp->buf_size) + schedule_delayed_work(&rt5514_dsp->copy_work, 0); +} + +static irqreturn_t rt5514_spi_irq(int irq, void *data) +{ + struct rt5514_dsp *rt5514_dsp = data; + + rt5514_schedule_copy(rt5514_dsp); + + return IRQ_HANDLED; +} + /* PCM for streaming audio from the DSP buffer */ static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream) { @@ -145,11 +205,19 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream, struct rt5514_dsp *rt5514_dsp = snd_soc_platform_get_drvdata(rtd->platform); int ret; + u8 buf[8]; mutex_lock(&rt5514_dsp->dma_lock); ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); rt5514_dsp->substream = substream; + rt5514_dsp->dma_offset = 0; + + /* Read IRQ status and schedule copy accordingly. */ + rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf)); + if (buf[0] & RT5514_IRQ_STATUS_BIT) + rt5514_schedule_copy(rt5514_dsp); + mutex_unlock(&rt5514_dsp->dma_lock); return ret; @@ -170,59 +238,6 @@ static int rt5514_spi_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_vmalloc_buffer(substream); } -static int rt5514_spi_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rt5514_dsp *rt5514_dsp = - snd_soc_platform_get_drvdata(rtd->platform); - u8 buf[8]; - - rt5514_dsp->dma_offset = 0; - rt5514_dsp->dsp_offset = 0; - - /** - * The address area x1800XXXX is the register address, and it cannot - * support spi burst read perfectly. So we use the spi burst read - * individually to make sure the data correctly. - */ - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_RP, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - rt5514_spi_burst_read(RT5514_BUFFER_VOICE_SIZE, (u8 *)&buf, - sizeof(buf)); - rt5514_dsp->buf_size = buf[0] | buf[1] << 8 | buf[2] << 16 | - buf[3] << 24; - - return 0; -} - -static int rt5514_spi_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct rt5514_dsp *rt5514_dsp = - snd_soc_platform_get_drvdata(rtd->platform); - - if (cmd == SNDRV_PCM_TRIGGER_START) { - if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit && - rt5514_dsp->buf_rp && rt5514_dsp->buf_size) - schedule_delayed_work(&rt5514_dsp->copy_work, 0); - } - - return 0; -} - static snd_pcm_uframes_t rt5514_spi_pcm_pointer( struct snd_pcm_substream *substream) { @@ -238,8 +253,6 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = { .open = rt5514_spi_pcm_open, .hw_params = rt5514_spi_hw_params, .hw_free = rt5514_spi_hw_free, - .trigger = rt5514_spi_trigger, - .prepare = rt5514_spi_prepare, .pointer = rt5514_spi_pcm_pointer, .mmap = snd_pcm_lib_mmap_vmalloc, .page = snd_pcm_lib_get_vmalloc_page, @@ -248,6 +261,7 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = { static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform) { struct rt5514_dsp *rt5514_dsp; + int ret; rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp), GFP_KERNEL); @@ -257,10 +271,21 @@ static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform) INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work); snd_soc_platform_set_drvdata(platform, rt5514_dsp); + if (rt5514_spi->irq) { + ret = devm_request_threaded_irq(&rt5514_spi->dev, + rt5514_spi->irq, NULL, rt5514_spi_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5514-spi", + rt5514_dsp); + if (ret) + dev_err(&rt5514_spi->dev, + "%s Failed to reguest IRQ: %d\n", __func__, + ret); + } + return 0; } -static struct snd_soc_platform_driver rt5514_spi_platform = { +static const struct snd_soc_platform_driver rt5514_spi_platform = { .probe = rt5514_spi_pcm_probe, .ops = &rt5514_spi_pcm_ops, }; diff --git a/sound/soc/codecs/rt5514-spi.h b/sound/soc/codecs/rt5514-spi.h index f69b1cdf2f9b..c1a36647c119 100644 --- a/sound/soc/codecs/rt5514-spi.h +++ b/sound/soc/codecs/rt5514-spi.h @@ -17,10 +17,12 @@ */ #define RT5514_SPI_BUF_LEN 240 -#define RT5514_BUFFER_VOICE_BASE 0x18001034 -#define RT5514_BUFFER_VOICE_LIMIT 0x18001038 -#define RT5514_BUFFER_VOICE_RP 0x1800103c -#define RT5514_BUFFER_VOICE_SIZE 0x18001040 +#define RT5514_BUFFER_VOICE_BASE 0x18000200 +#define RT5514_BUFFER_VOICE_LIMIT 0x18000204 +#define RT5514_BUFFER_VOICE_WP 0x1800020c +#define RT5514_IRQ_CTRL 0x18002094 + +#define RT5514_IRQ_STATUS_BIT (0x1 << 5) /* SPI Command */ enum { diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 1b6796c4c471..d7956ababd11 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -31,7 +31,7 @@ #include "rl6231.h" #include "rt5514.h" -#if defined(CONFIG_SND_SOC_RT5514_SPI) +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) #include "rt5514-spi.h" #endif @@ -63,6 +63,9 @@ static const struct reg_sequence rt5514_patch[] = { {RT5514_SRC_CTRL, 0x44000eee}, {RT5514_ANA_CTRL_LDO10, 0x00028604}, {RT5514_ANA_CTRL_ADCFED, 0x00000800}, + {RT5514_ASRC_IN_CTRL1, 0x00000003}, + {RT5514_DOWNFILTER0_CTRL3, 0x10000362}, + {RT5514_DOWNFILTER1_CTRL3, 0x10000362}, }; static const struct reg_default rt5514_reg[] = { @@ -88,10 +91,10 @@ static const struct reg_default rt5514_reg[] = { {RT5514_DELAY_BUF_CTRL3, 0x00000000}, {RT5514_DOWNFILTER0_CTRL1, 0x00020c2f}, {RT5514_DOWNFILTER0_CTRL2, 0x00020c2f}, - {RT5514_DOWNFILTER0_CTRL3, 0x00000362}, + {RT5514_DOWNFILTER0_CTRL3, 0x10000362}, {RT5514_DOWNFILTER1_CTRL1, 0x00020c2f}, {RT5514_DOWNFILTER1_CTRL2, 0x00020c2f}, - {RT5514_DOWNFILTER1_CTRL3, 0x00000362}, + {RT5514_DOWNFILTER1_CTRL3, 0x10000362}, {RT5514_ANA_CTRL_LDO10, 0x00028604}, {RT5514_ANA_CTRL_LDO18_16, 0x02000345}, {RT5514_ANA_CTRL_ADC12, 0x0000a2a8}, @@ -311,7 +314,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, request_firmware(&fw, RT5514_FIRMWARE1, codec->dev); if (fw) { -#if defined(CONFIG_SND_SOC_RT5514_SPI) +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ff60000, fw->data, ((fw->size/8)+1)*8); #else @@ -324,7 +327,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, request_firmware(&fw, RT5514_FIRMWARE2, codec->dev); if (fw) { -#if defined(CONFIG_SND_SOC_RT5514_SPI) +#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) rt5514_spi_burst_write(0x4ffc0000, fw->data, ((fw->size/8)+1)*8); #else @@ -471,33 +474,13 @@ static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, return 0; } -static int rt5514_pre_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int rt5514_i2s_use_asrc(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) { - struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - /** - * If the DSP is enabled in start of recording, the DSP - * should be disabled, and sync back to normal recording - * settings to make sure recording properly. - */ - if (rt5514->dsp_enabled) { - rt5514->dsp_enabled = 0; - regmap_multi_reg_write(rt5514->i2c_regmap, - rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); - regcache_mark_dirty(rt5514->regmap); - regcache_sync(rt5514->regmap); - } - break; - - default: - return 0; - } - - return 0; + return (rt5514->sysclk > rt5514->lrck * 384); } static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { @@ -570,6 +553,10 @@ static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { RT5514_POW_PLL1_LDO_BIT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("PLL1", RT5514_PWR_ANA2, RT5514_POW_PLL1_BIT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ASRC AD1", 1, RT5514_CLK_CTRL2, + RT5514_CLK_AD0_ASRC_EN_BIT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ASRC AD2", 1, RT5514_CLK_CTRL2, + RT5514_CLK_AD1_ASRC_EN_BIT, 0, NULL, 0), /* ADC Mux */ SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0, @@ -607,8 +594,6 @@ static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { /* Audio Interface */ SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), - - SND_SOC_DAPM_PRE("DAPM Pre", rt5514_pre_event), }; static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { @@ -669,6 +654,7 @@ static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { { "Stereo1 ADC MIX", NULL, "Stereo1 ADC MIXR" }, { "Stereo1 ADC MIX", NULL, "adc stereo1 filter" }, { "adc stereo1 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll }, + { "adc stereo1 filter", NULL, "ASRC AD1", rt5514_i2s_use_asrc }, { "Stereo2 DMIC Mux", "DMIC1", "DMIC1" }, { "Stereo2 DMIC Mux", "DMIC2", "DMIC2" }, @@ -685,6 +671,7 @@ static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { { "Stereo2 ADC MIX", NULL, "Stereo2 ADC MIXR" }, { "Stereo2 ADC MIX", NULL, "adc stereo2 filter" }, { "adc stereo2 filter", NULL, "PLL1", rt5514_is_sys_clk_from_pll }, + { "adc stereo2 filter", NULL, "ASRC AD2", rt5514_i2s_use_asrc }, { "AIF1TX", NULL, "Stereo1 ADC MIX"}, { "AIF1TX", NULL, "Stereo2 ADC MIX"}, @@ -737,6 +724,9 @@ static int rt5514_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL1, RT5514_I2S_DL_MASK, val_len); + regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL1, + RT5514_CLK_AD_ANA1_SEL_MASK, + (pre_div + 1) << RT5514_CLK_AD_ANA1_SEL_SFT); regmap_update_bits(rt5514->regmap, RT5514_CLK_CTRL2, RT5514_CLK_SYS_DIV_OUT_MASK | RT5514_SEL_ADC_OSR_MASK, pre_div << RT5514_CLK_SYS_DIV_OUT_SFT | @@ -902,11 +892,38 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, { struct snd_soc_codec *codec = dai->codec; struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); - unsigned int val = 0; + unsigned int val = 0, val2 = 0; if (rx_mask || tx_mask) val |= RT5514_TDM_MODE; + switch (tx_mask) { + case 0x3: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH2 | + RT5514_TDM_DOCKING_START_SLOT0; + break; + + case 0x30: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH2 | + RT5514_TDM_DOCKING_START_SLOT4; + break; + + case 0xf: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH4 | + RT5514_TDM_DOCKING_START_SLOT0; + break; + + case 0xf0: + val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH4 | + RT5514_TDM_DOCKING_START_SLOT4; + break; + + default: + break; + } + + + switch (slots) { case 4: val |= RT5514_TDMSLOT_SEL_RX_4CH | RT5514_TDMSLOT_SEL_TX_4CH; @@ -952,6 +969,10 @@ static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, RT5514_CH_LEN_RX_MASK | RT5514_CH_LEN_TX_MASK | RT5514_TDM_MODE2, val); + regmap_update_bits(rt5514->regmap, RT5514_I2S_CTRL2, + RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH_MASK | + RT5514_TDM_DOCKING_START_MASK, val2); + return 0; } @@ -975,6 +996,24 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec, } break; + case SND_SOC_BIAS_STANDBY: + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { + /* + * If the DSP is enabled in start of recording, the DSP + * should be disabled, and sync back to normal recording + * settings to make sure recording properly. + */ + if (rt5514->dsp_enabled) { + rt5514->dsp_enabled = 0; + regmap_multi_reg_write(rt5514->i2c_regmap, + rt5514_i2c_patch, + ARRAY_SIZE(rt5514_i2c_patch)); + regcache_mark_dirty(rt5514->regmap); + regcache_sync(rt5514->regmap); + } + } + break; + default: break; } @@ -1019,7 +1058,7 @@ static int rt5514_i2c_write(void *context, unsigned int reg, unsigned int val) #define RT5514_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) -struct snd_soc_dai_ops rt5514_aif_dai_ops = { +static const struct snd_soc_dai_ops rt5514_aif_dai_ops = { .hw_params = rt5514_hw_params, .set_fmt = rt5514_set_dai_fmt, .set_sysclk = rt5514_set_dai_sysclk, @@ -1027,7 +1066,7 @@ struct snd_soc_dai_ops rt5514_aif_dai_ops = { .set_tdm_slot = rt5514_set_tdm_slot, }; -struct snd_soc_dai_driver rt5514_dai[] = { +static struct snd_soc_dai_driver rt5514_dai[] = { { .name = "rt5514-aif1", .id = 0, @@ -1042,7 +1081,7 @@ struct snd_soc_dai_driver rt5514_dai[] = { } }; -static struct snd_soc_codec_driver soc_codec_dev_rt5514 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5514 = { .probe = rt5514_probe, .idle_bias_off = true, .set_bias_level = rt5514_set_bias_level, @@ -1097,7 +1136,7 @@ MODULE_DEVICE_TABLE(of, rt5514_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5514_acpi_match[] = { +static const struct acpi_device_id rt5514_acpi_match[] = { { "10EC5514", 0}, {}, }; diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h index 02bc212a86d9..2dc40e6d8b3f 100644 --- a/sound/soc/codecs/rt5514.h +++ b/sound/soc/codecs/rt5514.h @@ -37,6 +37,7 @@ #define RT5514_PLL3_CALIB_CTRL5 0x2124 #define RT5514_DELAY_BUF_CTRL1 0x2140 #define RT5514_DELAY_BUF_CTRL3 0x2148 +#define RT5514_ASRC_IN_CTRL1 0x2180 #define RT5514_DOWNFILTER0_CTRL1 0x2190 #define RT5514_DOWNFILTER0_CTRL2 0x2194 #define RT5514_DOWNFILTER0_CTRL3 0x2198 @@ -164,6 +165,18 @@ #define RT5514_I2S_DL_24 (0x2 << 0) #define RT5514_I2S_DL_8 (0x3 << 0) +/* RT5514_I2S_CTRL2 (0x2014) */ +#define RT5514_TDM_DOCKING_MODE (0x1 << 31) +#define RT5514_TDM_DOCKING_MODE_SFT 31 +#define RT5514_TDM_DOCKING_VALID_CH_MASK (0x1 << 29) +#define RT5514_TDM_DOCKING_VALID_CH_SFT 29 +#define RT5514_TDM_DOCKING_VALID_CH2 (0x0 << 29) +#define RT5514_TDM_DOCKING_VALID_CH4 (0x1 << 29) +#define RT5514_TDM_DOCKING_START_MASK (0x1 << 28) +#define RT5514_TDM_DOCKING_START_SFT 28 +#define RT5514_TDM_DOCKING_START_SLOT0 (0x0 << 28) +#define RT5514_TDM_DOCKING_START_SLOT4 (0x1 << 28) + /* RT5514_DIG_SOURCE_CTRL (0x20a4) */ #define RT5514_AD1_DMIC_INPUT_SEL (0x1 << 1) #define RT5514_AD1_DMIC_INPUT_SEL_SFT 1 @@ -185,8 +198,14 @@ #define RT5514_CLK_AD0_EN_BIT 23 #define RT5514_CLK_DMIC_OUT_SEL_MASK (0x7 << 8) #define RT5514_CLK_DMIC_OUT_SEL_SFT 8 +#define RT5514_CLK_AD_ANA1_SEL_MASK (0xf << 0) +#define RT5514_CLK_AD_ANA1_SEL_SFT 0 /* RT5514_CLK_CTRL2 (0x2108) */ +#define RT5514_CLK_AD1_ASRC_EN (0x1 << 17) +#define RT5514_CLK_AD1_ASRC_EN_BIT 17 +#define RT5514_CLK_AD0_ASRC_EN (0x1 << 16) +#define RT5514_CLK_AD0_ASRC_EN_BIT 16 #define RT5514_CLK_SYS_DIV_OUT_MASK (0x7 << 8) #define RT5514_CLK_SYS_DIV_OUT_SFT 8 #define RT5514_SEL_ADC_OSR_MASK (0x7 << 4) diff --git a/sound/soc/codecs/rt5616.c b/sound/soc/codecs/rt5616.c index 7d6e0823f98f..0e5f54a9bc7e 100644 --- a/sound/soc/codecs/rt5616.c +++ b/sound/soc/codecs/rt5616.c @@ -98,7 +98,7 @@ static const struct reg_default rt5616_reg[] = { { 0x8e, 0x0004 }, { 0x8f, 0x1100 }, { 0x90, 0x0000 }, - { 0x91, 0x0000 }, + { 0x91, 0x0c00 }, { 0x92, 0x0000 }, { 0x93, 0x2000 }, { 0x94, 0x0200 }, @@ -1265,7 +1265,7 @@ static int rt5616_resume(struct snd_soc_codec *codec) #define RT5616_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) -static struct snd_soc_dai_ops rt5616_aif_dai_ops = { +static const struct snd_soc_dai_ops rt5616_aif_dai_ops = { .hw_params = rt5616_hw_params, .set_fmt = rt5616_set_dai_fmt, .set_sysclk = rt5616_set_dai_sysclk, @@ -1294,7 +1294,7 @@ static struct snd_soc_dai_driver rt5616_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5616 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5616 = { .probe = rt5616_probe, .suspend = rt5616_suspend, .resume = rt5616_resume, diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 0e418089c053..55b04c55fb4b 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -1653,7 +1653,7 @@ static struct snd_soc_dai_driver rt5631_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5631 = { .probe = rt5631_probe, .set_bias_level = rt5631_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/rt5631.h b/sound/soc/codecs/rt5631.h index 13401581b0df..8a6b99a48c7c 100644 --- a/sound/soc/codecs/rt5631.h +++ b/sound/soc/codecs/rt5631.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __RTCODEC5631_H__ #define __RTCODEC5631_H__ diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 1584ccc3a87b..438fe52a12df 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2259,7 +2259,7 @@ static struct snd_soc_dai_driver rt5640_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5640 = { .probe = rt5640_probe, .remove = rt5640_remove, .suspend = rt5640_suspend, diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 9ec58166f7c4..a98647ac497c 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -3473,7 +3473,7 @@ static struct snd_soc_dai_driver rt5645_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5645 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5645 = { .probe = rt5645_probe, .remove = rt5645_remove, .suspend = rt5645_suspend, @@ -3559,7 +3559,7 @@ static const struct acpi_device_id rt5645_acpi_match[] = { MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); #endif -static struct rt5645_platform_data general_platform_data = { +static const struct rt5645_platform_data general_platform_data = { .dmic1_data_pin = RT5645_DMIC1_DISABLE, .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, .jd_mode = 3, @@ -3593,14 +3593,14 @@ static const struct dmi_system_id dmi_platform_intel_braswell[] = { { } }; -static struct rt5645_platform_data buddy_platform_data = { +static const struct rt5645_platform_data buddy_platform_data = { .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, .jd_mode = 3, .level_trigger_irq = true, }; -static struct dmi_system_id dmi_platform_intel_broadwell[] = { +static const struct dmi_system_id dmi_platform_intel_broadwell[] = { { .ident = "Chrome Buddy", .matches = { @@ -3610,7 +3610,7 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = { { } }; -static struct rt5645_platform_data gpd_win_platform_data = { +static const struct rt5645_platform_data gpd_win_platform_data = { .jd_mode = 3, .inv_jd1_1 = true, }; @@ -3637,6 +3637,39 @@ static const struct dmi_system_id dmi_platform_gpd_win[] = { {} }; +static struct rt5645_platform_data general_platform_data2 = { + .dmic1_data_pin = RT5645_DMIC_DATA_IN2N, + .dmic2_data_pin = RT5645_DMIC2_DISABLE, + .jd_mode = 3, + .inv_jd1_1 = true, +}; + +static struct dmi_system_id dmi_platform_asus_t100ha[] = { + { + .ident = "ASUS T100HAN", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"), + }, + }, + { } +}; + +static struct rt5645_platform_data minix_z83_4_platform_data = { + .jd_mode = 3, +}; + +static struct dmi_system_id dmi_platform_minix_z83_4[] = { + { + .ident = "MINIX Z83-4", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"), + DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), + }, + }, + { } +}; + static bool rt5645_check_dp(struct device *dev) { if (device_property_present(dev, "realtek,in2-differential") || @@ -3689,6 +3722,10 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, rt5645->pdata = general_platform_data; else if (dmi_check_system(dmi_platform_gpd_win)) rt5645->pdata = gpd_win_platform_data; + else if (dmi_check_system(dmi_platform_asus_t100ha)) + rt5645->pdata = general_platform_data2; + else if (dmi_check_system(dmi_platform_minix_z83_4)) + rt5645->pdata = minix_z83_4_platform_data; if (quirk != -1) { rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index db05b60d5002..da60b28ba3df 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -1664,7 +1664,7 @@ static struct snd_soc_dai_driver rt5651_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5651 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5651 = { .probe = rt5651_probe, .suspend = rt5651_suspend, .resume = rt5651_resume, diff --git a/sound/soc/codecs/rt5659.c b/sound/soc/codecs/rt5659.c index 1b7060850340..fa66b11df8d4 100644 --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -2744,7 +2744,8 @@ static const struct snd_soc_dapm_widget rt5659_dapm_widgets[] = { SND_SOC_DAPM_PRE_PMU), SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5659_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_PGA("LOUT Amp", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA_S("LOUT Amp", 1, RT5659_PWR_ANLG_1, RT5659_PWR_LM_BIT, + 0, NULL, 0), SND_SOC_DAPM_SUPPLY("Charge Pump", SND_SOC_NOPM, 0, 0, rt5659_charge_pump_event, SND_SOC_DAPM_PRE_PMU | @@ -3208,6 +3209,7 @@ static const struct snd_soc_dapm_route rt5659_dapm_routes[] = { { "LOUT R MIX", "OUTVOL R Switch", "OUTVOL R" }, { "LOUT Amp", NULL, "LOUT L MIX" }, { "LOUT Amp", NULL, "LOUT R MIX" }, + { "LOUT Amp", NULL, "Charge Pump" }, { "LOUT Amp", NULL, "SYS CLK DET" }, { "LOUT L Playback", "Switch", "LOUT Amp" }, { "LOUT R Playback", "Switch", "LOUT Amp" }, @@ -3730,7 +3732,7 @@ static struct snd_soc_dai_driver rt5659_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5659 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5659 = { .probe = rt5659_probe, .remove = rt5659_remove, .suspend = rt5659_suspend, @@ -4222,7 +4224,7 @@ MODULE_DEVICE_TABLE(of, rt5659_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5659_acpi_match[] = { +static const struct acpi_device_id rt5659_acpi_match[] = { { "10EC5658", 0, }, { "10EC5659", 0, }, { }, diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index c93490d77f2a..d22ef00e0d96 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1197,7 +1197,7 @@ static struct snd_soc_dai_driver rt5660_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5660 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5660 = { .probe = rt5660_probe, .remove = rt5660_remove, .suspend = rt5660_suspend, diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index fa550e3c1332..e45b895d8279 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -40,6 +40,7 @@ enum { struct rt5663_priv { struct snd_soc_codec *codec; + struct rt5663_platform_data pdata; struct regmap *regmap; struct delayed_work jack_detect_work; struct snd_soc_jack *hs_jack; @@ -57,6 +58,11 @@ struct rt5663_priv { int jack_type; }; +static const struct reg_sequence rt5663_patch_list[] = { + { 0x002a, 0x8020 }, + { 0x0086, 0x0028 }, +}; + static const struct reg_default rt5663_v2_reg[] = { { 0x0000, 0x0000 }, { 0x0001, 0xc8c8 }, @@ -476,7 +482,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0023, 0x0039 }, { 0x0026, 0xc0c0 }, { 0x0029, 0x8080 }, - { 0x002a, 0xa0a0 }, + { 0x002a, 0x8020 }, { 0x002c, 0x000c }, { 0x002d, 0x0000 }, { 0x0040, 0x0808 }, @@ -504,7 +510,7 @@ static const struct reg_default rt5663_reg[] = { { 0x0082, 0x0000 }, { 0x0083, 0x0000 }, { 0x0084, 0x0000 }, - { 0x0086, 0x0008 }, + { 0x0086, 0x0028 }, { 0x0087, 0x0000 }, { 0x008a, 0x0000 }, { 0x008b, 0x0000 }, @@ -1508,7 +1514,7 @@ static int rt5663_v2_jack_detect(struct snd_soc_codec *codec, int jack_insert) static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) { struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); - int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; + int val, i = 0; dev_dbg(codec->dev, "%s jack_insert:%d\n", __func__, jack_insert); @@ -1543,25 +1549,68 @@ static int rt5663_jack_detect(struct snd_soc_codec *codec, int jack_insert) RT5663_IRQ_POW_SAV_MASK, RT5663_IRQ_POW_SAV_EN); snd_soc_update_bits(codec, RT5663_IRQ_1, RT5663_EN_IRQ_JD1_MASK, RT5663_EN_IRQ_JD1_EN); - while (i < 5) { - msleep(sleep_time[i]); - val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & - 0x0003; - dev_dbg(codec->dev, "%s: MX-00e7 val=%x sleep %d\n", - __func__, val, sleep_time[i]); - i++; - if (val == 0x1 || val == 0x2 || val == 0x3) + + while (true) { + regmap_read(rt5663->regmap, RT5663_INT_ST_2, &val); + if (!(val & 0x80)) + usleep_range(10000, 10005); + else break; + + if (i > 200) + break; + i++; } + + val = snd_soc_read(codec, RT5663_EM_JACK_TYPE_2) & 0x0003; dev_dbg(codec->dev, "%s val = %d\n", __func__, val); + + snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, + RT5663_OSW_HP_L_MASK | RT5663_OSW_HP_R_MASK, + RT5663_OSW_HP_L_EN | RT5663_OSW_HP_R_EN); + switch (val) { case 1: case 2: rt5663->jack_type = SND_JACK_HEADSET; rt5663_enable_push_button_irq(codec, true); + + if (rt5663->pdata.dc_offset_l_manual_mic) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2, + rt5663->pdata.dc_offset_l_manual_mic >> + 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3, + rt5663->pdata.dc_offset_l_manual_mic & + 0xffff); + } + + if (rt5663->pdata.dc_offset_r_manual_mic) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5, + rt5663->pdata.dc_offset_r_manual_mic >> + 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6, + rt5663->pdata.dc_offset_r_manual_mic & + 0xffff); + } break; default: rt5663->jack_type = SND_JACK_HEADPHONE; + + if (rt5663->pdata.dc_offset_l_manual) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2, + rt5663->pdata.dc_offset_l_manual >> 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_3, + rt5663->pdata.dc_offset_l_manual & + 0xffff); + } + + if (rt5663->pdata.dc_offset_r_manual) { + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_5, + rt5663->pdata.dc_offset_r_manual >> 16); + regmap_write(rt5663->regmap, RT5663_MIC_DECRO_6, + rt5663->pdata.dc_offset_r_manual & + 0xffff); + } break; } } else { @@ -1590,7 +1639,8 @@ static irqreturn_t rt5663_irq(int irq, void *data) { struct rt5663_priv *rt5663 = data; - dev_dbg(rt5663->codec->dev, "%s IRQ queue work\n", __func__); + dev_dbg(regmap_get_device(rt5663->regmap), "%s IRQ queue work\n", + __func__); queue_delayed_work(system_wq, &rt5663->jack_detect_work, msecs_to_jiffies(250)); @@ -1656,6 +1706,9 @@ static void rt5663_jack_detect_work(struct work_struct *work) default: dev_err(codec->dev, "Unknown CODEC Version\n"); } + + /* Delay the jack insert report to avoid pop noise */ + msleep(30); } else { /* jack is already in, report button event */ report = SND_JACK_HEADSET; @@ -1953,13 +2006,9 @@ static const struct snd_kcontrol_new rt5663_adda_r_mix[] = { static const struct snd_kcontrol_new rt5663_sto1_dac_l_mix[] = { SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, RT5663_M_DAC_L1_STO_L_SHIFT, 1, 1), - SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, - RT5663_M_DAC_R1_STO_L_SHIFT, 1, 1), }; static const struct snd_kcontrol_new rt5663_sto1_dac_r_mix[] = { - SOC_DAPM_SINGLE("DAC L Switch", RT5663_STO_DAC_MIXER, - RT5663_M_DAC_L1_STO_R_SHIFT, 1, 1), SOC_DAPM_SINGLE("DAC R Switch", RT5663_STO_DAC_MIXER, RT5663_M_DAC_R1_STO_R_SHIFT, 1, 1), }; @@ -2024,10 +2073,6 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, RT5663_HP_SIG_SRC1_SILENCE); } else { snd_soc_write(codec, RT5663_DEPOP_2, 0x3003); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, - 0x000b); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, - 0x0030); snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_DIS); snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371); @@ -2036,6 +2081,8 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7766); snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa); snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777); + snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000, + 0x8000); snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x3000); } @@ -2050,9 +2097,36 @@ static int rt5663_hp_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x0); snd_soc_update_bits(codec, RT5663_HP_CHARGE_PUMP_1, RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0); - snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x000b, - 0x000b); + } + break; + + default: + return 0; + } + + return 0; +} + +static int rt5663_charge_pump_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (rt5663->codec_ver == CODEC_VER_0) { + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, + 0x0030); + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, + 0x0003); + } + break; + + case SND_SOC_DAPM_POST_PMD: + if (rt5663->codec_ver == CODEC_VER_0) { + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0); + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0); } break; @@ -2182,6 +2256,9 @@ static const struct snd_soc_dapm_widget rt5663_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC R", NULL, SND_SOC_NOPM, 0, 0), /* Headphone*/ + SND_SOC_DAPM_SUPPLY("HP Charge Pump", SND_SOC_NOPM, 0, 0, + rt5663_charge_pump_event, SND_SOC_DAPM_PRE_PMU | + SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5663_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), @@ -2330,14 +2407,13 @@ static const struct snd_soc_dapm_route rt5663_dapm_routes[] = { { "DAC R1", NULL, "ADDA MIXR" }, { "STO1 DAC MIXL", "DAC L Switch", "DAC L1" }, - { "STO1 DAC MIXL", "DAC R Switch", "DAC R1" }, { "STO1 DAC MIXL", NULL, "STO1 DAC L Power" }, { "STO1 DAC MIXL", NULL, "STO1 DAC Filter" }, { "STO1 DAC MIXR", "DAC R Switch", "DAC R1" }, - { "STO1 DAC MIXR", "DAC L Switch", "DAC L1" }, { "STO1 DAC MIXR", NULL, "STO1 DAC R Power" }, { "STO1 DAC MIXR", NULL, "STO1 DAC Filter" }, + { "HP Amp", NULL, "HP Charge Pump" }, { "HP Amp", NULL, "DAC L" }, { "HP Amp", NULL, "DAC R" }, }; @@ -2860,7 +2936,7 @@ static int rt5663_resume(struct snd_soc_codec *codec) #define RT5663_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) -static struct snd_soc_dai_ops rt5663_aif_dai_ops = { +static const struct snd_soc_dai_ops rt5663_aif_dai_ops = { .hw_params = rt5663_hw_params, .set_fmt = rt5663_set_dai_fmt, .set_sysclk = rt5663_set_dai_sysclk, @@ -2891,7 +2967,7 @@ static struct snd_soc_dai_driver rt5663_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5663 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5663 = { .probe = rt5663_probe, .remove = rt5663_remove, .suspend = rt5663_suspend, @@ -2956,7 +3032,7 @@ MODULE_DEVICE_TABLE(of, rt5663_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5663_acpi_match[] = { +static const struct acpi_device_id rt5663_acpi_match[] = { { "10EC5663", 0}, {}, }; @@ -2986,47 +3062,76 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) { int value, count; - regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0280); - regmap_write(rt5663->regmap, RT5663_GLB_CLK, 0x8000); - regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); - regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa2be); + regmap_write(rt5663->regmap, RT5663_RESET, 0x0000); msleep(20); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf2be); - regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400); - regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000); - regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); - regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0003); - regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c); - regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1111); + regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_4, 0x00a1); + regmap_write(rt5663->regmap, RT5663_RC_CLK, 0x0380); + regmap_write(rt5663->regmap, RT5663_GLB_CLK, 0x8000); + regmap_write(rt5663->regmap, RT5663_ADDA_CLK_1, 0x1000); + regmap_write(rt5663->regmap, RT5663_VREF_RECMIX, 0x0032); + regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x000c); + regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x0324); + regmap_write(rt5663->regmap, RT5663_DIG_MISC, 0x8001); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xa23b); + msleep(30); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0xf23b); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8000); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x0008); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_1, 0xffff); regmap_write(rt5663->regmap, RT5663_PRE_DIV_GATING_2, 0xffff); + regmap_write(rt5663->regmap, RT5663_CBJ_1, 0x8c10); + regmap_write(rt5663->regmap, RT5663_IL_CMD_2, 0x00c1); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb880); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4110); + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_2, 0x4118); + + count = 0; + while (true) { + regmap_read(rt5663->regmap, RT5663_INT_ST_2, &value); + if (!(value & 0x80)) + usleep_range(10000, 10005); + else + break; + + if (++count > 200) + break; + } + + regmap_write(rt5663->regmap, RT5663_HP_IMP_SEN_19, 0x0000); regmap_write(rt5663->regmap, RT5663_DEPOP_2, 0x3003); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0038); regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x003b); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_2, 0x8400); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x8df8); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x8003); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_3, 0x018c); regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_1, 0x1e32); - regmap_write(rt5663->regmap, RT5663_HP_CHARGE_PUMP_2, 0x1371); regmap_write(rt5663->regmap, RT5663_DACREF_LDO, 0x3b0b); - regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x2080); + msleep(40); + regmap_write(rt5663->regmap, RT5663_STO_DAC_MIXER, 0x0000); regmap_write(rt5663->regmap, RT5663_BYPASS_STO_DAC, 0x000c); - regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xabba); + regmap_write(rt5663->regmap, RT5663_HP_BIAS, 0xafaa); regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_1, 0x2224); regmap_write(rt5663->regmap, RT5663_HP_OUT_EN, 0x8088); regmap_write(rt5663->regmap, RT5663_STO_DRE_9, 0x0017); regmap_write(rt5663->regmap, RT5663_STO_DRE_10, 0x0017); regmap_write(rt5663->regmap, RT5663_STO1_ADC_MIXER, 0x4040); + regmap_write(rt5663->regmap, RT5663_CHOP_ADC, 0x3000); regmap_write(rt5663->regmap, RT5663_RECMIX, 0x0005); regmap_write(rt5663->regmap, RT5663_ADDA_RST, 0xc000); regmap_write(rt5663->regmap, RT5663_STO1_HPF_ADJ1, 0x3320); regmap_write(rt5663->regmap, RT5663_HP_CALIB_2, 0x00c9); regmap_write(rt5663->regmap, RT5663_DUMMY_1, 0x004c); - regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x7766); - regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4702); - msleep(200); + regmap_write(rt5663->regmap, RT5663_ANA_BIAS_CUR_1, 0x1111); + regmap_write(rt5663->regmap, RT5663_BIAS_CUR_8, 0x4402); + regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x3311); regmap_write(rt5663->regmap, RT5663_HP_CALIB_1, 0x0069); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06c2); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x7b00); - regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xfb00); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_3, 0x06ce); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6800); + regmap_write(rt5663->regmap, RT5663_CHARGE_PUMP_2, 0x1100); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0057); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe800); + count = 0; while (true) { regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value); @@ -3039,11 +3144,56 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) return; count++; } + + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0x6200); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_7, 0x0059); + regmap_write(rt5663->regmap, RT5663_HP_CALIB_1_1, 0xe200); + + count = 0; + while (true) { + regmap_read(rt5663->regmap, RT5663_HP_CALIB_1_1, &value); + if (value & 0x8000) + usleep_range(10000, 10005); + else + break; + + if (count > 200) + return; + count++; + } + + regmap_write(rt5663->regmap, RT5663_EM_JACK_TYPE_1, 0xb8e0); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_1, 0x003b); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_DIG_1, 0x0000); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x000b); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_DEPOP_1, 0x0008); + usleep_range(10000, 10005); + regmap_write(rt5663->regmap, RT5663_PWR_ANLG_2, 0x0000); + usleep_range(10000, 10005); +} + +static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) +{ + device_property_read_u32(dev, "realtek,dc_offset_l_manual", + &rt5663->pdata.dc_offset_l_manual); + device_property_read_u32(dev, "realtek,dc_offset_r_manual", + &rt5663->pdata.dc_offset_r_manual); + device_property_read_u32(dev, "realtek,dc_offset_l_manual_mic", + &rt5663->pdata.dc_offset_l_manual_mic); + device_property_read_u32(dev, "realtek,dc_offset_r_manual_mic", + &rt5663->pdata.dc_offset_r_manual_mic); + + return 0; } static int rt5663_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5663_priv *rt5663; int ret; unsigned int val; @@ -3057,6 +3207,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, rt5663); + if (pdata) + rt5663->pdata = *pdata; + else + rt5663_parse_dp(rt5663, &i2c->dev); + regmap = devm_regmap_init_i2c(i2c, &temp_regmap); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); @@ -3105,6 +3260,20 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, regmap_write(rt5663->regmap, RT5663_RESET, 0); dev_dbg(&i2c->dev, "calibrate done\n"); + switch (rt5663->codec_ver) { + case CODEC_VER_1: + break; + case CODEC_VER_0: + ret = regmap_register_patch(rt5663->regmap, rt5663_patch_list, + ARRAY_SIZE(rt5663_patch_list)); + if (ret != 0) + dev_warn(&i2c->dev, + "Failed to apply regmap patch: %d\n", ret); + break; + default: + dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); + } + /* GPIO1 as IRQ */ regmap_update_bits(rt5663->regmap, RT5663_GPIO_1, RT5663_GP1_PIN_MASK, RT5663_GP1_PIN_IRQ); diff --git a/sound/soc/codecs/rt5663.h b/sound/soc/codecs/rt5663.h index 4621812c94d8..c5a9b69579ad 100644 --- a/sound/soc/codecs/rt5663.h +++ b/sound/soc/codecs/rt5663.h @@ -12,6 +12,8 @@ #ifndef __RT5663_H__ #define __RT5663_H__ +#include + /* Info */ #define RT5663_RESET 0x0000 #define RT5663_VENDOR_ID 0x00fd diff --git a/sound/soc/codecs/rt5665.c b/sound/soc/codecs/rt5665.c index e597c893536d..f05d362c4e23 100644 --- a/sound/soc/codecs/rt5665.c +++ b/sound/soc/codecs/rt5665.c @@ -1381,6 +1381,16 @@ static void rt5665_jack_detect_handler(struct work_struct *work) mutex_unlock(&rt5665->calibrate_mutex); } +static const char * const rt5665_clk_sync[] = { + "I2S1_1", "I2S1_2", "I2S2", "I2S3", "IF2 Slave", "IF3 Slave" +}; + +static const struct soc_enum rt5665_enum[] = { + SOC_ENUM_SINGLE(RT5665_I2S1_SDP, 11, 5, rt5665_clk_sync), + SOC_ENUM_SINGLE(RT5665_I2S2_SDP, 11, 5, rt5665_clk_sync), + SOC_ENUM_SINGLE(RT5665_I2S3_SDP, 11, 5, rt5665_clk_sync), +}; + static const struct snd_kcontrol_new rt5665_snd_controls[] = { /* Headphone Output Volume */ SOC_DOUBLE_R_EXT_TLV("Headphone Playback Volume", RT5665_HPL_GAIN, @@ -1392,6 +1402,9 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = { RT5665_L_VOL_SFT, 15, 1, snd_soc_get_volsw, rt5665_mono_vol_put, mono_vol_tlv), + SOC_SINGLE_TLV("MONOVOL Playback Volume", RT5665_MONO_OUT, + RT5665_L_VOL_SFT, 39, 1, out_vol_tlv), + /* Output Volume */ SOC_DOUBLE_TLV("OUT Playback Volume", RT5665_LOUT, RT5665_L_VOL_SFT, RT5665_R_VOL_SFT, 39, 1, out_vol_tlv), @@ -1446,6 +1459,11 @@ static const struct snd_kcontrol_new rt5665_snd_controls[] = { SOC_DOUBLE_TLV("STO2 ADC Boost Gain Volume", RT5665_STO2_ADC_BOOST, RT5665_STO2_ADC_L_BST_SFT, RT5665_STO2_ADC_R_BST_SFT, 3, 0, adc_bst_tlv), + + /* I2S3 CLK Source */ + SOC_ENUM("I2S1 Master Clk Sel", rt5665_enum[0]), + SOC_ENUM("I2S2 Master Clk Sel", rt5665_enum[1]), + SOC_ENUM("I2S3 Master Clk Sel", rt5665_enum[2]), }; /** @@ -4098,9 +4116,12 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, rt5665->lrck[dai->id] = params_rate(params); pre_div = rl6231_get_clk_info(rt5665->sysclk, rt5665->lrck[dai->id]); if (pre_div < 0) { - dev_err(codec->dev, "Unsupported clock setting %d for DAI %d\n", - rt5665->lrck[dai->id], dai->id); - return -EINVAL; + dev_warn(codec->dev, "Force using PLL"); + snd_soc_codec_set_pll(codec, 0, RT5665_PLL1_S_MCLK, + rt5665->sysclk, rt5665->lrck[dai->id] * 512); + snd_soc_codec_set_sysclk(codec, RT5665_SCLK_S_PLL1, 0, + rt5665->lrck[dai->id] * 512, 0); + pre_div = 1; } frame_size = snd_soc_params_to_frame_size(params); if (frame_size < 0) { @@ -4183,6 +4204,15 @@ static int rt5665_hw_params(struct snd_pcm_substream *substream, break; } + if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S2_M_PD_MASK, pre_div << RT5665_I2S2_M_PD_SFT); + } + if (rt5665->master[RT5665_AIF3]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S3_M_PD_MASK, pre_div << RT5665_I2S3_M_PD_SFT); + } + return 0; } @@ -4259,7 +4289,7 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, int source, unsigned int freq, int dir) { struct rt5665_priv *rt5665 = snd_soc_codec_get_drvdata(codec); - unsigned int reg_val = 0; + unsigned int reg_val = 0, src = 0; if (freq == rt5665->sysclk && clk_id == rt5665->sysclk_src) return 0; @@ -4267,12 +4297,15 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, switch (clk_id) { case RT5665_SCLK_S_MCLK: reg_val |= RT5665_SCLK_SRC_MCLK; + src = RT5665_CLK_SRC_MCLK; break; case RT5665_SCLK_S_PLL1: reg_val |= RT5665_SCLK_SRC_PLL1; + src = RT5665_CLK_SRC_PLL1; break; case RT5665_SCLK_S_RCCLK: reg_val |= RT5665_SCLK_SRC_RCCLK; + src = RT5665_CLK_SRC_RCCLK; break; default: dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); @@ -4280,6 +4313,16 @@ static int rt5665_set_codec_sysclk(struct snd_soc_codec *codec, int clk_id, } snd_soc_update_bits(codec, RT5665_GLB_CLK, RT5665_SCLK_SRC_MASK, reg_val); + + if (rt5665->master[RT5665_AIF2_1] || rt5665->master[RT5665_AIF2_2]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S2_SRC_MASK, src << RT5665_I2S2_SRC_SFT); + } + if (rt5665->master[RT5665_AIF3]) { + snd_soc_update_bits(codec, RT5665_I2S_M_CLK_CTRL_1, + RT5665_I2S3_SRC_MASK, src << RT5665_I2S3_SRC_SFT); + } + rt5665->sysclk = freq; rt5665->sysclk_src = clk_id; @@ -4562,7 +4605,7 @@ static struct snd_soc_dai_driver rt5665_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5665 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5665 = { .probe = rt5665_probe, .remove = rt5665_remove, .suspend = rt5665_suspend, @@ -4927,7 +4970,7 @@ MODULE_DEVICE_TABLE(of, rt5665_of_match); #endif #ifdef CONFIG_ACPI -static struct acpi_device_id rt5665_acpi_match[] = { +static const struct acpi_device_id rt5665_acpi_match[] = { {"10EC5665", 0,}, {"10EC5666", 0,}, {"10EC5668", 0,}, diff --git a/sound/soc/codecs/rt5665.h b/sound/soc/codecs/rt5665.h index d95249c4c47b..5ddebd6a4a1b 100644 --- a/sound/soc/codecs/rt5665.h +++ b/sound/soc/codecs/rt5665.h @@ -1628,6 +1628,27 @@ #define RT5665_PWR_CLK1M_PD (0x0 << 8) #define RT5665_PWR_CLK1M_PU (0x1 << 8) +/* I2S Master Mode Clock Control 1 (0x00a0) */ +#define RT5665_CLK_SRC_MCLK (0x0) +#define RT5665_CLK_SRC_PLL1 (0x1) +#define RT5665_CLK_SRC_RCCLK (0x2) +#define RT5665_I2S_PD_1 (0x0) +#define RT5665_I2S_PD_2 (0x1) +#define RT5665_I2S_PD_3 (0x2) +#define RT5665_I2S_PD_4 (0x3) +#define RT5665_I2S_PD_6 (0x4) +#define RT5665_I2S_PD_8 (0x5) +#define RT5665_I2S_PD_12 (0x6) +#define RT5665_I2S_PD_16 (0x7) +#define RT5665_I2S2_SRC_MASK (0x3 << 12) +#define RT5665_I2S2_SRC_SFT 12 +#define RT5665_I2S2_M_PD_MASK (0x7 << 8) +#define RT5665_I2S2_M_PD_SFT 8 +#define RT5665_I2S3_SRC_MASK (0x3 << 4) +#define RT5665_I2S3_SRC_SFT 4 +#define RT5665_I2S3_M_PD_MASK (0x7 << 0) +#define RT5665_I2S3_M_PD_SFT 0 + /* EQ Control 1 (0x00b0) */ #define RT5665_EQ_SRC_DAC (0x0 << 15) diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c index 054b613cb0d0..9545764ef3eb 100644 --- a/sound/soc/codecs/rt5670.c +++ b/sound/soc/codecs/rt5670.c @@ -1151,20 +1151,15 @@ static const char * const rt5670_stereo_adc1_src[] = { static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc1_enum, RT5670_STO1_ADC_MIXER, RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); -static const struct snd_kcontrol_new rt5670_sto_adc_l1_mux = - SOC_DAPM_ENUM("Stereo1 ADC L1 source", rt5670_stereo1_adc1_enum); - -static const struct snd_kcontrol_new rt5670_sto_adc_r1_mux = - SOC_DAPM_ENUM("Stereo1 ADC R1 source", rt5670_stereo1_adc1_enum); +static const struct snd_kcontrol_new rt5670_sto_adc_1_mux = + SOC_DAPM_ENUM("Stereo1 ADC 1 Mux", rt5670_stereo1_adc1_enum); static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc1_enum, RT5670_STO2_ADC_MIXER, RT5670_ADC_1_SRC_SFT, rt5670_stereo_adc1_src); -static const struct snd_kcontrol_new rt5670_sto2_adc_l1_mux = - SOC_DAPM_ENUM("Stereo2 ADC L1 source", rt5670_stereo2_adc1_enum); +static const struct snd_kcontrol_new rt5670_sto2_adc_1_mux = + SOC_DAPM_ENUM("Stereo2 ADC 1 Mux", rt5670_stereo2_adc1_enum); -static const struct snd_kcontrol_new rt5670_sto2_adc_r1_mux = - SOC_DAPM_ENUM("Stereo2 ADC R1 source", rt5670_stereo2_adc1_enum); /* MX-27 MX-26 [11] */ static const char * const rt5670_stereo_adc2_src[] = { @@ -1174,20 +1169,15 @@ static const char * const rt5670_stereo_adc2_src[] = { static SOC_ENUM_SINGLE_DECL(rt5670_stereo1_adc2_enum, RT5670_STO1_ADC_MIXER, RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); -static const struct snd_kcontrol_new rt5670_sto_adc_l2_mux = - SOC_DAPM_ENUM("Stereo1 ADC L2 source", rt5670_stereo1_adc2_enum); - -static const struct snd_kcontrol_new rt5670_sto_adc_r2_mux = - SOC_DAPM_ENUM("Stereo1 ADC R2 source", rt5670_stereo1_adc2_enum); +static const struct snd_kcontrol_new rt5670_sto_adc_2_mux = + SOC_DAPM_ENUM("Stereo1 ADC 2 Mux", rt5670_stereo1_adc2_enum); static SOC_ENUM_SINGLE_DECL(rt5670_stereo2_adc2_enum, RT5670_STO2_ADC_MIXER, RT5670_ADC_2_SRC_SFT, rt5670_stereo_adc2_src); -static const struct snd_kcontrol_new rt5670_sto2_adc_l2_mux = - SOC_DAPM_ENUM("Stereo2 ADC L2 source", rt5670_stereo2_adc2_enum); +static const struct snd_kcontrol_new rt5670_sto2_adc_2_mux = + SOC_DAPM_ENUM("Stereo2 ADC 2 Mux", rt5670_stereo2_adc2_enum); -static const struct snd_kcontrol_new rt5670_sto2_adc_r2_mux = - SOC_DAPM_ENUM("Stereo2 ADC R2 source", rt5670_stereo2_adc2_enum); /* MX-27 MX26 [10] */ static const char * const rt5670_stereo_adc_src[] = { @@ -1642,23 +1632,23 @@ static const struct snd_soc_dapm_widget rt5670_dapm_widgets[] = { SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0, &rt5670_sto1_dmic_mux), SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_l2_mux), + &rt5670_sto_adc_2_mux), SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_r2_mux), + &rt5670_sto_adc_2_mux), SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_l1_mux), + &rt5670_sto_adc_1_mux), SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto_adc_r1_mux), + &rt5670_sto_adc_1_mux), SND_SOC_DAPM_MUX("Stereo2 DMIC Mux", SND_SOC_NOPM, 0, 0, &rt5670_sto2_dmic_mux), SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_l2_mux), + &rt5670_sto2_adc_2_mux), SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_r2_mux), + &rt5670_sto2_adc_2_mux), SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_l1_mux), + &rt5670_sto2_adc_1_mux), SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0, - &rt5670_sto2_adc_r1_mux), + &rt5670_sto2_adc_1_mux), SND_SOC_DAPM_MUX("Stereo2 ADC LR Mux", SND_SOC_NOPM, 0, 0, &rt5670_sto2_adc_lr_mux), SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0, @@ -2743,6 +2733,7 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, + .symmetric_rates = 1, }, { .name = "rt5670-aif2", @@ -2762,10 +2753,11 @@ static struct snd_soc_dai_driver rt5670_dai[] = { .formats = RT5670_FORMATS, }, .ops = &rt5670_aif_dai_ops, + .symmetric_rates = 1, }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5670 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5670 = { .probe = rt5670_probe, .remove = rt5670_remove, .suspend = rt5670_suspend, @@ -2859,6 +2851,17 @@ static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode2[] = { {} }; +static const struct dmi_system_id dmi_platform_intel_bytcht_jdmode3[] = { + { + .ident = "Dell Venue 8 Pro 5855", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5855"), + }, + }, + {} +}; + static int rt5670_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2888,6 +2891,11 @@ static int rt5670_i2c_probe(struct i2c_client *i2c, rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; rt5670->pdata.dev_gpio = true; rt5670->pdata.jd_mode = 2; + } else if (dmi_check_system(dmi_platform_intel_bytcht_jdmode3)) { + rt5670->pdata.dmic_en = true; + rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; + rt5670->pdata.dev_gpio = true; + rt5670->pdata.jd_mode = 3; } rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap); diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index 6f629278d982..0791fec398fb 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -779,9 +780,7 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) return 0; } -static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0); -static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); static const DECLARE_TLV_DB_SCALE(st_vol_tlv, -4650, 150, 0); @@ -4624,35 +4623,27 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset) struct regmap_irq_chip_data *data = rt5677->irq_data; int irq; - if (offset >= RT5677_GPIO1 && offset <= RT5677_GPIO3) { - if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || - (rt5677->pdata.jd1_gpio == 2 && - offset == RT5677_GPIO2) || - (rt5677->pdata.jd1_gpio == 3 && - offset == RT5677_GPIO3)) { - irq = RT5677_IRQ_JD1; - } else { - return -ENXIO; - } - } - - if (offset >= RT5677_GPIO4 && offset <= RT5677_GPIO6) { - if ((rt5677->pdata.jd2_gpio == 1 && offset == RT5677_GPIO4) || - (rt5677->pdata.jd2_gpio == 2 && - offset == RT5677_GPIO5) || - (rt5677->pdata.jd2_gpio == 3 && - offset == RT5677_GPIO6)) { - irq = RT5677_IRQ_JD2; - } else if ((rt5677->pdata.jd3_gpio == 1 && - offset == RT5677_GPIO4) || - (rt5677->pdata.jd3_gpio == 2 && - offset == RT5677_GPIO5) || - (rt5677->pdata.jd3_gpio == 3 && - offset == RT5677_GPIO6)) { - irq = RT5677_IRQ_JD3; - } else { - return -ENXIO; - } + if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) || + (rt5677->pdata.jd1_gpio == 2 && + offset == RT5677_GPIO2) || + (rt5677->pdata.jd1_gpio == 3 && + offset == RT5677_GPIO3)) { + irq = RT5677_IRQ_JD1; + } else if ((rt5677->pdata.jd2_gpio == 1 && offset == RT5677_GPIO4) || + (rt5677->pdata.jd2_gpio == 2 && + offset == RT5677_GPIO5) || + (rt5677->pdata.jd2_gpio == 3 && + offset == RT5677_GPIO6)) { + irq = RT5677_IRQ_JD2; + } else if ((rt5677->pdata.jd3_gpio == 1 && + offset == RT5677_GPIO4) || + (rt5677->pdata.jd3_gpio == 2 && + offset == RT5677_GPIO5) || + (rt5677->pdata.jd3_gpio == 3 && + offset == RT5677_GPIO6)) { + irq = RT5677_IRQ_JD3; + } else { + return -ENXIO; } return regmap_irq_get_virq(data, irq); @@ -4968,7 +4959,7 @@ static struct snd_soc_dai_driver rt5677_dai[] = { }, }; -static struct snd_soc_codec_driver soc_codec_dev_rt5677 = { +static const struct snd_soc_codec_driver soc_codec_dev_rt5677 = { .probe = rt5677_probe, .remove = rt5677_remove, .suspend = rt5677_suspend, @@ -5021,24 +5012,21 @@ static const struct regmap_config rt5677_regmap = { static const struct i2c_device_id rt5677_i2c_id[] = { { "rt5677", RT5677 }, { "rt5676", RT5676 }, - { "RT5677CE:00", RT5677 }, { } }; MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); static const struct of_device_id rt5677_of_match[] = { - { .compatible = "realtek,rt5677", }, + { .compatible = "realtek,rt5677", RT5677 }, { } }; MODULE_DEVICE_TABLE(of, rt5677_of_match); -#ifdef CONFIG_ACPI static const struct acpi_device_id rt5677_acpi_match[] = { { "RT5677CE", RT5677 }, { } }; MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match); -#endif static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677, struct device *dev) @@ -5148,7 +5136,6 @@ static void rt5677_free_irq(struct i2c_client *i2c) static int rt5677_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct rt5677_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5677_priv *rt5677; int ret; unsigned int val; @@ -5160,16 +5147,25 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, rt5677); - rt5677->type = id->driver_data; + if (i2c->dev.of_node) { + const struct of_device_id *match_id; + + match_id = of_match_device(rt5677_of_match, &i2c->dev); + if (match_id) + rt5677->type = (enum rt5677_type)match_id->data; - if (pdata) - rt5677->pdata = *pdata; - else if (i2c->dev.of_node) rt5677_read_device_properties(rt5677, &i2c->dev); - else if (ACPI_HANDLE(&i2c->dev)) + } else if (ACPI_HANDLE(&i2c->dev)) { + const struct acpi_device_id *acpi_id; + + acpi_id = acpi_match_device(rt5677_acpi_match, &i2c->dev); + if (acpi_id) + rt5677->type = (enum rt5677_type)acpi_id->driver_data; + rt5677_read_acpi_properties(rt5677, &i2c->dev); - else + } else { return -EINVAL; + } /* pow-ldo2 and reset are optional. The codec pins may be statically * connected on the board without gpios. If the gpio device property diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index d46855a42c40..97239973edc4 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h @@ -12,7 +12,6 @@ #ifndef __RT5677_H__ #define __RT5677_H__ -#include #include #include @@ -1761,6 +1760,35 @@ enum { RT5677_I2S4_SOURCE = (0x1 << 18), }; +enum rt5677_dmic2_clk { + RT5677_DMIC_CLK1 = 0, + RT5677_DMIC_CLK2 = 1, +}; + +struct rt5677_platform_data { + /* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */ + bool in1_diff; + bool in2_diff; + bool lout1_diff; + bool lout2_diff; + bool lout3_diff; + /* DMIC2 clock source selection */ + enum rt5677_dmic2_clk dmic2_clk_pin; + + /* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */ + u8 gpio_config[6]; + + /* jd1 can select 0 ~ 3 as OFF, GPIO1, GPIO2 and GPIO3 respectively */ + unsigned int jd1_gpio; + /* jd2 and jd3 can select 0 ~ 3 as + OFF, GPIO4, GPIO5 and GPIO6 respectively */ + unsigned int jd2_gpio; + unsigned int jd3_gpio; + + /* Set MICBIAS1 VDD 1v8 or 3v3 */ + bool micbias1_vdd_3v3; +}; + struct rt5677_priv { struct snd_soc_codec *codec; struct rt5677_platform_data pdata; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 80f6d1da7095..f2bb4feba3b6 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -1248,7 +1248,7 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver sgtl5000_driver = { +static const struct snd_soc_codec_driver sgtl5000_driver = { .probe = sgtl5000_probe, .remove = sgtl5000_remove, .set_bias_level = sgtl5000_set_bias_level, diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 5344f4aa8fde..354dc0d64f11 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -236,7 +236,7 @@ static struct regmap *si476x_get_regmap(struct device *dev) return dev_get_regmap(dev->parent, NULL); } -static struct snd_soc_codec_driver soc_codec_dev_si476x = { +static const struct snd_soc_codec_driver soc_codec_dev_si476x = { .get_regmap = si476x_get_regmap, .component_driver = { .dapm_widgets = si476x_dapm_widgets, diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 6bfd25c289d1..7ae8c181d1a4 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -429,13 +429,15 @@ static int sirf_audio_codec_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = { +static const struct snd_soc_codec_driver soc_codec_device_sirf_audio_codec = { .probe = sirf_audio_codec_probe, .remove = sirf_audio_codec_remove, - .dapm_widgets = sirf_audio_codec_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), - .dapm_routes = sirf_audio_codec_map, - .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), + .component_driver = { + .dapm_widgets = sirf_audio_codec_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sirf_audio_codec_dapm_widgets), + .dapm_routes = sirf_audio_codec_map, + .num_dapm_routes = ARRAY_SIZE(sirf_audio_codec_map), + }, .idle_bias_off = true, }; diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index eae54c37cff9..887923e68849 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -883,7 +883,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver sn95031_codec = { +static const struct snd_soc_codec_driver sn95031_codec = { .probe = sn95031_codec_probe, .set_bias_level = sn95031_set_vaud_bias, .idle_bias_off = true, diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index 234f87b54838..7acd05140a81 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c @@ -37,7 +37,7 @@ static const struct snd_soc_dapm_route dir_routes[] = { SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) -static struct snd_soc_codec_driver soc_codec_spdif_dir = { +static const struct snd_soc_codec_driver soc_codec_spdif_dir = { .component_driver = { .dapm_widgets = dir_widgets, .num_dapm_widgets = ARRAY_SIZE(dir_widgets), diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index ee367536a498..063a64ff82d3 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c @@ -37,7 +37,7 @@ static const struct snd_soc_dapm_route dit_routes[] = { { "spdif-out", NULL, "Playback" }, }; -static struct snd_soc_codec_driver soc_codec_spdif_dit = { +static const struct snd_soc_codec_driver soc_codec_spdif_dit = { .component_driver = { .dapm_widgets = dit_widgets, .num_dapm_widgets = ARRAY_SIZE(dit_widgets), diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c index 38a85f3adc80..15486fd16269 100644 --- a/sound/soc/codecs/ssm2518.c +++ b/sound/soc/codecs/ssm2518.c @@ -710,7 +710,7 @@ static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id, SSM2518_POWER1_NO_BCLK, val); } -static struct snd_soc_codec_driver ssm2518_codec_driver = { +static const struct snd_soc_codec_driver ssm2518_codec_driver = { .set_bias_level = ssm2518_set_bias_level, .set_sysclk = ssm2518_set_sysclk, .idle_bias_off = true, diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 993bde29ca1b..9b341c23f62b 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -591,7 +591,7 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec) return ret; } -static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { +static const struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { .probe = ssm260x_codec_probe, .resume = ssm2602_resume, .set_bias_level = ssm2602_set_bias_level, diff --git a/sound/soc/codecs/ssm4567.c b/sound/soc/codecs/ssm4567.c index a622623e8558..4afeddef7728 100644 --- a/sound/soc/codecs/ssm4567.c +++ b/sound/soc/codecs/ssm4567.c @@ -417,7 +417,7 @@ static struct snd_soc_dai_driver ssm4567_dai = { .ops = &ssm4567_dai_ops, }; -static struct snd_soc_codec_driver ssm4567_codec_driver = { +static const struct snd_soc_codec_driver ssm4567_codec_driver = { .set_bias_level = ssm4567_set_bias_level, .idle_bias_off = true, diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 0790ae8530d9..5b888476d9ff 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -847,8 +847,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, msleep(300); sta32x_watchdog_stop(sta32x); - if (sta32x->gpiod_nreset) - gpiod_set_value(sta32x->gpiod_nreset, 0); + gpiod_set_value(sta32x->gpiod_nreset, 0); regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 9de7fe8af255..c66363a2cac7 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -307,7 +307,7 @@ static int stac9766_codec_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { +static const struct snd_soc_codec_driver soc_codec_dev_stac9766 = { .component_driver = { .controls = stac9766_snd_ac97_controls, .num_controls = ARRAY_SIZE(stac9766_snd_ac97_controls), diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 8840f72f3c4a..87307dd0f12e 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -192,7 +192,7 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec, * pll_clk = (.5 * pll_clkin * J.D) / 2^p * Need to fill in J and D here based on incoming freq */ - unsigned int d; + unsigned int d, q, t; u8 j; u8 pll_sel = (tas2552->pll_clk_id << 3) & TAS2552_PLL_SRC_MASK; u8 p = snd_soc_read(codec, TAS2552_PLL_CTRL_1); @@ -200,9 +200,12 @@ static int tas2552_setup_pll(struct snd_soc_codec *codec, p = (p >> 7); recalc: - j = (pll_clk * 2 * (1 << p)) / pll_clkin; - d = (pll_clk * 2 * (1 << p)) % pll_clkin; - d /= (pll_clkin / 10000); + t = (pll_clk * 2) << p; + j = t / pll_clkin; + d = t % pll_clkin; + t = pll_clkin / 10000; + q = d / (t + 1); + d = q + ((9999 - pll_clkin % 10000) * (d / t - q)) / 10000; if (d && (pll_clkin < 512000 || pll_clkin > 9200000)) { if (tas2552->pll_clk_id == TAS2552_PLL_CLKIN_BCLK) { @@ -660,7 +663,7 @@ static int tas2552_resume(struct snd_soc_codec *codec) #define tas2552_resume NULL #endif -static struct snd_soc_codec_driver soc_codec_dev_tas2552 = { +static const struct snd_soc_codec_driver soc_codec_dev_tas2552 = { .probe = tas2552_codec_probe, .remove = tas2552_codec_remove, .suspend = tas2552_suspend, diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index b7de857abb16..199272d5cb6a 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -885,7 +885,7 @@ static int tas5086_remove(struct snd_soc_codec *codec) return 0; }; -static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { +static const struct snd_soc_codec_driver soc_codec_dev_tas5086 = { .probe = tas5086_probe, .remove = tas5086_remove, .suspend = tas5086_soc_suspend, diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index c65b917598d2..a736a2a6976c 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c @@ -483,7 +483,7 @@ static const struct snd_soc_dapm_route tas5720_audio_map[] = { { "OUT", NULL, "DAC" }, }; -static struct snd_soc_codec_driver soc_codec_dev_tas5720 = { +static const struct snd_soc_codec_driver soc_codec_dev_tas5720 = { .probe = tas5720_codec_probe, .remove = tas5720_codec_remove, .suspend = tas5720_suspend, @@ -507,7 +507,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5720 = { #define TAS5720_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE |\ SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops tas5720_speaker_dai_ops = { +static const struct snd_soc_dai_ops tas5720_speaker_dai_ops = { .hw_params = tas5720_hw_params, .set_fmt = tas5720_set_dai_fmt, .set_tdm_slot = tas5720_set_dai_tdm_slot, diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 628a8eeaab68..3d42138a7974 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -576,7 +576,7 @@ static int tlv320aic23_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { +static const struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { .probe = tlv320aic23_codec_probe, .resume = tlv320aic23_resume, .set_bias_level = tlv320aic23_set_bias_level, diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 14aa96d41719..89421caaeb70 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -319,7 +319,7 @@ static int aic26_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver aic26_soc_codec_dev = { +static const struct snd_soc_codec_driver aic26_soc_codec_dev = { .probe = aic26_probe, .component_driver = { .controls = aic26_snd_controls, diff --git a/sound/soc/codecs/tlv320aic26.h b/sound/soc/codecs/tlv320aic26.h index 629b85e75409..1f2879b7a080 100644 --- a/sound/soc/codecs/tlv320aic26.h +++ b/sound/soc/codecs/tlv320aic26.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Texas Instruments TLV320AIC26 low power audio CODEC * register definitions diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index d7d03c92cb8a..54a87a905eb6 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1185,7 +1185,7 @@ static int aic31xx_codec_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_driver_aic31xx = { +static const struct snd_soc_codec_driver soc_codec_driver_aic31xx = { .probe = aic31xx_codec_probe, .remove = aic31xx_codec_remove, .set_bias_level = aic31xx_set_bias_level, diff --git a/sound/soc/codecs/tlv320aic32x4-i2c.c b/sound/soc/codecs/tlv320aic32x4-i2c.c index 59606cf3008f..385fa2e9525a 100644 --- a/sound/soc/codecs/tlv320aic32x4-i2c.c +++ b/sound/soc/codecs/tlv320aic32x4-i2c.c @@ -47,12 +47,14 @@ static int aic32x4_i2c_remove(struct i2c_client *i2c) static const struct i2c_device_id aic32x4_i2c_id[] = { { "tlv320aic32x4", 0 }, + { "tlv320aic32x6", 1 }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, aic32x4_i2c_id); static const struct of_device_id aic32x4_of_id[] = { { .compatible = "ti,tlv320aic32x4", }, + { .compatible = "ti,tlv320aic32x6", }, { /* senitel */ } }; MODULE_DEVICE_TABLE(of, aic32x4_of_id); diff --git a/sound/soc/codecs/tlv320aic32x4-spi.c b/sound/soc/codecs/tlv320aic32x4-spi.c index 724fcdd491b2..07d78ae51e05 100644 --- a/sound/soc/codecs/tlv320aic32x4-spi.c +++ b/sound/soc/codecs/tlv320aic32x4-spi.c @@ -48,12 +48,14 @@ static int aic32x4_spi_remove(struct spi_device *spi) static const struct spi_device_id aic32x4_spi_id[] = { { "tlv320aic32x4", 0 }, + { "tlv320aic32x6", 1 }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, aic32x4_spi_id); static const struct of_device_id aic32x4_of_id[] = { { .compatible = "ti,tlv320aic32x4", }, + { .compatible = "ti,tlv320aic32x6", }, { /* senitel */ } }; MODULE_DEVICE_TABLE(of, aic32x4_of_id); diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 28fdfc5ec544..e694f5f04eb9 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -74,6 +74,152 @@ struct aic32x4_priv { struct regulator *supply_iov; struct regulator *supply_dv; struct regulator *supply_av; + + struct aic32x4_setup_data *setup; + struct device *dev; +}; + +static int aic32x4_get_mfp1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + + val = snd_soc_read(codec, AIC32X4_DINCTL); + + ucontrol->value.integer.value[0] = (val & 0x01); + + return 0; +}; + +static int aic32x4_set_mfp2_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + u8 gpio_check; + + val = snd_soc_read(codec, AIC32X4_DOUTCTL); + gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED); + if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) { + printk(KERN_ERR "%s: MFP2 is not configure as a GPIO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0] == (val & AIC32X4_MFP2_GPIO_OUT_HIGH)) + return 0; + + if (ucontrol->value.integer.value[0]) + val |= ucontrol->value.integer.value[0]; + else + val &= ~AIC32X4_MFP2_GPIO_OUT_HIGH; + + snd_soc_write(codec, AIC32X4_DOUTCTL, val); + + return 0; +}; + +static int aic32x4_get_mfp3_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + + val = snd_soc_read(codec, AIC32X4_SCLKCTL); + + ucontrol->value.integer.value[0] = (val & 0x01); + + return 0; +}; + +static int aic32x4_set_mfp4_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + u8 gpio_check; + + val = snd_soc_read(codec, AIC32X4_MISOCTL); + gpio_check = (val & AIC32X4_MFP_GPIO_ENABLED); + if (gpio_check != AIC32X4_MFP_GPIO_ENABLED) { + printk(KERN_ERR "%s: MFP4 is not configure as a GPIO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0] == (val & AIC32X4_MFP5_GPIO_OUT_HIGH)) + return 0; + + if (ucontrol->value.integer.value[0]) + val |= ucontrol->value.integer.value[0]; + else + val &= ~AIC32X4_MFP5_GPIO_OUT_HIGH; + + snd_soc_write(codec, AIC32X4_MISOCTL, val); + + return 0; +}; + +static int aic32x4_get_mfp5_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + + val = snd_soc_read(codec, AIC32X4_GPIOCTL); + ucontrol->value.integer.value[0] = ((val & 0x2) >> 1); + + return 0; +}; + +static int aic32x4_set_mfp5_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + u8 val; + u8 gpio_check; + + val = snd_soc_read(codec, AIC32X4_GPIOCTL); + gpio_check = (val & AIC32X4_MFP5_GPIO_OUTPUT); + if (gpio_check != AIC32X4_MFP5_GPIO_OUTPUT) { + printk(KERN_ERR "%s: MFP5 is not configure as a GPIO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0] == (val & 0x1)) + return 0; + + if (ucontrol->value.integer.value[0]) + val |= ucontrol->value.integer.value[0]; + else + val &= 0xfe; + + snd_soc_write(codec, AIC32X4_GPIOCTL, val); + + return 0; +}; + +static const struct snd_kcontrol_new aic32x4_mfp1[] = { + SOC_SINGLE_BOOL_EXT("MFP1 GPIO", 0, aic32x4_get_mfp1_gpio, NULL), +}; + +static const struct snd_kcontrol_new aic32x4_mfp2[] = { + SOC_SINGLE_BOOL_EXT("MFP2 GPIO", 0, NULL, aic32x4_set_mfp2_gpio), +}; + +static const struct snd_kcontrol_new aic32x4_mfp3[] = { + SOC_SINGLE_BOOL_EXT("MFP3 GPIO", 0, aic32x4_get_mfp3_gpio, NULL), +}; + +static const struct snd_kcontrol_new aic32x4_mfp4[] = { + SOC_SINGLE_BOOL_EXT("MFP4 GPIO", 0, NULL, aic32x4_set_mfp4_gpio), +}; + +static const struct snd_kcontrol_new aic32x4_mfp5[] = { + SOC_SINGLE_BOOL_EXT("MFP5 GPIO", 0, aic32x4_get_mfp5_gpio, + aic32x4_set_mfp5_gpio), }; /* 0dB min, 0.5dB steps */ @@ -734,6 +880,52 @@ static struct snd_soc_dai_driver aic32x4_dai = { .symmetric_rates = 1, }; +static void aic32x4_setup_gpios(struct snd_soc_codec *codec) +{ + struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); + + /* setup GPIO functions */ + /* MFP1 */ + if (aic32x4->setup->gpio_func[0] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_DINCTL, + aic32x4->setup->gpio_func[0]); + snd_soc_add_codec_controls(codec, aic32x4_mfp1, + ARRAY_SIZE(aic32x4_mfp1)); + } + + /* MFP2 */ + if (aic32x4->setup->gpio_func[1] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_DOUTCTL, + aic32x4->setup->gpio_func[1]); + snd_soc_add_codec_controls(codec, aic32x4_mfp2, + ARRAY_SIZE(aic32x4_mfp2)); + } + + /* MFP3 */ + if (aic32x4->setup->gpio_func[2] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_SCLKCTL, + aic32x4->setup->gpio_func[2]); + snd_soc_add_codec_controls(codec, aic32x4_mfp3, + ARRAY_SIZE(aic32x4_mfp3)); + } + + /* MFP4 */ + if (aic32x4->setup->gpio_func[3] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_MISOCTL, + aic32x4->setup->gpio_func[3]); + snd_soc_add_codec_controls(codec, aic32x4_mfp4, + ARRAY_SIZE(aic32x4_mfp4)); + } + + /* MFP5 */ + if (aic32x4->setup->gpio_func[4] != AIC32X4_MFPX_DEFAULT_VALUE) { + snd_soc_write(codec, AIC32X4_GPIOCTL, + aic32x4->setup->gpio_func[4]); + snd_soc_add_codec_controls(codec, aic32x4_mfp5, + ARRAY_SIZE(aic32x4_mfp5)); + } +} + static int aic32x4_codec_probe(struct snd_soc_codec *codec) { struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); @@ -746,6 +938,9 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec) snd_soc_write(codec, AIC32X4_RESET, 0x01); + if (aic32x4->setup) + aic32x4_setup_gpios(codec); + /* Power platform configuration */ if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) { snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN | @@ -792,7 +987,7 @@ static int aic32x4_codec_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { +static const struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { .probe = aic32x4_codec_probe, .set_bias_level = aic32x4_set_bias_level, .suspend_bias_off = true, @@ -810,10 +1005,20 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = { static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, struct device_node *np) { + struct aic32x4_setup_data *aic32x4_setup; + + aic32x4_setup = devm_kzalloc(aic32x4->dev, sizeof(*aic32x4_setup), + GFP_KERNEL); + if (!aic32x4_setup) + return -ENOMEM; + aic32x4->swapdacs = false; aic32x4->micpga_routing = 0; aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0); + if (of_property_read_u32_array(np, "aic32x4-gpio-func", + aic32x4_setup->gpio_func, 5) >= 0) + aic32x4->setup = aic32x4_setup; return 0; } @@ -932,6 +1137,7 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap) if (aic32x4 == NULL) return -ENOMEM; + aic32x4->dev = dev; dev_set_drvdata(dev, aic32x4); if (pdata) { diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h index a197dd51addc..da7cec482bcb 100644 --- a/sound/soc/codecs/tlv320aic32x4.h +++ b/sound/soc/codecs/tlv320aic32x4.h @@ -44,8 +44,11 @@ int aic32x4_remove(struct device *dev); #define AIC32X4_IFACE4 31 #define AIC32X4_IFACE5 32 #define AIC32X4_IFACE6 33 +#define AIC32X4_GPIOCTL 52 #define AIC32X4_DOUTCTL 53 #define AIC32X4_DINCTL 54 +#define AIC32X4_MISOCTL 55 +#define AIC32X4_SCLKCTL 56 #define AIC32X4_DACSPB 60 #define AIC32X4_ADCSPB 61 #define AIC32X4_DACSETUP 63 diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 29bf8c81ae02..06f92571eba4 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -93,6 +93,8 @@ struct aic3x_priv { /* Selects the micbias voltage */ enum aic3x_micbias_voltage micbias_vg; + /* Output Common-Mode Voltage */ + u8 ocmv; }; static const struct reg_default aic3x_reg[] = { @@ -1572,6 +1574,10 @@ static int aic3x_init(struct snd_soc_codec *codec) break; } + /* Output common-mode voltage = 1.5 V */ + snd_soc_update_bits(codec, HPOUT_SC, HPOUT_SC_OCMV_MASK, + aic3x->ocmv << HPOUT_SC_OCMV_SHIFT); + return 0; } @@ -1684,7 +1690,7 @@ static int aic3x_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_aic3x = { +static const struct snd_soc_codec_driver soc_codec_dev_aic3x = { .set_bias_level = aic3x_set_bias_level, .idle_bias_off = true, .probe = aic3x_probe, @@ -1699,6 +1705,43 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { }, }; +static void aic3x_configure_ocmv(struct i2c_client *client) +{ + struct device_node *np = client->dev.of_node; + struct aic3x_priv *aic3x = i2c_get_clientdata(client); + u32 value; + int dvdd, avdd; + + if (np && !of_property_read_u32(np, "ai3x-ocmv", &value)) { + /* OCMV setting is forced by DT */ + if (value <= 3) { + aic3x->ocmv = value; + return; + } + } + + dvdd = regulator_get_voltage(aic3x->supplies[1].consumer); + avdd = regulator_get_voltage(aic3x->supplies[2].consumer); + + if (avdd > 3600000 || dvdd > 1950000) { + dev_warn(&client->dev, + "Too high supply voltage(s) AVDD: %d, DVDD: %d\n", + avdd, dvdd); + } else if (avdd == 3600000 && dvdd == 1950000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_8V; + } else if (avdd > 3300000 && dvdd > 1800000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_65V; + } else if (avdd > 3000000 && dvdd > 1650000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_5V; + } else if (avdd >= 2700000 && dvdd >= 1525000) { + aic3x->ocmv = HPOUT_SC_OCMV_1_35V; + } else { + dev_warn(&client->dev, + "Invalid supply voltage(s) AVDD: %d, DVDD: %d\n", + avdd, dvdd); + } +} + /* * AIC3X 2 wire address can be up to 4 devices with device addresses * 0x18, 0x19, 0x1A, 0x1B @@ -1816,6 +1859,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, goto err_gpio; } + aic3x_configure_ocmv(i2c); + if (aic3x->model == AIC3X_MODEL_3007) { ret = regmap_register_patch(aic3x->regmap, aic3007_class_d, ARRAY_SIZE(aic3007_class_d)); diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 89fa692df206..34c35196aa0d 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -243,6 +243,14 @@ #define MICBIAS_LEVEL_SHIFT (6) #define MICBIAS_LEVEL_MASK (3 << 6) +/* HPOUT_SC */ +#define HPOUT_SC_OCMV_MASK (3 << 6) +#define HPOUT_SC_OCMV_SHIFT (6) +#define HPOUT_SC_OCMV_1_35V 0 +#define HPOUT_SC_OCMV_1_5V 1 +#define HPOUT_SC_OCMV_1_65V 2 +#define HPOUT_SC_OCMV_1_8V 3 + /* headset detection / button API */ /* The AIC3x supports detection of stereo headsets (GND + left + right signal) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 7bcf01efdf9a..5b94a151539c 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -1433,7 +1433,7 @@ static int dac33_soc_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { +static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { .read = dac33_read_reg_cache, .write = dac33_write_locked, .set_bias_level = dac33_set_bias_level, diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index a2104d68169d..c482b2e7a7d2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -2191,7 +2191,7 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { +static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = { .probe = twl4030_soc_probe, .remove = twl4030_soc_remove, .read = twl4030_read, diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 2b6ad09e0886..1773ff84ee3b 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1123,8 +1123,8 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->plug_irq = platform_get_irq(pdev, 0); if (priv->plug_irq < 0) { - dev_err(codec->dev, "invalid irq\n"); - return -EINVAL; + dev_err(codec->dev, "invalid irq: %d\n", priv->plug_irq); + return priv->plug_irq; } INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); @@ -1155,7 +1155,7 @@ static int twl6040_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { +static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = { .probe = twl6040_probe, .remove = twl6040_remove, .read = twl6040_read, diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 5fdee874406d..77c9cc4467b8 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -518,7 +518,7 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_uda134x = { +static const struct snd_soc_codec_driver soc_codec_dev_uda134x = { .probe = uda134x_soc_probe, .set_bias_level = uda134x_set_bias_level, .suspend_bias_off = true, diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h index e41ab38c6f69..664618c2571c 100644 --- a/sound/soc/codecs/uda134x.h +++ b/sound/soc/codecs/uda134x.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _UDA134X_CODEC_H #define _UDA134X_CODEC_H diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 61cdc79840e7..926c81ae8185 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -720,7 +720,7 @@ static int uda1380_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { +static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = { .probe = uda1380_probe, .read = uda1380_read_reg_cache, .write = uda1380_write, diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index fcffb6e707d9..942f1644973e 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -480,7 +480,7 @@ static int wl1273_remove(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_codec_driver soc_codec_dev_wl1273 = { +static const struct snd_soc_codec_driver soc_codec_dev_wl1273 = { .probe = wl1273_probe, .remove = wl1273_remove, diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 1fe358e6be61..72486bf072f2 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -2017,7 +2017,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = { }, }; -static struct snd_compr_ops wm5102_compr_ops = { +static const struct snd_compr_ops wm5102_compr_ops = { .open = wm5102_open, .free = wm_adsp_compr_free, .set_params = wm_adsp_compr_set_params, @@ -2027,7 +2027,7 @@ static struct snd_compr_ops wm5102_compr_ops = { .copy = wm_adsp_compr_copy, }; -static struct snd_soc_platform_driver wm5102_compr_platform = { +static const struct snd_soc_platform_driver wm5102_compr_platform = { .compr_ops = &wm5102_compr_ops, }; diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 1bc942152eff..858a24fc28e8 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2372,7 +2372,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = { }, }; -static struct snd_compr_ops wm5110_compr_ops = { +static const struct snd_compr_ops wm5110_compr_ops = { .open = wm5110_open, .free = wm_adsp_compr_free, .set_params = wm_adsp_compr_set_params, @@ -2382,7 +2382,7 @@ static struct snd_compr_ops wm5110_compr_ops = { .copy = wm_adsp_compr_copy, }; -static struct snd_soc_platform_driver wm5110_compr_platform = { +static const struct snd_soc_platform_driver wm5110_compr_platform = { .compr_ops = &wm5110_compr_ops, }; diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 6d0a2723bfde..c7c33e98fbcb 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -100,7 +100,7 @@ static const struct snd_soc_dapm_route wm8523_dapm_routes[] = { { "LINEVOUTR", NULL, "DAC" }, }; -static struct { +static const struct { int value; int ratio; } lrclk_ratios[WM8523_NUM_RATES] = { @@ -113,10 +113,10 @@ static struct { { 7, 1152 }, }; -static struct { +static const struct { int value; int ratio; -} bclk_ratios[WM8523_NUM_RATES] = { +} bclk_ratios[] = { { 2, 32 }, { 3, 64 }, { 4, 128 }, diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c new file mode 100644 index 000000000000..856a6950a451 --- /dev/null +++ b/sound/soc/codecs/wm8524.c @@ -0,0 +1,261 @@ +/* + * wm8524.c -- WM8524 ALSA SoC Audio driver + * + * Copyright 2009 Wolfson Microelectronics plc + * Copyright 2017 NXP + * + * Based on WM8523 ALSA SoC Audio driver written by Mark Brown + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WM8524_NUM_RATES 7 + +/* codec private data */ +struct wm8524_priv { + struct gpio_desc *mute; + unsigned int sysclk; + unsigned int rate_constraint_list[WM8524_NUM_RATES]; + struct snd_pcm_hw_constraint_list rate_constraint; +}; + + +static const struct snd_soc_dapm_widget wm8524_dapm_widgets[] = { +SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_OUTPUT("LINEVOUTL"), +SND_SOC_DAPM_OUTPUT("LINEVOUTR"), +}; + +static const struct snd_soc_dapm_route wm8524_dapm_routes[] = { + { "LINEVOUTL", NULL, "DAC" }, + { "LINEVOUTR", NULL, "DAC" }, +}; + +static const struct { + int value; + int ratio; +} lrclk_ratios[WM8524_NUM_RATES] = { + { 1, 128 }, + { 2, 192 }, + { 3, 256 }, + { 4, 384 }, + { 5, 512 }, + { 6, 768 }, + { 7, 1152 }, +}; + +static int wm8524_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + + /* The set of sample rates that can be supported depends on the + * MCLK supplied to the CODEC - enforce this. + */ + if (!wm8524->sysclk) { + dev_err(codec->dev, + "No MCLK configured, call set_sysclk() on init\n"); + return -EINVAL; + } + + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &wm8524->rate_constraint); + + gpiod_set_value_cansleep(wm8524->mute, 1); + + return 0; +} + +static void wm8524_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + + gpiod_set_value_cansleep(wm8524->mute, 0); +} + +static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + unsigned int val; + int i, j = 0; + + wm8524->sysclk = freq; + + wm8524->rate_constraint.count = 0; + for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { + val = freq / lrclk_ratios[i].ratio; + /* Check that it's a standard rate since core can't + * cope with others and having the odd rates confuses + * constraint matching. + */ + switch (val) { + case 8000: + case 32000: + case 44100: + case 48000: + case 88200: + case 96000: + case 176400: + case 192000: + dev_dbg(codec->dev, "Supported sample rate: %dHz\n", + val); + wm8524->rate_constraint_list[j++] = val; + wm8524->rate_constraint.count++; + break; + default: + dev_dbg(codec->dev, "Skipping sample rate: %dHz\n", + val); + } + } + + /* Need at least one supported rate... */ + if (wm8524->rate_constraint.count == 0) + return -EINVAL; + + return 0; +} + +static int wm8524_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK | + SND_SOC_DAIFMT_MASTER_MASK); + + if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS)) { + dev_err(codec_dai->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + return 0; +} + +static int wm8524_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +{ + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(dai->codec); + + if (wm8524->mute) + gpiod_set_value_cansleep(wm8524->mute, mute); + + return 0; +} + +#define WM8524_RATES SNDRV_PCM_RATE_8000_192000 + +#define WM8524_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) + +static const struct snd_soc_dai_ops wm8524_dai_ops = { + .startup = wm8524_startup, + .shutdown = wm8524_shutdown, + .set_sysclk = wm8524_set_dai_sysclk, + .set_fmt = wm8524_set_fmt, + .mute_stream = wm8524_mute_stream, +}; + +static struct snd_soc_dai_driver wm8524_dai = { + .name = "wm8524-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = WM8524_RATES, + .formats = WM8524_FORMATS, + }, + .ops = &wm8524_dai_ops, +}; + +static int wm8524_probe(struct snd_soc_codec *codec) +{ + struct wm8524_priv *wm8524 = snd_soc_codec_get_drvdata(codec); + + wm8524->rate_constraint.list = &wm8524->rate_constraint_list[0]; + wm8524->rate_constraint.count = + ARRAY_SIZE(wm8524->rate_constraint_list); + + return 0; +} + +static const struct snd_soc_codec_driver soc_codec_dev_wm8524 = { + .probe = wm8524_probe, + + .component_driver = { + .dapm_widgets = wm8524_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8524_dapm_widgets), + .dapm_routes = wm8524_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8524_dapm_routes), + }, +}; + +static const struct of_device_id wm8524_of_match[] = { + { .compatible = "wlf,wm8524" }, + { /* sentinel*/ } +}; +MODULE_DEVICE_TABLE(of, wm8524_of_match); + +static int wm8524_codec_probe(struct platform_device *pdev) +{ + struct wm8524_priv *wm8524; + int ret; + + wm8524 = devm_kzalloc(&pdev->dev, sizeof(struct wm8524_priv), + GFP_KERNEL); + if (wm8524 == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, wm8524); + + wm8524->mute = devm_gpiod_get(&pdev->dev, "wlf,mute", GPIOD_OUT_LOW); + if (IS_ERR(wm8524->mute)) { + ret = PTR_ERR(wm8524->mute); + dev_err(&pdev->dev, "Failed to get mute line: %d\n", ret); + return ret; + } + + ret = snd_soc_register_codec(&pdev->dev, + &soc_codec_dev_wm8524, &wm8524_dai, 1); + if (ret < 0) + dev_err(&pdev->dev, "Failed to register codec: %d\n", ret); + + return ret; +} + +static int wm8524_codec_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +static struct platform_driver wm8524_codec_driver = { + .probe = wm8524_codec_probe, + .remove = wm8524_codec_remove, + .driver = { + .name = "wm8524-codec", + .of_match_table = wm8524_of_match, + }, +}; +module_platform_driver(wm8524_codec_driver); + +MODULE_DESCRIPTION("ASoC WM8524 driver"); +MODULE_AUTHOR("Mihai Serban "); +MODULE_ALIAS("platform:wm8524-codec"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index af95d648265b..fc69b87443d8 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -623,8 +623,7 @@ int wm8804_probe(struct device *dev, struct regmap *regmap) return ret; } - if (wm8804->reset) - gpiod_set_value_cansleep(wm8804->reset, 1); + gpiod_set_value_cansleep(wm8804->reset, 1); ret = regmap_read(regmap, WM8804_RST_DEVID1, &id1); if (ret < 0) { diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h index 4478b40c86e3..91811aa158d8 100644 --- a/sound/soc/codecs/wm8993.h +++ b/sound/soc/codecs/wm8993.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef WM8993_H #define WM8993_H diff --git a/sound/soc/codecs/wm9713.h b/sound/soc/codecs/wm9713.h index 7ecffc563016..f0800dcca9b8 100644 --- a/sound/soc/codecs/wm9713.h +++ b/sound/soc/codecs/wm9713.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * wm9713.h -- WM9713 Soc Audio driver */ diff --git a/sound/soc/codecs/zx_aud96p22.c b/sound/soc/codecs/zx_aud96p22.c index 032fb7cf6cbd..ca1932d13738 100644 --- a/sound/soc/codecs/zx_aud96p22.c +++ b/sound/soc/codecs/zx_aud96p22.c @@ -261,7 +261,7 @@ static const struct snd_soc_dapm_route aud96p22_dapm_routes[] = { { "LINEOUTMN", NULL, "LD2" }, }; -static struct snd_soc_codec_driver aud96p22_driver = { +static const struct snd_soc_codec_driver aud96p22_driver = { .component_driver = { .controls = aud96p22_snd_controls, .num_controls = ARRAY_SIZE(aud96p22_snd_controls), @@ -312,7 +312,7 @@ static int aud96p22_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } -static struct snd_soc_dai_ops aud96p22_dai_ops = { +static const struct snd_soc_dai_ops aud96p22_dai_ops = { .set_fmt = aud96p22_set_fmt, }; @@ -382,7 +382,7 @@ static int aud96p22_i2c_remove(struct i2c_client *i2c) return 0; } -const struct of_device_id aud96p22_dt_ids[] = { +static const struct of_device_id aud96p22_dt_ids[] = { { .compatible = "zte,zx-aud96p22", }, { } }; diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile index f883933c1a19..23c6592eb31a 100644 --- a/sound/soc/davinci/Makefile +++ b/sound/soc/davinci/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # DAVINCI Platform Support snd-soc-edma-objs := edma-pcm.o snd-soc-davinci-i2s-objs := davinci-i2s.o diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 56ec1d301ac2..f395bbc7c354 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -1602,8 +1602,6 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of( pdata = devm_kmemdup(&pdev->dev, match->data, sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dev_err(&pdev->dev, - "Failed to allocate memory for pdata\n"); ret = -ENOMEM; return pdata; } @@ -1853,6 +1851,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev) mcasp->context.xrsr_regs = devm_kzalloc(&pdev->dev, sizeof(u32) * mcasp->num_serializer, GFP_KERNEL); + if (!mcasp->context.xrsr_regs) { + ret = -ENOMEM; + goto err; + } #endif mcasp->serial_dir = pdata->serial_dir; mcasp->version = pdata->version; diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index c77d9218795a..5415b72393fa 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -210,11 +210,8 @@ static int davinci_vcif_probe(struct platform_device *pdev) davinci_vcif_dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_vcif_dev), GFP_KERNEL); - if (!davinci_vcif_dev) { - dev_dbg(&pdev->dev, - "could not allocate memory for private data\n"); + if (!davinci_vcif_dev) return -ENOMEM; - } /* DMA tx params */ davinci_vcif_dev->davinci_vc = davinci_vc; diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index 916067638180..e27e21f8569a 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -381,7 +381,7 @@ static int dw_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) return ret; } -static struct snd_soc_dai_ops dw_i2s_dai_ops = { +static const struct snd_soc_dai_ops dw_i2s_dai_ops = { .startup = dw_i2s_startup, .shutdown = dw_i2s_shutdown, .hw_params = dw_i2s_hw_params, @@ -617,10 +617,8 @@ static int dw_i2s_probe(struct platform_device *pdev) const char *clk_id; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (!dev) { - dev_warn(&pdev->dev, "kzalloc fail\n"); + if (!dev) return -ENOMEM; - } dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL); if (!dw_i2s_dai) diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index d28dc25c9375..c67bf1139e1e 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # MPC8610 HPCD Machine Support snd-soc-mpc8610-hpcd-objs := mpc8610_hpcd.o obj-$(CONFIG_SND_SOC_MPC8610_HPCD) += snd-soc-mpc8610-hpcd.o diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 9998aea23597..2db4d0c80d33 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -683,7 +683,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(&priv->card, priv); ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); - if (ret) + if (ret && ret != -EPROBE_DEFER) dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); asrc_fail: diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index 8cfffa70c144..806d39927318 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -542,7 +542,7 @@ static int fsl_asrc_dai_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static struct snd_soc_dai_ops fsl_asrc_dai_ops = { +static const struct snd_soc_dai_ops fsl_asrc_dai_ops = { .hw_params = fsl_asrc_dai_hw_params, .hw_free = fsl_asrc_dai_hw_free, .trigger = fsl_asrc_dai_trigger, diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index 282d841840b1..e1b97e59275a 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -20,7 +20,7 @@ #define FSL_ASRC_DMABUF_SIZE (256 * 1024) -static struct snd_pcm_hardware snd_imx_hardware = { +static const struct snd_pcm_hardware snd_imx_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -279,10 +279,8 @@ static int fsl_asrc_dma_startup(struct snd_pcm_substream *substream) struct fsl_asrc_pair *pair; pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL); - if (!pair) { - dev_err(dev, "failed to allocate pair\n"); + if (!pair) return -ENOMEM; - } pair->asrc_priv = asrc_priv; diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index ccadefceeff2..0c11f434a374 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -63,7 +63,6 @@ struct dma_object { struct ccsr_dma_channel __iomem *channel; unsigned int irq; bool assigned; - char path[1]; }; /* @@ -870,7 +869,7 @@ static struct device_node *find_ssi_node(struct device_node *dma_channel_np) return NULL; } -static struct snd_pcm_ops fsl_dma_ops = { +static const struct snd_pcm_ops fsl_dma_ops = { .open = fsl_dma_open, .close = fsl_dma_close, .ioctl = snd_pcm_lib_ioctl, @@ -897,20 +896,18 @@ static int fsl_soc_dma_probe(struct platform_device *pdev) ret = of_address_to_resource(ssi_np, 0, &res); if (ret) { - dev_err(&pdev->dev, "could not determine resources for %s\n", - ssi_np->full_name); + dev_err(&pdev->dev, "could not determine resources for %pOF\n", + ssi_np); of_node_put(ssi_np); return ret; } - dma = kzalloc(sizeof(*dma) + strlen(np->full_name), GFP_KERNEL); + dma = kzalloc(sizeof(*dma), GFP_KERNEL); if (!dma) { - dev_err(&pdev->dev, "could not allocate dma object\n"); of_node_put(ssi_np); return -ENOMEM; } - strcpy(dma->path, np->full_name); dma->dai.ops = &fsl_dma_ops; dma->dai.pcm_new = fsl_dma_new; dma->dai.pcm_free = fsl_dma_free_dma_buffers; diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 809a069d490b..cef79a1a620b 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -620,7 +620,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static struct snd_soc_dai_ops fsl_esai_dai_ops = { +static const struct snd_soc_dai_ops fsl_esai_dai_ops = { .startup = fsl_esai_startup, .shutdown = fsl_esai_shutdown, .trigger = fsl_esai_trigger, diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 1ff467c9598a..7e6cc4da0088 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -626,7 +626,7 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops fsl_spdif_dai_ops = { +static const struct snd_soc_dai_ops fsl_spdif_dai_ops = { .startup = fsl_spdif_startup, .hw_params = fsl_spdif_hw_params, .trigger = fsl_spdif_trigger, diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 173cb8496641..64598d1183f8 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1432,10 +1432,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private), GFP_KERNEL); - if (!ssi_private) { - dev_err(&pdev->dev, "could not allocate DAI object\n"); + if (!ssi_private) return -ENOMEM; - } ssi_private->soc = of_id->data; ssi_private->dev = &pdev->dev; diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index fc57da341d61..392d5eef356d 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c @@ -268,13 +268,13 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, ret = of_property_read_u32(child, "fsl,audmux-port", &port); if (ret) { - dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n", - child->full_name); + dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%pOF\"\n", + child); continue; } if (!of_property_read_bool(child, "fsl,port-config")) { - dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n", - child->full_name); + dev_warn(&pdev->dev, "child node \"%pOF\" does not have property fsl,port-config\n", + child); continue; } @@ -292,15 +292,15 @@ static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, } if (ret != -EOVERFLOW) { - dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n", - i, child->full_name); + dev_err(&pdev->dev, "Failed to read u32 at index %d of child %pOF\n", + i, child); continue; } if (audmux_type == IMX31_AUDMUX) { if (i % 2) { - dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n", - child->full_name); + dev_err(&pdev->dev, "One pdcr value is missing in child node %pOF\n", + child); continue; } imx_audmux_v2_configure_port(port, ptcr, pdcr); diff --git a/sound/soc/fsl/imx-audmux.h b/sound/soc/fsl/imx-audmux.h index 38a4209af7c6..f75b4d3aeacc 100644 --- a/sound/soc/fsl/imx-audmux.h +++ b/sound/soc/fsl/imx-audmux.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __IMX_AUDMUX_H #define __IMX_AUDMUX_H diff --git a/sound/soc/fsl/imx-es8328.c b/sound/soc/fsl/imx-es8328.c index 20e7400e2611..9953438086e4 100644 --- a/sound/soc/fsl/imx-es8328.c +++ b/sound/soc/fsl/imx-es8328.c @@ -203,9 +203,6 @@ static int imx_es8328_remove(struct platform_device *pdev) { struct imx_es8328_data *data = platform_get_drvdata(pdev); - snd_soc_jack_free_gpios(&headset_jack, ARRAY_SIZE(headset_jack_gpios), - headset_jack_gpios); - snd_soc_unregister_card(&data->card); return 0; diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 92410f7ca1fa..4e5fefee111e 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -154,7 +154,7 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream return bytes_to_frames(substream->runtime, iprtd->offset); } -static struct snd_pcm_hardware snd_imx_hardware = { +static const struct snd_pcm_hardware snd_imx_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -227,7 +227,7 @@ static int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, return ret; } -static struct snd_pcm_ops imx_pcm_ops = { +static const struct snd_pcm_ops imx_pcm_ops = { .open = snd_imx_open, .close = snd_imx_close, .ioctl = snd_pcm_lib_ioctl, @@ -341,7 +341,7 @@ static void imx_pcm_fiq_free(struct snd_pcm *pcm) imx_pcm_free(pcm); } -static struct snd_soc_platform_driver imx_soc_platform_fiq = { +static const struct snd_soc_platform_driver imx_soc_platform_fiq = { .ops = &imx_pcm_ops, .pcm_new = imx_pcm_fiq_new, .pcm_free = imx_pcm_fiq_free, diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 1f7e70bfbd55..e63029f1aabc 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -287,7 +287,7 @@ psc_dma_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_pcm_ops psc_dma_ops = { +static const struct snd_pcm_ops psc_dma_ops = { .open = psc_dma_open, .close = psc_dma_close, .hw_free = psc_dma_hw_free, @@ -356,7 +356,7 @@ static void psc_dma_free(struct snd_pcm *pcm) } } -static struct snd_soc_platform_driver mpc5200_audio_dma_platform = { +static const struct snd_soc_platform_driver mpc5200_audio_dma_platform = { .ops = &psc_dma_ops, .pcm_new = &psc_dma_new, .pcm_free = &psc_dma_free, diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index dff253fde29a..d7ee33b5b9a8 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Freescale MPC5200 Audio DMA driver */ diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 9e000523a3b4..9dec293a4c4d 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-simple-card-utils-objs := simple-card-utils.o snd-soc-simple-card-objs := simple-card.o snd-soc-simple-scu-card-objs := simple-scu-card.o diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index de2550c7a96b..488c52f9405f 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -95,7 +95,7 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream) asoc_simple_card_clk_disable(&dai_props->codec_dai); } -static struct snd_soc_ops asoc_graph_card_ops = { +static const struct snd_soc_ops asoc_graph_card_ops = { .startup = asoc_graph_card_startup, .shutdown = asoc_graph_card_shutdown, }; @@ -325,6 +325,7 @@ MODULE_DEVICE_TABLE(of, asoc_graph_of_match); static struct platform_driver asoc_graph_card = { .driver = { .name = "asoc-audio-graph-card", + .pm = &snd_soc_pm_ops, .of_match_table = asoc_graph_of_match, }, .probe = asoc_graph_card_probe, diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c index 758ac06f3a99..a967aa143d51 100644 --- a/sound/soc/generic/audio-graph-scu-card.c +++ b/sound/soc/generic/audio-graph-scu-card.c @@ -56,7 +56,7 @@ static void asoc_graph_card_shutdown(struct snd_pcm_substream *substream) asoc_simple_card_clk_disable(dai_props); } -static struct snd_soc_ops asoc_graph_card_ops = { +static const struct snd_soc_ops asoc_graph_card_ops = { .startup = asoc_graph_card_startup, .shutdown = asoc_graph_card_shutdown, }; @@ -401,6 +401,7 @@ MODULE_DEVICE_TABLE(of, asoc_graph_of_match); static struct platform_driver asoc_graph_card = { .driver = { .name = "asoc-audio-graph-scu-card", + .pm = &snd_soc_pm_ops, .of_match_table = asoc_graph_of_match, }, .probe = asoc_graph_card_probe, diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index d72f7d58102f..3751a07de6aa 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -196,7 +196,11 @@ int asoc_simple_card_parse_clk(struct device *dev, simple_dai->sysclk = clk_get_rate(clk); } - dev_dbg(dev, "%s : sysclk = %d\n", name, simple_dai->sysclk); + if (of_property_read_bool(node, "system-clock-direction-out")) + simple_dai->clk_direction = SND_SOC_CLOCK_OUT; + + dev_dbg(dev, "%s : sysclk = %d, direction %d\n", name, + simple_dai->sysclk, simple_dai->clk_direction); return 0; } @@ -308,7 +312,8 @@ int asoc_simple_card_init_dai(struct snd_soc_dai *dai, int ret; if (simple_dai->sysclk) { - ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, 0); + ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk, + simple_dai->clk_direction); if (ret && ret != -ENOTSUPP) { dev_err(dai->dev, "simple-card: set_sysclk error\n"); return ret; diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index dfaf48ff88b0..6959a74a6f49 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -104,12 +104,6 @@ static int asoc_simple_card_init_jack(struct snd_soc_card *card, return 0; } -static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack) -{ - if (gpio_is_valid(sjack->gpio.gpio)) - snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio); -} - static int asoc_simple_card_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -493,10 +487,6 @@ err: static int asoc_simple_card_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct simple_card_data *priv = snd_soc_card_get_drvdata(card); - - asoc_simple_card_remove_jack(&priv->hp_jack); - asoc_simple_card_remove_jack(&priv->mic_jack); return asoc_simple_card_clean_reference(card); } diff --git a/sound/soc/generic/simple-scu-card.c b/sound/soc/generic/simple-scu-card.c index a75b385455c4..48606c63562a 100644 --- a/sound/soc/generic/simple-scu-card.c +++ b/sound/soc/generic/simple-scu-card.c @@ -191,6 +191,10 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv) if (!node) return -EINVAL; + ret = asoc_simple_card_of_parse_widgets(card, PREFIX); + if (ret < 0) + return ret; + ret = asoc_simple_card_of_parse_routing(card, PREFIX, 0); if (ret < 0) return ret; @@ -296,6 +300,7 @@ MODULE_DEVICE_TABLE(of, asoc_simple_of_match); static struct platform_driver asoc_simple_card = { .driver = { .name = "simple-scu-audio-card", + .pm = &snd_soc_pm_ops, .of_match_table = asoc_simple_of_match, }, .probe = asoc_simple_card_probe, diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c index b193d3beb253..0c8f86d4020e 100644 --- a/sound/soc/hisilicon/hi6210-i2s.c +++ b/sound/soc/hisilicon/hi6210-i2s.c @@ -517,7 +517,7 @@ static int hi6210_i2s_dai_probe(struct snd_soc_dai *dai) } -static struct snd_soc_dai_ops hi6210_i2s_dai_ops = { +static const struct snd_soc_dai_ops hi6210_i2s_dai_ops = { .trigger = hi6210_i2s_trigger, .hw_params = hi6210_i2s_hw_params, .set_fmt = hi6210_i2s_set_fmt, diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile index 0508c1ced636..3e7b0fd4fcbf 100644 --- a/sound/soc/img/Makefile +++ b/sound/soc/img/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o obj-$(CONFIG_SND_SOC_IMG_PARALLEL_OUT) += img-parallel-out.o diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c index 0389203f8560..567f9767fb73 100644 --- a/sound/soc/img/img-i2s-in.c +++ b/sound/soc/img/img-i2s-in.c @@ -443,7 +443,7 @@ static int img_i2s_in_probe(struct platform_device *pdev) SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE; i2s->dai_driver.ops = &img_i2s_in_dai_ops; - rst = devm_reset_control_get(dev, "rst"); + rst = devm_reset_control_get_exclusive(dev, "rst"); if (IS_ERR(rst)) { if (PTR_ERR(rst) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c index 5f997135a8ae..78b7f6cd675b 100644 --- a/sound/soc/img/img-i2s-out.c +++ b/sound/soc/img/img-i2s-out.c @@ -446,7 +446,7 @@ static int img_i2s_out_probe(struct platform_device *pdev) i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20); - i2s->rst = devm_reset_control_get(&pdev->dev, "rst"); + i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(i2s->rst)) { if (PTR_ERR(i2s->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c index 33ceb207ee70..23b0f0f6ec9c 100644 --- a/sound/soc/img/img-parallel-out.c +++ b/sound/soc/img/img-parallel-out.c @@ -224,7 +224,7 @@ static int img_prl_out_probe(struct platform_device *pdev) prl->base = base; - prl->rst = devm_reset_control_get(&pdev->dev, "rst"); + prl->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(prl->rst)) { if (PTR_ERR(prl->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c index 4d9953d318af..8adfd65d4390 100644 --- a/sound/soc/img/img-spdif-in.c +++ b/sound/soc/img/img-spdif-in.c @@ -727,7 +727,7 @@ static int img_spdif_in_probe(struct platform_device *pdev) if (ret) return ret; - rst = devm_reset_control_get(&pdev->dev, "rst"); + rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(rst)) { if (PTR_ERR(rst) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c index 08f93a5dadfe..383655da2e60 100644 --- a/sound/soc/img/img-spdif-out.c +++ b/sound/soc/img/img-spdif-out.c @@ -334,7 +334,7 @@ static int img_spdif_out_probe(struct platform_device *pdev) spdif->base = base; - spdif->rst = devm_reset_control_get(&pdev->dev, "rst"); + spdif->rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); if (IS_ERR(spdif->rst)) { if (PTR_ERR(spdif->rst) != -EPROBE_DEFER) dev_err(&pdev->dev, "No top level reset found\n"); diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index b301bfff1c09..b3c7f554ec30 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -255,11 +255,12 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode" - depends on X86_INTEL_LPSS && I2C + depends on X86_INTEL_LPSS && I2C && SPI select SND_SOC_INTEL_SST select SND_SOC_INTEL_SKYLAKE select SND_SOC_RT5663 select SND_SOC_RT5514 + select SND_SOC_RT5514_SPI select SND_SOC_MAX98927 select SND_SOC_HDAC_HDMI help diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index cdd495f7ee2c..62f37ffffdf0 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Core support obj-$(CONFIG_SND_SOC_INTEL_SST) += common/ diff --git a/sound/soc/intel/atom/Makefile b/sound/soc/intel/atom/Makefile index aa6548c6feab..1dc60471b399 100644 --- a/sound/soc/intel/atom/Makefile +++ b/sound/soc/intel/atom/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-sst-atom-hifi2-platform-objs := sst-mfld-platform-pcm.o \ sst-mfld-platform-compress.o \ sst-atom-controls.o diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index b082b31023d5..43e7fdd19f29 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -76,7 +76,7 @@ int sst_unregister_dsp(struct sst_device *dev) } EXPORT_SYMBOL_GPL(sst_unregister_dsp); -static struct snd_pcm_hardware sst_platform_pcm_hw = { +static const struct snd_pcm_hardware sst_platform_pcm_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_DOUBLE | SNDRV_PCM_INFO_PAUSE | @@ -471,7 +471,7 @@ static void sst_disable_ssp(struct snd_pcm_substream *substream, } } -static struct snd_soc_dai_ops sst_media_dai_ops = { +static const struct snd_soc_dai_ops sst_media_dai_ops = { .startup = sst_media_open, .shutdown = sst_media_close, .prepare = sst_media_prepare, @@ -480,11 +480,11 @@ static struct snd_soc_dai_ops sst_media_dai_ops = { .mute_stream = sst_media_digital_mute, }; -static struct snd_soc_dai_ops sst_compr_dai_ops = { +static const struct snd_soc_dai_ops sst_compr_dai_ops = { .mute_stream = sst_media_digital_mute, }; -static struct snd_soc_dai_ops sst_be_dai_ops = { +static const struct snd_soc_dai_ops sst_be_dai_ops = { .startup = sst_enable_ssp, .hw_params = sst_be_hw_params, .set_fmt = sst_set_format, @@ -705,7 +705,7 @@ static int sst_soc_probe(struct snd_soc_platform *platform) return sst_dsp_init_v2_dpcm(platform); } -static struct snd_soc_platform_driver sst_soc_platform_drv = { +static const struct snd_soc_platform_driver sst_soc_platform_drv = { .probe = sst_soc_probe, .ops = &sst_platform_ops, .compr_ops = &sst_platform_compr_ops, diff --git a/sound/soc/intel/atom/sst/Makefile b/sound/soc/intel/atom/sst/Makefile index fd21726361b5..795d1cf8f386 100644 --- a/sound/soc/intel/atom/sst/Makefile +++ b/sound/soc/intel/atom/sst/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o snd-intel-sst-pci-objs += sst_pci.o snd-intel-sst-acpi-objs += sst_acpi.o diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel/atom/sst/sst_drv_interface.c index ce689c5af5ab..71af5449be90 100644 --- a/sound/soc/intel/atom/sst/sst_drv_interface.c +++ b/sound/soc/intel/atom/sst/sst_drv_interface.c @@ -407,7 +407,7 @@ static int sst_cdev_caps(struct snd_compr_caps *caps) return 0; } -static struct snd_compr_codec_caps caps_mp3 = { +static const struct snd_compr_codec_caps caps_mp3 = { .num_descriptors = 1, .descriptor[0].max_ch = 2, .descriptor[0].sample_rates[0] = 48000, @@ -424,7 +424,7 @@ static struct snd_compr_codec_caps caps_mp3 = { .descriptor[0].formats = 0, }; -static struct snd_compr_codec_caps caps_aac = { +static const struct snd_compr_codec_caps caps_aac = { .num_descriptors = 2, .descriptor[1].max_ch = 2, .descriptor[0].sample_rates[0] = 48000, diff --git a/sound/soc/intel/atom/sst/sst_pci.c b/sound/soc/intel/atom/sst/sst_pci.c index 3a0b3bf0af97..6906ee624cf6 100644 --- a/sound/soc/intel/atom/sst/sst_pci.c +++ b/sound/soc/intel/atom/sst/sst_pci.c @@ -181,7 +181,7 @@ static void intel_sst_remove(struct pci_dev *pci) } /* PCI Routines */ -static struct pci_device_id intel_sst_ids[] = { +static const struct pci_device_id intel_sst_ids[] = { { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, { 0, } }; diff --git a/sound/soc/intel/baytrail/sst-baytrail-pcm.c b/sound/soc/intel/baytrail/sst-baytrail-pcm.c index 4765ad474544..c54529320f07 100644 --- a/sound/soc/intel/baytrail/sst-baytrail-pcm.c +++ b/sound/soc/intel/baytrail/sst-baytrail-pcm.c @@ -309,7 +309,7 @@ static int sst_byt_pcm_mmap(struct snd_pcm_substream *substream, return snd_pcm_lib_default_mmap(substream, vma); } -static struct snd_pcm_ops sst_byt_pcm_ops = { +static const struct snd_pcm_ops sst_byt_pcm_ops = { .open = sst_byt_pcm_open, .close = sst_byt_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -395,7 +395,7 @@ static int sst_byt_pcm_remove(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver byt_soc_platform = { +static const struct snd_soc_platform_driver byt_soc_platform = { .probe = sst_byt_pcm_probe, .remove = sst_byt_pcm_remove, .ops = &sst_byt_pcm_ops, diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index a5c5bc5732a2..69d2dfaeb00c 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-sst-haswell-objs := haswell.o snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c index 0c3a3cbcb884..7843104fadcb 100644 --- a/sound/soc/intel/boards/bxt_rt298.c +++ b/sound/soc/intel/boards/bxt_rt298.c @@ -114,7 +114,44 @@ static const struct snd_soc_dapm_route broxton_rt298_map[] = { { "iDisp2 Tx", NULL, "iDisp2_out"}, { "hifi1", NULL, "iDisp1 Tx"}, { "iDisp1 Tx", NULL, "iDisp1_out"}, +}; +static const struct snd_soc_dapm_route geminilake_rt298_map[] = { + /* speaker */ + {"Speaker", NULL, "SPOR"}, + {"Speaker", NULL, "SPOL"}, + + /* HP jack connectors - unknown if we have jack detect */ + {"Headphone Jack", NULL, "HPO Pin"}, + + /* other jacks */ + {"MIC1", NULL, "Mic Jack"}, + + /* digital mics */ + {"DMIC1 Pin", NULL, "DMIC2"}, + {"DMic", NULL, "SoC DMIC"}, + + {"HDMI1", NULL, "hif5-0 Output"}, + {"HDMI2", NULL, "hif6-0 Output"}, + {"HDMI2", NULL, "hif7-0 Output"}, + + /* CODEC BE connections */ + { "AIF1 Playback", NULL, "ssp2 Tx"}, + { "ssp2 Tx", NULL, "codec0_out"}, + { "ssp2 Tx", NULL, "codec1_out"}, + + { "codec0_in", NULL, "ssp2 Rx" }, + { "ssp2 Rx", NULL, "AIF1 Capture" }, + + { "dmic01_hifi", NULL, "DMIC01 Rx" }, + { "DMIC01 Rx", NULL, "Capture" }, + + { "hifi3", NULL, "iDisp3 Tx"}, + { "iDisp3 Tx", NULL, "iDisp3_out"}, + { "hifi2", NULL, "iDisp2 Tx"}, + { "iDisp2 Tx", NULL, "iDisp2_out"}, + { "hifi1", NULL, "iDisp1 Tx"}, + { "iDisp1 Tx", NULL, "iDisp1_out"}, }; static int broxton_rt298_fe_init(struct snd_soc_pcm_runtime *rtd) @@ -492,7 +529,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card) /* broxton audio machine driver for SPT + RT298S */ static struct snd_soc_card broxton_rt298 = { .name = "broxton-rt298", - .owner = THIS_MODULE, .dai_link = broxton_rt298_dais, .num_links = ARRAY_SIZE(broxton_rt298_dais), .controls = broxton_controls, @@ -506,9 +542,41 @@ static struct snd_soc_card broxton_rt298 = { }; +static struct snd_soc_card geminilake_rt298 = { + .name = "geminilake-rt298", + .dai_link = broxton_rt298_dais, + .num_links = ARRAY_SIZE(broxton_rt298_dais), + .controls = broxton_controls, + .num_controls = ARRAY_SIZE(broxton_controls), + .dapm_widgets = broxton_widgets, + .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), + .dapm_routes = geminilake_rt298_map, + .num_dapm_routes = ARRAY_SIZE(geminilake_rt298_map), + .fully_routed = true, + .late_probe = bxt_card_late_probe, +}; + static int broxton_audio_probe(struct platform_device *pdev) { struct bxt_rt286_private *ctx; + struct snd_soc_card *card = + (struct snd_soc_card *)pdev->id_entry->driver_data; + int i; + + for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) { + if (!strncmp(card->dai_link[i].codec_name, "i2c-INT343A:00", + I2C_NAME_SIZE)) { + if (!strncmp(card->name, "broxton-rt298", + PLATFORM_NAME_SIZE)) { + card->dai_link[i].name = "SSP5-Codec"; + card->dai_link[i].cpu_dai_name = "SSP5 Pin"; + } else if (!strncmp(card->name, "geminilake-rt298", + PLATFORM_NAME_SIZE)) { + card->dai_link[i].name = "SSP2-Codec"; + card->dai_link[i].cpu_dai_name = "SSP2 Pin"; + } + } + } ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC); if (!ctx) @@ -516,18 +584,27 @@ static int broxton_audio_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - broxton_rt298.dev = &pdev->dev; - snd_soc_card_set_drvdata(&broxton_rt298, ctx); + card->dev = &pdev->dev; + snd_soc_card_set_drvdata(card, ctx); - return devm_snd_soc_register_card(&pdev->dev, &broxton_rt298); + return devm_snd_soc_register_card(&pdev->dev, card); } +static const struct platform_device_id bxt_board_ids[] = { + { .name = "bxt_alc298s_i2s", .driver_data = + (unsigned long)&broxton_rt298 }, + { .name = "glk_alc298s_i2s", .driver_data = + (unsigned long)&geminilake_rt298 }, + {} +}; + static struct platform_driver broxton_audio = { .probe = broxton_audio_probe, .driver = { .name = "bxt_alc298s_i2s", .pm = &snd_soc_pm_ops, }, + .id_table = bxt_board_ids, }; module_platform_driver(broxton_audio) @@ -537,3 +614,4 @@ MODULE_AUTHOR("Senthilnathan Veppur "); MODULE_DESCRIPTION("Intel SST Audio for Broxton"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:bxt_alc298s_i2s"); +MODULE_ALIAS("platform:glk_alc298s_i2s"); diff --git a/sound/soc/intel/boards/byt-max98090.c b/sound/soc/intel/boards/byt-max98090.c index 047be7fa0ce9..0f8b8209c020 100644 --- a/sound/soc/intel/boards/byt-max98090.c +++ b/sound/soc/intel/boards/byt-max98090.c @@ -173,20 +173,8 @@ static int byt_max98090_probe(struct platform_device *pdev) return 0; } -static int byt_max98090_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct byt_max98090_private *priv = snd_soc_card_get_drvdata(card); - - snd_soc_jack_free_gpios(&priv->jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return 0; -} - static struct platform_driver byt_max98090_driver = { .probe = byt_max98090_probe, - .remove = byt_max98090_remove, .driver = { .name = "byt-max98090", .pm = &snd_soc_pm_ops, diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index f9ba97788157..7f7607420706 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -34,7 +34,7 @@ #define MAXIM_DEV0_NAME "i2c-MX98927:00" #define MAXIM_DEV1_NAME "i2c-MX98927:01" -static struct snd_soc_card kabylake_audio_card; +static struct snd_soc_card *kabylake_audio_card; static const struct snd_pcm_hw_constraint_list *dmic_constraints; static struct snd_soc_jack skylake_hdmi[3]; @@ -52,6 +52,8 @@ struct kbl_rt5663_private { enum { KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_CP, + KBL_DPCM_AUDIO_HS_PB, + KBL_DPCM_AUDIO_ECHO_REF_CP, KBL_DPCM_AUDIO_REF_CP, KBL_DPCM_AUDIO_DMIC_CP, KBL_DPCM_AUDIO_HDMI1_PB, @@ -72,8 +74,9 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL), SND_SOC_DAPM_MIC("SoC DMIC", NULL), - SND_SOC_DAPM_SPK("DP", NULL), - SND_SOC_DAPM_SPK("HDMI", NULL), + SND_SOC_DAPM_SPK("HDMI1", NULL), + SND_SOC_DAPM_SPK("HDMI2", NULL), + SND_SOC_DAPM_SPK("HDMI3", NULL), }; @@ -91,20 +94,22 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "IN1N", NULL, "Headset Mic" }, { "DMic", NULL, "SoC DMIC" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, - /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, + { "ssp0 Tx", NULL, "spk_out" }, { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, + { "ssp1 Tx", NULL, "hs_out" }, - { "codec0_in", NULL, "ssp1 Rx" }, + { "hs_in", NULL, "ssp1 Rx" }, { "ssp1 Rx", NULL, "AIF Capture" }, + /* IV feedback path */ + { "codec0_fb_in", NULL, "ssp0 Rx"}, + { "ssp0 Rx", NULL, "Left HiFi Capture" }, + { "ssp0 Rx", NULL, "Right HiFi Capture" }, + /* DMIC */ { "dmic01_hifi", NULL, "DMIC01 Rx" }, { "DMIC01 Rx", NULL, "DMIC AIF" }, @@ -117,6 +122,49 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "iDisp1 Tx", NULL, "iDisp1_out"}, }; +enum { + KBL_DPCM_AUDIO_5663_PB = 0, + KBL_DPCM_AUDIO_5663_CP, + KBL_DPCM_AUDIO_5663_HDMI1_PB, + KBL_DPCM_AUDIO_5663_HDMI2_PB, +}; + +static const struct snd_kcontrol_new kabylake_5663_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct snd_soc_dapm_widget kabylake_5663_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_SPK("DP", NULL), + SND_SOC_DAPM_SPK("HDMI", NULL), +}; + +static const struct snd_soc_dapm_route kabylake_5663_map[] = { + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, + + /* other jacks */ + { "IN1P", NULL, "Headset Mic" }, + { "IN1N", NULL, "Headset Mic" }, + + { "HDMI", NULL, "hif5 Output" }, + { "DP", NULL, "hif6 Output" }, + + /* CODEC BE connections */ + { "AIF Playback", NULL, "ssp1 Tx" }, + { "ssp1 Tx", NULL, "codec1_out" }, + + { "codec0_in", NULL, "ssp1 Rx" }, + { "ssp1 Rx", NULL, "AIF Capture" }, + + { "hifi2", NULL, "iDisp2 Tx"}, + { "iDisp2 Tx", NULL, "iDisp2_out"}, + { "hifi1", NULL, "iDisp1 Tx"}, + { "iDisp1 Tx", NULL, "iDisp1_out"}, +}; + static struct snd_soc_codec_conf max98927_codec_conf[] = { { .dev_name = MAXIM_DEV0_NAME, @@ -165,7 +213,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(&kabylake_audio_card, "Headset Jack", + ret = snd_soc_card_jack_new(kabylake_audio_card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->kabylake_headset, NULL, 0); @@ -173,8 +221,18 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret); return ret; } - rt5663_set_jack_detect(codec, &ctx->kabylake_headset); + return ret; +} + +static int kabylake_rt5663_max98927_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = kabylake_rt5663_codec_init(rtd); + if (ret) + return ret; + ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); if (ret) { dev_err(rtd->dev, "SoC DMIC ignore suspend failed %d\n", ret); @@ -184,7 +242,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) +static int kabylake_hdmi_init(struct snd_soc_pcm_runtime *rtd, int device) { struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_dai *dai = rtd->codec_dai; @@ -194,7 +252,7 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) if (!pcm) return -ENOMEM; - pcm->device = KBL_DPCM_AUDIO_HDMI1_PB; + pcm->device = device; pcm->codec_dai = dai; list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); @@ -202,47 +260,36 @@ static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int kabylake_hdmi1_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI1_PB); +} + static int kabylake_hdmi2_init(struct snd_soc_pcm_runtime *rtd) { - struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = rtd->codec_dai; - struct kbl_hdmi_pcm *pcm; - - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - - pcm->device = KBL_DPCM_AUDIO_HDMI2_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI2_PB); } static int kabylake_hdmi3_init(struct snd_soc_pcm_runtime *rtd) { - struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = rtd->codec_dai; - struct kbl_hdmi_pcm *pcm; + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_HDMI3_PB); +} - pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; +static int kabylake_5663_hdmi1_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI1_PB); +} - pcm->device = KBL_DPCM_AUDIO_HDMI3_PB; - pcm->codec_dai = dai; - - list_add_tail(&pcm->head, &ctx->hdmi_pcm_list); - - return 0; +static int kabylake_5663_hdmi2_init(struct snd_soc_pcm_runtime *rtd) +{ + return kabylake_hdmi_init(rtd, KBL_DPCM_AUDIO_5663_HDMI2_PB); } static unsigned int rates[] = { 48000, }; -static struct snd_pcm_hw_constraint_list constraints_rates = { +static const struct snd_pcm_hw_constraint_list constraints_rates = { .count = ARRAY_SIZE(rates), .list = rates, .mask = 0, @@ -252,7 +299,7 @@ static unsigned int channels[] = { 2, }; -static struct snd_pcm_hw_constraint_list constraints_channels = { +static const struct snd_pcm_hw_constraint_list constraints_channels = { .count = ARRAY_SIZE(channels), .list = channels, .mask = 0, @@ -312,11 +359,13 @@ static int kabylake_rt5663_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai = rtd->codec_dai; int ret; + /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ + rt5663_sel_asrc_clk_src(codec_dai->codec, + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER, + RT5663_CLK_SEL_I2S1_ASRC); + ret = snd_soc_dai_set_sysclk(codec_dai, RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN); - /* use ASRC for internal clocks, as PLL rate isn't multiple of BCLK */ - rt5663_sel_asrc_clk_src(codec_dai->codec, RT5663_DA_STEREO_FILTER, 1); - if (ret < 0) dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); @@ -381,7 +430,7 @@ static unsigned int rates_16000[] = { 16000, }; -static struct snd_pcm_hw_constraint_list constraints_16000 = { +static const struct snd_pcm_hw_constraint_list constraints_16000 = { .count = ARRAY_SIZE(rates_16000), .list = rates_16000, }; @@ -443,6 +492,28 @@ static struct snd_soc_dai_link kabylake_dais[] = { .dpcm_capture = 1, .ops = &kabylake_rt5663_fe_ops, }, + [KBL_DPCM_AUDIO_HS_PB] = { + .name = "Kbl Audio Headset Playback", + .stream_name = "Headset Audio", + .cpu_dai_name = "System Pin2", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_ECHO_REF_CP] = { + .name = "Kbl Audio Echo Reference cap", + .stream_name = "Echoreference Capture", + .cpu_dai_name = "Echoref Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .init = NULL, + .capture_only = 1, + .nonatomic = 1, + }, [KBL_DPCM_AUDIO_REF_CP] = { .name = "Kbl Audio Reference cap", .stream_name = "Wake on Voice", @@ -538,7 +609,7 @@ static struct snd_soc_dai_link kabylake_dais[] = { .no_pcm = 1, .codec_name = "i2c-10EC5663:00", .codec_dai_name = KBL_REALTEK_CODEC_DAI, - .init = kabylake_rt5663_codec_init, + .init = kabylake_rt5663_max98927_codec_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .ignore_pmdown_time = 1, @@ -594,15 +665,119 @@ static struct snd_soc_dai_link kabylake_dais[] = { }, }; +static struct snd_soc_dai_link kabylake_5663_dais[] = { + /* Front End DAI links */ + [KBL_DPCM_AUDIO_5663_PB] = { + .name = "Kbl Audio Port", + .stream_name = "Audio", + .cpu_dai_name = "System Pin", + .platform_name = "0000:00:1f.3", + .dynamic = 1, + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .nonatomic = 1, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_playback = 1, + .ops = &kabylake_rt5663_fe_ops, + }, + [KBL_DPCM_AUDIO_5663_CP] = { + .name = "Kbl Audio Capture Port", + .stream_name = "Audio Record", + .cpu_dai_name = "System Pin", + .platform_name = "0000:00:1f.3", + .dynamic = 1, + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .nonatomic = 1, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_capture = 1, + .ops = &kabylake_rt5663_fe_ops, + }, + [KBL_DPCM_AUDIO_5663_HDMI1_PB] = { + .name = "Kbl HDMI Port1", + .stream_name = "Hdmi1", + .cpu_dai_name = "HDMI1 Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = NULL, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_5663_HDMI2_PB] = { + .name = "Kbl HDMI Port2", + .stream_name = "Hdmi2", + .cpu_dai_name = "HDMI2 Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = NULL, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .nonatomic = 1, + .dynamic = 1, + }, + + /* Back End DAI links */ + { + /* SSP1 - Codec */ + .name = "SSP1-Codec", + .id = 0, + .cpu_dai_name = "SSP1 Pin", + .platform_name = "0000:00:1f.3", + .no_pcm = 1, + .codec_name = "i2c-10EC5663:00", + .codec_dai_name = KBL_REALTEK_CODEC_DAI, + .init = kabylake_rt5663_codec_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .ignore_pmdown_time = 1, + .be_hw_params_fixup = kabylake_ssp_fixup, + .ops = &kabylake_rt5663_ops, + .dpcm_playback = 1, + .dpcm_capture = 1, + }, + { + .name = "iDisp1", + .id = 1, + .cpu_dai_name = "iDisp1 Pin", + .codec_name = "ehdaudio0D2", + .codec_dai_name = "intel-hdmi-hifi1", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .init = kabylake_5663_hdmi1_init, + .no_pcm = 1, + }, + { + .name = "iDisp2", + .id = 2, + .cpu_dai_name = "iDisp2 Pin", + .codec_name = "ehdaudio0D2", + .codec_dai_name = "intel-hdmi-hifi2", + .platform_name = "0000:00:1f.3", + .init = kabylake_5663_hdmi2_init, + .dpcm_playback = 1, + .no_pcm = 1, + }, +}; + #define NAME_SIZE 32 static int kabylake_card_late_probe(struct snd_soc_card *card) { struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card); struct kbl_hdmi_pcm *pcm; + struct snd_soc_codec *codec = NULL; int err, i = 0; char jack_name[NAME_SIZE]; list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { + codec = pcm->codec_dai->codec; snprintf(jack_name, sizeof(jack_name), "HDMI/DP, pcm=%d Jack", pcm->device); err = snd_soc_card_jack_new(card, jack_name, @@ -620,11 +795,14 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) i++; } - return 0; + if (!codec) + return -EINVAL; + + return hdac_hdmi_jack_port_init(codec, &card->dapm); } /* kabylake audio machine driver for SPT + RT5663 */ -static struct snd_soc_card kabylake_audio_card = { +static struct snd_soc_card kabylake_audio_card_rt5663_m98927 = { .name = "kblrt5663max", .owner = THIS_MODULE, .dai_link = kabylake_dais, @@ -641,6 +819,22 @@ static struct snd_soc_card kabylake_audio_card = { .late_probe = kabylake_card_late_probe, }; +/* kabylake audio machine driver for RT5663 */ +static struct snd_soc_card kabylake_audio_card_rt5663 = { + .name = "kblrt5663", + .owner = THIS_MODULE, + .dai_link = kabylake_5663_dais, + .num_links = ARRAY_SIZE(kabylake_5663_dais), + .controls = kabylake_5663_controls, + .num_controls = ARRAY_SIZE(kabylake_5663_controls), + .dapm_widgets = kabylake_5663_widgets, + .num_dapm_widgets = ARRAY_SIZE(kabylake_5663_widgets), + .dapm_routes = kabylake_5663_map, + .num_dapm_routes = ARRAY_SIZE(kabylake_5663_map), + .fully_routed = true, + .late_probe = kabylake_card_late_probe, +}; + static int kabylake_audio_probe(struct platform_device *pdev) { struct kbl_rt5663_private *ctx; @@ -652,19 +846,30 @@ static int kabylake_audio_probe(struct platform_device *pdev) INIT_LIST_HEAD(&ctx->hdmi_pcm_list); - kabylake_audio_card.dev = &pdev->dev; - snd_soc_card_set_drvdata(&kabylake_audio_card, ctx); + kabylake_audio_card = + (struct snd_soc_card *)pdev->id_entry->driver_data; + + kabylake_audio_card->dev = &pdev->dev; + snd_soc_card_set_drvdata(kabylake_audio_card, ctx); pdata = dev_get_drvdata(&pdev->dev); if (pdata) dmic_constraints = pdata->dmic_num == 2 ? &constraints_dmic_2ch : &constraints_dmic_channels; - return devm_snd_soc_register_card(&pdev->dev, &kabylake_audio_card); + return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card); } static const struct platform_device_id kbl_board_ids[] = { - { .name = "kbl_rt5663_m98927" }, + { + .name = "kbl_rt5663", + .driver_data = (kernel_ulong_t)&kabylake_audio_card_rt5663, + }, + { + .name = "kbl_rt5663_m98927", + .driver_data = + (kernel_ulong_t)&kabylake_audio_card_rt5663_m98927, + }, { } }; @@ -684,4 +889,5 @@ MODULE_DESCRIPTION("Audio Machine driver-RT5663 & MAX98927 in I2S mode"); MODULE_AUTHOR("Naveen M "); MODULE_AUTHOR("Harsha Priya "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:kbl_rt5663"); MODULE_ALIAS("platform:kbl_rt5663_m98927"); diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index cfd89ca6a18d..88ff54220007 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -18,6 +18,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -62,7 +63,10 @@ struct kbl_codec_private { enum { KBL_DPCM_AUDIO_PB = 0, KBL_DPCM_AUDIO_CP, + KBL_DPCM_AUDIO_HS_PB, + KBL_DPCM_AUDIO_ECHO_REF_CP, KBL_DPCM_AUDIO_DMIC_CP, + KBL_DPCM_AUDIO_RT5514_DSP, KBL_DPCM_AUDIO_HDMI1_PB, KBL_DPCM_AUDIO_HDMI2_PB, }; @@ -81,8 +85,8 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = { SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL), SND_SOC_DAPM_MIC("DMIC", NULL), - SND_SOC_DAPM_SPK("DP", NULL), - SND_SOC_DAPM_SPK("HDMI", NULL), + SND_SOC_DAPM_SPK("HDMI1", NULL), + SND_SOC_DAPM_SPK("HDMI2", NULL), }; @@ -99,23 +103,25 @@ static const struct snd_soc_dapm_route kabylake_map[] = { { "IN1P", NULL, "Headset Mic" }, { "IN1N", NULL, "Headset Mic" }, - { "HDMI", NULL, "hif5 Output" }, - { "DP", NULL, "hif6 Output" }, - /* CODEC BE connections */ { "Left HiFi Playback", NULL, "ssp0 Tx" }, { "Right HiFi Playback", NULL, "ssp0 Tx" }, - { "ssp0 Tx", NULL, "codec0_out" }, + { "ssp0 Tx", NULL, "spk_out" }, { "AIF Playback", NULL, "ssp1 Tx" }, - { "ssp1 Tx", NULL, "codec1_out" }, + { "ssp1 Tx", NULL, "hs_out" }, - { "codec0_in", NULL, "ssp1 Rx" }, + { "hs_in", NULL, "ssp1 Rx" }, { "ssp1 Rx", NULL, "AIF Capture" }, { "codec1_in", NULL, "ssp0 Rx" }, { "ssp0 Rx", NULL, "AIF1 Capture" }, + /* IV feedback path */ + { "codec0_fb_in", NULL, "ssp0 Rx"}, + { "ssp0 Rx", NULL, "Left HiFi Capture" }, + { "ssp0 Rx", NULL, "Right HiFi Capture" }, + /* DMIC */ { "DMIC1L", NULL, "DMIC" }, { "DMIC1R", NULL, "DMIC" }, @@ -173,6 +179,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) int ret; struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(rtd->card); struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_jack *jack; /* * Headset buttons map to the google Reference headset. @@ -187,6 +194,12 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } + jack = &ctx->kabylake_headset; + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + rt5663_set_jack_detect(codec, &ctx->kabylake_headset); ret = snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "DMIC"); @@ -358,11 +371,18 @@ static int kabylake_ssp0_hw_params(struct snd_pcm_substream *substream, return ret; } } - if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME) || - !strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { - ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF0, 3, 8, 16); + if (!strcmp(codec_dai->component->name, MAXIM_DEV0_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x30, 3, 8, 16); if (ret < 0) { - dev_err(rtd->dev, "set TDM slot err:%d\n", ret); + dev_err(rtd->dev, "DEV0 TDM slot err:%d\n", ret); + return ret; + } + } + + if (!strcmp(codec_dai->component->name, MAXIM_DEV1_NAME)) { + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xC0, 3, 8, 16); + if (ret < 0) { + dev_err(rtd->dev, "DEV1 TDM slot err:%d\n", ret); return ret; } } @@ -442,6 +462,36 @@ static struct snd_soc_dai_link kabylake_dais[] = { .dpcm_capture = 1, .ops = &kabylake_rt5663_fe_ops, }, + [KBL_DPCM_AUDIO_HS_PB] = { + .name = "Kbl Audio Headset Playback", + .stream_name = "Headset Audio", + .cpu_dai_name = "System Pin2", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .dpcm_playback = 1, + .nonatomic = 1, + .dynamic = 1, + }, + [KBL_DPCM_AUDIO_ECHO_REF_CP] = { + .name = "Kbl Audio Echo Reference cap", + .stream_name = "Echoreference Capture", + .cpu_dai_name = "Echoref Pin", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .platform_name = "0000:00:1f.3", + .init = NULL, + .capture_only = 1, + .nonatomic = 1, + }, + [KBL_DPCM_AUDIO_RT5514_DSP] = { + .name = "rt5514 dsp", + .stream_name = "Wake on Voice", + .cpu_dai_name = "spi-PRP0001:00", + .platform_name = "spi-PRP0001:00", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + }, [KBL_DPCM_AUDIO_DMIC_CP] = { .name = "Kbl Audio DMIC cap", .stream_name = "dmiccap", @@ -548,10 +598,12 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) { struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card); struct kbl_hdmi_pcm *pcm; + struct snd_soc_codec *codec = NULL; int err, i = 0; char jack_name[NAME_SIZE]; list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { + codec = pcm->codec_dai->codec; err = snd_soc_card_jack_new(card, jack_name, SND_JACK_AVOUT, &ctx->kabylake_hdmi[i], NULL, 0); @@ -565,7 +617,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card) i++; } - return 0; + if (!codec) + return -EINVAL; + + return hdac_hdmi_jack_port_init(codec, &card->dapm); } /* diff --git a/sound/soc/intel/boards/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c index 4e08885f37aa..6f44acfb4aae 100644 --- a/sound/soc/intel/boards/mfld_machine.c +++ b/sound/soc/intel/boards/mfld_machine.c @@ -376,10 +376,8 @@ static int snd_mfld_mc_probe(struct platform_device *pdev) /* audio interrupt base of SRAM location where * interrupts are stored by System FW */ mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC); - if (!mc_drv_ctx) { - pr_err("allocation failed\n"); + if (!mc_drv_ctx) return -ENOMEM; - } irq_mem = platform_get_resource_byname( pdev, IORESOURCE_MEM, "IRQ_BASE"); diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile index 1a35149bcad7..0e029f354f6b 100644 --- a/sound/soc/intel/common/Makefile +++ b/sound/soc/intel/common/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-sst-dsp-objs := sst-dsp.o snd-soc-sst-acpi-objs := sst-acpi.o snd-soc-sst-match-objs := sst-match-acpi.o diff --git a/sound/soc/intel/haswell/sst-haswell-pcm.c b/sound/soc/intel/haswell/sst-haswell-pcm.c index 9e4094e2c6e3..c044400540ec 100644 --- a/sound/soc/intel/haswell/sst-haswell-pcm.c +++ b/sound/soc/intel/haswell/sst-haswell-pcm.c @@ -1135,7 +1135,7 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver hsw_soc_platform = { +static const struct snd_soc_platform_driver hsw_soc_platform = { .probe = hsw_pcm_probe, .remove = hsw_pcm_remove, .ops = &hsw_pcm_ops, diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile index e7d77722d560..d1ccbecd141f 100644 --- a/sound/soc/intel/skylake/Makefile +++ b/sound/soc/intel/skylake/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o \ skl-topology.o @@ -8,7 +9,8 @@ endif obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o # Skylake IPC Support -snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o skl-sst-cldma.o \ - skl-sst.o bxt-sst.o skl-sst-utils.o +snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o \ + skl-sst-cldma.o skl-sst.o bxt-sst.o cnl-sst.o \ + skl-sst-utils.o obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index cf11b84888b9..4524211960e4 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c @@ -530,7 +530,7 @@ static int bxt_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) return 0; } -static struct skl_dsp_fw_ops bxt_fw_ops = { +static const struct skl_dsp_fw_ops bxt_fw_ops = { .set_state_D0 = bxt_set_dsp_D0, .set_state_D3 = bxt_set_dsp_D3, .set_state_D0i3 = bxt_schedule_dsp_D0i3, @@ -581,10 +581,15 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, sst_dsp_mailbox_init(sst, (BXT_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, BXT_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); + ret = skl_ipc_init(dev, skl); + if (ret) { + skl_dsp_free(sst); + return ret; + } + /* set the D0i3 check */ skl->ipc.ops.check_dsp_lp_on = skl_ipc_check_D0i0; - skl->cores.count = 2; skl->boot_complete = false; init_waitqueue_head(&skl->boot_wait); INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); @@ -629,11 +634,6 @@ void bxt_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) release_firmware(ctx->dsp->fw); skl_freeup_uuid_list(ctx); skl_ipc_free(&ctx->ipc); - ctx->dsp->cl_dev.ops.cl_cleanup_controller(ctx->dsp); - - if (ctx->dsp->addr.lpe) - iounmap(ctx->dsp->addr.lpe); - ctx->dsp->ops->free(ctx->dsp); } EXPORT_SYMBOL_GPL(bxt_sst_dsp_cleanup); diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.c b/sound/soc/intel/skylake/cnl-sst-dsp.c new file mode 100644 index 000000000000..2f8326707c21 --- /dev/null +++ b/sound/soc/intel/skylake/cnl-sst-dsp.c @@ -0,0 +1,274 @@ +/* + * cnl-sst-dsp.c - CNL SST library generic function + * + * Copyright (C) 2016-17, Intel Corporation. + * Author: Guneshwor Singh + * + * Modified from: + * SKL SST library generic function + * Copyright (C) 2014-15, Intel Corporation. + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include +#include "../common/sst-dsp.h" +#include "../common/sst-ipc.h" +#include "../common/sst-dsp-priv.h" +#include "cnl-sst-dsp.h" + +/* various timeout values */ +#define CNL_DSP_PU_TO 50 +#define CNL_DSP_PD_TO 50 +#define CNL_DSP_RESET_TO 50 + +static int +cnl_dsp_core_set_reset_state(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, + CNL_ADSP_REG_ADSPCS, CNL_ADSPCS_CRST(core_mask), + CNL_ADSPCS_CRST(core_mask)); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, + CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CRST(core_mask), + CNL_ADSPCS_CRST(core_mask), + CNL_DSP_RESET_TO, + "Set reset"); +} + +static int +cnl_dsp_core_unset_reset_state(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CRST(core_mask), 0); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, + CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CRST(core_mask), + 0, + CNL_DSP_RESET_TO, + "Unset reset"); +} + +static bool is_cnl_dsp_core_enable(struct sst_dsp *ctx, unsigned int core_mask) +{ + int val; + bool is_enable; + + val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPCS); + + is_enable = (val & CNL_ADSPCS_CPA(core_mask)) && + (val & CNL_ADSPCS_SPA(core_mask)) && + !(val & CNL_ADSPCS_CRST(core_mask)) && + !(val & CNL_ADSPCS_CSTALL(core_mask)); + + dev_dbg(ctx->dev, "DSP core(s) enabled? %d: core_mask %#x\n", + is_enable, core_mask); + + return is_enable; +} + +static int cnl_dsp_reset_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* stall core */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CSTALL(core_mask), + CNL_ADSPCS_CSTALL(core_mask)); + + /* set reset state */ + return cnl_dsp_core_set_reset_state(ctx, core_mask); +} + +static int cnl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + int ret; + + /* unset reset state */ + ret = cnl_dsp_core_unset_reset_state(ctx, core_mask); + if (ret < 0) + return ret; + + /* run core */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CSTALL(core_mask), 0); + + if (!is_cnl_dsp_core_enable(ctx, core_mask)) { + cnl_dsp_reset_core(ctx, core_mask); + dev_err(ctx->dev, "DSP core mask %#x enable failed\n", + core_mask); + ret = -EIO; + } + + return ret; +} + +static int cnl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_SPA(core_mask), + CNL_ADSPCS_SPA(core_mask)); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CPA(core_mask), + CNL_ADSPCS_CPA(core_mask), + CNL_DSP_PU_TO, + "Power up"); +} + +static int cnl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask) +{ + /* update bits */ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_SPA(core_mask), 0); + + /* poll with timeout to check if operation successful */ + return sst_dsp_register_poll(ctx, + CNL_ADSP_REG_ADSPCS, + CNL_ADSPCS_CPA(core_mask), + 0, + CNL_DSP_PD_TO, + "Power down"); +} + +int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + int ret; + + /* power up */ + ret = cnl_dsp_core_power_up(ctx, core_mask); + if (ret < 0) { + dev_dbg(ctx->dev, "DSP core mask %#x power up failed", + core_mask); + return ret; + } + + return cnl_dsp_start_core(ctx, core_mask); +} + +int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask) +{ + int ret; + + ret = cnl_dsp_reset_core(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "DSP core mask %#x reset failed\n", + core_mask); + return ret; + } + + /* power down core*/ + ret = cnl_dsp_core_power_down(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "DSP core mask %#x power down failed\n", + core_mask); + return ret; + } + + if (is_cnl_dsp_core_enable(ctx, core_mask)) { + dev_err(ctx->dev, "DSP core mask %#x disable failed\n", + core_mask); + ret = -EIO; + } + + return ret; +} + +irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id) +{ + struct sst_dsp *ctx = dev_id; + u32 val; + irqreturn_t ret = IRQ_NONE; + + spin_lock(&ctx->spinlock); + + val = sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS); + ctx->intr_status = val; + + if (val == 0xffffffff) { + spin_unlock(&ctx->spinlock); + return IRQ_NONE; + } + + if (val & CNL_ADSPIS_IPC) { + cnl_ipc_int_disable(ctx); + ret = IRQ_WAKE_THREAD; + } + + spin_unlock(&ctx->spinlock); + + return ret; +} + +void cnl_dsp_free(struct sst_dsp *dsp) +{ + cnl_ipc_int_disable(dsp); + + free_irq(dsp->irq, dsp); + cnl_ipc_op_int_disable(dsp); + cnl_dsp_disable_core(dsp, SKL_DSP_CORE0_MASK); +} +EXPORT_SYMBOL_GPL(cnl_dsp_free); + +void cnl_ipc_int_enable(struct sst_dsp *ctx) +{ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_ADSPIC, + CNL_ADSPIC_IPC, CNL_ADSPIC_IPC); +} + +void cnl_ipc_int_disable(struct sst_dsp *ctx) +{ + sst_dsp_shim_update_bits_unlocked(ctx, CNL_ADSP_REG_ADSPIC, + CNL_ADSPIC_IPC, 0); +} + +void cnl_ipc_op_int_enable(struct sst_dsp *ctx) +{ + /* enable IPC DONE interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, + CNL_ADSP_REG_HIPCCTL_DONE); + + /* enable IPC BUSY interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_BUSY, + CNL_ADSP_REG_HIPCCTL_BUSY); +} + +void cnl_ipc_op_int_disable(struct sst_dsp *ctx) +{ + /* disable IPC DONE interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, 0); + + /* disable IPC BUSY interrupt */ + sst_dsp_shim_update_bits(ctx, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_BUSY, 0); +} + +bool cnl_ipc_int_status(struct sst_dsp *ctx) +{ + return sst_dsp_shim_read_unlocked(ctx, CNL_ADSP_REG_ADSPIS) & + CNL_ADSPIS_IPC; +} + +void cnl_ipc_free(struct sst_generic_ipc *ipc) +{ + cnl_ipc_op_int_disable(ipc->dsp); + sst_ipc_fini(ipc); +} diff --git a/sound/soc/intel/skylake/cnl-sst-dsp.h b/sound/soc/intel/skylake/cnl-sst-dsp.h new file mode 100644 index 000000000000..09bd218df5c4 --- /dev/null +++ b/sound/soc/intel/skylake/cnl-sst-dsp.h @@ -0,0 +1,112 @@ +/* + * Cannonlake SST DSP Support + * + * Copyright (C) 2016-17, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __CNL_SST_DSP_H__ +#define __CNL_SST_DSP_H__ + +struct sst_dsp; +struct skl_sst; +struct sst_dsp_device; +struct sst_generic_ipc; + +/* Intel HD Audio General DSP Registers */ +#define CNL_ADSP_GEN_BASE 0x0 +#define CNL_ADSP_REG_ADSPCS (CNL_ADSP_GEN_BASE + 0x04) +#define CNL_ADSP_REG_ADSPIC (CNL_ADSP_GEN_BASE + 0x08) +#define CNL_ADSP_REG_ADSPIS (CNL_ADSP_GEN_BASE + 0x0c) + +/* Intel HD Audio Inter-Processor Communication Registers */ +#define CNL_ADSP_IPC_BASE 0xc0 +#define CNL_ADSP_REG_HIPCTDR (CNL_ADSP_IPC_BASE + 0x00) +#define CNL_ADSP_REG_HIPCTDA (CNL_ADSP_IPC_BASE + 0x04) +#define CNL_ADSP_REG_HIPCTDD (CNL_ADSP_IPC_BASE + 0x08) +#define CNL_ADSP_REG_HIPCIDR (CNL_ADSP_IPC_BASE + 0x10) +#define CNL_ADSP_REG_HIPCIDA (CNL_ADSP_IPC_BASE + 0x14) +#define CNL_ADSP_REG_HIPCIDD (CNL_ADSP_IPC_BASE + 0x18) +#define CNL_ADSP_REG_HIPCCTL (CNL_ADSP_IPC_BASE + 0x28) + +/* HIPCTDR */ +#define CNL_ADSP_REG_HIPCTDR_BUSY BIT(31) + +/* HIPCTDA */ +#define CNL_ADSP_REG_HIPCTDA_DONE BIT(31) + +/* HIPCIDR */ +#define CNL_ADSP_REG_HIPCIDR_BUSY BIT(31) + +/* HIPCIDA */ +#define CNL_ADSP_REG_HIPCIDA_DONE BIT(31) + +/* CNL HIPCCTL */ +#define CNL_ADSP_REG_HIPCCTL_DONE BIT(1) +#define CNL_ADSP_REG_HIPCCTL_BUSY BIT(0) + +/* CNL HIPCT */ +#define CNL_ADSP_REG_HIPCT_BUSY BIT(31) + +/* Intel HD Audio SRAM Window 1 */ +#define CNL_ADSP_SRAM1_BASE 0xa0000 + +#define CNL_ADSP_MMIO_LEN 0x10000 + +#define CNL_ADSP_W0_STAT_SZ 0x1000 + +#define CNL_ADSP_W0_UP_SZ 0x1000 + +#define CNL_ADSP_W1_SZ 0x1000 + +#define CNL_FW_STS_MASK 0xf + +#define CNL_ADSPIC_IPC 0x1 +#define CNL_ADSPIS_IPC 0x1 + +#define CNL_DSP_CORES 4 +#define CNL_DSP_CORES_MASK ((1 << CNL_DSP_CORES) - 1) + +/* core reset - asserted high */ +#define CNL_ADSPCS_CRST_SHIFT 0 +#define CNL_ADSPCS_CRST(x) (x << CNL_ADSPCS_CRST_SHIFT) + +/* core run/stall - when set to 1 core is stalled */ +#define CNL_ADSPCS_CSTALL_SHIFT 8 +#define CNL_ADSPCS_CSTALL(x) (x << CNL_ADSPCS_CSTALL_SHIFT) + +/* set power active - when set to 1 turn core on */ +#define CNL_ADSPCS_SPA_SHIFT 16 +#define CNL_ADSPCS_SPA(x) (x << CNL_ADSPCS_SPA_SHIFT) + +/* current power active - power status of cores, set by hardware */ +#define CNL_ADSPCS_CPA_SHIFT 24 +#define CNL_ADSPCS_CPA(x) (x << CNL_ADSPCS_CPA_SHIFT) + +int cnl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core); +int cnl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core); +irqreturn_t cnl_dsp_sst_interrupt(int irq, void *dev_id); +void cnl_dsp_free(struct sst_dsp *dsp); + +void cnl_ipc_int_enable(struct sst_dsp *ctx); +void cnl_ipc_int_disable(struct sst_dsp *ctx); +void cnl_ipc_op_int_enable(struct sst_dsp *ctx); +void cnl_ipc_op_int_disable(struct sst_dsp *ctx); +bool cnl_ipc_int_status(struct sst_dsp *ctx); +void cnl_ipc_free(struct sst_generic_ipc *ipc); + +int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp); +int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx); +void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx); + +#endif /*__CNL_SST_DSP_H__*/ diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c new file mode 100644 index 000000000000..387de388ce29 --- /dev/null +++ b/sound/soc/intel/skylake/cnl-sst.c @@ -0,0 +1,497 @@ +/* + * cnl-sst.c - DSP library functions for CNL platform + * + * Copyright (C) 2016-17, Intel Corporation. + * + * Author: Guneshwor Singh + * + * Modified from: + * HDA DSP library functions for SKL platform + * Copyright (C) 2014-15, Intel Corporation. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include + +#include "../common/sst-dsp.h" +#include "../common/sst-dsp-priv.h" +#include "../common/sst-ipc.h" +#include "cnl-sst-dsp.h" +#include "skl-sst-dsp.h" +#include "skl-sst-ipc.h" + +#define CNL_FW_ROM_INIT 0x1 +#define CNL_FW_INIT 0x5 +#define CNL_IPC_PURGE 0x01004000 +#define CNL_INIT_TIMEOUT 300 +#define CNL_BASEFW_TIMEOUT 3000 + +#define CNL_ADSP_SRAM0_BASE 0x80000 + +/* Firmware status window */ +#define CNL_ADSP_FW_STATUS CNL_ADSP_SRAM0_BASE +#define CNL_ADSP_ERROR_CODE (CNL_ADSP_FW_STATUS + 0x4) + +#define CNL_INSTANCE_ID 0 +#define CNL_BASE_FW_MODULE_ID 0 +#define CNL_ADSP_FW_HDR_OFFSET 0x2000 +#define CNL_ROM_CTRL_DMA_ID 0x9 + +static int cnl_prepare_fw(struct sst_dsp *ctx, const void *fwdata, u32 fwsize) +{ + + int ret, stream_tag; + + stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab); + if (stream_tag <= 0) { + dev_err(ctx->dev, "dma prepare failed: 0%#x\n", stream_tag); + return stream_tag; + } + + ctx->dsp_ops.stream_tag = stream_tag; + memcpy(ctx->dmab.area, fwdata, fwsize); + + /* purge FW request */ + sst_dsp_shim_write(ctx, CNL_ADSP_REG_HIPCIDR, + CNL_ADSP_REG_HIPCIDR_BUSY | (CNL_IPC_PURGE | + ((stream_tag - 1) << CNL_ROM_CTRL_DMA_ID))); + + ret = cnl_dsp_enable_core(ctx, SKL_DSP_CORE0_MASK); + if (ret < 0) { + dev_err(ctx->dev, "dsp boot core failed ret: %d\n", ret); + ret = -EIO; + goto base_fw_load_failed; + } + + /* enable interrupt */ + cnl_ipc_int_enable(ctx); + cnl_ipc_op_int_enable(ctx); + + ret = sst_dsp_register_poll(ctx, CNL_ADSP_FW_STATUS, CNL_FW_STS_MASK, + CNL_FW_ROM_INIT, CNL_INIT_TIMEOUT, + "rom load"); + if (ret < 0) { + dev_err(ctx->dev, "rom init timeout, ret: %d\n", ret); + goto base_fw_load_failed; + } + + return 0; + +base_fw_load_failed: + ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); + cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); + + return ret; +} + +static int sst_transfer_fw_host_dma(struct sst_dsp *ctx) +{ + int ret; + + ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag); + ret = sst_dsp_register_poll(ctx, CNL_ADSP_FW_STATUS, CNL_FW_STS_MASK, + CNL_FW_INIT, CNL_BASEFW_TIMEOUT, + "firmware boot"); + + ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag); + ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag); + + return ret; +} + +static int cnl_load_base_firmware(struct sst_dsp *ctx) +{ + struct firmware stripped_fw; + struct skl_sst *cnl = ctx->thread_context; + int ret; + + if (!ctx->fw) { + ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); + if (ret < 0) { + dev_err(ctx->dev, "request firmware failed: %d\n", ret); + goto cnl_load_base_firmware_failed; + } + } + + /* parse uuids if first boot */ + if (cnl->is_first_boot) { + ret = snd_skl_parse_uuids(ctx, ctx->fw, + CNL_ADSP_FW_HDR_OFFSET, 0); + if (ret < 0) + goto cnl_load_base_firmware_failed; + } + + stripped_fw.data = ctx->fw->data; + stripped_fw.size = ctx->fw->size; + skl_dsp_strip_extended_manifest(&stripped_fw); + + ret = cnl_prepare_fw(ctx, stripped_fw.data, stripped_fw.size); + if (ret < 0) { + dev_err(ctx->dev, "prepare firmware failed: %d\n", ret); + goto cnl_load_base_firmware_failed; + } + + ret = sst_transfer_fw_host_dma(ctx); + if (ret < 0) { + dev_err(ctx->dev, "transfer firmware failed: %d\n", ret); + cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); + goto cnl_load_base_firmware_failed; + } + + ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete, + msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); + if (ret == 0) { + dev_err(ctx->dev, "FW ready timed-out\n"); + cnl_dsp_disable_core(ctx, SKL_DSP_CORE0_MASK); + ret = -EIO; + goto cnl_load_base_firmware_failed; + } + + cnl->fw_loaded = true; + + return 0; + +cnl_load_base_firmware_failed: + release_firmware(ctx->fw); + ctx->fw = NULL; + + return ret; +} + +static int cnl_set_dsp_D0(struct sst_dsp *ctx, unsigned int core_id) +{ + struct skl_sst *cnl = ctx->thread_context; + unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); + struct skl_ipc_dxstate_info dx; + int ret; + + if (!cnl->fw_loaded) { + cnl->boot_complete = false; + ret = cnl_load_base_firmware(ctx); + if (ret < 0) { + dev_err(ctx->dev, "fw reload failed: %d\n", ret); + return ret; + } + + cnl->cores.state[core_id] = SKL_DSP_RUNNING; + return ret; + } + + ret = cnl_dsp_enable_core(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "enable dsp core %d failed: %d\n", + core_id, ret); + goto err; + } + + if (core_id == SKL_DSP_CORE0_ID) { + /* enable interrupt */ + cnl_ipc_int_enable(ctx); + cnl_ipc_op_int_enable(ctx); + cnl->boot_complete = false; + + ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete, + msecs_to_jiffies(SKL_IPC_BOOT_MSECS)); + if (ret == 0) { + dev_err(ctx->dev, + "dsp boot timeout, status=%#x error=%#x\n", + sst_dsp_shim_read(ctx, CNL_ADSP_FW_STATUS), + sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE)); + goto err; + } + } else { + dx.core_mask = core_mask; + dx.dx_mask = core_mask; + + ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID, + CNL_BASE_FW_MODULE_ID, &dx); + if (ret < 0) { + dev_err(ctx->dev, "set_dx failed, core: %d ret: %d\n", + core_id, ret); + goto err; + } + } + cnl->cores.state[core_id] = SKL_DSP_RUNNING; + + return 0; +err: + cnl_dsp_disable_core(ctx, core_mask); + + return ret; +} + +static int cnl_set_dsp_D3(struct sst_dsp *ctx, unsigned int core_id) +{ + struct skl_sst *cnl = ctx->thread_context; + unsigned int core_mask = SKL_DSP_CORE_MASK(core_id); + struct skl_ipc_dxstate_info dx; + int ret; + + dx.core_mask = core_mask; + dx.dx_mask = SKL_IPC_D3_MASK; + + ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID, + CNL_BASE_FW_MODULE_ID, &dx); + if (ret < 0) { + dev_err(ctx->dev, + "dsp core %d to d3 failed; continue reset\n", + core_id); + cnl->fw_loaded = false; + } + + /* disable interrupts if core 0 */ + if (core_id == SKL_DSP_CORE0_ID) { + skl_ipc_op_int_disable(ctx); + skl_ipc_int_disable(ctx); + } + + ret = cnl_dsp_disable_core(ctx, core_mask); + if (ret < 0) { + dev_err(ctx->dev, "disable dsp core %d failed: %d\n", + core_id, ret); + return ret; + } + + cnl->cores.state[core_id] = SKL_DSP_RESET; + + return ret; +} + +static unsigned int cnl_get_errno(struct sst_dsp *ctx) +{ + return sst_dsp_shim_read(ctx, CNL_ADSP_ERROR_CODE); +} + +static const struct skl_dsp_fw_ops cnl_fw_ops = { + .set_state_D0 = cnl_set_dsp_D0, + .set_state_D3 = cnl_set_dsp_D3, + .load_fw = cnl_load_base_firmware, + .get_fw_errcode = cnl_get_errno, +}; + +static struct sst_ops cnl_ops = { + .irq_handler = cnl_dsp_sst_interrupt, + .write = sst_shim32_write, + .read = sst_shim32_read, + .ram_read = sst_memcpy_fromio_32, + .ram_write = sst_memcpy_toio_32, + .free = cnl_dsp_free, +}; + +#define CNL_IPC_GLB_NOTIFY_RSP_SHIFT 29 +#define CNL_IPC_GLB_NOTIFY_RSP_MASK 0x1 +#define CNL_IPC_GLB_NOTIFY_RSP_TYPE(x) (((x) >> CNL_IPC_GLB_NOTIFY_RSP_SHIFT) \ + & CNL_IPC_GLB_NOTIFY_RSP_MASK) + +static irqreturn_t cnl_dsp_irq_thread_handler(int irq, void *context) +{ + struct sst_dsp *dsp = context; + struct skl_sst *cnl = sst_dsp_get_thread_context(dsp); + struct sst_generic_ipc *ipc = &cnl->ipc; + struct skl_ipc_header header = {0}; + u32 hipcida, hipctdr, hipctdd; + int ipc_irq = 0; + + /* here we handle ipc interrupts only */ + if (!(dsp->intr_status & CNL_ADSPIS_IPC)) + return IRQ_NONE; + + hipcida = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDA); + hipctdr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDR); + + /* reply message from dsp */ + if (hipcida & CNL_ADSP_REG_HIPCIDA_DONE) { + sst_dsp_shim_update_bits(dsp, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, 0); + + /* clear done bit - tell dsp operation is complete */ + sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCIDA, + CNL_ADSP_REG_HIPCIDA_DONE, CNL_ADSP_REG_HIPCIDA_DONE); + + ipc_irq = 1; + + /* unmask done interrupt */ + sst_dsp_shim_update_bits(dsp, CNL_ADSP_REG_HIPCCTL, + CNL_ADSP_REG_HIPCCTL_DONE, CNL_ADSP_REG_HIPCCTL_DONE); + } + + /* new message from dsp */ + if (hipctdr & CNL_ADSP_REG_HIPCTDR_BUSY) { + hipctdd = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCTDD); + header.primary = hipctdr; + header.extension = hipctdd; + dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", + header.primary); + dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", + header.extension); + + if (CNL_IPC_GLB_NOTIFY_RSP_TYPE(header.primary)) { + /* Handle Immediate reply from DSP Core */ + skl_ipc_process_reply(ipc, header); + } else { + dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n"); + skl_ipc_process_notification(ipc, header); + } + /* clear busy interrupt */ + sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCTDR, + CNL_ADSP_REG_HIPCTDR_BUSY, CNL_ADSP_REG_HIPCTDR_BUSY); + + /* set done bit to ack dsp */ + sst_dsp_shim_update_bits_forced(dsp, CNL_ADSP_REG_HIPCTDA, + CNL_ADSP_REG_HIPCTDA_DONE, CNL_ADSP_REG_HIPCTDA_DONE); + ipc_irq = 1; + } + + if (ipc_irq == 0) + return IRQ_NONE; + + cnl_ipc_int_enable(dsp); + + /* continue to send any remaining messages */ + schedule_work(&ipc->kwork); + + return IRQ_HANDLED; +} + +static struct sst_dsp_device cnl_dev = { + .thread = cnl_dsp_irq_thread_handler, + .ops = &cnl_ops, +}; + +static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) +{ + struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->header); + + if (msg->tx_size) + sst_dsp_outbox_write(ipc->dsp, msg->tx_data, msg->tx_size); + sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, + header->extension); + sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, + header->primary | CNL_ADSP_REG_HIPCIDR_BUSY); +} + +static bool cnl_ipc_is_dsp_busy(struct sst_dsp *dsp) +{ + u32 hipcidr; + + hipcidr = sst_dsp_shim_read_unlocked(dsp, CNL_ADSP_REG_HIPCIDR); + + return (hipcidr & CNL_ADSP_REG_HIPCIDR_BUSY); +} + +static int cnl_ipc_init(struct device *dev, struct skl_sst *cnl) +{ + struct sst_generic_ipc *ipc; + int err; + + ipc = &cnl->ipc; + ipc->dsp = cnl->dsp; + ipc->dev = dev; + + ipc->tx_data_max_size = CNL_ADSP_W1_SZ; + ipc->rx_data_max_size = CNL_ADSP_W0_UP_SZ; + + err = sst_ipc_init(ipc); + if (err) + return err; + + /* + * overriding tx_msg and is_dsp_busy since + * ipc registers are different for cnl + */ + ipc->ops.tx_msg = cnl_ipc_tx_msg; + ipc->ops.tx_data_copy = skl_ipc_tx_data_copy; + ipc->ops.is_dsp_busy = cnl_ipc_is_dsp_busy; + + return 0; +} + +int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, + const char *fw_name, struct skl_dsp_loader_ops dsp_ops, + struct skl_sst **dsp) +{ + struct skl_sst *cnl; + struct sst_dsp *sst; + int ret; + + ret = skl_sst_ctx_init(dev, irq, fw_name, dsp_ops, dsp, &cnl_dev); + if (ret < 0) { + dev_err(dev, "%s: no device\n", __func__); + return ret; + } + + cnl = *dsp; + sst = cnl->dsp; + sst->fw_ops = cnl_fw_ops; + sst->addr.lpe = mmio_base; + sst->addr.shim = mmio_base; + sst->addr.sram0_base = CNL_ADSP_SRAM0_BASE; + sst->addr.sram1_base = CNL_ADSP_SRAM1_BASE; + sst->addr.w0_stat_sz = CNL_ADSP_W0_STAT_SZ; + sst->addr.w0_up_sz = CNL_ADSP_W0_UP_SZ; + + sst_dsp_mailbox_init(sst, (CNL_ADSP_SRAM0_BASE + CNL_ADSP_W0_STAT_SZ), + CNL_ADSP_W0_UP_SZ, CNL_ADSP_SRAM1_BASE, + CNL_ADSP_W1_SZ); + + ret = cnl_ipc_init(dev, cnl); + if (ret) { + skl_dsp_free(sst); + return ret; + } + + cnl->boot_complete = false; + init_waitqueue_head(&cnl->boot_wait); + + return 0; +} +EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); + +int cnl_sst_init_fw(struct device *dev, struct skl_sst *ctx) +{ + int ret; + struct sst_dsp *sst = ctx->dsp; + + ret = ctx->dsp->fw_ops.load_fw(sst); + if (ret < 0) { + dev_err(dev, "load base fw failed: %d", ret); + return ret; + } + + skl_dsp_init_core_state(sst); + + ctx->is_first_boot = false; + + return 0; +} +EXPORT_SYMBOL_GPL(cnl_sst_init_fw); + +void cnl_sst_dsp_cleanup(struct device *dev, struct skl_sst *ctx) +{ + if (ctx->dsp->fw) + release_firmware(ctx->dsp->fw); + + skl_freeup_uuid_list(ctx); + cnl_ipc_free(&ctx->ipc); + + ctx->dsp->ops->free(ctx->dsp); +} +EXPORT_SYMBOL_GPL(cnl_sst_dsp_cleanup); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Intel Cannonlake IPC driver"); diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index fb2f1f603f3c..89f70133c8e4 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c @@ -22,6 +22,7 @@ #include #include #include "skl-sst-dsp.h" +#include "cnl-sst-dsp.h" #include "skl-sst-ipc.h" #include "skl.h" #include "../common/sst-dsp.h" @@ -201,6 +202,7 @@ static struct skl_dsp_loader_ops bxt_get_loader_ops(void) static const struct skl_dsp_ops dsp_ops[] = { { .id = 0x9d70, + .num_cores = 2, .loader_ops = skl_get_loader_ops, .init = skl_sst_dsp_init, .init_fw = skl_sst_init_fw, @@ -208,6 +210,7 @@ static const struct skl_dsp_ops dsp_ops[] = { }, { .id = 0x9d71, + .num_cores = 2, .loader_ops = skl_get_loader_ops, .init = kbl_sst_dsp_init, .init_fw = skl_sst_init_fw, @@ -215,6 +218,7 @@ static const struct skl_dsp_ops dsp_ops[] = { }, { .id = 0x5a98, + .num_cores = 2, .loader_ops = bxt_get_loader_ops, .init = bxt_sst_dsp_init, .init_fw = bxt_sst_init_fw, @@ -222,11 +226,20 @@ static const struct skl_dsp_ops dsp_ops[] = { }, { .id = 0x3198, + .num_cores = 2, .loader_ops = bxt_get_loader_ops, .init = bxt_sst_dsp_init, .init_fw = bxt_sst_init_fw, .cleanup = bxt_sst_dsp_cleanup }, + { + .id = 0x9dc8, + .num_cores = 4, + .loader_ops = bxt_get_loader_ops, + .init = cnl_sst_dsp_init, + .init_fw = cnl_sst_init_fw, + .cleanup = cnl_sst_dsp_cleanup + }, }; const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) @@ -249,6 +262,7 @@ int skl_init_dsp(struct skl *skl) struct skl_dsp_loader_ops loader_ops; int irq = bus->irq; const struct skl_dsp_ops *ops; + struct skl_dsp_cores *cores; int ret; /* enable ppcap interrupt */ @@ -263,8 +277,10 @@ int skl_init_dsp(struct skl *skl) } ops = skl_get_dsp_ops(skl->pci->device); - if (!ops) - return -EIO; + if (!ops) { + ret = -EIO; + goto unmap_mmio; + } loader_ops = ops->loader_ops(); ret = ops->init(bus->dev, mmio_base, irq, @@ -272,11 +288,35 @@ int skl_init_dsp(struct skl *skl) &skl->skl_sst); if (ret < 0) - return ret; + goto unmap_mmio; skl->skl_sst->dsp_ops = ops; + cores = &skl->skl_sst->cores; + cores->count = ops->num_cores; + + cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL); + if (!cores->state) { + ret = -ENOMEM; + goto unmap_mmio; + } + + cores->usage_count = kcalloc(cores->count, sizeof(*cores->usage_count), + GFP_KERNEL); + if (!cores->usage_count) { + ret = -ENOMEM; + goto free_core_state; + } + dev_dbg(bus->dev, "dsp registration status=%d\n", ret); + return 0; + +free_core_state: + kfree(cores->state); + +unmap_mmio: + iounmap(mmio_base); + return ret; } @@ -291,6 +331,9 @@ int skl_free_dsp(struct skl *skl) ctx->dsp_ops->cleanup(bus->dev, ctx); + kfree(ctx->cores.state); + kfree(ctx->cores.usage_count); + if (ctx->dsp->addr.lpe) iounmap(ctx->dsp->addr.lpe); @@ -400,9 +443,12 @@ static void skl_set_base_module_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_base_cfg *base_cfg) { - struct skl_module_fmt *format = &mconfig->in_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_res *res = &module->resources[mconfig->res_idx]; + struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *format = &fmt->inputs[0].fmt; - base_cfg->audio_fmt.number_of_channels = (u8)format->channels; + base_cfg->audio_fmt.number_of_channels = format->channels; base_cfg->audio_fmt.s_freq = format->s_freq; base_cfg->audio_fmt.bit_depth = format->bit_depth; @@ -417,10 +463,10 @@ static void skl_set_base_module_format(struct skl_sst *ctx, base_cfg->audio_fmt.interleaving = format->interleaving_style; - base_cfg->cps = mconfig->mcps; - base_cfg->ibs = mconfig->ibs; - base_cfg->obs = mconfig->obs; - base_cfg->is_pages = mconfig->mem_pages; + base_cfg->cps = res->cps; + base_cfg->ibs = res->ibs; + base_cfg->obs = res->obs; + base_cfg->is_pages = res->is_pages; } /* @@ -508,6 +554,9 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, struct skl_cpr_cfg *cpr_mconfig) { u32 dma_io_buf; + struct skl_module_res *res; + int res_idx = mconfig->res_idx; + struct skl *skl = get_skl_ctx(ctx->dev); cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig); @@ -516,19 +565,27 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, return; } + if (skl->nr_modules) { + res = &mconfig->module->resources[mconfig->res_idx]; + cpr_mconfig->gtw_cfg.dma_buffer_size = res->dma_buffer_size; + goto skip_buf_size_calc; + } else { + res = &mconfig->module->resources[res_idx]; + } + switch (mconfig->hw_conn_type) { case SKL_CONN_SOURCE: if (mconfig->dev_type == SKL_DEVICE_HDAHOST) - dma_io_buf = mconfig->ibs; + dma_io_buf = res->ibs; else - dma_io_buf = mconfig->obs; + dma_io_buf = res->obs; break; case SKL_CONN_SINK: if (mconfig->dev_type == SKL_DEVICE_HDAHOST) - dma_io_buf = mconfig->obs; + dma_io_buf = res->obs; else - dma_io_buf = mconfig->ibs; + dma_io_buf = res->ibs; break; default: @@ -543,11 +600,12 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, /* fallback to 2ms default value */ if (!cpr_mconfig->gtw_cfg.dma_buffer_size) { if (mconfig->hw_conn_type == SKL_CONN_SOURCE) - cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs; + cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->obs; else - cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->ibs; + cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->ibs; } +skip_buf_size_calc: cpr_mconfig->cpr_feature_mask = 0; cpr_mconfig->gtw_cfg.config_length = 0; @@ -595,7 +653,9 @@ static void skl_setup_out_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_audio_data_format *out_fmt) { - struct skl_module_fmt *format = &mconfig->out_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *format = &fmt->outputs[0].fmt; out_fmt->number_of_channels = (u8)format->channels; out_fmt->s_freq = format->s_freq; @@ -620,7 +680,9 @@ static void skl_set_src_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_src_module_cfg *src_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *fmt = &iface->outputs[0].fmt; skl_set_base_module_format(ctx, mconfig, (struct skl_base_cfg *)src_mconfig); @@ -637,7 +699,9 @@ static void skl_set_updown_mixer_format(struct skl_sst *ctx, struct skl_module_cfg *mconfig, struct skl_up_down_mixer_cfg *mixer_mconfig) { - struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; + struct skl_module *module = mconfig->module; + struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx]; + struct skl_module_fmt *fmt = &iface->outputs[0].fmt; int i = 0; skl_set_base_module_format(ctx, mconfig, @@ -950,7 +1014,7 @@ static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg { dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", __func__, src_module->id.module_id, src_module->id.pvt_id); - dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, + dev_dbg(ctx->dev, "%s: dst_module=%d dst_instance=%d\n", __func__, dst_module->id.module_id, dst_module->id.pvt_id); dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", @@ -970,8 +1034,8 @@ int skl_unbind_modules(struct skl_sst *ctx, struct skl_ipc_bind_unbind_msg msg; struct skl_module_inst_id src_id = src_mcfg->id; struct skl_module_inst_id dst_id = dst_mcfg->id; - int in_max = dst_mcfg->max_in_queue; - int out_max = src_mcfg->max_out_queue; + int in_max = dst_mcfg->module->max_input_pins; + int out_max = src_mcfg->module->max_output_pins; int src_index, dst_index, src_pin_state, dst_pin_state; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); @@ -1019,6 +1083,21 @@ int skl_unbind_modules(struct skl_sst *ctx, return ret; } +static void fill_pin_params(struct skl_audio_data_format *pin_fmt, + struct skl_module_fmt *format) +{ + pin_fmt->number_of_channels = format->channels; + pin_fmt->s_freq = format->s_freq; + pin_fmt->bit_depth = format->bit_depth; + pin_fmt->valid_bit_depth = format->valid_bit_depth; + pin_fmt->ch_cfg = format->ch_cfg; + pin_fmt->sample_type = format->sample_type; + pin_fmt->channel_map = format->ch_map; + pin_fmt->interleaving = format->interleaving_style; +} + +#define CPR_SINK_FMT_PARAM_ID 2 + /* * Once a module is instantiated it need to be 'bind' with other modules in * the pipeline. For binding we need to find the module pins which are bind @@ -1030,11 +1109,15 @@ int skl_bind_modules(struct skl_sst *ctx, struct skl_module_cfg *src_mcfg, struct skl_module_cfg *dst_mcfg) { - int ret; + int ret = 0; struct skl_ipc_bind_unbind_msg msg; - int in_max = dst_mcfg->max_in_queue; - int out_max = src_mcfg->max_out_queue; + int in_max = dst_mcfg->module->max_input_pins; + int out_max = src_mcfg->module->max_output_pins; int src_index, dst_index; + struct skl_module_fmt *format; + struct skl_cpr_pin_fmt pin_fmt; + struct skl_module *module; + struct skl_module_iface *fmt; skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); @@ -1053,6 +1136,29 @@ int skl_bind_modules(struct skl_sst *ctx, return -EINVAL; } + /* + * Copier module requires the separate large_config_set_ipc to + * configure the pins other than 0 + */ + if (src_mcfg->m_type == SKL_MODULE_TYPE_COPIER && src_index > 0) { + pin_fmt.sink_id = src_index; + module = src_mcfg->module; + fmt = &module->formats[src_mcfg->fmt_idx]; + + /* Input fmt is same as that of src module input cfg */ + format = &fmt->inputs[0].fmt; + fill_pin_params(&(pin_fmt.src_fmt), format); + + format = &fmt->outputs[src_index].fmt; + fill_pin_params(&(pin_fmt.dst_fmt), format); + ret = skl_set_module_params(ctx, (void *)&pin_fmt, + sizeof(struct skl_cpr_pin_fmt), + CPR_SINK_FMT_PARAM_ID, src_mcfg); + + if (ret < 0) + goto out; + } + msg.dst_queue = dst_index; dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", @@ -1070,11 +1176,12 @@ int skl_bind_modules(struct skl_sst *ctx, src_mcfg->m_state = SKL_MODULE_BIND_DONE; src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; - } else { - /* error case , if IPC fails, clear the queue index */ - skl_free_queue(src_mcfg->m_out_pin, src_index); - skl_free_queue(dst_mcfg->m_in_pin, dst_index); + return ret; } +out: + /* error case , if IPC fails, clear the queue index */ + skl_free_queue(src_mcfg->m_out_pin, src_index); + skl_free_queue(dst_mcfg->m_in_pin, dst_index); return ret; } diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 0ebea34a4988..2b1e513b1680 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -33,7 +33,7 @@ #define HDA_STEREO 2 #define HDA_QUAD 4 -static struct snd_pcm_hardware azx_pcm_hw = { +static const struct snd_pcm_hardware azx_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -628,7 +628,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops skl_pcm_dai_ops = { +static const struct snd_soc_dai_ops skl_pcm_dai_ops = { .startup = skl_pcm_open, .shutdown = skl_pcm_close, .prepare = skl_pcm_prepare, @@ -637,15 +637,15 @@ static struct snd_soc_dai_ops skl_pcm_dai_ops = { .trigger = skl_pcm_trigger, }; -static struct snd_soc_dai_ops skl_dmic_dai_ops = { +static const struct snd_soc_dai_ops skl_dmic_dai_ops = { .hw_params = skl_be_hw_params, }; -static struct snd_soc_dai_ops skl_be_ssp_dai_ops = { +static const struct snd_soc_dai_ops skl_be_ssp_dai_ops = { .hw_params = skl_be_hw_params, }; -static struct snd_soc_dai_ops skl_link_dai_ops = { +static const struct snd_soc_dai_ops skl_link_dai_ops = { .prepare = skl_link_pcm_prepare, .hw_params = skl_link_hw_params, .hw_free = skl_link_hw_free, @@ -674,6 +674,32 @@ static struct snd_soc_dai_driver skl_platform_dai[] = { .sig_bits = 32, }, }, +{ + .name = "System Pin2", + .ops = &skl_pcm_dai_ops, + .playback = { + .stream_name = "Headset Playback", + .channels_min = HDA_MONO, + .channels_max = HDA_STEREO, + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, + }, +}, +{ + .name = "Echoref Pin", + .ops = &skl_pcm_dai_ops, + .capture = { + .stream_name = "Echoreference Capture", + .channels_min = HDA_STEREO, + .channels_max = HDA_STEREO, + .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | + SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, + }, +}, { .name = "Reference Pin", .ops = &skl_pcm_dai_ops, @@ -1194,8 +1220,11 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) { struct skl_sst *ctx = skl->skl_sst; + struct skl_module_inst_id *pin_id; + uuid_le *uuid_mod, *uuid_tplg; + struct skl_module *skl_module; struct uuid_module *module; - uuid_le *uuid_mod; + int i, ret = -EIO; uuid_mod = (uuid_le *)mconfig->guid; @@ -1207,12 +1236,45 @@ static int skl_get_module_info(struct skl *skl, struct skl_module_cfg *mconfig) list_for_each_entry(module, &ctx->uuid_list, list) { if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) { mconfig->id.module_id = module->id; - mconfig->is_loadable = module->is_loadable; - return 0; + if (mconfig->module) + mconfig->module->loadable = module->is_loadable; + ret = 0; + break; } } - return -EIO; + if (ret) + return ret; + + uuid_mod = &module->uuid; + ret = -EIO; + for (i = 0; i < skl->nr_modules; i++) { + skl_module = skl->modules[i]; + uuid_tplg = &skl_module->uuid; + if (!uuid_le_cmp(*uuid_mod, *uuid_tplg)) { + mconfig->module = skl_module; + ret = 0; + break; + } + } + if (skl->nr_modules && ret) + return ret; + + list_for_each_entry(module, &ctx->uuid_list, list) { + for (i = 0; i < MAX_IN_QUEUE; i++) { + pin_id = &mconfig->m_in_pin[i].id; + if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid)) + pin_id->module_id = module->id; + } + + for (i = 0; i < MAX_OUT_QUEUE; i++) { + pin_id = &mconfig->m_out_pin[i].id; + if (!uuid_le_cmp(pin_id->mod_uuid, module->uuid)) + pin_id->module_id = module->id; + } + } + + return 0; } static int skl_populate_modules(struct skl *skl) @@ -1284,7 +1346,7 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver skl_platform_drv = { +static const struct snd_soc_platform_driver skl_platform_drv = { .probe = skl_platform_soc_probe, .ops = &skl_platform_ops, .pcm_new = skl_pcm_new, diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c index 08332723c700..19ee1d4f3bdf 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.c +++ b/sound/soc/intel/skylake/skl-sst-dsp.c @@ -47,7 +47,7 @@ void skl_dsp_init_core_state(struct sst_dsp *ctx) skl->cores.state[SKL_DSP_CORE0_ID] = SKL_DSP_RUNNING; skl->cores.usage_count[SKL_DSP_CORE0_ID] = 1; - for (i = SKL_DSP_CORE0_ID + 1; i < SKL_DSP_CORES_MAX; i++) { + for (i = SKL_DSP_CORE0_ID + 1; i < skl->cores.count; i++) { skl->cores.state[i] = SKL_DSP_RESET; skl->cores.usage_count[i] = 0; } @@ -351,6 +351,8 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) return -EINVAL; } + skl->cores.usage_count[core_id]++; + if (skl->cores.state[core_id] == SKL_DSP_RESET) { ret = ctx->fw_ops.set_state_D0(ctx, core_id); if (ret < 0) { @@ -359,8 +361,6 @@ int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id) } } - skl->cores.usage_count[core_id]++; - out: dev_dbg(ctx->dev, "core id %d state %d usage_count %d\n", core_id, skl->cores.state[core_id], diff --git a/sound/soc/intel/skylake/skl-sst-ipc.c b/sound/soc/intel/skylake/skl-sst-ipc.c index 498b15345b1a..5234fafb758a 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.c +++ b/sound/soc/intel/skylake/skl-sst-ipc.c @@ -283,7 +283,7 @@ enum skl_ipc_module_msg { IPC_MOD_SET_D0IX = 8 }; -static void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, +void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, size_t tx_size) { if (tx_size) @@ -347,7 +347,7 @@ out: } -static int skl_ipc_process_notification(struct sst_generic_ipc *ipc, +int skl_ipc_process_notification(struct sst_generic_ipc *ipc, struct skl_ipc_header header) { struct skl_sst *skl = container_of(ipc, struct skl_sst, ipc); @@ -406,7 +406,7 @@ static int skl_ipc_set_reply_error_code(u32 reply) } } -static void skl_ipc_process_reply(struct sst_generic_ipc *ipc, +void skl_ipc_process_reply(struct sst_generic_ipc *ipc, struct skl_ipc_header header) { struct ipc_message *msg; diff --git a/sound/soc/intel/skylake/skl-sst-ipc.h b/sound/soc/intel/skylake/skl-sst-ipc.h index e057da2713c6..55f2d2ce09df 100644 --- a/sound/soc/intel/skylake/skl-sst-ipc.h +++ b/sound/soc/intel/skylake/skl-sst-ipc.h @@ -44,12 +44,10 @@ struct skl_ipc_header { u32 extension; }; -#define SKL_DSP_CORES_MAX 2 - struct skl_dsp_cores { unsigned int count; - enum skl_dsp_states state[SKL_DSP_CORES_MAX]; - int usage_count[SKL_DSP_CORES_MAX]; + enum skl_dsp_states *state; + int *usage_count; }; /** @@ -214,4 +212,10 @@ void skl_ipc_free(struct sst_generic_ipc *ipc); int skl_ipc_init(struct device *dev, struct skl_sst *skl); void skl_clear_module_cnt(struct sst_dsp *ctx); +void skl_ipc_process_reply(struct sst_generic_ipc *ipc, + struct skl_ipc_header header); +int skl_ipc_process_notification(struct sst_generic_ipc *ipc, + struct skl_ipc_header header); +void skl_ipc_tx_data_copy(struct ipc_message *msg, char *tx_data, + size_t tx_size); #endif /* __SKL_IPC_H */ diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index 81ee251881b4..369ef7ce981c 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c @@ -368,7 +368,6 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, { struct skl_sst *skl; struct sst_dsp *sst; - int ret; skl = devm_kzalloc(dev, sizeof(*skl), GFP_KERNEL); if (skl == NULL) @@ -388,15 +387,12 @@ int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, sst->dsp_ops = dsp_ops; init_waitqueue_head(&skl->mod_load_wait); INIT_LIST_HEAD(&sst->module_list); - ret = skl_ipc_init(dev, skl); - if (ret) - return ret; skl->is_first_boot = true; if (dsp) *dsp = skl; - return ret; + return 0; } int skl_prepare_lib_load(struct skl_sst *skl, struct skl_lib_info *linfo, diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index aba9ea11ac74..a436abf2fe3f 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c @@ -503,7 +503,7 @@ static void skl_clear_module_table(struct sst_dsp *ctx) } } -static struct skl_dsp_fw_ops skl_fw_ops = { +static const struct skl_dsp_fw_ops skl_fw_ops = { .set_state_D0 = skl_set_dsp_D0, .set_state_D3 = skl_set_dsp_D3, .load_fw = skl_load_base_firmware, @@ -512,7 +512,7 @@ static struct skl_dsp_fw_ops skl_fw_ops = { .unload_mod = skl_unload_module, }; -static struct skl_dsp_fw_ops kbl_fw_ops = { +static const struct skl_dsp_fw_ops kbl_fw_ops = { .set_state_D0 = skl_set_dsp_D0, .set_state_D3 = skl_set_dsp_D3, .load_fw = skl_load_base_firmware, @@ -561,9 +561,13 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, sst_dsp_mailbox_init(sst, (SKL_ADSP_SRAM0_BASE + SKL_ADSP_W0_STAT_SZ), SKL_ADSP_W0_UP_SZ, SKL_ADSP_SRAM1_BASE, SKL_ADSP_W1_SZ); - sst->fw_ops = skl_fw_ops; + ret = skl_ipc_init(dev, skl); + if (ret) { + skl_dsp_free(sst); + return ret; + } - skl->cores.count = 2; + sst->fw_ops = skl_fw_ops; return 0; } diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 68c3f121efc3..22f768ca3c73 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -49,6 +49,9 @@ static const int mic_quatro_list[][SKL_CH_QUATRO] = { {0, 1, 2, 3}, }; +#define CHECK_HW_PARAMS(ch, freq, bps, prm_ch, prm_freq, prm_bps) \ + ((ch == prm_ch) && (bps == prm_bps) && (freq == prm_freq)) + void skl_tplg_d0i3_get(struct skl *skl, enum d0i3_capability caps) { struct skl_d0i3_data *d0i3 = &skl->skl_sst->d0i3; @@ -153,8 +156,10 @@ static bool skl_is_pipe_mcps_avail(struct skl *skl, struct skl_module_cfg *mconfig) { struct skl_sst *ctx = skl->skl_sst; + u8 res_idx = mconfig->res_idx; + struct skl_module_res *res = &mconfig->module->resources[res_idx]; - if (skl->resource.mcps + mconfig->mcps > skl->resource.max_mcps) { + if (skl->resource.mcps + res->cps > skl->resource.max_mcps) { dev_err(ctx->dev, "%s: module_id %d instance %d\n", __func__, mconfig->id.module_id, mconfig->id.instance_id); @@ -170,7 +175,10 @@ static bool skl_is_pipe_mcps_avail(struct skl *skl, static void skl_tplg_alloc_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig) { - skl->resource.mcps += mconfig->mcps; + u8 res_idx = mconfig->res_idx; + struct skl_module_res *res = &mconfig->module->resources[res_idx]; + + skl->resource.mcps += res->cps; } /* @@ -179,7 +187,11 @@ static void skl_tplg_alloc_pipe_mcps(struct skl *skl, static void skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig) { - skl->resource.mcps -= mconfig->mcps; + u8 res_idx = mconfig->res_idx; + struct skl_module_res *res = &mconfig->module->resources[res_idx]; + + res = &mconfig->module->resources[res_idx]; + skl->resource.mcps -= res->cps; } /* @@ -195,17 +207,21 @@ skl_tplg_free_pipe_mem(struct skl *skl, struct skl_module_cfg *mconfig) static void skl_dump_mconfig(struct skl_sst *ctx, struct skl_module_cfg *mcfg) { + struct skl_module_iface *iface = &mcfg->module->formats[0]; + dev_dbg(ctx->dev, "Dumping config\n"); dev_dbg(ctx->dev, "Input Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->in_fmt[0].channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->in_fmt[0].s_freq); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->in_fmt[0].ch_cfg); - dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->in_fmt[0].valid_bit_depth); + dev_dbg(ctx->dev, "channels = %d\n", iface->inputs[0].fmt.channels); + dev_dbg(ctx->dev, "s_freq = %d\n", iface->inputs[0].fmt.s_freq); + dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->inputs[0].fmt.ch_cfg); + dev_dbg(ctx->dev, "valid bit depth = %d\n", + iface->inputs[0].fmt.valid_bit_depth); dev_dbg(ctx->dev, "Output Format:\n"); - dev_dbg(ctx->dev, "channels = %d\n", mcfg->out_fmt[0].channels); - dev_dbg(ctx->dev, "s_freq = %d\n", mcfg->out_fmt[0].s_freq); - dev_dbg(ctx->dev, "valid bit depth = %d\n", mcfg->out_fmt[0].valid_bit_depth); - dev_dbg(ctx->dev, "ch_cfg = %d\n", mcfg->out_fmt[0].ch_cfg); + dev_dbg(ctx->dev, "channels = %d\n", iface->outputs[0].fmt.channels); + dev_dbg(ctx->dev, "s_freq = %d\n", iface->outputs[0].fmt.s_freq); + dev_dbg(ctx->dev, "valid bit depth = %d\n", + iface->outputs[0].fmt.valid_bit_depth); + dev_dbg(ctx->dev, "ch_cfg = %d\n", iface->outputs[0].fmt.ch_cfg); } static void skl_tplg_update_chmap(struct skl_module_fmt *fmt, int chs) @@ -273,8 +289,8 @@ static void skl_tplg_update_params_fixup(struct skl_module_cfg *m_cfg, struct skl_module_fmt *in_fmt, *out_fmt; /* Fixups will be applied to pin 0 only */ - in_fmt = &m_cfg->in_fmt[0]; - out_fmt = &m_cfg->out_fmt[0]; + in_fmt = &m_cfg->module->formats[0].inputs[0].fmt; + out_fmt = &m_cfg->module->formats[0].outputs[0].fmt; if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (is_fe) { @@ -312,21 +328,23 @@ static void skl_tplg_update_buffer_size(struct skl_sst *ctx, { int multiplier = 1; struct skl_module_fmt *in_fmt, *out_fmt; + struct skl_module_res *res; /* Since fixups is applied to pin 0 only, ibs, obs needs * change for pin 0 only */ - in_fmt = &mcfg->in_fmt[0]; - out_fmt = &mcfg->out_fmt[0]; + res = &mcfg->module->resources[0]; + in_fmt = &mcfg->module->formats[0].inputs[0].fmt; + out_fmt = &mcfg->module->formats[0].outputs[0].fmt; if (mcfg->m_type == SKL_MODULE_TYPE_SRCINT) multiplier = 5; - mcfg->ibs = DIV_ROUND_UP(in_fmt->s_freq, 1000) * + res->ibs = DIV_ROUND_UP(in_fmt->s_freq, 1000) * in_fmt->channels * (in_fmt->bit_depth >> 3) * multiplier; - mcfg->obs = DIV_ROUND_UP(out_fmt->s_freq, 1000) * + res->obs = DIV_ROUND_UP(out_fmt->s_freq, 1000) * out_fmt->channels * (out_fmt->bit_depth >> 3) * multiplier; } @@ -365,6 +383,8 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, struct nhlt_specific_cfg *cfg; struct skl *skl = get_skl_ctx(ctx->dev); u8 dev_type = skl_tplg_be_dev_type(m_cfg->dev_type); + int fmt_idx = m_cfg->fmt_idx; + struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx]; /* check if we already have blob */ if (m_cfg->formats_config.caps_size > 0) @@ -375,23 +395,23 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, case SKL_DEVICE_DMIC: link_type = NHLT_LINK_DMIC; dir = SNDRV_PCM_STREAM_CAPTURE; - s_freq = m_cfg->in_fmt[0].s_freq; - s_fmt = m_cfg->in_fmt[0].bit_depth; - ch = m_cfg->in_fmt[0].channels; + s_freq = m_iface->inputs[0].fmt.s_freq; + s_fmt = m_iface->inputs[0].fmt.bit_depth; + ch = m_iface->inputs[0].fmt.channels; break; case SKL_DEVICE_I2S: link_type = NHLT_LINK_SSP; if (m_cfg->hw_conn_type == SKL_CONN_SOURCE) { dir = SNDRV_PCM_STREAM_PLAYBACK; - s_freq = m_cfg->out_fmt[0].s_freq; - s_fmt = m_cfg->out_fmt[0].bit_depth; - ch = m_cfg->out_fmt[0].channels; + s_freq = m_iface->outputs[0].fmt.s_freq; + s_fmt = m_iface->outputs[0].fmt.bit_depth; + ch = m_iface->outputs[0].fmt.channels; } else { dir = SNDRV_PCM_STREAM_CAPTURE; - s_freq = m_cfg->in_fmt[0].s_freq; - s_fmt = m_cfg->in_fmt[0].bit_depth; - ch = m_cfg->in_fmt[0].channels; + s_freq = m_iface->inputs[0].fmt.s_freq; + s_fmt = m_iface->inputs[0].fmt.bit_depth; + ch = m_iface->inputs[0].fmt.channels; } break; @@ -549,6 +569,7 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) struct snd_soc_dapm_widget *w; struct skl_module_cfg *mconfig; struct skl_sst *ctx = skl->skl_sst; + u8 cfg_idx; int ret = 0; list_for_each_entry(w_module, &pipe->w_list, node) { @@ -564,11 +585,15 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) return -EIO; } + cfg_idx = mconfig->pipe->cur_config_idx; + mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; + mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; + /* check resource available */ if (!skl_is_pipe_mcps_avail(skl, mconfig)) return -ENOMEM; - if (mconfig->is_loadable && ctx->dsp->fw_ops.load_mod) { + if (mconfig->module->loadable && ctx->dsp->fw_ops.load_mod) { ret = ctx->dsp->fw_ops.load_mod(ctx->dsp, mconfig->id.module_id, mconfig->guid); if (ret < 0) @@ -596,24 +621,35 @@ skl_tplg_init_pipe_modules(struct skl *skl, struct skl_pipe *pipe) if (mconfig->id.pvt_id < 0) return ret; skl_tplg_set_module_init_data(w); + + ret = skl_dsp_get_core(ctx->dsp, mconfig->core_id); + if (ret < 0) { + dev_err(ctx->dev, "Failed to wake up core %d ret=%d\n", + mconfig->core_id, ret); + return ret; + } + ret = skl_init_module(ctx, mconfig); if (ret < 0) { skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); - return ret; + goto err; } skl_tplg_alloc_pipe_mcps(skl, mconfig); ret = skl_tplg_set_module_params(w, ctx); if (ret < 0) - return ret; + goto err; } return 0; +err: + skl_dsp_put_core(ctx->dsp, mconfig->core_id); + return ret; } static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, struct skl_pipe *pipe) { - int ret; + int ret = 0; struct skl_pipe_module *w_module = NULL; struct skl_module_cfg *mconfig = NULL; @@ -622,7 +658,7 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, mconfig = w_module->w->priv; uuid_mod = (uuid_le *)mconfig->guid; - if (mconfig->is_loadable && ctx->dsp->fw_ops.unload_mod && + if (mconfig->module->loadable && ctx->dsp->fw_ops.unload_mod && mconfig->m_state > SKL_MODULE_UNINIT) { ret = ctx->dsp->fw_ops.unload_mod(ctx->dsp, mconfig->id.module_id); @@ -630,10 +666,76 @@ static int skl_tplg_unload_pipe_modules(struct skl_sst *ctx, return -EIO; } skl_put_pvt_id(ctx, uuid_mod, &mconfig->id.pvt_id); + + ret = skl_dsp_put_core(ctx->dsp, mconfig->core_id); + if (ret < 0) { + /* don't return; continue with other modules */ + dev_err(ctx->dev, "Failed to sleep core %d ret=%d\n", + mconfig->core_id, ret); + } } /* no modules to unload in this path, so return */ - return 0; + return ret; +} + +/* + * Here, we select pipe format based on the pipe type and pipe + * direction to determine the current config index for the pipeline. + * The config index is then used to select proper module resources. + * Intermediate pipes currently have a fixed format hence we select the + * 0th configuratation by default for such pipes. + */ +static int +skl_tplg_get_pipe_config(struct skl *skl, struct skl_module_cfg *mconfig) +{ + struct skl_sst *ctx = skl->skl_sst; + struct skl_pipe *pipe = mconfig->pipe; + struct skl_pipe_params *params = pipe->p_params; + struct skl_path_config *pconfig = &pipe->configs[0]; + struct skl_pipe_fmt *fmt = NULL; + bool in_fmt = false; + int i; + + if (pipe->nr_cfgs == 0) { + pipe->cur_config_idx = 0; + return 0; + } + + if (pipe->conn_type == SKL_PIPE_CONN_TYPE_NONE) { + dev_dbg(ctx->dev, "No conn_type detected, take 0th config\n"); + pipe->cur_config_idx = 0; + pipe->memory_pages = pconfig->mem_pages; + + return 0; + } + + if ((pipe->conn_type == SKL_PIPE_CONN_TYPE_FE && + pipe->direction == SNDRV_PCM_STREAM_PLAYBACK) || + (pipe->conn_type == SKL_PIPE_CONN_TYPE_BE && + pipe->direction == SNDRV_PCM_STREAM_CAPTURE)) + in_fmt = true; + + for (i = 0; i < pipe->nr_cfgs; i++) { + pconfig = &pipe->configs[i]; + if (in_fmt) + fmt = &pconfig->in_fmt; + else + fmt = &pconfig->out_fmt; + + if (CHECK_HW_PARAMS(params->ch, params->s_freq, params->s_fmt, + fmt->channels, fmt->freq, fmt->bps)) { + pipe->cur_config_idx = i; + pipe->memory_pages = pconfig->mem_pages; + dev_dbg(ctx->dev, "Using pipe config: %d\n", i); + + return 0; + } + } + + dev_err(ctx->dev, "Invalid pipe config: %d %d %d for pipe: %d\n", + params->ch, params->s_freq, params->s_fmt, pipe->ppl_id); + return -EINVAL; } /* @@ -655,6 +757,10 @@ static int skl_tplg_mixer_dapm_pre_pmu_event(struct snd_soc_dapm_widget *w, struct skl_sst *ctx = skl->skl_sst; struct skl_module_deferred_bind *modules; + ret = skl_tplg_get_pipe_config(skl, mconfig); + if (ret < 0) + return ret; + /* check resource available */ if (!skl_is_pipe_mcps_avail(skl, mconfig)) return -EBUSY; @@ -758,12 +864,12 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, * check all out/in pins are in bind state. * if so set the module param */ - for (i = 0; i < mcfg->max_out_queue; i++) { + for (i = 0; i < mcfg->module->max_output_pins; i++) { if (mcfg->m_out_pin[i].pin_state != SKL_PIN_BIND_DONE) return 0; } - for (i = 0; i < mcfg->max_in_queue; i++) { + for (i = 0; i < mcfg->module->max_input_pins; i++) { if (mcfg->m_in_pin[i].pin_state != SKL_PIN_BIND_DONE) return 0; } @@ -814,7 +920,7 @@ static int skl_tplg_module_add_deferred_bind(struct skl *skl, int i; /* only supported for module with static pin connection */ - for (i = 0; i < dst->max_in_queue; i++) { + for (i = 0; i < dst->module->max_input_pins; i++) { struct skl_module_pin *pin = &dst->m_in_pin[i]; if (pin->is_dynamic) @@ -925,7 +1031,7 @@ static int skl_tplg_bind_sinks(struct snd_soc_dapm_widget *w, } } - if (!sink) + if (!sink && next_sink) return skl_tplg_bind_sinks(next_sink, skl, src_w, src_mconfig); return 0; @@ -1074,7 +1180,7 @@ static int skl_tplg_mixer_dapm_pre_pmd_event(struct snd_soc_dapm_widget *w, if (ret) return ret; - for (i = 0; i < sink_mconfig->max_in_queue; i++) { + for (i = 0; i < sink_mconfig->module->max_input_pins; i++) { if (sink_mconfig->m_in_pin[i].pin_state == SKL_PIN_BIND_DONE) { src_mconfig = sink_mconfig->m_in_pin[i].tgt_mcfg; if (!src_mconfig) @@ -1185,7 +1291,7 @@ static int skl_tplg_pga_dapm_post_pmd_event(struct snd_soc_dapm_widget *w, if (ret) return ret; - for (i = 0; i < src_mconfig->max_out_queue; i++) { + for (i = 0; i < src_mconfig->module->max_output_pins; i++) { if (src_mconfig->m_out_pin[i].pin_state == SKL_PIN_BIND_DONE) { sink_mconfig = src_mconfig->m_out_pin[i].tgt_mcfg; if (!sink_mconfig) @@ -1479,14 +1585,22 @@ int skl_tplg_update_pipe_params(struct device *dev, struct skl_module_cfg *mconfig, struct skl_pipe_params *params) { + struct skl_module_res *res = &mconfig->module->resources[0]; + struct skl *skl = get_skl_ctx(dev); struct skl_module_fmt *format = NULL; + u8 cfg_idx = mconfig->pipe->cur_config_idx; skl_tplg_fill_dma_id(mconfig, params); + mconfig->fmt_idx = mconfig->mod_cfg[cfg_idx].fmt_idx; + mconfig->res_idx = mconfig->mod_cfg[cfg_idx].res_idx; + + if (skl->nr_modules) + return 0; if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) - format = &mconfig->in_fmt[0]; + format = &mconfig->module->formats[0].inputs[0].fmt; else - format = &mconfig->out_fmt[0]; + format = &mconfig->module->formats[0].outputs[0].fmt; /* set the hw_params */ format->s_freq = params->s_freq; @@ -1514,11 +1628,11 @@ int skl_tplg_update_pipe_params(struct device *dev, } if (params->stream == SNDRV_PCM_STREAM_PLAYBACK) { - mconfig->ibs = (format->s_freq / 1000) * + res->ibs = (format->s_freq / 1000) * (format->channels) * (format->bit_depth >> 3); } else { - mconfig->obs = (format->s_freq / 1000) * + res->obs = (format->s_freq / 1000) * (format->channels) * (format->bit_depth >> 3); } @@ -1792,6 +1906,54 @@ static const struct snd_soc_tplg_kcontrol_ops skl_tplg_kcontrol_ops[] = { }, }; +static int skl_tplg_fill_pipe_cfg(struct device *dev, + struct skl_pipe *pipe, u32 tkn, + u32 tkn_val, int conf_idx, int dir) +{ + struct skl_pipe_fmt *fmt; + struct skl_path_config *config; + + switch (dir) { + case SKL_DIR_IN: + fmt = &pipe->configs[conf_idx].in_fmt; + break; + + case SKL_DIR_OUT: + fmt = &pipe->configs[conf_idx].out_fmt; + break; + + default: + dev_err(dev, "Invalid direction: %d\n", dir); + return -EINVAL; + } + + config = &pipe->configs[conf_idx]; + + switch (tkn) { + case SKL_TKN_U32_CFG_FREQ: + fmt->freq = tkn_val; + break; + + case SKL_TKN_U8_CFG_CHAN: + fmt->channels = tkn_val; + break; + + case SKL_TKN_U8_CFG_BPS: + fmt->bps = tkn_val; + break; + + case SKL_TKN_U32_PATH_MEM_PGS: + config->mem_pages = tkn_val; + break; + + default: + dev_err(dev, "Invalid token config: %d\n", tkn); + return -EINVAL; + } + + return 0; +} + static int skl_tplg_fill_pipe_tkn(struct device *dev, struct skl_pipe *pipe, u32 tkn, u32 tkn_val) @@ -1814,6 +1976,14 @@ static int skl_tplg_fill_pipe_tkn(struct device *dev, pipe->lp_mode = tkn_val; break; + case SKL_TKN_U32_PIPE_DIRECTION: + pipe->direction = tkn_val; + break; + + case SKL_TKN_U32_NUM_CONFIGS: + pipe->nr_cfgs = tkn_val; + break; + default: dev_err(dev, "Token not handled %d\n", tkn); return -EINVAL; @@ -1930,27 +2100,9 @@ static int skl_tplg_fill_pins_info(struct device *dev, * on the direction */ static int skl_tplg_fill_fmt(struct device *dev, - struct skl_module_cfg *mconfig, u32 tkn, - u32 value, u32 dir, u32 pin_count) + struct skl_module_fmt *dst_fmt, + u32 tkn, u32 value) { - struct skl_module_fmt *dst_fmt; - - switch (dir) { - case SKL_DIR_IN: - dst_fmt = mconfig->in_fmt; - dst_fmt += pin_count; - break; - - case SKL_DIR_OUT: - dst_fmt = mconfig->out_fmt; - dst_fmt += pin_count; - break; - - default: - dev_err(dev, "Invalid direction value\n"); - return -EINVAL; - } - switch (tkn) { case SKL_TKN_U32_FMT_CH: dst_fmt->channels = value; @@ -1992,6 +2144,32 @@ static int skl_tplg_fill_fmt(struct device *dev, return 0; } +static int skl_tplg_widget_fill_fmt(struct device *dev, + struct skl_module_iface *fmt, + u32 tkn, u32 val, u32 dir, int fmt_idx) +{ + struct skl_module_fmt *dst_fmt; + + if (!fmt) + return -EINVAL; + + switch (dir) { + case SKL_DIR_IN: + dst_fmt = &fmt->inputs[fmt_idx].fmt; + break; + + case SKL_DIR_OUT: + dst_fmt = &fmt->outputs[fmt_idx].fmt; + break; + + default: + dev_err(dev, "Invalid direction: %d\n", dir); + return -EINVAL; + } + + return skl_tplg_fill_fmt(dev, dst_fmt, tkn, val); +} + static int skl_tplg_get_uuid(struct device *dev, struct skl_module_cfg *mconfig, struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn) { @@ -2014,6 +2192,108 @@ static void skl_tplg_fill_pin_dynamic_val( mpin[i].is_dynamic = value; } +/* + * Resource table in the manifest has pin specific resources + * like pin and pin buffer size + */ +static int skl_tplg_manifest_pin_res_tkn(struct device *dev, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + struct skl_module_res *res, int pin_idx, int dir) +{ + struct skl_module_pin_resources *m_pin; + + switch (dir) { + case SKL_DIR_IN: + m_pin = &res->input[pin_idx]; + break; + + case SKL_DIR_OUT: + m_pin = &res->output[pin_idx]; + break; + + default: + dev_err(dev, "Invalid pin direction: %d\n", dir); + return -EINVAL; + } + + switch (tkn_elem->token) { + case SKL_TKN_MM_U32_RES_PIN_ID: + m_pin->pin_index = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_PIN_BUF: + m_pin->buf_size = tkn_elem->value; + break; + + default: + dev_err(dev, "Invalid token: %d\n", tkn_elem->token); + return -EINVAL; + } + + return 0; +} + +/* + * Fill module specific resources from the manifest's resource + * table like CPS, DMA size, mem_pages. + */ +static int skl_tplg_fill_res_tkn(struct device *dev, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + struct skl_module_res *res, + int pin_idx, int dir) +{ + int ret, tkn_count = 0; + + if (!res) + return -EINVAL; + + switch (tkn_elem->token) { + case SKL_TKN_MM_U32_CPS: + res->cps = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_DMA_SIZE: + res->dma_buffer_size = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_CPC: + res->cpc = tkn_elem->value; + break; + + case SKL_TKN_U32_MEM_PAGES: + res->is_pages = tkn_elem->value; + break; + + case SKL_TKN_U32_OBS: + res->obs = tkn_elem->value; + break; + + case SKL_TKN_U32_IBS: + res->ibs = tkn_elem->value; + break; + + case SKL_TKN_U32_MAX_MCPS: + res->cps = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_RES_PIN_ID: + case SKL_TKN_MM_U32_PIN_BUF: + ret = skl_tplg_manifest_pin_res_tkn(dev, tkn_elem, res, + pin_idx, dir); + if (ret < 0) + return ret; + break; + + default: + dev_err(dev, "Not a res type token: %d", tkn_elem->token); + return -EINVAL; + + } + tkn_count++; + + return tkn_count; +} + /* * Parse tokens to fill up the module private data */ @@ -2024,49 +2304,54 @@ static int skl_tplg_get_token(struct device *dev, int tkn_count = 0; int ret; static int is_pipe_exists; - static int pin_index, dir; + static int pin_index, dir, conf_idx; + struct skl_module_iface *iface = NULL; + struct skl_module_res *res = NULL; + int res_idx = mconfig->res_idx; + int fmt_idx = mconfig->fmt_idx; + + /* + * If the manifest structure contains no modules, fill all + * the module data to 0th index. + * res_idx and fmt_idx are default set to 0. + */ + if (skl->nr_modules == 0) { + res = &mconfig->module->resources[res_idx]; + iface = &mconfig->module->formats[fmt_idx]; + } if (tkn_elem->token > SKL_TKN_MAX) return -EINVAL; switch (tkn_elem->token) { case SKL_TKN_U8_IN_QUEUE_COUNT: - mconfig->max_in_queue = tkn_elem->value; - mconfig->m_in_pin = devm_kzalloc(dev, mconfig->max_in_queue * - sizeof(*mconfig->m_in_pin), - GFP_KERNEL); - if (!mconfig->m_in_pin) - return -ENOMEM; - + mconfig->module->max_input_pins = tkn_elem->value; break; case SKL_TKN_U8_OUT_QUEUE_COUNT: - mconfig->max_out_queue = tkn_elem->value; - mconfig->m_out_pin = devm_kzalloc(dev, mconfig->max_out_queue * - sizeof(*mconfig->m_out_pin), - GFP_KERNEL); - - if (!mconfig->m_out_pin) - return -ENOMEM; - + mconfig->module->max_output_pins = tkn_elem->value; break; case SKL_TKN_U8_DYN_IN_PIN: + if (!mconfig->m_in_pin) + mconfig->m_in_pin = devm_kzalloc(dev, MAX_IN_QUEUE * + sizeof(*mconfig->m_in_pin), GFP_KERNEL); if (!mconfig->m_in_pin) return -ENOMEM; - skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin, - mconfig->max_in_queue, tkn_elem->value); - + skl_tplg_fill_pin_dynamic_val(mconfig->m_in_pin, MAX_IN_QUEUE, + tkn_elem->value); break; case SKL_TKN_U8_DYN_OUT_PIN: + if (!mconfig->m_out_pin) + mconfig->m_out_pin = devm_kzalloc(dev, MAX_IN_QUEUE * + sizeof(*mconfig->m_in_pin), GFP_KERNEL); if (!mconfig->m_out_pin) return -ENOMEM; - skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin, - mconfig->max_out_queue, tkn_elem->value); - + skl_tplg_fill_pin_dynamic_val(mconfig->m_out_pin, MAX_OUT_QUEUE, + tkn_elem->value); break; case SKL_TKN_U8_TIME_SLOT: @@ -2094,19 +2379,13 @@ static int skl_tplg_get_token(struct device *dev, break; case SKL_TKN_U32_MEM_PAGES: - mconfig->mem_pages = tkn_elem->value; - break; - case SKL_TKN_U32_MAX_MCPS: - mconfig->mcps = tkn_elem->value; - break; - case SKL_TKN_U32_OBS: - mconfig->obs = tkn_elem->value; - break; - case SKL_TKN_U32_IBS: - mconfig->ibs = tkn_elem->value; + ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, dir, pin_index); + if (ret < 0) + return ret; + break; case SKL_TKN_U32_VBUS_ID: @@ -2139,10 +2418,16 @@ static int skl_tplg_get_token(struct device *dev, break; + case SKL_TKN_U32_PIPE_CONFIG_ID: + conf_idx = tkn_elem->value; + break; + case SKL_TKN_U32_PIPE_CONN_TYPE: case SKL_TKN_U32_PIPE_PRIORITY: case SKL_TKN_U32_PIPE_MEM_PGS: case SKL_TKN_U32_PMODE: + case SKL_TKN_U32_PIPE_DIRECTION: + case SKL_TKN_U32_NUM_CONFIGS: if (is_pipe_exists) { ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe, tkn_elem->token, tkn_elem->value); @@ -2152,6 +2437,27 @@ static int skl_tplg_get_token(struct device *dev, break; + case SKL_TKN_U32_PATH_MEM_PGS: + case SKL_TKN_U32_CFG_FREQ: + case SKL_TKN_U8_CFG_CHAN: + case SKL_TKN_U8_CFG_BPS: + if (mconfig->pipe->nr_cfgs) { + ret = skl_tplg_fill_pipe_cfg(dev, mconfig->pipe, + tkn_elem->token, tkn_elem->value, + conf_idx, dir); + if (ret < 0) + return ret; + } + break; + + case SKL_TKN_CFG_MOD_RES_ID: + mconfig->mod_cfg[conf_idx].res_idx = tkn_elem->value; + break; + + case SKL_TKN_CFG_MOD_FMT_ID: + mconfig->mod_cfg[conf_idx].fmt_idx = tkn_elem->value; + break; + /* * SKL_TKN_U32_DIR_PIN_COUNT token has the value for both * direction and the pin count. The first four bits represent @@ -2172,7 +2478,7 @@ static int skl_tplg_get_token(struct device *dev, case SKL_TKN_U32_FMT_INTERLEAVE: case SKL_TKN_U32_FMT_SAMPLE_TYPE: case SKL_TKN_U32_FMT_CH_MAP: - ret = skl_tplg_fill_fmt(dev, mconfig, tkn_elem->token, + ret = skl_tplg_widget_fill_fmt(dev, iface, tkn_elem->token, tkn_elem->value, dir, pin_index); if (ret < 0) @@ -2397,11 +2703,11 @@ static void skl_clear_pin_config(struct snd_soc_platform *platform, strlen(platform->component.name))) { mconfig = w->priv; pipe = mconfig->pipe; - for (i = 0; i < mconfig->max_in_queue; i++) { + for (i = 0; i < mconfig->module->max_input_pins; i++) { mconfig->m_in_pin[i].in_use = false; mconfig->m_in_pin[i].pin_state = SKL_PIN_UNBIND; } - for (i = 0; i < mconfig->max_out_queue; i++) { + for (i = 0; i < mconfig->module->max_output_pins; i++) { mconfig->m_out_pin[i].in_use = false; mconfig->m_out_pin[i].pin_state = SKL_PIN_UNBIND; } @@ -2460,6 +2766,13 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, if (!mconfig) return -ENOMEM; + if (skl->nr_modules == 0) { + mconfig->module = devm_kzalloc(bus->dev, + sizeof(*mconfig->module), GFP_KERNEL); + if (!mconfig->module) + return -ENOMEM; + } + w->priv = mconfig; /* @@ -2602,13 +2915,13 @@ static int skl_tplg_fill_str_mfest_tkn(struct device *dev, str_elem->string, ARRAY_SIZE(skl->skl_sst->lib_info[ref_count].name)); ref_count++; - tkn_count++; break; default: dev_err(dev, "Not a string token %d\n", str_elem->token); break; } + tkn_count++; return tkn_count; } @@ -2634,26 +2947,236 @@ static int skl_tplg_get_str_tkn(struct device *dev, return tkn_count; } +static int skl_tplg_manifest_fill_fmt(struct device *dev, + struct skl_module_iface *fmt, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + u32 dir, int fmt_idx) +{ + struct skl_module_pin_fmt *dst_fmt; + struct skl_module_fmt *mod_fmt; + int ret; + + if (!fmt) + return -EINVAL; + + switch (dir) { + case SKL_DIR_IN: + dst_fmt = &fmt->inputs[fmt_idx]; + break; + + case SKL_DIR_OUT: + dst_fmt = &fmt->outputs[fmt_idx]; + break; + + default: + dev_err(dev, "Invalid direction: %d\n", dir); + return -EINVAL; + } + + mod_fmt = &dst_fmt->fmt; + + switch (tkn_elem->token) { + case SKL_TKN_MM_U32_INTF_PIN_ID: + dst_fmt->id = tkn_elem->value; + break; + + default: + ret = skl_tplg_fill_fmt(dev, mod_fmt, tkn_elem->token, + tkn_elem->value); + if (ret < 0) + return ret; + break; + } + + return 0; +} + +static int skl_tplg_fill_mod_info(struct device *dev, + struct snd_soc_tplg_vendor_value_elem *tkn_elem, + struct skl_module *mod) +{ + + if (!mod) + return -EINVAL; + + switch (tkn_elem->token) { + case SKL_TKN_U8_IN_PIN_TYPE: + mod->input_pin_type = tkn_elem->value; + break; + + case SKL_TKN_U8_OUT_PIN_TYPE: + mod->output_pin_type = tkn_elem->value; + break; + + case SKL_TKN_U8_IN_QUEUE_COUNT: + mod->max_input_pins = tkn_elem->value; + break; + + case SKL_TKN_U8_OUT_QUEUE_COUNT: + mod->max_output_pins = tkn_elem->value; + break; + + case SKL_TKN_MM_U8_NUM_RES: + mod->nr_resources = tkn_elem->value; + break; + + case SKL_TKN_MM_U8_NUM_INTF: + mod->nr_interfaces = tkn_elem->value; + break; + + default: + dev_err(dev, "Invalid mod info token %d", tkn_elem->token); + return -EINVAL; + } + + return 0; +} + + static int skl_tplg_get_int_tkn(struct device *dev, struct snd_soc_tplg_vendor_value_elem *tkn_elem, struct skl *skl) { - int tkn_count = 0; + int tkn_count = 0, ret; + static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx; + struct skl_module_res *res = NULL; + struct skl_module_iface *fmt = NULL; + struct skl_module *mod = NULL; + int i; + + if (skl->modules) { + mod = skl->modules[mod_idx]; + res = &mod->resources[res_val_idx]; + fmt = &mod->formats[intf_val_idx]; + } switch (tkn_elem->token) { case SKL_TKN_U32_LIB_COUNT: skl->skl_sst->lib_count = tkn_elem->value; - tkn_count++; + break; + + case SKL_TKN_U8_NUM_MOD: + skl->nr_modules = tkn_elem->value; + skl->modules = devm_kcalloc(dev, skl->nr_modules, + sizeof(*skl->modules), GFP_KERNEL); + if (!skl->modules) + return -ENOMEM; + + for (i = 0; i < skl->nr_modules; i++) { + skl->modules[i] = devm_kzalloc(dev, + sizeof(struct skl_module), GFP_KERNEL); + if (!skl->modules[i]) + return -ENOMEM; + } + break; + + case SKL_TKN_MM_U8_MOD_IDX: + mod_idx = tkn_elem->value; + break; + + case SKL_TKN_U8_IN_PIN_TYPE: + case SKL_TKN_U8_OUT_PIN_TYPE: + case SKL_TKN_U8_IN_QUEUE_COUNT: + case SKL_TKN_U8_OUT_QUEUE_COUNT: + case SKL_TKN_MM_U8_NUM_RES: + case SKL_TKN_MM_U8_NUM_INTF: + ret = skl_tplg_fill_mod_info(dev, tkn_elem, mod); + if (ret < 0) + return ret; + break; + + case SKL_TKN_U32_DIR_PIN_COUNT: + dir = tkn_elem->value & SKL_IN_DIR_BIT_MASK; + pin_idx = (tkn_elem->value & SKL_PIN_COUNT_MASK) >> 4; + break; + + case SKL_TKN_MM_U32_RES_ID: + if (!res) + return -EINVAL; + + res->id = tkn_elem->value; + res_val_idx = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_FMT_ID: + if (!fmt) + return -EINVAL; + + fmt->fmt_idx = tkn_elem->value; + intf_val_idx = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_CPS: + case SKL_TKN_MM_U32_DMA_SIZE: + case SKL_TKN_MM_U32_CPC: + case SKL_TKN_U32_MEM_PAGES: + case SKL_TKN_U32_OBS: + case SKL_TKN_U32_IBS: + case SKL_TKN_MM_U32_RES_PIN_ID: + case SKL_TKN_MM_U32_PIN_BUF: + ret = skl_tplg_fill_res_tkn(dev, tkn_elem, res, pin_idx, dir); + if (ret < 0) + return ret; + + break; + + case SKL_TKN_MM_U32_NUM_IN_FMT: + if (!fmt) + return -EINVAL; + + res->nr_input_pins = tkn_elem->value; + break; + + case SKL_TKN_MM_U32_NUM_OUT_FMT: + if (!fmt) + return -EINVAL; + + res->nr_output_pins = tkn_elem->value; + break; + + case SKL_TKN_U32_FMT_CH: + case SKL_TKN_U32_FMT_FREQ: + case SKL_TKN_U32_FMT_BIT_DEPTH: + case SKL_TKN_U32_FMT_SAMPLE_SIZE: + case SKL_TKN_U32_FMT_CH_CONFIG: + case SKL_TKN_U32_FMT_INTERLEAVE: + case SKL_TKN_U32_FMT_SAMPLE_TYPE: + case SKL_TKN_U32_FMT_CH_MAP: + case SKL_TKN_MM_U32_INTF_PIN_ID: + ret = skl_tplg_manifest_fill_fmt(dev, fmt, tkn_elem, + dir, pin_idx); + if (ret < 0) + return ret; break; default: dev_err(dev, "Not a manifest token %d\n", tkn_elem->token); return -EINVAL; } + tkn_count++; return tkn_count; } +static int skl_tplg_get_manifest_uuid(struct device *dev, + struct skl *skl, + struct snd_soc_tplg_vendor_uuid_elem *uuid_tkn) +{ + static int ref_count; + struct skl_module *mod; + + if (uuid_tkn->token == SKL_TKN_UUID) { + mod = skl->modules[ref_count]; + memcpy(&mod->uuid, &uuid_tkn->uuid, sizeof(uuid_tkn->uuid)); + ref_count++; + } else { + dev_err(dev, "Not an UUID token tkn %d\n", uuid_tkn->token); + return -EINVAL; + } + + return 0; +} + /* * Fill the manifest structure by parsing the tokens based on the * type. @@ -2686,7 +3209,11 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, continue; case SND_SOC_TPLG_TUPLE_TYPE_UUID: - dev_warn(dev, "no uuid tokens for skl tplf manifest\n"); + ret = skl_tplg_get_manifest_uuid(dev, skl, array->uuid); + if (ret < 0) + return ret; + + tuple_size += sizeof(*array->uuid); continue; default: @@ -2703,14 +3230,12 @@ static int skl_tplg_get_manifest_tkn(struct device *dev, tkn_count = tkn_count + ret; tkn_elem++; - tuple_size += tkn_count * - sizeof(struct snd_soc_tplg_vendor_value_elem); - break; } + tuple_size += (tkn_count * sizeof(*tkn_elem)); tkn_count = 0; } - return 0; + return off; } /* @@ -2733,11 +3258,10 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, num_blocks = ret; off += array->size; - array = (struct snd_soc_tplg_vendor_array *) - (manifest->priv.data + off); - /* Read the BLOCK_TYPE and BLOCK_SIZE descriptor */ while (num_blocks > 0) { + array = (struct snd_soc_tplg_vendor_array *) + (manifest->priv.data + off); ret = skl_tplg_get_desc_blocks(dev, array); if (ret < 0) @@ -2771,6 +3295,7 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest, } else { return -EINVAL; } + off += ret; } return 0; diff --git a/sound/soc/intel/skylake/skl-topology.h b/sound/soc/intel/skylake/skl-topology.h index c25e8868b84e..2717db92036b 100644 --- a/sound/soc/intel/skylake/skl-topology.h +++ b/sound/soc/intel/skylake/skl-topology.h @@ -44,6 +44,13 @@ #define SKL_DEFAULT_MIC_SEL_GAIN 0x3FF #define SKL_MIC_SEL_SWITCH 0x3 +#define SKL_OUTPUT_PIN 0 +#define SKL_INPUT_PIN 1 +#define SKL_MAX_PATH_CONFIGS 8 +#define SKL_MAX_MODULES_IN_PIPE 8 +#define SKL_MAX_MODULE_FORMATS 32 +#define SKL_MAX_MODULE_RESOURCES 32 + enum skl_channel_index { SKL_CHANNEL_LEFT = 0, SKL_CHANNEL_RIGHT = 1, @@ -131,6 +138,11 @@ struct skl_cpr_cfg { struct skl_cpr_gtw_cfg gtw_cfg; } __packed; +struct skl_cpr_pin_fmt { + u32 sink_id; + struct skl_audio_data_format src_fmt; + struct skl_audio_data_format dst_fmt; +} __packed; struct skl_src_module_cfg { struct skl_base_cfg base_cfg; @@ -214,6 +226,7 @@ struct skl_kpb_params { }; struct skl_module_inst_id { + uuid_le mod_uuid; int module_id; u32 instance_id; int pvt_id; @@ -266,6 +279,23 @@ struct skl_pipe_params { unsigned int link_bps; }; +struct skl_pipe_fmt { + u32 freq; + u8 channels; + u8 bps; +}; + +struct skl_pipe_mcfg { + u8 res_idx; + u8 fmt_idx; +}; + +struct skl_path_config { + u8 mem_pages; + struct skl_pipe_fmt in_fmt; + struct skl_pipe_fmt out_fmt; +}; + struct skl_pipe { u8 ppl_id; u8 pipe_priority; @@ -274,6 +304,10 @@ struct skl_pipe { u8 lp_mode; struct skl_pipe_params *p_params; enum skl_pipe_state state; + u8 direction; + u8 cur_config_idx; + u8 nr_cfgs; + struct skl_path_config configs[SKL_MAX_PATH_CONFIGS]; struct list_head w_list; bool passthru; }; @@ -292,9 +326,57 @@ enum d0i3_capability { SKL_D0I3_NON_STREAMING = 2, }; +struct skl_module_pin_fmt { + u8 id; + struct skl_module_fmt fmt; +}; + +struct skl_module_iface { + u8 fmt_idx; + u8 nr_in_fmt; + u8 nr_out_fmt; + struct skl_module_pin_fmt inputs[MAX_IN_QUEUE]; + struct skl_module_pin_fmt outputs[MAX_OUT_QUEUE]; +}; + +struct skl_module_pin_resources { + u8 pin_index; + u32 buf_size; +}; + +struct skl_module_res { + u8 id; + u32 is_pages; + u32 cps; + u32 ibs; + u32 obs; + u32 dma_buffer_size; + u32 cpc; + u8 nr_input_pins; + u8 nr_output_pins; + struct skl_module_pin_resources input[MAX_IN_QUEUE]; + struct skl_module_pin_resources output[MAX_OUT_QUEUE]; +}; + +struct skl_module { + uuid_le uuid; + u8 loadable; + u8 input_pin_type; + u8 output_pin_type; + u8 max_input_pins; + u8 max_output_pins; + u8 nr_resources; + u8 nr_interfaces; + struct skl_module_res resources[SKL_MAX_MODULE_RESOURCES]; + struct skl_module_iface formats[SKL_MAX_MODULE_FORMATS]; +}; + struct skl_module_cfg { u8 guid[16]; struct skl_module_inst_id id; + struct skl_module *module; + int res_idx; + int fmt_idx; u8 domain; bool homogenous_inputs; bool homogenous_outputs; @@ -329,6 +411,7 @@ struct skl_module_cfg { enum skl_module_state m_state; struct skl_pipe *pipe; struct skl_specific_cfg formats_config; + struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE]; }; struct skl_algo_data { diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 9e3f8c04dd32..f94b484abb99 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c @@ -415,7 +415,7 @@ static int skl_free(struct hdac_ext_bus *ebus) snd_hdac_ext_stop_streams(ebus); if (bus->irq >= 0) - free_irq(bus->irq, (void *)bus); + free_irq(bus->irq, (void *)ebus); snd_hdac_bus_free_stream_pages(bus); snd_hdac_stream_free_all(ebus); snd_hdac_link_free_all(ebus); @@ -528,7 +528,7 @@ static int probe_codec(struct hdac_ext_bus *ebus, int addr) } /* Codec initialization */ -static int skl_codec_create(struct hdac_ext_bus *ebus) +static void skl_codec_create(struct hdac_ext_bus *ebus) { struct hdac_bus *bus = ebus_to_hbus(ebus); int c, max_slots; @@ -559,8 +559,6 @@ static int skl_codec_create(struct hdac_ext_bus *ebus) } } } - - return 0; } static const struct hdac_bus_ops bus_core_ops = { @@ -612,9 +610,7 @@ static void skl_probe_work(struct work_struct *work) dev_info(bus->dev, "no hda codecs found!\n"); /* create codec instances */ - err = skl_codec_create(ebus); - if (err < 0) - goto out_err; + skl_codec_create(ebus); if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { err = snd_hdac_display_power(bus, false); @@ -702,6 +698,8 @@ static int skl_first_init(struct hdac_ext_bus *ebus) return -ENXIO; } + skl_init_chip(bus, true); + snd_hdac_bus_parse_capabilities(bus); if (skl_acquire_irq(ebus, 0) < 0) @@ -879,12 +877,12 @@ static void skl_remove(struct pci_dev *pci) static struct sst_codecs skl_codecs = { .num_codecs = 1, - .codecs = {"NAU88L25"} + .codecs = {"10508825"} }; static struct sst_codecs kbl_codecs = { .num_codecs = 1, - .codecs = {"NAU88L25"} + .codecs = {"10508825"} }; static struct sst_codecs bxt_codecs = { @@ -982,6 +980,11 @@ static struct sst_acpi_mach sst_kbl_devdata[] = { .quirk_data = &kbl_poppy_codecs, .pdata = &skl_dmic_data }, + { + .id = "10EC5663", + .drv_name = "kbl_rt5663", + .fw_filename = "intel/dsp_fw_kbl.bin", + }, {} }; @@ -995,6 +998,14 @@ static struct sst_acpi_mach sst_glk_devdata[] = { {} }; +static const struct sst_acpi_mach sst_cnl_devdata[] = { + { + .id = "INT34C2", + .drv_name = "cnl_rt274", + .fw_filename = "intel/dsp_fw_cnl.bin", + }, +}; + /* PCI IDs */ static const struct pci_device_id skl_ids[] = { /* Sunrise Point-LP */ @@ -1009,6 +1020,9 @@ static const struct pci_device_id skl_ids[] = { /* GLK */ { PCI_DEVICE(0x8086, 0x3198), .driver_data = (unsigned long)&sst_glk_devdata}, + /* CNL */ + { PCI_DEVICE(0x8086, 0x9dc8), + .driver_data = (unsigned long)&sst_cnl_devdata}, { 0, } }; MODULE_DEVICE_TABLE(pci, skl_ids); diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index a6b134b4c037..8d9d6899f761 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h @@ -71,6 +71,8 @@ struct skl { struct work_struct probe_work; struct skl_debug *debugfs; + u8 nr_modules; + struct skl_module **modules; }; #define skl_to_ebus(s) (&(s)->ebus) @@ -90,6 +92,7 @@ struct skl_machine_pdata { struct skl_dsp_ops { int id; + unsigned int num_cores; struct skl_dsp_loader_ops (*loader_ops)(void); int (*init)(struct device *dev, void __iomem *mmio_base, int irq, const char *fw_name, diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 794a3499e567..99394c036998 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -133,6 +133,7 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream, { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf, ctrl; + int ret; if (dai->active) return 0; @@ -141,7 +142,9 @@ static int jz4740_i2s_startup(struct snd_pcm_substream *substream, ctrl |= JZ_AIC_CTRL_FLUSH; jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); - clk_prepare_enable(i2s->clk_i2s); + ret = clk_prepare_enable(i2s->clk_i2s); + if (ret) + return ret; conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); conf |= JZ_AIC_CONF_ENABLE; @@ -352,11 +355,18 @@ static int jz4740_i2s_resume(struct snd_soc_dai *dai) { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf; + int ret; - clk_prepare_enable(i2s->clk_aic); + ret = clk_prepare_enable(i2s->clk_aic); + if (ret) + return ret; if (dai->active) { - clk_prepare_enable(i2s->clk_i2s); + ret = clk_prepare_enable(i2s->clk_i2s); + if (ret) { + clk_disable_unprepare(i2s->clk_aic); + return ret; + } conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); conf |= JZ_AIC_CONF_ENABLE; @@ -387,8 +397,11 @@ static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai) { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf; + int ret; - clk_prepare_enable(i2s->clk_aic); + ret = clk_prepare_enable(i2s->clk_aic); + if (ret) + return ret; jz4740_i2c_init_pcm_config(i2s); snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index dafd22e874e9..cf23af159acf 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -27,7 +27,7 @@ static struct kirkwood_dma_data *kirkwood_priv(struct snd_pcm_substream *subs) return snd_soc_dai_get_drvdata(soc_runtime->cpu_dai); } -static struct snd_pcm_hardware kirkwood_dma_snd_hw = { +static const struct snd_pcm_hardware kirkwood_dma_snd_hw = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 3a36d60e1785..105a73cc5158 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -538,10 +538,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) int err; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&pdev->dev, "allocation failed\n"); + if (!priv) return -ENOMEM; - } + dev_set_drvdata(&pdev->dev, priv); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -550,9 +549,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev) return PTR_ERR(priv->io); priv->irq = platform_get_irq(pdev, 0); - if (priv->irq <= 0) { - dev_err(&pdev->dev, "platform_get_irq failed\n"); - return -ENXIO; + if (priv->irq < 0) { + dev_err(&pdev->dev, "platform_get_irq failed: %d\n", priv->irq); + return priv->irq; } if (np) { diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c index b815ecc6bbf6..affa7fb25dd9 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c @@ -75,7 +75,7 @@ int mt2701_init_clock(struct mtk_base_afe *afe) for (i = 0; i < MT2701_CLOCK_NUM; i++) { afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); - if (IS_ERR(aud_clks[i])) { + if (IS_ERR(afe_priv->clocks[i])) { dev_warn(afe->dev, "%s devm_clk_get %s fail\n", __func__, aud_clks[i]); return PTR_ERR(aud_clks[i]); diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c index bc5d4db94de6..8fda182f849b 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c @@ -595,7 +595,7 @@ static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = { }; /* MRG BE DAIs */ -static struct snd_soc_dai_ops mt2701_btmrg_ops = { +static const struct snd_soc_dai_ops mt2701_btmrg_ops = { .startup = mt2701_btmrg_startup, .shutdown = mt2701_btmrg_shutdown, .hw_params = mt2701_btmrg_hw_params, @@ -1496,14 +1496,12 @@ static int mt2701_afe_runtime_resume(struct device *dev) static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) { - int ret, i; - unsigned int irq_id; struct mtk_base_afe *afe; struct mt2701_afe_private *afe_priv; struct resource *res; struct device *dev; + int i, irq_id, ret; - ret = 0; afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); if (!afe) return -ENOMEM; @@ -1516,11 +1514,12 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) afe->dev = &pdev->dev; dev = afe->dev; - irq_id = platform_get_irq(pdev, 0); - if (!irq_id) { - dev_err(dev, "%s no irq found\n", dev->of_node->name); - return -ENXIO; + irq_id = platform_get_irq_byname(pdev, "asys"); + if (irq_id < 0) { + dev_err(dev, "unable to get ASYS IRQ\n"); + return irq_id; } + ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); if (ret) { diff --git a/sound/soc/mediatek/mt8173/Makefile b/sound/soc/mediatek/mt8173/Makefile index 0357b27d29f2..c1eed0d2653b 100644 --- a/sound/soc/mediatek/mt8173/Makefile +++ b/sound/soc/mediatek/mt8173/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # MTK Platform Support obj-$(CONFIG_SND_SOC_MT8173) += mt8173-afe-pcm.o # Machine support diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c index 5e383eb456a4..99c15219dbc8 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c @@ -222,7 +222,6 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev) mt8173_rt5650_rt5514_codecs[1].of_node; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c index fed1f15a39c2..42de84ca8c84 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c @@ -279,7 +279,6 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) } card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c index a78470839b65..e69c141d8ed4 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c @@ -311,7 +311,6 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) return -EINVAL; } card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile index 565b5b51e8b7..ab0a9a553702 100644 --- a/sound/soc/mxs/Makefile +++ b/sound/soc/mxs/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # MXS Platform Support snd-soc-mxs-objs := mxs-saif.o snd-soc-mxs-pcm-objs := mxs-pcm.o diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index b42f301c6b96..156aa7c00787 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -125,7 +125,9 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, * * If MCLK is not used, we just set saif clk to 512*fs. */ - clk_prepare_enable(master_saif->clk); + ret = clk_prepare_enable(master_saif->clk); + if (ret) + return ret; if (master_saif->mclk_in_use) { switch (mclk / rate) { @@ -388,6 +390,7 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); + int ret; /* clear error status to 0 for each re-open */ saif->fifo_underrun = 0; @@ -401,7 +404,9 @@ static int mxs_saif_startup(struct snd_pcm_substream *substream, __raw_writel(BM_SAIF_CTRL_CLKGATE, saif->base + SAIF_CTRL + MXS_CLR_ADDR); - clk_prepare(saif->clk); + ret = clk_prepare(saif->clk); + if (ret) + return ret; return 0; } @@ -468,7 +473,9 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; - clk_prepare(master_saif->clk); + ret = clk_prepare(master_saif->clk); + if (ret) + return ret; } scr = __raw_readl(saif->base + SAIF_CTRL); diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index a96276e77332..2ed3240cc682 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -140,7 +140,6 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev) } card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) { diff --git a/sound/soc/nuc900/Makefile b/sound/soc/nuc900/Makefile index 7e46c7150316..c7ba2b9549d2 100644 --- a/sound/soc/nuc900/Makefile +++ b/sound/soc/nuc900/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # NUC900 series audio snd-soc-nuc900-pcm-objs := nuc900-pcm.o snd-soc-nuc900-ac97-objs := nuc900-ac97.o diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index 2cca055fd806..bd6dfa218d59 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c @@ -271,7 +271,7 @@ static int nuc900_dma_mmap(struct snd_pcm_substream *substream, runtime->dma_addr, runtime->dma_bytes); } -static struct snd_pcm_ops nuc900_dma_ops = { +static const struct snd_pcm_ops nuc900_dma_ops = { .open = nuc900_dma_open, .close = nuc900_dma_close, .ioctl = snd_pcm_lib_ioctl, @@ -299,7 +299,7 @@ static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static struct snd_soc_platform_driver nuc900_soc_platform = { +static const struct snd_soc_platform_driver nuc900_soc_platform = { .ops = &nuc900_dma_ops, .pcm_new = nuc900_dma_new, }; diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index db36fbd5d1a0..a6785dc4fc90 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # OMAP Platform Support snd-soc-omap-objs := omap-pcm.o snd-soc-omap-dmic-objs := omap-dmic.o diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 16cc95fa4573..6c49f3d6fd96 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -513,15 +513,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int ams_delta_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&ams_delta_hook_switch, - ARRAY_SIZE(ams_delta_hook_switch_gpios), - ams_delta_hook_switch_gpios); - - return 0; -} - /* DAI glue - connects codec <--> CPU */ static struct snd_soc_dai_link ams_delta_dai_link = { .name = "CX20442", @@ -540,7 +531,6 @@ static struct snd_soc_dai_link ams_delta_dai_link = { static struct snd_soc_card ams_delta_audio_card = { .name = "AMS_DELTA", .owner = THIS_MODULE, - .remove = ams_delta_card_remove, .dai_link = &ams_delta_dai_link, .num_links = 1, diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c index 888133f9e65d..3e9cc4842a1d 100644 --- a/sound/soc/omap/omap-hdmi-audio.c +++ b/sound/soc/omap/omap-hdmi-audio.c @@ -337,14 +337,11 @@ static int omap_hdmi_audio_probe(struct platform_device *pdev) ad->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; mutex_init(&ad->current_stream_lock); - switch (ha->dss_version) { - case OMAPDSS_VER_OMAP4430_ES1: - case OMAPDSS_VER_OMAP4430_ES2: - case OMAPDSS_VER_OMAP4: + switch (ha->version) { + case 4: dai_drv = &omap4_hdmi_dai; break; - case OMAPDSS_VER_OMAP5: - case OMAPDSS_VER_DRA7xx: + case 5: dai_drv = &omap5_hdmi_dai; break; default: diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 94e9ff791f3a..aca2c43d0f03 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -162,7 +162,7 @@ static int omap_pcm_mmap(struct snd_pcm_substream *substream, runtime->dma_addr, runtime->dma_bytes); } -static struct snd_pcm_ops omap_pcm_ops = { +static const struct snd_pcm_ops omap_pcm_ops = { .open = omap_pcm_open, .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, @@ -243,7 +243,7 @@ out: return ret; } -static struct snd_soc_platform_driver omap_soc_platform = { +static const struct snd_soc_platform_driver omap_soc_platform = { .ops = &omap_pcm_ops, .pcm_new = omap_pcm_new, .pcm_free = omap_pcm_free_dma_buffers, diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index a24b0dedabb9..cccc316743fa 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -208,18 +208,6 @@ static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) return ret; } -static int omap_twl4030_card_remove(struct snd_soc_card *card) -{ - struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); - - if (priv->jack_detect > 0) - snd_soc_jack_free_gpios(&priv->hs_jack, - ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return 0; -} - /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { { @@ -247,7 +235,6 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { /* Audio machine driver */ static struct snd_soc_card omap_twl4030_card = { .owner = THIS_MODULE, - .remove = omap_twl4030_card_remove, .dai_link = omap_twl4030_dai_links, .num_links = ARRAY_SIZE(omap_twl4030_dai_links), diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 3aeb65feaea1..57448bd5ad77 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -311,14 +311,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int rx51_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), - rx51_av_jack_gpios); - - return 0; -} - /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link rx51_dai[] = { { @@ -361,7 +353,6 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = { static struct snd_soc_card rx51_sound_card = { .name = "RX-51", .owner = THIS_MODULE, - .remove = rx51_card_remove, .dai_link = rx51_dai, .num_links = ARRAY_SIZE(rx51_dai), .aux_dev = rx51_aux_dev, diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index 2cff67b61dc3..5b265662f04f 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # PXA Platform Support snd-soc-pxa2xx-objs := pxa2xx-pcm.o snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index a9ac881c2e14..6cdef5d4954e 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c @@ -138,13 +138,6 @@ static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int hx4700_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&hs_jack, 1, &hs_jack_gpio); - - return 0; -} - /* hx4700 digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link hx4700_dai = { .name = "ak4641", @@ -163,7 +156,6 @@ static struct snd_soc_dai_link hx4700_dai = { static struct snd_soc_card snd_soc_card_hx4700 = { .name = "iPAQ hx4700", .owner = THIS_MODULE, - .remove = hx4700_card_remove, .dai_link = &hx4700_dai, .num_links = 1, .dapm_widgets = hx4700_dapm_widgets, diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c index 5b5f1a442891..624d9bd5dadd 100644 --- a/sound/soc/pxa/mmp-pcm.c +++ b/sound/soc/pxa/mmp-pcm.c @@ -131,7 +131,7 @@ static int mmp_pcm_mmap(struct snd_pcm_substream *substream, vma->vm_end - vma->vm_start, vma->vm_page_prot); } -static struct snd_pcm_ops mmp_pcm_ops = { +static const struct snd_pcm_ops mmp_pcm_ops = { .open = mmp_pcm_open, .close = snd_dmaengine_pcm_close_release_chan, .ioctl = snd_pcm_lib_ioctl, @@ -211,7 +211,7 @@ err: return ret; } -static struct snd_soc_platform_driver mmp_soc_platform = { +static const struct snd_soc_platform_driver mmp_soc_platform = { .ops = &mmp_pcm_ops, .pcm_new = mmp_pcm_new, .pcm_free = mmp_pcm_free_dma_buffers, diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c index 9cc35012e6e5..64b85e30c1f8 100644 --- a/sound/soc/pxa/mmp-sspa.c +++ b/sound/soc/pxa/mmp-sspa.c @@ -380,7 +380,7 @@ static int mmp_sspa_probe(struct snd_soc_dai *dai) SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops mmp_sspa_dai_ops = { +static const struct snd_soc_dai_ops mmp_sspa_dai_ops = { .startup = mmp_sspa_startup, .shutdown = mmp_sspa_shutdown, .trigger = mmp_sspa_trigger, diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index b51d7a0755d5..e64958d8bff0 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -45,7 +45,7 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops pxa2xx_pcm_ops = { +static const struct snd_pcm_ops pxa2xx_pcm_ops = { .open = __pxa2xx_pcm_open, .close = __pxa2xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -84,7 +84,7 @@ static int pxa2xx_soc_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } -static struct snd_soc_platform_driver pxa2xx_soc_platform = { +static const struct snd_soc_platform_driver pxa2xx_soc_platform = { .ops = &pxa2xx_pcm_ops, .pcm_new = pxa2xx_soc_pcm_new, .pcm_free = pxa2xx_pcm_free_dma_buffers, diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index 79e5c50a8f71..d5280355c24f 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Platform snd-soc-lpass-cpu-objs := lpass-cpu.o snd-soc-lpass-platform-objs := lpass-platform.o diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index d084d7468299..d49adc822a11 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c @@ -21,12 +21,16 @@ #include #include #include +#include #include +#include #include struct apq8016_sbc_data { void __iomem *mic_iomux; void __iomem *spkr_iomux; + struct snd_soc_jack jack; + bool jack_setup; struct snd_soc_dai_link dai_link[]; /* dynamically allocated */ }; @@ -34,13 +38,16 @@ struct apq8016_sbc_data { #define MIC_CTRL_QUA_WS_SLAVE_SEL_10 BIT(17) #define MIC_CTRL_TLMM_SCLK_EN BIT(1) #define SPKR_CTL_PRI_WS_SLAVE_SEL_11 (BIT(17) | BIT(16)) +#define DEFAULT_MCLK_RATE 9600000 static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_codec *codec; + struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_card *card = rtd->card; struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); - int rval = 0; + int i, rval; switch (cpu_dai->id) { case MI2S_PRIMARY: @@ -63,12 +70,54 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) default: dev_err(card->dev, "unsupported cpu dai configuration\n"); - rval = -EINVAL; - break; + return -EINVAL; } - return rval; + if (!pdata->jack_setup) { + struct snd_jack *jack; + + rval = snd_soc_card_jack_new(card, "Headset Jack", + SND_JACK_HEADSET | + SND_JACK_HEADPHONE | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | + SND_JACK_BTN_4, + &pdata->jack, NULL, 0); + + if (rval < 0) { + dev_err(card->dev, "Unable to add Headphone Jack\n"); + return rval; + } + + jack = pdata->jack.jack; + + snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_MEDIA); + snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + pdata->jack_setup = true; + } + + for (i = 0 ; i < dai_link->num_codecs; i++) { + struct snd_soc_dai *dai = rtd->codec_dais[i]; + + codec = dai->codec; + /* Set default mclk for internal codec */ + rval = snd_soc_codec_set_sysclk(codec, 0, 0, DEFAULT_MCLK_RATE, + SND_SOC_CLOCK_IN); + if (rval != 0 && rval != -ENOTSUPP) { + dev_warn(card->dev, "Failed to set mclk: %d\n", rval); + return rval; + } + rval = snd_soc_codec_set_jack(codec, &pdata->jack, NULL); + if (rval != 0 && rval != -ENOTSUPP) { + dev_warn(card->dev, "Failed to set jack: %d\n", rval); + return rval; + } + } + + return 0; } static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card) @@ -191,7 +240,6 @@ static int apq8016_sbc_platform_probe(struct platform_device *pdev) if (IS_ERR(data->spkr_iomux)) return PTR_ERR(data->spkr_iomux); - platform_set_drvdata(pdev, data); snd_soc_card_set_drvdata(card, data); return devm_snd_soc_register_card(&pdev->dev, card); diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c index 7aabf08de3d4..e1945e1772cd 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c @@ -32,7 +32,7 @@ struct lpass_pcm_data { #define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024) #define LPASS_PLATFORM_PERIODS 2 -static struct snd_pcm_hardware lpass_platform_pcm_hardware = { +static const struct snd_pcm_hardware lpass_platform_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | @@ -557,7 +557,7 @@ static void lpass_platform_pcm_free(struct snd_pcm *pcm) } } -static struct snd_soc_platform_driver lpass_platform_driver = { +static const struct snd_soc_platform_driver lpass_platform_driver = { .pcm_new = lpass_platform_pcm_new, .pcm_free = lpass_platform_pcm_free, .ops = &lpass_platform_pcm_ops, diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c index c5207af14104..a9fa972466ad 100644 --- a/sound/soc/qcom/storm.c +++ b/sound/soc/qcom/storm.c @@ -99,7 +99,6 @@ static int storm_platform_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); ret = snd_soc_of_parse_card_name(card, "qcom,model"); if (ret) { diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index c84487805876..b0825370d262 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -68,6 +68,8 @@ config SND_SOC_RK3399_GRU_SOUND select SND_SOC_RT5514 select SND_SOC_DA7219 select SND_SOC_RT5514_SPI + select SND_SOC_HDMI_CODEC + select SND_SOC_DMIC help Say Y or M here if you want to add support multiple codecs for SoC audio on Rockchip RK3399 GRU boards. diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile index 105f0e14a4ab..05b078e7b87f 100644 --- a/sound/soc/rockchip/Makefile +++ b/sound/soc/rockchip/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # ROCKCHIP Platform Support snd-soc-rockchip-i2s-objs := rockchip_i2s.o snd-soc-rockchip-pdm-objs := rockchip_pdm.o diff --git a/sound/soc/rockchip/rk3288_hdmi_analog.c b/sound/soc/rockchip/rk3288_hdmi_analog.c index dbc53e48c52c..fa44e3901336 100644 --- a/sound/soc/rockchip/rk3288_hdmi_analog.c +++ b/sound/soc/rockchip/rk3288_hdmi_analog.c @@ -147,7 +147,7 @@ static int rk_init(struct snd_soc_pcm_runtime *runtime) return 0; } -static struct snd_soc_ops rk_ops = { +static const struct snd_soc_ops rk_ops = { .hw_params = rk_hw_params, }; @@ -272,8 +272,6 @@ static int snd_rk_mc_probe(struct platform_device *pdev) return ret; } - platform_set_drvdata(pdev, card); - return ret; } diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index 3475c61a5fa0..0513fe480353 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c @@ -38,7 +38,7 @@ #define SOUND_FS 256 -static unsigned int rt5514_dmic_delay; +static unsigned int dmic_wakeup_delay; static struct snd_soc_jack rockchip_sound_jack; @@ -126,7 +126,7 @@ static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream, } /* Wait for DMIC stable */ - msleep(rt5514_dmic_delay); + msleep(dmic_wakeup_delay); return 0; } @@ -228,6 +228,67 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd) return 0; } +static int rockchip_sound_cdndp_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int mclk, ret; + + /* in bypass mode, the mclk has to be one of the frequencies below */ + switch (params_rate(params)) { + case 8000: + case 16000: + case 24000: + case 32000: + case 48000: + case 64000: + case 96000: + mclk = 12288000; + break; + case 11025: + case 22050: + case 44100: + case 88200: + mclk = 11289600; + break; + default: + return -EINVAL; + } + + ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, + SND_SOC_CLOCK_OUT); + if (ret < 0) { + dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret); + return ret; + } + + return 0; +} + +static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned int mclk; + int ret; + + mclk = params_rate(params) * SOUND_FS; + + ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0); + if (ret) { + dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n", + __func__, mclk, ret); + return ret; + } + + /* Wait for DMIC stable */ + msleep(dmic_wakeup_delay); + + return 0; +} + static const struct snd_soc_ops rockchip_sound_max98357a_ops = { .hw_params = rockchip_sound_max98357a_hw_params, }; @@ -240,16 +301,70 @@ static const struct snd_soc_ops rockchip_sound_da7219_ops = { .hw_params = rockchip_sound_da7219_hw_params, }; +static const struct snd_soc_ops rockchip_sound_cdndp_ops = { + .hw_params = rockchip_sound_cdndp_hw_params, +}; + +static const struct snd_soc_ops rockchip_sound_dmic_ops = { + .hw_params = rockchip_sound_dmic_hw_params, +}; + +static struct snd_soc_card rockchip_sound_card = { + .name = "rk3399-gru-sound", + .owner = THIS_MODULE, + .dapm_widgets = rockchip_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), + .dapm_routes = rockchip_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), + .controls = rockchip_controls, + .num_controls = ARRAY_SIZE(rockchip_controls), +}; + enum { + DAILINK_CDNDP, + DAILINK_DA7219, + DAILINK_DMIC, DAILINK_MAX98357A, DAILINK_RT5514, - DAILINK_DA7219, DAILINK_RT5514_DSP, }; -#define DAILINK_ENTITIES (DAILINK_DA7219 + 1) +static const char * const dailink_compat[] = { + [DAILINK_CDNDP] = "rockchip,rk3399-cdn-dp", + [DAILINK_DA7219] = "dlg,da7219", + [DAILINK_DMIC] = "dmic-codec", + [DAILINK_MAX98357A] = "maxim,max98357a", + [DAILINK_RT5514] = "realtek,rt5514-i2c", + [DAILINK_RT5514_DSP] = "realtek,rt5514-spi", +}; -static struct snd_soc_dai_link rockchip_dailinks[] = { +static const struct snd_soc_dai_link rockchip_dais[] = { + [DAILINK_CDNDP] = { + .name = "DP", + .stream_name = "DP PCM", + .codec_dai_name = "i2s-hifi", + .ops = &rockchip_sound_cdndp_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + }, + [DAILINK_DA7219] = { + .name = "DA7219", + .stream_name = "DA7219 PCM", + .codec_dai_name = "da7219-hifi", + .init = rockchip_sound_da7219_init, + .ops = &rockchip_sound_da7219_ops, + /* set da7219 as slave */ + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + }, + [DAILINK_DMIC] = { + .name = "DMIC", + .stream_name = "DMIC PCM", + .codec_dai_name = "dmic-hifi", + .ops = &rockchip_sound_dmic_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + }, [DAILINK_MAX98357A] = { .name = "MAX98357A", .stream_name = "MAX98357A PCM", @@ -268,108 +383,95 @@ static struct snd_soc_dai_link rockchip_dailinks[] = { .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, }, - [DAILINK_DA7219] = { - .name = "DA7219", - .stream_name = "DA7219 PCM", - .codec_dai_name = "da7219-hifi", - .init = rockchip_sound_da7219_init, - .ops = &rockchip_sound_da7219_ops, - /* set da7219 as slave */ - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - }, /* RT5514 DSP for voice wakeup via spi bus */ [DAILINK_RT5514_DSP] = { .name = "RT5514 DSP", .stream_name = "Wake on Voice", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", + .codec_dai_name = "rt5514-dsp-cpu-dai", }, }; -static struct snd_soc_card rockchip_sound_card = { - .name = "rk3399-gru-sound", - .owner = THIS_MODULE, - .dai_link = rockchip_dailinks, - .num_links = ARRAY_SIZE(rockchip_dailinks), - .dapm_widgets = rockchip_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets), - .dapm_routes = rockchip_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes), - .controls = rockchip_controls, - .num_controls = ARRAY_SIZE(rockchip_controls), -}; - -static int rockchip_sound_match_stub(struct device *dev, void *data) +static int rockchip_sound_codec_node_match(struct device_node *np_codec) { - return 1; + int i; + + for (i = 0; i < ARRAY_SIZE(dailink_compat); i++) { + if (of_device_is_compatible(np_codec, dailink_compat[i])) + return i; + } + return -1; +} + +static int rockchip_sound_of_parse_dais(struct device *dev, + struct snd_soc_card *card) +{ + struct device_node *np_cpu, *np_cpu0, *np_cpu1; + struct device_node *np_codec; + struct snd_soc_dai_link *dai; + int i, index; + + card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais), + GFP_KERNEL); + if (!card->dai_link) + return -ENOMEM; + + np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0); + np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1); + + card->num_links = 0; + for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) { + np_codec = of_parse_phandle(dev->of_node, + "rockchip,codec", i); + if (!np_codec) + break; + + if (!of_device_is_available(np_codec)) + continue; + + index = rockchip_sound_codec_node_match(np_codec); + if (index < 0) + continue; + + np_cpu = (index == DAILINK_CDNDP) ? np_cpu1 : np_cpu0; + if (!np_cpu) { + dev_err(dev, "Missing 'rockchip,cpu' for %s\n", + rockchip_dais[index].name); + return -EINVAL; + } + + dai = &card->dai_link[card->num_links++]; + *dai = rockchip_dais[index]; + + dai->codec_of_node = np_codec; + dai->platform_of_node = np_cpu; + dai->cpu_of_node = np_cpu; + } + + return 0; } static int rockchip_sound_probe(struct platform_device *pdev) { struct snd_soc_card *card = &rockchip_sound_card; - struct device_node *cpu_node; - struct device *dev; - struct device_driver *drv; - int i, ret; + int ret; - cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0); - if (!cpu_node) { - dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n"); - return -EINVAL; + ret = rockchip_sound_of_parse_dais(&pdev->dev, card); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret); + return ret; } - for (i = 0; i < DAILINK_ENTITIES; i++) { - rockchip_dailinks[i].platform_of_node = cpu_node; - rockchip_dailinks[i].cpu_of_node = cpu_node; - - rockchip_dailinks[i].codec_of_node = - of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i); - if (!rockchip_dailinks[i].codec_of_node) { - dev_err(&pdev->dev, - "Property[%d] 'rockchip,codec' missing or invalid\n", i); - return -EINVAL; - } - } - - /** - * To acquire the spi driver of the rt5514 and set the dai-links names - * for soc_bind_dai_link - */ - drv = driver_find("rt5514", &spi_bus_type); - if (!drv) { - dev_err(&pdev->dev, "Can not find the rt5514 driver at the spi bus\n"); - return -EINVAL; - } - - dev = driver_find_device(drv, NULL, NULL, rockchip_sound_match_stub); - if (!dev) { - dev_err(&pdev->dev, "Can not find the rt5514 device\n"); - return -ENODEV; - } - - /* Set DMIC delay */ - ret = device_property_read_u32(&pdev->dev, "dmic-delay", - &rt5514_dmic_delay); + /* Set DMIC wakeup delay */ + ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms", + &dmic_wakeup_delay); if (ret) { - rt5514_dmic_delay = 0; + dmic_wakeup_delay = 0; dev_dbg(&pdev->dev, - "no optional property 'dmic-delay' found, default: no delay\n"); + "no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n"); } - rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL); - rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL); - rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL); - card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", - __func__, ret); - - return ret; + return devm_snd_soc_register_card(&pdev->dev, card); } static const struct of_device_id rockchip_sound_of_match[] = { diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 199338fdeda0..b6590467fd14 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -579,10 +579,8 @@ static int rockchip_i2s_probe(struct platform_device *pdev) int val; i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); - if (!i2s) { - dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n"); + if (!i2s) return -ENOMEM; - } i2s->dev = &pdev->dev; diff --git a/sound/soc/rockchip/rockchip_pdm.c b/sound/soc/rockchip/rockchip_pdm.c index c5ddeed97260..400e29edb1c9 100644 --- a/sound/soc/rockchip/rockchip_pdm.c +++ b/sound/soc/rockchip/rockchip_pdm.c @@ -249,7 +249,7 @@ static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops rockchip_pdm_dai_ops = { +static const struct snd_soc_dai_ops rockchip_pdm_dai_ops = { .set_fmt = rockchip_pdm_set_fmt, .trigger = rockchip_pdm_trigger, .hw_params = rockchip_pdm_hw_params, diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index b6c2ee358333..030949e1e434 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # S3c24XX Platform Support snd-soc-s3c-dma-objs := dmaengine.o snd-soc-idma-objs := idma.o diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 5f5825faeb2a..051935162d7b 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -170,14 +170,6 @@ static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int h1940_uda1380_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - - return 0; -} - /* s3c24xx digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link h1940_uda1380_dai[] = { { @@ -197,7 +189,6 @@ static struct snd_soc_dai_link h1940_uda1380_dai[] = { static struct snd_soc_card h1940_asoc = { .name = "h1940", .owner = THIS_MODULE, - .remove = h1940_uda1380_card_remove, .dai_link = h1940_uda1380_dai, .num_links = ARRAY_SIZE(h1940_uda1380_dai), diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index af3ba4d4ccc5..10a4da06c0a1 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -50,6 +50,7 @@ struct samsung_i2s_variant_regs { struct samsung_i2s_dai_data { u32 quirks; + unsigned int pcm_rates; const struct samsung_i2s_variant_regs *i2s_variant_regs; }; @@ -550,7 +551,9 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, goto err; } - clk_prepare_enable(i2s->op_clk); + ret = clk_prepare_enable(i2s->op_clk); + if (ret) + goto err; i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); /* Over-ride the other's */ @@ -1076,13 +1079,13 @@ static const struct snd_soc_component_driver samsung_i2s_component = { .name = "samsung-i2s", }; -#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 - #define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) +static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, + const struct samsung_i2s_dai_data *i2s_dai_data, + bool sec) { struct i2s_dai *i2s; @@ -1101,13 +1104,13 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) i2s->i2s_dai_drv.resume = i2s_resume; i2s->i2s_dai_drv.playback.channels_min = 1; i2s->i2s_dai_drv.playback.channels_max = 2; - i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.playback.rates = i2s_dai_data->pcm_rates; i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; if (!sec) { i2s->i2s_dai_drv.capture.channels_min = 1; i2s->i2s_dai_drv.capture.channels_max = 2; - i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.capture.rates = i2s_dai_data->pcm_rates; i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; } return i2s; @@ -1132,10 +1135,19 @@ static int i2s_runtime_suspend(struct device *dev) static int i2s_runtime_resume(struct device *dev) { struct i2s_dai *i2s = dev_get_drvdata(dev); + int ret; - clk_prepare_enable(i2s->clk); - if (i2s->op_clk) - clk_prepare_enable(i2s->op_clk); + ret = clk_prepare_enable(i2s->clk); + if (ret) + return ret; + + if (i2s->op_clk) { + ret = clk_prepare_enable(i2s->op_clk); + if (ret) { + clk_disable_unprepare(i2s->clk); + return ret; + } + } writel(i2s->suspend_i2scon, i2s->addr + I2SCON); writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); @@ -1242,7 +1254,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) i2s_dai_data = (struct samsung_i2s_dai_data *) platform_get_device_id(pdev)->driver_data; - pri_dai = i2s_alloc_dai(pdev, false); + pri_dai = i2s_alloc_dai(pdev, i2s_dai_data, false); if (!pri_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); return -ENOMEM; @@ -1316,7 +1328,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) goto err_disable_clk; if (quirks & QUIRK_SEC_DAI) { - sec_dai = i2s_alloc_dai(pdev, true); + sec_dai = i2s_alloc_dai(pdev, i2s_dai_data, true); if (!sec_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); ret = -ENOMEM; @@ -1376,13 +1388,9 @@ err_disable_clk: static int samsung_i2s_remove(struct platform_device *pdev) { - struct i2s_dai *pri_dai, *sec_dai; + struct i2s_dai *pri_dai; pri_dai = dev_get_drvdata(&pdev->dev); - sec_dai = pri_dai->sec_dai; - - pri_dai->sec_dai = NULL; - sec_dai->pri_dai = NULL; pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1452,29 +1460,34 @@ static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = { static const struct samsung_i2s_dai_data i2sv3_dai_type = { .quirks = QUIRK_NO_MUXPSR, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv5_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_IDMA, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv3_regs, }; static const struct samsung_i2s_dai_data i2sv6_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv6_regs, }; static const struct samsung_i2s_dai_data i2sv7_dai_type = { .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | QUIRK_SUPPORTS_TDM, + .pcm_rates = SNDRV_PCM_RATE_8000_192000, .i2s_variant_regs = &i2sv7_regs, }; static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = { .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR, + .pcm_rates = SNDRV_PCM_RATE_8000_96000, .i2s_variant_regs = &i2sv5_i2s1_regs, }; diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 3e408158625d..a635df61f928 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -325,7 +325,7 @@ static int idma_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops idma_ops = { +static const struct snd_pcm_ops idma_ops = { .open = idma_open, .close = idma_close, .ioctl = snd_pcm_lib_ioctl, @@ -399,7 +399,7 @@ void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr) } EXPORT_SYMBOL_GPL(idma_reg_addr_init); -static struct snd_soc_platform_driver asoc_idma_platform = { +static const struct snd_soc_platform_driver asoc_idma_platform = { .ops = &idma_ops, .pcm_new = idma_new, .pcm_free = idma_free, diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 7fcb51faa2a0..529b10dc532b 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c @@ -79,7 +79,7 @@ static int jive_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops jive_ops = { +static const struct snd_soc_ops jive_ops = { .hw_params = jive_hw_params, }; diff --git a/sound/soc/samsung/odroid.c b/sound/soc/samsung/odroid.c index 0834319ead42..44b6de5a331a 100644 --- a/sound/soc/samsung/odroid.c +++ b/sound/soc/samsung/odroid.c @@ -19,8 +19,8 @@ struct odroid_priv { struct snd_soc_card card; struct snd_soc_dai_link dai_link; - struct clk *pll; - struct clk *rclk; + struct clk *clk_i2s_bus; + struct clk *sclk_i2s; }; static int odroid_card_startup(struct snd_pcm_substream *substream) @@ -58,13 +58,18 @@ static int odroid_card_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - ret = clk_set_rate(priv->pll, pll_freq + 1); + ret = clk_set_rate(priv->clk_i2s_bus, pll_freq / 2 + 1); if (ret < 0) return ret; - rclk_freq = params_rate(params) * 256 * 4; + /* + * We add 1 to the rclk_freq value in order to avoid too low clock + * frequency values due to the EPLL output frequency not being exact + * multiple of the audio sampling rate. + */ + rclk_freq = params_rate(params) * 256 + 1; - ret = clk_set_rate(priv->rclk, rclk_freq); + ret = clk_set_rate(priv->sclk_i2s, rclk_freq); if (ret < 0) return ret; @@ -118,14 +123,6 @@ static int odroid_audio_probe(struct platform_device *pdev) snd_soc_card_set_drvdata(card, priv); - priv->pll = devm_clk_get(dev, "epll"); - if (IS_ERR(priv->pll)) - return PTR_ERR(priv->pll); - - priv->rclk = devm_clk_get(dev, "i2s_rclk"); - if (IS_ERR(priv->rclk)) - return PTR_ERR(priv->rclk); - ret = snd_soc_of_parse_card_name(card, "model"); if (ret < 0) return ret; @@ -171,14 +168,31 @@ static int odroid_audio_probe(struct platform_device *pdev) link->name = "Primary"; link->stream_name = link->name; + + priv->sclk_i2s = of_clk_get_by_name(link->cpu_of_node, "i2s_opclk1"); + if (IS_ERR(priv->sclk_i2s)) { + ret = PTR_ERR(priv->sclk_i2s); + goto err_put_i2s_n; + } + + priv->clk_i2s_bus = of_clk_get_by_name(link->cpu_of_node, "iis"); + if (IS_ERR(priv->clk_i2s_bus)) { + ret = PTR_ERR(priv->clk_i2s_bus); + goto err_put_sclk; + } + ret = devm_snd_soc_register_card(dev, card); if (ret < 0) { dev_err(dev, "snd_soc_register_card() failed: %d\n", ret); - goto err_put_i2s_n; + goto err_put_clk_i2s; } return 0; +err_put_clk_i2s: + clk_put(priv->clk_i2s_bus); +err_put_sclk: + clk_put(priv->sclk_i2s); err_put_i2s_n: of_node_put(link->cpu_of_node); err_put_codec_n: @@ -192,6 +206,8 @@ static int odroid_audio_remove(struct platform_device *pdev) of_node_put(priv->dai_link.cpu_of_node); odroid_put_codec_of_nodes(&priv->dai_link); + clk_put(priv->sclk_i2s); + clk_put(priv->clk_i2s_bus); return 0; } diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index d50a6377c23d..37f95eee1558 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -522,7 +522,9 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to get audio-bus clock\n"); return PTR_ERR(pcm->cclk); } - clk_prepare_enable(pcm->cclk); + ret = clk_prepare_enable(pcm->cclk); + if (ret) + return ret; /* record our pcm structure for later use in the callbacks */ dev_set_drvdata(&pdev->dev, pcm); @@ -533,7 +535,9 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) ret = PTR_ERR(pcm->pclk); goto err_dis_cclk; } - clk_prepare_enable(pcm->pclk); + ret = clk_prepare_enable(pcm->pclk); + if (ret) + goto err_dis_cclk; s3c_pcm_stereo_in[pdev->id].addr = mem_res->start + S3C_PCM_RXFIFO; s3c_pcm_stereo_out[pdev->id].addr = mem_res->start + S3C_PCM_TXFIFO; diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index fa096abe9e75..a064ca7d78c3 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -31,7 +31,6 @@ #include "s3c24xx-i2s.h" static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd); -static int rx1950_uda1380_card_remove(struct snd_soc_card *card); static int rx1950_startup(struct snd_pcm_substream *substream); static int rx1950_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); @@ -118,7 +117,6 @@ static const struct snd_soc_dapm_route audio_map[] = { static struct snd_soc_card rx1950_asoc = { .name = "rx1950", .owner = THIS_MODULE, - .remove = rx1950_uda1380_card_remove, .dai_link = rx1950_uda1380_dai, .num_links = ARRAY_SIZE(rx1950_uda1380_dai), @@ -219,14 +217,6 @@ static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int rx1950_uda1380_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - - return 0; -} - static int __init rx1950_init(void) { int ret; diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 8f42deaa184b..58c3e9bfc6b7 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -27,7 +27,7 @@ #undef S3C_IIS_V2_SUPPORTED -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \ +#if defined(CONFIG_CPU_S3C2412) \ || defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_CPU_S5PV210) #define S3C_IIS_V2_SUPPORTED #endif @@ -634,11 +634,10 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai, i2s->iis_pclk = clk_get(dev, "iis"); if (IS_ERR(i2s->iis_pclk)) { dev_err(dev, "failed to get iis_clock\n"); - iounmap(i2s->regs); return -ENOENT; } - clk_enable(i2s->iis_pclk); + clk_prepare_enable(i2s->iis_pclk); /* Mark ourselves as in TXRX mode so we can run through our cleanup * process without warnings. */ @@ -652,6 +651,15 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai, } EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); +void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, + struct s3c_i2sv2_info *i2s) +{ + clk_disable_unprepare(i2s->iis_pclk); + clk_put(i2s->iis_pclk); + i2s->iis_pclk = NULL; +} +EXPORT_SYMBOL_GPL(s3c_i2sv2_cleanup); + #ifdef CONFIG_PM static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) { diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index 182d80564e37..3fca20f7a853 100644 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h @@ -91,6 +91,13 @@ extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, struct s3c_i2sv2_info *i2s, unsigned long base); +/** + * s3c_i2sv2_cleanup - cleanup resources allocated in s3c_i2sv2_probe + * @dai: The ASoC DAI structure supplied to the original probe. + * @i2s: Our local i2s structure to fill in. + */ +extern void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, + struct s3c_i2sv2_info *i2s); /** * s3c_i2sv2_register_component - register component and dai with soc core * @dev: DAI device diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 0a4718207e6e..cc0840fff5aa 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -65,26 +65,33 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk"); if (IS_ERR(s3c2412_i2s.iis_cclk)) { pr_err("failed to get i2sclk clock\n"); - return PTR_ERR(s3c2412_i2s.iis_cclk); + ret = PTR_ERR(s3c2412_i2s.iis_cclk); + goto err; } /* Set MPLL as the source for IIS CLK */ clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); - clk_prepare_enable(s3c2412_i2s.iis_cclk); - - s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; + ret = clk_prepare_enable(s3c2412_i2s.iis_cclk); + if (ret) + goto err; /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), S3C_GPIO_PULL_NONE); return 0; + +err: + s3c_i2sv2_cleanup(dai, &s3c2412_i2s); + + return ret; } static int s3c2412_i2s_remove(struct snd_soc_dai *dai) { clk_disable_unprepare(s3c2412_i2s.iis_cclk); + s3c_i2sv2_cleanup(dai, &s3c2412_i2s); return 0; } diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 91e6871e5413..8d58d02183bf 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -340,6 +340,7 @@ EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) { + int ret; snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, &s3c24xx_i2s_pcm_stereo_in); @@ -348,7 +349,9 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) pr_err("failed to get iis_clock\n"); return PTR_ERR(s3c24xx_i2s.iis_clk); } - clk_prepare_enable(s3c24xx_i2s.iis_clk); + ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); + if (ret) + return ret; /* Configure the I2S pins (GPE0...GPE4) in correct mode */ s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), @@ -377,7 +380,11 @@ static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) { - clk_prepare_enable(s3c24xx_i2s.iis_clk); + int ret; + + ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); + if (ret) + return ret; writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index dcc008d1e1ab..6de63f3e37d5 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c @@ -211,7 +211,7 @@ static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd) return 0; } -static struct snd_soc_ops simtec_snd_ops = { +static const struct snd_soc_ops simtec_snd_ops = { .hw_params = simtec_hw_params, }; diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 55538e333cc8..5fb3bab6bbfe 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -199,7 +199,7 @@ static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops s3c24xx_uda134x_ops = { +static const struct snd_soc_ops s3c24xx_uda134x_ops = { .startup = s3c24xx_uda134x_startup, .shutdown = s3c24xx_uda134x_shutdown, .hw_params = s3c24xx_uda134x_hw_params, @@ -237,7 +237,6 @@ static int s3c24xx_uda134x_probe(struct platform_device *pdev) mutex_init(&priv->clk_lock); card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, priv); ret = devm_snd_soc_register_card(&pdev->dev, card); diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index 425ee2ba37f0..cf0f54e652c1 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -160,14 +160,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int smartq_wm8987_card_remove(struct snd_soc_card *card) -{ - snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios), - smartq_jack_gpios); - - return 0; -} - static struct snd_soc_dai_link smartq_dai[] = { { .name = "wm8987", @@ -186,7 +178,6 @@ static struct snd_soc_dai_link smartq_dai[] = { static struct snd_soc_card snd_soc_smartq = { .name = "SmartQ", .owner = THIS_MODULE, - .remove = smartq_wm8987_card_remove, .dai_link = smartq_dai, .num_links = ARRAY_SIZE(smartq_dai), diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index a2f2363fe1c2..7fc7cc6d1530 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -144,7 +144,7 @@ static int smdk_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_ops smdk_spdif_ops = { +static const struct snd_soc_ops smdk_spdif_ops = { .hw_params = smdk_hw_params, }; diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 779504f54bc0..cb59911e65c0 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -391,7 +391,9 @@ static int spdif_probe(struct platform_device *pdev) ret = -ENOENT; goto err0; } - clk_prepare_enable(spdif->pclk); + ret = clk_prepare_enable(spdif->pclk); + if (ret) + goto err0; spdif->sclk = devm_clk_get(&pdev->dev, "sclk_spdif"); if (IS_ERR(spdif->sclk)) { @@ -399,7 +401,9 @@ static int spdif_probe(struct platform_device *pdev) ret = -ENOENT; goto err1; } - clk_prepare_enable(spdif->sclk); + ret = clk_prepare_enable(spdif->sclk); + if (ret) + goto err1; /* Request S/PDIF Register's memory region */ if (!request_mem_region(mem_res->start, diff --git a/sound/soc/samsung/tm2_wm5110.c b/sound/soc/samsung/tm2_wm5110.c index 24cc9d63ce87..68698f3d72f9 100644 --- a/sound/soc/samsung/tm2_wm5110.c +++ b/sound/soc/samsung/tm2_wm5110.c @@ -318,7 +318,7 @@ static const struct snd_kcontrol_new tm2_controls[] = { SOC_DAPM_PIN_SWITCH("Headset Mic"), }; -const struct snd_soc_dapm_widget tm2_dapm_widgets[] = { +static const struct snd_soc_dapm_widget tm2_dapm_widgets[] = { SND_SOC_DAPM_HP("HP", NULL), SND_SOC_DAPM_SPK("SPK", NULL), SND_SOC_DAPM_SPK("RCV", NULL), @@ -521,7 +521,7 @@ static void tm2_pm_complete(struct device *dev) tm2_start_sysclk(card); } -const struct dev_pm_ops tm2_pm_ops = { +static const struct dev_pm_ops tm2_pm_ops = { .prepare = tm2_pm_prepare, .suspend = snd_soc_suspend, .resume = snd_soc_resume, diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile index aaf3dcd1ee2a..51bd7c81671c 100644 --- a/sound/soc/sh/Makefile +++ b/sound/soc/sh/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ## DMA engines snd-soc-dma-sh7760-objs := dma-sh7760.o obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 8fad4441c87d..1e7d417b53ef 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -89,7 +89,7 @@ struct camelot_pcm { #define DMABRG_PREALLOC_BUFFER 32 * 1024 #define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 -static struct snd_pcm_hardware camelot_pcm_hardware = { +static const struct snd_pcm_hardware camelot_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -294,7 +294,7 @@ static snd_pcm_uframes_t camelot_pos(struct snd_pcm_substream *substream) return bytes_to_frames(runtime, pos); } -static struct snd_pcm_ops camelot_pcm_ops = { +static const struct snd_pcm_ops camelot_pcm_ops = { .open = camelot_pcm_open, .close = camelot_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -320,7 +320,7 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static struct snd_soc_platform_driver sh7760_soc_platform = { +static const struct snd_soc_platform_driver sh7760_soc_platform = { .ops = &camelot_pcm_ops, .pcm_new = camelot_pcm_new, }; diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 7c4bdd82bb95..6d3c7706d93f 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1710,7 +1710,7 @@ static const struct snd_soc_dai_ops fsi_dai_ops = { * pcm ops */ -static struct snd_pcm_hardware fsi_pcm_hardware = { +static const struct snd_pcm_hardware fsi_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID, @@ -1755,7 +1755,7 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) return fsi_sample2frame(fsi, io->buff_sample_pos); } -static struct snd_pcm_ops fsi_pcm_ops = { +static const struct snd_pcm_ops fsi_pcm_ops = { .open = fsi_pcm_open, .ioctl = snd_pcm_lib_ioctl, .hw_params = fsi_hw_params, @@ -1818,7 +1818,7 @@ static struct snd_soc_dai_driver fsi_soc_dai[] = { }, }; -static struct snd_soc_platform_driver fsi_soc_platform = { +static const struct snd_soc_platform_driver fsi_soc_platform = { .ops = &fsi_pcm_ops, .pcm_new = fsi_pcm_new, }; @@ -1962,10 +1962,8 @@ static int fsi_probe(struct platform_device *pdev) } master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL); - if (!master) { - dev_err(&pdev->dev, "Could not allocate master\n"); + if (!master) return -ENOMEM; - } master->base = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); @@ -2109,7 +2107,7 @@ static int fsi_resume(struct device *dev) return 0; } -static struct dev_pm_ops fsi_pm_ops = { +static const struct dev_pm_ops fsi_pm_ops = { .suspend = fsi_suspend, .resume = fsi_resume, }; diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index 672bcd4c252b..ecb057ff9fbb 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -98,7 +98,7 @@ static int migor_hw_free(struct snd_pcm_substream *substream) return 0; } -static struct snd_soc_ops migor_dai_ops = { +static const struct snd_soc_ops migor_dai_ops = { .hw_params = migor_hw_params, .hw_free = migor_hw_free, }; diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 197cb3ec075f..938baff86ef2 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c @@ -586,10 +586,8 @@ int rsnd_adg_probe(struct rsnd_priv *priv) int ret; adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); - if (!adg) { - dev_err(dev, "ADG allocate failed\n"); + if (!adg) return -ENOMEM; - } ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, NULL, NULL, 0, 0); @@ -610,6 +608,13 @@ void rsnd_adg_remove(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct device_node *np = dev->of_node; + struct rsnd_adg *adg = priv->adg; + struct clk *clk; + int i; + + for_each_rsnd_clkout(clk, adg, i) + if (adg->clkout[i]) + clk_unregister_fixed_rate(adg->clkout[i]); of_clk_del_provider(np); diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 3f2ced26ed37..107133297e8d 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -726,7 +726,6 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, case 2: case 6: case 8: - case 16: /* TDM Extend Mode */ rsnd_rdai_channels_set(rdai, slots); rsnd_rdai_ssi_lane_set(rdai, 1); @@ -740,7 +739,7 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, } static unsigned int rsnd_soc_hw_channels_list[] = { - 2, 6, 8, 16, + 2, 6, 8, }; static unsigned int rsnd_soc_hw_rate_list[] = { @@ -844,12 +843,28 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, ir, &ic); } -static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime, - struct snd_soc_dai *dai) +static const struct snd_pcm_hardware rsnd_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID, + .buffer_bytes_max = 64 * 1024, + .period_bytes_min = 32, + .period_bytes_max = 8192, + .periods_min = 1, + .periods_max = 32, + .fifo_size = 256, +}; + +static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); + struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); struct snd_pcm_hw_constraint_list *constraint = &rdai->constraint; + struct snd_pcm_runtime *runtime = substream->runtime; unsigned int max_channels = rsnd_rdai_channels_get(rdai); + int ret; int i; /* @@ -866,34 +881,26 @@ static void rsnd_soc_hw_constraint(struct snd_pcm_runtime *runtime, constraint->count = i + 1; } + snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware); + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, constraint); + snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + /* * Sampling Rate / Channel Limitation * It depends on Clock Master Mode */ - if (!rsnd_rdai_is_clk_master(rdai)) - return; - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - rsnd_soc_hw_rule_rate, dai, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - rsnd_soc_hw_rule_channels, dai, - SNDRV_PCM_HW_PARAM_RATE, -1); -} - -static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); - struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); - struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); - int ret; - - /* rsnd_io_to_runtime() is not yet enabled here */ - rsnd_soc_hw_constraint(substream->runtime, dai); + if (rsnd_rdai_is_clk_master(rdai)) { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + rsnd_soc_hw_rule_rate, dai, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + rsnd_soc_hw_rule_channels, dai, + SNDRV_PCM_HW_PARAM_RATE, -1); + } /* * call rsnd_dai_call without spinlock @@ -1017,7 +1024,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, drv->playback.rates = RSND_RATES; drv->playback.formats = RSND_FMTS; drv->playback.channels_min = 2; - drv->playback.channels_max = 16; + drv->playback.channels_max = 8; drv->playback.stream_name = rdai->playback.name; snprintf(rdai->capture.name, RSND_DAI_NAME_SIZE, @@ -1025,7 +1032,7 @@ static void __rsnd_dai_probe(struct rsnd_priv *priv, drv->capture.rates = RSND_RATES; drv->capture.formats = RSND_FMTS; drv->capture.channels_min = 2; - drv->capture.channels_max = 16; + drv->capture.channels_max = 8; drv->capture.stream_name = rdai->capture.name; rdai->playback.rdai = rdai; @@ -1105,31 +1112,6 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) /* * pcm ops */ -static struct snd_pcm_hardware rsnd_pcm_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID, - .buffer_bytes_max = 64 * 1024, - .period_bytes_min = 32, - .period_bytes_max = 8192, - .periods_min = 1, - .periods_max = 32, - .fifo_size = 256, -}; - -static int rsnd_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - int ret = 0; - - snd_soc_set_runtime_hwparams(substream, &rsnd_pcm_hardware); - - ret = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - - return ret; -} - static int rsnd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { @@ -1158,8 +1140,7 @@ static snd_pcm_uframes_t rsnd_pointer(struct snd_pcm_substream *substream) return pointer; } -static struct snd_pcm_ops rsnd_pcm_ops = { - .open = rsnd_pcm_open, +static const struct snd_pcm_ops rsnd_pcm_ops = { .ioctl = snd_pcm_lib_ioctl, .hw_params = rsnd_hw_params, .hw_free = snd_pcm_lib_free_pages, @@ -1169,11 +1150,10 @@ static struct snd_pcm_ops rsnd_pcm_ops = { /* * snd_kcontrol */ -#define kcontrol_to_cfg(kctrl) ((struct rsnd_kctrl_cfg *)kctrl->private_value) static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) { - struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl); if (cfg->texts) { uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -1199,7 +1179,7 @@ static int rsnd_kctrl_info(struct snd_kcontrol *kctrl, static int rsnd_kctrl_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc) { - struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl); int i; for (i = 0; i < cfg->size; i++) @@ -1214,8 +1194,7 @@ static int rsnd_kctrl_get(struct snd_kcontrol *kctrl, static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uc) { - struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); - struct rsnd_kctrl_cfg *cfg = kcontrol_to_cfg(kctrl); + struct rsnd_kctrl_cfg *cfg = snd_kcontrol_chip(kctrl); int i, change = 0; if (!cfg->accept(cfg->io)) @@ -1232,7 +1211,7 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, } if (change && cfg->update) - cfg->update(cfg->io, mod); + cfg->update(cfg->io, cfg->mod); return change; } @@ -1284,14 +1263,13 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, .index = rtd->num, .get = rsnd_kctrl_get, .put = rsnd_kctrl_put, - .private_value = (unsigned long)cfg, }; int ret; if (size > RSND_MAX_CHANNELS) return -EINVAL; - kctrl = snd_ctl_new1(&knew, mod); + kctrl = snd_ctl_new1(&knew, cfg); if (!kctrl) return -ENOMEM; @@ -1307,6 +1285,7 @@ int rsnd_kctrl_new(struct rsnd_mod *mod, cfg->card = card; cfg->kctrl = kctrl; cfg->io = io; + cfg->mod = mod; return 0; } @@ -1339,7 +1318,7 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); } -static struct snd_soc_platform_driver rsnd_soc_platform = { +static const struct snd_soc_platform_driver rsnd_soc_platform = { .ops = &rsnd_pcm_ops, .pcm_new = rsnd_pcm_new, }; @@ -1422,10 +1401,8 @@ static int rsnd_probe(struct platform_device *pdev) * init priv data */ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(dev, "priv allocate failed\n"); + if (!priv) return -ENODEV; - } priv->pdev = pdev; priv->flags = (unsigned long)of_device_get_match_data(dev); diff --git a/sound/soc/sh/rcar/ctu.c b/sound/soc/sh/rcar/ctu.c index 4ba8f2fe7a4c..e7f53f44165d 100644 --- a/sound/soc/sh/rcar/ctu.c +++ b/sound/soc/sh/rcar/ctu.c @@ -394,13 +394,16 @@ int rsnd_ctu_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_ctu_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(ctu), &rsnd_ctu_ops, clk, rsnd_mod_get_status, RSND_MOD_CTU, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_ctu_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 60aa5e96a49f..041ec1080d52 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -604,8 +604,8 @@ rsnd_gen2_dma_addr(struct rsnd_dai_stream *io, dma_addr_t in_addr; } dma_addrs[3][2][3] = { /* SRC */ + /* Capture */ {{{ 0, 0 }, - /* Capture */ { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, /* Playback */ diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 99d2d9459e75..1743ade3cc55 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c @@ -380,13 +380,16 @@ int rsnd_dvc_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_dvc_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops, clk, rsnd_mod_get_status, RSND_MOD_DVC, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_dvc_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index ee00e3516911..f04c4100043a 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@ -406,10 +406,8 @@ int rsnd_gen_probe(struct rsnd_priv *priv) int ret; gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); - if (!gen) { - dev_err(dev, "GEN allocate failed\n"); + if (!gen) return -ENOMEM; - } priv->gen = gen; diff --git a/sound/soc/sh/rcar/mix.c b/sound/soc/sh/rcar/mix.c index 195fc7bb22af..6c4826c189a4 100644 --- a/sound/soc/sh/rcar/mix.c +++ b/sound/soc/sh/rcar/mix.c @@ -168,13 +168,16 @@ int rsnd_mix_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_mix_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops, clk, rsnd_mod_get_status, RSND_MOD_MIX, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_mix_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 99c57611df88..c5de71f2dc8c 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -614,6 +614,7 @@ struct rsnd_kctrl_cfg { struct rsnd_dai_stream *io; struct snd_card *card; struct snd_kcontrol *kctrl; + struct rsnd_mod *mod; }; #define RSND_MAX_CHANNELS 8 diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 7aa239e28491..510b68a483b4 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -27,7 +27,6 @@ struct rsnd_src { #define RSND_SRC_NAME_SIZE 16 #define rsnd_src_get(priv, id) ((struct rsnd_src *)(priv->src) + id) -#define rsnd_src_to_dma(src) ((src)->dma) #define rsnd_src_nr(priv) ((priv)->src_nr) #define rsnd_src_sync_is_enabled(mod) (rsnd_mod_to_src(mod)->sen.val) @@ -108,7 +107,6 @@ unsigned int rsnd_src_get_rate(struct rsnd_priv *priv, int is_play = rsnd_io_is_play(io); /* - * * Playback * runtime_rate -> [SRC] -> convert_rate * @@ -203,13 +201,13 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, use_src = (fin != fout) | rsnd_src_sync_is_enabled(mod); /* - * SRC_ADINR + * SRC_ADINR */ adinr = rsnd_get_adinr_bit(mod, io) | rsnd_runtime_channel_original(io); /* - * SRC_IFSCR / SRC_IFSVR + * SRC_IFSCR / SRC_IFSVR */ ifscr = 0; fsrate = 0; @@ -223,7 +221,7 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, } /* - * SRC_SRCCR / SRC_ROUTE_MODE0 + * SRC_SRCCR / SRC_ROUTE_MODE0 */ cr = 0x00011110; route = 0x0; @@ -581,20 +579,24 @@ int rsnd_src_probe(struct rsnd_priv *priv) src->irq = irq_of_parse_and_map(np, 0); if (!src->irq) { ret = -EINVAL; + of_node_put(np); goto rsnd_src_probe_done; } clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_src_probe_done; } ret = rsnd_mod_init(priv, rsnd_mod_get(src), &rsnd_src_ops, clk, rsnd_mod_get_status, RSND_MOD_SRC, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_src_probe_done; + } skip: i++; diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 46feddd78ee2..fffc07e72627 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -72,6 +72,7 @@ struct rsnd_ssi { u32 cr_own; u32 cr_clk; u32 cr_mode; + u32 cr_en; u32 wsr; int chan; int rate; @@ -89,6 +90,7 @@ struct rsnd_ssi { #define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */ #define RSND_SSI_HDMI0 (1 << 2) /* for HDMI0 */ #define RSND_SSI_HDMI1 (1 << 3) /* for HDMI1 */ +#define RSND_SSI_PROBED (1 << 4) #define for_each_rsnd_ssi(pos, priv, i) \ for (i = 0; \ @@ -97,25 +99,27 @@ struct rsnd_ssi { i++) #define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id) -#define rsnd_ssi_to_dma(mod) ((ssi)->dma) #define rsnd_ssi_nr(priv) ((priv)->ssi_nr) #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) -#define rsnd_ssi_mode_flags(p) ((p)->flags) +#define rsnd_ssi_flags_has(p, f) ((p)->flags & f) +#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f) +#define rsnd_ssi_flags_del(p, f) ((p)->flags = ((p)->flags & ~f)) #define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) #define rsnd_ssi_is_multi_slave(mod, io) \ (rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod))) #define rsnd_ssi_is_run_mods(mod, io) \ (rsnd_ssi_run_mods(io) & (1 << rsnd_mod_id(mod))) +#define rsnd_ssi_can_output_clk(mod) (!__rsnd_ssi_is_pin_sharing(mod)) int rsnd_ssi_hdmi_port(struct rsnd_dai_stream *io) { struct rsnd_mod *mod = rsnd_io_to_mod_ssi(io); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI0) + if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI0)) return RSND_SSI_HDMI_PORT0; - if (rsnd_ssi_mode_flags(ssi) & RSND_SSI_HDMI1) + if (rsnd_ssi_flags_has(ssi, RSND_SSI_HDMI1)) return RSND_SSI_HDMI_PORT1; return 0; @@ -130,7 +134,7 @@ int rsnd_ssi_use_busif(struct rsnd_dai_stream *io) if (!rsnd_ssi_is_dma_mode(mod)) return 0; - if (!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_NO_BUSIF)) + if (!(rsnd_ssi_flags_has(ssi, RSND_SSI_NO_BUSIF))) use_busif = 1; if (rsnd_io_to_mod_src(io)) use_busif = 1; @@ -255,7 +259,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); int chan = rsnd_runtime_channel_for_ssi(io); int idx, ret; unsigned int main_rate; @@ -266,7 +269,7 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, if (!rsnd_rdai_is_clk_master(rdai)) return 0; - if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) + if (!rsnd_ssi_can_output_clk(mod)) return 0; if (rsnd_ssi_is_multi_slave(mod, io)) @@ -291,6 +294,16 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, if (ret < 0) return ret; + /* + * SSI clock will be output contiguously + * by below settings. + * This means, rsnd_ssi_master_clk_start() + * and rsnd_ssi_register_setup() are necessary + * for SSI parent + * + * SSICR : FORCE, SCKD, SWSD + * SSIWSR : CONT + */ ssi->cr_clk = FORCE | SWL_32 | SCKD | SWSD | CKDV(idx); ssi->wsr = CONT; ssi->rate = rate; @@ -307,12 +320,11 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod, { struct rsnd_dai *rdai = rsnd_io_to_rdai(io); struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); if (!rsnd_rdai_is_clk_master(rdai)) return; - if (ssi_parent_mod && !rsnd_ssi_is_parent(mod, io)) + if (!rsnd_ssi_can_output_clk(mod)) return; if (ssi->usrcnt > 1) @@ -335,6 +347,9 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod, u32 wsr; int is_tdm; + if (rsnd_ssi_is_parent(mod, io)) + return; + is_tdm = rsnd_runtime_is_ssi_tdm(io); /* @@ -393,7 +408,8 @@ static void rsnd_ssi_register_setup(struct rsnd_mod *mod) rsnd_mod_write(mod, SSIWSR, ssi->wsr); rsnd_mod_write(mod, SSICR, ssi->cr_own | ssi->cr_clk | - ssi->cr_mode); /* without EN */ + ssi->cr_mode | + ssi->cr_en); } static void rsnd_ssi_pointer_init(struct rsnd_mod *mod, @@ -472,8 +488,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, if (ret < 0) return ret; - if (!rsnd_ssi_is_parent(mod, io)) - rsnd_ssi_config_init(mod, io); + rsnd_ssi_config_init(mod, io); rsnd_ssi_register_setup(mod); @@ -544,6 +559,8 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) { + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + if (!rsnd_ssi_is_run_mods(mod, io)) return 0; @@ -554,7 +571,19 @@ static int rsnd_ssi_start(struct rsnd_mod *mod, if (rsnd_ssi_multi_slaves_runtime(io)) return 0; - rsnd_mod_bset(mod, SSICR, EN, EN); + /* + * EN is for data output. + * SSI parent EN is not needed. + */ + if (rsnd_ssi_is_parent(mod, io)) + return 0; + + ssi->cr_en = EN; + + rsnd_mod_write(mod, SSICR, ssi->cr_own | + ssi->cr_clk | + ssi->cr_mode | + ssi->cr_en); return 0; } @@ -569,13 +598,7 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, if (!rsnd_ssi_is_run_mods(mod, io)) return 0; - /* - * don't stop if not last user - * see also - * rsnd_ssi_start - * rsnd_ssi_interrupt - */ - if (ssi->usrcnt > 1) + if (rsnd_ssi_is_parent(mod, io)) return 0; /* @@ -595,6 +618,8 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, rsnd_mod_write(mod, SSICR, cr); /* disabled all */ rsnd_ssi_status_check(mod, IIRQ); + ssi->cr_en = 0; + return 0; } @@ -760,15 +785,47 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod, /* * SSI might be called again as PIO fallback * It is easy to manual handling for IRQ request/free + * + * OTOH, this function might be called many times if platform is + * using MIX. It needs xxx_attach() many times on xxx_probe(). + * Because of it, we can't control .probe/.remove calling count by + * mod->status. + * But it don't need to call request_irq() many times. + * Let's control it by RSND_SSI_PROBED flag. */ - ret = request_irq(ssi->irq, - rsnd_ssi_interrupt, - IRQF_SHARED, - dev_name(dev), mod); + if (!rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) { + ret = request_irq(ssi->irq, + rsnd_ssi_interrupt, + IRQF_SHARED, + dev_name(dev), mod); + + rsnd_ssi_flags_set(ssi, RSND_SSI_PROBED); + } return ret; } +static int rsnd_ssi_common_remove(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + struct rsnd_priv *priv) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io); + + /* Do nothing if non SSI (= SSI parent, multi SSI) mod */ + if (pure_ssi_mod != mod) + return 0; + + /* PIO will request IRQ again */ + if (rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) { + free_irq(ssi->irq, mod); + + rsnd_ssi_flags_del(ssi, RSND_SSI_PROBED); + } + + return 0; +} + static int rsnd_ssi_pointer(struct rsnd_mod *mod, struct rsnd_dai_stream *io, snd_pcm_uframes_t *pointer) @@ -784,6 +841,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod, static struct rsnd_mod_ops rsnd_ssi_pio_ops = { .name = SSI_NAME, .probe = rsnd_ssi_common_probe, + .remove = rsnd_ssi_common_remove, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, .start = rsnd_ssi_start, @@ -818,23 +876,6 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, return ret; } -static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, - struct rsnd_dai_stream *io, - struct rsnd_priv *priv) -{ - struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - struct rsnd_mod *ssi_parent_mod = rsnd_io_to_mod_ssip(io); - - /* Do nothing for SSI parent mod */ - if (ssi_parent_mod == mod) - return 0; - - /* PIO will request IRQ again */ - free_irq(ssi->irq, mod); - - return 0; -} - static int rsnd_ssi_fallback(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct rsnd_priv *priv) @@ -876,7 +917,7 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = { .name = SSI_NAME, .dma_req = rsnd_ssi_dma_req, .probe = rsnd_ssi_dma_probe, - .remove = rsnd_ssi_dma_remove, + .remove = rsnd_ssi_common_remove, .init = rsnd_ssi_init, .quit = rsnd_ssi_quit, .start = rsnd_ssi_start, @@ -962,13 +1003,13 @@ static void __rsnd_ssi_parse_hdmi_connection(struct rsnd_priv *priv, ssi = rsnd_mod_to_ssi(mod); if (strstr(remote_ep->full_name, "hdmi0")) { - ssi->flags |= RSND_SSI_HDMI0; + rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI0); dev_dbg(dev, "%s[%d] connected to HDMI0\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); } if (strstr(remote_ep->full_name, "hdmi1")) { - ssi->flags |= RSND_SSI_HDMI1; + rsnd_ssi_flags_set(ssi, RSND_SSI_HDMI1); dev_dbg(dev, "%s[%d] connected to HDMI1\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); } @@ -1001,7 +1042,7 @@ int __rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) { struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); - return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); + return !!(rsnd_ssi_flags_has(ssi, RSND_SSI_CLK_PIN_SHARE)); } static u32 *rsnd_ssi_get_status(struct rsnd_dai_stream *io, @@ -1079,18 +1120,20 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) clk = devm_clk_get(dev, name); if (IS_ERR(clk)) { ret = PTR_ERR(clk); + of_node_put(np); goto rsnd_ssi_probe_done; } if (of_get_property(np, "shared-pin", NULL)) - ssi->flags |= RSND_SSI_CLK_PIN_SHARE; + rsnd_ssi_flags_set(ssi, RSND_SSI_CLK_PIN_SHARE); if (of_get_property(np, "no-busif", NULL)) - ssi->flags |= RSND_SSI_NO_BUSIF; + rsnd_ssi_flags_set(ssi, RSND_SSI_NO_BUSIF); ssi->irq = irq_of_parse_and_map(np, 0); if (!ssi->irq) { ret = -EINVAL; + of_node_put(np); goto rsnd_ssi_probe_done; } @@ -1101,8 +1144,10 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) ret = rsnd_mod_init(priv, rsnd_mod_get(ssi), ops, clk, rsnd_ssi_get_status, RSND_MOD_SSI, i); - if (ret) + if (ret) { + of_node_put(np); goto rsnd_ssi_probe_done; + } i++; } diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index bed2c9c0004b..4d948757d300 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -250,7 +250,7 @@ int rsnd_ssiu_probe(struct rsnd_priv *priv) { struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_ssiu *ssiu; - static struct rsnd_mod_ops *ops; + struct rsnd_mod_ops *ops; int i, nr, ret; /* same number to SSI */ diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 4a22aadac294..160502947da2 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -333,7 +333,7 @@ static void siu_dai_spbstop(struct siu_port *port_info) /* API functions */ /* Playback and capture hardware properties are identical */ -static struct snd_pcm_hardware siu_dai_pcm_hw = { +static const struct snd_pcm_hardware siu_dai_pcm_hw = { .info = SNDRV_PCM_INFO_INTERLEAVED, .formats = SNDRV_PCM_FMTBIT_S16, .rates = SNDRV_PCM_RATE_8000_48000, diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 82902f56e82f..3118cb0ee3f2 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -593,7 +593,7 @@ static void siu_pcm_free(struct snd_pcm *pcm) dev_dbg(pcm->card->dev, "%s\n", __func__); } -static struct snd_pcm_ops siu_pcm_ops = { +static const struct snd_pcm_ops siu_pcm_ops = { .open = siu_pcm_open, .close = siu_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/soc/sirf/Makefile b/sound/soc/sirf/Makefile index dd917f20f12f..16ed11965ff9 100644 --- a/sound/soc/sirf/Makefile +++ b/sound/soc/sirf/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-soc-sirf-audio-objs := sirf-audio.o snd-soc-sirf-audio-port-objs := sirf-audio-port.o snd-soc-sirf-usp-objs := sirf-usp.o diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 206f36bf43e8..2cb8d3b55fbc 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -737,9 +737,6 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) } /* check client and interface hw capabilities */ - snprintf(new_name, sizeof(new_name), "%s %s-%d", - rtd->dai_link->stream_name, codec_dai->name, num); - if (codec_dai->driver->playback.channels_min) playback = 1; if (codec_dai->driver->capture.channels_min) @@ -758,21 +755,18 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) return -EINVAL; } - if(playback) + if (playback) direction = SND_COMPRESS_PLAYBACK; else direction = SND_COMPRESS_CAPTURE; compr = kzalloc(sizeof(*compr), GFP_KERNEL); - if (compr == NULL) { - snd_printk(KERN_ERR "Cannot allocate compr\n"); + if (!compr) return -ENOMEM; - } compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops), GFP_KERNEL); - if (compr->ops == NULL) { - dev_err(rtd->card->dev, "Cannot allocate compressed ops\n"); + if (!compr->ops) { ret = -ENOMEM; goto compr_err; } @@ -797,19 +791,18 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) else if (rtd->dai_link->dpcm_capture) be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops)); - } else + } else { + snprintf(new_name, sizeof(new_name), "%s %s-%d", + rtd->dai_link->stream_name, codec_dai->name, num); + memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops)); + } /* Add copy callback for not memory mapped DSPs */ if (platform->driver->compr_ops && platform->driver->compr_ops->copy) compr->ops->copy = soc_compr_copy; mutex_init(&compr->lock); - - snprintf(new_name, sizeof(new_name), "%s %s-%d", - rtd->dai_link->stream_name, - rtd->codec_dai->name, num); - ret = snd_compress_new(rtd->card->snd_card, num, direction, new_name, compr); if (ret < 0) { diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 13c875e2392a..fee4b0ef5566 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -339,11 +339,12 @@ static void soc_cleanup_component_debugfs(struct snd_soc_component *component) static void soc_init_codec_debugfs(struct snd_soc_component *component) { struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + struct dentry *debugfs_reg; - codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, - codec->component.debugfs_root, - codec, &codec_reg_fops); - if (!codec->debugfs_reg) + debugfs_reg = debugfs_create_file("codec_reg", 0644, + codec->component.debugfs_root, + codec, &codec_reg_fops); + if (!debugfs_reg) dev_warn(codec->dev, "ASoC: Failed to create codec register debugfs file\n"); } @@ -494,7 +495,7 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card) static void snd_soc_debugfs_init(void) { snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); - if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) { + if (IS_ERR_OR_NULL(snd_soc_debugfs_root)) { pr_warn("ASoC: Failed to create debugfs directory\n"); snd_soc_debugfs_root = NULL; return; @@ -550,6 +551,54 @@ static inline void snd_soc_debugfs_exit(void) #endif +static int snd_soc_rtdcom_add(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_component *component) +{ + struct snd_soc_rtdcom_list *rtdcom; + struct snd_soc_rtdcom_list *new_rtdcom; + + for_each_rtdcom(rtd, rtdcom) { + /* already connected */ + if (rtdcom->component == component) + return 0; + } + + new_rtdcom = kmalloc(sizeof(*new_rtdcom), GFP_KERNEL); + if (!new_rtdcom) + return -ENOMEM; + + new_rtdcom->component = component; + INIT_LIST_HEAD(&new_rtdcom->list); + + list_add_tail(&new_rtdcom->list, &rtd->component_list); + + return 0; +} + +static void snd_soc_rtdcom_del_all(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_rtdcom_list *rtdcom1, *rtdcom2; + + for_each_rtdcom_safe(rtd, rtdcom1, rtdcom2) + kfree(rtdcom1); + + INIT_LIST_HEAD(&rtd->component_list); +} + +struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, + const char *driver_name) +{ + struct snd_soc_rtdcom_list *rtdcom; + + for_each_rtdcom(rtd, rtdcom) { + if ((rtdcom->component->driver->name == driver_name) || + strcmp(rtdcom->component->driver->name, driver_name) == 0) + return rtdcom->component; + } + + return NULL; +} + struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, const char *dai_link, int stream) { @@ -574,6 +623,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( if (!rtd) return NULL; + INIT_LIST_HEAD(&rtd->component_list); rtd->card = card; rtd->dai_link = dai_link; rtd->codec_dais = kzalloc(sizeof(struct snd_soc_dai *) * @@ -591,6 +641,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) { if (rtd && rtd->codec_dais) kfree(rtd->codec_dais); + snd_soc_rtdcom_del_all(rtd); kfree(rtd); } @@ -653,9 +704,7 @@ int snd_soc_suspend(struct device *dev) /* Due to the resume being scheduled into a workqueue we could * suspend before that's finished - wait for it to complete. */ - snd_power_lock(card->snd_card); snd_power_wait(card->snd_card, SNDRV_CTL_POWER_D0); - snd_power_unlock(card->snd_card); /* we're going to block userspace touching us until resume completes */ snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); @@ -949,7 +998,7 @@ static struct snd_soc_component *soc_find_component( /** * snd_soc_find_dai - Find a registered DAI * - * @dlc: name of the DAI and optional component info to match + * @dlc: name of the DAI or the DAI driver and optional component info to match * * This function will search all registered components and their DAIs to * find the DAI of the same name. The component's of_node and name @@ -977,7 +1026,9 @@ struct snd_soc_dai *snd_soc_find_dai( if (dlc->name && strcmp(component->name, dlc->name)) continue; list_for_each_entry(dai, &component->dai_list, list) { - if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)) + if (dlc->dai_name && strcmp(dai->name, dlc->dai_name) + && (!dai->driver->name + || strcmp(dai->driver->name, dlc->dai_name))) continue; return dai; @@ -1049,6 +1100,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd; struct snd_soc_dai_link_component *codecs = dai_link->codecs; struct snd_soc_dai_link_component cpu_dai_component; + struct snd_soc_component *component; struct snd_soc_dai **codec_dais; struct snd_soc_platform *platform; struct device_node *platform_of_node; @@ -1076,6 +1128,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, dai_link->cpu_dai_name); goto _err_defer; } + snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component); rtd->num_codecs = dai_link->num_codecs; @@ -1088,6 +1141,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, codecs[i].dai_name); goto _err_defer; } + snd_soc_rtdcom_add(rtd, codec_dais[i]->component); } /* Single codec links expect codec and codec_dai in runtime data */ @@ -1099,6 +1153,23 @@ static int soc_bind_dai_link(struct snd_soc_card *card, if (!platform_name && !dai_link->platform_of_node) platform_name = "snd-soc-dummy"; + /* find one from the set of registered platforms */ + list_for_each_entry(component, &component_list, list) { + platform_of_node = component->dev->of_node; + if (!platform_of_node && component->dev->parent->of_node) + platform_of_node = component->dev->parent->of_node; + + if (dai_link->platform_of_node) { + if (platform_of_node != dai_link->platform_of_node) + continue; + } else { + if (strcmp(component->name, platform_name)) + continue; + } + + snd_soc_rtdcom_add(rtd, component); + } + /* find one from the set of registered platforms */ list_for_each_entry(platform, &platform_list, list) { platform_of_node = platform->dev->of_node; @@ -1184,27 +1255,15 @@ static void soc_remove_link_dais(struct snd_soc_card *card, static void soc_remove_link_components(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd, int order) { - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_platform *platform = rtd->platform; struct snd_soc_component *component; - int i; + struct snd_soc_rtdcom_list *rtdcom; - /* remove the platform */ - if (platform && platform->component.driver->remove_order == order) - soc_remove_component(&platform->component); + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; - /* remove the CODEC-side CODEC */ - for (i = 0; i < rtd->num_codecs; i++) { - component = rtd->codec_dais[i]->component; if (component->driver->remove_order == order) soc_remove_component(component); } - - /* remove any CPU-side CODEC */ - if (cpu_dai) { - if (cpu_dai->component->driver->remove_order == order) - soc_remove_component(cpu_dai->component); - } } static void soc_remove_dai_links(struct snd_soc_card *card) @@ -1451,9 +1510,10 @@ static int soc_probe_component(struct snd_soc_card *card, soc_init_component_debugfs(component); - if (component->dapm_widgets) { - ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets, - component->num_dapm_widgets); + if (component->driver->dapm_widgets) { + ret = snd_soc_dapm_new_controls(dapm, + component->driver->dapm_widgets, + component->driver->num_dapm_widgets); if (ret != 0) { dev_err(component->dev, @@ -1495,12 +1555,14 @@ static int soc_probe_component(struct snd_soc_card *card, } } - if (component->controls) - snd_soc_add_component_controls(component, component->controls, - component->num_controls); - if (component->dapm_routes) - snd_soc_dapm_add_routes(dapm, component->dapm_routes, - component->num_dapm_routes); + if (component->driver->controls) + snd_soc_add_component_controls(component, + component->driver->controls, + component->driver->num_controls); + if (component->driver->dapm_routes) + snd_soc_dapm_add_routes(dapm, + component->driver->dapm_routes, + component->driver->num_dapm_routes); list_add(&dapm->list, &card->dapm_list); list_add(&component->card_list, &card->component_dev_list); @@ -1556,21 +1618,13 @@ static int soc_probe_link_components(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd, int order) { - struct snd_soc_platform *platform = rtd->platform; struct snd_soc_component *component; - int i, ret; + struct snd_soc_rtdcom_list *rtdcom; + int ret; - /* probe the CPU-side component, if it is a CODEC */ - component = rtd->cpu_dai->component; - if (component->driver->probe_order == order) { - ret = soc_probe_component(card, component); - if (ret < 0) - return ret; - } + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; - /* probe the CODEC-side components */ - for (i = 0; i < rtd->num_codecs; i++) { - component = rtd->codec_dais[i]->component; if (component->driver->probe_order == order) { ret = soc_probe_component(card, component); if (ret < 0) @@ -1578,13 +1632,6 @@ static int soc_probe_link_components(struct snd_soc_card *card, } } - /* probe the platform */ - if (platform->component.driver->probe_order == order) { - ret = soc_probe_component(card, &platform->component); - if (ret < 0) - return ret; - } - return 0; } @@ -2587,11 +2634,9 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, { if (dai->driver && dai->driver->ops->set_sysclk) return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); - else if (dai->codec && dai->codec->driver->set_sysclk) - return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0, - freq, dir); - else - return -ENOTSUPP; + + return snd_soc_component_set_sysclk(dai->component, clk_id, 0, + freq, dir); } EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); @@ -2616,6 +2661,32 @@ int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, } EXPORT_SYMBOL_GPL(snd_soc_codec_set_sysclk); +/** + * snd_soc_component_set_sysclk - configure COMPONENT system or master clock. + * @component: COMPONENT + * @clk_id: DAI specific clock ID + * @source: Source for the clock + * @freq: new clock frequency in Hz + * @dir: new clock direction - input/output. + * + * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. + */ +int snd_soc_component_set_sysclk(struct snd_soc_component *component, int clk_id, + int source, unsigned int freq, int dir) +{ + /* will be removed */ + if (component->set_sysclk) + return component->set_sysclk(component, clk_id, source, + freq, dir); + + if (component->driver->set_sysclk) + return component->driver->set_sysclk(component, clk_id, source, + freq, dir); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk); + /** * snd_soc_dai_set_clkdiv - configure DAI clock dividers. * @dai: DAI @@ -2652,11 +2723,9 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source, if (dai->driver && dai->driver->ops->set_pll) return dai->driver->ops->set_pll(dai, pll_id, source, freq_in, freq_out); - else if (dai->codec && dai->codec->driver->set_pll) - return dai->codec->driver->set_pll(dai->codec, pll_id, source, - freq_in, freq_out); - else - return -EINVAL; + + return snd_soc_component_set_pll(dai->component, pll_id, source, + freq_in, freq_out); } EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); @@ -2681,6 +2750,33 @@ int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, } EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll); +/* + * snd_soc_component_set_pll - configure component PLL. + * @component: COMPONENT + * @pll_id: DAI specific PLL ID + * @source: DAI specific source for the PLL + * @freq_in: PLL input clock frequency in Hz + * @freq_out: requested PLL output clock frequency in Hz + * + * Configures and enables PLL to generate output clock based on input clock. + */ +int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id, + int source, unsigned int freq_in, + unsigned int freq_out) +{ + /* will be removed */ + if (component->set_pll) + return component->set_pll(component, pll_id, source, + freq_in, freq_out); + + if (component->driver->set_pll) + return component->driver->set_pll(component, pll_id, source, + freq_in, freq_out); + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_pll); + /** * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio. * @dai: DAI @@ -3171,8 +3267,11 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, component->remove = component->driver->remove; component->suspend = component->driver->suspend; component->resume = component->driver->resume; + component->set_sysclk = component->driver->set_sysclk; + component->set_pll = component->driver->set_pll; + component->set_jack = component->driver->set_jack; - dapm = &component->dapm; + dapm = snd_soc_component_get_dapm(component); dapm->dev = dev; dapm->component = component; dapm->bias_level = SND_SOC_BIAS_OFF; @@ -3182,13 +3281,6 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, if (driver->stream_event) dapm->stream_event = snd_soc_component_stream_event; - component->controls = driver->controls; - component->num_controls = driver->num_controls; - component->dapm_widgets = driver->dapm_widgets; - component->num_dapm_widgets = driver->num_dapm_widgets; - component->dapm_routes = driver->dapm_routes; - component->num_dapm_routes = driver->num_dapm_routes; - INIT_LIST_HEAD(&component->dai_list); mutex_init(&component->io_mutex); @@ -3280,67 +3372,79 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component) } int snd_soc_register_component(struct device *dev, - const struct snd_soc_component_driver *cmpnt_drv, + const struct snd_soc_component_driver *component_driver, struct snd_soc_dai_driver *dai_drv, int num_dai) { - struct snd_soc_component *cmpnt; + struct snd_soc_component *component; int ret; - cmpnt = kzalloc(sizeof(*cmpnt), GFP_KERNEL); - if (!cmpnt) { + component = kzalloc(sizeof(*component), GFP_KERNEL); + if (!component) { dev_err(dev, "ASoC: Failed to allocate memory\n"); return -ENOMEM; } - ret = snd_soc_component_initialize(cmpnt, cmpnt_drv, dev); + ret = snd_soc_component_initialize(component, component_driver, dev); if (ret) goto err_free; - cmpnt->ignore_pmdown_time = true; - cmpnt->registered_as_component = true; + component->ignore_pmdown_time = true; + component->registered_as_component = true; - ret = snd_soc_register_dais(cmpnt, dai_drv, num_dai, true); + ret = snd_soc_register_dais(component, dai_drv, num_dai, true); if (ret < 0) { dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); goto err_cleanup; } - snd_soc_component_add(cmpnt); + snd_soc_component_add(component); return 0; err_cleanup: - snd_soc_component_cleanup(cmpnt); + snd_soc_component_cleanup(component); err_free: - kfree(cmpnt); + kfree(component); return ret; } EXPORT_SYMBOL_GPL(snd_soc_register_component); /** - * snd_soc_unregister_component - Unregister a component from the ASoC core + * snd_soc_unregister_component - Unregister all related component + * from the ASoC core * * @dev: The device to unregister */ -void snd_soc_unregister_component(struct device *dev) +static int __snd_soc_unregister_component(struct device *dev) { - struct snd_soc_component *cmpnt; + struct snd_soc_component *component; + int found = 0; mutex_lock(&client_mutex); - list_for_each_entry(cmpnt, &component_list, list) { - if (dev == cmpnt->dev && cmpnt->registered_as_component) - goto found; + list_for_each_entry(component, &component_list, list) { + if (dev != component->dev || + !component->registered_as_component) + continue; + + snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); + snd_soc_component_del_unlocked(component); + found = 1; + break; } mutex_unlock(&client_mutex); - return; -found: - snd_soc_tplg_component_remove(cmpnt, SND_SOC_TPLG_INDEX_ALL); - snd_soc_component_del_unlocked(cmpnt); - mutex_unlock(&client_mutex); - snd_soc_component_cleanup(cmpnt); - kfree(cmpnt); + if (found) { + snd_soc_component_cleanup(component); + kfree(component); + } + + return found; +} + +void snd_soc_unregister_component(struct device *dev) +{ + while (__snd_soc_unregister_component(dev)); } EXPORT_SYMBOL_GPL(snd_soc_unregister_component); @@ -3557,6 +3661,31 @@ static int snd_soc_codec_drv_read(struct snd_soc_component *component, return 0; } +static int snd_soc_codec_set_sysclk_(struct snd_soc_component *component, + int clk_id, int source, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return snd_soc_codec_set_sysclk(codec, clk_id, source, freq, dir); +} + +static int snd_soc_codec_set_pll_(struct snd_soc_component *component, + int pll_id, int source, unsigned int freq_in, + unsigned int freq_out) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return snd_soc_codec_set_pll(codec, pll_id, source, freq_in, freq_out); +} + +static int snd_soc_codec_set_jack_(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return snd_soc_codec_set_jack(codec, jack, data); +} + static int snd_soc_codec_set_bias_level(struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { @@ -3608,6 +3737,12 @@ int snd_soc_register_codec(struct device *dev, codec->component.write = snd_soc_codec_drv_write; if (codec_drv->read) codec->component.read = snd_soc_codec_drv_read; + if (codec_drv->set_sysclk) + codec->component.set_sysclk = snd_soc_codec_set_sysclk_; + if (codec_drv->set_pll) + codec->component.set_pll = snd_soc_codec_set_pll_; + if (codec_drv->set_jack) + codec->component.set_jack = snd_soc_codec_set_jack_; codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; dapm = snd_soc_codec_get_dapm(codec); diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 7daf21fee355..99902ae1a2d9 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -22,6 +22,12 @@ #include #include +struct jack_gpio_tbl { + int count; + struct snd_soc_jack *jack; + struct snd_soc_jack_gpio *gpios; +}; + /** * snd_soc_codec_set_jack - configure codec jack. * @codec: CODEC @@ -36,10 +42,32 @@ int snd_soc_codec_set_jack(struct snd_soc_codec *codec, if (codec->driver->set_jack) return codec->driver->set_jack(codec, jack, data); else - return -EINVAL; + return -ENOTSUPP; } EXPORT_SYMBOL_GPL(snd_soc_codec_set_jack); +/** + * snd_soc_component_set_jack - configure component jack. + * @component: COMPONENTs + * @jack: structure to use for the jack + * @data: can be used if codec driver need extra data for configuring jack + * + * Configures and enables jack detection function. + */ +int snd_soc_component_set_jack(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + /* will be removed */ + if (component->set_jack) + return component->set_jack(component, jack, data); + + if (component->driver->set_jack) + return component->driver->set_jack(component, jack, data); + + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(snd_soc_component_set_jack); + /** * snd_soc_card_jack_new - Create a new jack * @card: ASoC card @@ -333,6 +361,28 @@ static int snd_soc_jack_pm_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static void jack_free_gpios(struct snd_soc_jack *jack, int count, + struct snd_soc_jack_gpio *gpios) +{ + int i; + + for (i = 0; i < count; i++) { + gpiod_unexport(gpios[i].desc); + unregister_pm_notifier(&gpios[i].pm_notifier); + free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); + cancel_delayed_work_sync(&gpios[i].work); + gpiod_put(gpios[i].desc); + gpios[i].jack = NULL; + } +} + +static void jack_devres_free_gpios(struct device *dev, void *res) +{ + struct jack_gpio_tbl *tbl = res; + + jack_free_gpios(tbl->jack, tbl->count, tbl->gpios); +} + /** * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack * @@ -347,6 +397,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { int i, ret; + struct jack_gpio_tbl *tbl; + + tbl = devres_alloc(jack_devres_free_gpios, sizeof(*tbl), GFP_KERNEL); + if (!tbl) + return -ENOMEM; + tbl->jack = jack; + tbl->count = count; + tbl->gpios = gpios; for (i = 0; i < count; i++) { if (!gpios[i].name) { @@ -424,12 +482,14 @@ got_gpio: msecs_to_jiffies(gpios[i].debounce_time)); } + devres_add(jack->card->dev, tbl); return 0; err: gpio_free(gpios[i].gpio); undo: - snd_soc_jack_free_gpios(jack, i, gpios); + jack_free_gpios(jack, i, gpios); + devres_free(tbl); return ret; } @@ -471,16 +531,8 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpiods); void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios) { - int i; - - for (i = 0; i < count; i++) { - gpiod_unexport(gpios[i].desc); - unregister_pm_notifier(&gpios[i].pm_notifier); - free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); - cancel_delayed_work_sync(&gpios[i].work); - gpiod_put(gpios[i].desc); - gpios[i].jack = NULL; - } + jack_free_gpios(jack, count, gpios); + devres_destroy(jack->card->dev, jack_devres_free_gpios, NULL, NULL); } EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios); #endif /* CONFIG_GPIOLIB */ diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 7d3859e1a7b9..94b88b897c3b 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -454,6 +454,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai; const char *codec_dai_name = "multicodec"; @@ -462,10 +464,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) pinctrl_pm_select_default_state(cpu_dai->dev); for (i = 0; i < rtd->num_codecs; i++) pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev); - pm_runtime_get_sync(cpu_dai->dev); - for (i = 0; i < rtd->num_codecs; i++) - pm_runtime_get_sync(rtd->codec_dais[i]->dev); - pm_runtime_get_sync(platform->dev); + + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + pm_runtime_get_sync(component->dev); + } mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); @@ -603,15 +607,13 @@ platform_err: out: mutex_unlock(&rtd->pcm_mutex); - pm_runtime_mark_last_busy(platform->dev); - pm_runtime_put_autosuspend(platform->dev); - for (i = 0; i < rtd->num_codecs; i++) { - pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev); - pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev); + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; + + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); } - pm_runtime_mark_last_busy(cpu_dai->dev); - pm_runtime_put_autosuspend(cpu_dai->dev); for (i = 0; i < rtd->num_codecs; i++) { if (!rtd->codec_dais[i]->active) pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev); @@ -659,6 +661,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_component *component; + struct snd_soc_rtdcom_list *rtdcom; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai; int i; @@ -715,17 +719,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) mutex_unlock(&rtd->pcm_mutex); - pm_runtime_mark_last_busy(platform->dev); - pm_runtime_put_autosuspend(platform->dev); + for_each_rtdcom(rtd, rtdcom) { + component = rtdcom->component; - for (i = 0; i < rtd->num_codecs; i++) { - pm_runtime_mark_last_busy(rtd->codec_dais[i]->dev); - pm_runtime_put_autosuspend(rtd->codec_dais[i]->dev); + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); } - pm_runtime_mark_last_busy(cpu_dai->dev); - pm_runtime_put_autosuspend(cpu_dai->dev); - for (i = 0; i < rtd->num_codecs; i++) { if (!rtd->codec_dais[i]->active) pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev); @@ -3000,8 +3000,7 @@ void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd) return; } - rtd->debugfs_dpcm_state = debugfs_create_file("state", 0444, - rtd->debugfs_dpcm_root, - rtd, &dpcm_state_fops); + debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root, + rtd, &dpcm_state_fops); } #endif diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index dd471d2c0266..01a50413c66f 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1301,7 +1301,7 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create( /* validate kcontrol */ if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == SNDRV_CTL_ELEM_ID_NAME_MAXLEN) - return NULL; + goto err; se = kzalloc(sizeof(*se), GFP_KERNEL); if (se == NULL) @@ -1378,6 +1378,9 @@ err_se: for (; i >= 0; i--) { /* free values and texts */ se = (struct soc_enum *)kc[i].private_value; + if (!se) + continue; + kfree(se->dobj.control.dvalues); for (j = 0; j < ec->items; j++) kfree(se->dobj.control.dtexts[j]); diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 644d9a9ebfbc..e30aacbcfc29 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -284,7 +284,7 @@ static const struct snd_pcm_ops dummy_dma_ops = { .ioctl = snd_pcm_lib_ioctl, }; -static struct snd_soc_platform_driver dummy_platform = { +static const struct snd_soc_platform_driver dummy_platform = { .ops = &dummy_dma_ops, }; diff --git a/sound/soc/spear/Makefile b/sound/soc/spear/Makefile index c4ea7161056c..31d9dae280e7 100644 --- a/sound/soc/spear/Makefile +++ b/sound/soc/spear/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # SPEAR Platform Support snd-soc-spear-pcm-objs := spear_pcm.o snd-soc-spear-spdif-in-objs := spdif_in.o diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index 977a078eb92f..78a6a360b4a6 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c @@ -151,7 +151,7 @@ static int spdif_in_trigger(struct snd_pcm_substream *substream, int cmd, return ret; } -static struct snd_soc_dai_ops spdif_in_dai_ops = { +static const struct snd_soc_dai_ops spdif_in_dai_ops = { .shutdown = spdif_in_shutdown, .trigger = spdif_in_trigger, .hw_params = spdif_in_hw_params, @@ -216,15 +216,15 @@ static int spdif_in_probe(struct platform_device *pdev) return -EINVAL; host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); - if (!host) { - dev_warn(&pdev->dev, "kzalloc fail\n"); + if (!host) return -ENOMEM; - } host->io_base = io_base; host->irq = platform_get_irq(pdev, 0); - if (host->irq < 0) - return -EINVAL; + if (host->irq < 0) { + dev_warn(&pdev->dev, "failed to get IRQ: %d\n", host->irq); + return host->irq; + } host->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c index 0a72d52d533e..58d5843811f9 100644 --- a/sound/soc/spear/spdif_out.c +++ b/sound/soc/spear/spdif_out.c @@ -282,10 +282,8 @@ static int spdif_out_probe(struct platform_device *pdev) int ret; host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); - if (!host) { - dev_warn(&pdev->dev, "kzalloc fail\n"); + if (!host) return -ENOMEM; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); host->io_base = devm_ioremap_resource(&pdev->dev, res); diff --git a/sound/soc/stm/Makefile b/sound/soc/stm/Makefile index 4ed22e648a9a..5b7f0fab0bd6 100644 --- a/sound/soc/stm/Makefile +++ b/sound/soc/stm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # SAI snd-soc-stm32-sai-sub-objs := stm32_sai_sub.o obj-$(CONFIG_SND_SOC_STM32_SAI) += snd-soc-stm32-sai-sub.o diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 8052629a89df..6d0bf78d114d 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -840,7 +840,7 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev, } /* Reset */ - rst = devm_reset_control_get(&pdev->dev, NULL); + rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index f7713314913b..1258bef4dcb3 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c @@ -85,7 +85,7 @@ static int stm32_sai_probe(struct platform_device *pdev) } /* reset */ - rst = reset_control_get(&pdev->dev, NULL); + rst = reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); diff --git a/sound/soc/stm/stm32_spdifrx.c b/sound/soc/stm/stm32_spdifrx.c index 4e4250bdb75a..84cc5678beba 100644 --- a/sound/soc/stm/stm32_spdifrx.c +++ b/sound/soc/stm/stm32_spdifrx.c @@ -930,7 +930,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev) return ret; } - rst = devm_reset_control_get(&pdev->dev, NULL); + rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(rst)) { reset_control_assert(rst); udelay(2); diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile index 1f1af6271731..4a9ef67386ca 100644 --- a/sound/soc/sunxi/Makefile +++ b/sound/soc/sunxi/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SND_SUN4I_CODEC) += sun4i-codec.o obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 150069987c0c..baa9007464ed 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -762,7 +762,7 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = { { "Mic1", NULL, "VMIC" }, }; -static struct snd_soc_codec_driver sun4i_codec_codec = { +static const struct snd_soc_codec_driver sun4i_codec_codec = { .component_driver = { .controls = sun4i_codec_controls, .num_controls = ARRAY_SIZE(sun4i_codec_controls), @@ -1068,7 +1068,7 @@ static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = { { "Right ADC", NULL, "Right ADC Mixer" }, }; -static struct snd_soc_codec_driver sun6i_codec_codec = { +static const struct snd_soc_codec_driver sun6i_codec_codec = { .component_driver = { .controls = sun6i_codec_codec_widgets, .num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets), @@ -1096,7 +1096,7 @@ static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = { }; -static struct snd_soc_codec_driver sun8i_a23_codec_codec = { +static const struct snd_soc_codec_driver sun8i_a23_codec_codec = { .component_driver = { .controls = sun8i_a23_codec_codec_controls, .num_controls = ARRAY_SIZE(sun8i_a23_codec_codec_controls), @@ -1171,9 +1171,8 @@ static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w, { struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card); - if (scodec->gpio_pa) - gpiod_set_value_cansleep(scodec->gpio_pa, - !!SND_SOC_DAPM_EVENT_ON(event)); + gpiod_set_value_cansleep(scodec->gpio_pa, + !!SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -1574,7 +1573,8 @@ static int sun4i_codec_probe(struct platform_device *pdev) } if (quirks->has_reset) { - scodec->rst = devm_reset_control_get(&pdev->dev, NULL); + scodec->rst = devm_reset_control_get_exclusive(&pdev->dev, + NULL); if (IS_ERR(scodec->rst)) { dev_err(&pdev->dev, "Failed to get reset control\n"); return PTR_ERR(scodec->rst); @@ -1655,7 +1655,6 @@ static int sun4i_codec_probe(struct platform_device *pdev) goto err_unregister_codec; } - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, scodec); ret = snd_soc_register_card(card); diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 3635bbc72cbc..04f92583a969 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -50,6 +50,8 @@ #define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0) #define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0) #define SUN4I_I2S_FMT0_FMT_I2S (0 << 0) +#define SUN4I_I2S_FMT0_POLARITY_INVERTED (1) +#define SUN4I_I2S_FMT0_POLARITY_NORMAL (0) #define SUN4I_I2S_FMT1_REG 0x08 #define SUN4I_I2S_FIFO_TX_REG 0x0c @@ -82,7 +84,7 @@ #define SUN4I_I2S_TX_CNT_REG 0x2c #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 -#define SUN4I_I2S_TX_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) +#define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample) ((sample) << (chan << 2)) @@ -90,6 +92,83 @@ #define SUN4I_I2S_RX_CHAN_SEL_REG 0x38 #define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c +/* Defines required for sun8i-h3 support */ +#define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) +#define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) + +#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) +#define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) + +#define SUN8I_I2S_INT_STA_REG 0x0c +#define SUN8I_I2S_FIFO_TX_REG 0x20 + +#define SUN8I_I2S_CHAN_CFG_REG 0x30 +#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK GENMASK(6, 4) +#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) (chan - 1) +#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(2, 0) +#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1) + +#define SUN8I_I2S_TX_CHAN_MAP_REG 0x44 +#define SUN8I_I2S_TX_CHAN_SEL_REG 0x34 +#define SUN8I_I2S_TX_CHAN_OFFSET_MASK GENMASK(13, 11) +#define SUN8I_I2S_TX_CHAN_OFFSET(offset) (offset << 12) +#define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4) +#define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4) + +#define SUN8I_I2S_RX_CHAN_SEL_REG 0x54 +#define SUN8I_I2S_RX_CHAN_MAP_REG 0x58 + +/** + * struct sun4i_i2s_quirks - Differences between SoC variants. + * + * @has_reset: SoC needs reset deasserted. + * @has_slave_select_bit: SoC has a bit to enable slave mode. + * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. + * @has_chcfg: tx and rx slot number need to be set. + * @has_chsel_tx_chen: SoC requires that the tx channels are enabled. + * @has_chsel_offset: SoC uses offset for selecting dai operational mode. + * @reg_offset_txdata: offset of the tx fifo. + * @sun4i_i2s_regmap: regmap config to use. + * @mclk_offset: Value by which mclkdiv needs to be adjusted. + * @bclk_offset: Value by which bclkdiv needs to be adjusted. + * @fmt_offset: Value by which wss and sr needs to be adjusted. + * @field_clkdiv_mclk_en: regmap field to enable mclk output. + * @field_fmt_wss: regmap field to set word select size. + * @field_fmt_sr: regmap field to set sample resolution. + * @field_fmt_bclk: regmap field to set clk polarity. + * @field_fmt_lrclk: regmap field to set frame polarity. + * @field_fmt_mode: regmap field to set the operational mode. + * @field_txchanmap: location of the tx channel mapping register. + * @field_rxchanmap: location of the rx channel mapping register. + * @field_txchansel: location of the tx channel select bit fields. + * @field_rxchansel: location of the rx channel select bit fields. + */ +struct sun4i_i2s_quirks { + bool has_reset; + bool has_slave_select_bit; + bool has_fmt_set_lrck_period; + bool has_chcfg; + bool has_chsel_tx_chen; + bool has_chsel_offset; + unsigned int reg_offset_txdata; /* TX FIFO */ + const struct regmap_config *sun4i_i2s_regmap; + unsigned int mclk_offset; + unsigned int bclk_offset; + unsigned int fmt_offset; + + /* Register fields for i2s */ + struct reg_field field_clkdiv_mclk_en; + struct reg_field field_fmt_wss; + struct reg_field field_fmt_sr; + struct reg_field field_fmt_bclk; + struct reg_field field_fmt_lrclk; + struct reg_field field_fmt_mode; + struct reg_field field_txchanmap; + struct reg_field field_rxchanmap; + struct reg_field field_txchansel; + struct reg_field field_rxchansel; +}; + struct sun4i_i2s { struct clk *bus_clk; struct clk *mod_clk; @@ -100,6 +179,20 @@ struct sun4i_i2s { struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data; + + /* Register fields for i2s */ + struct regmap_field *field_clkdiv_mclk_en; + struct regmap_field *field_fmt_wss; + struct regmap_field *field_fmt_sr; + struct regmap_field *field_fmt_bclk; + struct regmap_field *field_fmt_lrclk; + struct regmap_field *field_fmt_mode; + struct regmap_field *field_txchanmap; + struct regmap_field *field_rxchanmap; + struct regmap_field *field_txchansel; + struct regmap_field *field_rxchansel; + + const struct sun4i_i2s_quirks *variant; }; struct sun4i_i2s_clk_div { @@ -114,6 +207,7 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = { { .div = 8, .val = 3 }, { .div = 12, .val = 4 }, { .div = 16, .val = 5 }, + /* TODO - extend divide ratio supported by newer SoCs */ }; static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = { @@ -125,6 +219,7 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = { { .div = 12, .val = 5 }, { .div = 16, .val = 6 }, { .div = 24, .val = 7 }, + /* TODO - extend divide ratio supported by newer SoCs */ }; static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s, @@ -226,10 +321,21 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, if (mclk_div < 0) return -EINVAL; + /* Adjust the clock division values if needed */ + bclk_div += i2s->variant->bclk_offset; + mclk_div += i2s->variant->mclk_offset; + regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | - SUN4I_I2S_CLK_DIV_MCLK(mclk_div) | - SUN4I_I2S_CLK_DIV_MCLK_EN); + SUN4I_I2S_CLK_DIV_MCLK(mclk_div)); + + regmap_field_write(i2s->field_clkdiv_mclk_en, 1); + + /* Set sync period */ + if (i2s->variant->has_fmt_set_lrck_period) + regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, + SUN8I_I2S_FMT0_LRCK_PERIOD_MASK, + SUN8I_I2S_FMT0_LRCK_PERIOD(32)); return 0; } @@ -239,12 +345,38 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); - int sr, wss; + int sr, wss, channels; u32 width; - if (params_channels(params) != 2) + channels = params_channels(params); + if (channels != 2) return -EINVAL; + if (i2s->variant->has_chcfg) { + regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, + SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, + SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels)); + regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, + SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK, + SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels)); + } + + /* Map the channels for playback and capture */ + regmap_field_write(i2s->field_txchanmap, 0x76543210); + regmap_field_write(i2s->field_rxchanmap, 0x00003210); + + /* Configure the channels */ + regmap_field_write(i2s->field_txchansel, + SUN4I_I2S_CHAN_SEL(params_channels(params))); + + regmap_field_write(i2s->field_rxchansel, + SUN4I_I2S_CHAN_SEL(params_channels(params))); + + if (i2s->variant->has_chsel_tx_chen) + regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, + SUN8I_I2S_TX_CHAN_EN_MASK, + SUN8I_I2S_TX_CHAN_EN(channels)); + switch (params_physical_width(params)) { case 16: width = DMA_SLAVE_BUSWIDTH_2_BYTES; @@ -264,9 +396,10 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, - SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK, - SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr)); + regmap_field_write(i2s->field_fmt_wss, + wss + i2s->variant->fmt_offset); + regmap_field_write(i2s->field_fmt_sr, + sr + i2s->variant->fmt_offset); return sun4i_i2s_set_clk_rate(i2s, params_rate(params), params_width(params)); @@ -276,11 +409,15 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); u32 val; + u32 offset = 0; + u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; + u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; /* DAI Mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: val = SUN4I_I2S_FMT0_FMT_I2S; + offset = 1; break; case SND_SOC_DAIFMT_LEFT_J: val = SUN4I_I2S_FMT0_FMT_LEFT_J; @@ -292,59 +429,89 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, - SUN4I_I2S_FMT0_FMT_MASK, - val); + if (i2s->variant->has_chsel_offset) { + /* + * offset being set indicates that we're connected to an i2s + * device, however offset is only used on the sun8i block and + * i2s shares the same setting with the LJ format. Increment + * val so that the bit to value to write is correct. + */ + if (offset > 0) + val++; + /* blck offset determines whether i2s or LJ */ + regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, + SUN8I_I2S_TX_CHAN_OFFSET_MASK, + SUN8I_I2S_TX_CHAN_OFFSET(offset)); + } + + regmap_field_write(i2s->field_fmt_mode, val); /* DAI clock polarity */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_IF: /* Invert both clocks */ - val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | - SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED; + bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; + lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; break; case SND_SOC_DAIFMT_IB_NF: /* Invert bit clock */ - val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED | - SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL; + bclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; break; case SND_SOC_DAIFMT_NB_IF: /* Invert frame clock */ - val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED | - SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL; + lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_INVERTED; break; case SND_SOC_DAIFMT_NB_NF: - /* Nothing to do for both normal cases */ - val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL | - SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL; break; default: return -EINVAL; } - regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, - SUN4I_I2S_FMT0_BCLK_POLARITY_MASK | - SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK, - val); + regmap_field_write(i2s->field_fmt_bclk, bclk_polarity); + regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity); - /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* BCLK and LRCLK master */ - val = SUN4I_I2S_CTRL_MODE_MASTER; - break; - case SND_SOC_DAIFMT_CBM_CFM: - /* BCLK and LRCLK slave */ - val = SUN4I_I2S_CTRL_MODE_SLAVE; - break; - default: - return -EINVAL; + if (i2s->variant->has_slave_select_bit) { + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* BCLK and LRCLK master */ + val = SUN4I_I2S_CTRL_MODE_MASTER; + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* BCLK and LRCLK slave */ + val = SUN4I_I2S_CTRL_MODE_SLAVE; + break; + default: + return -EINVAL; + } + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN4I_I2S_CTRL_MODE_MASK, + val); + } else { + /* + * The newer i2s block does not have a slave select bit, + * instead the clk pins are configured as inputs. + */ + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* BCLK and LRCLK master */ + val = SUN8I_I2S_CTRL_BCLK_OUT | + SUN8I_I2S_CTRL_LRCK_OUT; + break; + case SND_SOC_DAIFMT_CBM_CFM: + /* BCLK and LRCLK slave */ + val = 0; + break; + default: + return -EINVAL; + } + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN8I_I2S_CTRL_BCLK_OUT | + SUN8I_I2S_CTRL_LRCK_OUT, + val); } - regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, - SUN4I_I2S_CTRL_MODE_MASK, - val); - /* Set significant bits in our FIFOs */ regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG, SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK | @@ -459,21 +626,14 @@ static int sun4i_i2s_startup(struct snd_pcm_substream *substream, struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); /* Enable the whole hardware block */ - regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, - SUN4I_I2S_CTRL_GL_EN); + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN); /* Enable the first output line */ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, SUN4I_I2S_CTRL_SDO_EN_MASK, SUN4I_I2S_CTRL_SDO_EN(0)); - /* Enable the first two channels */ - regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG, - SUN4I_I2S_TX_CHAN_SEL(2)); - - /* Map them to the two first samples coming in */ - regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, - SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1)); return clk_prepare_enable(i2s->mod_clk); } @@ -490,7 +650,8 @@ static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream, SUN4I_I2S_CTRL_SDO_EN_MASK, 0); /* Disable the whole hardware block */ - regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0); + regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, + SUN4I_I2S_CTRL_GL_EN, 0); } static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, @@ -589,6 +750,27 @@ static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg) } } +static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SUN8I_I2S_FIFO_TX_REG: + return false; + + default: + return true; + } +} + +static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg) +{ + if (reg == SUN8I_I2S_INT_STA_REG) + return true; + if (reg == SUN8I_I2S_FIFO_TX_REG) + return false; + + return sun4i_i2s_volatile_reg(dev, reg); +} + static const struct reg_default sun4i_i2s_reg_defaults[] = { { SUN4I_I2S_CTRL_REG, 0x00000000 }, { SUN4I_I2S_FMT0_REG, 0x0000000c }, @@ -602,6 +784,20 @@ static const struct reg_default sun4i_i2s_reg_defaults[] = { { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 }, }; +static const struct reg_default sun8i_i2s_reg_defaults[] = { + { SUN4I_I2S_CTRL_REG, 0x00060000 }, + { SUN4I_I2S_FMT0_REG, 0x00000033 }, + { SUN4I_I2S_FMT1_REG, 0x00000030 }, + { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 }, + { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 }, + { SUN4I_I2S_CLK_DIV_REG, 0x00000000 }, + { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 }, + { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 }, + { SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 }, + { SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 }, + { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 }, +}; + static const struct regmap_config sun4i_i2s_regmap_config = { .reg_bits = 32, .reg_stride = 4, @@ -616,6 +812,19 @@ static const struct regmap_config sun4i_i2s_regmap_config = { .volatile_reg = sun4i_i2s_volatile_reg, }; +static const struct regmap_config sun8i_i2s_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = SUN8I_I2S_RX_CHAN_MAP_REG, + .cache_type = REGCACHE_FLAT, + .reg_defaults = sun8i_i2s_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(sun8i_i2s_reg_defaults), + .writeable_reg = sun4i_i2s_wr_reg, + .readable_reg = sun8i_i2s_rd_reg, + .volatile_reg = sun8i_i2s_volatile_reg, +}; + static int sun4i_i2s_runtime_resume(struct device *dev) { struct sun4i_i2s *i2s = dev_get_drvdata(dev); @@ -654,22 +863,129 @@ static int sun4i_i2s_runtime_suspend(struct device *dev) return 0; } -struct sun4i_i2s_quirks { - bool has_reset; -}; - static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { - .has_reset = false, + .has_reset = false, + .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, + .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .has_slave_select_bit = true, + .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), + .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), }; static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { - .has_reset = true, + .has_reset = true, + .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, + .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .has_slave_select_bit = true, + .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), + .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), }; +static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { + .has_reset = true, + .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, + .sun4i_i2s_regmap = &sun8i_i2s_regmap_config, + .mclk_offset = 1, + .bclk_offset = 2, + .fmt_offset = 3, + .has_fmt_set_lrck_period = true, + .has_chcfg = true, + .has_chsel_tx_chen = true, + .has_chsel_offset = true, + .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), + .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), + .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), + .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), + .field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5), + .field_txchanmap = REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31), + .field_rxchanmap = REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31), + .field_txchansel = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2), + .field_rxchansel = REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2), +}; + +static int sun4i_i2s_init_regmap_fields(struct device *dev, + struct sun4i_i2s *i2s) +{ + i2s->field_clkdiv_mclk_en = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_clkdiv_mclk_en); + if (IS_ERR(i2s->field_clkdiv_mclk_en)) + return PTR_ERR(i2s->field_clkdiv_mclk_en); + + i2s->field_fmt_wss = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_wss); + if (IS_ERR(i2s->field_fmt_wss)) + return PTR_ERR(i2s->field_fmt_wss); + + i2s->field_fmt_sr = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_sr); + if (IS_ERR(i2s->field_fmt_sr)) + return PTR_ERR(i2s->field_fmt_sr); + + i2s->field_fmt_bclk = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_bclk); + if (IS_ERR(i2s->field_fmt_bclk)) + return PTR_ERR(i2s->field_fmt_bclk); + + i2s->field_fmt_lrclk = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_lrclk); + if (IS_ERR(i2s->field_fmt_lrclk)) + return PTR_ERR(i2s->field_fmt_lrclk); + + i2s->field_fmt_mode = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_fmt_mode); + if (IS_ERR(i2s->field_fmt_mode)) + return PTR_ERR(i2s->field_fmt_mode); + + i2s->field_txchanmap = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_txchanmap); + if (IS_ERR(i2s->field_txchanmap)) + return PTR_ERR(i2s->field_txchanmap); + + i2s->field_rxchanmap = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_rxchanmap); + if (IS_ERR(i2s->field_rxchanmap)) + return PTR_ERR(i2s->field_rxchanmap); + + i2s->field_txchansel = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_txchansel); + if (IS_ERR(i2s->field_txchansel)) + return PTR_ERR(i2s->field_txchansel); + + i2s->field_rxchansel = + devm_regmap_field_alloc(dev, i2s->regmap, + i2s->variant->field_rxchansel); + return PTR_ERR_OR_ZERO(i2s->field_rxchansel); +} + static int sun4i_i2s_probe(struct platform_device *pdev) { struct sun4i_i2s *i2s; - const struct sun4i_i2s_quirks *quirks; struct resource *res; void __iomem *regs; int irq, ret; @@ -690,8 +1006,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev) return irq; } - quirks = of_device_get_match_data(&pdev->dev); - if (!quirks) { + i2s->variant = of_device_get_match_data(&pdev->dev); + if (!i2s->variant) { dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); return -ENODEV; } @@ -703,7 +1019,7 @@ static int sun4i_i2s_probe(struct platform_device *pdev) } i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, - &sun4i_i2s_regmap_config); + i2s->variant->sun4i_i2s_regmap); if (IS_ERR(i2s->regmap)) { dev_err(&pdev->dev, "Regmap initialisation failed\n"); return PTR_ERR(i2s->regmap); @@ -715,8 +1031,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev) return PTR_ERR(i2s->mod_clk); } - if (quirks->has_reset) { - i2s->rst = devm_reset_control_get(&pdev->dev, NULL); + if (i2s->variant->has_reset) { + i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(i2s->rst)) { dev_err(&pdev->dev, "Failed to get reset control\n"); return PTR_ERR(i2s->rst); @@ -732,7 +1048,8 @@ static int sun4i_i2s_probe(struct platform_device *pdev) } } - i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG; + i2s->playback_dma_data.addr = res->start + + i2s->variant->reg_offset_txdata; i2s->playback_dma_data.maxburst = 8; i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG; @@ -759,6 +1076,12 @@ static int sun4i_i2s_probe(struct platform_device *pdev) goto err_suspend; } + ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s); + if (ret) { + dev_err(&pdev->dev, "Could not initialise regmap fields\n"); + goto err_suspend; + } + return 0; err_suspend: @@ -797,6 +1120,10 @@ static const struct of_device_id sun4i_i2s_match[] = { .compatible = "allwinner,sun6i-a31-i2s", .data = &sun6i_a31_i2s_quirks, }, + { + .compatible = "allwinner,sun8i-h3-i2s", + .data = &sun8i_h3_i2s_quirks, + }, {} }; MODULE_DEVICE_TABLE(of, sun4i_i2s_match); diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c index eaefd07a5ed0..b4af4aabead1 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c @@ -458,11 +458,16 @@ static int sun4i_spdif_runtime_suspend(struct device *dev) static int sun4i_spdif_runtime_resume(struct device *dev) { struct sun4i_spdif_dev *host = dev_get_drvdata(dev); + int ret; - clk_prepare_enable(host->spdif_clk); - clk_prepare_enable(host->apb_clk); + ret = clk_prepare_enable(host->spdif_clk); + if (ret) + return ret; + ret = clk_prepare_enable(host->apb_clk); + if (ret) + clk_disable_unprepare(host->spdif_clk); - return 0; + return ret; } static int sun4i_spdif_probe(struct platform_device *pdev) @@ -520,7 +525,8 @@ static int sun4i_spdif_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); if (quirks->has_reset) { - host->rst = devm_reset_control_get_optional(&pdev->dev, NULL); + host->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, + NULL); if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; dev_err(&pdev->dev, "Failed to get reset: %d\n", ret); diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 5723c3404f6b..abfb710df7cb 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -341,7 +341,7 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { "AIF1 Slot 0 Right"}, }; -static struct snd_soc_dai_ops sun8i_codec_dai_ops = { +static const struct snd_soc_dai_ops sun8i_codec_dai_ops = { .hw_params = sun8i_codec_hw_params, .set_fmt = sun8i_set_fmt, }; @@ -360,7 +360,7 @@ static struct snd_soc_dai_driver sun8i_codec_dai = { .ops = &sun8i_codec_dai_ops, }; -static struct snd_soc_codec_driver sun8i_soc_codec = { +static const struct snd_soc_codec_driver sun8i_soc_codec = { .component_driver = { .dapm_widgets = sun8i_codec_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets), diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index efbe8d4c019e..6875fc39a575 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -9,8 +9,8 @@ config SND_SOC_TEGRA Say Y or M here if you want support for SoC audio on Tegra. config SND_SOC_TEGRA20_AC97 - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 AC97 interface" + depends on SND_SOC_TEGRA select SND_SOC_AC97_BUS select SND_SOC_TEGRA20_DAS help @@ -19,16 +19,16 @@ config SND_SOC_TEGRA20_AC97 machine drivers to support below. config SND_SOC_TEGRA20_DAS - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 DAS module" + depends on SND_SOC_TEGRA help Say Y or M if you want to add support for the Tegra20 DAS module. You will also need to select the individual machine drivers to support below. config SND_SOC_TEGRA20_I2S - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 I2S interface" + depends on SND_SOC_TEGRA select SND_SOC_TEGRA20_DAS help Say Y or M if you want to add support for codecs attached to the @@ -36,8 +36,8 @@ config SND_SOC_TEGRA20_I2S machine drivers to support below. config SND_SOC_TEGRA20_SPDIF - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC + tristate "Tegra20 SPDIF interface" + depends on SND_SOC_TEGRA default m help Say Y or M if you want to add support for the Tegra20 SPDIF interface. @@ -45,16 +45,16 @@ config SND_SOC_TEGRA20_SPDIF below. config SND_SOC_TEGRA30_AHUB - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_3x_SOC + tristate "Tegra30 AHUB module" + depends on SND_SOC_TEGRA help - Say Y or M if you want to add support for the Tegra20 AHUB module. + Say Y or M if you want to add support for the Tegra30 AHUB module. You will also need to select the individual machine drivers to support below. config SND_SOC_TEGRA30_I2S - tristate - depends on SND_SOC_TEGRA && ARCH_TEGRA_3x_SOC + tristate "Tegra30 I2S interface" + depends on SND_SOC_TEGRA select SND_SOC_TEGRA30_AHUB help Say Y or M if you want to add support for codecs attached to the @@ -64,8 +64,6 @@ config SND_SOC_TEGRA30_I2S config SND_SOC_TEGRA_RT5640 tristate "SoC Audio support for Tegra boards using an RT5640 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_RT5640 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -74,8 +72,6 @@ config SND_SOC_TEGRA_RT5640 config SND_SOC_TEGRA_WM8753 tristate "SoC Audio support for Tegra boards using a WM8753 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_WM8753 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -84,8 +80,6 @@ config SND_SOC_TEGRA_WM8753 config SND_SOC_TEGRA_WM8903 tristate "SoC Audio support for Tegra boards using a WM8903 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_WM8903 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -94,7 +88,7 @@ config SND_SOC_TEGRA_WM8903 config SND_SOC_TEGRA_WM9712 tristate "SoC Audio support for Tegra boards using a WM9712 codec" - depends on SND_SOC_TEGRA && ARCH_TEGRA_2x_SOC && GPIOLIB + depends on SND_SOC_TEGRA && GPIOLIB select SND_SOC_TEGRA20_AC97 select SND_SOC_WM9712 help @@ -104,7 +98,6 @@ config SND_SOC_TEGRA_WM9712 config SND_SOC_TEGRA_TRIMSLICE tristate "SoC Audio support for TrimSlice board" depends on SND_SOC_TEGRA && I2C - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC select SND_SOC_TLV320AIC23_I2C help Say Y or M here if you want to add support for SoC audio on the @@ -113,7 +106,6 @@ config SND_SOC_TEGRA_TRIMSLICE config SND_SOC_TEGRA_ALC5632 tristate "SoC Audio support for Tegra boards using an ALC5632 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC select SND_SOC_ALC5632 help Say Y or M here if you want to add support for SoC audio on the @@ -122,8 +114,6 @@ config SND_SOC_TEGRA_ALC5632 config SND_SOC_TEGRA_MAX98090 tristate "SoC Audio support for Tegra boards using a MAX98090 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_MAX98090 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -132,8 +122,6 @@ config SND_SOC_TEGRA_MAX98090 config SND_SOC_TEGRA_RT5677 tristate "SoC Audio support for Tegra boards using a RT5677 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_RT5677 help Say Y or M here if you want to add support for SoC audio on Tegra @@ -142,8 +130,6 @@ config SND_SOC_TEGRA_RT5677 config SND_SOC_TEGRA_SGTL5000 tristate "SoC Audio support for Tegra boards using a SGTL5000 codec" depends on SND_SOC_TEGRA && I2C && GPIOLIB - select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC - select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC select SND_SOC_SGTL5000 help Say Y or M here if you want to add support for SoC audio on Tegra diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index f214a3fd0024..2329b72c93e3 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Tegra platform Support snd-soc-tegra-pcm-objs := tegra_pcm.o snd-soc-tegra-utils-objs += tegra_asoc_utils.o diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c index 8c10ae7982ba..43679aeeb12b 100644 --- a/sound/soc/tegra/tegra30_ahub.c +++ b/sound/soc/tegra/tegra30_ahub.c @@ -544,8 +544,8 @@ static int tegra30_ahub_probe(struct platform_device *pdev) soc_data->mod_list_mask)) continue; - rst = reset_control_get(&pdev->dev, - configlink_mods[i].rst_name); + rst = reset_control_get_exclusive(&pdev->dev, + configlink_mods[i].rst_name); if (IS_ERR(rst)) { dev_err(&pdev->dev, "Can't get reset %s\n", configlink_mods[i].rst_name); diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c index b2b279c96029..0b176ea24914 100644 --- a/sound/soc/tegra/tegra30_i2s.c +++ b/sound/soc/tegra/tegra30_i2s.c @@ -275,7 +275,7 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { +static const struct snd_soc_dai_ops tegra30_i2s_dai_ops = { .set_fmt = tegra30_i2s_set_fmt, .hw_params = tegra30_i2s_hw_params, .trigger = tegra30_i2s_trigger, diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 0509902512cc..5197d6b18cb6 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c @@ -124,18 +124,6 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_alc5632_card_remove(struct snd_soc_card *card) -{ - struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 1, - &tegra_alc5632_hp_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_alc5632_dai = { .name = "ALC5632", .stream_name = "ALC5632 PCM", @@ -150,7 +138,6 @@ static struct snd_soc_dai_link tegra_alc5632_dai = { static struct snd_soc_card snd_soc_tegra_alc5632 = { .name = "tegra-alc5632", .owner = THIS_MODULE, - .remove = tegra_alc5632_card_remove, .dai_link = &tegra_alc5632_dai, .num_links = 1, .controls = tegra_alc5632_controls, @@ -173,7 +160,6 @@ static int tegra_alc5632_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, alc5632); alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); diff --git a/sound/soc/tegra/tegra_max98090.c b/sound/soc/tegra/tegra_max98090.c index c34a54d6e812..cf142e2c7bd7 100644 --- a/sound/soc/tegra/tegra_max98090.c +++ b/sound/soc/tegra/tegra_max98090.c @@ -176,23 +176,6 @@ static int tegra_max98090_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_max98090_card_remove(struct snd_soc_card *card) -{ - struct tegra_max98090 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_max98090_hp_jack, 1, - &tegra_max98090_hp_jack_gpio); - } - - if (gpio_is_valid(machine->gpio_mic_det)) { - snd_soc_jack_free_gpios(&tegra_max98090_mic_jack, 1, - &tegra_max98090_mic_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_max98090_dai = { .name = "max98090", .stream_name = "max98090 PCM", @@ -206,7 +189,6 @@ static struct snd_soc_dai_link tegra_max98090_dai = { static struct snd_soc_card snd_soc_tegra_max98090 = { .name = "tegra-max98090", .owner = THIS_MODULE, - .remove = tegra_max98090_card_remove, .dai_link = &tegra_max98090_dai, .num_links = 1, .controls = tegra_max98090_controls, @@ -229,7 +211,6 @@ static int tegra_max98090_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c index 93a356802345..fc81b48aa9d6 100644 --- a/sound/soc/tegra/tegra_rt5640.c +++ b/sound/soc/tegra/tegra_rt5640.c @@ -126,18 +126,6 @@ static int tegra_rt5640_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_rt5640_card_remove(struct snd_soc_card *card) -{ - struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_rt5640_hp_jack, 1, - &tegra_rt5640_hp_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_rt5640_dai = { .name = "RT5640", .stream_name = "RT5640 PCM", @@ -151,7 +139,6 @@ static struct snd_soc_dai_link tegra_rt5640_dai = { static struct snd_soc_card snd_soc_tegra_rt5640 = { .name = "tegra-rt5640", .owner = THIS_MODULE, - .remove = tegra_rt5640_card_remove, .dai_link = &tegra_rt5640_dai, .num_links = 1, .controls = tegra_rt5640_controls, @@ -174,7 +161,6 @@ static int tegra_rt5640_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_hp_det = of_get_named_gpio_flags( diff --git a/sound/soc/tegra/tegra_rt5677.c b/sound/soc/tegra/tegra_rt5677.c index ebf58d0e0f10..0e4805c7b4ca 100644 --- a/sound/soc/tegra/tegra_rt5677.c +++ b/sound/soc/tegra/tegra_rt5677.c @@ -169,23 +169,6 @@ static int tegra_rt5677_asoc_init(struct snd_soc_pcm_runtime *rtd) return 0; } -static int tegra_rt5677_card_remove(struct snd_soc_card *card) -{ - struct tegra_rt5677 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_rt5677_hp_jack, 1, - &tegra_rt5677_hp_jack_gpio); - } - - if (gpio_is_valid(machine->gpio_mic_present)) { - snd_soc_jack_free_gpios(&tegra_rt5677_mic_jack, 1, - &tegra_rt5677_mic_jack_gpio); - } - - return 0; -} - static struct snd_soc_dai_link tegra_rt5677_dai = { .name = "RT5677", .stream_name = "RT5677 PCM", @@ -199,7 +182,6 @@ static struct snd_soc_dai_link tegra_rt5677_dai = { static struct snd_soc_card snd_soc_tegra_rt5677 = { .name = "tegra-rt5677", .owner = THIS_MODULE, - .remove = tegra_rt5677_card_remove, .dai_link = &tegra_rt5677_dai, .num_links = 1, .controls = tegra_rt5677_controls, @@ -222,7 +204,6 @@ static int tegra_rt5677_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); diff --git a/sound/soc/tegra/tegra_sgtl5000.c b/sound/soc/tegra/tegra_sgtl5000.c index 6dda01f69983..45a4aa9d2a47 100644 --- a/sound/soc/tegra/tegra_sgtl5000.c +++ b/sound/soc/tegra/tegra_sgtl5000.c @@ -124,7 +124,6 @@ static int tegra_sgtl5000_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); ret = snd_soc_of_parse_card_name(card, "nvidia,model"); diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c index d0ab0026a4cd..23a810e3bacc 100644 --- a/sound/soc/tegra/tegra_wm8753.c +++ b/sound/soc/tegra/tegra_wm8753.c @@ -132,7 +132,6 @@ static int tegra_wm8753_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); ret = snd_soc_of_parse_card_name(card, "nvidia,model"); diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index dbfb49298ae8..18bdae59a4df 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -203,12 +203,6 @@ static int tegra_wm8903_remove(struct snd_soc_card *card) snd_soc_get_pcm_runtime(card, card->dai_link[0].name); struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_codec *codec = codec_dai->codec; - struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - - if (gpio_is_valid(machine->gpio_hp_det)) { - snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1, - &tegra_wm8903_hp_jack_gpio); - } wm8903_mic_detect(codec, NULL, 0, 0); @@ -252,7 +246,6 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios", diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index c9cd22432627..864a3345972e 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c @@ -81,7 +81,6 @@ static int tegra_wm9712_driver_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); machine->codec = platform_device_alloc("wm9712-codec", -1); diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index c9dcad9bb931..99bcdd979eb2 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -127,7 +127,6 @@ static int tegra_snd_trimslice_probe(struct platform_device *pdev) return -ENOMEM; card->dev = &pdev->dev; - platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, trimslice); trimslice_tlv320aic23_dai.codec_of_node = of_parse_phandle(np, diff --git a/sound/soc/txx9/Makefile b/sound/soc/txx9/Makefile index 551f16c0c4f9..37ad833eb329 100644 --- a/sound/soc/txx9/Makefile +++ b/sound/soc/txx9/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Platform snd-soc-txx9aclc-objs := txx9aclc.o snd-soc-txx9aclc-ac97-objs := txx9aclc-ac97.o diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index 7912bf09dc4d..a2bb68fea5a3 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -271,7 +271,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) return 0; } -static struct snd_pcm_ops txx9aclc_pcm_ops = { +static const struct snd_pcm_ops txx9aclc_pcm_ops = { .open = txx9aclc_pcm_open, .close = txx9aclc_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -403,7 +403,7 @@ static int txx9aclc_pcm_remove(struct snd_soc_platform *platform) return 0; } -static struct snd_soc_platform_driver txx9aclc_soc_platform = { +static const struct snd_soc_platform_driver txx9aclc_soc_platform = { .probe = txx9aclc_pcm_probe, .remove = txx9aclc_pcm_remove, .ops = &txx9aclc_pcm_ops, diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile index cce0c11a4d86..e7d6de51b32b 100644 --- a/sound/soc/ux500/Makefile +++ b/sound/soc/ux500/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Ux500 Platform Support snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index ba9fc099cf67..070a6880980e 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -115,7 +115,6 @@ static int mop500_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n", __func__, mop500_card.name); - platform_set_drvdata(pdev, &mop500_card); snd_soc_card_set_drvdata(&mop500_card, NULL); diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index ec5152aa3f6e..625b72a5facd 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c @@ -707,7 +707,7 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops ux500_msp_dai_ops[] = { +static const struct snd_soc_dai_ops ux500_msp_dai_ops[] = { { .set_sysclk = ux500_msp_dai_set_dai_sysclk, .set_fmt = ux500_msp_dai_set_dai_fmt, diff --git a/sound/soc/zte/zx-i2s.c b/sound/soc/zte/zx-i2s.c index 8bbad1d72bc5..9a0565937d1f 100644 --- a/sound/soc/zte/zx-i2s.c +++ b/sound/soc/zte/zx-i2s.c @@ -357,7 +357,7 @@ static void zx_i2s_shutdown(struct snd_pcm_substream *substream, clk_disable_unprepare(zx_i2s->dai_pclk); } -static struct snd_soc_dai_ops zx_i2s_dai_ops = { +static const struct snd_soc_dai_ops zx_i2s_dai_ops = { .trigger = zx_i2s_trigger, .hw_params = zx_i2s_hw_params, .set_fmt = zx_i2s_set_fmt, diff --git a/sound/soc/zte/zx-spdif.c b/sound/soc/zte/zx-spdif.c index 9fa6463ce5d7..b143f9f682d2 100644 --- a/sound/soc/zte/zx-spdif.c +++ b/sound/soc/zte/zx-spdif.c @@ -264,7 +264,7 @@ static void zx_spdif_shutdown(struct snd_pcm_substream *substream, (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE \ | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops zx_spdif_dai_ops = { +static const struct snd_soc_dai_ops zx_spdif_dai_ops = { .trigger = zx_spdif_trigger, .startup = zx_spdif_startup, .shutdown = zx_spdif_shutdown, diff --git a/sound/soc/zte/zx-tdm.c b/sound/soc/zte/zx-tdm.c index bd632cc503b3..dc955272f58b 100644 --- a/sound/soc/zte/zx-tdm.c +++ b/sound/soc/zte/zx-tdm.c @@ -309,7 +309,7 @@ static void zx_tdm_shutdown(struct snd_pcm_substream *substream, clk_disable_unprepare(zx_tdm->dai_wclk); } -static struct snd_soc_dai_ops zx_tdm_dai_ops = { +static const struct snd_soc_dai_ops zx_tdm_dai_ops = { .trigger = zx_tdm_trigger, .hw_params = zx_tdm_hw_params, .set_fmt = zx_tdm_set_fmt, diff --git a/sound/sparc/Makefile b/sound/sparc/Makefile index 3cd89c67c2f2..e1f596571d7f 100644 --- a/sound/sparc/Makefile +++ b/sound/sparc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2002 by David S. Miller diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 35c1f6ae773f..56f17410fcea 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -666,7 +666,7 @@ static snd_pcm_uframes_t snd_amd7930_capture_pointer(struct snd_pcm_substream *s } /* Playback and capture have identical properties. */ -static struct snd_pcm_hardware snd_amd7930_pcm_hw = +static const struct snd_pcm_hardware snd_amd7930_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -733,7 +733,7 @@ static int snd_amd7930_hw_free(struct snd_pcm_substream *substream) return snd_pcm_lib_free_pages(substream); } -static struct snd_pcm_ops snd_amd7930_playback_ops = { +static const struct snd_pcm_ops snd_amd7930_playback_ops = { .open = snd_amd7930_playback_open, .close = snd_amd7930_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -744,7 +744,7 @@ static struct snd_pcm_ops snd_amd7930_playback_ops = { .pointer = snd_amd7930_playback_pointer, }; -static struct snd_pcm_ops snd_amd7930_capture_ops = { +static const struct snd_pcm_ops snd_amd7930_capture_ops = { .open = snd_amd7930_capture_open, .close = snd_amd7930_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 3d7d425fbd24..e73c962590eb 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1089,7 +1089,7 @@ static int snd_cs4231_probe(struct snd_cs4231 *chip) return 0; /* all things are ok.. */ } -static struct snd_pcm_hardware snd_cs4231_playback = { +static const struct snd_pcm_hardware snd_cs4231_playback = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1113,7 +1113,7 @@ static struct snd_pcm_hardware snd_cs4231_playback = { .periods_max = 1024, }; -static struct snd_pcm_hardware snd_cs4231_capture = { +static const struct snd_pcm_hardware snd_cs4231_capture = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID | @@ -1203,7 +1203,7 @@ static int snd_cs4231_capture_close(struct snd_pcm_substream *substream) * XXX the audio AUXIO register... */ -static struct snd_pcm_ops snd_cs4231_playback_ops = { +static const struct snd_pcm_ops snd_cs4231_playback_ops = { .open = snd_cs4231_playback_open, .close = snd_cs4231_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1214,7 +1214,7 @@ static struct snd_pcm_ops snd_cs4231_playback_ops = { .pointer = snd_cs4231_playback_pointer, }; -static struct snd_pcm_ops snd_cs4231_capture_ops = { +static const struct snd_pcm_ops snd_cs4231_capture_ops = { .open = snd_cs4231_capture_open, .close = snd_cs4231_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 52063b262667..abc7bd5055eb 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -1980,7 +1980,7 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id) /**************************************************************************** PCM Interface ****************************************************************************/ -static struct snd_pcm_hardware snd_dbri_pcm_hw = { +static const struct snd_pcm_hardware snd_dbri_pcm_hw = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -2213,7 +2213,7 @@ static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream) return ret; } -static struct snd_pcm_ops snd_dbri_ops = { +static const struct snd_pcm_ops snd_dbri_ops = { .open = snd_dbri_open, .close = snd_dbri_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/spi/Makefile b/sound/spi/Makefile index 026fb73f887f..a3834919b0f6 100644 --- a/sound/spi/Makefile +++ b/sound/spi/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for SPI drivers snd-at73c213-objs := at73c213.o diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index fac7e6eb9529..1ef52edeb538 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c @@ -322,7 +322,7 @@ snd_at73c213_pcm_pointer(struct snd_pcm_substream *substream) return pos; } -static struct snd_pcm_ops at73c213_playback_ops = { +static const struct snd_pcm_ops at73c213_playback_ops = { .open = snd_at73c213_pcm_open, .close = snd_at73c213_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/synth/Makefile b/sound/synth/Makefile index 11eb06ac2eca..b9f71d5dbc8c 100644 --- a/sound/synth/Makefile +++ b/sound/synth/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/synth/emux/Makefile b/sound/synth/emux/Makefile index d1bac923eb1b..ed28c81ac12e 100644 --- a/sound/synth/emux/Makefile +++ b/sound/synth/emux/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # Copyright (c) 2001 by Jaroslav Kysela diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c index 55579f6b8cb2..396c406d0f77 100644 --- a/sound/synth/emux/emux_seq.c +++ b/sound/synth/emux/emux_seq.c @@ -99,7 +99,7 @@ snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index) sprintf(tmpname, "%s Port %d", emu->name, i); p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS, 0, &pinfo); - if (p == NULL) { + if (!p) { snd_printk(KERN_ERR "can't create port\n"); return -ENOMEM; } @@ -144,13 +144,13 @@ snd_emux_create_port(struct snd_emux *emu, char *name, int i, type, cap; /* Allocate structures for this channel */ - if ((p = kzalloc(sizeof(*p), GFP_KERNEL)) == NULL) { - snd_printk(KERN_ERR "no memory\n"); + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) return NULL; - } - p->chset.channels = kcalloc(max_channels, sizeof(struct snd_midi_channel), GFP_KERNEL); - if (p->chset.channels == NULL) { - snd_printk(KERN_ERR "no memory\n"); + + p->chset.channels = kcalloc(max_channels, sizeof(*p->chset.channels), + GFP_KERNEL); + if (!p->chset.channels) { kfree(p); return NULL; } @@ -370,8 +370,8 @@ int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card) if (emu->midi_ports <= 0) return 0; - emu->vmidi = kcalloc(emu->midi_ports, sizeof(struct snd_rawmidi *), GFP_KERNEL); - if (emu->vmidi == NULL) + emu->vmidi = kcalloc(emu->midi_ports, sizeof(*emu->vmidi), GFP_KERNEL); + if (!emu->vmidi) return -ENOMEM; for (i = 0; i < emu->midi_ports; i++) { @@ -403,7 +403,7 @@ int snd_emux_delete_virmidi(struct snd_emux *emu) { int i; - if (emu->vmidi == NULL) + if (!emu->vmidi) return 0; for (i = 0; i < emu->midi_ports; i++) { diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index dcddfc354ba6..c7641cb50616 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c @@ -143,37 +143,32 @@ static int usb6fire_chip_probe(struct usb_interface *intf, chip->card = card; ret = usb6fire_comm_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = usb6fire_midi_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = usb6fire_pcm_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = usb6fire_control_init(chip); - if (ret < 0) { - usb6fire_chip_destroy(chip); - return ret; - } + if (ret < 0) + goto destroy_chip; ret = snd_card_register(card); if (ret < 0) { dev_err(&intf->dev, "cannot register card."); - usb6fire_chip_destroy(chip); - return ret; + goto destroy_chip; } usb_set_intfdata(intf, chip); return 0; + +destroy_chip: + usb6fire_chip_destroy(chip); + return ret; } static void usb6fire_chip_disconnect(struct usb_interface *intf) @@ -198,7 +193,7 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf) } } -static struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x0ccd, diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 36f4115eb1cd..224a6a5d1c0e 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -555,7 +555,7 @@ static snd_pcm_uframes_t usb6fire_pcm_pointer( return ret; } -static struct snd_pcm_ops pcm_ops = { +static const struct snd_pcm_ops pcm_ops = { .open = usb6fire_pcm_open, .close = usb6fire_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/usb/Makefile b/sound/usb/Makefile index 42cb33b94f6a..05440e2df8d9 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Makefile for ALSA # diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c index 2ff9d578753a..7371e5b06035 100644 --- a/sound/usb/bcd2000/bcd2000.c +++ b/sound/usb/bcd2000/bcd2000.c @@ -29,7 +29,7 @@ #define PREFIX "snd-bcd2000: " #define BUFSIZE 64 -static struct usb_device_id id_table[] = { +static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1397, 0x00bd) }, { }, }; diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 8f66ba730d69..fb1c1eac0b5e 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -338,7 +338,7 @@ unlock: } /* operators for both playback and capture */ -static struct snd_pcm_ops snd_usb_caiaq_ops = { +static const struct snd_pcm_ops snd_usb_caiaq_ops = { .open = snd_usb_caiaq_substream_open, .close = snd_usb_caiaq_substream_close, .ioctl = snd_pcm_lib_ioctl, @@ -722,7 +722,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) int i, frame; struct urb **urbs; struct usb_device *usb_dev = cdev->chip.dev; - struct device *dev = caiaqdev_to_dev(cdev); unsigned int pipe; pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? @@ -731,7 +730,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); if (!urbs) { - dev_err(dev, "unable to kmalloc() urbs, OOM!?\n"); *ret = -ENOMEM; return NULL; } @@ -746,7 +744,6 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) urbs[i]->transfer_buffer = kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); if (!urbs[i]->transfer_buffer) { - dev_err(dev, "unable to kmalloc() transfer buffer, OOM!?\n"); *ret = -ENOMEM; return urbs; } diff --git a/sound/usb/caiaq/audio.h b/sound/usb/caiaq/audio.h index bdf155300a8a..869bf6264d6a 100644 --- a/sound/usb/caiaq/audio.h +++ b/sound/usb/caiaq/audio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CAIAQ_AUDIO_H #define CAIAQ_AUDIO_H diff --git a/sound/usb/caiaq/control.h b/sound/usb/caiaq/control.h index 501c4883aef6..cb204fd45858 100644 --- a/sound/usb/caiaq/control.h +++ b/sound/usb/caiaq/control.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CAIAQ_CONTROL_H #define CAIAQ_CONTROL_H diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index b871ba407e4e..d8409d9ae55b 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -81,7 +81,7 @@ enum { DEPTH_32 = 3 }; -static struct usb_device_id snd_usb_id_table[] = { +static const struct usb_device_id snd_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = USB_VID_NATIVEINSTRUMENTS, @@ -469,10 +469,12 @@ static int init_card(struct snd_usb_caiaqdev *cdev) err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); if (err) - return err; + goto err_kill_urb; - if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) - return -ENODEV; + if (!wait_event_timeout(cdev->ep1_wait_queue, cdev->spec_received, HZ)) { + err = -ENODEV; + goto err_kill_urb; + } usb_string(usb_dev, usb_dev->descriptor.iManufacturer, cdev->vendor_name, CAIAQ_USB_STR_LEN); @@ -507,6 +509,10 @@ static int init_card(struct snd_usb_caiaqdev *cdev) setup_card(cdev); return 0; + + err_kill_urb: + usb_kill_urb(&cdev->ep1_in_urb); + return err; } static int snd_probe(struct usb_interface *intf, diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index ab0f7520a99b..50fea085765b 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CAIAQ_DEVICE_H #define CAIAQ_DEVICE_H diff --git a/sound/usb/caiaq/input.h b/sound/usb/caiaq/input.h index 6014e2713a60..c42891e7be88 100644 --- a/sound/usb/caiaq/input.h +++ b/sound/usb/caiaq/input.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CAIAQ_INPUT_H #define CAIAQ_INPUT_H diff --git a/sound/usb/caiaq/midi.h b/sound/usb/caiaq/midi.h index 60bf3442b283..a6ae0c22484d 100644 --- a/sound/usb/caiaq/midi.h +++ b/sound/usb/caiaq/midi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef CAIAQ_MIDI_H #define CAIAQ_MIDI_H diff --git a/sound/usb/card.c b/sound/usb/card.c index 6640277a725b..23d1d23aefec 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -221,6 +221,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) struct usb_interface_descriptor *altsd; void *control_header; int i, protocol; + int rest_bytes; /* find audiocontrol interface */ host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0]; @@ -235,6 +236,15 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) return -EINVAL; } + rest_bytes = (void *)(host_iface->extra + host_iface->extralen) - + control_header; + + /* just to be sure -- this shouldn't hit at all */ + if (rest_bytes <= 0) { + dev_err(&dev->dev, "invalid control header\n"); + return -EINVAL; + } + switch (protocol) { default: dev_warn(&dev->dev, @@ -245,11 +255,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) case UAC_VERSION_1: { struct uac1_ac_header_descriptor *h1 = control_header; + if (rest_bytes < sizeof(*h1)) { + dev_err(&dev->dev, "too short v1 buffer descriptor\n"); + return -EINVAL; + } + if (!h1->bInCollection) { dev_info(&dev->dev, "skipping empty audio interface (v1)\n"); return -EINVAL; } + if (rest_bytes < h1->bLength) { + dev_err(&dev->dev, "invalid buffer length (v1)\n"); + return -EINVAL; + } + if (h1->bLength < sizeof(*h1) + h1->bInCollection) { dev_err(&dev->dev, "invalid UAC_HEADER (v1)\n"); return -EINVAL; @@ -486,7 +506,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id) return false; } -static struct usb_device_id usb_audio_ids[]; /* defined below */ +static const struct usb_device_id usb_audio_ids[]; /* defined below */ /* look for the corresponding quirk */ static const struct snd_usb_audio_quirk * @@ -814,7 +834,7 @@ static int usb_audio_reset_resume(struct usb_interface *intf) #define usb_audio_reset_resume NULL #endif /* CONFIG_PM */ -static struct usb_device_id usb_audio_ids [] = { +static const struct usb_device_id usb_audio_ids [] = { #include "quirks-table.h" { .match_flags = (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS), .bInterfaceClass = USB_CLASS_AUDIO, diff --git a/sound/usb/card.h b/sound/usb/card.h index 111b0f009afa..ed87cc83eb47 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_CARD_H #define __USBAUDIO_CARD_H diff --git a/sound/usb/clock.h b/sound/usb/clock.h index d592e4a29856..87557cae1a0b 100644 --- a/sound/usb/clock.h +++ b/sound/usb/clock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_CLOCK_H #define __USBAUDIO_CLOCK_H diff --git a/sound/usb/debug.h b/sound/usb/debug.h index 58030176f008..7dd983c35001 100644 --- a/sound/usb/debug.h +++ b/sound/usb/debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_DEBUG_H #define __USBAUDIO_DEBUG_H diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 584f295d7c77..63a39d4fa8d8 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_ENDPOINT_H #define __USBAUDIO_ENDPOINT_H diff --git a/sound/usb/format.h b/sound/usb/format.h index 4b8a01129f24..8c3ff9ce0824 100644 --- a/sound/usb/format.h +++ b/sound/usb/format.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_FORMAT_H #define __USBAUDIO_FORMAT_H diff --git a/sound/usb/helper.h b/sound/usb/helper.h index 805c300dd004..4463e6d6dcb3 100644 --- a/sound/usb/helper.h +++ b/sound/usb/helper.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_HELPER_H #define __USBAUDIO_HELPER_H diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c index 33db205dd12b..175d8d6b7f59 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c @@ -513,7 +513,7 @@ static snd_pcm_uframes_t hiface_pcm_pointer(struct snd_pcm_substream *alsa_sub) return bytes_to_frames(alsa_sub->runtime, dma_offset); } -static struct snd_pcm_ops pcm_ops = { +static const struct snd_pcm_ops pcm_ops = { .open = hiface_pcm_open, .close = hiface_pcm_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/usb/line6/Makefile b/sound/usb/line6/Makefile index b8b3b2a543d8..4ba98eb32119 100644 --- a/sound/usb/line6/Makefile +++ b/sound/usb/line6/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-usb-line6-y := \ capture.o \ driver.o \ diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 0ff5a7d2e19f..c8f723c3a033 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -779,9 +779,10 @@ int line6_probe(struct usb_interface *interface, return 0; error: - if (line6->disconnect) - line6->disconnect(line6); - snd_card_free(card); + /* we can call disconnect callback here because no close-sync is + * needed yet at this point + */ + line6_disconnect(interface); return ret; } EXPORT_SYMBOL_GPL(line6_probe); diff --git a/sound/usb/line6/podhd.c b/sound/usb/line6/podhd.c index 956f847a96e4..451007c27743 100644 --- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -301,7 +301,8 @@ static void podhd_disconnect(struct usb_line6 *line6) intf = usb_ifnum_to_if(line6->usbdev, pod->line6.properties->ctrl_if); - usb_driver_release_interface(&podhd_driver, intf); + if (intf) + usb_driver_release_interface(&podhd_driver, intf); } } @@ -317,6 +318,9 @@ static int podhd_init(struct usb_line6 *line6, line6->disconnect = podhd_disconnect; + init_timer(&pod->startup_timer); + INIT_WORK(&pod->startup_work, podhd_startup_workqueue); + if (pod->line6.properties->capabilities & LINE6_CAP_CONTROL) { /* claim the data interface */ intf = usb_ifnum_to_if(line6->usbdev, @@ -358,8 +362,6 @@ static int podhd_init(struct usb_line6 *line6, } /* init device and delay registering */ - init_timer(&pod->startup_timer); - INIT_WORK(&pod->startup_work, podhd_startup_workqueue); podhd_startup(pod); return 0; } diff --git a/sound/usb/midi.c b/sound/usb/midi.c index a35f41467237..a92e2b2a91ec 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -242,8 +242,8 @@ static void dump_urb(const char *type, const u8 *data, int length) { snd_printk(KERN_DEBUG "%s packet: [", type); for (; length > 0; ++data, --length) - printk(" %02x", *data); - printk(" ]\n"); + printk(KERN_CONT " %02x", *data); + printk(KERN_CONT " ]\n"); } #else #define dump_urb(type, data, length) /* nothing */ @@ -2435,10 +2435,8 @@ int __snd_usbmidi_create(struct snd_card *card, err = -ENXIO; break; } - if (err < 0) { - kfree(umidi); - return err; - } + if (err < 0) + goto free_midi; /* create rawmidi device */ out_ports = 0; @@ -2448,23 +2446,25 @@ int __snd_usbmidi_create(struct snd_card *card, in_ports += hweight16(endpoints[i].in_cables); } err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); - if (err < 0) { - kfree(umidi); - return err; - } + if (err < 0) + goto free_midi; /* create endpoint/port structures */ if (quirk && quirk->type == QUIRK_MIDI_MIDIMAN) err = snd_usbmidi_create_endpoints_midiman(umidi, &endpoints[0]); else err = snd_usbmidi_create_endpoints(umidi, endpoints); - if (err < 0) { - return err; - } + if (err < 0) + goto exit; usb_autopm_get_interface_no_resume(umidi->iface); list_add_tail(&umidi->list, midi_list); return 0; + +free_midi: + kfree(umidi); +exit: + return err; } EXPORT_SYMBOL(__snd_usbmidi_create); diff --git a/sound/usb/midi.h b/sound/usb/midi.h index 5e25a3fd6c1d..8c38aec22999 100644 --- a/sound/usb/midi.h +++ b/sound/usb/midi.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBMIDI_H #define __USBMIDI_H diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index c19a5dd05631..386fbfd5c617 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c @@ -890,7 +890,7 @@ static snd_pcm_uframes_t playback_pcm_pointer(struct snd_pcm_substream *subs) return ua101_pcm_pointer(ua, &ua->playback); } -static struct snd_pcm_ops capture_pcm_ops = { +static const struct snd_pcm_ops capture_pcm_ops = { .open = capture_pcm_open, .close = capture_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -903,7 +903,7 @@ static struct snd_pcm_ops capture_pcm_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops playback_pcm_ops = { +static const struct snd_pcm_ops playback_pcm_ops = { .open = playback_pcm_open, .close = playback_pcm_close, .ioctl = snd_pcm_lib_ioctl, @@ -1366,7 +1366,7 @@ static void ua101_disconnect(struct usb_interface *interface) mutex_unlock(&devices_mutex); } -static struct usb_device_id ua101_ids[] = { +static const struct usb_device_id ua101_ids[] = { { USB_DEVICE(0x0582, 0x0044) }, /* UA-1000 high speed */ { USB_DEVICE(0x0582, 0x007d) }, /* UA-101 high speed */ { USB_DEVICE(0x0582, 0x008d) }, /* UA-101 full speed */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index e630813c5008..91bc8f18791e 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -318,12 +318,15 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, while (timeout-- > 0) { idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); - if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - validx, idx, buf, val_len) >= val_len) { + err = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, + validx, idx, buf, val_len); + if (err >= val_len) { *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); err = 0; goto out; + } else if (err == -ETIMEDOUT) { + goto out; } } usb_audio_dbg(chip, @@ -483,12 +486,15 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, while (timeout-- > 0) { idx = snd_usb_ctrl_intf(chip) | (cval->head.id << 8); - if (snd_usb_ctl_msg(chip->dev, - usb_sndctrlpipe(chip->dev, 0), request, - USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - validx, idx, buf, val_len) >= 0) { + err = snd_usb_ctl_msg(chip->dev, + usb_sndctrlpipe(chip->dev, 0), request, + USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, + validx, idx, buf, val_len); + if (err >= 0) { err = 0; goto out; + } else if (err == -ETIMEDOUT) { + goto out; } } usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", @@ -2228,6 +2234,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid) static void snd_usb_mixer_free(struct usb_mixer_interface *mixer) { + /* kill pending URBs */ + snd_usb_mixer_disconnect(mixer); + kfree(mixer->id_elems); if (mixer->urb) { kfree(mixer->urb->transfer_buffer); @@ -2578,8 +2587,13 @@ _error: void snd_usb_mixer_disconnect(struct usb_mixer_interface *mixer) { - usb_kill_urb(mixer->urb); - usb_kill_urb(mixer->rc_urb); + if (mixer->disconnected) + return; + if (mixer->urb) + usb_kill_urb(mixer->urb); + if (mixer->rc_urb) + usb_kill_urb(mixer->rc_urb); + mixer->disconnected = true; } #ifdef CONFIG_PM diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index 2b4b067646ab..ba27f7ade670 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBMIXER_H #define __USBMIXER_H @@ -22,6 +23,8 @@ struct usb_mixer_interface { struct urb *rc_urb; struct usb_ctrlrequest *rc_setup_packet; u8 rc_buffer[6]; + + bool disconnected; }; #define MAX_CHANNELS 16 /* max logical channels */ diff --git a/sound/usb/mixer_quirks.h b/sound/usb/mixer_quirks.h index 177c329cd4dd..b5abd328a361 100644 --- a/sound/usb/mixer_quirks.h +++ b/sound/usb/mixer_quirks.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef SND_USB_MIXER_QUIRKS_H #define SND_USB_MIXER_QUIRKS_H diff --git a/sound/usb/mixer_scarlett.h b/sound/usb/mixer_scarlett.h index 19c592ab0332..bbf063b79370 100644 --- a/sound/usb/mixer_scarlett.h +++ b/sound/usb/mixer_scarlett.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USB_MIXER_SCARLETT_H #define __USB_MIXER_SCARLETT_H diff --git a/sound/usb/mixer_us16x08.h b/sound/usb/mixer_us16x08.h index a6312fb0f962..56ff16c0698f 100644 --- a/sound/usb/mixer_us16x08.h +++ b/sound/usb/mixer_us16x08.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USB_MIXER_US16X08_H #define __USB_MIXER_US16X08_H diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 9aa5b1855481..b9c9a19f9588 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -857,7 +857,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) return ret; } -static struct snd_pcm_hardware snd_usb_hardware = +static const struct snd_pcm_hardware snd_usb_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | @@ -1690,7 +1690,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream return -EINVAL; } -static struct snd_pcm_ops snd_usb_playback_ops = { +static const struct snd_pcm_ops snd_usb_playback_ops = { .open = snd_usb_playback_open, .close = snd_usb_playback_close, .ioctl = snd_pcm_lib_ioctl, @@ -1703,7 +1703,7 @@ static struct snd_pcm_ops snd_usb_playback_ops = { .mmap = snd_pcm_lib_mmap_vmalloc, }; -static struct snd_pcm_ops snd_usb_capture_ops = { +static const struct snd_pcm_ops snd_usb_capture_ops = { .open = snd_usb_capture_open, .close = snd_usb_capture_close, .ioctl = snd_pcm_lib_ioctl, diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h index df7a003682ad..35740d5ef268 100644 --- a/sound/usb/pcm.h +++ b/sound/usb/pcm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_PCM_H #define __USBAUDIO_PCM_H diff --git a/sound/usb/power.h b/sound/usb/power.h index 48ee51dcb71e..b2e25f60c5a2 100644 --- a/sound/usb/power.h +++ b/sound/usb/power.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_POWER_H #define __USBAUDIO_POWER_H diff --git a/sound/usb/proc.h b/sound/usb/proc.h index a45b765e4cf1..72b1b2d28b44 100644 --- a/sound/usb/proc.h +++ b/sound/usb/proc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_PROC_H #define __USBAUDIO_PROC_H diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 5d2a63248b1d..20624320b753 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -146,10 +146,9 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, unsigned *rate_table = NULL; fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); - if (!fp) { - usb_audio_err(chip, "cannot memdup\n"); + if (!fp) return -ENOMEM; - } + INIT_LIST_HEAD(&fp->list); if (fp->nr_rates > MAX_NR_RATES) { kfree(fp); @@ -1138,6 +1137,9 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) case USB_ID(0x047F, 0x02F7): /* Plantronics BT-600 */ case USB_ID(0x047F, 0x0415): /* Plantronics BT-300 */ case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */ + case USB_ID(0x047F, 0xC022): /* Plantronics C310 */ + case USB_ID(0x047F, 0xC02F): /* Plantronics P610 */ + case USB_ID(0x047F, 0xC036): /* Plantronics C520-M */ case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ @@ -1352,6 +1354,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */ case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */ case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */ + case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ if (fp->altsetting == 2) return SNDRV_PCM_FMTBIT_DSD_U32_BE; break; @@ -1372,6 +1375,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, case 0x199: return SNDRV_PCM_FMTBIT_DSD_U32_LE; case 0x19b: + case 0x203: return SNDRV_PCM_FMTBIT_DSD_U32_BE; default: break; diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 192ff5ce9452..b90c8b7caab5 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_QUIRKS_H #define __USBAUDIO_QUIRKS_H diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 8e9548bc1f1a..d1776e5517ff 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -658,10 +658,8 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) continue; fp = kzalloc(sizeof(*fp), GFP_KERNEL); - if (! fp) { - dev_err(&dev->dev, "cannot malloc\n"); + if (!fp) return -ENOMEM; - } fp->iface = iface_no; fp->altsetting = altno; diff --git a/sound/usb/stream.h b/sound/usb/stream.h index c97f679fc84f..d92e18d5818f 100644 --- a/sound/usb/stream.h +++ b/sound/usb/stream.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USBAUDIO_STREAM_H #define __USBAUDIO_STREAM_H diff --git a/sound/usb/usx2y/Makefile b/sound/usb/usx2y/Makefile index 748933054b6c..cc4c2f1efab2 100644 --- a/sound/usb/usx2y/Makefile +++ b/sound/usb/usx2y/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 snd-usb-usx2y-objs := usbusx2y.o usX2Yhwdep.o usx2yhwdeppcm.o snd-usb-us122l-objs := us122l.o diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index a33e31b2fc2f..159da1f3924e 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c @@ -508,8 +508,7 @@ static bool us122l_create_card(struct snd_card *card) err = us122l_create_usbmidi(card); if (err < 0) { snd_printk(KERN_ERR "us122l_create_usbmidi error %i \n", err); - us122l_stop(us122l); - return false; + goto stop; } err = usb_stream_hwdep_new(card); if (err < 0) { @@ -518,10 +517,13 @@ static bool us122l_create_card(struct snd_card *card) list_for_each(p, &us122l->midi_list) snd_usbmidi_disconnect(p); - us122l_stop(us122l); - return false; + goto stop; } return true; + +stop: + us122l_stop(us122l); + return false; } static void snd_us122l_free(struct snd_card *card) @@ -736,7 +738,7 @@ unlock: return err; } -static struct usb_device_id snd_us122l_usb_id_table[] = { +static const struct usb_device_id snd_us122l_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x0644, diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h index 3e2a2d0041ee..34bea99d343c 100644 --- a/sound/usb/usx2y/us122l.h +++ b/sound/usb/usx2y/us122l.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef US122L_H #define US122L_H diff --git a/sound/usb/usx2y/usX2Yhwdep.h b/sound/usb/usx2y/usX2Yhwdep.h index c095d5bf1220..457199b5ed03 100644 --- a/sound/usb/usx2y/usX2Yhwdep.h +++ b/sound/usb/usx2y/usX2Yhwdep.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USX2YHWDEP_H #define USX2YHWDEP_H diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index bf618e1500ac..e229abd21652 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c @@ -191,7 +191,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk, } pg = get_order(read_size); - sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg); + sk->s = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO| + __GFP_NOWARN, pg); if (!sk->s) { snd_printk(KERN_WARNING "couldn't __get_free_pages()\n"); goto out; @@ -211,7 +212,8 @@ struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk, pg = get_order(write_size); sk->write_page = - (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO, pg); + (void *)__get_free_pages(GFP_KERNEL|__GFP_COMP|__GFP_ZERO| + __GFP_NOWARN, pg); if (!sk->write_page) { snd_printk(KERN_WARNING "couldn't __get_free_pages()\n"); usb_stream_free(sk); @@ -352,20 +354,22 @@ static int submit_urbs(struct usb_stream_kernel *sk, int err; prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb); err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "%i\n", err); - return err; - } + if (err < 0) + goto report_failure; + sk->idle_inurb = sk->completed_inurb; sk->completed_inurb = inurb; err = usb_submit_urb(sk->idle_outurb, GFP_ATOMIC); - if (err < 0) { - snd_printk(KERN_ERR "%i\n", err); - return err; - } + if (err < 0) + goto report_failure; + sk->idle_outurb = sk->completed_outurb; sk->completed_outurb = outurb; return 0; + +report_failure: + snd_printk(KERN_ERR "%i\n", err); + return err; } #ifdef DEBUG_LOOP_BACK @@ -625,9 +629,9 @@ static void i_capture_start(struct urb *urb) urb->iso_frame_desc[0].actual_length); for (pack = 1; pack < urb->number_of_packets; ++pack) { int l = urb->iso_frame_desc[pack].actual_length; - printk(" %i", l); + printk(KERN_CONT " %i", l); } - printk("\n"); + printk(KERN_CONT "\n"); } #endif if (!empty && s->state < usb_stream_sync1) diff --git a/sound/usb/usx2y/usb_stream.h b/sound/usb/usx2y/usb_stream.h index 90369001eab6..851358a8d709 100644 --- a/sound/usb/usx2y/usb_stream.h +++ b/sound/usb/usx2y/usb_stream.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __USB_STREAM_H #define __USB_STREAM_H diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index 91e0e2a4808c..4569c0efac0a 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -313,7 +313,7 @@ static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S) } -static struct usb_device_id snd_usX2Y_usb_id_table[] = { +static const struct usb_device_id snd_usX2Y_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x1604, diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h index 6ae6b0806938..e0f77172ce8f 100644 --- a/sound/usb/usx2y/usbusx2y.h +++ b/sound/usb/usx2y/usbusx2y.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef USBUSX2Y_H #define USBUSX2Y_H #include "../usbaudio.h" diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index dd40ca9d858a..f93b355756e6 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -419,10 +419,8 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs) if (is_playback && NULL == subs->tmpbuf) { /* allocate a temporary buffer for playback */ subs->tmpbuf = kcalloc(nr_of_packs(), subs->maxpacksize, GFP_KERNEL); - if (NULL == subs->tmpbuf) { - snd_printk(KERN_ERR "cannot malloc tmpbuf\n"); + if (!subs->tmpbuf) return -ENOMEM; - } } /* allocate and initialize data urbs */ for (i = 0; i < NRURBS; i++) { @@ -907,7 +905,7 @@ static int snd_usX2Y_pcm_close(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_usX2Y_pcm_ops = +static const struct snd_pcm_ops snd_usX2Y_pcm_ops = { .open = snd_usX2Y_pcm_open, .close = snd_usX2Y_pcm_close, @@ -949,10 +947,9 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint, for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; i <= SNDRV_PCM_STREAM_CAPTURE; ++i) { usX2Y_substream[i] = kzalloc(sizeof(struct snd_usX2Y_substream), GFP_KERNEL); - if (NULL == usX2Y_substream[i]) { - snd_printk(KERN_ERR "cannot malloc\n"); + if (!usX2Y_substream[i]) return -ENOMEM; - } + usX2Y_substream[i]->usX2Y = usX2Y(card); } diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index d51c7fd7835b..0d050528a4e1 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -587,7 +587,7 @@ static int snd_usX2Y_usbpcm_close(struct snd_pcm_substream *substream) } -static struct snd_pcm_ops snd_usX2Y_usbpcm_ops = +static const struct snd_pcm_ops snd_usX2Y_usbpcm_ops = { .open = snd_usX2Y_usbpcm_open, .close = snd_usX2Y_usbpcm_close, diff --git a/sound/usb/usx2y/usx2yhwdeppcm.h b/sound/usb/usx2y/usx2yhwdeppcm.h index 9c4fb84b2aa0..eb5a46466f0e 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.h +++ b/sound/usb/usx2y/usx2yhwdeppcm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define MAXPACK 50 #define MAXBUFFERMS 100 #define MAXSTRIDE 3 diff --git a/tools/Makefile b/tools/Makefile index 221e1ce78b06..c4f41ef9a7a7 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Some of the tools (perf) use same make variables # as in kernel build. export srctree= @@ -18,7 +19,6 @@ help: @echo ' iio - IIO tools' @echo ' kvm_stat - top-like utility for displaying kvm statistics' @echo ' leds - LEDs tools' - @echo ' lguest - a minimal 32-bit x86 hypervisor' @echo ' liblockdep - user-space wrapper for kernel locking-validator' @echo ' net - misc networking tools' @echo ' perf - Linux performance measurement and analysis tool' @@ -90,10 +90,10 @@ freefall: FORCE kvm_stat: FORCE $(call descend,kvm/$@) -all: acpi cgroup cpupower gpio hv firewire lguest liblockdep \ - perf selftests turbostat usb \ +all: acpi cgroup cpupower gpio hv firewire liblockdep \ + perf selftests spi turbostat usb \ virtio vm net x86_energy_perf_policy \ - tmon freefall objtool kvm_stat + tmon freefall iio objtool kvm_stat acpi_install: $(call descend,power/$(@:_install=),install) @@ -101,7 +101,7 @@ acpi_install: cpupower_install: $(call descend,power/$(@:_install=),install) -cgroup_install firewire_install gpio_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install: +cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install net_install objtool_install: $(call descend,$(@:_install=),install) liblockdep_install: @@ -123,7 +123,7 @@ kvm_stat_install: $(call descend,kvm/$(@:_install=),install) install: acpi_install cgroup_install cpupower_install gpio_install \ - hv_install firewire_install lguest_install liblockdep_install \ + hv_install firewire_install iio_install liblockdep_install \ perf_install selftests_install turbostat_install usb_install \ virtio_install vm_install net_install x86_energy_perf_policy_install \ tmon_install freefall_install objtool_install kvm_stat_install @@ -134,7 +134,7 @@ acpi_clean: cpupower_clean: $(call descend,power/cpupower,clean) -cgroup_clean hv_clean firewire_clean lguest_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean gpio_clean objtool_clean leds_clean: +cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean net_clean iio_clean gpio_clean objtool_clean leds_clean: $(call descend,$(@:_clean=),clean) liblockdep_clean: @@ -168,7 +168,7 @@ freefall_clean: build_clean: $(call descend,build,clean) -clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ +clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \ perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \ vm_clean net_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \ diff --git a/tools/accounting/Makefile b/tools/accounting/Makefile index 647c94a219bf..03687f19cbb1 100644 --- a/tools/accounting/Makefile +++ b/tools/accounting/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include diff --git a/tools/accounting/getdelays.c b/tools/accounting/getdelays.c index b5ca536e56a8..9f420d98b5fb 100644 --- a/tools/accounting/getdelays.c +++ b/tools/accounting/getdelays.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* getdelays.c * * Utility to get per-pid and per-tgid delay accounting statistics diff --git a/tools/arch/alpha/include/asm/barrier.h b/tools/arch/alpha/include/asm/barrier.h index 95df19c95482..da8d6457ed4f 100644 --- a/tools/arch/alpha/include/asm/barrier.h +++ b/tools/arch/alpha/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_LINUX_ASM_ALPHA_BARRIER_H #define __TOOLS_LINUX_ASM_ALPHA_BARRIER_H diff --git a/tools/arch/alpha/include/uapi/asm/bitsperlong.h b/tools/arch/alpha/include/uapi/asm/bitsperlong.h index ad57f7868203..6c5bf7d03f4e 100644 --- a/tools/arch/alpha/include/uapi/asm/bitsperlong.h +++ b/tools/arch/alpha/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_ALPHA_BITSPERLONG_H #define __ASM_ALPHA_BITSPERLONG_H diff --git a/tools/arch/alpha/include/uapi/asm/mman.h b/tools/arch/alpha/include/uapi/asm/mman.h index e38b64c82b97..c317d3e6867a 100644 --- a/tools/arch/alpha/include/uapi/asm/mman.h +++ b/tools/arch/alpha/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_ALPHA_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_ALPHA_UAPI_ASM_MMAN_FIX_H #define MADV_DODUMP 17 diff --git a/tools/arch/arc/include/uapi/asm/mman.h b/tools/arch/arc/include/uapi/asm/mman.h index aa3acd2aa9af..81f0f9bf0c25 100644 --- a/tools/arch/arc/include/uapi/asm/mman.h +++ b/tools/arch/arc/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h index 5e3c673fa3f4..1f57bbe82b6f 100644 --- a/tools/arch/arm/include/uapi/asm/kvm.h +++ b/tools/arch/arm/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 - Virtual Open Systems and Columbia University * Author: Christoffer Dall @@ -203,6 +204,14 @@ struct kvm_arch_memory_slot { #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff #define VGIC_LEVEL_INFO_LINE_LEVEL 0 +/* Device Control API on vcpu fd */ +#define KVM_ARM_VCPU_PMU_V3_CTRL 0 +#define KVM_ARM_VCPU_PMU_V3_IRQ 0 +#define KVM_ARM_VCPU_PMU_V3_INIT 1 +#define KVM_ARM_VCPU_TIMER_CTRL 1 +#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 +#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 + #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 #define KVM_DEV_ARM_ITS_SAVE_TABLES 1 #define KVM_DEV_ARM_ITS_RESTORE_TABLES 2 diff --git a/tools/arch/arm/include/uapi/asm/mman.h b/tools/arch/arm/include/uapi/asm/mman.h index 478f699f56fd..a6d46321e330 100644 --- a/tools/arch/arm/include/uapi/asm/mman.h +++ b/tools/arch/arm/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/arm/include/uapi/asm/perf_regs.h b/tools/arch/arm/include/uapi/asm/perf_regs.h index ce59448458b2..a3c046174e6b 100644 --- a/tools/arch/arm/include/uapi/asm/perf_regs.h +++ b/tools/arch/arm/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_ARM_PERF_REGS_H #define _ASM_ARM_PERF_REGS_H diff --git a/tools/arch/arm64/include/asm/barrier.h b/tools/arch/arm64/include/asm/barrier.h index a0483c8e0142..40bde6b23501 100644 --- a/tools/arch/arm64/include/asm/barrier.h +++ b/tools/arch/arm64/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_AARCH64_BARRIER_H #define _TOOLS_LINUX_ASM_AARCH64_BARRIER_H diff --git a/tools/arch/arm64/include/uapi/asm/bitsperlong.h b/tools/arch/arm64/include/uapi/asm/bitsperlong.h index fce9c2924fa3..485d60bee26c 100644 --- a/tools/arch/arm64/include/uapi/asm/bitsperlong.h +++ b/tools/arch/arm64/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012 ARM Ltd. * diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index 70eea2ecc663..51149ec75fe4 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (C) 2012,2013 - ARM Ltd * Author: Marc Zyngier @@ -232,6 +233,9 @@ struct kvm_arch_memory_slot { #define KVM_ARM_VCPU_PMU_V3_CTRL 0 #define KVM_ARM_VCPU_PMU_V3_IRQ 0 #define KVM_ARM_VCPU_PMU_V3_INIT 1 +#define KVM_ARM_VCPU_TIMER_CTRL 1 +#define KVM_ARM_VCPU_TIMER_IRQ_VTIMER 0 +#define KVM_ARM_VCPU_TIMER_IRQ_PTIMER 1 /* KVM_IRQ_LINE irq field index values */ #define KVM_ARM_IRQ_TYPE_SHIFT 24 diff --git a/tools/arch/arm64/include/uapi/asm/mman.h b/tools/arch/arm64/include/uapi/asm/mman.h index 70fd3113710a..2ee288e447ec 100644 --- a/tools/arch/arm64/include/uapi/asm/mman.h +++ b/tools/arch/arm64/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/arm64/include/uapi/asm/perf_regs.h b/tools/arch/arm64/include/uapi/asm/perf_regs.h index 172b8317ee49..d54daafa89e3 100644 --- a/tools/arch/arm64/include/uapi/asm/perf_regs.h +++ b/tools/arch/arm64/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_ARM64_PERF_REGS_H #define _ASM_ARM64_PERF_REGS_H diff --git a/tools/arch/frv/include/uapi/asm/bitsperlong.h b/tools/arch/frv/include/uapi/asm/bitsperlong.h index 6dc0bb0c13b2..76da34b10f59 100644 --- a/tools/arch/frv/include/uapi/asm/bitsperlong.h +++ b/tools/arch/frv/include/uapi/asm/bitsperlong.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/tools/arch/frv/include/uapi/asm/mman.h b/tools/arch/frv/include/uapi/asm/mman.h index 5be78ac12464..5bc900b0bc78 100644 --- a/tools/arch/frv/include/uapi/asm/mman.h +++ b/tools/arch/frv/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/h8300/include/asm/bitsperlong.h b/tools/arch/h8300/include/asm/bitsperlong.h index e140e46729ac..fa1508337ffc 100644 --- a/tools/arch/h8300/include/asm/bitsperlong.h +++ b/tools/arch/h8300/include/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_H8300_BITS_PER_LONG #define __ASM_H8300_BITS_PER_LONG diff --git a/tools/arch/h8300/include/uapi/asm/mman.h b/tools/arch/h8300/include/uapi/asm/mman.h index 9d9ac54d3c5a..be7bbe0528d1 100644 --- a/tools/arch/h8300/include/uapi/asm/mman.h +++ b/tools/arch/h8300/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/hexagon/include/uapi/asm/bitsperlong.h b/tools/arch/hexagon/include/uapi/asm/bitsperlong.h index 4a658151383d..5adca0d26913 100644 --- a/tools/arch/hexagon/include/uapi/asm/bitsperlong.h +++ b/tools/arch/hexagon/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/tools/arch/hexagon/include/uapi/asm/mman.h b/tools/arch/hexagon/include/uapi/asm/mman.h index 102f3fae6085..cd59ba932b3a 100644 --- a/tools/arch/hexagon/include/uapi/asm/mman.h +++ b/tools/arch/hexagon/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/ia64/include/asm/barrier.h b/tools/arch/ia64/include/asm/barrier.h index e4422b4b634e..d808ee0e77b5 100644 --- a/tools/arch/ia64/include/asm/barrier.h +++ b/tools/arch/ia64/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copied from the kernel sources to tools/: * diff --git a/tools/arch/ia64/include/uapi/asm/bitsperlong.h b/tools/arch/ia64/include/uapi/asm/bitsperlong.h index ec4db3c970b7..1146d55563db 100644 --- a/tools/arch/ia64/include/uapi/asm/bitsperlong.h +++ b/tools/arch/ia64/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_IA64_BITSPERLONG_H #define __ASM_IA64_BITSPERLONG_H diff --git a/tools/arch/ia64/include/uapi/asm/mman.h b/tools/arch/ia64/include/uapi/asm/mman.h index 1d6e5ac6442d..2a19bb1db4ab 100644 --- a/tools/arch/ia64/include/uapi/asm/mman.h +++ b/tools/arch/ia64/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/m32r/include/uapi/asm/bitsperlong.h b/tools/arch/m32r/include/uapi/asm/bitsperlong.h index 6dc0bb0c13b2..76da34b10f59 100644 --- a/tools/arch/m32r/include/uapi/asm/bitsperlong.h +++ b/tools/arch/m32r/include/uapi/asm/bitsperlong.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/tools/arch/m32r/include/uapi/asm/mman.h b/tools/arch/m32r/include/uapi/asm/mman.h index 1c29635bb73b..d19b82c9c290 100644 --- a/tools/arch/m32r/include/uapi/asm/mman.h +++ b/tools/arch/m32r/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/microblaze/include/uapi/asm/bitsperlong.h b/tools/arch/microblaze/include/uapi/asm/bitsperlong.h index 6dc0bb0c13b2..76da34b10f59 100644 --- a/tools/arch/microblaze/include/uapi/asm/bitsperlong.h +++ b/tools/arch/microblaze/include/uapi/asm/bitsperlong.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #include diff --git a/tools/arch/microblaze/include/uapi/asm/mman.h b/tools/arch/microblaze/include/uapi/asm/mman.h index 005cd50b50e1..f3f2103fd02c 100644 --- a/tools/arch/microblaze/include/uapi/asm/mman.h +++ b/tools/arch/microblaze/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/mips/include/asm/barrier.h b/tools/arch/mips/include/asm/barrier.h index 80f96f7556e3..0d1191523cd0 100644 --- a/tools/arch/mips/include/asm/barrier.h +++ b/tools/arch/mips/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_MIPS_BARRIER_H #define _TOOLS_LINUX_ASM_MIPS_BARRIER_H /* diff --git a/tools/arch/mips/include/uapi/asm/bitsperlong.h b/tools/arch/mips/include/uapi/asm/bitsperlong.h index 3e4c10a8e787..7268380d8d28 100644 --- a/tools/arch/mips/include/uapi/asm/bitsperlong.h +++ b/tools/arch/mips/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_MIPS_BITSPERLONG_H #define __ASM_MIPS_BITSPERLONG_H diff --git a/tools/arch/mips/include/uapi/asm/kvm.h b/tools/arch/mips/include/uapi/asm/kvm.h index 6985eb59b085..d2714cc1cd93 100644 --- a/tools/arch/mips/include/uapi/asm/kvm.h +++ b/tools/arch/mips/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive diff --git a/tools/arch/mips/include/uapi/asm/mman.h b/tools/arch/mips/include/uapi/asm/mman.h index c02052965d50..de2206883abc 100644 --- a/tools/arch/mips/include/uapi/asm/mman.h +++ b/tools/arch/mips/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_MIPS_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_MIPS_UAPI_ASM_MMAN_FIX_H #define MADV_DODUMP 17 diff --git a/tools/arch/mn10300/include/uapi/asm/mman.h b/tools/arch/mn10300/include/uapi/asm/mman.h index c1ea36d83acc..b9360639974f 100644 --- a/tools/arch/mn10300/include/uapi/asm/mman.h +++ b/tools/arch/mn10300/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/parisc/include/uapi/asm/bitsperlong.h b/tools/arch/parisc/include/uapi/asm/bitsperlong.h index e0a23c7bdd43..23ac7562927a 100644 --- a/tools/arch/parisc/include/uapi/asm/bitsperlong.h +++ b/tools/arch/parisc/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_PARISC_BITSPERLONG_H #define __ASM_PARISC_BITSPERLONG_H diff --git a/tools/arch/parisc/include/uapi/asm/mman.h b/tools/arch/parisc/include/uapi/asm/mman.h index 03d8d5b7ae7f..1bd78758bde9 100644 --- a/tools/arch/parisc/include/uapi/asm/mman.h +++ b/tools/arch/parisc/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_PARISC_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_PARISC_UAPI_ASM_MMAN_FIX_H #define MADV_DODUMP 70 @@ -36,9 +37,7 @@ #define PROT_READ 0x1 #define PROT_SEM 0x8 #define PROT_WRITE 0x2 -/* MADV_HWPOISON is undefined on parisc, fix it for perf */ #define MADV_HWPOISON 100 -/* MADV_SOFT_OFFLINE is undefined on parisc, fix it for perf */ #define MADV_SOFT_OFFLINE 101 /* MAP_32BIT is undefined on parisc, fix it for perf */ #define MAP_32BIT 0 diff --git a/tools/arch/powerpc/include/asm/barrier.h b/tools/arch/powerpc/include/asm/barrier.h index b23aee8e6d90..a634da05bc97 100644 --- a/tools/arch/powerpc/include/asm/barrier.h +++ b/tools/arch/powerpc/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copied from the kernel sources: * diff --git a/tools/arch/powerpc/include/uapi/asm/bitsperlong.h b/tools/arch/powerpc/include/uapi/asm/bitsperlong.h index 5f1659032c40..46ece3ecff31 100644 --- a/tools/arch/powerpc/include/uapi/asm/bitsperlong.h +++ b/tools/arch/powerpc/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_POWERPC_BITSPERLONG_H #define __ASM_POWERPC_BITSPERLONG_H diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h index 07fbeb927834..61d6049f4c1e 100644 --- a/tools/arch/powerpc/include/uapi/asm/kvm.h +++ b/tools/arch/powerpc/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as @@ -60,6 +61,12 @@ struct kvm_regs { #define KVM_SREGS_E_FSL_PIDn (1 << 0) /* PID1/PID2 */ +/* flags for kvm_run.flags */ +#define KVM_RUN_PPC_NMI_DISP_MASK (3 << 0) +#define KVM_RUN_PPC_NMI_DISP_FULLY_RECOV (1 << 0) +#define KVM_RUN_PPC_NMI_DISP_LIMITED_RECOV (2 << 0) +#define KVM_RUN_PPC_NMI_DISP_NOT_RECOV (3 << 0) + /* * Feature bits indicate which sections of the sregs struct are valid, * both in KVM_GET_SREGS and KVM_SET_SREGS. On KVM_SET_SREGS, registers diff --git a/tools/arch/powerpc/include/uapi/asm/mman.h b/tools/arch/powerpc/include/uapi/asm/mman.h index 761db43172fe..f33105bc5ca6 100644 --- a/tools/arch/powerpc/include/uapi/asm/mman.h +++ b/tools/arch/powerpc/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_POWERPC_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_POWERPC_UAPI_ASM_MMAN_FIX_H #define MAP_DENYWRITE 0x0800 diff --git a/tools/arch/powerpc/include/uapi/asm/perf_regs.h b/tools/arch/powerpc/include/uapi/asm/perf_regs.h index 6a93209748a1..9e52c86ccbd3 100644 --- a/tools/arch/powerpc/include/uapi/asm/perf_regs.h +++ b/tools/arch/powerpc/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_POWERPC_PERF_REGS_H #define _UAPI_ASM_POWERPC_PERF_REGS_H diff --git a/tools/arch/s390/include/asm/barrier.h b/tools/arch/s390/include/asm/barrier.h index f85141266b92..5030c99f47d2 100644 --- a/tools/arch/s390/include/asm/barrier.h +++ b/tools/arch/s390/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copied from the kernel sources: * diff --git a/tools/arch/s390/include/uapi/asm/bitsperlong.h b/tools/arch/s390/include/uapi/asm/bitsperlong.h index e351ea2ad43e..d2bb620119bf 100644 --- a/tools/arch/s390/include/uapi/asm/bitsperlong.h +++ b/tools/arch/s390/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_S390_BITSPERLONG_H #define __ASM_S390_BITSPERLONG_H diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h index 3dd2a1d308dd..9ad172dcd912 100644 --- a/tools/arch/s390/include/uapi/asm/kvm.h +++ b/tools/arch/s390/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __LINUX_KVM_S390_H #define __LINUX_KVM_S390_H /* @@ -28,6 +29,7 @@ #define KVM_DEV_FLIC_CLEAR_IO_IRQ 8 #define KVM_DEV_FLIC_AISM 9 #define KVM_DEV_FLIC_AIRQ_INJECT 10 +#define KVM_DEV_FLIC_AISM_ALL 11 /* * We can have up to 4*64k pending subchannels + 8 adapter interrupts, * as well as up to ASYNC_PF_PER_VCPU*KVM_MAX_VCPUS pfault done interrupts. @@ -53,6 +55,11 @@ struct kvm_s390_ais_req { __u16 mode; }; +struct kvm_s390_ais_all { + __u8 simm; + __u8 nimm; +}; + #define KVM_S390_IO_ADAPTER_MASK 1 #define KVM_S390_IO_ADAPTER_MAP 2 #define KVM_S390_IO_ADAPTER_UNMAP 3 @@ -70,6 +77,7 @@ struct kvm_s390_io_adapter_req { #define KVM_S390_VM_TOD 1 #define KVM_S390_VM_CRYPTO 2 #define KVM_S390_VM_CPU_MODEL 3 +#define KVM_S390_VM_MIGRATION 4 /* kvm attributes for mem_ctrl */ #define KVM_S390_VM_MEM_ENABLE_CMMA 0 @@ -81,6 +89,12 @@ struct kvm_s390_io_adapter_req { /* kvm attributes for KVM_S390_VM_TOD */ #define KVM_S390_VM_TOD_LOW 0 #define KVM_S390_VM_TOD_HIGH 1 +#define KVM_S390_VM_TOD_EXT 2 + +struct kvm_s390_vm_tod_clock { + __u8 epoch_idx; + __u64 tod; +}; /* kvm attributes for KVM_S390_VM_CPU_MODEL */ /* processor related attributes are r/w */ @@ -151,6 +165,11 @@ struct kvm_s390_vm_cpu_subfunc { #define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2 #define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3 +/* kvm attributes for migration mode */ +#define KVM_S390_VM_MIGRATION_STOP 0 +#define KVM_S390_VM_MIGRATION_START 1 +#define KVM_S390_VM_MIGRATION_STATUS 2 + /* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs { /* general purpose regs for s390 */ diff --git a/tools/arch/s390/include/uapi/asm/kvm_perf.h b/tools/arch/s390/include/uapi/asm/kvm_perf.h index 397282727e21..c36c97ffdc6f 100644 --- a/tools/arch/s390/include/uapi/asm/kvm_perf.h +++ b/tools/arch/s390/include/uapi/asm/kvm_perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Definitions for perf-kvm on s390 * diff --git a/tools/arch/s390/include/uapi/asm/mman.h b/tools/arch/s390/include/uapi/asm/mman.h index b03dea9e1f56..4ec32e4251a4 100644 --- a/tools/arch/s390/include/uapi/asm/mman.h +++ b/tools/arch/s390/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/s390/include/uapi/asm/sie.h b/tools/arch/s390/include/uapi/asm/sie.h index 3ac634368939..6ca1e68d7103 100644 --- a/tools/arch/s390/include/uapi/asm/sie.h +++ b/tools/arch/s390/include/uapi/asm/sie.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_ASM_S390_SIE_H #define _UAPI_ASM_S390_SIE_H diff --git a/tools/arch/score/include/uapi/asm/bitsperlong.h b/tools/arch/score/include/uapi/asm/bitsperlong.h index 86ff337aa459..df48f2717da2 100644 --- a/tools/arch/score/include/uapi/asm/bitsperlong.h +++ b/tools/arch/score/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_SCORE_BITSPERLONG_H #define _ASM_SCORE_BITSPERLONG_H diff --git a/tools/arch/score/include/uapi/asm/mman.h b/tools/arch/score/include/uapi/asm/mman.h index 2f8fb89944fd..b4bd195a8586 100644 --- a/tools/arch/score/include/uapi/asm/mman.h +++ b/tools/arch/score/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/sh/include/asm/barrier.h b/tools/arch/sh/include/asm/barrier.h index c18fd7599b97..bde5221af282 100644 --- a/tools/arch/sh/include/asm/barrier.h +++ b/tools/arch/sh/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copied from the kernel sources: * diff --git a/tools/arch/sh/include/uapi/asm/mman.h b/tools/arch/sh/include/uapi/asm/mman.h index 26504f6f060e..88c0e2930c47 100644 --- a/tools/arch/sh/include/uapi/asm/mman.h +++ b/tools/arch/sh/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H #include diff --git a/tools/arch/sparc/include/asm/barrier.h b/tools/arch/sparc/include/asm/barrier.h index 8c017b3b1391..95d1618465a6 100644 --- a/tools/arch/sparc/include/asm/barrier.h +++ b/tools/arch/sparc/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ___TOOLS_LINUX_ASM_SPARC_BARRIER_H #define ___TOOLS_LINUX_ASM_SPARC_BARRIER_H #if defined(__sparc__) && defined(__arch64__) diff --git a/tools/arch/sparc/include/asm/barrier_32.h b/tools/arch/sparc/include/asm/barrier_32.h index c5eadd0a7233..cc19ed1dde0b 100644 --- a/tools/arch/sparc/include/asm/barrier_32.h +++ b/tools/arch/sparc/include/asm/barrier_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_PERF_SPARC_BARRIER_H #define __TOOLS_PERF_SPARC_BARRIER_H diff --git a/tools/arch/sparc/include/asm/barrier_64.h b/tools/arch/sparc/include/asm/barrier_64.h index 9a7d7322c3f7..ba61344287d5 100644 --- a/tools/arch/sparc/include/asm/barrier_64.h +++ b/tools/arch/sparc/include/asm/barrier_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_LINUX_SPARC64_BARRIER_H #define __TOOLS_LINUX_SPARC64_BARRIER_H diff --git a/tools/arch/sparc/include/uapi/asm/bitsperlong.h b/tools/arch/sparc/include/uapi/asm/bitsperlong.h index b62dd907d7c3..3b4e61740b75 100644 --- a/tools/arch/sparc/include/uapi/asm/bitsperlong.h +++ b/tools/arch/sparc/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_ALPHA_BITSPERLONG_H #define __ASM_ALPHA_BITSPERLONG_H diff --git a/tools/arch/sparc/include/uapi/asm/mman.h b/tools/arch/sparc/include/uapi/asm/mman.h index 8640525de991..38920eed8cbf 100644 --- a/tools/arch/sparc/include/uapi/asm/mman.h +++ b/tools/arch/sparc/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_SPARC_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_SPARC_UAPI_ASM_MMAN_FIX_H #define MAP_DENYWRITE 0x0800 diff --git a/tools/arch/tile/include/asm/barrier.h b/tools/arch/tile/include/asm/barrier.h index 7d3692c3d4ac..7ad02a591b43 100644 --- a/tools/arch/tile/include/asm/barrier.h +++ b/tools/arch/tile/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_TILE_BARRIER_H #define _TOOLS_LINUX_ASM_TILE_BARRIER_H /* diff --git a/tools/arch/tile/include/uapi/asm/bitsperlong.h b/tools/arch/tile/include/uapi/asm/bitsperlong.h index 58c771f2af2f..57cca78c0fbb 100644 --- a/tools/arch/tile/include/uapi/asm/bitsperlong.h +++ b/tools/arch/tile/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright 2010 Tilera Corporation. All Rights Reserved. * diff --git a/tools/arch/tile/include/uapi/asm/mman.h b/tools/arch/tile/include/uapi/asm/mman.h index 7116c4b928b3..65ec92925c6c 100644 --- a/tools/arch/tile/include/uapi/asm/mman.h +++ b/tools/arch/tile/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_TILE_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_TILE_UAPI_ASM_MMAN_FIX_H #define MAP_DENYWRITE 0x0800 diff --git a/tools/arch/x86/include/asm/atomic.h b/tools/arch/x86/include/asm/atomic.h index 328eeceec709..7d8c3261a50d 100644 --- a/tools/arch/x86/include/asm/atomic.h +++ b/tools/arch/x86/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_X86_ATOMIC_H #define _TOOLS_LINUX_ASM_X86_ATOMIC_H diff --git a/tools/arch/x86/include/asm/barrier.h b/tools/arch/x86/include/asm/barrier.h index f366d8e550e4..8774dee27471 100644 --- a/tools/arch/x86/include/asm/barrier.h +++ b/tools/arch/x86/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_X86_BARRIER_H #define _TOOLS_LINUX_ASM_X86_BARRIER_H diff --git a/tools/arch/x86/include/asm/cmpxchg.h b/tools/arch/x86/include/asm/cmpxchg.h index f5253260f3cc..0ed9ca2766ad 100644 --- a/tools/arch/x86/include/asm/cmpxchg.h +++ b/tools/arch/x86/include/asm/cmpxchg.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TOOLS_ASM_X86_CMPXCHG_H #define TOOLS_ASM_X86_CMPXCHG_H diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index 2701e5f8145b..793690fbda36 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_CPUFEATURES_H #define _ASM_X86_CPUFEATURES_H @@ -177,7 +178,7 @@ #define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ #define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ #define X86_FEATURE_PTSC ( 6*32+27) /* performance time-stamp counter */ -#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ +#define X86_FEATURE_PERFCTR_LLC ( 6*32+28) /* Last Level Cache performance counter extensions */ #define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ /* @@ -196,6 +197,7 @@ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ +#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ @@ -286,6 +288,8 @@ #define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */ #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ +#define X86_FEATURE_V_VMSAVE_VMLOAD (15*32+15) /* Virtual VMSAVE VMLOAD */ +#define X86_FEATURE_VGIF (15*32+16) /* Virtual GIF */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ #define X86_FEATURE_AVX512VBMI (16*32+ 1) /* AVX512 Vector Bit Manipulation instructions*/ diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h index 5dff775af7cd..c10c9128f54e 100644 --- a/tools/arch/x86/include/asm/disabled-features.h +++ b/tools/arch/x86/include/asm/disabled-features.h @@ -21,11 +21,13 @@ # define DISABLE_K6_MTRR (1<<(X86_FEATURE_K6_MTRR & 31)) # define DISABLE_CYRIX_ARR (1<<(X86_FEATURE_CYRIX_ARR & 31)) # define DISABLE_CENTAUR_MCR (1<<(X86_FEATURE_CENTAUR_MCR & 31)) +# define DISABLE_PCID 0 #else # define DISABLE_VME 0 # define DISABLE_K6_MTRR 0 # define DISABLE_CYRIX_ARR 0 # define DISABLE_CENTAUR_MCR 0 +# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31)) #endif /* CONFIG_X86_64 */ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS @@ -49,7 +51,7 @@ #define DISABLED_MASK1 0 #define DISABLED_MASK2 0 #define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR) -#define DISABLED_MASK4 0 +#define DISABLED_MASK4 (DISABLE_PCID) #define DISABLED_MASK5 0 #define DISABLED_MASK6 0 #define DISABLED_MASK7 0 diff --git a/tools/arch/x86/include/asm/rmwcc.h b/tools/arch/x86/include/asm/rmwcc.h index a6669bc06939..dc90c0c2fae3 100644 --- a/tools/arch/x86/include/asm/rmwcc.h +++ b/tools/arch/x86/include/asm/rmwcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_X86_RMWcc #define _TOOLS_LINUX_ASM_X86_RMWcc diff --git a/tools/arch/x86/include/asm/unistd_32.h b/tools/arch/x86/include/asm/unistd_32.h index 88b3f8c8920c..60a89dba01b6 100644 --- a/tools/arch/x86/include/asm/unistd_32.h +++ b/tools/arch/x86/include/asm/unistd_32.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __NR_perf_event_open # define __NR_perf_event_open 336 #endif @@ -10,3 +11,6 @@ #ifndef __NR_getcpu # define __NR_getcpu 318 #endif +#ifndef __NR_setns +# define __NR_setns 346 +#endif diff --git a/tools/arch/x86/include/asm/unistd_64.h b/tools/arch/x86/include/asm/unistd_64.h index fbdb70ee8837..cb52a3a8b8fc 100644 --- a/tools/arch/x86/include/asm/unistd_64.h +++ b/tools/arch/x86/include/asm/unistd_64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __NR_perf_event_open # define __NR_perf_event_open 298 #endif @@ -10,3 +11,6 @@ #ifndef __NR_getcpu # define __NR_getcpu 309 #endif +#ifndef __NR_setns +#define __NR_setns 308 +#endif diff --git a/tools/arch/x86/include/uapi/asm/bitsperlong.h b/tools/arch/x86/include/uapi/asm/bitsperlong.h index 6e23c543cd80..f8a92e0009d6 100644 --- a/tools/arch/x86/include/uapi/asm/bitsperlong.h +++ b/tools/arch/x86/include/uapi/asm/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_X86_BITSPERLONG_H #define __ASM_X86_BITSPERLONG_H diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h index c2824d02ba37..f3a960488eae 100644 --- a/tools/arch/x86/include/uapi/asm/kvm.h +++ b/tools/arch/x86/include/uapi/asm/kvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_KVM_H #define _ASM_X86_KVM_H diff --git a/tools/arch/x86/include/uapi/asm/kvm_perf.h b/tools/arch/x86/include/uapi/asm/kvm_perf.h index 3bb964f88aa1..125cf5cdf6c5 100644 --- a/tools/arch/x86/include/uapi/asm/kvm_perf.h +++ b/tools/arch/x86/include/uapi/asm/kvm_perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_KVM_PERF_H #define _ASM_X86_KVM_PERF_H diff --git a/tools/arch/x86/include/uapi/asm/mman.h b/tools/arch/x86/include/uapi/asm/mman.h index b73c1af8b1dd..8449778de2ed 100644 --- a/tools/arch/x86/include/uapi/asm/mman.h +++ b/tools/arch/x86/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_X86_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_X86_UAPI_ASM_MMAN_FIX_H #define MAP_32BIT 0x40 diff --git a/tools/arch/x86/include/uapi/asm/perf_regs.h b/tools/arch/x86/include/uapi/asm/perf_regs.h index 3f2207bfd17b..f3329cabce5c 100644 --- a/tools/arch/x86/include/uapi/asm/perf_regs.h +++ b/tools/arch/x86/include/uapi/asm/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _ASM_X86_PERF_REGS_H #define _ASM_X86_PERF_REGS_H diff --git a/tools/arch/x86/include/uapi/asm/svm.h b/tools/arch/x86/include/uapi/asm/svm.h index 3725e145aa58..a9731f8a480f 100644 --- a/tools/arch/x86/include/uapi/asm/svm.h +++ b/tools/arch/x86/include/uapi/asm/svm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__SVM_H #define _UAPI__SVM_H diff --git a/tools/arch/x86/include/uapi/asm/unistd.h b/tools/arch/x86/include/uapi/asm/unistd.h new file mode 100644 index 000000000000..30d7d04d72d6 --- /dev/null +++ b/tools/arch/x86/include/uapi/asm/unistd.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_ASM_X86_UNISTD_H +#define _UAPI_ASM_X86_UNISTD_H + +/* x32 syscall flag bit */ +#define __X32_SYSCALL_BIT 0x40000000 + +#ifndef __KERNEL__ +# ifdef __i386__ +# include +# elif defined(__ILP32__) +# include +# else +# include +# endif +#endif + +#endif /* _UAPI_ASM_X86_UNISTD_H */ diff --git a/tools/arch/x86/include/uapi/asm/vmx.h b/tools/arch/x86/include/uapi/asm/vmx.h index 690a2dcf4078..f0b0c90dd398 100644 --- a/tools/arch/x86/include/uapi/asm/vmx.h +++ b/tools/arch/x86/include/uapi/asm/vmx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * vmx.h: VMX Architecture related definitions * Copyright (c) 2004, Intel Corporation. diff --git a/tools/arch/x86/lib/memcpy_64.S b/tools/arch/x86/lib/memcpy_64.S index 98dcc112b363..9a53a06e5a3e 100644 --- a/tools/arch/x86/lib/memcpy_64.S +++ b/tools/arch/x86/lib/memcpy_64.S @@ -4,6 +4,7 @@ #include #include #include +#include /* * We build a jump to memcpy_orig by default which gets NOPped out on @@ -40,6 +41,8 @@ ENTRY(memcpy) ret ENDPROC(memcpy) ENDPROC(__memcpy) +EXPORT_SYMBOL(memcpy) +EXPORT_SYMBOL(__memcpy) /* * memcpy_erms() - enhanced fast string memcpy. This is faster and @@ -274,6 +277,7 @@ ENTRY(memcpy_mcsafe_unrolled) xorq %rax, %rax ret ENDPROC(memcpy_mcsafe_unrolled) +EXPORT_SYMBOL_GPL(memcpy_mcsafe_unrolled) .section .fixup, "ax" /* Return -EFAULT for any failure */ diff --git a/tools/arch/x86/lib/memset_64.S b/tools/arch/x86/lib/memset_64.S index e1229ecd2a82..f8f3dc0a6690 100644 --- a/tools/arch/x86/lib/memset_64.S +++ b/tools/arch/x86/lib/memset_64.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright 2002 Andi Kleen, SuSE Labs */ #include diff --git a/tools/arch/xtensa/include/uapi/asm/mman.h b/tools/arch/xtensa/include/uapi/asm/mman.h index 4453195c450c..34dde6f44dae 100644 --- a/tools/arch/xtensa/include/uapi/asm/mman.h +++ b/tools/arch/xtensa/include/uapi/asm/mman.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef TOOLS_ARCH_XTENSA_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_XTENSA_UAPI_ASM_MMAN_FIX_H #define MADV_DODUMP 17 diff --git a/tools/build/Makefile b/tools/build/Makefile index 477f00eda591..5eb4b5ad79cb 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ifeq ($(srctree),) srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index c46b20e4ad87..cd72016c3cfa 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ### # Main build makefile. # diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 523911f316ce..c71a05b9c984 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -64,7 +64,8 @@ FEATURE_TESTS_BASIC := \ get_cpuid \ bpf \ sched_getcpu \ - sdt + sdt \ + setns # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list # of all feature tests diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index e35e4e5ad192..96982640fbf8 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 FILES= \ test-all.bin \ test-backtrace.bin \ @@ -49,7 +50,8 @@ FILES= \ test-sdt.bin \ test-cxx.bin \ test-jvmti.bin \ - test-sched_getcpu.bin + test-sched_getcpu.bin \ + test-setns.bin FILES := $(addprefix $(OUTPUT),$(FILES)) @@ -95,6 +97,9 @@ $(OUTPUT)test-glibc.bin: $(OUTPUT)test-sched_getcpu.bin: $(BUILD) +$(OUTPUT)test-setns.bin: + $(BUILD) + DWARFLIBS := -ldw ifeq ($(findstring -static,${LDFLAGS}),-static) DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index cc6c7c01f4ca..4112702e4aed 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * test-all.c: Try to build all the main testcases at once. * @@ -153,6 +154,10 @@ # include "test-sdt.c" #undef main +#define main main_test_setns +# include "test-setns.c" +#undef main + int main(int argc, char *argv[]) { main_test_libpython(); @@ -188,6 +193,7 @@ int main(int argc, char *argv[]) main_test_libcrypto(); main_test_sched_getcpu(); main_test_sdt(); + main_test_setns(); return 0; } diff --git a/tools/build/feature/test-backtrace.c b/tools/build/feature/test-backtrace.c index 7124aa1dc8fb..e9ddd27c69c3 100644 --- a/tools/build/feature/test-backtrace.c +++ b/tools/build/feature/test-backtrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-bionic.c b/tools/build/feature/test-bionic.c index eac24e9513eb..4bcc9776504c 100644 --- a/tools/build/feature/test-bionic.c +++ b/tools/build/feature/test-bionic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-bpf.c b/tools/build/feature/test-bpf.c index da2172ff9662..82070eadfc07 100644 --- a/tools/build/feature/test-bpf.c +++ b/tools/build/feature/test-bpf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/build/feature/test-clang.cpp b/tools/build/feature/test-clang.cpp index e23c1b1f1b91..a2b3f092d2f0 100644 --- a/tools/build/feature/test-clang.cpp +++ b/tools/build/feature/test-clang.cpp @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "clang/Basic/VirtualFileSystem.h" #include "clang/Driver/Driver.h" #include "clang/Frontend/TextDiagnosticPrinter.h" diff --git a/tools/build/feature/test-compile.c b/tools/build/feature/test-compile.c index c54e6551ae4c..9821b8271dee 100644 --- a/tools/build/feature/test-compile.c +++ b/tools/build/feature/test-compile.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) { diff --git a/tools/build/feature/test-cplus-demangle.c b/tools/build/feature/test-cplus-demangle.c index 610c686e0009..2ba56474ab71 100644 --- a/tools/build/feature/test-cplus-demangle.c +++ b/tools/build/feature/test-cplus-demangle.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 extern int printf(const char *format, ...); extern char *cplus_demangle(const char *, int); diff --git a/tools/build/feature/test-cxx.cpp b/tools/build/feature/test-cxx.cpp index b1dee9a31d6c..396aaedd2418 100644 --- a/tools/build/feature/test-cxx.cpp +++ b/tools/build/feature/test-cxx.cpp @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-dwarf.c b/tools/build/feature/test-dwarf.c index 3fc1801ce4a9..8d474bd7371b 100644 --- a/tools/build/feature/test-dwarf.c +++ b/tools/build/feature/test-dwarf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/build/feature/test-dwarf_getlocations.c b/tools/build/feature/test-dwarf_getlocations.c index 70162699dd43..78fb4a1fa68c 100644 --- a/tools/build/feature/test-dwarf_getlocations.c +++ b/tools/build/feature/test-dwarf_getlocations.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-get_cpuid.c b/tools/build/feature/test-get_cpuid.c index d7a2c407130d..bb4f065f28a6 100644 --- a/tools/build/feature/test-get_cpuid.c +++ b/tools/build/feature/test-get_cpuid.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-glibc.c b/tools/build/feature/test-glibc.c index 9367f7586676..9ab8e90e7b88 100644 --- a/tools/build/feature/test-glibc.c +++ b/tools/build/feature/test-glibc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #if !defined(__UCLIBC__) diff --git a/tools/build/feature/test-gtk2-infobar.c b/tools/build/feature/test-gtk2-infobar.c index 397b4646d066..b1b716dd5733 100644 --- a/tools/build/feature/test-gtk2-infobar.c +++ b/tools/build/feature/test-gtk2-infobar.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include #pragma GCC diagnostic error "-Wstrict-prototypes" diff --git a/tools/build/feature/test-gtk2.c b/tools/build/feature/test-gtk2.c index 6bd80e509439..2aaf4bfc2055 100644 --- a/tools/build/feature/test-gtk2.c +++ b/tools/build/feature/test-gtk2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #pragma GCC diagnostic ignored "-Wstrict-prototypes" #include #pragma GCC diagnostic error "-Wstrict-prototypes" diff --git a/tools/build/feature/test-jvmti.c b/tools/build/feature/test-jvmti.c index 1c665f09b9d6..5cf31192f204 100644 --- a/tools/build/feature/test-jvmti.c +++ b/tools/build/feature/test-jvmti.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libaudit.c b/tools/build/feature/test-libaudit.c index afc019f08641..f5b0863fa1ec 100644 --- a/tools/build/feature/test-libaudit.c +++ b/tools/build/feature/test-libaudit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include extern int printf(const char *format, ...); diff --git a/tools/build/feature/test-libbabeltrace.c b/tools/build/feature/test-libbabeltrace.c index 9cf802a04885..10bb69d55694 100644 --- a/tools/build/feature/test-libbabeltrace.c +++ b/tools/build/feature/test-libbabeltrace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libbfd.c b/tools/build/feature/test-libbfd.c index 24059907e990..afa46b0465cd 100644 --- a/tools/build/feature/test-libbfd.c +++ b/tools/build/feature/test-libbfd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include extern int printf(const char *format, ...); diff --git a/tools/build/feature/test-libcrypto.c b/tools/build/feature/test-libcrypto.c index bd79dc7f28d3..a98174e0569c 100644 --- a/tools/build/feature/test-libcrypto.c +++ b/tools/build/feature/test-libcrypto.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libdw-dwarf-unwind.c b/tools/build/feature/test-libdw-dwarf-unwind.c index f676a3ff442a..ed03d9505609 100644 --- a/tools/build/feature/test-libdw-dwarf-unwind.c +++ b/tools/build/feature/test-libdw-dwarf-unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include diff --git a/tools/build/feature/test-libelf-gelf_getnote.c b/tools/build/feature/test-libelf-gelf_getnote.c index d78cf4d5271f..075d062fe841 100644 --- a/tools/build/feature/test-libelf-gelf_getnote.c +++ b/tools/build/feature/test-libelf-gelf_getnote.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libelf-getphdrnum.c b/tools/build/feature/test-libelf-getphdrnum.c index d710459306c3..96a7f8d30a59 100644 --- a/tools/build/feature/test-libelf-getphdrnum.c +++ b/tools/build/feature/test-libelf-getphdrnum.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-libelf-getshdrstrndx.c b/tools/build/feature/test-libelf-getshdrstrndx.c index f0c3b47cce28..ae9f2fff5af0 100644 --- a/tools/build/feature/test-libelf-getshdrstrndx.c +++ b/tools/build/feature/test-libelf-getshdrstrndx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-libelf-mmap.c b/tools/build/feature/test-libelf-mmap.c index 564427d7ef18..2c3ef81affe2 100644 --- a/tools/build/feature/test-libelf-mmap.c +++ b/tools/build/feature/test-libelf-mmap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-libelf.c b/tools/build/feature/test-libelf.c index 08db322d8957..905044127d56 100644 --- a/tools/build/feature/test-libelf.c +++ b/tools/build/feature/test-libelf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-libnuma.c b/tools/build/feature/test-libnuma.c index 4763d9cd587d..b3aa59f8b3cb 100644 --- a/tools/build/feature/test-libnuma.c +++ b/tools/build/feature/test-libnuma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libperl.c b/tools/build/feature/test-libperl.c index 8871f6a0fdb4..0415f437eb31 100644 --- a/tools/build/feature/test-libperl.c +++ b/tools/build/feature/test-libperl.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libpython-version.c b/tools/build/feature/test-libpython-version.c index facea122d812..47714b942d4d 100644 --- a/tools/build/feature/test-libpython-version.c +++ b/tools/build/feature/test-libpython-version.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #if PY_VERSION_HEX >= 0x03000000 diff --git a/tools/build/feature/test-libpython.c b/tools/build/feature/test-libpython.c index b24b28ad6324..0c1641b0d9a7 100644 --- a/tools/build/feature/test-libpython.c +++ b/tools/build/feature/test-libpython.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-libslang.c b/tools/build/feature/test-libslang.c index 22ff22ed94d1..9cbff8d1df53 100644 --- a/tools/build/feature/test-libslang.c +++ b/tools/build/feature/test-libslang.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-libunwind-aarch64.c b/tools/build/feature/test-libunwind-aarch64.c index fc03fb64e8c1..323803f49212 100644 --- a/tools/build/feature/test-libunwind-aarch64.c +++ b/tools/build/feature/test-libunwind-aarch64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libunwind-arm.c b/tools/build/feature/test-libunwind-arm.c index 632d95ec641f..cb378b7d6866 100644 --- a/tools/build/feature/test-libunwind-arm.c +++ b/tools/build/feature/test-libunwind-arm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libunwind-debug-frame-aarch64.c b/tools/build/feature/test-libunwind-debug-frame-aarch64.c index 22844673fc26..36d6646c185e 100644 --- a/tools/build/feature/test-libunwind-debug-frame-aarch64.c +++ b/tools/build/feature/test-libunwind-debug-frame-aarch64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libunwind-debug-frame-arm.c b/tools/build/feature/test-libunwind-debug-frame-arm.c index f98859684fee..8696e48e1268 100644 --- a/tools/build/feature/test-libunwind-debug-frame-arm.c +++ b/tools/build/feature/test-libunwind-debug-frame-arm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libunwind-debug-frame.c b/tools/build/feature/test-libunwind-debug-frame.c index 0ef8087a104a..efb55cdd8d01 100644 --- a/tools/build/feature/test-libunwind-debug-frame.c +++ b/tools/build/feature/test-libunwind-debug-frame.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libunwind-x86.c b/tools/build/feature/test-libunwind-x86.c index 3561edce305e..e5e0f6c89637 100644 --- a/tools/build/feature/test-libunwind-x86.c +++ b/tools/build/feature/test-libunwind-x86.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libunwind-x86_64.c b/tools/build/feature/test-libunwind-x86_64.c index 5add2517b2a1..62ae4db597dc 100644 --- a/tools/build/feature/test-libunwind-x86_64.c +++ b/tools/build/feature/test-libunwind-x86_64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-libunwind.c b/tools/build/feature/test-libunwind.c index 43b9369bcab7..53fd26614ff0 100644 --- a/tools/build/feature/test-libunwind.c +++ b/tools/build/feature/test-libunwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/build/feature/test-llvm-version.cpp b/tools/build/feature/test-llvm-version.cpp index 896d31724568..8a091625446a 100644 --- a/tools/build/feature/test-llvm-version.cpp +++ b/tools/build/feature/test-llvm-version.cpp @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "llvm/Config/llvm-config.h" diff --git a/tools/build/feature/test-llvm.cpp b/tools/build/feature/test-llvm.cpp index 455a332dc8a8..88a3d1bdd9f6 100644 --- a/tools/build/feature/test-llvm.cpp +++ b/tools/build/feature/test-llvm.cpp @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #define NUM_VERSION (((LLVM_VERSION_MAJOR) << 16) + (LLVM_VERSION_MINOR << 8) + LLVM_VERSION_PATCH) diff --git a/tools/build/feature/test-lzma.c b/tools/build/feature/test-lzma.c index 95adc8ced3dd..78682bb01d57 100644 --- a/tools/build/feature/test-lzma.c +++ b/tools/build/feature/test-lzma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-numa_num_possible_cpus.c b/tools/build/feature/test-numa_num_possible_cpus.c index 2606e94b0659..573d07b9c570 100644 --- a/tools/build/feature/test-numa_num_possible_cpus.c +++ b/tools/build/feature/test-numa_num_possible_cpus.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-pthread-attr-setaffinity-np.c b/tools/build/feature/test-pthread-attr-setaffinity-np.c index fdada5e8d454..38c71131c452 100644 --- a/tools/build/feature/test-pthread-attr-setaffinity-np.c +++ b/tools/build/feature/test-pthread-attr-setaffinity-np.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/build/feature/test-sched_getcpu.c b/tools/build/feature/test-sched_getcpu.c index 9c6b4cbffb1c..e448deb4124c 100644 --- a/tools/build/feature/test-sched_getcpu.c +++ b/tools/build/feature/test-sched_getcpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif diff --git a/tools/build/feature/test-sdt.c b/tools/build/feature/test-sdt.c index e4531a6e80ea..22737b0dadc8 100644 --- a/tools/build/feature/test-sdt.c +++ b/tools/build/feature/test-sdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-setns.c b/tools/build/feature/test-setns.c new file mode 100644 index 000000000000..1f714d2a658b --- /dev/null +++ b/tools/build/feature/test-setns.c @@ -0,0 +1,7 @@ +#define _GNU_SOURCE +#include + +int main(void) +{ + return setns(0, 0); +} diff --git a/tools/build/feature/test-stackprotector-all.c b/tools/build/feature/test-stackprotector-all.c index c9f398d87868..c8a57194f9f2 100644 --- a/tools/build/feature/test-stackprotector-all.c +++ b/tools/build/feature/test-stackprotector-all.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/feature/test-sync-compare-and-swap.c b/tools/build/feature/test-sync-compare-and-swap.c index c34d4ca4af56..1e38d1930a97 100644 --- a/tools/build/feature/test-sync-compare-and-swap.c +++ b/tools/build/feature/test-sync-compare-and-swap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include volatile uint64_t x; diff --git a/tools/build/feature/test-timerfd.c b/tools/build/feature/test-timerfd.c index 8c5c083b4d3c..9c72c697a9df 100644 --- a/tools/build/feature/test-timerfd.c +++ b/tools/build/feature/test-timerfd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * test for timerfd functions used by perf-kvm-stat-live */ diff --git a/tools/build/feature/test-zlib.c b/tools/build/feature/test-zlib.c index e111fff6240e..da6c35794b93 100644 --- a/tools/build/feature/test-zlib.c +++ b/tools/build/feature/test-zlib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/build/fixdep.c b/tools/build/fixdep.c index 734d1547cbae..2501fea7aa3e 100644 --- a/tools/build/fixdep.c +++ b/tools/build/fixdep.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * "Optimize" a list of dependencies as spit out by gcc -MD * for the build framework. diff --git a/tools/build/tests/ex/Makefile b/tools/build/tests/ex/Makefile index c50d5782ad5a..fee032e06a85 100644 --- a/tools/build/tests/ex/Makefile +++ b/tools/build/tests/ex/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 export srctree := $(abspath ../../../..) export CC := gcc export LD := ld @@ -8,7 +9,7 @@ ex: include $(srctree)/tools/build/Makefile.include ex: ex-in.o libex-in.o - gcc -o $@ $^ + $(CC) -o $@ $^ ex.%: fixdep FORCE make -f $(srctree)/tools/build/Makefile.build dir=. $@ diff --git a/tools/build/tests/ex/a.c b/tools/build/tests/ex/a.c index 851762798c83..66017a9f40b6 100644 --- a/tools/build/tests/ex/a.c +++ b/tools/build/tests/ex/a.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int a(void) { diff --git a/tools/build/tests/ex/arch/e.c b/tools/build/tests/ex/arch/e.c index beaa4a1d7ba8..f6ef585b570c 100644 --- a/tools/build/tests/ex/arch/e.c +++ b/tools/build/tests/ex/arch/e.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int e(void) { diff --git a/tools/build/tests/ex/arch/f.c b/tools/build/tests/ex/arch/f.c index 7c3e9e9da5b7..bffd9c67e9af 100644 --- a/tools/build/tests/ex/arch/f.c +++ b/tools/build/tests/ex/arch/f.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int f(void) { diff --git a/tools/build/tests/ex/b.c b/tools/build/tests/ex/b.c index c24ff9ca9a97..2b29fb4d3c20 100644 --- a/tools/build/tests/ex/b.c +++ b/tools/build/tests/ex/b.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int b(void) { diff --git a/tools/build/tests/ex/c.c b/tools/build/tests/ex/c.c index e216d0217499..a63b20ab83d5 100644 --- a/tools/build/tests/ex/c.c +++ b/tools/build/tests/ex/c.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int c(void) { diff --git a/tools/build/tests/ex/d.c b/tools/build/tests/ex/d.c index 80dc0f06151b..e114e8dca0b6 100644 --- a/tools/build/tests/ex/d.c +++ b/tools/build/tests/ex/d.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int d(void) { diff --git a/tools/build/tests/ex/ex.c b/tools/build/tests/ex/ex.c index 57de6074d252..3c02756ef912 100644 --- a/tools/build/tests/ex/ex.c +++ b/tools/build/tests/ex/ex.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 int a(void); int b(void); diff --git a/tools/build/tests/ex/inc.c b/tools/build/tests/ex/inc.c index c20f1e9033a3..3636ab5bf339 100644 --- a/tools/build/tests/ex/inc.c +++ b/tools/build/tests/ex/inc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifdef INCLUDE #include "krava.h" #endif diff --git a/tools/build/tests/run.sh b/tools/build/tests/run.sh index 44d2a0fade67..2c54e4d43546 100755 --- a/tools/build/tests/run.sh +++ b/tools/build/tests/run.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 function test_ex { make -C ex V=1 clean > ex.out 2>&1 diff --git a/tools/cgroup/Makefile b/tools/cgroup/Makefile index b4286196b763..860fa151640a 100644 --- a/tools/cgroup/Makefile +++ b/tools/cgroup/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for cgroup tools CC = $(CROSS_COMPILE)gcc diff --git a/tools/cgroup/cgroup_event_listener.c b/tools/cgroup/cgroup_event_listener.c index 4eb5507205c9..3d70dc831a76 100644 --- a/tools/cgroup/cgroup_event_listener.c +++ b/tools/cgroup/cgroup_event_listener.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * cgroup_event_listener.c - Simple listener of cgroup events * diff --git a/tools/firewire/Makefile b/tools/firewire/Makefile index 81767adaae7d..67b6e9fca83c 100644 --- a/tools/firewire/Makefile +++ b/tools/firewire/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 prefix = /usr nosy-dump-version = 0.4 diff --git a/tools/firewire/decode-fcp.c b/tools/firewire/decode-fcp.c index e41223b6a4c8..b67ebc88434d 100644 --- a/tools/firewire/decode-fcp.c +++ b/tools/firewire/decode-fcp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/firewire/list.h b/tools/firewire/list.h index 41f4bdadf634..6278d08e99e3 100644 --- a/tools/firewire/list.h +++ b/tools/firewire/list.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ struct list { struct list *next, *prev; }; diff --git a/tools/firewire/nosy-dump.h b/tools/firewire/nosy-dump.h index 3a4b5b33ba5d..69e5e594f284 100644 --- a/tools/firewire/nosy-dump.h +++ b/tools/firewire/nosy-dump.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __nosy_dump_h__ #define __nosy_dump_h__ diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index b4401536cfa9..805a2c0cf4cd 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 include ../scripts/Makefile.include bindir ?= /usr/bin diff --git a/tools/hv/Makefile b/tools/hv/Makefile index 0d1e61b81844..31503819454d 100644 --- a/tools/hv/Makefile +++ b/tools/hv/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for Hyper-V tools CC = $(CROSS_COMPILE)gcc diff --git a/tools/hv/bondvf.sh b/tools/hv/bondvf.sh deleted file mode 100755 index 89b25068cd98..000000000000 --- a/tools/hv/bondvf.sh +++ /dev/null @@ -1,232 +0,0 @@ -#!/bin/bash - -# This example script creates bonding network devices based on synthetic NIC -# (the virtual network adapter usually provided by Hyper-V) and the matching -# VF NIC (SRIOV virtual function). So the synthetic NIC and VF NIC can -# function as one network device, and fail over to the synthetic NIC if VF is -# down. -# -# Usage: -# - After configured vSwitch and vNIC with SRIOV, start Linux virtual -# machine (VM) -# - Run this scripts on the VM. It will create configuration files in -# distro specific directory. -# - Reboot the VM, so that the bonding config are enabled. -# -# The config files are DHCP by default. You may edit them if you need to change -# to Static IP or change other settings. -# - -sysdir=/sys/class/net -netvsc_cls={f8615163-df3e-46c5-913f-f2d2f965ed0e} -bondcnt=0 - -# Detect Distro -if [ -f /etc/redhat-release ]; -then - cfgdir=/etc/sysconfig/network-scripts - distro=redhat -elif grep -q 'Ubuntu' /etc/issue -then - cfgdir=/etc/network - distro=ubuntu -elif grep -q 'SUSE' /etc/issue -then - cfgdir=/etc/sysconfig/network - distro=suse -else - echo "Unsupported Distro" - exit 1 -fi - -echo Detected Distro: $distro, or compatible - -# Get a list of ethernet names -list_eth=(`cd $sysdir && ls -d */ | cut -d/ -f1 | grep -v bond`) -eth_cnt=${#list_eth[@]} - -echo List of net devices: - -# Get the MAC addresses -for (( i=0; i < $eth_cnt; i++ )) -do - list_mac[$i]=`cat $sysdir/${list_eth[$i]}/address` - echo ${list_eth[$i]}, ${list_mac[$i]} -done - -# Find NIC with matching MAC -for (( i=0; i < $eth_cnt-1; i++ )) -do - for (( j=i+1; j < $eth_cnt; j++ )) - do - if [ "${list_mac[$i]}" = "${list_mac[$j]}" ] - then - list_match[$i]=${list_eth[$j]} - break - fi - done -done - -function create_eth_cfg_redhat { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo DEVICE=$1 >>$fn - echo TYPE=Ethernet >>$fn - echo BOOTPROTO=none >>$fn - echo UUID=`uuidgen` >>$fn - echo ONBOOT=yes >>$fn - echo PEERDNS=yes >>$fn - echo IPV6INIT=yes >>$fn - echo MASTER=$2 >>$fn - echo SLAVE=yes >>$fn -} - -function create_eth_cfg_pri_redhat { - create_eth_cfg_redhat $1 $2 -} - -function create_bond_cfg_redhat { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo DEVICE=$1 >>$fn - echo TYPE=Bond >>$fn - echo BOOTPROTO=dhcp >>$fn - echo UUID=`uuidgen` >>$fn - echo ONBOOT=yes >>$fn - echo PEERDNS=yes >>$fn - echo IPV6INIT=yes >>$fn - echo BONDING_MASTER=yes >>$fn - echo BONDING_OPTS=\"mode=active-backup miimon=100 primary=$2\" >>$fn -} - -function del_eth_cfg_ubuntu { - local mainfn=$cfgdir/interfaces - local fnlist=( $mainfn ) - - local dirlist=(`awk '/^[ \t]*source/{print $2}' $mainfn`) - - local i - for i in "${dirlist[@]}" - do - fnlist+=(`ls $i 2>/dev/null`) - done - - local tmpfl=$(mktemp) - - local nic_start='^[ \t]*(auto|iface|mapping|allow-.*)[ \t]+'$1 - local nic_end='^[ \t]*(auto|iface|mapping|allow-.*|source)' - - local fn - for fn in "${fnlist[@]}" - do - awk "/$nic_end/{x=0} x{next} /$nic_start/{x=1;next} 1" \ - $fn >$tmpfl - - cp $tmpfl $fn - done - - rm $tmpfl -} - -function create_eth_cfg_ubuntu { - local fn=$cfgdir/interfaces - - del_eth_cfg_ubuntu $1 - echo $'\n'auto $1 >>$fn - echo iface $1 inet manual >>$fn - echo bond-master $2 >>$fn -} - -function create_eth_cfg_pri_ubuntu { - local fn=$cfgdir/interfaces - - del_eth_cfg_ubuntu $1 - echo $'\n'allow-hotplug $1 >>$fn - echo iface $1 inet manual >>$fn - echo bond-master $2 >>$fn - echo bond-primary $1 >>$fn -} - -function create_bond_cfg_ubuntu { - local fn=$cfgdir/interfaces - - del_eth_cfg_ubuntu $1 - - echo $'\n'auto $1 >>$fn - echo iface $1 inet dhcp >>$fn - echo bond-mode active-backup >>$fn - echo bond-miimon 100 >>$fn - echo bond-slaves none >>$fn -} - -function create_eth_cfg_suse { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo BOOTPROTO=none >>$fn - echo STARTMODE=auto >>$fn -} - -function create_eth_cfg_pri_suse { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo BOOTPROTO=none >>$fn - echo STARTMODE=hotplug >>$fn -} - -function create_bond_cfg_suse { - local fn=$cfgdir/ifcfg-$1 - - rm -f $fn - echo BOOTPROTO=dhcp >>$fn - echo STARTMODE=auto >>$fn - echo BONDING_MASTER=yes >>$fn - echo BONDING_SLAVE_0=$2 >>$fn - echo BONDING_SLAVE_1=$3 >>$fn - echo BONDING_MODULE_OPTS=\'mode=active-backup miimon=100 primary=$2\' >>$fn -} - -function create_bond { - local bondname=bond$bondcnt - local primary - local secondary - - local class_id1=`cat $sysdir/$1/device/class_id 2>/dev/null` - local class_id2=`cat $sysdir/$2/device/class_id 2>/dev/null` - - if [ "$class_id1" = "$netvsc_cls" ] - then - primary=$2 - secondary=$1 - elif [ "$class_id2" = "$netvsc_cls" ] - then - primary=$1 - secondary=$2 - else - return 0 - fi - - echo $'\nBond name:' $bondname - - echo configuring $primary - create_eth_cfg_pri_$distro $primary $bondname - - echo configuring $secondary - create_eth_cfg_$distro $secondary $bondname - - echo creating: $bondname with primary slave: $primary - create_bond_cfg_$distro $bondname $primary $secondary - - let bondcnt=bondcnt+1 -} - -for (( i=0; i < $eth_cnt-1; i++ )) -do - if [ -n "${list_match[$i]}" ] - then - create_bond ${list_eth[$i]} ${list_match[$i]} - fi -done diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c index 26ae609a9448..457a1521f32f 100644 --- a/tools/hv/hv_fcopy_daemon.c +++ b/tools/hv/hv_fcopy_daemon.c @@ -138,14 +138,17 @@ void print_usage(char *argv[]) int main(int argc, char *argv[]) { - int fcopy_fd, len; + int fcopy_fd; int error; int daemonize = 1, long_index = 0, opt; int version = FCOPY_CURRENT_VERSION; - char *buffer[4096 * 2]; - struct hv_fcopy_hdr *in_msg; + union { + struct hv_fcopy_hdr hdr; + struct hv_start_fcopy start; + struct hv_do_fcopy copy; + __u32 kernel_modver; + } buffer = { }; int in_handshake = 1; - __u32 kernel_modver; static struct option long_options[] = { {"help", no_argument, 0, 'h' }, @@ -195,32 +198,31 @@ int main(int argc, char *argv[]) * In this loop we process fcopy messages after the * handshake is complete. */ - len = pread(fcopy_fd, buffer, (4096 * 2), 0); + ssize_t len; + + len = pread(fcopy_fd, &buffer, sizeof(buffer), 0); if (len < 0) { syslog(LOG_ERR, "pread failed: %s", strerror(errno)); exit(EXIT_FAILURE); } if (in_handshake) { - if (len != sizeof(kernel_modver)) { + if (len != sizeof(buffer.kernel_modver)) { syslog(LOG_ERR, "invalid version negotiation"); exit(EXIT_FAILURE); } - kernel_modver = *(__u32 *)buffer; in_handshake = 0; - syslog(LOG_INFO, "kernel module version: %d", - kernel_modver); + syslog(LOG_INFO, "kernel module version: %u", + buffer.kernel_modver); continue; } - in_msg = (struct hv_fcopy_hdr *)buffer; - - switch (in_msg->operation) { + switch (buffer.hdr.operation) { case START_FILE_COPY: - error = hv_start_fcopy((struct hv_start_fcopy *)in_msg); + error = hv_start_fcopy(&buffer.start); break; case WRITE_TO_FILE: - error = hv_copy_data((struct hv_do_fcopy *)in_msg); + error = hv_copy_data(&buffer.copy); break; case COMPLETE_FCOPY: error = hv_copy_finished(); @@ -231,7 +233,7 @@ int main(int argc, char *argv[]) default: syslog(LOG_ERR, "Unknown operation: %d", - in_msg->operation); + buffer.hdr.operation); } diff --git a/tools/hv/hv_get_dhcp_info.sh b/tools/hv/hv_get_dhcp_info.sh index ccd3e9532764..c38686c44656 100755 --- a/tools/hv/hv_get_dhcp_info.sh +++ b/tools/hv/hv_get_dhcp_info.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 # This example script retrieves the DHCP state of a given interface. # In the interest of keeping the KVP daemon code free of distro specific diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 88b20e007c05..eaa3bec273c8 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -1136,7 +1136,7 @@ static int process_ip_string(FILE *f, char *ip_string, int type) int i = 0; int j = 0; char str[256]; - char sub_str[10]; + char sub_str[13]; int offset = 0; memset(addr, 0, sizeof(addr)); diff --git a/tools/hv/hv_set_ifconfig.sh b/tools/hv/hv_set_ifconfig.sh index 735aafd64a3f..7ed9f85ef908 100755 --- a/tools/hv/hv_set_ifconfig.sh +++ b/tools/hv/hv_set_ifconfig.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 # This example script activates an interface based on the specified # configuration. diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 7ba54195934c..b2b4ebffab8c 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +72,7 @@ static int vss_operate(int operation) char match[] = "/dev/"; FILE *mounts; struct mntent *ent; + struct stat sb; char errdir[1024] = {0}; unsigned int cmd; int error = 0, root_seen = 0, save_errno = 0; @@ -92,6 +95,10 @@ static int vss_operate(int operation) while ((ent = getmntent(mounts))) { if (strncmp(ent->mnt_fsname, match, strlen(match))) continue; + if (stat(ent->mnt_fsname, &sb) == -1) + continue; + if (S_ISBLK(sb.st_mode) && major(sb.st_rdev) == LOOP_MAJOR) + continue; if (hasmntopt(ent, MNTOPT_RO) != NULL) continue; if (strcmp(ent->mnt_type, "vfat") == 0) diff --git a/tools/hv/lsvmbus b/tools/hv/lsvmbus index e8fecd61871f..353e56768df8 100644 --- a/tools/hv/lsvmbus +++ b/tools/hv/lsvmbus @@ -1,4 +1,5 @@ #!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0 import os from optparse import OptionParser diff --git a/tools/iio/Build b/tools/iio/Build new file mode 100644 index 000000000000..f74cbda64710 --- /dev/null +++ b/tools/iio/Build @@ -0,0 +1,3 @@ +lsiio-y += lsiio.o iio_utils.o +iio_event_monitor-y += iio_event_monitor.o iio_utils.o +iio_generic_buffer-y += iio_generic_buffer.o iio_utils.o diff --git a/tools/iio/Makefile b/tools/iio/Makefile index 8f08e03a9a5e..a08e7a47d6a3 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile @@ -1,31 +1,68 @@ +# SPDX-License-Identifier: GPL-2.0 +include ../scripts/Makefile.include + +bindir ?= /usr/bin + +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +endif + +# Do not use make's built-in rules +# (this improves performance and avoids hard-to-debug behaviour); +MAKEFLAGS += -r + CC = $(CROSS_COMPILE)gcc -CFLAGS += -Wall -g -D_GNU_SOURCE -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include +LD = $(CROSS_COMPILE)ld +CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include -BINDIR=usr/bin -INSTALL_PROGRAM=install -m 755 -p -DEL_FILE=rm -f +ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer +ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) -all: iio_event_monitor lsiio iio_generic_buffer +all: $(ALL_PROGRAMS) -iio_event_monitor: iio_event_monitor.o iio_utils.o +export srctree OUTPUT CC LD CFLAGS +include $(srctree)/tools/build/Makefile.include -lsiio: lsiio.o iio_utils.o +# +# We need the following to be outside of kernel tree +# +$(OUTPUT)include/linux/iio: ../../include/uapi/linux/iio + mkdir -p $(OUTPUT)include/linux/iio 2>&1 || true + ln -sf $(CURDIR)/../../include/uapi/linux/iio/events.h $@ + ln -sf $(CURDIR)/../../include/uapi/linux/iio/types.h $@ -iio_generic_buffer: iio_generic_buffer.o iio_utils.o +prepare: $(OUTPUT)include/linux/iio -%.o: %.c iio_utils.h +LSIIO_IN := $(OUTPUT)lsiio-in.o +$(LSIIO_IN): prepare FORCE + $(Q)$(MAKE) $(build)=lsiio +$(OUTPUT)lsiio: $(LSIIO_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -install: - - mkdir -p $(INSTALL_ROOT)/$(BINDIR) - - $(INSTALL_PROGRAM) "iio_event_monitor" "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor" - - $(INSTALL_PROGRAM) "lsiio" "$(INSTALL_ROOT)/$(BINDIR)/lsiio" - - $(INSTALL_PROGRAM) "iio_generic_buffer" "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer" +IIO_EVENT_MONITOR_IN := $(OUTPUT)iio_event_monitor-in.o +$(IIO_EVENT_MONITOR_IN): prepare FORCE + $(Q)$(MAKE) $(build)=iio_event_monitor +$(OUTPUT)iio_event_monitor: $(IIO_EVENT_MONITOR_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -uninstall: - $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor" - $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/lsiio" - $(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer" +IIO_GENERIC_BUFFER_IN := $(OUTPUT)iio_generic_buffer-in.o +$(IIO_GENERIC_BUFFER_IN): prepare FORCE + $(Q)$(MAKE) $(build)=iio_generic_buffer +$(OUTPUT)iio_generic_buffer: $(IIO_GENERIC_BUFFER_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ -.PHONY: clean clean: - rm -f *.o iio_event_monitor lsiio iio_generic_buffer + rm -f $(ALL_PROGRAMS) + rm -rf $(OUTPUT)include/linux/iio + find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete + +install: $(ALL_PROGRAMS) + install -d -m 755 $(DESTDIR)$(bindir); \ + for program in $(ALL_PROGRAMS); do \ + install $$program $(DESTDIR)$(bindir); \ + done + +FORCE: + +.PHONY: all install clean FORCE prepare diff --git a/tools/include/asm-generic/atomic-gcc.h b/tools/include/asm-generic/atomic-gcc.h index 5e9738f97bf3..40b231fb95bd 100644 --- a/tools/include/asm-generic/atomic-gcc.h +++ b/tools/include/asm-generic/atomic-gcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_ASM_GENERIC_ATOMIC_H #define __TOOLS_ASM_GENERIC_ATOMIC_H diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h index 0304600121da..9bce3b56b5e7 100644 --- a/tools/include/asm-generic/bitops.h +++ b/tools/include/asm-generic/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_ASM_GENERIC_BITOPS_H #define __TOOLS_ASM_GENERIC_BITOPS_H diff --git a/tools/include/asm-generic/bitops/__ffs.h b/tools/include/asm-generic/bitops/__ffs.h index b3accfdf24b9..9d1310519497 100644 --- a/tools/include/asm-generic/bitops/__ffs.h +++ b/tools/include/asm-generic/bitops/__ffs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ #define _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ diff --git a/tools/include/asm-generic/bitops/__fls.h b/tools/include/asm-generic/bitops/__fls.h index a60a7ccb6782..03f721a8a2b1 100644 --- a/tools/include/asm-generic/bitops/__fls.h +++ b/tools/include/asm-generic/bitops/__fls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_GENERIC_BITOPS___FLS_H_ #define _ASM_GENERIC_BITOPS___FLS_H_ diff --git a/tools/include/asm-generic/bitops/arch_hweight.h b/tools/include/asm-generic/bitops/arch_hweight.h index 6a211f40665c..c2705e1d220d 100644 --- a/tools/include/asm-generic/bitops/arch_hweight.h +++ b/tools/include/asm-generic/bitops/arch_hweight.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_ #define _ASM_GENERIC_BITOPS_ARCH_HWEIGHT_H_ diff --git a/tools/include/asm-generic/bitops/atomic.h b/tools/include/asm-generic/bitops/atomic.h index 68b8c1516c5a..21c41ccd1266 100644 --- a/tools/include/asm-generic/bitops/atomic.h +++ b/tools/include/asm-generic/bitops/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ diff --git a/tools/include/asm-generic/bitops/const_hweight.h b/tools/include/asm-generic/bitops/const_hweight.h index 0a7e06623470..149faeeeeaf2 100644 --- a/tools/include/asm-generic/bitops/const_hweight.h +++ b/tools/include/asm-generic/bitops/const_hweight.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ #define _ASM_GENERIC_BITOPS_CONST_HWEIGHT_H_ diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h index 5538ecdc964a..9311fadaaab2 100644 --- a/tools/include/asm-generic/bitops/find.h +++ b/tools/include/asm-generic/bitops/find.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ diff --git a/tools/include/asm-generic/bitops/fls.h b/tools/include/asm-generic/bitops/fls.h index 0576d1f42f43..753aecaab641 100644 --- a/tools/include/asm-generic/bitops/fls.h +++ b/tools/include/asm-generic/bitops/fls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_GENERIC_BITOPS_FLS_H_ #define _ASM_GENERIC_BITOPS_FLS_H_ diff --git a/tools/include/asm-generic/bitops/fls64.h b/tools/include/asm-generic/bitops/fls64.h index b097cf8444e3..866f2b2304ff 100644 --- a/tools/include/asm-generic/bitops/fls64.h +++ b/tools/include/asm-generic/bitops/fls64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_GENERIC_BITOPS_FLS64_H_ #define _ASM_GENERIC_BITOPS_FLS64_H_ diff --git a/tools/include/asm-generic/bitops/hweight.h b/tools/include/asm-generic/bitops/hweight.h index 290120c01a8e..3e681982bcd1 100644 --- a/tools/include/asm-generic/bitops/hweight.h +++ b/tools/include/asm-generic/bitops/hweight.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_HWEIGHT_H_ diff --git a/tools/include/asm-generic/bitsperlong.h b/tools/include/asm-generic/bitsperlong.h index 45eca517efb3..8f2283052333 100644 --- a/tools/include/asm-generic/bitsperlong.h +++ b/tools/include/asm-generic/bitsperlong.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ASM_GENERIC_BITS_PER_LONG #define __ASM_GENERIC_BITS_PER_LONG diff --git a/tools/include/asm-generic/hugetlb_encode.h b/tools/include/asm-generic/hugetlb_encode.h new file mode 100644 index 000000000000..e4732d3c2998 --- /dev/null +++ b/tools/include/asm-generic/hugetlb_encode.h @@ -0,0 +1,34 @@ +#ifndef _ASM_GENERIC_HUGETLB_ENCODE_H_ +#define _ASM_GENERIC_HUGETLB_ENCODE_H_ + +/* + * Several system calls take a flag to request "hugetlb" huge pages. + * Without further specification, these system calls will use the + * system's default huge page size. If a system supports multiple + * huge page sizes, the desired huge page size can be specified in + * bits [26:31] of the flag arguments. The value in these 6 bits + * will encode the log2 of the huge page size. + * + * The following definitions are associated with this huge page size + * encoding in flag arguments. System call specific header files + * that use this encoding should include this file. They can then + * provide definitions based on these with their own specific prefix. + * for example: + * #define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT + */ + +#define HUGETLB_FLAG_ENCODE_SHIFT 26 +#define HUGETLB_FLAG_ENCODE_MASK 0x3f + +#define HUGETLB_FLAG_ENCODE_64KB (16 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_512KB (19 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_1MB (20 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_2MB (21 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_8MB (23 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_16MB (24 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_256MB (28 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_1GB (30 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_2GB (31 << HUGETLB_FLAG_ENCODE_SHIFT) +#define HUGETLB_FLAG_ENCODE_16GB (34 << HUGETLB_FLAG_ENCODE_SHIFT) + +#endif /* _ASM_GENERIC_HUGETLB_ENCODE_H_ */ diff --git a/tools/include/asm/alternative-asm.h b/tools/include/asm/alternative-asm.h index 2a4d1bfa2988..b54bd860dff6 100644 --- a/tools/include/asm/alternative-asm.h +++ b/tools/include/asm/alternative-asm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_ASM_ALTERNATIVE_ASM_H #define _TOOLS_ASM_ALTERNATIVE_ASM_H diff --git a/tools/include/asm/atomic.h b/tools/include/asm/atomic.h index 70794f538a86..8c9bfffd4191 100644 --- a/tools/include/asm/atomic.h +++ b/tools/include/asm/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_LINUX_ASM_ATOMIC_H #define __TOOLS_LINUX_ASM_ATOMIC_H diff --git a/tools/include/asm/barrier.h b/tools/include/asm/barrier.h index ac66ac594685..391d942536e5 100644 --- a/tools/include/asm/barrier.h +++ b/tools/include/asm/barrier.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #if defined(__i386__) || defined(__x86_64__) #include "../../arch/x86/include/asm/barrier.h" #elif defined(__arm__) diff --git a/tools/include/asm/bug.h b/tools/include/asm/bug.h index 4790f047a89c..bbd75ac8b202 100644 --- a/tools/include/asm/bug.h +++ b/tools/include/asm/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_ASM_BUG_H #define _TOOLS_ASM_BUG_H diff --git a/tools/include/asm/export.h b/tools/include/asm/export.h new file mode 100644 index 000000000000..2cb1a0d83035 --- /dev/null +++ b/tools/include/asm/export.h @@ -0,0 +1,7 @@ +#ifndef _TOOLS_ASM_EXPORT_H +#define _TOOLS_ASM_EXPORT_H + +#define EXPORT_SYMBOL(x) +#define EXPORT_SYMBOL_GPL(x) + +#endif /* _TOOLS_ASM_EXPORT_H */ diff --git a/tools/include/linux/atomic.h b/tools/include/linux/atomic.h index 9f21fc2b092b..00a6c4ca562b 100644 --- a/tools/include/linux/atomic.h +++ b/tools/include/linux/atomic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_LINUX_ATOMIC_H #define __TOOLS_LINUX_ATOMIC_H diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index e8b9f518e36b..ca160270fdfa 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_BITOPS_H #define _PERF_BITOPS_H diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h index 969db1981868..acc704bd3998 100644 --- a/tools/include/linux/bitops.h +++ b/tools/include/linux/bitops.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_BITOPS_H_ #define _TOOLS_LINUX_BITOPS_H_ diff --git a/tools/include/linux/bug.h b/tools/include/linux/bug.h index 8e4a4f49135d..85f80258a15f 100644 --- a/tools/include/linux/bug.h +++ b/tools/include/linux/bug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_PERF_LINUX_BUG_H #define _TOOLS_PERF_LINUX_BUG_H diff --git a/tools/include/linux/compiler-gcc.h b/tools/include/linux/compiler-gcc.h index bd39b2090ad1..a3a4427441bf 100644 --- a/tools/include/linux/compiler-gcc.h +++ b/tools/include/linux/compiler-gcc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_COMPILER_H_ #error "Please don't include directly, include instead." #endif @@ -21,11 +22,14 @@ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) #define noinline __attribute__((noinline)) - +#ifndef __packed #define __packed __attribute__((packed)) - +#endif +#ifndef __noreturn #define __noreturn __attribute__((noreturn)) - +#endif +#ifndef __aligned #define __aligned(x) __attribute__((aligned(x))) +#endif #define __printf(a, b) __attribute__((format(printf, a, b))) #define __scanf(a, b) __attribute__((format(scanf, a, b))) diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index d7a5604c38d7..07fd03c74a77 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_COMPILER_H_ #define _TOOLS_LINUX_COMPILER_H_ diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h index 7d410260661b..edfeaba95429 100644 --- a/tools/include/linux/coresight-pmu.h +++ b/tools/include/linux/coresight-pmu.h @@ -24,6 +24,12 @@ /* ETMv3.5/PTM's ETMCR config bit */ #define ETM_OPT_CYCACC 12 #define ETM_OPT_TS 28 +#define ETM_OPT_RETSTK 29 + +/* ETMv4 CONFIGR programming bits for the ETM OPTs */ +#define ETM4_CFG_BIT_CYCACC 4 +#define ETM4_CFG_BIT_TS 11 +#define ETM4_CFG_BIT_RETSTK 12 static inline int coresight_get_trace_id(int cpu) { diff --git a/tools/include/linux/debug_locks.h b/tools/include/linux/debug_locks.h index 61cc7f501168..72d595ce764a 100644 --- a/tools/include/linux/debug_locks.h +++ b/tools/include/linux/debug_locks.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_DEBUG_LOCKS_H_ #define _LIBLOCKDEP_DEBUG_LOCKS_H_ diff --git a/tools/include/linux/err.h b/tools/include/linux/err.h index abf0478a8fb2..7a8b61ad44cb 100644 --- a/tools/include/linux/err.h +++ b/tools/include/linux/err.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_LINUX_ERR_H #define __TOOLS_LINUX_ERR_H diff --git a/tools/include/linux/filter.h b/tools/include/linux/filter.h index 4ce25d43e8e3..c5e512da8d8a 100644 --- a/tools/include/linux/filter.h +++ b/tools/include/linux/filter.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Linux Socket Filter Data Structures */ diff --git a/tools/include/linux/hardirq.h b/tools/include/linux/hardirq.h index c8f3f8f58729..b25580b6a9be 100644 --- a/tools/include/linux/hardirq.h +++ b/tools/include/linux/hardirq.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_LINUX_HARDIRQ_H_ #define _LIBLOCKDEP_LINUX_HARDIRQ_H_ diff --git a/tools/include/linux/hashtable.h b/tools/include/linux/hashtable.h index 251eabf2a05e..434dd5ac6d71 100644 --- a/tools/include/linux/hashtable.h +++ b/tools/include/linux/hashtable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Statically sized hash table implementation * (C) 2012 Sasha Levin diff --git a/tools/include/linux/irqflags.h b/tools/include/linux/irqflags.h index df77669cfe1c..e734da3e5b33 100644 --- a/tools/include/linux/irqflags.h +++ b/tools/include/linux/irqflags.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_ #define _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_ diff --git a/tools/include/linux/kallsyms.h b/tools/include/linux/kallsyms.h index 582cc1e5f3a4..89ca6fe257cc 100644 --- a/tools/include/linux/kallsyms.h +++ b/tools/include/linux/kallsyms.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_LINUX_KALLSYMS_H_ #define _LIBLOCKDEP_LINUX_KALLSYMS_H_ diff --git a/tools/include/linux/kern_levels.h b/tools/include/linux/kern_levels.h index 3b9bade28698..778ecb984480 100644 --- a/tools/include/linux/kern_levels.h +++ b/tools/include/linux/kern_levels.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __KERN_LEVELS_H__ #define __KERN_LEVELS_H__ diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h index 77d2e94ca5df..0ad884452c5c 100644 --- a/tools/include/linux/kernel.h +++ b/tools/include/linux/kernel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_LINUX_KERNEL_H #define __TOOLS_LINUX_KERNEL_H diff --git a/tools/include/linux/kmemcheck.h b/tools/include/linux/kmemcheck.h index 94d598bc6abe..2bccd2c7b897 100644 --- a/tools/include/linux/kmemcheck.h +++ b/tools/include/linux/kmemcheck.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_LINUX_KMEMCHECK_H_ #define _LIBLOCKDEP_LINUX_KMEMCHECK_H_ diff --git a/tools/include/linux/list.h b/tools/include/linux/list.h index 1da423820ad4..b2fc48d5478c 100644 --- a/tools/include/linux/list.h +++ b/tools/include/linux/list.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_LINUX_LIST_H #define __TOOLS_LINUX_LIST_H diff --git a/tools/include/linux/lockdep.h b/tools/include/linux/lockdep.h index 8da3e8effafa..940c1b075659 100644 --- a/tools/include/linux/lockdep.h +++ b/tools/include/linux/lockdep.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_LOCKDEP_H_ #define _LIBLOCKDEP_LOCKDEP_H_ diff --git a/tools/include/linux/module.h b/tools/include/linux/module.h index 07055db296f3..2c999abf68e7 100644 --- a/tools/include/linux/module.h +++ b/tools/include/linux/module.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_LINUX_MODULE_H_ #define _LIBLOCKDEP_LINUX_MODULE_H_ diff --git a/tools/include/linux/poison.h b/tools/include/linux/poison.h index 51334edec506..4bf6777a8a03 100644 --- a/tools/include/linux/poison.h +++ b/tools/include/linux/poison.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_POISON_H #define _LINUX_POISON_H diff --git a/tools/include/linux/rcu.h b/tools/include/linux/rcu.h index 5080649dad04..7d02527e5bce 100644 --- a/tools/include/linux/rcu.h +++ b/tools/include/linux/rcu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_RCU_H_ #define _LIBLOCKDEP_RCU_H_ diff --git a/tools/include/linux/refcount.h b/tools/include/linux/refcount.h index a0177c1f55b1..36cb29bc57c2 100644 --- a/tools/include/linux/refcount.h +++ b/tools/include/linux/refcount.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_REFCOUNT_H #define _TOOLS_LINUX_REFCOUNT_H diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h index 417cda4f793f..4ed569fcb139 100644 --- a/tools/include/linux/spinlock.h +++ b/tools/include/linux/spinlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_SPINLOCK_H_ #define __LINUX_SPINLOCK_H_ diff --git a/tools/include/linux/stacktrace.h b/tools/include/linux/stacktrace.h index 39aecc6b19d1..ae343ac35bfa 100644 --- a/tools/include/linux/stacktrace.h +++ b/tools/include/linux/stacktrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_LINUX_STACKTRACE_H_ #define _LIBLOCKDEP_LINUX_STACKTRACE_H_ diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index d62b56cf8c12..6c3e2cc274c5 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -1,8 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_STRING_H_ #define _TOOLS_LINUX_STRING_H_ - #include /* for size_t */ +#include void *memdup(const void *src, size_t len); @@ -18,6 +19,14 @@ extern size_t strlcpy(char *dest, const char *src, size_t size); char *str_error_r(int errnum, char *buf, size_t buflen); -int prefixcmp(const char *str, const char *prefix); +/** + * strstarts - does @str start with @prefix? + * @str: string to examine + * @prefix: prefix to look for. + */ +static inline bool strstarts(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)) == 0; +} #endif /* _LINUX_STRING_H_ */ diff --git a/tools/include/linux/stringify.h b/tools/include/linux/stringify.h index 841cec8ed525..60e2c187da2c 100644 --- a/tools/include/linux/stringify.h +++ b/tools/include/linux/stringify.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_STRINGIFY_H #define __LINUX_STRINGIFY_H diff --git a/tools/include/linux/time64.h b/tools/include/linux/time64.h index df9265483d65..55fa644b95fd 100644 --- a/tools/include/linux/time64.h +++ b/tools/include/linux/time64.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_TIME64_H #define _TOOLS_LINUX_TIME64_H diff --git a/tools/include/linux/types.h b/tools/include/linux/types.h index 77a28a26a670..154eb4e3ca7c 100644 --- a/tools/include/linux/types.h +++ b/tools/include/linux/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LINUX_TYPES_H_ #define _TOOLS_LINUX_TYPES_H_ diff --git a/tools/include/linux/unaligned/packed_struct.h b/tools/include/linux/unaligned/packed_struct.h index c0d817de4df2..dbd93c7df2e1 100644 --- a/tools/include/linux/unaligned/packed_struct.h +++ b/tools/include/linux/unaligned/packed_struct.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LINUX_UNALIGNED_PACKED_STRUCT_H #define _LINUX_UNALIGNED_PACKED_STRUCT_H diff --git a/tools/include/tools/be_byteshift.h b/tools/include/tools/be_byteshift.h index 84c17d836578..f7d1d1698938 100644 --- a/tools/include/tools/be_byteshift.h +++ b/tools/include/tools/be_byteshift.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_BE_BYTESHIFT_H #define _TOOLS_BE_BYTESHIFT_H diff --git a/tools/include/tools/endian.h b/tools/include/tools/endian.h index 8001194008da..c67888fd427e 100644 --- a/tools/include/tools/endian.h +++ b/tools/include/tools/endian.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_ENDIAN_H #define _TOOLS_ENDIAN_H diff --git a/tools/include/tools/le_byteshift.h b/tools/include/tools/le_byteshift.h index 8fe9f2488ec7..dc8565f39717 100644 --- a/tools/include/tools/le_byteshift.h +++ b/tools/include/tools/le_byteshift.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TOOLS_LE_BYTESHIFT_H #define _TOOLS_LE_BYTESHIFT_H diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h new file mode 100644 index 000000000000..ac190958c981 --- /dev/null +++ b/tools/include/uapi/asm-generic/fcntl.h @@ -0,0 +1,220 @@ +#ifndef _ASM_GENERIC_FCNTL_H +#define _ASM_GENERIC_FCNTL_H + +#include + +/* + * FMODE_EXEC is 0x20 + * FMODE_NONOTIFY is 0x4000000 + * These cannot be used by userspace O_* until internal and external open + * flags are split. + * -Eric Paris + */ + +/* + * When introducing new O_* bits, please check its uniqueness in fcntl_init(). + */ + +#define O_ACCMODE 00000003 +#define O_RDONLY 00000000 +#define O_WRONLY 00000001 +#define O_RDWR 00000002 +#ifndef O_CREAT +#define O_CREAT 00000100 /* not fcntl */ +#endif +#ifndef O_EXCL +#define O_EXCL 00000200 /* not fcntl */ +#endif +#ifndef O_NOCTTY +#define O_NOCTTY 00000400 /* not fcntl */ +#endif +#ifndef O_TRUNC +#define O_TRUNC 00001000 /* not fcntl */ +#endif +#ifndef O_APPEND +#define O_APPEND 00002000 +#endif +#ifndef O_NONBLOCK +#define O_NONBLOCK 00004000 +#endif +#ifndef O_DSYNC +#define O_DSYNC 00010000 /* used to be O_SYNC, see below */ +#endif +#ifndef FASYNC +#define FASYNC 00020000 /* fcntl, for BSD compatibility */ +#endif +#ifndef O_DIRECT +#define O_DIRECT 00040000 /* direct disk access hint */ +#endif +#ifndef O_LARGEFILE +#define O_LARGEFILE 00100000 +#endif +#ifndef O_DIRECTORY +#define O_DIRECTORY 00200000 /* must be a directory */ +#endif +#ifndef O_NOFOLLOW +#define O_NOFOLLOW 00400000 /* don't follow links */ +#endif +#ifndef O_NOATIME +#define O_NOATIME 01000000 +#endif +#ifndef O_CLOEXEC +#define O_CLOEXEC 02000000 /* set close_on_exec */ +#endif + +/* + * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using + * the O_SYNC flag. We continue to use the existing numerical value + * for O_DSYNC semantics now, but using the correct symbolic name for it. + * This new value is used to request true Posix O_SYNC semantics. It is + * defined in this strange way to make sure applications compiled against + * new headers get at least O_DSYNC semantics on older kernels. + * + * This has the nice side-effect that we can simply test for O_DSYNC + * wherever we do not care if O_DSYNC or O_SYNC is used. + * + * Note: __O_SYNC must never be used directly. + */ +#ifndef O_SYNC +#define __O_SYNC 04000000 +#define O_SYNC (__O_SYNC|O_DSYNC) +#endif + +#ifndef O_PATH +#define O_PATH 010000000 +#endif + +#ifndef __O_TMPFILE +#define __O_TMPFILE 020000000 +#endif + +/* a horrid kludge trying to make sure that this will fail on old kernels */ +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) +#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) + +#ifndef O_NDELAY +#define O_NDELAY O_NONBLOCK +#endif + +#define F_DUPFD 0 /* dup */ +#define F_GETFD 1 /* get close_on_exec */ +#define F_SETFD 2 /* set/clear close_on_exec */ +#define F_GETFL 3 /* get file->f_flags */ +#define F_SETFL 4 /* set file->f_flags */ +#ifndef F_GETLK +#define F_GETLK 5 +#define F_SETLK 6 +#define F_SETLKW 7 +#endif +#ifndef F_SETOWN +#define F_SETOWN 8 /* for sockets. */ +#define F_GETOWN 9 /* for sockets. */ +#endif +#ifndef F_SETSIG +#define F_SETSIG 10 /* for sockets. */ +#define F_GETSIG 11 /* for sockets. */ +#endif + +#ifndef CONFIG_64BIT +#ifndef F_GETLK64 +#define F_GETLK64 12 /* using 'struct flock64' */ +#define F_SETLK64 13 +#define F_SETLKW64 14 +#endif +#endif + +#ifndef F_SETOWN_EX +#define F_SETOWN_EX 15 +#define F_GETOWN_EX 16 +#endif + +#ifndef F_GETOWNER_UIDS +#define F_GETOWNER_UIDS 17 +#endif + +/* + * Open File Description Locks + * + * Usually record locks held by a process are released on *any* close and are + * not inherited across a fork(). + * + * These cmd values will set locks that conflict with process-associated + * record locks, but are "owned" by the open file description, not the + * process. This means that they are inherited across fork() like BSD (flock) + * locks, and they are only released automatically when the last reference to + * the the open file against which they were acquired is put. + */ +#define F_OFD_GETLK 36 +#define F_OFD_SETLK 37 +#define F_OFD_SETLKW 38 + +#define F_OWNER_TID 0 +#define F_OWNER_PID 1 +#define F_OWNER_PGRP 2 + +struct f_owner_ex { + int type; + __kernel_pid_t pid; +}; + +/* for F_[GET|SET]FL */ +#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +/* for posix fcntl() and lockf() */ +#ifndef F_RDLCK +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 +#endif + +/* for old implementation of bsd flock () */ +#ifndef F_EXLCK +#define F_EXLCK 4 /* or 3 */ +#define F_SHLCK 8 /* or 4 */ +#endif + +/* operations for bsd flock(), also used by the kernel implementation */ +#define LOCK_SH 1 /* shared lock */ +#define LOCK_EX 2 /* exclusive lock */ +#define LOCK_NB 4 /* or'd with one of the above to prevent + blocking */ +#define LOCK_UN 8 /* remove lock */ + +#define LOCK_MAND 32 /* This is a mandatory flock ... */ +#define LOCK_READ 64 /* which allows concurrent read operations */ +#define LOCK_WRITE 128 /* which allows concurrent write operations */ +#define LOCK_RW 192 /* which allows concurrent read & write ops */ + +#define F_LINUX_SPECIFIC_BASE 1024 + +#ifndef HAVE_ARCH_STRUCT_FLOCK +#ifndef __ARCH_FLOCK_PAD +#define __ARCH_FLOCK_PAD +#endif + +struct flock { + short l_type; + short l_whence; + __kernel_off_t l_start; + __kernel_off_t l_len; + __kernel_pid_t l_pid; + __ARCH_FLOCK_PAD +}; +#endif + +#ifndef HAVE_ARCH_STRUCT_FLOCK64 +#ifndef __ARCH_FLOCK64_PAD +#define __ARCH_FLOCK64_PAD +#endif + +struct flock64 { + short l_type; + short l_whence; + __kernel_loff_t l_start; + __kernel_loff_t l_len; + __kernel_pid_t l_pid; + __ARCH_FLOCK64_PAD +}; +#endif + +#endif /* _ASM_GENERIC_FCNTL_H */ diff --git a/tools/include/uapi/asm-generic/ioctls.h b/tools/include/uapi/asm-generic/ioctls.h new file mode 100644 index 000000000000..040651735662 --- /dev/null +++ b/tools/include/uapi/asm-generic/ioctls.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __ASM_GENERIC_IOCTLS_H +#define __ASM_GENERIC_IOCTLS_H + +#include + +/* + * These are the most common definitions for tty ioctl numbers. + * Most of them do not use the recommended _IOC(), but there is + * probably some source code out there hardcoding the number, + * so we might as well use them for all new platforms. + * + * The architectures that use different values here typically + * try to be compatible with some Unix variants for the same + * architecture. + */ + +/* 0x54 is just a magic number to make these relatively unique ('T') */ + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 +#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TCGETS2 _IOR('T', 0x2A, struct termios2) +#define TCSETS2 _IOW('T', 0x2B, struct termios2) +#define TCSETSW2 _IOW('T', 0x2C, struct termios2) +#define TCSETSF2 _IOW('T', 0x2D, struct termios2) +#define TIOCGRS485 0x542E +#ifndef TIOCSRS485 +#define TIOCSRS485 0x542F +#endif +#define TIOCGPTN _IOR('T', 0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ +#define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */ +#define TCGETX 0x5432 /* SYS5 TCGETX compatibility */ +#define TCSETX 0x5433 +#define TCSETXF 0x5434 +#define TCSETXW 0x5435 +#define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */ +#define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ +#define TIOCGPTPEER _IO('T', 0x41) /* Safely open the slave */ + +#define FIONCLEX 0x5450 +#define FIOCLEX 0x5451 +#define FIOASYNC 0x5452 +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 +#define TIOCGLCKTRMIOS 0x5456 +#define TIOCSLCKTRMIOS 0x5457 +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ + +/* + * Some arches already define FIOQSIZE due to a historical + * conflict with a Hayes modem-specific ioctl value. + */ +#ifndef FIOQSIZE +# define FIOQSIZE 0x5460 +#endif + +/* Used for packet mode */ +#define TIOCPKT_DATA 0 +#define TIOCPKT_FLUSHREAD 1 +#define TIOCPKT_FLUSHWRITE 2 +#define TIOCPKT_STOP 4 +#define TIOCPKT_START 8 +#define TIOCPKT_NOSTOP 16 +#define TIOCPKT_DOSTOP 32 +#define TIOCPKT_IOCTL 64 + +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + +#endif /* __ASM_GENERIC_IOCTLS_H */ diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h index 8c27db0c5c08..6d319c46fd90 100644 --- a/tools/include/uapi/asm-generic/mman-common.h +++ b/tools/include/uapi/asm-generic/mman-common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_GENERIC_MMAN_COMMON_H #define __ASM_GENERIC_MMAN_COMMON_H @@ -58,20 +59,12 @@ overrides the coredump filter bits */ #define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + /* compatibility flags */ #define MAP_FILE 0 -/* - * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. - * This gives us 6 bits, which is enough until someone invents 128 bit address - * spaces. - * - * Assume these are all power of twos. - * When 0 use the default page size. - */ -#define MAP_HUGE_SHIFT 26 -#define MAP_HUGE_MASK 0x3f - #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ diff --git a/tools/include/uapi/asm-generic/mman.h b/tools/include/uapi/asm-generic/mman.h index 10fa7857777f..2dffcbf705b3 100644 --- a/tools/include/uapi/asm-generic/mman.h +++ b/tools/include/uapi/asm-generic/mman.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef __ASM_GENERIC_MMAN_H #define __ASM_GENERIC_MMAN_H -#include +#include #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ diff --git a/tools/include/uapi/drm/drm.h b/tools/include/uapi/drm/drm.h new file mode 100644 index 000000000000..97677cd6964d --- /dev/null +++ b/tools/include/uapi/drm/drm.h @@ -0,0 +1,955 @@ +/** + * \file drm.h + * Header for the Direct Rendering Manager + * + * \author Rickard E. (Rik) Faith + * + * \par Acknowledgments: + * Dec 1999, Richard Henderson , move to generic \c cmpxchg. + */ + +/* + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DRM_H_ +#define _DRM_H_ + +#if defined(__KERNEL__) + +#include +#include +typedef unsigned int drm_handle_t; + +#elif defined(__linux__) + +#include +#include +typedef unsigned int drm_handle_t; + +#else /* One of the BSDs */ + +#include +#include +typedef int8_t __s8; +typedef uint8_t __u8; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef int32_t __s32; +typedef uint32_t __u32; +typedef int64_t __s64; +typedef uint64_t __u64; +typedef size_t __kernel_size_t; +typedef unsigned long drm_handle_t; + +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ +#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ +#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ +#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ + +#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ +#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ +#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) +#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) +#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) + +typedef unsigned int drm_context_t; +typedef unsigned int drm_drawable_t; +typedef unsigned int drm_magic_t; + +/** + * Cliprect. + * + * \warning: If you change this structure, make sure you change + * XF86DRIClipRectRec in the server as well + * + * \note KW: Actually it's illegal to change either for + * backwards-compatibility reasons. + */ +struct drm_clip_rect { + unsigned short x1; + unsigned short y1; + unsigned short x2; + unsigned short y2; +}; + +/** + * Drawable information. + */ +struct drm_drawable_info { + unsigned int num_rects; + struct drm_clip_rect *rects; +}; + +/** + * Texture region, + */ +struct drm_tex_region { + unsigned char next; + unsigned char prev; + unsigned char in_use; + unsigned char padding; + unsigned int age; +}; + +/** + * Hardware lock. + * + * The lock structure is a simple cache-line aligned integer. To avoid + * processor bus contention on a multiprocessor system, there should not be any + * other data stored in the same cache line. + */ +struct drm_hw_lock { + __volatile__ unsigned int lock; /**< lock variable */ + char padding[60]; /**< Pad to cache line */ +}; + +/** + * DRM_IOCTL_VERSION ioctl argument type. + * + * \sa drmGetVersion(). + */ +struct drm_version { + int version_major; /**< Major version */ + int version_minor; /**< Minor version */ + int version_patchlevel; /**< Patch level */ + __kernel_size_t name_len; /**< Length of name buffer */ + char __user *name; /**< Name of driver */ + __kernel_size_t date_len; /**< Length of date buffer */ + char __user *date; /**< User-space buffer to hold date */ + __kernel_size_t desc_len; /**< Length of desc buffer */ + char __user *desc; /**< User-space buffer to hold desc */ +}; + +/** + * DRM_IOCTL_GET_UNIQUE ioctl argument type. + * + * \sa drmGetBusid() and drmSetBusId(). + */ +struct drm_unique { + __kernel_size_t unique_len; /**< Length of unique */ + char __user *unique; /**< Unique name for driver instantiation */ +}; + +struct drm_list { + int count; /**< Length of user-space structures */ + struct drm_version __user *version; +}; + +struct drm_block { + int unused; +}; + +/** + * DRM_IOCTL_CONTROL ioctl argument type. + * + * \sa drmCtlInstHandler() and drmCtlUninstHandler(). + */ +struct drm_control { + enum { + DRM_ADD_COMMAND, + DRM_RM_COMMAND, + DRM_INST_HANDLER, + DRM_UNINST_HANDLER + } func; + int irq; +}; + +/** + * Type of memory to map. + */ +enum drm_map_type { + _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ + _DRM_REGISTERS = 1, /**< no caching, no core dump */ + _DRM_SHM = 2, /**< shared, cached */ + _DRM_AGP = 3, /**< AGP/GART */ + _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ + _DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */ +}; + +/** + * Memory mapping flags. + */ +enum drm_map_flags { + _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ + _DRM_READ_ONLY = 0x02, + _DRM_LOCKED = 0x04, /**< shared, cached, locked */ + _DRM_KERNEL = 0x08, /**< kernel requires access */ + _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ + _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ + _DRM_REMOVABLE = 0x40, /**< Removable mapping */ + _DRM_DRIVER = 0x80 /**< Managed by driver */ +}; + +struct drm_ctx_priv_map { + unsigned int ctx_id; /**< Context requesting private mapping */ + void *handle; /**< Handle of map */ +}; + +/** + * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls + * argument type. + * + * \sa drmAddMap(). + */ +struct drm_map { + unsigned long offset; /**< Requested physical address (0 for SAREA)*/ + unsigned long size; /**< Requested physical size (bytes) */ + enum drm_map_type type; /**< Type of memory to map */ + enum drm_map_flags flags; /**< Flags */ + void *handle; /**< User-space: "Handle" to pass to mmap() */ + /**< Kernel-space: kernel-virtual address */ + int mtrr; /**< MTRR slot used */ + /* Private data */ +}; + +/** + * DRM_IOCTL_GET_CLIENT ioctl argument type. + */ +struct drm_client { + int idx; /**< Which client desired? */ + int auth; /**< Is client authenticated? */ + unsigned long pid; /**< Process ID */ + unsigned long uid; /**< User ID */ + unsigned long magic; /**< Magic */ + unsigned long iocs; /**< Ioctl count */ +}; + +enum drm_stat_type { + _DRM_STAT_LOCK, + _DRM_STAT_OPENS, + _DRM_STAT_CLOSES, + _DRM_STAT_IOCTLS, + _DRM_STAT_LOCKS, + _DRM_STAT_UNLOCKS, + _DRM_STAT_VALUE, /**< Generic value */ + _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */ + _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */ + + _DRM_STAT_IRQ, /**< IRQ */ + _DRM_STAT_PRIMARY, /**< Primary DMA bytes */ + _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */ + _DRM_STAT_DMA, /**< DMA */ + _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ + _DRM_STAT_MISSED /**< Missed DMA opportunity */ + /* Add to the *END* of the list */ +}; + +/** + * DRM_IOCTL_GET_STATS ioctl argument type. + */ +struct drm_stats { + unsigned long count; + struct { + unsigned long value; + enum drm_stat_type type; + } data[15]; +}; + +/** + * Hardware locking flags. + */ +enum drm_lock_flags { + _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ + _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ + _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ + _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ + /* These *HALT* flags aren't supported yet + -- they will be used to support the + full-screen DGA-like mode. */ + _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ + _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ +}; + +/** + * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. + * + * \sa drmGetLock() and drmUnlock(). + */ +struct drm_lock { + int context; + enum drm_lock_flags flags; +}; + +/** + * DMA flags + * + * \warning + * These values \e must match xf86drm.h. + * + * \sa drm_dma. + */ +enum drm_dma_flags { + /* Flags for DMA buffer dispatch */ + _DRM_DMA_BLOCK = 0x01, /**< + * Block until buffer dispatched. + * + * \note The buffer may not yet have + * been processed by the hardware -- + * getting a hardware lock with the + * hardware quiescent will ensure + * that the buffer has been + * processed. + */ + _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ + _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ + + /* Flags for DMA buffer request */ + _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ + _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ + _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ +}; + +/** + * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. + * + * \sa drmAddBufs(). + */ +struct drm_buf_desc { + int count; /**< Number of buffers of this size */ + int size; /**< Size in bytes */ + int low_mark; /**< Low water mark */ + int high_mark; /**< High water mark */ + enum { + _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ + _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ + _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ + _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ + _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */ + } flags; + unsigned long agp_start; /**< + * Start address of where the AGP buffers are + * in the AGP aperture + */ +}; + +/** + * DRM_IOCTL_INFO_BUFS ioctl argument type. + */ +struct drm_buf_info { + int count; /**< Entries in list */ + struct drm_buf_desc __user *list; +}; + +/** + * DRM_IOCTL_FREE_BUFS ioctl argument type. + */ +struct drm_buf_free { + int count; + int __user *list; +}; + +/** + * Buffer information + * + * \sa drm_buf_map. + */ +struct drm_buf_pub { + int idx; /**< Index into the master buffer list */ + int total; /**< Buffer size */ + int used; /**< Amount of buffer in use (for DMA) */ + void __user *address; /**< Address of buffer */ +}; + +/** + * DRM_IOCTL_MAP_BUFS ioctl argument type. + */ +struct drm_buf_map { + int count; /**< Length of the buffer list */ +#ifdef __cplusplus + void __user *virt; +#else + void __user *virtual; /**< Mmap'd area in user-virtual */ +#endif + struct drm_buf_pub __user *list; /**< Buffer information */ +}; + +/** + * DRM_IOCTL_DMA ioctl argument type. + * + * Indices here refer to the offset into the buffer list in drm_buf_get. + * + * \sa drmDMA(). + */ +struct drm_dma { + int context; /**< Context handle */ + int send_count; /**< Number of buffers to send */ + int __user *send_indices; /**< List of handles to buffers */ + int __user *send_sizes; /**< Lengths of data to send */ + enum drm_dma_flags flags; /**< Flags */ + int request_count; /**< Number of buffers requested */ + int request_size; /**< Desired size for buffers */ + int __user *request_indices; /**< Buffer information */ + int __user *request_sizes; + int granted_count; /**< Number of buffers granted */ +}; + +enum drm_ctx_flags { + _DRM_CONTEXT_PRESERVED = 0x01, + _DRM_CONTEXT_2DONLY = 0x02 +}; + +/** + * DRM_IOCTL_ADD_CTX ioctl argument type. + * + * \sa drmCreateContext() and drmDestroyContext(). + */ +struct drm_ctx { + drm_context_t handle; + enum drm_ctx_flags flags; +}; + +/** + * DRM_IOCTL_RES_CTX ioctl argument type. + */ +struct drm_ctx_res { + int count; + struct drm_ctx __user *contexts; +}; + +/** + * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. + */ +struct drm_draw { + drm_drawable_t handle; +}; + +/** + * DRM_IOCTL_UPDATE_DRAW ioctl argument type. + */ +typedef enum { + DRM_DRAWABLE_CLIPRECTS +} drm_drawable_info_type_t; + +struct drm_update_draw { + drm_drawable_t handle; + unsigned int type; + unsigned int num; + unsigned long long data; +}; + +/** + * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. + */ +struct drm_auth { + drm_magic_t magic; +}; + +/** + * DRM_IOCTL_IRQ_BUSID ioctl argument type. + * + * \sa drmGetInterruptFromBusID(). + */ +struct drm_irq_busid { + int irq; /**< IRQ number */ + int busnum; /**< bus number */ + int devnum; /**< device number */ + int funcnum; /**< function number */ +}; + +enum drm_vblank_seq_type { + _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ + _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ + /* bits 1-6 are reserved for high crtcs */ + _DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e, + _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ + _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ + _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ + _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ + _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */ +}; +#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1 + +#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) +#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ + _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS) + +struct drm_wait_vblank_request { + enum drm_vblank_seq_type type; + unsigned int sequence; + unsigned long signal; +}; + +struct drm_wait_vblank_reply { + enum drm_vblank_seq_type type; + unsigned int sequence; + long tval_sec; + long tval_usec; +}; + +/** + * DRM_IOCTL_WAIT_VBLANK ioctl argument type. + * + * \sa drmWaitVBlank(). + */ +union drm_wait_vblank { + struct drm_wait_vblank_request request; + struct drm_wait_vblank_reply reply; +}; + +#define _DRM_PRE_MODESET 1 +#define _DRM_POST_MODESET 2 + +/** + * DRM_IOCTL_MODESET_CTL ioctl argument type + * + * \sa drmModesetCtl(). + */ +struct drm_modeset_ctl { + __u32 crtc; + __u32 cmd; +}; + +/** + * DRM_IOCTL_AGP_ENABLE ioctl argument type. + * + * \sa drmAgpEnable(). + */ +struct drm_agp_mode { + unsigned long mode; /**< AGP mode */ +}; + +/** + * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. + * + * \sa drmAgpAlloc() and drmAgpFree(). + */ +struct drm_agp_buffer { + unsigned long size; /**< In bytes -- will round to page boundary */ + unsigned long handle; /**< Used for binding / unbinding */ + unsigned long type; /**< Type of memory to allocate */ + unsigned long physical; /**< Physical used by i810 */ +}; + +/** + * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. + * + * \sa drmAgpBind() and drmAgpUnbind(). + */ +struct drm_agp_binding { + unsigned long handle; /**< From drm_agp_buffer */ + unsigned long offset; /**< In bytes -- will round to page boundary */ +}; + +/** + * DRM_IOCTL_AGP_INFO ioctl argument type. + * + * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(), + * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(), + * drmAgpVendorId() and drmAgpDeviceId(). + */ +struct drm_agp_info { + int agp_version_major; + int agp_version_minor; + unsigned long mode; + unsigned long aperture_base; /* physical address */ + unsigned long aperture_size; /* bytes */ + unsigned long memory_allowed; /* bytes */ + unsigned long memory_used; + + /* PCI information */ + unsigned short id_vendor; + unsigned short id_device; +}; + +/** + * DRM_IOCTL_SG_ALLOC ioctl argument type. + */ +struct drm_scatter_gather { + unsigned long size; /**< In bytes -- will round to page boundary */ + unsigned long handle; /**< Used for mapping / unmapping */ +}; + +/** + * DRM_IOCTL_SET_VERSION ioctl argument type. + */ +struct drm_set_version { + int drm_di_major; + int drm_di_minor; + int drm_dd_major; + int drm_dd_minor; +}; + +/** DRM_IOCTL_GEM_CLOSE ioctl argument type */ +struct drm_gem_close { + /** Handle of the object to be closed. */ + __u32 handle; + __u32 pad; +}; + +/** DRM_IOCTL_GEM_FLINK ioctl argument type */ +struct drm_gem_flink { + /** Handle for the object being named */ + __u32 handle; + + /** Returned global name */ + __u32 name; +}; + +/** DRM_IOCTL_GEM_OPEN ioctl argument type */ +struct drm_gem_open { + /** Name of object being opened */ + __u32 name; + + /** Returned handle for the object */ + __u32 handle; + + /** Returned size of the object */ + __u64 size; +}; + +#define DRM_CAP_DUMB_BUFFER 0x1 +#define DRM_CAP_VBLANK_HIGH_CRTC 0x2 +#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 +#define DRM_CAP_DUMB_PREFER_SHADOW 0x4 +#define DRM_CAP_PRIME 0x5 +#define DRM_PRIME_CAP_IMPORT 0x1 +#define DRM_PRIME_CAP_EXPORT 0x2 +#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 +#define DRM_CAP_ASYNC_PAGE_FLIP 0x7 +/* + * The CURSOR_WIDTH and CURSOR_HEIGHT capabilities return a valid widthxheight + * combination for the hardware cursor. The intention is that a hardware + * agnostic userspace can query a cursor plane size to use. + * + * Note that the cross-driver contract is to merely return a valid size; + * drivers are free to attach another meaning on top, eg. i915 returns the + * maximum plane size. + */ +#define DRM_CAP_CURSOR_WIDTH 0x8 +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#define DRM_CAP_ADDFB2_MODIFIERS 0x10 +#define DRM_CAP_PAGE_FLIP_TARGET 0x11 +#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12 +#define DRM_CAP_SYNCOBJ 0x13 + +/** DRM_IOCTL_GET_CAP ioctl argument type */ +struct drm_get_cap { + __u64 capability; + __u64 value; +}; + +/** + * DRM_CLIENT_CAP_STEREO_3D + * + * if set to 1, the DRM core will expose the stereo 3D capabilities of the + * monitor by advertising the supported 3D layouts in the flags of struct + * drm_mode_modeinfo. + */ +#define DRM_CLIENT_CAP_STEREO_3D 1 + +/** + * DRM_CLIENT_CAP_UNIVERSAL_PLANES + * + * If set to 1, the DRM core will expose all planes (overlay, primary, and + * cursor) to userspace. + */ +#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 + +/** + * DRM_CLIENT_CAP_ATOMIC + * + * If set to 1, the DRM core will expose atomic properties to userspace + */ +#define DRM_CLIENT_CAP_ATOMIC 3 + +/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ +struct drm_set_client_cap { + __u64 capability; + __u64 value; +}; + +#define DRM_RDWR O_RDWR +#define DRM_CLOEXEC O_CLOEXEC +struct drm_prime_handle { + __u32 handle; + + /** Flags.. only applicable for handle->fd */ + __u32 flags; + + /** Returned dmabuf file descriptor */ + __s32 fd; +}; + +struct drm_syncobj_create { + __u32 handle; +#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0) + __u32 flags; +}; + +struct drm_syncobj_destroy { + __u32 handle; + __u32 pad; +}; + +#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0) +#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0) +struct drm_syncobj_handle { + __u32 handle; + __u32 flags; + + __s32 fd; + __u32 pad; +}; + +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) +#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) +struct drm_syncobj_wait { + __u64 handles; + /* absolute timeout */ + __s64 timeout_nsec; + __u32 count_handles; + __u32 flags; + __u32 first_signaled; /* only valid when not waiting all */ + __u32 pad; +}; + +struct drm_syncobj_array { + __u64 handles; + __u32 count_handles; + __u32 pad; +}; + +#if defined(__cplusplus) +} +#endif + +#include "drm_mode.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) +#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) +#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) + +#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version) +#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique) +#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth) +#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid) +#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map) +#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) +#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) +#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) +#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) +#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close) +#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) +#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) +#define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap) +#define DRM_IOCTL_SET_CLIENT_CAP DRM_IOW( 0x0d, struct drm_set_client_cap) + +#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) +#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) +#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block) +#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block) +#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control) +#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map) +#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc) +#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc) +#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info) +#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map) +#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free) + +#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map) + +#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) +#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) + +#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) +#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) + +#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) +#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) +#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) +#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx) +#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx) +#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx) +#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res) +#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw) +#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw) +#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma) +#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock) +#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) +#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) + +#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle) +#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle) + +#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) +#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) +#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) +#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer) +#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding) + +#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather) +#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather) + +#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) + +#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) + +#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) +#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor) +#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder) +#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector) +#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) /* deprecated (never worked) */ +#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) /* deprecated (never worked) */ + +#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property) +#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property) +#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) +#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) +#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) +#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) + +#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb) +#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb) +#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) +#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) +#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) +#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) +#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2) +#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) +#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) +#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) +#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) +#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob) +#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob) + +#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create) +#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy) +#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle) +#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle) +#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait) +#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array) +#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array) + +/** + * Device specific ioctls should only be in their respective headers + * The device specific ioctl range is from 0x40 to 0x9f. + * Generic IOCTLS restart at 0xA0. + * + * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and + * drmCommandReadWrite(). + */ +#define DRM_COMMAND_BASE 0x40 +#define DRM_COMMAND_END 0xA0 + +/** + * Header for events written back to userspace on the drm fd. The + * type defines the type of event, the length specifies the total + * length of the event (including the header), and user_data is + * typically a 64 bit value passed with the ioctl that triggered the + * event. A read on the drm fd will always only return complete + * events, that is, if for example the read buffer is 100 bytes, and + * there are two 64 byte events pending, only one will be returned. + * + * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and + * up are chipset specific. + */ +struct drm_event { + __u32 type; + __u32 length; +}; + +#define DRM_EVENT_VBLANK 0x01 +#define DRM_EVENT_FLIP_COMPLETE 0x02 + +struct drm_event_vblank { + struct drm_event base; + __u64 user_data; + __u32 tv_sec; + __u32 tv_usec; + __u32 sequence; + __u32 crtc_id; /* 0 on older kernels that do not support this */ +}; + +/* typedef area */ +#ifndef __KERNEL__ +typedef struct drm_clip_rect drm_clip_rect_t; +typedef struct drm_drawable_info drm_drawable_info_t; +typedef struct drm_tex_region drm_tex_region_t; +typedef struct drm_hw_lock drm_hw_lock_t; +typedef struct drm_version drm_version_t; +typedef struct drm_unique drm_unique_t; +typedef struct drm_list drm_list_t; +typedef struct drm_block drm_block_t; +typedef struct drm_control drm_control_t; +typedef enum drm_map_type drm_map_type_t; +typedef enum drm_map_flags drm_map_flags_t; +typedef struct drm_ctx_priv_map drm_ctx_priv_map_t; +typedef struct drm_map drm_map_t; +typedef struct drm_client drm_client_t; +typedef enum drm_stat_type drm_stat_type_t; +typedef struct drm_stats drm_stats_t; +typedef enum drm_lock_flags drm_lock_flags_t; +typedef struct drm_lock drm_lock_t; +typedef enum drm_dma_flags drm_dma_flags_t; +typedef struct drm_buf_desc drm_buf_desc_t; +typedef struct drm_buf_info drm_buf_info_t; +typedef struct drm_buf_free drm_buf_free_t; +typedef struct drm_buf_pub drm_buf_pub_t; +typedef struct drm_buf_map drm_buf_map_t; +typedef struct drm_dma drm_dma_t; +typedef union drm_wait_vblank drm_wait_vblank_t; +typedef struct drm_agp_mode drm_agp_mode_t; +typedef enum drm_ctx_flags drm_ctx_flags_t; +typedef struct drm_ctx drm_ctx_t; +typedef struct drm_ctx_res drm_ctx_res_t; +typedef struct drm_draw drm_draw_t; +typedef struct drm_update_draw drm_update_draw_t; +typedef struct drm_auth drm_auth_t; +typedef struct drm_irq_busid drm_irq_busid_t; +typedef enum drm_vblank_seq_type drm_vblank_seq_type_t; + +typedef struct drm_agp_buffer drm_agp_buffer_t; +typedef struct drm_agp_binding drm_agp_binding_t; +typedef struct drm_agp_info drm_agp_info_t; +typedef struct drm_scatter_gather drm_scatter_gather_t; +typedef struct drm_set_version drm_set_version_t; +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/tools/include/uapi/drm/i915_drm.h b/tools/include/uapi/drm/i915_drm.h new file mode 100644 index 000000000000..9816590d3ad2 --- /dev/null +++ b/tools/include/uapi/drm/i915_drm.h @@ -0,0 +1,1522 @@ +/* + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _UAPI_I915_DRM_H_ +#define _UAPI_I915_DRM_H_ + +#include "drm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Please note that modifications to all structs defined here are + * subject to backwards-compatibility constraints. + */ + +/** + * DOC: uevents generated by i915 on it's device node + * + * I915_L3_PARITY_UEVENT - Generated when the driver receives a parity mismatch + * event from the gpu l3 cache. Additional information supplied is ROW, + * BANK, SUBBANK, SLICE of the affected cacheline. Userspace should keep + * track of these events and if a specific cache-line seems to have a + * persistent error remap it with the l3 remapping tool supplied in + * intel-gpu-tools. The value supplied with the event is always 1. + * + * I915_ERROR_UEVENT - Generated upon error detection, currently only via + * hangcheck. The error detection event is a good indicator of when things + * began to go badly. The value supplied with the event is a 1 upon error + * detection, and a 0 upon reset completion, signifying no more error + * exists. NOTE: Disabling hangcheck or reset via module parameter will + * cause the related events to not be seen. + * + * I915_RESET_UEVENT - Event is generated just before an attempt to reset the + * the GPU. The value supplied with the event is always 1. NOTE: Disable + * reset via module parameter will cause this event to not be seen. + */ +#define I915_L3_PARITY_UEVENT "L3_PARITY_ERROR" +#define I915_ERROR_UEVENT "ERROR" +#define I915_RESET_UEVENT "RESET" + +/* + * MOCS indexes used for GPU surfaces, defining the cacheability of the + * surface data and the coherency for this data wrt. CPU vs. GPU accesses. + */ +enum i915_mocs_table_index { + /* + * Not cached anywhere, coherency between CPU and GPU accesses is + * guaranteed. + */ + I915_MOCS_UNCACHED, + /* + * Cacheability and coherency controlled by the kernel automatically + * based on the DRM_I915_GEM_SET_CACHING IOCTL setting and the current + * usage of the surface (used for display scanout or not). + */ + I915_MOCS_PTE, + /* + * Cached in all GPU caches available on the platform. + * Coherency between CPU and GPU accesses to the surface is not + * guaranteed without extra synchronization. + */ + I915_MOCS_CACHED, +}; + +/* Each region is a minimum of 16k, and there are at most 255 of them. + */ +#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use + * of chars for next/prev indices */ +#define I915_LOG_MIN_TEX_REGION_SIZE 14 + +typedef struct _drm_i915_init { + enum { + I915_INIT_DMA = 0x01, + I915_CLEANUP_DMA = 0x02, + I915_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drm_i915_init_t; + +typedef struct _drm_i915_sarea { + struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int pipeA_x; + int pipeA_y; + int pipeA_w; + int pipeA_h; + int pipeB_x; + int pipeB_y; + int pipeB_w; + int pipeB_h; + + /* fill out some space for old userspace triple buffer */ + drm_handle_t unused_handle; + __u32 unused1, unused2, unused3; + + /* buffer object handles for static buffers. May change + * over the lifetime of the client. + */ + __u32 front_bo_handle; + __u32 back_bo_handle; + __u32 unused_bo_handle; + __u32 depth_bo_handle; + +} drm_i915_sarea_t; + +/* due to userspace building against these headers we need some compat here */ +#define planeA_x pipeA_x +#define planeA_y pipeA_y +#define planeA_w pipeA_w +#define planeA_h pipeA_h +#define planeB_x pipeB_x +#define planeB_y pipeB_y +#define planeB_w pipeB_w +#define planeB_h pipeB_h + +/* Flags for perf_boxes + */ +#define I915_BOX_RING_EMPTY 0x1 +#define I915_BOX_FLIP 0x2 +#define I915_BOX_WAIT 0x4 +#define I915_BOX_TEXTURE_LOAD 0x8 +#define I915_BOX_LOST_CONTEXT 0x10 + +/* + * i915 specific ioctls. + * + * The device specific ioctl range is [DRM_COMMAND_BASE, DRM_COMMAND_END) ie + * [0x40, 0xa0) (a0 is excluded). The numbers below are defined as offset + * against DRM_COMMAND_BASE and should be between [0x0, 0x60). + */ +#define DRM_I915_INIT 0x00 +#define DRM_I915_FLUSH 0x01 +#define DRM_I915_FLIP 0x02 +#define DRM_I915_BATCHBUFFER 0x03 +#define DRM_I915_IRQ_EMIT 0x04 +#define DRM_I915_IRQ_WAIT 0x05 +#define DRM_I915_GETPARAM 0x06 +#define DRM_I915_SETPARAM 0x07 +#define DRM_I915_ALLOC 0x08 +#define DRM_I915_FREE 0x09 +#define DRM_I915_INIT_HEAP 0x0a +#define DRM_I915_CMDBUFFER 0x0b +#define DRM_I915_DESTROY_HEAP 0x0c +#define DRM_I915_SET_VBLANK_PIPE 0x0d +#define DRM_I915_GET_VBLANK_PIPE 0x0e +#define DRM_I915_VBLANK_SWAP 0x0f +#define DRM_I915_HWS_ADDR 0x11 +#define DRM_I915_GEM_INIT 0x13 +#define DRM_I915_GEM_EXECBUFFER 0x14 +#define DRM_I915_GEM_PIN 0x15 +#define DRM_I915_GEM_UNPIN 0x16 +#define DRM_I915_GEM_BUSY 0x17 +#define DRM_I915_GEM_THROTTLE 0x18 +#define DRM_I915_GEM_ENTERVT 0x19 +#define DRM_I915_GEM_LEAVEVT 0x1a +#define DRM_I915_GEM_CREATE 0x1b +#define DRM_I915_GEM_PREAD 0x1c +#define DRM_I915_GEM_PWRITE 0x1d +#define DRM_I915_GEM_MMAP 0x1e +#define DRM_I915_GEM_SET_DOMAIN 0x1f +#define DRM_I915_GEM_SW_FINISH 0x20 +#define DRM_I915_GEM_SET_TILING 0x21 +#define DRM_I915_GEM_GET_TILING 0x22 +#define DRM_I915_GEM_GET_APERTURE 0x23 +#define DRM_I915_GEM_MMAP_GTT 0x24 +#define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 +#define DRM_I915_GEM_MADVISE 0x26 +#define DRM_I915_OVERLAY_PUT_IMAGE 0x27 +#define DRM_I915_OVERLAY_ATTRS 0x28 +#define DRM_I915_GEM_EXECBUFFER2 0x29 +#define DRM_I915_GEM_EXECBUFFER2_WR DRM_I915_GEM_EXECBUFFER2 +#define DRM_I915_GET_SPRITE_COLORKEY 0x2a +#define DRM_I915_SET_SPRITE_COLORKEY 0x2b +#define DRM_I915_GEM_WAIT 0x2c +#define DRM_I915_GEM_CONTEXT_CREATE 0x2d +#define DRM_I915_GEM_CONTEXT_DESTROY 0x2e +#define DRM_I915_GEM_SET_CACHING 0x2f +#define DRM_I915_GEM_GET_CACHING 0x30 +#define DRM_I915_REG_READ 0x31 +#define DRM_I915_GET_RESET_STATS 0x32 +#define DRM_I915_GEM_USERPTR 0x33 +#define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 +#define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 +#define DRM_I915_PERF_OPEN 0x36 +#define DRM_I915_PERF_ADD_CONFIG 0x37 +#define DRM_I915_PERF_REMOVE_CONFIG 0x38 + +#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) +#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) +#define DRM_IOCTL_I915_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP) +#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t) +#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t) +#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t) +#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t) +#define DRM_IOCTL_I915_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t) +#define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t) +#define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) +#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) +#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) +#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) +#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) +#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) +#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) +#define DRM_IOCTL_I915_HWS_ADDR DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init) +#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) +#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) +#define DRM_IOCTL_I915_GEM_EXECBUFFER2 DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2) +#define DRM_IOCTL_I915_GEM_EXECBUFFER2_WR DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2_WR, struct drm_i915_gem_execbuffer2) +#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) +#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) +#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) +#define DRM_IOCTL_I915_GEM_SET_CACHING DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching) +#define DRM_IOCTL_I915_GEM_GET_CACHING DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching) +#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE) +#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT) +#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT) +#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create) +#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) +#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) +#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap) +#define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt) +#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain) +#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish) +#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling) +#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) +#define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) +#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id) +#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) +#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) +#define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) +#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) +#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey) +#define DRM_IOCTL_I915_GEM_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait) +#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create) +#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy) +#define DRM_IOCTL_I915_REG_READ DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read) +#define DRM_IOCTL_I915_GET_RESET_STATS DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GET_RESET_STATS, struct drm_i915_reset_stats) +#define DRM_IOCTL_I915_GEM_USERPTR DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_USERPTR, struct drm_i915_gem_userptr) +#define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) +#define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) +#define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) +#define DRM_IOCTL_I915_PERF_ADD_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_ADD_CONFIG, struct drm_i915_perf_oa_config) +#define DRM_IOCTL_I915_PERF_REMOVE_CONFIG DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_REMOVE_CONFIG, __u64) + +/* Allow drivers to submit batchbuffers directly to hardware, relying + * on the security mechanisms provided by hardware. + */ +typedef struct drm_i915_batchbuffer { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ + int num_cliprects; /* mulitpass with multiple cliprects? */ + struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ +} drm_i915_batchbuffer_t; + +/* As above, but pass a pointer to userspace buffer which can be + * validated by the kernel prior to sending to hardware. + */ +typedef struct _drm_i915_cmdbuffer { + char __user *buf; /* pointer to userspace command buffer */ + int sz; /* nr bytes in buf */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */ + int num_cliprects; /* mulitpass with multiple cliprects? */ + struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */ +} drm_i915_cmdbuffer_t; + +/* Userspace can request & wait on irq's: + */ +typedef struct drm_i915_irq_emit { + int __user *irq_seq; +} drm_i915_irq_emit_t; + +typedef struct drm_i915_irq_wait { + int irq_seq; +} drm_i915_irq_wait_t; + +/* Ioctl to query kernel params: + */ +#define I915_PARAM_IRQ_ACTIVE 1 +#define I915_PARAM_ALLOW_BATCHBUFFER 2 +#define I915_PARAM_LAST_DISPATCH 3 +#define I915_PARAM_CHIPSET_ID 4 +#define I915_PARAM_HAS_GEM 5 +#define I915_PARAM_NUM_FENCES_AVAIL 6 +#define I915_PARAM_HAS_OVERLAY 7 +#define I915_PARAM_HAS_PAGEFLIPPING 8 +#define I915_PARAM_HAS_EXECBUF2 9 +#define I915_PARAM_HAS_BSD 10 +#define I915_PARAM_HAS_BLT 11 +#define I915_PARAM_HAS_RELAXED_FENCING 12 +#define I915_PARAM_HAS_COHERENT_RINGS 13 +#define I915_PARAM_HAS_EXEC_CONSTANTS 14 +#define I915_PARAM_HAS_RELAXED_DELTA 15 +#define I915_PARAM_HAS_GEN7_SOL_RESET 16 +#define I915_PARAM_HAS_LLC 17 +#define I915_PARAM_HAS_ALIASING_PPGTT 18 +#define I915_PARAM_HAS_WAIT_TIMEOUT 19 +#define I915_PARAM_HAS_SEMAPHORES 20 +#define I915_PARAM_HAS_PRIME_VMAP_FLUSH 21 +#define I915_PARAM_HAS_VEBOX 22 +#define I915_PARAM_HAS_SECURE_BATCHES 23 +#define I915_PARAM_HAS_PINNED_BATCHES 24 +#define I915_PARAM_HAS_EXEC_NO_RELOC 25 +#define I915_PARAM_HAS_EXEC_HANDLE_LUT 26 +#define I915_PARAM_HAS_WT 27 +#define I915_PARAM_CMD_PARSER_VERSION 28 +#define I915_PARAM_HAS_COHERENT_PHYS_GTT 29 +#define I915_PARAM_MMAP_VERSION 30 +#define I915_PARAM_HAS_BSD2 31 +#define I915_PARAM_REVISION 32 +#define I915_PARAM_SUBSLICE_TOTAL 33 +#define I915_PARAM_EU_TOTAL 34 +#define I915_PARAM_HAS_GPU_RESET 35 +#define I915_PARAM_HAS_RESOURCE_STREAMER 36 +#define I915_PARAM_HAS_EXEC_SOFTPIN 37 +#define I915_PARAM_HAS_POOLED_EU 38 +#define I915_PARAM_MIN_EU_IN_POOL 39 +#define I915_PARAM_MMAP_GTT_VERSION 40 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports user defined execution + * priorities and the driver will attempt to execute batches in priority order. + */ +#define I915_PARAM_HAS_SCHEDULER 41 +#define I915_PARAM_HUC_STATUS 42 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to opt-out of + * synchronisation with implicit fencing on individual objects. + * See EXEC_OBJECT_ASYNC. + */ +#define I915_PARAM_HAS_EXEC_ASYNC 43 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports explicit fence support - + * both being able to pass in a sync_file fd to wait upon before executing, + * and being able to return a new sync_file fd that is signaled when the + * current request is complete. See I915_EXEC_FENCE_IN and I915_EXEC_FENCE_OUT. + */ +#define I915_PARAM_HAS_EXEC_FENCE 44 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to capture + * user specified bufffers for post-mortem debugging of GPU hangs. See + * EXEC_OBJECT_CAPTURE. + */ +#define I915_PARAM_HAS_EXEC_CAPTURE 45 + +#define I915_PARAM_SLICE_MASK 46 + +/* Assuming it's uniform for each slice, this queries the mask of subslices + * per-slice for this system. + */ +#define I915_PARAM_SUBSLICE_MASK 47 + +/* + * Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying the batch buffer + * as the first execobject as opposed to the last. See I915_EXEC_BATCH_FIRST. + */ +#define I915_PARAM_HAS_EXEC_BATCH_FIRST 48 + +/* Query whether DRM_I915_GEM_EXECBUFFER2 supports supplying an array of + * drm_i915_gem_exec_fence structures. See I915_EXEC_FENCE_ARRAY. + */ +#define I915_PARAM_HAS_EXEC_FENCE_ARRAY 49 + +typedef struct drm_i915_getparam { + __s32 param; + /* + * WARNING: Using pointers instead of fixed-size u64 means we need to write + * compat32 code. Don't repeat this mistake. + */ + int __user *value; +} drm_i915_getparam_t; + +/* Ioctl to set kernel params: + */ +#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I915_SETPARAM_ALLOW_BATCHBUFFER 3 +#define I915_SETPARAM_NUM_USED_FENCES 4 + +typedef struct drm_i915_setparam { + int param; + int value; +} drm_i915_setparam_t; + +/* A memory manager for regions of shared memory: + */ +#define I915_MEM_REGION_AGP 1 + +typedef struct drm_i915_mem_alloc { + int region; + int alignment; + int size; + int __user *region_offset; /* offset from start of fb or agp */ +} drm_i915_mem_alloc_t; + +typedef struct drm_i915_mem_free { + int region; + int region_offset; +} drm_i915_mem_free_t; + +typedef struct drm_i915_mem_init_heap { + int region; + int size; + int start; +} drm_i915_mem_init_heap_t; + +/* Allow memory manager to be torn down and re-initialized (eg on + * rotate): + */ +typedef struct drm_i915_mem_destroy_heap { + int region; +} drm_i915_mem_destroy_heap_t; + +/* Allow X server to configure which pipes to monitor for vblank signals + */ +#define DRM_I915_VBLANK_PIPE_A 1 +#define DRM_I915_VBLANK_PIPE_B 2 + +typedef struct drm_i915_vblank_pipe { + int pipe; +} drm_i915_vblank_pipe_t; + +/* Schedule buffer swap at given vertical blank: + */ +typedef struct drm_i915_vblank_swap { + drm_drawable_t drawable; + enum drm_vblank_seq_type seqtype; + unsigned int sequence; +} drm_i915_vblank_swap_t; + +typedef struct drm_i915_hws_addr { + __u64 addr; +} drm_i915_hws_addr_t; + +struct drm_i915_gem_init { + /** + * Beginning offset in the GTT to be managed by the DRM memory + * manager. + */ + __u64 gtt_start; + /** + * Ending offset in the GTT to be managed by the DRM memory + * manager. + */ + __u64 gtt_end; +}; + +struct drm_i915_gem_create { + /** + * Requested size for the object. + * + * The (page-aligned) allocated size for the object will be returned. + */ + __u64 size; + /** + * Returned handle for the object. + * + * Object handles are nonzero. + */ + __u32 handle; + __u32 pad; +}; + +struct drm_i915_gem_pread { + /** Handle for the object being read. */ + __u32 handle; + __u32 pad; + /** Offset into the object to read from */ + __u64 offset; + /** Length of data to read */ + __u64 size; + /** + * Pointer to write the data into. + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 data_ptr; +}; + +struct drm_i915_gem_pwrite { + /** Handle for the object being written to. */ + __u32 handle; + __u32 pad; + /** Offset into the object to write to */ + __u64 offset; + /** Length of data to write */ + __u64 size; + /** + * Pointer to read the data from. + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 data_ptr; +}; + +struct drm_i915_gem_mmap { + /** Handle for the object being mapped. */ + __u32 handle; + __u32 pad; + /** Offset in the object to map. */ + __u64 offset; + /** + * Length of data to map. + * + * The value will be page-aligned. + */ + __u64 size; + /** + * Returned pointer the data was mapped at. + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 addr_ptr; + + /** + * Flags for extended behaviour. + * + * Added in version 2. + */ + __u64 flags; +#define I915_MMAP_WC 0x1 +}; + +struct drm_i915_gem_mmap_gtt { + /** Handle for the object being mapped. */ + __u32 handle; + __u32 pad; + /** + * Fake offset to use for subsequent mmap call + * + * This is a fixed-size type for 32/64 compatibility. + */ + __u64 offset; +}; + +struct drm_i915_gem_set_domain { + /** Handle for the object */ + __u32 handle; + + /** New read domains */ + __u32 read_domains; + + /** New write domain */ + __u32 write_domain; +}; + +struct drm_i915_gem_sw_finish { + /** Handle for the object */ + __u32 handle; +}; + +struct drm_i915_gem_relocation_entry { + /** + * Handle of the buffer being pointed to by this relocation entry. + * + * It's appealing to make this be an index into the mm_validate_entry + * list to refer to the buffer, but this allows the driver to create + * a relocation list for state buffers and not re-write it per + * exec using the buffer. + */ + __u32 target_handle; + + /** + * Value to be added to the offset of the target buffer to make up + * the relocation entry. + */ + __u32 delta; + + /** Offset in the buffer the relocation entry will be written into */ + __u64 offset; + + /** + * Offset value of the target buffer that the relocation entry was last + * written as. + * + * If the buffer has the same offset as last time, we can skip syncing + * and writing the relocation. This value is written back out by + * the execbuffer ioctl when the relocation is written. + */ + __u64 presumed_offset; + + /** + * Target memory domains read by this operation. + */ + __u32 read_domains; + + /** + * Target memory domains written by this operation. + * + * Note that only one domain may be written by the whole + * execbuffer operation, so that where there are conflicts, + * the application will get -EINVAL back. + */ + __u32 write_domain; +}; + +/** @{ + * Intel memory domains + * + * Most of these just align with the various caches in + * the system and are used to flush and invalidate as + * objects end up cached in different domains. + */ +/** CPU cache */ +#define I915_GEM_DOMAIN_CPU 0x00000001 +/** Render cache, used by 2D and 3D drawing */ +#define I915_GEM_DOMAIN_RENDER 0x00000002 +/** Sampler cache, used by texture engine */ +#define I915_GEM_DOMAIN_SAMPLER 0x00000004 +/** Command queue, used to load batch buffers */ +#define I915_GEM_DOMAIN_COMMAND 0x00000008 +/** Instruction cache, used by shader programs */ +#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010 +/** Vertex address cache */ +#define I915_GEM_DOMAIN_VERTEX 0x00000020 +/** GTT domain - aperture and scanout */ +#define I915_GEM_DOMAIN_GTT 0x00000040 +/** WC domain - uncached access */ +#define I915_GEM_DOMAIN_WC 0x00000080 +/** @} */ + +struct drm_i915_gem_exec_object { + /** + * User's handle for a buffer to be bound into the GTT for this + * operation. + */ + __u32 handle; + + /** Number of relocations to be performed on this buffer */ + __u32 relocation_count; + /** + * Pointer to array of struct drm_i915_gem_relocation_entry containing + * the relocations to be performed in this buffer. + */ + __u64 relocs_ptr; + + /** Required alignment in graphics aperture */ + __u64 alignment; + + /** + * Returned value of the updated offset of the object, for future + * presumed_offset writes. + */ + __u64 offset; +}; + +struct drm_i915_gem_execbuffer { + /** + * List of buffers to be validated with their relocations to be + * performend on them. + * + * This is a pointer to an array of struct drm_i915_gem_validate_entry. + * + * These buffers must be listed in an order such that all relocations + * a buffer is performing refer to buffers that have already appeared + * in the validate list. + */ + __u64 buffers_ptr; + __u32 buffer_count; + + /** Offset in the batchbuffer to start execution from. */ + __u32 batch_start_offset; + /** Bytes used in batchbuffer from batch_start_offset */ + __u32 batch_len; + __u32 DR1; + __u32 DR4; + __u32 num_cliprects; + /** This is a struct drm_clip_rect *cliprects */ + __u64 cliprects_ptr; +}; + +struct drm_i915_gem_exec_object2 { + /** + * User's handle for a buffer to be bound into the GTT for this + * operation. + */ + __u32 handle; + + /** Number of relocations to be performed on this buffer */ + __u32 relocation_count; + /** + * Pointer to array of struct drm_i915_gem_relocation_entry containing + * the relocations to be performed in this buffer. + */ + __u64 relocs_ptr; + + /** Required alignment in graphics aperture */ + __u64 alignment; + + /** + * When the EXEC_OBJECT_PINNED flag is specified this is populated by + * the user with the GTT offset at which this object will be pinned. + * When the I915_EXEC_NO_RELOC flag is specified this must contain the + * presumed_offset of the object. + * During execbuffer2 the kernel populates it with the value of the + * current GTT offset of the object, for future presumed_offset writes. + */ + __u64 offset; + +#define EXEC_OBJECT_NEEDS_FENCE (1<<0) +#define EXEC_OBJECT_NEEDS_GTT (1<<1) +#define EXEC_OBJECT_WRITE (1<<2) +#define EXEC_OBJECT_SUPPORTS_48B_ADDRESS (1<<3) +#define EXEC_OBJECT_PINNED (1<<4) +#define EXEC_OBJECT_PAD_TO_SIZE (1<<5) +/* The kernel implicitly tracks GPU activity on all GEM objects, and + * synchronises operations with outstanding rendering. This includes + * rendering on other devices if exported via dma-buf. However, sometimes + * this tracking is too coarse and the user knows better. For example, + * if the object is split into non-overlapping ranges shared between different + * clients or engines (i.e. suballocating objects), the implicit tracking + * by kernel assumes that each operation affects the whole object rather + * than an individual range, causing needless synchronisation between clients. + * The kernel will also forgo any CPU cache flushes prior to rendering from + * the object as the client is expected to be also handling such domain + * tracking. + * + * The kernel maintains the implicit tracking in order to manage resources + * used by the GPU - this flag only disables the synchronisation prior to + * rendering with this object in this execbuf. + * + * Opting out of implicit synhronisation requires the user to do its own + * explicit tracking to avoid rendering corruption. See, for example, + * I915_PARAM_HAS_EXEC_FENCE to order execbufs and execute them asynchronously. + */ +#define EXEC_OBJECT_ASYNC (1<<6) +/* Request that the contents of this execobject be copied into the error + * state upon a GPU hang involving this batch for post-mortem debugging. + * These buffers are recorded in no particular order as "user" in + * /sys/class/drm/cardN/error. Query I915_PARAM_HAS_EXEC_CAPTURE to see + * if the kernel supports this flag. + */ +#define EXEC_OBJECT_CAPTURE (1<<7) +/* All remaining bits are MBZ and RESERVED FOR FUTURE USE */ +#define __EXEC_OBJECT_UNKNOWN_FLAGS -(EXEC_OBJECT_CAPTURE<<1) + __u64 flags; + + union { + __u64 rsvd1; + __u64 pad_to_size; + }; + __u64 rsvd2; +}; + +struct drm_i915_gem_exec_fence { + /** + * User's handle for a drm_syncobj to wait on or signal. + */ + __u32 handle; + +#define I915_EXEC_FENCE_WAIT (1<<0) +#define I915_EXEC_FENCE_SIGNAL (1<<1) +#define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1)) + __u32 flags; +}; + +struct drm_i915_gem_execbuffer2 { + /** + * List of gem_exec_object2 structs + */ + __u64 buffers_ptr; + __u32 buffer_count; + + /** Offset in the batchbuffer to start execution from. */ + __u32 batch_start_offset; + /** Bytes used in batchbuffer from batch_start_offset */ + __u32 batch_len; + __u32 DR1; + __u32 DR4; + __u32 num_cliprects; + /** + * This is a struct drm_clip_rect *cliprects if I915_EXEC_FENCE_ARRAY + * is not set. If I915_EXEC_FENCE_ARRAY is set, then this is a + * struct drm_i915_gem_exec_fence *fences. + */ + __u64 cliprects_ptr; +#define I915_EXEC_RING_MASK (7<<0) +#define I915_EXEC_DEFAULT (0<<0) +#define I915_EXEC_RENDER (1<<0) +#define I915_EXEC_BSD (2<<0) +#define I915_EXEC_BLT (3<<0) +#define I915_EXEC_VEBOX (4<<0) + +/* Used for switching the constants addressing mode on gen4+ RENDER ring. + * Gen6+ only supports relative addressing to dynamic state (default) and + * absolute addressing. + * + * These flags are ignored for the BSD and BLT rings. + */ +#define I915_EXEC_CONSTANTS_MASK (3<<6) +#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */ +#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6) +#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */ + __u64 flags; + __u64 rsvd1; /* now used for context info */ + __u64 rsvd2; +}; + +/** Resets the SO write offset registers for transform feedback on gen7. */ +#define I915_EXEC_GEN7_SOL_RESET (1<<8) + +/** Request a privileged ("secure") batch buffer. Note only available for + * DRM_ROOT_ONLY | DRM_MASTER processes. + */ +#define I915_EXEC_SECURE (1<<9) + +/** Inform the kernel that the batch is and will always be pinned. This + * negates the requirement for a workaround to be performed to avoid + * an incoherent CS (such as can be found on 830/845). If this flag is + * not passed, the kernel will endeavour to make sure the batch is + * coherent with the CS before execution. If this flag is passed, + * userspace assumes the responsibility for ensuring the same. + */ +#define I915_EXEC_IS_PINNED (1<<10) + +/** Provide a hint to the kernel that the command stream and auxiliary + * state buffers already holds the correct presumed addresses and so the + * relocation process may be skipped if no buffers need to be moved in + * preparation for the execbuffer. + */ +#define I915_EXEC_NO_RELOC (1<<11) + +/** Use the reloc.handle as an index into the exec object array rather + * than as the per-file handle. + */ +#define I915_EXEC_HANDLE_LUT (1<<12) + +/** Used for switching BSD rings on the platforms with two BSD rings */ +#define I915_EXEC_BSD_SHIFT (13) +#define I915_EXEC_BSD_MASK (3 << I915_EXEC_BSD_SHIFT) +/* default ping-pong mode */ +#define I915_EXEC_BSD_DEFAULT (0 << I915_EXEC_BSD_SHIFT) +#define I915_EXEC_BSD_RING1 (1 << I915_EXEC_BSD_SHIFT) +#define I915_EXEC_BSD_RING2 (2 << I915_EXEC_BSD_SHIFT) + +/** Tell the kernel that the batchbuffer is processed by + * the resource streamer. + */ +#define I915_EXEC_RESOURCE_STREAMER (1<<15) + +/* Setting I915_EXEC_FENCE_IN implies that lower_32_bits(rsvd2) represent + * a sync_file fd to wait upon (in a nonblocking manner) prior to executing + * the batch. + * + * Returns -EINVAL if the sync_file fd cannot be found. + */ +#define I915_EXEC_FENCE_IN (1<<16) + +/* Setting I915_EXEC_FENCE_OUT causes the ioctl to return a sync_file fd + * in the upper_32_bits(rsvd2) upon success. Ownership of the fd is given + * to the caller, and it should be close() after use. (The fd is a regular + * file descriptor and will be cleaned up on process termination. It holds + * a reference to the request, but nothing else.) + * + * The sync_file fd can be combined with other sync_file and passed either + * to execbuf using I915_EXEC_FENCE_IN, to atomic KMS ioctls (so that a flip + * will only occur after this request completes), or to other devices. + * + * Using I915_EXEC_FENCE_OUT requires use of + * DRM_IOCTL_I915_GEM_EXECBUFFER2_WR ioctl so that the result is written + * back to userspace. Failure to do so will cause the out-fence to always + * be reported as zero, and the real fence fd to be leaked. + */ +#define I915_EXEC_FENCE_OUT (1<<17) + +/* + * Traditionally the execbuf ioctl has only considered the final element in + * the execobject[] to be the executable batch. Often though, the client + * will known the batch object prior to construction and being able to place + * it into the execobject[] array first can simplify the relocation tracking. + * Setting I915_EXEC_BATCH_FIRST tells execbuf to use element 0 of the + * execobject[] as the * batch instead (the default is to use the last + * element). + */ +#define I915_EXEC_BATCH_FIRST (1<<18) + +/* Setting I915_FENCE_ARRAY implies that num_cliprects and cliprects_ptr + * define an array of i915_gem_exec_fence structures which specify a set of + * dma fences to wait upon or signal. + */ +#define I915_EXEC_FENCE_ARRAY (1<<19) + +#define __I915_EXEC_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_ARRAY<<1)) + +#define I915_EXEC_CONTEXT_ID_MASK (0xffffffff) +#define i915_execbuffer2_set_context_id(eb2, context) \ + (eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK +#define i915_execbuffer2_get_context_id(eb2) \ + ((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK) + +struct drm_i915_gem_pin { + /** Handle of the buffer to be pinned. */ + __u32 handle; + __u32 pad; + + /** alignment required within the aperture */ + __u64 alignment; + + /** Returned GTT offset of the buffer. */ + __u64 offset; +}; + +struct drm_i915_gem_unpin { + /** Handle of the buffer to be unpinned. */ + __u32 handle; + __u32 pad; +}; + +struct drm_i915_gem_busy { + /** Handle of the buffer to check for busy */ + __u32 handle; + + /** Return busy status + * + * A return of 0 implies that the object is idle (after + * having flushed any pending activity), and a non-zero return that + * the object is still in-flight on the GPU. (The GPU has not yet + * signaled completion for all pending requests that reference the + * object.) An object is guaranteed to become idle eventually (so + * long as no new GPU commands are executed upon it). Due to the + * asynchronous nature of the hardware, an object reported + * as busy may become idle before the ioctl is completed. + * + * Furthermore, if the object is busy, which engine is busy is only + * provided as a guide. There are race conditions which prevent the + * report of which engines are busy from being always accurate. + * However, the converse is not true. If the object is idle, the + * result of the ioctl, that all engines are idle, is accurate. + * + * The returned dword is split into two fields to indicate both + * the engines on which the object is being read, and the + * engine on which it is currently being written (if any). + * + * The low word (bits 0:15) indicate if the object is being written + * to by any engine (there can only be one, as the GEM implicit + * synchronisation rules force writes to be serialised). Only the + * engine for the last write is reported. + * + * The high word (bits 16:31) are a bitmask of which engines are + * currently reading from the object. Multiple engines may be + * reading from the object simultaneously. + * + * The value of each engine is the same as specified in the + * EXECBUFFER2 ioctl, i.e. I915_EXEC_RENDER, I915_EXEC_BSD etc. + * Note I915_EXEC_DEFAULT is a symbolic value and is mapped to + * the I915_EXEC_RENDER engine for execution, and so it is never + * reported as active itself. Some hardware may have parallel + * execution engines, e.g. multiple media engines, which are + * mapped to the same identifier in the EXECBUFFER2 ioctl and + * so are not separately reported for busyness. + * + * Caveat emptor: + * Only the boolean result of this query is reliable; that is whether + * the object is idle or busy. The report of which engines are busy + * should be only used as a heuristic. + */ + __u32 busy; +}; + +/** + * I915_CACHING_NONE + * + * GPU access is not coherent with cpu caches. Default for machines without an + * LLC. + */ +#define I915_CACHING_NONE 0 +/** + * I915_CACHING_CACHED + * + * GPU access is coherent with cpu caches and furthermore the data is cached in + * last-level caches shared between cpu cores and the gpu GT. Default on + * machines with HAS_LLC. + */ +#define I915_CACHING_CACHED 1 +/** + * I915_CACHING_DISPLAY + * + * Special GPU caching mode which is coherent with the scanout engines. + * Transparently falls back to I915_CACHING_NONE on platforms where no special + * cache mode (like write-through or gfdt flushing) is available. The kernel + * automatically sets this mode when using a buffer as a scanout target. + * Userspace can manually set this mode to avoid a costly stall and clflush in + * the hotpath of drawing the first frame. + */ +#define I915_CACHING_DISPLAY 2 + +struct drm_i915_gem_caching { + /** + * Handle of the buffer to set/get the caching level of. */ + __u32 handle; + + /** + * Cacheing level to apply or return value + * + * bits0-15 are for generic caching control (i.e. the above defined + * values). bits16-31 are reserved for platform-specific variations + * (e.g. l3$ caching on gen7). */ + __u32 caching; +}; + +#define I915_TILING_NONE 0 +#define I915_TILING_X 1 +#define I915_TILING_Y 2 +#define I915_TILING_LAST I915_TILING_Y + +#define I915_BIT_6_SWIZZLE_NONE 0 +#define I915_BIT_6_SWIZZLE_9 1 +#define I915_BIT_6_SWIZZLE_9_10 2 +#define I915_BIT_6_SWIZZLE_9_11 3 +#define I915_BIT_6_SWIZZLE_9_10_11 4 +/* Not seen by userland */ +#define I915_BIT_6_SWIZZLE_UNKNOWN 5 +/* Seen by userland. */ +#define I915_BIT_6_SWIZZLE_9_17 6 +#define I915_BIT_6_SWIZZLE_9_10_17 7 + +struct drm_i915_gem_set_tiling { + /** Handle of the buffer to have its tiling state updated */ + __u32 handle; + + /** + * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X, + * I915_TILING_Y). + * + * This value is to be set on request, and will be updated by the + * kernel on successful return with the actual chosen tiling layout. + * + * The tiling mode may be demoted to I915_TILING_NONE when the system + * has bit 6 swizzling that can't be managed correctly by GEM. + * + * Buffer contents become undefined when changing tiling_mode. + */ + __u32 tiling_mode; + + /** + * Stride in bytes for the object when in I915_TILING_X or + * I915_TILING_Y. + */ + __u32 stride; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping. + */ + __u32 swizzle_mode; +}; + +struct drm_i915_gem_get_tiling { + /** Handle of the buffer to get tiling state for. */ + __u32 handle; + + /** + * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X, + * I915_TILING_Y). + */ + __u32 tiling_mode; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping. + */ + __u32 swizzle_mode; + + /** + * Returned address bit 6 swizzling required for CPU access through + * mmap mapping whilst bound. + */ + __u32 phys_swizzle_mode; +}; + +struct drm_i915_gem_get_aperture { + /** Total size of the aperture used by i915_gem_execbuffer, in bytes */ + __u64 aper_size; + + /** + * Available space in the aperture used by i915_gem_execbuffer, in + * bytes + */ + __u64 aper_available_size; +}; + +struct drm_i915_get_pipe_from_crtc_id { + /** ID of CRTC being requested **/ + __u32 crtc_id; + + /** pipe of requested CRTC **/ + __u32 pipe; +}; + +#define I915_MADV_WILLNEED 0 +#define I915_MADV_DONTNEED 1 +#define __I915_MADV_PURGED 2 /* internal state */ + +struct drm_i915_gem_madvise { + /** Handle of the buffer to change the backing store advice */ + __u32 handle; + + /* Advice: either the buffer will be needed again in the near future, + * or wont be and could be discarded under memory pressure. + */ + __u32 madv; + + /** Whether the backing store still exists. */ + __u32 retained; +}; + +/* flags */ +#define I915_OVERLAY_TYPE_MASK 0xff +#define I915_OVERLAY_YUV_PLANAR 0x01 +#define I915_OVERLAY_YUV_PACKED 0x02 +#define I915_OVERLAY_RGB 0x03 + +#define I915_OVERLAY_DEPTH_MASK 0xff00 +#define I915_OVERLAY_RGB24 0x1000 +#define I915_OVERLAY_RGB16 0x2000 +#define I915_OVERLAY_RGB15 0x3000 +#define I915_OVERLAY_YUV422 0x0100 +#define I915_OVERLAY_YUV411 0x0200 +#define I915_OVERLAY_YUV420 0x0300 +#define I915_OVERLAY_YUV410 0x0400 + +#define I915_OVERLAY_SWAP_MASK 0xff0000 +#define I915_OVERLAY_NO_SWAP 0x000000 +#define I915_OVERLAY_UV_SWAP 0x010000 +#define I915_OVERLAY_Y_SWAP 0x020000 +#define I915_OVERLAY_Y_AND_UV_SWAP 0x030000 + +#define I915_OVERLAY_FLAGS_MASK 0xff000000 +#define I915_OVERLAY_ENABLE 0x01000000 + +struct drm_intel_overlay_put_image { + /* various flags and src format description */ + __u32 flags; + /* source picture description */ + __u32 bo_handle; + /* stride values and offsets are in bytes, buffer relative */ + __u16 stride_Y; /* stride for packed formats */ + __u16 stride_UV; + __u32 offset_Y; /* offset for packet formats */ + __u32 offset_U; + __u32 offset_V; + /* in pixels */ + __u16 src_width; + __u16 src_height; + /* to compensate the scaling factors for partially covered surfaces */ + __u16 src_scan_width; + __u16 src_scan_height; + /* output crtc description */ + __u32 crtc_id; + __u16 dst_x; + __u16 dst_y; + __u16 dst_width; + __u16 dst_height; +}; + +/* flags */ +#define I915_OVERLAY_UPDATE_ATTRS (1<<0) +#define I915_OVERLAY_UPDATE_GAMMA (1<<1) +#define I915_OVERLAY_DISABLE_DEST_COLORKEY (1<<2) +struct drm_intel_overlay_attrs { + __u32 flags; + __u32 color_key; + __s32 brightness; + __u32 contrast; + __u32 saturation; + __u32 gamma0; + __u32 gamma1; + __u32 gamma2; + __u32 gamma3; + __u32 gamma4; + __u32 gamma5; +}; + +/* + * Intel sprite handling + * + * Color keying works with a min/mask/max tuple. Both source and destination + * color keying is allowed. + * + * Source keying: + * Sprite pixels within the min & max values, masked against the color channels + * specified in the mask field, will be transparent. All other pixels will + * be displayed on top of the primary plane. For RGB surfaces, only the min + * and mask fields will be used; ranged compares are not allowed. + * + * Destination keying: + * Primary plane pixels that match the min value, masked against the color + * channels specified in the mask field, will be replaced by corresponding + * pixels from the sprite plane. + * + * Note that source & destination keying are exclusive; only one can be + * active on a given plane. + */ + +#define I915_SET_COLORKEY_NONE (1<<0) /* disable color key matching */ +#define I915_SET_COLORKEY_DESTINATION (1<<1) +#define I915_SET_COLORKEY_SOURCE (1<<2) +struct drm_intel_sprite_colorkey { + __u32 plane_id; + __u32 min_value; + __u32 channel_mask; + __u32 max_value; + __u32 flags; +}; + +struct drm_i915_gem_wait { + /** Handle of BO we shall wait on */ + __u32 bo_handle; + __u32 flags; + /** Number of nanoseconds to wait, Returns time remaining. */ + __s64 timeout_ns; +}; + +struct drm_i915_gem_context_create { + /* output: id of new context*/ + __u32 ctx_id; + __u32 pad; +}; + +struct drm_i915_gem_context_destroy { + __u32 ctx_id; + __u32 pad; +}; + +struct drm_i915_reg_read { + /* + * Register offset. + * For 64bit wide registers where the upper 32bits don't immediately + * follow the lower 32bits, the offset of the lower 32bits must + * be specified + */ + __u64 offset; + __u64 val; /* Return value */ +}; +/* Known registers: + * + * Render engine timestamp - 0x2358 + 64bit - gen7+ + * - Note this register returns an invalid value if using the default + * single instruction 8byte read, in order to workaround that use + * offset (0x2538 | 1) instead. + * + */ + +struct drm_i915_reset_stats { + __u32 ctx_id; + __u32 flags; + + /* All resets since boot/module reload, for all contexts */ + __u32 reset_count; + + /* Number of batches lost when active in GPU, for this context */ + __u32 batch_active; + + /* Number of batches lost pending for execution, for this context */ + __u32 batch_pending; + + __u32 pad; +}; + +struct drm_i915_gem_userptr { + __u64 user_ptr; + __u64 user_size; + __u32 flags; +#define I915_USERPTR_READ_ONLY 0x1 +#define I915_USERPTR_UNSYNCHRONIZED 0x80000000 + /** + * Returned handle for the object. + * + * Object handles are nonzero. + */ + __u32 handle; +}; + +struct drm_i915_gem_context_param { + __u32 ctx_id; + __u32 size; + __u64 param; +#define I915_CONTEXT_PARAM_BAN_PERIOD 0x1 +#define I915_CONTEXT_PARAM_NO_ZEROMAP 0x2 +#define I915_CONTEXT_PARAM_GTT_SIZE 0x3 +#define I915_CONTEXT_PARAM_NO_ERROR_CAPTURE 0x4 +#define I915_CONTEXT_PARAM_BANNABLE 0x5 + __u64 value; +}; + +enum drm_i915_oa_format { + I915_OA_FORMAT_A13 = 1, /* HSW only */ + I915_OA_FORMAT_A29, /* HSW only */ + I915_OA_FORMAT_A13_B8_C8, /* HSW only */ + I915_OA_FORMAT_B4_C8, /* HSW only */ + I915_OA_FORMAT_A45_B8_C8, /* HSW only */ + I915_OA_FORMAT_B4_C8_A16, /* HSW only */ + I915_OA_FORMAT_C4_B8, /* HSW+ */ + + /* Gen8+ */ + I915_OA_FORMAT_A12, + I915_OA_FORMAT_A12_B8_C8, + I915_OA_FORMAT_A32u40_A4u32_B8_C8, + + I915_OA_FORMAT_MAX /* non-ABI */ +}; + +enum drm_i915_perf_property_id { + /** + * Open the stream for a specific context handle (as used with + * execbuffer2). A stream opened for a specific context this way + * won't typically require root privileges. + */ + DRM_I915_PERF_PROP_CTX_HANDLE = 1, + + /** + * A value of 1 requests the inclusion of raw OA unit reports as + * part of stream samples. + */ + DRM_I915_PERF_PROP_SAMPLE_OA, + + /** + * The value specifies which set of OA unit metrics should be + * be configured, defining the contents of any OA unit reports. + */ + DRM_I915_PERF_PROP_OA_METRICS_SET, + + /** + * The value specifies the size and layout of OA unit reports. + */ + DRM_I915_PERF_PROP_OA_FORMAT, + + /** + * Specifying this property implicitly requests periodic OA unit + * sampling and (at least on Haswell) the sampling frequency is derived + * from this exponent as follows: + * + * 80ns * 2^(period_exponent + 1) + */ + DRM_I915_PERF_PROP_OA_EXPONENT, + + DRM_I915_PERF_PROP_MAX /* non-ABI */ +}; + +struct drm_i915_perf_open_param { + __u32 flags; +#define I915_PERF_FLAG_FD_CLOEXEC (1<<0) +#define I915_PERF_FLAG_FD_NONBLOCK (1<<1) +#define I915_PERF_FLAG_DISABLED (1<<2) + + /** The number of u64 (id, value) pairs */ + __u32 num_properties; + + /** + * Pointer to array of u64 (id, value) pairs configuring the stream + * to open. + */ + __u64 properties_ptr; +}; + +/** + * Enable data capture for a stream that was either opened in a disabled state + * via I915_PERF_FLAG_DISABLED or was later disabled via + * I915_PERF_IOCTL_DISABLE. + * + * It is intended to be cheaper to disable and enable a stream than it may be + * to close and re-open a stream with the same configuration. + * + * It's undefined whether any pending data for the stream will be lost. + */ +#define I915_PERF_IOCTL_ENABLE _IO('i', 0x0) + +/** + * Disable data capture for a stream. + * + * It is an error to try and read a stream that is disabled. + */ +#define I915_PERF_IOCTL_DISABLE _IO('i', 0x1) + +/** + * Common to all i915 perf records + */ +struct drm_i915_perf_record_header { + __u32 type; + __u16 pad; + __u16 size; +}; + +enum drm_i915_perf_record_type { + + /** + * Samples are the work horse record type whose contents are extensible + * and defined when opening an i915 perf stream based on the given + * properties. + * + * Boolean properties following the naming convention + * DRM_I915_PERF_SAMPLE_xyz_PROP request the inclusion of 'xyz' data in + * every sample. + * + * The order of these sample properties given by userspace has no + * affect on the ordering of data within a sample. The order is + * documented here. + * + * struct { + * struct drm_i915_perf_record_header header; + * + * { u32 oa_report[]; } && DRM_I915_PERF_PROP_SAMPLE_OA + * }; + */ + DRM_I915_PERF_RECORD_SAMPLE = 1, + + /* + * Indicates that one or more OA reports were not written by the + * hardware. This can happen for example if an MI_REPORT_PERF_COUNT + * command collides with periodic sampling - which would be more likely + * at higher sampling frequencies. + */ + DRM_I915_PERF_RECORD_OA_REPORT_LOST = 2, + + /** + * An error occurred that resulted in all pending OA reports being lost. + */ + DRM_I915_PERF_RECORD_OA_BUFFER_LOST = 3, + + DRM_I915_PERF_RECORD_MAX /* non-ABI */ +}; + +/** + * Structure to upload perf dynamic configuration into the kernel. + */ +struct drm_i915_perf_oa_config { + /** String formatted like "%08x-%04x-%04x-%04x-%012x" */ + char uuid[36]; + + __u32 n_mux_regs; + __u32 n_boolean_regs; + __u32 n_flex_regs; + + __u64 __user mux_regs_ptr; + __u64 __user boolean_regs_ptr; + __u64 __user flex_regs_ptr; +}; + +#if defined(__cplusplus) +} +#endif + +#endif /* _UAPI_I915_DRM_H_ */ diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index ce2988be4f0e..30f2ce76b517 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com * * This program is free software; you can redistribute it and/or @@ -30,9 +31,14 @@ #define BPF_FROM_LE BPF_TO_LE #define BPF_FROM_BE BPF_TO_BE +/* jmp encodings */ #define BPF_JNE 0x50 /* jump != */ +#define BPF_JLT 0xa0 /* LT is unsigned, '<' */ +#define BPF_JLE 0xb0 /* LE is unsigned, '<=' */ #define BPF_JSGT 0x60 /* SGT is signed '>', GT in x86 */ #define BPF_JSGE 0x70 /* SGE is signed '>=', GE in x86 */ +#define BPF_JSLT 0xc0 /* SLT is signed, '<' */ +#define BPF_JSLE 0xd0 /* SLE is signed, '<=' */ #define BPF_CALL 0x80 /* function call */ #define BPF_EXIT 0x90 /* function return */ @@ -104,6 +110,8 @@ enum bpf_map_type { BPF_MAP_TYPE_LPM_TRIE, BPF_MAP_TYPE_ARRAY_OF_MAPS, BPF_MAP_TYPE_HASH_OF_MAPS, + BPF_MAP_TYPE_DEVMAP, + BPF_MAP_TYPE_SOCKMAP, }; enum bpf_prog_type { @@ -121,6 +129,7 @@ enum bpf_prog_type { BPF_PROG_TYPE_LWT_OUT, BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, + BPF_PROG_TYPE_SK_SKB, }; enum bpf_attach_type { @@ -128,6 +137,8 @@ enum bpf_attach_type { BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_SOCK_CREATE, BPF_CGROUP_SOCK_OPS, + BPF_SK_SKB_STREAM_PARSER, + BPF_SK_SKB_STREAM_VERDICT, __MAX_BPF_ATTACH_TYPE }; @@ -153,6 +164,7 @@ enum bpf_attach_type { #define BPF_NOEXIST 1 /* create new element if it didn't exist */ #define BPF_EXIST 2 /* update existing element */ +/* flags for BPF_MAP_CREATE command */ #define BPF_F_NO_PREALLOC (1U << 0) /* Instead of having one common LRU list in the * BPF_MAP_TYPE_LRU_[PERCPU_]HASH map, use a percpu LRU list @@ -161,6 +173,8 @@ enum bpf_attach_type { * across different LRU lists. */ #define BPF_F_NO_COMMON_LRU (1U << 1) +/* Specify numa node during map creation */ +#define BPF_F_NUMA_NODE (1U << 2) union bpf_attr { struct { /* anonymous struct used by BPF_MAP_CREATE command */ @@ -168,8 +182,13 @@ union bpf_attr { __u32 key_size; /* size of key in bytes */ __u32 value_size; /* size of value in bytes */ __u32 max_entries; /* max number of entries in a map */ - __u32 map_flags; /* prealloc or not */ + __u32 map_flags; /* BPF_MAP_CREATE related + * flags defined above. + */ __u32 inner_map_fd; /* fd pointing to the inner map */ + __u32 numa_node; /* numa node (effective only if + * BPF_F_NUMA_NODE is set). + */ }; struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ @@ -294,7 +313,7 @@ union bpf_attr { * jump into another BPF program * @ctx: context pointer passed to next program * @prog_array_map: pointer to map which type is BPF_MAP_TYPE_PROG_ARRAY - * @index: index inside array that selects specific program to run + * @index: 32-bit index inside array that selects specific program to run * Return: 0 on success or negative error * * int bpf_clone_redirect(skb, ifindex, flags) @@ -344,9 +363,20 @@ union bpf_attr { * int bpf_redirect(ifindex, flags) * redirect to another netdev * @ifindex: ifindex of the net device - * @flags: bit 0 - if set, redirect to ingress instead of egress - * other bits - reserved - * Return: TC_ACT_REDIRECT + * @flags: + * cls_bpf: + * bit 0 - if set, redirect to ingress instead of egress + * other bits - reserved + * xdp_bpf: + * all bits - reserved + * Return: cls_bpf: TC_ACT_REDIRECT on success or TC_ACT_SHOT on error + * xdp_bfp: XDP_REDIRECT on success or XDP_ABORT on error + * int bpf_redirect_map(map, key, flags) + * redirect to endpoint in map + * @map: pointer to dev map + * @key: index in map to lookup + * @flags: -- + * Return: XDP_REDIRECT on success or XDP_ABORT on error * * u32 bpf_get_route_realm(skb) * retrieve a dst's tclassid @@ -539,6 +569,20 @@ union bpf_attr { * @mode: operation mode (enum bpf_adj_room_mode) * @flags: reserved for future use * Return: 0 on success or negative error code + * + * int bpf_sk_redirect_map(map, key, flags) + * Redirect skb to a sock in map using key as a lookup key for the + * sock in map. + * @map: pointer to sockmap + * @key: key to lookup sock in map + * @flags: reserved for future use + * Return: SK_PASS + * + * int bpf_sock_map_update(skops, map, key, flags) + * @skops: pointer to bpf_sock_ops + * @map: pointer to sockmap to update + * @key: key to insert/update sock in map + * @flags: same flags as map update elem */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -591,7 +635,10 @@ union bpf_attr { FN(get_socket_uid), \ FN(set_hash), \ FN(setsockopt), \ - FN(skb_adjust_room), + FN(skb_adjust_room), \ + FN(redirect_map), \ + FN(sk_redirect_map), \ + FN(sock_map_update), \ /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call @@ -643,7 +690,7 @@ enum bpf_func_id { /* Mode for BPF_FUNC_skb_adjust_room helper. */ enum bpf_adj_room_mode { - BPF_ADJ_ROOM_NET_OPTS, + BPF_ADJ_ROOM_NET, }; /* user accessible mirror of in-kernel sk_buff. @@ -668,6 +715,15 @@ struct __sk_buff { __u32 data; __u32 data_end; __u32 napi_id; + + /* accessed by BPF_PROG_TYPE_sk_skb types */ + __u32 family; + __u32 remote_ip4; /* Stored in network byte order */ + __u32 local_ip4; /* Stored in network byte order */ + __u32 remote_ip6[4]; /* Stored in network byte order */ + __u32 local_ip6[4]; /* Stored in network byte order */ + __u32 remote_port; /* Stored in network byte order */ + __u32 local_port; /* stored in host byte order */ }; struct bpf_tunnel_key { @@ -703,20 +759,23 @@ struct bpf_sock { __u32 family; __u32 type; __u32 protocol; + __u32 mark; + __u32 priority; }; #define XDP_PACKET_HEADROOM 256 /* User return codes for XDP prog type. * A valid XDP program must return one of these defined values. All other - * return codes are reserved for future use. Unknown return codes will result - * in packet drop. + * return codes are reserved for future use. Unknown return codes will + * result in packet drops and a warning via bpf_warn_invalid_xdp_action(). */ enum xdp_action { XDP_ABORTED = 0, XDP_DROP, XDP_PASS, XDP_TX, + XDP_REDIRECT, }; /* user accessible metadata for XDP packet hook @@ -727,6 +786,11 @@ struct xdp_md { __u32 data_end; }; +enum sk_action { + SK_DROP = 0, + SK_PASS, +}; + #define BPF_TAG_SIZE 8 struct bpf_prog_info { @@ -750,6 +814,8 @@ struct bpf_map_info { /* User bpf_sock_ops struct to access socket values and specify request ops * and their replies. + * Some of this fields are in network (bigendian) byte order and may need + * to be converted before use (bpf_ntohl() defined in samples/bpf/bpf_endian.h). * New fields can only be added at the end of this structure */ struct bpf_sock_ops { @@ -759,12 +825,12 @@ struct bpf_sock_ops { __u32 replylong[4]; }; __u32 family; - __u32 remote_ip4; - __u32 local_ip4; - __u32 remote_ip6[4]; - __u32 local_ip6[4]; - __u32 remote_port; - __u32 local_port; + __u32 remote_ip4; /* Stored in network byte order */ + __u32 local_ip4; /* Stored in network byte order */ + __u32 remote_ip6[4]; /* Stored in network byte order */ + __u32 local_ip6[4]; /* Stored in network byte order */ + __u32 remote_port; /* Stored in network byte order */ + __u32 local_port; /* stored in host byte order */ }; /* List of known BPF sock_ops operators. diff --git a/tools/include/uapi/linux/bpf_common.h b/tools/include/uapi/linux/bpf_common.h index a5c220e0828f..18be90725ab0 100644 --- a/tools/include/uapi/linux/bpf_common.h +++ b/tools/include/uapi/linux/bpf_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI__LINUX_BPF_COMMON_H__ #define _UAPI__LINUX_BPF_COMMON_H__ diff --git a/tools/include/uapi/linux/fcntl.h b/tools/include/uapi/linux/fcntl.h index 813afd6eee71..6448cdd9a350 100644 --- a/tools/include/uapi/linux/fcntl.h +++ b/tools/include/uapi/linux/fcntl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_LINUX_FCNTL_H #define _UAPI_LINUX_FCNTL_H @@ -42,6 +43,27 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ /* (1U << 31) is reserved for signed error codes */ +/* + * Set/Get write life time hints. {GET,SET}_RW_HINT operate on the + * underlying inode, while {GET,SET}_FILE_RW_HINT operate only on + * the specific file. + */ +#define F_GET_RW_HINT (F_LINUX_SPECIFIC_BASE + 11) +#define F_SET_RW_HINT (F_LINUX_SPECIFIC_BASE + 12) +#define F_GET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 13) +#define F_SET_FILE_RW_HINT (F_LINUX_SPECIFIC_BASE + 14) + +/* + * Valid hint values for F_{GET,SET}_RW_HINT. 0 is "not set", or can be + * used to clear any hints previously set. + */ +#define RWF_WRITE_LIFE_NOT_SET 0 +#define RWH_WRITE_LIFE_NONE 1 +#define RWH_WRITE_LIFE_SHORT 2 +#define RWH_WRITE_LIFE_MEDIUM 3 +#define RWH_WRITE_LIFE_LONG 4 +#define RWH_WRITE_LIFE_EXTREME 5 + /* * Types of directory notifications that may be requested. */ diff --git a/tools/include/uapi/linux/hw_breakpoint.h b/tools/include/uapi/linux/hw_breakpoint.h index 2b65efd19a46..965e4d8606d8 100644 --- a/tools/include/uapi/linux/hw_breakpoint.h +++ b/tools/include/uapi/linux/hw_breakpoint.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_LINUX_HW_BREAKPOINT_H #define _UAPI_LINUX_HW_BREAKPOINT_H diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h new file mode 100644 index 000000000000..7e99999d6236 --- /dev/null +++ b/tools/include/uapi/linux/kvm.h @@ -0,0 +1,1421 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef __LINUX_KVM_H +#define __LINUX_KVM_H + +/* + * Userspace interface for /dev/kvm - kernel based virtual machine + * + * Note: you must update KVM_API_VERSION if you change this interface. + */ + +#include +#include +#include +#include + +#define KVM_API_VERSION 12 + +/* *** Deprecated interfaces *** */ + +#define KVM_TRC_SHIFT 16 + +#define KVM_TRC_ENTRYEXIT (1 << KVM_TRC_SHIFT) +#define KVM_TRC_HANDLER (1 << (KVM_TRC_SHIFT + 1)) + +#define KVM_TRC_VMENTRY (KVM_TRC_ENTRYEXIT + 0x01) +#define KVM_TRC_VMEXIT (KVM_TRC_ENTRYEXIT + 0x02) +#define KVM_TRC_PAGE_FAULT (KVM_TRC_HANDLER + 0x01) + +#define KVM_TRC_HEAD_SIZE 12 +#define KVM_TRC_CYCLE_SIZE 8 +#define KVM_TRC_EXTRA_MAX 7 + +#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) +#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) +#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04) +#define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05) +#define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06) +#define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07) +#define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08) +#define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09) +#define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A) +#define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B) +#define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C) +#define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D) +#define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E) +#define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F) +#define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10) +#define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11) +#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12) +#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13) +#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14) +#define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15) +#define KVM_TRC_GTLB_WRITE (KVM_TRC_HANDLER + 0x16) +#define KVM_TRC_STLB_WRITE (KVM_TRC_HANDLER + 0x17) +#define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18) +#define KVM_TRC_PPC_INSTR (KVM_TRC_HANDLER + 0x19) + +struct kvm_user_trace_setup { + __u32 buf_size; + __u32 buf_nr; +}; + +#define __KVM_DEPRECATED_MAIN_W_0x06 \ + _IOW(KVMIO, 0x06, struct kvm_user_trace_setup) +#define __KVM_DEPRECATED_MAIN_0x07 _IO(KVMIO, 0x07) +#define __KVM_DEPRECATED_MAIN_0x08 _IO(KVMIO, 0x08) + +#define __KVM_DEPRECATED_VM_R_0x70 _IOR(KVMIO, 0x70, struct kvm_assigned_irq) + +struct kvm_breakpoint { + __u32 enabled; + __u32 padding; + __u64 address; +}; + +struct kvm_debug_guest { + __u32 enabled; + __u32 pad; + struct kvm_breakpoint breakpoints[4]; + __u32 singlestep; +}; + +#define __KVM_DEPRECATED_VCPU_W_0x87 _IOW(KVMIO, 0x87, struct kvm_debug_guest) + +/* *** End of deprecated interfaces *** */ + + +/* for KVM_CREATE_MEMORY_REGION */ +struct kvm_memory_region { + __u32 slot; + __u32 flags; + __u64 guest_phys_addr; + __u64 memory_size; /* bytes */ +}; + +/* for KVM_SET_USER_MEMORY_REGION */ +struct kvm_userspace_memory_region { + __u32 slot; + __u32 flags; + __u64 guest_phys_addr; + __u64 memory_size; /* bytes */ + __u64 userspace_addr; /* start of the userspace allocated memory */ +}; + +/* + * The bit 0 ~ bit 15 of kvm_memory_region::flags are visible for userspace, + * other bits are reserved for kvm internal use which are defined in + * include/linux/kvm_host.h. + */ +#define KVM_MEM_LOG_DIRTY_PAGES (1UL << 0) +#define KVM_MEM_READONLY (1UL << 1) + +/* for KVM_IRQ_LINE */ +struct kvm_irq_level { + /* + * ACPI gsi notion of irq. + * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47.. + * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23.. + * For ARM: See Documentation/virtual/kvm/api.txt + */ + union { + __u32 irq; + __s32 status; + }; + __u32 level; +}; + + +struct kvm_irqchip { + __u32 chip_id; + __u32 pad; + union { + char dummy[512]; /* reserving space */ +#ifdef __KVM_HAVE_PIT + struct kvm_pic_state pic; +#endif +#ifdef __KVM_HAVE_IOAPIC + struct kvm_ioapic_state ioapic; +#endif + } chip; +}; + +/* for KVM_CREATE_PIT2 */ +struct kvm_pit_config { + __u32 flags; + __u32 pad[15]; +}; + +#define KVM_PIT_SPEAKER_DUMMY 1 + +struct kvm_s390_skeys { + __u64 start_gfn; + __u64 count; + __u64 skeydata_addr; + __u32 flags; + __u32 reserved[9]; +}; + +#define KVM_S390_CMMA_PEEK (1 << 0) + +/** + * kvm_s390_cmma_log - Used for CMMA migration. + * + * Used both for input and output. + * + * @start_gfn: Guest page number to start from. + * @count: Size of the result buffer. + * @flags: Control operation mode via KVM_S390_CMMA_* flags + * @remaining: Used with KVM_S390_GET_CMMA_BITS. Indicates how many dirty + * pages are still remaining. + * @mask: Used with KVM_S390_SET_CMMA_BITS. Bitmap of bits to actually set + * in the PGSTE. + * @values: Pointer to the values buffer. + * + * Used in KVM_S390_{G,S}ET_CMMA_BITS ioctls. + */ +struct kvm_s390_cmma_log { + __u64 start_gfn; + __u32 count; + __u32 flags; + union { + __u64 remaining; + __u64 mask; + }; + __u64 values; +}; + +struct kvm_hyperv_exit { +#define KVM_EXIT_HYPERV_SYNIC 1 +#define KVM_EXIT_HYPERV_HCALL 2 + __u32 type; + union { + struct { + __u32 msr; + __u64 control; + __u64 evt_page; + __u64 msg_page; + } synic; + struct { + __u64 input; + __u64 result; + __u64 params[2]; + } hcall; + } u; +}; + +#define KVM_S390_GET_SKEYS_NONE 1 +#define KVM_S390_SKEYS_MAX 1048576 + +#define KVM_EXIT_UNKNOWN 0 +#define KVM_EXIT_EXCEPTION 1 +#define KVM_EXIT_IO 2 +#define KVM_EXIT_HYPERCALL 3 +#define KVM_EXIT_DEBUG 4 +#define KVM_EXIT_HLT 5 +#define KVM_EXIT_MMIO 6 +#define KVM_EXIT_IRQ_WINDOW_OPEN 7 +#define KVM_EXIT_SHUTDOWN 8 +#define KVM_EXIT_FAIL_ENTRY 9 +#define KVM_EXIT_INTR 10 +#define KVM_EXIT_SET_TPR 11 +#define KVM_EXIT_TPR_ACCESS 12 +#define KVM_EXIT_S390_SIEIC 13 +#define KVM_EXIT_S390_RESET 14 +#define KVM_EXIT_DCR 15 /* deprecated */ +#define KVM_EXIT_NMI 16 +#define KVM_EXIT_INTERNAL_ERROR 17 +#define KVM_EXIT_OSI 18 +#define KVM_EXIT_PAPR_HCALL 19 +#define KVM_EXIT_S390_UCONTROL 20 +#define KVM_EXIT_WATCHDOG 21 +#define KVM_EXIT_S390_TSCH 22 +#define KVM_EXIT_EPR 23 +#define KVM_EXIT_SYSTEM_EVENT 24 +#define KVM_EXIT_S390_STSI 25 +#define KVM_EXIT_IOAPIC_EOI 26 +#define KVM_EXIT_HYPERV 27 + +/* For KVM_EXIT_INTERNAL_ERROR */ +/* Emulate instruction failed. */ +#define KVM_INTERNAL_ERROR_EMULATION 1 +/* Encounter unexpected simultaneous exceptions. */ +#define KVM_INTERNAL_ERROR_SIMUL_EX 2 +/* Encounter unexpected vm-exit due to delivery event. */ +#define KVM_INTERNAL_ERROR_DELIVERY_EV 3 + +/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ +struct kvm_run { + /* in */ + __u8 request_interrupt_window; + __u8 immediate_exit; + __u8 padding1[6]; + + /* out */ + __u32 exit_reason; + __u8 ready_for_interrupt_injection; + __u8 if_flag; + __u16 flags; + + /* in (pre_kvm_run), out (post_kvm_run) */ + __u64 cr8; + __u64 apic_base; + +#ifdef __KVM_S390 + /* the processor status word for s390 */ + __u64 psw_mask; /* psw upper half */ + __u64 psw_addr; /* psw lower half */ +#endif + union { + /* KVM_EXIT_UNKNOWN */ + struct { + __u64 hardware_exit_reason; + } hw; + /* KVM_EXIT_FAIL_ENTRY */ + struct { + __u64 hardware_entry_failure_reason; + } fail_entry; + /* KVM_EXIT_EXCEPTION */ + struct { + __u32 exception; + __u32 error_code; + } ex; + /* KVM_EXIT_IO */ + struct { +#define KVM_EXIT_IO_IN 0 +#define KVM_EXIT_IO_OUT 1 + __u8 direction; + __u8 size; /* bytes */ + __u16 port; + __u32 count; + __u64 data_offset; /* relative to kvm_run start */ + } io; + /* KVM_EXIT_DEBUG */ + struct { + struct kvm_debug_exit_arch arch; + } debug; + /* KVM_EXIT_MMIO */ + struct { + __u64 phys_addr; + __u8 data[8]; + __u32 len; + __u8 is_write; + } mmio; + /* KVM_EXIT_HYPERCALL */ + struct { + __u64 nr; + __u64 args[6]; + __u64 ret; + __u32 longmode; + __u32 pad; + } hypercall; + /* KVM_EXIT_TPR_ACCESS */ + struct { + __u64 rip; + __u32 is_write; + __u32 pad; + } tpr_access; + /* KVM_EXIT_S390_SIEIC */ + struct { + __u8 icptcode; + __u16 ipa; + __u32 ipb; + } s390_sieic; + /* KVM_EXIT_S390_RESET */ +#define KVM_S390_RESET_POR 1 +#define KVM_S390_RESET_CLEAR 2 +#define KVM_S390_RESET_SUBSYSTEM 4 +#define KVM_S390_RESET_CPU_INIT 8 +#define KVM_S390_RESET_IPL 16 + __u64 s390_reset_flags; + /* KVM_EXIT_S390_UCONTROL */ + struct { + __u64 trans_exc_code; + __u32 pgm_code; + } s390_ucontrol; + /* KVM_EXIT_DCR (deprecated) */ + struct { + __u32 dcrn; + __u32 data; + __u8 is_write; + } dcr; + /* KVM_EXIT_INTERNAL_ERROR */ + struct { + __u32 suberror; + /* Available with KVM_CAP_INTERNAL_ERROR_DATA: */ + __u32 ndata; + __u64 data[16]; + } internal; + /* KVM_EXIT_OSI */ + struct { + __u64 gprs[32]; + } osi; + /* KVM_EXIT_PAPR_HCALL */ + struct { + __u64 nr; + __u64 ret; + __u64 args[9]; + } papr_hcall; + /* KVM_EXIT_S390_TSCH */ + struct { + __u16 subchannel_id; + __u16 subchannel_nr; + __u32 io_int_parm; + __u32 io_int_word; + __u32 ipb; + __u8 dequeued; + } s390_tsch; + /* KVM_EXIT_EPR */ + struct { + __u32 epr; + } epr; + /* KVM_EXIT_SYSTEM_EVENT */ + struct { +#define KVM_SYSTEM_EVENT_SHUTDOWN 1 +#define KVM_SYSTEM_EVENT_RESET 2 +#define KVM_SYSTEM_EVENT_CRASH 3 + __u32 type; + __u64 flags; + } system_event; + /* KVM_EXIT_S390_STSI */ + struct { + __u64 addr; + __u8 ar; + __u8 reserved; + __u8 fc; + __u8 sel1; + __u16 sel2; + } s390_stsi; + /* KVM_EXIT_IOAPIC_EOI */ + struct { + __u8 vector; + } eoi; + /* KVM_EXIT_HYPERV */ + struct kvm_hyperv_exit hyperv; + /* Fix the size of the union. */ + char padding[256]; + }; + + /* + * shared registers between kvm and userspace. + * kvm_valid_regs specifies the register classes set by the host + * kvm_dirty_regs specified the register classes dirtied by userspace + * struct kvm_sync_regs is architecture specific, as well as the + * bits for kvm_valid_regs and kvm_dirty_regs + */ + __u64 kvm_valid_regs; + __u64 kvm_dirty_regs; + union { + struct kvm_sync_regs regs; + char padding[2048]; + } s; +}; + +/* for KVM_REGISTER_COALESCED_MMIO / KVM_UNREGISTER_COALESCED_MMIO */ + +struct kvm_coalesced_mmio_zone { + __u64 addr; + __u32 size; + __u32 pad; +}; + +struct kvm_coalesced_mmio { + __u64 phys_addr; + __u32 len; + __u32 pad; + __u8 data[8]; +}; + +struct kvm_coalesced_mmio_ring { + __u32 first, last; + struct kvm_coalesced_mmio coalesced_mmio[0]; +}; + +#define KVM_COALESCED_MMIO_MAX \ + ((PAGE_SIZE - sizeof(struct kvm_coalesced_mmio_ring)) / \ + sizeof(struct kvm_coalesced_mmio)) + +/* for KVM_TRANSLATE */ +struct kvm_translation { + /* in */ + __u64 linear_address; + + /* out */ + __u64 physical_address; + __u8 valid; + __u8 writeable; + __u8 usermode; + __u8 pad[5]; +}; + +/* for KVM_S390_MEM_OP */ +struct kvm_s390_mem_op { + /* in */ + __u64 gaddr; /* the guest address */ + __u64 flags; /* flags */ + __u32 size; /* amount of bytes */ + __u32 op; /* type of operation */ + __u64 buf; /* buffer in userspace */ + __u8 ar; /* the access register number */ + __u8 reserved[31]; /* should be set to 0 */ +}; +/* types for kvm_s390_mem_op->op */ +#define KVM_S390_MEMOP_LOGICAL_READ 0 +#define KVM_S390_MEMOP_LOGICAL_WRITE 1 +/* flags for kvm_s390_mem_op->flags */ +#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0) +#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1) + +/* for KVM_INTERRUPT */ +struct kvm_interrupt { + /* in */ + __u32 irq; +}; + +/* for KVM_GET_DIRTY_LOG */ +struct kvm_dirty_log { + __u32 slot; + __u32 padding1; + union { + void __user *dirty_bitmap; /* one bit per page */ + __u64 padding2; + }; +}; + +/* for KVM_SET_SIGNAL_MASK */ +struct kvm_signal_mask { + __u32 len; + __u8 sigset[0]; +}; + +/* for KVM_TPR_ACCESS_REPORTING */ +struct kvm_tpr_access_ctl { + __u32 enabled; + __u32 flags; + __u32 reserved[8]; +}; + +/* for KVM_SET_VAPIC_ADDR */ +struct kvm_vapic_addr { + __u64 vapic_addr; +}; + +/* for KVM_SET_MP_STATE */ + +/* not all states are valid on all architectures */ +#define KVM_MP_STATE_RUNNABLE 0 +#define KVM_MP_STATE_UNINITIALIZED 1 +#define KVM_MP_STATE_INIT_RECEIVED 2 +#define KVM_MP_STATE_HALTED 3 +#define KVM_MP_STATE_SIPI_RECEIVED 4 +#define KVM_MP_STATE_STOPPED 5 +#define KVM_MP_STATE_CHECK_STOP 6 +#define KVM_MP_STATE_OPERATING 7 +#define KVM_MP_STATE_LOAD 8 + +struct kvm_mp_state { + __u32 mp_state; +}; + +struct kvm_s390_psw { + __u64 mask; + __u64 addr; +}; + +/* valid values for type in kvm_s390_interrupt */ +#define KVM_S390_SIGP_STOP 0xfffe0000u +#define KVM_S390_PROGRAM_INT 0xfffe0001u +#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u +#define KVM_S390_RESTART 0xfffe0003u +#define KVM_S390_INT_PFAULT_INIT 0xfffe0004u +#define KVM_S390_INT_PFAULT_DONE 0xfffe0005u +#define KVM_S390_MCHK 0xfffe1000u +#define KVM_S390_INT_CLOCK_COMP 0xffff1004u +#define KVM_S390_INT_CPU_TIMER 0xffff1005u +#define KVM_S390_INT_VIRTIO 0xffff2603u +#define KVM_S390_INT_SERVICE 0xffff2401u +#define KVM_S390_INT_EMERGENCY 0xffff1201u +#define KVM_S390_INT_EXTERNAL_CALL 0xffff1202u +/* Anything below 0xfffe0000u is taken by INT_IO */ +#define KVM_S390_INT_IO(ai,cssid,ssid,schid) \ + (((schid)) | \ + ((ssid) << 16) | \ + ((cssid) << 18) | \ + ((ai) << 26)) +#define KVM_S390_INT_IO_MIN 0x00000000u +#define KVM_S390_INT_IO_MAX 0xfffdffffu +#define KVM_S390_INT_IO_AI_MASK 0x04000000u + + +struct kvm_s390_interrupt { + __u32 type; + __u32 parm; + __u64 parm64; +}; + +struct kvm_s390_io_info { + __u16 subchannel_id; + __u16 subchannel_nr; + __u32 io_int_parm; + __u32 io_int_word; +}; + +struct kvm_s390_ext_info { + __u32 ext_params; + __u32 pad; + __u64 ext_params2; +}; + +struct kvm_s390_pgm_info { + __u64 trans_exc_code; + __u64 mon_code; + __u64 per_address; + __u32 data_exc_code; + __u16 code; + __u16 mon_class_nr; + __u8 per_code; + __u8 per_atmid; + __u8 exc_access_id; + __u8 per_access_id; + __u8 op_access_id; +#define KVM_S390_PGM_FLAGS_ILC_VALID 0x01 +#define KVM_S390_PGM_FLAGS_ILC_0 0x02 +#define KVM_S390_PGM_FLAGS_ILC_1 0x04 +#define KVM_S390_PGM_FLAGS_ILC_MASK 0x06 +#define KVM_S390_PGM_FLAGS_NO_REWIND 0x08 + __u8 flags; + __u8 pad[2]; +}; + +struct kvm_s390_prefix_info { + __u32 address; +}; + +struct kvm_s390_extcall_info { + __u16 code; +}; + +struct kvm_s390_emerg_info { + __u16 code; +}; + +#define KVM_S390_STOP_FLAG_STORE_STATUS 0x01 +struct kvm_s390_stop_info { + __u32 flags; +}; + +struct kvm_s390_mchk_info { + __u64 cr14; + __u64 mcic; + __u64 failing_storage_address; + __u32 ext_damage_code; + __u32 pad; + __u8 fixed_logout[16]; +}; + +struct kvm_s390_irq { + __u64 type; + union { + struct kvm_s390_io_info io; + struct kvm_s390_ext_info ext; + struct kvm_s390_pgm_info pgm; + struct kvm_s390_emerg_info emerg; + struct kvm_s390_extcall_info extcall; + struct kvm_s390_prefix_info prefix; + struct kvm_s390_stop_info stop; + struct kvm_s390_mchk_info mchk; + char reserved[64]; + } u; +}; + +struct kvm_s390_irq_state { + __u64 buf; + __u32 flags; + __u32 len; + __u32 reserved[4]; +}; + +/* for KVM_SET_GUEST_DEBUG */ + +#define KVM_GUESTDBG_ENABLE 0x00000001 +#define KVM_GUESTDBG_SINGLESTEP 0x00000002 + +struct kvm_guest_debug { + __u32 control; + __u32 pad; + struct kvm_guest_debug_arch arch; +}; + +enum { + kvm_ioeventfd_flag_nr_datamatch, + kvm_ioeventfd_flag_nr_pio, + kvm_ioeventfd_flag_nr_deassign, + kvm_ioeventfd_flag_nr_virtio_ccw_notify, + kvm_ioeventfd_flag_nr_fast_mmio, + kvm_ioeventfd_flag_nr_max, +}; + +#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch) +#define KVM_IOEVENTFD_FLAG_PIO (1 << kvm_ioeventfd_flag_nr_pio) +#define KVM_IOEVENTFD_FLAG_DEASSIGN (1 << kvm_ioeventfd_flag_nr_deassign) +#define KVM_IOEVENTFD_FLAG_VIRTIO_CCW_NOTIFY \ + (1 << kvm_ioeventfd_flag_nr_virtio_ccw_notify) + +#define KVM_IOEVENTFD_VALID_FLAG_MASK ((1 << kvm_ioeventfd_flag_nr_max) - 1) + +struct kvm_ioeventfd { + __u64 datamatch; + __u64 addr; /* legal pio/mmio address */ + __u32 len; /* 1, 2, 4, or 8 bytes; or 0 to ignore length */ + __s32 fd; + __u32 flags; + __u8 pad[36]; +}; + +/* for KVM_ENABLE_CAP */ +struct kvm_enable_cap { + /* in */ + __u32 cap; + __u32 flags; + __u64 args[4]; + __u8 pad[64]; +}; + +/* for KVM_PPC_GET_PVINFO */ + +#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0) + +struct kvm_ppc_pvinfo { + /* out */ + __u32 flags; + __u32 hcall[4]; + __u8 pad[108]; +}; + +/* for KVM_PPC_GET_SMMU_INFO */ +#define KVM_PPC_PAGE_SIZES_MAX_SZ 8 + +struct kvm_ppc_one_page_size { + __u32 page_shift; /* Page shift (or 0) */ + __u32 pte_enc; /* Encoding in the HPTE (>>12) */ +}; + +struct kvm_ppc_one_seg_page_size { + __u32 page_shift; /* Base page shift of segment (or 0) */ + __u32 slb_enc; /* SLB encoding for BookS */ + struct kvm_ppc_one_page_size enc[KVM_PPC_PAGE_SIZES_MAX_SZ]; +}; + +#define KVM_PPC_PAGE_SIZES_REAL 0x00000001 +#define KVM_PPC_1T_SEGMENTS 0x00000002 + +struct kvm_ppc_smmu_info { + __u64 flags; + __u32 slb_size; + __u16 data_keys; /* # storage keys supported for data */ + __u16 instr_keys; /* # storage keys supported for instructions */ + struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; +}; + +/* for KVM_PPC_RESIZE_HPT_{PREPARE,COMMIT} */ +struct kvm_ppc_resize_hpt { + __u64 flags; + __u32 shift; + __u32 pad; +}; + +#define KVMIO 0xAE + +/* machine type bits, to be used as argument to KVM_CREATE_VM */ +#define KVM_VM_S390_UCONTROL 1 + +/* on ppc, 0 indicate default, 1 should force HV and 2 PR */ +#define KVM_VM_PPC_HV 1 +#define KVM_VM_PPC_PR 2 + +/* on MIPS, 0 forces trap & emulate, 1 forces VZ ASE */ +#define KVM_VM_MIPS_TE 0 +#define KVM_VM_MIPS_VZ 1 + +#define KVM_S390_SIE_PAGE_OFFSET 1 + +/* + * ioctls for /dev/kvm fds: + */ +#define KVM_GET_API_VERSION _IO(KVMIO, 0x00) +#define KVM_CREATE_VM _IO(KVMIO, 0x01) /* returns a VM fd */ +#define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 0x02, struct kvm_msr_list) + +#define KVM_S390_ENABLE_SIE _IO(KVMIO, 0x06) +/* + * Check if a kvm extension is available. Argument is extension number, + * return is 1 (yes) or 0 (no, sorry). + */ +#define KVM_CHECK_EXTENSION _IO(KVMIO, 0x03) +/* + * Get size for mmap(vcpu_fd) + */ +#define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */ +#define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2) +#define KVM_TRACE_ENABLE __KVM_DEPRECATED_MAIN_W_0x06 +#define KVM_TRACE_PAUSE __KVM_DEPRECATED_MAIN_0x07 +#define KVM_TRACE_DISABLE __KVM_DEPRECATED_MAIN_0x08 +#define KVM_GET_EMULATED_CPUID _IOWR(KVMIO, 0x09, struct kvm_cpuid2) + +/* + * Extension capability list. + */ +#define KVM_CAP_IRQCHIP 0 +#define KVM_CAP_HLT 1 +#define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2 +#define KVM_CAP_USER_MEMORY 3 +#define KVM_CAP_SET_TSS_ADDR 4 +#define KVM_CAP_VAPIC 6 +#define KVM_CAP_EXT_CPUID 7 +#define KVM_CAP_CLOCKSOURCE 8 +#define KVM_CAP_NR_VCPUS 9 /* returns recommended max vcpus per vm */ +#define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ +#define KVM_CAP_PIT 11 +#define KVM_CAP_NOP_IO_DELAY 12 +#define KVM_CAP_PV_MMU 13 +#define KVM_CAP_MP_STATE 14 +#define KVM_CAP_COALESCED_MMIO 15 +#define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ +#define KVM_CAP_IOMMU 18 +/* Bug in KVM_SET_USER_MEMORY_REGION fixed: */ +#define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21 +#define KVM_CAP_USER_NMI 22 +#ifdef __KVM_HAVE_GUEST_DEBUG +#define KVM_CAP_SET_GUEST_DEBUG 23 +#endif +#ifdef __KVM_HAVE_PIT +#define KVM_CAP_REINJECT_CONTROL 24 +#endif +#define KVM_CAP_IRQ_ROUTING 25 +#define KVM_CAP_IRQ_INJECT_STATUS 26 +#define KVM_CAP_ASSIGN_DEV_IRQ 29 +/* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */ +#define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30 +#ifdef __KVM_HAVE_MCE +#define KVM_CAP_MCE 31 +#endif +#define KVM_CAP_IRQFD 32 +#ifdef __KVM_HAVE_PIT +#define KVM_CAP_PIT2 33 +#endif +#define KVM_CAP_SET_BOOT_CPU_ID 34 +#ifdef __KVM_HAVE_PIT_STATE2 +#define KVM_CAP_PIT_STATE2 35 +#endif +#define KVM_CAP_IOEVENTFD 36 +#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37 +#ifdef __KVM_HAVE_XEN_HVM +#define KVM_CAP_XEN_HVM 38 +#endif +#define KVM_CAP_ADJUST_CLOCK 39 +#define KVM_CAP_INTERNAL_ERROR_DATA 40 +#ifdef __KVM_HAVE_VCPU_EVENTS +#define KVM_CAP_VCPU_EVENTS 41 +#endif +#define KVM_CAP_S390_PSW 42 +#define KVM_CAP_PPC_SEGSTATE 43 +#define KVM_CAP_HYPERV 44 +#define KVM_CAP_HYPERV_VAPIC 45 +#define KVM_CAP_HYPERV_SPIN 46 +#define KVM_CAP_PCI_SEGMENT 47 +#define KVM_CAP_PPC_PAIRED_SINGLES 48 +#define KVM_CAP_INTR_SHADOW 49 +#ifdef __KVM_HAVE_DEBUGREGS +#define KVM_CAP_DEBUGREGS 50 +#endif +#define KVM_CAP_X86_ROBUST_SINGLESTEP 51 +#define KVM_CAP_PPC_OSI 52 +#define KVM_CAP_PPC_UNSET_IRQ 53 +#define KVM_CAP_ENABLE_CAP 54 +#ifdef __KVM_HAVE_XSAVE +#define KVM_CAP_XSAVE 55 +#endif +#ifdef __KVM_HAVE_XCRS +#define KVM_CAP_XCRS 56 +#endif +#define KVM_CAP_PPC_GET_PVINFO 57 +#define KVM_CAP_PPC_IRQ_LEVEL 58 +#define KVM_CAP_ASYNC_PF 59 +#define KVM_CAP_TSC_CONTROL 60 +#define KVM_CAP_GET_TSC_KHZ 61 +#define KVM_CAP_PPC_BOOKE_SREGS 62 +#define KVM_CAP_SPAPR_TCE 63 +#define KVM_CAP_PPC_SMT 64 +#define KVM_CAP_PPC_RMA 65 +#define KVM_CAP_MAX_VCPUS 66 /* returns max vcpus per vm */ +#define KVM_CAP_PPC_HIOR 67 +#define KVM_CAP_PPC_PAPR 68 +#define KVM_CAP_SW_TLB 69 +#define KVM_CAP_ONE_REG 70 +#define KVM_CAP_S390_GMAP 71 +#define KVM_CAP_TSC_DEADLINE_TIMER 72 +#define KVM_CAP_S390_UCONTROL 73 +#define KVM_CAP_SYNC_REGS 74 +#define KVM_CAP_PCI_2_3 75 +#define KVM_CAP_KVMCLOCK_CTRL 76 +#define KVM_CAP_SIGNAL_MSI 77 +#define KVM_CAP_PPC_GET_SMMU_INFO 78 +#define KVM_CAP_S390_COW 79 +#define KVM_CAP_PPC_ALLOC_HTAB 80 +#define KVM_CAP_READONLY_MEM 81 +#define KVM_CAP_IRQFD_RESAMPLE 82 +#define KVM_CAP_PPC_BOOKE_WATCHDOG 83 +#define KVM_CAP_PPC_HTAB_FD 84 +#define KVM_CAP_S390_CSS_SUPPORT 85 +#define KVM_CAP_PPC_EPR 86 +#define KVM_CAP_ARM_PSCI 87 +#define KVM_CAP_ARM_SET_DEVICE_ADDR 88 +#define KVM_CAP_DEVICE_CTRL 89 +#define KVM_CAP_IRQ_MPIC 90 +#define KVM_CAP_PPC_RTAS 91 +#define KVM_CAP_IRQ_XICS 92 +#define KVM_CAP_ARM_EL1_32BIT 93 +#define KVM_CAP_SPAPR_MULTITCE 94 +#define KVM_CAP_EXT_EMUL_CPUID 95 +#define KVM_CAP_HYPERV_TIME 96 +#define KVM_CAP_IOAPIC_POLARITY_IGNORED 97 +#define KVM_CAP_ENABLE_CAP_VM 98 +#define KVM_CAP_S390_IRQCHIP 99 +#define KVM_CAP_IOEVENTFD_NO_LENGTH 100 +#define KVM_CAP_VM_ATTRIBUTES 101 +#define KVM_CAP_ARM_PSCI_0_2 102 +#define KVM_CAP_PPC_FIXUP_HCALL 103 +#define KVM_CAP_PPC_ENABLE_HCALL 104 +#define KVM_CAP_CHECK_EXTENSION_VM 105 +#define KVM_CAP_S390_USER_SIGP 106 +#define KVM_CAP_S390_VECTOR_REGISTERS 107 +#define KVM_CAP_S390_MEM_OP 108 +#define KVM_CAP_S390_USER_STSI 109 +#define KVM_CAP_S390_SKEYS 110 +#define KVM_CAP_MIPS_FPU 111 +#define KVM_CAP_MIPS_MSA 112 +#define KVM_CAP_S390_INJECT_IRQ 113 +#define KVM_CAP_S390_IRQ_STATE 114 +#define KVM_CAP_PPC_HWRNG 115 +#define KVM_CAP_DISABLE_QUIRKS 116 +#define KVM_CAP_X86_SMM 117 +#define KVM_CAP_MULTI_ADDRESS_SPACE 118 +#define KVM_CAP_GUEST_DEBUG_HW_BPS 119 +#define KVM_CAP_GUEST_DEBUG_HW_WPS 120 +#define KVM_CAP_SPLIT_IRQCHIP 121 +#define KVM_CAP_IOEVENTFD_ANY_LENGTH 122 +#define KVM_CAP_HYPERV_SYNIC 123 +#define KVM_CAP_S390_RI 124 +#define KVM_CAP_SPAPR_TCE_64 125 +#define KVM_CAP_ARM_PMU_V3 126 +#define KVM_CAP_VCPU_ATTRIBUTES 127 +#define KVM_CAP_MAX_VCPU_ID 128 +#define KVM_CAP_X2APIC_API 129 +#define KVM_CAP_S390_USER_INSTR0 130 +#define KVM_CAP_MSI_DEVID 131 +#define KVM_CAP_PPC_HTM 132 +#define KVM_CAP_SPAPR_RESIZE_HPT 133 +#define KVM_CAP_PPC_MMU_RADIX 134 +#define KVM_CAP_PPC_MMU_HASH_V3 135 +#define KVM_CAP_IMMEDIATE_EXIT 136 +#define KVM_CAP_MIPS_VZ 137 +#define KVM_CAP_MIPS_TE 138 +#define KVM_CAP_MIPS_64BIT 139 +#define KVM_CAP_S390_GS 140 +#define KVM_CAP_S390_AIS 141 +#define KVM_CAP_SPAPR_TCE_VFIO 142 +#define KVM_CAP_X86_GUEST_MWAIT 143 +#define KVM_CAP_ARM_USER_IRQ 144 +#define KVM_CAP_S390_CMMA_MIGRATION 145 +#define KVM_CAP_PPC_FWNMI 146 +#define KVM_CAP_PPC_SMT_POSSIBLE 147 +#define KVM_CAP_HYPERV_SYNIC2 148 +#define KVM_CAP_HYPERV_VP_INDEX 149 + +#ifdef KVM_CAP_IRQ_ROUTING + +struct kvm_irq_routing_irqchip { + __u32 irqchip; + __u32 pin; +}; + +struct kvm_irq_routing_msi { + __u32 address_lo; + __u32 address_hi; + __u32 data; + union { + __u32 pad; + __u32 devid; + }; +}; + +struct kvm_irq_routing_s390_adapter { + __u64 ind_addr; + __u64 summary_addr; + __u64 ind_offset; + __u32 summary_offset; + __u32 adapter_id; +}; + +struct kvm_irq_routing_hv_sint { + __u32 vcpu; + __u32 sint; +}; + +/* gsi routing entry types */ +#define KVM_IRQ_ROUTING_IRQCHIP 1 +#define KVM_IRQ_ROUTING_MSI 2 +#define KVM_IRQ_ROUTING_S390_ADAPTER 3 +#define KVM_IRQ_ROUTING_HV_SINT 4 + +struct kvm_irq_routing_entry { + __u32 gsi; + __u32 type; + __u32 flags; + __u32 pad; + union { + struct kvm_irq_routing_irqchip irqchip; + struct kvm_irq_routing_msi msi; + struct kvm_irq_routing_s390_adapter adapter; + struct kvm_irq_routing_hv_sint hv_sint; + __u32 pad[8]; + } u; +}; + +struct kvm_irq_routing { + __u32 nr; + __u32 flags; + struct kvm_irq_routing_entry entries[0]; +}; + +#endif + +#ifdef KVM_CAP_MCE +/* x86 MCE */ +struct kvm_x86_mce { + __u64 status; + __u64 addr; + __u64 misc; + __u64 mcg_status; + __u8 bank; + __u8 pad1[7]; + __u64 pad2[3]; +}; +#endif + +#ifdef KVM_CAP_XEN_HVM +struct kvm_xen_hvm_config { + __u32 flags; + __u32 msr; + __u64 blob_addr_32; + __u64 blob_addr_64; + __u8 blob_size_32; + __u8 blob_size_64; + __u8 pad2[30]; +}; +#endif + +#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0) +/* + * Available with KVM_CAP_IRQFD_RESAMPLE + * + * KVM_IRQFD_FLAG_RESAMPLE indicates resamplefd is valid and specifies + * the irqfd to operate in resampling mode for level triggered interrupt + * emulation. See Documentation/virtual/kvm/api.txt. + */ +#define KVM_IRQFD_FLAG_RESAMPLE (1 << 1) + +struct kvm_irqfd { + __u32 fd; + __u32 gsi; + __u32 flags; + __u32 resamplefd; + __u8 pad[16]; +}; + +/* For KVM_CAP_ADJUST_CLOCK */ + +/* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags. */ +#define KVM_CLOCK_TSC_STABLE 2 + +struct kvm_clock_data { + __u64 clock; + __u32 flags; + __u32 pad[9]; +}; + +/* For KVM_CAP_SW_TLB */ + +#define KVM_MMU_FSL_BOOKE_NOHV 0 +#define KVM_MMU_FSL_BOOKE_HV 1 + +struct kvm_config_tlb { + __u64 params; + __u64 array; + __u32 mmu_type; + __u32 array_len; +}; + +struct kvm_dirty_tlb { + __u64 bitmap; + __u32 num_dirty; +}; + +/* Available with KVM_CAP_ONE_REG */ + +#define KVM_REG_ARCH_MASK 0xff00000000000000ULL +#define KVM_REG_GENERIC 0x0000000000000000ULL + +/* + * Architecture specific registers are to be defined in arch headers and + * ORed with the arch identifier. + */ +#define KVM_REG_PPC 0x1000000000000000ULL +#define KVM_REG_X86 0x2000000000000000ULL +#define KVM_REG_IA64 0x3000000000000000ULL +#define KVM_REG_ARM 0x4000000000000000ULL +#define KVM_REG_S390 0x5000000000000000ULL +#define KVM_REG_ARM64 0x6000000000000000ULL +#define KVM_REG_MIPS 0x7000000000000000ULL + +#define KVM_REG_SIZE_SHIFT 52 +#define KVM_REG_SIZE_MASK 0x00f0000000000000ULL +#define KVM_REG_SIZE_U8 0x0000000000000000ULL +#define KVM_REG_SIZE_U16 0x0010000000000000ULL +#define KVM_REG_SIZE_U32 0x0020000000000000ULL +#define KVM_REG_SIZE_U64 0x0030000000000000ULL +#define KVM_REG_SIZE_U128 0x0040000000000000ULL +#define KVM_REG_SIZE_U256 0x0050000000000000ULL +#define KVM_REG_SIZE_U512 0x0060000000000000ULL +#define KVM_REG_SIZE_U1024 0x0070000000000000ULL + +struct kvm_reg_list { + __u64 n; /* number of regs */ + __u64 reg[0]; +}; + +struct kvm_one_reg { + __u64 id; + __u64 addr; +}; + +#define KVM_MSI_VALID_DEVID (1U << 0) +struct kvm_msi { + __u32 address_lo; + __u32 address_hi; + __u32 data; + __u32 flags; + __u32 devid; + __u8 pad[12]; +}; + +struct kvm_arm_device_addr { + __u64 id; + __u64 addr; +}; + +/* + * Device control API, available with KVM_CAP_DEVICE_CTRL + */ +#define KVM_CREATE_DEVICE_TEST 1 + +struct kvm_create_device { + __u32 type; /* in: KVM_DEV_TYPE_xxx */ + __u32 fd; /* out: device handle */ + __u32 flags; /* in: KVM_CREATE_DEVICE_xxx */ +}; + +struct kvm_device_attr { + __u32 flags; /* no flags currently defined */ + __u32 group; /* device-defined */ + __u64 attr; /* group-defined */ + __u64 addr; /* userspace address of attr data */ +}; + +#define KVM_DEV_VFIO_GROUP 1 +#define KVM_DEV_VFIO_GROUP_ADD 1 +#define KVM_DEV_VFIO_GROUP_DEL 2 +#define KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE 3 + +enum kvm_device_type { + KVM_DEV_TYPE_FSL_MPIC_20 = 1, +#define KVM_DEV_TYPE_FSL_MPIC_20 KVM_DEV_TYPE_FSL_MPIC_20 + KVM_DEV_TYPE_FSL_MPIC_42, +#define KVM_DEV_TYPE_FSL_MPIC_42 KVM_DEV_TYPE_FSL_MPIC_42 + KVM_DEV_TYPE_XICS, +#define KVM_DEV_TYPE_XICS KVM_DEV_TYPE_XICS + KVM_DEV_TYPE_VFIO, +#define KVM_DEV_TYPE_VFIO KVM_DEV_TYPE_VFIO + KVM_DEV_TYPE_ARM_VGIC_V2, +#define KVM_DEV_TYPE_ARM_VGIC_V2 KVM_DEV_TYPE_ARM_VGIC_V2 + KVM_DEV_TYPE_FLIC, +#define KVM_DEV_TYPE_FLIC KVM_DEV_TYPE_FLIC + KVM_DEV_TYPE_ARM_VGIC_V3, +#define KVM_DEV_TYPE_ARM_VGIC_V3 KVM_DEV_TYPE_ARM_VGIC_V3 + KVM_DEV_TYPE_ARM_VGIC_ITS, +#define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS + KVM_DEV_TYPE_MAX, +}; + +struct kvm_vfio_spapr_tce { + __s32 groupfd; + __s32 tablefd; +}; + +/* + * ioctls for VM fds + */ +#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 0x40, struct kvm_memory_region) +/* + * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns + * a vcpu fd. + */ +#define KVM_CREATE_VCPU _IO(KVMIO, 0x41) +#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log) +/* KVM_SET_MEMORY_ALIAS is obsolete: */ +#define KVM_SET_MEMORY_ALIAS _IOW(KVMIO, 0x43, struct kvm_memory_alias) +#define KVM_SET_NR_MMU_PAGES _IO(KVMIO, 0x44) +#define KVM_GET_NR_MMU_PAGES _IO(KVMIO, 0x45) +#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46, \ + struct kvm_userspace_memory_region) +#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47) +#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64) + +/* enable ucontrol for s390 */ +struct kvm_s390_ucas_mapping { + __u64 user_addr; + __u64 vcpu_addr; + __u64 length; +}; +#define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping) +#define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping) +#define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long) + +/* Device model IOC */ +#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60) +#define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level) +#define KVM_GET_IRQCHIP _IOWR(KVMIO, 0x62, struct kvm_irqchip) +#define KVM_SET_IRQCHIP _IOR(KVMIO, 0x63, struct kvm_irqchip) +#define KVM_CREATE_PIT _IO(KVMIO, 0x64) +#define KVM_GET_PIT _IOWR(KVMIO, 0x65, struct kvm_pit_state) +#define KVM_SET_PIT _IOR(KVMIO, 0x66, struct kvm_pit_state) +#define KVM_IRQ_LINE_STATUS _IOWR(KVMIO, 0x67, struct kvm_irq_level) +#define KVM_REGISTER_COALESCED_MMIO \ + _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone) +#define KVM_UNREGISTER_COALESCED_MMIO \ + _IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone) +#define KVM_ASSIGN_PCI_DEVICE _IOR(KVMIO, 0x69, \ + struct kvm_assigned_pci_dev) +#define KVM_SET_GSI_ROUTING _IOW(KVMIO, 0x6a, struct kvm_irq_routing) +/* deprecated, replaced by KVM_ASSIGN_DEV_IRQ */ +#define KVM_ASSIGN_IRQ __KVM_DEPRECATED_VM_R_0x70 +#define KVM_ASSIGN_DEV_IRQ _IOW(KVMIO, 0x70, struct kvm_assigned_irq) +#define KVM_REINJECT_CONTROL _IO(KVMIO, 0x71) +#define KVM_DEASSIGN_PCI_DEVICE _IOW(KVMIO, 0x72, \ + struct kvm_assigned_pci_dev) +#define KVM_ASSIGN_SET_MSIX_NR _IOW(KVMIO, 0x73, \ + struct kvm_assigned_msix_nr) +#define KVM_ASSIGN_SET_MSIX_ENTRY _IOW(KVMIO, 0x74, \ + struct kvm_assigned_msix_entry) +#define KVM_DEASSIGN_DEV_IRQ _IOW(KVMIO, 0x75, struct kvm_assigned_irq) +#define KVM_IRQFD _IOW(KVMIO, 0x76, struct kvm_irqfd) +#define KVM_CREATE_PIT2 _IOW(KVMIO, 0x77, struct kvm_pit_config) +#define KVM_SET_BOOT_CPU_ID _IO(KVMIO, 0x78) +#define KVM_IOEVENTFD _IOW(KVMIO, 0x79, struct kvm_ioeventfd) +#define KVM_XEN_HVM_CONFIG _IOW(KVMIO, 0x7a, struct kvm_xen_hvm_config) +#define KVM_SET_CLOCK _IOW(KVMIO, 0x7b, struct kvm_clock_data) +#define KVM_GET_CLOCK _IOR(KVMIO, 0x7c, struct kvm_clock_data) +/* Available with KVM_CAP_PIT_STATE2 */ +#define KVM_GET_PIT2 _IOR(KVMIO, 0x9f, struct kvm_pit_state2) +#define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) +/* Available with KVM_CAP_PPC_GET_PVINFO */ +#define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo) +/* Available with KVM_CAP_TSC_CONTROL */ +#define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2) +#define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3) +/* Available with KVM_CAP_PCI_2_3 */ +#define KVM_ASSIGN_SET_INTX_MASK _IOW(KVMIO, 0xa4, \ + struct kvm_assigned_pci_dev) +/* Available with KVM_CAP_SIGNAL_MSI */ +#define KVM_SIGNAL_MSI _IOW(KVMIO, 0xa5, struct kvm_msi) +/* Available with KVM_CAP_PPC_GET_SMMU_INFO */ +#define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info) +/* Available with KVM_CAP_PPC_ALLOC_HTAB */ +#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32) +#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) +#define KVM_CREATE_SPAPR_TCE_64 _IOW(KVMIO, 0xa8, \ + struct kvm_create_spapr_tce_64) +/* Available with KVM_CAP_RMA */ +#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) +/* Available with KVM_CAP_PPC_HTAB_FD */ +#define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd) +/* Available with KVM_CAP_ARM_SET_DEVICE_ADDR */ +#define KVM_ARM_SET_DEVICE_ADDR _IOW(KVMIO, 0xab, struct kvm_arm_device_addr) +/* Available with KVM_CAP_PPC_RTAS */ +#define KVM_PPC_RTAS_DEFINE_TOKEN _IOW(KVMIO, 0xac, struct kvm_rtas_token_args) +/* Available with KVM_CAP_SPAPR_RESIZE_HPT */ +#define KVM_PPC_RESIZE_HPT_PREPARE _IOR(KVMIO, 0xad, struct kvm_ppc_resize_hpt) +#define KVM_PPC_RESIZE_HPT_COMMIT _IOR(KVMIO, 0xae, struct kvm_ppc_resize_hpt) +/* Available with KVM_CAP_PPC_RADIX_MMU or KVM_CAP_PPC_HASH_MMU_V3 */ +#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg) +/* Available with KVM_CAP_PPC_RADIX_MMU */ +#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info) + +/* ioctl for vm fd */ +#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) + +/* ioctls for fds returned by KVM_CREATE_DEVICE */ +#define KVM_SET_DEVICE_ATTR _IOW(KVMIO, 0xe1, struct kvm_device_attr) +#define KVM_GET_DEVICE_ATTR _IOW(KVMIO, 0xe2, struct kvm_device_attr) +#define KVM_HAS_DEVICE_ATTR _IOW(KVMIO, 0xe3, struct kvm_device_attr) + +/* + * ioctls for vcpu fds + */ +#define KVM_RUN _IO(KVMIO, 0x80) +#define KVM_GET_REGS _IOR(KVMIO, 0x81, struct kvm_regs) +#define KVM_SET_REGS _IOW(KVMIO, 0x82, struct kvm_regs) +#define KVM_GET_SREGS _IOR(KVMIO, 0x83, struct kvm_sregs) +#define KVM_SET_SREGS _IOW(KVMIO, 0x84, struct kvm_sregs) +#define KVM_TRANSLATE _IOWR(KVMIO, 0x85, struct kvm_translation) +#define KVM_INTERRUPT _IOW(KVMIO, 0x86, struct kvm_interrupt) +/* KVM_DEBUG_GUEST is no longer supported, use KVM_SET_GUEST_DEBUG instead */ +#define KVM_DEBUG_GUEST __KVM_DEPRECATED_VCPU_W_0x87 +#define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs) +#define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs) +#define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid) +#define KVM_SET_SIGNAL_MASK _IOW(KVMIO, 0x8b, struct kvm_signal_mask) +#define KVM_GET_FPU _IOR(KVMIO, 0x8c, struct kvm_fpu) +#define KVM_SET_FPU _IOW(KVMIO, 0x8d, struct kvm_fpu) +#define KVM_GET_LAPIC _IOR(KVMIO, 0x8e, struct kvm_lapic_state) +#define KVM_SET_LAPIC _IOW(KVMIO, 0x8f, struct kvm_lapic_state) +#define KVM_SET_CPUID2 _IOW(KVMIO, 0x90, struct kvm_cpuid2) +#define KVM_GET_CPUID2 _IOWR(KVMIO, 0x91, struct kvm_cpuid2) +/* Available with KVM_CAP_VAPIC */ +#define KVM_TPR_ACCESS_REPORTING _IOWR(KVMIO, 0x92, struct kvm_tpr_access_ctl) +/* Available with KVM_CAP_VAPIC */ +#define KVM_SET_VAPIC_ADDR _IOW(KVMIO, 0x93, struct kvm_vapic_addr) +/* valid for virtual machine (for floating interrupt)_and_ vcpu */ +#define KVM_S390_INTERRUPT _IOW(KVMIO, 0x94, struct kvm_s390_interrupt) +/* store status for s390 */ +#define KVM_S390_STORE_STATUS_NOADDR (-1ul) +#define KVM_S390_STORE_STATUS_PREFIXED (-2ul) +#define KVM_S390_STORE_STATUS _IOW(KVMIO, 0x95, unsigned long) +/* initial ipl psw for s390 */ +#define KVM_S390_SET_INITIAL_PSW _IOW(KVMIO, 0x96, struct kvm_s390_psw) +/* initial reset for s390 */ +#define KVM_S390_INITIAL_RESET _IO(KVMIO, 0x97) +#define KVM_GET_MP_STATE _IOR(KVMIO, 0x98, struct kvm_mp_state) +#define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state) +/* Available with KVM_CAP_USER_NMI */ +#define KVM_NMI _IO(KVMIO, 0x9a) +/* Available with KVM_CAP_SET_GUEST_DEBUG */ +#define KVM_SET_GUEST_DEBUG _IOW(KVMIO, 0x9b, struct kvm_guest_debug) +/* MCE for x86 */ +#define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, __u64) +#define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, __u64) +#define KVM_X86_SET_MCE _IOW(KVMIO, 0x9e, struct kvm_x86_mce) +/* Available with KVM_CAP_VCPU_EVENTS */ +#define KVM_GET_VCPU_EVENTS _IOR(KVMIO, 0x9f, struct kvm_vcpu_events) +#define KVM_SET_VCPU_EVENTS _IOW(KVMIO, 0xa0, struct kvm_vcpu_events) +/* Available with KVM_CAP_DEBUGREGS */ +#define KVM_GET_DEBUGREGS _IOR(KVMIO, 0xa1, struct kvm_debugregs) +#define KVM_SET_DEBUGREGS _IOW(KVMIO, 0xa2, struct kvm_debugregs) +/* + * vcpu version available with KVM_ENABLE_CAP + * vm version available with KVM_CAP_ENABLE_CAP_VM + */ +#define KVM_ENABLE_CAP _IOW(KVMIO, 0xa3, struct kvm_enable_cap) +/* Available with KVM_CAP_XSAVE */ +#define KVM_GET_XSAVE _IOR(KVMIO, 0xa4, struct kvm_xsave) +#define KVM_SET_XSAVE _IOW(KVMIO, 0xa5, struct kvm_xsave) +/* Available with KVM_CAP_XCRS */ +#define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) +#define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) +/* Available with KVM_CAP_SW_TLB */ +#define KVM_DIRTY_TLB _IOW(KVMIO, 0xaa, struct kvm_dirty_tlb) +/* Available with KVM_CAP_ONE_REG */ +#define KVM_GET_ONE_REG _IOW(KVMIO, 0xab, struct kvm_one_reg) +#define KVM_SET_ONE_REG _IOW(KVMIO, 0xac, struct kvm_one_reg) +/* VM is being stopped by host */ +#define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad) +#define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init) +#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init) +#define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list) +/* Available with KVM_CAP_S390_MEM_OP */ +#define KVM_S390_MEM_OP _IOW(KVMIO, 0xb1, struct kvm_s390_mem_op) +/* Available with KVM_CAP_S390_SKEYS */ +#define KVM_S390_GET_SKEYS _IOW(KVMIO, 0xb2, struct kvm_s390_skeys) +#define KVM_S390_SET_SKEYS _IOW(KVMIO, 0xb3, struct kvm_s390_skeys) +/* Available with KVM_CAP_S390_INJECT_IRQ */ +#define KVM_S390_IRQ _IOW(KVMIO, 0xb4, struct kvm_s390_irq) +/* Available with KVM_CAP_S390_IRQ_STATE */ +#define KVM_S390_SET_IRQ_STATE _IOW(KVMIO, 0xb5, struct kvm_s390_irq_state) +#define KVM_S390_GET_IRQ_STATE _IOW(KVMIO, 0xb6, struct kvm_s390_irq_state) +/* Available with KVM_CAP_X86_SMM */ +#define KVM_SMI _IO(KVMIO, 0xb7) +/* Available with KVM_CAP_S390_CMMA_MIGRATION */ +#define KVM_S390_GET_CMMA_BITS _IOWR(KVMIO, 0xb8, struct kvm_s390_cmma_log) +#define KVM_S390_SET_CMMA_BITS _IOW(KVMIO, 0xb9, struct kvm_s390_cmma_log) + +#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) +#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) +#define KVM_DEV_ASSIGN_MASK_INTX (1 << 2) + +struct kvm_assigned_pci_dev { + __u32 assigned_dev_id; + __u32 busnr; + __u32 devfn; + __u32 flags; + __u32 segnr; + union { + __u32 reserved[11]; + }; +}; + +#define KVM_DEV_IRQ_HOST_INTX (1 << 0) +#define KVM_DEV_IRQ_HOST_MSI (1 << 1) +#define KVM_DEV_IRQ_HOST_MSIX (1 << 2) + +#define KVM_DEV_IRQ_GUEST_INTX (1 << 8) +#define KVM_DEV_IRQ_GUEST_MSI (1 << 9) +#define KVM_DEV_IRQ_GUEST_MSIX (1 << 10) + +#define KVM_DEV_IRQ_HOST_MASK 0x00ff +#define KVM_DEV_IRQ_GUEST_MASK 0xff00 + +struct kvm_assigned_irq { + __u32 assigned_dev_id; + __u32 host_irq; /* ignored (legacy field) */ + __u32 guest_irq; + __u32 flags; + union { + __u32 reserved[12]; + }; +}; + +struct kvm_assigned_msix_nr { + __u32 assigned_dev_id; + __u16 entry_nr; + __u16 padding; +}; + +#define KVM_MAX_MSIX_PER_DEV 256 +struct kvm_assigned_msix_entry { + __u32 assigned_dev_id; + __u32 gsi; + __u16 entry; /* The index of entry in the MSI-X table */ + __u16 padding[3]; +}; + +#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0) +#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1) + +/* Available with KVM_CAP_ARM_USER_IRQ */ + +/* Bits for run->s.regs.device_irq_level */ +#define KVM_ARM_DEV_EL1_VTIMER (1 << 0) +#define KVM_ARM_DEV_EL1_PTIMER (1 << 1) +#define KVM_ARM_DEV_PMU (1 << 2) + +#endif /* __LINUX_KVM_H */ diff --git a/tools/include/uapi/linux/mman.h b/tools/include/uapi/linux/mman.h index 81d8edf11789..bfd5938fede6 100644 --- a/tools/include/uapi/linux/mman.h +++ b/tools/include/uapi/linux/mman.h @@ -1,7 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_LINUX_MMAN_H #define _UAPI_LINUX_MMAN_H -#include +#include +#include #define MREMAP_MAYMOVE 1 #define MREMAP_FIXED 2 @@ -10,4 +12,25 @@ #define OVERCOMMIT_ALWAYS 1 #define OVERCOMMIT_NEVER 2 +/* + * Huge page size encoding when MAP_HUGETLB is specified, and a huge page + * size other than the default is desired. See hugetlb_encode.h. + * All known huge page size encodings are provided here. It is the + * responsibility of the application to know which sizes are supported on + * the running system. See mmap(2) man page for details. + */ +#define MAP_HUGE_SHIFT HUGETLB_FLAG_ENCODE_SHIFT +#define MAP_HUGE_MASK HUGETLB_FLAG_ENCODE_MASK + +#define MAP_HUGE_64KB HUGETLB_FLAG_ENCODE_64KB +#define MAP_HUGE_512KB HUGETLB_FLAG_ENCODE_512KB +#define MAP_HUGE_1MB HUGETLB_FLAG_ENCODE_1MB +#define MAP_HUGE_2MB HUGETLB_FLAG_ENCODE_2MB +#define MAP_HUGE_8MB HUGETLB_FLAG_ENCODE_8MB +#define MAP_HUGE_16MB HUGETLB_FLAG_ENCODE_16MB +#define MAP_HUGE_256MB HUGETLB_FLAG_ENCODE_256MB +#define MAP_HUGE_1GB HUGETLB_FLAG_ENCODE_1GB +#define MAP_HUGE_2GB HUGETLB_FLAG_ENCODE_2GB +#define MAP_HUGE_16GB HUGETLB_FLAG_ENCODE_16GB + #endif /* _UAPI_LINUX_MMAN_H */ diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h index b1c0b187acfe..362493a2f950 100644 --- a/tools/include/uapi/linux/perf_event.h +++ b/tools/include/uapi/linux/perf_event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Performance events: * @@ -139,8 +140,9 @@ enum perf_event_sample_format { PERF_SAMPLE_IDENTIFIER = 1U << 16, PERF_SAMPLE_TRANSACTION = 1U << 17, PERF_SAMPLE_REGS_INTR = 1U << 18, + PERF_SAMPLE_PHYS_ADDR = 1U << 19, - PERF_SAMPLE_MAX = 1U << 19, /* non-ABI */ + PERF_SAMPLE_MAX = 1U << 20, /* non-ABI */ }; /* @@ -174,6 +176,8 @@ enum perf_branch_sample_type_shift { PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT = 14, /* no flags */ PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT = 15, /* no cycles */ + PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT = 16, /* save branch type */ + PERF_SAMPLE_BRANCH_MAX_SHIFT /* non-ABI */ }; @@ -198,9 +202,30 @@ enum perf_branch_sample_type { PERF_SAMPLE_BRANCH_NO_FLAGS = 1U << PERF_SAMPLE_BRANCH_NO_FLAGS_SHIFT, PERF_SAMPLE_BRANCH_NO_CYCLES = 1U << PERF_SAMPLE_BRANCH_NO_CYCLES_SHIFT, + PERF_SAMPLE_BRANCH_TYPE_SAVE = + 1U << PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT, + PERF_SAMPLE_BRANCH_MAX = 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT, }; +/* + * Common flow change classification + */ +enum { + PERF_BR_UNKNOWN = 0, /* unknown */ + PERF_BR_COND = 1, /* conditional */ + PERF_BR_UNCOND = 2, /* unconditional */ + PERF_BR_IND = 3, /* indirect */ + PERF_BR_CALL = 4, /* function call */ + PERF_BR_IND_CALL = 5, /* indirect function call */ + PERF_BR_RET = 6, /* function return */ + PERF_BR_SYSCALL = 7, /* syscall */ + PERF_BR_SYSRET = 8, /* syscall return */ + PERF_BR_COND_CALL = 9, /* conditional function call */ + PERF_BR_COND_RET = 10, /* conditional function return */ + PERF_BR_MAX, +}; + #define PERF_SAMPLE_BRANCH_PLM_ALL \ (PERF_SAMPLE_BRANCH_USER|\ PERF_SAMPLE_BRANCH_KERNEL|\ @@ -791,6 +816,7 @@ enum perf_event_type { * { u64 transaction; } && PERF_SAMPLE_TRANSACTION * { u64 abi; # enum perf_sample_regs_abi * u64 regs[weight(mask)]; } && PERF_SAMPLE_REGS_INTR + * { u64 phys_addr;} && PERF_SAMPLE_PHYS_ADDR * }; */ PERF_RECORD_SAMPLE = 9, @@ -931,14 +957,20 @@ union perf_mem_data_src { mem_snoop:5, /* snoop mode */ mem_lock:2, /* lock instr */ mem_dtlb:7, /* tlb access */ - mem_rsvd:31; + mem_lvl_num:4, /* memory hierarchy level number */ + mem_remote:1, /* remote */ + mem_snoopx:2, /* snoop mode, ext */ + mem_rsvd:24; }; }; #elif defined(__BIG_ENDIAN_BITFIELD) union perf_mem_data_src { __u64 val; struct { - __u64 mem_rsvd:31, + __u64 mem_rsvd:24, + mem_snoopx:2, /* snoop mode, ext */ + mem_remote:1, /* remote */ + mem_lvl_num:4, /* memory hierarchy level number */ mem_dtlb:7, /* tlb access */ mem_lock:2, /* lock instr */ mem_snoop:5, /* snoop mode */ @@ -975,6 +1007,22 @@ union perf_mem_data_src { #define PERF_MEM_LVL_UNC 0x2000 /* Uncached memory */ #define PERF_MEM_LVL_SHIFT 5 +#define PERF_MEM_REMOTE_REMOTE 0x01 /* Remote */ +#define PERF_MEM_REMOTE_SHIFT 37 + +#define PERF_MEM_LVLNUM_L1 0x01 /* L1 */ +#define PERF_MEM_LVLNUM_L2 0x02 /* L2 */ +#define PERF_MEM_LVLNUM_L3 0x03 /* L3 */ +#define PERF_MEM_LVLNUM_L4 0x04 /* L4 */ +/* 5-0xa available */ +#define PERF_MEM_LVLNUM_ANY_CACHE 0x0b /* Any cache */ +#define PERF_MEM_LVLNUM_LFB 0x0c /* LFB */ +#define PERF_MEM_LVLNUM_RAM 0x0d /* RAM */ +#define PERF_MEM_LVLNUM_PMEM 0x0e /* PMEM */ +#define PERF_MEM_LVLNUM_NA 0x0f /* N/A */ + +#define PERF_MEM_LVLNUM_SHIFT 33 + /* snoop mode */ #define PERF_MEM_SNOOP_NA 0x01 /* not available */ #define PERF_MEM_SNOOP_NONE 0x02 /* no snoop */ @@ -983,6 +1031,10 @@ union perf_mem_data_src { #define PERF_MEM_SNOOP_HITM 0x10 /* snoop hit modified */ #define PERF_MEM_SNOOP_SHIFT 19 +#define PERF_MEM_SNOOPX_FWD 0x01 /* forward */ +/* 1 free */ +#define PERF_MEM_SNOOPX_SHIFT 37 + /* locked instruction */ #define PERF_MEM_LOCK_NA 0x01 /* not available */ #define PERF_MEM_LOCK_LOCKED 0x02 /* locked transaction */ @@ -1015,6 +1067,7 @@ union perf_mem_data_src { * in_tx: running in a hardware transaction * abort: aborting a hardware transaction * cycles: cycles from last branch (or 0 if not supported) + * type: branch type */ struct perf_branch_entry { __u64 from; @@ -1024,7 +1077,8 @@ struct perf_branch_entry { in_tx:1, /* in transaction */ abort:1, /* transaction abort */ cycles:16, /* cycle count to last branch */ - reserved:44; + type:4, /* branch type */ + reserved:40; }; #endif /* _UAPI_LINUX_PERF_EVENT_H */ diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h new file mode 100644 index 000000000000..30a9e51bbb1e --- /dev/null +++ b/tools/include/uapi/linux/sched.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_SCHED_H +#define _UAPI_LINUX_SCHED_H + +/* + * cloning flags: + */ +#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */ +#define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define CLONE_FS 0x00000200 /* set if fs info shared between processes */ +#define CLONE_FILES 0x00000400 /* set if open files shared between processes */ +#define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */ +#define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */ +#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */ +#define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */ +#define CLONE_THREAD 0x00010000 /* Same thread group? */ +#define CLONE_NEWNS 0x00020000 /* New mount namespace group */ +#define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */ +#define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */ +#define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */ +#define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */ +#define CLONE_DETACHED 0x00400000 /* Unused, ignored */ +#define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */ +#define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ +#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */ +#define CLONE_NEWUTS 0x04000000 /* New utsname namespace */ +#define CLONE_NEWIPC 0x08000000 /* New ipc namespace */ +#define CLONE_NEWUSER 0x10000000 /* New user namespace */ +#define CLONE_NEWPID 0x20000000 /* New pid namespace */ +#define CLONE_NEWNET 0x40000000 /* New network namespace */ +#define CLONE_IO 0x80000000 /* Clone io context */ + +/* + * Scheduling policies + */ +#define SCHED_NORMAL 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 +#define SCHED_BATCH 3 +/* SCHED_ISO: reserved but not implemented yet */ +#define SCHED_IDLE 5 +#define SCHED_DEADLINE 6 + +/* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ +#define SCHED_RESET_ON_FORK 0x40000000 + +/* + * For the sched_{set,get}attr() calls + */ +#define SCHED_FLAG_RESET_ON_FORK 0x01 +#define SCHED_FLAG_RECLAIM 0x02 + +#endif /* _UAPI_LINUX_SCHED_H */ diff --git a/tools/include/uapi/linux/stat.h b/tools/include/uapi/linux/stat.h index 17b10304c393..7b35e98d3c58 100644 --- a/tools/include/uapi/linux/stat.h +++ b/tools/include/uapi/linux/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_LINUX_STAT_H #define _UAPI_LINUX_STAT_H diff --git a/tools/include/uapi/linux/vhost.h b/tools/include/uapi/linux/vhost.h new file mode 100644 index 000000000000..c51f8e5cc608 --- /dev/null +++ b/tools/include/uapi/linux/vhost.h @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _LINUX_VHOST_H +#define _LINUX_VHOST_H +/* Userspace interface for in-kernel virtio accelerators. */ + +/* vhost is used to reduce the number of system calls involved in virtio. + * + * Existing virtio net code is used in the guest without modification. + * + * This header includes interface used by userspace hypervisor for + * device configuration. + */ + +#include +#include +#include +#include +#include + +struct vhost_vring_state { + unsigned int index; + unsigned int num; +}; + +struct vhost_vring_file { + unsigned int index; + int fd; /* Pass -1 to unbind from file. */ + +}; + +struct vhost_vring_addr { + unsigned int index; + /* Option flags. */ + unsigned int flags; + /* Flag values: */ + /* Whether log address is valid. If set enables logging. */ +#define VHOST_VRING_F_LOG 0 + + /* Start of array of descriptors (virtually contiguous) */ + __u64 desc_user_addr; + /* Used structure address. Must be 32 bit aligned */ + __u64 used_user_addr; + /* Available structure address. Must be 16 bit aligned */ + __u64 avail_user_addr; + /* Logging support. */ + /* Log writes to used structure, at offset calculated from specified + * address. Address must be 32 bit aligned. */ + __u64 log_guest_addr; +}; + +/* no alignment requirement */ +struct vhost_iotlb_msg { + __u64 iova; + __u64 size; + __u64 uaddr; +#define VHOST_ACCESS_RO 0x1 +#define VHOST_ACCESS_WO 0x2 +#define VHOST_ACCESS_RW 0x3 + __u8 perm; +#define VHOST_IOTLB_MISS 1 +#define VHOST_IOTLB_UPDATE 2 +#define VHOST_IOTLB_INVALIDATE 3 +#define VHOST_IOTLB_ACCESS_FAIL 4 + __u8 type; +}; + +#define VHOST_IOTLB_MSG 0x1 + +struct vhost_msg { + int type; + union { + struct vhost_iotlb_msg iotlb; + __u8 padding[64]; + }; +}; + +struct vhost_memory_region { + __u64 guest_phys_addr; + __u64 memory_size; /* bytes */ + __u64 userspace_addr; + __u64 flags_padding; /* No flags are currently specified. */ +}; + +/* All region addresses and sizes must be 4K aligned. */ +#define VHOST_PAGE_SIZE 0x1000 + +struct vhost_memory { + __u32 nregions; + __u32 padding; + struct vhost_memory_region regions[0]; +}; + +/* ioctls */ + +#define VHOST_VIRTIO 0xAF + +/* Features bitmask for forward compatibility. Transport bits are used for + * vhost specific features. */ +#define VHOST_GET_FEATURES _IOR(VHOST_VIRTIO, 0x00, __u64) +#define VHOST_SET_FEATURES _IOW(VHOST_VIRTIO, 0x00, __u64) + +/* Set current process as the (exclusive) owner of this file descriptor. This + * must be called before any other vhost command. Further calls to + * VHOST_OWNER_SET fail until VHOST_OWNER_RESET is called. */ +#define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01) +/* Give up ownership, and reset the device to default values. + * Allows subsequent call to VHOST_OWNER_SET to succeed. */ +#define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02) + +/* Set up/modify memory layout */ +#define VHOST_SET_MEM_TABLE _IOW(VHOST_VIRTIO, 0x03, struct vhost_memory) + +/* Write logging setup. */ +/* Memory writes can optionally be logged by setting bit at an offset + * (calculated from the physical address) from specified log base. + * The bit is set using an atomic 32 bit operation. */ +/* Set base address for logging. */ +#define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64) +/* Specify an eventfd file descriptor to signal on log write. */ +#define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int) + +/* Ring setup. */ +/* Set number of descriptors in ring. This parameter can not + * be modified while ring is running (bound to a device). */ +#define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state) +/* Set addresses for the ring. */ +#define VHOST_SET_VRING_ADDR _IOW(VHOST_VIRTIO, 0x11, struct vhost_vring_addr) +/* Base value where queue looks for available descriptors */ +#define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state) +/* Get accessor: reads index, writes value in num */ +#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state) + +/* Set the vring byte order in num. Valid values are VHOST_VRING_LITTLE_ENDIAN + * or VHOST_VRING_BIG_ENDIAN (other values return -EINVAL). + * The byte order cannot be changed while the device is active: trying to do so + * returns -EBUSY. + * This is a legacy only API that is simply ignored when VIRTIO_F_VERSION_1 is + * set. + * Not all kernel configurations support this ioctl, but all configurations that + * support SET also support GET. + */ +#define VHOST_VRING_LITTLE_ENDIAN 0 +#define VHOST_VRING_BIG_ENDIAN 1 +#define VHOST_SET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x13, struct vhost_vring_state) +#define VHOST_GET_VRING_ENDIAN _IOW(VHOST_VIRTIO, 0x14, struct vhost_vring_state) + +/* The following ioctls use eventfd file descriptors to signal and poll + * for events. */ + +/* Set eventfd to poll for added buffers */ +#define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file) +/* Set eventfd to signal when buffers have beed used */ +#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file) +/* Set eventfd to signal an error */ +#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file) +/* Set busy loop timeout (in us) */ +#define VHOST_SET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x23, \ + struct vhost_vring_state) +/* Get busy loop timeout (in us) */ +#define VHOST_GET_VRING_BUSYLOOP_TIMEOUT _IOW(VHOST_VIRTIO, 0x24, \ + struct vhost_vring_state) + +/* VHOST_NET specific defines */ + +/* Attach virtio net ring to a raw socket, or tap device. + * The socket must be already bound to an ethernet device, this device will be + * used for transmit. Pass fd -1 to unbind from the socket and the transmit + * device. This can be used to stop the ring (e.g. for migration). */ +#define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file) + +/* Feature bits */ +/* Log all write descriptors. Can be changed while device is active. */ +#define VHOST_F_LOG_ALL 26 +/* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */ +#define VHOST_NET_F_VIRTIO_NET_HDR 27 + +/* VHOST_SCSI specific definitions */ + +/* + * Used by QEMU userspace to ensure a consistent vhost-scsi ABI. + * + * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate + + * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage + * ABI Rev 1: January 2013. Ignore vhost_tpgt filed in struct vhost_scsi_target. + * All the targets under vhost_wwpn can be seen and used by guset. + */ + +#define VHOST_SCSI_ABI_VERSION 1 + +struct vhost_scsi_target { + int abi_version; + char vhost_wwpn[224]; /* TRANSPORT_IQN_LEN */ + unsigned short vhost_tpgt; + unsigned short reserved; +}; + +#define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) +#define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) +/* Changing this breaks userspace. */ +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int) +/* Set and get the events missed flag */ +#define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32) +#define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32) + +/* VHOST_VSOCK specific defines */ + +#define VHOST_VSOCK_SET_GUEST_CID _IOW(VHOST_VIRTIO, 0x60, __u64) +#define VHOST_VSOCK_SET_RUNNING _IOW(VHOST_VIRTIO, 0x61, int) + +#endif diff --git a/tools/include/uapi/sound/asound.h b/tools/include/uapi/sound/asound.h new file mode 100644 index 000000000000..c227ccba60ae --- /dev/null +++ b/tools/include/uapi/sound/asound.h @@ -0,0 +1,1027 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * Advanced Linux Sound Architecture - ALSA - Driver + * Copyright (c) 1994-2003 by Jaroslav Kysela , + * Abramo Bagnara + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _UAPI__SOUND_ASOUND_H +#define _UAPI__SOUND_ASOUND_H + +#if defined(__KERNEL__) || defined(__linux__) +#include +#else +#include +#endif + +#ifndef __KERNEL__ +#include +#endif + +/* + * protocol version + */ + +#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor)) +#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff) +#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff) +#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff) +#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) \ + (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || \ + (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && \ + SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion))) + +/**************************************************************************** + * * + * Digital audio interface * + * * + ****************************************************************************/ + +struct snd_aes_iec958 { + unsigned char status[24]; /* AES/IEC958 channel status bits */ + unsigned char subcode[147]; /* AES/IEC958 subcode bits */ + unsigned char pad; /* nothing */ + unsigned char dig_subframe[4]; /* AES/IEC958 subframe bits */ +}; + +/**************************************************************************** + * * + * CEA-861 Audio InfoFrame. Used in HDMI and DisplayPort * + * * + ****************************************************************************/ + +struct snd_cea_861_aud_if { + unsigned char db1_ct_cc; /* coding type and channel count */ + unsigned char db2_sf_ss; /* sample frequency and size */ + unsigned char db3; /* not used, all zeros */ + unsigned char db4_ca; /* channel allocation code */ + unsigned char db5_dminh_lsv; /* downmix inhibit & level-shit values */ +}; + +/**************************************************************************** + * * + * Section for driver hardware dependent interface - /dev/snd/hw? * + * * + ****************************************************************************/ + +#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1) + +enum { + SNDRV_HWDEP_IFACE_OPL2 = 0, + SNDRV_HWDEP_IFACE_OPL3, + SNDRV_HWDEP_IFACE_OPL4, + SNDRV_HWDEP_IFACE_SB16CSP, /* Creative Signal Processor */ + SNDRV_HWDEP_IFACE_EMU10K1, /* FX8010 processor in EMU10K1 chip */ + SNDRV_HWDEP_IFACE_YSS225, /* Yamaha FX processor */ + SNDRV_HWDEP_IFACE_ICS2115, /* Wavetable synth */ + SNDRV_HWDEP_IFACE_SSCAPE, /* Ensoniq SoundScape ISA card (MC68EC000) */ + SNDRV_HWDEP_IFACE_VX, /* Digigram VX cards */ + SNDRV_HWDEP_IFACE_MIXART, /* Digigram miXart cards */ + SNDRV_HWDEP_IFACE_USX2Y, /* Tascam US122, US224 & US428 usb */ + SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, /* EmuX wavetable */ + SNDRV_HWDEP_IFACE_BLUETOOTH, /* Bluetooth audio */ + SNDRV_HWDEP_IFACE_USX2Y_PCM, /* Tascam US122, US224 & US428 rawusb pcm */ + SNDRV_HWDEP_IFACE_PCXHR, /* Digigram PCXHR */ + SNDRV_HWDEP_IFACE_SB_RC, /* SB Extigy/Audigy2NX remote control */ + SNDRV_HWDEP_IFACE_HDA, /* HD-audio */ + SNDRV_HWDEP_IFACE_USB_STREAM, /* direct access to usb stream */ + SNDRV_HWDEP_IFACE_FW_DICE, /* TC DICE FireWire device */ + SNDRV_HWDEP_IFACE_FW_FIREWORKS, /* Echo Audio Fireworks based device */ + SNDRV_HWDEP_IFACE_FW_BEBOB, /* BridgeCo BeBoB based device */ + SNDRV_HWDEP_IFACE_FW_OXFW, /* Oxford OXFW970/971 based device */ + SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ + SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ + SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */ + SNDRV_HWDEP_IFACE_FW_MOTU, /* MOTU FireWire series */ + SNDRV_HWDEP_IFACE_FW_FIREFACE, /* RME Fireface series */ + + /* Don't forget to change the following: */ + SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE +}; + +struct snd_hwdep_info { + unsigned int device; /* WR: device number */ + int card; /* R: card number */ + unsigned char id[64]; /* ID (user selectable) */ + unsigned char name[80]; /* hwdep name */ + int iface; /* hwdep interface */ + unsigned char reserved[64]; /* reserved for future */ +}; + +/* generic DSP loader */ +struct snd_hwdep_dsp_status { + unsigned int version; /* R: driver-specific version */ + unsigned char id[32]; /* R: driver-specific ID string */ + unsigned int num_dsps; /* R: number of DSP images to transfer */ + unsigned int dsp_loaded; /* R: bit flags indicating the loaded DSPs */ + unsigned int chip_ready; /* R: 1 = initialization finished */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +struct snd_hwdep_dsp_image { + unsigned int index; /* W: DSP index */ + unsigned char name[64]; /* W: ID (e.g. file name) */ + unsigned char __user *image; /* W: binary image */ + size_t length; /* W: size of image in bytes */ + unsigned long driver_data; /* W: driver-specific data */ +}; + +#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int) +#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct snd_hwdep_info) +#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status) +#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image) + +/***************************************************************************** + * * + * Digital Audio (PCM) interface - /dev/snd/pcm?? * + * * + *****************************************************************************/ + +#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14) + +typedef unsigned long snd_pcm_uframes_t; +typedef signed long snd_pcm_sframes_t; + +enum { + SNDRV_PCM_CLASS_GENERIC = 0, /* standard mono or stereo device */ + SNDRV_PCM_CLASS_MULTI, /* multichannel device */ + SNDRV_PCM_CLASS_MODEM, /* software modem class */ + SNDRV_PCM_CLASS_DIGITIZER, /* digitizer class */ + /* Don't forget to change the following: */ + SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER, +}; + +enum { + SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */ + SNDRV_PCM_SUBCLASS_MULTI_MIX, /* multichannel subdevices are mixed together */ + /* Don't forget to change the following: */ + SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX, +}; + +enum { + SNDRV_PCM_STREAM_PLAYBACK = 0, + SNDRV_PCM_STREAM_CAPTURE, + SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE, +}; + +typedef int __bitwise snd_pcm_access_t; +#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0) /* interleaved mmap */ +#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1) /* noninterleaved mmap */ +#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2) /* complex mmap */ +#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3) /* readi/writei */ +#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4) /* readn/writen */ +#define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED + +typedef int __bitwise snd_pcm_format_t; +#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0) +#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1) +#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2) +#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3) +#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4) +#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5) +#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6) /* low three bytes */ +#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7) /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8) /* low three bytes */ +#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9) /* low three bytes */ +#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10) +#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11) +#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12) +#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13) +#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */ +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */ +#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20) +#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21) +#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22) +#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23) +#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24) +#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31) +#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40) /* in three bytes */ +#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42) /* in three bytes */ +#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43) /* in three bytes */ +#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44) /* 8 samples in 3 bytes */ +#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45) /* 1 sample in 1 byte */ +#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */ +#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */ +#define SNDRV_PCM_FORMAT_DSD_U8 ((__force snd_pcm_format_t) 48) /* DSD, 1-byte samples DSD (x8) */ +#define SNDRV_PCM_FORMAT_DSD_U16_LE ((__force snd_pcm_format_t) 49) /* DSD, 2-byte samples DSD (x16), little endian */ +#define SNDRV_PCM_FORMAT_DSD_U32_LE ((__force snd_pcm_format_t) 50) /* DSD, 4-byte samples DSD (x32), little endian */ +#define SNDRV_PCM_FORMAT_DSD_U16_BE ((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */ +#define SNDRV_PCM_FORMAT_DSD_U32_BE ((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */ +#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_DSD_U32_BE + +#ifdef SNDRV_LITTLE_ENDIAN +#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_LE +#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_LE +#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_LE +#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_LE +#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_LE +#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_LE +#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE +#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE +#endif +#ifdef SNDRV_BIG_ENDIAN +#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE +#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_BE +#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_BE +#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_BE +#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_BE +#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_BE +#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE +#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE +#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE +#endif + +typedef int __bitwise snd_pcm_subformat_t; +#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0) +#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD + +#define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */ +#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */ +#define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */ +#define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */ +#define SNDRV_PCM_INFO_SYNC_APPLPTR 0x00000020 /* need the explicit sync of appl_ptr update */ +#define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */ +#define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */ +#define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */ +#define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000 /* hardware transfer block of samples */ +#define SNDRV_PCM_INFO_OVERRANGE 0x00020000 /* hardware supports ADC (capture) overrange detection */ +#define SNDRV_PCM_INFO_RESUME 0x00040000 /* hardware supports stream resume after suspend */ +#define SNDRV_PCM_INFO_PAUSE 0x00080000 /* pause ioctl is supported */ +#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */ +#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ +#define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ +#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */ +#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000 /* (Deprecated)has audio wall clock for audio/system time sync */ +#define SNDRV_PCM_INFO_HAS_LINK_ATIME 0x01000000 /* report hardware link audio time, reset on startup */ +#define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000 /* report absolute hardware link audio time, not reset on startup */ +#define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000 /* report estimated link audio time */ +#define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000 /* report synchronized audio/system time */ + +#define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000 /* internal kernel flag - trigger in drain */ +#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */ + + + +typedef int __bitwise snd_pcm_state_t; +#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) /* stream is open */ +#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1) /* stream has a setup */ +#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2) /* stream is ready to start */ +#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3) /* stream is running */ +#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4) /* stream reached an xrun */ +#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5) /* stream is draining */ +#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6) /* stream is paused */ +#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7) /* hardware is suspended */ +#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8) /* hardware is disconnected */ +#define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED + +enum { + SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000, + SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000, + SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000, +}; + +union snd_pcm_sync_id { + unsigned char id[16]; + unsigned short id16[8]; + unsigned int id32[4]; +}; + +struct snd_pcm_info { + unsigned int device; /* RO/WR (control): device number */ + unsigned int subdevice; /* RO/WR (control): subdevice number */ + int stream; /* RO/WR (control): stream direction */ + int card; /* R: card number */ + unsigned char id[64]; /* ID (user selectable) */ + unsigned char name[80]; /* name of this device */ + unsigned char subname[32]; /* subdevice name */ + int dev_class; /* SNDRV_PCM_CLASS_* */ + int dev_subclass; /* SNDRV_PCM_SUBCLASS_* */ + unsigned int subdevices_count; + unsigned int subdevices_avail; + union snd_pcm_sync_id sync; /* hardware synchronization ID */ + unsigned char reserved[64]; /* reserved for future... */ +}; + +typedef int snd_pcm_hw_param_t; +#define SNDRV_PCM_HW_PARAM_ACCESS 0 /* Access type */ +#define SNDRV_PCM_HW_PARAM_FORMAT 1 /* Format */ +#define SNDRV_PCM_HW_PARAM_SUBFORMAT 2 /* Subformat */ +#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS +#define SNDRV_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_SUBFORMAT + +#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS 8 /* Bits per sample */ +#define SNDRV_PCM_HW_PARAM_FRAME_BITS 9 /* Bits per frame */ +#define SNDRV_PCM_HW_PARAM_CHANNELS 10 /* Channels */ +#define SNDRV_PCM_HW_PARAM_RATE 11 /* Approx rate */ +#define SNDRV_PCM_HW_PARAM_PERIOD_TIME 12 /* Approx distance between + * interrupts in us + */ +#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE 13 /* Approx frames between + * interrupts + */ +#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14 /* Approx bytes between + * interrupts + */ +#define SNDRV_PCM_HW_PARAM_PERIODS 15 /* Approx interrupts per + * buffer + */ +#define SNDRV_PCM_HW_PARAM_BUFFER_TIME 16 /* Approx duration of buffer + * in us + */ +#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE 17 /* Size of buffer in frames */ +#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18 /* Size of buffer in bytes */ +#define SNDRV_PCM_HW_PARAM_TICK_TIME 19 /* Approx tick duration in us */ +#define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_SAMPLE_BITS +#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME + +#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */ +#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */ +#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */ + +struct snd_interval { + unsigned int min, max; + unsigned int openmin:1, + openmax:1, + integer:1, + empty:1; +}; + +#define SNDRV_MASK_MAX 256 + +struct snd_mask { + __u32 bits[(SNDRV_MASK_MAX+31)/32]; +}; + +struct snd_pcm_hw_params { + unsigned int flags; + struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - + SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; + struct snd_mask mres[5]; /* reserved masks */ + struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - + SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; + struct snd_interval ires[9]; /* reserved intervals */ + unsigned int rmask; /* W: requested masks */ + unsigned int cmask; /* R: changed masks */ + unsigned int info; /* R: Info flags for returned setup */ + unsigned int msbits; /* R: used most significant bits */ + unsigned int rate_num; /* R: rate numerator */ + unsigned int rate_den; /* R: rate denominator */ + snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */ + unsigned char reserved[64]; /* reserved for future */ +}; + +enum { + SNDRV_PCM_TSTAMP_NONE = 0, + SNDRV_PCM_TSTAMP_ENABLE, + SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE, +}; + +struct snd_pcm_sw_params { + int tstamp_mode; /* timestamp mode */ + unsigned int period_step; + unsigned int sleep_min; /* min ticks to sleep */ + snd_pcm_uframes_t avail_min; /* min avail frames for wakeup */ + snd_pcm_uframes_t xfer_align; /* obsolete: xfer size need to be a multiple */ + snd_pcm_uframes_t start_threshold; /* min hw_avail frames for automatic start */ + snd_pcm_uframes_t stop_threshold; /* min avail frames for automatic stop */ + snd_pcm_uframes_t silence_threshold; /* min distance from noise for silence filling */ + snd_pcm_uframes_t silence_size; /* silence block size */ + snd_pcm_uframes_t boundary; /* pointers wrap point */ + unsigned int proto; /* protocol version */ + unsigned int tstamp_type; /* timestamp type (req. proto >= 2.0.12) */ + unsigned char reserved[56]; /* reserved for future */ +}; + +struct snd_pcm_channel_info { + unsigned int channel; + __kernel_off_t offset; /* mmap offset */ + unsigned int first; /* offset to first sample in bits */ + unsigned int step; /* samples distance in bits */ +}; + +enum { + /* + * first definition for backwards compatibility only, + * maps to wallclock/link time for HDAudio playback and DEFAULT/DMA time for everything else + */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0, + + /* timestamp definitions */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1, /* DMA time, reported as per hw_ptr */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK = 2, /* link time reported by sample or wallclock counter, reset on startup */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3, /* link time reported by sample or wallclock counter, not reset on startup */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4, /* link time estimated indirectly */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5, /* link time synchronized with system time */ + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED +}; + +struct snd_pcm_status { + snd_pcm_state_t state; /* stream state */ + struct timespec trigger_tstamp; /* time when stream was started/stopped/paused */ + struct timespec tstamp; /* reference timestamp */ + snd_pcm_uframes_t appl_ptr; /* appl ptr */ + snd_pcm_uframes_t hw_ptr; /* hw ptr */ + snd_pcm_sframes_t delay; /* current delay in frames */ + snd_pcm_uframes_t avail; /* number of frames available */ + snd_pcm_uframes_t avail_max; /* max frames available on hw since last status */ + snd_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */ + snd_pcm_state_t suspended_state; /* suspended stream state */ + __u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */ + struct timespec audio_tstamp; /* sample counter, wall clock, PHC or on-demand sync'ed */ + struct timespec driver_tstamp; /* useful in case reference system tstamp is reported with delay */ + __u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */ + unsigned char reserved[52-2*sizeof(struct timespec)]; /* must be filled with zero */ +}; + +struct snd_pcm_mmap_status { + snd_pcm_state_t state; /* RO: state - SNDRV_PCM_STATE_XXXX */ + int pad1; /* Needed for 64 bit alignment */ + snd_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ + struct timespec tstamp; /* Timestamp */ + snd_pcm_state_t suspended_state; /* RO: suspended stream state */ + struct timespec audio_tstamp; /* from sample counter or wall clock */ +}; + +struct snd_pcm_mmap_control { + snd_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */ + snd_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */ +}; + +#define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0) /* execute hwsync */ +#define SNDRV_PCM_SYNC_PTR_APPL (1<<1) /* get appl_ptr from driver (r/w op) */ +#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) /* get avail_min from driver */ + +struct snd_pcm_sync_ptr { + unsigned int flags; + union { + struct snd_pcm_mmap_status status; + unsigned char reserved[64]; + } s; + union { + struct snd_pcm_mmap_control control; + unsigned char reserved[64]; + } c; +}; + +struct snd_xferi { + snd_pcm_sframes_t result; + void __user *buf; + snd_pcm_uframes_t frames; +}; + +struct snd_xfern { + snd_pcm_sframes_t result; + void __user * __user *bufs; + snd_pcm_uframes_t frames; +}; + +enum { + SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0, /* gettimeofday equivalent */ + SNDRV_PCM_TSTAMP_TYPE_MONOTONIC, /* posix_clock_monotonic equivalent */ + SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW, /* monotonic_raw (no NTP) */ + SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW, +}; + +/* channel positions */ +enum { + SNDRV_CHMAP_UNKNOWN = 0, + SNDRV_CHMAP_NA, /* N/A, silent */ + SNDRV_CHMAP_MONO, /* mono stream */ + /* this follows the alsa-lib mixer channel value + 3 */ + SNDRV_CHMAP_FL, /* front left */ + SNDRV_CHMAP_FR, /* front right */ + SNDRV_CHMAP_RL, /* rear left */ + SNDRV_CHMAP_RR, /* rear right */ + SNDRV_CHMAP_FC, /* front center */ + SNDRV_CHMAP_LFE, /* LFE */ + SNDRV_CHMAP_SL, /* side left */ + SNDRV_CHMAP_SR, /* side right */ + SNDRV_CHMAP_RC, /* rear center */ + /* new definitions */ + SNDRV_CHMAP_FLC, /* front left center */ + SNDRV_CHMAP_FRC, /* front right center */ + SNDRV_CHMAP_RLC, /* rear left center */ + SNDRV_CHMAP_RRC, /* rear right center */ + SNDRV_CHMAP_FLW, /* front left wide */ + SNDRV_CHMAP_FRW, /* front right wide */ + SNDRV_CHMAP_FLH, /* front left high */ + SNDRV_CHMAP_FCH, /* front center high */ + SNDRV_CHMAP_FRH, /* front right high */ + SNDRV_CHMAP_TC, /* top center */ + SNDRV_CHMAP_TFL, /* top front left */ + SNDRV_CHMAP_TFR, /* top front right */ + SNDRV_CHMAP_TFC, /* top front center */ + SNDRV_CHMAP_TRL, /* top rear left */ + SNDRV_CHMAP_TRR, /* top rear right */ + SNDRV_CHMAP_TRC, /* top rear center */ + /* new definitions for UAC2 */ + SNDRV_CHMAP_TFLC, /* top front left center */ + SNDRV_CHMAP_TFRC, /* top front right center */ + SNDRV_CHMAP_TSL, /* top side left */ + SNDRV_CHMAP_TSR, /* top side right */ + SNDRV_CHMAP_LLFE, /* left LFE */ + SNDRV_CHMAP_RLFE, /* right LFE */ + SNDRV_CHMAP_BC, /* bottom center */ + SNDRV_CHMAP_BLC, /* bottom left center */ + SNDRV_CHMAP_BRC, /* bottom right center */ + SNDRV_CHMAP_LAST = SNDRV_CHMAP_BRC, +}; + +#define SNDRV_CHMAP_POSITION_MASK 0xffff +#define SNDRV_CHMAP_PHASE_INVERSE (0x01 << 16) +#define SNDRV_CHMAP_DRIVER_SPEC (0x02 << 16) + +#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int) +#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info) +#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) +#define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int) +#define SNDRV_PCM_IOCTL_USER_PVERSION _IOW('A', 0x04, int) +#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params) +#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params) +#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12) +#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct snd_pcm_sw_params) +#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status) +#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t) +#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22) +#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr) +#define SNDRV_PCM_IOCTL_STATUS_EXT _IOWR('A', 0x24, struct snd_pcm_status) +#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info) +#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40) +#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41) +#define SNDRV_PCM_IOCTL_START _IO('A', 0x42) +#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43) +#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44) +#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int) +#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, snd_pcm_uframes_t) +#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47) +#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48) +#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, snd_pcm_uframes_t) +#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi) +#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi) +#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct snd_xfern) +#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern) +#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int) +#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61) + +/***************************************************************************** + * * + * MIDI v1.0 interface * + * * + *****************************************************************************/ + +/* + * Raw MIDI section - /dev/snd/midi?? + */ + +#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0) + +enum { + SNDRV_RAWMIDI_STREAM_OUTPUT = 0, + SNDRV_RAWMIDI_STREAM_INPUT, + SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT, +}; + +#define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001 +#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002 +#define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004 + +struct snd_rawmidi_info { + unsigned int device; /* RO/WR (control): device number */ + unsigned int subdevice; /* RO/WR (control): subdevice number */ + int stream; /* WR: stream */ + int card; /* R: card number */ + unsigned int flags; /* SNDRV_RAWMIDI_INFO_XXXX */ + unsigned char id[64]; /* ID (user selectable) */ + unsigned char name[80]; /* name of device */ + unsigned char subname[32]; /* name of active or selected subdevice */ + unsigned int subdevices_count; + unsigned int subdevices_avail; + unsigned char reserved[64]; /* reserved for future use */ +}; + +struct snd_rawmidi_params { + int stream; + size_t buffer_size; /* queue size in bytes */ + size_t avail_min; /* minimum avail bytes for wakeup */ + unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +struct snd_rawmidi_status { + int stream; + struct timespec tstamp; /* Timestamp */ + size_t avail; /* available bytes */ + size_t xruns; /* count of overruns since last status (in bytes) */ + unsigned char reserved[16]; /* reserved for future use */ +}; + +#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) +#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) +#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params) +#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) +#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) +#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int) + +/* + * Timer section - /dev/snd/timer + */ + +#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6) + +enum { + SNDRV_TIMER_CLASS_NONE = -1, + SNDRV_TIMER_CLASS_SLAVE = 0, + SNDRV_TIMER_CLASS_GLOBAL, + SNDRV_TIMER_CLASS_CARD, + SNDRV_TIMER_CLASS_PCM, + SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM, +}; + +/* slave timer classes */ +enum { + SNDRV_TIMER_SCLASS_NONE = 0, + SNDRV_TIMER_SCLASS_APPLICATION, + SNDRV_TIMER_SCLASS_SEQUENCER, /* alias */ + SNDRV_TIMER_SCLASS_OSS_SEQUENCER, /* alias */ + SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER, +}; + +/* global timers (device member) */ +#define SNDRV_TIMER_GLOBAL_SYSTEM 0 +#define SNDRV_TIMER_GLOBAL_RTC 1 /* unused */ +#define SNDRV_TIMER_GLOBAL_HPET 2 +#define SNDRV_TIMER_GLOBAL_HRTIMER 3 + +/* info flags */ +#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */ + +struct snd_timer_id { + int dev_class; + int dev_sclass; + int card; + int device; + int subdevice; +}; + +struct snd_timer_ginfo { + struct snd_timer_id tid; /* requested timer ID */ + unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ + int card; /* card number */ + unsigned char id[64]; /* timer identification */ + unsigned char name[80]; /* timer name */ + unsigned long reserved0; /* reserved for future use */ + unsigned long resolution; /* average period resolution in ns */ + unsigned long resolution_min; /* minimal period resolution in ns */ + unsigned long resolution_max; /* maximal period resolution in ns */ + unsigned int clients; /* active timer clients */ + unsigned char reserved[32]; +}; + +struct snd_timer_gparams { + struct snd_timer_id tid; /* requested timer ID */ + unsigned long period_num; /* requested precise period duration (in seconds) - numerator */ + unsigned long period_den; /* requested precise period duration (in seconds) - denominator */ + unsigned char reserved[32]; +}; + +struct snd_timer_gstatus { + struct snd_timer_id tid; /* requested timer ID */ + unsigned long resolution; /* current period resolution in ns */ + unsigned long resolution_num; /* precise current period resolution (in seconds) - numerator */ + unsigned long resolution_den; /* precise current period resolution (in seconds) - denominator */ + unsigned char reserved[32]; +}; + +struct snd_timer_select { + struct snd_timer_id id; /* bind to timer ID */ + unsigned char reserved[32]; /* reserved */ +}; + +struct snd_timer_info { + unsigned int flags; /* timer flags - SNDRV_TIMER_FLG_* */ + int card; /* card number */ + unsigned char id[64]; /* timer identificator */ + unsigned char name[80]; /* timer name */ + unsigned long reserved0; /* reserved for future use */ + unsigned long resolution; /* average period resolution in ns */ + unsigned char reserved[64]; /* reserved */ +}; + +#define SNDRV_TIMER_PSFLG_AUTO (1<<0) /* auto start, otherwise one-shot */ +#define SNDRV_TIMER_PSFLG_EXCLUSIVE (1<<1) /* exclusive use, precise start/stop/pause/continue */ +#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2) /* write early event to the poll queue */ + +struct snd_timer_params { + unsigned int flags; /* flags - SNDRV_MIXER_PSFLG_* */ + unsigned int ticks; /* requested resolution in ticks */ + unsigned int queue_size; /* total size of queue (32-1024) */ + unsigned int reserved0; /* reserved, was: failure locations */ + unsigned int filter; /* event filter (bitmask of SNDRV_TIMER_EVENT_*) */ + unsigned char reserved[60]; /* reserved */ +}; + +struct snd_timer_status { + struct timespec tstamp; /* Timestamp - last update */ + unsigned int resolution; /* current period resolution in ns */ + unsigned int lost; /* counter of master tick lost */ + unsigned int overrun; /* count of read queue overruns */ + unsigned int queue; /* used queue size */ + unsigned char reserved[64]; /* reserved */ +}; + +#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) +#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id) +#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int) +#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo) +#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams) +#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus) +#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct snd_timer_select) +#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info) +#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct snd_timer_params) +#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct snd_timer_status) +/* The following four ioctls are changed since 1.0.9 due to confliction */ +#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0) +#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1) +#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) +#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) + +struct snd_timer_read { + unsigned int resolution; + unsigned int ticks; +}; + +enum { + SNDRV_TIMER_EVENT_RESOLUTION = 0, /* val = resolution in ns */ + SNDRV_TIMER_EVENT_TICK, /* val = ticks */ + SNDRV_TIMER_EVENT_START, /* val = resolution in ns */ + SNDRV_TIMER_EVENT_STOP, /* val = 0 */ + SNDRV_TIMER_EVENT_CONTINUE, /* val = resolution in ns */ + SNDRV_TIMER_EVENT_PAUSE, /* val = 0 */ + SNDRV_TIMER_EVENT_EARLY, /* val = 0, early event */ + SNDRV_TIMER_EVENT_SUSPEND, /* val = 0 */ + SNDRV_TIMER_EVENT_RESUME, /* val = resolution in ns */ + /* master timer events for slave timer instances */ + SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10, + SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10, + SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10, + SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10, + SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10, + SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10, +}; + +struct snd_timer_tread { + int event; + struct timespec tstamp; + unsigned int val; +}; + +/**************************************************************************** + * * + * Section for driver control interface - /dev/snd/control? * + * * + ****************************************************************************/ + +#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) + +struct snd_ctl_card_info { + int card; /* card number */ + int pad; /* reserved for future (was type) */ + unsigned char id[16]; /* ID of card (user selectable) */ + unsigned char driver[16]; /* Driver name */ + unsigned char name[32]; /* Short name of soundcard */ + unsigned char longname[80]; /* name + info text about soundcard */ + unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */ + unsigned char mixername[80]; /* visual mixer identification */ + unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */ +}; + +typedef int __bitwise snd_ctl_elem_type_t; +#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0) /* invalid */ +#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ +#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ +#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3) /* enumerated type */ +#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4) /* byte array */ +#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */ +#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */ +#define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64 + +typedef int __bitwise snd_ctl_elem_iface_t; +#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) /* global control */ +#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */ +#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */ +#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3) /* PCM device */ +#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */ +#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5) /* timer device */ +#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6) /* sequencer client */ +#define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER + +#define SNDRV_CTL_ELEM_ACCESS_READ (1<<0) +#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1) +#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE) +#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */ +#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<3) /* when was control changed */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4) /* TLV read is possible */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5) /* TLV write is possible */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) +#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND (1<<6) /* TLV command is possible */ +#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8) /* control does actually nothing, but may be updated */ +#define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9) /* write lock */ +#define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) /* write lock owner */ +#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1<<28) /* kernel use a TLV callback */ +#define SNDRV_CTL_ELEM_ACCESS_USER (1<<29) /* user space element */ +/* bits 30 and 31 are obsoleted (for indirect access) */ + +/* for further details see the ACPI and PCI power management specification */ +#define SNDRV_CTL_POWER_D0 0x0000 /* full On */ +#define SNDRV_CTL_POWER_D1 0x0100 /* partial On */ +#define SNDRV_CTL_POWER_D2 0x0200 /* partial On */ +#define SNDRV_CTL_POWER_D3 0x0300 /* Off */ +#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000) /* Off, with power */ +#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001) /* Off, without power */ + +#define SNDRV_CTL_ELEM_ID_NAME_MAXLEN 44 + +struct snd_ctl_elem_id { + unsigned int numid; /* numeric identifier, zero = invalid */ + snd_ctl_elem_iface_t iface; /* interface identifier */ + unsigned int device; /* device/client number */ + unsigned int subdevice; /* subdevice (substream) number */ + unsigned char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* ASCII name of item */ + unsigned int index; /* index of item */ +}; + +struct snd_ctl_elem_list { + unsigned int offset; /* W: first element ID to get */ + unsigned int space; /* W: count of element IDs to get */ + unsigned int used; /* R: count of element IDs set */ + unsigned int count; /* R: count of all elements */ + struct snd_ctl_elem_id __user *pids; /* R: IDs */ + unsigned char reserved[50]; +}; + +struct snd_ctl_elem_info { + struct snd_ctl_elem_id id; /* W: element ID */ + snd_ctl_elem_type_t type; /* R: value type - SNDRV_CTL_ELEM_TYPE_* */ + unsigned int access; /* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */ + unsigned int count; /* count of values */ + __kernel_pid_t owner; /* owner's PID of this control */ + union { + struct { + long min; /* R: minimum value */ + long max; /* R: maximum value */ + long step; /* R: step (0 variable) */ + } integer; + struct { + long long min; /* R: minimum value */ + long long max; /* R: maximum value */ + long long step; /* R: step (0 variable) */ + } integer64; + struct { + unsigned int items; /* R: number of items */ + unsigned int item; /* W: item number */ + char name[64]; /* R: value name */ + __u64 names_ptr; /* W: names list (ELEM_ADD only) */ + unsigned int names_length; + } enumerated; + unsigned char reserved[128]; + } value; + union { + unsigned short d[4]; /* dimensions */ + unsigned short *d_ptr; /* indirect - obsoleted */ + } dimen; + unsigned char reserved[64-4*sizeof(unsigned short)]; +}; + +struct snd_ctl_elem_value { + struct snd_ctl_elem_id id; /* W: element ID */ + unsigned int indirect: 1; /* W: indirect access - obsoleted */ + union { + union { + long value[128]; + long *value_ptr; /* obsoleted */ + } integer; + union { + long long value[64]; + long long *value_ptr; /* obsoleted */ + } integer64; + union { + unsigned int item[128]; + unsigned int *item_ptr; /* obsoleted */ + } enumerated; + union { + unsigned char data[512]; + unsigned char *data_ptr; /* obsoleted */ + } bytes; + struct snd_aes_iec958 iec958; + } value; /* RO */ + struct timespec tstamp; + unsigned char reserved[128-sizeof(struct timespec)]; +}; + +struct snd_ctl_tlv { + unsigned int numid; /* control element numeric identification */ + unsigned int length; /* in bytes aligned to 4 */ + unsigned int tlv[0]; /* first TLV */ +}; + +#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) +#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info) +#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list) +#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info) +#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value) +#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct snd_ctl_elem_value) +#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id) +#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct snd_ctl_elem_id) +#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int) +#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct snd_ctl_elem_info) +#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info) +#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct snd_ctl_elem_id) +#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct snd_ctl_tlv) +#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct snd_ctl_tlv) +#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv) +#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int) +#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct snd_hwdep_info) +#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int) +#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info) +#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int) +#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int) +#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info) +#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) +#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) +#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) + +/* + * Read interface. + */ + +enum sndrv_ctl_event_type { + SNDRV_CTL_EVENT_ELEM = 0, + SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM, +}; + +#define SNDRV_CTL_EVENT_MASK_VALUE (1<<0) /* element value was changed */ +#define SNDRV_CTL_EVENT_MASK_INFO (1<<1) /* element info was changed */ +#define SNDRV_CTL_EVENT_MASK_ADD (1<<2) /* element was added */ +#define SNDRV_CTL_EVENT_MASK_TLV (1<<3) /* element TLV tree was changed */ +#define SNDRV_CTL_EVENT_MASK_REMOVE (~0U) /* element was removed */ + +struct snd_ctl_event { + int type; /* event type - SNDRV_CTL_EVENT_* */ + union { + struct { + unsigned int mask; + struct snd_ctl_elem_id id; + } elem; + unsigned char data8[60]; + } data; +}; + +/* + * Control names + */ + +#define SNDRV_CTL_NAME_NONE "" +#define SNDRV_CTL_NAME_PLAYBACK "Playback " +#define SNDRV_CTL_NAME_CAPTURE "Capture " + +#define SNDRV_CTL_NAME_IEC958_NONE "" +#define SNDRV_CTL_NAME_IEC958_SWITCH "Switch" +#define SNDRV_CTL_NAME_IEC958_VOLUME "Volume" +#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default" +#define SNDRV_CTL_NAME_IEC958_MASK "Mask" +#define SNDRV_CTL_NAME_IEC958_CON_MASK "Con Mask" +#define SNDRV_CTL_NAME_IEC958_PRO_MASK "Pro Mask" +#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream" +#define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what + +#endif /* _UAPI__SOUND_ASOUND_H */ diff --git a/tools/kvm/kvm_stat/Makefile b/tools/kvm/kvm_stat/Makefile index 5b1cba57e3b3..c3e36c60d477 100644 --- a/tools/kvm/kvm_stat/Makefile +++ b/tools/kvm/kvm_stat/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 include ../../scripts/Makefile.include include ../../scripts/utilities.mak BINDIR=usr/bin diff --git a/tools/laptop/dslm/Makefile b/tools/laptop/dslm/Makefile index ff613b31730b..90f512c4e2bb 100644 --- a/tools/laptop/dslm/Makefile +++ b/tools/laptop/dslm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include diff --git a/tools/laptop/freefall/Makefile b/tools/laptop/freefall/Makefile index 48c6c9328419..5f758c489a20 100644 --- a/tools/laptop/freefall/Makefile +++ b/tools/laptop/freefall/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 PREFIX ?= /usr SBINDIR ?= sbin INSTALL ?= install diff --git a/tools/leds/Makefile b/tools/leds/Makefile index 078b666fd78b..c379af003807 100644 --- a/tools/leds/Makefile +++ b/tools/leds/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for LEDs tools CC = $(CROSS_COMPILE)gcc diff --git a/tools/leds/led_hw_brightness_mon.c b/tools/leds/led_hw_brightness_mon.c index 64642ccfe442..eb65ae988839 100644 --- a/tools/leds/led_hw_brightness_mon.c +++ b/tools/leds/led_hw_brightness_mon.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * led_hw_brightness_mon.c * diff --git a/tools/leds/uledmon.c b/tools/leds/uledmon.c index 25cbc7acf50a..c15a39c1f271 100644 --- a/tools/leds/uledmon.c +++ b/tools/leds/uledmon.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * uledmon.c * diff --git a/tools/lguest/.gitignore b/tools/lguest/.gitignore deleted file mode 100644 index 8d9a8383a52e..000000000000 --- a/tools/lguest/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -lguest -include diff --git a/tools/lguest/Makefile b/tools/lguest/Makefile deleted file mode 100644 index d04599a79802..000000000000 --- a/tools/lguest/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# This creates the demonstration utility "lguest" which runs a Linux guest. -CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE -Iinclude - -all: lguest - -include/linux/virtio_types.h: ../../include/uapi/linux/virtio_types.h - mkdir -p include/linux 2>&1 || true - ln -sf ../../../../include/uapi/linux/virtio_types.h $@ - -lguest: include/linux/virtio_types.h - -clean: - rm -f lguest - rm -rf include diff --git a/tools/lguest/extract b/tools/lguest/extract deleted file mode 100644 index 7730bb6e4b94..000000000000 --- a/tools/lguest/extract +++ /dev/null @@ -1,58 +0,0 @@ -#! /bin/sh - -set -e - -PREFIX=$1 -shift - -trap 'rm -r $TMPDIR' 0 -TMPDIR=`mktemp -d` - -exec 3>/dev/null -for f; do - while IFS=" -" read -r LINE; do - case "$LINE" in - *$PREFIX:[0-9]*:\**) - NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"` - if [ -f $TMPDIR/$NUM ]; then - echo "$TMPDIR/$NUM already exits prior to $f" - exit 1 - fi - exec 3>>$TMPDIR/$NUM - echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM - /bin/echo "$LINE" | sed -e "s/$PREFIX:[0-9]*//" -e "s/:\*/*/" >&3 - ;; - *$PREFIX:[0-9]*) - NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"` - if [ -f $TMPDIR/$NUM ]; then - echo "$TMPDIR/$NUM already exits prior to $f" - exit 1 - fi - exec 3>>$TMPDIR/$NUM - echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM - /bin/echo "$LINE" | sed "s/$PREFIX:[0-9]*//" >&3 - ;; - *:\**) - /bin/echo "$LINE" | sed -e "s/:\*/*/" -e "s,/\*\*/,," >&3 - echo >&3 - exec 3>/dev/null - ;; - *) - /bin/echo "$LINE" >&3 - ;; - esac - done < $f - echo >&3 - exec 3>/dev/null -done - -LASTFILE="" -for f in $TMPDIR/*; do - if [ "$LASTFILE" != $(cat $TMPDIR/.$(basename $f) ) ]; then - LASTFILE=$(cat $TMPDIR/.$(basename $f) ) - echo "[ $LASTFILE ]" - fi - cat $f -done - diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c deleted file mode 100644 index 897cd6f3f687..000000000000 --- a/tools/lguest/lguest.c +++ /dev/null @@ -1,3420 +0,0 @@ -/*P:100 - * This is the Launcher code, a simple program which lays out the "physical" - * memory for the new Guest by mapping the kernel image and the virtual - * devices, then opens /dev/lguest to tell the kernel about the Guest and - * control it. -:*/ -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef VIRTIO_F_ANY_LAYOUT -#define VIRTIO_F_ANY_LAYOUT 27 -#endif - -/*L:110 - * We can ignore the 43 include files we need for this program, but I do want - * to draw attention to the use of kernel-style types. - * - * As Linus said, "C is a Spartan language, and so should your naming be." I - * like these abbreviations, so we define them here. Note that u64 is always - * unsigned long long, which works on all Linux systems: this means that we can - * use %llu in printf for any u64. - */ -typedef unsigned long long u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; -/*:*/ - -#define VIRTIO_CONFIG_NO_LEGACY -#define VIRTIO_PCI_NO_LEGACY -#define VIRTIO_BLK_NO_LEGACY -#define VIRTIO_NET_NO_LEGACY - -/* Use in-kernel ones, which defines VIRTIO_F_VERSION_1 */ -#include "../../include/uapi/linux/virtio_config.h" -#include "../../include/uapi/linux/virtio_net.h" -#include "../../include/uapi/linux/virtio_blk.h" -#include "../../include/uapi/linux/virtio_console.h" -#include "../../include/uapi/linux/virtio_rng.h" -#include -#include "../../include/uapi/linux/virtio_pci.h" -#include -#include "../../include/linux/lguest_launcher.h" - -#define BRIDGE_PFX "bridge:" -#ifndef SIOCBRADDIF -#define SIOCBRADDIF 0x89a2 /* add interface to bridge */ -#endif -/* We can have up to 256 pages for devices. */ -#define DEVICE_PAGES 256 -/* This will occupy 3 pages: it must be a power of 2. */ -#define VIRTQUEUE_NUM 256 - -/*L:120 - * verbose is both a global flag and a macro. The C preprocessor allows - * this, and although I wouldn't recommend it, it works quite nicely here. - */ -static bool verbose; -#define verbose(args...) \ - do { if (verbose) printf(args); } while(0) -/*:*/ - -/* The pointer to the start of guest memory. */ -static void *guest_base; -/* The maximum guest physical address allowed, and maximum possible. */ -static unsigned long guest_limit, guest_max, guest_mmio; -/* The /dev/lguest file descriptor. */ -static int lguest_fd; - -/* a per-cpu variable indicating whose vcpu is currently running */ -static unsigned int __thread cpu_id; - -/* 5 bit device number in the PCI_CONFIG_ADDR => 32 only */ -#define MAX_PCI_DEVICES 32 - -/* This is our list of devices. */ -struct device_list { - /* Counter to assign interrupt numbers. */ - unsigned int next_irq; - - /* Counter to print out convenient device numbers. */ - unsigned int device_num; - - /* PCI devices. */ - struct device *pci[MAX_PCI_DEVICES]; -}; - -/* The list of Guest devices, based on command line arguments. */ -static struct device_list devices; - -/* - * Just like struct virtio_pci_cfg_cap in uapi/linux/virtio_pci.h, - * but uses a u32 explicitly for the data. - */ -struct virtio_pci_cfg_cap_u32 { - struct virtio_pci_cap cap; - u32 pci_cfg_data; /* Data for BAR access. */ -}; - -struct virtio_pci_mmio { - struct virtio_pci_common_cfg cfg; - u16 notify; - u8 isr; - u8 padding; - /* Device-specific configuration follows this. */ -}; - -/* This is the layout (little-endian) of the PCI config space. */ -struct pci_config { - u16 vendor_id, device_id; - u16 command, status; - u8 revid, prog_if, subclass, class; - u8 cacheline_size, lat_timer, header_type, bist; - u32 bar[6]; - u32 cardbus_cis_ptr; - u16 subsystem_vendor_id, subsystem_device_id; - u32 expansion_rom_addr; - u8 capabilities, reserved1[3]; - u32 reserved2; - u8 irq_line, irq_pin, min_grant, max_latency; - - /* Now, this is the linked capability list. */ - struct virtio_pci_cap common; - struct virtio_pci_notify_cap notify; - struct virtio_pci_cap isr; - struct virtio_pci_cap device; - struct virtio_pci_cfg_cap_u32 cfg_access; -}; - -/* The device structure describes a single device. */ -struct device { - /* The name of this device, for --verbose. */ - const char *name; - - /* Any queues attached to this device */ - struct virtqueue *vq; - - /* Is it operational */ - bool running; - - /* Has it written FEATURES_OK but not re-checked it? */ - bool wrote_features_ok; - - /* PCI configuration */ - union { - struct pci_config config; - u32 config_words[sizeof(struct pci_config) / sizeof(u32)]; - }; - - /* Features we offer, and those accepted. */ - u64 features, features_accepted; - - /* Device-specific config hangs off the end of this. */ - struct virtio_pci_mmio *mmio; - - /* PCI MMIO resources (all in BAR0) */ - size_t mmio_size; - u32 mmio_addr; - - /* Device-specific data. */ - void *priv; -}; - -/* The virtqueue structure describes a queue attached to a device. */ -struct virtqueue { - struct virtqueue *next; - - /* Which device owns me. */ - struct device *dev; - - /* Name for printing errors. */ - const char *name; - - /* The actual ring of buffers. */ - struct vring vring; - - /* The information about this virtqueue (we only use queue_size on) */ - struct virtio_pci_common_cfg pci_config; - - /* Last available index we saw. */ - u16 last_avail_idx; - - /* How many are used since we sent last irq? */ - unsigned int pending_used; - - /* Eventfd where Guest notifications arrive. */ - int eventfd; - - /* Function for the thread which is servicing this virtqueue. */ - void (*service)(struct virtqueue *vq); - pid_t thread; -}; - -/* Remember the arguments to the program so we can "reboot" */ -static char **main_args; - -/* The original tty settings to restore on exit. */ -static struct termios orig_term; - -/* - * We have to be careful with barriers: our devices are all run in separate - * threads and so we need to make sure that changes visible to the Guest happen - * in precise order. - */ -#define wmb() __asm__ __volatile__("" : : : "memory") -#define rmb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory") -#define mb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory") - -/* Wrapper for the last available index. Makes it easier to change. */ -#define lg_last_avail(vq) ((vq)->last_avail_idx) - -/* - * The virtio configuration space is defined to be little-endian. x86 is - * little-endian too, but it's nice to be explicit so we have these helpers. - */ -#define cpu_to_le16(v16) (v16) -#define cpu_to_le32(v32) (v32) -#define cpu_to_le64(v64) (v64) -#define le16_to_cpu(v16) (v16) -#define le32_to_cpu(v32) (v32) -#define le64_to_cpu(v64) (v64) - -/* - * A real device would ignore weird/non-compliant driver behaviour. We - * stop and flag it, to help debugging Linux problems. - */ -#define bad_driver(d, fmt, ...) \ - errx(1, "%s: bad driver: " fmt, (d)->name, ## __VA_ARGS__) -#define bad_driver_vq(vq, fmt, ...) \ - errx(1, "%s vq %s: bad driver: " fmt, (vq)->dev->name, \ - vq->name, ## __VA_ARGS__) - -/* Is this iovec empty? */ -static bool iov_empty(const struct iovec iov[], unsigned int num_iov) -{ - unsigned int i; - - for (i = 0; i < num_iov; i++) - if (iov[i].iov_len) - return false; - return true; -} - -/* Take len bytes from the front of this iovec. */ -static void iov_consume(struct device *d, - struct iovec iov[], unsigned num_iov, - void *dest, unsigned len) -{ - unsigned int i; - - for (i = 0; i < num_iov; i++) { - unsigned int used; - - used = iov[i].iov_len < len ? iov[i].iov_len : len; - if (dest) { - memcpy(dest, iov[i].iov_base, used); - dest += used; - } - iov[i].iov_base += used; - iov[i].iov_len -= used; - len -= used; - } - if (len != 0) - bad_driver(d, "iovec too short!"); -} - -/*L:100 - * The Launcher code itself takes us out into userspace, that scary place where - * pointers run wild and free! Unfortunately, like most userspace programs, - * it's quite boring (which is why everyone likes to hack on the kernel!). - * Perhaps if you make up an Lguest Drinking Game at this point, it will get - * you through this section. Or, maybe not. - * - * The Launcher sets up a big chunk of memory to be the Guest's "physical" - * memory and stores it in "guest_base". In other words, Guest physical == - * Launcher virtual with an offset. - * - * This can be tough to get your head around, but usually it just means that we - * use these trivial conversion functions when the Guest gives us its - * "physical" addresses: - */ -static void *from_guest_phys(unsigned long addr) -{ - return guest_base + addr; -} - -static unsigned long to_guest_phys(const void *addr) -{ - return (addr - guest_base); -} - -/*L:130 - * Loading the Kernel. - * - * We start with couple of simple helper routines. open_or_die() avoids - * error-checking code cluttering the callers: - */ -static int open_or_die(const char *name, int flags) -{ - int fd = open(name, flags); - if (fd < 0) - err(1, "Failed to open %s", name); - return fd; -} - -/* map_zeroed_pages() takes a number of pages. */ -static void *map_zeroed_pages(unsigned int num) -{ - int fd = open_or_die("/dev/zero", O_RDONLY); - void *addr; - - /* - * We use a private mapping (ie. if we write to the page, it will be - * copied). We allocate an extra two pages PROT_NONE to act as guard - * pages against read/write attempts that exceed allocated space. - */ - addr = mmap(NULL, getpagesize() * (num+2), - PROT_NONE, MAP_PRIVATE, fd, 0); - - if (addr == MAP_FAILED) - err(1, "Mmapping %u pages of /dev/zero", num); - - if (mprotect(addr + getpagesize(), getpagesize() * num, - PROT_READ|PROT_WRITE) == -1) - err(1, "mprotect rw %u pages failed", num); - - /* - * One neat mmap feature is that you can close the fd, and it - * stays mapped. - */ - close(fd); - - /* Return address after PROT_NONE page */ - return addr + getpagesize(); -} - -/* Get some bytes which won't be mapped into the guest. */ -static unsigned long get_mmio_region(size_t size) -{ - unsigned long addr = guest_mmio; - size_t i; - - if (!size) - return addr; - - /* Size has to be a power of 2 (and multiple of 16) */ - for (i = 1; i < size; i <<= 1); - - guest_mmio += i; - - return addr; -} - -/* - * This routine is used to load the kernel or initrd. It tries mmap, but if - * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries), - * it falls back to reading the memory in. - */ -static void map_at(int fd, void *addr, unsigned long offset, unsigned long len) -{ - ssize_t r; - - /* - * We map writable even though for some segments are marked read-only. - * The kernel really wants to be writable: it patches its own - * instructions. - * - * MAP_PRIVATE means that the page won't be copied until a write is - * done to it. This allows us to share untouched memory between - * Guests. - */ - if (mmap(addr, len, PROT_READ|PROT_WRITE, - MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) - return; - - /* pread does a seek and a read in one shot: saves a few lines. */ - r = pread(fd, addr, len, offset); - if (r != len) - err(1, "Reading offset %lu len %lu gave %zi", offset, len, r); -} - -/* - * This routine takes an open vmlinux image, which is in ELF, and maps it into - * the Guest memory. ELF = Embedded Linking Format, which is the format used - * by all modern binaries on Linux including the kernel. - * - * The ELF headers give *two* addresses: a physical address, and a virtual - * address. We use the physical address; the Guest will map itself to the - * virtual address. - * - * We return the starting address. - */ -static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr) -{ - Elf32_Phdr phdr[ehdr->e_phnum]; - unsigned int i; - - /* - * Sanity checks on the main ELF header: an x86 executable with a - * reasonable number of correctly-sized program headers. - */ - if (ehdr->e_type != ET_EXEC - || ehdr->e_machine != EM_386 - || ehdr->e_phentsize != sizeof(Elf32_Phdr) - || ehdr->e_phnum < 1 || ehdr->e_phnum > 65536U/sizeof(Elf32_Phdr)) - errx(1, "Malformed elf header"); - - /* - * An ELF executable contains an ELF header and a number of "program" - * headers which indicate which parts ("segments") of the program to - * load where. - */ - - /* We read in all the program headers at once: */ - if (lseek(elf_fd, ehdr->e_phoff, SEEK_SET) < 0) - err(1, "Seeking to program headers"); - if (read(elf_fd, phdr, sizeof(phdr)) != sizeof(phdr)) - err(1, "Reading program headers"); - - /* - * Try all the headers: there are usually only three. A read-only one, - * a read-write one, and a "note" section which we don't load. - */ - for (i = 0; i < ehdr->e_phnum; i++) { - /* If this isn't a loadable segment, we ignore it */ - if (phdr[i].p_type != PT_LOAD) - continue; - - verbose("Section %i: size %i addr %p\n", - i, phdr[i].p_memsz, (void *)phdr[i].p_paddr); - - /* We map this section of the file at its physical address. */ - map_at(elf_fd, from_guest_phys(phdr[i].p_paddr), - phdr[i].p_offset, phdr[i].p_filesz); - } - - /* The entry point is given in the ELF header. */ - return ehdr->e_entry; -} - -/*L:150 - * A bzImage, unlike an ELF file, is not meant to be loaded. You're supposed - * to jump into it and it will unpack itself. We used to have to perform some - * hairy magic because the unpacking code scared me. - * - * Fortunately, Jeremy Fitzhardinge convinced me it wasn't that hard and wrote - * a small patch to jump over the tricky bits in the Guest, so now we just read - * the funky header so we know where in the file to load, and away we go! - */ -static unsigned long load_bzimage(int fd) -{ - struct boot_params boot; - int r; - /* Modern bzImages get loaded at 1M. */ - void *p = from_guest_phys(0x100000); - - /* - * Go back to the start of the file and read the header. It should be - * a Linux boot header (see Documentation/x86/boot.txt) - */ - lseek(fd, 0, SEEK_SET); - read(fd, &boot, sizeof(boot)); - - /* Inside the setup_hdr, we expect the magic "HdrS" */ - if (memcmp(&boot.hdr.header, "HdrS", 4) != 0) - errx(1, "This doesn't look like a bzImage to me"); - - /* Skip over the extra sectors of the header. */ - lseek(fd, (boot.hdr.setup_sects+1) * 512, SEEK_SET); - - /* Now read everything into memory. in nice big chunks. */ - while ((r = read(fd, p, 65536)) > 0) - p += r; - - /* Finally, code32_start tells us where to enter the kernel. */ - return boot.hdr.code32_start; -} - -/*L:140 - * Loading the kernel is easy when it's a "vmlinux", but most kernels - * come wrapped up in the self-decompressing "bzImage" format. With a little - * work, we can load those, too. - */ -static unsigned long load_kernel(int fd) -{ - Elf32_Ehdr hdr; - - /* Read in the first few bytes. */ - if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) - err(1, "Reading kernel"); - - /* If it's an ELF file, it starts with "\177ELF" */ - if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0) - return map_elf(fd, &hdr); - - /* Otherwise we assume it's a bzImage, and try to load it. */ - return load_bzimage(fd); -} - -/* - * This is a trivial little helper to align pages. Andi Kleen hated it because - * it calls getpagesize() twice: "it's dumb code." - * - * Kernel guys get really het up about optimization, even when it's not - * necessary. I leave this code as a reaction against that. - */ -static inline unsigned long page_align(unsigned long addr) -{ - /* Add upwards and truncate downwards. */ - return ((addr + getpagesize()-1) & ~(getpagesize()-1)); -} - -/*L:180 - * An "initial ram disk" is a disk image loaded into memory along with the - * kernel which the kernel can use to boot from without needing any drivers. - * Most distributions now use this as standard: the initrd contains the code to - * load the appropriate driver modules for the current machine. - * - * Importantly, James Morris works for RedHat, and Fedora uses initrds for its - * kernels. He sent me this (and tells me when I break it). - */ -static unsigned long load_initrd(const char *name, unsigned long mem) -{ - int ifd; - struct stat st; - unsigned long len; - - ifd = open_or_die(name, O_RDONLY); - /* fstat() is needed to get the file size. */ - if (fstat(ifd, &st) < 0) - err(1, "fstat() on initrd '%s'", name); - - /* - * We map the initrd at the top of memory, but mmap wants it to be - * page-aligned, so we round the size up for that. - */ - len = page_align(st.st_size); - map_at(ifd, from_guest_phys(mem - len), 0, st.st_size); - /* - * Once a file is mapped, you can close the file descriptor. It's a - * little odd, but quite useful. - */ - close(ifd); - verbose("mapped initrd %s size=%lu @ %p\n", name, len, (void*)mem-len); - - /* We return the initrd size. */ - return len; -} -/*:*/ - -/* - * Simple routine to roll all the commandline arguments together with spaces - * between them. - */ -static void concat(char *dst, char *args[]) -{ - unsigned int i, len = 0; - - for (i = 0; args[i]; i++) { - if (i) { - strcat(dst+len, " "); - len++; - } - strcpy(dst+len, args[i]); - len += strlen(args[i]); - } - /* In case it's empty. */ - dst[len] = '\0'; -} - -/*L:185 - * This is where we actually tell the kernel to initialize the Guest. We - * saw the arguments it expects when we looked at initialize() in lguest_user.c: - * the base of Guest "physical" memory, the top physical page to allow and the - * entry point for the Guest. - */ -static void tell_kernel(unsigned long start) -{ - unsigned long args[] = { LHREQ_INITIALIZE, - (unsigned long)guest_base, - guest_limit / getpagesize(), start, - (guest_mmio+getpagesize()-1) / getpagesize() }; - verbose("Guest: %p - %p (%#lx, MMIO %#lx)\n", - guest_base, guest_base + guest_limit, - guest_limit, guest_mmio); - lguest_fd = open_or_die("/dev/lguest", O_RDWR); - if (write(lguest_fd, args, sizeof(args)) < 0) - err(1, "Writing to /dev/lguest"); -} -/*:*/ - -/*L:200 - * Device Handling. - * - * When the Guest gives us a buffer, it sends an array of addresses and sizes. - * We need to make sure it's not trying to reach into the Launcher itself, so - * we have a convenient routine which checks it and exits with an error message - * if something funny is going on: - */ -static void *_check_pointer(struct device *d, - unsigned long addr, unsigned int size, - unsigned int line) -{ - /* - * Check if the requested address and size exceeds the allocated memory, - * or addr + size wraps around. - */ - if ((addr + size) > guest_limit || (addr + size) < addr) - bad_driver(d, "%s:%i: Invalid address %#lx", - __FILE__, line, addr); - /* - * We return a pointer for the caller's convenience, now we know it's - * safe to use. - */ - return from_guest_phys(addr); -} -/* A macro which transparently hands the line number to the real function. */ -#define check_pointer(d,addr,size) _check_pointer(d, addr, size, __LINE__) - -/* - * Each buffer in the virtqueues is actually a chain of descriptors. This - * function returns the next descriptor in the chain, or vq->vring.num if we're - * at the end. - */ -static unsigned next_desc(struct device *d, struct vring_desc *desc, - unsigned int i, unsigned int max) -{ - unsigned int next; - - /* If this descriptor says it doesn't chain, we're done. */ - if (!(desc[i].flags & VRING_DESC_F_NEXT)) - return max; - - /* Check they're not leading us off end of descriptors. */ - next = desc[i].next; - /* Make sure compiler knows to grab that: we don't want it changing! */ - wmb(); - - if (next >= max) - bad_driver(d, "Desc next is %u", next); - - return next; -} - -/* - * This actually sends the interrupt for this virtqueue, if we've used a - * buffer. - */ -static void trigger_irq(struct virtqueue *vq) -{ - unsigned long buf[] = { LHREQ_IRQ, vq->dev->config.irq_line }; - - /* Don't inform them if nothing used. */ - if (!vq->pending_used) - return; - vq->pending_used = 0; - - /* - * 2.4.7.1: - * - * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: - * The driver MUST set flags to 0 or 1. - */ - if (vq->vring.avail->flags > 1) - bad_driver_vq(vq, "avail->flags = %u\n", vq->vring.avail->flags); - - /* - * 2.4.7.2: - * - * If the VIRTIO_F_EVENT_IDX feature bit is not negotiated: - * - * - The device MUST ignore the used_event value. - * - After the device writes a descriptor index into the used ring: - * - If flags is 1, the device SHOULD NOT send an interrupt. - * - If flags is 0, the device MUST send an interrupt. - */ - if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) { - return; - } - - /* - * 4.1.4.5.1: - * - * If MSI-X capability is disabled, the device MUST set the Queue - * Interrupt bit in ISR status before sending a virtqueue notification - * to the driver. - */ - vq->dev->mmio->isr = 0x1; - - /* Send the Guest an interrupt tell them we used something up. */ - if (write(lguest_fd, buf, sizeof(buf)) != 0) - err(1, "Triggering irq %i", vq->dev->config.irq_line); -} - -/* - * This looks in the virtqueue for the first available buffer, and converts - * it to an iovec for convenient access. Since descriptors consist of some - * number of output then some number of input descriptors, it's actually two - * iovecs, but we pack them into one and note how many of each there were. - * - * This function waits if necessary, and returns the descriptor number found. - */ -static unsigned wait_for_vq_desc(struct virtqueue *vq, - struct iovec iov[], - unsigned int *out_num, unsigned int *in_num) -{ - unsigned int i, head, max; - struct vring_desc *desc; - u16 last_avail = lg_last_avail(vq); - - /* - * 2.4.7.1: - * - * The driver MUST handle spurious interrupts from the device. - * - * That's why this is a while loop. - */ - - /* There's nothing available? */ - while (last_avail == vq->vring.avail->idx) { - u64 event; - - /* - * Since we're about to sleep, now is a good time to tell the - * Guest about what we've used up to now. - */ - trigger_irq(vq); - - /* OK, now we need to know about added descriptors. */ - vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY; - - /* - * They could have slipped one in as we were doing that: make - * sure it's written, then check again. - */ - mb(); - if (last_avail != vq->vring.avail->idx) { - vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY; - break; - } - - /* Nothing new? Wait for eventfd to tell us they refilled. */ - if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event)) - errx(1, "Event read failed?"); - - /* We don't need to be notified again. */ - vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY; - } - - /* Check it isn't doing very strange things with descriptor numbers. */ - if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num) - bad_driver_vq(vq, "Guest moved used index from %u to %u", - last_avail, vq->vring.avail->idx); - - /* - * Make sure we read the descriptor number *after* we read the ring - * update; don't let the cpu or compiler change the order. - */ - rmb(); - - /* - * Grab the next descriptor number they're advertising, and increment - * the index we've seen. - */ - head = vq->vring.avail->ring[last_avail % vq->vring.num]; - lg_last_avail(vq)++; - - /* If their number is silly, that's a fatal mistake. */ - if (head >= vq->vring.num) - bad_driver_vq(vq, "Guest says index %u is available", head); - - /* When we start there are none of either input nor output. */ - *out_num = *in_num = 0; - - max = vq->vring.num; - desc = vq->vring.desc; - i = head; - - /* - * We have to read the descriptor after we read the descriptor number, - * but there's a data dependency there so the CPU shouldn't reorder - * that: no rmb() required. - */ - - do { - /* - * If this is an indirect entry, then this buffer contains a - * descriptor table which we handle as if it's any normal - * descriptor chain. - */ - if (desc[i].flags & VRING_DESC_F_INDIRECT) { - /* 2.4.5.3.1: - * - * The driver MUST NOT set the VIRTQ_DESC_F_INDIRECT - * flag unless the VIRTIO_F_INDIRECT_DESC feature was - * negotiated. - */ - if (!(vq->dev->features_accepted & - (1<vring.desc) - bad_driver_vq(vq, "Indirect within indirect"); - - /* - * Proposed update VIRTIO-134 spells this out: - * - * A driver MUST NOT set both VIRTQ_DESC_F_INDIRECT - * and VIRTQ_DESC_F_NEXT in flags. - */ - if (desc[i].flags & VRING_DESC_F_NEXT) - bad_driver_vq(vq, "indirect and next together"); - - if (desc[i].len % sizeof(struct vring_desc)) - bad_driver_vq(vq, - "Invalid size for indirect table"); - /* - * 2.4.5.3.2: - * - * The device MUST ignore the write-only flag - * (flags&VIRTQ_DESC_F_WRITE) in the descriptor that - * refers to an indirect table. - * - * We ignore it here: :) - */ - - max = desc[i].len / sizeof(struct vring_desc); - desc = check_pointer(vq->dev, desc[i].addr, desc[i].len); - i = 0; - - /* 2.4.5.3.1: - * - * A driver MUST NOT create a descriptor chain longer - * than the Queue Size of the device. - */ - if (max > vq->pci_config.queue_size) - bad_driver_vq(vq, - "indirect has too many entries"); - } - - /* Grab the first descriptor, and check it's OK. */ - iov[*out_num + *in_num].iov_len = desc[i].len; - iov[*out_num + *in_num].iov_base - = check_pointer(vq->dev, desc[i].addr, desc[i].len); - /* If this is an input descriptor, increment that count. */ - if (desc[i].flags & VRING_DESC_F_WRITE) - (*in_num)++; - else { - /* - * If it's an output descriptor, they're all supposed - * to come before any input descriptors. - */ - if (*in_num) - bad_driver_vq(vq, - "Descriptor has out after in"); - (*out_num)++; - } - - /* If we've got too many, that implies a descriptor loop. */ - if (*out_num + *in_num > max) - bad_driver_vq(vq, "Looped descriptor"); - } while ((i = next_desc(vq->dev, desc, i, max)) != max); - - return head; -} - -/* - * After we've used one of their buffers, we tell the Guest about it. Sometime - * later we'll want to send them an interrupt using trigger_irq(); note that - * wait_for_vq_desc() does that for us if it has to wait. - */ -static void add_used(struct virtqueue *vq, unsigned int head, int len) -{ - struct vring_used_elem *used; - - /* - * The virtqueue contains a ring of used buffers. Get a pointer to the - * next entry in that used ring. - */ - used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num]; - used->id = head; - used->len = len; - /* Make sure buffer is written before we update index. */ - wmb(); - vq->vring.used->idx++; - vq->pending_used++; -} - -/* And here's the combo meal deal. Supersize me! */ -static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len) -{ - add_used(vq, head, len); - trigger_irq(vq); -} - -/* - * The Console - * - * We associate some data with the console for our exit hack. - */ -struct console_abort { - /* How many times have they hit ^C? */ - int count; - /* When did they start? */ - struct timeval start; -}; - -/* This is the routine which handles console input (ie. stdin). */ -static void console_input(struct virtqueue *vq) -{ - int len; - unsigned int head, in_num, out_num; - struct console_abort *abort = vq->dev->priv; - struct iovec iov[vq->vring.num]; - - /* Make sure there's a descriptor available. */ - head = wait_for_vq_desc(vq, iov, &out_num, &in_num); - if (out_num) - bad_driver_vq(vq, "Output buffers in console in queue?"); - - /* Read into it. This is where we usually wait. */ - len = readv(STDIN_FILENO, iov, in_num); - if (len <= 0) { - /* Ran out of input? */ - warnx("Failed to get console input, ignoring console."); - /* - * For simplicity, dying threads kill the whole Launcher. So - * just nap here. - */ - for (;;) - pause(); - } - - /* Tell the Guest we used a buffer. */ - add_used_and_trigger(vq, head, len); - - /* - * Three ^C within one second? Exit. - * - * This is such a hack, but works surprisingly well. Each ^C has to - * be in a buffer by itself, so they can't be too fast. But we check - * that we get three within about a second, so they can't be too - * slow. - */ - if (len != 1 || ((char *)iov[0].iov_base)[0] != 3) { - abort->count = 0; - return; - } - - abort->count++; - if (abort->count == 1) - gettimeofday(&abort->start, NULL); - else if (abort->count == 3) { - struct timeval now; - gettimeofday(&now, NULL); - /* Kill all Launcher processes with SIGINT, like normal ^C */ - if (now.tv_sec <= abort->start.tv_sec+1) - kill(0, SIGINT); - abort->count = 0; - } -} - -/* This is the routine which handles console output (ie. stdout). */ -static void console_output(struct virtqueue *vq) -{ - unsigned int head, out, in; - struct iovec iov[vq->vring.num]; - - /* We usually wait in here, for the Guest to give us something. */ - head = wait_for_vq_desc(vq, iov, &out, &in); - if (in) - bad_driver_vq(vq, "Input buffers in console output queue?"); - - /* writev can return a partial write, so we loop here. */ - while (!iov_empty(iov, out)) { - int len = writev(STDOUT_FILENO, iov, out); - if (len <= 0) { - warn("Write to stdout gave %i (%d)", len, errno); - break; - } - iov_consume(vq->dev, iov, out, NULL, len); - } - - /* - * We're finished with that buffer: if we're going to sleep, - * wait_for_vq_desc() will prod the Guest with an interrupt. - */ - add_used(vq, head, 0); -} - -/* - * The Network - * - * Handling output for network is also simple: we get all the output buffers - * and write them to /dev/net/tun. - */ -struct net_info { - int tunfd; -}; - -static void net_output(struct virtqueue *vq) -{ - struct net_info *net_info = vq->dev->priv; - unsigned int head, out, in; - struct iovec iov[vq->vring.num]; - - /* We usually wait in here for the Guest to give us a packet. */ - head = wait_for_vq_desc(vq, iov, &out, &in); - if (in) - bad_driver_vq(vq, "Input buffers in net output queue?"); - /* - * Send the whole thing through to /dev/net/tun. It expects the exact - * same format: what a coincidence! - */ - if (writev(net_info->tunfd, iov, out) < 0) - warnx("Write to tun failed (%d)?", errno); - - /* - * Done with that one; wait_for_vq_desc() will send the interrupt if - * all packets are processed. - */ - add_used(vq, head, 0); -} - -/* - * Handling network input is a bit trickier, because I've tried to optimize it. - * - * First we have a helper routine which tells is if from this file descriptor - * (ie. the /dev/net/tun device) will block: - */ -static bool will_block(int fd) -{ - fd_set fdset; - struct timeval zero = { 0, 0 }; - FD_ZERO(&fdset); - FD_SET(fd, &fdset); - return select(fd+1, &fdset, NULL, NULL, &zero) != 1; -} - -/* - * This handles packets coming in from the tun device to our Guest. Like all - * service routines, it gets called again as soon as it returns, so you don't - * see a while(1) loop here. - */ -static void net_input(struct virtqueue *vq) -{ - int len; - unsigned int head, out, in; - struct iovec iov[vq->vring.num]; - struct net_info *net_info = vq->dev->priv; - - /* - * Get a descriptor to write an incoming packet into. This will also - * send an interrupt if they're out of descriptors. - */ - head = wait_for_vq_desc(vq, iov, &out, &in); - if (out) - bad_driver_vq(vq, "Output buffers in net input queue?"); - - /* - * If it looks like we'll block reading from the tun device, send them - * an interrupt. - */ - if (vq->pending_used && will_block(net_info->tunfd)) - trigger_irq(vq); - - /* - * Read in the packet. This is where we normally wait (when there's no - * incoming network traffic). - */ - len = readv(net_info->tunfd, iov, in); - if (len <= 0) - warn("Failed to read from tun (%d).", errno); - - /* - * Mark that packet buffer as used, but don't interrupt here. We want - * to wait until we've done as much work as we can. - */ - add_used(vq, head, len); -} -/*:*/ - -/* This is the helper to create threads: run the service routine in a loop. */ -static int do_thread(void *_vq) -{ - struct virtqueue *vq = _vq; - - for (;;) - vq->service(vq); - return 0; -} - -/* - * When a child dies, we kill our entire process group with SIGTERM. This - * also has the side effect that the shell restores the console for us! - */ -static void kill_launcher(int signal) -{ - kill(0, SIGTERM); -} - -static void reset_vq_pci_config(struct virtqueue *vq) -{ - vq->pci_config.queue_size = VIRTQUEUE_NUM; - vq->pci_config.queue_enable = 0; -} - -static void reset_device(struct device *dev) -{ - struct virtqueue *vq; - - verbose("Resetting device %s\n", dev->name); - - /* Clear any features they've acked. */ - dev->features_accepted = 0; - - /* We're going to be explicitly killing threads, so ignore them. */ - signal(SIGCHLD, SIG_IGN); - - /* - * 4.1.4.3.1: - * - * The device MUST present a 0 in queue_enable on reset. - * - * This means we set it here, and reset the saved ones in every vq. - */ - dev->mmio->cfg.queue_enable = 0; - - /* Get rid of the virtqueue threads */ - for (vq = dev->vq; vq; vq = vq->next) { - vq->last_avail_idx = 0; - reset_vq_pci_config(vq); - if (vq->thread != (pid_t)-1) { - kill(vq->thread, SIGTERM); - waitpid(vq->thread, NULL, 0); - vq->thread = (pid_t)-1; - } - } - dev->running = false; - dev->wrote_features_ok = false; - - /* Now we care if threads die. */ - signal(SIGCHLD, (void *)kill_launcher); -} - -static void cleanup_devices(void) -{ - unsigned int i; - - for (i = 1; i < MAX_PCI_DEVICES; i++) { - struct device *d = devices.pci[i]; - if (!d) - continue; - reset_device(d); - } - - /* If we saved off the original terminal settings, restore them now. */ - if (orig_term.c_lflag & (ISIG|ICANON|ECHO)) - tcsetattr(STDIN_FILENO, TCSANOW, &orig_term); -} - -/*L:217 - * We do PCI. This is mainly done to let us test the kernel virtio PCI - * code. - */ - -/* Linux expects a PCI host bridge: ours is a dummy, and first on the bus. */ -static struct device pci_host_bridge; - -static void init_pci_host_bridge(void) -{ - pci_host_bridge.name = "PCI Host Bridge"; - pci_host_bridge.config.class = 0x06; /* bridge */ - pci_host_bridge.config.subclass = 0; /* host bridge */ - devices.pci[0] = &pci_host_bridge; -} - -/* The IO ports used to read the PCI config space. */ -#define PCI_CONFIG_ADDR 0xCF8 -#define PCI_CONFIG_DATA 0xCFC - -/* - * Not really portable, but does help readability: this is what the Guest - * writes to the PCI_CONFIG_ADDR IO port. - */ -union pci_config_addr { - struct { - unsigned mbz: 2; - unsigned offset: 6; - unsigned funcnum: 3; - unsigned devnum: 5; - unsigned busnum: 8; - unsigned reserved: 7; - unsigned enabled : 1; - } bits; - u32 val; -}; - -/* - * We cache what they wrote to the address port, so we know what they're - * talking about when they access the data port. - */ -static union pci_config_addr pci_config_addr; - -static struct device *find_pci_device(unsigned int index) -{ - return devices.pci[index]; -} - -/* PCI can do 1, 2 and 4 byte reads; we handle that here. */ -static void ioread(u16 off, u32 v, u32 mask, u32 *val) -{ - assert(off < 4); - assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF); - *val = (v >> (off * 8)) & mask; -} - -/* PCI can do 1, 2 and 4 byte writes; we handle that here. */ -static void iowrite(u16 off, u32 v, u32 mask, u32 *dst) -{ - assert(off < 4); - assert(mask == 0xFF || mask == 0xFFFF || mask == 0xFFFFFFFF); - *dst &= ~(mask << (off * 8)); - *dst |= (v & mask) << (off * 8); -} - -/* - * Where PCI_CONFIG_DATA accesses depends on the previous write to - * PCI_CONFIG_ADDR. - */ -static struct device *dev_and_reg(u32 *reg) -{ - if (!pci_config_addr.bits.enabled) - return NULL; - - if (pci_config_addr.bits.funcnum != 0) - return NULL; - - if (pci_config_addr.bits.busnum != 0) - return NULL; - - if (pci_config_addr.bits.offset * 4 >= sizeof(struct pci_config)) - return NULL; - - *reg = pci_config_addr.bits.offset; - return find_pci_device(pci_config_addr.bits.devnum); -} - -/* - * We can get invalid combinations of values while they're writing, so we - * only fault if they try to write with some invalid bar/offset/length. - */ -static bool valid_bar_access(struct device *d, - struct virtio_pci_cfg_cap_u32 *cfg_access) -{ - /* We only have 1 bar (BAR0) */ - if (cfg_access->cap.bar != 0) - return false; - - /* Check it's within BAR0. */ - if (cfg_access->cap.offset >= d->mmio_size - || cfg_access->cap.offset + cfg_access->cap.length > d->mmio_size) - return false; - - /* Check length is 1, 2 or 4. */ - if (cfg_access->cap.length != 1 - && cfg_access->cap.length != 2 - && cfg_access->cap.length != 4) - return false; - - /* - * 4.1.4.7.2: - * - * The driver MUST NOT write a cap.offset which is not a multiple of - * cap.length (ie. all accesses MUST be aligned). - */ - if (cfg_access->cap.offset % cfg_access->cap.length != 0) - return false; - - /* Return pointer into word in BAR0. */ - return true; -} - -/* Is this accessing the PCI config address port?. */ -static bool is_pci_addr_port(u16 port) -{ - return port >= PCI_CONFIG_ADDR && port < PCI_CONFIG_ADDR + 4; -} - -static bool pci_addr_iowrite(u16 port, u32 mask, u32 val) -{ - iowrite(port - PCI_CONFIG_ADDR, val, mask, - &pci_config_addr.val); - verbose("PCI%s: %#x/%x: bus %u dev %u func %u reg %u\n", - pci_config_addr.bits.enabled ? "" : " DISABLED", - val, mask, - pci_config_addr.bits.busnum, - pci_config_addr.bits.devnum, - pci_config_addr.bits.funcnum, - pci_config_addr.bits.offset); - return true; -} - -static void pci_addr_ioread(u16 port, u32 mask, u32 *val) -{ - ioread(port - PCI_CONFIG_ADDR, pci_config_addr.val, mask, val); -} - -/* Is this accessing the PCI config data port?. */ -static bool is_pci_data_port(u16 port) -{ - return port >= PCI_CONFIG_DATA && port < PCI_CONFIG_DATA + 4; -} - -static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask); - -static bool pci_data_iowrite(u16 port, u32 mask, u32 val) -{ - u32 reg, portoff; - struct device *d = dev_and_reg(®); - - /* Complain if they don't belong to a device. */ - if (!d) - return false; - - /* They can do 1 byte writes, etc. */ - portoff = port - PCI_CONFIG_DATA; - - /* - * PCI uses a weird way to determine the BAR size: the OS - * writes all 1's, and sees which ones stick. - */ - if (&d->config_words[reg] == &d->config.bar[0]) { - int i; - - iowrite(portoff, val, mask, &d->config.bar[0]); - for (i = 0; (1 << i) < d->mmio_size; i++) - d->config.bar[0] &= ~(1 << i); - return true; - } else if ((&d->config_words[reg] > &d->config.bar[0] - && &d->config_words[reg] <= &d->config.bar[6]) - || &d->config_words[reg] == &d->config.expansion_rom_addr) { - /* Allow writing to any other BAR, or expansion ROM */ - iowrite(portoff, val, mask, &d->config_words[reg]); - return true; - /* We let them override latency timer and cacheline size */ - } else if (&d->config_words[reg] == (void *)&d->config.cacheline_size) { - /* Only let them change the first two fields. */ - if (mask == 0xFFFFFFFF) - mask = 0xFFFF; - iowrite(portoff, val, mask, &d->config_words[reg]); - return true; - } else if (&d->config_words[reg] == (void *)&d->config.command - && mask == 0xFFFF) { - /* Ignore command writes. */ - return true; - } else if (&d->config_words[reg] - == (void *)&d->config.cfg_access.cap.bar - || &d->config_words[reg] - == &d->config.cfg_access.cap.length - || &d->config_words[reg] - == &d->config.cfg_access.cap.offset) { - - /* - * The VIRTIO_PCI_CAP_PCI_CFG capability - * provides a backdoor to access the MMIO - * regions without mapping them. Weird, but - * useful. - */ - iowrite(portoff, val, mask, &d->config_words[reg]); - return true; - } else if (&d->config_words[reg] == &d->config.cfg_access.pci_cfg_data) { - u32 write_mask; - - /* - * 4.1.4.7.1: - * - * Upon detecting driver write access to pci_cfg_data, the - * device MUST execute a write access at offset cap.offset at - * BAR selected by cap.bar using the first cap.length bytes - * from pci_cfg_data. - */ - - /* Must be bar 0 */ - if (!valid_bar_access(d, &d->config.cfg_access)) - return false; - - iowrite(portoff, val, mask, &d->config.cfg_access.pci_cfg_data); - - /* - * Now emulate a write. The mask we use is set by - * len, *not* this write! - */ - write_mask = (1ULL<<(8*d->config.cfg_access.cap.length)) - 1; - verbose("Window writing %#x/%#x to bar %u, offset %u len %u\n", - d->config.cfg_access.pci_cfg_data, write_mask, - d->config.cfg_access.cap.bar, - d->config.cfg_access.cap.offset, - d->config.cfg_access.cap.length); - - emulate_mmio_write(d, d->config.cfg_access.cap.offset, - d->config.cfg_access.pci_cfg_data, - write_mask); - return true; - } - - /* - * 4.1.4.1: - * - * The driver MUST NOT write into any field of the capability - * structure, with the exception of those with cap_type - * VIRTIO_PCI_CAP_PCI_CFG... - */ - return false; -} - -static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask); - -static void pci_data_ioread(u16 port, u32 mask, u32 *val) -{ - u32 reg; - struct device *d = dev_and_reg(®); - - if (!d) - return; - - /* Read through the PCI MMIO access window is special */ - if (&d->config_words[reg] == &d->config.cfg_access.pci_cfg_data) { - u32 read_mask; - - /* - * 4.1.4.7.1: - * - * Upon detecting driver read access to pci_cfg_data, the - * device MUST execute a read access of length cap.length at - * offset cap.offset at BAR selected by cap.bar and store the - * first cap.length bytes in pci_cfg_data. - */ - /* Must be bar 0 */ - if (!valid_bar_access(d, &d->config.cfg_access)) - bad_driver(d, - "Invalid cfg_access to bar%u, offset %u len %u", - d->config.cfg_access.cap.bar, - d->config.cfg_access.cap.offset, - d->config.cfg_access.cap.length); - - /* - * Read into the window. The mask we use is set by - * len, *not* this read! - */ - read_mask = (1ULL<<(8*d->config.cfg_access.cap.length))-1; - d->config.cfg_access.pci_cfg_data - = emulate_mmio_read(d, - d->config.cfg_access.cap.offset, - read_mask); - verbose("Window read %#x/%#x from bar %u, offset %u len %u\n", - d->config.cfg_access.pci_cfg_data, read_mask, - d->config.cfg_access.cap.bar, - d->config.cfg_access.cap.offset, - d->config.cfg_access.cap.length); - } - ioread(port - PCI_CONFIG_DATA, d->config_words[reg], mask, val); -} - -/*L:216 - * This is where we emulate a handful of Guest instructions. It's ugly - * and we used to do it in the kernel but it grew over time. - */ - -/* - * We use the ptrace syscall's pt_regs struct to talk about registers - * to lguest: these macros convert the names to the offsets. - */ -#define getreg(name) getreg_off(offsetof(struct user_regs_struct, name)) -#define setreg(name, val) \ - setreg_off(offsetof(struct user_regs_struct, name), (val)) - -static u32 getreg_off(size_t offset) -{ - u32 r; - unsigned long args[] = { LHREQ_GETREG, offset }; - - if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0) - err(1, "Getting register %u", offset); - if (pread(lguest_fd, &r, sizeof(r), cpu_id) != sizeof(r)) - err(1, "Reading register %u", offset); - - return r; -} - -static void setreg_off(size_t offset, u32 val) -{ - unsigned long args[] = { LHREQ_SETREG, offset, val }; - - if (pwrite(lguest_fd, args, sizeof(args), cpu_id) < 0) - err(1, "Setting register %u", offset); -} - -/* Get register by instruction encoding */ -static u32 getreg_num(unsigned regnum, u32 mask) -{ - /* 8 bit ops use regnums 4-7 for high parts of word */ - if (mask == 0xFF && (regnum & 0x4)) - return getreg_num(regnum & 0x3, 0xFFFF) >> 8; - - switch (regnum) { - case 0: return getreg(eax) & mask; - case 1: return getreg(ecx) & mask; - case 2: return getreg(edx) & mask; - case 3: return getreg(ebx) & mask; - case 4: return getreg(esp) & mask; - case 5: return getreg(ebp) & mask; - case 6: return getreg(esi) & mask; - case 7: return getreg(edi) & mask; - } - abort(); -} - -/* Set register by instruction encoding */ -static void setreg_num(unsigned regnum, u32 val, u32 mask) -{ - /* Don't try to set bits out of range */ - assert(~(val & ~mask)); - - /* 8 bit ops use regnums 4-7 for high parts of word */ - if (mask == 0xFF && (regnum & 0x4)) { - /* Construct the 16 bits we want. */ - val = (val << 8) | getreg_num(regnum & 0x3, 0xFF); - setreg_num(regnum & 0x3, val, 0xFFFF); - return; - } - - switch (regnum) { - case 0: setreg(eax, val | (getreg(eax) & ~mask)); return; - case 1: setreg(ecx, val | (getreg(ecx) & ~mask)); return; - case 2: setreg(edx, val | (getreg(edx) & ~mask)); return; - case 3: setreg(ebx, val | (getreg(ebx) & ~mask)); return; - case 4: setreg(esp, val | (getreg(esp) & ~mask)); return; - case 5: setreg(ebp, val | (getreg(ebp) & ~mask)); return; - case 6: setreg(esi, val | (getreg(esi) & ~mask)); return; - case 7: setreg(edi, val | (getreg(edi) & ~mask)); return; - } - abort(); -} - -/* Get bytes of displacement appended to instruction, from r/m encoding */ -static u32 insn_displacement_len(u8 mod_reg_rm) -{ - /* Switch on the mod bits */ - switch (mod_reg_rm >> 6) { - case 0: - /* If mod == 0, and r/m == 101, 16-bit displacement follows */ - if ((mod_reg_rm & 0x7) == 0x5) - return 2; - /* Normally, mod == 0 means no literal displacement */ - return 0; - case 1: - /* One byte displacement */ - return 1; - case 2: - /* Four byte displacement */ - return 4; - case 3: - /* Register mode */ - return 0; - } - abort(); -} - -static void emulate_insn(const u8 insn[]) -{ - unsigned long args[] = { LHREQ_TRAP, 13 }; - unsigned int insnlen = 0, in = 0, small_operand = 0, byte_access; - unsigned int eax, port, mask; - /* - * Default is to return all-ones on IO port reads, which traditionally - * means "there's nothing there". - */ - u32 val = 0xFFFFFFFF; - - /* - * This must be the Guest kernel trying to do something, not userspace! - * The bottom two bits of the CS segment register are the privilege - * level. - */ - if ((getreg(xcs) & 3) != 0x1) - goto no_emulate; - - /* Decoding x86 instructions is icky. */ - - /* - * Around 2.6.33, the kernel started using an emulation for the - * cmpxchg8b instruction in early boot on many configurations. This - * code isn't paravirtualized, and it tries to disable interrupts. - * Ignore it, which will Mostly Work. - */ - if (insn[insnlen] == 0xfa) { - /* "cli", or Clear Interrupt Enable instruction. Skip it. */ - insnlen = 1; - goto skip_insn; - } - - /* - * 0x66 is an "operand prefix". It means a 16, not 32 bit in/out. - */ - if (insn[insnlen] == 0x66) { - small_operand = 1; - /* The instruction is 1 byte so far, read the next byte. */ - insnlen = 1; - } - - /* If the lower bit isn't set, it's a single byte access */ - byte_access = !(insn[insnlen] & 1); - - /* - * Now we can ignore the lower bit and decode the 4 opcodes - * we need to emulate. - */ - switch (insn[insnlen] & 0xFE) { - case 0xE4: /* in ,%al */ - port = insn[insnlen+1]; - insnlen += 2; - in = 1; - break; - case 0xEC: /* in (%dx),%al */ - port = getreg(edx) & 0xFFFF; - insnlen += 1; - in = 1; - break; - case 0xE6: /* out %al, */ - port = insn[insnlen+1]; - insnlen += 2; - break; - case 0xEE: /* out %al,(%dx) */ - port = getreg(edx) & 0xFFFF; - insnlen += 1; - break; - default: - /* OK, we don't know what this is, can't emulate. */ - goto no_emulate; - } - - /* Set a mask of the 1, 2 or 4 bytes, depending on size of IO */ - if (byte_access) - mask = 0xFF; - else if (small_operand) - mask = 0xFFFF; - else - mask = 0xFFFFFFFF; - - /* - * If it was an "IN" instruction, they expect the result to be read - * into %eax, so we change %eax. - */ - eax = getreg(eax); - - if (in) { - /* This is the PS/2 keyboard status; 1 means ready for output */ - if (port == 0x64) - val = 1; - else if (is_pci_addr_port(port)) - pci_addr_ioread(port, mask, &val); - else if (is_pci_data_port(port)) - pci_data_ioread(port, mask, &val); - - /* Clear the bits we're about to read */ - eax &= ~mask; - /* Copy bits in from val. */ - eax |= val & mask; - /* Now update the register. */ - setreg(eax, eax); - } else { - if (is_pci_addr_port(port)) { - if (!pci_addr_iowrite(port, mask, eax)) - goto bad_io; - } else if (is_pci_data_port(port)) { - if (!pci_data_iowrite(port, mask, eax)) - goto bad_io; - } - /* There are many other ports, eg. CMOS clock, serial - * and parallel ports, so we ignore them all. */ - } - - verbose("IO %s of %x to %u: %#08x\n", - in ? "IN" : "OUT", mask, port, eax); -skip_insn: - /* Finally, we've "done" the instruction, so move past it. */ - setreg(eip, getreg(eip) + insnlen); - return; - -bad_io: - warnx("Attempt to %s port %u (%#x mask)", - in ? "read from" : "write to", port, mask); - -no_emulate: - /* Inject trap into Guest. */ - if (write(lguest_fd, args, sizeof(args)) < 0) - err(1, "Reinjecting trap 13 for fault at %#x", getreg(eip)); -} - -static struct device *find_mmio_region(unsigned long paddr, u32 *off) -{ - unsigned int i; - - for (i = 1; i < MAX_PCI_DEVICES; i++) { - struct device *d = devices.pci[i]; - - if (!d) - continue; - if (paddr < d->mmio_addr) - continue; - if (paddr >= d->mmio_addr + d->mmio_size) - continue; - *off = paddr - d->mmio_addr; - return d; - } - return NULL; -} - -/* FIXME: Use vq array. */ -static struct virtqueue *vq_by_num(struct device *d, u32 num) -{ - struct virtqueue *vq = d->vq; - - while (num-- && vq) - vq = vq->next; - - return vq; -} - -static void save_vq_config(const struct virtio_pci_common_cfg *cfg, - struct virtqueue *vq) -{ - vq->pci_config = *cfg; -} - -static void restore_vq_config(struct virtio_pci_common_cfg *cfg, - struct virtqueue *vq) -{ - /* Only restore the per-vq part */ - size_t off = offsetof(struct virtio_pci_common_cfg, queue_size); - - memcpy((void *)cfg + off, (void *)&vq->pci_config + off, - sizeof(*cfg) - off); -} - -/* - * 4.1.4.3.2: - * - * The driver MUST configure the other virtqueue fields before - * enabling the virtqueue with queue_enable. - * - * When they enable the virtqueue, we check that their setup is valid. - */ -static void check_virtqueue(struct device *d, struct virtqueue *vq) -{ - /* Because lguest is 32 bit, all the descriptor high bits must be 0 */ - if (vq->pci_config.queue_desc_hi - || vq->pci_config.queue_avail_hi - || vq->pci_config.queue_used_hi) - bad_driver_vq(vq, "invalid 64-bit queue address"); - - /* - * 2.4.1: - * - * The driver MUST ensure that the physical address of the first byte - * of each virtqueue part is a multiple of the specified alignment - * value in the above table. - */ - if (vq->pci_config.queue_desc_lo % 16 - || vq->pci_config.queue_avail_lo % 2 - || vq->pci_config.queue_used_lo % 4) - bad_driver_vq(vq, "invalid alignment in queue addresses"); - - /* Initialize the virtqueue and check they're all in range. */ - vq->vring.num = vq->pci_config.queue_size; - vq->vring.desc = check_pointer(vq->dev, - vq->pci_config.queue_desc_lo, - sizeof(*vq->vring.desc) * vq->vring.num); - vq->vring.avail = check_pointer(vq->dev, - vq->pci_config.queue_avail_lo, - sizeof(*vq->vring.avail) - + (sizeof(vq->vring.avail->ring[0]) - * vq->vring.num)); - vq->vring.used = check_pointer(vq->dev, - vq->pci_config.queue_used_lo, - sizeof(*vq->vring.used) - + (sizeof(vq->vring.used->ring[0]) - * vq->vring.num)); - - /* - * 2.4.9.1: - * - * The driver MUST initialize flags in the used ring to 0 - * when allocating the used ring. - */ - if (vq->vring.used->flags != 0) - bad_driver_vq(vq, "invalid initial used.flags %#x", - vq->vring.used->flags); -} - -static void start_virtqueue(struct virtqueue *vq) -{ - /* - * Create stack for thread. Since the stack grows upwards, we point - * the stack pointer to the end of this region. - */ - char *stack = malloc(32768); - - /* Create a zero-initialized eventfd. */ - vq->eventfd = eventfd(0, 0); - if (vq->eventfd < 0) - err(1, "Creating eventfd"); - - /* - * CLONE_VM: because it has to access the Guest memory, and SIGCHLD so - * we get a signal if it dies. - */ - vq->thread = clone(do_thread, stack + 32768, CLONE_VM | SIGCHLD, vq); - if (vq->thread == (pid_t)-1) - err(1, "Creating clone"); -} - -static void start_virtqueues(struct device *d) -{ - struct virtqueue *vq; - - for (vq = d->vq; vq; vq = vq->next) { - if (vq->pci_config.queue_enable) - start_virtqueue(vq); - } -} - -static void emulate_mmio_write(struct device *d, u32 off, u32 val, u32 mask) -{ - struct virtqueue *vq; - - switch (off) { - case offsetof(struct virtio_pci_mmio, cfg.device_feature_select): - /* - * 4.1.4.3.1: - * - * The device MUST present the feature bits it is offering in - * device_feature, starting at bit device_feature_select ∗ 32 - * for any device_feature_select written by the driver - */ - if (val == 0) - d->mmio->cfg.device_feature = d->features; - else if (val == 1) - d->mmio->cfg.device_feature = (d->features >> 32); - else - d->mmio->cfg.device_feature = 0; - goto feature_write_through32; - case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): - if (val > 1) - bad_driver(d, "Unexpected driver select %u", val); - goto feature_write_through32; - case offsetof(struct virtio_pci_mmio, cfg.guest_feature): - if (d->mmio->cfg.guest_feature_select == 0) { - d->features_accepted &= ~((u64)0xFFFFFFFF); - d->features_accepted |= val; - } else { - assert(d->mmio->cfg.guest_feature_select == 1); - d->features_accepted &= 0xFFFFFFFF; - d->features_accepted |= ((u64)val) << 32; - } - /* - * 2.2.1: - * - * The driver MUST NOT accept a feature which the device did - * not offer - */ - if (d->features_accepted & ~d->features) - bad_driver(d, "over-accepted features %#llx of %#llx", - d->features_accepted, d->features); - goto feature_write_through32; - case offsetof(struct virtio_pci_mmio, cfg.device_status): { - u8 prev; - - verbose("%s: device status -> %#x\n", d->name, val); - /* - * 4.1.4.3.1: - * - * The device MUST reset when 0 is written to device_status, - * and present a 0 in device_status once that is done. - */ - if (val == 0) { - reset_device(d); - goto write_through8; - } - - /* 2.1.1: The driver MUST NOT clear a device status bit. */ - if (d->mmio->cfg.device_status & ~val) - bad_driver(d, "unset of device status bit %#x -> %#x", - d->mmio->cfg.device_status, val); - - /* - * 2.1.2: - * - * The device MUST NOT consume buffers or notify the driver - * before DRIVER_OK. - */ - if (val & VIRTIO_CONFIG_S_DRIVER_OK - && !(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)) - start_virtqueues(d); - - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - * - Reset the device. - * - Set the ACKNOWLEDGE status bit: the guest OS has - * notice the device. - * - Set the DRIVER status bit: the guest OS knows how - * to drive the device. - * - Read device feature bits, and write the subset - * of feature bits understood by the OS and driver - * to the device. During this step the driver MAY - * read (but MUST NOT write) the device-specific - * configuration fields to check that it can - * support the device before accepting it. - * - Set the FEATURES_OK status bit. The driver - * MUST not accept new feature bits after this - * step. - * - Re-read device status to ensure the FEATURES_OK - * bit is still set: otherwise, the device does - * not support our subset of features and the - * device is unusable. - * - Perform device-specific setup, including - * discovery of virtqueues for the device, - * optional per-bus setup, reading and possibly - * writing the device’s virtio configuration - * space, and population of virtqueues. - * - Set the DRIVER_OK status bit. At this point the - * device is “live”. - */ - prev = 0; - switch (val & ~d->mmio->cfg.device_status) { - case VIRTIO_CONFIG_S_DRIVER_OK: - prev |= VIRTIO_CONFIG_S_FEATURES_OK; /* fall thru */ - case VIRTIO_CONFIG_S_FEATURES_OK: - prev |= VIRTIO_CONFIG_S_DRIVER; /* fall thru */ - case VIRTIO_CONFIG_S_DRIVER: - prev |= VIRTIO_CONFIG_S_ACKNOWLEDGE; /* fall thru */ - case VIRTIO_CONFIG_S_ACKNOWLEDGE: - break; - default: - bad_driver(d, "unknown device status bit %#x -> %#x", - d->mmio->cfg.device_status, val); - } - if (d->mmio->cfg.device_status != prev) - bad_driver(d, "unexpected status transition %#x -> %#x", - d->mmio->cfg.device_status, val); - - /* If they just wrote FEATURES_OK, we make sure they read */ - switch (val & ~d->mmio->cfg.device_status) { - case VIRTIO_CONFIG_S_FEATURES_OK: - d->wrote_features_ok = true; - break; - case VIRTIO_CONFIG_S_DRIVER_OK: - if (d->wrote_features_ok) - bad_driver(d, "did not re-read FEATURES_OK"); - break; - } - goto write_through8; - } - case offsetof(struct virtio_pci_mmio, cfg.queue_select): - vq = vq_by_num(d, val); - /* - * 4.1.4.3.1: - * - * The device MUST present a 0 in queue_size if the virtqueue - * corresponding to the current queue_select is unavailable. - */ - if (!vq) { - d->mmio->cfg.queue_size = 0; - goto write_through16; - } - /* Save registers for old vq, if it was a valid vq */ - if (d->mmio->cfg.queue_size) - save_vq_config(&d->mmio->cfg, - vq_by_num(d, d->mmio->cfg.queue_select)); - /* Restore the registers for the queue they asked for */ - restore_vq_config(&d->mmio->cfg, vq); - goto write_through16; - case offsetof(struct virtio_pci_mmio, cfg.queue_size): - /* - * 4.1.4.3.2: - * - * The driver MUST NOT write a value which is not a power of 2 - * to queue_size. - */ - if (val & (val-1)) - bad_driver(d, "invalid queue size %u", val); - if (d->mmio->cfg.queue_enable) - bad_driver(d, "changing queue size on live device"); - goto write_through16; - case offsetof(struct virtio_pci_mmio, cfg.queue_msix_vector): - bad_driver(d, "attempt to set MSIX vector to %u", val); - case offsetof(struct virtio_pci_mmio, cfg.queue_enable): { - struct virtqueue *vq = vq_by_num(d, d->mmio->cfg.queue_select); - - /* - * 4.1.4.3.2: - * - * The driver MUST NOT write a 0 to queue_enable. - */ - if (val != 1) - bad_driver(d, "setting queue_enable to %u", val); - - /* - * 3.1.1: - * - * 7. Perform device-specific setup, including discovery of - * virtqueues for the device, optional per-bus setup, - * reading and possibly writing the device’s virtio - * configuration space, and population of virtqueues. - * 8. Set the DRIVER_OK status bit. - * - * All our devices require all virtqueues to be enabled, so - * they should have done that before setting DRIVER_OK. - */ - if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK) - bad_driver(d, "enabling vq after DRIVER_OK"); - - d->mmio->cfg.queue_enable = val; - save_vq_config(&d->mmio->cfg, vq); - check_virtqueue(d, vq); - goto write_through16; - } - case offsetof(struct virtio_pci_mmio, cfg.queue_notify_off): - bad_driver(d, "attempt to write to queue_notify_off"); - case offsetof(struct virtio_pci_mmio, cfg.queue_desc_lo): - case offsetof(struct virtio_pci_mmio, cfg.queue_desc_hi): - case offsetof(struct virtio_pci_mmio, cfg.queue_avail_lo): - case offsetof(struct virtio_pci_mmio, cfg.queue_avail_hi): - case offsetof(struct virtio_pci_mmio, cfg.queue_used_lo): - case offsetof(struct virtio_pci_mmio, cfg.queue_used_hi): - /* - * 4.1.4.3.2: - * - * The driver MUST configure the other virtqueue fields before - * enabling the virtqueue with queue_enable. - */ - if (d->mmio->cfg.queue_enable) - bad_driver(d, "changing queue on live device"); - - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - *... - * 5. Set the FEATURES_OK status bit. The driver MUST not - * accept new feature bits after this step. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK)) - bad_driver(d, "setting up vq before FEATURES_OK"); - - /* - * 6. Re-read device status to ensure the FEATURES_OK bit is - * still set... - */ - if (d->wrote_features_ok) - bad_driver(d, "didn't re-read FEATURES_OK before setup"); - - goto write_through32; - case offsetof(struct virtio_pci_mmio, notify): - vq = vq_by_num(d, val); - if (!vq) - bad_driver(d, "Invalid vq notification on %u", val); - /* Notify the process handling this vq by adding 1 to eventfd */ - write(vq->eventfd, "\1\0\0\0\0\0\0\0", 8); - goto write_through16; - case offsetof(struct virtio_pci_mmio, isr): - bad_driver(d, "Unexpected write to isr"); - /* Weird corner case: write to emerg_wr of console */ - case sizeof(struct virtio_pci_mmio) - + offsetof(struct virtio_console_config, emerg_wr): - if (strcmp(d->name, "console") == 0) { - char c = val; - write(STDOUT_FILENO, &c, 1); - goto write_through32; - } - /* Fall through... */ - default: - /* - * 4.1.4.3.2: - * - * The driver MUST NOT write to device_feature, num_queues, - * config_generation or queue_notify_off. - */ - bad_driver(d, "Unexpected write to offset %u", off); - } - -feature_write_through32: - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - *... - * - Set the DRIVER status bit: the guest OS knows how - * to drive the device. - * - Read device feature bits, and write the subset - * of feature bits understood by the OS and driver - * to the device. - *... - * - Set the FEATURES_OK status bit. The driver MUST not - * accept new feature bits after this step. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) - bad_driver(d, "feature write before VIRTIO_CONFIG_S_DRIVER"); - if (d->mmio->cfg.device_status & VIRTIO_CONFIG_S_FEATURES_OK) - bad_driver(d, "feature write after VIRTIO_CONFIG_S_FEATURES_OK"); - - /* - * 4.1.3.1: - * - * The driver MUST access each field using the “natural” access - * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for - * 16-bit fields and 8-bit accesses for 8-bit fields. - */ -write_through32: - if (mask != 0xFFFFFFFF) { - bad_driver(d, "non-32-bit write to offset %u (%#x)", - off, getreg(eip)); - return; - } - memcpy((char *)d->mmio + off, &val, 4); - return; - -write_through16: - if (mask != 0xFFFF) - bad_driver(d, "non-16-bit write to offset %u (%#x)", - off, getreg(eip)); - memcpy((char *)d->mmio + off, &val, 2); - return; - -write_through8: - if (mask != 0xFF) - bad_driver(d, "non-8-bit write to offset %u (%#x)", - off, getreg(eip)); - memcpy((char *)d->mmio + off, &val, 1); - return; -} - -static u32 emulate_mmio_read(struct device *d, u32 off, u32 mask) -{ - u8 isr; - u32 val = 0; - - switch (off) { - case offsetof(struct virtio_pci_mmio, cfg.device_feature_select): - case offsetof(struct virtio_pci_mmio, cfg.device_feature): - case offsetof(struct virtio_pci_mmio, cfg.guest_feature_select): - case offsetof(struct virtio_pci_mmio, cfg.guest_feature): - /* - * 3.1.1: - * - * The driver MUST follow this sequence to initialize a device: - *... - * - Set the DRIVER status bit: the guest OS knows how - * to drive the device. - * - Read device feature bits, and write the subset - * of feature bits understood by the OS and driver - * to the device. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) - bad_driver(d, - "feature read before VIRTIO_CONFIG_S_DRIVER"); - goto read_through32; - case offsetof(struct virtio_pci_mmio, cfg.msix_config): - bad_driver(d, "read of msix_config"); - case offsetof(struct virtio_pci_mmio, cfg.num_queues): - goto read_through16; - case offsetof(struct virtio_pci_mmio, cfg.device_status): - /* As they did read, any write of FEATURES_OK is now fine. */ - d->wrote_features_ok = false; - goto read_through8; - case offsetof(struct virtio_pci_mmio, cfg.config_generation): - /* - * 4.1.4.3.1: - * - * The device MUST present a changed config_generation after - * the driver has read a device-specific configuration value - * which has changed since any part of the device-specific - * configuration was last read. - * - * This is simple: none of our devices change config, so this - * is always 0. - */ - goto read_through8; - case offsetof(struct virtio_pci_mmio, notify): - /* - * 3.1.1: - * - * The driver MUST NOT notify the device before setting - * DRIVER_OK. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER_OK)) - bad_driver(d, "notify before VIRTIO_CONFIG_S_DRIVER_OK"); - goto read_through16; - case offsetof(struct virtio_pci_mmio, isr): - if (mask != 0xFF) - bad_driver(d, "non-8-bit read from offset %u (%#x)", - off, getreg(eip)); - isr = d->mmio->isr; - /* - * 4.1.4.5.1: - * - * The device MUST reset ISR status to 0 on driver read. - */ - d->mmio->isr = 0; - return isr; - case offsetof(struct virtio_pci_mmio, padding): - bad_driver(d, "read from padding (%#x)", getreg(eip)); - default: - /* Read from device config space, beware unaligned overflow */ - if (off > d->mmio_size - 4) - bad_driver(d, "read past end (%#x)", getreg(eip)); - - /* - * 3.1.1: - * The driver MUST follow this sequence to initialize a device: - *... - * 3. Set the DRIVER status bit: the guest OS knows how to - * drive the device. - * 4. Read device feature bits, and write the subset of - * feature bits understood by the OS and driver to the - * device. During this step the driver MAY read (but MUST NOT - * write) the device-specific configuration fields to check - * that it can support the device before accepting it. - */ - if (!(d->mmio->cfg.device_status & VIRTIO_CONFIG_S_DRIVER)) - bad_driver(d, - "config read before VIRTIO_CONFIG_S_DRIVER"); - - if (mask == 0xFFFFFFFF) - goto read_through32; - else if (mask == 0xFFFF) - goto read_through16; - else - goto read_through8; - } - - /* - * 4.1.3.1: - * - * The driver MUST access each field using the “natural” access - * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses for - * 16-bit fields and 8-bit accesses for 8-bit fields. - */ -read_through32: - if (mask != 0xFFFFFFFF) - bad_driver(d, "non-32-bit read to offset %u (%#x)", - off, getreg(eip)); - memcpy(&val, (char *)d->mmio + off, 4); - return val; - -read_through16: - if (mask != 0xFFFF) - bad_driver(d, "non-16-bit read to offset %u (%#x)", - off, getreg(eip)); - memcpy(&val, (char *)d->mmio + off, 2); - return val; - -read_through8: - if (mask != 0xFF) - bad_driver(d, "non-8-bit read to offset %u (%#x)", - off, getreg(eip)); - memcpy(&val, (char *)d->mmio + off, 1); - return val; -} - -static void emulate_mmio(unsigned long paddr, const u8 *insn) -{ - u32 val, off, mask = 0xFFFFFFFF, insnlen = 0; - struct device *d = find_mmio_region(paddr, &off); - unsigned long args[] = { LHREQ_TRAP, 14 }; - - if (!d) { - warnx("MMIO touching %#08lx (not a device)", paddr); - goto reinject; - } - - /* Prefix makes it a 16 bit op */ - if (insn[0] == 0x66) { - mask = 0xFFFF; - insnlen++; - } - - /* iowrite */ - if (insn[insnlen] == 0x89) { - /* Next byte is r/m byte: bits 3-5 are register. */ - val = getreg_num((insn[insnlen+1] >> 3) & 0x7, mask); - emulate_mmio_write(d, off, val, mask); - insnlen += 2 + insn_displacement_len(insn[insnlen+1]); - } else if (insn[insnlen] == 0x8b) { /* ioread */ - /* Next byte is r/m byte: bits 3-5 are register. */ - val = emulate_mmio_read(d, off, mask); - setreg_num((insn[insnlen+1] >> 3) & 0x7, val, mask); - insnlen += 2 + insn_displacement_len(insn[insnlen+1]); - } else if (insn[0] == 0x88) { /* 8-bit iowrite */ - mask = 0xff; - /* Next byte is r/m byte: bits 3-5 are register. */ - val = getreg_num((insn[1] >> 3) & 0x7, mask); - emulate_mmio_write(d, off, val, mask); - insnlen = 2 + insn_displacement_len(insn[1]); - } else if (insn[0] == 0x8a) { /* 8-bit ioread */ - mask = 0xff; - val = emulate_mmio_read(d, off, mask); - setreg_num((insn[1] >> 3) & 0x7, val, mask); - insnlen = 2 + insn_displacement_len(insn[1]); - } else { - warnx("Unknown MMIO instruction touching %#08lx:" - " %02x %02x %02x %02x at %u", - paddr, insn[0], insn[1], insn[2], insn[3], getreg(eip)); - reinject: - /* Inject trap into Guest. */ - if (write(lguest_fd, args, sizeof(args)) < 0) - err(1, "Reinjecting trap 14 for fault at %#x", - getreg(eip)); - return; - } - - /* Finally, we've "done" the instruction, so move past it. */ - setreg(eip, getreg(eip) + insnlen); -} - -/*L:190 - * Device Setup - * - * All devices need a descriptor so the Guest knows it exists, and a "struct - * device" so the Launcher can keep track of it. We have common helper - * routines to allocate and manage them. - */ -static void add_pci_virtqueue(struct device *dev, - void (*service)(struct virtqueue *), - const char *name) -{ - struct virtqueue **i, *vq = malloc(sizeof(*vq)); - - /* Initialize the virtqueue */ - vq->next = NULL; - vq->last_avail_idx = 0; - vq->dev = dev; - vq->name = name; - - /* - * This is the routine the service thread will run, and its Process ID - * once it's running. - */ - vq->service = service; - vq->thread = (pid_t)-1; - - /* Initialize the configuration. */ - reset_vq_pci_config(vq); - vq->pci_config.queue_notify_off = 0; - - /* Add one to the number of queues */ - vq->dev->mmio->cfg.num_queues++; - - /* - * Add to tail of list, so dev->vq is first vq, dev->vq->next is - * second. - */ - for (i = &dev->vq; *i; i = &(*i)->next); - *i = vq; -} - -/* The Guest accesses the feature bits via the PCI common config MMIO region */ -static void add_pci_feature(struct device *dev, unsigned bit) -{ - dev->features |= (1ULL << bit); -} - -/* For devices with no config. */ -static void no_device_config(struct device *dev) -{ - dev->mmio_addr = get_mmio_region(dev->mmio_size); - - dev->config.bar[0] = dev->mmio_addr; - /* Bottom 4 bits must be zero */ - assert(~(dev->config.bar[0] & 0xF)); -} - -/* This puts the device config into BAR0 */ -static void set_device_config(struct device *dev, const void *conf, size_t len) -{ - /* Set up BAR 0 */ - dev->mmio_size += len; - dev->mmio = realloc(dev->mmio, dev->mmio_size); - memcpy(dev->mmio + 1, conf, len); - - /* - * 4.1.4.6: - * - * The device MUST present at least one VIRTIO_PCI_CAP_DEVICE_CFG - * capability for any device type which has a device-specific - * configuration. - */ - /* Hook up device cfg */ - dev->config.cfg_access.cap.cap_next - = offsetof(struct pci_config, device); - - /* - * 4.1.4.6.1: - * - * The offset for the device-specific configuration MUST be 4-byte - * aligned. - */ - assert(dev->config.cfg_access.cap.cap_next % 4 == 0); - - /* Fix up device cfg field length. */ - dev->config.device.length = len; - - /* The rest is the same as the no-config case */ - no_device_config(dev); -} - -static void init_cap(struct virtio_pci_cap *cap, size_t caplen, int type, - size_t bar_offset, size_t bar_bytes, u8 next) -{ - cap->cap_vndr = PCI_CAP_ID_VNDR; - cap->cap_next = next; - cap->cap_len = caplen; - cap->cfg_type = type; - cap->bar = 0; - memset(cap->padding, 0, sizeof(cap->padding)); - cap->offset = bar_offset; - cap->length = bar_bytes; -} - -/* - * This sets up the pci_config structure, as defined in the virtio 1.0 - * standard (and PCI standard). - */ -static void init_pci_config(struct pci_config *pci, u16 type, - u8 class, u8 subclass) -{ - size_t bar_offset, bar_len; - - /* - * 4.1.4.4.1: - * - * The device MUST either present notify_off_multiplier as an even - * power of 2, or present notify_off_multiplier as 0. - * - * 2.1.2: - * - * The device MUST initialize device status to 0 upon reset. - */ - memset(pci, 0, sizeof(*pci)); - - /* 4.1.2.1: Devices MUST have the PCI Vendor ID 0x1AF4 */ - pci->vendor_id = 0x1AF4; - /* 4.1.2.1: ... PCI Device ID calculated by adding 0x1040 ... */ - pci->device_id = 0x1040 + type; - - /* - * PCI have specific codes for different types of devices. - * Linux doesn't care, but it's a good clue for people looking - * at the device. - */ - pci->class = class; - pci->subclass = subclass; - - /* - * 4.1.2.1: - * - * Non-transitional devices SHOULD have a PCI Revision ID of 1 or - * higher - */ - pci->revid = 1; - - /* - * 4.1.2.1: - * - * Non-transitional devices SHOULD have a PCI Subsystem Device ID of - * 0x40 or higher. - */ - pci->subsystem_device_id = 0x40; - - /* We use our dummy interrupt controller, and irq_line is the irq */ - pci->irq_line = devices.next_irq++; - pci->irq_pin = 0; - - /* Support for extended capabilities. */ - pci->status = (1 << 4); - - /* Link them in. */ - /* - * 4.1.4.3.1: - * - * The device MUST present at least one common configuration - * capability. - */ - pci->capabilities = offsetof(struct pci_config, common); - - /* 4.1.4.3.1 ... offset MUST be 4-byte aligned. */ - assert(pci->capabilities % 4 == 0); - - bar_offset = offsetof(struct virtio_pci_mmio, cfg); - bar_len = sizeof(((struct virtio_pci_mmio *)0)->cfg); - init_cap(&pci->common, sizeof(pci->common), VIRTIO_PCI_CAP_COMMON_CFG, - bar_offset, bar_len, - offsetof(struct pci_config, notify)); - - /* - * 4.1.4.4.1: - * - * The device MUST present at least one notification capability. - */ - bar_offset += bar_len; - bar_len = sizeof(((struct virtio_pci_mmio *)0)->notify); - - /* - * 4.1.4.4.1: - * - * The cap.offset MUST be 2-byte aligned. - */ - assert(pci->common.cap_next % 2 == 0); - - /* FIXME: Use a non-zero notify_off, for per-queue notification? */ - /* - * 4.1.4.4.1: - * - * The value cap.length presented by the device MUST be at least 2 and - * MUST be large enough to support queue notification offsets for all - * supported queues in all possible configurations. - */ - assert(bar_len >= 2); - - init_cap(&pci->notify.cap, sizeof(pci->notify), - VIRTIO_PCI_CAP_NOTIFY_CFG, - bar_offset, bar_len, - offsetof(struct pci_config, isr)); - - bar_offset += bar_len; - bar_len = sizeof(((struct virtio_pci_mmio *)0)->isr); - /* - * 4.1.4.5.1: - * - * The device MUST present at least one VIRTIO_PCI_CAP_ISR_CFG - * capability. - */ - init_cap(&pci->isr, sizeof(pci->isr), - VIRTIO_PCI_CAP_ISR_CFG, - bar_offset, bar_len, - offsetof(struct pci_config, cfg_access)); - - /* - * 4.1.4.7.1: - * - * The device MUST present at least one VIRTIO_PCI_CAP_PCI_CFG - * capability. - */ - /* This doesn't have any presence in the BAR */ - init_cap(&pci->cfg_access.cap, sizeof(pci->cfg_access), - VIRTIO_PCI_CAP_PCI_CFG, - 0, 0, 0); - - bar_offset += bar_len + sizeof(((struct virtio_pci_mmio *)0)->padding); - assert(bar_offset == sizeof(struct virtio_pci_mmio)); - - /* - * This gets sewn in and length set in set_device_config(). - * Some devices don't have a device configuration interface, so - * we never expose this if we don't call set_device_config(). - */ - init_cap(&pci->device, sizeof(pci->device), VIRTIO_PCI_CAP_DEVICE_CFG, - bar_offset, 0, 0); -} - -/* - * This routine does all the creation and setup of a new device, but we don't - * actually place the MMIO region until we know the size (if any) of the - * device-specific config. And we don't actually start the service threads - * until later. - * - * See what I mean about userspace being boring? - */ -static struct device *new_pci_device(const char *name, u16 type, - u8 class, u8 subclass) -{ - struct device *dev = malloc(sizeof(*dev)); - - /* Now we populate the fields one at a time. */ - dev->name = name; - dev->vq = NULL; - dev->running = false; - dev->wrote_features_ok = false; - dev->mmio_size = sizeof(struct virtio_pci_mmio); - dev->mmio = calloc(1, dev->mmio_size); - dev->features = (u64)1 << VIRTIO_F_VERSION_1; - dev->features_accepted = 0; - - if (devices.device_num + 1 >= MAX_PCI_DEVICES) - errx(1, "Can only handle 31 PCI devices"); - - init_pci_config(&dev->config, type, class, subclass); - assert(!devices.pci[devices.device_num+1]); - devices.pci[++devices.device_num] = dev; - - return dev; -} - -/* - * Our first setup routine is the console. It's a fairly simple device, but - * UNIX tty handling makes it uglier than it could be. - */ -static void setup_console(void) -{ - struct device *dev; - struct virtio_console_config conf; - - /* If we can save the initial standard input settings... */ - if (tcgetattr(STDIN_FILENO, &orig_term) == 0) { - struct termios term = orig_term; - /* - * Then we turn off echo, line buffering and ^C etc: We want a - * raw input stream to the Guest. - */ - term.c_lflag &= ~(ISIG|ICANON|ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &term); - } - - dev = new_pci_device("console", VIRTIO_ID_CONSOLE, 0x07, 0x00); - - /* We store the console state in dev->priv, and initialize it. */ - dev->priv = malloc(sizeof(struct console_abort)); - ((struct console_abort *)dev->priv)->count = 0; - - /* - * The console needs two virtqueues: the input then the output. When - * they put something the input queue, we make sure we're listening to - * stdin. When they put something in the output queue, we write it to - * stdout. - */ - add_pci_virtqueue(dev, console_input, "input"); - add_pci_virtqueue(dev, console_output, "output"); - - /* We need a configuration area for the emerg_wr early writes. */ - add_pci_feature(dev, VIRTIO_CONSOLE_F_EMERG_WRITE); - set_device_config(dev, &conf, sizeof(conf)); - - verbose("device %u: console\n", devices.device_num); -} -/*:*/ - -/*M:010 - * Inter-guest networking is an interesting area. Simplest is to have a - * --sharenet= option which opens or creates a named pipe. This can be - * used to send packets to another guest in a 1:1 manner. - * - * More sophisticated is to use one of the tools developed for project like UML - * to do networking. - * - * Faster is to do virtio bonding in kernel. Doing this 1:1 would be - * completely generic ("here's my vring, attach to your vring") and would work - * for any traffic. Of course, namespace and permissions issues need to be - * dealt with. A more sophisticated "multi-channel" virtio_net.c could hide - * multiple inter-guest channels behind one interface, although it would - * require some manner of hotplugging new virtio channels. - * - * Finally, we could use a virtio network switch in the kernel, ie. vhost. -:*/ - -static u32 str2ip(const char *ipaddr) -{ - unsigned int b[4]; - - if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4) - errx(1, "Failed to parse IP address '%s'", ipaddr); - return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; -} - -static void str2mac(const char *macaddr, unsigned char mac[6]) -{ - unsigned int m[6]; - if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x", - &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6) - errx(1, "Failed to parse mac address '%s'", macaddr); - mac[0] = m[0]; - mac[1] = m[1]; - mac[2] = m[2]; - mac[3] = m[3]; - mac[4] = m[4]; - mac[5] = m[5]; -} - -/* - * This code is "adapted" from libbridge: it attaches the Host end of the - * network device to the bridge device specified by the command line. - * - * This is yet another James Morris contribution (I'm an IP-level guy, so I - * dislike bridging), and I just try not to break it. - */ -static void add_to_bridge(int fd, const char *if_name, const char *br_name) -{ - int ifidx; - struct ifreq ifr; - - if (!*br_name) - errx(1, "must specify bridge name"); - - ifidx = if_nametoindex(if_name); - if (!ifidx) - errx(1, "interface %s does not exist!", if_name); - - strncpy(ifr.ifr_name, br_name, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; - ifr.ifr_ifindex = ifidx; - if (ioctl(fd, SIOCBRADDIF, &ifr) < 0) - err(1, "can't add %s to bridge %s", if_name, br_name); -} - -/* - * This sets up the Host end of the network device with an IP address, brings - * it up so packets will flow, the copies the MAC address into the hwaddr - * pointer. - */ -static void configure_device(int fd, const char *tapif, u32 ipaddr) -{ - struct ifreq ifr; - struct sockaddr_in sin; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, tapif); - - /* Don't read these incantations. Just cut & paste them like I did! */ - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(ipaddr); - memcpy(&ifr.ifr_addr, &sin, sizeof(sin)); - if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) - err(1, "Setting %s interface address", tapif); - ifr.ifr_flags = IFF_UP; - if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) - err(1, "Bringing interface %s up", tapif); -} - -static int get_tun_device(char tapif[IFNAMSIZ]) -{ - struct ifreq ifr; - int vnet_hdr_sz; - int netfd; - - /* Start with this zeroed. Messy but sure. */ - memset(&ifr, 0, sizeof(ifr)); - - /* - * We open the /dev/net/tun device and tell it we want a tap device. A - * tap device is like a tun device, only somehow different. To tell - * the truth, I completely blundered my way through this code, but it - * works now! - */ - netfd = open_or_die("/dev/net/tun", O_RDWR); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; - strcpy(ifr.ifr_name, "tap%d"); - if (ioctl(netfd, TUNSETIFF, &ifr) != 0) - err(1, "configuring /dev/net/tun"); - - if (ioctl(netfd, TUNSETOFFLOAD, - TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0) - err(1, "Could not set features for tun device"); - - /* - * We don't need checksums calculated for packets coming in this - * device: trust us! - */ - ioctl(netfd, TUNSETNOCSUM, 1); - - /* - * In virtio before 1.0 (aka legacy virtio), we added a 16-bit - * field at the end of the network header iff - * VIRTIO_NET_F_MRG_RXBUF was negotiated. For virtio 1.0, - * that became the norm, but we need to tell the tun device - * about our expanded header (which is called - * virtio_net_hdr_mrg_rxbuf in the legacy system). - */ - vnet_hdr_sz = sizeof(struct virtio_net_hdr_v1); - if (ioctl(netfd, TUNSETVNETHDRSZ, &vnet_hdr_sz) != 0) - err(1, "Setting tun header size to %u", vnet_hdr_sz); - - memcpy(tapif, ifr.ifr_name, IFNAMSIZ); - return netfd; -} - -/*L:195 - * Our network is a Host<->Guest network. This can either use bridging or - * routing, but the principle is the same: it uses the "tun" device to inject - * packets into the Host as if they came in from a normal network card. We - * just shunt packets between the Guest and the tun device. - */ -static void setup_tun_net(char *arg) -{ - struct device *dev; - struct net_info *net_info = malloc(sizeof(*net_info)); - int ipfd; - u32 ip = INADDR_ANY; - bool bridging = false; - char tapif[IFNAMSIZ], *p; - struct virtio_net_config conf; - - net_info->tunfd = get_tun_device(tapif); - - /* First we create a new network device. */ - dev = new_pci_device("net", VIRTIO_ID_NET, 0x02, 0x00); - dev->priv = net_info; - - /* Network devices need a recv and a send queue, just like console. */ - add_pci_virtqueue(dev, net_input, "rx"); - add_pci_virtqueue(dev, net_output, "tx"); - - /* - * We need a socket to perform the magic network ioctls to bring up the - * tap interface, connect to the bridge etc. Any socket will do! - */ - ipfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - if (ipfd < 0) - err(1, "opening IP socket"); - - /* If the command line was --tunnet=bridge: do bridging. */ - if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) { - arg += strlen(BRIDGE_PFX); - bridging = true; - } - - /* A mac address may follow the bridge name or IP address */ - p = strchr(arg, ':'); - if (p) { - str2mac(p+1, conf.mac); - add_pci_feature(dev, VIRTIO_NET_F_MAC); - *p = '\0'; - } - - /* arg is now either an IP address or a bridge name */ - if (bridging) - add_to_bridge(ipfd, tapif, arg); - else - ip = str2ip(arg); - - /* Set up the tun device. */ - configure_device(ipfd, tapif, ip); - - /* Expect Guest to handle everything except UFO */ - add_pci_feature(dev, VIRTIO_NET_F_CSUM); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_CSUM); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO4); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO6); - add_pci_feature(dev, VIRTIO_NET_F_GUEST_ECN); - add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO4); - add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO6); - add_pci_feature(dev, VIRTIO_NET_F_HOST_ECN); - /* We handle indirect ring entries */ - add_pci_feature(dev, VIRTIO_RING_F_INDIRECT_DESC); - set_device_config(dev, &conf, sizeof(conf)); - - /* We don't need the socket any more; setup is done. */ - close(ipfd); - - if (bridging) - verbose("device %u: tun %s attached to bridge: %s\n", - devices.device_num, tapif, arg); - else - verbose("device %u: tun %s: %s\n", - devices.device_num, tapif, arg); -} -/*:*/ - -/* This hangs off device->priv. */ -struct vblk_info { - /* The size of the file. */ - off64_t len; - - /* The file descriptor for the file. */ - int fd; - -}; - -/*L:210 - * The Disk - * - * The disk only has one virtqueue, so it only has one thread. It is really - * simple: the Guest asks for a block number and we read or write that position - * in the file. - * - * Before we serviced each virtqueue in a separate thread, that was unacceptably - * slow: the Guest waits until the read is finished before running anything - * else, even if it could have been doing useful work. - * - * We could have used async I/O, except it's reputed to suck so hard that - * characters actually go missing from your code when you try to use it. - */ -static void blk_request(struct virtqueue *vq) -{ - struct vblk_info *vblk = vq->dev->priv; - unsigned int head, out_num, in_num, wlen; - int ret, i; - u8 *in; - struct virtio_blk_outhdr out; - struct iovec iov[vq->vring.num]; - off64_t off; - - /* - * Get the next request, where we normally wait. It triggers the - * interrupt to acknowledge previously serviced requests (if any). - */ - head = wait_for_vq_desc(vq, iov, &out_num, &in_num); - - /* Copy the output header from the front of the iov (adjusts iov) */ - iov_consume(vq->dev, iov, out_num, &out, sizeof(out)); - - /* Find and trim end of iov input array, for our status byte. */ - in = NULL; - for (i = out_num + in_num - 1; i >= out_num; i--) { - if (iov[i].iov_len > 0) { - in = iov[i].iov_base + iov[i].iov_len - 1; - iov[i].iov_len--; - break; - } - } - if (!in) - bad_driver_vq(vq, "Bad virtblk cmd with no room for status"); - - /* - * For historical reasons, block operations are expressed in 512 byte - * "sectors". - */ - off = out.sector * 512; - - if (out.type & VIRTIO_BLK_T_OUT) { - /* - * Write - * - * Move to the right location in the block file. This can fail - * if they try to write past end. - */ - if (lseek64(vblk->fd, off, SEEK_SET) != off) - err(1, "Bad seek to sector %llu", out.sector); - - ret = writev(vblk->fd, iov, out_num); - verbose("WRITE to sector %llu: %i\n", out.sector, ret); - - /* - * Grr... Now we know how long the descriptor they sent was, we - * make sure they didn't try to write over the end of the block - * file (possibly extending it). - */ - if (ret > 0 && off + ret > vblk->len) { - /* Trim it back to the correct length */ - ftruncate64(vblk->fd, vblk->len); - /* Die, bad Guest, die. */ - bad_driver_vq(vq, "Write past end %llu+%u", off, ret); - } - - wlen = sizeof(*in); - *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); - } else if (out.type & VIRTIO_BLK_T_FLUSH) { - /* Flush */ - ret = fdatasync(vblk->fd); - verbose("FLUSH fdatasync: %i\n", ret); - wlen = sizeof(*in); - *in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR); - } else { - /* - * Read - * - * Move to the right location in the block file. This can fail - * if they try to read past end. - */ - if (lseek64(vblk->fd, off, SEEK_SET) != off) - err(1, "Bad seek to sector %llu", out.sector); - - ret = readv(vblk->fd, iov + out_num, in_num); - if (ret >= 0) { - wlen = sizeof(*in) + ret; - *in = VIRTIO_BLK_S_OK; - } else { - wlen = sizeof(*in); - *in = VIRTIO_BLK_S_IOERR; - } - } - - /* Finished that request. */ - add_used(vq, head, wlen); -} - -/*L:198 This actually sets up a virtual block device. */ -static void setup_block_file(const char *filename) -{ - struct device *dev; - struct vblk_info *vblk; - struct virtio_blk_config conf; - - /* Create the device. */ - dev = new_pci_device("block", VIRTIO_ID_BLOCK, 0x01, 0x80); - - /* The device has one virtqueue, where the Guest places requests. */ - add_pci_virtqueue(dev, blk_request, "request"); - - /* Allocate the room for our own bookkeeping */ - vblk = dev->priv = malloc(sizeof(*vblk)); - - /* First we open the file and store the length. */ - vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE); - vblk->len = lseek64(vblk->fd, 0, SEEK_END); - - /* Tell Guest how many sectors this device has. */ - conf.capacity = cpu_to_le64(vblk->len / 512); - - /* - * Tell Guest not to put in too many descriptors at once: two are used - * for the in and out elements. - */ - add_pci_feature(dev, VIRTIO_BLK_F_SEG_MAX); - conf.seg_max = cpu_to_le32(VIRTQUEUE_NUM - 2); - - set_device_config(dev, &conf, sizeof(struct virtio_blk_config)); - - verbose("device %u: virtblock %llu sectors\n", - devices.device_num, le64_to_cpu(conf.capacity)); -} - -/*L:211 - * Our random number generator device reads from /dev/urandom into the Guest's - * input buffers. The usual case is that the Guest doesn't want random numbers - * and so has no buffers although /dev/urandom is still readable, whereas - * console is the reverse. - * - * The same logic applies, however. - */ -struct rng_info { - int rfd; -}; - -static void rng_input(struct virtqueue *vq) -{ - int len; - unsigned int head, in_num, out_num, totlen = 0; - struct rng_info *rng_info = vq->dev->priv; - struct iovec iov[vq->vring.num]; - - /* First we need a buffer from the Guests's virtqueue. */ - head = wait_for_vq_desc(vq, iov, &out_num, &in_num); - if (out_num) - bad_driver_vq(vq, "Output buffers in rng?"); - - /* - * Just like the console write, we loop to cover the whole iovec. - * In this case, short reads actually happen quite a bit. - */ - while (!iov_empty(iov, in_num)) { - len = readv(rng_info->rfd, iov, in_num); - if (len <= 0) - err(1, "Read from /dev/urandom gave %i", len); - iov_consume(vq->dev, iov, in_num, NULL, len); - totlen += len; - } - - /* Tell the Guest about the new input. */ - add_used(vq, head, totlen); -} - -/*L:199 - * This creates a "hardware" random number device for the Guest. - */ -static void setup_rng(void) -{ - struct device *dev; - struct rng_info *rng_info = malloc(sizeof(*rng_info)); - - /* Our device's private info simply contains the /dev/urandom fd. */ - rng_info->rfd = open_or_die("/dev/urandom", O_RDONLY); - - /* Create the new device. */ - dev = new_pci_device("rng", VIRTIO_ID_RNG, 0xff, 0); - dev->priv = rng_info; - - /* The device has one virtqueue, where the Guest places inbufs. */ - add_pci_virtqueue(dev, rng_input, "input"); - - /* We don't have any configuration space */ - no_device_config(dev); - - verbose("device %u: rng\n", devices.device_num); -} -/* That's the end of device setup. */ - -/*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */ -static void __attribute__((noreturn)) restart_guest(void) -{ - unsigned int i; - - /* - * Since we don't track all open fds, we simply close everything beyond - * stderr. - */ - for (i = 3; i < FD_SETSIZE; i++) - close(i); - - /* Reset all the devices (kills all threads). */ - cleanup_devices(); - - execv(main_args[0], main_args); - err(1, "Could not exec %s", main_args[0]); -} - -/*L:220 - * Finally we reach the core of the Launcher which runs the Guest, serves - * its input and output, and finally, lays it to rest. - */ -static void __attribute__((noreturn)) run_guest(void) -{ - for (;;) { - struct lguest_pending notify; - int readval; - - /* We read from the /dev/lguest device to run the Guest. */ - readval = pread(lguest_fd, ¬ify, sizeof(notify), cpu_id); - if (readval == sizeof(notify)) { - if (notify.trap == 13) { - verbose("Emulating instruction at %#x\n", - getreg(eip)); - emulate_insn(notify.insn); - } else if (notify.trap == 14) { - verbose("Emulating MMIO at %#x\n", - getreg(eip)); - emulate_mmio(notify.addr, notify.insn); - } else - errx(1, "Unknown trap %i addr %#08x\n", - notify.trap, notify.addr); - /* ENOENT means the Guest died. Reading tells us why. */ - } else if (errno == ENOENT) { - char reason[1024] = { 0 }; - pread(lguest_fd, reason, sizeof(reason)-1, cpu_id); - errx(1, "%s", reason); - /* ERESTART means that we need to reboot the guest */ - } else if (errno == ERESTART) { - restart_guest(); - /* Anything else means a bug or incompatible change. */ - } else - err(1, "Running guest failed"); - } -} -/*L:240 - * This is the end of the Launcher. The good news: we are over halfway - * through! The bad news: the most fiendish part of the code still lies ahead - * of us. - * - * Are you ready? Take a deep breath and join me in the core of the Host, in - * "make Host". -:*/ - -static struct option opts[] = { - { "verbose", 0, NULL, 'v' }, - { "tunnet", 1, NULL, 't' }, - { "block", 1, NULL, 'b' }, - { "rng", 0, NULL, 'r' }, - { "initrd", 1, NULL, 'i' }, - { "username", 1, NULL, 'u' }, - { "chroot", 1, NULL, 'c' }, - { NULL }, -}; -static void usage(void) -{ - errx(1, "Usage: lguest [--verbose] " - "[--tunnet=(:|bridge::)\n" - "|--block=|--initrd=]...\n" - " vmlinux [args...]"); -} - -/*L:105 The main routine is where the real work begins: */ -int main(int argc, char *argv[]) -{ - /* Memory, code startpoint and size of the (optional) initrd. */ - unsigned long mem = 0, start, initrd_size = 0; - /* Two temporaries. */ - int i, c; - /* The boot information for the Guest. */ - struct boot_params *boot; - /* If they specify an initrd file to load. */ - const char *initrd_name = NULL; - - /* Password structure for initgroups/setres[gu]id */ - struct passwd *user_details = NULL; - - /* Directory to chroot to */ - char *chroot_path = NULL; - - /* Save the args: we "reboot" by execing ourselves again. */ - main_args = argv; - - /* - * First we initialize the device list. We remember next interrupt - * number to use for devices (1: remember that 0 is used by the timer). - */ - devices.next_irq = 1; - - /* We're CPU 0. In fact, that's the only CPU possible right now. */ - cpu_id = 0; - - /* - * We need to know how much memory so we can set up the device - * descriptor and memory pages for the devices as we parse the command - * line. So we quickly look through the arguments to find the amount - * of memory now. - */ - for (i = 1; i < argc; i++) { - if (argv[i][0] != '-') { - mem = atoi(argv[i]) * 1024 * 1024; - /* - * We start by mapping anonymous pages over all of - * guest-physical memory range. This fills it with 0, - * and ensures that the Guest won't be killed when it - * tries to access it. - */ - guest_base = map_zeroed_pages(mem / getpagesize() - + DEVICE_PAGES); - guest_limit = mem; - guest_max = guest_mmio = mem + DEVICE_PAGES*getpagesize(); - break; - } - } - - /* If we exit via err(), this kills all the threads, restores tty. */ - atexit(cleanup_devices); - - /* We always have a console device, and it's always device 1. */ - setup_console(); - - /* The options are fairly straight-forward */ - while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) { - switch (c) { - case 'v': - verbose = true; - break; - case 't': - setup_tun_net(optarg); - break; - case 'b': - setup_block_file(optarg); - break; - case 'r': - setup_rng(); - break; - case 'i': - initrd_name = optarg; - break; - case 'u': - user_details = getpwnam(optarg); - if (!user_details) - err(1, "getpwnam failed, incorrect username?"); - break; - case 'c': - chroot_path = optarg; - break; - default: - warnx("Unknown argument %s", argv[optind]); - usage(); - } - } - /* - * After the other arguments we expect memory and kernel image name, - * followed by command line arguments for the kernel. - */ - if (optind + 2 > argc) - usage(); - - verbose("Guest base is at %p\n", guest_base); - - /* Initialize the (fake) PCI host bridge device. */ - init_pci_host_bridge(); - - /* Now we load the kernel */ - start = load_kernel(open_or_die(argv[optind+1], O_RDONLY)); - - /* Boot information is stashed at physical address 0 */ - boot = from_guest_phys(0); - - /* Map the initrd image if requested (at top of physical memory) */ - if (initrd_name) { - initrd_size = load_initrd(initrd_name, mem); - /* - * These are the location in the Linux boot header where the - * start and size of the initrd are expected to be found. - */ - boot->hdr.ramdisk_image = mem - initrd_size; - boot->hdr.ramdisk_size = initrd_size; - /* The bootloader type 0xFF means "unknown"; that's OK. */ - boot->hdr.type_of_loader = 0xFF; - } - - /* - * The Linux boot header contains an "E820" memory map: ours is a - * simple, single region. - */ - boot->e820_entries = 1; - boot->e820_table[0] = ((struct e820_entry) { 0, mem, E820_TYPE_RAM }); - /* - * The boot header contains a command line pointer: we put the command - * line after the boot header. - */ - boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1); - /* We use a simple helper to copy the arguments separated by spaces. */ - concat((char *)(boot + 1), argv+optind+2); - - /* Set kernel alignment to 16M (CONFIG_PHYSICAL_ALIGN) */ - boot->hdr.kernel_alignment = 0x1000000; - - /* Boot protocol version: 2.07 supports the fields for lguest. */ - boot->hdr.version = 0x207; - - /* X86_SUBARCH_LGUEST tells the Guest it's an lguest. */ - boot->hdr.hardware_subarch = X86_SUBARCH_LGUEST; - - /* Tell the entry path not to try to reload segment registers. */ - boot->hdr.loadflags |= KEEP_SEGMENTS; - - /* We don't support tboot: */ - boot->tboot_addr = 0; - - /* Ensure this is 0 to prevent APM from loading: */ - boot->apm_bios_info.version = 0; - - /* We tell the kernel to initialize the Guest. */ - tell_kernel(start); - - /* Ensure that we terminate if a device-servicing child dies. */ - signal(SIGCHLD, kill_launcher); - - /* If requested, chroot to a directory */ - if (chroot_path) { - if (chroot(chroot_path) != 0) - err(1, "chroot(\"%s\") failed", chroot_path); - - if (chdir("/") != 0) - err(1, "chdir(\"/\") failed"); - - verbose("chroot done\n"); - } - - /* If requested, drop privileges */ - if (user_details) { - uid_t u; - gid_t g; - - u = user_details->pw_uid; - g = user_details->pw_gid; - - if (initgroups(user_details->pw_name, g) != 0) - err(1, "initgroups failed"); - - if (setresgid(g, g, g) != 0) - err(1, "setresgid failed"); - - if (setresuid(u, u, u) != 0) - err(1, "setresuid failed"); - - verbose("Dropping privileges completed\n"); - } - - /* Finally, run the Guest. This doesn't return. */ - run_guest(); -} -/*:*/ - -/*M:999 - * Mastery is done: you now know everything I do. - * - * But surely you have seen code, features and bugs in your wanderings which - * you now yearn to attack? That is the real game, and I look forward to you - * patching and forking lguest into the Your-Name-Here-visor. - * - * Farewell, and good coding! - * Rusty Russell. - */ diff --git a/tools/lguest/lguest.txt b/tools/lguest/lguest.txt deleted file mode 100644 index 06e1f4649511..000000000000 --- a/tools/lguest/lguest.txt +++ /dev/null @@ -1,125 +0,0 @@ - __ - (___()'`; Rusty's Remarkably Unreliable Guide to Lguest - /, /` - or, A Young Coder's Illustrated Hypervisor - \\"--\\ http://lguest.ozlabs.org - -Lguest is designed to be a minimal 32-bit x86 hypervisor for the Linux kernel, -for Linux developers and users to experiment with virtualization with the -minimum of complexity. Nonetheless, it should have sufficient features to -make it useful for specific tasks, and, of course, you are encouraged to fork -and enhance it (see drivers/lguest/README). - -Features: - -- Kernel module which runs in a normal kernel. -- Simple I/O model for communication. -- Simple program to create new guests. -- Logo contains cute puppies: http://lguest.ozlabs.org - -Developer features: - -- Fun to hack on. -- No ABI: being tied to a specific kernel anyway, you can change anything. -- Many opportunities for improvement or feature implementation. - -Running Lguest: - -- The easiest way to run lguest is to use same kernel as guest and host. - You can configure them differently, but usually it's easiest not to. - - You will need to configure your kernel with the following options: - - "Processor type and features": - "Paravirtualized guest support" = Y - "Lguest guest support" = Y - "High Memory Support" = off/4GB - "Alignment value to which kernel should be aligned" = 0x100000 - (CONFIG_PARAVIRT=y, CONFIG_LGUEST_GUEST=y, CONFIG_HIGHMEM64G=n and - CONFIG_PHYSICAL_ALIGN=0x100000) - - "Device Drivers": - "Block devices" - "Virtio block driver" = M/Y - "Network device support" - "Universal TUN/TAP device driver support" = M/Y - "Virtio network driver" = M/Y - (CONFIG_VIRTIO_BLK=m, CONFIG_VIRTIO_NET=m and CONFIG_TUN=m) - - "Virtualization" - "Linux hypervisor example code" = M/Y - (CONFIG_LGUEST=m) - -- A tool called "lguest" is available in this directory: type "make" - to build it. If you didn't build your kernel in-tree, use "make - O=". - -- Create or find a root disk image. There are several useful ones - around, such as the xm-test tiny root image at - http://xm-test.xensource.com/ramdisks/initrd-1.1-i386.img - - For more serious work, I usually use a distribution ISO image and - install it under qemu, then make multiple copies: - - dd if=/dev/zero of=rootfile bs=1M count=2048 - qemu -cdrom image.iso -hda rootfile -net user -net nic -boot d - - Make sure that you install a getty on /dev/hvc0 if you want to log in on the - console! - -- "modprobe lg" if you built it as a module. - -- Run an lguest as root: - - tools/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 \ - --block=rootfile root=/dev/vda - - Explanation: - 64: the amount of memory to use, in MB. - - vmlinux: the kernel image found in the top of your build directory. You - can also use a standard bzImage. - - --tunnet=192.168.19.1: configures a "tap" device for networking with this - IP address. - - --block=rootfile: a file or block device which becomes /dev/vda - inside the guest. - - root=/dev/vda: this (and anything else on the command line) are - kernel boot parameters. - -- Configuring networking. I usually have the host masquerade, using - "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" and "echo 1 > - /proc/sys/net/ipv4/ip_forward". In this example, I would configure - eth0 inside the guest at 192.168.19.2. - - Another method is to bridge the tap device to an external interface - using --tunnet=bridge:, and perhaps run dhcp on the guest - to obtain an IP address. The bridge needs to be configured first: - this option simply adds the tap interface to it. - - A simple example on my system: - - ifconfig eth0 0.0.0.0 - brctl addbr lg0 - ifconfig lg0 up - brctl addif lg0 eth0 - dhclient lg0 - - Then use --tunnet=bridge:lg0 when launching the guest. - - See: - - http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge - - for general information on how to get bridging to work. - -- Random number generation. Using the --rng option will provide a - /dev/hwrng in the guest that will read from the host's /dev/random. - Use this option in conjunction with rng-tools (see ../hw_random.txt) - to provide entropy to the guest kernel's /dev/random. - -There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest - -Good luck! -Rusty Russell rusty@rustcorp.com.au. diff --git a/tools/lib/api/Makefile b/tools/lib/api/Makefile index eb6e0b36bfc1..a13e9c7f1fc5 100644 --- a/tools/lib/api/Makefile +++ b/tools/lib/api/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 include ../../scripts/Makefile.include include ../../scripts/utilities.mak # QUIET_CLEAN @@ -8,22 +9,28 @@ srctree := $(patsubst %/,%,$(dir $(srctree))) #$(info Determined 'srctree' to be $(srctree)) endif -CC = $(CROSS_COMPILE)gcc -AR = $(CROSS_COMPILE)ar -LD = $(CROSS_COMPILE)ld +CC ?= $(CROSS_COMPILE)gcc +AR ?= $(CROSS_COMPILE)ar +LD ?= $(CROSS_COMPILE)ld MAKEFLAGS += --no-print-directory LIBFILE = $(OUTPUT)libapi.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC +CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -fPIC -ifeq ($(CC), clang) +ifeq ($(DEBUG),0) +ifeq ($(CC_NO_CLANG), 0) CFLAGS += -O3 else CFLAGS += -O6 endif +endif + +ifeq ($(DEBUG),0) + CFLAGS += -D_FORTIFY_SOURCE +endif # Treat warnings as errors unless directed not to ifneq ($(WERROR),0) diff --git a/tools/lib/api/cpu.c b/tools/lib/api/cpu.c index 8c6489356e3a..4af6d4b7aa07 100644 --- a/tools/lib/api/cpu.c +++ b/tools/lib/api/cpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "cpu.h" diff --git a/tools/lib/api/cpu.h b/tools/lib/api/cpu.h index 81e9d3955961..90a102fb20de 100644 --- a/tools/lib/api/cpu.h +++ b/tools/lib/api/cpu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __API_CPU__ #define __API_CPU__ diff --git a/tools/lib/api/debug-internal.h b/tools/lib/api/debug-internal.h index 188f7880eafe..80c783497d25 100644 --- a/tools/lib/api/debug-internal.h +++ b/tools/lib/api/debug-internal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __API_DEBUG_INTERNAL_H__ #define __API_DEBUG_INTERNAL_H__ diff --git a/tools/lib/api/debug.c b/tools/lib/api/debug.c index 5fa5cf500a1f..69b1ba3d1ee3 100644 --- a/tools/lib/api/debug.c +++ b/tools/lib/api/debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "debug.h" diff --git a/tools/lib/api/debug.h b/tools/lib/api/debug.h index a0872f68fc56..3684dd6e0c02 100644 --- a/tools/lib/api/debug.h +++ b/tools/lib/api/debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __API_DEBUG_H__ #define __API_DEBUG_H__ diff --git a/tools/lib/api/fd/array.h b/tools/lib/api/fd/array.h index 71287dddc05f..b39557d1a88f 100644 --- a/tools/lib/api/fd/array.h +++ b/tools/lib/api/fd/array.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __API_FD_ARRAY__ #define __API_FD_ARRAY__ diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c index a7ecf8f469f4..b24afc0e6e81 100644 --- a/tools/lib/api/fs/fs.c +++ b/tools/lib/api/fs/fs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h index 45605348461e..dda49deefb52 100644 --- a/tools/lib/api/fs/fs.h +++ b/tools/lib/api/fs/fs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __API_FS__ #define __API_FS__ diff --git a/tools/lib/api/fs/tracing_path.c b/tools/lib/api/fs/tracing_path.c index 3e606b9c443e..7b7fd0b18551 100644 --- a/tools/lib/api/fs/tracing_path.c +++ b/tools/lib/api/fs/tracing_path.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif diff --git a/tools/lib/api/fs/tracing_path.h b/tools/lib/api/fs/tracing_path.h index 3f233ac70b6f..0066f06cc381 100644 --- a/tools/lib/api/fs/tracing_path.h +++ b/tools/lib/api/fs/tracing_path.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __API_FS_TRACING_PATH_H #define __API_FS_TRACING_PATH_H diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 1f5300e56b44..4555304dc18e 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Most of this file is copied from tools/lib/traceevent/Makefile BPF_VERSION = 0 @@ -154,12 +155,12 @@ all: fixdep $(VERSION_FILES) all_cmd all_cmd: $(CMD_TARGETS) $(BPF_IN): force elfdep bpfdep - @(test -f ../../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ + @(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \ (diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \ - echo "Warning: tools/include/uapi/linux/bpf.h differs from kernel" >&2 )) || true - @(test -f ../../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \ + echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true + @(test -f ../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \ (diff -B ../../include/uapi/linux/bpf_common.h ../../../include/uapi/linux/bpf_common.h >/dev/null) || \ - echo "Warning: tools/include/uapi/linux/bpf_common.h differs from kernel" >&2 )) || true + echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf_common.h' differs from latest version at 'include/uapi/linux/bpf_common.h'" >&2 )) || true $(Q)$(MAKE) $(build)=libbpf $(OUTPUT)libbpf.so: $(BPF_IN) @@ -189,6 +190,10 @@ install_lib: all_cmd $(call QUIET_INSTALL, $(LIB_FILE)) \ $(call do_install,$(LIB_FILE),$(libdir_SQ)) +install_headers: + $(call QUIET_INSTALL, headers) \ + $(call do_install,bpf.h,$(prefix)/include/bpf,644) + install: install_lib ### Cleaning rules diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index e5bbb090bf88..1d6907d379c9 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -57,8 +57,9 @@ static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, return syscall(__NR_bpf, cmd, attr, size); } -int bpf_create_map(enum bpf_map_type map_type, int key_size, - int value_size, int max_entries, __u32 map_flags) +int bpf_create_map_node(enum bpf_map_type map_type, int key_size, + int value_size, int max_entries, __u32 map_flags, + int node) { union bpf_attr attr; @@ -69,12 +70,24 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, attr.value_size = value_size; attr.max_entries = max_entries; attr.map_flags = map_flags; + if (node >= 0) { + attr.map_flags |= BPF_F_NUMA_NODE; + attr.numa_node = node; + } return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); } -int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, - int inner_map_fd, int max_entries, __u32 map_flags) +int bpf_create_map(enum bpf_map_type map_type, int key_size, + int value_size, int max_entries, __u32 map_flags) +{ + return bpf_create_map_node(map_type, key_size, value_size, + max_entries, map_flags, -1); +} + +int bpf_create_map_in_map_node(enum bpf_map_type map_type, int key_size, + int inner_map_fd, int max_entries, + __u32 map_flags, int node) { union bpf_attr attr; @@ -86,10 +99,21 @@ int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, attr.inner_map_fd = inner_map_fd; attr.max_entries = max_entries; attr.map_flags = map_flags; + if (node >= 0) { + attr.map_flags |= BPF_F_NUMA_NODE; + attr.numa_node = node; + } return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr)); } +int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, + int inner_map_fd, int max_entries, __u32 map_flags) +{ + return bpf_create_map_in_map_node(map_type, key_size, inner_map_fd, + max_entries, map_flags, -1); +} + int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns, size_t insns_cnt, const char *license, __u32 kern_version, char *log_buf, size_t log_buf_sz) diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 418c86e69bcb..b8ea5843c39e 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -24,8 +24,14 @@ #include #include +int bpf_create_map_node(enum bpf_map_type map_type, int key_size, + int value_size, int max_entries, __u32 map_flags, + int node); int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size, int max_entries, __u32 map_flags); +int bpf_create_map_in_map_node(enum bpf_map_type map_type, int key_size, + int inner_map_fd, int max_entries, + __u32 map_flags, int node); int bpf_create_map_in_map(enum bpf_map_type map_type, int key_size, int inner_map_fd, int max_entries, __u32 map_flags); diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 8c67a90dbd82..35f6dfcdc565 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -1745,3 +1745,32 @@ long libbpf_get_error(const void *ptr) return PTR_ERR(ptr); return 0; } + +int bpf_prog_load(const char *file, enum bpf_prog_type type, + struct bpf_object **pobj, int *prog_fd) +{ + struct bpf_program *prog; + struct bpf_object *obj; + int err; + + obj = bpf_object__open(file); + if (IS_ERR(obj)) + return -ENOENT; + + prog = bpf_program__next(NULL, obj); + if (!prog) { + bpf_object__close(obj); + return -ENOENT; + } + + bpf_program__set_type(prog, type); + err = bpf_object__load(obj); + if (err) { + bpf_object__close(obj); + return -EINVAL; + } + + *pobj = obj; + *prog_fd = bpf_program__fd(prog); + return 0; +} diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 32c7252f734e..7959086eb9c9 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -243,4 +243,6 @@ int bpf_map__pin(struct bpf_map *map, const char *path); long libbpf_get_error(const void *ptr); +int bpf_prog_load(const char *file, enum bpf_prog_type type, + struct bpf_object **pobj, int *prog_fd); #endif diff --git a/tools/lib/hweight.c b/tools/lib/hweight.c index 0b859b884339..a16ebf515417 100644 --- a/tools/lib/hweight.c +++ b/tools/lib/hweight.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index ed9ace59d112..9b0ca3ad1ef3 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # file format version FILE_VERSION = 1 diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c index d1c89cc06f5f..5c3b58cce8a9 100644 --- a/tools/lib/lockdep/common.c +++ b/tools/lib/lockdep/common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h index 6e66277ec437..8862da80995a 100644 --- a/tools/lib/lockdep/include/liblockdep/common.h +++ b/tools/lib/lockdep/include/liblockdep/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_COMMON_H #define _LIBLOCKDEP_COMMON_H diff --git a/tools/lib/lockdep/include/liblockdep/mutex.h b/tools/lib/lockdep/include/liblockdep/mutex.h index ee53a42818ca..a80ac39f966e 100644 --- a/tools/lib/lockdep/include/liblockdep/mutex.h +++ b/tools/lib/lockdep/include/liblockdep/mutex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_MUTEX_H #define _LIBLOCKDEP_MUTEX_H diff --git a/tools/lib/lockdep/include/liblockdep/rwlock.h b/tools/lib/lockdep/include/liblockdep/rwlock.h index 4ec03f861551..a96c3bf0fef1 100644 --- a/tools/lib/lockdep/include/liblockdep/rwlock.h +++ b/tools/lib/lockdep/include/liblockdep/rwlock.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_RWLOCK_H #define _LIBLOCKDEP_RWLOCK_H diff --git a/tools/lib/lockdep/lockdep.c b/tools/lib/lockdep/lockdep.c index ced6d7443cea..6002fcf2f9bc 100644 --- a/tools/lib/lockdep/lockdep.c +++ b/tools/lib/lockdep/lockdep.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/lib/lockdep/preload.c b/tools/lib/lockdep/preload.c index 6a2d3c5d4e92..76245d16196d 100644 --- a/tools/lib/lockdep/preload.c +++ b/tools/lib/lockdep/preload.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define _GNU_SOURCE #include #include diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh index f9b94098fc98..2e570a188f16 100755 --- a/tools/lib/lockdep/run_tests.sh +++ b/tools/lib/lockdep/run_tests.sh @@ -1,4 +1,5 @@ #! /bin/bash +# SPDX-License-Identifier: GPL-2.0 make &> /dev/null diff --git a/tools/lib/lockdep/tests/AA.c b/tools/lib/lockdep/tests/AA.c index 18211a5f354f..63c7ce97bda3 100644 --- a/tools/lib/lockdep/tests/AA.c +++ b/tools/lib/lockdep/tests/AA.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include int main(void) diff --git a/tools/lib/lockdep/tests/ABA.c b/tools/lib/lockdep/tests/ABA.c index 0f782ff404ac..efa39b23f05d 100644 --- a/tools/lib/lockdep/tests/ABA.c +++ b/tools/lib/lockdep/tests/ABA.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include void main(void) diff --git a/tools/lib/lockdep/tests/ABBA.c b/tools/lib/lockdep/tests/ABBA.c index 07f0e29d5485..1460afd33d71 100644 --- a/tools/lib/lockdep/tests/ABBA.c +++ b/tools/lib/lockdep/tests/ABBA.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "common.h" diff --git a/tools/lib/lockdep/tests/ABBA_2threads.c b/tools/lib/lockdep/tests/ABBA_2threads.c index cd807d736361..39325ef8a2ac 100644 --- a/tools/lib/lockdep/tests/ABBA_2threads.c +++ b/tools/lib/lockdep/tests/ABBA_2threads.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/lib/lockdep/tests/ABBCCA.c b/tools/lib/lockdep/tests/ABBCCA.c index 843db09ac666..a54c1b2af118 100644 --- a/tools/lib/lockdep/tests/ABBCCA.c +++ b/tools/lib/lockdep/tests/ABBCCA.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "common.h" diff --git a/tools/lib/lockdep/tests/ABBCCDDA.c b/tools/lib/lockdep/tests/ABBCCDDA.c index 33620e268f85..aa5d194e8869 100644 --- a/tools/lib/lockdep/tests/ABBCCDDA.c +++ b/tools/lib/lockdep/tests/ABBCCDDA.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "common.h" diff --git a/tools/lib/lockdep/tests/ABCABC.c b/tools/lib/lockdep/tests/ABCABC.c index 3fee51e3a68a..b54a08e60416 100644 --- a/tools/lib/lockdep/tests/ABCABC.c +++ b/tools/lib/lockdep/tests/ABCABC.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "common.h" diff --git a/tools/lib/lockdep/tests/ABCDBCDA.c b/tools/lib/lockdep/tests/ABCDBCDA.c index 427ba562c75b..a56742250d86 100644 --- a/tools/lib/lockdep/tests/ABCDBCDA.c +++ b/tools/lib/lockdep/tests/ABCDBCDA.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "common.h" diff --git a/tools/lib/lockdep/tests/ABCDBDDA.c b/tools/lib/lockdep/tests/ABCDBDDA.c index 680c6cf3e919..238a3353f3c3 100644 --- a/tools/lib/lockdep/tests/ABCDBDDA.c +++ b/tools/lib/lockdep/tests/ABCDBDDA.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "common.h" diff --git a/tools/lib/lockdep/tests/WW.c b/tools/lib/lockdep/tests/WW.c index d44f77d71029..eee88df7fc41 100644 --- a/tools/lib/lockdep/tests/WW.c +++ b/tools/lib/lockdep/tests/WW.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include void main(void) diff --git a/tools/lib/lockdep/tests/common.h b/tools/lib/lockdep/tests/common.h index d89e94d47d86..3026c29ccb5c 100644 --- a/tools/lib/lockdep/tests/common.h +++ b/tools/lib/lockdep/tests/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _LIBLOCKDEP_TEST_COMMON_H #define _LIBLOCKDEP_TEST_COMMON_H diff --git a/tools/lib/lockdep/tests/unlock_balance.c b/tools/lib/lockdep/tests/unlock_balance.c index 0bc62de686f7..34cf32f689de 100644 --- a/tools/lib/lockdep/tests/unlock_balance.c +++ b/tools/lib/lockdep/tests/unlock_balance.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include void main(void) diff --git a/tools/lib/str_error_r.c b/tools/lib/str_error_r.c index 503ae072244c..d6d65537b0d9 100644 --- a/tools/lib/str_error_r.c +++ b/tools/lib/str_error_r.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #undef _GNU_SOURCE #include #include diff --git a/tools/lib/string.c b/tools/lib/string.c index 8e678af1c6ee..93b3d4b6feac 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * linux/tools/lib/string.c * @@ -39,27 +40,45 @@ void *memdup(const void *src, size_t len) * @s: input string * @res: result * - * This routine returns 0 iff the first character is one of 'Yy1Nn0'. - * Otherwise it will return -EINVAL. Value pointed to by res is - * updated upon finding a match. + * This routine returns 0 iff the first character is one of 'Yy1Nn0', or + * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value + * pointed to by res is updated upon finding a match. */ int strtobool(const char *s, bool *res) { + if (!s) + return -EINVAL; + switch (s[0]) { case 'y': case 'Y': case '1': *res = true; - break; + return 0; case 'n': case 'N': case '0': *res = false; - break; + return 0; + case 'o': + case 'O': + switch (s[1]) { + case 'n': + case 'N': + *res = true; + return 0; + case 'f': + case 'F': + *res = false; + return 0; + default: + break; + } default: - return -EINVAL; + break; } - return 0; + + return -EINVAL; } /** @@ -87,12 +106,3 @@ size_t __weak strlcpy(char *dest, const char *src, size_t size) } return ret; } - -int prefixcmp(const char *str, const char *prefix) -{ - for (; ; str++, prefix++) - if (!*prefix) - return 0; - else if (*str != *prefix) - return (unsigned char)*prefix - (unsigned char)*str; -} diff --git a/tools/lib/subcmd/Makefile b/tools/lib/subcmd/Makefile index 3d1c3b5b5150..95563b8e1ad7 100644 --- a/tools/lib/subcmd/Makefile +++ b/tools/lib/subcmd/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 include ../../scripts/Makefile.include include ../../scripts/utilities.mak # QUIET_CLEAN @@ -21,7 +22,7 @@ LIBFILE = $(OUTPUT)libsubcmd.a CFLAGS := $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) CFLAGS += -ggdb3 -Wall -Wextra -std=gnu99 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC -ifeq ($(CC), clang) +ifeq ($(CC_NO_CLANG), 0) CFLAGS += -O3 else CFLAGS += -O6 diff --git a/tools/lib/subcmd/exec-cmd.c b/tools/lib/subcmd/exec-cmd.c index 1ae833af1a4a..33e94fb83986 100644 --- a/tools/lib/subcmd/exec-cmd.c +++ b/tools/lib/subcmd/exec-cmd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/subcmd/exec-cmd.h b/tools/lib/subcmd/exec-cmd.h index 5d08bda31d90..aba591b8d254 100644 --- a/tools/lib/subcmd/exec-cmd.h +++ b/tools/lib/subcmd/exec-cmd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUBCMD_EXEC_CMD_H #define __SUBCMD_EXEC_CMD_H diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c index ba970a73d053..2859f107abc8 100644 --- a/tools/lib/subcmd/help.c +++ b/tools/lib/subcmd/help.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -171,7 +172,7 @@ static void list_commands_in_dir(struct cmdnames *cmds, while ((de = readdir(dir)) != NULL) { int entlen; - if (prefixcmp(de->d_name, prefix)) + if (!strstarts(de->d_name, prefix)) continue; astrcat(&buf, de->d_name); diff --git a/tools/lib/subcmd/help.h b/tools/lib/subcmd/help.h index 9bd4223dc722..355c066c8d49 100644 --- a/tools/lib/subcmd/help.h +++ b/tools/lib/subcmd/help.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUBCMD_HELP_H #define __SUBCMD_HELP_H diff --git a/tools/lib/subcmd/pager.c b/tools/lib/subcmd/pager.c index 6518bea926d6..5ba754d17952 100644 --- a/tools/lib/subcmd/pager.c +++ b/tools/lib/subcmd/pager.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/subcmd/pager.h b/tools/lib/subcmd/pager.h index 623f5542d05d..f1a53cf29880 100644 --- a/tools/lib/subcmd/pager.h +++ b/tools/lib/subcmd/pager.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUBCMD_PAGER_H #define __SUBCMD_PAGER_H diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c index 359bfa77f39c..f6a1babcbac4 100644 --- a/tools/lib/subcmd/parse-options.c +++ b/tools/lib/subcmd/parse-options.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -368,7 +369,7 @@ retry: return 0; } if (!rest) { - if (!prefixcmp(options->long_name, "no-")) { + if (strstarts(options->long_name, "no-")) { /* * The long name itself starts with "no-", so * accept the option without "no-" so that users @@ -381,7 +382,7 @@ retry: goto match; } /* Abbreviated case */ - if (!prefixcmp(options->long_name + 3, arg)) { + if (strstarts(options->long_name + 3, arg)) { flags |= OPT_UNSET; goto is_abbreviated; } @@ -406,7 +407,7 @@ is_abbreviated: continue; } /* negated and abbreviated very much? */ - if (!prefixcmp("no-", arg)) { + if (strstarts("no-", arg)) { flags |= OPT_UNSET; goto is_abbreviated; } @@ -416,7 +417,7 @@ is_abbreviated: flags |= OPT_UNSET; rest = skip_prefix(arg + 3, options->long_name); /* abbreviated and negated? */ - if (!rest && !prefixcmp(options->long_name, arg + 3)) + if (!rest && strstarts(options->long_name, arg + 3)) goto is_abbreviated; if (!rest) continue; @@ -456,7 +457,7 @@ static void check_typos(const char *arg, const struct option *options) if (strlen(arg) < 3) return; - if (!prefixcmp(arg, "no-")) { + if (strstarts(arg, "no-")) { fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); exit(129); } @@ -464,7 +465,7 @@ static void check_typos(const char *arg, const struct option *options) for (; options->type != OPTION_END; options++) { if (!options->long_name) continue; - if (!prefixcmp(options->long_name, arg)) { + if (strstarts(options->long_name, arg)) { fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); exit(129); } @@ -933,10 +934,10 @@ opt: if (opts->long_name == NULL) continue; - if (!prefixcmp(opts->long_name, optstr)) + if (strstarts(opts->long_name, optstr)) print_option_help(opts, 0); - if (!prefixcmp("no-", optstr) && - !prefixcmp(opts->long_name, optstr + 3)) + if (strstarts("no-", optstr) && + strstarts(opts->long_name, optstr + 3)) print_option_help(opts, 0); } diff --git a/tools/lib/subcmd/parse-options.h b/tools/lib/subcmd/parse-options.h index f054ca1b899d..92fdbe1519f6 100644 --- a/tools/lib/subcmd/parse-options.h +++ b/tools/lib/subcmd/parse-options.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUBCMD_PARSE_OPTIONS_H #define __SUBCMD_PARSE_OPTIONS_H diff --git a/tools/lib/subcmd/run-command.c b/tools/lib/subcmd/run-command.c index 911f83942723..5cdac2162532 100644 --- a/tools/lib/subcmd/run-command.c +++ b/tools/lib/subcmd/run-command.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/subcmd/run-command.h b/tools/lib/subcmd/run-command.h index fe2befea1e73..17d969c6add3 100644 --- a/tools/lib/subcmd/run-command.h +++ b/tools/lib/subcmd/run-command.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUBCMD_RUN_COMMAND_H #define __SUBCMD_RUN_COMMAND_H diff --git a/tools/lib/subcmd/sigchain.c b/tools/lib/subcmd/sigchain.c index 3537c348a18e..f0fe3dbef7f7 100644 --- a/tools/lib/subcmd/sigchain.c +++ b/tools/lib/subcmd/sigchain.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "subcmd-util.h" #include "sigchain.h" diff --git a/tools/lib/subcmd/sigchain.h b/tools/lib/subcmd/sigchain.h index 0c919f2874ca..1ec663af43ea 100644 --- a/tools/lib/subcmd/sigchain.h +++ b/tools/lib/subcmd/sigchain.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUBCMD_SIGCHAIN_H #define __SUBCMD_SIGCHAIN_H diff --git a/tools/lib/subcmd/subcmd-config.c b/tools/lib/subcmd/subcmd-config.c index d017c728bd1b..84a7cf6c7878 100644 --- a/tools/lib/subcmd/subcmd-config.c +++ b/tools/lib/subcmd/subcmd-config.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "subcmd-config.h" #define UNDEFINED "SUBCMD_HAS_NOT_BEEN_INITIALIZED" diff --git a/tools/lib/subcmd/subcmd-config.h b/tools/lib/subcmd/subcmd-config.h index cc8514030b5c..9024dc17d100 100644 --- a/tools/lib/subcmd/subcmd-config.h +++ b/tools/lib/subcmd/subcmd-config.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_SUBCMD_CONFIG_H #define __PERF_SUBCMD_CONFIG_H diff --git a/tools/lib/subcmd/subcmd-util.h b/tools/lib/subcmd/subcmd-util.h index 8fa5f036eff0..794a375dad36 100644 --- a/tools/lib/subcmd/subcmd-util.h +++ b/tools/lib/subcmd/subcmd-util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __SUBCMD_UTIL_H #define __SUBCMD_UTIL_H diff --git a/tools/lib/symbol/kallsyms.c b/tools/lib/symbol/kallsyms.c index d270ac00613d..914cb8e3d40b 100644 --- a/tools/lib/symbol/kallsyms.c +++ b/tools/lib/symbol/kallsyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "symbol/kallsyms.h" #include diff --git a/tools/lib/symbol/kallsyms.h b/tools/lib/symbol/kallsyms.h index 4071316a766e..bc40101d72c1 100644 --- a/tools/lib/symbol/kallsyms.h +++ b/tools/lib/symbol/kallsyms.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TOOLS_KALLSYMS_H_ #define __TOOLS_KALLSYMS_H_ 1 diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 9b8555ea3459..46cd5f871ad7 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # trace-cmd version EP_VERSION = 1 EP_PATCHLEVEL = 1 diff --git a/tools/lib/traceevent/plugin_cfg80211.c b/tools/lib/traceevent/plugin_cfg80211.c index ec57d0c1fbc2..8f8586912da7 100644 --- a/tools/lib/traceevent/plugin_cfg80211.c +++ b/tools/lib/traceevent/plugin_cfg80211.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/traceevent/plugin_scsi.c b/tools/lib/traceevent/plugin_scsi.c index 3727de48c8d5..5e750af2b461 100644 --- a/tools/lib/traceevent/plugin_scsi.c +++ b/tools/lib/traceevent/plugin_scsi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/traceevent/plugin_xen.c b/tools/lib/traceevent/plugin_xen.c index 3a413eaada68..690173bfa13e 100644 --- a/tools/lib/traceevent/plugin_xen.c +++ b/tools/lib/traceevent/plugin_xen.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/lib/vsprintf.c b/tools/lib/vsprintf.c index 45f9a06daa56..e08ee147eab4 100644 --- a/tools/lib/vsprintf.c +++ b/tools/lib/vsprintf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/net/Makefile b/tools/net/Makefile index ddf888010652..5830670feae1 100644 --- a/tools/net/Makefile +++ b/tools/net/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 prefix = /usr CC = gcc diff --git a/tools/nfsd/inject_fault.sh b/tools/nfsd/inject_fault.sh index 06a399ac8b2f..10ceee64a09a 100755 --- a/tools/nfsd/inject_fault.sh +++ b/tools/nfsd/inject_fault.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 # # Copyright (c) 2011 Bryan Schumaker # diff --git a/tools/objtool/Build b/tools/objtool/Build index 6f2e1987c4d9..749becdf5b90 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -1,6 +1,9 @@ objtool-y += arch/$(SRCARCH)/ objtool-y += builtin-check.o +objtool-y += builtin-orc.o objtool-y += check.o +objtool-y += orc_gen.o +objtool-y += orc_dump.o objtool-y += elf.o objtool-y += special.o objtool-y += objtool.o diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt index 17c1195f11f4..3995735a878f 100644 --- a/tools/objtool/Documentation/stack-validation.txt +++ b/tools/objtool/Documentation/stack-validation.txt @@ -11,9 +11,6 @@ analyzes every .o file and ensures the validity of its stack metadata. It enforces a set of rules on asm code and C inline assembly code so that stack traces can be reliable. -Currently it only checks frame pointer usage, but there are plans to add -CFI validation for C files and CFI generation for asm files. - For each function, it recursively follows all possible code paths and validates the correct frame pointer state at each instruction. @@ -23,6 +20,10 @@ alternative execution paths to a given instruction (or set of instructions). Similarly, it knows how to follow switch statements, for which gcc sometimes uses jump tables. +(Objtool also has an 'orc generate' subcommand which generates debuginfo +for the ORC unwinder. See Documentation/x86/orc-unwinder.txt in the +kernel tree for more details.) + Why do we need stack metadata validation? ----------------------------------------- @@ -93,37 +94,14 @@ a) More reliable stack traces for frame pointer enabled kernels or at the very end of the function after the stack frame has been destroyed. This is an inherent limitation of frame pointers. -b) 100% reliable stack traces for DWARF enabled kernels +b) ORC (Oops Rewind Capability) unwind table generation - (NOTE: This is not yet implemented) + An alternative to frame pointers and DWARF, ORC unwind data can be + used to walk the stack. Unlike frame pointers, ORC data is out of + band. So it doesn't affect runtime performance and it can be + reliable even when interrupts or exceptions are involved. - As an alternative to frame pointers, DWARF Call Frame Information - (CFI) metadata can be used to walk the stack. Unlike frame pointers, - CFI metadata is out of band. So it doesn't affect runtime - performance and it can be reliable even when interrupts or exceptions - are involved. - - For C code, gcc automatically generates DWARF CFI metadata. But for - asm code, generating CFI is a tedious manual approach which requires - manually placed .cfi assembler macros to be scattered throughout the - code. It's clumsy and very easy to get wrong, and it makes the real - code harder to read. - - Stacktool will improve this situation in several ways. For code - which already has CFI annotations, it will validate them. For code - which doesn't have CFI annotations, it will generate them. So an - architecture can opt to strip out all the manual .cfi annotations - from their asm code and have objtool generate them instead. - - We might also add a runtime stack validation debug option where we - periodically walk the stack from schedule() and/or an NMI to ensure - that the stack metadata is sane and that we reach the bottom of the - stack. - - So the benefit of objtool here will be that external tooling should - always show perfect stack traces. And the same will be true for - kernel warning/oops traces if the architecture has a runtime DWARF - unwinder. + For more details, see Documentation/x86/orc-unwinder.txt. c) Higher live patching compatibility rate @@ -211,15 +189,15 @@ they mean, and suggestions for how to fix them. function, add proper frame pointer logic using the FRAME_BEGIN and FRAME_END macros. Otherwise, if it's not a callable function, remove its ELF function annotation by changing ENDPROC to END, and instead - use the manual CFI hint macros in asm/undwarf.h. + use the manual unwind hint macros in asm/unwind_hints.h. If it's a GCC-compiled .c file, the error may be because the function uses an inline asm() statement which has a "call" instruction. An asm() statement with a call instruction must declare the use of the - stack pointer in its output operand. For example, on x86_64: + stack pointer in its output operand. On x86_64, this means adding + the ASM_CALL_CONSTRAINT as an output constraint: - register void *__sp asm("rsp"); - asm volatile("call func" : "+r" (__sp)); + asm volatile("call func" : ASM_CALL_CONSTRAINT); Otherwise the stack frame may not get created before the call. @@ -231,8 +209,8 @@ they mean, and suggestions for how to fix them. If the error is for an asm file, and the instruction is inside (or reachable from) a callable function, the function should be annotated with the ENTRY/ENDPROC macros (ENDPROC is the important one). - Otherwise, the code should probably be annotated with the CFI hint - macros in asm/undwarf.h so objtool and the unwinder can know the + Otherwise, the code should probably be annotated with the unwind hint + macros in asm/unwind_hints.h so objtool and the unwinder can know the stack state associated with the code. If you're 100% sure the code won't affect stack traces, or if you're @@ -258,7 +236,7 @@ they mean, and suggestions for how to fix them. instructions aren't allowed in a callable function, and are most likely part of the kernel entry code. They should usually not have the callable function annotation (ENDPROC) and should always be - annotated with the CFI hint macros in asm/undwarf.h. + annotated with the unwind hint macros in asm/unwind_hints.h. 6. file.o: warning: objtool: func()+0x26: sibling call from callable instruction with modified stack frame @@ -272,7 +250,7 @@ they mean, and suggestions for how to fix them. If the instruction is not actually in a callable function (e.g. kernel entry code), change ENDPROC to END and annotate manually with - the CFI hint macros in asm/undwarf.h. + the unwind hint macros in asm/unwind_hints.h. 7. file: warning: objtool: func()+0x5c: stack state mismatch @@ -288,8 +266,8 @@ they mean, and suggestions for how to fix them. Another possibility is that the code has some asm or inline asm which does some unusual things to the stack or the frame pointer. In such - cases it's probably appropriate to use the CFI hint macros in - asm/undwarf.h. + cases it's probably appropriate to use the unwind hint macros in + asm/unwind_hints.h. 8. file.o: warning: objtool: funcA() falls through to next function funcB() diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 0e2765e243c0..424b1965d06f 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 include ../scripts/Makefile.include include ../scripts/Makefile.arch @@ -25,7 +26,8 @@ OBJTOOL_IN := $(OBJTOOL)-in.o all: $(OBJTOOL) INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi -CFLAGS += -Wall -Werror $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -fomit-frame-pointer -O2 -g $(INCLUDES) +WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed +CFLAGS += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES) LDFLAGS += -lelf $(LIBSUBCMD) # Allow old libelf to be used: @@ -52,6 +54,9 @@ $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN) diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \ diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \ || echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true + @(test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \ + diff ../../arch/x86/include/asm/orc_types.h orc_types.h >/dev/null) \ + || echo "warning: objtool: orc_types.h differs from kernel" >&2 )) || true $(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@ diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h index 21aeca874edb..b0d7dc3d71b5 100644 --- a/tools/objtool/arch.h +++ b/tools/objtool/arch.h @@ -31,8 +31,9 @@ #define INSN_RETURN 6 #define INSN_CONTEXT_SWITCH 7 #define INSN_STACK 8 -#define INSN_NOP 9 -#define INSN_OTHER 10 +#define INSN_BUG 9 +#define INSN_NOP 10 +#define INSN_OTHER 11 #define INSN_LAST INSN_OTHER enum op_dest_type { diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 4559a21a8de2..34a579f806e3 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -86,8 +86,8 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, struct insn insn; int x86_64, sign; unsigned char op1, op2, rex = 0, rex_b = 0, rex_r = 0, rex_w = 0, - modrm = 0, modrm_mod = 0, modrm_rm = 0, modrm_reg = 0, - sib = 0; + rex_x = 0, modrm = 0, modrm_mod = 0, modrm_rm = 0, + modrm_reg = 0, sib = 0; x86_64 = is_x86_64(elf); if (x86_64 == -1) @@ -114,6 +114,7 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, rex = insn.rex_prefix.bytes[0]; rex_w = X86_REX_W(rex) >> 3; rex_r = X86_REX_R(rex) >> 2; + rex_x = X86_REX_X(rex) >> 1; rex_b = X86_REX_B(rex); } @@ -207,16 +208,28 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, break; case 0x89: - if (rex == 0x48 && modrm == 0xe5) { + if (rex_w && !rex_r && modrm_mod == 3 && modrm_reg == 4) { - /* mov %rsp, %rbp */ + /* mov %rsp, reg */ *type = INSN_STACK; op->src.type = OP_SRC_REG; op->src.reg = CFI_SP; op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_BP; + op->dest.reg = op_to_cfi_reg[modrm_rm][rex_b]; break; } + + if (rex_w && !rex_b && modrm_mod == 3 && modrm_rm == 4) { + + /* mov reg, %rsp */ + *type = INSN_STACK; + op->src.type = OP_SRC_REG; + op->src.reg = op_to_cfi_reg[modrm_reg][rex_r]; + op->dest.type = OP_DEST_REG; + op->dest.reg = CFI_SP; + break; + } + /* fallthrough */ case 0x88: if (!rex_b && @@ -269,7 +282,22 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, break; case 0x8d: - if (rex == 0x48 && modrm == 0x65) { + if (sib == 0x24 && rex_w && !rex_b && !rex_x) { + + *type = INSN_STACK; + if (!insn.displacement.value) { + /* lea (%rsp), reg */ + op->src.type = OP_SRC_REG; + } else { + /* lea disp(%rsp), reg */ + op->src.type = OP_SRC_ADD; + op->src.offset = insn.displacement.value; + } + op->src.reg = CFI_SP; + op->dest.type = OP_DEST_REG; + op->dest.reg = op_to_cfi_reg[modrm_reg][rex_r]; + + } else if (rex == 0x48 && modrm == 0x65) { /* lea disp(%rbp), %rsp */ *type = INSN_STACK; @@ -278,71 +306,9 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, op->src.offset = insn.displacement.value; op->dest.type = OP_DEST_REG; op->dest.reg = CFI_SP; - break; - } - if (rex == 0x48 && (modrm == 0xa4 || modrm == 0x64) && - sib == 0x24) { - - /* lea disp(%rsp), %rsp */ - *type = INSN_STACK; - op->src.type = OP_SRC_ADD; - op->src.reg = CFI_SP; - op->src.offset = insn.displacement.value; - op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_SP; - break; - } - - if (rex == 0x48 && modrm == 0x2c && sib == 0x24) { - - /* lea (%rsp), %rbp */ - *type = INSN_STACK; - op->src.type = OP_SRC_REG; - op->src.reg = CFI_SP; - op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_BP; - break; - } - - if (rex == 0x4c && modrm == 0x54 && sib == 0x24 && - insn.displacement.value == 8) { - - /* - * lea 0x8(%rsp), %r10 - * - * Here r10 is the "drap" pointer, used as a stack - * pointer helper when the stack gets realigned. - */ - *type = INSN_STACK; - op->src.type = OP_SRC_ADD; - op->src.reg = CFI_SP; - op->src.offset = 8; - op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_R10; - break; - } - - if (rex == 0x4c && modrm == 0x6c && sib == 0x24 && - insn.displacement.value == 16) { - - /* - * lea 0x10(%rsp), %r13 - * - * Here r13 is the "drap" pointer, used as a stack - * pointer helper when the stack gets realigned. - */ - *type = INSN_STACK; - op->src.type = OP_SRC_ADD; - op->src.reg = CFI_SP; - op->src.offset = 16; - op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_R13; - break; - } - - if (rex == 0x49 && modrm == 0x62 && - insn.displacement.value == -8) { + } else if (rex == 0x49 && modrm == 0x62 && + insn.displacement.value == -8) { /* * lea -0x8(%r10), %rsp @@ -356,11 +322,9 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, op->src.offset = -8; op->dest.type = OP_DEST_REG; op->dest.reg = CFI_SP; - break; - } - if (rex == 0x49 && modrm == 0x65 && - insn.displacement.value == -16) { + } else if (rex == 0x49 && modrm == 0x65 && + insn.displacement.value == -16) { /* * lea -0x10(%r13), %rsp @@ -374,7 +338,6 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, op->src.offset = -16; op->dest.type = OP_DEST_REG; op->dest.reg = CFI_SP; - break; } break; @@ -406,20 +369,27 @@ int arch_decode_instruction(struct elf *elf, struct section *sec, case 0x0f: - if (op2 >= 0x80 && op2 <= 0x8f) + if (op2 >= 0x80 && op2 <= 0x8f) { + *type = INSN_JUMP_CONDITIONAL; - else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 || - op2 == 0x35) + + } else if (op2 == 0x05 || op2 == 0x07 || op2 == 0x34 || + op2 == 0x35) { /* sysenter, sysret */ *type = INSN_CONTEXT_SWITCH; - else if (op2 == 0x0d || op2 == 0x1f) + } else if (op2 == 0x0b || op2 == 0xb9) { + + /* ud2 */ + *type = INSN_BUG; + + } else if (op2 == 0x0d || op2 == 0x1f) { /* nopl/nopw */ *type = INSN_NOP; - else if (op2 == 0xa0 || op2 == 0xa8) { + } else if (op2 == 0xa0 || op2 == 0xa8) { /* push fs/gs */ *type = INSN_STACK; diff --git a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk index a3d2c62fd805..b02a36b2c14f 100644 --- a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk +++ b/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk @@ -1,4 +1,5 @@ #!/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 # gen-insn-attr-x86.awk: Instruction attribute table generator # Written by Masami Hiramatsu # diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 365c34ecab26..57254f5b2779 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -29,7 +29,7 @@ #include "builtin.h" #include "check.h" -bool nofp; +bool no_fp, no_unreachable; static const char * const check_usage[] = { "objtool check [] file.o", @@ -37,7 +37,8 @@ static const char * const check_usage[] = { }; const struct option check_options[] = { - OPT_BOOLEAN('f', "no-fp", &nofp, "Skip frame pointer validation"), + OPT_BOOLEAN('f', "no-fp", &no_fp, "Skip frame pointer validation"), + OPT_BOOLEAN('u', "no-unreachable", &no_unreachable, "Skip 'unreachable instruction' warnings"), OPT_END(), }; @@ -52,5 +53,5 @@ int cmd_check(int argc, const char **argv) objname = argv[0]; - return check(objname, nofp); + return check(objname, no_fp, no_unreachable, false); } diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c new file mode 100644 index 000000000000..4c6b5c9ef073 --- /dev/null +++ b/tools/objtool/builtin-orc.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +/* + * objtool orc: + * + * This command analyzes a .o file and adds .orc_unwind and .orc_unwind_ip + * sections to it, which is used by the in-kernel ORC unwinder. + * + * This command is a superset of "objtool check". + */ + +#include +#include +#include "builtin.h" +#include "check.h" + + +static const char *orc_usage[] = { + "objtool orc generate [] file.o", + "objtool orc dump file.o", + NULL, +}; + +extern const struct option check_options[]; +extern bool no_fp, no_unreachable; + +int cmd_orc(int argc, const char **argv) +{ + const char *objname; + + argc--; argv++; + if (!strncmp(argv[0], "gen", 3)) { + argc = parse_options(argc, argv, check_options, orc_usage, 0); + if (argc != 1) + usage_with_options(orc_usage, check_options); + + objname = argv[0]; + + return check(objname, no_fp, no_unreachable, true); + + } + + if (!strcmp(argv[0], "dump")) { + if (argc != 2) + usage_with_options(orc_usage, check_options); + + objname = argv[1]; + + return orc_dump(objname); + } + + usage_with_options(orc_usage, check_options); + + return 0; +} diff --git a/tools/objtool/builtin.h b/tools/objtool/builtin.h index 34d2ba78a616..dd526067fed5 100644 --- a/tools/objtool/builtin.h +++ b/tools/objtool/builtin.h @@ -18,5 +18,6 @@ #define _BUILTIN_H extern int cmd_check(int argc, const char **argv); +extern int cmd_orc(int argc, const char **argv); #endif /* _BUILTIN_H */ diff --git a/tools/objtool/cfi.h b/tools/objtool/cfi.h index 443ab2c69992..2fe883c665c7 100644 --- a/tools/objtool/cfi.h +++ b/tools/objtool/cfi.h @@ -40,7 +40,7 @@ #define CFI_R14 14 #define CFI_R15 15 #define CFI_RA 16 -#define CFI_NUM_REGS 17 +#define CFI_NUM_REGS 17 struct cfi_reg { int base; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 2c6d74880403..c0e26ad1fa7e 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -33,11 +33,11 @@ struct alternative { }; const char *objname; -static bool nofp; +static bool no_fp; struct cfi_state initial_func_cfi; -static struct instruction *find_insn(struct objtool_file *file, - struct section *sec, unsigned long offset) +struct instruction *find_insn(struct objtool_file *file, + struct section *sec, unsigned long offset) { struct instruction *insn; @@ -59,19 +59,6 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file, return next; } -static bool gcov_enabled(struct objtool_file *file) -{ - struct section *sec; - struct symbol *sym; - - for_each_sec(file, sec) - list_for_each_entry(sym, &sec->symbol_list, list) - if (!strncmp(sym->name, "__gcov_.", 8)) - return true; - - return false; -} - #define func_for_each_insn(file, func, insn) \ for (insn = find_insn(file, func->sec, func->offset); \ insn && &insn->list != &file->insn_list && \ @@ -100,7 +87,6 @@ static bool gcov_enabled(struct objtool_file *file) static bool ignore_func(struct objtool_file *file, struct symbol *func) { struct rela *rela; - struct instruction *insn; /* check for STACK_FRAME_NON_STANDARD */ if (file->whitelist && file->whitelist->rela) @@ -113,11 +99,6 @@ static bool ignore_func(struct objtool_file *file, struct symbol *func) return true; } - /* check if it has a context switching instruction */ - func_for_each_insn(file, func, insn) - if (insn->type == INSN_CONTEXT_SWITCH) - return true; - return false; } @@ -237,9 +218,12 @@ static void clear_insn_state(struct insn_state *state) memset(state, 0, sizeof(*state)); state->cfa.base = CFI_UNDEFINED; - for (i = 0; i < CFI_NUM_REGS; i++) + for (i = 0; i < CFI_NUM_REGS; i++) { state->regs[i].base = CFI_UNDEFINED; + state->vals[i].base = CFI_UNDEFINED; + } state->drap_reg = CFI_UNDEFINED; + state->drap_offset = -1; } /* @@ -259,6 +243,11 @@ static int decode_instructions(struct objtool_file *file) if (!(sec->sh.sh_flags & SHF_EXECINSTR)) continue; + if (strcmp(sec->name, ".altinstr_replacement") && + strcmp(sec->name, ".altinstr_aux") && + strncmp(sec->name, ".discard.", 9)) + sec->text = true; + for (offset = 0; offset < sec->len; offset += insn->len) { insn = malloc(sizeof(*insn)); if (!insn) { @@ -278,12 +267,13 @@ static int decode_instructions(struct objtool_file *file) &insn->immediate, &insn->stack_op); if (ret) - return ret; + goto err; if (!insn->type || insn->type > INSN_LAST) { WARN_FUNC("invalid instruction type %d", insn->sec, insn->offset, insn->type); - return -1; + ret = -1; + goto err; } hash_add(file->insn_hash, &insn->hash, insn->offset); @@ -307,10 +297,14 @@ static int decode_instructions(struct objtool_file *file) } return 0; + +err: + free(insn); + return ret; } /* - * Find all uses of the unreachable() macro, which are code path dead ends. + * Mark "ud2" instructions and manually annotated dead ends. */ static int add_dead_ends(struct objtool_file *file) { @@ -319,9 +313,20 @@ static int add_dead_ends(struct objtool_file *file) struct instruction *insn; bool found; + /* + * By default, "ud2" is a dead end unless otherwise annotated, because + * GCC 7 inserts it for certain divide-by-zero cases. + */ + for_each_insn(file, insn) + if (insn->type == INSN_BUG) + insn->dead_end = true; + + /* + * Check for manually annotated dead ends. + */ sec = find_section_by_name(file->elf, ".rela.discard.unreachable"); if (!sec) - return 0; + goto reachable; list_for_each_entry(rela, &sec->rela_list, list) { if (rela->sym->type != STT_SECTION) { @@ -354,6 +359,48 @@ static int add_dead_ends(struct objtool_file *file) insn->dead_end = true; } +reachable: + /* + * These manually annotated reachable checks are needed for GCC 4.4, + * where the Linux unreachable() macro isn't supported. In that case + * GCC doesn't know the "ud2" is fatal, so it generates code as if it's + * not a dead end. + */ + sec = find_section_by_name(file->elf, ".rela.discard.reachable"); + if (!sec) + return 0; + + list_for_each_entry(rela, &sec->rela_list, list) { + if (rela->sym->type != STT_SECTION) { + WARN("unexpected relocation symbol type in %s", sec->name); + return -1; + } + insn = find_insn(file, rela->sym->sec, rela->addend); + if (insn) + insn = list_prev_entry(insn, list); + else if (rela->addend == rela->sym->sec->len) { + found = false; + list_for_each_entry_reverse(insn, &file->insn_list, list) { + if (insn->sec == rela->sym->sec) { + found = true; + break; + } + } + + if (!found) { + WARN("can't find reachable insn at %s+0x%x", + rela->sym->sec->name, rela->addend); + return -1; + } + } else { + WARN("can't find reachable insn at %s+0x%x", + rela->sym->sec->name, rela->addend); + return -1; + } + + insn->dead_end = false; + } + return 0; } @@ -874,6 +921,99 @@ static int add_switch_table_alts(struct objtool_file *file) return 0; } +static int read_unwind_hints(struct objtool_file *file) +{ + struct section *sec, *relasec; + struct rela *rela; + struct unwind_hint *hint; + struct instruction *insn; + struct cfi_reg *cfa; + int i; + + sec = find_section_by_name(file->elf, ".discard.unwind_hints"); + if (!sec) + return 0; + + relasec = sec->rela; + if (!relasec) { + WARN("missing .rela.discard.unwind_hints section"); + return -1; + } + + if (sec->len % sizeof(struct unwind_hint)) { + WARN("struct unwind_hint size mismatch"); + return -1; + } + + file->hints = true; + + for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) { + hint = (struct unwind_hint *)sec->data->d_buf + i; + + rela = find_rela_by_dest(sec, i * sizeof(*hint)); + if (!rela) { + WARN("can't find rela for unwind_hints[%d]", i); + return -1; + } + + insn = find_insn(file, rela->sym->sec, rela->addend); + if (!insn) { + WARN("can't find insn for unwind_hints[%d]", i); + return -1; + } + + cfa = &insn->state.cfa; + + if (hint->type == UNWIND_HINT_TYPE_SAVE) { + insn->save = true; + continue; + + } else if (hint->type == UNWIND_HINT_TYPE_RESTORE) { + insn->restore = true; + insn->hint = true; + continue; + } + + insn->hint = true; + + switch (hint->sp_reg) { + case ORC_REG_UNDEFINED: + cfa->base = CFI_UNDEFINED; + break; + case ORC_REG_SP: + cfa->base = CFI_SP; + break; + case ORC_REG_BP: + cfa->base = CFI_BP; + break; + case ORC_REG_SP_INDIRECT: + cfa->base = CFI_SP_INDIRECT; + break; + case ORC_REG_R10: + cfa->base = CFI_R10; + break; + case ORC_REG_R13: + cfa->base = CFI_R13; + break; + case ORC_REG_DI: + cfa->base = CFI_DI; + break; + case ORC_REG_DX: + cfa->base = CFI_DX; + break; + default: + WARN_FUNC("unsupported unwind_hint sp base reg %d", + insn->sec, insn->offset, hint->sp_reg); + return -1; + } + + cfa->offset = hint->sp_offset; + insn->state.type = hint->type; + } + + return 0; +} + static int decode_sections(struct objtool_file *file) { int ret; @@ -904,6 +1044,10 @@ static int decode_sections(struct objtool_file *file) if (ret) return ret; + ret = read_unwind_hints(file); + if (ret) + return ret; + return 0; } @@ -947,11 +1091,34 @@ static bool has_valid_stack_frame(struct insn_state *state) return false; } +static int update_insn_state_regs(struct instruction *insn, struct insn_state *state) +{ + struct cfi_reg *cfa = &state->cfa; + struct stack_op *op = &insn->stack_op; + + if (cfa->base != CFI_SP) + return 0; + + /* push */ + if (op->dest.type == OP_DEST_PUSH) + cfa->offset += 8; + + /* pop */ + if (op->src.type == OP_SRC_POP) + cfa->offset -= 8; + + /* add immediate to sp */ + if (op->dest.type == OP_DEST_REG && op->src.type == OP_SRC_ADD && + op->dest.reg == CFI_SP && op->src.reg == CFI_SP) + cfa->offset -= op->src.offset; + + return 0; +} + static void save_reg(struct insn_state *state, unsigned char reg, int base, int offset) { - if ((arch_callee_saved_reg(reg) || - (state->drap && reg == state->drap_reg)) && + if (arch_callee_saved_reg(reg) && state->regs[reg].base == CFI_UNDEFINED) { state->regs[reg].base = base; state->regs[reg].offset = offset; @@ -1032,30 +1199,71 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) return 0; } + if (state->type == ORC_TYPE_REGS || state->type == ORC_TYPE_REGS_IRET) + return update_insn_state_regs(insn, state); + switch (op->dest.type) { case OP_DEST_REG: switch (op->src.type) { case OP_SRC_REG: - if (cfa->base == op->src.reg && cfa->base == CFI_SP && - op->dest.reg == CFI_BP && regs[CFI_BP].base == CFI_CFA && + if (op->src.reg == CFI_SP && op->dest.reg == CFI_BP && + cfa->base == CFI_SP && + regs[CFI_BP].base == CFI_CFA && regs[CFI_BP].offset == -cfa->offset) { /* mov %rsp, %rbp */ cfa->base = op->dest.reg; state->bp_scratch = false; - } else if (state->drap) { + } + + else if (op->src.reg == CFI_SP && + op->dest.reg == CFI_BP && state->drap) { /* drap: mov %rsp, %rbp */ regs[CFI_BP].base = CFI_BP; regs[CFI_BP].offset = -state->stack_size; state->bp_scratch = false; - } else if (!nofp) { + } - WARN_FUNC("unknown stack-related register move", - insn->sec, insn->offset); - return -1; + else if (op->src.reg == CFI_SP && cfa->base == CFI_SP) { + + /* + * mov %rsp, %reg + * + * This is needed for the rare case where GCC + * does: + * + * mov %rsp, %rax + * ... + * mov %rax, %rsp + */ + state->vals[op->dest.reg].base = CFI_CFA; + state->vals[op->dest.reg].offset = -state->stack_size; + } + + else if (op->dest.reg == cfa->base) { + + /* mov %reg, %rsp */ + if (cfa->base == CFI_SP && + state->vals[op->src.reg].base == CFI_CFA) { + + /* + * This is needed for the rare case + * where GCC does something dumb like: + * + * lea 0x8(%rsp), %rcx + * ... + * mov %rcx, %rsp + */ + cfa->offset = -state->vals[op->src.reg].offset; + state->stack_size = cfa->offset; + + } else { + cfa->base = CFI_UNDEFINED; + cfa->offset = 0; + } } break; @@ -1077,11 +1285,25 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) break; } - if (op->dest.reg != CFI_BP && op->src.reg == CFI_SP && - cfa->base == CFI_SP) { + if (op->src.reg == CFI_SP && cfa->base == CFI_SP) { /* drap: lea disp(%rsp), %drap */ state->drap_reg = op->dest.reg; + + /* + * lea disp(%rsp), %reg + * + * This is needed for the rare case where GCC + * does something dumb like: + * + * lea 0x8(%rsp), %rcx + * ... + * mov %rcx, %rsp + */ + state->vals[op->dest.reg].base = CFI_CFA; + state->vals[op->dest.reg].offset = \ + -state->stack_size + op->src.offset; + break; } @@ -1118,7 +1340,6 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = state->drap_reg; cfa->offset = state->stack_size = 0; state->drap = true; - } /* @@ -1136,17 +1357,19 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = CFI_SP; } - if (regs[op->dest.reg].offset == -state->stack_size) { + if (state->drap && cfa->base == CFI_BP_INDIRECT && + op->dest.type == OP_DEST_REG && + op->dest.reg == state->drap_reg && + state->drap_offset == -state->stack_size) { - if (state->drap && cfa->base == CFI_BP_INDIRECT && - op->dest.type == OP_DEST_REG && - op->dest.reg == state->drap_reg) { + /* drap: pop %drap */ + cfa->base = state->drap_reg; + cfa->offset = 0; + state->drap_offset = -1; - /* drap: pop %drap */ - cfa->base = state->drap_reg; - cfa->offset = 0; - } + } else if (regs[op->dest.reg].offset == -state->stack_size) { + /* pop %reg */ restore_reg(state, op->dest.reg); } @@ -1157,15 +1380,19 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) break; case OP_SRC_REG_INDIRECT: + if (state->drap && op->src.reg == CFI_BP && + op->src.offset == state->drap_offset) { + + /* drap: mov disp(%rbp), %drap */ + cfa->base = state->drap_reg; + cfa->offset = 0; + state->drap_offset = -1; + } + if (state->drap && op->src.reg == CFI_BP && op->src.offset == regs[op->dest.reg].offset) { /* drap: mov disp(%rbp), %reg */ - if (op->dest.reg == state->drap_reg) { - cfa->base = state->drap_reg; - cfa->offset = 0; - } - restore_reg(state, op->dest.reg); } else if (op->src.reg == cfa->base && @@ -1201,8 +1428,8 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = CFI_BP_INDIRECT; cfa->offset = -state->stack_size; - /* save drap so we know when to undefine it */ - save_reg(state, op->src.reg, CFI_CFA, -state->stack_size); + /* save drap so we know when to restore it */ + state->drap_offset = -state->stack_size; } else if (op->src.reg == CFI_BP && cfa->base == state->drap_reg) { @@ -1222,7 +1449,7 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) } /* detect when asm code uses rbp as a scratch register */ - if (!nofp && insn->func && op->src.reg == CFI_BP && + if (!no_fp && insn->func && op->src.reg == CFI_BP && cfa->base != CFI_BP) state->bp_scratch = true; break; @@ -1236,8 +1463,8 @@ static int update_insn_state(struct instruction *insn, struct insn_state *state) cfa->base = CFI_BP_INDIRECT; cfa->offset = op->dest.offset; - /* save drap so we know when to undefine it */ - save_reg(state, op->src.reg, CFI_CFA, op->dest.offset); + /* save drap offset so we know when to restore it */ + state->drap_offset = op->dest.offset; } else if (regs[op->src.reg].base == CFI_UNDEFINED) { @@ -1323,12 +1550,17 @@ static bool insn_state_match(struct instruction *insn, struct insn_state *state) break; } + } else if (state1->type != state2->type) { + WARN_FUNC("stack state mismatch: type1=%d type2=%d", + insn->sec, insn->offset, state1->type, state2->type); + } else if (state1->drap != state2->drap || - (state1->drap && state1->drap_reg != state2->drap_reg)) { - WARN_FUNC("stack state mismatch: drap1=%d(%d) drap2=%d(%d)", + (state1->drap && state1->drap_reg != state2->drap_reg) || + (state1->drap && state1->drap_offset != state2->drap_offset)) { + WARN_FUNC("stack state mismatch: drap1=%d(%d,%d) drap2=%d(%d,%d)", insn->sec, insn->offset, - state1->drap, state1->drap_reg, - state2->drap, state2->drap_reg); + state1->drap, state1->drap_reg, state1->drap_offset, + state2->drap, state2->drap_reg, state2->drap_offset); } else return true; @@ -1346,7 +1578,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, struct insn_state state) { struct alternative *alt; - struct instruction *insn; + struct instruction *insn, *next_insn; struct section *sec; struct symbol *func = NULL; int ret; @@ -1357,34 +1589,77 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, if (insn->alt_group && list_empty(&insn->alts)) { WARN_FUNC("don't know how to handle branch to middle of alternative instruction group", sec, insn->offset); - return -1; + return 1; } while (1) { - if (file->c_file && insn->func) { - if (func && func != insn->func) { - WARN("%s() falls through to next function %s()", - func->name, insn->func->name); - return 1; - } + next_insn = next_insn_same_sec(file, insn); + + + if (file->c_file && func && insn->func && func != insn->func) { + WARN("%s() falls through to next function %s()", + func->name, insn->func->name); + return 1; } - func = insn->func; + if (insn->func) + func = insn->func; if (func && insn->ignore) { WARN_FUNC("BUG: why am I validating an ignored function?", sec, insn->offset); - return -1; + return 1; } if (insn->visited) { - if (!!insn_state_match(insn, &state)) + if (!insn->hint && !insn_state_match(insn, &state)) return 1; return 0; } - insn->state = state; + if (insn->hint) { + if (insn->restore) { + struct instruction *save_insn, *i; + + i = insn; + save_insn = NULL; + func_for_each_insn_continue_reverse(file, func, i) { + if (i->save) { + save_insn = i; + break; + } + } + + if (!save_insn) { + WARN_FUNC("no corresponding CFI save for CFI restore", + sec, insn->offset); + return 1; + } + + if (!save_insn->visited) { + /* + * Oops, no state to copy yet. + * Hopefully we can reach this + * instruction from another branch + * after the save insn has been + * visited. + */ + if (insn == first) + return 0; + + WARN_FUNC("objtool isn't smart enough to handle this CFI save/restore combo", + sec, insn->offset); + return 1; + } + + insn->state = save_insn->state; + } + + state = insn->state; + + } else + insn->state = state; insn->visited = true; @@ -1423,7 +1698,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, /* fallthrough */ case INSN_CALL_DYNAMIC: - if (!nofp && func && !has_valid_stack_frame(&state)) { + if (!no_fp && func && !has_valid_stack_frame(&state)) { WARN_FUNC("call without frame pointer save/setup", sec, insn->offset); return 1; @@ -1461,9 +1736,17 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, return 0; + case INSN_CONTEXT_SWITCH: + if (func && (!next_insn || !next_insn->hint)) { + WARN_FUNC("unsupported instruction in callable function", + sec, insn->offset); + return 1; + } + return 0; + case INSN_STACK: if (update_insn_state(insn, &state)) - return -1; + return 1; break; @@ -1474,7 +1757,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, if (insn->dead_end) return 0; - insn = next_insn_same_sec(file, insn); + insn = next_insn; if (!insn) { WARN("%s: unexpected end of section", sec->name); return 1; @@ -1484,6 +1767,27 @@ static int validate_branch(struct objtool_file *file, struct instruction *first, return 0; } +static int validate_unwind_hints(struct objtool_file *file) +{ + struct instruction *insn; + int ret, warnings = 0; + struct insn_state state; + + if (!file->hints) + return 0; + + clear_insn_state(&state); + + for_each_insn(file, insn) { + if (insn->hint && !insn->visited) { + ret = validate_branch(file, insn, state); + warnings += ret; + } + } + + return warnings; +} + static bool is_kasan_insn(struct instruction *insn) { return (insn->type == INSN_CALL && @@ -1507,8 +1811,13 @@ static bool ignore_unreachable_insn(struct instruction *insn) /* * Ignore any unused exceptions. This can happen when a whitelisted * function has an exception table entry. + * + * Also ignore alternative replacement instructions. This can happen + * when a whitelisted function uses one of the ALTERNATIVE macros. */ - if (!strcmp(insn->sec->name, ".fixup")) + if (!strcmp(insn->sec->name, ".fixup") || + !strcmp(insn->sec->name, ".altinstr_replacement") || + !strcmp(insn->sec->name, ".altinstr_aux")) return true; /* @@ -1580,15 +1889,6 @@ static int validate_reachable_instructions(struct objtool_file *file) if (insn->visited || ignore_unreachable_insn(insn)) continue; - /* - * gcov produces a lot of unreachable instructions. If we get - * an unreachable warning and the file has gcov enabled, just - * ignore it, and all other such warnings for the file. Do - * this here because this is an expensive function. - */ - if (gcov_enabled(file)) - return 0; - WARN_FUNC("unreachable instruction", insn->sec, insn->offset); return 1; } @@ -1613,15 +1913,15 @@ static void cleanup(struct objtool_file *file) elf_close(file->elf); } -int check(const char *_objname, bool _nofp) +int check(const char *_objname, bool _no_fp, bool no_unreachable, bool orc) { struct objtool_file file; int ret, warnings = 0; objname = _objname; - nofp = _nofp; + no_fp = _no_fp; - file.elf = elf_open(objname); + file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY); if (!file.elf) return 1; @@ -1629,8 +1929,9 @@ int check(const char *_objname, bool _nofp) hash_init(file.insn_hash); file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard"); file.rodata = find_section_by_name(file.elf, ".rodata"); - file.ignore_unreachables = false; file.c_file = find_section_by_name(file.elf, ".comment"); + file.ignore_unreachables = no_unreachable; + file.hints = false; arch_initial_func_cfi_state(&initial_func_cfi); @@ -1647,6 +1948,11 @@ int check(const char *_objname, bool _nofp) goto out; warnings += ret; + ret = validate_unwind_hints(&file); + if (ret < 0) + goto out; + warnings += ret; + if (!warnings) { ret = validate_reachable_instructions(&file); if (ret < 0) @@ -1654,6 +1960,20 @@ int check(const char *_objname, bool _nofp) warnings += ret; } + if (orc) { + ret = create_orc(&file); + if (ret < 0) + goto out; + + ret = create_orc_sections(&file); + if (ret < 0) + goto out; + + ret = elf_write(file.elf); + if (ret < 0) + goto out; + } + out: cleanup(&file); diff --git a/tools/objtool/check.h b/tools/objtool/check.h index da85f5b00ec6..47d9ea70a83d 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h @@ -22,15 +22,18 @@ #include "elf.h" #include "cfi.h" #include "arch.h" +#include "orc.h" #include struct insn_state { struct cfi_reg cfa; struct cfi_reg regs[CFI_NUM_REGS]; int stack_size; + unsigned char type; bool bp_scratch; bool drap; - int drap_reg; + int drap_reg, drap_offset; + struct cfi_reg vals[CFI_NUM_REGS]; }; struct instruction { @@ -41,13 +44,14 @@ struct instruction { unsigned int len; unsigned char type; unsigned long immediate; - bool alt_group, visited, dead_end, ignore; + bool alt_group, visited, dead_end, ignore, hint, save, restore; struct symbol *call_dest; struct instruction *jump_dest; struct list_head alts; struct symbol *func; struct stack_op stack_op; struct insn_state state; + struct orc_entry orc; }; struct objtool_file { @@ -55,12 +59,22 @@ struct objtool_file { struct list_head insn_list; DECLARE_HASHTABLE(insn_hash, 16); struct section *rodata, *whitelist; - bool ignore_unreachables, c_file; + bool ignore_unreachables, c_file, hints; }; -int check(const char *objname, bool nofp); +int check(const char *objname, bool no_fp, bool no_unreachable, bool orc); + +struct instruction *find_insn(struct objtool_file *file, + struct section *sec, unsigned long offset); #define for_each_insn(file, insn) \ list_for_each_entry(insn, &file->insn_list, list) +#define sec_for_each_insn(file, sec, insn) \ + for (insn = find_insn(file, sec, 0); \ + insn && &insn->list != &file->insn_list && \ + insn->sec == sec; \ + insn = list_next_entry(insn, list)) + + #endif /* _CHECK_H */ diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 1a7e8aa2af58..24460155c82c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -30,16 +30,6 @@ #include "elf.h" #include "warn.h" -/* - * Fallback for systems without this "read, mmaping if possible" cmd. - */ -#ifndef ELF_C_READ_MMAP -#define ELF_C_READ_MMAP ELF_C_READ -#endif - -#define WARN_ELF(format, ...) \ - WARN(format ": %s", ##__VA_ARGS__, elf_errmsg(-1)) - struct section *find_section_by_name(struct elf *elf, const char *name) { struct section *sec; @@ -185,19 +175,20 @@ static int read_sections(struct elf *elf) return -1; } - sec->data = elf_getdata(s, NULL); - if (!sec->data) { - WARN_ELF("elf_getdata"); - return -1; + if (sec->sh.sh_size != 0) { + sec->data = elf_getdata(s, NULL); + if (!sec->data) { + WARN_ELF("elf_getdata"); + return -1; + } + if (sec->data->d_off != 0 || + sec->data->d_size != sec->sh.sh_size) { + WARN("unexpected data attributes for %s", + sec->name); + return -1; + } } - - if (sec->data->d_off != 0 || - sec->data->d_size != sec->sh.sh_size) { - WARN("unexpected data attributes for %s", sec->name); - return -1; - } - - sec->len = sec->data->d_size; + sec->len = sec->sh.sh_size; } /* sanity check, one more call to elf_nextscn() should return NULL */ @@ -349,9 +340,10 @@ static int read_relas(struct elf *elf) return 0; } -struct elf *elf_open(const char *name) +struct elf *elf_open(const char *name, int flags) { struct elf *elf; + Elf_Cmd cmd; elf_version(EV_CURRENT); @@ -364,13 +356,20 @@ struct elf *elf_open(const char *name) INIT_LIST_HEAD(&elf->sections); - elf->fd = open(name, O_RDONLY); + elf->fd = open(name, flags); if (elf->fd == -1) { perror("open"); goto err; } - elf->elf = elf_begin(elf->fd, ELF_C_READ_MMAP, NULL); + if ((flags & O_ACCMODE) == O_RDONLY) + cmd = ELF_C_READ_MMAP; + else if ((flags & O_ACCMODE) == O_RDWR) + cmd = ELF_C_RDWR; + else /* O_WRONLY */ + cmd = ELF_C_WRITE; + + elf->elf = elf_begin(elf->fd, cmd, NULL); if (!elf->elf) { WARN_ELF("elf_begin"); goto err; @@ -397,6 +396,200 @@ err: return NULL; } +struct section *elf_create_section(struct elf *elf, const char *name, + size_t entsize, int nr) +{ + struct section *sec, *shstrtab; + size_t size = entsize * nr; + struct Elf_Scn *s; + Elf_Data *data; + + sec = malloc(sizeof(*sec)); + if (!sec) { + perror("malloc"); + return NULL; + } + memset(sec, 0, sizeof(*sec)); + + INIT_LIST_HEAD(&sec->symbol_list); + INIT_LIST_HEAD(&sec->rela_list); + hash_init(sec->rela_hash); + hash_init(sec->symbol_hash); + + list_add_tail(&sec->list, &elf->sections); + + s = elf_newscn(elf->elf); + if (!s) { + WARN_ELF("elf_newscn"); + return NULL; + } + + sec->name = strdup(name); + if (!sec->name) { + perror("strdup"); + return NULL; + } + + sec->idx = elf_ndxscn(s); + sec->len = size; + sec->changed = true; + + sec->data = elf_newdata(s); + if (!sec->data) { + WARN_ELF("elf_newdata"); + return NULL; + } + + sec->data->d_size = size; + sec->data->d_align = 1; + + if (size) { + sec->data->d_buf = malloc(size); + if (!sec->data->d_buf) { + perror("malloc"); + return NULL; + } + memset(sec->data->d_buf, 0, size); + } + + if (!gelf_getshdr(s, &sec->sh)) { + WARN_ELF("gelf_getshdr"); + return NULL; + } + + sec->sh.sh_size = size; + sec->sh.sh_entsize = entsize; + sec->sh.sh_type = SHT_PROGBITS; + sec->sh.sh_addralign = 1; + sec->sh.sh_flags = SHF_ALLOC; + + + /* Add section name to .shstrtab */ + shstrtab = find_section_by_name(elf, ".shstrtab"); + if (!shstrtab) { + WARN("can't find .shstrtab section"); + return NULL; + } + + s = elf_getscn(elf->elf, shstrtab->idx); + if (!s) { + WARN_ELF("elf_getscn"); + return NULL; + } + + data = elf_newdata(s); + if (!data) { + WARN_ELF("elf_newdata"); + return NULL; + } + + data->d_buf = sec->name; + data->d_size = strlen(name) + 1; + data->d_align = 1; + + sec->sh.sh_name = shstrtab->len; + + shstrtab->len += strlen(name) + 1; + shstrtab->changed = true; + + return sec; +} + +struct section *elf_create_rela_section(struct elf *elf, struct section *base) +{ + char *relaname; + struct section *sec; + + relaname = malloc(strlen(base->name) + strlen(".rela") + 1); + if (!relaname) { + perror("malloc"); + return NULL; + } + strcpy(relaname, ".rela"); + strcat(relaname, base->name); + + sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0); + free(relaname); + if (!sec) + return NULL; + + base->rela = sec; + sec->base = base; + + sec->sh.sh_type = SHT_RELA; + sec->sh.sh_addralign = 8; + sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; + sec->sh.sh_info = base->idx; + sec->sh.sh_flags = SHF_INFO_LINK; + + return sec; +} + +int elf_rebuild_rela_section(struct section *sec) +{ + struct rela *rela; + int nr, idx = 0, size; + GElf_Rela *relas; + + nr = 0; + list_for_each_entry(rela, &sec->rela_list, list) + nr++; + + size = nr * sizeof(*relas); + relas = malloc(size); + if (!relas) { + perror("malloc"); + return -1; + } + + sec->data->d_buf = relas; + sec->data->d_size = size; + + sec->sh.sh_size = size; + + idx = 0; + list_for_each_entry(rela, &sec->rela_list, list) { + relas[idx].r_offset = rela->offset; + relas[idx].r_addend = rela->addend; + relas[idx].r_info = GELF_R_INFO(rela->sym->idx, rela->type); + idx++; + } + + return 0; +} + +int elf_write(struct elf *elf) +{ + struct section *sec; + Elf_Scn *s; + + /* Update section headers for changed sections: */ + list_for_each_entry(sec, &elf->sections, list) { + if (sec->changed) { + s = elf_getscn(elf->elf, sec->idx); + if (!s) { + WARN_ELF("elf_getscn"); + return -1; + } + if (!gelf_update_shdr(s, &sec->sh)) { + WARN_ELF("gelf_update_shdr"); + return -1; + } + } + } + + /* Make sure the new section header entries get updated properly. */ + elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); + + /* Write all changes to the file. */ + if (elf_update(elf->elf, ELF_C_WRITE) < 0) { + WARN_ELF("elf_update"); + return -1; + } + + return 0; +} + void elf_close(struct elf *elf) { struct section *sec, *tmpsec; diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h index 343968b778cb..d86e2ff14466 100644 --- a/tools/objtool/elf.h +++ b/tools/objtool/elf.h @@ -28,6 +28,13 @@ # define elf_getshdrstrndx elf_getshstrndx #endif +/* + * Fallback for systems without this "read, mmaping if possible" cmd. + */ +#ifndef ELF_C_READ_MMAP +#define ELF_C_READ_MMAP ELF_C_READ +#endif + struct section { struct list_head list; GElf_Shdr sh; @@ -41,6 +48,7 @@ struct section { char *name; int idx; unsigned int len; + bool changed, text; }; struct symbol { @@ -75,7 +83,7 @@ struct elf { }; -struct elf *elf_open(const char *name); +struct elf *elf_open(const char *name, int flags); struct section *find_section_by_name(struct elf *elf, const char *name); struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset); struct symbol *find_symbol_containing(struct section *sec, unsigned long offset); @@ -83,6 +91,11 @@ struct rela *find_rela_by_dest(struct section *sec, unsigned long offset); struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset, unsigned int len); struct symbol *find_containing_func(struct section *sec, unsigned long offset); +struct section *elf_create_section(struct elf *elf, const char *name, size_t + entsize, int nr); +struct section *elf_create_rela_section(struct elf *elf, struct section *base); +int elf_rebuild_rela_section(struct section *sec); +int elf_write(struct elf *elf); void elf_close(struct elf *elf); #define for_each_sec(file, sec) \ diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index ecc5b1b5d15d..31e0f9143840 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -42,10 +42,11 @@ struct cmd_struct { }; static const char objtool_usage_string[] = - "objtool [OPTIONS] COMMAND [ARGS]"; + "objtool COMMAND [ARGS]"; static struct cmd_struct objtool_cmds[] = { {"check", cmd_check, "Perform stack metadata validation on an object file" }, + {"orc", cmd_orc, "Generate in-place ORC unwind tables for an object file" }, }; bool help; diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h new file mode 100644 index 000000000000..a4139e386ef3 --- /dev/null +++ b/tools/objtool/orc.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _ORC_H +#define _ORC_H + +#include "orc_types.h" + +struct objtool_file; + +int create_orc(struct objtool_file *file); +int create_orc_sections(struct objtool_file *file); + +int orc_dump(const char *objname); + +#endif /* _ORC_H */ diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c new file mode 100644 index 000000000000..36c5bf6a2675 --- /dev/null +++ b/tools/objtool/orc_dump.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include "orc.h" +#include "warn.h" + +static const char *reg_name(unsigned int reg) +{ + switch (reg) { + case ORC_REG_PREV_SP: + return "prevsp"; + case ORC_REG_DX: + return "dx"; + case ORC_REG_DI: + return "di"; + case ORC_REG_BP: + return "bp"; + case ORC_REG_SP: + return "sp"; + case ORC_REG_R10: + return "r10"; + case ORC_REG_R13: + return "r13"; + case ORC_REG_BP_INDIRECT: + return "bp(ind)"; + case ORC_REG_SP_INDIRECT: + return "sp(ind)"; + default: + return "?"; + } +} + +static const char *orc_type_name(unsigned int type) +{ + switch (type) { + case ORC_TYPE_CALL: + return "call"; + case ORC_TYPE_REGS: + return "regs"; + case ORC_TYPE_REGS_IRET: + return "iret"; + default: + return "?"; + } +} + +static void print_reg(unsigned int reg, int offset) +{ + if (reg == ORC_REG_BP_INDIRECT) + printf("(bp%+d)", offset); + else if (reg == ORC_REG_SP_INDIRECT) + printf("(sp%+d)", offset); + else if (reg == ORC_REG_UNDEFINED) + printf("(und)"); + else + printf("%s%+d", reg_name(reg), offset); +} + +int orc_dump(const char *_objname) +{ + int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0; + struct orc_entry *orc = NULL; + char *name; + unsigned long nr_sections, orc_ip_addr = 0; + size_t shstrtab_idx; + Elf *elf; + Elf_Scn *scn; + GElf_Shdr sh; + GElf_Rela rela; + GElf_Sym sym; + Elf_Data *data, *symtab = NULL, *rela_orc_ip = NULL; + + + objname = _objname; + + elf_version(EV_CURRENT); + + fd = open(objname, O_RDONLY); + if (fd == -1) { + perror("open"); + return -1; + } + + elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); + if (!elf) { + WARN_ELF("elf_begin"); + return -1; + } + + if (elf_getshdrnum(elf, &nr_sections)) { + WARN_ELF("elf_getshdrnum"); + return -1; + } + + if (elf_getshdrstrndx(elf, &shstrtab_idx)) { + WARN_ELF("elf_getshdrstrndx"); + return -1; + } + + for (i = 0; i < nr_sections; i++) { + scn = elf_getscn(elf, i); + if (!scn) { + WARN_ELF("elf_getscn"); + return -1; + } + + if (!gelf_getshdr(scn, &sh)) { + WARN_ELF("gelf_getshdr"); + return -1; + } + + name = elf_strptr(elf, shstrtab_idx, sh.sh_name); + if (!name) { + WARN_ELF("elf_strptr"); + return -1; + } + + data = elf_getdata(scn, NULL); + if (!data) { + WARN_ELF("elf_getdata"); + return -1; + } + + if (!strcmp(name, ".symtab")) { + symtab = data; + } else if (!strcmp(name, ".orc_unwind")) { + orc = data->d_buf; + orc_size = sh.sh_size; + } else if (!strcmp(name, ".orc_unwind_ip")) { + orc_ip = data->d_buf; + orc_ip_addr = sh.sh_addr; + } else if (!strcmp(name, ".rela.orc_unwind_ip")) { + rela_orc_ip = data; + } + } + + if (!symtab || !orc || !orc_ip) + return 0; + + if (orc_size % sizeof(*orc) != 0) { + WARN("bad .orc_unwind section size"); + return -1; + } + + nr_entries = orc_size / sizeof(*orc); + for (i = 0; i < nr_entries; i++) { + if (rela_orc_ip) { + if (!gelf_getrela(rela_orc_ip, i, &rela)) { + WARN_ELF("gelf_getrela"); + return -1; + } + + if (!gelf_getsym(symtab, GELF_R_SYM(rela.r_info), &sym)) { + WARN_ELF("gelf_getsym"); + return -1; + } + + scn = elf_getscn(elf, sym.st_shndx); + if (!scn) { + WARN_ELF("elf_getscn"); + return -1; + } + + if (!gelf_getshdr(scn, &sh)) { + WARN_ELF("gelf_getshdr"); + return -1; + } + + name = elf_strptr(elf, shstrtab_idx, sh.sh_name); + if (!name || !*name) { + WARN_ELF("elf_strptr"); + return -1; + } + + printf("%s+%lx:", name, rela.r_addend); + + } else { + printf("%lx:", orc_ip_addr + (i * sizeof(int)) + orc_ip[i]); + } + + + printf(" sp:"); + + print_reg(orc[i].sp_reg, orc[i].sp_offset); + + printf(" bp:"); + + print_reg(orc[i].bp_reg, orc[i].bp_offset); + + printf(" type:%s\n", orc_type_name(orc[i].type)); + } + + elf_end(elf); + close(fd); + + return 0; +} diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c new file mode 100644 index 000000000000..e5ca31429c9b --- /dev/null +++ b/tools/objtool/orc_gen.c @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include + +#include "orc.h" +#include "check.h" +#include "warn.h" + +int create_orc(struct objtool_file *file) +{ + struct instruction *insn; + + for_each_insn(file, insn) { + struct orc_entry *orc = &insn->orc; + struct cfi_reg *cfa = &insn->state.cfa; + struct cfi_reg *bp = &insn->state.regs[CFI_BP]; + + if (cfa->base == CFI_UNDEFINED) { + orc->sp_reg = ORC_REG_UNDEFINED; + continue; + } + + switch (cfa->base) { + case CFI_SP: + orc->sp_reg = ORC_REG_SP; + break; + case CFI_SP_INDIRECT: + orc->sp_reg = ORC_REG_SP_INDIRECT; + break; + case CFI_BP: + orc->sp_reg = ORC_REG_BP; + break; + case CFI_BP_INDIRECT: + orc->sp_reg = ORC_REG_BP_INDIRECT; + break; + case CFI_R10: + orc->sp_reg = ORC_REG_R10; + break; + case CFI_R13: + orc->sp_reg = ORC_REG_R13; + break; + case CFI_DI: + orc->sp_reg = ORC_REG_DI; + break; + case CFI_DX: + orc->sp_reg = ORC_REG_DX; + break; + default: + WARN_FUNC("unknown CFA base reg %d", + insn->sec, insn->offset, cfa->base); + return -1; + } + + switch(bp->base) { + case CFI_UNDEFINED: + orc->bp_reg = ORC_REG_UNDEFINED; + break; + case CFI_CFA: + orc->bp_reg = ORC_REG_PREV_SP; + break; + case CFI_BP: + orc->bp_reg = ORC_REG_BP; + break; + default: + WARN_FUNC("unknown BP base reg %d", + insn->sec, insn->offset, bp->base); + return -1; + } + + orc->sp_offset = cfa->offset; + orc->bp_offset = bp->offset; + orc->type = insn->state.type; + } + + return 0; +} + +static int create_orc_entry(struct section *u_sec, struct section *ip_relasec, + unsigned int idx, struct section *insn_sec, + unsigned long insn_off, struct orc_entry *o) +{ + struct orc_entry *orc; + struct rela *rela; + + /* populate ORC data */ + orc = (struct orc_entry *)u_sec->data->d_buf + idx; + memcpy(orc, o, sizeof(*orc)); + + /* populate rela for ip */ + rela = malloc(sizeof(*rela)); + if (!rela) { + perror("malloc"); + return -1; + } + memset(rela, 0, sizeof(*rela)); + + rela->sym = insn_sec->sym; + rela->addend = insn_off; + rela->type = R_X86_64_PC32; + rela->offset = idx * sizeof(int); + + list_add_tail(&rela->list, &ip_relasec->rela_list); + hash_add(ip_relasec->rela_hash, &rela->hash, rela->offset); + + return 0; +} + +int create_orc_sections(struct objtool_file *file) +{ + struct instruction *insn, *prev_insn; + struct section *sec, *u_sec, *ip_relasec; + unsigned int idx; + + struct orc_entry empty = { + .sp_reg = ORC_REG_UNDEFINED, + .bp_reg = ORC_REG_UNDEFINED, + .type = ORC_TYPE_CALL, + }; + + sec = find_section_by_name(file->elf, ".orc_unwind"); + if (sec) { + WARN("file already has .orc_unwind section, skipping"); + return -1; + } + + /* count the number of needed orcs */ + idx = 0; + for_each_sec(file, sec) { + if (!sec->text) + continue; + + prev_insn = NULL; + sec_for_each_insn(file, sec, insn) { + if (!prev_insn || + memcmp(&insn->orc, &prev_insn->orc, + sizeof(struct orc_entry))) { + idx++; + } + prev_insn = insn; + } + + /* section terminator */ + if (prev_insn) + idx++; + } + if (!idx) + return -1; + + + /* create .orc_unwind_ip and .rela.orc_unwind_ip sections */ + sec = elf_create_section(file->elf, ".orc_unwind_ip", sizeof(int), idx); + + ip_relasec = elf_create_rela_section(file->elf, sec); + if (!ip_relasec) + return -1; + + /* create .orc_unwind section */ + u_sec = elf_create_section(file->elf, ".orc_unwind", + sizeof(struct orc_entry), idx); + + /* populate sections */ + idx = 0; + for_each_sec(file, sec) { + if (!sec->text) + continue; + + prev_insn = NULL; + sec_for_each_insn(file, sec, insn) { + if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc, + sizeof(struct orc_entry))) { + + if (create_orc_entry(u_sec, ip_relasec, idx, + insn->sec, insn->offset, + &insn->orc)) + return -1; + + idx++; + } + prev_insn = insn; + } + + /* section terminator */ + if (prev_insn) { + if (create_orc_entry(u_sec, ip_relasec, idx, + prev_insn->sec, + prev_insn->offset + prev_insn->len, + &empty)) + return -1; + + idx++; + } + } + + if (elf_rebuild_rela_section(ip_relasec)) + return -1; + + return 0; +} diff --git a/tools/objtool/orc_types.h b/tools/objtool/orc_types.h new file mode 100644 index 000000000000..9c9dc579bd7d --- /dev/null +++ b/tools/objtool/orc_types.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2017 Josh Poimboeuf + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _ORC_TYPES_H +#define _ORC_TYPES_H + +#include +#include + +/* + * The ORC_REG_* registers are base registers which are used to find other + * registers on the stack. + * + * ORC_REG_PREV_SP, also known as DWARF Call Frame Address (CFA), is the + * address of the previous frame: the caller's SP before it called the current + * function. + * + * ORC_REG_UNDEFINED means the corresponding register's value didn't change in + * the current frame. + * + * The most commonly used base registers are SP and BP -- which the previous SP + * is usually based on -- and PREV_SP and UNDEFINED -- which the previous BP is + * usually based on. + * + * The rest of the base registers are needed for special cases like entry code + * and GCC realigned stacks. + */ +#define ORC_REG_UNDEFINED 0 +#define ORC_REG_PREV_SP 1 +#define ORC_REG_DX 2 +#define ORC_REG_DI 3 +#define ORC_REG_BP 4 +#define ORC_REG_SP 5 +#define ORC_REG_R10 6 +#define ORC_REG_R13 7 +#define ORC_REG_BP_INDIRECT 8 +#define ORC_REG_SP_INDIRECT 9 +#define ORC_REG_MAX 15 + +/* + * ORC_TYPE_CALL: Indicates that sp_reg+sp_offset resolves to PREV_SP (the + * caller's SP right before it made the call). Used for all callable + * functions, i.e. all C code and all callable asm functions. + * + * ORC_TYPE_REGS: Used in entry code to indicate that sp_reg+sp_offset points + * to a fully populated pt_regs from a syscall, interrupt, or exception. + * + * ORC_TYPE_REGS_IRET: Used in entry code to indicate that sp_reg+sp_offset + * points to the iret return frame. + * + * The UNWIND_HINT macros are used only for the unwind_hint struct. They + * aren't used in struct orc_entry due to size and complexity constraints. + * Objtool converts them to real types when it converts the hints to orc + * entries. + */ +#define ORC_TYPE_CALL 0 +#define ORC_TYPE_REGS 1 +#define ORC_TYPE_REGS_IRET 2 +#define UNWIND_HINT_TYPE_SAVE 3 +#define UNWIND_HINT_TYPE_RESTORE 4 + +#ifndef __ASSEMBLY__ +/* + * This struct is more or less a vastly simplified version of the DWARF Call + * Frame Information standard. It contains only the necessary parts of DWARF + * CFI, simplified for ease of access by the in-kernel unwinder. It tells the + * unwinder how to find the previous SP and BP (and sometimes entry regs) on + * the stack for a given code address. Each instance of the struct corresponds + * to one or more code locations. + */ +struct orc_entry { + s16 sp_offset; + s16 bp_offset; + unsigned sp_reg:4; + unsigned bp_reg:4; + unsigned type:2; +} __packed; + +/* + * This struct is used by asm and inline asm code to manually annotate the + * location of registers on the stack for the ORC unwinder. + * + * Type can be either ORC_TYPE_* or UNWIND_HINT_TYPE_*. + */ +struct unwind_hint { + u32 ip; + s16 sp_offset; + u8 sp_reg; + u8 type; +}; +#endif /* __ASSEMBLY__ */ + +#endif /* _ORC_TYPES_H */ diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c index ad54a58d7dda..9074b477bff0 100644 --- a/tools/pci/pcitest.c +++ b/tools/pci/pcitest.c @@ -173,6 +173,7 @@ usage: "\t-D PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n" "\t-b BAR test (bar number between 0..5)\n" "\t-m MSI test (msi number between 1..32)\n" + "\t-l Legacy IRQ test\n" "\t-r Read buffer test\n" "\t-w Write buffer test\n" "\t-c Copy buffer test\n" diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh index 5442bbea4c22..77e8c85ef744 100644 --- a/tools/pci/pcitest.sh +++ b/tools/pci/pcitest.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 echo "BAR tests" echo diff --git a/tools/pcmcia/Makefile b/tools/pcmcia/Makefile index 81a7498c5cd9..eae24df1dbf5 100644 --- a/tools/pcmcia/Makefile +++ b/tools/pcmcia/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 CC := $(CROSS_COMPILE)gcc CFLAGS := -I../../usr/include diff --git a/tools/perf/Build b/tools/perf/Build index bd8eeb60533c..b48ca40fccf9 100644 --- a/tools/perf/Build +++ b/tools/perf/Build @@ -50,6 +50,6 @@ libperf-y += util/ libperf-y += arch/ libperf-y += ui/ libperf-y += scripts/ -libperf-y += trace/beauty/ +libperf-$(CONFIG_AUDIT) += trace/beauty/ gtk-y += ui/gtk/ diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 098cfb9ca8f0..db11478e30b4 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -192,7 +192,7 @@ do-install-man: man # $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir); \ # $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) -install-man: check-man-tools man +install-man: check-man-tools man do-install-man ifdef missing_tools DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed) diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt index 4b6cdbf8f935..76971d2e4164 100644 --- a/tools/perf/Documentation/intel-pt.txt +++ b/tools/perf/Documentation/intel-pt.txt @@ -104,9 +104,9 @@ system, asynchronous, interrupt, transaction abort, trace begin, trace end, and in transaction, respectively. While it is possible to create scripts to analyze the data, an alternative -approach is available to export the data to a postgresql database. Refer to -script export-to-postgresql.py for more details, and to script -call-graph-from-postgresql.py for an example of using the database. +approach is available to export the data to a sqlite or postgresql database. +Refer to script export-to-sqlite.py or export-to-postgresql.py for more details, +and to script call-graph-from-sql.py for an example of using the database. There is also script intel-pt-events.py which provides an example of how to unpack the raw data for power events and PTWRITE. @@ -873,7 +873,7 @@ amended to take the number of elements as a parameter. $ cat ~/.perfconfig [intel-pt] - mispred-all + mispred-all = on $ perf record -e intel_pt//u ./sort 3000 Bubble sorting array of 3000 elements diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index a89273d8e744..c635eab6af54 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -43,6 +43,10 @@ OPTIONS --quiet:: Do not show any message. (Suppress -v) +-n:: +--show-nr-samples:: + Show the number of samples for each symbol + -D:: --dump-raw-trace:: Dump raw trace in ASCII. @@ -88,6 +92,8 @@ OPTIONS --asm-raw:: Show raw instruction encoding of assembly instructions. +--show-total-period:: Show a column with the sum of periods. + --source:: Interleave source code with assembly code. Enabled by default, disable with --no-source. diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index 058064db39d2..84681007f80f 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -61,6 +61,11 @@ OPTIONS --verbose:: Be more verbose. +--target-ns=PID: + Obtain mount namespace information from the target pid. This is + used when creating a uprobe for a process that resides in a + different mount namespace from the perf(1) utility. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-buildid-list[1] diff --git a/tools/perf/Documentation/perf-mem.txt b/tools/perf/Documentation/perf-mem.txt index 73496320fca3..4be08a1e3f8d 100644 --- a/tools/perf/Documentation/perf-mem.txt +++ b/tools/perf/Documentation/perf-mem.txt @@ -59,6 +59,10 @@ OPTIONS --ldload:: Specify desired latency for loads event. +-p:: +--phys-data:: + Record/Report sample physical addresses + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-report[1] diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt index 165c2b1d4317..d7e4869905f1 100644 --- a/tools/perf/Documentation/perf-probe.txt +++ b/tools/perf/Documentation/perf-probe.txt @@ -130,6 +130,11 @@ OPTIONS --max-probes=NUM:: Set the maximum number of probe points for an event. Default is 128. +--target-ns=PID: + Obtain mount namespace information from the target pid. This is + used when creating a uprobe for a process that resides in a + different mount namespace from the perf(1) utility. + -x:: --exec=PATH:: Specify path to the executable or shared library file for user @@ -264,6 +269,15 @@ Add probes at malloc() function on libc ./perf probe -x /lib/libc.so.6 malloc or ./perf probe /lib/libc.so.6 malloc +Add a uprobe to a target process running in a different mount namespace + + ./perf probe --target-ns -x /lib64/libc.so.6 malloc + +Add a USDT probe to a target process running in a different mount namespace + + ./perf probe --target-ns -x /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/lib/amd64/server/libjvm.so %sdt_hotspot:thread__sleep__end + + SEE ALSO -------- linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1] diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index b0e9e921d534..63526f4416ea 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -8,8 +8,8 @@ perf-record - Run a command and record its profile into perf.data SYNOPSIS -------- [verse] -'perf record' [-e | --event=EVENT] [-l] [-a] -'perf record' [-e | --event=EVENT] [-l] [-a] -- [] +'perf record' [-e | --event=EVENT] [-a] +'perf record' [-e | --event=EVENT] [-a] -- [] DESCRIPTION ----------- @@ -249,7 +249,10 @@ OPTIONS -d:: --data:: - Record the sample addresses. + Record the sample virtual addresses. + +--phys-data:: + Record the sample physical addresses. -T:: --timestamp:: @@ -332,6 +335,7 @@ following filters are defined: - no_tx: only when the target is not in a hardware transaction - abort_tx: only when the target is a hardware transaction abort - cond: conditional branches + - save_type: save branch type during sampling in case binary is not available later + The option requires at least one branch type among any, any_call, any_ret, ind_call, cond. diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 9fa84617181e..383a98d992ed 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -137,6 +137,7 @@ OPTIONS - mem: type of memory access for the data at the time of the sample - snoop: type of snoop (if any) for the data at the time of the sample - dcacheline: the cacheline the data address is on at the time of the sample + - phys_daddr: physical address of data being executed on at the time of sample And the default sort keys are changed to local_weight, mem, sym, dso, symbol_daddr, dso_daddr, snoop, tlb, locked, see '--mem-mode'. diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 5ee8796be96e..18dfcfa38454 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -117,7 +117,7 @@ OPTIONS Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period, iregs, brstack, brstacksym, flags, bpf-output, brstackinsn, brstackoff, - callindent, insn, insnlen, synth. + callindent, insn, insnlen, synth, phys_addr. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 698076313606..c37d61682dfb 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -41,13 +41,13 @@ report:: - a symbolically formed event like 'pmu/param1=0x3,param2/' where param1 and param2 are defined as formats for the PMU in - /sys/bus/event_sources/devices//format/* + /sys/bus/event_source/devices//format/* - a symbolically formed event like 'pmu/config=M,config1=N,config2=K/' where M, N, K are numbers (in decimal, hex, octal format). Acceptable values for each of 'config', 'config1' and 'config2' parameters are defined by corresponding entries in - /sys/bus/event_sources/devices//format/* + /sys/bus/event_source/devices//format/* -i:: --no-inherit:: diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index e71d63843f45..d864ea6fd367 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -237,6 +237,10 @@ Default is to monitor all CPUS. --hierarchy:: Enable hierarchy output. +--force:: + Don't do ownership validation. + + INTERACTIVE PROMPTING KEYS -------------------------- diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index c1e3288a2dfb..d53bea6bd571 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -37,7 +37,7 @@ OPTIONS --expr:: --event:: List of syscalls and other perf events (tracepoints, HW cache events, - etc) to show. + etc) to show. Globbing is supported, e.g.: "epoll_*", "*msg*", etc. See 'perf list' for a complete list of events. Prefixing with ! shows all syscalls but the ones specified. You may need to escape it. diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index de8b39dda7b8..e90c59c6d815 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt @@ -398,6 +398,11 @@ struct auxtrace_error_event { char msg[MAX_AUXTRACE_ERROR_MSG]; }; + PERF_RECORD_HEADER_FEATURE = 80, + +Describes a header feature. These are records used in pipe-mode that +contain information that otherwise would be in perf.data file's header. + Event types Define the event attributes with their IDs. @@ -422,8 +427,9 @@ struct perf_pipe_file_header { }; The information about attrs, data, and event_types is instead in the -synthesized events PERF_RECORD_ATTR, PERF_RECORD_HEADER_TRACING_DATA and -PERF_RECORD_HEADER_EVENT_TYPE that are generated by perf record in pipe-mode. +synthesized events PERF_RECORD_ATTR, PERF_RECORD_HEADER_TRACING_DATA, +PERF_RECORD_HEADER_EVENT_TYPE, and PERF_RECORD_HEADER_FEATURE +that are generated by perf record in pipe-mode. References: diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index a29da46d180f..627b7cada144 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -1,34 +1,8 @@ tools/perf -tools/arch/alpha/include/asm/barrier.h -tools/arch/arm/include/asm/barrier.h -tools/arch/arm64/include/asm/barrier.h -tools/arch/ia64/include/asm/barrier.h -tools/arch/mips/include/asm/barrier.h -tools/arch/powerpc/include/asm/barrier.h -tools/arch/s390/include/asm/barrier.h -tools/arch/sh/include/asm/barrier.h -tools/arch/sparc/include/asm/barrier.h -tools/arch/sparc/include/asm/barrier_32.h -tools/arch/sparc/include/asm/barrier_64.h -tools/arch/tile/include/asm/barrier.h -tools/arch/x86/include/asm/barrier.h -tools/arch/x86/include/asm/cmpxchg.h -tools/arch/x86/include/asm/cpufeatures.h -tools/arch/x86/include/asm/disabled-features.h -tools/arch/x86/include/asm/required-features.h -tools/arch/x86/include/uapi/asm/svm.h -tools/arch/x86/include/uapi/asm/vmx.h -tools/arch/x86/include/uapi/asm/kvm.h -tools/arch/x86/include/uapi/asm/kvm_perf.h -tools/arch/x86/lib/memcpy_64.S -tools/arch/x86/lib/memset_64.S -tools/arch/s390/include/uapi/asm/kvm_perf.h -tools/arch/s390/include/uapi/asm/sie.h -tools/arch/xtensa/include/asm/barrier.h +tools/arch tools/scripts tools/build -tools/arch/x86/include/asm/atomic.h -tools/arch/x86/include/asm/rmwcc.h +tools/include tools/lib/traceevent tools/lib/api tools/lib/bpf @@ -42,52 +16,3 @@ tools/lib/find_bit.c tools/lib/bitmap.c tools/lib/str_error_r.c tools/lib/vsprintf.c -tools/include/asm/alternative-asm.h -tools/include/asm/atomic.h -tools/include/asm/barrier.h -tools/include/asm/bug.h -tools/include/asm-generic/atomic-gcc.h -tools/include/asm-generic/barrier.h -tools/include/asm-generic/bitops/arch_hweight.h -tools/include/asm-generic/bitops/atomic.h -tools/include/asm-generic/bitops/const_hweight.h -tools/include/asm-generic/bitops/__ffs.h -tools/include/asm-generic/bitops/__ffz.h -tools/include/asm-generic/bitops/__fls.h -tools/include/asm-generic/bitops/find.h -tools/include/asm-generic/bitops/fls64.h -tools/include/asm-generic/bitops/fls.h -tools/include/asm-generic/bitops/hweight.h -tools/include/asm-generic/bitops.h -tools/include/linux/atomic.h -tools/include/linux/bitops.h -tools/include/linux/compiler.h -tools/include/linux/compiler-gcc.h -tools/include/linux/coresight-pmu.h -tools/include/linux/bug.h -tools/include/linux/filter.h -tools/include/linux/hash.h -tools/include/linux/kernel.h -tools/include/linux/list.h -tools/include/linux/log2.h -tools/include/uapi/asm-generic/mman-common.h -tools/include/uapi/asm-generic/mman.h -tools/include/uapi/linux/bpf.h -tools/include/uapi/linux/bpf_common.h -tools/include/uapi/linux/fcntl.h -tools/include/uapi/linux/hw_breakpoint.h -tools/include/uapi/linux/mman.h -tools/include/uapi/linux/perf_event.h -tools/include/uapi/linux/stat.h -tools/include/linux/poison.h -tools/include/linux/rbtree.h -tools/include/linux/rbtree_augmented.h -tools/include/linux/refcount.h -tools/include/linux/string.h -tools/include/linux/stringify.h -tools/include/linux/types.h -tools/include/linux/err.h -tools/include/linux/bitmap.h -tools/include/linux/time64.h -tools/arch/*/include/uapi/asm/mman.h -tools/arch/*/include/uapi/asm/perf_regs.h diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 32a64e619028..225454416ed5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # This is a simple wrapper Makefile that calls the main Makefile.perf # with a -j option to do parallel builds diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index bdf0e87f9b29..63f534a0902f 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -35,7 +35,7 @@ ifeq ($(SRCARCH),x86) ifeq (${IS_64_BIT}, 1) CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT -DHAVE_SYSCALL_TABLE -I$(OUTPUT)arch/x86/include/generated ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S - LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 + LIBUNWIND_LIBS = -lunwind-x86_64 -lunwind -llzma $(call detected,CONFIG_X86_64) else LIBUNWIND_LIBS = -lunwind-x86 -llzma -lunwind @@ -103,8 +103,12 @@ ifdef LIBDW_DIR LIBDW_CFLAGS := -I$(LIBDW_DIR)/include LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib endif +DWARFLIBS := -ldw +ifeq ($(findstring -static,${LDFLAGS}),-static) + DWARFLIBS += -lelf -lebl -ldl -lz -llzma -lbz2 +endif FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) -FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw +FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) $(DWARFLIBS) # for linking with debug library, run like: # make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/ @@ -144,7 +148,7 @@ ifndef DEBUG endif ifeq ($(DEBUG),0) -ifeq ($(CC), clang) +ifeq ($(CC_NO_CLANG), 0) CFLAGS += -O3 else CFLAGS += -O6 @@ -180,7 +184,7 @@ ifdef PYTHON_CONFIG PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) - ifeq ($(CC), clang) + ifeq ($(CC_NO_CLANG), 1) PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS)) endif FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) @@ -330,6 +334,11 @@ ifeq ($(feature-sched_getcpu), 1) CFLAGS += -DHAVE_SCHED_GETCPU_SUPPORT endif +ifeq ($(feature-setns), 1) + CFLAGS += -DHAVE_SETNS_SUPPORT + $(call detected,CONFIG_SETNS) +endif + ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT EXTLIBS += -lelf @@ -360,10 +369,6 @@ ifndef NO_LIBELF else CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) LDFLAGS += $(LIBDW_LDFLAGS) - DWARFLIBS := -ldw - ifeq ($(findstring -static,${LDFLAGS}),-static) - DWARFLIBS += -lelf -lebl -lz -llzma -lbz2 - endif EXTLIBS += ${DWARFLIBS} $(call detected,CONFIG_DWARF) endif # PERF_HAVE_DWARF_REGS @@ -500,6 +505,10 @@ ifndef NO_LOCAL_LIBUNWIND EXTLIBS += $(LIBUNWIND_LIBS) LDFLAGS += $(LIBUNWIND_LIBS) endif +ifeq ($(findstring -static,${LDFLAGS}),-static) + # gcc -static links libgcc_eh which contans piece of libunwind + LIBUNWIND_LDFLAGS += -Wl,--allow-multiple-definition +endif ifndef NO_LIBUNWIND CFLAGS += -DHAVE_LIBUNWIND_SUPPORT diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 5008f51a08a2..91ef44bfaf3e 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -33,6 +33,11 @@ include ../scripts/utilities.mak # # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds. # +# Define EXCLUDE_EXTLIBS=-lmylib to exclude libmylib from the auto-generated +# EXTLIBS. +# +# Define EXTRA_PERFLIBS to pass extra libraries to PERFLIBS. +# # Define NO_DWARF if you do not want debug-info analysis feature at all. # # Define WERROR=0 to disable treating any warnings as errors. @@ -159,8 +164,8 @@ LN = ln -f MKDIR = mkdir FIND = find INSTALL = install -FLEX = flex -BISON = bison +FLEX ?= flex +BISON ?= bison STRIP = strip AWK = awk @@ -235,7 +240,7 @@ endif ifeq ($(FEATURES_DUMP),) FEATURE_DUMP_EXPORT := $(realpath $(OUTPUT)FEATURE-DUMP) else -FEATURE_DUMP_EXPORT := $(FEATURES_DUMP) +FEATURE_DUMP_EXPORT := $(realpath $(FEATURES_DUMP)) endif export prefix bindir sharedir sysconfdir DESTDIR @@ -274,7 +279,13 @@ LIBTRACEEVENT = $(TE_PATH)libtraceevent.a export LIBTRACEEVENT LIBTRACEEVENT_DYNAMIC_LIST = $(TE_PATH)libtraceevent-dynamic-list -LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) + +# +# The static build has no dynsym table, so this does not work for +# static build. Looks like linker starts to scream about that now +# (in Fedora 26) so we need to switch it off for static build. +DYNAMIC_LIST_LDFLAGS = -Xlinker --dynamic-list=$(LIBTRACEEVENT_DYNAMIC_LIST) +LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS = $(if $(findstring -static,$(LDFLAGS)),,$(DYNAMIC_LIST_LDFLAGS)) LIBAPI = $(API_PATH)libapi.a export LIBAPI @@ -352,7 +363,8 @@ ifdef ASCIIDOC8 export ASCIIDOC8 endif -LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group +EXTLIBS := $(call filter-out,$(EXCLUDE_EXTLIBS),$(EXTLIBS)) +LIBS = -Wl,--whole-archive $(PERFLIBS) $(EXTRA_PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group ifeq ($(USE_CLANG), 1) CLANGLIBS_LIST = AST Basic CodeGen Driver Frontend Lex Tooling Edit Sema Analysis Parse Serialization @@ -375,6 +387,60 @@ export INSTALL SHELL_PATH SHELL = $(SHELL_PATH) +beauty_outdir := $(OUTPUT)trace/beauty/generated +beauty_ioctl_outdir := $(beauty_outdir)/ioctl +drm_ioctl_array := $(beauty_ioctl_outdir)/drm_ioctl_array.c +drm_hdr_dir := $(srctree)/tools/include/uapi/drm +drm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/drm_ioctl.sh + +# Create output directory if not already present +_dummy := $(shell [ -d '$(beauty_ioctl_outdir)' ] || mkdir -p '$(beauty_ioctl_outdir)') + +$(drm_ioctl_array): $(drm_hdr_dir)/drm.h $(drm_hdr_dir)/i915_drm.h $(drm_ioctl_tbl) + $(Q)$(SHELL) '$(drm_ioctl_tbl)' $(drm_hdr_dir) > $@ + +pkey_alloc_access_rights_array := $(beauty_outdir)/pkey_alloc_access_rights_array.c +asm_generic_hdr_dir := $(srctree)/tools/include/uapi/asm-generic/ +pkey_alloc_access_rights_tbl := $(srctree)/tools/perf/trace/beauty/pkey_alloc_access_rights.sh + +$(pkey_alloc_access_rights_array): $(asm_generic_hdr_dir)/mman-common.h $(pkey_alloc_access_rights_tbl) + $(Q)$(SHELL) '$(pkey_alloc_access_rights_tbl)' $(asm_generic_hdr_dir) > $@ + +sndrv_ctl_ioctl_array := $(beauty_ioctl_outdir)/sndrv_ctl_ioctl_array.c +sndrv_ctl_hdr_dir := $(srctree)/tools/include/uapi/sound +sndrv_ctl_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh + +$(sndrv_ctl_ioctl_array): $(sndrv_ctl_hdr_dir)/asound.h $(sndrv_ctl_ioctl_tbl) + $(Q)$(SHELL) '$(sndrv_ctl_ioctl_tbl)' $(sndrv_ctl_hdr_dir) > $@ + +sndrv_pcm_ioctl_array := $(beauty_ioctl_outdir)/sndrv_pcm_ioctl_array.c +sndrv_pcm_hdr_dir := $(srctree)/tools/include/uapi/sound +sndrv_pcm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh + +$(sndrv_pcm_ioctl_array): $(sndrv_pcm_hdr_dir)/asound.h $(sndrv_pcm_ioctl_tbl) + $(Q)$(SHELL) '$(sndrv_pcm_ioctl_tbl)' $(sndrv_pcm_hdr_dir) > $@ + +kvm_ioctl_array := $(beauty_ioctl_outdir)/kvm_ioctl_array.c +kvm_hdr_dir := $(srctree)/tools/include/uapi/linux +kvm_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/kvm_ioctl.sh + +$(kvm_ioctl_array): $(kvm_hdr_dir)/kvm.h $(kvm_ioctl_tbl) + $(Q)$(SHELL) '$(kvm_ioctl_tbl)' $(kvm_hdr_dir) > $@ + +vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c +vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux +vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh + +$(vhost_virtio_ioctl_array): $(vhost_virtio_hdr_dir)/vhost.h $(vhost_virtio_ioctl_tbl) + $(Q)$(SHELL) '$(vhost_virtio_ioctl_tbl)' $(vhost_virtio_hdr_dir) > $@ + +perf_ioctl_array := $(beauty_ioctl_outdir)/perf_ioctl_array.c +perf_hdr_dir := $(srctree)/tools/include/uapi/linux +perf_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/perf_ioctl.sh + +$(perf_ioctl_array): $(perf_hdr_dir)/perf_event.h $(perf_ioctl_tbl) + $(Q)$(SHELL) '$(perf_ioctl_tbl)' $(perf_hdr_dir) > $@ + all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_DYNAMIC_LIST) @@ -469,7 +535,13 @@ endif __build-dir = $(subst $(OUTPUT),,$(dir $@)) build-dir = $(if $(__build-dir),$(__build-dir),.) -prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders +prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioctl_array) \ + $(pkey_alloc_access_rights_array) \ + $(sndrv_pcm_ioctl_array) \ + $(sndrv_ctl_ioctl_array) \ + $(kvm_ioctl_array) \ + $(vhost_virtio_ioctl_array) \ + $(perf_ioctl_array) $(OUTPUT)%.o: %.c prepare FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@ @@ -512,7 +584,7 @@ $(LIBJVMTI_IN): FORCE $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=jvmti obj=jvmti $(OUTPUT)$(LIBJVMTI): $(LIBJVMTI_IN) - $(QUIET_LINK)$(CC) -shared -Wl,-soname -Wl,$(LIBJVMTI) -o $@ $< -lelf -lrt + $(QUIET_LINK)$(CC) -shared -Wl,-soname -Wl,$(LIBJVMTI) -o $@ $< endif $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h) @@ -703,7 +775,11 @@ install-tests: all install-gtk $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ - $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr' + $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ + $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ + $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib' install-bin: install-tools install-tests install-traceevent-plugins @@ -734,7 +810,14 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ $(OUTPUT)util/intel-pt-decoder/inat-tables.c \ $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ - $(OUTPUT)pmu-events/pmu-events.c + $(OUTPUT)pmu-events/pmu-events.c \ + $(OUTPUT)$(drm_ioctl_array) \ + $(OUTPUT)$(pkey_alloc_access_rights_array) \ + $(OUTPUT)$(sndrv_ctl_ioctl_array) \ + $(OUTPUT)$(sndrv_pcm_ioctl_array) \ + $(OUTPUT)$(kvm_ioctl_array) \ + $(OUTPUT)$(vhost_virtio_ioctl_array) \ + $(OUTPUT)$(perf_ioctl_array) $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean $(python-clean) diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/arch/arm/annotate/instructions.c index 1ce0872b1726..b39b16395aac 100644 --- a/tools/perf/arch/arm/annotate/instructions.c +++ b/tools/perf/arch/arm/annotate/instructions.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/arch/arm/include/dwarf-regs-table.h b/tools/perf/arch/arm/include/dwarf-regs-table.h index f298d034c37b..5a45046fab72 100644 --- a/tools/perf/arch/arm/include/dwarf-regs-table.h +++ b/tools/perf/arch/arm/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h index f619c9c5a4bf..ed20e0253e25 100644 --- a/tools/perf/arch/arm/include/perf_regs.h +++ b/tools/perf/arch/arm/include/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_PERF_REGS_H #define ARCH_PERF_REGS_H diff --git a/tools/perf/arch/arm/tests/dwarf-unwind.c b/tools/perf/arch/arm/tests/dwarf-unwind.c index 62eff847f91c..8cb347760233 100644 --- a/tools/perf/arch/arm/tests/dwarf-unwind.c +++ b/tools/perf/arch/arm/tests/dwarf-unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "perf_regs.h" #include "thread.h" diff --git a/tools/perf/arch/arm/tests/regs_load.S b/tools/perf/arch/arm/tests/regs_load.S index e09e983946fe..6e2495cc4517 100644 --- a/tools/perf/arch/arm/tests/regs_load.S +++ b/tools/perf/arch/arm/tests/regs_load.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #define R0 0x00 diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index 7ce3d1a25133..fbfc055d3f4d 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -266,6 +266,32 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr) return config; } +#ifndef BIT +#define BIT(N) (1UL << (N)) +#endif + +static u64 cs_etmv4_get_config(struct auxtrace_record *itr) +{ + u64 config = 0; + u64 config_opts = 0; + + /* + * The perf event variable config bits represent both + * the command line options and register programming + * bits in ETMv3/PTM. For ETMv4 we must remap options + * to real bits + */ + config_opts = cs_etm_get_config(itr); + if (config_opts & BIT(ETM_OPT_CYCACC)) + config |= BIT(ETM4_CFG_BIT_CYCACC); + if (config_opts & BIT(ETM_OPT_TS)) + config |= BIT(ETM4_CFG_BIT_TS); + if (config_opts & BIT(ETM_OPT_RETSTK)) + config |= BIT(ETM4_CFG_BIT_RETSTK); + + return config; +} + static size_t cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused, struct perf_evlist *evlist __maybe_unused) @@ -363,7 +389,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset, magic = __perf_cs_etmv4_magic; /* Get trace configuration register */ info->priv[*offset + CS_ETMV4_TRCCONFIGR] = - cs_etm_get_config(itr); + cs_etmv4_get_config(itr); /* Get traceID from the framework */ info->priv[*offset + CS_ETMV4_TRCTRACEIDR] = coresight_get_trace_id(cpu); diff --git a/tools/perf/arch/arm/util/unwind-libdw.c b/tools/perf/arch/arm/util/unwind-libdw.c index bacfa00fca39..36ba4c69c3c5 100644 --- a/tools/perf/arch/arm/util/unwind-libdw.c +++ b/tools/perf/arch/arm/util/unwind-libdw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "../../util/unwind-libdw.h" #include "../../util/perf_regs.h" diff --git a/tools/perf/arch/arm/util/unwind-libunwind.c b/tools/perf/arch/arm/util/unwind-libunwind.c index 62c397ed3d97..3a550225dfaf 100644 --- a/tools/perf/arch/arm/util/unwind-libunwind.c +++ b/tools/perf/arch/arm/util/unwind-libunwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile index eebe1ec9d2ee..91de4860faad 100644 --- a/tools/perf/arch/arm64/Makefile +++ b/tools/perf/arch/arm64/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 endif diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/arch/arm64/annotate/instructions.c index 8f1908756cb6..9a3e0523e2c9 100644 --- a/tools/perf/arch/arm64/annotate/instructions.c +++ b/tools/perf/arch/arm64/annotate/instructions.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/arch/arm64/include/dwarf-regs-table.h b/tools/perf/arch/arm64/include/dwarf-regs-table.h index 36e375f5a211..177b2855f797 100644 --- a/tools/perf/arch/arm64/include/dwarf-regs-table.h +++ b/tools/perf/arch/arm64/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h index 4e5af27e3fbf..baaa5e64a3fb 100644 --- a/tools/perf/arch/arm64/include/perf_regs.h +++ b/tools/perf/arch/arm64/include/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_PERF_REGS_H #define ARCH_PERF_REGS_H diff --git a/tools/perf/arch/arm64/tests/dwarf-unwind.c b/tools/perf/arch/arm64/tests/dwarf-unwind.c index cf04a4c91c59..e907f0f4c20c 100644 --- a/tools/perf/arch/arm64/tests/dwarf-unwind.c +++ b/tools/perf/arch/arm64/tests/dwarf-unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "perf_regs.h" #include "thread.h" diff --git a/tools/perf/arch/arm64/tests/regs_load.S b/tools/perf/arch/arm64/tests/regs_load.S index 025b46e579a6..07042511dca9 100644 --- a/tools/perf/arch/arm64/tests/regs_load.S +++ b/tools/perf/arch/arm64/tests/regs_load.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include .text diff --git a/tools/perf/arch/arm64/util/unwind-libunwind.c b/tools/perf/arch/arm64/util/unwind-libunwind.c index b415dfdbccca..002520d4036b 100644 --- a/tools/perf/arch/arm64/util/unwind-libunwind.c +++ b/tools/perf/arch/arm64/util/unwind-libunwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #ifndef REMOTE_UNWIND_LIBUNWIND diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index 6b40e9f01740..8c0cfeb55f8e 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "common.h" diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h index 6b01c736b7d9..a1546509ad24 100644 --- a/tools/perf/arch/common.h +++ b/tools/perf/arch/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_PERF_COMMON_H #define ARCH_PERF_COMMON_H diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile index cc3930904d68..42dab7c8f508 100644 --- a/tools/perf/arch/powerpc/Makefile +++ b/tools/perf/arch/powerpc/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 endif diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c index 3c4004db81b9..b7bc04980fe8 100644 --- a/tools/perf/arch/powerpc/annotate/instructions.c +++ b/tools/perf/arch/powerpc/annotate/instructions.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name) { int i; diff --git a/tools/perf/arch/powerpc/include/arch-tests.h b/tools/perf/arch/powerpc/include/arch-tests.h index 84d8dedef2ed..1c7be75cbc78 100644 --- a/tools/perf/arch/powerpc/include/arch-tests.h +++ b/tools/perf/arch/powerpc/include/arch-tests.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H diff --git a/tools/perf/arch/powerpc/include/dwarf-regs-table.h b/tools/perf/arch/powerpc/include/dwarf-regs-table.h index db4730f5585c..66dc015a733d 100644 --- a/tools/perf/arch/powerpc/include/dwarf-regs-table.h +++ b/tools/perf/arch/powerpc/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/arch/powerpc/include/perf_regs.h b/tools/perf/arch/powerpc/include/perf_regs.h index c12f4e804f66..00e37b106913 100644 --- a/tools/perf/arch/powerpc/include/perf_regs.h +++ b/tools/perf/arch/powerpc/include/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_PERF_REGS_H #define ARCH_PERF_REGS_H diff --git a/tools/perf/arch/powerpc/tests/arch-tests.c b/tools/perf/arch/powerpc/tests/arch-tests.c index e24f46241f40..8c3fbd4af817 100644 --- a/tools/perf/arch/powerpc/tests/arch-tests.c +++ b/tools/perf/arch/powerpc/tests/arch-tests.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "tests/tests.h" #include "arch-tests.h" diff --git a/tools/perf/arch/powerpc/tests/dwarf-unwind.c b/tools/perf/arch/powerpc/tests/dwarf-unwind.c index 0bac3137ccbd..30cbbd6d5be0 100644 --- a/tools/perf/arch/powerpc/tests/dwarf-unwind.c +++ b/tools/perf/arch/powerpc/tests/dwarf-unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "perf_regs.h" #include "thread.h" diff --git a/tools/perf/arch/powerpc/tests/regs_load.S b/tools/perf/arch/powerpc/tests/regs_load.S index d76c9a32f327..36a20b0033f9 100644 --- a/tools/perf/arch/powerpc/tests/regs_load.S +++ b/tools/perf/arch/powerpc/tests/regs_load.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include /* Offset is based on macros from arch/powerpc/include/uapi/asm/ptrace.h. */ diff --git a/tools/perf/arch/powerpc/util/book3s_hcalls.h b/tools/perf/arch/powerpc/util/book3s_hcalls.h index 0dd6b7f2d44f..54cfa0530e86 100644 --- a/tools/perf/arch/powerpc/util/book3s_hcalls.h +++ b/tools/perf/arch/powerpc/util/book3s_hcalls.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_PERF_BOOK3S_HV_HCALLS_H #define ARCH_PERF_BOOK3S_HV_HCALLS_H diff --git a/tools/perf/arch/powerpc/util/book3s_hv_exits.h b/tools/perf/arch/powerpc/util/book3s_hv_exits.h index e68ba2da8970..853b95d1e139 100644 --- a/tools/perf/arch/powerpc/util/book3s_hv_exits.h +++ b/tools/perf/arch/powerpc/util/book3s_hv_exits.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_PERF_BOOK3S_HV_EXITS_H #define ARCH_PERF_BOOK3S_HV_EXITS_H diff --git a/tools/perf/arch/powerpc/util/header.c b/tools/perf/arch/powerpc/util/header.c index 9aaa6f5a9347..7a4cf80c207a 100644 --- a/tools/perf/arch/powerpc/util/header.c +++ b/tools/perf/arch/powerpc/util/header.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c index 249723f0e6a9..596ad6aedaac 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/arch/powerpc/util/kvm-stat.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "util/kvm-stat.h" #include "util/parse-events.h" diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c index f860dc411f69..ec50939b0418 100644 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ b/tools/perf/arch/powerpc/util/perf_regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/arch/powerpc/util/sym-handling.c b/tools/perf/arch/powerpc/util/sym-handling.c index bf9a2594572c..9c4e23d8c8ce 100644 --- a/tools/perf/arch/powerpc/util/sym-handling.c +++ b/tools/perf/arch/powerpc/util/sym-handling.c @@ -126,7 +126,7 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev, struct rb_node *tmp; int i = 0; - map = get_target_map(pev->target, pev->uprobes); + map = get_target_map(pev->target, pev->nsi, pev->uprobes); if (!map || map__load(map) < 0) return; diff --git a/tools/perf/arch/powerpc/util/unwind-libdw.c b/tools/perf/arch/powerpc/util/unwind-libdw.c index 3a24b3c43273..7a1f05ef2fc0 100644 --- a/tools/perf/arch/powerpc/util/unwind-libdw.c +++ b/tools/perf/arch/powerpc/util/unwind-libdw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "../../util/unwind-libdw.h" #include "../../util/perf_regs.h" diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c index 745b4b1b8b21..c9a81673e8aa 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/arch/s390/annotate/instructions.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name) { struct ins_ops *ops = NULL; diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h index 9da74a933bd6..792d4c277225 100644 --- a/tools/perf/arch/s390/include/dwarf-regs-table.h +++ b/tools/perf/arch/s390/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c index 0469df02ee62..0dff5b2ed1e5 100644 --- a/tools/perf/arch/s390/util/dwarf-regs.c +++ b/tools/perf/arch/s390/util/dwarf-regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Mapping of DWARF debug register numbers into register names. * diff --git a/tools/perf/arch/s390/util/machine.c b/tools/perf/arch/s390/util/machine.c index b9a95a1a8e69..0b2054007314 100644 --- a/tools/perf/arch/s390/util/machine.c +++ b/tools/perf/arch/s390/util/machine.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/arch/sh/include/dwarf-regs-table.h b/tools/perf/arch/sh/include/dwarf-regs-table.h index 3a2deaf3dab4..900e69619970 100644 --- a/tools/perf/arch/sh/include/dwarf-regs-table.h +++ b/tools/perf/arch/sh/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/arch/sparc/include/dwarf-regs-table.h b/tools/perf/arch/sparc/include/dwarf-regs-table.h index 12c07619002c..35ede84a6b0d 100644 --- a/tools/perf/arch/sparc/include/dwarf-regs-table.h +++ b/tools/perf/arch/sparc/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile index 6c9211b18ec0..d74eaa7aa927 100644 --- a/tools/perf/arch/x86/Makefile +++ b/tools/perf/arch/x86/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 endif @@ -20,7 +21,7 @@ _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)') $(header): $(sys)/syscall_64.tbl $(systbl) @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \ (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \ - || echo "Warning: x86_64's syscall_64.tbl differs from kernel" >&2 )) || true + || echo "Warning: Kernel ABI header at 'tools/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@ clean:: diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c index c1625f256df3..4adfb4ce2864 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 static struct ins x86__instructions[] = { { .name = "add", .ops = &mov_ops, }, { .name = "addl", .ops = &mov_ops, }, @@ -76,3 +77,49 @@ static struct ins x86__instructions[] = { { .name = "xbeginq", .ops = &jump_ops, }, { .name = "retq", .ops = &ret_ops, }, }; + +static bool x86__ins_is_fused(struct arch *arch, const char *ins1, + const char *ins2) +{ + if (arch->family != 6 || arch->model < 0x1e || strstr(ins2, "jmp")) + return false; + + if (arch->model == 0x1e) { + /* Nehalem */ + if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) || + strstr(ins1, "test")) { + return true; + } + } else { + /* Newer platform */ + if ((strstr(ins1, "cmp") && !strstr(ins1, "xchg")) || + strstr(ins1, "test") || + strstr(ins1, "add") || + strstr(ins1, "sub") || + strstr(ins1, "and") || + strstr(ins1, "inc") || + strstr(ins1, "dec")) { + return true; + } + } + + return false; +} + +static int x86__cpuid_parse(struct arch *arch, char *cpuid) +{ + unsigned int family, model, stepping; + int ret; + + /* + * cpuid = "GenuineIntel,family,model,stepping" + */ + ret = sscanf(cpuid, "%*[^,],%u,%u,%u", &family, &model, &stepping); + if (ret == 3) { + arch->family = family; + arch->model = model; + return 0; + } + + return -1; +} diff --git a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh index 49a18b9ad9cf..029a72c20b19 100755 --- a/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh +++ b/tools/perf/arch/x86/entry/syscalls/syscalltbl.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 in="$1" arch="$2" diff --git a/tools/perf/arch/x86/include/arch-tests.h b/tools/perf/arch/x86/include/arch-tests.h index b48de2f5813c..9834fdc7c59e 100644 --- a/tools/perf/arch/x86/include/arch-tests.h +++ b/tools/perf/arch/x86/include/arch-tests.h @@ -1,11 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H +#include +struct test; + /* Tests */ -int test__rdpmc(int subtest); -int test__perf_time_to_tsc(int subtest); -int test__insn_x86(int subtest); -int test__intel_cqm_count_nmi_context(int subtest); +int test__rdpmc(struct test *test __maybe_unused, int subtest); +int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest); +int test__insn_x86(struct test *test __maybe_unused, int subtest); +int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest); #ifdef HAVE_DWARF_UNWIND_SUPPORT struct thread; diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h index 9b5e5cbb4209..b9bd5dc9d4c0 100644 --- a/tools/perf/arch/x86/include/dwarf-regs-table.h +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h index 7df517acfef8..7f6d538f8a89 100644 --- a/tools/perf/arch/x86/include/perf_regs.h +++ b/tools/perf/arch/x86/include/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef ARCH_PERF_REGS_H #define ARCH_PERF_REGS_H diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c index 99d66191e56c..34a078136a47 100644 --- a/tools/perf/arch/x86/tests/arch-tests.c +++ b/tools/perf/arch/x86/tests/arch-tests.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "tests/tests.h" #include "arch-tests.h" diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index 7f209ce827bf..95036c7a59e8 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "perf_regs.h" #include "thread.h" diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-32.c b/tools/perf/arch/x86/tests/insn-x86-dat-32.c index 3cbf6fad169f..fab3c6de73fa 100644 --- a/tools/perf/arch/x86/tests/insn-x86-dat-32.c +++ b/tools/perf/arch/x86/tests/insn-x86-dat-32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk * from insn-x86-dat-src.c for inclusion by insn-x86.c diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-64.c b/tools/perf/arch/x86/tests/insn-x86-dat-64.c index aa512fa944dd..c57f34603b9b 100644 --- a/tools/perf/arch/x86/tests/insn-x86-dat-64.c +++ b/tools/perf/arch/x86/tests/insn-x86-dat-64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Generated by gen-insn-x86-dat.sh and gen-insn-x86-dat.awk * from insn-x86-dat-src.c for inclusion by insn-x86.c diff --git a/tools/perf/arch/x86/tests/insn-x86-dat-src.c b/tools/perf/arch/x86/tests/insn-x86-dat-src.c index 6cdb65d25b79..891415b10984 100644 --- a/tools/perf/arch/x86/tests/insn-x86-dat-src.c +++ b/tools/perf/arch/x86/tests/insn-x86-dat-src.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file contains instructions for testing by the test titled: * diff --git a/tools/perf/arch/x86/tests/insn-x86.c b/tools/perf/arch/x86/tests/insn-x86.c index 08d9b2bc185c..a5d24ae5810d 100644 --- a/tools/perf/arch/x86/tests/insn-x86.c +++ b/tools/perf/arch/x86/tests/insn-x86.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "debug.h" @@ -171,7 +172,7 @@ static int test_data_set(struct test_data *dat_set, int x86_64) * verbose (-v) option to see all the instructions and whether or not they * decoded successfuly. */ -int test__insn_x86(int subtest __maybe_unused) +int test__insn_x86(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret = 0; diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index f9713a71d77e..90a4a8c58a62 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tests/tests.h" #include "perf.h" #include "cloexec.h" @@ -36,7 +37,7 @@ static pid_t spawn(void) * the last read counter value to avoid triggering a WARN_ON_ONCE() in * smp_call_function_many() caused by sending IPIs from NMI context. */ -int test__intel_cqm_count_nmi_context(int subtest __maybe_unused) +int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evlist *evlist = NULL; struct perf_evsel *evsel = NULL; diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c index e3ae9cff2b67..b59678e8c1e2 100644 --- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c +++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -37,7 +38,7 @@ * %0 is returned, otherwise %-1 is returned. If TSC conversion is not * supported then then the test passes but " (not supported)" is printed. */ -int test__perf_time_to_tsc(int subtest __maybe_unused) +int test__perf_time_to_tsc(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 500cf96db979..7a11f02d6c6c 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -154,7 +155,7 @@ out_close: return 0; } -int test__rdpmc(int subtest __maybe_unused) +int test__rdpmc(struct test *test __maybe_unused, int subtest __maybe_unused) { int status = 0; int wret = 0; diff --git a/tools/perf/arch/x86/tests/regs_load.S b/tools/perf/arch/x86/tests/regs_load.S index 60875d5c556c..bbe5a0d16e51 100644 --- a/tools/perf/arch/x86/tests/regs_load.S +++ b/tools/perf/arch/x86/tests/regs_load.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #include #define AX 0 diff --git a/tools/perf/arch/x86/util/group.c b/tools/perf/arch/x86/util/group.c index 37f92aa39a5d..e2f8034b8973 100644 --- a/tools/perf/arch/x86/util/group.c +++ b/tools/perf/arch/x86/util/group.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "api/fs/fs.h" #include "util/group.h" diff --git a/tools/perf/arch/x86/util/header.c b/tools/perf/arch/x86/util/header.c index a74a48db26f5..33027c5e6f92 100644 --- a/tools/perf/arch/x86/util/header.c +++ b/tools/perf/arch/x86/util/header.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index 9535be57033f..db0ba8caf5a2 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -701,6 +701,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, perf_evsel__set_sample_bit(switch_evsel, TID); perf_evsel__set_sample_bit(switch_evsel, TIME); perf_evsel__set_sample_bit(switch_evsel, CPU); + perf_evsel__reset_sample_bit(switch_evsel, BRANCH_STACK); opts->record_switch_events = false; ptr->have_sched_switch = 3; @@ -752,6 +753,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, tracking_evsel->attr.freq = 0; tracking_evsel->attr.sample_period = 1; + tracking_evsel->no_aux_samples = true; if (need_immediate) tracking_evsel->immediate = true; @@ -761,6 +763,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, /* And the CPU for switch events */ perf_evsel__set_sample_bit(tracking_evsel, CPU); } + perf_evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK); } /* diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/arch/x86/util/kvm-stat.c index bf817beca0a8..b32409a0e546 100644 --- a/tools/perf/arch/x86/util/kvm-stat.c +++ b/tools/perf/arch/x86/util/kvm-stat.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "../../util/kvm-stat.h" #include diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c index f95edebfb716..4b2caf6d48e7 100644 --- a/tools/perf/arch/x86/util/perf_regs.c +++ b/tools/perf/arch/x86/util/perf_regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/arch/x86/util/pmu.c b/tools/perf/arch/x86/util/pmu.c index 79fe07158d00..63a74c32ddc5 100644 --- a/tools/perf/arch/x86/util/pmu.c +++ b/tools/perf/arch/x86/util/pmu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/arch/x86/util/tsc.c b/tools/perf/arch/x86/util/tsc.c index 2e5567c94e09..06bae7023a51 100644 --- a/tools/perf/arch/x86/util/tsc.c +++ b/tools/perf/arch/x86/util/tsc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/arch/x86/util/unwind-libdw.c b/tools/perf/arch/x86/util/unwind-libdw.c index 38dc9bb2a7c9..fda8f4206ee4 100644 --- a/tools/perf/arch/x86/util/unwind-libdw.c +++ b/tools/perf/arch/x86/util/unwind-libdw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "../../util/unwind-libdw.h" #include "../../util/perf_regs.h" diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c index 4f16661cbdbb..9c917f80c906 100644 --- a/tools/perf/arch/x86/util/unwind-libunwind.c +++ b/tools/perf/arch/x86/util/unwind-libunwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef REMOTE_UNWIND_LIBUNWIND #include diff --git a/tools/perf/arch/xtensa/include/dwarf-regs-table.h b/tools/perf/arch/xtensa/include/dwarf-regs-table.h index aa0444a33fe6..d7c9f1fb4444 100644 --- a/tools/perf/arch/xtensa/include/dwarf-regs-table.h +++ b/tools/perf/arch/xtensa/include/dwarf-regs-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef DEFINE_DWARF_REGSTR_TABLE /* This is included in perf/util/dwarf-regs.c */ diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h index 842ab2781cdc..6c9fcd757f31 100644 --- a/tools/perf/bench/bench.h +++ b/tools/perf/bench/bench.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BENCH_H #define BENCH_H diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c index fe16b310097f..58ae6ed8f38b 100644 --- a/tools/perf/bench/futex-hash.c +++ b/tools/perf/bench/futex-hash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2013 Davidlohr Bueso * diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 73a1c44ea63c..08653ae8a8c4 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2015 Davidlohr Bueso. */ diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 41786cbea24c..1058c194608a 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2013 Davidlohr Bueso * diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index 4ab12c8e016a..b4732dad9f89 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2015 Davidlohr Bueso. * diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 2fa49222ef8d..8c5c0b6b5c97 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2013 Davidlohr Bueso * diff --git a/tools/perf/bench/futex.h b/tools/perf/bench/futex.h index e44fd3239530..db4853f209c7 100644 --- a/tools/perf/bench/futex.h +++ b/tools/perf/bench/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Glibc independent futex library for testing kernel functionality. * Shamelessly stolen from Darren Hart diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c index fbd732b54047..0251dd348124 100644 --- a/tools/perf/bench/mem-functions.c +++ b/tools/perf/bench/mem-functions.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * mem-memcpy.c * diff --git a/tools/perf/bench/mem-memcpy-arch.h b/tools/perf/bench/mem-memcpy-arch.h index 5aad2a9408b0..5bcaec5601a8 100644 --- a/tools/perf/bench/mem-memcpy-arch.h +++ b/tools/perf/bench/mem-memcpy-arch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef HAVE_ARCH_X86_64_SUPPORT diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm-def.h b/tools/perf/bench/mem-memcpy-x86-64-asm-def.h index 8c0c1a2770c8..50ae8bd58296 100644 --- a/tools/perf/bench/mem-memcpy-x86-64-asm-def.h +++ b/tools/perf/bench/mem-memcpy-x86-64-asm-def.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ MEMCPY_FN(memcpy_orig, "x86-64-unrolled", diff --git a/tools/perf/bench/mem-memcpy-x86-64-asm.S b/tools/perf/bench/mem-memcpy-x86-64-asm.S index f700369bb0f6..b43f8d2a34ec 100644 --- a/tools/perf/bench/mem-memcpy-x86-64-asm.S +++ b/tools/perf/bench/mem-memcpy-x86-64-asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Various wrappers to make the kernel .S file build in user-space: */ diff --git a/tools/perf/bench/mem-memset-arch.h b/tools/perf/bench/mem-memset-arch.h index 0d15786d9ae3..53f45482663f 100644 --- a/tools/perf/bench/mem-memset-arch.h +++ b/tools/perf/bench/mem-memset-arch.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifdef HAVE_ARCH_X86_64_SUPPORT diff --git a/tools/perf/bench/mem-memset-x86-64-asm-def.h b/tools/perf/bench/mem-memset-x86-64-asm-def.h index f02d028771d9..dac6d2b7c39b 100644 --- a/tools/perf/bench/mem-memset-x86-64-asm-def.h +++ b/tools/perf/bench/mem-memset-x86-64-asm-def.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ MEMSET_FN(memset_orig, "x86-64-unrolled", diff --git a/tools/perf/bench/mem-memset-x86-64-asm.S b/tools/perf/bench/mem-memset-x86-64-asm.S index 58407aa24c1b..d550bd526162 100644 --- a/tools/perf/bench/mem-memset-x86-64-asm.S +++ b/tools/perf/bench/mem-memset-x86-64-asm.S @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define memset MEMSET /* don't hide glibc's memset() */ #define altinstr_replacement text #define globl p2align 4; .globl diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 469d65b21122..d95fdcc26f4b 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * numa.c * diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index 4f961e74535b..f9d7641ae833 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * * sched-messaging.c diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index a152737370c5..0591be008f2a 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * * sched-pipe.c diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 7a5dc7e5c577..3d32aa45016d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-annotate.c * @@ -177,14 +178,11 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, */ process_branch_stack(sample->branch_stack, al, sample); - sample->period = 1; - sample->weight = 1; - he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true); if (he == NULL) return -ENOMEM; - ret = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); + ret = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); hists__inc_nr_samples(hists, true); return ret; } @@ -397,6 +395,8 @@ int cmd_annotate(int argc, const char **argv) .namespaces = perf_event__process_namespaces, .attr = perf_event__process_attr, .build_id = perf_event__process_build_id, + .tracing_data = perf_event__process_tracing_data, + .feature = perf_event__process_feature, .ordered_events = true, .ordering_requires_timestamps = true, }, @@ -404,7 +404,7 @@ int cmd_annotate(int argc, const char **argv) struct perf_data_file file = { .mode = PERF_DATA_MODE_READ, }; - const struct option options[] = { + struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", @@ -446,13 +446,20 @@ int cmd_annotate(int argc, const char **argv) "Show event group information together"), OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, "Show a column with the sum of periods"), + OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, + "Show a column with the number of samples"), OPT_CALLBACK_DEFAULT(0, "stdio-color", NULL, "mode", "'always' (default), 'never' or 'auto' only applicable to --stdio mode", stdio__config_color, "always"), OPT_END() }; - int ret = hists__init(); + int ret; + set_option_flag(options, 0, "show-total-period", PARSE_OPT_EXCLUSIVE); + set_option_flag(options, 0, "show-nr-samples", PARSE_OPT_EXCLUSIVE); + + + ret = hists__init(); if (ret < 0) return ret; @@ -468,6 +475,11 @@ int cmd_annotate(int argc, const char **argv) annotate.sym_hist_filter = argv[0]; } + if (symbol_conf.show_nr_samples && annotate.use_gtk) { + pr_err("--show-nr-samples is not available in --gtk mode at this time\n"); + return ret; + } + if (quiet) perf_quiet_option(); diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index 445e62881254..17a6bcd01aa6 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-bench.c * diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 9eba7f1add1f..5f53a7ad5ef3 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-buildid-cache.c * @@ -14,6 +15,7 @@ #include #include "builtin.h" #include "perf.h" +#include "namespaces.h" #include "util/cache.h" #include "util/debug.h" #include "util/header.h" @@ -165,33 +167,41 @@ static int build_id_cache__add_kcore(const char *filename, bool force) return 0; } -static int build_id_cache__add_file(const char *filename) +static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi) { char sbuild_id[SBUILD_ID_SIZE]; u8 build_id[BUILD_ID_SIZE]; int err; + struct nscookie nsc; - if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { + nsinfo__mountns_enter(nsi, &nsc); + err = filename__read_build_id(filename, &build_id, sizeof(build_id)); + nsinfo__mountns_exit(&nsc); + if (err < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); - err = build_id_cache__add_s(sbuild_id, filename, + err = build_id_cache__add_s(sbuild_id, filename, nsi, false, false); pr_debug("Adding %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); return err; } -static int build_id_cache__remove_file(const char *filename) +static int build_id_cache__remove_file(const char *filename, struct nsinfo *nsi) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[SBUILD_ID_SIZE]; + struct nscookie nsc; int err; - if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { + nsinfo__mountns_enter(nsi, &nsc); + err = filename__read_build_id(filename, &build_id, sizeof(build_id)); + nsinfo__mountns_exit(&nsc); + if (err < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } @@ -204,13 +214,13 @@ static int build_id_cache__remove_file(const char *filename) return err; } -static int build_id_cache__purge_path(const char *pathname) +static int build_id_cache__purge_path(const char *pathname, struct nsinfo *nsi) { struct strlist *list; struct str_node *pos; int err; - err = build_id_cache__list_build_ids(pathname, &list); + err = build_id_cache__list_build_ids(pathname, nsi, &list); if (err) goto out; @@ -234,7 +244,7 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) char filename[PATH_MAX]; u8 build_id[BUILD_ID_SIZE]; - if (dso__build_id_filename(dso, filename, sizeof(filename)) && + if (dso__build_id_filename(dso, filename, sizeof(filename), false) && filename__read_build_id(filename, build_id, sizeof(build_id)) != sizeof(build_id)) { if (errno == ENOENT) @@ -256,24 +266,30 @@ static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *f return 0; } -static int build_id_cache__update_file(const char *filename) +static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi) { u8 build_id[BUILD_ID_SIZE]; char sbuild_id[SBUILD_ID_SIZE]; + struct nscookie nsc; - int err = 0; + int err; - if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { + nsinfo__mountns_enter(nsi, &nsc); + err = filename__read_build_id(filename, &build_id, sizeof(build_id)); + nsinfo__mountns_exit(&nsc); + if (err < 0) { pr_debug("Couldn't read a build-id in %s\n", filename); return -1; } + err = 0; build_id__sprintf(build_id, sizeof(build_id), sbuild_id); if (build_id_cache__cached(sbuild_id)) err = build_id_cache__remove_s(sbuild_id); if (!err) - err = build_id_cache__add_s(sbuild_id, filename, false, false); + err = build_id_cache__add_s(sbuild_id, filename, nsi, false, + false); pr_debug("Updating %s %s: %s\n", sbuild_id, filename, err ? "FAIL" : "Ok"); @@ -286,6 +302,7 @@ int cmd_buildid_cache(int argc, const char **argv) struct strlist *list; struct str_node *pos; int ret = 0; + int ns_id = -1; bool force = false; char const *add_name_list_str = NULL, *remove_name_list_str = NULL, @@ -299,6 +316,7 @@ int cmd_buildid_cache(int argc, const char **argv) .mode = PERF_DATA_MODE_READ, }; struct perf_session *session = NULL; + struct nsinfo *nsi = NULL; const struct option buildid_cache_options[] = { OPT_STRING('a', "add", &add_name_list_str, @@ -315,6 +333,7 @@ int cmd_buildid_cache(int argc, const char **argv) OPT_STRING('u', "update", &update_name_list_str, "file list", "file(s) to update"), OPT_INCR('v', "verbose", &verbose, "be more verbose"), + OPT_INTEGER(0, "target-ns", &ns_id, "target pid for namespace context"), OPT_END() }; const char * const buildid_cache_usage[] = { @@ -330,6 +349,9 @@ int cmd_buildid_cache(int argc, const char **argv) !missing_filename && !update_name_list_str)) usage_with_options(buildid_cache_usage, buildid_cache_options); + if (ns_id > 0) + nsi = nsinfo__new(ns_id); + if (missing_filename) { file.path = missing_filename; file.force = force; @@ -348,7 +370,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(add_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__add_file(pos->s)) { + if (build_id_cache__add_file(pos->s, nsi)) { if (errno == EEXIST) { pr_debug("%s already in the cache\n", pos->s); @@ -366,7 +388,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(remove_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__remove_file(pos->s)) { + if (build_id_cache__remove_file(pos->s, nsi)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -384,7 +406,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(purge_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__purge_path(pos->s)) { + if (build_id_cache__purge_path(pos->s, nsi)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -405,7 +427,7 @@ int cmd_buildid_cache(int argc, const char **argv) list = strlist__new(update_name_list_str, NULL); if (list) { strlist__for_each_entry(pos, list) - if (build_id_cache__update_file(pos->s)) { + if (build_id_cache__update_file(pos->s, nsi)) { if (errno == ENOENT) { pr_debug("%s wasn't in the cache\n", pos->s); @@ -424,6 +446,7 @@ int cmd_buildid_cache(int argc, const char **argv) out: perf_session__delete(session); + nsinfo__zput(nsi); return ret; } diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index fdaca16e0c74..ec2f327cd79d 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-buildid-list.c * diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 475999e48f66..fd32ad08c6d4 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This is rewrite of original c2c tool introduced in here: * http://lwn.net/Articles/588866/ diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index ece45582a48d..abfa49eaf7fd 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-config.c * @@ -13,6 +14,7 @@ #include "util/util.h" #include "util/debug.h" #include "util/config.h" +#include static bool use_system_config, use_user_config; @@ -58,7 +60,7 @@ static int set_config(struct perf_config_set *set, const char *file_name, fprintf(fp, "[%s]\n", section->name); perf_config_items__for_each_entry(§ion->items, item) { - if (!use_system_config && section->from_system_config) + if (!use_system_config && item->from_system_config) continue; if (item->value) fprintf(fp, "\t%s = %s\n", @@ -79,7 +81,7 @@ static int show_spec_config(struct perf_config_set *set, const char *var) return -1; perf_config_items__for_each_entry(&set->sections, section) { - if (prefixcmp(var, section->name) != 0) + if (!strstarts(var, section->name)) continue; perf_config_items__for_each_entry(§ion->items, item) { diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index 0adb5f82335a..dde25d4ca56d 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "builtin.h" #include "perf.h" @@ -69,7 +70,7 @@ static int cmd_data_convert(int argc, const char **argv) }; #ifndef HAVE_LIBBABELTRACE_SUPPORT - pr_err("No conversion support compiled in.\n"); + pr_err("No conversion support compiled in. perf should be compiled with environment variables LIBBABELTRACE=1 and LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n"); return -1; #endif diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 0cd4cf6a344b..56223bdfa205 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-diff.c * diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 6d210e40d611..cdd145613f60 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Builtin evlist command: Show the list of event selectors present * in a perf.data file. diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index dd26c62c9893..25a42acabee1 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -381,7 +381,7 @@ static int perf_ftrace_config(const char *var, const char *value, void *cb) { struct perf_ftrace *ftrace = cb; - if (prefixcmp(var, "ftrace.")) + if (!strstarts(var, "ftrace.")) return 0; if (strcmp(var, "ftrace.tracer")) diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 530a7f2fa0f3..bd1fedef3d1c 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-help.c * @@ -90,7 +91,7 @@ static int check_emacsclient_version(void) */ finish_command(&ec_process); - if (prefixcmp(buffer.buf, "emacsclient")) { + if (!strstarts(buffer.buf, "emacsclient")) { fprintf(stderr, "Failed to parse emacsclient version.\n"); goto out; } @@ -283,7 +284,7 @@ static int perf_help_config(const char *var, const char *value, void *cb) add_man_viewer(value); return 0; } - if (!prefixcmp(var, "man.")) + if (!strstarts(var, "man.")) return add_man_viewer_info(var, value); return 0; @@ -313,7 +314,7 @@ static const char *cmd_to_page(const char *perf_cmd) if (!perf_cmd) return "perf"; - else if (!prefixcmp(perf_cmd, "perf")) + else if (!strstarts(perf_cmd, "perf")) return perf_cmd; return asprintf(&s, "perf-%s", perf_cmd) < 0 ? NULL : s; diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ea8db38eedd1..3e0e73b0dc67 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-inject.c * @@ -770,6 +771,7 @@ int cmd_inject(int argc, const char **argv) .finished_round = perf_event__repipe_oe_synth, .build_id = perf_event__repipe_op2_synth, .id_index = perf_event__repipe_op2_synth, + .feature = perf_event__repipe_op2_synth, }, .input_name = "-", .samples = LIST_HEAD_INIT(inject.samples), diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index a1497c516d85..35d4b9c9a9e8 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "builtin.h" #include "perf.h" @@ -627,7 +628,6 @@ static const struct { { "GFP_HIGHUSER_MOVABLE", "HUM" }, { "GFP_HIGHUSER", "HU" }, { "GFP_USER", "U" }, - { "GFP_TEMPORARY", "TMP" }, { "GFP_KERNEL_ACCOUNT", "KAC" }, { "GFP_KERNEL", "K" }, { "GFP_NOFS", "NF" }, diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index f309c3773522..5fb40368d5d1 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "builtin.h" #include "perf.h" diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 4bf2cb4d25aa..eeedbe433776 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-list.c * diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index ff98652484a7..fe69cd6b89e1 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "builtin.h" diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index e001c0290793..4db960085273 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -23,6 +24,7 @@ struct perf_mem { bool hide_unresolved; bool dump_raw; bool force; + bool phys_addr; int operation; const char *cpu_list; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); @@ -101,6 +103,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem) rec_argv[i++] = "-d"; + if (mem->phys_addr) + rec_argv[i++] = "--phys-data"; + for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { if (!perf_mem_events[j].record) continue; @@ -161,30 +166,60 @@ dump_raw_samples(struct perf_tool *tool, if (al.map != NULL) al.map->dso->hit = 1; - if (symbol_conf.field_sep) { - fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64 - "%s0x%"PRIx64"%s%s:%s\n"; - } else { - fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 - "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n"; - symbol_conf.field_sep = " "; - } + if (mem->phys_addr) { + if (symbol_conf.field_sep) { + fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s0x%016"PRIx64 + "%s%"PRIu64"%s0x%"PRIx64"%s%s:%s\n"; + } else { + fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 + "%s0x%016"PRIx64"%s%5"PRIu64"%s0x%06"PRIx64 + "%s%s:%s\n"; + symbol_conf.field_sep = " "; + } - printf(fmt, - sample->pid, - symbol_conf.field_sep, - sample->tid, - symbol_conf.field_sep, - sample->ip, - symbol_conf.field_sep, - sample->addr, - symbol_conf.field_sep, - sample->weight, - symbol_conf.field_sep, - sample->data_src, - symbol_conf.field_sep, - al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", - al.sym ? al.sym->name : "???"); + printf(fmt, + sample->pid, + symbol_conf.field_sep, + sample->tid, + symbol_conf.field_sep, + sample->ip, + symbol_conf.field_sep, + sample->addr, + symbol_conf.field_sep, + sample->phys_addr, + symbol_conf.field_sep, + sample->weight, + symbol_conf.field_sep, + sample->data_src, + symbol_conf.field_sep, + al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", + al.sym ? al.sym->name : "???"); + } else { + if (symbol_conf.field_sep) { + fmt = "%d%s%d%s0x%"PRIx64"%s0x%"PRIx64"%s%"PRIu64 + "%s0x%"PRIx64"%s%s:%s\n"; + } else { + fmt = "%5d%s%5d%s0x%016"PRIx64"%s0x016%"PRIx64 + "%s%5"PRIu64"%s0x%06"PRIx64"%s%s:%s\n"; + symbol_conf.field_sep = " "; + } + + printf(fmt, + sample->pid, + symbol_conf.field_sep, + sample->tid, + symbol_conf.field_sep, + sample->ip, + symbol_conf.field_sep, + sample->addr, + symbol_conf.field_sep, + sample->weight, + symbol_conf.field_sep, + sample->data_src, + symbol_conf.field_sep, + al.map ? (al.map->dso ? al.map->dso->long_name : "???") : "???", + al.sym ? al.sym->name : "???"); + } out_put: addr_location__put(&al); return 0; @@ -224,7 +259,10 @@ static int report_raw_events(struct perf_mem *mem) if (ret < 0) goto out_delete; - printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); + if (mem->phys_addr) + printf("# PID, TID, IP, ADDR, PHYS ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); + else + printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); ret = perf_session__process_events(session); @@ -254,9 +292,16 @@ static int report_events(int argc, const char **argv, struct perf_mem *mem) * there is no weight (cost) associated with stores, so don't print * the column */ - if (!(mem->operation & MEM_OPERATION_LOAD)) - rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," - "dso_daddr,tlb,locked"; + if (!(mem->operation & MEM_OPERATION_LOAD)) { + if (mem->phys_addr) + rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," + "dso_daddr,tlb,locked,phys_daddr"; + else + rep_argv[i++] = "--sort=mem,sym,dso,symbol_daddr," + "dso_daddr,tlb,locked"; + } else if (mem->phys_addr) + rep_argv[i++] = "--sort=local_weight,mem,sym,dso,symbol_daddr," + "dso_daddr,snoop,tlb,locked,phys_daddr"; for (j = 1; j < argc; j++, i++) rep_argv[i] = argv[j]; @@ -373,6 +418,7 @@ int cmd_mem(int argc, const char **argv) "separator for columns, no spaces will be added" " between columns '.' is reserved."), OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"), + OPT_BOOLEAN('p', "phys-data", &mem.phys_addr, "Record/Report sample physical addresses"), OPT_END() }; const char *const mem_subcommands[] = { "record", "report", NULL }; diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index cf9f9e9c2fc0..c0065923a525 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -58,6 +58,7 @@ static struct { struct line_range line_range; char *target; struct strfilter *filter; + struct nsinfo *nsi; } params; /* Parse an event definition. Note that any error must die. */ @@ -80,6 +81,9 @@ static int parse_probe_event(const char *str) params.target_used = true; } + if (params.nsi) + pev->nsi = nsinfo__get(params.nsi); + /* Parse a perf-probe command into event */ ret = parse_perf_probe_command(str, pev); pr_debug("%d arguments\n", pev->nargs); @@ -189,7 +193,7 @@ static int opt_set_target(const struct option *opt, const char *str, /* Expand given path to absolute path, except for modulename */ if (params.uprobes || strchr(str, '/')) { - tmp = realpath(str, NULL); + tmp = nsinfo__realpath(str, params.nsi); if (!tmp) { pr_warning("Failed to get the absolute path of %s: %m\n", str); return ret; @@ -208,6 +212,34 @@ static int opt_set_target(const struct option *opt, const char *str, return ret; } +static int opt_set_target_ns(const struct option *opt __maybe_unused, + const char *str, int unset __maybe_unused) +{ + int ret = -ENOENT; + pid_t ns_pid; + struct nsinfo *nsip; + + if (str) { + errno = 0; + ns_pid = (pid_t)strtol(str, NULL, 10); + if (errno != 0) { + ret = -errno; + pr_warning("Failed to parse %s as a pid: %s\n", str, + strerror(errno)); + return ret; + } + nsip = nsinfo__new(ns_pid); + if (nsip && nsip->need_setns) + params.nsi = nsinfo__get(nsip); + nsinfo__put(nsip); + + ret = 0; + } + + return ret; +} + + /* Command option callbacks */ #ifdef HAVE_DWARF_SUPPORT @@ -299,6 +331,7 @@ static void cleanup_params(void) line_range__clear(¶ms.line_range); free(params.target); strfilter__delete(params.filter); + nsinfo__put(params.nsi); memset(¶ms, 0, sizeof(params)); } @@ -383,7 +416,7 @@ static int del_perf_probe_caches(struct strfilter *filter) } strlist__for_each_entry(nd, bidlist) { - cache = probe_cache__new(nd->s); + cache = probe_cache__new(nd->s, NULL); if (!cache) continue; if (probe_cache__filter_purge(cache, filter) < 0 || @@ -554,6 +587,8 @@ __cmd_probe(int argc, const char **argv) OPT_BOOLEAN(0, "cache", &probe_conf.cache, "Manipulate probe cache"), OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", "Look for files with symbols relative to this directory"), + OPT_CALLBACK(0, "target-ns", NULL, "pid", + "target pid for namespace contexts", opt_set_target_ns), OPT_END() }; int ret; @@ -634,15 +669,15 @@ __cmd_probe(int argc, const char **argv) pr_err_with_code(" Error: Failed to show event list.", ret); return ret; case 'F': - ret = show_available_funcs(params.target, params.filter, - params.uprobes); + ret = show_available_funcs(params.target, params.nsi, + params.filter, params.uprobes); if (ret < 0) pr_err_with_code(" Error: Failed to show functions.", ret); return ret; #ifdef HAVE_DWARF_SUPPORT case 'L': ret = show_line_range(¶ms.line_range, params.target, - params.uprobes); + params.nsi, params.uprobes); if (ret < 0) pr_err_with_code(" Error: Failed to show lines.", ret); return ret; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 17a14bcce34a..0c95ffefb6cc 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-record.c * @@ -799,6 +800,13 @@ static int record__synthesize(struct record *rec, bool tail) return 0; if (file->is_pipe) { + err = perf_event__synthesize_features( + tool, session, rec->evlist, process_synthesized_event); + if (err < 0) { + pr_err("Couldn't synthesize features.\n"); + return err; + } + err = perf_event__synthesize_attrs(tool, session, process_synthesized_event); if (err < 0) { @@ -1597,6 +1605,8 @@ static struct option __record_options[] = { OPT_BOOLEAN('s', "stat", &record.opts.inherit_stat, "per thread counts"), OPT_BOOLEAN('d', "data", &record.opts.sample_address, "Record the sample addresses"), + OPT_BOOLEAN(0, "phys-data", &record.opts.sample_phys_addr, + "Record the sample physical addresses"), OPT_BOOLEAN(0, "sample-cpu", &record.opts.sample_cpu, "Record the sample cpu"), OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time, &record.opts.sample_time_set, @@ -1821,7 +1831,7 @@ int cmd_record(int argc, const char **argv) record.opts.tail_synthesize = true; if (rec->evlist->nr_entries == 0 && - perf_evlist__add_default(rec->evlist) < 0) { + __perf_evlist__add_default(rec->evlist, !record.opts.no_samples) < 0) { pr_err("Not enough memory for event selector list\n"); goto out; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 79a33eb1a10d..fae4b0340750 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-report.c * @@ -38,6 +39,7 @@ #include "util/time-utils.h" #include "util/auxtrace.h" #include "util/units.h" +#include "util/branch.h" #include #include @@ -73,6 +75,7 @@ struct report { u64 queue_size; int socket_filter; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); + struct branch_type_stat brtype_stat; }; static int report__config(const char *var, const char *value, void *cb) @@ -113,43 +116,60 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter, struct report *rep = arg; struct hist_entry *he = iter->he; struct perf_evsel *evsel = iter->evsel; + struct perf_sample *sample = iter->sample; struct mem_info *mi; struct branch_info *bi; if (!ui__has_annotation()) return 0; - hist__account_cycles(iter->sample->branch_stack, al, iter->sample, + hist__account_cycles(sample->branch_stack, al, sample, rep->nonany_branch_mode); if (sort__mode == SORT_MODE__BRANCH) { bi = he->branch_info; - err = addr_map_symbol__inc_samples(&bi->from, evsel->idx); + err = addr_map_symbol__inc_samples(&bi->from, sample, evsel->idx); if (err) goto out; - err = addr_map_symbol__inc_samples(&bi->to, evsel->idx); + err = addr_map_symbol__inc_samples(&bi->to, sample, evsel->idx); } else if (rep->mem_mode) { mi = he->mem_info; - err = addr_map_symbol__inc_samples(&mi->daddr, evsel->idx); + err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel->idx); if (err) goto out; - err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); + err = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); } else if (symbol_conf.cumulate_callchain) { if (single) - err = hist_entry__inc_addr_samples(he, evsel->idx, + err = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); } else { - err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); + err = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); } out: return err; } +static int hist_iter__branch_callback(struct hist_entry_iter *iter, + struct addr_location *al __maybe_unused, + bool single __maybe_unused, + void *arg) +{ + struct hist_entry *he = iter->he; + struct report *rep = arg; + struct branch_info *bi; + + bi = he->branch_info; + branch_type_count(&rep->brtype_stat, &bi->flags, + bi->from.addr, bi->to.addr); + + return 0; +} + static int process_sample_event(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, @@ -188,6 +208,8 @@ static int process_sample_event(struct perf_tool *tool, */ if (!sample->branch_stack) goto out_put; + + iter.add_entry_cb = hist_iter__branch_callback; iter.ops = &hist_iter_branch; } else if (rep->mem_mode) { iter.ops = &hist_iter_mem; @@ -220,7 +242,7 @@ static int process_read_event(struct perf_tool *tool, const char *name = evsel ? perf_evsel__name(evsel) : "unknown"; int err = perf_read_values_add_value(&rep->show_threads_values, event->read.pid, event->read.tid, - event->read.id, + evsel->idx, name, event->read.value); @@ -228,10 +250,6 @@ static int process_read_event(struct perf_tool *tool, return err; } - dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, - evsel ? perf_evsel__name(evsel) : "FAIL", - event->read.value); - return 0; } @@ -258,10 +276,11 @@ static int report__setup_sample_type(struct report *rep) "'perf record' without -g?\n"); return -EINVAL; } - if (symbol_conf.use_callchain) { - ui__error("Selected -g or --branch-history but no " - "callchain data. Did\n" - "you call 'perf record' without -g?\n"); + if (symbol_conf.use_callchain && + !symbol_conf.show_branchflag_count) { + ui__error("Selected -g or --branch-history.\n" + "But no callchain or branch data.\n" + "Did you call 'perf record' without -g or -b?\n"); return -1; } } else if (!callchain_param.enabled && @@ -396,7 +415,8 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, hists__fprintf_nr_sample_events(hists, rep, evname, stdout); hists__fprintf(hists, !quiet, 0, 0, rep->min_percent, stdout, - symbol_conf.use_callchain); + symbol_conf.use_callchain || + symbol_conf.show_branchflag_count); fprintf(stdout, "\n\n"); } @@ -410,6 +430,9 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, perf_read_values_destroy(&rep->show_threads_values); } + if (sort__mode == SORT_MODE__BRANCH) + branch_type_stat_display(stdout, &rep->brtype_stat); + return 0; } @@ -718,6 +741,7 @@ int cmd_report(int argc, const char **argv) .id_index = perf_event__process_id_index, .auxtrace_info = perf_event__process_auxtrace_info, .auxtrace = perf_event__process_auxtrace, + .feature = perf_event__process_feature, .ordered_events = true, .ordering_requires_timestamps = true, }, @@ -943,6 +967,8 @@ repeat: if (has_br_stack && branch_call_mode) symbol_conf.show_branchflag_count = true; + memset(&report.brtype_stat, 0, sizeof(struct branch_type_stat)); + /* * Branch mode is a tristate: * -1 means default, so decide based on the file having branch data. @@ -988,6 +1014,10 @@ repeat: /* Force tty output for header output and per-thread stat. */ if (report.header || report.header_only || report.show_threads) use_browser = 0; + if (report.header || report.header_only) + report.tool.show_feat_hdr = SHOW_FEAT_HEADER; + if (report.show_full_info) + report.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO; if (strcmp(input_name, "-") != 0) setup_browser(true); diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 322b4def8411..f380d91ee609 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "builtin.h" #include "perf.h" diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 83cdc0a61fd6..0fe02758de7d 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "builtin.h" #include "perf.h" @@ -87,6 +88,7 @@ enum perf_output_field { PERF_OUTPUT_BRSTACKINSN = 1U << 23, PERF_OUTPUT_BRSTACKOFF = 1U << 24, PERF_OUTPUT_SYNTH = 1U << 25, + PERF_OUTPUT_PHYS_ADDR = 1U << 26, }; struct output_option { @@ -119,6 +121,7 @@ struct output_option { {.str = "brstackinsn", .field = PERF_OUTPUT_BRSTACKINSN}, {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, {.str = "synth", .field = PERF_OUTPUT_SYNTH}, + {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, }; enum { @@ -175,7 +178,8 @@ static struct { PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | PERF_OUTPUT_SYM | PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD | PERF_OUTPUT_ADDR | - PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT, + PERF_OUTPUT_DATA_SRC | PERF_OUTPUT_WEIGHT | + PERF_OUTPUT_PHYS_ADDR, .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT, }, @@ -382,6 +386,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, PERF_OUTPUT_IREGS)) return -EINVAL; + if (PRINT_FIELD(PHYS_ADDR) && + perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", + PERF_OUTPUT_PHYS_ADDR)) + return -EINVAL; + return 0; } @@ -578,7 +587,7 @@ static void print_sample_brstack(struct perf_sample *sample, thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); } - printf("0x%"PRIx64, from); + printf(" 0x%"PRIx64, from); if (PRINT_FIELD(DSO)) { printf("("); map__fprintf_dsoname(alf.map, stdout); @@ -673,7 +682,7 @@ static void print_sample_brstackoff(struct perf_sample *sample, if (alt.map && !alt.map->dso->adjust_symbols) to = map__map_ip(alt.map, to); - printf("0x%"PRIx64, from); + printf(" 0x%"PRIx64, from); if (PRINT_FIELD(DSO)) { printf("("); map__fprintf_dsoname(alf.map, stdout); @@ -1446,6 +1455,9 @@ static void process_event(struct perf_script *script, if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) print_sample_bpf_output(sample); print_insn(sample, attr, thread, machine); + + if (PRINT_FIELD(PHYS_ADDR)) + printf("%16" PRIx64, sample->phys_addr); printf("\n"); } @@ -2199,16 +2211,11 @@ static struct script_desc *script_desc__findnew(const char *name) s = script_desc__new(name); if (!s) - goto out_delete_desc; + return NULL; script_desc__add(s); return s; - -out_delete_desc: - script_desc__delete(s); - - return NULL; } static const char *ends_with(const char *str, const char *suffix) @@ -2682,6 +2689,7 @@ int cmd_script(int argc, const char **argv) .attr = process_attr, .event_update = perf_event__process_event_update, .tracing_data = perf_event__process_tracing_data, + .feature = perf_event__process_feature, .build_id = perf_event__process_build_id, .id_index = perf_event__process_id_index, .auxtrace_info = perf_event__process_auxtrace_info, @@ -2733,7 +2741,7 @@ int cmd_script(int argc, const char **argv) "Valid types: hw,sw,trace,raw,synth. " "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," "addr,symoff,period,iregs,brstack,brstacksym,flags," - "bpf-output,callindent,insn,insnlen,brstackinsn,synth", + "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", parse_output_fields), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), @@ -2972,10 +2980,13 @@ int cmd_script(int argc, const char **argv) return -1; if (header || header_only) { + script.tool.show_feat_hdr = SHOW_FEAT_HEADER; perf_session__fprintf_info(session, stdout, show_full_info); if (header_only) goto out_delete; } + if (show_full_info) + script.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO; if (symbol__init(&session->header.env) < 0) goto out_delete; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 48ac53b199fc..69523ed55894 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -213,10 +213,20 @@ static void perf_stat__reset_stats(void) static int create_perf_stat_counter(struct perf_evsel *evsel) { struct perf_event_attr *attr = &evsel->attr; + struct perf_evsel *leader = evsel->leader; - if (stat_config.scale) + if (stat_config.scale) { attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; + } + + /* + * The event is part of non trivial group, let's enable + * the group read (for leader) and ID retrieval for all + * members. + */ + if (leader->nr_members > 1) + attr->read_format |= PERF_FORMAT_ID|PERF_FORMAT_GROUP; attr->inherit = !no_inherit; @@ -333,13 +343,21 @@ static int read_counter(struct perf_evsel *counter) struct perf_counts_values *count; count = perf_counts(counter->counts, cpu, thread); - if (perf_evsel__read(counter, cpu, thread, count)) { + + /* + * The leader's group read loads data into its group members + * (via perf_evsel__read_counter) and sets threir count->loaded. + */ + if (!count->loaded && + perf_evsel__read_counter(counter, cpu, thread)) { counter->counts->scaled = -1; perf_counts(counter->counts, cpu, thread)->ena = 0; perf_counts(counter->counts, cpu, thread)->run = 0; return -1; } + count->loaded = false; + if (STAT_RECORD) { if (perf_evsel__write_stat_event(counter, cpu, thread, count)) { pr_err("failed to write stat event\n"); @@ -559,6 +577,11 @@ static int store_counter_ids(struct perf_evsel *counter) return __store_counter_ids(counter, cpus, threads); } +static bool perf_evsel__should_store_id(struct perf_evsel *counter) +{ + return STAT_RECORD || counter->attr.read_format & PERF_FORMAT_ID; +} + static int __run_perf_stat(int argc, const char **argv) { int interval = stat_config.interval; @@ -631,7 +654,8 @@ try_again: if (l > unit_width) unit_width = l; - if (STAT_RECORD && store_counter_ids(counter)) + if (perf_evsel__should_store_id(counter) && + store_counter_ids(counter)) return -1; } @@ -683,7 +707,7 @@ try_again: process_interval(); } } - wait(&status); + waitpid(child_pid, &status, 0); if (workload_exec_errno) { const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); @@ -1233,7 +1257,7 @@ static bool collect_data(struct perf_evsel *counter, if (counter->merged_stat) return false; cb(counter, data, true); - if (!no_merge) + if (!no_merge && counter->auto_merge_stats) collect_all_aliases(counter, cb, data); return true; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6052376634c0..ee954bde7e3e 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -134,7 +134,7 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he) return err; } - err = symbol__disassemble(sym, map, NULL, 0, NULL); + err = symbol__disassemble(sym, map, NULL, 0, NULL, NULL); if (err == 0) { out_assign: top->sym_filter_entry = he; @@ -183,6 +183,7 @@ static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip) static void perf_top__record_precise_ip(struct perf_top *top, struct hist_entry *he, + struct perf_sample *sample, int counter, u64 ip) { struct annotation *notes; @@ -199,7 +200,7 @@ static void perf_top__record_precise_ip(struct perf_top *top, if (pthread_mutex_trylock(¬es->lock)) return; - err = hist_entry__inc_addr_samples(he, counter, ip); + err = hist_entry__inc_addr_samples(he, sample, counter, ip); pthread_mutex_unlock(¬es->lock); @@ -586,6 +587,13 @@ static void *display_thread_tui(void *arg) .refresh = top->delay_secs, }; + /* In order to read symbols from other namespaces perf to needs to call + * setns(2). This isn't permitted if the struct_fs has multiple users. + * unshare(2) the fs so that we may continue to setns into namespaces + * that we're observing. + */ + unshare(CLONE_FS); + perf_top__sort_new_samples(top); /* @@ -627,6 +635,13 @@ static void *display_thread(void *arg) struct perf_top *top = arg; int delay_msecs, c; + /* In order to read symbols from other namespaces perf to needs to call + * setns(2). This isn't permitted if the struct_fs has multiple users. + * unshare(2) the fs so that we may continue to setns into namespaces + * that we're observing. + */ + unshare(CLONE_FS); + display_setup_sig(); pthread__unblock_sigwinch(); repeat: @@ -671,7 +686,7 @@ static int hist_iter__top_callback(struct hist_entry_iter *iter, struct perf_evsel *evsel = iter->evsel; if (perf_hpp_list.sym && single) - perf_top__record_precise_ip(top, he, evsel->idx, al->addr); + perf_top__record_precise_ip(top, he, iter->sample, evsel->idx, al->addr); hist__account_cycles(iter->sample->branch_stack, al, iter->sample, !(top->record_opts.branch_stack & PERF_SAMPLE_BRANCH_ANY)); @@ -1205,6 +1220,7 @@ int cmd_top(int argc, const char **argv) "Show raw trace event output (do not use print fmt or plugins)"), OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy, "Show entries in a hierarchy"), + OPT_BOOLEAN(0, "force", &symbol_conf.force, "don't complain, do it"), OPT_END() }; const char * const top_usage[] = { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 4b2a5d298197..d5d7fff1c211 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -64,6 +64,10 @@ # define O_CLOEXEC 02000000 #endif +#ifndef F_LINUX_SPECIFIC_BASE +# define F_LINUX_SPECIFIC_BASE 1024 +#endif + struct trace { struct perf_tool tool; struct syscalltbl *sctbl; @@ -279,34 +283,21 @@ out_delete: ({ struct syscall_tp *fields = evsel->priv; \ fields->name.pointer(&fields->name, sample); }) -struct strarray { - int offset; - int nr_entries; - const char **entries; -}; +size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val) +{ + int idx = val - sa->offset; -#define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \ - .nr_entries = ARRAY_SIZE(array), \ - .entries = array, \ -} + if (idx < 0 || idx >= sa->nr_entries) + return scnprintf(bf, size, intfmt, val); -#define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \ - .offset = off, \ - .nr_entries = ARRAY_SIZE(array), \ - .entries = array, \ + return scnprintf(bf, size, "%s", sa->entries[idx]); } static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size, const char *intfmt, struct syscall_arg *arg) { - struct strarray *sa = arg->parm; - int idx = arg->val - sa->offset; - - if (idx < 0 || idx >= sa->nr_entries) - return scnprintf(bf, size, intfmt, arg->val); - - return scnprintf(bf, size, "%s", sa->entries[idx]); + return strarray__scnprintf(arg->parm, bf, size, intfmt, arg->val); } static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, @@ -317,24 +308,35 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, #define SCA_STRARRAY syscall_arg__scnprintf_strarray -#if defined(__i386__) || defined(__x86_64__) -/* - * FIXME: Make this available to all arches as soon as the ioctl beautifier - * gets rewritten to support all arches. - */ -static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, - struct syscall_arg *arg) -{ - return __syscall_arg__scnprintf_strarray(bf, size, "%#x", arg); +struct strarrays { + int nr_entries; + struct strarray **entries; +}; + +#define DEFINE_STRARRAYS(array) struct strarrays strarrays__##array = { \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ } -#define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray -#endif /* defined(__i386__) || defined(__x86_64__) */ +size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, + struct syscall_arg *arg) +{ + struct strarrays *sas = arg->parm; + int i; -static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, - struct syscall_arg *arg); + for (i = 0; i < sas->nr_entries; ++i) { + struct strarray *sa = sas->entries[i]; + int idx = arg->val - sa->offset; -#define SCA_FD syscall_arg__scnprintf_fd + if (idx >= 0 && idx < sa->nr_entries) { + if (sa->entries[idx] == NULL) + break; + return scnprintf(bf, size, "%s", sa->entries[idx]); + } + } + + return scnprintf(bf, size, "%d", arg->val); +} #ifndef AT_FDCWD #define AT_FDCWD -100 @@ -358,21 +360,20 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, #define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd -static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg) { return scnprintf(bf, size, "%#lx", arg->val); } -#define SCA_HEX syscall_arg__scnprintf_hex - -static size_t syscall_arg__scnprintf_int(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg) { return scnprintf(bf, size, "%d", arg->val); } -#define SCA_INT syscall_arg__scnprintf_int +size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *arg) +{ + return scnprintf(bf, size, "%ld", arg->val); +} static const char *bpf_cmd[] = { "MAP_CREATE", "MAP_LOOKUP_ELEM", "MAP_UPDATE_ELEM", "MAP_DELETE_ELEM", @@ -407,12 +408,27 @@ static DEFINE_STRARRAY(whences); static const char *fcntl_cmds[] = { "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK", - "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64", - "F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX", - "F_GETOWNER_UIDS", + "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "GETLK64", + "SETLK64", "SETLKW64", "SETOWN_EX", "GETOWN_EX", + "GETOWNER_UIDS", }; static DEFINE_STRARRAY(fcntl_cmds); +static const char *fcntl_linux_specific_cmds[] = { + "SETLEASE", "GETLEASE", "NOTIFY", [5] = "CANCELLK", "DUPFD_CLOEXEC", + "SETPIPE_SZ", "GETPIPE_SZ", "ADD_SEALS", "GET_SEALS", + "GET_RW_HINT", "SET_RW_HINT", "GET_FILE_RW_HINT", "SET_FILE_RW_HINT", +}; + +static DEFINE_STRARRAY_OFFSET(fcntl_linux_specific_cmds, F_LINUX_SPECIFIC_BASE); + +static struct strarray *fcntl_cmds_arrays[] = { + &strarray__fcntl_cmds, + &strarray__fcntl_linux_specific_cmds, +}; + +static DEFINE_STRARRAYS(fcntl_cmds_arrays); + static const char *rlimit_resources[] = { "CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE", "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO", @@ -495,33 +511,6 @@ static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, #define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags -#if defined(__i386__) || defined(__x86_64__) -/* - * FIXME: Make this available to all arches. - */ -#define TCGETS 0x5401 - -static const char *tioctls[] = { - "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW", - "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL", - "TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI", - "TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC", - "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", "FIONREAD", "TIOCLINUX", - "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", "FIONBIO", - "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", [0x27] = "TIOCSBRK", - "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", "TCSETSW2", "TCSETSF2", - "TIOCGRS485", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK", - "TIOCGDEV||TCGETX", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG", - "TIOCVHANGUP", "TIOCGPKT", "TIOCGPTLCK", "TIOCGEXCL", - [0x50] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG", - "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS", - "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI", - "TIOCMIWAIT", "TIOCGICOUNT", [0x60] = "FIOQSIZE", -}; - -static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401); -#endif /* defined(__i386__) || defined(__x86_64__) */ - #ifndef GRND_NONBLOCK #define GRND_NONBLOCK 0x0001 #endif @@ -552,9 +541,9 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, #define SCA_GETRANDOM_FLAGS syscall_arg__scnprintf_getrandom_flags -#define STRARRAY(arg, name, array) \ - .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ - .arg_parm = { [arg] = &strarray__##array, } +#define STRARRAY(name, array) \ + { .scnprintf = SCA_STRARRAY, \ + .parm = &strarray__##array, } #include "trace/beauty/eventfd.c" #include "trace/beauty/flock.c" @@ -571,242 +560,219 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size, #include "trace/beauty/socket_type.c" #include "trace/beauty/waitid_options.c" +struct syscall_arg_fmt { + size_t (*scnprintf)(char *bf, size_t size, struct syscall_arg *arg); + void *parm; + const char *name; + bool show_zero; +}; + static struct syscall_fmt { const char *name; const char *alias; - size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg); - void *arg_parm[6]; - bool errmsg; + struct syscall_arg_fmt arg[6]; + u8 nr_args; bool errpid; bool timeout; bool hexret; } syscall_fmts[] = { - { .name = "access", .errmsg = true, - .arg_scnprintf = { [1] = SCA_ACCMODE, /* mode */ }, }, - { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, - { .name = "bpf", .errmsg = true, STRARRAY(0, cmd, bpf_cmd), }, + { .name = "access", + .arg = { [1] = { .scnprintf = SCA_ACCMODE, /* mode */ }, }, }, + { .name = "arch_prctl", .alias = "prctl", }, + { .name = "bpf", + .arg = { [0] = STRARRAY(cmd, bpf_cmd), }, }, { .name = "brk", .hexret = true, - .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, - { .name = "chdir", .errmsg = true, }, - { .name = "chmod", .errmsg = true, }, - { .name = "chroot", .errmsg = true, }, - { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), }, - { .name = "clone", .errpid = true, }, - { .name = "close", .errmsg = true, - .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, - { .name = "connect", .errmsg = true, }, - { .name = "creat", .errmsg = true, }, - { .name = "dup", .errmsg = true, }, - { .name = "dup2", .errmsg = true, }, - { .name = "dup3", .errmsg = true, }, - { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), }, - { .name = "eventfd2", .errmsg = true, - .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, }, - { .name = "faccessat", .errmsg = true, }, - { .name = "fadvise64", .errmsg = true, }, - { .name = "fallocate", .errmsg = true, }, - { .name = "fchdir", .errmsg = true, }, - { .name = "fchmod", .errmsg = true, }, - { .name = "fchmodat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "fchown", .errmsg = true, }, - { .name = "fchownat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "fcntl", .errmsg = true, - .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, - .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, - { .name = "fdatasync", .errmsg = true, }, - { .name = "flock", .errmsg = true, - .arg_scnprintf = { [1] = SCA_FLOCK, /* cmd */ }, }, - { .name = "fsetxattr", .errmsg = true, }, - { .name = "fstat", .errmsg = true, .alias = "newfstat", }, - { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, - { .name = "fstatfs", .errmsg = true, }, - { .name = "fsync", .errmsg = true, }, - { .name = "ftruncate", .errmsg = true, }, - { .name = "futex", .errmsg = true, - .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, - { .name = "futimesat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "getdents", .errmsg = true, }, - { .name = "getdents64", .errmsg = true, }, - { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, + .arg = { [0] = { .scnprintf = SCA_HEX, /* brk */ }, }, }, + { .name = "clock_gettime", + .arg = { [0] = STRARRAY(clk_id, clockid), }, }, + { .name = "clone", .errpid = true, .nr_args = 5, + .arg = { [0] = { .name = "flags", .scnprintf = SCA_CLONE_FLAGS, }, + [1] = { .name = "child_stack", .scnprintf = SCA_HEX, }, + [2] = { .name = "parent_tidptr", .scnprintf = SCA_HEX, }, + [3] = { .name = "child_tidptr", .scnprintf = SCA_HEX, }, + [4] = { .name = "tls", .scnprintf = SCA_HEX, }, }, }, + { .name = "close", + .arg = { [0] = { .scnprintf = SCA_CLOSE_FD, /* fd */ }, }, }, + { .name = "epoll_ctl", + .arg = { [1] = STRARRAY(op, epoll_ctl_ops), }, }, + { .name = "eventfd2", + .arg = { [1] = { .scnprintf = SCA_EFD_FLAGS, /* flags */ }, }, }, + { .name = "fchmodat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "fchownat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "fcntl", + .arg = { [1] = { .scnprintf = SCA_FCNTL_CMD, /* cmd */ + .parm = &strarrays__fcntl_cmds_arrays, + .show_zero = true, }, + [2] = { .scnprintf = SCA_FCNTL_ARG, /* arg */ }, }, }, + { .name = "flock", + .arg = { [1] = { .scnprintf = SCA_FLOCK, /* cmd */ }, }, }, + { .name = "fstat", .alias = "newfstat", }, + { .name = "fstatat", .alias = "newfstatat", }, + { .name = "futex", + .arg = { [1] = { .scnprintf = SCA_FUTEX_OP, /* op */ }, }, }, + { .name = "futimesat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "getitimer", + .arg = { [0] = STRARRAY(which, itimers), }, }, { .name = "getpid", .errpid = true, }, { .name = "getpgid", .errpid = true, }, { .name = "getppid", .errpid = true, }, - { .name = "getrandom", .errmsg = true, - .arg_scnprintf = { [2] = SCA_GETRANDOM_FLAGS, /* flags */ }, }, - { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, - { .name = "getxattr", .errmsg = true, }, - { .name = "inotify_add_watch", .errmsg = true, }, - { .name = "ioctl", .errmsg = true, - .arg_scnprintf = { + { .name = "getrandom", + .arg = { [2] = { .scnprintf = SCA_GETRANDOM_FLAGS, /* flags */ }, }, }, + { .name = "getrlimit", + .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "ioctl", + .arg = { #if defined(__i386__) || defined(__x86_64__) /* * FIXME: Make this available to all arches. */ - [1] = SCA_STRHEXARRAY, /* cmd */ - [2] = SCA_HEX, /* arg */ }, - .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, }, + [1] = { .scnprintf = SCA_IOCTL_CMD, /* cmd */ }, + [2] = { .scnprintf = SCA_HEX, /* arg */ }, }, }, #else - [2] = SCA_HEX, /* arg */ }, }, + [2] = { .scnprintf = SCA_HEX, /* arg */ }, }, }, #endif - { .name = "keyctl", .errmsg = true, STRARRAY(0, option, keyctl_options), }, - { .name = "kill", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "lchown", .errmsg = true, }, - { .name = "lgetxattr", .errmsg = true, }, - { .name = "linkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "listxattr", .errmsg = true, }, - { .name = "llistxattr", .errmsg = true, }, - { .name = "lremovexattr", .errmsg = true, }, - { .name = "lseek", .errmsg = true, - .arg_scnprintf = { [2] = SCA_STRARRAY, /* whence */ }, - .arg_parm = { [2] = &strarray__whences, /* whence */ }, }, - { .name = "lsetxattr", .errmsg = true, }, - { .name = "lstat", .errmsg = true, .alias = "newlstat", }, - { .name = "lsxattr", .errmsg = true, }, - { .name = "madvise", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* start */ - [2] = SCA_MADV_BHV, /* behavior */ }, }, - { .name = "mkdir", .errmsg = true, }, - { .name = "mkdirat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "mknod", .errmsg = true, }, - { .name = "mknodat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, - { .name = "mlock", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, - { .name = "mlockall", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, + { .name = "keyctl", + .arg = { [0] = STRARRAY(option, keyctl_options), }, }, + { .name = "kill", + .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "linkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "lseek", + .arg = { [2] = STRARRAY(whence, whences), }, }, + { .name = "lstat", .alias = "newlstat", }, + { .name = "madvise", + .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ }, + [2] = { .scnprintf = SCA_MADV_BHV, /* behavior */ }, }, }, + { .name = "mkdirat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "mknodat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fd */ }, }, }, + { .name = "mlock", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, + { .name = "mlockall", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, { .name = "mmap", .hexret = true, /* The standard mmap maps to old_mmap on s390x */ #if defined(__s390x__) .alias = "old_mmap", #endif - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ - [2] = SCA_MMAP_PROT, /* prot */ - [3] = SCA_MMAP_FLAGS, /* flags */ }, }, - { .name = "mprotect", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* start */ - [2] = SCA_MMAP_PROT, /* prot */ }, }, - { .name = "mq_unlink", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FILENAME, /* u_name */ }, }, + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, + [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, + [3] = { .scnprintf = SCA_MMAP_FLAGS, /* flags */ }, }, }, + { .name = "mprotect", + .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ }, + [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, }, }, + { .name = "mq_unlink", + .arg = { [0] = { .scnprintf = SCA_FILENAME, /* u_name */ }, }, }, { .name = "mremap", .hexret = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ - [3] = SCA_MREMAP_FLAGS, /* flags */ - [4] = SCA_HEX, /* new_addr */ }, }, - { .name = "munlock", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, - { .name = "munmap", .errmsg = true, - .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, - { .name = "name_to_handle_at", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "newfstatat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "open", .errmsg = true, - .arg_scnprintf = { [1] = SCA_OPEN_FLAGS, /* flags */ }, }, - { .name = "open_by_handle_at", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ - [2] = SCA_OPEN_FLAGS, /* flags */ }, }, - { .name = "openat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ - [2] = SCA_OPEN_FLAGS, /* flags */ }, }, - { .name = "perf_event_open", .errmsg = true, - .arg_scnprintf = { [2] = SCA_INT, /* cpu */ - [3] = SCA_FD, /* group_fd */ - [4] = SCA_PERF_FLAGS, /* flags */ }, }, - { .name = "pipe2", .errmsg = true, - .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, }, - { .name = "poll", .errmsg = true, .timeout = true, }, - { .name = "ppoll", .errmsg = true, .timeout = true, }, - { .name = "pread", .errmsg = true, .alias = "pread64", }, - { .name = "preadv", .errmsg = true, .alias = "pread", }, - { .name = "prlimit64", .errmsg = true, STRARRAY(1, resource, rlimit_resources), }, - { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, - { .name = "pwritev", .errmsg = true, }, - { .name = "read", .errmsg = true, }, - { .name = "readlink", .errmsg = true, }, - { .name = "readlinkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "readv", .errmsg = true, }, - { .name = "recvfrom", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "recvmmsg", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "recvmsg", .errmsg = true, - .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "removexattr", .errmsg = true, }, - { .name = "renameat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "rmdir", .errmsg = true, }, - { .name = "rt_sigaction", .errmsg = true, - .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, }, - { .name = "rt_sigprocmask", .errmsg = true, STRARRAY(0, how, sighow), }, - { .name = "rt_sigqueueinfo", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "rt_tgsigqueueinfo", .errmsg = true, - .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, - { .name = "sched_getattr", .errmsg = true, }, - { .name = "sched_setattr", .errmsg = true, }, - { .name = "sched_setscheduler", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SCHED_POLICY, /* policy */ }, }, - { .name = "seccomp", .errmsg = true, - .arg_scnprintf = { [0] = SCA_SECCOMP_OP, /* op */ - [1] = SCA_SECCOMP_FLAGS, /* flags */ }, }, - { .name = "select", .errmsg = true, .timeout = true, }, - { .name = "sendmmsg", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "sendmsg", .errmsg = true, - .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "sendto", .errmsg = true, - .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, + [3] = { .scnprintf = SCA_MREMAP_FLAGS, /* flags */ }, + [4] = { .scnprintf = SCA_HEX, /* new_addr */ }, }, }, + { .name = "munlock", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, + { .name = "munmap", + .arg = { [0] = { .scnprintf = SCA_HEX, /* addr */ }, }, }, + { .name = "name_to_handle_at", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "newfstatat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "open", + .arg = { [1] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, + { .name = "open_by_handle_at", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, + [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, + { .name = "openat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, + [2] = { .scnprintf = SCA_OPEN_FLAGS, /* flags */ }, }, }, + { .name = "perf_event_open", + .arg = { [2] = { .scnprintf = SCA_INT, /* cpu */ }, + [3] = { .scnprintf = SCA_FD, /* group_fd */ }, + [4] = { .scnprintf = SCA_PERF_FLAGS, /* flags */ }, }, }, + { .name = "pipe2", + .arg = { [1] = { .scnprintf = SCA_PIPE_FLAGS, /* flags */ }, }, }, + { .name = "pkey_alloc", + .arg = { [1] = { .scnprintf = SCA_PKEY_ALLOC_ACCESS_RIGHTS, /* access_rights */ }, }, }, + { .name = "pkey_free", + .arg = { [0] = { .scnprintf = SCA_INT, /* key */ }, }, }, + { .name = "pkey_mprotect", + .arg = { [0] = { .scnprintf = SCA_HEX, /* start */ }, + [2] = { .scnprintf = SCA_MMAP_PROT, /* prot */ }, + [3] = { .scnprintf = SCA_INT, /* pkey */ }, }, }, + { .name = "poll", .timeout = true, }, + { .name = "ppoll", .timeout = true, }, + { .name = "pread", .alias = "pread64", }, + { .name = "preadv", .alias = "pread", }, + { .name = "prlimit64", + .arg = { [1] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "pwrite", .alias = "pwrite64", }, + { .name = "readlinkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "recvfrom", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "recvmmsg", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "recvmsg", + .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "renameat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "rt_sigaction", + .arg = { [0] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "rt_sigprocmask", + .arg = { [0] = STRARRAY(how, sighow), }, }, + { .name = "rt_sigqueueinfo", + .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "rt_tgsigqueueinfo", + .arg = { [2] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "sched_setscheduler", + .arg = { [1] = { .scnprintf = SCA_SCHED_POLICY, /* policy */ }, }, }, + { .name = "seccomp", + .arg = { [0] = { .scnprintf = SCA_SECCOMP_OP, /* op */ }, + [1] = { .scnprintf = SCA_SECCOMP_FLAGS, /* flags */ }, }, }, + { .name = "select", .timeout = true, }, + { .name = "sendmmsg", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "sendmsg", + .arg = { [2] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, + { .name = "sendto", + .arg = { [3] = { .scnprintf = SCA_MSG_FLAGS, /* flags */ }, }, }, { .name = "set_tid_address", .errpid = true, }, - { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, - { .name = "setpgid", .errmsg = true, }, - { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, - { .name = "setxattr", .errmsg = true, }, - { .name = "shutdown", .errmsg = true, }, - { .name = "socket", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ - [1] = SCA_SK_TYPE, /* type */ }, - .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, - { .name = "socketpair", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ - [1] = SCA_SK_TYPE, /* type */ }, - .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, - { .name = "stat", .errmsg = true, .alias = "newstat", }, - { .name = "statfs", .errmsg = true, }, - { .name = "statx", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* flags */ - [2] = SCA_STATX_FLAGS, /* flags */ - [3] = SCA_STATX_MASK, /* mask */ }, }, - { .name = "swapoff", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, }, - { .name = "swapon", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FILENAME, /* specialfile */ }, }, - { .name = "symlinkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "tgkill", .errmsg = true, - .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, - { .name = "tkill", .errmsg = true, - .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "truncate", .errmsg = true, }, - { .name = "uname", .errmsg = true, .alias = "newuname", }, - { .name = "unlinkat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, - { .name = "utime", .errmsg = true, }, - { .name = "utimensat", .errmsg = true, - .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ }, }, - { .name = "utimes", .errmsg = true, }, - { .name = "vmsplice", .errmsg = true, }, + { .name = "setitimer", + .arg = { [0] = STRARRAY(which, itimers), }, }, + { .name = "setrlimit", + .arg = { [0] = STRARRAY(resource, rlimit_resources), }, }, + { .name = "socket", + .arg = { [0] = STRARRAY(family, socket_families), + [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, + { .name = "socketpair", + .arg = { [0] = STRARRAY(family, socket_families), + [1] = { .scnprintf = SCA_SK_TYPE, /* type */ }, }, }, + { .name = "stat", .alias = "newstat", }, + { .name = "statx", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* fdat */ }, + [2] = { .scnprintf = SCA_STATX_FLAGS, /* flags */ } , + [3] = { .scnprintf = SCA_STATX_MASK, /* mask */ }, }, }, + { .name = "swapoff", + .arg = { [0] = { .scnprintf = SCA_FILENAME, /* specialfile */ }, }, }, + { .name = "swapon", + .arg = { [0] = { .scnprintf = SCA_FILENAME, /* specialfile */ }, }, }, + { .name = "symlinkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "tgkill", + .arg = { [2] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "tkill", + .arg = { [1] = { .scnprintf = SCA_SIGNUM, /* sig */ }, }, }, + { .name = "uname", .alias = "newuname", }, + { .name = "unlinkat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dfd */ }, }, }, + { .name = "utimensat", + .arg = { [0] = { .scnprintf = SCA_FDAT, /* dirfd */ }, }, }, { .name = "wait4", .errpid = true, - .arg_scnprintf = { [2] = SCA_WAITID_OPTIONS, /* options */ }, }, + .arg = { [2] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, }, { .name = "waitid", .errpid = true, - .arg_scnprintf = { [3] = SCA_WAITID_OPTIONS, /* options */ }, }, - { .name = "write", .errmsg = true, }, - { .name = "writev", .errmsg = true, }, + .arg = { [3] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, }, }; static int syscall_fmt__cmp(const void *name, const void *fmtp) @@ -828,8 +794,7 @@ struct syscall { const char *name; bool is_exit; struct syscall_fmt *fmt; - size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); - void **arg_parm; + struct syscall_arg_fmt *arg_fmt; }; /* @@ -859,6 +824,8 @@ static size_t fprintf_duration(unsigned long t, bool calculated, FILE *fp) * filename.ptr: The filename char pointer that will be vfs_getname'd * filename.entry_str_pos: Where to insert the string translated from * filename.ptr by the vfs_getname tracepoint/kprobe. + * ret_scnprintf: syscall args may set this to a different syscall return + * formatter, for instance, fcntl may return fds, file flags, etc. */ struct thread_trace { u64 entry_time; @@ -867,6 +834,7 @@ struct thread_trace { unsigned long pfmaj, pfmin; char *entry_str; double runtime_ms; + size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); struct { unsigned long ptr; short int entry_str_pos; @@ -917,6 +885,15 @@ fail: return NULL; } + +void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, + size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg)) +{ + struct thread_trace *ttrace = thread__priv(arg->thread); + + ttrace->ret_scnprintf = ret_scnprintf; +} + #define TRACE_PFMAJ (1 << 0) #define TRACE_PFMIN (1 << 1) @@ -996,8 +973,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, return ttrace->paths.table[fd]; } -static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, - struct syscall_arg *arg) +size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg) { int fd = arg->val; size_t printed = scnprintf(bf, size, "%d", fd); @@ -1162,32 +1138,54 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) return err; } +static void trace__symbols__exit(struct trace *trace) +{ + machine__exit(trace->host); + trace->host = NULL; + + symbol__exit(); +} + +static int syscall__alloc_arg_fmts(struct syscall *sc, int nr_args) +{ + int idx; + + if (nr_args == 6 && sc->fmt && sc->fmt->nr_args != 0) + nr_args = sc->fmt->nr_args; + + sc->arg_fmt = calloc(nr_args, sizeof(*sc->arg_fmt)); + if (sc->arg_fmt == NULL) + return -1; + + for (idx = 0; idx < nr_args; ++idx) { + if (sc->fmt) + sc->arg_fmt[idx] = sc->fmt->arg[idx]; + } + + sc->nr_args = nr_args; + return 0; +} + static int syscall__set_arg_fmts(struct syscall *sc) { struct format_field *field; int idx = 0, len; - sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *)); - if (sc->arg_scnprintf == NULL) - return -1; + for (field = sc->args; field; field = field->next, ++idx) { + if (sc->fmt && sc->fmt->arg[idx].scnprintf) + continue; - if (sc->fmt) - sc->arg_parm = sc->fmt->arg_parm; - - for (field = sc->args; field; field = field->next) { - if (sc->fmt && sc->fmt->arg_scnprintf[idx]) - sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; - else if (strcmp(field->type, "const char *") == 0 && + if (strcmp(field->type, "const char *") == 0 && (strcmp(field->name, "filename") == 0 || strcmp(field->name, "path") == 0 || strcmp(field->name, "pathname") == 0)) - sc->arg_scnprintf[idx] = SCA_FILENAME; + sc->arg_fmt[idx].scnprintf = SCA_FILENAME; else if (field->flags & FIELD_IS_POINTER) - sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; + sc->arg_fmt[idx].scnprintf = syscall_arg__scnprintf_hex; else if (strcmp(field->type, "pid_t") == 0) - sc->arg_scnprintf[idx] = SCA_PID; + sc->arg_fmt[idx].scnprintf = SCA_PID; else if (strcmp(field->type, "umode_t") == 0) - sc->arg_scnprintf[idx] = SCA_MODE_T; + sc->arg_fmt[idx].scnprintf = SCA_MODE_T; else if ((strcmp(field->type, "int") == 0 || strcmp(field->type, "unsigned int") == 0 || strcmp(field->type, "long") == 0) && @@ -1200,9 +1198,8 @@ static int syscall__set_arg_fmts(struct syscall *sc) * 23 unsigned int * 7 unsigned long */ - sc->arg_scnprintf[idx] = SCA_FD; + sc->arg_fmt[idx].scnprintf = SCA_FD; } - ++idx; } return 0; @@ -1247,11 +1244,13 @@ static int trace__read_syscall_info(struct trace *trace, int id) sc->tp_format = trace_event__tp_format("syscalls", tp_name); } + if (syscall__alloc_arg_fmts(sc, IS_ERR(sc->tp_format) ? 6 : sc->tp_format->format.nr_fields)) + return -1; + if (IS_ERR(sc->tp_format)) return -1; sc->args = sc->tp_format->format.fields; - sc->nr_args = sc->tp_format->format.nr_fields; /* * We need to check and discard the first variable '__syscall_nr' * or 'nr' that mean the syscall number. It is needless here. @@ -1270,6 +1269,7 @@ static int trace__read_syscall_info(struct trace *trace, int id) static int trace__validate_ev_qualifier(struct trace *trace) { int err = 0, i; + size_t nr_allocated; struct str_node *pos; trace->ev_qualifier_ids.nr = strlist__nr_entries(trace->ev_qualifier); @@ -1283,13 +1283,18 @@ static int trace__validate_ev_qualifier(struct trace *trace) goto out; } + nr_allocated = trace->ev_qualifier_ids.nr; i = 0; strlist__for_each_entry(pos, trace->ev_qualifier) { const char *sc = pos->s; - int id = syscalltbl__id(trace->sctbl, sc); + int id = syscalltbl__id(trace->sctbl, sc), match_next = -1; if (id < 0) { + id = syscalltbl__strglobmatch_first(trace->sctbl, sc, &match_next); + if (id >= 0) + goto matches; + if (err == 0) { fputs("Error:\tInvalid syscall ", trace->output); err = -EINVAL; @@ -1299,13 +1304,37 @@ static int trace__validate_ev_qualifier(struct trace *trace) fputs(sc, trace->output); } - +matches: trace->ev_qualifier_ids.entries[i++] = id; + if (match_next == -1) + continue; + + while (1) { + id = syscalltbl__strglobmatch_next(trace->sctbl, sc, &match_next); + if (id < 0) + break; + if (nr_allocated == trace->ev_qualifier_ids.nr) { + void *entries; + + nr_allocated += 8; + entries = realloc(trace->ev_qualifier_ids.entries, + nr_allocated * sizeof(trace->ev_qualifier_ids.entries[0])); + if (entries == NULL) { + err = -ENOMEM; + fputs("\nError:\t Not enough memory for parsing\n", trace->output); + goto out_free; + } + trace->ev_qualifier_ids.entries = entries; + } + trace->ev_qualifier_ids.nr++; + trace->ev_qualifier_ids.entries[i++] = id; + } } if (err < 0) { fputs("\nHint:\ttry 'perf list syscalls:sys_enter_*'" "\nHint:\tand: 'man syscalls'\n", trace->output); +out_free: zfree(&trace->ev_qualifier_ids.entries); trace->ev_qualifier_ids.nr = 0; } @@ -1321,33 +1350,68 @@ out: * variable to read it. Most notably this avoids extended load instructions * on unaligned addresses */ +unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx) +{ + unsigned long val; + unsigned char *p = arg->args + sizeof(unsigned long) * idx; + + memcpy(&val, p, sizeof(val)); + return val; +} + +static size_t syscall__scnprintf_name(struct syscall *sc, char *bf, size_t size, + struct syscall_arg *arg) +{ + if (sc->arg_fmt && sc->arg_fmt[arg->idx].name) + return scnprintf(bf, size, "%s: ", sc->arg_fmt[arg->idx].name); + + return scnprintf(bf, size, "arg%d: ", arg->idx); +} + +static size_t syscall__scnprintf_val(struct syscall *sc, char *bf, size_t size, + struct syscall_arg *arg, unsigned long val) +{ + if (sc->arg_fmt && sc->arg_fmt[arg->idx].scnprintf) { + arg->val = val; + if (sc->arg_fmt[arg->idx].parm) + arg->parm = sc->arg_fmt[arg->idx].parm; + return sc->arg_fmt[arg->idx].scnprintf(bf, size, arg); + } + return scnprintf(bf, size, "%ld", val); +} static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, unsigned char *args, struct trace *trace, struct thread *thread) { size_t printed = 0; - unsigned char *p; unsigned long val; + u8 bit = 1; + struct syscall_arg arg = { + .args = args, + .idx = 0, + .mask = 0, + .trace = trace, + .thread = thread, + }; + struct thread_trace *ttrace = thread__priv(thread); + + /* + * Things like fcntl will set this in its 'cmd' formatter to pick the + * right formatter for the return value (an fd? file flags?), which is + * not needed for syscalls that always return a given type, say an fd. + */ + ttrace->ret_scnprintf = NULL; if (sc->args != NULL) { struct format_field *field; - u8 bit = 1; - struct syscall_arg arg = { - .idx = 0, - .mask = 0, - .trace = trace, - .thread = thread, - }; for (field = sc->args; field; field = field->next, ++arg.idx, bit <<= 1) { if (arg.mask & bit) continue; - /* special care for unaligned accesses */ - p = args + sizeof(unsigned long) * arg.idx; - memcpy(&val, p, sizeof(val)); + val = syscall_arg__val(&arg, arg.idx); /* * Suppress this argument if its value is zero and @@ -1355,23 +1419,16 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, * strarray for it. */ if (val == 0 && - !(sc->arg_scnprintf && - sc->arg_scnprintf[arg.idx] == SCA_STRARRAY && - sc->arg_parm[arg.idx])) + !(sc->arg_fmt && + (sc->arg_fmt[arg.idx].show_zero || + sc->arg_fmt[arg.idx].scnprintf == SCA_STRARRAY || + sc->arg_fmt[arg.idx].scnprintf == SCA_STRARRAYS) && + sc->arg_fmt[arg.idx].parm)) continue; printed += scnprintf(bf + printed, size - printed, "%s%s: ", printed ? ", " : "", field->name); - if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) { - arg.val = val; - if (sc->arg_parm) - arg.parm = sc->arg_parm[arg.idx]; - printed += sc->arg_scnprintf[arg.idx](bf + printed, - size - printed, &arg); - } else { - printed += scnprintf(bf + printed, size - printed, - "%ld", val); - } + printed += syscall__scnprintf_val(sc, bf + printed, size - printed, &arg, val); } } else if (IS_ERR(sc->tp_format)) { /* @@ -1379,16 +1436,17 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, * may end up not having any args, like with gettid(), so only * print the raw args when we didn't manage to read it. */ - int i = 0; - - while (i < 6) { - /* special care for unaligned accesses */ - p = args + sizeof(unsigned long) * i; - memcpy(&val, p, sizeof(val)); - printed += scnprintf(bf + printed, size - printed, - "%sarg%d: %ld", - printed ? ", " : "", i, val); - ++i; + while (arg.idx < sc->nr_args) { + if (arg.mask & bit) + goto next_arg; + val = syscall_arg__val(&arg, arg.idx); + if (printed) + printed += scnprintf(bf + printed, size - printed, ", "); + printed += syscall__scnprintf_name(sc, bf + printed, size - printed, &arg); + printed += syscall__scnprintf_val(sc, bf + printed, size - printed, &arg, val); +next_arg: + ++arg.idx; + bit <<= 1; } } @@ -1635,17 +1693,31 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, } if (sc->fmt == NULL) { + if (ret < 0) + goto errno_print; signed_print: fprintf(trace->output, ") = %ld", ret); - } else if (ret < 0 && (sc->fmt->errmsg || sc->fmt->errpid)) { + } else if (ret < 0) { +errno_print: { char bf[STRERR_BUFSIZE]; const char *emsg = str_error_r(-ret, bf, sizeof(bf)), *e = audit_errno_to_name(-ret); fprintf(trace->output, ") = -1 %s %s", e, emsg); + } } else if (ret == 0 && sc->fmt->timeout) fprintf(trace->output, ") = 0 Timeout"); - else if (sc->fmt->hexret) + else if (ttrace->ret_scnprintf) { + char bf[1024]; + struct syscall_arg arg = { + .val = ret, + .thread = thread, + .trace = trace, + }; + ttrace->ret_scnprintf(bf, sizeof(bf), &arg); + ttrace->ret_scnprintf = NULL; + fprintf(trace->output, ") = %s", bf); + } else if (sc->fmt->hexret) fprintf(trace->output, ") = %#lx", ret); else if (sc->fmt->errpid) { struct thread *child = machine__find_thread(trace->host, ret, ret); @@ -2171,6 +2243,30 @@ out_enomem: goto out; } +static int trace__set_filter_loop_pids(struct trace *trace) +{ + unsigned int nr = 1; + pid_t pids[32] = { + getpid(), + }; + struct thread *thread = machine__find_thread(trace->host, pids[0], pids[0]); + + while (thread && nr < ARRAY_SIZE(pids)) { + struct thread *parent = machine__find_thread(trace->host, thread->ppid, thread->ppid); + + if (parent == NULL) + break; + + if (!strcmp(thread__comm_str(parent), "sshd")) { + pids[nr++] = parent->tid; + break; + } + thread = parent; + } + + return perf_evlist__set_filter_pids(trace->evlist, nr, pids); +} + static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = trace->evlist; @@ -2294,7 +2390,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (trace->filter_pids.nr > 0) err = perf_evlist__set_filter_pids(evlist, trace->filter_pids.nr, trace->filter_pids.entries); else if (thread_map__pid(evlist->threads, 0) == -1) - err = perf_evlist__set_filter_pid(evlist, getpid()); + err = trace__set_filter_loop_pids(trace); if (err < 0) goto out_error_mem; @@ -2393,6 +2489,8 @@ out_disable: } out_delete_evlist: + trace__symbols__exit(trace); + perf_evlist__delete(evlist); trace->evlist = NULL; trace->live = false; @@ -2756,7 +2854,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str, struct trace *trace = (struct trace *)opt->value; const char *s = str; char *sep = NULL, *lists[2] = { NULL, NULL, }; - int len = strlen(str), err = -1, list; + int len = strlen(str) + 1, err = -1, list, idx; char *strace_groups_dir = system_path(STRACE_GROUPS_DIR); char group_name[PATH_MAX]; @@ -2773,7 +2871,8 @@ static int trace__parse_events_option(const struct option *opt, const char *str, *sep = '\0'; list = 0; - if (syscalltbl__id(trace->sctbl, s) >= 0) { + if (syscalltbl__id(trace->sctbl, s) >= 0 || + syscalltbl__strglobmatch_first(trace->sctbl, s, &idx) >= 0) { list = 1; } else { path__join(group_name, sizeof(group_name), strace_groups_dir, s); diff --git a/tools/perf/builtin-version.c b/tools/perf/builtin-version.c index d25149456a2f..37019c5d675f 100644 --- a/tools/perf/builtin-version.c +++ b/tools/perf/builtin-version.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "builtin.h" #include "perf.h" #include diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h index d4d19fe3d050..05745f3ce912 100644 --- a/tools/perf/builtin.h +++ b/tools/perf/builtin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BUILTIN_H #define BUILTIN_H diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 83fe2202382e..50cd6228f506 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -1,9 +1,16 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 HEADERS=' +include/uapi/drm/drm.h +include/uapi/drm/i915_drm.h include/uapi/linux/fcntl.h +include/uapi/linux/kvm.h include/uapi/linux/perf_event.h +include/uapi/linux/sched.h include/uapi/linux/stat.h +include/uapi/linux/vhost.h +include/uapi/sound/asound.h include/linux/hash.h include/uapi/linux/hw_breakpoint.h arch/x86/include/asm/disabled-features.h @@ -16,6 +23,7 @@ arch/x86/include/uapi/asm/perf_regs.h arch/x86/include/uapi/asm/kvm.h arch/x86/include/uapi/asm/kvm_perf.h arch/x86/include/uapi/asm/svm.h +arch/x86/include/uapi/asm/unistd.h arch/x86/include/uapi/asm/vmx.h arch/powerpc/include/uapi/asm/kvm.h arch/s390/include/uapi/asm/kvm.h @@ -29,12 +37,13 @@ include/asm-generic/bitops/__fls.h include/asm-generic/bitops/fls.h include/asm-generic/bitops/fls64.h include/linux/coresight-pmu.h +include/uapi/asm-generic/ioctls.h include/uapi/asm-generic/mman-common.h ' check () { file=$1 - opts= + opts="--ignore-blank-lines --ignore-space-change" shift while [ -n "$*" ]; do @@ -45,7 +54,7 @@ check () { cmd="diff $opts ../$file ../../$file > /dev/null" test -f ../../$file && - eval $cmd || echo "Warning: $file differs from kernel" >&2 + eval $cmd || echo "Warning: Kernel ABI header at 'tools/$file' differs from latest version at '$file'" >&2 } @@ -55,7 +64,7 @@ for i in $HEADERS; do done # diff with extra ignore lines -check arch/x86/lib/memcpy_64.S -B -I "^EXPORT_SYMBOL" -I "^#include " -check arch/x86/lib/memset_64.S -B -I "^EXPORT_SYMBOL" -I "^#include " -check include/uapi/asm-generic/mman.h -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>" -check include/uapi/linux/mman.h -B -I "^#include <\(uapi/\)*asm/mman.h>" +check arch/x86/lib/memcpy_64.S -I "^EXPORT_SYMBOL" -I "^#include " +check arch/x86/lib/memset_64.S -I "^EXPORT_SYMBOL" -I "^#include " +check include/uapi/asm-generic/mman.h -I "^#include <\(uapi/\)*asm-generic/mman-common.h>" +check include/uapi/linux/mman.h -I "^#include <\(uapi/\)*asm/mman.h>" diff --git a/tools/perf/jvmti/jvmti_agent.h b/tools/perf/jvmti/jvmti_agent.h index c53a41f48b63..fe32d8344a82 100644 --- a/tools/perf/jvmti/jvmti_agent.h +++ b/tools/perf/jvmti/jvmti_agent.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __JVMTI_AGENT_H__ #define __JVMTI_AGENT_H__ diff --git a/tools/perf/jvmti/libjvmti.c b/tools/perf/jvmti/libjvmti.c index 6d710904c837..c62c9fc9a525 100644 --- a/tools/perf/jvmti/libjvmti.c +++ b/tools/perf/jvmti/libjvmti.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/perf-archive.sh b/tools/perf/perf-archive.sh index e91930620269..0cfb3e2cefef 100644 --- a/tools/perf/perf-archive.sh +++ b/tools/perf/perf-archive.sh @@ -1,4 +1,5 @@ #!/bin/bash +# SPDX-License-Identifier: GPL-2.0 # perf archive # Arnaldo Carvalho de Melo diff --git a/tools/perf/perf-completion.sh b/tools/perf/perf-completion.sh index 3ba80b2359cc..345f5d6e9ed5 100644 --- a/tools/perf/perf-completion.sh +++ b/tools/perf/perf-completion.sh @@ -1,4 +1,5 @@ # perf bash and zsh completion +# SPDX-License-Identifier: GPL-2.0 # Taken from git.git's completion script. __my_reassemble_comp_words_by_ref() diff --git a/tools/perf/perf-read-vdso.c b/tools/perf/perf-read-vdso.c index 764e2547c25a..8c0ca0cc428f 100644 --- a/tools/perf/perf-read-vdso.c +++ b/tools/perf/perf-read-vdso.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h index e4b717e9eb6c..36673f98d66b 100644 --- a/tools/perf/perf-sys.h +++ b/tools/perf/perf-sys.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_SYS_H #define _PERF_SYS_H @@ -9,16 +10,6 @@ #include #include -#if defined(__i386__) -#define cpu_relax() asm volatile("rep; nop" ::: "memory"); -#define CPUINFO_PROC {"model name"} -#endif - -#if defined(__x86_64__) -#define cpu_relax() asm volatile("rep; nop" ::: "memory"); -#define CPUINFO_PROC {"model name"} -#endif - #ifdef __powerpc__ #define CPUINFO_PROC {"cpu"} #endif @@ -43,19 +34,10 @@ #define CPUINFO_PROC {"cpu model"} #endif -#ifdef __ia64__ -#define cpu_relax() asm volatile ("hint @pause" ::: "memory") -#define CPUINFO_PROC {"model name"} -#endif - #ifdef __arm__ #define CPUINFO_PROC {"model name", "Processor"} #endif -#ifdef __aarch64__ -#define cpu_relax() asm volatile("yield" ::: "memory") -#endif - #ifdef __mips__ #define CPUINFO_PROC {"cpu model"} #endif @@ -72,13 +54,8 @@ #define CPUINFO_PROC {"core ID"} #endif -#ifdef __tile__ -#define cpu_relax() asm volatile ("mfspr zero, PASS" ::: "memory") -#define CPUINFO_PROC {"model name"} -#endif - -#ifndef cpu_relax -#define cpu_relax() barrier() +#ifndef CPUINFO_PROC +#define CPUINFO_PROC { "model name", } #endif static inline int diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 628a5e412cb1..62b13518bc6e 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * perf.c * @@ -89,7 +90,7 @@ struct pager_config { static int pager_command_config(const char *var, const char *value, void *data) { struct pager_config *c = data; - if (!prefixcmp(var, "pager.") && !strcmp(var + 6, c->cmd)) + if (strstarts(var, "pager.") && !strcmp(var + 6, c->cmd)) c->val = perf_config_bool(var, value); return 0; } @@ -108,9 +109,9 @@ static int check_pager_config(const char *cmd) static int browser_command_config(const char *var, const char *value, void *data) { struct pager_config *c = data; - if (!prefixcmp(var, "tui.") && !strcmp(var + 4, c->cmd)) + if (strstarts(var, "tui.") && !strcmp(var + 4, c->cmd)) c->val = perf_config_bool(var, value); - if (!prefixcmp(var, "gtk.") && !strcmp(var + 4, c->cmd)) + if (strstarts(var, "gtk.") && !strcmp(var + 4, c->cmd)) c->val = perf_config_bool(var, value) ? 2 : 0; return 0; } @@ -192,7 +193,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) /* * Check remaining flags. */ - if (!prefixcmp(cmd, CMD_EXEC_PATH)) { + if (strstarts(cmd, CMD_EXEC_PATH)) { cmd += strlen(CMD_EXEC_PATH); if (*cmd == '=') set_argv_exec_path(cmd + 1); @@ -229,7 +230,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) *envchanged = 1; (*argv)++; (*argc)--; - } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { + } else if (strstarts(cmd, CMD_DEBUGFS_DIR)) { tracing_path_set(cmd + strlen(CMD_DEBUGFS_DIR)); fprintf(stderr, "dir: %s\n", tracing_path); if (envchanged) @@ -467,17 +468,23 @@ int main(int argc, const char **argv) * - cannot execute it externally (since it would just do * the same thing over again) * - * So we just directly call the internal command handler, and - * die if that one cannot handle it. + * So we just directly call the internal command handler. If that one + * fails to handle this, then maybe we just run a renamed perf binary + * that contains a dash in its name. To handle this scenario, we just + * fall through and ignore the "xxxx" part of the command string. */ - if (!prefixcmp(cmd, "perf-")) { + if (strstarts(cmd, "perf-")) { cmd += 5; argv[0] = cmd; handle_internal_command(argc, argv); - fprintf(stderr, "cannot handle %s internally", cmd); - goto out; + /* + * If the command is handled, the above function does not + * return undo changes and fall through in such a case. + */ + cmd -= 5; + argv[0] = cmd; } - if (!prefixcmp(cmd, "trace")) { + if (strstarts(cmd, "trace")) { #ifdef HAVE_LIBAUDIT_SUPPORT setup_path(); argv[0] = "trace"; @@ -495,7 +502,7 @@ int main(int argc, const char **argv) commit_pager_choice(); if (argc > 0) { - if (!prefixcmp(argv[0], "--")) + if (strstarts(argv[0], "--")) argv[0] += 2; } else { /* The user didn't specify a command; give them help */ diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 806c216a1078..f75f3dec7485 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_PERF_H #define _PERF_PERF_H @@ -7,6 +8,7 @@ #include extern bool test_attr__enabled; +void test_attr__ready(void); void test_attr__init(void); void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, int fd, int group_fd, unsigned long flags); @@ -42,6 +44,7 @@ struct record_opts { bool no_samples; bool raw_samples; bool sample_address; + bool sample_phys_addr; bool sample_weight; bool sample_time; bool sample_time_set; diff --git a/tools/perf/pmu-events/README b/tools/perf/pmu-events/README index 1408ade0d773..c2ee3e4417fe 100644 --- a/tools/perf/pmu-events/README +++ b/tools/perf/pmu-events/README @@ -85,10 +85,6 @@ users to specify events by their name: where 'pm_1plus_ppc_cmpl' is a Power8 PMU event. -In case of errors when processing files in the tools/perf/pmu-events/arch -directory, 'jevents' tries to create an empty mapping file to allow the perf -build to succeed even if the PMU event aliases cannot be used. - However some errors in processing may cause the perf build to fail. Mapfile format diff --git a/tools/perf/pmu-events/arch/powerpc/mapfile.csv b/tools/perf/pmu-events/arch/powerpc/mapfile.csv index e925baa0c30b..a0f3a11ca19f 100644 --- a/tools/perf/pmu-events/arch/powerpc/mapfile.csv +++ b/tools/perf/pmu-events/arch/powerpc/mapfile.csv @@ -13,9 +13,13 @@ # # Power8 entries -004b0000,1,power8.json,core -004b0201,1,power8.json,core -004c0000,1,power8.json,core -004d0000,1,power8.json,core -004d0100,1,power8.json,core -004d0200,1,power8.json,core +004b0000,1,power8,core +004b0201,1,power8,core +004c0000,1,power8,core +004d0000,1,power8,core +004d0100,1,power8,core +004d0200,1,power8,core +004c0100,1,power8,core +004e0100,1,power9,core +004e0200,1,power9,core +004e1200,1,power9,core diff --git a/tools/perf/pmu-events/arch/powerpc/power9/cache.json b/tools/perf/pmu-events/arch/powerpc/power9/cache.json new file mode 100644 index 000000000000..18f6645f2897 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/cache.json @@ -0,0 +1,137 @@ +[ + {, + "EventCode": "0x300F4", + "EventName": "PM_THRD_CONC_RUN_INST", + "BriefDescription": "PPC Instructions Finished by this thread when all threads in the core had the run-latch set" + }, + {, + "EventCode": "0x1E056", + "EventName": "PM_CMPLU_STALL_FLUSH_ANY_THREAD", + "BriefDescription": "Cycles in which the NTC instruction is not allowed to complete because any of the 4 threads in the same core suffered a flush, which blocks completion" + }, + {, + "EventCode": "0x4D016", + "EventName": "PM_CMPLU_STALL_FXLONG", + "BriefDescription": "Completion stall due to a long latency scalar fixed point instruction (division, square root)" + }, + {, + "EventCode": "0x2D016", + "EventName": "PM_CMPLU_STALL_FXU", + "BriefDescription": "Finish stall due to a scalar fixed point or CR instruction in the execution pipeline. These instructions get routed to the ALU, ALU2, and DIV pipes" + }, + {, + "EventCode": "0x1D15C", + "EventName": "PM_MRK_DTLB_MISS_1G", + "BriefDescription": "Marked Data TLB reload (after a miss) page size 2M. Implies radix translation was used" + }, + {, + "EventCode": "0x4D12A", + "EventName": "PM_MRK_DATA_FROM_RL4_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's L4 on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x1003C", + "EventName": "PM_CMPLU_STALL_DMISS_L2L3", + "BriefDescription": "Completion stall by Dcache miss which resolved in L2/L3" + }, + {, + "EventCode": "0x4C014", + "EventName": "PM_CMPLU_STALL_LMQ_FULL", + "BriefDescription": "Finish stall because the NTF instruction was a load that missed in the L1 and the LMQ was unable to accept this load miss request because it was full" + }, + {, + "EventCode": "0x14048", + "EventName": "PM_INST_FROM_ON_CHIP_CACHE", + "BriefDescription": "The processor's Instruction cache was reloaded either shared or modified data from another core's L2/L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4D014", + "EventName": "PM_CMPLU_STALL_LOAD_FINISH", + "BriefDescription": "Finish stall because the NTF instruction was a load instruction with all its dependencies satisfied just going through the LSU pipe to finish" + }, + {, + "EventCode": "0x2404A", + "EventName": "PM_INST_FROM_RL4", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's L4 on the same Node or Group ( Remote) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1404A", + "EventName": "PM_INST_FROM_RL2L3_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x401EA", + "EventName": "PM_THRESH_EXC_128", + "BriefDescription": "Threshold counter exceeded a value of 128" + }, + {, + "EventCode": "0x400F6", + "EventName": "PM_BR_MPRED_CMPL", + "BriefDescription": "Number of Branch Mispredicts" + }, + {, + "EventCode": "0x2F140", + "EventName": "PM_MRK_DPTEG_FROM_L2_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 hit without dispatch conflicts on Mepf state. due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x101E6", + "EventName": "PM_THRESH_EXC_4096", + "BriefDescription": "Threshold counter exceed a count of 4096" + }, + {, + "EventCode": "0x3D156", + "EventName": "PM_MRK_DTLB_MISS_64K", + "BriefDescription": "Marked Data TLB Miss page size 64K" + }, + {, + "EventCode": "0x4C15E", + "EventName": "PM_MRK_DTLB_MISS_16M", + "BriefDescription": "Marked Data TLB Miss page size 16M" + }, + {, + "EventCode": "0x2D15E", + "EventName": "PM_MRK_DTLB_MISS_16G", + "BriefDescription": "Marked Data TLB Miss page size 16G" + }, + {, + "EventCode": "0x3F14A", + "EventName": "PM_MRK_DPTEG_FROM_RMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group ( Remote) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4C016", + "EventName": "PM_CMPLU_STALL_DMISS_L2L3_CONFLICT", + "BriefDescription": "Completion stall due to cache miss that resolves in the L2 or L3 with a conflict" + }, + {, + "EventCode": "0x2C01A", + "EventName": "PM_CMPLU_STALL_LHS", + "BriefDescription": "Finish stall because the NTF instruction was a load that hit on an older store and it was waiting for store data" + }, + {, + "EventCode": "0x401E4", + "EventName": "PM_MRK_DTLB_MISS", + "BriefDescription": "Marked dtlb miss" + }, + {, + "EventCode": "0x24046", + "EventName": "PM_INST_FROM_RL2L3_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1002A", + "EventName": "PM_CMPLU_STALL_LARX", + "BriefDescription": "Finish stall because the NTF instruction was a larx waiting to be satisfied" + }, + {, + "EventCode": "0x3006C", + "EventName": "PM_RUN_CYC_SMT2_MODE", + "BriefDescription": "Cycles in which this thread's run latch is set and the core is in SMT2 mode" + }, + {, + "EventCode": "0x1C058", + "EventName": "PM_DTLB_MISS_16G", + "BriefDescription": "Data TLB Miss page size 16G" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/powerpc/power9/floating-point.json b/tools/perf/pmu-events/arch/powerpc/power9/floating-point.json new file mode 100644 index 000000000000..8a83bca26552 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/floating-point.json @@ -0,0 +1,32 @@ +[ + {, + "EventCode": "0x1415A", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_LDHITST_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 with load hit store conflict due to a marked load" + }, + {, + "EventCode": "0x10058", + "EventName": "PM_MEM_LOC_THRESH_IFU", + "BriefDescription": "Local Memory above threshold for IFU speculation control" + }, + {, + "EventCode": "0x2D028", + "EventName": "PM_RADIX_PWC_L2_PDE_FROM_L2", + "BriefDescription": "A Page Directory Entry was reloaded to a level 2 page walk cache from the core's L2 data cache" + }, + {, + "EventCode": "0x30012", + "EventName": "PM_FLUSH_COMPLETION", + "BriefDescription": "The instruction that was next to complete did not complete because it suffered a flush" + }, + {, + "EventCode": "0x2D154", + "EventName": "PM_MRK_DERAT_MISS_64K", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 64K" + }, + {, + "EventCode": "0x4016E", + "EventName": "PM_THRESH_NOT_MET", + "BriefDescription": "Threshold counter did not meet threshold" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/powerpc/power9/frontend.json b/tools/perf/pmu-events/arch/powerpc/power9/frontend.json new file mode 100644 index 000000000000..c63a919eda98 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/frontend.json @@ -0,0 +1,372 @@ +[ + {, + "EventCode": "0x3E15C", + "EventName": "PM_MRK_L2_TM_ST_ABORT_SISTER", + "BriefDescription": "TM marked store abort for this thread" + }, + {, + "EventCode": "0x25044", + "EventName": "PM_IPTEG_FROM_L31_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x101E8", + "EventName": "PM_THRESH_EXC_256", + "BriefDescription": "Threshold counter exceed a count of 256" + }, + {, + "EventCode": "0x4504E", + "EventName": "PM_IPTEG_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L3 due to a instruction side request" + }, + {, + "EventCode": "0x1006A", + "EventName": "PM_NTC_ISSUE_HELD_DARQ_FULL", + "BriefDescription": "The NTC instruction is being held at dispatch because there are no slots in the DARQ for it" + }, + {, + "EventCode": "0x4E016", + "EventName": "PM_CMPLU_STALL_LSAQ_ARB", + "BriefDescription": "Finish stall because the NTF instruction was a load or store that was held in LSAQ because an older instruction from SRQ or LRQ won arbitration to the LSU pipe when this instruction tried to launch" + }, + {, + "EventCode": "0x1001A", + "EventName": "PM_LSU_SRQ_FULL_CYC", + "BriefDescription": "Cycles in which the Store Queue is full on all 4 slices. This is event is not per thread. All the threads will see the same count for this core resource" + }, + {, + "EventCode": "0x1E15E", + "EventName": "PM_MRK_L2_TM_REQ_ABORT", + "BriefDescription": "TM abort" + }, + {, + "EventCode": "0x34052", + "EventName": "PM_INST_SYS_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (system) mispredicted. Either the original scope was too small (Chip/Group) or the original scope was System and it should have been smaller. Counts for an instruction fetch" + }, + {, + "EventCode": "0x20114", + "EventName": "PM_MRK_L2_RC_DISP", + "BriefDescription": "Marked Instruction RC dispatched in L2" + }, + {, + "EventCode": "0x4C044", + "EventName": "PM_DATA_FROM_L31_ECO_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's ECO L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x1C044", + "EventName": "PM_DATA_FROM_L3_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without conflict due to a demand load" + }, + {, + "EventCode": "0x44050", + "EventName": "PM_INST_SYS_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (system) ended up larger than Initial Pump Scope (Chip/Group) for an instruction fetch" + }, + {, + "EventCode": "0x30154", + "EventName": "PM_MRK_FAB_RSP_DCLAIM", + "BriefDescription": "Marked store had to do a dclaim" + }, + {, + "EventCode": "0x30014", + "EventName": "PM_CMPLU_STALL_STORE_FIN_ARB", + "BriefDescription": "Finish stall because the NTF instruction was a store waiting for a slot in the store finish pipe. This means the instruction is ready to finish but there are instructions ahead of it, using the finish pipe" + }, + {, + "EventCode": "0x3E054", + "EventName": "PM_LD_MISS_L1", + "BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." + }, + {, + "EventCode": "0x2E01A", + "EventName": "PM_CMPLU_STALL_LSU_FLUSH_NEXT", + "BriefDescription": "Completion stall of one cycle because the LSU requested to flush the next iop in the sequence. It takes 1 cycle for the ISU to process this request before the LSU instruction is allowed to complete" + }, + {, + "EventCode": "0x2D01C", + "EventName": "PM_CMPLU_STALL_STCX", + "BriefDescription": "Finish stall because the NTF instruction was a stcx waiting for response from L2" + }, + {, + "EventCode": "0x2C010", + "EventName": "PM_CMPLU_STALL_LSU", + "BriefDescription": "Completion stall by LSU instruction" + }, + {, + "EventCode": "0x2C042", + "EventName": "PM_DATA_FROM_L3_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without dispatch conflicts hit on Mepf state due to a demand load" + }, + {, + "EventCode": "0x4E012", + "EventName": "PM_CMPLU_STALL_MTFPSCR", + "BriefDescription": "Completion stall because the ISU is updating the register and notifying the Effective Address Table (EAT)" + }, + {, + "EventCode": "0x100F2", + "EventName": "PM_1PLUS_PPC_CMPL", + "BriefDescription": "1 or more ppc insts finished" + }, + {, + "EventCode": "0x3001C", + "EventName": "PM_LSU_REJECT_LMQ_FULL", + "BriefDescription": "LSU Reject due to LMQ full (up to 4 per cycles)" + }, + {, + "EventCode": "0x15046", + "EventName": "PM_IPTEG_FROM_L31_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x1015E", + "EventName": "PM_MRK_FAB_RSP_RD_T_INTV", + "BriefDescription": "Sampled Read got a T intervention" + }, + {, + "EventCode": "0x101EC", + "EventName": "PM_THRESH_MET", + "BriefDescription": "threshold exceeded" + }, + {, + "EventCode": "0x10020", + "EventName": "PM_PMC4_REWIND", + "BriefDescription": "PMC4 Rewind Event" + }, + {, + "EventCode": "0x301EA", + "EventName": "PM_THRESH_EXC_1024", + "BriefDescription": "Threshold counter exceeded a value of 1024" + }, + {, + "EventCode": "0x34056", + "EventName": "PM_CMPLU_STALL_LSU_MFSPR", + "BriefDescription": "Finish stall because the NTF instruction was a mfspr instruction targeting an LSU SPR and it was waiting for the register data to be returned" + }, + {, + "EventCode": "0x44056", + "EventName": "PM_VECTOR_ST_CMPL", + "BriefDescription": "Number of vector store instructions completed" + }, + {, + "EventCode": "0x2C124", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_OTHER", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0x4C12A", + "EventName": "PM_MRK_DATA_FROM_RL2L3_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x3C056", + "EventName": "PM_DTLB_MISS_64K", + "BriefDescription": "Data TLB Miss page size 64K" + }, + {, + "EventCode": "0x30060", + "EventName": "PM_TM_TRANS_RUN_INST", + "BriefDescription": "Run instructions completed in transactional state (gated by the run latch)" + }, + {, + "EventCode": "0x2C014", + "EventName": "PM_CMPLU_STALL_STORE_FINISH", + "BriefDescription": "Finish stall because the NTF instruction was a store with all its dependencies met, just waiting to go through the LSU pipe to finish" + }, + {, + "EventCode": "0x3515A", + "EventName": "PM_MRK_DATA_FROM_ON_CHIP_CACHE_CYC", + "BriefDescription": "Duration in cycles to reload either shared or modified data from another core's L2/L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x34050", + "EventName": "PM_INST_SYS_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was system pump (prediction=correct) for an instruction fetch" + }, + {, + "EventCode": "0x3015E", + "EventName": "PM_MRK_FAB_RSP_CLAIM_RTY", + "BriefDescription": "Sampled store did a rwitm and got a rty" + }, + {, + "EventCode": "0x0", + "EventName": "PM_SUSPENDED", + "BriefDescription": "Counter OFF" + }, + {, + "EventCode": "0x10010", + "EventName": "PM_PMC4_OVERFLOW", + "BriefDescription": "Overflow from counter 4" + }, + {, + "EventCode": "0x3E04A", + "EventName": "PM_DPTEG_FROM_RMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group ( Remote) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2F152", + "EventName": "PM_MRK_FAB_RSP_DCLAIM_CYC", + "BriefDescription": "cycles L2 RC took for a dclaim" + }, + {, + "EventCode": "0x10004", + "EventName": "PM_CMPLU_STALL_LRQ_OTHER", + "BriefDescription": "Finish stall due to LRQ miscellaneous reasons, lost arbitration to LMQ slot, bank collisions, set prediction cleanup, set prediction multihit and others" + }, + {, + "EventCode": "0x4F150", + "EventName": "PM_MRK_FAB_RSP_RWITM_CYC", + "BriefDescription": "cycles L2 RC took for a rwitm" + }, + {, + "EventCode": "0x4E042", + "EventName": "PM_DPTEG_FROM_L3", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1F054", + "EventName": "PM_TLB_HIT", + "BriefDescription": "Number of times the TLB had the data required by the instruction. Applies to both HPT and RPT" + }, + {, + "EventCode": "0x2C01E", + "EventName": "PM_CMPLU_STALL_SYNC_PMU_INT", + "BriefDescription": "Cycles in which the NTC instruction is waiting for a synchronous PMU interrupt" + }, + {, + "EventCode": "0x24050", + "EventName": "PM_IOPS_CMPL", + "BriefDescription": "Internal Operations completed" + }, + {, + "EventCode": "0x1515C", + "EventName": "PM_SYNC_MRK_BR_MPRED", + "BriefDescription": "Marked Branch mispredict that can cause a synchronous interrupt" + }, + {, + "EventCode": "0x300FA", + "EventName": "PM_INST_FROM_L3MISS", + "BriefDescription": "Marked instruction was reloaded from a location beyond the local chiplet" + }, + {, + "EventCode": "0x15044", + "EventName": "PM_IPTEG_FROM_L3_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without conflict due to a instruction side request" + }, + {, + "EventCode": "0x15152", + "EventName": "PM_SYNC_MRK_BR_LINK", + "BriefDescription": "Marked Branch and link branch that can cause a synchronous interrupt" + }, + {, + "EventCode": "0x1E050", + "EventName": "PM_CMPLU_STALL_TEND", + "BriefDescription": "Finish stall because the NTF instruction was a tend instruction awaiting response from L2" + }, + {, + "EventCode": "0x1013E", + "EventName": "PM_MRK_LD_MISS_EXPOSED_CYC", + "BriefDescription": "Marked Load exposed Miss (use edge detect to count #)" + }, + {, + "EventCode": "0x25042", + "EventName": "PM_IPTEG_FROM_L3_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without dispatch conflicts hit on Mepf state. due to a instruction side request" + }, + {, + "EventCode": "0x14054", + "EventName": "PM_INST_PUMP_CPRED", + "BriefDescription": "Pump prediction correct. Counts across all types of pumps for an instruction fetch" + }, + {, + "EventCode": "0x4015E", + "EventName": "PM_MRK_FAB_RSP_RD_RTY", + "BriefDescription": "Sampled L2 reads retry count" + }, + {, + "EventCode": "0x45048", + "EventName": "PM_IPTEG_FROM_DL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x44052", + "EventName": "PM_INST_PUMP_MPRED", + "BriefDescription": "Pump misprediction. Counts across all types of pumps for an instruction fetch" + }, + {, + "EventCode": "0x30026", + "EventName": "PM_CMPLU_STALL_STORE_DATA", + "BriefDescription": "Finish stall because the next to finish instruction was a store waiting on data" + }, + {, + "EventCode": "0x301E6", + "EventName": "PM_MRK_DERAT_MISS", + "BriefDescription": "Erat Miss (TLB Access) All page sizes" + }, + {, + "EventCode": "0x24154", + "EventName": "PM_THRESH_ACC", + "BriefDescription": "This event increments every time the threshold event counter ticks. Thresholding must be enabled (via MMCRA) and the thresholding start event must occur for this counter to increment. It will stop incrementing when the thresholding stop event occurs or when thresholding is disabled, until the next time a configured thresholding start event occurs." + }, + {, + "EventCode": "0x2015E", + "EventName": "PM_MRK_FAB_RSP_RWITM_RTY", + "BriefDescription": "Sampled store did a rwitm and got a rty" + }, + {, + "EventCode": "0x200FA", + "EventName": "PM_BR_TAKEN_CMPL", + "BriefDescription": "New event for Branch Taken" + }, + {, + "EventCode": "0x35044", + "EventName": "PM_IPTEG_FROM_L31_ECO_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's ECO L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x4C010", + "EventName": "PM_CMPLU_STALL_STORE_PIPE_ARB", + "BriefDescription": "Finish stall because the NTF instruction was a store waiting for the next relaunch opportunity after an internal reject. This means the instruction is ready to relaunch and tried once but lost arbitration" + }, + {, + "EventCode": "0x4C01C", + "EventName": "PM_CMPLU_STALL_ST_FWD", + "BriefDescription": "Completion stall due to store forward" + }, + {, + "EventCode": "0x3515C", + "EventName": "PM_MRK_DATA_FROM_RL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x2D14C", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x40116", + "EventName": "PM_MRK_LARX_FIN", + "BriefDescription": "Larx finished" + }, + {, + "EventCode": "0x4C056", + "EventName": "PM_DTLB_MISS_16M", + "BriefDescription": "Data TLB Miss page size 16M" + }, + {, + "EventCode": "0x1003A", + "EventName": "PM_CMPLU_STALL_LSU_FIN", + "BriefDescription": "Finish stall because the NTF instruction was an LSU op (other than a load or a store) with all its dependencies met and just going through the LSU pipe to finish" + }, + {, + "EventCode": "0x3012A", + "EventName": "PM_MRK_L2_RC_DONE", + "BriefDescription": "Marked RC done" + }, + {, + "EventCode": "0x45044", + "EventName": "PM_IPTEG_FROM_L31_ECO_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a instruction side request" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/marked.json b/tools/perf/pmu-events/arch/powerpc/power9/marked.json new file mode 100644 index 000000000000..b9df54fb37e3 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/marked.json @@ -0,0 +1,647 @@ +[ + {, + "EventCode": "0x3C052", + "EventName": "PM_DATA_SYS_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (system) mispredicted. Either the original scope was too small (Chip/Group) or the original scope was System and it should have been smaller. Counts for a demand load" + }, + {, + "EventCode": "0x3013E", + "EventName": "PM_MRK_STALL_CMPLU_CYC", + "BriefDescription": "Number of cycles the marked instruction is experiencing a stall while it is next to complete (NTC)" + }, + {, + "EventCode": "0x4F056", + "EventName": "PM_RADIX_PWC_L1_PDE_FROM_L3MISS", + "BriefDescription": "A Page Directory Entry was reloaded to a level 1 page walk cache from beyond the core's L3 data cache. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x24158", + "EventName": "PM_MRK_INST", + "BriefDescription": "An instruction was marked. Includes both Random Instruction Sampling (RIS) at decode time and Random Event Sampling (RES) at the time the configured event happens" + }, + {, + "EventCode": "0x1E046", + "EventName": "PM_DPTEG_FROM_L31_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3C04A", + "EventName": "PM_DATA_FROM_RMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group ( Remote) due to a demand load" + }, + {, + "EventCode": "0x2C01C", + "EventName": "PM_CMPLU_STALL_DMISS_REMOTE", + "BriefDescription": "Completion stall by Dcache miss which resolved from remote chip (cache or memory)" + }, + {, + "EventCode": "0x44040", + "EventName": "PM_INST_FROM_L2_DISP_CONFLICT_OTHER", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 with dispatch conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x2E050", + "EventName": "PM_DARQ0_7_9_ENTRIES", + "BriefDescription": "Cycles in which 7,8, or 9 DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x2D02E", + "EventName": "PM_RADIX_PWC_L3_PTE_FROM_L2", + "BriefDescription": "A Page Table Entry was reloaded to a level 3 page walk cache from the core's L2 data cache. This implies that a level 4 PWC access was not necessary for this translation" + }, + {, + "EventCode": "0x3F05E", + "EventName": "PM_RADIX_PWC_L3_PTE_FROM_L3", + "BriefDescription": "A Page Table Entry was reloaded to a level 3 page walk cache from the core's L3 data cache. This implies that a level 4 PWC access was not necessary for this translation" + }, + {, + "EventCode": "0x2E01E", + "EventName": "PM_CMPLU_STALL_NTC_FLUSH", + "BriefDescription": "Completion stall due to ntc flush" + }, + {, + "EventCode": "0x1F14C", + "EventName": "PM_MRK_DPTEG_FROM_LL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's L4 cache due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x20130", + "EventName": "PM_MRK_INST_DECODED", + "BriefDescription": "An instruction was marked at decode time. Random Instruction Sampling (RIS) only" + }, + {, + "EventCode": "0x3F144", + "EventName": "PM_MRK_DPTEG_FROM_L31_ECO_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's ECO L3 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D058", + "EventName": "PM_VECTOR_FLOP_CMPL", + "BriefDescription": "Vector FP instruction completed" + }, + {, + "EventCode": "0x14040", + "EventName": "PM_INST_FROM_L2_NO_CONFLICT", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 without conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4404E", + "EventName": "PM_INST_FROM_L3MISS_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded from a location other than the local core's L3 due to a instruction fetch" + }, + {, + "EventCode": "0x3003A", + "EventName": "PM_CMPLU_STALL_EXCEPTION", + "BriefDescription": "Cycles in which the NTC instruction is not allowed to complete because it was interrupted by ANY exception, which has to be serviced before the instruction can complete" + }, + {, + "EventCode": "0x4F144", + "EventName": "PM_MRK_DPTEG_FROM_L31_ECO_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3E044", + "EventName": "PM_DPTEG_FROM_L31_ECO_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's ECO L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x300F6", + "EventName": "PM_L1_DCACHE_RELOAD_VALID", + "BriefDescription": "DL1 reloaded due to Demand Load" + }, + {, + "EventCode": "0x1415E", + "EventName": "PM_MRK_DATA_FROM_L3MISS_CYC", + "BriefDescription": "Duration in cycles to reload from a location other than the local core's L3 due to a marked load" + }, + {, + "EventCode": "0x1E052", + "EventName": "PM_CMPLU_STALL_SLB", + "BriefDescription": "Finish stall because the NTF instruction was awaiting L2 response for an SLB" + }, + {, + "EventCode": "0x4404C", + "EventName": "PM_INST_FROM_DMEM", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's memory on the same Node or Group (Distant) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3000E", + "EventName": "PM_FXU_1PLUS_BUSY", + "BriefDescription": "At least one of the 4 FXU units is busy" + }, + {, + "EventCode": "0x2C048", + "EventName": "PM_DATA_FROM_LMEM", + "BriefDescription": "The processor's data cache was reloaded from the local chip's Memory due to a demand load" + }, + {, + "EventCode": "0x3000A", + "EventName": "PM_CMPLU_STALL_PM", + "BriefDescription": "Finish stall because the NTF instruction was issued to the Permute execution pipe and waiting to finish. Includes permute and decimal fixed point instructions (128 bit BCD arithmetic) + a few 128 bit fixpoint add/subtract instructions with carry. Not qualified by vector or multicycle" + }, + {, + "EventCode": "0x1504E", + "EventName": "PM_IPTEG_FROM_L2MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L2 due to a instruction side request" + }, + {, + "EventCode": "0x1C052", + "EventName": "PM_DATA_GRP_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for a demand load" + }, + {, + "EventCode": "0x30008", + "EventName": "PM_DISP_STARVED", + "BriefDescription": "Dispatched Starved" + }, + {, + "EventCode": "0x14042", + "EventName": "PM_INST_FROM_L2", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4000C", + "EventName": "PM_FREQ_UP", + "BriefDescription": "Power Management: Above Threshold A" + }, + {, + "EventCode": "0x3C050", + "EventName": "PM_DATA_SYS_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was system pump (prediction=correct) for a demand load" + }, + {, + "EventCode": "0x25040", + "EventName": "PM_IPTEG_FROM_L2_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 hit without dispatch conflicts on Mepf state. due to a instruction side request" + }, + {, + "EventCode": "0x10132", + "EventName": "PM_MRK_INST_ISSUED", + "BriefDescription": "Marked instruction issued" + }, + {, + "EventCode": "0x1C046", + "EventName": "PM_DATA_FROM_L31_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x2C044", + "EventName": "PM_DATA_FROM_L31_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x2C04A", + "EventName": "PM_DATA_FROM_RL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on the same Node or Group ( Remote) due to a demand load" + }, + {, + "EventCode": "0x24044", + "EventName": "PM_INST_FROM_L31_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another core's L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4C050", + "EventName": "PM_DATA_SYS_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (system) ended up larger than Initial Pump Scope (Chip/Group) for a demand load" + }, + {, + "EventCode": "0x2C052", + "EventName": "PM_DATA_GRP_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (Group) ended up either larger or smaller than Initial Pump Scope for a demand load" + }, + {, + "EventCode": "0x2F148", + "EventName": "PM_MRK_DPTEG_FROM_LMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D01A", + "EventName": "PM_CMPLU_STALL_EIEIO", + "BriefDescription": "Finish stall because the NTF instruction is an EIEIO waiting for response from L2" + }, + {, + "EventCode": "0x4F14E", + "EventName": "PM_MRK_DPTEG_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L3 due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4F05A", + "EventName": "PM_RADIX_PWC_L4_PTE_FROM_L3", + "BriefDescription": "A Page Table Entry was reloaded to a level 4 page walk cache from the core's L3 data cache. This is the deepest level of PWC possible for a translation" + }, + {, + "EventCode": "0x1F05A", + "EventName": "PM_RADIX_PWC_L4_PTE_FROM_L2", + "BriefDescription": "A Page Table Entry was reloaded to a level 4 page walk cache from the core's L2 data cache. This is the deepest level of PWC possible for a translation" + }, + {, + "EventCode": "0x30068", + "EventName": "PM_L1_ICACHE_RELOADED_PREF", + "BriefDescription": "Counts all Icache prefetch reloads ( includes demand turned into prefetch)" + }, + {, + "EventCode": "0x4C04A", + "EventName": "PM_DATA_FROM_OFF_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a demand load" + }, + {, + "EventCode": "0x400FE", + "EventName": "PM_DATA_FROM_MEMORY", + "BriefDescription": "The processor's data cache was reloaded from a memory location including L4 from local remote or distant due to a demand load" + }, + {, + "EventCode": "0x3F058", + "EventName": "PM_RADIX_PWC_L1_PDE_FROM_L3", + "BriefDescription": "A Page Directory Entry was reloaded to a level 1 page walk cache from the core's L3 data cache" + }, + {, + "EventCode": "0x4D142", + "EventName": "PM_MRK_DATA_FROM_L3", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 due to a marked load" + }, + {, + "EventCode": "0x30050", + "EventName": "PM_SYS_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was system pump for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x30028", + "EventName": "PM_CMPLU_STALL_SPEC_FINISH", + "BriefDescription": "Finish stall while waiting for the non-speculative finish of either a stcx waiting for its result or a load waiting for non-critical sectors of data and ECC" + }, + {, + "EventCode": "0x400F4", + "EventName": "PM_RUN_PURR", + "BriefDescription": "Run_PURR" + }, + {, + "EventCode": "0x3404C", + "EventName": "PM_INST_FROM_DL4", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's L4 on a different Node or Group (Distant) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3D05A", + "EventName": "PM_NTC_ISSUE_HELD_OTHER", + "BriefDescription": "The NTC instruction is being held at dispatch during regular pipeline cycles, or because the VSU is busy with multi-cycle instructions, or because of a write-back collision with VSU" + }, + {, + "EventCode": "0x2E048", + "EventName": "PM_DPTEG_FROM_LMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2D02A", + "EventName": "PM_RADIX_PWC_L3_PDE_FROM_L2", + "BriefDescription": "A Page Directory Entry was reloaded to a level 3 page walk cache from the core's L2 data cache" + }, + {, + "EventCode": "0x1F05C", + "EventName": "PM_RADIX_PWC_L3_PDE_FROM_L3", + "BriefDescription": "A Page Directory Entry was reloaded to a level 3 page walk cache from the core's L3 data cache" + }, + {, + "EventCode": "0x4D04A", + "EventName": "PM_DARQ0_0_3_ENTRIES", + "BriefDescription": "Cycles in which 3 or less DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x1404C", + "EventName": "PM_INST_FROM_LL4", + "BriefDescription": "The processor's Instruction cache was reloaded from the local chip's L4 cache due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x200FD", + "EventName": "PM_L1_ICACHE_MISS", + "BriefDescription": "Demand iCache Miss" + }, + {, + "EventCode": "0x34040", + "EventName": "PM_INST_FROM_L2_DISP_CONFLICT_LDHITST", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 with load hit store conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x20138", + "EventName": "PM_MRK_ST_NEST", + "BriefDescription": "Marked store sent to nest" + }, + {, + "EventCode": "0x44048", + "EventName": "PM_INST_FROM_DL2L3_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x35046", + "EventName": "PM_IPTEG_FROM_L21_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L2 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x4C04E", + "EventName": "PM_DATA_FROM_L3MISS_MOD", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L3 due to a demand load" + }, + {, + "EventCode": "0x401E0", + "EventName": "PM_MRK_INST_CMPL", + "BriefDescription": "marked instruction completed" + }, + {, + "EventCode": "0x2C128", + "EventName": "PM_MRK_DATA_FROM_DL2L3_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0x34044", + "EventName": "PM_INST_FROM_L31_ECO_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another core's ECO L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4E018", + "EventName": "PM_CMPLU_STALL_NTC_DISP_FIN", + "BriefDescription": "Finish stall because the NTF instruction was one that must finish at dispatch." + }, + {, + "EventCode": "0x2E05E", + "EventName": "PM_LMQ_EMPTY_CYC", + "BriefDescription": "Cycles in which the LMQ has no pending load misses for this thread" + }, + {, + "EventCode": "0x4C122", + "EventName": "PM_DARQ1_0_3_ENTRIES", + "BriefDescription": "Cycles in which 3 or fewer DARQ1 entries (out of 12) are in use" + }, + {, + "EventCode": "0x4F058", + "EventName": "PM_RADIX_PWC_L2_PTE_FROM_L3", + "BriefDescription": "A Page Table Entry was reloaded to a level 2 page walk cache from the core's L3 data cache. This implies that level 3 and level 4 PWC accesses were not necessary for this translation" + }, + {, + "EventCode": "0x14046", + "EventName": "PM_INST_FROM_L31_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another core's L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3012C", + "EventName": "PM_MRK_ST_FWD", + "BriefDescription": "Marked st forwards" + }, + {, + "EventCode": "0x101E0", + "EventName": "PM_MRK_INST_DISP", + "BriefDescription": "The thread has dispatched a randomly sampled marked instruction" + }, + {, + "EventCode": "0x1D058", + "EventName": "PM_DARQ0_10_12_ENTRIES", + "BriefDescription": "Cycles in which 10 or more DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x300FE", + "EventName": "PM_DATA_FROM_L3MISS", + "BriefDescription": "Demand LD - L3 Miss (not L2 hit and not L3 hit)" + }, + {, + "EventCode": "0x30006", + "EventName": "PM_CMPLU_STALL_OTHER_CMPL", + "BriefDescription": "Instructions the core completed while this tread was stalled" + }, + {, + "EventCode": "0x1005C", + "EventName": "PM_CMPLU_STALL_DP", + "BriefDescription": "Finish stall because the NTF instruction was a scalar instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Not qualified multicycle. Qualified by NOT vector" + }, + {, + "EventCode": "0x1E042", + "EventName": "PM_DPTEG_FROM_L2", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1016E", + "EventName": "PM_MRK_BR_CMPL", + "BriefDescription": "Branch Instruction completed" + }, + {, + "EventCode": "0x2013A", + "EventName": "PM_MRK_BRU_FIN", + "BriefDescription": "bru marked instr finish" + }, + {, + "EventCode": "0x4F05E", + "EventName": "PM_RADIX_PWC_L3_PTE_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was reloaded to a level 3 page walk cache from beyond the core's L3 data cache. This implies that a level 4 PWC access was not necessary for this translation. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x400FC", + "EventName": "PM_ITLB_MISS", + "BriefDescription": "ITLB Reloaded. Counts 1 per ITLB miss for HPT but multiple for radix depending on number of levels traveresed" + }, + {, + "EventCode": "0x2D024", + "EventName": "PM_RADIX_PWC_L2_HIT", + "BriefDescription": "A radix translation attempt missed in the TLB but hit on both the first and second levels of page walk cache." + }, + {, + "EventCode": "0x3F056", + "EventName": "PM_RADIX_PWC_L3_HIT", + "BriefDescription": "A radix translation attempt missed in the TLB but hit on the first, second, and third levels of page walk cache." + }, + {, + "EventCode": "0x4E014", + "EventName": "PM_TM_TX_PASS_RUN_INST", + "BriefDescription": "Run instructions spent in successful transactions" + }, + {, + "EventCode": "0x1E044", + "EventName": "PM_DPTEG_FROM_L3_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without conflict due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D05A", + "EventName": "PM_NON_MATH_FLOP_CMPL", + "BriefDescription": "Non FLOP operation completed" + }, + {, + "EventCode": "0x101E2", + "EventName": "PM_MRK_BR_TAKEN_CMPL", + "BriefDescription": "Marked Branch Taken completed" + }, + {, + "EventCode": "0x3E158", + "EventName": "PM_MRK_STCX_FAIL", + "BriefDescription": "marked stcx failed" + }, + {, + "EventCode": "0x1C048", + "EventName": "PM_DATA_FROM_ON_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x1C054", + "EventName": "PM_DATA_PUMP_CPRED", + "BriefDescription": "Pump prediction correct. Counts across all types of pumps for a demand load" + }, + {, + "EventCode": "0x4405E", + "EventName": "PM_DARQ_STORE_REJECT", + "BriefDescription": "The DARQ attempted to transmit a store into an LSAQ or SRQ entry but It was rejected. Divide by PM_DARQ_STORE_XMIT to get reject ratio" + }, + {, + "EventCode": "0x1C042", + "EventName": "PM_DATA_FROM_L2", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 due to a demand load" + }, + {, + "EventCode": "0x1D14C", + "EventName": "PM_MRK_DATA_FROM_LL4", + "BriefDescription": "The processor's data cache was reloaded from the local chip's L4 cache due to a marked load" + }, + {, + "EventCode": "0x1006C", + "EventName": "PM_RUN_CYC_ST_MODE", + "BriefDescription": "Cycles run latch is set and core is in ST mode" + }, + {, + "EventCode": "0x3C044", + "EventName": "PM_DATA_FROM_L31_ECO_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's ECO L3 on the same chip due to a demand load" + }, + {, + "EventCode": "0x4C052", + "EventName": "PM_DATA_PUMP_MPRED", + "BriefDescription": "Pump misprediction. Counts across all types of pumps for a demand load" + }, + {, + "EventCode": "0x20050", + "EventName": "PM_GRP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope and data sourced across this scope was group pump for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x1F150", + "EventName": "PM_MRK_ST_L2DISP_TO_CMPL_CYC", + "BriefDescription": "cycles from L2 rc disp to l2 rc completion" + }, + {, + "EventCode": "0x4505A", + "EventName": "PM_SP_FLOP_CMPL", + "BriefDescription": "SP instruction completed" + }, + {, + "EventCode": "0x4000A", + "EventName": "PM_ISQ_36_44_ENTRIES", + "BriefDescription": "Cycles in which 36 or more Issue Queue entries are in use. This is a shared event, not per thread. There are 44 issue queue entries across 4 slices in the whole core" + }, + {, + "EventCode": "0x2C12E", + "EventName": "PM_MRK_DATA_FROM_LL4_CYC", + "BriefDescription": "Duration in cycles to reload from the local chip's L4 cache due to a marked load" + }, + {, + "EventCode": "0x2C058", + "EventName": "PM_MEM_PREF", + "BriefDescription": "Memory prefetch for this thread. Includes L4" + }, + {, + "EventCode": "0x40012", + "EventName": "PM_L1_ICACHE_RELOADED_ALL", + "BriefDescription": "Counts all Icache reloads includes demand, prefetch, prefetch turned into demand and demand turned into prefetch" + }, + {, + "EventCode": "0x4003C", + "EventName": "PM_DISP_HELD_SYNC_HOLD", + "BriefDescription": "Cycles in which dispatch is held because of a synchronizing instruction in the pipeline" + }, + {, + "EventCode": "0x3003C", + "EventName": "PM_CMPLU_STALL_NESTED_TEND", + "BriefDescription": "Completion stall because the ISU is updating the TEXASR to keep track of the nested tend and decrement the TEXASR nested level. This is a short delay" + }, + {, + "EventCode": "0x3D05C", + "EventName": "PM_DISP_HELD_HB_FULL", + "BriefDescription": "Dispatch held due to History Buffer full. Could be GPR/VSR/VMR/FPR/CR/XVF; CR; XVF (XER/VSCR/FPSCR)" + }, + {, + "EventCode": "0x30052", + "EventName": "PM_SYS_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (system) mispredicted. Either the original scope was too small (Chip/Group) or the original scope was System and it should have been smaller. Counts for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x2E044", + "EventName": "PM_DPTEG_FROM_L31_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x34048", + "EventName": "PM_INST_FROM_DL2L3_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x45042", + "EventName": "PM_IPTEG_FROM_L3", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 due to a instruction side request" + }, + {, + "EventCode": "0x15042", + "EventName": "PM_IPTEG_FROM_L2", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 due to a instruction side request" + }, + {, + "EventCode": "0x1C05E", + "EventName": "PM_MEM_LOC_THRESH_LSU_MED", + "BriefDescription": "Local memory above threshold for data prefetch" + }, + {, + "EventCode": "0x40134", + "EventName": "PM_MRK_INST_TIMEO", + "BriefDescription": "marked Instruction finish timeout (instruction lost)" + }, + {, + "EventCode": "0x1002C", + "EventName": "PM_L1_DCACHE_RELOADED_ALL", + "BriefDescription": "L1 data cache reloaded for demand. If MMCR1[16] is 1, prefetches will be included as well" + }, + {, + "EventCode": "0x30130", + "EventName": "PM_MRK_INST_FIN", + "BriefDescription": "marked instruction finished" + }, + {, + "EventCode": "0x1F14A", + "EventName": "PM_MRK_DPTEG_FROM_RL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3504E", + "EventName": "PM_DARQ0_4_6_ENTRIES", + "BriefDescription": "Cycles in which 4, 5, or 6 DARQ entries (out of 12) are in use" + }, + {, + "EventCode": "0x30064", + "EventName": "PM_DARQ_STORE_XMIT", + "BriefDescription": "The DARQ attempted to transmit a store into an LSAQ or SRQ entry. Includes rejects. Not qualified by thread, so it includes counts for the whole core" + }, + {, + "EventCode": "0x45046", + "EventName": "PM_IPTEG_FROM_L21_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L2 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x2C016", + "EventName": "PM_CMPLU_STALL_PASTE", + "BriefDescription": "Finish stall because the NTF instruction was a paste waiting for response from L2" + }, + {, + "EventCode": "0x24156", + "EventName": "PM_MRK_STCX_FIN", + "BriefDescription": "Number of marked stcx instructions finished. This includes instructions in the speculative path of a branch that may be flushed" + }, + {, + "EventCode": "0x15150", + "EventName": "PM_SYNC_MRK_PROBE_NOP", + "BriefDescription": "Marked probeNops which can cause synchronous interrupts" + }, + {, + "EventCode": "0x301E4", + "EventName": "PM_MRK_BR_MPRED_CMPL", + "BriefDescription": "Marked Branch Mispredicted" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/memory.json b/tools/perf/pmu-events/arch/powerpc/power9/memory.json new file mode 100644 index 000000000000..9960d1c0dd44 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/memory.json @@ -0,0 +1,132 @@ +[ + {, + "EventCode": "0x3006E", + "EventName": "PM_NEST_REF_CLK", + "BriefDescription": "Multiply by 4 to obtain the number of PB cycles" + }, + {, + "EventCode": "0x20010", + "EventName": "PM_PMC1_OVERFLOW", + "BriefDescription": "Overflow from counter 1" + }, + {, + "EventCode": "0x2005A", + "EventName": "PM_DARQ1_7_9_ENTRIES", + "BriefDescription": "Cycles in which 7 to 9 DARQ1 entries (out of 12) are in use" + }, + {, + "EventCode": "0x3C048", + "EventName": "PM_DATA_FROM_DL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a demand load" + }, + {, + "EventCode": "0x10008", + "EventName": "PM_RUN_SPURR", + "BriefDescription": "Run SPURR" + }, + {, + "EventCode": "0x200F6", + "EventName": "PM_LSU_DERAT_MISS", + "BriefDescription": "DERAT Reloaded due to a DERAT miss" + }, + {, + "EventCode": "0x4C048", + "EventName": "PM_DATA_FROM_DL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a demand load" + }, + {, + "EventCode": "0x1D15E", + "EventName": "PM_MRK_RUN_CYC", + "BriefDescription": "Run cycles in which a marked instruction is in the pipeline" + }, + {, + "EventCode": "0x4003E", + "EventName": "PM_LD_CMPL", + "BriefDescription": "count of Loads completed" + }, + {, + "EventCode": "0x2D156", + "EventName": "PM_MRK_DTLB_MISS_4K", + "BriefDescription": "Marked Data TLB Miss page size 4k" + }, + {, + "EventCode": "0x4C042", + "EventName": "PM_DATA_FROM_L3", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 due to a demand load" + }, + {, + "EventCode": "0x4D02C", + "EventName": "PM_PMC1_REWIND", + "BriefDescription": "" + }, + {, + "EventCode": "0x15158", + "EventName": "PM_SYNC_MRK_L2HIT", + "BriefDescription": "Marked L2 Hits that can throw a synchronous interrupt" + }, + {, + "EventCode": "0x3404A", + "EventName": "PM_INST_FROM_RMEM", + "BriefDescription": "The processor's Instruction cache was reloaded from another chip's memory on the same Node or Group ( Remote) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x301E2", + "EventName": "PM_MRK_ST_CMPL", + "BriefDescription": "Marked store completed and sent to nest" + }, + {, + "EventCode": "0x1C050", + "EventName": "PM_DATA_CHIP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was chip pump (prediction=correct) for a demand load" + }, + {, + "EventCode": "0x4C040", + "EventName": "PM_DATA_FROM_L2_DISP_CONFLICT_OTHER", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with dispatch conflict due to a demand load" + }, + {, + "EventCode": "0x2E05C", + "EventName": "PM_LSU_REJECT_ERAT_MISS", + "BriefDescription": "LSU Reject due to ERAT (up to 4 per cycles)" + }, + {, + "EventCode": "0x1000A", + "EventName": "PM_PMC3_REWIND", + "BriefDescription": "PMC3 rewind event. A rewind happens when a speculative event (such as latency or CPI stack) is selected on PMC3 and the stall reason or reload source did not match the one programmed in PMC3. When this occurs, the count in PMC3 will not change." + }, + {, + "EventCode": "0x3C058", + "EventName": "PM_LARX_FIN", + "BriefDescription": "Larx finished" + }, + {, + "EventCode": "0x1C040", + "EventName": "PM_DATA_FROM_L2_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 without conflict due to a demand load" + }, + {, + "EventCode": "0x2C040", + "EventName": "PM_DATA_FROM_L2_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 hit without dispatch conflicts on Mepf state due to a demand load" + }, + {, + "EventCode": "0x2E05A", + "EventName": "PM_LRQ_REJECT", + "BriefDescription": "Internal LSU reject from LRQ. Rejects cause the load to go back to LRQ, but it stays contained within the LSU once it gets issued. This event counts the number of times the LRQ attempts to relaunch an instruction after a reject. Any load can suffer multiple rejects" + }, + {, + "EventCode": "0x2C05C", + "EventName": "PM_INST_GRP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was group pump (prediction=correct) for an instruction fetch (demand only)" + }, + {, + "EventCode": "0x4D056", + "EventName": "PM_NON_FMA_FLOP_CMPL", + "BriefDescription": "Non FMA instruction completed" + }, + {, + "EventCode": "0x3E050", + "EventName": "PM_DARQ1_4_6_ENTRIES", + "BriefDescription": "Cycles in which 4, 5, or 6 DARQ1 entries (out of 12) are in use" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/powerpc/power9/other.json b/tools/perf/pmu-events/arch/powerpc/power9/other.json new file mode 100644 index 000000000000..54cc3be00fc2 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/other.json @@ -0,0 +1,2392 @@ +[ + {, + "EventCode": "0x3084", + "EventName": "PM_ISU1_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0xF880", + "EventName": "PM_SNOOP_TLBIE", + "BriefDescription": "TLBIE snoop" + }, + {, + "EventCode": "0x4088", + "EventName": "PM_IC_DEMAND_REQ", + "BriefDescription": "Demand Instruction fetch request" + }, + {, + "EventCode": "0x20A4", + "EventName": "PM_TM_TRESUME", + "BriefDescription": "TM resume instruction completed" + }, + {, + "EventCode": "0x40008", + "EventName": "PM_SRQ_EMPTY_CYC", + "BriefDescription": "Cycles in which the SRQ has at least one (out of four) empty slice" + }, + {, + "EventCode": "0x20064", + "EventName": "PM_IERAT_RELOAD_4K", + "BriefDescription": "IERAT reloaded (after a miss) for 4K pages" + }, + {, + "EventCode": "0x260B4", + "EventName": "PM_L3_P2_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 2 (can try 4 times)" + }, + {, + "EventCode": "0x20006", + "EventName": "PM_DISP_HELD_ISSQ_FULL", + "BriefDescription": "Dispatch held due to Issue q full. Includes issue queue and branch queue" + }, + {, + "EventCode": "0x201E4", + "EventName": "PM_MRK_DATA_FROM_L3MISS", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L3 due to a marked load" + }, + {, + "EventCode": "0x4E044", + "EventName": "PM_DPTEG_FROM_L31_ECO_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's ECO L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40B8", + "EventName": "PM_BR_MPRED_TAKEN_CR", + "BriefDescription": "A Conditional Branch that resolved to taken was mispredicted as not taken (due to the BHT Direction Prediction)." + }, + {, + "EventCode": "0xF8AC", + "EventName": "PM_DC_DEALLOC_NO_CONF", + "BriefDescription": "A demand load referenced a line in an active fuzzy prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software.Fuzzy stream confirm (out of order effects, or pf cant keep up)" + }, + {, + "EventCode": "0xD090", + "EventName": "PM_LS0_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x40BC", + "EventName": "PM_THRD_PRIO_0_1_CYC", + "BriefDescription": "Cycles thread running at priority level 0 or 1" + }, + {, + "EventCode": "0x2084", + "EventName": "PM_FLUSH_HB_RESTORE_CYC", + "BriefDescription": "Cycles in which no new instructions can be dispatched to the ICT after a flush. History buffer recovery" + }, + {, + "EventCode": "0x4F054", + "EventName": "PM_RADIX_PWC_MISS", + "BriefDescription": "A radix translation attempt missed in the TLB and all levels of page walk cache." + }, + {, + "EventCode": "0x24048", + "EventName": "PM_INST_FROM_LMEM", + "BriefDescription": "The processor's Instruction cache was reloaded from the local chip's Memory due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0xD8B4", + "EventName": "PM_LSU0_LRQ_S0_VALID_CYC", + "BriefDescription": "Slot 0 of LRQ valid" + }, + {, + "EventCode": "0x2E052", + "EventName": "PM_TM_PASSED", + "BriefDescription": "Number of TM transactions that passed" + }, + {, + "EventCode": "0xD1A0", + "EventName": "PM_MRK_LSU_FLUSH_LHS", + "BriefDescription": "Effective Address alias flush : no EA match but Real Address match. If the data has not yet been returned for this load, the instruction will just be rejected, but if it has returned data, it will be flushed" + }, + {, + "EventCode": "0xF088", + "EventName": "PM_LSU0_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x360B2", + "EventName": "PM_L3_GRP_GUESS_WRONG_LOW", + "BriefDescription": "Initial scope=group (GS or NNS) but data from outside group (far or rem). Prediction too Low" + }, + {, + "EventCode": "0x168A6", + "EventName": "PM_TM_CAM_OVERFLOW", + "BriefDescription": "L3 TM cam overflow during L2 co of SC" + }, + {, + "EventCode": "0xE8B0", + "EventName": "PM_TEND_PEND_CYC", + "BriefDescription": "TEND latency per thread" + }, + {, + "EventCode": "0x4884", + "EventName": "PM_IBUF_FULL_CYC", + "BriefDescription": "Cycles No room in ibuff" + }, + {, + "EventCode": "0xD08C", + "EventName": "PM_LSU2_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])" + }, + {, + "EventCode": "0x300F8", + "EventName": "PM_TB_BIT_TRANS", + "BriefDescription": "timebase event" + }, + {, + "EventCode": "0x3C040", + "EventName": "PM_DATA_FROM_L2_DISP_CONFLICT_LDHITST", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with load hit store conflict due to a demand load" + }, + {, + "EventCode": "0xE0BC", + "EventName": "PM_LS0_PTE_TABLEWALK_CYC", + "BriefDescription": "Cycles when a tablewalk is pending on this thread on table 0" + }, + {, + "EventCode": "0x3884", + "EventName": "PM_ISU3_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0x460A6", + "EventName": "PM_RD_FORMING_SC", + "BriefDescription": "Read forming SC" + }, + {, + "EventCode": "0x468A0", + "EventName": "PM_L3_PF_OFF_CHIP_MEM", + "BriefDescription": "L3 PF from Off chip memory" + }, + {, + "EventCode": "0x268AA", + "EventName": "PM_L3_P1_LCO_DATA", + "BriefDescription": "LCO sent with data port 1" + }, + {, + "EventCode": "0xE894", + "EventName": "PM_LSU1_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x5888", + "EventName": "PM_IC_INVALIDATE", + "BriefDescription": "Ic line invalidated" + }, + {, + "EventCode": "0x2890", + "EventName": "PM_DISP_CLB_HELD_TLBIE", + "BriefDescription": "Dispatch Hold: Due to TLBIE" + }, + {, + "EventCode": "0x1001C", + "EventName": "PM_CMPLU_STALL_THRD", + "BriefDescription": "Completion Stalled because the thread was blocked" + }, + {, + "EventCode": "0x368A6", + "EventName": "PM_SNP_TM_HIT_T", + "BriefDescription": "Snp TM sthit T/Tn/Te" + }, + {, + "EventCode": "0x3001A", + "EventName": "PM_DATA_TABLEWALK_CYC", + "BriefDescription": "Data Tablewalk Cycles. Could be 1 or 2 active tablewalks. Includes data prefetches." + }, + {, + "EventCode": "0xD894", + "EventName": "PM_LS3_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x35158", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0xF0B4", + "EventName": "PM_DC_PREF_CONS_ALLOC", + "BriefDescription": "Prefetch stream allocated in the conservative phase by either the hardware prefetch mechanism or software prefetch" + }, + {, + "EventCode": "0xF894", + "EventName": "PM_LSU3_L1_CAM_CANCEL", + "BriefDescription": "ls3 l1 tm cam cancel" + }, + {, + "EventCode": "0x2888", + "EventName": "PM_FLUSH_DISP_TLBIE", + "BriefDescription": "Dispatch Flush: TLBIE" + }, + {, + "EventCode": "0xD1A4", + "EventName": "PM_MRK_LSU_FLUSH_SAO", + "BriefDescription": "A load-hit-load condition with Strong Address Ordering will have address compare disabled and flush" + }, + {, + "EventCode": "0x4E11E", + "EventName": "PM_MRK_DATA_FROM_DMEM_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's memory on the same Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x5894", + "EventName": "PM_LWSYNC", + "BriefDescription": "Lwsync instruction decoded and transferred" + }, + {, + "EventCode": "0x14156", + "EventName": "PM_MRK_DATA_FROM_L2_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 due to a marked load" + }, + {, + "EventCode": "0x468A6", + "EventName": "PM_RD_CLEARING_SC", + "BriefDescription": "Read clearing SC" + }, + {, + "EventCode": "0x50A0", + "EventName": "PM_HWSYNC", + "BriefDescription": "Hwsync instruction decoded and transferred" + }, + {, + "EventCode": "0x168B0", + "EventName": "PM_L3_P1_NODE_PUMP", + "BriefDescription": "L3 PF sent with nodal scope port 1, counts even retried requests" + }, + {, + "EventCode": "0xD0BC", + "EventName": "PM_LSU0_1_LRQF_FULL_CYC", + "BriefDescription": "Counts the number of cycles the LRQF is full. LRQF is the queue that holds loads between finish and completion. If it fills up, instructions stay in LRQ until completion, potentially backing up the LRQ" + }, + {, + "EventCode": "0x2D148", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_LDHITST", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 with load hit store conflict due to a marked load" + }, + {, + "EventCode": "0x460A8", + "EventName": "PM_SN_HIT", + "BriefDescription": "Any port snooper hit L3. Up to 4 can happen in a cycle but we only count 1" + }, + {, + "EventCode": "0x360AA", + "EventName": "PM_L3_P0_CO_MEM", + "BriefDescription": "L3 CO to memory port 0 with or without data" + }, + {, + "EventCode": "0xF0A4", + "EventName": "PM_DC_PREF_HW_ALLOC", + "BriefDescription": "Prefetch stream allocated by the hardware prefetch mechanism" + }, + {, + "EventCode": "0xF0BC", + "EventName": "PM_LS2_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0xD0AC", + "EventName": "PM_SRQ_SYNC_CYC", + "BriefDescription": "A sync is in the S2Q (edge detect to count)" + }, + {, + "EventCode": "0x401E6", + "EventName": "PM_MRK_INST_FROM_L3MISS", + "BriefDescription": "Marked instruction was reloaded from a location beyond the local chiplet" + }, + {, + "EventCode": "0x26082", + "EventName": "PM_L2_IC_INV", + "BriefDescription": "I-cache Invalidates sent over the realod bus to the core" + }, + {, + "EventCode": "0xC8AC", + "EventName": "PM_LSU_FLUSH_RELAUNCH_MISS", + "BriefDescription": "If a load that has already returned data and has to relaunch for any reason then gets a miss (erat, setp, data cache), it will often be flushed at relaunch time because the data might be inconsistent" + }, + {, + "EventCode": "0x260A4", + "EventName": "PM_L3_LD_HIT", + "BriefDescription": "L3 Hits for demand LDs" + }, + {, + "EventCode": "0xF0A0", + "EventName": "PM_DATA_STORE", + "BriefDescription": "All ops that drain from s2q to L2 containing data" + }, + {, + "EventCode": "0x1D148", + "EventName": "PM_MRK_DATA_FROM_RMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x16088", + "EventName": "PM_L2_LOC_GUESS_CORRECT", + "BriefDescription": "L2 guess local (LNS) and guess was correct (ie data local)" + }, + {, + "EventCode": "0x160A4", + "EventName": "PM_L3_HIT", + "BriefDescription": "L3 Hits (L2 miss hitting L3, including data/instrn/xlate)" + }, + {, + "EventCode": "0xE09C", + "EventName": "PM_LSU0_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x168B4", + "EventName": "PM_L3_P1_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 1 (can try 4 times)" + }, + {, + "EventCode": "0x268AC", + "EventName": "PM_L3_RD_USAGE", + "BriefDescription": "Rotating sample of 16 RD actives" + }, + {, + "EventCode": "0x1415C", + "EventName": "PM_MRK_DATA_FROM_L3_MEPF_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 without dispatch conflicts hit on Mepf state due to a marked load" + }, + {, + "EventCode": "0xE880", + "EventName": "PM_L1_SW_PREF", + "BriefDescription": "Software L1 Prefetches, including SW Transient Prefetches" + }, + {, + "EventCode": "0x288C", + "EventName": "PM_DISP_CLB_HELD_BAL", + "BriefDescription": "Dispatch/CLB Hold: Balance Flush" + }, + {, + "EventCode": "0x101EA", + "EventName": "PM_MRK_L1_RELOAD_VALID", + "BriefDescription": "Marked demand reload" + }, + {, + "EventCode": "0x1D156", + "EventName": "PM_MRK_LD_MISS_L1_CYC", + "BriefDescription": "Marked ld latency" + }, + {, + "EventCode": "0x4C01A", + "EventName": "PM_CMPLU_STALL_DMISS_L3MISS", + "BriefDescription": "Completion stall due to cache miss resolving missed the L3" + }, + {, + "EventCode": "0x2006C", + "EventName": "PM_RUN_CYC_SMT4_MODE", + "BriefDescription": "Cycles in which this thread's run latch is set and the core is in SMT4 mode" + }, + {, + "EventCode": "0x5088", + "EventName": "PM_DECODE_FUSION_OP_PRESERV", + "BriefDescription": "Destructive op operand preservation" + }, + {, + "EventCode": "0x1D14E", + "EventName": "PM_MRK_DATA_FROM_OFF_CHIP_CACHE_CYC", + "BriefDescription": "Duration in cycles to reload either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a marked load" + }, + {, + "EventCode": "0x509C", + "EventName": "PM_FORCED_NOP", + "BriefDescription": "Instruction was forced to execute as a nop because it was found to behave like a nop (have no effect) at decode time" + }, + {, + "EventCode": "0xC098", + "EventName": "PM_LS2_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x20058", + "EventName": "PM_DARQ1_10_12_ENTRIES", + "BriefDescription": "Cycles in which 10 or more DARQ1 entries (out of 12) are in use" + }, + {, + "EventCode": "0x360A6", + "EventName": "PM_SNP_TM_HIT_M", + "BriefDescription": "Snp TM st hit M/Mu" + }, + {, + "EventCode": "0x5898", + "EventName": "PM_LINK_STACK_INVALID_PTR", + "BriefDescription": "It is most often caused by certain types of flush where the pointer is not available. Can result in the data in the link stack becoming unusable." + }, + {, + "EventCode": "0x46088", + "EventName": "PM_L2_CHIP_PUMP", + "BriefDescription": "RC requests that were local (aka chip) pump attempts" + }, + {, + "EventCode": "0x28A0", + "EventName": "PM_TM_TSUSPEND", + "BriefDescription": "TM suspend instruction completed" + }, + {, + "EventCode": "0x20054", + "EventName": "PM_L1_PREF", + "BriefDescription": "A data line was written to the L1 due to a hardware or software prefetch" + }, + {, + "EventCode": "0xF888", + "EventName": "PM_LSU1_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x4505E", + "EventName": "PM_FLOP_CMPL", + "BriefDescription": "Floating Point Operation Finished" + }, + {, + "EventCode": "0x1D144", + "EventName": "PM_MRK_DATA_FROM_L3_DISP_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0x400FA", + "EventName": "PM_RUN_INST_CMPL", + "BriefDescription": "Run_Instructions" + }, + {, + "EventCode": "0x15154", + "EventName": "PM_SYNC_MRK_L3MISS", + "BriefDescription": "Marked L3 misses that can throw a synchronous interrupt" + }, + {, + "EventCode": "0xE0B4", + "EventName": "PM_LS0_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x26884", + "EventName": "PM_DSIDE_MRU_TOUCH", + "BriefDescription": "D-side L2 MRU touch sent to L2" + }, + {, + "EventCode": "0x30134", + "EventName": "PM_MRK_ST_CMPL_INT", + "BriefDescription": "marked store finished with intervention" + }, + {, + "EventCode": "0xC0B8", + "EventName": "PM_LSU_FLUSH_SAO", + "BriefDescription": "A load-hit-load condition with Strong Address Ordering will have address compare disabled and flush" + }, + {, + "EventCode": "0x50A8", + "EventName": "PM_EAT_FORCE_MISPRED", + "BriefDescription": "XL-form branch was mispredicted due to the predicted target address missing from EAT. The EAT forces a mispredict in this case since there is no predicated target to validate. This is a rare case that may occur when the EAT is full and a branch is issued" + }, + {, + "EventCode": "0xC094", + "EventName": "PM_LS0_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0xF8BC", + "EventName": "PM_LS3_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x58B0", + "EventName": "PM_BTAC_GOOD_RESULT", + "BriefDescription": "BTAC predicts a taken branch and the BHT agrees, and the target address is correct" + }, + {, + "EventCode": "0x1C04C", + "EventName": "PM_DATA_FROM_LL4", + "BriefDescription": "The processor's data cache was reloaded from the local chip's L4 cache due to a demand load" + }, + {, + "EventCode": "0x3608E", + "EventName": "PM_TM_ST_CONF", + "BriefDescription": "TM Store (fav or non-fav) ran into conflict (failed)" + }, + {, + "EventCode": "0xD998", + "EventName": "PM_MRK_LSU_FLUSH_EMSH", + "BriefDescription": "An ERAT miss was detected after a set-p hit. Erat tracker indicates fail due to tlbmiss and the instruction gets flushed because the instruction was working on the wrong address" + }, + {, + "EventCode": "0xF8A0", + "EventName": "PM_NON_DATA_STORE", + "BriefDescription": "All ops that drain from s2q to L2 and contain no data" + }, + {, + "EventCode": "0x3F146", + "EventName": "PM_MRK_DPTEG_FROM_L21_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L2 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40A0", + "EventName": "PM_BR_UNCOND", + "BriefDescription": "Unconditional Branch Completed. HW branch prediction was not used for this branch. This can be an I-form branch, a B-form branch with BO-field set to branch always, or a B-form branch which was covenrted to a Resolve." + }, + {, + "EventCode": "0x1F056", + "EventName": "PM_RADIX_PWC_L1_HIT", + "BriefDescription": "A radix translation attempt missed in the TLB and only the first level page walk cache was a hit." + }, + {, + "EventCode": "0xF8A8", + "EventName": "PM_DC_PREF_FUZZY_CONF", + "BriefDescription": "A demand load referenced a line in an active fuzzy prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software.Fuzzy stream confirm (out of order effects, or pf cant keep up)" + }, + {, + "EventCode": "0xF8A4", + "EventName": "PM_DC_PREF_SW_ALLOC", + "BriefDescription": "Prefetch stream allocated by software prefetching" + }, + {, + "EventCode": "0xE0A0", + "EventName": "PM_LSU2_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x2894", + "EventName": "PM_TM_OUTER_TEND", + "BriefDescription": "Completion time outer tend" + }, + {, + "EventCode": "0xF098", + "EventName": "PM_XLATE_HPT_MODE", + "BriefDescription": "LSU reports every cycle the thread is in HPT translation mode (as opposed to radix mode)" + }, + {, + "EventCode": "0x2C04E", + "EventName": "PM_LD_MISS_L1_FIN", + "BriefDescription": "Number of load instructions that finished with an L1 miss. Note that even if a load spans multiple slices this event will increment only once per load op." + }, + {, + "EventCode": "0x30162", + "EventName": "PM_MRK_LSU_DERAT_MISS", + "BriefDescription": "Marked derat reload (miss) for any page size" + }, + {, + "EventCode": "0x160A0", + "EventName": "PM_L3_PF_MISS_L3", + "BriefDescription": "L3 PF missed in L3" + }, + {, + "EventCode": "0x1C04A", + "EventName": "PM_DATA_FROM_RL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a demand load" + }, + {, + "EventCode": "0xD99C", + "EventName": "PM_MRK_LSU_FLUSH_UE", + "BriefDescription": "Correctable ECC error on reload data, reported at critical data forward time" + }, + {, + "EventCode": "0x268B0", + "EventName": "PM_L3_P1_GRP_PUMP", + "BriefDescription": "L3 PF sent with grp scope port 1, counts even retried requests" + }, + {, + "EventCode": "0x30016", + "EventName": "PM_CMPLU_STALL_SRQ_FULL", + "BriefDescription": "Finish stall because the NTF instruction was a store that was held in LSAQ because the SRQ was full" + }, + {, + "EventCode": "0x40B4", + "EventName": "PM_BR_PRED_TA", + "BriefDescription": "Conditional Branch Completed that had its target address predicted. Only XL-form branches set this event. This equal the sum of CCACHE, LSTACK, and PCACHE" + }, + {, + "EventCode": "0x40AC", + "EventName": "PM_BR_MPRED_CCACHE", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to the Count Cache Target Prediction" + }, + {, + "EventCode": "0x3688A", + "EventName": "PM_L2_RTY_LD", + "BriefDescription": "RC retries on PB for any load from core (excludes DCBFs)" + }, + {, + "EventCode": "0xE08C", + "EventName": "PM_LSU0_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0xE088", + "EventName": "PM_LS2_ERAT_MISS_PREF", + "BriefDescription": "LS0 Erat miss due to prefetch" + }, + {, + "EventCode": "0xF0A8", + "EventName": "PM_DC_PREF_CONF", + "BriefDescription": "A demand load referenced a line in an active prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software. Includes forwards and backwards streams" + }, + {, + "EventCode": "0x16888", + "EventName": "PM_L2_LOC_GUESS_WRONG", + "BriefDescription": "L2 guess local (LNS) and guess was not correct (ie data not on chip)" + }, + {, + "EventCode": "0xE0A4", + "EventName": "PM_TMA_REQ_L2", + "BriefDescription": "addrs only req to L2 only on the first one,Indication that Load footprint is not expanding" + }, + {, + "EventCode": "0x5884", + "EventName": "PM_DECODE_LANES_NOT_AVAIL", + "BriefDescription": "Decode has something to transmit but dispatch lanes are not available" + }, + {, + "EventCode": "0x3C042", + "EventName": "PM_DATA_FROM_L3_DISP_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 with dispatch conflict due to a demand load" + }, + {, + "EventCode": "0x168AA", + "EventName": "PM_L3_P1_LCO_NO_DATA", + "BriefDescription": "Dataless L3 LCO sent port 1" + }, + {, + "EventCode": "0x3D140", + "EventName": "PM_MRK_DATA_FROM_L2_DISP_CONFLICT_OTHER_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0xC89C", + "EventName": "PM_LS1_LAUNCH_HELD_PREF", + "BriefDescription": "Number of times a load or store instruction was unable to launch/relaunch because a high priority prefetch used that relaunch cycle" + }, + {, + "EventCode": "0x4894", + "EventName": "PM_IC_RELOAD_PRIVATE", + "BriefDescription": "Reloading line was brought in private for a specific thread. Most lines are brought in shared for all eight threads. If RA does not match then invalidates and then brings it shared to other thread. In P7 line brought in private , then line was invalidat" + }, + {, + "EventCode": "0x1688E", + "EventName": "PM_TM_LD_CAUSED_FAIL", + "BriefDescription": "Non-TM Load caused any thread to fail" + }, + {, + "EventCode": "0x26084", + "EventName": "PM_L2_RCLD_DISP_FAIL_OTHER", + "BriefDescription": "All I-or-D side load dispatch attempts for this thread that failed due to reason other than address collision (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x101E4", + "EventName": "PM_MRK_L1_ICACHE_MISS", + "BriefDescription": "sampled Instruction suffered an icache Miss" + }, + {, + "EventCode": "0x20A0", + "EventName": "PM_TM_NESTED_TBEGIN", + "BriefDescription": "Completion Tm nested tbegin" + }, + {, + "EventCode": "0x368AA", + "EventName": "PM_L3_P1_CO_MEM", + "BriefDescription": "L3 CO to memory port 1 with or without data" + }, + {, + "EventCode": "0xC8A4", + "EventName": "PM_LSU3_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0xD9A4", + "EventName": "PM_MRK_LSU_FLUSH_LARX_STCX", + "BriefDescription": "A larx is flushed because an older larx has an LMQ reservation for the same thread. A stcx is flushed because an older stcx is in the LMQ. The flush happens when the older larx/stcx relaunches" + }, + {, + "EventCode": "0x4D012", + "EventName": "PM_PMC3_SAVED", + "BriefDescription": "PMC3 Rewind Value saved" + }, + {, + "EventCode": "0xE888", + "EventName": "PM_LS3_ERAT_MISS_PREF", + "BriefDescription": "LS1 Erat miss due to prefetch" + }, + {, + "EventCode": "0x368B4", + "EventName": "PM_L3_RD0_BUSY", + "BriefDescription": "Lifetime, sample of RD machine 0 valid" + }, + {, + "EventCode": "0x46080", + "EventName": "PM_L2_DISP_ALL_L2MISS", + "BriefDescription": "All successful Ld/St dispatches for this thread that were an L2 miss (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0xF8B8", + "EventName": "PM_LS1_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x408C", + "EventName": "PM_L1_DEMAND_WRITE", + "BriefDescription": "Instruction Demand sectors written into IL1" + }, + {, + "EventCode": "0x368A8", + "EventName": "PM_SN_INVL", + "BriefDescription": "Any port snooper detects a store to a line in the Sx state and invalidates the line. Up to 4 can happen in a cycle but we only count 1" + }, + {, + "EventCode": "0x160B2", + "EventName": "PM_L3_LOC_GUESS_CORRECT", + "BriefDescription": "initial scope=node/chip (LNS) and data from local node (local) (pred successful) - always PFs only" + }, + {, + "EventCode": "0x48B4", + "EventName": "PM_DECODE_FUSION_CONST_GEN", + "BriefDescription": "32-bit constant generation" + }, + {, + "EventCode": "0x4D146", + "EventName": "PM_MRK_DATA_FROM_L21_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L2 on the same chip due to a marked load" + }, + {, + "EventCode": "0xE080", + "EventName": "PM_S2Q_FULL", + "BriefDescription": "Cycles during which the S2Q is full" + }, + {, + "EventCode": "0x268B4", + "EventName": "PM_L3_P3_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 3 (can try 4 times)" + }, + {, + "EventCode": "0xD8B8", + "EventName": "PM_LSU0_LMQ_S0_VALID", + "BriefDescription": "Slot 0 of LMQ valid" + }, + {, + "EventCode": "0x2098", + "EventName": "PM_TM_NESTED_TEND", + "BriefDescription": "Completion time nested tend" + }, + {, + "EventCode": "0x36084", + "EventName": "PM_L2_RCST_DISP", + "BriefDescription": "All D-side store dispatch attempts for this thread" + }, + {, + "EventCode": "0x368A0", + "EventName": "PM_L3_PF_OFF_CHIP_CACHE", + "BriefDescription": "L3 PF from Off chip cache" + }, + {, + "EventCode": "0x20056", + "EventName": "PM_TAKEN_BR_MPRED_CMPL", + "BriefDescription": "Total number of taken branches that were incorrectly predicted as not-taken. This event counts branches completed and does not include speculative instructions" + }, + {, + "EventCode": "0x4688A", + "EventName": "PM_L2_SYS_PUMP", + "BriefDescription": "RC requests that were system pump attempts" + }, + {, + "EventCode": "0xE090", + "EventName": "PM_LSU2_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0x4001C", + "EventName": "PM_INST_IMC_MATCH_CMPL", + "BriefDescription": "IMC Match Count" + }, + {, + "EventCode": "0x40A8", + "EventName": "PM_BR_PRED_LSTACK", + "BriefDescription": "Conditional Branch Completed that used the Link Stack for Target Prediction" + }, + {, + "EventCode": "0x268A2", + "EventName": "PM_L3_CI_MISS", + "BriefDescription": "L3 castins miss (total count)" + }, + {, + "EventCode": "0x289C", + "EventName": "PM_TM_NON_FAV_TBEGIN", + "BriefDescription": "Dispatch time non favored tbegin" + }, + {, + "EventCode": "0xF08C", + "EventName": "PM_LSU2_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x360A0", + "EventName": "PM_L3_PF_ON_CHIP_CACHE", + "BriefDescription": "L3 PF from On chip cache" + }, + {, + "EventCode": "0x35152", + "EventName": "PM_MRK_DATA_FROM_L2MISS_CYC", + "BriefDescription": "Duration in cycles to reload from a location other than the local core's L2 due to a marked load" + }, + {, + "EventCode": "0x160AC", + "EventName": "PM_L3_SN_USAGE", + "BriefDescription": "Rotating sample of 16 snoop valids" + }, + {, + "EventCode": "0x16084", + "EventName": "PM_L2_RCLD_DISP", + "BriefDescription": "All I-or-D side load dispatch attempts for this thread (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x1608C", + "EventName": "PM_RC0_BUSY", + "BriefDescription": "RC mach 0 Busy. Used by PMU to sample ave RC lifetime (mach0 used as sample point)" + }, + {, + "EventCode": "0x36082", + "EventName": "PM_L2_LD_DISP", + "BriefDescription": "All successful I-or-D side load dispatches for this thread (excludes i_l2mru_tch_reqs)." + }, + {, + "EventCode": "0xF8B0", + "EventName": "PM_L3_SW_PREF", + "BriefDescription": "L3 load prefetch, sourced from a software prefetch stream, was sent to the nest" + }, + {, + "EventCode": "0xF884", + "EventName": "PM_TABLEWALK_CYC_PREF", + "BriefDescription": "tablewalk qualified for pte prefetches" + }, + {, + "EventCode": "0x4D144", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x16884", + "EventName": "PM_L2_RCLD_DISP_FAIL_ADDR", + "BriefDescription": "All I-od-D side load dispatch attempts for this thread that failed due to address collision with RC/CO/SN/SQ machine (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x460A0", + "EventName": "PM_L3_PF_ON_CHIP_MEM", + "BriefDescription": "L3 PF from On chip memory" + }, + {, + "EventCode": "0xF084", + "EventName": "PM_PTE_PREFETCH", + "BriefDescription": "PTE prefetches" + }, + {, + "EventCode": "0x2D026", + "EventName": "PM_RADIX_PWC_L1_PDE_FROM_L2", + "BriefDescription": "A Page Directory Entry was reloaded to a level 1 page walk cache from the core's L2 data cache" + }, + {, + "EventCode": "0x48B0", + "EventName": "PM_BR_MPRED_PCACHE", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to pattern cache prediction" + }, + {, + "EventCode": "0x2C126", + "EventName": "PM_MRK_DATA_FROM_L2", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 due to a marked load" + }, + {, + "EventCode": "0xE0AC", + "EventName": "PM_TM_FAIL_TLBIE", + "BriefDescription": "Transaction failed because there was a TLBIE hit in the bloom filter" + }, + {, + "EventCode": "0x260AA", + "EventName": "PM_L3_P0_LCO_DATA", + "BriefDescription": "LCO sent with data port 0" + }, + {, + "EventCode": "0x4888", + "EventName": "PM_IC_PREF_REQ", + "BriefDescription": "Instruction prefetch requests" + }, + {, + "EventCode": "0xC898", + "EventName": "PM_LS3_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x488C", + "EventName": "PM_IC_PREF_WRITE", + "BriefDescription": "Instruction prefetch written into IL1" + }, + {, + "EventCode": "0xF89C", + "EventName": "PM_XLATE_MISS", + "BriefDescription": "The LSU requested a line from L2 for translation. It may be satisfied from any source beyond L2. Includes speculative instructions" + }, + {, + "EventCode": "0x14158", + "EventName": "PM_MRK_DATA_FROM_L2_NO_CONFLICT_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 without conflict due to a marked load" + }, + {, + "EventCode": "0x35156", + "EventName": "PM_MRK_DATA_FROM_L31_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x268A6", + "EventName": "PM_TM_RST_SC", + "BriefDescription": "TM-snp rst RM SC" + }, + {, + "EventCode": "0x468A4", + "EventName": "PM_L3_TRANS_PF", + "BriefDescription": "L3 Transient prefetch received from L2" + }, + {, + "EventCode": "0x4094", + "EventName": "PM_IC_PREF_CANCEL_L2", + "BriefDescription": "L2 Squashed a demand or prefetch request" + }, + {, + "EventCode": "0x48AC", + "EventName": "PM_BR_MPRED_LSTACK", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to the Link Stack Target Prediction" + }, + {, + "EventCode": "0xE88C", + "EventName": "PM_LSU1_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0xC0B4", + "EventName": "PM_LSU_FLUSH_WRK_ARND", + "BriefDescription": "LSU workaround flush. These flushes are setup with programmable scan only latches to perform various actions when the flush macro receives a trigger from the dbg macros. These actions include things like flushing the next op encountered for a particular thread or flushing the next op that is NTC op that is encountered on a particular slice. The kind of flush that the workaround is setup to perform is highly variable." + }, + {, + "EventCode": "0x34054", + "EventName": "PM_PARTIAL_ST_FIN", + "BriefDescription": "Any store finished by an LSU slice" + }, + {, + "EventCode": "0x5880", + "EventName": "PM_THRD_PRIO_6_7_CYC", + "BriefDescription": "Cycles thread running at priority level 6 or 7" + }, + {, + "EventCode": "0x4898", + "EventName": "PM_IC_DEMAND_L2_BR_REDIRECT", + "BriefDescription": "L2 I cache demand request due to branch Mispredict ( 15 cycle path)" + }, + {, + "EventCode": "0x4880", + "EventName": "PM_BANK_CONFLICT", + "BriefDescription": "Read blocked due to interleave conflict. The ifar logic will detect an interleave conflict and kill the data that was read that cycle." + }, + {, + "EventCode": "0x360B0", + "EventName": "PM_L3_P0_SYS_PUMP", + "BriefDescription": "L3 PF sent with sys scope port 0, counts even retried requests" + }, + {, + "EventCode": "0x3006A", + "EventName": "PM_IERAT_RELOAD_64K", + "BriefDescription": "IERAT Reloaded (Miss) for a 64k page" + }, + {, + "EventCode": "0xD8BC", + "EventName": "PM_LSU2_3_LRQF_FULL_CYC", + "BriefDescription": "Counts the number of cycles the LRQF is full. LRQF is the queue that holds loads between finish and completion. If it fills up, instructions stay in LRQ until completion, potentially backing up the LRQ" + }, + {, + "EventCode": "0x46086", + "EventName": "PM_L2_SN_M_RD_DONE", + "BriefDescription": "SNP dispatched for a read and was M (true M)" + }, + {, + "EventCode": "0x40154", + "EventName": "PM_MRK_FAB_RSP_BKILL", + "BriefDescription": "Marked store had to do a bkill" + }, + {, + "EventCode": "0xF094", + "EventName": "PM_LSU2_L1_CAM_CANCEL", + "BriefDescription": "ls2 l1 tm cam cancel" + }, + {, + "EventCode": "0x2D014", + "EventName": "PM_CMPLU_STALL_LRQ_FULL", + "BriefDescription": "Finish stall because the NTF instruction was a load that was held in LSAQ (load-store address queue) because the LRQ (load-reorder queue) was full" + }, + {, + "EventCode": "0x3E05E", + "EventName": "PM_L3_CO_MEPF", + "BriefDescription": "L3 castouts in Mepf state for this thread" + }, + {, + "EventCode": "0x460A2", + "EventName": "PM_L3_LAT_CI_HIT", + "BriefDescription": "L3 Lateral Castins Hit" + }, + {, + "EventCode": "0x3D14E", + "EventName": "PM_MRK_DATA_FROM_DL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0x3D15E", + "EventName": "PM_MULT_MRK", + "BriefDescription": "mult marked instr" + }, + {, + "EventCode": "0x4084", + "EventName": "PM_EAT_FULL_CYC", + "BriefDescription": "Cycles No room in EAT" + }, + {, + "EventCode": "0x5098", + "EventName": "PM_LINK_STACK_WRONG_ADD_PRED", + "BriefDescription": "Link stack predicts wrong address, because of link stack design limitation or software violating the coding conventions" + }, + {, + "EventCode": "0x2C050", + "EventName": "PM_DATA_GRP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was group pump (prediction=correct) for a demand load" + }, + {, + "EventCode": "0xC0A4", + "EventName": "PM_LSU2_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0x58A0", + "EventName": "PM_LINK_STACK_CORRECT", + "BriefDescription": "Link stack predicts right address" + }, + {, + "EventCode": "0x4C05A", + "EventName": "PM_DTLB_MISS_1G", + "BriefDescription": "Data TLB reload (after a miss) page size 1G. Implies radix translation was used" + }, + {, + "EventCode": "0x36886", + "EventName": "PM_L2_SN_SX_I_DONE", + "BriefDescription": "SNP dispatched and went from Sx to Ix" + }, + {, + "EventCode": "0x4E04A", + "EventName": "PM_DPTEG_FROM_OFF_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2C12C", + "EventName": "PM_MRK_DATA_FROM_DL4_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's L4 on a different Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x2608E", + "EventName": "PM_TM_LD_CONF", + "BriefDescription": "TM Load (fav or non-fav) ran into conflict (failed)" + }, + {, + "EventCode": "0x4080", + "EventName": "PM_INST_FROM_L1", + "BriefDescription": "Instruction fetches from L1. L1 instruction hit" + }, + {, + "EventCode": "0xE898", + "EventName": "PM_LSU3_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x260A0", + "EventName": "PM_L3_CO_MEM", + "BriefDescription": "L3 CO to memory OR of port 0 and 1 (lossy = may undercount if two cresp come in the same cyc)" + }, + {, + "EventCode": "0x16082", + "EventName": "PM_L2_CASTOUT_MOD", + "BriefDescription": "L2 Castouts - Modified (M,Mu,Me)" + }, + {, + "EventCode": "0xC09C", + "EventName": "PM_LS0_LAUNCH_HELD_PREF", + "BriefDescription": "Number of times a load or store instruction was unable to launch/relaunch because a high priority prefetch used that relaunch cycle" + }, + {, + "EventCode": "0xC8B8", + "EventName": "PM_LSU_FLUSH_LARX_STCX", + "BriefDescription": "A larx is flushed because an older larx has an LMQ reservation for the same thread. A stcx is flushed because an older stcx is in the LMQ. The flush happens when the older larx/stcx relaunches" + }, + {, + "EventCode": "0x260A6", + "EventName": "PM_NON_TM_RST_SC", + "BriefDescription": "Non-TM snp rst TM SC" + }, + {, + "EventCode": "0x3608A", + "EventName": "PM_L2_RTY_ST", + "BriefDescription": "RC retries on PB for any store from core (excludes DCBFs)" + }, + {, + "EventCode": "0x24040", + "EventName": "PM_INST_FROM_L2_MEPF", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L2 hit without dispatch conflicts on Mepf state. due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x209C", + "EventName": "PM_TM_FAV_TBEGIN", + "BriefDescription": "Dispatch time Favored tbegin" + }, + {, + "EventCode": "0x2D01E", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_ISSQ", + "BriefDescription": "Ict empty for this thread due to dispatch hold on this thread due to Issue q full, BRQ full, XVCF Full, Count cache, Link, Tar full" + }, + {, + "EventCode": "0x50A4", + "EventName": "PM_FLUSH_MPRED", + "BriefDescription": "Branch mispredict flushes. Includes target and address misprecition" + }, + {, + "EventCode": "0x508C", + "EventName": "PM_SHL_CREATED", + "BriefDescription": "Store-Hit-Load Table Entry Created" + }, + {, + "EventCode": "0x1504C", + "EventName": "PM_IPTEG_FROM_LL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's L4 cache due to a instruction side request" + }, + {, + "EventCode": "0x268A4", + "EventName": "PM_L3_LD_MISS", + "BriefDescription": "L3 Misses for demand LDs" + }, + {, + "EventCode": "0x26088", + "EventName": "PM_L2_GRP_GUESS_CORRECT", + "BriefDescription": "L2 guess grp (GS or NNS) and guess was correct (data intra-group AND ^on-chip)" + }, + {, + "EventCode": "0xD088", + "EventName": "PM_LSU0_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])." + }, + {, + "EventCode": "0xE8B4", + "EventName": "PM_LS1_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x1688C", + "EventName": "PM_RC_USAGE", + "BriefDescription": "Continuous 16 cycle (2to1) window where this signals rotates thru sampling each RC machine busy. PMU uses this wave to then do 16 cyc count to sample total number of machs running" + }, + {, + "EventCode": "0x3F054", + "EventName": "PM_RADIX_PWC_L4_PTE_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was reloaded to a level 4 page walk cache from beyond the core's L3 data cache. This is the deepest level of PWC possible for a translation. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x2608A", + "EventName": "PM_ISIDE_DISP_FAIL_ADDR", + "BriefDescription": "All I-side dispatch attempts for this thread that failed due to a addr collision with another machine (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x50B4", + "EventName": "PM_TAGE_CORRECT_TAKEN_CMPL", + "BriefDescription": "The TAGE overrode BHT direction prediction and it was correct. Counted at completion for taken branches only" + }, + {, + "EventCode": "0x2090", + "EventName": "PM_DISP_CLB_HELD_SB", + "BriefDescription": "Dispatch/CLB Hold: Scoreboard" + }, + {, + "EventCode": "0xE0B0", + "EventName": "PM_TM_FAIL_NON_TX_CONFLICT", + "BriefDescription": "Non transactional conflict from LSU, gets reported to TEXASR" + }, + {, + "EventCode": "0xD198", + "EventName": "PM_MRK_LSU_FLUSH_ATOMIC", + "BriefDescription": "Quad-word loads (lq) are considered atomic because they always span at least 2 slices. If a snoop or store from another thread changes the data the load is accessing between the 2 or 3 pieces of the lq instruction, the lq will be flushed" + }, + {, + "EventCode": "0x201E0", + "EventName": "PM_MRK_DATA_FROM_MEMORY", + "BriefDescription": "The processor's data cache was reloaded from a memory location including L4 from local remote or distant due to a marked load" + }, + {, + "EventCode": "0x368A2", + "EventName": "PM_L3_L2_CO_MISS", + "BriefDescription": "L2 CO miss" + }, + {, + "EventCode": "0x3608C", + "EventName": "PM_CO0_BUSY", + "BriefDescription": "CO mach 0 Busy. Used by PMU to sample ave CO lifetime (mach0 used as sample point)" + }, + {, + "EventCode": "0x2C122", + "EventName": "PM_MRK_DATA_FROM_L3_DISP_CONFLICT_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 with dispatch conflict due to a marked load" + }, + {, + "EventCode": "0x35154", + "EventName": "PM_MRK_DATA_FROM_L3_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 due to a marked load" + }, + {, + "EventCode": "0x1D140", + "EventName": "PM_MRK_DATA_FROM_L31_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x4404A", + "EventName": "PM_INST_FROM_OFF_CHIP_CACHE", + "BriefDescription": "The processor's Instruction cache was reloaded either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x28AC", + "EventName": "PM_TM_FAIL_SELF", + "BriefDescription": "TM aborted because a self-induced conflict occurred in Suspended state, due to one of the following: a store to a storage location that was previously accessed transactionally; a dcbf, dcbi, or icbi specify- ing a block that was previously accessed transactionally; a dcbst specifying a block that was previously written transactionally; or a tlbie that specifies a translation that was pre- viously used transactionally" + }, + {, + "EventCode": "0x45056", + "EventName": "PM_SCALAR_FLOP_CMPL", + "BriefDescription": "Scalar flop operation completed" + }, + {, + "EventCode": "0x16092", + "EventName": "PM_L2_LD_MISS_128B", + "BriefDescription": "All successful D-side load dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 128B (i.e., M=0)" + }, + {, + "EventCode": "0x2E014", + "EventName": "PM_STCX_FIN", + "BriefDescription": "Number of stcx instructions finished. This includes instructions in the speculative path of a branch that may be flushed" + }, + {, + "EventCode": "0xE0B8", + "EventName": "PM_LS2_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x2094", + "EventName": "PM_TM_OUTER_TBEGIN", + "BriefDescription": "Completion time outer tbegin" + }, + {, + "EventCode": "0x160B4", + "EventName": "PM_L3_P0_LCO_RTY", + "BriefDescription": "L3 initiated LCO received retry on port 0 (can try 4 times)" + }, + {, + "EventCode": "0x36892", + "EventName": "PM_DSIDE_OTHER_64B_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an D-side fetch where data came EXCLUSIVELY from memory that was for hpc_read64, (RC had to fetch other 64B of a line from MC) i.e., number of times RC had to go to memory to get 'missing' 64B" + }, + {, + "EventCode": "0x20A8", + "EventName": "PM_TM_FAIL_FOOTPRINT_OVERFLOW", + "BriefDescription": "TM aborted because the tracking limit for transactional storage accesses was exceeded.. Asynchronous" + }, + {, + "EventCode": "0x30018", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_HB_FULL", + "BriefDescription": "Ict empty for this thread due to dispatch holds because the History Buffer was full. Could be GPR/VSR/VMR/FPR/CR/XVF; CR; XVF (XER/VSCR/FPSCR)" + }, + {, + "EventCode": "0xC894", + "EventName": "PM_LS1_UNALIGNED_LD", + "BriefDescription": "Load instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the load of that size. If the load wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x360A2", + "EventName": "PM_L3_L2_CO_HIT", + "BriefDescription": "L2 CO hits" + }, + {, + "EventCode": "0x36092", + "EventName": "PM_DSIDE_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an D-side fetch where data came EXCLUSIVELY from memory (excluding hpcread64 accesses), i.e., total memory accesses by RCs" + }, + {, + "EventCode": "0x10138", + "EventName": "PM_MRK_BR_2PATH", + "BriefDescription": "marked branches which are not strongly biased" + }, + {, + "EventCode": "0x2884", + "EventName": "PM_ISYNC", + "BriefDescription": "Isync completion count per thread" + }, + {, + "EventCode": "0x16882", + "EventName": "PM_L2_CASTOUT_SHR", + "BriefDescription": "L2 Castouts - Shared (Tx,Sx)" + }, + {, + "EventCode": "0xD884", + "EventName": "PM_LSU3_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0x26092", + "EventName": "PM_L2_LD_MISS_64B", + "BriefDescription": "All successful D-side load dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 64B(i.e., M=1)" + }, + {, + "EventCode": "0x26080", + "EventName": "PM_L2_LD_MISS", + "BriefDescription": "All successful D-Side Load dispatches that were an L2 miss for this thread" + }, + {, + "EventCode": "0x3D14C", + "EventName": "PM_MRK_DATA_FROM_DMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x100FA", + "EventName": "PM_ANY_THRD_RUN_CYC", + "BriefDescription": "Cycles in which at least one thread has the run latch set" + }, + {, + "EventCode": "0x2C12A", + "EventName": "PM_MRK_DATA_FROM_RMEM_CYC", + "BriefDescription": "Duration in cycles to reload from another chip's memory on the same Node or Group ( Remote) due to a marked load" + }, + {, + "EventCode": "0x25048", + "EventName": "PM_IPTEG_FROM_LMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's Memory due to a instruction side request" + }, + {, + "EventCode": "0xD8A8", + "EventName": "PM_ISLB_MISS", + "BriefDescription": "Instruction SLB miss - Total of all segment sizes" + }, + {, + "EventCode": "0xD19C", + "EventName": "PM_MRK_LSU_FLUSH_RELAUNCH_MISS", + "BriefDescription": "If a load that has already returned data and has to relaunch for any reason then gets a miss (erat, setp, data cache), it will often be flushed at relaunch time because the data might be inconsistent" + }, + {, + "EventCode": "0x260A2", + "EventName": "PM_L3_CI_HIT", + "BriefDescription": "L3 Castins Hit (total count)" + }, + {, + "EventCode": "0x44054", + "EventName": "PM_VECTOR_LD_CMPL", + "BriefDescription": "Number of vector load instructions completed" + }, + {, + "EventCode": "0x1E05C", + "EventName": "PM_CMPLU_STALL_NESTED_TBEGIN", + "BriefDescription": "Completion stall because the ISU is updating the TEXASR to keep track of the nested tbegin. This is a short delay, and it includes ROT" + }, + {, + "EventCode": "0x1608E", + "EventName": "PM_ST_CAUSED_FAIL", + "BriefDescription": "Non-TM Store caused any thread to fail" + }, + {, + "EventCode": "0x3080", + "EventName": "PM_ISU0_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0x1515A", + "EventName": "PM_SYNC_MRK_L2MISS", + "BriefDescription": "Marked L2 Miss that can throw a synchronous interrupt" + }, + {, + "EventCode": "0x26892", + "EventName": "PM_L2_ST_MISS_64B", + "BriefDescription": "All successful D-side store dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 64B (i.e., M=1)" + }, + {, + "EventCode": "0x2688C", + "EventName": "PM_CO_USAGE", + "BriefDescription": "Continuous 16 cycle (2to1) window where this signals rotates thru sampling each CO machine busy. PMU uses this wave to then do 16 cyc count to sample total number of machs running" + }, + {, + "EventCode": "0xD084", + "EventName": "PM_LSU2_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0x48B8", + "EventName": "PM_BR_MPRED_TAKEN_TA", + "BriefDescription": "Conditional Branch Completed that was Mispredicted due to the Target Address Prediction from the Count Cache or Link Stack. Only XL-form branches that resolved Taken set this event." + }, + {, + "EventCode": "0x50B0", + "EventName": "PM_BTAC_BAD_RESULT", + "BriefDescription": "BTAC thinks branch will be taken but it is either predicted not-taken by the BHT, or the target address is wrong (less common). In both cases, a redirect will happen" + }, + {, + "EventCode": "0xD888", + "EventName": "PM_LSU1_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])." + }, + {, + "EventCode": "0x58B4", + "EventName": "PM_TAGE_CORRECT", + "BriefDescription": "The TAGE overrode BHT direction prediction and it was correct. Includes taken and not taken and is counted at execution time" + }, + {, + "EventCode": "0x3688C", + "EventName": "PM_SN_USAGE", + "BriefDescription": "Continuous 16 cycle (2to1) window where this signals rotates thru sampling each SN machine busy. PMU uses this wave to then do 16 cyc count to sample total number of machs running" + }, + {, + "EventCode": "0x46084", + "EventName": "PM_L2_RCST_DISP_FAIL_OTHER", + "BriefDescription": "All D-side store dispatch attempts for this thread that failed due to reason other than address collision" + }, + {, + "EventCode": "0xF0AC", + "EventName": "PM_DC_PREF_STRIDED_CONF", + "BriefDescription": "A demand load referenced a line in an active strided prefetch stream. The stream could have been allocated through the hardware prefetch mechanism or through software." + }, + {, + "EventCode": "0x45054", + "EventName": "PM_FMA_CMPL", + "BriefDescription": "two flops operation completed (fmadd, fnmadd, fmsub, fnmsub) Scalar instructions only. " + }, + {, + "EventCode": "0x5090", + "EventName": "PM_SHL_ST_DISABLE", + "BriefDescription": "Store-Hit-Load Table Read Hit with entry Disabled (entry was disabled due to the entry shown to not prevent the flush)" + }, + {, + "EventCode": "0x201E8", + "EventName": "PM_THRESH_EXC_512", + "BriefDescription": "Threshold counter exceeded a value of 512" + }, + {, + "EventCode": "0x5084", + "EventName": "PM_DECODE_FUSION_EXT_ADD", + "BriefDescription": "32-bit extended addition" + }, + {, + "EventCode": "0x36080", + "EventName": "PM_L2_INST", + "BriefDescription": "All successful I-side dispatches for this thread (excludes i_l2mru_tch reqs)." + }, + {, + "EventCode": "0x3504C", + "EventName": "PM_IPTEG_FROM_DL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on a different Node or Group (Distant) due to a instruction side request" + }, + {, + "EventCode": "0xD890", + "EventName": "PM_LS1_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x1688A", + "EventName": "PM_ISIDE_DISP", + "BriefDescription": "All I-side dispatch attempts for this thread (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x468AA", + "EventName": "PM_L3_P1_CO_L31", + "BriefDescription": "L3 CO to L3.1 (LCO) port 1 with or without data" + }, + {, + "EventCode": "0x28B0", + "EventName": "PM_DISP_HELD_TBEGIN", + "BriefDescription": "This outer tbegin transaction cannot be dispatched until the previous tend instruction completes" + }, + {, + "EventCode": "0xE8A0", + "EventName": "PM_LSU3_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x2C05E", + "EventName": "PM_INST_GRP_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (Group) ended up either larger or smaller than Initial Pump Scope for an instruction fetch (demand only)" + }, + {, + "EventCode": "0xC8BC", + "EventName": "PM_STCX_SUCCESS_CMPL", + "BriefDescription": "Number of stcx instructions that completed successfully" + }, + {, + "EventCode": "0xE098", + "EventName": "PM_LSU2_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x44044", + "EventName": "PM_INST_FROM_L31_ECO_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another core's ECO L3 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x16886", + "EventName": "PM_CO_DISP_FAIL", + "BriefDescription": "CO dispatch failed due to all CO machines being busy" + }, + {, + "EventCode": "0x3D146", + "EventName": "PM_MRK_DATA_FROM_L3_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without conflict due to a marked load" + }, + {, + "EventCode": "0x16892", + "EventName": "PM_L2_ST_MISS_128B", + "BriefDescription": "All successful D-side store dispatches that were an L2 miss (NOT Sx,Tx,Mx) for this thread and the RC calculated the request should be for 128B (i.e., M=0)" + }, + {, + "EventCode": "0x26890", + "EventName": "PM_ISIDE_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an I-side fetch where data came from memory" + }, + {, + "EventCode": "0xD094", + "EventName": "PM_LS2_DC_COLLISIONS", + "BriefDescription": "Read-write data cache collisions" + }, + {, + "EventCode": "0x3C05E", + "EventName": "PM_MEM_RWITM", + "BriefDescription": "Memory Read With Intent to Modify for this thread" + }, + {, + "EventCode": "0x26882", + "EventName": "PM_L2_DC_INV", + "BriefDescription": "D-cache invalidates sent over the reload bus to the core" + }, + {, + "EventCode": "0xC090", + "EventName": "PM_LSU_STCX", + "BriefDescription": "STCX sent to nest, i.e. total" + }, + {, + "EventCode": "0xD080", + "EventName": "PM_LSU0_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0x2C120", + "EventName": "PM_MRK_DATA_FROM_L2_NO_CONFLICT", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 without conflict due to a marked load" + }, + {, + "EventCode": "0x36086", + "EventName": "PM_L2_RC_ST_DONE", + "BriefDescription": "RC did store to line that was Tx or Sx" + }, + {, + "EventCode": "0xE8AC", + "EventName": "PM_TM_FAIL_TX_CONFLICT", + "BriefDescription": "Transactional conflict from LSU, gets reported to TEXASR" + }, + {, + "EventCode": "0x48A8", + "EventName": "PM_DECODE_FUSION_LD_ST_DISP", + "BriefDescription": "32-bit displacement D-form and 16-bit displacement X-form" + }, + {, + "EventCode": "0x3D144", + "EventName": "PM_MRK_DATA_FROM_L2_MEPF_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L2 hit without dispatch conflicts on Mepf state. due to a marked load" + }, + {, + "EventCode": "0x44046", + "EventName": "PM_INST_FROM_L21_MOD", + "BriefDescription": "The processor's Instruction cache was reloaded with Modified (M) data from another core's L2 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x40B0", + "EventName": "PM_BR_PRED_TAKEN_CR", + "BriefDescription": "Conditional Branch that had its direction predicted. I-form branches do not set this event. In addition, B-form branches which do not use the BHT do not set this event - these are branches with BO-field set to 'always taken' and branches" + }, + {, + "EventCode": "0x15040", + "EventName": "PM_IPTEG_FROM_L2_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 without conflict due to a instruction side request" + }, + {, + "EventCode": "0xD9A0", + "EventName": "PM_MRK_LSU_FLUSH_LHL_SHL", + "BriefDescription": "The instruction was flushed because of a sequential load/store consistency. If a load or store hits on an older load that has either been snooped (for loads) or has stale data (for stores)." + }, + {, + "EventCode": "0x35042", + "EventName": "PM_IPTEG_FROM_L3_DISP_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 with dispatch conflict due to a instruction side request" + }, + {, + "EventCode": "0xF898", + "EventName": "PM_XLATE_RADIX_MODE", + "BriefDescription": "LSU reports every cycle the thread is in radix translation mode (as opposed to HPT mode)" + }, + {, + "EventCode": "0x2D142", + "EventName": "PM_MRK_DATA_FROM_L3_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L3 without dispatch conflicts hit on Mepf state. due to a marked load" + }, + {, + "EventCode": "0x160B0", + "EventName": "PM_L3_P0_NODE_PUMP", + "BriefDescription": "L3 PF sent with nodal scope port 0, counts even retried requests" + }, + {, + "EventCode": "0xD88C", + "EventName": "PM_LSU3_LDMX_FIN", + "BriefDescription": "New P9 instruction LDMX. The definition of this new PMU event is (from the ldmx RFC02491): The thread has executed an ldmx instruction that accessed a doubleword that contains an effective address within an enabled section of the Load Monitored region. This event, therefore, should not occur if the FSCR has disabled the load monitored facility (FSCR[52]) or disabled the EBB facility (FSCR[56])." + }, + {, + "EventCode": "0x36882", + "EventName": "PM_L2_LD_HIT", + "BriefDescription": "All successful I-or-D side load dispatches for this thread that were L2 hits (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x168AC", + "EventName": "PM_L3_CI_USAGE", + "BriefDescription": "Rotating sample of 16 CI or CO actives" + }, + {, + "EventCode": "0x20134", + "EventName": "PM_MRK_FXU_FIN", + "BriefDescription": "fxu marked instr finish" + }, + {, + "EventCode": "0x4608E", + "EventName": "PM_TM_CAP_OVERFLOW", + "BriefDescription": "TM Footprint Capacity Overflow" + }, + {, + "EventCode": "0x4F05C", + "EventName": "PM_RADIX_PWC_L2_PTE_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was reloaded to a level 2 page walk cache from beyond the core's L3 data cache. This implies that level 3 and level 4 PWC accesses were not necessary for this translation. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x40014", + "EventName": "PM_PROBE_NOP_DISP", + "BriefDescription": "ProbeNops dispatched" + }, + {, + "EventCode": "0x58A8", + "EventName": "PM_DECODE_HOLD_ICT_FULL", + "BriefDescription": "Counts the number of cycles in which the IFU was not able to decode and transmit one or more instructions because all itags were in use. This means the ICT is full for this thread" + }, + {, + "EventCode": "0x10052", + "EventName": "PM_GRP_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x2505E", + "EventName": "PM_BACK_BR_CMPL", + "BriefDescription": "Branch instruction completed with a target address less than current instruction address" + }, + {, + "EventCode": "0x2688A", + "EventName": "PM_ISIDE_DISP_FAIL_OTHER", + "BriefDescription": "All I-side dispatch attempts for this thread that failed due to a reason other than addrs collision (excludes i_l2mru_tch_reqs)" + }, + {, + "EventCode": "0x2001A", + "EventName": "PM_NTC_ALL_FIN", + "BriefDescription": "Cycles after all instructions have finished to group completed" + }, + {, + "EventCode": "0x3005A", + "EventName": "PM_ISQ_0_8_ENTRIES", + "BriefDescription": "Cycles in which 8 or less Issue Queue entries are in use. This is a shared event, not per thread" + }, + {, + "EventCode": "0x3515E", + "EventName": "PM_MRK_BACK_BR_CMPL", + "BriefDescription": "Marked branch instruction completed with a target address less than current instruction address" + }, + {, + "EventCode": "0xF890", + "EventName": "PM_LSU1_L1_CAM_CANCEL", + "BriefDescription": "ls1 l1 tm cam cancel" + }, + {, + "EventCode": "0xE884", + "EventName": "PM_LS1_ERAT_MISS_PREF", + "BriefDescription": "LS1 Erat miss due to prefetch" + }, + {, + "EventCode": "0xE89C", + "EventName": "PM_LSU1_TM_L1_MISS", + "BriefDescription": "Load tm L1 miss" + }, + {, + "EventCode": "0x28A8", + "EventName": "PM_TM_FAIL_CONF_NON_TM", + "BriefDescription": "TM aborted because a conflict occurred with a non-transactional access by another processor" + }, + {, + "EventCode": "0x16890", + "EventName": "PM_L1PF_L2MEMACC", + "BriefDescription": "Valid when first beat of data comes in for an L1PF where data came from memory" + }, + {, + "EventCode": "0x4504C", + "EventName": "PM_IPTEG_FROM_DMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group (Distant) due to a instruction side request" + }, + {, + "EventCode": "0x1002E", + "EventName": "PM_LMQ_MERGE", + "BriefDescription": "A demand miss collides with a prefetch for the same line" + }, + {, + "EventCode": "0x160B6", + "EventName": "PM_L3_WI0_BUSY", + "BriefDescription": "Rotating sample of 8 WI valid" + }, + {, + "EventCode": "0x368AC", + "EventName": "PM_L3_CO0_BUSY", + "BriefDescription": "Lifetime, sample of CO machine 0 valid" + }, + {, + "EventCode": "0x2E040", + "EventName": "PM_DPTEG_FROM_L2_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 hit without dispatch conflicts on Mepf state. due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1D152", + "EventName": "PM_MRK_DATA_FROM_DL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on a different Node or Group (Distant) due to a marked load" + }, + {, + "EventCode": "0x46880", + "EventName": "PM_ISIDE_MRU_TOUCH", + "BriefDescription": "I-side L2 MRU touch sent to L2 for this thread" + }, + {, + "EventCode": "0x1C05C", + "EventName": "PM_DTLB_MISS_2M", + "BriefDescription": "Data TLB reload (after a miss) page size 2M. Implies radix translation was used" + }, + {, + "EventCode": "0x50B8", + "EventName": "PM_TAGE_OVERRIDE_WRONG", + "BriefDescription": "The TAGE overrode BHT direction prediction but it was incorrect. Counted at completion for taken branches only" + }, + {, + "EventCode": "0x160AE", + "EventName": "PM_L3_P0_PF_RTY", + "BriefDescription": "L3 PF received retry port 0, every retry counted" + }, + {, + "EventCode": "0x268B2", + "EventName": "PM_L3_LOC_GUESS_WRONG", + "BriefDescription": "Initial scope=node (LNS) but data from out side local node (near or far or rem). Prediction too Low" + }, + {, + "EventCode": "0x36088", + "EventName": "PM_L2_SYS_GUESS_CORRECT", + "BriefDescription": "L2 guess system (VGS or RNS) and guess was correct (ie data beyond-group)" + }, + {, + "EventCode": "0x589C", + "EventName": "PM_PTESYNC", + "BriefDescription": "ptesync instruction counted when the instruction is decoded and transmitted" + }, + {, + "EventCode": "0x26086", + "EventName": "PM_CO_TM_SC_FOOTPRINT", + "BriefDescription": "L2 did a cleanifdirty CO to the L3 (ie created an SC line in the L3) OR L2 TM_store hit dirty HPC line and L3 indicated SC line formed in L3 on RDR bus" + }, + {, + "EventCode": "0x1E05A", + "EventName": "PM_CMPLU_STALL_ANY_SYNC", + "BriefDescription": "Cycles in which the NTC sync instruction (isync, lwsync or hwsync) is not allowed to complete" + }, + {, + "EventCode": "0xF090", + "EventName": "PM_LSU0_L1_CAM_CANCEL", + "BriefDescription": "ls0 l1 tm cam cancel" + }, + {, + "EventCode": "0xC0A8", + "EventName": "PM_LSU_FLUSH_CI", + "BriefDescription": "Load was not issued to LSU as a cache inhibited (non-cacheable) load but it was later determined to be cache inhibited" + }, + {, + "EventCode": "0x20AC", + "EventName": "PM_TM_FAIL_CONF_TM", + "BriefDescription": "TM aborted because a conflict occurred with another transaction." + }, + {, + "EventCode": "0x588C", + "EventName": "PM_SHL_ST_DEP_CREATED", + "BriefDescription": "Store-Hit-Load Table Read Hit with entry Enabled" + }, + {, + "EventCode": "0x360AC", + "EventName": "PM_L3_SN0_BUSY", + "BriefDescription": "Lifetime, sample of snooper machine 0 valid" + }, + {, + "EventCode": "0x3005C", + "EventName": "PM_BFU_BUSY", + "BriefDescription": "Cycles in which all 4 Binary Floating Point units are busy. The BFU is running at capacity" + }, + {, + "EventCode": "0x48A0", + "EventName": "PM_BR_PRED_PCACHE", + "BriefDescription": "Conditional branch completed that used pattern cache prediction" + }, + {, + "EventCode": "0x26880", + "EventName": "PM_L2_ST_MISS", + "BriefDescription": "All successful D-Side Store dispatches that were an L2 miss for this thread" + }, + {, + "EventCode": "0xF8B4", + "EventName": "PM_DC_PREF_XCONS_ALLOC", + "BriefDescription": "Prefetch stream allocated in the Ultra conservative phase by either the hardware prefetch mechanism or software prefetch" + }, + {, + "EventCode": "0x35048", + "EventName": "PM_IPTEG_FROM_DL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x260A8", + "EventName": "PM_L3_PF_HIT_L3", + "BriefDescription": "L3 PF hit in L3 (abandoned)" + }, + {, + "EventCode": "0x360B4", + "EventName": "PM_L3_PF0_BUSY", + "BriefDescription": "Lifetime, sample of PF machine 0 valid" + }, + {, + "EventCode": "0xC0B0", + "EventName": "PM_LSU_FLUSH_UE", + "BriefDescription": "Correctable ECC error on reload data, reported at critical data forward time" + }, + {, + "EventCode": "0x4013A", + "EventName": "PM_MRK_IC_MISS", + "BriefDescription": "Marked instruction experienced I cache miss" + }, + {, + "EventCode": "0x2088", + "EventName": "PM_FLUSH_DISP_SB", + "BriefDescription": "Dispatch Flush: Scoreboard" + }, + {, + "EventCode": "0x401E8", + "EventName": "PM_MRK_DATA_FROM_L2MISS", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L2 due to a marked load" + }, + {, + "EventCode": "0x3688E", + "EventName": "PM_TM_ST_CAUSED_FAIL", + "BriefDescription": "TM Store (fav or non-fav) caused another thread to fail" + }, + {, + "EventCode": "0x460B2", + "EventName": "PM_L3_SYS_GUESS_WRONG", + "BriefDescription": "Initial scope=system (VGS or RNS) but data from local or near. Prediction too high" + }, + {, + "EventCode": "0x58B8", + "EventName": "PM_TAGE_OVERRIDE_WRONG_SPEC", + "BriefDescription": "The TAGE overrode BHT direction prediction and it was correct. Includes taken and not taken and is counted at execution time" + }, + {, + "EventCode": "0xE890", + "EventName": "PM_LSU3_ERAT_HIT", + "BriefDescription": "Primary ERAT hit. There is no secondary ERAT" + }, + {, + "EventCode": "0x2898", + "EventName": "PM_TM_TABORT_TRECLAIM", + "BriefDescription": "Completion time tabortnoncd, tabortcd, treclaim" + }, + {, + "EventCode": "0x4C054", + "EventName": "PM_DERAT_MISS_16G", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 16G" + }, + {, + "EventCode": "0x268A0", + "EventName": "PM_L3_CO_L31", + "BriefDescription": "L3 CO to L3.1 OR of port 0 and 1 (lossy = may undercount if two cresps come in the same cyc)" + }, + {, + "EventCode": "0x5080", + "EventName": "PM_THRD_PRIO_4_5_CYC", + "BriefDescription": "Cycles thread running at priority level 4 or 5" + }, + {, + "EventCode": "0x2505C", + "EventName": "PM_VSU_FIN", + "BriefDescription": "VSU instruction finished. Up to 4 per cycle" + }, + {, + "EventCode": "0x40A4", + "EventName": "PM_BR_PRED_CCACHE", + "BriefDescription": "Conditional Branch Completed that used the Count Cache for Target Prediction" + }, + {, + "EventCode": "0x2E04A", + "EventName": "PM_DPTEG_FROM_RL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on the same Node or Group ( Remote) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D12E", + "EventName": "PM_MRK_DATA_FROM_DL2L3_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0xC8B4", + "EventName": "PM_LSU_FLUSH_LHL_SHL", + "BriefDescription": "The instruction was flushed because of a sequential load/store consistency. If a load or store hits on an older load that has either been snooped (for loads) or has stale data (for stores)." + }, + {, + "EventCode": "0x58A4", + "EventName": "PM_FLUSH_LSU", + "BriefDescription": "LSU flushes. Includes all lsu flushes" + }, + {, + "EventCode": "0x1D150", + "EventName": "PM_MRK_DATA_FROM_DL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked load" + }, + {, + "EventCode": "0xC8A0", + "EventName": "PM_LSU1_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0x48BC", + "EventName": "PM_THRD_PRIO_2_3_CYC", + "BriefDescription": "Cycles thread running at priority level 2 or 3" + }, + {, + "EventCode": "0x10134", + "EventName": "PM_MRK_ST_DONE_L2", + "BriefDescription": "marked store completed in L2 ( RC machine done)" + }, + {, + "EventCode": "0x368B2", + "EventName": "PM_L3_GRP_GUESS_WRONG_HIGH", + "BriefDescription": "Initial scope=group (GS or NNS) but data from local node. Prediction too high" + }, + {, + "EventCode": "0xE8BC", + "EventName": "PM_LS1_PTE_TABLEWALK_CYC", + "BriefDescription": "Cycles when a tablewalk is pending on this thread on table 1" + }, + {, + "EventCode": "0x1F152", + "EventName": "PM_MRK_FAB_RSP_BKILL_CYC", + "BriefDescription": "cycles L2 RC took for a bkill" + }, + {, + "EventCode": "0x4C124", + "EventName": "PM_MRK_DATA_FROM_L3_NO_CONFLICT_CYC", + "BriefDescription": "Duration in cycles to reload from local core's L3 without conflict due to a marked load" + }, + {, + "EventCode": "0x2F14A", + "EventName": "PM_MRK_DPTEG_FROM_RL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on the same Node or Group ( Remote) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x26888", + "EventName": "PM_L2_GRP_GUESS_WRONG", + "BriefDescription": "L2 guess grp (GS or NNS) and guess was not correct (ie data on-chip OR beyond-group)" + }, + {, + "EventCode": "0x368AE", + "EventName": "PM_L3_P1_CO_RTY", + "BriefDescription": "L3 CO received retry port 1 (memory only), every retry counted" + }, + {, + "EventCode": "0xC0AC", + "EventName": "PM_LSU_FLUSH_EMSH", + "BriefDescription": "An ERAT miss was detected after a set-p hit. Erat tracker indicates fail due to tlbmiss and the instruction gets flushed because the instruction was working on the wrong address" + }, + {, + "EventCode": "0x260B2", + "EventName": "PM_L3_SYS_GUESS_CORRECT", + "BriefDescription": "Initial scope=system (VGS or RNS) and data from outside group (far or rem)(pred successful)" + }, + {, + "EventCode": "0x1D146", + "EventName": "PM_MRK_DATA_FROM_MEMORY_CYC", + "BriefDescription": "Duration in cycles to reload from a memory location including L4 from local remote or distant due to a marked load" + }, + {, + "EventCode": "0xE094", + "EventName": "PM_LSU0_TM_L1_HIT", + "BriefDescription": "Load tm hit in L1" + }, + {, + "EventCode": "0x46888", + "EventName": "PM_L2_GROUP_PUMP", + "BriefDescription": "RC requests that were on group (aka nodel) pump attempts" + }, + {, + "EventCode": "0xF0B0", + "EventName": "PM_L3_LD_PREF", + "BriefDescription": "L3 load prefetch, sourced from a hardware or software stream, was sent to the nest" + }, + {, + "EventCode": "0x16080", + "EventName": "PM_L2_LD", + "BriefDescription": "All successful D-side Load dispatches for this thread (L2 miss + L2 hits)" + }, + {, + "EventCode": "0x4505C", + "EventName": "PM_MATH_FLOP_CMPL", + "BriefDescription": "Math flop instruction completed" + }, + {, + "EventCode": "0x368B0", + "EventName": "PM_L3_P1_SYS_PUMP", + "BriefDescription": "L3 PF sent with sys scope port 1, counts even retried requests" + }, + {, + "EventCode": "0x1F146", + "EventName": "PM_MRK_DPTEG_FROM_L31_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L3 on the same chip due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2000C", + "EventName": "PM_THRD_ALL_RUN_CYC", + "BriefDescription": "Cycles in which all the threads have the run latch set" + }, + {, + "EventCode": "0xC0BC", + "EventName": "PM_LSU_FLUSH_OTHER", + "BriefDescription": "Other LSU flushes including: Sync (sync ack from L2 caused search of LRQ for oldest snooped load, This will either signal a Precise Flush of the oldest snooped loa or a Flush Next PPC); Data Valid Flush Next (several cases of this, one example is store and reload are lined up such that a store-hit-reload scenario exists and the CDF has already launched and has gotten bad/stale data); Bad Data Valid Flush Next (might be a few cases of this, one example is a larxa (D$ hit) return data and dval but can't allocate to LMQ (LMQ full or other reason). Already gave dval but can't watch it for snoop_hit_larx. Need to take the “bad dval” back and flush all younger ops)" + }, + {, + "EventCode": "0x5094", + "EventName": "PM_IC_MISS_ICBI", + "BriefDescription": "threaded version, IC Misses where we got EA dir hit but no sector valids were on. ICBI took line out" + }, + {, + "EventCode": "0xC8A8", + "EventName": "PM_LSU_FLUSH_ATOMIC", + "BriefDescription": "Quad-word loads (lq) are considered atomic because they always span at least 2 slices. If a snoop or store from another thread changes the data the load is accessing between the 2 or 3 pieces of the lq instruction, the lq will be flushed" + }, + {, + "EventCode": "0x1E04E", + "EventName": "PM_DPTEG_FROM_L2MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L2 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D05E", + "EventName": "PM_BR_CMPL", + "BriefDescription": "Any Branch instruction completed" + }, + {, + "EventCode": "0x260B0", + "EventName": "PM_L3_P0_GRP_PUMP", + "BriefDescription": "L3 PF sent with grp scope port 0, counts even retried requests" + }, + {, + "EventCode": "0x30132", + "EventName": "PM_MRK_VSU_FIN", + "BriefDescription": "VSU marked instr finish" + }, + {, + "EventCode": "0x2D120", + "EventName": "PM_MRK_DATA_FROM_OFF_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a marked load" + }, + {, + "EventCode": "0x1E048", + "EventName": "PM_DPTEG_FROM_ON_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x16086", + "EventName": "PM_L2_SN_M_WR_DONE", + "BriefDescription": "SNP dispatched for a write and was M (true M); for DMA cacheinj this will pulse if rty/push is required (won't pulse if cacheinj is accepted)" + }, + {, + "EventCode": "0x489C", + "EventName": "PM_BR_CORECT_PRED_TAKEN_CMPL", + "BriefDescription": "Conditional Branch Completed in which the HW correctly predicted the direction as taken. Counted at completion time" + }, + {, + "EventCode": "0xF0B8", + "EventName": "PM_LS0_UNALIGNED_ST", + "BriefDescription": "Store instructions whose data crosses a double-word boundary, which causes it to require an additional slice than than what normally would be required of the Store of that size. If the Store wraps from slice 3 to slice 0, thee is an additional 3-cycle penalty" + }, + {, + "EventCode": "0x20132", + "EventName": "PM_MRK_DFU_FIN", + "BriefDescription": "Decimal Unit marked Instruction Finish" + }, + {, + "EventCode": "0x160A6", + "EventName": "PM_TM_SC_CO", + "BriefDescription": "L3 castout TM SC line" + }, + {, + "EventCode": "0xC8B0", + "EventName": "PM_LSU_FLUSH_LHS", + "BriefDescription": "Effective Address alias flush : no EA match but Real Address match. If the data has not yet been returned for this load, the instruction will just be rejected, but if it has returned data, it will be flushed" + }, + {, + "EventCode": "0x3F150", + "EventName": "PM_MRK_ST_DRAIN_TO_L2DISP_CYC", + "BriefDescription": "cycles to drain st from core to L2" + }, + {, + "EventCode": "0x168A4", + "EventName": "PM_L3_MISS", + "BriefDescription": "L3 Misses (L2 miss also missing L3, including data/instrn/xlate)" + }, + {, + "EventCode": "0xF080", + "EventName": "PM_LSU_STCX_FAIL", + "BriefDescription": "" + }, + {, + "EventCode": "0x30038", + "EventName": "PM_CMPLU_STALL_DMISS_LMEM", + "BriefDescription": "Completion stall due to cache miss that resolves in local memory" + }, + {, + "EventCode": "0x28A4", + "EventName": "PM_MRK_TEND_FAIL", + "BriefDescription": "Nested or not nested tend failed for a marked tend instruction" + }, + {, + "EventCode": "0x100FC", + "EventName": "PM_LD_REF_L1", + "BriefDescription": "All L1 D cache load references counted at finish, gated by reject" + }, + {, + "EventCode": "0xC0A0", + "EventName": "PM_LSU0_FALSE_LHS", + "BriefDescription": "False LHS match detected" + }, + {, + "EventCode": "0x468A8", + "EventName": "PM_SN_MISS", + "BriefDescription": "Any port snooper L3 miss or collision. Up to 4 can happen in a cycle but we only count 1" + }, + {, + "EventCode": "0x36888", + "EventName": "PM_L2_SYS_GUESS_WRONG", + "BriefDescription": "L2 guess system (VGS or RNS) and guess was not correct (ie data ^beyond-group)" + }, + {, + "EventCode": "0x2080", + "EventName": "PM_EE_OFF_EXT_INT", + "BriefDescription": "CyclesMSR[EE] is off and external interrupts are active" + }, + {, + "EventCode": "0xE8B8", + "EventName": "PM_LS3_TM_DISALLOW", + "BriefDescription": "A TM-ineligible instruction tries to execute inside a transaction and the LSU disallows it" + }, + {, + "EventCode": "0x2688E", + "EventName": "PM_TM_FAV_CAUSED_FAIL", + "BriefDescription": "TM Load (fav) caused another thread to fail" + }, + {, + "EventCode": "0x16090", + "EventName": "PM_SN0_BUSY", + "BriefDescription": "SN mach 0 Busy. Used by PMU to sample ave SN lifetime (mach0 used as sample point)" + }, + {, + "EventCode": "0x360AE", + "EventName": "PM_L3_P0_CO_RTY", + "BriefDescription": "L3 CO received retry port 0 (memory only), every retry counted" + }, + {, + "EventCode": "0x168A8", + "EventName": "PM_L3_WI_USAGE", + "BriefDescription": "Lifetime, sample of Write Inject machine 0 valid" + }, + {, + "EventCode": "0x468A2", + "EventName": "PM_L3_LAT_CI_MISS", + "BriefDescription": "L3 Lateral Castins Miss" + }, + {, + "EventCode": "0x4090", + "EventName": "PM_IC_PREF_CANCEL_PAGE", + "BriefDescription": "Prefetch Canceled due to page boundary" + }, + {, + "EventCode": "0xF09C", + "EventName": "PM_SLB_TABLEWALK_CYC", + "BriefDescription": "Cycles when a tablewalk is pending on this thread on the SLB table" + }, + {, + "EventCode": "0x460AA", + "EventName": "PM_L3_P0_CO_L31", + "BriefDescription": "L3 CO to L3.1 (LCO) port 0 with or without data" + }, + {, + "EventCode": "0x2880", + "EventName": "PM_FLUSH_DISP", + "BriefDescription": "Dispatch flush" + }, + {, + "EventCode": "0x168AE", + "EventName": "PM_L3_P1_PF_RTY", + "BriefDescription": "L3 PF received retry port 1, every retry counted" + }, + {, + "EventCode": "0x46082", + "EventName": "PM_L2_ST_DISP", + "BriefDescription": "All successful D-side store dispatches for this thread " + }, + {, + "EventCode": "0x4609E", + "EventName": "PM_L2_INST_MISS", + "BriefDescription": "All successful I-side dispatches that were an L2 miss for this thread (excludes i_l2mru_tch reqs)" + }, + {, + "EventCode": "0xE084", + "EventName": "PM_LS0_ERAT_MISS_PREF", + "BriefDescription": "LS0 Erat miss due to prefetch" + }, + {, + "EventCode": "0x409C", + "EventName": "PM_BR_PRED", + "BriefDescription": "Conditional Branch Executed in which the HW predicted the Direction or Target. Includes taken and not taken and is counted at execution time" + }, + {, + "EventCode": "0x2D144", + "EventName": "PM_MRK_DATA_FROM_L31_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x360A4", + "EventName": "PM_L3_CO_LCO", + "BriefDescription": "Total L3 COs occurred on LCO L3.1 (good cresp, may end up in mem on a retry)" + }, + {, + "EventCode": "0x4890", + "EventName": "PM_IC_PREF_CANCEL_HIT", + "BriefDescription": "Prefetch Canceled due to icache hit" + }, + {, + "EventCode": "0x268A8", + "EventName": "PM_RD_HIT_PF", + "BriefDescription": "RD machine hit L3 PF machine" + }, + {, + "EventCode": "0x16880", + "EventName": "PM_L2_ST", + "BriefDescription": "All successful D-side store dispatches for this thread (L2 miss + L2 hits)" + }, + {, + "EventCode": "0x4098", + "EventName": "PM_IC_DEMAND_L2_BHT_REDIRECT", + "BriefDescription": "L2 I cache demand request due to BHT redirect, branch redirect ( 2 bubbles 3 cycles)" + }, + {, + "EventCode": "0xD0B4", + "EventName": "PM_LSU0_SRQ_S0_VALID_CYC", + "BriefDescription": "Slot 0 of SRQ valid" + }, + {, + "EventCode": "0x160AA", + "EventName": "PM_L3_P0_LCO_NO_DATA", + "BriefDescription": "Dataless L3 LCO sent port 0" + }, + {, + "EventCode": "0x208C", + "EventName": "PM_CLB_HELD", + "BriefDescription": "CLB (control logic block - indicates quadword fetch block) Hold: Any Reason" + }, + {, + "EventCode": "0xF88C", + "EventName": "PM_LSU3_STORE_REJECT", + "BriefDescription": "All internal store rejects cause the instruction to go back to the SRQ and go to sleep until woken up to try again after the condition has been met" + }, + {, + "EventCode": "0x200F2", + "EventName": "PM_INST_DISP", + "BriefDescription": "# PPC Dispatched" + }, + {, + "EventCode": "0x4E05E", + "EventName": "PM_TM_OUTER_TBEGIN_DISP", + "BriefDescription": "Number of outer tbegin instructions dispatched. The dispatch unit determines whether the tbegin instruction is outer or nested. This is a speculative count, which includes flushed instructions" + }, + {, + "EventCode": "0x2D018", + "EventName": "PM_CMPLU_STALL_EXEC_UNIT", + "BriefDescription": "Completion stall due to execution units (FXU/VSU/CRU)" + }, + {, + "EventCode": "0x20B0", + "EventName": "PM_LSU_FLUSH_NEXT", + "BriefDescription": "LSU flush next reported at flush time. Sometimes these also come with an exception" + }, + {, + "EventCode": "0x3880", + "EventName": "PM_ISU2_ISS_HOLD_ALL", + "BriefDescription": "All ISU rejects" + }, + {, + "EventCode": "0x46882", + "EventName": "PM_L2_ST_HIT", + "BriefDescription": "All successful D-side store dispatches for this thread that were L2 hits" + }, + {, + "EventCode": "0x360A8", + "EventName": "PM_L3_CO", + "BriefDescription": "L3 castout occurring (does not include casthrough or log writes (cinj/dmaw))" + }, + {, + "EventCode": "0x368A4", + "EventName": "PM_L3_CINJ", + "BriefDescription": "L3 castin of cache inject" + }, + {, + "EventCode": "0xC890", + "EventName": "PM_LSU_NCST", + "BriefDescription": "Asserts when a i=1 store op is sent to the nest. No record of issue pipe (LS0/LS1) is maintained so this is for both pipes. Probably don't need separate LS0 and LS1" + }, + {, + "EventCode": "0xD880", + "EventName": "PM_LSU1_SET_MPRED", + "BriefDescription": "Set prediction(set-p) miss. The entry was not found in the Set prediction table" + }, + {, + "EventCode": "0xD0B8", + "EventName": "PM_LSU_LMQ_FULL_CYC", + "BriefDescription": "Counts the number of cycles the LMQ is full" + }, + {, + "EventCode": "0x168B2", + "EventName": "PM_L3_GRP_GUESS_CORRECT", + "BriefDescription": "Initial scope=group (GS or NNS) and data from same group (near) (pred successful)" + }, + {, + "EventCode": "0x48A4", + "EventName": "PM_STOP_FETCH_PENDING_CYC", + "BriefDescription": "Fetching is stopped due to an incoming instruction that will result in a flush" + }, + {, + "EventCode": "0x36884", + "EventName": "PM_L2_RCST_DISP_FAIL_ADDR", + "BriefDescription": "All D-side store dispatch attempts for this thread that failed due to address collision with RC/CO/SN/SQ" + }, + {, + "EventCode": "0x260AC", + "EventName": "PM_L3_PF_USAGE", + "BriefDescription": "Rotating sample of 32 PF actives" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json new file mode 100644 index 000000000000..bc2db636dabf --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/pipeline.json @@ -0,0 +1,552 @@ +[ + {, + "EventCode": "0x4D04C", + "EventName": "PM_DFU_BUSY", + "BriefDescription": "Cycles in which all 4 Decimal Floating Point units are busy. The DFU is running at capacity" + }, + {, + "EventCode": "0x100F6", + "EventName": "PM_IERAT_RELOAD", + "BriefDescription": "Number of I-ERAT reloads" + }, + {, + "EventCode": "0x201E2", + "EventName": "PM_MRK_LD_MISS_L1", + "BriefDescription": "Marked DL1 Demand Miss counted at exec time. Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." + }, + {, + "EventCode": "0x40010", + "EventName": "PM_PMC3_OVERFLOW", + "BriefDescription": "Overflow from counter 3" + }, + {, + "EventCode": "0x1005A", + "EventName": "PM_CMPLU_STALL_DFLONG", + "BriefDescription": "Finish stall because the NTF instruction was a multi-cycle instruction issued to the Decimal Floating Point execution pipe and waiting to finish. Includes decimal floating point instructions + 128 bit binary floating point instructions. Qualified by multicycle" + }, + {, + "EventCode": "0x4D140", + "EventName": "PM_MRK_DATA_FROM_ON_CHIP_CACHE", + "BriefDescription": "The processor's data cache was reloaded either shared or modified data from another core's L2/L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x3F14C", + "EventName": "PM_MRK_DPTEG_FROM_DL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on a different Node or Group (Distant) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1E040", + "EventName": "PM_DPTEG_FROM_L2_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 without conflict due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x24052", + "EventName": "PM_FXU_IDLE", + "BriefDescription": "Cycles in which FXU0, FXU1, FXU2, and FXU3 are all idle" + }, + {, + "EventCode": "0x1E054", + "EventName": "PM_CMPLU_STALL", + "BriefDescription": "Nothing completed and ICT not empty" + }, + {, + "EventCode": "0x2", + "EventName": "PM_INST_CMPL", + "BriefDescription": "Number of PowerPC Instructions that completed." + }, + {, + "EventCode": "0x3D058", + "EventName": "PM_VSU_DP_FSQRT_FDIV", + "BriefDescription": "vector versions of fdiv,fsqrt" + }, + {, + "EventCode": "0x10006", + "EventName": "PM_DISP_HELD", + "BriefDescription": "Dispatch Held" + }, + {, + "EventCode": "0x3D154", + "EventName": "PM_MRK_DERAT_MISS_16M", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 16M" + }, + {, + "EventCode": "0x200F8", + "EventName": "PM_EXT_INT", + "BriefDescription": "external interrupt" + }, + {, + "EventCode": "0x20008", + "EventName": "PM_ICT_EMPTY_CYC", + "BriefDescription": "Cycles in which the ICT is completely empty. No itags are assigned to any thread" + }, + {, + "EventCode": "0x4F146", + "EventName": "PM_MRK_DPTEG_FROM_L21_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L2 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10056", + "EventName": "PM_MEM_READ", + "BriefDescription": "Reads from Memory from this thread (includes data/inst/xlate/l1prefetch/inst prefetch). Includes L4" + }, + {, + "EventCode": "0x3C04C", + "EventName": "PM_DATA_FROM_DL4", + "BriefDescription": "The processor's data cache was reloaded from another chip's L4 on a different Node or Group (Distant) due to a demand load" + }, + {, + "EventCode": "0x4E046", + "EventName": "PM_DPTEG_FROM_L21_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L2 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2E016", + "EventName": "PM_NTC_ISSUE_HELD_ARB", + "BriefDescription": "The NTC instruction is being held at dispatch because it lost arbitration onto the issue pipe to another instruction (from the same thread or a different thread)" + }, + {, + "EventCode": "0x15156", + "EventName": "PM_SYNC_MRK_FX_DIVIDE", + "BriefDescription": "Marked fixed point divide that can cause a synchronous interrupt" + }, + {, + "EventCode": "0x1C056", + "EventName": "PM_DERAT_MISS_4K", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 4K" + }, + {, + "EventCode": "0x2F142", + "EventName": "PM_MRK_DPTEG_FROM_L3_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without dispatch conflicts hit on Mepf state. due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10024", + "EventName": "PM_PMC5_OVERFLOW", + "BriefDescription": "Overflow from counter 5" + }, + {, + "EventCode": "0x2C018", + "EventName": "PM_CMPLU_STALL_DMISS_L21_L31", + "BriefDescription": "Completion stall by Dcache miss which resolved on chip ( excluding local L2/L3)" + }, + {, + "EventCode": "0x4006A", + "EventName": "PM_IERAT_RELOAD_16M", + "BriefDescription": "IERAT Reloaded (Miss) for a 16M page" + }, + {, + "EventCode": "0x4E010", + "EventName": "PM_ICT_NOSLOT_IC_L3MISS", + "BriefDescription": "Ict empty for this thread due to icache misses that were sourced from beyond the local L3. The source could be local/remote/distant memory or another core's cache" + }, + {, + "EventCode": "0x4D01C", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_SYNC", + "BriefDescription": "Dispatch held due to a synchronizing instruction at dispatch" + }, + {, + "EventCode": "0x2D01A", + "EventName": "PM_ICT_NOSLOT_IC_MISS", + "BriefDescription": "Ict empty for this thread due to Icache Miss" + }, + {, + "EventCode": "0x3D152", + "EventName": "PM_MRK_DERAT_MISS_1G", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 1G. Implies radix translation" + }, + {, + "EventCode": "0x4F14A", + "EventName": "PM_MRK_DPTEG_FROM_OFF_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x30058", + "EventName": "PM_TLBIE_FIN", + "BriefDescription": "tlbie finished" + }, + {, + "EventCode": "0x100F8", + "EventName": "PM_ICT_NOSLOT_CYC", + "BriefDescription": "Number of cycles the ICT has no itags assigned to this thread" + }, + {, + "EventCode": "0x3E042", + "EventName": "PM_DPTEG_FROM_L3_DISP_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 with dispatch conflict due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1F140", + "EventName": "PM_MRK_DPTEG_FROM_L2_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 without conflict due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2C05A", + "EventName": "PM_DERAT_MISS_1G", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 1G. Implies radix translation" + }, + {, + "EventCode": "0x1F058", + "EventName": "PM_RADIX_PWC_L2_PTE_FROM_L2", + "BriefDescription": "A Page Table Entry was reloaded to a level 2 page walk cache from the core's L2 data cache. This implies that level 3 and level 4 PWC accesses were not necessary for this translation" + }, + {, + "EventCode": "0x1D14A", + "EventName": "PM_MRK_DATA_FROM_RL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x10050", + "EventName": "PM_CHIP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was chip pump (prediction=correct) for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x45058", + "EventName": "PM_IC_MISS_CMPL", + "BriefDescription": "Non-speculative icache miss, counted at completion" + }, + {, + "EventCode": "0x2D150", + "EventName": "PM_MRK_DERAT_MISS_4K", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 4K" + }, + {, + "EventCode": "0x34058", + "EventName": "PM_ICT_NOSLOT_BR_MPRED_ICMISS", + "BriefDescription": "Ict empty for this thread due to Icache Miss and branch mispred" + }, + {, + "EventCode": "0x10022", + "EventName": "PM_PMC2_SAVED", + "BriefDescription": "PMC2 Rewind Value saved" + }, + {, + "EventCode": "0x2000A", + "EventName": "PM_HV_CYC", + "BriefDescription": "Cycles in which msr_hv is high. Note that this event does not take msr_pr into consideration" + }, + {, + "EventCode": "0x1F144", + "EventName": "PM_MRK_DPTEG_FROM_L3_NO_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without conflict due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x300FC", + "EventName": "PM_DTLB_MISS", + "BriefDescription": "Data PTEG reload" + }, + {, + "EventCode": "0x2D152", + "EventName": "PM_MRK_DERAT_MISS_2M", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 2M. Implies radix translation" + }, + {, + "EventCode": "0x2C046", + "EventName": "PM_DATA_FROM_RL2L3_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a demand load" + }, + {, + "EventCode": "0x20052", + "EventName": "PM_GRP_PUMP_MPRED", + "BriefDescription": "Final Pump Scope (Group) ended up either larger or smaller than Initial Pump Scope for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x3F05A", + "EventName": "PM_RADIX_PWC_L2_PDE_FROM_L3", + "BriefDescription": "A Page Directory Entry was reloaded to a level 2 page walk cache from the core's L3 data cache" + }, + {, + "EventCode": "0x1E04A", + "EventName": "PM_DPTEG_FROM_RL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10064", + "EventName": "PM_ICT_NOSLOT_DISP_HELD_TBEGIN", + "BriefDescription": "the NTC instruction is being held at dispatch because it is a tbegin instruction and there is an older tbegin in the pipeline that must complete before the younger tbegin can dispatch" + }, + {, + "EventCode": "0x2E046", + "EventName": "PM_DPTEG_FROM_RL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4F14C", + "EventName": "PM_MRK_DPTEG_FROM_DMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group (Distant) due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2E042", + "EventName": "PM_DPTEG_FROM_L3_MEPF", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 without dispatch conflicts hit on Mepf state. due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2D012", + "EventName": "PM_CMPLU_STALL_DFU", + "BriefDescription": "Finish stall because the NTF instruction was issued to the Decimal Floating Point execution pipe and waiting to finish. Includes decimal floating point instructions + 128 bit binary floating point instructions. Not qualified by multicycle" + }, + {, + "EventCode": "0x4C04C", + "EventName": "PM_DATA_FROM_DMEM", + "BriefDescription": "The processor's data cache was reloaded from another chip's memory on the same Node or Group (Distant) due to a demand load" + }, + {, + "EventCode": "0x30022", + "EventName": "PM_PMC4_SAVED", + "BriefDescription": "PMC4 Rewind Value saved (matched condition)" + }, + {, + "EventCode": "0x200F4", + "EventName": "PM_RUN_CYC", + "BriefDescription": "Run_cycles" + }, + {, + "EventCode": "0x400F2", + "EventName": "PM_1PLUS_PPC_DISP", + "BriefDescription": "Cycles at least one Instr Dispatched" + }, + {, + "EventCode": "0x3D148", + "EventName": "PM_MRK_DATA_FROM_L21_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another core's L2 on the same chip due to a marked load" + }, + {, + "EventCode": "0x2F146", + "EventName": "PM_MRK_DPTEG_FROM_RL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4E01A", + "EventName": "PM_ICT_NOSLOT_DISP_HELD", + "BriefDescription": "Cycles in which the NTC instruction is held at dispatch for any reason" + }, + {, + "EventCode": "0x401EC", + "EventName": "PM_THRESH_EXC_2048", + "BriefDescription": "Threshold counter exceeded a value of 2048" + }, + {, + "EventCode": "0x35150", + "EventName": "PM_MRK_DATA_FROM_RL2L3_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x3E052", + "EventName": "PM_ICT_NOSLOT_IC_L3", + "BriefDescription": "Ict empty for this thread due to icache misses that were sourced from the local L3" + }, + {, + "EventCode": "0x2405A", + "EventName": "PM_NTC_FIN", + "BriefDescription": "Cycles in which the oldest instruction in the pipeline (NTC) finishes. This event is used to account for cycles in which work is being completed in the CPI stack" + }, + {, + "EventCode": "0x40052", + "EventName": "PM_PUMP_MPRED", + "BriefDescription": "Pump misprediction. Counts across all types of pumps for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x30056", + "EventName": "PM_TM_ABORTS", + "BriefDescription": "Number of TM transactions aborted" + }, + {, + "EventCode": "0x2404C", + "EventName": "PM_INST_FROM_MEMORY", + "BriefDescription": "The processor's Instruction cache was reloaded from a memory location including L4 from local remote or distant due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1C05A", + "EventName": "PM_DERAT_MISS_2M", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 2M. Implies radix translation" + }, + {, + "EventCode": "0x30024", + "EventName": "PM_PMC6_OVERFLOW", + "BriefDescription": "Overflow from counter 6" + }, + {, + "EventCode": "0x10068", + "EventName": "PM_BRU_FIN", + "BriefDescription": "Branch Instruction Finished" + }, + {, + "EventCode": "0x30020", + "EventName": "PM_PMC2_REWIND", + "BriefDescription": "PMC2 Rewind Event (did not match condition)" + }, + {, + "EventCode": "0x40064", + "EventName": "PM_DUMMY2_REMOVE_ME", + "BriefDescription": "Space holder for LS_PC_RELOAD_RA" + }, + {, + "EventCode": "0x3F148", + "EventName": "PM_MRK_DPTEG_FROM_DL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D01E", + "EventName": "PM_ICT_NOSLOT_BR_MPRED", + "BriefDescription": "Ict empty for this thread due to branch mispred" + }, + {, + "EventCode": "0x3405E", + "EventName": "PM_IFETCH_THROTTLE", + "BriefDescription": "Cycles in which Instruction fetch throttle was active." + }, + {, + "EventCode": "0x1F148", + "EventName": "PM_MRK_DPTEG_FROM_ON_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on the same chip due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3E046", + "EventName": "PM_DPTEG_FROM_L21_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another core's L2 on the same chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2F144", + "EventName": "PM_MRK_DPTEG_FROM_L31_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another core's L3 on the same chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4C15C", + "EventName": "PM_MRK_DERAT_MISS_16G", + "BriefDescription": "Marked Data ERAT Miss (Data TLB Access) page size 16G" + }, + {, + "EventCode": "0x14052", + "EventName": "PM_INST_GRP_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (Group) ended up larger than Initial Pump Scope (Chip) for an instruction fetch" + }, + {, + "EventCode": "0xD0A8", + "EventName": "PM_DSLB_MISS", + "BriefDescription": "Data SLB Miss - Total of all segment sizes" + }, + {, + "EventCode": "0x4C058", + "EventName": "PM_MEM_CO", + "BriefDescription": "Memory castouts from this thread" + }, + {, + "EventCode": "0x40004", + "EventName": "PM_FXU_FIN", + "BriefDescription": "The fixed point unit Unit finished an instruction. Instructions that finish may not necessary complete." + }, + {, + "EventCode": "0x2C054", + "EventName": "PM_DERAT_MISS_64K", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 64K" + }, + {, + "EventCode": "0x10018", + "EventName": "PM_IC_DEMAND_CYC", + "BriefDescription": "Icache miss demand cycles" + }, + {, + "EventCode": "0x3C054", + "EventName": "PM_DERAT_MISS_16M", + "BriefDescription": "Data ERAT Miss (Data TLB Access) page size 16M" + }, + {, + "EventCode": "0x2D14E", + "EventName": "PM_MRK_DATA_FROM_L21_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L2 on the same chip due to a marked load" + }, + {, + "EventCode": "0x3405C", + "EventName": "PM_CMPLU_STALL_DPLONG", + "BriefDescription": "Finish stall because the NTF instruction was a scalar multi-cycle instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Qualified by NOT vector AND multicycle" + }, + {, + "EventCode": "0x4D052", + "EventName": "PM_2FLOP_CMPL", + "BriefDescription": "DP vector version of fmul, fsub, fcmp, fsel, fabs, fnabs, fres ,fsqrte, fneg " + }, + {, + "EventCode": "0x1F142", + "EventName": "PM_MRK_DPTEG_FROM_L2", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L2 due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40062", + "EventName": "PM_DUMMY1_REMOVE_ME", + "BriefDescription": "Space holder for L2_PC_PM_MK_LDST_SCOPE_PRED_STATUS" + }, + {, + "EventCode": "0x4C012", + "EventName": "PM_CMPLU_STALL_ERAT_MISS", + "BriefDescription": "Finish stall because the NTF instruction was a load or store that suffered a translation miss" + }, + {, + "EventCode": "0x4D050", + "EventName": "PM_VSU_NON_FLOP_CMPL", + "BriefDescription": "Non FLOP operation completed" + }, + {, + "EventCode": "0x2E012", + "EventName": "PM_TM_TX_PASS_RUN_CYC", + "BriefDescription": "cycles spent in successful transactions" + }, + {, + "EventCode": "0x4D04E", + "EventName": "PM_VSU_FSQRT_FDIV", + "BriefDescription": "four flops operation (fdiv,fsqrt) Scalar Instructions only" + }, + {, + "EventCode": "0x4C120", + "EventName": "PM_MRK_DATA_FROM_L2_MEPF", + "BriefDescription": "The processor's data cache was reloaded from local core's L2 hit without dispatch conflicts on Mepf state. due to a marked load" + }, + {, + "EventCode": "0x10062", + "EventName": "PM_LD_L3MISS_PEND_CYC", + "BriefDescription": "Cycles L3 miss was pending for this thread" + }, + {, + "EventCode": "0x2F14C", + "EventName": "PM_MRK_DPTEG_FROM_MEMORY", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a memory location including L4 from local remote or distant due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x14050", + "EventName": "PM_INST_CHIP_PUMP_CPRED", + "BriefDescription": "Initial and Final Pump Scope was chip pump (prediction=correct) for an instruction fetch" + }, + {, + "EventCode": "0x2000E", + "EventName": "PM_FXU_BUSY", + "BriefDescription": "Cycles in which all 4 FXUs are busy. The FXU is running at capacity" + }, + {, + "EventCode": "0x20066", + "EventName": "PM_TLB_MISS", + "BriefDescription": "TLB Miss (I + D)" + }, + {, + "EventCode": "0x10054", + "EventName": "PM_PUMP_CPRED", + "BriefDescription": "Pump prediction correct. Counts across all types of pumps for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x4D124", + "EventName": "PM_MRK_DATA_FROM_L31_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x400F8", + "EventName": "PM_FLUSH", + "BriefDescription": "Flush (any type)" + }, + {, + "EventCode": "0x30004", + "EventName": "PM_CMPLU_STALL_EMQ_FULL", + "BriefDescription": "Finish stall because the next to finish instruction suffered an ERAT miss and the EMQ was full" + }, + {, + "EventCode": "0x1D154", + "EventName": "PM_MRK_DATA_FROM_L21_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's L2 on the same chip due to a marked load" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/pmc.json b/tools/perf/pmu-events/arch/powerpc/power9/pmc.json new file mode 100644 index 000000000000..3ef8a10aac86 --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/pmc.json @@ -0,0 +1,122 @@ +[ + {, + "EventCode": "0x20036", + "EventName": "PM_BR_2PATH", + "BriefDescription": "Branches that are not strongly biased" + }, + {, + "EventCode": "0x40056", + "EventName": "PM_MEM_LOC_THRESH_LSU_HIGH", + "BriefDescription": "Local memory above threshold for LSU medium" + }, + {, + "EventCode": "0x2C056", + "EventName": "PM_DTLB_MISS_4K", + "BriefDescription": "Data TLB Miss page size 4k" + }, + {, + "EventCode": "0x40118", + "EventName": "PM_MRK_DCACHE_RELOAD_INTV", + "BriefDescription": "Combined Intervention event" + }, + {, + "EventCode": "0x4F148", + "EventName": "PM_MRK_DPTEG_FROM_DL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x301E8", + "EventName": "PM_THRESH_EXC_64", + "BriefDescription": "Threshold counter exceeded a value of 64" + }, + {, + "EventCode": "0x4E04E", + "EventName": "PM_DPTEG_FROM_L3MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L3 due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x40050", + "EventName": "PM_SYS_PUMP_MPRED_RTY", + "BriefDescription": "Final Pump Scope (system) ended up larger than Initial Pump Scope (Chip/Group) for all data types excluding data prefetch (demand load,inst prefetch,inst fetch,xlate)" + }, + {, + "EventCode": "0x1F14E", + "EventName": "PM_MRK_DPTEG_FROM_L2MISS", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a location other than the local core's L2 due to a marked data side request.. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4D018", + "EventName": "PM_CMPLU_STALL_BRU", + "BriefDescription": "Completion stall due to a Branch Unit" + }, + {, + "EventCode": "0x45052", + "EventName": "PM_4FLOP_CMPL", + "BriefDescription": "4 FLOP instruction completed" + }, + {, + "EventCode": "0x3D142", + "EventName": "PM_MRK_DATA_FROM_LMEM", + "BriefDescription": "The processor's data cache was reloaded from the local chip's Memory due to a marked load" + }, + {, + "EventCode": "0x4C01E", + "EventName": "PM_CMPLU_STALL_CRYPTO", + "BriefDescription": "Finish stall because the NTF instruction was routed to the crypto execution pipe and was waiting to finish" + }, + {, + "EventCode": "0x3000C", + "EventName": "PM_FREQ_DOWN", + "BriefDescription": "Power Management: Below Threshold B" + }, + {, + "EventCode": "0x4D128", + "EventName": "PM_MRK_DATA_FROM_LMEM_CYC", + "BriefDescription": "Duration in cycles to reload from the local chip's Memory due to a marked load" + }, + {, + "EventCode": "0x4D054", + "EventName": "PM_8FLOP_CMPL", + "BriefDescription": "8 FLOP instruction completed" + }, + {, + "EventCode": "0x10026", + "EventName": "PM_TABLEWALK_CYC", + "BriefDescription": "Cycles when an instruction tablewalk is active" + }, + {, + "EventCode": "0x2C012", + "EventName": "PM_CMPLU_STALL_DCACHE_MISS", + "BriefDescription": "Finish stall because the NTF instruction was a load that missed the L1 and was waiting for the data to return from the nest" + }, + {, + "EventCode": "0x2E04C", + "EventName": "PM_DPTEG_FROM_MEMORY", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a memory location including L4 from local remote or distant due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x3F142", + "EventName": "PM_MRK_DPTEG_FROM_L3_DISP_CONFLICT", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 with dispatch conflict due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x4F142", + "EventName": "PM_MRK_DPTEG_FROM_L3", + "BriefDescription": "A Page Table Entry was loaded into the TLB from local core's L3 due to a marked data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x10060", + "EventName": "PM_TM_TRANS_RUN_CYC", + "BriefDescription": "run cycles in transactional state" + }, + {, + "EventCode": "0x1E04C", + "EventName": "PM_DPTEG_FROM_LL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from the local chip's L4 cache due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x45050", + "EventName": "PM_1FLOP_CMPL", + "BriefDescription": "one flop (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg) operation completed" + } +] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/translation.json b/tools/perf/pmu-events/arch/powerpc/power9/translation.json new file mode 100644 index 000000000000..8c0f12024afa --- /dev/null +++ b/tools/perf/pmu-events/arch/powerpc/power9/translation.json @@ -0,0 +1,232 @@ +[ + {, + "EventCode": "0x1E", + "EventName": "PM_CYC", + "BriefDescription": "Processor cycles" + }, + {, + "EventCode": "0x30010", + "EventName": "PM_PMC2_OVERFLOW", + "BriefDescription": "Overflow from counter 2" + }, + {, + "EventCode": "0x3C046", + "EventName": "PM_DATA_FROM_L21_SHR", + "BriefDescription": "The processor's data cache was reloaded with Shared (S) data from another core's L2 on the same chip due to a demand load" + }, + {, + "EventCode": "0x4D05C", + "EventName": "PM_DP_QP_FLOP_CMPL", + "BriefDescription": "Double-Precion or Quad-Precision instruction completed" + }, + {, + "EventCode": "0x4E04C", + "EventName": "PM_DPTEG_FROM_DMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group (Distant) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x20016", + "EventName": "PM_ST_FIN", + "BriefDescription": "Store finish count. Includes speculative activity" + }, + {, + "EventCode": "0x44042", + "EventName": "PM_INST_FROM_L3", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1504A", + "EventName": "PM_IPTEG_FROM_RL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x40132", + "EventName": "PM_MRK_LSU_FIN", + "BriefDescription": "lsu marked instr PPC finish" + }, + {, + "EventCode": "0x3C05C", + "EventName": "PM_CMPLU_STALL_VFXU", + "BriefDescription": "Finish stall due to a vector fixed point instruction in the execution pipeline. These instructions get routed to the ALU, ALU2, and DIV pipes" + }, + {, + "EventCode": "0x30066", + "EventName": "PM_LSU_FIN", + "BriefDescription": "LSU Finished a PPC instruction (up to 4 per cycle)" + }, + {, + "EventCode": "0x2011C", + "EventName": "PM_MRK_NTC_CYC", + "BriefDescription": "Cycles during which the marked instruction is next to complete (completion is held up because the marked instruction hasn't completed yet)" + }, + {, + "EventCode": "0x3E048", + "EventName": "PM_DPTEG_FROM_DL2L3_SHR", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Shared (S) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x2E018", + "EventName": "PM_CMPLU_STALL_VFXLONG", + "BriefDescription": "Completion stall due to a long latency vector fixed point instruction (division, square root)" + }, + {, + "EventCode": "0x1C04E", + "EventName": "PM_DATA_FROM_L2MISS_MOD", + "BriefDescription": "The processor's data cache was reloaded from a location other than the local core's L2 due to a demand load" + }, + {, + "EventCode": "0x15048", + "EventName": "PM_IPTEG_FROM_ON_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on the same chip due to a instruction side request" + }, + {, + "EventCode": "0x34046", + "EventName": "PM_INST_FROM_L21_SHR", + "BriefDescription": "The processor's Instruction cache was reloaded with Shared (S) data from another core's L2 on the same chip due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x1E058", + "EventName": "PM_STCX_FAIL", + "BriefDescription": "stcx failed" + }, + {, + "EventCode": "0x20112", + "EventName": "PM_MRK_NTF_FIN", + "BriefDescription": "Marked next to finish instruction finished" + }, + {, + "EventCode": "0x300F0", + "EventName": "PM_ST_MISS_L1", + "BriefDescription": "Store Missed L1" + }, + {, + "EventCode": "0x4C046", + "EventName": "PM_DATA_FROM_L21_MOD", + "BriefDescription": "The processor's data cache was reloaded with Modified (M) data from another core's L2 on the same chip due to a demand load" + }, + {, + "EventCode": "0x2504A", + "EventName": "PM_IPTEG_FROM_RL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on the same Node or Group ( Remote) due to a instruction side request" + }, + {, + "EventCode": "0x2003E", + "EventName": "PM_LSU_LMQ_SRQ_EMPTY_CYC", + "BriefDescription": "Cycles in which the LSU is empty for all threads (lmq and srq are completely empty)" + }, + {, + "EventCode": "0x201E6", + "EventName": "PM_THRESH_EXC_32", + "BriefDescription": "Threshold counter exceeded a value of 32" + }, + {, + "EventCode": "0x4405C", + "EventName": "PM_CMPLU_STALL_VDP", + "BriefDescription": "Finish stall because the NTF instruction was a vector instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Not qualified multicycle. Qualified by vector" + }, + {, + "EventCode": "0x4D010", + "EventName": "PM_PMC1_SAVED", + "BriefDescription": "PMC1 Rewind Value saved" + }, + {, + "EventCode": "0x200FE", + "EventName": "PM_DATA_FROM_L2MISS", + "BriefDescription": "Demand LD - L2 Miss (not L2 hit)" + }, + {, + "EventCode": "0x2D14A", + "EventName": "PM_MRK_DATA_FROM_RL2L3_MOD_CYC", + "BriefDescription": "Duration in cycles to reload with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a marked load" + }, + {, + "EventCode": "0x10028", + "EventName": "PM_STALL_END_ICT_EMPTY", + "BriefDescription": "The number a times the core transitioned from a stall to ICT-empty for this thread" + }, + {, + "EventCode": "0x2504C", + "EventName": "PM_IPTEG_FROM_MEMORY", + "BriefDescription": "A Page Table Entry was loaded into the TLB from a memory location including L4 from local remote or distant due to a instruction side request" + }, + {, + "EventCode": "0x4504A", + "EventName": "PM_IPTEG_FROM_OFF_CHIP_CACHE", + "BriefDescription": "A Page Table Entry was loaded into the TLB either shared or modified data from another core's L2/L3 on a different chip (remote or distant) due to a instruction side request" + }, + {, + "EventCode": "0x1404E", + "EventName": "PM_INST_FROM_L2MISS", + "BriefDescription": "The processor's Instruction cache was reloaded from a location other than the local core's L2 due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x34042", + "EventName": "PM_INST_FROM_L3_DISP_CONFLICT", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 with dispatch conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x4E048", + "EventName": "PM_DPTEG_FROM_DL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on a different Node or Group (Distant), as this chip due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x200F0", + "EventName": "PM_ST_CMPL", + "BriefDescription": "Stores completed from S2Q (2nd-level store queue)." + }, + {, + "EventCode": "0x4E05C", + "EventName": "PM_LSU_REJECT_LHS", + "BriefDescription": "LSU Reject due to LHS (up to 4 per cycle)" + }, + {, + "EventCode": "0x14044", + "EventName": "PM_INST_FROM_L3_NO_CONFLICT", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 without conflict due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x3E04C", + "EventName": "PM_DPTEG_FROM_DL4", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's L4 on a different Node or Group (Distant) due to a data side request. When using Radix Page Translation, this count excludes PDE reloads. Only PTE reloads are included" + }, + {, + "EventCode": "0x1F15E", + "EventName": "PM_MRK_PROBE_NOP_CMPL", + "BriefDescription": "Marked probeNops completed" + }, + {, + "EventCode": "0x20018", + "EventName": "PM_ST_FWD", + "BriefDescription": "Store forwards that finished" + }, + {, + "EventCode": "0x1D142", + "EventName": "PM_MRK_DATA_FROM_L31_ECO_SHR_CYC", + "BriefDescription": "Duration in cycles to reload with Shared (S) data from another core's ECO L3 on the same chip due to a marked load" + }, + {, + "EventCode": "0x24042", + "EventName": "PM_INST_FROM_L3_MEPF", + "BriefDescription": "The processor's Instruction cache was reloaded from local core's L3 without dispatch conflicts hit on Mepf state. due to an instruction fetch (not prefetch)" + }, + {, + "EventCode": "0x25046", + "EventName": "PM_IPTEG_FROM_RL2L3_MOD", + "BriefDescription": "A Page Table Entry was loaded into the TLB with Modified (M) data from another chip's L2 or L3 on the same Node or Group (Remote), as this chip due to a instruction side request" + }, + {, + "EventCode": "0x3504A", + "EventName": "PM_IPTEG_FROM_RMEM", + "BriefDescription": "A Page Table Entry was loaded into the TLB from another chip's memory on the same Node or Group ( Remote) due to a instruction side request" + }, + {, + "EventCode": "0x3C05A", + "EventName": "PM_CMPLU_STALL_VDPLONG", + "BriefDescription": "Finish stall because the NTF instruction was a scalar multi-cycle instruction issued to the Double Precision execution pipe and waiting to finish. Includes binary floating point instructions in 32 and 64 bit binary floating point format. Qualified by NOT vector AND multicycle" + }, + {, + "EventCode": "0x2E01C", + "EventName": "PM_CMPLU_STALL_TLBIE", + "BriefDescription": "Finish stall because the NTF instruction was a tlbie waiting for response from L2" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index d1a12e584c1b..4ea068366c3e 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -34,3 +34,4 @@ GenuineIntel-6-2C,v2,westmereep-dp,core GenuineIntel-6-2C,v2,westmereep-dp,core GenuineIntel-6-25,v2,westmereep-sp,core GenuineIntel-6-2F,v2,westmereex,core +GenuineIntel-6-55,v1,skylakex,core diff --git a/tools/perf/pmu-events/arch/x86/skylakex/cache.json b/tools/perf/pmu-events/arch/x86/skylakex/cache.json new file mode 100644 index 000000000000..b5bc742b6fbc --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/cache.json @@ -0,0 +1,1672 @@ +[ + { + "EventCode": "0x24", + "UMask": "0x21", + "BriefDescription": "Demand Data Read miss L2, no rejects", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_MISS", + "PublicDescription": "Counts the number of demand Data Read requests that miss L2 cache. Only not rejected loads are counted.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x22", + "BriefDescription": "RFO requests that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.RFO_MISS", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x24", + "BriefDescription": "L2 cache misses when fetching instructions", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.CODE_RD_MISS", + "PublicDescription": "Counts L2 cache misses when fetching instructions.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x27", + "BriefDescription": "Demand requests that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_MISS", + "PublicDescription": "Demand requests that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x38", + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.PF_MISS", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x3f", + "BriefDescription": "All requests that miss L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.MISS", + "PublicDescription": "All requests that miss L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x41", + "BriefDescription": "Demand Data Read requests that hit L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.DEMAND_DATA_RD_HIT", + "PublicDescription": "Counts the number of demand Data Read requests that hit L2 cache. Only non rejected loads are counted.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x42", + "BriefDescription": "RFO requests that hit L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.RFO_HIT", + "PublicDescription": "Counts the RFO (Read-for-Ownership) requests that hit L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0x44", + "BriefDescription": "L2 cache hits when fetching instructions, code reads.", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.CODE_RD_HIT", + "PublicDescription": "Counts L2 cache hits when fetching instructions, code reads.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xd8", + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.PF_HIT", + "PublicDescription": "Counts requests from the L1/L2/L3 hardware prefetchers or Load software prefetches that hit L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe1", + "BriefDescription": "Demand Data Read requests", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_DATA_RD", + "PublicDescription": "Counts the number of demand Data Read requests (including requests from L1D hardware prefetchers). These loads may hit or miss L2 cache. Only non rejected loads are counted.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe2", + "BriefDescription": "RFO requests to L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_RFO", + "PublicDescription": "Counts the total number of RFO (read for ownership) requests to L2 cache. L2 RFO requests include both L1D demand RFO misses as well as L1D RFO prefetches.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe4", + "BriefDescription": "L2 code requests", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_CODE_RD", + "PublicDescription": "Counts the total number of L2 code requests.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xe7", + "BriefDescription": "Demand requests to L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_DEMAND_REFERENCES", + "PublicDescription": "Demand requests to L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xf8", + "BriefDescription": "Requests from the L1/L2/L3 hardware prefetchers or Load software prefetches", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.ALL_PF", + "PublicDescription": "Counts the total number of requests from the L2 hardware prefetchers.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x24", + "UMask": "0xff", + "BriefDescription": "All L2 requests", + "Counter": "0,1,2,3", + "EventName": "L2_RQSTS.REFERENCES", + "PublicDescription": "All L2 requests.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x2E", + "UMask": "0x41", + "BriefDescription": "Core-originated cacheable demand requests missed L3", + "Counter": "0,1,2,3", + "EventName": "LONGEST_LAT_CACHE.MISS", + "PublicDescription": "Counts core-originated cacheable requests that miss the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all misses to the L3.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x2E", + "UMask": "0x4f", + "BriefDescription": "Core-originated cacheable demand requests that refer to L3", + "Counter": "0,1,2,3", + "EventName": "LONGEST_LAT_CACHE.REFERENCE", + "PublicDescription": "Counts core-originated cacheable requests to the L3 cache (Longest Latency cache). Requests include data and code reads, Reads-for-Ownership (RFOs), speculative accesses and hardware prefetches from L1 and L2. It does not include all accesses to the L3.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x1", + "BriefDescription": "L1D miss outstandings duration in cycles", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING", + "PublicDescription": "Counts duration of L1D miss outstanding, that is each cycle number of Fill Buffers (FB) outstanding required by Demand Reads. FB either is held by demand loads, or it is held by non-demand loads and gets hit at least once by demand. The valid outstanding interval is defined until the FB deallocation by one of the following ways: from FB allocation, if FB is allocated by demand from the demand Hit FB, if it is allocated by hardware or software prefetch.Note: In the L1D, a Demand Read contains cacheable or noncacheable demand loads, including ones causing cache-line splits and reads due to page walks resulted from any request type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x1", + "BriefDescription": "Cycles with L1D load Misses outstanding.", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts duration of L1D miss outstanding in cycles.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x1", + "BriefDescription": "Cycles with L1D load Misses outstanding from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.PENDING_CYCLES_ANY", + "AnyThread": "1", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x48", + "UMask": "0x2", + "BriefDescription": "Number of times a request needed a FB entry but there was no entry available for it. That is the FB unavailability was dominant reason for blocking the request. A request includes cacheable/uncacheable demands that is load, store or SW prefetch.", + "Counter": "0,1,2,3", + "EventName": "L1D_PEND_MISS.FB_FULL", + "PublicDescription": "Number of times a request needed a FB (Fill Buffer) entry but there was no entry available for it. A request includes cacheable/uncacheable demands that are load, store or SW prefetch instructions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x51", + "UMask": "0x1", + "BriefDescription": "L1D data line replacements", + "Counter": "0,1,2,3", + "EventName": "L1D.REPLACEMENT", + "PublicDescription": "Counts L1D data line replacements including opportunistic replacements, and replacements that require stall-for-replace or block-for-replace.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x1", + "BriefDescription": "Offcore outstanding Demand Data Read transactions in uncore queue.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD", + "PublicDescription": "Counts the number of offcore outstanding Demand Data Read transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor. See the corresponding Umask under OFFCORE_REQUESTS.Note: A prefetch promoted to Demand is counted from the promotion point.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x1", + "BriefDescription": "Cycles when offcore outstanding Demand Data Read transactions are present in SuperQueue (SQ), queue to uncore", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_DATA_RD", + "CounterMask": "1", + "PublicDescription": "Counts cycles when offcore outstanding Demand Data Read transactions are present in the super queue (SQ). A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x1", + "BriefDescription": "Cycles with at least 6 offcore outstanding Demand Data Read transactions in uncore queue.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_DATA_RD_GE_6", + "CounterMask": "6", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x2", + "BriefDescription": "Offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore, every cycle. ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_CODE_RD", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x2", + "BriefDescription": "Cycles with offcore outstanding Code Reads transactions in the SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_CODE_RD", + "CounterMask": "1", + "PublicDescription": "Counts the number of offcore outstanding Code Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x4", + "BriefDescription": "Offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore, every cycle", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.DEMAND_RFO", + "PublicDescription": "Counts the number of offcore outstanding RFO (store) transactions in the super queue (SQ) every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x4", + "BriefDescription": "Cycles with offcore outstanding demand rfo reads transactions in SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DEMAND_RFO", + "CounterMask": "1", + "PublicDescription": "Counts the number of offcore outstanding demand rfo Reads transactions in the super queue every cycle. The 'Offcore outstanding' state of the transaction lasts from the L2 miss until the sending transaction completion to requestor (SQ deallocation). See the corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x8", + "BriefDescription": "Offcore outstanding cacheable Core Data Read transactions in SuperQueue (SQ), queue to uncore", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.ALL_DATA_RD", + "PublicDescription": "Counts the number of offcore outstanding cacheable Core Data Read transactions in the super queue every cycle. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x8", + "BriefDescription": "Cycles when offcore outstanding cacheable Core Data Read transactions are present in SuperQueue (SQ), queue to uncore.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_DATA_RD", + "CounterMask": "1", + "PublicDescription": "Counts cycles when offcore outstanding cacheable Core Data Read transactions are present in the super queue. A transaction is considered to be in the Offcore outstanding state between L2 miss and transaction completion sent to requestor (SQ de-allocation). See corresponding Umask under OFFCORE_REQUESTS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x1", + "BriefDescription": "Demand Data Read requests sent to uncore", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_DATA_RD", + "PublicDescription": "Counts the Demand Data Read requests sent to uncore. Use it in conjunction with OFFCORE_REQUESTS_OUTSTANDING to determine average latency in the uncore.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x2", + "BriefDescription": "Cacheable and noncachaeble code read requests", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_CODE_RD", + "PublicDescription": "Counts both cacheable and non-cacheable code read requests.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x4", + "BriefDescription": "Demand RFO requests including regular RFOs, locks, ItoM", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.DEMAND_RFO", + "PublicDescription": "Counts the demand RFO (read for ownership) requests including regular RFOs, locks, ItoM.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x8", + "BriefDescription": "Demand and prefetch data reads", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.ALL_DATA_RD", + "PublicDescription": "Counts the demand and prefetch data reads. All Core Data Reads include cacheable 'Demands' and L2 prefetchers (not L3 prefetchers). Counting also covers reads due to page walks resulted from any request type.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x80", + "BriefDescription": "Any memory transaction that reached the SQ.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.ALL_REQUESTS", + "PublicDescription": "Counts memory transactions reached the super queue including requests initiated by the core, all L3 prefetches, page walks, etc..", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB2", + "UMask": "0x1", + "BriefDescription": "Offcore requests buffer cannot take more entries for this thread core.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_BUFFER.SQ_FULL", + "PublicDescription": "Counts the number of cases when the offcore requests buffer cannot take more entries for the core. This can happen when the superqueue does not contain eligible entries, or when L1D writeback pending FIFO requests is full.Note: Writeback pending FIFO has six entries.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE", + "PublicDescription": "Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x11", + "BriefDescription": "Retired load instructions that miss the STLB.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.STLB_MISS_LOADS", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x12", + "BriefDescription": "Retired store instructions that miss the STLB.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.STLB_MISS_STORES", + "SampleAfterValue": "100003", + "L1_Hit_Indication": "1", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x21", + "BriefDescription": "Retired load instructions with locked access.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.LOCK_LOADS", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x41", + "BriefDescription": "Retired load instructions that split across a cacheline boundary.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.SPLIT_LOADS", + "PublicDescription": "Counts retired load instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x42", + "BriefDescription": "Retired store instructions that split across a cacheline boundary.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.SPLIT_STORES", + "PublicDescription": "Counts retired store instructions that split across a cacheline boundary.", + "SampleAfterValue": "100003", + "L1_Hit_Indication": "1", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x81", + "BriefDescription": "All retired load instructions.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.ALL_LOADS", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD0", + "UMask": "0x82", + "BriefDescription": "All retired store instructions.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_INST_RETIRED.ALL_STORES", + "SampleAfterValue": "2000003", + "L1_Hit_Indication": "1", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x1", + "BriefDescription": "Retired load instructions with L1 cache hits as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L1_HIT", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L1 data cache. This event includes all SW prefetches and lock instructions regardless of the data source.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x2", + "BriefDescription": "Retired load instructions with L2 cache hits as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L2_HIT", + "PublicDescription": "Retired load instructions with L2 cache hits as data sources.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x4", + "BriefDescription": "Retired load instructions with L3 cache hits as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L3_HIT", + "PublicDescription": "Counts retired load instructions with at least one uop that hit in the L3 cache. ", + "SampleAfterValue": "50021", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x8", + "BriefDescription": "Retired load instructions missed L1 cache as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L1_MISS", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L1 cache.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x10", + "BriefDescription": "Retired load instructions missed L2 cache as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L2_MISS", + "PublicDescription": "Retired load instructions missed L2 cache as data sources.", + "SampleAfterValue": "50021", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x20", + "BriefDescription": "Retired load instructions missed L3 cache as data sources", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.L3_MISS", + "PublicDescription": "Counts retired load instructions with at least one uop that missed in the L3 cache. ", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD1", + "UMask": "0x40", + "BriefDescription": "Retired load instructions which data sources were load missed L1 but hit FB due to preceding miss to the same cache line with data not ready", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_RETIRED.FB_HIT", + "PublicDescription": "Counts retired load instructions with at least one uop was load missed in L1 but hit FB (Fill Buffers) due to preceding miss to the same cache line with data not ready. ", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x1", + "BriefDescription": "Retired load instructions which data sources were L3 hit and cross-core snoop missed in on-pkg core cache.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_MISS", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x2", + "BriefDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HIT", + "PublicDescription": "Retired load instructions which data sources were L3 and cross-core snoop hits in on-pkg core cache.", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x4", + "BriefDescription": "Retired load instructions which data sources were HitM responses from shared L3", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_HITM", + "PublicDescription": "Retired load instructions which data sources were HitM responses from shared L3.", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD2", + "UMask": "0x8", + "BriefDescription": "Retired load instructions which data sources were hits in L3 without snoops required", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_HIT_RETIRED.XSNP_NONE", + "PublicDescription": "Retired load instructions which data sources were hits in L3 without snoops required.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x1", + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from local dram", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.LOCAL_DRAM", + "PublicDescription": "Retired load instructions which data sources missed L3 but serviced from local DRAM.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x2", + "BriefDescription": "Retired load instructions which data sources missed L3 but serviced from remote dram", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_DRAM", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x4", + "BriefDescription": "Retired load instructions whose data sources was remote HITM", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_HITM", + "PublicDescription": "Retired load instructions whose data sources was remote HITM.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD3", + "UMask": "0x8", + "BriefDescription": "Retired load instructions whose data sources was forwarded from a remote cache", + "Data_LA": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_L3_MISS_RETIRED.REMOTE_FWD", + "PublicDescription": "Retired load instructions whose data sources was forwarded from a remote cache.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xD4", + "UMask": "0x4", + "BriefDescription": "Retired instructions with at least 1 uncacheable load or lock.", + "Data_LA": "1", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "MEM_LOAD_MISC_RETIRED.UC", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xF0", + "UMask": "0x40", + "BriefDescription": "L2 writebacks that access L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_TRANS.L2_WB", + "PublicDescription": "Counts L2 writebacks that access L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF1", + "UMask": "0x1f", + "BriefDescription": "L2 cache lines filling L2", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_IN.ALL", + "PublicDescription": "Counts the number of L2 cache lines filling the L2. Counting does not cover rejects.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x1", + "BriefDescription": "Counts the number of lines that are silently dropped by L2 cache when triggered by an L2 cache fill. These lines are typically in Shared state. A non-threaded event.", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.SILENT", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x2", + "BriefDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped ", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.NON_SILENT", + "PublicDescription": "Counts the number of lines that are evicted by L2 cache when triggered by an L2 cache fill. Those lines can be either in modified state or clean state. Modified lines may either be written back to L3 or directly written to memory and not allocated in L3. Clean lines may either be allocated in L3 or dropped.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x4", + "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.USELESS_PREF", + "PublicDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF2", + "UMask": "0x4", + "BriefDescription": "Counts the number of lines that have been hardware prefetched but not used and now evicted by L2 cache", + "Counter": "0,1,2,3", + "EventName": "L2_LINES_OUT.USELESS_HWPF", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xF4", + "UMask": "0x10", + "BriefDescription": "Number of cache line split locks sent to uncore.", + "Counter": "0,1,2,3", + "EventName": "SQ_MISC.SPLIT_LOCK", + "PublicDescription": "Counts the number of cache line split locks sent to the uncore.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that have any response type.", + "MSRValue": "0x0000010001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "DEMAND_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that hit in the L3.", + "MSRValue": "0x3f803c0001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that have any response type.", + "MSRValue": "0x0000010002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "DEMAND_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that hit in the L3.", + "MSRValue": "0x3f803c0002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that have any response type.", + "MSRValue": "0x0000010004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "DEMAND_CODE_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that hit in the L3.", + "MSRValue": "0x3f803c0004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that have any response type.", + "MSRValue": "0x0000010010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L2_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3.", + "MSRValue": "0x3f803c0010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that have any response type.", + "MSRValue": "0x0000010020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L2_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3.", + "MSRValue": "0x3f803c0020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that have any response type.", + "MSRValue": "0x0000010080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L3_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3.", + "MSRValue": "0x3f803c0080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that have any response type.", + "MSRValue": "0x0000010100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L3_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3.", + "MSRValue": "0x3f803c0100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that have any response type.", + "MSRValue": "0x0000010400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "PF_L1D_AND_SW & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3.", + "MSRValue": "0x3f803c0400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that have any response type.", + "MSRValue": "0x0000010490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_PF_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that hit in the L3.", + "MSRValue": "0x3f803c0490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that have any response type.", + "MSRValue": "0x0000010120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_PF_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that hit in the L3.", + "MSRValue": "0x3f803c0120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that have any response type.", + "MSRValue": "0x0000010491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_DATA_RD & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that hit in the L3.", + "MSRValue": "0x3f803c0491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that have any response type.", + "MSRValue": "0x0000010122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.ANY_RESPONSE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that have any response type.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.", + "MSRValue": "0x01003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.NO_SNOOP_NEEDED", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3 and sibling core snoops are not needed as either the core-valid bit is not set or the shared line is present in multiple cores.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x04003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HIT_OTHER_CORE_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "ALL_RFO & L3_HIT & SNOOP_HIT_WITH_FWD", + "MSRValue": "0x08003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.SNOOP_HIT_WITH_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "tbd; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.", + "MSRValue": "0x10003c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.HITM_OTHER_CORE", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3 and the snoop to one of the sibling cores hits the line in M state and the line is forwarded.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that hit in the L3.", + "MSRValue": "0x3f803c0122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_HIT.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that hit in the L3.; Offcore response can be programmed only with a specific pair of event select and counter MSR, and with specific event codes and predefine mask bit value in a dedicated MSR to specify attributes of the offcore transaction.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json b/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json new file mode 100644 index 000000000000..1c09a328df36 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/floating-point.json @@ -0,0 +1,88 @@ +[ + { + "EventCode": "0xC7", + "UMask": "0x1", + "BriefDescription": "Number of SSE/AVX computational scalar double precision floating-point instructions retired. Each count represents 1 computation. Applies to SSE* and AVX* scalar double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x2", + "BriefDescription": "Number of SSE/AVX computational scalar single precision floating-point instructions retired. Each count represents 1 computation. Applies to SSE* and AVX* scalar single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT FM(N)ADD/SUB. FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.SCALAR_SINGLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x4", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed double precision floating-point instructions retired. Each count represents 2 computations. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x8", + "BriefDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired. Each count represents 4 computations. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element. ", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", + "PublicDescription": "Number of SSE/AVX computational 128-bit packed single precision floating-point instructions retired. Each count represents 4 computations. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x10", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed double precision floating-point instructions retired. Each count represents 4 computations. Applies to SSE* and AVX* packed double precision floating-point instructions: ADD SUB MUL DIV MIN MAX SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x20", + "BriefDescription": "Number of SSE/AVX computational 256-bit packed single precision floating-point instructions retired. Each count represents 8 computations. Applies to SSE* and AVX* packed single precision floating-point instructions: ADD SUB MUL DIV MIN MAX RCP RSQRT SQRT DPP FM(N)ADD/SUB. DPP and FM(N)ADD/SUB instructions count twice as they perform multiple calculations per element.", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x40", + "BriefDescription": "Number of Packed Double-Precision FP arithmetic instructions (Use operation multiplier of 8)", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE", + "PublicDescription": "Number of Packed Double-Precision FP arithmetic instructions (Use operation multiplier of 8).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC7", + "UMask": "0x80", + "BriefDescription": "Number of Packed Single-Precision FP arithmetic instructions (Use operation multiplier of 16)", + "Counter": "0,1,2,3", + "EventName": "FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE", + "PublicDescription": "Number of Packed Single-Precision FP arithmetic instructions (Use operation multiplier of 16).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCA", + "UMask": "0x1e", + "BriefDescription": "Cycles with any input/output SSE or FP assist", + "Counter": "0,1,2,3", + "EventName": "FP_ASSIST.ANY", + "CounterMask": "1", + "PublicDescription": "Counts cycles with any input and output SSE or x87 FP assist. If an input and output assist are detected on the same cycle the event increments by 1.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/frontend.json b/tools/perf/pmu-events/arch/x86/skylakex/frontend.json new file mode 100644 index 000000000000..40abc0852cd6 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/frontend.json @@ -0,0 +1,482 @@ +[ + { + "EventCode": "0x79", + "UMask": "0x4", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from MITE path", + "Counter": "0,1,2,3", + "EventName": "IDQ.MITE_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ. This also means that uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x4", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from MITE path", + "Counter": "0,1,2,3", + "EventName": "IDQ.MITE_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the MITE path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x8", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path", + "Counter": "0,1,2,3", + "EventName": "IDQ.DSB_UOPS", + "PublicDescription": "Counts the number of uops delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x8", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) from Decode Stream Buffer (DSB) path", + "Counter": "0,1,2,3", + "EventName": "IDQ.DSB_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x10", + "BriefDescription": "Cycles when uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_DSB_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops initiated by Decode Stream Buffer (DSB) are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x18", + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering 4 Uops", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_DSB_CYCLES_4_UOPS", + "CounterMask": "4", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x18", + "BriefDescription": "Cycles Decode Stream Buffer (DSB) is delivering any Uop", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_DSB_CYCLES_ANY_UOPS", + "CounterMask": "1", + "PublicDescription": "Counts the number of cycles uops were delivered to Instruction Decode Queue (IDQ) from the Decode Stream Buffer (DSB) path. Count includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x20", + "BriefDescription": "Uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_MITE_UOPS", + "PublicDescription": "Counts the number of uops initiated by MITE and delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x24", + "BriefDescription": "Cycles MITE is delivering 4 Uops", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_MITE_CYCLES_4_UOPS", + "CounterMask": "4", + "PublicDescription": "Counts the number of cycles 4 uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x24", + "BriefDescription": "Cycles MITE is delivering any Uop", + "Counter": "0,1,2,3", + "EventName": "IDQ.ALL_MITE_CYCLES_ANY_UOPS", + "CounterMask": "1", + "PublicDescription": "Counts the number of cycles uops were delivered to the Instruction Decode Queue (IDQ) from the MITE (legacy decode pipeline) path. Counting includes uops that may 'bypass' the IDQ. During these cycles uops are not being delivered from the Decode Stream Buffer (DSB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x30", + "BriefDescription": "Cycles when uops are being delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which uops are being delivered to Instruction Decode Queue (IDQ) while the Microcode Sequencer (MS) is busy. Counting includes uops that may 'bypass' the IDQ. Uops maybe initiated by Decode Stream Buffer (DSB) or MITE.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "EventCode": "0x79", + "UMask": "0x30", + "BriefDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_SWITCHES", + "CounterMask": "1", + "PublicDescription": "Number of switches from DSB (Decode Stream Buffer) or MITE (legacy decode pipeline) to the Microcode Sequencer.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x79", + "UMask": "0x30", + "BriefDescription": "Uops delivered to Instruction Decode Queue (IDQ) while Microcode Sequenser (MS) is busy", + "Counter": "0,1,2,3", + "EventName": "IDQ.MS_UOPS", + "PublicDescription": "Counts the total number of uops delivered by the Microcode Sequencer (MS). Any instruction over 4 uops will be delivered by the MS. Some instructions such as transcendentals may additionally generate uops from the MS.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x80", + "UMask": "0x4", + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache miss.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_16B.IFDATA_STALL", + "PublicDescription": "Cycles where a code line fetch is stalled due to an L1 instruction cache miss. The legacy decode pipeline works at a 16 Byte granularity.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x83", + "UMask": "0x1", + "BriefDescription": "Instruction fetch tag lookups that hit in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_HIT", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x83", + "UMask": "0x2", + "BriefDescription": "Instruction fetch tag lookups that miss in the instruction cache (L1I). Counts at 64-byte cache-line granularity.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_MISS", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x83", + "UMask": "0x4", + "BriefDescription": "Cycles where a code fetch is stalled due to L1 instruction cache tag miss.", + "Counter": "0,1,2,3", + "EventName": "ICACHE_64B.IFTAG_STALL", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Uops not delivered to Resource Allocation Table (RAT) per thread when backend of the machine is not stalled", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CORE", + "PublicDescription": "Counts the number of uops not delivered to Resource Allocation Table (RAT) per thread adding \u201c4 \u2013 x\u201d when Resource Allocation Table (RAT) is not stalled and Instruction Decode Queue (IDQ) delivers x uops to Resource Allocation Table (RAT) (where x belongs to {0,1,2,3}). Counting does not cover cases when: a. IDQ-Resource Allocation Table (RAT) pipe serves the other thread. b. Resource Allocation Table (RAT) is stalled for the thread (including uop drops and clear BE conditions). c. Instruction Decode Queue (IDQ) delivers four uops.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles per thread when 4 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_0_UOPS_DELIV.CORE", + "CounterMask": "4", + "PublicDescription": "Counts, on the per-thread basis, cycles when no uops are delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core =4.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles per thread when 3 or more uops are not delivered to Resource Allocation Table (RAT) when backend of the machine is not stalled", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_1_UOP_DELIV.CORE", + "CounterMask": "3", + "PublicDescription": "Counts, on the per-thread basis, cycles when less than 1 uop is delivered to Resource Allocation Table (RAT). IDQ_Uops_Not_Delivered.core >= 3.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles with less than 2 uops delivered by the front end.", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_2_UOP_DELIV.CORE", + "CounterMask": "2", + "PublicDescription": "Cycles with less than 2 uops delivered by the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Cycles with less than 3 uops delivered by the front end.", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_LE_3_UOP_DELIV.CORE", + "CounterMask": "1", + "PublicDescription": "Cycles with less than 3 uops delivered by the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0x9C", + "UMask": "0x1", + "BriefDescription": "Counts cycles FE delivered 4 uops or Resource Allocation Table (RAT) was stalling FE.", + "Counter": "0,1,2,3", + "EventName": "IDQ_UOPS_NOT_DELIVERED.CYCLES_FE_WAS_OK", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xAB", + "UMask": "0x2", + "BriefDescription": "Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles.", + "Counter": "0,1,2,3", + "EventName": "DSB2MITE_SWITCHES.PENALTY_CYCLES", + "PublicDescription": "Counts Decode Stream Buffer (DSB)-to-MITE switch true penalty cycles. These cycles do not include uops routed through because of the switch itself, for example, when Instruction Decode Queue (IDQ) pre-allocation is unavailable, or Instruction Decode Queue (IDQ) is full. SBD-to-MITE switch true penalty cycles happen after the merge mux (MM) receives Decode Stream Buffer (DSB) Sync-indication until receiving the first MITE uop. MM is placed before Instruction Decode Queue (IDQ) to merge uops being fed from the MITE and Decode Stream Buffer (DSB) paths. Decode Stream Buffer (DSB) inserts the Sync-indication whenever a Decode Stream Buffer (DSB)-to-MITE switch occurs.Penalty: A Decode Stream Buffer (DSB) hit followed by a Decode Stream Buffer (DSB) miss can cost up to six cycles in which no uops are delivered to the IDQ. Most often, such switches from the Decode Stream Buffer (DSB) to the legacy pipeline cost 0\u20132 cycles.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced decode stream buffer (DSB - the decoded instruction-cache) miss.", + "PEBS": "1", + "MSRValue": "0x11", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.DSB_MISS", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired Instructions that experienced DSB (Decode stream buffer i.e. the decoded instruction-cache) miss. ", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced Instruction L1 Cache true miss.", + "PEBS": "1", + "MSRValue": "0x12", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.L1I_MISS", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced Instruction L2 Cache true miss.", + "PEBS": "1", + "MSRValue": "0x13", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.L2_MISS", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced iTLB true miss.", + "PEBS": "1", + "MSRValue": "0x14", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.ITLB_MISS", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired Instructions that experienced iTLB (Instruction TLB) true miss.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired Instructions who experienced STLB (2nd level TLB) true miss.", + "PEBS": "1", + "MSRValue": "0x15", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.STLB_MISS", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired Instructions that experienced STLB (2nd level TLB) true miss. ", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x400206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 2 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x200206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_2", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 4 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x400406", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_4", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 8 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x400806", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_8", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 8 cycles. During this period the front-end delivered no uops.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 16 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x401006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_16", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 16 cycles. During this period the front-end delivered no uops.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 32 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x402006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_32", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after a front-end stall of at least 32 cycles. During this period the front-end delivered no uops.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 64 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x404006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_64", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 128 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x408006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_128", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 256 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x410006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_256", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end delivered no uops for a period of 512 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x420006", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_512", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 1 bubble-slot for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x100206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_1", + "MSRIndex": "0x3F7", + "PublicDescription": "Counts retired instructions that are delivered to the back-end after the front-end had at least 1 bubble-slot for a period of 2 cycles. A bubble-slot is an empty issue-pipeline slot while there was no RAT stall.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC6", + "UMask": "0x1", + "BriefDescription": "Retired instructions that are fetched after an interval where the front-end had at least 3 bubble-slots for a period of 2 cycles which was not interrupted by a back-end stall.", + "PEBS": "1", + "MSRValue": "0x300206", + "Counter": "0,1,2,3", + "EventName": "FRONTEND_RETIRED.LATENCY_GE_2_BUBBLES_GE_3", + "MSRIndex": "0x3F7", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/memory.json b/tools/perf/pmu-events/arch/x86/skylakex/memory.json new file mode 100644 index 000000000000..ca22a22c1abd --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/memory.json @@ -0,0 +1,1396 @@ +[ + { + "EventCode": "0x54", + "UMask": "0x1", + "BriefDescription": "Number of times a transactional abort was signaled due to a data conflict on a transactionally accessed address", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_CONFLICT", + "PublicDescription": "Number of times a TSX line had a cache conflict.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x2", + "BriefDescription": "Number of times a transactional abort was signaled due to a data capacity limitation for transactional reads or writes.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_CAPACITY", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x4", + "BriefDescription": "Number of times a HLE transactional region aborted due to a non XRELEASE prefixed instruction writing to an elided lock in the elision buffer", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_STORE_TO_ELIDED_LOCK", + "PublicDescription": "Number of times a TSX Abort was triggered due to a non-release/commit store to lock.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x8", + "BriefDescription": "Number of times an HLE transactional execution aborted due to NoAllocatedElisionBuffer being non-zero.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_NOT_EMPTY", + "PublicDescription": "Number of times a TSX Abort was triggered due to commit but Lock Buffer not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x10", + "BriefDescription": "Number of times an HLE transactional execution aborted due to XRELEASE lock not satisfying the address and value requirements in the elision buffer", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_MISMATCH", + "PublicDescription": "Number of times a TSX Abort was triggered due to release/commit but data and address mismatch.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x20", + "BriefDescription": "Number of times an HLE transactional execution aborted due to an unsupported read alignment from the elision buffer.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.ABORT_HLE_ELISION_BUFFER_UNSUPPORTED_ALIGNMENT", + "PublicDescription": "Number of times a TSX Abort was triggered due to attempting an unsupported alignment from Lock Buffer.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x54", + "UMask": "0x40", + "BriefDescription": "Number of times HLE lock could not be elided due to ElisionBufferAvailable being zero.", + "Counter": "0,1,2,3", + "EventName": "TX_MEM.HLE_ELISION_BUFFER_FULL", + "PublicDescription": "Number of times we could not allocate Lock Buffer.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x1", + "BriefDescription": "Counts the number of times a class of instructions that may cause a transactional abort was executed. Since this is the count of execution, it may not always cause a transactional abort.", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x2", + "BriefDescription": "Counts the number of times a class of instructions (e.g., vzeroupper) that may cause a transactional abort was executed inside a transactional region", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC2", + "PublicDescription": "Unfriendly TSX abort triggered by a vzeroupper instruction.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x4", + "BriefDescription": "Counts the number of times an instruction execution caused the transactional nest count supported to be exceeded", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC3", + "PublicDescription": "Unfriendly TSX abort triggered by a nest count that is too deep.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x8", + "BriefDescription": "Counts the number of times a XBEGIN instruction was executed inside an HLE transactional region.", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC4", + "PublicDescription": "RTM region detected inside HLE.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5d", + "UMask": "0x10", + "BriefDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region", + "Counter": "0,1,2,3", + "EventName": "TX_EXEC.MISC5", + "PublicDescription": "Counts the number of times an HLE XACQUIRE instruction was executed inside an RTM transactional region.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x10", + "BriefDescription": "Counts number of Offcore outstanding Demand Data Read requests that miss L3 cache in the superQ every cycle.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x10", + "BriefDescription": "Cycles with at least 1 Demand Data Read requests who miss L3 cache in the superQ.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.CYCLES_WITH_L3_MISS_DEMAND_DATA_RD", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x60", + "UMask": "0x10", + "BriefDescription": "Cycles with at least 6 Demand Data Read requests that miss L3 cache in the superQ.", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS_OUTSTANDING.L3_MISS_DEMAND_DATA_RD_GE_6", + "CounterMask": "6", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x2", + "BriefDescription": "Cycles while L3 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L3_MISS", + "CounterMask": "2", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x6", + "BriefDescription": "Execution stalls while L3 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L3_MISS", + "CounterMask": "6", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB0", + "UMask": "0x10", + "BriefDescription": "Demand Data Read requests who miss L3 cache", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_REQUESTS.L3_MISS_DEMAND_DATA_RD", + "PublicDescription": "Demand Data Read requests who miss L3 cache.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC3", + "UMask": "0x2", + "BriefDescription": "Counts the number of machine clears due to memory order conflicts.", + "Counter": "0,1,2,3", + "EventName": "MACHINE_CLEARS.MEMORY_ORDERING", + "Errata": "SKL089", + "PublicDescription": "Counts the number of memory ordering Machine Clears detected. Memory Ordering Machine Clears can result from one of the following:a. memory disambiguation,b. external snoop, orc. cross SMT-HW-thread snoop (stores) hitting load buffer.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x1", + "BriefDescription": "Number of times an HLE execution started.", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.START", + "PublicDescription": "Number of times we entered an HLE region. Does not count nested transactions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x2", + "BriefDescription": "Number of times an HLE execution successfully committed", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.COMMIT", + "PublicDescription": "Number of times HLE commit succeeded.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x4", + "BriefDescription": "Number of times an HLE execution aborted due to any reasons (multiple categories may count as one). ", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED", + "PublicDescription": "Number of times HLE abort was triggered.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x8", + "BriefDescription": "Number of times an HLE execution aborted due to various memory events (e.g., read/write capacity and conflicts).", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_MEM", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x10", + "BriefDescription": "Number of times an HLE execution aborted due to hardware timer expiration.", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x20", + "BriefDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.). ", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_UNFRIENDLY", + "PublicDescription": "Number of times an HLE execution aborted due to HLE-unfriendly instructions and certain unfriendly events (such as AD assists etc.).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x40", + "BriefDescription": "Number of times an HLE execution aborted due to incompatible memory type", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an HLE execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC8", + "UMask": "0x80", + "BriefDescription": "Number of times an HLE execution aborted due to unfriendly events (such as interrupts).", + "Counter": "0,1,2,3", + "EventName": "HLE_RETIRED.ABORTED_EVENTS", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x1", + "BriefDescription": "Number of times an RTM execution started.", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.START", + "PublicDescription": "Number of times we entered an RTM region. Does not count nested transactions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x2", + "BriefDescription": "Number of times an RTM execution successfully committed", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.COMMIT", + "PublicDescription": "Number of times RTM commit succeeded.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x4", + "BriefDescription": "Number of times an RTM execution aborted due to any reasons (multiple categories may count as one). ", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED", + "PublicDescription": "Number of times RTM abort was triggered.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x8", + "BriefDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts)", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_MEM", + "PublicDescription": "Number of times an RTM execution aborted due to various memory events (e.g. read/write capacity and conflicts).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x10", + "BriefDescription": "Number of times an RTM execution aborted due to uncommon conditions.", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_TIMER", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x20", + "BriefDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_UNFRIENDLY", + "PublicDescription": "Number of times an RTM execution aborted due to HLE-unfriendly instructions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x40", + "BriefDescription": "Number of times an RTM execution aborted due to incompatible memory type", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_MEMTYPE", + "PublicDescription": "Number of times an RTM execution aborted due to incompatible memory type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC9", + "UMask": "0x80", + "BriefDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt)", + "Counter": "0,1,2,3", + "EventName": "RTM_RETIRED.ABORTED_EVENTS", + "PublicDescription": "Number of times an RTM execution aborted due to none of the previous 4 categories (e.g. interrupt).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 4 cycles.", + "PEBS": "2", + "MSRValue": "0x4", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_4", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 4 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 8 cycles.", + "PEBS": "2", + "MSRValue": "0x8", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_8", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 8 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "50021", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 16 cycles.", + "PEBS": "2", + "MSRValue": "0x10", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_16", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 16 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "20011", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 32 cycles.", + "PEBS": "2", + "MSRValue": "0x20", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_32", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 32 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 64 cycles.", + "PEBS": "2", + "MSRValue": "0x40", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_64", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 64 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "2003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 128 cycles.", + "PEBS": "2", + "MSRValue": "0x80", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_128", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 128 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "1009", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 256 cycles.", + "PEBS": "2", + "MSRValue": "0x100", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_256", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 256 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "503", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xCD", + "UMask": "0x1", + "BriefDescription": "Counts loads when the latency from first dispatch to completion is greater than 512 cycles.", + "PEBS": "2", + "MSRValue": "0x200", + "Counter": "0,1,2,3", + "EventName": "MEM_TRANS_RETIRED.LOAD_LATENCY_GT_512", + "MSRIndex": "0x3F6", + "PublicDescription": "Counts loads when the latency from first dispatch to completion is greater than 512 cycles. Reported latency may be longer than just the memory latency.", + "TakenAlone": "1", + "SampleAfterValue": "101", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss in the L3.", + "MSRValue": "0x3fbc000001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts demand data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000001 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts demand data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss in the L3.", + "MSRValue": "0x3fbc000002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000002 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand data writes (RFOs) that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss in the L3.", + "MSRValue": "0x3fbc000004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand code reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000004 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.DEMAND_CODE_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand code reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss in the L3.", + "MSRValue": "0x3fbc000010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000010 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch (that bring data to L2) data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss in the L3.", + "MSRValue": "0x3fbc000020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000020 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L2_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to L2) RFOs that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss in the L3.", + "MSRValue": "0x3fbc000080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000080 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss in the L3.", + "MSRValue": "0x3fbc000100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000100 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L3_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch (that bring data to LLC only) RFOs that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss in the L3.", + "MSRValue": "0x3fbc000400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000400 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.PF_L1D_AND_SW.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts L1 data cache hardware prefetch requests and software prefetch requests that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss in the L3.", + "MSRValue": "0x3fbc000490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000490 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all prefetch data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss in the L3.", + "MSRValue": "0x3fbc000120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000120 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_PF_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts prefetch RFOs that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss in the L3.", + "MSRValue": "0x3fbc000491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000491 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_DATA_RD.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch data reads that miss the L3 and the data is returned from local dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss in the L3.", + "MSRValue": "0x3fbc000122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.ANY_SNOOP", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss in the L3. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache.", + "MSRValue": "0x083fc00122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HIT_FORWARD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and clean or shared data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the modified data is transferred from remote cache.", + "MSRValue": "0x103fc00122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.REMOTE_HITM", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the modified data is transferred from remote cache. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local or remote dram.", + "MSRValue": "0x063fc00122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local or remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from remote dram.", + "MSRValue": "0x063b800122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_REMOTE_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from remote dram. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + }, + { + "Offcore": "1", + "EventCode": "0xB7, 0xBB", + "UMask": "0x1", + "BriefDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local dram.", + "MSRValue": "0x0604000122 ", + "Counter": "0,1,2,3", + "EventName": "OFFCORE_RESPONSE.ALL_RFO.L3_MISS_LOCAL_DRAM.SNOOP_MISS_OR_NO_FWD", + "MSRIndex": "0x1a6,0x1a7", + "PublicDescription": "Counts all demand & prefetch RFOs that miss the L3 and the data is returned from local dram.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/other.json b/tools/perf/pmu-events/arch/x86/skylakex/other.json new file mode 100644 index 000000000000..70243b0b0586 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/other.json @@ -0,0 +1,72 @@ +[ + { + "EventCode": "0x28", + "UMask": "0x7", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the Non-AVX turbo schedule.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.LVL0_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for baseline license level 0. This includes non-AVX codes, SSE, AVX 128-bit, and low-current AVX 256-bit codes.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x28", + "UMask": "0x18", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX2 turbo schedule.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.LVL1_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 1. This includes high current AVX 256-bit instructions as well as low current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x28", + "UMask": "0x20", + "BriefDescription": "Core cycles where the core was running in a manner where Turbo may be clipped to the AVX512 turbo schedule.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.LVL2_TURBO_LICENSE", + "PublicDescription": "Core cycles where the core was running with power-delivery for license level 2 (introduced in Skylake Server michroarchtecture). This includes high current AVX 512-bit instructions.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x28", + "UMask": "0x40", + "BriefDescription": "Core cycles the core was throttled due to a pending power level request.", + "Counter": "0,1,2,3", + "EventName": "CORE_POWER.THROTTLE", + "PublicDescription": "Core cycles the out-of-order engine was throttled due to a pending power level request.", + "SampleAfterValue": "200003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCB", + "UMask": "0x1", + "BriefDescription": "Number of hardware interrupts received by the processor.", + "Counter": "0,1,2,3", + "EventName": "HW_INTERRUPTS.RECEIVED", + "PublicDescription": "Counts the number of hardware interruptions received by the processor.", + "SampleAfterValue": "203", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xFE", + "UMask": "0x2", + "BriefDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly", + "Counter": "0,1,2,3", + "EventName": "IDI_MISC.WB_UPGRADE", + "PublicDescription": "Counts number of cache lines that are allocated and written back to L3 with the intention that they are more likely to be reused shortly.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xFE", + "UMask": "0x4", + "BriefDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly", + "Counter": "0,1,2,3", + "EventName": "IDI_MISC.WB_DOWNGRADE", + "PublicDescription": "Counts number of cache lines that are dropped and not written back to L3 as they are deemed to be less likely to be reused shortly.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json b/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json new file mode 100644 index 000000000000..0895d1e52a4a --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/pipeline.json @@ -0,0 +1,950 @@ +[ + { + "EventCode": "0x00", + "UMask": "0x1", + "BriefDescription": "Instructions retired from execution.", + "Counter": "Fixed counter 1", + "EventName": "INST_RETIRED.ANY", + "PublicDescription": "Counts the number of instructions retired from execution. For instructions that consist of multiple micro-ops, Counts the retirement of the last micro-op of the instruction. Counting continues during hardware interrupts, traps, and inside interrupt handlers. Notes: INST_RETIRED.ANY is counted by a designated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. INST_RETIRED.ANY_P is counted by a programmable counter and it is an architectural performance event. Counting: Faulting executions of GETSEC/VM entry/VM Exit/MWait will not count as retired instructions.", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 1" + }, + { + "EventCode": "0x00", + "UMask": "0x2", + "BriefDescription": "Core cycles when the thread is not in halt state", + "Counter": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.THREAD", + "PublicDescription": "Counts the number of core cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. This event is a component in many key event ratios. The core frequency may change from time to time due to transitions associated with Enhanced Intel SpeedStep Technology or TM2. For this reason this event may have a changing ratio with regards to time. When the core frequency is constant, this event can approximate elapsed time while the core was not in the halt state. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events.", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 2" + }, + { + "EventCode": "0x00", + "UMask": "0x2", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "Counter": "Fixed counter 2", + "EventName": "CPU_CLK_UNHALTED.THREAD_ANY", + "AnyThread": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 2" + }, + { + "EventCode": "0x00", + "UMask": "0x3", + "BriefDescription": "Reference cycles when the core is not in halt state.", + "Counter": "Fixed counter 3", + "EventName": "CPU_CLK_UNHALTED.REF_TSC", + "PublicDescription": "Counts the number of reference cycles when the core is not in a halt state. The core enters the halt state when it is running the HLT instruction or the MWAIT instruction. This event is not affected by core frequency changes (for example, P states, TM2 transitions) but has the same incrementing frequency as the time stamp counter. This event can approximate elapsed time while the core was not in a halt state. This event has a constant ratio with the CPU_CLK_UNHALTED.REF_XCLK event. It is counted on a dedicated fixed counter, leaving the four (eight when Hyperthreading is disabled) programmable counters available for other events. Note: On all current platforms this event stops counting during 'throttling (TM)' states duty off periods the processor is 'halted'. The counter update is done at a lower clock rate then the core clock the overflow status bit for this counter may appear 'sticky'. After the counter has overflowed and software clears the overflow status bit and resets the counter to less than MAX. The reset value to the counter is not clocked immediately so the overflow status bit will flip 'high (1)' and generate another PMI (if enabled) after which the reset value gets clocked into the counter. Therefore, software will get the interrupt, read the overflow status bit '1 for bit 34 while the counter value is less than MAX. Software should ignore this case.", + "SampleAfterValue": "2000003", + "CounterHTOff": "Fixed counter 3" + }, + { + "EventCode": "0x03", + "UMask": "0x2", + "BriefDescription": "Loads blocked by overlapping with store buffer that cannot be forwarded .", + "Counter": "0,1,2,3", + "EventName": "LD_BLOCKS.STORE_FORWARD", + "PublicDescription": "Counts how many times the load operation got the true Block-on-Store blocking code preventing store forwarding. This includes cases when:a. preceding store conflicts with the load (incomplete overlap),b. store forwarding is impossible due to u-arch limitations,c. preceding lock RMW operations are not forwarded,d. store has the no-forward bit set (uncacheable/page-split/masked stores),e. all-blocking stores are used (mostly, fences and port I/O), and others.The most common case is a load blocked due to its address range overlapping with a preceding smaller uncompleted store. Note: This event does not take into account cases of out-of-SW-control (for example, SbTailHit), unknown physical STA, and cases of blocking loads on store due to being non-WB memory type or a lock. These cases are covered by other events. See the table of not supported store forwards in the Optimization Guide.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x03", + "UMask": "0x8", + "BriefDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use", + "Counter": "0,1,2,3", + "EventName": "LD_BLOCKS.NO_SR", + "PublicDescription": "The number of times that split load operations are temporarily blocked because all resources for handling the split accesses are in use.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x07", + "UMask": "0x1", + "BriefDescription": "False dependencies in MOB due to partial compare on address.", + "Counter": "0,1,2,3", + "EventName": "LD_BLOCKS_PARTIAL.ADDRESS_ALIAS", + "PublicDescription": "Counts false dependencies in MOB when the partial comparison upon loose net check and dependency was resolved by the Enhanced Loose net mechanism. This may not result in high performance penalties. Loose net checks can fail when loads and stores are 4k aliased.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0D", + "UMask": "0x1", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for this thread (e.g. misprediction or memory nuke)", + "Counter": "0,1,2,3", + "EventName": "INT_MISC.RECOVERY_CYCLES", + "PublicDescription": "Core cycles the Resource allocator was stalled due to recovery from an earlier branch misprediction or machine clear event.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0D", + "UMask": "0x1", + "BriefDescription": "Core cycles the allocator was stalled due to recovery from earlier clear event for any thread running on the physical core (e.g. misprediction or memory nuke).", + "Counter": "0,1,2,3", + "EventName": "INT_MISC.RECOVERY_CYCLES_ANY", + "AnyThread": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0D", + "UMask": "0x80", + "BriefDescription": "Cycles the issue-stage is waiting for front-end to fetch from resteered path following branch misprediction or machine clear events.", + "Counter": "0,1,2,3", + "EventName": "INT_MISC.CLEAR_RESTEER_CYCLES", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0E", + "UMask": "0x1", + "BriefDescription": "Uops that Resource Allocation Table (RAT) issues to Reservation Station (RS)", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.ANY", + "PublicDescription": "Counts the number of uops that the Resource Allocation Table (RAT) issues to the Reservation Station (RS).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0x0E", + "UMask": "0x1", + "BriefDescription": "Cycles when Resource Allocation Table (RAT) does not issue Uops to Reservation Station (RS) for the thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.STALL_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which the Resource Allocation Table (RAT) does not issue any Uops to the reservation station (RS) for the current thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0E", + "UMask": "0x2", + "BriefDescription": "Uops inserted at issue-stage in order to preserve upper bits of vector registers.", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.VECTOR_WIDTH_MISMATCH", + "PublicDescription": "Counts the number of Blend Uops issued by the Resource Allocation Table (RAT) to the reservation station (RS) in order to preserve upper bits of vector registers. Starting with the Skylake microarchitecture, these Blend uops are needed since every Intel SSE instruction executed in Dirty Upper State needs to preserve bits 128-255 of the destination register. For more information, refer to \u201cMixing Intel AVX and Intel SSE Code\u201d section of the Optimization Guide.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x0E", + "UMask": "0x20", + "BriefDescription": "Number of slow LEA uops being allocated. A uop is generally considered SlowLea if it has 3 sources (e.g. 2 sources + immediate) regardless if as a result of LEA instruction or not.", + "Counter": "0,1,2,3", + "EventName": "UOPS_ISSUED.SLOW_LEA", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x14", + "UMask": "0x1", + "BriefDescription": "Cycles when divide unit is busy executing divide or square root operations. Accounts for integer and floating-point operations.", + "Counter": "0,1,2,3", + "EventName": "ARITH.DIVIDER_ACTIVE", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x0", + "BriefDescription": "Thread cycles when thread is not in halt state", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.THREAD_P", + "PublicDescription": "This is an architectural event that counts the number of thread cycles while the thread is not in a halt state. The thread enters the halt state when it is running the HLT instruction. The core frequency may change from time to time due to power or thermal throttling. For this reason, this event may have a changing ratio with regards to wall clock time.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x0", + "BriefDescription": "Core cycles when at least one thread on the physical core is not in halt state.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.THREAD_P_ANY", + "AnyThread": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "EventCode": "0x3C", + "UMask": "0x0", + "BriefDescription": "Counts when there is a transition from ring 1, 2 or 3 to ring 0.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.RING0_TRANS", + "CounterMask": "1", + "PublicDescription": "Counts when the Current Privilege Level (CPL) transitions from ring 1, 2 or 3 to ring 0 (Kernel).", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_THREAD_UNHALTED.REF_XCLK_ANY", + "AnyThread": "1", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when the thread is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x1", + "BriefDescription": "Core crystal clock cycles when at least one thread on the physical core is unhalted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.REF_XCLK_ANY", + "AnyThread": "1", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x2", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_THREAD_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x3C", + "UMask": "0x2", + "BriefDescription": "Core crystal clock cycles when this thread is unhalted and the other thread is halted.", + "Counter": "0,1,2,3", + "EventName": "CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE", + "SampleAfterValue": "2503", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x4C", + "UMask": "0x1", + "BriefDescription": "Demand load dispatches that hit L1D fill buffer (FB) allocated for software prefetch.", + "Counter": "0,1,2,3", + "EventName": "LOAD_HIT_PRE.SW_PF", + "PublicDescription": "Counts all not software-prefetch load dispatches that hit the fill buffer (FB) allocated for the software prefetch. It can also be incremented by some lock instructions. So it should only be used with profiling so that the locks can be excluded by ASM (Assembly File) inspection of the nearby instructions.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x5E", + "UMask": "0x1", + "BriefDescription": "Cycles when Reservation Station (RS) is empty for the thread", + "Counter": "0,1,2,3", + "EventName": "RS_EVENTS.EMPTY_CYCLES", + "PublicDescription": "Counts cycles during which the reservation station (RS) is empty for the thread.; Note: In ST-mode, not active thread should drive 0. This is usually caused by severely costly branch mispredictions, or allocator/FE issues.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "Invert": "1", + "EventCode": "0x5E", + "UMask": "0x1", + "BriefDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate Frontend Latency Bound issues.", + "Counter": "0,1,2,3", + "EventName": "RS_EVENTS.EMPTY_END", + "CounterMask": "1", + "PublicDescription": "Counts end of periods where the Reservation Station (RS) was empty. Could be useful to precisely locate front-end Latency Bound issues.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x87", + "UMask": "0x1", + "BriefDescription": "Stalls caused by changing prefix length of the instruction.", + "Counter": "0,1,2,3", + "EventName": "ILD_STALL.LCP", + "PublicDescription": "Counts cycles that the Instruction Length decoder (ILD) stalls occurred due to dynamically changing prefix length of the decoded instruction (by operand size prefix instruction 0x66, address size prefix instruction 0x67 or REX.W for Intel64). Count is proportional to the number of prefixes in a 16B-line. This may result in a three-cycle penalty for each LCP (Length changing prefix) in a 16-byte chunk.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x1", + "BriefDescription": "Cycles per thread when uops are executed in port 0", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_0", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 0.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x2", + "BriefDescription": "Cycles per thread when uops are executed in port 1", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_1", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 1.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x4", + "BriefDescription": "Cycles per thread when uops are executed in port 2", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_2", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 2.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x8", + "BriefDescription": "Cycles per thread when uops are executed in port 3", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_3", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 3.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x10", + "BriefDescription": "Cycles per thread when uops are executed in port 4", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_4", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 4.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x20", + "BriefDescription": "Cycles per thread when uops are executed in port 5", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_5", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 5.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x40", + "BriefDescription": "Cycles per thread when uops are executed in port 6", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_6", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 6.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA1", + "UMask": "0x80", + "BriefDescription": "Cycles per thread when uops are executed in port 7", + "Counter": "0,1,2,3", + "EventName": "UOPS_DISPATCHED_PORT.PORT_7", + "PublicDescription": "Counts, on the per-thread basis, cycles during which at least one uop is dispatched from the Reservation Station (RS) to port 7.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA2", + "UMask": "0x1", + "BriefDescription": "Resource-related stall cycles", + "Counter": "0,1,2,3", + "EventName": "RESOURCE_STALLS.ANY", + "PublicDescription": "Counts resource-related stall cycles. Reasons for stalls can be as follows:a. *any* u-arch structure got full (LB, SB, RS, ROB, BOB, LM, Physical Register Reclaim Table (PRRT), or Physical History Table (PHT) slots).b. *any* u-arch structure got empty (like INT/SIMD FreeLists).c. FPU control word (FPCW), MXCSR.and others. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA2", + "UMask": "0x8", + "BriefDescription": "Cycles stalled due to no store buffers available. (not including draining form sync).", + "Counter": "0,1,2,3", + "EventName": "RESOURCE_STALLS.SB", + "PublicDescription": "Counts allocation stall cycles caused by the store buffer (SB) being full. This counts cycles that the pipeline back-end blocked uop delivery from the front-end.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x1", + "BriefDescription": "Cycles while L2 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L2_MISS", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x4", + "BriefDescription": "Total execution stalls.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_TOTAL", + "CounterMask": "4", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x5", + "BriefDescription": "Execution stalls while L2 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L2_MISS", + "CounterMask": "5", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x8", + "BriefDescription": "Cycles while L1 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_L1D_MISS", + "CounterMask": "8", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0xc", + "BriefDescription": "Execution stalls while L1 cache miss demand load is outstanding.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_L1D_MISS", + "CounterMask": "12", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x10", + "BriefDescription": "Cycles while memory subsystem has an outstanding load.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.CYCLES_MEM_ANY", + "CounterMask": "16", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA3", + "UMask": "0x14", + "BriefDescription": "Execution stalls while memory subsystem has an outstanding load.", + "Counter": "0,1,2,3", + "EventName": "CYCLE_ACTIVITY.STALLS_MEM_ANY", + "CounterMask": "20", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xA6", + "UMask": "0x1", + "BriefDescription": "Cycles where no uops were executed, the Reservation Station was not empty, the Store Buffer was full and there was no outstanding load.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.EXE_BOUND_0_PORTS", + "PublicDescription": "Counts cycles during which no uops were executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x2", + "BriefDescription": "Cycles total of 1 uop is executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.1_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 1 uop was executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x4", + "BriefDescription": "Cycles total of 2 uops are executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.2_PORTS_UTIL", + "PublicDescription": "Counts cycles during which a total of 2 uops were executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x8", + "BriefDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.3_PORTS_UTIL", + "PublicDescription": "Cycles total of 3 uops are executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x10", + "BriefDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station was not empty.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.4_PORTS_UTIL", + "PublicDescription": "Cycles total of 4 uops are executed on all ports and Reservation Station (RS) was not empty.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA6", + "UMask": "0x40", + "BriefDescription": "Cycles where the Store Buffer was full and no outstanding load.", + "Counter": "0,1,2,3", + "EventName": "EXE_ACTIVITY.BOUND_ON_STORES", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA8", + "UMask": "0x1", + "BriefDescription": "Number of Uops delivered by the LSD.", + "Counter": "0,1,2,3", + "EventName": "LSD.UOPS", + "PublicDescription": "Number of uops delivered to the back-end by the LSD(Loop Stream Detector).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA8", + "UMask": "0x1", + "BriefDescription": "Cycles Uops delivered by the LSD, but didn't come from the decoder.", + "Counter": "0,1,2,3", + "EventName": "LSD.CYCLES_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Counts the cycles when at least one uop is delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xA8", + "UMask": "0x1", + "BriefDescription": "Cycles 4 Uops delivered by the LSD, but didn't come from the decoder.", + "Counter": "0,1,2,3", + "EventName": "LSD.CYCLES_4_UOPS", + "CounterMask": "4", + "PublicDescription": "Counts the cycles when 4 uops are delivered by the LSD (Loop-stream detector).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Counts the number of uops to be executed per-thread each cycle.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.THREAD", + "PublicDescription": "Number of uops to be executed per-thread each cycle.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Counts number of cycles no uops were dispatched to be executed on this thread.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.STALL_CYCLES", + "CounterMask": "1", + "PublicDescription": "Counts cycles during which no uops were dispatched from the Reservation Station (RS) per thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 1 uop was executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_1_UOP_EXEC", + "CounterMask": "1", + "PublicDescription": "Cycles where at least 1 uop was executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 2 uops were executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_2_UOPS_EXEC", + "CounterMask": "2", + "PublicDescription": "Cycles where at least 2 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 3 uops were executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_3_UOPS_EXEC", + "CounterMask": "3", + "PublicDescription": "Cycles where at least 3 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x1", + "BriefDescription": "Cycles where at least 4 uops were executed per-thread", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CYCLES_GE_4_UOPS_EXEC", + "CounterMask": "4", + "PublicDescription": "Cycles where at least 4 uops were executed per-thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Number of uops executed on the core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE", + "PublicDescription": "Number of uops executed from any thread.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 1 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_1", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 2 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_2", + "CounterMask": "2", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 3 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_3", + "CounterMask": "3", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles at least 4 micro-op is executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_GE_4", + "CounterMask": "4", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xB1", + "UMask": "0x2", + "BriefDescription": "Cycles with no micro-ops executed from any thread on physical core.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.CORE_CYCLES_NONE", + "CounterMask": "1", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xB1", + "UMask": "0x10", + "BriefDescription": "Counts the number of x87 uops dispatched.", + "Counter": "0,1,2,3", + "EventName": "UOPS_EXECUTED.X87", + "PublicDescription": "Counts the number of x87 uops executed.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC0", + "UMask": "0x0", + "BriefDescription": "Number of instructions retired. General Counter - architectural event", + "Counter": "0,1,2,3", + "EventName": "INST_RETIRED.ANY_P", + "Errata": "SKL091, SKL044", + "PublicDescription": "Counts the number of instructions (EOMs) retired. Counting covers macro-fused instructions individually (that is, increments by two).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC0", + "UMask": "0x1", + "BriefDescription": "Precise instruction retired event with HW to reduce effect of PEBS shadow in IP distribution", + "PEBS": "2", + "Counter": "1", + "EventName": "INST_RETIRED.PREC_DIST", + "Errata": "SKL091, SKL044", + "PublicDescription": "A version of INST_RETIRED that allows for a more unbiased distribution of samples across instructions retired. It utilizes the Precise Distribution of Instructions Retired (PDIR) feature to mitigate some bias in how retired instructions get sampled.", + "SampleAfterValue": "2000003", + "CounterHTOff": "1" + }, + { + "Invert": "1", + "EventCode": "0xC0", + "UMask": "0x1", + "BriefDescription": "Number of cycles using always true condition applied to PEBS instructions retired event.", + "PEBS": "2", + "Counter": "0,2,3", + "EventName": "INST_RETIRED.TOTAL_CYCLES_PS", + "CounterMask": "10", + "Errata": "SKL091, SKL044", + "PublicDescription": "Number of cycles using an always true condition applied to PEBS instructions retired event. (inst_ret< 16)", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,2,3" + }, + { + "EventCode": "0xC1", + "UMask": "0x3f", + "BriefDescription": "Number of times a microcode assist is invoked by HW other than FP-assist. Examples include AD (page Access Dirty) and AVX* related assists.", + "Counter": "0,1,2,3", + "EventName": "OTHER_ASSISTS.ANY", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC2", + "UMask": "0x2", + "BriefDescription": "Retirement slots used.", + "Counter": "0,1,2,3", + "EventName": "UOPS_RETIRED.RETIRE_SLOTS", + "PublicDescription": "Counts the retirement slots used.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xC2", + "UMask": "0x2", + "BriefDescription": "Cycles without actually retired uops.", + "Counter": "0,1,2,3", + "EventName": "UOPS_RETIRED.STALL_CYCLES", + "CounterMask": "1", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts cycles without actually retired uops.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "Invert": "1", + "EventCode": "0xC2", + "UMask": "0x2", + "BriefDescription": "Cycles with less than 10 actually retired uops.", + "Counter": "0,1,2,3", + "EventName": "UOPS_RETIRED.TOTAL_CYCLES", + "CounterMask": "10", + "PublicDescription": "Number of cycles using always true condition (uops_ret < 16) applied to non PEBS uops retired event.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EdgeDetect": "1", + "EventCode": "0xC3", + "UMask": "0x1", + "BriefDescription": "Number of machine clears (nukes) of any type. ", + "Counter": "0,1,2,3", + "EventName": "MACHINE_CLEARS.COUNT", + "CounterMask": "1", + "PublicDescription": "Number of machine clears (nukes) of any type.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC3", + "UMask": "0x4", + "BriefDescription": "Self-modifying code (SMC) detected.", + "Counter": "0,1,2,3", + "EventName": "MACHINE_CLEARS.SMC", + "PublicDescription": "Counts self-modifying code (SMC) detected, which causes a machine clear.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x0", + "BriefDescription": "All (macro) branch instructions retired.", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES", + "Errata": "SKL091", + "PublicDescription": "Counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x1", + "BriefDescription": "Conditional branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.CONDITIONAL", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts conditional branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x2", + "BriefDescription": "Direct and indirect near call instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NEAR_CALL", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts both direct and indirect near call instructions retired.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x4", + "BriefDescription": "All (macro) branch instructions retired. ", + "PEBS": "2", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.ALL_BRANCHES_PEBS", + "Errata": "SKL091", + "PublicDescription": "This is a precise version of BR_INST_RETIRED.ALL_BRANCHES that counts all (macro) branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC4", + "UMask": "0x8", + "BriefDescription": "Return instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NEAR_RETURN", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts return instructions retired.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x10", + "BriefDescription": "Not taken branch instructions retired.", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NOT_TAKEN", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts not taken branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x20", + "BriefDescription": "Taken branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.NEAR_TAKEN", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts taken branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC4", + "UMask": "0x40", + "BriefDescription": "Far branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_INST_RETIRED.FAR_BRANCH", + "Errata": "SKL091", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts far branch instructions retired.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x0", + "BriefDescription": "All mispredicted macro branch instructions retired.", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES", + "PublicDescription": "Counts all the retired branch instructions that were mispredicted by the processor. A branch misprediction occurs when the processor incorrectly predicts the destination of the branch. When the misprediction is discovered at execution, all the instructions executed in the wrong (speculative) path must be discarded, and the processor must start fetching from the correct path.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x1", + "BriefDescription": "Mispredicted conditional branch instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.CONDITIONAL", + "PublicDescription": "This is a non-precise version (that is, does not use PEBS) of the event that counts mispredicted conditional branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x2", + "BriefDescription": "Mispredicted direct and indirect near call instructions retired.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.NEAR_CALL", + "PublicDescription": "Counts both taken and not taken retired mispredicted direct and indirect near calls, including both register and memory indirect.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xC5", + "UMask": "0x4", + "BriefDescription": "Mispredicted macro branch instructions retired. ", + "PEBS": "2", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.ALL_BRANCHES_PEBS", + "PublicDescription": "This is a precise version of BR_MISP_RETIRED.ALL_BRANCHES that counts all mispredicted macro branch instructions retired.", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3" + }, + { + "EventCode": "0xC5", + "UMask": "0x20", + "BriefDescription": "Number of near branch instructions retired that were mispredicted and taken.", + "PEBS": "1", + "Counter": "0,1,2,3", + "EventName": "BR_MISP_RETIRED.NEAR_TAKEN", + "SampleAfterValue": "400009", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xCC", + "UMask": "0x20", + "BriefDescription": "Increments whenever there is an update to the LBR array.", + "Counter": "0,1,2,3", + "EventName": "ROB_MISC_EVENTS.LBR_INSERTS", + "PublicDescription": "Increments when an entry is added to the Last Branch Record (LBR) array (or removed from the array in case of RETURNs in call stack mode). The event requires LBR enable via IA32_DEBUGCTL MSR and branch type selection via MSR_LBR_SELECT.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xE6", + "UMask": "0x1", + "BriefDescription": "Counts the total number when the front end is resteered, mainly when the BPU cannot provide a correct prediction and this is corrected by other branch handling mechanisms at the front end.", + "Counter": "0,1,2,3", + "EventName": "BACLEARS.ANY", + "PublicDescription": "Counts the number of times the front-end is resteered when it finds a branch instruction in a fetch line. This occurs for the first time a branch instruction is fetched or when the branch is not tracked by the BPU (Branch Prediction Unit) anymore.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json b/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json new file mode 100644 index 000000000000..9c7e5f8beee2 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/uncore-memory.json @@ -0,0 +1,172 @@ +[ + { + "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_READ", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x3", + "Unit": "iMC" + }, + { + "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_WRITE", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0xC", + "Unit": "iMC" + }, + { + "BriefDescription": "Memory controller clock ticks", + "Counter": "0,1,2,3", + "EventName": "UNC_M_CLOCKTICKS", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Cycles where DRAM ranks are in power down (CKE) mode", + "Counter": "0,1,2,3", + "EventCode": "0x85", + "EventName": "UNC_M_POWER_CHANNEL_PPD", + "MetricExpr": "(UNC_M_POWER_CHANNEL_PPD / UNC_M_CLOCKTICKS) * 100.", + "MetricName": "power_channel_ppd %", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Cycles Memory is in self refresh power mode", + "Counter": "0,1,2,3", + "EventCode": "0x43", + "EventName": "UNC_M_POWER_SELF_REFRESH", + "MetricExpr": "(UNC_M_POWER_SELF_REFRESH / UNC_M_CLOCKTICKS) * 100.", + "MetricName": "power_self_refresh %", + "PerPkg": "1", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charges due to page misses", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_M_PRE_COUNT.PAGE_MISS", + "PerPkg": "1", + "UMask": "0x1", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charge for reads", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_M_PRE_COUNT.RD", + "PerPkg": "1", + "UMask": "0x4", + "Unit": "iMC" + }, + { + "BriefDescription": "Pre-charge for writes", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_M_PRE_COUNT.WR", + "PerPkg": "1", + "UMask": "0x8", + "Unit": "iMC" + }, + { + "BriefDescription": "DRAM Page Activate commands sent due to a write request", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_M_ACT_COUNT.WR", + "PerPkg": "1", + "PublicDescription": "Counts DRAM Page Activate commands sent on this channel due to a write request to the iMC (Memory Controller). Activate commands are issued to open up a page on the DRAM devices so that it can be read or written to with a CAS (Column Access Select) command.", + "UMask": "0x2", + "Unit": "iMC" + }, + { + "BriefDescription": "All DRAM CAS Commands issued", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "UNC_M_CAS_COUNT.ALL", + "PerPkg": "1", + "PublicDescription": "Counts all CAS (Column Address Select) commands issued to DRAM per memory channel. CAS commands are issued to specify the address to read or write on DRAM, so this event increments for every read and write. This event counts whether AutoPrecharge (which closes the DRAM Page automatically after a read/write) is enabled or not.", + "UMask": "0xF", + "Unit": "iMC" + }, + { + "BriefDescription": "read requests to memory controller. Derived from unc_m_cas_count.rd", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_READ", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x3", + "Unit": "iMC" + }, + { + "BriefDescription": "All DRAM Read CAS Commands issued (does not include underfills) ", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "UNC_M_CAS_COUNT.RD_REG", + "PerPkg": "1", + "PublicDescription": "Counts CAS (Column Access Select) regular read commands issued to DRAM on a per channel basis. CAS commands are issued to specify the address to read or write on DRAM, and this event increments for every regular read. This event only counts regular reads and does not includes underfill reads due to partial write requests. This event counts whether AutoPrecharge (which closes the DRAM Page automatically after a read/write) is enabled or not.", + "UMask": "0x1", + "Unit": "iMC" + }, + { + "BriefDescription": "DRAM Underfill Read CAS Commands issued", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "UNC_M_CAS_COUNT.RD_UNDERFILL", + "PerPkg": "1", + "PublicDescription": "Counts CAS (Column Access Select) underfill read commands issued to DRAM due to a partial write, on a per channel basis. CAS commands are issued to specify the address to read or write on DRAM, and this command counts underfill reads. Partial writes must be completed by first reading in the underfill from DRAM and then merging in the partial write data before writing the full line back to DRAM. This event will generally count about the same as the number of partial writes, but may be slightly less because of partials hitting in the WPQ (due to a previous write request). ", + "UMask": "0x2", + "Unit": "iMC" + }, + { + "BriefDescription": "write requests to memory controller. Derived from unc_m_cas_count.wr", + "Counter": "0,1,2,3", + "EventCode": "0x4", + "EventName": "LLC_MISSES.MEM_WRITE", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0xC", + "Unit": "iMC" + }, + { + "BriefDescription": "Read Pending Queue Allocations", + "Counter": "0,1,2,3", + "EventCode": "0x10", + "EventName": "UNC_M_RPQ_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts the number of read requests allocated into the Read Pending Queue (RPQ). This queue is used to schedule reads out to the memory controller and to track the requests. Requests allocate into the RPQ soon after they enter the memory controller, and need credits for an entry in this buffer before being sent from the CHA to the iMC. The requests deallocate after the read CAS command has been issued to DRAM. This event counts both Isochronous and non-Isochronous requests which were issued to the RPQ. ", + "Unit": "iMC" + }, + { + "BriefDescription": "Read Pending Queue Occupancy", + "Counter": "0,1,2,3", + "EventCode": "0x80", + "EventName": "UNC_M_RPQ_OCCUPANCY", + "PerPkg": "1", + "PublicDescription": "Counts the number of entries in the Read Pending Queue (RPQ) at each cycle. This can then be used to calculate both the average occupancy of the queue (in conjunction with the number of cycles not empty) and the average latency in the queue (in conjunction with the number of allocations). The RPQ is used to schedule reads out to the memory controller and to track the requests. Requests allocate into the RPQ soon after they enter the memory controller, and need credits for an entry in this buffer before being sent from the CHA to the iMC. They deallocate from the RPQ after the CAS command has been issued to memory.", + "Unit": "iMC" + }, + { + "BriefDescription": "Write Pending Queue Allocations", + "Counter": "0,1,2,3", + "EventCode": "0x20", + "EventName": "UNC_M_WPQ_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts the number of writes requests allocated into the Write Pending Queue (WPQ). The WPQ is used to schedule writes out to the memory controller and to track the requests. Requests allocate into the WPQ soon after they enter the memory controller, and need credits for an entry in this buffer before being sent from the CHA to the iMC (Memory Controller). The write requests deallocate after being issued to DRAM. Write requests themselves are able to complete (from the perspective of the rest of the system) as soon they have 'posted' to the iMC.", + "Unit": "iMC" + }, + { + "BriefDescription": "Write Pending Queue Occupancy", + "Counter": "0,1,2,3", + "EventCode": "0x81", + "EventName": "UNC_M_WPQ_OCCUPANCY", + "PerPkg": "1", + "PublicDescription": "Counts the number of entries in the Write Pending Queue (WPQ) at each cycle. This can then be used to calculate both the average queue occupancy (in conjunction with the number of cycles not empty) and the average latency (in conjunction with the number of allocations). The WPQ is used to schedule writes out to the memory controller and to track the requests.", + "Unit": "iMC" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json b/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json new file mode 100644 index 000000000000..de6e70e552e2 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/uncore-other.json @@ -0,0 +1,1156 @@ +[ + { + "BriefDescription": "Uncore cache clock ticks", + "Counter": "0,1,2,3", + "EventName": "UNC_CHA_CLOCKTICKS", + "PerPkg": "1", + "Unit": "CHA" + }, + { + "BriefDescription": "LLC misses - Uncacheable reads (from cpu) . Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_MISSES.UNCACHEABLE", + "Filter": "config1=0x40e33", + "PerPkg": "1", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "MMIO reads. Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_MISSES.MMIO_READ", + "Filter": "config1=0x40040e33", + "PerPkg": "1", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "MMIO writes. Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_MISSES.MMIO_WRITE", + "Filter": "config1=0x40041e33", + "PerPkg": "1", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "Streaming stores (full cache line). Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_REFERENCES.STREAMING_FULL", + "Filter": "config1=0x41833", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "Streaming stores (partial cache line). Derived from unc_cha_tor_inserts.ia_miss", + "Counter": "0,1,2,3", + "EventCode": "0x35", + "EventName": "LLC_REFERENCES.STREAMING_PARTIAL", + "Filter": "config1=0x41a33", + "PerPkg": "1", + "ScaleUnit": "64Bytes", + "UMask": "0x21", + "Unit": "CHA" + }, + { + "BriefDescription": "read requests from home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.READS", + "PerPkg": "1", + "UMask": "0x03", + "Unit": "CHA" + }, + { + "BriefDescription": "read requests from local home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.READS_LOCAL", + "PerPkg": "1", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "read requests from remote home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.READS_REMOTE", + "PerPkg": "1", + "UMask": "0x02", + "Unit": "CHA" + }, + { + "BriefDescription": "write requests from home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.WRITES", + "PerPkg": "1", + "UMask": "0x0C", + "Unit": "CHA" + }, + { + "BriefDescription": "write requests from local home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.WRITES_LOCAL", + "PerPkg": "1", + "UMask": "0x04", + "Unit": "CHA" + }, + { + "BriefDescription": "write requests from remote home agent", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.WRITES_REMOTE", + "PerPkg": "1", + "UMask": "0x08", + "Unit": "CHA" + }, + { + "BriefDescription": "UPI interconnect send bandwidth for payload. Derived from unc_upi_txl_flits.all_data", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UPI_DATA_BANDWIDTH_TX", + "PerPkg": "1", + "ScaleUnit": "7.11E-06Bytes", + "UMask": "0x0F", + "Unit": "UPI LL" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO. Derived from unc_iio_data_req_of_cpu.mem_read.part0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "LLC_MISSES.PCIE_READ", + "FCMask": "0x07", + "Filter": "ch_mask=0x1f", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "MetricName": "LLC_MISSES.PCIE_READ", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO. Derived from unc_iio_data_req_of_cpu.mem_write.part0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "LLC_MISSES.PCIE_WRITE", + "FCMask": "0x07", + "Filter": "ch_mask=0x1f", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "MetricName": "LLC_MISSES.PCIE_WRITE", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART0 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2 +UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "MetricName": "LLC_MISSES.PCIE_WRITE", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 1", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 2", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth writing at IIO, part 3", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "ScaleUnit": "4Bytes", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 0", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "MetricExpr": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART0 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2 + UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "MetricName": "LLC_MISSES.PCIE_READ", + "PerPkg": "1", + "PortMask": "0x01", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 1", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 2", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "PCI Express bandwidth reading at IIO, part 3", + "Counter": "0,1", + "EventCode": "0x83", + "EventName": "UNC_IIO_DATA_REQ_OF_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "ScaleUnit": "4Bytes", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Core Cross Snoops Issued; Multiple Core Requests", + "Counter": "0,1,2,3", + "EventCode": "0x33", + "EventName": "UNC_CHA_CORE_SNP.CORE_GTONE", + "PerPkg": "1", + "PublicDescription": "Counts the number of transactions that trigger a configurable number of cross snoops. Cores are snooped if the transaction looks up the cache and determines that it is necessary based on the operation type and what CoreValid bits are set. For example, if 2 CV bits are set on a data read, the cores must have the data in S state so it is not necessary to snoop them. However, if only 1 CV bit is set the core my have modified the data. If the transaction was an RFO, it would need to invalidate the lines. This event can be filtered based on who triggered the initial snoop(s).", + "UMask": "0x42", + "Unit": "CHA" + }, + { + "BriefDescription": "Core Cross Snoops Issued; Multiple Eviction", + "Counter": "0,1,2,3", + "EventCode": "0x33", + "EventName": "UNC_CHA_CORE_SNP.EVICT_GTONE", + "PerPkg": "1", + "PublicDescription": "Counts the number of transactions that trigger a configurable number of cross snoops. Cores are snooped if the transaction looks up the cache and determines that it is necessary based on the operation type and what CoreValid bits are set. For example, if 2 CV bits are set on a data read, the cores must have the data in S state so it is not necessary to snoop them. However, if only 1 CV bit is set the core my have modified the data. If the transaction was an RFO, it would need to invalidate the lines. This event can be filtered based on who triggered the initial snoop(s).", + "UMask": "0x82", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state lookups; Snoop Not Needed", + "Counter": "0,1,2,3", + "EventCode": "0x53", + "EventName": "UNC_CHA_DIR_LOOKUP.NO_SNP", + "PerPkg": "1", + "PublicDescription": "Counts transactions that looked into the multi-socket cacheline Directory state, and therefore did not send a snoop because the Directory indicated it was not needed", + "UMask": "0x02", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state lookups; Snoop Needed", + "Counter": "0,1,2,3", + "EventCode": "0x53", + "EventName": "UNC_CHA_DIR_LOOKUP.SNP", + "PerPkg": "1", + "PublicDescription": "Counts transactions that looked into the multi-socket cacheline Directory state, and sent one or more snoops, because the Directory indicated it was needed", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state updates; Directory Updated memory write from the HA pipe", + "Counter": "0,1,2,3", + "EventCode": "0x54", + "EventName": "UNC_CHA_DIR_UPDATE.HA", + "PerPkg": "1", + "PublicDescription": "Counts only multi-socket cacheline Directory state updates memory writes issued from the HA pipe. This does not include memory write requests which are for I (Invalid) or E (Exclusive) cachelines.", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Multi-socket cacheline Directory state updates; Directory Updated memory write from TOR pipe", + "Counter": "0,1,2,3", + "EventCode": "0x54", + "EventName": "UNC_CHA_DIR_UPDATE.TOR", + "PerPkg": "1", + "PublicDescription": "Counts only multi-socket cacheline Directory state updates due to memory writes issued from the TOR pipe which are the result of remote transaction hitting the SF/LLC and returning data Core2Core. This does not include memory write requests which are for I (Invalid) or E (Exclusive) cachelines.", + "UMask": "0x02", + "Unit": "CHA" + }, + { + "BriefDescription": "Read request from a remote socket which hit in the HitMe Cache to a line In the E state", + "Counter": "0,1,2,3", + "EventCode": "0x5F", + "EventName": "UNC_CHA_HITME_HIT.EX_RDS", + "PerPkg": "1", + "PublicDescription": "Counts read requests from a remote socket which hit in the HitME cache (used to cache the multi-socket Directory state) to a line in the E(Exclusive) state. This includes the following read opcodes (RdCode, RdData, RdDataMigratory, RdCur, RdInv*, Inv*)", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Normal priority reads issued to the memory controller from the CHA", + "Counter": "0,1,2,3", + "EventCode": "0x59", + "EventName": "UNC_CHA_IMC_READS_COUNT.NORMAL", + "PerPkg": "1", + "PublicDescription": "Counts when a normal (Non-Isochronous) read is issued to any of the memory controller channels from the CHA.", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "CHA to iMC Full Line Writes Issued; Full Line Non-ISOCH", + "Counter": "0,1,2,3", + "EventCode": "0x5B", + "EventName": "UNC_CHA_IMC_WRITES_COUNT.FULL", + "PerPkg": "1", + "PublicDescription": "Counts when a normal (Non-Isochronous) full line write is issued from the CHA to the any of the memory controller channels.", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "Number of times that an RFO hit in S state.", + "Counter": "0,1,2,3", + "EventCode": "0x39", + "EventName": "UNC_CHA_MISC.RFO_HIT_S", + "PerPkg": "1", + "PublicDescription": "Counts when a RFO (the Read for Ownership issued before a write) request hit a cacheline in the S (Shared) state.", + "UMask": "0x08", + "Unit": "CHA" + }, + { + "BriefDescription": "Local requests for exclusive ownership of a cache line without receiving data", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.INVITOE_LOCAL", + "PerPkg": "1", + "PublicDescription": "Counts the total number of requests coming from a unit on this socket for exclusive ownership of a cache line without receiving data (INVITOE) to the CHA.", + "UMask": "0x10", + "Unit": "CHA" + }, + { + "BriefDescription": "Local requests for exclusive ownership of a cache line without receiving data", + "Counter": "0,1,2,3", + "EventCode": "0x50", + "EventName": "UNC_CHA_REQUESTS.INVITOE_REMOTE", + "PerPkg": "1", + "PublicDescription": "Counts the total number of requests coming from a remote socket for exclusive ownership of a cache line without receiving data (INVITOE) to the CHA.", + "UMask": "0x20", + "Unit": "CHA" + }, + { + "BriefDescription": "RspCnflct* Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPCNFLCTS", + "PerPkg": "1", + "PublicDescription": "Counts when a a transaction with the opcode type RspCnflct* Snoop Response was received. This is returned when a snoop finds an existing outstanding transaction in a remote caching agent. This triggers conflict resolution hardware. This covers both the opcode RspCnflct and RspCnflctWbI.", + "UMask": "0x40", + "Unit": "CHA" + }, + { + "BriefDescription": "RspI Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPI", + "PerPkg": "1", + "PublicDescription": "Counts when a transaction with the opcode type RspI Snoop Response was received which indicates the remote cache does not have the data, or when the remote cache silently evicts data (such as when an RFO: the Read for Ownership issued before a write hits non-modified data).", + "UMask": "0x01", + "Unit": "CHA" + }, + { + "BriefDescription": "RspIFwd Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPIFWD", + "PerPkg": "1", + "PublicDescription": "Counts when a a transaction with the opcode type RspIFwd Snoop Response was received which indicates a remote caching agent forwarded the data and the requesting agent is able to acquire the data in E (Exclusive) or M (modified) states. This is commonly returned with RFO (the Read for Ownership issued before a write) transactions. The snoop could have either been to a cacheline in the M,E,F (Modified, Exclusive or Forward) states.", + "UMask": "0x04", + "Unit": "CHA" + }, + { + "BriefDescription": "RspSFwd Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSPSFWD", + "PerPkg": "1", + "PublicDescription": "Counts when a a transaction with the opcode type RspSFwd Snoop Response was received which indicates a remote caching agent forwarded the data but held on to its current copy. This is common for data and code reads that hit in a remote socket in E (Exclusive) or F (Forward) state.", + "UMask": "0x08", + "Unit": "CHA" + }, + { + "BriefDescription": "Rsp*Fwd*WB Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSP_FWD_WB", + "PerPkg": "1", + "PublicDescription": "Counts when a transaction with the opcode type Rsp*Fwd*WB Snoop Response was received which indicates the data was written back to it's home socket, and the cacheline was forwarded to the requestor socket. This snoop response is only used in >= 4 socket systems. It is used when a snoop HITM's in a remote caching agent and it directly forwards data to a requestor, and simultaneously returns data to it's home socket to be written back to memory.", + "UMask": "0x20", + "Unit": "CHA" + }, + { + "BriefDescription": "Rsp*WB Snoop Responses Received", + "Counter": "0,1,2,3", + "EventCode": "0x5C", + "EventName": "UNC_CHA_SNOOP_RESP.RSP_WBWB", + "PerPkg": "1", + "PublicDescription": "Counts when a transaction with the opcode type Rsp*WB Snoop Response was received which indicates which indicates the data was written back to it's home. This is returned when a non-RFO request hits a cacheline in the Modified state. The Cache can either downgrade the cacheline to a S (Shared) or I (Invalid) state depending on how the system has been configured. This reponse will also be sent when a cache requests E (Exclusive) ownership of a cache line without receiving data, because the cache must acquire ownership.", + "UMask": "0x10", + "Unit": "CHA" + }, + { + "BriefDescription": "Clockticks of the IIO Traffic Controller", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_IIO_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Counts clockticks of the 1GHz trafiic controller clock in the IIO unit.", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part0", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part0. In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part1", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part1. In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part2", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part2. In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for 4 bytes made by the CPU to IIO Part3", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every read request for 4 bytes of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part3. In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part0 by the CPU", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part0 by a unit on the main die (generally a core). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part1 by the CPU", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part1 by a unit on the main die (generally a core). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part2 by the CPU ", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part2 by a unit on the main die (generally a core). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of 4 bytes made to IIO Part3 by the CPU ", + "Counter": "2,3", + "EventCode": "0xC0", + "EventName": "UNC_IIO_DATA_REQ_BY_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every write request of 4 bytes of data made to the MMIO space of a card on IIO Part3 by a unit on the main die (generally a core). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part0", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part0. In the general case, part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part1", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part1. In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part2", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part2. In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by the CPU to IIO Part3", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by a unit on the main die (generally a core) to the MMIO space of a card on IIO Part3. In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part0 by the CPU", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part0 by a unit on the main die (generally a core). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part1 by the CPU", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part1 by a unit on the main die (generally a core). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part2 by the CPU ", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part2 by a unit on the main die (generally a core). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made to IIO Part3 by the CPU ", + "Counter": "0,1,2,3", + "EventCode": "0xC1", + "EventName": "UNC_IIO_TXN_REQ_BY_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made to the MMIO space of a card on IIO Part3 by a unit on the main die (generally a core). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part0 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part0 to a unit on the main die (generally memory). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part1 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part1 to a unit on the main die (generally memory). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part2 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part2 to a unit on the main die (generally memory). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Read request for up to a 64 byte transaction is made by IIO Part3 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_READ.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every read request for up to a 64 byte transaction of data made by IIO Part3 to a unit on the main die (generally memory). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x04", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part0 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART0", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x01", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part0 to a unit on the main die (generally memory). In the general case, Part0 refers to a standard PCIe card of any size (x16,x8,x4) that is plugged directly into one of the PCIe slots. Part0 could also refer to any device plugged into the first slot of a PCIe riser card or to a device attached to the IIO unit which starts its use of the bus using lane 0 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part1 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART1", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x02", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part1 to a unit on the main die (generally memory). In the general case, Part1 refers to a x4 PCIe card plugged into the second slot of a PCIe riser card, but it could refer to any x4 device attached to the IIO unit using lanes starting at lane 4 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part2 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART2", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x04", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part2 to a unit on the main die (generally memory). In the general case, Part2 refers to a x4 or x8 PCIe card plugged into the third slot of a PCIe riser card, but it could refer to any x4 or x8 device attached to the IIO unit and using lanes starting at lane 8 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Write request of up to a 64 byte transaction is made by IIO Part3 to Memory", + "Counter": "0,1,2,3", + "EventCode": "0x84", + "EventName": "UNC_IIO_TXN_REQ_OF_CPU.MEM_WRITE.PART3", + "FCMask": "0x07", + "PerPkg": "1", + "PortMask": "0x08", + "PublicDescription": "Counts every write request of up to a 64 byte transaction of data made by IIO Part3 to a unit on the main die (generally memory). In the general case, Part3 refers to a x4 PCIe card plugged into the fourth slot of a PCIe riser card, but it could brefer to any device attached to the IIO unit using the lanes starting at lane 12 of the 16 lanes supported by the bus.", + "UMask": "0x01", + "Unit": "IIO" + }, + { + "BriefDescription": "Traffic in which the M2M to iMC Bypass was not taken", + "Counter": "0,1,2,3", + "EventCode": "0x22", + "EventName": "UNC_M2M_BYPASS_M2M_Egress.NOT_TAKEN", + "PerPkg": "1", + "PublicDescription": "Counts traffic in which the M2M (Mesh to Memory) to iMC (Memory Controller) bypass was not taken", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Cycles when direct to core mode (which bypasses the CHA) was disabled", + "Counter": "0,1,2,3", + "EventCode": "0x24", + "EventName": "UNC_M2M_DIRECT2CORE_NOT_TAKEN_DIRSTATE", + "PerPkg": "1", + "PublicDescription": "Counts cycles when direct to core mode (which bypasses the CHA) was disabled", + "Unit": "M2M" + }, + { + "BriefDescription": "Messages sent direct to core (bypassing the CHA)", + "Counter": "0,1,2,3", + "EventCode": "0x23", + "EventName": "UNC_M2M_DIRECT2CORE_TAKEN", + "PerPkg": "1", + "PublicDescription": "Counts when messages were sent direct to core (bypassing the CHA)", + "Unit": "M2M" + }, + { + "BriefDescription": "Number of reads in which direct to core transaction were overridden", + "Counter": "0,1,2,3", + "EventCode": "0x25", + "EventName": "UNC_M2M_DIRECT2CORE_TXN_OVERRIDE", + "PerPkg": "1", + "PublicDescription": "Counts reads in which direct to core transactions (which would have bypassed the CHA) were overridden", + "Unit": "M2M" + }, + { + "BriefDescription": "Number of reads in which direct to Intel UPI transactions were overridden", + "Counter": "0,1,2,3", + "EventCode": "0x28", + "EventName": "UNC_M2M_DIRECT2UPI_NOT_TAKEN_CREDITS", + "PerPkg": "1", + "PublicDescription": "Counts reads in which direct to Intel Ultra Path Interconnect (UPI) transactions (which would have bypassed the CHA) were overridden", + "Unit": "M2M" + }, + { + "BriefDescription": "Cycles when direct to Intel UPI was disabled", + "Counter": "0,1,2,3", + "EventCode": "0x27", + "EventName": "UNC_M2M_DIRECT2UPI_NOT_TAKEN_DIRSTATE", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the ability to send messages direct to the Intel Ultra Path Interconnect (bypassing the CHA) was disabled", + "Unit": "M2M" + }, + { + "BriefDescription": "Messages sent direct to the Intel UPI", + "Counter": "0,1,2,3", + "EventCode": "0x26", + "EventName": "UNC_M2M_DIRECT2UPI_TAKEN", + "PerPkg": "1", + "PublicDescription": "Counts when messages were sent direct to the Intel Ultra Path Interconnect (bypassing the CHA)", + "Unit": "M2M" + }, + { + "BriefDescription": "Number of reads that a message sent direct2 Intel UPI was overridden", + "Counter": "0,1,2,3", + "EventCode": "0x29", + "EventName": "UNC_M2M_DIRECT2UPI_TXN_OVERRIDE", + "PerPkg": "1", + "PublicDescription": "Counts when a read message that was sent direct to the Intel Ultra Path Interconnect (bypassing the CHA) was overridden", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookups (any state found)", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.ANY", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state, and found the cacheline marked in Any State (A, I, S or unused)", + "UMask": "0x1", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookups (cacheline found in A state) ", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.STATE_A", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state, and found the cacheline marked in the A (SnoopAll) state, indicating the cacheline is stored in another socket in any state, and we must snoop the other sockets to make sure we get the latest data. The data may be stored in any state in the local socket.", + "UMask": "0x8", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookup (cacheline found in I state) ", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.STATE_I", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state , and found the cacheline marked in the I (Invalid) state indicating the cacheline is not stored in another socket, and so there is no need to snoop the other sockets for the latest data. The data may be stored in any state in the local socket.", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory lookup (cacheline found in S state) ", + "Counter": "0,1,2,3", + "EventCode": "0x2D", + "EventName": "UNC_M2M_DIRECTORY_LOOKUP.STATE_S", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) looks into the multi-socket cacheline Directory state , and found the cacheline marked in the S (Shared) state indicating the cacheline is either stored in another socket in the S(hared) state , and so there is no need to snoop the other sockets for the latest data. The data may be stored in any state in the local socket.", + "UMask": "0x4", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from A to I", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.A2I", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from A (SnoopAll) to I (Invalid)", + "UMask": "0x20", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from A to S", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.A2S", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from A (SnoopAll) to S (Shared)", + "UMask": "0x40", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from/to Any state ", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.ANY", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory to a new state", + "UMask": "0x1", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from I to A", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.I2A", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from I (Invalid) to A (SnoopAll)", + "UMask": "0x4", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from I to S", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.I2S", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from I (Invalid) to S (Shared)", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from S to A", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.S2A", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from S (Shared) to A (SnoopAll)", + "UMask": "0x10", + "Unit": "M2M" + }, + { + "BriefDescription": "Multi-socket cacheline Directory update from S to I", + "Counter": "0,1,2,3", + "EventCode": "0x2E", + "EventName": "UNC_M2M_DIRECTORY_UPDATE.S2I", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) updates the multi-socket cacheline Directory state from from S (Shared) to I (Invalid)", + "UMask": "0x8", + "Unit": "M2M" + }, + { + "BriefDescription": "Reads to iMC issued", + "Counter": "0,1,2,3", + "EventCode": "0x37", + "EventName": "UNC_M2M_IMC_READS.ALL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues reads to the iMC (Memory Controller). ", + "UMask": "0x4", + "Unit": "M2M" + }, + { + "BriefDescription": "Reads to iMC issued at Normal Priority (Non-Isochronous)", + "Counter": "0,1,2,3", + "EventCode": "0x37", + "EventName": "UNC_M2M_IMC_READS.NORMAL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues reads to the iMC (Memory Controller). It only counts normal priority non-isochronous reads.", + "UMask": "0x1", + "Unit": "M2M" + }, + { + "BriefDescription": "Writes to iMC issued", + "Counter": "0,1,2,3", + "EventCode": "0x38", + "EventName": "UNC_M2M_IMC_WRITES.ALL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues writes to the iMC (Memory Controller).", + "UMask": "0x10", + "Unit": "M2M" + }, + { + "BriefDescription": "Partial Non-Isochronous writes to the iMC", + "Counter": "0,1,2,3", + "EventCode": "0x38", + "EventName": "UNC_M2M_IMC_WRITES.PARTIAL", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) issues partial writes to the iMC (Memory Controller). It only counts normal priority non-isochronous writes.", + "UMask": "0x2", + "Unit": "M2M" + }, + { + "BriefDescription": "Prefecth requests that got turn into a demand request", + "Counter": "0,1,2,3", + "EventCode": "0x56", + "EventName": "UNC_M2M_PREFCAM_DEMAND_PROMOTIONS", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) promotes a outstanding request in the prefetch queue due to a subsequent demand read request that entered the M2M with the same address. Explanatory Side Note: The Prefecth queue is made of CAM (Content Addressable Memory)", + "Unit": "M2M" + }, + { + "BriefDescription": "Inserts into the Memory Controller Prefetch Queue", + "Counter": "0,1,2,3", + "EventCode": "0x57", + "EventName": "UNC_M2M_PREFCAM_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts when the M2M (Mesh to Memory) recieves a prefetch request and inserts it into its outstanding prefetch queue. Explanatory Side Note: the prefect queue is made from CAM: Content Addressable Memory", + "Unit": "M2M" + }, + { + "BriefDescription": "AD Ingress (from CMS) Queue Inserts", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_M2M_RxC_AD_INSERTS", + "PerPkg": "1", + "PublicDescription": "Counts when the a new entry is Received(RxC) and then added to the AD (Address Ring) Ingress Queue from the CMS (Common Mesh Stop). This is generally used for reads, and ", + "Unit": "M2M" + }, + { + "BriefDescription": "Prefetches generated by the flow control queue of the M3UPI unit.", + "Counter": "0,1,2,3", + "EventCode": "0x29", + "EventName": "UNC_M3UPI_UPI_PREFETCH_SPAWN", + "PerPkg": "1", + "PublicDescription": "Count cases where flow control queue that sits between the Intel Ultra Path Interconnect (UPI) and the mesh spawns a prefetch to the iMC (Memory Controller)", + "Unit": "M3UPI" + }, + { + "BriefDescription": "Clocks of the Intel Ultra Path Interconnect (UPI)", + "Counter": "0,1,2,3", + "EventCode": "0x1", + "EventName": "UNC_UPI_CLOCKTICKS", + "PerPkg": "1", + "PublicDescription": "Counts clockticks of the fixed frequency clock controlling the Intel Ultra Path Interconnect (UPI). This clock runs at1/8th the 'GT/s' speed of the UPI link. For example, a 9.6GT/s link will have a fixed Frequency of 1.2 Ghz.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Data Response packets that go direct to core", + "Counter": "0,1,2,3", + "EventCode": "0x12", + "EventName": "UNC_UPI_DIRECT_ATTEMPTS.D2C", + "PerPkg": "1", + "PublicDescription": "Counts Data Response (DRS) packets that attempted to go direct to core bypassing the CHA.", + "UMask": "0x1", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Data Response packets that go direct to Intel UPI", + "Counter": "0,1,2,3", + "EventCode": "0x12", + "EventName": "UNC_UPI_DIRECT_ATTEMPTS.D2U", + "PerPkg": "1", + "PublicDescription": "Counts Data Response (DRS) packets that attempted to go direct to Intel Ultra Path Interconnect (UPI) bypassing the CHA .", + "UMask": "0x2", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Cycles Intel UPI is in L1 power mode (shutdown)", + "Counter": "0,1,2,3", + "EventCode": "0x21", + "EventName": "UNC_UPI_L1_POWER_CYCLES", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the Intel Ultra Path Interconnect (UPI) is in L1 power mode. L1 is a mode that totally shuts down the UPI link. Link power states are per link and per direction, so for example the Tx direction could be in one state while Rx was in another, this event only coutns when both links are shutdown.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Cycles the Rx of the Intel UPI is in L0p power mode", + "Counter": "0,1,2,3", + "EventCode": "0x25", + "EventName": "UNC_UPI_RxL0P_POWER_CYCLES", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the the receive side (Rx) of the Intel Ultra Path Interconnect(UPI) is in L0p power mode. L0p is a mode where we disable 60% of the UPI lanes, decreasing our bandwidth in order to save power.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs received which bypassed the Slot0 Receive Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x31", + "EventName": "UNC_UPI_RxL_BYPASSED.SLOT0", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot0 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "UMask": "0x1", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs received which bypassed the Slot0 Receive Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x31", + "EventName": "UNC_UPI_RxL_BYPASSED.SLOT1", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the slot1 RxQ buffer (Receive Queue) and passed directly across the BGF and into the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "UMask": "0x2", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs received which bypassed the Slot0 Recieve Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x31", + "EventName": "UNC_UPI_RxL_BYPASSED.SLOT2", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) whcih bypassed the slot2 RxQ buffer (Receive Queue) and passed directly to the Egress. This is a latency optimization, and should generally be the common case. If this value is less than the number of FLITs transfered, it implies that there was queueing getting onto the ring, and thus the transactions saw higher latency.", + "UMask": "0x4", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Valid data FLITs received from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x3", + "EventName": "UNC_UPI_RxL_FLITS.ALL_DATA", + "PerPkg": "1", + "PublicDescription": "Counts valid data FLITs (80 bit FLow control unITs: 64bits of data) received from any of the 3 Intel Ultra Path Interconnect (UPI) Receive Queue slots on this UPI unit.", + "UMask": "0x0F", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Null FLITs received from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x3", + "EventName": "UNC_UPI_RxL_FLITS.ALL_NULL", + "PerPkg": "1", + "PublicDescription": "Counts null FLITs (80 bit FLow control unITs) received from any of the 3 Intel Ultra Path Interconnect (UPI) Receive Queue slots on this UPI unit.", + "UMask": "0x27", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Protocol header and credit FLITs received from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x3", + "EventName": "UNC_UPI_RxL_FLITS.NON_DATA", + "PerPkg": "1", + "PublicDescription": "Counts protocol header and credit FLITs (80 bit FLow control unITs) received from any of the 3 UPI slots on this UPI unit.", + "UMask": "0x97", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Cycles in which the Tx of the Intel Ultra Path Interconnect (UPI) is in L0p power mode", + "Counter": "0,1,2,3", + "EventCode": "0x27", + "EventName": "UNC_UPI_TxL0P_POWER_CYCLES", + "PerPkg": "1", + "PublicDescription": "Counts cycles when the transmit side (Tx) of the Intel Ultra Path Interconnect(UPI) is in L0p power mode. L0p is a mode where we disable 60% of the UPI lanes, decreasing our bandwidth in order to save power.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "FLITs that bypassed the TxL Buffer", + "Counter": "0,1,2,3", + "EventCode": "0x41", + "EventName": "UNC_UPI_TxL_BYPASSED", + "PerPkg": "1", + "PublicDescription": "Counts incoming FLITs (FLow control unITs) which bypassed the TxL(transmit) FLIT buffer and pass directly out the UPI Link. Generally, when data is transmitted across the Intel Ultra Path Interconnect (UPI), it will bypass the TxQ and pass directly to the link. However, the TxQ will be used in L0p (Low Power) mode and (Link Layer Retry) LLR mode, increasing latency to transfer out to the link.", + "Unit": "UPI LL" + }, + { + "BriefDescription": "UPI interconnect send bandwidth for payload. Derived from unc_upi_txl_flits.all_data", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UPI_DATA_BANDWIDTH_TX", + "PerPkg": "1", + "ScaleUnit": "7.11E-06Bytes", + "UMask": "0x0F", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Null FLITs transmitted from any slot", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_UPI_TxL_FLITS.ALL_NULL", + "PerPkg": "1", + "PublicDescription": "Counts null FLITs (80 bit FLow control unITs) transmitted via any of the 3 Intel Ulra Path Interconnect (UPI) slots on this UPI unit.", + "UMask": "0x27", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Idle FLITs transmitted", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_UPI_TxL_FLITS.IDLE", + "PerPkg": "1", + "PublicDescription": "Counts when the Intel Ultra Path Interconnect(UPI) transmits an idle FLIT(80 bit FLow control unITs). Every UPI cycle must be sending either data FLITs, protocol/credit FLITs or idle FLITs.", + "UMask": "0x47", + "Unit": "UPI LL" + }, + { + "BriefDescription": "Protocol header and credit FLITs transmitted across any slot", + "Counter": "0,1,2,3", + "EventCode": "0x2", + "EventName": "UNC_UPI_TxL_FLITS.NON_DATA", + "PerPkg": "1", + "PublicDescription": "Counts protocol header and credit FLITs (80 bit FLow control unITs) transmitted across any of the 3 UPI (Ultra Path Interconnect) slots on this UPI unit.", + "UMask": "0x97", + "Unit": "UPI LL" + } +] diff --git a/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json b/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json new file mode 100644 index 000000000000..70750dab7ead --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/skylakex/virtual-memory.json @@ -0,0 +1,284 @@ +[ + { + "EventCode": "0x08", + "UMask": "0x1", + "BriefDescription": "Load misses in all DTLB levels that cause page walks", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts demand data loads that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x2", + "BriefDescription": "Demand load Miss in all translation lookaside buffer (TLB) levels causes a page walk that completes (4K).", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts demand data loads that caused a completed page walk (4K page size). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x4", + "BriefDescription": "Demand load Miss in all translation lookaside buffer (TLB) levels causes a page walk that completes (2M/4M).", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts demand data loads that caused a completed page walk (2M and 4M page sizes). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x8", + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (1G)", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts load misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0xe", + "BriefDescription": "Load miss in all TLB levels causes a page walk that completes. (All page sizes)", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts demand data loads that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a load. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a load. EPT page walk duration are excluded in Skylake microarchitecture. ", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x10", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a load. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.WALK_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a load.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x08", + "UMask": "0x20", + "BriefDescription": "Loads that miss the DTLB and hit the STLB.", + "Counter": "0,1,2,3", + "EventName": "DTLB_LOAD_MISSES.STLB_HIT", + "PublicDescription": "Counts loads that miss the DTLB (Data TLB) and hit the STLB (Second level TLB).", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x1", + "BriefDescription": "Store misses in all DTLB levels that cause page walks", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts demand data stores that caused a page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels, but the walk need not have completed.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x2", + "BriefDescription": "Store miss in all TLB levels causes a page walk that completes. (4K)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts demand data stores that caused a completed page walk (4K page size). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x4", + "BriefDescription": "Store misses in all DTLB levels that cause completed page walks (2M/4M)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts demand data stores that caused a completed page walk (2M and 4M page sizes). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x8", + "BriefDescription": "Store misses in all DTLB levels that cause completed page walks (1G)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts store misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0xe", + "BriefDescription": "Store misses in all TLB levels causes a page walk that completes. (All page sizes)", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts demand data stores that caused a completed page walk of any page size (4K/2M/4M/1G). This implies it missed in all TLB levels. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for a store. EPT page walk duration are excluded in Skylake microarchitecture. ", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x10", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for a store. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.WALK_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Counts cycles when at least one PMH (Page Miss Handler) is busy with a page walk for a store.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x49", + "UMask": "0x20", + "BriefDescription": "Stores that miss the DTLB and hit the STLB.", + "Counter": "0,1,2,3", + "EventName": "DTLB_STORE_MISSES.STLB_HIT", + "PublicDescription": "Stores that miss the DTLB (Data TLB) and hit the STLB (2nd Level TLB).", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x4F", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a EPT (Extended Page Table) walk for any request type.", + "Counter": "0,1,2,3", + "EventName": "EPT.WALK_PENDING", + "PublicDescription": "Counts cycles for each PMH (Page Miss Handler) that is busy with an EPT (Extended Page Table) walk for any request type.", + "SampleAfterValue": "2000003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x1", + "BriefDescription": "Misses at all ITLB levels that cause page walks", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.MISS_CAUSES_A_WALK", + "PublicDescription": "Counts page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB, but the walk need not have completed.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x2", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (4K)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_4K", + "PublicDescription": "Counts completed page walks (4K page size) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x4", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (2M/4M)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_2M_4M", + "PublicDescription": "Counts completed page walks of any page size (4K/2M/4M/1G) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x8", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (1G)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED_1G", + "PublicDescription": "Counts store misses in all DTLB levels that cause a completed page walk (1G page size). The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0xe", + "BriefDescription": "Code miss in all TLB levels causes a page walk that completes. (All page sizes)", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_COMPLETED", + "PublicDescription": "Counts completed page walks (2M and 4M page sizes) caused by a code fetch. This implies it missed in the ITLB and further levels of TLB. The page walk can end with or without a fault.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x10", + "BriefDescription": "Counts 1 per cycle for each PMH that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake. ", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_PENDING", + "PublicDescription": "Counts 1 per cycle for each PMH (Page Miss Handler) that is busy with a page walk for an instruction fetch request. EPT page walk duration are excluded in Skylake michroarchitecture. ", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x10", + "BriefDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake.", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.WALK_ACTIVE", + "CounterMask": "1", + "PublicDescription": "Cycles when at least one PMH is busy with a page walk for code (instruction fetch) request. EPT page walk duration are excluded in Skylake microarchitecture.", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0x85", + "UMask": "0x20", + "BriefDescription": "Instruction fetch requests that miss the ITLB and hit the STLB.", + "Counter": "0,1,2,3", + "EventName": "ITLB_MISSES.STLB_HIT", + "SampleAfterValue": "100003", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xAE", + "UMask": "0x1", + "BriefDescription": "Flushing of the Instruction TLB (ITLB) pages, includes 4k/2M/4M pages.", + "Counter": "0,1,2,3", + "EventName": "ITLB.ITLB_FLUSH", + "PublicDescription": "Counts the number of flushes of the big or small ITLB pages. Counting include both TLB Flush (covering all sets) and TLB Set Clear (set-specific).", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xBD", + "UMask": "0x1", + "BriefDescription": "DTLB flush attempts of the thread-specific entries", + "Counter": "0,1,2,3", + "EventName": "TLB_FLUSH.DTLB_THREAD", + "PublicDescription": "Counts the number of DTLB flush attempts of the thread-specific entries.", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + }, + { + "EventCode": "0xBD", + "UMask": "0x20", + "BriefDescription": "STLB flush attempts", + "Counter": "0,1,2,3", + "EventName": "TLB_FLUSH.STLB_ANY", + "PublicDescription": "Counts the number of any STLB flush attempts (such as entire, VPID, PCID, InvPage, CR3 write, etc.).", + "SampleAfterValue": "100007", + "CounterHTOff": "0,1,2,3,4,5,6,7" + } +] \ No newline at end of file diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index bd0aabb2bd0f..d51dc9ca8861 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -137,6 +137,8 @@ static struct field { { "AnyThread", "any=" }, { "EdgeDetect", "edge=" }, { "SampleAfterValue", "period=" }, + { "FCMask", "fc_mask=" }, + { "PortMask", "ch_mask=" }, { NULL, NULL } }; @@ -822,10 +824,6 @@ static int process_one_file(const char *fpath, const struct stat *sb, * PMU event tables (see struct pmu_events_map). * * Write out the PMU events tables and the mapping table to pmu-event.c. - * - * If unable to process the JSON or arch files, create an empty mapping - * table so we can continue to build/use perf even if we cannot use the - * PMU event aliases. */ int main(int argc, char *argv[]) { @@ -836,6 +834,7 @@ int main(int argc, char *argv[]) const char *arch; const char *output_file; const char *start_dirname; + struct stat stbuf; prog = basename(argv[0]); if (argc < 4) { @@ -857,11 +856,17 @@ int main(int argc, char *argv[]) return 2; } + sprintf(ldirname, "%s/%s", start_dirname, arch); + + /* If architecture does not have any event lists, bail out */ + if (stat(ldirname, &stbuf) < 0) { + pr_info("%s: Arch %s has no PMU event lists\n", prog, arch); + goto empty_map; + } + /* Include pmu-events.h first */ fprintf(eventsfp, "#include \"../../pmu-events/pmu-events.h\"\n"); - sprintf(ldirname, "%s/%s", start_dirname, arch); - /* * The mapfile allows multiple CPUids to point to the same JSON file, * so, not sure if there is a need for symlinks within the pmu-events @@ -878,6 +883,9 @@ int main(int argc, char *argv[]) if (rc && verbose) { pr_info("%s: Error walking file tree %s\n", prog, ldirname); goto empty_map; + } else if (rc < 0) { + /* Make build fail */ + return 1; } else if (rc) { goto empty_map; } @@ -892,7 +900,8 @@ int main(int argc, char *argv[]) if (process_mapfile(eventsfp, mapfile)) { pr_info("%s: Error processing mapfile %s\n", prog, mapfile); - goto empty_map; + /* Make build fail */ + return 1; } return 0; diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h index 611fac01913d..d87efd2685b8 100644 --- a/tools/perf/pmu-events/jevents.h +++ b/tools/perf/pmu-events/jevents.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef JEVENTS_H #define JEVENTS_H 1 diff --git a/tools/perf/pmu-events/jsmn.h b/tools/perf/pmu-events/jsmn.h index d666b10cf25b..c7b0f6ea2a31 100644 --- a/tools/perf/pmu-events/jsmn.h +++ b/tools/perf/pmu-events/jsmn.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __JSMN_H_ #define __JSMN_H_ diff --git a/tools/perf/pmu-events/json.h b/tools/perf/pmu-events/json.h index 278ebd32cfb6..fbcd5a0590ad 100644 --- a/tools/perf/pmu-events/json.h +++ b/tools/perf/pmu-events/json.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef JSON_H #define JSON_H 1 diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h index 569eab3688dd..e08789ddfe6c 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PMU_EVENTS_H #define PMU_EVENTS_H diff --git a/tools/perf/python/tracepoint.py b/tools/perf/python/tracepoint.py index eb4dbed57de7..eb76f6516247 100755 --- a/tools/perf/python/tracepoint.py +++ b/tools/perf/python/tracepoint.py @@ -1,4 +1,5 @@ #! /usr/bin/python +# SPDX-License-Identifier: GPL-2.0 # -*- python -*- # -*- coding: utf-8 -*- diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL b/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL index decdeb0f6789..e8994332d7dc 100644 --- a/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL +++ b/tools/perf/scripts/perl/Perf-Trace-Util/Makefile.PL @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 use 5.010000; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py index 9e0985794e20..81a56cd2b3c1 100755 --- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/EventClass.py @@ -1,4 +1,5 @@ # EventClass.py +# SPDX-License-Identifier: GPL-2.0 # # This is a library defining some events types classes, which could # be used by other scripts to analyzing the perf samples. diff --git a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py index 1d95009592eb..f6c84966e4f8 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py +++ b/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py @@ -57,6 +57,7 @@ try: 'ia64' : audit.MACH_IA64, 'ppc' : audit.MACH_PPC, 'ppc64' : audit.MACH_PPC64, + 'ppc64le' : audit.MACH_PPC64LE, 's390' : audit.MACH_S390, 's390x' : audit.MACH_S390X, 'i386' : audit.MACH_X86, diff --git a/tools/perf/scripts/python/bin/export-to-sqlite-record b/tools/perf/scripts/python/bin/export-to-sqlite-record new file mode 100644 index 000000000000..070204fd6d00 --- /dev/null +++ b/tools/perf/scripts/python/bin/export-to-sqlite-record @@ -0,0 +1,8 @@ +#!/bin/bash + +# +# export perf data to a sqlite3 database. Can cover +# perf ip samples (excluding the tracepoints). No special +# record requirements, just record what you want to export. +# +perf record $@ diff --git a/tools/perf/scripts/python/bin/export-to-sqlite-report b/tools/perf/scripts/python/bin/export-to-sqlite-report new file mode 100644 index 000000000000..5ff6033e70ba --- /dev/null +++ b/tools/perf/scripts/python/bin/export-to-sqlite-report @@ -0,0 +1,29 @@ +#!/bin/bash +# description: export perf data to a sqlite3 database +# args: [database name] [columns] [calls] +n_args=0 +for i in "$@" +do + if expr match "$i" "-" > /dev/null ; then + break + fi + n_args=$(( $n_args + 1 )) +done +if [ "$n_args" -gt 3 ] ; then + echo "usage: export-to-sqlite-report [database name] [columns] [calls]" + exit +fi +if [ "$n_args" -gt 2 ] ; then + dbname=$1 + columns=$2 + calls=$3 + shift 3 +elif [ "$n_args" -gt 1 ] ; then + dbname=$1 + columns=$2 + shift 2 +elif [ "$n_args" -gt 0 ] ; then + dbname=$1 + shift +fi +perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/export-to-sqlite.py $dbname $columns $calls diff --git a/tools/perf/scripts/python/call-graph-from-postgresql.py b/tools/perf/scripts/python/call-graph-from-sql.py similarity index 87% rename from tools/perf/scripts/python/call-graph-from-postgresql.py rename to tools/perf/scripts/python/call-graph-from-sql.py index e78fdc2a5a9d..b494a67a1c67 100644 --- a/tools/perf/scripts/python/call-graph-from-postgresql.py +++ b/tools/perf/scripts/python/call-graph-from-sql.py @@ -1,6 +1,6 @@ #!/usr/bin/python2 -# call-graph-from-postgresql.py: create call-graph from postgresql database -# Copyright (c) 2014, Intel Corporation. +# call-graph-from-sql.py: create call-graph from sql database +# Copyright (c) 2014-2017, Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, @@ -11,18 +11,19 @@ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. -# To use this script you will need to have exported data using the -# export-to-postgresql.py script. Refer to that script for details. +# To use this script you will need to have exported data using either the +# export-to-sqlite.py or the export-to-postgresql.py script. Refer to those +# scripts for details. # -# Following on from the example in the export-to-postgresql.py script, a +# Following on from the example in the export scripts, a # call-graph can be displayed for the pt_example database like this: # -# python tools/perf/scripts/python/call-graph-from-postgresql.py pt_example +# python tools/perf/scripts/python/call-graph-from-sql.py pt_example # -# Note this script supports connecting to remote databases by setting hostname, -# port, username, password, and dbname e.g. +# Note that for PostgreSQL, this script supports connecting to remote databases +# by setting hostname, port, username, password, and dbname e.g. # -# python tools/perf/scripts/python/call-graph-from-postgresql.py "hostname=myhost username=myuser password=mypassword dbname=pt_example" +# python tools/perf/scripts/python/call-graph-from-sql.py "hostname=myhost username=myuser password=mypassword dbname=pt_example" # # The result is a GUI window with a tree representing a context-sensitive # call-graph. Expanding a couple of levels of the tree and adjusting column @@ -160,7 +161,7 @@ class TreeItem(): '( SELECT short_name FROM dsos WHERE id = ( SELECT dso_id FROM symbols WHERE id = ( SELECT symbol_id FROM call_paths WHERE id = call_path_id ) ) ), ' '( SELECT ip FROM call_paths where id = call_path_id ) ' 'FROM calls WHERE parent_call_path_id = ' + str(self.call_path_id) + ' AND comm_id = ' + str(self.comm_id) + ' AND thread_id = ' + str(self.thread_id) + - 'ORDER BY call_path_id') + ' ORDER BY call_path_id') if not ret: raise Exception("Query failed: " + query.lastError().text()) last_call_path_id = 0 @@ -291,29 +292,40 @@ class MainWindow(QMainWindow): if __name__ == '__main__': if (len(sys.argv) < 2): - print >> sys.stderr, "Usage is: call-graph-from-postgresql.py " + print >> sys.stderr, "Usage is: call-graph-from-sql.py " raise Exception("Too few arguments") dbname = sys.argv[1] - db = QSqlDatabase.addDatabase('QPSQL') + is_sqlite3 = False + try: + f = open(dbname) + if f.read(15) == "SQLite format 3": + is_sqlite3 = True + f.close() + except: + pass - opts = dbname.split() - for opt in opts: - if '=' in opt: - opt = opt.split('=') - if opt[0] == 'hostname': - db.setHostName(opt[1]) - elif opt[0] == 'port': - db.setPort(int(opt[1])) - elif opt[0] == 'username': - db.setUserName(opt[1]) - elif opt[0] == 'password': - db.setPassword(opt[1]) - elif opt[0] == 'dbname': - dbname = opt[1] - else: - dbname = opt + if is_sqlite3: + db = QSqlDatabase.addDatabase('QSQLITE') + else: + db = QSqlDatabase.addDatabase('QPSQL') + opts = dbname.split() + for opt in opts: + if '=' in opt: + opt = opt.split('=') + if opt[0] == 'hostname': + db.setHostName(opt[1]) + elif opt[0] == 'port': + db.setPort(int(opt[1])) + elif opt[0] == 'username': + db.setUserName(opt[1]) + elif opt[0] == 'password': + db.setPassword(opt[1]) + elif opt[0] == 'dbname': + dbname = opt[1] + else: + dbname = opt db.setDatabaseName(dbname) if not db.open(): diff --git a/tools/perf/scripts/python/event_analyzing_sample.py b/tools/perf/scripts/python/event_analyzing_sample.py index 163c39fa12d9..4e843b9864ec 100644 --- a/tools/perf/scripts/python/event_analyzing_sample.py +++ b/tools/perf/scripts/python/event_analyzing_sample.py @@ -1,4 +1,5 @@ # event_analyzing_sample.py: general event handler in python +# SPDX-License-Identifier: GPL-2.0 # # Current perf report is already very powerful with the annotation integrated, # and this script is not trying to be as powerful as perf report, but diff --git a/tools/perf/scripts/python/export-to-postgresql.py b/tools/perf/scripts/python/export-to-postgresql.py index 7656ff8aa066..efcaf6cac2eb 100644 --- a/tools/perf/scripts/python/export-to-postgresql.py +++ b/tools/perf/scripts/python/export-to-postgresql.py @@ -59,7 +59,7 @@ import datetime # pt_example=# \q # # An example of using the database is provided by the script -# call-graph-from-postgresql.py. Refer to that script for details. +# call-graph-from-sql.py. Refer to that script for details. # # Tables: # @@ -340,7 +340,8 @@ if branches: 'to_sym_offset bigint,' 'to_ip bigint,' 'branch_type integer,' - 'in_tx boolean)') + 'in_tx boolean,' + 'call_path_id bigint)') else: do_query(query, 'CREATE TABLE samples (' 'id bigint NOT NULL,' diff --git a/tools/perf/scripts/python/export-to-sqlite.py b/tools/perf/scripts/python/export-to-sqlite.py new file mode 100644 index 000000000000..f827bf77e9d2 --- /dev/null +++ b/tools/perf/scripts/python/export-to-sqlite.py @@ -0,0 +1,451 @@ +# export-to-sqlite.py: export perf data to a sqlite3 database +# Copyright (c) 2017, Intel Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. + +import os +import sys +import struct +import datetime + +# To use this script you will need to have installed package python-pyside which +# provides LGPL-licensed Python bindings for Qt. You will also need the package +# libqt4-sql-sqlite for Qt sqlite3 support. +# +# An example of using this script with Intel PT: +# +# $ perf record -e intel_pt//u ls +# $ perf script -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py pt_example branches calls +# 2017-07-31 14:26:07.326913 Creating database... +# 2017-07-31 14:26:07.538097 Writing records... +# 2017-07-31 14:26:09.889292 Adding indexes +# 2017-07-31 14:26:09.958746 Done +# +# To browse the database, sqlite3 can be used e.g. +# +# $ sqlite3 pt_example +# sqlite> .header on +# sqlite> select * from samples_view where id < 10; +# sqlite> .mode column +# sqlite> select * from samples_view where id < 10; +# sqlite> .tables +# sqlite> .schema samples_view +# sqlite> .quit +# +# An example of using the database is provided by the script +# call-graph-from-sql.py. Refer to that script for details. +# +# The database structure is practically the same as created by the script +# export-to-postgresql.py. Refer to that script for details. A notable +# difference is the 'transaction' column of the 'samples' table which is +# renamed 'transaction_' in sqlite because 'transaction' is a reserved word. + +from PySide.QtSql import * + +sys.path.append(os.environ['PERF_EXEC_PATH'] + \ + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') + +# These perf imports are not used at present +#from perf_trace_context import * +#from Core import * + +perf_db_export_mode = True +perf_db_export_calls = False +perf_db_export_callchains = False + +def usage(): + print >> sys.stderr, "Usage is: export-to-sqlite.py [] [] []" + print >> sys.stderr, "where: columns 'all' or 'branches'" + print >> sys.stderr, " calls 'calls' => create calls and call_paths table" + print >> sys.stderr, " callchains 'callchains' => create call_paths table" + raise Exception("Too few arguments") + +if (len(sys.argv) < 2): + usage() + +dbname = sys.argv[1] + +if (len(sys.argv) >= 3): + columns = sys.argv[2] +else: + columns = "all" + +if columns not in ("all", "branches"): + usage() + +branches = (columns == "branches") + +for i in range(3,len(sys.argv)): + if (sys.argv[i] == "calls"): + perf_db_export_calls = True + elif (sys.argv[i] == "callchains"): + perf_db_export_callchains = True + else: + usage() + +def do_query(q, s): + if (q.exec_(s)): + return + raise Exception("Query failed: " + q.lastError().text()) + +def do_query_(q): + if (q.exec_()): + return + raise Exception("Query failed: " + q.lastError().text()) + +print datetime.datetime.today(), "Creating database..." + +db_exists = False +try: + f = open(dbname) + f.close() + db_exists = True +except: + pass + +if db_exists: + raise Exception(dbname + " already exists") + +db = QSqlDatabase.addDatabase('QSQLITE') +db.setDatabaseName(dbname) +db.open() + +query = QSqlQuery(db) + +do_query(query, 'PRAGMA journal_mode = OFF') +do_query(query, 'BEGIN TRANSACTION') + +do_query(query, 'CREATE TABLE selected_events (' + 'id integer NOT NULL PRIMARY KEY,' + 'name varchar(80))') +do_query(query, 'CREATE TABLE machines (' + 'id integer NOT NULL PRIMARY KEY,' + 'pid integer,' + 'root_dir varchar(4096))') +do_query(query, 'CREATE TABLE threads (' + 'id integer NOT NULL PRIMARY KEY,' + 'machine_id bigint,' + 'process_id bigint,' + 'pid integer,' + 'tid integer)') +do_query(query, 'CREATE TABLE comms (' + 'id integer NOT NULL PRIMARY KEY,' + 'comm varchar(16))') +do_query(query, 'CREATE TABLE comm_threads (' + 'id integer NOT NULL PRIMARY KEY,' + 'comm_id bigint,' + 'thread_id bigint)') +do_query(query, 'CREATE TABLE dsos (' + 'id integer NOT NULL PRIMARY KEY,' + 'machine_id bigint,' + 'short_name varchar(256),' + 'long_name varchar(4096),' + 'build_id varchar(64))') +do_query(query, 'CREATE TABLE symbols (' + 'id integer NOT NULL PRIMARY KEY,' + 'dso_id bigint,' + 'sym_start bigint,' + 'sym_end bigint,' + 'binding integer,' + 'name varchar(2048))') +do_query(query, 'CREATE TABLE branch_types (' + 'id integer NOT NULL PRIMARY KEY,' + 'name varchar(80))') + +if branches: + do_query(query, 'CREATE TABLE samples (' + 'id integer NOT NULL PRIMARY KEY,' + 'evsel_id bigint,' + 'machine_id bigint,' + 'thread_id bigint,' + 'comm_id bigint,' + 'dso_id bigint,' + 'symbol_id bigint,' + 'sym_offset bigint,' + 'ip bigint,' + 'time bigint,' + 'cpu integer,' + 'to_dso_id bigint,' + 'to_symbol_id bigint,' + 'to_sym_offset bigint,' + 'to_ip bigint,' + 'branch_type integer,' + 'in_tx boolean,' + 'call_path_id bigint)') +else: + do_query(query, 'CREATE TABLE samples (' + 'id integer NOT NULL PRIMARY KEY,' + 'evsel_id bigint,' + 'machine_id bigint,' + 'thread_id bigint,' + 'comm_id bigint,' + 'dso_id bigint,' + 'symbol_id bigint,' + 'sym_offset bigint,' + 'ip bigint,' + 'time bigint,' + 'cpu integer,' + 'to_dso_id bigint,' + 'to_symbol_id bigint,' + 'to_sym_offset bigint,' + 'to_ip bigint,' + 'period bigint,' + 'weight bigint,' + 'transaction_ bigint,' + 'data_src bigint,' + 'branch_type integer,' + 'in_tx boolean,' + 'call_path_id bigint)') + +if perf_db_export_calls or perf_db_export_callchains: + do_query(query, 'CREATE TABLE call_paths (' + 'id integer NOT NULL PRIMARY KEY,' + 'parent_id bigint,' + 'symbol_id bigint,' + 'ip bigint)') +if perf_db_export_calls: + do_query(query, 'CREATE TABLE calls (' + 'id integer NOT NULL PRIMARY KEY,' + 'thread_id bigint,' + 'comm_id bigint,' + 'call_path_id bigint,' + 'call_time bigint,' + 'return_time bigint,' + 'branch_count bigint,' + 'call_id bigint,' + 'return_id bigint,' + 'parent_call_path_id bigint,' + 'flags integer)') + +# printf was added to sqlite in version 3.8.3 +sqlite_has_printf = False +try: + do_query(query, 'SELECT printf("") FROM machines') + sqlite_has_printf = True +except: + pass + +def emit_to_hex(x): + if sqlite_has_printf: + return 'printf("%x", ' + x + ')' + else: + return x + +do_query(query, 'CREATE VIEW machines_view AS ' + 'SELECT ' + 'id,' + 'pid,' + 'root_dir,' + 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest' + ' FROM machines') + +do_query(query, 'CREATE VIEW dsos_view AS ' + 'SELECT ' + 'id,' + 'machine_id,' + '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,' + 'short_name,' + 'long_name,' + 'build_id' + ' FROM dsos') + +do_query(query, 'CREATE VIEW symbols_view AS ' + 'SELECT ' + 'id,' + 'name,' + '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,' + 'dso_id,' + 'sym_start,' + 'sym_end,' + 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding' + ' FROM symbols') + +do_query(query, 'CREATE VIEW threads_view AS ' + 'SELECT ' + 'id,' + 'machine_id,' + '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,' + 'process_id,' + 'pid,' + 'tid' + ' FROM threads') + +do_query(query, 'CREATE VIEW comm_threads_view AS ' + 'SELECT ' + 'comm_id,' + '(SELECT comm FROM comms WHERE id = comm_id) AS command,' + 'thread_id,' + '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' + '(SELECT tid FROM threads WHERE id = thread_id) AS tid' + ' FROM comm_threads') + +if perf_db_export_calls or perf_db_export_callchains: + do_query(query, 'CREATE VIEW call_paths_view AS ' + 'SELECT ' + 'c.id,' + + emit_to_hex('c.ip') + ' AS ip,' + 'c.symbol_id,' + '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,' + '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,' + '(SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,' + 'c.parent_id,' + + emit_to_hex('p.ip') + ' AS parent_ip,' + 'p.symbol_id AS parent_symbol_id,' + '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,' + '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,' + '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name' + ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id') +if perf_db_export_calls: + do_query(query, 'CREATE VIEW calls_view AS ' + 'SELECT ' + 'calls.id,' + 'thread_id,' + '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' + '(SELECT tid FROM threads WHERE id = thread_id) AS tid,' + '(SELECT comm FROM comms WHERE id = comm_id) AS command,' + 'call_path_id,' + + emit_to_hex('ip') + ' AS ip,' + 'symbol_id,' + '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,' + 'call_time,' + 'return_time,' + 'return_time - call_time AS elapsed_time,' + 'branch_count,' + 'call_id,' + 'return_id,' + 'CASE WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' ELSE \'\' END AS flags,' + 'parent_call_path_id' + ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id') + +do_query(query, 'CREATE VIEW samples_view AS ' + 'SELECT ' + 'id,' + 'time,' + 'cpu,' + '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' + '(SELECT tid FROM threads WHERE id = thread_id) AS tid,' + '(SELECT comm FROM comms WHERE id = comm_id) AS command,' + '(SELECT name FROM selected_events WHERE id = evsel_id) AS event,' + + emit_to_hex('ip') + ' AS ip_hex,' + '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,' + 'sym_offset,' + '(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,' + + emit_to_hex('to_ip') + ' AS to_ip_hex,' + '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,' + 'to_sym_offset,' + '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,' + '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,' + 'in_tx' + ' FROM samples') + +do_query(query, 'END TRANSACTION') + +evsel_query = QSqlQuery(db) +evsel_query.prepare("INSERT INTO selected_events VALUES (?, ?)") +machine_query = QSqlQuery(db) +machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)") +thread_query = QSqlQuery(db) +thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") +comm_query = QSqlQuery(db) +comm_query.prepare("INSERT INTO comms VALUES (?, ?)") +comm_thread_query = QSqlQuery(db) +comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") +dso_query = QSqlQuery(db) +dso_query.prepare("INSERT INTO dsos VALUES (?, ?, ?, ?, ?)") +symbol_query = QSqlQuery(db) +symbol_query.prepare("INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)") +branch_type_query = QSqlQuery(db) +branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)") +sample_query = QSqlQuery(db) +if branches: + sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") +else: + sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") +if perf_db_export_calls or perf_db_export_callchains: + call_path_query = QSqlQuery(db) + call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)") +if perf_db_export_calls: + call_query = QSqlQuery(db) + call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") + +def trace_begin(): + print datetime.datetime.today(), "Writing records..." + do_query(query, 'BEGIN TRANSACTION') + # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs + evsel_table(0, "unknown") + machine_table(0, 0, "unknown") + thread_table(0, 0, 0, -1, -1) + comm_table(0, "unknown") + dso_table(0, 0, "unknown", "unknown", "") + symbol_table(0, 0, 0, 0, 0, "unknown") + sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + if perf_db_export_calls or perf_db_export_callchains: + call_path_table(0, 0, 0, 0) + +unhandled_count = 0 + +def trace_end(): + do_query(query, 'END TRANSACTION') + + print datetime.datetime.today(), "Adding indexes" + if perf_db_export_calls: + do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') + + if (unhandled_count): + print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" + print datetime.datetime.today(), "Done" + +def trace_unhandled(event_name, context, event_fields_dict): + global unhandled_count + unhandled_count += 1 + +def sched__sched_switch(*x): + pass + +def bind_exec(q, n, x): + for xx in x[0:n]: + q.addBindValue(str(xx)) + do_query_(q) + +def evsel_table(*x): + bind_exec(evsel_query, 2, x) + +def machine_table(*x): + bind_exec(machine_query, 3, x) + +def thread_table(*x): + bind_exec(thread_query, 5, x) + +def comm_table(*x): + bind_exec(comm_query, 2, x) + +def comm_thread_table(*x): + bind_exec(comm_thread_query, 3, x) + +def dso_table(*x): + bind_exec(dso_query, 5, x) + +def symbol_table(*x): + bind_exec(symbol_query, 6, x) + +def branch_type_table(*x): + bind_exec(branch_type_query, 2, x) + +def sample_table(*x): + if branches: + bind_exec(sample_query, 18, x) + else: + bind_exec(sample_query, 22, x) + +def call_path_table(*x): + bind_exec(call_path_query, 4, x) + +def call_return_table(*x): + bind_exec(call_query, 11, x) diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py index 0b6ce8c253e8..a150164b44a3 100755 --- a/tools/perf/scripts/python/net_dropmonitor.py +++ b/tools/perf/scripts/python/net_dropmonitor.py @@ -1,4 +1,5 @@ # Monitor the system for dropped packets and proudce a report of drop locations and counts +# SPDX-License-Identifier: GPL-2.0 import os import sys diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py index 4c6f09ac7d12..9b2050f778f1 100644 --- a/tools/perf/scripts/python/netdev-times.py +++ b/tools/perf/scripts/python/netdev-times.py @@ -1,4 +1,5 @@ # Display a process of packets and processed time. +# SPDX-License-Identifier: GPL-2.0 # It helps us to investigate networking or network device. # # options diff --git a/tools/perf/scripts/python/stackcollapse.py b/tools/perf/scripts/python/stackcollapse.py index 5a605f70ef32..1697b5e18c96 100755 --- a/tools/perf/scripts/python/stackcollapse.py +++ b/tools/perf/scripts/python/stackcollapse.py @@ -1,4 +1,5 @@ # stackcollapse.py - format perf samples with one line per distinct call stack +# SPDX-License-Identifier: GPL-2.0 # # This script's output has two space-separated fields. The first is a semicolon # separated stack including the program name (from the "comm" field) and the diff --git a/tools/perf/scripts/python/stat-cpi.py b/tools/perf/scripts/python/stat-cpi.py index 8b60f343dd07..8410672efb8b 100644 --- a/tools/perf/scripts/python/stat-cpi.py +++ b/tools/perf/scripts/python/stat-cpi.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0 data = {} times = [] diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 84222bdb8689..87bf3edb037c 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -34,6 +34,7 @@ perf-y += thread-map.o perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o llvm-src-relocation.o perf-y += bpf.o perf-y += topology.o +perf-y += mem.o perf-y += cpumap.o perf-y += stat.o perf-y += event_update.o diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 0e77b2cf61ec..c180bbcdbef6 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * The struct perf_event_attr test support. * @@ -36,6 +37,7 @@ #define ENV "PERF_TEST_ATTR" static char *dir; +static bool ready; void test_attr__init(void) { @@ -67,6 +69,9 @@ static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, FILE *file; char path[PATH_MAX]; + if (!ready) + return 0; + snprintf(path, PATH_MAX, "%s/event-%d-%llu-%d", dir, attr->type, attr->config, fd); @@ -136,7 +141,7 @@ void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, { int errno_saved = errno; - if (store_event(attr, pid, cpu, fd, group_fd, flags)) { + if ((fd != -1) && store_event(attr, pid, cpu, fd, group_fd, flags)) { pr_err("test attr FAILED"); exit(128); } @@ -144,6 +149,12 @@ void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, errno = errno_saved; } +void test_attr__ready(void) +{ + if (unlikely(test_attr__enabled) && !ready) + ready = true; +} + static int run_dir(const char *d, const char *perf) { char v[] = "-vvvvv"; @@ -159,7 +170,7 @@ static int run_dir(const char *d, const char *perf) return system(cmd); } -int test__attr(int subtest __maybe_unused) +int test__attr(struct test *test __maybe_unused, int subtest __maybe_unused) { struct stat st; char path_perf[PATH_MAX]; diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py index cdf21a9d0c35..907b1b2f56ad 100644 --- a/tools/perf/tests/attr.py +++ b/tools/perf/tests/attr.py @@ -1,4 +1,5 @@ #! /usr/bin/python +# SPDX-License-Identifier: GPL-2.0 import os import sys @@ -9,6 +10,20 @@ import logging import shutil import ConfigParser +def data_equal(a, b): + # Allow multiple values in assignment separated by '|' + a_list = a.split('|') + b_list = b.split('|') + + for a_item in a_list: + for b_item in b_list: + if (a_item == b_item): + return True + elif (a_item == '*') or (b_item == '*'): + return True + + return False + class Fail(Exception): def __init__(self, test, msg): self.msg = msg @@ -82,34 +97,25 @@ class Event(dict): self.add(base) self.add(data) - def compare_data(self, a, b): - # Allow multiple values in assignment separated by '|' - a_list = a.split('|') - b_list = b.split('|') - - for a_item in a_list: - for b_item in b_list: - if (a_item == b_item): - return True - elif (a_item == '*') or (b_item == '*'): - return True - - return False - def equal(self, other): for t in Event.terms: log.debug(" [%s] %s %s" % (t, self[t], other[t])); if not self.has_key(t) or not other.has_key(t): return False - if not self.compare_data(self[t], other[t]): + if not data_equal(self[t], other[t]): return False return True + def optional(self): + if self.has_key('optional') and self['optional'] == '1': + return True + return False + def diff(self, other): for t in Event.terms: if not self.has_key(t) or not other.has_key(t): continue - if not self.compare_data(self[t], other[t]): + if not data_equal(self[t], other[t]): log.warning("expected %s=%s, got %s" % (t, self[t], other[t])) # Test file description needs to have following sections: @@ -218,9 +224,9 @@ class Test(object): self.perf, self.command, tempdir, self.args) ret = os.WEXITSTATUS(os.system(cmd)) - log.info(" '%s' ret %d " % (cmd, ret)) + log.info(" '%s' ret '%s', expected '%s'" % (cmd, str(ret), str(self.ret))) - if ret != int(self.ret): + if not data_equal(str(ret), str(self.ret)): raise Unsup(self) def compare(self, expect, result): @@ -244,9 +250,12 @@ class Test(object): log.debug(" match: [%s] matches %s" % (exp_name, str(exp_list))) # we did not any matching event - fail - if (not exp_list): - exp_event.diff(res_event) - raise Fail(self, 'match failure'); + if not exp_list: + if exp_event.optional(): + log.debug(" %s does not match, but is optional" % exp_name) + else: + exp_event.diff(res_event) + raise Fail(self, 'match failure'); match[exp_name] = exp_list diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record index 7e6d74946e04..31e0b1da830b 100644 --- a/tools/perf/tests/attr/base-record +++ b/tools/perf/tests/attr/base-record @@ -7,7 +7,7 @@ cpu=* type=0|1 size=112 config=0 -sample_period=4000 +sample_period=* sample_type=263 read_format=0 disabled=1 @@ -15,7 +15,7 @@ inherit=1 pinned=0 exclusive=0 exclude_user=0 -exclude_kernel=0 +exclude_kernel=0|1 exclude_hv=0 exclude_idle=0 mmap=1 @@ -25,7 +25,7 @@ inherit_stat=0 enable_on_exec=1 task=0 watermark=0 -precise_ip=0 +precise_ip=0|1|2|3 mmap_data=0 sample_id_all=1 exclude_host=0|1 diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat index f4cf148f14cb..4d0c2e42b64e 100644 --- a/tools/perf/tests/attr/base-stat +++ b/tools/perf/tests/attr/base-stat @@ -8,14 +8,14 @@ type=0 size=112 config=0 sample_period=0 -sample_type=0 +sample_type=65536 read_format=3 disabled=1 inherit=1 pinned=0 exclusive=0 exclude_user=0 -exclude_kernel=0 +exclude_kernel=0|1 exclude_hv=0 exclude_idle=0 mmap=0 diff --git a/tools/perf/tests/attr/test-record-C0 b/tools/perf/tests/attr/test-record-C0 index d6a7e43f61b3..cb0a3138fa54 100644 --- a/tools/perf/tests/attr/test-record-C0 +++ b/tools/perf/tests/attr/test-record-C0 @@ -1,6 +1,7 @@ [config] command = record args = -C 0 kill >/dev/null 2>&1 +ret = 1 [event:base-record] cpu=0 diff --git a/tools/perf/tests/attr/test-record-basic b/tools/perf/tests/attr/test-record-basic index 55c0428370ca..85a23cf35ba1 100644 --- a/tools/perf/tests/attr/test-record-basic +++ b/tools/perf/tests/attr/test-record-basic @@ -1,5 +1,6 @@ [config] command = record args = kill >/dev/null 2>&1 +ret = 1 [event:base-record] diff --git a/tools/perf/tests/attr/test-record-branch-any b/tools/perf/tests/attr/test-record-branch-any index 1421960ed4e9..81f839e2fad0 100644 --- a/tools/perf/tests/attr/test-record-branch-any +++ b/tools/perf/tests/attr/test-record-branch-any @@ -1,8 +1,8 @@ [config] command = record args = -b kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any b/tools/perf/tests/attr/test-record-branch-filter-any index 915c4df0e0c2..357421f4dfce 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-any +++ b/tools/perf/tests/attr/test-record-branch-filter-any @@ -1,8 +1,8 @@ [config] command = record args = -j any kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_call b/tools/perf/tests/attr/test-record-branch-filter-any_call index 8708dbd4f373..dbc55f2ab845 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-any_call +++ b/tools/perf/tests/attr/test-record-branch-filter-any_call @@ -1,8 +1,8 @@ [config] command = record args = -j any_call kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=16 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_ret b/tools/perf/tests/attr/test-record-branch-filter-any_ret index 0d3607a6dcbe..a0824ff8e131 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-any_ret +++ b/tools/perf/tests/attr/test-record-branch-filter-any_ret @@ -1,8 +1,8 @@ [config] command = record args = -j any_ret kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=32 diff --git a/tools/perf/tests/attr/test-record-branch-filter-hv b/tools/perf/tests/attr/test-record-branch-filter-hv index f25526740cec..f34d6f120181 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-hv +++ b/tools/perf/tests/attr/test-record-branch-filter-hv @@ -1,8 +1,8 @@ [config] command = record args = -j hv kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-ind_call b/tools/perf/tests/attr/test-record-branch-filter-ind_call index e862dd179128..b86a35232248 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-ind_call +++ b/tools/perf/tests/attr/test-record-branch-filter-ind_call @@ -1,8 +1,8 @@ [config] command = record args = -j ind_call kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=64 diff --git a/tools/perf/tests/attr/test-record-branch-filter-k b/tools/perf/tests/attr/test-record-branch-filter-k index 182971e898f5..d3fbc5e1858a 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-k +++ b/tools/perf/tests/attr/test-record-branch-filter-k @@ -1,8 +1,8 @@ [config] command = record args = -j k kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-u b/tools/perf/tests/attr/test-record-branch-filter-u index 83449ef9e687..a318f0dda173 100644 --- a/tools/perf/tests/attr/test-record-branch-filter-u +++ b/tools/perf/tests/attr/test-record-branch-filter-u @@ -1,8 +1,8 @@ [config] command = record args = -j u kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=2311 branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-count b/tools/perf/tests/attr/test-record-count index 2f841de56f6b..34f6cc577263 100644 --- a/tools/perf/tests/attr/test-record-count +++ b/tools/perf/tests/attr/test-record-count @@ -1,6 +1,7 @@ [config] command = record args = -c 123 kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=123 diff --git a/tools/perf/tests/attr/test-record-data b/tools/perf/tests/attr/test-record-data index 716e143b5291..a9cf2233b0ce 100644 --- a/tools/perf/tests/attr/test-record-data +++ b/tools/perf/tests/attr/test-record-data @@ -1,10 +1,9 @@ [config] command = record args = -d kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 - # sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME | # PERF_SAMPLE_ADDR | PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC sample_type=33039 diff --git a/tools/perf/tests/attr/test-record-freq b/tools/perf/tests/attr/test-record-freq index 600d0f8f2583..bf4cb459f0d5 100644 --- a/tools/perf/tests/attr/test-record-freq +++ b/tools/perf/tests/attr/test-record-freq @@ -1,6 +1,7 @@ [config] command = record args = -F 100 kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=100 diff --git a/tools/perf/tests/attr/test-record-graph-default b/tools/perf/tests/attr/test-record-graph-default index 853597a9a8f6..0b216e69760c 100644 --- a/tools/perf/tests/attr/test-record-graph-default +++ b/tools/perf/tests/attr/test-record-graph-default @@ -1,6 +1,7 @@ [config] command = record args = -g kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_type=295 diff --git a/tools/perf/tests/attr/test-record-graph-dwarf b/tools/perf/tests/attr/test-record-graph-dwarf index d6f324ea578c..da2fa73bd0a2 100644 --- a/tools/perf/tests/attr/test-record-graph-dwarf +++ b/tools/perf/tests/attr/test-record-graph-dwarf @@ -1,10 +1,12 @@ [config] command = record args = --call-graph dwarf -- kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_type=12583 +sample_type=45359 exclude_callchain_user=1 sample_stack_user=8192 # TODO different for each arch, no support for that now sample_regs_user=* +mmap_data=1 diff --git a/tools/perf/tests/attr/test-record-graph-fp b/tools/perf/tests/attr/test-record-graph-fp index 055e3bee7993..625d190bb798 100644 --- a/tools/perf/tests/attr/test-record-graph-fp +++ b/tools/perf/tests/attr/test-record-graph-fp @@ -1,6 +1,7 @@ [config] command = record args = --call-graph fp kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_type=295 diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group index 57739cacdb2a..6e7961f6f7a5 100644 --- a/tools/perf/tests/attr/test-record-group +++ b/tools/perf/tests/attr/test-record-group @@ -1,6 +1,7 @@ [config] command = record args = --group -e cycles,instructions kill >/dev/null 2>&1 +ret = 1 [event-1:base-record] fd=1 diff --git a/tools/perf/tests/attr/test-record-group-sampling b/tools/perf/tests/attr/test-record-group-sampling index 658f5d60c873..ef59afd6d635 100644 --- a/tools/perf/tests/attr/test-record-group-sampling +++ b/tools/perf/tests/attr/test-record-group-sampling @@ -1,6 +1,7 @@ [config] command = record args = -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1 +ret = 1 [event-1:base-record] fd=1 diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1 index c5548d054aff..87a222d014d8 100644 --- a/tools/perf/tests/attr/test-record-group1 +++ b/tools/perf/tests/attr/test-record-group1 @@ -1,6 +1,7 @@ [config] command = record args = -e '{cycles,instructions}' kill >/dev/null 2>&1 +ret = 1 [event-1:base-record] fd=1 diff --git a/tools/perf/tests/attr/test-record-no-delay b/tools/perf/tests/attr/test-record-no-buffering similarity index 61% rename from tools/perf/tests/attr/test-record-no-delay rename to tools/perf/tests/attr/test-record-no-buffering index f253b78cdbf2..aa3956d8fe20 100644 --- a/tools/perf/tests/attr/test-record-no-delay +++ b/tools/perf/tests/attr/test-record-no-buffering @@ -1,9 +1,9 @@ [config] command = record -args = -D kill >/dev/null 2>&1 +args = --no-buffering kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=263 watermark=0 wakeup_events=1 diff --git a/tools/perf/tests/attr/test-record-no-inherit b/tools/perf/tests/attr/test-record-no-inherit index 44edcb2edcd5..560943decb87 100644 --- a/tools/perf/tests/attr/test-record-no-inherit +++ b/tools/perf/tests/attr/test-record-no-inherit @@ -1,6 +1,7 @@ [config] command = record args = -i kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_type=263 diff --git a/tools/perf/tests/attr/test-record-no-samples b/tools/perf/tests/attr/test-record-no-samples index d0141b2418b5..8eb73ab639e0 100644 --- a/tools/perf/tests/attr/test-record-no-samples +++ b/tools/perf/tests/attr/test-record-no-samples @@ -1,6 +1,7 @@ [config] command = record args = -n kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=0 diff --git a/tools/perf/tests/attr/test-record-period b/tools/perf/tests/attr/test-record-period index 8abc5314fc52..69bc748f0f27 100644 --- a/tools/perf/tests/attr/test-record-period +++ b/tools/perf/tests/attr/test-record-period @@ -1,6 +1,7 @@ [config] command = record args = -c 100 -P kill >/dev/null 2>&1 +ret = 1 [event:base-record] sample_period=100 diff --git a/tools/perf/tests/attr/test-record-raw b/tools/perf/tests/attr/test-record-raw index 4a8ef25b5f49..a188a614a44c 100644 --- a/tools/perf/tests/attr/test-record-raw +++ b/tools/perf/tests/attr/test-record-raw @@ -1,7 +1,7 @@ [config] command = record args = -R kill >/dev/null 2>&1 +ret = 1 [event:base-record] -sample_period=4000 sample_type=1415 diff --git a/tools/perf/tests/attr/test-stat-C0 b/tools/perf/tests/attr/test-stat-C0 index aa835950751f..67717fe6a65d 100644 --- a/tools/perf/tests/attr/test-stat-C0 +++ b/tools/perf/tests/attr/test-stat-C0 @@ -4,6 +4,6 @@ args = -e cycles -C 0 kill >/dev/null 2>&1 ret = 1 [event:base-stat] -# events are enabled by default when attached to cpu -disabled=0 +# events are disabled by default when attached to cpu +disabled=1 enable_on_exec=0 diff --git a/tools/perf/tests/attr/test-stat-default b/tools/perf/tests/attr/test-stat-default index 19270f54c96e..e911dbd4eb47 100644 --- a/tools/perf/tests/attr/test-stat-default +++ b/tools/perf/tests/attr/test-stat-default @@ -38,12 +38,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] diff --git a/tools/perf/tests/attr/test-stat-detailed-1 b/tools/perf/tests/attr/test-stat-detailed-1 index 51426b87153b..b39270a08e74 100644 --- a/tools/perf/tests/attr/test-stat-detailed-1 +++ b/tools/perf/tests/attr/test-stat-detailed-1 @@ -39,12 +39,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] diff --git a/tools/perf/tests/attr/test-stat-detailed-2 b/tools/perf/tests/attr/test-stat-detailed-2 index 8de5acc31c27..45f8e6ea34f8 100644 --- a/tools/perf/tests/attr/test-stat-detailed-2 +++ b/tools/perf/tests/attr/test-stat-detailed-2 @@ -39,12 +39,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] @@ -108,6 +110,7 @@ config=65538 fd=15 type=3 config=1 +optional=1 # PERF_TYPE_HW_CACHE, # PERF_COUNT_HW_CACHE_L1I << 0 | diff --git a/tools/perf/tests/attr/test-stat-detailed-3 b/tools/perf/tests/attr/test-stat-detailed-3 index 0a1f45bf7d79..30ae0fb7a3fd 100644 --- a/tools/perf/tests/attr/test-stat-detailed-3 +++ b/tools/perf/tests/attr/test-stat-detailed-3 @@ -39,12 +39,14 @@ config=0 fd=6 type=0 config=7 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND [event7:base-stat] fd=7 type=0 config=8 +optional=1 # PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS [event8:base-stat] @@ -108,6 +110,7 @@ config=65538 fd=15 type=3 config=1 +optional=1 # PERF_TYPE_HW_CACHE, # PERF_COUNT_HW_CACHE_L1I << 0 | @@ -162,6 +165,7 @@ config=65540 fd=21 type=3 config=512 +optional=1 # PERF_TYPE_HW_CACHE, # PERF_COUNT_HW_CACHE_L1D << 0 | @@ -171,3 +175,4 @@ config=512 fd=22 type=3 config=66048 +optional=1 diff --git a/tools/perf/tests/backward-ring-buffer.c b/tools/perf/tests/backward-ring-buffer.c index 50f6d7afee58..71b9a0b613d2 100644 --- a/tools/perf/tests/backward-ring-buffer.c +++ b/tools/perf/tests/backward-ring-buffer.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Test backward bit in event attribute, read ring buffer from end to * beginning @@ -75,7 +76,7 @@ static int do_test(struct perf_evlist *evlist, int mmap_pages, } -int test__backward_ring_buffer(int subtest __maybe_unused) +int test__backward_ring_buffer(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret = TEST_SKIP, err, sample_count = 0, comm_count = 0; char pid[16], sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 9abe6c13090f..47bedf25ba69 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "tests.h" @@ -40,7 +41,7 @@ static int test_bitmap(const char *str) return ret; } -int test__bitmap_print(int subtest __maybe_unused) +int test__bitmap_print(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", test_bitmap("1")); TEST_ASSERT_VAL("failed to convert map", test_bitmap("1,5")); diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c index 39bbb97cd30a..335b695f4970 100644 --- a/tools/perf/tests/bp_signal.c +++ b/tools/perf/tests/bp_signal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Inspired by breakpoint overflow test done by * Vince Weaver for perf_event_tests @@ -164,7 +165,7 @@ static long long bp_count(int fd) return count; } -int test__bp_signal(int subtest __maybe_unused) +int test__bp_signal(struct test *test __maybe_unused, int subtest __maybe_unused) { struct sigaction sa; long long count1, count2, count3; diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c index 3b1ac6f31b15..ca962559e845 100644 --- a/tools/perf/tests/bp_signal_overflow.c +++ b/tools/perf/tests/bp_signal_overflow.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Originally done by Vince Weaver for * perf_event_tests (git://github.com/deater/perf_event_tests) @@ -57,7 +58,7 @@ static long long bp_count(int fd) #define EXECUTIONS 10000 #define THRESHOLD 100 -int test__bp_signal_overflow(int subtest __maybe_unused) +int test__bp_signal_overflow(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_event_attr pe; struct sigaction sa; diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c index b4ebc75e25ae..43f1e16486f4 100644 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ b/tools/perf/tests/bpf-script-test-prologue.c @@ -26,9 +26,11 @@ static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = (void *) 6; SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long f_mode, +int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, unsigned long offset, unsigned long orig) { + fmode_t f_mode = (fmode_t)_f_mode; + if (err) return 0; if (f_mode & FMODE_WRITE) diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 5876da126b58..34c22cdf4d5d 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -124,16 +124,16 @@ static int do_test(struct bpf_object *obj, int (*func)(void), struct perf_evlist *evlist; int i, ret = TEST_FAIL, err = 0, count = 0; - struct parse_events_evlist parse_evlist; + struct parse_events_state parse_state; struct parse_events_error parse_error; bzero(&parse_error, sizeof(parse_error)); - bzero(&parse_evlist, sizeof(parse_evlist)); - parse_evlist.error = &parse_error; - INIT_LIST_HEAD(&parse_evlist.list); + bzero(&parse_state, sizeof(parse_state)); + parse_state.error = &parse_error; + INIT_LIST_HEAD(&parse_state.list); - err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj, NULL); - if (err || list_empty(&parse_evlist.list)) { + err = parse_events_load_bpf_obj(&parse_state, &parse_state.list, obj, NULL); + if (err || list_empty(&parse_state.list)) { pr_debug("Failed to add events selected by BPF\n"); return TEST_FAIL; } @@ -155,8 +155,8 @@ static int do_test(struct bpf_object *obj, int (*func)(void), goto out_delete_evlist; } - perf_evlist__splice_list_tail(evlist, &parse_evlist.list); - evlist->nr_groups = parse_evlist.nr_groups; + perf_evlist__splice_list_tail(evlist, &parse_state.list); + evlist->nr_groups = parse_state.nr_groups; perf_evlist__config(evlist, &opts, NULL); @@ -321,7 +321,7 @@ static int check_env(void) return 0; } -int test__bpf(int i) +int test__bpf(struct test *test __maybe_unused, int i) { int err; @@ -351,7 +351,7 @@ const char *test__bpf_subtest_get_desc(int i __maybe_unused) return NULL; } -int test__bpf(int i __maybe_unused) +int test__bpf(struct test *test __maybe_unused, int i __maybe_unused) { pr_debug("Skip BPF test because BPF support is not compiled\n"); return TEST_SKIP; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 3ccfd58a8c3c..53d06f37406a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * builtin-test.c * @@ -6,7 +7,10 @@ #include #include #include +#include +#include #include +#include #include "builtin.h" #include "hist.h" #include "intlist.h" @@ -14,8 +18,10 @@ #include "debug.h" #include "color.h" #include +#include "string2.h" #include "symbol.h" #include +#include static bool dont_fork; @@ -42,6 +48,10 @@ static struct test generic_tests[] = { .desc = "Read samples using the mmap interface", .func = test__basic_mmap, }, + { + .desc = "Test data source output", + .func = test__mem, + }, { .desc = "Parse event definition strings", .func = test__parse_events, @@ -179,7 +189,7 @@ static struct test generic_tests[] = { }, { .desc = "Session topology", - .func = test_session_topology, + .func = test__session_topology, }, { .desc = "BPF filter", @@ -325,7 +335,7 @@ static int run_test(struct test *test, int subtest) } } - err = test->func(subtest); + err = test->func(test, subtest); if (!dont_fork) exit(err); } @@ -383,12 +393,143 @@ static int test_and_print(struct test *t, bool force_skip, int subtest) return err; } +static const char *shell_test__description(char *description, size_t size, + const char *path, const char *name) +{ + FILE *fp; + char filename[PATH_MAX]; + + path__join(filename, sizeof(filename), path, name); + fp = fopen(filename, "r"); + if (!fp) + return NULL; + + description = fgets(description, size, fp); + fclose(fp); + + return description ? trim(description + 1) : NULL; +} + +#define for_each_shell_test(dir, ent) \ + while ((ent = readdir(dir)) != NULL) \ + if (ent->d_type == DT_REG && ent->d_name[0] != '.') + +static const char *shell_tests__dir(char *path, size_t size) +{ + const char *devel_dirs[] = { "./tools/perf/tests", "./tests", }; + char *exec_path; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(devel_dirs); ++i) { + struct stat st; + if (!lstat(devel_dirs[i], &st)) { + scnprintf(path, size, "%s/shell", devel_dirs[i]); + if (!lstat(devel_dirs[i], &st)) + return path; + } + } + + /* Then installed path. */ + exec_path = get_argv_exec_path(); + scnprintf(path, size, "%s/tests/shell", exec_path); + free(exec_path); + return path; +} + +static int shell_tests__max_desc_width(void) +{ + DIR *dir; + struct dirent *ent; + char path_dir[PATH_MAX]; + const char *path = shell_tests__dir(path_dir, sizeof(path_dir)); + int width = 0; + + if (path == NULL) + return -1; + + dir = opendir(path); + if (!dir) + return -1; + + for_each_shell_test(dir, ent) { + char bf[256]; + const char *desc = shell_test__description(bf, sizeof(bf), path, ent->d_name); + + if (desc) { + int len = strlen(desc); + + if (width < len) + width = len; + } + } + + closedir(dir); + return width; +} + +struct shell_test { + const char *dir; + const char *file; +}; + +static int shell_test__run(struct test *test, int subdir __maybe_unused) +{ + int err; + char script[PATH_MAX]; + struct shell_test *st = test->priv; + + path__join(script, sizeof(script), st->dir, st->file); + + err = system(script); + if (!err) + return TEST_OK; + + return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL; +} + +static int run_shell_tests(int argc, const char *argv[], int i, int width) +{ + DIR *dir; + struct dirent *ent; + char path_dir[PATH_MAX]; + struct shell_test st = { + .dir = shell_tests__dir(path_dir, sizeof(path_dir)), + }; + + if (st.dir == NULL) + return -1; + + dir = opendir(st.dir); + if (!dir) + return -1; + + for_each_shell_test(dir, ent) { + int curr = i++; + char desc[256]; + struct test test = { + .desc = shell_test__description(desc, sizeof(desc), st.dir, ent->d_name), + .func = shell_test__run, + .priv = &st, + }; + + if (!perf_test__matches(&test, curr, argc, argv)) + continue; + + st.file = ent->d_name; + pr_info("%2d: %-*s:", i, width, test.desc); + test_and_print(&test, false, -1); + } + + closedir(dir); + return 0; +} + static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) { struct test *t; unsigned int j; int i = 0; - int width = 0; + int width = shell_tests__max_desc_width(); for_each_test(j, t) { int len = strlen(t->desc); @@ -455,6 +596,37 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) } } + return run_shell_tests(argc, argv, i, width); +} + +static int perf_test__list_shell(int argc, const char **argv, int i) +{ + DIR *dir; + struct dirent *ent; + char path_dir[PATH_MAX]; + const char *path = shell_tests__dir(path_dir, sizeof(path_dir)); + + if (path == NULL) + return -1; + + dir = opendir(path); + if (!dir) + return -1; + + for_each_shell_test(dir, ent) { + int curr = i++; + char bf[256]; + struct test t = { + .desc = shell_test__description(bf, sizeof(bf), path, ent->d_name), + }; + + if (!perf_test__matches(&t, curr, argc, argv)) + continue; + + pr_info("%2d: %s\n", i, t.desc); + } + + closedir(dir); return 0; } @@ -465,12 +637,17 @@ static int perf_test__list(int argc, const char **argv) int i = 0; for_each_test(j, t) { - if (argc > 1 && !strstr(t->desc, argv[1])) + int curr = i++; + + if (!perf_test__matches(t, curr, argc, argv) || + (t->is_supported && !t->is_supported())) continue; - pr_info("%2d: %s\n", ++i, t->desc); + pr_info("%2d: %s\n", i, t->desc); } + perf_test__list_shell(argc, argv, i); + return 0; } @@ -498,7 +675,7 @@ int cmd_test(int argc, const char **argv) argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0); if (argc >= 1 && !strcmp(argv[0], "list")) - return perf_test__list(argc, argv); + return perf_test__list(argc - 1, argv + 1); symbol_conf.priv_size = sizeof(int); symbol_conf.sort_by_name = true; diff --git a/tools/perf/tests/clang.c b/tools/perf/tests/clang.c index c5bb2203f5a9..f45fe11dcf50 100644 --- a/tools/perf/tests/clang.c +++ b/tools/perf/tests/clang.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tests.h" #include "debug.h" #include "util.h" @@ -33,12 +34,12 @@ const char *test__clang_subtest_get_desc(int i) } #ifndef HAVE_LIBCLANGLLVM_SUPPORT -int test__clang(int i __maybe_unused) +int test__clang(struct test *test __maybe_unused, int i __maybe_unused) { return TEST_SKIP; } #else -int test__clang(int i) +int test__clang(struct test *test __maybe_unused, int i) { if (i < 0 || i >= (int)ARRAY_SIZE(clang_testcase_table)) return TEST_FAIL; diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 94b7c7b02bde..fcc8984bc329 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -237,6 +238,11 @@ static int read_object_code(u64 addr, size_t len, u8 cpumode, thread__find_addr_map(thread, cpumode, MAP__FUNCTION, addr, &al); if (!al.map || !al.map->dso) { + if (cpumode == PERF_RECORD_MISC_HYPERVISOR) { + pr_debug("Hypervisor address can not be resolved - skipping\n"); + return 0; + } + pr_debug("thread__find_addr_map failed\n"); return -1; } @@ -673,7 +679,7 @@ out_err: return err; } -int test__code_reading(int subtest __maybe_unused) +int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret; diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c index 4478773cdb97..e78b897677bd 100644 --- a/tools/perf/tests/cpumap.c +++ b/tools/perf/tests/cpumap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tests.h" #include #include "cpumap.h" @@ -72,7 +73,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, } -int test__cpu_map_synthesize(int subtest __maybe_unused) +int test__cpu_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { struct cpu_map *cpus; @@ -106,7 +107,7 @@ static int cpu_map_print(const char *str) return !strcmp(buf, str); } -int test__cpu_map_print(int subtest __maybe_unused) +int test__cpu_map_print(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1")); TEST_ASSERT_VAL("failed to convert map", cpu_map_print("1,5")); diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 8f08df5861cb..7f6c52021e41 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -112,7 +113,7 @@ static int dso__data_fd(struct dso *dso, struct machine *machine) return fd; } -int test__dso_data(int subtest __maybe_unused) +int test__dso_data(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; struct dso *dso; @@ -247,7 +248,7 @@ static int set_fd_limit(int n) return setrlimit(RLIMIT_NOFILE, &rlim); } -int test__dso_data_cache(int subtest __maybe_unused) +int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(); @@ -307,7 +308,7 @@ int test__dso_data_cache(int subtest __maybe_unused) return 0; } -int test__dso_data_reopen(int subtest __maybe_unused) +int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; long nr_end, nr = open_files_cnt(); diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c index 3e56d08f7995..ac40e05bcab4 100644 --- a/tools/perf/tests/dwarf-unwind.c +++ b/tools/perf/tests/dwarf-unwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -6,7 +7,7 @@ #include "debug.h" #include "machine.h" #include "event.h" -#include "unwind.h" +#include "../util/unwind.h" #include "perf_regs.h" #include "map.h" #include "thread.h" @@ -154,7 +155,7 @@ static noinline int krava_1(struct thread *thread) return krava_2(thread); } -int test__dwarf_unwind(int subtest __maybe_unused) +int test__dwarf_unwind(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine *machine; struct thread *thread; diff --git a/tools/perf/tests/event-times.c b/tools/perf/tests/event-times.c index 634f20c631d8..1a2686f1fcf0 100644 --- a/tools/perf/tests/event-times.c +++ b/tools/perf/tests/event-times.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -213,7 +214,7 @@ out_err: * and checks that enabled and running times * match. */ -int test__event_times(int subtest __maybe_unused) +int test__event_times(struct test *test __maybe_unused, int subtest __maybe_unused) { int err, ret = 0; diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c index 63ecf21750eb..f14dcd613438 100644 --- a/tools/perf/tests/event_update.c +++ b/tools/perf/tests/event_update.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "evlist.h" #include "evsel.h" @@ -76,7 +77,7 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused, return 0; } -int test__event_update(int subtest __maybe_unused) +int test__event_update(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evlist *evlist; struct perf_evsel *evsel; diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index d2bea6f780f8..a104728ebf25 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "evlist.h" #include "evsel.h" #include "parse-events.h" @@ -97,7 +98,7 @@ out_delete_evlist: #define perf_evsel__name_array_test(names) \ __perf_evsel__name_array_test(names, ARRAY_SIZE(names)) -int test__perf_evsel__roundtrip_name_test(int subtest __maybe_unused) +int test__perf_evsel__roundtrip_name_test(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = 0, ret = 0; diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c index 1984b3bbfe15..699561fa512c 100644 --- a/tools/perf/tests/evsel-tp-sched.c +++ b/tools/perf/tests/evsel-tp-sched.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "evsel.h" @@ -32,7 +33,7 @@ static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, return ret; } -int test__perf_evsel__tp_sched_test(int subtest __maybe_unused) +int test__perf_evsel__tp_sched_test(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch"); int ret = 0; diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 6c6a3749aaf6..01f0706995a9 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util/debug.h" #include "util/expr.h" #include "tests.h" @@ -13,7 +14,7 @@ static int test(struct parse_ctx *ctx, const char *e, double val2) return 0; } -int test__expr(int subtest __maybe_unused) +int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) { const char *p; const char **other; @@ -31,6 +32,11 @@ int test__expr(int subtest __maybe_unused) ret |= test(&ctx, "(BAR/2)%2", 1); ret |= test(&ctx, "1 - -4", 5); ret |= test(&ctx, "(FOO-1)*2 + (BAR/2)%2 - -4", 5); + ret |= test(&ctx, "1-1 | 1", 1); + ret |= test(&ctx, "1-1 & 1", 0); + ret |= test(&ctx, "min(1,2) + 1", 2); + ret |= test(&ctx, "max(1,2) + 1", 3); + ret |= test(&ctx, "1+1 if 3*4 else 0", 2); if (ret) return ret; diff --git a/tools/perf/tests/fdarray.c b/tools/perf/tests/fdarray.c index bc5982f42dc3..c7c81c4a5b2b 100644 --- a/tools/perf/tests/fdarray.c +++ b/tools/perf/tests/fdarray.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "util/debug.h" @@ -26,7 +27,7 @@ static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE return printed + fdarray__fprintf(fda, fp); } -int test__fdarray__filter(int subtest __maybe_unused) +int test__fdarray__filter(struct test *test __maybe_unused, int subtest __maybe_unused) { int nr_fds, expected_fd[2], fd, err = TEST_FAIL; struct fdarray *fda = fdarray__new(5, 5); @@ -104,7 +105,7 @@ out: return err; } -int test__fdarray__add(int subtest __maybe_unused) +int test__fdarray__add(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct fdarray *fda = fdarray__new(2, 2); diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c index 00b8dc50f3db..f7c5b613d667 100644 --- a/tools/perf/tests/hists_common.c +++ b/tools/perf/tests/hists_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "perf.h" #include "util/debug.h" diff --git a/tools/perf/tests/hists_common.h b/tools/perf/tests/hists_common.h index 888254e8665c..a2de0ff0ce3a 100644 --- a/tools/perf/tests/hists_common.h +++ b/tools/perf/tests/hists_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_TESTS__HISTS_COMMON_H__ #define __PERF_TESTS__HISTS_COMMON_H__ diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index d549a9f2c41b..65fe02bebbee 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "perf.h" #include "util/debug.h" #include "util/event.h" @@ -687,7 +688,7 @@ out: return err; } -int test__hists_cumulate(int subtest __maybe_unused) +int test__hists_cumulate(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/hists_filter.c b/tools/perf/tests/hists_filter.c index df9c91f49af1..1c5bedab3c2c 100644 --- a/tools/perf/tests/hists_filter.c +++ b/tools/perf/tests/hists_filter.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "perf.h" #include "util/debug.h" #include "util/symbol.h" @@ -101,7 +102,7 @@ out: return TEST_FAIL; } -int test__hists_filter(int subtest __maybe_unused) +int test__hists_filter(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index a26cbb79e988..9a9d06cb0222 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "perf.h" #include "tests.h" #include "debug.h" @@ -264,7 +265,7 @@ static int validate_link(struct hists *leader, struct hists *other) return __validate_link(leader, 0) || __validate_link(other, 1); } -int test__hists_link(int subtest __maybe_unused) +int test__hists_link(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; struct hists *hists, *first_hists; diff --git a/tools/perf/tests/hists_output.c b/tools/perf/tests/hists_output.c index 06e5080182d3..faacb4f41460 100644 --- a/tools/perf/tests/hists_output.c +++ b/tools/perf/tests/hists_output.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "perf.h" #include "util/debug.h" #include "util/event.h" @@ -573,7 +574,7 @@ out: return err; } -int test__hists_output(int subtest __maybe_unused) +int test__hists_output(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = TEST_FAIL; struct machines machines; diff --git a/tools/perf/tests/is_printable_array.c b/tools/perf/tests/is_printable_array.c index a5192f6a20d7..9c7b3baca4fe 100644 --- a/tools/perf/tests/is_printable_array.c +++ b/tools/perf/tests/is_printable_array.c @@ -1,10 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "tests.h" #include "debug.h" #include "print_binary.h" -int test__is_printable_array(int subtest __maybe_unused) +int test__is_printable_array(struct test *test __maybe_unused, int subtest __maybe_unused) { char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 }; char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 }; diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 614e45a3c603..842d33637a18 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -49,7 +50,7 @@ static int find_comm(struct perf_evlist *evlist, const char *comm) * when an event is disabled but a dummy software event is not disabled. If the * test passes %0 is returned, otherwise %-1 is returned. */ -int test__keep_tracking(int subtest __maybe_unused) +int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .mmap_pages = UINT_MAX, diff --git a/tools/perf/tests/kmod-path.c b/tools/perf/tests/kmod-path.c index 6cd9e5107f77..8e57d46109de 100644 --- a/tools/perf/tests/kmod-path.c +++ b/tools/perf/tests/kmod-path.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "tests.h" @@ -50,7 +51,7 @@ static int test_is_kernel_module(const char *path, int cpumode, bool expect) #define M(path, c, e) \ TEST_ASSERT_VAL("failed", !test_is_kernel_module(path, c, e)) -int test__kmod_path__parse(int subtest __maybe_unused) +int test__kmod_path__parse(struct test *t __maybe_unused, int subtest __maybe_unused) { /* path alloc_name alloc_ext kmod comp name ext */ T("/xxxx/xxxx/x-x.ko", true , true , true, false, "[x_x]", NULL); diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 482b5365e68d..a039f93199e5 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -132,7 +133,7 @@ out: return ret; } -int test__llvm(int subtest) +int test__llvm(struct test *test __maybe_unused, int subtest) { int ret; void *obj_buf = NULL; diff --git a/tools/perf/tests/llvm.h b/tools/perf/tests/llvm.h index b83571758d83..f68b0d9b8ae2 100644 --- a/tools/perf/tests/llvm.h +++ b/tools/perf/tests/llvm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_TEST_LLVM_H #define PERF_TEST_LLVM_H diff --git a/tools/perf/tests/mem.c b/tools/perf/tests/mem.c new file mode 100644 index 000000000000..21952e1e6e6d --- /dev/null +++ b/tools/perf/tests/mem.c @@ -0,0 +1,56 @@ +#include "util/mem-events.h" +#include "util/symbol.h" +#include "linux/perf_event.h" +#include "util/debug.h" +#include "tests.h" +#include + +static int check(union perf_mem_data_src data_src, + const char *string) +{ + char out[100]; + char failure[100]; + struct mem_info mi = { .data_src = data_src }; + + int n; + + n = perf_mem__snp_scnprintf(out, sizeof out, &mi); + n += perf_mem__lvl_scnprintf(out + n, sizeof out - n, &mi); + snprintf(failure, sizeof failure, "unexpected %s", out); + TEST_ASSERT_VAL(failure, !strcmp(string, out)); + return 0; +} + +int test__mem(struct test *text __maybe_unused, int subtest __maybe_unused) +{ + int ret = 0; + union perf_mem_data_src src; + + memset(&src, 0, sizeof(src)); + + src.mem_lvl = PERF_MEM_LVL_HIT; + src.mem_lvl_num = 4; + + ret |= check(src, "N/AL4 hit"); + + src.mem_remote = 1; + + ret |= check(src, "N/ARemote L4 hit"); + + src.mem_lvl = PERF_MEM_LVL_MISS; + src.mem_lvl_num = PERF_MEM_LVLNUM_PMEM; + src.mem_remote = 0; + + ret |= check(src, "N/APMEM miss"); + + src.mem_remote = 1; + + ret |= check(src, "N/ARemote PMEM miss"); + + src.mem_snoopx = PERF_MEM_SNOOPX_FWD; + src.mem_lvl_num = PERF_MEM_LVLNUM_RAM; + + ret |= check(src , "FwdRemote RAM miss"); + + return ret; +} diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 15c770856aac..5a8bf318f8a7 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include /* For the CLR_() macros */ @@ -22,7 +23,7 @@ * Then it checks if the number of syscalls reported as perf events by * the kernel corresponds to the number of syscalls made. */ -int test__basic_mmap(int subtest __maybe_unused) +int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c index 6ea4d8a5d26b..3c3f3e029e33 100644 --- a/tools/perf/tests/mmap-thread-lookup.c +++ b/tools/perf/tests/mmap-thread-lookup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -221,7 +222,7 @@ static int mmap_events(synth_cb synth) * * by using all thread objects. */ -int test__mmap_thread_lookup(int subtest __maybe_unused) +int test__mmap_thread_lookup(struct test *test __maybe_unused, int subtest __maybe_unused) { /* perf_event__synthesize_threads synthesize */ TEST_ASSERT_VAL("failed with sythesizing all", diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c index 1a74dd9fd067..c531e6deb104 100644 --- a/tools/perf/tests/openat-syscall-all-cpus.c +++ b/tools/perf/tests/openat-syscall-all-cpus.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include /* For the CPU_* macros */ @@ -16,7 +17,7 @@ #include "debug.h" #include "stat.h" -int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused) +int test__openat_syscall_event_on_all_cpus(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd, cpu; struct cpu_map *cpus; @@ -115,7 +116,7 @@ int test__openat_syscall_event_on_all_cpus(int subtest __maybe_unused) perf_evsel__free_counts(evsel); out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); + perf_evsel__close_fd(evsel); out_evsel_delete: perf_evsel__delete(evsel); out_thread_map_delete: diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c index 9788fac91095..d9619d265314 100644 --- a/tools/perf/tests/openat-syscall-tp-fields.c +++ b/tools/perf/tests/openat-syscall-tp-fields.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "perf.h" #include "evlist.h" @@ -14,7 +15,7 @@ #define AT_FDCWD -100 #endif -int test__syscall_openat_tp_fields(int subtest __maybe_unused) +int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .target = { diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c index e44506e21ee7..00cd63f90b92 100644 --- a/tools/perf/tests/openat-syscall.c +++ b/tools/perf/tests/openat-syscall.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -10,7 +11,7 @@ #include "debug.h" #include "tests.h" -int test__openat_syscall_event(int subtest __maybe_unused) +int test__openat_syscall_event(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1, fd; struct perf_evsel *evsel; @@ -56,7 +57,7 @@ int test__openat_syscall_event(int subtest __maybe_unused) err = 0; out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); + perf_evsel__close_fd(evsel); out_evsel_delete: perf_evsel__delete(evsel); out_thread_map_delete: diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 812a053d1941..f0679613bd18 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "parse-events.h" #include "evsel.h" #include "evlist.h" @@ -1810,7 +1811,7 @@ static int test_pmu_events(void) return ret; } -int test__parse_events(int subtest __maybe_unused) +int test__parse_events(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret1, ret2 = 0; diff --git a/tools/perf/tests/parse-no-sample-id-all.c b/tools/perf/tests/parse-no-sample-id-all.c index c6207db09f12..2196d1497c0c 100644 --- a/tools/perf/tests/parse-no-sample-id-all.c +++ b/tools/perf/tests/parse-no-sample-id-all.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -68,7 +69,7 @@ struct test_attr_event { * * Return: %0 on success, %-1 if the test fails. */ -int test__parse_no_sample_id_all(int subtest __maybe_unused) +int test__parse_no_sample_id_all(struct test *test __maybe_unused, int subtest __maybe_unused) { int err; diff --git a/tools/perf/tests/perf-hooks.c b/tools/perf/tests/perf-hooks.c index 665ecc19671c..a693bcf017ea 100644 --- a/tools/perf/tests/perf-hooks.c +++ b/tools/perf/tests/perf-hooks.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -27,7 +28,7 @@ static void the_hook(void *_hook_flags) *p = 0; } -int test__perf_hooks(int subtest __maybe_unused) +int test__perf_hooks(struct test *test __maybe_unused, int subtest __maybe_unused) { int hook_flags = 0; diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index d37cd9588cc0..c34904d37705 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include /* For the CLR_() macros */ @@ -37,7 +38,7 @@ realloc: return cpu; } -int test__PERF_RECORD(int subtest __maybe_unused) +int test__PERF_RECORD(struct test *test __maybe_unused, int subtest __maybe_unused) { struct record_opts opts = { .target = { diff --git a/tools/perf/tests/perf-targz-src-pkg b/tools/perf/tests/perf-targz-src-pkg index f2d9c5fe58e0..fae26b1cf08f 100755 --- a/tools/perf/tests/perf-targz-src-pkg +++ b/tools/perf/tests/perf-targz-src-pkg @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # Test one of the main kernel Makefile targets to generate a perf sources tarball # suitable for build outside the full kernel sources. # diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index a6d7aef30030..9abca267afa9 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "parse-events.h" #include "pmu.h" #include "util.h" @@ -135,7 +136,7 @@ static struct list_head *test_terms_list(void) return &terms; } -int test__pmu(int subtest __maybe_unused) +int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused) { char *format = test_format_dir_get(); LIST_HEAD(formats); diff --git a/tools/perf/tests/python-use.c b/tools/perf/tests/python-use.c index fa79509da535..5d2df65ada6a 100644 --- a/tools/perf/tests/python-use.c +++ b/tools/perf/tests/python-use.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Just test if we can load the python binding. */ @@ -9,7 +10,7 @@ extern int verbose; -int test__python_use(int subtest __maybe_unused) +int test__python_use(struct test *test __maybe_unused, int subtest __maybe_unused) { char *cmd; int ret; diff --git a/tools/perf/tests/sample-parsing.c b/tools/perf/tests/sample-parsing.c index bac5c3885b3b..3ec6302b6498 100644 --- a/tools/perf/tests/sample-parsing.c +++ b/tools/perf/tests/sample-parsing.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -141,6 +142,9 @@ static bool samples_same(const struct perf_sample *s1, } } + if (type & PERF_SAMPLE_PHYS_ADDR) + COMP(phys_addr); + return true; } @@ -206,6 +210,7 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 read_format) .mask = sample_regs, .regs = regs, }, + .phys_addr = 113, }; struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},}; struct perf_sample sample_out; @@ -292,7 +297,7 @@ out_free: * checks sample format bits separately and together. If the test passes %0 is * returned, otherwise %-1 is returned. */ -int test__sample_parsing(int subtest __maybe_unused) +int test__sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) { const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15}; u64 sample_type; @@ -305,7 +310,7 @@ int test__sample_parsing(int subtest __maybe_unused) * were added. Please actually update the test rather than just change * the condition below. */ - if (PERF_SAMPLE_MAX > PERF_SAMPLE_REGS_INTR << 1) { + if (PERF_SAMPLE_MAX > PERF_SAMPLE_PHYS_ADDR << 1) { pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n"); return -1; } diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index 06eda675ae2c..5059452d27dd 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -33,7 +34,7 @@ static int build_id_cache__add_file(const char *filename) } build_id__sprintf(build_id, sizeof(build_id), sbuild_id); - err = build_id_cache__add_s(sbuild_id, filename, false, false); + err = build_id_cache__add_s(sbuild_id, filename, NULL, false, false); if (err < 0) pr_debug("Failed to add build id cache of %s\n", filename); return err; @@ -54,7 +55,7 @@ static char *get_self_path(void) static int search_cached_probe(const char *target, const char *group, const char *event) { - struct probe_cache *cache = probe_cache__new(target); + struct probe_cache *cache = probe_cache__new(target, NULL); int ret = 0; if (!cache) { @@ -71,7 +72,7 @@ static int search_cached_probe(const char *target, return ret; } -int test__sdt_event(int subtests __maybe_unused) +int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) { int ret = TEST_FAIL; char __tempdir[] = "./test-buildid-XXXXXX"; @@ -83,6 +84,8 @@ int test__sdt_event(int subtests __maybe_unused) } /* Note that buildid_dir must be an absolute path */ tempdir = realpath(__tempdir, NULL); + if (tempdir == NULL) + goto error_rmdir; /* At first, scan itself */ set_buildid_dir(tempdir); @@ -100,14 +103,14 @@ int test__sdt_event(int subtests __maybe_unused) error_rmdir: /* Cleanup temporary buildid dir */ - rm_rf(tempdir); + rm_rf(__tempdir); error: free(tempdir); free(myself); return ret; } #else -int test__sdt_event(int subtests __maybe_unused) +int test__sdt_event(struct test *test __maybe_unused, int subtests __maybe_unused) { pr_debug("Skip SDT event test because SDT support is not compiled\n"); return TEST_SKIP; diff --git a/tools/perf/tests/shell/lib/probe.sh b/tools/perf/tests/shell/lib/probe.sh new file mode 100644 index 000000000000..6293cc660947 --- /dev/null +++ b/tools/perf/tests/shell/lib/probe.sh @@ -0,0 +1,6 @@ +# Arnaldo Carvalho de Melo , 2017 + +skip_if_no_perf_probe() { + perf probe 2>&1 | grep -q 'is not a perf-command' && return 2 + return 0 +} diff --git a/tools/perf/tests/shell/lib/probe_vfs_getname.sh b/tools/perf/tests/shell/lib/probe_vfs_getname.sh new file mode 100644 index 000000000000..30a950c9d407 --- /dev/null +++ b/tools/perf/tests/shell/lib/probe_vfs_getname.sh @@ -0,0 +1,23 @@ +# Arnaldo Carvalho de Melo , 2017 + +perf probe -l 2>&1 | grep -q probe:vfs_getname +had_vfs_getname=$? + +cleanup_probe_vfs_getname() { + if [ $had_vfs_getname -eq 1 ] ; then + perf probe -q -d probe:vfs_getname + fi +} + +add_probe_vfs_getname() { + local verbose=$1 + if [ $had_vfs_getname -eq 1 ] ; then + line=$(perf probe -L getname_flags 2>&1 | egrep 'result.*=.*filename;' | sed -r 's/[[:space:]]+([[:digit:]]+)[[:space:]]+result->uptr.*/\1/') + perf probe $verbose "vfs_getname=getname_flags:${line} pathname=result->name:string" + fi +} + +skip_if_no_debuginfo() { + add_probe_vfs_getname -v 2>&1 | egrep -q "^(Failed to find the path for kernel|Debuginfo-analysis is not supported)" && return 2 + return 1 +} diff --git a/tools/perf/tests/shell/probe_vfs_getname.sh b/tools/perf/tests/shell/probe_vfs_getname.sh new file mode 100755 index 000000000000..9b7635184dc2 --- /dev/null +++ b/tools/perf/tests/shell/probe_vfs_getname.sh @@ -0,0 +1,14 @@ +# Add vfs_getname probe to get syscall args filenames +# +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +skip_if_no_perf_probe || exit 2 + +. $(dirname $0)/lib/probe_vfs_getname.sh + +add_probe_vfs_getname || skip_if_no_debuginfo +err=$? +cleanup_probe_vfs_getname +exit $err diff --git a/tools/perf/tests/shell/record+script_probe_vfs_getname.sh b/tools/perf/tests/shell/record+script_probe_vfs_getname.sh new file mode 100755 index 000000000000..ba29535b8580 --- /dev/null +++ b/tools/perf/tests/shell/record+script_probe_vfs_getname.sh @@ -0,0 +1,41 @@ +# Use vfs_getname probe to get syscall args filenames + +# Uses the 'perf test shell' library to add probe:vfs_getname to the system +# then use it with 'perf record' using 'touch' to write to a temp file, then +# checks that that was captured by the vfs_getname probe in the generated +# perf.data file, with the temp file name as the pathname argument. + +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +skip_if_no_perf_probe || exit 2 + +. $(dirname $0)/lib/probe_vfs_getname.sh + +perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) +file=$(mktemp /tmp/temporary_file.XXXXX) + +record_open_file() { + echo "Recording open file:" + perf record -o ${perfdata} -e probe:vfs_getname touch $file +} + +perf_script_filenames() { + echo "Looking at perf.data file for vfs_getname records for the file we touched:" + perf script -i ${perfdata} | \ + egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname: +\([[:xdigit:]]+\) +pathname=\"${file}\"" +} + +add_probe_vfs_getname || skip_if_no_debuginfo +err=$? +if [ $err -ne 0 ] ; then + exit $err +fi + +record_open_file && perf_script_filenames +err=$? +rm -f ${perfdata} +rm -f ${file} +cleanup_probe_vfs_getname +exit $err diff --git a/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh new file mode 100755 index 000000000000..7a84d73324e3 --- /dev/null +++ b/tools/perf/tests/shell/trace+probe_libc_inet_pton.sh @@ -0,0 +1,46 @@ +# probe libc's inet_pton & backtrace it with ping + +# Installs a probe on libc's inet_pton function, that will use uprobes, +# then use 'perf trace' on a ping to localhost asking for just one packet +# with the a backtrace 3 levels deep, check that it is what we expect. +# This needs no debuginfo package, all is done using the libc ELF symtab +# and the CFI info in the binaries. + +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +ld=$(realpath /lib64/ld*.so.* | uniq) +libc=$(echo $ld | sed 's/ld/libc/g') + +trace_libc_inet_pton_backtrace() { + idx=0 + expected[0]="PING.*bytes" + expected[1]="64 bytes from ::1.*" + expected[2]=".*ping statistics.*" + expected[3]=".*packets transmitted.*" + expected[4]="rtt min.*" + expected[5]="[0-9]+\.[0-9]+[[:space:]]+probe_libc:inet_pton:\([[:xdigit:]]+\)" + expected[6]=".*inet_pton[[:space:]]\($libc\)$" + expected[7]="getaddrinfo[[:space:]]\($libc\)$" + expected[8]=".*\(.*/bin/ping.*\)$" + + perf trace --no-syscalls -e probe_libc:inet_pton/max-stack=3/ ping -6 -c 1 ::1 2>&1 | grep -v ^$ | while read line ; do + echo $line + echo "$line" | egrep -q "${expected[$idx]}" + if [ $? -ne 0 ] ; then + printf "FAIL: expected backtrace entry %d \"%s\" got \"%s\"\n" $idx "${expected[$idx]}" "$line" + exit 1 + fi + let idx+=1 + [ $idx -eq 9 ] && break + done +} + +skip_if_no_perf_probe && \ +perf probe -q $libc inet_pton && \ +trace_libc_inet_pton_backtrace +err=$? +rm -f ${file} +perf probe -q -d probe_libc:inet_pton +exit $err diff --git a/tools/perf/tests/shell/trace+probe_vfs_getname.sh b/tools/perf/tests/shell/trace+probe_vfs_getname.sh new file mode 100755 index 000000000000..2e68c5f120da --- /dev/null +++ b/tools/perf/tests/shell/trace+probe_vfs_getname.sh @@ -0,0 +1,35 @@ +# Check open filename arg using perf trace + vfs_getname + +# Uses the 'perf test shell' library to add probe:vfs_getname to the system +# then use it with 'perf trace' using 'touch' to write to a temp file, then +# checks that that was captured by the vfs_getname was used by 'perf trace', +# that already handles "probe:vfs_getname" if present, and used in the +# "open" syscall "filename" argument beautifier. + +# Arnaldo Carvalho de Melo , 2017 + +. $(dirname $0)/lib/probe.sh + +skip_if_no_perf_probe || exit 2 + +. $(dirname $0)/lib/probe_vfs_getname.sh + +file=$(mktemp /tmp/temporary_file.XXXXX) + +trace_open_vfs_getname() { + perf trace -e open touch $file 2>&1 | \ + egrep " +[0-9]+\.[0-9]+ +\( +[0-9]+\.[0-9]+ ms\): +touch\/[0-9]+ open\(filename: +${file}, +flags: CREAT\|NOCTTY\|NONBLOCK\|WRONLY, +mode: +IRUGO\|IWUGO\) += +[0-9]+$" +} + + +add_probe_vfs_getname || skip_if_no_debuginfo +err=$? +if [ $err -ne 0 ] ; then + exit $err +fi + +trace_open_vfs_getname +err=$? +rm -f ${file} +cleanup_probe_vfs_getname +exit $err diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c index 6a20ff2326bb..94250024684a 100644 --- a/tools/perf/tests/stat.c +++ b/tools/perf/tests/stat.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "event.h" #include "tests.h" @@ -45,7 +46,7 @@ static int process_stat_config_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat_config(int subtest __maybe_unused) +int test__synthesize_stat_config(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_stat_config stat_config = { .aggr_mode = AGGR_CORE, @@ -75,7 +76,7 @@ static int process_stat_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat(int subtest __maybe_unused) +int test__synthesize_stat(struct test *test __maybe_unused, int subtest __maybe_unused) { struct perf_counts_values count; @@ -101,7 +102,7 @@ static int process_stat_round_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__synthesize_stat_round(int subtest __maybe_unused) +int test__synthesize_stat_round(struct test *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("failed to synthesize stat_config", !perf_event__synthesize_stat_round(NULL, 0xdeadbeef, PERF_STAT_ROUND_TYPE__INTERVAL, diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 828494db4a19..725a196991a8 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -124,7 +125,7 @@ out_delete_evlist: return err; } -int test__sw_clock_freq(int subtest __maybe_unused) +int test__sw_clock_freq(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret; diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c index 65474fd80da7..7d3f4bf9534f 100644 --- a/tools/perf/tests/switch-tracking.c +++ b/tools/perf/tests/switch-tracking.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -306,7 +307,7 @@ out_free_nodes: * evsel->system_wide and evsel->tracking flags (respectively) with other events * sometimes enabled or disabled. */ -int test__switch_tracking(int subtest __maybe_unused) +int test__switch_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) { const char *sched_switch = "sched:sched_switch"; struct switch_tracking switch_tracking = { .tids = NULL, }; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index cf00ebad2ef5..bc4a7344e274 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "evlist.h" #include "evsel.h" #include "thread_map.h" @@ -32,7 +33,7 @@ static void workload_exec_failed_signal(int signo __maybe_unused, * if the number of exit event reported by the kernel is 1 or not * in order to check the kernel returns correct number of event. */ -int test__task_exit(int subtest __maybe_unused) +int test__task_exit(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; union perf_event *event; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 577363809c9b..2862b80bc288 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef TESTS_H #define TESTS_H @@ -28,77 +29,79 @@ enum { struct test { const char *desc; - int (*func)(int subtest); + int (*func)(struct test *test, int subtest); struct { bool skip_if_fail; int (*get_nr)(void); const char *(*get_desc)(int subtest); } subtest; bool (*is_supported)(void); + void *priv; }; /* Tests */ -int test__vmlinux_matches_kallsyms(int subtest); -int test__openat_syscall_event(int subtest); -int test__openat_syscall_event_on_all_cpus(int subtest); -int test__basic_mmap(int subtest); -int test__PERF_RECORD(int subtest); -int test__perf_evsel__roundtrip_name_test(int subtest); -int test__perf_evsel__tp_sched_test(int subtest); -int test__syscall_openat_tp_fields(int subtest); -int test__pmu(int subtest); -int test__attr(int subtest); -int test__dso_data(int subtest); -int test__dso_data_cache(int subtest); -int test__dso_data_reopen(int subtest); -int test__parse_events(int subtest); -int test__hists_link(int subtest); -int test__python_use(int subtest); -int test__bp_signal(int subtest); -int test__bp_signal_overflow(int subtest); -int test__task_exit(int subtest); -int test__sw_clock_freq(int subtest); -int test__code_reading(int subtest); -int test__sample_parsing(int subtest); -int test__keep_tracking(int subtest); -int test__parse_no_sample_id_all(int subtest); -int test__dwarf_unwind(int subtest); -int test__expr(int subtest); -int test__hists_filter(int subtest); -int test__mmap_thread_lookup(int subtest); -int test__thread_mg_share(int subtest); -int test__hists_output(int subtest); -int test__hists_cumulate(int subtest); -int test__switch_tracking(int subtest); -int test__fdarray__filter(int subtest); -int test__fdarray__add(int subtest); -int test__kmod_path__parse(int subtest); -int test__thread_map(int subtest); -int test__llvm(int subtest); +int test__vmlinux_matches_kallsyms(struct test *test, int subtest); +int test__openat_syscall_event(struct test *test, int subtest); +int test__openat_syscall_event_on_all_cpus(struct test *test, int subtest); +int test__basic_mmap(struct test *test, int subtest); +int test__PERF_RECORD(struct test *test, int subtest); +int test__perf_evsel__roundtrip_name_test(struct test *test, int subtest); +int test__perf_evsel__tp_sched_test(struct test *test, int subtest); +int test__syscall_openat_tp_fields(struct test *test, int subtest); +int test__pmu(struct test *test, int subtest); +int test__attr(struct test *test, int subtest); +int test__dso_data(struct test *test, int subtest); +int test__dso_data_cache(struct test *test, int subtest); +int test__dso_data_reopen(struct test *test, int subtest); +int test__parse_events(struct test *test, int subtest); +int test__hists_link(struct test *test, int subtest); +int test__python_use(struct test *test, int subtest); +int test__bp_signal(struct test *test, int subtest); +int test__bp_signal_overflow(struct test *test, int subtest); +int test__task_exit(struct test *test, int subtest); +int test__mem(struct test *test, int subtest); +int test__sw_clock_freq(struct test *test, int subtest); +int test__code_reading(struct test *test, int subtest); +int test__sample_parsing(struct test *test, int subtest); +int test__keep_tracking(struct test *test, int subtest); +int test__parse_no_sample_id_all(struct test *test, int subtest); +int test__dwarf_unwind(struct test *test, int subtest); +int test__expr(struct test *test, int subtest); +int test__hists_filter(struct test *test, int subtest); +int test__mmap_thread_lookup(struct test *test, int subtest); +int test__thread_mg_share(struct test *test, int subtest); +int test__hists_output(struct test *test, int subtest); +int test__hists_cumulate(struct test *test, int subtest); +int test__switch_tracking(struct test *test, int subtest); +int test__fdarray__filter(struct test *test, int subtest); +int test__fdarray__add(struct test *test, int subtest); +int test__kmod_path__parse(struct test *test, int subtest); +int test__thread_map(struct test *test, int subtest); +int test__llvm(struct test *test, int subtest); const char *test__llvm_subtest_get_desc(int subtest); int test__llvm_subtest_get_nr(void); -int test__bpf(int subtest); +int test__bpf(struct test *test, int subtest); const char *test__bpf_subtest_get_desc(int subtest); int test__bpf_subtest_get_nr(void); -int test_session_topology(int subtest); -int test__thread_map_synthesize(int subtest); -int test__thread_map_remove(int subtest); -int test__cpu_map_synthesize(int subtest); -int test__synthesize_stat_config(int subtest); -int test__synthesize_stat(int subtest); -int test__synthesize_stat_round(int subtest); -int test__event_update(int subtest); -int test__event_times(int subtest); -int test__backward_ring_buffer(int subtest); -int test__cpu_map_print(int subtest); -int test__sdt_event(int subtest); -int test__is_printable_array(int subtest); -int test__bitmap_print(int subtest); -int test__perf_hooks(int subtest); -int test__clang(int subtest); +int test__session_topology(struct test *test, int subtest); +int test__thread_map_synthesize(struct test *test, int subtest); +int test__thread_map_remove(struct test *test, int subtest); +int test__cpu_map_synthesize(struct test *test, int subtest); +int test__synthesize_stat_config(struct test *test, int subtest); +int test__synthesize_stat(struct test *test, int subtest); +int test__synthesize_stat_round(struct test *test, int subtest); +int test__event_update(struct test *test, int subtest); +int test__event_times(struct test *test, int subtest); +int test__backward_ring_buffer(struct test *test, int subtest); +int test__cpu_map_print(struct test *test, int subtest); +int test__sdt_event(struct test *test, int subtest); +int test__is_printable_array(struct test *test, int subtest); +int test__bitmap_print(struct test *test, int subtest); +int test__perf_hooks(struct test *test, int subtest); +int test__clang(struct test *test, int subtest); const char *test__clang_subtest_get_desc(int subtest); int test__clang_subtest_get_nr(void); -int test__unit_number__scnprint(int subtest); +int test__unit_number__scnprint(struct test *test, int subtest); bool test__bp_signal_is_supported(void); diff --git a/tools/perf/tests/thread-map.c b/tools/perf/tests/thread-map.c index a63d6945807b..dbcb6a19b375 100644 --- a/tools/perf/tests/thread-map.c +++ b/tools/perf/tests/thread-map.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -9,7 +10,7 @@ #define NAME (const char *) "perf" #define NAMEUL (unsigned long) NAME -int test__thread_map(int subtest __maybe_unused) +int test__thread_map(struct test *test __maybe_unused, int subtest __maybe_unused) { struct thread_map *map; @@ -76,7 +77,7 @@ static int process_event(struct perf_tool *tool __maybe_unused, return 0; } -int test__thread_map_synthesize(int subtest __maybe_unused) +int test__thread_map_synthesize(struct test *test __maybe_unused, int subtest __maybe_unused) { struct thread_map *threads; @@ -95,7 +96,7 @@ int test__thread_map_synthesize(int subtest __maybe_unused) return 0; } -int test__thread_map_remove(int subtest __maybe_unused) +int test__thread_map_remove(struct test *test __maybe_unused, int subtest __maybe_unused) { struct thread_map *threads; char *str; diff --git a/tools/perf/tests/thread-mg-share.c b/tools/perf/tests/thread-mg-share.c index 76686dd6f5ec..b1d1bbafe7ae 100644 --- a/tools/perf/tests/thread-mg-share.c +++ b/tools/perf/tests/thread-mg-share.c @@ -1,10 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 #include "tests.h" #include "machine.h" #include "thread.h" #include "map.h" #include "debug.h" -int test__thread_mg_share(int subtest __maybe_unused) +int test__thread_mg_share(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machines machines; struct machine *machine; diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index 803f893550d6..a59db7c45a65 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -86,7 +87,7 @@ static int check_cpu_topology(char *path, struct cpu_map *map) return 0; } -int test_session_topology(int subtest __maybe_unused) +int test__session_topology(struct test *test __maybe_unused, int subtest __maybe_unused) { char path[PATH_MAX]; struct cpu_map *map; diff --git a/tools/perf/tests/unit_number__scnprintf.c b/tools/perf/tests/unit_number__scnprintf.c index 44589de084b8..2bb8cb0039c1 100644 --- a/tools/perf/tests/unit_number__scnprintf.c +++ b/tools/perf/tests/unit_number__scnprintf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -5,7 +6,7 @@ #include "units.h" #include "debug.h" -int test__unit_number__scnprint(int subtest __maybe_unused) +int test__unit_number__scnprint(struct test *t __maybe_unused, int subtest __maybe_unused) { struct { u64 n; diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c index 8456175fc234..f6789fb029d6 100644 --- a/tools/perf/tests/vmlinux-kallsyms.c +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -11,7 +12,7 @@ #define UM(x) kallsyms_map->unmap_ip(kallsyms_map, (x)) -int test__vmlinux_matches_kallsyms(int subtest __maybe_unused) +int test__vmlinux_matches_kallsyms(struct test *test __maybe_unused, int subtest __maybe_unused) { int err = -1; struct rb_node *nd; diff --git a/tools/perf/trace/beauty/Build b/tools/perf/trace/beauty/Build index be95ac6ce845..175d633c6b49 100644 --- a/tools/perf/trace/beauty/Build +++ b/tools/perf/trace/beauty/Build @@ -1 +1,7 @@ +libperf-y += clone.o +libperf-y += fcntl.o +ifeq ($(SRCARCH),$(filter $(SRCARCH),x86)) +libperf-y += ioctl.o +endif +libperf-y += pkey_alloc.o libperf-y += statx.o diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index cf50be3f17a4..d80655cd1881 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h @@ -1,13 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_TRACE_BEAUTY_H #define _PERF_TRACE_BEAUTY_H +#include #include +struct strarray { + int offset; + int nr_entries; + const char **entries; +}; + +#define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + +#define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \ + .offset = off, \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + +size_t strarray__scnprintf(struct strarray *sa, char *bf, size_t size, const char *intfmt, int val); + struct trace; struct thread; +/** + * @val: value of syscall argument being formatted + * @args: All the args, use syscall_args__val(arg, nth) to access one + * @thread: tid state (maps, pid, tid, etc) + * @trace: 'perf trace' internals: all threads, etc + * @parm: private area, may be an strarray, for instance + * @idx: syscall arg idx (is this the first?) + * @mask: a syscall arg may mask another arg, see syscall_arg__scnprintf_futex_op + */ + struct syscall_arg { unsigned long val; + unsigned char *args; struct thread *thread; struct trace *trace; void *parm; @@ -15,10 +47,53 @@ struct syscall_arg { u8 mask; }; +unsigned long syscall_arg__val(struct syscall_arg *arg, u8 idx); + +size_t syscall_arg__scnprintf_strarrays(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_STRARRAYS syscall_arg__scnprintf_strarrays + +size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FD syscall_arg__scnprintf_fd + +size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_HEX syscall_arg__scnprintf_hex + +size_t syscall_arg__scnprintf_int(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_INT syscall_arg__scnprintf_int + +size_t syscall_arg__scnprintf_long(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_LONG syscall_arg__scnprintf_long + +size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_PID syscall_arg__scnprintf_pid + +size_t syscall_arg__scnprintf_clone_flags(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_CLONE_FLAGS syscall_arg__scnprintf_clone_flags + +size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FCNTL_CMD syscall_arg__scnprintf_fcntl_cmd + +size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_FCNTL_ARG syscall_arg__scnprintf_fcntl_arg + +size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_IOCTL_CMD syscall_arg__scnprintf_ioctl_cmd + +size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_PKEY_ALLOC_ACCESS_RIGHTS syscall_arg__scnprintf_pkey_alloc_access_rights + +size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg); +#define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags + size_t syscall_arg__scnprintf_statx_flags(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_FLAGS syscall_arg__scnprintf_statx_flags size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_arg *arg); #define SCA_STATX_MASK syscall_arg__scnprintf_statx_mask +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size); + +void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, + size_t (*ret_scnprintf)(char *bf, size_t size, struct syscall_arg *arg)); + #endif /* _PERF_TRACE_BEAUTY_H */ diff --git a/tools/perf/trace/beauty/clone.c b/tools/perf/trace/beauty/clone.c new file mode 100644 index 000000000000..d64d049ab991 --- /dev/null +++ b/tools/perf/trace/beauty/clone.c @@ -0,0 +1,75 @@ +/* + * trace/beauty/cone.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include +#include +#include + +static size_t clone__scnprintf_flags(unsigned long flags, char *bf, size_t size) +{ + int printed = 0; + +#define P_FLAG(n) \ + if (flags & CLONE_##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + flags &= ~CLONE_##n; \ + } + + P_FLAG(VM); + P_FLAG(FS); + P_FLAG(FILES); + P_FLAG(SIGHAND); + P_FLAG(PTRACE); + P_FLAG(VFORK); + P_FLAG(PARENT); + P_FLAG(THREAD); + P_FLAG(NEWNS); + P_FLAG(SYSVSEM); + P_FLAG(SETTLS); + P_FLAG(PARENT_SETTID); + P_FLAG(CHILD_CLEARTID); + P_FLAG(DETACHED); + P_FLAG(UNTRACED); + P_FLAG(CHILD_SETTID); + P_FLAG(NEWCGROUP); + P_FLAG(NEWUTS); + P_FLAG(NEWIPC); + P_FLAG(NEWUSER); + P_FLAG(NEWPID); + P_FLAG(NEWNET); + P_FLAG(IO); +#undef P_FLAG + + if (flags) + printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags); + + return printed; +} + +size_t syscall_arg__scnprintf_clone_flags(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long flags = arg->val; + enum syscall_clone_args { + SCC_FLAGS = (1 << 0), + SCC_CHILD_STACK = (1 << 1), + SCC_PARENT_TIDPTR = (1 << 2), + SCC_CHILD_TIDPTR = (1 << 3), + SCC_TLS = (1 << 4), + }; + if (!(flags & CLONE_PARENT_SETTID)) + arg->mask |= SCC_PARENT_TIDPTR; + + if (!(flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))) + arg->mask |= SCC_CHILD_TIDPTR; + + if (!(flags & CLONE_SETTLS)) + arg->mask |= SCC_TLS; + + return clone__scnprintf_flags(flags, bf, size); +} diff --git a/tools/perf/trace/beauty/drm_ioctl.sh b/tools/perf/trace/beauty/drm_ioctl.sh new file mode 100755 index 000000000000..2149d3a98e42 --- /dev/null +++ b/tools/perf/trace/beauty/drm_ioctl.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +drm_header_dir=$1 +printf "#ifndef DRM_COMMAND_BASE\n" +grep "#define DRM_COMMAND_BASE" $drm_header_dir/drm.h +printf "#endif\n" + +printf "static const char *drm_ioctl_cmds[] = {\n" +grep "^#define DRM_IOCTL.*DRM_IO" $drm_header_dir/drm.h | \ + sed -r 's/^#define +DRM_IOCTL_([A-Z0-9_]+)[ ]+DRM_IO[A-Z]* *\( *(0x[[:xdigit:]]+),*.*/ [\2] = "\1",/g' +grep "^#define DRM_I915_[A-Z_0-9]\+[ ]\+0x" $drm_header_dir/i915_drm.h | \ + sed -r 's/^#define +DRM_I915_([A-Z0-9_]+)[ ]+(0x[[:xdigit:]]+)/\t[DRM_COMMAND_BASE + \2] = "I915_\1",/g' +printf "};\n" diff --git a/tools/perf/trace/beauty/eventfd.c b/tools/perf/trace/beauty/eventfd.c index b08f21eb6f4d..5d6a477a6400 100644 --- a/tools/perf/trace/beauty/eventfd.c +++ b/tools/perf/trace/beauty/eventfd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef EFD_SEMAPHORE #define EFD_SEMAPHORE 1 #endif diff --git a/tools/perf/trace/beauty/fcntl.c b/tools/perf/trace/beauty/fcntl.c new file mode 100644 index 000000000000..9e8900c13cb1 --- /dev/null +++ b/tools/perf/trace/beauty/fcntl.c @@ -0,0 +1,100 @@ +/* + * trace/beauty/fcntl.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include +#include + +static size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size) +{ + return scnprintf(bf, size, "%s", val ? "CLOEXEC" : "0"); +} + +static size_t syscall_arg__scnprintf_fcntl_getfd(char *bf, size_t size, struct syscall_arg *arg) +{ + return fcntl__scnprintf_getfd(arg->val, bf, size); +} + +static size_t fcntl__scnprintf_getlease(unsigned long val, char *bf, size_t size) +{ + static const char *fcntl_setlease[] = { "RDLCK", "WRLCK", "UNLCK", }; + static DEFINE_STRARRAY(fcntl_setlease); + + return strarray__scnprintf(&strarray__fcntl_setlease, bf, size, "%x", val); +} + +static size_t syscall_arg__scnprintf_fcntl_getlease(char *bf, size_t size, struct syscall_arg *arg) +{ + return fcntl__scnprintf_getlease(arg->val, bf, size); +} + +size_t syscall_arg__scnprintf_fcntl_cmd(char *bf, size_t size, struct syscall_arg *arg) +{ + if (arg->val == F_GETFL) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_open_flags); + goto mask_arg; + } + if (arg->val == F_GETFD) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fcntl_getfd); + goto mask_arg; + } + if (arg->val == F_DUPFD_CLOEXEC || arg->val == F_DUPFD) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fd); + goto out; + } + if (arg->val == F_GETOWN) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_pid); + goto mask_arg; + } + if (arg->val == F_GETLEASE) { + syscall_arg__set_ret_scnprintf(arg, syscall_arg__scnprintf_fcntl_getlease); + goto mask_arg; + } + /* + * Some commands ignore the third fcntl argument, "arg", so mask it + */ + if (arg->val == F_GET_SEALS || + arg->val == F_GETSIG) { +mask_arg: + arg->mask |= (1 << 2); + } +out: + return syscall_arg__scnprintf_strarrays(bf, size, arg); +} + +size_t syscall_arg__scnprintf_fcntl_arg(char *bf, size_t size, struct syscall_arg *arg) +{ + int cmd = syscall_arg__val(arg, 1); + + if (cmd == F_DUPFD) + return syscall_arg__scnprintf_fd(bf, size, arg); + + if (cmd == F_SETFD) + return fcntl__scnprintf_getfd(arg->val, bf, size); + + if (cmd == F_SETFL) + return open__scnprintf_flags(arg->val, bf, size); + + if (cmd == F_SETOWN) + return syscall_arg__scnprintf_pid(bf, size, arg); + + if (cmd == F_SETLEASE) + return fcntl__scnprintf_getlease(arg->val, bf, size); + /* + * We still don't grab the contents of pointers on entry or exit, + * so just print them as hex numbers + */ + if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK || + cmd == F_OFD_SETLK || cmd == F_OFD_SETLKW || cmd == F_OFD_GETLK || + cmd == F_GETOWN_EX || cmd == F_SETOWN_EX || + cmd == F_GET_RW_HINT || cmd == F_SET_RW_HINT || + cmd == F_GET_FILE_RW_HINT || cmd == F_SET_FILE_RW_HINT) + return syscall_arg__scnprintf_hex(bf, size, arg); + + return syscall_arg__scnprintf_long(bf, size, arg); +} diff --git a/tools/perf/trace/beauty/flock.c b/tools/perf/trace/beauty/flock.c index 74613703a14e..f9707f57566c 100644 --- a/tools/perf/trace/beauty/flock.c +++ b/tools/perf/trace/beauty/flock.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #ifndef LOCK_MAND diff --git a/tools/perf/trace/beauty/futex_op.c b/tools/perf/trace/beauty/futex_op.c index bfd3359b09b6..61850fbc85ff 100644 --- a/tools/perf/trace/beauty/futex_op.c +++ b/tools/perf/trace/beauty/futex_op.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #ifndef FUTEX_WAIT_BITSET diff --git a/tools/perf/trace/beauty/ioctl.c b/tools/perf/trace/beauty/ioctl.c new file mode 100644 index 000000000000..1be3b4cf0827 --- /dev/null +++ b/tools/perf/trace/beauty/ioctl.c @@ -0,0 +1,162 @@ +/* + * trace/beauty/ioctl.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include + +/* + * FIXME: to support all arches we have to improve this, for + * now, to build on older systems without things like TIOCGEXCL, + * get it directly from our copy. + * + * Right now only x86 is being supported for beautifying ioctl args + * in 'perf trace', see tools/perf/trace/beauty/Build and builtin-trace.c + */ +#include + +static size_t ioctl__scnprintf_tty_cmd(int nr, int dir, char *bf, size_t size) +{ + static const char *ioctl_tty_cmd[] = { + "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW", + "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL", "TIOCSCTTY", + "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI", "TIOCGWINSZ", "TIOCSWINSZ", + "TIOCMGET", "TIOCMBIS", "TIOCMBIC", "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", + "FIONREAD", "TIOCLINUX", "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", + "FIONBIO", "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", + [_IOC_NR(TIOCSBRK)] = "TIOCSBRK", "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", + "TCSETSW2", "TCSETSF2", "TIOCGRS48", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK", + "TIOCGDEV", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG", "TIOCVHANGUP", "TIOCGPKT", + "TIOCGPTLCK", [_IOC_NR(TIOCGEXCL)] = "TIOCGEXCL", "TIOCGPTPEER", + [_IOC_NR(FIONCLEX)] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG", + "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS", + "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI", + "TIOCMIWAIT", "TIOCGICOUNT", }; + static DEFINE_STRARRAY(ioctl_tty_cmd); + + if (nr < strarray__ioctl_tty_cmd.nr_entries && strarray__ioctl_tty_cmd.entries[nr] != NULL) + return scnprintf(bf, size, "%s", strarray__ioctl_tty_cmd.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'T', nr, dir); +} + +static size_t ioctl__scnprintf_drm_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/drm_ioctl_array.c" + static DEFINE_STRARRAY(drm_ioctl_cmds); + + if (nr < strarray__drm_ioctl_cmds.nr_entries && strarray__drm_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "DRM_%s", strarray__drm_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'd', nr, dir); +} + +static size_t ioctl__scnprintf_sndrv_pcm_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/sndrv_pcm_ioctl_array.c" + static DEFINE_STRARRAY(sndrv_pcm_ioctl_cmds); + + if (nr < strarray__sndrv_pcm_ioctl_cmds.nr_entries && strarray__sndrv_pcm_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "SNDRV_PCM_%s", strarray__sndrv_pcm_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'A', nr, dir); +} + +static size_t ioctl__scnprintf_sndrv_ctl_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/sndrv_ctl_ioctl_array.c" + static DEFINE_STRARRAY(sndrv_ctl_ioctl_cmds); + + if (nr < strarray__sndrv_ctl_ioctl_cmds.nr_entries && strarray__sndrv_ctl_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "SNDRV_CTL_%s", strarray__sndrv_ctl_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 'U', nr, dir); +} + +static size_t ioctl__scnprintf_kvm_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/kvm_ioctl_array.c" + static DEFINE_STRARRAY(kvm_ioctl_cmds); + + if (nr < strarray__kvm_ioctl_cmds.nr_entries && strarray__kvm_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "KVM_%s", strarray__kvm_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAE, nr, dir); +} + +static size_t ioctl__scnprintf_vhost_virtio_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/vhost_virtio_ioctl_array.c" + static DEFINE_STRARRAY(vhost_virtio_ioctl_cmds); + static DEFINE_STRARRAY(vhost_virtio_ioctl_read_cmds); + struct strarray *s = (dir & _IOC_READ) ? &strarray__vhost_virtio_ioctl_read_cmds : &strarray__vhost_virtio_ioctl_cmds; + + if (nr < s->nr_entries && s->entries[nr] != NULL) + return scnprintf(bf, size, "VHOST_%s", s->entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAF, nr, dir); +} + +static size_t ioctl__scnprintf_perf_cmd(int nr, int dir, char *bf, size_t size) +{ +#include "trace/beauty/generated/ioctl/perf_ioctl_array.c" + static DEFINE_STRARRAY(perf_ioctl_cmds); + + if (nr < strarray__perf_ioctl_cmds.nr_entries && strarray__perf_ioctl_cmds.entries[nr] != NULL) + return scnprintf(bf, size, "PERF_%s", strarray__perf_ioctl_cmds.entries[nr]); + + return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAE, nr, dir); +} + +static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size) +{ + int dir = _IOC_DIR(cmd), + type = _IOC_TYPE(cmd), + nr = _IOC_NR(cmd), + sz = _IOC_SIZE(cmd); + int printed = 0; + static const struct ioctl_type { + int type; + size_t (*scnprintf)(int nr, int dir, char *bf, size_t size); + } ioctl_types[] = { /* Must be ordered by type */ + { .type = '$', .scnprintf = ioctl__scnprintf_perf_cmd, }, + ['A' - '$'] = { .type = 'A', .scnprintf = ioctl__scnprintf_sndrv_pcm_cmd, }, + ['T' - '$'] = { .type = 'T', .scnprintf = ioctl__scnprintf_tty_cmd, }, + ['U' - '$'] = { .type = 'U', .scnprintf = ioctl__scnprintf_sndrv_ctl_cmd, }, + ['d' - '$'] = { .type = 'd', .scnprintf = ioctl__scnprintf_drm_cmd, }, + [0xAE - '$'] = { .type = 0xAE, .scnprintf = ioctl__scnprintf_kvm_cmd, }, + [0xAF - '$'] = { .type = 0xAF, .scnprintf = ioctl__scnprintf_vhost_virtio_cmd, }, + }; + const int nr_types = ARRAY_SIZE(ioctl_types); + + if (type >= ioctl_types[0].type && type <= ioctl_types[nr_types - 1].type) { + const int index = type - ioctl_types[0].type; + + if (ioctl_types[index].scnprintf != NULL) + return ioctl_types[index].scnprintf(nr, dir, bf, size); + } + + printed += scnprintf(bf + printed, size - printed, "%c", '('); + + if (dir == _IOC_NONE) { + printed += scnprintf(bf + printed, size - printed, "%s", "NONE"); + } else { + if (dir & _IOC_READ) + printed += scnprintf(bf + printed, size - printed, "%s", "READ"); + if (dir & _IOC_WRITE) + printed += scnprintf(bf + printed, size - printed, "%s%s", dir & _IOC_READ ? "|" : "", "WRITE"); + } + + return printed + scnprintf(bf + printed, size - printed, ", %#x, %#x, %#x)", type, nr, sz); +} + +size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long cmd = arg->val; + + return ioctl__scnprintf_cmd(cmd, bf, size); +} diff --git a/tools/perf/trace/beauty/kvm_ioctl.sh b/tools/perf/trace/beauty/kvm_ioctl.sh new file mode 100755 index 000000000000..bd28817afced --- /dev/null +++ b/tools/perf/trace/beauty/kvm_ioctl.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +kvm_header_dir=$1 + +printf "static const char *kvm_ioctl_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+KVM_(\w+)[[:space:]]+_IO[RW]*\([[:space:]]*KVMIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' +egrep $regex ${kvm_header_dir}/kvm.h | \ + sed -r "s/$regex/\2 \1/g" | \ + egrep -v " ((ARM|PPC|S390)_|[GS]ET_(DEBUGREGS|PIT2|XSAVE|TSC_KHZ)|CREATE_SPAPR_TCE_64)" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index af1cfde6b97b..51f1cea406f5 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, @@ -34,6 +35,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, { int printed = 0, flags = arg->val; + if (flags & MAP_ANONYMOUS) + arg->mask |= (1 << 4) | (1 << 5); /* Mask 4th ('fd') and 5th ('offset') args, ignored */ + #define P_MMAP_FLAG(n) \ if (flags & MAP_##n) { \ printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ diff --git a/tools/perf/trace/beauty/mode_t.c b/tools/perf/trace/beauty/mode_t.c index 930d8fef2400..d929ad7dd97b 100644 --- a/tools/perf/trace/beauty/mode_t.c +++ b/tools/perf/trace/beauty/mode_t.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/trace/beauty/msg_flags.c b/tools/perf/trace/beauty/msg_flags.c index 1106c8960cc4..c064d6aae659 100644 --- a/tools/perf/trace/beauty/msg_flags.c +++ b/tools/perf/trace/beauty/msg_flags.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/trace/beauty/open_flags.c b/tools/perf/trace/beauty/open_flags.c index f55a4597fc38..6aec6178a99d 100644 --- a/tools/perf/trace/beauty/open_flags.c +++ b/tools/perf/trace/beauty/open_flags.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -14,13 +15,16 @@ #define O_NOATIME 01000000 #endif -static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, - struct syscall_arg *arg) -{ - int printed = 0, flags = arg->val; +#ifndef O_TMPFILE +#define O_TMPFILE 020000000 +#endif - if (!(flags & O_CREAT)) - arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ +#undef O_LARGEFILE +#define O_LARGEFILE 00100000 + +size_t open__scnprintf_flags(unsigned long flags, char *bf, size_t size) +{ + int printed = 0; if (flags == 0) return scnprintf(bf, size, "RDONLY"); @@ -30,6 +34,7 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, flags &= ~O_##n; \ } + P_FLAG(RDWR); P_FLAG(APPEND); P_FLAG(ASYNC); P_FLAG(CLOEXEC); @@ -38,6 +43,8 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, P_FLAG(DIRECTORY); P_FLAG(EXCL); P_FLAG(LARGEFILE); + P_FLAG(NOFOLLOW); + P_FLAG(TMPFILE); P_FLAG(NOATIME); P_FLAG(NOCTTY); #ifdef O_NONBLOCK @@ -48,7 +55,6 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, #ifdef O_PATH P_FLAG(PATH); #endif - P_FLAG(RDWR); #ifdef O_DSYNC if ((flags & O_SYNC) == O_SYNC) printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", "SYNC"); @@ -68,4 +74,12 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, return printed; } -#define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags +size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) +{ + int flags = arg->val; + + if (!(flags & O_CREAT)) + arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ + + return open__scnprintf_flags(flags, bf, size); +} diff --git a/tools/perf/trace/beauty/perf_event_open.c b/tools/perf/trace/beauty/perf_event_open.c index 311f09dd718d..2bafd7c995ff 100644 --- a/tools/perf/trace/beauty/perf_event_open.c +++ b/tools/perf/trace/beauty/perf_event_open.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef PERF_FLAG_FD_NO_GROUP # define PERF_FLAG_FD_NO_GROUP (1UL << 0) #endif diff --git a/tools/perf/trace/beauty/perf_ioctl.sh b/tools/perf/trace/beauty/perf_ioctl.sh new file mode 100755 index 000000000000..faea4237c793 --- /dev/null +++ b/tools/perf/trace/beauty/perf_ioctl.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +header_dir=$1 + +printf "static const char *perf_ioctl_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+PERF_EVENT_IOC_(\w+)[[:space:]]+_IO[RW]*[[:space:]]*\([[:space:]]*.\$.[[:space:]]*,[[:space:]]*([[:digit:]]+).*' +egrep $regex ${header_dir}/perf_event.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/pid.c b/tools/perf/trace/beauty/pid.c index 07486ea65ae3..0313df342830 100644 --- a/tools/perf/trace/beauty/pid.c +++ b/tools/perf/trace/beauty/pid.c @@ -1,4 +1,5 @@ -static size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg) +// SPDX-License-Identifier: GPL-2.0 +size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_arg *arg) { int pid = arg->val; struct trace *trace = arg->trace; @@ -17,5 +18,3 @@ static size_t syscall_arg__scnprintf_pid(char *bf, size_t size, struct syscall_a return printed; } - -#define SCA_PID syscall_arg__scnprintf_pid diff --git a/tools/perf/trace/beauty/pkey_alloc.c b/tools/perf/trace/beauty/pkey_alloc.c new file mode 100644 index 000000000000..2ba784a3734a --- /dev/null +++ b/tools/perf/trace/beauty/pkey_alloc.c @@ -0,0 +1,50 @@ +/* + * trace/beauty/pkey_alloc.c + * + * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo + * + * Released under the GPL v2. (and only v2, not any later version) + */ + +#include "trace/beauty/beauty.h" +#include +#include + +static size_t pkey_alloc__scnprintf_access_rights(int access_rights, char *bf, size_t size) +{ + int i, printed = 0; + +#include "trace/beauty/generated/pkey_alloc_access_rights_array.c" + static DEFINE_STRARRAY(pkey_alloc_access_rights); + + if (access_rights == 0) { + const char *s = strarray__pkey_alloc_access_rights.entries[0]; + if (s) + return scnprintf(bf, size, "%s", s); + return scnprintf(bf, size, "%d", 0); + } + + for (i = 1; i < strarray__pkey_alloc_access_rights.nr_entries; ++i) { + int bit = 1 << (i - 1); + + if (!(access_rights & bit)) + continue; + + if (printed != 0) + printed += scnprintf(bf + printed, size - printed, "|"); + + if (strarray__pkey_alloc_access_rights.entries[i] != NULL) + printed += scnprintf(bf + printed, size - printed, "%s", strarray__pkey_alloc_access_rights.entries[i]); + else + printed += scnprintf(bf + printed, size - printed, "0x%#", bit); + } + + return printed; +} + +size_t syscall_arg__scnprintf_pkey_alloc_access_rights(char *bf, size_t size, struct syscall_arg *arg) +{ + unsigned long cmd = arg->val; + + return pkey_alloc__scnprintf_access_rights(cmd, bf, size); +} diff --git a/tools/perf/trace/beauty/pkey_alloc_access_rights.sh b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh new file mode 100755 index 000000000000..62e51a02b839 --- /dev/null +++ b/tools/perf/trace/beauty/pkey_alloc_access_rights.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +header_dir=$1 + +printf "static const char *pkey_alloc_access_rights[] = {\n" +regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+PKEY_([[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*' +egrep $regex ${header_dir}/mman-common.h | \ + sed -r "s/$regex/\2 \2 \1/g" | \ + sort | xargs printf "\t[%s ? (ilog2(%s) + 1) : 0] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/sched_policy.c b/tools/perf/trace/beauty/sched_policy.c index 34775295b9b3..ba5096ae76b6 100644 --- a/tools/perf/trace/beauty/sched_policy.c +++ b/tools/perf/trace/beauty/sched_policy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include /* diff --git a/tools/perf/trace/beauty/seccomp.c b/tools/perf/trace/beauty/seccomp.c index 356441bce27d..b7097fd5fed9 100644 --- a/tools/perf/trace/beauty/seccomp.c +++ b/tools/perf/trace/beauty/seccomp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #ifndef SECCOMP_SET_MODE_STRICT #define SECCOMP_SET_MODE_STRICT 0 #endif diff --git a/tools/perf/trace/beauty/signum.c b/tools/perf/trace/beauty/signum.c index fde8f2fc6558..bde18a53f090 100644 --- a/tools/perf/trace/beauty/signum.c +++ b/tools/perf/trace/beauty/signum.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg) diff --git a/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh new file mode 100755 index 000000000000..aad5ab130539 --- /dev/null +++ b/tools/perf/trace/beauty/sndrv_ctl_ioctl.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +sound_header_dir=$1 + +printf "static const char *sndrv_ctl_ioctl_cmds[] = {\n" +grep "^#define[\t ]\+SNDRV_CTL_IOCTL_" $sound_header_dir/asound.h | \ + sed -r 's/^#define +SNDRV_CTL_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.U., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' +printf "};\n" diff --git a/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh new file mode 100755 index 000000000000..b7e9ef6b2f55 --- /dev/null +++ b/tools/perf/trace/beauty/sndrv_pcm_ioctl.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +sound_header_dir=$1 + +printf "static const char *sndrv_pcm_ioctl_cmds[] = {\n" +grep "^#define[\t ]\+SNDRV_PCM_IOCTL_" $sound_header_dir/asound.h | \ + sed -r 's/^#define +SNDRV_PCM_IOCTL_([A-Z0-9_]+)[\t ]+_IO[RW]*\( *.A., *(0x[[:xdigit:]]+),?.*/\t[\2] = \"\1\",/g' +printf "};\n" diff --git a/tools/perf/trace/beauty/socket_type.c b/tools/perf/trace/beauty/socket_type.c index 0a5ce818131c..bca26aef4a77 100644 --- a/tools/perf/trace/beauty/socket_type.c +++ b/tools/perf/trace/beauty/socket_type.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/trace/beauty/vhost_virtio_ioctl.sh b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh new file mode 100755 index 000000000000..76f1de697787 --- /dev/null +++ b/tools/perf/trace/beauty/vhost_virtio_ioctl.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +vhost_virtio_header_dir=$1 + +printf "static const char *vhost_virtio_ioctl_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' +egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" + +printf "static const char *vhost_virtio_ioctl_read_cmds[] = {\n" +regex='^#[[:space:]]*define[[:space:]]+VHOST_(\w+)[[:space:]]+_IOW?R\([[:space:]]*VHOST_VIRTIO[[:space:]]*,[[:space:]]*(0x[[:xdigit:]]+).*' +egrep $regex ${vhost_virtio_header_dir}/vhost.h | \ + sed -r "s/$regex/\2 \1/g" | \ + sort | xargs printf "\t[%s] = \"%s\",\n" +printf "};\n" diff --git a/tools/perf/trace/beauty/waitid_options.c b/tools/perf/trace/beauty/waitid_options.c index 7942724adec8..8465281a093d 100644 --- a/tools/perf/trace/beauty/waitid_options.c +++ b/tools/perf/trace/beauty/waitid_options.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 83874b0e266c..63399af3049f 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../util.h" #include "../string2.h" #include "../config.h" @@ -8,6 +9,7 @@ #include #include #include +#include #include #include #include "browser.h" @@ -563,7 +565,7 @@ static int ui_browser__color_config(const char *var, const char *value, int i; /* same dir for all commands */ - if (prefixcmp(var, "colors.") != 0) + if (!strstarts(var, "colors.") != 0) return 0; for (i = 0; ui_browser__colorsets[i].name != NULL; ++i) { @@ -738,6 +740,35 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, __ui_browser__line_arrow_down(browser, column, start, end); } +void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, + unsigned int row, bool arrow_down) +{ + unsigned int end_row; + + if (row >= browser->top_idx) + end_row = row - browser->top_idx; + else + return; + + SLsmg_set_char_set(1); + + if (arrow_down) { + ui_browser__gotorc(browser, end_row, column - 1); + SLsmg_write_char(SLSMG_ULCORN_CHAR); + ui_browser__gotorc(browser, end_row, column); + SLsmg_draw_hline(2); + ui_browser__gotorc(browser, end_row + 1, column - 1); + SLsmg_write_char(SLSMG_LTEE_CHAR); + } else { + ui_browser__gotorc(browser, end_row, column - 1); + SLsmg_write_char(SLSMG_LTEE_CHAR); + ui_browser__gotorc(browser, end_row, column); + SLsmg_draw_hline(2); + } + + SLsmg_set_char_set(0); +} + void ui_browser__init(void) { int i = 0; diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h index be3b70eb5fca..03e1734412b9 100644 --- a/tools/perf/ui/browser.h +++ b/tools/perf/ui/browser.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_BROWSER_H_ #define _PERF_UI_BROWSER_H_ 1 @@ -43,6 +44,8 @@ void ui_browser__printf(struct ui_browser *browser, const char *fmt, ...); void ui_browser__write_graph(struct ui_browser *browser, int graph); void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column, u64 start, u64 end); +void ui_browser__mark_fused(struct ui_browser *browser, unsigned int column, + unsigned int row, bool arrow_down); void __ui_browser__show_title(struct ui_browser *browser, const char *title); void ui_browser__show_title(struct ui_browser *browser, const char *title); int ui_browser__show(struct ui_browser *browser, const char *title, diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 27f41f28dcb4..8f7f59d1a2b5 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../../util/util.h" #include "../browser.h" #include "../helpline.h" @@ -9,14 +10,16 @@ #include "../../util/symbol.h" #include "../../util/evsel.h" #include "../../util/config.h" +#include "../../util/evlist.h" #include #include #include +#include #include struct disasm_line_samples { - double percent; - u64 nr; + double percent; + struct sym_hist_entry he; }; #define IPC_WIDTH 6 @@ -40,6 +43,7 @@ static struct annotate_browser_opt { jump_arrows, show_linenr, show_nr_jumps, + show_nr_samples, show_total_period; } annotate_browser__opts = { .use_offset = true, @@ -108,11 +112,12 @@ static int annotate_browser__set_jumps_percent_color(struct annotate_browser *br static int annotate_browser__pcnt_width(struct annotate_browser *ab) { - int w = 7 * ab->nr_events; + return (annotate_browser__opts.show_total_period ? 12 : 7) * ab->nr_events; +} - if (ab->have_cycles) - w += IPC_WIDTH + CYCLES_WIDTH; - return w; +static int annotate_browser__cycles_width(struct annotate_browser *ab) +{ + return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0; } static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) @@ -125,7 +130,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int (!current_entry || (browser->use_navkeypressed && !browser->navkeypressed))); int width = browser->width, printed; - int i, pcnt_width = annotate_browser__pcnt_width(ab); + int i, pcnt_width = annotate_browser__pcnt_width(ab), + cycles_width = annotate_browser__cycles_width(ab); double percent_max = 0.0; char bf[256]; bool show_title = false; @@ -149,8 +155,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int bdl->samples[i].percent, current_entry); if (annotate_browser__opts.show_total_period) { + ui_browser__printf(browser, "%11" PRIu64 " ", + bdl->samples[i].he.period); + } else if (annotate_browser__opts.show_nr_samples) { ui_browser__printf(browser, "%6" PRIu64 " ", - bdl->samples[i].nr); + bdl->samples[i].he.nr_samples); } else { ui_browser__printf(browser, "%6.2f ", bdl->samples[i].percent); @@ -160,9 +169,12 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int ui_browser__set_percent_color(browser, 0, current_entry); if (!show_title) - ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); - else - ui_browser__printf(browser, "%*s", 7, "Percent"); + ui_browser__write_nstring(browser, " ", pcnt_width); + else { + ui_browser__printf(browser, "%*s", pcnt_width, + annotate_browser__opts.show_total_period ? "Period" : + annotate_browser__opts.show_nr_samples ? "Samples" : "Percent"); + } } if (ab->have_cycles) { if (dl->ipc) @@ -188,7 +200,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int width += 1; if (!*dl->line) - ui_browser__write_nstring(browser, " ", width - pcnt_width); + ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); else if (dl->offset == -1) { if (dl->line_nr && annotate_browser__opts.show_linenr) printed = scnprintf(bf, sizeof(bf), "%-*d ", @@ -197,7 +209,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int printed = scnprintf(bf, sizeof(bf), "%*s ", ab->addr_width, " "); ui_browser__write_nstring(browser, bf, printed); - ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width + 1); + ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width - cycles_width + 1); } else { u64 addr = dl->offset; int color = -1; @@ -254,7 +266,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int } disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); - ui_browser__write_nstring(browser, bf, width - pcnt_width - 3 - printed); + ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed); } if (current_entry) @@ -272,6 +284,25 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy return true; } +static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) +{ + struct disasm_line *pos = list_prev_entry(cursor, node); + const char *name; + + if (!pos) + return false; + + if (ins__is_lock(&pos->ins)) + name = pos->ops.locked.ins.name; + else + name = pos->ins.name; + + if (!name || !cursor->ins.name) + return false; + + return ins__is_fused(ab->arch, name, cursor->ins.name); +} + static void annotate_browser__draw_current_jump(struct ui_browser *browser) { struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); @@ -307,6 +338,13 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); __ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width, from, to); + + if (is_fused(ab, cursor)) { + ui_browser__mark_fused(browser, + pcnt_width + 3 + ab->addr_width, + from - 1, + to > from ? true : false); + } } static unsigned int annotate_browser__refresh(struct ui_browser *browser) @@ -422,14 +460,14 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, next = disasm__get_next_ip_line(¬es->src->source, pos); for (i = 0; i < browser->nr_events; i++) { - u64 nr_samples; + struct sym_hist_entry sample; bpos->samples[i].percent = disasm__calc_percent(notes, evsel->idx + i, pos->offset, next ? next->offset : len, - &path, &nr_samples); - bpos->samples[i].nr = nr_samples; + &path, &sample); + bpos->samples[i].he = sample; if (max_percent < bpos->samples[i].percent) max_percent = bpos->samples[i].percent; @@ -792,13 +830,14 @@ static int annotate_browser__run(struct annotate_browser *browser, "q/ESC/CTRL+C Exit\n\n" "ENTER Go to target\n" "ESC Exit\n" - "H Cycle thru hottest instructions\n" + "H Go to hottest instruction\n" + "TAB/shift+TAB Cycle thru hottest instructions\n" "j Toggle showing jump to target arrows\n" "J Toggle showing number of jump sources on targets\n" "n Search next string\n" "o Toggle disassembler output/simplified view\n" "s Toggle source code view\n" - "t Toggle total period view\n" + "t Circulate percent, total period, samples view\n" "/ Search string\n" "k Toggle line numbers\n" "r Run available scripts\n" @@ -875,8 +914,13 @@ show_sup_ins: } continue; case 't': - annotate_browser__opts.show_total_period = - !annotate_browser__opts.show_total_period; + if (annotate_browser__opts.show_total_period) { + annotate_browser__opts.show_total_period = false; + annotate_browser__opts.show_nr_samples = true; + } else if (annotate_browser__opts.show_nr_samples) + annotate_browser__opts.show_nr_samples = false; + else + annotate_browser__opts.show_total_period = true; annotate_browser__update_addr_width(browser); continue; case K_LEFT: @@ -899,9 +943,11 @@ out: int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, struct hist_browser_timer *hbt) { - /* Set default value for show_total_period. */ + /* Set default value for show_total_period and show_nr_samples */ annotate_browser__opts.show_total_period = - symbol_conf.show_total_period; + symbol_conf.show_total_period; + annotate_browser__opts.show_nr_samples = + symbol_conf.show_nr_samples; return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt); } @@ -1074,7 +1120,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, } err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - sizeof_bdl, &browser.arch); + sizeof_bdl, &browser.arch, + perf_evsel__env_cpuid(evsel)); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); @@ -1151,6 +1198,7 @@ static struct annotate_config { ANNOTATE_CFG(jump_arrows), ANNOTATE_CFG(show_linenr), ANNOTATE_CFG(show_nr_jumps), + ANNOTATE_CFG(show_nr_samples), ANNOTATE_CFG(show_total_period), ANNOTATE_CFG(use_offset), }; @@ -1170,7 +1218,7 @@ static int annotate__config(const char *var, const char *value, struct annotate_config *cfg; const char *name; - if (prefixcmp(var, "annotate.") != 0) + if (!strstarts(var, "annotate.")) return 0; name = var + 9; diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c index e2c9390ff4c5..d75492189acb 100644 --- a/tools/perf/ui/browsers/header.c +++ b/tools/perf/ui/browsers/header.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util/cache.h" #include "util/debug.h" #include "ui/browser.h" diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 69f4570bd4f9..628ad5f7eddb 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -166,9 +167,6 @@ static struct inline_node *inline_node__create(struct map *map, u64 ip) if (dso == NULL) return NULL; - if (dso->kernel != DSO_TYPE_USER) - return NULL; - node = dso__parse_addr_inlines(dso, map__rip_2objdump(map, ip)); @@ -934,12 +932,8 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, browser->show_dso); if (symbol_conf.show_branchflag_count) { - if (need_percent) - callchain_list_counts__printf_value(node, chain, NULL, - buf, sizeof(buf)); - else - callchain_list_counts__printf_value(NULL, chain, NULL, - buf, sizeof(buf)); + callchain_list_counts__printf_value(chain, NULL, + buf, sizeof(buf)); if (asprintf(&alloc_str2, "%s%s", str, buf) < 0) str = "Not enough memory!"; diff --git a/tools/perf/ui/browsers/hists.h b/tools/perf/ui/browsers/hists.h index 23d6acb84800..ba431777f559 100644 --- a/tools/perf/ui/browsers/hists.h +++ b/tools/perf/ui/browsers/hists.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_BROWSER_HISTS_H_ #define _PERF_UI_BROWSER_HISTS_H_ 1 diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index ffa5addf631d..e03fa75f108a 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/ui/browsers/map.h b/tools/perf/ui/browsers/map.h index 2d58e4b3eb6f..0ed7dbb3a373 100644 --- a/tools/perf/ui/browsers/map.h +++ b/tools/perf/ui/browsers/map.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_MAP_BROWSER_H_ #define _PERF_UI_MAP_BROWSER_H_ 1 struct map; diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c index ad6b6ee3770e..90a32ac69e76 100644 --- a/tools/perf/ui/browsers/scripts.c +++ b/tools/perf/ui/browsers/scripts.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index d903fd493416..fc7a2e105bfd 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "gtk.h" #include "util/debug.h" #include "util/annotate.h" @@ -34,10 +35,10 @@ static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym, return 0; symhist = annotation__histogram(symbol__annotation(sym), evidx); - if (!symbol_conf.event_group && !symhist->addr[dl->offset]) + if (!symbol_conf.event_group && !symhist->addr[dl->offset].nr_samples) return 0; - percent = 100.0 * symhist->addr[dl->offset] / symhist->sum; + percent = 100.0 * symhist->addr[dl->offset].nr_samples / symhist->nr_samples; markup = perf_gtk__get_percent_color(percent); if (markup) @@ -169,7 +170,7 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map, return -1; err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - 0, NULL); + 0, NULL, NULL); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index c24d91221290..4820e25ac68d 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../evlist.h" #include "../cache.h" #include "../evsel.h" diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 0a9173ff9a61..9846ea5c831b 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_GTK_H_ #define _PERF_GTK_H_ 1 diff --git a/tools/perf/ui/gtk/helpline.c b/tools/perf/ui/gtk/helpline.c index 3388cbd12186..fbf1ea9ce9a2 100644 --- a/tools/perf/ui/gtk/helpline.c +++ b/tools/perf/ui/gtk/helpline.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index e24f83957705..24e1ec201ffd 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../evlist.h" #include "../cache.h" #include "../evsel.h" diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c index b656655fbc39..b6ad8857da78 100644 --- a/tools/perf/ui/gtk/progress.c +++ b/tools/perf/ui/gtk/progress.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "gtk.h" diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c index 1d57676f8212..506e73b3834c 100644 --- a/tools/perf/ui/gtk/setup.c +++ b/tools/perf/ui/gtk/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "gtk.h" #include "../../util/cache.h" #include "../../util/debug.h" diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index 00b91921edb1..7250d8101c8f 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../util.h" #include "../../util/util.h" #include "../../util/debug.h" diff --git a/tools/perf/ui/helpline.c b/tools/perf/ui/helpline.c index 379039ab00d8..b3c421429ed4 100644 --- a/tools/perf/ui/helpline.c +++ b/tools/perf/ui/helpline.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/ui/helpline.h b/tools/perf/ui/helpline.h index d52d0a1a881b..8f775a053ca3 100644 --- a/tools/perf/ui/helpline.h +++ b/tools/perf/ui/helpline.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_HELPLINE_H_ #define _PERF_UI_HELPLINE_H_ 1 diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index ddb2c6fbdf91..706f6f1e9c7d 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -532,7 +533,7 @@ void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list, void perf_hpp__column_unregister(struct perf_hpp_fmt *format) { - list_del(&format->list); + list_del_init(&format->list); } void perf_hpp__cancel_cumulate(void) @@ -606,6 +607,13 @@ next: static void fmt_free(struct perf_hpp_fmt *fmt) { + /* + * At this point fmt should be completely + * unhooked, if not it's a bug. + */ + BUG_ON(!list_empty(&fmt->list)); + BUG_ON(!list_empty(&fmt->sort_list)); + if (fmt->free) fmt->free(fmt); } diff --git a/tools/perf/ui/keysyms.h b/tools/perf/ui/keysyms.h index 65092d576b4e..fbfac29077f2 100644 --- a/tools/perf/ui/keysyms.h +++ b/tools/perf/ui/keysyms.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_KEYSYMS_H_ #define _PERF_KEYSYMS_H_ 1 diff --git a/tools/perf/ui/libslang.h b/tools/perf/ui/libslang.h index db816695ad97..c0686cda39a5 100644 --- a/tools/perf/ui/libslang.h +++ b/tools/perf/ui/libslang.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_SLANG_H_ #define _PERF_UI_SLANG_H_ 1 /* diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c index a0f24c7115c5..b5a5df14d702 100644 --- a/tools/perf/ui/progress.c +++ b/tools/perf/ui/progress.c @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: GPL-2.0 +#include #include "../cache.h" #include "progress.h" @@ -14,10 +16,14 @@ struct ui_progress_ops *ui_progress__ops = &null_progress__ops; void ui_progress__update(struct ui_progress *p, u64 adv) { + u64 last = p->curr; + p->curr += adv; if (p->curr >= p->next) { - p->next += p->step; + u64 nr = DIV_ROUND_UP(p->curr - last, p->step); + + p->next += nr * p->step; ui_progress__ops->update(p); } } @@ -25,7 +31,7 @@ void ui_progress__update(struct ui_progress *p, u64 adv) void ui_progress__init(struct ui_progress *p, u64 total, const char *title) { p->curr = 0; - p->next = p->step = total / 16; + p->next = p->step = total / 16 ?: 1; p->total = total; p->title = title; diff --git a/tools/perf/ui/progress.h b/tools/perf/ui/progress.h index 717d39d3052b..594bbe6935dd 100644 --- a/tools/perf/ui/progress.h +++ b/tools/perf/ui/progress.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_PROGRESS_H_ #define _PERF_UI_PROGRESS_H_ 1 diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index caf1ce6f5152..44fe824e96cd 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 42e432bd2eb4..de2810ae16be 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -1,4 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 #include +#include #include "../../util/util.h" #include "../../util/hist.h" @@ -35,9 +37,6 @@ static size_t inline__fprintf(struct map *map, u64 ip, int left_margin, if (dso == NULL) return 0; - if (dso->kernel != DSO_TYPE_USER) - return 0; - node = dso__parse_addr_inlines(dso, map__rip_2objdump(map, ip)); if (node == NULL) @@ -126,12 +125,8 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node, str = callchain_list__sym_name(chain, bf, sizeof(bf), false); if (symbol_conf.show_branchflag_count) { - if (!period) - callchain_list_counts__printf_value(node, chain, NULL, - buf, sizeof(buf)); - else - callchain_list_counts__printf_value(NULL, chain, NULL, - buf, sizeof(buf)); + callchain_list_counts__printf_value(chain, NULL, + buf, sizeof(buf)); if (asprintf(&alloc_str, "%s%s", str, buf) < 0) str = "Not enough memory!"; @@ -295,7 +290,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, * displayed twice. */ if (!i++ && field_order == NULL && - sort_order && !prefixcmp(sort_order, "sym")) + sort_order && strstarts(sort_order, "sym")) continue; if (!printed) { @@ -315,7 +310,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root, if (symbol_conf.show_branchflag_count) ret += callchain_list_counts__printf_value( - NULL, chain, fp, NULL, 0); + chain, fp, NULL, 0); ret += fprintf(fp, "\n"); if (++entries_printed == callchain_param.print_limit) diff --git a/tools/perf/ui/tui/helpline.c b/tools/perf/ui/tui/helpline.c index 88f5143a5981..4ca799aadb4e 100644 --- a/tools/perf/ui/tui/helpline.c +++ b/tools/perf/ui/tui/helpline.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c index c4b99008e2c9..236bcb620ae4 100644 --- a/tools/perf/ui/tui/progress.c +++ b/tools/perf/ui/tui/progress.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../cache.h" #include "../progress.h" #include "../libslang.h" diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index d9350a1da48b..d4ac41679721 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/ui/tui/tui.h b/tools/perf/ui/tui/tui.h index 18961c7b6ec5..8de06f634c56 100644 --- a/tools/perf/ui/tui/tui.h +++ b/tools/perf/ui/tui/tui.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_TUI_H_ #define _PERF_TUI_H_ 1 diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c index d96ad7c8325d..b9794d6185af 100644 --- a/tools/perf/ui/tui/util.c +++ b/tools/perf/ui/tui/util.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../../util/util.h" #include #include diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h index 4b6fb6c7a542..9b6fdf06e1d2 100644 --- a/tools/perf/ui/ui.h +++ b/tools/perf/ui/ui.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_H_ #define _PERF_UI_H_ 1 diff --git a/tools/perf/ui/util.c b/tools/perf/ui/util.c index e3e0a963d03a..63bf06e80ab9 100644 --- a/tools/perf/ui/util.c +++ b/tools/perf/ui/util.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util.h" #include "../debug.h" diff --git a/tools/perf/ui/util.h b/tools/perf/ui/util.h index 361f08c52d37..5e44223b56fa 100644 --- a/tools/perf/ui/util.h +++ b/tools/perf/ui/util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UI_UTIL_H_ #define _PERF_UI_UTIL_H_ 1 diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 79dea95a7f68..94518c1bf8b6 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -22,6 +22,7 @@ libperf-y += rbtree.o libperf-y += libstring.o libperf-y += bitmap.o libperf-y += hweight.o +libperf-y += smt.o libperf-y += quote.o libperf-y += strbuf.o libperf-y += string.o @@ -93,6 +94,7 @@ libperf-y += drv_configs.o libperf-y += units.o libperf-y += time-utils.o libperf-y += expr-bison.o +libperf-y += branch.o libperf-$(CONFIG_LIBBPF) += bpf-loader.o libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o @@ -104,6 +106,10 @@ ifndef CONFIG_LIBELF libperf-y += symbol-minimal.o endif +ifndef CONFIG_SETNS +libperf-y += setns.o +endif + libperf-$(CONFIG_DWARF) += probe-finder.o libperf-$(CONFIG_DWARF) += dwarf-aux.o libperf-$(CONFIG_DWARF) += dwarf-regs.o diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index 39f17507578d..3802cee5e188 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 if [ $# -eq 1 ] ; then OUTPUT=$1 diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index be1caabb9290..aa66791b1bfc 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -47,7 +47,12 @@ struct arch { bool sorted_instructions; bool initialized; void *priv; + unsigned int model; + unsigned int family; int (*init)(struct arch *arch); + bool (*ins_is_fused)(struct arch *arch, const char *ins1, + const char *ins2); + int (*cpuid_parse)(struct arch *arch, char *cpuid); struct { char comment_char; char skip_functions_char; @@ -129,6 +134,8 @@ static struct arch architectures[] = { .name = "x86", .instructions = x86__instructions, .nr_instructions = ARRAY_SIZE(x86__instructions), + .ins_is_fused = x86__ins_is_fused, + .cpuid_parse = x86__cpuid_parse, .objdump = { .comment_char = '#', }, @@ -171,6 +178,14 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size, return ins__raw_scnprintf(ins, bf, size, ops); } +bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) +{ + if (!arch || !arch->ins_is_fused) + return false; + + return arch->ins_is_fused(arch, ins1, ins2); +} + static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) { char *endptr, *tok, *name; @@ -502,6 +517,11 @@ bool ins__is_ret(const struct ins *ins) return ins->ops == &ret_ops; } +bool ins__is_lock(const struct ins *ins) +{ + return ins->ops == &lock_ops; +} + static int ins__key_cmp(const void *name, const void *insp) { const struct ins *ins = insp; @@ -586,14 +606,24 @@ static struct arch *arch__find(const char *name) int symbol__alloc_hist(struct symbol *sym) { struct annotation *notes = symbol__annotation(sym); - const size_t size = symbol__size(sym); + size_t size = symbol__size(sym); size_t sizeof_sym_hist; + /* + * Add buffer of one element for zero length symbol. + * When sample is taken from first instruction of + * zero length symbol, perf still resolves it and + * shows symbol name in perf report and allows to + * annotate it. + */ + if (size == 0) + size = 1; + /* Check for overflow when calculating sizeof_sym_hist */ - if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64)) + if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) return -1; - sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); + sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry)); /* Check for overflow in zalloc argument */ if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) @@ -677,7 +707,8 @@ static int __symbol__account_cycles(struct annotation *notes, } static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, - struct annotation *notes, int evidx, u64 addr) + struct annotation *notes, int evidx, u64 addr, + struct perf_sample *sample) { unsigned offset; struct sym_hist *h; @@ -693,12 +724,15 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, offset = addr - sym->start; h = annotation__histogram(notes, evidx); - h->sum++; - h->addr[offset]++; + h->nr_samples++; + h->addr[offset].nr_samples++; + h->period += sample->period; + h->addr[offset].period += sample->period; pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 - ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, - addr, addr - sym->start, evidx, h->addr[offset]); + ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n", + sym->start, sym->name, addr, addr - sym->start, evidx, + h->addr[offset].nr_samples, h->addr[offset].period); return 0; } @@ -718,7 +752,8 @@ static struct annotation *symbol__get_annotation(struct symbol *sym, bool cycles } static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, - int evidx, u64 addr) + int evidx, u64 addr, + struct perf_sample *sample) { struct annotation *notes; @@ -727,7 +762,7 @@ static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, notes = symbol__get_annotation(sym, false); if (notes == NULL) return -ENOMEM; - return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); + return __symbol__inc_addr_samples(sym, map, notes, evidx, addr, sample); } static int symbol__account_cycles(u64 addr, u64 start, @@ -791,14 +826,16 @@ int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, return err; } -int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) +int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, + int evidx) { - return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); + return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr, sample); } -int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) +int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, + int evidx, u64 ip) { - return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); + return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample); } static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) @@ -908,11 +945,12 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa } double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, - s64 end, const char **path, u64 *nr_samples) + s64 end, const char **path, struct sym_hist_entry *sample) { struct source_line *src_line = notes->src->lines; double percent = 0.0; - *nr_samples = 0; + + sample->nr_samples = sample->period = 0; if (src_line) { size_t sizeof_src_line = sizeof(*src_line) + @@ -926,19 +964,24 @@ double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, *path = src_line->path; percent += src_line->samples[evidx].percent; - *nr_samples += src_line->samples[evidx].nr; + sample->nr_samples += src_line->samples[evidx].nr; offset++; } } else { struct sym_hist *h = annotation__histogram(notes, evidx); unsigned int hits = 0; + u64 period = 0; - while (offset < end) - hits += h->addr[offset++]; + while (offset < end) { + hits += h->addr[offset].nr_samples; + period += h->addr[offset].period; + ++offset; + } - if (h->sum) { - *nr_samples = hits; - percent = 100.0 * hits / h->sum; + if (h->nr_samples) { + sample->period = period; + sample->nr_samples = hits; + percent = 100.0 * hits / h->nr_samples; } } @@ -1037,10 +1080,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (dl->offset != -1) { const char *path = NULL; - u64 nr_samples; double percent, max_percent = 0.0; double *ppercents = &percent; - u64 *psamples = &nr_samples; + struct sym_hist_entry sample; + struct sym_hist_entry *psamples = &sample; int i, nr_percent = 1; const char *color; struct annotation *notes = symbol__annotation(sym); @@ -1054,7 +1097,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (perf_evsel__is_group_event(evsel)) { nr_percent = evsel->nr_members; ppercents = calloc(nr_percent, sizeof(double)); - psamples = calloc(nr_percent, sizeof(u64)); + psamples = calloc(nr_percent, sizeof(struct sym_hist_entry)); if (ppercents == NULL || psamples == NULL) { return -1; } @@ -1065,10 +1108,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st notes->src->lines ? i : evsel->idx + i, offset, next ? next->offset : (s64) len, - &path, &nr_samples); + &path, &sample); ppercents[i] = percent; - psamples[i] = nr_samples; + psamples[i] = sample; if (percent > max_percent) max_percent = percent; } @@ -1106,12 +1149,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st for (i = 0; i < nr_percent; i++) { percent = ppercents[i]; - nr_samples = psamples[i]; + sample = psamples[i]; color = get_percent_color(percent); if (symbol_conf.show_total_period) + color_fprintf(stdout, color, " %11" PRIu64, + sample.period); + else if (symbol_conf.show_nr_samples) color_fprintf(stdout, color, " %7" PRIu64, - nr_samples); + sample.nr_samples); else color_fprintf(stdout, color, " %7.2f", percent); } @@ -1127,13 +1173,13 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st if (ppercents != &percent) free(ppercents); - if (psamples != &nr_samples) + if (psamples != &sample) free(psamples); } else if (max_lines && printed >= max_lines) return 1; else { - int width = 8; + int width = symbol_conf.show_total_period ? 12 : 8; if (queue) return -1; @@ -1327,7 +1373,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil !dso__is_kcore(dso)) return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; - build_id_filename = dso__build_id_filename(dso, NULL, 0); + build_id_filename = dso__build_id_filename(dso, NULL, 0, false); if (build_id_filename) { __symbol__join_symfs(filename, filename_size, build_id_filename); free(build_id_filename); @@ -1381,7 +1427,7 @@ static const char *annotate__norm_arch(const char *arch_name) int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize, - struct arch **parch) + struct arch **parch, char *cpuid) { struct dso *dso = map->dso; char command[PATH_MAX * 2]; @@ -1418,6 +1464,9 @@ int symbol__disassemble(struct symbol *sym, struct map *map, } } + if (arch->cpuid_parse && cpuid) + arch->cpuid_parse(arch, cpuid); + pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, symfs_filename, sym->name, map->unmap_ip(map, sym->start), map->unmap_ip(map, sym->end)); @@ -1648,19 +1697,19 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, struct sym_hist *h = annotation__histogram(notes, evidx); struct rb_root tmp_root = RB_ROOT; int nr_pcnt = 1; - u64 h_sum = h->sum; + u64 nr_samples = h->nr_samples; size_t sizeof_src_line = sizeof(struct source_line); if (perf_evsel__is_group_event(evsel)) { for (i = 1; i < evsel->nr_members; i++) { h = annotation__histogram(notes, evidx + i); - h_sum += h->sum; + nr_samples += h->nr_samples; } nr_pcnt = evsel->nr_members; sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->samples); } - if (!h_sum) + if (!nr_samples) return 0; src_line = notes->src->lines = calloc(len, sizeof_src_line); @@ -1670,7 +1719,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, start = map__rip_2objdump(map, sym->start); for (i = 0; i < len; i++) { - u64 offset, nr_samples; + u64 offset; double percent_max = 0.0; src_line->nr_pcnt = nr_pcnt; @@ -1679,9 +1728,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, double percent = 0.0; h = annotation__histogram(notes, evidx + k); - nr_samples = h->addr[i]; - if (h->sum) - percent = 100.0 * nr_samples / h->sum; + nr_samples = h->addr[i].nr_samples; + if (h->nr_samples) + percent = 100.0 * nr_samples / h->nr_samples; if (percent > percent_max) percent_max = percent; @@ -1750,10 +1799,10 @@ static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) u64 len = symbol__size(sym), offset; for (offset = 0; offset < len; ++offset) - if (h->addr[offset] != 0) + if (h->addr[offset].nr_samples != 0) printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, - sym->start + offset, h->addr[offset]); - printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); + sym->start + offset, h->addr[offset].nr_samples); + printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples); } int symbol__annotate_printf(struct symbol *sym, struct map *map, @@ -1771,7 +1820,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int printed = 2, queue_len = 0; int more = 0; u64 len; - int width = 8; + int width = symbol_conf.show_total_period ? 12 : 8; int graph_dotted_len; filename = strdup(dso->long_name); @@ -1789,7 +1838,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, width *= evsel->nr_members; graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n", - width, width, "Percent", d_filename, evsel_name, h->sum); + width, width, symbol_conf.show_total_period ? "Period" : + symbol_conf.show_nr_samples ? "Samples" : "Percent", + d_filename, evsel_name, h->nr_samples); printf("%-*.*s----\n", graph_dotted_len, graph_dotted_len, graph_dotted_line); @@ -1853,10 +1904,10 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) struct sym_hist *h = annotation__histogram(notes, evidx); int len = symbol__size(sym), offset; - h->sum = 0; + h->nr_samples = 0; for (offset = 0; offset < len; ++offset) { - h->addr[offset] = h->addr[offset] * 7 / 8; - h->sum += h->addr[offset]; + h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8; + h->nr_samples += h->addr[offset].nr_samples; } } @@ -1907,7 +1958,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, u64 len; if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - 0, NULL) < 0) + 0, NULL, NULL) < 0) return -1; len = symbol__size(sym); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 21055034aedd..f6ba3560de5e 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_ANNOTATE_H #define __PERF_ANNOTATE_H @@ -52,7 +53,9 @@ struct ins_ops { bool ins__is_jump(const struct ins *ins); bool ins__is_call(const struct ins *ins); bool ins__is_ret(const struct ins *ins); +bool ins__is_lock(const struct ins *ins); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); +bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); struct annotation; @@ -72,16 +75,22 @@ static inline bool disasm_line__has_offset(const struct disasm_line *dl) return dl->ops.target.offset_avail; } +struct sym_hist_entry { + u64 nr_samples; + u64 period; +}; + void disasm_line__free(struct disasm_line *dl); struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos); int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw); size_t disasm__fprintf(struct list_head *head, FILE *fp); double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, - s64 end, const char **path, u64 *nr_samples); + s64 end, const char **path, struct sym_hist_entry *sample); struct sym_hist { - u64 sum; - u64 addr[0]; + u64 nr_samples; + u64 period; + struct sym_hist_entry addr[0]; }; struct cyc_hist { @@ -147,20 +156,22 @@ static inline struct annotation *symbol__annotation(struct symbol *sym) return (void *)sym - symbol_conf.priv_size; } -int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx); +int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, + int evidx); int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, struct addr_map_symbol *start, unsigned cycles); -int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr); +int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, + int evidx, u64 addr); int symbol__alloc_hist(struct symbol *sym); void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_name, size_t privsize, - struct arch **parch); + struct arch **parch, char *cpuid); enum symbol_disassemble_errno { SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, diff --git a/tools/perf/util/block-range.c b/tools/perf/util/block-range.c index 7b3e1d75d803..f1451c987eec 100644 --- a/tools/perf/util/block-range.c +++ b/tools/perf/util/block-range.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "block-range.h" #include "annotate.h" diff --git a/tools/perf/util/block-range.h b/tools/perf/util/block-range.h index a8c841381131..a5ba719d69fb 100644 --- a/tools/perf/util/block-range.h +++ b/tools/perf/util/block-range.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_BLOCK_RANGE_H #define __PERF_BLOCK_RANGE_H diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index 4bd2d1d882af..72c107fcbc5a 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * bpf-loader.c * @@ -1246,7 +1247,7 @@ int bpf__config_obj(struct bpf_object *obj, if (!obj || !term || !term->config) return -EINVAL; - if (!prefixcmp(term->config, "map:")) { + if (strstarts(term->config, "map:")) { key_scan_pos = sizeof("map:") - 1; err = bpf__obj_config_map(obj, term, evlist, &key_scan_pos); goto out; diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h index 48863867878b..5d3aefd6fae7 100644 --- a/tools/perf/util/bpf-loader.h +++ b/tools/perf/util/bpf-loader.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2015, Wang Nan * Copyright (C) 2015, Huawei Inc. diff --git a/tools/perf/util/bpf-prologue.c b/tools/perf/util/bpf-prologue.c index 1356220a9f1b..29347756b0af 100644 --- a/tools/perf/util/bpf-prologue.c +++ b/tools/perf/util/bpf-prologue.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * bpf-prologue.c * @@ -58,6 +59,46 @@ check_pos(struct bpf_insn_pos *pos) return 0; } +/* + * Convert type string (u8/u16/u32/u64/s8/s16/s32/s64 ..., see + * Documentation/trace/kprobetrace.txt) to size field of BPF_LDX_MEM + * instruction (BPF_{B,H,W,DW}). + */ +static int +argtype_to_ldx_size(const char *type) +{ + int arg_size = type ? atoi(&type[1]) : 64; + + switch (arg_size) { + case 8: + return BPF_B; + case 16: + return BPF_H; + case 32: + return BPF_W; + case 64: + default: + return BPF_DW; + } +} + +static const char * +insn_sz_to_str(int insn_sz) +{ + switch (insn_sz) { + case BPF_B: + return "BPF_B"; + case BPF_H: + return "BPF_H"; + case BPF_W: + return "BPF_W"; + case BPF_DW: + return "BPF_DW"; + default: + return "UNKNOWN"; + } +} + /* Give it a shorter name */ #define ins(i, p) append_insn((i), (p)) @@ -258,9 +299,14 @@ gen_prologue_slowpath(struct bpf_insn_pos *pos, } /* Final pass: read to registers */ - for (i = 0; i < nargs; i++) - ins(BPF_LDX_MEM(BPF_DW, BPF_PROLOGUE_START_ARG_REG + i, + for (i = 0; i < nargs; i++) { + int insn_sz = (args[i].ref) ? argtype_to_ldx_size(args[i].type) : BPF_DW; + + pr_debug("prologue: load arg %d, insn_sz is %s\n", + i, insn_sz_to_str(insn_sz)); + ins(BPF_LDX_MEM(insn_sz, BPF_PROLOGUE_START_ARG_REG + i, BPF_REG_FP, -BPF_REG_SIZE * (i + 1)), pos); + } ins(BPF_JMP_IMM(BPF_JA, BPF_REG_0, 0, JMP_TO_SUCCESS_CODE), pos); diff --git a/tools/perf/util/bpf-prologue.h b/tools/perf/util/bpf-prologue.h index ba564838375f..c50c7358009f 100644 --- a/tools/perf/util/bpf-prologue.h +++ b/tools/perf/util/bpf-prologue.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2015, He Kuang * Copyright (C) 2015, Huawei Inc. diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c new file mode 100644 index 000000000000..a4fce2729e50 --- /dev/null +++ b/tools/perf/util/branch.c @@ -0,0 +1,147 @@ +#include "perf.h" +#include "util/util.h" +#include "util/debug.h" +#include "util/branch.h" + +static bool cross_area(u64 addr1, u64 addr2, int size) +{ + u64 align1, align2; + + align1 = addr1 & ~(size - 1); + align2 = addr2 & ~(size - 1); + + return (align1 != align2) ? true : false; +} + +#define AREA_4K 4096 +#define AREA_2M (2 * 1024 * 1024) + +void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags, + u64 from, u64 to) +{ + if (flags->type == PERF_BR_UNKNOWN || from == 0) + return; + + st->counts[flags->type]++; + + if (flags->type == PERF_BR_COND) { + if (to > from) + st->cond_fwd++; + else + st->cond_bwd++; + } + + if (cross_area(from, to, AREA_2M)) + st->cross_2m++; + else if (cross_area(from, to, AREA_4K)) + st->cross_4k++; +} + +const char *branch_type_name(int type) +{ + const char *branch_names[PERF_BR_MAX] = { + "N/A", + "COND", + "UNCOND", + "IND", + "CALL", + "IND_CALL", + "RET", + "SYSCALL", + "SYSRET", + "COND_CALL", + "COND_RET" + }; + + if (type >= 0 && type < PERF_BR_MAX) + return branch_names[type]; + + return NULL; +} + +void branch_type_stat_display(FILE *fp, struct branch_type_stat *st) +{ + u64 total = 0; + int i; + + for (i = 0; i < PERF_BR_MAX; i++) + total += st->counts[i]; + + if (total == 0) + return; + + fprintf(fp, "\n#"); + fprintf(fp, "\n# Branch Statistics:"); + fprintf(fp, "\n#"); + + if (st->cond_fwd > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "COND_FWD", + 100.0 * (double)st->cond_fwd / (double)total); + } + + if (st->cond_bwd > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "COND_BWD", + 100.0 * (double)st->cond_bwd / (double)total); + } + + if (st->cross_4k > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "CROSS_4K", + 100.0 * (double)st->cross_4k / (double)total); + } + + if (st->cross_2m > 0) { + fprintf(fp, "\n%8s: %5.1f%%", + "CROSS_2M", + 100.0 * (double)st->cross_2m / (double)total); + } + + for (i = 0; i < PERF_BR_MAX; i++) { + if (st->counts[i] > 0) + fprintf(fp, "\n%8s: %5.1f%%", + branch_type_name(i), + 100.0 * + (double)st->counts[i] / (double)total); + } +} + +static int count_str_scnprintf(int idx, const char *str, char *bf, int size) +{ + return scnprintf(bf, size, "%s%s", (idx) ? " " : " (", str); +} + +int branch_type_str(struct branch_type_stat *st, char *bf, int size) +{ + int i, j = 0, printed = 0; + u64 total = 0; + + for (i = 0; i < PERF_BR_MAX; i++) + total += st->counts[i]; + + if (total == 0) + return 0; + + if (st->cond_fwd > 0) + printed += count_str_scnprintf(j++, "COND_FWD", bf + printed, size - printed); + + if (st->cond_bwd > 0) + printed += count_str_scnprintf(j++, "COND_BWD", bf + printed, size - printed); + + for (i = 0; i < PERF_BR_MAX; i++) { + if (i == PERF_BR_COND) + continue; + + if (st->counts[i] > 0) + printed += count_str_scnprintf(j++, branch_type_name(i), bf + printed, size - printed); + } + + if (st->cross_4k > 0) + printed += count_str_scnprintf(j++, "CROSS_4K", bf + printed, size - printed); + + if (st->cross_2m > 0) + printed += count_str_scnprintf(j++, "CROSS_2M", bf + printed, size - printed); + + return printed; +} diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h new file mode 100644 index 000000000000..1e3c7c5cdc63 --- /dev/null +++ b/tools/perf/util/branch.h @@ -0,0 +1,25 @@ +#ifndef _PERF_BRANCH_H +#define _PERF_BRANCH_H 1 + +#include +#include "../perf.h" + +struct branch_type_stat { + bool branch_to; + u64 counts[PERF_BR_MAX]; + u64 cond_fwd; + u64 cond_bwd; + u64 cross_4k; + u64 cross_2m; +}; + +struct branch_flags; + +void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags, + u64 from, u64 to); + +const char *branch_type_name(int type); +void branch_type_stat_display(FILE *fp, struct branch_type_stat *st); +int branch_type_str(struct branch_type_stat *st, char *bf, int bfsize); + +#endif /* _PERF_BRANCH_H */ diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e0148b081bdf..7f8553630c4d 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * build-id.c * @@ -243,12 +244,15 @@ static bool build_id_cache__valid_id(char *sbuild_id) return result; } -static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso) +static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso, + bool is_debug) { - return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf"); + return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : (is_debug ? + "debug" : "elf")); } -char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) +char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size, + bool is_debug) { bool is_kallsyms = dso__is_kallsyms((struct dso *)dso); bool is_vdso = dso__is_vdso((struct dso *)dso); @@ -270,7 +274,8 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) ret = asnprintf(&bf, size, "%s", linkname); else ret = asnprintf(&bf, size, "%s/%s", linkname, - build_id_cache__basename(is_kallsyms, is_vdso)); + build_id_cache__basename(is_kallsyms, is_vdso, + is_debug)); if (ret < 0 || (!alloc && size < (unsigned int)ret)) bf = NULL; free(linkname); @@ -285,7 +290,7 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) else static int write_buildid(const char *name, size_t name_len, u8 *build_id, - pid_t pid, u16 misc, int fd) + pid_t pid, u16 misc, struct feat_fd *fd) { int err; struct build_id_event b; @@ -300,14 +305,15 @@ static int write_buildid(const char *name, size_t name_len, u8 *build_id, b.header.misc = misc; b.header.size = sizeof(b) + len; - err = writen(fd, &b, sizeof(b)); + err = do_write(fd, &b, sizeof(b)); if (err < 0) return err; return write_padded(fd, name, name_len + 1, len); } -static int machine__write_buildid_table(struct machine *machine, int fd) +static int machine__write_buildid_table(struct machine *machine, + struct feat_fd *fd) { int err = 0; char nm[PATH_MAX]; @@ -352,7 +358,8 @@ static int machine__write_buildid_table(struct machine *machine, int fd) return err; } -int perf_session__write_buildid_table(struct perf_session *session, int fd) +int perf_session__write_buildid_table(struct perf_session *session, + struct feat_fd *fd) { struct rb_node *nd; int err = machine__write_buildid_table(&session->machines.host, fd); @@ -534,13 +541,14 @@ char *build_id_cache__complement(const char *incomplete_sbuild_id) } char *build_id_cache__cachedir(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso) + struct nsinfo *nsi, bool is_kallsyms, + bool is_vdso) { char *realname = (char *)name, *filename; bool slash = is_kallsyms || is_vdso; if (!slash) { - realname = realpath(name, NULL); + realname = nsinfo__realpath(name, nsi); if (!realname) return NULL; } @@ -556,13 +564,13 @@ char *build_id_cache__cachedir(const char *sbuild_id, const char *name, return filename; } -int build_id_cache__list_build_ids(const char *pathname, +int build_id_cache__list_build_ids(const char *pathname, struct nsinfo *nsi, struct strlist **result) { char *dir_name; int ret = 0; - dir_name = build_id_cache__cachedir(NULL, pathname, false, false); + dir_name = build_id_cache__cachedir(NULL, pathname, nsi, false, false); if (!dir_name) return -ENOMEM; @@ -576,16 +584,20 @@ int build_id_cache__list_build_ids(const char *pathname, #if defined(HAVE_LIBELF_SUPPORT) && defined(HAVE_GELF_GETNOTE_SUPPORT) static int build_id_cache__add_sdt_cache(const char *sbuild_id, - const char *realname) + const char *realname, + struct nsinfo *nsi) { struct probe_cache *cache; int ret; + struct nscookie nsc; - cache = probe_cache__new(sbuild_id); + cache = probe_cache__new(sbuild_id, nsi); if (!cache) return -1; + nsinfo__mountns_enter(nsi, &nsc); ret = probe_cache__scan_sdt(cache, realname); + nsinfo__mountns_exit(&nsc); if (ret >= 0) { pr_debug4("Found %d SDTs in %s\n", ret, realname); if (probe_cache__commit(cache) < 0) @@ -595,25 +607,56 @@ static int build_id_cache__add_sdt_cache(const char *sbuild_id, return ret; } #else -#define build_id_cache__add_sdt_cache(sbuild_id, realname) (0) +#define build_id_cache__add_sdt_cache(sbuild_id, realname, nsi) (0) #endif +static char *build_id_cache__find_debug(const char *sbuild_id, + struct nsinfo *nsi) +{ + char *realname = NULL; + char *debugfile; + struct nscookie nsc; + size_t len = 0; + + debugfile = calloc(1, PATH_MAX); + if (!debugfile) + goto out; + + len = __symbol__join_symfs(debugfile, PATH_MAX, + "/usr/lib/debug/.build-id/"); + snprintf(debugfile + len, PATH_MAX - len, "%.2s/%s.debug", sbuild_id, + sbuild_id + 2); + + nsinfo__mountns_enter(nsi, &nsc); + realname = realpath(debugfile, NULL); + if (realname && access(realname, R_OK)) + zfree(&realname); + nsinfo__mountns_exit(&nsc); +out: + free(debugfile); + return realname; +} + int build_id_cache__add_s(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso) + struct nsinfo *nsi, bool is_kallsyms, bool is_vdso) { const size_t size = PATH_MAX; char *realname = NULL, *filename = NULL, *dir_name = NULL, *linkname = zalloc(size), *tmp; + char *debugfile = NULL; int err = -1; if (!is_kallsyms) { - realname = realpath(name, NULL); + if (!is_vdso) + realname = nsinfo__realpath(name, nsi); + else + realname = realpath(name, NULL); if (!realname) goto out_free; } - dir_name = build_id_cache__cachedir(sbuild_id, name, - is_kallsyms, is_vdso); + dir_name = build_id_cache__cachedir(sbuild_id, name, nsi, is_kallsyms, + is_vdso); if (!dir_name) goto out_free; @@ -627,20 +670,52 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, /* Save the allocated buildid dirname */ if (asprintf(&filename, "%s/%s", dir_name, - build_id_cache__basename(is_kallsyms, is_vdso)) < 0) { + build_id_cache__basename(is_kallsyms, is_vdso, + false)) < 0) { filename = NULL; goto out_free; } if (access(filename, F_OK)) { if (is_kallsyms) { - if (copyfile("/proc/kallsyms", filename)) + if (copyfile("/proc/kallsyms", filename)) + goto out_free; + } else if (nsi && nsi->need_setns) { + if (copyfile_ns(name, filename, nsi)) goto out_free; } else if (link(realname, filename) && errno != EEXIST && copyfile(name, filename)) goto out_free; } + /* Some binaries are stripped, but have .debug files with their symbol + * table. Check to see if we can locate one of those, since the elf + * file itself may not be very useful to users of our tools without a + * symtab. + */ + if (!is_kallsyms && !is_vdso && + strncmp(".ko", name + strlen(name) - 3, 3)) { + debugfile = build_id_cache__find_debug(sbuild_id, nsi); + if (debugfile) { + zfree(&filename); + if (asprintf(&filename, "%s/%s", dir_name, + build_id_cache__basename(false, false, true)) < 0) { + filename = NULL; + goto out_free; + } + if (access(filename, F_OK)) { + if (nsi && nsi->need_setns) { + if (copyfile_ns(debugfile, filename, + nsi)) + goto out_free; + } else if (link(debugfile, filename) && + errno != EEXIST && + copyfile(debugfile, filename)) + goto out_free; + } + } + } + if (!build_id_cache__linkname(sbuild_id, linkname, size)) goto out_free; tmp = strrchr(linkname, '/'); @@ -657,27 +732,30 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, err = 0; /* Update SDT cache : error is just warned */ - if (realname && build_id_cache__add_sdt_cache(sbuild_id, realname) < 0) + if (realname && + build_id_cache__add_sdt_cache(sbuild_id, realname, nsi) < 0) pr_debug4("Failed to update/scan SDT cache for %s\n", realname); out_free: if (!is_kallsyms) free(realname); free(filename); + free(debugfile); free(dir_name); free(linkname); return err; } static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, - const char *name, bool is_kallsyms, - bool is_vdso) + const char *name, struct nsinfo *nsi, + bool is_kallsyms, bool is_vdso) { char sbuild_id[SBUILD_ID_SIZE]; build_id__sprintf(build_id, build_id_size, sbuild_id); - return build_id_cache__add_s(sbuild_id, name, is_kallsyms, is_vdso); + return build_id_cache__add_s(sbuild_id, name, nsi, is_kallsyms, + is_vdso); } bool build_id_cache__cached(const char *sbuild_id) @@ -743,7 +821,7 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine) name = nm; } return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name, - is_kallsyms, is_vdso); + dso->nsinfo, is_kallsyms, is_vdso); } static int __dsos__cache_build_ids(struct list_head *head, diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 96690a55c62c..f0c565164a97 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_BUILD_ID_H_ #define PERF_BUILD_ID_H_ 1 @@ -5,10 +6,12 @@ #define SBUILD_ID_SIZE (BUILD_ID_SIZE * 2 + 1) #include "tool.h" +#include "namespaces.h" #include extern struct perf_tool build_id__mark_dso_hit_ops; struct dso; +struct feat_fd; int build_id__sprintf(const u8 *build_id, int len, char *bf); int sysfs__sprintf_build_id(const char *root_dir, char *sbuild_id); @@ -16,7 +19,8 @@ int filename__sprintf_build_id(const char *pathname, char *sbuild_id); char *build_id_cache__kallsyms_path(const char *sbuild_id, char *bf, size_t size); -char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size); +char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size, + bool is_debug); int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, @@ -25,23 +29,26 @@ int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, int dsos__hit_all(struct perf_session *session); bool perf_session__read_build_ids(struct perf_session *session, bool with_hits); -int perf_session__write_buildid_table(struct perf_session *session, int fd); +int perf_session__write_buildid_table(struct perf_session *session, + struct feat_fd *fd); int perf_session__cache_build_ids(struct perf_session *session); char *build_id_cache__origname(const char *sbuild_id); char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size); char *build_id_cache__cachedir(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso); + struct nsinfo *nsi, bool is_kallsyms, + bool is_vdso); struct strlist; struct strlist *build_id_cache__list_all(bool validonly); char *build_id_cache__complement(const char *incomplete_sbuild_id); -int build_id_cache__list_build_ids(const char *pathname, +int build_id_cache__list_build_ids(const char *pathname, struct nsinfo *nsi, struct strlist **result); bool build_id_cache__cached(const char *sbuild_id); int build_id_cache__add_s(const char *sbuild_id, - const char *name, bool is_kallsyms, bool is_vdso); + const char *name, struct nsinfo *nsi, + bool is_kallsyms, bool is_vdso); int build_id_cache__remove_s(const char *sbuild_id); extern char buildid_dir[]; diff --git a/tools/perf/util/c++/clang-c.h b/tools/perf/util/c++/clang-c.h index ccafcf72b37a..e513366f2ee0 100644 --- a/tools/perf/util/c++/clang-c.h +++ b/tools/perf/util/c++/clang-c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_UTIL_CLANG_C_H #define PERF_UTIL_CLANG_C_H diff --git a/tools/perf/util/c++/clang-test.cpp b/tools/perf/util/c++/clang-test.cpp index 9b11e8c82798..a4014d786676 100644 --- a/tools/perf/util/c++/clang-test.cpp +++ b/tools/perf/util/c++/clang-test.cpp @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "clang.h" #include "clang-c.h" #include "llvm/IR/Function.h" diff --git a/tools/perf/util/c++/clang.cpp b/tools/perf/util/c++/clang.cpp index 1e974152cac2..1bfc946e37dc 100644 --- a/tools/perf/util/c++/clang.cpp +++ b/tools/perf/util/c++/clang.cpp @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * llvm C frontend for perf. Support dynamically compile C file * diff --git a/tools/perf/util/c++/clang.h b/tools/perf/util/c++/clang.h index dd8b0427550d..6ce33e22f23c 100644 --- a/tools/perf/util/c++/clang.h +++ b/tools/perf/util/c++/clang.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_UTIL_CLANG_H #define PERF_UTIL_CLANG_H diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 0175765c05b9..9f2e36ef5072 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_CACHE_H #define __PERF_CACHE_H diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index b4204b43ed58..6031933d811c 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2009-2011, Frederic Weisbecker * @@ -23,6 +24,7 @@ #include "sort.h" #include "machine.h" #include "callchain.h" +#include "branch.h" #define CALLCHAIN_PARAM_DEFAULT \ .mode = CHAIN_GRAPH_ABS, \ @@ -64,8 +66,6 @@ static int parse_callchain_mode(const char *value) callchain_param.mode = CHAIN_FOLDED; return 0; } - - pr_err("Invalid callchain mode: %s\n", value); return -1; } @@ -81,8 +81,6 @@ static int parse_callchain_order(const char *value) callchain_param.order_set = true; return 0; } - - pr_err("Invalid callchain order: %s\n", value); return -1; } @@ -104,8 +102,6 @@ static int parse_callchain_sort_key(const char *value) callchain_param.branch_callstack = 1; return 0; } - - pr_err("Invalid callchain sort key: %s\n", value); return -1; } @@ -123,8 +119,6 @@ static int parse_callchain_value(const char *value) callchain_param.value = CCVAL_COUNT; return 0; } - - pr_err("Invalid callchain config key: %s\n", value); return -1; } @@ -303,7 +297,7 @@ int perf_callchain_config(const char *var, const char *value) { char *endptr; - if (prefixcmp(var, "call-graph.")) + if (!strstarts(var, "call-graph.")) return 0; var += sizeof("call-graph.") - 1; @@ -318,12 +312,27 @@ int perf_callchain_config(const char *var, const char *value) return ret; } - if (!strcmp(var, "print-type")) - return parse_callchain_mode(value); - if (!strcmp(var, "order")) - return parse_callchain_order(value); - if (!strcmp(var, "sort-key")) - return parse_callchain_sort_key(value); + if (!strcmp(var, "print-type")){ + int ret; + ret = parse_callchain_mode(value); + if (ret == -1) + pr_err("Invalid callchain mode: %s\n", value); + return ret; + } + if (!strcmp(var, "order")){ + int ret; + ret = parse_callchain_order(value); + if (ret == -1) + pr_err("Invalid callchain order: %s\n", value); + return ret; + } + if (!strcmp(var, "sort-key")){ + int ret; + ret = parse_callchain_sort_key(value); + if (ret == -1) + pr_err("Invalid callchain sort key: %s\n", value); + return ret; + } if (!strcmp(var, "threshold")) { callchain_param.min_percent = strtod(value, &endptr); if (value == endptr) { @@ -562,15 +571,33 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor) if (cursor_node->branch) { call->branch_count = 1; - if (cursor_node->branch_flags.predicted) - call->predicted_count = 1; + if (cursor_node->branch_from) { + /* + * branch_from is set with value somewhere else + * to imply it's "to" of a branch. + */ + call->brtype_stat.branch_to = true; - if (cursor_node->branch_flags.abort) - call->abort_count = 1; + if (cursor_node->branch_flags.predicted) + call->predicted_count = 1; - call->cycles_count = cursor_node->branch_flags.cycles; - call->iter_count = cursor_node->nr_loop_iter; - call->samples_count = cursor_node->samples; + if (cursor_node->branch_flags.abort) + call->abort_count = 1; + + branch_type_count(&call->brtype_stat, + &cursor_node->branch_flags, + cursor_node->branch_from, + cursor_node->ip); + } else { + /* + * It's "from" of a branch + */ + call->brtype_stat.branch_to = false; + call->cycles_count = + cursor_node->branch_flags.cycles; + call->iter_count = cursor_node->nr_loop_iter; + call->iter_cycles = cursor_node->iter_cycles; + } } list_add_tail(&call->list, &node->val); @@ -659,6 +686,8 @@ static enum match_result match_chain(struct callchain_cursor_node *node, { struct symbol *sym = node->sym; u64 left, right; + struct dso *left_dso = NULL; + struct dso *right_dso = NULL; if (callchain_param.key == CCKEY_SRCLINE) { enum match_result match = match_chain_srcline(node, cnode); @@ -670,24 +699,43 @@ static enum match_result match_chain(struct callchain_cursor_node *node, if (cnode->ms.sym && sym && callchain_param.key == CCKEY_FUNCTION) { left = cnode->ms.sym->start; right = sym->start; + left_dso = cnode->ms.map->dso; + right_dso = node->map->dso; } else { left = cnode->ip; right = node->ip; } - if (left == right) { + if (left == right && left_dso == right_dso) { if (node->branch) { cnode->branch_count++; - if (node->branch_flags.predicted) - cnode->predicted_count++; + if (node->branch_from) { + /* + * It's "to" of a branch + */ + cnode->brtype_stat.branch_to = true; - if (node->branch_flags.abort) - cnode->abort_count++; + if (node->branch_flags.predicted) + cnode->predicted_count++; - cnode->cycles_count += node->branch_flags.cycles; - cnode->iter_count += node->nr_loop_iter; - cnode->samples_count += node->samples; + if (node->branch_flags.abort) + cnode->abort_count++; + + branch_type_count(&cnode->brtype_stat, + &node->branch_flags, + node->branch_from, + node->ip); + } else { + /* + * It's "from" of a branch + */ + cnode->brtype_stat.branch_to = false; + cnode->cycles_count += + node->branch_flags.cycles; + cnode->iter_count += node->nr_loop_iter; + cnode->iter_cycles += node->iter_cycles; + } } return MATCH_EQ; @@ -922,7 +970,7 @@ merge_chain_branch(struct callchain_cursor *cursor, list_for_each_entry_safe(list, next_list, &src->val, list) { callchain_cursor_append(cursor, list->ip, list->ms.map, list->ms.sym, - false, NULL, 0, 0); + false, NULL, 0, 0, 0); list_del(&list->list); map__zput(list->ms.map); free(list); @@ -962,7 +1010,7 @@ int callchain_merge(struct callchain_cursor *cursor, int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, struct map *map, struct symbol *sym, bool branch, struct branch_flags *flags, - int nr_loop_iter, int samples) + int nr_loop_iter, u64 iter_cycles, u64 branch_from) { struct callchain_cursor_node *node = *cursor->last; @@ -980,12 +1028,13 @@ int callchain_cursor_append(struct callchain_cursor *cursor, node->sym = sym; node->branch = branch; node->nr_loop_iter = nr_loop_iter; - node->samples = samples; + node->iter_cycles = iter_cycles; if (flags) memcpy(&node->branch_flags, flags, sizeof(struct branch_flags)); + node->branch_from = branch_from; cursor->nr++; cursor->last = &node->next; @@ -998,11 +1047,11 @@ int sample__resolve_callchain(struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al, int max_stack) { - if (sample->callchain == NULL) + if (sample->callchain == NULL && !symbol_conf.show_branchflag_count) return 0; if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain || - perf_hpp_list.parent) { + perf_hpp_list.parent || symbol_conf.show_branchflag_count) { return thread__resolve_callchain(al->thread, cursor, evsel, sample, parent, al, max_stack); } @@ -1011,7 +1060,8 @@ int sample__resolve_callchain(struct perf_sample *sample, int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample) { - if (!symbol_conf.use_callchain || sample->callchain == NULL) + if ((!symbol_conf.use_callchain || sample->callchain == NULL) && + !symbol_conf.show_branchflag_count) return 0; return callchain_append(he->callchain, &callchain_cursor, sample->period); } @@ -1214,95 +1264,124 @@ int callchain_branch_counts(struct callchain_root *root, cycles_count); } +static int count_pri64_printf(int idx, const char *str, u64 value, char *bf, int bfsize) +{ + int printed; + + printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value); + + return printed; +} + +static int count_float_printf(int idx, const char *str, float value, + char *bf, int bfsize, float threshold) +{ + int printed; + + if (threshold != 0.0 && value < threshold) + return 0; + + printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value); + + return printed; +} + +static int branch_to_str(char *bf, int bfsize, + u64 branch_count, u64 predicted_count, + u64 abort_count, + struct branch_type_stat *brtype_stat) +{ + int printed, i = 0; + + printed = branch_type_str(brtype_stat, bf, bfsize); + if (printed) + i++; + + if (predicted_count < branch_count) { + printed += count_float_printf(i++, "predicted", + predicted_count * 100.0 / branch_count, + bf + printed, bfsize - printed, 0.0); + } + + if (abort_count) { + printed += count_float_printf(i++, "abort", + abort_count * 100.0 / branch_count, + bf + printed, bfsize - printed, 0.1); + } + + if (i) + printed += scnprintf(bf + printed, bfsize - printed, ")"); + + return printed; +} + +static int branch_from_str(char *bf, int bfsize, + u64 branch_count, + u64 cycles_count, u64 iter_count, + u64 iter_cycles) +{ + int printed = 0, i = 0; + u64 cycles; + + cycles = cycles_count / branch_count; + if (cycles) { + printed += count_pri64_printf(i++, "cycles", + cycles, + bf + printed, bfsize - printed); + } + + if (iter_count) { + printed += count_pri64_printf(i++, "iter", + iter_count, + bf + printed, bfsize - printed); + + printed += count_pri64_printf(i++, "avg_cycles", + iter_cycles / iter_count, + bf + printed, bfsize - printed); + } + + if (i) + printed += scnprintf(bf + printed, bfsize - printed, ")"); + + return printed; +} + static int counts_str_build(char *bf, int bfsize, u64 branch_count, u64 predicted_count, u64 abort_count, u64 cycles_count, - u64 iter_count, u64 samples_count) + u64 iter_count, u64 iter_cycles, + struct branch_type_stat *brtype_stat) { - double predicted_percent = 0.0; - const char *null_str = ""; - char iter_str[32]; - char cycle_str[32]; - char *istr, *cstr; - u64 cycles; + int printed; if (branch_count == 0) return scnprintf(bf, bfsize, " (calltrace)"); - cycles = cycles_count / branch_count; - - if (iter_count && samples_count) { - if (cycles > 0) - scnprintf(iter_str, sizeof(iter_str), - " iterations:%" PRId64 "", - iter_count / samples_count); - else - scnprintf(iter_str, sizeof(iter_str), - "iterations:%" PRId64 "", - iter_count / samples_count); - istr = iter_str; - } else - istr = (char *)null_str; - - if (cycles > 0) { - scnprintf(cycle_str, sizeof(cycle_str), - "cycles:%" PRId64 "", cycles); - cstr = cycle_str; - } else - cstr = (char *)null_str; - - predicted_percent = predicted_count * 100.0 / branch_count; - - if ((predicted_count == branch_count) && (abort_count == 0)) { - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, " (%s%s)", cstr, istr); - else - return scnprintf(bf, bfsize, "%s", (char *)null_str); + if (brtype_stat->branch_to) { + printed = branch_to_str(bf, bfsize, branch_count, + predicted_count, abort_count, brtype_stat); + } else { + printed = branch_from_str(bf, bfsize, branch_count, + cycles_count, iter_count, iter_cycles); } - if ((predicted_count < branch_count) && (abort_count == 0)) { - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, - " (predicted:%.1f%% %s%s)", - predicted_percent, cstr, istr); - else { - return scnprintf(bf, bfsize, - " (predicted:%.1f%%)", - predicted_percent); - } - } + if (!printed) + bf[0] = 0; - if ((predicted_count == branch_count) && (abort_count > 0)) { - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, - " (abort:%" PRId64 " %s%s)", - abort_count, cstr, istr); - else - return scnprintf(bf, bfsize, - " (abort:%" PRId64 ")", - abort_count); - } - - if ((cycles > 0) || (istr != (char *)null_str)) - return scnprintf(bf, bfsize, - " (predicted:%.1f%% abort:%" PRId64 " %s%s)", - predicted_percent, abort_count, cstr, istr); - - return scnprintf(bf, bfsize, - " (predicted:%.1f%% abort:%" PRId64 ")", - predicted_percent, abort_count); + return printed; } static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, u64 branch_count, u64 predicted_count, u64 abort_count, u64 cycles_count, - u64 iter_count, u64 samples_count) + u64 iter_count, u64 iter_cycles, + struct branch_type_stat *brtype_stat) { - char str[128]; + char str[256]; counts_str_build(str, sizeof(str), branch_count, predicted_count, abort_count, cycles_count, - iter_count, samples_count); + iter_count, iter_cycles, brtype_stat); if (fp) return fprintf(fp, "%s", str); @@ -1310,31 +1389,24 @@ static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, return scnprintf(bf, bfsize, "%s", str); } -int callchain_list_counts__printf_value(struct callchain_node *node, - struct callchain_list *clist, +int callchain_list_counts__printf_value(struct callchain_list *clist, FILE *fp, char *bf, int bfsize) { u64 branch_count, predicted_count; u64 abort_count, cycles_count; - u64 iter_count = 0, samples_count = 0; + u64 iter_count, iter_cycles; branch_count = clist->branch_count; predicted_count = clist->predicted_count; abort_count = clist->abort_count; cycles_count = clist->cycles_count; - - if (node) { - struct callchain_list *call; - - list_for_each_entry(call, &node->val, list) { - iter_count += call->iter_count; - samples_count += call->samples_count; - } - } + iter_count = clist->iter_count; + iter_cycles = clist->iter_cycles; return callchain_counts_printf(fp, bf, bfsize, branch_count, predicted_count, abort_count, - cycles_count, iter_count, samples_count); + cycles_count, iter_count, iter_cycles, + &clist->brtype_stat); } static void free_callchain_node(struct callchain_node *node) @@ -1459,7 +1531,9 @@ int callchain_cursor__copy(struct callchain_cursor *dst, rc = callchain_cursor_append(dst, node->ip, node->map, node->sym, node->branch, &node->branch_flags, - node->nr_loop_iter, node->samples); + node->nr_loop_iter, + node->iter_cycles, + node->branch_from); if (rc) break; diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index c56c23dbbf72..f967aa47d0a1 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_CALLCHAIN_H #define __PERF_CALLCHAIN_H @@ -7,6 +8,7 @@ #include "event.h" #include "map.h" #include "symbol.h" +#include "branch.h" #define HELP_PAD "\t\t\t\t" @@ -118,7 +120,8 @@ struct callchain_list { u64 abort_count; u64 cycles_count; u64 iter_count; - u64 samples_count; + u64 iter_cycles; + struct branch_type_stat brtype_stat; char *srcline; struct list_head list; }; @@ -135,8 +138,9 @@ struct callchain_cursor_node { struct symbol *sym; bool branch; struct branch_flags branch_flags; + u64 branch_from; int nr_loop_iter; - int samples; + u64 iter_cycles; struct callchain_cursor_node *next; }; @@ -198,7 +202,7 @@ static inline void callchain_cursor_reset(struct callchain_cursor *cursor) int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, struct map *map, struct symbol *sym, bool branch, struct branch_flags *flags, - int nr_loop_iter, int samples); + int nr_loop_iter, u64 iter_cycles, u64 branch_from); /* Close a cursor writing session. Initialize for the reader */ static inline void callchain_cursor_commit(struct callchain_cursor *cursor) @@ -279,8 +283,7 @@ char *callchain_node__scnprintf_value(struct callchain_node *node, int callchain_node__fprintf_value(struct callchain_node *node, FILE *fp, u64 total); -int callchain_list_counts__printf_value(struct callchain_node *node, - struct callchain_list *clist, +int callchain_list_counts__printf_value(struct callchain_list *clist, FILE *fp, char *bf, int bfsize); void free_callchain(struct callchain_root *root); diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 03347748f3fa..d9ffc1e6eb39 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util.h" #include "../perf.h" #include @@ -98,8 +99,10 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) cgrp = counter->cgrp; if (!cgrp) continue; - if (!strcmp(cgrp->name, str)) + if (!strcmp(cgrp->name, str)) { + refcount_inc(&cgrp->refcnt); break; + } cgrp = NULL; } @@ -110,6 +113,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) return -1; cgrp->name = str; + refcount_set(&cgrp->refcnt, 1); cgrp->fd = open_cgroup(str); if (cgrp->fd == -1) { @@ -128,12 +132,11 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) goto found; n++; } - if (refcount_read(&cgrp->refcnt) == 0) + if (refcount_dec_and_test(&cgrp->refcnt)) free(cgrp); return -1; found: - refcount_inc(&cgrp->refcnt); counter->cgrp = cgrp; return 0; } diff --git a/tools/perf/util/cgroup.h b/tools/perf/util/cgroup.h index d91966b97cbd..afafc87e9201 100644 --- a/tools/perf/util/cgroup.h +++ b/tools/perf/util/cgroup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CGROUP_H__ #define __CGROUP_H__ diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index 4b4f00df58a8..ca0fff6272be 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "util.h" diff --git a/tools/perf/util/cloexec.h b/tools/perf/util/cloexec.h index 94a5a7d829d5..78216b1015c4 100644 --- a/tools/perf/util/cloexec.h +++ b/tools/perf/util/cloexec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_CLOEXEC_H #define __PERF_CLOEXEC_H diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index dbbf89b050a5..39e628b8938e 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "cache.h" #include "config.h" diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h index 52122bcc3170..22777b1812ee 100644 --- a/tools/perf/util/color.h +++ b/tools/perf/util/color.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_COLOR_H #define __PERF_COLOR_H diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index 7bc981b6bf29..8808570f8e9c 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "comm.h" #include "util.h" #include diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h index 71c9c39340d4..3e5c438fe85e 100644 --- a/tools/perf/util/comm.h +++ b/tools/perf/util/comm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_COMM_H #define __PERF_COMM_H diff --git a/tools/perf/util/compress.h b/tools/perf/util/compress.h index 67fd1bb7c2b7..ecca688a25fb 100644 --- a/tools/perf/util/compress.h +++ b/tools/perf/util/compress.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_COMPRESS_H #define PERF_COMPRESS_H diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 31a7dea248d0..4b893c622236 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * config.c * @@ -19,6 +20,7 @@ #include #include #include +#include #include "sane_ctype.h" @@ -433,22 +435,22 @@ static int perf_ui_config(const char *var, const char *value) int perf_default_config(const char *var, const char *value, void *dummy __maybe_unused) { - if (!prefixcmp(var, "core.")) + if (strstarts(var, "core.")) return perf_default_core_config(var, value); - if (!prefixcmp(var, "hist.")) + if (strstarts(var, "hist.")) return perf_hist_config(var, value); - if (!prefixcmp(var, "ui.")) + if (strstarts(var, "ui.")) return perf_ui_config(var, value); - if (!prefixcmp(var, "call-graph.")) + if (strstarts(var, "call-graph.")) return perf_callchain_config(var, value); - if (!prefixcmp(var, "llvm.")) + if (strstarts(var, "llvm.")) return perf_llvm_config(var, value); - if (!prefixcmp(var, "buildid.")) + if (strstarts(var, "buildid.")) return perf_buildid_config(var, value); /* Add other config variables here. */ diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h index b6bb11f3f165..baf82bf227ac 100644 --- a/tools/perf/util/config.h +++ b/tools/perf/util/config.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_CONFIG_H #define __PERF_CONFIG_H diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c index c4af82ab7808..03032b410c29 100644 --- a/tools/perf/util/counts.c +++ b/tools/perf/util/counts.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "evsel.h" diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h index 34d8baaf558a..0d1050ccc586 100644 --- a/tools/perf/util/counts.h +++ b/tools/perf/util/counts.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_COUNTS_H #define __PERF_COUNTS_H @@ -12,6 +13,7 @@ struct perf_counts_values { }; u64 values[3]; }; + bool loaded; }; struct perf_counts { diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c index 37b3bb79ee08..1ccbd3342069 100644 --- a/tools/perf/util/cpumap.c +++ b/tools/perf/util/cpumap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util.h" #include #include "../perf.h" diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h index 6b8bff87481d..ed8999d1a640 100644 --- a/tools/perf/util/cpumap.h +++ b/tools/perf/util/cpumap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_CPUMAP_H #define __PERF_CPUMAP_H diff --git a/tools/perf/util/ctype.c b/tools/perf/util/ctype.c index 4b261c2ec0f1..ee4c1e8ed54b 100644 --- a/tools/perf/util/ctype.c +++ b/tools/perf/util/ctype.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Sane locale-independent, ASCII ctype. * diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 3149b70799fd..2346cecb8ea2 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -76,6 +76,8 @@ struct ctf_writer { struct bt_ctf_event_class *comm_class; struct bt_ctf_event_class *exit_class; struct bt_ctf_event_class *fork_class; + struct bt_ctf_event_class *mmap_class; + struct bt_ctf_event_class *mmap2_class; }; struct convert { @@ -506,6 +508,81 @@ put_len_type: return ret; } +static int +add_callchain_output_values(struct bt_ctf_event_class *event_class, + struct bt_ctf_event *event, + struct ip_callchain *callchain) +{ + struct bt_ctf_field_type *len_type, *seq_type; + struct bt_ctf_field *len_field, *seq_field; + unsigned int nr_elements = callchain->nr; + unsigned int i; + int ret; + + len_type = bt_ctf_event_class_get_field_by_name( + event_class, "perf_callchain_size"); + len_field = bt_ctf_field_create(len_type); + if (!len_field) { + pr_err("failed to create 'perf_callchain_size' for callchain output event\n"); + ret = -1; + goto put_len_type; + } + + ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements); + if (ret) { + pr_err("failed to set field value for perf_callchain_size\n"); + goto put_len_field; + } + ret = bt_ctf_event_set_payload(event, "perf_callchain_size", len_field); + if (ret) { + pr_err("failed to set payload to perf_callchain_size\n"); + goto put_len_field; + } + + seq_type = bt_ctf_event_class_get_field_by_name( + event_class, "perf_callchain"); + seq_field = bt_ctf_field_create(seq_type); + if (!seq_field) { + pr_err("failed to create 'perf_callchain' for callchain output event\n"); + ret = -1; + goto put_seq_type; + } + + ret = bt_ctf_field_sequence_set_length(seq_field, len_field); + if (ret) { + pr_err("failed to set length of 'perf_callchain'\n"); + goto put_seq_field; + } + + for (i = 0; i < nr_elements; i++) { + struct bt_ctf_field *elem_field = + bt_ctf_field_sequence_get_field(seq_field, i); + + ret = bt_ctf_field_unsigned_integer_set_value(elem_field, + ((u64 *)(callchain->ips))[i]); + + bt_ctf_field_put(elem_field); + if (ret) { + pr_err("failed to set callchain[%d]\n", i); + goto put_seq_field; + } + } + + ret = bt_ctf_event_set_payload(event, "perf_callchain", seq_field); + if (ret) + pr_err("failed to set payload for raw_data\n"); + +put_seq_field: + bt_ctf_field_put(seq_field); +put_seq_type: + bt_ctf_field_type_put(seq_type); +put_len_field: + bt_ctf_field_put(len_field); +put_len_type: + bt_ctf_field_type_put(len_type); + return ret; +} + static int add_generic_values(struct ctf_writer *cw, struct bt_ctf_event *event, struct perf_evsel *evsel, @@ -519,7 +596,6 @@ static int add_generic_values(struct ctf_writer *cw, * PERF_SAMPLE_TIME - not needed as we have it in * ctf event header * PERF_SAMPLE_READ - TODO - * PERF_SAMPLE_CALLCHAIN - TODO * PERF_SAMPLE_RAW - tracepoint fields are handled separately * PERF_SAMPLE_BRANCH_STACK - TODO * PERF_SAMPLE_REGS_USER - TODO @@ -720,6 +796,7 @@ static int process_sample_event(struct perf_tool *tool, struct bt_ctf_event_class *event_class; struct bt_ctf_event *event; int ret; + unsigned long type = evsel->attr.sample_type; if (WARN_ONCE(!priv, "Failed to setup all events.\n")) return 0; @@ -751,6 +828,13 @@ static int process_sample_event(struct perf_tool *tool, return -1; } + if (type & PERF_SAMPLE_CALLCHAIN) { + ret = add_callchain_output_values(event_class, + event, sample->callchain); + if (ret) + return -1; + } + if (perf_evsel__is_bpf_output(evsel)) { ret = add_bpf_output_values(event_class, event, sample); if (ret) @@ -833,6 +917,18 @@ __FUNC_PROCESS_NON_SAMPLE(exit, __NON_SAMPLE_SET_FIELD(fork, u32, ptid); __NON_SAMPLE_SET_FIELD(fork, u64, time); ) +__FUNC_PROCESS_NON_SAMPLE(mmap, + __NON_SAMPLE_SET_FIELD(mmap, u32, pid); + __NON_SAMPLE_SET_FIELD(mmap, u32, tid); + __NON_SAMPLE_SET_FIELD(mmap, u64_hex, start); + __NON_SAMPLE_SET_FIELD(mmap, string, filename); +) +__FUNC_PROCESS_NON_SAMPLE(mmap2, + __NON_SAMPLE_SET_FIELD(mmap2, u32, pid); + __NON_SAMPLE_SET_FIELD(mmap2, u32, tid); + __NON_SAMPLE_SET_FIELD(mmap2, u64_hex, start); + __NON_SAMPLE_SET_FIELD(mmap2, string, filename); +) #undef __NON_SAMPLE_SET_FIELD #undef __FUNC_PROCESS_NON_SAMPLE @@ -1043,6 +1139,14 @@ static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, if (type & PERF_SAMPLE_TRANSACTION) ADD_FIELD(event_class, cw->data.u64, "perf_transaction"); + if (type & PERF_SAMPLE_CALLCHAIN) { + ADD_FIELD(event_class, cw->data.u32, "perf_callchain_size"); + ADD_FIELD(event_class, + bt_ctf_field_type_sequence_create( + cw->data.u64_hex, "perf_callchain_size"), + "perf_callchain"); + } + #undef ADD_FIELD return 0; } @@ -1164,6 +1268,19 @@ __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(exit, __NON_SAMPLE_ADD_FIELD(u64, time); ) +__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap, + __NON_SAMPLE_ADD_FIELD(u32, pid); + __NON_SAMPLE_ADD_FIELD(u32, tid); + __NON_SAMPLE_ADD_FIELD(u64_hex, start); + __NON_SAMPLE_ADD_FIELD(string, filename); +) + +__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap2, + __NON_SAMPLE_ADD_FIELD(u32, pid); + __NON_SAMPLE_ADD_FIELD(u32, tid); + __NON_SAMPLE_ADD_FIELD(u64_hex, start); + __NON_SAMPLE_ADD_FIELD(string, filename); +) #undef __NON_SAMPLE_ADD_FIELD #undef __FUNC_ADD_NON_SAMPLE_EVENT_CLASS @@ -1179,6 +1296,12 @@ static int setup_non_sample_events(struct ctf_writer *cw, if (ret) return ret; ret = add_fork_event(cw); + if (ret) + return ret; + ret = add_mmap_event(cw); + if (ret) + return ret; + ret = add_mmap2_event(cw); if (ret) return ret; return 0; @@ -1482,6 +1605,8 @@ int bt_convert__perf2ctf(const char *input, const char *path, c.tool.comm = process_comm_event; c.tool.exit = process_exit_event; c.tool.fork = process_fork_event; + c.tool.mmap = process_mmap_event; + c.tool.mmap2 = process_mmap2_event; } err = perf_config(convert__config, &c); diff --git a/tools/perf/util/data-convert-bt.h b/tools/perf/util/data-convert-bt.h index 9a3b587f76c1..821674d63c4e 100644 --- a/tools/perf/util/data-convert-bt.h +++ b/tools/perf/util/data-convert-bt.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __DATA_CONVERT_BT_H #define __DATA_CONVERT_BT_H #include "data-convert.h" diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h index 5314962fe95b..af90b6076c06 100644 --- a/tools/perf/util/data-convert.h +++ b/tools/perf/util/data-convert.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __DATA_CONVERT_H #define __DATA_CONVERT_H diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index e84bbc8ec058..79192758bdb3 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -10,6 +11,16 @@ #include "util.h" #include "debug.h" +#ifndef O_CLOEXEC +#ifdef __sparc__ +#define O_CLOEXEC 0x400000 +#elif defined(__alpha__) || defined(__hppa__) +#define O_CLOEXEC 010000000 +#else +#define O_CLOEXEC 02000000 +#endif +#endif + static bool check_pipe(struct perf_data_file *file) { struct stat st; @@ -96,7 +107,8 @@ static int open_file_write(struct perf_data_file *file) if (check_backup(file)) return -1; - fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, + S_IRUSR|S_IWUSR); if (fd < 0) pr_err("failed to open %s : %s\n", file->path, diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h index ae510ce16cb1..80241ba78101 100644 --- a/tools/perf/util/data.h +++ b/tools/perf/util/data.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_DATA_H #define __PERF_DATA_H diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index a5b3777ffee6..dc8b53b6950e 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* For general debugging purposes */ #include "../perf.h" diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index c818bdb1c1ab..77445dfc5c7d 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* For debugging general purposes */ #ifndef __PERF_DEBUG_H #define __PERF_DEBUG_H diff --git a/tools/perf/util/demangle-java.c b/tools/perf/util/demangle-java.c index cb66d334f532..e4c486756053 100644 --- a/tools/perf/util/demangle-java.c +++ b/tools/perf/util/demangle-java.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/demangle-java.h b/tools/perf/util/demangle-java.h index a981c1f968fe..f936c8eabe5d 100644 --- a/tools/perf/util/demangle-java.h +++ b/tools/perf/util/demangle-java.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_DEMANGLE_JAVA #define __PERF_DEMANGLE_JAVA 1 /* diff --git a/tools/perf/util/demangle-rust.c b/tools/perf/util/demangle-rust.c index f9dafa888c06..423afbbd386b 100644 --- a/tools/perf/util/demangle-rust.c +++ b/tools/perf/util/demangle-rust.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "util.h" #include "debug.h" diff --git a/tools/perf/util/demangle-rust.h b/tools/perf/util/demangle-rust.h index 7b41ead7e0dd..2fca618b1aa5 100644 --- a/tools/perf/util/demangle-rust.h +++ b/tools/perf/util/demangle-rust.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_DEMANGLE_RUST #define __PERF_DEMANGLE_RUST 1 diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 4e7ab611377a..00c98c968cb1 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -32,6 +33,7 @@ char dso__symtab_origin(const struct dso *dso) [DSO_BINARY_TYPE__JAVA_JIT] = 'j', [DSO_BINARY_TYPE__DEBUGLINK] = 'l', [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', + [DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO] = 'D', [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', [DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO] = 'o', @@ -97,7 +99,12 @@ int dso__read_binary_type_filename(const struct dso *dso, break; } case DSO_BINARY_TYPE__BUILD_ID_CACHE: - if (dso__build_id_filename(dso, filename, size) == NULL) + if (dso__build_id_filename(dso, filename, size, false) == NULL) + ret = -1; + break; + + case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO: + if (dso__build_id_filename(dso, filename, size, true) == NULL) ret = -1; break; @@ -504,7 +511,14 @@ static void check_data_close(void); */ static int open_dso(struct dso *dso, struct machine *machine) { - int fd = __open_dso(dso, machine); + int fd; + struct nscookie nsc; + + if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_enter(dso->nsinfo, &nsc); + fd = __open_dso(dso, machine); + if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_exit(&nsc); if (fd >= 0) { dso__list_add(dso); @@ -1236,6 +1250,7 @@ void dso__delete(struct dso *dso) dso_cache__free(dso); dso__free_a2l(dso); zfree(&dso->symsrc_filename); + nsinfo__zput(dso->nsinfo); pthread_mutex_destroy(&dso->lock); free(dso); } @@ -1301,6 +1316,7 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits) { bool have_build_id = false; struct dso *pos; + struct nscookie nsc; list_for_each_entry(pos, head, node) { if (with_hits && !pos->hit && !dso__is_vdso(pos)) @@ -1309,11 +1325,13 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits) have_build_id = true; continue; } + nsinfo__mountns_enter(pos->nsinfo, &nsc); if (filename__read_build_id(pos->long_name, pos->build_id, sizeof(pos->build_id)) > 0) { have_build_id = true; pos->has_build_id = true; } + nsinfo__mountns_exit(&nsc); } return have_build_id; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index bd061ba7b47c..926ff2e7f668 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_DSO #define __PERF_DSO @@ -10,6 +11,7 @@ #include #include #include "map.h" +#include "namespaces.h" #include "build-id.h" enum dso_binary_type { @@ -20,6 +22,7 @@ enum dso_binary_type { DSO_BINARY_TYPE__JAVA_JIT, DSO_BINARY_TYPE__DEBUGLINK, DSO_BINARY_TYPE__BUILD_ID_CACHE, + DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO, DSO_BINARY_TYPE__FEDORA_DEBUGINFO, DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__BUILDID_DEBUGINFO, @@ -187,6 +190,7 @@ struct dso { void *priv; u64 db_id; }; + struct nsinfo *nsinfo; refcount_t refcnt; char name[0]; }; diff --git a/tools/perf/util/dump-insn.c b/tools/perf/util/dump-insn.c index ffbdb19f05d0..10988d3de7ce 100644 --- a/tools/perf/util/dump-insn.c +++ b/tools/perf/util/dump-insn.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "dump-insn.h" diff --git a/tools/perf/util/dump-insn.h b/tools/perf/util/dump-insn.h index 90fb115981cf..0e06280a8860 100644 --- a/tools/perf/util/dump-insn.h +++ b/tools/perf/util/dump-insn.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_DUMP_INSN_H #define __PERF_DUMP_INSN_H 1 diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c index c708395b3cb6..db55eddce8cd 100644 --- a/tools/perf/util/dwarf-regs.c +++ b/tools/perf/util/dwarf-regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * dwarf-regs.c : Mapping of DWARF debug register numbers into register names. * diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index 9e21538c42ae..6276b340f893 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "cpumap.h" #include "env.h" #include "util.h" diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index b164dfd2dcbf..1eb35b190b34 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_ENV_H #define __PERF_ENV_H diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index dc5c3bb69d73..fc690fecbfd6 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -57,6 +58,7 @@ static const char *perf_event__names[] = { [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE", [PERF_RECORD_TIME_CONV] = "TIME_CONV", + [PERF_RECORD_HEADER_FEATURE] = "FEATURE", }; static const char *perf_ns__names[] = { diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 9967c87af7a6..5524ee69279c 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_RECORD_H #define __PERF_RECORD_H @@ -142,7 +143,8 @@ struct branch_flags { u64 in_tx:1; u64 abort:1; u64 cycles:16; - u64 reserved:44; + u64 type:4; + u64 reserved:40; }; struct branch_entry { @@ -199,6 +201,7 @@ struct perf_sample { u32 cpu; u32 raw_size; u64 data_src; + u64 phys_addr; u32 flags; u16 insn_len; u8 cpumode; @@ -244,6 +247,7 @@ enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_STAT_ROUND = 77, PERF_RECORD_EVENT_UPDATE = 78, PERF_RECORD_TIME_CONV = 79, + PERF_RECORD_HEADER_FEATURE = 80, PERF_RECORD_HEADER_MAX }; @@ -609,6 +613,12 @@ struct time_conv_event { u64 time_zero; }; +struct feature_event { + struct perf_event_header header; + u64 feat_id; + char data[]; +}; + union perf_event { struct perf_event_header header; struct mmap_event mmap; @@ -639,6 +649,7 @@ union perf_event { struct stat_event stat; struct stat_round_event stat_round; struct time_conv_event time_conv; + struct feature_event feat; }; void perf_event__print_totals(void); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 46c0faf6c502..6a0d7ffbeba0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -242,9 +242,9 @@ void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr) } } -int perf_evlist__add_default(struct perf_evlist *evlist) +int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise) { - struct perf_evsel *evsel = perf_evsel__new_cycles(); + struct perf_evsel *evsel = perf_evsel__new_cycles(precise); if (evsel == NULL) return -ENOMEM; @@ -1419,8 +1419,6 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e { struct perf_evsel *evsel; int err = 0; - const int ncpus = cpu_map__nr(evlist->cpus), - nthreads = thread_map__nr(evlist->threads); evlist__for_each_entry(evlist, evsel) { if (evsel->filter == NULL) @@ -1430,7 +1428,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **e * filters only work for tracepoint event, which doesn't have cpu limit. * So evlist and evsel should always be same. */ - err = perf_evsel__apply_filter(evsel, ncpus, nthreads, evsel->filter); + err = perf_evsel__apply_filter(evsel, evsel->filter); if (err) { *err_evsel = evsel; break; @@ -1623,13 +1621,9 @@ void perf_evlist__set_selected(struct perf_evlist *evlist, void perf_evlist__close(struct perf_evlist *evlist) { struct perf_evsel *evsel; - int ncpus = cpu_map__nr(evlist->cpus); - int nthreads = thread_map__nr(evlist->threads); - evlist__for_each_entry_reverse(evlist, evsel) { - int n = evsel->cpus ? evsel->cpus->nr : ncpus; - perf_evsel__close(evsel, n, nthreads); - } + evlist__for_each_entry_reverse(evlist, evsel) + perf_evsel__close(evsel); } static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 8d601fbdd8d6..c1750a400bb7 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_EVLIST_H #define __PERF_EVLIST_H 1 @@ -115,7 +116,14 @@ void perf_evlist__delete(struct perf_evlist *evlist); void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); void perf_evlist__remove(struct perf_evlist *evlist, struct perf_evsel *evsel); -int perf_evlist__add_default(struct perf_evlist *evlist); + +int __perf_evlist__add_default(struct perf_evlist *evlist, bool precise); + +static inline int perf_evlist__add_default(struct perf_evlist *evlist) +{ + return __perf_evlist__add_default(evlist, true); +} + int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, struct perf_event_attr *attrs, size_t nr_attrs); @@ -258,6 +266,11 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist); void perf_evlist__splice_list_tail(struct perf_evlist *evlist, struct list_head *list); +static inline bool perf_evlist__empty(struct perf_evlist *evlist) +{ + return list_empty(&evlist->entries); +} + static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) { return list_entry(evlist->entries.next, struct perf_evsel, node); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 413f74df08de..0dccdb89572c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -49,6 +49,7 @@ static struct { bool clockid_wrong; bool lbr_flags; bool write_backward; + bool group_read; } perf_missing_features; static clockid_t clockid; @@ -58,6 +59,8 @@ static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) return 0; } +void __weak test_attr__ready(void) { } + static void perf_evsel__no_extra_fini(struct perf_evsel *evsel __maybe_unused) { } @@ -268,16 +271,24 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) return evsel; } -struct perf_evsel *perf_evsel__new_cycles(void) +static bool perf_event_can_profile_kernel(void) +{ + return geteuid() == 0 || perf_event_paranoid() == -1; +} + +struct perf_evsel *perf_evsel__new_cycles(bool precise) { struct perf_event_attr attr = { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, - .exclude_kernel = geteuid() != 0, + .exclude_kernel = !perf_event_can_profile_kernel(), }; struct perf_evsel *evsel; event_attr_init(&attr); + + if (!precise) + goto new_event; /* * Unnamed union member, not supported as struct member named * initializer in older compilers such as gcc 4.4.7 @@ -292,7 +303,7 @@ struct perf_evsel *perf_evsel__new_cycles(void) * to kick in when we return and before perf_evsel__open() is called. */ attr.sample_period = 0; - +new_event: evsel = perf_evsel__new(&attr); if (evsel == NULL) goto out; @@ -896,8 +907,13 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, if (opts->no_samples) attr->sample_freq = 0; - if (opts->inherit_stat) + if (opts->inherit_stat) { + evsel->attr.read_format |= + PERF_FORMAT_TOTAL_TIME_ENABLED | + PERF_FORMAT_TOTAL_TIME_RUNNING | + PERF_FORMAT_ID; attr->inherit_stat = 1; + } if (opts->sample_address) { perf_evsel__set_sample_bit(evsel, ADDR); @@ -944,6 +960,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, if (opts->sample_address) perf_evsel__set_sample_bit(evsel, DATA_SRC); + if (opts->sample_phys_addr) + perf_evsel__set_sample_bit(evsel, PHYS_ADDR); + if (opts->no_buffering) { attr->watermark = 0; attr->wakeup_events = 1; @@ -1045,16 +1064,13 @@ static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthread return evsel->fd != NULL ? 0 : -ENOMEM; } -static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthreads, +static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ioc, void *arg) { int cpu, thread; - if (evsel->system_wide) - nthreads = 1; - - for (cpu = 0; cpu < ncpus; cpu++) { - for (thread = 0; thread < nthreads; thread++) { + for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) { + for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) { int fd = FD(evsel, cpu, thread), err = ioctl(fd, ioc, arg); @@ -1066,10 +1082,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea return 0; } -int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads, - const char *filter) +int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter) { - return perf_evsel__run_ioctl(evsel, ncpus, nthreads, + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_SET_FILTER, (void *)filter); } @@ -1116,20 +1131,14 @@ int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter) int perf_evsel__enable(struct perf_evsel *evsel) { - int nthreads = thread_map__nr(evsel->threads); - int ncpus = cpu_map__nr(evsel->cpus); - - return perf_evsel__run_ioctl(evsel, ncpus, nthreads, + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, 0); } int perf_evsel__disable(struct perf_evsel *evsel) { - int nthreads = thread_map__nr(evsel->threads); - int ncpus = cpu_map__nr(evsel->cpus); - - return perf_evsel__run_ioctl(evsel, ncpus, nthreads, + return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, 0); } @@ -1179,15 +1188,12 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel) } } -void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) +void perf_evsel__close_fd(struct perf_evsel *evsel) { int cpu, thread; - if (evsel->system_wide) - nthreads = 1; - - for (cpu = 0; cpu < ncpus; cpu++) - for (thread = 0; thread < nthreads; ++thread) { + for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) + for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) { close(FD(evsel, cpu, thread)); FD(evsel, cpu, thread) = -1; } @@ -1256,20 +1262,148 @@ void perf_counts_values__scale(struct perf_counts_values *count, *pscaled = scaled; } +static int perf_evsel__read_size(struct perf_evsel *evsel) +{ + u64 read_format = evsel->attr.read_format; + int entry = sizeof(u64); /* value */ + int size = 0; + int nr = 1; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + size += sizeof(u64); + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + size += sizeof(u64); + + if (read_format & PERF_FORMAT_ID) + entry += sizeof(u64); + + if (read_format & PERF_FORMAT_GROUP) { + nr = evsel->nr_members; + size += sizeof(u64); + } + + size += entry * nr; + return size; +} + int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, struct perf_counts_values *count) { + size_t size = perf_evsel__read_size(evsel); + memset(count, 0, sizeof(*count)); if (FD(evsel, cpu, thread) < 0) return -EINVAL; - if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) <= 0) + if (readn(FD(evsel, cpu, thread), count->values, size) <= 0) return -errno; return 0; } +static int +perf_evsel__read_one(struct perf_evsel *evsel, int cpu, int thread) +{ + struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread); + + return perf_evsel__read(evsel, cpu, thread, count); +} + +static void +perf_evsel__set_count(struct perf_evsel *counter, int cpu, int thread, + u64 val, u64 ena, u64 run) +{ + struct perf_counts_values *count; + + count = perf_counts(counter->counts, cpu, thread); + + count->val = val; + count->ena = ena; + count->run = run; + count->loaded = true; +} + +static int +perf_evsel__process_group_data(struct perf_evsel *leader, + int cpu, int thread, u64 *data) +{ + u64 read_format = leader->attr.read_format; + struct sample_read_value *v; + u64 nr, ena = 0, run = 0, i; + + nr = *data++; + + if (nr != (u64) leader->nr_members) + return -EINVAL; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + ena = *data++; + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + run = *data++; + + v = (struct sample_read_value *) data; + + perf_evsel__set_count(leader, cpu, thread, + v[0].value, ena, run); + + for (i = 1; i < nr; i++) { + struct perf_evsel *counter; + + counter = perf_evlist__id2evsel(leader->evlist, v[i].id); + if (!counter) + return -EINVAL; + + perf_evsel__set_count(counter, cpu, thread, + v[i].value, ena, run); + } + + return 0; +} + +static int +perf_evsel__read_group(struct perf_evsel *leader, int cpu, int thread) +{ + struct perf_stat_evsel *ps = leader->priv; + u64 read_format = leader->attr.read_format; + int size = perf_evsel__read_size(leader); + u64 *data = ps->group_data; + + if (!(read_format & PERF_FORMAT_ID)) + return -EINVAL; + + if (!perf_evsel__is_group_leader(leader)) + return -EINVAL; + + if (!data) { + data = zalloc(size); + if (!data) + return -ENOMEM; + + ps->group_data = data; + } + + if (FD(leader, cpu, thread) < 0) + return -EINVAL; + + if (readn(FD(leader, cpu, thread), data, size) <= 0) + return -errno; + + return perf_evsel__process_group_data(leader, cpu, thread, data); +} + +int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread) +{ + u64 read_format = evsel->attr.read_format; + + if (read_format & PERF_FORMAT_GROUP) + return perf_evsel__read_group(evsel, cpu, thread); + else + return perf_evsel__read_one(evsel, cpu, thread); +} + int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, int cpu, int thread, bool scale) { @@ -1338,7 +1472,7 @@ static void __p_sample_type(char *buf, size_t size, u64 value) bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), bit_name(IDENTIFIER), bit_name(REGS_INTR), bit_name(DATA_SRC), - bit_name(WEIGHT), + bit_name(WEIGHT), bit_name(PHYS_ADDR), { .name = NULL, } }; #undef bit_name @@ -1545,6 +1679,8 @@ fallback_missing_features: if (perf_missing_features.lbr_flags) evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | PERF_SAMPLE_BRANCH_NO_CYCLES); + if (perf_missing_features.group_read && evsel->attr.inherit) + evsel->attr.read_format &= ~(PERF_FORMAT_GROUP|PERF_FORMAT_ID); retry_sample_id: if (perf_missing_features.sample_id_all) evsel->attr.sample_id_all = 0; @@ -1569,6 +1705,8 @@ retry_open: pr_debug2("sys_perf_event_open: pid %d cpu %d group_fd %d flags %#lx", pid, cpus->map[cpu], group_fd, flags); + test_attr__ready(); + fd = sys_perf_event_open(&evsel->attr, pid, cpus->map[cpu], group_fd, flags); @@ -1664,31 +1802,45 @@ try_fallback: */ if (!perf_missing_features.write_backward && evsel->attr.write_backward) { perf_missing_features.write_backward = true; + pr_debug2("switching off write_backward\n"); goto out_close; } else if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) { perf_missing_features.clockid_wrong = true; + pr_debug2("switching off clockid\n"); goto fallback_missing_features; } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) { perf_missing_features.clockid = true; + pr_debug2("switching off use_clockid\n"); goto fallback_missing_features; } else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) { perf_missing_features.cloexec = true; + pr_debug2("switching off cloexec flag\n"); goto fallback_missing_features; } else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) { perf_missing_features.mmap2 = true; + pr_debug2("switching off mmap2\n"); goto fallback_missing_features; } else if (!perf_missing_features.exclude_guest && (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { perf_missing_features.exclude_guest = true; + pr_debug2("switching off exclude_guest, exclude_host\n"); goto fallback_missing_features; } else if (!perf_missing_features.sample_id_all) { perf_missing_features.sample_id_all = true; + pr_debug2("switching off sample_id_all\n"); goto retry_sample_id; } else if (!perf_missing_features.lbr_flags && (evsel->attr.branch_sample_type & (PERF_SAMPLE_BRANCH_NO_CYCLES | PERF_SAMPLE_BRANCH_NO_FLAGS))) { perf_missing_features.lbr_flags = true; + pr_debug2("switching off branch sample type no (cycles/flags)\n"); + goto fallback_missing_features; + } else if (!perf_missing_features.group_read && + evsel->attr.inherit && + (evsel->attr.read_format & PERF_FORMAT_GROUP)) { + perf_missing_features.group_read = true; + pr_debug2("switching off group read\n"); goto fallback_missing_features; } out_close: @@ -1702,12 +1854,12 @@ out_close: return err; } -void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads) +void perf_evsel__close(struct perf_evsel *evsel) { if (evsel->fd == NULL) return; - perf_evsel__close_fd(evsel, ncpus, nthreads); + perf_evsel__close_fd(evsel); perf_evsel__free_fd(evsel); } @@ -2062,6 +2214,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, } } + data->phys_addr = 0; + if (type & PERF_SAMPLE_PHYS_ADDR) { + data->phys_addr = *array; + array++; + } + return 0; } @@ -2167,6 +2325,9 @@ size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, } } + if (type & PERF_SAMPLE_PHYS_ADDR) + result += sizeof(u64); + return result; } @@ -2356,6 +2517,11 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, } } + if (type & PERF_SAMPLE_PHYS_ADDR) { + *array = sample->phys_addr; + array++; + } + return 0; } @@ -2535,7 +2701,9 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, "unprivileged users (without CAP_SYS_ADMIN).\n\n" "The current value is %d:\n\n" " -1: Allow use of (almost) all events by all users\n" - ">= 0: Disallow raw tracepoint access by users without CAP_IOC_LOCK\n" + " Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK\n" + ">= 0: Disallow ftrace function tracepoint by users without CAP_SYS_ADMIN\n" + " Disallow raw tracepoint access by users without CAP_SYS_ADMIN\n" ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n" ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN\n\n" "To make this setting permanent, edit /etc/sysctl.conf too, e.g.:\n\n" @@ -2610,3 +2778,10 @@ char *perf_evsel__env_arch(struct perf_evsel *evsel) return evsel->evlist->env->arch; return NULL; } + +char *perf_evsel__env_cpuid(struct perf_evsel *evsel) +{ + if (evsel && evsel->evlist && evsel->evlist->env) + return evsel->evlist->env->cpuid; + return NULL; +} diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d101695c482c..b4df79d72329 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_EVSEL_H #define __PERF_EVSEL_H 1 @@ -131,6 +132,7 @@ struct perf_evsel { bool cmdline_group_boundary; struct list_head config_terms; int bpf_fd; + bool auto_merge_stats; bool merged_stat; const char * metric_expr; const char * metric_name; @@ -185,7 +187,7 @@ static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char * return perf_evsel__newtp_idx(sys, name, 0); } -struct perf_evsel *perf_evsel__new_cycles(void); +struct perf_evsel *perf_evsel__new_cycles(bool precise); struct event_format *event_format__new(const char *sys, const char *name); @@ -226,7 +228,7 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel); int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size); int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); -void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); +void perf_evsel__close_fd(struct perf_evsel *evsel); void __perf_evsel__set_sample_bit(struct perf_evsel *evsel, enum perf_event_sample_format bit); @@ -246,8 +248,7 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, const char *filter); int perf_evsel__append_tp_filter(struct perf_evsel *evsel, const char *filter); int perf_evsel__append_addr_filter(struct perf_evsel *evsel, const char *filter); -int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads, - const char *filter); +int perf_evsel__apply_filter(struct perf_evsel *evsel, const char *filter); int perf_evsel__enable(struct perf_evsel *evsel); int perf_evsel__disable(struct perf_evsel *evsel); @@ -257,7 +258,7 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel, struct thread_map *threads); int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, struct thread_map *threads); -void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads); +void perf_evsel__close(struct perf_evsel *evsel); struct perf_sample; @@ -299,6 +300,8 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1, int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, struct perf_counts_values *count); +int perf_evsel__read_counter(struct perf_evsel *evsel, int cpu, int thread); + int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, int cpu, int thread, bool scale); @@ -436,5 +439,6 @@ int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, attr__fprintf_f attr__fprintf, void *priv); char *perf_evsel__env_arch(struct perf_evsel *evsel); +char *perf_evsel__env_cpuid(struct perf_evsel *evsel); #endif /* __PERF_EVSEL_H */ diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 583f3a602506..1fd7c2e46db2 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h index 9c2760a1a96e..046160831f90 100644 --- a/tools/perf/util/expr.h +++ b/tools/perf/util/expr.h @@ -1,7 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PARSE_CTX_H #define PARSE_CTX_H 1 -#define EXPR_MAX_OTHER 8 +#define EXPR_MAX_OTHER 15 #define MAX_PARSE_ID EXPR_MAX_OTHER struct parse_id { diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 954556bea36e..432b8560cf51 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -4,6 +4,7 @@ #include "util/debug.h" #define IN_EXPR_Y 1 #include "expr.h" +#include "smt.h" #include #define MAXIDLEN 256 @@ -22,13 +23,15 @@ %token NUMBER %token ID +%token MIN MAX IF ELSE SMT_ON +%left MIN MAX IF %left '|' %left '^' %left '&' %left '-' '+' %left '*' '/' '%' %left NEG NOT -%type expr +%type expr if_expr %{ static int expr__lex(YYSTYPE *res, const char **pp); @@ -57,22 +60,33 @@ static int lookup_id(struct parse_ctx *ctx, char *id, double *val) %} %% -all_expr: expr { *final_val = $1; } +all_expr: if_expr { *final_val = $1; } + ; + +if_expr: + expr IF expr ELSE expr { $$ = $3 ? $1 : $5; } + | expr ; expr: NUMBER | ID { if (lookup_id(ctx, $1, &$$) < 0) { - pr_debug("%s not found", $1); + pr_debug("%s not found\n", $1); YYABORT; } } + | expr '|' expr { $$ = (long)$1 | (long)$3; } + | expr '&' expr { $$ = (long)$1 & (long)$3; } + | expr '^' expr { $$ = (long)$1 ^ (long)$3; } | expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { if ($3 == 0) YYABORT; $$ = $1 / $3; } | expr '%' expr { if ((long)$3 == 0) YYABORT; $$ = (long)$1 % (long)$3; } | '-' expr %prec NEG { $$ = -$2; } - | '(' expr ')' { $$ = $2; } + | '(' if_expr ')' { $$ = $2; } + | MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; } + | MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; } + | SMT_ON { $$ = smt_on() > 0; } ; %% @@ -82,13 +96,47 @@ static int expr__symbol(YYSTYPE *res, const char *p, const char **pp) char *dst = res->id; const char *s = p; - while (isalnum(*p) || *p == '_' || *p == '.') { + if (*p == '#') + *dst++ = *p++; + + while (isalnum(*p) || *p == '_' || *p == '.' || *p == ':' || *p == '@' || *p == '\\') { if (p - s >= MAXIDLEN) return -1; - *dst++ = *p++; + /* + * Allow @ instead of / to be able to specify pmu/event/ without + * conflicts with normal division. + */ + if (*p == '@') + *dst++ = '/'; + else if (*p == '\\') + *dst++ = *++p; + else + *dst++ = *p; + p++; } *dst = 0; *pp = p; + dst = res->id; + switch (dst[0]) { + case 'm': + if (!strcmp(dst, "min")) + return MIN; + if (!strcmp(dst, "max")) + return MAX; + break; + case 'i': + if (!strcmp(dst, "if")) + return IF; + break; + case 'e': + if (!strcmp(dst, "else")) + return ELSE; + break; + case '#': + if (!strcasecmp(dst, "#smt_on")) + return SMT_ON; + break; + } return ID; } @@ -102,6 +150,7 @@ static int expr__lex(YYSTYPE *res, const char **pp) p++; s = p; switch (*p++) { + case '#': case 'a' ... 'z': case 'A' ... 'Z': return expr__symbol(res, p - 1, pp); @@ -132,6 +181,19 @@ void expr__ctx_init(struct parse_ctx *ctx) ctx->num_ids = 0; } +static bool already_seen(const char *val, const char *one, const char **other, + int num_other) +{ + int i; + + if (one && !strcasecmp(one, val)) + return true; + for (i = 0; i < num_other; i++) + if (!strcasecmp(other[i], val)) + return true; + return false; +} + int expr__find_other(const char *p, const char *one, const char ***other, int *num_otherp) { @@ -151,7 +213,7 @@ int expr__find_other(const char *p, const char *one, const char ***other, err = 0; break; } - if (tok == ID && strcasecmp(one, val.id)) { + if (tok == ID && !already_seen(val.id, one, *other, num_other)) { if (num_other >= EXPR_MAX_OTHER - 1) { pr_debug("Too many extra events in %s\n", orig); break; diff --git a/tools/perf/util/find-vdso-map.c b/tools/perf/util/find-vdso-map.c index 95ef1cffc056..d7823e3508fc 100644 --- a/tools/perf/util/find-vdso-map.c +++ b/tools/perf/util/find-vdso-map.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 static int find_vdso_map(void **start, void **end) { FILE *maps; diff --git a/tools/perf/util/genelf.h b/tools/perf/util/genelf.h index 2424bd9862a3..de322d51c7fe 100644 --- a/tools/perf/util/genelf.h +++ b/tools/perf/util/genelf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __GENELF_H__ #define __GENELF_H__ diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh index 0ac2037c970c..9bbcec4e3365 100755 --- a/tools/perf/util/generate-cmdlist.sh +++ b/tools/perf/util/generate-cmdlist.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 echo "/* Automatically generated by $0 */ struct cmdname_help diff --git a/tools/perf/util/group.h b/tools/perf/util/group.h index 116debe7a995..f36c7e31780a 100644 --- a/tools/perf/util/group.h +++ b/tools/perf/util/group.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef GROUP_H #define GROUP_H 1 diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 76ed7d03e500..ba0cea8fef72 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "util.h" @@ -12,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +36,7 @@ #include "data.h" #include #include "asm/bug.h" +#include "tool.h" #include "sane_ctype.h" @@ -59,6 +62,15 @@ struct perf_file_attr { struct perf_file_section ids; }; +struct feat_fd { + struct perf_header *ph; + int fd; + void *buf; /* Either buf != NULL or fd >= 0 */ + ssize_t offset; + size_t size; + struct perf_evsel *events; +}; + void perf_header__set_feat(struct perf_header *header, int feat) { set_bit(feat, header->adds_features); @@ -74,28 +86,60 @@ bool perf_header__has_feat(const struct perf_header *header, int feat) return test_bit(feat, header->adds_features); } -static int do_write(int fd, const void *buf, size_t size) +static int __do_write_fd(struct feat_fd *ff, const void *buf, size_t size) { - while (size) { - int ret = write(fd, buf, size); + ssize_t ret = writen(ff->fd, buf, size); - if (ret < 0) - return -errno; + if (ret != (ssize_t)size) + return ret < 0 ? (int)ret : -1; + return 0; +} - size -= ret; - buf += ret; +static int __do_write_buf(struct feat_fd *ff, const void *buf, size_t size) +{ + /* struct perf_event_header::size is u16 */ + const size_t max_size = 0xffff - sizeof(struct perf_event_header); + size_t new_size = ff->size; + void *addr; + + if (size + ff->offset > max_size) + return -E2BIG; + + while (size > (new_size - ff->offset)) + new_size <<= 1; + new_size = min(max_size, new_size); + + if (ff->size < new_size) { + addr = realloc(ff->buf, new_size); + if (!addr) + return -ENOMEM; + ff->buf = addr; + ff->size = new_size; } + memcpy(ff->buf + ff->offset, buf, size); + ff->offset += size; + return 0; } -int write_padded(int fd, const void *bf, size_t count, size_t count_aligned) +/* Return: 0 if succeded, -ERR if failed. */ +int do_write(struct feat_fd *ff, const void *buf, size_t size) +{ + if (!ff->buf) + return __do_write_fd(ff, buf, size); + return __do_write_buf(ff, buf, size); +} + +/* Return: 0 if succeded, -ERR if failed. */ +int write_padded(struct feat_fd *ff, const void *bf, + size_t count, size_t count_aligned) { static const char zero_buf[NAME_ALIGN]; - int err = do_write(fd, bf, count); + int err = do_write(ff, bf, count); if (!err) - err = do_write(fd, zero_buf, count_aligned - count); + err = do_write(ff, zero_buf, count_aligned - count); return err; } @@ -103,7 +147,8 @@ int write_padded(int fd, const void *bf, size_t count, size_t count_aligned) #define string_size(str) \ (PERF_ALIGN((strlen(str) + 1), NAME_ALIGN) + sizeof(u32)) -static int do_write_string(int fd, const char *str) +/* Return: 0 if succeded, -ERR if failed. */ +static int do_write_string(struct feat_fd *ff, const char *str) { u32 len, olen; int ret; @@ -112,32 +157,80 @@ static int do_write_string(int fd, const char *str) len = PERF_ALIGN(olen, NAME_ALIGN); /* write len, incl. \0 */ - ret = do_write(fd, &len, sizeof(len)); + ret = do_write(ff, &len, sizeof(len)); if (ret < 0) return ret; - return write_padded(fd, str, olen, len); + return write_padded(ff, str, olen, len); } -static char *do_read_string(int fd, struct perf_header *ph) +static int __do_read_fd(struct feat_fd *ff, void *addr, ssize_t size) +{ + ssize_t ret = readn(ff->fd, addr, size); + + if (ret != size) + return ret < 0 ? (int)ret : -1; + return 0; +} + +static int __do_read_buf(struct feat_fd *ff, void *addr, ssize_t size) +{ + if (size > (ssize_t)ff->size - ff->offset) + return -1; + + memcpy(addr, ff->buf + ff->offset, size); + ff->offset += size; + + return 0; + +} + +static int __do_read(struct feat_fd *ff, void *addr, ssize_t size) +{ + if (!ff->buf) + return __do_read_fd(ff, addr, size); + return __do_read_buf(ff, addr, size); +} + +static int do_read_u32(struct feat_fd *ff, u32 *addr) +{ + int ret; + + ret = __do_read(ff, addr, sizeof(*addr)); + if (ret) + return ret; + + if (ff->ph->needs_swap) + *addr = bswap_32(*addr); + return 0; +} + +static int do_read_u64(struct feat_fd *ff, u64 *addr) +{ + int ret; + + ret = __do_read(ff, addr, sizeof(*addr)); + if (ret) + return ret; + + if (ff->ph->needs_swap) + *addr = bswap_64(*addr); + return 0; +} + +static char *do_read_string(struct feat_fd *ff) { - ssize_t sz, ret; u32 len; char *buf; - sz = readn(fd, &len, sizeof(len)); - if (sz < (ssize_t)sizeof(len)) + if (do_read_u32(ff, &len)) return NULL; - if (ph->needs_swap) - len = bswap_32(len); - buf = malloc(len); if (!buf) return NULL; - ret = readn(fd, buf, len); - if (ret == (ssize_t)len) { + if (!__do_read(ff, buf, len)) { /* * strings are padded by zeroes * thus the actual strlen of buf @@ -150,25 +243,30 @@ static char *do_read_string(int fd, struct perf_header *ph) return NULL; } -static int write_tracing_data(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist) +static int write_tracing_data(struct feat_fd *ff, + struct perf_evlist *evlist) { - return read_tracing_data(fd, &evlist->entries); + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + + return read_tracing_data(ff->fd, &evlist->entries); } - -static int write_build_id(int fd, struct perf_header *h, +static int write_build_id(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct perf_session *session; int err; - session = container_of(h, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); if (!perf_session__read_build_ids(session, true)) return -1; - err = perf_session__write_buildid_table(session, fd); + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; + + err = perf_session__write_buildid_table(session, ff); if (err < 0) { pr_debug("failed to write buildid table\n"); return err; @@ -178,7 +276,7 @@ static int write_build_id(int fd, struct perf_header *h, return 0; } -static int write_hostname(int fd, struct perf_header *h __maybe_unused, +static int write_hostname(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct utsname uts; @@ -188,10 +286,10 @@ static int write_hostname(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return -1; - return do_write_string(fd, uts.nodename); + return do_write_string(ff, uts.nodename); } -static int write_osrelease(int fd, struct perf_header *h __maybe_unused, +static int write_osrelease(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct utsname uts; @@ -201,10 +299,10 @@ static int write_osrelease(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return -1; - return do_write_string(fd, uts.release); + return do_write_string(ff, uts.release); } -static int write_arch(int fd, struct perf_header *h __maybe_unused, +static int write_arch(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct utsname uts; @@ -214,16 +312,16 @@ static int write_arch(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return -1; - return do_write_string(fd, uts.machine); + return do_write_string(ff, uts.machine); } -static int write_version(int fd, struct perf_header *h __maybe_unused, +static int write_version(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { - return do_write_string(fd, perf_version_string); + return do_write_string(ff, perf_version_string); } -static int __write_cpudesc(int fd, const char *cpuinfo_proc) +static int __write_cpudesc(struct feat_fd *ff, const char *cpuinfo_proc) { FILE *file; char *buf = NULL; @@ -273,25 +371,22 @@ static int __write_cpudesc(int fd, const char *cpuinfo_proc) } p++; } - ret = do_write_string(fd, s); + ret = do_write_string(ff, s); done: free(buf); fclose(file); return ret; } -static int write_cpudesc(int fd, struct perf_header *h __maybe_unused, +static int write_cpudesc(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { -#ifndef CPUINFO_PROC -#define CPUINFO_PROC {"model name", } -#endif const char *cpuinfo_procs[] = CPUINFO_PROC; unsigned int i; for (i = 0; i < ARRAY_SIZE(cpuinfo_procs); i++) { int ret; - ret = __write_cpudesc(fd, cpuinfo_procs[i]); + ret = __write_cpudesc(ff, cpuinfo_procs[i]); if (ret >= 0) return ret; } @@ -299,7 +394,7 @@ static int write_cpudesc(int fd, struct perf_header *h __maybe_unused, } -static int write_nrcpus(int fd, struct perf_header *h __maybe_unused, +static int write_nrcpus(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { long nr; @@ -314,14 +409,14 @@ static int write_nrcpus(int fd, struct perf_header *h __maybe_unused, nra = (u32)(nr & UINT_MAX); - ret = do_write(fd, &nrc, sizeof(nrc)); + ret = do_write(ff, &nrc, sizeof(nrc)); if (ret < 0) return ret; - return do_write(fd, &nra, sizeof(nra)); + return do_write(ff, &nra, sizeof(nra)); } -static int write_event_desc(int fd, struct perf_header *h __maybe_unused, +static int write_event_desc(struct feat_fd *ff, struct perf_evlist *evlist) { struct perf_evsel *evsel; @@ -333,7 +428,7 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused, /* * write number of events */ - ret = do_write(fd, &nre, sizeof(nre)); + ret = do_write(ff, &nre, sizeof(nre)); if (ret < 0) return ret; @@ -341,12 +436,12 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused, * size of perf_event_attr struct */ sz = (u32)sizeof(evsel->attr); - ret = do_write(fd, &sz, sizeof(sz)); + ret = do_write(ff, &sz, sizeof(sz)); if (ret < 0) return ret; evlist__for_each_entry(evlist, evsel) { - ret = do_write(fd, &evsel->attr, sz); + ret = do_write(ff, &evsel->attr, sz); if (ret < 0) return ret; /* @@ -357,27 +452,27 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused, * type of ids, */ nri = evsel->ids; - ret = do_write(fd, &nri, sizeof(nri)); + ret = do_write(ff, &nri, sizeof(nri)); if (ret < 0) return ret; /* * write event string as passed on cmdline */ - ret = do_write_string(fd, perf_evsel__name(evsel)); + ret = do_write_string(ff, perf_evsel__name(evsel)); if (ret < 0) return ret; /* * write unique ids for this event */ - ret = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); + ret = do_write(ff, evsel->id, evsel->ids * sizeof(u64)); if (ret < 0) return ret; } return 0; } -static int write_cmdline(int fd, struct perf_header *h __maybe_unused, +static int write_cmdline(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { char buf[MAXPATHLEN]; @@ -395,16 +490,16 @@ static int write_cmdline(int fd, struct perf_header *h __maybe_unused, /* account for binary path */ n = perf_env.nr_cmdline + 1; - ret = do_write(fd, &n, sizeof(n)); + ret = do_write(ff, &n, sizeof(n)); if (ret < 0) return ret; - ret = do_write_string(fd, buf); + ret = do_write_string(ff, buf); if (ret < 0) return ret; for (i = 0 ; i < perf_env.nr_cmdline; i++) { - ret = do_write_string(fd, perf_env.cmdline_argv[i]); + ret = do_write_string(ff, perf_env.cmdline_argv[i]); if (ret < 0) return ret; } @@ -557,8 +652,8 @@ out_free: return tp; } -static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_cpu_topology(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { struct cpu_topo *tp; u32 i; @@ -568,21 +663,21 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused, if (!tp) return -1; - ret = do_write(fd, &tp->core_sib, sizeof(tp->core_sib)); + ret = do_write(ff, &tp->core_sib, sizeof(tp->core_sib)); if (ret < 0) goto done; for (i = 0; i < tp->core_sib; i++) { - ret = do_write_string(fd, tp->core_siblings[i]); + ret = do_write_string(ff, tp->core_siblings[i]); if (ret < 0) goto done; } - ret = do_write(fd, &tp->thread_sib, sizeof(tp->thread_sib)); + ret = do_write(ff, &tp->thread_sib, sizeof(tp->thread_sib)); if (ret < 0) goto done; for (i = 0; i < tp->thread_sib; i++) { - ret = do_write_string(fd, tp->thread_siblings[i]); + ret = do_write_string(ff, tp->thread_siblings[i]); if (ret < 0) break; } @@ -592,11 +687,11 @@ static int write_cpu_topology(int fd, struct perf_header *h __maybe_unused, goto done; for (j = 0; j < perf_env.nr_cpus_avail; j++) { - ret = do_write(fd, &perf_env.cpu[j].core_id, + ret = do_write(ff, &perf_env.cpu[j].core_id, sizeof(perf_env.cpu[j].core_id)); if (ret < 0) return ret; - ret = do_write(fd, &perf_env.cpu[j].socket_id, + ret = do_write(ff, &perf_env.cpu[j].socket_id, sizeof(perf_env.cpu[j].socket_id)); if (ret < 0) return ret; @@ -608,8 +703,8 @@ done: -static int write_total_mem(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_total_mem(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { char *buf = NULL; FILE *fp; @@ -629,7 +724,7 @@ static int write_total_mem(int fd, struct perf_header *h __maybe_unused, if (!ret) { n = sscanf(buf, "%*s %"PRIu64, &mem); if (n == 1) - ret = do_write(fd, &mem, sizeof(mem)); + ret = do_write(ff, &mem, sizeof(mem)); } else ret = -1; free(buf); @@ -637,7 +732,7 @@ static int write_total_mem(int fd, struct perf_header *h __maybe_unused, return ret; } -static int write_topo_node(int fd, int node) +static int write_topo_node(struct feat_fd *ff, int node) { char str[MAXPATHLEN]; char field[32]; @@ -667,11 +762,11 @@ static int write_topo_node(int fd, int node) fclose(fp); fp = NULL; - ret = do_write(fd, &mem_total, sizeof(u64)); + ret = do_write(ff, &mem_total, sizeof(u64)); if (ret) goto done; - ret = do_write(fd, &mem_free, sizeof(u64)); + ret = do_write(ff, &mem_free, sizeof(u64)); if (ret) goto done; @@ -689,7 +784,7 @@ static int write_topo_node(int fd, int node) if (p) *p = '\0'; - ret = do_write_string(fd, buf); + ret = do_write_string(ff, buf); done: free(buf); if (fp) @@ -697,8 +792,8 @@ done: return ret; } -static int write_numa_topology(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_numa_topology(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { char *buf = NULL; size_t len = 0; @@ -725,17 +820,17 @@ static int write_numa_topology(int fd, struct perf_header *h __maybe_unused, nr = (u32)node_map->nr; - ret = do_write(fd, &nr, sizeof(nr)); + ret = do_write(ff, &nr, sizeof(nr)); if (ret < 0) goto done; for (i = 0; i < nr; i++) { j = (u32)node_map->map[i]; - ret = do_write(fd, &j, sizeof(j)); + ret = do_write(ff, &j, sizeof(j)); if (ret < 0) break; - ret = write_topo_node(fd, i); + ret = write_topo_node(ff, i); if (ret < 0) break; } @@ -758,39 +853,40 @@ done: * }; */ -static int write_pmu_mappings(int fd, struct perf_header *h __maybe_unused, +static int write_pmu_mappings(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct perf_pmu *pmu = NULL; - off_t offset = lseek(fd, 0, SEEK_CUR); - __u32 pmu_num = 0; + u32 pmu_num = 0; int ret; - /* write real pmu_num later */ - ret = do_write(fd, &pmu_num, sizeof(pmu_num)); + /* + * Do a first pass to count number of pmu to avoid lseek so this + * works in pipe mode as well. + */ + while ((pmu = perf_pmu__scan(pmu))) { + if (!pmu->name) + continue; + pmu_num++; + } + + ret = do_write(ff, &pmu_num, sizeof(pmu_num)); if (ret < 0) return ret; while ((pmu = perf_pmu__scan(pmu))) { if (!pmu->name) continue; - pmu_num++; - ret = do_write(fd, &pmu->type, sizeof(pmu->type)); + ret = do_write(ff, &pmu->type, sizeof(pmu->type)); if (ret < 0) return ret; - ret = do_write_string(fd, pmu->name); + ret = do_write_string(ff, pmu->name); if (ret < 0) return ret; } - if (pwrite(fd, &pmu_num, sizeof(pmu_num), offset) != sizeof(pmu_num)) { - /* discard all */ - lseek(fd, offset, SEEK_SET); - return -1; - } - return 0; } @@ -806,14 +902,14 @@ static int write_pmu_mappings(int fd, struct perf_header *h __maybe_unused, * }[nr_groups]; * }; */ -static int write_group_desc(int fd, struct perf_header *h __maybe_unused, +static int write_group_desc(struct feat_fd *ff, struct perf_evlist *evlist) { u32 nr_groups = evlist->nr_groups; struct perf_evsel *evsel; int ret; - ret = do_write(fd, &nr_groups, sizeof(nr_groups)); + ret = do_write(ff, &nr_groups, sizeof(nr_groups)); if (ret < 0) return ret; @@ -824,15 +920,15 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused, u32 leader_idx = evsel->idx; u32 nr_members = evsel->nr_members; - ret = do_write_string(fd, name); + ret = do_write_string(ff, name); if (ret < 0) return ret; - ret = do_write(fd, &leader_idx, sizeof(leader_idx)); + ret = do_write(ff, &leader_idx, sizeof(leader_idx)); if (ret < 0) return ret; - ret = do_write(fd, &nr_members, sizeof(nr_members)); + ret = do_write(ff, &nr_members, sizeof(nr_members)); if (ret < 0) return ret; } @@ -849,7 +945,7 @@ int __weak get_cpuid(char *buffer __maybe_unused, size_t sz __maybe_unused) return -1; } -static int write_cpuid(int fd, struct perf_header *h __maybe_unused, +static int write_cpuid(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { char buffer[64]; @@ -861,25 +957,27 @@ static int write_cpuid(int fd, struct perf_header *h __maybe_unused, return -1; write_it: - return do_write_string(fd, buffer); + return do_write_string(ff, buffer); } -static int write_branch_stack(int fd __maybe_unused, - struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_branch_stack(struct feat_fd *ff __maybe_unused, + struct perf_evlist *evlist __maybe_unused) { return 0; } -static int write_auxtrace(int fd, struct perf_header *h, +static int write_auxtrace(struct feat_fd *ff, struct perf_evlist *evlist __maybe_unused) { struct perf_session *session; int err; - session = container_of(h, struct perf_session, header); + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; - err = auxtrace_index__write(fd, &session->auxtrace_index); + session = container_of(ff->ph, struct perf_session, header); + + err = auxtrace_index__write(ff->fd, &session->auxtrace_index); if (err < 0) pr_err("Failed to write auxtrace index\n"); return err; @@ -1026,8 +1124,8 @@ static int build_caches(struct cpu_cache_level caches[], u32 size, u32 *cntp) #define MAX_CACHES 2000 -static int write_cache(int fd, struct perf_header *h __maybe_unused, - struct perf_evlist *evlist __maybe_unused) +static int write_cache(struct feat_fd *ff, + struct perf_evlist *evlist __maybe_unused) { struct cpu_cache_level caches[MAX_CACHES]; u32 cnt = 0, i, version = 1; @@ -1039,11 +1137,11 @@ static int write_cache(int fd, struct perf_header *h __maybe_unused, qsort(&caches, cnt, sizeof(struct cpu_cache_level), cpu_cache_level__sort); - ret = do_write(fd, &version, sizeof(u32)); + ret = do_write(ff, &version, sizeof(u32)); if (ret < 0) goto out; - ret = do_write(fd, &cnt, sizeof(u32)); + ret = do_write(ff, &cnt, sizeof(u32)); if (ret < 0) goto out; @@ -1051,7 +1149,7 @@ static int write_cache(int fd, struct perf_header *h __maybe_unused, struct cpu_cache_level *c = &caches[i]; #define _W(v) \ - ret = do_write(fd, &c->v, sizeof(u32)); \ + ret = do_write(ff, &c->v, sizeof(u32)); \ if (ret < 0) \ goto out; @@ -1062,7 +1160,7 @@ static int write_cache(int fd, struct perf_header *h __maybe_unused, #undef _W #define _W(v) \ - ret = do_write_string(fd, (const char *) c->v); \ + ret = do_write_string(ff, (const char *) c->v); \ if (ret < 0) \ goto out; @@ -1078,69 +1176,62 @@ out: return ret; } -static int write_stat(int fd __maybe_unused, - struct perf_header *h __maybe_unused, +static int write_stat(struct feat_fd *ff __maybe_unused, struct perf_evlist *evlist __maybe_unused) { return 0; } -static void print_hostname(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_hostname(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# hostname : %s\n", ph->env.hostname); + fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname); } -static void print_osrelease(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_osrelease(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# os release : %s\n", ph->env.os_release); + fprintf(fp, "# os release : %s\n", ff->ph->env.os_release); } -static void print_arch(struct perf_header *ph, int fd __maybe_unused, FILE *fp) +static void print_arch(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# arch : %s\n", ph->env.arch); + fprintf(fp, "# arch : %s\n", ff->ph->env.arch); } -static void print_cpudesc(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_cpudesc(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# cpudesc : %s\n", ph->env.cpu_desc); + fprintf(fp, "# cpudesc : %s\n", ff->ph->env.cpu_desc); } -static void print_nrcpus(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_nrcpus(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# nrcpus online : %u\n", ph->env.nr_cpus_online); - fprintf(fp, "# nrcpus avail : %u\n", ph->env.nr_cpus_avail); + fprintf(fp, "# nrcpus online : %u\n", ff->ph->env.nr_cpus_online); + fprintf(fp, "# nrcpus avail : %u\n", ff->ph->env.nr_cpus_avail); } -static void print_version(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_version(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# perf version : %s\n", ph->env.version); + fprintf(fp, "# perf version : %s\n", ff->ph->env.version); } -static void print_cmdline(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_cmdline(struct feat_fd *ff, FILE *fp) { int nr, i; - nr = ph->env.nr_cmdline; + nr = ff->ph->env.nr_cmdline; fprintf(fp, "# cmdline : "); for (i = 0; i < nr; i++) - fprintf(fp, "%s ", ph->env.cmdline_argv[i]); + fprintf(fp, "%s ", ff->ph->env.cmdline_argv[i]); fputc('\n', fp); } -static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_cpu_topology(struct feat_fd *ff, FILE *fp) { + struct perf_header *ph = ff->ph; + int cpu_nr = ph->env.nr_cpus_avail; int nr, i; char *str; - int cpu_nr = ph->env.nr_cpus_avail; nr = ph->env.nr_sibling_cores; str = ph->env.sibling_cores; @@ -1181,31 +1272,21 @@ static void free_event_desc(struct perf_evsel *events) free(events); } -static struct perf_evsel * -read_event_desc(struct perf_header *ph, int fd) +static struct perf_evsel *read_event_desc(struct feat_fd *ff) { struct perf_evsel *evsel, *events = NULL; u64 *id; void *buf = NULL; u32 nre, sz, nr, i, j; - ssize_t ret; size_t msz; /* number of events */ - ret = readn(fd, &nre, sizeof(nre)); - if (ret != (ssize_t)sizeof(nre)) + if (do_read_u32(ff, &nre)) goto error; - if (ph->needs_swap) - nre = bswap_32(nre); - - ret = readn(fd, &sz, sizeof(sz)); - if (ret != (ssize_t)sizeof(sz)) + if (do_read_u32(ff, &sz)) goto error; - if (ph->needs_swap) - sz = bswap_32(sz); - /* buffer to hold on file attr struct */ buf = malloc(sz); if (!buf) @@ -1227,25 +1308,23 @@ read_event_desc(struct perf_header *ph, int fd) * must read entire on-file attr struct to * sync up with layout. */ - ret = readn(fd, buf, sz); - if (ret != (ssize_t)sz) + if (__do_read(ff, buf, sz)) goto error; - if (ph->needs_swap) + if (ff->ph->needs_swap) perf_event__attr_swap(buf); memcpy(&evsel->attr, buf, msz); - ret = readn(fd, &nr, sizeof(nr)); - if (ret != (ssize_t)sizeof(nr)) + if (do_read_u32(ff, &nr)) goto error; - if (ph->needs_swap) { - nr = bswap_32(nr); + if (ff->ph->needs_swap) evsel->needs_swap = true; - } - evsel->name = do_read_string(fd, ph); + evsel->name = do_read_string(ff); + if (!evsel->name) + goto error; if (!nr) continue; @@ -1257,11 +1336,8 @@ read_event_desc(struct perf_header *ph, int fd) evsel->id = id; for (j = 0 ; j < nr; j++) { - ret = readn(fd, id, sizeof(*id)); - if (ret != (ssize_t)sizeof(*id)) + if (do_read_u64(ff, id)) goto error; - if (ph->needs_swap) - *id = bswap_64(*id); id++; } } @@ -1280,12 +1356,17 @@ static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, return fprintf(fp, ", %s = %s", name, val); } -static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) +static void print_event_desc(struct feat_fd *ff, FILE *fp) { - struct perf_evsel *evsel, *events = read_event_desc(ph, fd); + struct perf_evsel *evsel, *events; u32 j; u64 *id; + if (ff->events) + events = ff->events; + else + events = read_event_desc(ff); + if (!events) { fprintf(fp, "# event desc: not available or unable to read\n"); return; @@ -1310,22 +1391,21 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) } free_event_desc(events); + ff->events = NULL; } -static void print_total_mem(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_total_mem(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# total memory : %Lu kB\n", ph->env.total_mem); + fprintf(fp, "# total memory : %llu kB\n", ff->ph->env.total_mem); } -static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_numa_topology(struct feat_fd *ff, FILE *fp) { int i; struct numa_node *n; - for (i = 0; i < ph->env.nr_numa_nodes; i++) { - n = &ph->env.numa_nodes[i]; + for (i = 0; i < ff->ph->env.nr_numa_nodes; i++) { + n = &ff->ph->env.numa_nodes[i]; fprintf(fp, "# node%u meminfo : total = %"PRIu64" kB," " free = %"PRIu64" kB\n", @@ -1336,56 +1416,51 @@ static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, } } -static void print_cpuid(struct perf_header *ph, int fd __maybe_unused, FILE *fp) +static void print_cpuid(struct feat_fd *ff, FILE *fp) { - fprintf(fp, "# cpuid : %s\n", ph->env.cpuid); + fprintf(fp, "# cpuid : %s\n", ff->ph->env.cpuid); } -static void print_branch_stack(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp) +static void print_branch_stack(struct feat_fd *ff __maybe_unused, FILE *fp) { fprintf(fp, "# contains samples with branch stack\n"); } -static void print_auxtrace(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp) +static void print_auxtrace(struct feat_fd *ff __maybe_unused, FILE *fp) { fprintf(fp, "# contains AUX area data (e.g. instruction trace)\n"); } -static void print_stat(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp) +static void print_stat(struct feat_fd *ff __maybe_unused, FILE *fp) { fprintf(fp, "# contains stat data\n"); } -static void print_cache(struct perf_header *ph __maybe_unused, - int fd __maybe_unused, FILE *fp __maybe_unused) +static void print_cache(struct feat_fd *ff, FILE *fp __maybe_unused) { int i; fprintf(fp, "# CPU cache info:\n"); - for (i = 0; i < ph->env.caches_cnt; i++) { + for (i = 0; i < ff->ph->env.caches_cnt; i++) { fprintf(fp, "# "); - cpu_cache_level__fprintf(fp, &ph->env.caches[i]); + cpu_cache_level__fprintf(fp, &ff->ph->env.caches[i]); } } -static void print_pmu_mappings(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_pmu_mappings(struct feat_fd *ff, FILE *fp) { const char *delimiter = "# pmu mappings: "; char *str, *tmp; u32 pmu_num; u32 type; - pmu_num = ph->env.nr_pmu_mappings; + pmu_num = ff->ph->env.nr_pmu_mappings; if (!pmu_num) { fprintf(fp, "# pmu mappings: not available\n"); return; } - str = ph->env.pmu_mappings; + str = ff->ph->env.pmu_mappings; while (pmu_num) { type = strtoul(str, &tmp, 0); @@ -1408,14 +1483,13 @@ error: fprintf(fp, "# pmu mappings: unable to read\n"); } -static void print_group_desc(struct perf_header *ph, int fd __maybe_unused, - FILE *fp) +static void print_group_desc(struct feat_fd *ff, FILE *fp) { struct perf_session *session; struct perf_evsel *evsel; u32 nr = 0; - session = container_of(ph, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); evlist__for_each_entry(session->evlist, evsel) { if (perf_evsel__is_group_leader(evsel) && @@ -1588,113 +1662,61 @@ out: return err; } -static int process_tracing_data(struct perf_file_section *section __maybe_unused, - struct perf_header *ph __maybe_unused, - int fd, void *data) +/* Macro for features that simply need to read and store a string. */ +#define FEAT_PROCESS_STR_FUN(__feat, __feat_env) \ +static int process_##__feat(struct feat_fd *ff, void *data __maybe_unused) \ +{\ + ff->ph->env.__feat_env = do_read_string(ff); \ + return ff->ph->env.__feat_env ? 0 : -ENOMEM; \ +} + +FEAT_PROCESS_STR_FUN(hostname, hostname); +FEAT_PROCESS_STR_FUN(osrelease, os_release); +FEAT_PROCESS_STR_FUN(version, version); +FEAT_PROCESS_STR_FUN(arch, arch); +FEAT_PROCESS_STR_FUN(cpudesc, cpu_desc); +FEAT_PROCESS_STR_FUN(cpuid, cpuid); + +static int process_tracing_data(struct feat_fd *ff, void *data) { - ssize_t ret = trace_report(fd, data, false); + ssize_t ret = trace_report(ff->fd, data, false); + return ret < 0 ? -1 : 0; } -static int process_build_id(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_build_id(struct feat_fd *ff, void *data __maybe_unused) { - if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) + if (perf_header__read_build_ids(ff->ph, ff->fd, ff->offset, ff->size)) pr_debug("Failed to read buildids, continuing...\n"); return 0; } -static int process_hostname(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_nrcpus(struct feat_fd *ff, void *data __maybe_unused) { - ph->env.hostname = do_read_string(fd, ph); - return ph->env.hostname ? 0 : -ENOMEM; -} + int ret; + u32 nr_cpus_avail, nr_cpus_online; -static int process_osrelease(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.os_release = do_read_string(fd, ph); - return ph->env.os_release ? 0 : -ENOMEM; -} + ret = do_read_u32(ff, &nr_cpus_avail); + if (ret) + return ret; -static int process_version(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.version = do_read_string(fd, ph); - return ph->env.version ? 0 : -ENOMEM; -} - -static int process_arch(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.arch = do_read_string(fd, ph); - return ph->env.arch ? 0 : -ENOMEM; -} - -static int process_nrcpus(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ssize_t ret; - u32 nr; - - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) - return -1; - - if (ph->needs_swap) - nr = bswap_32(nr); - - ph->env.nr_cpus_avail = nr; - - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) - return -1; - - if (ph->needs_swap) - nr = bswap_32(nr); - - ph->env.nr_cpus_online = nr; + ret = do_read_u32(ff, &nr_cpus_online); + if (ret) + return ret; + ff->ph->env.nr_cpus_avail = (int)nr_cpus_avail; + ff->ph->env.nr_cpus_online = (int)nr_cpus_online; return 0; } -static int process_cpudesc(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_total_mem(struct feat_fd *ff, void *data __maybe_unused) { - ph->env.cpu_desc = do_read_string(fd, ph); - return ph->env.cpu_desc ? 0 : -ENOMEM; -} + u64 total_mem; + int ret; -static int process_cpuid(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - ph->env.cpuid = do_read_string(fd, ph); - return ph->env.cpuid ? 0 : -ENOMEM; -} - -static int process_total_mem(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) -{ - uint64_t mem; - ssize_t ret; - - ret = readn(fd, &mem, sizeof(mem)); - if (ret != sizeof(mem)) + ret = do_read_u64(ff, &total_mem); + if (ret) return -1; - - if (ph->needs_swap) - mem = bswap_64(mem); - - ph->env.total_mem = mem; + ff->ph->env.total_mem = (unsigned long long)total_mem; return 0; } @@ -1731,43 +1753,42 @@ perf_evlist__set_event_name(struct perf_evlist *evlist, } static int -process_event_desc(struct perf_file_section *section __maybe_unused, - struct perf_header *header, int fd, - void *data __maybe_unused) +process_event_desc(struct feat_fd *ff, void *data __maybe_unused) { struct perf_session *session; - struct perf_evsel *evsel, *events = read_event_desc(header, fd); + struct perf_evsel *evsel, *events = read_event_desc(ff); if (!events) return 0; - session = container_of(header, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); + + if (session->file->is_pipe) { + /* Save events for reading later by print_event_desc, + * since they can't be read again in pipe mode. */ + ff->events = events; + } + for (evsel = events; evsel->attr.size; evsel++) perf_evlist__set_event_name(session->evlist, evsel); - free_event_desc(events); + if (!session->file->is_pipe) + free_event_desc(events); return 0; } -static int process_cmdline(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_cmdline(struct feat_fd *ff, void *data __maybe_unused) { - ssize_t ret; char *str, *cmdline = NULL, **argv = NULL; u32 nr, i, len = 0; - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) return -1; - if (ph->needs_swap) - nr = bswap_32(nr); + ff->ph->env.nr_cmdline = nr; - ph->env.nr_cmdline = nr; - - cmdline = zalloc(section->size + nr + 1); + cmdline = zalloc(ff->size + nr + 1); if (!cmdline) return -1; @@ -1776,7 +1797,7 @@ static int process_cmdline(struct perf_file_section *section, goto error; for (i = 0; i < nr; i++) { - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1785,8 +1806,8 @@ static int process_cmdline(struct perf_file_section *section, len += strlen(str) + 1; free(str); } - ph->env.cmdline = cmdline; - ph->env.cmdline_argv = (const char **) argv; + ff->ph->env.cmdline = cmdline; + ff->ph->env.cmdline_argv = (const char **) argv; return 0; error: @@ -1795,35 +1816,29 @@ error: return -1; } -static int process_cpu_topology(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_cpu_topology(struct feat_fd *ff, void *data __maybe_unused) { - ssize_t ret; u32 nr, i; char *str; struct strbuf sb; - int cpu_nr = ph->env.nr_cpus_avail; + int cpu_nr = ff->ph->env.nr_cpus_avail; u64 size = 0; + struct perf_header *ph = ff->ph; ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); if (!ph->env.cpu) return -1; - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) goto free_cpu; - if (ph->needs_swap) - nr = bswap_32(nr); - ph->env.nr_sibling_cores = nr; size += sizeof(u32); if (strbuf_init(&sb, 128) < 0) goto free_cpu; for (i = 0; i < nr; i++) { - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1835,18 +1850,14 @@ static int process_cpu_topology(struct perf_file_section *section, } ph->env.sibling_cores = strbuf_detach(&sb, NULL); - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) return -1; - if (ph->needs_swap) - nr = bswap_32(nr); - ph->env.nr_sibling_threads = nr; size += sizeof(u32); for (i = 0; i < nr; i++) { - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1862,28 +1873,20 @@ static int process_cpu_topology(struct perf_file_section *section, * The header may be from old perf, * which doesn't include core id and socket id information. */ - if (section->size <= size) { + if (ff->size <= size) { zfree(&ph->env.cpu); return 0; } for (i = 0; i < (u32)cpu_nr; i++) { - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) goto free_cpu; - if (ph->needs_swap) - nr = bswap_32(nr); - ph->env.cpu[i].core_id = nr; - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) goto free_cpu; - if (ph->needs_swap) - nr = bswap_32(nr); - if (nr != (u32)-1 && nr > (u32)cpu_nr) { pr_debug("socket_id number is too big." "You may need to upgrade the perf tool.\n"); @@ -1902,23 +1905,16 @@ free_cpu: return -1; } -static int process_numa_topology(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_numa_topology(struct feat_fd *ff, void *data __maybe_unused) { struct numa_node *nodes, *n; - ssize_t ret; u32 nr, i; char *str; /* nr nodes */ - ret = readn(fd, &nr, sizeof(nr)); - if (ret != sizeof(nr)) + if (do_read_u32(ff, &nr)) return -1; - if (ph->needs_swap) - nr = bswap_32(nr); - nodes = zalloc(sizeof(*nodes) * nr); if (!nodes) return -ENOMEM; @@ -1927,25 +1923,16 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse n = &nodes[i]; /* node number */ - ret = readn(fd, &n->node, sizeof(u32)); - if (ret != sizeof(n->node)) + if (do_read_u32(ff, &n->node)) goto error; - ret = readn(fd, &n->mem_total, sizeof(u64)); - if (ret != sizeof(u64)) + if (do_read_u64(ff, &n->mem_total)) goto error; - ret = readn(fd, &n->mem_free, sizeof(u64)); - if (ret != sizeof(u64)) + if (do_read_u64(ff, &n->mem_free)) goto error; - if (ph->needs_swap) { - n->node = bswap_32(n->node); - n->mem_total = bswap_64(n->mem_total); - n->mem_free = bswap_64(n->mem_free); - } - - str = do_read_string(fd, ph); + str = do_read_string(ff); if (!str) goto error; @@ -1955,8 +1942,8 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse free(str); } - ph->env.nr_numa_nodes = nr; - ph->env.numa_nodes = nodes; + ff->ph->env.nr_numa_nodes = nr; + ff->ph->env.numa_nodes = nodes; return 0; error: @@ -1964,39 +1951,30 @@ error: return -1; } -static int process_pmu_mappings(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_pmu_mappings(struct feat_fd *ff, void *data __maybe_unused) { - ssize_t ret; char *name; u32 pmu_num; u32 type; struct strbuf sb; - ret = readn(fd, &pmu_num, sizeof(pmu_num)); - if (ret != sizeof(pmu_num)) + if (do_read_u32(ff, &pmu_num)) return -1; - if (ph->needs_swap) - pmu_num = bswap_32(pmu_num); - if (!pmu_num) { pr_debug("pmu mappings not available\n"); return 0; } - ph->env.nr_pmu_mappings = pmu_num; + ff->ph->env.nr_pmu_mappings = pmu_num; if (strbuf_init(&sb, 128) < 0) return -1; while (pmu_num) { - if (readn(fd, &type, sizeof(type)) != sizeof(type)) + if (do_read_u32(ff, &type)) goto error; - if (ph->needs_swap) - type = bswap_32(type); - name = do_read_string(fd, ph); + name = do_read_string(ff); if (!name) goto error; @@ -2007,12 +1985,12 @@ static int process_pmu_mappings(struct perf_file_section *section __maybe_unused goto error; if (!strcmp(name, "msr")) - ph->env.msr_pmu_type = type; + ff->ph->env.msr_pmu_type = type; free(name); pmu_num--; } - ph->env.pmu_mappings = strbuf_detach(&sb, NULL); + ff->ph->env.pmu_mappings = strbuf_detach(&sb, NULL); return 0; error: @@ -2020,9 +1998,7 @@ error: return -1; } -static int process_group_desc(struct perf_file_section *section __maybe_unused, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_group_desc(struct feat_fd *ff, void *data __maybe_unused) { size_t ret = -1; u32 i, nr, nr_groups; @@ -2034,13 +2010,10 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, u32 nr_members; } *desc; - if (readn(fd, &nr_groups, sizeof(nr_groups)) != sizeof(nr_groups)) + if (do_read_u32(ff, &nr_groups)) return -1; - if (ph->needs_swap) - nr_groups = bswap_32(nr_groups); - - ph->env.nr_groups = nr_groups; + ff->ph->env.nr_groups = nr_groups; if (!nr_groups) { pr_debug("group desc not available\n"); return 0; @@ -2051,26 +2024,21 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, return -1; for (i = 0; i < nr_groups; i++) { - desc[i].name = do_read_string(fd, ph); + desc[i].name = do_read_string(ff); if (!desc[i].name) goto out_free; - if (readn(fd, &desc[i].leader_idx, sizeof(u32)) != sizeof(u32)) + if (do_read_u32(ff, &desc[i].leader_idx)) goto out_free; - if (readn(fd, &desc[i].nr_members, sizeof(u32)) != sizeof(u32)) + if (do_read_u32(ff, &desc[i].nr_members)) goto out_free; - - if (ph->needs_swap) { - desc[i].leader_idx = bswap_32(desc[i].leader_idx); - desc[i].nr_members = bswap_32(desc[i].nr_members); - } } /* * Rebuild group relationship based on the group_desc */ - session = container_of(ph, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); session->evlist->nr_groups = nr_groups; i = nr = 0; @@ -2114,44 +2082,34 @@ out_free: return ret; } -static int process_auxtrace(struct perf_file_section *section, - struct perf_header *ph, int fd, - void *data __maybe_unused) +static int process_auxtrace(struct feat_fd *ff, void *data __maybe_unused) { struct perf_session *session; int err; - session = container_of(ph, struct perf_session, header); + session = container_of(ff->ph, struct perf_session, header); - err = auxtrace_index__process(fd, section->size, session, - ph->needs_swap); + err = auxtrace_index__process(ff->fd, ff->size, session, + ff->ph->needs_swap); if (err < 0) pr_err("Failed to process auxtrace index\n"); return err; } -static int process_cache(struct perf_file_section *section __maybe_unused, - struct perf_header *ph __maybe_unused, int fd __maybe_unused, - void *data __maybe_unused) +static int process_cache(struct feat_fd *ff, void *data __maybe_unused) { struct cpu_cache_level *caches; u32 cnt, i, version; - if (readn(fd, &version, sizeof(version)) != sizeof(version)) + if (do_read_u32(ff, &version)) return -1; - if (ph->needs_swap) - version = bswap_32(version); - if (version != 1) return -1; - if (readn(fd, &cnt, sizeof(cnt)) != sizeof(cnt)) + if (do_read_u32(ff, &cnt)) return -1; - if (ph->needs_swap) - cnt = bswap_32(cnt); - caches = zalloc(sizeof(*caches) * cnt); if (!caches) return -1; @@ -2160,10 +2118,8 @@ static int process_cache(struct perf_file_section *section __maybe_unused, struct cpu_cache_level c; #define _R(v) \ - if (readn(fd, &c.v, sizeof(u32)) != sizeof(u32))\ + if (do_read_u32(ff, &c.v))\ goto out_free_caches; \ - if (ph->needs_swap) \ - c.v = bswap_32(c.v); \ _R(level) _R(line_size) @@ -2171,9 +2127,9 @@ static int process_cache(struct perf_file_section *section __maybe_unused, _R(ways) #undef _R - #define _R(v) \ - c.v = do_read_string(fd, ph); \ - if (!c.v) \ + #define _R(v) \ + c.v = do_read_string(ff); \ + if (!c.v) \ goto out_free_caches; _R(type) @@ -2184,8 +2140,8 @@ static int process_cache(struct perf_file_section *section __maybe_unused, caches[i] = c; } - ph->env.caches = caches; - ph->env.caches_cnt = cnt; + ff->ph->env.caches = caches; + ff->ph->env.caches_cnt = cnt; return 0; out_free_caches: free(caches); @@ -2193,48 +2149,62 @@ out_free_caches: } struct feature_ops { - int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); - void (*print)(struct perf_header *h, int fd, FILE *fp); - int (*process)(struct perf_file_section *section, - struct perf_header *h, int fd, void *data); + int (*write)(struct feat_fd *ff, struct perf_evlist *evlist); + void (*print)(struct feat_fd *ff, FILE *fp); + int (*process)(struct feat_fd *ff, void *data); const char *name; bool full_only; + bool synthesize; }; -#define FEAT_OPA(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func } -#define FEAT_OPP(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func, \ - .process = process_##func } -#define FEAT_OPF(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func, \ - .process = process_##func, .full_only = true } +#define FEAT_OPR(n, func, __full_only) \ + [HEADER_##n] = { \ + .name = __stringify(n), \ + .write = write_##func, \ + .print = print_##func, \ + .full_only = __full_only, \ + .process = process_##func, \ + .synthesize = true \ + } + +#define FEAT_OPN(n, func, __full_only) \ + [HEADER_##n] = { \ + .name = __stringify(n), \ + .write = write_##func, \ + .print = print_##func, \ + .full_only = __full_only, \ + .process = process_##func \ + } /* feature_ops not implemented: */ #define print_tracing_data NULL #define print_build_id NULL +#define process_branch_stack NULL +#define process_stat NULL + + static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { - FEAT_OPP(HEADER_TRACING_DATA, tracing_data), - FEAT_OPP(HEADER_BUILD_ID, build_id), - FEAT_OPP(HEADER_HOSTNAME, hostname), - FEAT_OPP(HEADER_OSRELEASE, osrelease), - FEAT_OPP(HEADER_VERSION, version), - FEAT_OPP(HEADER_ARCH, arch), - FEAT_OPP(HEADER_NRCPUS, nrcpus), - FEAT_OPP(HEADER_CPUDESC, cpudesc), - FEAT_OPP(HEADER_CPUID, cpuid), - FEAT_OPP(HEADER_TOTAL_MEM, total_mem), - FEAT_OPP(HEADER_EVENT_DESC, event_desc), - FEAT_OPP(HEADER_CMDLINE, cmdline), - FEAT_OPF(HEADER_CPU_TOPOLOGY, cpu_topology), - FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology), - FEAT_OPA(HEADER_BRANCH_STACK, branch_stack), - FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings), - FEAT_OPP(HEADER_GROUP_DESC, group_desc), - FEAT_OPP(HEADER_AUXTRACE, auxtrace), - FEAT_OPA(HEADER_STAT, stat), - FEAT_OPF(HEADER_CACHE, cache), + FEAT_OPN(TRACING_DATA, tracing_data, false), + FEAT_OPN(BUILD_ID, build_id, false), + FEAT_OPR(HOSTNAME, hostname, false), + FEAT_OPR(OSRELEASE, osrelease, false), + FEAT_OPR(VERSION, version, false), + FEAT_OPR(ARCH, arch, false), + FEAT_OPR(NRCPUS, nrcpus, false), + FEAT_OPR(CPUDESC, cpudesc, false), + FEAT_OPR(CPUID, cpuid, false), + FEAT_OPR(TOTAL_MEM, total_mem, false), + FEAT_OPR(EVENT_DESC, event_desc, false), + FEAT_OPR(CMDLINE, cmdline, false), + FEAT_OPR(CPU_TOPOLOGY, cpu_topology, true), + FEAT_OPR(NUMA_TOPOLOGY, numa_topology, true), + FEAT_OPN(BRANCH_STACK, branch_stack, false), + FEAT_OPR(PMU_MAPPINGS, pmu_mappings, false), + FEAT_OPN(GROUP_DESC, group_desc, false), + FEAT_OPN(AUXTRACE, auxtrace, false), + FEAT_OPN(STAT, stat, false), + FEAT_OPN(CACHE, cache, true), }; struct header_print_data { @@ -2247,6 +2217,7 @@ static int perf_file_section__fprintf_info(struct perf_file_section *section, int feat, int fd, void *data) { struct header_print_data *hd = data; + struct feat_fd ff; if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { pr_debug("Failed to lseek to %" PRIu64 " offset for feature " @@ -2260,8 +2231,13 @@ static int perf_file_section__fprintf_info(struct perf_file_section *section, if (!feat_ops[feat].print) return 0; + ff = (struct feat_fd) { + .fd = fd, + .ph = ph, + }; + if (!feat_ops[feat].full_only || hd->full) - feat_ops[feat].print(ph, fd, hd->fp); + feat_ops[feat].print(&ff, hd->fp); else fprintf(hd->fp, "# %s info available, use -I to display\n", feat_ops[feat].name); @@ -2302,29 +2278,32 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) return 0; } -static int do_write_feat(int fd, struct perf_header *h, int type, +static int do_write_feat(struct feat_fd *ff, int type, struct perf_file_section **p, struct perf_evlist *evlist) { int err; int ret = 0; - if (perf_header__has_feat(h, type)) { + if (perf_header__has_feat(ff->ph, type)) { if (!feat_ops[type].write) return -1; - (*p)->offset = lseek(fd, 0, SEEK_CUR); + if (WARN(ff->buf, "Error: calling %s in pipe-mode.\n", __func__)) + return -1; - err = feat_ops[type].write(fd, h, evlist); + (*p)->offset = lseek(ff->fd, 0, SEEK_CUR); + + err = feat_ops[type].write(ff, evlist); if (err < 0) { pr_debug("failed to write feature %s\n", feat_ops[type].name); /* undo anything written */ - lseek(fd, (*p)->offset, SEEK_SET); + lseek(ff->fd, (*p)->offset, SEEK_SET); return -1; } - (*p)->size = lseek(fd, 0, SEEK_CUR) - (*p)->offset; + (*p)->size = lseek(ff->fd, 0, SEEK_CUR) - (*p)->offset; (*p)++; } return ret; @@ -2334,12 +2313,18 @@ static int perf_header__adds_write(struct perf_header *header, struct perf_evlist *evlist, int fd) { int nr_sections; + struct feat_fd ff; struct perf_file_section *feat_sec, *p; int sec_size; u64 sec_start; int feat; int err; + ff = (struct feat_fd){ + .fd = fd, + .ph = header, + }; + nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS); if (!nr_sections) return 0; @@ -2354,7 +2339,7 @@ static int perf_header__adds_write(struct perf_header *header, lseek(fd, sec_start + sec_size, SEEK_SET); for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) { - if (do_write_feat(fd, header, feat, &p, evlist)) + if (do_write_feat(&ff, feat, &p, evlist)) perf_header__clear_feat(header, feat); } @@ -2363,7 +2348,7 @@ static int perf_header__adds_write(struct perf_header *header, * may write more than needed due to dropped feature, but * this is okay, reader will skip the mising entries */ - err = do_write(fd, feat_sec, sec_size); + err = do_write(&ff, feat_sec, sec_size); if (err < 0) pr_debug("failed to write feature section\n"); free(feat_sec); @@ -2373,14 +2358,17 @@ static int perf_header__adds_write(struct perf_header *header, int perf_header__write_pipe(int fd) { struct perf_pipe_file_header f_header; + struct feat_fd ff; int err; + ff = (struct feat_fd){ .fd = fd }; + f_header = (struct perf_pipe_file_header){ .magic = PERF_MAGIC, .size = sizeof(f_header), }; - err = do_write(fd, &f_header, sizeof(f_header)); + err = do_write(&ff, &f_header, sizeof(f_header)); if (err < 0) { pr_debug("failed to write perf pipe header\n"); return err; @@ -2397,21 +2385,23 @@ int perf_session__write_header(struct perf_session *session, struct perf_file_attr f_attr; struct perf_header *header = &session->header; struct perf_evsel *evsel; + struct feat_fd ff; u64 attr_offset; int err; + ff = (struct feat_fd){ .fd = fd}; lseek(fd, sizeof(f_header), SEEK_SET); evlist__for_each_entry(session->evlist, evsel) { evsel->id_offset = lseek(fd, 0, SEEK_CUR); - err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); + err = do_write(&ff, evsel->id, evsel->ids * sizeof(u64)); if (err < 0) { pr_debug("failed to write perf header\n"); return err; } } - attr_offset = lseek(fd, 0, SEEK_CUR); + attr_offset = lseek(ff.fd, 0, SEEK_CUR); evlist__for_each_entry(evlist, evsel) { f_attr = (struct perf_file_attr){ @@ -2421,7 +2411,7 @@ int perf_session__write_header(struct perf_session *session, .size = evsel->ids * sizeof(u64), } }; - err = do_write(fd, &f_attr, sizeof(f_attr)); + err = do_write(&ff, &f_attr, sizeof(f_attr)); if (err < 0) { pr_debug("failed to write perf header attribute\n"); return err; @@ -2456,7 +2446,7 @@ int perf_session__write_header(struct perf_session *session, memcpy(&f_header.adds_features, &header->adds_features, sizeof(header->adds_features)); lseek(fd, 0, SEEK_SET); - err = do_write(fd, &f_header, sizeof(f_header)); + err = do_write(&ff, &f_header, sizeof(f_header)); if (err < 0) { pr_debug("failed to write perf header\n"); return err; @@ -2710,6 +2700,13 @@ static int perf_file_section__process(struct perf_file_section *section, struct perf_header *ph, int feat, int fd, void *data) { + struct feat_fd fdd = { + .fd = fd, + .ph = ph, + .size = section->size, + .offset = section->offset, + }; + if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { pr_debug("Failed to lseek to %" PRIu64 " offset for feature " "%d, continuing...\n", section->offset, feat); @@ -2724,13 +2721,17 @@ static int perf_file_section__process(struct perf_file_section *section, if (!feat_ops[feat].process) return 0; - return feat_ops[feat].process(section, ph, fd, data); + return feat_ops[feat].process(&fdd, data); } static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, struct perf_header *ph, int fd, bool repipe) { + struct feat_fd ff = { + .fd = STDOUT_FILENO, + .ph = ph, + }; ssize_t ret; ret = readn(fd, header, sizeof(*header)); @@ -2745,7 +2746,7 @@ static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, if (ph->needs_swap) header->size = bswap_64(header->size); - if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0) + if (repipe && do_write(&ff, header, sizeof(*header)) < 0) return -1; return 0; @@ -2995,6 +2996,103 @@ int perf_event__synthesize_attr(struct perf_tool *tool, return err; } +int perf_event__synthesize_features(struct perf_tool *tool, + struct perf_session *session, + struct perf_evlist *evlist, + perf_event__handler_t process) +{ + struct perf_header *header = &session->header; + struct feat_fd ff; + struct feature_event *fe; + size_t sz, sz_hdr; + int feat, ret; + + sz_hdr = sizeof(fe->header); + sz = sizeof(union perf_event); + /* get a nice alignment */ + sz = PERF_ALIGN(sz, page_size); + + memset(&ff, 0, sizeof(ff)); + + ff.buf = malloc(sz); + if (!ff.buf) + return -ENOMEM; + + ff.size = sz - sz_hdr; + + for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) { + if (!feat_ops[feat].synthesize) { + pr_debug("No record header feature for header :%d\n", feat); + continue; + } + + ff.offset = sizeof(*fe); + + ret = feat_ops[feat].write(&ff, evlist); + if (ret || ff.offset <= (ssize_t)sizeof(*fe)) { + pr_debug("Error writing feature\n"); + continue; + } + /* ff.buf may have changed due to realloc in do_write() */ + fe = ff.buf; + memset(fe, 0, sizeof(*fe)); + + fe->feat_id = feat; + fe->header.type = PERF_RECORD_HEADER_FEATURE; + fe->header.size = ff.offset; + + ret = process(tool, ff.buf, NULL, NULL); + if (ret) { + free(ff.buf); + return ret; + } + } + free(ff.buf); + return 0; +} + +int perf_event__process_feature(struct perf_tool *tool, + union perf_event *event, + struct perf_session *session __maybe_unused) +{ + struct feat_fd ff = { .fd = 0 }; + struct feature_event *fe = (struct feature_event *)event; + int type = fe->header.type; + u64 feat = fe->feat_id; + + if (type < 0 || type >= PERF_RECORD_HEADER_MAX) { + pr_warning("invalid record type %d in pipe-mode\n", type); + return 0; + } + if (feat == HEADER_RESERVED || feat > HEADER_LAST_FEATURE) { + pr_warning("invalid record type %d in pipe-mode\n", type); + return -1; + } + + if (!feat_ops[feat].process) + return 0; + + ff.buf = (void *)fe->data; + ff.size = event->header.size - sizeof(event->header); + ff.ph = &session->header; + + if (feat_ops[feat].process(&ff, NULL)) + return -1; + + if (!feat_ops[feat].print || !tool->show_feat_hdr) + return 0; + + if (!feat_ops[feat].full_only || + tool->show_feat_hdr >= SHOW_FEAT_HEADER_FULL_INFO) { + feat_ops[feat].print(&ff, stdout); + } else { + fprintf(stdout, "# %s info available, use -I to display\n", + feat_ops[feat].name); + } + + return 0; +} + static struct event_update_event * event_update_event__new(size_t size, u64 type, u64 id) { @@ -3253,6 +3351,7 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, union perf_event ev; struct tracing_data *tdata; ssize_t size = 0, aligned_size = 0, padding; + struct feat_fd ff; int err __maybe_unused = 0; /* @@ -3287,7 +3386,9 @@ int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, */ tracing_data_put(tdata); - write_padded(fd, NULL, 0, padding); + ff = (struct feat_fd){ .fd = fd }; + if (write_padded(&ff, NULL, 0, padding)) + return -1; return aligned_size; } diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index d30109b421ee..29ccbfdf8724 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_HEADER_H #define __PERF_HEADER_H @@ -101,6 +102,15 @@ int perf_header__process_sections(struct perf_header *header, int fd, int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full); +int perf_event__synthesize_features(struct perf_tool *tool, + struct perf_session *session, + struct perf_evlist *evlist, + perf_event__handler_t process); + +int perf_event__process_feature(struct perf_tool *tool, + union perf_event *event, + struct perf_session *session); + int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, u32 ids, u64 *id, perf_event__handler_t process); @@ -144,7 +154,12 @@ bool is_perf_magic(u64 magic); #define NAME_ALIGN 64 -int write_padded(int fd, const void *bf, size_t count, size_t count_aligned); +struct feat_fd; + +int do_write(struct feat_fd *fd, const void *buf, size_t size); + +int write_padded(struct feat_fd *fd, const void *bf, + size_t count, size_t count_aligned); /* * arch specific callback diff --git a/tools/perf/util/help-unknown-cmd.c b/tools/perf/util/help-unknown-cmd.c index 15b95300d7f3..4f07a5ba5030 100644 --- a/tools/perf/util/help-unknown-cmd.c +++ b/tools/perf/util/help-unknown-cmd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "cache.h" #include "config.h" #include diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index cf0186a088c1..097473600d94 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util.h" #include "build-id.h" #include "hist.h" @@ -167,6 +168,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) symlen = unresolved_col_width + 4 + 2; hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO); } + + hists__new_col_len(hists, HISTC_MEM_PHYS_DADDR, + unresolved_col_width + 4 + 2); + } else { symlen = unresolved_col_width + 4 + 2; hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen); @@ -749,12 +754,9 @@ iter_prepare_branch_entry(struct hist_entry_iter *iter, struct addr_location *al } static int -iter_add_single_branch_entry(struct hist_entry_iter *iter, +iter_add_single_branch_entry(struct hist_entry_iter *iter __maybe_unused, struct addr_location *al __maybe_unused) { - /* to avoid calling callback function */ - iter->he = NULL; - return 0; } @@ -1762,6 +1764,8 @@ void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *pro else use_callchain = symbol_conf.use_callchain; + use_callchain |= symbol_conf.show_branchflag_count; + output_resort(evsel__hists(evsel), prog, use_callchain, NULL); } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ee3670a388df..f6630cb95eff 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_HIST_H #define __PERF_HIST_H @@ -47,6 +48,7 @@ enum hist_column { HISTC_GLOBAL_WEIGHT, HISTC_MEM_DADDR_SYMBOL, HISTC_MEM_DADDR_DSO, + HISTC_MEM_PHYS_DADDR, HISTC_MEM_LOCKED, HISTC_MEM_TLB, HISTC_MEM_LVL, diff --git a/tools/perf/util/include/asm/asm-offsets.h b/tools/perf/util/include/asm/asm-offsets.h index ed538942523d..3aff4cf44944 100644 --- a/tools/perf/util/include/asm/asm-offsets.h +++ b/tools/perf/util/include/asm/asm-offsets.h @@ -1 +1,2 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* stub */ diff --git a/tools/perf/util/include/asm/cpufeature.h b/tools/perf/util/include/asm/cpufeature.h index acffd5e4d1d4..2270481c7e0a 100644 --- a/tools/perf/util/include/asm/cpufeature.h +++ b/tools/perf/util/include/asm/cpufeature.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_CPUFEATURE_H #define PERF_CPUFEATURE_H diff --git a/tools/perf/util/include/asm/dwarf2.h b/tools/perf/util/include/asm/dwarf2.h index afe38199e922..e9876be63dbf 100644 --- a/tools/perf/util/include/asm/dwarf2.h +++ b/tools/perf/util/include/asm/dwarf2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_DWARF2_H #define PERF_DWARF2_H diff --git a/tools/perf/util/include/asm/uaccess.h b/tools/perf/util/include/asm/uaccess.h index d0f72b8fcc35..6a6f4b990547 100644 --- a/tools/perf/util/include/asm/uaccess.h +++ b/tools/perf/util/include/asm/uaccess.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_ASM_UACCESS_H_ #define _PERF_ASM_UACCESS_H_ diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h index 43bfd8da7919..7d99a084e82d 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_DWARF_REGS_H_ #define _PERF_DWARF_REGS_H_ diff --git a/tools/perf/util/include/linux/linkage.h b/tools/perf/util/include/linux/linkage.h index 06387cffe125..f01d48a8d707 100644 --- a/tools/perf/util/include/linux/linkage.h +++ b/tools/perf/util/include/linux/linkage.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_LINUX_LINKAGE_H_ #define PERF_LINUX_LINKAGE_H_ diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build index 7aca5d6d7e1f..10e0814bb8d2 100644 --- a/tools/perf/util/intel-pt-decoder/Build +++ b/tools/perf/util/intel-pt-decoder/Build @@ -25,6 +25,6 @@ $(OUTPUT)util/intel-pt-decoder/intel-pt-insn-decoder.o: util/intel-pt-decoder/in CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder -ifneq ($(CC), clang) +ifeq ($(CC_NO_CLANG), 1) CFLAGS_intel-pt-insn-decoder.o += -Wno-override-init endif diff --git a/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk b/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk index 54e961659514..ddd5c4c21129 100644 --- a/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk +++ b/tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk @@ -1,4 +1,5 @@ #!/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 # gen-insn-attr-x86.awk: Instruction attribute table generator # Written by Masami Hiramatsu # diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h index 020b9ca1b47e..85bab8735fa9 100644 --- a/tools/perf/util/intlist.h +++ b/tools/perf/util/intlist.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_INTLIST_H #define __PERF_INTLIST_H diff --git a/tools/perf/util/jit.h b/tools/perf/util/jit.h index 3f42ee4d2a0b..c2582fa9fe21 100644 --- a/tools/perf/util/jit.h +++ b/tools/perf/util/jit.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __JIT_H__ #define __JIT_H__ diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index 9084930e1757..36483db032e8 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index d01e73592f6e..7b1f06567521 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_KVM_STAT_H #define __PERF_KVM_STAT_H diff --git a/tools/perf/util/levenshtein.c b/tools/perf/util/levenshtein.c index f616e4f65b67..a217ecf0359d 100644 --- a/tools/perf/util/levenshtein.c +++ b/tools/perf/util/levenshtein.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "levenshtein.h" #include #include diff --git a/tools/perf/util/levenshtein.h b/tools/perf/util/levenshtein.h index b0fcb6d8a881..34ca173c557d 100644 --- a/tools/perf/util/levenshtein.h +++ b/tools/perf/util/levenshtein.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_LEVENSHTEIN_H #define __PERF_LEVENSHTEIN_H diff --git a/tools/perf/util/libunwind/arm64.c b/tools/perf/util/libunwind/arm64.c index 6559bc586643..66756e6be111 100644 --- a/tools/perf/util/libunwind/arm64.c +++ b/tools/perf/util/libunwind/arm64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file setups defines to compile arch specific binary from the * generic one. diff --git a/tools/perf/util/libunwind/x86_32.c b/tools/perf/util/libunwind/x86_32.c index 957ffff72428..c5e568188e19 100644 --- a/tools/perf/util/libunwind/x86_32.c +++ b/tools/perf/util/libunwind/x86_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file setups defines to compile arch specific binary from the * generic one. diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index c6a15f204c03..4952b429caa7 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2015, Wang Nan * Copyright (C) 2015, Huawei Inc. @@ -33,7 +34,7 @@ struct llvm_param llvm_param = { int perf_llvm_config(const char *var, const char *value) { - if (prefixcmp(var, "llvm.")) + if (!strstarts(var, "llvm.")) return 0; var += sizeof("llvm.") - 1; diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h index c87a2a92a88f..d3ad8deb5db4 100644 --- a/tools/perf/util/llvm-utils.h +++ b/tools/perf/util/llvm-utils.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2015, Wang Nan * Copyright (C) 2015, Huawei Inc. diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c index 4ca7c5c6cdcd..07498eaddc08 100644 --- a/tools/perf/util/lzma.c +++ b/tools/perf/util/lzma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 2e9eb6aa3ce2..bd5d5b5e2218 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -705,7 +706,8 @@ size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp) if (kdso->has_build_id) { char filename[PATH_MAX]; - if (dso__build_id_filename(kdso, filename, sizeof(filename))) + if (dso__build_id_filename(kdso, filename, sizeof(filename), + false)) printed += fprintf(fp, "[0] %s\n", filename); } @@ -1137,7 +1139,8 @@ int __weak arch__fix_module_text_start(u64 *start __maybe_unused, return 0; } -static int machine__create_module(void *arg, const char *name, u64 start) +static int machine__create_module(void *arg, const char *name, u64 start, + u64 size) { struct machine *machine = arg; struct map *map; @@ -1148,6 +1151,7 @@ static int machine__create_module(void *arg, const char *name, u64 start) map = machine__findnew_module_map(machine, start, name); if (map == NULL) return -1; + map->end = start + size; dso__kernel_module_get_build_id(map->dso, machine->root_dir); @@ -1392,7 +1396,7 @@ int machine__process_mmap2_event(struct machine *machine, map = map__new(machine, event->mmap2.start, event->mmap2.len, event->mmap2.pgoff, - event->mmap2.pid, event->mmap2.maj, + event->mmap2.maj, event->mmap2.min, event->mmap2.ino, event->mmap2.ino_generation, event->mmap2.prot, @@ -1450,7 +1454,7 @@ int machine__process_mmap_event(struct machine *machine, union perf_event *event map = map__new(machine, event->mmap.start, event->mmap.len, event->mmap.pgoff, - event->mmap.pid, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, event->mmap.filename, type, thread); @@ -1632,10 +1636,12 @@ static void ip__resolve_ams(struct thread *thread, ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; + ams->phys_addr = 0; } static void ip__resolve_data(struct thread *thread, - u8 m, struct addr_map_symbol *ams, u64 addr) + u8 m, struct addr_map_symbol *ams, + u64 addr, u64 phys_addr) { struct addr_location al; @@ -1655,6 +1661,7 @@ static void ip__resolve_data(struct thread *thread, ams->al_addr = al.addr; ams->sym = al.sym; ams->map = al.map; + ams->phys_addr = phys_addr; } struct mem_info *sample__resolve_mem(struct perf_sample *sample, @@ -1666,12 +1673,18 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample, return NULL; ip__resolve_ams(al->thread, &mi->iaddr, sample->ip); - ip__resolve_data(al->thread, al->cpumode, &mi->daddr, sample->addr); + ip__resolve_data(al->thread, al->cpumode, &mi->daddr, + sample->addr, sample->phys_addr); mi->data_src.val = sample->data_src; return mi; } +struct iterations { + int nr_loop_iter; + u64 cycles; +}; + static int add_callchain_ip(struct thread *thread, struct callchain_cursor *cursor, struct symbol **parent, @@ -1680,10 +1693,12 @@ static int add_callchain_ip(struct thread *thread, u64 ip, bool branch, struct branch_flags *flags, - int nr_loop_iter, - int samples) + struct iterations *iter, + u64 branch_from) { struct addr_location al; + int nr_loop_iter = 0; + u64 iter_cycles = 0; al.filtered = 0; al.sym = NULL; @@ -1733,8 +1748,15 @@ static int add_callchain_ip(struct thread *thread, if (symbol_conf.hide_unresolved && al.sym == NULL) return 0; + + if (iter) { + nr_loop_iter = iter->nr_loop_iter; + iter_cycles = iter->cycles; + } + return callchain_cursor_append(cursor, al.addr, al.map, al.sym, - branch, flags, nr_loop_iter, samples); + branch, flags, nr_loop_iter, + iter_cycles, branch_from); } struct branch_info *sample__resolve_bstack(struct perf_sample *sample, @@ -1755,6 +1777,18 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, return bi; } +static void save_iterations(struct iterations *iter, + struct branch_entry *be, int nr) +{ + int i; + + iter->nr_loop_iter = nr; + iter->cycles = 0; + + for (i = 0; i < nr; i++) + iter->cycles += be[i].flags.cycles; +} + #define CHASHSZ 127 #define CHASHBITS 7 #define NO_ENTRY 0xff @@ -1762,7 +1796,8 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample, #define PERF_MAX_BRANCH_DEPTH 127 /* Remove loops. */ -static int remove_loops(struct branch_entry *l, int nr) +static int remove_loops(struct branch_entry *l, int nr, + struct iterations *iter) { int i, j, off; unsigned char chash[CHASHSZ]; @@ -1787,8 +1822,18 @@ static int remove_loops(struct branch_entry *l, int nr) break; } if (is_loop) { - memmove(l + i, l + i + off, - (nr - (i + off)) * sizeof(*l)); + j = nr - (i + off); + if (j > 0) { + save_iterations(iter + i + off, + l + i, off); + + memmove(iter + i, iter + i + off, + j * sizeof(*iter)); + + memmove(l + i, l + i + off, + j * sizeof(*l)); + } + nr -= off; } } @@ -1813,7 +1858,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread, struct ip_callchain *chain = sample->callchain; int chain_nr = min(max_stack, (int)chain->nr), i; u8 cpumode = PERF_RECORD_MISC_USER; - u64 ip; + u64 ip, branch_from = 0; for (i = 0; i < chain_nr; i++) { if (chain->ips[i] == PERF_CONTEXT_USER) @@ -1855,6 +1900,8 @@ static int resolve_lbr_callchain_sample(struct thread *thread, ip = lbr_stack->entries[0].to; branch = true; flags = &lbr_stack->entries[0].flags; + branch_from = + lbr_stack->entries[0].from; } } else { if (j < lbr_nr) { @@ -1869,12 +1916,15 @@ static int resolve_lbr_callchain_sample(struct thread *thread, ip = lbr_stack->entries[0].to; branch = true; flags = &lbr_stack->entries[0].flags; + branch_from = + lbr_stack->entries[0].from; } } err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, - branch, flags, 0, 0); + branch, flags, NULL, + branch_from); if (err) return (err < 0) ? err : 0; } @@ -1894,12 +1944,14 @@ static int thread__resolve_callchain_sample(struct thread *thread, { struct branch_stack *branch = sample->branch_stack; struct ip_callchain *chain = sample->callchain; - int chain_nr = chain->nr; + int chain_nr = 0; u8 cpumode = PERF_RECORD_MISC_USER; int i, j, err, nr_entries; int skip_idx = -1; int first_call = 0; - int nr_loop_iter; + + if (chain) + chain_nr = chain->nr; if (perf_evsel__has_branch_callstack(evsel)) { err = resolve_lbr_callchain_sample(thread, cursor, sample, parent, @@ -1929,6 +1981,7 @@ static int thread__resolve_callchain_sample(struct thread *thread, if (branch && callchain_param.branch_callstack) { int nr = min(max_stack, (int)branch->nr); struct branch_entry be[nr]; + struct iterations iter[nr]; if (branch->nr > PERF_MAX_BRANCH_DEPTH) { pr_warning("corrupted branch chain. skipping...\n"); @@ -1938,6 +1991,10 @@ static int thread__resolve_callchain_sample(struct thread *thread, for (i = 0; i < nr; i++) { if (callchain_param.order == ORDER_CALLEE) { be[i] = branch->entries[i]; + + if (chain == NULL) + continue; + /* * Check for overlap into the callchain. * The return address is one off compared to @@ -1955,42 +2012,30 @@ static int thread__resolve_callchain_sample(struct thread *thread, be[i] = branch->entries[branch->nr - i - 1]; } - nr_loop_iter = nr; - nr = remove_loops(be, nr); - - /* - * Get the number of iterations. - * It's only approximation, but good enough in practice. - */ - if (nr_loop_iter > nr) - nr_loop_iter = nr_loop_iter - nr + 1; - else - nr_loop_iter = 0; + memset(iter, 0, sizeof(struct iterations) * nr); + nr = remove_loops(be, nr, iter); for (i = 0; i < nr; i++) { - if (i == nr - 1) - err = add_callchain_ip(thread, cursor, parent, - root_al, - NULL, be[i].to, - true, &be[i].flags, - nr_loop_iter, 1); - else - err = add_callchain_ip(thread, cursor, parent, - root_al, - NULL, be[i].to, - true, &be[i].flags, - 0, 0); + err = add_callchain_ip(thread, cursor, parent, + root_al, + NULL, be[i].to, + true, &be[i].flags, + NULL, be[i].from); if (!err) err = add_callchain_ip(thread, cursor, parent, root_al, NULL, be[i].from, true, &be[i].flags, - 0, 0); + &iter[i], 0); if (err == -EINVAL) break; if (err) return err; } + + if (chain_nr == 0) + return 0; + chain_nr -= nr; } @@ -2015,7 +2060,7 @@ check_calls: err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip, - false, NULL, 0, 0); + false, NULL, NULL, 0); if (err) return (err < 0) ? err : 0; @@ -2032,7 +2077,7 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) return 0; return callchain_cursor_append(cursor, entry->ip, entry->map, entry->sym, - false, NULL, 0, 0); + false, NULL, 0, 0, 0); } static int thread__resolve_callchain_unwind(struct thread *thread, diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 3cdb1340f917..d551aa80a59b 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_MACHINE_H #define __PERF_MACHINE_H diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 2179b2deb730..4e7bd2750122 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "symbol.h" #include #include @@ -16,6 +17,7 @@ #include "machine.h" #include #include "srcline.h" +#include "namespaces.h" #include "unwind.h" static void __maps__insert(struct maps *maps, struct map *map); @@ -145,11 +147,13 @@ void map__init(struct map *map, enum map_type type, } struct map *map__new(struct machine *machine, u64 start, u64 len, - u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, + u64 pgoff, u32 d_maj, u32 d_min, u64 ino, u64 ino_gen, u32 prot, u32 flags, char *filename, enum map_type type, struct thread *thread) { struct map *map = malloc(sizeof(*map)); + struct nsinfo *nsi = NULL; + struct nsinfo *nnsi; if (map != NULL) { char newfilename[PATH_MAX]; @@ -167,9 +171,11 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, map->ino_generation = ino_gen; map->prot = prot; map->flags = flags; + nsi = nsinfo__get(thread->nsinfo); - if ((anon || no_dso) && type == MAP__FUNCTION) { - snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid); + if ((anon || no_dso) && nsi && type == MAP__FUNCTION) { + snprintf(newfilename, sizeof(newfilename), + "/tmp/perf-%d.map", nsi->pid); filename = newfilename; } @@ -179,6 +185,16 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, } if (vdso) { + /* The vdso maps are always on the host and not the + * container. Ensure that we don't use setns to look + * them up. + */ + nnsi = nsinfo__copy(nsi); + if (nnsi) { + nsinfo__put(nsi); + nnsi->need_setns = false; + nsi = nnsi; + } pgoff = 0; dso = machine__findnew_vdso(machine, thread); } else @@ -200,10 +216,12 @@ struct map *map__new(struct machine *machine, u64 start, u64 len, if (type != MAP__FUNCTION) dso__set_loaded(dso, map->type); } + dso->nsinfo = nsi; dso__put(dso); } return map; out_delete: + nsinfo__put(nsi); free(map); return NULL; } diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index f9e8ac8a52cd..1fb9b8589adc 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_MAP_H #define __PERF_MAP_H @@ -141,7 +142,7 @@ struct thread; void map__init(struct map *map, enum map_type type, u64 start, u64 end, u64 pgoff, struct dso *dso); struct map *map__new(struct machine *machine, u64 start, u64 len, - u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino, + u64 pgoff, u32 d_maj, u32 d_min, u64 ino, u64 ino_gen, u32 prot, u32 flags, char *filename, enum map_type type, struct thread *thread); struct map *map__new2(u64 start, struct dso *dso, enum map_type type); diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c index 06f5a3a4295c..93f74d8d3cdd 100644 --- a/tools/perf/util/mem-events.c +++ b/tools/perf/util/mem-events.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -166,11 +167,20 @@ static const char * const mem_lvl[] = { "Uncached", }; +static const char * const mem_lvlnum[] = { + [PERF_MEM_LVLNUM_ANY_CACHE] = "Any cache", + [PERF_MEM_LVLNUM_LFB] = "LFB", + [PERF_MEM_LVLNUM_RAM] = "RAM", + [PERF_MEM_LVLNUM_PMEM] = "PMEM", + [PERF_MEM_LVLNUM_NA] = "N/A", +}; + int perf_mem__lvl_scnprintf(char *out, size_t sz, struct mem_info *mem_info) { size_t i, l = 0; u64 m = PERF_MEM_LVL_NA; u64 hit, miss; + int printed; if (mem_info) m = mem_info->data_src.mem_lvl; @@ -184,17 +194,37 @@ int perf_mem__lvl_scnprintf(char *out, size_t sz, struct mem_info *mem_info) /* already taken care of */ m &= ~(PERF_MEM_LVL_HIT|PERF_MEM_LVL_MISS); + + if (mem_info && mem_info->data_src.mem_remote) { + strcat(out, "Remote "); + l += 7; + } + + printed = 0; for (i = 0; m && i < ARRAY_SIZE(mem_lvl); i++, m >>= 1) { if (!(m & 0x1)) continue; - if (l) { + if (printed++) { strcat(out, " or "); l += 4; } l += scnprintf(out + l, sz - l, mem_lvl[i]); } - if (*out == '\0') - l += scnprintf(out, sz - l, "N/A"); + + if (mem_info && mem_info->data_src.mem_lvl_num) { + int lvl = mem_info->data_src.mem_lvl_num; + if (printed++) { + strcat(out, " or "); + l += 4; + } + if (mem_lvlnum[lvl]) + l += scnprintf(out + l, sz - l, mem_lvlnum[lvl]); + else + l += scnprintf(out + l, sz - l, "L%d", lvl); + } + + if (l == 0) + l += scnprintf(out + l, sz - l, "N/A"); if (hit) l += scnprintf(out + l, sz - l, " hit"); if (miss) @@ -231,6 +261,14 @@ int perf_mem__snp_scnprintf(char *out, size_t sz, struct mem_info *mem_info) } l += scnprintf(out + l, sz - l, snoop_access[i]); } + if (mem_info && + (mem_info->data_src.mem_snoopx & PERF_MEM_SNOOPX_FWD)) { + if (l) { + strcat(out, " or "); + l += 4; + } + l += scnprintf(out + l, sz - l, "Fwd"); + } if (*out == '\0') l += scnprintf(out, sz - l, "N/A"); @@ -279,6 +317,11 @@ int c2c_decode_stats(struct c2c_stats *stats, struct mem_info *mi) u64 lvl = data_src->mem_lvl; u64 snoop = data_src->mem_snoop; u64 lock = data_src->mem_lock; + /* + * Skylake might report unknown remote level via this + * bit, consider it when evaluating remote HITMs. + */ + bool mrem = data_src->mem_remote; int err = 0; #define HITM_INC(__f) \ @@ -324,7 +367,8 @@ do { \ } if ((lvl & P(LVL, REM_RAM1)) || - (lvl & P(LVL, REM_RAM2))) { + (lvl & P(LVL, REM_RAM2)) || + mrem) { stats->rmt_dram++; if (snoop & P(SNOOP, HIT)) stats->ld_shared++; @@ -334,7 +378,8 @@ do { \ } if ((lvl & P(LVL, REM_CCE1)) || - (lvl & P(LVL, REM_CCE2))) { + (lvl & P(LVL, REM_CCE2)) || + mrem) { if (snoop & P(SNOOP, HIT)) stats->rmt_hit++; else if (snoop & P(SNOOP, HITM)) diff --git a/tools/perf/util/mem-events.h b/tools/perf/util/mem-events.h index 40f72ee4f42a..a889ec2fa9f5 100644 --- a/tools/perf/util/mem-events.h +++ b/tools/perf/util/mem-events.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_MEM_EVENTS_H #define __PERF_MEM_EVENTS_H diff --git a/tools/perf/util/memswap.c b/tools/perf/util/memswap.c index 55f7faa8d9ec..c1317e4983bc 100644 --- a/tools/perf/util/memswap.c +++ b/tools/perf/util/memswap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "memswap.h" #include diff --git a/tools/perf/util/memswap.h b/tools/perf/util/memswap.h index 7d1b1c34bb57..1e29ff903ca9 100644 --- a/tools/perf/util/memswap.h +++ b/tools/perf/util/memswap.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_MEMSWAP_H_ #define PERF_MEMSWAP_H_ diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c index 67dcbcc73c7d..a58e91197729 100644 --- a/tools/perf/util/namespaces.c +++ b/tools/perf/util/namespaces.c @@ -9,9 +9,14 @@ #include "namespaces.h" #include "util.h" #include "event.h" +#include +#include +#include +#include #include #include #include +#include struct namespaces *namespaces__new(struct namespaces_event *event) { @@ -35,3 +40,209 @@ void namespaces__free(struct namespaces *namespaces) { free(namespaces); } + +int nsinfo__init(struct nsinfo *nsi) +{ + char oldns[PATH_MAX]; + char spath[PATH_MAX]; + char *newns = NULL; + char *statln = NULL; + struct stat old_stat; + struct stat new_stat; + FILE *f = NULL; + size_t linesz = 0; + int rv = -1; + + if (snprintf(oldns, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX) + return rv; + + if (asprintf(&newns, "/proc/%d/ns/mnt", nsi->pid) == -1) + return rv; + + if (stat(oldns, &old_stat) < 0) + goto out; + + if (stat(newns, &new_stat) < 0) + goto out; + + /* Check if the mount namespaces differ, if so then indicate that we + * want to switch as part of looking up dso/map data. + */ + if (old_stat.st_ino != new_stat.st_ino) { + nsi->need_setns = true; + nsi->mntns_path = newns; + newns = NULL; + } + + /* If we're dealing with a process that is in a different PID namespace, + * attempt to work out the innermost tgid for the process. + */ + if (snprintf(spath, PATH_MAX, "/proc/%d/status", nsi->pid) >= PATH_MAX) + goto out; + + f = fopen(spath, "r"); + if (f == NULL) + goto out; + + while (getline(&statln, &linesz, f) != -1) { + /* Use tgid if CONFIG_PID_NS is not defined. */ + if (strstr(statln, "Tgid:") != NULL) { + nsi->tgid = (pid_t)strtol(strrchr(statln, '\t'), + NULL, 10); + nsi->nstgid = nsi->tgid; + } + + if (strstr(statln, "NStgid:") != NULL) { + nsi->nstgid = (pid_t)strtol(strrchr(statln, '\t'), + NULL, 10); + break; + } + } + rv = 0; + +out: + if (f != NULL) + (void) fclose(f); + free(statln); + free(newns); + return rv; +} + +struct nsinfo *nsinfo__new(pid_t pid) +{ + struct nsinfo *nsi; + + if (pid == 0) + return NULL; + + nsi = calloc(1, sizeof(*nsi)); + if (nsi != NULL) { + nsi->pid = pid; + nsi->tgid = pid; + nsi->nstgid = pid; + nsi->need_setns = false; + /* Init may fail if the process exits while we're trying to look + * at its proc information. In that case, save the pid but + * don't try to enter the namespace. + */ + if (nsinfo__init(nsi) == -1) + nsi->need_setns = false; + + refcount_set(&nsi->refcnt, 1); + } + + return nsi; +} + +struct nsinfo *nsinfo__copy(struct nsinfo *nsi) +{ + struct nsinfo *nnsi; + + nnsi = calloc(1, sizeof(*nnsi)); + if (nnsi != NULL) { + nnsi->pid = nsi->pid; + nnsi->tgid = nsi->tgid; + nnsi->nstgid = nsi->nstgid; + nnsi->need_setns = nsi->need_setns; + if (nsi->mntns_path) { + nnsi->mntns_path = strdup(nsi->mntns_path); + if (!nnsi->mntns_path) { + free(nnsi); + return NULL; + } + } + refcount_set(&nnsi->refcnt, 1); + } + + return nnsi; +} + +void nsinfo__delete(struct nsinfo *nsi) +{ + zfree(&nsi->mntns_path); + free(nsi); +} + +struct nsinfo *nsinfo__get(struct nsinfo *nsi) +{ + if (nsi) + refcount_inc(&nsi->refcnt); + return nsi; +} + +void nsinfo__put(struct nsinfo *nsi) +{ + if (nsi && refcount_dec_and_test(&nsi->refcnt)) + nsinfo__delete(nsi); +} + +void nsinfo__mountns_enter(struct nsinfo *nsi, + struct nscookie *nc) +{ + char curpath[PATH_MAX]; + int oldns = -1; + int newns = -1; + + if (nc == NULL) + return; + + nc->oldns = -1; + nc->newns = -1; + + if (!nsi || !nsi->need_setns) + return; + + if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX) + return; + + oldns = open(curpath, O_RDONLY); + if (oldns < 0) + return; + + newns = open(nsi->mntns_path, O_RDONLY); + if (newns < 0) + goto errout; + + if (setns(newns, CLONE_NEWNS) < 0) + goto errout; + + nc->oldns = oldns; + nc->newns = newns; + return; + +errout: + if (oldns > -1) + close(oldns); + if (newns > -1) + close(newns); +} + +void nsinfo__mountns_exit(struct nscookie *nc) +{ + if (nc == NULL || nc->oldns == -1 || nc->newns == -1) + return; + + setns(nc->oldns, CLONE_NEWNS); + + if (nc->oldns > -1) { + close(nc->oldns); + nc->oldns = -1; + } + + if (nc->newns > -1) { + close(nc->newns); + nc->newns = -1; + } +} + +char *nsinfo__realpath(const char *path, struct nsinfo *nsi) +{ + char *rpath; + struct nscookie nsc; + + nsinfo__mountns_enter(nsi, &nsc); + rpath = realpath(path, NULL); + nsinfo__mountns_exit(&nsc); + + return rpath; +} diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h index 468f1e9a1484..05d82601c9a6 100644 --- a/tools/perf/util/namespaces.h +++ b/tools/perf/util/namespaces.h @@ -11,6 +11,7 @@ #include "../perf.h" #include +#include struct namespaces_event; @@ -23,4 +24,41 @@ struct namespaces { struct namespaces *namespaces__new(struct namespaces_event *event); void namespaces__free(struct namespaces *namespaces); +struct nsinfo { + pid_t pid; + pid_t tgid; + pid_t nstgid; + bool need_setns; + char *mntns_path; + refcount_t refcnt; +}; + +struct nscookie { + int oldns; + int newns; +}; + +int nsinfo__init(struct nsinfo *nsi); +struct nsinfo *nsinfo__new(pid_t pid); +struct nsinfo *nsinfo__copy(struct nsinfo *nsi); +void nsinfo__delete(struct nsinfo *nsi); + +struct nsinfo *nsinfo__get(struct nsinfo *nsi); +void nsinfo__put(struct nsinfo *nsi); + +void nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc); +void nsinfo__mountns_exit(struct nscookie *nc); + +char *nsinfo__realpath(const char *path, struct nsinfo *nsi); + +static inline void __nsinfo__zput(struct nsinfo **nsip) +{ + if (nsip) { + nsinfo__put(*nsip); + *nsip = NULL; + } +} + +#define nsinfo__zput(nsi) __nsinfo__zput(&nsi) + #endif /* __PERF_NAMESPACES_H */ diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index 4de398cfb577..8e09fd2d842f 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h index e11468a9a6e4..96e5292d88e2 100644 --- a/tools/perf/util/ordered-events.h +++ b/tools/perf/util/ordered-events.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __ORDERED_EVENTS_H #define __ORDERED_EVENTS_H diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c index 38fd11504015..bd779d9f4d1e 100644 --- a/tools/perf/util/parse-branch-options.c +++ b/tools/perf/util/parse-branch-options.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "perf.h" #include "util/util.h" #include "util/debug.h" @@ -28,6 +29,7 @@ static const struct branch_mode branch_modes[] = { BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND), BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP), BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL), + BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE), BRANCH_END }; diff --git a/tools/perf/util/parse-branch-options.h b/tools/perf/util/parse-branch-options.h index 6086fd90eb23..11d1722733f2 100644 --- a/tools/perf/util/parse-branch-options.h +++ b/tools/perf/util/parse-branch-options.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_PARSE_BRANCH_OPTIONS_H #define _PERF_PARSE_BRANCH_OPTIONS_H 1 #include diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 01e779b91c8e..56694e3409ea 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -34,7 +35,7 @@ #ifdef PARSER_DEBUG extern int parse_events_debug; #endif -int parse_events_parse(void *data, void *scanner); +int parse_events_parse(void *parse_state, void *scanner); static int get_config_terms(struct list_head *head_config, struct list_head *head_terms __maybe_unused); @@ -309,10 +310,11 @@ static char *get_config_name(struct list_head *head_terms) static struct perf_evsel * __add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, - char *name, struct cpu_map *cpus, - struct list_head *config_terms) + char *name, struct perf_pmu *pmu, + struct list_head *config_terms, bool auto_merge_stats) { struct perf_evsel *evsel; + struct cpu_map *cpus = pmu ? pmu->cpus : NULL; event_attr_init(attr); @@ -323,7 +325,8 @@ __add_event(struct list_head *list, int *idx, (*idx)++; evsel->cpus = cpu_map__get(cpus); evsel->own_cpus = cpu_map__get(cpus); - evsel->system_wide = !!cpus; + evsel->system_wide = pmu ? pmu->is_uncore : false; + evsel->auto_merge_stats = auto_merge_stats; if (name) evsel->name = strdup(name); @@ -339,7 +342,7 @@ static int add_event(struct list_head *list, int *idx, struct perf_event_attr *attr, char *name, struct list_head *config_terms) { - return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM; + return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM; } static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) @@ -589,7 +592,7 @@ static int add_tracepoint_multi_sys(struct list_head *list, int *idx, } struct __add_bpf_event_param { - struct parse_events_evlist *data; + struct parse_events_state *parse_state; struct list_head *list; struct list_head *head_config; }; @@ -599,7 +602,7 @@ static int add_bpf_event(const char *group, const char *event, int fd, { LIST_HEAD(new_evsels); struct __add_bpf_event_param *param = _param; - struct parse_events_evlist *evlist = param->data; + struct parse_events_state *parse_state = param->parse_state; struct list_head *list = param->list; struct perf_evsel *pos; int err; @@ -607,8 +610,8 @@ static int add_bpf_event(const char *group, const char *event, int fd, pr_debug("add bpf event %s:%s and attach bpf program %d\n", group, event, fd); - err = parse_events_add_tracepoint(&new_evsels, &evlist->idx, group, - event, evlist->error, + err = parse_events_add_tracepoint(&new_evsels, &parse_state->idx, group, + event, parse_state->error, param->head_config); if (err) { struct perf_evsel *evsel, *tmp; @@ -632,14 +635,14 @@ static int add_bpf_event(const char *group, const char *event, int fd, return 0; } -int parse_events_load_bpf_obj(struct parse_events_evlist *data, +int parse_events_load_bpf_obj(struct parse_events_state *parse_state, struct list_head *list, struct bpf_object *obj, struct list_head *head_config) { int err; char errbuf[BUFSIZ]; - struct __add_bpf_event_param param = {data, list, head_config}; + struct __add_bpf_event_param param = {parse_state, list, head_config}; static bool registered_unprobe_atexit = false; if (IS_ERR(obj) || !obj) { @@ -680,13 +683,13 @@ int parse_events_load_bpf_obj(struct parse_events_evlist *data, return 0; errout: - data->error->help = strdup("(add -v to see detail)"); - data->error->str = strdup(errbuf); + parse_state->error->help = strdup("(add -v to see detail)"); + parse_state->error->str = strdup(errbuf); return err; } static int -parse_events_config_bpf(struct parse_events_evlist *data, +parse_events_config_bpf(struct parse_events_state *parse_state, struct bpf_object *obj, struct list_head *head_config) { @@ -705,28 +708,28 @@ parse_events_config_bpf(struct parse_events_evlist *data, "Invalid config term for BPF object"); errbuf[BUFSIZ - 1] = '\0'; - data->error->idx = term->err_term; - data->error->str = strdup(errbuf); + parse_state->error->idx = term->err_term; + parse_state->error->str = strdup(errbuf); return -EINVAL; } - err = bpf__config_obj(obj, term, data->evlist, &error_pos); + err = bpf__config_obj(obj, term, parse_state->evlist, &error_pos); if (err) { - bpf__strerror_config_obj(obj, term, data->evlist, + bpf__strerror_config_obj(obj, term, parse_state->evlist, &error_pos, err, errbuf, sizeof(errbuf)); - data->error->help = strdup( + parse_state->error->help = strdup( "Hint:\tValid config terms:\n" " \tmap:[].value=[value]\n" " \tmap:[].event=[event]\n" "\n" " \twhere is something like [0,3...5] or [all]\n" " \t(add -v to see detail)"); - data->error->str = strdup(errbuf); + parse_state->error->str = strdup(errbuf); if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE) - data->error->idx = term->err_val; + parse_state->error->idx = term->err_val; else - data->error->idx = term->err_term + error_pos; + parse_state->error->idx = term->err_term + error_pos; return err; } } @@ -762,7 +765,7 @@ split_bpf_config_terms(struct list_head *evt_head_config, list_move_tail(&term->list, obj_head_config); } -int parse_events_load_bpf(struct parse_events_evlist *data, +int parse_events_load_bpf(struct parse_events_state *parse_state, struct list_head *list, char *bpf_file_name, bool source, @@ -790,15 +793,15 @@ int parse_events_load_bpf(struct parse_events_evlist *data, -err, errbuf, sizeof(errbuf)); - data->error->help = strdup("(add -v to see detail)"); - data->error->str = strdup(errbuf); + parse_state->error->help = strdup("(add -v to see detail)"); + parse_state->error->str = strdup(errbuf); return err; } - err = parse_events_load_bpf_obj(data, list, obj, head_config); + err = parse_events_load_bpf_obj(parse_state, list, obj, head_config); if (err) return err; - err = parse_events_config_bpf(data, obj, &obj_head_config); + err = parse_events_config_bpf(parse_state, obj, &obj_head_config); /* * Caller doesn't know anything about obj_head_config, @@ -1184,7 +1187,7 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx, err, head_config); } -int parse_events_add_numeric(struct parse_events_evlist *data, +int parse_events_add_numeric(struct parse_events_state *parse_state, struct list_head *list, u32 type, u64 config, struct list_head *head_config) @@ -1197,7 +1200,7 @@ int parse_events_add_numeric(struct parse_events_evlist *data, attr.config = config; if (head_config) { - if (config_attr(&attr, head_config, data->error, + if (config_attr(&attr, head_config, parse_state->error, config_term_common)) return -EINVAL; @@ -1205,13 +1208,13 @@ int parse_events_add_numeric(struct parse_events_evlist *data, return -ENOMEM; } - return add_event(list, &data->idx, &attr, + return add_event(list, &parse_state->idx, &attr, get_config_name(head_config), &config_terms); } -int parse_events_add_pmu(struct parse_events_evlist *data, +static int __parse_events_add_pmu(struct parse_events_state *parse_state, struct list_head *list, char *name, - struct list_head *head_config) + struct list_head *head_config, bool auto_merge_stats) { struct perf_event_attr attr; struct perf_pmu_info info; @@ -1232,7 +1235,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data, if (!head_config) { attr.type = pmu->type; - evsel = __add_event(list, &data->idx, &attr, NULL, pmu->cpus, NULL); + evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats); return evsel ? 0 : -ENOMEM; } @@ -1243,18 +1246,18 @@ int parse_events_add_pmu(struct parse_events_evlist *data, * Configure hardcoded terms first, no need to check * return value when called with fail == 0 ;) */ - if (config_attr(&attr, head_config, data->error, config_term_pmu)) + if (config_attr(&attr, head_config, parse_state->error, config_term_pmu)) return -EINVAL; if (get_config_terms(head_config, &config_terms)) return -ENOMEM; - if (perf_pmu__config(pmu, &attr, head_config, data->error)) + if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) return -EINVAL; - evsel = __add_event(list, &data->idx, &attr, - get_config_name(head_config), pmu->cpus, - &config_terms); + evsel = __add_event(list, &parse_state->idx, &attr, + get_config_name(head_config), pmu, + &config_terms, auto_merge_stats); if (evsel) { evsel->unit = info.unit; evsel->scale = info.scale; @@ -1267,7 +1270,14 @@ int parse_events_add_pmu(struct parse_events_evlist *data, return evsel ? 0 : -ENOMEM; } -int parse_events_multi_pmu_add(struct parse_events_evlist *data, +int parse_events_add_pmu(struct parse_events_state *parse_state, + struct list_head *list, char *name, + struct list_head *head_config) +{ + return __parse_events_add_pmu(parse_state, list, name, head_config, false); +} + +int parse_events_multi_pmu_add(struct parse_events_state *parse_state, char *str, struct list_head **listp) { struct list_head *head; @@ -1296,8 +1306,8 @@ int parse_events_multi_pmu_add(struct parse_events_evlist *data, return -1; list_add_tail(&term->list, head); - if (!parse_events_add_pmu(data, list, - pmu->name, head)) { + if (!__parse_events_add_pmu(parse_state, list, + pmu->name, head, true)) { pr_debug("%s -> %s/%s/\n", str, pmu->name, alias->str); ok++; @@ -1628,7 +1638,7 @@ perf_pmu__parse_check(const char *name) return r ? r->type : PMU_EVENT_SYMBOL_ERR; } -static int parse_events__scanner(const char *str, void *data, int start_token) +static int parse_events__scanner(const char *str, void *parse_state, int start_token) { YY_BUFFER_STATE buffer; void *scanner; @@ -1643,7 +1653,7 @@ static int parse_events__scanner(const char *str, void *data, int start_token) #ifdef PARSER_DEBUG parse_events_debug = 1; #endif - ret = parse_events_parse(data, scanner); + ret = parse_events_parse(parse_state, scanner); parse_events__flush_buffer(buffer, scanner); parse_events__delete_buffer(buffer, scanner); @@ -1656,45 +1666,45 @@ static int parse_events__scanner(const char *str, void *data, int start_token) */ int parse_events_terms(struct list_head *terms, const char *str) { - struct parse_events_terms data = { + struct parse_events_state parse_state = { .terms = NULL, }; int ret; - ret = parse_events__scanner(str, &data, PE_START_TERMS); + ret = parse_events__scanner(str, &parse_state, PE_START_TERMS); if (!ret) { - list_splice(data.terms, terms); - zfree(&data.terms); + list_splice(parse_state.terms, terms); + zfree(&parse_state.terms); return 0; } - parse_events_terms__delete(data.terms); + parse_events_terms__delete(parse_state.terms); return ret; } int parse_events(struct perf_evlist *evlist, const char *str, struct parse_events_error *err) { - struct parse_events_evlist data = { - .list = LIST_HEAD_INIT(data.list), + struct parse_events_state parse_state = { + .list = LIST_HEAD_INIT(parse_state.list), .idx = evlist->nr_entries, .error = err, .evlist = evlist, }; int ret; - ret = parse_events__scanner(str, &data, PE_START_EVENTS); + ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS); perf_pmu__parse_cleanup(); if (!ret) { struct perf_evsel *last; - if (list_empty(&data.list)) { + if (list_empty(&parse_state.list)) { WARN_ONCE(true, "WARNING: event parser found nothing"); return -1; } - perf_evlist__splice_list_tail(evlist, &data.list); - evlist->nr_groups += data.nr_groups; + perf_evlist__splice_list_tail(evlist, &parse_state.list); + evlist->nr_groups += parse_state.nr_groups; last = perf_evlist__last(evlist); last->cmdline_group_boundary = true; @@ -2124,7 +2134,7 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, return; } strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s); + pcache = probe_cache__new(nd->s, NULL); if (!pcache) continue; list_for_each_entry(ent, &pcache->entries, node) { @@ -2520,10 +2530,10 @@ void parse_events__clear_array(struct parse_events_array *a) zfree(&a->ranges); } -void parse_events_evlist_error(struct parse_events_evlist *data, +void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str) { - struct parse_events_error *err = data->error; + struct parse_events_error *err = parse_state->error; if (!err) return; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index a235f4d6d5e5..eed50b54bab3 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_PARSE_EVENTS_H #define __PERF_PARSE_EVENTS_H /* @@ -108,16 +109,13 @@ struct parse_events_error { char *help; /* optional help string */ }; -struct parse_events_evlist { +struct parse_events_state { struct list_head list; int idx; int nr_groups; struct parse_events_error *error; struct perf_evlist *evlist; -}; - -struct parse_events_terms { - struct list_head *terms; + struct list_head *terms; }; void parse_events__shrink_config_terms(void); @@ -143,18 +141,18 @@ int parse_events_add_tracepoint(struct list_head *list, int *idx, const char *sys, const char *event, struct parse_events_error *error, struct list_head *head_config); -int parse_events_load_bpf(struct parse_events_evlist *data, +int parse_events_load_bpf(struct parse_events_state *parse_state, struct list_head *list, char *bpf_file_name, bool source, struct list_head *head_config); /* Provide this function for perf test */ struct bpf_object; -int parse_events_load_bpf_obj(struct parse_events_evlist *data, +int parse_events_load_bpf_obj(struct parse_events_state *parse_state, struct list_head *list, struct bpf_object *obj, struct list_head *head_config); -int parse_events_add_numeric(struct parse_events_evlist *data, +int parse_events_add_numeric(struct parse_events_state *parse_state, struct list_head *list, u32 type, u64 config, struct list_head *head_config); @@ -164,11 +162,11 @@ int parse_events_add_cache(struct list_head *list, int *idx, struct list_head *head_config); int parse_events_add_breakpoint(struct list_head *list, int *idx, void *ptr, char *type, u64 len); -int parse_events_add_pmu(struct parse_events_evlist *data, +int parse_events_add_pmu(struct parse_events_state *parse_state, struct list_head *list, char *name, struct list_head *head_config); -int parse_events_multi_pmu_add(struct parse_events_evlist *data, +int parse_events_multi_pmu_add(struct parse_events_state *parse_state, char *str, struct list_head **listp); @@ -180,7 +178,7 @@ perf_pmu__parse_check(const char *name); void parse_events__set_leader(char *name, struct list_head *list); void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all); -void parse_events_evlist_error(struct parse_events_evlist *data, +void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str); void print_events(const char *event_glob, bool name_only, bool quiet, diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 660fca05bc93..025729510525 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -5,9 +5,13 @@ %option stack %option bison-locations %option yylineno +%option reject %{ #include +#include +#include +#include #include "../perf.h" #include "parse-events.h" #include "parse-events-bison.h" @@ -53,6 +57,31 @@ static int str(yyscan_t scanner, int token) return token; } +static bool isbpf_suffix(char *text) +{ + int len = strlen(text); + + if (len < 2) + return false; + if ((text[len - 1] == 'c' || text[len - 1] == 'o') && + text[len - 2] == '.') + return true; + if (len > 4 && !strcmp(text + len - 4, ".obj")) + return true; + return false; +} + +static bool isbpf(yyscan_t scanner) +{ + char *text = parse_events_get_text(scanner); + struct stat st; + + if (!isbpf_suffix(text)) + return false; + + return stat(text, &st) == 0; +} + /* * This function is called when the parser gets two kind of input: * @@ -126,6 +155,10 @@ do { \ yycolumn += yyleng; \ } while (0); +#define USER_REJECT \ + yycolumn -= yyleng; \ + REJECT + %} %x mem @@ -136,8 +169,8 @@ do { \ group [^,{}/]*[{][^}]*[}][^,{}/]* event_pmu [^,{}/]+[/][^/]*[/][^,{}/]* event [^,{}/]+ -bpf_object [^,{}]+\.(o|bpf) -bpf_source [^,{}]+\.c +bpf_object [^,{}]+\.(o|bpf)[a-zA-Z0-9._]* +bpf_source [^,{}]+\.c[a-zA-Z0-9._]* num_dec [0-9]+ num_hex 0x[a-fA-F0-9]+ @@ -307,8 +340,8 @@ r{num_raw_hex} { return raw(yyscanner); } {num_hex} { return value(yyscanner, 16); } {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } -{bpf_object} { return str(yyscanner, PE_BPF_OBJECT); } -{bpf_source} { return str(yyscanner, PE_BPF_SOURCE); } +{bpf_object} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_OBJECT); } +{bpf_source} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_SOURCE); } {name} { return pmu_str_check(yyscanner); } "/" { BEGIN(config); return '/'; } - { return '-'; } diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 04fd8c9af9f9..e81a20ea8d7d 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -1,5 +1,5 @@ %pure-parser -%parse-param {void *_data} +%parse-param {void *_parse_state} %parse-param {void *scanner} %lex-param {void* scanner} %locations @@ -17,7 +17,7 @@ #include "parse-events.h" #include "parse-events-bison.h" -void parse_events_error(YYLTYPE *loc, void *data, void *scanner, char const *msg); +void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg); #define ABORT_ON(val) \ do { \ @@ -33,11 +33,11 @@ do { \ } while (0) static void inc_group_count(struct list_head *list, - struct parse_events_evlist *data) + struct parse_events_state *parse_state) { /* Count groups only have more than 1 members */ if (!list_is_last(list->next, list)) - data->nr_groups++; + parse_state->nr_groups++; } %} @@ -115,9 +115,9 @@ PE_START_TERMS start_terms start_events: groups { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; - parse_events_update_lists($1, &data->list); + parse_events_update_lists($1, &parse_state->list); } groups: @@ -159,7 +159,7 @@ PE_NAME '{' events '}' { struct list_head *list = $3; - inc_group_count(list, _data); + inc_group_count(list, _parse_state); parse_events__set_leader($1, list); $$ = list; } @@ -168,7 +168,7 @@ PE_NAME '{' events '}' { struct list_head *list = $2; - inc_group_count(list, _data); + inc_group_count(list, _parse_state); parse_events__set_leader(NULL, list); $$ = list; } @@ -225,14 +225,13 @@ event_def: event_pmu | event_pmu: PE_NAME opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list, *orig_terms, *terms; if (parse_events_copy_term_list($2, &orig_terms)) YYABORT; ALLOC_LIST(list); - if (parse_events_add_pmu(data, list, $1, $2)) { + if (parse_events_add_pmu(_parse_state, list, $1, $2)) { struct perf_pmu *pmu = NULL; int ok = 0; @@ -245,7 +244,7 @@ PE_NAME opt_event_config if (!strncmp($1, name, strlen($1))) { if (parse_events_copy_term_list(orig_terms, &terms)) YYABORT; - if (!parse_events_add_pmu(data, list, pmu->name, terms)) + if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms)) ok++; parse_events_terms__delete(terms); } @@ -262,7 +261,7 @@ PE_KERNEL_PMU_EVENT sep_dc { struct list_head *list; - if (parse_events_multi_pmu_add(_data, $1, &list) < 0) + if (parse_events_multi_pmu_add(_parse_state, $1, &list) < 0) YYABORT; $$ = list; } @@ -273,7 +272,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc char pmu_name[128]; snprintf(&pmu_name, 128, "%s-%s", $1, $3); - if (parse_events_multi_pmu_add(_data, pmu_name, &list) < 0) + if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0) YYABORT; $$ = list; } @@ -286,62 +285,60 @@ PE_VALUE_SYM_SW event_legacy_symbol: value_sym '/' event_config '/' { - struct parse_events_evlist *data = _data; struct list_head *list; int type = $1 >> 16; int config = $1 & 255; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, type, config, $3)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3)); parse_events_terms__delete($3); $$ = list; } | value_sym sep_slash_dc { - struct parse_events_evlist *data = _data; struct list_head *list; int type = $1 >> 16; int config = $1 & 255; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, type, config, NULL)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); $$ = list; } event_legacy_cache: PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5, error, $6)); + ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6)); parse_events_terms__delete($6); $$ = list; } | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL, error, $4)); + ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4)); parse_events_terms__delete($4); $$ = list; } | PE_NAME_CACHE_TYPE opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL, error, $2)); + ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2)); parse_events_terms__delete($2); $$ = list; } @@ -349,44 +346,44 @@ PE_NAME_CACHE_TYPE opt_event_config event_legacy_mem: PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, $6, $4)); $$ = list; } | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, NULL, $4)); $$ = list; } | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, $4, 0)); $$ = list; } | PE_PREFIX_MEM PE_VALUE sep_dc { - struct parse_events_evlist *data = _data; + struct parse_events_state *parse_state = _parse_state; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_breakpoint(list, &data->idx, + ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, NULL, 0)); $$ = list; } @@ -394,15 +391,15 @@ PE_PREFIX_MEM PE_VALUE sep_dc event_legacy_tracepoint: tracepoint_name opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); if (error) error->idx = @1.first_column; - if (parse_events_add_tracepoint(list, &data->idx, $1.sys, $1.event, + if (parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, error, $2)) return -1; @@ -432,11 +429,10 @@ PE_NAME ':' PE_NAME event_legacy_numeric: PE_VALUE ':' PE_VALUE opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, (u32)$1, $3, $4)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4)); parse_events_terms__delete($4); $$ = list; } @@ -444,11 +440,10 @@ PE_VALUE ':' PE_VALUE opt_event_config event_legacy_raw: PE_RAW opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_add_numeric(data, list, PERF_TYPE_RAW, $1, $2)); + ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2)); parse_events_terms__delete($2); $$ = list; } @@ -456,23 +451,22 @@ PE_RAW opt_event_config event_bpf_file: PE_BPF_OBJECT opt_event_config { - struct parse_events_evlist *data = _data; - struct parse_events_error *error = data->error; + struct parse_events_state *parse_state = _parse_state; + struct parse_events_error *error = parse_state->error; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_load_bpf(data, list, $1, false, $2)); + ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2)); parse_events_terms__delete($2); $$ = list; } | PE_BPF_SOURCE opt_event_config { - struct parse_events_evlist *data = _data; struct list_head *list; ALLOC_LIST(list); - ABORT_ON(parse_events_load_bpf(data, list, $1, true, $2)); + ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2)); parse_events_terms__delete($2); $$ = list; } @@ -494,8 +488,8 @@ opt_event_config: start_terms: event_config { - struct parse_events_terms *data = _data; - data->terms = $1; + struct parse_events_state *parse_state = _parse_state; + parse_state->terms = $1; } event_config: @@ -685,9 +679,9 @@ sep_slash_dc: '/' | ':' | %% -void parse_events_error(YYLTYPE *loc, void *data, +void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner __maybe_unused, char const *msg __maybe_unused) { - parse_events_evlist_error(data, loc->last_column, "parser error"); + parse_events_evlist_error(parse_state, loc->last_column, "parser error"); } diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c index 646ecf736aad..e6599e290f46 100644 --- a/tools/perf/util/parse-regs-options.c +++ b/tools/perf/util/parse-regs-options.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "perf.h" #include "util/util.h" #include "util/debug.h" diff --git a/tools/perf/util/parse-regs-options.h b/tools/perf/util/parse-regs-options.h index 7d762b188007..cdefb1acf6be 100644 --- a/tools/perf/util/parse-regs-options.h +++ b/tools/perf/util/parse-regs-options.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_PARSE_REGS_OPTIONS_H #define _PERF_PARSE_REGS_OPTIONS_H 1 struct option; diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c index 50ec3bc87a60..933f5c6bffb4 100644 --- a/tools/perf/util/path.c +++ b/tools/perf/util/path.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * I'm tired of doing "vsnprintf()" etc just to open a * file, so here's a "return static buffer with printf" diff --git a/tools/perf/util/path.h b/tools/perf/util/path.h index 9a276a58e3c2..14a254ada7eb 100644 --- a/tools/perf/util/path.h +++ b/tools/perf/util/path.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_PATH_H #define _PERF_PATH_H diff --git a/tools/perf/util/perf-hooks.c b/tools/perf/util/perf-hooks.c index d55092964da2..4f3aa8d99ef4 100644 --- a/tools/perf/util/perf-hooks.c +++ b/tools/perf/util/perf-hooks.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * perf_hooks.c * diff --git a/tools/perf/util/perf-hooks.h b/tools/perf/util/perf-hooks.h index 838d5797bc1e..27fbec62d4fe 100644 --- a/tools/perf/util/perf-hooks.h +++ b/tools/perf/util/perf-hooks.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_UTIL_PERF_HOOKS_H #define PERF_UTIL_PERF_HOOKS_H diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index b2ae039eff85..2acfcc527cac 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "perf_regs.h" #include "event.h" diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 32b37d19dcc3..c9319f8d17a6 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_REGS_H #define __PERF_REGS_H diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index ac16a9db1fb5..b10b35a63138 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -470,31 +471,10 @@ static void pmu_read_sysfs(void) closedir(dir); } -static struct cpu_map *pmu_cpumask(const char *name) +static struct cpu_map *__pmu_cpumask(const char *path) { - struct stat st; - char path[PATH_MAX]; FILE *file; struct cpu_map *cpus; - const char *sysfs = sysfs__mountpoint(); - const char *templates[] = { - "%s/bus/event_source/devices/%s/cpumask", - "%s/bus/event_source/devices/%s/cpus", - NULL - }; - const char **template; - - if (!sysfs) - return NULL; - - for (template = templates; *template; template++) { - snprintf(path, PATH_MAX, *template, sysfs, name); - if (stat(path, &st) == 0) - break; - } - - if (!*template) - return NULL; file = fopen(path, "r"); if (!file) @@ -505,6 +485,51 @@ static struct cpu_map *pmu_cpumask(const char *name) return cpus; } +/* + * Uncore PMUs have a "cpumask" file under sysfs. CPU PMUs (e.g. on arm/arm64) + * may have a "cpus" file. + */ +#define CPUS_TEMPLATE_UNCORE "%s/bus/event_source/devices/%s/cpumask" +#define CPUS_TEMPLATE_CPU "%s/bus/event_source/devices/%s/cpus" + +static struct cpu_map *pmu_cpumask(const char *name) +{ + char path[PATH_MAX]; + struct cpu_map *cpus; + const char *sysfs = sysfs__mountpoint(); + const char *templates[] = { + CPUS_TEMPLATE_UNCORE, + CPUS_TEMPLATE_CPU, + NULL + }; + const char **template; + + if (!sysfs) + return NULL; + + for (template = templates; *template; template++) { + snprintf(path, PATH_MAX, *template, sysfs, name); + cpus = __pmu_cpumask(path); + if (cpus) + return cpus; + } + + return NULL; +} + +static bool pmu_is_uncore(const char *name) +{ + char path[PATH_MAX]; + struct cpu_map *cpus; + const char *sysfs = sysfs__mountpoint(); + + snprintf(path, PATH_MAX, CPUS_TEMPLATE_UNCORE, sysfs, name); + cpus = __pmu_cpumask(path); + cpu_map__put(cpus); + + return !!cpus; +} + /* * Return the CPU id as a raw string. * @@ -617,6 +642,8 @@ static struct perf_pmu *pmu_lookup(const char *name) pmu->cpus = pmu_cpumask(name); + pmu->is_uncore = pmu_is_uncore(name); + INIT_LIST_HEAD(&pmu->format); INIT_LIST_HEAD(&pmu->aliases); list_splice(&format, &pmu->format); diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 389e9729331f..eca99435f4a0 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PMU_H #define __PMU_H @@ -22,6 +23,7 @@ struct perf_pmu { char *name; __u32 type; bool selectable; + bool is_uncore; struct perf_event_attr *default_config; struct cpu_map *cpus; struct list_head format; /* HEAD struct perf_pmu_format -> list */ diff --git a/tools/perf/util/print_binary.c b/tools/perf/util/print_binary.c index e908177b9976..779e35c9e566 100644 --- a/tools/perf/util/print_binary.c +++ b/tools/perf/util/print_binary.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "print_binary.h" #include #include "sane_ctype.h" diff --git a/tools/perf/util/print_binary.h b/tools/perf/util/print_binary.h index da0427263d2d..2be3075e2b05 100644 --- a/tools/perf/util/print_binary.h +++ b/tools/perf/util/print_binary.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_PRINT_BINARY_H #define PERF_PRINT_BINARY_H diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a2670e9d652d..b7aaf9b2294d 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -184,13 +184,19 @@ static struct map *kernel_get_module_map(const char *module) return NULL; } -struct map *get_target_map(const char *target, bool user) +struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user) { /* Init maps of given executable or kernel */ - if (user) - return dso__new_map(target); - else + if (user) { + struct map *map; + + map = dso__new_map(target); + if (map && map->dso) + map->dso->nsinfo = nsinfo__get(nsi); + return map; + } else { return kernel_get_module_map(target); + } } static int convert_exec_to_group(const char *exec, char **result) @@ -366,7 +372,8 @@ found: static int find_alternative_probe_point(struct debuginfo *dinfo, struct perf_probe_point *pp, struct perf_probe_point *result, - const char *target, bool uprobes) + const char *target, struct nsinfo *nsi, + bool uprobes) { struct map *map = NULL; struct symbol *sym; @@ -377,7 +384,7 @@ static int find_alternative_probe_point(struct debuginfo *dinfo, if (!pp->function || pp->file) return -ENOTSUP; - map = get_target_map(target, uprobes); + map = get_target_map(target, nsi, uprobes); if (!map) return -EINVAL; @@ -421,8 +428,8 @@ static int get_alternative_probe_event(struct debuginfo *dinfo, memcpy(tmp, &pev->point, sizeof(*tmp)); memset(&pev->point, 0, sizeof(pev->point)); - ret = find_alternative_probe_point(dinfo, tmp, &pev->point, - pev->target, pev->uprobes); + ret = find_alternative_probe_point(dinfo, tmp, &pev->point, pev->target, + pev->nsi, pev->uprobes); if (ret < 0) memcpy(&pev->point, tmp, sizeof(*tmp)); @@ -444,7 +451,7 @@ static int get_alternative_line_range(struct debuginfo *dinfo, if (lr->end != INT_MAX) len = lr->end - lr->start; ret = find_alternative_probe_point(dinfo, &pp, &result, - target, user); + target, NULL, user); if (!ret) { lr->function = result.function; lr->file = result.file; @@ -457,12 +464,14 @@ static int get_alternative_line_range(struct debuginfo *dinfo, } /* Open new debuginfo of given module */ -static struct debuginfo *open_debuginfo(const char *module, bool silent) +static struct debuginfo *open_debuginfo(const char *module, struct nsinfo *nsi, + bool silent) { const char *path = module; char reason[STRERR_BUFSIZE]; struct debuginfo *ret = NULL; struct dso *dso = NULL; + struct nscookie nsc; int err; if (!module || !strchr(module, '/')) { @@ -480,6 +489,7 @@ static struct debuginfo *open_debuginfo(const char *module, bool silent) } path = dso->long_name; } + nsinfo__mountns_enter(nsi, &nsc); ret = debuginfo__new(path); if (!ret && !silent) { pr_warning("The %s file has no debug information.\n", path); @@ -489,6 +499,7 @@ static struct debuginfo *open_debuginfo(const char *module, bool silent) pr_warning("Rebuild with -g, "); pr_warning("or install an appropriate debuginfo package.\n"); } + nsinfo__mountns_exit(&nsc); return ret; } @@ -516,7 +527,7 @@ static struct debuginfo *debuginfo_cache__open(const char *module, bool silent) goto out; } - debuginfo_cache = open_debuginfo(module, silent); + debuginfo_cache = open_debuginfo(module, NULL, silent); if (!debuginfo_cache) zfree(&debuginfo_cache_path); out: @@ -531,14 +542,18 @@ static void debuginfo_cache__exit(void) } -static int get_text_start_address(const char *exec, unsigned long *address) +static int get_text_start_address(const char *exec, unsigned long *address, + struct nsinfo *nsi) { Elf *elf; GElf_Ehdr ehdr; GElf_Shdr shdr; int fd, ret = -ENOENT; + struct nscookie nsc; + nsinfo__mountns_enter(nsi, &nsc); fd = open(exec, O_RDONLY); + nsinfo__mountns_exit(&nsc); if (fd < 0) return -errno; @@ -582,7 +597,7 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp, ret = -EINVAL; goto error; } - ret = get_text_start_address(tp->module, &stext); + ret = get_text_start_address(tp->module, &stext, NULL); if (ret < 0) goto error; addr += stext; @@ -659,7 +674,7 @@ post_process_offline_probe_trace_events(struct probe_trace_event *tevs, /* Prepare a map for offline binary */ map = dso__new_map(pathname); - if (!map || get_text_start_address(pathname, &stext) < 0) { + if (!map || get_text_start_address(pathname, &stext, NULL) < 0) { pr_warning("Failed to get ELF symbols for %s\n", pathname); return -EINVAL; } @@ -676,7 +691,8 @@ post_process_offline_probe_trace_events(struct probe_trace_event *tevs, } static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, - int ntevs, const char *exec) + int ntevs, const char *exec, + struct nsinfo *nsi) { int i, ret = 0; unsigned long stext = 0; @@ -684,7 +700,7 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs, if (!exec) return 0; - ret = get_text_start_address(exec, &stext); + ret = get_text_start_address(exec, &stext, nsi); if (ret < 0) return ret; @@ -715,7 +731,7 @@ post_process_module_probe_trace_events(struct probe_trace_event *tevs, if (!module) return 0; - map = get_target_map(module, false); + map = get_target_map(module, NULL, false); if (!map || debuginfo__get_text_offset(dinfo, &text_offs, true) < 0) { pr_warning("Failed to get ELF symbols for %s\n", module); return -EINVAL; @@ -802,7 +818,8 @@ static int post_process_probe_trace_events(struct perf_probe_event *pev, int ret; if (uprobe) - ret = add_exec_to_probe_trace_events(tevs, ntevs, module); + ret = add_exec_to_probe_trace_events(tevs, ntevs, module, + pev->nsi); else if (module) /* Currently ref_reloc_sym based probe is not for drivers */ ret = post_process_module_probe_trace_events(tevs, ntevs, @@ -825,7 +842,7 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, struct debuginfo *dinfo; int ntevs, ret = 0; - dinfo = open_debuginfo(pev->target, !need_dwarf); + dinfo = open_debuginfo(pev->target, pev->nsi, !need_dwarf); if (!dinfo) { if (need_dwarf) return -ENOENT; @@ -945,7 +962,7 @@ static int __show_line_range(struct line_range *lr, const char *module, char sbuf[STRERR_BUFSIZE]; /* Search a line range */ - dinfo = open_debuginfo(module, false); + dinfo = open_debuginfo(module, NULL, false); if (!dinfo) return -ENOENT; @@ -1021,14 +1038,18 @@ end: return ret; } -int show_line_range(struct line_range *lr, const char *module, bool user) +int show_line_range(struct line_range *lr, const char *module, + struct nsinfo *nsi, bool user) { int ret; + struct nscookie nsc; ret = init_probe_symbol_maps(user); if (ret < 0) return ret; + nsinfo__mountns_enter(nsi, &nsc); ret = __show_line_range(lr, module, user); + nsinfo__mountns_exit(&nsc); exit_probe_symbol_maps(); return ret; @@ -1111,7 +1132,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, if (ret < 0) return ret; - dinfo = open_debuginfo(pevs->target, false); + dinfo = open_debuginfo(pevs->target, pevs->nsi, false); if (!dinfo) { ret = -ENOENT; goto out; @@ -1155,6 +1176,7 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, int show_line_range(struct line_range *lr __maybe_unused, const char *module __maybe_unused, + struct nsinfo *nsi __maybe_unused, bool user __maybe_unused) { pr_warning("Debuginfo-analysis is not supported.\n"); @@ -2373,7 +2395,7 @@ kprobe_blacklist__find_by_address(struct list_head *blacklist, struct kprobe_blacklist_node *node; list_for_each_entry(node, blacklist, list) { - if (node->start <= address && address <= node->end) + if (node->start <= address && address < node->end) return node; } @@ -2703,6 +2725,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, struct probe_trace_event *tev = NULL; struct probe_cache *cache = NULL; struct strlist *namelist[2] = {NULL, NULL}; + struct nscookie nsc; up = pev->uprobes ? 1 : 0; fd[up] = __open_probe_file_and_namelist(up, &namelist[up]); @@ -2729,7 +2752,9 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, if (ret < 0) break; + nsinfo__mountns_enter(pev->nsi, &nsc); ret = probe_file__add_event(fd[up], tev); + nsinfo__mountns_exit(&nsc); if (ret < 0) break; @@ -2744,7 +2769,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, if (ret == -EINVAL && pev->uprobes) warn_uprobe_event_compat(tev); if (ret == 0 && probe_conf.cache) { - cache = probe_cache__new(pev->target); + cache = probe_cache__new(pev->target, pev->nsi); if (!cache || probe_cache__add_entry(cache, pev, tevs, ntevs) < 0 || probe_cache__commit(cache) < 0) @@ -2805,7 +2830,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, int ret, i, j, skipped = 0; char *mod_name; - map = get_target_map(pev->target, pev->uprobes); + map = get_target_map(pev->target, pev->nsi, pev->uprobes); if (!map) { ret = -EINVAL; goto out; @@ -3094,7 +3119,7 @@ static int find_cached_events(struct perf_probe_event *pev, int ntevs = 0; int ret = 0; - cache = probe_cache__new(target); + cache = probe_cache__new(target, pev->nsi); /* Return 0 ("not found") if the target has no probe cache. */ if (!cache) return 0; @@ -3184,7 +3209,7 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev, else return find_cached_events(pev, tevs, pev->target); } - cache = probe_cache__new(pev->target); + cache = probe_cache__new(pev->target, pev->nsi); if (!cache) return 0; @@ -3345,13 +3370,16 @@ int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs) void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs) { int i, j; + struct perf_probe_event *pev; /* Loop 3: cleanup and free trace events */ for (i = 0; i < npevs; i++) { + pev = &pevs[i]; for (j = 0; j < pevs[i].ntevs; j++) clear_probe_trace_event(&pevs[i].tevs[j]); zfree(&pevs[i].tevs); pevs[i].ntevs = 0; + nsinfo__zput(pev->nsi); clear_perf_probe_event(&pevs[i]); } } @@ -3409,8 +3437,8 @@ out: return ret; } -int show_available_funcs(const char *target, struct strfilter *_filter, - bool user) +int show_available_funcs(const char *target, struct nsinfo *nsi, + struct strfilter *_filter, bool user) { struct rb_node *nd; struct map *map; @@ -3421,7 +3449,7 @@ int show_available_funcs(const char *target, struct strfilter *_filter, return ret; /* Get a symbol map */ - map = get_target_map(target, user); + map = get_target_map(target, nsi, user); if (!map) { pr_err("Failed to get a map for %s\n", (target) ? : "kernel"); return -EINVAL; diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 5812947418dd..45b14f020558 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -1,9 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PROBE_EVENT_H #define _PROBE_EVENT_H #include #include #include "intlist.h" +#include "namespaces.h" /* Probe related configurations */ struct probe_conf { @@ -92,6 +94,7 @@ struct perf_probe_event { struct perf_probe_arg *args; /* Arguments */ struct probe_trace_event *tevs; int ntevs; + struct nsinfo *nsi; /* Target namespace */ }; /* Line range */ @@ -163,10 +166,12 @@ int show_perf_probe_event(const char *group, const char *event, struct perf_probe_event *pev, const char *module, bool use_stdout); int show_perf_probe_events(struct strfilter *filter); -int show_line_range(struct line_range *lr, const char *module, bool user); +int show_line_range(struct line_range *lr, const char *module, + struct nsinfo *nsi, bool user); int show_available_vars(struct perf_probe_event *pevs, int npevs, struct strfilter *filter); -int show_available_funcs(const char *module, struct strfilter *filter, bool user); +int show_available_funcs(const char *module, struct nsinfo *nsi, + struct strfilter *filter, bool user); void arch__fix_tev_from_maps(struct perf_probe_event *pev, struct probe_trace_event *tev, struct map *map, struct symbol *sym); @@ -180,7 +185,7 @@ int e_snprintf(char *str, size_t size, const char *format, ...) __printf(3, 4); int copy_to_probe_trace_arg(struct probe_trace_arg *tvar, struct perf_probe_arg *pvar); -struct map *get_target_map(const char *target, bool user); +struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user); void arch__post_process_probe_trace_events(struct perf_probe_event *pev, int ntevs); diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index d679389e627c..cdf8d83a484c 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -412,13 +412,15 @@ int probe_cache_entry__get_event(struct probe_cache_entry *entry, } /* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ -static int probe_cache__open(struct probe_cache *pcache, const char *target) +static int probe_cache__open(struct probe_cache *pcache, const char *target, + struct nsinfo *nsi) { char cpath[PATH_MAX]; char sbuildid[SBUILD_ID_SIZE]; char *dir_name = NULL; bool is_kallsyms = false; int ret, fd; + struct nscookie nsc; if (target && build_id_cache__cached(target)) { /* This is a cached buildid */ @@ -431,8 +433,11 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) target = DSO__NAME_KALLSYMS; is_kallsyms = true; ret = sysfs__sprintf_build_id("/", sbuildid); - } else + } else { + nsinfo__mountns_enter(nsi, &nsc); ret = filename__sprintf_build_id(target, sbuildid); + nsinfo__mountns_exit(&nsc); + } if (ret < 0) { pr_debug("Failed to get build-id from %s.\n", target); @@ -441,7 +446,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) /* If we have no buildid cache, make it */ if (!build_id_cache__cached(sbuildid)) { - ret = build_id_cache__add_s(sbuildid, target, + ret = build_id_cache__add_s(sbuildid, target, nsi, is_kallsyms, NULL); if (ret < 0) { pr_debug("Failed to add build-id cache: %s\n", target); @@ -449,7 +454,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) } } - dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms, + dir_name = build_id_cache__cachedir(sbuildid, target, nsi, is_kallsyms, false); found: if (!dir_name) { @@ -554,7 +559,7 @@ void probe_cache__delete(struct probe_cache *pcache) free(pcache); } -struct probe_cache *probe_cache__new(const char *target) +struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi) { struct probe_cache *pcache = probe_cache__alloc(); int ret; @@ -562,7 +567,7 @@ struct probe_cache *probe_cache__new(const char *target) if (!pcache) return NULL; - ret = probe_cache__open(pcache, target); + ret = probe_cache__open(pcache, target, nsi); if (ret < 0) { pr_debug("Cache open error: %d\n", ret); goto out_err; @@ -974,7 +979,7 @@ int probe_cache__show_all_caches(struct strfilter *filter) return -EINVAL; } strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s); + pcache = probe_cache__new(nd->s, NULL); if (!pcache) continue; if (!list_empty(&pcache->entries)) { diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h index 5ecc9d3925db..63f29b1d22c1 100644 --- a/tools/perf/util/probe-file.h +++ b/tools/perf/util/probe-file.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PROBE_FILE_H #define __PROBE_FILE_H @@ -51,7 +52,7 @@ int probe_file__del_strlist(int fd, struct strlist *namelist); int probe_cache_entry__get_event(struct probe_cache_entry *entry, struct probe_trace_event **tevs); -struct probe_cache *probe_cache__new(const char *target); +struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi); int probe_cache__add_entry(struct probe_cache *pcache, struct perf_probe_event *pev, struct probe_trace_event *tevs, int ntevs); @@ -69,7 +70,7 @@ int probe_cache__show_all_caches(struct strfilter *filter); bool probe_type_is_available(enum probe_type type); bool kretprobe_offset_is_supported(void); #else /* ! HAVE_LIBELF_SUPPORT */ -static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused) +static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) { return NULL; } diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index 27f061551012..16252980ff00 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PROBE_FINDER_H #define _PROBE_FINDER_H diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c index b234a6e3d0d4..797fe1ae2d2e 100644 --- a/tools/perf/util/pstack.c +++ b/tools/perf/util/pstack.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Simple pointer stack * diff --git a/tools/perf/util/pstack.h b/tools/perf/util/pstack.h index ded7f2e36624..8729b8be061d 100644 --- a/tools/perf/util/pstack.h +++ b/tools/perf/util/pstack.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_PSTACK_ #define _PERF_PSTACK_ diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 9f3b0d9754a8..e66dc495809a 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -10,6 +10,7 @@ util/ctype.c util/evlist.c util/evsel.c util/cpumap.c +util/namespaces.c ../lib/bitmap.c ../lib/find_bit.c ../lib/hweight.c diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index c129e99114ae..8e49d9cafcfc 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/quote.c b/tools/perf/util/quote.c index 1ba8920151d8..22eaa201aa27 100644 --- a/tools/perf/util/quote.c +++ b/tools/perf/util/quote.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include "strbuf.h" diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h index 055ca45bed99..274bf26d3511 100644 --- a/tools/perf/util/quote.h +++ b/tools/perf/util/quote.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_QUOTE_H #define __PERF_QUOTE_H diff --git a/tools/perf/util/rb_resort.h b/tools/perf/util/rb_resort.h index 808cc45611fe..7d8972b33f6b 100644 --- a/tools/perf/util/rb_resort.h +++ b/tools/perf/util/rb_resort.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_RESORT_RB_H_ #define _PERF_RESORT_RB_H_ /* diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h index ff9913b994c2..4c8638a22571 100644 --- a/tools/perf/util/rblist.h +++ b/tools/perf/util/rblist.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_RBLIST_H #define __PERF_RBLIST_H diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index d91bdf5a1aa4..1e97937b03a9 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "evlist.h" #include "evsel.h" #include "cpumap.h" diff --git a/tools/perf/util/sane_ctype.h b/tools/perf/util/sane_ctype.h index 4308c22c22ad..c2b42ff9ff32 100644 --- a/tools/perf/util/sane_ctype.h +++ b/tools/perf/util/sane_ctype.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_SANE_CTYPE_H #define _PERF_SANE_CTYPE_H diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 57b7a00e6f16..c7187f067d31 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -116,6 +116,34 @@ static PyObject *get_handler(const char *handler_name) return handler; } +static int get_argument_count(PyObject *handler) +{ + int arg_count = 0; + + /* + * The attribute for the code object is func_code in Python 2, + * whereas it is __code__ in Python 3.0+. + */ + PyObject *code_obj = PyObject_GetAttrString(handler, + "func_code"); + if (PyErr_Occurred()) { + PyErr_Clear(); + code_obj = PyObject_GetAttrString(handler, + "__code__"); + } + PyErr_Clear(); + if (code_obj) { + PyObject *arg_count_obj = PyObject_GetAttrString(code_obj, + "co_argcount"); + if (arg_count_obj) { + arg_count = (int) PyInt_AsLong(arg_count_obj); + Py_DECREF(arg_count_obj); + } + Py_DECREF(code_obj); + } + return arg_count; +} + static void call_object(PyObject *handler, PyObject *args, const char *die_msg) { PyObject *retval; @@ -391,13 +419,115 @@ exit: return pylist; } +static PyObject *get_sample_value_as_tuple(struct sample_read_value *value) +{ + PyObject *t; + + t = PyTuple_New(2); + if (!t) + Py_FatalError("couldn't create Python tuple"); + PyTuple_SetItem(t, 0, PyLong_FromUnsignedLongLong(value->id)); + PyTuple_SetItem(t, 1, PyLong_FromUnsignedLongLong(value->value)); + return t; +} + +static void set_sample_read_in_dict(PyObject *dict_sample, + struct perf_sample *sample, + struct perf_evsel *evsel) +{ + u64 read_format = evsel->attr.read_format; + PyObject *values; + unsigned int i; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { + pydict_set_item_string_decref(dict_sample, "time_enabled", + PyLong_FromUnsignedLongLong(sample->read.time_enabled)); + } + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { + pydict_set_item_string_decref(dict_sample, "time_running", + PyLong_FromUnsignedLongLong(sample->read.time_running)); + } + + if (read_format & PERF_FORMAT_GROUP) + values = PyList_New(sample->read.group.nr); + else + values = PyList_New(1); + + if (!values) + Py_FatalError("couldn't create Python list"); + + if (read_format & PERF_FORMAT_GROUP) { + for (i = 0; i < sample->read.group.nr; i++) { + PyObject *t = get_sample_value_as_tuple(&sample->read.group.values[i]); + PyList_SET_ITEM(values, i, t); + } + } else { + PyObject *t = get_sample_value_as_tuple(&sample->read.one); + PyList_SET_ITEM(values, 0, t); + } + pydict_set_item_string_decref(dict_sample, "values", values); +} + +static PyObject *get_perf_sample_dict(struct perf_sample *sample, + struct perf_evsel *evsel, + struct addr_location *al, + PyObject *callchain) +{ + PyObject *dict, *dict_sample; + + dict = PyDict_New(); + if (!dict) + Py_FatalError("couldn't create Python dictionary"); + + dict_sample = PyDict_New(); + if (!dict_sample) + Py_FatalError("couldn't create Python dictionary"); + + pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); + pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( + (const char *)&evsel->attr, sizeof(evsel->attr))); + + pydict_set_item_string_decref(dict_sample, "pid", + PyInt_FromLong(sample->pid)); + pydict_set_item_string_decref(dict_sample, "tid", + PyInt_FromLong(sample->tid)); + pydict_set_item_string_decref(dict_sample, "cpu", + PyInt_FromLong(sample->cpu)); + pydict_set_item_string_decref(dict_sample, "ip", + PyLong_FromUnsignedLongLong(sample->ip)); + pydict_set_item_string_decref(dict_sample, "time", + PyLong_FromUnsignedLongLong(sample->time)); + pydict_set_item_string_decref(dict_sample, "period", + PyLong_FromUnsignedLongLong(sample->period)); + set_sample_read_in_dict(dict_sample, sample, evsel); + pydict_set_item_string_decref(dict, "sample", dict_sample); + + pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( + (const char *)sample->raw_data, sample->raw_size)); + pydict_set_item_string_decref(dict, "comm", + PyString_FromString(thread__comm_str(al->thread))); + if (al->map) { + pydict_set_item_string_decref(dict, "dso", + PyString_FromString(al->map->dso->name)); + } + if (al->sym) { + pydict_set_item_string_decref(dict, "symbol", + PyString_FromString(al->sym->name)); + } + + pydict_set_item_string_decref(dict, "callchain", callchain); + + return dict; +} + static void python_process_tracepoint(struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al) { struct event_format *event = evsel->tp_format; PyObject *handler, *context, *t, *obj = NULL, *callchain; - PyObject *dict = NULL; + PyObject *dict = NULL, *all_entries_dict = NULL; static char handler_name[256]; struct format_field *field; unsigned long s, ns; @@ -407,10 +537,7 @@ static void python_process_tracepoint(struct perf_sample *sample, void *data = sample->raw_data; unsigned long long nsecs = sample->time; const char *comm = thread__comm_str(al->thread); - - t = PyTuple_New(MAX_FIELDS); - if (!t) - Py_FatalError("couldn't create Python tuple"); + const char *default_handler_name = "trace_unhandled"; if (!event) { snprintf(handler_name, sizeof(handler_name), @@ -427,10 +554,19 @@ static void python_process_tracepoint(struct perf_sample *sample, handler = get_handler(handler_name); if (!handler) { + handler = get_handler(default_handler_name); + if (!handler) + return; dict = PyDict_New(); if (!dict) Py_FatalError("couldn't create Python dict"); } + + t = PyTuple_New(MAX_FIELDS); + if (!t) + Py_FatalError("couldn't create Python tuple"); + + s = nsecs / NSEC_PER_SEC; ns = nsecs - s * NSEC_PER_SEC; @@ -444,8 +580,10 @@ static void python_process_tracepoint(struct perf_sample *sample, /* ip unwinding */ callchain = python_process_callchain(sample, evsel, al); + /* Need an additional reference for the perf_sample dict */ + Py_INCREF(callchain); - if (handler) { + if (!dict) { PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); PyTuple_SetItem(t, n++, PyInt_FromLong(s)); PyTuple_SetItem(t, n++, PyInt_FromLong(ns)); @@ -484,26 +622,35 @@ static void python_process_tracepoint(struct perf_sample *sample, } else { /* FIELD_IS_NUMERIC */ obj = get_field_numeric_entry(event, field, data); } - if (handler) + if (!dict) PyTuple_SetItem(t, n++, obj); else pydict_set_item_string_decref(dict, field->name, obj); } - if (!handler) + if (dict) PyTuple_SetItem(t, n++, dict); + if (get_argument_count(handler) == (int) n + 1) { + all_entries_dict = get_perf_sample_dict(sample, evsel, al, + callchain); + PyTuple_SetItem(t, n++, all_entries_dict); + } else { + Py_DECREF(callchain); + } + if (_PyTuple_Resize(&t, n) == -1) Py_FatalError("error resizing Python tuple"); - if (handler) { + if (!dict) { call_object(handler, t, handler_name); } else { - try_call_object("trace_unhandled", t); + call_object(handler, t, default_handler_name); Py_DECREF(dict); } + Py_XDECREF(all_entries_dict); Py_DECREF(t); } @@ -795,10 +942,16 @@ static void python_process_general_event(struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al) { - PyObject *handler, *t, *dict, *callchain, *dict_sample; + PyObject *handler, *t, *dict, *callchain; static char handler_name[64]; unsigned n = 0; + snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); + + handler = get_handler(handler_name); + if (!handler) + return; + /* * Use the MAX_FIELDS to make the function expandable, though * currently there is only one item for the tuple. @@ -807,61 +960,16 @@ static void python_process_general_event(struct perf_sample *sample, if (!t) Py_FatalError("couldn't create Python tuple"); - dict = PyDict_New(); - if (!dict) - Py_FatalError("couldn't create Python dictionary"); - - dict_sample = PyDict_New(); - if (!dict_sample) - Py_FatalError("couldn't create Python dictionary"); - - snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); - - handler = get_handler(handler_name); - if (!handler) - goto exit; - - pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); - pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize( - (const char *)&evsel->attr, sizeof(evsel->attr))); - - pydict_set_item_string_decref(dict_sample, "pid", - PyInt_FromLong(sample->pid)); - pydict_set_item_string_decref(dict_sample, "tid", - PyInt_FromLong(sample->tid)); - pydict_set_item_string_decref(dict_sample, "cpu", - PyInt_FromLong(sample->cpu)); - pydict_set_item_string_decref(dict_sample, "ip", - PyLong_FromUnsignedLongLong(sample->ip)); - pydict_set_item_string_decref(dict_sample, "time", - PyLong_FromUnsignedLongLong(sample->time)); - pydict_set_item_string_decref(dict_sample, "period", - PyLong_FromUnsignedLongLong(sample->period)); - pydict_set_item_string_decref(dict, "sample", dict_sample); - - pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize( - (const char *)sample->raw_data, sample->raw_size)); - pydict_set_item_string_decref(dict, "comm", - PyString_FromString(thread__comm_str(al->thread))); - if (al->map) { - pydict_set_item_string_decref(dict, "dso", - PyString_FromString(al->map->dso->name)); - } - if (al->sym) { - pydict_set_item_string_decref(dict, "symbol", - PyString_FromString(al->sym->name)); - } - /* ip unwinding */ callchain = python_process_callchain(sample, evsel, al); - pydict_set_item_string_decref(dict, "callchain", callchain); + dict = get_perf_sample_dict(sample, evsel, al, callchain); PyTuple_SetItem(t, n++, dict); if (_PyTuple_Resize(&t, n) == -1) Py_FatalError("error resizing Python tuple"); call_object(handler, t, handler_name); -exit: + Py_DECREF(dict); Py_DECREF(t); } @@ -1259,6 +1367,12 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) fprintf(ofp, "%s", f->name); } + if (not_first++) + fprintf(ofp, ", "); + if (++count % 5 == 0) + fprintf(ofp, "\n\t\t"); + fprintf(ofp, "perf_sample_dict"); + fprintf(ofp, "):\n"); fprintf(ofp, "\t\tprint_header(event_name, common_cpu, " @@ -1328,6 +1442,9 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) fprintf(ofp, ")\n\n"); + fprintf(ofp, "\t\tprint 'Sample: {'+" + "get_dict_as_string(perf_sample_dict['sample'], ', ')+'}'\n\n"); + fprintf(ofp, "\t\tfor node in common_callchain:"); fprintf(ofp, "\n\t\t\tif 'sym' in node:"); fprintf(ofp, "\n\t\t\t\tprint \"\\t[%%x] %%s\" %% (node['ip'], node['sym']['name'])"); @@ -1338,15 +1455,20 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) } fprintf(ofp, "def trace_unhandled(event_name, context, " - "event_fields_dict):\n"); + "event_fields_dict, perf_sample_dict):\n"); - fprintf(ofp, "\t\tprint ' '.join(['%%s=%%s'%%(k,str(v))" - "for k,v in sorted(event_fields_dict.items())])\n\n"); + fprintf(ofp, "\t\tprint get_dict_as_string(event_fields_dict)\n"); + fprintf(ofp, "\t\tprint 'Sample: {'+" + "get_dict_as_string(perf_sample_dict['sample'], ', ')+'}'\n\n"); fprintf(ofp, "def print_header(" "event_name, cpu, secs, nsecs, pid, comm):\n" "\tprint \"%%-20s %%5u %%05u.%%09u %%8u %%-20s \" %% \\\n\t" - "(event_name, cpu, secs, nsecs, pid, comm),\n"); + "(event_name, cpu, secs, nsecs, pid, comm),\n\n"); + + fprintf(ofp, "def get_dict_as_string(a_dict, delimiter=' '):\n" + "\treturn delimiter.join" + "(['%%s=%%s'%%(k,str(v))for k,v in sorted(a_dict.items())])\n"); fclose(ofp); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index d19c40a81040..da55081aefc6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -374,6 +375,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->mmap2 = process_event_stub; if (tool->comm == NULL) tool->comm = process_event_stub; + if (tool->namespaces == NULL) + tool->namespaces = process_event_stub; if (tool->fork == NULL) tool->fork = process_event_stub; if (tool->exit == NULL) @@ -428,6 +431,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool) tool->stat_round = process_stat_round_stub; if (tool->time_conv == NULL) tool->time_conv = process_event_op2_stub; + if (tool->feature == NULL) + tool->feature = process_event_op2_stub; } static void swap_sample_id_all(union perf_event *event, void *data) @@ -1118,6 +1123,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, if (sample_type & PERF_SAMPLE_DATA_SRC) printf(" . data_src: 0x%"PRIx64"\n", sample->data_src); + if (sample_type & PERF_SAMPLE_PHYS_ADDR) + printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr); + if (sample_type & PERF_SAMPLE_TRANSACTION) printf("... transaction: %" PRIx64 "\n", sample->transaction); @@ -1125,6 +1133,30 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event, sample_read__printf(sample, evsel->attr.read_format); } +static void dump_read(struct perf_evsel *evsel, union perf_event *event) +{ + struct read_event *read_event = &event->read; + u64 read_format; + + if (!dump_trace) + return; + + printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, + evsel ? perf_evsel__name(evsel) : "FAIL", + event->read.value); + + read_format = evsel->attr.read_format; + + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + printf("... time enabled : %" PRIu64 "\n", read_event->time_enabled); + + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + printf("... time running : %" PRIu64 "\n", read_event->time_running); + + if (read_format & PERF_FORMAT_ID) + printf("... id : %" PRIu64 "\n", read_event->id); +} + static struct machine *machines__find_for_cpumode(struct machines *machines, union perf_event *event, struct perf_sample *sample) @@ -1269,6 +1301,7 @@ static int machines__deliver_event(struct machines *machines, evlist->stats.total_lost_samples += event->lost_samples.lost; return tool->lost_samples(tool, event, sample, machine); case PERF_RECORD_READ: + dump_read(evsel, event); return tool->read(tool, event, sample, evsel, machine); case PERF_RECORD_THROTTLE: return tool->throttle(tool, event, sample, machine); @@ -1371,6 +1404,8 @@ static s64 perf_session__process_user_event(struct perf_session *session, case PERF_RECORD_TIME_CONV: session->time_conv = event->time_conv; return tool->time_conv(tool, event, session); + case PERF_RECORD_HEADER_FEATURE: + return tool->feature(tool, event, session); default: return -EINVAL; } diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 47b5e7dbcb18..41caa098ed15 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_SESSION_H #define __PERF_SESSION_H diff --git a/tools/perf/util/setns.c b/tools/perf/util/setns.c new file mode 100644 index 000000000000..ce8fc290fce8 --- /dev/null +++ b/tools/perf/util/setns.c @@ -0,0 +1,8 @@ +#include "util.h" +#include +#include + +int setns(int fd, int nstype) +{ + return syscall(__NR_setns, fd, nstype); +} diff --git a/tools/perf/util/smt.c b/tools/perf/util/smt.c new file mode 100644 index 000000000000..453f6f6f29f3 --- /dev/null +++ b/tools/perf/util/smt.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include "api/fs/fs.h" +#include "smt.h" + +int smt_on(void) +{ + static bool cached; + static int cached_result; + int cpu; + int ncpu; + + if (cached) + return cached_result; + + ncpu = sysconf(_SC_NPROCESSORS_CONF); + for (cpu = 0; cpu < ncpu; cpu++) { + unsigned long long siblings; + char *str; + size_t strlen; + char fn[256]; + + snprintf(fn, sizeof fn, + "devices/system/cpu/cpu%d/topology/thread_siblings", + cpu); + if (sysfs__read_str(fn, &str, &strlen) < 0) + continue; + /* Entry is hex, but does not have 0x, so need custom parser */ + siblings = strtoull(str, NULL, 16); + free(str); + if (hweight64(siblings) > 1) { + cached_result = 1; + cached = true; + break; + } + } + if (!cached) { + cached_result = 0; + cached = true; + } + return cached_result; +} diff --git a/tools/perf/util/smt.h b/tools/perf/util/smt.h new file mode 100644 index 000000000000..b8414b7bcbc8 --- /dev/null +++ b/tools/perf/util/smt.h @@ -0,0 +1,6 @@ +#ifndef SMT_H +#define SMT_H 1 + +int smt_on(void); + +#endif diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 8b327c955a4f..84a33f1e9ec9 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -1315,6 +1316,47 @@ struct sort_entry sort_mem_dcacheline = { .se_width_idx = HISTC_MEM_DCACHELINE, }; +static int64_t +sort__phys_daddr_cmp(struct hist_entry *left, struct hist_entry *right) +{ + uint64_t l = 0, r = 0; + + if (left->mem_info) + l = left->mem_info->daddr.phys_addr; + if (right->mem_info) + r = right->mem_info->daddr.phys_addr; + + return (int64_t)(r - l); +} + +static int hist_entry__phys_daddr_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) +{ + uint64_t addr = 0; + size_t ret = 0; + size_t len = BITS_PER_LONG / 4; + + addr = he->mem_info->daddr.phys_addr; + + ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", he->level); + + ret += repsep_snprintf(bf + ret, size - ret, "%-#.*llx", len, addr); + + ret += repsep_snprintf(bf + ret, size - ret, "%-*s", width - ret, ""); + + if (ret > width) + bf[width] = '\0'; + + return width; +} + +struct sort_entry sort_mem_phys_daddr = { + .se_header = "Data Physical Address", + .se_cmp = sort__phys_daddr_cmp, + .se_snprintf = hist_entry__phys_daddr_snprintf, + .se_width_idx = HISTC_MEM_PHYS_DADDR, +}; + static int64_t sort__abort_cmp(struct hist_entry *left, struct hist_entry *right) { @@ -1547,6 +1589,7 @@ static struct sort_dimension memory_sort_dimensions[] = { DIM(SORT_MEM_LVL, "mem", sort_mem_lvl), DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop), DIM(SORT_MEM_DCACHELINE, "dcacheline", sort_mem_dcacheline), + DIM(SORT_MEM_PHYS_DADDR, "phys_daddr", sort_mem_phys_daddr), }; #undef DIM @@ -2563,7 +2606,7 @@ static const char *get_default_sort_order(struct perf_evlist *evlist) BUG_ON(sort__mode >= ARRAY_SIZE(default_sort_orders)); - if (evlist == NULL) + if (evlist == NULL || perf_evlist__empty(evlist)) goto out_no_evlist; evlist__for_each_entry(evlist, evsel) { diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index b7c75597e18f..b2b55e5149a7 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_SORT_H #define __PERF_SORT_H #include "../builtin.h" @@ -245,6 +246,7 @@ enum sort_type { SORT_MEM_SNOOP, SORT_MEM_DCACHELINE, SORT_MEM_IADDR_SYMBOL, + SORT_MEM_PHYS_DADDR, }; /* diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index ebc88a74e67b..4105682afc7a 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -155,6 +156,9 @@ static void find_address_in_section(bfd *abfd, asection *section, void *data) a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, &a2l->filename, &a2l->funcname, &a2l->line); + + if (a2l->filename && !strlen(a2l->filename)) + a2l->filename = NULL; } static struct a2l_data *addr2line_init(const char *path) @@ -248,6 +252,9 @@ static int addr2line(const char *dso_name, u64 addr, &a2l->funcname, &a2l->line) && cnt++ < MAX_INLINE_NEST) { + if (a2l->filename && !strlen(a2l->filename)) + a2l->filename = NULL; + if (node != NULL) { if (inline_list__append_dso_a2l(dso, node)) return 0; diff --git a/tools/perf/util/srcline.h b/tools/perf/util/srcline.h index 7b52ba88676e..8e73f607dfa3 100644 --- a/tools/perf/util/srcline.h +++ b/tools/perf/util/srcline.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_SRCLINE_H #define PERF_SRCLINE_H diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 719d6cb86952..37363869c9a1 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include "evsel.h" #include "stat.h" @@ -70,7 +71,11 @@ static int saved_value_cmp(struct rb_node *rb_node, const void *entry) return a->ctx - b->ctx; if (a->cpu != b->cpu) return a->cpu - b->cpu; - return a->evsel - b->evsel; + if (a->evsel == b->evsel) + return 0; + if ((char *)a->evsel < (char *)b->evsel) + return -1; + return +1; } static struct rb_node *saved_value_new(struct rblist *rblist __maybe_unused, diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 53b9a994a3dc..c9bae5fb8b47 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -128,6 +129,10 @@ static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) { + struct perf_stat_evsel *ps = evsel->priv; + + if (ps) + free(ps->group_data); zfree(&evsel->priv); } diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index 7522bf10b03e..96326b1f9443 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_STATS_H #define __PERF_STATS_H @@ -28,8 +29,9 @@ enum perf_stat_evsel_id { }; struct perf_stat_evsel { - struct stats res_stats[3]; - enum perf_stat_evsel_id id; + struct stats res_stats[3]; + enum perf_stat_evsel_id id; + u64 *group_data; }; enum aggr_mode { diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index aafe908b82b5..3d1cf5bf7f18 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "debug.h" #include "util.h" #include diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h index 802d743378af..ea94d8628980 100644 --- a/tools/perf/util/strbuf.h +++ b/tools/perf/util/strbuf.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_STRBUF_H #define __PERF_STRBUF_H diff --git a/tools/perf/util/strfilter.c b/tools/perf/util/strfilter.c index 4dc0af669a30..7f3253d44afd 100644 --- a/tools/perf/util/strfilter.c +++ b/tools/perf/util/strfilter.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "util.h" #include "string2.h" #include "strfilter.h" diff --git a/tools/perf/util/strfilter.h b/tools/perf/util/strfilter.h index cff5eda88728..e0c25a40f796 100644 --- a/tools/perf/util/strfilter.h +++ b/tools/perf/util/strfilter.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_STRFILTER_H #define __PERF_STRFILTER_H /* General purpose glob matching filter */ diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index cca53b693a48..aaa08ee8c717 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "string2.h" #include #include diff --git a/tools/perf/util/string2.h b/tools/perf/util/string2.h index 2f619681bd6a..ee14ca5451ab 100644 --- a/tools/perf/util/string2.h +++ b/tools/perf/util/string2.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_STRING_H #define PERF_STRING_H diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 19207e50fce5..d58f1e08b170 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_STRLIST_H #define __PERF_STRLIST_H diff --git a/tools/perf/util/svghelper.h b/tools/perf/util/svghelper.h index 946fdf2db97c..e55338d5c3bd 100644 --- a/tools/perf/util/svghelper.h +++ b/tools/perf/util/svghelper.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_SVGHELPER_H #define __PERF_SVGHELPER_H diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 502505cf236a..2de770511e70 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -259,7 +260,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * { uint32_t nr_rel_entries, idx; GElf_Sym sym; - u64 plt_offset; + u64 plt_offset, plt_header_size, plt_entry_size; GElf_Shdr shdr_plt; struct symbol *f; GElf_Shdr shdr_rel_plt, shdr_dynsym; @@ -326,6 +327,23 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; plt_offset = shdr_plt.sh_offset; + switch (ehdr.e_machine) { + case EM_ARM: + plt_header_size = 20; + plt_entry_size = 12; + break; + + case EM_AARCH64: + plt_header_size = 32; + plt_entry_size = 16; + break; + + default: /* FIXME: s390/alpha/mips/parisc/poperpc/sh/sparc/xtensa need to be checked */ + plt_header_size = shdr_plt.sh_entsize; + plt_entry_size = shdr_plt.sh_entsize; + break; + } + plt_offset += plt_header_size; if (shdr_rel_plt.sh_type == SHT_RELA) { GElf_Rela pos_mem, *pos; @@ -335,7 +353,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * const char *elf_name = NULL; char *demangled = NULL; symidx = GELF_R_SYM(pos->r_info); - plt_offset += shdr_plt.sh_entsize; gelf_getsym(syms, symidx, &sym); elf_name = elf_sym__name(&sym, symstrs); @@ -346,11 +363,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * "%s@plt", elf_name); free(demangled); - f = symbol__new(plt_offset, shdr_plt.sh_entsize, + f = symbol__new(plt_offset, plt_entry_size, STB_GLOBAL, sympltname); if (!f) goto out_elf_end; + plt_offset += plt_entry_size; symbols__insert(&dso->symbols[map->type], f); ++nr; } @@ -361,7 +379,6 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * const char *elf_name = NULL; char *demangled = NULL; symidx = GELF_R_SYM(pos->r_info); - plt_offset += shdr_plt.sh_entsize; gelf_getsym(syms, symidx, &sym); elf_name = elf_sym__name(&sym, symstrs); @@ -372,11 +389,12 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map * "%s@plt", elf_name); free(demangled); - f = symbol__new(plt_offset, shdr_plt.sh_entsize, + f = symbol__new(plt_offset, plt_entry_size, STB_GLOBAL, sympltname); if (!f) goto out_elf_end; + plt_offset += plt_entry_size; symbols__insert(&dso->symbols[map->type], f); ++nr; } @@ -391,7 +409,7 @@ out_elf_end: return 0; } -char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name) +char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name) { return demangle_sym(dso, kmodule, elf_name); } @@ -1442,7 +1460,7 @@ static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci, static int kcore_copy__process_modules(void *arg, const char *name __maybe_unused, - u64 start) + u64 start, u64 size __maybe_unused) { struct kcore_copy_info *kci = arg; diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 40bf5d4c0bfd..ff48d0d49584 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "symbol.h" #include "util.h" @@ -377,7 +378,7 @@ void symbol__elf_init(void) char *dso__demangle_sym(struct dso *dso __maybe_unused, int kmodule __maybe_unused, - char *elf_name __maybe_unused) + const char *elf_name __maybe_unused) { return NULL; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e7a98dbd2aed..6492ef38b090 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -18,6 +19,7 @@ #include "symbol.h" #include "strlist.h" #include "intlist.h" +#include "namespaces.h" #include "header.h" #include "path.h" #include "sane_ctype.h" @@ -52,6 +54,7 @@ static enum dso_binary_type binary_type_symtab[] = { DSO_BINARY_TYPE__JAVA_JIT, DSO_BINARY_TYPE__DEBUGLINK, DSO_BINARY_TYPE__BUILD_ID_CACHE, + DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO, DSO_BINARY_TYPE__FEDORA_DEBUGINFO, DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, DSO_BINARY_TYPE__BUILDID_DEBUGINFO, @@ -231,7 +234,8 @@ void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) goto out_unlock; for (next = map__next(curr); next; next = map__next(curr)) { - curr->end = next->start; + if (!curr->end) + curr->end = next->start; curr = next; } @@ -239,7 +243,8 @@ void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) * We still haven't the actual symbols, so guess the * last map final address. */ - curr->end = ~0ULL; + if (!curr->end) + curr->end = ~0ULL; out_unlock: pthread_rwlock_unlock(&maps->lock); @@ -550,7 +555,7 @@ void dso__sort_by_name(struct dso *dso, enum map_type type) int modules__parse(const char *filename, void *arg, int (*process_module)(void *arg, const char *name, - u64 start)) + u64 start, u64 size)) { char *line = NULL; size_t n; @@ -563,8 +568,8 @@ int modules__parse(const char *filename, void *arg, while (1) { char name[PATH_MAX]; - u64 start; - char *sep; + u64 start, size; + char *sep, *endptr; ssize_t line_len; line_len = getline(&line, &n, file); @@ -596,7 +601,11 @@ int modules__parse(const char *filename, void *arg, scnprintf(name, sizeof(name), "[%s]", line); - err = process_module(arg, name, start); + size = strtoul(sep + 1, &endptr, 0); + if (*endptr != ' ' && *endptr != '\t') + continue; + + err = process_module(arg, name, start, size); if (err) break; } @@ -943,7 +952,8 @@ static struct module_info *find_module(const char *name, return NULL; } -static int __read_proc_modules(void *arg, const char *name, u64 start) +static int __read_proc_modules(void *arg, const char *name, u64 start, + u64 size __maybe_unused) { struct rb_root *modules = arg; struct module_info *mi; @@ -1325,14 +1335,15 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, return __dso__load_kallsyms(dso, filename, map, false); } -static int dso__load_perf_map(struct dso *dso, struct map *map) +static int dso__load_perf_map(const char *map_path, struct dso *dso, + struct map *map) { char *line = NULL; size_t n; FILE *file; int nr_syms = 0; - file = fopen(dso->long_name, "r"); + file = fopen(map_path, "r"); if (file == NULL) goto out_failure; @@ -1416,6 +1427,7 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, return kmod && dso->symtab_type == type; case DSO_BINARY_TYPE__BUILD_ID_CACHE: + case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO: return true; case DSO_BINARY_TYPE__NOT_FOUND: @@ -1424,6 +1436,44 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, } } +/* Checks for the existence of the perf-.map file in two different + * locations. First, if the process is a separate mount namespace, check in + * that namespace using the pid of the innermost pid namespace. If's not in a + * namespace, or the file can't be found there, try in the mount namespace of + * the tracing process using our view of its pid. + */ +static int dso__find_perf_map(char *filebuf, size_t bufsz, + struct nsinfo **nsip) +{ + struct nscookie nsc; + struct nsinfo *nsi; + struct nsinfo *nnsi; + int rc = -1; + + nsi = *nsip; + + if (nsi->need_setns) { + snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nsi->nstgid); + nsinfo__mountns_enter(nsi, &nsc); + rc = access(filebuf, R_OK); + nsinfo__mountns_exit(&nsc); + if (rc == 0) + return rc; + } + + nnsi = nsinfo__copy(nsi); + if (nnsi) { + nsinfo__put(nsi); + + nnsi->need_setns = false; + snprintf(filebuf, bufsz, "/tmp/perf-%d.map", nnsi->tgid); + *nsip = nnsi; + rc = 0; + } + + return rc; +} + int dso__load(struct dso *dso, struct map *map) { char *name; @@ -1435,8 +1485,21 @@ int dso__load(struct dso *dso, struct map *map) struct symsrc ss_[2]; struct symsrc *syms_ss = NULL, *runtime_ss = NULL; bool kmod; + bool perfmap; unsigned char build_id[BUILD_ID_SIZE]; + struct nscookie nsc; + char newmapname[PATH_MAX]; + const char *map_path = dso->long_name; + perfmap = strncmp(dso->name, "/tmp/perf-", 10) == 0; + if (perfmap) { + if (dso->nsinfo && (dso__find_perf_map(newmapname, + sizeof(newmapname), &dso->nsinfo) == 0)) { + map_path = newmapname; + } + } + + nsinfo__mountns_enter(dso->nsinfo, &nsc); pthread_mutex_lock(&dso->lock); /* check again under the dso->lock */ @@ -1461,19 +1524,19 @@ int dso__load(struct dso *dso, struct map *map) dso->adjust_symbols = 0; - if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { + if (perfmap) { struct stat st; - if (lstat(dso->name, &st) < 0) + if (lstat(map_path, &st) < 0) goto out; if (!symbol_conf.force && st.st_uid && (st.st_uid != geteuid())) { pr_warning("File %s not owned by current user or root, " - "ignoring it (use -f to override).\n", dso->name); + "ignoring it (use -f to override).\n", map_path); goto out; } - ret = dso__load_perf_map(dso, map); + ret = dso__load_perf_map(map_path, dso, map); dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : DSO_BINARY_TYPE__NOT_FOUND; goto out; @@ -1511,9 +1574,15 @@ int dso__load(struct dso *dso, struct map *map) for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) { struct symsrc *ss = &ss_[ss_pos]; bool next_slot = false; + bool is_reg; + bool nsexit; + int sirc; enum dso_binary_type symtab_type = binary_type_symtab[i]; + nsexit = (symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE || + symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO); + if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type)) continue; @@ -1521,12 +1590,20 @@ int dso__load(struct dso *dso, struct map *map) root_dir, name, PATH_MAX)) continue; - if (!is_regular_file(name)) - continue; + if (nsexit) + nsinfo__mountns_exit(&nsc); - /* Name is now the name of the next image to try */ - if (symsrc__init(ss, dso, name, symtab_type) < 0) + is_reg = is_regular_file(name); + sirc = symsrc__init(ss, dso, name, symtab_type); + + if (nsexit) + nsinfo__mountns_enter(dso->nsinfo, &nsc); + + if (!is_reg || sirc < 0) { + if (sirc >= 0) + symsrc__destroy(ss); continue; + } if (!syms_ss && symsrc__has_symtab(ss)) { syms_ss = ss; @@ -1584,6 +1661,7 @@ out_free: out: dso__set_loaded(dso, map->type); pthread_mutex_unlock(&dso->lock); + nsinfo__mountns_exit(&nsc); return ret; } @@ -1660,7 +1738,7 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map) } if (!symbol_conf.ignore_vmlinux_buildid) - filename = dso__build_id_filename(dso, NULL, 0); + filename = dso__build_id_filename(dso, NULL, 0, false); if (filename != NULL) { err = dso__load_vmlinux(dso, map, filename, true); if (err > 0) diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 41ebba9a2eb2..6352022593c6 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_SYMBOL #define __PERF_SYMBOL 1 @@ -186,6 +187,7 @@ struct addr_map_symbol { struct symbol *sym; u64 addr; u64 al_addr; + u64 phys_addr; }; struct branch_info { @@ -273,7 +275,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size); int sysfs__read_build_id(const char *filename, void *bf, size_t size); int modules__parse(const char *filename, void *arg, int (*process_module)(void *arg, const char *name, - u64 start)); + u64 start, u64 size)); int filename__read_debuglink(const char *filename, char *debuglink, size_t size); @@ -306,7 +308,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *map); -char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name); +char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name); void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel); void symbols__insert(struct rb_root *symbols, struct symbol *sym); diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c index 63694e174e5c..6dd2cb88ccbe 100644 --- a/tools/perf/util/symbol_fprintf.c +++ b/tools/perf/util/symbol_fprintf.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/syscalltbl.c b/tools/perf/util/syscalltbl.c index bbb4c1957578..6eea7cff3d4e 100644 --- a/tools/perf/util/syscalltbl.c +++ b/tools/perf/util/syscalltbl.c @@ -15,10 +15,11 @@ #include "syscalltbl.h" #include +#include #ifdef HAVE_SYSCALL_TABLE -#include #include +#include "string2.h" #include "util.h" #if defined(__x86_64__) @@ -105,6 +106,27 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) return sc ? sc->id : -1; } +int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx) +{ + int i; + struct syscall *syscalls = tbl->syscalls.entries; + + for (i = *idx + 1; i < tbl->syscalls.nr_entries; ++i) { + if (strglobmatch(syscalls[i].name, syscall_glob)) { + *idx = i; + return syscalls[i].id; + } + } + + return -1; +} + +int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx) +{ + *idx = -1; + return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx); +} + #else /* HAVE_SYSCALL_TABLE */ #include @@ -131,4 +153,15 @@ int syscalltbl__id(struct syscalltbl *tbl, const char *name) { return audit_name_to_syscall(name, tbl->audit_machine); } + +int syscalltbl__strglobmatch_next(struct syscalltbl *tbl __maybe_unused, + const char *syscall_glob __maybe_unused, int *idx __maybe_unused) +{ + return -1; +} + +int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx) +{ + return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx); +} #endif /* HAVE_SYSCALL_TABLE */ diff --git a/tools/perf/util/syscalltbl.h b/tools/perf/util/syscalltbl.h index e2951510484f..c8e7e9ce0f01 100644 --- a/tools/perf/util/syscalltbl.h +++ b/tools/perf/util/syscalltbl.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_SYSCALLTBL_H #define __PERF_SYSCALLTBL_H @@ -17,4 +18,7 @@ void syscalltbl__delete(struct syscalltbl *tbl); const char *syscalltbl__name(const struct syscalltbl *tbl, int id); int syscalltbl__id(struct syscalltbl *tbl, const char *name); +int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_glob, int *idx); +int syscalltbl__strglobmatch_next(struct syscalltbl *tbl, const char *syscall_glob, int *idx); + #endif /* __PERF_SYSCALLTBL_H */ diff --git a/tools/perf/util/target.h b/tools/perf/util/target.h index 7381b1ca4041..446aa7a56f25 100644 --- a/tools/perf/util/target.h +++ b/tools/perf/util/target.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_TARGET_H #define _PERF_TARGET_H diff --git a/tools/perf/util/term.c b/tools/perf/util/term.c index 8f254a74d97d..e7aa82c06c76 100644 --- a/tools/perf/util/term.c +++ b/tools/perf/util/term.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "term.h" #include #include diff --git a/tools/perf/util/term.h b/tools/perf/util/term.h index 2c06a61846a1..607b170a9017 100644 --- a/tools/perf/util/term.h +++ b/tools/perf/util/term.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_TERM_H #define __PERF_TERM_H diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 378c418ca0c1..1dbcd3c8dee0 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../perf.h" #include #include @@ -59,6 +60,8 @@ struct thread *thread__new(pid_t pid, pid_t tid) list_add(&comm->list, &thread->comm_list); refcount_set(&thread->refcnt, 1); RB_CLEAR_NODE(&thread->rb_node); + /* Thread holds first ref to nsdata. */ + thread->nsinfo = nsinfo__new(pid); } return thread; @@ -91,6 +94,7 @@ void thread__delete(struct thread *thread) comm__free(comm); } unwind__finish_access(thread); + nsinfo__zput(thread->nsinfo); free(thread); } diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 4eb849e9098f..fdcea7c0cac1 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_THREAD_H #define __PERF_THREAD_H @@ -34,6 +35,7 @@ struct thread { void *priv; struct thread_stack *ts; + struct nsinfo *nsinfo; #ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space; struct unwind_libunwind_ops *unwind_libunwind_ops; diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 63ead7b06324..be0d5a736dea 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h index bd34d7a0b9fa..f15803985435 100644 --- a/tools/perf/util/thread_map.h +++ b/tools/perf/util/thread_map.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_THREAD_MAP_H #define __PERF_THREAD_MAP_H diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c index 5b5d0214debd..81927d027417 100644 --- a/tools/perf/util/time-utils.c +++ b/tools/perf/util/time-utils.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/time-utils.h b/tools/perf/util/time-utils.h index 8656be08513b..15b475c50ccf 100644 --- a/tools/perf/util/time-utils.h +++ b/tools/perf/util/time-utils.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _TIME_UTILS_H_ #define _TIME_UTILS_H_ diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 829471a1c6d7..2532b558099b 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_TOOL_H #define __PERF_TOOL_H @@ -34,6 +35,12 @@ typedef int (*event_oe)(struct perf_tool *tool, union perf_event *event, typedef s64 (*event_op3)(struct perf_tool *tool, union perf_event *event, struct perf_session *session); +enum show_feature_header { + SHOW_FEAT_NO_HEADER = 0, + SHOW_FEAT_HEADER, + SHOW_FEAT_HEADER_FULL_INFO, +}; + struct perf_tool { event_sample sample, read; @@ -63,11 +70,13 @@ struct perf_tool { cpu_map, stat_config, stat, - stat_round; + stat_round, + feature; event_op3 auxtrace; bool ordered_events; bool ordering_requires_timestamps; bool namespace_events; + enum show_feature_header show_feat_hdr; }; #endif /* __PERF_TOOL_H */ diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 9bdfb78a9a35..506150a75bd0 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_TOP_H #define __PERF_TOP_H 1 diff --git a/tools/perf/util/trace-event.c b/tools/perf/util/trace-event.c index c330780674fc..16a776371d03 100644 --- a/tools/perf/util/trace-event.c +++ b/tools/perf/util/trace-event.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 1fbc044f9eb0..dcbdb53dc702 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_UTIL_TRACE_EVENT_H #define _PERF_UTIL_TRACE_EVENT_H diff --git a/tools/perf/util/trigger.h b/tools/perf/util/trigger.h index e97d7016d771..370138e7e35c 100644 --- a/tools/perf/util/trigger.h +++ b/tools/perf/util/trigger.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __TRIGGER_H_ #define __TRIGGER_H_ 1 diff --git a/tools/perf/util/tsc.c b/tools/perf/util/tsc.c index 1b741646eed0..bfa782421cbd 100644 --- a/tools/perf/util/tsc.c +++ b/tools/perf/util/tsc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include diff --git a/tools/perf/util/tsc.h b/tools/perf/util/tsc.h index d5b11e2b85e0..e0c3af34ac8d 100644 --- a/tools/perf/util/tsc.h +++ b/tools/perf/util/tsc.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_TSC_H #define __PERF_TSC_H diff --git a/tools/perf/util/units.c b/tools/perf/util/units.c index 4767ec2c5ef6..a46762aec4c9 100644 --- a/tools/perf/util/units.c +++ b/tools/perf/util/units.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "units.h" #include #include diff --git a/tools/perf/util/units.h b/tools/perf/util/units.h index f02c87317150..99263b6a23f7 100644 --- a/tools/perf/util/units.h +++ b/tools/perf/util/units.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef PERF_UNIT_H #define PERF_UNIT_H diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index 7755a5e0fe5e..1e9c974faf67 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/unwind-libdw.h b/tools/perf/util/unwind-libdw.h index 4a2b269a7b3b..0cbd2650e280 100644 --- a/tools/perf/util/unwind-libdw.h +++ b/tools/perf/util/unwind-libdw.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_UNWIND_LIBDW_H #define __PERF_UNWIND_LIBDW_H diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 672c2ada9357..7a42f703e858 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Post mortem Dwarf CFI based unwinding on top of regs and stack dumps. * diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c index 8aef572d0889..647a1e6b4c7b 100644 --- a/tools/perf/util/unwind-libunwind.c +++ b/tools/perf/util/unwind-libunwind.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "unwind.h" #include "thread.h" #include "session.h" diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index bfbdcc6198c9..8a44a1569a21 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __UNWIND_H #define __UNWIND_H diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c index 6cc9d9888ce0..070d25ceea6a 100644 --- a/tools/perf/util/usage.c +++ b/tools/perf/util/usage.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * usage.c * diff --git a/tools/perf/util/util-cxx.h b/tools/perf/util/util-cxx.h index 0e0e019c9f34..80a99e458d4e 100644 --- a/tools/perf/util/util-cxx.h +++ b/tools/perf/util/util-cxx.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Support C++ source use utilities defined in util.h */ diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 988111e0bab5..3687b720327a 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "../perf.h" #include "util.h" #include "debug.h" @@ -143,13 +144,17 @@ out: return list; } -static int slow_copyfile(const char *from, const char *to) +static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) { int err = -1; char *line = NULL; size_t n; - FILE *from_fp = fopen(from, "r"), *to_fp; + FILE *from_fp, *to_fp; + struct nscookie nsc; + nsinfo__mountns_enter(nsi, &nsc); + from_fp = fopen(from, "r"); + nsinfo__mountns_exit(&nsc); if (from_fp == NULL) goto out; @@ -198,15 +203,21 @@ int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) return size ? -1 : 0; } -int copyfile_mode(const char *from, const char *to, mode_t mode) +static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, + struct nsinfo *nsi) { int fromfd, tofd; struct stat st; - int err = -1; + int err; char *tmp = NULL, *ptr = NULL; + struct nscookie nsc; - if (stat(from, &st)) + nsinfo__mountns_enter(nsi, &nsc); + err = stat(from, &st); + nsinfo__mountns_exit(&nsc); + if (err) goto out; + err = -1; /* extra 'x' at the end is to reserve space for '.' */ if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { @@ -227,11 +238,13 @@ int copyfile_mode(const char *from, const char *to, mode_t mode) goto out_close_to; if (st.st_size == 0) { /* /proc? do it slowly... */ - err = slow_copyfile(from, tmp); + err = slow_copyfile(from, tmp, nsi); goto out_close_to; } + nsinfo__mountns_enter(nsi, &nsc); fromfd = open(from, O_RDONLY); + nsinfo__mountns_exit(&nsc); if (fromfd < 0) goto out_close_to; @@ -248,6 +261,16 @@ out: return err; } +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) +{ + return copyfile_mode_ns(from, to, 0755, nsi); +} + +int copyfile_mode(const char *from, const char *to, mode_t mode) +{ + return copyfile_mode_ns(from, to, mode, NULL); +} + int copyfile(const char *from, const char *to) { return copyfile_mode(from, to, 0755); @@ -259,6 +282,7 @@ static ssize_t ion(bool is_read, int fd, void *buf, size_t n) size_t left = n; while (left) { + /* buf must be treated as const if !is_read. */ ssize_t ret = is_read ? read(fd, buf, left) : write(fd, buf, left); @@ -286,9 +310,10 @@ ssize_t readn(int fd, void *buf, size_t n) /* * Write exactly 'n' bytes or return an error. */ -ssize_t writen(int fd, void *buf, size_t n) +ssize_t writen(int fd, const void *buf, size_t n) { - return ion(false, fd, buf, n); + /* ion does not modify buf. */ + return ion(false, fd, (void *)buf, n); } size_t hex_width(u64 v) diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 2c9e58a45310..b52765e6d7b4 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef GIT_COMPAT_UTIL_H #define GIT_COMPAT_UTIL_H @@ -12,6 +13,7 @@ #include #include #include +#include "namespaces.h" /* General helper functions */ void usage(const char *err) __noreturn; @@ -33,10 +35,11 @@ struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dire bool lsdir_no_dot_filter(const char *name, struct dirent *d); int copyfile(const char *from, const char *to); int copyfile_mode(const char *from, const char *to, mode_t mode); +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); int copyfile_offset(int fromfd, loff_t from_ofs, int tofd, loff_t to_ofs, u64 size); ssize_t readn(int fd, void *buf, size_t n); -ssize_t writen(int fd, void *buf, size_t n); +ssize_t writen(int fd, const void *buf, size_t n); size_t hex_width(u64 v); int hex2u64(const char *ptr, u64 *val); @@ -58,4 +61,8 @@ const char *perf_tip(const char *dirpath); int sched_getcpu(void); #endif +#ifndef HAVE_SETNS_SUPPORT +int setns(int fd, int nstype); +#endif + #endif /* GIT_COMPAT_UTIL_H */ diff --git a/tools/perf/util/values.c b/tools/perf/util/values.c index 5de2e15e2eda..4b7a303e4ba8 100644 --- a/tools/perf/util/values.c +++ b/tools/perf/util/values.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -12,7 +13,7 @@ int perf_read_values_init(struct perf_read_values *values) values->threads_max = 16; values->pid = malloc(values->threads_max * sizeof(*values->pid)); values->tid = malloc(values->threads_max * sizeof(*values->tid)); - values->value = malloc(values->threads_max * sizeof(*values->value)); + values->value = zalloc(values->threads_max * sizeof(*values->value)); if (!values->pid || !values->tid || !values->value) { pr_debug("failed to allocate read_values threads arrays"); goto out_free_pid; @@ -98,15 +99,16 @@ static int perf_read_values__findnew_thread(struct perf_read_values *values, return i; } - i = values->threads + 1; - values->value[i] = malloc(values->counters_max * sizeof(**values->value)); + i = values->threads; + + values->value[i] = zalloc(values->counters_max * sizeof(**values->value)); if (!values->value[i]) { pr_debug("failed to allocate read_values counters array"); return -ENOMEM; } values->pid[i] = pid; values->tid[i] = tid; - values->threads = i; + values->threads = i + 1; return i; } @@ -130,12 +132,16 @@ static int perf_read_values__enlarge_counters(struct perf_read_values *values) for (i = 0; i < values->threads; i++) { u64 *value = realloc(values->value[i], counters_max * sizeof(**values->value)); + int j; - if (value) { + if (!value) { pr_debug("failed to enlarge read_values ->values array"); goto out_free_name; } + for (j = values->counters_max; j < counters_max; j++) + value[j] = 0; + values->value[i] = value; } @@ -187,7 +193,7 @@ int perf_read_values_add_value(struct perf_read_values *values, if (cindex < 0) return cindex; - values->value[tindex][cindex] = value; + values->value[tindex][cindex] += value; return 0; } diff --git a/tools/perf/util/values.h b/tools/perf/util/values.h index 808ff9c73bf5..8c41f22f42cf 100644 --- a/tools/perf/util/values.h +++ b/tools/perf/util/values.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_VALUES_H #define __PERF_VALUES_H diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index d3c39eec89a8..cffcda448c28 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/perf/util/vdso.h b/tools/perf/util/vdso.h index cdc4fabfc212..bc74ace603ae 100644 --- a/tools/perf/util/vdso.h +++ b/tools/perf/util/vdso.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __PERF_VDSO__ #define __PERF_VDSO__ diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c index 7251fdbabced..dc95154f5646 100644 --- a/tools/perf/util/xyarray.c +++ b/tools/perf/util/xyarray.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "xyarray.h" #include "util.h" #include @@ -12,6 +13,8 @@ struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size) xy->entry_size = entry_size; xy->row_size = row_size; xy->entries = xlen * ylen; + xy->max_x = xlen; + xy->max_y = ylen; } return xy; diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h index 7f30af371b7e..7ffe562e7ae7 100644 --- a/tools/perf/util/xyarray.h +++ b/tools/perf/util/xyarray.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_XYARRAY_H_ #define _PERF_XYARRAY_H_ 1 @@ -7,6 +8,8 @@ struct xyarray { size_t row_size; size_t entry_size; size_t entries; + size_t max_x; + size_t max_y; char contents[]; }; @@ -19,4 +22,14 @@ static inline void *xyarray__entry(struct xyarray *xy, int x, int y) return &xy->contents[x * xy->row_size + y * xy->entry_size]; } +static inline int xyarray__max_y(struct xyarray *xy) +{ + return xy->max_y; +} + +static inline int xyarray__max_x(struct xyarray *xy) +{ + return xy->max_x; +} + #endif /* _PERF_XYARRAY_H_ */ diff --git a/tools/perf/util/zlib.c b/tools/perf/util/zlib.c index 1329d843eb7b..008fe68d7b76 100644 --- a/tools/perf/util/zlib.c +++ b/tools/perf/util/zlib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c index 82a2ff896a95..52a39ecf5ca1 100644 --- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c +++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c @@ -759,7 +759,7 @@ static acpi_status osl_list_bios_tables(void) /* Skip NULL entries in RSDT/XSDT */ - if (!table_address) { + if (table_address == 0) { continue; } @@ -808,7 +808,8 @@ osl_get_bios_table(char *signature, u8 number_of_tables; u8 item_size; u32 current_instance = 0; - acpi_physical_address table_address = 0; + acpi_physical_address table_address; + acpi_physical_address first_table_address = 0; u32 table_length = 0; acpi_status status = AE_OK; u32 i; @@ -820,9 +821,10 @@ osl_get_bios_table(char *signature, ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT) || ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT) || ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { - if (instance > 0) { - return (AE_LIMIT); - } + +find_next_instance: + + table_address = 0; /* * Get the appropriate address, either 32-bit or 64-bit. Be very @@ -830,41 +832,66 @@ osl_get_bios_table(char *signature, * Note: The 64-bit addresses have priority. */ if (ACPI_COMPARE_NAME(signature, ACPI_SIG_DSDT)) { - if ((gbl_fadt->header.length >= MIN_FADT_FOR_XDSDT) && - gbl_fadt->Xdsdt) { - table_address = - (acpi_physical_address)gbl_fadt->Xdsdt; - } else - if ((gbl_fadt->header.length >= MIN_FADT_FOR_DSDT) - && gbl_fadt->dsdt) { - table_address = - (acpi_physical_address)gbl_fadt->dsdt; + if (current_instance < 2) { + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_XDSDT) && gbl_fadt->Xdsdt + && current_instance == 0) { + table_address = + (acpi_physical_address)gbl_fadt-> + Xdsdt; + } else + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_DSDT) + && gbl_fadt->dsdt != + first_table_address) { + table_address = + (acpi_physical_address)gbl_fadt-> + dsdt; + } } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_FACS)) { - if ((gbl_fadt->header.length >= MIN_FADT_FOR_XFACS) && - gbl_fadt->Xfacs) { - table_address = - (acpi_physical_address)gbl_fadt->Xfacs; - } else - if ((gbl_fadt->header.length >= MIN_FADT_FOR_FACS) - && gbl_fadt->facs) { - table_address = - (acpi_physical_address)gbl_fadt->facs; + if (current_instance < 2) { + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_XFACS) && gbl_fadt->Xfacs + && current_instance == 0) { + table_address = + (acpi_physical_address)gbl_fadt-> + Xfacs; + } else + if ((gbl_fadt->header.length >= + MIN_FADT_FOR_FACS) + && gbl_fadt->facs != + first_table_address) { + table_address = + (acpi_physical_address)gbl_fadt-> + facs; + } } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_XSDT)) { if (!gbl_revision) { return (AE_BAD_SIGNATURE); } - table_address = - (acpi_physical_address)gbl_rsdp. - xsdt_physical_address; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp. + xsdt_physical_address; + } } else if (ACPI_COMPARE_NAME(signature, ACPI_SIG_RSDT)) { - table_address = - (acpi_physical_address)gbl_rsdp. - rsdt_physical_address; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp. + rsdt_physical_address; + } } else { - table_address = (acpi_physical_address)gbl_rsdp_address; - signature = ACPI_SIG_RSDP; + if (current_instance == 0) { + table_address = + (acpi_physical_address)gbl_rsdp_address; + signature = ACPI_SIG_RSDP; + } + } + + if (table_address == 0) { + goto exit_find_table; } /* Now we can get the requested special table */ @@ -875,6 +902,18 @@ osl_get_bios_table(char *signature, } table_length = ap_get_table_length(mapped_table); + if (first_table_address == 0) { + first_table_address = table_address; + } + + /* Match table instance */ + + if (current_instance != instance) { + osl_unmap_table(mapped_table); + mapped_table = NULL; + current_instance++; + goto find_next_instance; + } } else { /* Case for a normal ACPI table */ if (osl_can_use_xsdt()) { @@ -913,7 +952,7 @@ osl_get_bios_table(char *signature, /* Skip NULL entries in RSDT/XSDT */ - if (!table_address) { + if (table_address == 0) { continue; } @@ -946,6 +985,8 @@ osl_get_bios_table(char *signature, } } +exit_find_table: + if (!mapped_table) { return (AE_LIMIT); } diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c index 31b5a7f74015..d686e11936c4 100644 --- a/tools/power/acpi/tools/acpidump/apfiles.c +++ b/tools/power/acpi/tools/acpidump/apfiles.c @@ -61,7 +61,7 @@ static int ap_is_existing_file(char *pathname); static int ap_is_existing_file(char *pathname) { -#ifndef _GNU_EFI +#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) struct stat stat_info; if (!stat(pathname, &stat_info)) { diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c index dd82afa897bd..943b6b614683 100644 --- a/tools/power/acpi/tools/acpidump/apmain.c +++ b/tools/power/acpi/tools/acpidump/apmain.c @@ -300,7 +300,7 @@ static int ap_do_options(int argc, char **argv) * ******************************************************************************/ -#ifndef _GNU_EFI +#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) #else int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[]) diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile index 3e59f1aa3947..d79ab161cc75 100644 --- a/tools/power/cpupower/bench/Makefile +++ b/tools/power/cpupower/bench/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 OUTPUT := ./ ifeq ("$(origin O)", "command line") ifneq ($(O),) diff --git a/tools/power/cpupower/debug/i386/Makefile b/tools/power/cpupower/debug/i386/Makefile index c05cc0ac80c7..b3f771039b17 100644 --- a/tools/power/cpupower/debug/i386/Makefile +++ b/tools/power/cpupower/debug/i386/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 OUTPUT=./ ifeq ("$(origin O)", "command line") OUTPUT := $(O)/ diff --git a/tools/power/cpupower/debug/kernel/Makefile b/tools/power/cpupower/debug/kernel/Makefile index a8a6f8eec5c2..c23e5a6ceb7e 100644 --- a/tools/power/cpupower/debug/kernel/Makefile +++ b/tools/power/cpupower/debug/kernel/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 obj-m := KDIR := /lib/modules/$(shell uname -r)/build diff --git a/tools/power/cpupower/debug/x86_64/Makefile b/tools/power/cpupower/debug/x86_64/Makefile index 1c5214526716..59af84b8ef45 100644 --- a/tools/power/cpupower/debug/x86_64/Makefile +++ b/tools/power/cpupower/debug/x86_64/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 OUTPUT=./ ifeq ("$(origin O)", "command line") OUTPUT := $(O)/ diff --git a/tools/power/cpupower/lib/cpuidle.h b/tools/power/cpupower/lib/cpuidle.h index 04eb3cfa6e42..2e10fead2e1e 100644 --- a/tools/power/cpupower/lib/cpuidle.h +++ b/tools/power/cpupower/lib/cpuidle.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPUPOWER_CPUIDLE_H__ #define __CPUPOWER_CPUIDLE_H__ diff --git a/tools/power/cpupower/lib/cpupower.h b/tools/power/cpupower/lib/cpupower.h index fa031fcc7710..e4e4292eacec 100644 --- a/tools/power/cpupower/lib/cpupower.h +++ b/tools/power/cpupower/lib/cpupower.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPUPOWER_CPUPOWER_H__ #define __CPUPOWER_CPUPOWER_H__ diff --git a/tools/power/cpupower/lib/cpupower_intern.h b/tools/power/cpupower/lib/cpupower_intern.h index f8ec4009621c..92affdfbe417 100644 --- a/tools/power/cpupower/lib/cpupower_intern.h +++ b/tools/power/cpupower/lib/cpupower_intern.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #define PATH_TO_CPU "/sys/devices/system/cpu/" #define MAX_LINE_LEN 4096 #define SYSFS_PATH_MAX 255 diff --git a/tools/power/cpupower/utils/builtin.h b/tools/power/cpupower/utils/builtin.h index 2284c8ea4e2a..f7065ae60a14 100644 --- a/tools/power/cpupower/utils/builtin.h +++ b/tools/power/cpupower/utils/builtin.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef BUILTIN_H #define BUILTIN_H diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c index 691c24d50ef4..569f268f4c7f 100644 --- a/tools/power/cpupower/utils/cpuidle-set.c +++ b/tools/power/cpupower/utils/cpuidle-set.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c index 9ea914378985..2dccf4998599 100644 --- a/tools/power/cpupower/utils/cpupower.c +++ b/tools/power/cpupower/utils/cpupower.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ static int cmd_help(int argc, const char **argv); */ struct cpupower_cpu_info cpupower_cpu_info; int run_as_root; +int base_cpu; /* Affected cpus chosen by -c/--cpu param */ struct bitmask *cpus_chosen; @@ -174,6 +176,7 @@ int main(int argc, const char *argv[]) unsigned int i, ret; struct stat statbuf; struct utsname uts; + char pathname[32]; cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); @@ -198,17 +201,23 @@ int main(int argc, const char *argv[]) argv[0] = cmd = "help"; } - get_cpu_info(0, &cpupower_cpu_info); + base_cpu = sched_getcpu(); + if (base_cpu < 0) { + fprintf(stderr, _("No valid cpus found.\n")); + return EXIT_FAILURE; + } + + get_cpu_info(&cpupower_cpu_info); run_as_root = !geteuid(); if (run_as_root) { ret = uname(&uts); + sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); if (!ret && !strcmp(uts.machine, "x86_64") && - stat("/dev/cpu/0/msr", &statbuf) != 0) { + stat(pathname, &statbuf) != 0) { if (system("modprobe msr") == -1) fprintf(stderr, _("MSR access not available.\n")); } } - for (i = 0; i < ARRAY_SIZE(commands); i++) { struct cmd_struct *p = commands + i; diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 5fd5c5b8c7b8..bb41cdd0df6b 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #if defined(__i386__) || defined(__x86_64__) #include #include diff --git a/tools/power/cpupower/utils/helpers/bitmask.c b/tools/power/cpupower/utils/helpers/bitmask.c index 5c074c60f904..6c7932f5bd66 100644 --- a/tools/power/cpupower/utils/helpers/bitmask.c +++ b/tools/power/cpupower/utils/helpers/bitmask.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include diff --git a/tools/power/cpupower/utils/helpers/bitmask.h b/tools/power/cpupower/utils/helpers/bitmask.h index eb289df41053..b98d93a44e1b 100644 --- a/tools/power/cpupower/utils/helpers/bitmask.h +++ b/tools/power/cpupower/utils/helpers/bitmask.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPUPOWER_BITMASK__ #define __CPUPOWER_BITMASK__ diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index 39c2c7d067bb..732b0b41ba26 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include #include #include @@ -42,7 +43,7 @@ cpuid_func(edx); * * TBD: Should there be a cpuid alternative for this if /proc is not mounted? */ -int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info) +int get_cpu_info(struct cpupower_cpu_info *cpu_info) { FILE *fp; char value[64]; @@ -70,7 +71,7 @@ int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info) if (!strncmp(value, "processor\t: ", 12)) sscanf(value, "processor\t: %u", &proc); - if (proc != cpu) + if (proc != (unsigned int)base_cpu) continue; /* Get CPU vendor */ diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 799a18be60aa..41da392be448 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -34,6 +34,7 @@ /* Internationalization ****************************/ extern int run_as_root; +extern int base_cpu; extern struct bitmask *cpus_chosen; /* Global verbose (-d) stuff *********************************/ @@ -87,11 +88,11 @@ struct cpupower_cpu_info { * * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo * - * Returns 0 on success or a negativ error code + * Returns 0 on success or a negative error code * Only used on x86, below global's struct values are zero/unknown on * other archs */ -extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info); +extern int get_cpu_info(struct cpupower_cpu_info *cpu_info); extern struct cpupower_cpu_info cpupower_cpu_info; /* cpuid and cpuinfo helpers **************************/ diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c index 601d719d4e60..80fdf55f414d 100644 --- a/tools/power/cpupower/utils/helpers/misc.c +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #if defined(__i386__) || defined(__x86_64__) #include "helpers/helpers.h" @@ -13,7 +14,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, *support = *active = *states = 0; - ret = get_cpu_info(0, &cpu_info); + ret = get_cpu_info(&cpu_info); if (ret) return ret; diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c index 31a4b24a8bc6..ab9950748838 100644 --- a/tools/power/cpupower/utils/helpers/msr.c +++ b/tools/power/cpupower/utils/helpers/msr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #if defined(__i386__) || defined(__x86_64__) #include diff --git a/tools/power/cpupower/utils/helpers/pci.c b/tools/power/cpupower/utils/helpers/pci.c index 8b278983cfc5..113f3da2a203 100644 --- a/tools/power/cpupower/utils/helpers/pci.c +++ b/tools/power/cpupower/utils/helpers/pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #if defined(__i386__) || defined(__x86_64__) #include diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h index d28f11fedbda..0f0b9ad97e4a 100644 --- a/tools/power/cpupower/utils/helpers/sysfs.h +++ b/tools/power/cpupower/utils/helpers/sysfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __CPUPOWER_HELPERS_SYSFS_H__ #define __CPUPOWER_HELPERS_SYSFS_H__ diff --git a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c index ebeaba6571a3..f794d6bbb7e9 100644 --- a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c @@ -123,7 +123,7 @@ static int hsw_ext_start(void) previous_count[num][cpu] = val; } } - hsw_ext_get_count(TSC, &tsc_at_measure_start, 0); + hsw_ext_get_count(TSC, &tsc_at_measure_start, base_cpu); return 0; } @@ -132,7 +132,7 @@ static int hsw_ext_stop(void) unsigned long long val; int num, cpu; - hsw_ext_get_count(TSC, &tsc_at_measure_end, 0); + hsw_ext_get_count(TSC, &tsc_at_measure_end, base_cpu); for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c index c83f1606970b..d7c2a6d13dea 100644 --- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c @@ -80,7 +80,8 @@ static int *is_valid; static int mperf_get_tsc(unsigned long long *tsc) { int ret; - ret = read_msr(0, MSR_TSC, tsc); + + ret = read_msr(base_cpu, MSR_TSC, tsc); if (ret) dprint("Reading TSC MSR failed, returning %llu\n", *tsc); return ret; diff --git a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c index d2a91dd0d563..abf8cb5f7349 100644 --- a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c @@ -129,7 +129,7 @@ static int nhm_start(void) int num, cpu; unsigned long long dbg, val; - nhm_get_count(TSC, &tsc_at_measure_start, 0); + nhm_get_count(TSC, &tsc_at_measure_start, base_cpu); for (num = 0; num < NHM_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { @@ -137,7 +137,7 @@ static int nhm_start(void) previous_count[num][cpu] = val; } } - nhm_get_count(TSC, &dbg, 0); + nhm_get_count(TSC, &dbg, base_cpu); dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start); return 0; } @@ -148,7 +148,7 @@ static int nhm_stop(void) unsigned long long dbg; int num, cpu; - nhm_get_count(TSC, &tsc_at_measure_end, 0); + nhm_get_count(TSC, &tsc_at_measure_end, base_cpu); for (num = 0; num < NHM_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { @@ -156,7 +156,7 @@ static int nhm_stop(void) current_count[num][cpu] = val; } } - nhm_get_count(TSC, &dbg, 0); + nhm_get_count(TSC, &dbg, base_cpu); dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end); return 0; diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c index efc8a69c9aba..a2b45219648d 100644 --- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c @@ -120,7 +120,7 @@ static int snb_start(void) previous_count[num][cpu] = val; } } - snb_get_count(TSC, &tsc_at_measure_start, 0); + snb_get_count(TSC, &tsc_at_measure_start, base_cpu); return 0; } @@ -129,7 +129,7 @@ static int snb_stop(void) unsigned long long val; int num, cpu; - snb_get_count(TSC, &tsc_at_measure_end, 0); + snb_get_count(TSC, &tsc_at_measure_end, base_cpu); for (num = 0; num < SNB_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { diff --git a/tools/power/cpupower/utils/version-gen.sh b/tools/power/cpupower/utils/version-gen.sh index 5ec41c556992..c70de2eabffb 100755 --- a/tools/power/cpupower/utils/version-gen.sh +++ b/tools/power/cpupower/utils/version-gen.sh @@ -1,4 +1,5 @@ #!/bin/sh +# SPDX-License-Identifier: GPL-2.0 # # Script which prints out the version to use for building cpupowerutils. # Must be called from tools/power/cpupower/ diff --git a/tools/power/pm-graph/Makefile b/tools/power/pm-graph/Makefile index 4d0ccc89e6c6..4e1e999e7b05 100644 --- a/tools/power/pm-graph/Makefile +++ b/tools/power/pm-graph/Makefile @@ -1,10 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 PREFIX ?= /usr DESTDIR ?= all: @echo "Nothing to build" -install : +install : uninstall install -d $(DESTDIR)$(PREFIX)/lib/pm-graph install analyze_suspend.py $(DESTDIR)$(PREFIX)/lib/pm-graph install analyze_boot.py $(DESTDIR)$(PREFIX)/lib/pm-graph @@ -17,12 +18,15 @@ install : install sleepgraph.8 $(DESTDIR)$(PREFIX)/share/man/man8 uninstall : - rm $(DESTDIR)$(PREFIX)/share/man/man8/bootgraph.8 - rm $(DESTDIR)$(PREFIX)/share/man/man8/sleepgraph.8 + rm -f $(DESTDIR)$(PREFIX)/share/man/man8/bootgraph.8 + rm -f $(DESTDIR)$(PREFIX)/share/man/man8/sleepgraph.8 - rm $(DESTDIR)$(PREFIX)/bin/bootgraph - rm $(DESTDIR)$(PREFIX)/bin/sleepgraph + rm -f $(DESTDIR)$(PREFIX)/bin/bootgraph + rm -f $(DESTDIR)$(PREFIX)/bin/sleepgraph - rm $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_boot.py - rm $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_suspend.py - rmdir $(DESTDIR)$(PREFIX)/lib/pm-graph + rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_boot.py + rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/analyze_suspend.py + rm -f $(DESTDIR)$(PREFIX)/lib/pm-graph/*.pyc + if [ -d $(DESTDIR)$(PREFIX)/lib/pm-graph ] ; then \ + rmdir $(DESTDIR)$(PREFIX)/lib/pm-graph; \ + fi; diff --git a/tools/power/pm-graph/analyze_boot.py b/tools/power/pm-graph/analyze_boot.py index 3e1dcbbf1adc..e83df141a597 100755 --- a/tools/power/pm-graph/analyze_boot.py +++ b/tools/power/pm-graph/analyze_boot.py @@ -42,7 +42,7 @@ import analyze_suspend as aslib # store system values and test parameters class SystemValues(aslib.SystemValues): title = 'BootGraph' - version = 2.0 + version = '2.1' hostname = 'localhost' testtime = '' kernel = '' @@ -50,9 +50,14 @@ class SystemValues(aslib.SystemValues): ftracefile = '' htmlfile = 'bootgraph.html' outfile = '' - phoronix = False - addlogs = False + testdir = '' + testdirprefix = 'boot' + embedded = False + testlog = False + dmesglog = False + ftracelog = False useftrace = False + usecallgraph = False usedevsrc = True suspendmode = 'boot' max_graph_depth = 2 @@ -61,10 +66,12 @@ class SystemValues(aslib.SystemValues): manual = False iscronjob = False timeformat = '%.6f' + bootloader = 'grub' + blexec = [] def __init__(self): if('LOG_FILE' in os.environ and 'TEST_RESULTS_IDENTIFIER' in os.environ): - self.phoronix = True - self.addlogs = True + self.embedded = True + self.dmesglog = True self.outfile = os.environ['LOG_FILE'] self.htmlfile = os.environ['LOG_FILE'] self.hostname = platform.node() @@ -76,42 +83,80 @@ class SystemValues(aslib.SystemValues): self.kernel = self.kernelVersion(val) else: self.kernel = 'unknown' + self.testdir = datetime.now().strftime('boot-%y%m%d-%H%M%S') def kernelVersion(self, msg): return msg.split()[2] + def checkFtraceKernelVersion(self): + val = tuple(map(int, self.kernel.split('-')[0].split('.'))) + if val >= (4, 10, 0): + return True + return False def kernelParams(self): cmdline = 'initcall_debug log_buf_len=32M' if self.useftrace: - cmdline += ' trace_buf_size=128M trace_clock=global '\ + if self.cpucount > 0: + bs = min(self.memtotal / 2, 2*1024*1024) / self.cpucount + else: + bs = 131072 + cmdline += ' trace_buf_size=%dK trace_clock=global '\ 'trace_options=nooverwrite,funcgraph-abstime,funcgraph-cpu,'\ 'funcgraph-duration,funcgraph-proc,funcgraph-tail,'\ 'nofuncgraph-overhead,context-info,graph-time '\ 'ftrace=function_graph '\ 'ftrace_graph_max_depth=%d '\ 'ftrace_graph_filter=%s' % \ - (self.max_graph_depth, self.graph_filter) + (bs, self.max_graph_depth, self.graph_filter) return cmdline def setGraphFilter(self, val): - fp = open(self.tpath+'available_filter_functions') - master = fp.read().split('\n') - fp.close() + master = self.getBootFtraceFilterFunctions() + fs = '' for i in val.split(','): func = i.strip() + if func == '': + doError('badly formatted filter function string') + if '[' in func or ']' in func: + doError('loadable module functions not allowed - "%s"' % func) + if ' ' in func: + doError('spaces found in filter functions - "%s"' % func) if func not in master: doError('function "%s" not available for ftrace' % func) - self.graph_filter = val + if not fs: + fs = func + else: + fs += ','+func + if not fs: + doError('badly formatted filter function string') + self.graph_filter = fs + def getBootFtraceFilterFunctions(self): + self.rootCheck(True) + fp = open(self.tpath+'available_filter_functions') + fulllist = fp.read().split('\n') + fp.close() + list = [] + for i in fulllist: + if not i or ' ' in i or '[' in i or ']' in i: + continue + list.append(i) + return list + def myCronJob(self, line): + if '@reboot' not in line: + return False + if 'bootgraph' in line or 'analyze_boot.py' in line or '-cronjob' in line: + return True + return False def cronjobCmdString(self): cmdline = '%s -cronjob' % os.path.abspath(sys.argv[0]) args = iter(sys.argv[1:]) for arg in args: if arg in ['-h', '-v', '-cronjob', '-reboot']: continue - elif arg in ['-o', '-dmesg', '-ftrace', '-filter']: + elif arg in ['-o', '-dmesg', '-ftrace', '-func']: args.next() continue cmdline += ' '+arg if self.graph_filter != 'do_one_initcall': - cmdline += ' -filter "%s"' % self.graph_filter - cmdline += ' -o "%s"' % os.path.abspath(self.htmlfile) + cmdline += ' -func "%s"' % self.graph_filter + cmdline += ' -o "%s"' % os.path.abspath(self.testdir) return cmdline def manualRebootRequired(self): cmdline = self.kernelParams() @@ -121,6 +166,39 @@ class SystemValues(aslib.SystemValues): print '3. After reboot, re-run this tool with the same arguments but no command (w/o -reboot or -manual).\n' print 'CMDLINE="%s"' % cmdline sys.exit() + def getExec(self, cmd): + dirlist = ['/sbin', '/bin', '/usr/sbin', '/usr/bin', + '/usr/local/sbin', '/usr/local/bin'] + for path in dirlist: + cmdfull = os.path.join(path, cmd) + if os.path.exists(cmdfull): + return cmdfull + return '' + def blGrub(self): + blcmd = '' + for cmd in ['update-grub', 'grub-mkconfig', 'grub2-mkconfig']: + if blcmd: + break + blcmd = self.getExec(cmd) + if not blcmd: + doError('[GRUB] missing update command') + if not os.path.exists('/etc/default/grub'): + doError('[GRUB] missing /etc/default/grub') + if 'grub2' in blcmd: + cfg = '/boot/grub2/grub.cfg' + else: + cfg = '/boot/grub/grub.cfg' + if not os.path.exists(cfg): + doError('[GRUB] missing %s' % cfg) + if 'update-grub' in blcmd: + self.blexec = [blcmd] + else: + self.blexec = [blcmd, '-o', cfg] + def getBootLoader(self): + if self.bootloader == 'grub': + self.blGrub() + else: + doError('unknown boot loader: %s' % self.bootloader) sysvals = SystemValues() @@ -136,20 +214,23 @@ class Data(aslib.Data): idstr = '' html_device_id = 0 valid = False - initstart = 0.0 + tUserMode = 0.0 boottime = '' - phases = ['boot'] + phases = ['kernel', 'user'] do_one_initcall = False def __init__(self, num): self.testnumber = num self.idstr = 'a' self.dmesgtext = [] self.dmesg = { - 'boot': {'list': dict(), 'start': -1.0, 'end': -1.0, 'row': 0, 'color': '#dddddd'} + 'kernel': {'list': dict(), 'start': -1.0, 'end': -1.0, 'row': 0, + 'order': 0, 'color': 'linear-gradient(to bottom, #fff, #bcf)'}, + 'user': {'list': dict(), 'start': -1.0, 'end': -1.0, 'row': 0, + 'order': 1, 'color': '#fff'} } def deviceTopology(self): return '' - def newAction(self, phase, name, start, end, ret, ulen): + def newAction(self, phase, name, pid, start, end, ret, ulen): # new device callback for a specific phase self.html_device_id += 1 devid = '%s%d' % (self.idstr, self.html_device_id) @@ -163,41 +244,46 @@ class Data(aslib.Data): name = '%s[%d]' % (origname, i) i += 1 list[name] = {'name': name, 'start': start, 'end': end, - 'pid': 0, 'length': length, 'row': 0, 'id': devid, + 'pid': pid, 'length': length, 'row': 0, 'id': devid, 'ret': ret, 'ulen': ulen } return name - def deviceMatch(self, cg): + def deviceMatch(self, pid, cg): if cg.end - cg.start == 0: return True - list = self.dmesg['boot']['list'] - for devname in list: - dev = list[devname] - if cg.name == 'do_one_initcall': - if(cg.start <= dev['start'] and cg.end >= dev['end'] and dev['length'] > 0): - dev['ftrace'] = cg - self.do_one_initcall = True - return True - else: - if(cg.start > dev['start'] and cg.end < dev['end']): - if 'ftraces' not in dev: - dev['ftraces'] = [] - dev['ftraces'].append(cg) - return True + for p in data.phases: + list = self.dmesg[p]['list'] + for devname in list: + dev = list[devname] + if pid != dev['pid']: + continue + if cg.name == 'do_one_initcall': + if(cg.start <= dev['start'] and cg.end >= dev['end'] and dev['length'] > 0): + dev['ftrace'] = cg + self.do_one_initcall = True + return True + else: + if(cg.start > dev['start'] and cg.end < dev['end']): + if 'ftraces' not in dev: + dev['ftraces'] = [] + dev['ftraces'].append(cg) + return True return False # ----------------- FUNCTIONS -------------------- -# Function: loadKernelLog +# Function: parseKernelLog # Description: -# Load a raw kernel log from dmesg -def loadKernelLog(): +# parse a kernel log for boot data +def parseKernelLog(): + phase = 'kernel' data = Data(0) - data.dmesg['boot']['start'] = data.start = ktime = 0.0 + data.dmesg['kernel']['start'] = data.start = ktime = 0.0 sysvals.stamp = { 'time': datetime.now().strftime('%B %d %Y, %I:%M:%S %p'), 'host': sysvals.hostname, 'mode': 'boot', 'kernel': ''} + tp = aslib.TestProps() devtemp = dict() if(sysvals.dmesgfile): lf = open(sysvals.dmesgfile, 'r') @@ -205,6 +291,13 @@ def loadKernelLog(): lf = Popen('dmesg', stdout=PIPE).stdout for line in lf: line = line.replace('\r\n', '') + # grab the stamp and sysinfo + if re.match(tp.stampfmt, line): + tp.stamp = line + continue + elif re.match(tp.sysinfofmt, line): + tp.sysinfo = line + continue idx = line.find('[') if idx > 1: line = line[idx:] @@ -215,7 +308,6 @@ def loadKernelLog(): if(ktime > 120): break msg = m.group('msg') - data.end = data.initstart = ktime data.dmesgtext.append(line) if(ktime == 0.0 and re.match('^Linux version .*', msg)): if(not sysvals.stamp['kernel']): @@ -228,43 +320,39 @@ def loadKernelLog(): data.boottime = bt.strftime('%Y-%m-%d_%H:%M:%S') sysvals.stamp['time'] = bt.strftime('%B %d %Y, %I:%M:%S %p') continue - m = re.match('^calling *(?P.*)\+.*', msg) + m = re.match('^calling *(?P.*)\+.* @ (?P

    [0-9]*)', msg) if(m): - devtemp[m.group('f')] = ktime + func = m.group('f') + pid = int(m.group('p')) + devtemp[func] = (ktime, pid) continue m = re.match('^initcall *(?P.*)\+.* returned (?P.*) after (?P.*) usecs', msg) if(m): data.valid = True + data.end = ktime f, r, t = m.group('f', 'r', 't') if(f in devtemp): - data.newAction('boot', f, devtemp[f], ktime, int(r), int(t)) - data.end = ktime + start, pid = devtemp[f] + data.newAction(phase, f, pid, start, ktime, int(r), int(t)) del devtemp[f] continue if(re.match('^Freeing unused kernel memory.*', msg)): - break + data.tUserMode = ktime + data.dmesg['kernel']['end'] = ktime + data.dmesg['user']['start'] = ktime + phase = 'user' - data.dmesg['boot']['end'] = data.end + if tp.stamp: + sysvals.stamp = 0 + tp.parseStamp(data, sysvals) + data.dmesg['user']['end'] = data.end lf.close() return data -# Function: loadTraceLog +# Function: parseTraceLog # Description: # Check if trace is available and copy to a temp file -def loadTraceLog(data): - # load the data to a temp file if none given - if not sysvals.ftracefile: - lib = aslib.sysvals - aslib.rootCheck(True) - if not lib.verifyFtrace(): - doError('ftrace not available') - if lib.fgetVal('current_tracer').strip() != 'function_graph': - doError('ftrace not configured for a boot callgraph') - sysvals.ftracefile = '/tmp/boot_ftrace.%s.txt' % os.getpid() - call('cat '+lib.tpath+'trace > '+sysvals.ftracefile, shell=True) - if not sysvals.ftracefile: - doError('No trace data available') - +def parseTraceLog(data): # parse the trace log ftemp = dict() tp = aslib.TestProps() @@ -306,9 +394,29 @@ def loadTraceLog(data): print('Sanity check failed for %s-%d' % (proc, pid)) continue # match cg data to devices - if not data.deviceMatch(cg): + if not data.deviceMatch(pid, cg): print ' BAD: %s %s-%d [%f - %f]' % (cg.name, proc, pid, cg.start, cg.end) +# Function: retrieveLogs +# Description: +# Create copies of dmesg and/or ftrace for later processing +def retrieveLogs(): + # check ftrace is configured first + if sysvals.useftrace: + tracer = sysvals.fgetVal('current_tracer').strip() + if tracer != 'function_graph': + doError('ftrace not configured for a boot callgraph') + # create the folder and get dmesg + sysvals.systemInfo(aslib.dmidecode(sysvals.mempath)) + sysvals.initTestOutput('boot') + sysvals.writeDatafileHeader(sysvals.dmesgfile) + call('dmesg >> '+sysvals.dmesgfile, shell=True) + if not sysvals.useftrace: + return + # get ftrace + sysvals.writeDatafileHeader(sysvals.ftracefile) + call('cat '+sysvals.tpath+'trace >> '+sysvals.ftracefile, shell=True) + # Function: colorForName # Description: # Generate a repeatable color from a list for a given name @@ -353,18 +461,19 @@ def cgOverview(cg, minlen): # testruns: array of Data objects from parseKernelLog or parseTraceLog # Output: # True if the html file was created, false if it failed -def createBootGraph(data, embedded): +def createBootGraph(data): # html function templates html_srccall = '

    {0}
    \n' html_timetotal = '\n'\ - ''\ + ''\ + ''\ '\n
    Time from Kernel Boot to start of User Mode: {0} msInit process starts @ {0} msLast initcall ends @ {1} ms
    \n' # device timeline devtl = aslib.Timeline(100, 20) # write the test title and general info header - devtl.createHeader(sysvals, 'noftrace') + devtl.createHeader(sysvals) # Generate the header for this timeline t0 = data.start @@ -373,84 +482,98 @@ def createBootGraph(data, embedded): if(tTotal == 0): print('ERROR: No timeline data') return False - boot_time = '%.0f'%(tTotal*1000) - devtl.html += html_timetotal.format(boot_time) + user_mode = '%.0f'%(data.tUserMode*1000) + last_init = '%.0f'%(tTotal*1000) + devtl.html += html_timetotal.format(user_mode, last_init) # determine the maximum number of rows we need to draw - phase = 'boot' - list = data.dmesg[phase]['list'] devlist = [] - for devname in list: - d = aslib.DevItem(0, phase, list[devname]) - devlist.append(d) - devtl.getPhaseRows(devlist) + for p in data.phases: + list = data.dmesg[p]['list'] + for devname in list: + d = aslib.DevItem(0, p, list[devname]) + devlist.append(d) + devtl.getPhaseRows(devlist, 0, 'start') devtl.calcTotalRows() # draw the timeline background devtl.createZoomBox() - boot = data.dmesg[phase] - length = boot['end']-boot['start'] - left = '%.3f' % (((boot['start']-t0)*100.0)/tTotal) - width = '%.3f' % ((length*100.0)/tTotal) - devtl.html += devtl.html_tblock.format(phase, left, width, devtl.scaleH) - devtl.html += devtl.html_phase.format('0', '100', \ - '%.3f'%devtl.scaleH, '%.3f'%devtl.bodyH, \ - 'white', '') + devtl.html += devtl.html_tblock.format('boot', '0', '100', devtl.scaleH) + for p in data.phases: + phase = data.dmesg[p] + length = phase['end']-phase['start'] + left = '%.3f' % (((phase['start']-t0)*100.0)/tTotal) + width = '%.3f' % ((length*100.0)/tTotal) + devtl.html += devtl.html_phase.format(left, width, \ + '%.3f'%devtl.scaleH, '%.3f'%devtl.bodyH, \ + phase['color'], '') # draw the device timeline num = 0 devstats = dict() - for devname in sorted(list): - cls, color = colorForName(devname) - dev = list[devname] - info = '@|%.3f|%.3f|%.3f|%d' % (dev['start']*1000.0, dev['end']*1000.0, - dev['ulen']/1000.0, dev['ret']) - devstats[dev['id']] = {'info':info} - dev['color'] = color - height = devtl.phaseRowHeight(0, phase, dev['row']) - top = '%.6f' % ((dev['row']*height) + devtl.scaleH) - left = '%.6f' % (((dev['start']-t0)*100)/tTotal) - width = '%.6f' % (((dev['end']-dev['start'])*100)/tTotal) - length = ' (%0.3f ms) ' % ((dev['end']-dev['start'])*1000) - devtl.html += devtl.html_device.format(dev['id'], - devname+length+'kernel_mode', left, top, '%.3f'%height, - width, devname, ' '+cls, '') - rowtop = devtl.phaseRowTop(0, phase, dev['row']) - height = '%.6f' % (devtl.rowH / 2) - top = '%.6f' % (rowtop + devtl.scaleH + (devtl.rowH / 2)) - if data.do_one_initcall: - if('ftrace' not in dev): + for phase in data.phases: + list = data.dmesg[phase]['list'] + for devname in sorted(list): + cls, color = colorForName(devname) + dev = list[devname] + info = '@|%.3f|%.3f|%.3f|%d' % (dev['start']*1000.0, dev['end']*1000.0, + dev['ulen']/1000.0, dev['ret']) + devstats[dev['id']] = {'info':info} + dev['color'] = color + height = devtl.phaseRowHeight(0, phase, dev['row']) + top = '%.6f' % ((dev['row']*height) + devtl.scaleH) + left = '%.6f' % (((dev['start']-t0)*100)/tTotal) + width = '%.6f' % (((dev['end']-dev['start'])*100)/tTotal) + length = ' (%0.3f ms) ' % ((dev['end']-dev['start'])*1000) + devtl.html += devtl.html_device.format(dev['id'], + devname+length+phase+'_mode', left, top, '%.3f'%height, + width, devname, ' '+cls, '') + rowtop = devtl.phaseRowTop(0, phase, dev['row']) + height = '%.6f' % (devtl.rowH / 2) + top = '%.6f' % (rowtop + devtl.scaleH + (devtl.rowH / 2)) + if data.do_one_initcall: + if('ftrace' not in dev): + continue + cg = dev['ftrace'] + large, stats = cgOverview(cg, 0.001) + devstats[dev['id']]['fstat'] = stats + for l in large: + left = '%f' % (((l.time-t0)*100)/tTotal) + width = '%f' % (l.length*100/tTotal) + title = '%s (%0.3fms)' % (l.name, l.length * 1000.0) + devtl.html += html_srccall.format(l.name, left, + top, height, width, title, 'x%d'%num) + num += 1 continue - cg = dev['ftrace'] - large, stats = cgOverview(cg, 0.001) - devstats[dev['id']]['fstat'] = stats - for l in large: - left = '%f' % (((l.time-t0)*100)/tTotal) - width = '%f' % (l.length*100/tTotal) - title = '%s (%0.3fms)' % (l.name, l.length * 1000.0) - devtl.html += html_srccall.format(l.name, left, - top, height, width, title, 'x%d'%num) + if('ftraces' not in dev): + continue + for cg in dev['ftraces']: + left = '%f' % (((cg.start-t0)*100)/tTotal) + width = '%f' % ((cg.end-cg.start)*100/tTotal) + cglen = (cg.end - cg.start) * 1000.0 + title = '%s (%0.3fms)' % (cg.name, cglen) + cg.id = 'x%d' % num + devtl.html += html_srccall.format(cg.name, left, + top, height, width, title, dev['id']+cg.id) num += 1 - continue - if('ftraces' not in dev): - continue - for cg in dev['ftraces']: - left = '%f' % (((cg.start-t0)*100)/tTotal) - width = '%f' % ((cg.end-cg.start)*100/tTotal) - cglen = (cg.end - cg.start) * 1000.0 - title = '%s (%0.3fms)' % (cg.name, cglen) - cg.id = 'x%d' % num - devtl.html += html_srccall.format(cg.name, left, - top, height, width, title, dev['id']+cg.id) - num += 1 # draw the time scale, try to make the number of labels readable - devtl.createTimeScale(t0, tMax, tTotal, phase) + devtl.createTimeScale(t0, tMax, tTotal, 'boot') devtl.html += '\n' # timeline is finished devtl.html += '\n\n' + # draw a legend which describes the phases by color + devtl.html += '
    \n' + pdelta = 20.0 + pmargin = 36.0 + for phase in data.phases: + order = '%.2f' % ((data.dmesg[phase]['order'] * pdelta) + pmargin) + devtl.html += devtl.html_legend.format(order, \ + data.dmesg[phase]['color'], phase+'_mode', phase[0]) + devtl.html += '
    \n' + if(sysvals.outfile == sysvals.htmlfile): hf = open(sysvals.htmlfile, 'a') else: @@ -474,7 +597,7 @@ def createBootGraph(data, embedded): .fstat td {text-align:left;width:35px;}\n\ .srccall {position:absolute;font-size:10px;z-index:7;overflow:hidden;color:black;text-align:center;white-space:nowrap;border-radius:5px;border:1px solid black;background:linear-gradient(to bottom right,#CCC,#969696);}\n\ .srccall:hover {color:white;font-weight:bold;border:1px solid white;}\n' - if(not embedded): + if(not sysvals.embedded): aslib.addCSS(hf, sysvals, 1, False, extra) # write the device timeline @@ -495,9 +618,11 @@ def createBootGraph(data, embedded): html = \ '
    \n'\ '\n'\ + '
    \n' + for p in data.phases: + phase = data.dmesg[p] + html += devtl.html_phaselet.format(p+'_mode', '0', '100', phase['color']) + html += '
    \n\n'\ '\n' hf.write(html) @@ -507,21 +632,21 @@ def createBootGraph(data, embedded): aslib.addCallgraphs(sysvals, hf, data) # add the dmesg log as a hidden div - if sysvals.addlogs: + if sysvals.dmesglog: hf.write('\n') - if(not embedded): + if(not sysvals.embedded): # write the footer and close aslib.addScriptCode(hf, [data]) hf.write('\n\n') else: # embedded out will be loaded in a page, skip the js hf.write('' % \ - (data.start*1000, data.initstart*1000)) + (data.start*1000, data.end*1000)) hf.close() return True @@ -533,17 +658,20 @@ def updateCron(restore=False): if not restore: sysvals.rootUser(True) crondir = '/var/spool/cron/crontabs/' - cronfile = crondir+'root' - backfile = crondir+'root-analyze_boot-backup' + if not os.path.exists(crondir): + crondir = '/var/spool/cron/' if not os.path.exists(crondir): doError('%s not found' % crondir) - out = Popen(['which', 'crontab'], stdout=PIPE).stdout.read() - if not out: + cronfile = crondir+'root' + backfile = crondir+'root-analyze_boot-backup' + cmd = sysvals.getExec('crontab') + if not cmd: doError('crontab not found') # on restore: move the backup cron back into place if restore: if os.path.exists(backfile): shutil.move(backfile, cronfile) + call([cmd, cronfile]) return # backup current cron and install new one with reboot if os.path.exists(cronfile): @@ -556,13 +684,13 @@ def updateCron(restore=False): fp = open(backfile, 'r') op = open(cronfile, 'w') for line in fp: - if '@reboot' not in line: + if not sysvals.myCronJob(line): op.write(line) continue fp.close() op.write('@reboot python %s\n' % sysvals.cronjobCmdString()) op.close() - res = call('crontab %s' % cronfile, shell=True) + res = call([cmd, cronfile]) except Exception, e: print 'Exception: %s' % str(e) shutil.move(backfile, cronfile) @@ -577,25 +705,16 @@ def updateGrub(restore=False): # call update-grub on restore if restore: try: - call(['update-grub'], stderr=PIPE, stdout=PIPE, + call(sysvals.blexec, stderr=PIPE, stdout=PIPE, env={'PATH': '.:/sbin:/usr/sbin:/usr/bin:/sbin:/bin'}) except Exception, e: print 'Exception: %s\n' % str(e) return - # verify we can do this - sysvals.rootUser(True) - grubfile = '/etc/default/grub' - if not os.path.exists(grubfile): - print 'ERROR: Unable to set the kernel parameters via grub.\n' - sysvals.manualRebootRequired() - out = Popen(['which', 'update-grub'], stdout=PIPE).stdout.read() - if not out: - print 'ERROR: Unable to set the kernel parameters via grub.\n' - sysvals.manualRebootRequired() - # extract the option and create a grub config without it + sysvals.rootUser(True) tgtopt = 'GRUB_CMDLINE_LINUX_DEFAULT' cmdline = '' + grubfile = '/etc/default/grub' tempfile = '/etc/default/grub.analyze_boot' shutil.move(grubfile, tempfile) res = -1 @@ -622,7 +741,7 @@ def updateGrub(restore=False): # if the target option value is in quotes, strip them sp = '"' val = cmdline.strip() - if val[0] == '\'' or val[0] == '"': + if val and (val[0] == '\'' or val[0] == '"'): sp = val[0] val = val.strip(sp) cmdline = val @@ -633,7 +752,7 @@ def updateGrub(restore=False): # write out the updated target option op.write('\n%s=%s%s%s\n' % (tgtopt, sp, cmdline, sp)) op.close() - res = call('update-grub') + res = call(sysvals.blexec) os.remove(grubfile) except Exception, e: print 'Exception: %s' % str(e) @@ -641,10 +760,18 @@ def updateGrub(restore=False): # cleanup shutil.move(tempfile, grubfile) if res != 0: - doError('update-grub failed') + doError('update grub failed') -# Function: doError +# Function: updateKernelParams # Description: +# update boot conf for all kernels with our parameters +def updateKernelParams(restore=False): + # find the boot loader + sysvals.getBootLoader() + if sysvals.bootloader == 'grub': + updateGrub(restore) + +# Function: doError Description: # generic error function for catastrphic failures # Arguments: # msg: the error message to print @@ -660,7 +787,7 @@ def doError(msg, help=False): # print out the help text def printHelp(): print('') - print('%s v%.1f' % (sysvals.title, sysvals.version)) + print('%s v%s' % (sysvals.title, sysvals.version)) print('Usage: bootgraph ') print('') print('Description:') @@ -669,13 +796,19 @@ def printHelp(): print(' the start of the init process.') print('') print(' If no specific command is given the tool reads the current dmesg') - print(' and/or ftrace log and outputs bootgraph.html') + print(' and/or ftrace log and creates a timeline') + print('') + print(' Generates output files in subdirectory: boot-yymmdd-HHMMSS') + print(' HTML output: _boot.html') + print(' raw dmesg output: _boot_dmesg.txt') + print(' raw ftrace output: _boot_ftrace.txt') print('') print('Options:') print(' -h Print this help text') print(' -v Print the current tool version') print(' -addlogs Add the dmesg log to the html output') - print(' -o file Html timeline name (default: bootgraph.html)') + print(' -o name Overrides the output subdirectory name when running a new test') + print(' default: boot-{date}-{time}') print(' [advanced]') print(' -f Use ftrace to add function detail (default: disabled)') print(' -callgraph Add callgraph detail, can be very large (default: disabled)') @@ -683,13 +816,18 @@ def printHelp(): print(' -mincg ms Discard all callgraphs shorter than ms milliseconds (e.g. 0.001 for us)') print(' -timeprec N Number of significant digits in timestamps (0:S, 3:ms, [6:us])') print(' -expandcg pre-expand the callgraph data in the html output (default: disabled)') - print(' -filter list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)') - print(' [commands]') + print(' -func list Limit ftrace to comma-delimited list of functions (default: do_one_initcall)') + print(' -cgfilter S Filter the callgraph output in the timeline') + print(' -bl name Use the following boot loader for kernel params (default: grub)') print(' -reboot Reboot the machine automatically and generate a new timeline') - print(' -manual Show the requirements to generate a new timeline manually') - print(' -dmesg file Load a stored dmesg file (used with -ftrace)') - print(' -ftrace file Load a stored ftrace file (used with -dmesg)') + print(' -manual Show the steps to generate a new timeline manually (used with -reboot)') + print('') + print('Other commands:') print(' -flistall Print all functions capable of being captured in ftrace') + print(' -sysinfo Print out system info extracted from BIOS') + print(' [redo]') + print(' -dmesg file Create HTML output using dmesg input (used with -ftrace)') + print(' -ftrace file Create HTML output using ftrace input (used with -dmesg)') print('') return True @@ -698,14 +836,15 @@ def printHelp(): if __name__ == '__main__': # loop through the command line arguments cmd = '' - simplecmds = ['-updategrub', '-flistall'] + testrun = True + simplecmds = ['-sysinfo', '-kpupdate', '-flistall', '-checkbl'] args = iter(sys.argv[1:]) for arg in args: if(arg == '-h'): printHelp() sys.exit() elif(arg == '-v'): - print("Version %.1f" % sysvals.version) + print("Version %s" % sysvals.version) sys.exit() elif(arg in simplecmds): cmd = arg[1:] @@ -716,16 +855,32 @@ if __name__ == '__main__': sysvals.usecallgraph = True elif(arg == '-mincg'): sysvals.mincglen = aslib.getArgFloat('-mincg', args, 0.0, 10000.0) + elif(arg == '-cgfilter'): + try: + val = args.next() + except: + doError('No callgraph functions supplied', True) + sysvals.setDeviceFilter(val) + elif(arg == '-bl'): + try: + val = args.next() + except: + doError('No boot loader name supplied', True) + if val.lower() not in ['grub']: + doError('Unknown boot loader: %s' % val, True) + sysvals.bootloader = val.lower() elif(arg == '-timeprec'): sysvals.setPrecision(aslib.getArgInt('-timeprec', args, 0, 6)) elif(arg == '-maxdepth'): sysvals.max_graph_depth = aslib.getArgInt('-maxdepth', args, 0, 1000) - elif(arg == '-filter'): + elif(arg == '-func'): try: val = args.next() except: doError('No filter functions supplied', True) - aslib.rootCheck(True) + sysvals.useftrace = True + sysvals.usecallgraph = True + sysvals.rootCheck(True) sysvals.setGraphFilter(val) elif(arg == '-ftrace'): try: @@ -734,9 +889,10 @@ if __name__ == '__main__': doError('No ftrace file supplied', True) if(os.path.exists(val) == False): doError('%s does not exist' % val) + testrun = False sysvals.ftracefile = val elif(arg == '-addlogs'): - sysvals.addlogs = True + sysvals.dmesglog = True elif(arg == '-expandcg'): sysvals.cgexp = True elif(arg == '-dmesg'): @@ -748,18 +904,15 @@ if __name__ == '__main__': doError('%s does not exist' % val) if(sysvals.htmlfile == val or sysvals.outfile == val): doError('Output filename collision') + testrun = False sysvals.dmesgfile = val elif(arg == '-o'): try: val = args.next() except: - doError('No HTML filename supplied', True) - if(sysvals.dmesgfile == val or sysvals.ftracefile == val): - doError('Output filename collision') - sysvals.htmlfile = val + doError('No subdirectory name supplied', True) + sysvals.testdir = sysvals.setOutputFolder(val) elif(arg == '-reboot'): - if sysvals.iscronjob: - doError('-reboot and -cronjob are incompatible') sysvals.reboot = True elif(arg == '-manual'): sysvals.reboot = True @@ -767,58 +920,93 @@ if __name__ == '__main__': # remaining options are only for cron job use elif(arg == '-cronjob'): sysvals.iscronjob = True - if sysvals.reboot: - doError('-reboot and -cronjob are incompatible') else: doError('Invalid argument: '+arg, True) + # compatibility errors and access checks + if(sysvals.iscronjob and (sysvals.reboot or \ + sysvals.dmesgfile or sysvals.ftracefile or cmd)): + doError('-cronjob is meant for batch purposes only') + if(sysvals.reboot and (sysvals.dmesgfile or sysvals.ftracefile)): + doError('-reboot and -dmesg/-ftrace are incompatible') + if cmd or sysvals.reboot or sysvals.iscronjob or testrun: + sysvals.rootCheck(True) + if (testrun and sysvals.useftrace) or cmd == 'flistall': + if not sysvals.verifyFtrace(): + doError('Ftrace is not properly enabled') + + # run utility commands + sysvals.cpuInfo() if cmd != '': - if cmd == 'updategrub': - updateGrub() + if cmd == 'kpupdate': + updateKernelParams() elif cmd == 'flistall': - sysvals.getFtraceFilterFunctions(False) + for f in sysvals.getBootFtraceFilterFunctions(): + print f + elif cmd == 'checkbl': + sysvals.getBootLoader() + print 'Boot Loader: %s\n%s' % (sysvals.bootloader, sysvals.blexec) + elif(cmd == 'sysinfo'): + sysvals.printSystemInfo() sys.exit() - # update grub, setup a cronjob, and reboot + # reboot: update grub, setup a cronjob, and reboot if sysvals.reboot: + if (sysvals.useftrace or sysvals.usecallgraph) and \ + not sysvals.checkFtraceKernelVersion(): + doError('Ftrace functionality requires kernel v4.10 or newer') if not sysvals.manual: - updateGrub() + updateKernelParams() updateCron() call('reboot') else: sysvals.manualRebootRequired() sys.exit() - # disable the cronjob + # cronjob: remove the cronjob, grub changes, and disable ftrace if sysvals.iscronjob: updateCron(True) - updateGrub(True) + updateKernelParams(True) + try: + sysvals.fsetVal('0', 'tracing_on') + except: + pass - data = loadKernelLog() - if sysvals.useftrace: - loadTraceLog(data) - if sysvals.iscronjob: - try: - sysvals.fsetVal('0', 'tracing_on') - except: - pass + # testrun: generate copies of the logs + if testrun: + retrieveLogs() + else: + sysvals.setOutputFile() - if(sysvals.outfile and sysvals.phoronix): - fp = open(sysvals.outfile, 'w') - fp.write('pass %s initstart %.3f end %.3f boot %s\n' % - (data.valid, data.initstart*1000, data.end*1000, data.boottime)) - fp.close() - if(not data.valid): - if sysvals.dmesgfile: + # process the log data + if sysvals.dmesgfile: + data = parseKernelLog() + if(not data.valid): doError('No initcall data found in %s' % sysvals.dmesgfile) - else: - doError('No initcall data found, is initcall_debug enabled?') + if sysvals.useftrace and sysvals.ftracefile: + parseTraceLog(data) + else: + doError('dmesg file required') print(' Host: %s' % sysvals.hostname) print(' Test time: %s' % sysvals.testtime) print(' Boot time: %s' % data.boottime) print('Kernel Version: %s' % sysvals.kernel) print(' Kernel start: %.3f' % (data.start * 1000)) - print(' init start: %.3f' % (data.initstart * 1000)) + print('Usermode start: %.3f' % (data.tUserMode * 1000)) + print('Last Init Call: %.3f' % (data.end * 1000)) - createBootGraph(data, sysvals.phoronix) + # handle embedded output logs + if(sysvals.outfile and sysvals.embedded): + fp = open(sysvals.outfile, 'w') + fp.write('pass %s initstart %.3f end %.3f boot %s\n' % + (data.valid, data.tUserMode*1000, data.end*1000, data.boottime)) + fp.close() + + createBootGraph(data) + + # if running as root, change output dir owner to sudo_user + if testrun and os.path.isdir(sysvals.testdir) and \ + os.getuid() == 0 and 'SUDO_USER' in os.environ: + cmd = 'chown -R {0}:{0} {1} > /dev/null 2>&1' + call(cmd.format(os.environ['SUDO_USER'], sysvals.testdir), shell=True) diff --git a/tools/power/pm-graph/analyze_suspend.py b/tools/power/pm-graph/analyze_suspend.py index a9206e67fc1f..1b60fe203741 100755 --- a/tools/power/pm-graph/analyze_suspend.py +++ b/tools/power/pm-graph/analyze_suspend.py @@ -68,10 +68,12 @@ from subprocess import call, Popen, PIPE # store system values and test parameters class SystemValues: title = 'SleepGraph' - version = '4.6' + version = '4.7' ansi = False verbose = False - addlogs = False + testlog = True + dmesglog = False + ftracelog = False mindevlen = 0.0 mincglen = 0.0 cgphase = '' @@ -79,10 +81,11 @@ class SystemValues: max_graph_depth = 0 callloopmaxgap = 0.0001 callloopmaxlen = 0.005 + cpucount = 0 + memtotal = 204800 srgap = 0 cgexp = False - outdir = '' - testdir = '.' + testdir = '' tpath = '/sys/kernel/debug/tracing/' fpdtpath = '/sys/firmware/acpi/tables/FPDT' epath = '/sys/kernel/debug/tracing/events/power/' @@ -95,14 +98,17 @@ class SystemValues: testcommand = '' mempath = '/dev/mem' powerfile = '/sys/power/state' + mempowerfile = '/sys/power/mem_sleep' suspendmode = 'mem' + memmode = '' hostname = 'localhost' prefix = 'test' teststamp = '' + sysstamp = '' dmesgstart = 0.0 dmesgfile = '' ftracefile = '' - htmlfile = '' + htmlfile = 'output.html' embedded = False rtcwake = True rtcwaketime = 15 @@ -127,9 +133,6 @@ class SystemValues: devpropfmt = '# Device Properties: .*' tracertypefmt = '# tracer: (?P.*)' firmwarefmt = '# fwsuspend (?P[0-9]*) fwresume (?P[0-9]*)$' - stampfmt = '# suspend-(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})-'+\ - '(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})'+\ - ' (?P.*) (?P.*) (?P.*)$' tracefuncs = { 'sys_sync': dict(), 'pm_prepare_console': dict(), @@ -218,7 +221,7 @@ class SystemValues: # if this is a phoronix test run, set some default options if('LOG_FILE' in os.environ and 'TEST_RESULTS_IDENTIFIER' in os.environ): self.embedded = True - self.addlogs = True + self.dmesglog = self.ftracelog = True self.htmlfile = os.environ['LOG_FILE'] self.archargs = 'args_'+platform.machine() self.hostname = platform.node() @@ -233,6 +236,13 @@ class SystemValues: self.rtcpath = rtc if (hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()): self.ansi = True + self.testdir = datetime.now().strftime('suspend-%y%m%d-%H%M%S') + def rootCheck(self, fatal=True): + if(os.access(self.powerfile, os.W_OK)): + return True + if fatal: + doError('This command requires sysfs mount and root access') + return False def rootUser(self, fatal=False): if 'USER' in os.environ and os.environ['USER'] == 'root': return True @@ -249,30 +259,60 @@ class SystemValues: args['date'] = n.strftime('%y%m%d') args['time'] = n.strftime('%H%M%S') args['hostname'] = self.hostname - self.outdir = value.format(**args) + return value.format(**args) def setOutputFile(self): - if((self.htmlfile == '') and (self.dmesgfile != '')): + if self.dmesgfile != '': m = re.match('(?P.*)_dmesg\.txt$', self.dmesgfile) if(m): self.htmlfile = m.group('name')+'.html' - if((self.htmlfile == '') and (self.ftracefile != '')): + if self.ftracefile != '': m = re.match('(?P.*)_ftrace\.txt$', self.ftracefile) if(m): self.htmlfile = m.group('name')+'.html' - if(self.htmlfile == ''): - self.htmlfile = 'output.html' - def initTestOutput(self, subdir, testpath=''): + def systemInfo(self, info): + p = c = m = b = '' + if 'baseboard-manufacturer' in info: + m = info['baseboard-manufacturer'] + elif 'system-manufacturer' in info: + m = info['system-manufacturer'] + if 'baseboard-product-name' in info: + p = info['baseboard-product-name'] + elif 'system-product-name' in info: + p = info['system-product-name'] + if 'processor-version' in info: + c = info['processor-version'] + if 'bios-version' in info: + b = info['bios-version'] + self.sysstamp = '# sysinfo | man:%s | plat:%s | cpu:%s | bios:%s | numcpu:%d | memsz:%d' % \ + (m, p, c, b, self.cpucount, self.memtotal) + def printSystemInfo(self): + self.rootCheck(True) + out = dmidecode(self.mempath, True) + fmt = '%-24s: %s' + for name in sorted(out): + print fmt % (name, out[name]) + print fmt % ('cpucount', ('%d' % self.cpucount)) + print fmt % ('memtotal', ('%d kB' % self.memtotal)) + def cpuInfo(self): + self.cpucount = 0 + fp = open('/proc/cpuinfo', 'r') + for line in fp: + if re.match('^processor[ \t]*:[ \t]*[0-9]*', line): + self.cpucount += 1 + fp.close() + fp = open('/proc/meminfo', 'r') + for line in fp: + m = re.match('^MemTotal:[ \t]*(?P[0-9]*) *kB', line) + if m: + self.memtotal = int(m.group('sz')) + break + fp.close() + def initTestOutput(self, name): self.prefix = self.hostname v = open('/proc/version', 'r').read().strip() kver = string.split(v)[2] - n = datetime.now() - testtime = n.strftime('suspend-%m%d%y-%H%M%S') - if not testpath: - testpath = n.strftime('suspend-%y%m%d-%H%M%S') - if(subdir != "."): - self.testdir = subdir+"/"+testpath - else: - self.testdir = testpath + fmt = name+'-%m%d%y-%H%M%S' + testtime = datetime.now().strftime(fmt) self.teststamp = \ '# '+testtime+' '+self.prefix+' '+self.suspendmode+' '+kver if(self.embedded): @@ -355,7 +395,7 @@ class SystemValues: continue self.tracefuncs[i] = dict() def getFtraceFilterFunctions(self, current): - rootCheck(True) + self.rootCheck(True) if not current: call('cat '+self.tpath+'available_filter_functions', shell=True) return @@ -453,7 +493,7 @@ class SystemValues: val += '\nr:%s_ret %s $retval\n' % (name, func) return val def addKprobes(self, output=False): - if len(sysvals.kprobes) < 1: + if len(self.kprobes) < 1: return if output: print(' kprobe functions in this kernel:') @@ -525,7 +565,7 @@ class SystemValues: fp.flush() fp.close() except: - pass + return False return True def fgetVal(self, path): file = self.tpath+path @@ -566,9 +606,15 @@ class SystemValues: self.cleanupFtrace() # set the trace clock to global self.fsetVal('global', 'trace_clock') - # set trace buffer to a huge value self.fsetVal('nop', 'current_tracer') - self.fsetVal('131073', 'buffer_size_kb') + # set trace buffer to a huge value + if self.usecallgraph or self.usedevsrc: + tgtsize = min(self.memtotal / 2, 2*1024*1024) + maxbuf = '%d' % (tgtsize / max(1, self.cpucount)) + if self.cpucount < 1 or not self.fsetVal(maxbuf, 'buffer_size_kb'): + self.fsetVal('131072', 'buffer_size_kb') + else: + self.fsetVal('16384', 'buffer_size_kb') # go no further if this is just a status check if testing: return @@ -641,6 +687,15 @@ class SystemValues: if not self.ansi: return str return '\x1B[%d;40m%s\x1B[m' % (color, str) + def writeDatafileHeader(self, filename, fwdata=[]): + fp = open(filename, 'w') + fp.write(self.teststamp+'\n') + fp.write(self.sysstamp+'\n') + if(self.suspendmode == 'mem' or self.suspendmode == 'command'): + for fw in fwdata: + if(fw): + fp.write('# fwsuspend %u fwresume %u\n' % (fw[0], fw[1])) + fp.close() sysvals = SystemValues() suspendmodename = { @@ -1008,6 +1063,12 @@ class Data: else: self.trimTime(self.tSuspended, \ self.tResumed-self.tSuspended, False) + def getTimeValues(self): + sktime = (self.dmesg['suspend_machine']['end'] - \ + self.tKernSus) * 1000 + rktime = (self.dmesg['resume_complete']['end'] - \ + self.dmesg['resume_machine']['start']) * 1000 + return (sktime, rktime) def setPhase(self, phase, ktime, isbegin): if(isbegin): self.dmesg[phase]['start'] = ktime @@ -1517,7 +1578,7 @@ class FTraceCallGraph: prelinedep += 1 last = 0 lasttime = line.time - virtualfname = 'execution_misalignment' + virtualfname = 'missing_function_name' if len(self.list) > 0: last = self.list[-1] lasttime = last.time @@ -1773,24 +1834,30 @@ class Timeline: html_device = '
    {6}
    \n' html_phase = '
    {5}
    \n' html_phaselet = '
    \n' + html_legend = '
     {2}
    \n' def __init__(self, rowheight, scaleheight): self.rowH = rowheight self.scaleH = scaleheight self.html = '' - def createHeader(self, sv, suppress=''): + def createHeader(self, sv): if(not sv.stamp['time']): return self.html += '
    ' \ % (sv.title, sv.version) - if sv.logmsg and 'log' not in suppress: - self.html += '' - if sv.addlogs and 'dmesg' not in suppress: - self.html += '' - if sv.addlogs and sv.ftracefile and 'ftrace' not in suppress: - self.html += '' + if sv.logmsg and sv.testlog: + self.html += '' + if sv.dmesglog: + self.html += '' + if sv.ftracelog: + self.html += '' headline_stamp = '
    {0} {1} {2} {3}
    \n' self.html += headline_stamp.format(sv.stamp['host'], sv.stamp['kernel'], sv.stamp['mode'], sv.stamp['time']) + if 'man' in sv.stamp and 'plat' in sv.stamp and 'cpu' in sv.stamp: + headline_sysinfo = '
    {0} {1} with {2}
    \n' + self.html += headline_sysinfo.format(sv.stamp['man'], + sv.stamp['plat'], sv.stamp['cpu']) + # Function: getDeviceRows # Description: # determine how may rows the device funcs will take @@ -1839,7 +1906,7 @@ class Timeline: # devlist: the list of devices/actions in a group of contiguous phases # Output: # The total number of rows needed to display this phase of the timeline - def getPhaseRows(self, devlist, row=0): + def getPhaseRows(self, devlist, row=0, sortby='length'): # clear all rows and set them to undefined remaining = len(devlist) rowdata = dict() @@ -1852,8 +1919,12 @@ class Timeline: if tp not in myphases: myphases.append(tp) dev['row'] = -1 - # sort by length 1st, then name 2nd - sortdict[item] = (float(dev['end']) - float(dev['start']), item.dev['name']) + if sortby == 'start': + # sort by start 1st, then length 2nd + sortdict[item] = (-1*float(dev['start']), float(dev['end']) - float(dev['start'])) + else: + # sort by length 1st, then name 2nd + sortdict[item] = (float(dev['end']) - float(dev['start']), item.dev['name']) if 'src' in dev: dev['devrows'] = self.getDeviceRows(dev['src']) # sort the devlist by length so that large items graph on top @@ -1995,8 +2066,13 @@ class Timeline: # A list of values describing the properties of these test runs class TestProps: stamp = '' + sysinfo = '' S0i3 = False fwdata = [] + stampfmt = '# [a-z]*-(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})-'+\ + '(?P[0-9]{2})(?P[0-9]{2})(?P[0-9]{2})'+\ + ' (?P.*) (?P.*) (?P.*)$' + sysinfofmt = '^# sysinfo .*' ftrace_line_fmt_fg = \ '^ *(?P